
    ը	f                        d Z ddlZddlZddlZddlZddlZddl 	 ddl ddl dZ	dZ
ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZ ddlmZ ddlm Z  ddl!m"Z"m#Z#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7m8Z8m9Z9m:Z: ddl;m<Z< ddl=m>Z>  G d de      Z? G d dee?      Z@ G d d      ZAd ZBeCd k(  r eB        yy# e$ rZdZ	 ed      ez  Z
Y dZ[dZ[ww xY w)!a  
@package iclass.frame

@brief wxIClass frame with toolbar for digitizing training areas and
for spectral signature analysis.

Classes:
 - frame::IClassMapPanel
 - frame::IClassMapDisplay
 - frame::MapManager

(C) 2006-2013 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.

@author Vaclav Petras <wenzeslaus gmail.com>
@author Anna Kratochvilova <kratochanna gmail.com>
    N)*T FzLoading imagery lib failed.
%s)	statusbar)"StandaloneMapDisplayGrassInterface)BufferedMapWindow)VDigitToolbar)DoubleMapPanel
FrameMixin)	globalvar)Map)
RunCommandGMessageGError)SetOpacityDialog)Menu)VectorDBInfo)IClassVDigitWindowIClassVDigit)IClassMapToolbarIClassMiscToolbarIClassToolbarIClassMapManagerToolbar)StatisticsData)IClassCategoryManagerDialogIClassGroupDialogIClassSignatureFileDialogIClassExportAreasDialogIClassMapDialog)	PlotPanel)Signalc                       e Zd ZdZdd ed      g dddfdZd Zd	 Zd
 Zd Z	d Z
d Zd Zd Zd Zd Zd Zd Zd Zd Zd?dZd?dZd Zd Zd Zd Zd Zd Zd Zd Zd  Zd! Zd" Z d# Z!d$ Z"d% Z#d& Z$d' Z%d( Z&d) Z'd* Z(d+ Z)d, Z*d@d-Z+d. Z,d/ Z-d0 Z.d1 Z/d2 Z0d3 Z1d4 Z2d5 Z3d6 Z4d?d7Z5d8 Z6d9 Z7 fd:Z8 fd;Z9 fd<Z:d= Z;d> Z< xZ=S )AIClassMapPanela!  wxIClass main frame

    It has two map windows one for digitizing training areas and one for
    result preview.
    It generates histograms, raster maps and signature files using
    @c I_iclass_* functions from C imagery library.

    It is wxGUI counterpart of old i.class module.
    NSupervised Classification Tool)
iClassMisc	iClassMapvdigitiClass)ik  iX  IClassWindowc           	      P	    t        j                   f|||t               t               d| |r| _        nt	                _        d _        d j                  _        t          j                   j                   j                         _
        t          j                   j                   j                         _         j                   _         j                           j!                   j                          j!                   j                          j                  j#                           j                  j#                           j                  j$                  j'                   fd        j                  j(                  j'                   fd        j+                  |       t-        d       _        t-        d	       _         j3                          |D ]  } j5                  |         j                  j7                   j8                  d
           j;                         j=                         j?                  t@        jB                   jD                         tG          jI                          jK                                _&        tG          jO                          jQ                                _)        d _*        d _+        tY                _-        d jZ                  d<   d jZ                  d<   d jZ                  d<   d jZ                  d<   t]          j                   j^                         _0        tb        jd                  tb        jf                  tb        jh                  tb        jj                  tb        jl                  tb        jn                  g}	 jq                  |	       _9         ju                           jv                  jy                           jL                  j7                   j8                  d           jR                  j7                   j8                  d           j;                         j{                          tA        j|                   j~                          j?                  t@        j                   j                          j                          y)z
        :param parent: (no parent is expected)
        :param title: window title
        :param toolbars: dictionary of active toolbars (default value represents all toolbars)
        :param size: default size
        )parenttitlenamefirstMap	secondMapNT)r*   giface
