From 84ea6f195b19fed6051407c107d3d594232923a4 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 2 Oct 2018 10:25:56 -0700 Subject: [PATCH 01/39] fix user-specified k crashes --- DialogTools/KMeansDlg.cpp | 18 +++++++++++++++--- DialogTools/SpectralClusteringDlg.cpp | 9 ++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/DialogTools/KMeansDlg.cpp b/DialogTools/KMeansDlg.cpp index 526e5ec64..be51461e6 100644 --- a/DialogTools/KMeansDlg.cpp +++ b/DialogTools/KMeansDlg.cpp @@ -321,9 +321,16 @@ void KClusterDlg::OnClose(wxCloseEvent& ev) wxString KClusterDlg::_printConfiguration() { + int ncluster = 0; + wxString str_ncluster = combo_n->GetValue(); + long value_ncluster; + if (str_ncluster.ToLong(&value_ncluster)) { + ncluster = value_ncluster; + } + wxString txt; txt << _("Method:\t") << cluster_method << "\n"; - txt << _("Number of clusters:\t") << combo_n->GetSelection() + 2 << "\n"; + txt << _("Number of clusters:\t") << ncluster << "\n"; txt << _("Initialization method:\t") << combo_method->GetString(combo_method->GetSelection()) << "\n"; txt << _("Initialization re-runs:\t") << m_pass->GetValue() << "\n"; txt << _("Maximum iterations:\t") << m_iterations->GetValue() << "\n"; @@ -572,8 +579,13 @@ void KClusterDlg::OnOK(wxCommandEvent& event ) { wxLogMessage("Click KClusterDlg::OnOK"); - int ncluster = combo_n->GetSelection() + 2; - + int ncluster = 0; + wxString str_ncluster = combo_n->GetValue(); + long value_ncluster; + if (str_ncluster.ToLong(&value_ncluster)) { + ncluster = value_ncluster; + } + wxString field_name = m_textbox->GetValue(); if (field_name.IsEmpty()) { wxString err_msg = _("Please enter a field name for saving clustering results."); diff --git a/DialogTools/SpectralClusteringDlg.cpp b/DialogTools/SpectralClusteringDlg.cpp index fa3634e98..803fecbbf 100644 --- a/DialogTools/SpectralClusteringDlg.cpp +++ b/DialogTools/SpectralClusteringDlg.cpp @@ -490,8 +490,15 @@ void SpectralClusteringDlg::OnClose(wxCloseEvent& ev) wxString SpectralClusteringDlg::_printConfiguration() { + int ncluster = 0; + wxString str_ncluster = combo_n->GetValue(); + long value_ncluster; + if (str_ncluster.ToLong(&value_ncluster)) { + ncluster = value_ncluster; + } + wxString txt; - txt << _("Number of clusters:\t") << combo_n->GetString(combo_n->GetSelection()) << "\n"; + txt << _("Number of clusters:\t") << ncluster << "\n"; if (chk_kernel->IsChecked()) { txt << _("Affinity with Guassian Kernel:\tSigma=") << m_sigma->GetValue() << "\n"; From de02dd5514b3523a2e8966d4930b6c4e4ce86618 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 2 Oct 2018 15:23:00 -0700 Subject: [PATCH 02/39] remove category number limitation --- Explore/CatClassification.cpp | 56 +++++++---------------------------- Explore/CatClassification.h | 4 +-- 2 files changed, 11 insertions(+), 49 deletions(-) diff --git a/Explore/CatClassification.cpp b/Explore/CatClassification.cpp index 521638379..f6bd287c4 100644 --- a/Explore/CatClassification.cpp +++ b/Explore/CatClassification.cpp @@ -49,7 +49,6 @@ void create_unique_val_mapping(std::vector& uv_mapping, const std::vector& v_undef) { uv_mapping.clear(); - //uv_mapping.push_back(UniqueValElem(v[0], 0, 0)); int cur_ind = -1; for (int i=0, iend=v.size(); i& b, int N, boost::uniform_01 N-1) return; - // Mersenne Twister random number generator, randomly seeded - // with current time in seconds since Jan 1 1970. - //static boost::mt19937 rng(GdaConst::gda_user_seed); - //static boost::uniform_01 X(rng); - + std::set s; while (s.size() != num_breaks) s.insert(1 + (N-1)*X()); int cnt=0; @@ -127,6 +122,7 @@ double calc_gvf(const std::vector& b, const std::vector& v, return 1-(tssd/gssd); } + void CatClassification::CatLabelsFromBreaks(const std::vector& breaks, std::vector& cat_labels, const CatClassifType theme, @@ -403,8 +399,6 @@ PopulateCatClassifData(const CatClassifDef& cat_def, if (!cats_valid[t]) continue; int n_cat = u_vals_map[t].size(); - if (n_cat > max_num_categories) - n_cat = max_num_categories; bool reversed = false; cat_data.SetCategoryBrushesAtCanvasTm(CatClassification::unique_color_scheme, n_cat, reversed, t); @@ -423,11 +417,9 @@ PopulateCatClassifData(const CatClassifDef& cat_def, int ind = var[t][i].second; if (var_undef[t][ind]) continue; - if (val == unique_val) - if (cat < max_num_categories-1) - cat_data.AppendIdToCategory(t, cat, var[t][i].second); - else - cat_data.AppendIdToCategory(t, max_num_categories-1, var[t][i].second); + if (val == unique_val) { + cat_data.AppendIdToCategory(t, cat, var[t][i].second); + } } } int cur_cat = u_vals_map[t].size(); @@ -441,22 +433,12 @@ PopulateCatClassifData(const CatClassifDef& cat_def, } // for labels int n_cat = u_vals_map[t].size(); - if (n_cat > max_num_categories) - n_cat = max_num_categories; std::vector labels(n_cat); for (int cat=0; cat max_num_categories) - n_cat = max_num_categories; - bool reversed = false; - cat_data.SetCategoryBrushesAtCanvasTm(CatClassification::unique_color_scheme, - n_cat, reversed, t); + cat_data.SetCategoryBrushesAtCanvasTm(CatClassification::unique_color_scheme, n_cat, reversed, t); } cat_data.ResetAllCategoryMinMax(); @@ -1319,9 +1297,7 @@ PopulateCatClassifData(const CatClassifDef& cat_def, continue; } - if (u_vals_map[t][cur_cat] != val && - cur_cat < max_num_categories-1) - { + if (u_vals_map[t][cur_cat] != val) { cur_cat++; } @@ -1341,8 +1317,6 @@ PopulateCatClassifData(const CatClassifDef& cat_def, // for labels int n_cat = u_vals_map[t].size(); - if (n_cat > max_num_categories) - n_cat = max_num_categories; std::vector labels(n_cat); for (int cat=0; cat Date: Tue, 2 Oct 2018 15:37:05 -0700 Subject: [PATCH 03/39] update basemap names and urls --- GdaConst.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/GdaConst.cpp b/GdaConst.cpp index 5237502ed..084673620 100644 --- a/GdaConst.cpp +++ b/GdaConst.cpp @@ -365,13 +365,13 @@ wxString GdaConst::gda_basemap_sources = "\nOpenStreetMap.BlackAndWhite,http://a.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png" "\nStamen.Toner,https://stamen-tiles-a.a.ssl.fastly.net/toner/{z}/{x}/{y}@2x.png" "\nStamen.TonerLite,https://stamen-tiles-a.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}@2x.png" -"\nStamen.Watercolor,https://stamen-tiles-a.a.ssl.fastly.net/watercolor/{z}/{x}/{y}@2x.png" -"\nOther.AMAP,http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}" -"\nOther.AMAP(Satellite),http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}" -"\nOther.AMAP(SatelliteLabel),http://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}" -"\nOther.TianDiTu,http://t0.tianditu.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}" -"\nOther.TianDiTu(Satellite),http://t0.tianditu.cn/DataServer?T=cia_w&X={x}&Y={y}&L={z}" -"\nOther.TianDiTu(Terrain),http://t0.tianditu.cn/DataServer?T=cta_w&X={x}&Y={y}&L={z}" +"\nStamen.Watercolor,https://stamen-tiles-a.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg" +"\nOther (China).AMAP,http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}" +"\nOther (China).AMAP(Satellite),http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}" +"\nOther (China).AMAP(SatelliteLabel),http://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}" +"\nOther (China).TianDiTu,http://t0.tianditu.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}" +"\nOther (China).TianDiTu(Satellite),http://t0.tianditu.cn/DataServer?T=cia_w&X={x}&Y={y}&L={z}" +"\nOther (China).TianDiTu(Terrain),http://t0.tianditu.cn/DataServer?T=cta_w&X={x}&Y={y}&L={z}" ; From 38a5a823d1623b5af594153b223c36a4d04ca58a Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 2 Oct 2018 16:24:39 -0700 Subject: [PATCH 04/39] add count for selected added layers at bottom of view #1722 --- Explore/Basemap.cpp | 4 ++-- Explore/MapLayer.cpp | 11 +++++++++++ Explore/MapLayer.hpp | 3 ++- Explore/MapLayerTree.cpp | 11 ++++++++--- Explore/MapLayerTree.hpp | 2 +- Explore/MapNewView.cpp | 31 ++++++++++++++++++++++++++++++- Explore/MapNewView.h | 3 +++ 7 files changed, 57 insertions(+), 8 deletions(-) diff --git a/Explore/Basemap.cpp b/Explore/Basemap.cpp index 0d9cee1ac..ca990ce90 100644 --- a/Explore/Basemap.cpp +++ b/Explore/Basemap.cpp @@ -180,6 +180,8 @@ Basemap::Basemap(BasemapItem& _basemap_item, nokia_id = "oRnRceLPyM8OFQQA5LYH"; nokia_code = "uEt3wtyghaTfPdDHdOsEGQ"; + wxInitAllImageHandlers(); + GetEasyZoomLevel(); SetupMapType(basemap_item); } @@ -766,8 +768,6 @@ bool Basemap::Draw(wxBitmap* buffer) if (imageSuffix == ".png") { bmp.LoadFile(wxFilePath, wxBITMAP_TYPE_PNG); } else if (imageSuffix == ".jpeg" || imageSuffix == ".jpg" ) { - wxImageHandler * jpegLoader = new wxJPEGHandler(); - wxImage::AddHandler(jpegLoader); bmp.LoadFile(wxFilePath, wxBITMAP_TYPE_JPEG); } if (bmp.IsOk()) { diff --git a/Explore/MapLayer.cpp b/Explore/MapLayer.cpp index d12f1c4f2..88f2cc250 100644 --- a/Explore/MapLayer.cpp +++ b/Explore/MapLayer.cpp @@ -113,6 +113,17 @@ GdaShape* BackgroundMapLayer::GetShape(int idx) return shapes[idx]; } +int BackgroundMapLayer::GetHighlightRecords() +{ + int hl_cnt = 0; + for (int i=0; i GetKeyNames() = 0; virtual bool GetKeyColumnData(wxString col_name, vector& data) = 0; virtual void ResetHighlight() = 0; @@ -95,7 +96,7 @@ class BackgroundMapLayer : public AssociateLayerInt wxString key, bool show_connline=true); virtual bool IsAssociatedWith(AssociateLayerInt* layer); virtual void RemoveAssociatedLayer(AssociateLayerInt* layer); - + virtual int GetHighlightRecords(); // clone all except shapes and geoms, which are owned by Project* instance; // so that different map window can configure the multi-layers diff --git a/Explore/MapLayerTree.cpp b/Explore/MapLayerTree.cpp index 415c42e02..954f64559 100644 --- a/Explore/MapLayerTree.cpp +++ b/Explore/MapLayerTree.cpp @@ -851,16 +851,21 @@ void MapTree::DrawLegend(wxDC& dc, int x, int y, wxString text) if (text == current_map_title) { dc.SetTextForeground(*wxLIGHT_GREY); } - dc.DrawText(text, x, y); - // draw switch button + // add highlight/all AssociateLayerInt* ml_int; if (ml) { ml_int = ml; } else { ml_int = canvas; } + int hl_cnt = ml_int->GetHighlightRecords(); + int all_cnt = ml_int->GetNumRecords(); + wxString hl_str = wxString::Format(" (%d/%d highlight)", hl_cnt, all_cnt); + text = text + hl_str; + dc.DrawText(text, x, y); + // draw switch button wxString ds_thumb = "switch-on.png"; if (ml_int->IsHide()) ds_thumb = "switch-off.png"; wxString file_path_str = GenUtils::GetSamplesDir() + ds_thumb; @@ -903,7 +908,7 @@ int MapTree::GetSwitchClick(wxMouseEvent& event) for (int i = 0; i px_switch) && (x < px_switch + 30) && + if ((x > px_switch) && (x < px_switch + 40) && (y > cur_y) && (y < cur_y + leg_h)) { return i; diff --git a/Explore/MapLayerTree.hpp b/Explore/MapLayerTree.hpp index 386496491..86d5b7a96 100644 --- a/Explore/MapLayerTree.hpp +++ b/Explore/MapLayerTree.hpp @@ -35,7 +35,7 @@ class SetAssociationDlg : public wxDialog vector& _all_layers, const wxString& title = _("Set Association Dialog"), const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxSize(400,300)); + const wxSize& size = wxSize(480,300)); void CreateControls(int nrows); void Init(); diff --git a/Explore/MapNewView.cpp b/Explore/MapNewView.cpp index 2e1864426..875cefd5b 100644 --- a/Explore/MapNewView.cpp +++ b/Explore/MapNewView.cpp @@ -307,8 +307,10 @@ void MapCanvas::UpdateSelectionPoints(bool shiftdown, bool pointsel) TemplateCanvas::UpdateSelectionPoints(shiftdown, pointsel); // if multi-layer presents and top layer is not current map - if ( fg_maps.empty() ) + if ( fg_maps.empty() ) { + UpdateMapTree(); return; + } BackgroundMapLayer* ml = fg_maps[0]; int nn = ml->GetNumRecords(); @@ -391,6 +393,7 @@ void MapCanvas::UpdateSelectionPoints(bool shiftdown, bool pointsel) highlight_state->SetTotalHighlighted(total_highlighted); highlight_timer->Start(50); } + UpdateMapTree(); } void MapCanvas::DetermineMouseHoverObjects(wxPoint pointsel) @@ -1071,6 +1074,18 @@ void MapCanvas::SetHighlight(int idx) } } +int MapCanvas::GetHighlightRecords() +{ + int hl_cnt = 0; + vector& hs = highlight_state->GetHighlight(); + for (int i=0; i(template_frame)) { + f->UpdateMapTree(); + } +} + void MapCanvas::DisplayRightClickMenu(const wxPoint& pos) { // Workaround for right-click not changing window focus in OSX / wxW 3.0 @@ -3183,6 +3205,13 @@ void MapFrame::OnMapEditLayer(wxCommandEvent& e) map_tree->Show(true); } +void MapFrame::UpdateMapTree() +{ + if (map_tree != NULL) { + map_tree->Refresh(); + } +} + void MapFrame::OnMapTreeClose(wxWindowDestroyEvent& event) { map_tree = NULL; diff --git a/Explore/MapNewView.h b/Explore/MapNewView.h index e52c60f55..fc57a6f71 100644 --- a/Explore/MapNewView.h +++ b/Explore/MapNewView.h @@ -210,6 +210,8 @@ class MapCanvas : public TemplateCanvas, public CatClassifStateObserver, public wxString key, bool show_connline=true); virtual bool IsAssociatedWith(AssociateLayerInt* layer); virtual GdaShape* GetShape(int idx); + virtual int GetHighlightRecords(); + void UpdateMapTree(); Shapefile::Main& GetGeometryData(); OGRLayerProxy* GetOGRLayerProxy(); @@ -406,6 +408,7 @@ class MapFrame : public TemplateFrame, public WeightsManStateObserver void OnMapEditLayer(wxCommandEvent& e); void OnMapTreeClose(wxWindowDestroyEvent& event); void OnShowMapBoundary(wxCommandEvent& event); + void UpdateMapTree(); bool ChangeMapType(CatClassification::CatClassifType new_map_theme, MapCanvas::SmoothingType new_map_smoothing, int num_categories, From 2728575ba3c15c76596af30863dbbe834fede9d0 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 18 Oct 2018 20:14:43 -0700 Subject: [PATCH 05/39] Update Spatial Join When spatial join finish, close the Spatial Join dialog automatically and bring up the Table to front so that user ca n browse the newly added column Other: update highlight text in map layer tree window (xx/xx highlighted -->xx/xx selected) Add GdaGridLayer for future use (e.g. raster/KDE layer) --- DialogTools/SpatialJoinDlg.cpp | 3 ++- Explore/MapLayer.cpp | 4 ++++ Explore/MapLayer.hpp | 22 +++++++++++++++++++--- Explore/MapLayerTree.cpp | 2 +- GeoDa.cpp | 4 +++- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/DialogTools/SpatialJoinDlg.cpp b/DialogTools/SpatialJoinDlg.cpp index 9ca5d96ed..a0653b79e 100644 --- a/DialogTools/SpatialJoinDlg.cpp +++ b/DialogTools/SpatialJoinDlg.cpp @@ -327,7 +327,7 @@ void SpatialJoinDlg::OnOK(wxCommandEvent& e) } sj->Run(); - wxString dlg_title = _("Save Results: ") + label; + wxString dlg_title = _("Save Results to Table: ") + label; vector spatial_counts = sj->GetResults(); // save results int new_col = 1; @@ -343,6 +343,7 @@ void SpatialJoinDlg::OnOK(wxCommandEvent& e) dlg.ShowModal(); delete sj; + EndDialog(wxID_OK); } } diff --git a/Explore/MapLayer.cpp b/Explore/MapLayer.cpp index 88f2cc250..abe591a6c 100644 --- a/Explore/MapLayer.cpp +++ b/Explore/MapLayer.cpp @@ -294,6 +294,10 @@ bool BackgroundMapLayer::GetKeyColumnData(wxString field_name, vector& data[i] << layer_proxy->data[i]->GetFieldAsInteger64(col_idx); } return true; + } else if (type == GdaConst::double_type) { + for (int i=0; idata[i]->GetFieldAsDouble(col_idx); + } } else if (type == GdaConst::string_type) { for (int i=0; idata[i]->GetFieldAsString(col_idx); diff --git a/Explore/MapLayer.hpp b/Explore/MapLayer.hpp index 82596d282..1d790a033 100644 --- a/Explore/MapLayer.hpp +++ b/Explore/MapLayer.hpp @@ -39,19 +39,27 @@ class AssociateLayerInt virtual bool IsCurrentMap() = 0; virtual wxString GetName() = 0; virtual int GetNumRecords() = 0; - virtual int GetHighlightRecords() = 0; + virtual vector GetKeyNames() = 0; virtual bool GetKeyColumnData(wxString col_name, vector& data) = 0; + //virtual bool GetColumnData(wxString col_name, vector& data) = 0; + virtual void ResetHighlight() = 0; virtual void SetHighlight(int idx) = 0; virtual void DrawHighlight(wxMemoryDC& dc, MapCanvas* map_canvas) = 0; + virtual int GetHighlightRecords() = 0; + + virtual GdaShape* GetShape(int i) = 0; + //virtual vector GetShapes() = 0; + //virtual wxRect GetExtent() = 0; + virtual void SetLayerAssociation(wxString my_key, AssociateLayerInt* layer, wxString key, bool show_connline=true) = 0; virtual bool IsAssociatedWith(AssociateLayerInt* layer) = 0; virtual void ClearLayerAssociation() { associated_layers.clear(); } - virtual GdaShape* GetShape(int i) = 0; + virtual void SetHide(bool flag) { is_hide = flag; } virtual bool IsHide() { return is_hide; } }; @@ -160,5 +168,13 @@ class GdaShapeLayer : public GdaShape { virtual void paintSelf(wxGraphicsContext* gc); }; - +class GdaGridLayer : public GdaShape { + wxString name; + vector geoms; + +public: + GdaGridLayer(wxString name, int width, int height); + ~GdaGridLayer(); + +}; #endif /* MapLayer_hpp */ diff --git a/Explore/MapLayerTree.cpp b/Explore/MapLayerTree.cpp index 954f64559..76f3dea01 100644 --- a/Explore/MapLayerTree.cpp +++ b/Explore/MapLayerTree.cpp @@ -861,7 +861,7 @@ void MapTree::DrawLegend(wxDC& dc, int x, int y, wxString text) } int hl_cnt = ml_int->GetHighlightRecords(); int all_cnt = ml_int->GetNumRecords(); - wxString hl_str = wxString::Format(" (%d/%d highlight)", hl_cnt, all_cnt); + wxString hl_str = wxString::Format(" (%d/%d selected)", hl_cnt, all_cnt); text = text + hl_str; dc.DrawText(text, x, y); diff --git a/GeoDa.cpp b/GeoDa.cpp index 503bbc2c3..0798837a6 100644 --- a/GeoDa.cpp +++ b/GeoDa.cpp @@ -2526,7 +2526,9 @@ void GdaFrame::OnSpatialJoin(wxCommandEvent& event) return; } SpatialJoinDlg dlg(this, project_p); - dlg.ShowModal(); + if (dlg.ShowModal() == wxID_OK) { + OnOpenNewTable(); + } } void GdaFrame::OnExportSelectedToOGR(wxCommandEvent& event) From 12d6991849bdbe5bf3e893ba0d43283419a2907c Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 18 Oct 2018 20:15:03 -0700 Subject: [PATCH 06/39] Update version.h --- version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.h b/version.h index 9c2f1227b..9f0fb9acc 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 12; const int version_build = 1; - const int version_subbuild = 167; + const int version_subbuild = 169; const int version_year = 2018; const int version_month = 10; - const int version_day = 1; + const int version_day = 18; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From 93bf18f77157beaae10dec98f62214bdf8436368 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 29 Oct 2018 17:22:34 -0700 Subject: [PATCH 07/39] fix issues #1733 #1734 #1735 after version v161-v169 due to a merging issue --- DialogTools/VarGroupingEditorDlg.cpp | 7 +- Explore/ConditionalScatterPlotView.cpp | 7 +- Explore/MapNewView.cpp | 147 ++++++++++++++++++++----- Explore/MapNewView.h | 6 + GdaShape.h | 1 + TemplateCanvas.cpp | 15 +++ TemplateCanvas.h | 2 +- VarCalc/WeightsMetaInfo.cpp | 1 + version.h | 4 +- 9 files changed, 158 insertions(+), 32 deletions(-) diff --git a/DialogTools/VarGroupingEditorDlg.cpp b/DialogTools/VarGroupingEditorDlg.cpp index 93b57e57c..d7a20cff7 100644 --- a/DialogTools/VarGroupingEditorDlg.cpp +++ b/DialogTools/VarGroupingEditorDlg.cpp @@ -431,8 +431,11 @@ void VarGroupingEditorDlg::OnSaveSpaceTimeTableClick( wxCommandEvent& event ) table_int->GetColData(i, t, dat); stack_dat.insert(stack_dat.end(), dat.begin(), dat.end()); int deci = table_int->GetColDecimals(i, t); - if (deci > n_decimal) - n_decimal = deci; + if (deci > 0 && deci > n_decimal) { + n_decimal = deci; + } else { + n_decimal = 12; // default + } } OGRColumn* var_col = new OGRColumnDouble(col_name, 18, n_decimal, n); var_col->UpdateData(stack_dat, undefs); diff --git a/Explore/ConditionalScatterPlotView.cpp b/Explore/ConditionalScatterPlotView.cpp index c42d7481a..2fe93189f 100644 --- a/Explore/ConditionalScatterPlotView.cpp +++ b/Explore/ConditionalScatterPlotView.cpp @@ -103,7 +103,8 @@ show_lowess_smoother(false) // 1 = #cats cat_data.CreateCategoriesAllCanvasTms(1, num_time_vals, num_obs); for (int t=0; tnum_obs; i++) { - if (h[i]) { - selectable_shps[i]->setPen(pen); - selectable_shps[i]->setBrush(*wxTRANSPARENT_BRUSH); - selectable_shps[i]->paintSelf(dc); - } - } - } if (display_neighbors) { - // paint neighbors with specified fill color + wxPen pen(selectable_outline_color); + wxBrush brush(*wxWHITE); + if (GetCcType() != CatClassification::no_theme || selectable_shps_type == points) { + // only paint neighbors with white if no_theme, otherwise transparent + brush = *wxTRANSPARENT_BRUSH; + } if (neighbor_fill_color.Alpha() != 0) { - wxBrush brush(neighbor_fill_color); - for (it=ids_of_nbrs.begin(); it!= ids_of_nbrs.end(); it++) { - selectable_shps[*it]->setBrush(brush); - selectable_shps[*it]->paintSelf(dc); - } + // paint neighbors with specified fill color + wxBrush spec_brush(neighbor_fill_color); + brush = spec_brush; + } + for (it=ids_of_nbrs.begin(); it!= ids_of_nbrs.end(); it++) { + selectable_shps[*it]->setPen(pen); + selectable_shps[*it]->setBrush(brush); + selectable_shps[*it]->paintSelf(dc); + } + } + // paint selected with specified outline color + wxPen pen(selectable_outline_color); + if (selectable_shps_type == points || GetCcType() != CatClassification::no_theme ) { + pen.SetColour(*wxRED); + } + if (conn_selected_color.Alpha() != 0) { + pen.SetColour(conn_selected_color); + } + for (int i=0; inum_obs; i++) { + if (h[i]) { + selectable_shps[i]->setPen(pen); + selectable_shps[i]->setBrush(*wxTRANSPARENT_BRUSH); + selectable_shps[i]->paintSelf(dc); } } } @@ -1187,12 +1199,12 @@ void MapCanvas::DisplayRightClickMenu(const wxPoint& pos) { // Workaround for right-click not changing window focus in OSX / wxW 3.0 wxActivateEvent ae(wxEVT_NULL, true, 0, wxActivateEvent::Reason_Mouse); - if (MapFrame* f = dynamic_cast(template_frame)) { - f->OnActivate(ae); - } + MapFrame* f = dynamic_cast(template_frame); + f->OnActivate(ae); + wxMenu* optMenu = wxXmlResource::Get()->LoadMenu("ID_MAP_NEW_VIEW_MENU_OPTIONS"); AddTimeVariantOptionsToMenu(optMenu); - TemplateCanvas::AppendCustomCategories(optMenu, project->GetCatClassifManager()); + f->AppendCustomCategories(optMenu, project->GetCatClassifManager()); SetCheckMarks(optMenu); GeneralWxUtils::EnableMenuItem(optMenu, XRCID("ID_SAVE_CATEGORIES"), GetCcType() != CatClassification::no_theme); @@ -2949,8 +2961,8 @@ BEGIN_EVENT_TABLE(MapFrame, TemplateFrame) END_EVENT_TABLE() MapFrame::MapFrame(wxFrame *parent, Project* project, - const vector& var_info, - const vector& col_ids, + const vector& _var_info, + const vector& _col_ids, CatClassification::CatClassifType theme_type, MapCanvas::SmoothingType smoothing_type, int num_categories, @@ -2958,7 +2970,10 @@ MapFrame::MapFrame(wxFrame *parent, Project* project, const wxPoint& pos, const wxSize& size, const long style) : TemplateFrame(parent, project, _("Map"), pos, size, style), -w_man_state(project->GetWManState()), export_dlg(NULL), +var_info(_var_info), +col_ids(_col_ids), +w_man_state(project->GetWManState()), +export_dlg(NULL), no_update_weights(false) { wxLogMessage("Open MapFrame."); @@ -3310,13 +3325,67 @@ void MapFrame::MapMenus() // Map Options Menus wxMenu* optMenu = wxXmlResource::Get()->LoadMenu("ID_MAP_NEW_VIEW_MENU_OPTIONS"); ((MapCanvas*) template_canvas)->AddTimeVariantOptionsToMenu(optMenu); - TemplateCanvas::AppendCustomCategories(optMenu, project->GetCatClassifManager()); + AppendCustomCategories(optMenu, project->GetCatClassifManager()); ((MapCanvas*) template_canvas)->SetCheckMarks(optMenu); GeneralWxUtils::ReplaceMenu(mb, _("Options"), optMenu); UpdateOptionMenuItems(); } +void MapFrame::AppendCustomCategories(wxMenu* menu, CatClassifManager* ccm) +{ + // search for ID_CAT_CLASSIF_A(B,C)_MENU submenus + const int num_sub_menus=3; + vector menu_id(num_sub_menus); + vector sub_menu_id(num_sub_menus); + vector base_id(num_sub_menus); + menu_id[0] = XRCID("ID_NEW_CUSTOM_CAT_CLASSIF_A"); + menu_id[1] = XRCID("ID_NEW_CUSTOM_CAT_CLASSIF_B"); // conditional horizontal menu + menu_id[2] = XRCID("ID_NEW_CUSTOM_CAT_CLASSIF_C"); // conditional verticle menu + sub_menu_id[0] = XRCID("ID_CAT_CLASSIF_A_MENU"); + sub_menu_id[1] = XRCID("ID_CAT_CLASSIF_B_MENU"); + sub_menu_id[2] = XRCID("ID_CAT_CLASSIF_C_MENU"); + base_id[0] = GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0; + base_id[1] = GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_B0; + base_id[2] = GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_C0; + + for (int i=0; iFindItem(sub_menu_id[i]); + if (!smii) continue; + wxMenu* smi = smii->GetSubMenu(); + if (!smi) continue; + int m_id = smi->FindItem(_("Custom Breaks")); + wxMenuItem* mi = smi->FindItem(m_id); + if (!mi) continue; + + wxMenu* sm = mi->GetSubMenu(); + // clean + wxMenuItemList items = sm->GetMenuItems(); + for (int i=0; iDelete(items[i]); + } + + sm->Append(menu_id[i], _("Create New Custom"), _("Create new custom categories classification.")); + sm->AppendSeparator(); + + vector titles; + ccm->GetTitles(titles); + for (size_t j=0; jAppend(base_id[i]+j, titles[j]); + } + if (i==0) { + // regular map men + Bind(wxEVT_COMMAND_MENU_SELECTED, &MapFrame::OnCustomCategoryClick, this, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0 + titles.size()); + } else if (i==1) { + // conditional horizontal map menu + GdaFrame::GetGdaFrame()->Bind(wxEVT_COMMAND_MENU_SELECTED, &GdaFrame::OnCustomCategoryClick_B, GdaFrame::GetGdaFrame(), GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_B0, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_B0 + titles.size()); + } else if (i==2) { + // conditional verticle map menu + GdaFrame::GetGdaFrame()->Bind(wxEVT_COMMAND_MENU_SELECTED, &GdaFrame::OnCustomCategoryClick_C, GdaFrame::GetGdaFrame(), GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_C0, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_C0 + titles.size()); + } + } +} + void MapFrame::UpdateOptionMenuItems() { TemplateFrame::UpdateOptionMenuItems(); // set common items first @@ -3733,6 +3802,32 @@ void MapFrame::OnSpatialEmpiricalBayes() true, dlg.var_info, dlg.col_ids); } +void MapFrame::OnCustomCategoryClick(wxCommandEvent& event) +{ + int xrc_id = event.GetId(); + CatClassifManager* ccm = project->GetCatClassifManager(); + if (!ccm) return; + vector titles; + ccm->GetTitles(titles); + int idx = xrc_id - GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0; + if (idx < 0 || idx >= titles.size()) return; + wxString cc_title = titles[idx]; + + if (var_info.empty() == false && col_ids.empty() == false) { + ChangeMapType(CatClassification::custom, + MapCanvas::no_smoothing, + 4, boost::uuids::nil_uuid(), + true, var_info, col_ids, cc_title); + } else { + VariableSettingsDlg dlg(project, VariableSettingsDlg::univariate); + if (dlg.ShowModal() != wxID_OK) return; + ChangeMapType(CatClassification::custom, + MapCanvas::no_smoothing, + 4, boost::uuids::nil_uuid(), + true, dlg.var_info, dlg.col_ids, cc_title); + } +} + void MapFrame::OnSaveRates() { ((MapCanvas*) template_canvas)->SaveRates(); @@ -3747,6 +3842,8 @@ bool MapFrame::ChangeMapType(CatClassification::CatClassifType new_map_theme, const vector& new_col_ids, const wxString& custom_classif_title) { + var_info = new_var_info; + col_ids = new_col_ids; bool r=((MapCanvas*) template_canvas)-> ChangeMapType(new_map_theme, new_map_smoothing, num_categories, weights_id, diff --git a/Explore/MapNewView.h b/Explore/MapNewView.h index fc57a6f71..1dd7e42cc 100644 --- a/Explore/MapNewView.h +++ b/Explore/MapNewView.h @@ -352,6 +352,7 @@ class MapFrame : public TemplateFrame, public WeightsManStateObserver virtual void update(WeightsManState* o); virtual int numMustCloseToRemove(boost::uuids::uuid id) const; virtual void closeObserver(boost::uuids::uuid id); + virtual void OnCustomCategoryClick(wxCommandEvent& event); virtual void OnNewCustomCatClassifA(); virtual void OnCustomCatClassifA(const wxString& cc_title); virtual void OnThemelessMap(); @@ -424,7 +425,12 @@ class MapFrame : public TemplateFrame, public WeightsManStateObserver if (!template_legend) return; template_legend->Recreate(); } + void AppendCustomCategories(wxMenu* menu, CatClassifManager* ccm); + + vector var_info; + vector col_ids; + protected: wxBoxSizer* rbox; diff --git a/GdaShape.h b/GdaShape.h index 3f6b22999..916f4a165 100644 --- a/GdaShape.h +++ b/GdaShape.h @@ -237,6 +237,7 @@ class GdaPoint: public GdaShape { double GetY(); void SetX(double x); void SetY(double y); + void SetRadius(double r) {radius = r;} }; diff --git a/TemplateCanvas.cpp b/TemplateCanvas.cpp index 942539f8e..192c35e82 100644 --- a/TemplateCanvas.cpp +++ b/TemplateCanvas.cpp @@ -799,6 +799,21 @@ void TemplateCanvas::OnSize(wxSizeEvent& event) event.Skip(); } +void TemplateCanvas::SetPointRadius(double r) +{ + point_radius = r; + // also update seletable_shps[] with new point_radius + GdaPoint* p; + for (int i=0, iend=selectable_shps.size(); iisNull()) { + continue; + } + p->SetRadius(point_radius); + } + } +} bool TemplateCanvas::_IsShpValid(int idx) { diff --git a/TemplateCanvas.h b/TemplateCanvas.h index 7b1109fdf..5e4a5bcf9 100644 --- a/TemplateCanvas.h +++ b/TemplateCanvas.h @@ -312,7 +312,7 @@ class TemplateCanvas : public wxScrolledWindow, public HighlightStateObserver virtual wxString GetVariableNames() = 0; virtual SelectableShpType GetShapeType() {return selectable_shps_type;} virtual double GetPointRadius() { return point_radius; } - virtual void SetPointRadius(double r) { point_radius = r;} + virtual void SetPointRadius(double r); void GetVizInfo(std::map >& colors); void GetVizInfo(wxString& shape_type, std::vector& clrs, std::vector& bins); diff --git a/VarCalc/WeightsMetaInfo.cpp b/VarCalc/WeightsMetaInfo.cpp index 57a623f5b..e1f7756d9 100644 --- a/VarCalc/WeightsMetaInfo.cpp +++ b/VarCalc/WeightsMetaInfo.cpp @@ -26,6 +26,7 @@ WeightsMetaInfo::WeightsMetaInfo() void WeightsMetaInfo::SetToDefaults() { + weights_type = WT_custom; id_var = ""; filename = ""; sym_type = SYM_unknown; diff --git a/version.h b/version.h index 9f0fb9acc..1cb3d12a9 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 12; const int version_build = 1; - const int version_subbuild = 169; + const int version_subbuild = 171; const int version_year = 2018; const int version_month = 10; - const int version_day = 18; + const int version_day = 29; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From a047e4c86a8f88838682c15a430e4967578ca663 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 29 Oct 2018 19:49:30 -0700 Subject: [PATCH 08/39] fix issue: PCP with Custom Category doesn't work correclty steps: 1. create a custom category: brk1 2. create PCP 3. in PCP, right click->Custom Break->brk1 A new map will be created, which is not correct --- Explore/PCPNewView.cpp | 92 +++++++++++++++++++++++++++++++++++++----- Explore/PCPNewView.h | 20 ++++----- 2 files changed, 91 insertions(+), 21 deletions(-) diff --git a/Explore/PCPNewView.cpp b/Explore/PCPNewView.cpp index c8389042c..6c39e4bad 100644 --- a/Explore/PCPNewView.cpp +++ b/Explore/PCPNewView.cpp @@ -177,14 +177,14 @@ void PCPCanvas::DisplayRightClickMenu(const wxPoint& pos) { // Workaround for right-click not changing window focus in OSX / wxW 3.0 wxActivateEvent ae(wxEVT_NULL, true, 0, wxActivateEvent::Reason_Mouse); - ((PCPFrame*) template_frame)->OnActivate(ae); + PCPFrame* f = (PCPFrame*) template_frame; + f->OnActivate(ae); wxMenu* optMenu; optMenu = wxXmlResource::Get()-> LoadMenu("ID_PCP_NEW_PLOT_VIEW_MENU_OPTIONS"); AddTimeVariantOptionsToMenu(optMenu); - TemplateCanvas::AppendCustomCategories(optMenu, - project->GetCatClassifManager()); + f->AppendCustomCategories(optMenu,project->GetCatClassifManager()); SetCheckMarks(optMenu); template_frame->UpdateContextMenuItems(optMenu); @@ -362,9 +362,7 @@ void PCPCanvas::NewCustomCatClassif() cat_classif_def = ccs->GetCatClassif(); custom_classif_state = ccs; custom_classif_state->registerObserver(this); - //wxString s; - //CatClassification::PrintCatClassifDef(cat_classif_def, s); - //LOG_MSG(s); + CreateAndUpdateCategories(); PopulateCanvas(); if (template_frame) { @@ -1122,13 +1120,15 @@ IMPLEMENT_CLASS(PCPFrame, TemplateFrame) END_EVENT_TABLE() PCPFrame::PCPFrame(wxFrame *parent, Project* project, - const std::vector& var_info, - const std::vector& col_ids, + const std::vector& _var_info, + const std::vector& _col_ids, const wxString& title, const wxPoint& pos, const wxSize& size, const long style) -: TemplateFrame(parent, project, title, pos, size, style) +: TemplateFrame(parent, project, title, pos, size, style), +var_info(_var_info), +col_ids(_col_ids) { wxLogMessage("Open PCPFrame."); @@ -1196,13 +1196,83 @@ void PCPFrame::MapMenus() LoadMenu("ID_PCP_NEW_PLOT_VIEW_MENU_OPTIONS"); ((PCPCanvas*) template_canvas)-> AddTimeVariantOptionsToMenu(optMenu); - TemplateCanvas::AppendCustomCategories(optMenu, - project->GetCatClassifManager()); + AppendCustomCategories(optMenu, project->GetCatClassifManager()); ((PCPCanvas*) template_canvas)->SetCheckMarks(optMenu); GeneralWxUtils::ReplaceMenu(mb, _("Options"), optMenu); UpdateOptionMenuItems(); } +void PCPFrame::AppendCustomCategories(wxMenu* menu, CatClassifManager* ccm) +{ + // search for ID_CAT_CLASSIF_A(B,C)_MENU submenus + const int num_sub_menus=3; + vector menu_id(num_sub_menus); + vector sub_menu_id(num_sub_menus); + vector base_id(num_sub_menus); + menu_id[0] = XRCID("ID_NEW_CUSTOM_CAT_CLASSIF_A"); + menu_id[1] = XRCID("ID_NEW_CUSTOM_CAT_CLASSIF_B"); // conditional horizontal menu + menu_id[2] = XRCID("ID_NEW_CUSTOM_CAT_CLASSIF_C"); // conditional verticle menu + sub_menu_id[0] = XRCID("ID_CAT_CLASSIF_A_MENU"); + sub_menu_id[1] = XRCID("ID_CAT_CLASSIF_B_MENU"); + sub_menu_id[2] = XRCID("ID_CAT_CLASSIF_C_MENU"); + base_id[0] = GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0; + base_id[1] = GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_B0; + base_id[2] = GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_C0; + + for (int i=0; iFindItem(sub_menu_id[i]); + if (!smii) continue; + wxMenu* smi = smii->GetSubMenu(); + if (!smi) continue; + int m_id = smi->FindItem(_("Custom Breaks")); + wxMenuItem* mi = smi->FindItem(m_id); + if (!mi) continue; + + wxMenu* sm = mi->GetSubMenu(); + // clean + wxMenuItemList items = sm->GetMenuItems(); + for (int i=0; iDelete(items[i]); + } + + sm->Append(menu_id[i], _("Create New Custom"), _("Create new custom categories classification.")); + sm->AppendSeparator(); + + vector titles; + ccm->GetTitles(titles); + for (size_t j=0; jAppend(base_id[i]+j, titles[j]); + } + if (i==0) { + // regular map men + Bind(wxEVT_COMMAND_MENU_SELECTED, &PCPFrame::OnCustomCategoryClick, this, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0 + titles.size()); + } else if (i==1) { + // conditional horizontal map menu + GdaFrame::GetGdaFrame()->Bind(wxEVT_COMMAND_MENU_SELECTED, &GdaFrame::OnCustomCategoryClick_B, GdaFrame::GetGdaFrame(), GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_B0, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_B0 + titles.size()); + } else if (i==2) { + // conditional verticle map menu + GdaFrame::GetGdaFrame()->Bind(wxEVT_COMMAND_MENU_SELECTED, &GdaFrame::OnCustomCategoryClick_C, GdaFrame::GetGdaFrame(), GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_C0, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_C0 + titles.size()); + } + } +} + +void PCPFrame::OnCustomCategoryClick(wxCommandEvent& event) +{ + int xrc_id = event.GetId(); + CatClassifManager* ccm = project->GetCatClassifManager(); + if (!ccm) return; + vector titles; + ccm->GetTitles(titles); + int idx = xrc_id - GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0; + if (idx < 0 || idx >= titles.size()) return; + wxString cc_title = titles[idx]; + + PCPCanvas* f = (PCPCanvas*) template_canvas; + + ChangeThemeType(CatClassification::custom, 4, cc_title); +} + + void PCPFrame::UpdateOptionMenuItems() { TemplateFrame::UpdateOptionMenuItems(); // set common items first diff --git a/Explore/PCPNewView.h b/Explore/PCPNewView.h index 1ff1cba42..0c6717480 100644 --- a/Explore/PCPNewView.h +++ b/Explore/PCPNewView.h @@ -65,15 +65,8 @@ class PCPCanvas : public TemplateCanvas, public CatClassifStateObserver virtual void SetCheckMarks(wxMenu* menu); void OnSaveCategories(); // cats -protected: - virtual void PopulateCanvas(); - virtual void TimeChange(); - void VarInfoAttributeChange(); - -public: void CreateAndUpdateCategories(); // cats -public: virtual void TimeSyncVariableToggle(int var_index); virtual void FixedScaleVariableToggle(int var_index); @@ -85,8 +78,7 @@ class PCPCanvas : public TemplateCanvas, public CatClassifStateObserver bool IsShowAxes() { return show_axes; } /** Used by PCP for detecting and updating PCP-specific controls */ - enum PCPSelectState { pcp_start, pcp_leftdown_on_circ, - pcp_leftdown_on_label, pcp_dragging }; + enum PCPSelectState { pcp_start, pcp_leftdown_on_circ, pcp_leftdown_on_label, pcp_dragging }; /** The function handles all mouse events. */ void OnMouseEvent(wxMouseEvent& event); void VarLabelClicked(); @@ -100,7 +92,10 @@ class PCPCanvas : public TemplateCanvas, public CatClassifStateObserver virtual void UpdateStatusBar(); protected: - + virtual void PopulateCanvas(); + virtual void TimeChange(); + void VarInfoAttributeChange(); + CatClassifState* custom_classif_state; wxPoint pcp_prev; @@ -190,6 +185,11 @@ class PCPFrame : public TemplateFrame { virtual void OnNaturalBreaks(int num_cats); virtual void OnEqualIntervals(int num_cats); virtual void OnSaveCategories(); + virtual void OnCustomCategoryClick(wxCommandEvent& event); + void AppendCustomCategories(wxMenu* menu, CatClassifManager* ccm); + + vector var_info; + vector col_ids; protected: void ChangeThemeType(CatClassification::CatClassifType new_theme, From 1053ad501be723eae17bbcd78d4bf4934f237bb7 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 29 Oct 2018 20:52:14 -0700 Subject: [PATCH 09/39] update ui to match lab notes some UI has been changed based on the new rendering style (e.g. the point dataset are loaded with high precision with configurable radius, multi-layer etc.), so I just go through the notes and make sure the latest GeoDa generates same (or very close) screenshots with lab notes. --- DataViewer/OGRColumn.cpp | 2 +- DataViewer/OGRTable.cpp | 5 ++++- DataViewer/TableBase.cpp | 5 +++-- Explore/LisaScatterPlotView.cpp | 4 +++- Explore/MapNewView.cpp | 1 + 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/DataViewer/OGRColumn.cpp b/DataViewer/OGRColumn.cpp index e380964e6..bfcb98130 100644 --- a/DataViewer/OGRColumn.cpp +++ b/DataViewer/OGRColumn.cpp @@ -657,7 +657,7 @@ wxString OGRColumnDouble::GetValueAt(int row_idx, int disp_decimals, if (undef_markers[row_idx] == true) return wxEmptyString; - if ( disp_decimals < 0) + if ( disp_decimals <= 0) disp_decimals = GdaConst::default_dbf_double_decimals; double val; diff --git a/DataViewer/OGRTable.cpp b/DataViewer/OGRTable.cpp index 7c06b8779..18af96403 100644 --- a/DataViewer/OGRTable.cpp +++ b/DataViewer/OGRTable.cpp @@ -1444,13 +1444,16 @@ void OGRTable::GroupCols(const std::vector& cols, GetColType(cols[i]) != GdaConst::placeholder_type) { decimals = GetColDecimals(cols[i]); - displayed_decimals = GetColDecimals(cols[i]); + displayed_decimals = GetColDispDecimals(cols[i]); length = GetColLength(cols[i]); type = GetColType(cols[i]); found_nonplaceholder = true; } } + if (decimals <=0) decimals = GdaConst::default_dbf_double_decimals; + if (displayed_decimals<=0) displayed_decimals = decimals; + TableDeltaList_type tdl; var_order.Group(cols, name, pos, tdl); // Last entry in tdl should be an insert operation. Add missing diff --git a/DataViewer/TableBase.cpp b/DataViewer/TableBase.cpp index 8433042c2..c5c511cc8 100644 --- a/DataViewer/TableBase.cpp +++ b/DataViewer/TableBase.cpp @@ -517,8 +517,9 @@ void TableBase::update(TableState* o) } else if (e.type == GdaConst::double_type) { int dd = e.displayed_decimals; if (dd == -1) dd = e.decimals; - GetView()->SetColFormatFloat(e.pos_final, -1, - std::min(e.decimals, dd)); + dd = std::min(e.decimals, dd); + if (dd <=0) dd = GdaConst::default_dbf_double_decimals; + GetView()->SetColFormatFloat(e.pos_final, -1, dd); } else { // leave as a string } diff --git a/Explore/LisaScatterPlotView.cpp b/Explore/LisaScatterPlotView.cpp index 0736c756a..2afbac965 100644 --- a/Explore/LisaScatterPlotView.cpp +++ b/Explore/LisaScatterPlotView.cpp @@ -78,7 +78,9 @@ rand_dlg(0), morans_sel_text(NULL), morans_unsel_text(NULL) wxColour default_cat_color = GdaConst::scatterplot_regression_excluded_color; cat_data.CreateCategoriesAllCanvasTms(1, 1, num_obs); - cat_data.SetCategoryColor(0, 0, default_cat_color); + //cat_data.SetCategoryColor(0, 0, default_cat_color); + cat_data.SetCategoryPenColor(0, 0, default_cat_color); + cat_data.SetCategoryBrushColor(0, 0, *wxWHITE); for (int i=0; iGetWManState()), export_dlg(NULL) { + map_tree = NULL; w_man_state->registerObserver(this); } From ec54164f07b0dc82a6d6e725c96736f8d55302e8 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 30 Oct 2018 09:42:09 -0700 Subject: [PATCH 10/39] fix UI issue in macOS majave The main map window doesn't show under macOS majave --- GeoDa.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GeoDa.cpp b/GeoDa.cpp index 0798837a6..d2543f9f9 100644 --- a/GeoDa.cpp +++ b/GeoDa.cpp @@ -1362,6 +1362,7 @@ void GdaFrame::InitWithProject(wxString gda_file_path) wxDEFAULT_FRAME_STYLE); if (project_p->IsTableOnlyProject()) { tf->Show(true); + tf->Raise(); } SetProjectOpen(true); @@ -1393,6 +1394,8 @@ void GdaFrame::InitWithProject(wxString gda_file_path) wxPoint(80,160), GdaConst::map_default_size); nf->UpdateTitle(); + nf->Show(true); + nf->Raise(); } } From 21a7a90587eb229ffca3b4937fbb3765a9605ba7 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 6 Nov 2018 13:19:55 -0700 Subject: [PATCH 11/39] fix issues on windows Use unable to open saved gda files by double clicking it on windows. Spline drawing code update: number of points should be more than 2, see: dc.cpp line 1099 wxASSERT_MSG( n_points > 2 , wxT("incomplete list of spline points?") ); --- GdaShape.cpp | 2 +- GeoDa.cpp | 23 +++++++++++++++++++---- GeoDa.h | 5 +++-- version.h | 6 +++--- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/GdaShape.cpp b/GdaShape.cpp index 11952d288..135296a97 100644 --- a/GdaShape.cpp +++ b/GdaShape.cpp @@ -1958,7 +1958,7 @@ void GdaSpline::applyScaleTrans(const GdaScaleTrans& A) void GdaSpline::paintSelf(wxDC& dc) { - if (null_shape || n<2 || !points) return; + if (null_shape || n<=2 || !points) return; dc.SetPen(getPen()); dc.SetBrush(getBrush()); diff --git a/GeoDa.cpp b/GeoDa.cpp index d2543f9f9..f6b3ffdb5 100644 --- a/GeoDa.cpp +++ b/GeoDa.cpp @@ -290,7 +290,7 @@ bool GdaApp::OnInit(void) wxString no_crash = items[0]; if (no_crash == "false") { // ask user to send crash data - wxString msg = _("It looks like GeoDa has been terminated abnormally. \nDo you want to send a crash report to GeoDa team? \n\n(Optional) Please leave your email address,\nso we can send a follow-up email once we have a fix."); + wxString msg = _("It looks like GeoDa has been terminated abnormally. \nDo you want to send a crash report to GeoDa team? \n\n(Optional) Please leave your email address,\nso we can send a follow-up email once we have a fix."); wxString ttl = _("Send Crash Report"); wxString user_email = GdaConst::gda_user_email; wxTextEntryDialog msgDlg(GdaFrame::GetGdaFrame(), msg, ttl, user_email, @@ -352,7 +352,6 @@ bool GdaApp::OnInit(void) // of %100, %125 or %150. // Therefore, we might need to slighly increase the window size // when sizes > %100 are used in the Display options. - if (GdaFrame::GetGdaFrame()->GetClientSize().GetHeight() < 22) { GdaFrame::GetGdaFrame()->SetSize( GdaFrame::GetGdaFrame()->GetSize().GetWidth(), @@ -382,8 +381,7 @@ bool GdaApp::OnInit(void) wxSetEnv("GEODA_GDAL_DATA", gal_data_dir); CPLSetConfigOption("GEODA_GDAL_DATA", GET_ENCODED_FILENAME(gal_data_dir)); #endif - - + // Setup new Logger after crash check wxString loggerFile = GenUtils::GetSamplesDir() +"logger.txt"; @@ -429,6 +427,22 @@ bool GdaApp::OnCmdLineParsed(wxCmdLineParser& parser) return true; } +const wxCmdLineEntryDesc GdaApp::globalCmdLineDesc [] = +{ + { wxCMD_LINE_SWITCH, "h", "help", + "displays help on the command line parameters", + wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, + { wxCMD_LINE_PARAM, NULL, NULL, "project file", + wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_NONE } +}; + +void GdaApp::OnInitCmdLine(wxCmdLineParser& parser) +{ + parser.SetDesc (GdaApp::globalCmdLineDesc); + parser.SetSwitchChars ("-"); +} + void GdaApp::MacOpenFiles(const wxArrayString& fileNames) { wxLogMessage("MacOpenFiles"); @@ -440,6 +454,7 @@ void GdaApp::MacOpenFiles(const wxArrayString& fileNames) while (node) { wxWindow* win = node->GetData(); if (ConnectDatasourceDlg* w = dynamic_cast(win)) { + wxLogMessage("Close ConnectDatasourceDlg"); w->EndModal(wxID_CANCEL); } node = node->GetNext(); diff --git a/GeoDa.h b/GeoDa.h index c1e8d5fe7..170566bfe 100644 --- a/GeoDa.h +++ b/GeoDa.h @@ -55,9 +55,10 @@ class GdaApp: public wxApp virtual bool OnInit(void); virtual int OnExit(void); virtual void OnFatalException(void); - virtual bool OnCmdLineParsed(wxCmdLineParser& parser); + virtual void OnInitCmdLine(wxCmdLineParser& parser); + virtual bool OnCmdLineParsed(wxCmdLineParser& parser); virtual void MacOpenFiles(const wxArrayString& fileNames); - + static const wxCmdLineEntryDesc globalCmdLineDesc[]; private: wxString cmd_line_proj_file_name; wxTranslationHelper* m_TranslationHelper; diff --git a/version.h b/version.h index 1cb3d12a9..d54c97f2d 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 12; const int version_build = 1; - const int version_subbuild = 171; + const int version_subbuild = 173; const int version_year = 2018; - const int version_month = 10; - const int version_day = 29; + const int version_month = 11; + const int version_day = 6; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From bd32f0566d131134bd9829c5782095599c550c30 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 8 Nov 2018 17:46:27 -0700 Subject: [PATCH 12/39] try to fix an issue on windows platform The error message is from wxWidgets. It is possible caused by duplicated ID assigned to different windows. So this ci contains update with: ID for wxWindow: replace -1 with wxID_ANY to prevent potential conflict replace predefined menu id (e.g. TemplateLegend::ID_CATEGORY_COLOR = wxID_HIGHEST + 1;) with XRCID() generated id to prevent potential id conflict --- DialogTools/3DControlPan.h | 4 +-- DialogTools/AbstractClusterDlg.cpp | 2 +- DialogTools/AddIdVariable.h | 2 +- DialogTools/AdjustYAxisDlg.h | 4 +-- DialogTools/Bnd2ShpDlg.h | 4 +-- DialogTools/CreateGridDlg.h | 4 +-- DialogTools/CreatingWeightDlg.h | 4 +-- DialogTools/FieldNameCorrectionDlg.cpp | 4 +-- DialogTools/FieldNewCalcSheetDlg.h | 2 +- DialogTools/GeocodingDlg.cpp | 4 +-- DialogTools/HistIntervalDlg.h | 2 +- DialogTools/LisaWhat2OpenDlg.h | 6 ++-- DialogTools/PermutationCounterDlg.h | 4 +-- DialogTools/PreferenceDlg.cpp | 4 +-- DialogTools/ProjectInfoDlg.cpp | 4 +-- DialogTools/RandomizationDlg.cpp | 10 +++--- DialogTools/RegressionDlg.h | 4 +-- DialogTools/SaveToTableDlg.cpp | 10 +++--- DialogTools/SpatialJoinDlg.cpp | 6 ++-- DialogTools/VariableSettingsDlg.cpp | 4 +-- Explore/3DPlotView.cpp | 2 +- Explore/AbstractClusterMap.cpp | 4 +-- Explore/CartogramNewView.cpp | 4 +-- Explore/ColocationMapView.cpp | 4 +-- Explore/ConditionalClusterMapView.cpp | 8 ++--- Explore/ConditionalMapView.cpp | 2 +- Explore/ConnectivityMapView.cpp | 2 +- Explore/GetisOrdMapNewView.cpp | 4 +-- Explore/LineChartView.cpp | 2 +- Explore/LocalGearyMapNewView.cpp | 4 +-- Explore/MLJCMapNewView.cpp | 4 +-- Explore/MapLayerTree.cpp | 4 +-- Explore/MapLayoutView.cpp | 16 +++++----- Explore/MapNewView.cpp | 4 +-- Explore/PCPNewView.cpp | 2 +- Explore/ScatterNewPlotView.cpp | 6 ++-- GeneralWxUtils.cpp | 6 ++-- GeoDa.cpp | 42 ++++++++++++++------------ TemplateCanvas.cpp | 2 +- TemplateFrame.cpp | 2 +- TemplateLegend.cpp | 8 ++--- 41 files changed, 111 insertions(+), 109 deletions(-) diff --git a/DialogTools/3DControlPan.h b/DialogTools/3DControlPan.h index b509217be..3b596193a 100644 --- a/DialogTools/3DControlPan.h +++ b/DialogTools/3DControlPan.h @@ -35,7 +35,7 @@ class C3DControlPan: public wxPanel public: C3DControlPan( ); - C3DControlPan( wxWindow* parent, wxWindowID id = -1, + C3DControlPan( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxDEFAULT_DIALOG_STYLE, @@ -43,7 +43,7 @@ class C3DControlPan: public wxPanel const wxString& y3d_l = "Y", const wxString& z3d_l = "Z" ); - bool Create( wxWindow* parent, wxWindowID id = -1, + bool Create( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxDEFAULT_DIALOG_STYLE, diff --git a/DialogTools/AbstractClusterDlg.cpp b/DialogTools/AbstractClusterDlg.cpp index f958380f2..cf20e9c40 100644 --- a/DialogTools/AbstractClusterDlg.cpp +++ b/DialogTools/AbstractClusterDlg.cpp @@ -51,7 +51,7 @@ AbstractClusterDlg::AbstractClusterDlg(wxFrame* parent_s, Project* project_s, wxString title) : frames_manager(project_s->GetFramesManager()), table_state(project_s->GetTableState()), -wxDialog(NULL, -1, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER), +wxDialog(NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER), validator(wxFILTER_INCLUDE_CHAR_LIST), input_data(NULL), mask(NULL), weight(NULL), m_use_centroids(NULL), m_weight_centroids(NULL), m_wc_txt(NULL), chk_floor(NULL), combo_floor(NULL), txt_floor(NULL), txt_floor_pct(NULL), slider_floor(NULL), combo_var(NULL), m_reportbox(NULL), gal(NULL) { wxLogMessage("Open AbstractClusterDlg."); diff --git a/DialogTools/AddIdVariable.h b/DialogTools/AddIdVariable.h index 69ba9bee8..2e0d3a5c4 100644 --- a/DialogTools/AddIdVariable.h +++ b/DialogTools/AddIdVariable.h @@ -30,7 +30,7 @@ class TableInterface; class AddIdVariable: public wxDialog { public: AddIdVariable(TableInterface* table_int, - wxWindow* parent, wxWindowID id = -1, + wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Add New ID Variable"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/AdjustYAxisDlg.h b/DialogTools/AdjustYAxisDlg.h index c322fa2a5..8f8dbb306 100644 --- a/DialogTools/AdjustYAxisDlg.h +++ b/DialogTools/AdjustYAxisDlg.h @@ -32,7 +32,7 @@ class AdjustYAxisDlg: public wxDialog public: AdjustYAxisDlg( double min_val, double max_val, - wxWindow* parent, wxWindowID id = -1, + wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Adjust Values of Y Axis"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -61,7 +61,7 @@ class AxisLabelPrecisionDlg : public wxDialog{ public: AxisLabelPrecisionDlg( int precision, - wxWindow* parent, wxWindowID id = -1, + wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Set Display Precision on Axis"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/Bnd2ShpDlg.h b/DialogTools/Bnd2ShpDlg.h index ae9d0d4bf..2eaedbede 100644 --- a/DialogTools/Bnd2ShpDlg.h +++ b/DialogTools/Bnd2ShpDlg.h @@ -27,13 +27,13 @@ class Bnd2ShpDlg: public wxDialog public: Bnd2ShpDlg( ); - Bnd2ShpDlg( wxWindow* parent, wxWindowID id = -1, + Bnd2ShpDlg( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Convert Boundary to SHP"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxDEFAULT_DIALOG_STYLE ); - bool Create( wxWindow* parent, wxWindowID id = -1, + bool Create( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Convert Boundary to SHP"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/CreateGridDlg.h b/DialogTools/CreateGridDlg.h index cf21166e7..b4aba26e3 100644 --- a/DialogTools/CreateGridDlg.h +++ b/DialogTools/CreateGridDlg.h @@ -30,13 +30,13 @@ class CreateGridDlg: public wxDialog public: ~CreateGridDlg( ); - CreateGridDlg( wxWindow* parent, wxWindowID id = -1, + CreateGridDlg( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Creating Grid"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxDEFAULT_DIALOG_STYLE ); - bool Create( wxWindow* parent, wxWindowID id = -1, + bool Create( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Creating Grid"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/CreatingWeightDlg.h b/DialogTools/CreatingWeightDlg.h index 96b5cf4a2..e7efa9d45 100644 --- a/DialogTools/CreatingWeightDlg.h +++ b/DialogTools/CreatingWeightDlg.h @@ -52,14 +52,14 @@ public TableStateObserver, public WeightsManStateObserver CreatingWeightDlg(wxWindow* parent, Project* project, bool user_xy = false, - wxWindowID id = -1, + wxWindowID id = wxID_ANY, const wxString& caption = _("Weights File Creation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxDEFAULT_DIALOG_STYLE ); virtual ~CreatingWeightDlg(); void OnClose(wxCloseEvent& ev); - bool Create(wxWindow* parent, wxWindowID id = -1, + bool Create(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Weights File Creation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/FieldNameCorrectionDlg.cpp b/DialogTools/FieldNameCorrectionDlg.cpp index 0a15d8d14..d0508e0b4 100644 --- a/DialogTools/FieldNameCorrectionDlg.cpp +++ b/DialogTools/FieldNameCorrectionDlg.cpp @@ -604,7 +604,7 @@ FieldNameCorrectionDlg:: FieldNameCorrectionDlg(GdaConst::DataSourceType ds_type, vector& all_fname, wxString title) -: wxDialog(NULL, -1, title, wxDefaultPosition, wxDefaultSize,wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) +: wxDialog(NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize,wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) { wxPanel *panel = new wxPanel(this); @@ -647,7 +647,7 @@ FieldNameCorrectionDlg(GdaConst::DataSourceType ds_type, set& dup_fname, set& bad_fname, wxString title) -: wxDialog(NULL, -1, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) +: wxDialog(NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) { wxLogMessage("Open FieldNameCorrectionDlg:"); diff --git a/DialogTools/FieldNewCalcSheetDlg.h b/DialogTools/FieldNewCalcSheetDlg.h index 2de4169eb..8167a0f09 100644 --- a/DialogTools/FieldNewCalcSheetDlg.h +++ b/DialogTools/FieldNewCalcSheetDlg.h @@ -51,7 +51,7 @@ class FieldNewCalcSheetDlg: public wxDialog, public FramesManagerObserver, long style = wxDEFAULT_DIALOG_STYLE ); virtual ~FieldNewCalcSheetDlg(); - bool Create( wxWindow* parent, wxWindowID id = -1, + bool Create( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Var Calc Container"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/GeocodingDlg.cpp b/DialogTools/GeocodingDlg.cpp index 24ddf0fad..5ba2bd80c 100644 --- a/DialogTools/GeocodingDlg.cpp +++ b/DialogTools/GeocodingDlg.cpp @@ -50,7 +50,7 @@ END_EVENT_TABLE() using namespace std; GeocodingDlg::GeocodingDlg(wxWindow* parent, Project* p, const wxString& title, const wxPoint& pos, const wxSize& size ) -: wxDialog(NULL, -1, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER), +: wxDialog(NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER), frames_manager(p->GetFramesManager()), project(p), table_int(p->GetTableInt()), table_state(p->GetTableState()), t(NULL), stop(false) { wxLogMessage("Open GeocodingDlg()."); @@ -122,7 +122,7 @@ void GeocodingDlg::CreateControls() // parameters wxNotebook* notebook = new wxNotebook(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize); - wxNotebookPage* google_page = new wxNotebookPage(notebook, -1, wxDefaultPosition, wxSize(560, 180)); + wxNotebookPage* google_page = new wxNotebookPage(notebook, wxID_ANY, wxDefaultPosition, wxSize(560, 180)); notebook->AddPage(google_page, _("Google Places API")); wxFlexGridSizer* gbox = new wxFlexGridSizer(5,1,10,0); diff --git a/DialogTools/HistIntervalDlg.h b/DialogTools/HistIntervalDlg.h index 8007e2829..96605fc9a 100644 --- a/DialogTools/HistIntervalDlg.h +++ b/DialogTools/HistIntervalDlg.h @@ -32,7 +32,7 @@ class HistIntervalDlg: public wxDialog HistIntervalDlg( int min_intervals, int default_num_intervals, int max_intervals, - wxWindow* parent, wxWindowID id = -1, + wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Intervals in the Histogram"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/LisaWhat2OpenDlg.h b/DialogTools/LisaWhat2OpenDlg.h index 414ba3935..c68fc6bb5 100644 --- a/DialogTools/LisaWhat2OpenDlg.h +++ b/DialogTools/LisaWhat2OpenDlg.h @@ -26,7 +26,7 @@ class LisaWhat2OpenDlg: public wxDialog DECLARE_EVENT_TABLE() public: - LisaWhat2OpenDlg( wxWindow* parent, wxWindowID id = -1, + LisaWhat2OpenDlg( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("What windows to open?"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -53,7 +53,7 @@ class GetisWhat2OpenDlg: public wxDialog public: GetisWhat2OpenDlg( wxWindow* parent, bool show_row_stand = true, - wxWindowID id = -1, + wxWindowID id = wxID_ANY, const wxString& caption = _("What windows to open?"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -82,7 +82,7 @@ class LocalGearyWhat2OpenDlg: public wxDialog DECLARE_EVENT_TABLE() public: - LocalGearyWhat2OpenDlg( wxWindow* parent, wxWindowID id = -1, + LocalGearyWhat2OpenDlg( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("What windows to open?"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/PermutationCounterDlg.h b/DialogTools/PermutationCounterDlg.h index 4e1d2c959..9d02b034b 100644 --- a/DialogTools/PermutationCounterDlg.h +++ b/DialogTools/PermutationCounterDlg.h @@ -29,13 +29,13 @@ class PermutationCounterDlg: public wxDialog public: PermutationCounterDlg( ); - PermutationCounterDlg( wxWindow* parent, wxWindowID id = -1, + PermutationCounterDlg( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption=_("Set Number of Permutation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxDEFAULT_DIALOG_STYLE ); - bool Create( wxWindow* parent, wxWindowID id = -1, + bool Create( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Set Number of Permutation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/PreferenceDlg.cpp b/DialogTools/PreferenceDlg.cpp index 10400afc3..75261d553 100644 --- a/DialogTools/PreferenceDlg.cpp +++ b/DialogTools/PreferenceDlg.cpp @@ -102,7 +102,7 @@ void PreferenceDlg::Init() wxNotebook* notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); // visualization tab - wxNotebookPage* vis_page = new wxNotebookPage(notebook, -1, wxDefaultPosition, wxSize(560, 680)); + wxNotebookPage* vis_page = new wxNotebookPage(notebook, wxID_ANY, wxDefaultPosition, wxSize(560, 680)); #ifdef __WIN32__ vis_page->SetBackgroundColour(*wxWHITE); #endif @@ -385,7 +385,7 @@ void PreferenceDlg::Init() wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); - wxButton *resetButton = new wxButton(this, -1, _("Reset"), wxDefaultPosition, wxSize(70, 30)); + wxButton *resetButton = new wxButton(this, wxID_ANY, _("Reset"), wxDefaultPosition, wxSize(70, 30)); wxButton *closeButton = new wxButton(this, wxID_OK, _("Close"), wxDefaultPosition, wxSize(70, 30)); resetButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &PreferenceDlg::OnReset, this); diff --git a/DialogTools/ProjectInfoDlg.cpp b/DialogTools/ProjectInfoDlg.cpp index 7643d8484..14e286ca8 100644 --- a/DialogTools/ProjectInfoDlg.cpp +++ b/DialogTools/ProjectInfoDlg.cpp @@ -25,7 +25,7 @@ #include "ProjectInfoDlg.h" ProjectInfoDlg::ProjectInfoDlg(Project* project) -: wxDialog(0, -1, "Project Information", wxDefaultPosition, wxSize(250, 150)) +: wxDialog(NULL, wxID_ANY, "Project Information", wxDefaultPosition, wxSize(250, 150)) { wxLogMessage("Open ProjectInfoDlg."); @@ -121,7 +121,7 @@ ProjectInfoDlg::ProjectInfoDlg(Project* project) s << key[i] << ": " << val[i]; wxStaticText* st; wxPoint pos(left_offset, top_offset + i*line_space); - st = new wxStaticText(panel, -1, s, pos, wxDefaultSize, wxALIGN_LEFT); + st = new wxStaticText(panel, wxID_ANY, s, pos, wxDefaultSize, wxALIGN_LEFT); } diff --git a/DialogTools/RandomizationDlg.cpp b/DialogTools/RandomizationDlg.cpp index e132e9312..dcb4df2e2 100644 --- a/DialogTools/RandomizationDlg.cpp +++ b/DialogTools/RandomizationDlg.cpp @@ -74,17 +74,17 @@ InferenceSettingsDlg::InferenceSettingsDlg(wxWindow* parent, // Parameters wxFlexGridSizer* gbox = new wxFlexGridSizer(9,2,10,0); - m_rdo_1 = new wxRadioButton(panel, -1, _("Bonferroni bound:"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); + m_rdo_1 = new wxRadioButton(panel, wxID_ANY, _("Bonferroni bound:"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); m_txt_bo = new wxStaticText(panel, wxID_ANY, _(""), wxDefaultPosition, wxSize(150,-1)); gbox->Add(m_rdo_1, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, 10); gbox->Add(m_txt_bo, 1, wxEXPAND); - m_rdo_2 = new wxRadioButton(panel, -1, _("False Discovery Rate:"), wxDefaultPosition, wxDefaultSize); + m_rdo_2 = new wxRadioButton(panel, wxID_ANY, _("False Discovery Rate:"), wxDefaultPosition, wxDefaultSize); m_txt_fdr = new wxStaticText(panel, wxID_ANY, _(""), wxDefaultPosition, wxSize(150,-1)); gbox->Add(m_rdo_2, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, 10); gbox->Add(m_txt_fdr, 1, wxEXPAND); - m_rdo_3 = new wxRadioButton(panel, -1, _("Input significance:"), wxDefaultPosition, wxDefaultSize); + m_rdo_3 = new wxRadioButton(panel, wxID_ANY, _("Input significance:"), wxDefaultPosition, wxDefaultSize); m_txt_pval = new wxTextCtrl(panel, XRCID("ID_INFERENCE_TCTRL"), p_str, wxDefaultPosition, wxSize(100,-1),wxTE_PROCESS_ENTER); m_txt_pval->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); Connect(XRCID("ID_INFERENCE_TCTRL"), wxEVT_TEXT, @@ -245,7 +245,7 @@ num_obs(raw_data1_s.size()), Permutations(NumPermutations), MoranI(NumPermutations, 0), is_bivariate(false), -wxPanel(parent, -1, wxDefaultPosition, size) +wxPanel(parent, wxID_ANY, wxDefaultPosition, size) { SetBackgroundStyle(wxBG_STYLE_CUSTOM); @@ -275,7 +275,7 @@ undefs(undefs_s), W(W_s), num_obs(raw_data1_s.size()), Permutations(NumPermutations), MoranI(NumPermutations, 0), is_bivariate(true), -wxPanel(parent, -1, wxDefaultPosition, size) +wxPanel(parent, wxID_ANY, wxDefaultPosition, size) { SetBackgroundStyle(wxBG_STYLE_CUSTOM); diff --git a/DialogTools/RegressionDlg.h b/DialogTools/RegressionDlg.h index ce6f6fb12..e5e36387f 100644 --- a/DialogTools/RegressionDlg.h +++ b/DialogTools/RegressionDlg.h @@ -49,14 +49,14 @@ class RegressionDlg: public wxDialog, public FramesManagerObserver, RegressionDlg(Project* project, wxWindow* parent, wxString title = _("Regression"), - wxWindowID id = -1, + wxWindowID id = wxID_ANY, const wxString& caption = _("Regression"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxDEFAULT_DIALOG_STYLE ); virtual ~RegressionDlg(); - bool Create( wxWindow* parent, wxWindowID id = -1, + bool Create( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = _("Regression"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/DialogTools/SaveToTableDlg.cpp b/DialogTools/SaveToTableDlg.cpp index 6133f7043..057652fcf 100644 --- a/DialogTools/SaveToTableDlg.cpp +++ b/DialogTools/SaveToTableDlg.cpp @@ -34,11 +34,11 @@ #include "../Project.h" #include "SaveToTableDlg.h" -const int ID_ADD_BUTTON = wxID_HIGHEST+1; -const int ID_FIELD_CHOICE = wxID_HIGHEST+2; -const int ID_TIME_CHOICE = wxID_HIGHEST+3; -const int ID_CHECK = wxID_HIGHEST+4; -const int ID_FIELD_TEXT = wxID_HIGHEST+5; +const int ID_ADD_BUTTON = XRCID("SAVETOTABLEDLG_ADD_BUTTON"); +const int ID_FIELD_CHOICE = XRCID("SAVETOTABLEDLG_FIELD_CHOICE"); +const int ID_TIME_CHOICE = XRCID("SAVETOTABLEDLG_TIME_CHOICE"); +const int ID_CHECK = XRCID("SAVETOTABLEDLG_CHECK"); +const int ID_FIELD_TEXT = XRCID("SAVETOTABLEDLG_FIELD_TEXT"); BEGIN_EVENT_TABLE( SaveToTableDlg, wxDialog ) EVT_CHECKBOX( ID_CHECK, SaveToTableDlg::OnCheck ) diff --git a/DialogTools/SpatialJoinDlg.cpp b/DialogTools/SpatialJoinDlg.cpp index a0653b79e..3ab088057 100644 --- a/DialogTools/SpatialJoinDlg.cpp +++ b/DialogTools/SpatialJoinDlg.cpp @@ -154,17 +154,17 @@ void AssignPolygonToPoint::sub_run(int start, int end) SpatialJoinDlg::SpatialJoinDlg(wxWindow* parent, Project* _project) -: wxDialog(parent, -1, "Spatial Join", wxDefaultPosition, wxSize(350, 250)) +: wxDialog(parent, wxID_ANY, "Spatial Join", wxDefaultPosition, wxSize(350, 250)) { project = _project; panel = new wxPanel(this, -1); wxString info = _("Please select a map layer to apply spatial join to current map (%s):"); info = wxString::Format(info, project->GetProjectTitle()); - wxStaticText* st = new wxStaticText(panel, -1, info); + wxStaticText* st = new wxStaticText(panel, wxID_ANY, info); map_list = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(160,-1)); - field_st = new wxStaticText(panel, -1, "Select ID Variable (Optional)"); + field_st = new wxStaticText(panel, wxID_ANY, "Select ID Variable (Optional)"); field_list = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(100,-1)); wxBoxSizer* mbox = new wxBoxSizer(wxHORIZONTAL); mbox->Add(map_list, 0, wxALIGN_CENTER | wxALL, 5); diff --git a/DialogTools/VariableSettingsDlg.cpp b/DialogTools/VariableSettingsDlg.cpp index 4ace2ebbf..a1d589912 100644 --- a/DialogTools/VariableSettingsDlg.cpp +++ b/DialogTools/VariableSettingsDlg.cpp @@ -52,7 +52,7 @@ // //////////////////////////////////////////////////////////////////////////// DiffMoranVarSettingDlg::DiffMoranVarSettingDlg(Project* project_s) - : wxDialog(NULL, -1, _("Differential Moran Variable Settings"), wxDefaultPosition, wxSize(590, 230)) + : wxDialog(NULL, wxID_ANY, _("Differential Moran Variable Settings"), wxDefaultPosition, wxSize(590, 230)) { wxLogMessage("Open DiffMoranVarSettingDlg."); @@ -298,7 +298,7 @@ boost::uuids::uuid DiffMoranVarSettingDlg::GetWeightsId() //////////////////////////////////////////////////////////////////////////// MultiVariableSettingsDlg::MultiVariableSettingsDlg(Project* project_s) - : wxDialog(NULL, -1, _("Multi-Variable Settings"), wxDefaultPosition, wxSize(320, 430)) + : wxDialog(NULL, wxID_ANY, _("Multi-Variable Settings"), wxDefaultPosition, wxSize(320, 430)) { wxLogMessage("Entering MultiVariableSettingsDlg::MultiVariableSettingsDlg()."); diff --git a/Explore/3DPlotView.cpp b/Explore/3DPlotView.cpp index 1c7f25846..7494d171e 100644 --- a/Explore/3DPlotView.cpp +++ b/Explore/3DPlotView.cpp @@ -1102,7 +1102,7 @@ C3DPlotFrame::C3DPlotFrame(wxFrame *parent, Project* project, var_info, col_ids, m_splitter); - control = new C3DControlPan(m_splitter, -1, wxDefaultPosition, + control = new C3DControlPan(m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxCAPTION|wxDEFAULT_DIALOG_STYLE); control->template_frame = this; m_splitter->SplitVertically(control, canvas, 70); diff --git a/Explore/AbstractClusterMap.cpp b/Explore/AbstractClusterMap.cpp index 870f07810..8ddfec286 100644 --- a/Explore/AbstractClusterMap.cpp +++ b/Explore/AbstractClusterMap.cpp @@ -448,7 +448,7 @@ a_coord(a_coordinator) void AbstractMapFrame::Init() { - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); @@ -476,7 +476,7 @@ void AbstractMapFrame::Init() splitter_win->SplitVertically(lpanel, rpanel, GdaConst::map_default_legend_width); - wxPanel* toolbar_panel = new wxPanel(this,-1, wxDefaultPosition); + wxPanel* toolbar_panel = new wxPanel(this,wxID_ANY, wxDefaultPosition); wxBoxSizer* toolbar_sizer= new wxBoxSizer(wxVERTICAL); toolbar = wxXmlResource::Get()->LoadToolBar(toolbar_panel, "ToolBar_MAP"); SetupToolbar(); diff --git a/Explore/CartogramNewView.cpp b/Explore/CartogramNewView.cpp index aef47968d..30909830f 100644 --- a/Explore/CartogramNewView.cpp +++ b/Explore/CartogramNewView.cpp @@ -956,7 +956,7 @@ CartogramNewFrame::CartogramNewFrame(wxFrame *parent, Project* project, int width, height; GetClientSize(&width, &height); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); @@ -983,7 +983,7 @@ CartogramNewFrame::CartogramNewFrame(wxFrame *parent, Project* project, splitter_win->SplitVertically(lpanel, rpanel, GdaConst::map_default_legend_width); - wxPanel* toolbar_panel = new wxPanel(this,-1, wxDefaultPosition); + wxPanel* toolbar_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition); wxBoxSizer* toolbar_sizer= new wxBoxSizer(wxVERTICAL); toolbar = wxXmlResource::Get()->LoadToolBar(toolbar_panel, "ToolBar_MAP"); SetupToolbar(); diff --git a/Explore/ColocationMapView.cpp b/Explore/ColocationMapView.cpp index 5684c9be7..f43fd71ef 100644 --- a/Explore/ColocationMapView.cpp +++ b/Explore/ColocationMapView.cpp @@ -721,7 +721,7 @@ ColocationMapFrame::ColocationMapFrame(wxFrame *parent, Project* project, vector int width, height; GetClientSize(&width, &height); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); + wxSplitterWindow* splitter_win = new wxSplitterWindow(this,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); CatClassification::CatClassifType theme_type_s = CatClassification::colocation; @@ -743,7 +743,7 @@ ColocationMapFrame::ColocationMapFrame(wxFrame *parent, Project* project, vector splitter_win->SplitVertically(lpanel, rpanel, GdaConst::map_default_legend_width); - wxPanel* toolbar_panel = new wxPanel(this,-1, wxDefaultPosition); + wxPanel* toolbar_panel = new wxPanel(this,wxID_ANY, wxDefaultPosition); wxBoxSizer* toolbar_sizer= new wxBoxSizer(wxVERTICAL); toolbar = wxXmlResource::Get()->LoadToolBar(toolbar_panel, "ToolBar_MAP"); SetupToolbar(); diff --git a/Explore/ConditionalClusterMapView.cpp b/Explore/ConditionalClusterMapView.cpp index a309c834f..a0973ac35 100644 --- a/Explore/ConditionalClusterMapView.cpp +++ b/Explore/ConditionalClusterMapView.cpp @@ -702,7 +702,7 @@ ConditionalClusterMapFrame(wxFrame *parent, Project* project, GetClientSize(&width, &height); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); @@ -756,7 +756,7 @@ ConditionalClusterMapFrame(wxFrame *parent, Project* project, GetClientSize(&width, &height); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); @@ -808,7 +808,7 @@ ConditionalClusterMapFrame(wxFrame *parent, Project* project, GetClientSize(&width, &height); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); @@ -860,7 +860,7 @@ ConditionalClusterMapFrame(wxFrame *parent, Project* project, GetClientSize(&width, &height); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); diff --git a/Explore/ConditionalMapView.cpp b/Explore/ConditionalMapView.cpp index 67184268b..25218dbbb 100644 --- a/Explore/ConditionalMapView.cpp +++ b/Explore/ConditionalMapView.cpp @@ -895,7 +895,7 @@ ConditionalMapFrame::ConditionalMapFrame(wxFrame *parent, Project* project, GetClientSize(&width, &height); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); diff --git a/Explore/ConnectivityMapView.cpp b/Explore/ConnectivityMapView.cpp index 5c3986ef5..46bd60c2b 100644 --- a/Explore/ConnectivityMapView.cpp +++ b/Explore/ConnectivityMapView.cpp @@ -568,7 +568,7 @@ ConnectivityMapFrame::ConnectivityMapFrame(wxFrame *parent, Project* project, rbox->Add(template_canvas, 1, wxEXPAND); rpanel->SetSizer(rbox); - wxPanel* toolbar_panel = new wxPanel(this,-1, wxDefaultPosition); + wxPanel* toolbar_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition); wxBoxSizer* toolbar_sizer= new wxBoxSizer(wxVERTICAL); toolbar = wxXmlResource::Get()->LoadToolBar(toolbar_panel, "ToolBar_MAP"); toolbar->EnableTool(XRCID("ID_SELECT_INVERT"), false); diff --git a/Explore/GetisOrdMapNewView.cpp b/Explore/GetisOrdMapNewView.cpp index c1ec16122..edd1ba85a 100644 --- a/Explore/GetisOrdMapNewView.cpp +++ b/Explore/GetisOrdMapNewView.cpp @@ -540,7 +540,7 @@ row_standardize(row_standardize_s) DisplayStatusBar(true); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); @@ -577,7 +577,7 @@ row_standardize(row_standardize_s) splitter_win->SplitVertically(lpanel, rpanel, GdaConst::map_default_legend_width); - wxPanel* toolbar_panel = new wxPanel(this,-1, wxDefaultPosition); + wxPanel* toolbar_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition); wxBoxSizer* toolbar_sizer= new wxBoxSizer(wxVERTICAL); toolbar = wxXmlResource::Get()->LoadToolBar(toolbar_panel, "ToolBar_MAP"); SetupToolbar(); diff --git a/Explore/LineChartView.cpp b/Explore/LineChartView.cpp index f70fe8995..788601171 100644 --- a/Explore/LineChartView.cpp +++ b/Explore/LineChartView.cpp @@ -115,7 +115,7 @@ fixed_scale_over_change(true) */ SetBackgroundColour(*wxWHITE); wxSplitterWindow* splitter_win = 0; - splitter_win = new wxSplitterWindow(this,-1, wxDefaultPosition, + splitter_win = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_THIN_SASH |wxSP_NOBORDER | wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); diff --git a/Explore/LocalGearyMapNewView.cpp b/Explore/LocalGearyMapNewView.cpp index ef54ecd76..f9fdab281 100644 --- a/Explore/LocalGearyMapNewView.cpp +++ b/Explore/LocalGearyMapNewView.cpp @@ -645,7 +645,7 @@ local_geary_coord(local_geary_coordinator) int width, height; GetClientSize(&width, &height); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); @@ -680,7 +680,7 @@ local_geary_coord(local_geary_coordinator) splitter_win->SplitVertically(lpanel, rpanel, GdaConst::map_default_legend_width); - wxPanel* toolbar_panel = new wxPanel(this,-1, wxDefaultPosition); + wxPanel* toolbar_panel = new wxPanel(this,wxID_ANY, wxDefaultPosition); wxBoxSizer* toolbar_sizer= new wxBoxSizer(wxVERTICAL); toolbar = wxXmlResource::Get()->LoadToolBar(toolbar_panel, "ToolBar_MAP"); SetupToolbar(); diff --git a/Explore/MLJCMapNewView.cpp b/Explore/MLJCMapNewView.cpp index ca39f4cfb..2c01e5f35 100644 --- a/Explore/MLJCMapNewView.cpp +++ b/Explore/MLJCMapNewView.cpp @@ -508,7 +508,7 @@ is_clust(isClusterMap) DisplayStatusBar(true); - wxSplitterWindow* splitter_win = new wxSplitterWindow(this,-1, + wxSplitterWindow* splitter_win = new wxSplitterWindow(this,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); @@ -534,7 +534,7 @@ is_clust(isClusterMap) splitter_win->SplitVertically(lpanel, rpanel, GdaConst::map_default_legend_width); - wxPanel* toolbar_panel = new wxPanel(this,-1, wxDefaultPosition); + wxPanel* toolbar_panel = new wxPanel(this,wxID_ANY, wxDefaultPosition); wxBoxSizer* toolbar_sizer= new wxBoxSizer(wxVERTICAL); toolbar = wxXmlResource::Get()->LoadToolBar(toolbar_panel, "ToolBar_MAP"); SetupToolbar(); diff --git a/Explore/MapLayerTree.cpp b/Explore/MapLayerTree.cpp index 76f3dea01..299b8cfe3 100644 --- a/Explore/MapLayerTree.cpp +++ b/Explore/MapLayerTree.cpp @@ -25,7 +25,7 @@ wxString SetAssociationDlg::LAYER_LIST_ID = "SETASSOCIATIONDLG_LAYER_LIST"; SetAssociationDlg::SetAssociationDlg(wxWindow* parent, AssociateLayerInt* ml,vector& _all_layers, const wxString& title, const wxPoint& pos, const wxSize& size) -: wxDialog(parent, -1, title, pos, size) +: wxDialog(parent, wxID_ANY, title, pos, size) { current_ml = ml; all_layers = _all_layers; @@ -1014,7 +1014,7 @@ void MapTree::AddCategoryColorToMenu(wxMenu* menu, int cat_clicked) } MapTreeFrame::MapTreeFrame(wxWindow* parent, MapCanvas* _canvas, const wxPoint& pos, const wxSize& size) -: wxFrame(parent, -1, _canvas->GetCanvasTitle(), pos, size) +: wxFrame(parent, wxID_ANY, _canvas->GetCanvasTitle(), pos, size) { SetIcon(wxIcon(GeoDaIcon_16x16_xpm)); SetBackgroundColour(*wxWHITE); diff --git a/Explore/MapLayoutView.cpp b/Explore/MapLayoutView.cpp index 8eb40d993..5b36cfad8 100644 --- a/Explore/MapLayoutView.cpp +++ b/Explore/MapLayoutView.cpp @@ -17,7 +17,7 @@ using namespace std; CanvasExportSettingDialog::CanvasExportSettingDialog(int w, int h, const wxString & title) -: wxDialog(NULL, -1, title, wxDefaultPosition, wxSize(320, 230)) +: wxDialog(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(320, 230)) { width = w; height = h; @@ -32,13 +32,13 @@ CanvasExportSettingDialog::CanvasExportSettingDialog(int w, int h, const wxStrin wxFlexGridSizer *fgs = new wxFlexGridSizer(3, 3, 9, 25); - wxStaticText *thetitle = new wxStaticText(panel, -1, _("Width:")); - wxStaticText *author = new wxStaticText(panel, -1, _("Height:")); - wxStaticText *review = new wxStaticText(panel, -1, _("Resolution(dpi):")); + wxStaticText *thetitle = new wxStaticText(panel, wxID_ANY, _("Width:")); + wxStaticText *author = new wxStaticText(panel, wxID_ANY, _("Height:")); + wxStaticText *review = new wxStaticText(panel, wxID_ANY, _("Resolution(dpi):")); - tc1 = new wxTextCtrl(panel, -1, wxString::Format("%d", w)); - tc2 = new wxTextCtrl(panel, -1, wxString::Format("%d", h)); - tc3 = new wxTextCtrl(panel, -1, "300"); + tc1 = new wxTextCtrl(panel, wxID_ANY, wxString::Format("%d", w)); + tc2 = new wxTextCtrl(panel, wxID_ANY, wxString::Format("%d", h)); + tc3 = new wxTextCtrl(panel, wxID_ANY, "300"); wxString choices[] = {_("pixels"), _("inches"), _("mm")}; m_unit = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(100,-1), 3, choices); @@ -308,7 +308,7 @@ void CanvasLayoutEvtHandler::OnEndSize(double w, double h) CanvasLayoutDialog::CanvasLayoutDialog(wxString _project_name, TemplateLegend* _legend, TemplateCanvas* _canvas, const wxString& title, const wxPoint& pos, const wxSize& size) -: wxDialog(NULL, -1, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ) +: wxDialog(NULL, wxID_ANY, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ) { legend_shape = NULL; diff --git a/Explore/MapNewView.cpp b/Explore/MapNewView.cpp index 956607a2b..443251083 100644 --- a/Explore/MapNewView.cpp +++ b/Explore/MapNewView.cpp @@ -2991,7 +2991,7 @@ no_update_weights(false) GetClientSize(&width, &height); wxSplitterWindow* splitter_win = 0; - splitter_win = new wxSplitterWindow(this,-1, wxDefaultPosition, wxDefaultSize, wxSP_3D |wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); + splitter_win = new wxSplitterWindow(this,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D |wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); wxPanel* rpanel = new wxPanel(splitter_win); @@ -3022,7 +3022,7 @@ no_update_weights(false) splitter_win->SplitVertically(lpanel, rpanel, GdaConst::map_default_legend_width); - wxPanel* toolbar_panel = new wxPanel(this,-1, wxDefaultPosition); + wxPanel* toolbar_panel = new wxPanel(this,wxID_ANY, wxDefaultPosition); wxBoxSizer* toolbar_sizer= new wxBoxSizer(wxVERTICAL); toolbar = wxXmlResource::Get()->LoadToolBar(toolbar_panel, "ToolBar_MAP"); SetupToolbar(); diff --git a/Explore/PCPNewView.cpp b/Explore/PCPNewView.cpp index 6c39e4bad..0458cadb0 100644 --- a/Explore/PCPNewView.cpp +++ b/Explore/PCPNewView.cpp @@ -1136,7 +1136,7 @@ col_ids(_col_ids) GetClientSize(&width, &height); wxSplitterWindow* splitter_win = 0; - splitter_win = new wxSplitterWindow(this,-1, + splitter_win = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); diff --git a/Explore/ScatterNewPlotView.cpp b/Explore/ScatterNewPlotView.cpp index 8678b8137..f7fbc7df6 100644 --- a/Explore/ScatterNewPlotView.cpp +++ b/Explore/ScatterNewPlotView.cpp @@ -52,7 +52,7 @@ BubbleSizeSliderDlg::BubbleSizeSliderDlg (ScatterNewPlotCanvas* _canvas, const wxString & caption ) -: wxDialog( NULL, -1, caption, wxDefaultPosition, wxDefaultSize) +: wxDialog( NULL, wxID_ANY, caption, wxDefaultPosition, wxDefaultSize) { wxLogMessage("Open BubbleSizeDlg."); @@ -1917,7 +1917,7 @@ void ScatterNewPlotFrame::Init(const std::vector& var_info wxSplitterWindow* splitter_win = 0; if (is_bubble_plot) { - splitter_win = new wxSplitterWindow(this,-1,wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); + splitter_win = new wxSplitterWindow(this,wxID_ANY,wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); } wxPanel* rpanel = NULL; @@ -2321,7 +2321,7 @@ MDSPlotFrame::MDSPlotFrame(wxFrame *parent, Project* project, const std::vector< GetClientSize(&width, &height); wxSplitterWindow* splitter_win = 0; if (is_bubble_plot) { - splitter_win = new wxSplitterWindow(this,-1,wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); + splitter_win = new wxSplitterWindow(this,wxID_ANY,wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN); splitter_win->SetMinimumPaneSize(10); } template_canvas = new MDSPlotCanvas(this, this, project, diff --git a/GeneralWxUtils.cpp b/GeneralWxUtils.cpp index 16ca14022..b3dd27501 100644 --- a/GeneralWxUtils.cpp +++ b/GeneralWxUtils.cpp @@ -85,20 +85,20 @@ void SimpleReportTextCtrl::OnSaveClick( wxCommandEvent& event ) //////////////////////////////////////////////////////////////////////// ScrolledDetailMsgDialog::ScrolledDetailMsgDialog(const wxString & title, const wxString & msg, const wxString & details, const wxSize &size, const wxArtID & art_id) -: wxDialog(NULL, -1, title, wxDefaultPosition, size, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +: wxDialog(NULL, wxID_ANY, title, wxDefaultPosition, size, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { wxPanel *panel = new wxPanel(this, -1); wxBoxSizer *vbox0 = new wxBoxSizer(wxVERTICAL); - wxStaticText *st = new wxStaticText(panel, -1, msg, wxDefaultPosition, wxDefaultSize, wxTE_WORDWRAP); + wxStaticText *st = new wxStaticText(panel, wxID_ANY, msg, wxDefaultPosition, wxDefaultSize, wxTE_WORDWRAP); tc = new SimpleReportTextCtrl(panel, XRCID("ID_TEXTCTRL_1"), details, wxDefaultPosition, wxSize(-1, 300)); vbox0->Add(st, 0, wxBOTTOM, 10); vbox0->Add(tc, 1, wxEXPAND); wxBoxSizer *hbox0 = new wxBoxSizer(wxHORIZONTAL); wxBitmap save = wxArtProvider::GetBitmap(wxART_WARNING); - wxStaticBitmap *warn = new wxStaticBitmap(panel, -1, save); + wxStaticBitmap *warn = new wxStaticBitmap(panel, wxID_ANY, save); hbox0->Add(warn, 0, wxRIGHT, 5); hbox0->Add(vbox0, 1); diff --git a/GeoDa.cpp b/GeoDa.cpp index f6b3ffdb5..892cff35f 100644 --- a/GeoDa.cpp +++ b/GeoDa.cpp @@ -197,8 +197,6 @@ // the application binary. extern void GdaInitXmlResource(); -const int ID_TEST_MAP_FRAME = wxID_HIGHEST + 10; - IMPLEMENT_APP(GdaApp) GdaApp::GdaApp() : m_pLogFile(0) @@ -399,7 +397,8 @@ bool GdaApp::OnInit(void) #ifdef __DEBUG__ wxLog::SetLogLevel(wxLOG_Message); #endif - wxLogMessage(GeneralWxUtils::LogOsId()); + wxString os_id = GeneralWxUtils::LogOsId(); + wxLogMessage(os_id); wxString versionlog = wxString::Format("vs: %d-%d-%d-%d", Gda::version_major, Gda::version_minor, @@ -414,6 +413,11 @@ bool GdaApp::OnInit(void) wxArrayString fnames; fnames.Add(proj_fname); MacOpenFiles(fnames); + } else { + if (os_id != "\nos: 1-10-14") { + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, XRCID("ID_NEW_PROJECT")); + frame->GetEventHandler()->ProcessEvent(ev); + } } return true; @@ -709,7 +713,7 @@ void GdaFrame::SetMenusToDefault() GdaFrame::GdaFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style) -: wxFrame(NULL, -1, title, pos, size, style) +: wxFrame(NULL, wxID_ANY, title, pos, size, style) { SetBackgroundColour(*wxWHITE); SetIcon(wxIcon(GeoDaIcon_16x16_xpm)); @@ -742,7 +746,7 @@ GdaFrame::GdaFrame(const wxString& title, const wxPoint& pos, UpdateToolbarAndMenus(); SetEncodingCheckmarks(wxFONTENCODING_UTF8); - CallAfter(&GdaFrame::ShowOpenDatasourceDlg,wxPoint(80, 220),true); + //CallAfter(&GdaFrame::ShowOpenDatasourceDlg,wxPoint(80, 220),true); // check update in a new thread if (GdaConst::disable_auto_upgrade == false) { @@ -1380,18 +1384,6 @@ void GdaFrame::InitWithProject(wxString gda_file_path) tf->Raise(); } - SetProjectOpen(true); - UpdateToolbarAndMenus(); - - // Associate Project with Calculator if open - wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); - while (node) { - wxWindow* win = node->GetData(); - if (CalculatorDlg* w = dynamic_cast(win)) { - w->ConnectToProject(GetProject()); - } - node = node->GetNext(); - } if (!project_p->IsTableOnlyProject()) { std::vector col_ids; @@ -1409,8 +1401,19 @@ void GdaFrame::InitWithProject(wxString gda_file_path) wxPoint(80,160), GdaConst::map_default_size); nf->UpdateTitle(); - nf->Show(true); - nf->Raise(); + } + + SetProjectOpen(true); + UpdateToolbarAndMenus(); + + // Associate Project with Calculator if open + wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); + while (node) { + wxWindow* win = node->GetData(); + if (CalculatorDlg* w = dynamic_cast(win)) { + w->ConnectToProject(GetProject()); + } + node = node->GetNext(); } } @@ -6676,7 +6679,6 @@ BEGIN_EVENT_TABLE(GdaFrame, wxFrame) EVT_BUTTON(XRCID("IDM_BUBBLECHART"), GdaFrame::OnExploreBubbleChart) EVT_BUTTON(XRCID("IDM_SCATTERPLOT_MAT"), GdaFrame::OnExploreScatterPlotMat) EVT_BUTTON(XRCID("IDM_COV_SCATTERPLOT"), GdaFrame::OnExploreCovScatterPlot) - EVT_MENU(ID_TEST_MAP_FRAME, GdaFrame::OnExploreTestMap) EVT_MENU(XRCID("IDM_BOX"), GdaFrame::OnExploreNewBox) EVT_TOOL(XRCID("IDM_BOX"), GdaFrame::OnExploreNewBox) EVT_BUTTON(XRCID("IDM_BOX"), GdaFrame::OnExploreNewBox) diff --git a/TemplateCanvas.cpp b/TemplateCanvas.cpp index 192c35e82..0975d11c7 100644 --- a/TemplateCanvas.cpp +++ b/TemplateCanvas.cpp @@ -91,7 +91,7 @@ TemplateCanvas::TemplateCanvas(wxWindow* parent, bool fixed_aspect_ratio_mode_s, bool fit_to_window_mode_s, bool enable_high_dpi_support_) -: wxScrolledWindow(parent, -1, pos, size, +: wxScrolledWindow(parent, wxID_ANY, pos, size, wxNO_FULL_REPAINT_ON_RESIZE | wxCLIP_CHILDREN), mousemode(select), selectstate(start), brushtype(rectangle), is_brushing(false), scrollbarmode(none), remember_shiftdown(false), project(project_s), diff --git a/TemplateFrame.cpp b/TemplateFrame.cpp index c857add49..85c8362f8 100644 --- a/TemplateFrame.cpp +++ b/TemplateFrame.cpp @@ -62,7 +62,7 @@ TemplateFrame::TemplateFrame(wxFrame *parent, Project* project_s, const wxString& title, const wxPoint& pos, const wxSize& size, const long style) -: wxFrame(parent, -1, title, pos, size, style), +: wxFrame(parent, wxID_ANY, title, pos, size, style), template_canvas(0), template_legend(0), project(project_s), frames_manager(project_s->GetFramesManager()), table_state(project_s->GetTableState()), diff --git a/TemplateLegend.cpp b/TemplateLegend.cpp index b4122f6d0..014b6c5aa 100644 --- a/TemplateLegend.cpp +++ b/TemplateLegend.cpp @@ -34,7 +34,7 @@ PointRadiusDialog::PointRadiusDialog(const wxString & title, int r) -: wxDialog(NULL, -1, title, wxDefaultPosition, wxSize(250, 160)) +: wxDialog(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 160)) { wxPanel *panel = new wxPanel(this, -1); @@ -43,11 +43,11 @@ PointRadiusDialog::PointRadiusDialog(const wxString & title, int r) wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *sbox = new wxBoxSizer(wxHORIZONTAL); - wxStaticText *lbl = new wxStaticText(panel, -1, _("Point Radius:")); + wxStaticText *lbl = new wxStaticText(panel, wxID_ANY, _("Point Radius:")); wxString s_radius; if (r > 0) s_radius << r; else s_radius = "2"; - rb = new wxSpinCtrl(panel, -1, s_radius); + rb = new wxSpinCtrl(panel, wxID_ANY, s_radius); sbox->Add(lbl); sbox->Add(rb); wxBoxSizer* panel_v_szr = new wxBoxSizer(wxVERTICAL); @@ -165,7 +165,7 @@ void GdaLegendLabel::drawMove(wxDC& dc) // // /////////////////////////////////////////////////////////////////////////////////////////////// -const int TemplateLegend::ID_CATEGORY_COLOR = wxID_HIGHEST + 1; +const int TemplateLegend::ID_CATEGORY_COLOR = XRCID("IDC_LEGEND_CATEGORY_COLOR"); IMPLEMENT_ABSTRACT_CLASS(TemplateLegend, wxScrolledWindow) From 179aba22c1c998c5d3c249593fb71490a37c92c7 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 9 Nov 2018 20:48:21 -0700 Subject: [PATCH 13/39] fix possible issue to lead crash on windows when do spatial join with a csv file, and the csv file has rows with empty location. Or the user ignore to specify the lat/lon for this csv file. --- Project.cpp | 6 ++++++ ShapeOperations/OGRLayerProxy.cpp | 13 +++++++++++++ ShapeOperations/OGRLayerProxy.h | 1 + 3 files changed, 20 insertions(+) diff --git a/Project.cpp b/Project.cpp index 492cd6960..d19950f35 100644 --- a/Project.cpp +++ b/Project.cpp @@ -1608,7 +1608,13 @@ BackgroundMapLayer* Project::AddMapLayer(wxString datasource_name, GdaConst::Dat BackgroundMapLayer* map_layer = NULL; // Use global OGR adapter to manage all datasources, so they can be reused OGRDatasourceProxy* proxy = OGRDataAdapter::GetInstance().GetDatasourceProxy(datasource_name, ds_type); + if (proxy == NULL) { + return NULL; + } OGRLayerProxy* p_layer = proxy->GetLayerProxy(layer_name); + if (p_layer == NULL || p_layer->CheckIsTableOnly()) { + return NULL; + } if (p_layer->ReadData()) { if (p_layer->IsTableOnly() == false) { // always add to bg_maps diff --git a/ShapeOperations/OGRLayerProxy.cpp b/ShapeOperations/OGRLayerProxy.cpp index 9eea4c9a4..282c3902b 100644 --- a/ShapeOperations/OGRLayerProxy.cpp +++ b/ShapeOperations/OGRLayerProxy.cpp @@ -531,6 +531,11 @@ Shapefile::ShapeType OGRLayerProxy::GetOGRGeometries(vector& geoms for ( int row_idx=0; row_idx < n_rows; row_idx++ ) { OGRFeature* feature = data[row_idx]; OGRGeometry* geometry= feature->GetGeometryRef(); + if (geometry == NULL) { + // in case of invalid geometry (e.g. rows with empty lat/lon in csv file) + geoms.push_back(NULL); + continue; + } if (poCT) { geometry->transform(poCT); } @@ -885,6 +890,14 @@ bool OGRLayerProxy::HasError() return !error_message.str().empty(); } +bool OGRLayerProxy::CheckIsTableOnly() +{ + layer->ResetReading(); + OGRFeature *feature = layer->GetNextFeature(); + OGRGeometry* my_geom = feature->GetGeometryRef(); + return my_geom == NULL; +} + bool OGRLayerProxy::ReadData() { if (n_rows > 0 && n_rows == data.size()) { diff --git a/ShapeOperations/OGRLayerProxy.h b/ShapeOperations/OGRLayerProxy.h index 6b2c2744c..19f63325e 100644 --- a/ShapeOperations/OGRLayerProxy.h +++ b/ShapeOperations/OGRLayerProxy.h @@ -237,6 +237,7 @@ class OGRLayerProxy { * */ bool IsTableOnly(); + bool CheckIsTableOnly(); /** * */ From 91c44ace71ab3fb6a549cb6c82bdd5eb61966c6b Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 9 Nov 2018 21:02:07 -0700 Subject: [PATCH 14/39] KMeans UI update --- DialogTools/AbstractClusterDlg.cpp | 8 ++------ DialogTools/AbstractClusterDlg.h | 2 ++ DialogTools/KMeansDlg.cpp | 9 ++++++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/DialogTools/AbstractClusterDlg.cpp b/DialogTools/AbstractClusterDlg.cpp index cf20e9c40..1016cb62e 100644 --- a/DialogTools/AbstractClusterDlg.cpp +++ b/DialogTools/AbstractClusterDlg.cpp @@ -207,9 +207,7 @@ void AbstractClusterDlg::AddSimpleInputCtrls(wxPanel *panel, wxBoxSizer* vbox, b hbox0->Add(st, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 10); hbox0->Add(combo_var, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10); - wxStaticText* note_st = new wxStaticText(panel, wxID_ANY, - _("(Please note: Only supported for smaller datasets.)"), - wxDefaultPosition, wxDefaultSize); + note_st = new wxStaticText(panel, wxID_ANY, _("(Please note: Only supported for smaller datasets.)"), wxDefaultPosition, wxDefaultSize); vbox->Add(note_st, 0, wxEXPAND | wxALL, 10); vbox->Add(hbox0, 1, wxEXPAND | wxTOP | wxLEFT, 10); } @@ -251,9 +249,7 @@ void AbstractClusterDlg::AddInputCtrls(wxPanel *panel, wxBoxSizer* vbox, bool sh hbox0->Add(hbox_w, 0, wxLEFT | wxRIGHT, 10); - wxStaticText* note_st = new wxStaticText (panel, wxID_ANY, - _("(Please note: Only supported for smaller datasets.)"), - wxDefaultPosition, wxDefaultSize); + note_st = new wxStaticText (panel, wxID_ANY, _("(Please note: Only supported for smaller datasets.)"), wxDefaultPosition, wxDefaultSize); vbox->Add(note_st, 0, wxEXPAND | wxALL, 10); vbox->Add(hbox0, 1, wxEXPAND | wxALL, 10); diff --git a/DialogTools/AbstractClusterDlg.h b/DialogTools/AbstractClusterDlg.h index abc48f192..de8262c7e 100644 --- a/DialogTools/AbstractClusterDlg.h +++ b/DialogTools/AbstractClusterDlg.h @@ -93,6 +93,8 @@ class AbstractClusterDlg : public wxDialog, public FramesManagerObserver, public // Utils bool CheckConnectivity(GalWeight* gw); + wxStaticText* note_st; + // Input related std::vector var_info; std::vector col_ids; diff --git a/DialogTools/KMeansDlg.cpp b/DialogTools/KMeansDlg.cpp index be51461e6..4978ff747 100644 --- a/DialogTools/KMeansDlg.cpp +++ b/DialogTools/KMeansDlg.cpp @@ -76,6 +76,9 @@ void KClusterDlg::CreateControls() // Input AddInputCtrls(panel, vbox, true); + // issue: #1742 + note_st->SetLabel(""); + note_st->Hide(); // Parameters wxFlexGridSizer* gbox = new wxFlexGridSizer(9,2,5,0); @@ -681,7 +684,7 @@ void KClusterDlg::OnOK(wxCommandEvent& event ) // KMeans //////////////////////////////////////////////////////////////////////// KMeansDlg::KMeansDlg(wxFrame *parent, Project* project) -: KClusterDlg(parent, project, _("KMeans Dialog")) +: KClusterDlg(parent, project, _("KMeans Clustering Setting")) { wxLogMessage("In KMeansDlg()"); @@ -729,7 +732,7 @@ void KMeansDlg::doRun(int s1,int ncluster, int npass, int n_maxiter, int meth_se // KMedians //////////////////////////////////////////////////////////////////////// KMediansDlg::KMediansDlg(wxFrame *parent, Project* project) -: KClusterDlg(parent, project, _("KMedians Dialog")) +: KClusterDlg(parent, project, _("KMedians Clustering Setting")) { wxLogMessage("In KMediansDlg()"); @@ -777,7 +780,7 @@ void KMediansDlg::doRun(int s1,int ncluster, int npass, int n_maxiter, int meth_ // KMedoids //////////////////////////////////////////////////////////////////////// KMedoidsDlg::KMedoidsDlg(wxFrame *parent, Project* project) -: KClusterDlg(parent, project, _("KMedoids Dialog")) +: KClusterDlg(parent, project, _("KMedoids Clustering Setting")) { wxLogMessage("In KMedoidsDlg()"); From a5d6e69dc7ab7c89f655bb922262d7e6b7462f96 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 9 Nov 2018 21:03:40 -0700 Subject: [PATCH 15/39] #1740 HCluster dialog: remove text " Please Save results to see summary report" --- DialogTools/HClusterDlg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DialogTools/HClusterDlg.cpp b/DialogTools/HClusterDlg.cpp index 107834348..0fc60d206 100644 --- a/DialogTools/HClusterDlg.cpp +++ b/DialogTools/HClusterDlg.cpp @@ -221,7 +221,7 @@ void HClusterDlg::CreateControls() notebook = new wxNotebook( panel, wxID_ANY); m_panel = new DendrogramPanel(max_n_clusters, notebook, wxID_ANY); notebook->AddPage(m_panel, _("Dendrogram")); - m_reportbox = new SimpleReportTextCtrl(notebook, wxID_ANY, _("(Please save results to see the summary report.)")); + m_reportbox = new SimpleReportTextCtrl(notebook, wxID_ANY, ""); notebook->AddPage(m_reportbox, _("Summary")); notebook->Connect(wxEVT_NOTEBOOK_PAGE_CHANGING, wxBookCtrlEventHandler(HClusterDlg::OnNotebookChange), NULL, this); From 527add77f4077272f9049c118b2ad49962df1030 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 9 Nov 2018 21:05:12 -0700 Subject: [PATCH 16/39] #1741 Change "Save pca results" to "Save Results" for dialog when save output of clustering results --- GeneralWxUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GeneralWxUtils.cpp b/GeneralWxUtils.cpp index b3dd27501..8d474be91 100644 --- a/GeneralWxUtils.cpp +++ b/GeneralWxUtils.cpp @@ -63,7 +63,7 @@ void SimpleReportTextCtrl::OnContextMenu(wxContextMenuEvent& event) void SimpleReportTextCtrl::OnSaveClick( wxCommandEvent& event ) { wxLogMessage("In SimpleReportTextCtrl::OnSaveClick()"); - wxFileDialog dlg( this, "Save PCA results", wxEmptyString, + wxFileDialog dlg( this, "Save Results", wxEmptyString, wxEmptyString, "TXT files (*.txt)|*.txt", wxFD_SAVE ); From a60546a65101f451725221e78273c6dcb49fc1dc Mon Sep 17 00:00:00 2001 From: Xun Li Date: Sun, 11 Nov 2018 20:18:24 -0700 Subject: [PATCH 17/39] =?UTF-8?q?=E2=80=9CUse=20geometric=20centroids?= =?UTF-8?q?=E2=80=9D=20in=20hierarchical=20clustering=20bug=20#1746?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Algorithms/DataUtils.h | 12 ++++++------ DialogTools/HClusterDlg.cpp | 8 ++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Algorithms/DataUtils.h b/Algorithms/DataUtils.h index dd099d1ef..994810c77 100644 --- a/Algorithms/DataUtils.h +++ b/Algorithms/DataUtils.h @@ -17,20 +17,20 @@ using namespace std; class DataUtils { public: - static double ManhattanDistance(double* x1, double* x2, size_t size) + static double ManhattanDistance(double* x1, double* x2, size_t size, double* weight) { double d =0; for (size_t i =0; igal, input_data, rows, columns, DataUtils::EuclideanDistance); + double* pwdist = NULL; + if (dist == 'e') { + pwdist = DataUtils::getPairWiseDistance(input_data, weight, rows, columns, DataUtils::EuclideanDistance); + } else { + pwdist = DataUtils::getPairWiseDistance(input_data, weight, rows, columns, DataUtils::ManhattanDistance); + } fastcluster::auto_array_ptr members; From 20994af5c3432aff15e1d146381cd2a0f44cd17f Mon Sep 17 00:00:00 2001 From: Xun Li Date: Sun, 11 Nov 2018 20:48:47 -0700 Subject: [PATCH 18/39] #1741 also fix the issue in HDBSCAN and spectral clustering --- DialogTools/HDBScanDlg.cpp | 7 +++++++ DialogTools/SpectralClusteringDlg.cpp | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/DialogTools/HDBScanDlg.cpp b/DialogTools/HDBScanDlg.cpp index 17859dbb7..293343b3e 100644 --- a/DialogTools/HDBScanDlg.cpp +++ b/DialogTools/HDBScanDlg.cpp @@ -491,6 +491,13 @@ void HDBScanDlg::OnOKClick(wxCommandEvent& event ) for (int i = 1; i < rows; i++) free(ragged_distances[i]); free(ragged_distances); + // add weight to input_data + for (int i=0; i Date: Mon, 12 Nov 2018 21:11:17 -0700 Subject: [PATCH 19/39] update UI; try to fix crash when load csv with empty location and create thiessen polygons GeoDa accepts csv file with empty locations now, and it will cause a crash when create thiessen polygons from points with empty location. This is going to fix this issue. --- BuildTools/windows/GeoDa.vcxproj | 4 ++-- BuildTools/windows/GeoDa.vs2017.sln | 12 ++---------- DialogTools/AbstractClusterDlg.cpp | 5 ----- DialogTools/AbstractClusterDlg.h | 2 -- DialogTools/HClusterDlg.cpp | 2 +- DialogTools/KMeansDlg.cpp | 9 +++------ Explore/MapLayerTree.cpp | 2 +- Explore/MapLayoutView.cpp | 2 +- ShapeOperations/OGRLayerProxy.cpp | 14 ++++++++------ TemplateFrame.cpp | 2 +- 10 files changed, 19 insertions(+), 35 deletions(-) diff --git a/BuildTools/windows/GeoDa.vcxproj b/BuildTools/windows/GeoDa.vcxproj index 38f33f604..2e2516f9a 100644 --- a/BuildTools/windows/GeoDa.vcxproj +++ b/BuildTools/windows/GeoDa.vcxproj @@ -30,7 +30,7 @@ {B3CB134F-61C6-48C7-B6E4-353AC473A467} GeoDa Win32Proj - 8.1 + 10.0.17134.0 @@ -51,7 +51,7 @@ Application - Windows7.1SDK + v141 Application diff --git a/BuildTools/windows/GeoDa.vs2017.sln b/BuildTools/windows/GeoDa.vs2017.sln index 670512cbd..648a24173 100644 --- a/BuildTools/windows/GeoDa.vs2017.sln +++ b/BuildTools/windows/GeoDa.vs2017.sln @@ -1,16 +1,12 @@  -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26401.1 -MinimumVisualStudioVersion = 10.0.40219.1 +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GeoDa", "GeoDa.vcxproj", "{B3CB134F-61C6-48C7-B6E4-353AC473A467}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 - Debug2017|Win32 = Debug2017|Win32 - Debug2017|x64 = Debug2017|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection @@ -19,10 +15,6 @@ Global {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Debug|Win32.Build.0 = Debug|Win32 {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Debug|x64.ActiveCfg = Debug|x64 {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Debug|x64.Build.0 = Debug|x64 - {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Debug2017|Win32.ActiveCfg = Debug2017|Win32 - {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Debug2017|Win32.Build.0 = Debug2017|Win32 - {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Debug2017|x64.ActiveCfg = Debug2017|x64 - {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Debug2017|x64.Build.0 = Debug2017|x64 {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Release|Win32.ActiveCfg = Release|Win32 {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Release|Win32.Build.0 = Release|Win32 {B3CB134F-61C6-48C7-B6E4-353AC473A467}.Release|x64.ActiveCfg = Release|x64 diff --git a/DialogTools/AbstractClusterDlg.cpp b/DialogTools/AbstractClusterDlg.cpp index 1016cb62e..b51857cc8 100644 --- a/DialogTools/AbstractClusterDlg.cpp +++ b/DialogTools/AbstractClusterDlg.cpp @@ -207,8 +207,6 @@ void AbstractClusterDlg::AddSimpleInputCtrls(wxPanel *panel, wxBoxSizer* vbox, b hbox0->Add(st, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 10); hbox0->Add(combo_var, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10); - note_st = new wxStaticText(panel, wxID_ANY, _("(Please note: Only supported for smaller datasets.)"), wxDefaultPosition, wxDefaultSize); - vbox->Add(note_st, 0, wxEXPAND | wxALL, 10); vbox->Add(hbox0, 1, wxEXPAND | wxTOP | wxLEFT, 10); } @@ -248,9 +246,6 @@ void AbstractClusterDlg::AddInputCtrls(wxPanel *panel, wxBoxSizer* vbox, bool sh hbox0->Add(hbox_c, 0, wxLEFT | wxRIGHT, 10); hbox0->Add(hbox_w, 0, wxLEFT | wxRIGHT, 10); - - note_st = new wxStaticText (panel, wxID_ANY, _("(Please note: Only supported for smaller datasets.)"), wxDefaultPosition, wxDefaultSize); - vbox->Add(note_st, 0, wxEXPAND | wxALL, 10); vbox->Add(hbox0, 1, wxEXPAND | wxALL, 10); if (project->IsTableOnlyProject()) { diff --git a/DialogTools/AbstractClusterDlg.h b/DialogTools/AbstractClusterDlg.h index de8262c7e..abc48f192 100644 --- a/DialogTools/AbstractClusterDlg.h +++ b/DialogTools/AbstractClusterDlg.h @@ -93,8 +93,6 @@ class AbstractClusterDlg : public wxDialog, public FramesManagerObserver, public // Utils bool CheckConnectivity(GalWeight* gw); - wxStaticText* note_st; - // Input related std::vector var_info; std::vector col_ids; diff --git a/DialogTools/HClusterDlg.cpp b/DialogTools/HClusterDlg.cpp index d8c4a904d..2fadfb2eb 100644 --- a/DialogTools/HClusterDlg.cpp +++ b/DialogTools/HClusterDlg.cpp @@ -158,7 +158,7 @@ void HClusterDlg::CreateControls() gbox->Add(box13, 1, wxEXPAND); - wxStaticText* st17 = new wxStaticText(panel, wxID_ANY, _("Spatially Constraint:"), + wxStaticText* st17 = new wxStaticText(panel, wxID_ANY, _("Spatial Constraint:"), wxDefaultPosition, wxSize(128,-1)); chk_contiguity = new wxCheckBox(panel, wxID_ANY, ""); gbox->Add(st17, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, 10); diff --git a/DialogTools/KMeansDlg.cpp b/DialogTools/KMeansDlg.cpp index 4978ff747..6af750ac0 100644 --- a/DialogTools/KMeansDlg.cpp +++ b/DialogTools/KMeansDlg.cpp @@ -76,9 +76,6 @@ void KClusterDlg::CreateControls() // Input AddInputCtrls(panel, vbox, true); - // issue: #1742 - note_st->SetLabel(""); - note_st->Hide(); // Parameters wxFlexGridSizer* gbox = new wxFlexGridSizer(9,2,5,0); @@ -684,7 +681,7 @@ void KClusterDlg::OnOK(wxCommandEvent& event ) // KMeans //////////////////////////////////////////////////////////////////////// KMeansDlg::KMeansDlg(wxFrame *parent, Project* project) -: KClusterDlg(parent, project, _("KMeans Clustering Setting")) +: KClusterDlg(parent, project, _("KMeans Clustering Settings")) { wxLogMessage("In KMeansDlg()"); @@ -732,7 +729,7 @@ void KMeansDlg::doRun(int s1,int ncluster, int npass, int n_maxiter, int meth_se // KMedians //////////////////////////////////////////////////////////////////////// KMediansDlg::KMediansDlg(wxFrame *parent, Project* project) -: KClusterDlg(parent, project, _("KMedians Clustering Setting")) +: KClusterDlg(parent, project, _("KMedians Clustering Settings")) { wxLogMessage("In KMediansDlg()"); @@ -780,7 +777,7 @@ void KMediansDlg::doRun(int s1,int ncluster, int npass, int n_maxiter, int meth_ // KMedoids //////////////////////////////////////////////////////////////////////// KMedoidsDlg::KMedoidsDlg(wxFrame *parent, Project* project) -: KClusterDlg(parent, project, _("KMedoids Clustering Setting")) +: KClusterDlg(parent, project, _("KMedoids Clustering Settings")) { wxLogMessage("In KMedoidsDlg()"); diff --git a/Explore/MapLayerTree.cpp b/Explore/MapLayerTree.cpp index 299b8cfe3..50e19bcf3 100644 --- a/Explore/MapLayerTree.cpp +++ b/Explore/MapLayerTree.cpp @@ -801,7 +801,7 @@ void MapTree::OnDraw(wxDC& dc) wxCoord w, h; dc.GetSize(&w, &h); - dc.DrawText(_("Map Layer Setting"), 5, 10); + dc.DrawText(_("Map Layer Settings"), 5, 10); if ( !select_name.IsEmpty() ) { DrawLegend(dc, px_switch, move_pos.y, select_name); diff --git a/Explore/MapLayoutView.cpp b/Explore/MapLayoutView.cpp index 5b36cfad8..53deec8c5 100644 --- a/Explore/MapLayoutView.cpp +++ b/Explore/MapLayoutView.cpp @@ -410,7 +410,7 @@ void CanvasLayoutDialog::OnSave(wxCommandEvent &event) { int layout_w = GetWidth(); int layout_h = GetHeight(); - CanvasExportSettingDialog setting_dlg(layout_w*2, layout_h*2, _("Image Dimension Setting")); + CanvasExportSettingDialog setting_dlg(layout_w*2, layout_h*2, _("Image Dimension Settings")); if (setting_dlg.ShowModal() != wxID_OK) { return; diff --git a/ShapeOperations/OGRLayerProxy.cpp b/ShapeOperations/OGRLayerProxy.cpp index 282c3902b..f774f82d8 100644 --- a/ShapeOperations/OGRLayerProxy.cpp +++ b/ShapeOperations/OGRLayerProxy.cpp @@ -1149,16 +1149,18 @@ bool OGRLayerProxy::GetExtent(double& minx, double& miny, void OGRLayerProxy::GetCentroids(vector& centroids) { if (centroids.size() == 0 && n_rows > 0) { - centroids.resize(n_rows); + // if centroids is empty double x, y; for ( int row_idx=0; row_idx < n_rows; row_idx++ ) { OGRFeature* feature = data[row_idx]; OGRGeometry* geometry= feature->GetGeometryRef(); - OGRPoint poPoint; - geometry->Centroid(&poPoint); - x = poPoint.getX(); - y = poPoint.getY(); - centroids[row_idx] = new GdaPoint(x, y); + if (geometry) { + OGRPoint poPoint; + geometry->Centroid(&poPoint); + x = poPoint.getX(); + y = poPoint.getY(); + centroids.push_back(new GdaPoint(x, y)); + } } } } diff --git a/TemplateFrame.cpp b/TemplateFrame.cpp index 85c8362f8..c7c8e734f 100644 --- a/TemplateFrame.cpp +++ b/TemplateFrame.cpp @@ -469,7 +469,7 @@ void TemplateFrame::ExportImage(TemplateCanvas* canvas, const wxString& type) int default_width = canvas_width*2; int default_height = canvas_height*2; - CanvasExportSettingDialog setting_dlg(default_width, default_height, _("Image Dimension Setting")); + CanvasExportSettingDialog setting_dlg(default_width, default_height, _("Image Dimension Settings")); if (setting_dlg.ShowModal() == wxID_OK) { int out_res_x = setting_dlg.GetMapWidth(); int out_res_y = setting_dlg.GetMapHeight(); From 5a07e787855950ccef5221b30cd8c51446573a41 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 13 Nov 2018 20:47:26 -0700 Subject: [PATCH 20/39] update version for lab; fixes for K clustering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. The “cluster centers” reported in the summary for Kmedians are the medians, and for Kmedoids the medoids 2. KMedians —> only have Manhattan distance function 3. KMeans —> only have Euclidean distance function 4. KMedoids -> have both, Manhattan as default --- DialogTools/AbstractClusterDlg.h | 2 +- DialogTools/KMeansDlg.cpp | 74 ++++++++++++++++++++++++++++++++ DialogTools/KMeansDlg.h | 5 +++ Explore/AbstractCoordinator.h | 2 +- Explore/LisaCoordinator.cpp | 2 +- Explore/LisaCoordinator.h | 2 +- version.h | 4 +- 7 files changed, 85 insertions(+), 6 deletions(-) diff --git a/DialogTools/AbstractClusterDlg.h b/DialogTools/AbstractClusterDlg.h index abc48f192..d9fdead19 100644 --- a/DialogTools/AbstractClusterDlg.h +++ b/DialogTools/AbstractClusterDlg.h @@ -163,7 +163,7 @@ class AbstractClusterDlg : public wxDialog, public FramesManagerObserver, public // -- functions double _getTotalSumOfSquares(); double _calcSumOfSquares(const vector& cluster_ids); - vector > _getMeanCenters(const vector >& solution); + virtual vector > _getMeanCenters(const vector >& solution); vector _getWithinSumOfSquares(const vector >& solution); wxString _printMeanCenters(const vector >& mean_centers); wxString _printWithinSS(const vector& within_ss); diff --git a/DialogTools/KMeansDlg.cpp b/DialogTools/KMeansDlg.cpp index 6af750ac0..786491988 100644 --- a/DialogTools/KMeansDlg.cpp +++ b/DialogTools/KMeansDlg.cpp @@ -691,6 +691,7 @@ KMeansDlg::KMeansDlg(wxFrame *parent, Project* project) cluster_method = "KMeans"; CreateControls(); + m_distance->Disable(); } KMeansDlg::~KMeansDlg() @@ -740,6 +741,7 @@ KMediansDlg::KMediansDlg(wxFrame *parent, Project* project) CreateControls(); m_distance->SetSelection(1); // set manhattan + m_distance->Disable(); } KMediansDlg::~KMediansDlg() @@ -772,6 +774,37 @@ void KMediansDlg::doRun(int s1,int ncluster, int npass, int n_maxiter, int meth_ delete[] clusterid; } +vector > KMediansDlg::_getMeanCenters(const vector >& solutions) +{ + int n_clusters = solutions.size(); + vector > result(n_clusters); + + if (columns <= 0 || rows <= 0) return result; + + for (int i=0; i medians; + for (int c=0; c > KMedoidsDlg::_getMeanCenters(const vector >& solutions) +{ + // The centroid is defined as the element with the + // smallest sum of distances to the other elements. + int n_clusters = solutions.size(); + vector > result(n_clusters); + + if (columns <= 0 || rows <= 0) return result; + + vector centroid_ids(n_clusters,0); + vector errors(n_clusters); + for (int j=0; j means; + for (int c=0; c > _getMeanCenters(const vector >& solution) { + return AbstractClusterDlg::_getMeanCenters(solution); + } virtual void doRun(int s1, int ncluster, int npass, int n_maxiter, int meth_sel, int dist_sel, double min_bound, double* bound_vals)=0; @@ -112,6 +115,7 @@ class KMediansDlg : public KClusterDlg virtual ~KMediansDlg(); virtual void doRun(int s1, int ncluster, int npass, int n_maxiter, int meth_sel, int dist_sel, double min_bound, double* bound_vals); + virtual vector > _getMeanCenters(const vector >& solution); }; class KMedoidsDlg : public KClusterDlg @@ -122,5 +126,6 @@ class KMedoidsDlg : public KClusterDlg virtual void ComputeDistMatrix(int dist_sel); virtual void doRun(int s1, int ncluster, int npass, int n_maxiter, int meth_sel, int dist_sel, double min_bound, double* bound_vals); + virtual vector > _getMeanCenters(const vector >& solution); }; #endif diff --git a/Explore/AbstractCoordinator.h b/Explore/AbstractCoordinator.h index dfb2f8467..1486b3c5c 100644 --- a/Explore/AbstractCoordinator.h +++ b/Explore/AbstractCoordinator.h @@ -145,7 +145,7 @@ class AbstractCoordinator : public WeightsManStateObserver virtual void CalcPseudoP_range(int obs_start, int obs_end, uint64_t seed_start); - virtual void ComputeLarger(int cnt, std::vector permNeighbors, + virtual void ComputeLarger(int cnt, std::vector& permNeighbors, std::vector& countLarger) = 0; virtual std::vector GetDefaultCategories(); diff --git a/Explore/LisaCoordinator.cpp b/Explore/LisaCoordinator.cpp index ba944a983..8e2ce16c6 100644 --- a/Explore/LisaCoordinator.cpp +++ b/Explore/LisaCoordinator.cpp @@ -556,7 +556,7 @@ void LisaCoordinator::CalcPseudoP() LOG_MSG(wxString::Format("GPU took %ld ms", sw_vd.Time())); } -void LisaCoordinator::ComputeLarger(int cnt, std::vector permNeighbors, std::vector& countLarger) +void LisaCoordinator::ComputeLarger(int cnt, std::vector& permNeighbors, std::vector& countLarger) { // for each time step, reuse permuation for (int t=0; t permNeighbors, + virtual void ComputeLarger(int cnt, std::vector& permNeighbors, std::vector& countLarger); virtual void Init(); virtual void Calc(); diff --git a/version.h b/version.h index d54c97f2d..362648302 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 12; const int version_build = 1; - const int version_subbuild = 173; + const int version_subbuild = 175; const int version_year = 2018; const int version_month = 11; - const int version_day = 6; + const int version_day = 13; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From 00b928068e9e1806c434f59cc25a518cd78f856c Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 13 Nov 2018 20:48:25 -0700 Subject: [PATCH 21/39] update build script on windows --- BuildTools/windows/GeoDa.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BuildTools/windows/GeoDa.vcxproj b/BuildTools/windows/GeoDa.vcxproj index 2e2516f9a..5ec5c80ec 100644 --- a/BuildTools/windows/GeoDa.vcxproj +++ b/BuildTools/windows/GeoDa.vcxproj @@ -51,7 +51,7 @@ Application - v141 + Windows7.1SDK Application From 1329ae7334e8f794bb4d126ae2edfe4d08c5923c Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 15 Nov 2018 21:26:54 -0700 Subject: [PATCH 22/39] #1751 weights enhancement --- DialogTools/CreatingWeightDlg.cpp | 59 +- DialogTools/CreatingWeightDlg.h | 7 +- DialogTools/ProjectInfoDlg.cpp | 7 + PointSetAlgs.cpp | 2 +- Project.cpp | 9 + Project.h | 3 +- rc/GdaAppResources.cpp | 1348 ++++++++++++++++------------- rc/dialogs.xrc | 159 +++- 8 files changed, 964 insertions(+), 630 deletions(-) diff --git a/DialogTools/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp index 4cd79e56a..06bc7cca1 100644 --- a/DialogTools/CreatingWeightDlg.cpp +++ b/DialogTools/CreatingWeightDlg.cpp @@ -70,6 +70,7 @@ EVT_CHECKBOX( XRCID("IDC_CHK_INVERSE_DISTANCE"), CreatingWeightDlg::OnInverseDis EVT_CHECKBOX( XRCID("IDC_CHK_INVERSE_DISTANCE_KNN"), CreatingWeightDlg::OnInverseKNNCheck) EVT_SPIN( XRCID("IDC_SPIN_POWER"), CreatingWeightDlg::OnCSpinPowerInverseDistUpdated ) EVT_SPIN( XRCID("IDC_SPIN_POWER_KNN"), CreatingWeightDlg::OnCSpinPowerInverseKNNUpdated ) +EVT_NOTEBOOK_PAGE_CHANGED( XRCID("IDC_WEIGHTS_DIST_VARS_LIST"), CreatingWeightDlg::OnDistanceWeightsInputUpdate ) END_EVENT_TABLE() @@ -178,6 +179,8 @@ void CreatingWeightDlg::CreateControls() m_X_time = XRCCTRL(*this, "IDC_XCOORD_TIME", wxChoice); m_Y = XRCCTRL(*this, "IDC_YCOORDINATES", wxChoice); m_Y_time = XRCCTRL(*this, "IDC_YCOORD_TIME", wxChoice); + m_Vars = XRCCTRL(*this, "IDC_WEIGHTS_DIST_VARS_LIST", wxListBox); + m_nb_distance_variables = XRCCTRL(*this, "IDC_NB_DISTANCE_VARIABLES", wxNotebook); m_nb_distance_methods = XRCCTRL(*this, "IDC_NB_DISTANCE_WEIGHTS", wxNotebook); m_threshold = XRCCTRL(*this, "IDC_THRESHOLD_EDIT", wxTextCtrl); m_sliderdistance = XRCCTRL(*this, "IDC_THRESHOLD_SLIDER", wxSlider); @@ -209,9 +212,48 @@ void CreatingWeightDlg::CreateControls() m_power->Enable(false); m_power_knn->Enable(false); + m_nb_distance_variables->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, &CreatingWeightDlg::OnDistanceWeightsInputUpdate, this); + m_Vars->Bind(wxEVT_LISTBOX, &CreatingWeightDlg::OnDistanceWeightsVarsSel, this); + InitDlg(); } +void CreatingWeightDlg::OnDistanceWeightsVarsSel( wxCommandEvent& event ) +{ + // update Threshold values for distance weight + wxArrayInt selections; + m_Vars->GetSelections(selections); + int num_var = selections.size(); + if (num_var <= 0) { + return; + } + for (int i=0; iGetString(idx); + + // get data [] + //int col = table_int->FindColId(nm); + } +} + +void CreatingWeightDlg::OnDistanceWeightsInputUpdate( wxBookCtrlEvent& event ) +{ + int sel = event.GetSelection(); + if (sel == 0) { + UpdateThresholdValues(); + } else { + wxArrayInt selections; + m_Vars->GetSelections(selections); + int n_sel = selections.GetCount(); + if (n_sel <= 0) { + m_thres_val_valid = false; + m_threshold->ChangeValue("0"); + m_bandwidth_thres_val_valid = false; + m_manu_bandwidth->ChangeValue("0"); + } + } +} + void CreatingWeightDlg::OnCreateNewIdClick( wxCommandEvent& event ) { wxLogMessage("Click CreatingWeightDlg::OnCreateNewIdClick"); @@ -571,14 +613,27 @@ void CreatingWeightDlg::InitFields() m_id_field->Clear(); m_X_time->Clear(); m_Y_time->Clear(); + m_Vars->Clear(); + ResetThresXandYCombo(); for (int i=0, iend=col_id_map.size(); iAppend(table_int->GetColName(col)); - m_Y->Append(table_int->GetColName(col)); + wxString name = table_int->GetColName(col); + m_X->Append(name); + m_Y->Append(name); + if (table_int->IsColTimeVariant(col)) { + for (int t=0; tGetColTimeSteps(col); t++) { + wxString nm = name; + nm << " (" << table_int->GetTimeString(t) << ")"; + m_Vars->Append(nm); + } + } else { + m_Vars->Append(name); + } + if (table_int->GetColType(col) == GdaConst::long64_type || table_int->GetColType(col) == GdaConst::string_type) { if (!table_int->IsColTimeVariant(col)) { diff --git a/DialogTools/CreatingWeightDlg.h b/DialogTools/CreatingWeightDlg.h index e7efa9d45..3843ab75a 100644 --- a/DialogTools/CreatingWeightDlg.h +++ b/DialogTools/CreatingWeightDlg.h @@ -90,7 +90,8 @@ public TableStateObserver, public WeightsManStateObserver void OnCThresholdSliderUpdated( wxCommandEvent& event ); void OnCSpinPowerInverseDistUpdated( wxSpinEvent& event ); void OnCSpinPowerInverseKNNUpdated( wxSpinEvent& event ); - + void OnDistanceWeightsInputUpdate( wxBookCtrlEvent& event ); + void OnDistanceWeightsVarsSel( wxCommandEvent& event ); /** Implementation of FramesManagerObserver interface */ virtual void update(FramesManager* o); @@ -129,7 +130,9 @@ public TableStateObserver, public WeightsManStateObserver wxChoice* m_X_time; wxChoice* m_Y; wxChoice* m_Y_time; - wxNotebook* m_nb_distance_methods; + wxListBox* m_Vars; + wxNotebook* m_nb_distance_variables; + wxNotebook* m_nb_distance_methods; wxTextCtrl* m_threshold; wxSlider* m_sliderdistance; wxCheckBox* m_use_inverse; diff --git a/DialogTools/ProjectInfoDlg.cpp b/DialogTools/ProjectInfoDlg.cpp index 14e286ca8..c5bdaed77 100644 --- a/DialogTools/ProjectInfoDlg.cpp +++ b/DialogTools/ProjectInfoDlg.cpp @@ -112,6 +112,13 @@ ProjectInfoDlg::ProjectInfoDlg(Project* project) key.push_back("Number Table Groups"); val.push_back(wxString::Format("%d", grp_cnt)); + + if (project->IsTableOnlyProject() == false) { + key.push_back("Map boundary"); + double minx = 0, miny = 0, maxx = 0, maxy = 0; + project->GetMapExtent(minx, miny, maxx, maxy); + val.push_back(wxString::Format("Lower left: %f, %f Upper right: %f, %f", minx, miny, maxx, maxy)); + } const int left_offset = 0; const int top_offset = 0; diff --git a/PointSetAlgs.cpp b/PointSetAlgs.cpp index 1cdbb26db..ca7898b16 100644 --- a/PointSetAlgs.cpp +++ b/PointSetAlgs.cpp @@ -49,7 +49,7 @@ void PointSetAlgs::GetMinMax(const std::vector& pts, double PointSetAlgs::EstDiameter(const std::vector& x, const std::vector& y, bool is_arc, - wxRealPoint& pt1, wxRealPoint& pt2) + wxRealPoint& pt1, wxRealPoint& pt2) { LOG_MSG("Entering PointSetAlgs::EstDiameter"); using namespace GenGeomAlgs; diff --git a/Project.cpp b/Project.cpp index d19950f35..5a9f9e331 100644 --- a/Project.cpp +++ b/Project.cpp @@ -1108,6 +1108,15 @@ GdaPolygon* Project::GetMapBoundary() } } +void Project::GetMapExtent(double& minx, double& miny, double& maxx, double& maxy) +{ + wxLogMessage("Project::GetMapExtent()"); + + if (layer_proxy) { + layer_proxy->GetExtent(minx, miny, maxx, maxy); + } +} + void Project::GetCentroids(std::vector& x, std::vector& y) { wxLogMessage("Project::GetCentroids(std::vector& x, std::vector& y)"); diff --git a/Project.h b/Project.h index ec979eb67..9e803baa5 100644 --- a/Project.h +++ b/Project.h @@ -162,7 +162,8 @@ class Project { void GetCentroids(std::vector& pts); const std::vector& GetVoronoiPolygons(); GdaPolygon* GetMapBoundary(); - + void GetMapExtent(double& minx, double& miny, double& maxx, double& maxy); + double GetMin1nnDistEuc(); double GetMax1nnDistEuc(); double GetMaxDistEuc(); // diameter of convex hull diff --git a/rc/GdaAppResources.cpp b/rc/GdaAppResources.cpp index 4e3477530..d8ed25eb1 100644 --- a/rc/GdaAppResources.cpp +++ b/rc/GdaAppResources.cpp @@ -15530,7 +15530,7 @@ static unsigned char xml_res_file_7[] = { 16,48,4,12,1,67,192,16,48,4,12,1,67,160,133,35,240,255,75,175,9,51,209, 227,12,205,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_8 = 385362; +static size_t xml_res_size_8 = 389594; 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,117,116,102,45,56,34,63,62,10,60,114,101, @@ -22203,441 +22203,469 @@ static unsigned char xml_res_file_8[] = { 34,32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,95,68,73,83,84, 95,77,69,84,82,73,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,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,116,97,110,99,101,32,109,101,116,114,105,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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,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,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,68,73,83,84,65,78,67,69,95,77,69,84, -82,73,67,34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +115,116,97,110,99,101,32,109,101,116,114,105,99,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,76,69,70,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, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, -61,34,73,68,67,95,83,84,65,84,73,67,95,88,67,79,79,82,68,95,86,65,82,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,88,45,99,111,111,114,100,105, -110,97,116,101,32,118,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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,67, -69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,68,73,83,84,65,78,67,69,95,77, +69,84,82,73,67,34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,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,60, -47,111,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,69,82, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,32,32,32,32,60,118,103,97,112,62,53,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,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,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,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,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,102, +108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,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,60,111,98,106,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,86,97, +114,105,97,98,108,101,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,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,73,68,67,95,78,66,95,68,73,83,84,65,78,67,69,95,86,65, +82,73,65,66,76,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,88,67,79,79,82,68,73,78,65,84,69,83, -34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,32,110,97,109, +101,61,34,73,68,67,95,78,66,95,80,65,71,69,95,71,69,79,77,95,67,69,78,84, +82,79,73,68,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,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,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, +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,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,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,60,47,102,108,97, 103,62,10,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,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,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,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, +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,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,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,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,73,68,67,95,88,67,79,79,82,68,95, -84,73,77,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,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,60,115,105,122,101,62,51,48,44,50,60,47,115,105,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,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,83,84,65,84,73,67,95,89,67,79,79,82,68,95,86,65,82,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,89,45,99,111,111,114,100,105,110,97,116,101, -32,118,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,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,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,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, +83,84,65,84,73,67,95,88,67,79,79,82,68,95,86,65,82,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,88,45,99,111,111, +114,100,105,110,97,116,101,32,118,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,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,89,67,79,79,82,68,73,78,65,84,69,83,34,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,76,69,70,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,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,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,32,32,32,32, -32,32,60,115,105,122,101,62,57,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,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,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,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,88,67,79,79,82,68,73,78,65,84, +69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,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,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,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,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,89,67,79,79,82,68,95,84,73,77,69,34, +61,34,119,120,67,104,111,105,99,101,34,32,110,97,109,101,61,34,73,68,67, +95,88,67,79,79,82,68,95,84,73,77,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,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,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,52,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,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,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,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,60,118,103,97,112,62,53,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,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,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,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,78,111,116,101,98,111,111,107,34,32,110,97,109, -101,61,34,73,68,67,95,78,66,95,68,73,83,84,65,78,67,69,95,87,69,73,71,72, -84,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,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,73, -68,67,95,82,65,68,73,79,95,68,73,83,84,65,78,67,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,32,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,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, -84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, -69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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, +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,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,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,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,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, -60,111,98,106,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,60,115,105,122,101,62,51,48,44,50,60, +47,115,105,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,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, 32,32,32,32,32,32,32,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,112,101,99,105,102,121,32,98,97,110,100,119, -105,100,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,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,95,89,67,79,79,82,68,95, +86,65,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,89,45,99,111,111,114,100,105,110,97,116,101,32,118,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,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,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, +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,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,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,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,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,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,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,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,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,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,73,68,67,95,89,67,79,79, +82,68,73,78,65,84,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,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,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -84,72,82,69,83,72,79,76,68,95,69,68,73,84,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,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,57,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,32,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,73,71,72,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +32,32,32,32,32,32,32,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,60,47,102,108,97,103,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,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,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,89,67,79,79,82,68,95,84,73,77,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,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,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,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,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,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,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,111,109,101,116,114,105,99,32,99,101,110,116,114,111,105, +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,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,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,32,110,97,109,101, +61,34,73,68,67,95,78,66,95,80,65,71,69,95,77,85,76,84,73,95,86,65,82,83, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,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,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,32,32,32,32,32, -60,115,105,122,101,62,51,48,44,50,60,47,115,105,122,101,62,10,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,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,49,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,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,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,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,108,105, -100,101,114,34,32,110,97,109,101,61,34,73,68,67,95,84,72,82,69,83,72,79, -76,68,95,83,76,73,68,69,82,34,62,10,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,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,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, -60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,87,69,73,71,72,84,83,95,68,73,83, +84,95,86,65,82,83,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,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,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,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,109,97,120,62,49,48,48,60,47,109,97,120,62,10,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,48,44,51,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,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,66,95,77,85,76,84,73,80,76,69,32,124,32,119,120, +76,66,95,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,32,32,32,32,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,83,76, -95,72,79,82,73,90,79,78,84,65,76,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,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,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,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,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,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,56,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,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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, +45,118,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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, +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,32,32,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,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78,67,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,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,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,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,60,111,98,106, +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,77,101,116,104,111,100,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,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,78,66,95, +68,73,83,84,65,78,67,69,95,87,69,73,71,72,84,83,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +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,73,68,67,95,82,65,68,73,79,95,68, +73,83,84,65,78,67,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,32,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,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,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73,83,84,65, -78,67,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,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,105,110,118,101,114,115,101,32,100,105,115,116, -97,110,99,101,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,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,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,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, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,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,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,112,101, +99,105,102,121,32,98,97,110,100,119,105,100,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,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,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,60,102,108,97,103,62,119,120, +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,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,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,32,32,32,32,32,32,32,60,115,105,122,101,62,49,48,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, -61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,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,32,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,119,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,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, 106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, 109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, -110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,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,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,73,68,67,95,84,72,82,69,83,72,79,76,68,95,69,68,73,84,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,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,57,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,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,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,60,115,116,121,108,101,62,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,66,117, -116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80,73,78,95,80, -79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,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,32,32, 32,32,32,32,32,32,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,105,110,62,49,60,47,109,105,110,62,10,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,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,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,48,44,50,60,47,115,105,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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,116,97,110,99,101,32,98,97,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,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,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,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, -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,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, -84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,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,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,108,105,100,101,114,34,32,110,97,109,101,61,34,73,68,67,95,84,72, +82,69,83,72,79,76,68,95,83,76,73,68,69,82,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,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,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,62,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,32,32,32,32,32,32,32, +32,32,32,32,32,60,109,105,110,62,48,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,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,76,95,72,79,82,73,90,79,78,84,65,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,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,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,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,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,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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, @@ -22647,85 +22675,150 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,124,119,120,65,68,74,85,83,84,95,77,73,78,83,73,90,69,60,47,102,108, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78,67,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62, +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,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73, +83,84,65,78,67,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,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,105,110,118,101,114,115,101,32,100,105, +115,116,97,110,99,101,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,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,83, -84,65,84,73,67,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,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,111,102,32,110,101, -105,103,104,98,111,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,32,32,32,32,32,32,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,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,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,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,75,78, -78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,60,115,105,122,101,62,49,48,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,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,84,69,95,82,69,65, -68,79,78,76,89,124,119,120,84,69,95,82,73,71,72,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,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -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,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,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,60,108,97,98,101,108,62,80,111,119, +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,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,115,105, -122,101,62,50,44,50,60,47,115,105,122,101,62,10,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,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,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,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, 116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,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,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,66,117,116,116,111, -110,34,32,110,97,109,101,61,34,73,68,67,95,83,80,73,78,95,75,78,78,34,62, +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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73,67,65,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, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32,60, -109,105,110,62,48,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,32,32,32,32,32,60,102,108,97,103,62,119,120,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120,62,10,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, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, +110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, +73,78,95,80,79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,62,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,32,32, +32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48, +60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,76,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,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,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,116,97,110,99,101,32,98,97,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +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,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,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,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, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -22739,117 +22832,209 @@ static unsigned char xml_res_file_8[] = { 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 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, +120,65,76,76,124,119,120,65,68,74,85,83,84,95,77,73,78,83,73,90,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,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,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,83,84,65,84,73,67,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,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,111,102, +32,110,101,105,103,104,98,111,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,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73, +84,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +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,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,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +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,32,32,32,32, +32,32,60,115,105,122,101,62,50,44,50,60,47,115,105,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, +110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, +73,78,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,62,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,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,105,110,62,48,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,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97, +120,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78, +60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,75,95,73,78,86, +69,82,83,69,95,68,73,83,84,65,78,67,69,95,75,78,78,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78, 67,69,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 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,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +108,97,98,101,108,62,85,115,101,32,105,110,118,101,114,115,101,32,100,105, +115,116,97,110,99,101,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,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,85,83,69,95,73, -78,86,69,82,83,69,95,68,73,83,84,65,78,67,69,95,75,78,78,34,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, -32,105,110,118,101,114,115,101,32,100,105,115,116,97,110,99,101,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,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,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,102,108,97,103,62,119,120,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,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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,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,60,115,105,122,101,62,49,48,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,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,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,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32, 32,32,32,32,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,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,119, +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,32, -32,32,32,32,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,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,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,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,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,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, -83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82, +95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,80,111,119,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,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,124,119,120,84,69,95,82,73,71,72,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, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,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, -67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +62,119,120,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,32,32,32,32,32,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,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82,95,75,78,78,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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, -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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,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,84,69,95,82,69,65,68,79, -78,76,89,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,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,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112, +105,110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83, +80,73,78,95,80,79,87,69,82,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,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,115,116,121,108,101,62,119,120,83,80,95,86,69,82,84, +73,67,65,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,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,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, +32,32,32,32,32,60,118,97,108,117,101,62,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,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,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, -110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, -73,78,95,80,79,87,69,82,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73, -67,65,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,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, 62,49,48,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -23341,7 +23526,7 @@ static unsigned char xml_res_file_8[] = { 108,97,103,62,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,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,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,49,53,60,47,98,111,114,100,101,114,62, +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,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, @@ -23350,7 +23535,7 @@ static unsigned char xml_res_file_8[] = { 101,108,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,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,115,105,122,101,62,53,48,48,44,52,56,48,60,47, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,48,48,44,53,48,48,60,47, 115,105,122,101,62,10,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32, @@ -32729,97 +32914,98 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,60,111,98,106,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,60,108,97,98,101,108,62,66,97,115,101, -109,97,112,32,83,111,117,114,99,101,115,58,32,40,110,97,109,101,44,98,97, -115,101,109,97,112,95,117,114,108,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,76,69,70,84,124,119,120,65,76,76,124,119,120,65,76, -73,71,78,95,76,69,70,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,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,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73, -68,67,95,66,65,83,69,77,65,80,95,83,79,85,82,67,69,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, -48,48,44,50,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,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,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,32,32,32,32,32, +109,97,112,32,83,111,117,114,99,101,115,58,32,40,70,111,114,109,97,116, +58,32,103,114,111,117,112,95,110,97,109,101,46,98,97,115,101,109,97,112, +95,110,97,109,101,44,98,97,115,101,109,97,112,95,117,114,108,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,76,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,49,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,62,10,32,32,32,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,109,97,112,32,80,97,114,97,109,101,116,101,114,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,60,47,111,98,106,101,99,116,62,10,32,32,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, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120, 65,76,76,124,119,120,65,76,73,71,78,95,76,69,70,84,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,73,68,67,95,66,65,83,69,77,65,80,95,83,79,85,82,67, +69,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,48,48,44,50,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,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, +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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,124,119,120,65,76,76,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,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,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,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,49,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,62,10,32,32,32,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,109,97,112,32,80,97,114,97,109,101, +116,101,114,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,60,47,111,98,106,101,99,116,62,10,32,32,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,65,76,76,124,119,120,65,76,73,71,78,95,76,69,70, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,95,83,84,65,84,73,67,84,69,88,84,34,62,10,32,32,32,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, -69,82,69,32,65,112,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,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,84,101,120,116,67,116,114,108,34,32,110, -97,109,101,61,34,73,68,67,95,78,79,75,73,65,95,85,83,69,82,78,65,77,69, -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,48,44,45,49,60,47,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, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,95,83,84,65,84,73,67,84,69,88,84,34,62,10, +32,32,32,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,69,82,69,32,65,112,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,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,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,78,79,75,73,65,95,85,83,69,82, +78,65,77,69,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,48,44,45,49,60,47,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, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,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,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, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,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,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,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,34,62,10,32,32,32, -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,69,82,69,32,65,112,112,32,75,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,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,34,62,10,32, +32,32,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,69,82,69,32,65,112,112,32,75,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,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,78, diff --git a/rc/dialogs.xrc b/rc/dialogs.xrc index 22570674c..f408b434a 100644 --- a/rc/dialogs.xrc +++ b/rc/dialogs.xrc @@ -3579,7 +3579,7 @@ - + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL @@ -3591,53 +3591,126 @@ 2 - - - - - wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL - 2 - - - - 98,-1d - - wxALIGN_CENTER - 2 - - - - 40,-1d - - wxALIGN_CENTER - - - - - - wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL - 2 - - - - 98,-1d + 3 + 1 + 5 + 5 + + wxALIGN_LEFT|wxALL + 2 + + + + wxALIGN_LEFT|wxALL + 2 + + + + + + + + + + wxVERTICAL + + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 10 + + wxHORIZONTAL + + 30,2 + + + + + + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxALL + 2 + + + + 60,-1d + + wxALIGN_CENTER|wxALL + 2 + + + + 40,-1d + + wxALIGN_CENTER + + + + + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 10 + + wxHORIZONTAL + + 30,2 + + + + + + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxALL + 2 + + + + 60,-1d + + wxALIGN_CENTER|wxALL + 2 + + + + 40,-1d + + wxALIGN_CENTER + + + + - wxALIGN_CENTER - 2 + + wxALL|wxEXPAND - - - 40,-1d + + + + wxVERTICAL + + wxALIGN_CENTER + 1 + + wxHORIZONTAL + + + + 150,30d + + + wxALIGN_CENTER + + + + + 280,-1d - wxALIGN_CENTER + + wxALL|wxEXPAND - 3 - 3 - 5 - 5 + + wxALIGN_LEFT|wxALL 2 + + + @@ -4026,14 +4099,14 @@ wxALIGN_CENTRE_HORIZONTAL|wxALL|wxEXPAND - 15 + 10 wxALL|wxEXPAND - 500,480 + 500,500 wxALL|wxEXPAND wxALL|wxEXPAND|wxALIGN_CENTRE_HORIZONTAL From cef9860c9156d422a753d35cb7a4b7c645b1a498 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 19 Nov 2018 12:42:56 -0700 Subject: [PATCH 23/39] time editor - incorrect number of views open #1754 --- DialogTools/WeightsManDlg.cpp | 4 ++++ TemplateFrame.cpp | 6 ++++++ TemplateFrame.h | 3 +-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/DialogTools/WeightsManDlg.cpp b/DialogTools/WeightsManDlg.cpp index 5e825b419..7e17c07d1 100644 --- a/DialogTools/WeightsManDlg.cpp +++ b/DialogTools/WeightsManDlg.cpp @@ -65,6 +65,10 @@ create_btn(0), load_btn(0), remove_btn(0), w_list(0) panel->SetBackgroundColour(*wxWHITE); SetBackgroundColour(*wxWHITE); + // time editor - incorrect number of views open #1754 + bool is_any_time_variant = false; + SetDependsOnNonSimpleGroups(is_any_time_variant); + create_btn = new wxButton(panel, XRCID("ID_CREATE_BTN"), _("Create"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); load_btn = new wxButton(panel, XRCID("ID_LOAD_BTN"), _("Load"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); diff --git a/TemplateFrame.cpp b/TemplateFrame.cpp index c7c8e734f..6a55eba51 100644 --- a/TemplateFrame.cpp +++ b/TemplateFrame.cpp @@ -753,6 +753,12 @@ void TemplateFrame::update(TimeState* o) { } +void TemplateFrame::SetDependsOnNonSimpleGroups(bool v) +{ + depends_on_non_simple_groups = v; + +} + bool TemplateFrame::AllowTimelineChanges() { if (supports_timeline_changes) return true; diff --git a/TemplateFrame.h b/TemplateFrame.h index 8e930a36b..c4152da24 100644 --- a/TemplateFrame.h +++ b/TemplateFrame.h @@ -129,8 +129,7 @@ class TemplateFrame: public wxFrame, public FramesManagerObserver, virtual void RemoveGroupDependancy(const wxString& grp_nm); virtual void ClearAllGroupDependencies(); - virtual void SetDependsOnNonSimpleGroups(bool v) { - depends_on_non_simple_groups = v; } + virtual void SetDependsOnNonSimpleGroups(bool v); virtual int GetCurrentCanvasTimeStep(); From 272ff3934d84cbfe41a06da46fb4b466b15e32eb Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 19 Nov 2018 14:41:34 -0700 Subject: [PATCH 24/39] bivariate Moran scatterplot crashes #1752 #1753 --- Explore/LisaScatterPlotView.cpp | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/Explore/LisaScatterPlotView.cpp b/Explore/LisaScatterPlotView.cpp index 2afbac965..2f09590f0 100644 --- a/Explore/LisaScatterPlotView.cpp +++ b/Explore/LisaScatterPlotView.cpp @@ -111,7 +111,7 @@ void LisaScatterPlotCanvas::ShowRegimesRegression(bool flag) void LisaScatterPlotCanvas::OnRandDlgClose( wxWindowDestroyEvent& event) { - rand_dlg = 0; + rand_dlg = NULL; } void LisaScatterPlotCanvas::DisplayRightClickMenu(const wxPoint& pos) @@ -832,7 +832,7 @@ void LisaScatterPlotCanvas::PopCanvPreResizeShpsHook() wxString s("Moran's I: "); s << regressionXY.beta; - int t = project->GetTimeState()->GetCurrTime(); + int t = var_info_orig[0].time-var_info_orig[0].time_min; if (t >= lisa_coord->Gal_vecs.size()) { return; } @@ -866,8 +866,6 @@ void LisaScatterPlotCanvas::ShowRandomizationDialog(int permutation) } else if (permutation > 99999) { permutation = 99999; } - - int cts = project->GetTimeState()->GetCurrTime(); std::vector raw_data1(num_obs); @@ -890,40 +888,38 @@ void LisaScatterPlotCanvas::ShowRandomizationDialog(int permutation) raw_data2[i] = lisa_coord->data2_vecs[yt][i]; } - if (rand_dlg != 0) { + if (rand_dlg != NULL) { rand_dlg->Destroy(); - rand_dlg = 0; + delete rand_dlg; + rand_dlg = NULL; } // here W handles undefined rand_dlg = new RandomizationDlg(raw_data1, raw_data2, - lisa_coord->Gal_vecs[cts], - lisa_coord->undef_tms[cts], + lisa_coord->Gal_vecs[xt], + lisa_coord->undef_tms[xt], highlight_state->GetHighlight(), is_show_regimes_regression, permutation, reuse_last_seed, last_used_seed, this); - rand_dlg->Connect(wxEVT_DESTROY, - wxWindowDestroyEventHandler(LisaScatterPlotCanvas::OnRandDlgClose), - NULL, this); + rand_dlg->Connect(wxEVT_DESTROY, wxWindowDestroyEventHandler(LisaScatterPlotCanvas::OnRandDlgClose), NULL, this); rand_dlg->Show(true); } else { - if (rand_dlg != 0) { + if (rand_dlg != NULL) { rand_dlg->Destroy(); - rand_dlg = 0; + delete rand_dlg; + rand_dlg = NULL; } - rand_dlg = new RandomizationDlg(raw_data1, lisa_coord->Gal_vecs[cts], - lisa_coord->undef_tms[cts], + rand_dlg = new RandomizationDlg(raw_data1, lisa_coord->Gal_vecs[xt], + lisa_coord->undef_tms[xt], highlight_state->GetHighlight(), is_show_regimes_regression, permutation, reuse_last_seed, last_used_seed, this); - rand_dlg->Connect(wxEVT_DESTROY, - wxWindowDestroyEventHandler(LisaScatterPlotCanvas::OnRandDlgClose), - NULL, this); + rand_dlg->Connect(wxEVT_DESTROY, wxWindowDestroyEventHandler(LisaScatterPlotCanvas::OnRandDlgClose), NULL, this); rand_dlg->Show(true); } } From 32509230c0cfb511b5c9f99ab50b4590bb8af5e4 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 19 Nov 2018 14:51:47 -0700 Subject: [PATCH 25/39] restore weights enhancement --- DialogTools/CreatingWeightDlg.cpp | 59 +- DialogTools/CreatingWeightDlg.h | 7 +- rc/GdaAppResources.cpp | 1380 +++++++++++++---------------- rc/dialogs.xrc | 159 +--- 4 files changed, 644 insertions(+), 961 deletions(-) diff --git a/DialogTools/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp index 06bc7cca1..4cd79e56a 100644 --- a/DialogTools/CreatingWeightDlg.cpp +++ b/DialogTools/CreatingWeightDlg.cpp @@ -70,7 +70,6 @@ EVT_CHECKBOX( XRCID("IDC_CHK_INVERSE_DISTANCE"), CreatingWeightDlg::OnInverseDis EVT_CHECKBOX( XRCID("IDC_CHK_INVERSE_DISTANCE_KNN"), CreatingWeightDlg::OnInverseKNNCheck) EVT_SPIN( XRCID("IDC_SPIN_POWER"), CreatingWeightDlg::OnCSpinPowerInverseDistUpdated ) EVT_SPIN( XRCID("IDC_SPIN_POWER_KNN"), CreatingWeightDlg::OnCSpinPowerInverseKNNUpdated ) -EVT_NOTEBOOK_PAGE_CHANGED( XRCID("IDC_WEIGHTS_DIST_VARS_LIST"), CreatingWeightDlg::OnDistanceWeightsInputUpdate ) END_EVENT_TABLE() @@ -179,8 +178,6 @@ void CreatingWeightDlg::CreateControls() m_X_time = XRCCTRL(*this, "IDC_XCOORD_TIME", wxChoice); m_Y = XRCCTRL(*this, "IDC_YCOORDINATES", wxChoice); m_Y_time = XRCCTRL(*this, "IDC_YCOORD_TIME", wxChoice); - m_Vars = XRCCTRL(*this, "IDC_WEIGHTS_DIST_VARS_LIST", wxListBox); - m_nb_distance_variables = XRCCTRL(*this, "IDC_NB_DISTANCE_VARIABLES", wxNotebook); m_nb_distance_methods = XRCCTRL(*this, "IDC_NB_DISTANCE_WEIGHTS", wxNotebook); m_threshold = XRCCTRL(*this, "IDC_THRESHOLD_EDIT", wxTextCtrl); m_sliderdistance = XRCCTRL(*this, "IDC_THRESHOLD_SLIDER", wxSlider); @@ -212,48 +209,9 @@ void CreatingWeightDlg::CreateControls() m_power->Enable(false); m_power_knn->Enable(false); - m_nb_distance_variables->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, &CreatingWeightDlg::OnDistanceWeightsInputUpdate, this); - m_Vars->Bind(wxEVT_LISTBOX, &CreatingWeightDlg::OnDistanceWeightsVarsSel, this); - InitDlg(); } -void CreatingWeightDlg::OnDistanceWeightsVarsSel( wxCommandEvent& event ) -{ - // update Threshold values for distance weight - wxArrayInt selections; - m_Vars->GetSelections(selections); - int num_var = selections.size(); - if (num_var <= 0) { - return; - } - for (int i=0; iGetString(idx); - - // get data [] - //int col = table_int->FindColId(nm); - } -} - -void CreatingWeightDlg::OnDistanceWeightsInputUpdate( wxBookCtrlEvent& event ) -{ - int sel = event.GetSelection(); - if (sel == 0) { - UpdateThresholdValues(); - } else { - wxArrayInt selections; - m_Vars->GetSelections(selections); - int n_sel = selections.GetCount(); - if (n_sel <= 0) { - m_thres_val_valid = false; - m_threshold->ChangeValue("0"); - m_bandwidth_thres_val_valid = false; - m_manu_bandwidth->ChangeValue("0"); - } - } -} - void CreatingWeightDlg::OnCreateNewIdClick( wxCommandEvent& event ) { wxLogMessage("Click CreatingWeightDlg::OnCreateNewIdClick"); @@ -613,27 +571,14 @@ void CreatingWeightDlg::InitFields() m_id_field->Clear(); m_X_time->Clear(); m_Y_time->Clear(); - m_Vars->Clear(); - ResetThresXandYCombo(); for (int i=0, iend=col_id_map.size(); iGetColName(col); - m_X->Append(name); - m_Y->Append(name); + m_X->Append(table_int->GetColName(col)); + m_Y->Append(table_int->GetColName(col)); - if (table_int->IsColTimeVariant(col)) { - for (int t=0; tGetColTimeSteps(col); t++) { - wxString nm = name; - nm << " (" << table_int->GetTimeString(t) << ")"; - m_Vars->Append(nm); - } - } else { - m_Vars->Append(name); - } - if (table_int->GetColType(col) == GdaConst::long64_type || table_int->GetColType(col) == GdaConst::string_type) { if (!table_int->IsColTimeVariant(col)) { diff --git a/DialogTools/CreatingWeightDlg.h b/DialogTools/CreatingWeightDlg.h index 3843ab75a..e7efa9d45 100644 --- a/DialogTools/CreatingWeightDlg.h +++ b/DialogTools/CreatingWeightDlg.h @@ -90,8 +90,7 @@ public TableStateObserver, public WeightsManStateObserver void OnCThresholdSliderUpdated( wxCommandEvent& event ); void OnCSpinPowerInverseDistUpdated( wxSpinEvent& event ); void OnCSpinPowerInverseKNNUpdated( wxSpinEvent& event ); - void OnDistanceWeightsInputUpdate( wxBookCtrlEvent& event ); - void OnDistanceWeightsVarsSel( wxCommandEvent& event ); + /** Implementation of FramesManagerObserver interface */ virtual void update(FramesManager* o); @@ -130,9 +129,7 @@ public TableStateObserver, public WeightsManStateObserver wxChoice* m_X_time; wxChoice* m_Y; wxChoice* m_Y_time; - wxListBox* m_Vars; - wxNotebook* m_nb_distance_variables; - wxNotebook* m_nb_distance_methods; + wxNotebook* m_nb_distance_methods; wxTextCtrl* m_threshold; wxSlider* m_sliderdistance; wxCheckBox* m_use_inverse; diff --git a/rc/GdaAppResources.cpp b/rc/GdaAppResources.cpp index d8ed25eb1..4e3477530 100644 --- a/rc/GdaAppResources.cpp +++ b/rc/GdaAppResources.cpp @@ -15530,7 +15530,7 @@ static unsigned char xml_res_file_7[] = { 16,48,4,12,1,67,192,16,48,4,12,1,67,160,133,35,240,255,75,175,9,51,209, 227,12,205,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_8 = 389594; +static size_t xml_res_size_8 = 385362; 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,117,116,102,45,56,34,63,62,10,60,114,101, @@ -22203,523 +22203,305 @@ static unsigned char xml_res_file_8[] = { 34,32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,95,68,73,83,84, 95,77,69,84,82,73,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,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,116,97,110,99,101,32,109,101,116,114,105,99,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,76,69,70,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, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,68,73,83,84,65,78,67,69,95,77, -69,84,82,73,67,34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,32,32,32,32,60,118,103,97,112,62,53,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,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,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,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,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,102, -108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,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,60,111,98,106,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,86,97, -114,105,97,98,108,101,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,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,73,68,67,95,78,66,95,68,73,83,84,65,78,67,69,95,86,65, -82,73,65,66,76,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,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,73,68,67,95,78,66,95,80,65,71,69,95,71,69,79,77,95,67,69,78,84, -82,79,73,68,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +115,116,97,110,99,101,32,109,101,116,114,105,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,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,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,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,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, -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,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,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,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,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,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,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, -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,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,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,32,32,32, -32,32,32,60,115,105,122,101,62,51,48,44,50,60,47,115,105,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, -83,84,65,84,73,67,95,88,67,79,79,82,68,95,86,65,82,34,62,10,32,32,32,32, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,68,73,83,84,65,78,67,69,95,77,69,84, +82,73,67,34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,88,45,99,111,111, -114,100,105,110,97,116,101,32,118,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,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,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, -67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47, 102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,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,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,88,67,79,79,82,68,73,78,65,84, -69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,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,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,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,73,68,67, -95,88,67,79,79,82,68,95,84,73,77,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,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,73,68,67,95,83,84,65,84,73,67,95,88,67,79,79,82,68,95,86,65,82,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,88,45,99,111,111,114,100,105, +110,97,116,101,32,118,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,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,32,32,60,102,108,97,103,62,119,120,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,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,88,67,79,79,82,68,73,78,65,84,69,83, +34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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, +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,73,68,67,95,88,67,79,79,82,68,95, +84,73,77,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,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,83,84,65,84,73,67,95,89,67,79,79,82,68,95,86,65,82,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,48,44,50,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,89,45,99,111,111,114,100,105,110,97,116,101, +32,118,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,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,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,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,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,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,95,89,67,79,79,82,68,95, -86,65,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,89,45,99,111,111,114,100,105,110,97,116,101,32,118,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,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,99,108,97,115,115,61,34,119,120,67,104,111,105,99,101,34,32,110,97,109, +101,61,34,73,68,67,95,89,67,79,79,82,68,73,78,65,84,69,83,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,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, +32,32,60,115,105,122,101,62,57,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,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,89,67,79,79, -82,68,73,78,65,84,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,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,32,32, -32,32,32,32,32,32,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,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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, +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,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,89,67,79,79,82,68,95,84,73,77,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,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +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,73,68,67,95,89,67,79,79,82,68,95,84,73,77,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,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, 97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97, 103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,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,111,109,101,116,114,105,99,32,99,101,110,116,114,111,105, -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,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,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,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,73,68,67,95,78,66,95,80,65,71,69,95,77,85,76,84,73,95,86,65,82,83, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,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,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,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,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,49,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,87,69,73,71,72,84,83,95,68,73,83, -84,95,86,65,82,83,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,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,32,32,60,115,105,122,101,62,49,53,48,44,51,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,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,76,66,95,77,85,76,84,73,80,76,69,32,124,32,119,120, -76,66,95,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,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,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,60,118,103,97,112,62,53,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,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,56,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,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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, -45,118,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,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,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,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,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,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,60,111,98,106, -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,77,101,116,104,111,100,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,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,78,66,95, -68,73,83,84,65,78,67,69,95,87,69,73,71,72,84,83,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -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,73,68,67,95,82,65,68,73,79,95,68, -73,83,84,65,78,67,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,32,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,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,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,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, -84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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, +62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,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,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,73,68,67,95,78,66,95,68,73,83,84,65,78,67,69,95,87,69,73,71,72, +84,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,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,73, +68,67,95,82,65,68,73,79,95,68,73,83,84,65,78,67,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,32,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,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,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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,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, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,112,101, -99,105,102,121,32,98,97,110,100,119,105,100,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,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -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,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,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,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,111,98,106,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,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,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, +60,108,97,98,101,108,62,83,112,101,99,105,102,121,32,98,97,110,100,119, +105,100,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,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, -101,61,34,73,68,67,95,84,72,82,69,83,72,79,76,68,95,69,68,73,84,34,62,10, +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,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,57,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,102,108,97,103,62,119,120,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,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,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,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,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,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +84,72,82,69,83,72,79,76,68,95,69,68,73,84,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,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,57,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,32,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,73,71,72,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,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,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,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, 32,32,32,32,32,32,32,32,32,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,48,44,50,60,47,115,105,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,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,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,108,105,100,101,114,34,32,110,97,109,101,61,34,73,68,67,95,84,72, -82,69,83,72,79,76,68,95,83,76,73,68,69,82,34,62,10,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,48,44,50,60,47,115,105,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,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,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,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,62,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,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,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,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,97,120,62,49,48,48,60,47,109,97,120, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,76,95,72,79,82,73,90,79,78,84,65,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,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,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, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,108,105, +100,101,114,34,32,110,97,109,101,61,34,73,68,67,95,84,72,82,69,83,72,79, +76,68,95,83,76,73,68,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,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,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,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,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,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,32,32, +60,109,105,110,62,48,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,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,60,115,116,121,108,101,62,119,120,83,76, +95,72,79,82,73,90,79,78,84,65,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,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73, -68,67,95,67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78,67,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62, -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,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73, -83,84,65,78,67,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,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,105,110,118,101,114,115,101,32,100,105, -115,116,97,110,99,101,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,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,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,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,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,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78,67,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,32, -32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,48,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,32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, @@ -22727,314 +22509,347 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,119, -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,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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, +101,61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73,83,84,65, +78,67,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,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,105,110,118,101,114,115,101,32,100,105,115,116, +97,110,99,101,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, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,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,84,69,95,82,69,65,68, -79,78,76,89,124,119,120,84,69,95,82,73,71,72,84,60,47,115,116,121,108,101, +32,32,32,60,102,108,97,103,62,119,120,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, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,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, -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,60,102,108,97,103,62,119,120,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,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,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,48,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,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,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,60,108,97,98,101,108,62,80,111,119,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,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, -110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, -73,78,95,80,79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82,34,62,10, 32,32,32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,60,115,105,122,101,62,50,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,32,32,32,32,32,32,32,32,32,32,32, -60,118,97,108,117,101,62,48,60,47,118,97,108,117,101,62,10,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48, -60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,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,116,97,110,99,101,32,98,97,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, -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,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,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,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,60,102,108,97,103,62,119,120,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,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,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, -73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -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,124,119,120,65,68,74,85,83,84,95,77,73,78,83,73,90,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,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, +102,108,97,103,62,119,120,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,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,83,84,65,84,73,67,95,75,78,78,34,62,10,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80,73,78,95,80, +79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,62,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,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,111,102, -32,110,101,105,103,104,98,111,114,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,109,105,110,62,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,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, -120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73, -84,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -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,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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,116,97,110,99,101,32,98,97,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,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,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,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, +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,32,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, 62,119,120,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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,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,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, 32,32,32,32,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,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,124,119,120,65,68,74,85,83,84,95,77,73,78,83,73,90,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,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,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,83, +84,65,84,73,67,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,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,111,102,32,110,101, +105,103,104,98,111,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,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,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,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, -110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, -73,78,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,62,48,60,47,118,97,108,117,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,32,32,32,32,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,105,110,62,48,60,47,109,105,110,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,75,78, +78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97, -120,62,10,32,32,32,32,32,32,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,84,69,95,82,69,65, +68,79,78,76,89,124,119,120,84,69,95,82,73,71,72,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,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +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,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,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, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,115,105, +122,101,62,50,44,50,60,47,115,105,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,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,73,68,67,95,83,80,73,78,95,75,78,78,34,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,76,60,47,102,108,97,103,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,80,95,86,69,82,84,73,67,65,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, -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,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,105,110,62,48,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,32,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,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,60,109,97,120,62,49,48,48,60,47,109,97,120,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,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,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,75,95,73,78,86, -69,82,83,69,95,68,73,83,84,65,78,67,69,95,75,78,78,34,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +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,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, -61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78, +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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78, 67,69,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,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,105,110,118,101,114,115,101,32,100,105, -115,116,97,110,99,101,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +118,97,108,117,101,62,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,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,85,83,69,95,73, +78,86,69,82,83,69,95,68,73,83,84,65,78,67,69,95,75,78,78,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,60,108,97,98,101,108,62,85,115,101, +32,105,110,118,101,114,115,101,32,100,105,115,116,97,110,99,101,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,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,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,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,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,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,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,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,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,119, -101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,49,48,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82, -95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, +83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,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,84,69,95,82, -69,65,68,79,78,76,89,124,119,120,84,69,95,82,73,71,72,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, +32,32,32,32,32,60,108,97,98,101,108,62,80,111,119,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,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,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, +62,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,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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +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,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82,95,75,78,78,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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, +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,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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, +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, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112, -105,110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83, -80,73,78,95,80,79,87,69,82,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,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,83,80,95,86,69,82,84, -73,67,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,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,48,60,47,118,97,108,117,101,62, +32,32,60,102,108,97,103,62,119,120,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, +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,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, +110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, +73,78,95,80,79,87,69,82,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73, +67,65,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,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, 62,49,48,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -23526,7 +23341,7 @@ static unsigned char xml_res_file_8[] = { 108,97,103,62,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,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,32,32,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, +32,32,60,98,111,114,100,101,114,62,49,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, @@ -23535,7 +23350,7 @@ static unsigned char xml_res_file_8[] = { 101,108,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,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,115,105,122,101,62,53,48,48,44,53,48,48,60,47, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,48,48,44,52,56,48,60,47, 115,105,122,101,62,10,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32, @@ -32914,98 +32729,97 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,60,111,98,106,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,60,108,97,98,101,108,62,66,97,115,101, -109,97,112,32,83,111,117,114,99,101,115,58,32,40,70,111,114,109,97,116, -58,32,103,114,111,117,112,95,110,97,109,101,46,98,97,115,101,109,97,112, -95,110,97,109,101,44,98,97,115,101,109,97,112,95,117,114,108,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, +109,97,112,32,83,111,117,114,99,101,115,58,32,40,110,97,109,101,44,98,97, +115,101,109,97,112,95,117,114,108,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,76,69,70,84,124,119,120,65,76,76,124,119,120,65,76, +73,71,78,95,76,69,70,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,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,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73, +68,67,95,66,65,83,69,77,65,80,95,83,79,85,82,67,69,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, +48,48,44,50,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,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,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,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,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, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,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,49,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,62,10,32,32,32,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,109,97,112,32,80,97,114,97,109,101,116,101,114,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,60,47,111,98,106,101,99,116,62,10,32,32,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, 65,76,76,124,119,120,65,76,73,71,78,95,76,69,70,84,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, -110,97,109,101,61,34,73,68,67,95,66,65,83,69,77,65,80,95,83,79,85,82,67, -69,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,48,48,44,50,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,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, -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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,124,119,120,65,76,76,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,49,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,62,10,32,32,32,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,109,97,112,32,80,97,114,97,109,101, -116,101,114,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,60,47,111,98,106,101,99,116,62,10,32,32,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,65,76,76,124,119,120,65,76,73,71,78,95,76,69,70, -84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,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,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,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,73,68,95,83,84,65,84,73,67,84,69,88,84,34,62,10,32,32,32,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, +69,82,69,32,65,112,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,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,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,95,83,84,65,84,73,67,84,69,88,84,34,62,10, -32,32,32,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,69,82,69,32,65,112,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,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,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,78,79,75,73,65,95,85,83,69,82, -78,65,77,69,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,48,44,45,49,60,47,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, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,73,68,67,95,78,79,75,73,65,95,85,83,69,82,78,65,77,69, +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,48,44,45,49,60,47,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, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,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,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, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,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,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,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,34,62,10,32, -32,32,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,69,82,69,32,65,112,112,32,75,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,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,34,62,10,32,32,32, +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,69,82,69,32,65,112,112,32,75,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,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,78, diff --git a/rc/dialogs.xrc b/rc/dialogs.xrc index f408b434a..22570674c 100644 --- a/rc/dialogs.xrc +++ b/rc/dialogs.xrc @@ -3579,7 +3579,7 @@ - + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL @@ -3591,126 +3591,53 @@ 2 - 3 - 1 - 5 - 5 - - wxALIGN_LEFT|wxALL - 2 - - - - wxALIGN_LEFT|wxALL - 2 - - - - - - - - - - wxVERTICAL - - wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT - 10 - - wxHORIZONTAL - - 30,2 - - - - - - wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxALL - 2 - - - - 60,-1d - - wxALIGN_CENTER|wxALL - 2 - - - - 40,-1d - - wxALIGN_CENTER - - - - - wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT - 10 - - wxHORIZONTAL - - 30,2 - - - - - - wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxALL - 2 - - - - 60,-1d - - wxALIGN_CENTER|wxALL - 2 - - - - 40,-1d - - wxALIGN_CENTER - - - - + + + - - wxALL|wxEXPAND + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL + 2 - - - - wxVERTICAL - - wxALIGN_CENTER - 1 - - wxHORIZONTAL - - - - 150,30d - - - wxALIGN_CENTER - - - - - 280,-1d + + + 98,-1d - - wxALL|wxEXPAND + wxALIGN_CENTER + 2 + + + + 40,-1d + + wxALIGN_CENTER + + + + + + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL + 2 + + + + 98,-1d + + wxALIGN_CENTER + 2 + + + 40,-1d + + wxALIGN_CENTER + + 3 + 3 + 5 + 5 - - wxALIGN_LEFT|wxALL 2 - - - @@ -4099,14 +4026,14 @@ wxALIGN_CENTRE_HORIZONTAL|wxALL|wxEXPAND - 10 + 15 wxALL|wxEXPAND - 500,500 + 500,480 wxALL|wxEXPAND wxALL|wxEXPAND|wxALIGN_CENTRE_HORIZONTAL From dccaa076ebdd3fe1c0999415878373ed326975b2 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 19 Nov 2018 14:52:04 -0700 Subject: [PATCH 26/39] Update version.h --- version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.h b/version.h index 362648302..56a3e772e 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 12; const int version_build = 1; - const int version_subbuild = 175; + const int version_subbuild = 177; const int version_year = 2018; const int version_month = 11; - const int version_day = 13; + const int version_day = 19; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From 49c9b2121cd4306275e01f49c4127cbe1a9cc125 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 19 Nov 2018 16:21:19 -0700 Subject: [PATCH 27/39] bivariate Moran scatterplot crashes #1752 #1753 --- Explore/LisaScatterPlotView.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Explore/LisaScatterPlotView.cpp b/Explore/LisaScatterPlotView.cpp index 2f09590f0..9525d5b83 100644 --- a/Explore/LisaScatterPlotView.cpp +++ b/Explore/LisaScatterPlotView.cpp @@ -539,7 +539,12 @@ void LisaScatterPlotCanvas::PopulateCanvas() if (is_show_regimes_regression) { const std::vector& hl = highlight_state->GetHighlight(); - int t = project->GetTimeState()->GetCurrTime(); + //int t = project->GetTimeState()->GetCurrTime(); + int t = var_info_orig[0].time-var_info_orig[0].time_min; + if (is_diff) { + // in case its differential moran, there is only one grouped variable + t = 0; + } int num_obs = lisa_coord->num_obs; std::vector undefs(num_obs, false); @@ -753,7 +758,12 @@ void LisaScatterPlotCanvas::RegimeMoran(std::vector& undefs, std::vector& X, std::vector& Y) { - int t = project->GetTimeState()->GetCurrTime(); + //int t = project->GetTimeState()->GetCurrTime(); + int t = var_info_orig[0].time-var_info_orig[0].time_min; + if (is_diff) { + // in case its differential moran, there is only one grouped variable + t = 0; + } GalWeight* copy_w = new GalWeight(*lisa_coord->Gal_vecs[t]); copy_w->Update(undefs); GalElement* W = copy_w->gal; From 652bff9acd226a38556eb816d390cc9f259e069e Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 19 Nov 2018 20:42:26 -0700 Subject: [PATCH 28/39] k medians cluster map - incorrect heading #1755 e should report the proper center and make sure they are labeled, e.g. Cluster centers (median): and Cluster centers (medoid): --- DialogTools/AbstractClusterDlg.cpp | 2 +- DialogTools/AbstractClusterDlg.h | 3 ++- DialogTools/KMeansDlg.cpp | 10 ++++++++-- DialogTools/KMeansDlg.h | 5 +---- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/DialogTools/AbstractClusterDlg.cpp b/DialogTools/AbstractClusterDlg.cpp index b51857cc8..c3d67f258 100644 --- a/DialogTools/AbstractClusterDlg.cpp +++ b/DialogTools/AbstractClusterDlg.cpp @@ -842,7 +842,7 @@ double AbstractClusterDlg::_calcSumOfSquares(const vector& cluster_ids) wxString AbstractClusterDlg::_printMeanCenters(const vector >& mean_centers) { wxString txt; - txt << _("Cluster centers:\n"); + txt << _("Cluster centers:") << mean_center_type << "\n"; stringstream ss; TextTable t( TextTable::MD ); diff --git a/DialogTools/AbstractClusterDlg.h b/DialogTools/AbstractClusterDlg.h index d9fdead19..1273cccd0 100644 --- a/DialogTools/AbstractClusterDlg.h +++ b/DialogTools/AbstractClusterDlg.h @@ -158,6 +158,7 @@ class AbstractClusterDlg : public wxDialog, public FramesManagerObserver, public // - the between sum of squares // - the ratio of between to total sum of squares // -- variables + wxString mean_center_type; SimpleReportTextCtrl* m_reportbox; wxNotebook* AddSimpleReportCtrls(wxPanel *panel); // -- functions @@ -165,7 +166,7 @@ class AbstractClusterDlg : public wxDialog, public FramesManagerObserver, public double _calcSumOfSquares(const vector& cluster_ids); virtual vector > _getMeanCenters(const vector >& solution); vector _getWithinSumOfSquares(const vector >& solution); - wxString _printMeanCenters(const vector >& mean_centers); + virtual wxString _printMeanCenters(const vector >& mean_centers); wxString _printWithinSS(const vector& within_ss); virtual wxString _printConfiguration()=0; double CreateSummary(const vector& clusters, bool show_print = true); diff --git a/DialogTools/KMeansDlg.cpp b/DialogTools/KMeansDlg.cpp index 786491988..c57918faf 100644 --- a/DialogTools/KMeansDlg.cpp +++ b/DialogTools/KMeansDlg.cpp @@ -225,6 +225,11 @@ void KClusterDlg::CreateControls() m_distance->Bind(wxEVT_CHOICE, &KClusterDlg::OnDistanceChoice, this); } +vector > KClusterDlg::_getMeanCenters(const vector >& solution) +{ + return AbstractClusterDlg::_getMeanCenters(solution); +} + void KClusterDlg::OnDistanceChoice(wxCommandEvent& event) { if (m_distance->GetSelection() == 1) { @@ -670,7 +675,7 @@ void KClusterDlg::OnOK(wxCommandEvent& event ) wxDefaultPosition, GdaConst::map_default_size); wxString ttl; - ttl << "KMeans " << _("Cluster Map ") << "("; + ttl << cluster_method << " " << _("Cluster Map ") << "("; ttl << ncluster; ttl << " clusters)"; nf->SetTitle(ttl); @@ -738,7 +743,7 @@ KMediansDlg::KMediansDlg(wxFrame *parent, Project* project) show_distance = true; show_iteration = true; cluster_method = "KMedians"; - + mean_center_type = " (median)"; CreateControls(); m_distance->SetSelection(1); // set manhattan m_distance->Disable(); @@ -818,6 +823,7 @@ KMedoidsDlg::KMedoidsDlg(wxFrame *parent, Project* project) show_distance = true; show_iteration = false; cluster_method = "KMedoids"; + mean_center_type = " (medoid)"; CreateControls(); m_distance->SetSelection(1); // set manhattan diff --git a/DialogTools/KMeansDlg.h b/DialogTools/KMeansDlg.h index 74bbb71e1..affdf737b 100644 --- a/DialogTools/KMeansDlg.h +++ b/DialogTools/KMeansDlg.h @@ -58,10 +58,7 @@ class KClusterDlg : public AbstractClusterDlg virtual void ComputeDistMatrix(int dist_sel); virtual wxString _printConfiguration(); - virtual vector > _getMeanCenters(const vector >& solution) { - return AbstractClusterDlg::_getMeanCenters(solution); - } - + virtual vector > _getMeanCenters(const vector >& solution); virtual void doRun(int s1, int ncluster, int npass, int n_maxiter, int meth_sel, int dist_sel, double min_bound, double* bound_vals)=0; std::vector var_info; From ee11ff23e6ebd348583e148fd09b59e3f63e59e9 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 21 Nov 2018 20:49:07 -0700 Subject: [PATCH 29/39] #1750 enhance weights function --- Algorithms/hdbscan.h | 2 +- .../macosx/GeoDa.xcodeproj/project.pbxproj | 26 +- DataViewer/OGRTable.cpp | 27 + DataViewer/OGRTable.h | 2 + DataViewer/TableInterface.h | 11 +- DialogTools/CreatingWeightDlg.cpp | 75 +- DialogTools/CreatingWeightDlg.h | 7 +- Weights/DistUtils.cpp | 109 ++ Weights/DistUtils.h | 42 + kNN/ANN.cpp | 251 +-- kNN/ANN.h | 507 ------- kNN/ANN/ANN.h | 830 ++++++++++ kNN/ANN/ANNperf.h | 223 +++ kNN/ANN/ANNx.h | 169 +++ kNN/ANNperf.h | 131 -- kNN/ANNx.h | 165 -- kNN/Makefile | 121 ++ kNN/bd_fix_rad_search.cpp | 61 + kNN/bd_pr_search.cpp | 62 + kNN/bd_search.cpp | 61 + kNN/bd_tree.cpp | 417 +++++ kNN/bd_tree.h | 100 ++ kNN/brute.cpp | 109 ++ kNN/kNN.cpp | 1 - kNN/kd_dump.cpp | 444 ++++++ kNN/kd_fix_rad_search.cpp | 183 +++ kNN/kd_fix_rad_search.h | 44 + kNN/kd_pr_search.cpp | 359 +++-- kNN/kd_pr_search.h | 65 +- kNN/kd_search.cpp | 336 ++-- kNN/kd_search.h | 65 +- kNN/kd_split.cpp | 702 +++++---- kNN/kd_split.h | 131 +- kNN/kd_tree.cpp | 570 ++++--- kNN/kd_tree.h | 250 +-- kNN/kd_util.cpp | 671 ++++---- kNN/kd_util.h | 217 +-- kNN/perf.cpp | 136 ++ kNN/pr_queue.h | 186 +-- kNN/pr_queue_k.h | 164 +- kNN/values.h | 1 - rc/GdaAppResources.cpp | 1348 ++++++++++------- rc/dialogs.xrc | 159 +- 43 files changed, 6183 insertions(+), 3357 deletions(-) create mode 100644 Weights/DistUtils.cpp create mode 100644 Weights/DistUtils.h mode change 100644 => 100755 kNN/ANN.cpp delete mode 100644 kNN/ANN.h create mode 100755 kNN/ANN/ANN.h create mode 100755 kNN/ANN/ANNperf.h create mode 100755 kNN/ANN/ANNx.h delete mode 100644 kNN/ANNperf.h delete mode 100644 kNN/ANNx.h create mode 100755 kNN/Makefile create mode 100755 kNN/bd_fix_rad_search.cpp create mode 100755 kNN/bd_pr_search.cpp create mode 100755 kNN/bd_search.cpp create mode 100755 kNN/bd_tree.cpp create mode 100755 kNN/bd_tree.h create mode 100755 kNN/brute.cpp delete mode 100644 kNN/kNN.cpp create mode 100755 kNN/kd_dump.cpp create mode 100755 kNN/kd_fix_rad_search.cpp create mode 100755 kNN/kd_fix_rad_search.h mode change 100644 => 100755 kNN/kd_pr_search.cpp mode change 100644 => 100755 kNN/kd_pr_search.h mode change 100644 => 100755 kNN/kd_search.cpp mode change 100644 => 100755 kNN/kd_search.h mode change 100644 => 100755 kNN/kd_split.cpp mode change 100644 => 100755 kNN/kd_split.h mode change 100644 => 100755 kNN/kd_tree.cpp mode change 100644 => 100755 kNN/kd_tree.h mode change 100644 => 100755 kNN/kd_util.cpp mode change 100644 => 100755 kNN/kd_util.h create mode 100755 kNN/perf.cpp mode change 100644 => 100755 kNN/pr_queue.h mode change 100644 => 100755 kNN/pr_queue_k.h delete mode 100644 kNN/values.h diff --git a/Algorithms/hdbscan.h b/Algorithms/hdbscan.h index 7eea18764..f3cd67839 100644 --- a/Algorithms/hdbscan.h +++ b/Algorithms/hdbscan.h @@ -26,7 +26,7 @@ #include #include -#include "../kNN/ANN.h" +#include "../kNN/ANN/ANN.h" #include "redcap.h" using namespace SpanningTreeClustering; diff --git a/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj b/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj index 6ef47b6a4..b593d9934 100644 --- a/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj +++ b/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ A12E0F4F1705087A00B6059C /* OGRDataAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A12E0F4E1705087A00B6059C /* OGRDataAdapter.cpp */; }; A1311C6720FFDF7100008D7F /* localjc_kernel.cl in CopyFiles */ = {isa = PBXBuildFile; fileRef = A4E00F0F20FD8ECC0038BA80 /* localjc_kernel.cl */; }; A13B6B9418760CF100F93ACF /* SaveAsDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A13B6B9318760CF100F93ACF /* SaveAsDlg.cpp */; }; + A14735AA21A5F72D00CA69B2 /* DistUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735A921A5F72D00CA69B2 /* DistUtils.cpp */; }; A14C496F1D76174000D9831C /* CsvFieldConfDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14C496D1D76174000D9831C /* CsvFieldConfDlg.cpp */; }; A16BA470183D626200D3B7DA /* DatasourceDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A16BA46E183D626200D3B7DA /* DatasourceDlg.cpp */; }; A186F0A11C16508A00AEBA13 /* GdaCartoDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A186F09F1C16508A00AEBA13 /* GdaCartoDB.cpp */; }; @@ -124,7 +125,6 @@ A4E5FE191F624D5600D75662 /* AggregateDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A4E5FE171F624D5600D75662 /* AggregateDlg.cpp */; }; A4ED7D442097EC55008685D6 /* ANN.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A4ED7D412097EC54008685D6 /* ANN.cpp */; }; A4ED7D472097EDE9008685D6 /* kd_tree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A4ED7D462097EDE9008685D6 /* kd_tree.cpp */; }; - A4ED7D542097F114008685D6 /* kNN.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A4ED7D4C2097F113008685D6 /* kNN.cpp */; }; A4ED7D552097F114008685D6 /* kd_pr_search.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A4ED7D4E2097F113008685D6 /* kd_pr_search.cpp */; }; A4ED7D562097F114008685D6 /* kd_search.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A4ED7D502097F114008685D6 /* kd_search.cpp */; }; A4ED7D572097F114008685D6 /* kd_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A4ED7D512097F114008685D6 /* kd_util.cpp */; }; @@ -324,6 +324,8 @@ A12E0F4E1705087A00B6059C /* OGRDataAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGRDataAdapter.cpp; sourceTree = ""; }; A13B6B9218760CF100F93ACF /* SaveAsDlg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveAsDlg.h; sourceTree = ""; }; A13B6B9318760CF100F93ACF /* SaveAsDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SaveAsDlg.cpp; sourceTree = ""; }; + A14735A821A5F72D00CA69B2 /* DistUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DistUtils.h; sourceTree = ""; }; + A14735A921A5F72D00CA69B2 /* DistUtils.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DistUtils.cpp; sourceTree = ""; }; A14C496D1D76174000D9831C /* CsvFieldConfDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CsvFieldConfDlg.cpp; sourceTree = ""; }; A14C496E1D76174000D9831C /* CsvFieldConfDlg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CsvFieldConfDlg.h; sourceTree = ""; }; A16BA46E183D626200D3B7DA /* DatasourceDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatasourceDlg.cpp; sourceTree = ""; }; @@ -510,17 +512,12 @@ A4E138BA1F71D6B800433256 /* GeocodingDlg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeocodingDlg.h; sourceTree = ""; }; A4E5FE171F624D5600D75662 /* AggregateDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AggregateDlg.cpp; sourceTree = ""; }; A4E5FE181F624D5600D75662 /* AggregateDlg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AggregateDlg.h; sourceTree = ""; }; - A4ED7D402097EC54008685D6 /* ANNx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ANNx.h; path = ../kNN/ANNx.h; sourceTree = ""; }; A4ED7D412097EC54008685D6 /* ANN.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ANN.cpp; path = ../kNN/ANN.cpp; sourceTree = ""; }; - A4ED7D422097EC54008685D6 /* ANNperf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ANNperf.h; path = ../kNN/ANNperf.h; sourceTree = ""; }; - A4ED7D432097EC55008685D6 /* ANN.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ANN.h; path = ../kNN/ANN.h; sourceTree = ""; }; - A4ED7D452097ECC6008685D6 /* values.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = values.h; sourceTree = ""; }; A4ED7D462097EDE9008685D6 /* kd_tree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kd_tree.cpp; sourceTree = ""; }; A4ED7D482097F113008685D6 /* kd_tree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kd_tree.h; sourceTree = ""; }; A4ED7D492097F113008685D6 /* kd_search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kd_search.h; sourceTree = ""; }; A4ED7D4A2097F113008685D6 /* kd_pr_search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kd_pr_search.h; sourceTree = ""; }; A4ED7D4B2097F113008685D6 /* kd_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kd_util.h; sourceTree = ""; }; - A4ED7D4C2097F113008685D6 /* kNN.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kNN.cpp; sourceTree = ""; }; A4ED7D4D2097F113008685D6 /* pr_queue_k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pr_queue_k.h; sourceTree = ""; }; A4ED7D4E2097F113008685D6 /* kd_pr_search.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kd_pr_search.cpp; sourceTree = ""; }; A4ED7D4F2097F113008685D6 /* pr_queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pr_queue.h; sourceTree = ""; }; @@ -886,6 +883,15 @@ path = visualization; sourceTree = ""; }; + A14735A721A5F6CE00CA69B2 /* Weights */ = { + isa = PBXGroup; + children = ( + A14735A821A5F72D00CA69B2 /* DistUtils.h */, + A14735A921A5F72D00CA69B2 /* DistUtils.cpp */, + ); + path = Weights; + sourceTree = ""; + }; A19483772118BA8B009A87A2 /* ogl */ = { isa = PBXGroup; children = ( @@ -1076,15 +1082,10 @@ A4ED7D482097F113008685D6 /* kd_tree.h */, A4ED7D512097F114008685D6 /* kd_util.cpp */, A4ED7D4B2097F113008685D6 /* kd_util.h */, - A4ED7D4C2097F113008685D6 /* kNN.cpp */, A4ED7D4D2097F113008685D6 /* pr_queue_k.h */, A4ED7D4F2097F113008685D6 /* pr_queue.h */, A4ED7D462097EDE9008685D6 /* kd_tree.cpp */, - A4ED7D452097ECC6008685D6 /* values.h */, A4ED7D412097EC54008685D6 /* ANN.cpp */, - A4ED7D432097EC55008685D6 /* ANN.h */, - A4ED7D422097EC54008685D6 /* ANNperf.h */, - A4ED7D402097EC54008685D6 /* ANNx.h */, ); path = kNN; sourceTree = ""; @@ -1101,6 +1102,7 @@ DD7974650F1D1B0700496A84 /* ../../ */ = { isa = PBXGroup; children = ( + A14735A721A5F6CE00CA69B2 /* Weights */, A10EF2ED21273E4900564FE1 /* visualization */, A19483772118BA8B009A87A2 /* ogl */, A40AB91A20F5336600F94543 /* arizona */, @@ -1860,6 +1862,7 @@ A10EF2F021273E7E00564FE1 /* AbstractCanvas.cpp in Sources */, A194839B2118BAAA009A87A2 /* basic2.cpp in Sources */, A1E77FDC17889BE200CC1037 /* OGRTable.cpp in Sources */, + A14735AA21A5F72D00CA69B2 /* DistUtils.cpp in Sources */, A4404A12209275550007753D /* hdbscan.cpp in Sources */, A1E78139178A90A100CC1037 /* OGRDatasourceProxy.cpp in Sources */, A4ED7D552097F114008685D6 /* kd_pr_search.cpp in Sources */, @@ -1869,7 +1872,6 @@ A1F1BA5C178D3B46005A46E5 /* GdaCache.cpp in Sources */, DD92D22417BAAF2300F8FE01 /* TimeEditorDlg.cpp in Sources */, A1DA623A17BCBC070070CAAB /* AutoCompTextCtrl.cpp in Sources */, - A4ED7D542097F114008685D6 /* kNN.cpp in Sources */, A1B93AC017D18735007F8195 /* ProjectConf.cpp in Sources */, A4B1F994207730FA00905246 /* matlab_mat.cpp in Sources */, A48356BB1E456310002791C8 /* ConditionalClusterMapView.cpp in Sources */, diff --git a/DataViewer/OGRTable.cpp b/DataViewer/OGRTable.cpp index 18af96403..f2472eb84 100644 --- a/DataViewer/OGRTable.cpp +++ b/DataViewer/OGRTable.cpp @@ -837,6 +837,33 @@ void OGRTable::GetColData(int col, int time, std::vector& da ogr_col->FillData(data); } +void OGRTable::GetDataByColumns(const std::vector& col_names, + std::vector >& data) +{ + // column names could be time (grouped) variable + int col_idx; + int tm_idx; + int dt_idx = 0; + wxString col_name; + wxString sub_col_name; + wxString time_id; + int n_col_names = col_names.size(); + for (int i=0; i= var_order.GetNumVarGroups()) diff --git a/DataViewer/OGRTable.h b/DataViewer/OGRTable.h index 62badc14c..c99b15241 100644 --- a/DataViewer/OGRTable.h +++ b/DataViewer/OGRTable.h @@ -145,6 +145,8 @@ class OGRTable : public TableInterface, TableStateObserver virtual void GetDirectColData(int col, std::vector& data); virtual void GetDirectColData(int col, std::vector& data); virtual bool GetDirectColUndefined(int col, std::vector& undefined); + virtual void GetDataByColumns(const std::vector& col_names, + std::vector >& data); virtual bool GetColUndefined(int col, b_array_type& undefined); virtual bool GetColUndefined(int col, int time, diff --git a/DataViewer/TableInterface.h b/DataViewer/TableInterface.h index 6f10d416d..c276fa70c 100644 --- a/DataViewer/TableInterface.h +++ b/DataViewer/TableInterface.h @@ -177,6 +177,9 @@ class TableInterface virtual void GetDirectColData(int col, std::vector& data)=0; virtual bool GetDirectColUndefined(int col, std::vector& undefs)=0; + virtual void GetDataByColumns(const std::vector& col_names, + std::vector >& data) = 0; + virtual void GetMinMaxVals(int col, std::vector& min_vals, std::vector& max_vals) = 0; virtual bool GetMinMaxVals(int col, int time, @@ -329,21 +332,19 @@ class TableInterface protected: - + wxString open_err_msg; + TableState* table_state; TimeState* time_state; + int rows; bool is_valid; - wxString open_err_msg; - int rows; bool changed_since_last_save; bool project_changed_since_last_save; - bool is_set_cell_from_string_fail; wxString set_cell_from_string_fail_msg; /** Table Attributes. Should reflect limitations of underlying database. */ - wxFontEncoding encoding_type; wxCSConv* m_wx_encoding; // can be NULL. Should match encoding_type diff --git a/DialogTools/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp index 4cd79e56a..b53eda09e 100644 --- a/DialogTools/CreatingWeightDlg.cpp +++ b/DialogTools/CreatingWeightDlg.cpp @@ -46,6 +46,7 @@ #include "../GenUtils.h" #include "../SpatialIndAlgs.h" #include "../PointSetAlgs.h" +#include "../Weights/DistUtils.h" #include "AddIdVariable.h" #include "CreatingWeightDlg.h" @@ -70,6 +71,7 @@ EVT_CHECKBOX( XRCID("IDC_CHK_INVERSE_DISTANCE"), CreatingWeightDlg::OnInverseDis EVT_CHECKBOX( XRCID("IDC_CHK_INVERSE_DISTANCE_KNN"), CreatingWeightDlg::OnInverseKNNCheck) EVT_SPIN( XRCID("IDC_SPIN_POWER"), CreatingWeightDlg::OnCSpinPowerInverseDistUpdated ) EVT_SPIN( XRCID("IDC_SPIN_POWER_KNN"), CreatingWeightDlg::OnCSpinPowerInverseKNNUpdated ) +EVT_NOTEBOOK_PAGE_CHANGED( XRCID("IDC_WEIGHTS_DIST_VARS_LIST"), CreatingWeightDlg::OnDistanceWeightsInputUpdate ) END_EVENT_TABLE() @@ -178,6 +180,8 @@ void CreatingWeightDlg::CreateControls() m_X_time = XRCCTRL(*this, "IDC_XCOORD_TIME", wxChoice); m_Y = XRCCTRL(*this, "IDC_YCOORDINATES", wxChoice); m_Y_time = XRCCTRL(*this, "IDC_YCOORD_TIME", wxChoice); + m_Vars = XRCCTRL(*this, "IDC_WEIGHTS_DIST_VARS_LIST", wxListBox); + m_nb_distance_variables = XRCCTRL(*this, "IDC_NB_DISTANCE_VARIABLES", wxNotebook); m_nb_distance_methods = XRCCTRL(*this, "IDC_NB_DISTANCE_WEIGHTS", wxNotebook); m_threshold = XRCCTRL(*this, "IDC_THRESHOLD_EDIT", wxTextCtrl); m_sliderdistance = XRCCTRL(*this, "IDC_THRESHOLD_SLIDER", wxSlider); @@ -209,9 +213,63 @@ void CreatingWeightDlg::CreateControls() m_power->Enable(false); m_power_knn->Enable(false); + m_nb_distance_variables->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, &CreatingWeightDlg::OnDistanceWeightsInputUpdate, this); + m_Vars->Bind(wxEVT_LISTBOX, &CreatingWeightDlg::OnDistanceWeightsVarsSel, this); + InitDlg(); } +void CreatingWeightDlg::OnDistanceWeightsVarsSel( wxCommandEvent& event ) +{ + // update Threshold values for distance weight + wxArrayInt selections; + m_Vars->GetSelections(selections); + int num_var = selections.size(); + if (num_var <= 0) { + return; + } + std::vector col_names; + std::vector > data; + for (int i=0; iGetString(idx); + col_names.push_back(sel_str); + } + data.resize(num_var); + table_int->GetDataByColumns(col_names, data); + // UpdateThresholdValues(); + GeoDa::DistUtils dist_util(data); + m_thres_min = dist_util.GetMinThreshold(); + m_thres_max = dist_util.GetMaxThreshold(); + + m_thres_val_valid = true; + m_threshold_val = (m_sliderdistance->GetValue() * (m_thres_max-m_thres_min)/100.0) + m_thres_min; + m_threshold->ChangeValue( wxString::Format("%f", m_threshold_val)); + + m_bandwidth_thres_val_valid = true; + m_bandwidth_thres_val = (m_bandwidth_slider->GetValue() * (m_thres_max-m_thres_min)/100.0) + m_thres_min; + m_manu_bandwidth->ChangeValue( wxString::Format("%f", m_bandwidth_thres_val) ); + // UpdateCreateButtonState +} + +void CreatingWeightDlg::OnDistanceWeightsInputUpdate( wxBookCtrlEvent& event ) +{ + int sel = event.GetSelection(); + if (sel == 0) { + UpdateThresholdValues(); + } else { + wxArrayInt selections; + m_Vars->GetSelections(selections); + int n_sel = selections.GetCount(); + if (n_sel <= 0) { + m_thres_val_valid = false; + m_threshold->ChangeValue("0"); + m_bandwidth_thres_val_valid = false; + m_manu_bandwidth->ChangeValue("0"); + } + } +} + void CreatingWeightDlg::OnCreateNewIdClick( wxCommandEvent& event ) { wxLogMessage("Click CreatingWeightDlg::OnCreateNewIdClick"); @@ -571,14 +629,27 @@ void CreatingWeightDlg::InitFields() m_id_field->Clear(); m_X_time->Clear(); m_Y_time->Clear(); + m_Vars->Clear(); + ResetThresXandYCombo(); for (int i=0, iend=col_id_map.size(); iAppend(table_int->GetColName(col)); - m_Y->Append(table_int->GetColName(col)); + wxString name = table_int->GetColName(col); + m_X->Append(name); + m_Y->Append(name); + if (table_int->IsColTimeVariant(col)) { + for (int t=0; tGetColTimeSteps(col); t++) { + wxString nm = name; + nm << " (" << table_int->GetTimeString(t) << ")"; + m_Vars->Append(nm); + } + } else { + m_Vars->Append(name); + } + if (table_int->GetColType(col) == GdaConst::long64_type || table_int->GetColType(col) == GdaConst::string_type) { if (!table_int->IsColTimeVariant(col)) { diff --git a/DialogTools/CreatingWeightDlg.h b/DialogTools/CreatingWeightDlg.h index e7efa9d45..3843ab75a 100644 --- a/DialogTools/CreatingWeightDlg.h +++ b/DialogTools/CreatingWeightDlg.h @@ -90,7 +90,8 @@ public TableStateObserver, public WeightsManStateObserver void OnCThresholdSliderUpdated( wxCommandEvent& event ); void OnCSpinPowerInverseDistUpdated( wxSpinEvent& event ); void OnCSpinPowerInverseKNNUpdated( wxSpinEvent& event ); - + void OnDistanceWeightsInputUpdate( wxBookCtrlEvent& event ); + void OnDistanceWeightsVarsSel( wxCommandEvent& event ); /** Implementation of FramesManagerObserver interface */ virtual void update(FramesManager* o); @@ -129,7 +130,9 @@ public TableStateObserver, public WeightsManStateObserver wxChoice* m_X_time; wxChoice* m_Y; wxChoice* m_Y_time; - wxNotebook* m_nb_distance_methods; + wxListBox* m_Vars; + wxNotebook* m_nb_distance_variables; + wxNotebook* m_nb_distance_methods; wxTextCtrl* m_threshold; wxSlider* m_sliderdistance; wxCheckBox* m_use_inverse; diff --git a/Weights/DistUtils.cpp b/Weights/DistUtils.cpp new file mode 100644 index 000000000..d34888d6a --- /dev/null +++ b/Weights/DistUtils.cpp @@ -0,0 +1,109 @@ +// +// DistUtils.c +// GeoDa +// +// Created by Xun Li on 11/21/18. +// + +#include +#include +#include "DistUtils.h" + +using namespace GeoDa; + +DistUtils::DistUtils(const std::vector >& input_data) +{ + eps = 0.0; + + n_cols = input_data.size(); + if (n_cols > 0) { + n_rows = input_data[0].size(); + } + data = new double*[n_rows]; + for (size_t i=0; iannkSearch(data[i], k, nnIdx, dists); + if (dists[1] > max_1nn_dist) { + max_1nn_dist = dists[1]; + } + } + delete[] nnIdx; + delete[] dists; + + return sqrt(max_1nn_dist); +} + +/* + The classic 2-approximation algorithm for this problem, with running time O(nd), is to choose an arbitrary point and then return the maximum distance to another point. The diameter is no smaller than this value and no larger than twice this value. + An optional extension: Pick random point x. Pick point y furthest from x. Pick point z furthest from y. + More: http://www-sop.inria.fr/members/Gregoire.Malandain/diameter/ + */ +double DistUtils::GetMaxThreshold() +{ + srand(0); + int k = n_rows; + int x_idx; + int y_idx; + double dist_cand = 0; + + int n_iter = 10; + + ANNidxArray nnIdx = new ANNidx[k]; + ANNdistArray dists = new ANNdist[k]; + for (size_t i=0; iannkSearch(data[i], k, nnIdx, dists); + y_idx = nnIdx[k-1]; + kdTree->annkSearch(data[y_idx], k, nnIdx, dists); + if (dists[k-1] > dist_cand) { + dist_cand = dists[k-1]; + } + } + delete[] nnIdx; + delete[] dists; + + return sqrt(dist_cand); +} + +void DistUtils::CreateDistBandWeights(double band, bool is_inverse, int power) +{ + double radius = ANN_POW(band); + for (size_t i=0; iannkFRSearch(data[i], radius, 0, NULL, NULL); + ANNidxArray nnIdx = new ANNidx[k]; + ANNdistArray dists = new ANNdist[k]; + kdTree->annkFRSearch(data[i], radius, k, nnIdx, dists); + for (size_t j=0; j +#include + +#include "../kNN/ANN/ANN.h" + +namespace GeoDa { + + class DistUtils + { + protected: + ANNkd_tree* kdTree; + double** data; + double eps; + unsigned long n_cols; + unsigned long n_rows; + + public: + DistUtils(const std::vector >& input_data); + ~DistUtils(); + + // The minimum threshold distance guarantees that every observation has + // at least one neighbor if creating a weights + double GetMinThreshold(); + + // The maximu, threshold distance should be the diameter of the space + // represents by all data points + double GetMaxThreshold(); + + void CreateDistBandWeights(double band, bool is_inverse, int power); + }; +} +#endif /* DistUtils_h */ diff --git a/kNN/ANN.cpp b/kNN/ANN.cpp old mode 100644 new mode 100755 index 090482ec0..b9b8d4a1d --- a/kNN/ANN.cpp +++ b/kNN/ANN.cpp @@ -1,190 +1,201 @@ //---------------------------------------------------------------------- -// File: ANN.cc -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Methods for ANN.h and ANNx.h +// File: ANN.cpp +// Programmer: Sunil Arya and David Mount +// Description: Methods for ANN.h and ANNx.h +// Last modified: 01/27/10 (Version 1.1.2) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2010 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 +// Added performance counting to annDist() +// Revision 1.1.2 01/27/10 +// Fixed minor compilation bugs for new versions of gcc //---------------------------------------------------------------------- -#include "ANN.h" // ANN includes -#include "ANNx.h" // all ANN includes +#include // C standard lib defs +#include "ANN/ANNx.h" // all ANN includes +#include "ANN/ANNperf.h" // ANN performance + +using namespace std; // make std:: accessible //---------------------------------------------------------------------- -// Point methods +// Point methods //---------------------------------------------------------------------- //---------------------------------------------------------------------- -// Distance utility. -// (Note: In the nearest neighbor search, most distances are -// computed using partial distance calculations, not this -// procedure.) +// Distance utility. +// (Note: In the nearest neighbor search, most distances are +// computed using partial distance calculations, not this +// procedure.) //---------------------------------------------------------------------- -ANNdist annDist( // interpoint squared distance - int dim, - ANNpoint p, - ANNpoint q) +ANNdist annDist( // interpoint squared distance + int dim, + ANNpoint p, + ANNpoint q) { - register int d; - register ANNcoord diff; - register ANNcoord dist; - - dist = 0; - for (d = 0; d < dim; d++) { - diff = p[d] - q[d]; - dist = ANN_SUM(dist, ANN_POW(diff)); - } - return dist; + register int d; + register ANNcoord diff; + register ANNcoord dist; + + dist = 0; + for (d = 0; d < dim; d++) { + diff = p[d] - q[d]; + dist = ANN_SUM(dist, ANN_POW(diff)); + } + ANN_FLOP(3*dim) // performance counts + ANN_PTS(1) + ANN_COORD(dim) + return dist; } //---------------------------------------------------------------------- -// annPrintPoint() prints a point to a given output stream. +// annPrintPoint() prints a point to a given output stream. //---------------------------------------------------------------------- -void annPrintPt( // print a point - ANNpoint pt, // the point - int dim, // the dimension - ostream &out) // output stream +void annPrintPt( // print a point + ANNpoint pt, // the point + int dim, // the dimension + std::ostream &out) // output stream { - for (int j = 0; j < dim; j++) { - out << pt[j]; - if (j < dim-1) out << " "; - } + for (int j = 0; j < dim; j++) { + out << pt[j]; + if (j < dim-1) out << " "; + } } //---------------------------------------------------------------------- -// Point allocation/deallocation: +// Point allocation/deallocation: // -// Because points (somewhat like strings in C) are stored -// as pointers. Consequently, creating and destroying -// copies of points may require storage allocation. These -// procedures do this. +// Because points (somewhat like strings in C) are stored +// as pointers. Consequently, creating and destroying +// copies of points may require storage allocation. These +// procedures do this. // -// annAllocPt() and annDeallocPt() allocate a deallocate -// storage for a single point, and return a pointer to it. +// annAllocPt() and annDeallocPt() allocate a deallocate +// storage for a single point, and return a pointer to it. // -// annAllocPts() allocates an array of points as well a place -// to store their coordinates, and initializes the points to -// point to their respective coordinates. It allocates point -// storage in a contiguous block large enough to store all the -// points. It performs no initialization. +// annAllocPts() allocates an array of points as well a place +// to store their coordinates, and initializes the points to +// point to their respective coordinates. It allocates point +// storage in a contiguous block large enough to store all the +// points. It performs no initialization. // -// annDeallocPts() should only be used on point arrays allocated -// by annAllocPts since it assumes that points are allocated in -// a block. +// annDeallocPts() should only be used on point arrays allocated +// by annAllocPts since it assumes that points are allocated in +// a block. // -// annCopyPt() copies a point taking care to allocate storage -// for the new point. +// annCopyPt() copies a point taking care to allocate storage +// for the new point. // -// annAssignRect() assigns the coordinates of one rectangle to -// another. The two rectangles must have the same dimension -// (and it is not possible to test this here). +// annAssignRect() assigns the coordinates of one rectangle to +// another. The two rectangles must have the same dimension +// (and it is not possible to test this here). //---------------------------------------------------------------------- -ANNpoint annAllocPt(int dim, ANNcoord c) // allocate 1 point +ANNpoint annAllocPt(int dim, ANNcoord c) // allocate 1 point { - ANNpoint p = new ANNcoord[dim]; - for (int i = 0; i < dim; i++) p[i] = c; - return p; + ANNpoint p = new ANNcoord[dim]; + for (int i = 0; i < dim; i++) p[i] = c; + return p; } -ANNpointArray annAllocPts(int n, int dim) // allocate n pts in dim +ANNpointArray annAllocPts(int n, int dim) // allocate n pts in dim { - ANNpointArray pa = new ANNpoint[n]; // allocate points - ANNpoint p = new ANNcoord[n*dim]; // allocate space for coords - for (int i = 0; i < n; i++) { - pa[i] = &(p[i*dim]); - } - return pa; + ANNpointArray pa = new ANNpoint[n]; // allocate points + ANNpoint p = new ANNcoord[n*dim]; // allocate space for coords + for (int i = 0; i < n; i++) { + pa[i] = &(p[i*dim]); + } + return pa; } -void annDeallocPt(ANNpoint &p) // deallocate 1 point +void annDeallocPt(ANNpoint &p) // deallocate 1 point { - delete [] p; - p = NULL; + delete [] p; + p = NULL; } -void annDeallocPts(ANNpointArray &pa) // deallocate points +void annDeallocPts(ANNpointArray &pa) // deallocate points { - delete [] pa[0]; // dealloc coordinate storage - delete [] pa; // dealloc points - pa = NULL; + delete [] pa[0]; // dealloc coordinate storage + delete [] pa; // dealloc points + pa = NULL; } ANNpoint annCopyPt(int dim, ANNpoint source) // copy point { - ANNpoint p = new ANNcoord[dim]; - for (int i = 0; i < dim; i++) p[i] = source[i]; - return p; + ANNpoint p = new ANNcoord[dim]; + for (int i = 0; i < dim; i++) p[i] = source[i]; + return p; } - // assign one rect to another + // assign one rect to another void annAssignRect(int dim, ANNorthRect &dest, const ANNorthRect &source) { - for (int i = 0; i < dim; i++) { - dest.lo[i] = source.lo[i]; - dest.hi[i] = source.hi[i]; - } + for (int i = 0; i < dim; i++) { + dest.lo[i] = source.lo[i]; + dest.hi[i] = source.hi[i]; + } } - // is point inside rectangle? + // is point inside rectangle? ANNbool ANNorthRect::inside(int dim, ANNpoint p) { - for (int i = 0; i < dim; i++) { - if (p[i] < lo[i] || p[i] > hi[i]) return ANNfalse; - } - return ANNtrue; + for (int i = 0; i < dim; i++) { + if (p[i] < lo[i] || p[i] > hi[i]) return ANNfalse; + } + return ANNtrue; } //---------------------------------------------------------------------- -// Error handler +// Error handler //---------------------------------------------------------------------- -void annError(char *msg, ANNerr level) +void annError(const char* msg, ANNerr level) { - if (level == ANNabort) { - cerr << "ANN: ERROR------->" << msg << "<-------------ERROR\n"; - exit(1); - } - else { - cerr << "ANN: WARNING----->" << msg << "<-------------WARNING\n"; - } + if (level == ANNabort) { + cerr << "ANN: ERROR------->" << msg << "<-------------ERROR\n"; + exit(1); + } + else { + cerr << "ANN: WARNING----->" << msg << "<-------------WARNING\n"; + } } //---------------------------------------------------------------------- -// Limit on number of points visited -// We have an option for terminating the search early if the -// number of points visited exceeds some threshold. If the -// threshold is 0 (its default) this means there is no limit -// and the algorithm applies its normal termination condition. -// This is for applications where there are real time constraints -// on the running time of the algorithm. +// Limit on number of points visited +// We have an option for terminating the search early if the +// number of points visited exceeds some threshold. If the +// threshold is 0 (its default) this means there is no limit +// and the algorithm applies its normal termination condition. +// This is for applications where there are real time constraints +// on the running time of the algorithm. //---------------------------------------------------------------------- -int ANNmaxPtsVisited = 0; // maximum number of pts visited -int ANNptsVisited; // number of pts visited in search +int ANNmaxPtsVisited = 0; // maximum number of pts visited +int ANNptsVisited; // number of pts visited in search //---------------------------------------------------------------------- -// Global function declarations +// Global function declarations //---------------------------------------------------------------------- -void annMaxPtsVisit( // set limit on max. pts to visit in search - int maxPts) // the limit +void annMaxPtsVisit( // set limit on max. pts to visit in search + int maxPts) // the limit { - ANNmaxPtsVisited = maxPts; + ANNmaxPtsVisited = maxPts; } diff --git a/kNN/ANN.h b/kNN/ANN.h deleted file mode 100644 index 0d240ac92..000000000 --- a/kNN/ANN.h +++ /dev/null @@ -1,507 +0,0 @@ -//---------------------------------------------------------------------- -// File: ANN.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Basic include file for approximate nearest -// neighbor searching. -//---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. -// -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). -// -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// ANN - approximate nearest neighbor searching -// ANN is a library for approximate nearest neighbor searching, -// based on the use of standard and priority search in kd-trees -// and balanced box-decomposition (bbd) trees. Here are some -// references: -// -// kd-trees: -// Friedman, Bentley, and Finkel, ``An algorithm for finding -// best matches in logarithmic expected time,'' ACM -// Transactions on Mathematical Software, 3(3):209-226, 1977. -// -// priority search in kd-trees: -// Arya and Mount, ``Algorithms for fast vector quantization,'' -// Proc. of DCC '93: Data Compression Conference, eds. J. A. -// Storer and M. Cohn, IEEE Press, 1993, 381-390. -// -// approximate nearest neighbor search and bbd trees: -// Arya, Mount, Netanyahu, Silverman, and Wu, ``An optimal -// algorithm for approximate nearest neighbor searching,'' -// 5th Ann. ACM-SIAM Symposium on Discrete Algorithms, -// 1994, 573-582. -//---------------------------------------------------------------------- - -#ifndef ANN_H -#define ANN_H - -//---------------------------------------------------------------------- -// basic includes -//---------------------------------------------------------------------- -#include "values.h" // special values -#include // standard libs -#include // standard I/O (for NULL) -#include // I/O streams -#include // math includes -using namespace std; - -#define ANNversion "0.1" // ANN version number - -//---------------------------------------------------------------------- -// ANNbool -// This is a simple boolean type. Although ANSI C++ is supposed -// to support the type bool, many compilers do not have it. -//---------------------------------------------------------------------- - - // ANN boolean type (non ANSI C++) -enum ANNbool {ANNfalse = 0, ANNtrue = 1}; - -//---------------------------------------------------------------------- -// Basic Types: ANNcoord, ANNdist, ANNidx -// ANNcoord and ANNdist are the types used for representing -// point coordinates and distances. They can be modified by the -// user, with some care. It is assumed that they are both numeric -// types, and that ANNdist is generally of an equal or higher type -// from ANNcoord. A variable of type ANNdist should be large -// enough to store the sum of squared components of a variable -// of type ANNcoord for the number of dimensions needed in the -// application. For example, the following combinations are -// legal: -// -// ANNcoord ANNdist -// --------- ------------------------------- -// short short, int, long, float, double -// int int, long, float, double -// long long, float, double -// float float, double -// double double -// -// It is the user's responsibility to make sure that overflow does -// not occur in distance calculation. -// -// The code assumes that there is an infinite distance, ANN_DIST_INF -// (as large as any legal distance). Possible values are given below: -// -// Examples: -// ANNdist: double, float, long, int, short -// ANN_DIST_INF: MAXDOUBLE, MAXFLOAT, MAXLONG, MAXINT, MAXSHORT -// -// -// ANNidx is a point index. When the data structure is built, -// the points are given as an array. Nearest neighbor results are -// returned as an index into this array. To make it clearer when -// this is happening, we define the integer type ANNidx. -// -//---------------------------------------------------------------------- - -typedef double ANNcoord; // coordinate data type -typedef double ANNdist; // distance data type -typedef int ANNidx; // point index - - // largest possible distance -const ANNdist ANN_DIST_INF = MAXDOUBLE; - -//---------------------------------------------------------------------- -// Self match? -// In some applications, the nearest neighbor of a point is not -// allowed to be the point itself. This occurs, for example, when -// computing all nearest neighbors in a set. By setting the -// parameter ANN_ALLOW_SELF_MATCH to ANNfalse, the nearest neighbor -// is the closest point whose distance from the query point is -// strictly positive. -//---------------------------------------------------------------------- - -const ANNbool ANN_ALLOW_SELF_MATCH = ANNtrue; - -//---------------------------------------------------------------------- -// Norms and metrics: -// ANN supports any Minkowski norm for defining distance. In -// particular, for any p >= 1, the L_p Minkowski norm defines the -// length of a d-vector (v0, v1, ..., v(d-1)) to be -// -// (|v0|^p + |v1|^p + ... + |v(d-1)|^p)^(1/p), -// -// (where ^ denotes exponentiation, and |.| denotes absolute -// value). The distance between two points is defined to be -// the norm of the vector joining them. Some common distance -// metrics include -// -// Euclidean metric p = 2 -// Manhattan metric p = 1 -// Max metric p = infinity -// -// In the case of the max metric, the norm is computed by -// taking the maxima of the absolute values of the components. -// ANN is highly "coordinate-based" and does not support general -// distances functions (e.g. those obeying just the triangle -// inequality). It also does not support distance functions -// based on inner-products. -// -// For the purpose of computing nearest neighbors, it is not -// necessary to compute the final power (1/p). Thus the only -// component that is used by the program is |v(i)|^p. -// -// ANN parameterizes the distance computation through the following -// macros. (Macros are used rather than procedures for efficiency.) -// Recall that the distance between two points is given by the length -// of the vector joining them, and the length or norm of a vector v -// is given by formula: -// -// |v| = ROOT(POW(v0) # POW(v1) # ... # POW(v(d-1))) -// -// where ROOT, POW are unary functions and # is an associative and -// commutative binary operator satisfying: -// -// ** POW: coord --> dist -// ** #: dist x dist --> dist -// ** ROOT: dist (>0) --> double -// -// For early termination in distance calculation (partial distance -// calculation) we assume that POW and # together are monotonically -// increasing on sequences of arguments, meaning that for all -// v0..vk and y: -// -// POW(v0) #...# POW(vk) <= (POW(v0) #...# POW(vk)) # POW(y). -// -// Due to the use of incremental distance calculations in the code -// for searching k-d trees, we assume that there is an incremental -// update function DIFF(x,y) for #, such that if: -// -// s = x0 # ... # xi # ... # xk -// -// then if s' is s with xi replaced by y, that is, -// -// s' = x0 # ... # y # ... # xk -// -// can be computed by: -// -// s' = s # DIFF(xi,y). -// -// Thus, if # is + then DIFF(xi,y) is (yi-x). For the L_infinity -// norm we make use of the fact that in the program this function -// is only invoked when y > xi, and hence DIFF(xi,y)=y. -// -// Finally, for approximate nearest neighbor queries we assume -// that POW and ROOT are related such that -// -// v*ROOT(x) = ROOT(POW(v)*x) -// -// Here are the values for the various Minkowski norms: -// -// L_p: p even: p odd: -// ------------------------- ------------------------ -// POW(v) = v^p POW(v) = |v|^p -// ROOT(x) = x^(1/p) ROOT(x) = x^(1/p) -// # = + # = + -// DIFF(x,y) = y - x DIFF(x,y) = y - x -// -// L_inf: -// POW(v) = |v| -// ROOT(x) = x -// # = max -// DIFF(x,y) = y -// -// By default the Euclidean norm is assumed. To change the norm, -// uncomment the appropriate set of macros below. -// -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// Use the following for the Euclidean norm -//---------------------------------------------------------------------- -#define ANN_POW(v) ((v)*(v)) -#define ANN_ROOT(x) sqrt(x) -#define ANN_SUM(x,y) ((x) + (y)) -#define ANN_DIFF(x,y) ((y) - (x)) - -//---------------------------------------------------------------------- -// Use the following for the L_1 (Manhattan) norm -//---------------------------------------------------------------------- -// #define ANN_POW(v) fabs(v) -// #define ANN_ROOT(x) (x) -// #define ANN_SUM(x,y) ((x) + (y)) -// #define ANN_DIFF(x,y) ((y) - (x)) - -//---------------------------------------------------------------------- -// Use the following for a general L_p norm -//---------------------------------------------------------------------- -// #define ANN_POW(v) pow(fabs(v),p) -// #define ANN_ROOT(x) pow(fabs(x),1/p) -// #define ANN_SUM(x,y) ((x) + (y)) -// #define ANN_DIFF(x,y) ((y) - (x)) - -//---------------------------------------------------------------------- -// Use the following for the L_infinity (Max) norm -//---------------------------------------------------------------------- -// #define ANN_POW(v) fabs(v) -// #define ANN_ROOT(x) (x) -// #define ANN_SUM(x,y) ((x) > (y) ? (x) : (y)) -// #define ANN_DIFF(x,y) (y) - -//---------------------------------------------------------------------- -// Array types -// -// ANNpoint: -// A point is represented as a (dimensionless) vector of -// coordinates, that is, as a pointer to ANNcoord. It is the -// user's responsibility to be sure that each such vector has -// been allocated with enough components. Because only -// pointers are stored, the values should not be altered -// through the lifetime of the nearest neighbor data structure. -// ANNpointArray is a dimensionless array of ANNpoint. -// ANNdistArray is a dimensionless array of ANNdist. -// ANNidxArray is a dimensionless array of ANNidx. This is used for -// storing buckets of points in the search trees, and for returning -// the results of k nearest neighbor queries. -//---------------------------------------------------------------------- - -typedef ANNcoord *ANNpoint; // a point -typedef ANNpoint *ANNpointArray; // an array of points -typedef ANNdist *ANNdistArray; // an array of distances -typedef ANNidx *ANNidxArray; // an array of point indices - -//---------------------------------------------------------------------- -// Point operations: -// -// annDist() computes the (squared) distance between a pair -// of points. Distance calculations for queries are NOT -// performed using this routine (for reasons of efficiency). -// -// Because points (somewhat like strings in C) are stored -// as pointers. Consequently, creating and destroying -// copies of points may require storage allocation. These -// procedures do this. -// -// annAllocPt() and annDeallocPt() allocate a deallocate -// storage for a single point, and return a pointer to it. -// The argument to AllocPt() is used to initialize all -// components. -// -// annAllocPts() allocates an array of points as well a place -// to store their coordinates, and initializes the points to -// point to their respective coordinates. It allocates point -// storage in a contiguous block large enough to store all the -// points. It performs no initialization. -// -// annDeallocPt() deallocates a point allocated by annAllocPt(). -// annDeallocPts() deallocates points allocated by annAllocPts(). -// -// annCopyPt() allocates space and makes a copy of a given point. -//---------------------------------------------------------------------- - -ANNdist annDist( - int dim, // dimension of space - ANNpoint p, // points - ANNpoint q); - -ANNpoint annAllocPt( - int dim, // dimension - ANNcoord c = 0); // coordinate value (all equal) - -ANNpointArray annAllocPts( - int n, // number of points - int dim); // dimension - -void annDeallocPt( - ANNpoint &p); // deallocate 1 point - -void annDeallocPts( - ANNpointArray &pa); // point array - -ANNpoint annCopyPt( // copy point - int dim, // dimension - ANNpoint source); // point to copy - -//---------------------------------------------------------------------- -// Generic approximate nearest neighbor search structure. -// ANN supports a few different data structures for -// approximate nearest neighbor searching. All these -// data structures at a minimum support single and k-nearest -// neighbor queries described here. The nearest neighbor -// query returns an integer identifier and the distance -// to the nearest neighbor(s). -//---------------------------------------------------------------------- -class ANNpointSet { -public: - virtual ~ANNpointSet() {} // virtual distroyer - - virtual void annkSearch( // approx k near neighbor search - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor array (returned) - ANNdistArray dd, // dist to near neighbors (returned) - double eps=0.0, // error bound - int method = 1 // method of distance computation, 1: Eucl - // 2: Arc Distance - ) = 0; // pure virtual (defined elsewhere) -}; - -//---------------------------------------------------------------------- -// kd-tree: -// The basic search data structure supported by ann is a kd-tree. -// The tree basically consists of a root pointer. We also store -// the dimension of the space (since it is needed for many routines -// that access the structure). The number of data points and the -// bucket size are stored, but they are mostly information items, -// and do not affect the data structure's function. We also store -// the bounding box for the point set. -// -// kd-trees support two searching algorithms, standard search -// (which searches nodes in tree traversal order) and priority -// search (which searches nodes in order of increasing distance -// from the query point). For many distributions the standard -// search seems to work just fine, but priority search is safer -// for worst-case performance. -// -// The nearest neighbor index returned is the index in the -// array pa[] which is passed to the constructor. -// -// There are two methods provided for printing the tree. Print() -// is used to produce a "human-readable" display of the tree, with -// indenation, which is handy for debugging. Dump() produces a -// format that is suitable reading by a program. Finally the -// method getStats() collects statistics information on the tree -// (its size, height, etc.) See ANNperf.h for information on the -// stats structure it returns. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// Some types and objects used by kd-tree functions -// See kd_tree.h and kd_tree.cc for definitions -//---------------------------------------------------------------------- -class ANNkd_node; // generic node in a kd-tree -typedef ANNkd_node *ANNkd_ptr; // pointer to a kd-tree node - -//---------------------------------------------------------------------- -// kd-tree splitting rules -// kd-trees supports a collection of different splitting rules. -// In addition to the standard kd-tree splitting rule proposed -// by Friedman, Bentley, and Finkel, we have introduced a -// number of other splitting rules, which seem to perform -// as well or better (for the distributions we have tested). -// -// The splitting methods given below allow the user to tailor -// the data structure to the particular data set. They are -// are described in greater details in the kd_split.cc source -// file. The method ANN_KD_SUGGEST is the method chosen (rather -// subjectively) by the implementors as the one giving the -// fastest performance, and is the default splitting method. -//---------------------------------------------------------------------- - -enum ANNsplitRule { - ANN_KD_STD, // the optimized kd-splitting rule - ANN_KD_MIDPT, // midpoint split - ANN_KD_FAIR, // fair split - ANN_KD_SL_MIDPT, // sliding midpoint splitting method - ANN_KD_SL_FAIR, // sliding fair split method - ANN_KD_SUGGEST}; // the authors' suggestion for best - -class ANNkd_tree: public ANNpointSet -{ -protected: - int dim; // dimension of space - int n_pts; // number of points in tree - int bkt_size; // bucket size - ANNpointArray pts; // the points - ANNidxArray pidx; // point indices (to pts) - ANNkd_ptr root; // root of kd-tree - ANNpoint bnd_box_lo; // bounding box low point - ANNpoint bnd_box_hi; // bounding box high point - - void SkeletonTree( // construct skeleton tree - int n, // number of points - int dd, // dimension - int bs); // bucket size - -public: - ANNkd_tree( // build skeleton tree - int n, // number of points - int dd, // dimension - int bs = 1); // bucket size - - ANNkd_tree( // build from point array - ANNpointArray pa, // point array - int n, // number of points - int dd, // dimension - int bs = 1, // bucket size - ANNsplitRule split = ANN_KD_SUGGEST); // splitting method - - ~ANNkd_tree(); // tree destructor - - virtual void annkSearch( // approx k near neighbor search - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor array (returned) - ANNdistArray dd, // dist to near neighbors (returned) - double eps=0.0, // error bound - int method = 1); // method of dist computation - - virtual void annkPriSearch( // priority k near neighbor search - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor array (returned) - ANNdistArray dd, // dist to near neighbors (returned) - double eps=0.0); // error bound - -}; - -//---------------------------------------------------------------------- -// Box decomposition tree (bd-tree) -// The bd-tree is inherited from a kd-tree. The main difference -// in the bd-tree and the kd-tree is a new type of internal node -// called a shrinking node (in the kd-tree there is only one type -// of internal node, a splitting node). The shrinking node -// makes it possible to generate balanced trees in which the -// cells have bounded aspect ratio. -// -// As with splitting rules, there are a number of different -// shrinking rules. The shrinking rule ANN_BD_NONE does no -// shrinking (and hence produces a kd-tree tree). The rule -// ANN_BD_SUGGEST uses the implementors favorite rule. -//---------------------------------------------------------------------- - -enum ANNshrinkRule { - ANN_BD_NONE, // no shrinking at all (just kd-tree) - ANN_BD_SIMPLE, // simple splitting - ANN_BD_CENTROID, // centroid splitting - ANN_BD_SUGGEST}; // the authors' suggested choice - -class ANNbd_tree: public ANNkd_tree { -public: - ANNbd_tree( // build skeleton tree - int n, // number of points - int dd, // dimension - int bs = 1) // bucket size - : ANNkd_tree(n, dd, bs) {} // build base kd-tree - - ANNbd_tree( // build from point array - ANNpointArray pa, // point array - int n, // number of points - int dd, // dimension - int bs = 1, // bucket size - ANNsplitRule split = ANN_KD_SUGGEST, // splitting rule - ANNshrinkRule shrink = ANN_BD_SUGGEST); // shrinking rule -}; - -//---------------------------------------------------------------------- -// Other functions -//---------------------------------------------------------------------- - -void annMaxPtsVisit( // limit max. pts to visit in search - int maxPts); // the limit - -#endif diff --git a/kNN/ANN/ANN.h b/kNN/ANN/ANN.h new file mode 100755 index 000000000..3f70ec633 --- /dev/null +++ b/kNN/ANN/ANN.h @@ -0,0 +1,830 @@ +//---------------------------------------------------------------------- +// File: ANN.h +// Programmer: Sunil Arya and David Mount +// Description: Basic include file for approximate nearest +// neighbor searching. +// Last modified: 01/27/10 (Version 1.1.2) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2010 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 +// Added copyright and revision information +// Added ANNcoordPrec for coordinate precision. +// Added methods theDim, nPoints, maxPoints, thePoints to ANNpointSet. +// Cleaned up C++ structure for modern compilers +// Revision 1.1 05/03/05 +// Added fixed-radius k-NN searching +// Revision 1.1.2 01/27/10 +// Fixed minor compilation bugs for new versions of gcc +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// ANN - approximate nearest neighbor searching +// ANN is a library for approximate nearest neighbor searching, +// based on the use of standard and priority search in kd-trees +// and balanced box-decomposition (bbd) trees. Here are some +// references to the main algorithmic techniques used here: +// +// kd-trees: +// Friedman, Bentley, and Finkel, ``An algorithm for finding +// best matches in logarithmic expected time,'' ACM +// Transactions on Mathematical Software, 3(3):209-226, 1977. +// +// Priority search in kd-trees: +// Arya and Mount, ``Algorithms for fast vector quantization,'' +// Proc. of DCC '93: Data Compression Conference, eds. J. A. +// Storer and M. Cohn, IEEE Press, 1993, 381-390. +// +// Approximate nearest neighbor search and bbd-trees: +// Arya, Mount, Netanyahu, Silverman, and Wu, ``An optimal +// algorithm for approximate nearest neighbor searching,'' +// 5th Ann. ACM-SIAM Symposium on Discrete Algorithms, +// 1994, 573-582. +//---------------------------------------------------------------------- + +#ifndef ANN_H +#define ANN_H + +#ifdef WIN32 + //---------------------------------------------------------------------- + // For Microsoft Visual C++, externally accessible symbols must be + // explicitly indicated with DLL_API, which is somewhat like "extern." + // + // The following ifdef block is the standard way of creating macros + // which make exporting from a DLL simpler. All files within this DLL + // are compiled with the DLL_EXPORTS preprocessor symbol defined on the + // command line. In contrast, projects that use (or import) the DLL + // objects do not define the DLL_EXPORTS symbol. This way any other + // project whose source files include this file see DLL_API functions as + // being imported from a DLL, wheras this DLL sees symbols defined with + // this macro as being exported. + //---------------------------------------------------------------------- + #ifdef DLL_EXPORTS + #define DLL_API __declspec(dllexport) + #else + #define DLL_API __declspec(dllimport) + #endif + //---------------------------------------------------------------------- + // DLL_API is ignored for all other systems + //---------------------------------------------------------------------- +#else + #define DLL_API +#endif + +//---------------------------------------------------------------------- +// basic includes +//---------------------------------------------------------------------- + +#include // standard lib includes +#include // math includes +#include // I/O streams +#include // C-style strings + +//---------------------------------------------------------------------- +// Limits +// There are a number of places where we use the maximum double value as +// default initializers (and others may be used, depending on the +// data/distance representation). These can usually be found in limits.h +// (as LONG_MAX, INT_MAX) or in float.h (as DBL_MAX, FLT_MAX). +// +// Not all systems have these files. If you are using such a system, +// you should set the preprocessor symbol ANN_NO_LIMITS_H when +// compiling, and modify the statements below to generate the +// appropriate value. For practical purposes, this does not need to be +// the maximum double value. It is sufficient that it be at least as +// large than the maximum squared distance between between any two +// points. +//---------------------------------------------------------------------- +#ifdef ANN_NO_LIMITS_H // limits.h unavailable + #include // replacement for limits.h + const double ANN_DBL_MAX = MAXDOUBLE; // insert maximum double +#else + #include + #include + const double ANN_DBL_MAX = DBL_MAX; +#endif + +#define ANNversion "1.1.2" // ANN version and information +#define ANNversionCmt "" +#define ANNcopyright "David M. Mount and Sunil Arya" +#define ANNlatestRev "Jan 27, 2010" + +//---------------------------------------------------------------------- +// ANNbool +// This is a simple boolean type. Although ANSI C++ is supposed +// to support the type bool, some compilers do not have it. +//---------------------------------------------------------------------- + +enum ANNbool {ANNfalse = 0, ANNtrue = 1}; // ANN boolean type (non ANSI C++) + +//---------------------------------------------------------------------- +// ANNcoord, ANNdist +// ANNcoord and ANNdist are the types used for representing +// point coordinates and distances. They can be modified by the +// user, with some care. It is assumed that they are both numeric +// types, and that ANNdist is generally of an equal or higher type +// from ANNcoord. A variable of type ANNdist should be large +// enough to store the sum of squared components of a variable +// of type ANNcoord for the number of dimensions needed in the +// application. For example, the following combinations are +// legal: +// +// ANNcoord ANNdist +// --------- ------------------------------- +// short short, int, long, float, double +// int int, long, float, double +// long long, float, double +// float float, double +// double double +// +// It is the user's responsibility to make sure that overflow does +// not occur in distance calculation. +//---------------------------------------------------------------------- + +typedef double ANNcoord; // coordinate data type +typedef double ANNdist; // distance data type + +//---------------------------------------------------------------------- +// ANNidx +// ANNidx is a point index. When the data structure is built, the +// points are given as an array. Nearest neighbor results are +// returned as an integer index into this array. To make it +// clearer when this is happening, we define the integer type +// ANNidx. Indexing starts from 0. +// +// For fixed-radius near neighbor searching, it is possible that +// there are not k nearest neighbors within the search radius. To +// indicate this, the algorithm returns ANN_NULL_IDX as its result. +// It should be distinguishable from any valid array index. +//---------------------------------------------------------------------- + +typedef int ANNidx; // point index +const ANNidx ANN_NULL_IDX = -1; // a NULL point index + +//---------------------------------------------------------------------- +// Infinite distance: +// The code assumes that there is an "infinite distance" which it +// uses to initialize distances before performing nearest neighbor +// searches. It should be as larger or larger than any legitimate +// nearest neighbor distance. +// +// On most systems, these should be found in the standard include +// file or possibly . If you do not have these +// file, some suggested values are listed below, assuming 64-bit +// long, 32-bit int and 16-bit short. +// +// ANNdist ANN_DIST_INF Values (see or ) +// ------- ------------ ------------------------------------ +// double DBL_MAX 1.79769313486231570e+308 +// float FLT_MAX 3.40282346638528860e+38 +// long LONG_MAX 0x7fffffffffffffff +// int INT_MAX 0x7fffffff +// short SHRT_MAX 0x7fff +//---------------------------------------------------------------------- + +const ANNdist ANN_DIST_INF = ANN_DBL_MAX; + +//---------------------------------------------------------------------- +// Significant digits for tree dumps: +// When floating point coordinates are used, the routine that dumps +// a tree needs to know roughly how many significant digits there +// are in a ANNcoord, so it can output points to full precision. +// This is defined to be ANNcoordPrec. On most systems these +// values can be found in the standard include files or +// . For integer types, the value is essentially ignored. +// +// ANNcoord ANNcoordPrec Values (see or ) +// -------- ------------ ------------------------------------ +// double DBL_DIG 15 +// float FLT_DIG 6 +// long doesn't matter 19 +// int doesn't matter 10 +// short doesn't matter 5 +//---------------------------------------------------------------------- + +#ifdef DBL_DIG // number of sig. bits in ANNcoord + const int ANNcoordPrec = DBL_DIG; +#else + const int ANNcoordPrec = 15; // default precision +#endif + +//---------------------------------------------------------------------- +// Self match? +// In some applications, the nearest neighbor of a point is not +// allowed to be the point itself. This occurs, for example, when +// computing all nearest neighbors in a set. By setting the +// parameter ANN_ALLOW_SELF_MATCH to ANNfalse, the nearest neighbor +// is the closest point whose distance from the query point is +// strictly positive. +//---------------------------------------------------------------------- + +const ANNbool ANN_ALLOW_SELF_MATCH = ANNtrue; + +//---------------------------------------------------------------------- +// Norms and metrics: +// ANN supports any Minkowski norm for defining distance. In +// particular, for any p >= 1, the L_p Minkowski norm defines the +// length of a d-vector (v0, v1, ..., v(d-1)) to be +// +// (|v0|^p + |v1|^p + ... + |v(d-1)|^p)^(1/p), +// +// (where ^ denotes exponentiation, and |.| denotes absolute +// value). The distance between two points is defined to be the +// norm of the vector joining them. Some common distance metrics +// include +// +// Euclidean metric p = 2 +// Manhattan metric p = 1 +// Max metric p = infinity +// +// In the case of the max metric, the norm is computed by taking +// the maxima of the absolute values of the components. ANN is +// highly "coordinate-based" and does not support general distances +// functions (e.g. those obeying just the triangle inequality). It +// also does not support distance functions based on +// inner-products. +// +// For the purpose of computing nearest neighbors, it is not +// necessary to compute the final power (1/p). Thus the only +// component that is used by the program is |v(i)|^p. +// +// ANN parameterizes the distance computation through the following +// macros. (Macros are used rather than procedures for +// efficiency.) Recall that the distance between two points is +// given by the length of the vector joining them, and the length +// or norm of a vector v is given by formula: +// +// |v| = ROOT(POW(v0) # POW(v1) # ... # POW(v(d-1))) +// +// where ROOT, POW are unary functions and # is an associative and +// commutative binary operator mapping the following types: +// +// ** POW: ANNcoord --> ANNdist +// ** #: ANNdist x ANNdist --> ANNdist +// ** ROOT: ANNdist (>0) --> double +// +// For early termination in distance calculation (partial distance +// calculation) we assume that POW and # together are monotonically +// increasing on sequences of arguments, meaning that for all +// v0..vk and y: +// +// POW(v0) #...# POW(vk) <= (POW(v0) #...# POW(vk)) # POW(y). +// +// Incremental Distance Calculation: +// The program uses an optimized method of computing distances for +// kd-trees and bd-trees, called incremental distance calculation. +// It is used when distances are to be updated when only a single +// coordinate of a point has been changed. In order to use this, +// we assume that there is an incremental update function DIFF(x,y) +// for #, such that if: +// +// s = x0 # ... # xi # ... # xk +// +// then if s' is equal to s but with xi replaced by y, that is, +// +// s' = x0 # ... # y # ... # xk +// +// then the length of s' can be computed by: +// +// |s'| = |s| # DIFF(xi,y). +// +// Thus, if # is + then DIFF(xi,y) is (yi-x). For the L_infinity +// norm we make use of the fact that in the program this function +// is only invoked when y > xi, and hence DIFF(xi,y)=y. +// +// Finally, for approximate nearest neighbor queries we assume +// that POW and ROOT are related such that +// +// v*ROOT(x) = ROOT(POW(v)*x) +// +// Here are the values for the various Minkowski norms: +// +// L_p: p even: p odd: +// ------------------------- ------------------------ +// POW(v) = v^p POW(v) = |v|^p +// ROOT(x) = x^(1/p) ROOT(x) = x^(1/p) +// # = + # = + +// DIFF(x,y) = y - x DIFF(x,y) = y - x +// +// L_inf: +// POW(v) = |v| +// ROOT(x) = x +// # = max +// DIFF(x,y) = y +// +// By default the Euclidean norm is assumed. To change the norm, +// uncomment the appropriate set of macros below. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// Use the following for the Euclidean norm +//---------------------------------------------------------------------- +#define ANN_POW(v) ((v)*(v)) +#define ANN_ROOT(x) sqrt(x) +#define ANN_SUM(x,y) ((x) + (y)) +#define ANN_DIFF(x,y) ((y) - (x)) + +//---------------------------------------------------------------------- +// Use the following for the L_1 (Manhattan) norm +//---------------------------------------------------------------------- +// #define ANN_POW(v) fabs(v) +// #define ANN_ROOT(x) (x) +// #define ANN_SUM(x,y) ((x) + (y)) +// #define ANN_DIFF(x,y) ((y) - (x)) + +//---------------------------------------------------------------------- +// Use the following for a general L_p norm +//---------------------------------------------------------------------- +// #define ANN_POW(v) pow(fabs(v),p) +// #define ANN_ROOT(x) pow(fabs(x),1/p) +// #define ANN_SUM(x,y) ((x) + (y)) +// #define ANN_DIFF(x,y) ((y) - (x)) + +//---------------------------------------------------------------------- +// Use the following for the L_infinity (Max) norm +//---------------------------------------------------------------------- +// #define ANN_POW(v) fabs(v) +// #define ANN_ROOT(x) (x) +// #define ANN_SUM(x,y) ((x) > (y) ? (x) : (y)) +// #define ANN_DIFF(x,y) (y) + +//---------------------------------------------------------------------- +// Array types +// The following array types are of basic interest. A point is +// just a dimensionless array of coordinates, a point array is a +// dimensionless array of points. A distance array is a +// dimensionless array of distances and an index array is a +// dimensionless array of point indices. The latter two are used +// when returning the results of k-nearest neighbor queries. +//---------------------------------------------------------------------- + +typedef ANNcoord* ANNpoint; // a point +typedef ANNpoint* ANNpointArray; // an array of points +typedef ANNdist* ANNdistArray; // an array of distances +typedef ANNidx* ANNidxArray; // an array of point indices + +//---------------------------------------------------------------------- +// Basic point and array utilities: +// The following procedures are useful supplements to ANN's nearest +// neighbor capabilities. +// +// annDist(): +// Computes the (squared) distance between a pair of points. +// Note that this routine is not used internally by ANN for +// computing distance calculations. For reasons of efficiency +// this is done using incremental distance calculation. Thus, +// this routine cannot be modified as a method of changing the +// metric. +// +// Because points (somewhat like strings in C) are stored as +// pointers. Consequently, creating and destroying copies of +// points may require storage allocation. These procedures do +// this. +// +// annAllocPt() and annDeallocPt(): +// Allocate a deallocate storage for a single point, and +// return a pointer to it. The argument to AllocPt() is +// used to initialize all components. +// +// annAllocPts() and annDeallocPts(): +// Allocate and deallocate an array of points as well a +// place to store their coordinates, and initializes the +// points to point to their respective coordinates. It +// allocates point storage in a contiguous block large +// enough to store all the points. It performs no +// initialization. +// +// annCopyPt(): +// Creates a copy of a given point, allocating space for +// the new point. It returns a pointer to the newly +// allocated copy. +//---------------------------------------------------------------------- + +DLL_API ANNdist annDist( + int dim, // dimension of space + ANNpoint p, // points + ANNpoint q); + +DLL_API ANNpoint annAllocPt( + int dim, // dimension + ANNcoord c = 0); // coordinate value (all equal) + +DLL_API ANNpointArray annAllocPts( + int n, // number of points + int dim); // dimension + +DLL_API void annDeallocPt( + ANNpoint &p); // deallocate 1 point + +DLL_API void annDeallocPts( + ANNpointArray &pa); // point array + +DLL_API ANNpoint annCopyPt( + int dim, // dimension + ANNpoint source); // point to copy + +//---------------------------------------------------------------------- +//Overall structure: ANN supports a number of different data structures +//for approximate and exact nearest neighbor searching. These are: +// +// ANNbruteForce A simple brute-force search structure. +// ANNkd_tree A kd-tree tree search structure. ANNbd_tree +// A bd-tree tree search structure (a kd-tree with shrink +// capabilities). +// +// At a minimum, each of these data structures support k-nearest +// neighbor queries. The nearest neighbor query, annkSearch, +// returns an integer identifier and the distance to the nearest +// neighbor(s) and annRangeSearch returns the nearest points that +// lie within a given query ball. +// +// Each structure is built by invoking the appropriate constructor +// and passing it (at a minimum) the array of points, the total +// number of points and the dimension of the space. Each structure +// is also assumed to support a destructor and member functions +// that return basic information about the point set. +// +// Note that the array of points is not copied by the data +// structure (for reasons of space efficiency), and it is assumed +// to be constant throughout the lifetime of the search structure. +// +// The search algorithm, annkSearch, is given the query point (q), +// and the desired number of nearest neighbors to report (k), and +// the error bound (eps) (whose default value is 0, implying exact +// nearest neighbors). It returns two arrays which are assumed to +// contain at least k elements: one (nn_idx) contains the indices +// (within the point array) of the nearest neighbors and the other +// (dd) contains the squared distances to these nearest neighbors. +// +// The search algorithm, annkFRSearch, is a fixed-radius kNN +// search. In addition to a query point, it is given a (squared) +// radius bound. (This is done for consistency, because the search +// returns distances as squared quantities.) It does two things. +// First, it computes the k nearest neighbors within the radius +// bound, and second, it returns the total number of points lying +// within the radius bound. It is permitted to set k = 0, in which +// case it effectively answers a range counting query. If the +// error bound epsilon is positive, then the search is approximate +// in the sense that it is free to ignore any point that lies +// outside a ball of radius r/(1+epsilon), where r is the given +// (unsquared) radius bound. +// +// The generic object from which all the search structures are +// dervied is given below. It is a virtual object, and is useless +// by itself. +//---------------------------------------------------------------------- + +class DLL_API ANNpointSet { +public: + virtual ~ANNpointSet() {} // virtual distructor + + virtual void annkSearch( // approx k near neighbor search + ANNpoint q, // query point + int k, // number of near neighbors to return + ANNidxArray nn_idx, // nearest neighbor array (modified) + ANNdistArray dd, // dist to near neighbors (modified) + double eps=0.0 // error bound + ) = 0; // pure virtual (defined elsewhere) + + virtual int annkFRSearch( // approx fixed-radius kNN search + ANNpoint q, // query point + ANNdist sqRad, // squared radius + int k = 0, // number of near neighbors to return + ANNidxArray nn_idx = NULL, // nearest neighbor array (modified) + ANNdistArray dd = NULL, // dist to near neighbors (modified) + double eps=0.0 // error bound + ) = 0; // pure virtual (defined elsewhere) + + virtual int theDim() = 0; // return dimension of space + virtual int nPoints() = 0; // return number of points + // return pointer to points + virtual ANNpointArray thePoints() = 0; +}; + +//---------------------------------------------------------------------- +// Brute-force nearest neighbor search: +// The brute-force search structure is very simple but inefficient. +// It has been provided primarily for the sake of comparison with +// and validation of the more complex search structures. +// +// Query processing is the same as described above, but the value +// of epsilon is ignored, since all distance calculations are +// performed exactly. +// +// WARNING: This data structure is very slow, and should not be +// used unless the number of points is very small. +// +// Internal information: +// --------------------- +// This data structure bascially consists of the array of points +// (each a pointer to an array of coordinates). The search is +// performed by a simple linear scan of all the points. +//---------------------------------------------------------------------- + +class DLL_API ANNbruteForce: public ANNpointSet { + int dim; // dimension + int n_pts; // number of points + ANNpointArray pts; // point array +public: + ANNbruteForce( // constructor from point array + ANNpointArray pa, // point array + int n, // number of points + int dd); // dimension + + ~ANNbruteForce(); // destructor + + void annkSearch( // approx k near neighbor search + ANNpoint q, // query point + int k, // number of near neighbors to return + ANNidxArray nn_idx, // nearest neighbor array (modified) + ANNdistArray dd, // dist to near neighbors (modified) + double eps=0.0); // error bound + + int annkFRSearch( // approx fixed-radius kNN search + ANNpoint q, // query point + ANNdist sqRad, // squared radius + int k = 0, // number of near neighbors to return + ANNidxArray nn_idx = NULL, // nearest neighbor array (modified) + ANNdistArray dd = NULL, // dist to near neighbors (modified) + double eps=0.0); // error bound + + int theDim() // return dimension of space + { return dim; } + + int nPoints() // return number of points + { return n_pts; } + + ANNpointArray thePoints() // return pointer to points + { return pts; } +}; + +//---------------------------------------------------------------------- +// kd- and bd-tree splitting and shrinking rules +// kd-trees supports a collection of different splitting rules. +// In addition to the standard kd-tree splitting rule proposed +// by Friedman, Bentley, and Finkel, we have introduced a +// number of other splitting rules, which seem to perform +// as well or better (for the distributions we have tested). +// +// The splitting methods given below allow the user to tailor +// the data structure to the particular data set. They are +// are described in greater details in the kd_split.cc source +// file. The method ANN_KD_SUGGEST is the method chosen (rather +// subjectively) by the implementors as the one giving the +// fastest performance, and is the default splitting method. +// +// As with splitting rules, there are a number of different +// shrinking rules. The shrinking rule ANN_BD_NONE does no +// shrinking (and hence produces a kd-tree tree). The rule +// ANN_BD_SUGGEST uses the implementors favorite rule. +//---------------------------------------------------------------------- + +enum ANNsplitRule { + ANN_KD_STD = 0, // the optimized kd-splitting rule + ANN_KD_MIDPT = 1, // midpoint split + ANN_KD_FAIR = 2, // fair split + ANN_KD_SL_MIDPT = 3, // sliding midpoint splitting method + ANN_KD_SL_FAIR = 4, // sliding fair split method + ANN_KD_SUGGEST = 5}; // the authors' suggestion for best +const int ANN_N_SPLIT_RULES = 6; // number of split rules + +enum ANNshrinkRule { + ANN_BD_NONE = 0, // no shrinking at all (just kd-tree) + ANN_BD_SIMPLE = 1, // simple splitting + ANN_BD_CENTROID = 2, // centroid splitting + ANN_BD_SUGGEST = 3}; // the authors' suggested choice +const int ANN_N_SHRINK_RULES = 4; // number of shrink rules + +//---------------------------------------------------------------------- +// kd-tree: +// The main search data structure supported by ANN is a kd-tree. +// The main constructor is given a set of points and a choice of +// splitting method to use in building the tree. +// +// Construction: +// ------------- +// The constructor is given the point array, number of points, +// dimension, bucket size (default = 1), and the splitting rule +// (default = ANN_KD_SUGGEST). The point array is not copied, and +// is assumed to be kept constant throughout the lifetime of the +// search structure. There is also a "load" constructor that +// builds a tree from a file description that was created by the +// Dump operation. +// +// Search: +// ------- +// There are two search methods: +// +// Standard search (annkSearch()): +// Searches nodes in tree-traversal order, always visiting +// the closer child first. +// Priority search (annkPriSearch()): +// Searches nodes in order of increasing distance of the +// associated cell from the query point. For many +// distributions the standard search seems to work just +// fine, but priority search is safer for worst-case +// performance. +// +// Printing: +// --------- +// There are two methods provided for printing the tree. Print() +// is used to produce a "human-readable" display of the tree, with +// indenation, which is handy for debugging. Dump() produces a +// format that is suitable reading by another program. There is a +// "load" constructor, which constructs a tree which is assumed to +// have been saved by the Dump() procedure. +// +// Performance and Structure Statistics: +// ------------------------------------- +// The procedure getStats() collects statistics information on the +// tree (its size, height, etc.) See ANNperf.h for information on +// the stats structure it returns. +// +// Internal information: +// --------------------- +// The data structure consists of three major chunks of storage. +// The first (implicit) storage are the points themselves (pts), +// which have been provided by the users as an argument to the +// constructor, or are allocated dynamically if the tree is built +// using the load constructor). These should not be changed during +// the lifetime of the search structure. It is the user's +// responsibility to delete these after the tree is destroyed. +// +// The second is the tree itself (which is dynamically allocated in +// the constructor) and is given as a pointer to its root node +// (root). These nodes are automatically deallocated when the tree +// is deleted. See the file src/kd_tree.h for further information +// on the structure of the tree nodes. +// +// Each leaf of the tree does not contain a pointer directly to a +// point, but rather contains a pointer to a "bucket", which is an +// array consisting of point indices. The third major chunk of +// storage is an array (pidx), which is a large array in which all +// these bucket subarrays reside. (The reason for storing them +// separately is the buckets are typically small, but of varying +// sizes. This was done to avoid fragmentation.) This array is +// also deallocated when the tree is deleted. +// +// In addition to this, the tree consists of a number of other +// pieces of information which are used in searching and for +// subsequent tree operations. These consist of the following: +// +// dim Dimension of space +// n_pts Number of points currently in the tree +// n_max Maximum number of points that are allowed +// in the tree +// bkt_size Maximum bucket size (no. of points per leaf) +// bnd_box_lo Bounding box low point +// bnd_box_hi Bounding box high point +// splitRule Splitting method used +// +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// Some types and objects used by kd-tree functions +// See src/kd_tree.h and src/kd_tree.cpp for definitions +//---------------------------------------------------------------------- +class ANNkdStats; // stats on kd-tree +class ANNkd_node; // generic node in a kd-tree +typedef ANNkd_node* ANNkd_ptr; // pointer to a kd-tree node + +class DLL_API ANNkd_tree: public ANNpointSet { +protected: + int dim; // dimension of space + int n_pts; // number of points in tree + int bkt_size; // bucket size + ANNpointArray pts; // the points + ANNidxArray pidx; // point indices (to pts array) + ANNkd_ptr root; // root of kd-tree + ANNpoint bnd_box_lo; // bounding box low point + ANNpoint bnd_box_hi; // bounding box high point + + void SkeletonTree( // construct skeleton tree + int n, // number of points + int dd, // dimension + int bs, // bucket size + ANNpointArray pa = NULL, // point array (optional) + ANNidxArray pi = NULL); // point indices (optional) + +public: + ANNkd_tree( // build skeleton tree + int n = 0, // number of points + int dd = 0, // dimension + int bs = 1); // bucket size + + ANNkd_tree( // build from point array + ANNpointArray pa, // point array + int n, // number of points + int dd, // dimension + int bs = 1, // bucket size + ANNsplitRule split = ANN_KD_SUGGEST); // splitting method + + ANNkd_tree( // build from dump file + std::istream& in); // input stream for dump file + + ~ANNkd_tree(); // tree destructor + + void annkSearch( // approx k near neighbor search + ANNpoint q, // query point + int k, // number of near neighbors to return + ANNidxArray nn_idx, // nearest neighbor array (modified) + ANNdistArray dd, // dist to near neighbors (modified) + double eps=0.0); // error bound + + void annkPriSearch( // priority k near neighbor search + ANNpoint q, // query point + int k, // number of near neighbors to return + ANNidxArray nn_idx, // nearest neighbor array (modified) + ANNdistArray dd, // dist to near neighbors (modified) + double eps=0.0); // error bound + + int annkFRSearch( // approx fixed-radius kNN search + ANNpoint q, // the query point + ANNdist sqRad, // squared radius of query ball + int k, // number of neighbors to return + ANNidxArray nn_idx = NULL, // nearest neighbor array (modified) + ANNdistArray dd = NULL, // dist to near neighbors (modified) + double eps=0.0); // error bound + + int theDim() // return dimension of space + { return dim; } + + int nPoints() // return number of points + { return n_pts; } + + ANNpointArray thePoints() // return pointer to points + { return pts; } + + virtual void Print( // print the tree (for debugging) + ANNbool with_pts, // print points as well? + std::ostream& out); // output stream + + virtual void Dump( // dump entire tree + ANNbool with_pts, // print points as well? + std::ostream& out); // output stream + + virtual void getStats( // compute tree statistics + ANNkdStats& st); // the statistics (modified) +}; + +//---------------------------------------------------------------------- +// Box decomposition tree (bd-tree) +// The bd-tree is inherited from a kd-tree. The main difference +// in the bd-tree and the kd-tree is a new type of internal node +// called a shrinking node (in the kd-tree there is only one type +// of internal node, a splitting node). The shrinking node +// makes it possible to generate balanced trees in which the +// cells have bounded aspect ratio, by allowing the decomposition +// to zoom in on regions of dense point concentration. Although +// this is a nice idea in theory, few point distributions are so +// densely clustered that this is really needed. +//---------------------------------------------------------------------- + +class DLL_API ANNbd_tree: public ANNkd_tree { +public: + ANNbd_tree( // build skeleton tree + int n, // number of points + int dd, // dimension + int bs = 1) // bucket size + : ANNkd_tree(n, dd, bs) {} // build base kd-tree + + ANNbd_tree( // build from point array + ANNpointArray pa, // point array + int n, // number of points + int dd, // dimension + int bs = 1, // bucket size + ANNsplitRule split = ANN_KD_SUGGEST, // splitting rule + ANNshrinkRule shrink = ANN_BD_SUGGEST); // shrinking rule + + ANNbd_tree( // build from dump file + std::istream& in); // input stream for dump file +}; + +//---------------------------------------------------------------------- +// Other functions +// annMaxPtsVisit Sets a limit on the maximum number of points +// to visit in the search. +// annClose Can be called when all use of ANN is finished. +// It clears up a minor memory leak. +//---------------------------------------------------------------------- + +DLL_API void annMaxPtsVisit( // max. pts to visit in search + int maxPts); // the limit + +DLL_API void annClose(); // called to end use of ANN + +#endif diff --git a/kNN/ANN/ANNperf.h b/kNN/ANN/ANNperf.h new file mode 100755 index 000000000..4ce4b61b6 --- /dev/null +++ b/kNN/ANN/ANNperf.h @@ -0,0 +1,223 @@ +//---------------------------------------------------------------------- +// File: ANNperf.h +// Programmer: Sunil Arya and David Mount +// Last modified: 03/04/98 (Release 0.1) +// Description: Include file for ANN performance stats +// +// Some of the code for statistics gathering has been adapted +// from the SmplStat.h package in the g++ library. +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 +// Added ANN_ prefix to avoid name conflicts. +//---------------------------------------------------------------------- + +#ifndef ANNperf_H +#define ANNperf_H + +//---------------------------------------------------------------------- +// basic includes +//---------------------------------------------------------------------- + +#include "ANN.h" // basic ANN includes + +//---------------------------------------------------------------------- +// kd-tree stats object +// This object is used for collecting information about a kd-tree +// or bd-tree. +//---------------------------------------------------------------------- + +class ANNkdStats { // stats on kd-tree +public: + int dim; // dimension of space + int n_pts; // no. of points + int bkt_size; // bucket size + int n_lf; // no. of leaves (including trivial) + int n_tl; // no. of trivial leaves (no points) + int n_spl; // no. of splitting nodes + int n_shr; // no. of shrinking nodes (for bd-trees) + int depth; // depth of tree + float sum_ar; // sum of leaf aspect ratios + float avg_ar; // average leaf aspect ratio + // + // reset stats + void reset(int d=0, int n=0, int bs=0) + { + dim = d; n_pts = n; bkt_size = bs; + n_lf = n_tl = n_spl = n_shr = depth = 0; + sum_ar = avg_ar = 0.0; + } + + ANNkdStats() // basic constructor + { reset(); } + + void merge(const ANNkdStats &st); // merge stats from child +}; + +//---------------------------------------------------------------------- +// ANNsampStat +// A sample stat collects numeric (double) samples and returns some +// simple statistics. Its main functions are: +// +// reset() Reset to no samples. +// += x Include sample x. +// samples() Return number of samples. +// mean() Return mean of samples. +// stdDev() Return standard deviation +// min() Return minimum of samples. +// max() Return maximum of samples. +//---------------------------------------------------------------------- +class DLL_API ANNsampStat { + int n; // number of samples + double sum; // sum + double sum2; // sum of squares + double minVal, maxVal; // min and max +public : + void reset() // reset everything + { + n = 0; + sum = sum2 = 0; + minVal = ANN_DBL_MAX; + maxVal = -ANN_DBL_MAX; + } + + ANNsampStat() { reset(); } // constructor + + void operator+=(double x) // add sample + { + n++; sum += x; sum2 += x*x; + if (x < minVal) minVal = x; + if (x > maxVal) maxVal = x; + } + + int samples() { return n; } // number of samples + + double mean() { return sum/n; } // mean + + // standard deviation + double stdDev() { return sqrt((sum2 - (sum*sum)/n)/(n-1));} + + double min() { return minVal; } // minimum + double max() { return maxVal; } // maximum +}; + +//---------------------------------------------------------------------- +// Operation count updates +//---------------------------------------------------------------------- + +#ifdef ANN_PERF + #define ANN_FLOP(n) {ann_Nfloat_ops += (n);} + #define ANN_LEAF(n) {ann_Nvisit_lfs += (n);} + #define ANN_SPL(n) {ann_Nvisit_spl += (n);} + #define ANN_SHR(n) {ann_Nvisit_shr += (n);} + #define ANN_PTS(n) {ann_Nvisit_pts += (n);} + #define ANN_COORD(n) {ann_Ncoord_hts += (n);} +#else + #define ANN_FLOP(n) + #define ANN_LEAF(n) + #define ANN_SPL(n) + #define ANN_SHR(n) + #define ANN_PTS(n) + #define ANN_COORD(n) +#endif + +//---------------------------------------------------------------------- +// Performance statistics +// The following data and routines are used for computing performance +// statistics for nearest neighbor searching. Because these routines +// can slow the code down, they can be activated and deactiviated by +// defining the ANN_PERF variable, by compiling with the option: +// -DANN_PERF +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// Global counters for performance measurement +// +// visit_lfs The number of leaf nodes visited in the +// tree. +// +// visit_spl The number of splitting nodes visited in the +// tree. +// +// visit_shr The number of shrinking nodes visited in the +// tree. +// +// visit_pts The number of points visited in all the +// leaf nodes visited. Equivalently, this +// is the number of points for which distance +// calculations are performed. +// +// coord_hts The number of times a coordinate of a +// data point is accessed. This is generally +// less than visit_pts*d if partial distance +// calculation is used. This count is low +// in the sense that if a coordinate is hit +// many times in the same routine we may +// count it only once. +// +// float_ops The number of floating point operations. +// This includes all operations in the heap +// as well as distance calculations to boxes. +// +// average_err The average error of each query (the +// error of the reported point to the true +// nearest neighbor). For k nearest neighbors +// the error is computed k times. +// +// rank_err The rank error of each query (the difference +// in the rank of the reported point and its +// true rank). +// +// data_pts The number of data points. This is not +// a counter, but used in stats computation. +//---------------------------------------------------------------------- + +extern int ann_Ndata_pts; // number of data points +extern int ann_Nvisit_lfs; // number of leaf nodes visited +extern int ann_Nvisit_spl; // number of splitting nodes visited +extern int ann_Nvisit_shr; // number of shrinking nodes visited +extern int ann_Nvisit_pts; // visited points for one query +extern int ann_Ncoord_hts; // coordinate hits for one query +extern int ann_Nfloat_ops; // floating ops for one query +extern ANNsampStat ann_visit_lfs; // stats on leaf nodes visits +extern ANNsampStat ann_visit_spl; // stats on splitting nodes visits +extern ANNsampStat ann_visit_shr; // stats on shrinking nodes visits +extern ANNsampStat ann_visit_nds; // stats on total nodes visits +extern ANNsampStat ann_visit_pts; // stats on points visited +extern ANNsampStat ann_coord_hts; // stats on coordinate hits +extern ANNsampStat ann_float_ops; // stats on floating ops +//---------------------------------------------------------------------- +// The following need to be part of the public interface, because +// they are accessed outside the DLL in ann_test.cpp. +//---------------------------------------------------------------------- +DLL_API extern ANNsampStat ann_average_err; // average error +DLL_API extern ANNsampStat ann_rank_err; // rank error + +//---------------------------------------------------------------------- +// Declaration of externally accessible routines for statistics +//---------------------------------------------------------------------- + +DLL_API void annResetStats(int data_size); // reset stats for a set of queries + +DLL_API void annResetCounts(); // reset counts for one queries + +DLL_API void annUpdateStats(); // update stats with current counts + +DLL_API void annPrintStats(ANNbool validate); // print statistics for a run + +#endif diff --git a/kNN/ANN/ANNx.h b/kNN/ANN/ANNx.h new file mode 100755 index 000000000..1433631c4 --- /dev/null +++ b/kNN/ANN/ANNx.h @@ -0,0 +1,169 @@ +//---------------------------------------------------------------------- +// File: ANNx.h +// Programmer: Sunil Arya and David Mount +// Description: Internal include file for ANN +// Last modified: 01/27/10 (Version 1.1.2) +// +// These declarations are of use in manipulating some of +// the internal data objects appearing in ANN, but are not +// needed for applications just using the nearest neighbor +// search. +// +// Typical users of ANN should not need to access this file. +//---------------------------------------------------------------------- +// Copyright (c) 1997-2010 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 +// Changed LO, HI, IN, OUT to ANN_LO, ANN_HI, etc. +// Revision 1.1.2 01/27/10 +// Fixed minor compilation bugs for new versions of gcc +//---------------------------------------------------------------------- + +#ifndef ANNx_H +#define ANNx_H + +#include // I/O manipulators +#include "ANN.h" // ANN includes + +//---------------------------------------------------------------------- +// Global constants and types +//---------------------------------------------------------------------- +enum {ANN_LO=0, ANN_HI=1}; // splitting indices +enum {ANN_IN=0, ANN_OUT=1}; // shrinking indices + // what to do in case of error +enum ANNerr {ANNwarn = 0, ANNabort = 1}; + +//---------------------------------------------------------------------- +// Maximum number of points to visit +// We have an option for terminating the search early if the +// number of points visited exceeds some threshold. If the +// threshold is 0 (its default) this means there is no limit +// and the algorithm applies its normal termination condition. +//---------------------------------------------------------------------- + +extern int ANNmaxPtsVisited; // maximum number of pts visited +extern int ANNptsVisited; // number of pts visited in search + +//---------------------------------------------------------------------- +// Global function declarations +//---------------------------------------------------------------------- + +void annError( // ANN error routine + const char* msg, // error message + ANNerr level); // level of error + +void annPrintPt( // print a point + ANNpoint pt, // the point + int dim, // the dimension + std::ostream &out); // output stream + +//---------------------------------------------------------------------- +// Orthogonal (axis aligned) rectangle +// Orthogonal rectangles are represented by two points, one +// for the lower left corner (min coordinates) and the other +// for the upper right corner (max coordinates). +// +// The constructor initializes from either a pair of coordinates, +// pair of points, or another rectangle. Note that all constructors +// allocate new point storage. The destructor deallocates this +// storage. +// +// BEWARE: Orthogonal rectangles should be passed ONLY BY REFERENCE. +// (C++'s default copy constructor will not allocate new point +// storage, then on return the destructor free's storage, and then +// you get into big trouble in the calling procedure.) +//---------------------------------------------------------------------- + +class ANNorthRect { +public: + ANNpoint lo; // rectangle lower bounds + ANNpoint hi; // rectangle upper bounds +// + ANNorthRect( // basic constructor + int dd, // dimension of space + ANNcoord l=0, // default is empty + ANNcoord h=0) + { lo = annAllocPt(dd, l); hi = annAllocPt(dd, h); } + + ANNorthRect( // (almost a) copy constructor + int dd, // dimension + const ANNorthRect &r) // rectangle to copy + { lo = annCopyPt(dd, r.lo); hi = annCopyPt(dd, r.hi); } + + ANNorthRect( // construct from points + int dd, // dimension + ANNpoint l, // low point + ANNpoint h) // hight point + { lo = annCopyPt(dd, l); hi = annCopyPt(dd, h); } + + ~ANNorthRect() // destructor + { annDeallocPt(lo); annDeallocPt(hi); } + + ANNbool inside(int dim, ANNpoint p);// is point p inside rectangle? +}; + +void annAssignRect( // assign one rect to another + int dim, // dimension (both must be same) + ANNorthRect &dest, // destination (modified) + const ANNorthRect &source); // source + +//---------------------------------------------------------------------- +// Orthogonal (axis aligned) halfspace +// An orthogonal halfspace is represented by an integer cutting +// dimension cd, coordinate cutting value, cv, and side, sd, which is +// either +1 or -1. Our convention is that point q lies in the (closed) +// halfspace if (q[cd] - cv)*sd >= 0. +//---------------------------------------------------------------------- + +class ANNorthHalfSpace { +public: + int cd; // cutting dimension + ANNcoord cv; // cutting value + int sd; // which side +// + ANNorthHalfSpace() // default constructor + { cd = 0; cv = 0; sd = 0; } + + ANNorthHalfSpace( // basic constructor + int cdd, // dimension of space + ANNcoord cvv, // cutting value + int sdd) // side + { cd = cdd; cv = cvv; sd = sdd; } + + ANNbool in(ANNpoint q) const // is q inside halfspace? + { return (ANNbool) ((q[cd] - cv)*sd >= 0); } + + ANNbool out(ANNpoint q) const // is q outside halfspace? + { return (ANNbool) ((q[cd] - cv)*sd < 0); } + + ANNdist dist(ANNpoint q) const // (squared) distance from q + { return (ANNdist) ANN_POW(q[cd] - cv); } + + void setLowerBound(int d, ANNpoint p)// set to lower bound at p[i] + { cd = d; cv = p[d]; sd = +1; } + + void setUpperBound(int d, ANNpoint p)// set to upper bound at p[i] + { cd = d; cv = p[d]; sd = -1; } + + void project(ANNpoint &q) // project q (modified) onto halfspace + { if (out(q)) q[cd] = cv; } +}; + + // array of halfspaces +typedef ANNorthHalfSpace *ANNorthHSArray; + +#endif diff --git a/kNN/ANNperf.h b/kNN/ANNperf.h deleted file mode 100644 index 5d2d21a09..000000000 --- a/kNN/ANNperf.h +++ /dev/null @@ -1,131 +0,0 @@ -//---------------------------------------------------------------------- -// File: ANNperf.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Include file for ANN performance stats -// -// Some of the code for statistics gathering has been adapted -// from the SmplStat.h package in the g++ library. -//---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. -// -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). -// -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. -//---------------------------------------------------------------------- - -#ifndef ANNperf_H -#define ANNperf_H - -//---------------------------------------------------------------------- -// basic includes -//---------------------------------------------------------------------- -#include // standard libaries -#include // standard I/O -#include // C++ I/O streams -#include // math routines -using namespace std; - -#include "values.h" - -//---------------------------------------------------------------------- -// Operation count updates -//---------------------------------------------------------------------- - -#ifdef PERF -#define FLOP(n) {N_float_ops += (n);} -#define LEAF(n) {N_visit_lfs += (n);} -#define SPL(n) {N_visit_spl += (n);} -#define SHR(n) {N_visit_shr += (n);} -#define PTS(n) {N_visit_pts += (n);} -#define COORD(n) {N_coord_hts += (n);} -#else -#define FLOP(n) -#define LEAF(n) -#define SPL(n) -#define SHR(n) -#define PTS(n) -#define COORD(n) -#endif - -//---------------------------------------------------------------------- -// Performance statistics -// The following data and routines are used for computing -// performance statistics for nearest neighbor searching. -// Because these routines can slow the code down, they can be -// activated and deactiviated by defining the PERF variable, -// by compiling with the option: -DPERF -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// Global counters for performance measurement -// -// visit_lfs The number of leaf nodes visited in the -// tree. -// -// visit_spl The number of splitting nodes visited in the -// tree. -// -// visit_shr The number of shrinking nodes visited in the -// tree. -// -// visit_pts The number of points visited in all the -// leaf nodes visited. Equivalently, this -// is the number of points for which distance -// calculations are performed. -// -// coord_hts The number of times a coordinate of a -// data point is accessed. This is generally -// less than visit_pts*d if partial distance -// calculation is used. This count is low -// in the sense that if a coordinate is hit -// many times in the same routine we may -// count it only once. -// -// float_ops The number of floating point operations. -// This includes all operations in the heap -// as well as distance calculations to boxes. -// -// average_err The average error of each query (the -// error of the reported point to the true -// nearest neighbor). For k nearest neighbors -// the error is computed k times. -// -// rank_err The rank error of each query (the difference -// in the rank of the reported point and its -// true rank). -// -// data_pts The number of data points. This is not -// a counter, but used in stats computation. -//---------------------------------------------------------------------- - -extern int N_data_pts; // number of data points -extern int N_visit_lfs; // number of leaf nodes visited -extern int N_visit_spl; // number of splitting nodes visited -extern int N_visit_shr; // number of shrinking nodes visited -extern int N_visit_pts; // visited points for one query -extern int N_coord_hts; // coordinate hits for one query -extern int N_float_ops; // floating ops for one query -//---------------------------------------------------------------------- -// Declaration of externally accessible routines for statistics -//---------------------------------------------------------------------- - -void reset_stats(int data_size); // reset stats for a set of queries - -void reset_counts(); // reset counts for one queries - -void update_stats(); // update stats with current counts - -void print_stats(ANNbool validate); // print statistics for a run - -#endif diff --git a/kNN/ANNx.h b/kNN/ANNx.h deleted file mode 100644 index b981f499f..000000000 --- a/kNN/ANNx.h +++ /dev/null @@ -1,165 +0,0 @@ -//---------------------------------------------------------------------- -// File: ANNx.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Internal include file for ANN -// -// These declarations are of use in manipulating some of -// the internal data objects appearing in ANN, but are not -// needed for applications just using the nearest neighbor -// search. -// -// Typical users of ANN should not need to access this file. -//---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. -// -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). -// -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. -//---------------------------------------------------------------------- - -#ifndef ANNx_H -#define ANNx_H - -#include // I/O manipulators -using namespace std; - -//---------------------------------------------------------------------- -// Global constants and types -//---------------------------------------------------------------------- -enum {LO=0, HI=1}; // splitting indices -enum {INx=0, OUTx=1}; // shrinking indices - - // what to do in case of error -enum ANNerr {ANNwarn = 0, ANNabort = 1}; - -//---------------------------------------------------------------------- -// Maximum number of points to visit -// We have an option for terminating the search early if the -// number of points visited exceeds some threshold. If the -// threshold is 0 (its default) this means there is no limit -// and the algorithm applies its normal termination condition. -//---------------------------------------------------------------------- - -extern int ANNmaxPtsVisited;// maximum number of pts visited -extern int ANNptsVisited; // number of pts visited in search - -//---------------------------------------------------------------------- -// Global function declarations -//---------------------------------------------------------------------- - -void annError( // ANN error routine - char *msg, // error message - ANNerr level); // level of error - -void annPrintPt( // print a point - ANNpoint pt, // the point - int dim, // the dimension - ostream &out); // output stream - -//---------------------------------------------------------------------- -// Orthogonal (axis aligned) rectangle -// Orthogonal rectangles are represented by two points, one -// for the lower left corner (min coordinates) and the other -// for the upper right corner (max coordinates). -// -// The constructor initializes from either a pair of coordinates, -// pair of points, or another rectangle. Note that all constructors -// allocate new point storage. The destructor deallocates this -// storage. -// -// BEWARE: Orthogonal rectangles should be passed ONLY BY REFERENCE. -// (C++'s default copy constructor will not allocate new point -// storage, then on return the destructor free's storage, and then -// you get into big trouble in the calling procedure.) -//---------------------------------------------------------------------- - -class ANNorthRect { -public: - ANNpoint lo; // rectangle lower bounds - ANNpoint hi; // rectangle upper bounds -// - ANNorthRect( // basic constructor - int dd, // dimension of space - ANNcoord l=0, // default is empty - ANNcoord h=0) - { lo = annAllocPt(dd, l); hi = annAllocPt(dd, h); } - - ANNorthRect( // (almost a) copy constructor - int dd, // dimension - const ANNorthRect &r) // rectangle to copy - { lo = annCopyPt(dd, r.lo); hi = annCopyPt(dd, r.hi); } - - ANNorthRect( // construct from points - int dd, // dimension - ANNpoint l, // low point - ANNpoint h) // hight point - { lo = annCopyPt(dd, l); hi = annCopyPt(dd, h); } - - ~ANNorthRect() // destructor - { } - - ANNbool inside(int dim, ANNpoint p);// is point p inside rectangle? -}; - -void annAssignRect( // assign one rect to another - int dim, // dimension (both must be same) - ANNorthRect &dest, // destination (modified) - const ANNorthRect &source); // source - -//---------------------------------------------------------------------- -// Orthogonal (axis aligned) halfspace -// An orthogonal halfspace is represented by an integer cutting -// dimension cd, coordinate cutting value, cv, and side, sd, which -// is either +1 or -1. Our convention is that point q lies in the -// (closed) halfspace if (q[cd] - cv)*sd >= 0. -//---------------------------------------------------------------------- - -class ANNorthHalfSpace { -public: - int cd; // cutting dimension - ANNcoord cv; // cutting value - int sd; // which side -// - ANNorthHalfSpace() // default constructor - { cd = 0; cv = 0; sd = 0; } - - ANNorthHalfSpace( // basic constructor - int cdd, // dimension of space - ANNcoord cvv, // cutting value - int sdd) // side - { cd = cdd; cv = cvv; sd = sdd; } - - ANNbool in(ANNpoint q) const // is q inside halfspace? - { return (ANNbool) ((q[cd] - cv)*sd >= 0); } - - ANNbool out(ANNpoint q) const // is q outside halfspace? - { return (ANNbool) ((q[cd] - cv)*sd < 0); } - - ANNdist dist(ANNpoint q) const // (squared) distance from q - { return (ANNdist) ANN_POW(q[cd] - cv); } - - void setLowerBound(int d, ANNpoint p)// set to lower bound at p[i] - { cd = d; cv = p[d]; sd = +1; } - - void setUpperBound(int d, ANNpoint p)// set to upper bound at p[i] - { cd = d; cv = p[d]; sd = -1; } - - void project(ANNpoint &q) // project q (modified) onto halfspace - { if (out(q)) q[cd] = cv; } -}; - - // array of halfspaces -typedef ANNorthHalfSpace *ANNorthHSArray; - -#endif diff --git a/kNN/Makefile b/kNN/Makefile new file mode 100755 index 000000000..1c8ec2731 --- /dev/null +++ b/kNN/Makefile @@ -0,0 +1,121 @@ +#----------------------------------------------------------------------------- +# Makefile for ANN library +#---------------------------------------------------------------------- +# Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +# David Mount. All Rights Reserved. +# +# This software and related documentation is part of the Approximate +# Nearest Neighbor Library (ANN). This software is provided under +# the provisions of the Lesser GNU Public License (LGPL). See the +# file ../ReadMe.txt for further information. +# +# The University of Maryland (U.M.) and the authors make no +# representations about the suitability or fitness of this software for +# any purpose. It is provided "as is" without express or implied +# warranty. +#---------------------------------------------------------------------- +# History: +# Revision 0.1 03/04/98 +# Initial release +# Revision 1.0 04/01/05 +# Renamed files from .cc to .cpp for Microsoft Visual C++ +# Added kd_dump.cpp +# Revision 1.1 05/03/05 +# Added kd_fix_rad_search.cpp and bd_fix_rad_search.cpp +#---------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Some basic definitions: +# BASEDIR where include, src, lib, ... are +# INCLIB include directory +# LIBLIB library directory +#----------------------------------------------------------------------------- +BASEDIR = .. +INCDIR = $(BASEDIR)/include +LIBDIR = $(BASEDIR)/lib + +SOURCES = ANN.cpp brute.cpp kd_tree.cpp kd_util.cpp kd_split.cpp \ + kd_dump.cpp kd_search.cpp kd_pr_search.cpp kd_fix_rad_search.cpp \ + bd_tree.cpp bd_search.cpp bd_pr_search.cpp bd_fix_rad_search.cpp \ + perf.cpp + +HEADERS = kd_tree.h kd_split.h kd_util.h kd_search.h \ + kd_pr_search.h kd_fix_rad_search.h perf.h pr_queue.h pr_queue_k.h + +OBJECTS = $(SOURCES:.cpp=.o) + +#----------------------------------------------------------------------------- +# Make the library +#----------------------------------------------------------------------------- + +default: + @echo "Specify a target configuration" + +targets: $(LIBDIR)/$(ANNLIB) + +$(LIBDIR)/$(ANNLIB): $(OBJECTS) + $(MAKELIB) $(ANNLIB) $(OBJECTS) + $(RANLIB) $(ANNLIB) + mv $(ANNLIB) $(LIBDIR) + +#----------------------------------------------------------------------------- +# Make object files +#----------------------------------------------------------------------------- + +ANN.o: ANN.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) ANN.cpp + +brute.o: brute.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) brute.cpp + +kd_tree.o: kd_tree.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) kd_tree.cpp + +kd_util.o: kd_util.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) kd_util.cpp + +kd_split.o: kd_split.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) kd_split.cpp + +kd_search.o: kd_search.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) kd_search.cpp + +kd_pr_search.o: kd_pr_search.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) kd_pr_search.cpp + +kd_fix_rad_search.o: kd_fix_rad_search.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) kd_fix_rad_search.cpp + +kd_dump.o: kd_dump.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) kd_dump.cpp + +bd_tree.o: bd_tree.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) bd_tree.cpp + +bd_search.o: bd_search.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) bd_search.cpp + +bd_pr_search.o: bd_pr_search.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) bd_pr_search.cpp + +bd_fix_rad_search.o: bd_fix_rad_search.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) bd_fix_rad_search.cpp + +perf.o: perf.cpp + $(C++) -c -I$(INCDIR) $(CFLAGS) perf.cpp + +#----------------------------------------------------------------------------- +# Configuration definitions +#----------------------------------------------------------------------------- + +include ../Make-config + +#----------------------------------------------------------------------------- +# Cleaning +#----------------------------------------------------------------------------- + +clean: + -rm -f *.o core + +realclean: clean + diff --git a/kNN/bd_fix_rad_search.cpp b/kNN/bd_fix_rad_search.cpp new file mode 100755 index 000000000..8c8cb0242 --- /dev/null +++ b/kNN/bd_fix_rad_search.cpp @@ -0,0 +1,61 @@ +//---------------------------------------------------------------------- +// File: bd_fix_rad_search.cpp +// Programmer: David Mount +// Description: Standard bd-tree search +// Last modified: 05/03/05 (Version 1.1) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 1.1 05/03/05 +// Initial release +//---------------------------------------------------------------------- + +#include "bd_tree.h" // bd-tree declarations +#include "kd_fix_rad_search.h" // kd-tree FR search declarations + +//---------------------------------------------------------------------- +// Approximate searching for bd-trees. +// See the file kd_FR_search.cpp for general information on the +// approximate nearest neighbor search algorithm. Here we +// include the extensions for shrinking nodes. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// bd_shrink::ann_FR_search - search a shrinking node +//---------------------------------------------------------------------- + +void ANNbd_shrink::ann_FR_search(ANNdist box_dist) +{ + // check dist calc term cond. + if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; + + ANNdist inner_dist = 0; // distance to inner box + for (int i = 0; i < n_bnds; i++) { // is query point in the box? + if (bnds[i].out(ANNkdFRQ)) { // outside this bounding side? + // add to inner distance + inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdFRQ)); + } + } + if (inner_dist <= box_dist) { // if inner box is closer + child[ANN_IN]->ann_FR_search(inner_dist);// search inner child first + child[ANN_OUT]->ann_FR_search(box_dist);// ...then outer child + } + else { // if outer box is closer + child[ANN_OUT]->ann_FR_search(box_dist);// search outer child first + child[ANN_IN]->ann_FR_search(inner_dist);// ...then outer child + } + ANN_FLOP(3*n_bnds) // increment floating ops + ANN_SHR(1) // one more shrinking node +} diff --git a/kNN/bd_pr_search.cpp b/kNN/bd_pr_search.cpp new file mode 100755 index 000000000..ad980fba3 --- /dev/null +++ b/kNN/bd_pr_search.cpp @@ -0,0 +1,62 @@ +//---------------------------------------------------------------------- +// File: bd_pr_search.cpp +// Programmer: David Mount +// Description: Priority search for bd-trees +// Last modified: 01/04/05 (Version 1.0) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +//History: +// Revision 0.1 03/04/98 +// Initial release +//---------------------------------------------------------------------- + +#include "bd_tree.h" // bd-tree declarations +#include "kd_pr_search.h" // kd priority search declarations + +//---------------------------------------------------------------------- +// Approximate priority searching for bd-trees. +// See the file kd_pr_search.cc for general information on the +// approximate nearest neighbor priority search algorithm. Here +// we include the extensions for shrinking nodes. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// bd_shrink::ann_search - search a shrinking node +//---------------------------------------------------------------------- + +void ANNbd_shrink::ann_pri_search(ANNdist box_dist) +{ + ANNdist inner_dist = 0; // distance to inner box + for (int i = 0; i < n_bnds; i++) { // is query point in the box? + if (bnds[i].out(ANNprQ)) { // outside this bounding side? + // add to inner distance + inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNprQ)); + } + } + if (inner_dist <= box_dist) { // if inner box is closer + if (child[ANN_OUT] != KD_TRIVIAL) // enqueue outer if not trivial + ANNprBoxPQ->insert(box_dist,child[ANN_OUT]); + // continue with inner child + child[ANN_IN]->ann_pri_search(inner_dist); + } + else { // if outer box is closer + if (child[ANN_IN] != KD_TRIVIAL) // enqueue inner if not trivial + ANNprBoxPQ->insert(inner_dist,child[ANN_IN]); + // continue with outer child + child[ANN_OUT]->ann_pri_search(box_dist); + } + ANN_FLOP(3*n_bnds) // increment floating ops + ANN_SHR(1) // one more shrinking node +} diff --git a/kNN/bd_search.cpp b/kNN/bd_search.cpp new file mode 100755 index 000000000..1e4926143 --- /dev/null +++ b/kNN/bd_search.cpp @@ -0,0 +1,61 @@ +//---------------------------------------------------------------------- +// File: bd_search.cpp +// Programmer: David Mount +// Description: Standard bd-tree search +// Last modified: 01/04/05 (Version 1.0) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +//---------------------------------------------------------------------- + +#include "bd_tree.h" // bd-tree declarations +#include "kd_search.h" // kd-tree search declarations + +//---------------------------------------------------------------------- +// Approximate searching for bd-trees. +// See the file kd_search.cpp for general information on the +// approximate nearest neighbor search algorithm. Here we +// include the extensions for shrinking nodes. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// bd_shrink::ann_search - search a shrinking node +//---------------------------------------------------------------------- + +void ANNbd_shrink::ann_search(ANNdist box_dist) +{ + // check dist calc term cond. + if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; + + ANNdist inner_dist = 0; // distance to inner box + for (int i = 0; i < n_bnds; i++) { // is query point in the box? + if (bnds[i].out(ANNkdQ)) { // outside this bounding side? + // add to inner distance + inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdQ)); + } + } + if (inner_dist <= box_dist) { // if inner box is closer + child[ANN_IN]->ann_search(inner_dist); // search inner child first + child[ANN_OUT]->ann_search(box_dist); // ...then outer child + } + else { // if outer box is closer + child[ANN_OUT]->ann_search(box_dist); // search outer child first + child[ANN_IN]->ann_search(inner_dist); // ...then outer child + } + ANN_FLOP(3*n_bnds) // increment floating ops + ANN_SHR(1) // one more shrinking node +} diff --git a/kNN/bd_tree.cpp b/kNN/bd_tree.cpp new file mode 100755 index 000000000..99425e484 --- /dev/null +++ b/kNN/bd_tree.cpp @@ -0,0 +1,417 @@ +//---------------------------------------------------------------------- +// File: bd_tree.cpp +// Programmer: David Mount +// Description: Basic methods for bd-trees. +// Last modified: 01/04/05 (Version 1.0) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision l.0 04/01/05 +// Fixed centroid shrink threshold condition to depend on the +// dimension. +// Moved dump routine to kd_dump.cpp. +//---------------------------------------------------------------------- + +#include "bd_tree.h" // bd-tree declarations +#include "kd_util.h" // kd-tree utilities +#include "kd_split.h" // kd-tree splitting rules + +#include // performance evaluation + +//---------------------------------------------------------------------- +// Printing a bd-tree +// These routines print a bd-tree. See the analogous procedure +// in kd_tree.cpp for more information. +//---------------------------------------------------------------------- + +void ANNbd_shrink::print( // print shrinking node + int level, // depth of node in tree + ostream &out) // output stream +{ + child[ANN_OUT]->print(level+1, out); // print out-child + + out << " "; + for (int i = 0; i < level; i++) // print indentation + out << ".."; + out << "Shrink"; + for (int j = 0; j < n_bnds; j++) { // print sides, 2 per line + if (j % 2 == 0) { + out << "\n"; // newline and indentation + for (int i = 0; i < level+2; i++) out << " "; + } + out << " ([" << bnds[j].cd << "]" + << (bnds[j].sd > 0 ? ">=" : "< ") + << bnds[j].cv << ")"; + } + out << "\n"; + + child[ANN_IN]->print(level+1, out); // print in-child +} + +//---------------------------------------------------------------------- +// kd_tree statistics utility (for performance evaluation) +// This routine computes various statistics information for +// shrinking nodes. See file kd_tree.cpp for more information. +//---------------------------------------------------------------------- + +void ANNbd_shrink::getStats( // get subtree statistics + int dim, // dimension of space + ANNkdStats &st, // stats (modified) + ANNorthRect &bnd_box) // bounding box +{ + ANNkdStats ch_stats; // stats for children + ANNorthRect inner_box(dim); // inner box of shrink + + annBnds2Box(bnd_box, // enclosing box + dim, // dimension + n_bnds, // number of bounds + bnds, // bounds array + inner_box); // inner box (modified) + // get stats for inner child + ch_stats.reset(); // reset + child[ANN_IN]->getStats(dim, ch_stats, inner_box); + st.merge(ch_stats); // merge them + // get stats for outer child + ch_stats.reset(); // reset + child[ANN_OUT]->getStats(dim, ch_stats, bnd_box); + st.merge(ch_stats); // merge them + + st.depth++; // increment depth + st.n_shr++; // increment number of shrinks +} + +//---------------------------------------------------------------------- +// bd-tree constructor +// This is the main constructor for bd-trees given a set of points. +// It first builds a skeleton kd-tree as a basis, then computes the +// bounding box of the data points, and then invokes rbd_tree() to +// actually build the tree, passing it the appropriate splitting +// and shrinking information. +//---------------------------------------------------------------------- + +ANNkd_ptr rbd_tree( // recursive construction of bd-tree + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices to store in subtree + int n, // number of points + int dim, // dimension of space + int bsp, // bucket space + ANNorthRect &bnd_box, // bounding box for current node + ANNkd_splitter splitter, // splitting routine + ANNshrinkRule shrink); // shrinking rule + +ANNbd_tree::ANNbd_tree( // construct from point array + ANNpointArray pa, // point array (with at least n pts) + int n, // number of points + int dd, // dimension + int bs, // bucket size + ANNsplitRule split, // splitting rule + ANNshrinkRule shrink) // shrinking rule + : ANNkd_tree(n, dd, bs) // build skeleton base tree +{ + pts = pa; // where the points are + if (n == 0) return; // no points--no sweat + + ANNorthRect bnd_box(dd); // bounding box for points + // construct bounding rectangle + annEnclRect(pa, pidx, n, dd, bnd_box); + // copy to tree structure + bnd_box_lo = annCopyPt(dd, bnd_box.lo); + bnd_box_hi = annCopyPt(dd, bnd_box.hi); + + switch (split) { // build by rule + case ANN_KD_STD: // standard kd-splitting rule + root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, kd_split, shrink); + break; + case ANN_KD_MIDPT: // midpoint split + root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, midpt_split, shrink); + break; + case ANN_KD_SUGGEST: // best (in our opinion) + case ANN_KD_SL_MIDPT: // sliding midpoint split + root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, sl_midpt_split, shrink); + break; + case ANN_KD_FAIR: // fair split + root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, fair_split, shrink); + break; + case ANN_KD_SL_FAIR: // sliding fair split + root = rbd_tree(pa, pidx, n, dd, bs, + bnd_box, sl_fair_split, shrink); + break; + default: + annError("Illegal splitting method", ANNabort); + } +} + +//---------------------------------------------------------------------- +// Shrinking rules +//---------------------------------------------------------------------- + +enum ANNdecomp {SPLIT, SHRINK}; // decomposition methods + +//---------------------------------------------------------------------- +// trySimpleShrink - Attempt a simple shrink +// +// We compute the tight bounding box of the points, and compute +// the 2*dim ``gaps'' between the sides of the tight box and the +// bounding box. If any of the gaps is large enough relative to +// the longest side of the tight bounding box, then we shrink +// all sides whose gaps are large enough. (The reason for +// comparing against the tight bounding box, is that after +// shrinking the longest box size will decrease, and if we use +// the standard bounding box, we may decide to shrink twice in +// a row. Since the tight box is fixed, we cannot shrink twice +// consecutively.) +//---------------------------------------------------------------------- +const float BD_GAP_THRESH = 0.5; // gap threshold (must be < 1) +const int BD_CT_THRESH = 2; // min number of shrink sides + +ANNdecomp trySimpleShrink( // try a simple shrink + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices to store in subtree + int n, // number of points + int dim, // dimension of space + const ANNorthRect &bnd_box, // current bounding box + ANNorthRect &inner_box) // inner box if shrinking (returned) +{ + int i; + // compute tight bounding box + annEnclRect(pa, pidx, n, dim, inner_box); + + ANNcoord max_length = 0; // find longest box side + for (i = 0; i < dim; i++) { + ANNcoord length = inner_box.hi[i] - inner_box.lo[i]; + if (length > max_length) { + max_length = length; + } + } + + int shrink_ct = 0; // number of sides we shrunk + for (i = 0; i < dim; i++) { // select which sides to shrink + // gap between boxes + ANNcoord gap_hi = bnd_box.hi[i] - inner_box.hi[i]; + // big enough gap to shrink? + if (gap_hi < max_length*BD_GAP_THRESH) + inner_box.hi[i] = bnd_box.hi[i]; // no - expand + else shrink_ct++; // yes - shrink this side + + // repeat for high side + ANNcoord gap_lo = inner_box.lo[i] - bnd_box.lo[i]; + if (gap_lo < max_length*BD_GAP_THRESH) + inner_box.lo[i] = bnd_box.lo[i]; // no - expand + else shrink_ct++; // yes - shrink this side + } + + if (shrink_ct >= BD_CT_THRESH) // did we shrink enough sides? + return SHRINK; + else return SPLIT; +} + +//---------------------------------------------------------------------- +// tryCentroidShrink - Attempt a centroid shrink +// +// We repeatedly apply the splitting rule, always to the larger subset +// of points, until the number of points decreases by the constant +// fraction BD_FRACTION. If this takes more than dim*BD_MAX_SPLIT_FAC +// splits for this to happen, then we shrink to the final inner box +// Otherwise we split. +//---------------------------------------------------------------------- + +const float BD_MAX_SPLIT_FAC = 0.5; // maximum number of splits allowed +const float BD_FRACTION = 0.5; // ...to reduce points by this fraction + // ...This must be < 1. + +ANNdecomp tryCentroidShrink( // try a centroid shrink + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices to store in subtree + int n, // number of points + int dim, // dimension of space + const ANNorthRect &bnd_box, // current bounding box + ANNkd_splitter splitter, // splitting procedure + ANNorthRect &inner_box) // inner box if shrinking (returned) +{ + int n_sub = n; // number of points in subset + int n_goal = (int) (n*BD_FRACTION); // number of point in goal + int n_splits = 0; // number of splits needed + // initialize inner box to bounding box + annAssignRect(dim, inner_box, bnd_box); + + while (n_sub > n_goal) { // keep splitting until goal reached + int cd; // cut dim from splitter (ignored) + ANNcoord cv; // cut value from splitter (ignored) + int n_lo; // number of points on low side + // invoke splitting procedure + (*splitter)(pa, pidx, inner_box, n_sub, dim, cd, cv, n_lo); + n_splits++; // increment split count + + if (n_lo >= n_sub/2) { // most points on low side + inner_box.hi[cd] = cv; // collapse high side + n_sub = n_lo; // recurse on lower points + } + else { // most points on high side + inner_box.lo[cd] = cv; // collapse low side + pidx += n_lo; // recurse on higher points + n_sub -= n_lo; + } + } + if (n_splits > dim*BD_MAX_SPLIT_FAC)// took too many splits + return SHRINK; // shrink to final subset + else + return SPLIT; +} + +//---------------------------------------------------------------------- +// selectDecomp - select which decomposition to use +//---------------------------------------------------------------------- + +ANNdecomp selectDecomp( // select decomposition method + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices to store in subtree + int n, // number of points + int dim, // dimension of space + const ANNorthRect &bnd_box, // current bounding box + ANNkd_splitter splitter, // splitting procedure + ANNshrinkRule shrink, // shrinking rule + ANNorthRect &inner_box) // inner box if shrinking (returned) +{ + ANNdecomp decomp = SPLIT; // decomposition + + switch (shrink) { // check shrinking rule + case ANN_BD_NONE: // no shrinking allowed + decomp = SPLIT; + break; + case ANN_BD_SUGGEST: // author's suggestion + case ANN_BD_SIMPLE: // simple shrink + decomp = trySimpleShrink( + pa, pidx, // points and indices + n, dim, // number of points and dimension + bnd_box, // current bounding box + inner_box); // inner box if shrinking (returned) + break; + case ANN_BD_CENTROID: // centroid shrink + decomp = tryCentroidShrink( + pa, pidx, // points and indices + n, dim, // number of points and dimension + bnd_box, // current bounding box + splitter, // splitting procedure + inner_box); // inner box if shrinking (returned) + break; + default: + annError("Illegal shrinking rule", ANNabort); + } + return decomp; +} + +//---------------------------------------------------------------------- +// rbd_tree - recursive procedure to build a bd-tree +// +// This is analogous to rkd_tree, but for bd-trees. See the +// procedure rkd_tree() in kd_split.cpp for more information. +// +// If the number of points falls below the bucket size, then a +// leaf node is created for the points. Otherwise we invoke the +// procedure selectDecomp() which determines whether we are to +// split or shrink. If splitting is chosen, then we essentially +// do exactly as rkd_tree() would, and invoke the specified +// splitting procedure to the points. Otherwise, the selection +// procedure returns a bounding box, from which we extract the +// appropriate shrinking bounds, and create a shrinking node. +// Finally the points are subdivided, and the procedure is +// invoked recursively on the two subsets to form the children. +//---------------------------------------------------------------------- + +ANNkd_ptr rbd_tree( // recursive construction of bd-tree + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices to store in subtree + int n, // number of points + int dim, // dimension of space + int bsp, // bucket space + ANNorthRect &bnd_box, // bounding box for current node + ANNkd_splitter splitter, // splitting routine + ANNshrinkRule shrink) // shrinking rule +{ + ANNdecomp decomp; // decomposition method + + ANNorthRect inner_box(dim); // inner box (if shrinking) + + if (n <= bsp) { // n small, make a leaf node + if (n == 0) // empty leaf node + return KD_TRIVIAL; // return (canonical) empty leaf + else // construct the node and return + return new ANNkd_leaf(n, pidx); + } + + decomp = selectDecomp( // select decomposition method + pa, pidx, // points and indices + n, dim, // number of points and dimension + bnd_box, // current bounding box + splitter, shrink, // splitting/shrinking methods + inner_box); // inner box if shrinking (returned) + + if (decomp == SPLIT) { // split selected + int cd; // cutting dimension + ANNcoord cv; // cutting value + int n_lo; // number on low side of cut + // invoke splitting procedure + (*splitter)(pa, pidx, bnd_box, n, dim, cd, cv, n_lo); + + ANNcoord lv = bnd_box.lo[cd]; // save bounds for cutting dimension + ANNcoord hv = bnd_box.hi[cd]; + + bnd_box.hi[cd] = cv; // modify bounds for left subtree + ANNkd_ptr lo = rbd_tree( // build left subtree + pa, pidx, n_lo, // ...from pidx[0..n_lo-1] + dim, bsp, bnd_box, splitter, shrink); + bnd_box.hi[cd] = hv; // restore bounds + + bnd_box.lo[cd] = cv; // modify bounds for right subtree + ANNkd_ptr hi = rbd_tree( // build right subtree + pa, pidx + n_lo, n-n_lo,// ...from pidx[n_lo..n-1] + dim, bsp, bnd_box, splitter, shrink); + bnd_box.lo[cd] = lv; // restore bounds + // create the splitting node + return new ANNkd_split(cd, cv, lv, hv, lo, hi); + } + else { // shrink selected + int n_in; // number of points in box + int n_bnds; // number of bounding sides + + annBoxSplit( // split points around inner box + pa, // points to split + pidx, // point indices + n, // number of points + dim, // dimension + inner_box, // inner box + n_in); // number of points inside (returned) + + ANNkd_ptr in = rbd_tree( // build inner subtree pidx[0..n_in-1] + pa, pidx, n_in, dim, bsp, inner_box, splitter, shrink); + ANNkd_ptr out = rbd_tree( // build outer subtree pidx[n_in..n] + pa, pidx+n_in, n - n_in, dim, bsp, bnd_box, splitter, shrink); + + ANNorthHSArray bnds = NULL; // bounds (alloc in Box2Bnds and + // ...freed in bd_shrink destroyer) + + annBox2Bnds( // convert inner box to bounds + inner_box, // inner box + bnd_box, // enclosing box + dim, // dimension + n_bnds, // number of bounds (returned) + bnds); // bounds array (modified) + + // return shrinking node + return new ANNbd_shrink(n_bnds, bnds, in, out); + } +} diff --git a/kNN/bd_tree.h b/kNN/bd_tree.h new file mode 100755 index 000000000..e922b972e --- /dev/null +++ b/kNN/bd_tree.h @@ -0,0 +1,100 @@ +//---------------------------------------------------------------------- +// File: bd_tree.h +// Programmer: David Mount +// Description: Declarations for standard bd-tree routines +// Last modified: 01/04/05 (Version 1.0) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 +// Changed IN, OUT to ANN_IN, ANN_OUT +//---------------------------------------------------------------------- + +#ifndef ANN_bd_tree_H +#define ANN_bd_tree_H + +#include // all ANN includes +#include "kd_tree.h" // kd-tree includes + +//---------------------------------------------------------------------- +// bd-tree shrinking node. +// The main addition in the bd-tree is the shrinking node, which +// is declared here. +// +// Shrinking nodes are defined by list of orthogonal halfspaces. +// These halfspaces define a (possibly unbounded) orthogonal +// rectangle. There are two children, in and out. Points that +// lie within this rectangle are stored in the in-child, and the +// other points are stored in the out-child. +// +// We use a list of orthogonal halfspaces rather than an +// orthogonal rectangle object because typically the number of +// sides of the shrinking box will be much smaller than the +// worst case bound of 2*dim. +// +// BEWARE: Note that constructor just copies the pointer to the +// bounding array, but the destructor deallocates it. This is +// rather poor practice, but happens to be convenient. The list +// is allocated in the bd-tree building procedure rbd_tree() just +// prior to construction, and is used for no other purposes. +// +// WARNING: In the near neighbor searching code it is assumed that +// the list of bounding halfspaces is irredundant, meaning that there +// are no two distinct halfspaces in the list with the same outward +// pointing normals. +//---------------------------------------------------------------------- + +class ANNbd_shrink : public ANNkd_node // splitting node of a kd-tree +{ + int n_bnds; // number of bounding halfspaces + ANNorthHSArray bnds; // list of bounding halfspaces + ANNkd_ptr child[2]; // in and out children +public: + ANNbd_shrink( // constructor + int nb, // number of bounding halfspaces + ANNorthHSArray bds, // list of bounding halfspaces + ANNkd_ptr ic=NULL, ANNkd_ptr oc=NULL) // children + { + n_bnds = nb; // cutting dimension + bnds = bds; // assign bounds + child[ANN_IN] = ic; // set children + child[ANN_OUT] = oc; + } + + ~ANNbd_shrink() // destructor + { + if (child[ANN_IN]!= NULL && child[ANN_IN]!= KD_TRIVIAL) + delete child[ANN_IN]; + if (child[ANN_OUT]!= NULL&& child[ANN_OUT]!= KD_TRIVIAL) + delete child[ANN_OUT]; + if (bnds != NULL) + delete [] bnds; // delete bounds + } + + virtual void getStats( // get tree statistics + int dim, // dimension of space + ANNkdStats &st, // statistics + ANNorthRect &bnd_box); // bounding box + virtual void print(int level, ostream &out);// print node + virtual void dump(ostream &out); // dump node + + virtual void ann_search(ANNdist); // standard search + virtual void ann_pri_search(ANNdist); // priority search + virtual void ann_FR_search(ANNdist); // fixed-radius search +}; + +#endif diff --git a/kNN/brute.cpp b/kNN/brute.cpp new file mode 100755 index 000000000..f930adfde --- /dev/null +++ b/kNN/brute.cpp @@ -0,0 +1,109 @@ +//---------------------------------------------------------------------- +// File: brute.cpp +// Programmer: Sunil Arya and David Mount +// Description: Brute-force nearest neighbors +// Last modified: 05/03/05 (Version 1.1) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.1 05/03/05 +// Added fixed-radius kNN search +//---------------------------------------------------------------------- + +#include // all ANN includes +#include "pr_queue_k.h" // k element priority queue + +//---------------------------------------------------------------------- +// Brute-force search simply stores a pointer to the list of +// data points and searches linearly for the nearest neighbor. +// The k nearest neighbors are stored in a k-element priority +// queue (which is implemented in a pretty dumb way as well). +// +// If ANN_ALLOW_SELF_MATCH is ANNfalse then data points at distance +// zero are not considered. +// +// Note that the error bound eps is passed in, but it is ignored. +// These routines compute exact nearest neighbors (which is needed +// for validation purposes in ann_test.cpp). +//---------------------------------------------------------------------- + +ANNbruteForce::ANNbruteForce( // constructor from point array + ANNpointArray pa, // point array + int n, // number of points + int dd) // dimension +{ + dim = dd; n_pts = n; pts = pa; +} + +ANNbruteForce::~ANNbruteForce() { } // destructor (empty) + +void ANNbruteForce::annkSearch( // approx k near neighbor search + ANNpoint q, // query point + int k, // number of near neighbors to return + ANNidxArray nn_idx, // nearest neighbor indices (returned) + ANNdistArray dd, // dist to near neighbors (returned) + double eps) // error bound (ignored) +{ + ANNmin_k mk(k); // construct a k-limited priority queue + int i; + + if (k > n_pts) { // too many near neighbors? + annError("Requesting more near neighbors than data points", ANNabort); + } + // run every point through queue + for (i = 0; i < n_pts; i++) { + // compute distance to point + ANNdist sqDist = annDist(dim, pts[i], q); + if (ANN_ALLOW_SELF_MATCH || sqDist != 0) + mk.insert(sqDist, i); + } + for (i = 0; i < k; i++) { // extract the k closest points + dd[i] = mk.ith_smallest_key(i); + nn_idx[i] = mk.ith_smallest_info(i); + } +} + +int ANNbruteForce::annkFRSearch( // approx fixed-radius kNN search + ANNpoint q, // query point + ANNdist sqRad, // squared radius + int k, // number of near neighbors to return + ANNidxArray nn_idx, // nearest neighbor array (returned) + ANNdistArray dd, // dist to near neighbors (returned) + double eps) // error bound +{ + ANNmin_k mk(k); // construct a k-limited priority queue + int i; + int pts_in_range = 0; // number of points in query range + // run every point through queue + for (i = 0; i < n_pts; i++) { + // compute distance to point + ANNdist sqDist = annDist(dim, pts[i], q); + if (sqDist <= sqRad && // within radius bound + (ANN_ALLOW_SELF_MATCH || sqDist != 0)) { // ...and no self match + mk.insert(sqDist, i); + pts_in_range++; + } + } + for (i = 0; i < k; i++) { // extract the k closest points + if (dd != NULL) + dd[i] = mk.ith_smallest_key(i); + if (nn_idx != NULL) + nn_idx[i] = mk.ith_smallest_info(i); + } + + return pts_in_range; +} diff --git a/kNN/kNN.cpp b/kNN/kNN.cpp deleted file mode 100644 index 33b2a7d7b..000000000 --- a/kNN/kNN.cpp +++ /dev/null @@ -1 +0,0 @@ -// This file is empty. \ No newline at end of file diff --git a/kNN/kd_dump.cpp b/kNN/kd_dump.cpp new file mode 100755 index 000000000..82cf55920 --- /dev/null +++ b/kNN/kd_dump.cpp @@ -0,0 +1,444 @@ +//---------------------------------------------------------------------- +// File: kd_dump.cc +// Programmer: David Mount +// Description: Dump and Load for kd- and bd-trees +// Last modified: 01/04/05 (Version 1.0) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 +// Moved dump out of kd_tree.cc into this file. +// Added kd-tree load constructor. +//---------------------------------------------------------------------- +// This file contains routines for dumping kd-trees and bd-trees and +// reloading them. (It is an abuse of policy to include both kd- and +// bd-tree routines in the same file, sorry. There should be no problem +// in deleting the bd- versions of the routines if they are not +// desired.) +//---------------------------------------------------------------------- + +#include "kd_tree.h" // kd-tree declarations +#include "bd_tree.h" // bd-tree declarations + +using namespace std; // make std:: available + +//---------------------------------------------------------------------- +// Constants +//---------------------------------------------------------------------- + +const int STRING_LEN = 500; // maximum string length +const double EPSILON = 1E-5; // small number for float comparison + +enum ANNtreeType {KD_TREE, BD_TREE}; // tree types (used in loading) + +//---------------------------------------------------------------------- +// Procedure declarations +//---------------------------------------------------------------------- + +static ANNkd_ptr annReadDump( // read dump file + istream &in, // input stream + ANNtreeType tree_type, // type of tree expected + ANNpointArray &the_pts, // new points (if applic) + ANNidxArray &the_pidx, // point indices (returned) + int &the_dim, // dimension (returned) + int &the_n_pts, // number of points (returned) + int &the_bkt_size, // bucket size (returned) + ANNpoint &the_bnd_box_lo, // low bounding point + ANNpoint &the_bnd_box_hi); // high bounding point + +static ANNkd_ptr annReadTree( // read tree-part of dump file + istream &in, // input stream + ANNtreeType tree_type, // type of tree expected + ANNidxArray the_pidx, // point indices (modified) + int &next_idx); // next index (modified) + +//---------------------------------------------------------------------- +// ANN kd- and bd-tree Dump Format +// The dump file begins with a header containing the version of +// ANN, an optional section containing the points, followed by +// a description of the tree. The tree is printed in preorder. +// +// Format: +// #ANN [END_OF_LINE] +// points (point coordinates: this is optional) +// 0 ... (point indices and coordinates) +// 1 ... +// ... +// tree +// ... (lower end of bounding box) +// ... (upper end of bounding box) +// If the tree is null, then a single line "null" is +// output. Otherwise the nodes of the tree are printed +// one per line in preorder. Leaves and splitting nodes +// have the following formats: +// Leaf node: +// leaf ... +// Splitting nodes: +// split +// +// For bd-trees: +// +// Shrinking nodes: +// shrink +// +// +// ... (repeated n_bnds times) +//---------------------------------------------------------------------- + +void ANNkd_tree::Dump( // dump entire tree + ANNbool with_pts, // print points as well? + ostream &out) // output stream +{ + out << "#ANN " << ANNversion << "\n"; + out.precision(ANNcoordPrec); // use full precision in dumping + if (with_pts) { // print point coordinates + out << "points " << dim << " " << n_pts << "\n"; + for (int i = 0; i < n_pts; i++) { + out << i << " "; + annPrintPt(pts[i], dim, out); + out << "\n"; + } + } + out << "tree " // print tree elements + << dim << " " + << n_pts << " " + << bkt_size << "\n"; + + annPrintPt(bnd_box_lo, dim, out); // print lower bound + out << "\n"; + annPrintPt(bnd_box_hi, dim, out); // print upper bound + out << "\n"; + + if (root == NULL) // empty tree? + out << "null\n"; + else { + root->dump(out); // invoke printing at root + } + out.precision(0); // restore default precision +} + +void ANNkd_split::dump( // dump a splitting node + ostream &out) // output stream +{ + out << "split " << cut_dim << " " << cut_val << " "; + out << cd_bnds[ANN_LO] << " " << cd_bnds[ANN_HI] << "\n"; + + child[ANN_LO]->dump(out); // print low child + child[ANN_HI]->dump(out); // print high child +} + +void ANNkd_leaf::dump( // dump a leaf node + ostream &out) // output stream +{ + if (this == KD_TRIVIAL) { // canonical trivial leaf node + out << "leaf 0\n"; // leaf no points + } + else{ + out << "leaf " << n_pts; + for (int j = 0; j < n_pts; j++) { + out << " " << bkt[j]; + } + out << "\n"; + } +} + +void ANNbd_shrink::dump( // dump a shrinking node + ostream &out) // output stream +{ + out << "shrink " << n_bnds << "\n"; + for (int j = 0; j < n_bnds; j++) { + out << bnds[j].cd << " " << bnds[j].cv << " " << bnds[j].sd << "\n"; + } + child[ANN_IN]->dump(out); // print in-child + child[ANN_OUT]->dump(out); // print out-child +} + +//---------------------------------------------------------------------- +// Load kd-tree from dump file +// This rebuilds a kd-tree which was dumped to a file. The dump +// file contains all the basic tree information according to a +// preorder traversal. We assume that the dump file also contains +// point data. (This is to guarantee the consistency of the tree.) +// If not, then an error is generated. +// +// Indirectly, this procedure allocates space for points, point +// indices, all nodes in the tree, and the bounding box for the +// tree. When the tree is destroyed, all but the points are +// deallocated. +// +// This routine calls annReadDump to do all the work. +//---------------------------------------------------------------------- + +ANNkd_tree::ANNkd_tree( // build from dump file + istream &in) // input stream for dump file +{ + int the_dim; // local dimension + int the_n_pts; // local number of points + int the_bkt_size; // local number of points + ANNpoint the_bnd_box_lo; // low bounding point + ANNpoint the_bnd_box_hi; // high bounding point + ANNpointArray the_pts; // point storage + ANNidxArray the_pidx; // point index storage + ANNkd_ptr the_root; // root of the tree + + the_root = annReadDump( // read the dump file + in, // input stream + KD_TREE, // expecting a kd-tree + the_pts, // point array (returned) + the_pidx, // point indices (returned) + the_dim, the_n_pts, the_bkt_size, // basic tree info (returned) + the_bnd_box_lo, the_bnd_box_hi); // bounding box info (returned) + + // create a skeletal tree + SkeletonTree(the_n_pts, the_dim, the_bkt_size, the_pts, the_pidx); + + bnd_box_lo = the_bnd_box_lo; + bnd_box_hi = the_bnd_box_hi; + + root = the_root; // set the root +} + +ANNbd_tree::ANNbd_tree( // build bd-tree from dump file + istream &in) : ANNkd_tree() // input stream for dump file +{ + int the_dim; // local dimension + int the_n_pts; // local number of points + int the_bkt_size; // local number of points + ANNpoint the_bnd_box_lo; // low bounding point + ANNpoint the_bnd_box_hi; // high bounding point + ANNpointArray the_pts; // point storage + ANNidxArray the_pidx; // point index storage + ANNkd_ptr the_root; // root of the tree + + the_root = annReadDump( // read the dump file + in, // input stream + BD_TREE, // expecting a bd-tree + the_pts, // point array (returned) + the_pidx, // point indices (returned) + the_dim, the_n_pts, the_bkt_size, // basic tree info (returned) + the_bnd_box_lo, the_bnd_box_hi); // bounding box info (returned) + + // create a skeletal tree + SkeletonTree(the_n_pts, the_dim, the_bkt_size, the_pts, the_pidx); + bnd_box_lo = the_bnd_box_lo; + bnd_box_hi = the_bnd_box_hi; + + root = the_root; // set the root +} + +//---------------------------------------------------------------------- +// annReadDump - read a dump file +// +// This procedure reads a dump file, constructs a kd-tree +// and returns all the essential information needed to actually +// construct the tree. Because this procedure is used for +// constructing both kd-trees and bd-trees, the second argument +// is used to indicate which type of tree we are expecting. +//---------------------------------------------------------------------- + +static ANNkd_ptr annReadDump( + istream &in, // input stream + ANNtreeType tree_type, // type of tree expected + ANNpointArray &the_pts, // new points (returned) + ANNidxArray &the_pidx, // point indices (returned) + int &the_dim, // dimension (returned) + int &the_n_pts, // number of points (returned) + int &the_bkt_size, // bucket size (returned) + ANNpoint &the_bnd_box_lo, // low bounding point (ret'd) + ANNpoint &the_bnd_box_hi) // high bounding point (ret'd) +{ + int j; + char str[STRING_LEN]; // storage for string + char version[STRING_LEN]; // ANN version number + ANNkd_ptr the_root = NULL; + + //------------------------------------------------------------------ + // Input file header + //------------------------------------------------------------------ + in >> str; // input header + if (strcmp(str, "#ANN") != 0) { // incorrect header + annError("Incorrect header for dump file", ANNabort); + } + in.getline(version, STRING_LEN); // get version (ignore) + + //------------------------------------------------------------------ + // Input the points + // An array the_pts is allocated and points are read from + // the dump file. + //------------------------------------------------------------------ + in >> str; // get major heading + if (strcmp(str, "points") == 0) { // points section + in >> the_dim; // input dimension + in >> the_n_pts; // number of points + // allocate point storage + the_pts = annAllocPts(the_n_pts, the_dim); + for (int i = 0; i < the_n_pts; i++) { // input point coordinates + ANNidx idx; // point index + in >> idx; // input point index + if (idx < 0 || idx >= the_n_pts) { + annError("Point index is out of range", ANNabort); + } + for (j = 0; j < the_dim; j++) { + in >> the_pts[idx][j]; // read point coordinates + } + } + in >> str; // get next major heading + } + else { // no points were input + annError("Points must be supplied in the dump file", ANNabort); + } + + //------------------------------------------------------------------ + // Input the tree + // After the basic header information, we invoke annReadTree + // to do all the heavy work. We create our own array of + // point indices (so we can pass them to annReadTree()) + // but we do not deallocate them. They will be deallocated + // when the tree is destroyed. + //------------------------------------------------------------------ + if (strcmp(str, "tree") == 0) { // tree section + in >> the_dim; // read dimension + in >> the_n_pts; // number of points + in >> the_bkt_size; // bucket size + the_bnd_box_lo = annAllocPt(the_dim); // allocate bounding box pts + the_bnd_box_hi = annAllocPt(the_dim); + + for (j = 0; j < the_dim; j++) { // read bounding box low + in >> the_bnd_box_lo[j]; + } + for (j = 0; j < the_dim; j++) { // read bounding box low + in >> the_bnd_box_hi[j]; + } + the_pidx = new ANNidx[the_n_pts]; // allocate point index array + int next_idx = 0; // number of indices filled + // read the tree and indices + the_root = annReadTree(in, tree_type, the_pidx, next_idx); + if (next_idx != the_n_pts) { // didn't see all the points? + annError("Didn't see as many points as expected", ANNwarn); + } + } + else { + annError("Illegal dump format. Expecting section heading", ANNabort); + } + return the_root; +} + +//---------------------------------------------------------------------- +// annReadTree - input tree and return pointer +// +// annReadTree reads in a node of the tree, makes any recursive +// calls as needed to input the children of this node (if internal). +// It returns a pointer to the node that was created. An array +// of point indices is given along with a pointer to the next +// available location in the array. As leaves are read, their +// point indices are stored here, and the point buckets point +// to the first entry in the array. +// +// Recall that these are the formats. The tree is given in +// preorder. +// +// Leaf node: +// leaf ... +// Splitting nodes: +// split +// +// For bd-trees: +// +// Shrinking nodes: +// shrink +// +// +// ... (repeated n_bnds times) +//---------------------------------------------------------------------- + +static ANNkd_ptr annReadTree( + istream &in, // input stream + ANNtreeType tree_type, // type of tree expected + ANNidxArray the_pidx, // point indices (modified) + int &next_idx) // next index (modified) +{ + char tag[STRING_LEN]; // tag (leaf, split, shrink) + int n_pts; // number of points in leaf + int cd; // cut dimension + ANNcoord cv; // cut value + ANNcoord lb; // low bound + ANNcoord hb; // high bound + int n_bnds; // number of bounding sides + int sd; // which side + + in >> tag; // input node tag + + if (strcmp(tag, "null") == 0) { // null tree + return NULL; + } + //------------------------------------------------------------------ + // Read a leaf + //------------------------------------------------------------------ + if (strcmp(tag, "leaf") == 0) { // leaf node + + in >> n_pts; // input number of points + int old_idx = next_idx; // save next_idx + if (n_pts == 0) { // trivial leaf + return KD_TRIVIAL; + } + else { + for (int i = 0; i < n_pts; i++) { // input point indices + in >> the_pidx[next_idx++]; // store in array of indices + } + } + return new ANNkd_leaf(n_pts, &the_pidx[old_idx]); + } + //------------------------------------------------------------------ + // Read a splitting node + //------------------------------------------------------------------ + else if (strcmp(tag, "split") == 0) { // splitting node + + in >> cd >> cv >> lb >> hb; + + // read low and high subtrees + ANNkd_ptr lc = annReadTree(in, tree_type, the_pidx, next_idx); + ANNkd_ptr hc = annReadTree(in, tree_type, the_pidx, next_idx); + // create new node and return + return new ANNkd_split(cd, cv, lb, hb, lc, hc); + } + //------------------------------------------------------------------ + // Read a shrinking node (bd-tree only) + //------------------------------------------------------------------ + else if (strcmp(tag, "shrink") == 0) { // shrinking node + if (tree_type != BD_TREE) { + annError("Shrinking node not allowed in kd-tree", ANNabort); + } + + in >> n_bnds; // number of bounding sides + // allocate bounds array + ANNorthHSArray bds = new ANNorthHalfSpace[n_bnds]; + for (int i = 0; i < n_bnds; i++) { + in >> cd >> cv >> sd; // input bounding halfspace + // copy to array + bds[i] = ANNorthHalfSpace(cd, cv, sd); + } + // read inner and outer subtrees + ANNkd_ptr ic = annReadTree(in, tree_type, the_pidx, next_idx); + ANNkd_ptr oc = annReadTree(in, tree_type, the_pidx, next_idx); + // create new node and return + return new ANNbd_shrink(n_bnds, bds, ic, oc); + } + else { + annError("Illegal node type in dump file", ANNabort); + exit(0); // to keep the compiler happy + } +} diff --git a/kNN/kd_fix_rad_search.cpp b/kNN/kd_fix_rad_search.cpp new file mode 100755 index 000000000..3b554690c --- /dev/null +++ b/kNN/kd_fix_rad_search.cpp @@ -0,0 +1,183 @@ +//---------------------------------------------------------------------- +// File: kd_fix_rad_search.cpp +// Programmer: Sunil Arya and David Mount +// Description: Standard kd-tree fixed-radius kNN search +// Last modified: 05/03/05 (Version 1.1) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 1.1 05/03/05 +// Initial release +//---------------------------------------------------------------------- + +#include "kd_fix_rad_search.h" // kd fixed-radius search decls + +//---------------------------------------------------------------------- +// Approximate fixed-radius k nearest neighbor search +// The squared radius is provided, and this procedure finds the +// k nearest neighbors within the radius, and returns the total +// number of points lying within the radius. +// +// The method used for searching the kd-tree is a variation of the +// nearest neighbor search used in kd_search.cpp, except that the +// radius of the search ball is known. We refer the reader to that +// file for the explanation of the recursive search procedure. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// To keep argument lists short, a number of global variables +// are maintained which are common to all the recursive calls. +// These are given below. +//---------------------------------------------------------------------- + +int ANNkdFRDim; // dimension of space +ANNpoint ANNkdFRQ; // query point +ANNdist ANNkdFRSqRad; // squared radius search bound +double ANNkdFRMaxErr; // max tolerable squared error +ANNpointArray ANNkdFRPts; // the points +ANNmin_k* ANNkdFRPointMK; // set of k closest points +int ANNkdFRPtsVisited; // total points visited +int ANNkdFRPtsInRange; // number of points in the range + +//---------------------------------------------------------------------- +// annkFRSearch - fixed radius search for k nearest neighbors +//---------------------------------------------------------------------- + +int ANNkd_tree::annkFRSearch( + ANNpoint q, // the query point + ANNdist sqRad, // squared radius search bound + int k, // number of near neighbors to return + ANNidxArray nn_idx, // nearest neighbor indices (returned) + ANNdistArray dd, // the approximate nearest neighbor + double eps) // the error bound +{ + ANNkdFRDim = dim; // copy arguments to static equivs + ANNkdFRQ = q; + ANNkdFRSqRad = sqRad; + ANNkdFRPts = pts; + ANNkdFRPtsVisited = 0; // initialize count of points visited + ANNkdFRPtsInRange = 0; // ...and points in the range + + ANNkdFRMaxErr = ANN_POW(1.0 + eps); + ANN_FLOP(2) // increment floating op count + + ANNkdFRPointMK = new ANNmin_k(k); // create set for closest k points + // search starting at the root + root->ann_FR_search(annBoxDistance(q, bnd_box_lo, bnd_box_hi, dim)); + + for (int i = 0; i < k; i++) { // extract the k-th closest points + if (dd != NULL) + dd[i] = ANNkdFRPointMK->ith_smallest_key(i); + if (nn_idx != NULL) + nn_idx[i] = ANNkdFRPointMK->ith_smallest_info(i); + } + + delete ANNkdFRPointMK; // deallocate closest point set + return ANNkdFRPtsInRange; // return final point count +} + +//---------------------------------------------------------------------- +// kd_split::ann_FR_search - search a splitting node +// Note: This routine is similar in structure to the standard kNN +// search. It visits the subtree that is closer to the query point +// first. For fixed-radius search, there is no benefit in visiting +// one subtree before the other, but we maintain the same basic +// code structure for the sake of uniformity. +//---------------------------------------------------------------------- + +void ANNkd_split::ann_FR_search(ANNdist box_dist) +{ + // check dist calc term condition + if (ANNmaxPtsVisited != 0 && ANNkdFRPtsVisited > ANNmaxPtsVisited) return; + + // distance to cutting plane + ANNcoord cut_diff = ANNkdFRQ[cut_dim] - cut_val; + + if (cut_diff < 0) { // left of cutting plane + child[ANN_LO]->ann_FR_search(box_dist);// visit closer child first + + ANNcoord box_diff = cd_bnds[ANN_LO] - ANNkdFRQ[cut_dim]; + if (box_diff < 0) // within bounds - ignore + box_diff = 0; + // distance to further box + box_dist = (ANNdist) ANN_SUM(box_dist, + ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); + + // visit further child if in range + if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad) + child[ANN_HI]->ann_FR_search(box_dist); + + } + else { // right of cutting plane + child[ANN_HI]->ann_FR_search(box_dist);// visit closer child first + + ANNcoord box_diff = ANNkdFRQ[cut_dim] - cd_bnds[ANN_HI]; + if (box_diff < 0) // within bounds - ignore + box_diff = 0; + // distance to further box + box_dist = (ANNdist) ANN_SUM(box_dist, + ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); + + // visit further child if close enough + if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad) + child[ANN_LO]->ann_FR_search(box_dist); + + } + ANN_FLOP(13) // increment floating ops + ANN_SPL(1) // one more splitting node visited +} + +//---------------------------------------------------------------------- +// kd_leaf::ann_FR_search - search points in a leaf node +// Note: The unreadability of this code is the result of +// some fine tuning to replace indexing by pointer operations. +//---------------------------------------------------------------------- + +void ANNkd_leaf::ann_FR_search(ANNdist box_dist) +{ + register ANNdist dist; // distance to data point + register ANNcoord* pp; // data coordinate pointer + register ANNcoord* qq; // query coordinate pointer + register ANNcoord t; + register int d; + + for (int i = 0; i < n_pts; i++) { // check points in bucket + + pp = ANNkdFRPts[bkt[i]]; // first coord of next data point + qq = ANNkdFRQ; // first coord of query point + dist = 0; + + for(d = 0; d < ANNkdFRDim; d++) { + ANN_COORD(1) // one more coordinate hit + ANN_FLOP(5) // increment floating ops + + t = *(qq++) - *(pp++); // compute length and adv coordinate + // exceeds dist to k-th smallest? + if( (dist = ANN_SUM(dist, ANN_POW(t))) > ANNkdFRSqRad) { + break; + } + } + + if (d >= ANNkdFRDim && // among the k best? + (ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem + // add it to the list + ANNkdFRPointMK->insert(dist, bkt[i]); + ANNkdFRPtsInRange++; // increment point count + } + } + ANN_LEAF(1) // one more leaf node visited + ANN_PTS(n_pts) // increment points visited + ANNkdFRPtsVisited += n_pts; // increment number of points visited +} diff --git a/kNN/kd_fix_rad_search.h b/kNN/kd_fix_rad_search.h new file mode 100755 index 000000000..756732780 --- /dev/null +++ b/kNN/kd_fix_rad_search.h @@ -0,0 +1,44 @@ +//---------------------------------------------------------------------- +// File: kd_fix_rad_search.h +// Programmer: Sunil Arya and David Mount +// Description: Standard kd-tree fixed-radius kNN search +// Last modified: 05/03/05 (Version 1.1) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 1.1 05/03/05 +// Initial release +//---------------------------------------------------------------------- + +#ifndef ANN_kd_fix_rad_search_H +#define ANN_kd_fix_rad_search_H + +#include "kd_tree.h" // kd-tree declarations +#include "kd_util.h" // kd-tree utilities +#include "pr_queue_k.h" // k-element priority queue + +#include // performance evaluation + +//---------------------------------------------------------------------- +// Global variables +// These are active for the life of each call to +// annRangeSearch(). They are set to save the number of +// variables that need to be passed among the various search +// procedures. +//---------------------------------------------------------------------- + +extern ANNpoint ANNkdFRQ; // query point (static copy) + +#endif diff --git a/kNN/kd_pr_search.cpp b/kNN/kd_pr_search.cpp old mode 100644 new mode 100755 index 604bd3ee4..0d16060c1 --- a/kNN/kd_pr_search.cpp +++ b/kNN/kd_pr_search.cpp @@ -1,226 +1,219 @@ //---------------------------------------------------------------------- -// File: kd_pr_search.cc -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Priority search for kd-trees +// File: kd_pr_search.cpp +// Programmer: Sunil Arya and David Mount +// Description: Priority search for kd-trees +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release //---------------------------------------------------------------------- -#include "ANN.h" -#include "ANNx.h" // all ANN includes -#include "ANNperf.h" // performance evaluation -#include "kd_pr_search.h" // kd priority search declarations +#include "kd_pr_search.h" // kd priority search declarations //---------------------------------------------------------------------- -// Approximate nearest neighbor searching by priority search. -// The kd-tree is searched for an approximate nearest neighbor. -// The point is returned through one of the arguments, and the -// distance returned is the SQUARED distance to this point. +// Approximate nearest neighbor searching by priority search. +// The kd-tree is searched for an approximate nearest neighbor. +// The point is returned through one of the arguments, and the +// distance returned is the SQUARED distance to this point. // -// The method used for searching the kd-tree is called priority -// search. (It is described in Arya and Mount, ``Algorithms for -// fast vector quantization,'' Proc. of DCC '93: Data Compression -// Conference}, eds. J. A. Storer and M. Cohn, IEEE Press, 1993, -// 381--390.) +// The method used for searching the kd-tree is called priority +// search. (It is described in Arya and Mount, ``Algorithms for +// fast vector quantization,'' Proc. of DCC '93: Data Compression +// Conference}, eds. J. A. Storer and M. Cohn, IEEE Press, 1993, +// 381--390.) // -// The cell of the kd-tree containing the query point is located, -// and cells are visited in increasing order of distance from the -// query point. This is done by placing each subtree which has -// NOT been visited in a priority queue, according to the closest -// distance of the corresponding enclosing rectangle from the -// query point. The search stops when the distance to the nearest -// remaining rectangle exceeds the distance to the nearest point -// seen by a factor of more than 1/(1+eps). (Implying that any -// point found subsequently in the search cannot be closer by more -// than this factor.) +// The cell of the kd-tree containing the query point is located, +// and cells are visited in increasing order of distance from the +// query point. This is done by placing each subtree which has +// NOT been visited in a priority queue, according to the closest +// distance of the corresponding enclosing rectangle from the +// query point. The search stops when the distance to the nearest +// remaining rectangle exceeds the distance to the nearest point +// seen by a factor of more than 1/(1+eps). (Implying that any +// point found subsequently in the search cannot be closer by more +// than this factor.) // -// The main entry point is annkPriSearch() which sets things up and -// then call the recursive routine ann_pri_search(). This is a -// recursive routine which performs the processing for one node in -// the kd-tree. There are two versions of this virtual procedure, -// one for splitting nodes and one for leaves. When a splitting node -// is visited, we determine which child to continue the search on -// (the closer one), and insert the other child into the priority -// queue. When a leaf is visited, we compute the distances to the -// points in the buckets, and update information on the closest -// points. +// The main entry point is annkPriSearch() which sets things up and +// then call the recursive routine ann_pri_search(). This is a +// recursive routine which performs the processing for one node in +// the kd-tree. There are two versions of this virtual procedure, +// one for splitting nodes and one for leaves. When a splitting node +// is visited, we determine which child to continue the search on +// (the closer one), and insert the other child into the priority +// queue. When a leaf is visited, we compute the distances to the +// points in the buckets, and update information on the closest +// points. // -// Some trickery is used to incrementally update the distance from -// a kd-tree rectangle to the query point. This comes about from -// the fact that which each successive split, only one component -// (along the dimension that is split) of the squared distance to -// the child rectangle is different from the squared distance to -// the parent rectangle. +// Some trickery is used to incrementally update the distance from +// a kd-tree rectangle to the query point. This comes about from +// the fact that which each successive split, only one component +// (along the dimension that is split) of the squared distance to +// the child rectangle is different from the squared distance to +// the parent rectangle. //---------------------------------------------------------------------- //---------------------------------------------------------------------- -// To keep argument lists short, a number of global variables -// are maintained which are common to all the recursive calls. -// These are given below. +// To keep argument lists short, a number of global variables +// are maintained which are common to all the recursive calls. +// These are given below. //---------------------------------------------------------------------- -double ANNprEps; // the error bound -int ANNprDim; // dimension of space -ANNpoint ANNprQ; // query point -double ANNprMaxErr; // max tolerable squared error -ANNpointArray ANNprPts; // the points -ANNpr_queue *ANNprBoxPQ; // priority queue for boxes -ANNmin_k *ANNprPointMK; // set of k closest points +double ANNprEps; // the error bound +int ANNprDim; // dimension of space +ANNpoint ANNprQ; // query point +double ANNprMaxErr; // max tolerable squared error +ANNpointArray ANNprPts; // the points +ANNpr_queue *ANNprBoxPQ; // priority queue for boxes +ANNmin_k *ANNprPointMK; // set of k closest points //---------------------------------------------------------------------- -// annkPriSearch - priority search for k nearest neighbors +// annkPriSearch - priority search for k nearest neighbors //---------------------------------------------------------------------- void ANNkd_tree::annkPriSearch( - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor indices (returned) - ANNdistArray dd, // dist to near neighbors (returned) - double eps) // error bound (ignored) + ANNpoint q, // query point + int k, // number of near neighbors to return + ANNidxArray nn_idx, // nearest neighbor indices (returned) + ANNdistArray dd, // dist to near neighbors (returned) + double eps) // error bound (ignored) { - // max tolerable squared error - ANNprMaxErr = ANN_POW(1.0 + eps); - FLOP(2) // increment floating ops - - ANNprDim = dim; // copy arguments to static equivs - ANNprQ = q; - ANNprPts = pts; - ANNptsVisited = 0; // initialize count of points visited - - ANNprPointMK = new ANNmin_k(k); // create set for closest k points - - // distance to root box - ANNdist box_dist = annBoxDistance(q, - bnd_box_lo, bnd_box_hi, dim); - - ANNprBoxPQ = new ANNpr_queue(n_pts);// create priority queue for boxes - ANNprBoxPQ->insert(box_dist, root); // insert root in priority queue - - while (ANNprBoxPQ->non_empty() && - (!ANNmaxPtsVisited || ANNptsVisited < ANNmaxPtsVisited)) - { - ANNkd_ptr np; // next box from prior queue - // extract closest box from queue - ANNprBoxPQ->extr_min(box_dist, (void *&) np); - FLOP(2) // increment floating ops - if (box_dist*ANNprMaxErr >= ANNprPointMK->max_key()) - break; - np->ann_pri_search(box_dist); // search this subtree. - } + // max tolerable squared error + ANNprMaxErr = ANN_POW(1.0 + eps); + ANN_FLOP(2) // increment floating ops - for (int i = 0; i < k; i++) - { // extract the k-th closest points - dd[i] = ANNprPointMK->ith_smallest_key(i); - nn_idx[i] = ANNprPointMK->ith_smallest_info(i); - } + ANNprDim = dim; // copy arguments to static equivs + ANNprQ = q; + ANNprPts = pts; + ANNptsVisited = 0; // initialize count of points visited + + ANNprPointMK = new ANNmin_k(k); // create set for closest k points + + // distance to root box + ANNdist box_dist = annBoxDistance(q, + bnd_box_lo, bnd_box_hi, dim); + + ANNprBoxPQ = new ANNpr_queue(n_pts);// create priority queue for boxes + ANNprBoxPQ->insert(box_dist, root); // insert root in priority queue + + while (ANNprBoxPQ->non_empty() && + (!(ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited))) { + ANNkd_ptr np; // next box from prior queue + + // extract closest box from queue + ANNprBoxPQ->extr_min(box_dist, (void *&) np); + + ANN_FLOP(2) // increment floating ops + if (box_dist*ANNprMaxErr >= ANNprPointMK->max_key()) + break; + + np->ann_pri_search(box_dist); // search this subtree. + } - delete ANNprPointMK; // deallocate closest point set - ANNprPointMK = NULL; - delete ANNprBoxPQ; // deallocate priority queue - ANNprBoxPQ = NULL; + for (int i = 0; i < k; i++) { // extract the k-th closest points + dd[i] = ANNprPointMK->ith_smallest_key(i); + nn_idx[i] = ANNprPointMK->ith_smallest_info(i); + } + + delete ANNprPointMK; // deallocate closest point set + delete ANNprBoxPQ; // deallocate priority queue } //---------------------------------------------------------------------- -// kd_split::ann_pri_search - search a splitting node +// kd_split::ann_pri_search - search a splitting node //---------------------------------------------------------------------- void ANNkd_split::ann_pri_search(ANNdist box_dist) { - ANNdist new_dist; // distance to child visited later - // distance to cutting plane - ANNcoord cut_diff = ANNprQ[cut_dim] - cut_val; - - if (cut_diff < 0) { // left of cutting plane - ANNcoord box_diff = cd_bnds[LO] - ANNprQ[cut_dim]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box - new_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - - if (child[HI] != KD_TRIVIAL) // enqueue if not trivial - ANNprBoxPQ->insert(new_dist, child[HI]); - // continue with closer child - child[LO]->ann_pri_search(box_dist); - } - else { // right of cutting plane - ANNcoord box_diff = ANNprQ[cut_dim] - cd_bnds[HI]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box - new_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - - if (child[LO] != KD_TRIVIAL) // enqueue if not trivial - ANNprBoxPQ->insert(new_dist, child[LO]); - // continue with closer child - child[HI]->ann_pri_search(box_dist); - } - SPL(1) // one more splitting node visited - FLOP(8) // increment floating ops + ANNdist new_dist; // distance to child visited later + // distance to cutting plane + ANNcoord cut_diff = ANNprQ[cut_dim] - cut_val; + + if (cut_diff < 0) { // left of cutting plane + ANNcoord box_diff = cd_bnds[ANN_LO] - ANNprQ[cut_dim]; + if (box_diff < 0) // within bounds - ignore + box_diff = 0; + // distance to further box + new_dist = (ANNdist) ANN_SUM(box_dist, + ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); + + if (child[ANN_HI] != KD_TRIVIAL)// enqueue if not trivial + ANNprBoxPQ->insert(new_dist, child[ANN_HI]); + // continue with closer child + child[ANN_LO]->ann_pri_search(box_dist); + } + else { // right of cutting plane + ANNcoord box_diff = ANNprQ[cut_dim] - cd_bnds[ANN_HI]; + if (box_diff < 0) // within bounds - ignore + box_diff = 0; + // distance to further box + new_dist = (ANNdist) ANN_SUM(box_dist, + ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); + + if (child[ANN_LO] != KD_TRIVIAL)// enqueue if not trivial + ANNprBoxPQ->insert(new_dist, child[ANN_LO]); + // continue with closer child + child[ANN_HI]->ann_pri_search(box_dist); + } + ANN_SPL(1) // one more splitting node visited + ANN_FLOP(8) // increment floating ops } //---------------------------------------------------------------------- -// kd_leaf::ann_pri_search - search points in a leaf node +// kd_leaf::ann_pri_search - search points in a leaf node // -// This is virtually identical to the ann_search for standard search. +// This is virtually identical to the ann_search for standard search. //---------------------------------------------------------------------- void ANNkd_leaf::ann_pri_search(ANNdist box_dist) { - register ANNdist dist; // distance to data point - register ANNcoord* pp; // data coordinate pointer - register ANNcoord* qq; // query coordinate pointer - register ANNdist min_dist; // distance to k-th closest point - register ANNcoord t; - register int d; - - min_dist = ANNprPointMK->max_key(); // k-th smallest distance so far - - for (int i = 0; i < n_pts; i++) - { // check points in bucket - - pp = ANNprPts[bkt[i]]; // first coord of next data point - qq = ANNprQ; // first coord of query point - dist = 0; - - for(d = 0; d < ANNprDim; d++) - { - COORD(1) // one more coordinate hit - FLOP(4) // increment floating ops - - t = *(qq++) - *(pp++); // compute length and adv coordinate - // exceeds dist to k-th smallest? - if( (dist = ANN_SUM(dist, ANN_POW(t))) > min_dist) - { - break; - } - } + register ANNdist dist; // distance to data point + register ANNcoord* pp; // data coordinate pointer + register ANNcoord* qq; // query coordinate pointer + register ANNdist min_dist; // distance to k-th closest point + register ANNcoord t; + register int d; + + min_dist = ANNprPointMK->max_key(); // k-th smallest distance so far + + for (int i = 0; i < n_pts; i++) { // check points in bucket + + pp = ANNprPts[bkt[i]]; // first coord of next data point + qq = ANNprQ; // first coord of query point + dist = 0; - if (d >= ANNprDim && // among the k best? - (ANN_ALLOW_SELF_MATCH || dist!=0)) - { // and no self-match problem - // add it to the list - ANNprPointMK->insert(dist, bkt[i]); - min_dist = ANNprPointMK->max_key(); + for(d = 0; d < ANNprDim; d++) { + ANN_COORD(1) // one more coordinate hit + ANN_FLOP(4) // increment floating ops + + t = *(qq++) - *(pp++); // compute length and adv coordinate + // exceeds dist to k-th smallest? + if( (dist = ANN_SUM(dist, ANN_POW(t))) > min_dist) { + break; } - } - LEAF(1) // one more leaf node visited - PTS(n_pts) // increment points visited - ANNptsVisited += n_pts; // increment number of points visited + } + + if (d >= ANNprDim && // among the k best? + (ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem + // add it to the list + ANNprPointMK->insert(dist, bkt[i]); + min_dist = ANNprPointMK->max_key(); + } + } + ANN_LEAF(1) // one more leaf node visited + ANN_PTS(n_pts) // increment points visited + ANNptsVisited += n_pts; // increment number of points visited } diff --git a/kNN/kd_pr_search.h b/kNN/kd_pr_search.h old mode 100644 new mode 100755 index 0974220f9..fa06c2f5b --- a/kNN/kd_pr_search.h +++ b/kNN/kd_pr_search.h @@ -1,46 +1,49 @@ //---------------------------------------------------------------------- -// File: kd_pr_search.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Priority kd-tree search +// File: kd_pr_search.h +// Programmer: Sunil Arya and David Mount +// Description: Priority kd-tree search +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release //---------------------------------------------------------------------- #ifndef ANN_kd_pr_search_H #define ANN_kd_pr_search_H -#include "kd_tree.h" // kd-tree declarations -#include "kd_util.h" // kd-tree utilities -#include "pr_queue.h" // priority queue declarations -#include "pr_queue_k.h" // k-element priority queue +#include "kd_tree.h" // kd-tree declarations +#include "kd_util.h" // kd-tree utilities +#include "pr_queue.h" // priority queue declarations +#include "pr_queue_k.h" // k-element priority queue + +#include "ANN/ANNperf.h" // performance evaluation //---------------------------------------------------------------------- -// Global variables -// Active for the life of each call to Appx_Near_Neigh() or -// Appx_k_Near_Neigh(). +// Global variables +// Active for the life of each call to Appx_Near_Neigh() or +// Appx_k_Near_Neigh(). //---------------------------------------------------------------------- -extern double ANNprEps; // the error bound -extern int ANNprDim; // dimension of space -extern ANNpoint ANNprQ; // query point -extern double ANNprMaxErr; // max tolerable squared error -extern ANNpointArray ANNprPts; // the points -extern ANNpr_queue *ANNprBoxPQ; // priority queue for boxes -extern ANNmin_k *ANNprPointMK; // set of k closest points +extern double ANNprEps; // the error bound +extern int ANNprDim; // dimension of space +extern ANNpoint ANNprQ; // query point +extern double ANNprMaxErr; // max tolerable squared error +extern ANNpointArray ANNprPts; // the points +extern ANNpr_queue *ANNprBoxPQ; // priority queue for boxes +extern ANNmin_k *ANNprPointMK; // set of k closest points #endif diff --git a/kNN/kd_search.cpp b/kNN/kd_search.cpp old mode 100644 new mode 100755 index 203b17f08..745e0e3c3 --- a/kNN/kd_search.cpp +++ b/kNN/kd_search.cpp @@ -1,270 +1,210 @@ //---------------------------------------------------------------------- -// File: kd_search.cc -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Standard kd-tree search +// File: kd_search.cpp +// Programmer: Sunil Arya and David Mount +// Description: Standard kd-tree search +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 +// Changed names LO, HI to ANN_LO, ANN_HI //---------------------------------------------------------------------- -#include "ANN.h" -#include "ANNx.h" // all ANN includes -#include "ANNperf.h" -#include "../GenGeomAlgs.h" - -#include "kd_search.h" // kd-search declarations +#include "kd_search.h" // kd-search declarations //---------------------------------------------------------------------- -// Approximate nearest neighbor searching by kd-tree search -// The kd-tree is searched for an approximate nearest neighbor. -// The point is returned through one of the arguments, and the -// distance returned is the squared distance to this point. +// Approximate nearest neighbor searching by kd-tree search +// The kd-tree is searched for an approximate nearest neighbor. +// The point is returned through one of the arguments, and the +// distance returned is the squared distance to this point. // -// The method used for searching the kd-tree is an approximate -// adaptation of the search algorithm described by Friedman, -// Bentley, and Finkel, ``An algorithm for finding best matches -// in logarithmic expected time,'' ACM Transactions on Mathematical -// Software, 3(3):209-226, 1977). +// The method used for searching the kd-tree is an approximate +// adaptation of the search algorithm described by Friedman, +// Bentley, and Finkel, ``An algorithm for finding best matches +// in logarithmic expected time,'' ACM Transactions on Mathematical +// Software, 3(3):209-226, 1977). // -// The algorithm operates recursively. When first encountering a -// node of the kd-tree we first visit the child which is closest to -// the query point. On return, we decide whether we want to visit -// the other child. If the box containing the other child exceeds -// 1/(1+eps) times the current best distance, then we skip it (since -// any point found in this child cannot be closer to the query point -// by more than this factor.) Otherwise, we visit it recursively. -// The distance between a box and the query point is computed exactly -// (not approximated as is often done in kd-tree), using incremental -// distance updates, as described by Arya and Mount in ``Algorithms -// for fast vector quantization,'' Proc. of DCC '93: Data Compression -// Conference, eds. J. A. Storer and M. Cohn, IEEE Press, 1993, -// 381-390. +// The algorithm operates recursively. When first encountering a +// node of the kd-tree we first visit the child which is closest to +// the query point. On return, we decide whether we want to visit +// the other child. If the box containing the other child exceeds +// 1/(1+eps) times the current best distance, then we skip it (since +// any point found in this child cannot be closer to the query point +// by more than this factor.) Otherwise, we visit it recursively. +// The distance between a box and the query point is computed exactly +// (not approximated as is often done in kd-tree), using incremental +// distance updates, as described by Arya and Mount in ``Algorithms +// for fast vector quantization,'' Proc. of DCC '93: Data Compression +// Conference, eds. J. A. Storer and M. Cohn, IEEE Press, 1993, +// 381-390. // -// The main entry points is annkSearch() which sets things up and -// then call the recursive routine ann_search(). This is a recursive -// routine which performs the processing for one node in the kd-tree. -// There are two versions of this virtual procedure, one for splitting -// nodes and one for leaves. When a splitting node is visited, we -// determine which child to visit first (the closer one), and visit -// the other child on return. When a leaf is visited, we compute -// the distances to the points in the buckets, and update information -// on the closest points. +// The main entry points is annkSearch() which sets things up and +// then call the recursive routine ann_search(). This is a recursive +// routine which performs the processing for one node in the kd-tree. +// There are two versions of this virtual procedure, one for splitting +// nodes and one for leaves. When a splitting node is visited, we +// determine which child to visit first (the closer one), and visit +// the other child on return. When a leaf is visited, we compute +// the distances to the points in the buckets, and update information +// on the closest points. // -// Some trickery is used to incrementally update the distance from -// a kd-tree rectangle to the query point. This comes about from -// the fact that which each successive split, only one component -// (along the dimension that is split) of the squared distance to -// the child rectangle is different from the squared distance to -// the parent rectangle. +// Some trickery is used to incrementally update the distance from +// a kd-tree rectangle to the query point. This comes about from +// the fact that which each successive split, only one component +// (along the dimension that is split) of the squared distance to +// the child rectangle is different from the squared distance to +// the parent rectangle. //---------------------------------------------------------------------- //---------------------------------------------------------------------- -// To keep argument lists short, a number of global variables -// are maintained which are common to all the recursive calls. -// These are given below. +// To keep argument lists short, a number of global variables +// are maintained which are common to all the recursive calls. +// These are given below. //---------------------------------------------------------------------- -int ANNkdDim; // dimension of space -ANNpoint ANNkdQ; // query point -double ANNkdMaxErr; // max tolerable squared error +int ANNkdDim; // dimension of space +ANNpoint ANNkdQ; // query point +double ANNkdMaxErr; // max tolerable squared error ANNpointArray ANNkdPts; // the points -ANNmin_k *ANNkdPointMK; // set of k closest points +ANNmin_k *ANNkdPointMK; // set of k closest points //---------------------------------------------------------------------- -// annkSearch - search for the k nearest neighbors +// annkSearch - search for the k nearest neighbors //---------------------------------------------------------------------- void ANNkd_tree::annkSearch( - ANNpoint q, // the query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor indices (returned) - ANNdistArray dd, // the approximate nearest neighbor - double eps, // the error bound - int method) // 1 == Euclidean Dist, 2== Arc Dist - + ANNpoint q, // the query point + int k, // number of near neighbors to return + ANNidxArray nn_idx, // nearest neighbor indices (returned) + ANNdistArray dd, // the approximate nearest neighbor + double eps) // the error bound { - ANNkdDim = dim; // copy arguments to static equivs - ANNkdQ = q; + ANNkdDim = dim; // copy arguments to static equivs + ANNkdQ = q; ANNkdPts = pts; - ANNptsVisited = 0; // initialize count of points visited + ANNptsVisited = 0; // initialize count of points visited - if (k > n_pts) - { // too many near neighbors? + if (k > n_pts) { // too many near neighbors? annError("Requesting more near neighbors than data points", ANNabort); } ANNkdMaxErr = ANN_POW(1.0 + eps); - FLOP(2) // increment floating op count + ANN_FLOP(2) // increment floating op count - ANNkdPointMK = new ANNmin_k(k); // create set for closest k points - // search starting at the root - root->ann_search(annBoxDistance(q, bnd_box_lo, bnd_box_hi, dim), method); + ANNkdPointMK = new ANNmin_k(k); // create set for closest k points + // search starting at the root + root->ann_search(annBoxDistance(q, bnd_box_lo, bnd_box_hi, dim)); - for (int i = 0; i < k; i++) - { // extract the k-th closest points + for (int i = 0; i < k; i++) { // extract the k-th closest points dd[i] = ANNkdPointMK->ith_smallest_key(i); nn_idx[i] = ANNkdPointMK->ith_smallest_info(i); } - delete ANNkdPointMK; // deallocate closest point set - ANNkdPointMK = NULL; + delete ANNkdPointMK; // deallocate closest point set } //---------------------------------------------------------------------- -// kd_split::ann_search - search a splitting node +// kd_split::ann_search - search a splitting node //---------------------------------------------------------------------- -void ANNkd_split::ann_search(ANNdist box_dist, int method) +void ANNkd_split::ann_search(ANNdist box_dist) { - // check dist calc termination condition - if (ANNmaxPtsVisited && ANNptsVisited > ANNmaxPtsVisited) return; + // check dist calc term condition + if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; - // distance to cutting plane + // distance to cutting plane ANNcoord cut_diff = ANNkdQ[cut_dim] - cut_val; - if (cut_diff < 0) - { // left of cutting plane - child[LO]->ann_search(box_dist, method);// visit closer child first + if (cut_diff < 0) { // left of cutting plane + child[ANN_LO]->ann_search(box_dist);// visit closer child first - ANNcoord box_diff = cd_bnds[LO] - ANNkdQ[cut_dim]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box + ANNcoord box_diff = cd_bnds[ANN_LO] - ANNkdQ[cut_dim]; + if (box_diff < 0) // within bounds - ignore + box_diff = 0; + // distance to further box box_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); + ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - // visit further child if close enough + // visit further child if close enough if (box_dist * ANNkdMaxErr < ANNkdPointMK->max_key()) - child[HI]->ann_search(box_dist, method); + child[ANN_HI]->ann_search(box_dist); } - else - { // right of cutting plane - child[HI]->ann_search(box_dist, method);// visit closer child first + else { // right of cutting plane + child[ANN_HI]->ann_search(box_dist);// visit closer child first - ANNcoord box_diff = ANNkdQ[cut_dim] - cd_bnds[HI]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box + ANNcoord box_diff = ANNkdQ[cut_dim] - cd_bnds[ANN_HI]; + if (box_diff < 0) // within bounds - ignore + box_diff = 0; + // distance to further box box_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); + ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - // visit further child if close enough + // visit further child if close enough if (box_dist * ANNkdMaxErr < ANNkdPointMK->max_key()) - child[LO]->ann_search(box_dist, method); + child[ANN_LO]->ann_search(box_dist); + } - FLOP(10) // increment floating ops - SPL(1) // one more splitting node visited + ANN_FLOP(10) // increment floating ops + ANN_SPL(1) // one more splitting node visited } - //---------------------------------------------------------------------- -// kd_leaf::ann_search - search points in a leaf node -// Note: The unreadability of this code is the result of -// some fine tuning to replace indexing by pointer operations. +// kd_leaf::ann_search - search points in a leaf node +// Note: The unreadability of this code is the result of +// some fine tuning to replace indexing by pointer operations. //---------------------------------------------------------------------- -// adding ArcDist computation - -void ANNkd_leaf::ann_search(ANNdist box_dist, int method) +void ANNkd_leaf::ann_search(ANNdist box_dist) { - register ANNdist dist; // distance to data point - register ANNcoord* pp; // data coordinate pointer - register ANNcoord* qq; // query coordinate pointer - register ANNdist min_dist; // distance to k-th closest point + register ANNdist dist; // distance to data point + register ANNcoord* pp; // data coordinate pointer + register ANNcoord* qq; // query coordinate pointer + register ANNdist min_dist; // distance to k-th closest point register ANNcoord t; register int d; - min_dist = ANNkdPointMK->max_key(); // k-th smallest distance so far - int i = 0; - switch (method) - { - case 1: // Euclidean Distance - for (i = 0; i < n_pts; i++) - { // check points in bucket + min_dist = ANNkdPointMK->max_key(); // k-th smallest distance so far - pp = ANNkdPts[bkt[i]]; // first coord of next data point - qq = ANNkdQ; // first coord of query point - dist = 0; + for (int i = 0; i < n_pts; i++) { // check points in bucket - for(d = 0; d < ANNkdDim; d++) - { - COORD(1) // one more coordinate hit - FLOP(4) // increment floating ops + pp = ANNkdPts[bkt[i]]; // first coord of next data point + qq = ANNkdQ; // first coord of query point + dist = 0; - t = *(qq++) - *(pp++); // compute length and adv coordinate - // exceeds dist to k-th smallest? - if( (dist = ANN_SUM(dist, ANN_POW(t))) > min_dist) - { - break; - } - } + for(d = 0; d < ANNkdDim; d++) { + ANN_COORD(1) // one more coordinate hit + ANN_FLOP(4) // increment floating ops - if (d >= ANNkdDim && // among the k best? - (ANN_ALLOW_SELF_MATCH || dist!=0)) - { // and no self-match problem - // add it to the list - ANNkdPointMK->insert(dist, bkt[i]); - min_dist = ANNkdPointMK->max_key(); - } + t = *(qq++) - *(pp++); // compute length and adv coordinate + // exceeds dist to k-th smallest? + if( (dist = ANN_SUM(dist, ANN_POW(t))) > min_dist) { + break; } - break; - case 2: // Arc Distance - for (i = 0; i < n_pts; i++) - { // check points in bucket - - pp = ANNkdPts[bkt[i]]; // first coord of next data point - qq = ANNkdQ; // first coord of query point - dist = 0; - double x[4]; - - for(d = 0; d < ANNkdDim; d++) - { - COORD(1) // one more coordinate hit - FLOP(4) // increment floating ops - - x[d] = *(qq++); - x[d+2] = *(pp++); // compute length and adv coordinate - } - - dist = GenGeomAlgs::ComputeArcDistRad(x[0], x[1], x[2], x[3]); - dist = dist * dist; - - if (dist > min_dist) - d = 0; - - if (ANN_ALLOW_SELF_MATCH || dist!=0) - { // and no self-match problem - // add it to the list - ANNkdPointMK->insert(dist, bkt[i]); - min_dist = ANNkdPointMK->max_key(); - } - } - - break; - default: - break; + } + + if (d >= ANNkdDim && // among the k best? + (ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem + // add it to the list + ANNkdPointMK->insert(dist, bkt[i]); + min_dist = ANNkdPointMK->max_key(); + } } - - LEAF(1) // one more leaf node visited - PTS(n_pts) // increment points visited - ANNptsVisited += n_pts; // increment number of points visited - - char buf[333]; - sprintf(buf,"Visited: %d, %f\n",n_pts,min_dist); + ANN_LEAF(1) // one more leaf node visited + ANN_PTS(n_pts) // increment points visited + ANNptsVisited += n_pts; // increment number of points visited } - diff --git a/kNN/kd_search.h b/kNN/kd_search.h old mode 100644 new mode 100755 index fb6cfa398..c90674862 --- a/kNN/kd_search.h +++ b/kNN/kd_search.h @@ -1,47 +1,48 @@ //---------------------------------------------------------------------- -// File: kd_search.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Standard kd-tree search +// File: kd_search.h +// Programmer: Sunil Arya and David Mount +// Description: Standard kd-tree search +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release //---------------------------------------------------------------------- #ifndef ANN_kd_search_H #define ANN_kd_search_H -#include "kd_tree.h" // kd-tree declarations -#include "kd_util.h" // kd-tree utilities -#include "pr_queue_k.h" // k-element priority queue -#include "ANNperf.h" // performance evaluation +#include "kd_tree.h" // kd-tree declarations +#include "kd_util.h" // kd-tree utilities +#include "pr_queue_k.h" // k-element priority queue + +#include "ANN/ANNperf.h" // performance evaluation //---------------------------------------------------------------------- -// More global variables -// These are active for the life of each call to Appx_Near_Neigh() -// or Appx_k_Near_Neigh(). They are set to save the number of -// variables that need to be passed among the various search -// procedures. +// More global variables +// These are active for the life of each call to annkSearch(). They +// are set to save the number of variables that need to be passed +// among the various search procedures. //---------------------------------------------------------------------- -extern int ANNkdDim; // dimension of space (static copy) -extern ANNpoint ANNkdQ; // query point (static copy) -extern double ANNkdMaxErr; // max tolerable squared error -extern ANNpointArray ANNkdPts; // the points (static copy) -extern ANNmin_k *ANNkdPointMK; // set of k closest points -extern int ANNptsVisited; // number of points visited +extern int ANNkdDim; // dimension of space (static copy) +extern ANNpoint ANNkdQ; // query point (static copy) +extern double ANNkdMaxErr; // max tolerable squared error +extern ANNpointArray ANNkdPts; // the points (static copy) +extern ANNmin_k *ANNkdPointMK; // set of k closest points +extern int ANNptsVisited; // number of points visited #endif diff --git a/kNN/kd_split.cpp b/kNN/kd_split.cpp old mode 100644 new mode 100755 index 43afecece..f5fb62018 --- a/kNN/kd_split.cpp +++ b/kNN/kd_split.cpp @@ -1,434 +1,428 @@ //---------------------------------------------------------------------- -// File: kd_split.cc -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Methods for splitting kd-trees +// File: kd_split.cpp +// Programmer: Sunil Arya and David Mount +// Description: Methods for splitting kd-trees +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 //---------------------------------------------------------------------- -#include "ANN.h" -#include "ANNx.h" // all ANN includes -#include "ANNperf.h" // performance evaluation - -#include "kd_tree.h" // kd-tree definitions -#include "kd_util.h" // kd-tree utilities -#include "kd_split.h" // splitting functions +#include "kd_tree.h" // kd-tree definitions +#include "kd_util.h" // kd-tree utilities +#include "kd_split.h" // splitting functions //---------------------------------------------------------------------- -// Constants +// Constants //---------------------------------------------------------------------- -const double ERR = 0.001; // a small value +const double ERR = 0.001; // a small value +const double FS_ASPECT_RATIO = 3.0; // maximum allowed aspect ratio + // in fair split. Must be >= 2. //---------------------------------------------------------------------- -// kd_split - Bentley's standard splitting routine for kd-trees -// Find the dimension of the greatest spread, and split -// just before the median point along this dimension. +// kd_split - Bentley's standard splitting routine for kd-trees +// Find the dimension of the greatest spread, and split +// just before the median point along this dimension. //---------------------------------------------------------------------- void kd_split( - ANNpointArray pa, // point array (permuted on return) - ANNidxArray pidx, // point indices - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) + ANNpointArray pa, // point array (permuted on return) + ANNidxArray pidx, // point indices + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo) // num of points on low side (returned) { - // find dimension of maximum spread - cut_dim = annMaxSpread(pa, pidx, n, dim); - n_lo = n/2; // median rank - // split about median - annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo); + // find dimension of maximum spread + cut_dim = annMaxSpread(pa, pidx, n, dim); + n_lo = n/2; // median rank + // split about median + annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo); } //---------------------------------------------------------------------- -// midpt_split - midpoint splitting rule for box-decomposition trees +// midpt_split - midpoint splitting rule for box-decomposition trees // -// This is the simplest splitting rule that guarantees boxes -// of bounded aspect ratio. It simply cuts the box with the -// longest side through its midpoint. If there are ties, it -// selects the dimension with the maximum point spread. +// This is the simplest splitting rule that guarantees boxes +// of bounded aspect ratio. It simply cuts the box with the +// longest side through its midpoint. If there are ties, it +// selects the dimension with the maximum point spread. // -// WARNING: This routine (while simple) doesn't seem to work -// well in practice in high dimensions, because it tends to -// generate a large number of trivial and/or unbalanced splits. -// Either kd_split(), sl_midpt_split(), or fair_split() are -// recommended, instead. +// WARNING: This routine (while simple) doesn't seem to work +// well in practice in high dimensions, because it tends to +// generate a large number of trivial and/or unbalanced splits. +// Either kd_split(), sl_midpt_split(), or fair_split() are +// recommended, instead. //---------------------------------------------------------------------- void midpt_split( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo) // num of points on low side (returned) { - int d; + int d; - ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; - for (d = 1; d < dim; d++) { // find length of longest box side - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (length > max_length) { - max_length = length; + ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; + for (d = 1; d < dim; d++) { // find length of longest box side + ANNcoord length = bnds.hi[d] - bnds.lo[d]; + if (length > max_length) { + max_length = length; + } } - } - ANNcoord max_spread = -1; // find long side with most spread - for (d = 0; d < dim; d++) { - // is it among longest? - if (double(bnds.hi[d] - bnds.lo[d]) >= (1-ERR)*max_length) { - // compute its spread - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spread) { // is it max so far? - max_spread = spr; - cut_dim = d; - } + ANNcoord max_spread = -1; // find long side with most spread + for (d = 0; d < dim; d++) { + // is it among longest? + if (double(bnds.hi[d] - bnds.lo[d]) >= (1-ERR)*max_length) { + // compute its spread + ANNcoord spr = annSpread(pa, pidx, n, d); + if (spr > max_spread) { // is it max so far? + max_spread = spr; + cut_dim = d; + } + } } - } - // split along cut_dim at midpoint - cut_val = (bnds.lo[cut_dim] + bnds.hi[cut_dim]) / 2; - // permute points accordingly - int br1, br2; - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - //------------------------------------------------------------------ - // On return: pa[0..br1-1] < cut_val - // pa[br1..br2-1] == cut_val - // pa[br2..n-1] > cut_val - // - // We can set n_lo to any value in the range [br1..br2]. - // We choose split so that points are most evenly divided. - //------------------------------------------------------------------ - if (br1 > n/2) n_lo = br1; - else if (br2 < n/2) n_lo = br2; - else n_lo = n/2; + // split along cut_dim at midpoint + cut_val = (bnds.lo[cut_dim] + bnds.hi[cut_dim]) / 2; + // permute points accordingly + int br1, br2; + annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); + //------------------------------------------------------------------ + // On return: pa[0..br1-1] < cut_val + // pa[br1..br2-1] == cut_val + // pa[br2..n-1] > cut_val + // + // We can set n_lo to any value in the range [br1..br2]. + // We choose split so that points are most evenly divided. + //------------------------------------------------------------------ + if (br1 > n/2) n_lo = br1; + else if (br2 < n/2) n_lo = br2; + else n_lo = n/2; } //---------------------------------------------------------------------- -// sl_midpt_split - sliding midpoint splitting rule +// sl_midpt_split - sliding midpoint splitting rule // -// This is a modification of midpt_split, which has the nonsensical -// name "sliding midpoint". The idea is that we try to use the -// midpoint rule, by bisecting the longest side. If there are -// ties, the dimension with the maximum spread is selected. If, -// however, the midpoint split produces a trivial split (no points -// on one side of the splitting plane) then we slide the splitting -// (maintaining its orientation) until it produces a nontrivial -// split. For example, if the splitting plane is along the x-axis, -// and all the data points have x-coordinate less than the x-bisector, -// then the split is taken along the maximum x-coordinate of the -// data points. +// This is a modification of midpt_split, which has the nonsensical +// name "sliding midpoint". The idea is that we try to use the +// midpoint rule, by bisecting the longest side. If there are +// ties, the dimension with the maximum spread is selected. If, +// however, the midpoint split produces a trivial split (no points +// on one side of the splitting plane) then we slide the splitting +// (maintaining its orientation) until it produces a nontrivial +// split. For example, if the splitting plane is along the x-axis, +// and all the data points have x-coordinate less than the x-bisector, +// then the split is taken along the maximum x-coordinate of the +// data points. // -// Intuitively, this rule cannot generate trivial splits, and -// hence avoids midpt_split's tendency to produce trees with -// a very large number of nodes. +// Intuitively, this rule cannot generate trivial splits, and +// hence avoids midpt_split's tendency to produce trees with +// a very large number of nodes. // //---------------------------------------------------------------------- void sl_midpt_split( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo) // num of points on low side (returned) { - int d; + int d; - ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; - for (d = 1; d < dim; d++) { // find length of longest box side - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (length > max_length) { - max_length = length; + ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; + for (d = 1; d < dim; d++) { // find length of longest box side + ANNcoord length = bnds.hi[d] - bnds.lo[d]; + if (length > max_length) { + max_length = length; + } } - } - ANNcoord max_spread = -1; // find long side with most spread - for (d = 0; d < dim; d++) { - // is it among longest? - if ((bnds.hi[d] - bnds.lo[d]) >= (1-ERR)*max_length) { - // compute its spread - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spread) { // is it max so far? - max_spread = spr; - cut_dim = d; - } + ANNcoord max_spread = -1; // find long side with most spread + for (d = 0; d < dim; d++) { + // is it among longest? + if ((bnds.hi[d] - bnds.lo[d]) >= (1-ERR)*max_length) { + // compute its spread + ANNcoord spr = annSpread(pa, pidx, n, d); + if (spr > max_spread) { // is it max so far? + max_spread = spr; + cut_dim = d; + } + } } - } - // ideal split at midpoint - ANNcoord ideal_cut_val = (bnds.lo[cut_dim] + bnds.hi[cut_dim])/2; + // ideal split at midpoint + ANNcoord ideal_cut_val = (bnds.lo[cut_dim] + bnds.hi[cut_dim])/2; - ANNcoord min, max; - annMinMax(pa, pidx, n, cut_dim, min, max); // find min/max coordinates + ANNcoord min, max; + annMinMax(pa, pidx, n, cut_dim, min, max); // find min/max coordinates - if (ideal_cut_val < min) // slide to min or max as needed - cut_val = min; - else if (ideal_cut_val > max) - cut_val = max; - else - cut_val = ideal_cut_val; + if (ideal_cut_val < min) // slide to min or max as needed + cut_val = min; + else if (ideal_cut_val > max) + cut_val = max; + else + cut_val = ideal_cut_val; - // permute points accordingly - int br1, br2; - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - //------------------------------------------------------------------ - // On return: pa[0..br1-1] < cut_val - // pa[br1..br2-1] == cut_val - // pa[br2..n-1] > cut_val - // - // We can set n_lo to any value in the range [br1..br2] to satisfy - // the exit conditions of the procedure. - // - // if ideal_cut_val < min (implying br2 >= 1), - // then we select n_lo = 1 (so there is one point on left) and - // if ideal_cut_val > max (implying br1 <= n-1), - // then we select n_lo = n-1 (so there is one point on right). - // Otherwise, we select n_lo as close to n/2 as possible within - // [br1..br2]. - //------------------------------------------------------------------ - if (ideal_cut_val < min) n_lo = 1; - else if (ideal_cut_val > max) n_lo = n-1; - else if (br1 > n/2) n_lo = br1; - else if (br2 < n/2) n_lo = br2; - else n_lo = n/2; + // permute points accordingly + int br1, br2; + annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); + //------------------------------------------------------------------ + // On return: pa[0..br1-1] < cut_val + // pa[br1..br2-1] == cut_val + // pa[br2..n-1] > cut_val + // + // We can set n_lo to any value in the range [br1..br2] to satisfy + // the exit conditions of the procedure. + // + // if ideal_cut_val < min (implying br2 >= 1), + // then we select n_lo = 1 (so there is one point on left) and + // if ideal_cut_val > max (implying br1 <= n-1), + // then we select n_lo = n-1 (so there is one point on right). + // Otherwise, we select n_lo as close to n/2 as possible within + // [br1..br2]. + //------------------------------------------------------------------ + if (ideal_cut_val < min) n_lo = 1; + else if (ideal_cut_val > max) n_lo = n-1; + else if (br1 > n/2) n_lo = br1; + else if (br2 < n/2) n_lo = br2; + else n_lo = n/2; } //---------------------------------------------------------------------- -// fair_split - fair-split splitting rule +// fair_split - fair-split splitting rule // -// This is a compromise between the kd-tree splitting rule (which -// always splits data points at their median) and the midpoint -// splitting rule (which always splits a box through its center. -// The goal of this procedure is to achieve both nicely balanced -// splits, and boxes of bounded aspect ratio. +// This is a compromise between the kd-tree splitting rule (which +// always splits data points at their median) and the midpoint +// splitting rule (which always splits a box through its center. +// The goal of this procedure is to achieve both nicely balanced +// splits, and boxes of bounded aspect ratio. // -// A constant FS_ASPECT_RATIO is defined. Given a box, those sides -// which can be split so that the ratio of the longest to shortest -// side does not exceed ASPECT_RATIO are identified. Among these -// sides, we select the one in which the points have the largest -// spread. We then split the points in a manner which most evenly -// distributes the points on either side of the splitting plane, -// subject to maintaining the bound on the ratio of long to short -// sides. To determine that the aspect ratio will be preserved, -// we determine the longest side (other than this side), and -// determine how narrowly we can cut this side, without causing the -// aspect ratio bound to be exceeded (small_piece). +// A constant FS_ASPECT_RATIO is defined. Given a box, those sides +// which can be split so that the ratio of the longest to shortest +// side does not exceed ASPECT_RATIO are identified. Among these +// sides, we select the one in which the points have the largest +// spread. We then split the points in a manner which most evenly +// distributes the points on either side of the splitting plane, +// subject to maintaining the bound on the ratio of long to short +// sides. To determine that the aspect ratio will be preserved, +// we determine the longest side (other than this side), and +// determine how narrowly we can cut this side, without causing the +// aspect ratio bound to be exceeded (small_piece). // -// This procedure is more robust than either kd_split or midpt_split, -// but is more complicated as well. When point distribution is -// extremely skewed, this degenerates to midpt_split (actually -// 1/3 point split), and when the points are most evenly distributed, -// this degenerates to kd-split. +// This procedure is more robust than either kd_split or midpt_split, +// but is more complicated as well. When point distribution is +// extremely skewed, this degenerates to midpt_split (actually +// 1/3 point split), and when the points are most evenly distributed, +// this degenerates to kd-split. //---------------------------------------------------------------------- -const double FS_ASPECT_RATIO = 3.0; // maximum allowed aspect ratio - // must be >= 2. - void fair_split( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo) // num of points on low side (returned) { - int d; - ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; - cut_dim = 0; - for (d = 1; d < dim; d++) { // find length of longest box side - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (length > max_length) { - max_length = length; - cut_dim = d; + int d; + ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; + cut_dim = 0; + for (d = 1; d < dim; d++) { // find length of longest box side + ANNcoord length = bnds.hi[d] - bnds.lo[d]; + if (length > max_length) { + max_length = length; + cut_dim = d; + } } - } - ANNcoord max_spread = 0; // find legal cut with max spread - cut_dim = 0; - for (d = 0; d < dim; d++) { - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - // is this side midpoint splitable - // without violating aspect ratio? - if (((double) max_length)*2.0/((double) length) <= FS_ASPECT_RATIO) { - // compute spread along this dim - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spread) { // best spread so far - max_spread = spr; - cut_dim = d; // this is dimension to cut - } + ANNcoord max_spread = 0; // find legal cut with max spread + cut_dim = 0; + for (d = 0; d < dim; d++) { + ANNcoord length = bnds.hi[d] - bnds.lo[d]; + // is this side midpoint splitable + // without violating aspect ratio? + if (((double) max_length)*2.0/((double) length) <= FS_ASPECT_RATIO) { + // compute spread along this dim + ANNcoord spr = annSpread(pa, pidx, n, d); + if (spr > max_spread) { // best spread so far + max_spread = spr; + cut_dim = d; // this is dimension to cut + } + } } - } - max_length = 0; // find longest side other than cut_dim - for (d = 0; d < dim; d++) { - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (d != cut_dim && length > max_length) - max_length = length; - } - // consider most extreme splits - ANNcoord small_piece = max_length / FS_ASPECT_RATIO; - ANNcoord lo_cut = bnds.lo[cut_dim] + small_piece;// lowest legal cut - ANNcoord hi_cut = bnds.hi[cut_dim] - small_piece;// highest legal cut + max_length = 0; // find longest side other than cut_dim + for (d = 0; d < dim; d++) { + ANNcoord length = bnds.hi[d] - bnds.lo[d]; + if (d != cut_dim && length > max_length) + max_length = length; + } + // consider most extreme splits + ANNcoord small_piece = max_length / FS_ASPECT_RATIO; + ANNcoord lo_cut = bnds.lo[cut_dim] + small_piece;// lowest legal cut + ANNcoord hi_cut = bnds.hi[cut_dim] - small_piece;// highest legal cut - int br1, br2; - // is median below lo_cut ? - if (annSplitBalance(pa, pidx, n, cut_dim, lo_cut) >= 0) { - cut_val = lo_cut; // cut at lo_cut - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = br1; - } - // is median above hi_cut? - else if (annSplitBalance(pa, pidx, n, cut_dim, hi_cut) <= 0) { - cut_val = hi_cut; // cut at hi_cut - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = br2; - } - else { // median cut preserves asp ratio - n_lo = n/2; // split about median - annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo); - } + int br1, br2; + // is median below lo_cut ? + if (annSplitBalance(pa, pidx, n, cut_dim, lo_cut) >= 0) { + cut_val = lo_cut; // cut at lo_cut + annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); + n_lo = br1; + } + // is median above hi_cut? + else if (annSplitBalance(pa, pidx, n, cut_dim, hi_cut) <= 0) { + cut_val = hi_cut; // cut at hi_cut + annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); + n_lo = br2; + } + else { // median cut preserves asp ratio + n_lo = n/2; // split about median + annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo); + } } //---------------------------------------------------------------------- -// sl_fair_split - sliding fair split splitting rule +// sl_fair_split - sliding fair split splitting rule // -// Sliding fair split is a splitting rule that combines the -// strengths of both fair split with sliding midpoint split. -// Fair split tends to produce balanced splits when the points -// are roughly uniformly distributed, but it can produce many -// trivial splits when points are highly clustered. Sliding -// midpoint never produces trivial splits, and shrinks boxes -// nicely if points are highly clustered, but it may produce -// rather unbalanced splits when points are unclustered but not -// quite uniform. +// Sliding fair split is a splitting rule that combines the +// strengths of both fair split with sliding midpoint split. +// Fair split tends to produce balanced splits when the points +// are roughly uniformly distributed, but it can produce many +// trivial splits when points are highly clustered. Sliding +// midpoint never produces trivial splits, and shrinks boxes +// nicely if points are highly clustered, but it may produce +// rather unbalanced splits when points are unclustered but not +// quite uniform. // -// Sliding fair split is based on the theory that there are two -// types of splits that are "good": balanced splits that produce -// fat boxes, and unbalanced splits provided the cell with fewer -// points is fat. +// Sliding fair split is based on the theory that there are two +// types of splits that are "good": balanced splits that produce +// fat boxes, and unbalanced splits provided the cell with fewer +// points is fat. // -// This splitting rule operates by first computing the longest -// side of the current bounding box. Then it asks which sides -// could be split (at the midpoint) and still satisfy the aspect -// ratio bound with respect to this side. Among these, it selects -// the side with the largest spread (as fair split would). It -// then considers the most extreme cuts that would be allowed by -// the aspect ratio bound. This is done by dividing the longest -// side of the box by the aspect ratio bound. If the median cut -// lies between these extreme cuts, then we use the median cut. -// If not, then consider the extreme cut that is closer to the -// median. If all the points lie to one side of this cut, then -// we slide the cut until it hits the first point. This may -// violate the aspect ratio bound, but will never generate empty -// cells. However the sibling of every such skinny cell is fat, -// and hence packing arguments still apply. +// This splitting rule operates by first computing the longest +// side of the current bounding box. Then it asks which sides +// could be split (at the midpoint) and still satisfy the aspect +// ratio bound with respect to this side. Among these, it selects +// the side with the largest spread (as fair split would). It +// then considers the most extreme cuts that would be allowed by +// the aspect ratio bound. This is done by dividing the longest +// side of the box by the aspect ratio bound. If the median cut +// lies between these extreme cuts, then we use the median cut. +// If not, then consider the extreme cut that is closer to the +// median. If all the points lie to one side of this cut, then +// we slide the cut until it hits the first point. This may +// violate the aspect ratio bound, but will never generate empty +// cells. However the sibling of every such skinny cell is fat, +// and hence packing arguments still apply. // //---------------------------------------------------------------------- -const double SFS_ASPECT_RATIO = 3.0; // maximum allowed aspect ratio - // must be >= 2. - void sl_fair_split( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo) // num of points on low side (returned) { - int d; - ANNcoord min, max; // min/max coordinates - int br1, br2; // split break points + int d; + ANNcoord min, max; // min/max coordinates + int br1, br2; // split break points - ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; - cut_dim = 0; - for (d = 1; d < dim; d++) { // find length of longest box side - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (length > max_length) { - max_length = length; - cut_dim = d; + ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; + cut_dim = 0; + for (d = 1; d < dim; d++) { // find length of longest box side + ANNcoord length = bnds.hi[d] - bnds.lo[d]; + if (length > max_length) { + max_length = length; + cut_dim = d; + } } - } - ANNcoord max_spread = 0; // find legal cut with max spread - cut_dim = 0; - for (d = 0; d < dim; d++) { - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - // is this side midpoint splitable - // without violating aspect ratio? - if (((double) max_length)*2.0/((double) length) <= SFS_ASPECT_RATIO) { - // compute spread along this dim - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spread) { // best spread so far - max_spread = spr; - cut_dim = d; // this is dimension to cut - } + ANNcoord max_spread = 0; // find legal cut with max spread + cut_dim = 0; + for (d = 0; d < dim; d++) { + ANNcoord length = bnds.hi[d] - bnds.lo[d]; + // is this side midpoint splitable + // without violating aspect ratio? + if (((double) max_length)*2.0/((double) length) <= FS_ASPECT_RATIO) { + // compute spread along this dim + ANNcoord spr = annSpread(pa, pidx, n, d); + if (spr > max_spread) { // best spread so far + max_spread = spr; + cut_dim = d; // this is dimension to cut + } + } } - } - max_length = 0; // find longest side other than cut_dim - for (d = 0; d < dim; d++) { - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (d != cut_dim && length > max_length) - max_length = length; - } - // consider most extreme splits - ANNcoord small_piece = max_length / SFS_ASPECT_RATIO; - ANNcoord lo_cut = bnds.lo[cut_dim] + small_piece;// lowest legal cut - ANNcoord hi_cut = bnds.hi[cut_dim] - small_piece;// highest legal cut - // find min and max along cut_dim - annMinMax(pa, pidx, n, cut_dim, min, max); - // is median below lo_cut? - if (annSplitBalance(pa, pidx, n, cut_dim, lo_cut) >= 0) { - if (max > lo_cut) { // are any points above lo_cut? - cut_val = lo_cut; // cut at lo_cut - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = br1; // balance if there are ties + max_length = 0; // find longest side other than cut_dim + for (d = 0; d < dim; d++) { + ANNcoord length = bnds.hi[d] - bnds.lo[d]; + if (d != cut_dim && length > max_length) + max_length = length; } - else { // all points below lo_cut - cut_val = max; // cut at max value - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = n-1; + // consider most extreme splits + ANNcoord small_piece = max_length / FS_ASPECT_RATIO; + ANNcoord lo_cut = bnds.lo[cut_dim] + small_piece;// lowest legal cut + ANNcoord hi_cut = bnds.hi[cut_dim] - small_piece;// highest legal cut + // find min and max along cut_dim + annMinMax(pa, pidx, n, cut_dim, min, max); + // is median below lo_cut? + if (annSplitBalance(pa, pidx, n, cut_dim, lo_cut) >= 0) { + if (max > lo_cut) { // are any points above lo_cut? + cut_val = lo_cut; // cut at lo_cut + annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); + n_lo = br1; // balance if there are ties + } + else { // all points below lo_cut + cut_val = max; // cut at max value + annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); + n_lo = n-1; + } } - } - // is median above hi_cut? - else if (annSplitBalance(pa, pidx, n, cut_dim, hi_cut) <= 0) { - if (min < hi_cut) { // are any points below hi_cut? - cut_val = hi_cut; // cut at hi_cut - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = br2; // balance if there are ties + // is median above hi_cut? + else if (annSplitBalance(pa, pidx, n, cut_dim, hi_cut) <= 0) { + if (min < hi_cut) { // are any points below hi_cut? + cut_val = hi_cut; // cut at hi_cut + annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); + n_lo = br2; // balance if there are ties + } + else { // all points above hi_cut + cut_val = min; // cut at min value + annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); + n_lo = 1; + } } - else { // all points above hi_cut - cut_val = min; // cut at min value - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = 1; + else { // median cut is good enough + n_lo = n/2; // split about median + annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo); } - } - else { // median cut is good enough - n_lo = n/2; // split about median - annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo); - } } diff --git a/kNN/kd_split.h b/kNN/kd_split.h old mode 100644 new mode 100755 index d6f04e95c..130e188f0 --- a/kNN/kd_split.h +++ b/kNN/kd_split.h @@ -1,84 +1,85 @@ //---------------------------------------------------------------------- -// File: kd_split.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Methods for splitting kd-trees +// File: kd_split.h +// Programmer: Sunil Arya and David Mount +// Description: Methods for splitting kd-trees +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release //---------------------------------------------------------------------- #ifndef ANN_KD_SPLIT_H #define ANN_KD_SPLIT_H -#include "kd_tree.h" // kd-tree definitions +#include "kd_tree.h" // kd-tree definitions //---------------------------------------------------------------------- -// External entry points -// These are all splitting procedures for kd-trees. +// External entry points +// These are all splitting procedures for kd-trees. //---------------------------------------------------------------------- -void kd_split( // standard (optimized) kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) +void kd_split( // standard (optimized) kd-splitter + ANNpointArray pa, // point array (unaltered) + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo); // num of points on low side (returned) -void midpt_split( // midpoint kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) +void midpt_split( // midpoint kd-splitter + ANNpointArray pa, // point array (unaltered) + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo); // num of points on low side (returned) -void sl_midpt_split( // sliding midpoint kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) +void sl_midpt_split( // sliding midpoint kd-splitter + ANNpointArray pa, // point array (unaltered) + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo); // num of points on low side (returned) -void fair_split( // fair-split kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) +void fair_split( // fair-split kd-splitter + ANNpointArray pa, // point array (unaltered) + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo); // num of points on low side (returned) -void sl_fair_split( // sliding fair-split kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) +void sl_fair_split( // sliding fair-split kd-splitter + ANNpointArray pa, // point array (unaltered) + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo); // num of points on low side (returned) #endif diff --git a/kNN/kd_tree.cpp b/kNN/kd_tree.cpp old mode 100644 new mode 100755 index 90b6630a4..526ba76e9 --- a/kNN/kd_tree.cpp +++ b/kNN/kd_tree.cpp @@ -1,283 +1,405 @@ //---------------------------------------------------------------------- -// File: kd_tree.cc -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Basic methods for kd-trees. +// File: kd_tree.cpp +// Programmer: Sunil Arya and David Mount +// Description: Basic methods for kd-trees. +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 +// Increased aspect ratio bound (ANN_AR_TOOBIG) from 100 to 1000. +// Fixed leaf counts to count trivial leaves. +// Added optional pa, pi arguments to Skeleton kd_tree constructor +// for use in load constructor. +// Added annClose() to eliminate KD_TRIVIAL memory leak. //---------------------------------------------------------------------- -#include "ANN.h" -#include "ANNx.h" -#include "kd_tree.h" // kd-tree declarations -#include "kd_split.h" // kd-tree splitting rules -#include "kd_util.h" // kd-tree utilities -#include "ANNperf.h" // performance evaluation +#include "kd_tree.h" // kd-tree declarations +#include "kd_split.h" // kd-tree splitting rules +#include "kd_util.h" // kd-tree utilities +#include "ANN/ANNperf.h" // performance evaluation //---------------------------------------------------------------------- -// Global data +// Global data // -// For some splitting rules, especially with small bucket sizes, -// it is possible to generate a large number of empty leaf nodes. -// To save storage we allocate a single trivial leaf node which -// contains no points. For messy coding reasons it is convenient -// to have it reference a trivial point index. +// For some splitting rules, especially with small bucket sizes, +// it is possible to generate a large number of empty leaf nodes. +// To save storage we allocate a single trivial leaf node which +// contains no points. For messy coding reasons it is convenient +// to have it reference a trivial point index. // -// KD_TRIVIAL is allocated when the first kd-tree is created. It -// must *never* deallocated (since it may be shared by more than -// one tree). +// KD_TRIVIAL is allocated when the first kd-tree is created. It +// must *never* deallocated (since it may be shared by more than +// one tree). //---------------------------------------------------------------------- -static int IDX_TRIVIAL[] = {0}; // trivial point index -ANNkd_leaf *KD_TRIVIAL = NULL; // trivial leaf node +static int IDX_TRIVIAL[] = {0}; // trivial point index +ANNkd_leaf *KD_TRIVIAL = NULL; // trivial leaf node //---------------------------------------------------------------------- -// Printing the kd-tree -// These routines print a kd-tree in reverse inorder (high then -// root then low). (This is so that if you look at the output -// from the right side it appear from left to right in standard -// inorder.) When outputting leaves we output only the point -// indices rather than the point coordinates. There is an option -// to print the point coordinates separately. +// Printing the kd-tree +// These routines print a kd-tree in reverse inorder (high then +// root then low). (This is so that if you look at the output +// from the right side it appear from left to right in standard +// inorder.) When outputting leaves we output only the point +// indices rather than the point coordinates. There is an option +// to print the point coordinates separately. // -// The tree printing routine calls the printing routines on the -// individual nodes of the tree, passing in the level or depth -// in the tree. The level in the tree is used to print indentation -// for readability. +// The tree printing routine calls the printing routines on the +// individual nodes of the tree, passing in the level or depth +// in the tree. The level in the tree is used to print indentation +// for readability. //---------------------------------------------------------------------- +void ANNkd_split::print( // print splitting node + int level, // depth of node in tree + ostream &out) // output stream +{ + child[ANN_HI]->print(level+1, out); // print high child + out << " "; + for (int i = 0; i < level; i++) // print indentation + out << ".."; + out << "Split cd=" << cut_dim << " cv=" << cut_val; + out << " lbnd=" << cd_bnds[ANN_LO]; + out << " hbnd=" << cd_bnds[ANN_HI]; + out << "\n"; + child[ANN_LO]->print(level+1, out); // print low child +} + +void ANNkd_leaf::print( // print leaf node + int level, // depth of node in tree + ostream &out) // output stream +{ + + out << " "; + for (int i = 0; i < level; i++) // print indentation + out << ".."; + + if (this == KD_TRIVIAL) { // canonical trivial leaf node + out << "Leaf (trivial)\n"; + } + else{ + out << "Leaf n=" << n_pts << " <"; + for (int j = 0; j < n_pts; j++) { + out << bkt[j]; + if (j < n_pts-1) out << ","; + } + out << ">\n"; + } +} + +void ANNkd_tree::Print( // print entire tree + ANNbool with_pts, // print points as well? + ostream &out) // output stream +{ + out << "ANN Version " << ANNversion << "\n"; + if (with_pts) { // print point coordinates + out << " Points:\n"; + for (int i = 0; i < n_pts; i++) { + out << "\t" << i << ": "; + annPrintPt(pts[i], dim, out); + out << "\n"; + } + } + if (root == NULL) // empty tree? + out << " Null tree.\n"; + else { + root->print(0, out); // invoke printing at root + } +} //---------------------------------------------------------------------- -// Dumping a kd-tree -// This routine dumps a kd-tree to a file. The tree is printed -// in preorder. Eventually there should be a routine that loads -// a tree that has been dumped. -// -// Format: -// #ANN -// points (point coordinates: this is optional) -// 0 ... (point indices and coordinates) -// 1 ... -// ... -// tree -// ... (lower end of bounding box) -// ... (upper end of bounding box) -// If the tree is null, then a single line "null" is -// output. Otherwise the nodes of the tree are printed -// one per line in preorder. Leaves and splitting nodes -// have the following formats: -// Leaf node: -// leaf ... -// Splitting nodes: -// split -// -// Note: Infinite lo_ and hi_bounds are printed as the special -// values "-INF" and "+INF", respectively. +// kd_tree statistics (for performance evaluation) +// This routine compute various statistics information for +// a kd-tree. It is used by the implementors for performance +// evaluation of the data structure. //---------------------------------------------------------------------- +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +void ANNkdStats::merge(const ANNkdStats &st) // merge stats from child +{ + n_lf += st.n_lf; n_tl += st.n_tl; + n_spl += st.n_spl; n_shr += st.n_shr; + depth = MAX(depth, st.depth); + sum_ar += st.sum_ar; +} + +//---------------------------------------------------------------------- +// Update statistics for nodes +//---------------------------------------------------------------------- + +const double ANN_AR_TOOBIG = 1000; // too big an aspect ratio + +void ANNkd_leaf::getStats( // get subtree statistics + int dim, // dimension of space + ANNkdStats &st, // stats (modified) + ANNorthRect &bnd_box) // bounding box +{ + st.reset(); + st.n_lf = 1; // count this leaf + if (this == KD_TRIVIAL) st.n_tl = 1; // count trivial leaf + double ar = annAspectRatio(dim, bnd_box); // aspect ratio of leaf + // incr sum (ignore outliers) + st.sum_ar += float(ar < ANN_AR_TOOBIG ? ar : ANN_AR_TOOBIG); +} + +void ANNkd_split::getStats( // get subtree statistics + int dim, // dimension of space + ANNkdStats &st, // stats (modified) + ANNorthRect &bnd_box) // bounding box +{ + ANNkdStats ch_stats; // stats for children + // get stats for low child + ANNcoord hv = bnd_box.hi[cut_dim]; // save box bounds + bnd_box.hi[cut_dim] = cut_val; // upper bound for low child + ch_stats.reset(); // reset + child[ANN_LO]->getStats(dim, ch_stats, bnd_box); + st.merge(ch_stats); // merge them + bnd_box.hi[cut_dim] = hv; // restore bound + // get stats for high child + ANNcoord lv = bnd_box.lo[cut_dim]; // save box bounds + bnd_box.lo[cut_dim] = cut_val; // lower bound for high child + ch_stats.reset(); // reset + child[ANN_HI]->getStats(dim, ch_stats, bnd_box); + st.merge(ch_stats); // merge them + bnd_box.lo[cut_dim] = lv; // restore bound + + st.depth++; // increment depth + st.n_spl++; // increment number of splits +} //---------------------------------------------------------------------- -// kd_tree statistics (for performance evaluation) -// This routine compute various statistics information for -// a kd-tree. It is used by the implementors for performance -// evaluation of the data structure. +// getStats +// Collects a number of statistics related to kd_tree or +// bd_tree. //---------------------------------------------------------------------- -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -/* +void ANNkd_tree::getStats( // get tree statistics + ANNkdStats &st) // stats (modified) +{ + st.reset(dim, n_pts, bkt_size); // reset stats + // create bounding box + ANNorthRect bnd_box(dim, bnd_box_lo, bnd_box_hi); + if (root != NULL) { // if nonempty tree + root->getStats(dim, st, bnd_box); // get statistics + st.avg_ar = st.sum_ar / st.n_lf; // average leaf asp ratio + } +} //---------------------------------------------------------------------- -// kd_tree destructor -// The destructor just frees the various elements that were -// allocated in the construction process. +// kd_tree destructor +// The destructor just frees the various elements that were +// allocated in the construction process. //---------------------------------------------------------------------- -*/ -ANNkd_tree::~ANNkd_tree() // tree destructor +ANNkd_tree::~ANNkd_tree() // tree destructor { if (root != NULL) delete root; - root = NULL; if (pidx != NULL) delete [] pidx; - pidx = NULL; if (bnd_box_lo != NULL) annDeallocPt(bnd_box_lo); - bnd_box_lo = NULL; if (bnd_box_hi != NULL) annDeallocPt(bnd_box_hi); - bnd_box_hi = NULL; } //---------------------------------------------------------------------- -// kd_tree constructors -// There is a skeleton kd-tree constructor which sets up a -// trivial empty tree. +// This is called with all use of ANN is finished. It eliminates the +// minor memory leak caused by the allocation of KD_TRIVIAL. +//---------------------------------------------------------------------- +void annClose() // close use of ANN +{ + if (KD_TRIVIAL != NULL) { + delete KD_TRIVIAL; + KD_TRIVIAL = NULL; + } +} + +//---------------------------------------------------------------------- +// kd_tree constructors +// There is a skeleton kd-tree constructor which sets up a +// trivial empty tree. The last optional argument allows +// the routine to be passed a point index array which is +// assumed to be of the proper size (n). Otherwise, one is +// allocated and initialized to the identity. Warning: In +// either case the destructor will deallocate this array. // -// The more interesting constructor is given a collection of -// points and builds the entire tree. It appears in the file -// kd_split.cc. +// As a kludge, we need to allocate KD_TRIVIAL if one has not +// already been allocated. (This is because I'm too dumb to +// figure out how to cause a pointer to be allocated at load +// time.) //---------------------------------------------------------------------- -void ANNkd_tree::SkeletonTree( // construct skeleton tree - int n, // number of points - int dd, // dimension - int bs) // bucket size +void ANNkd_tree::SkeletonTree( // construct skeleton tree + int n, // number of points + int dd, // dimension + int bs, // bucket size + ANNpointArray pa, // point array + ANNidxArray pi) // point indices { - dim = dd; // initialize basic elements - n_pts = n; - bkt_size = bs; - root = NULL; // no associated tree yet - pts = NULL; // no associated points yet - - pidx = new int[n]; // allocate space for point indices - for (int i = 0; i < n; i++) { - pidx[i] = i; // initially identity - } - bnd_box_lo = bnd_box_hi = NULL; // bounding box is nonexistent - if (KD_TRIVIAL == NULL) // no trivial leaf node yet? - KD_TRIVIAL = new ANNkd_leaf(0, IDX_TRIVIAL); // allocate it + dim = dd; // initialize basic elements + n_pts = n; + bkt_size = bs; + pts = pa; // initialize points array + + root = NULL; // no associated tree yet + + if (pi == NULL) { // point indices provided? + pidx = new ANNidx[n]; // no, allocate space for point indices + for (int i = 0; i < n; i++) { + pidx[i] = i; // initially identity + } + } + else { + pidx = pi; // yes, use them + } + + bnd_box_lo = bnd_box_hi = NULL; // bounding box is nonexistent + if (KD_TRIVIAL == NULL) // no trivial leaf node yet? + KD_TRIVIAL = new ANNkd_leaf(0, IDX_TRIVIAL); // allocate it } -ANNkd_tree::ANNkd_tree( // basic constructor - int n, // number of points - int dd, // dimension - int bs) // bucket size -{ SkeletonTree(n, dd, bs); } // construct skeleton tree +ANNkd_tree::ANNkd_tree( // basic constructor + int n, // number of points + int dd, // dimension + int bs) // bucket size +{ SkeletonTree(n, dd, bs); } // construct skeleton tree //---------------------------------------------------------------------- -// rkd_tree - recursive procedure to build a kd-tree +// rkd_tree - recursive procedure to build a kd-tree // -// Builds a kd-tree for points in pa as indexed through the -// array pidx[0..n-1] (typically a subarray of the array used in -// the top-level call). This routine permutes the array pidx, -// but does not alter pa[]. +// Builds a kd-tree for points in pa as indexed through the +// array pidx[0..n-1] (typically a subarray of the array used in +// the top-level call). This routine permutes the array pidx, +// but does not alter pa[]. // -// The construction is based on a standard algorithm for constructing -// the kd-tree (see Friedman, Bentley, and Finkel, ``An algorithm for -// finding best matches in logarithmic expected time,'' ACM Transactions -// on Mathematical Software, 3(3):209-226, 1977). The procedure -// operates by a simple divide-and-conquer strategy, which determines -// an appropriate orthogonal cutting plane (see below), and splits -// the points. When the number of points falls below the bucket size, -// we simply store the points in a leaf node's bucket. +// The construction is based on a standard algorithm for constructing +// the kd-tree (see Friedman, Bentley, and Finkel, ``An algorithm for +// finding best matches in logarithmic expected time,'' ACM Transactions +// on Mathematical Software, 3(3):209-226, 1977). The procedure +// operates by a simple divide-and-conquer strategy, which determines +// an appropriate orthogonal cutting plane (see below), and splits +// the points. When the number of points falls below the bucket size, +// we simply store the points in a leaf node's bucket. // -// One of the arguments is a pointer to a splitting routine, -// whose prototype is: -// -// void split( -// ANNpointArray pa, // complete point array -// ANNidxArray pidx, // point array (permuted on return) -// ANNorthRect &bnds, // bounds of current cell -// int n, // number of points -// int dim, // dimension of space -// int &cut_dim, // cutting dimension -// ANNcoord &cut_val, // cutting value -// int &n_lo) // no. of points on low side of cut +// One of the arguments is a pointer to a splitting routine, +// whose prototype is: +// +// void split( +// ANNpointArray pa, // complete point array +// ANNidxArray pidx, // point array (permuted on return) +// ANNorthRect &bnds, // bounds of current cell +// int n, // number of points +// int dim, // dimension of space +// int &cut_dim, // cutting dimension +// ANNcoord &cut_val, // cutting value +// int &n_lo) // no. of points on low side of cut // -// This procedure selects a cutting dimension and cutting value, -// partitions pa about these values, and returns the number of -// points on the low side of the cut. +// This procedure selects a cutting dimension and cutting value, +// partitions pa about these values, and returns the number of +// points on the low side of the cut. //---------------------------------------------------------------------- -ANNkd_ptr rkd_tree( // recursive construction of kd-tree - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices to store in subtree - int n, // number of points - int dim, // dimension of space - int bsp, // bucket space - ANNorthRect &bnd_box, // bounding box for current node - ANNkd_splitter splitter) // splitting routine +ANNkd_ptr rkd_tree( // recursive construction of kd-tree + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices to store in subtree + int n, // number of points + int dim, // dimension of space + int bsp, // bucket space + ANNorthRect &bnd_box, // bounding box for current node + ANNkd_splitter splitter) // splitting routine { - if (n <= bsp) { // n small, make a leaf node - if (n == 0) // empty leaf node - return KD_TRIVIAL; // return (canonical) empty leaf - else // construct the node and return - return new ANNkd_leaf(n, pidx); - } - else { // n large, make a splitting node - int cd; // cutting dimension - ANNcoord cv; // cutting value - int n_lo; // number on low side of cut - ANNkd_node *lo, *hi; // low and high children - - // invoke splitting procedure - (*splitter)(pa, pidx, bnd_box, n, dim, cd, cv, n_lo); - - ANNcoord lv = bnd_box.lo[cd]; // save bounds for cutting dimension - ANNcoord hv = bnd_box.hi[cd]; - - bnd_box.hi[cd] = cv; // modify bounds for left subtree - lo = rkd_tree( // build left subtree - pa, pidx, n_lo, // ...from pidx[0..n_lo-1] - dim, bsp, bnd_box, splitter); - bnd_box.hi[cd] = hv; // restore bounds - - bnd_box.lo[cd] = cv; // modify bounds for right subtree - hi = rkd_tree( // build right subtree - pa, pidx + n_lo, n-n_lo,// ...from pidx[n_lo..n-1] - dim, bsp, bnd_box, splitter); - bnd_box.lo[cd] = lv; // restore bounds - - // create the splitting node - ANNkd_split *ptr = new ANNkd_split(cd, cv, lv, hv, lo, hi); - - return ptr; // return pointer to this node - } + if (n <= bsp) { // n small, make a leaf node + if (n == 0) // empty leaf node + return KD_TRIVIAL; // return (canonical) empty leaf + else // construct the node and return + return new ANNkd_leaf(n, pidx); + } + else { // n large, make a splitting node + int cd; // cutting dimension + ANNcoord cv; // cutting value + int n_lo; // number on low side of cut + ANNkd_node *lo, *hi; // low and high children + + // invoke splitting procedure + (*splitter)(pa, pidx, bnd_box, n, dim, cd, cv, n_lo); + + ANNcoord lv = bnd_box.lo[cd]; // save bounds for cutting dimension + ANNcoord hv = bnd_box.hi[cd]; + + bnd_box.hi[cd] = cv; // modify bounds for left subtree + lo = rkd_tree( // build left subtree + pa, pidx, n_lo, // ...from pidx[0..n_lo-1] + dim, bsp, bnd_box, splitter); + bnd_box.hi[cd] = hv; // restore bounds + + bnd_box.lo[cd] = cv; // modify bounds for right subtree + hi = rkd_tree( // build right subtree + pa, pidx + n_lo, n-n_lo,// ...from pidx[n_lo..n-1] + dim, bsp, bnd_box, splitter); + bnd_box.lo[cd] = lv; // restore bounds + + // create the splitting node + ANNkd_split *ptr = new ANNkd_split(cd, cv, lv, hv, lo, hi); + + return ptr; // return pointer to this node + } } //---------------------------------------------------------------------- // kd-tree constructor -// This is the main constructor for kd-trees given a set of points. -// It first builds a skeleton tree, then computes the bounding box -// of the data points, and then invokes rkd_tree() to actually -// build the tree, passing it the appropriate splitting routine. +// This is the main constructor for kd-trees given a set of points. +// It first builds a skeleton tree, then computes the bounding box +// of the data points, and then invokes rkd_tree() to actually +// build the tree, passing it the appropriate splitting routine. //---------------------------------------------------------------------- -ANNkd_tree::ANNkd_tree( // construct from point array - ANNpointArray pa, // point array (with at least n pts) - int n, // number of points - int dd, // dimension - int bs, // bucket size - ANNsplitRule split) // splitting method +ANNkd_tree::ANNkd_tree( // construct from point array + ANNpointArray pa, // point array (with at least n pts) + int n, // number of points + int dd, // dimension + int bs, // bucket size + ANNsplitRule split) // splitting method { - SkeletonTree(n, dd, bs); // set up the basic stuff - pts = pa; // where the points are - if (n == 0) return; // no points--no sweat - - ANNorthRect bnd_box(dd); // bounding box for points - annEnclRect(pa, pidx, n, dd, bnd_box);// construct bounding rectangle - // copy to tree structure - bnd_box_lo = annCopyPt(dd, bnd_box.lo); - bnd_box_hi = annCopyPt(dd, bnd_box.hi); - - switch (split) { // build by rule - case ANN_KD_STD: // standard kd-splitting rule - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, kd_split); - break; - case ANN_KD_MIDPT: // midpoint split - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, midpt_split); - break; - case ANN_KD_FAIR: // fair split - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, fair_split); - break; - case ANN_KD_SUGGEST: // best (in our opinion) - case ANN_KD_SL_MIDPT: // sliding midpoint split - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, sl_midpt_split); - break; - case ANN_KD_SL_FAIR: // sliding fair split - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, sl_fair_split); - break; - default: - annError("Illegal splitting method", ANNabort); - } + SkeletonTree(n, dd, bs); // set up the basic stuff + pts = pa; // where the points are + if (n == 0) return; // no points--no sweat + + ANNorthRect bnd_box(dd); // bounding box for points + annEnclRect(pa, pidx, n, dd, bnd_box);// construct bounding rectangle + // copy to tree structure + bnd_box_lo = annCopyPt(dd, bnd_box.lo); + bnd_box_hi = annCopyPt(dd, bnd_box.hi); + + switch (split) { // build by rule + case ANN_KD_STD: // standard kd-splitting rule + root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, kd_split); + break; + case ANN_KD_MIDPT: // midpoint split + root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, midpt_split); + break; + case ANN_KD_FAIR: // fair split + root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, fair_split); + break; + case ANN_KD_SUGGEST: // best (in our opinion) + case ANN_KD_SL_MIDPT: // sliding midpoint split + root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, sl_midpt_split); + break; + case ANN_KD_SL_FAIR: // sliding fair split + root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, sl_fair_split); + break; + default: + annError("Illegal splitting method", ANNabort); + } } diff --git a/kNN/kd_tree.h b/kNN/kd_tree.h old mode 100644 new mode 100755 index 38521a68a..d52a622e2 --- a/kNN/kd_tree.h +++ b/kNN/kd_tree.h @@ -1,117 +1,197 @@ +//---------------------------------------------------------------------- +// File: kd_tree.h +// Programmer: Sunil Arya and David Mount +// Description: Declarations for standard kd-tree routines +// Last modified: 05/03/05 (Version 1.1) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.1 05/03/05 +// Added fixed radius kNN search +//---------------------------------------------------------------------- #ifndef ANN_kd_tree_H #define ANN_kd_tree_H -class ANNkd_node{ // generic kd-tree node (empty shell) +#include "ANN/ANNx.h" // all ANN includes + +using namespace std; // make std:: available + +//---------------------------------------------------------------------- +// Generic kd-tree node +// +// Nodes in kd-trees are of two types, splitting nodes which contain +// splitting information (a splitting hyperplane orthogonal to one +// of the coordinate axes) and leaf nodes which contain point +// information (an array of points stored in a bucket). This is +// handled by making a generic class kd_node, which is essentially an +// empty shell, and then deriving the leaf and splitting nodes from +// this. +//---------------------------------------------------------------------- + +class ANNkd_node{ // generic kd-tree node (empty shell) public: - virtual ~ANNkd_node() {} // virtual distroyer + virtual ~ANNkd_node() {} // virtual distroyer - virtual void ann_search(ANNdist, int) = 0; // tree search - virtual void ann_pri_search(ANNdist) = 0; // priority search + virtual void ann_search(ANNdist) = 0; // tree search + virtual void ann_pri_search(ANNdist) = 0; // priority search + virtual void ann_FR_search(ANNdist) = 0; // fixed-radius search + virtual void getStats( // get tree statistics + int dim, // dimension of space + ANNkdStats &st, // statistics + ANNorthRect &bnd_box) = 0; // bounding box + // print node + virtual void print(int level, ostream &out) = 0; + virtual void dump(ostream &out) = 0; // dump node - friend class ANNkd_tree; // allow kd-tree to access us + friend class ANNkd_tree; // allow kd-tree to access us }; -typedef void (*ANNkd_splitter)( // splitting routine for kd-trees - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) - -class ANNkd_leaf: public ANNkd_node // leaf node for kd-tree +//---------------------------------------------------------------------- +// kd-splitting function: +// kd_splitter is a pointer to a splitting routine for preprocessing. +// Different splitting procedures result in different strategies +// for building the tree. +//---------------------------------------------------------------------- + +typedef void (*ANNkd_splitter)( // splitting routine for kd-trees + ANNpointArray pa, // point array (unaltered) + ANNidxArray pidx, // point indices (permuted on return) + const ANNorthRect &bnds, // bounding rectangle for cell + int n, // number of points + int dim, // dimension of space + int &cut_dim, // cutting dimension (returned) + ANNcoord &cut_val, // cutting value (returned) + int &n_lo); // num of points on low side (returned) + +//---------------------------------------------------------------------- +// Leaf kd-tree node +// Leaf nodes of the kd-tree store the set of points associated +// with this bucket, stored as an array of point indices. These +// are indices in the array points, which resides with the +// root of the kd-tree. We also store the number of points +// that reside in this bucket. +//---------------------------------------------------------------------- + +class ANNkd_leaf: public ANNkd_node // leaf node for kd-tree { - int n_pts; // no. points in bucket - ANNidxArray bkt; // bucket of points + int n_pts; // no. points in bucket + ANNidxArray bkt; // bucket of points public: - ANNkd_leaf( // constructor - int n, // number of points - ANNidxArray b) // bucket - { - n_pts = n; // number of points in bucket - bkt = b; // the bucket - } - - ~ANNkd_leaf() { } // destructor (none) -// ANNkd_leaf::CalcLatLongDist(double lat1, double long1, double lat2, double long2) ; - - virtual void ann_search(ANNdist, int); // standard search routine - virtual void ann_pri_search(ANNdist); // priority search routine + ANNkd_leaf( // constructor + int n, // number of points + ANNidxArray b) // bucket + { + n_pts = n; // number of points in bucket + bkt = b; // the bucket + } + + ~ANNkd_leaf() { } // destructor (none) + + virtual void getStats( // get tree statistics + int dim, // dimension of space + ANNkdStats &st, // statistics + ANNorthRect &bnd_box); // bounding box + virtual void print(int level, ostream &out);// print node + virtual void dump(ostream &out); // dump node + + virtual void ann_search(ANNdist); // standard search + virtual void ann_pri_search(ANNdist); // priority search + virtual void ann_FR_search(ANNdist); // fixed-radius search }; //---------------------------------------------------------------------- -// KD_TRIVIAL is a special pointer to an empty leaf node. Since -// some splitting rules generate many (more than 50%) trivial -// leaves, we use this one shared node to save space. +// KD_TRIVIAL is a special pointer to an empty leaf node. Since +// some splitting rules generate many (more than 50%) trivial +// leaves, we use this one shared node to save space. // -// The pointer is initialized to NULL, but whenever a kd-tree is -// created, we allocate this node, if it has not already been -// allocated. This node is *never* deallocated, so it produces -// a small memory leak. +// The pointer is initialized to NULL, but whenever a kd-tree is +// created, we allocate this node, if it has not already been +// allocated. This node is *never* deallocated, so it produces +// a small memory leak. //---------------------------------------------------------------------- -extern ANNkd_leaf *KD_TRIVIAL; // trivial (empty) leaf node +extern ANNkd_leaf *KD_TRIVIAL; // trivial (empty) leaf node //---------------------------------------------------------------------- -// kd-tree splitting node. -// Splitting nodes contain a cutting dimension and a cutting value. -// These indicate the axis-parellel plane which subdivide the -// box for this node. The extent of the bounding box along the -// cutting dimension is maintained (this is used to speed up point -// to box distance calculations) [we do not store the entire bounding -// box since this may be wasteful of space in high dimensions]. -// We also store pointers to the 2 children. +// kd-tree splitting node. +// Splitting nodes contain a cutting dimension and a cutting value. +// These indicate the axis-parellel plane which subdivide the +// box for this node. The extent of the bounding box along the +// cutting dimension is maintained (this is used to speed up point +// to box distance calculations) [we do not store the entire bounding +// box since this may be wasteful of space in high dimensions]. +// We also store pointers to the 2 children. //---------------------------------------------------------------------- class ANNkd_split : public ANNkd_node // splitting node of a kd-tree { - int cut_dim; // dim orthogonal to cutting plane - ANNcoord cut_val; // location of cutting plane - ANNcoord cd_bnds[2]; // lower and upper bounds of - // rectangle along cut_dim - ANNkd_ptr child[2]; // left and right children + int cut_dim; // dim orthogonal to cutting plane + ANNcoord cut_val; // location of cutting plane + ANNcoord cd_bnds[2]; // lower and upper bounds of + // rectangle along cut_dim + ANNkd_ptr child[2]; // left and right children public: - ANNkd_split( // constructor - int cd, // cutting dimension - ANNcoord cv, // cutting value - ANNcoord lv, ANNcoord hv, // low and high values - ANNkd_ptr lc=NULL, ANNkd_ptr hc=NULL) // children - { - cut_dim = cd; // cutting dimension - cut_val = cv; // cutting value - cd_bnds[LO] = lv; // lower bound for rectangle - cd_bnds[HI] = hv; // upper bound for rectangle - child[LO] = lc; // left child - child[HI] = hc; // right child - } - - ~ANNkd_split() // destructor - { - if (child[LO]!= NULL && child[LO]!= KD_TRIVIAL) delete child[LO]; - child[LO] = NULL; - if (child[HI]!= NULL && child[HI]!= KD_TRIVIAL) delete child[HI]; - child[HI] = NULL; - } - - virtual void ann_search(ANNdist, int); // standard search routine - virtual void ann_pri_search(ANNdist); // priority search routine + ANNkd_split( // constructor + int cd, // cutting dimension + ANNcoord cv, // cutting value + ANNcoord lv, ANNcoord hv, // low and high values + ANNkd_ptr lc=NULL, ANNkd_ptr hc=NULL) // children + { + cut_dim = cd; // cutting dimension + cut_val = cv; // cutting value + cd_bnds[ANN_LO] = lv; // lower bound for rectangle + cd_bnds[ANN_HI] = hv; // upper bound for rectangle + child[ANN_LO] = lc; // left child + child[ANN_HI] = hc; // right child + } + + ~ANNkd_split() // destructor + { + if (child[ANN_LO]!= NULL && child[ANN_LO]!= KD_TRIVIAL) + delete child[ANN_LO]; + if (child[ANN_HI]!= NULL && child[ANN_HI]!= KD_TRIVIAL) + delete child[ANN_HI]; + } + + virtual void getStats( // get tree statistics + int dim, // dimension of space + ANNkdStats &st, // statistics + ANNorthRect &bnd_box); // bounding box + virtual void print(int level, ostream &out);// print node + virtual void dump(ostream &out); // dump node + + virtual void ann_search(ANNdist); // standard search + virtual void ann_pri_search(ANNdist); // priority search + virtual void ann_FR_search(ANNdist); // fixed-radius search }; //---------------------------------------------------------------------- -// External entry points +// External entry points //---------------------------------------------------------------------- -ANNkd_ptr rkd_tree( // recursive construction of kd-tree - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices to store in subtree - int n, // number of points - int dim, // dimension of space - int bsp, // bucket space - ANNorthRect &bnd_box, // bounding box for current node - ANNkd_splitter splitter); // splitting routine +ANNkd_ptr rkd_tree( // recursive construction of kd-tree + ANNpointArray pa, // point array (unaltered) + ANNidxArray pidx, // point indices to store in subtree + int n, // number of points + int dim, // dimension of space + int bsp, // bucket space + ANNorthRect &bnd_box, // bounding box for current node + ANNkd_splitter splitter); // splitting routine #endif diff --git a/kNN/kd_util.cpp b/kNN/kd_util.cpp old mode 100644 new mode 100755 index ae81d56e5..d131d808b --- a/kNN/kd_util.cpp +++ b/kNN/kd_util.cpp @@ -1,442 +1,439 @@ //---------------------------------------------------------------------- -// File: kd_util.cc -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Common utilities for kd-trees -// -// The following routines are utility functions for manipulating -// points sets, used in determining splitting planes for kd-tree -// construction. +// File: kd_util.cpp +// Programmer: Sunil Arya and David Mount +// Description: Common utilities for kd-trees +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. -// -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. //---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +//---------------------------------------------------------------------- + +#include "kd_util.h" // kd-utility declarations -#include "ANN.h" -#include "ANNx.h" // all ANN includes -#include "ANNperf.h" // performance evaluation -#include "kd_util.h" // kd-utility declarations +#include "ANN/ANNperf.h" // performance evaluation + +//---------------------------------------------------------------------- +// The following routines are utility functions for manipulating +// points sets, used in determining splitting planes for kd-tree +// construction. +//---------------------------------------------------------------------- //---------------------------------------------------------------------- -// NOTE: Virtually all point indexing is done through an -// index (i.e. permutation) array pidx. Consequently, -// a reference to the d-th coordinate of the i-th point -// is pa[pidx[i]][d]. The macro PA(i,d) is a shorthand -// for this. +// NOTE: Virtually all point indexing is done through an index (i.e. +// permutation) array pidx. Consequently, a reference to the d-th +// coordinate of the i-th point is pa[pidx[i]][d]. The macro PA(i,d) +// is a shorthand for this. //---------------------------------------------------------------------- - // standard 2-d indirect indexing -#define PA(i,d) (pa[pidx[(i)]][(d)]) - // accessing a single point -#define PP(i) (pa[pidx[(i)]]) + // standard 2-d indirect indexing +#define PA(i,d) (pa[pidx[(i)]][(d)]) + // accessing a single point +#define PP(i) (pa[pidx[(i)]]) //---------------------------------------------------------------------- -// annAspectRatio -// Compute the aspect ratio (ratio of longest to shortest side) -// of a rectangle. +// annAspectRatio +// Compute the aspect ratio (ratio of longest to shortest side) +// of a rectangle. //---------------------------------------------------------------------- double annAspectRatio( - int dim, // dimension - const ANNorthRect &bnd_box) // bounding cube + int dim, // dimension + const ANNorthRect &bnd_box) // bounding cube { - ANNcoord length = bnd_box.hi[0] - bnd_box.lo[0]; - ANNcoord min_length = length; // min side length - ANNcoord max_length = length; // max side length - for (int d = 0; d < dim; d++) { - length = bnd_box.hi[d] - bnd_box.lo[d]; - if (length < min_length) min_length = length; - if (length > max_length) max_length = length; - } - return max_length/min_length; + ANNcoord length = bnd_box.hi[0] - bnd_box.lo[0]; + ANNcoord min_length = length; // min side length + ANNcoord max_length = length; // max side length + for (int d = 0; d < dim; d++) { + length = bnd_box.hi[d] - bnd_box.lo[d]; + if (length < min_length) min_length = length; + if (length > max_length) max_length = length; + } + return max_length/min_length; } //---------------------------------------------------------------------- -// annEnclRect, annEnclCube -// These utilities compute the smallest rectangle and cube enclosing -// a set of points, respectively. +// annEnclRect, annEnclCube +// These utilities compute the smallest rectangle and cube enclosing +// a set of points, respectively. //---------------------------------------------------------------------- void annEnclRect( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension - ANNorthRect &bnds) // bounding cube (returned) + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int dim, // dimension + ANNorthRect &bnds) // bounding cube (returned) { - for (int d = 0; d < dim; d++) { // find smallest enclosing rectangle - ANNcoord lo_bnd = PA(0,d); // lower bound on dimension d - ANNcoord hi_bnd = PA(0,d); // upper bound on dimension d - for (int i = 0; i < n; i++) { - if (PA(i,d) < lo_bnd) lo_bnd = PA(i,d); - else if (PA(i,d) > hi_bnd) hi_bnd = PA(i,d); + for (int d = 0; d < dim; d++) { // find smallest enclosing rectangle + ANNcoord lo_bnd = PA(0,d); // lower bound on dimension d + ANNcoord hi_bnd = PA(0,d); // upper bound on dimension d + for (int i = 0; i < n; i++) { + if (PA(i,d) < lo_bnd) lo_bnd = PA(i,d); + else if (PA(i,d) > hi_bnd) hi_bnd = PA(i,d); + } + bnds.lo[d] = lo_bnd; + bnds.hi[d] = hi_bnd; } - bnds.lo[d] = lo_bnd; - bnds.hi[d] = hi_bnd; - } } -void annEnclCube( // compute smallest enclosing cube - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension - ANNorthRect &bnds) // bounding cube (returned) +void annEnclCube( // compute smallest enclosing cube + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int dim, // dimension + ANNorthRect &bnds) // bounding cube (returned) { - int d; - // compute smallest enclosing rect - annEnclRect(pa, pidx, n, dim, bnds); - - ANNcoord max_len = 0; // max length of any side - for (d = 0; d < dim; d++) { // determine max side length - ANNcoord len = bnds.hi[d] - bnds.lo[d]; - if (len > max_len) { // update max_len if longest - max_len = len; + int d; + // compute smallest enclosing rect + annEnclRect(pa, pidx, n, dim, bnds); + + ANNcoord max_len = 0; // max length of any side + for (d = 0; d < dim; d++) { // determine max side length + ANNcoord len = bnds.hi[d] - bnds.lo[d]; + if (len > max_len) { // update max_len if longest + max_len = len; + } + } + for (d = 0; d < dim; d++) { // grow sides to match max + ANNcoord len = bnds.hi[d] - bnds.lo[d]; + ANNcoord half_diff = (max_len - len) / 2; + bnds.lo[d] -= half_diff; + bnds.hi[d] += half_diff; } - } - for (d = 0; d < dim; d++) { // grow sides to match max - ANNcoord len = bnds.hi[d] - bnds.lo[d]; - ANNcoord half_diff = (max_len - len) / 2; - bnds.lo[d] -= half_diff; - bnds.hi[d] += half_diff; - } } //---------------------------------------------------------------------- -// annBoxDistance - utility routine which computes distance from point to -// box (Note: most distances to boxes are computed using incremental -// distance updates, not this function.) +// annBoxDistance - utility routine which computes distance from point to +// box (Note: most distances to boxes are computed using incremental +// distance updates, not this function.) //---------------------------------------------------------------------- -ANNdist annBoxDistance( // compute distance from point to box - const ANNpoint q, // the point - const ANNpoint lo, // low point of box - const ANNpoint hi, // high point of box - int dim) // dimension of space +ANNdist annBoxDistance( // compute distance from point to box + const ANNpoint q, // the point + const ANNpoint lo, // low point of box + const ANNpoint hi, // high point of box + int dim) // dimension of space { - register ANNdist dist = 0.0; // sum of squared distances - register ANNdist t; - - for (register int d = 0; d < dim; d++) - { - if (q[d] < lo[d]) - { // q is left of box - t = ANNdist(lo[d]) - ANNdist(q[d]); - dist = ANN_SUM(dist, ANN_POW(t)); + register ANNdist dist = 0.0; // sum of squared distances + register ANNdist t; + + for (register int d = 0; d < dim; d++) { + if (q[d] < lo[d]) { // q is left of box + t = ANNdist(lo[d]) - ANNdist(q[d]); + dist = ANN_SUM(dist, ANN_POW(t)); } - else if (q[d] > hi[d]) - { // q is right of box - t = ANNdist(q[d]) - ANNdist(hi[d]); - dist = ANN_SUM(dist, ANN_POW(t)); + else if (q[d] > hi[d]) { // q is right of box + t = ANNdist(q[d]) - ANNdist(hi[d]); + dist = ANN_SUM(dist, ANN_POW(t)); } } - FLOP(4*dim) // increment floating op count + ANN_FLOP(4*dim) // increment floating op count - return dist; + return dist; } //---------------------------------------------------------------------- -// annSpread - find spread along given dimension -// annMinMax - find min and max coordinates along given dimension -// annMaxSpread - find dimension of max spread +// annSpread - find spread along given dimension +// annMinMax - find min and max coordinates along given dimension +// annMaxSpread - find dimension of max spread //---------------------------------------------------------------------- -ANNcoord annSpread( // compute point spread along dimension - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int d) // dimension to check +ANNcoord annSpread( // compute point spread along dimension + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int d) // dimension to check { - ANNcoord min = PA(0,d); // compute max and min coords - ANNcoord max = PA(0,d); - for (int i = 1; i < n; i++) { - ANNcoord c = PA(i,d); - if (c < min) min = c; - else if (c > max) max = c; - } - return (max - min); // total spread is difference + ANNcoord min = PA(0,d); // compute max and min coords + ANNcoord max = PA(0,d); + for (int i = 1; i < n; i++) { + ANNcoord c = PA(i,d); + if (c < min) min = c; + else if (c > max) max = c; + } + return (max - min); // total spread is difference } -void annMinMax( // compute min and max coordinates along dim - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension to check - ANNcoord &min, // minimum value (returned) - ANNcoord &max) // maximum value (returned) +void annMinMax( // compute min and max coordinates along dim + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int d, // dimension to check + ANNcoord &min, // minimum value (returned) + ANNcoord &max) // maximum value (returned) { - min = PA(0,d); // compute max and min coords - max = PA(0,d); - for (int i = 1; i < n; i++) { - ANNcoord c = PA(i,d); - if (c < min) min = c; - else if (c > max) max = c; - } + min = PA(0,d); // compute max and min coords + max = PA(0,d); + for (int i = 1; i < n; i++) { + ANNcoord c = PA(i,d); + if (c < min) min = c; + else if (c > max) max = c; + } } -int annMaxSpread( // compute dimension of max spread - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim) // dimension of space +int annMaxSpread( // compute dimension of max spread + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int dim) // dimension of space { - int max_dim = 0; // dimension of max spread - ANNcoord max_spr = 0; // amount of max spread + int max_dim = 0; // dimension of max spread + ANNcoord max_spr = 0; // amount of max spread - if (n == 0) return max_dim; // no points, who cares? + if (n == 0) return max_dim; // no points, who cares? - for (int d = 0; d < dim; d++) { // compute spread along each dim - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spr) { // bigger than current max - max_spr = spr; - max_dim = d; + for (int d = 0; d < dim; d++) { // compute spread along each dim + ANNcoord spr = annSpread(pa, pidx, n, d); + if (spr > max_spr) { // bigger than current max + max_spr = spr; + max_dim = d; + } } - } - return max_dim; + return max_dim; } //---------------------------------------------------------------------- -// annMedianSplit - split point array about its median -// Splits a subarray of points pa[0..n] about an element of given -// rank (median: n_lo = n/2) with respect to dimension d. It places -// the element of rank n_lo-1 correctly (because our splitting rule -// takes the mean of these two). On exit, the array is permuted so -// that: +// annMedianSplit - split point array about its median +// Splits a subarray of points pa[0..n] about an element of given +// rank (median: n_lo = n/2) with respect to dimension d. It places +// the element of rank n_lo-1 correctly (because our splitting rule +// takes the mean of these two). On exit, the array is permuted so +// that: // -// pa[0..n_lo-2][d] <= pa[n_lo-1][d] <= pa[n_lo][d] <= pa[n_lo+1..n-1][d]. +// pa[0..n_lo-2][d] <= pa[n_lo-1][d] <= pa[n_lo][d] <= pa[n_lo+1..n-1][d]. // -// The mean of pa[n_lo-1][d] and pa[n_lo][d] is returned as the -// splitting value. +// The mean of pa[n_lo-1][d] and pa[n_lo][d] is returned as the +// splitting value. // -// All indexing is done indirectly through the index array pidx. +// All indexing is done indirectly through the index array pidx. // -// This function uses the well known selection algorithm due to -// C.A.R. Hoare. +// This function uses the well known selection algorithm due to +// C.A.R. Hoare. //---------------------------------------------------------------------- - // swap two points in pa array -#define PASWAP(a,b) { int tmp = pidx[a];\ - pidx[a] = pidx[b];\ - pidx[b] = tmp; } + + // swap two points in pa array +#define PASWAP(a,b) { int tmp = pidx[a]; pidx[a] = pidx[b]; pidx[b] = tmp; } void annMedianSplit( - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord &cv, // cutting value - int n_lo) // split into n_lo and n-n_lo + ANNpointArray pa, // points to split + ANNidxArray pidx, // point indices + int n, // number of points + int d, // dimension along which to split + ANNcoord &cv, // cutting value + int n_lo) // split into n_lo and n-n_lo { - int l = 0; // left end of current subarray - int r = n-1; // right end of current subarray - while (l < r) { - register int i = (r+l)/2; // select middle as pivot - register int k; - - if (PA(i,d) > PA(r,d)) // make sure last > pivot - PASWAP(i,r) - PASWAP(l,i); // move pivot to first position - - ANNcoord c = PA(l,d); // pivot value - i = l; - k = r; - for(;;) { // pivot about c - while (PA(++i,d) < c) ; - while (PA(--k,d) > c) ; - if (i < k) PASWAP(i,k) else break; + int l = 0; // left end of current subarray + int r = n-1; // right end of current subarray + while (l < r) { + register int i = (r+l)/2; // select middle as pivot + register int k; + + if (PA(i,d) > PA(r,d)) // make sure last > pivot + PASWAP(i,r) + PASWAP(l,i); // move pivot to first position + + ANNcoord c = PA(l,d); // pivot value + i = l; + k = r; + for(;;) { // pivot about c + while (PA(++i,d) < c) ; + while (PA(--k,d) > c) ; + if (i < k) PASWAP(i,k) else break; + } + PASWAP(l,k); // pivot winds up in location k + + if (k > n_lo) r = k-1; // recurse on proper subarray + else if (k < n_lo) l = k+1; + else break; // got the median exactly } - PASWAP(l,k); // pivot winds up in location k - - if (k > n_lo) r = k-1; // recurse on proper subarray - else if (k < n_lo) l = k+1; - else break; // got the median exactly - } - if (n_lo > 0) { // search for next smaller item - ANNcoord c = PA(0,d); // candidate for max - int k = 0; // candidate's index - for (int i = 1; i < n_lo; i++) { - if (PA(i,d) > c) { - c = PA(i,d); - k = i; - } + if (n_lo > 0) { // search for next smaller item + ANNcoord c = PA(0,d); // candidate for max + int k = 0; // candidate's index + for (int i = 1; i < n_lo; i++) { + if (PA(i,d) > c) { + c = PA(i,d); + k = i; + } + } + PASWAP(n_lo-1, k); // max among pa[0..n_lo-1] to pa[n_lo-1] } - PASWAP(n_lo-1, k); // max among pa[0..n_lo-1] to pa[n_lo-1] - } - // cut value is midpoint value - cv = (PA(n_lo-1,d) + PA(n_lo,d))/2.0; + // cut value is midpoint value + cv = (PA(n_lo-1,d) + PA(n_lo,d))/2.0; } //---------------------------------------------------------------------- -// annPlaneSplit - split point array about a cutting plane -// Split the points in an array about a given plane along a -// given cutting dimension. On exit, br1 and br2 are set so -// that: -// -// pa[ 0 ..br1-1] < cv -// pa[br1..br2-1] == cv -// pa[br2.. n -1] > cv +// annPlaneSplit - split point array about a cutting plane +// Split the points in an array about a given plane along a +// given cutting dimension. On exit, br1 and br2 are set so +// that: +// +// pa[ 0 ..br1-1] < cv +// pa[br1..br2-1] == cv +// pa[br2.. n -1] > cv // -// All indexing is done indirectly through the index array pidx. +// All indexing is done indirectly through the index array pidx. // //---------------------------------------------------------------------- -void annPlaneSplit( // split points by a plane - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord cv, // cutting value - int &br1, // first break (values < cv) - int &br2) // second break (values == cv) +void annPlaneSplit( // split points by a plane + ANNpointArray pa, // points to split + ANNidxArray pidx, // point indices + int n, // number of points + int d, // dimension along which to split + ANNcoord cv, // cutting value + int &br1, // first break (values < cv) + int &br2) // second break (values == cv) { - int l = 0; - int r = n-1; - for(;;) { // partition pa[0..n-1] about cv - while (l < n && PA(l,d) < cv) l++; - while (r >= 0 && PA(r,d) >= cv) r--; - if (l > r) break; - PASWAP(l,r); - l++; r--; - } - br1 = l; // now: pa[0..br1-1] < cv <= pa[br1..n-1] - r = n-1; - for(;;) { // partition pa[br1..n-1] about cv - while (l < n && PA(l,d) <= cv) l++; - while (r >= br1 && PA(r,d) > cv) r--; - if (l > r) break; - PASWAP(l,r); - l++; r--; - } - br2 = l; // now: pa[br1..br2-1] == cv < pa[br2..n-1] + int l = 0; + int r = n-1; + for(;;) { // partition pa[0..n-1] about cv + while (l < n && PA(l,d) < cv) l++; + while (r >= 0 && PA(r,d) >= cv) r--; + if (l > r) break; + PASWAP(l,r); + l++; r--; + } + br1 = l; // now: pa[0..br1-1] < cv <= pa[br1..n-1] + r = n-1; + for(;;) { // partition pa[br1..n-1] about cv + while (l < n && PA(l,d) <= cv) l++; + while (r >= br1 && PA(r,d) > cv) r--; + if (l > r) break; + PASWAP(l,r); + l++; r--; + } + br2 = l; // now: pa[br1..br2-1] == cv < pa[br2..n-1] } //---------------------------------------------------------------------- -// annBoxSplit - split point array about a orthogonal rectangle -// Split the points in an array about a given orthogonal -// rectangle. On exit, n_in is set to the number of points -// that are inside (or on the boundary of) the rectangle. +// annBoxSplit - split point array about a orthogonal rectangle +// Split the points in an array about a given orthogonal +// rectangle. On exit, n_in is set to the number of points +// that are inside (or on the boundary of) the rectangle. // -// All indexing is done indirectly through the index array pidx. +// All indexing is done indirectly through the index array pidx. // //---------------------------------------------------------------------- -void annBoxSplit( // split points by a box - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension of space - ANNorthRect &box, // the box - int &n_in) // number of points inside (returned) +void annBoxSplit( // split points by a box + ANNpointArray pa, // points to split + ANNidxArray pidx, // point indices + int n, // number of points + int dim, // dimension of space + ANNorthRect &box, // the box + int &n_in) // number of points inside (returned) { - int l = 0; - int r = n-1; - for(;;) { // partition pa[0..n-1] about box - while (l < n && box.inside(dim, PP(l))) l++; - while (r >= 0 && !box.inside(dim, PP(r))) r--; - if (l > r) break; - PASWAP(l,r); - l++; r--; - } - n_in = l; // now: pa[0..n_in-1] inside and rest outside + int l = 0; + int r = n-1; + for(;;) { // partition pa[0..n-1] about box + while (l < n && box.inside(dim, PP(l))) l++; + while (r >= 0 && !box.inside(dim, PP(r))) r--; + if (l > r) break; + PASWAP(l,r); + l++; r--; + } + n_in = l; // now: pa[0..n_in-1] inside and rest outside } //---------------------------------------------------------------------- -// annSplitBalance - compute balance factor for a given plane split -// Balance factor is defined as the number of points lying -// below the splitting value minus n/2 (median). Thus, a -// median split has balance 0, left of this is negative and -// right of this is positive. (The points are unchanged.) +// annSplitBalance - compute balance factor for a given plane split +// Balance factor is defined as the number of points lying +// below the splitting value minus n/2 (median). Thus, a +// median split has balance 0, left of this is negative and +// right of this is positive. (The points are unchanged.) //---------------------------------------------------------------------- -int annSplitBalance( // determine balance factor of a split - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord cv) // cutting value +int annSplitBalance( // determine balance factor of a split + ANNpointArray pa, // points to split + ANNidxArray pidx, // point indices + int n, // number of points + int d, // dimension along which to split + ANNcoord cv) // cutting value { - int n_lo = 0; - for(int i = 0; i < n; i++) { // count number less than cv - if (PA(i,d) < cv) n_lo++; - } - return n_lo - n/2; + int n_lo = 0; + for(int i = 0; i < n; i++) { // count number less than cv + if (PA(i,d) < cv) n_lo++; + } + return n_lo - n/2; } //---------------------------------------------------------------------- -// annBox2Bnds - convert bounding box to list of bounds -// Given two boxes, an inner box enclosed within a bounding -// box, this routine determines all the sides for which the -// inner box is strictly contained with the bounding box, -// and adds an appropriate entry to a list of bounds. Then -// we allocate storage for the final list of bounds, and return -// the resulting list and its size. +// annBox2Bnds - convert bounding box to list of bounds +// Given two boxes, an inner box enclosed within a bounding +// box, this routine determines all the sides for which the +// inner box is strictly contained with the bounding box, +// and adds an appropriate entry to a list of bounds. Then +// we allocate storage for the final list of bounds, and return +// the resulting list and its size. //---------------------------------------------------------------------- -void annBox2Bnds( // convert inner box to bounds - const ANNorthRect &inner_box, // inner box - const ANNorthRect &bnd_box, // enclosing box - int dim, // dimension of space - int &n_bnds, // number of bounds (returned) - ANNorthHSArray &bnds) // bounds array (returned) +void annBox2Bnds( // convert inner box to bounds + const ANNorthRect &inner_box, // inner box + const ANNorthRect &bnd_box, // enclosing box + int dim, // dimension of space + int &n_bnds, // number of bounds (returned) + ANNorthHSArray &bnds) // bounds array (returned) { - int i; - n_bnds = 0; // count number of bounds - for (i = 0; i < dim; i++) { - if (inner_box.lo[i] > bnd_box.lo[i]) // low bound is inside - n_bnds++; - if (inner_box.hi[i] < bnd_box.hi[i]) // high bound is inside - n_bnds++; - } - - bnds = new ANNorthHalfSpace[n_bnds]; // allocate appropriate size - - int j = 0; - for (i = 0; i < dim; i++) { // fill the array - if (inner_box.lo[i] > bnd_box.lo[i]) { - bnds[j].cd = i; - bnds[j].cv = inner_box.lo[i]; - bnds[j].sd = +1; - j++; + int i; + n_bnds = 0; // count number of bounds + for (i = 0; i < dim; i++) { + if (inner_box.lo[i] > bnd_box.lo[i]) // low bound is inside + n_bnds++; + if (inner_box.hi[i] < bnd_box.hi[i]) // high bound is inside + n_bnds++; } - if (inner_box.hi[i] < bnd_box.hi[i]) { - bnds[j].cd = i; - bnds[j].cv = inner_box.hi[i]; - bnds[j].sd = -1; - j++; + + bnds = new ANNorthHalfSpace[n_bnds]; // allocate appropriate size + + int j = 0; + for (i = 0; i < dim; i++) { // fill the array + if (inner_box.lo[i] > bnd_box.lo[i]) { + bnds[j].cd = i; + bnds[j].cv = inner_box.lo[i]; + bnds[j].sd = +1; + j++; + } + if (inner_box.hi[i] < bnd_box.hi[i]) { + bnds[j].cd = i; + bnds[j].cv = inner_box.hi[i]; + bnds[j].sd = -1; + j++; + } } - } } //---------------------------------------------------------------------- -// annBnds2Box - convert list of bounds to bounding box -// Given an enclosing box and a list of bounds, this routine -// computes the corresponding inner box. It is assumed that -// the box points have been allocated already. +// annBnds2Box - convert list of bounds to bounding box +// Given an enclosing box and a list of bounds, this routine +// computes the corresponding inner box. It is assumed that +// the box points have been allocated already. //---------------------------------------------------------------------- void annBnds2Box( - const ANNorthRect &bnd_box, // enclosing box - int dim, // dimension of space - int n_bnds, // number of bounds - ANNorthHSArray bnds, // bounds array - ANNorthRect &inner_box) // inner box (returned) + const ANNorthRect &bnd_box, // enclosing box + int dim, // dimension of space + int n_bnds, // number of bounds + ANNorthHSArray bnds, // bounds array + ANNorthRect &inner_box) // inner box (returned) { - annAssignRect(dim, inner_box, bnd_box); // copy bounding box to inner + annAssignRect(dim, inner_box, bnd_box); // copy bounding box to inner - for (int i = 0; i < n_bnds; i++) { - bnds[i].project(inner_box.lo); // project each endpoint - bnds[i].project(inner_box.hi); - } + for (int i = 0; i < n_bnds; i++) { + bnds[i].project(inner_box.lo); // project each endpoint + bnds[i].project(inner_box.hi); + } } diff --git a/kNN/kd_util.h b/kNN/kd_util.h old mode 100644 new mode 100755 index c923e23b8..da7f732f8 --- a/kNN/kd_util.h +++ b/kNN/kd_util.h @@ -1,123 +1,124 @@ //---------------------------------------------------------------------- -// File: kd_util.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Common utilities for kd- trees +// File: kd_util.h +// Programmer: Sunil Arya and David Mount +// Description: Common utilities for kd- trees +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release //---------------------------------------------------------------------- #ifndef ANN_kd_util_H #define ANN_kd_util_H -#include "kd_tree.h" // kd-tree declarations +#include "kd_tree.h" // kd-tree declarations //---------------------------------------------------------------------- -// externally accessible functions +// externally accessible functions //---------------------------------------------------------------------- -double annAspectRatio( // compute aspect ratio of box - int dim, // dimension - const ANNorthRect &bnd_box); // bounding cube - -void annEnclRect( // compute smallest enclosing rectangle - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension - ANNorthRect &bnds); // bounding cube (returned) - -void annEnclCube( // compute smallest enclosing cube - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension - ANNorthRect &bnds); // bounding cube (returned) - -ANNdist annBoxDistance( // compute distance from point to box - const ANNpoint q, // the point - const ANNpoint lo, // low point of box - const ANNpoint hi, // high point of box - int dim); // dimension of space - -ANNcoord annSpread( // compute point spread along dimension - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int d); // dimension to check - -void annMinMax( // compute min and max coordinates along dim - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension to check - ANNcoord& min, // minimum value (returned) - ANNcoord& max); // maximum value (returned) - -int annMaxSpread( // compute dimension of max spread - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim); // dimension of space - -void annMedianSplit( // split points along median value - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord &cv, // cutting value - int n_lo); // split into n_lo and n-n_lo - -void annPlaneSplit( // split points by a plane - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord cv, // cutting value - int &br1, // first break (values < cv) - int &br2); // second break (values == cv) - -void annBoxSplit( // split points by a box - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension of space - ANNorthRect &box, // the box - int &n_in); // number of points inside (returned) - -int annSplitBalance( // determine balance factor of a split - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord cv); // cutting value - -void annBox2Bnds( // convert inner box to bounds - const ANNorthRect &inner_box, // inner box - const ANNorthRect &bnd_box, // enclosing box - int dim, // dimension of space - int &n_bnds, // number of bounds (returned) - ANNorthHSArray &bnds); // bounds array (returned) - -void annBnds2Box( // convert bounds to inner box - const ANNorthRect &bnd_box, // enclosing box - int dim, // dimension of space - int n_bnds, // number of bounds - ANNorthHSArray bnds, // bounds array - ANNorthRect &inner_box); // inner box (returned) +double annAspectRatio( // compute aspect ratio of box + int dim, // dimension + const ANNorthRect &bnd_box); // bounding cube + +void annEnclRect( // compute smallest enclosing rectangle + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int dim, // dimension + ANNorthRect &bnds); // bounding cube (returned) + +void annEnclCube( // compute smallest enclosing cube + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int dim, // dimension + ANNorthRect &bnds); // bounding cube (returned) + +ANNdist annBoxDistance( // compute distance from point to box + const ANNpoint q, // the point + const ANNpoint lo, // low point of box + const ANNpoint hi, // high point of box + int dim); // dimension of space + +ANNcoord annSpread( // compute point spread along dimension + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int d); // dimension to check + +void annMinMax( // compute min and max coordinates along dim + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int d, // dimension to check + ANNcoord& min, // minimum value (returned) + ANNcoord& max); // maximum value (returned) + +int annMaxSpread( // compute dimension of max spread + ANNpointArray pa, // point array + ANNidxArray pidx, // point indices + int n, // number of points + int dim); // dimension of space + +void annMedianSplit( // split points along median value + ANNpointArray pa, // points to split + ANNidxArray pidx, // point indices + int n, // number of points + int d, // dimension along which to split + ANNcoord &cv, // cutting value + int n_lo); // split into n_lo and n-n_lo + +void annPlaneSplit( // split points by a plane + ANNpointArray pa, // points to split + ANNidxArray pidx, // point indices + int n, // number of points + int d, // dimension along which to split + ANNcoord cv, // cutting value + int &br1, // first break (values < cv) + int &br2); // second break (values == cv) + +void annBoxSplit( // split points by a box + ANNpointArray pa, // points to split + ANNidxArray pidx, // point indices + int n, // number of points + int dim, // dimension of space + ANNorthRect &box, // the box + int &n_in); // number of points inside (returned) + +int annSplitBalance( // determine balance factor of a split + ANNpointArray pa, // points to split + ANNidxArray pidx, // point indices + int n, // number of points + int d, // dimension along which to split + ANNcoord cv); // cutting value + +void annBox2Bnds( // convert inner box to bounds + const ANNorthRect &inner_box, // inner box + const ANNorthRect &bnd_box, // enclosing box + int dim, // dimension of space + int &n_bnds, // number of bounds (returned) + ANNorthHSArray &bnds); // bounds array (returned) + +void annBnds2Box( // convert bounds to inner box + const ANNorthRect &bnd_box, // enclosing box + int dim, // dimension of space + int n_bnds, // number of bounds + ANNorthHSArray bnds, // bounds array + ANNorthRect &inner_box); // inner box (returned) #endif diff --git a/kNN/perf.cpp b/kNN/perf.cpp new file mode 100755 index 000000000..1b412f237 --- /dev/null +++ b/kNN/perf.cpp @@ -0,0 +1,136 @@ +//---------------------------------------------------------------------- +// File: perf.cpp +// Programmer: Sunil Arya and David Mount +// Description: Methods for performance stats +// Last modified: 01/27/10 (Version 1.1.2) +//---------------------------------------------------------------------- +// Copyright (c) 1997-2010 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. +// +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. +// +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release +// Revision 1.0 04/01/05 +// Changed names to avoid namespace conflicts. +// Added flush after printing performance stats to fix bug +// in Microsoft Windows version. +// Revision 1.1.2 01/27/10 +// Fixed minor compilation bugs for new versions of gcc +//---------------------------------------------------------------------- + +#include // basic ANN includes +#include // performance includes + +using namespace std; // make std:: available + +//---------------------------------------------------------------------- +// Performance statistics +// The following data and routines are used for computing +// performance statistics for nearest neighbor searching. +// Because these routines can slow the code down, they can be +// activated and deactiviated by defining the PERF variable, +// by compiling with the option: -DPERF +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// Global counters for performance measurement +//---------------------------------------------------------------------- + +int ann_Ndata_pts = 0; // number of data points +int ann_Nvisit_lfs = 0; // number of leaf nodes visited +int ann_Nvisit_spl = 0; // number of splitting nodes visited +int ann_Nvisit_shr = 0; // number of shrinking nodes visited +int ann_Nvisit_pts = 0; // visited points for one query +int ann_Ncoord_hts = 0; // coordinate hits for one query +int ann_Nfloat_ops = 0; // floating ops for one query +ANNsampStat ann_visit_lfs; // stats on leaf nodes visits +ANNsampStat ann_visit_spl; // stats on splitting nodes visits +ANNsampStat ann_visit_shr; // stats on shrinking nodes visits +ANNsampStat ann_visit_nds; // stats on total nodes visits +ANNsampStat ann_visit_pts; // stats on points visited +ANNsampStat ann_coord_hts; // stats on coordinate hits +ANNsampStat ann_float_ops; // stats on floating ops +// +ANNsampStat ann_average_err; // average error +ANNsampStat ann_rank_err; // rank error + +//---------------------------------------------------------------------- +// Routines for statistics. +//---------------------------------------------------------------------- + +DLL_API void annResetStats(int data_size) // reset stats for a set of queries +{ + ann_Ndata_pts = data_size; + ann_visit_lfs.reset(); + ann_visit_spl.reset(); + ann_visit_shr.reset(); + ann_visit_nds.reset(); + ann_visit_pts.reset(); + ann_coord_hts.reset(); + ann_float_ops.reset(); + ann_average_err.reset(); + ann_rank_err.reset(); +} + +DLL_API void annResetCounts() // reset counts for one query +{ + ann_Nvisit_lfs = 0; + ann_Nvisit_spl = 0; + ann_Nvisit_shr = 0; + ann_Nvisit_pts = 0; + ann_Ncoord_hts = 0; + ann_Nfloat_ops = 0; +} + +DLL_API void annUpdateStats() // update stats with current counts +{ + ann_visit_lfs += ann_Nvisit_lfs; + ann_visit_nds += ann_Nvisit_spl + ann_Nvisit_lfs; + ann_visit_spl += ann_Nvisit_spl; + ann_visit_shr += ann_Nvisit_shr; + ann_visit_pts += ann_Nvisit_pts; + ann_coord_hts += ann_Ncoord_hts; + ann_float_ops += ann_Nfloat_ops; +} + + // print a single statistic +void print_one_stat(const char* title, ANNsampStat s, double div) +{ + cout << title << "= [ "; + cout.width(9); cout << s.mean()/div << " : "; + cout.width(9); cout << s.stdDev()/div << " ]<"; + cout.width(9); cout << s.min()/div << " , "; + cout.width(9); cout << s.max()/div << " >\n"; +} + +DLL_API void annPrintStats( // print statistics for a run + ANNbool validate) // true if average errors desired +{ + cout.precision(4); // set floating precision + cout << " (Performance stats: " + << " [ mean : stddev ]< min , max >\n"; + print_one_stat(" leaf_nodes ", ann_visit_lfs, 1); + print_one_stat(" splitting_nodes ", ann_visit_spl, 1); + print_one_stat(" shrinking_nodes ", ann_visit_shr, 1); + print_one_stat(" total_nodes ", ann_visit_nds, 1); + print_one_stat(" points_visited ", ann_visit_pts, 1); + print_one_stat(" coord_hits/pt ", ann_coord_hts, ann_Ndata_pts); + print_one_stat(" floating_ops_(K) ", ann_float_ops, 1000); + if (validate) { + print_one_stat(" average_error ", ann_average_err, 1); + print_one_stat(" rank_error ", ann_rank_err, 1); + } + cout.precision(0); // restore the default + cout << " )\n"; + cout.flush(); +} diff --git a/kNN/pr_queue.h b/kNN/pr_queue.h old mode 100644 new mode 100755 index afc44d964..a1634dd4b --- a/kNN/pr_queue.h +++ b/kNN/pr_queue.h @@ -1,121 +1,125 @@ //---------------------------------------------------------------------- -// File: pr_queue.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Include file for priority queue and related -// structures. +// File: pr_queue.h +// Programmer: Sunil Arya and David Mount +// Description: Include file for priority queue and related +// structures. +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release //---------------------------------------------------------------------- #ifndef PR_QUEUE_H #define PR_QUEUE_H +#include "ANN/ANNx.h" // all ANN includes +#include "ANN/ANNperf.h" // performance evaluation + //---------------------------------------------------------------------- -// Basic types. +// Basic types. //---------------------------------------------------------------------- -typedef void *PQinfo; // info field is generic pointer -typedef ANNdist PQkey; // key field is distance +typedef void *PQinfo; // info field is generic pointer +typedef ANNdist PQkey; // key field is distance //---------------------------------------------------------------------- -// Priority queue -// A priority queue is a list of items, along with associated -// priorities. The basic operations are insert and extract_minimum. +// Priority queue +// A priority queue is a list of items, along with associated +// priorities. The basic operations are insert and extract_minimum. // -// The priority queue is maintained using a standard binary heap. -// (Implementation note: Indexing is performed from [1..max] rather -// than the C standard of [0..max-1]. This simplifies parent/child -// computations.) User information consists of a void pointer, -// and the user is responsible for casting this quantity into whatever -// useful form is desired. +// The priority queue is maintained using a standard binary heap. +// (Implementation note: Indexing is performed from [1..max] rather +// than the C standard of [0..max-1]. This simplifies parent/child +// computations.) User information consists of a void pointer, +// and the user is responsible for casting this quantity into whatever +// useful form is desired. // -// Because the priority queue is so mean_center to the efficiency of -// query processing, all the code is inline. +// Because the priority queue is so central to the efficiency of +// query processing, all the code is inline. //---------------------------------------------------------------------- class ANNpr_queue { - struct pq_node { // node in priority queue - PQkey key; // key value - PQinfo info; // info field - }; - int n; // number of items in queue - int max_size; // maximum queue size - pq_node *pq; // the priority queue (array of nodes) + struct pq_node { // node in priority queue + PQkey key; // key value + PQinfo info; // info field + }; + int n; // number of items in queue + int max_size; // maximum queue size + pq_node *pq; // the priority queue (array of nodes) public: - ANNpr_queue(int max) // constructor (given max size) - { - n = 0; // initially empty - max_size = max; // maximum number of items - pq = new pq_node[max+1]; // queue is array [1..max] of nodes - } + ANNpr_queue(int max) // constructor (given max size) + { + n = 0; // initially empty + max_size = max; // maximum number of items + pq = new pq_node[max+1]; // queue is array [1..max] of nodes + } - ~ANNpr_queue() // destructor - { delete [] pq; } + ~ANNpr_queue() // destructor + { delete [] pq; } - ANNbool empty() // is queue empty? - { if (n==0) return ANNtrue; else return ANNfalse; } + ANNbool empty() // is queue empty? + { if (n==0) return ANNtrue; else return ANNfalse; } - ANNbool non_empty() // is queue nonempty? - { if (n==0) return ANNfalse; else return ANNtrue; } + ANNbool non_empty() // is queue nonempty? + { if (n==0) return ANNfalse; else return ANNtrue; } - void reset() // make existing queue empty - { n = 0; } + void reset() // make existing queue empty + { n = 0; } - inline void insert( // insert item (inlined for speed) - PQkey kv, // key value - PQinfo inf) // item info - { - if (++n > max_size) annError("Priority queue overflow.", ANNabort); - register int r = n; - while (r > 1) { // sift up new item - register int p = r/2; - FLOP(1) // increment floating ops - if (pq[p].key <= kv) // in proper order - break; - pq[r] = pq[p]; // else swap with parent - r = p; - } - pq[r].key = kv; // insert new item at final location - pq[r].info = inf; - } + inline void insert( // insert item (inlined for speed) + PQkey kv, // key value + PQinfo inf) // item info + { + if (++n > max_size) annError("Priority queue overflow.", ANNabort); + register int r = n; + while (r > 1) { // sift up new item + register int p = r/2; + ANN_FLOP(1) // increment floating ops + if (pq[p].key <= kv) // in proper order + break; + pq[r] = pq[p]; // else swap with parent + r = p; + } + pq[r].key = kv; // insert new item at final location + pq[r].info = inf; + } - inline void extr_min( // extract minimum (inlined for speed) - PQkey &kv, // key (returned) - PQinfo &inf) // item info (returned) - { - kv = pq[1].key; // key of min item - inf = pq[1].info; // information of min item - register PQkey kn = pq[n--].key;// last item in queue - register int p = 1; // p points to item out of position - register int r = p<<1; // left child of p - while (r <= n) { // while r is still within the heap - FLOP(2) // increment floating ops - // set r to smaller child of p - if (r < n && pq[r].key > pq[r+1].key) r++; - if (kn <= pq[r].key) // in proper order - break; - pq[p] = pq[r]; // else swap with child - p = r; // advance pointers - r = p<<1; - } - pq[p] = pq[n+1]; // insert last item in proper place - } + inline void extr_min( // extract minimum (inlined for speed) + PQkey &kv, // key (returned) + PQinfo &inf) // item info (returned) + { + kv = pq[1].key; // key of min item + inf = pq[1].info; // information of min item + register PQkey kn = pq[n--].key;// last item in queue + register int p = 1; // p points to item out of position + register int r = p<<1; // left child of p + while (r <= n) { // while r is still within the heap + ANN_FLOP(2) // increment floating ops + // set r to smaller child of p + if (r < n && pq[r].key > pq[r+1].key) r++; + if (kn <= pq[r].key) // in proper order + break; + pq[p] = pq[r]; // else swap with child + p = r; // advance pointers + r = p<<1; + } + pq[p] = pq[n+1]; // insert last item in proper place + } }; #endif diff --git a/kNN/pr_queue_k.h b/kNN/pr_queue_k.h old mode 100644 new mode 100755 index 3bd6c2762..1649116dd --- a/kNN/pr_queue_k.h +++ b/kNN/pr_queue_k.h @@ -1,110 +1,118 @@ //---------------------------------------------------------------------- -// File: pr_queue_k.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Include file for priority queue with k items. +// File: pr_queue_k.h +// Programmer: Sunil Arya and David Mount +// Description: Include file for priority queue with k items. +// Last modified: 01/04/05 (Version 1.0) //---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. +// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and +// David Mount. All Rights Reserved. // -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). +// This software and related documentation is part of the Approximate +// Nearest Neighbor Library (ANN). This software is provided under +// the provisions of the Lesser GNU Public License (LGPL). See the +// file ../ReadMe.txt for further information. // -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. +// The University of Maryland (U.M.) and the authors make no +// representations about the suitability or fitness of this software for +// any purpose. It is provided "as is" without express or implied +// warranty. +//---------------------------------------------------------------------- +// History: +// Revision 0.1 03/04/98 +// Initial release //---------------------------------------------------------------------- #ifndef PR_QUEUE_K_H #define PR_QUEUE_K_H +#include "ANN/ANNx.h" // all ANN includes +#include "ANN/ANNperf.h" // performance evaluation //---------------------------------------------------------------------- -// Basic types +// Basic types //---------------------------------------------------------------------- -typedef ANNdist PQKkey; // key field is distance -typedef int PQKinfo; // info field is int +typedef ANNdist PQKkey; // key field is distance +typedef int PQKinfo; // info field is int //---------------------------------------------------------------------- -// Constants +// Constants +// The NULL key value is used to initialize the priority queue, and +// so it should be larger than any valid distance, so that it will +// be replaced as legal distance values are inserted. The NULL +// info value must be a nonvalid array index, we use ANN_NULL_IDX, +// which is guaranteed to be negative. //---------------------------------------------------------------------- const PQKkey PQ_NULL_KEY = ANN_DIST_INF; // nonexistent key value -const PQKinfo PQ_NULL_INFO = -1; // nonexistent info value +const PQKinfo PQ_NULL_INFO = ANN_NULL_IDX; // nonexistent info value //---------------------------------------------------------------------- -// ANNmin_k -// An ANNmin_k structure is one which maintains the smallest -// k values (of type PQKkey) and associated information (of type -// PQKinfo). The special info and key values PQ_NULL_INFO and -// PQ_NULL_KEY means that thise entry is empty. +// ANNmin_k +// An ANNmin_k structure is one which maintains the smallest +// k values (of type PQKkey) and associated information (of type +// PQKinfo). The special info and key values PQ_NULL_INFO and +// PQ_NULL_KEY means that thise entry is empty. // -// It is currently implemented using an array with k items. -// Items are stored in increasing sorted order, and insertions -// are made through standard insertion sort. (This is quite -// inefficient, but current applications call for small values -// of k and relatively few insertions.) +// It is currently implemented using an array with k items. +// Items are stored in increasing sorted order, and insertions +// are made through standard insertion sort. (This is quite +// inefficient, but current applications call for small values +// of k and relatively few insertions.) +// +// Note that the list contains k+1 entries, but the last entry +// is used as a simple placeholder and is otherwise ignored. //---------------------------------------------------------------------- -class ANNmin_k -{ - struct mk_node { // node in min_k structure - PQKkey key; // key value - PQKinfo info; // info field (user defined) - }; +class ANNmin_k { + struct mk_node { // node in min_k structure + PQKkey key; // key value + PQKinfo info; // info field (user defined) + }; - int k; // max number of keys to store - int n; // number of keys currently active - mk_node *mk; // the list itself + int k; // max number of keys to store + int n; // number of keys currently active + mk_node *mk; // the list itself public: - ANNmin_k(int max) // constructor (given max size) - { - n = 0; // initially no items - k = max; // maximum number of items - mk = new mk_node[max+1]; // sorted array of keys - } - - ~ANNmin_k() // destructor - { delete [] mk; } - - PQKkey ANNmin_key() // return minimum key - { return (n > 0 ? mk[0].key : PQ_NULL_KEY); } - - PQKkey max_key() // return maximum key - { return (n == k ? mk[k-1].key : PQ_NULL_KEY); } - - PQKkey ith_smallest_key(int i) // ith smallest key (i in [0..n-1]) - { return (i < n ? mk[i].key : PQ_NULL_KEY); } - - PQKinfo ith_smallest_info(int i) // info for ith smallest (i in [0..n-1]) - { return (i < n ? mk[i].info : PQ_NULL_INFO); } + ANNmin_k(int max) // constructor (given max size) + { + n = 0; // initially no items + k = max; // maximum number of items + mk = new mk_node[max+1]; // sorted array of keys + } + ~ANNmin_k() // destructor + { delete [] mk; } + + PQKkey ANNmin_key() // return minimum key + { return (n > 0 ? mk[0].key : PQ_NULL_KEY); } + + PQKkey max_key() // return maximum key + { return (n == k ? mk[k-1].key : PQ_NULL_KEY); } + + PQKkey ith_smallest_key(int i) // ith smallest key (i in [0..n-1]) + { return (i < n ? mk[i].key : PQ_NULL_KEY); } + + PQKinfo ith_smallest_info(int i) // info for ith smallest (i in [0..n-1]) + { return (i < n ? mk[i].info : PQ_NULL_INFO); } - inline void insert( // insert item (inlined for speed) - PQKkey kv, // key value - PQKinfo inf) // item info - { - register int i; - // slide larger values up - for (i = n; i > 0; i--) + inline void insert( // insert item (inlined for speed) + PQKkey kv, // key value + PQKinfo inf) // item info { - if (mk[i-1].key > kv) - mk[i] = mk[i-1]; - else - break; + register int i; + // slide larger values up + for (i = n; i > 0; i--) { + if (mk[i-1].key > kv) + mk[i] = mk[i-1]; + else + break; + } + mk[i].key = kv; // store element here + mk[i].info = inf; + if (n < k) n++; // increment number of items + ANN_FLOP(k-i+1) // increment floating ops } - mk[i].key = kv; // store element here - mk[i].info = inf; - if (n < k) n++; // increment number of items - FLOP(k-i+1) // increment floating ops - } }; #endif diff --git a/kNN/values.h b/kNN/values.h deleted file mode 100644 index 80cebad16..000000000 --- a/kNN/values.h +++ /dev/null @@ -1 +0,0 @@ -#define MAXDOUBLE 1.70141E+38 diff --git a/rc/GdaAppResources.cpp b/rc/GdaAppResources.cpp index 4e3477530..d8ed25eb1 100644 --- a/rc/GdaAppResources.cpp +++ b/rc/GdaAppResources.cpp @@ -15530,7 +15530,7 @@ static unsigned char xml_res_file_7[] = { 16,48,4,12,1,67,192,16,48,4,12,1,67,160,133,35,240,255,75,175,9,51,209, 227,12,205,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_8 = 385362; +static size_t xml_res_size_8 = 389594; 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,117,116,102,45,56,34,63,62,10,60,114,101, @@ -22203,441 +22203,469 @@ static unsigned char xml_res_file_8[] = { 34,32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,95,68,73,83,84, 95,77,69,84,82,73,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,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,116,97,110,99,101,32,109,101,116,114,105,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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,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,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,68,73,83,84,65,78,67,69,95,77,69,84, -82,73,67,34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +115,116,97,110,99,101,32,109,101,116,114,105,99,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,76,69,70,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, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, -61,34,73,68,67,95,83,84,65,84,73,67,95,88,67,79,79,82,68,95,86,65,82,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,88,45,99,111,111,114,100,105, -110,97,116,101,32,118,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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,67, -69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,68,73,83,84,65,78,67,69,95,77, +69,84,82,73,67,34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,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,60, -47,111,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,69,82, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,32,32,32,32,60,118,103,97,112,62,53,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,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,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,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,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,102, +108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,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,60,111,98,106,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,86,97, +114,105,97,98,108,101,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,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,73,68,67,95,78,66,95,68,73,83,84,65,78,67,69,95,86,65, +82,73,65,66,76,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,88,67,79,79,82,68,73,78,65,84,69,83, -34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,32,110,97,109, +101,61,34,73,68,67,95,78,66,95,80,65,71,69,95,71,69,79,77,95,67,69,78,84, +82,79,73,68,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,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,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, +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,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,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,60,47,102,108,97, 103,62,10,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,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,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,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, +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,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,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,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,73,68,67,95,88,67,79,79,82,68,95, -84,73,77,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,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,60,115,105,122,101,62,51,48,44,50,60,47,115,105,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,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,83,84,65,84,73,67,95,89,67,79,79,82,68,95,86,65,82,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,89,45,99,111,111,114,100,105,110,97,116,101, -32,118,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,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,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,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, +83,84,65,84,73,67,95,88,67,79,79,82,68,95,86,65,82,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,88,45,99,111,111, +114,100,105,110,97,116,101,32,118,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,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,89,67,79,79,82,68,73,78,65,84,69,83,34,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,76,69,70,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,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,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,32,32,32,32, -32,32,60,115,105,122,101,62,57,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,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,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,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,88,67,79,79,82,68,73,78,65,84, +69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,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,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,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,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,89,67,79,79,82,68,95,84,73,77,69,34, +61,34,119,120,67,104,111,105,99,101,34,32,110,97,109,101,61,34,73,68,67, +95,88,67,79,79,82,68,95,84,73,77,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,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,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,52,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,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,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,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,60,118,103,97,112,62,53,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,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,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,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,78,111,116,101,98,111,111,107,34,32,110,97,109, -101,61,34,73,68,67,95,78,66,95,68,73,83,84,65,78,67,69,95,87,69,73,71,72, -84,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,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,73, -68,67,95,82,65,68,73,79,95,68,73,83,84,65,78,67,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,32,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,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, -84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, -69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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, +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,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,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,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,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, -60,111,98,106,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,60,115,105,122,101,62,51,48,44,50,60, +47,115,105,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,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, 32,32,32,32,32,32,32,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,112,101,99,105,102,121,32,98,97,110,100,119, -105,100,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,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,95,89,67,79,79,82,68,95, +86,65,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,89,45,99,111,111,114,100,105,110,97,116,101,32,118,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,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,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, +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,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,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,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,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,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,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,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,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,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,73,68,67,95,89,67,79,79, +82,68,73,78,65,84,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,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,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -84,72,82,69,83,72,79,76,68,95,69,68,73,84,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,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,57,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,32,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,73,71,72,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +32,32,32,32,32,32,32,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,60,47,102,108,97,103,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,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,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,89,67,79,79,82,68,95,84,73,77,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,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,52,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,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,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,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,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,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,111,109,101,116,114,105,99,32,99,101,110,116,114,111,105, +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,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,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,32,110,97,109,101, +61,34,73,68,67,95,78,66,95,80,65,71,69,95,77,85,76,84,73,95,86,65,82,83, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,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,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,32,32,32,32,32, -60,115,105,122,101,62,51,48,44,50,60,47,115,105,122,101,62,10,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,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,49,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,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,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,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,108,105, -100,101,114,34,32,110,97,109,101,61,34,73,68,67,95,84,72,82,69,83,72,79, -76,68,95,83,76,73,68,69,82,34,62,10,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,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,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, -60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,87,69,73,71,72,84,83,95,68,73,83, +84,95,86,65,82,83,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,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,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,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,109,97,120,62,49,48,48,60,47,109,97,120,62,10,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,48,44,51,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,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,66,95,77,85,76,84,73,80,76,69,32,124,32,119,120, +76,66,95,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,32,32,32,32,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,83,76, -95,72,79,82,73,90,79,78,84,65,76,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,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,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,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,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,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,56,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,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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, +45,118,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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, +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,32,32,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,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78,67,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,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,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,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,60,111,98,106, +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,77,101,116,104,111,100,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,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,78,66,95, +68,73,83,84,65,78,67,69,95,87,69,73,71,72,84,83,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +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,73,68,67,95,82,65,68,73,79,95,68, +73,83,84,65,78,67,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,32,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,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,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73,83,84,65, -78,67,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,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,105,110,118,101,114,115,101,32,100,105,115,116, -97,110,99,101,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,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,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,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, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,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,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,112,101, +99,105,102,121,32,98,97,110,100,119,105,100,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,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,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,60,102,108,97,103,62,119,120, +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,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,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,32,32,32,32,32,32,32,60,115,105,122,101,62,49,48,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, -61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,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,32,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,119,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,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, 106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, 109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, -110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,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,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,73,68,67,95,84,72,82,69,83,72,79,76,68,95,69,68,73,84,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,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,57,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,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,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,60,115,116,121,108,101,62,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,66,117, -116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80,73,78,95,80, -79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,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,32,32, 32,32,32,32,32,32,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,105,110,62,49,60,47,109,105,110,62,10,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,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,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,48,44,50,60,47,115,105,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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,116,97,110,99,101,32,98,97,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,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,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,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, -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,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, -84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,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,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,108,105,100,101,114,34,32,110,97,109,101,61,34,73,68,67,95,84,72, +82,69,83,72,79,76,68,95,83,76,73,68,69,82,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,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,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,62,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,32,32,32,32,32,32,32, +32,32,32,32,32,60,109,105,110,62,48,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,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,76,95,72,79,82,73,90,79,78,84,65,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,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,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,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,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,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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, @@ -22647,85 +22675,150 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,124,119,120,65,68,74,85,83,84,95,77,73,78,83,73,90,69,60,47,102,108, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78,67,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62, +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,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73, +83,84,65,78,67,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,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,105,110,118,101,114,115,101,32,100,105, +115,116,97,110,99,101,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,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,83, -84,65,84,73,67,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,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,111,102,32,110,101, -105,103,104,98,111,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,32,32,32,32,32,32,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,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,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,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,75,78, -78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,60,115,105,122,101,62,49,48,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,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,84,69,95,82,69,65, -68,79,78,76,89,124,119,120,84,69,95,82,73,71,72,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,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -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,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,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,60,108,97,98,101,108,62,80,111,119, +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,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,115,105, -122,101,62,50,44,50,60,47,115,105,122,101,62,10,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,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,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,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, 116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,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,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,66,117,116,116,111, -110,34,32,110,97,109,101,61,34,73,68,67,95,83,80,73,78,95,75,78,78,34,62, +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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73,67,65,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, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32,60, -109,105,110,62,48,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,32,32,32,32,32,60,102,108,97,103,62,119,120,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120,62,10,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, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, +110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, +73,78,95,80,79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,62,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,32,32, +32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48, +60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,76,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,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,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,116,97,110,99,101,32,98,97,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +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,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,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,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, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -22739,117 +22832,209 @@ static unsigned char xml_res_file_8[] = { 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 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, +120,65,76,76,124,119,120,65,68,74,85,83,84,95,77,73,78,83,73,90,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,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,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,83,84,65,84,73,67,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,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,111,102, +32,110,101,105,103,104,98,111,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,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73, +84,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +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,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,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +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,32,32,32,32, +32,32,60,115,105,122,101,62,50,44,50,60,47,115,105,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, +110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, +73,78,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,62,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,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,105,110,62,48,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,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97, +120,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78, +60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,75,95,73,78,86, +69,82,83,69,95,68,73,83,84,65,78,67,69,95,75,78,78,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78, 67,69,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 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,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +108,97,98,101,108,62,85,115,101,32,105,110,118,101,114,115,101,32,100,105, +115,116,97,110,99,101,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,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,85,83,69,95,73, -78,86,69,82,83,69,95,68,73,83,84,65,78,67,69,95,75,78,78,34,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, -32,105,110,118,101,114,115,101,32,100,105,115,116,97,110,99,101,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,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,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,102,108,97,103,62,119,120,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,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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,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,60,115,105,122,101,62,49,48,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,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,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,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32, 32,32,32,32,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,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,119, +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,32, -32,32,32,32,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,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,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,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,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,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, -83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82, +95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,80,111,119,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,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,124,119,120,84,69,95,82,73,71,72,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, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,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, -67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +62,119,120,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,32,32,32,32,32,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,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82,95,75,78,78,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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, -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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,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,84,69,95,82,69,65,68,79, -78,76,89,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,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,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112, +105,110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83, +80,73,78,95,80,79,87,69,82,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,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,115,116,121,108,101,62,119,120,83,80,95,86,69,82,84, +73,67,65,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,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,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, +32,32,32,32,32,60,118,97,108,117,101,62,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,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,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, -110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, -73,78,95,80,79,87,69,82,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73, -67,65,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,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, 62,49,48,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -23341,7 +23526,7 @@ static unsigned char xml_res_file_8[] = { 108,97,103,62,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,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,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,49,53,60,47,98,111,114,100,101,114,62, +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,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, @@ -23350,7 +23535,7 @@ static unsigned char xml_res_file_8[] = { 101,108,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,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,115,105,122,101,62,53,48,48,44,52,56,48,60,47, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,48,48,44,53,48,48,60,47, 115,105,122,101,62,10,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32, @@ -32729,97 +32914,98 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,60,111,98,106,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,60,108,97,98,101,108,62,66,97,115,101, -109,97,112,32,83,111,117,114,99,101,115,58,32,40,110,97,109,101,44,98,97, -115,101,109,97,112,95,117,114,108,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,76,69,70,84,124,119,120,65,76,76,124,119,120,65,76, -73,71,78,95,76,69,70,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,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,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73, -68,67,95,66,65,83,69,77,65,80,95,83,79,85,82,67,69,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, -48,48,44,50,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,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,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,32,32,32,32,32, +109,97,112,32,83,111,117,114,99,101,115,58,32,40,70,111,114,109,97,116, +58,32,103,114,111,117,112,95,110,97,109,101,46,98,97,115,101,109,97,112, +95,110,97,109,101,44,98,97,115,101,109,97,112,95,117,114,108,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,76,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,49,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,62,10,32,32,32,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,109,97,112,32,80,97,114,97,109,101,116,101,114,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,60,47,111,98,106,101,99,116,62,10,32,32,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, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120, 65,76,76,124,119,120,65,76,73,71,78,95,76,69,70,84,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,73,68,67,95,66,65,83,69,77,65,80,95,83,79,85,82,67, +69,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,48,48,44,50,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,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, +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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,124,119,120,65,76,76,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,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,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,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,49,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,62,10,32,32,32,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,109,97,112,32,80,97,114,97,109,101, +116,101,114,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,60,47,111,98,106,101,99,116,62,10,32,32,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,65,76,76,124,119,120,65,76,73,71,78,95,76,69,70, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,95,83,84,65,84,73,67,84,69,88,84,34,62,10,32,32,32,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, -69,82,69,32,65,112,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,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,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,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,84,101,120,116,67,116,114,108,34,32,110, -97,109,101,61,34,73,68,67,95,78,79,75,73,65,95,85,83,69,82,78,65,77,69, -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,48,44,45,49,60,47,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, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,95,83,84,65,84,73,67,84,69,88,84,34,62,10, +32,32,32,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,69,82,69,32,65,112,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,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,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,78,79,75,73,65,95,85,83,69,82, +78,65,77,69,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,48,44,45,49,60,47,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, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,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,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, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,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,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,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,34,62,10,32,32,32, -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,69,82,69,32,65,112,112,32,75,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,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,34,62,10,32, +32,32,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,69,82,69,32,65,112,112,32,75,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,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,78, diff --git a/rc/dialogs.xrc b/rc/dialogs.xrc index 22570674c..f408b434a 100644 --- a/rc/dialogs.xrc +++ b/rc/dialogs.xrc @@ -3579,7 +3579,7 @@ - + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL @@ -3591,53 +3591,126 @@ 2 - - - - - wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL - 2 - - - - 98,-1d - - wxALIGN_CENTER - 2 - - - - 40,-1d - - wxALIGN_CENTER - - - - - - wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL - 2 - - - - 98,-1d + 3 + 1 + 5 + 5 + + wxALIGN_LEFT|wxALL + 2 + + + + wxALIGN_LEFT|wxALL + 2 + + + + + + + + + + wxVERTICAL + + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 10 + + wxHORIZONTAL + + 30,2 + + + + + + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxALL + 2 + + + + 60,-1d + + wxALIGN_CENTER|wxALL + 2 + + + + 40,-1d + + wxALIGN_CENTER + + + + + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 10 + + wxHORIZONTAL + + 30,2 + + + + + + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxALL + 2 + + + + 60,-1d + + wxALIGN_CENTER|wxALL + 2 + + + + 40,-1d + + wxALIGN_CENTER + + + + - wxALIGN_CENTER - 2 + + wxALL|wxEXPAND - - - 40,-1d + + + + wxVERTICAL + + wxALIGN_CENTER + 1 + + wxHORIZONTAL + + + + 150,30d + + + wxALIGN_CENTER + + + + + 280,-1d - wxALIGN_CENTER + + wxALL|wxEXPAND - 3 - 3 - 5 - 5 + + wxALIGN_LEFT|wxALL 2 + + + @@ -4026,14 +4099,14 @@ wxALIGN_CENTRE_HORIZONTAL|wxALL|wxEXPAND - 15 + 10 wxALL|wxEXPAND - 500,480 + 500,500 wxALL|wxEXPAND wxALL|wxEXPAND|wxALIGN_CENTRE_HORIZONTAL From e1f025954d2d70a59ba65d17c2a5bd012cc8e4cc Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 21 Nov 2018 20:52:32 -0700 Subject: [PATCH 30/39] #1751 weights function enhancement --- .../macosx/GeoDa.xcodeproj/project.pbxproj | 36 +++++++++++++++++++ kNN/bd_tree.cpp | 2 +- kNN/bd_tree.h | 2 +- kNN/brute.cpp | 2 +- kNN/kd_fix_rad_search.h | 2 +- kNN/perf.cpp | 4 +-- 6 files changed, 42 insertions(+), 6 deletions(-) diff --git a/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj b/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj index b593d9934..cb830c503 100644 --- a/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj +++ b/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj @@ -19,6 +19,14 @@ A1311C6720FFDF7100008D7F /* localjc_kernel.cl in CopyFiles */ = {isa = PBXBuildFile; fileRef = A4E00F0F20FD8ECC0038BA80 /* localjc_kernel.cl */; }; A13B6B9418760CF100F93ACF /* SaveAsDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A13B6B9318760CF100F93ACF /* SaveAsDlg.cpp */; }; A14735AA21A5F72D00CA69B2 /* DistUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735A921A5F72D00CA69B2 /* DistUtils.cpp */; }; + A14735B521A65F1800CA69B2 /* bd_tree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735AB21A65F1600CA69B2 /* bd_tree.cpp */; }; + A14735B621A65F1800CA69B2 /* kd_dump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735AC21A65F1600CA69B2 /* kd_dump.cpp */; }; + A14735B721A65F1800CA69B2 /* bd_fix_rad_search.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735AD21A65F1700CA69B2 /* bd_fix_rad_search.cpp */; }; + A14735B821A65F1800CA69B2 /* kd_fix_rad_search.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735AE21A65F1700CA69B2 /* kd_fix_rad_search.cpp */; }; + A14735B921A65F1800CA69B2 /* bd_search.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735AF21A65F1700CA69B2 /* bd_search.cpp */; }; + A14735BA21A65F1800CA69B2 /* perf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735B121A65F1700CA69B2 /* perf.cpp */; }; + A14735BB21A65F1800CA69B2 /* bd_pr_search.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735B221A65F1700CA69B2 /* bd_pr_search.cpp */; }; + A14735BC21A65F1800CA69B2 /* brute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14735B321A65F1700CA69B2 /* brute.cpp */; }; A14C496F1D76174000D9831C /* CsvFieldConfDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14C496D1D76174000D9831C /* CsvFieldConfDlg.cpp */; }; A16BA470183D626200D3B7DA /* DatasourceDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A16BA46E183D626200D3B7DA /* DatasourceDlg.cpp */; }; A186F0A11C16508A00AEBA13 /* GdaCartoDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A186F09F1C16508A00AEBA13 /* GdaCartoDB.cpp */; }; @@ -326,6 +334,16 @@ A13B6B9318760CF100F93ACF /* SaveAsDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SaveAsDlg.cpp; sourceTree = ""; }; A14735A821A5F72D00CA69B2 /* DistUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DistUtils.h; sourceTree = ""; }; A14735A921A5F72D00CA69B2 /* DistUtils.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DistUtils.cpp; sourceTree = ""; }; + A14735AB21A65F1600CA69B2 /* bd_tree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bd_tree.cpp; sourceTree = ""; }; + A14735AC21A65F1600CA69B2 /* kd_dump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kd_dump.cpp; sourceTree = ""; }; + A14735AD21A65F1700CA69B2 /* bd_fix_rad_search.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bd_fix_rad_search.cpp; sourceTree = ""; }; + A14735AE21A65F1700CA69B2 /* kd_fix_rad_search.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kd_fix_rad_search.cpp; sourceTree = ""; }; + A14735AF21A65F1700CA69B2 /* bd_search.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bd_search.cpp; sourceTree = ""; }; + A14735B021A65F1700CA69B2 /* kd_fix_rad_search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kd_fix_rad_search.h; sourceTree = ""; }; + A14735B121A65F1700CA69B2 /* perf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = perf.cpp; sourceTree = ""; }; + A14735B221A65F1700CA69B2 /* bd_pr_search.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bd_pr_search.cpp; sourceTree = ""; }; + A14735B321A65F1700CA69B2 /* brute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = brute.cpp; sourceTree = ""; }; + A14735B421A65F1700CA69B2 /* bd_tree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bd_tree.h; sourceTree = ""; }; A14C496D1D76174000D9831C /* CsvFieldConfDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CsvFieldConfDlg.cpp; sourceTree = ""; }; A14C496E1D76174000D9831C /* CsvFieldConfDlg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CsvFieldConfDlg.h; sourceTree = ""; }; A16BA46E183D626200D3B7DA /* DatasourceDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatasourceDlg.cpp; sourceTree = ""; }; @@ -1073,6 +1091,16 @@ A4ED7D3F2097EC0F008685D6 /* kNN */ = { isa = PBXGroup; children = ( + A14735AD21A65F1700CA69B2 /* bd_fix_rad_search.cpp */, + A14735B221A65F1700CA69B2 /* bd_pr_search.cpp */, + A14735AF21A65F1700CA69B2 /* bd_search.cpp */, + A14735AB21A65F1600CA69B2 /* bd_tree.cpp */, + A14735B421A65F1700CA69B2 /* bd_tree.h */, + A14735B321A65F1700CA69B2 /* brute.cpp */, + A14735AC21A65F1600CA69B2 /* kd_dump.cpp */, + A14735AE21A65F1700CA69B2 /* kd_fix_rad_search.cpp */, + A14735B021A65F1700CA69B2 /* kd_fix_rad_search.h */, + A14735B121A65F1700CA69B2 /* perf.cpp */, A4ED7D4E2097F113008685D6 /* kd_pr_search.cpp */, A4ED7D4A2097F113008685D6 /* kd_pr_search.h */, A4ED7D502097F114008685D6 /* kd_search.cpp */, @@ -1820,6 +1848,7 @@ DDC9DD8515937AA000A0E5BA /* ExportCsvDlg.cpp in Sources */, DDC9DD8A15937B2F00A0E5BA /* CsvFileUtils.cpp in Sources */, DDC9DD9C15937C0200A0E5BA /* ImportCsvDlg.cpp in Sources */, + A14735B721A65F1800CA69B2 /* bd_fix_rad_search.cpp in Sources */, DD75A04115E81AF9008A7F8C /* VoronoiUtils.cpp in Sources */, DDB2A75F15FA7DA900022ABE /* CartogramNewView.cpp in Sources */, A11F1B821850437A006F5F98 /* OGRTableOperation.cpp in Sources */, @@ -1853,12 +1882,14 @@ A1D82DEF174D3EB6003DE20A /* ConnectDatasourceDlg.cpp in Sources */, A1BE9E51174DD85F007B9C64 /* GdaAppResources.cpp in Sources */, DDFE0E2A175034EC0099FFEC /* TimeState.cpp in Sources */, + A14735B921A65F1800CA69B2 /* bd_search.cpp in Sources */, A4404A02208E65DD0007753D /* wxTranslationHelper.cpp in Sources */, A19483962118BAAA009A87A2 /* oglmisc.cpp in Sources */, DD4974B71770AC700007BB9F /* TableFrame.cpp in Sources */, DD4974BA1770AC840007BB9F /* TableBase.cpp in Sources */, DD4974E21770CE9E0007BB9F /* TableInterface.cpp in Sources */, A1E77E1A177D6A2E00CC1037 /* ExportDataDlg.cpp in Sources */, + A14735B821A65F1800CA69B2 /* kd_fix_rad_search.cpp in Sources */, A10EF2F021273E7E00564FE1 /* AbstractCanvas.cpp in Sources */, A194839B2118BAAA009A87A2 /* basic2.cpp in Sources */, A1E77FDC17889BE200CC1037 /* OGRTable.cpp in Sources */, @@ -1894,8 +1925,10 @@ A4ED7D472097EDE9008685D6 /* kd_tree.cpp in Sources */, DDEA3CBD193CEE5C0028B746 /* GdaFlexValue.cpp in Sources */, DDEA3CBE193CEE5C0028B746 /* GdaLexer.cpp in Sources */, + A14735BA21A65F1800CA69B2 /* perf.cpp in Sources */, DDEA3CBF193CEE5C0028B746 /* GdaParser.cpp in Sources */, DDEA3D01193D17130028B746 /* CalculatorDlg.cpp in Sources */, + A14735B621A65F1800CA69B2 /* kd_dump.cpp in Sources */, A14C496F1D76174000D9831C /* CsvFieldConfDlg.cpp in Sources */, DDA4F0A4196311A9007645E2 /* WeightsMetaInfo.cpp in Sources */, DDA4F0AD196315AF007645E2 /* WeightUtils.cpp in Sources */, @@ -1903,6 +1936,7 @@ DD8183C3197054CA00228B0A /* WeightsMapCanvas.cpp in Sources */, DD8183C81970619800228B0A /* WeightsManDlg.cpp in Sources */, A47614AE20759EAD00D9F3BE /* arcgis_swm.cpp in Sources */, + A14735BC21A65F1800CA69B2 /* brute.cpp in Sources */, DD81857C19709B7800228B0A /* ConnectivityMapView.cpp in Sources */, DD4DED12197E16FF00FE29E8 /* SelectWeightsDlg.cpp in Sources */, DD5AA73D1982D200009B30C6 /* CalcHelp.cpp in Sources */, @@ -1914,6 +1948,7 @@ A4A6AD7B207F198E00D29677 /* ShpFile.cpp in Sources */, DD30798E19ED80E0001E5E89 /* Lowess.cpp in Sources */, DD3079C719ED9F61001E5E89 /* LowessParamObservable.cpp in Sources */, + A14735B521A65F1800CA69B2 /* bd_tree.cpp in Sources */, DD3079E319EDAE6C001E5E89 /* LowessParamDlg.cpp in Sources */, DD307DB919F0483B001E5E89 /* SmoothingUtils.cpp in Sources */, DD3082B319F709BB001E5E89 /* WebViewHelpWin.cpp in Sources */, @@ -1948,6 +1983,7 @@ DDFFC7D51AC0E7DC00F7DD6D /* CorrelParamsDlg.cpp in Sources */, A19483932118BAAA009A87A2 /* composit.cpp in Sources */, A19483992118BAAA009A87A2 /* canvas.cpp in Sources */, + A14735BB21A65F1800CA69B2 /* bd_pr_search.cpp in Sources */, DDFFC7F21AC1C7CF00F7DD6D /* HighlightState.cpp in Sources */, DD9373F71AC1FEAA0066AF21 /* PolysToContigWeights.cpp in Sources */, DDCCB5CC1AD47C200067D6C4 /* SimpleBinsHistCanvas.cpp in Sources */, diff --git a/kNN/bd_tree.cpp b/kNN/bd_tree.cpp index 99425e484..aadf7c147 100755 --- a/kNN/bd_tree.cpp +++ b/kNN/bd_tree.cpp @@ -30,7 +30,7 @@ #include "kd_util.h" // kd-tree utilities #include "kd_split.h" // kd-tree splitting rules -#include // performance evaluation +#include "ANN/ANNperf.h" // performance evaluation //---------------------------------------------------------------------- // Printing a bd-tree diff --git a/kNN/bd_tree.h b/kNN/bd_tree.h index e922b972e..71e886ea8 100755 --- a/kNN/bd_tree.h +++ b/kNN/bd_tree.h @@ -27,7 +27,7 @@ #ifndef ANN_bd_tree_H #define ANN_bd_tree_H -#include // all ANN includes +#include "ANN/ANNx.h" // all ANN includes #include "kd_tree.h" // kd-tree includes //---------------------------------------------------------------------- diff --git a/kNN/brute.cpp b/kNN/brute.cpp index f930adfde..fb6e596a6 100755 --- a/kNN/brute.cpp +++ b/kNN/brute.cpp @@ -24,7 +24,7 @@ // Added fixed-radius kNN search //---------------------------------------------------------------------- -#include // all ANN includes +#include "ANN/ANNx.h" // all ANN includes #include "pr_queue_k.h" // k element priority queue //---------------------------------------------------------------------- diff --git a/kNN/kd_fix_rad_search.h b/kNN/kd_fix_rad_search.h index 756732780..06f9659b7 100755 --- a/kNN/kd_fix_rad_search.h +++ b/kNN/kd_fix_rad_search.h @@ -29,7 +29,7 @@ #include "kd_util.h" // kd-tree utilities #include "pr_queue_k.h" // k-element priority queue -#include // performance evaluation +#include "ANN/ANNperf.h" // performance evaluation //---------------------------------------------------------------------- // Global variables diff --git a/kNN/perf.cpp b/kNN/perf.cpp index 1b412f237..9f7786091 100755 --- a/kNN/perf.cpp +++ b/kNN/perf.cpp @@ -28,8 +28,8 @@ // Fixed minor compilation bugs for new versions of gcc //---------------------------------------------------------------------- -#include // basic ANN includes -#include // performance includes +#include "ANN/ANN.h" // basic ANN includes +#include "ANN/ANNperf.h" // performance includes using namespace std; // make std:: available From 133714f1a5fa8fe3c281c60d265110574767e244 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 21 Nov 2018 21:00:58 -0700 Subject: [PATCH 31/39] cluster variable setting typo for iterations #1757 --- DialogTools/KMeansDlg.cpp | 2 +- DialogTools/SpectralClusteringDlg.cpp | 2 +- internationalization/pofiles/es.po | 2 +- internationalization/pofiles/zh_CN.po | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DialogTools/KMeansDlg.cpp b/DialogTools/KMeansDlg.cpp index c57918faf..1113f1ab5 100644 --- a/DialogTools/KMeansDlg.cpp +++ b/DialogTools/KMeansDlg.cpp @@ -141,7 +141,7 @@ void KClusterDlg::CreateControls() } wxStaticText* st11 = new wxStaticText(panel, wxID_ANY, - _("Maximal Iterations:"), + _("Maximum Iterations:"), wxDefaultPosition, wxSize(128,-1)); m_iterations = new wxTextCtrl(panel, wxID_ANY, "1000", wxDefaultPosition, wxSize(200,-1)); gbox->Add(st11, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, 10); diff --git a/DialogTools/SpectralClusteringDlg.cpp b/DialogTools/SpectralClusteringDlg.cpp index 94cf947bb..26a10ac79 100644 --- a/DialogTools/SpectralClusteringDlg.cpp +++ b/DialogTools/SpectralClusteringDlg.cpp @@ -215,7 +215,7 @@ void SpectralClusteringDlg::CreateControls() seedButton->Enable(); } - wxStaticText* st11 = new wxStaticText(panel, wxID_ANY, _("Maximal Iterations:"),wxDefaultPosition, wxSize(128,-1)); + wxStaticText* st11 = new wxStaticText(panel, wxID_ANY, _("Maximum Iterations:"),wxDefaultPosition, wxSize(128,-1)); wxTextCtrl *box11 = new wxTextCtrl(panel, wxID_ANY, "300"); gbox->Add(st11, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, 10); gbox->Add(box11, 1, wxEXPAND); diff --git a/internationalization/pofiles/es.po b/internationalization/pofiles/es.po index 74d67345d..8640d3e12 100644 --- a/internationalization/pofiles/es.po +++ b/internationalization/pofiles/es.po @@ -3390,7 +3390,7 @@ msgstr "Bajo" msgid "Select variable " msgstr "Seleccionar variable " -msgid "Maximal Iterations:" +msgid "Maximum Iterations:" msgstr "Iteraciones máximas:" msgid "Datasource path is empty." diff --git a/internationalization/pofiles/zh_CN.po b/internationalization/pofiles/zh_CN.po index bbdcfd27c..b9b31ef21 100644 --- a/internationalization/pofiles/zh_CN.po +++ b/internationalization/pofiles/zh_CN.po @@ -3296,7 +3296,7 @@ msgstr "低" msgid "Select variable " msgstr "选择变量 " -msgid "Maximal Iterations:" +msgid "Maximum Iterations:" msgstr "最大迭代:" msgid "Datasource path is empty." From 125faadd3a6db4f082a60f4a33783f8a9a73ab8c Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 26 Nov 2018 09:42:12 -0700 Subject: [PATCH 32/39] kmedoids has no maximum iterations #1756 The c cluster library ignores the maximum iteration parameter in KMedoids algorithm. This ci adds this parameter in KMedoids algorithm. --- Algorithms/cluster.cpp | 11 ++++++++--- Algorithms/cluster.h | 2 +- DialogTools/KMeansDlg.cpp | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Algorithms/cluster.cpp b/Algorithms/cluster.cpp index 63e349d57..636c0cba2 100644 --- a/Algorithms/cluster.cpp +++ b/Algorithms/cluster.cpp @@ -2977,7 +2977,7 @@ number of clusters is larger than the number of elements being clustered, /* *********************************************************************** */ void kmedoids (int nclusters, int nelements, double** distmatrix, - int npass, int clusterid[], double* error, int* ifound, double bound_vals[], double min_bound, int s1, int s2) + int npass, int n_maxiter, int clusterid[], double* error, int* ifound, double bound_vals[], double min_bound, int s1, int s2) /* Purpose ======= @@ -3092,8 +3092,13 @@ to 0. If kmedoids fails due to a memory allocation error, ifound is set to -1. if (npass!=0) randomassign (nclusters, nelements, tclusterid, _s1, _s2); - while(1) - { double previous = total; + + int iter = 0; + + while(iter < n_maxiter) + { + iter ++; + double previous = total; total = 0.0; if (counter % period == 0) /* Save the current cluster assignments */ diff --git a/Algorithms/cluster.h b/Algorithms/cluster.h index ec58c7fb5..20d532f59 100644 --- a/Algorithms/cluster.h +++ b/Algorithms/cluster.h @@ -70,7 +70,7 @@ void kcluster (int nclusters, int ngenes, int ndata, double** data, int** mask, double weight[], int transpose, int npass, int n_maxiter, char method, char dist, int clusterid[], double* error, int* ifound, double bound_vals[], double min_bound, int s1, int s2); void kmedoids (int nclusters, int nelements, double** distance, - int npass, int clusterid[], double* error, int* ifound, double bound_vals[], double min_bound, int s1, int s2); + int npass, int n_maxiter, int clusterid[], double* error, int* ifound, double bound_vals[], double min_bound, int s1, int s2); void test (int nclusters, int nrows, int ncolumns, double** data, int** mask, double weight[], int transpose, int npass, int n_maxiter, char a); diff --git a/DialogTools/KMeansDlg.cpp b/DialogTools/KMeansDlg.cpp index 1113f1ab5..f062f0add 100644 --- a/DialogTools/KMeansDlg.cpp +++ b/DialogTools/KMeansDlg.cpp @@ -821,7 +821,7 @@ KMedoidsDlg::KMedoidsDlg(wxFrame *parent, Project* project) show_initmethod = false; show_distance = true; - show_iteration = false; + show_iteration = true; cluster_method = "KMedoids"; mean_center_type = " (medoid)"; @@ -851,7 +851,7 @@ void KMedoidsDlg::doRun(int s1,int ncluster, int npass, int n_maxiter, int meth_ int s2 = s1==0 ? 0 : s1 + npass; - kmedoids(ncluster, rows, distmatrix, npass, clusterid, &error, &ifound, bound_vals, min_bound, s1, s2); + kmedoids(ncluster, rows, distmatrix, npass, n_maxiter, clusterid, &error, &ifound, bound_vals, min_bound, s1, s2); set centers; map > c_dist; From 90c4f6c4b966dd47103d2d7f6106be1da4154d2b Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 26 Nov 2018 09:42:39 -0700 Subject: [PATCH 33/39] Update version.h --- version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.h b/version.h index 56a3e772e..27619bad7 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 12; const int version_build = 1; - const int version_subbuild = 177; + const int version_subbuild = 179; const int version_year = 2018; const int version_month = 11; - const int version_day = 19; + const int version_day = 26; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From 2dbdeeb9b9b9778f6fc89370d5e9f1132d798ab5 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 26 Nov 2018 21:27:11 -0700 Subject: [PATCH 34/39] #1751 weights function enhancement add adaptive kernel weights for social weights creation --- ShapeOperations/PolysToContigWeights.cpp | 1 + Weights/DistUtils.cpp | 179 ++++++++++++++++++++++- Weights/DistUtils.h | 21 ++- kNN/ANN.cpp | 30 ++++ kNN/ANN/ANN.h | 15 +- 5 files changed, 238 insertions(+), 8 deletions(-) diff --git a/ShapeOperations/PolysToContigWeights.cpp b/ShapeOperations/PolysToContigWeights.cpp index 159f00c86..c523cfed9 100644 --- a/ShapeOperations/PolysToContigWeights.cpp +++ b/ShapeOperations/PolysToContigWeights.cpp @@ -453,6 +453,7 @@ GalElement* PolysToContigWeights(Shapefile::Main& main, bool is_queen, if (!gl) return NULL; GeoDaSet Neighbors(gRecords), Related(gRecords); // cout << "total steps= " << gMinX.Cells() << endl; + for (int step= 0; step < gMinX.Cells(); ++step) { // include all elements from xmin[step] for (curr= gMinX.first(step); curr != GdaConst::EMPTY; diff --git a/Weights/DistUtils.cpp b/Weights/DistUtils.cpp index d34888d6a..2d149485f 100644 --- a/Weights/DistUtils.cpp +++ b/Weights/DistUtils.cpp @@ -11,10 +11,12 @@ using namespace GeoDa; -DistUtils::DistUtils(const std::vector >& input_data) +DistUtils::DistUtils(const std::vector >& input_data, int distance_metric) { eps = 0.0; + ANN_DIST_TYPE = distance_metric; + n_cols = input_data.size(); if (n_cols > 0) { n_rows = input_data[0].size(); @@ -92,18 +94,191 @@ double DistUtils::GetMaxThreshold() return sqrt(dist_cand); } -void DistUtils::CreateDistBandWeights(double band, bool is_inverse, int power) +GeoDa::Weights DistUtils::CreateDistBandWeights(double band, bool is_inverse, int power) { + GeoDa::Weights weights; + double radius = ANN_POW(band); + double w; + for (size_t i=0; iannkFRSearch(data[i], radius, 0, NULL, NULL); ANNidxArray nnIdx = new ANNidx[k]; ANNdistArray dists = new ANNdist[k]; kdTree->annkFRSearch(data[i], radius, k, nnIdx, dists); + std::vector > nbrs; for (size_t j=0; jannkSearch(data[i], k+1, nnIdx, dists); + std::vector > nbrs; + for (size_t j=0; jannkSearch(data[i], k+1, nnIdx, dists); + std::vector > nbrs; + double local_band = 0; + for (size_t j=0; j local_band) { + local_band = dists[j]; + } + } + } + local_band = ANN_ROOT(local_band); + for (size_t j=0; j 0 ? w / local_band : 0; + nbrs.push_back(std::make_pair(nnIdx[j], w)); + } + } + weights.push_back(nbrs); + } + } else { + // use max knn distance as bandwidth + for (size_t i=0; iannkSearch(data[i], k+1, nnIdx, dists); + std::vector > nbrs; + for (size_t j=0; j max_knn_bandwidth) { + max_knn_bandwidth = w; + } + } + } + weights.push_back(nbrs); + } + for (size_t i=0; iannkFRSearch(data[i], radius, 0, NULL, NULL); + ANNidxArray nnIdx = new ANNidx[k]; + ANNdistArray dists = new ANNdist[k]; + kdTree->annkFRSearch(data[i], radius, k, nnIdx, dists); + std::vector > nbrs; + for (size_t j=0; j > > Weights; class DistUtils { @@ -25,7 +26,8 @@ namespace GeoDa { unsigned long n_rows; public: - DistUtils(const std::vector >& input_data); + DistUtils(const std::vector >& input_data, + int distance_metric = 2); ~DistUtils(); // The minimum threshold distance guarantees that every observation has @@ -36,7 +38,22 @@ namespace GeoDa { // represents by all data points double GetMaxThreshold(); - void CreateDistBandWeights(double band, bool is_inverse, int power); + GeoDa::Weights CreateDistBandWeights(double band, bool is_inverse, int power); + + GeoDa::Weights CreateKNNWeights(int k, bool is_inverse, int power); + + // is_adaptive_bandwidth: true: use distance of k n-neighbors as bandwidth + // false: use max KNN as bandwidth + // apply_kernel_to_diag: true: apply kernel to diagnal weights + // false: diagonal weights = 1 + GeoDa::Weights CreateAdaptiveKernelWeights(int kernel_type, int k, + bool is_adaptive_bandwidth = true, + bool apply_kernel_to_diag = false); + + GeoDa::Weights CreateAdaptiveKernelWeights(int kernel_type, double band, + bool apply_kernel_to_diag = false); + + void ApplyKernel(GeoDa::Weights& w, int kernel_type, bool apply_kernel_to_diag); }; } #endif /* DistUtils_h */ diff --git a/kNN/ANN.cpp b/kNN/ANN.cpp index b9b8d4a1d..7ea2e41ae 100755 --- a/kNN/ANN.cpp +++ b/kNN/ANN.cpp @@ -31,6 +31,36 @@ #include "ANN/ANNperf.h" // ANN performance using namespace std; // make std:: accessible + + +double ANN_POW(double v) +{ + if (ANN_DIST_TYPE == 1) { + return fabs(v); + } else if (ANN_DIST_TYPE == 2) { + return v * v; + } else { + return pow(fabs(v), ANN_DIST_TYPE); + } +} +double ANN_ROOT(double x) +{ + if (ANN_DIST_TYPE == 1) { + return x; + } else if (ANN_DIST_TYPE == 2) { + return sqrt(x); + } else { + return pow(fabs(x), 1/ANN_DIST_TYPE); + } +} +double ANN_SUM(double x, double y) +{ + return x + y; +} +double ANN_DIFF(double x, double y) +{ + return y - x; +} //---------------------------------------------------------------------- // Point methods diff --git a/kNN/ANN/ANN.h b/kNN/ANN/ANN.h index 3f70ec633..79aceaed0 100755 --- a/kNN/ANN/ANN.h +++ b/kNN/ANN/ANN.h @@ -329,14 +329,21 @@ const ANNbool ANN_ALLOW_SELF_MATCH = ANNtrue; // By default the Euclidean norm is assumed. To change the norm, // uncomment the appropriate set of macros below. //---------------------------------------------------------------------- + +static int ANN_DIST_TYPE = 2; + +double ANN_POW(double v); +double ANN_ROOT(double x); +double ANN_SUM(double x, double y); +double ANN_DIFF(double x, double y); //---------------------------------------------------------------------- // Use the following for the Euclidean norm //---------------------------------------------------------------------- -#define ANN_POW(v) ((v)*(v)) -#define ANN_ROOT(x) sqrt(x) -#define ANN_SUM(x,y) ((x) + (y)) -#define ANN_DIFF(x,y) ((y) - (x)) +// #define ANN_POW(v) ((v)*(v)) +// #define ANN_ROOT(x) sqrt(x) +// #define ANN_SUM(x,y) ((x) + (y)) +// #define ANN_DIFF(x,y) ((y) - (x)) //---------------------------------------------------------------------- // Use the following for the L_1 (Manhattan) norm From 2a630a61945b0cb2fdf2636ebc9a8f1cfb54037f Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 27 Nov 2018 20:10:06 -0700 Subject: [PATCH 35/39] #1751 update UI and allow create weights from selected Table variables --- DataViewer/OGRTable.cpp | 10 +- DataViewer/OGRTable.h | 3 +- DataViewer/TableInterface.h | 3 +- DialogTools/CreatingWeightDlg.cpp | 223 +++++- DialogTools/CreatingWeightDlg.h | 19 +- GenUtils.cpp | 63 ++ GenUtils.h | 9 + rc/GdaAppResources.cpp | 1117 ++++++++++++++++------------- rc/dialogs.xrc | 104 ++- 9 files changed, 968 insertions(+), 583 deletions(-) diff --git a/DataViewer/OGRTable.cpp b/DataViewer/OGRTable.cpp index f2472eb84..cb250a042 100644 --- a/DataViewer/OGRTable.cpp +++ b/DataViewer/OGRTable.cpp @@ -838,7 +838,8 @@ void OGRTable::GetColData(int col, int time, std::vector& da } void OGRTable::GetDataByColumns(const std::vector& col_names, - std::vector >& data) + std::vector >& data, + std::vector >& undefs) { // column names could be time (grouped) variable int col_idx; @@ -851,15 +852,16 @@ void OGRTable::GetDataByColumns(const std::vector& col_names, for (int i=0; i& data); virtual bool GetDirectColUndefined(int col, std::vector& undefined); virtual void GetDataByColumns(const std::vector& col_names, - std::vector >& data); + std::vector >& data, + std::vector >& undefs); virtual bool GetColUndefined(int col, b_array_type& undefined); virtual bool GetColUndefined(int col, int time, diff --git a/DataViewer/TableInterface.h b/DataViewer/TableInterface.h index c276fa70c..febde0f4b 100644 --- a/DataViewer/TableInterface.h +++ b/DataViewer/TableInterface.h @@ -178,7 +178,8 @@ class TableInterface virtual bool GetDirectColUndefined(int col, std::vector& undefs)=0; virtual void GetDataByColumns(const std::vector& col_names, - std::vector >& data) = 0; + std::vector >& data, + std::vector >& undefs) = 0; virtual void GetMinMaxVals(int col, std::vector& min_vals, std::vector& max_vals) = 0; diff --git a/DialogTools/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp index b53eda09e..4cbbe6237 100644 --- a/DialogTools/CreatingWeightDlg.cpp +++ b/DialogTools/CreatingWeightDlg.cpp @@ -46,7 +46,6 @@ #include "../GenUtils.h" #include "../SpatialIndAlgs.h" #include "../PointSetAlgs.h" -#include "../Weights/DistUtils.h" #include "AddIdVariable.h" #include "CreatingWeightDlg.h" @@ -90,6 +89,7 @@ m_arc_in_km(false), m_thres_val_valid(false), m_threshold_val(0.01), project(project_s), +dist_util(NULL), frames_manager(project_s->GetFramesManager()), table_int(project_s->GetTableInt()), table_state(project_s->GetTableState()), @@ -106,12 +106,16 @@ suspend_table_state_updates(false) table_state->registerObserver(this); w_man_state->registerObserver(this); // use_xy is for MDS creating weights only - if (!user_xy) + if (!user_xy) { Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CreatingWeightDlg::OnClose) ); + } } CreatingWeightDlg::~CreatingWeightDlg() { + if (dist_util) { + delete dist_util; + } frames_manager->removeObserver(this); table_state->removeObserver(this); w_man_state->removeObserver(this); @@ -176,6 +180,8 @@ void CreatingWeightDlg::CreateControls() m_txt_precision_threshold = XRCCTRL(*this, "IDC_PRECISION_THRESHOLD_EDIT", wxTextCtrl); // distance weight m_dist_choice = XRCCTRL(*this, "IDC_DISTANCE_METRIC", wxChoice); + m_trans_choice_vars = XRCCTRL(*this, "IDC_DISTANCE_TRANSFORMATION", wxChoice); + m_dist_choice_vars = XRCCTRL(*this, "IDC_DISTANCE_METRIC1", wxChoice); m_X = XRCCTRL(*this, "IDC_XCOORDINATES", wxChoice); m_X_time = XRCCTRL(*this, "IDC_XCOORD_TIME", wxChoice); m_Y = XRCCTRL(*this, "IDC_YCOORDINATES", wxChoice); @@ -215,41 +221,86 @@ void CreatingWeightDlg::CreateControls() m_nb_distance_variables->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, &CreatingWeightDlg::OnDistanceWeightsInputUpdate, this); m_Vars->Bind(wxEVT_LISTBOX, &CreatingWeightDlg::OnDistanceWeightsVarsSel, this); - + m_dist_choice_vars->Bind(wxEVT_CHOICE, &CreatingWeightDlg::OnDistanceMetricVarsSel, this); + m_trans_choice_vars->Bind(wxEVT_CHOICE, &CreatingWeightDlg::OnDistanceMetricVarsSel, this); InitDlg(); } +void CreatingWeightDlg::OnDistanceMetricVarsSel( wxCommandEvent& event ) +{ + int dist_metric = m_dist_choice_vars->GetSelection(); + if (dist_metric > 0) { + m_nb_distance_methods->Enable(); + } else { + m_thres_val_valid = false; + m_threshold->ChangeValue("0"); + m_bandwidth_thres_val_valid = false; + m_manu_bandwidth->ChangeValue("0"); + m_nb_distance_methods->Disable(); + } + UpdateThresholdValuesMultiVars(); +} + void CreatingWeightDlg::OnDistanceWeightsVarsSel( wxCommandEvent& event ) { - // update Threshold values for distance weight + m_dist_choice_vars->SetSelection(0); + UpdateThresholdValuesMultiVars(); + + m_thres_val_valid = false; + m_threshold->ChangeValue("0"); + m_bandwidth_thres_val_valid = false; + m_manu_bandwidth->ChangeValue("0"); + m_nb_distance_methods->Disable(); +} + +void CreatingWeightDlg::UpdateThresholdValuesMultiVars() +{ + // distance metric + int dist_metric = m_dist_choice_vars->GetSelection(); + if (dist_metric < 1) { + return; + } + wxArrayInt selections; m_Vars->GetSelections(selections); int num_var = selections.size(); if (num_var <= 0) { return; } + + // update Threshold values for distance weight std::vector col_names; std::vector > data; + std::vector > undefs; for (int i=0; iGetString(idx); col_names.push_back(sel_str); } data.resize(num_var); - table_int->GetDataByColumns(col_names, data); + undefs.resize(num_var); + table_int->GetDataByColumns(col_names, data, undefs); + + // transformation + int trans_type = m_trans_choice_vars->GetSelection(); + GenUtils::Transformation(trans_type, data, undefs); + // UpdateThresholdValues(); - GeoDa::DistUtils dist_util(data); - m_thres_min = dist_util.GetMinThreshold(); - m_thres_max = dist_util.GetMaxThreshold(); + if (dist_util) { + delete dist_util; + } + dist_util = new GeoDa::DistUtils(data, dist_metric); + m_thres_min_multivars = dist_util->GetMinThreshold(); + m_thres_max_multivars = dist_util->GetMaxThreshold(); + double thres_range = m_thres_max_multivars - m_thres_min_multivars; m_thres_val_valid = true; - m_threshold_val = (m_sliderdistance->GetValue() * (m_thres_max-m_thres_min)/100.0) + m_thres_min; - m_threshold->ChangeValue( wxString::Format("%f", m_threshold_val)); + m_threshold_val_multivars = (m_sliderdistance->GetValue() * thres_range /100.0) + m_thres_min_multivars; + m_threshold->ChangeValue( wxString::Format("%f", m_threshold_val_multivars)); m_bandwidth_thres_val_valid = true; - m_bandwidth_thres_val = (m_bandwidth_slider->GetValue() * (m_thres_max-m_thres_min)/100.0) + m_thres_min; - m_manu_bandwidth->ChangeValue( wxString::Format("%f", m_bandwidth_thres_val) ); - // UpdateCreateButtonState + m_bandwidth_thres_val_multivars = (m_bandwidth_slider->GetValue() * thres_range/100.0) + m_thres_min_multivars; + m_manu_bandwidth->ChangeValue( wxString::Format("%f", m_bandwidth_thres_val_multivars) ); } void CreatingWeightDlg::OnDistanceWeightsInputUpdate( wxBookCtrlEvent& event ) @@ -257,15 +308,27 @@ void CreatingWeightDlg::OnDistanceWeightsInputUpdate( wxBookCtrlEvent& event ) int sel = event.GetSelection(); if (sel == 0) { UpdateThresholdValues(); + m_nb_distance_methods->Enable(); + //m_dist_choice_vars->SetSelection(0); } else { wxArrayInt selections; m_Vars->GetSelections(selections); int n_sel = selections.GetCount(); - if (n_sel <= 0) { + if (n_sel <= 0 || m_dist_choice_vars->GetSelection() == 0) { m_thres_val_valid = false; m_threshold->ChangeValue("0"); m_bandwidth_thres_val_valid = false; m_manu_bandwidth->ChangeValue("0"); + m_nb_distance_methods->Disable(); + } else { + m_nb_distance_methods->Enable(); + double thres_range = m_thres_max_multivars - m_thres_min_multivars; + m_thres_val_valid = true; + m_threshold_val_multivars = (m_sliderdistance->GetValue() * thres_range /100.0) + m_thres_min_multivars; + m_threshold->ChangeValue( wxString::Format("%f", m_threshold_val_multivars)); + m_bandwidth_thres_val_valid = true; + m_bandwidth_thres_val_multivars = (m_bandwidth_slider->GetValue() * thres_range/100.0) + m_thres_min_multivars; + m_manu_bandwidth->ChangeValue( wxString::Format("%f", m_bandwidth_thres_val_multivars) ); } } } @@ -519,17 +582,27 @@ void CreatingWeightDlg::OnCThresholdSliderUpdated( wxCommandEvent& event ) wxLogMessage("Click CreatingWeightDlg::OnCThresholdSliderUpdated:"); if (!all_init) return; - bool m_rad_inv_dis_val = false; - m_threshold_val = (m_sliderdistance->GetValue() * (m_thres_max-m_thres_min)/100.0) + m_thres_min; - m_threshold->ChangeValue( wxString::Format("%f", (double) m_threshold_val)); - if (m_threshold_val > 0) { - FindWindow(XRCID("wxID_OK"))->Enable(true); - } - - wxString str_val; - str_val << m_threshold_val; - wxLogMessage(str_val); + int dist_var_type = m_nb_distance_variables->GetSelection(); + if (dist_var_type == 0) { + m_threshold_val = (m_sliderdistance->GetValue() * (m_thres_max-m_thres_min)/100.0) + m_thres_min; + m_threshold->ChangeValue( wxString::Format("%f", (double) m_threshold_val)); + if (m_threshold_val > 0) { + FindWindow(XRCID("wxID_OK"))->Enable(true); + } + wxString str_val; + str_val << m_threshold_val; + wxLogMessage(str_val); + } else { + m_threshold_val_multivars = (m_sliderdistance->GetValue() * (m_thres_max_multivars-m_thres_min_multivars)/100.0) + m_thres_min_multivars; + m_threshold->ChangeValue( wxString::Format("%f", (double) m_threshold_val_multivars)); + if (m_threshold_val_multivars > 0) { + FindWindow(XRCID("wxID_OK"))->Enable(true); + } + wxString str_val; + str_val << m_threshold_val_multivars; + wxLogMessage(str_val); + } } void CreatingWeightDlg::OnCBandwidthThresholdSliderUpdated( wxCommandEvent& event ) @@ -538,15 +611,26 @@ void CreatingWeightDlg::OnCBandwidthThresholdSliderUpdated( wxCommandEvent& even if (!all_init) return; - m_bandwidth_thres_val = (m_bandwidth_slider->GetValue() * (m_thres_max-m_thres_min)/100.0) + m_thres_min; - m_manu_bandwidth->ChangeValue( wxString::Format("%f", (double) m_bandwidth_thres_val)); - if (m_bandwidth_thres_val > 0) { - m_btn_ok->Enable(true); + int dist_var_type = m_nb_distance_variables->GetSelection(); + if (dist_var_type == 0) { + m_bandwidth_thres_val = (m_bandwidth_slider->GetValue() * (m_thres_max-m_thres_min)/100.0) + m_thres_min; + m_manu_bandwidth->ChangeValue( wxString::Format("%f", (double) m_bandwidth_thres_val)); + if (m_bandwidth_thres_val > 0) { + m_btn_ok->Enable(true); + } + wxString str_val; + str_val << m_bandwidth_thres_val; + wxLogMessage(str_val); + } else { + m_bandwidth_thres_val_multivars = (m_bandwidth_slider->GetValue() * (m_thres_max_multivars-m_thres_min_multivars)/100.0) + m_thres_min_multivars; + m_manu_bandwidth->ChangeValue( wxString::Format("%f", (double) m_bandwidth_thres_val_multivars)); + if (m_bandwidth_thres_val_multivars > 0) { + m_btn_ok->Enable(true); + } + wxString str_val; + str_val << m_bandwidth_thres_val_multivars; + wxLogMessage(str_val); } - - wxString str_val; - str_val << m_bandwidth_thres_val; - wxLogMessage(str_val); } void CreatingWeightDlg::OnCSpinPowerInverseDistUpdated( wxSpinEvent& event ) @@ -793,7 +877,20 @@ void CreatingWeightDlg::InitDlg() m_dist_choice->Append("Arc Distance (mi)"); m_dist_choice->Append("Arc Distance (km)"); m_dist_choice->SetSelection(0); + + m_dist_choice_vars->Clear(); + m_dist_choice_vars->Append(""); + m_dist_choice_vars->Append("Euclidean Distance"); + m_dist_choice_vars->Append("Manhattan Distance"); + m_dist_choice_vars->SetSelection(0); + m_trans_choice_vars->Clear(); + m_trans_choice_vars->Append("Raw"); + m_trans_choice_vars->Append("Demean"); + m_trans_choice_vars->Append("Standardize (Z)"); + m_trans_choice_vars->Append("Standardize (MAD)"); + m_trans_choice_vars->SetSelection(2); + m_radio_queen->SetValue(true); // Previously from OpenShapefile: @@ -818,6 +915,7 @@ void CreatingWeightDlg::InitDlg() m_nb_weights_type->Enable(false); if (user_xy) { + // MDS create weights m_X_time->Hide(); m_Y_time->Hide(); m_dist_choice->Hide(); @@ -826,6 +924,7 @@ void CreatingWeightDlg::InitDlg() FindWindow(XRCID("IDC_STATIC_DIST_METRIC"))->Hide(); FindWindow(XRCID("IDC_STATIC_XCOORD_VAR"))->Hide(); FindWindow(XRCID("IDC_STATIC_YCOORD_VAR"))->Hide(); + m_nb_distance_variables->Hide(); } Refresh(); @@ -982,6 +1081,66 @@ double CreatingWeightDlg::GetBandwidth() return bandwidth; } +bool CreatingWeightDlg::CheckTableVariableInput() +{ + if (m_nb_distance_variables->GetSelection()> 0) { + + } + return true; +} + +void CreatingWeightDlg::CreateWeightsFromTable(WeightsMetaInfo& wmi) +{ + if (CheckTableVariableInput() == false) { + return; + } + GeoDa::Weights w; + + int method = m_nb_distance_methods->GetSelection(); + if (method == 0) { + // distance band + double band = m_threshold_val_multivars; + double power = 1.0; + bool is_inverse = m_use_inverse->IsChecked(); + if (is_inverse) { + // if use inverse distance + wxString inverse_val = m_power->GetValue(); + if (inverse_val.ToDouble(&power)) { + power = -power; + } + } + w = dist_util->CreateDistBandWeights(band, is_inverse, power); + + } else if ( method == 1) { + // kNN + int k = m_spinneigh->GetValue(); + double power = 1.0; + bool is_inverse = m_use_inverse_knn->IsChecked(); + if ( is_inverse) { + // if use inverse distance + wxString inverse_val = m_power_knn->GetValue(); + if (inverse_val.ToDouble(&power)) { + power = -power; + } + } + w = dist_util->CreateKNNWeights(k, is_inverse, power); + + } else if ( method == 2) { + // adaptive kernel + int kernel_type = m_kernel_methods->GetSelection(); + bool apply_kernel_to_diag = m_kernel_diagnals->GetValue(); + double bandwidth = GetBandwidth(); + bool is_adaptive_bandwidth = m_radio_adaptive_bandwidth->GetValue(); + int k = m_spinn_kernel->GetValue(); + + if (m_radio_manu_bandwdith->GetValue() == true) { + w = dist_util->CreateAdaptiveKernelWeights(kernel_type, bandwidth, apply_kernel_to_diag); + } else { + w = dist_util->CreateAdaptiveKernelWeights(kernel_type, k, is_adaptive_bandwidth, apply_kernel_to_diag); + } + } +} + bool CreatingWeightDlg::CheckThresholdInput() { if (m_nb_weights_type->GetSelection() == 0) { diff --git a/DialogTools/CreatingWeightDlg.h b/DialogTools/CreatingWeightDlg.h index 3843ab75a..b7bb2a110 100644 --- a/DialogTools/CreatingWeightDlg.h +++ b/DialogTools/CreatingWeightDlg.h @@ -34,6 +34,7 @@ #include "../DataViewer/TableStateObserver.h" #include "../ShapeOperations/WeightsManStateObserver.h" #include "../VarCalc/WeightsMetaInfo.h" +#include "../Weights/DistUtils.h" class wxSpinButton; class FramesManager; @@ -92,6 +93,7 @@ public TableStateObserver, public WeightsManStateObserver void OnCSpinPowerInverseKNNUpdated( wxSpinEvent& event ); void OnDistanceWeightsInputUpdate( wxBookCtrlEvent& event ); void OnDistanceWeightsVarsSel( wxCommandEvent& event ); + void OnDistanceMetricVarsSel( wxCommandEvent& event ); /** Implementation of FramesManagerObserver interface */ virtual void update(FramesManager* o); @@ -109,7 +111,7 @@ public TableStateObserver, public WeightsManStateObserver void SetXCOO(const std::vector& xx); void SetYCOO(const std::vector& yy); -private: +protected: bool all_init; @@ -125,6 +127,8 @@ public TableStateObserver, public WeightsManStateObserver wxCheckBox* m_cbx_precision_threshold; wxTextCtrl* m_txt_precision_threshold; // distance weight + wxChoice* m_trans_choice_vars; + wxChoice* m_dist_choice_vars; wxChoice* m_dist_choice; wxChoice* m_X; wxChoice* m_X_time; @@ -173,8 +177,14 @@ public TableStateObserver, public WeightsManStateObserver double m_thres_min; // minimum to avoid isolates double m_thres_max; // maxiumum to include everything double m_threshold_val; - bool m_thres_val_valid; double m_bandwidth_thres_val; + + double m_thres_min_multivars; // minimum to avoid isolates + double m_thres_max_multivars; // maxiumum to include everything + double m_threshold_val_multivars; + double m_bandwidth_thres_val_multivars; + + bool m_thres_val_valid; bool m_bandwidth_thres_val_valid; const double m_thres_delta_factor; bool m_cbx_precision_threshold_first_click; @@ -183,6 +193,8 @@ public TableStateObserver, public WeightsManStateObserver std::vector m_XCOO; std::vector m_YCOO; + GeoDa::DistUtils* dist_util; + WeightsMetaInfo::DistanceMetricEnum dist_metric; WeightsMetaInfo::DistanceUnitsEnum dist_units; WeightsMetaInfo::DistanceValuesEnum dist_values; @@ -196,6 +208,7 @@ public TableStateObserver, public WeightsManStateObserver // updates the enable/disable state of the Create button based // on the values of various other controls. + void UpdateThresholdValuesMultiVars(); void UpdateCreateButtonState(); void UpdateTmSelEnableState(); void UpdateThresholdValues(); @@ -204,6 +217,8 @@ public TableStateObserver, public WeightsManStateObserver void InitDlg(); bool CheckID(const wxString& id); bool CheckThresholdInput(); + bool CheckTableVariableInput(); + void CreateWeightsFromTable(WeightsMetaInfo& wmi); double GetBandwidth(); bool IsSaveAsGwt(); // determine if save type will be GWT or GAL. bool WriteWeightFile(GalWeight* Wp_gal, GwtWeight* Wp_gwt, diff --git a/GenUtils.cpp b/GenUtils.cpp index 093ab3325..d9cd648f9 100644 --- a/GenUtils.cpp +++ b/GenUtils.cpp @@ -1333,6 +1333,23 @@ void GenUtils::DeviationFromMean(std::vector& data) for (int i=0, iend=data.size(); i& data, std::vector& undef) +{ + if (data.size() == 0) return; + double sum = 0.0; + int n = 0; + for (int i=0, iend=data.size(); i& data, std::vector >& data, std::vector >& undefs) +{ + if (trans_type < 1) { + return; + } + for (size_t i=0; i& x, std::vector& y) { int nObs = x.size(); @@ -1496,6 +1532,33 @@ bool GenUtils::StandardizeData(std::vector& data) return true; } +bool GenUtils::StandardizeData(std::vector& data, std::vector& undef) +{ + int nObs = data.size(); + if (nObs <= 1) return false; + + int nValid = 0; + for (int i=0; i >& data, + vector >& undef); + void MeanAbsoluteDeviation(int nObs, double* data); void MeanAbsoluteDeviation(int nObs, double* data, vector& undef); void MeanAbsoluteDeviation(vector& data); void MeanAbsoluteDeviation(vector& data, vector& undef); + void DeviationFromMean(int nObs, double* data); void DeviationFromMean(int nObs, double* data, vector& undef); void DeviationFromMean(vector& data); + void DeviationFromMean(std::vector& data, std::vector& undef); + double Sum(vector& data); double SumOfSquares(vector& data); + bool StandardizeData(int nObs, double* data); bool StandardizeData(int nObs, double* data, vector& undef); bool StandardizeData(vector& data); + bool StandardizeData(vector& data, vector& undef); + double Correlation(vector& x, vector& y); double GetVariance(vector& data); wxString swapExtension(const wxString& fname, const wxString& ext); diff --git a/rc/GdaAppResources.cpp b/rc/GdaAppResources.cpp index d8ed25eb1..438fcff80 100644 --- a/rc/GdaAppResources.cpp +++ b/rc/GdaAppResources.cpp @@ -15530,7 +15530,7 @@ static unsigned char xml_res_file_7[] = { 16,48,4,12,1,67,192,16,48,4,12,1,67,160,133,35,240,255,75,175,9,51,209, 227,12,205,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_8 = 389594; +static size_t xml_res_size_8 = 391933; 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,117,116,102,45,56,34,63,62,10,60,114,101, @@ -22194,71 +22194,6 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,95,68,73,83,84, -95,77,69,84,82,73,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,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,116,97,110,99,101,32,109,101,116,114,105,99,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,76,69,70,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, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,68,73,83,84,65,78,67,69,95,77, -69,84,82,73,67,34,62,10,32,32,32,32,32,32,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,57,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,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,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,32,32,32,32,60,118,103,97,112,62,53,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,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,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,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,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,102, -108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,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,60,111,98,106,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,86,97, -114,105,97,98,108,101,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,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,73,68,67,95,78,66,95,68,73,83,84,65,78,67,69,95,86,65, 82,73,65,66,76,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -22432,177 +22367,122 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,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,111,109,101,116,114,105,99,32,99,101,110,116,114,111,105, -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,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,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,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,73,68,67,95,78,66,95,80,65,71,69,95,77,85,76,84,73,95,86,65,82,83, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,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,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,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,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,32,32,32,32,32,32,32,32,32,32, +32,32,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,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,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,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,67,69,78,84,69,82,60,47,102,108,97,103,62,10,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,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,49,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32, -32,32,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, +60,115,105,122,101,62,51,48,44,50,60,47,115,105,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,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,87,69,73,71,72,84,83,95,68,73,83, -84,95,86,65,82,83,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,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, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,83,84,65,84, +73,67,95,68,73,83,84,95,77,69,84,82,73,67,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,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,48,44,51,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,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,76,66,95,77,85,76,84,73,80,76,69,32,124,32,119,120, -76,66,95,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,60,108,97,98,101,108,62,32,68,105,115,116,97,110,99, +101,32,109,101,116,114,105,99,58,32,60,47,108,97,98,101,108,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,68,73,83,84,65,78,67,69,95,77,69,84,82,73, +67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,57,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,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,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,56,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,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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, -45,118,97,114,105,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,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,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,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,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,60,111,98,106, -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,77,101,116,104,111,100,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,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95,78,66,95, -68,73,83,84,65,78,67,69,95,87,69,73,71,72,84,83,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -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,73,68,67,95,82,65,68,73,79,95,68, -73,83,84,65,78,67,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,32,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,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,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,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, -84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,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,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,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,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,112,101, -99,105,102,121,32,98,97,110,100,119,105,100,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,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,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,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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,111, +109,101,116,114,105,99,32,99,101,110,116,114,111,105,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,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,73,68,67,95, +78,66,95,80,65,71,69,95,77,85,76,84,73,95,86,65,82,83,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,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,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,49,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,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, +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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, -101,61,34,73,68,67,95,84,72,82,69,83,72,79,76,68,95,69,68,73,84,34,62,10, +97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,87,69,73,71,72,84,83,95,68,73,83,84,95,86,65,82,83,95, +76,73,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,57,48,44, -45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,54,48,44,51,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,60,115,116,121,108,101,62,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +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,77,85,76,84,73,80,76,69,32,124,32,119,120,76,66,95,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -22611,209 +22491,155 @@ static unsigned char xml_res_file_8[] = { 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, 105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,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,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,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,32,32,32,32,32,32,60,115,105,122,101,62,51,48,44,50,60,47,115,105,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +120,65,76,73,71,78,95,67,69,78,84,69,82,32,124,32,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,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,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,108,105,100,101,114,34,32,110,97,109,101,61,34,73,68,67,95,84,72, -82,69,83,72,79,76,68,95,83,76,73,68,69,82,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,73,68,67,95,83,84,65,84,73,67,95,68,73,83,84,95,84,82,65, +78,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,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,97,110,115,102,111,114,109,97,116,105,111,110,58,32,32,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,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,53,48,44,45,49,60,47,115, -105,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,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,62,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,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,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,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32, +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,73,68,67,95,68,73, +83,84,65,78,67,69,95,84,82,65,78,83,70,79,82,77,65,84,73,79,78,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,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,97,120,62,49,48,48,60,47,109,97,120, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,76,95,72,79,82,73,90,79,78,84,65,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,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,57,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,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,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,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,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,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73, -68,67,95,67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78,67,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62, -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,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73, -83,84,65,78,67,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,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,105,110,118,101,114,115,101,32,100,105, -115,116,97,110,99,101,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,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32, -32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,48,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,119, -101,114,60,47,108,97,98,101,108,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,32, +124,32,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,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,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,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,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,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,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,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, 116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,83,84,65,84,73,67,95,68, +73,83,84,95,77,69,84,82,73,67,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,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,105,115,116,97,110,99,101,32,109, +101,116,114,105,99,58,32,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,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,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,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, +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,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,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,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,73,68,67,95,68,73,83,84,65,78,67,69,95,77,69,84,82,73,67,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,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,32,60,115,105,122,101,62,57,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,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, -110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, -73,78,95,80,79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,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,83,80,95,86,69,82,84,73,67,65,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,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,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,32,32,32,32, -60,118,97,108,117,101,62,48,60,47,118,97,108,117,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,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +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,56,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,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,60,47,109,105,110,62, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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,32,118,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,32,32,32,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,97,120,62,49,48,48, -60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,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,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,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,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,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,60,111,98, +106,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,77,101,116,104,111,100, +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,32,32,32,32,60,108, -97,98,101,108,62,68,105,115,116,97,110,99,101,32,98,97,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,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,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, -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,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,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,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, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,73,68,67,95, +78,66,95,68,73,83,84,65,78,67,69,95,87,69,73,71,72,84,83,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,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,73,68,67,95,82,65,68,73,79, +95,68,73,83,84,65,78,67,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,32,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,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,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,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, 108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, @@ -22830,36 +22656,12 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -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,124,119,120,65,68,74,85,83,84,95,77,73,78,83,73,90,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,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,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,83,84,65,84,73,67,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,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,111,102, -32,110,101,105,103,104,98,111,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,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, -120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73, -84,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -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,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,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,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,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,112,101,99,105,102,121,32,98,97,110,100,119,105,100,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,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, @@ -22873,33 +22675,84 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 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,32,32,32,32, -32,32,60,115,105,122,101,62,50,44,50,60,47,115,105,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,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, -110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, -73,78,95,75,78,78,34,62,10,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,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,84,72,82,69,83,72,79, +76,68,95,69,68,73,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,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,57,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,32,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,73,71,72,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,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,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,105,110,62,48,60,47,109,105,110,62,10,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,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,97,120,62,49,48,48,60,47,109,97, -120,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,115,105,122,101, +62,51,48,44,50,60,47,115,105,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,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,108,105,100,101,114,34,32,110,97, +109,101,61,34,73,68,67,95,84,72,82,69,83,72,79,76,68,95,83,76,73,68,69, +82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,53,48,44,45,49,60,47,115,105,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,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97, +120,62,49,48,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,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,83,76,95,72,79,82,73,90,79,78, +84,65,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,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -22931,110 +22784,360 @@ static unsigned char xml_res_file_8[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, 66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,75,95,73,78,86, -69,82,83,69,95,68,73,83,84,65,78,67,69,95,75,78,78,34,62,10,32,32,32,32, +69,82,83,69,95,68,73,83,84,65,78,67,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,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,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,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,85,83,69,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78,67,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, +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,105,110,118,101,114,115,101,32,100,105,115,116,97,110,99,101,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,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,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,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,49,48,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, +83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,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,119,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,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,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, +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,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,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,124, +119,120,84,69,95,82,73,71,72,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,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80,73,78,95,80,79,87, +69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73,67,65,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,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,32,32,32,32,32,32,32,32,32,32, +32,32,60,109,105,110,62,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,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,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, +116,97,110,99,101,32,98,97,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, +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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,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,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, -61,34,73,68,67,95,85,83,69,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78, -67,69,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,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,105,110,118,101,114,115,101,32,100,105, -115,116,97,110,99,101,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +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,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,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,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,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,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,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, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,124,119,120,65,68,74,85,83,84,95,77,73,78,83,73,90,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,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,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,83, +84,65,84,73,67,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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,60,108,97,98,101,108,62,78,117,109,98,101,114,32,111,102,32,110,101, +105,103,104,98,111,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,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,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,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,67,95,83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,75,78, +78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +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,32,32,32,32,32,32,32,32,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,119, -101,114,60,47,108,97,98,101,108,62,10,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,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,60,111,98,106,101,99,116,32,99,108,97,115,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,32,32,32,32,32,32,60,115,105, +122,101,62,50,44,50,60,47,115,105,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,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, 116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82, -95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,102,108,97, +103,62,119,120,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,32,32,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,124,119,120,84,69,95,82,73,71,72,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, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,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,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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,73,68,67,95,83,80,73,78,95,75,78,78,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73,67,65,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, -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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,105,110,62,48,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,109,97,120,62,49,48,48,60,47,109,97,120,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +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,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,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,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +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,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,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,72,75,95,73,78,86,69,82,83,69,95,68,73,83,84,65,78, +67,69,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +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,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,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,85,83,69,95,73, +78,86,69,82,83,69,95,68,73,83,84,65,78,67,69,95,75,78,78,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,105,110,118,101,114,115,101,32,100,105,115,116,97,110,99,101,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,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,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,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,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,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,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112, -105,110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83, -80,73,78,95,80,79,87,69,82,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,49,48,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,32,32,32,32,60,115,116,121,108,101,62,119,120,83,80,95,86,69,82,84, -73,67,65,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,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,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,48,60,47,118,97,108,117,101,62, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, +83,84,65,84,73,67,95,80,79,87,69,82,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,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,119,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,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,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, +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,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,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,80,79,87,69,82,95,75,78,78,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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, +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,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,124,119,120,84,69,95,82,73,71,72,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,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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,105,110,62,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, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,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,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, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,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,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,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105, +110,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,83,80, +73,78,95,80,79,87,69,82,95,75,78,78,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,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,83,80,95,86,69,82,84,73, +67,65,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,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,62,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,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,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,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, 62,49,48,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -23509,7 +23612,7 @@ static unsigned char xml_res_file_8[] = { 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,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,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,52,56,48,44,50,56,48,60,47,115,105,122,101,62,10,32, +115,105,122,101,62,52,56,48,44,51,48,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,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, @@ -23535,7 +23638,7 @@ static unsigned char xml_res_file_8[] = { 101,108,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,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,115,105,122,101,62,53,48,48,44,53,48,48,60,47, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,48,48,44,53,50,48,60,47, 115,105,122,101,62,10,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,60,47,111,98,106,101,99,116,62,10,32,32,32,32, diff --git a/rc/dialogs.xrc b/rc/dialogs.xrc index f408b434a..ad7867028 100644 --- a/rc/dialogs.xrc +++ b/rc/dialogs.xrc @@ -3575,38 +3575,7 @@ wxVERTICAL - - - - - - - wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL - - - - 98,-1d - - wxALIGN_CENTER - 2 - - - 3 - 1 - 5 - 5 - - wxALIGN_LEFT|wxALL - 2 - - - - wxALIGN_LEFT|wxALL - 2 - - - - + @@ -3673,6 +3642,29 @@ + + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 10 + + wxHORIZONTAL + + 30,2 + + + + + + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL + + + + 98,-1d + + wxALIGN_CENTER + 2 + + + @@ -3690,17 +3682,57 @@ - 150,30d + 160,30d wxALIGN_CENTER + + wxALIGN_CENTER | wxTOP + 10 + + wxHORIZONTAL + + + + + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL + + + + 98,-1d + + wxALIGN_CENTER + 2 + + + + + wxALIGN_CENTER | wxTOP + 5 + + wxHORIZONTAL + + + + + wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL + + + + 98,-1d + + wxALIGN_CENTER + 2 + + + 280,-1d - + wxALL|wxEXPAND @@ -4090,7 +4122,7 @@ wxALL|wxEXPAND - 480,280 + 480,300 wxALL|wxEXPAND wxALL|wxEXPAND @@ -4106,7 +4138,7 @@ wxALL|wxEXPAND - 500,500 + 500,520 wxALL|wxEXPAND wxALL|wxEXPAND|wxALIGN_CENTRE_HORIZONTAL From 8811750e2865b0d4455473855edacfb6ffa694ac Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 28 Nov 2018 14:52:34 -0700 Subject: [PATCH 36/39] #1751 social weights: tests complete --- DialogTools/CreatingWeightDlg.cpp | 101 ++++- DialogTools/CreatingWeightDlg.h | 3 +- ShapeOperations/WeightsManPtree.cpp | 4 + VarCalc/WeightsMetaInfo.cpp | 2 + VarCalc/WeightsMetaInfo.h | 2 +- Weights/DistUtils.cpp | 40 +- kNN/ANN.cpp | 1 + kNN/ANN/ANN.h | 2 +- rc/GdaAppResources.cpp | 557 ++++++++++++++-------------- rc/dialogs.xrc | 12 +- 10 files changed, 402 insertions(+), 322 deletions(-) diff --git a/DialogTools/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp index 4cbbe6237..9470b36e9 100644 --- a/DialogTools/CreatingWeightDlg.cpp +++ b/DialogTools/CreatingWeightDlg.cpp @@ -228,8 +228,8 @@ void CreatingWeightDlg::CreateControls() void CreatingWeightDlg::OnDistanceMetricVarsSel( wxCommandEvent& event ) { - int dist_metric = m_dist_choice_vars->GetSelection(); - if (dist_metric > 0) { + int metric = m_dist_choice_vars->GetSelection(); + if (metric > 0) { m_nb_distance_methods->Enable(); } else { m_thres_val_valid = false; @@ -256,8 +256,8 @@ void CreatingWeightDlg::OnDistanceWeightsVarsSel( wxCommandEvent& event ) void CreatingWeightDlg::UpdateThresholdValuesMultiVars() { // distance metric - int dist_metric = m_dist_choice_vars->GetSelection(); - if (dist_metric < 1) { + int metric = m_dist_choice_vars->GetSelection(); + if (metric < 1) { return; } @@ -289,7 +289,7 @@ void CreatingWeightDlg::UpdateThresholdValuesMultiVars() if (dist_util) { delete dist_util; } - dist_util = new GeoDa::DistUtils(data, dist_metric); + dist_util = new GeoDa::DistUtils(data, metric); m_thres_min_multivars = dist_util->GetMinThreshold(); m_thres_max_multivars = dist_util->GetMaxThreshold(); double thres_range = m_thres_max_multivars - m_thres_min_multivars; @@ -880,8 +880,8 @@ void CreatingWeightDlg::InitDlg() m_dist_choice_vars->Clear(); m_dist_choice_vars->Append(""); - m_dist_choice_vars->Append("Euclidean Distance"); m_dist_choice_vars->Append("Manhattan Distance"); + m_dist_choice_vars->Append("Euclidean Distance"); m_dist_choice_vars->SetSelection(0); m_trans_choice_vars->Clear(); @@ -1083,18 +1083,42 @@ double CreatingWeightDlg::GetBandwidth() bool CreatingWeightDlg::CheckTableVariableInput() { - if (m_nb_distance_variables->GetSelection()> 0) { + // check selected variables + wxArrayInt selections; + m_Vars->GetSelections(selections); + if (selections.GetCount() == 0) { + wxString msg = _("Please select at least one variable."); + wxMessageDialog dlg(this, msg, _("Warning"), wxOK | wxICON_WARNING); + dlg.ShowModal(); + return false; + } + + // check distance metric + if (m_dist_choice_vars->GetSelection() == 0) { + wxString msg = _("Please specify distance metric."); + wxMessageDialog dlg(this, msg, _("Warning"), wxOK | wxICON_WARNING); + dlg.ShowModal(); + return false; + } + // check threshold + int method = m_nb_distance_methods->GetSelection(); + if ( method == 0 || method == 2) { + wxString not_valid_msg = _("The currently entered threshold value is not a valid number. Please move the slider, or enter a valid number."); + if ( !m_thres_val_valid || !m_bandwidth_thres_val_valid) { + wxMessageDialog dlg(this, not_valid_msg, _("Error"), wxOK | wxICON_ERROR); + dlg.ShowModal(); + return false; + } } return true; } -void CreatingWeightDlg::CreateWeightsFromTable(WeightsMetaInfo& wmi) +void CreatingWeightDlg::CreateWeightsFromTable(wxString id, wxString outputfile, WeightsMetaInfo& wmi) { - if (CheckTableVariableInput() == false) { - return; - } GeoDa::Weights w; + int metric = m_dist_choice_vars->GetSelection(); + WeightsMetaInfo::DistanceMetricEnum dist_metric = metric == 1 ? WeightsMetaInfo::DM_manhattan : WeightsMetaInfo::DM_euclidean; int method = m_nb_distance_methods->GetSelection(); if (method == 0) { @@ -1110,6 +1134,7 @@ void CreatingWeightDlg::CreateWeightsFromTable(WeightsMetaInfo& wmi) } } w = dist_util->CreateDistBandWeights(band, is_inverse, power); + wmi.SetToThres(id, dist_metric, WeightsMetaInfo::DU_unspecified, "", WeightsMetaInfo::DV_vars, band, power); } else if ( method == 1) { // kNN @@ -1124,10 +1149,12 @@ void CreatingWeightDlg::CreateWeightsFromTable(WeightsMetaInfo& wmi) } } w = dist_util->CreateKNNWeights(k, is_inverse, power); + wmi.SetToKnn(id, dist_metric, WeightsMetaInfo::DU_unspecified, "", WeightsMetaInfo::DV_vars, k, power); } else if ( method == 2) { // adaptive kernel int kernel_type = m_kernel_methods->GetSelection(); + wxString kernel = m_kernel_methods->GetString(kernel_type); bool apply_kernel_to_diag = m_kernel_diagnals->GetValue(); double bandwidth = GetBandwidth(); bool is_adaptive_bandwidth = m_radio_adaptive_bandwidth->GetValue(); @@ -1138,7 +1165,26 @@ void CreatingWeightDlg::CreateWeightsFromTable(WeightsMetaInfo& wmi) } else { w = dist_util->CreateAdaptiveKernelWeights(kernel_type, k, is_adaptive_bandwidth, apply_kernel_to_diag); } + wmi.SetToKernel(id, dist_metric, WeightsMetaInfo::DU_unspecified, "", WeightsMetaInfo::DV_vars, kernel, k, bandwidth, is_adaptive_bandwidth, apply_kernel_to_diag); + } + + // save to file + GwtWeight* Wp = new GwtWeight; + Wp->num_obs = w.size(); + Wp->is_symmetric = false; + Wp->symmetry_checked = true; + Wp->gwt = new GwtElement[Wp->num_obs]; + for (size_t i=0; igwt[i]; + e.alloc(w[i].size()); + for (size_t j=0; jGetProjectTitle(), outputfile, id, wmi); } bool CreatingWeightDlg::CheckThresholdInput() @@ -1171,14 +1217,15 @@ bool CreatingWeightDlg::CheckThresholdInput() ( !is_dist_band && m_bandwidth_thres_val*m_thres_delta_factor < m_thres_min) ) { wxString msg; - if (is_dist_band) + if (is_dist_band) { msg = wxString::Format(nbrless_msg, m_threshold_val, m_thres_min); - else + } else { msg = wxString::Format(nbrless_msg, m_bandwidth_thres_val, m_thres_min); - + } wxMessageDialog dlg(this, msg, _("Warning"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION ); - if (dlg.ShowModal() != wxID_YES) + if (dlg.ShowModal() != wxID_YES) { return false; + } } return true; } @@ -1219,13 +1266,21 @@ void CreatingWeightDlg::CreateWeights() dlg.ShowModal(); return; } - - if (!CheckThresholdInput()) - return; wxString id = m_id_field->GetString(m_id_field->GetSelection()); - if (!CheckID(id)) + if (!CheckID(id)) { return; + } + + if (m_nb_distance_variables->GetSelection() == 1) { + if (CheckTableVariableInput() == false) { + return; + } + } else { + if (!CheckThresholdInput()) { + return; + } + } wxString wildcard; wxString defaultFile(project->GetProjectTitle()); @@ -1258,11 +1313,17 @@ void CreatingWeightDlg::CreateWeights() wxLogMessage("CreateWeights()"); wxLogMessage(outputfile); + // 1/2 case social weights: + if (m_nb_distance_variables->GetSelection() == 1) { + CreateWeightsFromTable(id, outputfile, wmi); + return; + } + + // 2/2 other cases: int m_ooC = m_spincont->GetValue(); int m_kNN = m_spinneigh->GetValue(); int m_kernel_kNN = m_spinn_kernel->GetValue(); int m_alpha = 1; - bool done = false; wxString str_X = m_X->GetString(m_X->GetSelection()); diff --git a/DialogTools/CreatingWeightDlg.h b/DialogTools/CreatingWeightDlg.h index b7bb2a110..d5c13e1d1 100644 --- a/DialogTools/CreatingWeightDlg.h +++ b/DialogTools/CreatingWeightDlg.h @@ -218,7 +218,8 @@ public TableStateObserver, public WeightsManStateObserver bool CheckID(const wxString& id); bool CheckThresholdInput(); bool CheckTableVariableInput(); - void CreateWeightsFromTable(WeightsMetaInfo& wmi); + void CreateWeightsFromTable(wxString id, wxString outputfile, + WeightsMetaInfo& wmi); double GetBandwidth(); bool IsSaveAsGwt(); // determine if save type will be GWT or GAL. bool WriteWeightFile(GalWeight* Wp_gal, GwtWeight* Wp_gwt, diff --git a/ShapeOperations/WeightsManPtree.cpp b/ShapeOperations/WeightsManPtree.cpp index 28c85ceef..8756e8cf1 100644 --- a/ShapeOperations/WeightsManPtree.cpp +++ b/ShapeOperations/WeightsManPtree.cpp @@ -157,6 +157,8 @@ void WeightsManPtree::ReadPtree(const boost::property_tree::ptree& pt, wxString s = v.second.data(); if (s == "euclidean") { e.wmi.dist_metric = WeightsMetaInfo::DM_euclidean; + } else if (s == "manhattan") { + e.wmi.dist_metric = WeightsMetaInfo::DM_manhattan; } else if (s == "arc") { e.wmi.dist_metric = WeightsMetaInfo::DM_arc; } else if (s == "unspecified" || s.IsEmpty()) { @@ -332,6 +334,8 @@ void WeightsManPtree::WritePtree(boost::property_tree::ptree& pt, if (e.wmi.dist_metric == WeightsMetaInfo::DM_euclidean) { sssub.put("dist_metric", "euclidean"); + } else if (e.wmi.dist_metric == WeightsMetaInfo::DM_manhattan) { + sssub.put("dist_metric", "manhattan"); } else if (e.wmi.dist_metric == WeightsMetaInfo::DM_arc) { sssub.put("dist_metric", "arc"); } diff --git a/VarCalc/WeightsMetaInfo.cpp b/VarCalc/WeightsMetaInfo.cpp index e1f7756d9..25d06f109 100644 --- a/VarCalc/WeightsMetaInfo.cpp +++ b/VarCalc/WeightsMetaInfo.cpp @@ -295,6 +295,8 @@ wxString WeightsMetaInfo::DistMetricToStr() const { if (dist_metric == DM_euclidean) { return "Euclidean"; + } else if (dist_metric == DM_manhattan) { + return "Manhattan"; } else if (dist_metric == DM_arc) { return "arc"; } diff --git a/VarCalc/WeightsMetaInfo.h b/VarCalc/WeightsMetaInfo.h index 901b4c67e..05756904d 100644 --- a/VarCalc/WeightsMetaInfo.h +++ b/VarCalc/WeightsMetaInfo.h @@ -35,7 +35,7 @@ struct WeightsMetaInfo DV_unspecified, DV_centroids, DV_mean_centers, DV_vars, DV_coordinates }; enum DistanceMetricEnum { - DM_unspecified, DM_euclidean, DM_arc + DM_unspecified, DM_euclidean, DM_arc, DM_manhattan }; enum DistanceUnitsEnum { DU_unspecified, DU_km, DU_mile diff --git a/Weights/DistUtils.cpp b/Weights/DistUtils.cpp index 2d149485f..711ec3928 100644 --- a/Weights/DistUtils.cpp +++ b/Weights/DistUtils.cpp @@ -130,8 +130,8 @@ GeoDa::Weights DistUtils::CreateKNNWeights(int k, bool is_inverse, int power) GeoDa::Weights weights; double w; - ANNidxArray nnIdx = new ANNidx[k]; - ANNdistArray dists = new ANNdist[k]; + ANNidxArray nnIdx = new ANNidx[k+1]; + ANNdistArray dists = new ANNdist[k+1]; for (size_t i=0; iannkSearch(data[i], k+1, nnIdx, dists); @@ -161,8 +161,8 @@ GeoDa::Weights DistUtils::CreateAdaptiveKernelWeights(int kernel_type, int k, GeoDa::Weights weights; double w; double max_knn_bandwidth = 0; - ANNidxArray nnIdx = new ANNidx[k]; - ANNdistArray dists = new ANNdist[k]; + ANNidxArray nnIdx = new ANNidx[k+1]; + ANNdistArray dists = new ANNdist[k+1]; if (is_adaptive_bandwidth) { for (size_t i=0; i > nbrs; double local_band = 0; for (size_t j=0; j local_band) { - local_band = dists[j]; - } + // iter each neighbor, include itself + if (dists[j] > local_band) { + local_band = dists[j]; } } local_band = ANN_ROOT(local_band); for (size_t j=0; j 0 ? w / local_band : 0; - nbrs.push_back(std::make_pair(nnIdx[j], w)); - } + w = ANN_ROOT(dists[j]); + w = local_band > 0 ? w / local_band : 0; + nbrs.push_back(std::make_pair(nnIdx[j], w)); } weights.push_back(nbrs); } @@ -197,12 +193,10 @@ GeoDa::Weights DistUtils::CreateAdaptiveKernelWeights(int kernel_type, int k, std::vector > nbrs; for (size_t j=0; j max_knn_bandwidth) { - max_knn_bandwidth = w; - } + w = ANN_ROOT(dists[j]); + nbrs.push_back(std::make_pair(nnIdx[j], w)); + if (w > max_knn_bandwidth) { + max_knn_bandwidth = w; } } weights.push_back(nbrs); @@ -237,10 +231,8 @@ GeoDa::Weights DistUtils::CreateAdaptiveKernelWeights(int kernel_type, double ba std::vector > nbrs; for (size_t j=0; j wxVERTICAL - + + wxALIGN_LEFT|wxALL + 2 + + + + @@ -4122,7 +4128,7 @@ wxALL|wxEXPAND - 480,300 + 480,320 wxALL|wxEXPAND wxALL|wxEXPAND @@ -4138,7 +4144,7 @@ wxALL|wxEXPAND - 500,520 + 500,540 wxALL|wxEXPAND wxALL|wxEXPAND|wxALIGN_CENTRE_HORIZONTAL From 46b308ca7d5fe4c84e5cf3aa2457705795abde1f Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 28 Nov 2018 17:02:33 -0700 Subject: [PATCH 37/39] update build scripts for osx --- BuildTools/macosx/GNUmakefile | 5 ++++- Weights/GNUmakefile | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Weights/GNUmakefile diff --git a/BuildTools/macosx/GNUmakefile b/BuildTools/macosx/GNUmakefile index 16ca8e31b..4eb8c9d7e 100644 --- a/BuildTools/macosx/GNUmakefile +++ b/BuildTools/macosx/GNUmakefile @@ -11,7 +11,7 @@ default: compile-geoda app: build-geoda-mac -compile-geoda: ogl-target io-target algorithms-target dataviewer-target dialogtools-target \ +compile-geoda: weights-target ogl-target io-target algorithms-target dataviewer-target dialogtools-target \ knn-target explore-target libgdiam-target regression-target \ shapeoperations-target resource-target varcalc-target \ geoda-target @@ -22,6 +22,9 @@ test: resource-target: (cd $(GeoDa_ROOT)/rc; $(MAKE) xrc; $(MAKE)) +weights-target: + (cd $(GeoDa_ROOT)/Weights; $(MAKE)) + ogl-target: (cd $(GeoDa_ROOT)/ogl; $(MAKE)) diff --git a/Weights/GNUmakefile b/Weights/GNUmakefile new file mode 100644 index 000000000..e72fae931 --- /dev/null +++ b/Weights/GNUmakefile @@ -0,0 +1,16 @@ + +include ../GeoDamake.opt + +#include ./file.lst + +CPPFLAGS := $(CPPFLAGS) +CXXFLAGS := $(CXXFLAGS) + +CXX_SRCS := $(wildcard *.cpp) +OBJ := ${CXX_SRCS:.cpp=.o} + +default: $(O_OBJ:.o=.$(OBJ_EXT)) + +clean: + rm -f *.o + From 9aacabe41f6a3f74d2e55571dc2665b87e336e46 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 29 Nov 2018 20:47:03 -0700 Subject: [PATCH 38/39] Update DistUtils.cpp fix an issue when get estimated max threshold value --- Weights/DistUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Weights/DistUtils.cpp b/Weights/DistUtils.cpp index 711ec3928..40389a06d 100644 --- a/Weights/DistUtils.cpp +++ b/Weights/DistUtils.cpp @@ -81,7 +81,7 @@ double DistUtils::GetMaxThreshold() ANNdistArray dists = new ANNdist[k]; for (size_t i=0; iannkSearch(data[i], k, nnIdx, dists); + kdTree->annkSearch(data[x_idx], k, nnIdx, dists); y_idx = nnIdx[k-1]; kdTree->annkSearch(data[y_idx], k, nnIdx, dists); if (dists[k-1] > dist_cand) { From 626de7d19e77c7329c663a980495bfd52616f90d Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 3 Dec 2018 16:31:40 -0700 Subject: [PATCH 39/39] report weights for geometric centroids #1760 --- DialogTools/AbstractClusterDlg.cpp | 24 ++++++++++++++++++++++++ DialogTools/KMeansDlg.cpp | 13 +++++++++++++ Weights/DistUtils.cpp | 1 + 3 files changed, 38 insertions(+) diff --git a/DialogTools/AbstractClusterDlg.cpp b/DialogTools/AbstractClusterDlg.cpp index c3d67f258..1ad086458 100644 --- a/DialogTools/AbstractClusterDlg.cpp +++ b/DialogTools/AbstractClusterDlg.cpp @@ -737,6 +737,30 @@ double AbstractClusterDlg::CreateSummary(const vector >& solution, c if (isolated.size()>0) summary << _("Number of not clustered observations: ") << isolated.size() << "\n"; summary << _printConfiguration(); + + // auto weighting + if (m_use_centroids->IsChecked()) { + wxString w_val = m_wc_txt->GetValue(); + double w_valf = 0; + if (w_val.ToDouble(&w_valf)) { + double w_valf_vars = 1 - w_valf; + w_valf = w_valf * 0.5; + w_valf_vars = w_valf_vars / (columns - 2); + + summary << _("Use geometric centroids (weighting): \n"); + for (int i=0; iGetValue(); + long value_ncluster; + if (str_ncluster.ToLong(&value_ncluster)) { + ncluster = value_ncluster; + } + if (ncluster < 2 || ncluster > num_obs) { + wxString err_msg = _("Please enter a valid number of clusters."); + wxMessageDialog dlg(NULL, err_msg, _("Error"), wxOK | wxICON_ERROR); + dlg.ShowModal(); + return; + } + double mid = left + delta /2.0; // assume left is always not contiguity and right is always contiguity diff --git a/Weights/DistUtils.cpp b/Weights/DistUtils.cpp index 40389a06d..68dce194e 100644 --- a/Weights/DistUtils.cpp +++ b/Weights/DistUtils.cpp @@ -43,6 +43,7 @@ DistUtils::~DistUtils() delete kdTree; } } + double DistUtils::GetMinThreshold() { double max_1nn_dist = 0;