propertiesmap)r*   r/   r0   r   c                 T    j                   j                  d   j                  |       S NcoordinatesstatusbarManagerstatusbarItemsSetAdditionalInfo)textselfs    -/usr/lib/grass83/gui/wxpython/iclass/frame.py<lambda>z)IClassMapPanel.__init__.<locals>.<lambda>   s)    ..==%     c                  T     j                   j                  d   j                  d       S r3   r5   r:   s   r;   r<   z)IClassMapPanel.__init__.<locals>.<lambda>   s)    D))88% r=   zIClassMapPanel.groupSetzIClassMapPanel.categoryChangedr&   )	mapWindowr   FclassManager
scatt_plot
attributescategory)r/   
stats_dataiClassTrainingMapManageriClassPreviewMapManager)Cr	   __init__r   r/   r   treemapWindowProperties
showRegionr   r-   firstMapWindowr   r.   secondMapWindow	MapWindow_bindWindowsActivation_setUpMapWindowInitZoomHistorydigitizingInfoconnectdigitizingInfoUnavailableSetSizer    groupSetcategoryChangedInitStatistics
AddToolbar
SetToolbartoolbarsGetMapToolbarGetActiveMapToolBindwx
EVT_CHOICEOnUpdateActive
MapManagerGetFirstWindowGetFirstMaptrainingMapManagerGetSecondWindowGetSecondMappreviewMapManagerchangesexportVectordictdialogsr   rE   	plotPanelsbSbCoordinatesSbRegionExtentSbCompRegionExtentSbDisplayGeometry
SbMapScaleSbGoToCreateStatusbarr   	_addPanes_mgrUpdateSelectDefault	CallAfterAddTrainingAreaMapEVT_SIZEOnSizeSendSizeEvent)
r:   r*   r/   r+   r[   sizer,   kwargstoolbr7   s
   `         r;   rH   zIClassMapPanel.__init__U   s     		
Ue	
 	
  DK<TBDK	 /3  +0;;//	
  1;;//	 
 ,,##%T001T112++-,,. 	**22&	

 	55==&	

 	T 89%&FG
  	#EOOE"	#&&t}}X'>?--/44R]]DDWDWX",D//1t7G7G7I#
 ",D0028I8I8K"
   v'+^$%)\"%)\"#'Z  #4X !!  MMII
 --n=		**4==9S+TU))$--8Q*RS 	**,
T,,-		"++t{{+r=   c                    | j                         j                         j                          | j                  j	                          | j                          | j                  j                          | j                          y N)	rc   GetDigitCloseMaprm   CloseWindow_cleanuprw   UnInitDestroyr:   events     r;   OnCloseWindowzIClassMapPanel.OnCloseWindow   sR    &&(113""$		r=   c                 r   t        | j                         t        | j                         | j                  j                         D ]  }t        |        | j                          | j                  j                         D ]6  }| j                  | j                  j                  |      j                         8 y)z;Frees C structs and removes vector map and all raster maps.N)I_free_signatures
signaturesI_free_group_refrefercStatisticsDictvaluesI_iclass_free_statisticsRemoveTempVectorrE   GetCategoriesRemoveTempRasterGetStatistics
rasterName)r:   stis      r;   r   zIClassMapPanel._cleanup   s    $//*$&&--/ 	)B$R(	) 	..0 	OA!!$//"?"?"B"M"MN	Or=   c                 <    | j                   j                  d       y)zShow help pagezwxGUI.iclass)entryN)r/   Helpr   s     r;   OnHelpzIClassMapPanel.OnHelp   s    ~.r=   c                     t        j                  d      }dt        j                  j	                  |      j                  dd      z   S )z9Return new name for temporary vector map (training areas)F)createtrAreas.r   )grasstempfileospathbasenamereplace)r:   
vectorPaths     r;   _getTempVectorNamez!IClassMapPanel._getTempVectorName   s7    ^^51
277++J7??RHHHr=   c                     ||d| _         y)zSet group and subgroup manuallygroupsubgroupN)g)r:   r   r   s      r;   SetGroupzIClassMapPanel.SetGroup   s     h7r=   c                     | j                         }t        j                  j                         }d|d<   dd|df}t	        d
|d   | |d|d   }|dk7  ry	|S )z.Create temporary vector map for training areas1GRASS_VECTOR_TEMPORARYzv.editr   )toolr1   r   )progr*   env   F )r   r   environcopyr   )r:   
vectorNamer   cmdrets        r;   CreateTempVectorzIClassMapPanel.CreateTempVector   sh    ,,.
jjoo(+$%(:>?Ec!fTsEc!fE!8r=   c                 D    t        d| dd| j                        }|dk7  ryy)z0Removes temporary vector map with training areasg.removefvectorr   r*   flagstyper,   r   FT)r   trainingAreaVector)r:   r   s     r;   r   zIClassMapPanel.RemoveTempVector  s0    ((
 !8r=   c                     | j                         j                          | j                         j                          t        d| dd|      }|dk7  ryy)zRemoves temporary raster mapsr   r   rasterr   r   FT)rd   Cleanrg   r   )r:   r   r   s      r;   r   zIClassMapPanel.RemoveTempRaster  sP      "!!#D(
 !8r=   c           	      r   |dk(  r[d| j                   vr#t        | | j                        | j                   |<   | j                  j	                  | j                   |   t
        j                  j                         j                  |      j                  t        d            j                         j                         j                  d      j                  d      j                  d      j!                  d      j#                  d      j%                  d      j'                  d      j)                  d      j+                  | j                   |   j-                                      |dk(  r\d| j                   vr$t/        | | j0                  	      | j                   |<   | j                  j	                  | j                   |   t
        j                  j                         j                  |      j                  t        d
            j                         j                         j                  d      j                  d      j                  d      j!                  d      j#                  d      j%                  d      j'                  d      j)                  d      j+                  | j                   |   j-                                      |dk(  rPd| j                   vrt3        |       | j                   |<   | j                  j	                  | j                   |   t
        j                  j                         j                  |      j                  t        d            j                         j                         j                  d      j                  d      j                  d      j!                  d      j#                  d      j%                  d      j'                  d      j)                  d      j+                  | j                   |   j-                                      |dk(  r~d| j                   vrFt5        | | j                  | j7                         t8        | j:                  g d      | j                   |<   | j                  j	                  | j                   |   t
        j                  j                         j                  |      j                  t        d            j                         j                         j                  d      j                  d      j                  d      j!                  d      j#                  d      j%                  d      j'                  d      j)                  d      j+                  | j                   |   j-                                      | j                  j=                          y)an  Add defined toolbar to the window

        Currently known toolbars are:
         - 'iClassMap'          - basic map toolbar
         - 'iClass'             - iclass tools
         - 'iClassMisc'         - miscellaneous (help)
         - 'vdigit'             - digitizer toolbar (areas)

         Toolbars 'iClassPreviewMapManager' are added in _addPanes().
        r%   zMap ToolbarFT   r   r   r'   )rE   zIClass Toolbarr$   zIClass Misc Toolbarr&   )
addArea
moveVertex	addVertexremoveVertexeditLinemoveLine
deleteAreaundoredosettings)r*   toolSwitcherrN   
digitClassr/   toolszDigitization ToolbarN)r[   r   _toolSwitcherrw   AddPaner_   auiAuiPaneInfoNameCaption_ToolbarPaneTopLeftDockableRightDockableBottomDockableTopDockableCloseButtonLayerRowPositionBestSizeGetBestSizer   rE   r   r   rc   r   r/   rx   r:   r,   s     r;   rY   zIClassMapPanel.AddToolbar  s    ;$--/&6tT=O=O&Pd#IId#""$d=)*e$u%&T"U#qQ!4==.::<>$ 8t}},&3DT__&Ud#IId#""$d+,-e$u%&T"U#qQ!4==.::<>$ <4==0&7&=d#IId#""$d012e$u%&T"U#qQ!4==.::<>$ 8t}},&3!%!3!3"113+;;'d#( IId#""$d123e$u%&T"U#qQ!4==.::<>$ 			r=   c                 x   | j                  dd       | j                  dd       | j                  dd       | j                  dd	       | j                  j                  d
d
       | j                  j	                  | j
                  t        j                  j                         j                  d      j                  t        d            j                  d      j                  d      j                  d      j                         j!                  d      j#                  d             | j%                          y)z5Add mapwindows, toolbars and statusbar to aui managertrainingr   )r,   positionrF   r   previewr   rG      g      ?plotsPlotsF)iO  N)_addPaneMapWindow_addPaneToolbarrw   SetDockSizeConstraintr   rm   r_   r   r   r   r   r   Dockable	Floatabler   Leftr   r   AddStatusbarPaner?   s    r;   rv   zIClassMapPanel._addPanes  s    J;"<qII:";aH 			''S1		NNFF T']WQwZ Xe_Yu[TVU1XXi 	
 	r=   c                    |dk(  r| j                   }n| j                  }t        | |      | j                  |<   | j                  j                  | j                  |   t        j                  j                         j                         j                         j                  |      j                  d      j                         j                  d      j                  |      j!                  | j                  |   j#                                      y )NrG   Fr   )rh   re   r   r[   rw   r   r_   r   r   r   Movabler   r   Centerr   r   r   r   )r:   r,   r   r*   s       r;   r   zIClassMapPanel._addPaneToolbar  s    ,,++F,,F5dFCd		MM$FF []WYT$Z[VXU1XXhXt}}T*668:	
r=   c                    |dk(  r| j                         }t        d      }n| j                         }t        d      }| j                  j	                  |t
        j                  j                         j                  |      j                  |      j                  d      j                  d      j                  d      j                         j                  d      j                  |             y )Nr   zPreview DisplayzTraining Areas DisplayFr   )rf   r   rc   rw   r   r_   r   r   r   r   r   r   r   r   r   r   )r:   r,   r   windowcaptions        r;   r   z IClassMapPanel._addPaneMapWindow  s    9))+F)*G((*F01G		FF T$ZWWXe_Yu[VXU1XXh	
r=   c                 b   | j                         j                         dk(  r#| j                  | _        | j                  | _        n"| j                  | _        | j                  | _        | j                  | j                         t        j                  dk(  r| j                  j                          yy)?
        .. todo::
            move to DoubleMapPanel?
        r   ntN)r\   GetActiveMaprL   rN   r-   r   rM   r.   UpdateActiver   r,   SetFocusr   s     r;   ra   zIClassMapPanel.OnUpdateActive  s    
 ,,.!3!00DN}}DH!11DN~~DH$..)77d?NN##% r=   c                 &   | j                         }|j                  dt        | j                  j                        dkD         |j                         || j                  k(  k7  r|j                  || j                  k(         | j                          y)r  zoomBackr   enableN)	r\   EnablelenrN   zoomhistoryr  rM   SetActiveMapStatusbarUpdate)r:   winmapTbs      r;   r  zIClassMapPanel.UpdateActive  sw    
 ""$ZT^^-G-G)H1)LNC4+?+?$?@t';'; ;=r=   c                     t        j                  | |       | j                         j                  dt	        | j
                  j                        dkD         y Nr
  r   r  )r	   ActivateFirstMapr\   r  r  rN   r  r   s     r;   r  zIClassMapPanel.ActivateFirstMap  sG    ''e4##DNN$>$> ?! C 	$ 	
r=   c                     t        j                  | |       | j                         j                  dt	        | j
                  j                        dkD         y r  )r	   ActivateSecondMapr\   r  r  rN   r  r   s     r;   r  z IClassMapPanel.ActivateSecondMap  sG    ((u5##DNN$>$> ?! C 	$ 	
r=   c                 @    d| j                   v r| j                   d   S dS )z"Returns toolbar with zooming toolsr%   N)r[   r?   s    r;   r\   zIClassMapPanel.GetMapToolbar  s!    -8DMM-It}}[)StSr=   c                     || j                   j                         v r%| j                   j                  |      j                  S y)z`Get class color as string

        :param cat: class category

        :return: 'R:G:B'
        0:0:0)rE   r   r   color)r:   cats     r;   GetClassColorzIClassMapPanel.GetClassColor  s7     $////11??005;;;r=   c                 j    t               }d}t        d       j                  ft        d       j                  ft        d       fdft        d       fdffD ]  \  }}||j	                          t        j                  |t
        j                  |      }|j                  |        j                  t
        j                  ||       |d	k(  r|j                   j                          n |d
k(  r|j                   j                         |dz  }  j                  |       |j                          y)zPopup Zoom menur   z/Adjust Training Area Display to Preview Displayz/Adjust Preview display to Training Area DisplayzDisplay synchronization ONc                 &    j                  d      S )NTSetBindRegionsr   r:   s    r;   r<   z+IClassMapPanel.OnZoomMenu.<locals>.<lambda>!  s    D<O<OPT<U r=   zDisplay synchronization OFFc                 &    j                  d      S NFr!  r#  s    r;   r<   z+IClassMapPanel.OnZoomMenu.<locals>.<lambda>$  s    d11%8 r=   Nr      r   )r   r   OnZoomToPreviewOnZoomToTrainingAppendSeparatorr_   MenuItemID_ANY
AppendItemr^   EVT_MENUr  _bindRegions	PopupMenur   )r:   r   zoommenur   labelhandleritems   `      r;   
OnZoomMenuzIClassMapPanel.OnZoomMenu  s    6  CD$$
 CD%% +,.UV/08
 	NE7 }((*;;xE:D%IIbkk7D1Av 1 112aD--.FA5	< 	x r=   c                    | j                   | j                         k(  sI| j                         | _         | j                         | _        | j	                  | j                                | j
                  j                         }t        j                  |      | j                         _        | j                  | j                                yz8Set preview display to match extents of training displayN)
rN   rf   rg   r   r  r-   GetCurrentRegionr   regionRenderr:   r   newregs      r;   r(  zIClassMapPanel.OnZoomToTraining9  s     ~~!5!5!77!113DN((*DHd2245//1%)YYv%6"D((*+r=   c                    | j                   | j                         k(  sI| j                         | _         | j                         | _        | j	                  | j                                | j                         j                         }t        j                  |      | j                         _        | j                  | j                                yr6  )
rN   rc   rd   r   r  rg   r7  r   r8  r9  r:  s      r;   r'  zIClassMapPanel.OnZoomToPreviewF  s     ~~!4!4!66!002DN'')DHd1134""$557$(IIf$5!D'')*r=   c                    t        | | j                  d         }	 |j                         t        j                  k(  r|j                  |       r|j                         \  }}t        j                  |d      }|d   | j                  d<   || j                  d<   | j                  j                  | j                  d   | j                  d          nn|j                          y)	zAdd imagery groupr   )r   r*   )r,   elementr,   r   r   N)r   r   	ShowModalr_   ID_OKGetGroupBandsErrGetDatar   	find_filerV   emitr   )r:   dlgr   sr   s        r;   AddBandszIClassMapPanel.AddBandsS  s    DFF7O<}}"((*''t'4;;=DAq!OOGDE&+FmDFF7O)*DFF:&MM&&"ffWoz8J '    	r=   c                 r   | j                         s| j                  j                         rt        j                  | t        d      t        j                  t        j                  z  t        j                  z  t        j                  z        }|j                         t        j                  k(  r|j                          y|j                          t        | t        d      d      }|j                         t        j                  k(  r!|j                         }| j!                  |       |j                          y)zImport training areasz2All changes will be lost. Do you want to continue?)r*   messagestyleNzImport vector mapr   )r+   r?  )GetAreasCountrE   r   r_   MessageDialogr   YES_NO
NO_DEFAULTICON_QUESTIONCENTREr@  ID_NOr   r   rA  GetMapImportAreas)r:   r   qdlgrF  vNames        r;   OnImportAreaszIClassMapPanel.OnImportAreasg  s     4??#@#@#B##QRii"--/"2B2BBRYYND
 ~~288+LLNd!,?*@(S==?bhh&JJLEU#r=   c                     t        j                  |      }d}|d   dk(  rt        d|z        }|d   s|d   r|t        d|z        z  }|S )	zCheck if imported vector map has areas

        :param str vector: vector map name

        :return: warning message (empty if topology is ok)
        )r1   r   areasr   zNo areas in vector map <%s>.
pointslineszEVector map <%s> contains points or lines, these features are ignored.)r   vector_info_topor   )r:   r   topowarnings       r;   _checkImportedTopoz!IClassMapPanel._checkImportedTopo}  sg     %%&1=A86ABG>T']q.067 G
 r=   c                 ~   | j                  |      }|rt        | |       yt        j                          t        j                         j                          | j                         j                         }|j                  |d      t        | t        d      |z         y| j                         }dt        j                  d<   |j                  |dd	      d
k(  rt        | t        d      |z         yt        j                  d= |j                          |j                  |d      | _        | j                   t        | t        d             y| j"                  j%                         D ]6  }| j'                  | j"                  j)                  |      j*                         8 | j"                  j-                          | j.                  j1                          | j                         j3                  dd       | j5                  |       | j6                  d   j9                  d       t        j:                          y)zImport training areas.

        If table connected, try load certain columns to class manager

        :param str vector: vector map name
        r*   rJ  NF)updatezUnable to open vector map <%s>r   r   T)tmprb  r   z(Unable to copy vector features from <%s>)rc  z#Unable to open temporary vector maprenderrenderVectorr'   g      ?)r_  r   r_   BeginBusyCursorGetAppYieldrc   r   OpenMapr   r   r   r   r   CopyMapr   	poMapInforE   r   r   r   r   DeleteAllStatisticsrm   Reset	UpdateMapImportClassesr[   UpdateStddevEndBusyCursor)r:   r   r^  r   vnamer  s         r;   rT  zIClassMapPanel.ImportAreas  s    ))&1D'2

		 ((*335
 fU3;$*J(Kf(TU '')/2

+,ed;rADEN JJ/0 	 $++Et+<>>!$*O(PQ ??002 	QC!!$//"?"?"D"O"OP	Q 	++- 	''u4'H6" 	h,,S1
r=   c                    t        |      }t        |j                  j                               dkD  }|rt	        dd| j
                         d}|j                  j                         D ]  }|j                  |      s|} |"|j                  |j                  |            }ng }| j                  d   t        |       | j                  d<   | j                  d   j                         }|r
|d|vsd	|vrxt	        d
|ddd      }t        t        |j                         j                               }t        t!        t#        |                  }|D ]  }	|j%                  |	d|	z  d        yg d}t	        dd| d|ddj'                  |      d      }
|
j                         j)                         }|D ]9  }|j                  d      }|j%                  t        |d         |d   |d          ; y)zIIf imported map has table, try to import certain columns to class managerr   zv.db.droptabler   )r   r1   N)tablerA   classr  z
v.categoryr   printT)inputlayeroptionreadzclass_%dr  )r  r,   r  )r  rv  r  zv.db.selectc,)quietr*   r   r1   ry  columnsr{  |r   )r   r  layerskeysr   r   GetTable
GetColumnsrl   r   GetListCtrlr1   intstripsplitsortedlistsetAddCategoryjoin
splitlines)r:   r   dbInfo	connectedry  keyr  listCtrlcatsr  r   recordsrecords                r;   rp  zIClassMapPanel.ImportClasses  s    f%**,-1	 's8O8OP ==%%' 	Cs#	 ''fooe.D'EGG <<'/+Ft+LDLL(<</;;= }g%g% D sDJJL..01D$s4y/*D T$$:3C7$ST 0G)	C iik,,.G! c*$$F1IVAYfQi % r=   c                 
   | j                         dk(  rt        | t        d             yt        | | j                        }|j                         t        j                  k(  r|j                         }|| _        |j                         }|j                          | j                  ||      rVt        t        d      | j                         t        | j                  j                               | j                  fz  |        yyy)	zExport training areasr   zNo training areas to export.ra  N)r   )r   	withTablez;%d training areas (%d classes) exported to vector map <%s>.r>  )rL  r   r   r   rj   r@  r_   rA  GetVectorName	WithTabler   ExportAreasr  rE   r   )r:   r   rF  rV  r  s        r;   OnExportAreaszIClassMapPanel.OnExportAreas  s    1$D!,J*KL%dt7H7HI==?bhh&%%'E %DIKKM5IFST**,DOO99;<))   G 'r=   c           	         t        j                          t        j                         j                          | j	                         j                         }d|v r|j                  d      d   }|j                  |      dk  ry|st        j                          yg d}t        | j                  | j                  d   | j                  d               }dD ]0  \  }}t        |      D ]  }|j                  d|d	z   ||d
z          2 dt        d|||       k7  rt        j                          y	 t        j                   |      d	   }	t%        j&                  dd      }
|	d   dk7  r|
j)                  d       | j*                  j-                         D ]J  }| j*                  j/                  |      }| j1                  |
|	d   d|j2                  |       | j1                  |
|	d   d|j4                  |       |j7                         sv| j1                  |
|	d   d|j8                  |       t        |      D ]  }| j1                  |
|	d   d|d	z   z  |j:                  |   j<                  |       | j1                  |
|	d   d|d	z   z  |j:                  |   j>                  |       | j1                  |
|	d   d|d	z   z  |j:                  |   j@                  |        M |	d   dk7  r|
j)                  d       |
jB                  jE                          t        d|
j2                  |	d   |	d         }t        j                          tG        jH                  |
j2                         |dk7  ryy# t"        $ r t        j                          Y yw xY w)zExport training areas to new vector map (with attribute table).

        :param str vectorName: name of exported vector map
        :param bool withTable: true if attribute table is required
        @r   F)zclass varchar(30)zcolor varchar(11)zn_cells integerr   r   ))mininteger)meanzdouble precision)maxr  z band%(band)d_%(stat)s %(format)sr   )bandstatformatzv.db.addtable)r1   r  r*   w)modedeletedriverdbfzBEGIN
ru  rv  )ru  columnvaluer  r  n_cellsz
band%d_minzband%d_meanz
band%d_maxzCOMMIT
z
db.executedatabase)rx  r  r  T)%r_   rg  rh  ri  rc   r   r  rk  rr  r  GetGroupLayersr   rangeappendr   r   	vector_dbKeyErrorr   NamedTemporaryFilewriterE   r   r   _runDBUpdater,   r  IsReadyncellsbandsr  r  r  filecloser   remove)r:   r   r  r   r  nbands	statisticr  r   r  dbFiler  r  r   s                 r;   r  zIClassMapPanel.ExportAreas1  s    	
		 ((*335
*#))#.q1Jj)A-
 T(($&&:LMN"
 
	Iv
 6] 6 1ui6JK
	 
WT
 
 	__Z03F
 ,,#eD(u$LL#??002 *	C??005DfWogTYYTW   fWogTZZUX   <<>Wo kk   6] !! /'1q51**Q-++ "  !! /(AE2**Q-,, "  !! /'1q51**Q-++ " +*	X (u$LL$++(#J'	
 	
		&++!8E  		s   /M+ +N
Nc                     t        |t        t        f      r|j                  d||||fz         y|j                  d||||fz         y)a  Helper function for UPDATE statement

        :param tmpFile: file where to write UPDATE statements
        :param table: table name
        :param column: name of updated column
        :param value: new value
        :param cat: which category to update
        z%UPDATE %s SET %s = %d WHERE cat = %d
z'UPDATE %s SET %s = '%s' WHERE cat = %d
N)
isinstancer  floatr  )r:   tmpFileru  r  r  r  s         r;   r  zIClassMapPanel._runDBUpdate  sP     ec5\*MM8E65RU;VV MM:eVUTW=XXr=   c                    | j                   d   ;t        |       }|j                          |j                          || j                   d<   y| j                   d   j	                         s| j                   d   j                          yy)zShow category management dialogrA   N)rl   r   CenterOnParentShowIsShown)r:   r   rF  s      r;   OnCategoryManagerz IClassMapPanel.OnCategoryManager  sm    <<'/-d3C HHJ+.DLL(<</779^,113 :r=   c                    |r| j                   j                  |      }|j                  }| j                  d   j	                  |       | j
                  j                  |       | j
                  j                  d       |j                  }| j                  j                  |      }|r| j                  j                  |       | j                  j                  |       y)zUpdates everything which depends on current category.

        Updates number of stddev, histograms, layer in preview display.
        r'   N)r  )rE   r   nstdr[   rq  rm   UpdateCategoryOnPlotTypeSelectedr   rh   GetAliasSelectLayerrW   rE  )r:   
currentCatr  r  r,   s        r;   CategoryChangedzIClassMapPanel.CategoryChanged  s    
 ??00<D99DMM(#006NN))*5NN--d3??D))2248D&&2248!!j!1r=   c                     | j                   j                         j                  |       | j                   j                  dd       y)znRemoves all training areas of given categories

        :param cats: list of categories to be deleted
        FTrd  N)rL   r   DeleteAreasByCatro  r:   r  s     r;   DeleteAreaszIClassMapPanel.DeleteAreas  s:    
 	$$&77=%%U%Fr=   c                     | j                   j                         j                         j                  |d       | j                   j	                  dd       y)z!Highlight araes given by categoryr   )ry  FTrd  N)rL   r   
GetDisplaySetSelectedro  r  s     r;   HighlightCategoryz IClassMapPanel.HighlightCategory  sF    $$&113??A?N%%U%Fr=   c                    | j                         j                         j                         j                         \  }}}}| j	                         j                  ||||d       | j	                         j                          | j	                         j                          | j                         j                  dd       y)zZoom to areas given by categoryT)nrG  r  erb  rd  N)	rc   r   r  GetRegionSelectedrd   	GetRegionAdjustRegionAlignExtentFromDisplayro  )r:   r  r  rG  r  r  s         r;   ZoomToAreasByCatzIClassMapPanel.ZoomToAreasByCat  s    ((*335@@BTTV
1a$$qAa$E'')113''t$'Gr=   c                     | j                   j                  |      j                  }| j                  j	                  || j                  |             y)z8Update alias of raster map when category name is changedN)rE   r   r   rh   SetAlias
_addSuffix)r:   newNamer  origNames       r;   UpdateRasterNamezIClassMapPanel.UpdateRasterName  s;    ??005@@''$//'2JKr=   c                    | j                   j                  |      }|j                  d|i       |j                         sy|j                  }| j
                  |   }t        ||       t        || j                  |       | j                  | j                                |j                  |       | j                  j                          y)z?Standard deviation multiplier changed, rerender map, histogramsr  N)rE   r   SetStatisticsr  r   r   I_iclass_statistics_set_nstdI_iclass_create_rasterr   r9  rf   SetBandStatisticsrm   StddevChanged)r:   r  r  r  r   cstats         r;   r  zIClassMapPanel.StddevChanged  s    ,,S1FD>*||~$$S)$UD1udjj&9D((*+u%$$&r=   c                     || _         y)z[Informs if any important changes happened
        since last analysis computation.
        Nri   )r:   ri   s     r;   UpdateChangeStatez IClassMapPanel.UpdateChangeState  s     r=   c           	      0   dd|z  g}|rE| j                         j                  d|d|ddd       | j                  | j                                |rF| j	                         j                  d|d|ddd       | j                  | j                                yy)	zAdd raster map to Mapd.rastmap=%sr   TF      ?ltypecommandactiver,   hiddenopacityre  N)rd   AddLayerr9  rc   rg   rf   )r:   r,   r-   r.   cmdlists        r;   AddRasterMapzIClassMapPanel.AddRasterMap
  s    X_-'' (  KK++-.(( )  KK,,./ r=   c                    | j                         }|r|| _        nt        | t        d             y| j	                         j                  ddd|z  g|dd	      }| j                  d
   j                  |       | j                         j                         j                         | _        | j                  | j                                y)zHAdd vector map with training areas to Map (training
        sub-display)z&Failed to create temporary vector map.ra  Nr   zd.vectr  FT)r  r  r,   r  r  r&   )r   r   r   r   rd   r  r[   StartEditingrc   r   
GetMapInforl  r9  )r:   rs  mapLayers      r;   r{   z!IClassMapPanel.AddTrainingAreaMap$  s     %%'&+D#D!,T*UV ##%..x%/0 / 
 	h,,X6,,.779DDFD'')*r=   c                     | j                         rT| j                         }| j                  j                  | j                  d   | j                  d   || j
                         yy)zRun analysis and update plotsr   r   )r   r   r  rE   N)RunAnalysisGetCurrentCategoryIdxrm   UpdatePlotsr   rE   )r:   r   r  s      r;   OnRunAnalysiszIClassMapPanel.OnRunAnalysis;  sY    335JNN&&ffWo
+%??	 '  r=   c           	         | j                  | j                  d   | j                        sy| j                  j	                         D ]  }t        |        i | _        t        | j                         t        | j                  d   | j                  d   | j                        syt        | j                         t        | j                  | j                        }|s,t        | t        d             t        | j                         y| j                  j                         }|D ]  }| j                  j!                  |      }t#               }t%        |      }t'        ||j(                  |j*                  |j,                  |j.                         t1        || j                  | j2                  d| j                  d   |j4                        }|d	kD  r|| j                  |<   |j7                  |       |j9                          | j;                  |j4                  
       | j<                  j?                  |j4                  | jA                  |j*                        d       tC        | j                  |       P|d	k(  r0t        | t        d      |j(                  z         t        |       t        | t        d             t        |        | jE                  d       y)zRun analysis

        Calls C functions to compute all statistics and creates raster maps.
        Signatures are created but signature file is not.
        r   )r   r   Nr   FzUThere was an error initializing signatures. Check GUI console for any error messages.ra  r   r   r,   T)r,   aliasresultsLayerz)No area in category %s. Category skipped.zAnalysis failed.r  )#
CheckInputr   r   r   r   r   r   r   I_iclass_init_groupr   r   I_iclass_init_signaturesr   r   rE   r   r   IClass_statisticspointerI_iclass_init_statisticsrD   r,   r  r  I_iclass_analysisrl  r   SetFromcStatisticsSetReadyConvertToNullrh   r  r  I_iclass_add_signaturer  )r:   r  r   r  r   statsstatistics_obj
statisticss           r;   r  zIClassMapPanel.RunAnalysisF  sb    TVVG_T=T=TU--446 	0I$Y/	0! 	$"466'?DFF:4F

S$//*&t

C@ doo.
 ,,. .	5AOO11!4E.0N 0J$ENNEJJUZZ $

w  C Qw*4$$Q'((4 
 ""(8(8"9&&//))//%**5!% 0  't
CIJnn%
 )4a0B.CD(4].	5` 	u-r=   c                 >    t        d      }dj                  ||f      S )Nresultsr   )r   r  )r:   r,   suffixs      r;   r  zIClassMapPanel._addSuffix  s    9xxv''r=   c                    | j                   d   st        | t        d             y| j                  rt	        j
                  | t        d      t        d      t        j                  t        j                  z  t        j                  z  t        j                  z        }|j                         t        j                  k(  r|j                          n|j                          y| j                  j                  j                  st        | t        d             yt!        | | j"                  	      }|j                         t        j$                  k(  r*t&        j(                  j+                  |j-                  d
            rt	        j
                  | t        d      |j-                         z  t        d      t        j                  t        j.                  z  t        j                  z  t        j                  z        }|j                         t        j                  k(  r|j                          n|j                          y|j-                         | _        | j1                  | j                  | j"                         |j                          y)z*Asks for signature file name and saves it.r   zNo imagery group selected.ra  NzwDue to recent changes in classes, signatures can be outdated and should be recalculated. Do you still want to continue?zOutdated signatures)r*   rJ  r  rK  z>Signatures are not valid. Recalculate them and then try again.)r  T)fullPathzDA signature file named %s already exists.
Do you want to replace it?zFile already exists)r   r   r   ri   r_   rM  rN  rO  rP  rQ  r@  ID_YESr   r   contentsnsigsr   sigFilerA  r   r   existsGetFileNameYES_DEFAULTWriteSignatures)r:   r   rU  rF  s       r;   OnSaveSigFilezIClassMapPanel.OnSaveSigFile  s   vvgD!,H*IJ<<##5
 /0ii"--/"2B2BBRYYN	D ~~299,''--T '4<<@==?bhh&ww~~cooto<=''5 oo'	(
 34))bnn4r7G7GG"))S	 >>#ryy0LLNLLN??,DL  $,,?r=   c                 .   ddd| _         d| _        t               | _        i | _        t               | _        t        | j                        | _        t        | j                  d       t               }t        |      | _        t        | j                         y)zZInitialize variables and c structures necessary for
        computing statistics.
        Nr   r   )r   r   r   rE   r   	Signaturesignatures_objr  r   I_init_signaturesRefr   I_init_group_ref)r:   	refer_objs     r;   rX   zIClassMapPanel.InitStatistics  sr      T2(*!'k!$"5"56$//1-E	Y'
$r=   c                     t        ||       y)zWrites current signatures to signature file

        :param signatures: signature (c structure)
        :param filename: signature file name
        N)I_iclass_write_signatures)r:   r   filenames      r;   r$  zIClassMapPanel.WriteSignatures  s     	"*h7r=   c                 |   |st        | t        d             y| j                  | j                  d   | j                  d         }t	        |      }|dk  rt        | t        d      ||dz         y| j                         d	k(  rt        | t        d
             yt               }t        | j                  t        |             t        j                  |d	         }|j                  |d   kD  s6|j                  |d   k  s$|j                  |d   kD  s|j                  |d   k  rt        | t        d             yy)zCheck if input is validz.No imagery group selected. Operation canceled.ra  Fr   r   r   zZGroup <%(group)s> does not have enough files (it has %(files)d files). Operation canceled.)r   filesr   z#No areas given. Operation canceled.northsoutheastwestz>Vector features are outside raster layers. Operation canceled.T)r   r   r  r   r  rL  	bound_boxVect_get_map_boxrl  byrefr   raster_infoNSEW)r:   r   r   groupLayersnLayers	regionBox
rasterInfos          r;   r
  zIClassMapPanel.CheckInput  s;    MN ))$&&/466*;MNk"a<D "G4	5  1$D!,T*UV K	y)9:&&{1~6
 KK*W--{{Z00{{Z//{{Z//W r=   c                     d}t        | j                        }t        |      D ]!  }t        | j                  |dz         s|dz  }# |S )z Returns number of not dead areasr   r   )Vect_get_num_areasrl  r  Vect_area_alive)r:   countnumAreasr   s       r;   rL  zIClassMapPanel.GetAreasCount(  sJ    %dnn5x 	At~~q1u5
	 r=   c                     i }|r||d<   t        dd|dd|j                         }|j                         d   rt        |j                               S g S )zGet layers in subgroup (expecting same name for group and subgroup)

        .. todo::
            consider moving this function to core module for convenient
        r   r   T)r   r   r{  r   )zi.group)r   r  r  r  )r:   r   r   r   ress        r;   r  zIClassMapPanel.GetGroupLayers1  s[     !)F:P#UPPVVX>>A#..*++	r=   c                      t        d|d       y)zlSets value which represents null values for given raster map.

        :param name: raster map name
        zr.nullr   )r1   setnullN)r   r   s     r;   r  zIClassMapPanel.ConvertToNullA  s    
 	8q1r=   c                 <    | j                   d   j                         S )zReturns current category numberr'   )r[   GetSelectedCategoryIdxr?   s    r;   r  z$IClassMapPanel.GetCurrentCategoryIdxH  s    }}X&==??r=   c                 d    t         t        |   |       | j                  j	                  d       y)Enable zooming for plotsr   r   N)superr"   OnZoomInrm   
EnableZoomr:   r   	__class__s     r;   rQ  zIClassMapPanel.OnZoomInL  s'    nd,U3!!q!)r=   c                 d    t         t        |   |       | j                  j	                  d       y)rN  r   rO  N)rP  r"   	OnZoomOutrm   rR  rS  s     r;   rV  zIClassMapPanel.OnZoomOutQ  s'    nd-e4!!r!*r=   c                 `    t         t        |   |       | j                  j	                          y)zEnable panning for plotsN)rP  r"   OnPanrm   	EnablePanrS  s     r;   rX  zIClassMapPanel.OnPanV  s"    nd)%0  "r=   c                 |    | j                         j                          | j                         j                          y)zSSet pointer mode.

        .. todo::
            pointers need refactoring
        N)rc   SetModePointerrf   r   s     r;   	OnPointerzIClassMapPanel.OnPointer[  s.     	,,.--/r=   c                 2    | j                   | j                  fS )z]Get map managers of wxIClass

        :return: trainingMapManager, previewMapManager
        )re   rh   r?   s    r;   GetMapManagerszIClassMapPanel.GetMapManagersd  s    
 &&(>(>>>r=   r   )TT)>__name__
__module____qualname____doc__r   rH   r   r   r   r   r   r   r   r   rY   rv   r   r   ra   r  r  r  r\   r  r4  r(  r'  rH  rW  r_  rT  rp  r  r  r  r  r  r  r  r  r  r  r  r  r{   r  r  r  r%  rX   r$  r
  rL  r  r  r  rQ  rV  rX  r\  r^  __classcell__)rT  s   @r;   r"   r"   J   sP    01@AF	O/I8	un 4
(
*&"

T	%N,+(,(?BDL2rh$	42(GG
HL
'&04+.	Un(6p%&82h 2@*
+
#
0?r=   r"   c                       e Zd ZdZd Zy)IClassMapDisplayz5Map display for wrapping map panel with frame methodsc                    t        j                  | f||d| |j                  t        j                  t
        j                  j                  t        j                  d      t        j                               |j                  t        j                  | j                         | j                  j                  | j                   t        j"                  t        j$                  f       | j'                          t        j(                  t        j*                        }|j-                  | dt        j.                         |j1                  |       |j3                          y )N)r*   r/   zgrass_map.icor   )
proportionflag)r"   rH   SetIconr_   Iconr   r   r  r   ICONDIRBITMAP_TYPE_ICOr^   	EVT_CLOSEr   shortcuts_tabler  OnFullScreenACCEL_NORMALWXK_F11_initShortcutsBoxSizerVERTICALAddEXPANDSetSizerLayout)r:   r*   r/   r   sizers        r;   rH   zIClassMapDisplay.__init__o  s    	
	
 		
 	GGY..@"BTBT	
 	BLL$"4"45 	##T%6%6$TU BKK(		$1299	5r=   N)r_  r`  ra  rb  rH   r   r=   r;   re  re  l  s
    ?r=   re  c                   Z    e Zd ZdZd Zd ZddZd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd Zy)rb   zXClass for managing map renderer.

    It is connected with iClassMapManagerToolbar.
    c                 J    || _         || _        || _        d| _        i | _        y)z

        It is expected that  mapWindow is connected with  Map.

        :param frame: application main window
        :param mapWindow: map window instance
        :param map: map renderer instance
        N)r1   framer@   toolbar	layerName)r:   r|  r@   r   s       r;   rH   zMapManager.__init__  s'     
"r=   c                     || _         y r   )r}  )r:   r}  s     r;   rZ   zMapManager.SetToolbar  s	    r=   Nc           	      J   |r`|| j                   j                  |      D cg c]  }|j                          c}v r&| j                  j	                  | j
                         ydd|z  g}| j                   j                  d|d|ddd	       | j                  j	                  | j
                         ||| j                  |<   |}n|| j                  |<   | j                  j                  j                  |d
       | j                  j                  j                  d
       yc c}w )zAdds layer to Map and update toolbar

        :param str name: layer (raster) name
        :param str resultsLayer: True if layer is temp. raster showing the results of computation
        r  Nr  r  r   TFr  r  r   )r1   GetListOfLayersGetNamer|  r9  r@   r  r~  r}  choiceInsertSetSelection)r:   r,   r  r	  ry  r  s         r;   r  zMapManager.AddLayer  s    D)-)A)At)A)L%
 %EMMO%
 
 JJdnn-X_- 	 	
 	

$..)$(DNN5!D#'DNN4 ""4+((+3%
s   D c           	         g }|D ]*  }d|v s|j                  |j                  d      d          , dj                  |      }| j                  j	                  d|d|ddd       | j
                  j                  | j                         || j                  |<   | j                  j                  j                  |d	       | j                  j                  j                  d	       y
)zXAdds RGB layer and update toolbar.

        :param cmd: d.rgb command as a list
        =r   r}  rgbTFr  r  r   N)r  r  r  r1   r  r|  r9  r@   r~  r}  r  r  r  )r:   r   r,   params       r;   AddLayerRGBzMapManager.AddLayerRGB  s    
  	1Ee|EKK,Q/0	1 xx~ 	 	
 	

$..)#t""4+((+r=   c                    | j                   j                  d      }d}t        |      D ]  \  }}||j                         k(  s|} n |y| j                   j	                  |       | j                  |      }|| j                  vry| j                  |= | j                  j                  j                  |      }|t        j                  k7  rn| j                  j                  j                  |       | j                  j                  j                         s%| j                  j                  j                  d       | j                  j!                  | j"                         y)zwRemoves temporary layer (if exists) from Map and and updates toolbar.

        :param name: real name of layer
        r   r  Nr  r   )r1   r  	enumerater  RemoveLayerr  r~  r}  r  
FindStringr_   	NOT_FOUNDDeleteIsEmptyr  r|  r9  r@   )r:   r,   r  idxr   ry  r  s          r;   RemoveTemporaryLayerzMapManager.RemoveTemporaryLayer  s    )))9!&) 	HAuu}}&	 ;$' d#&NN5!ll!!,,U3",,LL&&s+<<&&..0##003

$..)r=   c                 N    | j                   j                  | j                         y)zK
        .. todo::
            giface should be used instead of this methodN)r|  r9  r@   r?   s    r;   r9  zMapManager.Render  s     	

$..)r=   c                    | j                   |   }| j                  j                  |       | j                   |= | j                  j                  j                  |       | j                  j                  j                         s%| j                  j                  j                  d       | j                  j                  | j                         y)z)Removes layer from Map and update toolbarr  r   N)r~  r1   r  r}  r  r  r  r  r|  r9  r@   )r:   r,   r  s      r;   r  zMapManager.RemoveLayer  s    ~~d#$'NN4 ""3'||""**,LL,,Q/

$..)r=   c                 d   | j                   j                  d      | j                   j                  d      z   }d}t        |      D ])  \  }}| j                  |   |j	                         k(  s'|} n ||j                  |j                  |             | j                  j                  }|j                  |      }|j                  |       |j                  |d       |j                  d       | j                   j                  |       | j                  j                  | j                          yy)zMoves selected layer to topr  r  r   Nr   )r1   r  r  r~  r  r  popr}  r  r  r  r  r  	SetLayersr|  r9  r@   )r:   r,   r  r  r   ry  r  s          r;   r  zMapManager.SelectLayer  s   )))69Q9Q :R :
 
 !&) 	HAu~~d#u}}6	
 ?MM&**S/*\\((F##D)CMM#MM$"" HHv&JJdnn- r=   c                      j                   |   } j                  j                  |      syd   j                         }t	         j
                  |      }|j                  j                   fd       |j                         t        j                  k(  r$ j                  d   |j                                |j                          y)zSets opacity of layers.r  Nr   )r  c                 0    j                  d   |       S )Nr   ry  r  )_changeOpacity)r  r  r:   s    r;   r<   z'MapManager.SetOpacity.<locals>.<lambda>2  s    $--F1Iu-M r=   r  )r~  r1   r  
GetOpacityr   r|  applyOpacityrS   r@  r_   rA  r  r   )r:   r,   
oldOpacityrF  r  s   `   @r;   
SetOpacityzMapManager.SetOpacity'  s    ~~d#))t)4 AY))+
tzz:>  M	
 ==?bhh&fQi9IJr=   c                     | j                   j                  ||       | j                  j                  | j                         y )Nr  )r1   ChangeOpacityr|  r9  r@   )r:   ry  r  s      r;   r  zMapManager._changeOpacity:  s/    UG<

$..)r=   c                     t        j                  | j                        D cg c]  \  }}||k(  s| }}}|r|d   S yc c}}w )zReturns alias for layerr   N)six	iteritemsr~  )r:   r,   kvs       r;   r  zMapManager.GetAlias>  sA    !mmDNN;IdaqDyII7N Js
   A A c                 "   | j                  |      }|r||| j                  |<   | j                  |= | j                  j                  j	                  |      }|t
        j                  k7  r'| j                  j                  j                  ||       y y y r   )r  r~  r}  r  r  r_   r  	SetString)r:   originalr  r,   r  s        r;   r  zMapManager.SetAliasE  sw    }}X&$,DNN5!t$,,%%006Cbll"##--c59 #	 r=   r%  )r_  r`  ra  rb  rH   rZ   r  r  r  r9  r  r  r  r  r  r  r   r=   r;   rb   rb     sE    
 ,B,0*@*	*.0&*:r=   rb   c                      t        j                         } t        j                  d t        j                  t        d            }t        |      }|j                          | j                          y )Nr#   )r*   r   r+   r>  )	r_   AppFramer   MAP_WINDOW_SIZEr   re  r  MainLoop)appr|  s     r;   testr  O  sN    
&&(CHH&&01E
 E*E	JJLLLNr=   __main__)Drb  r   r  r   r   r_   ctypesgrass.lib.imagerygrass.lib.vector
haveIClasserrMsgImportErrorr  r   grass.scriptscriptr   mapdispr   rn   mapdisp.mainr   mapwin.bufferedr   vdigit.toolbarsr   gui_core.mapdispr	   r
   corer   core.renderr   	core.gcmdr   r   r   gui_core.dialogsr   gui_core.wrapr   dbmgr.vinfor   iclass.digitr   r   iclass.toolbarsr   r   r   r   iclass.statisticsr   iclass.dialogsr   r   r   r   r   iclass.plotsr   grass.pydispatch.signalr    r"   re  rb   r  r_  r   r=   r;   <module>r     s   ( 
 
   	 6#"JF
  # ; - ) 7   2 2 -  $ 9  -  # *_?^ _?D)z> @@: @:F
 zF q1  6J01A5F6s   C C;$C66C;