cyclograph-1.6.1/0000755000175000017500000000000012231302005015220 5ustar federicofederico00000000000000cyclograph-1.6.1/CHANGELOG.txt0000644000175000017500000001103012231301772017255 0ustar federicofederico00000000000000Version 1.6.1: * Cyclograph can import fitlog files with gps coordinates * Can now save map to image * Miscellaneous and bug fixes * Set map dimension equal to plot on html report * Added configuration option to disable check for the latest version. * Fixed bug: Fixed km bar drawing color for black theme in Qt gui * Fixed bug: Fixed Qt translation file not loaded * Fixed bug: Fixed average grad calc * Fixed bug: Fixed import of TCX files: no hardcoded indices * Fixed bug: Fixed slope import from osrm site * Fixed bug: mark created slopes as not saved Version 1.6.0: * Removed separation from import and open * New cgx format saves imported coordinates * Added map window * Added map within the html report * Auto-import gpx if no altitude is present * Miscellaneous and bug fixes * Case insensitive open routines Version 1.5.2: * Added blue theme * Added filter dialog to select the step between consecutive cps * Removed Google maps service * Added Open Route Service * Added OSRM * Miscellaneous and bug fixes * First release with a user manual Version 1.5.1: * Initial support for html report * Added height gain * Support for kml 2.2 ext (i.e. my tracks) * Miscellaneous and bug fixes * Resizable splitter in qt4 "create" window * New submodule structure * Fixed bug: Fixed haversine formula (for distant points) * Fixed bug: Fixed save as image for qt4 interface Version 1.5.0: * New grayscale theme. * Added pdf report about a slope. * Initial implementation of the gtk3 interface. Version 1.4.2: * Miscellaneous and bug fixes * Added some information within plot window. Version 1.4.1: * More granular distnace bar. * Support for slopes startig from distance grater than zero. * Support for drawing on Open Cycle Map and Open Street Map. * Miscellaneous and bug fixes * Changed accessing mode to Google Maps. * Fixed bug: Window size and maximization status correctely saved for the next session. Version 1.4.0: * Names are imported from gpx wayposints. * Added new theme. * All supported files can be read from standard input. * Added support to utf-8. * Removed google elevation. * Miscellaneous and bug fixes * Plot animated. * Icons little update. * Moved icons to a better location. * Workaround to geonames unstable service. * Main window remember its position and size. * Improvements in text layout in plots. Version 1.3.1: * Added preferences dialog. * Number of points shown in gpx is customizable. * User can select the resolution of the images saved. * Miscellaneous and bug fixes * Kml import is now more robust (i.e. it works much better with kml produced by saliteweb). Version 1.3.0: * Added new themes. * Now it is possible to create draw a route within CycloGraph. * A route found by Google Maps direction can be drawn by CycloGraph. * New version notifier. * Miscellaneous and bug fixes * Better handling of slopes and user-friendly behaviour when quitting. * Possible to easily report bugs. Version 1.2.1: * Miscellaneous and bug fixes * Migration from 1.x wx version is now smooth. * Fixed bug: Fixed a paint issue in Qt under X11 with composing window managers. Version 1.2.0: * A new 3D visualization mode is available in addition to the usual 2D. * New format support for gpx and crp (binary and textual) files. * New toolbar with icons to give a more user-friendly experience. * Added an help file, to guide te user on basic usage of CycloGraph. * Added the ability to signal bugs (link to sourceforge page). * A new GTK+ interfece has replaced the wx (Qt became default on Win and MacOs). * Miscellaneous and bug fixes * Command line usage is now simpler (see Help file). * Launching Cyclograph without the appropriate graphic library is told to the user in a understandable way. Version 1.1.1: * New icons. * Cyclograph can load Cyclomainac's xml. * Miscellaneous and bug fixes * Fixed bug: .sal file can't be opened. Version 1.1.0: * Added a Qt interface. * Added minimal command line interface. * Miscellaneous and bug fixes * Added more error dialog to make usage clearer. * Fixed bug: Cancelling a file opening and creating a new file. * Fixed bug: Export as image under some platforms. * Fixed bug: Segmentation fault when importing KML. Version 1.0.0: * Miscellaneous and bug fixes * New Release, many changes, almost everything is changed : Version 0.4.1: * Miscellaneous and bug fixes * Fixed bug: Fixed issue with icon in plot window. Version 0.4: * Initial release cyclograph-1.6.1/cyclograph-gtk.desktop0000644000175000017500000000056612065361217021557 0ustar federicofederico00000000000000[Desktop Entry] Version=1.0 Encoding=UTF-8 Icon=cyclograph.png Name=Cyclograph GTK GenericName=Plot your ride (GTK interface) GenericName[it]=Disegna il tuo giro (interfaccia GTK) Comment=Plots slopes of bycicle routes. Comment[it]=Disegna altimetrie di percorsi. Exec=python /usr/bin/cyclograph --gtk Terminal=false Type=Application Categories=Utility; StartupNotify=false cyclograph-1.6.1/cyclograph-qt.desktop0000644000175000017500000000056212065361217021412 0ustar federicofederico00000000000000[Desktop Entry] Version=1.0 Encoding=UTF-8 Icon=cyclograph.png Name=Cyclograph Qt GenericName=Plot your ride (Qt interface) GenericName[it]=Disegna il tuo giro (interfaccia Qt) Comment=Plots slopes of bycicle routes. Comment[it]=Disegna altimetrie di percorsi. Exec=python /usr/bin/cyclograph --qt Terminal=false Type=Application Categories=Utility; StartupNotify=false cyclograph-1.6.1/cyclograph-gtk3.desktop0000644000175000017500000000057412065361217021641 0ustar federicofederico00000000000000[Desktop Entry] Version=1.0 Encoding=UTF-8 Icon=cyclograph.png Name=Cyclograph GTK3 GenericName=Plot your ride (GTK 3 interface) GenericName[it]=Disegna il tuo giro (interfaccia GTK 3) Comment=Plots slopes of bycicle routes. Comment[it]=Disegna altimetrie di percorsi. Exec=python /usr/bin/cyclograph --gtk3 Terminal=false Type=Application Categories=Utility; StartupNotify=false cyclograph-1.6.1/README0000644000175000017500000000521112204123117016104 0ustar federicofederico00000000000000Cyclograph ---------------------------------- CycloGraph is an application for plotting the elevation profile of routes. Its main value is in the graphical visualization of the difficulty of a road, in term of slope, difference in height, etc. Plots like these are often used in cycling competitions, but are also useful in other sports, such as hiking or running. website: http://cyclograph.sourceforge.net ---------------------------------- System Requirements: * Python 2.6 or later (python 3 is not yet supported) If you want a graphical interface: * PyQt 4.x (pyqt4) or * pygtk (we actively support only X11) and python-webkit or * gir-1.2-gtk-3.0 (we actively support only X11) and gir-1.2-webkit N.B.: The Widows installer already ships everything need. ---------------------------------- Usage: * GUI - Graphical User Inteface cyclograph Tries any available graphical interface. cyclograph --qt [-f FILE, --file=FILE] Executes CycloGraph with qt4 graphic libraries. Is possible to open at startup any supported file. cyclograph --gtk [-f FILE, --file=FILE] Executes Cyclograph with gtk2 graphic libraries. Is possible to open at startup any supported file. cyclograph --gtk3 [-f FILE, --file=FILE] Executes Cyclograph with gtk3 graphic libraries. Is possible to open at startup any supported file. * CLI - Command Line Interface cyclograph -f FILE, --file=FILE Executes Cyclograph with command line interface. This require a ciclograph supported file and prints on the standard output the svg image rapresenting the slope. ---------------------------------- Installation: There are several ways to install CycloGraph, depending on witch package you have downloaded. cyclograph*.tar.gz You can just run cyclograph without installing it with python cyclograph/cyclograph [OPTIONS] If you really want to install it do the followings: 1) Ensure you have the required libraries installed (PyQt4 or pyGtk). 2) Extract the archive. 3) Go into the newly created dirctory and launch the installation process with: python setup.py install This will build CycloGraph for your machine and then install it. N.B.: This may require superuser priviledges. cyclograph*.deb Use this if you are using Debian or a derived distribution like Ubuntu. For the installation procedure follow the documentation provided by your distibution. cyclograph*.exe If you are a windows user you may prefer this executable to install a standalone version of cyclograph. cyclograp*.app Sadly we cannot provide a packaged app anymore. CycloGraph shoud still work on Mac OS X, if someone is interested in this please email us or the mailing-list. cyclograph-1.6.1/po/0000755000175000017500000000000012231302005015636 5ustar federicofederico00000000000000cyclograph-1.6.1/po/it/0000755000175000017500000000000012231302005016252 5ustar federicofederico00000000000000cyclograph-1.6.1/po/it/LC_MESSAGES/0000755000175000017500000000000012231302005020037 5ustar federicofederico00000000000000cyclograph-1.6.1/po/it/LC_MESSAGES/cyclograph.mo0000644000175000017500000002033612217121674022552 0ustar federicofederico00000000000000, 0 1 = I U Z ` i {     #      % , 4 > O a f m z "      #  0:P`got  * 6=C   B5 9CHW`x}& 0! 1,=:j      "! DN Was      "-FAMQU=CW u 41     &-J P \ h+s   '8!Gip   "   '/8*J&u     0+\a |  P0 6DK^"n) 2 >F X6cA   ! + 9 D P[.r     "+!Np 7Q!sRx% # ) 2 E K V c 'x  ,  &:+GsL8<n$`HKi!}AxztaPXj_@ %*q>N2T|.y7-d?WrFM5Q0pY vhZ;"kJ)#ob(Dm3~'R6,ucBEl=41feI9gVw ]UO/ S\^[{C Create Kml&Create Kml&Kml server&New&Open&Options&Orizzontal lines&Preferences&Quit&Save&Saving resolution&Theme3D &effect3D _effect3D effectA new version of CycloGraph is out!AboutAddAdd a check-pointAltitude [m]Altitude:AuthorAuthor:AutomaticAverage gradientAverage gradient:BackCancelCheck onlineChoose a fileChoose the type of import you wantCloseClose without savingCountryCreateCreate KMLCreate KmlDeleteDescriptionDistance [km]Distance and altitude are required.Distance:Downloading altitudesDraw on the mapE-mailE-mail:EditEdit a check-pointError on loading slopeError while loading dataFileFile savedFinishFontsForm incompleteGeneralGradientGradient colorsHeight differenceHeight difference:Height gainHeight gain:If you don't save, all your changes will be permanently lost.InfoInformations about the slopeKml serverLatest versionMapMax gradientMax gradient:ModeModesNameName:Network error : unable to create an handler to download kml route.NewNew SlopeNextNo coordinatesNo routeNot enough check pointsNoteNote:OSRMOld file format: please save it again.OpenOpen Route ServiceOpen SlopeOptionsOrizzontal linesPlease wait, Cycograph is downloading altitudes.PlotPlot your slopePreferencesPress + on the keyboard to add a check-pointPress - on the keyboard to remove the selected check-pointRemove a check-pointResolutionRestore DefaultSaveSave &AsSave PDFSave SlopeSave _PDFSave _htmlSave asSave changesSave changes to %s before closing?Save htmlSave mapSave plotSave plot to htmlSave plot to pdfSaving _resolutionSelect FontSelect colorSelect the distance rateSelect the number of checkpointsShow infoShow the map of your slopeSignal a bugSlopeSlope InfoSpecify one route first.State:The %s file contains %d points. Choose how many will be imported.The %s file contains a route of %d Km. Choose what range you want between points.ThemeThere aren't enougth check points to plot. At least two points are required to plot.TitleUnable to open fileUse every point (discouraged)Visualization_File_Options_Orizzontal lines_Themefont | dimkml namenumber of checkpointsold cofiguration issue.slopeslope %dthere aren't coordinates associated with this slope.Project-Id-Version: Cyclograph Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-18 23:12+0200 PO-Revision-Date: 2013-09-18 23:14+0100 Last-Translator: agron85 Language-Team: Italian Language: it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: Poedit 1.5.4 Plural-Forms: nplurals=2; plural=(n != 1); Crea Kml&Crea Kml&Server KML&Nuovo&Apri&Opzioni&Linee orizzontali&Preferenze&Esci&Salva&Risoluzione del salvataggio&Temi&Effetto 3d_Effetto 3dEffetto 3Dé uscita una nuova versione di CycloGraph!&InformazioniAggiungiAggiungi un puntoAltezza [m]Altezza:AutoreAutore:AutomaticaPendenza mediaPendenza media:IndietroAnnullaControlla onlineScegli un fileSeleziona il tipo di importazioneChiudiChiudi senza salvareNazioneCreaCrea un KMLCrea KmlCancellaDescrizioneDistanza [Km]Distanza e altezza sono richieste.Distanza:Scaricamento altezzeDisegna sulla mappaE-mailE-mail:ModificaModifica un puntoErrore durante il caricamento della salitaErrore durante il caricamento dei datiFileFile salvatoFineCaratteriForm incompletoGeneralePendenzaColori salitaDislivelloDislivello:Aumento in altezzaAumento in altezza:Se non salvi, tutte le modifiche andranno perse.Info Informazioni sulla salitakml serverUltima versioneMappaPendenza massimaPendenza massima:ModalitàModalitàNomeNome:Errore di rete: impossibile creare un gestore per scaricare il percorso del kml.Nuovo Nuova SalitaAvantiNessuna coordinataNessun percorsoNon ci sono abbastanza check pointNoteNote:OSRMVecchio formato di file: salvare di nuovoApriOpen Route Service Apri Salita&OpzioniLinee orizzontaliattendere, Cyclograph sta scaricando le altimetrieDisegnaDisegna la salitaPreferenzePremere + sulla tastiera per aggiungere un check-pointPremere - sulla tastiera per rimuovere il check-point selezionatoRimuove check-pointRisoluzioneRipristina defaultSalvaSalva &comeSalva PDF Salva SalitaSalva _PDFSalva _htmlSalva comeSalvare le modifiche aSalvare i cambiamenti in %s prima di chiudere?Salva htmlSalva mappaSalva kmlSalva grafico in htmlSalva grafico in PDF_Risoluzione del salvataggioSeleziona lo stileColori salitaSeleziona l'intervallo di distanzaSeleziona il numero di checkpointMostra informazioniMostra la mappa della salitaSegnala un bugSalitaInfo SalitaSpecificare prima un percorso.Stato:il file %s contiene %d punti. Scegli quanti importarne.il file %s contiene un percorso di %d Km. Scegli quale distanza vuoi tra i punti.TemaNon ci sono abbastanza punti da disegnare. Per il disegno servono almeno 2 punti.TitoloImpossibile aprire il fileUtilizza tutti i punti (sconsigliato)Visualizzazione_File_Opzioni_Linee orizzontali_Temafont | dimnome del kmlnumero di checkpointproblema con una vecchia configurazioneSalitaSalita %dnon ci sono coordinate associate alla salitacyclograph-1.6.1/po/it/LC_MESSAGES/cyclograph.po0000644000175000017500000005516012217121674022560 0ustar federicofederico00000000000000# Cyclograph. # Copyright (C) 2010 Pierluigi Villani # This file is distributed under the same license as the Cyclograph package. # # Pierluigi Villani , 2010, 2011, 2012, 2013. # Federico Brega , 2010, 2011. msgid "" msgstr "" "Project-Id-Version: Cyclograph\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-18 23:12+0200\n" "PO-Revision-Date: 2013-09-18 23:14+0100\n" "Last-Translator: Pierluigi Villani \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: qt4_ui/ui_qt_ts.py:289 msgid " Create Kml" msgstr " Crea Kml" #: qt4_ui/ui_qt_ts.py:287 msgid "&Create Kml" msgstr "&Crea Kml" #: qt4_ui/ui_qt_ts.py:270 msgid "&Kml server" msgstr "&Server KML" #: qt4_ui/ui_qt_ts.py:275 msgid "&New" msgstr "&Nuovo" #: qt4_ui/ui_qt_ts.py:271 msgid "&Open" msgstr "&Apri" #: cyclograph/qt/gui.py:465 msgid "&Options" msgstr "&Opzioni" #: cyclograph/qt/gui.py:446 msgid "&Orizzontal lines" msgstr "&Linee orizzontali" #: qt4_ui/ui_qt_ts.py:292 msgid "&Preferences" msgstr "&Preferenze" #: qt4_ui/ui_qt_ts.py:273 msgid "&Quit" msgstr "&Esci" #: qt4_ui/ui_qt_ts.py:272 msgid "&Save" msgstr "&Salva" #: cyclograph/qt/gui.py:477 msgid "&Saving resolution" msgstr "&Risoluzione del salvataggio" #: cyclograph/qt/gui.py:472 msgid "&Theme" msgstr "&Temi" #: cyclograph/qt/gui.py:450 msgid "3D &effect" msgstr "&Effetto 3d" #: cyclograph/gtk_/gui.py:572 msgid "3D _effect" msgstr "_Effetto 3d" #: cyclograph/gtk_/gui.py:745 cyclograph/gtk3/gui.py:564 #: cyclograph/gtk3/gui.py:740 qt4_ui/ui_qt_ts.py:868 msgid "3D effect" msgstr "Effetto 3D" #: cyclograph/cyclograph.py:121 msgid "A new version of CycloGraph is out!" msgstr "é uscita una nuova versione di CycloGraph!" #: qt4_ui/ui_qt_ts.py:274 msgid "About" msgstr "&Informazioni" #: cyclograph/cyclograph.py:588 cyclograph/gtk_/gui.py:105 #: cyclograph/gtk3/gui.py:105 qt4_ui/ui_qt_ts.py:276 msgid "Add" msgstr "Aggiungi" #: cyclograph/gtk_/gui.py:107 cyclograph/gtk3/gui.py:107 msgid "Add a check-point" msgstr "Aggiungi un punto" #: cyclograph/gtk_/gui.py:337 cyclograph/gtk3/gui.py:342 #: qt4_ui/ui_qt_ts.py:645 msgid "Altitude [m]" msgstr "Altezza [m]" #: cyclograph/gtk_/gui.py:388 cyclograph/gtk3/gui.py:396 #: qt4_ui/ui_qt_ts.py:442 msgid "Altitude:" msgstr "Altezza:" #: cyclograph/cyclograph.py:745 cyclograph/cyclograph.py:781 #: qt4_ui/ui_qt_ts.py:886 msgid "Author" msgstr "Autore" #: cyclograph/gtk_/gui.py:459 cyclograph/gtk3/gui.py:463 #: qt4_ui/ui_qt_ts.py:383 msgid "Author:" msgstr "Autore:" #: cyclograph/gtk_/gui.py:1470 cyclograph/gtk3/gui.py:1438 #: qt4_ui/ui_qt_ts.py:603 msgid "Automatic" msgstr "Automatica" #: cyclograph/cyclograph.py:741 cyclograph/cyclograph.py:777 msgid "Average gradient" msgstr "Pendenza media" #: cyclograph/gtk_/gui.py:473 cyclograph/gtk3/gui.py:471 #: cyclograph/slope.py:220 qt4_ui/ui_qt_ts.py:385 msgid "Average gradient:" msgstr "Pendenza media:" #: cyclograph/gtk_/gui.py:1513 cyclograph/gtk_/gui.py:1539 #: cyclograph/gtk3/gui.py:1481 cyclograph/gtk3/gui.py:1507 msgid "Back" msgstr "Indietro" #: cyclograph/qt/glal.py:319 cyclograph/qt/gui.py:835 msgid "Cancel" msgstr "Annulla" #: cyclograph/gtk_/gui.py:809 cyclograph/gtk3/gui.py:804 #: qt4_ui/ui_qt_ts.py:874 msgid "Check online" msgstr "Controlla online" #: cyclograph/cyclograph.py:187 cyclograph/cyclograph.py:381 msgid "Choose a file" msgstr "Scegli un file" #: cyclograph/qt/gui.py:743 cyclograph/gtk_/gui.py:1465 #: cyclograph/gtk3/gui.py:1433 msgid "Choose the type of import you want" msgstr "Seleziona il tipo di importazione" #: qt4_ui/ui_qt_ts.py:641 msgid "Close" msgstr "Chiudi" #: cyclograph/qt/gui.py:834 cyclograph/gtk_/gui.py:1658 #: cyclograph/gtk3/gui.py:1626 msgid "Close without saving" msgstr "Chiudi senza salvare" #: cyclograph/cyclograph.py:740 cyclograph/cyclograph.py:776 msgid "Country" msgstr "Nazione" #: cyclograph/gtk_/gui.py:87 cyclograph/gtk3/gui.py:88 qt4_ui/ui_qt_ts.py:288 msgid "Create" msgstr "Crea" #: cyclograph/gtk_/gui.py:87 cyclograph/gtk3/gui.py:89 msgid "Create KML" msgstr "Crea un KML" #: cyclograph/gtk_/gui.py:1198 cyclograph/gtk3/gui.py:1159 #: qt4_ui/ui_qt_ts.py:83 msgid "Create Kml" msgstr "Crea Kml" #: cyclograph/gtk_/gui.py:116 cyclograph/gtk3/gui.py:116 #: qt4_ui/ui_qt_ts.py:280 msgid "Delete" msgstr "Cancella" #: cyclograph/gtk_/gui.py:823 cyclograph/gtk3/gui.py:818 #: qt4_ui/ui_qt_ts.py:876 msgid "Description" msgstr "Descrizione" #: cyclograph/gtk_/gui.py:332 cyclograph/gtk3/gui.py:337 #: qt4_ui/ui_qt_ts.py:643 msgid "Distance [km]" msgstr "Distanza [Km]" #: cyclograph/qt/gui.py:813 cyclograph/gtk_/gui.py:1601 #: cyclograph/gtk3/gui.py:1566 msgid "Distance and altitude are required." msgstr "Distanza e altezza sono richieste." #: cyclograph/gtk_/gui.py:387 cyclograph/gtk3/gui.py:395 #: qt4_ui/ui_qt_ts.py:440 msgid "Distance:" msgstr "Distanza:" #: cyclograph/qt/glal.py:318 cyclograph/gtk_/glal.py:355 #: cyclograph/gtk3/glal.py:338 msgid "Downloading altitudes" msgstr "Scaricamento altezze" #: cyclograph/qt/gui.py:643 cyclograph/gtk_/gui.py:1193 #: cyclograph/gtk_/gui.py:1216 cyclograph/gtk3/gui.py:1154 #: cyclograph/gtk3/gui.py:1177 qt4_ui/ui_qt_ts.py:92 msgid "Draw on the map" msgstr "Disegna sulla mappa" #: cyclograph/cyclograph.py:747 cyclograph/cyclograph.py:783 #: cyclograph/gtk_/gui.py:924 cyclograph/gtk3/gui.py:913 msgid "E-mail" msgstr "E-mail" #: cyclograph/gtk_/gui.py:466 cyclograph/gtk3/gui.py:467 #: qt4_ui/ui_qt_ts.py:384 qt4_ui/ui_qt_ts.py:885 msgid "E-mail:" msgstr "E-mail:" #: cyclograph/cyclograph.py:610 cyclograph/gtk_/gui.py:112 #: cyclograph/gtk3/gui.py:112 qt4_ui/ui_qt_ts.py:278 msgid "Edit" msgstr "Modifica" #: cyclograph/gtk_/gui.py:114 cyclograph/gtk3/gui.py:114 #: qt4_ui/ui_qt_ts.py:279 msgid "Edit a check-point" msgstr "Modifica un punto" #: cyclograph/cyclograph.py:294 msgid "Error on loading slope" msgstr "Errore durante il caricamento della salita" #: cyclograph/cyclograph.py:342 msgid "Error while loading data" msgstr "Errore durante il caricamento dei dati" #: qt4_ui/ui_qt_ts.py:268 msgid "File" msgstr "File" #: cyclograph/cyclograph.py:390 msgid "File saved" msgstr "File salvato" #: cyclograph/gtk_/gui.py:1512 cyclograph/gtk_/gui.py:1538 #: cyclograph/gtk3/gui.py:1480 cyclograph/gtk3/gui.py:1506 msgid "Finish" msgstr "Fine" #: qt4_ui/ui_qt_ts.py:882 msgid "Fonts" msgstr "Caratteri" #: cyclograph/qt/gui.py:812 cyclograph/gtk_/gui.py:1602 #: cyclograph/gtk3/gui.py:1565 msgid "Form incomplete" msgstr "Form incompleto" #: qt4_ui/ui_qt_ts.py:875 msgid "General" msgstr "Generale" #: cyclograph/gtk_/gui.py:835 cyclograph/gtk3/gui.py:830 #: qt4_ui/ui_qt_ts.py:878 msgid "Gradient" msgstr "Pendenza" #: qt4_ui/ui_qt_ts.py:883 msgid "Gradient colors" msgstr "Colori salita" #: cyclograph/cyclograph.py:743 cyclograph/cyclograph.py:779 msgid "Height difference" msgstr "Dislivello" #: cyclograph/gtk_/gui.py:483 cyclograph/gtk3/gui.py:475 #: cyclograph/slope.py:222 qt4_ui/ui_qt_ts.py:387 msgid "Height difference:" msgstr "Dislivello:" #: cyclograph/cyclograph.py:744 cyclograph/cyclograph.py:780 #: cyclograph/slope.py:223 msgid "Height gain" msgstr "Aumento in altezza" #: cyclograph/gtk_/gui.py:488 cyclograph/gtk3/gui.py:477 #: qt4_ui/ui_qt_ts.py:388 msgid "Height gain:" msgstr "Aumento in altezza:" #: cyclograph/gtk_/gui.py:1651 cyclograph/gtk3/gui.py:1619 msgid "If you don't save, all your changes will be permanently lost." msgstr "Se non salvi, tutte le modifiche andranno perse." #: cyclograph/gtk_/gui.py:132 cyclograph/gtk3/gui.py:132 #: qt4_ui/ui_qt_ts.py:284 msgid "Info" msgstr "Info" #: cyclograph/gtk_/gui.py:133 cyclograph/gtk3/gui.py:133 #: qt4_ui/ui_qt_ts.py:285 msgid "Informations about the slope" msgstr " Informazioni sulla salita" #: cyclograph/gtk_/gui.py:785 cyclograph/gtk3/gui.py:780 #: qt4_ui/ui_qt_ts.py:871 msgid "Kml server" msgstr "kml server" #: cyclograph/gtk_/gui.py:804 cyclograph/gtk3/gui.py:799 #: qt4_ui/ui_qt_ts.py:873 msgid "Latest version" msgstr "Ultima versione" #: cyclograph/qt/gui.py:614 cyclograph/gtk_/gui.py:128 #: cyclograph/gtk_/gui.py:1123 cyclograph/gtk3/gui.py:128 #: cyclograph/gtk3/gui.py:1080 qt4_ui/ui_qt_ts.py:293 qt4_ui/ui_qt_ts.py:294 msgid "Map" msgstr "Mappa" #: cyclograph/cyclograph.py:742 cyclograph/cyclograph.py:778 msgid "Max gradient" msgstr "Pendenza massima" #: cyclograph/gtk_/gui.py:478 cyclograph/gtk3/gui.py:473 #: cyclograph/slope.py:221 qt4_ui/ui_qt_ts.py:386 msgid "Max gradient:" msgstr "Pendenza massima:" #: qt4_ui/ui_qt_ts.py:84 msgid "Mode" msgstr "Modalità" #: cyclograph/gtk_/gui.py:1226 cyclograph/gtk3/gui.py:1188 msgid "Modes" msgstr "Modalità" #: cyclograph/cyclograph.py:739 cyclograph/cyclograph.py:746 #: cyclograph/cyclograph.py:775 cyclograph/cyclograph.py:782 #: cyclograph/gtk_/gui.py:342 cyclograph/gtk_/gui.py:914 #: cyclograph/gtk3/gui.py:347 cyclograph/gtk3/gui.py:903 #: qt4_ui/ui_qt_ts.py:647 msgid "Name" msgstr "Nome" #: cyclograph/gtk_/gui.py:389 cyclograph/gtk_/gui.py:445 #: cyclograph/gtk3/gui.py:397 cyclograph/gtk3/gui.py:455 #: qt4_ui/ui_qt_ts.py:380 qt4_ui/ui_qt_ts.py:441 qt4_ui/ui_qt_ts.py:884 msgid "Name:" msgstr "Nome:" #: cyclograph/cyclograph.py:275 msgid "Network error : unable to create an handler to download kml route." msgstr "" "Errore di rete: impossibile creare un gestore per scaricare il percorso del " "kml." #: cyclograph/gtk_/gui.py:85 cyclograph/gtk3/gui.py:84 msgid "New" msgstr "Nuovo" #: cyclograph/gtk_/gui.py:85 cyclograph/gtk3/gui.py:85 msgid "New Slope" msgstr " Nuova Salita" #: cyclograph/gtk_/gui.py:1489 cyclograph/gtk3/gui.py:1457 #: qt4_ui/ui_qt_ts.py:607 msgid "Next" msgstr "Avanti" #: cyclograph/qt/gui.py:818 cyclograph/gtk_/gui.py:1611 #: cyclograph/gtk3/gui.py:1574 msgid "No coordinates" msgstr "Nessuna coordinata" #: cyclograph/qt/gui.py:806 cyclograph/gtk_/gui.py:1593 #: cyclograph/gtk3/gui.py:1556 msgid "No route" msgstr "Nessun percorso" #: cyclograph/qt/gui.py:825 cyclograph/gtk_/gui.py:1621 #: cyclograph/gtk3/gui.py:1583 msgid "Not enough check points" msgstr "Non ci sono abbastanza check point" #: cyclograph/cyclograph.py:785 cyclograph/gtk_/gui.py:501 #: cyclograph/gtk3/gui.py:480 msgid "Note" msgstr "Note" #: qt4_ui/ui_qt_ts.py:382 msgid "Note:" msgstr "Note:" #: cyclograph/qt/gui.py:642 cyclograph/gtk_/gui.py:1192 #: cyclograph/gtk_/gui.py:1215 cyclograph/gtk3/gui.py:1153 #: cyclograph/gtk3/gui.py:1176 qt4_ui/ui_qt_ts.py:90 msgid "OSRM" msgstr "OSRM" #: cyclograph/cyclograph.py:244 msgid "Old file format: please save it again." msgstr "Vecchio formato di file: salvare di nuovo" #: cyclograph/gtk_/gui.py:86 cyclograph/gtk3/gui.py:86 msgid "Open" msgstr "Apri" #: cyclograph/qt/gui.py:641 cyclograph/gtk_/gui.py:1191 #: cyclograph/gtk_/gui.py:1214 cyclograph/gtk3/gui.py:1152 #: cyclograph/gtk3/gui.py:1175 qt4_ui/ui_qt_ts.py:88 msgid "Open Route Service" msgstr "Open Route Service" #: cyclograph/gtk_/gui.py:86 cyclograph/gtk3/gui.py:87 msgid "Open Slope" msgstr " Apri Salita" #: qt4_ui/ui_qt_ts.py:269 msgid "Options" msgstr "&Opzioni" #: cyclograph/gtk_/gui.py:742 cyclograph/gtk3/gui.py:561 #: cyclograph/gtk3/gui.py:737 qt4_ui/ui_qt_ts.py:867 msgid "Orizzontal lines" msgstr "Linee orizzontali" #: cyclograph/gtk_/glal.py:356 cyclograph/gtk3/glal.py:339 msgid "Please wait, Cycograph is downloading altitudes." msgstr "attendere, Cyclograph sta scaricando le altimetrie" #: cyclograph/gtk_/gui.py:124 cyclograph/gtk3/gui.py:124 #: qt4_ui/ui_qt_ts.py:282 msgid "Plot" msgstr "Disegna" #: cyclograph/gtk_/gui.py:125 cyclograph/gtk3/gui.py:125 #: qt4_ui/ui_qt_ts.py:283 msgid "Plot your slope" msgstr "Disegna la salita" #: cyclograph/gtk_/gui.py:716 cyclograph/gtk3/gui.py:709 #: qt4_ui/ui_qt_ts.py:865 msgid "Preferences" msgstr "Preferenze" #: qt4_ui/ui_qt_ts.py:277 msgid "Press + on the keyboard to add a check-point" msgstr "Premere + sulla tastiera per aggiungere un check-point" #: qt4_ui/ui_qt_ts.py:281 msgid "Press - on the keyboard to remove the selected check-point" msgstr "Premere - sulla tastiera per rimuovere il check-point selezionato" #: cyclograph/gtk_/gui.py:118 cyclograph/gtk3/gui.py:118 msgid "Remove a check-point" msgstr "Rimuove check-point" #: cyclograph/gtk_/gui.py:752 cyclograph/gtk3/gui.py:747 #: qt4_ui/ui_qt_ts.py:869 msgid "Resolution" msgstr "Risoluzione" #: cyclograph/gtk_/gui.py:941 cyclograph/gtk3/gui.py:930 msgid "Restore Default" msgstr "Ripristina default" #: cyclograph/qt/gui.py:437 cyclograph/qt/gui.py:833 cyclograph/gtk_/gui.py:88 #: cyclograph/gtk3/gui.py:90 msgid "Save" msgstr "Salva" #: qt4_ui/ui_qt_ts.py:290 msgid "Save &As" msgstr "Salva &come" #: cyclograph/qt/gui.py:441 msgid "Save PDF" msgstr "Salva PDF" #: cyclograph/gtk_/gui.py:88 cyclograph/gtk3/gui.py:91 msgid "Save Slope" msgstr " Salva Salita" #: cyclograph/gtk_/gui.py:565 cyclograph/gtk3/gui.py:557 msgid "Save _PDF" msgstr "Salva _PDF" #: cyclograph/gtk_/gui.py:567 cyclograph/gtk3/gui.py:559 msgid "Save _html" msgstr "Salva _html" #: cyclograph/cyclograph.py:362 qt4_ui/ui_qt_ts.py:291 msgid "Save as" msgstr "Salva come" #: cyclograph/qt/gui.py:838 cyclograph/gtk_/gui.py:1655 #: cyclograph/gtk3/gui.py:1623 msgid "Save changes" msgstr "Salvare le modifiche a" #: cyclograph/qt/gui.py:837 cyclograph/gtk_/gui.py:1650 #: cyclograph/gtk3/gui.py:1618 #, python-format msgid "Save changes to %s before closing?" msgstr "Salvare i cambiamenti in %s prima di chiudere?" #: cyclograph/qt/gui.py:442 msgid "Save html" msgstr "Salva html" #: cyclograph/cyclograph.py:687 msgid "Save map" msgstr "Salva mappa" #: cyclograph/cyclograph.py:705 msgid "Save plot" msgstr "Salva kml" #: cyclograph/cyclograph.py:761 msgid "Save plot to html" msgstr "Salva grafico in html" #: cyclograph/cyclograph.py:728 msgid "Save plot to pdf" msgstr "Salva grafico in PDF" #: cyclograph/gtk_/gui.py:602 cyclograph/gtk3/gui.py:594 msgid "Saving _resolution" msgstr "_Risoluzione del salvataggio" #: cyclograph/gtk_/gui.py:1039 cyclograph/gtk3/gui.py:1019 msgid "Select Font" msgstr "Seleziona lo stile" #: cyclograph/gtk_/gui.py:1071 msgid "Select color" msgstr "Colori salita" #: cyclograph/gtk_/gui.py:1479 cyclograph/gtk3/gui.py:1447 #: qt4_ui/ui_qt_ts.py:604 msgid "Select the distance rate" msgstr "Seleziona l'intervallo di distanza" #: cyclograph/gtk_/gui.py:1475 cyclograph/gtk3/gui.py:1443 #: qt4_ui/ui_qt_ts.py:605 msgid "Select the number of checkpoints" msgstr "Seleziona il numero di checkpoint" #: cyclograph/gtk_/gui.py:748 cyclograph/gtk3/gui.py:743 #: qt4_ui/ui_qt_ts.py:872 msgid "Show info" msgstr "Mostra informazioni" #: cyclograph/gtk_/gui.py:129 cyclograph/gtk3/gui.py:129 #: qt4_ui/ui_qt_ts.py:295 msgid "Show the map of your slope" msgstr "Mostra la mappa della salita" #: cyclograph/gtk_/gui.py:241 cyclograph/gtk3/gui.py:243 #: qt4_ui/ui_qt_ts.py:286 msgid "Signal a bug" msgstr "Segnala un bug" #: cyclograph/cyclograph.py:738 cyclograph/cyclograph.py:774 msgid "Slope" msgstr "Salita" #: cyclograph/gtk_/gui.py:430 cyclograph/gtk3/gui.py:437 #: qt4_ui/ui_qt_ts.py:379 msgid "Slope Info" msgstr "Info Salita" #: cyclograph/qt/gui.py:806 cyclograph/gtk_/gui.py:1592 #: cyclograph/gtk3/gui.py:1557 msgid "Specify one route first." msgstr "Specificare prima un percorso." #: cyclograph/gtk_/gui.py:452 cyclograph/gtk3/gui.py:459 #: qt4_ui/ui_qt_ts.py:381 msgid "State:" msgstr "Stato:" #: cyclograph/qt/gui.py:740 cyclograph/gtk_/gui.py:1500 #: cyclograph/gtk3/gui.py:1468 #, python-format msgid "" "The %s file contains %d points.\n" "Choose how many will be imported." msgstr "" "il file %s contiene %d punti.\n" "Scegli quanti importarne." #: cyclograph/qt/gui.py:742 cyclograph/gtk_/gui.py:1526 #: cyclograph/gtk3/gui.py:1494 #, python-format msgid "" "The %s file contains a route of %d Km.\n" "Choose what range you want between points." msgstr "" "il file %s contiene un percorso di %d Km.\n" "Scegli quale distanza vuoi tra i punti." #: cyclograph/gtk_/gui.py:771 cyclograph/gtk3/gui.py:766 #: qt4_ui/ui_qt_ts.py:870 msgid "Theme" msgstr "Tema" #: cyclograph/qt/gui.py:826 cyclograph/gtk_/gui.py:1619 #: cyclograph/gtk3/gui.py:1584 msgid "" "There aren't enougth check points to plot.\n" " At least two points are required to plot." msgstr "" "Non ci sono abbastanza punti da disegnare.\n" " Per il disegno servono almeno 2 punti." #: cyclograph/gtk_/gui.py:847 cyclograph/gtk3/gui.py:842 #: qt4_ui/ui_qt_ts.py:880 msgid "Title" msgstr "Titolo" #: cyclograph/cyclograph.py:238 msgid "Unable to open file" msgstr "Impossibile aprire il file" #: cyclograph/gtk_/gui.py:1483 cyclograph/gtk3/gui.py:1451 #: qt4_ui/ui_qt_ts.py:606 msgid "Use every point (discouraged)" msgstr "Utilizza tutti i punti (sconsigliato)" #: cyclograph/gtk_/gui.py:737 cyclograph/gtk3/gui.py:732 #: qt4_ui/ui_qt_ts.py:866 msgid "Visualization" msgstr "Visualizzazione" #: cyclograph/gtk_/gui.py:159 cyclograph/gtk3/gui.py:159 msgid "_File" msgstr "_File" #: cyclograph/gtk_/gui.py:208 cyclograph/gtk_/gui.py:554 #: cyclograph/gtk3/gui.py:207 cyclograph/gtk3/gui.py:549 msgid "_Options" msgstr "_Opzioni" #: cyclograph/gtk_/gui.py:569 msgid "_Orizzontal lines" msgstr "_Linee orizzontali" #: cyclograph/gtk_/gui.py:577 cyclograph/gtk3/gui.py:569 msgid "_Theme" msgstr "_Tema" #: qt4_ui/ui_qt_ts.py:877 qt4_ui/ui_qt_ts.py:879 qt4_ui/ui_qt_ts.py:881 msgid "font | dim" msgstr "font | dim" #: cyclograph/cyclograph.py:259 msgid "kml name" msgstr "nome del kml" #: qt4_ui/ui_qt_ts.py:472 #, fuzzy msgid "map" msgstr "Mappa" #: cyclograph/gtk_/gui.py:1451 cyclograph/gtk3/gui.py:1419 #: qt4_ui/ui_qt_ts.py:602 msgid "number of checkpoints" msgstr "numero di checkpoint" #: cyclograph/cyclograph.py:149 msgid "old cofiguration issue." msgstr "problema con una vecchia configurazione" #: cyclograph/cyclograph.py:168 cyclograph/cyclograph.py:523 #: cyclograph/cyclograph.py:532 msgid "slope" msgstr "Salita" #: cyclograph/cyclograph.py:300 #, python-format msgid "slope %d" msgstr "Salita %d" #: cyclograph/qt/gui.py:819 cyclograph/gtk_/gui.py:1610 #: cyclograph/gtk3/gui.py:1575 msgid "there aren't coordinates associated with this slope." msgstr "non ci sono coordinate associate alla salita" #~ msgid "&Delete configuration file" #~ msgstr "&Cancella i file di configurazione" #~ msgid "&Description" #~ msgstr "&Descrizione" #~ msgid "&Gradient" #~ msgstr "&Pendenza" #~ msgid "&Import KML" #~ msgstr "&Importa KML" #~ msgid "&Save preferences" #~ msgstr "&Salva preferenze" #~ msgid "&Slope colors..." #~ msgstr "&Colori salita" #~ msgid "&Title" #~ msgstr "&Titolo" #~ msgid "&Use default preferences" #~ msgstr "&Usa le preferenze di default" #~ msgid "Cyclograph" #~ msgstr "CycloGraph" #~ msgid "Frame" #~ msgstr "Riquadro" #~ msgid "&Effect 3d" #~ msgstr "&Effetto 3d" #~ msgid "3D effect " #~ msgstr "Effetto 3d" #~ msgid "Import" #~ msgstr "Importa" #~ msgid "Import KML" #~ msgstr "Importa KML" #~ msgid "Save kml" #~ msgstr "Salva kml" #~ msgid "Error" #~ msgstr "Errore:" #~ msgid "_Create Kml" #~ msgstr "_Crea Kml" #~ msgid "_Import KML" #~ msgstr "_Importa KML" #~ msgid "Library not available" #~ msgstr "Libreria non disponibile" #~ msgid "PyQt4 is not installed on the system" #~ msgstr "PyQt4 non è installato sul sistema." #~ msgid "The gtk python module is not installed on the system" #~ msgstr "Il modulo python di gtk non è installato sul sistema." #~ msgid "" #~ "You should have it on your machine if you want to use the GTK+ front-end" #~ msgstr "" #~ "Dovresti averlo installato sul tuo sistema se vuoi usare l'interfaccia GTK" #~ "+." #~ msgid "" #~ "You should have it on your machine if you want to use the qt front-end" #~ msgstr "" #~ "Dovresti averlo installato sul tuo sistema se vuoi usare l'interfaccia qt." #~ msgid "_Saving resolution" #~ msgstr "_Risoluzione del salvataggio" #~ msgid "pygtk not installed" #~ msgstr "le librerie pygtk non sono installate" #~ msgid "pyqt not installed" #~ msgstr "le librerie pyqt non sono installate" #~ msgid "" #~ "There aren't enougth check points to plot.\n" #~ " To plot are required at least 2 points." #~ msgstr "" #~ "Non ci sono abbastanza punti da disegnare.\n" #~ " Per il disegno servono almeno 2 punti." #~ msgid "Save changes to " #~ msgstr "Salvare le modifiche a " #~ msgid "Are you sure you want to reset to initial configuration preferences?" #~ msgstr "" #~ "Sei sicuro di voler azzerare la configurazione delle preferenze al valore " #~ "iniziale?" #~ msgid "Default preferences" #~ msgstr "Azzera preferenze" #~ msgid "Des_cription" #~ msgstr "Des_crizione" #~ msgid "Grad_ient" #~ msgstr "_Pendenza" #~ msgid "_Delete configuration file" #~ msgstr "_Cancella i file di configurazione" #~ msgid "_Font" #~ msgstr "_Caratteri" #~ msgid "_Gradient colors" #~ msgstr "C_olori salita" #~ msgid "_Resolution" #~ msgstr "_Risoluzione" #~ msgid "_Save preferences" #~ msgstr "_Salva preferenze" #~ msgid "_Title" #~ msgstr "_Titolo" #~ msgid "_Use default preferences" #~ msgstr "_Usa le preferenze di default" #~ msgid "Color type unknown" #~ msgstr "tipo di colore sconosciuto" #~ msgid "Specify one route." #~ msgstr "Specificare un percorso." #~ msgid "" #~ "The gtk python module is not installed on the system.\n" #~ "You should have it on your machine if you want to use the GTK+ front-end." #~ msgstr "" #~ "Il modulo gtk per python non è installato sul sistema.\n" #~ "devi installarlosul tuo sistema se vuoi usare il front-end GTK+." #, fuzzy #~ msgid "&save as" #~ msgstr "&Salva" #~ msgid "&Reset preferences" #~ msgstr "&Ripristina preferenze" #~ msgid "Graph" #~ msgstr "Grafico" #~ msgid "average gradient:" #~ msgstr "pendenza media:" #~ msgid "max gradient:" #~ msgstr "pendenza massima:" #~ msgid "Properties" #~ msgstr "Proprietà" #~ msgid "Altitude" #~ msgstr "Altezza" #~ msgid "Distance" #~ msgstr "Distanza" #~ msgid "Old file format" #~ msgstr "Vecchio formato di file" #~ msgid " Default preferences" #~ msgstr "Azzera preferenze" #~ msgid " Information about this program" #~ msgstr " Informazioni su questo programma" #~ msgid " Load Slope" #~ msgstr " Carica Salita" #~ msgid " Save preferences" #~ msgstr "Salva preferenze" #~ msgid " Terminate the program" #~ msgstr " Termina il programma" #~ msgid "&About" #~ msgstr "&Info" #~ msgid "&Exit\tCtrl+Q" #~ msgstr "&Esci\tCtrl+Q" #~ msgid "&File" #~ msgstr "&File" #~ msgid "&Gradient colors" #~ msgstr "&Colori salita" #~ msgid "&Import KML\tCtrl+I" #~ msgstr "&Importa KML\tCtrl+I" #~ msgid "&New\tCtrl+N" #~ msgstr "&Nuova\tCtrl+N" #~ msgid "&Open\tCtrl+O" #~ msgstr "&Apri\tCtrl+O" #~ msgid "&Save\tCtrl+S" #~ msgstr "&Salva\tCtrl+S" #~ msgid "&orizzontal lines" #~ msgstr "&linee orizzontali" #~ msgid "&save preferences" #~ msgstr "&Salva preferenze" #~ msgid "Add cp" #~ msgstr "Aggiungi" #~ msgid "OK" #~ msgstr "OK" #~ msgid "State" #~ msgstr "Stato" #~ msgid "&Font..." #~ msgstr "&Carattere" cyclograph-1.6.1/po/en/0000755000175000017500000000000012231302005016240 5ustar federicofederico00000000000000cyclograph-1.6.1/po/en/LC_MESSAGES/0000755000175000017500000000000012231302005020025 5ustar federicofederico00000000000000cyclograph-1.6.1/po/en/LC_MESSAGES/cyclograph.mo0000644000175000017500000000063612217121674022541 0ustar federicofederico00000000000000$,8d9Project-Id-Version: Cyclograph Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-18 23:12+0200 PO-Revision-Date: 2013-09-19 20:07+0100 Last-Translator: agron85 Language-Team: english Language: en MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: Poedit 1.5.4 cyclograph-1.6.1/po/en/LC_MESSAGES/cyclograph.po0000644000175000017500000003675312217121674022555 0ustar federicofederico00000000000000# Cyclograph. # Copyright (C) 2010 Pierluigi Villani # This file is distributed under the same license as the Cyclograph package. # Pierluigi Villani , 2010, 2011, 2012, 2013. # msgid "" msgstr "" "Project-Id-Version: Cyclograph\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-18 23:12+0200\n" "PO-Revision-Date: 2013-09-19 20:07+0100\n" "Last-Translator: Pierluigi Villani \n" "Language-Team: english \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.4\n" #: qt4_ui/ui_qt_ts.py:289 msgid " Create Kml" msgstr "" #: qt4_ui/ui_qt_ts.py:287 msgid "&Create Kml" msgstr "" #: qt4_ui/ui_qt_ts.py:270 msgid "&Kml server" msgstr "" #: qt4_ui/ui_qt_ts.py:275 msgid "&New" msgstr "" #: qt4_ui/ui_qt_ts.py:271 msgid "&Open" msgstr "" #: cyclograph/qt/gui.py:465 msgid "&Options" msgstr "" #: cyclograph/qt/gui.py:446 msgid "&Orizzontal lines" msgstr "" #: qt4_ui/ui_qt_ts.py:292 msgid "&Preferences" msgstr "" #: qt4_ui/ui_qt_ts.py:273 msgid "&Quit" msgstr "" #: qt4_ui/ui_qt_ts.py:272 msgid "&Save" msgstr "" #: cyclograph/qt/gui.py:477 msgid "&Saving resolution" msgstr "" #: cyclograph/qt/gui.py:472 msgid "&Theme" msgstr "" #: cyclograph/qt/gui.py:450 msgid "3D &effect" msgstr "" #: cyclograph/gtk_/gui.py:572 msgid "3D _effect" msgstr "" #: cyclograph/gtk_/gui.py:745 cyclograph/gtk3/gui.py:564 #: cyclograph/gtk3/gui.py:740 qt4_ui/ui_qt_ts.py:868 msgid "3D effect" msgstr "" #: cyclograph/cyclograph.py:121 msgid "A new version of CycloGraph is out!" msgstr "" #: qt4_ui/ui_qt_ts.py:274 msgid "About" msgstr "" #: cyclograph/cyclograph.py:588 cyclograph/gtk_/gui.py:105 #: cyclograph/gtk3/gui.py:105 qt4_ui/ui_qt_ts.py:276 #, fuzzy msgid "Add" msgstr "Add" #: cyclograph/gtk_/gui.py:107 cyclograph/gtk3/gui.py:107 msgid "Add a check-point" msgstr "" #: cyclograph/gtk_/gui.py:337 cyclograph/gtk3/gui.py:342 #: qt4_ui/ui_qt_ts.py:645 msgid "Altitude [m]" msgstr "" #: cyclograph/gtk_/gui.py:388 cyclograph/gtk3/gui.py:396 #: qt4_ui/ui_qt_ts.py:442 msgid "Altitude:" msgstr "" #: cyclograph/cyclograph.py:745 cyclograph/cyclograph.py:781 #: qt4_ui/ui_qt_ts.py:886 msgid "Author" msgstr "" #: cyclograph/gtk_/gui.py:459 cyclograph/gtk3/gui.py:463 #: qt4_ui/ui_qt_ts.py:383 msgid "Author:" msgstr "" #: cyclograph/gtk_/gui.py:1470 cyclograph/gtk3/gui.py:1438 #: qt4_ui/ui_qt_ts.py:603 msgid "Automatic" msgstr "" #: cyclograph/cyclograph.py:741 cyclograph/cyclograph.py:777 msgid "Average gradient" msgstr "" #: cyclograph/gtk_/gui.py:473 cyclograph/gtk3/gui.py:471 #: cyclograph/slope.py:220 qt4_ui/ui_qt_ts.py:385 msgid "Average gradient:" msgstr "" #: cyclograph/gtk_/gui.py:1513 cyclograph/gtk_/gui.py:1539 #: cyclograph/gtk3/gui.py:1481 cyclograph/gtk3/gui.py:1507 msgid "Back" msgstr "" #: cyclograph/qt/glal.py:319 cyclograph/qt/gui.py:835 msgid "Cancel" msgstr "" #: cyclograph/gtk_/gui.py:809 cyclograph/gtk3/gui.py:804 #: qt4_ui/ui_qt_ts.py:874 msgid "Check online" msgstr "" #: cyclograph/cyclograph.py:187 cyclograph/cyclograph.py:381 msgid "Choose a file" msgstr "" #: cyclograph/qt/gui.py:743 cyclograph/gtk_/gui.py:1465 #: cyclograph/gtk3/gui.py:1433 msgid "Choose the type of import you want" msgstr "" #: qt4_ui/ui_qt_ts.py:641 msgid "Close" msgstr "" #: cyclograph/qt/gui.py:834 cyclograph/gtk_/gui.py:1658 #: cyclograph/gtk3/gui.py:1626 msgid "Close without saving" msgstr "" #: cyclograph/cyclograph.py:740 cyclograph/cyclograph.py:776 msgid "Country" msgstr "" #: cyclograph/gtk_/gui.py:87 cyclograph/gtk3/gui.py:88 qt4_ui/ui_qt_ts.py:288 msgid "Create" msgstr "" #: cyclograph/gtk_/gui.py:87 cyclograph/gtk3/gui.py:89 msgid "Create KML" msgstr "" #: cyclograph/gtk_/gui.py:1198 cyclograph/gtk3/gui.py:1159 #: qt4_ui/ui_qt_ts.py:83 msgid "Create Kml" msgstr "" #: cyclograph/gtk_/gui.py:116 cyclograph/gtk3/gui.py:116 #: qt4_ui/ui_qt_ts.py:280 msgid "Delete" msgstr "" #: cyclograph/gtk_/gui.py:823 cyclograph/gtk3/gui.py:818 #: qt4_ui/ui_qt_ts.py:876 msgid "Description" msgstr "" #: cyclograph/gtk_/gui.py:332 cyclograph/gtk3/gui.py:337 #: qt4_ui/ui_qt_ts.py:643 msgid "Distance [km]" msgstr "" #: cyclograph/qt/gui.py:813 cyclograph/gtk_/gui.py:1601 #: cyclograph/gtk3/gui.py:1566 msgid "Distance and altitude are required." msgstr "" #: cyclograph/gtk_/gui.py:387 cyclograph/gtk3/gui.py:395 #: qt4_ui/ui_qt_ts.py:440 msgid "Distance:" msgstr "" #: cyclograph/qt/glal.py:318 cyclograph/gtk_/glal.py:355 #: cyclograph/gtk3/glal.py:338 msgid "Downloading altitudes" msgstr "" #: cyclograph/qt/gui.py:643 cyclograph/gtk_/gui.py:1193 #: cyclograph/gtk_/gui.py:1216 cyclograph/gtk3/gui.py:1154 #: cyclograph/gtk3/gui.py:1177 qt4_ui/ui_qt_ts.py:92 msgid "Draw on the map" msgstr "" #: cyclograph/cyclograph.py:747 cyclograph/cyclograph.py:783 #: cyclograph/gtk_/gui.py:924 cyclograph/gtk3/gui.py:913 msgid "E-mail" msgstr "" #: cyclograph/gtk_/gui.py:466 cyclograph/gtk3/gui.py:467 #: qt4_ui/ui_qt_ts.py:384 qt4_ui/ui_qt_ts.py:885 msgid "E-mail:" msgstr "" #: cyclograph/cyclograph.py:610 cyclograph/gtk_/gui.py:112 #: cyclograph/gtk3/gui.py:112 qt4_ui/ui_qt_ts.py:278 msgid "Edit" msgstr "" #: cyclograph/gtk_/gui.py:114 cyclograph/gtk3/gui.py:114 #: qt4_ui/ui_qt_ts.py:279 msgid "Edit a check-point" msgstr "" #: cyclograph/cyclograph.py:294 msgid "Error on loading slope" msgstr "" #: cyclograph/cyclograph.py:342 msgid "Error while loading data" msgstr "" #: qt4_ui/ui_qt_ts.py:268 msgid "File" msgstr "" #: cyclograph/cyclograph.py:390 msgid "File saved" msgstr "" #: cyclograph/gtk_/gui.py:1512 cyclograph/gtk_/gui.py:1538 #: cyclograph/gtk3/gui.py:1480 cyclograph/gtk3/gui.py:1506 msgid "Finish" msgstr "" #: qt4_ui/ui_qt_ts.py:882 msgid "Fonts" msgstr "" #: cyclograph/qt/gui.py:812 cyclograph/gtk_/gui.py:1602 #: cyclograph/gtk3/gui.py:1565 msgid "Form incomplete" msgstr "" #: qt4_ui/ui_qt_ts.py:875 msgid "General" msgstr "" #: cyclograph/gtk_/gui.py:835 cyclograph/gtk3/gui.py:830 #: qt4_ui/ui_qt_ts.py:878 msgid "Gradient" msgstr "" #: qt4_ui/ui_qt_ts.py:883 msgid "Gradient colors" msgstr "" #: cyclograph/cyclograph.py:743 cyclograph/cyclograph.py:779 msgid "Height difference" msgstr "" #: cyclograph/gtk_/gui.py:483 cyclograph/gtk3/gui.py:475 #: cyclograph/slope.py:222 qt4_ui/ui_qt_ts.py:387 msgid "Height difference:" msgstr "" #: cyclograph/cyclograph.py:744 cyclograph/cyclograph.py:780 #: cyclograph/slope.py:223 msgid "Height gain" msgstr "" #: cyclograph/gtk_/gui.py:488 cyclograph/gtk3/gui.py:477 #: qt4_ui/ui_qt_ts.py:388 msgid "Height gain:" msgstr "" #: cyclograph/gtk_/gui.py:1651 cyclograph/gtk3/gui.py:1619 msgid "If you don't save, all your changes will be permanently lost." msgstr "" #: cyclograph/gtk_/gui.py:132 cyclograph/gtk3/gui.py:132 #: qt4_ui/ui_qt_ts.py:284 msgid "Info" msgstr "" #: cyclograph/gtk_/gui.py:133 cyclograph/gtk3/gui.py:133 #: qt4_ui/ui_qt_ts.py:285 msgid "Informations about the slope" msgstr "" #: cyclograph/gtk_/gui.py:785 cyclograph/gtk3/gui.py:780 #: qt4_ui/ui_qt_ts.py:871 msgid "Kml server" msgstr "" #: cyclograph/gtk_/gui.py:804 cyclograph/gtk3/gui.py:799 #: qt4_ui/ui_qt_ts.py:873 msgid "Latest version" msgstr "" #: cyclograph/qt/gui.py:614 cyclograph/gtk_/gui.py:128 #: cyclograph/gtk_/gui.py:1123 cyclograph/gtk3/gui.py:128 #: cyclograph/gtk3/gui.py:1080 qt4_ui/ui_qt_ts.py:293 qt4_ui/ui_qt_ts.py:294 msgid "Map" msgstr "" #: cyclograph/cyclograph.py:742 cyclograph/cyclograph.py:778 msgid "Max gradient" msgstr "" #: cyclograph/gtk_/gui.py:478 cyclograph/gtk3/gui.py:473 #: cyclograph/slope.py:221 qt4_ui/ui_qt_ts.py:386 msgid "Max gradient:" msgstr "" #: qt4_ui/ui_qt_ts.py:84 msgid "Mode" msgstr "" #: cyclograph/gtk_/gui.py:1226 cyclograph/gtk3/gui.py:1188 msgid "Modes" msgstr "" #: cyclograph/cyclograph.py:739 cyclograph/cyclograph.py:746 #: cyclograph/cyclograph.py:775 cyclograph/cyclograph.py:782 #: cyclograph/gtk_/gui.py:342 cyclograph/gtk_/gui.py:914 #: cyclograph/gtk3/gui.py:347 cyclograph/gtk3/gui.py:903 #: qt4_ui/ui_qt_ts.py:647 msgid "Name" msgstr "" #: cyclograph/gtk_/gui.py:389 cyclograph/gtk_/gui.py:445 #: cyclograph/gtk3/gui.py:397 cyclograph/gtk3/gui.py:455 #: qt4_ui/ui_qt_ts.py:380 qt4_ui/ui_qt_ts.py:441 qt4_ui/ui_qt_ts.py:884 msgid "Name:" msgstr "" #: cyclograph/cyclograph.py:275 msgid "Network error : unable to create an handler to download kml route." msgstr "" #: cyclograph/gtk_/gui.py:85 cyclograph/gtk3/gui.py:84 msgid "New" msgstr "" #: cyclograph/gtk_/gui.py:85 cyclograph/gtk3/gui.py:85 msgid "New Slope" msgstr "" #: cyclograph/gtk_/gui.py:1489 cyclograph/gtk3/gui.py:1457 #: qt4_ui/ui_qt_ts.py:607 msgid "Next" msgstr "" #: cyclograph/qt/gui.py:818 cyclograph/gtk_/gui.py:1611 #: cyclograph/gtk3/gui.py:1574 msgid "No coordinates" msgstr "" #: cyclograph/qt/gui.py:806 cyclograph/gtk_/gui.py:1593 #: cyclograph/gtk3/gui.py:1556 msgid "No route" msgstr "" #: cyclograph/qt/gui.py:825 cyclograph/gtk_/gui.py:1621 #: cyclograph/gtk3/gui.py:1583 msgid "Not enough check points" msgstr "" #: cyclograph/cyclograph.py:785 cyclograph/gtk_/gui.py:501 #: cyclograph/gtk3/gui.py:480 msgid "Note" msgstr "" #: qt4_ui/ui_qt_ts.py:382 msgid "Note:" msgstr "" #: cyclograph/qt/gui.py:642 cyclograph/gtk_/gui.py:1192 #: cyclograph/gtk_/gui.py:1215 cyclograph/gtk3/gui.py:1153 #: cyclograph/gtk3/gui.py:1176 qt4_ui/ui_qt_ts.py:90 msgid "OSRM" msgstr "" #: cyclograph/cyclograph.py:244 msgid "Old file format: please save it again." msgstr "" #: cyclograph/gtk_/gui.py:86 cyclograph/gtk3/gui.py:86 msgid "Open" msgstr "" #: cyclograph/qt/gui.py:641 cyclograph/gtk_/gui.py:1191 #: cyclograph/gtk_/gui.py:1214 cyclograph/gtk3/gui.py:1152 #: cyclograph/gtk3/gui.py:1175 qt4_ui/ui_qt_ts.py:88 msgid "Open Route Service" msgstr "" #: cyclograph/gtk_/gui.py:86 cyclograph/gtk3/gui.py:87 msgid "Open Slope" msgstr "" #: qt4_ui/ui_qt_ts.py:269 msgid "Options" msgstr "" #: cyclograph/gtk_/gui.py:742 cyclograph/gtk3/gui.py:561 #: cyclograph/gtk3/gui.py:737 qt4_ui/ui_qt_ts.py:867 msgid "Orizzontal lines" msgstr "" #: cyclograph/gtk_/glal.py:356 cyclograph/gtk3/glal.py:339 msgid "Please wait, Cycograph is downloading altitudes." msgstr "" #: cyclograph/gtk_/gui.py:124 cyclograph/gtk3/gui.py:124 #: qt4_ui/ui_qt_ts.py:282 msgid "Plot" msgstr "" #: cyclograph/gtk_/gui.py:125 cyclograph/gtk3/gui.py:125 #: qt4_ui/ui_qt_ts.py:283 msgid "Plot your slope" msgstr "" #: cyclograph/gtk_/gui.py:716 cyclograph/gtk3/gui.py:709 #: qt4_ui/ui_qt_ts.py:865 msgid "Preferences" msgstr "" #: qt4_ui/ui_qt_ts.py:277 msgid "Press + on the keyboard to add a check-point" msgstr "" #: qt4_ui/ui_qt_ts.py:281 msgid "Press - on the keyboard to remove the selected check-point" msgstr "" #: cyclograph/gtk_/gui.py:118 cyclograph/gtk3/gui.py:118 msgid "Remove a check-point" msgstr "" #: cyclograph/gtk_/gui.py:752 cyclograph/gtk3/gui.py:747 #: qt4_ui/ui_qt_ts.py:869 msgid "Resolution" msgstr "" #: cyclograph/gtk_/gui.py:941 cyclograph/gtk3/gui.py:930 msgid "Restore Default" msgstr "" #: cyclograph/qt/gui.py:437 cyclograph/qt/gui.py:833 cyclograph/gtk_/gui.py:88 #: cyclograph/gtk3/gui.py:90 msgid "Save" msgstr "" #: qt4_ui/ui_qt_ts.py:290 msgid "Save &As" msgstr "" #: cyclograph/qt/gui.py:441 msgid "Save PDF" msgstr "" #: cyclograph/gtk_/gui.py:88 cyclograph/gtk3/gui.py:91 msgid "Save Slope" msgstr "" #: cyclograph/gtk_/gui.py:565 cyclograph/gtk3/gui.py:557 msgid "Save _PDF" msgstr "" #: cyclograph/gtk_/gui.py:567 cyclograph/gtk3/gui.py:559 msgid "Save _html" msgstr "" #: cyclograph/cyclograph.py:362 qt4_ui/ui_qt_ts.py:291 msgid "Save as" msgstr "" #: cyclograph/qt/gui.py:838 cyclograph/gtk_/gui.py:1655 #: cyclograph/gtk3/gui.py:1623 msgid "Save changes" msgstr "" #: cyclograph/qt/gui.py:837 cyclograph/gtk_/gui.py:1650 #: cyclograph/gtk3/gui.py:1618 #, python-format msgid "Save changes to %s before closing?" msgstr "" #: cyclograph/qt/gui.py:442 msgid "Save html" msgstr "" #: cyclograph/cyclograph.py:687 msgid "Save map" msgstr "" #: cyclograph/cyclograph.py:705 msgid "Save plot" msgstr "" #: cyclograph/cyclograph.py:761 msgid "Save plot to html" msgstr "" #: cyclograph/cyclograph.py:728 msgid "Save plot to pdf" msgstr "" #: cyclograph/gtk_/gui.py:602 cyclograph/gtk3/gui.py:594 msgid "Saving _resolution" msgstr "" #: cyclograph/gtk_/gui.py:1039 cyclograph/gtk3/gui.py:1019 msgid "Select Font" msgstr "" #: cyclograph/gtk_/gui.py:1071 msgid "Select color" msgstr "" #: cyclograph/gtk_/gui.py:1479 cyclograph/gtk3/gui.py:1447 #: qt4_ui/ui_qt_ts.py:604 msgid "Select the distance rate" msgstr "" #: cyclograph/gtk_/gui.py:1475 cyclograph/gtk3/gui.py:1443 #: qt4_ui/ui_qt_ts.py:605 msgid "Select the number of checkpoints" msgstr "" #: cyclograph/gtk_/gui.py:748 cyclograph/gtk3/gui.py:743 #: qt4_ui/ui_qt_ts.py:872 msgid "Show info" msgstr "" #: cyclograph/gtk_/gui.py:129 cyclograph/gtk3/gui.py:129 #: qt4_ui/ui_qt_ts.py:295 msgid "Show the map of your slope" msgstr "" #: cyclograph/gtk_/gui.py:241 cyclograph/gtk3/gui.py:243 #: qt4_ui/ui_qt_ts.py:286 msgid "Signal a bug" msgstr "" #: cyclograph/cyclograph.py:738 cyclograph/cyclograph.py:774 msgid "Slope" msgstr "" #: cyclograph/gtk_/gui.py:430 cyclograph/gtk3/gui.py:437 #: qt4_ui/ui_qt_ts.py:379 msgid "Slope Info" msgstr "" #: cyclograph/qt/gui.py:806 cyclograph/gtk_/gui.py:1592 #: cyclograph/gtk3/gui.py:1557 msgid "Specify one route first." msgstr "" #: cyclograph/gtk_/gui.py:452 cyclograph/gtk3/gui.py:459 #: qt4_ui/ui_qt_ts.py:381 msgid "State:" msgstr "" #: cyclograph/qt/gui.py:740 cyclograph/gtk_/gui.py:1500 #: cyclograph/gtk3/gui.py:1468 #, python-format msgid "" "The %s file contains %d points.\n" "Choose how many will be imported." msgstr "" #: cyclograph/qt/gui.py:742 cyclograph/gtk_/gui.py:1526 #: cyclograph/gtk3/gui.py:1494 #, python-format msgid "" "The %s file contains a route of %d Km.\n" "Choose what range you want between points." msgstr "" #: cyclograph/gtk_/gui.py:771 cyclograph/gtk3/gui.py:766 #: qt4_ui/ui_qt_ts.py:870 msgid "Theme" msgstr "" #: cyclograph/qt/gui.py:826 cyclograph/gtk_/gui.py:1619 #: cyclograph/gtk3/gui.py:1584 msgid "" "There aren't enougth check points to plot.\n" " At least two points are required to plot." msgstr "" #: cyclograph/gtk_/gui.py:847 cyclograph/gtk3/gui.py:842 #: qt4_ui/ui_qt_ts.py:880 msgid "Title" msgstr "" #: cyclograph/cyclograph.py:238 msgid "Unable to open file" msgstr "" #: cyclograph/gtk_/gui.py:1483 cyclograph/gtk3/gui.py:1451 #: qt4_ui/ui_qt_ts.py:606 msgid "Use every point (discouraged)" msgstr "" #: cyclograph/gtk_/gui.py:737 cyclograph/gtk3/gui.py:732 #: qt4_ui/ui_qt_ts.py:866 msgid "Visualization" msgstr "" #: cyclograph/gtk_/gui.py:159 cyclograph/gtk3/gui.py:159 msgid "_File" msgstr "" #: cyclograph/gtk_/gui.py:208 cyclograph/gtk_/gui.py:554 #: cyclograph/gtk3/gui.py:207 cyclograph/gtk3/gui.py:549 msgid "_Options" msgstr "" #: cyclograph/gtk_/gui.py:569 msgid "_Orizzontal lines" msgstr "" #: cyclograph/gtk_/gui.py:577 cyclograph/gtk3/gui.py:569 msgid "_Theme" msgstr "" #: qt4_ui/ui_qt_ts.py:877 qt4_ui/ui_qt_ts.py:879 qt4_ui/ui_qt_ts.py:881 msgid "font | dim" msgstr "" #: cyclograph/cyclograph.py:259 msgid "kml name" msgstr "" #: qt4_ui/ui_qt_ts.py:472 msgid "map" msgstr "" #: cyclograph/gtk_/gui.py:1451 cyclograph/gtk3/gui.py:1419 #: qt4_ui/ui_qt_ts.py:602 msgid "number of checkpoints" msgstr "" #: cyclograph/cyclograph.py:149 msgid "old cofiguration issue." msgstr "" #: cyclograph/cyclograph.py:168 cyclograph/cyclograph.py:523 #: cyclograph/cyclograph.py:532 msgid "slope" msgstr "" #: cyclograph/cyclograph.py:300 #, python-format msgid "slope %d" msgstr "" #: cyclograph/qt/gui.py:819 cyclograph/gtk_/gui.py:1610 #: cyclograph/gtk3/gui.py:1575 msgid "there aren't coordinates associated with this slope." msgstr "" #~ msgid "Add cp" #~ msgstr "Add" cyclograph-1.6.1/man/0000755000175000017500000000000012231302005015773 5ustar federicofederico00000000000000cyclograph-1.6.1/man/cyclograph.10000644000175000017500000000172612231302004020215 0ustar federicofederico00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.43.3. .TH CYCLOGRAPH "1" "October 2013" "cyclograph 1.6.1" "User Commands" .SH NAME cyclograph \- route altimetry plotting application .SH SYNOPSIS .B cyclograph \fI{-q|-g|-G|-f}\fR .SH DESCRIPTION filename \fB\-\-qt\fR \fB\-\-gtk\fR \fB\-\-gtk3\fR or \fB\-\-file\fR=\fIFILENAME\fR for cli .SH OPTIONS .TP \fB\-\-version\fR show program's version number and exit .TP \fB\-h\fR, \fB\-\-help\fR show this help message and exit .TP \fB\-g\fR, \fB\-\-gtk\fR gtk graphical user interface .TP \fB\-G\fR, \fB\-\-gtk3\fR gtk3 graphical user interface .TP \fB\-q\fR, \fB\-\-qt\fR qt graphical user interface .TP \fB\-f\fR FILE, \fB\-\-file\fR=\fIFILE\fR open cgx, csv, gpx, tcx, sal, crp or cyclomaniac file .TP \fB\-l\fR, \fB\-\-list\fR list available themes and exit .TP \fB\-t\fR THEME, \fB\-\-theme\fR=\fITHEME\fR use selected theme .TP \fB\-e\fR EXT, \fB\-\-extension\fR=\fIEXT\fR choose default file format extension cyclograph-1.6.1/cyclograph/0000755000175000017500000000000012231302005017353 5ustar federicofederico00000000000000cyclograph-1.6.1/cyclograph/cyclograph.py0000644000175000017500000011746212231301360022076 0ustar federicofederico00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """cyclograph.py """ # Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from __future__ import with_statement, print_function, unicode_literals import slope import iofile import glal import altitude_downloader import report_html from themes import ThemeManager import os import gettext import ConfigParser import sys import Queue from optparse import OptionParser from version import VERSION, LastVersionQuery #font-typ light, normal, bold DEFAULT_CONF = {"version" : "1.2", "orizzontal lines" : "True", "slopeinfo" : "True", "effect-3d" : "True", "theme" : "Classic", "font-des 1" : "Sans", "font-typ 1" : "normal", "font-dim 1" : "10", "font-des g" : "Sans", "font-typ g" : "normal", "font-dim g" : "10", "font-des t" : "Sans", "font-typ t" : "bold", "font-dim t" : "20", "width" : "800", "height" : "600", "color 1" : "rgb(0,0,255)", "color 2" : "rgb(0,255,0)", "color 3" : "rgb(255,255,0)", "color 4" : "rgb(255,0,0)", "color 5" : "rgb(200,0,0)", "color 6" : "rgb(150,0,0)", "color 7" : "rgb(100,0,0)", "level 1" : "0", "level 2" : "3.0", "level 3" : "6.0", "level 4" : "9.0", "level 5" : "12.0", "level 6" : "15.0", "level 7" : "18.0", "server" : "geonames.org", "numcps" : "20", "widthsize" : "540", "heightsize" : "400", "maximized" : "False", "latestVersionCheck" : "True", "authorname" : "", "authormail" : "", } SECTIONS = ["global", "font", "resolution", "colors", "levels", "kml", "main window"] class Cyclograph(): """Controller according to MCV""" def __init__(self): self.slopelist = slope.SlopeList() self.init_configparser() size = (self.config.getint("main window", "widthsize"), self.config.getint("main window", "heightsize"), self.config.getboolean("main window", "maximized")) self.mygui = glal.gui.Gui(None, "CycloGraph", size) self.notebook = glal.Notebook(self.mygui.notebook, self.close) self.slopecounter = 1 self.setguiopt() glal.bind(self.new_slope, self.mygui.menu_item_new) glal.bind(self.open_slope, self.mygui.menu_item_open) glal.bind(self.create_kml, self.mygui.menu_item_createkml) glal.bind(self.save_slope, self.mygui.menu_item_save) glal.bind(self.save_slope_as, self.mygui.menu_item_save_as) glal.bind(self.preferences, self.mygui.preferences) glal.bind(self.ser1, self.mygui.menu_item_s1) glal.bind(self.ser2, self.mygui.menu_item_s2) glal.bind(self.ser3, self.mygui.menu_item_s3) glal.bind(glal.signalbug, self.mygui.menu_item_bug) glal.bind_close(self.exit, self.mygui) #Toolbar glal.ToolbarBind(self.add_cp, self.mygui.action_add) glal.ToolbarBind(self.edit_cp, self.mygui.action_edit) glal.ToolbarBind(self.delete_cp, self.mygui.action_delete) glal.ToolbarBind(self.plot_graph, self.mygui.action_plot) glal.ToolbarBind(self.map_slope, self.mygui.action_map) glal.ToolbarBind(self.info, self.mygui.action_properties) glal.Message().subscribe(self.slope_add, self.slopelist.message, "SLOPE_ADD") glal.Message().subscribe(self.slope_del, self.slopelist.message, "SLOPE_DEL") self.mygui.show() #Check if this is the latest version if self.config.getboolean("main window", "latestVersionCheck"): def notify(): self.versionchk.stop() if self.lvq.islast(): return glal.addstatusbartext(self.mygui, _("A new version of CycloGraph is out!")+"(%s)" % self.lvq.lastversion) del self.versionchk del self.lvq self.lvq = LastVersionQuery() self.lvq.start() self.versionchk = glal.Timer(10000, notify) #wait 1s before notify self.versionchk.start() def init_configparser(self): """Create a new configparser, and inizializes with default values, if the user saved his preferencese, open configuration file and use this values """ self.config = ConfigParser.SafeConfigParser(DEFAULT_CONF) self.config.read(get_config_file_path()) for sec in SECTIONS: if not self.config.has_section(sec): self.config.add_section(sec) if self.config.get("global", "version") > VERSION: #The configuration file has been saved by a future version of #CycloGraph thus it is not guaranteeted to be backward compatible. #It is better to leave the file as it is and use default settings. self.defaultpref() return if self.config.get("global", "version") < '1.1': glal.addstatusbartext(self.mygui, _("old cofiguration issue.")) def setguiopt(self): """Set gui options to the value from preferences""" serv = self.config.get("kml", "server") glal.OptionCheck(self.mygui.menu_item_s1, True) glal.OptionCheck(self.mygui.menu_item_s2, serv == "earthtools.org") glal.OptionCheck(self.mygui.menu_item_s3, serv == "usgs.net") altitude_downloader.choose_service(serv) ### Functions responding to menu events ### def new_slope(self, event=None): """ Create new slope""" pagen = self.slopelist.new_slope() self.slopelist.set_author(pagen, self.config.get("global", "authorname")) self.slopelist.set_email(pagen, self.config.get("global", "authormail")) pag = self.notebook.Page() pag.slopecounternew = self.slopecounter self.notebook.add_page(pag, _('slope')+" "+str(self.slopecounter)) self.slopecounter = self.slopecounter + 1 glal.enable_saving(self.mygui, True) def open_slope(self, event=None, filepath=None): """ Open a file""" #statusok = True types = [('Supported files','*.cgx *.csv *.xml *.gpx *.kml *.fitlog *.tcx *.crp *.sal *.txt'), ('CycloGraphXml (*.cgx)', '*.cgx'), ('CycloGraph (*.csv)', '*.csv'), ('Ciclomaniac (*.xml)', '*.xml'), ('GPS eXchange Format (*.gpx)', '*.gpx'), ('Keyhole Markup Language (*.kml)', '*.kml'), ('SportTracks Fitlog files (*.fitlog)', '*.fitlog'), ('Training Center xml (*.tcx)', '*.tcx'), ('Ciclotour (*.crp)', '*.crp'), ('Salitaker (*.sal)', '*.sal'), ('Ciclomaniac (*.txt)', '*.txt')] if not filepath: filepath = glal.FileDialog(self.mygui, _("Choose a file"), '', "", types, glal.FD_OPEN) if not filepath: return for nump in range(len(self.slopelist)): #Check if the file has already been opened. page = self.notebook.get_page(nump) if page.savedfilepath == filepath: #Select the page of the selected file. self.notebook.setselpagnum(nump) return slope_num = self.slopelist.new_slope() pag = self.notebook.Page() pag.savedfilepath = filepath self.notebook.add_page(pag, "") slopefile = None filetype = "None" if filepath.lower().endswith(".gpx"): slopefile = iofile.load_gpxfile(filepath) filetype = "gpx" elif filepath.lower().endswith(".kml"): slopefile = iofile.load_kmlfile(filepath) filetype = "kml" elif filepath.lower().endswith(".fitlog"): slopefile = iofile.load_fitlogfile(filepath) filetype = "fitlog" elif filepath.lower().endswith(".tcx"): slopefile = iofile.load_tcxfile(filepath) filetype = "tcx" if filetype == "None": statusok = iofile.open_file(filepath, self.slopelist, slope_num) else: if slopefile != None: max_num_cps = len(slopefile) (seltype, num) = glal.gui.numcpsdlg(max_num_cps, slopefile.max_dist(), filetype) if not slopefile.hasAltitudes: self.import_altitudes(num, seltype, slopefile, slope_num) return statusok = slopefile.newSlope(self.slopelist, slope_num, num, seltype) #listcoords = self.slopelist.get_coords(slope_num) #print(listcoords) else: statusok = False if not statusok: nbook = None self.slopelist.del_slope(slope_num) self.notebook.remove_page(slope_num) glal.addstatusbartext(self.mygui, _("Unable to open file")) return self.tabupdate(slope_num) glal.enable_saving(self.mygui, True) if statusok == 2: glal.addstatusbartext(self.mygui, _("Old file format: please save it again.")) def create_kml(self, event=None): """ Create kml file""" #TODO: check for internet connection def downloadfunc(url): """Download current create_kml page""" import urllib2 #FIXME if url: return urllib2.urlopen(url) def savefunc(handler, mode): """Save as kml current create_kml selected route""" content = handler.read() if mode != 'DRAW': content = iofile.gpxtokml(content) filepath = glal.FileDialog(None, _("kml name"), "", "", [("Keyhole Markup Language (*.kml)","*.kml")], glal.FD_SAVE) if not filepath: return if not filepath.endswith('.kml'): filepath = filepath+".kml" with open(filepath, "w") as outfile: print(content, file=outfile) create = glal.gui.Create_kml(self.mygui, downloadfunc, savefunc) accepted = create.show_modal() if not accepted: create.destroy() return if not create.handler: glal.addstatusbartext(self.mygui, _("Network error : unable to create an handler to download kml route.")) return if create.mode == 'DRAW': #If the user drawned the path cg must use every point, #and not waste user effort. numcps = 99999 #Hack: unlikely any user will draw more points. kmlcontent = create.handler.read() else: numcps = self.config.getint("kml", "numcps") if create.mode == 'ORS': gpxcontent = create.handler.read() kmlcontent = iofile.gpxtokml(gpxcontent) elif create.mode == 'OSRM': gpxcontent = create.handler.read() gpxcontent = gpxcontent.replace("rte", "trk") gpxcontent = gpxcontent.replace("rtept", "trkseg") kmlcontent = iofile.gpxtokml(gpxcontent) kmlfile = iofile.load_kmlfile(kmlcontent) if kmlfile == None: glal.addstatusbartext(self.mygui, _("Error on loading slope")) create.destroy() return slope_num = self.slopelist.new_slope() nbook = self.notebook.Page() nbook.slopecounternew = self.slopecounter self.notebook.add_page(nbook, _('slope %d') % self.slopecounter) self.slopecounter = self.slopecounter + 1 self.tabupdate(slope_num, '*') self.import_altitudes(numcps, 0, kmlfile, slope_num) create.destroy() def import_altitudes(self, num, seltype, slopefile, slope_num): """ Start the import kml process in cycloGraph""" #TODO: check for internet connection self.slopenumber_kml = slope_num slopefile.getCoords(self.slopelist, slope_num) self.pdlg = glal.ProgressDialog() refresh_time = 30 #FIXME: is the measure unit milliseconds? self.timer = glal.Timer(refresh_time, self.on_altitude_importing) self.queue = Queue.Queue() self.prsrthrd = altitude_downloader.ImporterThread(self.queue, slopefile, num, seltype) self.prsrthrd.daemon = True #start thread and timer self.prsrthrd.start() self.timer.start() def on_altitude_importing(self, widget=None): """ Called by a timer: check if thread is still executing (if not stop timer and, according to status, handle the produced slope) reads the progress of importer-thread updates the progress dialog check if operation is cancelled and tells to thread """ try: (progress, chkp) = self.queue.get(block=False) except Queue.Empty: #print("is alive "+str(self.prsrthrd.isAlive())) if not self.prsrthrd.isAlive(): self.timer.stop() self.pdlg.destroy() if self.prsrthrd.status != 'OK': slope_num = self.slopenumber_kml self.slopelist.del_slope(slope_num) self.notebook.remove_page(slope_num) glal.addstatusbartext(self.mygui, _("Error while loading data")) else: self.tabupdate(self.slopenumber_kml, '*') glal.enable_saving(self.mygui, True) del self.prsrthrd #there is nothing to update but gtk wants True return True self.slopelist.add_cp(self.slopenumber_kml, *chkp) #There is a new progress value => update the gui want2abort = self.pdlg.update(progress) if want2abort: self.prsrthrd.abort() #need to return True to keep timer_gtk running return True def save_slope_as(self, event=None, pagenumber=None, filename = None): """ Save_as selected slope """ if pagenumber == None: pagenumber = self.notebook.getselpagnum() myslope = self.slopelist.get_slope_copy(pagenumber) filepath = glal.FileDialog(self.mygui, _("Save as"), '', "", [("CycloGraphXml(*.cgx)","*.cgx")], glal.FD_SAVE, filename) if not filepath: return False if not filepath.endswith('.cgx'): filepath = filepath + '.cgx' iofile.save_file(filepath, myslope) page = self.notebook.get_page(pagenumber) page.savedfilepath = filepath self.tabupdate(pagenumber) return True def save_slope(self, event=None): """ Save selected slope """ pagenumber = self.notebook.getselpagnum() page = self.notebook.get_page(pagenumber) myslope = self.slopelist.get_slope_copy(pagenumber) filepath = page.savedfilepath if filepath == None or not filepath.endswith('.cgx'): filepath = glal.FileDialog(self.mygui, _("Choose a file"), '', "", [("CycloGraphXml(*.cgx)","*.cgx")], glal.FD_SAVE) if not filepath: return if not filepath.endswith('.cgx'): filepath = filepath + '.cgx' iofile.save_file(filepath, myslope) page.savedfilepath = filepath self.tabupdate(pagenumber) glal.addstatusbartext(self.mygui, _("File saved")) def exit(self): """ Check if there are unsaved slopes, and cg is ready to exit This funciotn is called by the gui""" if not len(self.slopelist): if not self.mygui.ismaximized(): dim = self.mygui.getdimensions() self.config.set("main window", "widthsize", str(dim[0])) self.config.set("main window", "heightsize", str(dim[1])) self.config.set("main window", "maximized", "%s" % self.mygui.ismaximized()) self.savepref() return True for pagenum in reversed(range(len(self.slopelist))): self.check_unsaved(pagenum) if not len(self.slopelist): if not self.mygui.ismaximized(): dim = self.mygui.getdimensions() self.config.set("main window", "widthsize", str(dim[0])) self.config.set("main window", "heightsize", str(dim[1])) self.config.set("main window", "maximized", "%s" % self.mygui.ismaximized()) self.savepref() return True else: return False def preferences(self, event=None): config = ConfigParser.SafeConfigParser(DEFAULT_CONF) config.read(get_config_file_path()) for sec in SECTIONS: if not config.has_section(sec): config.add_section(sec) if config.get("global", "version") > VERSION: self.defaultpref() settings = getconfig(config) pref = glal.gui.preferences(self.mygui, settings, DEFAULT_CONF) if not pref: return self.config.set("global", "orizzontal lines", str(pref['olines'])) self.config.set("global", "theme", pref['theme']) self.config.set("global", "slopeinfo", str(pref['sinfo'])) self.config.set("global", "effect-3d", str(pref['3d'])) self.config.set("global", "latestVersionCheck", str(pref['vcheck'])) self.config.set("global", "authorname", unicode(pref['aname'])) self.config.set("global", "authormail", unicode(pref['amail'])) font = pref['fdesc'] self.config.set("font", "font-des 1", font["des"]) self.config.set("font", "font-typ 1", font["typ"]) self.config.set("font", "font-dim 1", str(font["dim"])) font = pref['ftitle'] self.config.set("font", "font-des t", font["des"]) self.config.set("font", "font-typ t", font["typ"]) self.config.set("font", "font-dim t", str(font["dim"])) font = pref['fgrad'] self.config.set("font", "font-des g", font["des"]) self.config.set("font", "font-typ g", font["typ"]) self.config.set("font", "font-dim g", str(font["dim"])) self.config.set("resolution", "width", pref['width']) self.config.set("resolution", "height", pref['height']) self.config.set("kml", "server", pref['serv']) colorlist = pref['colors'] levellist = pref['levels'] for i in range(0, 7): self.config.set("colors", "color "+str(i+1), unicode(colorlist[i])) self.config.set("levels", "level "+str(i+1), unicode(levellist[i])) self.savepref() self.setguiopt() ### Functions related to kml server ### def ser1(self, event=None): """Set kml server1""" self.config.set("kml", "server", "geonames.org") altitude_downloader.choose_service("geonames.org") def ser2(self, event=None): """Set kml server2""" self.config.set("kml", "server", "earthtools.org") altitude_downloader.choose_service("earthtools.org") def ser3(self, event=None): """Set kml server3""" self.config.set("kml", "server", "usgs.net") altitude_downloader.choose_service("usgs.net") def ser4(self, event=None): """Set kml server4""" self.config.set("kml", "server", "google elevation") altitude_downloader.choose_service("google elevation") def savepref(self, event=None): """Save preferences. Configuration file is save in the user's home as standardized byXDG.""" with open(get_config_file_path(), "wb") as fid: self.config.write(fid) def defaultpref(self, event=None): """Load default preferences: delete current config parser and recreate a new configparser with default values""" del self.config self.config = ConfigParser.SafeConfigParser(DEFAULT_CONF) for sec in SECTIONS: if not self.config.has_section(sec): self.config.add_section(sec) self.setguiopt() ### Functions related to a single Page ### def close(self, *argument): #only qt < 4.5 doesn't pass any argument """Close a single page of notebook.""" if not len(self.slopelist): return if not argument: pagenum = self.notebook.getselpagnum() else: pagenum = self.notebook.get_pagenum(argument) self.check_unsaved(pagenum) def tabupdate(self, num, tag=''): """Update page.modified and title of the page tab""" page = self.notebook.get_page(num) name = self.slopelist.get_name(num) if tag == '': page.modified = False else: page.modified = True if name == '' or name == None: if not page.savedfilepath == None: self.notebook.set_page_label(num, tag+ os.path.split(page.savedfilepath)[-1]) else: self.notebook.set_page_label(num, tag+ _('slope')+" "+str(page.slopecounternew)) return self.notebook.set_page_label(num, tag+name) def check_unsaved(self, pagenum): """ Check if passed page is not saved and ask to save it""" page = self.notebook.get_page(pagenum) if page.modified: if page.savedfilepath == None: response = glal.gui.save_changes(self.mygui, _('slope')+" "+ str(page.slopecounternew)) if (response == 'SAVE' \ and not self.save_slope_as(None, pagenum) ) \ or response != 'DISCARD': return else: filename = os.path.split(page.savedfilepath)[-1] response = glal.gui.save_changes(self.mygui, filename) if response == 'SAVE': if not filename.endswith('.cgx'): self.save_slope_as(None, pagenum, filename.rsplit('.',1)[0]+'.cgx') return filepath = page.savedfilepath myslope = self.slopelist.get_slope_copy(pagenum) iofile.save_file(filepath, myslope) page.savedfilepath = filepath page.modified = False elif not response == 'DISCARD': return self.notebook.remove_page(pagenum) self.slopelist.del_slope(pagenum) if not len(self.slopelist): glal.enable_saving(self.mygui, False) def plot_graph(self, event=None): """Open the Plot windows showing a graphical image of current slope""" # slope_num == pagenumber == num num = self.notebook.getselpagnum() myslope = self.slopelist.get_slope_copy(num) if len(myslope) < 2: glal.gui.geterrnocp(self.mygui) return plotdata = getconfig(self.config) myplot = glal.gui.Plot(self.mygui, myslope, plotdata, export_as_image, save_pdf, save_html) myplot.showplot() def map_slope(self, event=None): """Open a Map window""" num = self.notebook.getselpagnum() slope = self.slopelist.get_slope_copy(num) if len(slope.coords) != 0: (lat, lng)= slope.coords[0] stringc = "%s %s" % (lng, lat) for i in range(1, len(slope.coords)): (lat, lng)= slope.coords[i] stringc += ",%s %s" % (lng, lat) smap = glal.gui.Map(self.mygui, slope.name, stringc, save_map_image) else: glal.gui.mapcoorderr(self.mygui) def add_cp(self, event=None): """Add a check point to current slope.""" num = self.notebook.getselpagnum() mng = glal.gui.Managecp(self.mygui, _("Add"), "", "", "") if mng.show_modal(): (dist, alt, name) = mng.getcp() if (dist != "") and (alt != ""): self.slopelist.add_cp(num, float(dist), float(alt), name) page = self.notebook.get_page(num) self.tabupdate(num, '*') else: glal.gui.managecperr(self.mygui) mng.destroy() def edit_cp(self, event=None): """Edit a check point to current slope.""" num = self.notebook.getselpagnum() page = self.notebook.get_page(num) editcp = page.get_sel_row() myslope = self.slopelist.get_slope_copy(num) if editcp < 0: return (dist, alt, name) = (str(myslope.cps[editcp][0]), str(myslope.cps[editcp][1]), str(myslope.cps[editcp][2])) mng = glal.gui.Managecp(self.mygui, _("Edit"), dist, alt, name) if mng.show_modal(): (dist, alt, name) = mng.getcp() if (dist != "") and (alt != ""): self.slopelist.remove_cp(num, editcp) self.slopelist.add_cp(num, float(dist), float(alt), name) page = self.notebook.get_page(num) self.tabupdate(num, '*') else: glal.gui.managecperr(self.mygui) mng.destroy() def delete_cp(self, event=None): """Delete a check point to current slope.""" num = self.notebook.getselpagnum() page = self.notebook.get_page(num) rm_cps = page.get_sel_multi_row() #remove selected cps starting from the end #to not affect row number of non removed items rm_cps.reverse() for i in rm_cps: self.slopelist.remove_cp(num, i) self.tabupdate(num, '*') def info(self, event=None): """Show informations on current slope""" num = self.notebook.getselpagnum() #need to call calc to have the correct value of average and max gradient myslope = self.slopelist.get_slope_copy(num) myslope.calc() slopedata = {'name' : self.slopelist.get_name(num), 'state' : self.slopelist.get_state(num), 'author' : self.slopelist.get_author(num), 'email' : self.slopelist.get_email(num), 'comment' : self.slopelist.get_comment(num), 'average_grad' : "%.1f" % self.slopelist.get_average_grad(num)+' %', 'max_grad' :"%.1f" % self.slopelist.get_max_grad(num)+' %', 'height_difference' : str(self.slopelist.get_height_difference(num)) + ' m', 'height_gain' : str(self.slopelist.get_height_gain(num)) + ' m'} dlg = glal.gui.formslopeinfo(self.mygui, slopedata) if not dlg: return self.slopelist.set_name(num, dlg['name']) self.slopelist.set_country(num, dlg['state']) self.slopelist.set_author(num, dlg['author']) self.slopelist.set_email(num, dlg['email']) self.slopelist.set_comment(num, dlg['comment']) self.tabupdate(num, '*') ### Functions activated in response to Messages by the GUI ### def slope_add(self, pagenumber, row_num): """Callback from a SLOPE ADD message""" page = self.notebook.get_page(pagenumber) if page == None: return myslope = self.slopelist.get_slope_copy(pagenumber) page.insert_row(row_num, myslope.cps[row_num]) def slope_del(self, pagenumber, row_num): """Callback from a SLOPE DEL message""" page = self.notebook.get_page(pagenumber) if page == None: return page.delete_row(row_num) ### Functions related to Map ### def save_map_image(mapwindow): """ Save map to an image""" formats = [("Portable Network Graphics (*.png)", "*.png"), ("Bitmap (*.bmp)", "*.bmp"), ("Joint Photographic Experts Group (*.jpg)", "*.jpg")] filepath = '' #Control if the right extension is given by user while not filepath.lower().endswith(('.png', '.bmp', '.jpg')): if filepath: filepath += '.png' filepath = glal.FileDialog(None, _("Save map"), filepath, "", formats, glal.FD_SAVE) if not filepath: return mapwindow.saveimage(filepath) ### Functions related to Plot ### def export_as_image(imgslope, settings): """ Save a plot to an image""" formats = [("Portable Network Graphics (*.png)", "*.png"), ("Bitmap (*.bmp)", "*.bmp"), ("Joint Photographic Experts Group (*.jpg)", "*.jpg"), ("Scalable Vector Graphics (*.svg)", "*.svg")] filepath = '' #Control if the right extension is given by user while not filepath.lower().endswith(('.png', '.bmp', '.jpg', '.svg')): if filepath: filepath += '.png' filepath = glal.FileDialog(None, _("Save plot"), filepath, "", formats, glal.FD_SAVE) if not filepath: return format = filepath.rsplit('.', 1)[1] if format.lower() == 'svg': image = glal.Image_svg(settings['width'], settings['height'], imgslope.paint) else: image = glal.Image(settings['width'], settings['height'], imgslope.paint) image.plot(settings) image.savetofile(filepath, format) def save_pdf(imgslope, settings): """ Save a pdf from current plot""" formats = [("Portable Document Format (*.pdf)", "*.pdf")] filepath = '' #Check if the right extension is given by user while not filepath.lower().endswith('.pdf'): if filepath: filepath += '.pdf' filepath = glal.FileDialog(None, _("Save plot to pdf"), filepath, "", formats, glal.FD_SAVE) if not filepath: return pdf = glal.Pdf(filepath) pdfconfig = settings.copy() pdfconfig['sinfo'] = False pdf.plot_image(pdfconfig, 793, 600,#settings['width'], settings['height'],) imgslope.paint) pdf.addtitle(_("Slope")) pdf.addtext(_("Name")+": "+ imgslope.name) pdf.addtext(_("Country")+": "+ imgslope.country) pdf.addtext(_("Average gradient")+": "+"%.1f" % imgslope.average_grad+" %") pdf.addtext(_("Max gradient")+": "+"%.1f" % imgslope.max_grad+" %") pdf.addtext(_("Height difference")+": "+str(imgslope.height_difference)+" m") pdf.addtext(_("Height gain")+": "+str(imgslope.height_gain)+" m") pdf.addtitle(_("Author")) pdf.addtext(_("Name")+": "+ imgslope.author) pdf.addtext(_("E-mail")+": "+ imgslope.email) #TODO:use correct indentation to include notes on the pdf output #pdf.addtitle(_("Note")) #pdf.addtext(imgslope.comment) pdf.save() def save_html(imgslope, settings): """ Save an html from current plot""" formats = [("HyperText Markup Language (*.html)", "*.html")] filepath = '' #Check if the right extension is given by user while not filepath.lower().endswith('.html'): if filepath: filepath += '.html' filepath = glal.FileDialog(None, _("Save plot to html"), filepath, "", formats, glal.FD_SAVE) if not filepath: return image = glal.Image_svg(settings['width'], settings['height'] , imgslope.paint) image.plot(settings) reportpage = report_html.Report_html(imgslope.name) reportpage.add_image(image.svg) if len(imgslope.coords) != 0: reportpage.add_map(imgslope, settings['width'], settings['height']) reportpage.addtitle(_("Slope")) reportpage.addtext(_("Name")+": ", imgslope.name) reportpage.addtext(_("Country")+": ", imgslope.country) reportpage.addtext(_("Average gradient")+": ","%.1f" % imgslope.average_grad+" %") reportpage.addtext(_("Max gradient")+": ","%.1f" % imgslope.max_grad+" %") reportpage.addtext(_("Height difference")+": ", str(imgslope.height_difference)+" m") reportpage.addtext(_("Height gain")+": ", str(imgslope.height_gain)+" m") reportpage.addtitle(_("Author")) reportpage.addtext(_("Name")+": ", imgslope.author) reportpage.addtext(_("E-mail")+": ", imgslope.email) if imgslope.comment != '': reportpage.addtitle(_("Note")+": ") reportpage.addnote(imgslope.comment) reportpage.save(filepath) def get_config_file_path(): config_path = os.path.expanduser(os.path.normpath('~/.config/CycloGraph')) if os.environ.has_key('XDG_CONFIG_HOME') and os.path.isabs(os.environ['XDG_CONFIG_HOME']): config_path = os.environ['XDG_CONFIG_HOME'] + os.path.normpath('/CycloGraph') config_file = config_path +os.path.normpath('/CycloGraph.conf') #Create a directory if needed if not os.path.exists(config_path): os.makedirs(config_path) #migrate old configuration file if there is any old_file = os.path.expanduser(os.path.normpath('~/.cyclograph.cfg')) if os.path.exists(old_file): os.rename(old_file, config_file) return config_file def getconfig(config): """ Return current settings from config""" settings = { 'olines': config.getboolean("global", "orizzontal lines"), 'theme' : config.get("global", "theme"), 'sinfo' : config.getboolean("global", "slopeinfo"), '3d' : config.getboolean("global", "effect-3d"), 'vcheck' : config.getboolean("global", "latestVersionCheck"), 'fdesc' : { "des" : config.get("font", "font-des 1"), "typ" : config.get("font", "font-typ 1"), "dim" : config.getint("font", "font-dim 1") }, 'ftitle': { "des" : config.get("font", "font-des t"), "typ" : config.get("font", "font-typ t"), "dim" : config.getint("font", "font-dim t") }, 'fgrad' : { "des" : config.get("font", "font-des g"), "typ" : config.get("font", "font-typ g"), "dim" : config.getint("font", "font-dim g") }, 'width' : config.getint("resolution", "width"), 'height': config.getint("resolution", "height"), 'themelist': ThemeManager().getthemeslist(), 'serv' : config.get("kml", "server"), 'aname' : unicode(config.get("global", "authorname")), 'amail' : unicode(config.get("global", "authormail")), 'colors':[ unicode(config.get("colors", "color "+str(i))) for i in range(1, 8) ], 'levels':[ config.getfloat("levels", "level "+str(i)) for i in range(1, 8) ] } return settings ######################################################## def usage(): """ Print usage on standard error""" sys.stderr.write( "usage: %s {-q|-g|-G|-f}\n"% sys.argv[0]) sys.stderr.write("\t--qt --gtk --gtk3 or --file=*.cgx file for cli\n") def opt_parser(argv): """ Parse console input""" domain = gettext.textdomain(None) gettext.textdomain("help") parser = OptionParser(usage=( """usage: %s {-q|-g|-G|-f} filename\t--qt --gtk --gtk3 or --file=FILENAME for cli""" % argv[0]), version="%prog "+VERSION) #parser = OptionParser(version="%prog "+VERSION) parser.set_defaults(filename="") parser.set_defaults(gui="cli") parser.add_option("-g", "--gtk", help="gtk graphical user interface", action="store_const", dest="gui", const="gtk") parser.add_option("-G", "--gtk3", help="gtk3 graphical user interface", action="store_const", dest="gui", const="gtk3") parser.add_option("-q", "--qt", help="qt graphical user interface", action="store_const", dest="gui", const="qt") parser.add_option("-f", "--file", dest="filename", help="open cgx, csv, gpx, tcx, sal, crp or cyclomaniac file", metavar="FILE") parser.add_option("-l", "--list", dest="_list", action="store_true", help="list available themes and exit") parser.add_option("-t", "--theme", help="use selected theme", action="store", type="string", dest="theme") parser.add_option("-e", "--extension", dest="extension", default="", help="choose default file format extension", metavar="EXT") (options, args) = parser.parse_args(argv) if options._list: #print("available themes are:") # User asked for the available themes, so telling him is quite useless # also is less machine readable: silence is golden. for theme in ThemeManager().getthemeslist(): print(theme) sys.exit(0) if options.theme and \ options.theme not in ThemeManager().getthemeslist(): parser.error('there is no theme named "%s"' % options.theme) parser.destroy() gettext.textdomain(domain) return options ######################################################## def main_qt(): """Main application for qt interface""" app = glal.initapp(sys.argv) arg = [unicode(s) for s in app.arguments()] options = opt_parser(arg) # WARNING: The return value of CycloGraph MUST be stored in a variable #otherwise the application could segfault. controller = Cyclograph() if options.filename: controller.open_slope(filepath=options.filename) sys.exit(app.exec_()) def main_gtk(): """Main application for gtk interface""" controller = Cyclograph() options = opt_parser(sys.argv) if options.filename: controller.open_slope(filepath=options.filename) glal.initapp() def main_gtk3(): """Main application for gtk3 interface""" controller = Cyclograph() options = opt_parser(sys.argv) if options.filename: controller.open_slope(filepath=options.filename) glal.initapp() def main_cli(): """Main application for cli interface""" slopelist = slope.SlopeList() slope_num = slopelist.new_slope() opt = opt_parser(sys.argv) filein = opt.filename if filein == "-": filein = sys.stdin success = iofile.open_file(filein, slopelist, slope_num, opt.extension) if not success: print(('Unable to open "%s"' % filein), file=sys.stderr) return False devc = glal.DeviceContext() myslope = slopelist.get_slope_copy(slope_num) myslope.calc() config = ConfigParser.SafeConfigParser(DEFAULT_CONF) config.read(get_config_file_path()) for sec in SECTIONS: if not config.has_section(sec): config.add_section(sec) settings = getconfig(config) if opt.theme: settings['theme'] = opt.theme #FIXME: this should work also with GUIs devc.init_draw_surf((settings['width'], settings['height']), settings['3d']) myslope.paint(settings, devc) devc.end_draw() #img.savetofile(filecsv[:-4]+".svg") # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/glal.py0000644000175000017500000002331212065361217020664 0ustar federicofederico00000000000000# -*- coding: utf-8 -*- #glal.py """This module provides a graphic library abstraction layer for Cyclograph""" # Copyright (C) 2008, 2009, 2010, 2011, 2012 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from __future__ import print_function, unicode_literals import sys import os.path import glal_selected LIBRARY = glal_selected.library (FD_OPEN, FD_SAVE) = range(2) def Message(*args): """This funcion return the class that wraps the using messaging library""" if LIBRARY == 'cli': return Message_cli(*args) def DeviceContext(*args): if LIBRARY == 'cli': return DeviceContext_cli(*args) def Image(*args): if LIBRARY == 'cli': return Image_cli(*args) def addstatusbartext(maingui, text): """Add text to main gui status bar""" if LIBRARY == 'cli': sys.stderr.write(text) def FileDialog(parent, title, dirname, other, file_types, rw, filename=None): """Return File dialog """ return gui.FileDialog(parent, title, dirname, filename, other, file_types, rw, FD_OPEN, FD_SAVE) ### Begin of cli classes ### class Message_cli(): """CLI interfaces doesn't need to update their view because they haven't got any """ def send(self, *args): """ send method not used for cli""" pass def subscribe(self, *args): """ subscribe method not used for cli""" pass def DeviceContext_cli(*args): """ Get a device contex for CLI default is an svg generator.""" return DeviceContext_svg(*args) class Image_cli(): """ Image cli not used""" pass ### End of cli classes ### ### Begin of SVG ### class DeviceContext_svg(): """Device Context class to draw sgv files""" colors = {'white' : '#ffffff', 'black' : '#000000'} def setcolor(self, color): """ Set color converting to svg compatible format.""" if type(color) == type(unicode()): if color.startswith('#'): return color elif color.startswith('rgb'): tuple_ = map(int, color[4:-1].split(',')) return tupletocss(tuple_) else: return self.colors[color] else: sys.stderr.write("Color type unknown: "+color+" "+str(type(color))+"\n") return False def init_draw_surf(self, size, p3d): """ Init draw surface""" self.size_x = size[0] self.size_y = size[1] self.pencolor = None self.lineargcount = 0 self.pensize = 0 self.svg = ''' \n ''' % size if p3d: self.brushcolor = '#ffffff' #white background self.svg += ''' ''' % ( self.size_x, self.size_y, self.brushcolor) def shear(self, shear): self.shear = shear if shear: self.svg += '' % (shear*50,) def getsize(self): """ Return size""" return (self.size_x, self.size_y) def gradfill(self, rect, startcolor, endcolor): """ Fill gradient""" self.svg += ''' ''' % (self.setcolor(startcolor), self.setcolor(endcolor), rect[2] - rect[0], rect[3] - rect[1]) def setpen(self, color, size): """ Set pen's size and color""" self.pencolor = self.setcolor(color) self.pensize = str(size) def setfont(self, fontdict): """ Set font""" self.dim = fontdict['dim'] self.font = "font-family:%s;font-size:%spx" % (fontdict['des'], self.dim) def drawtext(self, text, pos_x, pos_y): """ Draw text at position pos_x,pos_y """ self.drawrotatedtext(text, pos_x, pos_y, 0) def gettextwidth(self, text): """ Return text length""" return self.dim*len(text)-30#TODO: check if there is a more accurate method def gettextheight(self, text): """ Return text height""" return self.dim #TODO: check if there is a more accurate method def drawline(self, pos_x0, pos_y0, pos_x1, pos_y1): """ draw line""" self.svg += ''' ''' % (pos_x0, pos_y0, pos_x1, pos_y1, self.pencolor, self.pensize) def setlineargradientbrush(self, colorlist, startp, endp): """ Get a linear gradient from startp to endp, using colors in colorlist. The elments of colorlist are tuple in the format (color, realtive position).""" self.svg += ''' ''' % (self.lineargcount, startp[0], startp[1], endp[0], endp[1]) for color in colorlist: self.svg += ''' ''' % (color[1]*100, self.setcolor(color[0])) self.svg += ''' ''' self.brushcolor = "url(#linearg%s)" % (self.lineargcount) self.lineargcount = self.lineargcount + 1 def setbrush(self, color): """ Set brush color""" self.brushcolor = self.setcolor(color) def drawrectangle(self, pos_x0, pos_y0, width, height): """ Draw rectangle""" self.svg += ''' ''' % (pos_x0, pos_y0, width, height, self.brushcolor, self.pencolor, self.pensize) def drawrotatedtext(self, text, pos_x, pos_y, angle): """Draw the text given, rotated by the angle.""" dy = self.dim self.svg += '%s ''' % (text) def drawpolygon(self, sequence): """ Draw polygon""" if len(sequence) < 2: return self.svg += '\n' \ % (self.brushcolor, self.pencolor, self.pensize) def startpath(self, point): """ Start a path in the specified point,""" self.svg += '''= 0x040500: self.notebook.setTabsClosable(True) QtCore.QObject.connect(self.notebook, QtCore.SIGNAL("tabCloseRequested(int)"), fun_close) def Page(self): """ Return qt Page""" return gui.Page(self.notebook) def set_page_label(self, page_num, text): """ Set page label text""" self.notebook.setTabText(page_num, text) def add_page(self, page, title): """ Add page""" self.notebook.addTab(page, title) if QtCore.PYQT_VERSION < 0x040500: QtCore.QObject.connect(page.button_close, QtCore.SIGNAL("clicked()"), self.fun_close) else: page.button_close.setVisible(False) self.notebook.setCurrentWidget(page) def remove_page(self, page_num): """ Remove page""" self.notebook.removeTab(page_num) def getselpagnum(self): """ Return number from selected page""" return self.notebook.currentIndex() def setselpagnum(self, page_num): """Set current selected page""" self.notebook.setCurrentWidget(self.get_page(page_num)) def get_page(self, page_num): """ Return page""" page = self.notebook.widget(page_num) return page def get_pagenum(self, argument): """Return page_num from page passed as argument""" return argument[0] class DeviceContext(): """Device Context Qt class wrapper""" def _convqcolor(self, color): """ Convert color""" if isinstance(color, basestring): if color.startswith("rgb"): col = map(int, color[4:-1].split(',')) return QtGui.QColor(*col) else: return QtGui.QColor(color) else: return QtGui.QColor(*color) def init_draw_surf(self, panel): """ Initialize drawing surface""" (self.size_x, self.size_y) = (panel.width(), panel.height()) self.paint = QtGui.QPainter() self.paint.begin(panel) self.paint.setRenderHint(QtGui.QPainter.SmoothPixmapTransform) self.paint.setRenderHint(QtGui.QPainter.Antialiasing) def shear(self, shear): """ device shear""" self.paint.shear(0.0, shear) def getsize(self): """ Return size""" return (self.size_x, self.size_y) def gradfill(self, rect, startcolor, endcolor): """ Fill gradient""" (sx, sy, ex, ey) = (rect[0], rect[1], rect[0], rect[1]+rect[3]) gradient = QtGui.QLinearGradient(sx, sy, ex, ey) sqcol = self._convqcolor(startcolor) gradient.setColorAt(0, sqcol) eqcol = self._convqcolor(endcolor) gradient.setColorAt(1, eqcol) brush = QtGui.QBrush(gradient) self.paint.fillRect(QtCore.QRect(*rect), brush) def setpen(self, color, size): """ Set pen's color and size""" qcol = self._convqcolor(color) pen = QtGui.QPen(qcol) pen.setWidth(size) self.paint.setPen(pen) def setfont(self, fontdict): """ Set font to use""" font = QtGui.QFont() self.fontmetrics = QtGui.QFontMetrics(font) try: font.setFamily(fontdict["des"]) font.setPointSize(fontdict["dim"]) font.setWeight(eval('QtGui.QFont.'+fontdict["typ"].capitalize())) self.paint.setFont(font) except Exception: pass def drawtext(self, text, pos_x, pos_y): """ Draw text at position x,y""" self.paint.drawText(pos_x, pos_y+10, text) def gettextwidth(self, text): """ Return text length""" return self.fontmetrics.width(text) def gettextheight(self, text): """ Return text height""" return self.fontmetrics.height() def drawline(self, pos_x0, pos_y0, pos_x1, pos_y1): """ Draw line""" self.paint.drawLine(pos_x0, pos_y0, pos_x1, pos_y1) def setlineargradientbrush(self, colorlist, startp, endp): """ Get a linear gradient from startp to endp, using colors in colorlist. The elments of colorlist are tuple in the format (color, realtive position).""" grad = QtGui.QLinearGradient(startp[0], startp[1], endp[0], endp[1]) for color in colorlist: grad.setColorAt(color[1], self._convqcolor(color[0])) brush = QtGui.QBrush(grad) self.paint.setBrush(brush) def setbrush(self, color): """ Set brush's color""" qcol = self._convqcolor(color) brush = QtGui.QBrush(qcol) self.paint.setBrush(brush) def drawrectangle(self, pos_x0, pos_y0, width, height): """ Draw rectangle""" self.paint.drawRect(pos_x0, pos_y0, width, height) def drawrotatedtext(self, text, pos_x, pos_y, angle): """ Draw rotated text at position x,y by angle""" self.paint.save() self.paint.rotate(-angle) transform = QtGui.QTransform() transform.rotate(angle) (newx, newy) = transform.map(pos_x+10, pos_y-5) self.paint.drawText(newx, newy, text) self.paint.restore() def drawpolygon(self, sequence): """ Draw polygon""" points = [QtCore.QPoint(*p) for p in sequence] self.paint.drawPolygon(*points) def startpath(self, point): """ Start a path in the specified point,""" point = QtCore.QPointF(*point) path = QtGui.QPainterPath() path.moveTo(point) return path def drawpathlineto(self, path, point): """ Draw a straight line from the last point to the given point.""" point = QtCore.QPointF(*point) path.lineTo(point) def drawpathcubicto(self, path, controlpoints): """ Draw a cubic Beziér frome the last point using the given list of three control points.""" points = [QtCore.QPointF(pnt[0], pnt[1]) for pnt in controlpoints] path.cubicTo(*points) def endpath(self, path): """ Show the path.""" self.paint.drawPath(path) def end_draw(self): """ Finish drawing""" self.paint.end() del self.paint class Image(): """Image Qt class wrapper""" def __init__(self, size_x, size_y, plotfnct): (self.size_x, self.size_y) = (size_x, size_y) self.plotfnct = plotfnct self.image = QtGui.QPixmap(size_x, size_y) self.image.fill() #white backgound def plot(self, settings): """ Draw slope to the device context""" dcwrpp = DeviceContext() (dcwrpp.size_x, dcwrpp.size_y) = (self.size_x, self.size_y) dcwrpp.paint = QtGui.QPainter() dcwrpp.paint.begin(self.image) dcwrpp.paint.setRenderHint(QtGui.QPainter.SmoothPixmapTransform) dcwrpp.paint.setRenderHint(QtGui.QPainter.Antialiasing) self.plotfnct(settings, dcwrpp) dcwrpp.end_draw() def savetofile(self, path, format): """ Save image to file""" self.image.save(path, format) class Pdf(): """Qt pdf class wrapper""" def __init__(self, filepath): self.dy = 90 self.dx = 300 self.y_incr = 30 self.printer = QtGui.QPrinter(QtGui.QPrinter.ScreenResolution) self.printer.setOutputFormat(QtGui.QPrinter.PdfFormat) self.printer.setOutputFileName(filepath) self.printer.setFullPage(True) # paperSize = QtCore.QSizeF(793, 1122) # self.printer.setPaperSize(paperSize, QtGui.QPrinter.Millimeter) self.printer.setCreator('Cyclograph {0}'.format(VERSION)) self.painter = QtGui.QPainter() self.painter.begin(self.printer) self.painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform) self.painter.setRenderHint(QtGui.QPainter.Antialiasing) self.painter.setFont(QtGui.QFont('Decorative', 18)) def plot_image(self, settings, size_x, size_y, plotfnct): """ Draw slope to pdf""" image = QtGui.QPicture() dcwrpp = DeviceContext() (dcwrpp.size_x, dcwrpp.size_y) = (size_x, size_y) dcwrpp.paint = QtGui.QPainter() dcwrpp.paint.begin(image) dcwrpp.paint.setRenderHint(QtGui.QPainter.SmoothPixmapTransform) dcwrpp.paint.setRenderHint(QtGui.QPainter.Antialiasing) plotfnct(settings, dcwrpp) dcwrpp.end_draw() self.painter.drawPicture(0, 0, image) self.dy += size_y def addtext(self, text): self.dy += self.y_incr self.painter.setPen(QtGui.QColor(0, 0, 0)) self.painter.drawText(self.dx, self.dy, text) def addtitle(self, text): self.dy += self.y_incr self.painter.setPen(QtGui.QColor(0, 0, 102)) self.painter.drawText(self.dx-50, self.dy, text+":") def save(self): """Save pdf""" self.painter.end() class ProgressDialog(): """ Progress dialog for importkml""" def __init__(self): self.pd = QtGui.QProgressDialog (_("Downloading altitudes"), _("Cancel"),0,1000) def update(self, value): """Update the progress shown and return if user want to abort.""" self.pd.setValue(value) return self.pd.wasCanceled() def destroy(self): """ Destroy progress dialog""" self.pd = None class Timer(): """ Timer for Qt gui""" def __init__(self, period, callback): self.timer = self.timer = QtCore.QTimer() self.period = period self.timer.connect(self.timer, QtCore.SIGNAL("timeout()"), callback) def start(self): """ Start timer count""" self.timer.start(self.period) def stop(self): """ Stop timer count""" self.timer.stop() # vim:sw=4:softtabstop=4:expandtab ��������������������������������������������cyclograph-1.6.1/cyclograph/qt/cyclograph_rc.py�����������������������������������������������������0000644�0001750�0001750�00000651273�12222637240�023222� 0����������������������������������������������������������������������������������������������������ustar �federico������������������������federico������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # Resource object code # # Created: Thu Sep 19 20:06:07 2013 # by: The Resource Compiler for PyQt (Qt v4.8.5) # # WARNING! All changes made in this file will be lost! from PyQt4 import QtCore qt_resource_data = "\ \x00\x00\x59\x52\ \x00\ \x01\x3f\x35\x78\x9c\xcd\x3d\x09\x78\x1b\xc5\xd5\x23\x5b\x92\x65\ \xf9\x4a\x8c\x09\x21\x09\x61\x09\x58\x76\x0e\x1c\x72\x71\x98\x10\ \xf0\x11\x27\x26\x76\x62\x5b\x76\x12\xc2\xb9\x96\xd6\xf6\x12\x49\ \x2b\x56\x2b\x3b\x06\x4a\x0b\x14\x68\x4b\xa0\xd0\xd2\x02\x85\x42\ \xe9\x5f\x4a\x5b\x68\xe9\xc1\x55\xee\x02\x2d\x77\x0f\x4a\x0b\xe5\ \x2e\xd0\x42\x81\x9e\x94\x9b\xd2\xff\xcd\xb1\xbb\xb3\xbb\xb3\x92\ \x9c\x84\xb6\xf8\x23\x63\x4b\x33\x6f\xde\xcc\xbc\x79\xf3\xde\x9b\ \xf7\xde\xac\xbc\x25\x39\xf3\xa1\xbf\x5e\xfe\xa5\x47\xf7\x99\x73\ \xd7\x09\x57\xdd\xf1\x6c\x3b\x42\xb3\x8f\x40\x08\x2d\x40\x81\xe0\ \xb3\x50\x2e\x44\xe8\xe9\x1e\x84\x82\xf0\xd9\x6d\x17\x42\xd9\x06\ \xe5\x0d\x50\x42\xbd\xdb\x9e\x80\xb2\x03\xca\xf7\xa1\xec\x44\xe8\ \xf6\xbd\xa0\x5c\x0d\x25\xd4\x0d\x76\x41\x99\x80\x72\x0d\x94\x67\ \x43\xb9\x16\xca\x6f\x43\xd9\x0d\xe5\x23\x50\xf6\x21\x74\xc7\xfe\ \x50\xf6\x43\x09\xbf\x07\x07\xa0\xbc\x18\xca\x38\x94\xb7\x42\x39\ \x08\x25\xf4\x1f\x1c\x42\xe8\x4e\x40\x23\xb8\x11\xca\x7d\xa1\xdc\ \x04\x25\xc0\x0e\x6e\x86\x52\x85\xf2\x28\x28\xb7\x43\x79\x2c\x42\ \x07\x8e\x23\x14\x3a\x14\xa1\x3d\xbf\x40\xcb\x43\xcb\x69\x79\xf1\ \x05\x50\xf6\xc2\xf7\x5f\x81\x72\x03\x42\x2f\x7c\x8b\x96\xaf\xfd\ \x1d\xca\xbb\x11\xfa\xc3\x15\x08\x85\x3f\x01\xdf\x43\x47\x15\x69\ \x28\x5f\x84\xf2\x7a\x84\x1e\x8e\xc2\xf0\xa1\x7d\xf8\x4e\x5a\x1e\ \xbc\x9c\x96\xab\xde\x84\x12\xda\x87\x2f\xa2\xe5\xc1\x61\x84\x96\ \xd4\x42\xfd\x13\x11\x5a\x0d\x63\xbf\x23\x87\x50\xd7\x97\x00\x2f\ \x80\xb1\x16\xda\x3c\xbd\x15\x4a\xc0\xb3\x0f\x3e\x5b\x7b\x3a\x42\ \xcf\x9d\x89\x50\x77\x08\xa1\xbb\x66\x20\x74\xe4\xed\x08\x3d\xab\ \x40\x79\x1f\x42\xff\x82\xba\xeb\xca\x10\xaa\x9a\x8e\x50\x0f\xcc\ \xe7\xb3\x80\x47\xcf\x17\xa1\xfe\xc1\xd0\x16\xe6\xe5\xf9\x57\x10\ \x1a\xf8\x24\x42\x83\x97\x20\xb4\x45\x07\xbc\x01\xe7\xa3\x4f\x00\ \xf8\x73\x48\x19\xd8\x17\xf0\x39\x06\xe6\x6c\xf2\x79\x84\x8e\xbf\ \x17\xa1\x3f\x7e\x9e\x96\xaf\x7f\x16\x05\x96\xc0\x9c\x1e\xfe\x47\ \x54\x76\x17\xfc\x5d\xf1\x00\x2d\x0f\x1e\x46\xc1\x73\x2e\x43\xa8\ \xb2\x85\x96\xab\x5f\xa3\xe5\xd3\xdb\x51\xf0\xcb\xfb\x21\xd4\x7f\ \x05\x2d\x3f\x88\xa1\xe0\x25\x8b\xe0\xf3\x3b\x51\xf0\x9b\x93\x08\ \x7d\x78\x2a\x0a\x5e\xf3\x38\x42\xb3\xae\xa7\xe5\xe9\xbf\xa2\xe5\ \x5b\x15\x28\xf8\xad\xab\x11\x8a\x6e\x46\xc1\x6b\x61\x4d\x9e\xed\ \x40\xc1\xeb\x0e\x01\x9c\xeb\x51\xf0\x46\x80\xbb\x6a\x29\x0a\xde\ \x04\xf4\x71\xd0\x15\xa4\x0c\x84\xcf\x82\xf2\x39\xa8\x77\x2b\x0a\ \xfe\xb2\x11\xc6\xfd\x37\x5a\xae\x79\x05\x05\x7f\x7b\x1e\x42\x3f\ \xfd\x32\x2d\xef\xbf\x8e\x96\x0f\x5f\x84\x82\x6f\x1c\x00\xeb\x9b\ \xa4\x65\xeb\x20\x2d\xcf\xff\x1e\x2d\x2f\xae\xa2\xe5\xf3\x3d\xa4\ \x0c\x84\xdf\x40\xc1\xb7\x57\xc0\xdf\xdb\x50\x48\x82\xf9\x3c\xac\ \x9b\x96\x1b\x54\x14\x5a\x08\xf8\xbe\xb0\x14\x85\x16\xfd\x1f\xe0\ \x75\x31\x2d\xff\xb4\x2f\x0a\xad\x04\x7a\xfb\xfc\xb1\xb4\x7c\x21\ \x09\xe5\x55\x50\x9e\x8d\x42\x5d\x67\x41\xbd\x9f\xd1\xf2\x4f\x3d\ \x28\xb4\x16\xe0\xd6\x5c\x4f\xcb\xc3\x26\x68\xb9\xe1\x6d\x5a\xde\ \xf0\x73\x14\xda\x08\xe3\x7c\xe0\x14\x14\x1a\x01\xda\xa9\xdb\x8d\ \x96\x2d\x07\xd3\xf2\xd0\x05\xb4\x3c\x72\x3e\x2d\x2f\x8c\xd0\xf2\ \xd1\x34\x2d\xdf\xba\x05\x85\x46\x7f\x03\xe3\xff\x15\x0a\xa5\x80\ \x3e\x5f\xfc\x24\x0a\x9d\x0b\xb4\xf4\xf6\x57\x69\xf9\xce\x62\x14\ \xda\x1e\x44\x81\x8a\x19\x28\x74\xc9\x4f\x11\x5a\x79\x04\x0a\x5d\ \x05\xf4\x34\xed\xf7\xb4\x3c\xec\x2a\x5a\xf6\x35\xa1\xd0\x37\x81\ \x26\xa6\xcf\x42\xa1\x6b\x81\x4e\x5e\xfe\x13\x29\x03\x65\x30\xce\ \xef\xc1\x3a\x6e\x7a\x14\x85\x7e\x7c\x23\xec\x81\xa5\xb4\x6c\x19\ \x86\xed\x00\xb4\xb8\xdb\x18\x2d\x0f\x7b\x82\x96\x7d\x30\x0f\xf7\ \xe1\xfe\x1f\xa2\xe5\x3b\xc7\xa0\x69\xa7\x01\x2f\xf8\xf3\x65\x68\ \xfa\x71\x50\xbe\xf1\x3e\xaa\xbf\xf0\x1f\x08\x9d\xf9\x06\xda\xfd\ \x8a\x7e\x14\x98\x33\x84\x9a\x97\xff\x10\x68\xf9\x45\x28\xe1\xf3\ \x9e\x19\xa8\x79\x45\x3d\x94\x47\x42\x79\x06\x94\xa7\xa1\x05\x98\ \x8e\xf6\xbc\x81\x96\xa7\x57\xd3\xf2\xcd\xbb\xd1\x82\xdf\xc2\xbe\ \xdf\xfc\x0b\xb4\x00\xaf\x63\xe3\x57\x48\x19\x08\x35\xa1\x85\x5d\ \x30\xce\xf3\xbe\x44\xca\x40\xc5\xb5\x68\x61\xcf\x3f\xe1\xf3\x41\ \xb4\x10\xcf\x57\xf8\x55\x5a\x76\xdc\x82\x16\x9e\x7b\x32\x42\x8b\ \xd6\x43\x09\x78\xce\xda\x93\x96\xa7\x6b\xb4\xfc\xe7\x7c\xb4\xf0\ \x12\xfc\xfd\x19\x50\x02\xbc\x8a\x01\x5a\x76\x4a\x68\x21\x9e\xaf\ \xa3\x22\xb4\x3c\x3f\x4a\xca\x40\x64\x16\x5a\x88\xc7\x3b\xab\x9b\ \x96\xa7\x5f\x41\xcb\x7f\x1e\x8d\x16\xde\x0f\x3c\x6f\xd1\x0f\xd1\ \x9a\x2f\xc3\xfc\x1e\x7c\x21\x5a\x3b\x01\x74\x3e\xf3\x2e\x5a\x1e\ \xfc\x0b\xd4\xdd\x04\xf4\xde\xaf\xa1\xee\xd7\xa1\x5c\x30\x44\xcb\ \x47\x2f\x45\x47\x2e\x84\xf1\xcf\xfa\x04\x3a\xf2\x40\xe0\x05\xb3\ \x9b\x68\xb9\xff\x33\xb4\x3c\xe4\x08\x5a\xae\x0a\xd0\xf2\xfc\x53\ \x68\x79\xc1\xf7\x69\x79\xcf\x41\xa4\x0c\x44\xce\x45\x47\x26\x86\ \x11\xfa\xd9\x7a\xb4\xae\x7f\x77\x84\xfe\x3d\x81\xd6\x5d\x00\xe3\ \x58\x73\x0b\xea\xd9\x72\x0f\xf0\x8b\x2a\xd4\x73\x26\xd4\x0f\x3e\ \x4c\xcb\x16\xf8\xfb\x52\xa8\x5f\x75\x27\xea\x5d\xf1\x69\x80\x3f\ \x82\x7a\x95\x1f\x01\xbf\x79\x0c\xf5\x9e\x09\x7c\x20\x80\xd0\xfa\ \x73\x6f\x83\x7d\xfa\x0a\xda\x70\xea\xe7\x00\x9f\xe3\x51\x5f\x17\ \xd0\xef\x5e\x27\xd3\xf2\xf3\x0f\x91\x32\x50\xb9\x02\xf5\xbf\x09\ \xf0\x07\x0f\x45\x03\x9f\xfb\x08\xca\x3b\xd0\xc0\xbf\xfe\x09\xe5\ \xdf\xd0\xe0\x83\xc0\x13\x03\x2d\x68\xf0\xa1\x1b\x50\x60\xef\x59\ \x68\xf0\x8f\xbf\x42\x68\x77\x03\x0d\x5d\x7f\x2a\xec\xf7\x30\x1a\ \x7a\x0e\x78\xd5\xd0\x1f\xd1\xc6\x25\xc0\xef\x1e\xbc\x0c\x6d\xfc\ \xdc\xd5\xd0\x6d\x02\x6d\xdc\x0e\xf8\xbd\x38\x0f\x6d\xbc\x00\x78\ \xf1\xc6\x1a\xb4\x69\x3b\xec\xc3\xb7\x5e\x46\x9b\x2e\x00\x3a\xb8\ \xf7\x77\xb4\x7c\xf1\x5a\xb4\xf9\x41\xe0\x8f\x87\x1e\x4d\xca\x40\ \xa0\x1e\x6d\x7e\xf8\x52\xa0\xfb\x08\xda\x8c\xfb\x7f\xe9\x74\x74\ \xd4\x7d\xd0\xff\xc6\xe5\xe8\xa8\xbf\xc2\xbe\x7e\xf9\x5c\x74\xd4\ \xdb\xc0\xf3\xd7\xcd\x44\x5b\x46\x01\xfe\xcb\xb7\xa2\x2d\x67\x7e\ \x08\xf4\xbe\x11\x1d\x13\x86\xf1\x3d\x1a\x42\xc7\x1c\x0b\xbc\xf6\ \xb2\x1f\xd0\xf2\x95\xa7\xd1\x31\x67\x02\xfd\xdf\xf0\x6f\x74\xcc\ \xfb\x77\xc1\x38\x2e\x41\xa9\x35\x3f\x46\x81\xbd\x9e\x41\xa7\x06\ \x8f\x43\xe8\xca\x11\xf4\xe9\x71\xe0\xa5\x07\x3d\x46\xca\x40\xf0\ \x6b\xe8\xac\x3f\xc1\xbc\x49\x37\xa1\x73\x47\x80\x57\x9f\xb0\x19\ \x9d\xbf\x1c\xce\xc8\x5b\x9f\x44\xe7\xaf\xf8\x1e\x9c\x87\xb3\xd0\ \xf9\x2f\xb5\xc0\x3e\x78\x0c\x5d\x70\x20\x9c\x8f\xfd\xbf\x45\x97\ \x74\xc3\xb9\x39\xe3\x48\x74\xf5\xd1\x30\xef\x87\x5e\x8a\xbe\x75\ \x39\xb4\xdb\xed\x19\xf4\xe0\x8d\x19\x38\x3b\xbe\x46\xcb\x6c\x8e\ \x96\x67\xff\x9e\x96\xd7\x6e\xa5\xe5\x2f\x07\x69\xf9\x78\x08\x3d\ \x3c\x1b\xc6\x17\xbb\x84\x96\x89\x11\xf4\xcb\x2a\x38\x87\xbf\xf2\ \x3c\x7a\xe9\x7c\xe0\xa3\x2f\x3e\x89\x5e\xeb\x05\x3e\x7f\xcb\x81\ \xe8\x9d\x87\xdf\x43\x68\x64\x49\x60\xee\x13\xc0\x8f\xbe\x72\x4a\ \xa0\x71\x08\xe6\xf1\xab\x27\x04\x9a\x7f\x7a\x3e\xec\xbf\x3f\x07\ \x16\xbc\x0c\xe3\xfe\xee\x9b\x81\xc3\x1b\x0c\x84\x46\xf7\x0c\x74\ \x54\x00\xfd\x4c\x7f\x25\xd0\xf1\x73\xd8\xef\xd3\xd7\x05\x3a\xe7\ \xbd\x05\xe5\xa5\x81\xce\x5f\x2f\x41\xe8\xb8\x0b\x03\xbd\x17\x03\ \xbe\x0d\xef\x04\xe4\x81\xc3\x61\xbf\xf4\x07\x46\xfa\x7e\x8f\x50\ \x6d\x2e\x90\x3a\xe7\x1c\x84\x7e\xfb\xa3\x80\x36\x00\x65\x73\x5f\ \x40\xbb\x47\x87\xf5\x79\x2e\x30\x71\x13\xcc\xdb\xc5\x3f\x0c\x9c\ \x7e\x0f\xc8\x00\x2d\xcf\x07\xce\x5a\x03\xeb\x3b\x58\x1f\xf8\xd6\ \xd2\x69\x40\xcf\x1b\x49\x19\xa8\x7c\x3b\xf0\xed\x4f\x36\x20\xf4\ \xde\x29\x81\x1f\x9c\xd2\x04\xe7\xcc\x75\x81\x1b\x6f\x68\x81\x73\ \x6a\x66\xe0\xa6\x81\xe7\x50\x60\xf7\x89\xc0\xcd\x6d\x70\xc6\xbf\ \x9f\x0e\xfc\xe3\x56\xa0\xdb\x49\x2d\xf0\xe6\x74\xf8\xfb\x94\x27\ \x03\x6f\xe6\xe1\xfc\xcb\x7f\x54\x56\xf5\x36\x9c\x91\x57\xbf\x50\ \xb6\xff\xdd\xdf\x40\x48\x5e\x59\xb6\xe4\x49\x38\xaf\x2e\xfd\x73\ \xd9\x8a\x69\xa7\x21\x74\xec\xbc\xb2\x95\x12\xd0\xcd\xc9\xc1\xb2\ \xde\xab\x5e\x02\x7a\xfb\x62\xd9\xb1\xcf\xfe\x09\xc6\x31\xb7\xec\ \x84\xd7\x60\xdf\x2c\xbb\x8a\x96\xdf\xbf\xb7\x6c\xdc\x00\xfe\xb3\ \xf8\x82\xb2\xcf\x2f\xf9\x17\xd0\x69\x63\xd9\xc5\x41\xd8\xdf\xd5\ \x9b\xca\x2e\x3d\x1d\x97\xbb\xd3\x72\x6d\x55\xd9\xd5\x3f\x9c\x8f\ \xd0\xc4\xb7\xca\xbe\x83\xf7\xe3\x79\xc7\x93\x32\x50\xb1\xad\xec\ \x86\xe3\xe0\x9c\x38\xe1\xa5\xb2\x1b\xce\x04\xfa\x7a\xf8\xa0\xb2\ \x9b\x80\xbe\xd1\x9e\x2f\xd3\xf2\xf4\x43\x69\xf9\xe6\x3f\xca\x6e\ \xc6\xf4\x7c\xdb\x31\x65\xb7\x1e\x06\xb2\xd2\x25\xa1\xb2\x5b\xdf\ \x01\xd9\xe3\xa1\x4f\x96\xdd\x7e\x1a\xd0\xcb\x8c\x03\xcb\xee\x3c\ \x03\x64\xab\x37\xf7\x2a\xbb\xf3\xf2\x0f\x80\xae\xbf\x5f\x76\xd7\ \xde\xc0\xd7\x7e\xf7\x25\x52\x06\xf6\xb9\xa3\xec\xae\xd5\x7f\x80\ \xbf\x5f\x21\x65\x60\xde\xde\x65\x77\xe3\xfa\x4f\x35\x92\x32\x30\ \x2f\x5d\x76\xdf\x29\xb0\xbe\x6f\x7f\x50\xf6\xd0\xc1\x40\x6f\xd1\ \xb3\xca\x9e\x9e\x0d\xe5\xf1\x35\x65\x2f\x7f\x03\x36\xf9\xeb\xdf\ \x2e\x7b\xf3\x0c\x98\xa7\xe5\xb3\x69\xf9\xb9\x3c\x2d\xbf\x93\xa3\ \xe5\x0f\x56\xd1\xf2\x57\x9f\xa2\xe5\x6f\x97\x97\xbd\xf5\x24\xc8\ \x43\xe7\xaf\x29\x7b\xeb\x6f\x20\x3f\x9d\x37\x8f\x94\x81\x8a\x55\ \x65\x6f\xaf\x06\xbe\x77\xf4\x35\xb4\x4c\x3e\x5b\x5e\xf9\x28\xc8\ \x75\x3f\x39\xa0\x7c\xfa\x53\x40\x17\x7f\xbf\xb1\x7c\xfe\x6f\xe6\ \x82\x7c\x72\x4f\xf9\x82\xc5\x40\x4f\x7f\x0c\x95\x77\xfd\x00\xf0\ \x3e\xa8\xb1\x7c\xc3\xb5\x20\x27\xdd\xb8\xa2\x7c\xcb\x5b\x23\x80\ \xe7\x6e\xe5\x23\x2f\xc1\x7e\x9e\x39\xb7\xfc\xc4\x08\xec\x93\x9e\ \x1f\x96\x9f\xb4\x37\xe0\xf9\x97\x95\xe5\xf9\x66\xd8\x8f\xcf\x7f\ \xbd\xfc\xf4\x3b\x80\x0e\x37\x8e\x96\x9f\x93\x7a\x10\xd6\x7d\x79\ \xf9\x79\xbf\x3e\x0d\x05\x1a\x0e\x29\xff\xe2\x45\x95\x08\x5d\x77\ \x62\xf9\xb7\x9f\x7f\x0c\xa1\x33\x1e\x2f\xbf\xfe\x41\x58\xf7\x9f\ \x7f\x85\x94\x81\xba\xeb\xca\xbf\x7f\xc6\x8d\x28\x50\xf3\xcb\xf2\ \x1b\x5e\x78\x19\xf8\xda\xc1\xe5\xf7\x36\x7f\x0d\xf0\xe8\x29\xff\ \xd5\x3a\x80\x57\xfe\x79\x52\x06\xf6\x1e\x2c\x7f\x29\x0a\xfb\xea\ \xa6\xe5\xe5\x2f\xbd\x05\xf0\x3f\x3b\x5e\xfe\xf2\x22\xd8\x57\x27\ \x5d\x59\xfe\xfa\x6f\xfe\x8d\xd0\x8f\xbf\x5c\xfe\xf6\xe7\x80\xdf\ \xed\xff\xf9\x20\x7a\x0f\xe6\xf1\x2f\x77\x04\x2b\xae\x80\xfd\xf5\ \x48\x79\xb0\x7b\x1b\xc8\x63\x0b\xde\x09\x1e\xd5\x0b\xe3\x3d\xfa\ \x3d\x5a\x2a\x07\x04\xc7\x4e\x07\xba\x9f\x7b\x42\x50\xfd\xeb\xaf\ \x11\xda\xf7\x97\xc1\x4f\xdd\x06\x7c\xf0\x98\xc1\xe0\x67\xb6\x01\ \x7f\xea\x7b\x24\x78\xfe\xd3\x98\xbf\xb6\x04\xbf\x7c\xc3\x7a\x68\ \x3f\x3b\xf8\xe5\xdb\x40\x6e\x7d\xe2\x6a\x52\x06\xf6\xfe\x72\xf0\ \xe2\x47\x60\x1f\x3e\xb0\x22\x78\x49\x37\xf0\xc9\xca\x04\x2d\x67\ \x9e\xcd\xca\x7f\xd0\xf2\x90\x0a\x5a\x3e\xca\xea\xfd\x29\x47\xca\ \x40\xe8\xef\xc1\xab\xf2\x20\xdf\x1c\xff\x28\x2d\xc7\xfe\x1a\xfc\ \x66\x27\xc8\x09\xe1\x7d\x82\xdf\xd4\x80\x5f\xfd\xec\x77\xc1\xeb\ \x16\x01\x1d\x06\x2f\xa6\xe5\x19\x01\x5a\x3e\x7b\x3e\x2d\x5f\x9b\ \x4f\xcb\xb7\x5a\x83\xd7\x5d\x0b\x78\xdd\xf9\xeb\xe0\x8f\x1f\x82\ \x75\xbb\xf9\x4a\x5a\xde\x93\x0d\x3e\x78\x09\xac\xe7\x73\x47\x05\ \x1f\x59\x01\xf3\x5d\x77\x44\xf0\x57\x23\x20\xb7\xd7\x3c\x43\xcb\ \xee\x97\x82\xaf\xae\x07\x79\xe5\xf9\x86\xe0\x9f\xbe\xb4\x27\xc8\ \x37\x43\xc1\xd7\x2f\xb9\x1f\xa1\x78\x2a\xf8\xd6\x75\xc0\x07\xf6\ \xc9\x06\xdf\x8d\xc3\x7a\x0d\xf5\x05\x3f\xe8\x3b\x09\xa1\xe1\xeb\ \x83\x1f\x6d\x04\x79\xaa\xf5\x1c\x5a\x7e\x94\x0e\xfe\x1b\xc3\xe9\ \xd0\x42\xa1\xcb\x81\xae\x82\xef\xd3\xf2\x85\x08\x2d\x5f\xbb\x3b\ \x14\x3d\x03\xe6\x31\x7e\x05\x2d\x3f\x7a\x3d\x54\xf5\x04\xac\xef\ \x9c\x23\x43\x33\x5e\x06\xba\x0f\xdc\x17\x9a\x75\x3b\x9c\xaf\xe3\ \xf7\x85\x1a\x3b\x60\x3d\xe7\x7e\x29\x14\x3b\x17\xf8\xc0\xe0\x70\ \x68\xd1\xad\xb0\x8e\x77\x47\x43\xeb\x6a\x61\xde\xff\xb1\x20\xb4\ \xf1\x8b\x70\x2e\x0d\x4d\x86\x8e\xbd\x0b\xf6\x9f\x76\x1a\x2d\x8d\ \x05\xa1\xad\x58\x1e\x7d\x71\x43\x68\xfb\x0a\x03\xf8\xc5\xf3\xa1\ \xed\x58\xee\x38\xf2\xdb\xa1\xed\xb7\x03\xfc\x97\xe2\xa1\x2f\x46\ \x60\x1e\x86\xae\x0f\x5d\xb2\x06\xe4\xd4\x2d\x75\xa1\x4b\x9f\x04\ \x3a\xfd\x56\x28\xf4\x95\xfb\xe1\x3c\xab\xbc\x2b\x74\xd9\x67\x40\ \x36\x7f\xb9\x29\x74\xf9\x42\xd8\x3f\x2f\x0f\x85\xbe\xf9\x03\xe0\ \xaf\x15\x9f\x0e\x5d\x7b\x11\xac\x43\xd9\xfa\xd0\x75\x87\x42\xfb\ \x4d\x9f\x08\x7d\x6f\x1b\xd0\xd3\xa6\xab\x43\xdf\x3f\xe4\x18\xa0\ \xef\xd7\x42\xdf\xff\xcc\x4f\x60\xbf\xec\x1e\xfa\xfe\xe7\x41\x77\ \xd8\x24\x85\xbe\xff\x9d\x3b\x00\xff\xfd\x43\x37\x3e\x07\xfd\x2c\ \xf8\x5c\xe8\x8e\x0e\xd0\x95\x7e\x7e\x40\xe8\x9e\x15\x0f\x23\xf4\ \xfb\xb2\xd0\xcf\x3a\x80\xce\xd4\x53\x43\x3f\xc3\xf2\x76\xe8\x38\ \x5a\xbe\xbe\x25\xf4\xf0\x9d\x30\x1f\xc6\x75\xa1\xc7\xbe\x0a\x72\ \x4e\xcd\x49\xa1\xc7\xf7\x04\x7e\xf9\xb7\xd1\xd0\x6f\xae\x01\xbe\ \xfd\xda\xc6\xd0\x53\x5b\x56\xa1\xc0\x9e\x57\x86\x5e\x19\x01\xfe\ \xf5\xb5\x50\xe8\xc3\x97\x01\x0e\xba\x3d\x5c\xfd\x60\x2d\x0a\x4c\ \x7f\x2d\xbc\xdb\x69\x20\x27\x74\x5f\x40\xcb\x0d\x57\x84\x17\xfe\ \x75\x19\x42\x8f\xa1\xf0\xe2\x7f\xc2\xfa\x3c\xf8\x87\xf0\x92\xd3\ \x61\xdf\xcc\xdd\x1c\x5e\x3e\x07\xe6\xf5\x9b\xd7\x86\x0f\xfc\x45\ \x15\xcc\xcb\x9f\xc3\x87\xd7\x2c\x85\x73\x71\x4d\xb8\xed\xff\x00\ \xee\xcf\x3e\x13\xee\xac\x7b\x05\x05\xea\xb3\xe1\x35\x77\x02\xdf\ \x3f\xba\x29\xbc\xe6\xe7\x00\x6f\xfd\x79\xe1\x9e\x36\x90\xab\xff\ \xf1\x8d\x70\xdf\xaf\xae\x01\x3a\x1e\x0f\xf7\x9f\xf5\x17\x38\x7f\ \xee\x0b\xc7\x7f\x0a\xfb\xf0\x96\x7b\xc3\x43\x65\x70\x9e\x6f\xab\ \xa2\xe5\x57\x2b\xc3\x5b\x1e\x86\xfd\xf3\x4c\x02\x4a\xa0\x9b\x67\ \x2e\x83\x12\xf6\xd5\x33\xbf\x86\x12\xf6\xe9\xb3\x55\xe1\xa3\x03\ \xbb\x03\x7d\xf7\x87\x8f\xdd\xba\x00\xf0\xde\x18\x3e\xee\xa5\x0c\ \x0a\xd4\x4e\x84\x95\x3a\x90\x4b\x6b\xf7\x0d\xab\x57\xc0\x7c\x9c\ \xb0\x17\x2d\xd5\x23\xc2\x5b\xfb\x81\x8f\xce\x5a\x15\x9e\x3c\x14\ \xe8\xf2\x9c\x17\xc3\xa7\x84\x41\x47\x7c\xe0\xa6\xf0\x27\xf2\x20\ \x2f\xfc\xfe\xef\xe1\x4f\x4c\x40\xf9\xe4\x4b\xb4\x7c\x25\x4b\xca\ \xc0\x3e\xfb\x85\xcf\xfb\x0d\xb4\xdf\xf6\x61\xf8\xe2\xe7\x61\x3d\ \xbf\xfd\xdb\xf0\x65\xe3\x20\xa7\x3c\xd2\x1f\xbe\xec\x4c\xf8\xfb\ \x96\x4f\xd3\xf2\xde\xe1\xf0\xd7\xae\x85\xf3\xeb\x77\xb3\x69\xf9\ \xca\xd5\xe1\x1b\x3b\x3f\x0d\x7c\x68\x71\xf8\xc6\xa3\x80\x4f\x7f\ \x3a\x1e\xbe\xf9\x59\xa8\x17\x3b\x98\x96\xca\xd3\xb4\xbc\xb4\x2e\ \x7c\xeb\x2b\xd0\x4f\xc3\x35\xe1\xbb\x8f\xaf\x06\x3c\xce\x0e\x3f\ \xd8\xf5\x03\xe0\xcf\x6f\x86\x1f\xfa\x3a\xf4\xbb\xa2\x92\x96\x3f\ \x6c\x09\x3f\xf4\x4a\x12\xfe\x7e\x9f\x96\xe7\x1e\x47\xcb\xef\xfc\ \x95\x96\x3f\xfc\x66\xf8\x91\x15\x20\x7f\xea\x3f\x0c\xbf\x7c\xce\ \xde\x40\x0f\xd5\xe1\x37\x6e\x83\xf9\xbe\x2a\x1a\xfe\x4b\x12\xf4\ \xce\x1f\x35\x86\x3f\xba\xbe\x1d\x05\xa6\xfd\xb0\x22\x30\x01\x72\ \xca\xb7\x4e\xac\x08\x7e\x19\xe8\xec\x13\xaf\x55\x48\x67\xc1\x7c\ \xe5\xf6\xad\x58\xf8\x1d\xa0\xdb\xad\x9f\xae\x58\xb4\x1d\xf8\xc7\ \xbf\xe7\x54\x2c\x7d\x63\x16\x9c\xc7\x17\x54\x1c\xf8\x05\x58\x07\ \xf9\xe4\x8a\x83\x6e\xee\x04\xb9\x48\xa9\xe8\x18\x02\xfe\xf0\xd1\ \xe5\x15\x9d\x7b\x3d\x09\xf0\xe4\x8a\x75\xb3\x41\x5f\xa9\xbb\xbd\ \x62\xdd\xf5\xb0\x1e\x81\xb5\x15\x43\xa7\xce\x06\x7d\xf1\x8d\x0a\ \x59\x87\xfd\xf3\xd8\x78\x85\xb1\xd7\x67\xe1\xfb\x93\x2b\x4e\x6d\ \x3e\x0e\xbe\x3f\xb7\xe2\xd4\xeb\x40\x0e\xb8\x37\x5a\xf1\x89\x89\ \x2d\xc0\x5f\x5e\xaa\xf8\xc4\x57\x80\x9f\x3c\xf9\x35\x5a\xbe\x72\ \x00\x29\x03\xd2\xaf\x2a\xb6\xff\xe2\x62\x98\xe7\x0b\x2b\x2e\xd8\ \x02\x3a\xfd\x23\x0f\x57\x5c\xf9\x03\xc0\x2b\xb3\x6f\xc5\x0d\xeb\ \x56\x02\xdf\xb8\xb3\xe2\xc6\x91\x85\xa0\x8f\xbe\x56\x71\xcf\xcd\ \xa0\x53\xb7\x6c\xaf\xf8\xd9\x13\x20\x5f\x3d\xf0\xcf\x8a\xdf\x2c\ \x06\xb9\x62\x54\xae\x78\xe9\x03\xd8\x9f\x77\x1f\x5e\xf1\xf2\x1d\ \x43\x40\xb7\xbf\xab\x78\xfd\x36\x90\x67\x8f\xba\x3d\x12\xd8\x3d\ \x0f\xfc\xf5\x92\x48\x59\x23\xd6\xdb\xaa\x23\xe5\x97\xc1\xb9\xfc\ \x93\xab\x22\x75\x2a\xd0\x75\xc5\x9b\x91\x3d\xde\x87\x7d\x83\xb6\ \x45\xe6\x80\x6c\x8d\x3e\x38\x2a\xb2\xd7\x70\x3d\x0a\xcc\x7e\x3b\ \xd2\xf8\x05\xa0\x9f\x3d\x06\x23\x4d\xbf\x81\x73\xea\x1b\x55\x91\ \x15\x5b\x01\xde\xa3\xbf\x8a\x1c\x76\x26\xc8\x21\x4b\x56\x44\x0e\ \xc7\xe5\x99\x67\xd1\xf2\xac\x77\x23\x1d\x46\x37\xd6\xd9\x23\x9b\ \x87\xa2\x20\x3f\xf4\x44\x86\xc3\x80\xff\x1f\x56\x47\x86\xd7\xdc\ \x0c\x72\xc9\x58\x64\xe4\x8b\xb0\x6e\xef\x3d\x14\x19\xbd\x12\xf8\ \xc1\xee\x8f\x46\xc6\xba\x61\xff\xc4\x1f\x8f\x6c\x5b\x02\xfb\xea\ \x99\xf9\x91\x33\xbe\x05\xdf\x7f\x37\x1d\x39\xff\x1d\xc0\xf3\x17\ \xeb\x22\x5f\x0a\xc0\xbe\x3e\xa2\x25\xf2\xa5\x04\xd0\xd7\xd6\x77\ \x22\xdf\x7e\x0c\xe6\xf5\xd4\xaf\x47\xbe\xf3\x55\xe0\xb7\x07\xdc\ \x1a\xb9\x75\x1a\x9c\xd7\x5b\x7e\x19\xb9\xf5\x0f\xb0\xaf\xff\xf5\ \x95\xc8\xed\x6f\xc0\xbe\xda\xe3\xf6\xc8\x1d\xdb\x1f\x80\x7d\x3a\ \x37\x72\xcf\xd9\x2b\x80\x0f\x9d\x12\xb9\xef\x49\x18\x5f\xff\xf2\ \xc8\xfd\x1d\x70\x7e\xac\xcc\x45\x1e\xba\x01\xe0\x9f\xf7\x10\x29\ \x03\x15\xcf\x46\x1e\x79\x10\xd6\xed\xa1\xb6\xc8\x53\x8f\x03\xfd\ \x56\x7d\x2b\xf2\xf4\x45\xfb\x22\x74\x9f\x12\x79\x16\xd3\x73\x55\ \x65\xe4\x6f\x5d\x50\x7f\xaf\xc3\x69\xf9\xf9\xbd\x23\xff\xb8\xed\ \x28\x58\xc7\x43\x22\x1f\xbe\x07\xe3\xad\xbe\x94\x96\x6b\x2f\x8a\ \xfc\xab\x0d\xf8\x59\xe4\xef\x95\xc1\x97\x81\x7e\x56\x7c\xaa\x32\ \xf4\x09\x58\xdf\xed\xc3\x95\x91\x93\xe0\x1c\x49\xdc\x5c\x59\xf9\ \x14\xd0\xdb\x25\xbd\x50\x02\xff\xba\xff\x0f\x95\xbb\xfd\x19\xe6\ \xf3\xb3\xe5\xb4\xfc\xb6\x52\x39\xa7\x0d\xce\x8d\x69\x9f\xa6\xe5\ \xba\xee\xca\x65\x5f\x81\xfe\xbe\xf6\xb9\xca\x95\xeb\x40\xff\xe8\ \xfb\xa8\xf2\xb0\x56\xa8\xf7\xe1\xaa\xca\x8e\x6b\x60\xbf\xfc\xed\ \x83\xca\x75\xfb\x00\x9f\x5b\x9d\xa8\x1c\x46\x18\xff\x7b\x2b\x87\ \xef\x04\xbd\xf7\xa9\x9f\x93\x32\xb0\xef\x81\x95\xa3\x43\xa0\x8f\ \x9e\x75\x46\xa5\xfa\x32\xf0\xb5\x79\x7f\xab\x4c\xc9\xc0\x67\xbe\ \x7c\x57\xe5\xb6\x93\xe6\xa2\xc0\x6e\xdb\x2b\xcf\x38\x15\xda\x5d\ \xf1\x8b\xca\xcf\xdd\x7c\x24\xc8\x71\x3f\xad\xdc\x6e\x00\xbf\x99\ \xb6\x96\x96\x47\x3e\x5b\x79\x7e\x25\x96\xd3\x6e\xaa\x3c\xff\xcf\ \xb0\xfe\xb7\xff\xb5\xf2\xca\xab\xe1\xbc\x38\x62\xa4\xf2\xeb\x3f\ \x02\x39\xf3\xd2\x5c\xe5\x35\x9f\x04\xbd\xf7\xb2\x13\x2a\xc9\xba\ \xdc\xfd\x78\xe5\x77\xb1\xad\xe8\x37\x37\x57\x7e\x17\xe4\x11\x54\ \xfd\x72\xe5\x2d\x7f\x84\x73\x29\xbf\x9d\x96\x9f\x2b\xaf\x7c\x66\ \xdd\x2b\xa0\x07\x5e\x5b\xf9\xe7\xed\x30\x0f\xd7\x34\x56\xbe\x5d\ \x0d\xfb\x32\x74\x51\x34\x70\xd8\xf9\xc0\x3f\x6f\x89\x06\x5f\x85\ \x73\x72\xe3\x4f\xa2\xe1\x0f\xe1\xf3\x1b\x6f\x8a\xce\xbf\x11\xce\ \xa9\xbb\x3f\x15\x3d\x28\xff\x26\xec\xbb\x19\xd1\x43\xcf\xfb\x1d\ \x42\xa7\x3d\x12\x3d\x6c\x26\xf0\x87\x2d\x1d\xd1\x23\x3f\x3b\x0f\ \xa1\xff\xfb\x2c\x2d\x7f\xf4\x7a\x74\xe0\xe9\xef\x01\x5f\xdf\x18\ \x1d\x3a\x11\xe4\xfd\x33\xe7\x47\x8f\xbd\x10\xda\x5f\x75\x4f\xf4\ \x84\x1f\x80\x9e\xab\x7d\x44\xcb\xc7\x3e\x8c\x0e\x07\x61\xff\x9e\ \xb5\x30\x9a\x68\x86\xf3\xe9\x67\xd5\xd1\xe4\x2f\x1f\x05\xb9\xe2\ \xbd\xa8\x72\x39\xf0\xc9\x9a\x85\xb4\xec\x9e\x1e\x1d\x39\x1f\xf4\ \x81\x63\x6f\x8b\x8e\x7c\x08\xfc\xf6\xfe\xfa\xe8\xe8\x5f\x80\xdf\ \xd6\xed\x1e\xdd\x7a\xe5\x22\x84\xea\xdb\xa2\x7a\x27\xf4\x3b\xb3\ \x22\x6a\xac\x84\xfd\x94\x3c\x95\x96\xda\xf4\x68\x1e\xf7\x7f\xc0\ \x96\xe8\x69\x6f\xc2\x39\x9e\xfb\x4e\xf4\xac\x3f\xc1\x7c\xce\x3b\ \x22\x7a\xce\xcf\x81\x5f\xed\xf6\xa5\xe8\x25\xdd\x97\x83\xbe\x7f\ \x70\xf4\x2b\x0f\x1e\x0a\xf2\xf9\xa5\xd1\xcb\xaf\x83\xfd\x7b\xee\ \x73\xb4\x7c\x42\x8a\x5e\x39\x02\xf3\xd7\x51\x1e\xfd\xce\x27\x81\ \x7e\x16\x2f\x8d\x5e\xb7\x08\xce\xa3\xf0\x31\xb4\xec\x38\x38\xfa\ \xfd\x47\x00\xff\xe6\xd9\xd1\xdb\xb7\x03\x3f\xfd\xd7\x09\xd1\xbb\ \x4e\x08\x22\x94\xba\x37\xfa\xa0\x01\x7a\x7c\xf9\x2f\xa2\x0f\x5f\ \x84\xf5\xfb\x8e\xe8\x2f\xfb\x6e\x81\x7e\x52\xa4\x0c\x04\xdf\x8f\ \x3e\xfe\x02\xac\xdb\x71\xcb\x68\x39\x72\x6b\xf4\xd5\xdb\x5b\x41\ \xaf\x9f\x19\x7d\x7d\x04\xe4\xcb\xc8\xff\xd1\x72\xf5\x8c\xe8\x3b\ \xcb\xcf\x03\xbe\x3a\x2f\xfa\xee\x43\xb0\xef\x36\x7d\x10\xfd\xd7\ \x39\x40\xd7\x55\xab\x69\xb9\xa6\xad\x2a\xd8\x06\xfb\x57\x7e\xbb\ \xaa\xf2\x12\x80\x73\xc8\x13\x55\x95\xef\xc0\xb8\xb6\x3f\x5f\x55\ \x35\x07\xf4\x8b\xfb\xfe\x5e\x75\xc0\xd9\x20\x77\x34\xbf\x56\xd5\ \x76\x19\xe8\x65\x6f\x6c\xa9\xea\x78\x13\xf8\xf2\xe6\xcf\x57\xf5\ \x5c\x08\x74\xff\xe1\x35\x55\x3d\x6f\x83\xbc\xdc\xf8\x00\x29\x03\ \xa1\x33\xab\x7a\x13\x20\x17\xac\xbc\xa9\x6a\xe3\x13\xd0\x7e\x62\ \x61\xd5\xa6\x2f\x82\xbc\x3f\xb7\xa6\xea\xd8\x17\x61\xfc\xcb\x62\ \x55\xe9\x0f\x80\xae\xf7\xfa\x5b\xd5\xc4\xfd\x40\x87\xd3\x2a\xab\ \x26\xaf\x02\x7d\xe8\xa0\x44\xd5\x67\xef\x03\x38\x17\xb6\x54\x6d\ \x5f\x0b\xed\x2a\x66\xd2\xb2\xe3\x95\xaa\xf3\x9e\x81\x73\xa5\xe9\ \xe1\xaa\x0b\xf7\x83\x7d\xd3\x35\xb7\xea\x8b\x1f\x01\x3f\x9d\xf1\ \xa7\xaa\xff\xc3\x9f\xcf\x7a\x81\x96\x67\x2c\xa3\xe5\x5b\x5a\xd5\ \xf5\xbf\x03\xfa\xaf\x3a\x9d\x96\x6b\x4e\xad\xba\x61\x16\xd0\x63\ \xc3\xb3\x55\x77\x19\x30\xfe\xeb\x67\x56\xdd\xb3\x15\xce\xdf\x37\ \xb3\x55\xf7\xfe\x1a\xf4\xbe\xd9\x9b\xaa\x1e\xe8\x85\x71\xff\x34\ \x5e\xf5\xc0\xfd\xbb\x81\xde\x13\xab\x7a\x68\xfd\x2a\x38\x57\xfa\ \xaa\x1e\xb9\x15\xe8\xff\xa8\x73\xaa\x1e\xdf\x1f\xf8\xde\x96\x8b\ \xaa\x7e\xfb\x24\xb4\xff\xd4\xa2\xaa\xa7\x6f\x06\x3a\xbb\xf7\x1b\ \x55\x2f\x62\x38\x4f\x9d\x42\xca\xc0\xbc\x5f\x57\xbd\x3a\x04\xfa\ \x95\xfa\x8f\xaa\x37\xaf\x7c\x09\xd6\xf9\xaf\x55\x6f\x1d\x00\xf2\ \xce\x0b\x0f\x54\x87\x4e\x06\x3e\xff\xef\x5b\xaa\x2b\xa2\xa0\x07\ \x1e\x7f\x16\x2d\xc7\xbe\x53\x1d\xd9\x0e\x7c\x26\x3e\xb3\xba\xe6\ \x0c\x90\x93\x36\x2f\xaf\xae\x7f\x1b\xce\x9d\xdf\xaf\xa8\xde\xfd\ \xdb\x70\xde\xbe\x7f\x7f\xf5\x8c\x6d\x6b\xe1\xbc\xb8\xac\xba\xe5\ \x41\x80\xb7\xf0\xa4\xea\x55\xbf\x80\xfd\x3f\xac\xd0\x32\xb1\x07\ \x2d\x93\xcd\xb4\x4c\x3f\x49\xcb\x6d\xdf\xa5\xe5\xa7\xee\xa4\xe5\ \x55\x2a\x2d\x7f\xdc\x51\x7d\xb8\x01\x72\xe3\x3b\xe7\x55\x77\x7e\ \x0a\xe8\xba\xfc\x77\xd5\xdd\xaf\x03\x7e\x0b\x6e\xaf\x1e\xd8\x08\ \xf2\xe1\xba\xab\x49\x19\x08\xd6\x40\x09\xfb\xf5\x27\xef\x55\xc7\ \x5b\xae\x84\x7d\xf4\xb5\xea\xf8\x1a\x58\xf7\xab\xd7\x55\xc7\xef\ \x06\x3a\x7a\x70\x63\xf5\x51\x7f\x80\x73\x32\x32\x58\x3d\x06\xfb\ \x13\x0d\x5c\x5b\x7d\xe2\x41\x1a\x42\xed\xe3\xd5\xd9\xab\x40\x4e\ \x5f\x78\x47\xf5\xf6\x9f\xc0\x3c\xfd\xf2\x89\xea\xed\xbf\x02\xfd\ \x3e\xdf\x5c\x7d\xfe\xab\x40\xc7\xd3\xcb\xab\x2f\xb8\x03\xfa\x5d\ \xba\x2f\x2d\xcf\x39\x83\x96\xd7\x55\xd1\xf2\xa6\xa7\xaa\xbf\x70\ \xd9\xd7\x41\xfe\x3d\xa1\xfa\x8b\xaf\xc2\x7a\x2c\xbf\x98\x96\x3f\ \xb8\xad\xfa\xa2\x9f\x02\x1d\xc7\xdb\xab\xaf\xc3\x70\x97\x9e\x4e\ \xcb\xec\xbb\xb4\xfc\xcc\x31\xb4\xfc\xd6\xdd\xb4\xfc\x9e\x4e\xcb\ \xc7\xcf\xa9\xfe\xee\x34\x38\x7f\x81\x73\xdd\x22\xc3\x7e\xba\x22\ \x51\xfd\xd8\x19\x7f\x01\xbd\xfc\xb9\xea\x17\x66\x61\x7b\xcf\x31\ \xd5\xaf\x5f\x07\xeb\x78\xc1\xd3\xd5\xef\xbf\x07\x74\xb8\xc7\x71\ \x35\xe5\x65\x32\x42\x7f\x7d\xa7\x26\xd4\x0a\xf2\xde\x89\x5a\xcd\ \x6e\x95\x40\x97\xaf\x9e\x58\xb3\x70\x15\xe8\x4d\x8b\x5e\xac\x39\ \xf4\x41\xd0\x67\xff\x79\x61\xcd\xba\x27\x60\x7f\x7c\xbd\xa7\xa6\ \xcf\x80\x7d\xfd\xf9\x73\x49\x19\x88\xbc\x57\x33\xf2\x2a\x9c\x0b\ \x4f\x3c\x45\xca\xc0\xde\x4f\xd7\xa8\x5d\xa0\x17\x3e\xf7\x9d\x1a\ \xf5\x49\x18\xc7\xda\xe7\x68\xf9\xdc\x4b\x35\xe9\x43\xa0\xfc\xa8\ \xb5\x26\xf3\x0d\xc0\x67\xe6\x1d\x35\x79\x04\xf3\xf8\xfb\xdb\x6b\ \xf2\x1f\x82\x1c\xfd\xd7\xe3\x6b\x26\xf0\xdf\x4f\xce\xa5\xe5\x1f\ \x6f\x20\x65\x40\x5a\x5c\x33\xf1\x09\xe0\xb3\x4f\x6e\xa1\xe5\x1f\ \xff\x4c\xca\x80\x74\x4a\xcd\xa9\x47\xc3\xf7\xb3\xbb\x6a\x3e\xf5\ \x3d\x18\xc7\x8f\x8c\x9a\x33\x1f\x80\x73\xe1\x98\xc7\x69\xa9\x6c\ \xaf\x39\xfb\x6a\xa0\xaf\x77\xef\xaf\xb9\xf8\x5e\x6c\xd7\x38\xa4\ \xe6\x07\x57\xf4\xc1\x39\xfa\x5e\xcd\x4d\x21\xe0\xf7\x5f\xff\x77\ \xcd\xfd\x8f\xc1\x7e\xfe\xf4\xed\x35\x4f\xbf\x77\x05\xc8\xd7\x4b\ \x6b\x9e\xd9\x0c\xf2\x4d\xed\xdd\x35\x2f\xc7\x9e\x03\x79\xf3\x89\ \x9a\xbf\x19\x70\x6e\x9d\xff\x1c\x29\x03\x91\xdb\x6a\xde\xdd\x0b\ \xe6\xe1\x82\x32\x52\x06\x2a\x33\x35\xef\xce\x07\x7c\x82\xfb\xd7\ \xbc\x8f\x3f\xdf\xeb\x47\xb5\xd3\xbe\x0a\xeb\x19\x7b\xad\xb6\xe1\ \x9c\xa7\x61\x9c\x61\x52\x06\xc2\x3f\xae\x9d\x3d\x0a\x9f\x37\x0d\ \xd5\x2e\x38\xe7\x5a\xe0\x17\x1f\x91\x32\x10\xba\xa5\x76\xf1\xfd\ \x70\x0e\x5e\x7e\x44\x6d\xf7\x23\xc7\xc3\xbc\x7f\x50\xbb\xee\x66\ \x2c\xa7\x5f\x5c\x7b\xf4\x95\x95\x28\x10\xed\xad\x95\x5b\xe0\x5c\ \x6b\xad\xab\xcd\x4c\xae\x01\x7c\x2e\xa9\x1d\x7f\x10\xf8\x66\xc3\ \x70\xed\x64\x04\xf8\xc9\x2f\x2a\x6a\x3f\x75\xda\x8f\x81\xfe\x17\ \xd6\x5e\xfb\x6b\xe0\xd3\xef\xea\xb5\x37\xbc\x03\xfa\xed\xb6\xcd\ \xb5\xb7\x7d\x0f\xc6\x7b\xeb\xa2\xda\x3b\xee\xbf\x18\x9b\x09\x6b\ \xef\x6f\x07\x3c\xf7\xfb\x5e\xed\xcf\x83\xc0\x4f\xbf\xfa\x87\xda\ \x67\x74\x58\xbf\x33\x26\x6b\x9f\xfd\x32\xf0\x95\xbb\x5a\xeb\xaa\ \xfe\x0c\x72\x7a\xe5\xbb\xb4\xec\xfa\x6a\xdd\xde\xf0\x79\x60\x8f\ \xef\xd5\xcd\xdb\x37\x02\xe7\xe0\xe2\xba\xfd\x9e\x82\x79\xaa\x7f\ \xb7\xae\xf1\x56\xe8\x67\xe5\x47\xb4\x5c\x7f\x6b\xdd\x92\xaf\xc2\ \xf9\x7e\xf9\x35\x75\x9d\x5f\x07\xfa\x9f\xfb\x54\xdd\xda\xf7\x61\ \xbf\xd4\x4f\xd6\x1d\x99\x04\xfe\x9f\xd2\xeb\x7a\xf6\x83\x73\xb7\ \xba\xbb\x4e\x7e\xf2\xe7\x70\x5e\x57\xd7\x25\x56\x40\xff\xbf\x1b\ \x24\x65\x60\x9f\x54\xdd\xe8\x32\xe0\x73\xf7\xdc\x5c\x37\x79\x26\ \xd0\xcb\xde\xcf\xd6\x7d\xf2\x28\x98\xef\xb2\x8e\xba\xd3\x63\xb0\ \x6f\xbf\x71\x13\x2d\x6f\x38\xba\xee\xaa\xa3\xff\x09\xe7\xfc\xee\ \x75\xd7\x87\x40\xfe\x8a\xde\x4b\xcb\xae\x7f\xd6\xdd\xde\x00\xe7\ \xf5\xfb\x7b\xd7\xdd\x89\x80\x4f\xb7\x9d\x5e\xf7\xea\x1e\xc0\xc7\ \xee\xab\xaf\xfb\x53\xfb\x3b\x70\xce\xad\xaf\x7b\xd7\x58\x8a\xd0\ \xfc\x8b\xeb\x3e\xb8\x13\xf8\xeb\xd9\xc7\xd3\xf2\x9a\xb3\x68\xf9\ \x8b\xc7\x68\xf9\xeb\x33\xea\xfe\x3d\x04\xf3\xf1\xce\xdb\x2a\x08\ \x1b\x8f\x83\x66\x81\x56\xa1\x01\xa4\xa2\x2c\xd2\xe1\xdf\x1c\x32\ \xe0\xdf\x0c\xd2\x90\x84\x92\x48\x41\x29\x52\xe2\xcf\xb3\xf0\x59\ \x0e\x7e\xc3\xdf\x8f\x93\xef\x9b\x50\x23\x5a\x82\x9a\x22\x78\xf3\ \x85\xe1\xff\x59\x03\xca\xb8\xa2\x1b\xd2\xb0\x9c\xd8\x2a\x19\x9a\ \x94\x54\xc6\xd5\x84\x22\x35\x35\x2e\x69\xaa\x80\xaf\xab\xda\xf2\ \x49\x55\xdb\x90\x37\xb2\x79\x23\x80\xfb\x9d\x85\xda\x50\x02\x7e\ \x14\x80\x8b\x21\x0f\xc3\xff\x29\xd2\xc3\x0b\x16\xcc\x9a\xb6\x44\ \x42\xc9\xe5\xd4\x61\x35\xa5\x1a\x93\x18\x4c\xa4\x6f\x4c\xcb\x68\ \x99\xd6\x56\x06\xa3\x03\x70\x49\xa3\x3c\xe0\xac\x02\x2c\x19\x9d\ \x0c\xa5\x06\x7f\x29\x36\x8c\x0e\x2d\x9d\xce\x67\xd4\x84\x6c\xa8\ \x5a\xc6\x0b\xa3\x1a\xad\x21\x6d\x12\x68\x0c\xa9\x56\xab\xd0\x1a\ \x39\xad\xe4\x44\xb5\x7b\xa1\xb7\x1c\xed\xcd\xae\xdd\x9b\xcf\xa9\ \x09\x6f\xed\x7a\x58\x2b\x8d\xcc\xd9\x08\x69\x31\xc6\xe3\xb5\x5e\ \x33\xd4\x11\x86\x96\xa0\xa7\x28\xda\x08\x6d\xf0\x2a\x68\x76\x3f\ \x1b\xd5\xa4\xa2\x79\xeb\x1e\x8c\x06\xc9\x1a\x6a\x6c\xbd\x24\xc0\ \x50\x83\x15\x1d\x85\xd6\x19\xe8\x5f\x81\x4f\x32\x64\x5e\x24\x58\ \x3d\x99\xcc\x73\x12\xfe\x6e\xb1\x20\x37\x74\x67\xc6\xe5\x94\x9a\ \x94\x72\x5a\x5e\x87\x65\x33\x26\xb3\x4a\x0b\xee\x68\xae\xd9\xd1\ \x9a\x9c\xa1\x2b\x30\x29\x7a\x6b\x6b\xaf\x92\x54\xe5\x0d\xc3\x27\ \x2a\x09\xba\x94\x8f\xa0\x21\x32\x48\x0c\xf6\x64\xf8\x91\xa1\x9b\ \x93\x60\x9a\x14\x42\x50\x18\xa9\x04\xfc\xa5\x33\xa4\x30\x32\x59\ \xf8\x57\x87\x12\xff\x35\x0a\x9f\xa6\xa0\x0d\xfd\x46\x25\x44\x37\ \x4e\x3e\xcb\xc3\xd2\x2a\xa8\x05\xfe\xee\x21\x30\x4d\x22\xb4\x16\ \x19\x3e\xc3\x83\x49\x01\x31\xd2\xbe\x30\x8c\x34\xa9\x9b\x23\x84\ \xac\xb2\x4f\xf1\x27\xaf\xc2\xff\x07\x00\xd1\x2e\x22\xad\x28\x81\ \x3b\xbf\xc5\x04\xdd\x68\x4d\xc9\xa6\xa1\x1c\xcc\xc3\x98\x9a\x93\ \x72\x30\x31\x8a\x8e\x89\x5a\x4e\x9e\x98\xcf\x19\xf0\xa9\x22\x8d\ \x6b\xa9\x7c\x5a\x69\x91\x06\xe1\xf7\x94\x32\x62\xa4\x35\xf8\x22\ \xab\xe5\x54\xbc\x9e\x12\xb4\x3a\xa0\x71\x11\xa9\xa8\xab\xa3\x63\ \xf4\x5b\xf8\xb0\x71\x49\x23\x9e\xd5\x06\x73\x56\x37\x12\x28\x71\ \xd2\x01\x99\xcb\x19\xb0\xec\xf6\xd8\x5b\x3d\x58\x55\xd1\x16\xad\ \xc5\x21\xc5\x48\xcb\x45\x04\xc2\x52\x8e\x00\xf0\xb8\x47\xd8\xec\ \x18\x1c\x71\xd5\x37\x2e\x59\x24\x35\x2e\x95\x32\x9a\x01\x9b\x77\ \x44\xcd\x28\x49\xdc\x41\x45\xff\x32\xbc\x0b\x53\x04\xe6\x81\xb0\ \x69\xd3\x64\xab\x8e\x02\x86\x64\xb3\x5a\x24\x87\x7b\xb3\x7b\x19\ \x65\xb3\x8b\xeb\xd8\x1b\x65\x66\x5b\x7a\x58\x1d\xcd\x6b\x79\x3c\ \x13\xa4\xa7\x31\x39\x93\x4c\x09\x7a\xaa\x45\xab\x09\x3d\xa5\x09\ \xa6\x36\x84\x70\xa7\x92\x52\x0c\x85\xb0\x94\xfe\x65\x9d\xb2\x21\ \x0f\xca\xc3\x29\x85\x6d\x99\x2e\x42\x0f\x39\x7e\xcb\x74\xc9\xa9\ \x9c\xb8\x7a\x3d\xea\x06\xd0\x39\x42\x8a\x98\x50\x12\xdc\xfe\x0f\ \x77\x67\x72\xc0\xcd\x84\xed\x22\xb0\x44\xb8\x8d\xdd\x49\x70\x50\ \xcf\x8b\xfb\x98\x06\x13\x36\x0a\x3f\x2a\x21\x7d\xc7\x40\x86\xb2\ \x49\xd9\x67\x20\xa7\x92\xc9\xc4\xc3\xc1\xdb\x81\xdf\xbd\x98\x5c\ \x35\xb2\x87\xf1\xc6\x6a\x81\x3a\x1d\xe4\x1b\xfa\x79\x8a\x6c\x24\ \x73\x13\xd1\x4d\x96\x20\x3d\xe7\xc8\x36\xb4\x37\x58\x86\xf0\x4d\ \x85\xe3\xf3\x23\xac\x2f\x9b\x27\x2c\x6c\x5c\x12\xed\x52\x53\x0a\ \x59\xa7\x11\x2d\x9f\x49\xb6\x44\x3b\xc6\x14\x60\xef\x59\xd9\x18\ \x93\x60\xe1\xa4\x11\xf8\x3a\x03\x4c\x81\xb0\x8a\xea\xfe\x65\xb8\ \x7a\xa7\x2a\xa7\xb4\x51\x36\xfa\x98\xcf\x32\x56\xc4\xec\x75\xf4\ \xb6\x0b\x43\xbb\xf5\xdc\xfc\x96\xc7\xd6\x6b\xfe\x35\x37\xa0\x75\ \x5c\xcd\x0d\xeb\xc4\x35\xa3\x50\xb3\x8d\x9e\x73\x36\x71\xc4\x36\ \x64\x95\x8c\xb8\x7e\x3d\xd4\x1f\x60\xa7\xa1\x17\xfb\x01\x32\x6c\ \x71\xcb\x6a\x68\x19\x27\x84\x38\xce\x9f\x11\xb1\xb8\x3c\xee\xd3\ \x62\x16\x1d\x2f\x59\x61\xbc\x5a\x49\xda\x1f\xde\x3e\x56\xfb\xca\ \xd8\x50\x26\xa7\xe9\x06\xdd\x2b\xe2\x99\x88\xa3\x37\x6c\x9a\x8c\ \x1d\x45\x0f\x30\x6f\xd5\xe3\xd0\x4a\xe0\xcf\x06\x1c\xfd\x71\x58\ \x70\x95\x71\x4b\xca\xa3\xed\x23\x84\xf2\x60\xca\xa7\x15\x7e\x11\ \x19\xa7\xa6\xfb\x7d\x1e\xe1\x2e\xf3\xd0\xe1\x00\x73\x31\x85\x6a\ \xa1\xb0\x64\xe5\x49\xc6\xaa\x36\x5d\x91\x26\xb5\xbc\x94\xcb\xb3\ \x5f\x26\xd4\xdc\x18\x15\x10\x30\x01\x60\x3e\x30\xaf\x71\xe9\xbc\ \xc3\x57\x2e\x86\xca\x62\x7c\x25\x38\xde\xf2\x00\xd9\x20\x78\xa9\ \x1c\xb1\x4a\xa8\x19\x2d\x40\xf3\x39\x81\x21\x95\x92\x70\xeb\x9c\ \xd4\xbc\x60\xbe\xdf\xc2\xb6\x11\x58\x3a\x11\x3a\xf2\x8e\x49\x8e\ \xb6\x19\x86\xae\x0e\xe7\x0d\xbf\xa9\x9b\x46\x78\x06\x9e\x20\x85\ \xee\x39\x7b\xbe\xdb\x41\xf0\x11\x37\xaa\x85\x1e\x33\xf0\x93\xa7\ \x1b\xd4\x66\x01\x1d\x72\x06\xf8\x9d\xb8\xd1\x22\xb2\xb3\xb3\xd0\ \x93\x4c\xa8\x42\xb2\xa4\x30\x83\x7c\x92\x27\xd4\xc2\x26\xc2\x02\ \xb9\x5b\x87\x96\x9d\x94\x34\x5d\xea\xd5\xc6\x15\x49\x26\x73\x21\ \x86\xdf\x02\xf0\xf1\x42\x9a\xb0\x64\xc2\x15\xf2\x8c\xbb\x48\x44\ \x9a\xd2\x89\xec\xe0\x44\x7a\x7a\x07\x88\x01\xb0\x6e\xeb\x95\x09\ \xa9\x4b\x4b\xc1\x69\x23\x86\x1f\x41\x9d\x84\x82\xed\x96\xc1\x4e\ \xd9\x6f\xc3\x37\x38\xd9\x04\xa5\x2e\x9b\xf4\x3b\x4d\x52\x11\xb7\ \x9e\x47\x44\x25\x73\x62\x92\x64\x69\xf0\xef\xa3\x04\xa6\x13\x89\ \xaa\x4e\xc5\x90\xd5\x94\xb4\x51\x55\x26\xfc\x96\xb8\xc3\x67\xe8\ \xe5\x9d\xaa\xcf\x60\xdd\x6d\x14\xae\x3f\x55\x07\x39\x49\xd3\x55\ \x3f\x92\xaa\x77\xf7\x87\x5a\x6d\x7a\x34\x5b\x4f\xb6\xfa\xf1\x9a\ \xd5\xd0\x54\xa7\x82\x95\xcd\x6b\x56\xeb\xba\x26\x42\xf5\xdf\xf0\ \x9f\xbd\x1e\xfe\xc4\x31\x83\x31\x24\x7a\x44\x98\xbb\xcd\xc6\xab\ \x8a\x9c\x0b\x31\xcc\x03\x7d\x10\xc3\x10\x6c\xa1\xd4\x17\x02\x96\ \x33\x7d\x20\xcc\x81\xf6\x7a\x51\x72\xac\xed\x52\xe1\x1c\xb2\xa6\ \xc9\x8f\xbf\x76\x13\xb2\xf2\xea\x1b\xf6\x9c\x55\x77\x67\x64\xa6\ \x6d\xf8\xcd\xca\x1c\x07\x9d\xc9\x8c\x2f\x62\x11\x3b\xc1\x31\x82\ \xca\x1e\x15\x64\x3d\x7f\xfa\x6a\x80\xf5\xa6\x07\x33\x86\x10\x23\ \x14\xdf\xca\xb5\xd6\xb4\xad\x52\x4c\xcd\xf8\xcc\x4a\xc4\x5c\x17\ \x7b\x19\xd7\xfb\x9e\x44\x73\xa0\x72\xf1\x1d\x1d\x2d\xb6\x95\xe7\ \x15\x02\xe3\xda\xab\x35\x36\x30\xdf\xfd\x2a\x15\x81\x67\x43\xab\ \xe6\xa0\xf9\x6e\xfe\x1e\xa2\x93\xd2\xe6\x94\x4f\xe6\x99\xec\xa3\ \xba\xf6\xc5\xb4\x0d\x19\x45\x4a\x9a\xb4\x22\xe5\xb3\x7e\x73\xec\ \x16\x14\x82\x85\xe4\x04\x2c\x25\xc4\xd8\x30\x9c\x7a\x61\xc5\x40\ \x4c\x49\x69\xb2\xcf\x89\x3d\x13\x8e\x5f\x8d\x0d\x39\xc5\x98\x16\ \x3e\x82\xed\xf6\x95\x03\x8a\x9c\xdc\x5f\xcb\xa4\x7c\xe8\x1a\x8f\ \x9d\x6b\x87\xf6\x27\x52\xac\x4e\x84\x6e\x37\xac\x28\x81\x35\xa1\ \xab\x7e\x3c\x78\x86\x0b\x58\xab\x6b\x65\x23\x18\x40\xab\xef\xa2\ \x36\xd8\x32\x0f\x59\x54\x27\x91\x56\x60\xe1\x47\x6a\xf3\x61\x81\ \x0b\x40\xab\xc6\x27\x5b\xcc\x52\xc7\xec\x03\x1e\xef\xdb\x1c\x81\ \x97\x73\x1c\xd5\xf5\xf1\x31\x6d\x42\x8a\x8d\xa9\xc9\xa4\x92\x21\ \x82\xa8\x0f\xf0\x06\x38\x88\x54\xc2\xc9\x32\x64\xe3\x3b\xcd\x03\ \xc1\xb8\x7a\xb2\xaf\x1c\xb7\xc1\x96\xc5\xb8\x06\x1a\xd5\x0b\x44\ \x74\xcd\x35\xe0\xb4\xdc\x18\x7c\xe6\x3c\x85\x6a\x30\x10\x69\x78\ \x52\x8a\xf9\x9f\x89\xfe\xd0\x32\xae\xc9\xb5\xa1\xf9\xb3\x82\x45\ \x3e\xd0\x92\xd6\xdc\xc4\x04\xb3\x63\x43\xf6\x9f\xa6\x69\xb0\xf0\ \x18\x5a\x82\x9c\xb5\x29\xc7\xa2\x67\x95\x04\x54\x14\xb7\x3b\x92\ \x08\x38\xe4\xb4\x84\x93\x5a\x66\x58\x18\x6c\x0b\xab\x44\xcf\xd4\ \xc8\x09\x9e\x20\x9f\xf1\x82\x8a\x1f\x2b\x6b\x88\x4f\xa6\x53\x6a\ \x86\x18\xa0\x8a\x9c\x09\x47\xec\x60\xf7\x5e\x99\xab\x8e\xeb\xd4\ \xff\x48\x8d\x98\xc7\x21\xa7\x35\xc2\xe1\xe7\xc7\xb8\x6d\xd6\x50\ \x60\x4b\x6f\xc2\xbb\xb9\x00\x7f\xc0\x1c\x86\x6f\xec\xdd\xd4\x95\ \x04\x84\xff\xae\x9e\xc1\x90\xf0\x9b\xf0\x1a\x6c\xe1\x48\x16\x9e\ \xe9\x5a\xa6\x73\xba\xe7\x2d\x82\xdb\x8e\xf8\x4e\xd8\x52\xd6\x2c\ \x51\xfa\x32\xd9\xd2\x05\x06\x9d\xa3\xcb\x22\x86\xde\x0e\x22\x41\ \x9a\x09\xd4\x9c\x38\x40\xfa\xa3\x62\x31\xd5\x72\x84\xc3\x07\x65\ \x92\x9f\xc4\xbd\x3a\xb4\x7c\x2a\x49\xd4\xe4\x04\x15\x8e\xad\x19\ \x89\xd2\x89\xad\xec\x5f\xd6\xa3\x25\xe4\x54\x57\x8e\xf1\x3b\xbf\ \xce\x65\x66\x89\xc5\x9d\x3b\x3b\x99\x6e\x77\xa2\xc1\x61\x24\x06\ \xdc\xe9\x0b\x98\xce\xdf\x28\xd9\xf5\xa5\x8e\x6b\xb6\xdd\x25\x0c\ \x2b\x59\x6c\x54\xc7\xf8\x76\xae\x93\x85\xa2\x47\xbe\x89\x80\x83\ \x26\x98\x86\x53\x0a\x52\x8d\x3c\x52\x69\xac\xe5\x60\x12\xc2\x2a\ \x4f\x11\xf4\x56\x15\x44\x8f\x53\xf3\xed\xc9\x87\x7f\xf1\x27\xf8\ \xf7\xa5\x16\x02\x7b\xf2\x08\x60\x09\x18\xba\x8b\x1a\x5a\xb4\x71\ \xa9\xa0\xd3\x16\xdf\x4e\xcd\x6d\x6d\xce\x88\x73\x94\xf5\x76\x27\ \xe4\xc8\x16\x0f\x69\x2e\xea\x23\xad\x73\x84\x6d\xcb\x9c\x01\xb6\ \x05\xff\xd8\x62\x54\x47\x3e\x67\x68\x69\x60\xe1\x2d\x2d\xa6\xa9\ \xa6\x57\x56\x33\x9b\x40\x76\xd6\x26\x08\xa8\x95\x70\x3e\xd0\x33\ \x41\x76\xd8\x57\x47\xc8\x67\x69\x7a\x7e\x91\xf3\xc2\xb4\xb8\xe6\ \xc9\x12\x11\xf3\xb2\xbd\x13\x40\x4e\xd2\x89\x45\x5b\x82\x0e\xb3\ \x59\x25\x89\x0f\x0f\xbc\x19\xf3\x39\x2a\x5d\x4e\xef\x5f\xb6\x5e\ \x31\x26\x34\x7d\x6b\x9f\xae\x19\x5a\x42\x33\xcd\x7d\x45\x55\xe4\ \x69\xfd\xcb\xa0\xc9\xa8\x0e\x22\xba\x4b\xb7\xce\xc2\x4f\xca\x6d\ \x92\x6f\xcb\x66\x29\x5b\xac\xea\x5f\x36\x28\x0f\x4f\x4d\x1d\xf7\ \xb4\x99\x01\x33\x8d\x57\xc9\x69\x3c\xb5\xa5\x91\x48\xa7\x32\x22\ \xe7\x53\x46\x4e\xd8\x3a\x0a\x3d\xaa\x64\xc2\x38\xee\xbf\x56\x49\ \x65\xbd\xb5\x1d\x1a\x5a\x19\x35\x66\x79\xe0\x61\x0b\x93\x65\x1d\ \xe0\x2c\x4c\x58\xf9\xc7\x0d\xa2\xd0\x40\xd9\x66\xac\x4e\xaa\x86\ \x65\x87\xeb\xa6\x6a\x8a\x7b\xcc\xb1\x3e\x39\x47\x25\x10\x77\xa3\ \x6a\x66\x00\x1b\x81\x15\xe7\x4d\x66\x03\x4a\x52\x13\x77\xd2\x46\ \x64\x13\xef\xc4\x86\x62\x43\x19\x71\x9b\x5a\x98\xd6\x3c\x59\x3b\ \xa7\xf9\x35\xd4\x91\x52\x64\x5d\xdc\x02\xeb\x95\x96\x6e\x6f\x4f\ \x67\x47\x3e\x66\x88\x1a\xcc\x25\x46\x2e\xbc\xe7\x4c\xb2\x96\x89\ \x1d\x95\x1a\x94\xec\xf5\x88\xc6\x95\x14\xb0\x0f\xa9\x2d\x95\x12\ \xcf\x46\x07\xbe\x20\x82\x66\x49\x27\x9e\x5a\xce\x9a\x3d\xd5\x48\ \x29\xed\x32\xb5\xbe\xef\xc7\xd5\xb7\xf9\x2d\x25\x1d\xeb\xde\x81\ \x63\xee\x18\x4e\x8e\xec\x94\x09\xb2\x29\x45\x30\x37\x5a\xc6\x5e\ \x95\xec\x3c\xc5\x12\xb4\x65\x66\x94\xb2\xe5\x3a\xfa\x19\xd5\xbf\ \x53\xae\xd3\xcc\x0f\x8b\x05\x1d\x5a\xc6\x00\xb6\x90\x93\x12\x5a\ \x3a\x2d\x67\x92\x39\x2c\xd2\xc0\x2f\x6a\x36\x9f\xc2\xc7\x5a\x61\ \xf4\x2e\x60\xea\x71\xde\xc1\x89\xfc\x2c\xce\x42\x54\x98\x8d\x3a\ \xe1\x19\xa6\xca\x7d\x6a\x5a\xba\x0b\x0f\x97\x27\xc0\xae\x4e\x35\ \x97\x4d\xc9\x93\x74\x82\x31\xcf\x96\xb4\x11\x6e\x34\xc4\x96\x9d\ \xb0\x07\x9f\x31\x74\x2d\xe5\x1e\xbc\x6a\x88\x06\xdd\x00\xaa\x8b\ \xcc\x98\x7b\xda\x1c\xb4\xcd\x16\x7a\xe5\x6d\x6a\x9a\x89\xce\xee\ \xa6\xf5\xd0\x94\x72\x12\x51\x43\x35\xb3\x43\x0d\xab\x07\x14\xe0\ \xbc\x3a\x88\x20\xda\x44\x46\x8c\xb0\xf7\xbe\xd7\xa1\x25\xd2\xe6\ \x54\x37\x76\x37\xae\x85\xcd\x44\x9b\x91\x7b\x36\x9b\x8d\xc4\x27\ \x81\x8b\xa4\x45\x4d\x30\x5b\x48\xb1\x55\x73\x9e\x4a\x15\xbd\xd0\ \x11\x3b\x90\xe0\x60\x1b\xd4\xb4\x94\xd9\x68\x16\x6a\x66\x4a\x5f\ \x86\x1c\x9d\x09\x93\x7d\x72\xb6\xde\xca\xe6\x7c\x66\x6b\x06\x46\ \x49\xec\xbc\x35\xfd\xcb\x86\xf4\x14\x3d\x7e\x34\x0a\xe4\x12\xe0\ \x79\xf4\x1e\x44\x27\xb7\xb0\x9a\xc5\xff\xb0\xac\x71\x2d\x39\xe0\ \x6f\xe3\xee\x56\xa8\xdd\x20\x4b\x6c\x06\x06\xd3\xca\x4d\x5d\x96\ \xb7\xc3\x9a\x56\x06\xdb\x1a\xcb\x0b\xa5\x49\x97\x81\x5a\xf3\x48\ \x34\xf6\x71\xd9\x8d\x2f\x0f\xb3\xec\x1c\x94\x4e\x68\x5c\xd2\x04\ \xcb\x06\x6c\x00\x1f\xfb\xb9\x7c\x36\x8b\x95\xaf\x04\xf0\x74\x35\ \x33\x8a\x05\x1c\x90\x76\xf0\x6f\x44\xd7\xe5\x05\x1e\x66\x5a\x14\ \x4c\xc1\xa9\xbb\x6c\x0a\xa8\x4c\xcc\x4b\x06\x74\xa0\x19\x4b\xac\ \xf3\x1f\xe6\xa1\xa5\x0c\x13\x0b\xce\x78\x74\x19\x65\xa2\x84\x81\ \x8d\xed\xa2\x81\x51\x8b\x8d\x22\x18\x98\x5b\x5b\x39\xa0\x84\x41\ \x8c\x2a\x86\x61\xad\x90\x0f\xe6\xdb\x76\x01\xe6\x4d\x9c\xe1\xd1\ \xbd\x28\x6c\xf2\x0b\x2c\xc7\x81\x25\x8c\x24\xa5\xe6\xc8\x48\x8a\ \xaf\xc4\x71\xbb\x64\x3c\x98\x0b\x8d\x93\x71\xec\xcc\xfc\x67\xf3\ \xc5\xe7\xff\xb4\x5d\x48\x39\x69\xf8\xd4\x97\x72\x8a\xec\xfd\x23\ \x4a\x18\x0f\x51\x70\xfe\x4b\x5b\xde\xad\x14\x7d\x1c\xa3\x83\x93\ \x78\x8a\xa3\xeb\x9a\xe2\xe8\x5e\x15\x8c\x90\x97\xfa\xe6\x79\xf1\ \x54\x1d\x58\xd2\xeb\x56\x01\x26\xfe\xe2\x6e\x45\xcc\x56\x24\x22\ \xfd\xcb\x36\xa9\x27\xcb\x7a\xd2\xba\x83\xee\xa2\x12\x0f\x57\xbb\ \x0b\x8e\xfa\xdc\x98\xb7\x76\x35\xd1\x1a\x62\x2e\xbd\x21\x14\x33\ \x15\x07\x67\xed\x7a\x72\xbf\x3d\x4e\xe4\x20\x7a\x51\xba\x8a\xeb\ \x63\x3d\xc8\xb2\xd2\x2a\x6f\xab\x19\xa0\xf8\x49\x4c\x3b\x10\xdd\ \x6a\x56\xac\x94\x62\xe6\xc5\xa6\xb3\xe5\x02\x26\x8c\x66\xac\x1b\ \x15\x73\x17\xe8\x88\xfa\x3b\xe5\xd9\x6c\xdb\x33\x03\x5a\x6d\x26\ \x03\x2b\x8c\xf5\x43\x5d\x19\x01\x9d\x90\xcc\x6e\x5d\x7f\xdb\x70\ \xce\xd0\xe5\x84\x11\xd7\x12\x5b\x15\x83\x99\x3f\xd7\xb2\xf3\xd5\ \xc7\xfb\xc1\xbe\x02\x5a\x8b\x9d\x6b\x2c\x27\x05\x5f\x88\x07\x30\ \xda\xc9\x11\xaa\xd9\x4a\xc6\xea\xa4\x94\x84\x63\x44\x76\x0f\x7b\ \x50\x28\x26\x69\x24\xe8\x28\x0a\x20\x7f\xb0\x8f\x36\x6d\x3b\x67\ \xd9\x08\xe4\xc8\x26\x4a\xd2\xe9\xb2\xdd\xe9\x58\x97\x9a\xa5\x50\ \x1b\x6a\x1a\xd4\x69\x2d\x6f\x14\x98\xb2\x58\x89\xca\x4e\x55\xcc\ \xa9\xed\x4c\xb3\xc1\x65\xd5\x4c\xbb\xb6\xcd\x22\x40\x83\xb9\xfc\ \x71\xa2\x69\x1b\x2c\xe0\xb8\x65\xb6\xc6\x7a\x36\xf3\x62\x63\x4a\ \x0a\xd7\xc8\x4f\xe5\x60\x3b\x58\x25\x27\x18\x96\x46\x65\xc6\x53\ \x4c\x6f\x14\xba\xbf\x47\x49\xdd\xb4\x43\xd4\xdc\xd7\xec\x9e\x0a\ \xf3\x59\x6c\x12\x90\xd3\x4d\x39\x10\xd5\xd5\x0c\xa7\x9d\x78\x31\ \x3b\x01\xf5\x30\x47\x31\x85\xb9\x2f\xd9\xd6\x18\x9b\x73\x50\x89\ \x60\x8c\xec\x05\xaa\xba\xf5\x93\x65\xc2\x6e\x0e\x8b\x5c\x34\xc8\ \x7f\xbb\x8c\x93\x6c\x17\xad\xde\xa6\x24\xf2\x06\xf6\xe7\x21\x0e\ \x90\x40\xec\x27\xe5\x81\xb7\xe5\xa4\x7e\x43\x6a\x5c\xba\x88\x12\ \x2a\xf9\x63\x59\x8b\x18\xd9\x2e\xfe\x62\xd7\xa2\x9c\x14\x41\x5a\ \x67\x97\x5b\xb2\xd5\xbd\xca\x94\xfb\x34\x99\x4a\x03\x79\xaf\x37\ \xf7\xea\xce\x80\x52\x97\x85\x0e\x30\x52\xd0\x73\x8f\x3a\xac\xcb\ \xfa\xa4\xc4\x5d\x15\xbb\x71\x08\xc3\x84\x0d\xa2\x01\xdb\xb9\xa0\ \x7f\xf0\xf8\x9e\xb6\xa3\x36\x0c\x0d\x1e\xdf\xd9\x3d\xb0\xba\x63\ \xb0\x7b\xc3\x7a\x71\xcb\x7a\x2f\x1d\x72\x3a\x33\xf6\x21\xa2\x42\ \x3f\xf9\xd5\x24\xb7\x5a\xe6\xcd\x99\x76\x6d\x85\xf0\xa0\x36\x3a\ \x4a\xad\xc4\xae\x16\x33\x50\x27\x5b\x4f\x71\x57\x15\x43\x99\x84\ \x4f\x67\x9d\x84\x5d\x52\xd7\x2c\x6c\xd6\x1f\x25\xf3\x2b\x5b\x8a\ \x66\x8a\xcc\xbc\xad\x62\x7a\x4d\x6c\xbc\xf9\x67\xf7\x58\x5b\x32\ \x89\xf5\x45\x6a\x68\x93\x3a\xb4\x94\xa6\xb3\xfb\x28\xf2\x3b\x67\ \xbc\x99\xcb\x2e\x1e\x4c\xf8\x74\x65\x63\xb0\x62\x58\x8f\xe4\xee\ \x5e\x80\xf1\xe6\xd4\x04\x70\x1b\x7f\x58\x8b\x98\x21\x68\x6a\xd8\ \xd6\xc6\x18\x9a\x85\x40\x63\x43\x0b\xf5\x73\x4b\x3a\x2e\xee\x2b\ \x62\x6b\x74\x45\x31\xaf\xa7\x45\xad\x06\x98\xb5\x53\xe3\x5a\x11\ \xb3\x91\x4f\x9b\x28\xf3\x97\x32\x1c\xf5\xe3\xb2\x51\xa0\xfe\x46\ \x32\x38\xbe\xfe\x46\x39\xe5\x53\x7f\x0e\x71\xb0\xc8\x58\x3c\x46\ \x86\xf6\x29\x98\xa8\x31\x87\xab\x45\x5d\x5b\x2c\x95\x1d\x93\xa5\ \xc4\x98\x0c\xdc\xdd\x0f\x56\x14\xb5\x43\x5b\x7c\x26\xdb\x2d\xc3\ \xed\xa9\x58\x5e\xf1\x6d\x30\x08\xd5\x35\xc7\x1d\x7f\x68\x6d\x3e\ \xe6\x57\x5f\x12\x72\x70\x9b\x22\x39\x87\x05\xc6\xc2\xc9\x22\x8a\ \x81\x15\x33\x5a\xc1\x9e\xd0\xd2\xc3\x9a\xb9\x27\x0a\xfb\x4f\xba\ \x2a\x17\xb8\x24\xf7\xd4\xf4\xf5\x97\x74\xd5\x9c\x43\xb8\x70\x2b\ \xb1\x02\xe5\x2c\x43\x83\x44\x36\xa7\xed\x15\x5e\xdf\xb8\xa4\x55\ \x92\x53\xf8\x4a\x62\x52\x52\xb6\x81\xa6\x92\xa3\x67\x58\x87\xa6\ \x2b\x6e\x4e\x64\x83\x34\x0f\x7a\x0e\xb4\x13\x24\x16\x50\x33\x4d\ \x46\x51\x90\x0b\x2c\x90\x23\x44\x02\xdd\xca\x01\xd7\xc9\x6c\x53\ \x83\x05\x7f\xe0\xd6\xe1\x0e\x46\x0c\x6d\xab\x34\x22\xab\xcc\xdf\ \xb5\x18\x74\x53\xf5\x1e\x23\xac\x9e\xaa\xd8\x58\x4a\x19\x27\x2a\ \x37\xcf\x21\xa7\x61\xe8\x5b\x95\x49\x2c\xa0\x28\xe9\x2c\x75\x95\ \x17\x83\x5f\x6a\x81\xa7\x06\x20\xea\x1c\xaa\xb0\x33\x04\x8b\xca\ \x23\xcc\x59\x5d\x65\x46\x0d\x7b\x81\x1b\x70\x37\x20\x80\x60\xe3\ \x19\x1c\x66\xc4\x53\xbc\xc0\x3c\xc5\xac\xae\xb2\xec\x12\x81\xc9\ \x55\x64\xbe\xe8\x75\x1e\x3f\x47\xbb\x63\xf0\x20\xee\xa4\xd5\x5c\ \x0e\x0b\x3c\x49\x25\xa3\x16\x9a\xa9\x23\x2c\xf8\xea\x94\xae\xf2\ \xac\xf9\xb4\x7a\x9e\x81\x7b\xce\x67\xc8\x79\x4d\x8c\x7e\x5b\x15\ \x3c\x9d\xa5\xcc\xa2\xe2\x38\xa5\xc5\x36\x2b\xc9\x71\x7f\xd4\x40\ \x3b\x23\xa6\x2b\x49\xc1\xa7\xaf\x44\xaf\x8e\xc4\x5d\xad\x2d\x78\ \x57\x68\x5d\x7c\x38\xc6\x48\x65\x2c\xbc\x9c\xa2\x88\x88\x39\x43\ \xd6\x48\xb1\x9d\x57\x35\x24\x90\xfc\x32\x39\x39\x61\x06\x48\x44\ \xfb\x3b\xdb\x97\x76\xea\xea\x38\xf3\x24\xf7\xbf\xc4\xb2\x05\x66\ \x83\x6c\x55\x4c\x4b\x36\xbd\x4c\xe7\x3b\x22\x22\xb3\x08\xfa\x98\ \x2f\x74\x85\xd0\xa2\xe9\x93\xe2\x8c\x10\x30\x8d\xc0\xf8\xd4\x4c\ \x90\x2d\xc8\x9b\x95\x0b\x4f\xc0\x5c\x1b\x2f\x5d\x4b\xa5\x68\xc4\ \x4a\xe1\x29\xf0\xbf\x58\xb5\x69\xcf\xe0\x56\xa1\x09\x7e\xcf\x5b\ \xfa\x69\x9a\x68\xd1\x86\x85\xc0\x4c\x1b\x81\x1c\xc8\xf8\x72\x1e\ \xab\x9f\x78\x25\xa6\xd6\xb5\xcc\xb6\x13\xf5\xbc\xe0\x09\x60\x1c\ \xc9\x4c\x42\x74\xcb\x81\x7b\xd8\x5d\x0f\x63\xcf\xb9\x71\x59\x57\ \x65\xe6\xf1\x46\x7a\x1e\x50\x72\xf9\x94\x51\xe4\x8e\x9c\x17\xa2\ \xed\x21\x9b\xd1\x16\x79\xc1\x9c\xcf\xb6\xfb\x55\x88\x70\xac\x48\ \x39\x03\xa4\xf8\xb4\x92\x31\x44\x7d\x17\xba\xad\x55\x88\xaf\xb2\ \xa9\x5f\xf1\x54\x91\x35\xcd\x32\x36\x53\xb1\xfb\x1d\x51\x8c\xc4\ \x98\x34\xa2\xea\x39\x61\x8f\xfe\xf3\x5c\xac\x47\xb3\x05\xdf\x6f\ \x83\xbb\xdf\x0c\x68\xe0\x53\x9b\x64\x8d\x6d\xaa\x0c\x52\x5c\xa4\ \xaf\x30\xaf\xfe\x24\x72\x7a\x73\xec\xe9\xee\x54\x57\x12\x9a\x9e\ \x64\xde\x1d\xc5\x7b\xa6\xfd\x66\x49\x0f\x59\x32\x50\x79\xea\xcb\ \x9b\xd5\x95\xac\xac\x17\x5a\x5e\xe7\x1d\x67\x5b\x2f\xb5\xb0\x60\ \x4f\xa8\x41\xd0\x71\xe9\x95\x9b\xb3\x4e\x5f\x09\x75\xe4\x74\xf1\ \x3a\xd9\xe2\x75\x42\xfd\x9d\xcc\x65\x89\xfe\x66\x39\xd2\xd0\xa0\ \x29\xbc\x14\x6b\xd9\x7d\x9b\xc3\x7d\x94\x46\xde\xac\x25\xe1\x2c\ \xae\xd6\x33\x98\x87\x94\x42\x82\xae\x7a\x09\x47\x03\x38\xb6\x36\ \x1e\xcf\x2a\x4a\x52\xeb\x55\x0c\x7a\x47\xce\x35\x6d\x60\x3a\x51\ \x16\x51\x0f\x41\xe7\x89\x19\xec\xd4\x32\xa4\xb3\x8a\x7e\x97\xd4\ \x87\xd7\xb4\x09\xa4\x85\xc3\x6d\x04\x37\x8d\xc9\x06\xa8\xc9\x83\ \x63\x6a\xee\x70\x4f\x1b\xbf\x88\x8b\x69\xac\x52\x7b\xde\x30\x34\ \xcb\x30\xe0\x17\x75\xe1\x5f\x5b\x18\x99\x20\xae\xde\x40\x8c\x51\ \x86\x75\xb2\xe2\xc1\x73\xc2\x6b\xdb\x30\xf3\xbf\x13\xb7\x2e\xee\ \x0f\xe0\xdf\xae\xa8\x03\x82\xa8\x61\x31\x19\x5b\xdc\xaa\x99\x6f\ \x45\x04\x07\xbc\xcf\x4f\x66\x0e\x5f\xa6\x1f\x25\x2f\xee\x37\x10\ \x88\xd2\x84\x6a\x8c\x61\x11\x2c\x2e\x63\xc3\x70\x21\xb4\xe2\x96\ \x71\x96\x53\x88\x3b\xd5\x5c\x42\xd6\x93\xfe\xed\x66\x58\x81\x28\ \x62\x34\xa2\x40\x72\x4d\xa4\xfb\x02\xa3\x2b\xe8\xef\xe0\x87\x6f\ \x37\x9c\x27\x19\xc2\xd6\xb8\xd9\xef\x1e\xcd\x80\x4c\x54\x18\xdd\ \x18\x32\xfd\xf3\x4c\x43\x17\x17\xd0\xb1\x3e\xa6\x61\xa6\x64\xd9\ \xb9\x3c\x40\x44\x0e\x17\xe2\xbe\x0a\x68\x3c\x7e\x94\x5c\xe8\xaa\ \x35\x04\xec\x50\x29\x40\xc9\xad\xa2\xd6\xc8\x0c\xe0\xb4\xf5\xfd\ \x42\x6e\x29\xd3\xcc\xeb\x5c\xde\x3d\xc5\x6f\x03\x98\xdd\x69\xce\ \xb8\xa5\x01\xc5\xd0\x0b\x6c\x9c\xa8\x20\xd6\x29\x58\x98\x3c\x66\ \x38\x5c\x85\xbd\xd6\xc9\x08\x75\x16\xf6\x5d\x32\xc6\x90\xdf\x20\ \x66\x13\xc7\xba\x23\xc9\x66\xaa\x47\x29\xe4\x06\x3f\x56\x10\x8e\ \x64\x46\xa9\x58\x86\x18\x7c\xa7\x93\x44\x66\xc4\x2e\xe7\xe9\x88\ \xcf\x0c\xa9\x57\x4b\xaa\x23\x4c\x2b\xa9\x04\x88\x3a\x7c\xc0\x22\ \x16\xab\x39\x3f\x58\xce\xbf\x78\x9d\x9a\x11\xd5\x2e\xe0\xc7\xef\ \xaa\x59\xa2\xff\xb2\x07\xbe\xaf\xbb\xa9\x07\xef\xc2\x0c\xac\xaa\ \xbf\x53\x4b\x6c\xdd\xa4\x26\x47\x15\xdb\xd1\x67\x94\x68\x6f\xd4\ \x7a\xcb\x47\xf8\x68\xd4\xd8\xe6\x69\x53\x4d\x3c\xbc\xdd\xc2\x68\ \xa8\x2b\xa5\xc9\x86\xb0\x41\x84\x9c\x93\x19\x1e\xff\x1e\x25\x47\ \xe8\xb7\x16\xea\xe6\x41\xd8\xe0\x4d\xd5\x61\xd4\x07\xb0\xdf\xb3\ \x2b\xf7\x32\xb6\xe1\xa9\xec\xd8\xef\xe6\xc1\x55\xd3\x4f\xcc\xa0\ \xbd\xd0\x83\x3c\xaa\x30\x01\x14\x63\x1c\xe3\x2c\xd6\x32\x33\xb2\ \xd2\xbf\x9c\x01\xce\xa6\x6e\x2b\x9b\xd1\x9e\xb6\xac\x1f\x23\x8e\ \xea\x24\x90\x38\x4d\xe1\x4b\xf2\xa8\xac\x66\x7c\xfa\x8d\x91\x81\ \x3b\x60\x59\xb4\x89\xb7\x39\x0e\x59\x1b\xe5\x8c\x49\xb5\x9d\xca\ \x70\x7e\x54\x62\x20\x5a\x7d\xa0\xce\x72\x99\x93\xa9\x65\x7d\xdc\ \x61\xd9\xab\xee\x92\x0d\x39\x45\x0d\xc2\x7e\x70\x6a\xc9\x1d\xd3\ \x38\x33\x1d\xd8\x6d\x23\x9b\x64\x3d\x03\x07\x92\x5f\xbb\xef\x33\ \x77\x4a\x77\xa8\x93\xf8\x6e\x47\x26\x91\xad\x1b\x99\x99\x9b\xed\ \x44\xa6\xbb\x53\x35\x5b\x65\x27\x25\x93\x88\x88\x2d\x86\x46\xd8\ \xaa\xec\x6f\xb7\xd7\x11\x5d\x39\x9d\xa9\x93\x76\x86\x03\xb1\xcf\ \xa9\x6d\xcb\x5f\xd7\xb8\xc4\x8e\xc2\xe2\x43\x61\xfb\x52\x8a\x0c\ \x07\x32\xa8\x69\xea\x08\xf5\x71\x04\x59\x1b\xd7\xe3\x22\x4c\x88\ \xab\xd1\x84\x9c\x93\x46\x41\x9d\xcb\xb4\x50\x4a\x77\x79\x22\x5f\ \x34\x85\x60\xdf\x5d\x3b\x25\xf6\x55\xae\x7b\x72\xec\xe1\xb7\x09\ \x82\x80\xfd\x47\x4e\x5c\x71\x4b\x19\xf4\x11\x2c\x7c\x94\x58\xf6\ \x5c\xf6\x3e\x3a\x50\x6c\xe3\x32\x2f\xcb\xcc\x40\x72\xaa\x6e\xe2\ \xc3\xcf\x96\x6b\xf7\x6f\x5c\xe2\x32\x06\xb6\x80\x8c\x42\x23\x4d\ \xe5\x8c\x41\x94\x7c\x25\x9b\x92\x13\xd8\x83\xeb\x70\x21\x32\xd8\ \xab\x29\x46\xdc\x40\x88\x57\x21\x7f\x91\x3b\xa6\x59\x5c\x70\x87\ \x62\x9b\x3d\xcd\xe6\x12\x41\xbb\x78\x50\x56\x55\xcc\x19\x95\xe5\ \x01\x54\x38\x9e\xd9\x53\xbd\xd4\x70\x66\x4f\xc3\x62\xd1\xcc\x9e\ \x06\x29\xee\x32\xed\x55\x64\x5f\xd5\xf3\x1b\xcf\x1b\xd7\x20\xbb\ \x96\xdd\x1d\x71\x9c\x62\xee\x06\x66\xba\x0f\xca\x7e\x6d\x32\x38\ \xa4\x89\xdd\xdd\x13\x77\x69\x72\xa5\x4f\xae\x68\x3d\xc4\xc0\xc2\ \x8e\x55\x43\x92\x33\x93\x13\xf2\xa4\x98\x24\x76\x26\xe4\xd8\x03\ \xac\x6b\xa7\xe2\xac\x59\xa2\x15\x6e\xac\xfb\xe0\x98\x6a\x3b\x9e\ \xda\x39\x30\x3c\x0f\xe2\x31\x95\x10\xbb\xec\x69\xe3\x6f\x14\x11\ \xa1\x5a\x8c\x97\x72\x01\x05\x0c\x5b\x8b\x55\x8a\xd9\x44\x8c\x0b\ \x52\xde\xf1\xe0\x64\x0f\xd8\x9d\x09\x18\x16\x4c\x6b\xa9\xb1\xbf\ \x82\x4d\x59\x72\xe8\xaf\x60\xff\x77\x22\xea\x36\xcd\x5d\xd6\x10\ \xb3\xa1\xb7\xba\x38\xec\xd7\x03\x72\xaa\x51\xbf\x1e\x00\xb3\xb8\ \x43\x8c\x12\xb7\x41\x85\x50\x5e\x5e\xa1\x7b\x05\xfb\xdf\x9a\xb1\ \xbf\x1e\x38\x3b\x1c\xfa\x2b\xe0\x5e\x9c\x4f\x8c\xcd\xf0\xba\x34\ \x7d\x82\xa9\xc1\x82\xce\xa7\x1e\xe5\x2b\x5c\x59\x3b\xc8\xd7\x19\ \xe2\x1b\x21\x21\xbe\x2c\xc2\xd7\xd3\xb2\x99\xb0\x69\xfe\x62\xc6\ \xf4\x89\x30\x2f\xf8\xf3\x6e\xf3\x51\xef\xa4\xd4\xa1\xa5\xb3\x79\ \xc3\x87\xdc\x77\x28\x0c\xd8\x03\xa5\x80\xfa\xeb\xa9\xbb\x9f\x40\ \xd0\xa3\xc9\x88\x54\x64\x30\x17\x0b\x2e\x2c\xb7\x4f\xd6\x15\x60\ \x62\x85\x97\x92\x2a\xa8\x66\x18\x11\x97\xaa\x65\x80\x84\x01\x09\ \xdb\x94\x1e\x94\x2a\xa0\x9c\x5e\x26\x79\xf0\x06\x89\x10\x11\xe6\ \x85\x0d\x76\x61\x10\xab\x60\x67\xc6\x45\x37\x4b\xbc\xa3\x03\xb9\ \x4f\xf2\xe1\x14\x54\xd6\x5a\x83\xda\xed\x71\x80\xd4\xb4\xa6\x9d\ \xea\xc5\xb8\x3a\xf5\xdf\xb6\x95\x42\xb3\xcd\x3a\x57\x9b\x75\x25\ \xb4\xe9\x75\xb5\xe9\x2d\xa1\xcd\xa0\xab\xcd\x60\x81\x36\xb5\xac\ \xcd\x30\x9a\x74\x5c\xe2\x46\xa0\xdd\xf0\xa4\x61\xda\x16\x05\x4d\ \x03\xd5\x68\x25\x34\x5b\xc5\x1c\xc1\x6c\x49\x78\x1e\x01\x39\x8f\ \x93\xbd\xf1\x36\xfb\x07\x13\x4c\x73\x96\x01\x9e\x64\x0b\x71\x78\ \x55\x60\xb9\x1c\x67\x3e\xc1\x50\x57\x42\xab\x55\x24\x50\xc8\xdc\ \x6b\xb2\xa0\x8d\x09\x29\x83\x68\xf6\x2a\x83\x49\x03\x26\x36\x8b\ \xac\x7b\x35\x89\x69\xfd\xb6\xa3\xa5\x6c\xdd\xb3\x51\x19\x49\xb2\ \x9c\xd5\xf2\xcc\x66\xa7\x30\x2b\x9a\xc9\x80\xb3\xe4\x1b\x03\x29\ \x4c\x99\x94\x91\x19\xdf\x6d\x1f\xcb\xda\xca\xe1\x55\x83\x66\x60\ \xc4\xbc\xc6\x25\xf3\xa4\x84\x9c\x21\xa7\xf4\x30\x09\xdc\x4a\xb6\ \xac\x5c\x3c\xbc\x6a\x65\x76\xd5\x20\x0e\x9a\xcf\x61\x97\x4d\x19\ \xbe\x1d\x53\x74\xd2\x64\x11\x31\x4a\x4a\x23\xca\x04\x7c\x90\x18\ \x93\xb1\x1b\x99\xa2\x13\x87\xce\x8c\x26\x65\xf3\x99\x84\x91\xa7\ \x59\xce\xa4\xb4\xac\x6f\xcd\xb5\xf8\xac\x8f\xe3\x94\x8a\xf0\x1c\ \x4d\x4c\x07\x3b\x63\xbb\x11\x43\x6c\x16\x1c\x7f\xc2\xcc\x69\x36\ \xeb\x32\xf3\xa6\x99\x99\x90\xfc\x81\x17\xb1\x0f\xf9\x61\xb4\xb3\ \xa7\x81\x18\x6e\x01\xf3\x93\xb8\x41\x89\x56\x28\xbf\xde\x7c\x8d\ \x51\xe2\x06\xf5\xa8\x9f\x85\x11\x59\xb2\xbe\x6d\xb3\x69\xcb\x4c\ \x52\x2b\x43\x97\x96\x31\x70\xe2\xac\x61\xd0\x46\x2d\xbb\xb3\x4e\ \x2e\x3d\xed\x9e\xc2\x6d\xba\x3c\x4c\x93\xf3\x09\x5a\x54\x93\x16\ \x69\x97\xa9\x29\xd2\xa6\xa7\x95\x8c\x2a\x67\x7c\x5a\xd5\xa3\x76\ \xd2\x62\x94\xf9\x14\xf1\x6e\x5b\x15\xed\x4a\x66\x14\x48\xc2\xa7\ \x29\x9e\x78\xa7\x33\x4c\xa8\x3d\xc5\xa4\x6f\x61\x4f\x6b\xc8\x88\ \x28\x13\x72\x9a\x49\x83\xed\x70\x58\xfb\xb6\xeb\x20\xba\xb2\x8a\ \x52\xc8\x1d\x1c\x1d\xe9\x98\xd4\xd5\x54\x4a\x3c\x27\x4e\x51\xb1\ \x53\x49\xfb\x0d\x64\x0e\xf1\xbd\x4b\x93\x7d\x37\xea\x8b\x63\x25\ \x86\x20\xf9\x21\xea\xe8\x2c\xda\xa9\x8c\xcb\x19\x79\x54\xd6\xfd\ \xba\xc4\x93\xa1\x20\x9a\xd8\x50\x25\x42\x1d\x37\xa8\x35\x8a\xa6\ \x8f\xfa\x2f\x59\x94\x4c\xa4\xe2\x14\x97\xb1\x27\x9b\x70\xe6\x9d\ \xac\x68\x4d\xfe\x44\x19\x3b\xe1\x96\x52\x53\x4f\xe7\xb7\x8e\xf9\ \x0d\x20\x8a\x56\x33\xf7\x4d\x8e\x3e\xd7\x2a\xc3\x3a\x95\x22\x05\ \x2d\xa8\x4f\x24\x71\xab\xc0\x8a\x22\x77\x31\x62\xc8\x3e\x2b\x48\ \x36\xeb\x1a\x32\x41\xd4\xeb\x3d\xe3\xa2\xd0\xc8\x91\x72\x56\xce\ \x28\xd4\xae\x51\x70\x3c\x15\xeb\xe4\x4c\x46\x4e\xca\x45\x2b\x86\ \xd6\x8d\xa5\x29\xbb\x29\x30\x06\xc5\xb5\x64\xe1\x75\x1a\x68\x6b\ \xc2\x05\x73\x1a\x69\x7b\x64\xcd\x77\xfb\xf6\x50\xdf\x46\x07\xe0\ \x50\x0f\x0e\x25\xf2\xc5\xa6\x07\xd9\xa1\xf0\x7c\x23\x9c\xa7\xb1\ \x28\x32\x95\xbd\x72\x4a\x9e\x84\xff\xd3\xc5\x67\xaf\x77\x52\xce\ \xa4\x65\xff\x69\x59\x4f\xa6\x25\x8d\x9c\x59\x33\xc2\xeb\x35\x3d\ \x4d\x6f\xa0\x85\xad\x36\x90\x8b\x7a\x95\x70\x45\x4e\x02\xdc\x30\ \x9c\x52\x4f\xca\x17\x5f\xd3\xd0\x86\xd1\xb1\x12\x90\x0f\x6d\xd0\ \xd5\x49\xe1\xc2\x93\x69\x1f\xb0\x72\xae\x72\x33\x38\x80\xd3\xac\ \xfa\x34\x89\x11\x86\xc4\x48\x91\x49\x2a\x69\x76\x4f\x6b\x5a\x33\ \x1d\xd9\x28\xe3\x6a\x3a\x9b\x22\xe7\xb5\xd4\x31\xa6\x96\x46\xae\ \x71\x35\x33\x06\x4b\xe3\x3b\x75\x71\x64\x27\x8c\xe0\xe8\x30\x3e\ \x99\x1e\xd6\xfc\x27\x3c\xce\x38\xa9\x8b\x7a\xe3\xc0\x45\xe5\xe2\ \x3c\x34\x34\x28\xa7\x55\x21\x70\x47\xb5\xf0\xa0\x92\xca\x8f\xe6\ \x4b\xa8\x37\x26\x03\x97\xf4\x3d\x5d\x06\x89\x5b\x2b\xa7\xa3\x41\ \x7d\x3f\x76\x34\x8d\x1c\xcb\xc3\xcc\xb1\x80\x1f\x5c\xc5\xa0\x3a\ \xac\x18\xbe\xcc\xd4\xbd\x98\x54\xe1\x49\x22\x95\x73\x5a\x75\x64\ \xa5\x1b\xd4\xe5\x24\x49\x8c\x2a\xa7\x0a\xad\x26\x61\x5d\x1b\x99\ \x81\x0a\x03\x21\x6e\x53\xbc\x8e\x0a\x0a\xb7\x81\xc5\xac\x02\xed\ \x63\x4c\xf7\xb4\x65\x65\xee\xc2\x29\x86\x1b\x30\x2d\x09\x37\xe5\ \x55\x2c\x5b\xc0\x11\xa5\xc2\x09\x59\x29\x70\x3c\x4d\x67\x11\xfb\ \xb1\xc6\xec\x9b\x29\x36\x35\x4e\x7a\x8e\xe2\x18\x78\x45\x4f\xa9\ \x19\x31\x0c\x9c\xef\xd4\xf6\x76\xe3\x4c\x15\xab\x47\x46\x40\x29\ \xce\x09\x1b\x35\x93\x8e\x0d\xce\xe6\x62\xca\x86\x7e\x13\x50\x85\ \x21\x48\x39\x23\x36\x99\xf2\xc7\xc3\xdc\x9b\xaa\x83\xdc\x65\xd8\ \x8f\xe2\x36\xe2\xa8\x93\x02\x48\x30\xcf\x65\xdf\xb5\xa8\x27\xe3\ \x1a\x26\x00\x74\xf7\x44\xc6\x0d\x5d\x8d\x6d\x55\x58\x20\x8c\xcf\ \x9c\x70\x41\xca\xc8\x0e\xbb\x71\x18\x9c\x2d\x88\x75\x9b\xf4\x98\ \x4a\xe2\x06\xed\x28\x66\x0f\xd8\x23\x09\x55\xd1\xdc\xb7\xce\x80\ \x5f\x6f\xfe\x32\x1f\x67\x60\xd4\xea\xc9\x1b\x33\x26\x67\x46\xf9\ \x30\xcb\x49\xe6\x1e\xdc\xca\xf2\x7d\x04\xfb\xbb\x8c\xac\xe5\x30\ \x22\x0e\xb7\x32\xf3\x71\x8c\x51\xeb\x02\x67\x0b\x35\xc3\x94\xb0\ \x75\x78\x4c\xa3\x5e\x6f\x36\xc4\x96\x52\x21\xba\x9c\xcc\x1a\x3c\ \x70\x25\x37\xb2\x47\x4e\x01\xb4\x78\xb2\x64\xc1\x64\xb1\xd8\x31\ \x98\x2e\xb3\x5f\xbf\xc9\xda\xcf\xb7\xff\x04\xbb\xea\xce\x39\x8c\ \xc6\x76\x54\x5a\x02\xdf\x7a\x27\x9d\xd0\xb6\x94\x1e\xe9\x86\xec\ \x8c\x04\x76\xec\xb8\xa8\x25\x4d\x08\x66\x6f\xf3\x98\x37\x32\x4e\ \x1a\xc1\x11\x91\xc0\xdb\x4c\xe7\x59\xe6\x9a\x6a\x23\xd6\x3e\xb5\ \x15\x14\x21\xec\x9d\x5e\x0e\x01\xbf\xe5\x2d\x44\x39\x66\x4f\xa2\ \x89\xde\x83\xeb\x03\x60\x37\x2e\x11\x4e\x77\x97\x65\xf3\x3f\xd9\ \xb1\x70\xa5\xed\x32\x11\xe1\x98\xa1\xe5\xc5\x77\x59\xa7\xe5\x35\ \x45\x25\x12\x7e\x9f\x7b\x0d\x02\xc5\xf6\xf7\xec\x4e\x6d\x22\x83\ \xf3\xff\x99\x41\xae\xbe\xfd\xce\xe3\x0c\xde\xb4\x37\xff\xfd\x57\ \xb3\x96\xae\x89\x1d\xed\x68\xc3\x89\x71\x41\x93\xce\x7c\xdc\xe2\ \xd0\xc9\xe9\x26\x2c\x47\xf4\xa4\x0d\x6f\x26\x07\x4f\x0c\x21\x4a\ \x20\x08\x9a\x6e\x24\xb7\xa3\x85\x62\xd4\xc5\xc9\x1f\x4b\x5d\xd6\ \x39\x3d\xae\x10\x75\xff\x55\x3d\xc0\xf1\xd4\x80\x36\x85\x15\x9c\ \xd6\xa3\x01\x7f\xf6\x05\x3c\xd3\x72\x96\xf3\x8b\x1c\xc5\x59\xfe\ \x9d\xf1\xa2\x3c\xa1\x53\x83\xb6\xb6\xab\x08\x7d\xc0\x0c\x17\x2f\ \x3e\x25\xab\x84\x7d\x17\x23\x71\x6f\x9f\x33\x07\xf8\x10\xf5\x02\ \x0c\xd9\xe9\x7e\x22\x8c\x93\xb0\x27\x6d\x88\x8f\x8e\x70\x42\x3a\ \x90\x5c\x62\x9a\xa9\x02\xa6\xbe\x27\xf7\x1c\xca\x96\xb4\x23\x77\ \x16\xe3\xca\x7e\xbc\x31\xba\x33\x23\x1a\xb3\x55\xee\x44\x34\x73\ \xad\x05\xab\x6d\x54\xc9\x18\xcc\x3b\xd0\xfd\xe4\x83\xca\x2e\x77\ \x75\x66\x69\xd6\x8a\x62\xdd\x60\x62\x2d\x27\x93\x38\xad\x16\xb9\ \x91\xf3\xeb\x70\x67\x27\x44\x04\x13\x6f\x4c\x3b\x8d\x98\xea\xe1\ \x14\x7c\x2c\x6e\xce\x71\x5c\xed\xd1\x96\x37\xc6\x00\x0c\x8b\x94\ \x31\x03\x6c\xc9\x74\x85\xfa\xd7\x1a\xbb\x58\x6a\xe2\x40\xee\x72\ \xb1\x89\x83\xbd\x2b\xe4\x16\x0e\xdc\x2e\x0c\xd1\xe7\xa0\xae\x9f\ \x92\x38\xd4\x4c\xe8\xd0\x60\x1a\x85\x49\x93\x66\xbc\x3b\x9f\xcf\ \x67\x1f\x81\x04\xd2\x0c\x22\x90\x15\xf7\x3e\x7f\x0a\x2b\xb1\xa3\ \x62\x08\x07\xde\xbc\x5e\x50\x99\xb8\x46\x3b\xb2\x6f\x51\xb8\x78\ \xda\x4e\x2a\xa5\xe9\x7a\x3e\x6b\x78\xe0\x1c\x48\x58\xad\x83\x8c\ \x09\x3b\x18\x84\x9f\x3e\x7f\x56\x6b\x2b\xcf\x6b\x07\x07\xfb\x08\ \x81\x2b\x96\xc8\xeb\xea\xe2\x0b\xc2\x2e\xec\x64\xa9\xe2\x59\x32\ \x51\x88\x93\x2b\xa7\x34\xb2\x73\x75\x39\x33\x66\xe0\x45\x8b\xc3\ \x4f\x0f\x72\xe7\xd5\xb0\x5d\xcd\xcc\xdb\x08\x95\x9c\x59\x3c\x27\ \x68\xc5\xe8\xc7\x39\x19\xd6\x1c\x0a\xce\x0d\x88\x1d\xd9\xe3\x3d\ \x56\x46\x10\x9a\x5c\x21\x9d\xc5\x43\x94\xa8\x05\x8f\x1b\xe5\x5c\ \x8f\x70\x23\xe6\xa0\x5e\x01\x89\x03\xb2\x6b\x24\x24\x0e\xe0\x94\ \x45\x24\xae\xed\x11\x24\x23\x81\xcd\x2f\xbc\xb9\x07\xec\x48\x32\ \x21\x8f\xb4\xa5\x21\xd2\x87\x95\x66\x40\x76\x70\x47\x57\xaf\xa6\ \x76\x46\x61\xd2\x6d\x68\x93\x23\xcd\x6c\xa5\x90\x23\xc4\xf4\x8b\ \x31\x1c\x42\x93\xe8\x1e\x6c\x4f\xf3\x1e\x8c\x10\x6b\x62\x2c\x9f\ \xd9\x8a\xd7\x57\x4b\x4e\xba\x3a\xdf\x68\x45\x77\x50\xf2\xf1\x13\ \x0c\xa9\xd7\x3b\xff\xe0\x81\x77\xc7\xd8\x88\xd8\xbb\x65\x8e\x03\ \x11\x98\x8b\xac\x96\xc9\x29\xd2\x98\x22\x27\xcd\xe0\x1a\x0b\x97\ \x41\x72\x17\xe3\xbc\x3d\xd5\x59\x42\x4e\x77\x60\x1f\x9d\x82\x12\ \x94\x3b\x5b\xfa\x5f\x8f\xa3\xfb\xf4\x71\x45\x27\x41\x7e\x76\x10\ \x24\xfc\xea\x42\x64\xa5\x70\xff\x16\x58\x77\x64\xba\xd5\x6d\x43\ \x93\xb6\xfc\xd7\xa7\x6b\xdb\x26\x5d\x6b\xef\x77\x32\x76\x3a\x12\ \xe9\x00\x98\x9d\x22\x3f\xd6\x75\x69\xf4\xd7\x2c\x1c\xad\x8a\xf8\ \xa0\x1f\xc3\xc1\x02\xeb\x06\x18\xf7\x93\x87\xad\x94\x3c\x1c\xc0\ \x56\xb2\x8e\xa3\x4c\x98\x75\x4e\x93\x9b\x71\xf9\x71\xd9\x06\xcc\ \x87\xf0\x63\x44\xb9\x31\x1c\xfd\x2b\x64\xb3\x19\x2b\x81\x0c\x4f\ \x27\x63\x48\x66\x27\x9c\x6e\xb9\xc3\x99\xfe\xb6\xd4\xef\x23\xcb\ \x6d\x24\x5b\xa7\x54\x0a\xd3\x11\x17\xca\xd0\x18\xa7\x64\x44\x8f\ \x29\x9e\x95\xe6\x33\xca\xb6\x2c\x11\x2a\x52\xee\x8d\xb6\xb3\xf2\ \x9a\x83\x56\xfa\x90\x28\xdd\x52\xce\xba\xcf\xe6\x2c\xf8\x45\xbb\ \x9a\x65\x76\x65\xa5\x5d\xca\xe1\x34\xe1\xe6\xcd\x3c\xd7\xef\x5a\ \x58\x39\x9a\x9b\x63\x8c\x31\x24\x19\x39\x2f\xc0\x9d\x4c\xcc\x5e\ \x65\xa7\x3f\x33\xb7\xca\x9b\x74\x0d\x24\x7f\x9c\xe1\x11\x3b\x1c\ \xa5\x94\xcc\xa8\x31\xe6\xea\xf5\xe3\x11\x4a\xa7\x93\x0e\x68\xb2\ \x9e\xd5\xd8\xe8\xa7\x14\xf1\xaf\x94\x99\x9f\xfd\x54\x22\xbb\x39\ \xff\xca\x9c\x21\xeb\x9e\xc0\xee\xea\xfe\xee\x76\x39\xa7\x70\xc1\ \xc5\xab\x84\x69\x66\x64\xc6\xe8\x4c\x57\x11\xfe\x35\x40\x4a\xc4\ \xee\x64\x25\x33\x88\xc7\x3f\xc9\x4c\x4d\x14\x50\x66\x92\x17\x77\ \xfa\x5f\x08\x69\xf7\x22\xf1\x3f\x19\x76\xee\x45\xb3\xcb\x17\x4d\ \xfa\x7e\x9d\x33\x89\x74\xf1\x40\xdd\x39\xbc\x0b\x6e\x2e\xa1\xab\ \xc3\xae\x48\x5d\x86\x02\x17\x27\xbc\x71\x57\x04\x46\x23\xd3\x8d\ \xd2\x32\xa9\xd9\xb2\x83\x8d\x92\x1d\x2a\x2d\xa9\xcc\x12\xef\xc5\ \x67\xa5\x2f\x3e\xb6\xfc\xe5\x7c\x4c\xd0\x74\x3d\x77\xc6\x53\xda\ \xbd\x62\x3f\x52\x59\xd7\xe5\x49\x71\x87\xeb\xa7\x1c\xa2\xed\xe8\ \x12\xd9\xe1\x3b\x4e\xbd\x61\xa6\x8d\xc2\x28\x4e\x03\x80\x31\x20\ \x5b\x47\x8c\x86\x3f\xaf\xd8\xa1\x88\x6d\xbb\x73\x61\xc4\xb6\xb7\ \x7f\x7f\x52\xa4\x81\x87\x27\x7f\x3c\xdc\xaa\xa4\x58\xf9\x04\xb2\ \x93\x2d\x97\x36\x7e\x2e\x56\x9e\x9c\xab\xc5\x46\x5f\x28\x09\x06\ \x9f\x65\xa4\x1d\x0e\xad\x0d\x9c\x37\x23\x97\x80\x80\x3d\x0e\xd0\ \xde\xb3\xa1\x5d\xdc\x47\xeb\x94\x12\x2e\xd8\x51\x68\x3a\x27\x05\ \xee\xe1\x4d\xb4\x00\xb2\x93\xee\x43\xda\xfe\xa3\xe2\x5f\x22\xf0\ \x8e\x6a\x37\xbb\x17\xcc\xf3\x0b\x8c\xe9\x80\x92\x9f\x24\x28\xd0\ \x07\x79\x7e\xc0\xbf\x8f\xa5\x25\x67\xd9\xf7\xf6\xc2\x25\x6a\xa0\ \xa1\x23\xfe\xdd\xac\xb5\xcc\xbd\xaf\x22\x33\x01\xa8\x8c\x72\x96\ \xd4\x93\xb5\xc8\x9c\xaa\xd0\xbe\xcf\xe7\xda\x8b\x85\x75\x84\x2c\ \x8e\x4d\xc2\x4f\x88\x4a\x24\xe9\x0d\x7e\x36\x97\x5a\x10\xbb\x37\ \x74\x92\xbf\x48\xe7\x8b\x5c\xca\x4a\xa1\x3c\x9c\xb6\x48\xb2\x27\ \xee\x20\x4f\xd2\x5e\xb8\x1e\x49\x10\x74\x61\x3e\x27\x50\x2c\x51\ \xcf\xf4\x3e\x51\x92\x1e\x17\xb0\xfd\xd8\x95\x46\x96\x58\x05\x78\ \x7c\x6d\xe9\xc2\x66\x85\xbb\x0d\x6a\x24\xd9\xf6\x24\x25\x27\xcb\ \x13\xda\x03\x74\x67\xad\xb2\x0e\x70\x2b\x59\x32\x06\x8d\x24\x66\ \xe0\x0d\xa9\xe6\xab\xa0\xfc\x05\x50\x2f\x39\xf3\xf1\xb3\x3c\x71\ \xf8\x77\xb3\xbd\xc3\x7b\xe5\x84\xb4\x21\x2e\x6d\x96\xd4\x4c\x36\ \x6f\x48\x69\xc5\x18\xd3\x98\xbf\x5b\x37\xfe\x04\xa7\x55\x87\x23\ \x8d\x6d\xf1\xa9\x74\xb9\x09\x51\xab\xae\x86\x26\x50\x8e\x93\x62\ \x49\x96\xc3\x5c\xd1\xfe\x9c\x6e\x54\x9b\xbb\x7b\x7d\x90\x5a\x3a\ \x25\xa4\x36\xc3\x6e\xeb\xb5\xaf\x48\x00\x6c\x29\x03\x3f\x9b\xcc\ \x5f\x86\xa9\x09\xa6\xda\xa3\x73\x8a\x7e\x86\x70\xef\x0c\x27\xe6\ \x73\x87\x26\xb2\xc3\xa5\xdc\x21\x90\xa6\x04\x66\x3e\x02\xec\x70\ \x51\x65\xe3\xf0\xbe\x57\x3d\xbf\x2f\x95\xc7\x77\x3b\x24\x8a\xd1\ \x94\xd8\xc9\x75\x2b\x90\x76\x5a\xc6\x72\x08\x7c\x6b\x3e\x5f\x1d\ \xe9\x67\xf9\x12\xc9\x58\x4e\x40\xfd\xe4\xd5\xb1\x61\x76\xde\x4e\ \xc2\xb2\xb6\x12\xa5\x08\x1b\x36\x8f\x87\xde\x27\xe1\x7f\x9c\x1e\ \xca\xff\xcc\xb0\x2f\x19\xf9\xe7\x34\x9b\x49\x9e\x49\xdb\x28\xda\ \x64\xf6\xdb\xda\x8a\xaf\x2d\x8e\xcf\x4d\xe6\x5a\xa5\x0e\x39\x83\ \x0f\x4d\xfc\x01\xb6\x4c\x35\x37\x2e\x9d\xef\xc5\x71\x5c\x88\xa3\ \x4e\xe6\x48\x23\x21\x11\x8a\x03\x53\x87\x6f\x14\x12\xb9\xc4\xbb\ \x1e\x0e\xb6\x66\x96\x3e\x2f\xdc\x4c\x72\x60\xda\x98\x1f\x64\x63\ \x8e\x73\x85\xa5\xc6\x15\x8a\x3c\x75\xb6\xa2\x6e\xe6\xf9\x0c\x7b\ \x68\x18\x4f\x75\xe3\x52\x18\xc9\x32\xc1\x48\x46\x84\x23\xc1\x5c\ \x70\x2a\x33\x2e\x7a\x83\x46\x3c\xe7\x0b\x6d\xcc\xf3\x19\xcf\xac\ \xd3\x8f\xfc\xe7\x7d\x23\x33\x12\xd8\xfc\x4e\x9c\x95\x18\xe3\xef\ \x47\xb1\x34\xa9\x27\x67\xde\xe2\x9c\xf5\x9b\x06\xd9\xab\x49\x52\ \x13\x97\xad\x58\x96\xa8\xd5\xab\x1f\xa4\x39\x42\xd7\x2d\x5e\xcc\ \x3e\x63\x99\x7c\x52\x24\x86\xdc\xb1\x2f\x90\x37\x50\xc1\x9d\x6e\ \xd4\xc6\x8c\x57\xb3\xdd\x29\x47\x55\xf2\x60\x37\x9d\xd3\x16\x9a\ \x17\x15\xfe\x5d\x8e\xe6\xc3\xa7\x47\xc3\x6f\x2b\xd0\xb1\xd6\x58\ \x0e\x23\xd9\x97\xe9\x3e\x24\xa3\xc9\xe3\x47\x30\x54\x57\xa6\xd2\ \x14\x1d\x43\x0b\x9e\xf0\x96\xc6\x65\x2d\x8d\xcb\xe7\x4b\x47\x37\ \xae\x38\xd6\x3b\xc2\x37\xac\x0c\xaf\xde\x39\xb5\x57\xc1\x3b\x4e\ \xd3\x52\x3e\xe5\xf4\xaa\x6c\xac\xbc\x58\x20\xa2\xbd\x34\xa2\x91\ \x7a\x63\x0e\x09\xd9\x3d\xb7\xee\x18\x7f\x89\xfb\x94\x7a\x72\xcb\ \xec\x98\xc3\x41\x27\x36\xbd\x6e\x9a\xe2\x2c\x32\x42\x4e\xab\xdb\ \xe0\xf4\xc6\xb9\x03\xf0\xeb\x17\xba\x42\x83\xba\x69\x35\x55\xc9\ \xb5\x08\x68\x7b\x90\x3d\xc4\xee\x9d\xa7\x04\xe3\xdf\x2a\xcb\x0d\ \x20\x23\xf1\x5d\x81\xa9\x15\x70\x91\xfe\xf6\x05\x10\x1e\x47\x6e\ \x0c\x34\x91\xa4\x89\x2d\x09\x23\xb7\x23\xcf\xbd\x18\xed\xac\x40\ \xe0\x84\x56\xec\x5d\x9d\x4a\xa8\x9d\x51\xa6\xf6\xac\x8e\xab\x4d\ \xb1\x57\x75\x3c\x5d\x14\x7f\x54\xc7\xd5\xa4\xe8\x0b\x39\x9e\xfa\ \x45\x5f\x5a\x77\xb5\xd8\xc1\x27\x75\x5c\x50\x9a\xad\x1c\x8a\x66\ \x58\x32\x7f\x73\x4d\x99\x13\xb6\xd4\x3a\x5e\xa8\x6f\x95\xda\xd8\ \x5d\x35\x10\x7b\xde\x34\x30\x91\x37\xb1\xa8\x91\x94\x5d\xf2\x98\ \xa0\x9d\xd4\x91\x61\x56\x2c\xf7\x03\x8a\xb5\x18\x30\x8e\x7f\xb1\ \x09\xa3\x10\xd0\xd2\xa4\x64\x92\xce\x52\x28\x29\x7b\x61\x2f\xf5\ \x41\xb8\xe4\x7c\x92\x43\x82\x7c\x92\xa5\x77\x43\x79\x4c\xe1\xeb\ \x0c\xd2\x0d\x77\x73\xea\x99\x29\x3b\x0f\xb9\xdd\xcd\xd4\xef\x9f\ \x67\xb8\xba\xe1\xee\xa0\xbd\x1d\x1d\x6c\x75\x64\x46\x82\x71\x19\ \xc3\x2d\x4e\x93\x65\x17\xcf\xa3\xcc\x1a\x91\x74\x67\xfe\xc4\xd7\ \xb7\x38\x89\x38\xe8\x80\x9a\x94\x92\xf5\x51\x45\xdc\x9d\x4d\x01\ \x76\x98\x58\xc1\xe0\x30\x0c\xdc\xbc\x8f\xb2\xdf\x8b\x77\x83\x5d\ \x55\x70\x55\xf8\x57\x8b\x69\x9e\x2b\x57\x0e\x7b\x5b\x99\xc4\xdd\ \xb1\xb4\xf1\xf4\x29\xe3\xd2\x16\xe9\x63\x20\x39\xbb\x9b\x5d\x6e\ \x34\xe2\xf2\x57\x2a\xf8\xc4\xf3\x18\x8d\x7a\x8f\x8a\xf7\xf7\x70\ \x16\xd4\xe4\x0e\x19\x7a\xb9\xb4\x9d\x68\x2a\x46\xde\x12\x2c\xd1\ \x6e\x04\x77\x6d\x7a\x55\x2f\xfc\x23\x4a\xb4\xf1\xa8\x22\x0b\x3f\ \x96\x10\x45\x36\x33\xa2\xa6\x9b\x66\x7e\xa9\x49\xdc\xf3\xff\xa8\ \x8d\xdd\x8d\xa6\x7f\xae\x51\x51\x86\x55\xd3\xc2\x6b\x66\x61\xe3\ \x58\xa4\x27\xb7\x6a\x2a\xaf\x70\x5d\x72\xa6\xa4\xbe\x1d\xb7\xf4\ \x21\x6a\x5c\xe2\xdf\x32\xe7\x33\xb3\xcc\xf1\xda\xff\x88\x3d\x9d\ \x33\x02\xba\x91\xf9\xf8\xcd\x8e\xee\x1e\xff\x93\x99\x65\xbd\xbd\ \x1f\x38\x25\x7b\xbe\xd7\x6e\xef\xc9\xed\x6a\xdb\xec\xdd\x5d\xed\ \x62\x9b\x7d\x91\x2c\xab\xde\xfe\x8f\x2c\xa8\x0f\xbb\x93\x0b\x4e\ \xd9\x72\xae\xe3\x14\x86\xc5\x70\xf0\x3f\x02\xf0\x11\x9a\x46\x9a\ \x25\xf8\xc9\xdc\xa4\x53\xcc\xb0\xd4\x6b\xb8\xa6\x7f\x06\x97\x3d\ \x99\x24\x37\xd4\x49\x5f\xe2\xce\xe7\x90\x80\x10\xdb\xac\x64\x30\ \xe3\x05\xde\xbb\xb6\x0a\x15\x6d\x1e\xca\x18\xf8\xd5\xba\x24\xd3\ \x7a\x7a\x93\x6a\x9b\xae\xc8\x2c\x1a\x85\xda\x09\xf6\x67\x1a\xec\ \x52\x4e\x83\xad\x6c\x5c\x22\xed\x0f\xda\xe8\xd2\x63\xa9\xd9\x0b\ \xda\xc5\xf3\xc3\xdc\xbb\xaa\xb5\x44\xa5\xf0\xe6\xd7\x0b\xc7\xac\ \x04\x7b\xc2\x56\x38\x88\xc5\xf2\x3e\xe1\x84\xfe\x5e\x96\xea\x42\ \xd0\x68\x06\x53\x2d\xfc\x12\x4e\x46\x62\x2c\x1b\xa4\x6f\xfb\x52\ \x23\xa0\x04\x8d\xab\xad\xe9\x59\xc2\x4d\x4f\x18\xcf\xcd\x12\xbf\ \xb9\x29\x96\x79\x50\xd0\xa4\x60\x66\x51\xe1\x98\x9c\xcf\x33\xc6\ \x5c\xcf\x25\x56\xf6\xca\x31\xfb\x85\x46\x01\x80\x29\xbc\xef\x28\ \x68\x6d\x66\x31\xcc\xdb\xc8\xf6\x2a\x99\x7c\x81\xbe\x54\xa2\xee\ \x89\xfa\xaa\xec\x55\x63\x99\x42\x9d\xd5\x5a\xcf\x42\x16\x78\x4b\ \x52\xd0\x4e\x48\x35\x96\x0a\x36\x6c\x1e\x82\x16\x3c\xeb\x89\xc9\ \x4e\x96\x71\x44\x00\x73\x11\xd9\x74\x69\xc6\xe5\x4c\x58\x31\x3b\ \x41\x37\xe1\x80\xee\x98\xca\xea\xb8\x21\x4f\xe2\x5b\x90\xd8\xa0\ \xe6\xb7\xa2\xc5\x88\x26\xd4\x8f\x67\x98\x55\x5d\x6d\x9f\x26\x56\ \xd5\x0a\xfa\x38\x8f\xbb\x72\x81\xf4\x36\x76\xad\xf2\x76\x96\xe4\ \xa3\xdf\x91\xfd\xd1\xf3\x5a\x91\x8f\x35\x8d\xa6\x6f\x65\x72\x9c\ \xcb\xda\x47\x1f\x8c\xc2\xb3\x84\x9f\x7e\xc7\x7e\x17\x09\xf2\xed\ \x6a\xa2\x07\x18\xac\x3e\xb5\x59\xd2\x94\x23\x59\x2b\xe5\xc8\xd4\ \x20\xbc\x8a\x4c\xe7\x01\x73\xad\x4d\x7f\x33\xdb\xb1\x67\x9c\xe0\ \x9e\xb7\x74\x27\xdb\x2f\xc4\x76\xcf\x30\x4f\x06\xd5\xb7\xef\x16\ \x4b\x59\x96\x76\x18\x72\x96\xe9\x70\xd4\x4a\x66\x30\xbb\xb9\x42\ \xec\x6e\x34\x2f\xc6\x28\xb2\x1d\xaa\x6c\x7f\x5f\x8d\x58\x1c\x5f\ \x65\xca\xb9\x29\x2b\xd1\xd6\x66\xbf\x39\xe6\xe3\xca\xeb\x5b\xbc\ \x2d\x30\xc1\x1d\x1c\x74\x8e\x4d\xb5\x80\xe6\x76\x52\x91\xcc\xac\ \x80\xce\xf5\xc0\x69\x1a\xed\x9b\xe8\x95\xa4\xfd\x18\xf9\x6b\x04\ \x1d\x86\xe6\xc1\xef\x58\xcc\xc8\x82\xe0\xb5\x18\x7e\x26\xc8\x4f\ \x0b\xb2\x5f\xb6\x35\x08\xc6\x63\xf0\x19\xed\x6f\x31\x67\x7d\xcc\ \x80\x04\xb8\x98\x65\x3a\xc1\x52\xf1\x62\x80\xb7\x6a\xa7\x61\x60\ \xfc\x65\x80\x63\xbb\x38\x9a\xf3\x40\xeb\x6b\x8c\xb6\x9d\x77\x2e\ \x34\xa1\x9d\x37\xd2\x92\x9f\x3b\x93\xc2\xad\x39\x32\xf7\x57\xe0\ \x54\x9c\x51\x06\xa7\x45\x65\x6f\x78\x51\xbb\x65\xbf\x21\xe1\x7d\ \x07\x8a\x2c\x7e\x5e\x44\x5a\x4d\xe3\x86\xf1\x35\x0d\xb1\xa2\x34\ \x2e\x69\x59\xb9\x38\x8b\x93\xd1\xf8\x54\x54\xb1\x69\xc8\x50\x32\ \x49\x16\x41\x87\xd3\x53\x26\x95\x71\x25\xa5\x65\xb1\x88\x82\x13\ \x8f\xf1\xcd\x64\xfb\xb9\x8d\x5c\x8b\x74\x94\x96\x07\x69\x19\x5a\ \xca\x44\x7b\x53\xf4\x84\x2a\xa7\xa8\xf5\x34\xa1\x60\x3f\x52\x12\ \x93\xe7\x84\x06\xd8\x67\x75\x55\x31\xb0\xb9\xb2\x99\xb9\xe8\xd1\ \xb7\x51\xe6\x3b\xa1\x33\xbc\x59\xf6\xcc\x9c\xa2\x48\x2b\x65\x69\ \x4c\x57\x46\x0e\x9b\x37\x66\x18\xd9\xd6\xc5\x8b\x27\x26\x26\x5a\ \xf0\xd3\xc3\x29\x43\x49\x8c\xb5\x00\x06\x8b\x89\x0d\x37\x33\xb9\ \x38\x8d\x53\xa3\x2c\x9e\xb7\xaa\x58\x8d\x95\x8b\xe5\x55\x04\x49\ \x39\x23\x81\xa4\xa0\x8f\xab\xca\x04\x46\xd2\x1a\x82\x9a\x19\x25\ \x88\x60\xbe\x56\xd5\xcf\x52\xb4\x9a\x59\x74\x53\x1f\x03\x77\xa3\ \xb2\x13\xa5\x0b\x21\x1d\xa0\x26\x3f\x3a\x70\xad\xb9\x10\xe5\xfd\ \x88\xf5\x90\x66\x3a\x4d\xbb\x58\x07\x16\x1f\x49\xa7\xf6\x51\xd8\ \x36\x8c\x93\xa7\xf7\x1b\x42\x58\x45\x9e\x69\x77\xd5\xc6\x66\x7f\ \x33\xab\x57\x86\x33\xde\xf3\xa9\x04\x9d\x0f\x1e\xd7\xad\x55\x93\ \x38\x15\x37\xce\x27\x98\x63\x0f\x1f\x3b\xc1\x8a\x5f\x7f\xf7\x0c\ \x99\xcb\x4c\x56\xbc\x53\x92\x62\xac\x50\xa7\x88\xa6\xd3\xf6\x5a\ \x74\xf9\x6b\xde\x4a\x66\xcb\xa5\x77\xc8\xf5\xfd\xbd\x20\x60\xab\ \x9e\x4b\xde\x11\x34\x84\xdc\x79\xad\x9c\xaf\x1d\xbe\x8a\xec\xa4\ \xaf\x2a\xab\x9b\x63\x16\x74\xd3\x8f\x22\x6f\x29\xfb\x94\xb5\xe4\ \xd8\x85\x82\xf5\x84\xa7\x85\xd5\xf2\x36\x96\x87\x2a\x67\x3d\xd0\ \x68\xe6\x82\xc5\x2f\xd8\x52\x67\x44\x1c\xe6\x81\x6f\x16\xb0\x7d\ \x37\xcb\x1e\x0f\xd8\xad\x7f\x3d\xec\xca\x71\xc5\xe3\x90\xb9\x0b\ \x63\x66\x7c\xfb\x58\xe5\xdb\xc7\x08\xb9\xa0\xa4\xd9\xbd\xf8\x98\ \x99\x34\x27\x83\x72\xf1\x5b\x7c\x20\x0b\xff\x3a\xa4\x6f\xcf\x6b\ \xa7\x6a\x28\x45\xbc\xcf\x3b\xf7\x4c\xaf\x6d\x70\xb1\x8c\xa7\xf8\ \xaa\xc6\x32\xa0\xd2\xa7\x6d\x32\x85\xe7\x61\x91\x20\x28\x4e\x47\ \x66\xda\x6b\xf3\x55\x3e\x77\xd2\xf0\x69\x24\xd4\x21\x9f\x81\x65\ \x4e\x8c\x99\x4f\xd7\xf8\xf6\x71\x04\x7b\x22\xd0\x0e\xfd\x77\x9a\ \x57\xc5\x8f\x81\x16\x0c\x71\x60\xb4\x46\xdd\x27\xb3\x06\x35\xb0\ \xfa\x22\x30\x47\x68\xd5\xa5\xae\xc9\xdc\x63\x7f\xeb\x15\x63\x42\ \xd3\xb7\xda\x16\x5b\x5f\x80\x3d\x05\xdf\x16\x65\x80\xa7\x4c\x4b\ \xb3\x4d\x04\x7c\x1e\x1c\x2d\xb0\x88\x03\x56\x97\xa5\x2f\xe2\x6e\ \x66\x77\xa5\xae\xe3\x02\x4f\x22\xb4\xe2\xef\x95\x4d\xdb\x20\x78\ \xab\xcc\xb7\x87\x9d\xf3\x7e\xf2\x05\xdb\xee\x09\xd4\x14\xbf\x5d\ \xec\xf7\x1e\x33\xdf\xf5\xec\x3e\xd3\x65\x1e\x47\x6a\x7a\x9f\x29\ \xf6\x45\xa2\x95\x5c\x8c\x8b\x22\x44\xf9\x4b\x5a\x5b\x24\xce\x08\ \x96\x6c\x0e\xbe\x9e\x35\x23\x45\x4d\xb7\x83\x71\x38\x55\x8a\xae\ \xdd\x22\xdf\xde\x05\xf9\xa1\x6d\xef\x58\x57\x7f\x56\x4a\xe7\x22\ \xbb\xc3\xaf\x2f\xa7\x2d\xd7\xb0\xfa\x37\x4f\x23\x41\x6e\x47\x0b\ \x97\x7d\x31\x2e\xc3\xe4\xd1\x56\x0e\x23\xf3\xa8\xb1\xaf\x22\x7d\ \xd1\x1a\xf0\x44\x7a\x51\xcb\x17\x45\xc3\x3f\x84\xa4\x94\x40\xa3\ \x46\x8c\x1c\x7e\x2a\xdc\x50\x68\x5c\x29\x13\x42\x69\x62\x76\x3e\ \x75\x44\x01\x22\x2d\x64\x26\xc4\xa2\xbc\xed\x34\x43\xdd\x0f\xfd\ \x1f\x3c\x98\xcd\x9b\x07\x13\x0a\x74\x07\xd2\x34\x7b\xf9\xa0\x08\ \xab\x2e\x74\x55\xc4\xc7\x42\x14\x43\xc1\xf1\xbe\x1a\x5e\xb3\x92\ \xfa\x6f\x2e\xd5\x8b\xd4\x96\xad\x5c\xbe\xa3\x05\xc1\xef\xac\xab\ \x82\x2f\xe0\x2e\x9f\x03\x81\x8a\xbf\xe2\x03\xce\xcb\x65\x1c\x37\ \x08\x16\x57\x31\x0f\x3b\xeb\x54\x28\x88\xc9\x70\x89\x37\x4d\xf6\ \xbb\x8d\x29\x4b\xc0\x48\x30\xd6\x6e\x6e\x4b\x3b\x7a\x55\xec\xd9\ \xba\x2f\x73\x63\x21\x17\x51\xe4\xaa\x5d\x36\xc6\xc8\xae\x74\xfa\ \xb8\xee\xd9\xcf\x8e\x9a\x36\x72\x25\x8a\xb3\x4d\xe2\x6c\xe7\x40\ \x16\x4c\x22\x72\xae\x0a\x95\x49\x47\xac\xcb\x2f\xff\x80\x18\x95\ \x1b\x88\xe3\x72\xd4\x19\x0a\x83\x51\xa3\x97\xa3\x45\x30\x39\xd0\ \xe7\xc5\x67\xf3\x92\xcc\xec\x57\xf6\xe9\x77\xee\x00\x76\x92\xa6\ \xb7\xb1\x98\x2f\x91\x14\x07\xba\x96\x2e\x1d\x83\xcd\xc2\xc0\xbc\ \x62\x21\x41\xde\x1c\x0c\x29\x42\x72\xe6\x73\xbb\x7c\x10\x7c\xa3\ \x19\xc8\x37\xc2\xcd\x50\x46\xcb\xec\x9f\xc2\xd7\xc6\xd4\xad\x8d\ \x46\xc5\x17\x41\xf5\xc8\x92\x96\xcd\x99\xf1\xa9\xd8\xc2\xed\xb5\ \x89\xf8\x7f\xd3\x19\xc4\xfb\x99\xa5\x1a\x2a\x79\xfe\xfc\x2f\x5b\ \xc4\xe4\x5f\x0a\x99\xcf\x75\x93\xb9\x97\xc2\x67\xba\xb0\x32\xb2\ \x3c\x52\x9f\xf2\x90\x55\x9e\x89\xf7\x66\x08\xa2\x1d\x94\x2f\x4a\ \x7b\x63\xcf\x17\xbd\x01\x31\x23\xc4\xbd\x21\x90\xce\x90\x5d\xcd\ \x33\xbf\xf3\xe9\xc6\x48\x72\x49\x71\xc8\xed\x09\x0b\x92\xc5\xaf\ \x74\x80\x30\x65\xce\x75\x8d\x39\xaa\x01\xf8\x7c\xd2\x3a\x20\xec\ \xd0\x22\xb7\x00\x65\x3b\xac\xbe\x5a\x94\xbb\xce\xb4\x04\x29\xe2\ \x87\x0a\x73\x9a\xb7\x13\x68\x0b\x7a\x6e\xf6\x61\xb1\x32\xef\x9a\ \xe5\xd4\x09\x37\x58\x72\x74\x82\xbc\x20\x67\x86\x01\xf2\xb0\xbb\ \xd3\xd9\xd4\x7f\xc5\x4b\x22\xda\xbf\xa1\xa3\x9b\xbb\x01\xf7\x0f\ \xa0\xe0\xfb\x77\xe4\xb0\x16\xdd\x86\xaa\x19\xd8\x34\xa0\x23\x9d\ \xac\x88\x3a\xf1\x3f\x5f\x4d\x1f\x97\xa4\xff\xf9\x9a\xd2\x46\xc5\ \xa8\xff\x4f\xfa\x18\xb8\x91\xfc\xd8\x3d\x0c\x48\x87\xdc\xb5\xe7\ \x31\x3b\x7f\xc1\xce\x71\x51\xa7\x69\xc8\x46\x67\x9e\xe0\xea\x9d\ \x9a\x89\x5c\x8f\x7f\x3a\x91\xfb\xcf\xbe\x2b\x5b\xac\xef\x8f\xf3\ \xd1\x53\x67\xdf\xff\x63\x9e\x48\x55\xfd\x1b\x3a\xdb\x3b\x3e\x36\ \x47\x24\x0f\xf8\xaf\x4d\x0d\x3c\x3b\x6f\xba\x99\x57\x92\x2d\x7f\ \xfb\x4b\xb1\xb6\x13\xaa\x19\x5f\x46\xcd\x20\x19\x47\x5e\x52\x3c\ \x91\x2f\x20\x6f\x20\xb7\x3d\x75\x1d\x9e\x01\xc1\x31\x45\x47\x62\ \xbd\x12\x6f\xe6\x2c\x91\x53\x29\x72\x65\x80\xaf\x1b\x70\xaa\x7b\ \x92\xe4\x54\x35\x26\x85\x53\xe0\x2f\x21\x50\xdd\xdb\x7c\xaf\x59\ \x45\xa5\x3f\x26\xcd\xad\x73\x52\xcd\x91\x5f\x9d\x0f\x4a\x7b\xb0\ \x28\x14\x74\x3e\xf5\xfe\xf9\x1d\x98\x29\xa5\xfb\xff\x49\x8e\xed\ \xc6\x32\x80\x53\xd0\x6f\x80\xa9\xc2\x49\x16\x07\x08\x85\x50\x5f\ \x14\x3b\x8a\x46\x21\x7f\xf9\x47\x9c\x88\x5e\x06\x6f\x42\x71\x12\ \xcd\x72\x3c\x40\x1d\x02\xb8\x71\xe8\x63\x00\xfe\x8a\xa3\x41\xd4\ \x06\xff\x77\xc3\xe7\x4d\xd6\xa6\xa7\x4b\x62\x20\xfa\x64\xca\xb0\ \xe5\x8b\x69\x47\x3c\x89\xf8\x36\xbe\x75\x35\x33\xbc\x98\xb3\x66\ \xdf\xd0\xd0\xbd\x86\x85\xf6\x51\x26\x09\x7a\x53\xb0\xb8\xf7\x1b\ \x9b\x07\x6b\x3e\x27\xc9\x64\x51\xce\x46\xc2\x7b\x14\x03\xfb\x83\ \xf2\x6f\x9a\x37\xc5\xfb\x7b\x8e\xef\x18\x1a\x88\x6f\x18\x38\x3e\ \x3e\xd8\x36\xd8\xdd\xd1\x24\xc9\x39\x9b\x3f\x4a\xb2\x61\xe8\xea\ \x30\xf0\xeb\x16\x89\xdd\x88\x25\xc6\x14\x58\x97\x49\x2d\xaf\x4b\ \x18\xbc\x94\xa4\x1b\x0e\x76\xe0\x88\x3a\x9a\xb7\xd5\xcf\x2a\xae\ \xf7\xa2\xf4\xbc\x6b\x5f\x48\xf7\x74\xfd\x9f\x3c\xca\x3c\x9d\x7f\ \xfc\x6f\xa4\x4f\x61\xaa\x77\xe9\x23\xe9\x53\xe8\xf7\xe3\x38\xb8\ \x3d\xdd\xef\x47\x36\x6b\x37\x12\xde\x10\x30\x45\xc7\xd6\x72\xeb\ \xcc\x9b\x82\xa1\x81\xee\x56\xa6\xcf\x56\xf4\x6f\x18\x3e\x11\x0e\ \x12\xb6\x70\x62\x75\xa2\x80\x75\x06\x99\xf6\x1c\x47\xc6\x47\x5b\ \xc9\x70\xd8\x82\x25\x72\x69\xea\xe9\xf6\x3f\x60\x61\x70\xf4\xd7\ \x2a\xec\x4f\xa4\x94\x5b\x43\xdb\x01\xa5\xdc\xd1\x65\xc1\x77\x4d\ \xfa\xfa\x3a\x37\x64\xc9\x5d\x3c\xff\x2a\xcb\x46\x81\x9c\x1d\xda\ \x68\x0a\xd6\xe2\x56\x1f\x63\x2a\x04\xa1\xbe\x56\xd5\xdf\xe7\x74\ \x59\xf6\xe7\x3b\xb6\x27\x4d\xa9\xbb\x81\x4b\x09\xe2\x27\x28\xf6\ \xfd\xd7\xfd\xba\x6d\x1c\xfd\x4f\xf0\xbe\x8f\xd3\xaf\xde\x03\xde\ \x3f\xb1\x81\x33\x21\x84\xd7\x57\x9a\x73\x60\x65\x29\x21\x2c\x57\ \x69\xda\x0b\xc7\x79\x66\x00\xab\xb0\x6f\x31\x32\x84\x15\xf0\xa7\ \x55\x65\x0f\xce\x59\x95\x90\xcd\xd7\x74\xfa\xe4\x51\x25\xae\x18\ \xf9\x2c\xf7\x96\xf2\x7e\x82\xb7\x7b\xe8\x45\x94\xcc\xc2\x40\x1d\ \x0f\x0f\x62\x10\x52\x0e\x94\xf8\x56\x7f\x90\x73\x18\x5a\xb4\xb9\ \xc2\x19\xb0\x78\x50\x35\x7d\x80\x97\xce\xbc\x61\x0a\x40\xab\x67\ \x0f\xdb\x9a\xe9\x96\xf8\x01\x46\xfa\x80\xa5\xe9\xb2\x6a\xf8\x37\ \xef\x2c\x10\xf6\xe9\x17\x84\xc8\x9b\xbb\x9c\x61\x88\xb3\xb8\x70\ \x4a\x33\xfc\x10\xdb\xab\x14\x1a\x7f\x58\xd3\x4f\x03\xc7\x7b\xf0\ \x47\xfa\x2e\xb1\xec\x0b\x40\x76\x31\x8b\x1b\xff\x2e\xae\x79\x55\ \xe5\x7d\x1f\x77\x1c\xd1\xf7\x77\xf8\x5b\x0a\xe7\x2b\xb9\x8b\x8b\ \xbf\x92\x8b\xdd\x85\x68\x06\x0c\xf6\x4e\x6e\x75\x7f\x9f\xae\x3a\ \x92\xe0\x0f\x32\xac\x0a\x18\x2e\x09\x76\x71\x64\x3d\xa6\x8b\xcc\ \xdb\x1a\xfb\xb1\xb5\xa4\x85\x23\xc6\xdd\x9e\xf8\x83\x00\x47\xa7\ \x75\xd3\x7a\x6a\x38\x41\xde\xe1\x25\x5f\x8d\x8c\x28\xe4\xb1\x40\ \xeb\xa9\xe1\x16\x31\xae\xd8\x1b\x1a\x9f\xb2\xbc\x43\xd0\x4a\xb4\ \xd2\xea\xad\x2a\xc6\xb8\xba\xb4\x72\x65\xe9\x10\x56\x71\x7e\x4b\ \x36\x84\x55\xab\xc4\x10\xb0\x1b\x37\x4d\xf9\x86\x3d\x5f\x1d\xe1\ \xa1\xb8\xa6\xa0\x91\xd3\x01\xa8\xed\x80\xe2\x55\x96\x14\xaf\xb2\ \xb4\x78\x95\x65\xc5\xab\x2c\x2f\x5e\x65\x45\xf1\x2a\x07\x16\xaf\ \x72\x50\xf1\x2a\x07\x17\xaf\x72\x88\x78\x49\xea\x41\xcd\xa2\x87\ \x63\xce\x23\xb7\x55\xb5\xa5\x54\xa0\xb6\x9c\x29\xb3\x15\xec\xa0\ \xbd\xf8\xda\xb4\x17\x85\x52\xde\xbe\xa4\x04\x30\xc5\xd7\xaf\xbd\ \xf8\xfa\xb5\x17\x5f\xbf\xf6\xe2\xeb\xd7\x5e\x7c\xfd\xda\x8b\xaf\ \x5f\x7b\xf1\xf5\x6b\x17\xad\x9f\x73\xee\x3a\x56\xac\x16\xaf\xf1\ \x1c\xe6\xc9\x91\xe3\x4c\x3e\xde\x3b\xfd\x70\x47\x3e\x67\x68\xe9\ \xa2\xdd\x74\xf6\xf8\x74\xa3\x7b\x32\x3d\x38\x13\xca\x9a\xd7\x10\ \x94\x27\xf3\x39\x03\x8a\x71\x48\x1b\xa2\x1f\xaf\x3c\xac\x8b\x5e\ \x95\x99\x8e\x18\x98\x71\x63\x99\x62\x67\x38\x26\x7d\x19\xcb\x94\ \x88\x38\x6e\xd5\xa3\x18\xec\x31\x41\x11\x93\xb4\x9f\xfc\xe5\xee\ \xfd\x6c\x69\xa2\xc7\xba\xd9\x13\x03\x98\x67\xf1\xc8\x2c\xa7\x0a\ \x8c\x58\x73\xc5\xfb\x32\x4e\x27\x8d\xa5\x41\x8d\x3c\xb8\x2d\x31\ \x6f\x46\x2f\xcc\xe6\x82\x30\xb1\xe7\x78\x1f\x08\x0d\x5d\x5c\x00\ \xd0\x6e\x14\xb2\xc1\x20\x37\xf7\x75\x76\xcd\x17\xc3\x3e\xb0\x04\ \xd8\xd4\xe6\x63\xae\x7d\x16\x7e\xb7\x7b\x9a\xe5\xee\x49\x83\xc3\ \x98\x38\x92\xf9\x74\x18\x73\xb9\x7f\xc8\x8e\x99\xb6\xb2\x89\xda\ \x93\x44\xee\x52\x53\x93\xce\x67\x07\x44\x2b\x57\x58\x4e\xa9\xe0\ \xae\xc4\xbc\xad\x8b\x85\x61\xec\x46\x5b\xf4\xe9\x0a\x76\x41\x76\ \x74\x3b\x15\x81\xd6\x17\xcc\x3c\x98\x66\x5b\x7a\x2d\x1c\x12\x59\ \xb9\x1e\x07\x40\x66\x2d\xff\x0f\x1f\x90\x31\x4e\xa0\xe7\x53\x13\ \xbb\x44\x65\xb7\xa0\x8c\x85\xd1\x82\x70\x4b\x96\x6e\xc5\x10\x1c\ \xdc\xa8\x86\x7c\xa9\xe5\x73\xc5\x87\x53\xcd\x13\xaa\xbd\x42\x96\ \xe4\xe1\xdb\x70\x96\xcb\xbf\xd8\x1e\x3b\x47\x64\xc4\xab\x78\x44\ \x4e\x60\x75\x1c\xa3\x92\x2b\x08\xf2\x48\x17\x48\x6a\x53\xa6\x57\ \xd0\xa6\x3d\xca\xbe\x9c\xf7\x1a\xf1\x45\x28\xcc\x22\x28\xf0\x4e\ \xee\xd8\x14\x5f\x1c\x97\x05\xbe\xc3\xa3\x74\xa4\x12\x97\x45\xcd\ \x71\x0b\x3f\x8d\xf4\x85\x9d\xe7\x61\xcb\x16\x9d\xf9\x69\xd6\xa3\ \xe3\xf4\xcc\xe1\x96\xbb\x2d\x39\x8e\x6f\x83\xc9\x96\x9c\x61\xb6\ \xc7\xce\x35\x86\xaa\xe4\x38\x95\x86\xbe\x3e\x9d\x24\x36\x67\xce\ \x19\xbd\x4b\xd3\xd3\xc5\x9b\xf6\x09\x88\x35\xd8\xc7\xb0\x2e\xd4\ \xb4\x1e\x78\xa2\x99\x63\x26\xe1\x9a\x82\x8a\x0e\xd0\xbb\x65\xea\ \xe3\xd4\x40\x61\x80\x1e\x86\xcd\x31\xb9\x0d\x79\x23\x9b\x37\x2c\ \xb6\xa0\x79\xcd\x29\xd0\x96\xaa\x3a\xfe\x2d\xe7\xb2\x11\xf3\x37\ \x34\x09\x01\xac\x28\x81\x85\x1f\xf3\x2d\x82\x4a\xd4\x4a\xe5\xc2\ \xbd\xad\xd8\xa1\x65\x55\x4a\x1f\xc5\xc6\x40\x1a\x72\xba\x6c\x05\ \x6d\xda\x5a\xb8\x6d\xcc\x75\x3a\x8c\x10\xb5\x90\x12\xfa\x62\x44\ \x9d\x73\xf9\x57\x27\xeb\x3a\xf3\xd9\x94\xb2\x4d\x22\xf0\x00\x56\ \x31\xcc\x0a\x52\x45\xa1\xc9\x8d\x33\xd6\x63\xef\xb2\x51\x4b\x81\ \xe7\x9e\x6b\x5d\xa3\xcb\x93\xc0\x7c\x53\x45\xe6\xb6\x81\xbd\xbb\ \x49\x5d\x14\xa9\x93\x2f\x07\xa5\x07\x27\x59\xce\xa9\xc5\x56\xa8\ \xd6\x91\xd2\x90\xa3\xd5\xf5\x5a\xa6\x68\x53\x87\x66\x66\xaf\x12\ \x53\xc9\x0a\xb7\x5e\x50\x80\xd3\x27\x81\x35\x89\x12\x84\xd7\xd1\ \xf6\x92\x09\xae\x70\x0f\xf5\xdc\x26\xa4\x72\x9c\xeb\xdc\xc8\x11\ \xcb\x69\x61\x20\x33\x5d\xc4\xe4\xcd\xb0\x53\x49\x85\x09\x99\x26\ \xd8\xf1\x87\xd4\x6c\x65\xdd\xd7\x99\xe5\x3a\x85\x6c\xe7\x9e\x9c\ \xe0\x9c\xa8\xa2\x90\x75\x39\x33\x5a\x74\x29\xe8\x8b\x3c\x54\x48\ \xe5\x18\xc6\x80\x82\x03\x78\x8a\xb4\xae\xf7\x44\x9e\x70\xa2\x00\ \x8d\x39\x61\xf6\xbd\xd2\xa8\x31\xc1\x8c\xe6\x7c\x16\xa2\x31\x7c\ \x4f\x5b\x9c\x1c\xcb\x38\xe4\xcb\x68\x8e\xfe\x42\x5b\x31\x66\x65\ \x81\xb1\x99\x44\x38\x86\xad\xcd\xad\x9c\xc8\xc4\x71\xd7\xb0\x4b\ \x9a\x2d\x77\xca\xaf\xa5\x73\x7f\x6f\x83\x06\x26\x74\xaa\xdc\x75\ \x42\x2b\xbf\x1f\x69\x0c\x9a\x0f\x62\x38\x30\xd7\x96\xe2\xcd\x30\ \x48\xee\xd1\x27\x5b\xfc\x60\x9b\x20\x86\xe5\x79\x1f\x68\x18\x97\ \x18\x72\x06\x6d\xbe\xc0\xd1\x55\xcc\x3a\x79\xc4\xed\xb1\x86\xee\ \x92\x0c\x6c\x9a\x62\x87\xad\x5f\x4b\x7e\xbf\x38\xa5\xe2\x0a\x52\ \xd9\xa1\xc5\x70\x2d\xa3\x96\x93\xbe\x3d\xd6\x10\x7e\xa2\xdc\x67\ \x8c\xb5\x04\x47\x6f\x52\xae\x70\x07\xf1\xf5\xc2\x8d\xea\xa0\x91\ \x36\x8a\x5d\xc5\x39\xc9\xa0\x40\x90\x71\x55\x7f\x5f\x3e\x37\xd6\ \x9e\x37\x0c\x2d\xe3\xb3\x33\x38\x29\xae\x03\xdf\x95\x52\xdc\x06\ \xe4\xa4\xaa\x71\xed\x0e\xe0\x3d\x87\x90\x99\xd3\xc2\xf4\xc6\x2c\ \x14\xe1\xb2\x9b\xca\xee\xad\xb4\x84\x01\x3a\x9b\xe5\x5c\x54\xd1\ \x3f\xa0\x8c\xae\xde\x66\xbe\x55\x41\xad\xf6\x2a\x73\x49\xa1\x1b\ \xcf\x34\x7c\xd2\xeb\x8f\x1c\x32\x83\xbf\xd2\xc8\xcc\xf9\xe9\x5c\ \x8e\x7a\x12\x41\x01\xa7\x04\xc9\x7b\x9b\x54\x52\x6a\xda\xd3\xd3\ \x11\xdc\x7d\x98\xca\xf4\x69\x77\xf6\x4f\xba\xe9\xf1\x50\x12\x4c\ \x8b\x36\x5f\x90\xe0\x65\x86\xe9\x19\x8d\xdd\x20\x69\x89\x44\x5e\ \x67\x29\xf9\x1d\x9d\xcd\x62\xa9\x2d\xcd\x3b\x1c\xf3\xdd\x52\x9e\ \xa3\xd5\xda\xcf\x2d\x48\x2c\xb6\xc9\x01\x63\xfd\x0e\xfb\x12\x97\ \x94\x5c\xdf\x9d\x75\x07\xf7\x5f\xdb\x1f\xef\xef\x51\x0d\x65\x69\ \x49\xee\x1d\xe6\xe5\xd4\xae\x74\x25\x9c\x1a\x06\xe2\x04\xff\x45\ \xee\xa7\x8a\x39\x32\x89\x50\xf8\xdf\x70\x32\x19\x2c\x8e\xe8\x7f\ \xd2\x83\xc0\xea\xbf\xa4\x6c\xfa\xde\x64\x38\xfe\x39\x59\xf6\x70\ \xdf\xe4\xd3\x9c\x2c\x39\xbf\x5e\x4b\xdb\x2a\x76\x34\xff\x14\xb7\ \x0a\x8e\x80\x71\xbf\x43\x51\xc3\xd0\xe0\xe6\xfe\x63\xde\xb0\xa2\ \xd7\x30\x04\x58\xfc\xa7\x9d\x7f\x05\x28\xfc\x87\x37\xac\x00\x83\ \xff\x8d\xfd\x5a\x1c\xcf\xf5\xcc\xe8\x8b\xcf\x7e\x9a\x06\xc2\x74\ \xc8\x32\xcd\x44\x34\xae\x56\x61\x4e\x5b\xde\x37\x69\x1c\xe9\xae\ \x2d\x6c\x66\xf6\xc9\x3a\x88\x8e\x06\x71\x78\xca\x67\x0c\x2b\x0b\ \x35\x8f\x47\x49\x8e\x47\x62\x8f\x62\x01\x6e\x56\xdf\x7b\xba\x3c\ \x9e\xb2\x26\x2a\xb9\x29\x77\xbe\xeb\x79\x96\xa0\xfb\x83\xa7\xc0\ \xb2\xec\xd7\xc4\x46\xf9\x37\xf5\x3c\xec\x4a\x9b\xf0\xe9\xec\x3f\ \x9f\x41\x4b\x80\xc4\x34\xa2\x63\x89\x92\xf1\x84\xdb\x35\x83\xdd\ \x62\x44\xfb\xe3\x09\x4c\xc9\xed\xb2\xce\xae\x41\xda\x09\xc9\xd1\ \x9c\xee\x2e\xd9\x8c\x53\x0e\xb0\x04\xa6\x24\x47\x15\x11\x8c\x06\ \x97\x99\x15\xff\xf6\x1e\xa7\x7e\x62\x0b\x68\x92\x19\x89\xdd\x6d\ \xe7\x7a\x4c\xb4\x3c\x06\xb2\x0b\x0a\x16\x04\x45\x50\x66\xb9\xa0\ \x98\x99\x6b\x74\x8f\x25\x56\x57\x47\xc7\x84\x20\xea\xbd\xb6\x62\ \x4e\x2f\xc0\x4d\xa9\x05\x57\xd4\xce\xa5\x55\xf1\x86\xdb\x9c\x6a\ \xbb\xfb\x3b\x1b\xce\x74\xcc\xbc\x8d\x31\xa7\x94\x0e\x60\x64\x7d\ \xa7\xbd\x99\xd8\x6b\x4c\x7e\xc1\x87\xe3\xf8\x25\x65\xaa\xa2\x00\ \x7c\x17\xa3\xc1\x01\x91\x7a\xa5\xa8\x9e\xd6\x63\x8a\x2e\xc4\x67\ \x91\x2f\x3e\x85\x16\xd6\x84\xea\xb7\xb4\xfe\xa3\xf4\x5b\xe8\x6a\ \x06\xd1\x77\xa9\x63\x45\x26\x8e\x26\xa6\xe0\xa8\x9f\x01\x14\x13\ \x40\x2d\xdb\x76\xee\x56\xe5\x2c\x3d\x95\xa3\xbe\xc3\x4e\x1f\x58\ \x88\xbf\xaf\xec\x27\xb6\x87\x44\xde\xf3\x16\x43\x5b\xca\x70\x57\ \xb0\xb6\x79\x92\x29\xcd\x3c\xbd\x04\x71\x48\x97\xa0\x85\x79\x0d\ \x23\x3b\xd4\xe4\x60\x87\x6c\xa6\x5c\x76\xd4\x9e\x01\x74\x49\xaf\ \x8e\xe8\x6b\x16\xec\x29\x3c\x7b\x36\x3a\xe4\x6c\x4e\xea\xd1\x84\ \x5d\x35\x58\x8d\x45\x4d\x23\xb8\xa9\x4f\xcb\x7a\xee\xc1\x49\x1a\ \x1a\xb6\x84\x6b\x47\xd3\x87\x2c\x29\xa9\xdd\x52\x4f\xbb\xa5\x25\ \xb5\x5b\xe6\x69\xb7\xac\xa4\x76\xcb\x3d\xed\x96\x17\x5c\xd7\x60\ \x87\xa1\x8b\x26\x3e\x02\x90\x89\x22\xcc\x5d\x2b\x2b\xa5\x55\x74\ \xa4\xe1\x76\xd4\x0d\xa3\x35\x0e\x6e\x1c\x34\xf3\xb1\x79\x60\x76\ \xb9\xae\x4e\xca\x57\x67\x92\x82\x8a\x51\xfb\x6d\x6d\xdb\xd2\xb0\ \xda\xb4\x9a\xf8\x13\xf3\xea\x5c\x42\x88\xde\x6a\x07\x85\x84\x57\ \x5b\xb7\x7a\x9e\x9a\x5d\x0e\x3f\x8c\xf2\xae\x46\x31\x39\xf4\x21\ \x9a\x43\x4b\x61\x0e\xa4\x36\x03\xab\xec\x92\xc7\x35\xec\xbc\x94\ \x13\x6e\x12\xf3\x3e\x86\x6f\x52\xd1\xa5\xe9\x13\xb2\x2e\x9a\x88\ \x06\x12\x08\x4b\xe3\xca\xa9\xfd\x82\x4f\xa4\x1e\x5e\x2b\x67\x46\ \x29\xc3\xf0\x4c\x60\x81\x04\x42\x9e\x55\x59\x8b\x5c\x9e\xaa\x6b\ \xb5\xb4\x68\x7a\xdc\xe7\xa8\x33\x24\x8f\x33\x97\xe2\xf6\x92\x79\ \xcf\xe3\xbf\x5c\xdd\x19\xd1\x24\x85\xc9\xe2\xdb\x8f\xcc\x84\xa1\ \x9a\xa2\x8b\xb9\x54\xdc\x87\xe1\x07\x7b\x18\xa7\xf7\xdf\x20\x66\ \xfa\xc3\x42\x35\x68\x32\x55\xdf\x1a\x65\xeb\x35\x5f\xf6\x44\x19\ \x14\xe6\x6f\xeb\xb1\x80\x6e\x6f\xdf\xf5\xf9\xb4\x1f\x63\xab\xb5\ \x18\x9b\xb3\x4d\x05\xb4\xf1\x69\xd2\x6c\x35\x49\x20\xfa\xbe\x35\ \x7d\x07\x8a\xd7\x0b\xc8\x15\x9a\x7d\x16\x02\xb0\x61\x10\xee\x7d\ \x00\x4e\x33\x0d\x83\x00\x02\xbb\x9a\xf7\xd8\x98\x93\x6c\x65\x43\ \x03\x3d\x42\xcc\x29\x65\x48\x2e\x4e\x40\x25\x2a\x1f\x76\x50\x6d\ \x35\x8a\x7b\xe4\xa0\x21\x31\x55\xe3\x06\xce\x37\xb4\x43\x7d\x32\ \x4b\x79\xe1\x03\xdd\x89\x50\xb8\x6f\xd4\x07\x9b\x28\xab\xcf\xe3\ \x12\xec\x1b\xf5\x41\xc4\xb2\xef\x0a\xee\xb3\x5d\x95\xe7\x78\xfc\ \x34\x12\xe4\x19\x51\xdd\x11\x81\x50\x4d\xaf\x39\xe0\x18\x57\x14\ \x11\x7a\x78\x5d\x58\x76\x09\x68\x99\x71\x5e\x6f\x8c\x80\xf0\x3e\ \x56\x22\x1f\x0d\x0f\x28\x46\x5e\x17\xaf\x47\xa7\x40\xd2\x09\x0d\ \x98\x22\x8e\xef\x31\x2c\xd9\xb2\x8e\x47\xe4\xf2\x3d\x89\xcd\xc6\ \xde\xa6\x51\xda\xd4\xa7\x25\xbe\x4d\xa5\x69\x1a\x38\x46\x18\x57\ \x64\x3d\x21\x9a\x81\x42\xb6\xeb\x30\xbd\xd5\x11\xce\x84\x48\xb2\ \x08\xc5\xc7\x54\x2f\x57\x41\xd4\xc1\xc1\x7a\x72\x8d\xab\x8e\xdf\ \x53\x13\x8e\xa0\x8b\x2d\x3f\xc7\xb0\xe2\x86\x26\xa2\xb4\x6a\xd8\ \x82\x56\x72\x43\x0e\xf3\xc9\xdc\x80\x72\x52\xc9\xf5\x6b\xa1\x3e\ \xa8\x75\x12\x4b\x7a\x50\x98\x2b\x0f\xca\xc3\x02\xc0\x41\xc7\xc6\ \x28\x13\x6e\x8b\x59\xe4\xb4\x4a\x12\x07\x18\xfa\x42\x96\x46\x2e\ \x65\xf9\xb3\xa5\x6a\xa3\x96\xca\xa7\x7d\x79\xc2\x5c\xc2\xd2\x53\ \x88\xa6\x6c\xa4\x4f\xba\x14\x02\xd3\x9b\x17\x4a\x24\x73\xc8\xd3\ \xb9\xa6\xd4\xed\x07\xa4\x92\x01\x11\x0e\x06\x0f\xf8\x0d\x7b\x56\ \x8e\x12\x1e\xe8\x53\xd1\x4a\x2b\xfa\xe3\x29\xd5\x74\xab\xde\x31\ \x95\xd4\x01\x62\x07\xf4\x51\x47\xfb\x52\x95\x51\x4f\xa3\x92\x34\ \x51\x47\xab\xff\x56\xa6\x30\x9c\x17\x26\xb7\x42\x90\x1d\xc6\x2f\ \xed\x9d\xf9\xa6\x05\x9f\x53\x22\x8e\x68\xde\x9a\x1c\x5a\x51\x2a\ \x8a\xdc\x93\xd9\x8b\x29\x0e\x04\x33\x9c\xf1\x91\xde\xfe\x98\xd9\ \x90\x68\x08\x11\x4e\x6d\x93\x63\xd9\x27\x0a\x22\x6e\x66\x71\xe6\ \x84\xba\x1e\x25\x47\x08\x33\xd2\x1f\xcf\xaa\x19\x33\x8d\x62\x18\ \x96\xc9\x21\x91\xf7\xb2\x6c\xdb\xce\x6a\x25\xdc\x1e\x06\xfb\xe3\ \x27\xd1\x50\xa3\x16\x67\x65\xcb\xc2\xa4\x90\xd1\x6b\x64\x31\xe9\ \x6d\x18\x3e\xdd\x6c\x8f\xff\x7a\x0a\x8c\xc6\x53\x2a\x49\xd5\xc8\ \x1d\xee\x04\x3c\x8d\x2d\xc7\x88\x87\x2b\x56\x74\xe0\x90\x4b\x7a\ \xd7\x6c\xd7\x2f\xe1\x9d\x20\xbb\xf2\x2a\x67\x65\xc4\x87\xc2\x98\ \x89\x65\x74\x62\x29\xb4\x36\x1f\x47\xa2\xf6\x28\x76\xa3\xc0\x25\ \x03\xe7\x07\xd5\x95\x84\xa6\x27\x5d\xc3\xa8\xa7\x72\x2b\x13\xb9\ \xc8\xa5\xb5\x48\x86\x65\x0d\x44\x82\xa4\x0d\x6b\x01\x50\x1d\xa6\ \xc5\xf1\x29\xcc\x73\x55\x5c\x1e\x57\x7c\x26\xd8\x4f\x76\x08\x0f\ \x65\x93\xb2\x7b\xca\xc4\x9c\xcf\xfe\x7e\xc4\xd7\x10\x39\xc2\x3a\ \x30\x4d\xae\x79\x66\x6f\x36\x9d\x0e\xdd\xaf\xb3\xdb\x49\x8d\xcd\ \x27\xc9\xf0\xa6\x5b\x84\x9c\xde\xf0\x8b\x58\xe6\x99\xac\xae\x8d\ \xe3\xbc\xa5\xb2\x94\xc0\xd7\xf6\xe4\xad\x44\x45\x9a\x50\x8d\x31\ \x29\xa3\x49\x5b\x95\xc9\x45\xcc\x5d\x3e\xda\x1f\xcf\xf1\x4f\xbf\ \x0c\x97\x78\xc7\x43\x83\xa5\x44\x51\xc8\xf6\x13\xef\x66\x2e\xda\ \x38\xfc\xf4\x20\x89\x3d\x1e\x65\x7b\xd5\xee\xcd\xee\x7d\x70\x38\ \x15\xde\xde\xf1\x78\x0f\x7d\xe5\x7d\x9b\x21\x35\x37\x2e\x99\x2f\ \xc2\x2f\x59\x34\x33\x8e\x5c\x10\x3f\x33\x45\xa9\x9b\x9b\x51\x1c\ \xdd\xd3\x39\x57\x80\x61\x4e\x21\x69\x04\xfd\x26\xf0\xe3\x45\xd0\ \x1d\xfd\x50\x00\xc1\x56\x1f\x04\x3b\x8b\x22\xd8\x44\x72\x03\x61\ \x9b\x56\x8e\xfc\xb6\xb5\x38\x02\xc9\xbc\x6e\x76\x3f\x86\x5d\x81\ \xc7\xe4\xad\x8a\x1f\x02\x27\xf8\x3c\x64\xe5\x97\xca\xc8\x24\x2b\ \xf1\xce\xe0\xf3\x56\xb9\x97\x6f\x5f\x8a\x9c\x99\xb8\x88\xe6\xab\ \xe2\x36\x84\xdf\x1a\x1e\xb3\x03\x18\xa6\x3c\x7b\xd3\x8c\xda\x36\ \x1f\xcd\x73\x63\xb7\x97\x13\xbb\xac\xae\x8e\xe3\x4d\x5a\x60\x73\ \xba\x63\x73\xc5\x9b\xd3\x19\x1b\xec\x5e\xb0\x3d\x68\xaf\x13\x63\ \xd8\x91\x9d\x05\x04\xfb\xad\xd4\x20\x79\xc2\xd3\x99\x53\x2c\x41\ \x56\x40\x27\x63\x32\xaf\x56\xbd\xfe\x29\x32\xa2\x4f\x1c\x8f\x13\ \x11\x80\xb6\x77\x6f\xff\x7d\xcc\x88\x6b\x40\x47\x49\x67\x8d\x49\ \x29\xa1\x66\x71\x5e\x60\x9c\x05\xd8\x97\x01\xa4\xd8\x73\x86\x85\ \x66\x9a\xbf\xbf\x73\x53\x8d\xe4\xb3\x52\x79\x60\x7d\xc3\xd6\x9d\ \xa9\x7b\xad\x16\xf7\xd9\xab\x43\xb2\x89\xd0\xc8\x5b\x8e\xb7\x66\ \xf3\xc3\x29\x35\x51\x68\xf5\xfc\x23\xff\xbd\x0f\x5e\xf3\x8f\xe8\ \xba\x57\x90\x4b\x94\x48\x43\xff\xf0\x55\xb5\xdf\x12\x16\x8e\x39\ \xb6\xd3\x9b\x95\x92\xb3\xd2\xfd\x92\x94\x33\x4f\x65\xb4\x7f\xb0\ \x33\x5e\xd2\xf5\xb4\x3b\x69\x67\x81\x97\xac\xec\xdb\x79\xbb\xef\ \x7c\x4e\x71\xdc\xce\xbb\x3b\xde\xb9\x7b\x8f\x1e\x4b\x7f\x00\xe5\ \x6e\xe7\x2f\x3d\x06\x6c\x7d\x82\x83\x57\xec\xcd\xca\xea\xfe\x41\ \x38\x04\xb1\xf5\x1a\x80\x30\xb9\xa4\x84\x67\x2b\xbd\xcd\x8a\xbd\ \x5c\x29\xea\xa8\xf8\xe3\x95\xde\x56\xed\xf6\x70\x90\xf9\x9c\xaa\ \xea\x2b\x1e\xc4\x08\x64\x9a\xa5\xd7\x9a\x4c\x5b\x7c\xc4\xb3\x20\ \xc5\x7a\xd4\xcc\x56\xc9\x74\x82\x14\xf7\x5a\xf4\xd5\x4c\x51\x93\ \xa2\x02\xb1\xb7\xd1\x0e\xbe\x9d\xe9\x05\x54\xd0\x95\x70\x50\xd3\ \x52\x9c\x4b\x60\x94\x59\xce\xd3\xfc\xc2\xf5\xe9\x4c\x87\xf1\x54\ \x5f\xcb\x3d\x00\x40\xd7\x80\x66\xcc\xc5\x7f\xd9\x99\xf6\x0b\xa5\ \x61\xea\x86\x0e\xc7\xd1\x81\xf6\xe9\x49\xf3\xfb\xa7\x64\x63\x44\ \xd3\xd3\x36\xd7\x33\x93\x28\x75\xf7\x8d\x1f\x48\xf7\xdf\x50\x32\ \xcb\xb1\x9c\xa8\x80\xe2\x82\x26\xc1\x41\x65\x20\xa2\x35\xba\x96\ \xcf\x16\x54\xab\x82\x26\xad\x79\x1b\xac\xb4\x4e\x15\x8d\x0b\xec\ \xad\x58\x49\xce\x90\x55\x76\x1b\x3b\xf3\x43\x09\x18\xc5\x0d\x39\ \xb1\x75\x2a\x18\xd9\x0d\xfc\x9d\xb1\xe8\xb3\xba\x79\x24\x7b\x98\ \x1d\x16\xb2\x9c\x26\xe3\x3a\x26\xb9\xe7\x70\xd0\x8a\x65\x39\xde\ \xa4\x0c\x77\x61\xbf\x8e\x22\x5e\x0d\xfe\x1d\x51\xae\x8a\xf9\xad\ \xa9\x7b\xab\x0e\xbb\x4e\x03\xdf\x6d\x1a\x14\x6f\x9c\xa4\x5a\xd0\ \xf7\x7e\x9e\xb8\x49\x93\x90\xb8\x68\x77\x7b\x0b\x93\x30\x39\x8b\ \x62\x48\xf0\xba\x00\x68\x96\x5c\x9c\x89\x64\xaa\x11\xcb\xeb\x85\ \x4a\x39\xd4\x0b\x5e\x67\xbe\x22\x1a\x32\x33\x9e\x98\x5a\x13\xae\ \x3b\x8c\x54\x8f\x64\x66\xda\x4c\x68\x6c\x90\x8d\x60\x8c\x20\x41\ \x5f\x63\x27\x2e\xc6\x7a\x3e\xab\x24\xa5\xe1\x49\x29\xab\xc1\x31\ \x0e\xa2\xc8\x98\xe9\x44\xef\xc2\x79\x9e\x27\xdf\xaa\x44\xe4\x06\ \x7a\xaf\xe0\xcc\x27\x59\x67\x66\x4e\x1d\x4e\xe1\xed\x91\x14\x80\ \x8b\x09\xd3\xb7\xfa\xa7\xa8\x9c\x6e\x82\xa4\x09\x2a\x53\x42\xa0\ \xce\x47\xd2\xb7\x91\x07\xbd\x29\x47\xd8\x46\xf8\x98\x2d\x83\x4d\ \xa7\x4f\xa2\x6f\x6b\x5c\x26\x65\xd5\x6d\x4a\x2a\xc7\x9e\x52\x03\ \x70\xd8\xac\xc5\xce\x53\x53\x25\x36\x13\xc3\x9b\xc6\x9f\x24\xc7\ \xe3\xd9\x23\x3d\x36\xe4\xb6\x64\x12\x07\x7d\x76\xaa\x34\xbd\x1a\ \x4d\x95\xe1\x84\xbc\x54\x38\xf8\xb5\xc0\xd3\x07\x81\x17\x09\xe5\ \x4a\x0b\xfe\xb4\x76\x58\xba\xb5\x83\x83\x7d\x20\xc4\x5a\x96\x5a\ \x27\xf8\x7a\xb4\x06\xe9\xcc\xd6\xe4\x4e\x54\x1e\x6c\xd7\x52\x49\ \x6f\x93\x66\x61\x12\x2e\x16\x9d\xc0\xde\x58\x18\x71\x9c\x35\xb5\ \xc4\xab\x5b\x8a\x67\x61\x31\x58\x2c\x90\x13\xe4\x16\x9f\xbc\x5e\ \x4d\x22\xb0\xbe\x0a\x23\x9e\x6a\x3c\xf5\x7c\xe4\x0b\x9f\x8a\xc6\ \x81\x84\xb4\x89\x48\xf7\x83\x93\x59\x21\x46\x33\x5c\x91\xcc\x6c\ \x4f\xdb\xa2\x50\x07\x8d\x43\xee\x62\xf1\xbf\xce\xd6\x51\x81\xe4\ \x12\x34\x05\x17\x67\xd5\x39\x0e\xa9\x40\x45\xf4\xe5\x0a\x77\x4c\ \x60\x94\x9c\xf7\xdd\x69\x76\x07\xea\x04\xb1\x9f\x03\x84\x29\xfd\ \xf8\x89\x0e\x95\x04\x14\x96\x1c\xbc\x90\xaa\x85\xa2\x42\x79\x47\ \x5e\x40\x39\x33\xd8\xd9\x9b\x24\x37\xd7\x54\x60\xe4\x77\x61\x45\ \xa7\x32\x22\xb3\xe7\x0b\xdd\x34\xd7\xc9\x64\x6a\x41\x68\x4c\x27\ \xc9\x91\xc1\xc4\x19\x77\x3b\xca\x0a\x4d\x17\x76\x5e\x46\x08\x75\ \x81\x08\x91\xf3\xb6\xf1\xf7\x3c\xa9\x58\xa3\x49\xa6\xf3\x89\x7b\ \x16\x44\xd7\xea\x51\xa8\xcf\xdd\xac\xbb\x9b\x74\xc3\xb4\xb1\xe7\ \xa4\x38\x33\xdd\x68\xc6\x32\x94\x16\xac\x2e\xd1\x9a\xd2\x1a\xe0\ \x4f\x69\x59\xb7\x4c\x3c\x69\x25\x93\x97\x40\x7f\x49\x17\x04\x57\ \x4b\x08\x80\x26\x97\x1c\xe7\xef\xe6\xba\x0d\x50\x1e\x13\xde\x06\ \x2d\x8e\x00\x35\xfe\xc4\x72\xe7\x44\x75\xa6\x16\x98\xb6\x5e\xa3\ \xd1\xf6\x34\x1b\xaa\x22\x98\x89\x59\xdc\x85\xaf\x2f\x35\x93\xab\ \x5f\x1f\x6a\x9e\xc7\x01\x28\x4a\xcb\x04\x90\x98\x96\x97\x3b\x10\ \xc9\x20\x3b\xb3\x4b\x86\x88\x46\xe3\x48\x66\x23\xcf\x08\x74\x93\ \x7a\x02\x59\xcd\x48\xeb\x95\x09\x89\xbe\xd2\x27\x9a\x77\xb1\xba\ \x11\xb2\xb4\x0d\x67\x7d\x89\xf1\x72\x7a\xdf\x38\x86\xec\xf4\x72\ \xee\x17\x3e\xe0\x54\x4c\xe0\xd4\x06\x39\x72\x11\xa9\x08\x09\x7b\ \x00\xa9\xbc\xbd\x85\xbf\x91\xc5\x67\xb6\xb7\x49\x43\xc1\x57\x34\ \x43\x03\xd8\x63\x53\xc4\xa0\x6c\xdb\x71\x81\x25\x25\xd6\x62\x9f\ \x25\x5d\xe0\x00\xe1\xb3\xa8\xae\x20\xb2\x6a\x02\x10\x2f\x2d\x8b\ \x26\x73\x93\x99\x75\x6d\x8b\xe8\x73\x26\xf8\xb0\xdd\x04\xe5\x30\ \x77\x4d\x49\x66\x4f\xc2\x79\x8f\xa0\xad\x88\x4d\x17\xb8\x39\x75\ \x57\x35\xaf\xbe\xf9\x0b\xdf\xfc\x30\xcb\x05\x5a\xb0\x72\x3f\xad\ \x27\x35\xab\xf8\x59\x29\x09\xb6\x0e\xf6\x88\x9d\x2f\xc9\x29\x43\ \x22\xbb\x1c\x27\x8d\x5f\x49\xbe\x5c\x65\x7e\x9b\xb3\x0c\xd1\x50\ \x6b\x91\x44\xde\x70\x5d\x84\xad\x40\x24\x78\xa9\x60\xef\x67\xbb\ \x9e\x39\x7b\x15\xd9\x6f\x1c\x25\x19\xfd\xd9\xef\x5f\xd0\x29\xb4\ \x53\x78\x48\x84\x39\x9b\xc7\xa8\x79\xb4\x52\x1f\x6b\x4d\x68\x17\ \x32\x25\x48\x1e\x5e\x2b\x77\x65\xb5\x8c\xe8\x48\x24\x01\x12\x25\ \x67\x62\xa4\x80\x2d\xa5\x6c\x6b\x91\x88\x17\x16\xfb\x1c\x1b\x86\ \x26\x34\x3d\x99\x6b\x95\xbc\xa3\x9a\x49\x2e\xce\xa8\x64\x9b\x62\ \x9b\xd6\xc9\x9c\x2a\x41\xe5\x50\x74\x38\xdb\x05\x14\x38\x83\x19\ \x27\x9c\x39\x21\xb8\xc3\x6a\xc8\xce\x09\xe1\xa6\xdd\x36\xe4\xc9\ \xb5\xc2\x14\x87\x09\x4c\x6e\x88\xa6\xf3\xe5\x73\xfb\xd5\x03\x00\ \xa9\x3b\x93\xcb\x92\x6c\x4f\xd2\xfe\x2c\xa1\x9f\xfb\x0c\xe8\x20\ \xc8\x34\xc1\x02\xd9\xb7\x2e\xd5\x9b\xc6\x64\xa3\x29\x27\xe1\x39\ \x23\xd7\x2e\xd3\xfa\xf1\x27\x39\xfc\x77\x1b\x39\x17\xdd\x0e\x99\ \x0b\xa8\xe5\xc4\x11\xf4\x17\xf3\x78\xc6\x55\xc4\xba\xd4\x8c\x4a\ \xbd\x3a\x70\xe5\x93\xe1\x18\xb3\x0e\x3b\xfc\x36\xab\xd3\xb9\x2b\ \x14\x33\xbd\xbb\x1c\x95\x6b\xd9\xc9\x18\x73\xb1\xab\x50\x6c\x3d\ \x4b\x70\xe9\xa8\x5e\xef\xac\x0e\xb3\xc4\xe9\xa2\xa4\x89\xb4\xca\ \xd3\x68\x06\x28\x8b\x12\xb3\xe4\x08\xcf\xed\x95\x52\xcc\x3c\xb7\ \x3d\xc8\x15\xb9\x7d\xf4\xd4\xe7\x62\x40\xb8\xfa\x56\x8a\x5f\x47\ \xfd\x69\x96\x90\xaa\x92\x5e\xb8\x87\x68\xb1\xfd\x42\xcd\x98\x41\ \x85\x5c\x9b\x06\xd2\x26\x4d\x7a\xa1\x8f\x7c\x3a\x04\xec\x4e\x16\ \x0f\xee\xea\xa7\x14\x91\xc5\xd1\xa4\xa0\x7f\x9e\xa3\x66\x84\x3a\ \x2f\xf2\x4a\x7e\x7f\x5e\x30\xd8\xd2\xdf\x86\x8e\xf6\x6f\xd2\xf4\ \xad\x39\xec\x9c\x62\x19\x9c\x8a\x3c\x0c\x2d\x6a\x12\xb7\xc3\xd6\ \x39\xb2\x32\x5f\x85\x76\xb7\x98\xd2\x93\xd0\xa2\xc6\x82\xc4\x81\ \x5c\xb7\x71\x2b\xd3\xbf\xb3\xe5\x34\x82\xa8\xf9\x48\x43\xca\xd1\ \xe1\x50\x26\x37\x26\x27\x85\xcd\x8a\xe5\x94\xf1\x22\xd8\x4b\x76\ \x8d\xdf\xeb\xcc\xce\xc7\x9d\xdd\xad\xa7\xf2\xda\xb2\xbb\x6d\xbd\ \xf5\xd4\xb2\xe8\x4d\x68\xd5\xbf\xe1\x4e\xbf\xb5\xec\xc5\x24\x06\ \x44\xad\x0b\x27\x3b\x1c\x1f\x8b\xf9\x4c\xf5\x2e\x7a\x9f\xd9\x0d\ \x36\x6b\xd9\x56\x74\x66\xd8\xb1\xef\xb3\x92\x96\x7e\x2e\xfb\x78\ \xa4\xf0\x17\xbd\xf6\x63\xbc\x4d\xa6\xd4\x87\x68\x52\x10\x33\xcf\ \xa3\xf3\x4a\x7d\x19\xf5\xf0\x50\xe9\x5b\x8f\x44\x5c\x48\x2a\x89\ \x94\xcc\x3c\x54\x70\x76\x98\x8c\x04\x9f\x2a\x7a\x46\x4e\x49\x0a\ \x7e\xed\x7d\x92\xde\xaf\x6f\x4e\xa7\xd8\x75\xb5\xe9\x40\x60\xaa\ \xd8\xe6\xbd\xa0\x73\x4c\xa2\x4b\x4e\xd9\x3a\xfb\x68\xa8\x32\x6f\ \xa1\x4e\x0b\x04\xf2\xfd\x9c\xd1\xc8\xec\x0a\x2d\x2b\xeb\x24\x6a\ \x91\x3c\x3d\x9b\x31\x9c\xe8\x25\x3f\x26\xf4\x68\xbd\x8c\x8b\x2b\ \x16\x43\x10\xbf\xb0\xeb\x42\xf0\x92\x5d\x8e\xa0\x49\x37\xb6\xe2\ \x2c\xba\x05\xb0\x0d\x92\xe6\x1b\xac\x1a\x09\x06\xf7\xce\xfa\x8a\ \x82\x83\x4a\x6a\x89\x3c\xc9\x4c\x4e\xde\xd6\x4b\x2a\x23\xe4\x35\ \x13\xaa\x60\x7f\x9c\xcb\x90\x22\x14\x9e\x22\xdb\x71\x6a\x74\xc2\ \x64\x60\x27\x82\x63\xbb\x18\x41\x53\x68\x35\xbd\xee\x4d\x24\x6d\ \x06\x1d\x2b\x88\xa4\xae\x90\xf4\x73\x09\xc5\x89\xe6\x71\x88\x4f\ \x08\x5a\x28\x9d\xbd\xb9\xae\x0a\xa1\x87\x61\x6a\x0c\x10\xa6\xcd\ \x16\xe5\x34\x68\x32\x73\x1a\xe0\xc4\x77\x44\x83\xc8\xea\x1a\x7e\ \x26\x09\xe3\xa6\x66\x72\x86\x9e\x4f\x78\x57\x79\x33\x61\x7e\xef\ \x39\xf8\xd0\xae\xa5\xc5\x58\x1a\x73\x75\x63\x0c\xbf\xd3\x9c\x51\ \x4a\x24\xbe\x8f\x3b\x23\x82\xdd\x93\xe4\x62\xba\xcc\x9d\xdd\x32\ \x9e\x70\x99\x1c\x74\x05\x00\xe4\xf0\x33\x7f\x84\xab\xaa\xa6\xdf\ \x92\x09\x6a\x11\xa2\xef\xcd\x16\x89\x84\x45\xce\x04\x11\xd5\x86\ \x3c\xea\x88\x81\xb5\x01\xee\xc7\xd4\x79\xdb\xbe\xe5\x4d\xda\xc0\ \xe5\x98\xe7\x92\x36\x80\x4e\xa5\xcb\x09\x16\xcf\xc2\x03\xb4\x73\ \x3f\xd8\x26\x1e\xbf\x2c\x10\x33\x9c\x59\x20\xf0\xd1\x62\x66\x37\ \xb4\x41\x0e\xb8\x32\xe5\x4a\x84\x2c\xcd\x39\xe5\xd7\x8a\x62\xdf\ \x87\x86\x50\x3b\xea\x21\xef\x3f\x88\x93\xcc\xdb\x2a\xff\xbe\x2c\ \x4f\x2e\xb6\xbb\x50\xda\xee\x1b\x6a\xef\xe9\xee\x90\xd4\x24\x5e\ \x81\x11\x55\xd1\x5b\xe8\xe1\x0c\xd8\xc4\x0d\x5d\x91\xd3\xec\x5a\ \xcf\x8d\x93\x33\x27\x2f\x5d\x98\x24\xe2\x1d\x1c\x0a\x63\xb2\xb7\ \x07\x13\xd8\xe8\x1a\x71\x41\xb1\xf2\x4c\xba\xb1\x98\x4b\x1c\x22\ \xe8\x05\xa2\xfd\xb8\xa4\xf9\xb2\x45\x93\x6d\x39\x5e\x24\x0d\xe7\ \x0d\x69\x54\x33\xa4\x26\x11\x1c\xac\x70\x7a\x5f\xc6\xd0\xd9\x3c\ \xdb\x96\x56\x1e\xdf\x86\x36\xf3\xd1\x09\x60\x4b\x64\x93\xb1\xa4\ \xce\x6e\xe0\xab\x2c\xcf\x10\xf7\x84\x88\x52\x7c\xfa\x3f\xa5\x38\ \x6b\xb5\x39\x1f\x74\xa6\xf2\x19\xc7\x7b\xad\xee\x6e\x47\xd8\x23\ \xb7\x5e\xde\xed\x39\xa9\x5d\xdb\x29\xe9\xe1\x00\xe6\x26\x33\xdf\ \x06\xb7\x12\x45\x72\xf3\xd1\x8c\xd1\xcb\x63\xd3\x82\x82\xef\xae\ \x12\x9a\x8e\x8d\xca\xa9\x49\xba\x8c\x78\xc3\xd0\x83\x5e\x38\x47\ \xf8\x35\x01\x9e\x45\x34\x91\xb9\x69\xe2\x10\x73\x4b\x7c\xce\x3c\ \xdb\x7b\xae\x26\x42\x98\xd4\xd4\xb8\xa4\x89\x5c\xed\x51\x79\xcd\ \x67\x45\x6a\xd9\x72\x93\xcd\xcd\x59\x4d\x2a\x57\x9b\x7b\x51\xd4\ \x6a\x0b\x17\xd1\x67\x4f\x1c\xff\x38\xb1\x41\xd8\x99\xc9\x32\x53\ \x0e\x63\x27\x9f\xe8\xc1\xc5\xc7\xb9\x71\xec\xb3\x7a\x9b\xa1\xcb\ \xe6\x54\x49\xb2\x61\x72\x05\x93\xa7\x0b\xc7\xb3\xd4\x63\xa4\xc7\ \xfd\x6d\x06\xbd\xa2\xa7\xe8\xb6\x9b\x61\x7a\x3b\x6d\xee\xed\xb1\ \x79\x9a\xb0\x9b\x66\x2b\x49\x55\xa9\xc0\xa7\xf3\xc0\x7d\x77\x71\ \x17\x89\xae\xd1\x11\x4d\x96\x68\xbb\x74\x99\x69\xc0\xec\xa3\xd1\ \xbf\x57\x9e\x18\x66\xf3\xbd\xe2\xb4\x61\x58\x68\x87\xc3\x19\xb6\ \x8e\xb0\xff\x2d\xc2\xdd\x2f\x1a\x59\xe9\x4a\x08\xc5\xd4\xc6\xa9\ \xd1\xc4\xc9\x7a\xaa\x06\xab\x17\x18\x41\x4e\xb3\x10\x62\xb7\x00\ \xf4\x66\x37\xc1\x94\x3c\xef\x05\xc9\x66\x25\xff\x5c\x85\x4b\x84\ \xe4\x37\x63\xe1\xbe\x76\xef\xb6\xd8\x35\xd9\x82\xc4\x58\x2a\xec\ \xef\x38\x2b\xe6\x52\x45\xe6\xa3\xd8\x66\xd2\x38\x2b\xf6\x86\x93\ \x14\xe9\x89\xa2\x96\xc8\x0e\xec\x53\x7a\x1e\xce\x9b\x46\xf4\x48\ \xfc\x22\xcb\x88\xba\xcd\xcb\x16\xc4\xd3\xd1\x65\xed\x55\xd5\x52\ \x67\xc7\x11\xef\x69\x58\x7c\x07\xcf\xea\xd3\x15\x90\x33\xf2\xba\ \x52\xd2\xd6\x5d\x4e\xb8\x74\x8a\x74\x64\x3a\x09\x16\x96\x96\x1c\ \xcf\x0b\x0c\x38\xe5\xa5\x49\x18\x20\x7d\xd7\xda\x87\xd0\xb1\xa2\ \x4e\x1d\xe7\x4d\xaf\xed\x26\x74\x2c\xfc\xac\x72\x4c\x2e\x3d\x20\ \x72\x1c\x22\xbc\xc1\x5f\x74\x80\xd8\x28\xc5\xe2\xf8\xda\x1b\x44\ \x74\xa9\xe9\xd8\x63\x57\xd1\x59\x97\x53\x29\x6d\x82\x9c\x0a\x05\ \x0f\x81\x66\x27\x5b\xb6\x44\x3d\x57\x8c\x2a\xd7\xd9\x6e\x71\x43\ \xd6\x41\xce\x05\xf1\xce\x14\xa3\x84\x90\x1b\x88\x79\x4f\x76\x40\ \xb7\xa5\x83\xea\x21\x5b\x08\x13\x8a\x07\x07\xb3\xa4\xbb\x85\x58\ \x91\xe8\x99\x1d\x1b\xd1\x99\xfc\x33\xc8\x1c\x5b\x12\x62\x3b\xc6\ \x04\x86\xe2\xfc\xc5\x29\x3c\xc8\x96\xe2\x63\xab\x14\xa5\x11\xed\ \x7c\x17\x23\xa2\xab\x46\x52\x89\xe8\x46\x51\x1a\x5e\xe0\x91\x05\ \xb1\xed\xb2\x48\x7a\x38\x8f\xb4\x67\xbe\xd4\x6a\x00\xf0\x3e\x19\ \x27\x09\xcf\xe4\x98\xa2\x32\x64\x51\x65\x5a\xc8\x04\xb1\x97\xec\ \x3f\x5c\x74\x69\x9e\x82\xbc\x87\xea\xec\x36\xd3\x1c\x82\xdd\x54\ \xe8\x1b\x35\x19\x43\x56\xcd\x07\x8e\x04\x9d\x0f\x08\x3b\x57\x85\ \xdd\x3b\xdf\x5c\xa7\xdd\x27\x58\x1d\x73\x5e\x96\xf0\x12\xaf\x07\ \x1d\xcc\x31\xc8\x1d\x94\x0c\x18\xb5\xf8\xa0\xb4\x92\x91\x87\xe7\ \xd5\x31\x4b\xa2\x7c\x95\x6d\x1a\xef\x2b\xf4\xb6\x34\xb9\x27\xbe\ \xa1\x33\x9f\x23\xb3\x24\xca\x7c\x8e\xf2\x46\x41\xb7\x51\xdb\xbd\ \xcd\x36\xa7\x12\xdf\x36\x9f\x06\x73\xa9\xae\xe3\x11\x19\xe9\x64\ \x70\xd1\xcc\xca\x36\x99\x08\x8a\xcc\x30\x2f\x00\x55\x4f\x9b\x20\ \xc9\xb2\x25\xda\x71\x51\x55\x58\xe5\x05\xdd\x33\xcd\x2c\xcf\x82\ \xe6\x0d\x30\x7a\x33\xbb\x92\x17\x40\xf5\xc9\x8a\xae\x4d\x11\x82\ \x6b\x04\x26\x04\xff\x11\x34\x78\x82\x22\x1d\xf3\x88\x63\x20\x69\ \x6a\x75\x1a\xcf\xc8\x05\xde\xcd\x00\xe6\x63\xc5\x3d\x9a\x4e\xd7\ \xa8\xd1\xee\x9c\xb6\xc0\x8e\xd6\x8d\x62\x08\x25\x25\xfc\x99\xb5\ \x49\x19\xee\x80\x09\x68\x6d\xed\x63\x9e\x95\xd4\x53\x78\x78\x27\ \x12\x00\x15\x83\x39\x95\xd0\xcb\x62\xb0\x76\x2c\x1a\xb3\x18\xd4\ \x1d\x08\xd0\x2c\x06\xb2\xd4\x98\xcd\x62\x70\xa6\x9c\x17\xa8\x18\ \xc0\x9d\xcf\x13\x54\x7c\xbd\xa7\x92\x37\xa8\x18\xb4\x5d\x93\x47\ \x68\xc7\x67\xa5\xe4\xbc\x42\xc5\xba\xd8\xb9\x3c\x43\xc5\xa0\x17\ \xcb\x3b\x54\xa8\xfd\x67\xe0\xfb\xb2\x40\xe0\xff\x01\x8e\x14\xc8\ \xee\ \x00\x00\x17\x10\ \x00\ \x00\xce\xf9\x78\x9c\xed\x5d\xe9\x6f\xe3\x46\xb2\xff\x3e\x7f\x85\ \x9e\xf2\x25\x83\x67\x52\x7d\x1f\x8e\x3d\x8b\x97\x0c\x36\x58\x60\ \xf3\x16\xc8\x81\xfd\xb8\xe0\x48\xb4\x2d\x44\x16\x05\x4a\x1e\xdb\ \xf3\xd7\x6f\x55\x93\xe2\xa5\xd6\x7d\x50\x96\x63\x67\x62\x91\x6c\ \x76\x75\xff\xea\xe8\xaa\xea\x43\x37\x7f\x7b\x79\x1c\x75\xbe\xc6\ \xe9\x74\x98\x8c\x6f\xbb\x34\x24\xdd\x4e\x3c\xee\x27\x83\xe1\xf8\ \xfe\xb6\xfb\xc7\xef\x7f\x0f\x4c\xb7\x33\x9d\x45\xe3\x41\x34\x4a\ \xc6\xf1\x6d\x77\x9c\x74\xff\xf6\xe9\xc3\xcd\xff\x04\x41\xe7\xa7\ \x34\x8e\x66\xf1\xa0\xf3\x3c\x9c\x3d\x74\xfe\x31\xfe\x73\xda\x8f\ \x26\x71\xe7\xfb\x87\xd9\x6c\x72\xdd\xeb\x3d\x3f\x3f\x87\xc3\xfc\ \x66\x98\xa4\xf7\xbd\x8f\x9d\x20\xf8\xf4\xe1\xc3\xcd\xf4\xeb\xfd\ \x87\x4e\xa7\x03\x74\xc7\xd3\xeb\x41\xff\xb6\x9b\xbf\x30\x79\x4a\ \x47\xae\xe0\xa0\xdf\x8b\x47\xf1\x63\x3c\x9e\x4d\x7b\x34\xa4\xbd\ \x6e\x59\xbc\x5f\x16\xef\x23\xf5\xe1\xd7\xb8\x9f\x3c\x3e\x26\xe3\ \xa9\x7b\x73\x3c\xfd\xae\x52\x38\x1d\xdc\x15\xa5\xb1\x35\xcf\xdc\ \x15\xa2\xd6\xda\x1e\x61\x3d\xc6\x02\x28\x11\x4c\x5f\xc7\xb3\xe8\ \x25\xa8\xbf\x0a\x6d\xf4\xbd\xca\x08\x21\x3d\x78\x56\x96\xdc\xac\ \xd4\xf5\xcb\x08\xa0\x58\xda\x18\xf7\xb4\x4a\x1d\xe0\x9f\xc0\xbf\ \xe2\x85\xf9\x8d\x70\x9a\x3c\xa5\xfd\xf8\x0e\xde\x8c\xc3\x71\x3c\ \xeb\x7d\xfe\xfd\x73\xf1\x30\x20\xe1\x60\x36\xa8\x54\x33\x47\xbf\ \x46\xb7\xc6\x92\x71\xf4\x18\x4f\x27\x51\x3f\x9e\xf6\xe6\xf7\xdd\ \xfb\xcf\xc3\xc1\xec\xe1\xb6\xcb\x99\xbb\x7a\x88\x87\xf7\x0f\xb3\ \xe2\x72\x38\xb8\xed\x42\xef\xb8\xb4\xc4\x5d\x57\x84\x87\x66\x05\ \xf2\xaa\xae\x8b\x27\x24\x14\xba\x93\x32\x26\x0d\x77\x25\xe6\x4d\ \xbe\x1e\x24\x7d\x6c\xc3\x6d\xb7\x7f\x1f\x0c\xfb\xc9\x38\x44\xd8\ \x3e\x41\x91\x9b\x41\x7c\x37\xc5\xa2\x19\x3d\xbc\x02\x82\xcc\x3d\ \x83\xa7\x00\x58\x1c\xa5\x3f\xa7\xd1\x60\x08\x62\x92\x95\xcb\x4a\ \xd6\x9f\x08\x42\x64\xfe\x0e\xbc\x35\x9d\x25\x93\x79\x59\x68\xc4\ \xec\x75\x04\x94\xf1\x66\xd0\x4f\x46\x49\x7a\xfd\xdd\x9d\xfb\xf9\ \xc1\xdd\x4a\x00\x97\xe1\xec\xf5\x9a\xfe\xd0\x2d\xdf\x49\xee\xee\ \xa6\x31\x40\x41\x2a\xf7\x1c\x1e\xf0\x06\xd0\xd2\xdd\x4e\x6f\x3f\ \x6a\x24\xe4\x92\x59\x41\xa9\xf5\x91\xa5\x7e\xb2\xb6\x20\x7b\xd3\ \xab\xf7\x7f\x4b\xb8\xb8\x51\xe2\x54\x70\x01\x2d\xd5\x02\x5c\x40\ \xd6\x1c\x0c\x2e\x2b\xd8\xc9\xe0\xb2\x42\x1c\x02\x2e\xae\x99\x14\ \xd6\x4b\xd6\x0b\x97\x15\xea\x80\x70\xd9\x2d\xe0\x22\x84\xa9\x58\ \xee\x0c\x97\xa4\x5b\xc1\x05\x5a\x64\x37\xa2\xe6\x47\x49\xf2\x43\ \xa1\x24\x98\xe0\x5b\xa1\x44\x74\xdf\xee\x6a\xb2\x98\x90\x5b\xa1\ \xf4\x45\xf6\xc9\x46\x22\xec\xb5\x54\x4c\xe8\xc3\xa1\x44\xc9\x32\ \x94\x4a\x7a\x94\xad\x01\x62\x07\xbd\x39\xae\x0e\xc2\x48\x29\x25\ \xf4\xcd\x28\x2f\x80\x74\x3b\x1b\x40\xdc\xcf\x76\xf4\x35\x35\x9a\ \x4b\xb1\x84\xfe\x0a\x93\x5d\x29\x65\xd6\x48\xc4\x0e\x4d\x3d\x94\ \xdc\x50\xad\xf7\x34\xd9\x64\x63\xed\xa2\xda\x6e\x29\x2e\x1e\x0c\ \x36\xd6\x2e\x6a\xe8\xe1\x50\x52\xfb\xba\x4d\x5b\xa0\xa4\x56\xb8\ \x4d\x15\x2c\xa5\x57\x5c\x15\x3b\x92\x3a\x57\x28\x73\x3f\x65\x7e\ \x18\x89\x3e\x28\xc2\x7e\xc9\x50\x6b\x3d\xc4\xc2\x67\x9f\x80\xcf\ \x3e\x89\xfb\x18\x59\xcd\x6b\x2a\xbc\xf5\xd9\x2b\x06\x13\xf5\xa2\ \x7c\x50\x50\x2c\xfd\xfe\xc9\x7f\x5e\x00\xa1\xce\x75\x47\x32\x15\ \x82\x5c\x12\x0b\x9f\xa9\xb7\xe0\x6b\x56\x90\x02\x54\xf0\x87\x78\ \xcb\x7c\xbb\xed\x6a\x21\x42\x02\x2e\x90\x59\x5f\x69\xde\xac\x20\ \x49\x87\xf7\x43\x08\x3e\x00\xf0\x90\x08\xcd\x04\x14\xe7\x12\x0c\ \x1c\xd8\xb7\xc6\xab\x00\x54\xa5\xdf\x10\x68\x54\x5c\xc4\x55\xc8\ \x34\x5e\x14\x54\x6e\xd0\x1e\x12\x4a\xec\x29\x48\x42\xf6\xb3\x14\ \x1a\xe8\x36\x75\x25\xe5\x5e\xe8\xe5\xac\x68\x56\xb3\x8e\xab\xbb\ \x00\xc0\x0c\xe8\xf2\xfb\x06\xc0\xd8\x77\x0d\x00\x68\xe8\xfb\x96\ \x00\x21\xb9\x7a\xdf\x00\x28\x22\xde\x39\x00\xe2\x02\x55\xe0\x6e\ \x38\x9a\xc5\x69\xb5\xcb\xd9\x1d\xa1\xb9\x87\xdd\xa3\xe8\x4b\x3c\ \xba\xed\xfe\x3a\x1c\xdc\xc7\x83\xce\x97\x24\x1d\xc4\xe9\x62\xa9\ \xc7\x78\xfc\x74\xdb\xfd\x31\xfe\x1a\x8f\xa6\xfe\xa7\xc1\x2c\x49\ \x46\xb3\xe1\xa4\x51\x55\x96\x72\x1e\x8e\xc7\xf0\xf1\x0b\xbe\x5e\ \xbc\xed\xfc\xa5\x60\x38\x86\x96\x4d\x92\x51\x34\x1b\x26\xe3\x20\ \x6b\xe8\x14\x9c\xa1\x5f\x7f\xfe\xb1\x74\x6b\xef\xe2\x5f\x92\x74\ \xf2\x00\x2f\xdc\xbf\xd6\x9d\xa6\xea\x13\xe8\x5f\x35\x14\x42\xaf\ \xe9\x09\xaa\x12\x61\xd5\xfb\x43\x86\xfe\xe6\x52\xb3\xff\x37\x9a\ \x3c\x44\xd5\xf2\xf1\xf4\x69\x04\x7e\x59\xf6\xd7\xd6\x72\x12\x77\ \xf1\x4f\xc9\xe3\x24\x99\x0e\x67\x71\x93\x7e\xf1\x00\xc8\x9b\x1a\ \x21\x56\xa9\xab\xe2\xfe\x01\xbf\xa2\x59\x92\xde\x76\x93\xa7\x99\ \xb7\x61\xe0\xef\x4d\x1e\x86\xfd\x3a\xfd\x9f\xa3\xa7\xe9\x74\x18\ \x8d\x7f\x1c\x3d\xa5\xcd\x26\x54\x9f\x09\x2d\xc8\xd2\x4e\xd5\xe3\ \xe9\xc1\xe7\xf8\xeb\xd0\xe1\x8e\x09\x61\x56\xa7\xf7\x79\x78\x77\ \xf7\x34\x8d\xff\x89\xf9\xe4\xe1\xf8\xbe\x49\xb2\xf1\x18\xa8\x56\ \x9d\xfb\x41\xf6\xf4\xa7\x64\x8c\xf3\x11\x0d\x5f\xb7\x81\x73\x99\ \x96\xcb\xe9\xba\x57\x5c\xc5\xe5\x3b\x25\xd9\xf2\x29\xd0\x14\xdd\ \x6a\x91\x78\x14\x7f\xcd\xbb\xa3\x54\xed\x49\xf4\x6d\xf8\xf8\x84\ \x69\x72\xc6\x6a\x49\x94\xde\x42\x47\x2a\x08\xfc\x38\x8a\xc7\x83\ \x66\xbf\xdd\x4d\xa0\xac\x9a\x9c\xae\xb3\xae\x7c\xf8\x98\x0c\x40\ \x59\x1f\x9f\x50\x35\x46\xaf\xcb\x61\xe0\xdb\x8b\x9b\x58\x10\x37\ \xbf\x60\x97\x12\x37\x1c\x57\x82\x8b\x4c\xd7\xd6\xda\x0c\xe9\x31\ \x52\x97\x64\x33\x24\x6b\xd5\x66\x48\x71\x0e\x36\x43\xaa\x36\x6c\ \x86\x34\xa7\xb7\x19\x8a\xb4\x65\x33\x6a\xe9\x8f\xb6\x6c\x86\x5a\ \x10\xb7\x63\xd8\x0c\xe5\xf1\xab\x2f\xc9\x66\x28\xd3\xaa\xcd\xd0\ \xe4\x1c\x6c\x86\x66\x6d\xd8\x0c\x2d\x4e\x6f\x33\xb4\x6a\xcb\x66\ \xe8\x25\x43\xfc\x49\x6d\x86\x59\x10\xb7\x63\xd8\x0c\xc3\x2e\xdb\ \x66\x18\xd1\xaa\xcd\x30\x0b\x1e\x6b\x1b\x36\xc3\x98\x36\x6c\x86\ \x25\xa7\xb7\x19\x96\xb5\x65\x33\xec\x92\x21\xfe\xa4\x36\xc3\x2e\ \x09\x90\x76\xb1\x19\xdb\x24\x74\x0c\xb9\xc0\x94\xde\xaa\x84\x4e\ \x20\x2f\xdb\x6c\x72\x15\xb4\x1b\xa0\x71\x13\x9c\x45\x88\x26\x48\ \xd0\x52\x62\x27\x68\xc1\x7c\x0a\x11\xb4\xe6\x74\x09\x15\x9c\x83\ \xdb\x25\x4c\x20\x0f\x67\x44\x57\x25\x78\x82\x0b\x4f\x0b\x4b\x16\ \xd8\x56\x6d\x88\x14\xe7\x61\x43\xa4\x0a\x5a\x4a\xf4\x04\xad\xa4\ \x7a\x02\xde\x96\x0d\x51\x2c\x38\x8f\x74\x4f\xc0\x4f\x61\x43\x54\ \x55\xb0\x2e\xd2\x86\x28\xd3\xb2\x1f\xa2\xc9\xa2\x44\xb5\x93\xf6\ \xa9\xd9\xb2\x13\x26\x7e\x02\x7d\x7a\x1b\xa2\x55\xd0\x5a\xc2\x58\ \x7b\x3c\xcf\x56\xd2\x3f\xb5\xd1\xf3\x88\x09\xa0\x4b\xb7\x21\x46\ \xd4\x3c\xba\x36\x92\x40\xe7\xe1\x87\x18\xd3\x8e\x1f\x62\x49\xd0\ \x42\xfa\xd8\xd6\x7d\x81\x13\x27\x83\x96\x05\x11\x27\x4e\x07\x05\ \xf4\x70\x36\x64\x8b\x84\x90\x24\xd4\x93\x93\x79\xeb\x09\xa1\x2d\ \x01\xa8\xf8\x80\xef\x13\x02\xe1\x99\x5b\x78\x57\x00\xe8\x77\x2e\ \x01\x94\xbd\x77\x00\xde\xf9\x5a\x5f\x29\x85\x27\x51\xfe\x9e\x00\ \x50\xf4\x02\x25\x60\xc9\x2e\xa9\x79\x79\xf0\xe1\x47\xd0\xfd\xdb\ \x6e\x34\x7a\x8e\x5e\xcb\xc8\xc0\xed\xe2\xbf\x7e\x48\xe3\xbb\xdb\ \xee\x77\x8b\x7b\x3a\xab\xf9\x50\xdf\xa6\x4f\x5b\x71\x66\x5e\x28\ \x38\x6b\x26\x2c\x85\xeb\x15\x6e\x58\x2b\x43\xae\xaa\x9b\xeb\x5e\ \x58\xb3\x18\xdc\xa0\x44\x32\x2c\x57\x8e\x4e\xf7\x39\x91\x3f\xc6\ \xc3\x19\x44\x06\xe0\xef\xa5\xbf\xe1\xa6\xff\x7f\x8d\xff\x98\xc6\ \x6b\xbb\xed\xdd\xa0\x1a\x6c\xb3\x4d\x7c\xef\x2d\xaa\xc1\x89\x37\ \xa9\x06\x3b\xee\x10\xf7\xc3\xbf\xc8\x25\x3f\x33\x9b\x3c\x5f\xcd\ \xb6\xe5\xfc\x91\x8a\xcb\x5d\x84\x72\x9d\x7c\xcf\xdb\xf3\x7b\x1a\ \x8d\xa7\x77\x49\xfa\x78\xdb\x9d\xe1\x47\x08\x63\xe3\xef\xa9\xd0\ \xa1\xb6\x54\xb0\x2b\x4a\x59\xa8\x98\xb2\xf4\xe3\x6e\x26\x45\xb3\ \x0b\xf4\xab\x10\xba\x68\x74\x50\x93\x42\x95\xac\xe4\xbf\x11\xc5\ \x3a\x11\xa9\x49\x35\xb9\xb5\x99\x34\x79\x78\xfc\x18\xcd\xd2\xe1\ \xcb\xf7\x01\x0b\x35\xb1\x92\x31\x73\x45\xe0\x37\xa0\xa1\x14\x06\ \xa2\x50\x79\xc5\x88\x0a\xb9\xd0\xf4\x8a\x49\x6e\x43\xa3\x14\xfb\ \x58\x02\x34\x49\xe3\x68\xf0\x4b\x3c\x7b\x48\x90\xcd\x51\xb9\x59\ \xb0\xff\x82\xba\xc2\xa0\x16\x51\x59\xc3\xd8\x7f\x45\xd5\x50\xa1\ \xa5\xbc\xb2\xaa\xe3\xce\x5b\xf6\xce\x5b\x36\xcd\xb5\x68\x7b\xb3\ \x96\x01\x7a\xd4\xcd\xdd\x3e\x7b\x43\x95\x0e\x36\xd9\x55\x4d\xb5\ \xac\xe5\x37\x4e\xbc\x05\xb6\x96\xae\x6b\x67\x13\x6c\xdf\x6c\xbb\ \x9b\x7d\xd9\x6e\xd8\x60\xd7\x33\x2d\xf6\xf2\x01\x20\x66\x36\xab\ \xec\xb6\x26\xd5\x84\xc6\xbe\x0a\x4b\x42\x6b\x98\x96\x46\x5a\xa7\ \xb0\xf3\x4b\x75\x15\x58\x1b\x4a\x62\x84\xb1\x57\x54\x87\x4a\x32\ \x4d\x6d\xa9\xb1\x38\x0c\x49\xbd\x30\x5a\x09\x50\xec\xa6\xeb\x81\ \xc5\x08\xa1\xac\x94\xca\x6c\x00\xa4\x34\x64\xda\xee\xa2\x82\x19\ \x44\x1b\x1c\xeb\x10\x78\x37\x83\x1f\x49\x0d\x4e\x73\xb0\x43\xb0\ \xdd\x59\x01\x47\x38\xda\x61\x23\x33\x04\x42\xe0\x35\x43\x6b\x8e\ \x77\x58\xa7\xbb\x6b\xd4\xb1\x95\xf1\xb3\xb2\xf3\xea\xaf\xd1\x73\ \x8d\xea\x4a\xdc\x21\x76\xea\xb1\x53\xe2\x06\xb1\xb5\x22\x2b\xeb\ \x5b\xba\x4e\x38\x6e\xca\xfa\x96\xae\xb7\x3c\x6a\x4a\xdc\x18\x76\ \x8e\x63\x66\x65\x27\xd9\x3b\x1c\x31\x25\xee\x34\x5b\x2b\x85\xd2\ \x2b\xff\x6f\x76\xb4\x94\xb8\xb3\xac\xc5\xb1\x52\xe2\x1e\xb3\x0d\ \x94\xbf\xb6\x2b\xec\x34\xe3\xe4\x36\x81\xb6\xa9\xd8\xfd\xbf\x02\ \xed\xd5\x8e\x82\xae\xd9\xa0\x86\xa3\x60\x54\x75\x5d\xe9\xf1\x5c\ \x05\x6a\x80\x0f\x4c\x10\x75\xc5\x34\xa1\xa1\xb6\x84\xbf\x49\x5f\ \x21\x47\xb4\x95\x48\x7b\xc5\xf9\x69\xb5\x48\x5b\x7b\x8d\xc2\x69\ \x22\x6d\xea\xa7\xfd\x96\x8e\x9b\x0a\x76\x3d\x8a\x6c\x5f\x67\x81\ \x74\x97\xcb\x1d\x28\x6a\x75\x11\xf6\xf1\xdc\x05\xca\x64\x28\x39\ \x95\x0c\xdc\x05\xf0\x1c\xb4\x32\x67\xe2\x2e\xe4\x10\x6d\x12\x60\ \x7b\x1d\xd7\x37\xeb\x32\xb8\x00\xbb\x55\xa7\x21\x0b\xb0\xc9\x86\ \x11\xb6\x2f\xd9\xb6\x8b\xe7\xd0\x56\x60\xbd\x72\xbc\xc4\xc4\xf4\ \xe1\xbc\xf6\xcb\x0f\xad\xed\xde\x67\x58\xef\x10\x5a\xdb\x55\x87\ \x59\x57\x4a\x2d\x49\x0b\x1f\x3d\xb4\xb6\xf4\x8d\x0f\x93\xd0\x83\ \x5d\xcf\x0c\x3e\xea\x20\x89\x59\xe8\x6d\x27\x21\x2f\x2b\xa6\xb6\ \x54\xad\x8d\xa9\xad\xf7\x8c\xdb\xb7\x3b\x40\x4a\xcb\x56\x8c\x4d\ \x27\x88\xa9\x2d\xdb\x24\x95\x67\x99\x2f\x95\x71\xc2\x91\x31\x6d\ \x4c\xd2\xfb\x6d\xbd\x7f\x5c\xf0\x8f\x21\xfe\xf1\x66\xf9\xf8\x74\ \x98\xc8\x51\x7e\xdc\x52\xc5\x3d\xe3\xb8\x65\x76\x23\x93\xd3\x70\ \x08\x96\x59\xaf\x35\x8a\x5a\xd7\xea\x35\x16\xc0\x6f\x2d\x9a\x46\ \xe5\x10\xbe\x3d\xe0\xb9\x0b\x94\x4d\x93\xc3\xe9\x2e\xd6\x7b\x2d\ \x94\xcb\x36\x46\x28\xa1\x2f\x7a\x7b\x26\xf4\xaf\xcd\x53\xfb\x80\ \xfc\x19\x9c\xda\xa7\x44\xed\x90\x95\x13\x6d\x88\x00\xaa\x27\x3f\ \xb5\x0f\x68\xb6\x74\x6a\x1f\x50\x6e\xff\xd4\x3e\x68\xc4\x09\x4e\ \xed\x53\xc2\x7a\x4c\xcf\x25\xd9\x0c\xdb\xe6\x66\x4c\x20\x7f\x06\ \xdb\xa8\xa0\x15\x2d\x6c\xa2\x02\xaa\x27\xdf\xca\xad\xc0\x67\x68\ \xc9\x66\x48\xd2\xfe\x36\x6e\x68\xc4\x09\x4e\xed\x03\x2a\x17\xbd\ \xfd\x12\xfa\xd7\xe6\xa9\x7d\x4a\x52\x72\x06\x36\x43\xd6\xbe\x67\ \xe7\x54\x36\x43\xd2\x93\x6f\xbb\x04\x9a\x2d\x1d\x20\x03\x94\xdb\ \x3f\x3e\x46\x49\x76\x82\x53\xfb\x80\xca\x45\x9f\xda\x07\xfd\x6b\ \xf3\xd4\x3e\x20\x7f\x06\xa7\xf6\x41\x2b\x5a\x38\xb5\x4f\x49\x7e\ \xf2\x63\xa7\x80\x66\x4b\x1b\xb5\x81\x72\xfb\x47\x3d\x28\xc9\x97\ \x04\x48\x87\xb5\x19\xc2\xb3\x98\x25\xb7\x19\x9f\xd3\x64\xd2\x99\ \x3e\x44\x83\xe4\xb9\x28\x93\x7f\xc3\x29\xad\x64\x83\xe6\x5f\x73\ \x5a\xbd\xf7\x72\xdb\x0d\x48\xc8\x2a\x79\xe8\xe6\x8d\xad\xcc\xc3\ \xe6\xda\x21\xc9\x46\xc6\xa0\xae\x1d\x2c\xcc\xb2\xb2\x1e\xf6\x7d\ \x81\x5a\x9b\xac\x83\x86\xff\xe2\xd2\x5d\x8b\xcc\x2b\x1e\x41\x4b\ \x7c\x63\x3b\x56\x17\x35\xda\x92\x2d\xcd\xc9\x12\x68\x95\xdb\x5f\ \xa3\xd1\x53\x3c\xc5\xd5\x41\xa4\xf8\x5d\xf6\x19\xbf\xce\x13\x3b\ \x00\x1f\xeb\x8d\xfd\x97\xcb\xf4\x36\xdb\x99\xdd\x85\x26\x8a\x06\ \x58\xbe\xe6\x0d\x5e\x10\x20\xd9\x04\x68\xf0\xea\xbd\x3d\xef\x68\ \x96\x62\xfe\x71\x01\xbd\x5f\xe2\xf4\x7e\x41\xe8\xdd\x4d\x68\x8e\ \x2f\x82\xba\xfb\x52\x57\xbd\x9a\x35\x71\x2f\xfe\x3f\xa8\xe0\xa2\ \x29\x29\x1e\x41\xbd\xa6\x66\x2d\xb0\xa3\xde\xe6\x6d\x51\x65\xe3\ \xe0\xf2\x95\xc6\xbd\x97\xbf\xb9\x4e\x86\x96\xf4\xb8\x29\xba\x48\ \xab\x09\xca\xa2\xd4\x64\x72\x11\x94\x42\xe2\xff\x48\x3b\xcd\x49\ \xcc\x86\x14\x2b\xb6\xeb\x38\xa5\x9a\xc2\xb5\xa6\x5f\x27\x50\x49\ \xe5\x13\xb0\xf3\x52\x49\x65\x36\x54\x49\xbe\x08\x10\xaa\xa4\xe7\ \xf6\x3e\x2a\xa9\xc9\x2e\x0a\xa7\xd9\xc1\x15\x4e\x8b\x85\x2a\x9b\ \x4a\xb0\x54\xe5\x1a\x63\xe1\x71\x96\x6e\xd4\x66\x29\xea\x24\x38\ \x3d\xc9\x8e\x08\xfe\x26\x97\x6d\xec\x39\x27\x5f\x83\xbd\xf1\xb5\ \xc9\x54\x9c\x60\x8d\x3b\x09\x85\xa5\x92\x12\x6b\x8a\xf9\x78\x7e\ \xdc\xf9\xf8\x2d\xd6\x2a\xf3\xf7\xfe\xc5\x8a\x82\x90\x0b\xdc\x15\ \xbd\x15\x00\xbe\x09\xcb\xb7\x0e\xc0\xb2\x70\x86\x1b\xeb\x69\xd4\ \x9b\x0d\x67\xa0\x3b\x9b\xe5\x36\x8e\xee\x3b\x41\x4b\xe4\x92\xea\ \xce\xc5\x77\x82\x26\xea\x06\x58\x6d\xfa\x4e\xd0\x1c\xeb\xa9\x68\ \xef\x70\x86\x5b\x52\xcd\xb6\x1c\xc2\xbb\x82\x2a\xf9\x42\x95\x97\ \x18\xce\x70\x5c\x11\xba\x53\x38\xc3\x71\x59\xe7\x79\x85\x33\xbc\ \xbe\x86\xf4\x2c\x55\xb2\xbe\xd8\xb4\x75\x95\xc4\x95\xa3\x3b\x68\ \x07\x95\x07\x57\x38\xaa\x17\xaa\xdc\x35\x9c\xd9\xc6\x1d\x24\xe6\ \x02\x9d\x81\xc3\x07\x16\xdc\x0a\x5b\x3d\xa6\x71\x31\xb4\xb0\x52\ \x56\xf6\x1a\x9c\xf2\xd8\xa9\x15\xa1\x4a\xe5\x54\x21\x16\x52\x26\ \x14\x84\x24\x4c\x87\x9c\x58\x0c\x49\xb6\x5e\xcf\x9b\xa3\xb0\xdd\ \xd2\xd6\xfd\x57\xd0\x03\xb6\x34\xa8\xcd\xce\x6c\xb6\xa6\x77\xb0\ \xe3\x7a\x72\xa0\xc7\x2b\x67\x48\xec\xbf\x41\x94\x53\x76\x81\x1b\ \x44\x4f\x79\x72\x97\x5f\xa6\x43\x29\x2d\x53\x92\xc6\x81\x72\x69\ \x0f\x6d\xb4\x60\x2c\x0e\xc4\xfe\xeb\x48\x41\x45\x78\x65\xe7\xd6\ \x5a\xd3\x10\x78\xf8\xb0\xe5\xb2\xdc\x65\xfa\x06\x55\x6f\xa3\x71\ \x4c\xc5\x72\xc7\x13\xe2\x32\x45\xdb\xf2\x8c\x38\x42\xac\xdd\x88\ \xe2\x72\x55\xab\x50\x3c\xd9\xf6\x8d\xb5\x16\x5d\x90\x8a\x5b\x7d\ \xb4\x64\x11\xa5\x3a\xa4\x5a\x73\x0b\x02\xac\x4d\xc8\x29\x61\xba\ \x9e\x2c\x12\xb8\x07\x48\x54\xb2\xc0\xa8\x3a\x94\x32\x1a\xd2\xea\ \xfc\x08\x6a\xd8\x62\x51\x54\x46\xac\xd7\x15\x3d\xee\xf8\xc8\x56\ \x63\xc9\xcf\x01\x4b\x65\xfd\x58\x02\x6e\x4d\x2c\x17\x8b\x3a\x2c\ \x39\x0d\x09\x86\x95\x3b\x1d\xc8\x67\xd5\x05\x0e\x03\x4b\x27\x92\ \xa9\x2f\xd1\x36\xcf\xbc\x44\xe9\x9f\xf1\xb8\x13\x0f\xee\xe3\x25\ \xab\x4b\x20\xde\x74\x89\x99\x69\x27\x1a\x0f\x3a\x3f\x8f\xe0\x93\ \xbf\x60\xb9\x0c\x25\xaf\x74\xf6\x10\x67\x15\x67\x2b\x51\xa2\xf1\ \x7c\x31\x0a\xfa\xe6\xf3\x2a\x8e\x33\xd9\x4c\xc9\xf2\xef\xde\xa8\ \xce\x34\x35\x97\x62\xc8\x66\xb8\xb7\x76\x2d\x00\x25\x4b\x96\x9e\ \xd4\x76\x1b\x17\xeb\x00\xe0\xff\x13\x6f\xde\x68\x31\xc0\xae\xb7\ \xda\xec\xd0\xb2\x0d\x57\x50\x63\x23\xe6\x44\x36\x68\xf3\xb2\x7c\ \xc9\xfa\x40\xf9\x0c\xf3\x0e\x8a\x52\xb2\x5b\xde\x01\xde\x5c\xbe\ \x44\x70\xb5\x8c\xad\xee\xea\xd6\x7c\xa6\x4b\x16\x59\x6f\x2c\x81\ \xcb\xc1\xde\x5b\x06\xe9\x82\x76\x6c\xc0\xfc\x1d\x84\x31\x5f\xcb\ \xb3\xf5\x22\x1b\xca\x3d\xc6\xf8\xcd\x66\xa5\xa1\x3b\xcc\x6b\x5d\ \x4e\x3f\xa3\x4f\xb9\xcf\x02\x9f\x53\x0a\x0c\x9a\xa8\x1a\x60\xb5\ \x3a\xa3\x5f\x9d\x8a\x3e\xe4\x22\x9b\xea\x5c\xeb\xbc\xa3\x7b\xce\ \xf9\x53\xb1\xb8\x8c\xe0\x12\xb3\xd2\xd0\x51\xb1\xeb\xe8\x20\x9a\ \xc2\xd5\x76\x56\x1a\x9a\xe4\x13\xb0\xf3\x52\xc9\x85\x45\x82\xed\ \xaa\xa4\x77\xa5\xe0\x01\x54\x52\x2e\xae\x99\xd9\x57\x25\xa5\x5a\ \xa8\x72\xe3\xbc\xf5\x1b\x53\x4a\x69\x76\x55\x4a\xd5\x14\xaf\xf6\ \x95\x52\x9d\xfd\x62\x54\xba\xb0\x5e\xb0\x5d\xa5\x54\x6a\x17\x95\ \x53\x07\x5f\x6a\x4a\xf5\xe2\xc0\x7a\x82\xa9\x22\x4a\xb8\x79\xdf\ \x2b\x67\x38\x91\xf6\x9d\x03\x60\x3c\x6d\x78\x47\x00\x50\xfa\xde\ \xbf\xa9\x8a\x42\x80\xf5\xbe\x17\x10\x52\x2a\xe4\xfb\xb6\x83\x94\ \x56\x4f\x1e\xba\x18\x04\x8e\x33\xc7\xb4\x62\x56\x84\x57\x8d\xc9\ \xfe\xb3\x22\x52\x52\xcd\xb8\xe5\xf9\xac\x88\xbb\x14\x42\xc3\x47\ \x37\x3d\x42\x14\xbb\x12\x9a\x86\x02\x0a\xb1\xfa\xb4\xc8\xfe\x2b\ \x15\x76\x1a\x4d\x8c\xf9\x4b\x8a\x36\x90\x22\x41\x88\x5c\x21\x45\ \x82\x54\x96\x54\x21\x37\xb9\x8b\x17\x9a\x87\x38\x51\xc2\x88\xe3\ \x69\x8d\xa5\x9e\xb2\x8e\xaf\x4c\x84\x82\xe9\x4d\xe7\x3f\x77\xe2\ \x3e\x93\x17\x38\x19\xb6\xdd\xa2\x90\x0b\xfc\xc6\xbf\x2d\x01\x08\ \xde\xb9\x43\x8d\x10\x5c\xe0\x02\xbc\x6d\x26\xc5\x59\xe5\x3b\xf6\ \x2e\x03\x80\x9b\xde\x20\xbe\x9b\xba\x4f\xc5\x0b\xe3\xe8\x31\x1e\ \x7c\x1d\xc6\xcf\x1f\x0a\x10\xbe\x44\xc5\xc0\x3e\x89\xee\x63\x37\ \x33\x03\xc6\x3f\x3b\x8e\x32\x7f\x90\x1d\xa9\x30\x7f\xa4\xdc\x4f\ \xed\x51\xbe\xe2\x06\xa7\x81\xe6\x3d\x29\x5b\x05\xb5\x16\xcf\x89\ \xff\x79\x36\xcf\x04\x63\x7b\xf3\xe1\xb7\x24\x01\xe7\x82\x8a\xd0\ \x32\x6b\x8a\x63\x16\xca\x71\x0c\x37\x7e\xa9\x50\x52\x49\x8a\x1d\ \x09\xe5\x43\x97\x7c\xd1\xca\x6a\xc2\x6d\xf3\xe1\x20\xe9\x3f\x3d\ \xc2\x50\x12\x3c\x65\x63\xc9\xe4\x65\xe1\xf5\xa7\x34\xc5\x02\xa3\ \xe8\x35\x86\x6e\xbb\x3f\x73\x1e\x4c\x1f\x92\xe7\xfb\xd4\xa5\x44\ \xa2\x51\x81\x5f\xf1\xea\xf3\x70\x0c\xdd\x09\xe6\xd3\x65\xcc\x2c\ \x74\x3a\x2f\x31\x9f\x3d\xd3\x72\xa1\xe7\x79\x89\x97\x72\x8d\x54\ \xf3\x11\x6e\x74\x5e\x40\x24\x7f\xf6\x18\xbd\x0c\x1f\x87\xdf\xe2\ \x01\x2e\x78\xca\xe5\xe1\x31\x9e\x45\x83\x68\x16\x95\xbc\x9f\xdf\ \xe1\xd2\xce\x4f\x24\xbe\x49\x07\x77\xd7\xbf\x7e\xfe\x7b\x91\xb8\ \xe9\xf7\xaf\xff\x9d\xa4\x7f\xce\x65\xaf\xd3\xc1\x02\xd1\x97\xe4\ \x09\x9a\x5d\xcd\x44\x0d\xfa\xd7\xe8\x09\x46\xb3\x4f\xc3\x47\xe0\ \x68\x6f\xfa\xf5\xfe\x7f\x5f\x1e\x47\x20\x85\xc5\x83\x5a\x61\x94\ \xdd\xb2\xd2\xac\xda\x34\x9e\xba\xfc\xd1\x6d\xf7\x61\x36\x9b\x5c\ \xf7\x7a\x93\xa7\x74\x14\x26\xe9\x3d\x54\x02\xff\x3d\x0e\xf1\xa5\ \xde\x6f\xb3\xe1\x68\xf4\x0f\x24\x52\x4f\x5c\x61\xa5\xc3\xd9\x28\ \xae\x66\x9d\xf2\xd6\xcf\xb3\x4e\x95\xce\xdd\xf4\xe6\xbd\x77\x57\ \xf7\x0d\x1c\xf3\x59\xd0\x7f\x22\xd7\x0b\xd5\x2b\x9e\xde\xa7\xc9\ \xd3\x24\x3b\x62\xc1\xc9\x45\xb7\xc4\xb4\x26\x27\x33\xdf\x82\x41\ \xdc\x1c\x99\xbb\x41\xe0\x01\xcf\x61\x07\x3b\x54\x38\x3f\xb9\x9f\ \xa4\xb8\xa9\xf8\x49\xa8\x3c\xce\x85\xa6\x76\x71\xfa\x95\x83\x47\ \x2d\x0c\xab\x9c\xf5\x95\x0b\x5f\xfe\xa0\xb9\x0f\x14\xa8\x71\x5b\ \x99\x6e\xc8\x57\xd4\xdd\x01\xb2\xd7\x80\xf9\xf7\xcd\x10\x02\x62\ \x84\x8f\x3f\xe0\xd3\xca\xe2\xba\xe9\x2c\x4d\xfe\x8c\x7d\xc5\xd1\ \x19\xfc\x98\x3f\xcf\xb4\xe0\x1a\x23\x01\x46\xaa\x3f\x72\x5e\x00\ \xd8\x1a\xa7\x23\x10\xd7\xd9\xb5\x98\xdf\x1b\x44\x60\x12\xd2\x34\ \x7a\xbd\x1e\x27\xe3\x32\xf0\x48\xdd\x9e\xff\x0c\x84\xca\x96\xce\ \xd7\xf9\x5d\xc6\xca\x19\xab\x9b\xfb\x6a\x8f\xef\x21\x60\xa6\x26\ \x20\x41\x19\x34\xcf\x3c\xd1\x8b\xc6\x23\x75\xc1\xef\xcc\xa3\x17\ \x4d\x88\x21\x4a\xd1\x2b\xc6\x6c\x28\x8d\x85\xe0\x85\x83\x31\x92\ \x96\x17\x9c\x6b\xf0\xae\x04\x3e\x04\xb5\xe7\xa2\x76\x32\x58\xa1\ \xee\x50\x17\x98\xa5\x4a\x0a\x23\xeb\x1a\x0d\x15\x40\xa7\x6b\x1b\ \x69\x52\x67\x55\xa9\x62\xd0\xae\xea\x6e\x18\x9c\x64\x17\x1c\x02\ \x24\xc9\x6a\x67\x53\xe2\xa6\x57\x25\x42\x5e\x9f\xdf\xf5\xf5\xd5\ \x1a\x3c\x74\x9b\x99\xab\x80\x40\xfd\x9a\x29\x4b\x30\x4c\xa3\x42\ \x42\x80\x06\x3d\xc5\x12\x16\x84\x54\x30\xc4\xe2\x63\xa5\xb6\x42\ \x84\x18\x53\x81\x0e\x64\x50\x4d\x91\x57\x45\x69\x7e\xaa\x71\x4d\ \x72\xa0\x5e\x2d\x85\x25\x6c\x2e\x41\x8e\xc5\x15\xad\x5d\x82\xa7\ \xa0\xda\x4a\x23\x3d\x78\xda\x50\x59\x46\x55\xed\x6b\xc1\x32\x3c\ \x35\x2e\x93\xab\x1f\x03\xe8\xf0\x14\x46\x92\xfa\xbe\x2c\xc4\x93\ \x12\x65\x20\xe2\xa8\x9d\x77\xf9\x8a\xa7\xba\x84\x14\x54\x8b\xdb\ \x35\x80\x72\x2e\x05\x31\xd2\x01\x6a\x05\x23\x9a\x69\xdc\x87\x6b\ \x25\x35\x92\x13\x03\x1f\x39\xc1\xc3\x2d\xa4\x59\x01\xa8\x09\x2c\ \x42\x7a\x7c\x40\x19\xb2\xd7\xb2\x65\x80\x42\xdc\x25\x6a\x3d\xce\ \x00\x15\x56\x80\x78\x79\x00\xd5\x12\xe2\x37\x5b\x07\x94\x53\xa8\ \x48\xd2\xda\x16\x3d\x67\xdc\x0c\x68\x87\xaa\xcd\xfd\x78\x05\x14\ \x62\x73\x6e\x18\x4a\x22\x17\x20\xeb\x46\x32\x84\x16\x00\xc4\xdc\ \x0f\xdc\x85\xa7\x1c\x17\xf8\x2d\x87\x93\x13\x50\x79\x11\x78\xce\ \x90\x3f\xbc\x7c\x12\x45\x34\xa9\x9d\xc5\x54\xc2\x09\xb2\x60\x69\ \xed\x4c\xc4\x0c\x4e\x90\x0b\x2e\x29\x5f\x80\x93\x03\x79\x22\xe5\ \xa2\x7c\xf2\x10\x8c\x90\x6d\xe0\xc9\x8d\x53\xd5\x75\x78\x72\xab\ \xb5\xe5\x3a\x93\x4f\xaa\x85\x06\x2d\x40\xf9\x14\x9a\x19\x41\x11\ \x50\x0e\x36\xc6\x62\xb2\x66\x29\x9e\x2c\xe0\x01\x0b\xcc\x29\xf0\ \x04\xc6\x2a\xaf\x74\xba\xf5\xb5\x82\xd5\xd5\x3a\x83\x13\xb0\x14\ \x4c\x2e\xc0\x49\xac\xd5\x4a\x37\xcd\x27\x88\x16\x18\x7c\x21\x69\ \x1d\xce\x40\x82\x78\x1a\xc0\xc1\xac\xc4\x33\x40\x75\x66\x92\x0b\ \x3c\x45\x1a\xb5\x1c\x8f\x53\xe0\xce\x6c\x52\xb0\x8b\x46\x39\x9c\ \x05\xb1\xd2\x32\xbe\x02\x51\x90\x4e\x90\x51\xcf\x91\xe7\x7b\x20\ \x3a\x89\x66\x0f\x75\x62\x78\x47\x40\x4b\x02\xea\x7e\xd9\x02\x51\ \x74\x07\x3b\x01\x58\xac\x50\x81\x31\xbd\x72\xc9\x17\x22\x55\xa7\ \xdf\x09\xc0\x89\xd6\xa0\xf6\xd0\x33\x22\x4c\x27\x50\xa1\x21\x02\ \xb4\x12\x38\x24\x05\xc5\x6b\x2d\x95\x54\x57\x2a\xc4\xae\x76\xb0\ \x94\xd6\xf0\xd4\x10\xd9\x81\x32\x42\x19\x0e\xcf\x0c\xe0\xdf\x81\ \x22\x4c\x01\x46\x70\x49\xad\xe8\xcc\x2b\x0e\xb2\x9a\x15\x2a\x34\ \x05\x34\xe1\x2d\x10\x67\xb8\xc6\x83\xcd\xe9\x15\x50\xb0\x60\x4f\ \x3b\xa3\x0e\x16\xe4\xdc\xbd\xc0\xb4\x35\xd8\x38\x18\xb0\xac\xc6\ \x41\x8c\x87\x0a\x2c\x3a\xb6\x96\x49\x85\x65\x14\x8a\x03\xc3\xf6\ \x65\x44\xf1\x06\x11\xaa\xf3\xad\xf3\x58\x54\x44\x91\x12\x54\x83\ \x93\xb4\x4a\x72\xd7\x12\x6e\x3a\xd2\x7d\x95\x81\xbc\x62\x60\xd3\ \xf1\x4a\xa1\x23\x70\x05\x83\xad\x01\x44\x46\x1d\x74\x0d\x30\xa9\ \x09\x2f\x62\x79\x8b\x50\xc0\xb0\x01\xf0\x85\x82\x6b\xab\xa1\xa4\ \xb2\x50\x32\xc0\xa3\xc5\x05\xc3\x6b\x0d\xe3\x34\xb6\x8d\xa0\xfa\ \x5e\xb9\xb7\xf0\xb1\xe2\x94\x88\x2b\x7c\x4f\x32\xe9\x6e\x38\x4a\ \xf8\x22\x08\x54\xd6\x4c\xeb\x00\x81\x6a\x3a\x59\xf5\xee\xb1\x86\ \xa1\xa4\x33\xaf\x1e\xaf\xc1\xf4\x74\xbe\x1d\x51\x88\x8a\x18\x32\ \x99\xc4\x63\x74\x67\x9f\xe2\xae\xe7\x69\x3c\xc6\x90\x83\x41\x48\ \xc6\x64\x4d\x41\x8b\x12\xd3\x59\x94\x82\x12\x2b\xe0\x20\x91\xba\ \x76\x7e\xca\xa2\x92\x81\x25\xe4\x0c\xc4\x29\x4b\x27\xa3\x5d\xe4\ \x58\x31\x78\xd0\x16\x86\x16\x05\x5e\x0b\x48\x2a\x91\x28\x91\xf4\ \xe3\x82\x34\x2b\x16\x32\xe0\xb2\x63\x1d\xc8\x1f\x38\x3b\x19\xc7\ \xc0\xf6\x19\xa8\x8c\x81\xb0\x81\x61\xee\x04\x68\x20\x18\xa5\xdc\ \xf1\x9b\x2b\xf0\x7f\x1c\x2b\xb5\xe1\x82\xe2\x3d\x61\x0d\x45\x7e\ \x01\x7d\xf4\x31\x71\x24\x27\x54\x51\x69\xb1\x98\x64\x82\x4a\x8d\ \x3b\x7f\x08\x30\xd7\x98\xec\xa6\xa0\x8a\x2b\x64\x2c\xd8\x7d\xf0\ \x1d\xa8\x63\xa5\xa3\x1b\x94\x84\x0b\xba\x41\x49\xb8\xa0\x1b\xe4\ \x84\x05\x14\xe3\x42\x81\xca\x39\xe9\xa4\x52\x59\x8a\xa5\x94\x34\ \x2e\xad\x0e\x72\x02\x23\x85\x80\x5b\x12\x06\x4b\xfc\x4a\x00\xd0\ \x08\x69\x48\xed\xf4\xbf\x02\xfd\xcc\x57\x06\x3b\xaf\x79\x6d\x58\ \x2e\x0b\x64\xc7\x6a\x51\x42\x4d\xed\xc8\xf5\xa2\x00\x86\xd5\x00\ \x27\xf8\x43\xba\xb6\xd1\xb7\x2c\x80\xb6\x15\x5c\x50\x2d\xb8\xa9\ \x1d\x3e\x5c\xda\x21\x63\xc0\xc7\xd1\x30\x30\x6b\xb0\x43\x07\x18\ \x9c\x3d\xad\xc8\x72\x23\x51\xda\xdf\xc2\x2e\x8a\x00\x37\x3a\xf1\ \x80\xfb\x2c\xa3\x05\xcb\x88\xca\x0a\x96\xd1\x42\xdf\x68\x69\x19\ \xcd\xee\x96\x51\x64\x96\x91\xd5\x2d\x23\x5f\x6d\x19\x59\xc3\x32\ \xd2\x9d\x2c\x23\xdf\xc3\x32\x2a\x9f\x65\x94\xa5\x65\x34\x87\xb1\ \x8c\x3c\xb7\x8c\xea\x9c\x2c\xe3\x4d\x2f\x3f\xad\xb1\x26\x4d\x65\ \x8a\x2d\x19\xc4\x28\x7b\xd3\xdb\x6e\x7f\x3a\x9d\xf6\xdd\x4f\x2d\ \xf8\xc6\xd7\x64\x35\x22\x77\x02\x66\x41\xa3\x41\xdb\x8d\x06\x01\ \x13\x26\x64\x68\x5d\x00\x44\xc4\x5d\x83\x32\xba\x0e\x43\x00\xed\ \x06\x0b\x06\x1e\x38\x8a\x88\x89\x83\xf2\xda\xd9\x24\x0e\xb2\x08\ \xf6\x02\x7c\x23\x6e\x88\x63\x1a\x33\xba\xe3\x7c\x29\xa8\xdb\xdd\ \x90\x20\x13\x1d\x8c\x8c\x18\x30\xd8\x95\x50\xae\x08\x93\x60\x48\ \xdd\x0d\xb0\x43\xc2\xdd\x80\xb8\xc5\x5d\x83\x84\xa1\x1c\x12\xa5\ \x5d\x0c\x83\x0c\xd2\x20\x81\x48\x1d\x68\x41\xb3\xcb\x6b\x16\x9a\ \xb9\x24\xc0\x47\xe0\x29\xb2\x16\xdc\x35\x8a\x31\x75\xf1\x19\x5a\ \x42\xb0\x6f\xd0\x74\xaa\x29\x1a\x56\x19\x07\xe0\x8b\x56\xf8\xb4\ \xc0\x25\x42\x96\x24\x20\xca\xaf\xae\xa9\xe5\x1b\xc0\xca\x08\x43\ \xf5\xaa\x2c\x43\xb3\xaa\x66\xda\xa1\x60\x79\x95\xd3\x15\x16\xea\ \x3a\x0b\x71\x16\x0b\xfa\xa3\x72\x16\x5a\x40\x31\xe7\xa0\x21\x8c\ \x65\x22\xab\x1d\xc3\x80\x8f\x22\xe3\xa8\xa4\xc5\x35\x32\x10\x83\ \x1d\x60\x8e\x80\x51\x46\xbb\xb8\x5c\x02\xd8\x1c\x45\xde\x5a\xc7\ \x3d\x01\x46\x03\x0a\x58\x0b\xfe\x42\xa6\xec\xc8\x2a\x03\x2a\x2a\ \xdc\xb5\x30\x06\x45\xc3\x30\x18\x5a\xcb\x1b\x48\x09\x02\x28\xe4\ \x80\xd3\x1b\xeb\x86\x3f\x85\x2e\xc7\xfc\x1a\xc7\x2c\x60\x24\x32\ \x8e\x86\x80\x9c\xd3\x49\x05\x43\x11\x0e\x77\xc5\xe7\x8c\x6d\x14\ \xc1\x05\xce\xd2\x95\x4c\xc3\x4d\xd7\xdb\x32\x0d\x82\x45\x50\x01\ \x43\xf7\xe1\xda\x86\x2a\xb9\x8e\xb9\xb6\xce\x5c\x0a\x63\x1e\x7e\ \x51\xb0\x45\xe6\xea\x50\x2a\x21\x33\xee\x02\x33\xa4\x56\x4e\x41\ \x14\xc6\xfe\x20\xf6\xf0\x10\xaf\x15\x8c\x80\xd5\x6b\x0a\x10\x66\ \xec\xd5\xf0\x86\x8b\x1a\x78\xae\x6a\x0c\xad\x94\xd3\x75\x08\xe4\ \x50\x3b\xc1\xc6\x65\x71\x85\x90\x60\x2e\xa1\x84\x90\x30\x20\x64\ \x91\x9b\x1b\x3d\x98\x02\x75\x55\xc5\x0d\xac\x5e\x58\x96\x73\x38\ \x3b\xf6\x2b\xd4\xe0\x5c\x94\xd7\x28\x26\x2c\x73\x5f\x81\x9b\xe0\ \x23\xb8\x11\x01\xc6\x11\x99\x73\x18\x82\x19\xc5\xc5\x5c\x33\xa1\ \xd5\xfc\x48\x9a\x69\x20\xde\x04\xa9\x6b\x9f\xc9\x95\xb9\xe5\x4c\ \x83\x19\x36\x8e\x80\xe7\x06\x4c\x56\x38\x54\xe5\x2a\xcc\xd0\xfc\ \x59\x87\x32\x41\x46\x71\x34\xca\xee\x9a\x81\xa5\xae\x5e\x53\xb0\ \x00\x8e\xc9\x1a\x0c\x01\x75\x3c\x55\xc0\x4d\xe0\x98\x52\x52\xba\ \x5d\xa1\xa8\x69\x12\x4a\x18\x25\x4c\xa6\xd5\x98\x89\x73\x25\x80\ \xed\xd2\x95\x50\xc8\x74\xf0\x26\x95\xb1\xf3\x6b\xa7\xc4\x6c\xae\ \xc4\x02\xfd\x0e\x50\x5a\x45\x78\x79\x0d\x32\x0a\x3e\xa3\x63\xb1\ \x40\x0b\xcf\x9d\xe2\x02\x53\x31\x7a\x2b\x3e\x9b\x8c\xc5\xae\xcd\ \x66\x39\x63\x1d\xeb\xb6\xd4\x5e\x06\x6e\xa7\x56\x47\x67\x6c\x31\ \xc5\x05\x43\xf1\x0d\x4e\x35\x7c\xfa\xf0\x5f\xd7\x20\xa3\x93\ \x00\x00\x06\xca\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\ \xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\ \x0d\xd7\x01\x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ \xdd\x02\x0b\x13\x29\x17\x16\x40\x76\x35\x00\x00\x06\x57\x49\x44\ \x41\x54\x58\xc3\xb5\x96\x69\x68\x5c\xd7\x19\x86\x9f\x7b\xee\x99\ \x3b\x8b\x66\xd1\x48\x23\xa9\xae\x6c\xc9\xb1\x15\x6b\xb1\x6c\x27\ \x38\x76\x9c\x90\x62\xc5\x0d\x4d\x45\x17\xb9\x50\x1a\x02\x21\x05\ \x3b\xd0\x1f\x89\xe3\x26\xd0\x36\x2e\x81\xba\x14\x02\xa5\xb8\x85\ \x42\x0b\x82\x86\xa6\x1b\x6e\x5d\x53\x48\x03\x5d\x88\x9d\x56\x36\ \x6a\xeb\xe2\x2d\xb1\xdd\x58\xb2\x76\xc5\x9b\x16\x4b\x33\xa3\x89\ \x66\xee\xdc\x7b\x4e\x7f\xcc\x68\x34\xa3\x35\x71\xeb\x03\x1f\xdc\ \xfb\x9c\xf7\xfb\x38\xf3\x9d\x77\xce\x3d\x46\x67\x67\x67\xe0\x66\ \xfa\xd6\xb1\xa4\x27\xd9\xa2\xbc\x3a\x20\x31\x85\x2d\x5c\x97\xa2\ \x61\x6a\x61\x98\xda\xf8\xbf\x71\x95\x51\x33\x81\xb4\xff\x7d\x33\ \x61\x3e\x25\x7b\xa6\xaf\xbd\xf1\xaf\xa6\x7f\x3f\x39\x18\x18\x91\ \x41\x23\x48\xa5\x51\xc1\xb0\x1a\x29\xce\xe3\x1e\xf0\xaa\x0d\xf6\ \xfa\x75\xdb\xcf\x6d\xfd\xb9\x1c\x71\x86\xb7\x0c\x78\x47\x24\x2e\ \x68\x03\x10\xa0\x4b\xd6\x7d\x6f\x78\xbf\x39\x24\x6b\xbc\xd5\x4d\ \xd2\x76\x9c\xe0\x66\xd1\x0c\x80\xdf\xf0\x13\x11\x61\xca\x74\x59\ \x49\xe2\xbd\xe2\xca\x75\xc3\x72\xc2\x9e\xc8\xf4\xd9\x23\x85\x16\ \xc5\xcc\x0a\x86\x9c\xc5\xad\xbb\x17\x7c\xa3\x5d\x97\x11\x5a\xe7\ \x5a\xa2\x5d\x40\xcd\x3f\x17\xc7\xdd\xf2\x9a\x71\x97\x87\xae\x64\ \x4a\xf8\x9e\xae\x09\x44\x36\xaf\x55\x20\xd1\xa0\x95\xce\xed\x11\ \x1a\x0d\xa8\xb4\x17\xfb\xe2\x1e\xec\x9e\x9d\xa8\x44\x05\xe9\xd8\ \x38\xde\xc7\xba\xd1\xb5\xc3\xa5\x7b\x9a\xd7\xcf\xe5\x2f\xe4\x1d\ \xa7\x52\x1c\x3a\x3a\xcd\xb3\xaf\x54\xd1\xb5\xcd\xc7\x0b\xbf\x1b\ \xe3\xc0\xb1\x09\xce\x7c\xbf\x86\x4b\x1b\xac\xdc\x02\xb4\xd2\xa0\ \xe6\x93\x93\xd7\x36\x33\xfd\xeb\x1f\x61\x6d\x39\x85\x6f\xd7\x9b\ \x88\xf0\x24\xd6\x58\x23\x43\xbf\x7c\x1e\x1a\xb7\xe0\xdd\xf1\x27\ \xe4\x9a\x41\x10\x4e\x2e\xc1\xa0\x24\xbf\x30\x0c\xe8\xfc\x5c\x88\ \xea\x29\x97\xa3\xdf\x1b\xa7\xbb\xd5\xcb\xce\x1e\x9b\x03\xdf\x6d\ \xe5\xd2\xfa\x38\xa8\x5c\xaa\x04\xa3\xe0\xd6\xcc\xe8\x26\x6e\x1d\ \xdb\x47\x68\xff\x4b\x98\x35\xf3\xbf\xd6\x1f\xbb\xc3\xda\xe6\x01\ \xae\xfe\x63\x2b\xa9\x37\x5f\x40\xdd\xa9\x05\x65\x32\x8d\x20\x5e\ \x3f\x84\xf1\xcc\xc1\xd2\x0e\xe4\x1b\xa2\x14\xbc\xf6\x54\x84\xc7\ \x2f\xa6\x69\x7b\x37\x4d\xe7\xde\x18\x67\x5b\xca\xd1\xd9\x78\x5e\ \x00\x32\x24\x82\x9e\x56\xab\x05\xad\x04\x17\x7e\xfb\x2a\xbb\xf7\ \xff\x9e\xd9\x9a\x32\xa0\xa5\x50\x30\x60\xf8\x89\x98\x61\x82\xbb\ \x7b\x60\x77\xcf\x22\x7e\xd3\x69\x29\x59\xc0\x1c\xaf\xc8\xfa\x38\ \x7c\xe4\x22\xeb\x26\xe1\x87\x75\xcf\xf0\xf5\x3f\xfe\x86\x40\x2c\ \xcd\xeb\x9f\xcf\xe9\x7d\xc2\xf4\xca\xa4\x93\xcc\xf6\xa4\x86\xc9\ \xf6\x3e\x82\xae\xbe\xca\x58\x45\x37\x83\xa9\xd2\xbd\x0e\x89\x20\ \x31\x59\xc9\xa0\xfd\xf1\xf8\xbe\x37\xde\x65\x53\x4f\x8a\xf6\x4f\ \xef\xe3\x82\xbf\x99\xdb\xa1\x93\xbc\xf6\xfa\x59\xde\xaa\x88\x71\ \x62\x9b\x8f\x4d\x76\x9d\x9d\x37\x21\x38\x43\x5b\x08\x34\x9c\x43\ \xe7\xdf\x4b\x4d\xc5\x5d\xf1\x5f\x3d\x5c\xc5\xcf\xb2\x07\xb9\x3c\ \xb5\x8b\xb2\x2f\xbe\xc4\x51\x6f\x39\xe9\x68\x94\xee\xfb\x13\x85\ \x1c\xa9\x94\xd6\xda\xd5\xe8\x74\x00\xc3\x1a\x41\xbb\x1a\xed\x2e\ \xe1\xea\x8f\xc1\xdd\x54\x98\xdb\xe7\x3b\xb8\x75\xa6\x0d\x6b\xe7\ \x71\xca\x1e\x79\x1e\x84\x8b\x56\x41\x4e\x3d\x50\x41\x2a\x93\x00\ \x57\xa3\x5d\x90\x46\xde\xc5\x46\xf8\x36\xce\x64\x2d\xa8\xff\x2c\ \x76\xf5\x9c\xd3\x57\xe1\x2a\x5e\x43\xa6\xeb\x39\x52\x83\x3b\xa8\ \x7a\xe8\x34\xc1\xfd\xcf\x61\x04\x27\x0b\x86\x5b\xaa\x8e\x98\x6b\ \xa1\x6c\x3e\x41\xea\x6c\x3b\xce\x6c\x19\x5a\xb1\x38\x34\x2b\x72\ \x95\x8c\x92\xfa\xc5\x4f\x31\xeb\xcf\x51\xf3\xe2\x57\xa9\x7e\xfc\ \x38\x04\x26\x57\xac\x03\x20\x83\x22\xe4\xd9\xea\x6f\x01\x3f\x4c\ \xed\xf9\x1b\x43\x3f\x39\x42\x70\xc3\x65\x2a\x5b\xce\x13\x6d\x7c\ \x0f\x0c\x8d\x5f\xf8\x29\x97\x61\x42\xc6\x82\xb3\xbd\x88\x4f\x7f\ \xb0\x99\xf1\xfa\x11\xee\xdf\x39\x82\x5f\x34\xac\xaa\xcf\xbd\x4b\ \x4b\x26\x9c\x44\xf6\x6a\x22\xe7\xe2\x50\xe3\x30\xeb\x9b\xfe\x4a\ \xdf\x95\x5a\x26\xfe\xd9\x8e\x7e\xfb\x09\x7c\x4f\xbf\x48\xd8\x0f\ \x55\x56\x25\x03\xb3\x0b\xdc\x6e\x06\xe7\x79\xe5\x35\x3e\xbc\xde\ \x41\xfc\x7c\x94\x68\xe3\xc5\xd5\xf5\x40\x53\xb6\xde\x16\xb9\x83\ \x28\x6f\x26\xa5\x31\x44\x1a\xb3\xe1\x1d\xbc\x7b\xbf\x81\xb9\xf1\ \x14\xd9\x33\x5f\x41\xab\x79\xb3\x95\x44\x31\x37\x32\xf8\xbe\x7c\ \x10\xfb\xc4\x41\xec\xe1\xcd\xab\xeb\x5d\x8d\xd6\x20\x72\x13\xcb\ \xec\x91\xb0\xd1\xae\xfc\x48\x1e\xd0\x0a\x08\x8c\x63\xed\xfd\x26\ \xd3\x6f\x1d\x62\xf6\xe6\x7d\xab\xeb\x5d\x10\x05\x87\x2e\x08\x35\ \xbc\x1d\xe7\x52\x07\xf2\xc1\xa3\x4b\xce\x2f\x17\x22\x3a\x40\x79\ \xc7\x61\x46\x8f\xbf\x8c\x3b\xb4\x63\x65\x3d\x20\xd0\x2c\x6a\x93\ \x9a\x89\x90\x79\xfb\x55\xac\x2f\xbc\x0c\x9e\xf8\xd2\xed\x5b\xae\ \xad\xae\xc6\x8c\xf5\x52\xff\xf4\x61\xec\x13\xdf\x46\x4d\x57\x2f\ \xab\x47\x83\x0c\x7b\xc2\x72\x5b\xa8\x35\x77\x86\x9b\x7e\xca\x3d\ \x61\x26\xce\xb6\x53\xf6\xe8\x49\xaa\xd7\x45\x80\x48\x81\x87\x44\ \xa8\xf4\xcc\x5f\x89\x47\xc3\x38\x8f\x9e\xc4\xee\xfd\x1a\x6b\xdb\ \xfe\xb0\xa4\x3e\xe8\x91\x5e\x19\xcf\x26\xb2\x57\xa6\x06\x01\x08\ \xcb\x20\x55\xde\x4a\xc6\x7a\x9b\xb0\x1e\x7e\x85\xeb\x53\x4e\x09\ \xef\x5f\xf0\x8d\x58\x8d\x8f\x7a\x92\xa8\xc9\xcf\x32\x3e\x75\x79\ \x49\x7d\x6b\xfa\x3e\x5b\xe6\x6e\x2f\xf9\x0b\x89\xd0\x28\x47\x82\ \x70\xd0\x3a\x0b\xf9\xcf\xb4\x16\x79\xa3\x2e\x3c\x8a\x57\xe1\xea\ \x46\x2b\x94\xf7\x97\xd4\x2f\xd6\x6b\x3d\xe7\x01\x55\x7c\x3a\x39\ \xe0\x7a\xd0\x8e\xb9\xb4\x8b\x3f\x62\x64\xe3\x95\xa8\xf7\xbf\x84\ \x68\xf8\xcb\xb2\x1a\x03\x23\xb7\x00\xdc\xa2\x50\x60\xac\x39\x87\ \xea\xfb\xcc\x22\x5e\xf2\xbe\x02\x77\x6e\x36\x33\x7a\xfc\x3b\x88\ \x5d\x3f\x00\x6b\x62\x79\xbd\x06\xa9\xb5\x9e\xbf\x13\xaa\xdc\xb3\ \xd8\xfe\x63\xdc\x3f\x77\x82\x99\xc2\xa8\xeb\x2a\xf0\x45\x77\xbf\ \x39\xee\x48\x74\xbc\x1e\x7d\xfb\x41\xf4\xd0\x13\x7c\x68\x48\x6a\ \xdb\x8f\xf0\x81\xf7\xef\x25\x9f\xea\x85\x75\xb4\xd6\x18\x6d\x07\ \x9e\x1c\x9c\xd9\xe8\xac\x07\x28\x33\xfd\x44\xac\x08\x37\x66\x6f\ \x91\x99\xae\x61\xe4\x9d\x67\xc9\x4c\x57\x53\x51\xdf\x4b\xc0\xaf\ \x98\x71\x52\x68\xd7\x83\x33\x1b\xc4\x49\x07\xd1\xe9\x30\x6e\x3a\ \x84\x12\x19\x7c\x95\xd7\x29\xfb\x44\x3f\xe5\x1b\x2e\x50\x59\x3d\ \x55\xa8\x53\x3c\x8a\xeb\x03\x84\xae\x59\xa3\x72\x3a\x9d\xc8\xbe\ \x37\x36\x90\x73\xa9\x27\x48\xb5\x3f\x46\x5f\x62\x08\xb8\x0c\x8f\ \x9d\x84\x6c\x88\xf8\xf8\xa7\x70\xdd\x75\x8c\xa9\x49\xf0\x25\x31\ \xaa\xc6\xc1\x9a\x22\x14\x72\xf9\x64\xc4\xa2\x7f\xa6\x8f\x0c\x10\ \x07\x6e\xb8\x10\x9e\x28\xae\x53\xf4\xef\xf0\x94\xf2\x07\xec\x86\ \x8c\x94\x4a\xc4\x8b\x5b\xb2\xa8\xd5\x66\x02\x59\xd7\x45\xd8\x17\ \x63\x2c\x9f\x58\x98\xb5\x82\x40\x6c\xf1\xd6\xe8\x65\xb6\x6c\x01\ \x37\x1d\x92\xa2\x9a\x8a\xd3\xb1\x74\xb9\x73\x37\x66\xfb\x5f\x78\ \xcc\x8e\x3a\xe5\x76\xe8\xb4\x5c\x6b\xae\xf9\x96\x8e\xa3\xee\x88\ \x64\x9b\x29\x44\x99\x47\x78\xcc\xa8\xe3\xcb\x16\xaf\x5c\x9a\x52\ \x78\x2c\x4b\x85\x6d\xaf\x63\xba\x86\x2c\x70\x21\x85\x25\x2d\x23\ \xec\x7a\x33\xc5\x7a\xaf\xf6\x58\x1e\xe1\x31\x23\xae\x95\xd1\xc2\ \x28\xd8\xd0\x32\xa5\xb0\x4c\xaf\x88\x66\x7c\xc9\x8a\x4c\xb8\x3b\ \x64\xfb\x0f\xfd\x17\xab\x4f\xcd\x85\xce\xe9\x07\xc6\x00\x00\x00\ \x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x04\xfb\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdb\x02\x0a\ \x01\x2b\x28\xe3\x57\xca\xec\x00\x00\x04\x7b\x49\x44\x41\x54\x58\ \xc3\xe5\x97\x6d\x4c\x53\x57\x18\xc7\x7f\xbd\xa5\xf5\x52\x5e\x3a\ \x58\x47\xc7\x88\xc8\x14\x3f\xe8\xd2\x38\x06\xba\x65\x0b\xc9\x12\ \x96\xf8\x41\xbe\x8a\x53\xb6\x04\xb7\x69\x26\xd9\x96\x60\xc4\x30\ \x5c\x04\x09\x31\x66\x21\x8b\x09\xd3\xb0\x12\x97\x2d\x86\x45\xe3\ \x07\x5d\xc2\x48\xa6\x7b\x95\x4c\x08\x8a\x1a\x31\x46\xad\x20\x1d\ \x0e\xb6\xb6\xb8\x4e\xea\xed\x0b\xed\x3d\xfb\x50\xde\x2e\xe5\xa5\ \x54\xb3\x65\xd9\x93\xdc\xe4\xe6\x77\x72\xcf\xfd\x9f\xe7\x79\xce\ \x73\x9e\x03\xff\x77\xd3\xcd\x05\x93\x93\x93\x5f\x49\x4b\x4b\x7b\ \x49\xa7\xd3\x45\x26\x59\x38\x1c\x56\x47\x47\x47\x03\xf3\xcc\xf3\ \xe7\x8c\xf9\x4e\x03\xe3\xf1\x0a\x48\x9a\x0b\x5a\x2c\x96\x0f\x2a\ \x2a\x2a\xca\x6c\x36\xdb\x92\x56\xd3\xd4\xd4\xa4\xba\x5c\xae\x31\ \x97\xcb\x55\xa2\x28\x4a\x6f\xc2\x02\x0c\x06\xc3\xd8\xe6\xcd\x9b\ \x59\xaa\x80\xbe\xbe\x3e\x49\x51\x14\x73\x57\x57\x57\xb7\xdb\xed\ \x3e\xee\x70\x38\xde\x06\xc4\x42\xdf\x48\x8f\x33\x9e\x46\xa3\x91\ \x94\x94\x14\x4a\x4b\x4b\x93\x0a\x0a\x0a\x2a\x56\xae\x5c\x39\x02\ \xe4\x2d\xd9\x03\x33\xad\xbf\xbf\x1f\xaf\xd7\xab\x61\xa1\x50\x08\ \xa3\xd1\xa8\x61\xc1\x60\x90\xa1\xa1\x21\x3c\x1e\x0f\xb2\x2c\x33\ \x3e\x3e\xae\xcb\xca\xca\xb2\xfa\x7c\xbe\x5b\x8a\xa2\x1c\xf2\xf9\ \x7c\x75\x09\x79\xe0\xd4\xa9\x53\x13\x5e\x9c\x7e\x9a\x9b\x9b\x63\ \x98\xdd\x6e\x67\xe7\xce\x1d\xd4\xd6\x7e\xc8\xee\xdd\x55\xec\xdb\ \x57\x4b\x51\x51\x11\x4e\xa7\xd3\x58\x5e\x5e\xfe\x9e\xd5\x6a\x3d\ \x19\xb7\x07\x54\x55\x35\x4c\xbe\xe7\xe6\xe6\x52\x58\x58\xa8\x19\ \xcf\xc9\xc9\x89\x61\xd9\xd9\xd9\x31\xac\xa7\xa7\x07\x59\x96\x69\ \x69\x69\xc9\x6c\x6f\x6f\xb7\xc5\xed\x81\x48\x24\x22\x3f\xee\xfd\ \x6e\x30\x18\x02\x71\x7b\x60\xd9\xb2\x65\x53\x01\x3e\x76\xe2\x18\ \xad\x67\x3e\xd3\x8c\xdf\xbe\xe1\xe0\x92\xb3\x27\x86\x75\xf7\x5f\ \xd0\xb0\xe1\xc1\x11\x76\xed\xaa\x24\xa1\x24\x4c\x4d\x4d\x8d\x16\ \xa5\xe5\x32\x9d\xa6\x9f\x34\x63\xe6\xfb\x19\x5c\x5e\x71\x49\xc3\ \xe4\xe1\x94\x18\x66\x35\x3e\xbd\xa8\x67\xe6\x4d\x42\xbd\x5e\xff\ \x8f\x94\x62\x89\x7f\xd9\x16\xad\x03\xca\x88\x82\xcd\xb4\x4e\xc3\ \x06\x3c\x77\xb1\x8d\x68\x59\xff\x5f\xfd\xd8\xee\x6a\x99\xe7\xde\ \x68\x62\xaa\xf2\xf3\xf3\x4f\x3b\x9d\x4e\x21\x84\x10\x6d\x6d\x6d\ \x42\x08\x55\xf3\xec\xd9\xb3\x27\x86\xd5\xd4\xd4\xc4\xb0\xa3\x47\ \x8f\x88\x49\xcb\xcb\xcb\xbb\xfc\xdf\x0c\x41\x57\xd7\x05\xdc\x6e\ \x97\x86\x5d\xbd\x7a\x95\xc6\xc6\x46\x0d\xbb\x78\xb1\x87\xc6\xc6\ \x46\xae\xdd\xb8\xc6\xcd\xd1\x5b\x28\xe3\x0a\xa1\xd1\x10\xeb\x37\ \x6c\xa0\xa8\xb0\x28\x71\x01\x6b\xd7\x3e\xc7\x96\x2d\x65\x1a\x36\ \x38\x38\x48\x65\xa5\x76\x7f\x77\x9c\xef\xa0\xfe\xb7\xfd\xe8\x37\ \x82\x90\x80\x20\x10\x80\x97\xcf\xac\x27\x52\x0d\x96\x60\x56\x6a\ \x42\x02\xcc\x66\x33\x99\x99\x99\xb3\x6a\x44\x9a\x86\x6d\x7a\xbf\ \x94\xde\x6d\xdd\xe8\x4d\x20\x42\x50\x6d\xaa\xc1\x90\x69\xe0\xfc\ \xad\x9f\xe9\x4c\x39\x8f\x54\x0c\xf7\x73\x5d\xab\xf9\x9a\xb7\xf0\ \xf2\x79\x3c\xa5\x38\x29\xde\x18\xd6\x1d\xae\xe7\xbb\x17\x3a\x40\ \x06\xa1\x44\x7b\xa3\xbd\x25\x35\xd4\x6f\x6a\x60\x8d\x65\x2d\x04\ \x80\x30\x90\x01\xfa\x12\x8e\x61\xe0\xc5\x45\x3d\x30\xf3\x2c\xe8\ \xec\xec\xc4\xe1\x70\x68\xc6\xaf\x5c\xb9\xc2\x81\x03\x0d\x84\x42\ \x21\x3e\x0e\x1c\x44\x67\x01\x1e\x02\x5e\x10\x0f\x66\x9e\xdb\x13\ \xa1\x08\x83\x08\x02\xa9\xc0\xb3\xfc\xc2\xed\xe9\xff\xce\xd7\x11\ \x4d\xf1\xe2\xe2\x62\xb6\x6d\xdb\xaa\x19\xaf\xae\xde\x4b\x5d\xdd\ \x7e\x6a\x0f\xed\x43\x97\x0f\xf8\x81\x31\x10\xde\x89\x1f\x4e\x9e\ \xaa\x61\x35\x2a\x22\x0c\x44\xa2\x39\x21\x65\xa1\x57\x6f\x93\x0d\ \x8c\xc4\x75\x16\x2c\x64\xdf\x5c\x6f\x07\x33\xac\x93\x9e\xe7\xec\ \xf6\x1f\xa6\x78\x7a\x7a\x3a\x00\xcd\xef\x1c\xe1\xe0\xd8\xa1\xe9\ \x5e\x73\x7b\x26\x18\x00\x99\x1d\x04\x68\x58\x50\x40\x3c\x67\xc1\ \xa0\x6b\x10\x7c\x20\x4c\x90\x91\x91\x11\x9b\xe1\x49\x49\x5a\xae\ \x4c\xba\x98\x1c\x02\x71\xee\x02\xbf\x5f\xc1\x6e\x6f\x9d\xc5\xfc\ \xd8\xed\xad\x98\x02\x26\x94\x87\x63\xf8\x83\x7e\xbe\xfc\xf6\x0b\ \x50\x41\x87\x8e\x37\x36\xbe\x89\x24\x49\x0c\xbb\x87\x39\x77\xe9\ \x2c\xa8\x13\x61\x08\x4f\x26\x19\xbf\x2f\x78\x2f\x58\xb5\x6a\xd5\ \x8f\xbd\xbd\xbd\xaf\x9a\xcd\xe6\x05\xc5\x55\x7d\x54\xc5\xa7\xfe\ \xc3\xb3\xbb\x33\x3c\x0d\x5e\xcc\x66\x33\x95\x2d\xbb\xb0\xf7\xb5\ \xc0\x03\x10\x7f\x4c\x08\xf0\x83\xda\xcd\x6a\xe0\xce\x23\x97\xe2\ \xfa\xea\x7a\xd4\x9b\x20\xc6\x40\x3c\x8c\x66\xba\x08\xcd\xec\xed\ \x88\xfe\xdc\x33\xbd\x7a\x11\x5d\xfb\x9d\x05\x77\x41\x38\x1c\x96\ \x07\x06\x06\x58\xcc\x03\x00\x5b\x97\x97\x73\xc2\xdd\x36\xbd\x94\ \x24\x78\xf2\xdd\x27\x40\x80\x08\x44\x05\xcc\xcc\x01\x71\x8f\xd7\ \x16\xad\x03\x7e\xbf\xff\x5c\x59\x59\x99\x57\x92\xa4\x48\x5c\x4d\ \x85\x62\x28\x8e\xac\x19\x4f\x9f\x8a\xf1\x9c\x93\x82\x7a\x9d\x5a\ \xc2\x7c\xbf\xe8\xdd\x30\x21\x4b\xe3\x13\xdd\x0a\xaa\x74\x96\x59\ \xb3\x46\x40\x0c\x83\xf8\x95\xd7\x09\x71\x32\xae\xcb\xe9\xa3\x5c\ \x8e\x78\x8a\xbd\x58\x29\xd1\xc9\x3c\x23\x1e\x30\xc0\x10\xc7\xf1\ \xf3\xd5\x7c\x1f\xfc\x0d\xb4\x6c\xf0\x92\xe9\xcc\xd4\xdd\x00\x00\ \x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x03\x66\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xda\x03\x0a\ \x0b\x32\x07\x28\x2d\x21\x6e\x00\x00\x02\xe6\x49\x44\x41\x54\x58\ \xc3\xc5\x96\x4b\x48\x54\x51\x18\xc7\x7f\xf7\xde\xe3\x63\xc6\xc6\ \xa9\xa1\xc8\xc4\x0a\x83\x02\x73\x8a\x40\x92\x0a\x2a\x5a\xf4\x20\ \xa2\x4d\xd6\x22\x8a\x6a\x25\x6d\x7a\x2d\x0c\x42\x5a\x95\x24\x11\ \x81\xb4\x28\x68\xd7\x20\x65\xf4\x82\x70\x11\x3d\xa8\x44\x2c\x23\ \x83\x88\x42\x53\x4c\xcd\xc9\xc7\x88\xce\x38\x33\x7a\xe7\xde\xb9\ \x2d\x66\x46\x9a\x4c\xbd\x36\xe3\xf5\x0f\x67\x73\xef\xe1\xfb\xbe\ \xf3\xff\xfe\xff\xef\x1c\xc9\x30\x0c\xe9\xf5\x7b\xf5\xd2\x8f\x5e\ \x7d\xef\xb0\xdf\x70\x60\x01\x16\xe6\x4a\x81\x95\xf9\x4a\xfd\xf6\ \xd2\xcc\x4a\xf1\xe4\x65\xb8\xe2\x54\x55\xa0\xa2\xcb\xab\x09\x2c\ \xc4\x8a\x65\xc2\x5d\x73\xc1\xe1\x17\x6f\x5b\xd4\x3d\x5d\x03\x9a\ \xc0\xd2\xf4\xd0\x35\xa0\x89\xb7\x9f\xd4\xdd\xa2\xb5\x47\xcf\x42\ \x61\x5e\xd0\xda\xad\x67\x0b\x7f\x18\xcd\xea\xd3\x27\xe0\x0f\xa3\ \x09\x64\x98\x2f\x06\x90\x41\x46\x01\x84\xb5\xcb\xe1\xbb\x0b\xc6\ \x20\x28\x20\x26\x7e\x58\x00\x25\xf4\x9d\xf5\x6d\x95\xec\x1a\x79\ \x4f\xf5\x82\x55\x20\x0a\x10\x48\x16\xb4\x40\x0f\xb2\xaa\xf5\x22\ \x47\x7d\xaf\xa8\x1c\xef\xa3\x09\xa8\x96\x01\x69\xae\x19\xd0\xc3\ \xe4\xb5\x5f\x66\xc7\x40\x03\x35\xa3\x6d\x2c\x4e\xa2\x23\x96\x57\ \x4c\x68\x20\x5d\x30\x74\x72\x82\xcf\x59\x6d\xab\xa3\xd4\xfd\x8d\ \x9f\x9f\xfb\xa9\x1d\x0d\xfd\xa3\x1f\xc4\x35\x90\x2e\x17\x68\x41\ \x96\xf7\x9e\x64\x73\xc9\x4f\xca\x8f\x74\xb0\x63\xbb\x8a\x24\x41\ \xd9\xe3\x29\xa6\xbb\x12\x73\x41\x7a\x18\x88\x46\x58\xfb\xee\x28\ \x79\x05\x5f\xb8\x77\x7b\xd4\xa4\x22\x63\x4b\x4e\xd9\x56\x8a\x8e\ \xbb\xb9\x9c\xbb\x43\xcd\xd8\xb3\xe5\x59\x58\x22\xa1\x81\x14\x5d\ \xb0\xa6\xf1\x34\x75\xde\x17\xe4\x1b\xd1\x59\x0f\xa1\x94\x5d\x50\ \xd8\x74\x1e\x4f\x4f\x3d\x45\x51\x8d\x11\x62\x01\x27\x41\x9a\x23\ \x06\x0a\x3e\x5e\xe1\x56\xe7\x43\x36\xea\xe3\xff\x3d\x86\xff\x93\ \x01\x83\xa5\x8d\x67\xb8\xf6\xfd\x19\x3b\x23\xa1\x19\x77\x4b\xb2\ \x3c\x03\x03\xb2\xf9\x02\xa4\x70\x1f\x1b\x7c\xa7\xc8\xf4\xb7\x70\ \x48\x0d\x9a\x9b\x45\xd1\x29\x7a\x20\x12\x97\x91\x49\xb5\xbb\x06\ \x6b\x39\xe1\x3a\x40\xe3\xfd\x06\x9c\x2e\xf3\x3d\x33\x0c\x23\x45\ \x0d\x8c\x07\x28\xee\x3d\x4b\xd5\xc9\x37\xec\xdf\x13\x4c\xdf\xc4\ \x9c\x51\x03\x61\x1f\xb4\x5d\xa7\x44\x7b\xce\x8b\x47\xdd\x38\x9d\ \x66\x7a\x44\x8a\x73\x20\xd8\x0f\xbf\xee\x80\xbd\x09\x8a\x3a\x60\ \xdb\x2f\xb6\xb6\x38\xcc\x25\x9f\x6d\x51\x49\x0c\x0c\xbe\x84\xc8\ \x0d\x58\xd7\x09\x95\x7d\x90\x17\xdf\xd4\x00\xb4\xa4\x21\xd9\xb4\ \x0c\x28\x40\xe8\x03\xdc\x7c\x07\xce\x39\x48\x34\x15\x32\xc4\x1f\ \x77\x81\xc4\xdc\x61\xaa\xd8\x36\x3b\x08\x90\x91\xe2\xfd\xb0\x10\ \x11\x39\x76\x7a\xa4\x04\x03\x16\x17\xa0\x8a\xcc\x09\x0d\xc4\x18\ \x48\x53\x0b\x84\x30\x17\x28\x8c\x31\xe1\x02\xd9\x66\x33\x86\xa6\ \x65\xc0\xe4\x0d\x17\x06\xa2\x59\x93\x03\x65\xc8\x93\x37\xab\xf1\ \x51\x6c\xcf\x96\x7c\xa2\x78\x91\xf0\xbc\xc9\xdf\xb2\x2f\x74\xbc\ \x5d\x41\xf9\x2b\x40\x20\x40\x5d\x46\x0e\x4f\x8f\xe5\x26\x7d\x1e\ \xcb\xf1\x52\x58\x92\xfc\xd4\x8a\x6a\x11\xd4\x50\x88\xc2\xb2\x64\ \x2b\x45\x73\x87\x28\x2c\x71\x25\x17\xa0\x8e\xe1\xc8\xcb\x8f\x14\ \x2d\x91\x3d\x12\xc0\xb9\xc6\xe1\x83\x5f\x87\xa3\x87\x47\x55\x7d\ \x99\x15\x1a\x58\x90\xa9\x78\xdd\xae\x0c\xcf\xd5\x4d\x8e\x07\xbf\ \x01\x44\x5c\xe5\x31\x30\xd0\x60\xe0\x00\x00\x00\x00\x49\x45\x4e\ \x44\xae\x42\x60\x82\ \x00\x00\x04\x7c\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdb\x02\x0a\ \x01\x2a\x2d\x8a\x26\x0f\x22\x00\x00\x03\xfc\x49\x44\x41\x54\x58\ \xc3\xe5\x97\x5f\x48\x5b\x57\x1c\xc7\xbf\x49\x4c\xbc\x62\x4c\x8a\ \x48\x9c\x13\xa2\xa8\xeb\xfa\x62\x21\xc4\xc1\x60\x7d\x5a\x5b\x06\ \xc3\xf6\xa5\xa8\xa8\x94\xca\xec\x3f\x47\x49\xab\x28\xfe\x29\xac\ \x18\x64\x16\x6a\xd9\x83\x34\x0b\xe9\xc3\x0a\xd6\x07\x49\xa5\x2b\ \xf8\x20\x6c\x30\x46\xc4\x14\xc3\x16\x51\x9c\x6b\x6e\x0d\x49\x83\ \xb4\xcb\x9f\x36\x8d\xd9\x8d\xd1\x24\xa7\x2f\x57\x77\x6f\x6e\x62\ \x6e\x82\xfb\x03\x3b\xf0\x23\xe7\x7c\xce\x3d\xf7\xfe\xee\xf7\xf7\ \xbb\xbf\x93\x03\xfc\xdf\x9b\x24\x13\x2c\x29\x29\xf9\xa4\xac\xac\ \xec\x63\x89\x44\x92\xdc\x63\x89\x44\x22\x15\x0a\x85\xb6\xb3\xdc\ \xe7\x0d\xe7\x7e\x8f\x01\xec\x8a\x75\xa0\x28\x13\xac\xa8\xa8\x30\ \x74\x75\x75\xb5\x36\x36\x36\xe6\xf5\x36\x13\x13\x13\x29\xbf\xdf\ \xbf\xe5\xf7\xfb\x4f\x32\x0c\xf3\x4b\xc1\x0e\xc8\xe5\xf2\xad\x96\ \x96\x16\xe4\xeb\xc0\xea\xea\xaa\x94\x61\x18\xb5\xdd\x6e\x7f\x1a\ \x08\x04\xa6\x68\x9a\xee\x06\x40\x0e\x5a\x23\x3d\xcc\x78\x2a\x14\ \x0a\x94\x96\x96\xa2\xb9\xb9\xb9\x48\xa7\xd3\x75\xd5\xd5\xd5\xbd\ \x04\x50\x9b\xb7\x02\xdc\xb6\xb1\xb1\x81\x70\x38\xcc\x63\x3b\x3b\ \x3b\x50\x28\x14\x3c\x16\x8f\xc7\xe1\xf3\xf9\x10\x0c\x06\x41\x51\ \x14\x76\x77\x77\x25\x1a\x8d\xa6\x32\x1a\x8d\x3e\x63\x18\xe6\x76\ \x34\x1a\xbd\x55\x90\x02\x56\xab\x95\x55\xf1\x2f\x9b\x9c\x9c\x14\ \x30\x8b\xc5\x82\xcb\x97\x2f\x61\x64\x64\x18\x7d\x7d\xbd\xb8\x79\ \x73\x04\x4d\x4d\x4d\xf0\x7a\xbd\x8a\xce\xce\xce\x6b\x95\x95\x95\ \x33\xa2\x15\x48\xa5\x52\xf2\xbd\xbe\x56\xab\x85\x5e\xaf\xe7\xcd\ \x57\x57\x57\x0b\x58\x55\x55\x95\x80\x2d\x2d\x2d\x81\xa2\x28\x98\ \xcd\xe6\xf2\xb9\xb9\xb9\x46\xd1\x0a\x24\x93\x49\xea\xb0\xbf\x77\ \xb9\x5c\xbe\x2d\x5a\x81\xe2\xe2\xe2\xfd\x00\xcf\xcf\xcf\xc3\xe1\ \x70\xf0\xe6\x57\x56\x56\xd0\xdb\xdb\x97\x93\xb9\x5c\x2e\xf4\xf4\ \x7c\x99\xbf\xb7\x0d\x0d\x0d\x8f\xdd\x6e\x37\x21\x84\x10\x93\xc9\ \x44\xd2\xdb\xe0\xe0\xa0\x80\x19\x0c\x06\x01\x9b\x9e\x9e\xde\xef\ \xd7\xd6\xd6\xfe\x9a\x57\x12\xca\x64\xb2\x7f\xa4\x14\x4b\xf1\x2f\ \xb7\x9c\x75\x60\x79\x79\x19\xe3\xe3\x5f\xf3\xd8\xfa\xfa\xba\x80\ \xb9\x5c\x2e\x0c\x0c\x0c\xf0\x18\x4d\xd3\xe8\xe8\xe8\x28\x2c\x07\ \xbc\x5e\x2f\x27\x8e\x29\x9e\xf5\xf7\xf7\x0b\xd8\xd0\xd0\x90\x80\ \x99\x4c\xf7\x0a\xcf\x81\xff\x4c\x08\xec\xf6\x45\x04\x02\x7e\x41\ \x58\xc6\xc6\xc6\x78\xcc\xe1\x58\x82\xd1\x68\x84\xcd\xf6\x1c\x34\ \x5d\x85\x48\xa4\x14\x32\xd9\x73\x10\xa2\xc2\x95\x2b\xed\x85\x87\ \xc0\x64\x32\x91\x50\x28\xc8\xb3\x1b\x37\xae\x0b\x98\x4e\xd7\x49\ \x00\xc2\xb1\x3f\x39\xfd\x1f\xc8\x91\x23\xc7\x36\x0b\x0a\x81\x5a\ \xad\x46\x79\x79\x39\xcf\x94\xca\x32\xde\xf8\xcc\x99\x27\x70\x3a\ \x1f\xee\xaf\x19\x1e\xfe\x1d\x1e\x4f\x04\x6d\x6d\x6e\x96\x9c\x42\ \x38\xbc\xf6\x3e\xf0\xd9\x23\xb1\xa5\xb8\x48\xac\x5a\x3d\x3d\xdf\ \x61\x71\xf1\x0b\xee\x4e\x82\xd6\x56\x0a\x35\x35\xef\xe1\xec\xd9\ \xf4\x47\xdd\x3b\x07\x7c\xd0\x9f\x33\x07\xb8\x7b\x81\xcd\x66\x03\ \x4d\xd3\xbc\x79\xa7\xd3\x89\xd1\x51\x23\x62\xb1\x18\xcc\xe6\xdb\ \x82\x77\x7a\xf0\x20\x8e\x0b\x17\x3c\x98\x99\xe1\x16\xb3\x38\xeb\ \xc4\xf9\x3b\xc0\x57\xdf\x00\x48\x66\x7d\xab\xfa\xfa\xfa\x9f\xc4\ \x7c\x86\x06\xc3\xb7\x69\x71\xe7\x5a\x32\x6d\x1c\x21\x80\x93\x00\ \xdf\x13\xa0\xa2\x37\x67\x0e\x28\x95\xca\x9c\xf2\xcf\xce\x66\xe6\ \xed\xed\xbf\xe1\xee\x5d\x0f\x4e\x9f\x76\xa6\x29\xf0\x16\xc0\x6b\ \x00\xd5\xe7\x0e\x65\x2f\xd8\xdc\xcc\xfc\x77\x4f\xaf\x57\xe2\xea\ \xd5\x3a\x1c\x3d\xba\x17\xe1\x1d\xf6\xe1\x6f\xd8\xbe\x52\x2b\xba\ \x0e\xc4\x62\x0c\x2c\x96\xfb\x69\x2c\x06\x8b\xe5\x3e\x54\xaa\x17\ \x88\x44\x0e\x5a\x9d\x62\x7f\xb7\x01\x44\x00\xfc\xc1\x8e\x99\x57\ \xa2\x1d\xe8\xee\xbe\x98\x75\x6e\x61\xc1\x88\xa9\xa9\x74\x4a\xd2\ \x32\x3f\x06\x60\x0b\x80\x87\x33\xff\x72\xfe\x50\x4a\xf1\xe8\xe8\ \x79\x00\x3f\xb3\xd2\xbe\x66\x65\x8e\x73\x12\x3c\x0e\x20\x08\x60\ \x0d\xc0\x5e\x35\x5d\x03\xf0\x6a\xfc\x40\x05\x12\x89\x04\xe5\x76\ \xbb\xa1\x56\xab\x73\x3a\x71\xe2\x84\x15\x0b\x0b\x4a\x8e\xe4\x72\ \xf8\x7c\x6f\x61\xb3\xc5\x11\x0c\x7a\x01\xb8\x58\x05\xc0\x1e\x98\ \xe6\xcc\xac\x2c\xd9\x8f\x66\x1a\x8d\xc6\xa8\x52\xa9\x3e\x92\x4a\ \xa5\x49\x31\x4a\xd0\xf4\xb1\xcf\x09\xe9\x90\x00\x51\x00\x89\x2c\ \x57\x25\x01\x4c\x6d\x00\x4f\x1b\x72\x9e\x0d\x0b\x3b\x63\x1e\xff\ \x11\x68\xfe\x14\xd0\x66\x98\x76\x03\x78\x62\x05\x9e\xb5\xfe\xcd\ \x9b\x6b\xf1\x87\x40\xdb\x2c\x30\xb9\x0d\xcc\x10\x60\x3c\x02\x9c\ \x9a\x06\x50\x93\x6d\xc5\x3b\x48\x59\x60\xc6\xe8\x3d\x22\x0e\x00\ \x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x04\x70\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdb\x02\x0a\ \x01\x2b\x0a\x36\x37\x8b\x08\x00\x00\x03\xf0\x49\x44\x41\x54\x58\ \xc3\xe5\x97\x6d\x48\x64\x55\x18\xc7\x7f\x33\xce\x8c\x23\x8e\xce\ \x22\x32\x6a\xb6\x22\x3a\x9f\x5c\x8d\x44\x4b\xa9\x3e\x24\xc1\x2e\ \x84\xd4\x87\x45\x37\x12\x4a\x08\x85\x75\x63\x41\x31\xd6\xdc\xd8\ \x17\x1b\xa8\x16\xa1\x0f\x6e\xee\x30\x6b\x5b\x12\x42\xa2\x61\x85\ \x41\x6d\x84\x81\xed\xda\x2a\xa6\x34\x2d\x95\xc3\xcc\x3a\xf9\xc1\ \x1a\xb5\x26\x9c\xbd\xce\x9b\x73\xfa\x30\x63\xeb\x6d\x1c\xef\xcc\ \x60\x2f\xd0\x03\x87\x7b\xf9\x9d\x73\x2e\xff\xf3\x3c\xcf\x79\xce\ \xb9\xf0\x7f\x37\xd5\x5e\x30\x2b\x2b\xeb\xd1\x9c\x9c\x9c\x7a\x95\ \x4a\xb5\xbd\xc3\xc2\xe1\x70\x64\x63\x63\xc3\x9f\xe0\x3b\xbf\xed\ \xfa\xde\x04\x10\x4a\x56\x80\x66\x2f\x98\x9f\x9f\x7f\xba\xb5\xb5\ \xb5\xb9\xaa\xaa\x2a\xa5\xd5\xf4\xf7\xf7\x47\x3c\x1e\xcf\xa6\xc7\ \xe3\x79\x42\x92\xa4\xf9\xb4\x05\x68\xb5\xda\xcd\xa6\xa6\x26\x52\ \x15\x60\xb7\xdb\xd5\x92\x24\x19\x67\x66\x66\xbe\x5e\x5b\x5b\x7b\ \xcf\xe1\x70\xbc\x00\x88\xfd\xe6\xa8\x0f\x32\x9e\x3a\x9d\x8e\xec\ \xec\x6c\x1a\x1b\x1b\x35\xd5\xd5\xd5\xad\x65\x65\x65\xab\x40\x69\ \xca\x1e\xd8\x6d\x4e\xa7\x13\xaf\xd7\x2b\x63\xc1\x60\x10\x9d\x4e\ \x27\x63\x81\x40\x80\x95\x95\x15\xd6\xd7\xd7\xd1\xeb\xf5\x84\x42\ \x21\x95\xc9\x64\x2a\xf0\xf9\x7c\x3f\x4a\x92\xf4\xba\xcf\xe7\x3b\ \x9f\x96\x07\xc6\xc6\xc6\x62\x5e\xbc\xd7\x06\x06\x06\xe2\x98\xcd\ \x66\xa3\xbd\xbd\x8d\xde\xde\x97\xe9\xea\xea\xe4\xec\xd9\x5e\x6a\ \x6b\x6b\x71\xbb\xdd\xba\x96\x96\x96\x17\x0b\x0a\x0a\x46\x93\xf6\ \x40\x24\x12\xd1\xee\xbc\x97\x94\x94\x50\x53\x53\x23\xeb\x2f\x2e\ \x2e\x8e\x63\x45\x45\x45\x71\x6c\x76\x76\x16\xbd\x5e\x8f\xd5\x6a\ \xcd\x9b\x9c\x9c\xac\x4a\xda\x03\xdb\xdb\xdb\xfa\x83\xde\xef\x5a\ \xad\xd6\x9f\xb4\x07\x32\x33\x33\xff\x0c\xf0\xa7\x43\x43\xcc\x59\ \xad\xb2\xfe\x6f\x1d\x0e\x3a\x6f\xdd\x92\xb3\xa5\x25\x3a\x6f\xdc\ \x90\xb1\xa5\xd5\x55\x4e\x9e\xec\x48\x5d\xad\xd9\x6c\x9e\x70\xb9\ \x5c\x42\x08\x21\x06\x8f\x1d\x13\x02\x64\xed\x4c\x61\x61\x1c\x3b\ \x7d\xe8\x50\x1c\x1b\x39\x7c\x58\xec\x58\x69\x69\xe9\x37\x29\x25\ \x61\x46\x46\xc6\x3f\x52\x8a\xd5\xfc\xcb\xa6\x58\x07\x16\xfd\x7e\ \x5e\xab\x7b\x58\xc6\xbe\xbf\xb3\x1c\xc7\x96\x9c\x2e\x5e\xaa\xab\ \x93\x31\xc7\xc6\x06\xcf\xa6\xa3\xca\x6c\x36\x4f\xb8\xdd\x6e\x21\ \x84\x10\x23\x23\x23\x42\x88\x88\xac\x75\x77\x77\xc7\xb1\x9e\x9e\ \x9e\x38\x36\x38\xf8\x56\xfa\x39\xf0\x9f\x09\xc1\xcc\xcc\x4d\xd6\ \xd6\x3c\xf2\xb0\x2c\x2e\x62\xb1\x58\x64\x6c\x6e\x6e\x16\x8b\xc5\ \x82\x24\x49\xb8\xed\x76\x54\x9b\x3e\x9c\x5e\x2f\x6d\x6d\xed\x68\ \x34\x9a\xf4\x05\x54\x54\x1c\xe1\xc4\x89\x66\x19\x5b\x5e\x5e\xa6\ \xa3\x43\xbe\xbf\xed\xf3\xf3\x54\xf5\xbd\xca\xd3\x21\xf9\x55\xc0\ \xa3\xd5\x62\x2b\x2b\x23\x1c\x0e\xeb\xd2\x12\x60\x34\x1a\xc9\xcb\ \xcb\x93\x31\x83\x21\x47\xc6\xde\xbf\x74\x89\xd1\x0f\x3f\xda\x73\ \xbe\x09\x78\xc5\xe5\xe2\x71\x38\x72\x1c\x8e\x7a\xe0\x7a\x32\xa5\ \x58\x93\x6c\x0c\x3f\x1f\x1f\xe7\x99\x33\x3d\x8a\xe3\x1e\x03\x86\ \xe0\x33\xc0\xac\xe8\x81\xdd\x67\xc1\xf4\xf4\x34\x0e\x87\x43\xd6\ \xbf\xb0\xb0\xc0\xc5\x8b\x7d\x00\x3c\x77\xe1\x42\x52\x42\xc3\xc0\ \x03\xc0\x71\xb8\xf9\x41\xd4\x31\x89\xad\xbc\xbc\x7c\x2a\x99\x6d\ \x38\x7e\xed\xed\xb8\xf2\x9b\xa8\x79\x41\xcc\x83\xe8\x8f\x9e\xdf\ \x05\x8a\x39\x60\x30\x18\x14\x57\xf5\xcb\x3b\xef\x46\x0b\x4e\x4d\ \x0d\x99\x95\x95\x09\xc7\x09\xc0\x07\xac\x0f\x0f\x63\x00\x0a\xa1\ \xe3\x67\x38\xbf\xaf\x80\x64\xce\x82\x90\xd3\x19\xbd\x45\xd7\xd7\ \x73\xff\xe5\xcb\x8a\xe3\x6f\x0f\x0f\x47\x17\xb7\x2b\x0f\x14\x93\ \x6d\x6b\x4b\xc2\x66\xbb\xfa\x17\xb6\x85\xcd\x76\x95\x9f\x52\x2c\ \x3a\x3b\x77\xf7\xc0\xbd\xd7\xc4\x39\xe0\xf5\x7a\x85\x92\xbd\x71\ \xea\x54\xc2\x98\x07\x63\x4f\x09\x84\x1b\xc4\x28\x08\x2b\x88\x37\ \x41\x64\xc2\xd1\x03\x29\xc5\xad\xe7\xce\xf1\x25\xe0\x05\x7e\x05\ \xfc\xc0\x56\xec\x19\x8c\xf1\x75\xe0\xf6\xae\xd5\xcf\x45\x3d\x70\ \x7d\xdf\x10\x84\xc3\x61\xbd\xcb\xe5\xc2\x68\x34\x2a\x8a\x98\x68\ \x68\xc0\x38\x35\x45\x08\xd0\xc6\x7e\x8d\x74\xb1\x6d\x77\x17\xb8\ \x03\x6c\xc6\xc6\xde\x05\xbe\x80\x2e\xc5\x5f\x33\x93\xc9\xd4\x97\ \x9b\x9b\xfb\x90\x5a\xad\xde\x4e\xc6\x13\x15\x0e\xc7\x93\xcd\x42\ \xa8\x02\xd1\xd5\xed\x69\xfe\x68\x21\xfa\xe4\x3b\x68\x54\x14\x90\ \xce\x3f\xe6\x83\xf0\xd5\x53\xf0\xc8\x7d\x7b\x74\xfe\x00\x7c\x0c\ \x57\x5c\xd0\xc1\xdf\x69\x3a\xa8\x7c\x1e\x26\xaf\x40\x70\x14\x84\ \x05\x7e\x6f\x80\x6b\x40\x51\xa2\x39\x7f\x00\x88\x1a\x30\xc2\x48\ \x5c\x9e\x07\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x06\x9e\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xda\x03\x04\ \x0b\x2c\x1c\x96\xd6\xa0\x6e\x00\x00\x06\x1e\x49\x44\x41\x54\x58\ \xc3\xbd\x97\x6b\x70\x94\xd5\x19\xc7\x7f\xe7\x7d\xdf\xbd\xbc\x9b\ \xec\x66\x59\x12\x92\x50\x11\x0c\xd4\x02\x2a\x62\xa5\xb4\x54\xc0\ \x16\xad\x56\xe9\x30\xc5\x82\x20\xd8\x69\xda\xc2\x50\xdb\x52\x18\ \x51\x6c\x9d\x38\x65\x6a\x4b\xd1\x22\x9d\x14\xc6\x8e\x74\x6a\x3b\ \x42\xeb\x60\x1b\x9c\x58\x06\xa8\xa5\x0e\x8d\x60\x87\x68\x12\x2e\ \x42\x42\xc0\x45\x72\x21\x97\xcd\x65\x2f\x49\xf6\xf2\xde\xfa\x21\ \x76\x97\x98\xdd\x0d\xcb\x07\xce\xcc\xf9\xf0\x3e\xef\x73\xfe\xe7\ \xcc\xff\xf9\x3f\xcf\x79\x8e\xb0\x2c\x4b\xfc\xa7\x36\xf1\xcb\xcb\ \x57\x8c\x87\x83\x61\xcb\xcd\x0d\x18\x5e\x8f\x88\x4c\x9e\x28\x1f\ \xbc\x77\xae\xbd\x42\xa9\x7e\x27\xba\xf9\x27\x5b\x23\x9b\x5b\x3a\ \x74\x85\x1b\x38\x6e\x2e\x55\x6e\xff\xdd\xb3\xee\xb0\xf2\x6e\x43\ \xe2\xeb\x2d\x01\x5d\xe1\x3a\xb6\x9f\xfd\x39\x1b\x33\xa7\x2a\x9c\ \x38\xa3\xf1\x51\xab\x9e\xd3\xda\x96\x80\xae\xbc\x7b\x32\xf1\xa0\ \xd2\xdc\x66\x38\x90\x73\xdf\xbc\x62\x8d\x9b\xe7\xd6\xe6\x03\xa0\ \x1b\xf0\xbd\x2d\x41\xf6\xbd\x1d\xcd\x09\xa3\xb9\xd5\x70\x4a\xe1\ \x28\x3a\x0a\xe4\x32\x6d\x4e\xc1\xe6\xf2\xfc\x24\x90\x22\x33\xfc\ \x9d\x23\x4e\x38\x8a\xae\x20\x41\xae\x0c\xe8\x58\x84\x07\x4d\x8a\ \xbc\x52\xd2\xd6\x17\x31\x73\xc6\x41\x02\x09\x99\x9c\x4f\x6e\xc9\ \x50\xbe\x35\x48\x57\xbf\x09\xc0\xf9\x56\x9d\x8d\x3b\x43\x39\xe3\ \x20\x83\x92\xfc\xc8\x61\x14\x79\x25\x8e\x37\x26\x98\xb2\xb2\x8b\ \xf1\x05\x12\x81\xa0\xf9\x49\x2c\xc0\xe3\x12\x7c\xeb\x5e\x95\xc3\ \xb5\x71\x3a\x7a\x8d\xec\x40\x0a\x28\x88\xdc\x42\xf0\xec\xaa\x7c\ \x9e\xff\xae\x87\x78\xc2\xe2\xad\xff\xc6\xa8\x7e\x2f\xc6\xa1\xda\ \x38\xa5\x3e\x89\x27\x96\xe4\xb1\x6a\x91\x8a\xdb\x25\xd8\x7d\x60\ \x88\xf5\xbb\x42\xd9\xc1\x44\x8e\x0c\x4c\x9e\x20\xb3\x79\x45\x3e\ \x42\x80\xdd\x26\x58\x3a\xdf\xc9\xd2\xf9\x4e\x0c\x03\x1c\x36\x81\ \x6e\x5a\x00\x04\x42\x26\x47\x3f\x8c\x8f\x8d\xab\x80\x92\xd4\xc0\ \x58\x7a\x11\xf0\xc7\x4d\x5e\x54\x87\xe0\x83\x0b\x09\x2a\xf6\x44\ \x58\x3c\xc7\xc9\x92\x2f\x3a\xf9\x4c\xa1\x84\x10\x70\xd2\xaf\x51\ \xf9\xd6\x20\x55\xc7\x63\xc4\x35\x6b\x6c\x5c\x19\xae\x39\x0b\x9e\ \x59\xe6\x66\xc1\x6d\x76\x62\x09\x28\xaf\x0c\x72\xae\x55\xe7\xed\ \x53\x71\x36\xbe\x1a\xe2\xae\x32\x1b\xba\x01\xa7\x3f\xd6\x92\xfe\ \x76\x87\xc0\xad\x0a\x42\x43\x26\xba\x91\x39\x0b\xae\x89\x81\x85\ \x33\xed\xfc\xea\x71\x37\x42\x80\xbf\x4b\x67\xd1\x6c\x07\x51\xc3\ \xe2\x52\xb7\x81\x05\xd4\x5f\xd6\x92\x94\x2e\x98\x61\xa7\x62\xb9\ \x9b\x42\xb7\x44\xdf\x80\xc9\x44\x9f\x4c\xbd\x5f\x63\xcb\xbe\x08\ \x1f\x75\xea\x69\x18\xb8\x06\x0d\x94\x8c\x1f\xa6\xc8\x34\xa1\xac\ \x58\xe6\xa5\x72\x0f\x2f\x95\x7b\x68\xe9\x31\x78\xbe\x6a\x80\xd7\ \x6a\x86\x00\x58\xb3\xc8\xc5\xda\xfb\x5c\xfc\xe0\x0f\x21\x1a\x3e\ \x61\x43\x08\x78\x7c\x81\xca\xc1\x0a\x1f\xdf\xde\x15\xa4\xf6\x62\ \x62\x84\x06\xa4\x64\x16\x64\x99\x6f\xd4\x46\x99\xfe\x54\x37\x3f\ \xdb\x17\xe6\xc4\x45\x0d\xd3\x02\x45\x12\x4c\x2b\x51\x78\x61\xb5\ \x07\x64\x98\x36\x51\x61\xfd\x43\x79\x3c\xb0\xad\x8f\x86\x56\x2d\ \xb9\xd6\x92\x60\xcf\xf1\x28\x4f\xbc\x1a\xe2\xcf\x3f\xf4\x62\x77\ \x88\x14\xb6\x00\x29\x5b\xa1\x70\x38\x05\x25\xe3\x25\x9c\xaa\xa0\ \x39\xa0\xf3\xe2\xa1\x01\x16\x6e\xed\xe1\xe6\x8d\x5d\x1c\x39\x1b\ \xc7\x30\xc1\x12\xc3\x62\x2b\xff\xaa\xca\xce\x23\x83\x84\x12\x66\ \x5a\xac\x77\xce\xc7\x69\xec\xd0\x79\x60\xb6\x63\x84\x3d\x6d\x1d\ \xb8\x73\x92\x8d\x5f\x2c\x75\x33\xc9\x27\xd3\x15\x36\x29\xf5\x4a\ \xb4\xf7\x1b\xfc\xfc\xcd\x08\x1f\x7c\xac\x11\x18\x32\xd9\x5f\x1f\ \xe3\x2b\x33\xec\x8c\xcf\x93\xf0\xba\x25\x6e\x2d\x55\xd8\x5f\x1f\ \xcb\x2a\xe8\xfa\x16\x8d\xdb\x26\x29\x1c\x38\x93\xa5\x0e\x2c\x9e\ \xe5\xe4\xd7\x8f\xb8\xf9\xf1\x5f\x43\xd4\x34\xa7\xe2\xf5\xb5\x99\ \x0e\xf6\xac\x1b\xc7\x4f\xab\xc2\x54\x9f\x8c\xd1\xd4\x9d\x52\xfc\ \xf4\x9b\x14\x82\x31\x0b\x9f\x47\xca\xaa\xa7\x09\x05\x12\x8d\x1d\ \x7a\xca\x47\x01\x09\x29\x45\x87\xaf\x40\x62\xfb\x72\x0f\x0f\xed\ \xea\xa3\xc6\x9f\x18\x41\xd5\xbf\x9a\xe3\x2c\x7d\xa5\x8f\xca\xc7\ \x0a\x28\xf6\x49\x9c\xee\xd4\x69\xec\xd4\xa9\x6b\xd1\x68\x09\x19\ \x1c\x3c\x1b\x63\xf5\x3c\x35\x63\x38\xf3\xf2\x04\xdf\xb8\xd3\xc9\ \xe1\xa6\x58\xca\x2e\x7d\x4a\x03\x8f\xdc\xed\xe4\x6f\x27\xa3\xb4\ \x0f\x18\x69\x41\x9a\x7a\x74\xde\x68\x88\xb2\xe2\x0b\x2a\xfd\x09\ \x93\xd9\x2f\x04\xf8\xf2\x6f\x7b\xb8\x32\x68\x50\x7d\x2e\x46\x71\ \x81\xcc\xda\x85\xae\x51\xeb\x9c\xaa\xe0\x4f\xdf\xf1\xb2\xf7\xfd\ \x21\xda\x9a\xeb\x28\x3d\xf0\x28\x18\xa1\xd1\x1a\xb8\xb5\x58\xa1\ \xf6\xb2\x96\x35\x8e\xa7\xae\x68\x2c\x9c\xea\x18\xe5\x63\x01\x2b\ \x5f\xeb\xe3\xf7\xcb\xbd\x2c\xbb\x4b\x65\xff\xe9\x18\xbd\x83\x26\ \x9f\x2d\x92\x79\x74\x96\x8d\xed\xdb\x77\x73\xf1\xef\x7b\xd9\xd1\ \x7f\x81\x2b\x92\x9d\x6d\xc6\x00\x88\xe2\x91\x1a\xe8\x8b\x99\x14\ \x8e\x11\xc7\x22\x8f\x44\x7f\xdc\x4c\xeb\x13\xd6\x2d\x56\xbf\xde\ \xcf\x1d\xa5\x36\xee\x9b\x66\x67\x2a\x3d\xd4\xef\xdc\x46\x63\xc3\ \x31\x9e\xea\xf5\x73\x8f\x39\x5c\x88\x9e\xcb\x2f\xe1\xff\x05\x70\ \x04\x03\x87\x9a\xe3\x54\x2e\x29\xe0\x95\xf7\x07\xb1\xac\x34\xa5\ \x5b\x82\x55\x77\xbb\x78\xf2\x1f\xa1\xcc\x2c\x0d\xf5\xd2\x5e\x5b\ \xcd\xa1\x97\xdf\xe4\xc1\x40\x07\x7b\x22\x1d\x14\xa5\xf3\xb3\xc9\ \xa3\xb3\xe0\x54\x40\xa3\xa9\x47\xe3\xc5\xc5\x1e\x9e\xf9\x67\x18\ \xd3\x1a\xb9\xf9\x8e\x87\x0b\x68\x0c\x68\x1c\x6b\x4b\xa4\x18\x88\ \x47\x70\x75\x1e\xe5\xa6\xd8\x11\x26\xbb\x2f\x31\x77\x7a\x1b\xe5\ \x1b\xba\xd8\x70\x8f\x97\xca\x48\x30\xe3\x35\x8c\x9a\x97\xfe\x36\ \x5c\x7f\x38\xcc\xb6\xfb\xdd\x1c\x5b\x57\x48\xd5\xb9\x18\x2d\x21\ \x83\x29\x5e\x99\x95\x77\xa8\x1c\xbd\x18\x66\xdd\xee\x13\x4c\x0c\ \xfd\x9b\x12\xf9\x02\xe1\xe6\x33\xcc\xfb\xfc\x20\x3f\x5a\xdf\xcb\ \x9c\x39\x26\xf2\x55\xac\x48\x56\xe6\x30\xc6\x2c\x33\x73\x47\xa4\ \x99\x1a\x9b\xaa\xce\x32\x41\x6b\xa3\x4c\x6d\x22\x1e\x6e\xe2\xc3\ \xce\xf3\xb4\xdf\xa2\x53\xec\x0d\x50\xf5\xcd\x00\xf3\xe6\xc6\x19\ \x37\x0e\x56\x7f\xdf\xc3\x96\xa7\xc3\x94\x95\xe5\xd6\x51\x69\x58\ \x9f\xd2\x40\xdf\x05\xf0\x6f\x80\x22\x0d\x5c\x11\x28\x1b\xa2\x7b\ \x46\x90\xee\x5b\x0c\x98\x02\x85\xcb\xbc\xfc\x65\x47\x7a\x3a\x15\ \x25\x73\xb7\x33\x56\x2f\x90\xd2\x40\xb8\x0d\x9e\x3e\x05\xf3\x33\ \x5c\xdb\x46\x7a\xb4\x78\xdc\xba\xbe\x67\x91\x48\xd5\x08\x29\x29\ \x88\x6c\xdd\x90\x2a\xa5\xb5\x5b\xe6\x75\x1e\xe0\x6a\x06\x54\xd5\ \xea\x43\x06\xea\x00\x35\xbd\x6f\x22\xac\xe3\xf7\x8f\xb6\x87\x82\ \x26\x75\x75\x10\x08\x8c\xfe\xd7\x1b\x4f\x50\x97\x61\x6f\xbf\x3e\ \x9c\x45\x2e\xa7\xe8\x15\x9b\x6a\x82\xcb\x76\xd7\x77\xbe\x1e\xb9\ \x54\xa3\x8c\x90\xf1\x55\xc3\xde\xd3\x8e\x4d\x1d\xfd\x70\x36\xfb\ \xbb\x90\x3c\x3e\x90\x6d\xa3\xd9\xe9\xee\x42\xe4\x15\xa7\xc5\x33\ \x2d\x03\xdb\xfc\x15\xda\x9a\x59\xee\xc7\x04\xc0\x93\xef\x05\x97\ \x37\x06\xcd\x55\x03\x09\xa3\xf4\x46\xbc\x8c\xf3\xed\x72\xc7\xed\ \x3e\xdb\xde\xdf\x7c\xc9\x5d\xf5\x3f\xf6\xa7\x5f\x62\x5c\x88\x56\ \xa2\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x05\xd2\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdb\x02\x0a\ \x01\x2f\x25\xf9\x8a\x73\x55\x00\x00\x05\x52\x49\x44\x41\x54\x58\ \xc3\xe5\x97\x7f\x4c\x53\x57\x14\xc7\xbf\x7d\xfd\x89\x50\xaa\xa5\ \x69\xe9\x90\xc2\x28\x20\x6a\xc0\x20\x38\xeb\xd8\xa2\x51\xb3\x39\ \x87\x1b\xdb\x02\xc6\xe1\x14\x5d\x34\x62\x94\x45\xc5\x88\x18\xe3\ \x32\x21\x32\xc7\xb2\x4d\x32\x07\x75\x4e\x9d\xa1\x89\x82\x92\x2d\ \x38\xeb\xd0\xa0\xa2\x56\x70\x2a\x01\x86\x93\x46\xa4\xc3\x1f\xa4\ \x2d\xb4\x42\x79\x94\x96\xf6\xee\x8f\x0d\xe4\x09\x85\x52\xcd\xf6\ \xc7\x4e\x72\x93\xd7\xcf\xbd\x7d\xef\xbc\xef\x39\xe7\xbe\x73\x81\ \xff\xbb\xb1\x46\x83\x7e\x7e\x7e\x49\x42\xa1\x50\xc5\x62\xb1\x5c\ \x83\x6c\x60\x60\xc0\xdd\xd9\xd9\x69\xf7\x70\x1f\xcb\xb0\xfb\x55\ \x00\x70\x7a\xeb\x00\x67\x34\x28\x91\x48\xb2\x32\x32\x32\xd2\x62\ \x63\x63\x27\xf4\x36\x85\x85\x85\x6e\xa3\xd1\xd8\x63\x34\x1a\x17\ \xd1\x34\x7d\xd3\x67\x07\xb8\x5c\x6e\x4f\x6a\x6a\x2a\x26\xea\x40\ \x63\x63\x23\x45\xd3\xb4\x48\xa7\xd3\x5d\x37\x99\x4c\xc7\xf5\x7a\ \xfd\xc7\x00\xc8\x58\xff\xa1\x5e\x64\x3c\x79\x3c\x1e\xfc\xfd\xfd\ \x91\x9c\x9c\xcc\x89\x8f\x8f\xcf\x88\x88\x88\x78\x0c\x20\x7c\xc2\ \x0a\x0c\xb7\x7b\xf7\xee\xc1\x6a\xb5\x32\x98\xc3\xe1\x00\x8f\xc7\ \x63\xb0\xfe\xfe\x7e\xb4\xb7\xb7\xc3\x6c\x36\x43\x20\x10\xc0\xe9\ \x74\xb2\xa4\x52\xa9\xcc\x66\xb3\xdd\xa5\x69\xba\xc0\x66\xb3\xed\ \xf1\x49\x81\xb2\xb2\xb2\x7f\x54\x7c\x3a\x8a\x8a\x8a\x46\x30\xb5\ \x5a\x8d\xf5\xeb\xd7\x21\x37\x77\x27\xb6\x6e\xdd\x82\x5d\xbb\x72\ \x91\x98\x98\x08\x83\xc1\xc0\x4b\x4f\x4f\xdf\x24\x93\xc9\x4e\x78\ \xad\x80\xdb\xed\xe6\x0e\x5e\x2b\x14\x0a\x24\x24\x24\x30\xe6\x43\ \x42\x42\x46\x30\xb9\x5c\x3e\x82\xd5\xd5\xd5\x41\x20\x10\xa0\xb8\ \xb8\x58\x5c\x59\x59\x19\xeb\xb5\x02\x2e\x97\x4b\xf0\xa2\xeb\x9d\ \xcb\xe5\xda\xbd\x56\x80\xcf\xe7\x0f\x05\x58\x7b\xea\x7b\xdc\xd0\ \x16\x33\xe6\x1b\x9a\xf5\xd8\xb2\xaa\x96\xc9\x9a\x5a\xb0\xe5\xe1\ \x55\x06\x6b\xb9\xff\x18\x99\x99\x1b\xe1\x53\x12\x06\x04\x04\x00\ \x00\xe6\x45\xf3\x90\x39\xad\x9a\x31\x97\x43\x07\xa3\x60\x61\x0d\ \x83\x7d\xd2\x35\x19\x5f\x3d\xc3\x34\x8d\xa1\xe3\x2a\xe3\x31\x09\ \xd9\x6c\xf6\xbf\xb2\x15\x53\xf8\x8f\x6d\xdc\x7d\xa0\xfe\xbe\x1d\ \xfb\xac\xaf\x30\xd8\x9d\x47\x6d\xd8\x57\xcb\x64\x2d\xc6\x56\x6c\ \xaf\x9e\xcb\x60\x7a\x43\x27\x3e\xf4\xc5\xab\xc8\xc8\xc8\x0a\x83\ \xc1\x40\x08\x21\xa4\xb4\xb4\x94\x10\xe2\x66\x8c\xec\xec\xec\x11\ \x2c\x27\x27\x67\x04\x3b\x78\xf0\x5b\x32\x68\xe1\xe1\xe1\xb7\x7c\ \x52\xc0\x5b\xa3\x69\x1a\x05\x7b\x73\xa1\xbb\x78\x16\x4e\x7b\x37\ \x28\x16\x60\xb6\xd2\xd0\x37\x5e\xc3\x47\xeb\xb6\xfa\x1e\x02\x9d\ \xee\x1a\x4c\x26\x23\x33\x2c\xf5\xf5\xc8\xcb\xcb\x1b\xfa\xdd\x74\ \xbb\x16\x2d\xb7\xcf\x23\x2f\xc5\x81\xec\x74\x02\xce\xb0\xcc\xfa\ \xfd\x61\x29\x0e\xe4\xfe\x0a\x42\x77\x2b\x01\x08\x01\xf4\x4c\xc8\ \x81\x19\x33\x66\x62\xf9\xf2\x34\x06\x6b\x6b\x6b\xc3\xc6\x8d\x7f\ \xd7\x77\xd1\x97\x7b\x11\xee\xbe\x0a\xcd\xee\x7e\xf4\xd8\x81\xe2\ \x9a\x49\x68\xe8\x10\xa2\xd7\x41\x21\x6a\x8a\x05\xab\xe7\xda\x51\ \xb2\xdc\x84\x4b\xb3\x20\xcc\x38\x0c\x5d\x9b\x19\x49\x00\x9e\x78\ \x5d\x05\x22\x91\x08\x62\xb1\x98\x31\x02\x02\x84\x10\x8b\xc5\xa8\ \xbf\xfd\x1b\xba\x1a\x4a\x51\xf0\xae\x15\xa7\x6f\xb1\xf1\xfe\x8f\ \xd3\x20\x7b\xeb\x10\x76\xab\xeb\x70\xe0\x64\x03\x9e\x84\x6e\xc0\ \xf6\x8b\x49\xc8\x3f\x37\x19\xf3\x63\xc0\xfa\x39\x0b\xd3\xa3\x64\ \x28\xf7\x66\x2b\xf6\x2a\x37\xf6\xed\xce\x42\x7e\xb2\x19\x17\xfe\ \xe0\x60\xff\x25\x05\xb4\x97\x1b\x90\x9a\xb6\x02\xa1\xa1\xa1\x08\ \x0a\x0a\x42\x74\x74\x34\xca\xcf\x5c\x81\x20\x6e\x33\xf2\x2b\x29\ \x57\x6c\x28\xa8\x95\xaf\x62\x76\xa0\x3f\xde\x1c\xb3\x25\x53\x28\ \x14\x55\x35\x35\x35\x8b\x15\x0a\x05\x32\x33\x33\x11\x1c\x1c\x3c\ \x34\x77\x42\x73\x14\xc4\x6e\x01\xc5\xe1\x21\x71\x6a\x0f\x8e\xad\ \xb1\x83\xbd\x16\x88\x9c\x1a\x88\x8e\x2e\x07\x56\xae\x5e\x0b\xb9\ \x5c\x0e\x00\x68\x6e\x6e\x86\x46\xa3\x01\x00\x4c\x9f\xca\xb7\x5d\ \xde\xe1\x08\xe0\x50\x80\x2a\x0f\x97\x5b\x3a\x30\xdf\xe3\x9b\x29\ \x95\xca\x6a\x4f\x65\x78\xe1\xbc\x96\x2c\x89\x9f\x44\x06\x0e\x83\ \x90\x23\x4f\xc7\xe9\x2c\x36\x49\x7b\x67\x01\x19\x18\x70\x8e\x5a\ \x86\x32\xa9\xa4\xf5\xbb\x55\xa0\xc9\x11\x90\x59\x0a\xb4\x8e\x9b\ \x03\x83\xdf\x82\x67\x6d\xe1\xa2\x37\x20\x08\x79\x0d\x59\xe5\x41\ \x43\xac\xb6\x95\xc2\xa7\x67\x25\x38\x5e\xa6\xf5\xb8\x85\x53\x6c\ \x6e\xff\x9d\xc7\xb0\x01\x00\x8f\x0d\xfe\xa0\xfa\x3e\x7d\x0b\x22\ \x63\xe2\x10\xaa\x5a\x87\x82\x2a\x11\x9a\x1e\xb2\x90\x5b\x15\x85\ \x79\x0b\x53\x46\x74\x49\xc3\x3b\x28\x97\xcb\xc5\x91\x8b\x20\x00\ \x00\xa7\x0b\x8e\xc1\x5e\x71\xdc\x64\xeb\xeb\xa3\xa1\x56\x1f\x7a\ \x86\xf5\x41\x1c\x15\x87\xf2\x0b\x91\xd8\xa9\xb9\x89\x6d\xdb\x92\ \xe1\x74\x3a\xa1\x56\xab\x99\xbd\xba\xc5\x3a\xb4\x5e\xc8\xb1\x05\ \xbd\x97\x00\xe1\x93\x3e\x80\x76\xe0\xc1\x98\x0f\x55\x2a\x95\xd5\ \x56\xab\x95\x8c\x65\x29\xcb\x96\x12\xe5\x4b\x01\x24\xf5\x75\x29\ \x59\x10\x2b\x22\xdf\x14\xe6\x7b\x5c\x7b\x4e\x7b\x86\x7c\x30\x87\ \x72\x92\x23\x20\xfb\xd3\x60\x0d\x12\x22\xe5\xb9\x1d\x68\x6f\x6f\ \x27\x4b\xe6\x86\x10\xe7\x61\x10\xf7\x0f\x20\x9b\xde\x0e\x22\xdb\ \x36\xaf\x25\x46\xa3\x71\x68\x4d\x5f\x5f\x1f\xf9\xfa\x8b\x7c\xb2\ \x4c\x25\x25\xbd\x25\x20\xfa\xcf\x41\x62\xe4\xb8\x32\xee\xc9\x28\ \x2c\x2c\x4c\x57\x51\x51\xa1\x12\x89\x44\x63\x3a\x5a\x7d\xfe\x2c\ \x7e\x39\xb6\x07\x9a\x35\x9d\xe0\x73\x00\x6d\x13\x1b\x25\xd7\x25\ \xe8\x1d\xf0\x07\x8b\xcd\x06\xdb\x65\x43\xda\x2c\x0b\x56\xa9\xec\ \x78\x64\x05\x16\xef\xc7\x9f\x77\x3b\x90\x04\x3c\x0d\xc1\xa8\x0e\ \x48\xa5\xd2\xcf\x02\x03\x03\xe7\x50\x14\xe5\x1a\x2f\x47\x1c\x74\ \xb7\x54\xca\x37\xc5\x9d\xd8\xe0\xe2\x87\x4b\x46\x5f\x73\xea\x06\ \x8b\x64\x9f\x64\x59\xda\xcc\x6e\x15\x00\xfd\xb8\x0a\xf8\x60\x31\ \xe1\x12\x1c\x9d\x1d\x86\xb0\x15\x2a\x48\x5f\x96\x80\xb2\xf5\x03\ \x37\xee\xa3\xf7\xf8\x35\x58\xba\x6c\xf8\xe9\x81\x05\x3b\x00\xf4\ \x7a\x75\x38\x7d\x0e\x8b\x98\xe2\x87\xa5\x53\x84\x98\xd9\xef\x44\ \x67\x47\x37\x6a\x5d\x2e\x54\x01\xf0\x74\xa8\xc5\x5f\xdd\x0f\xd7\ \x91\x5a\x5a\xf8\xaf\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\ \x82\ \x00\x00\x09\x4c\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdb\x02\x07\ \x16\x3b\x14\x6d\xf9\xc9\x12\x00\x00\x08\xcc\x49\x44\x41\x54\x58\ \xc3\xc5\x97\x6b\x8c\x55\xd5\x15\xc7\x7f\xe7\xdc\x7b\xcf\xbd\x73\ \xe7\x3d\xc3\xc0\xcc\x68\x70\x14\x10\x86\x01\x07\x04\x35\x82\x80\ \x8f\xda\x62\x55\xb0\x18\x69\x6d\xab\x6d\x93\xb6\x96\xb6\xa6\xf5\ \x83\xb5\xa4\x1f\xb4\xa6\xa6\x8f\xb4\xb6\x89\x36\x4d\x34\x6a\x6d\ \x55\x88\x89\x2f\x10\x5f\x85\x68\x78\x38\x14\x79\x88\x32\x0c\x0f\ \x99\x81\x61\x66\xee\xbd\x33\xf7\xfd\x38\xe7\x9e\xc7\xde\xbb\x1f\ \xee\x99\x91\x91\x4a\x6c\x6b\xd2\x9d\xac\x9c\x2f\x67\xef\xff\x7f\ \xad\xf5\xdf\x6b\xad\x0d\xff\xe7\xa5\xfd\xa7\x1b\x94\x52\x41\xe0\ \xca\x58\x2c\x77\x55\x3e\x6f\x76\x5a\x96\xdb\x18\x89\x04\x93\x53\ \xa6\xd4\x7c\x30\x65\x4a\xdd\x6e\x60\x8f\xa6\x69\xe2\x73\x27\x30\ \x38\x98\xfa\x6a\xdf\xe9\xdc\x2f\x62\xba\xde\xe5\x36\x86\x75\x91\ \x17\x08\xa9\xe1\x58\x82\xa1\x5d\x19\x9a\x66\x46\xa8\x9e\x1a\x22\ \x92\x29\x38\x1d\x35\xa1\xed\x97\x2d\x3e\xef\xf7\xcd\xcd\xf5\x6f\ \xfe\xcf\x04\x86\x86\x92\xd7\xee\xfa\x28\xfb\x7c\xfd\x8a\x19\xcd\ \x4b\x80\x51\xe0\xad\x77\xc7\x48\xf5\x04\x28\x25\x15\xe5\x32\x58\ \x96\xc4\x34\x05\xad\x97\x79\xdc\x7f\xf7\xf9\xc4\x81\xbf\xfd\xfd\ \x20\xb3\x34\x7b\xef\x9a\x35\x0b\xef\xaa\xae\x36\xf6\x7f\xda\xf9\ \xfa\x39\x42\xad\xbf\xf0\x46\xdf\x2b\x5b\xbd\xc0\xb6\x74\xa0\xaa\ \x59\x07\xe2\xc0\xb6\x3d\x59\x6e\x5c\xd2\x42\xd3\xfc\x08\x91\x48\ \xbd\x6f\x0d\x44\x22\x4d\xa4\x8f\x36\xf1\xdc\x91\x18\xcd\xc0\x5d\ \x77\x74\x73\x98\xc8\xe2\xf5\x7f\xd8\xb9\x6f\xf3\xe6\xf7\x1f\x54\ \x4a\x69\x9f\x39\x02\x4a\xa9\xe8\xd3\x6f\xf4\xf5\xce\x58\xd9\xd9\ \x71\x68\xdf\x69\x74\x37\x4c\xf3\xdc\xa9\x24\xb7\x5b\xb4\x7d\xb1\ \x8a\x55\x06\x1c\x07\x9e\x7f\x08\x3c\x0f\x6c\x25\x71\x95\x64\xc6\ \xad\x19\xbe\x79\x49\x0b\x02\x28\x03\x25\xff\xfb\x8f\xbd\x47\x09\ \x1f\x18\xde\xf4\x83\xef\x5d\xbb\x56\xd3\x34\xfb\x9c\x11\x50\x4a\ \xe9\x7f\xd9\x74\xe0\xc4\xb2\x95\x9d\x1d\xb3\x81\x48\x73\x0d\xda\ \x91\x06\xb2\xa7\x92\xac\xbd\xa9\x8a\x9b\x0d\xd8\x03\x6c\x79\x4c\ \x10\x6d\x17\x44\xdb\x04\x46\x50\xa3\x76\xaa\x22\xd7\x1f\x46\x01\ \x12\xf0\x00\x1b\xb0\x80\xee\xc5\xb3\x39\x11\xc9\xae\x7a\xe4\xd1\ \x2d\xcf\x7f\x32\x12\x81\x4f\x12\x68\x5b\xb4\x7a\xd7\xd5\xab\x16\ \x76\x0e\x03\x79\x20\xb5\x39\x04\x1d\x26\x04\xa1\x6f\xc0\xe3\x40\ \xbf\x60\xf0\xf5\x10\xb2\xac\xe3\x15\x75\xbc\x92\x8e\x12\x1a\x55\ \xd3\x1d\x9a\xba\x4c\xe6\xb5\x54\xe3\x9c\x11\x01\x13\x28\x4a\xa8\ \x69\x6c\xa3\x67\xff\x3b\xb3\x63\xbd\xa3\x91\x2d\xaf\x6e\xd8\xfa\ \x6f\x53\xb0\x69\xcb\xfe\xdb\x4f\x96\x8c\xe7\xa4\xac\x21\xd0\x10\ \xa0\x2a\xd9\x82\x21\x0d\x02\x01\x0d\xa5\xc0\xad\x75\x90\x55\x0a\ \xe7\x44\x18\xd7\x85\xda\x6b\x8a\xdc\x3a\xaf\x86\x17\x4f\xe6\x08\ \x57\x45\x58\x35\x2d\x8c\xeb\x83\x16\x80\x8c\xef\x44\x2e\x0b\x63\ \x83\xa7\x18\xf8\x60\x3f\x87\x5f\xeb\xe5\xa1\xfb\xd6\x5e\xb1\x60\ \xc1\xec\x3d\x93\x08\x28\xa5\x02\x0f\xff\xb1\x27\xaf\x31\x3d\x1a\ \x0a\x35\x10\x0c\x1b\x18\x81\x20\xa1\x90\x46\x28\x54\xf9\xc7\x75\ \x7d\x13\x60\x2c\xc9\x73\x4b\x57\xdd\x44\x0e\xa3\xbe\xd7\xb6\x4f\ \x20\x07\xa4\x80\xac\x09\xb9\xb1\x1c\xf1\xfe\xe3\x64\x47\x13\xe4\ \xc6\x12\x04\x3e\xca\x1d\x7f\xe4\x4f\xf7\xcc\xd6\x34\x4d\x4d\x68\ \xe0\x99\xe7\xde\xbb\x47\xa9\xc6\xa8\x94\x51\xa4\x34\x90\x6e\x10\ \x21\x34\x84\xa8\x80\x7a\x1e\xc8\x80\x44\xbb\x32\x03\x86\xe4\xba\ \xae\x3a\x7a\x14\x38\x80\x41\xe5\x3b\x9e\xf7\x92\x1f\x81\x9c\x05\ \xb9\xb1\x2c\x85\x74\x92\x7c\x2a\x49\x21\x95\x04\xa0\x2f\x73\x78\ \xd6\xa6\x4d\xdb\x6f\x9e\x24\xc2\xc1\x93\x85\x9f\x96\xad\x28\x42\ \x18\x08\xa1\x4f\x02\x1f\x37\x6f\x56\x9e\xce\xce\x46\xf4\x5a\x8f\ \x28\x10\x3b\x94\xa6\xda\xdf\x3f\x9e\xf7\xa2\xef\x7d\x4e\x41\x3a\ \x9e\x26\x9b\x88\x93\x1a\x1e\x22\x13\x1f\xc1\xb1\xcb\x78\xae\xcb\ \xf4\xb9\xf3\xd9\xba\xf5\xbd\x7b\x26\x08\x28\xa5\x6a\xa5\xd6\x78\ \x9e\x10\x61\x84\x08\xe2\x79\xfa\x24\xcf\xc7\x09\xc8\x84\xc1\x54\ \xe0\xce\x35\x06\xb5\xc0\x37\xe6\x37\xa1\xce\x00\xcf\xfb\xe0\x05\ \x20\x3b\xe6\x50\x48\x25\xc9\x24\x62\xa4\x63\xc3\x78\xae\x3b\xa1\ \xb5\xa0\x11\xa6\x7f\x68\xe4\x6a\xa5\x54\x24\x08\xf0\xe8\xa3\xdb\ \x56\x3b\xd6\x34\x20\x84\xa6\xe9\x68\x9a\xe6\xeb\xa2\x62\xba\x0e\ \x7a\x47\x1e\xbd\xd6\xa3\x8d\x28\x12\x10\xbe\x80\xca\xc0\x18\xa0\ \xfc\xd0\xf7\xf6\xa7\xb0\x2d\x13\xe1\xba\x24\x87\x06\xc9\xc4\x63\ \xd8\x96\x79\x56\xad\xc9\x14\x25\x3b\x76\xec\x9b\x1b\x04\x88\x25\ \x8a\xd7\xe7\xb3\xad\x44\x22\x81\x09\x5d\x8e\x83\x4b\x09\x81\xa0\ \x62\xd5\x4d\x75\x54\x03\x4f\xbe\x93\x42\x13\x30\x7d\x45\x33\x33\ \x83\x50\x0b\xbc\xb4\x61\x90\x07\xd7\x2d\x27\xd2\xb2\x00\x2d\x60\ \x54\xe8\x28\x89\x92\x1e\x4a\x09\xbc\x62\x9c\x96\x36\x83\xeb\xef\ \xfc\xd6\x04\x81\xea\xf3\xcb\xbc\xf5\x56\xcf\xb2\x20\x80\x15\x62\ \xbe\x65\xe9\x3e\xb8\x36\x09\x5c\x4a\x10\x28\x0e\x95\x35\x4e\xed\ \x19\x41\xc4\x6a\x91\x42\xe3\xa3\x1d\xa7\x39\xa6\xca\x9c\xbf\xe0\ \x22\xbe\x74\xfb\x74\x7e\xf9\xc3\x10\x0b\x7f\xf4\x32\x01\x03\x94\ \x07\xd2\x03\xe1\x80\x70\xa1\x70\x7a\x80\xe4\x8e\xb5\x15\xad\x58\ \x26\xfd\x07\x0e\xd3\xd8\xd6\xc0\xd0\x50\x62\x46\x10\xc0\x15\x2a\ \x58\x2e\x33\xe1\xb9\x94\x10\x0e\x57\x4c\x85\x3c\xe6\x7c\x37\xc8\ \x15\x11\xb8\x7c\x79\x3b\x12\x78\xb5\x6f\x84\xc4\xcb\xed\x48\x01\ \x87\xde\xcf\xb2\x4f\x66\x26\xaa\x8a\xa6\xc1\xa4\x5a\x27\x41\x09\ \xc7\x4f\x12\x0c\x1f\x3b\x42\xfc\xe0\x22\x8a\xa3\x47\x09\x34\xe7\ \xab\x83\x00\x55\xd3\xc2\xb5\xc3\x1f\xba\x48\x29\x2b\x1e\x8b\x8a\ \xf8\xf4\xc6\x02\xab\xef\xad\xa5\xc1\x2f\xa9\xd2\xb7\x65\x9d\xed\ \x6c\x4a\xec\xa5\x34\x56\xc6\x76\x52\x14\x87\x0d\x9f\x7d\xc5\x01\ \x00\x25\x41\x0a\x90\x2e\x48\xd7\xc4\xb3\x2b\x1e\x96\x52\x51\x40\ \x23\x10\x10\x18\x46\x55\x3e\x08\xa0\x69\x72\x94\xaa\x72\x87\x65\ \x0a\xa4\x94\x08\xa9\xe1\xba\x3a\xf3\x57\x97\x88\x50\x4b\xf9\x0c\ \x70\x09\xb8\xc0\xb2\xab\x17\x57\xd4\x9e\xf4\x48\x8d\x0c\xc1\xaf\ \x15\x4a\x54\x80\x95\x0f\x2c\x6c\xf0\xca\x12\x61\x67\x29\xa5\x23\ \x64\x13\x31\xa4\x17\x04\x24\xe1\xba\x32\xb5\xb5\xcd\x7d\x3a\x80\ \xe6\xc8\x27\x5b\xe6\x58\x98\xa6\x83\x69\x4a\xcc\x92\x46\xd9\xf1\ \xe8\xba\xb8\x95\xb2\xaf\xf4\xf2\x19\xd7\xcd\x1c\xbf\x72\x69\x49\ \x7a\x64\x78\xa2\xc0\x48\xe1\x83\x0b\x10\xbe\x06\x3c\x3b\x8b\x70\ \x0a\xa0\xe0\xe8\xdb\x75\x84\xeb\x32\x80\x87\x1d\x9f\xc2\x0d\x37\ \x5c\xb5\x55\x07\xf8\xcd\x4f\x6e\x7e\x62\xe6\x8a\x3a\x4c\xd3\xa4\ \x54\xf2\x28\x16\x15\xb6\xb4\x91\x67\x74\xb4\xa2\x0f\x9a\x07\x32\ \x65\xc8\x8e\xb9\x64\xe2\x31\xb2\xa3\x71\xc6\x4e\x9f\x02\x25\x27\ \x84\xe7\x95\x2b\xde\x0b\xab\x88\x67\xa5\xf0\xec\x0c\x20\xb1\x32\ \xad\xc4\x0e\x2c\x01\x1c\x22\xa1\x3c\x6b\xd6\x5c\x77\xd2\x4f\x81\ \xe6\xad\xdf\xf0\x9a\x6c\x5f\x5c\xd2\x07\x77\x37\xe0\xba\x06\xae\ \x1b\x64\xf3\x86\x37\x58\x79\xfb\x4a\x5c\xc0\x95\xe0\x39\x60\x5b\ \x8a\xaf\xb5\xd6\x13\x8c\x34\x9e\xd1\xd4\x03\x08\x27\x8f\xb0\x41\ \x3a\x7e\xe8\xad\x12\x4e\x29\x86\x5b\x8a\x21\xdd\x12\xa6\x79\x84\ \xfe\xc1\x1f\x57\xb4\xaa\xe9\x0c\x0c\x69\xe8\x81\xc7\x45\x70\xfc\ \x0c\x6b\xa4\xf0\xdb\x45\xb7\x4c\x5b\xdf\xb7\xad\x80\x61\x80\xeb\ \x2a\xfe\xf9\x44\x17\x35\x4d\xbb\x98\xb7\x6c\x69\x05\xdc\x34\x31\ \xf3\x39\x2e\xbd\xfe\x46\x46\xd2\xb3\xb8\xe0\x0b\x0f\x7e\xac\x74\ \x05\xd2\x06\xe1\x7a\x08\x3b\x83\x6b\x8e\xe1\x16\x63\x38\xc5\x61\ \xa4\xb0\x69\xbf\x62\xfd\xe4\x42\x74\xec\x05\x4c\xbb\x74\xdf\xa4\ \x76\x7c\xc7\xcf\x1e\x2b\xee\x7e\xa9\xb3\x3a\x10\x98\x46\x28\xa4\ \x11\x0c\x7a\x04\x83\x36\x91\xda\x12\xd1\xa6\x2c\xf5\x17\x0c\x31\ \xef\xba\x4e\x40\xe3\x89\x9f\xaf\x47\xb5\xac\x65\xda\xc2\xbb\x51\ \xd2\x41\x09\x17\x25\x1d\x84\x9d\xc7\x35\x13\x78\x56\x1a\xb7\x14\ \xc7\x2d\xc5\x51\xd2\x9d\x04\x9e\x1b\x78\x13\x33\x71\xf0\x71\x29\ \x8a\xdf\x9f\x34\x90\x2c\x5d\xfe\x95\x5d\xf9\xd1\xfc\xb7\x4b\x25\ \xf0\x3c\x1b\xd7\xb5\xf1\x3c\x0b\xa7\x6c\x53\xca\x78\x64\x4e\x86\ \x48\x8f\xf6\xd2\xd0\x1e\xa6\xa3\x6b\x0e\xbb\x9e\xfd\x15\x7a\xa8\ \x9e\x50\x4d\x3b\xc2\xc9\xe1\x59\x19\xdc\x52\x6c\x02\xd8\x2d\x8e\ \x54\xae\xc5\x19\xab\x30\xb4\x9d\x72\xea\xfd\xdd\xc2\x29\xdc\x72\ \xd6\x44\xb4\x77\xe7\x2b\xa7\xba\xbb\x2f\x95\xb6\x2d\xae\x71\x1c\ \x17\xf0\x90\xb2\x8c\xe7\x15\x70\x5d\x0b\xd7\x55\xd8\x26\xb4\x5c\ \x54\x42\x0a\x49\xf7\xf2\xe5\xec\x78\xfa\x7e\x8c\xfa\x0e\x02\x46\ \xcd\x04\xb0\x67\x8d\xe1\x59\xc9\xb3\xea\xbf\x39\x7a\x80\x72\xbc\ \x27\xe9\x58\xd9\xd9\x9f\x3a\x92\x1d\x3f\xfe\xf6\xf6\xb9\x73\x67\ \x5d\xea\xba\xee\x6c\xcf\x1b\x1f\x2b\x3f\x1e\xa0\x5c\x2b\x8c\x65\ \xee\xa5\xe5\x82\x69\xa0\x69\x5c\x72\xf5\x72\x76\x3c\xb9\x9e\x60\ \xf5\x54\xa4\x1f\x7e\xe9\x95\xcf\x02\x2f\x67\x8e\x91\xed\x7f\x1d\ \xcf\xce\x55\x9f\x73\x26\x04\x18\x18\xe8\xd9\xd8\xdd\xdd\x75\xa1\ \x52\x72\x81\x6d\xcb\x89\x1e\x31\xde\xa8\xaa\x9a\xe2\x4c\xbd\xb0\ \xc5\x57\xb4\x46\xd7\xd2\xa5\xf4\x6c\xfc\x1d\xe1\x86\x8b\xd0\x03\ \x91\xb3\xce\xb3\xf3\x83\x64\x8e\xbf\x88\x74\x0b\x67\x0d\xc1\x81\ \x4f\x7b\x17\x9c\x38\xb1\xfb\xe5\x45\x8b\x16\x0f\x85\xc3\xf6\x2a\ \xd3\x14\x28\x35\xfe\xda\x52\x84\xeb\x72\xb4\xce\xfc\xf8\x1a\x06\ \x82\x41\xe6\x5c\xbe\x98\x3d\x2f\xfc\x99\x68\xcb\x7c\xbf\x23\x56\ \x96\x67\x25\x49\x1f\xd9\x88\x74\x72\x51\xbf\x88\x7e\x36\x02\x00\ \xc7\x8e\xbd\x7b\x60\xdd\xba\xef\x3c\x9c\xcd\x0e\x5c\x52\x55\xc5\ \xc5\x8e\x63\x23\x84\x43\x39\xdb\x80\x32\x0e\xd2\xd8\xda\x3e\xd1\ \xc1\x4e\xec\xed\x45\x15\x96\x90\x38\xf5\x0c\xd1\xa9\xdd\x68\x5a\ \xa5\x36\x24\x7b\xff\x8a\xb0\x33\x0d\x7e\x2d\xfb\xef\xdf\x86\x0f\ \x3c\xf0\x70\xd3\x87\x1f\x26\xee\x4d\xa7\xf3\xeb\x74\x7d\x4a\xbd\ \xe3\x84\x91\x75\x09\x94\xd4\x50\x66\x0d\x01\x51\x85\x61\x98\x64\ \xb3\x87\x93\xc7\x47\xd3\x53\x66\xac\x7e\x89\xa3\x1b\x57\x60\xa5\ \x7a\x5b\x81\xc4\xe7\xf6\x3a\x1e\x7f\x21\x3f\xf5\xd4\x2b\x6d\x3b\ \x77\x1e\x9c\x67\x18\xd1\x88\xe3\x94\x0a\x2b\x57\x5e\x76\xe8\xb6\ \xdb\xbe\x3c\xa6\x69\x9a\x08\x18\xd5\x5f\x57\x8a\x67\xa5\x5b\x9a\ \x0f\x1c\x3a\xd7\x59\xff\x02\x88\x0e\xe8\x4f\xfe\xf2\x2b\xcc\x00\ \x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x0c\xa8\ \x2f\ \x2a\x0a\x20\x2a\x20\x43\x6f\x70\x79\x72\x69\x67\x68\x74\x20\x28\ \x43\x29\x20\x32\x30\x31\x31\x2c\x20\x32\x30\x31\x32\x20\x46\x65\ \x64\x65\x72\x69\x63\x6f\x20\x42\x72\x65\x67\x61\x0a\x20\x2a\x20\ \x0a\x20\x2a\x20\x54\x68\x69\x73\x20\x70\x72\x6f\x67\x72\x61\x6d\ \x20\x69\x73\x20\x66\x72\x65\x65\x20\x73\x6f\x66\x74\x77\x61\x72\ \x65\x3b\x20\x79\x6f\x75\x20\x63\x61\x6e\x20\x72\x65\x64\x69\x73\ \x74\x72\x69\x62\x75\x74\x65\x20\x69\x74\x20\x61\x6e\x64\x2f\x6f\ \x72\x0a\x20\x2a\x20\x6d\x6f\x64\x69\x66\x79\x20\x69\x74\x20\x75\ \x6e\x64\x65\x72\x20\x74\x68\x65\x20\x74\x65\x72\x6d\x73\x20\x6f\ \x66\x20\x74\x68\x65\x20\x47\x4e\x55\x20\x47\x65\x6e\x65\x72\x61\ \x6c\x20\x50\x75\x62\x6c\x69\x63\x20\x4c\x69\x63\x65\x6e\x73\x65\ \x0a\x20\x2a\x20\x61\x73\x20\x70\x75\x62\x6c\x69\x73\x68\x65\x64\ \x20\x62\x79\x20\x74\x68\x65\x20\x46\x72\x65\x65\x20\x53\x6f\x66\ \x74\x77\x61\x72\x65\x20\x46\x6f\x75\x6e\x64\x61\x74\x69\x6f\x6e\ \x3b\x20\x65\x69\x74\x68\x65\x72\x20\x76\x65\x72\x73\x69\x6f\x6e\ \x20\x33\x0a\x20\x2a\x20\x6f\x66\x20\x74\x68\x65\x20\x4c\x69\x63\ \x65\x6e\x73\x65\x2c\x20\x6f\x72\x20\x28\x61\x74\x20\x79\x6f\x75\ \x72\x20\x6f\x70\x74\x69\x6f\x6e\x29\x20\x61\x6e\x79\x20\x6c\x61\ \x74\x65\x72\x20\x76\x65\x72\x73\x69\x6f\x6e\x2e\x0a\x20\x2a\x20\ \x0a\x20\x2a\x20\x54\x68\x69\x73\x20\x70\x72\x6f\x67\x72\x61\x6d\ \x20\x69\x73\x20\x64\x69\x73\x74\x72\x69\x62\x75\x74\x65\x64\x20\ \x69\x6e\x20\x74\x68\x65\x20\x68\x6f\x70\x65\x20\x74\x68\x61\x74\ \x20\x69\x74\x20\x77\x69\x6c\x6c\x20\x62\x65\x20\x75\x73\x65\x66\ \x75\x6c\x2c\x0a\x20\x2a\x20\x62\x75\x74\x20\x57\x49\x54\x48\x4f\ \x55\x54\x20\x41\x4e\x59\x20\x57\x41\x52\x52\x41\x4e\x54\x59\x3b\ \x20\x77\x69\x74\x68\x6f\x75\x74\x20\x65\x76\x65\x6e\x20\x74\x68\ \x65\x20\x69\x6d\x70\x6c\x69\x65\x64\x20\x77\x61\x72\x72\x61\x6e\ \x74\x79\x20\x6f\x66\x0a\x20\x2a\x20\x4d\x45\x52\x43\x48\x41\x4e\ \x54\x41\x42\x49\x4c\x49\x54\x59\x20\x6f\x72\x20\x46\x49\x54\x4e\ \x45\x53\x53\x20\x46\x4f\x52\x20\x41\x20\x50\x41\x52\x54\x49\x43\ \x55\x4c\x41\x52\x20\x50\x55\x52\x50\x4f\x53\x45\x2e\x20\x20\x53\ \x65\x65\x20\x74\x68\x65\x0a\x20\x2a\x20\x47\x4e\x55\x20\x47\x65\ \x6e\x65\x72\x61\x6c\x20\x50\x75\x62\x6c\x69\x63\x20\x4c\x69\x63\ \x65\x6e\x73\x65\x20\x66\x6f\x72\x20\x6d\x6f\x72\x65\x20\x64\x65\ \x74\x61\x69\x6c\x73\x2e\x0a\x20\x2a\x20\x0a\x20\x2a\x2f\x0a\x0a\ \x76\x61\x72\x20\x6d\x61\x70\x3b\x0a\x76\x61\x72\x20\x66\x65\x61\ \x74\x75\x72\x65\x4c\x61\x74\x4c\x6f\x6e\x3b\x0a\x0a\x66\x75\x6e\ \x63\x74\x69\x6f\x6e\x20\x69\x6e\x69\x74\x28\x29\x20\x7b\x0a\x20\ \x20\x20\x20\x6d\x61\x70\x20\x3d\x20\x6e\x65\x77\x20\x4f\x70\x65\ \x6e\x4c\x61\x79\x65\x72\x73\x2e\x4d\x61\x70\x28\x27\x6d\x61\x70\ \x27\x2c\x20\x7b\x64\x69\x73\x70\x6c\x61\x79\x50\x72\x6f\x6a\x65\ \x63\x74\x69\x6f\x6e\x3a\x20\x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\ \x61\x79\x65\x72\x73\x2e\x50\x72\x6f\x6a\x65\x63\x74\x69\x6f\x6e\ \x28\x22\x45\x50\x53\x47\x3a\x34\x33\x32\x36\x22\x29\x7d\x29\x3b\ \x0a\x20\x20\x20\x20\x6d\x61\x70\x2e\x61\x64\x64\x43\x6f\x6e\x74\ \x72\x6f\x6c\x28\x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\ \x72\x73\x2e\x43\x6f\x6e\x74\x72\x6f\x6c\x2e\x4c\x61\x79\x65\x72\ \x53\x77\x69\x74\x63\x68\x65\x72\x28\x29\x29\x3b\x0a\x0a\x20\x20\ \x20\x20\x76\x61\x72\x20\x6f\x73\x6d\x20\x3d\x20\x6e\x65\x77\x20\ \x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x4c\x61\x79\x65\x72\ \x2e\x4f\x53\x4d\x28\x29\x3b\x0a\x20\x20\x20\x20\x76\x61\x72\x20\ \x63\x79\x63\x6c\x65\x20\x3d\x20\x6e\x65\x77\x20\x4f\x70\x65\x6e\ \x4c\x61\x79\x65\x72\x73\x2e\x4c\x61\x79\x65\x72\x2e\x4f\x53\x4d\ \x28\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x22\x4f\x70\x65\x6e\x43\ \x79\x63\x6c\x65\x4d\x61\x70\x22\x2c\x0a\x20\x20\x20\x20\x20\x20\ \x20\x20\x5b\x22\x68\x74\x74\x70\x3a\x2f\x2f\x61\x2e\x74\x69\x6c\ \x65\x2e\x6f\x70\x65\x6e\x63\x79\x63\x6c\x65\x6d\x61\x70\x2e\x6f\ \x72\x67\x2f\x63\x79\x63\x6c\x65\x2f\x24\x7b\x7a\x7d\x2f\x24\x7b\ \x78\x7d\x2f\x24\x7b\x79\x7d\x2e\x70\x6e\x67\x22\x2c\x0a\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22\x68\x74\x74\x70\x3a\ \x2f\x2f\x62\x2e\x74\x69\x6c\x65\x2e\x6f\x70\x65\x6e\x63\x79\x63\ \x6c\x65\x6d\x61\x70\x2e\x6f\x72\x67\x2f\x63\x79\x63\x6c\x65\x2f\ \x24\x7b\x7a\x7d\x2f\x24\x7b\x78\x7d\x2f\x24\x7b\x79\x7d\x2e\x70\ \x6e\x67\x22\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\x2e\x74\x69\x6c\x65\x2e\ \x6f\x70\x65\x6e\x63\x79\x63\x6c\x65\x6d\x61\x70\x2e\x6f\x72\x67\ \x2f\x63\x79\x63\x6c\x65\x2f\x24\x7b\x7a\x7d\x2f\x24\x7b\x78\x7d\ \x2f\x24\x7b\x79\x7d\x2e\x70\x6e\x67\x22\x5d\x2c\x0a\x20\x20\x20\ \x20\x20\x20\x20\x20\x7b\x20\x74\x79\x70\x65\x3a\x20\x27\x70\x6e\ \x67\x27\x2c\x20\x64\x69\x73\x70\x6c\x61\x79\x4f\x75\x74\x73\x69\ \x64\x65\x4d\x61\x78\x45\x78\x74\x65\x6e\x74\x3a\x20\x74\x72\x75\ \x65\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\ \x72\x61\x6e\x73\x69\x74\x69\x6f\x6e\x45\x66\x66\x65\x63\x74\x3a\ \x20\x27\x72\x65\x73\x69\x7a\x65\x27\x7d\x0a\x20\x20\x20\x20\x29\ \x3b\x0a\x20\x20\x20\x20\x76\x61\x72\x20\x67\x70\x68\x79\x20\x3d\ \x20\x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\ \x4c\x61\x79\x65\x72\x2e\x47\x6f\x6f\x67\x6c\x65\x28\x0a\x20\x20\ \x20\x20\x20\x20\x20\x20\x22\x47\x6f\x6f\x67\x6c\x65\x20\x50\x68\ \x79\x73\x69\x63\x61\x6c\x22\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x7b\x74\x79\x70\x65\x3a\x20\x67\x6f\x6f\x67\x6c\x65\x2e\x6d\ \x61\x70\x73\x2e\x4d\x61\x70\x54\x79\x70\x65\x49\x64\x2e\x54\x45\ \x52\x52\x41\x49\x4e\x7d\x0a\x20\x20\x20\x20\x29\x3b\x0a\x20\x20\ \x20\x20\x76\x61\x72\x20\x67\x6d\x61\x70\x20\x3d\x20\x6e\x65\x77\ \x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x4c\x61\x79\x65\ \x72\x2e\x47\x6f\x6f\x67\x6c\x65\x28\x0a\x20\x20\x20\x20\x20\x20\ \x20\x20\x22\x47\x6f\x6f\x67\x6c\x65\x20\x53\x74\x72\x65\x65\x74\ \x73\x22\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x7b\x6e\x75\x6d\ \x5a\x6f\x6f\x6d\x4c\x65\x76\x65\x6c\x73\x3a\x20\x32\x30\x7d\x0a\ \x20\x20\x20\x20\x29\x3b\x0a\x20\x20\x20\x20\x76\x61\x72\x20\x67\ \x68\x79\x62\x20\x3d\x20\x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\ \x79\x65\x72\x73\x2e\x4c\x61\x79\x65\x72\x2e\x47\x6f\x6f\x67\x6c\ \x65\x28\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x22\x47\x6f\x6f\x67\ \x6c\x65\x20\x48\x79\x62\x72\x69\x64\x22\x2c\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x7b\x74\x79\x70\x65\x3a\x20\x67\x6f\x6f\x67\x6c\ \x65\x2e\x6d\x61\x70\x73\x2e\x4d\x61\x70\x54\x79\x70\x65\x49\x64\ \x2e\x48\x59\x42\x52\x49\x44\x2c\x20\x6e\x75\x6d\x5a\x6f\x6f\x6d\ \x4c\x65\x76\x65\x6c\x73\x3a\x20\x32\x30\x7d\x0a\x20\x20\x20\x20\ \x29\x3b\x0a\x20\x20\x20\x20\x76\x61\x72\x20\x67\x73\x61\x74\x20\ \x3d\x20\x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\ \x2e\x4c\x61\x79\x65\x72\x2e\x47\x6f\x6f\x67\x6c\x65\x28\x0a\x20\ \x20\x20\x20\x20\x20\x20\x20\x22\x47\x6f\x6f\x67\x6c\x65\x20\x53\ \x61\x74\x65\x6c\x6c\x69\x74\x65\x22\x2c\x0a\x20\x20\x20\x20\x20\ \x20\x20\x20\x7b\x74\x79\x70\x65\x3a\x20\x67\x6f\x6f\x67\x6c\x65\ \x2e\x6d\x61\x70\x73\x2e\x4d\x61\x70\x54\x79\x70\x65\x49\x64\x2e\ \x53\x41\x54\x45\x4c\x4c\x49\x54\x45\x2c\x20\x6e\x75\x6d\x5a\x6f\ \x6f\x6d\x4c\x65\x76\x65\x6c\x73\x3a\x20\x32\x32\x7d\x0a\x20\x20\ \x20\x20\x29\x3b\x0a\x20\x20\x20\x20\x76\x61\x72\x20\x72\x65\x6e\ \x64\x65\x72\x65\x72\x20\x3d\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\ \x72\x73\x2e\x55\x74\x69\x6c\x2e\x67\x65\x74\x50\x61\x72\x61\x6d\ \x65\x74\x65\x72\x73\x28\x77\x69\x6e\x64\x6f\x77\x2e\x6c\x6f\x63\ \x61\x74\x69\x6f\x6e\x2e\x68\x72\x65\x66\x29\x2e\x72\x65\x6e\x64\ \x65\x72\x65\x72\x3b\x0a\x20\x20\x20\x20\x72\x65\x6e\x64\x65\x72\ \x65\x72\x20\x3d\x20\x28\x72\x65\x6e\x64\x65\x72\x65\x72\x29\x20\ \x3f\x20\x5b\x72\x65\x6e\x64\x65\x72\x65\x72\x5d\x20\x3a\x20\x4f\ \x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x4c\x61\x79\x65\x72\x2e\ \x56\x65\x63\x74\x6f\x72\x2e\x70\x72\x6f\x74\x6f\x74\x79\x70\x65\ \x2e\x72\x65\x6e\x64\x65\x72\x65\x72\x73\x3b\x0a\x0a\x20\x20\x20\ \x20\x76\x65\x63\x74\x6f\x72\x73\x20\x3d\x20\x6e\x65\x77\x20\x4f\ \x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x4c\x61\x79\x65\x72\x2e\ \x56\x65\x63\x74\x6f\x72\x28\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ \x22\x44\x72\x61\x77\x6e\x22\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x7b\x72\x65\x6e\x64\x65\x72\x65\x72\x73\x3a\x20\x72\x65\x6e\ \x64\x65\x72\x65\x72\x7d\x0a\x20\x20\x20\x20\x29\x3b\x0a\x20\x20\ \x20\x20\x0a\x20\x20\x20\x20\x6d\x61\x70\x2e\x61\x64\x64\x4c\x61\ \x79\x65\x72\x73\x28\x5b\x63\x79\x63\x6c\x65\x2c\x20\x6f\x73\x6d\ \x2c\x20\x67\x70\x68\x79\x2c\x20\x67\x6d\x61\x70\x2c\x20\x67\x68\ \x79\x62\x2c\x20\x67\x73\x61\x74\x2c\x20\x76\x65\x63\x74\x6f\x72\ \x73\x5d\x29\x3b\x0a\x20\x20\x20\x20\x6d\x61\x70\x2e\x61\x64\x64\ \x43\x6f\x6e\x74\x72\x6f\x6c\x28\x6e\x65\x77\x20\x4f\x70\x65\x6e\ \x4c\x61\x79\x65\x72\x73\x2e\x43\x6f\x6e\x74\x72\x6f\x6c\x2e\x4c\ \x61\x79\x65\x72\x53\x77\x69\x74\x63\x68\x65\x72\x28\x29\x29\x3b\ \x0a\x20\x20\x20\x20\x6d\x61\x70\x2e\x61\x64\x64\x43\x6f\x6e\x74\ \x72\x6f\x6c\x28\x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\ \x72\x73\x2e\x43\x6f\x6e\x74\x72\x6f\x6c\x2e\x4d\x6f\x75\x73\x65\ \x50\x6f\x73\x69\x74\x69\x6f\x6e\x28\x29\x29\x3b\x0a\x0a\x20\x20\ \x20\x20\x63\x6f\x6e\x76\x65\x72\x74\x43\x61\x6c\x6c\x62\x61\x63\ \x6b\x20\x3d\x20\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x66\x65\x61\ \x74\x75\x72\x65\x29\x20\x7b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ \x66\x65\x61\x74\x75\x72\x65\x4c\x61\x74\x4c\x6f\x6e\x20\x3d\x20\ \x66\x65\x61\x74\x75\x72\x65\x2e\x63\x6c\x6f\x6e\x65\x28\x29\x3b\ \x0a\x20\x20\x20\x20\x20\x20\x20\x20\x76\x61\x72\x20\x67\x65\x6f\ \x6d\x20\x3d\x20\x66\x65\x61\x74\x75\x72\x65\x4c\x61\x74\x4c\x6f\ \x6e\x2e\x67\x65\x6f\x6d\x65\x74\x72\x79\x3b\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x67\x65\x6f\x6d\x2e\x74\x72\x61\x6e\x73\x66\x6f\ \x72\x6d\x28\x6d\x61\x70\x2e\x67\x65\x74\x50\x72\x6f\x6a\x65\x63\ \x74\x69\x6f\x6e\x4f\x62\x6a\x65\x63\x74\x28\x29\x2c\x20\x6e\x65\ \x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x50\x72\x6f\ \x6a\x65\x63\x74\x69\x6f\x6e\x28\x22\x45\x50\x53\x47\x3a\x34\x33\ \x32\x36\x22\x29\x29\x3b\x0a\x20\x20\x20\x20\x7d\x3b\x0a\x0a\x20\ \x20\x20\x20\x63\x6f\x6e\x74\x72\x6f\x6c\x73\x20\x3d\x20\x7b\x0a\ \x20\x20\x20\x20\x20\x20\x20\x20\x70\x6f\x69\x6e\x74\x3a\x20\x6e\ \x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x43\x6f\ \x6e\x74\x72\x6f\x6c\x2e\x44\x72\x61\x77\x46\x65\x61\x74\x75\x72\ \x65\x28\x76\x65\x63\x74\x6f\x72\x73\x2c\x0a\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x4f\ \x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x48\x61\x6e\x64\x6c\x65\ \x72\x2e\x50\x6f\x69\x6e\x74\x29\x2c\x0a\x20\x20\x20\x20\x20\x20\ \x20\x20\x6c\x69\x6e\x65\x3a\x20\x6e\x65\x77\x20\x4f\x70\x65\x6e\ \x4c\x61\x79\x65\x72\x73\x2e\x43\x6f\x6e\x74\x72\x6f\x6c\x2e\x44\ \x72\x61\x77\x46\x65\x61\x74\x75\x72\x65\x28\x76\x65\x63\x74\x6f\ \x72\x73\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\ \x72\x73\x2e\x48\x61\x6e\x64\x6c\x65\x72\x2e\x50\x61\x74\x68\x2c\ \x20\x7b\x27\x66\x65\x61\x74\x75\x72\x65\x41\x64\x64\x65\x64\x27\ \x3a\x20\x63\x6f\x6e\x76\x65\x72\x74\x43\x61\x6c\x6c\x62\x61\x63\ \x6b\x7d\x29\x2c\x0a\x20\x20\x20\x20\x7d\x3b\x0a\x0a\x20\x20\x20\ \x20\x66\x6f\x72\x28\x76\x61\x72\x20\x6b\x65\x79\x20\x69\x6e\x20\ \x63\x6f\x6e\x74\x72\x6f\x6c\x73\x29\x20\x7b\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x6d\x61\x70\x2e\x61\x64\x64\x43\x6f\x6e\x74\x72\ \x6f\x6c\x28\x63\x6f\x6e\x74\x72\x6f\x6c\x73\x5b\x6b\x65\x79\x5d\ \x29\x3b\x0a\x20\x20\x20\x20\x7d\x0a\x20\x20\x20\x20\x63\x6f\x6e\ \x74\x72\x6f\x6c\x73\x5b\x22\x6c\x69\x6e\x65\x22\x5d\x2e\x61\x63\ \x74\x69\x76\x61\x74\x65\x28\x29\x3b\x20\x2f\x2f\x54\x4f\x44\x4f\ \x3a\x20\x61\x63\x74\x69\x76\x61\x74\x65\x20\x74\x68\x72\x6f\x75\ \x67\x68\x20\x61\x20\x70\x72\x6f\x70\x65\x72\x20\x66\x75\x6e\x63\ \x74\x69\x6f\x6e\x0a\x0a\x20\x20\x20\x20\x2f\x2f\x20\x47\x6f\x6f\ \x67\x6c\x65\x2e\x76\x33\x20\x75\x73\x65\x73\x20\x45\x50\x53\x47\ \x3a\x39\x30\x30\x39\x31\x33\x20\x0a\x20\x20\x20\x20\x6d\x61\x70\ \x2e\x73\x65\x74\x43\x65\x6e\x74\x65\x72\x28\x6e\x65\x77\x20\x4f\ \x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x4c\x6f\x6e\x4c\x61\x74\ \x28\x31\x30\x2e\x32\x2c\x20\x34\x38\x2e\x39\x29\x2e\x74\x72\x61\ \x6e\x73\x66\x6f\x72\x6d\x28\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ \x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x50\ \x72\x6f\x6a\x65\x63\x74\x69\x6f\x6e\x28\x22\x45\x50\x53\x47\x3a\ \x34\x33\x32\x36\x22\x29\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ \x6d\x61\x70\x2e\x67\x65\x74\x50\x72\x6f\x6a\x65\x63\x74\x69\x6f\ \x6e\x4f\x62\x6a\x65\x63\x74\x28\x29\x0a\x20\x20\x20\x20\x29\x2c\ \x20\x35\x29\x3b\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x66\x6f\ \x72\x20\x28\x76\x61\x72\x20\x69\x20\x3d\x20\x30\x3b\x20\x69\x20\ \x3c\x20\x6d\x61\x70\x2e\x6c\x61\x79\x65\x72\x73\x2e\x6c\x65\x6e\ \x67\x74\x68\x3b\x20\x69\x2b\x2b\x29\x20\x7b\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x6d\x61\x70\x2e\x6c\x61\x79\x65\x72\x73\x5b\x69\ \x5d\x2e\x61\x6e\x69\x6d\x61\x74\x69\x6f\x6e\x45\x6e\x61\x62\x6c\ \x65\x64\x20\x3d\x20\x74\x72\x75\x65\x3b\x0a\x20\x20\x20\x20\x7d\ \x0a\x20\x20\x20\x20\x0a\x7d\x0a\x0a\x6b\x6d\x6c\x46\x6f\x72\x6d\ \x61\x74\x20\x3d\x20\x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\ \x65\x72\x73\x2e\x46\x6f\x72\x6d\x61\x74\x2e\x4b\x4d\x4c\x28\x29\ \x3b\x0a\x66\x75\x6e\x63\x74\x69\x6f\x6e\x20\x63\x72\x65\x61\x74\ \x65\x4b\x6d\x6c\x28\x29\x20\x7b\x0a\x20\x20\x20\x20\x76\x61\x72\ \x20\x6b\x6d\x6c\x20\x3d\x20\x6b\x6d\x6c\x46\x6f\x72\x6d\x61\x74\ \x2e\x77\x72\x69\x74\x65\x28\x66\x65\x61\x74\x75\x72\x65\x4c\x61\ \x74\x4c\x6f\x6e\x29\x3b\x0a\x20\x20\x20\x20\x72\x65\x74\x75\x72\ \x6e\x20\x6b\x6d\x6c\x0a\x7d\ \x00\x00\x07\xf0\ \x3c\ \x68\x74\x6d\x6c\x3e\x0a\x3c\x68\x65\x61\x64\x3e\x0a\x0a\x3c\x73\ \x74\x79\x6c\x65\x20\x74\x79\x70\x65\x3d\x22\x74\x65\x78\x74\x2f\ \x63\x73\x73\x22\x3e\x0a\x20\x20\x20\x20\x68\x32\x20\x7b\x0a\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6d\x61\x72\x67\x69\ \x6e\x2d\x6c\x65\x66\x74\x3a\x31\x30\x30\x70\x78\x3b\x0a\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x63\x6f\x6c\x6f\x72\x3a\ \x20\x23\x30\x30\x30\x30\x36\x36\x3b\x20\x0a\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\ \x3a\x20\x32\x34\x70\x78\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x7d\ \x0a\x0a\x20\x20\x20\x20\x68\x33\x20\x7b\x0a\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x6d\x61\x72\x67\x69\x6e\x2d\x6c\x65\ \x66\x74\x3a\x31\x35\x30\x70\x78\x3b\x0a\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x63\x6f\x6c\x6f\x72\x3a\x20\x23\x30\x30\ \x30\x30\x30\x30\x3b\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x20\x31\x36\ \x70\x78\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x7d\x0a\x0a\x20\x20\ \x20\x20\x70\x20\x20\x7b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x6d\x61\x72\x67\x69\x6e\x2d\x6c\x65\x66\x74\x3a\x31\ \x35\x30\x70\x78\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x6d\x61\x72\x67\x69\x6e\x2d\x72\x69\x67\x68\x74\x3a\x32\ \x35\x30\x70\x78\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x63\x6f\x6c\x6f\x72\x3a\x20\x23\x30\x30\x30\x30\x30\x30\ \x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x7d\x0a\x0a\x20\x20\x20\x20\ \x62\x20\x20\x7b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x66\x6f\x6e\x74\x2d\x73\x69\x7a\x65\x3a\x20\x31\x38\x70\x78\ \x0a\x20\x20\x20\x20\x20\x20\x20\x7d\x0a\x3c\x2f\x73\x74\x79\x6c\ \x65\x3e\x0a\x0a\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\ \x79\x3e\x0a\x3c\x64\x69\x76\x3e\x0a\x0a\x3c\x64\x69\x76\x20\x69\ \x64\x3d\x22\x6d\x61\x70\x22\x20\x63\x6c\x61\x73\x73\x3d\x22\x73\ \x6d\x61\x6c\x6c\x6d\x61\x70\x22\x3e\x3c\x2f\x64\x69\x76\x3e\x0a\ \x0a\x3c\x73\x63\x72\x69\x70\x74\x20\x74\x79\x70\x65\x3d\x22\x74\ \x65\x78\x74\x2f\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x22\x20\ \x73\x72\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\ \x6f\x70\x65\x6e\x6c\x61\x79\x65\x72\x73\x2e\x6f\x72\x67\x2f\x64\ \x65\x76\x2f\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x6a\x73\ \x22\x3e\x3c\x2f\x73\x63\x72\x69\x70\x74\x3e\x0a\x3c\x73\x63\x72\ \x69\x70\x74\x20\x74\x79\x70\x65\x3d\x22\x74\x65\x78\x74\x2f\x6a\ \x61\x76\x61\x73\x63\x72\x69\x70\x74\x22\x3e\x0a\x0a\x76\x65\x63\ \x74\x6f\x72\x6c\x61\x79\x65\x72\x20\x3d\x20\x6e\x65\x77\x20\x4f\ \x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x4c\x61\x79\x65\x72\x2e\ \x56\x65\x63\x74\x6f\x72\x28\x22\x56\x65\x63\x74\x6f\x72\x20\x4c\ \x61\x79\x65\x72\x22\x2c\x20\x7b\x73\x74\x79\x6c\x65\x3a\x20\x7b\ \x73\x74\x72\x6f\x6b\x65\x43\x6f\x6c\x6f\x72\x3a\x20\x22\x62\x6c\ \x75\x65\x22\x2c\x20\x73\x74\x72\x6f\x6b\x65\x57\x69\x64\x74\x68\ \x3a\x20\x35\x2c\x20\x73\x74\x72\x6f\x6b\x65\x4f\x70\x61\x63\x69\ \x74\x79\x3a\x20\x30\x2e\x36\x7d\x7d\x29\x3b\x0a\x0a\x6d\x61\x70\ \x20\x3d\x20\x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\ \x73\x2e\x4d\x61\x70\x28\x7b\x0a\x20\x20\x20\x20\x64\x69\x76\x3a\ \x20\x22\x6d\x61\x70\x22\x2c\x0a\x20\x20\x20\x20\x6c\x61\x79\x65\ \x72\x73\x3a\x20\x5b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x6e\x65\ \x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x4c\x61\x79\ \x65\x72\x2e\x4f\x53\x4d\x28\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x22\x4f\x70\x65\x6e\x43\x79\x63\x6c\x65\x4d\x61\ \x70\x22\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x5b\x22\x68\x74\x74\x70\x3a\x2f\x2f\x61\x2e\x74\x69\x6c\x65\x2e\ \x6f\x70\x65\x6e\x63\x79\x63\x6c\x65\x6d\x61\x70\x2e\x6f\x72\x67\ \x2f\x63\x79\x63\x6c\x65\x2f\x24\x7b\x7a\x7d\x2f\x24\x7b\x78\x7d\ \x2f\x24\x7b\x79\x7d\x2e\x70\x6e\x67\x22\x2c\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22\x68\x74\x74\ \x70\x3a\x2f\x2f\x62\x2e\x74\x69\x6c\x65\x2e\x6f\x70\x65\x6e\x63\ \x79\x63\x6c\x65\x6d\x61\x70\x2e\x6f\x72\x67\x2f\x63\x79\x63\x6c\ \x65\x2f\x24\x7b\x7a\x7d\x2f\x24\x7b\x78\x7d\x2f\x24\x7b\x79\x7d\ \x2e\x70\x6e\x67\x22\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x63\ \x2e\x74\x69\x6c\x65\x2e\x6f\x70\x65\x6e\x63\x79\x63\x6c\x65\x6d\ \x61\x70\x2e\x6f\x72\x67\x2f\x63\x79\x63\x6c\x65\x2f\x24\x7b\x7a\ \x7d\x2f\x24\x7b\x78\x7d\x2f\x24\x7b\x79\x7d\x2e\x70\x6e\x67\x22\ \x5d\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7b\ \x20\x74\x79\x70\x65\x3a\x20\x27\x70\x6e\x67\x27\x2c\x20\x64\x69\ \x73\x70\x6c\x61\x79\x4f\x75\x74\x73\x69\x64\x65\x4d\x61\x78\x45\ \x78\x74\x65\x6e\x74\x3a\x20\x74\x72\x75\x65\x2c\x0a\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x74\x72\x61\ \x6e\x73\x69\x74\x69\x6f\x6e\x45\x66\x66\x65\x63\x74\x3a\x20\x27\ \x72\x65\x73\x69\x7a\x65\x27\x7d\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x29\x2c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x6e\x65\x77\x20\ \x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x4c\x61\x79\x65\x72\ \x2e\x4f\x53\x4d\x28\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x22\x4f\x70\x65\x6e\x53\x74\x72\x65\x65\x74\x4d\x61\x70\ \x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x29\x2c\x0a\x20\x20\x20\ \x20\x20\x20\x20\x20\x76\x65\x63\x74\x6f\x72\x6c\x61\x79\x65\x72\ \x0a\x20\x20\x20\x20\x5d\x2c\x0a\x70\x72\x6f\x6a\x65\x63\x74\x69\ \x6f\x6e\x3a\x20\x6e\x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\ \x72\x73\x2e\x50\x72\x6f\x6a\x65\x63\x74\x69\x6f\x6e\x28\x22\x45\ \x50\x53\x47\x3a\x34\x33\x32\x36\x22\x29\x2c\x0a\x64\x69\x73\x70\ \x6c\x61\x79\x50\x72\x6f\x6a\x65\x63\x74\x69\x6f\x6e\x3a\x20\x6e\ \x65\x77\x20\x4f\x70\x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x50\x72\ \x6f\x6a\x65\x63\x74\x69\x6f\x6e\x28\x22\x45\x50\x53\x47\x3a\x34\ \x33\x32\x36\x22\x29\x0a\x7d\x29\x3b\x0a\x0a\x6d\x61\x70\x2e\x61\ \x64\x64\x43\x6f\x6e\x74\x72\x6f\x6c\x28\x6e\x65\x77\x20\x4f\x70\ \x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x43\x6f\x6e\x74\x72\x6f\x6c\ \x2e\x4c\x61\x79\x65\x72\x53\x77\x69\x74\x63\x68\x65\x72\x28\x29\ \x29\x3b\x0a\x0a\x77\x6b\x74\x20\x3d\x20\x6e\x65\x77\x20\x4f\x70\ \x65\x6e\x4c\x61\x79\x65\x72\x73\x2e\x46\x6f\x72\x6d\x61\x74\x2e\ \x57\x4b\x54\x28\x29\x3b\x0a\x76\x61\x72\x20\x66\x65\x61\x74\x75\ \x72\x65\x73\x20\x3d\x20\x77\x6b\x74\x2e\x72\x65\x61\x64\x28\x22\ \x4c\x49\x4e\x45\x53\x54\x52\x49\x4e\x47\x28\x25\x73\x29\x22\x29\ \x3b\x0a\x0a\x69\x66\x28\x66\x65\x61\x74\x75\x72\x65\x73\x29\x7b\ \x0a\x20\x20\x20\x20\x66\x65\x61\x74\x75\x72\x65\x73\x2e\x67\x65\ \x6f\x6d\x65\x74\x72\x79\x2e\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\ \x28\x6d\x61\x70\x2e\x64\x69\x73\x70\x6c\x61\x79\x50\x72\x6f\x6a\ \x65\x63\x74\x69\x6f\x6e\x2c\x20\x6d\x61\x70\x2e\x67\x65\x74\x50\ \x72\x6f\x6a\x65\x63\x74\x69\x6f\x6e\x4f\x62\x6a\x65\x63\x74\x28\ \x29\x29\x3b\x0a\x20\x20\x20\x20\x69\x66\x28\x66\x65\x61\x74\x75\ \x72\x65\x73\x2e\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\ \x21\x3d\x20\x41\x72\x72\x61\x79\x29\x7b\x0a\x20\x20\x20\x20\x20\ \x20\x20\x20\x66\x65\x61\x74\x75\x72\x65\x73\x20\x3d\x20\x5b\x66\ \x65\x61\x74\x75\x72\x65\x73\x5d\x3b\x0a\x20\x20\x20\x20\x7d\x0a\ \x20\x20\x20\x20\x62\x6f\x75\x6e\x64\x73\x20\x3d\x20\x66\x65\x61\ \x74\x75\x72\x65\x73\x5b\x30\x5d\x2e\x67\x65\x6f\x6d\x65\x74\x72\ \x79\x2e\x67\x65\x74\x42\x6f\x75\x6e\x64\x73\x28\x29\x3b\x0a\x20\ \x20\x20\x20\x66\x6f\x72\x28\x76\x61\x72\x20\x69\x3d\x31\x3b\x20\ \x69\x3c\x66\x65\x61\x74\x75\x72\x65\x73\x2e\x6c\x65\x6e\x67\x74\ \x68\x3b\x20\x2b\x2b\x69\x29\x7b\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x62\x6f\x75\x6e\x64\x73\x2e\x65\x78\x74\x65\x6e\x64\x28\x66\ \x65\x61\x74\x75\x72\x65\x73\x5b\x69\x5d\x2e\x67\x65\x6f\x6d\x65\ \x74\x72\x79\x2e\x67\x65\x74\x42\x6f\x75\x6e\x64\x73\x28\x29\x29\ \x3b\x0a\x20\x20\x20\x20\x7d\x0a\x20\x20\x20\x20\x76\x65\x63\x74\ \x6f\x72\x6c\x61\x79\x65\x72\x2e\x61\x64\x64\x46\x65\x61\x74\x75\ \x72\x65\x73\x28\x66\x65\x61\x74\x75\x72\x65\x73\x29\x3b\x0a\x20\ \x20\x20\x20\x6d\x61\x70\x2e\x7a\x6f\x6f\x6d\x54\x6f\x45\x78\x74\ \x65\x6e\x74\x28\x62\x6f\x75\x6e\x64\x73\x29\x3b\x0a\x7d\x0a\x0a\ \x77\x69\x6e\x64\x6f\x77\x2e\x6f\x6e\x72\x65\x73\x69\x7a\x65\x20\ \x3d\x20\x66\x75\x6e\x63\x74\x69\x6f\x6e\x28\x29\x20\x7b\x20\x6d\ \x61\x70\x2e\x7a\x6f\x6f\x6d\x54\x6f\x45\x78\x74\x65\x6e\x74\x28\ \x62\x6f\x75\x6e\x64\x73\x29\x3b\x20\x7d\x0a\x0a\x3c\x2f\x73\x63\ \x72\x69\x70\x74\x3e\x0a\x0a\x3c\x2f\x64\x69\x76\x3e\x0a\x3c\x2f\ \x62\x6f\x64\x79\x3e\x0a\x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\x0a\ \x00\x00\x04\xf9\ \x3c\ \x21\x44\x4f\x43\x54\x59\x50\x45\x20\x68\x74\x6d\x6c\x3e\x0a\x3c\ \x68\x74\x6d\x6c\x3e\x0a\x20\x20\x20\x20\x3c\x68\x65\x61\x64\x3e\ \x0a\x20\x20\x20\x20\x3c\x6d\x65\x74\x61\x20\x6e\x61\x6d\x65\x3d\ \x22\x76\x69\x65\x77\x70\x6f\x72\x74\x22\x20\x63\x6f\x6e\x74\x65\ \x6e\x74\x3d\x22\x77\x69\x64\x74\x68\x3d\x64\x65\x76\x69\x63\x65\ \x2d\x77\x69\x64\x74\x68\x3b\x20\x69\x6e\x69\x74\x69\x61\x6c\x2d\ \x73\x63\x61\x6c\x65\x3d\x31\x2e\x30\x3b\x20\x6d\x61\x78\x69\x6d\ \x75\x6d\x2d\x73\x63\x61\x6c\x65\x3d\x31\x2e\x30\x3b\x20\x75\x73\ \x65\x72\x2d\x73\x63\x61\x6c\x61\x62\x6c\x65\x3d\x30\x3b\x22\x20\ \x2f\x3e\x0a\x20\x20\x20\x20\x3c\x6d\x65\x74\x61\x20\x6e\x61\x6d\ \x65\x3d\x22\x61\x70\x70\x6c\x65\x2d\x6d\x6f\x62\x69\x6c\x65\x2d\ \x77\x65\x62\x2d\x61\x70\x70\x2d\x63\x61\x70\x61\x62\x6c\x65\x22\ \x20\x63\x6f\x6e\x74\x65\x6e\x74\x3d\x22\x79\x65\x73\x22\x20\x2f\ \x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x74\x69\x74\x6c\x65\ \x3e\x43\x79\x63\x6c\x6f\x47\x72\x61\x70\x68\x3a\x20\x64\x72\x61\ \x77\x20\x6f\x6e\x20\x6d\x61\x70\x3c\x2f\x74\x69\x74\x6c\x65\x3e\ \x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x6c\x69\x6e\x6b\x20\x72\ \x65\x6c\x3d\x22\x73\x74\x79\x6c\x65\x73\x68\x65\x65\x74\x22\x20\ \x68\x72\x65\x66\x3d\x22\x67\x6f\x6f\x67\x6c\x65\x2e\x63\x73\x73\ \x22\x20\x74\x79\x70\x65\x3d\x22\x74\x65\x78\x74\x2f\x63\x73\x73\ \x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x73\x74\x79\x6c\ \x65\x20\x74\x79\x70\x65\x3d\x22\x74\x65\x78\x74\x2f\x63\x73\x73\ \x22\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x68\ \x74\x6d\x6c\x2c\x20\x62\x6f\x64\x79\x2c\x20\x23\x6d\x61\x70\x20\ \x7b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x6d\x61\x72\x67\x69\x6e\x3a\x20\x30\x3b\x0a\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\ \x74\x68\x3a\x20\x31\x30\x30\x25\x3b\x0a\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x68\x65\x69\x67\x68\x74\ \x3a\x20\x31\x30\x30\x25\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x7d\x0a\x2f\x2a\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x23\x74\x65\x78\x74\x20\x7b\x0a\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x70\x6f\x73\ \x69\x74\x69\x6f\x6e\x3a\x20\x61\x62\x73\x6f\x6c\x75\x74\x65\x3b\ \x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x62\x6f\x74\x74\x6f\x6d\x3a\x20\x31\x65\x6d\x3b\x0a\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6c\x65\ \x66\x74\x3a\x20\x31\x65\x6d\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x77\x69\x64\x74\x68\x3a\x20\ \x32\x35\x36\x70\x78\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x7a\x2d\x69\x6e\x64\x65\x78\x3a\x20\ \x32\x30\x30\x30\x30\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\ \x64\x2d\x63\x6f\x6c\x6f\x72\x3a\x20\x77\x68\x69\x74\x65\x3b\x0a\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ \x6f\x70\x61\x63\x69\x74\x79\x3a\x20\x30\x2e\x36\x3b\x0a\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x70\x61\ \x64\x64\x69\x6e\x67\x3a\x20\x30\x20\x30\x2e\x35\x65\x6d\x20\x30\ \x2e\x35\x65\x6d\x20\x30\x2e\x35\x65\x6d\x3b\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\x7d\x2a\x2f\x0a\x20\x20\x20\x20\ \x20\x20\x20\x20\x3c\x2f\x73\x74\x79\x6c\x65\x3e\x0a\x20\x20\x20\ \x20\x20\x20\x20\x20\x3c\x73\x63\x72\x69\x70\x74\x20\x74\x79\x70\ \x65\x3d\x22\x74\x65\x78\x74\x2f\x6a\x61\x76\x61\x73\x63\x72\x69\ \x70\x74\x22\x20\x73\x72\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\ \x6d\x61\x70\x73\x2e\x67\x6f\x6f\x67\x6c\x65\x2e\x63\x6f\x6d\x2f\ \x6d\x61\x70\x73\x2f\x61\x70\x69\x2f\x6a\x73\x3f\x76\x3d\x33\x2e\ \x33\x26\x61\x6d\x70\x3b\x73\x65\x6e\x73\x6f\x72\x3d\x66\x61\x6c\ \x73\x65\x22\x3e\x3c\x2f\x73\x63\x72\x69\x70\x74\x3e\x0a\x20\x20\ \x20\x20\x20\x20\x20\x20\x3c\x73\x63\x72\x69\x70\x74\x20\x74\x79\ \x70\x65\x3d\x22\x74\x65\x78\x74\x2f\x6a\x61\x76\x61\x73\x63\x72\ \x69\x70\x74\x22\x20\x73\x72\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\ \x2f\x77\x77\x77\x2e\x6f\x70\x65\x6e\x6c\x61\x79\x65\x72\x73\x2e\ \x6f\x72\x67\x2f\x64\x65\x76\x2f\x4f\x70\x65\x6e\x4c\x61\x79\x65\ \x72\x73\x2e\x6a\x73\x22\x3e\x3c\x2f\x73\x63\x72\x69\x70\x74\x3e\ \x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x73\x63\x72\x69\x70\x74\ \x20\x74\x79\x70\x65\x3d\x22\x74\x65\x78\x74\x2f\x6a\x61\x76\x61\ \x73\x63\x72\x69\x70\x74\x22\x20\x73\x72\x63\x3d\x22\x64\x72\x61\ \x77\x5f\x6f\x6e\x5f\x6d\x61\x70\x2e\x6a\x73\x22\x3e\x3c\x2f\x73\ \x63\x72\x69\x70\x74\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\ \x73\x63\x72\x69\x70\x74\x20\x74\x79\x70\x65\x3d\x22\x74\x65\x78\ \x74\x2f\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x22\x20\x73\x72\ \x63\x3d\x22\x66\x69\x6c\x65\x3a\x2f\x2f\x2e\x2f\x64\x72\x61\x77\ \x5f\x6f\x6e\x5f\x6d\x61\x70\x2e\x6a\x73\x22\x3e\x3c\x2f\x73\x63\ \x72\x69\x70\x74\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x68\x65\x61\x64\ \x3e\x0a\x20\x20\x20\x20\x3c\x62\x6f\x64\x79\x20\x6f\x6e\x6c\x6f\ \x61\x64\x3d\x22\x69\x6e\x69\x74\x28\x29\x22\x3e\x0a\x20\x20\x20\ \x20\x20\x20\x20\x20\x3c\x64\x69\x76\x20\x69\x64\x3d\x22\x6d\x61\ \x70\x22\x2f\x3e\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x2f\x64\ \x69\x76\x3e\x0a\x20\x20\x20\x20\x3c\x2f\x62\x6f\x64\x79\x3e\x0a\ \x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\ \x00\x00\x00\xe5\ \x2e\ \x6f\x6c\x4c\x61\x79\x65\x72\x47\x6f\x6f\x67\x6c\x65\x43\x6f\x70\ \x79\x72\x69\x67\x68\x74\x7b\x72\x69\x67\x68\x74\x3a\x33\x70\x78\ \x3b\x62\x6f\x74\x74\x6f\x6d\x3a\x32\x70\x78\x3b\x6c\x65\x66\x74\ \x3a\x61\x75\x74\x6f\x3b\x7d\x2e\x6f\x6c\x4c\x61\x79\x65\x72\x47\ \x6f\x6f\x67\x6c\x65\x56\x33\x2e\x6f\x6c\x4c\x61\x79\x65\x72\x47\ \x6f\x6f\x67\x6c\x65\x43\x6f\x70\x79\x72\x69\x67\x68\x74\x7b\x62\ \x6f\x74\x74\x6f\x6d\x3a\x30\x3b\x72\x69\x67\x68\x74\x3a\x30\x21\ \x69\x6d\x70\x6f\x72\x74\x61\x6e\x74\x3b\x7d\x2e\x6f\x6c\x4c\x61\ \x79\x65\x72\x47\x6f\x6f\x67\x6c\x65\x50\x6f\x77\x65\x72\x65\x64\ \x42\x79\x7b\x6c\x65\x66\x74\x3a\x32\x70\x78\x3b\x62\x6f\x74\x74\ \x6f\x6d\x3a\x32\x70\x78\x3b\x7d\x2e\x6f\x6c\x4c\x61\x79\x65\x72\ \x47\x6f\x6f\x67\x6c\x65\x56\x33\x2e\x6f\x6c\x4c\x61\x79\x65\x72\ \x47\x6f\x6f\x67\x6c\x65\x50\x6f\x77\x65\x72\x65\x64\x42\x79\x7b\ \x62\x6f\x74\x74\x6f\x6d\x3a\x30\x21\x69\x6d\x70\x6f\x72\x74\x61\ \x6e\x74\x3b\x7d\ \x00\x00\x03\x75\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdb\x02\x0a\ \x01\x29\x2e\x38\x02\x0d\x5b\x00\x00\x02\xf5\x49\x44\x41\x54\x58\ \xc3\xed\x97\x4d\x4f\x13\x41\x18\xc7\xff\xdd\x6d\x82\xa9\xbb\x74\ \x0f\xa5\x41\xe8\x76\xdb\x52\xc3\x01\x02\xa9\x1e\xc4\x44\x2e\x78\ \x90\x4f\xc0\xa1\x5c\xbd\x48\xf8\x06\x1c\x8a\x09\x2d\xdf\x80\xe0\ \xb1\x89\x9c\x14\x4e\x20\xe1\x68\x82\x18\x68\x40\x52\xb1\x07\x4b\ \x68\x0d\xa5\x98\xc6\xec\xb6\xd0\x17\x0a\xdb\x8e\x07\x74\xdb\x51\ \xa1\xaf\x04\x8c\x3e\xc9\x5c\x7e\x33\x3b\xf3\x9f\xe7\x65\x66\x16\ \xf8\xd7\x4d\x77\x01\xb7\x73\x1c\xf7\xb6\xbd\xbd\x3d\x56\x69\x82\ \xc2\xb9\x15\x01\xe0\xec\xec\xec\x76\x3e\x9f\x5f\x92\x65\xd9\xd3\ \xa8\xb0\x87\xe3\xe3\xe3\x09\x52\x66\xc7\xc7\xc7\x44\x96\xe5\x4b\ \xdb\xf2\xf2\x32\xe9\xe9\xe9\x29\x3a\x9d\xce\xcf\x00\x8c\xd5\x2c\ \xa4\xbf\x80\xb3\x0c\xc3\xb0\xe5\x80\xe3\xb8\x8a\x93\x39\x1c\x0e\ \xb8\x5c\x2e\x9d\x28\x8a\x77\x57\x56\x56\xbe\x26\x12\x89\xa7\xb1\ \x58\x6c\xee\xb2\x6f\x98\x0b\x95\xe9\xf5\xfa\xba\x62\xaa\xd3\xc1\ \x6c\x36\x63\x64\x64\xe4\x56\x77\x77\xb7\x5f\x92\xa4\xf7\x00\x5a\ \x6a\xf5\x00\x78\x9e\x2f\x02\x40\x20\x10\x40\x34\x1a\xa1\xfa\xc2\ \xe1\x5d\x58\xad\x22\x5a\x5a\x4a\xf3\xc6\xe3\x71\x24\x93\x49\x44\ \x22\xe7\x63\x09\x21\x30\x18\x0c\xac\xd1\x68\x1c\x10\x04\xe1\x5b\ \x32\x99\x1c\x00\xf0\xa9\xda\x8d\x3c\xf2\x78\x3c\x0a\x21\x84\xcc\ \xcd\xbd\x24\x84\x14\xa9\xe6\xf5\x7a\x89\xa2\xc8\x14\x9b\x9f\x7f\ \x4d\xb6\xb7\xb7\x29\x96\x4c\x2a\x64\x71\x71\x91\xc4\x62\x31\x62\ \x36\x9b\x15\x00\x5c\xd5\x21\x68\xa6\x75\x76\x76\xc2\xe5\x72\x65\ \x01\xb0\xd7\x22\xa0\x9e\x2a\xd0\x2c\x12\x89\x60\x72\xf2\x39\xc5\ \xd6\xd7\xd7\x11\x8f\xc7\x61\x32\x99\x34\x16\x0a\x85\x60\x30\x18\ \x60\xb3\xd9\x34\x96\xcb\x65\x21\x49\xb6\xc6\x04\xd8\xed\x76\xb8\ \xdd\x6e\x8a\xf9\x7c\xd3\x18\x1d\x75\x43\x92\x24\x8d\x2d\x2c\x2c\ \xa0\xab\xcb\x89\xfe\xfe\x3e\x8d\xa5\x52\x29\x2c\x2d\xbd\x41\x5d\ \x65\x78\x63\x42\x90\xcf\x9f\x42\x96\x65\x8a\xa5\xd3\x69\xc8\xb2\ \x02\x9e\xe7\xa9\xdd\x2a\x8a\x42\x8d\x4d\xa5\x52\x50\x55\xb5\x31\ \x01\x87\x87\x87\x98\x99\x99\xa1\x58\x20\x10\x80\xaa\xaa\x68\x6d\ \x2d\x09\x08\x06\x3f\x82\xe3\x38\x38\x1c\x76\x8d\x65\xb3\x39\x38\ \x9d\xce\xba\x04\x68\xf5\x6a\xb3\x49\xbf\xe5\x00\xc3\x4c\x63\x6c\ \xec\x19\x04\x41\xa8\x98\x03\xab\xab\xef\x7e\x24\x64\x8e\xad\x25\ \x07\x58\x86\x61\xf4\xcd\x8c\xb5\xaa\xaa\xba\x9a\x42\xf0\xf3\x2e\ \xd8\xdf\xdf\xc7\xc4\xc4\x04\xd5\xb7\xb5\xf5\x01\x07\x07\x07\x94\ \x07\x42\xa1\x10\x04\x41\x40\x47\xc7\x1d\x8d\x9d\x9c\xe4\x35\x8f\ \x14\x0a\x85\x42\xad\x77\x01\x01\x00\x51\x14\xab\x2a\xc3\xd9\xd9\ \x17\x18\x1e\x7e\x42\x9d\x03\xe5\x21\x00\x40\x6e\x42\x19\xe6\xae\ \x5b\xc0\x69\xcd\x65\x18\x8d\x7e\xc1\xd4\x94\x97\x62\x6b\x6b\x6b\ \xc8\x64\x32\xd4\x23\x65\x67\x67\x07\x1b\x1b\x1b\xb0\x5a\xc5\xb2\ \x1c\xc8\xa1\xb7\xb7\xaf\xb1\x73\xe0\x4f\x65\xe8\xf3\xd5\x5e\x86\ \x7f\xef\x51\xac\xaa\x2a\x14\x45\xa1\x58\x26\x93\x86\xa2\x28\x20\ \xa4\x94\xd8\x47\x47\x47\x88\x44\xf6\xc0\xf3\x5c\x73\x8f\xe2\xa1\ \xa1\xc7\xd8\xdc\xdc\xa2\xd8\xbd\x7b\xf7\x11\x0e\xef\x82\x61\x4a\ \x0e\x6c\x6b\x33\xa3\x58\x2c\x62\x6f\xaf\xf4\x7c\x23\x84\x60\x70\ \x70\xb0\x31\x01\x16\x8b\x05\x16\x8b\xe5\xca\x42\xc0\x54\xba\x0b\ \xae\x2b\x07\x58\xbf\xdf\xaf\x67\x59\x36\xdb\xac\x85\x82\xc1\xa0\ \xa9\x96\x5f\x33\x2b\x80\x07\x57\xb0\xe1\x57\xf8\x6f\xbf\xd8\x77\ \x00\xaf\x8a\xb7\x13\x1e\xff\xdc\x00\x00\x00\x00\x49\x45\x4e\x44\ \xae\x42\x60\x82\ \x00\x00\x04\x8f\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdb\x02\x0c\ \x12\x05\x1e\x1c\xe1\x14\xac\x00\x00\x04\x0f\x49\x44\x41\x54\x58\ \xc3\xed\x97\x6d\x4c\x5b\x55\x18\xc7\x7f\xb7\xa5\x2f\x12\x4c\x80\ \x05\x18\xf2\x96\x30\x43\x8c\xce\xe1\x52\xb7\x65\x80\x8c\x81\x89\ \x19\xa0\xdb\x40\x5c\x58\x5c\x86\xdb\x3a\x93\x05\x0d\xd6\xfa\x69\ \xb2\x2c\xc6\x14\x32\x08\x6e\x66\xb2\x06\x22\x83\xcd\x44\x4c\x1c\ \x08\x1f\x20\x23\x71\x13\x32\x56\x0d\xd0\x61\x30\x08\x86\x4d\x13\ \x5e\x4a\xab\xbc\x49\x1c\x14\x5a\x8e\x1f\xa4\x5d\xd9\x84\x22\x05\ \xfd\xe2\x3f\xb9\xc9\x7d\xee\x3d\xcf\xfd\xff\xf3\x3c\xff\x73\xee\ \x39\xf0\xef\x42\x4a\x48\x20\x9b\xff\x0a\x5a\x2d\x9f\x98\x4c\x4c\ \x66\x65\xf1\xaa\x5b\xd1\x83\xd7\x7e\x45\xe0\x97\xea\x99\x90\x96\ \xb6\x27\x2c\x35\x35\x65\x93\x2f\xa4\xf5\xf5\x0d\xd6\xce\xce\xee\ \xb1\xad\x5b\x9d\xe1\x0d\x0d\xf3\x11\xd1\xd1\xc8\x62\x63\xf9\x79\ \x70\x90\x74\xa0\xcf\xef\xc1\x50\x79\x10\xc8\x76\x7a\x26\x07\x06\ \x06\x92\x96\xb6\x77\x45\x82\x4f\xab\xaa\x68\x6b\x6b\x73\xc7\xcf\ \x6e\xdb\x86\x5e\xa7\x73\xc7\x2d\x2d\x5f\x07\x44\x45\x89\x2d\x15\ \x15\x0e\x62\x63\x41\xa3\x91\x18\x1c\x14\x31\x40\x35\xb0\xc7\xcf\ \xd7\xb2\x8e\x8f\x8f\xd3\xdf\xd7\xe7\x8e\x23\x23\x23\x97\x36\x5d\ \x9a\xa2\xb8\x78\x8e\xdd\xbb\x05\x99\x99\x12\x66\xb3\x00\x90\x01\ \xa3\x80\x43\xb6\x91\x3d\x9f\x98\xb0\xb2\x7f\x7f\x1f\x87\x0f\x0b\ \xf4\x7a\x89\xa6\x26\xb7\x2c\x2b\x90\x07\x38\x37\x4c\xc0\xec\xec\ \x0c\x23\x23\x67\x28\x28\x98\xe6\xea\x55\x89\x0b\x17\x40\x08\xb1\ \x68\x3b\xc5\x4d\x60\xd2\x55\x8a\x75\xc7\xc2\xc2\x02\x1d\x1d\x67\ \x38\x7a\xf4\x7b\x4c\x26\x39\x5a\x2d\x38\x1c\x2e\x72\x15\x20\x4d\ \xb9\xc6\x6e\x88\x80\xae\xae\xf3\x9c\x3a\x75\x8b\x89\x09\x89\x03\ \x07\x14\xd8\xed\x2e\x72\xe5\x23\x94\x3e\x9b\x30\x2e\x2e\x8e\xf4\ \xf4\x74\x77\x1c\x15\x35\x41\x4e\x4e\x2b\x4a\xa5\x20\x39\x79\x33\ \x36\xdb\xa8\x07\x95\xfc\x91\xfc\x15\x05\xf4\xf6\xf6\x53\x56\xf6\ \xb1\x57\x11\x01\x01\x81\x00\x38\x9d\xbf\xa0\xd5\x76\x12\x16\x36\ \x8f\x46\xe3\x8f\xd9\xec\x49\xae\xf0\xf6\x19\x95\x11\xfc\xc5\x5a\ \xaf\xe0\x60\xb5\xa8\xab\x93\x84\x10\x88\x8c\x0c\x49\x00\x8b\x97\ \xfc\x6f\xc6\xab\x8c\xeb\xea\x01\xb5\x5a\x70\xfa\xb4\x9d\x83\x07\ \x05\xf9\xf9\x32\x8f\xe9\x26\x5f\x34\xdd\xf2\xf0\x59\x80\x24\xc1\ \xb1\x63\x73\xe8\x74\x82\xf2\x72\x09\xa3\x51\x2c\x4e\x37\xd9\xa2\ \xe9\xd8\x58\x01\x87\x0e\xd9\xb9\x78\xd1\x49\x7b\x3b\xe8\x74\xe0\ \x74\x7a\x3a\x5e\xf2\x9a\xbf\xac\x09\x13\x12\x76\x92\x92\x92\xbc\ \x62\xf2\xf4\x74\x23\xc5\xc5\xdd\x58\x2c\x12\x39\x39\x01\xd8\xed\ \xd3\xa8\xd5\x6a\x32\x33\x5f\x21\x2e\xee\x29\x00\x1c\x8e\x79\xce\ \x9d\x3b\xbf\x1a\x31\x4b\x4d\x78\xfc\xf8\x9b\x62\x25\x34\x36\x7e\ \x28\x6c\x36\xa5\x98\x9d\x45\x68\x34\x91\x02\x10\x0a\x85\x42\x94\ \x94\x94\x2c\x19\x37\x39\x39\x29\xe0\xb1\x65\x4d\xe8\x75\x1d\x58\ \xb0\x58\x10\x33\x33\x4b\x9e\xb5\x99\xbf\xe4\x99\xe7\x8a\x08\x09\ \x99\x23\xe3\xa5\x27\x30\x9b\x87\x91\x24\x89\x93\xb9\xb9\xbc\x93\ \x95\x85\xf3\xde\x3d\x90\xcb\x91\xc7\xc4\xac\xbd\x05\x2e\xd8\xee\ \x74\x63\x1f\x1b\x73\xc7\x3f\x5a\x7a\x79\x7c\x47\x39\xb1\x4f\xfe\ \x41\x6e\x56\x10\x2d\x37\xac\x08\x21\xc8\xdc\xb5\x0b\x7d\xda\x8b\ \x0c\xb5\xdf\xfe\xcb\xff\x0a\x05\x91\xd1\xd1\xbe\x0b\xd8\x9c\xbe\ \xcf\x7d\x3f\x3c\x3c\x80\xb2\xdf\x40\xe2\xde\x29\xce\x9e\x0d\xa5\ \xf9\xc6\x2c\x0e\x87\x93\xa4\xa4\x24\xbe\xb8\x7e\x1d\x7f\x7f\xff\ \x7f\x6c\xe2\x55\xcf\x82\xbb\x77\x7f\xe2\x83\xc2\x97\x51\x29\x07\ \xb8\x7c\x39\x18\xa3\x71\x81\xa9\xa9\xdf\x89\x8f\x8f\xa7\xb6\xb6\ \x76\x4d\xe4\xab\xaa\xc0\x68\x75\x35\x8e\x91\x11\xde\x6f\xaa\xa7\ \xf0\xc4\x5b\x74\x34\xf7\x50\xf2\xd9\x57\x58\xad\xa3\x44\x07\x05\ \x51\x94\x98\x88\xa8\xa9\x61\xe8\xe1\xf5\xc1\x4f\x41\xc4\x7b\xfa\ \x75\x68\x41\x5e\x1e\x42\x08\x9e\xb6\x0e\x11\x1a\x18\x48\xc6\x8e\ \x17\xb8\xf6\x8d\x99\xd1\x69\x3b\x65\x95\x95\xec\xcb\xf6\x6d\x93\ \xbb\xaa\x16\x7c\x6b\x32\xb1\x3d\x3c\xcc\x1d\x87\x6f\x0a\xc6\x60\ \x30\x90\x9d\xed\xfb\x0e\xdb\x6b\x05\xac\x35\x57\x68\x6e\xb8\x46\ \xfe\x91\xd7\x00\xa8\x6b\xbd\xc5\xf0\xc8\x28\x85\xe3\xe3\x0c\x19\ \x0c\xcb\x27\x2a\x55\x44\xea\xdf\xf5\x5d\x40\xc8\x91\xd7\x51\x9a\ \xbf\x63\xf0\xd7\xdf\xa8\xb9\xdd\x41\xce\x1b\x27\x38\xf9\x51\xf9\ \xba\x6d\x5e\xbc\x0a\x68\x6d\xbd\x49\x57\xcf\x0f\x28\x43\xc2\x28\ \xad\xa8\x42\xa9\x54\xb2\x9e\xf0\x2a\xa0\xe7\xf3\x5a\x0a\xb6\x3f\ \xcf\x16\x99\x1f\xb6\xd2\xd2\xd5\xff\x25\x55\x2a\x22\x3c\xce\x07\ \x6b\x16\xf0\x76\x45\xe5\x86\x1e\xd7\x3c\x04\x38\x07\x80\x3a\x57\ \x64\xb1\x58\x62\x2e\x5d\x32\x86\xfa\x4a\x70\xff\xfe\xac\x04\x0b\ \x77\x80\xf9\x87\xb8\xfe\x07\x00\x7f\x02\xa3\x27\xb0\x0f\xab\x70\ \x14\x29\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x02\x27\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xda\x05\x01\ \x0f\x34\x39\xe0\x5e\x41\x3e\x00\x00\x01\xa7\x49\x44\x41\x54\x58\ \xc3\xed\x97\x3f\x4b\xc3\x50\x14\xc5\x7f\x36\xad\x41\x71\xa8\x08\ \x2a\x18\xec\xa0\x06\x2a\xd4\xd1\xa1\x83\xd6\x76\xb2\x1f\x42\x0b\ \x1d\xea\xac\x75\xf0\x13\x08\x0e\xe2\x66\x1d\x14\xf5\x03\x28\xae\ \x82\x4b\x27\x85\x42\xbb\x55\xc5\x45\xb0\xc6\x0a\x2d\x9d\xfc\x97\ \xd4\x38\xa8\x6d\x2c\xa2\xc6\x57\x74\x48\x0f\x04\x72\xf2\x72\xdf\ \x39\x79\xf7\xbe\x9b\x04\x9c\x8e\xb6\xfa\xa9\x7b\x19\xdc\x61\xeb\ \x60\x24\x32\xd9\x17\x0e\x87\x7a\x44\x04\xf6\xf7\x0f\x8a\x99\x4c\ \xae\xf4\x46\x0d\xa8\x1e\x83\xbe\x04\x3c\x01\xb8\xeb\xb7\x4a\xdd\ \xe0\x1a\xb7\x06\x7b\xbd\x5e\x22\x91\xa9\x2f\x05\x36\xb7\xb6\x48\ \xa7\xd3\x35\x1e\x18\x1b\x23\x39\x3f\x5f\xe3\x87\x87\x47\x5d\xe0\ \x1a\xaa\x47\xb8\x82\x60\x16\xc0\x58\x6d\x30\xf0\x3b\x94\xcb\x65\ \xce\x4e\x4f\x6b\x5c\x51\x94\x1f\x44\x49\x2a\x18\xaf\x76\xfe\xbb\ \x06\x5a\x06\xfe\xdd\x80\x70\x11\xaa\xaa\x4a\x34\x1a\xad\xf1\xe1\ \x91\x91\xdf\xf6\x01\x39\x05\x52\xc2\x3a\xe8\xf7\xab\x04\x02\xa3\ \x42\x06\x4f\x4e\x32\x5c\x5e\x5e\x35\x5c\xad\x6e\xc0\xe3\xdc\xb7\ \x2b\x90\xcf\x9f\x93\xcf\x9f\xb7\x8a\xd0\xa1\xbb\x20\x18\x1c\x27\ \x14\x9a\x10\x16\x30\x0c\x9d\x95\x95\xb5\x8f\xf5\xfe\x39\xe4\x14\ \x74\x9a\xef\x47\x3c\x9e\x30\x9b\x81\x4a\xa5\x62\x42\x87\x69\x9d\ \xfb\x55\xeb\x87\x7d\xe0\x59\xd3\x30\xef\xef\xed\x3f\xba\x24\x21\ \xf9\x7c\xe2\x8d\xe8\x36\x9b\xe3\xb1\x54\xb2\xaf\xef\xf1\xa0\x0c\ \x0e\x8a\x1b\xe8\x8f\x4e\x3b\xfc\x5d\x70\xb3\xbd\x8d\x71\x7d\x6d\ \xff\x5b\xcf\xed\x61\x60\x31\xd9\x84\x14\xc4\x62\x0e\x4f\x41\x71\ \x67\x17\xbd\x70\x65\x7f\xe6\x76\x19\x25\xb9\x20\x6e\xa0\x6f\x76\ \xc6\xf1\x29\xd8\x41\x2f\x14\xec\xef\x02\x59\x66\xc0\xf2\x7f\x20\ \x90\x82\xd9\xbf\x5a\x81\xea\x05\xb0\xf7\xce\x34\x4d\xf3\xad\xaf\ \xa7\x7a\x45\x05\xee\xee\x1e\xda\xe0\x39\x0b\xe8\x0d\x5a\x2d\x00\ \xf0\x02\x83\xf6\xbb\x15\x02\x7f\xf1\x4b\x00\x00\x00\x00\x49\x45\ \x4e\x44\xae\x42\x60\x82\ \x00\x00\x06\x5d\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ \x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ \x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\ \x42\x28\x9b\x78\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdb\x02\x0a\ \x01\x29\x0d\x9a\x65\x7c\x29\x00\x00\x05\xdd\x49\x44\x41\x54\x58\ \xc3\xed\x97\x5f\x68\x5b\xd7\x1d\xc7\x3f\x57\xba\xb2\xa4\xf8\x4f\ \xd5\x49\xb6\x6b\xe5\x8f\xab\xfc\x69\xeb\x96\xa6\x90\xc4\xc9\x93\ \xad\xb0\x95\x41\xa1\xd0\x16\xda\xa6\x7b\x48\xc9\x06\x0d\xcd\xdb\ \x68\x58\x17\xf2\x12\xf6\x30\xc6\x60\xdd\xcb\x1e\xea\xb1\x52\x88\ \x61\x10\xb6\x35\x26\x24\x83\x6e\x2f\xdb\x9a\x85\xad\x24\x34\x29\ \xa6\x75\x42\xe2\xd4\x9e\x63\x2b\x92\x6c\x59\xbe\x92\xae\xae\xee\ \x3d\xf7\x9c\x3d\x1c\x29\xfa\x63\x07\x4a\x9b\x6e\x2f\x3d\xf0\xe3\ \x1e\x5d\x5d\x9d\xef\xe7\xf7\xe7\xfc\xee\x11\x7c\xf5\x31\x06\x18\ \xfc\x9f\xc6\xfe\x58\x2c\xe6\x6c\xdf\xbe\xfd\xf6\xe6\xcd\x9b\x7f\ \x0e\x0c\xfe\x4f\xd5\x53\xa9\xd4\xf9\x99\x99\x19\x25\x84\x50\xe7\ \xce\x9d\x13\xe3\xe3\xe3\x4b\xa9\x54\xea\x1f\xa6\x69\x7e\x1f\x08\ \x7c\xd3\xfa\x7d\x7b\xf6\xec\xb9\xa3\x3a\xc6\xc2\xc2\x82\x3a\x71\ \xe2\x44\x71\xe7\xce\x9d\xb7\x93\xc9\xe4\x2f\x80\xa1\x6f\x44\x3d\ \x91\x48\xbc\x35\x39\x39\x59\x53\xf7\x19\x42\x08\x75\xfe\xfc\x79\ \x3f\x9d\x4e\x2f\xa6\x52\xa9\x8b\xe1\x70\xf8\xb9\x07\x1a\x95\x54\ \x2a\x75\xa3\x5a\xad\x2a\xa5\x94\x9a\x9a\x9a\x52\x8e\xe3\xdc\x8f\ \x45\x2d\x2e\x2e\xaa\x93\x27\x4f\x16\x77\xec\xd8\x31\x97\x4c\x26\ \x7f\x09\x0c\x74\xae\xb7\xbe\x8a\x07\x77\xa7\x88\xc5\x8f\x11\xe9\ \xeb\x23\x10\x02\xa3\x05\x7e\x6d\x71\xe0\x87\x07\x47\x9e\x7b\xff\ \xbd\xdf\x45\xae\x5c\xb9\x4c\x2e\x97\x23\x9b\xcd\xe2\x79\x82\xb1\ \xb1\x31\x46\x46\x46\x36\x84\x96\x52\x32\x31\x31\x21\x4f\x9d\x3a\ \x65\x2f\x2f\x2f\xc7\x00\xbf\xf1\x9d\xd9\xf1\x6c\x90\x81\x6d\x7f\ \x64\xcb\xee\xbd\xf4\xc4\xc1\x8c\xb4\x01\x0c\x5e\xff\x80\x9f\x1c\ \x7f\x0b\x80\xcb\x97\xaf\x70\xec\xd8\x9b\x00\x28\xa5\xb8\x78\xf1\ \x22\x93\x93\x93\x0c\x0c\x0c\x70\xf4\xe8\x51\xba\xbb\xbb\xef\xfd\ \x2e\x10\x08\x90\xc9\x64\x02\xe9\x74\xba\xfb\xda\xb5\x6b\x7f\x9a\ \x9d\x9d\x7d\x69\x63\x80\x2d\x07\x9e\x62\xf0\xb1\xbd\xc4\x87\xa1\ \xa7\x1f\x42\xe1\x66\x90\x5c\x9b\xc1\xb0\xcf\xc8\xc8\x08\xe5\x72\ \x99\xde\xde\x9e\x66\x18\x0d\x83\xf1\xf1\x71\xa6\xa6\xa6\x78\xfd\ \xf5\xc3\x9c\x3d\xfb\x01\x95\x8a\xcd\xe8\xe8\x3e\xf6\xee\xdd\x87\ \x94\x92\x4c\x26\xc3\xc1\x83\x07\x8d\x62\xb1\xf8\x7c\x3e\x9f\x3f\ \x60\x59\xd6\xc7\xeb\x01\x22\xd1\x4d\x44\xfb\x20\xfa\x90\x36\x33\ \x7c\x4f\x3f\x7a\xfb\xef\xfc\xf8\xcd\x1f\x01\x70\xe6\xcc\x19\x66\ \x66\x66\xb8\x79\xf3\x26\xc7\x8f\x1f\xa7\xaf\xaf\x0f\xdf\xf7\x89\ \xc7\x13\xc4\xe3\x71\x0e\x1f\x3e\x5c\x8f\xd2\x65\x8e\x1c\x39\xc2\ \xb6\x6d\xdb\x88\xc5\x62\x24\x12\x09\x0e\x1d\x3a\x64\xe6\x72\xb9\ \xbf\x4e\x4f\x4f\x7f\x07\xf0\xcd\x75\x09\x0b\x86\xb4\x05\x82\xda\ \x0c\x4d\x10\x5f\xf8\x27\x3f\x78\xf5\x67\x00\x08\x21\x78\xe7\x9d\ \x5f\xb1\xb2\xb2\xc2\xe9\xd3\xa7\xf9\xe2\x8b\x39\x2c\xab\xc8\xdb\ \x6f\xff\xb4\x6d\xa9\xd1\xd1\x51\xb6\x6e\xdd\x8a\x6d\xdb\x64\x32\ \x19\x2c\xcb\x22\x12\x89\x90\x4e\xa7\xfb\x6c\xdb\x3e\x3b\x3b\x3b\ \xfb\x82\x5e\x7d\x78\x77\x8a\x50\xf4\x35\xba\x36\x3d\x4a\xff\xae\ \xa3\xf4\x24\x20\xbc\x09\x02\x75\x3e\x2b\xc7\x33\xc1\x25\x5e\x7e\ \xe1\x79\xf2\xf9\x3c\x95\x4a\x99\x47\x87\x87\x01\xe8\x4f\xc4\x09\ \x06\x83\x4c\x4c\xfc\x96\xe4\xd0\x10\xbe\xef\xf3\xec\xb3\xdf\xa3\ \xb7\xa7\x97\xab\x9f\x5c\x25\x1a\x8d\xf0\xc4\xe3\xbb\xc8\x65\xef\ \xf2\xf1\xbf\xfe\x4d\x36\xb3\x44\xb2\xff\x61\xe6\x6f\x5d\x17\xd3\ \xd3\xd3\x63\x06\x43\x23\xc3\xec\x4a\xcf\xb1\x6f\x3f\xc4\xfa\x21\ \x1c\xd6\x5e\x2b\xb4\x49\xd6\xcf\x01\xa4\xd2\xa6\x14\x48\xd9\xfe\ \x9c\xdf\x6a\x1e\x54\xd7\xc0\x5e\x05\xe1\xea\x79\x61\x81\xc7\x6b\ \xd7\x99\x9f\xf9\xd4\x31\x09\x85\x5e\xe4\x99\xa7\x61\xcb\x13\x10\ \x7f\x04\x22\x11\x9d\xf7\x4e\x51\x7f\x23\xa0\x06\x40\xcb\x3d\x51\ \x7f\xd6\x03\x84\xa7\x45\x4b\x59\xb0\x36\xe9\x79\x57\x14\xcc\x10\ \x6b\xb7\x66\x48\x24\x12\x25\x93\x68\xef\x87\xb8\xbd\x10\x7d\x18\ \xba\xe3\x1a\xc0\x6c\x69\x0f\xad\x1e\x35\x00\x64\x23\x02\x1d\xa0\ \xb2\x2e\xec\x01\x41\x0f\x6a\xe5\x7a\xc4\x0c\x90\x02\xa4\x07\xbe\ \x0f\x0a\x86\x06\xfa\x29\x54\xb2\x7f\x31\xb9\x71\xe9\x06\x3b\xbf\ \x0b\x4f\x1f\x00\x69\x82\x0c\x81\x32\x20\xd8\xd1\xae\x8c\x16\x98\ \x40\x2b\x48\x4b\x5b\xb9\x97\x82\x1a\xb8\x36\x38\x25\x0d\x51\xca\ \x43\x79\x05\x3c\x07\xaa\x16\x38\x45\xaa\xa5\x62\x75\x7e\x7e\xfe\ \xd7\xba\xca\x96\xe7\xc0\xf5\xc0\xf3\xc1\x54\x10\x30\xda\xfb\xa4\ \xea\x10\xe8\xf4\xda\xaf\x87\x5e\x02\x42\x42\xad\x02\xb5\x12\x38\ \x96\x86\x70\x2c\x6d\x6e\x55\x5f\xcb\xcb\xac\xe6\x96\x56\x81\xab\ \x1a\xc0\x5e\x5e\xc2\x76\x92\x38\x3e\x04\x55\xb3\x45\x19\x2d\x10\ \x72\x03\xaf\xfd\x8e\x9c\xfb\x42\x0b\xda\xab\x4d\xab\xae\xe9\x08\ \x54\x56\x75\x1a\x5c\x1b\x56\xfe\x03\xae\xfd\x7e\xb3\x11\xf9\xf2\ \x12\x65\xfb\x15\x2a\x1e\x18\x4a\x2f\x68\xa2\xd3\x60\x74\xd4\x82\ \xea\x10\xf6\x01\xcf\x03\xaf\x06\x5e\xb5\x29\x5c\x5e\x81\x4a\x41\ \x03\x94\x97\xeb\x6b\x28\x50\x12\xec\x22\xd9\x6c\xf6\xdd\x26\x80\ \xf0\x3e\xa2\x52\x7e\x05\xa7\x06\x5d\x52\x3f\xec\x35\x1a\x79\x0b\ \x80\x68\x89\x80\x70\xc1\x77\xf5\xd5\xb5\x75\x78\x3d\x1b\xec\xa2\ \x16\x2e\xe7\xeb\xe1\x2f\xd1\x56\xd1\x52\x82\x5b\x01\x58\x6a\x02\ \x84\xa3\xbf\xe7\xce\xb5\xdf\x90\x48\x41\x57\x2f\x08\xd5\x4c\xbc\ \x92\xda\xfc\xfa\x96\x92\x3e\x88\x9a\x9e\x0b\x47\x0b\xbb\xb6\xbe\ \xe7\x55\xeb\x00\x2b\x3a\xe4\x4a\xb6\x8b\x2b\x05\x52\x60\xf8\xde\ \x1d\xd5\xf6\x32\x9a\xfe\xf3\x2a\x3d\x71\x4d\x1e\xec\xd2\xad\x58\ \xf9\x9a\xd6\xf7\xb4\x90\xe7\xe8\x1c\x7b\x8e\xf6\xd4\xf7\xb4\xb0\ \xe7\xd4\xa3\x51\xff\xec\x58\x5a\xa8\x73\x28\xa5\xe1\x7d\x0f\x85\ \xf1\xb7\xf5\x6f\xc3\xc2\x82\xce\x57\x28\xa2\xdf\x01\x9e\xd3\x6e\ \xae\xad\x3d\x74\xab\xda\xdb\x46\x41\x79\xce\x97\x3c\xca\x28\xed\ \x94\xa8\x81\x34\x3e\x5a\x0f\xe0\x55\x3f\xc7\x2e\x3e\x49\x28\xa2\ \x2b\xaf\x56\xd2\xdb\xa9\x21\xea\x94\xf4\xfc\x4b\x0b\x76\x78\xdf\ \x68\xd9\x95\x02\x04\x4b\x7f\x58\x0f\x20\xdc\x4b\xd8\x85\x27\x31\ \xc3\xfa\x73\x03\xc0\xb5\x75\x33\xf9\x2a\xc2\xeb\x40\xf4\x0e\xa0\ \x50\xb0\x36\x88\x80\xff\x21\xcb\x73\x6f\x20\x5c\x4d\x5b\x5d\xd3\ \xe1\x7a\x50\x43\x49\x5d\x03\xb5\x4a\xdb\xed\x26\x40\x46\x5c\x20\ \xfe\xb9\x3e\x82\x29\xd9\x3c\x8a\x19\x5f\xf3\xcf\x8f\x52\xcd\xed\ \x27\x05\x08\x77\x69\x63\x00\x3e\x73\x59\x0b\x43\x7c\x58\x8b\x07\ \xbb\xbe\xbe\x78\x6b\xfe\x45\x4d\xd7\x92\x12\x57\xef\x03\x00\x94\ \xf3\xb7\xa9\x14\xb6\x13\xec\x02\xb3\x01\xf0\x00\x22\xa0\x7c\x2d\ \x6e\xdd\x05\x5f\x4c\xdc\x1f\x40\xc8\xfd\xe4\x6f\xcd\x32\xf4\xd4\ \x43\x1a\x20\x50\x4f\x45\xcb\x01\x41\x29\x7d\x56\x54\x2d\xcd\x4a\ \xca\x66\xdf\x90\xa2\xe5\x5a\xb7\x5a\x45\x77\x46\xeb\xee\x05\x4a\ \xd9\x0b\x7c\x3b\x5a\xc6\x7f\x01\x3d\xc4\x81\x26\x03\xd0\x2d\x2c\ \x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ " qt_resource_name = "\ \x00\x08\ \x07\x3f\xad\x53\ \x00\x71\ \x00\x74\x00\x2d\x00\x69\x00\x63\x00\x6f\x00\x6e\x00\x73\ \x00\x0a\ \x05\x26\x31\x13\ \x00\x6f\ \x00\x70\x00\x65\x00\x6e\x00\x6c\x00\x61\x00\x79\x00\x65\x00\x72\x00\x73\ \x00\x04\ \x00\x06\xfa\x5e\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\ \x00\x0f\ \x0b\xfb\xb1\x53\ \x00\x71\ \x00\x74\x00\x2d\x00\x74\x00\x72\x00\x61\x00\x6e\x00\x73\x00\x6c\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\ \x00\x08\ \x0a\x60\x7a\x7d\ \x00\x71\ \x00\x74\x00\x5f\x00\x69\x00\x74\x00\x2e\x00\x71\x00\x6d\ \x00\x07\ \x07\x0f\x38\x93\ \x00\x70\ \x00\x69\x00\x78\x00\x6d\x00\x61\x00\x70\x00\x73\ \x00\x0e\ \x07\x2d\xfd\x67\ \x00\x63\ \x00\x79\x00\x63\x00\x6c\x00\x6f\x00\x67\x00\x72\x00\x61\x00\x70\x00\x68\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x0c\ \x0e\x77\x9f\x87\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x5f\x00\x6d\x00\x61\x00\x70\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0c\ \x0a\x53\x9f\xe7\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x5f\x00\x61\x00\x64\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0d\ \x0c\x2b\xda\x07\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x5f\x00\x70\x00\x6c\x00\x6f\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0d\ \x0b\x9e\xdd\xe7\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x5f\x00\x69\x00\x6e\x00\x66\x00\x6f\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0f\ \x00\x2e\xb9\x87\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x5f\x00\x64\x00\x65\x00\x6c\x00\x65\x00\x74\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0e\ \x07\x2d\xf0\xe7\ \x00\x63\ \x00\x79\x00\x63\x00\x6c\x00\x6f\x00\x67\x00\x72\x00\x61\x00\x70\x00\x68\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0f\ \x03\x56\x62\x87\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x5f\x00\x6d\x00\x6f\x00\x64\x00\x69\x00\x66\x00\x79\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0d\ \x01\x73\xdc\x47\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x5f\x00\x63\x00\x6b\x00\x6d\x00\x6c\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0a\ \x03\x53\xd7\x28\ \x00\x63\ \x00\x79\x00\x63\x00\x6c\x00\x6f\x00\x67\x00\x72\x00\x61\x00\x70\x00\x68\ \x00\x0e\ \x07\x22\xe3\xf3\ \x00\x64\ \x00\x72\x00\x61\x00\x77\x00\x5f\x00\x6f\x00\x6e\x00\x5f\x00\x6d\x00\x61\x00\x70\x00\x2e\x00\x6a\x00\x73\ \x00\x08\ \x08\x34\xf5\x5c\ \x00\x6d\ \x00\x61\x00\x70\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ \x00\x0f\ \x02\x00\x3d\x1c\ \x00\x6f\ \x00\x70\x00\x65\x00\x6e\x00\x6c\x00\x61\x00\x79\x00\x65\x00\x72\x00\x73\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ \x00\x0a\ \x0e\x2d\x86\x03\ \x00\x67\ \x00\x6f\x00\x6f\x00\x67\x00\x6c\x00\x65\x00\x2e\x00\x63\x00\x73\x00\x73\ \x00\x07\ \x04\xca\x57\xa7\ \x00\x6e\ \x00\x65\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0b\ \x05\x79\x4e\x27\ \x00\x73\ \x00\x61\x00\x76\x00\x65\x00\x5f\x00\x61\x00\x73\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x08\ \x08\xc8\x58\x67\ \x00\x73\ \x00\x61\x00\x76\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x08\ \x06\xc1\x59\x87\ \x00\x6f\ \x00\x70\x00\x65\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ " qt_resource_struct = "\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x01\ \x00\x00\x00\x30\x00\x02\x00\x00\x00\x01\x00\x00\x00\x10\ \x00\x00\x00\x16\x00\x02\x00\x00\x00\x01\x00\x00\x00\x0b\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x06\ \x00\x00\x00\x3e\x00\x02\x00\x00\x00\x01\x00\x00\x00\x05\ \x00\x00\x00\x62\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x00\x78\x00\x02\x00\x00\x00\x04\x00\x00\x00\x07\ \x00\x00\x02\x44\x00\x00\x00\x00\x00\x01\x00\x00\xb8\xe3\ \x00\x00\x02\x58\x00\x00\x00\x00\x00\x01\x00\x00\xbc\x5c\ \x00\x00\x02\x8a\x00\x00\x00\x00\x00\x01\x00\x00\xc3\x1a\ \x00\x00\x02\x74\x00\x00\x00\x00\x00\x01\x00\x00\xc0\xef\ \x00\x00\x01\xb4\x00\x02\x00\x00\x00\x04\x00\x00\x00\x0c\ \x00\x00\x02\x06\x00\x00\x00\x00\x00\x01\x00\x00\xb2\xfd\ \x00\x00\x01\xce\x00\x00\x00\x00\x00\x01\x00\x00\x9e\x5d\ \x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x00\xab\x09\ \x00\x00\x02\x2a\x00\x00\x00\x00\x00\x01\x00\x00\xb7\xfa\ \x00\x00\x00\x78\x00\x02\x00\x00\x00\x09\x00\x00\x00\x11\ \x00\x00\x01\x2a\x00\x00\x00\x00\x00\x01\x00\x00\x84\x21\ \x00\x00\x01\x94\x00\x00\x00\x00\x00\x01\x00\x00\x95\x0d\ \x00\x00\x01\x70\x00\x00\x00\x00\x00\x01\x00\x00\x8f\x37\ \x00\x00\x01\x4e\x00\x00\x00\x00\x00\x01\x00\x00\x88\x95\ \x00\x00\x00\x8c\x00\x01\x00\x00\x00\x01\x00\x00\x59\x56\ \x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00\x77\x38\ \x00\x00\x01\x0a\x00\x00\x00\x00\x00\x01\x00\x00\x7f\xa1\ \x00\x00\x00\xea\x00\x00\x00\x00\x00\x01\x00\x00\x7c\x37\ \x00\x00\x00\xae\x00\x00\x00\x00\x00\x01\x00\x00\x70\x6a\ " def qInitResources(): QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) def qCleanupResources(): QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) qInitResources() �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cyclograph-1.6.1/cyclograph/qt/__init__.py����������������������������������������������������������0000644�0001750�0001750�00000000000�12065361217�022115� 0����������������������������������������������������������������������������������������������������ustar �federico������������������������federico������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������cyclograph-1.6.1/cyclograph/qt/gui.py���������������������������������������������������������������0000644�0001750�0001750�00000106424�12231301360�021147� 0����������������������������������������������������������������������������������������������������ustar �federico������������������������federico������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- """qt.gui.py""" # Copyright (C) 2009, 2010, 2011, 2012, 2013 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from __future__ import unicode_literals from PyQt4 import QtGui, QtCore import ui_qt import glal import os.path from themes import ThemeManager from version import VERSION import StringIO if QtCore.PYQT_VERSION >= 0x040700: iconFromTheme = QtGui.QIcon.fromTheme else: #define fallback method if using an odl version of Qt def iconFromTheme(_, icon=None): if icon == None: icon = QtGui.QIcon() return icon class Gui(QtGui.QMainWindow, ui_qt.Ui_MainWindow): """Main frame""" def __init__(self, parent, title, size): QtGui.QMainWindow.__init__(self, parent) self.setupUi(self) self.setWindowTitle(title) self.notebook.removeTab(0) self.cg_exit = None #check on exit callback self.setContextMenuPolicy(QtCore.Qt.PreventContextMenu) self.resize(QtCore.QSize(size[0], size[1])) # center Gui screen = QtGui.QDesktopWidget().screenGeometry() dimension = self.geometry() self.move( (screen.width() - dimension.width()) / 2, (screen.height() - dimension.height()) / 2) if size[2]: self.showMaximized() ##Set standard icons icon1 = QtGui.QIcon(QtGui.QPixmap(":/qt-icons/pixmaps/open.png")) icon1 = iconFromTheme("document-open", icon1) self.menu_item_open.setIcon(icon1) icon2 = QtGui.QIcon(QtGui.QPixmap(":/qt-icons/pixmaps/save_as.png")) icon2 = iconFromTheme("document-save-as", icon2) self.menu_item_save_as.setIcon(icon2) icon0 = QtGui.QIcon(QtGui.QPixmap(":/qt-icons/pixmaps/save.png")) icon0 = iconFromTheme("document-save", icon0) self.menu_item_save.setIcon(icon0) icon3 = QtGui.QIcon(QtGui.QPixmap(":/qt-icons/pixmaps/new.png")) icon3 = iconFromTheme("document-new", icon3) self.menu_item_new.setIcon(icon3) icon_about = iconFromTheme("help-about") self.menu_item_about.setIcon(icon_about) icon_bug = iconFromTheme("tools-report-bug") self.menu_item_bug.setIcon(icon_bug) icon_exit = iconFromTheme("application-exit") self.menu_item_exit.setIcon(icon_exit) icon_server = iconFromTheme("network-server") self.menu_Kml_server.setIcon(icon_server) icon_pref = iconFromTheme("preferences-desktop") self.preferences.setIcon(icon_pref) #Group the altitude services to have radio button. serv_Action_group = QtGui.QActionGroup(self) serv_Action_group.addAction(self.menu_item_s1) serv_Action_group.addAction(self.menu_item_s2) serv_Action_group.addAction(self.menu_item_s3) self.connect(self.menu_item_about, QtCore.SIGNAL("triggered()"), self.onabout) def closeEvent(self, event): """If a close event is generated call the controller""" if self.cg_exit(): event.accept() else: event.ignore() def quit(self): """ Exit from CycloGraph""" self.close() def getdimensions(self): """Return window width and height""" return (self.size().width(), self.size().height()) def ismaximized(self): """Return true if window is maximized""" return self.isMaximized() def addstatusbartext(self, text): """Show text in the statusbar for 5000 ms""" self.statusbar.showMessage(text, 5000) def onabout(self): """About dialog""" description = """CycloGraph""" licence = """ CycloGraph is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CycloGraph is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. """ text = 'Copyright (C) 2008-2013 Federico Brega, Pierluigi Villani\n'+\ 'http://cyclograph.sourceforge.net\n'+ licence QtGui.QMessageBox.about(self, description +" "+ VERSION, text) class Page(QtGui.QFrame, ui_qt.Ui_Frame_Page): """Page showed in a tab""" def __init__(self, parent): QtGui.QFrame.__init__(self, parent) self.savedfilepath = None self.slopecounternew = 0 self.modified = False self.setupUi(self) def insert_row(self, row_num, cp): """Insert item to this page at position row_num""" self.tableWidget.insertRow(row_num) for col in range(len(cp)): item = QtGui.QTableWidgetItem(unicode(cp[col])) self.tableWidget.setItem(row_num, col, item) def delete_row(self, row_num): """Removes row at position row_num in this page.""" self.tableWidget.removeRow(row_num) def get_sel_row(self): """Gives the row number that is selected.""" row = self.tableWidget.currentRow() return row def get_sel_multi_row(self): """Gives a list with the row number of selected items.""" rows = [self.tableWidget.row(item) \ for item in self.tableWidget.selectedItems()] rows = list(set(rows)) rows.sort() return rows class Managecp(QtGui.QDialog, ui_qt.Ui_manag_dlg): """Add and edit dialog""" def __init__(self, parent, title, dist="", alt="", name=""): QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(title) self.distance.setText(dist) self.altitude.setText(alt) self.name.setText(name) def show_modal(self): """Shows the dialog and returns True if the value has to be chenged.""" val = self.exec_() return val == QtGui.QDialog.Accepted def destroy(self): """Destroy current managecp""" pass def getcp(self): """Gives the modified values.""" dist = self.distance.text() alt = self.altitude.text() name = self.name.text() return (dist, alt, name) class FormSlopeInfo(QtGui.QDialog, ui_qt.Ui_Slope_Dialog): """info dialog about the slope""" def __init__(self, parent, slopedata): QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.s_name.setText(slopedata['name']) self.s_state.setText(slopedata['state']) self.s_author.setText(slopedata['author']) self.s_email.setText(slopedata['email']) self.average_grad.setText(slopedata['average_grad']) self.max_grad.setText(slopedata['max_grad']) self.height_difference.setText(slopedata['height_difference']) self.height_gain.setText(slopedata['height_gain']) self.s_comment.setText(slopedata['comment']) def getslopeinfo(self): """Returns the slope infos: name, state, comment""" return {'name' : self.s_name.text(), 'state' : self.s_state.text(), 'author' : self.s_author.text(), 'email' : self.s_email.text(), 'comment' : self.s_comment.toPlainText()} FONT_TYP = { QtGui.QFont.Light : "light", QtGui.QFont.Normal : "normal", QtGui.QFont.Bold : "bold", QtGui.QFont.DemiBold : "bold", QtGui.QFont.Black : "bold", } class Preferences(QtGui.QDialog, ui_qt.Ui_Pref_Dialog): """Set gradient's color""" def __init__(self, parent, pref, default_pref): QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.default = default_pref #General self.olines.setChecked(pref['olines']) self.effect3d.setChecked(pref['3d']) self.showinfo.setChecked(pref['sinfo']) self.vcheck.setChecked(pref['vcheck']) res = 0 if pref['width'] == 1600: res = 3 if pref['width'] == 1280: res = 2 elif pref['width'] == 1024: res = 1 self.res.setCurrentIndex(res) current = 0 for theme in pref['themelist']: self.theme.addItem("") self.theme.setItemText(current, theme) if theme == pref['theme']: self.theme.setCurrentIndex(current) current += 1 self.serv.setCurrentIndex(0) if pref['serv'] == 'usgs.net': self.serv.setCurrentIndex(2) elif pref['serv'] == 'earthtools.org': self.serv.setCurrentIndex(1) elif pref['serv'] == 'google elevation': self.serv.setCurrentIndex(3) #Fonts self.fontbuttonlist = [self.fdesc, self.fgrad, self.ftitle] self.fontbuttongroup = QtGui.QButtonGroup(parent) for id_, button in enumerate(self.fontbuttonlist): self.fontbuttongroup.addButton(button, id_) desc = pref['fdesc'] self.fdesc.setText(desc['des']+' | '+str(desc["dim"])) self.fdesc.desc = desc desc = pref['fgrad'] self.fgrad.setText(desc['des']+' | '+str(desc["dim"])) self.fgrad.desc = desc desc = pref['ftitle'] self.ftitle.setText(desc['des']+' | '+str(desc["dim"])) self.ftitle.desc = desc self.connect(self.fontbuttongroup, QtCore.SIGNAL("buttonClicked(int)"), self.font_button_clicked) #Color group buttons self.buttonlist = [self.button1, self.button2, self.button3, self.button4, self.button5, self.button6, self.button7] self.buttongroup = QtGui.QButtonGroup(parent) for id_, button in enumerate(self.buttonlist): self.buttongroup.addButton(button, id_) self.colorlist = [ map(int, color[4:-1].split(',')) \ for color in pref['colors']] for index in range(len(self.buttonlist)): self.setcolor(index, self.colorlist[index]) self.connect(self.buttonBox, QtCore.SIGNAL("clicked(QAbstractButton *)"), self.restore_default) self.bindsgc() #Author info self.aname.setText(pref['aname']) self.amail.setText(pref['amail']) #Level group SpinButtons self.levlist = [self.lev_1, self.lev_2, self.lev_3, self.lev_4, self.lev_5, self.lev_6, self.lev_7] for i in range(len(pref['levels'])): self.levlist[i].setValue(float(pref['levels'][i])) self.levlist[i].editingFinished.connect(self.updatelevelconstraints) self.updatelevelconstraints() def restore_default(self, button): button_id = self.buttonBox.standardButton(button) if button_id == QtGui.QDialogButtonBox.RestoreDefaults: self.olines.setChecked(bool(self.default['orizzontal lines'])) self.showinfo.setChecked(bool(self.default['slopeinfo'])) self.effect3d.setChecked(bool(self.default['effect-3d'])) self.vcheck.setChecked(bool(self.default['vcheck'])) res = 0 if self.default['width'] == 1600: res = 3 if self.default['width'] == 1280: res = 2 elif self.default['width'] == 1024: res = 1 self.res.setCurrentIndex(res) index = self.theme.findText(self.default['theme']) if index: self.theme.setCurrentIndex(index) self.serv.setCurrentIndex(0) if self.default['server'] == 'usgs.net': self.serv.setCurrentIndex(2) elif self.default['server'] == 'earthtools.org': self.serv.setCurrentIndex(1) elif self.default['server'] == 'google elevation': self.serv.setCurrentIndex(3) self.fdesc.setText(self.default['font-des 1']+' | '+self.default['font-dim 1']) self.fdesc.desc = { "des" : self.default['font-des 1'], "typ" : self.default['font-typ 1'], "dim" : self.default['font-dim 1'] } self.fgrad.setText(self.default['font-des g']+' | '+self.default['font-dim g']) self.fgrad.desc = { "des" : self.default['font-des g'], "typ" : self.default['font-typ g'], "dim" : self.default['font-dim g'] } self.ftitle.setText(self.default['font-des t']+' | '+self.default['font-dim t']) self.ftitle.desc = { "des" : self.default['font-des t'], "typ" : self.default['font-typ t'], "dim" : self.default['font-dim t'] } self.aname.setText(self.default['authorname']) self.amail.setText(self.default['authormail']) colorlist = [ self.default["color "+str(i)] for i in range(1, 8) ] self.colorlist = [ map(int, color[4:-1].split(',')) \ for color in colorlist] for index in range(len(self.buttonlist)): self.setcolor(index, self.colorlist[index]) levellist = [self.default["level "+str(i)] for i in range(1, 8)] for i in range(len(self.levlist)): #disable range fot this widget self.levlist[i].setMinimum(0.0) self.levlist[i].setMaximum(90.0) #set the range for this widget self.levlist[i].setValue(float(levellist[i])) self.updatelevelconstraints() def bindsgc(self): """Bind Setgcolor buttons """ self.connect(self.buttongroup, QtCore.SIGNAL("buttonClicked(int)"), self.changecolor) def setcolor(self, index, color): """Set color in the colorlist""" qcolor = QtGui.QColor(*color) palette = self.buttonlist[index].palette() palette.setColor(QtGui.QPalette.Button, qcolor) self.colorlist[index] = (color[0], color[1], color[2]) self.buttonlist[index].setStyleSheet("QWidget { background-color: %s }" % qcolor.name()) def updatelevelconstraints(self): for i in range(1,len(self.levlist)): self.levlist[i-1].setMaximum(self.levlist[i].value()-0.1) for i in range(len(self.levlist)-1): self.levlist[i+1].setMinimum(self.levlist[i].value()+0.1) def changecolor(self, index): """Change the color used by plot to fill different classes of gradients """ button = self.buttonlist[index] palette = button.palette() qcolor = palette.color(QtGui.QPalette.Button) newcolor = QtGui.QColorDialog.getColor(qcolor, self) if newcolor.isValid(): self.setcolor(index, (newcolor.red(), newcolor.green(), newcolor.blue())) def font_button_clicked(self, index): button = self.fontbuttonlist[index] qfont = QtGui.QFont() qfont.setFamily(button.desc["des"]) qfont.setPointSize(int(button.desc["dim"])) try: res = eval('QtGui.QFont.'+button.desc["typ"].capitalize()) except AttributeError: res = QtGui.QFont.Normal qfont.setWeight(res) (qfont, ok) = QtGui.QFontDialog.getFont(qfont, self) if ok: button.desc = { "des" : str(qfont.family()), "typ" : FONT_TYP[qfont.weight()], "dim" : str(qfont.pointSize()) } button.setText(str(qfont.family())+' | '+str(qfont.pointSize())) def getconfig(self): """Returns selected config options""" res = str(self.res.currentText()).split(' ') settings = { 'olines': self.olines.isChecked(), 'theme' : str(self.theme.currentText()), 'sinfo' : self.showinfo.isChecked(), 'vcheck': self.vcheck.isChecked(), '3d' : self.effect3d.isChecked(), 'aname' : self.aname.text(), 'amail' : self.amail.text(), 'fdesc' : self.fdesc.desc, 'ftitle': self.ftitle.desc, 'fgrad' : self.fgrad.desc, 'width' : res[0], 'height': res[2], 'serv' : str(self.serv.currentText()), 'colors': ['rgb(%d,%d,%d)' % (clr[0], clr[1], clr[2]) \ for clr in self.colorlist], 'levels': ['%f' %(lev.value()) for lev in self.levlist] } return settings class Plot(QtGui.QMainWindow): """ Plot window""" def __init__(self, parent, slope, plot_settings, exportfunc, exportfunc_pdf, exportfunc_html): QtGui.QMainWindow.__init__(self, parent) self.panel = AnimatedPanel(slope) self.setCentralWidget(self.panel) title = "CycloGraph" if slope.name: title += " - " + slope.name self.setWindowTitle(title) self.myslope = slope self.menu_item_save = QtGui.QAction( _('Save'), self) icon_save = QtGui.QIcon(QtGui.QPixmap(":/qt-icons/pixmaps/save.png")) icon_save = iconFromTheme("document-save-as", icon_save) self.menu_item_save.setIcon(icon_save) self.menu_item_savepdf = QtGui.QAction( _('Save PDF'), self) self.menu_item_savehtml = QtGui.QAction( _('Save html'), self) self.menu_item_olines = QtGui.QAction(self) self.menu_item_olines.setCheckable(True) self.menu_item_olines.setChecked(plot_settings['olines']) self.menu_item_olines.setText(_("&Orizzontal lines")) self.menu_item_3d = QtGui.QAction(self) self.menu_item_3d.setCheckable(True) self.menu_item_3d.setChecked(plot_settings['3d']) self.menu_item_3d.setText(_("3D &effect")) self.themeitems = {} self.theme_action_group = QtGui.QActionGroup(self) self.thememanager = ThemeManager() for theme in self.thememanager.getthemeslist(): themeitem = QtGui.QAction(self) themeitem.setCheckable(True) if plot_settings['theme'] == theme: themeitem.setChecked(True) themeitem.setText(theme) self.theme_action_group.addAction(themeitem) self.themeitems[themeitem] = theme menubar = self.menuBar() options_menu = menubar.addMenu( _('&Options') ) options_menu.addAction(self.menu_item_save) options_menu.addAction(self.menu_item_savepdf) options_menu.addAction(self.menu_item_savehtml) options_menu.addAction(self.menu_item_olines) options_menu.addAction(self.menu_item_3d) themes_menu = QtGui.QMenu(options_menu) themes_menu.setTitle(_("&Theme")) for action in self.themeitems.keys(): themes_menu.addAction(action) options_menu.addAction(themes_menu.menuAction()) res_menu = QtGui.QMenu(options_menu) res_menu.setTitle(_("&Saving resolution")) self.resitems = {} res_action_group = QtGui.QActionGroup(self) rlist = [('800','600'), ('1024','768'), ('1280','800'), ('1600','1200')] for res in rlist: resitem = QtGui.QAction(self) resitem.setCheckable(True) restext = res[0]+'x'+res[1] resitem.setText(restext) if plot_settings['width'] == int(res[0]): resitem.setChecked(True) res_action_group.addAction(resitem) self.resitems[resitem] = restext res_menu.addAction(resitem) options_menu.addAction(res_menu.menuAction()) self.exportfunc = exportfunc self.exportfunc_pdf = exportfunc_pdf self.exportfunc_html = exportfunc_html self.myslope.calc() self.settings = plot_settings self.panel.settings = self.settings self.panel.devc = glal.DeviceContext() self.resize(plot_settings['width'], plot_settings['height']) self.settings['colors'] = plot_settings['colors'] self.animation3d = QtCore.QPropertyAnimation(self.panel, "depth") self.animation3d.setDuration(1000) self.animation3d.setStartValue(100) self.animation3d.setEndValue(0) self.animationTh = QtCore.QPropertyAnimation(self.panel, "opacity") self.animationTh.setDuration(1000) self.animationTh.setStartValue(1.0) self.animationTh.setEndValue(0.0) QtCore.QObject.connect(self.menu_item_save, QtCore.SIGNAL("triggered()"), self.saveimage) QtCore.QObject.connect(self.menu_item_savepdf, QtCore.SIGNAL("triggered()"), self.savepdf) QtCore.QObject.connect(self.menu_item_savehtml, QtCore.SIGNAL("triggered()"), self.savehtml) QtCore.QObject.connect(self.menu_item_olines, QtCore.SIGNAL("triggered()"), self.olines) QtCore.QObject.connect(self.menu_item_3d, QtCore.SIGNAL("triggered()"), self.change3d) QtCore.QObject.connect(self.theme_action_group, QtCore.SIGNAL("triggered(QAction *)"), self.changetheme) QtCore.QObject.connect(res_action_group, QtCore.SIGNAL("triggered(QAction *)"), self.changeres) def showplot(self): """ Show plot""" self.show() def saveimage(self): """ Save image""" self.exportfunc(self.myslope, self.settings) def savepdf(self): """ Save pdf""" self.exportfunc_pdf(self.myslope, self.settings) def savehtml(self): """ Save html report""" self.exportfunc_html(self.myslope, self.settings) def change3d(self): """ If active switch 3d effect off, else turn it on.""" if self.settings['3d']: self.animation3d.setDirection(self.animation3d.Forward) else: self.animation3d.setDirection(self.animation3d.Backward) self.animation3d.start() def olines(self): """ If active draws orizzontal lines""" self.panel.shot() self.settings['olines'] = not self.settings['olines'] self.animationTh.start() def changetheme(self, action): """Change the actual slope theme.""" self.panel.shot() self.settings["theme"] = self.themeitems[action] self.animationTh.start() def changeres(self, action): """Change saving resolution.""" text = self.resitems[action] width, height = text.split('x') self.settings['width'] = int(width) self.settings['height'] = int(height) class AnimatedPanel(QtGui.QWidget): """This class implements a personalized widget that draws a slope. It also implements the fade between different images and 2D to 3D. Using this class prevents from drawing on the menu.""" def __init__(self, slope, parent=None): QtGui.QWidget.__init__(self, parent) self.__old_opacity = 0.0 self.__depth = 100 self.myslope = slope def shot(self): """Create an internal pixmap representing the current state of the widget""" self.__old_pixmap = QtGui.QPixmap(self.size()) self.render(self.__old_pixmap) def oldOpacity(self): """Get the opacity of the pixamp of the old slope""" return self.__old_opacity def setOldOpacity(self, opacity): """Set the opacity of the pixamp of the old slope""" self.__old_opacity = opacity self.repaint() def changeres(self, action): """Change saving resolution.""" text = self.resitems[action] width, height = text.split('x') self.settings['width'] = int(width) self.settings['height'] = int(height) opacity = QtCore.pyqtProperty("double", oldOpacity, setOldOpacity) def depth(self): """Get the depth of the current slope (0 means 2D)""" return self.__depth def setDepth(self, depth): """Set the depth of the current slope""" self.__depth = depth self.settings['3d'] = (depth != 0) self.repaint() depth = QtCore.pyqtProperty("int", depth, setDepth) def paintEvent(self, event): """Actually draws the content.""" self.myslope.depth = self.__depth self.devc.init_draw_surf(self) self.myslope.paint(self.settings, self.devc) if self.__old_opacity > 0.0: self.devc.paint.resetTransform() self.devc.paint.setOpacity(self.__old_opacity) self.devc.paint.drawPixmap(0, 0, self.__old_pixmap) self.devc.end_draw() class Map(QtGui.QDialog, ui_qt.Ui_map): """Show map of slopes""" def __init__(self, parent, slopename, stringc, savefnct): QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.savefnct = savefnct self.setWindowFlags(QtCore.Qt.Window) self.setWindowTitle(_(u"Map")+" - "+ slopename) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("clicked(QAbstractButton *)"), self.button_clicked) mapfile = QtCore.QFile(":/openlayers/cyclograph/map.html") if mapfile.open(QtCore.QFile.ReadOnly): mapdata = unicode(mapfile.readAll()) htmlMap = mapdata % (stringc,) mapfile.close() self.webView.setHtml(htmlMap) self.show() def saveimage(self, filepath): """ Save map image""" page = self.webView.page() img = QtGui.QImage(page.viewportSize(), QtGui.QImage.Format_ARGB32) painter = QtGui.QPainter(img) self.webView.render(painter) painter.end() img.save(filepath) def button_clicked(self, button): button_id = self.buttonBox.standardButton(button) if button_id == QtGui.QDialogButtonBox.Save: self.savefnct(self) class Create_kml(QtGui.QDialog, ui_qt.Ui_Create_KML_Dialog): """Create kml dialog""" MODE = {_("Open Route Service") : 'ORS', _(u'OSRM') : 'OSRM', _("Draw on the map") : 'DRAW'} def __init__(self, parent, downloadfunc, savefunc): QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowFlags(QtCore.Qt.Window) self.downloadfunc = downloadfunc #used to downlaod from url self.savefunc = savefunc self.handler = None self.mode = None self.mode_changed(self.listWidget.currentItem().text()) self.splitter.setStretchFactor(0, 1) self.splitter.setStretchFactor(1, 3) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("clicked(QAbstractButton *)"), self.button_clicked) QtCore.QObject.connect(self.listWidget, QtCore.SIGNAL("currentTextChanged(const QString&)"), self.mode_changed) def webview_init(self): """ Check mode and set webview accordingly""" if self.mode == 'ORS': self.webView.setUrl(QtCore.QUrl("http://openrouteservice.org/")) elif self.mode == 'OSRM': self.webView.setUrl(QtCore.QUrl("http://map.project-osrm.org/")) elif self.mode == 'DRAW': url = QtCore.QUrl("qrc:/openlayers/cyclograph/openlayers.html")#.fromLocalFile(os.path.join(os.path.dirname(__file__),"openlayers.html")) self.webView.setUrl(url) def button_clicked(self, button): button_id = self.buttonBox.standardButton(button) if button_id == QtGui.QDialogButtonBox.Ok: self.download() QtGui.QDialog.accept(self) elif button_id == QtGui.QDialogButtonBox.Save: self.save_kml() #Do not accept the dialog: it must stay open if the user wants to #import without opening the file saved or if he hasn't saved and #wants to go back. elif button_id == QtGui.QDialogButtonBox.Cancel: self.handler = None QtGui.QDialog.reject(self) def mode_changed(self, sel_string): """ Change current mode""" newmode = self.MODE[str(sel_string)] if newmode != self.mode: self.mode = newmode self.webview_init() def get_ors(self): page = self.webView.page() frame = page.currentFrame() gpxcontent = unicode(frame.evaluateJavaScript("document.getElementById('gpx').innerHTML").toString()) from xml.sax.saxutils import unescape return StringIO.StringIO(unescape(gpxcontent)) def get_osrm(self): """ Returns gpx content from ORSM service""" page = self.webView.page() frame = page.currentFrame() gpxcontent = unicode(frame.evaluateJavaScript("document.getElementsByClassName('text-link')[1].getAttribute('onclick')").toString()) url = gpxcontent.split('\'') return self.downloadfunc(url[1]) def get_draw(self): frame = self.webView.page().currentFrame() kmlstring = frame.evaluateJavaScript("createKml()").toString() return StringIO.StringIO(kmlstring) def download(self): if self.mode == 'ORS': self.handler = self.get_ors() elif self.mode == 'OSRM': self.handler = self.get_osrm() elif self.mode == 'DRAW': self.handler = self.get_draw() def save_kml(self): self.download() if not self.handler: return self.savefunc(self.handler, self.mode) def show_modal(self): """Shows the dialog and returns True if the value has to be chenged.""" val = self.exec_() return val == QtGui.QDialog.Accepted class NumcpsDialog(QtGui.QDialog, ui_qt.Ui_numcps_dlg): """ask cps number you want to import""" def __init__(self, max_num_cps, max_length, file_ext): QtGui.QDialog.__init__(self, None) self.setupUi(self) self.slider.setMaximum(max_num_cps) self.spinBox.setMaximum(max_num_cps) self.slider_2.setMaximum(int(max_length)) self.spinBox_2.setMaximum(int(max_length)) text = _("The %s file contains %d points.\nChoose how many will be imported.") % (file_ext, max_num_cps) self.label.setText(text) self.label_2.setText(_(u"The %s file contains a route of %d Km.\nChoose what range you want between points.") % (file_ext, max_length)) self.label_3.setText(_("Choose the type of import you want")) self.proceedButton.clicked.connect(self.onProceedClicked) def onProceedClicked(self): btn = self.buttonGroup.checkedButton() if btn == self.all_ or btn == self.automatic: self.accept() elif btn == self.number: self.stackedWidget.setCurrentIndex(1) elif btn == self.distance_2: self.stackedWidget.setCurrentIndex(2) def preferences(parent, cgpref, defaultpref): """ set Preference dialog""" dlg = Preferences(parent, cgpref, defaultpref) if dlg.exec_() == QtGui.QDialog.Rejected: return {} else: return dlg.getconfig() def formslopeinfo(parent, slopedata): """ Show slope's info""" dlg = FormSlopeInfo(parent, slopedata) if dlg.exec_() == QtGui.QDialog.Rejected: return {} else: return dlg.getslopeinfo() def FileDialog(parent, title, dirname, filename, other, file_types, rw, FD_OPEN, FD_SAVE ): """ Show File dialog""" filters = reduce(lambda x, y: x + ';;' + y, [ ("%s (%s)" % elem) for elem in file_types]) #print filters if rw == FD_OPEN: file_ = QtGui.QFileDialog.getOpenFileName(parent, title, dirname, filters) elif rw == FD_SAVE: file_ = QtGui.QFileDialog.getSaveFileName(parent, title, dirname, filters) if file_: return unicode(file_) else: return None def numcpsdlg(max_num_cps, max_length, file_ext): """ask how many cps in a gpx or tcx files shall be imported""" dlg = NumcpsDialog(max_num_cps, max_length, file_ext) if dlg.exec_() == QtGui.QDialog.Rejected: return (-1, 0) elif dlg.buttonGroup.checkedButton() == dlg.automatic: return (0, -1) elif dlg.buttonGroup.checkedButton() == dlg.all_: return (0, 0) elif dlg.stackedWidget.currentIndex() == 1: return (0, dlg.slider.value()) else: return (1, dlg.slider_2.value()) def geterrnoroute(parent): """Get an error message explaining that you should have selected one route""" return QtGui.QMessageBox.warning(parent, _('No route'), _("Specify one route first."), QtGui.QMessageBox.Ok) def managecperr(parent): """Get an error message explaining that you should have inserted altitude and distance""" return QtGui.QMessageBox.critical(parent, _("Form incomplete"), _("Distance and altitude are required."), QtGui.QMessageBox.Ok) def mapcoorderr(parent): """Get an error message explaining that there are no coords in the slope""" return QtGui.QMessageBox.critical(parent, _("No coordinates"), _("there aren't coordinates associated with this slope."), QtGui.QMessageBox.Ok) def geterrnocp(parent): """Get an error message explaining that you should have at least two cps to plot """ return QtGui.QMessageBox.warning(parent, _('Not enough check points'), _( """There aren't enougth check points to plot. At least two points are required to plot."""), QtGui.QMessageBox.Ok) def save_changes(parent, filename): """Show a message if you close a modified and not saved slope""" response = None SAVE = _('Save') DISCARD = _('Close without saving') CANCEL = _('Cancel') message = QtGui.QMessageBox(parent) message.setText(_("Save changes to %s before closing?") % filename) message.setWindowTitle(_('Save changes')) message.setIcon(QtGui.QMessageBox.Warning) message.addButton(SAVE, QtGui.QMessageBox.AcceptRole) message.addButton(DISCARD, QtGui.QMessageBox.DestructiveRole) message.addButton(CANCEL, QtGui.QMessageBox.RejectRole) message.exec_() response = message.clickedButton().text() if response == SAVE: return 'SAVE' if response == DISCARD: return 'DISCARD' if response == CANCEL: return 'CANCEL' return response # vim:sw=4:softtabstop=4:expandtab ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������cyclograph-1.6.1/cyclograph/qt/ui_qt.py�������������������������������������������������������������0000644�0001750�0001750�00000143716�12222637240�021522� 0����������������������������������������������������������������������������������������������������ustar �federico������������������������federico������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## imports are included from imports.py ## from PyQt4 import QtCore, QtGui, QtWebKit import cyclograph_rc ## end of imports ## # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'create_kml.ui' # # Created: Thu Sep 19 20:06:07 2013 # by: PyQt4 UI code generator 4.10.2 # # WARNING! All changes made in this file will be lost! try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: def _fromUtf8(s): return s try: _encoding = QtGui.QApplication.UnicodeUTF8 def _translate(context, text, disambig): return _(text) except AttributeError: def _translate(context, text, disambig): return _(text) class Ui_Create_KML_Dialog(object): def setupUi(self, Create_KML_Dialog): Create_KML_Dialog.setObjectName(_fromUtf8("Create_KML_Dialog")) Create_KML_Dialog.resize(800, 550) Create_KML_Dialog.setMinimumSize(QtCore.QSize(484, 0)) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/cyclograph.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) Create_KML_Dialog.setWindowIcon(icon) self.verticalLayout = QtGui.QVBoxLayout(Create_KML_Dialog) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.splitter = QtGui.QSplitter(Create_KML_Dialog) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setChildrenCollapsible(False) self.splitter.setObjectName(_fromUtf8("splitter")) self.groupBox = QtGui.QGroupBox(self.splitter) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth()) self.groupBox.setSizePolicy(sizePolicy) self.groupBox.setObjectName(_fromUtf8("groupBox")) self.verticalLayout_2 = QtGui.QVBoxLayout(self.groupBox) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.listWidget = QtGui.QListWidget(self.groupBox) self.listWidget.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) self.listWidget.setViewMode(QtGui.QListView.ListMode) self.listWidget.setUniformItemSizes(False) self.listWidget.setWordWrap(True) self.listWidget.setObjectName(_fromUtf8("listWidget")) item = QtGui.QListWidgetItem() self.listWidget.addItem(item) item = QtGui.QListWidgetItem() self.listWidget.addItem(item) item = QtGui.QListWidgetItem() self.listWidget.addItem(item) self.verticalLayout_2.addWidget(self.listWidget) self.webView = QtWebKit.QWebView(self.splitter) self.webView.setMinimumSize(QtCore.QSize(0, 0)) self.webView.setUrl(QtCore.QUrl(_fromUtf8("about:blank"))) self.webView.setObjectName(_fromUtf8("webView")) self.verticalLayout.addWidget(self.splitter) self.buttonBox = QtGui.QDialogButtonBox(Create_KML_Dialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Save) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.verticalLayout.addWidget(self.buttonBox) self.retranslateUi(Create_KML_Dialog) self.listWidget.setCurrentRow(0) QtCore.QMetaObject.connectSlotsByName(Create_KML_Dialog) def retranslateUi(self, Create_KML_Dialog): Create_KML_Dialog.setWindowTitle(_translate("Create_KML_Dialog", "Create Kml", None)) self.groupBox.setTitle(_translate("Create_KML_Dialog", "Mode", None)) __sortingEnabled = self.listWidget.isSortingEnabled() self.listWidget.setSortingEnabled(False) item = self.listWidget.item(0) item.setText(_translate("Create_KML_Dialog", "Open Route Service", None)) item = self.listWidget.item(1) item.setText(_translate("Create_KML_Dialog", "OSRM", None)) item = self.listWidget.item(2) item.setText(_translate("Create_KML_Dialog", "Draw on the map", None)) self.listWidget.setSortingEnabled(__sortingEnabled) class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(580, 436) MainWindow.setWindowTitle(_fromUtf8("Cyclograph")) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/cyclograph.svg")), QtGui.QIcon.Normal, QtGui.QIcon.Off) MainWindow.setWindowIcon(icon) MainWindow.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.notebook = QtGui.QTabWidget(self.centralwidget) self.notebook.setTabShape(QtGui.QTabWidget.Rounded) self.notebook.setDocumentMode(True) self.notebook.setObjectName(_fromUtf8("notebook")) self.tab = QtGui.QWidget() self.tab.setObjectName(_fromUtf8("tab")) self.notebook.addTab(self.tab, _fromUtf8("Tab 1")) self.horizontalLayout.addWidget(self.notebook) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 580, 27)) self.menubar.setObjectName(_fromUtf8("menubar")) self.filemenu = QtGui.QMenu(self.menubar) self.filemenu.setObjectName(_fromUtf8("filemenu")) self.menu = QtGui.QMenu(self.menubar) self.menu.setTitle(_fromUtf8("?")) self.menu.setObjectName(_fromUtf8("menu")) self.menuOptions = QtGui.QMenu(self.menubar) self.menuOptions.setObjectName(_fromUtf8("menuOptions")) self.menu_Kml_server = QtGui.QMenu(self.menuOptions) self.menu_Kml_server.setObjectName(_fromUtf8("menu_Kml_server")) MainWindow.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) self.toolBar = QtGui.QToolBar(MainWindow) self.toolBar.setWindowTitle(_fromUtf8("toolbar")) self.toolBar.setMovable(True) self.toolBar.setIconSize(QtCore.QSize(32, 32)) self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) self.toolBar.setObjectName(_fromUtf8("toolBar")) MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) self.menu_item_open = QtGui.QAction(MainWindow) icon1 = QtGui.QIcon() icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/qt-icons/pixmaps/open.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.menu_item_open.setIcon(icon1) self.menu_item_open.setShortcut(_fromUtf8("Ctrl+O")) self.menu_item_open.setObjectName(_fromUtf8("menu_item_open")) self.menu_item_save = QtGui.QAction(MainWindow) self.menu_item_save.setEnabled(False) icon2 = QtGui.QIcon() icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/qt-icons/pixmaps/save.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.menu_item_save.setIcon(icon2) self.menu_item_save.setShortcut(_fromUtf8("Ctrl+S")) self.menu_item_save.setObjectName(_fromUtf8("menu_item_save")) self.menu_item_exit = QtGui.QAction(MainWindow) self.menu_item_exit.setShortcut(_fromUtf8("Ctrl+Q")) self.menu_item_exit.setObjectName(_fromUtf8("menu_item_exit")) self.menu_item_about = QtGui.QAction(MainWindow) self.menu_item_about.setObjectName(_fromUtf8("menu_item_about")) self.menu_item_s1 = QtGui.QAction(MainWindow) self.menu_item_s1.setCheckable(True) self.menu_item_s1.setChecked(True) self.menu_item_s1.setText(_fromUtf8("geonames.org")) self.menu_item_s1.setObjectName(_fromUtf8("menu_item_s1")) self.menu_item_s2 = QtGui.QAction(MainWindow) self.menu_item_s2.setCheckable(True) self.menu_item_s2.setText(_fromUtf8("earthtools.org")) self.menu_item_s2.setObjectName(_fromUtf8("menu_item_s2")) self.menu_item_s3 = QtGui.QAction(MainWindow) self.menu_item_s3.setCheckable(True) self.menu_item_s3.setText(_fromUtf8("usgs.net")) self.menu_item_s3.setObjectName(_fromUtf8("menu_item_s3")) self.menu_item_new = QtGui.QAction(MainWindow) icon3 = QtGui.QIcon() icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/qt-icons/pixmaps/new.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.menu_item_new.setIcon(icon3) self.menu_item_new.setShortcut(_fromUtf8("Ctrl+N")) self.menu_item_new.setObjectName(_fromUtf8("menu_item_new")) self.action_add = QtGui.QAction(MainWindow) self.action_add.setEnabled(False) icon4 = QtGui.QIcon() icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/icon_add.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.action_add.setIcon(icon4) self.action_add.setShortcut(_fromUtf8("+")) self.action_add.setObjectName(_fromUtf8("action_add")) self.action_edit = QtGui.QAction(MainWindow) self.action_edit.setEnabled(False) icon5 = QtGui.QIcon() icon5.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/icon_modify.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.action_edit.setIcon(icon5) self.action_edit.setObjectName(_fromUtf8("action_edit")) self.action_delete = QtGui.QAction(MainWindow) self.action_delete.setEnabled(False) icon6 = QtGui.QIcon() icon6.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/icon_delete.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.action_delete.setIcon(icon6) self.action_delete.setShortcut(_fromUtf8("-")) self.action_delete.setObjectName(_fromUtf8("action_delete")) self.action_plot = QtGui.QAction(MainWindow) self.action_plot.setEnabled(False) icon7 = QtGui.QIcon() icon7.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/icon_plot.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.action_plot.setIcon(icon7) self.action_plot.setObjectName(_fromUtf8("action_plot")) self.action_properties = QtGui.QAction(MainWindow) self.action_properties.setEnabled(False) icon8 = QtGui.QIcon() icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/icon_info.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.action_properties.setIcon(icon8) self.action_properties.setObjectName(_fromUtf8("action_properties")) self.menu_item_bug = QtGui.QAction(MainWindow) self.menu_item_bug.setObjectName(_fromUtf8("menu_item_bug")) self.menu_item_createkml = QtGui.QAction(MainWindow) icon9 = QtGui.QIcon() icon9.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/icon_ckml.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.menu_item_createkml.setIcon(icon9) self.menu_item_createkml.setShortcut(_fromUtf8("")) self.menu_item_createkml.setObjectName(_fromUtf8("menu_item_createkml")) self.menu_item_save_as = QtGui.QAction(MainWindow) self.menu_item_save_as.setEnabled(False) icon10 = QtGui.QIcon() icon10.addPixmap(QtGui.QPixmap(_fromUtf8(":/qt-icons/pixmaps/save_as.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.menu_item_save_as.setIcon(icon10) self.menu_item_save_as.setShortcut(_fromUtf8("Ctrl+Alt+S")) self.menu_item_save_as.setObjectName(_fromUtf8("menu_item_save_as")) self.preferences = QtGui.QAction(MainWindow) self.preferences.setObjectName(_fromUtf8("preferences")) self.action_map = QtGui.QAction(MainWindow) self.action_map.setEnabled(False) icon11 = QtGui.QIcon() icon11.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/icon_map.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.action_map.setIcon(icon11) self.action_map.setObjectName(_fromUtf8("action_map")) self.filemenu.addAction(self.menu_item_new) self.filemenu.addAction(self.menu_item_open) self.filemenu.addAction(self.menu_item_createkml) self.filemenu.addAction(self.menu_item_save) self.filemenu.addAction(self.menu_item_save_as) self.filemenu.addSeparator() self.filemenu.addAction(self.menu_item_exit) self.menu.addAction(self.menu_item_about) self.menu.addAction(self.menu_item_bug) self.menu_Kml_server.addAction(self.menu_item_s1) self.menu_Kml_server.addAction(self.menu_item_s2) self.menu_Kml_server.addAction(self.menu_item_s3) self.menuOptions.addAction(self.menu_Kml_server.menuAction()) self.menuOptions.addSeparator() self.menuOptions.addAction(self.preferences) self.menubar.addAction(self.filemenu.menuAction()) self.menubar.addAction(self.menuOptions.menuAction()) self.menubar.addAction(self.menu.menuAction()) self.toolBar.addAction(self.menu_item_new) self.toolBar.addAction(self.menu_item_open) self.toolBar.addAction(self.menu_item_createkml) self.toolBar.addAction(self.menu_item_save) self.toolBar.addSeparator() self.toolBar.addAction(self.action_add) self.toolBar.addAction(self.action_edit) self.toolBar.addAction(self.action_delete) self.toolBar.addSeparator() self.toolBar.addAction(self.action_plot) self.toolBar.addAction(self.action_map) self.toolBar.addAction(self.action_properties) self.retranslateUi(MainWindow) self.notebook.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): self.filemenu.setTitle(_translate("MainWindow", "File", None)) self.menuOptions.setTitle(_translate("MainWindow", "Options", None)) self.menu_Kml_server.setTitle(_translate("MainWindow", "&Kml server", None)) self.menu_item_open.setText(_translate("MainWindow", "&Open", None)) self.menu_item_save.setText(_translate("MainWindow", "&Save", None)) self.menu_item_exit.setText(_translate("MainWindow", "&Quit", None)) self.menu_item_about.setText(_translate("MainWindow", "About", None)) self.menu_item_new.setText(_translate("MainWindow", "&New", None)) self.action_add.setText(_translate("MainWindow", "Add", None)) self.action_add.setToolTip(_translate("MainWindow", "Press + on the keyboard to add a check-point", None)) self.action_edit.setText(_translate("MainWindow", "Edit", None)) self.action_edit.setToolTip(_translate("MainWindow", "Edit a check-point", None)) self.action_delete.setText(_translate("MainWindow", "Delete", None)) self.action_delete.setToolTip(_translate("MainWindow", "Press - on the keyboard to remove the selected check-point", None)) self.action_plot.setText(_translate("MainWindow", "Plot", None)) self.action_plot.setToolTip(_translate("MainWindow", "Plot your slope", None)) self.action_properties.setText(_translate("MainWindow", "Info", None)) self.action_properties.setToolTip(_translate("MainWindow", "Informations about the slope", None)) self.menu_item_bug.setText(_translate("MainWindow", "Signal a bug", None)) self.menu_item_createkml.setText(_translate("MainWindow", "&Create Kml", None)) self.menu_item_createkml.setIconText(_translate("MainWindow", "Create", None)) self.menu_item_createkml.setToolTip(_translate("MainWindow", " Create Kml", None)) self.menu_item_save_as.setText(_translate("MainWindow", "Save &As", None)) self.menu_item_save_as.setIconText(_translate("MainWindow", "Save as", None)) self.preferences.setText(_translate("MainWindow", "&Preferences", None)) self.action_map.setText(_translate("MainWindow", "Map", None)) self.action_map.setIconText(_translate("MainWindow", "Map", None)) self.action_map.setToolTip(_translate("MainWindow", "Show the map of your slope", None)) class Ui_Slope_Dialog(object): def setupUi(self, Slope_Dialog): Slope_Dialog.setObjectName(_fromUtf8("Slope_Dialog")) Slope_Dialog.resize(313, 336) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/cyclograph.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) Slope_Dialog.setWindowIcon(icon) self.formLayout = QtGui.QFormLayout(Slope_Dialog) self.formLayout.setObjectName(_fromUtf8("formLayout")) self.label = QtGui.QLabel(Slope_Dialog) self.label.setObjectName(_fromUtf8("label")) self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label) self.s_name = QtGui.QLineEdit(Slope_Dialog) self.s_name.setObjectName(_fromUtf8("s_name")) self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.s_name) self.label_2 = QtGui.QLabel(Slope_Dialog) self.label_2.setObjectName(_fromUtf8("label_2")) self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_2) self.s_state = QtGui.QLineEdit(Slope_Dialog) self.s_state.setObjectName(_fromUtf8("s_state")) self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.s_state) self.label_3 = QtGui.QLabel(Slope_Dialog) self.label_3.setObjectName(_fromUtf8("label_3")) self.formLayout.setWidget(8, QtGui.QFormLayout.LabelRole, self.label_3) self.s_comment = QtGui.QTextEdit(Slope_Dialog) self.s_comment.setObjectName(_fromUtf8("s_comment")) self.formLayout.setWidget(8, QtGui.QFormLayout.FieldRole, self.s_comment) self.buttonBox = QtGui.QDialogButtonBox(Slope_Dialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.formLayout.setWidget(9, QtGui.QFormLayout.FieldRole, self.buttonBox) self.label_4 = QtGui.QLabel(Slope_Dialog) self.label_4.setObjectName(_fromUtf8("label_4")) self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_4) self.s_author = QtGui.QLineEdit(Slope_Dialog) self.s_author.setObjectName(_fromUtf8("s_author")) self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.s_author) self.label_5 = QtGui.QLabel(Slope_Dialog) self.label_5.setObjectName(_fromUtf8("label_5")) self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_5) self.s_email = QtGui.QLineEdit(Slope_Dialog) self.s_email.setObjectName(_fromUtf8("s_email")) self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.s_email) self.label_6 = QtGui.QLabel(Slope_Dialog) self.label_6.setObjectName(_fromUtf8("label_6")) self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_6) self.label_7 = QtGui.QLabel(Slope_Dialog) self.label_7.setObjectName(_fromUtf8("label_7")) self.formLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.label_7) self.average_grad = QtGui.QLabel(Slope_Dialog) self.average_grad.setText(_fromUtf8("")) self.average_grad.setObjectName(_fromUtf8("average_grad")) self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.average_grad) self.max_grad = QtGui.QLabel(Slope_Dialog) self.max_grad.setText(_fromUtf8("")) self.max_grad.setObjectName(_fromUtf8("max_grad")) self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.max_grad) self.label_8 = QtGui.QLabel(Slope_Dialog) self.label_8.setObjectName(_fromUtf8("label_8")) self.formLayout.setWidget(6, QtGui.QFormLayout.LabelRole, self.label_8) self.height_difference = QtGui.QLabel(Slope_Dialog) self.height_difference.setText(_fromUtf8("")) self.height_difference.setObjectName(_fromUtf8("height_difference")) self.formLayout.setWidget(6, QtGui.QFormLayout.FieldRole, self.height_difference) self.label_9 = QtGui.QLabel(Slope_Dialog) self.label_9.setObjectName(_fromUtf8("label_9")) self.formLayout.setWidget(7, QtGui.QFormLayout.LabelRole, self.label_9) self.height_gain = QtGui.QLabel(Slope_Dialog) self.height_gain.setText(_fromUtf8("")) self.height_gain.setObjectName(_fromUtf8("height_gain")) self.formLayout.setWidget(7, QtGui.QFormLayout.FieldRole, self.height_gain) self.label.setBuddy(self.s_name) self.label_2.setBuddy(self.s_state) self.label_3.setBuddy(self.s_comment) self.retranslateUi(Slope_Dialog) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Slope_Dialog.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Slope_Dialog.reject) QtCore.QMetaObject.connectSlotsByName(Slope_Dialog) def retranslateUi(self, Slope_Dialog): Slope_Dialog.setWindowTitle(_translate("Slope_Dialog", "Slope Info", None)) self.label.setText(_translate("Slope_Dialog", "Name:", None)) self.label_2.setText(_translate("Slope_Dialog", "State:", None)) self.label_3.setText(_translate("Slope_Dialog", "Note:", None)) self.label_4.setText(_translate("Slope_Dialog", "Author:", None)) self.label_5.setText(_translate("Slope_Dialog", "E-mail:", None)) self.label_6.setText(_translate("Slope_Dialog", "Average gradient:", None)) self.label_7.setText(_translate("Slope_Dialog", "Max gradient:", None)) self.label_8.setText(_translate("Slope_Dialog", "Height difference:", None)) self.label_9.setText(_translate("Slope_Dialog", "Height gain:", None)) class Ui_manag_dlg(object): def setupUi(self, manag_dlg): manag_dlg.setObjectName(_fromUtf8("manag_dlg")) manag_dlg.resize(317, 159) manag_dlg.setWindowTitle(_fromUtf8("")) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/cyclograph.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) manag_dlg.setWindowIcon(icon) self.formLayout = QtGui.QFormLayout(manag_dlg) self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow) self.formLayout.setObjectName(_fromUtf8("formLayout")) self.label_2 = QtGui.QLabel(manag_dlg) self.label_2.setObjectName(_fromUtf8("label_2")) self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_2) self.distance = QtGui.QLineEdit(manag_dlg) self.distance.setObjectName(_fromUtf8("distance")) self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.distance) self.buttonBox = QtGui.QDialogButtonBox(manag_dlg) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.buttonBox) self.label = QtGui.QLabel(manag_dlg) self.label.setObjectName(_fromUtf8("label")) self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label) self.name = QtGui.QLineEdit(manag_dlg) self.name.setObjectName(_fromUtf8("name")) self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.name) self.label_3 = QtGui.QLabel(manag_dlg) self.label_3.setObjectName(_fromUtf8("label_3")) self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_3) self.altitude = QtGui.QLineEdit(manag_dlg) self.altitude.setObjectName(_fromUtf8("altitude")) self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.altitude) self.label_2.setBuddy(self.distance) self.label.setBuddy(self.name) self.label_3.setBuddy(self.altitude) self.retranslateUi(manag_dlg) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), manag_dlg.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), manag_dlg.reject) QtCore.QObject.connect(self.name, QtCore.SIGNAL(_fromUtf8("returnPressed()")), manag_dlg.accept) QtCore.QObject.connect(self.distance, QtCore.SIGNAL(_fromUtf8("returnPressed()")), self.altitude.selectAll) QtCore.QObject.connect(self.altitude, QtCore.SIGNAL(_fromUtf8("returnPressed()")), self.name.selectAll) QtCore.QMetaObject.connectSlotsByName(manag_dlg) manag_dlg.setTabOrder(self.distance, self.altitude) manag_dlg.setTabOrder(self.altitude, self.name) manag_dlg.setTabOrder(self.name, self.buttonBox) def retranslateUi(self, manag_dlg): self.label_2.setText(_translate("manag_dlg", "Distance:", None)) self.label.setText(_translate("manag_dlg", "Name:", None)) self.label_3.setText(_translate("manag_dlg", "Altitude:", None)) class Ui_map(object): def setupUi(self, map): map.setObjectName(_fromUtf8("map")) map.resize(800, 550) map.setMinimumSize(QtCore.QSize(484, 0)) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/cyclograph.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) map.setWindowIcon(icon) self.verticalLayout = QtGui.QVBoxLayout(map) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.splitter = QtGui.QSplitter(map) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setChildrenCollapsible(False) self.splitter.setObjectName(_fromUtf8("splitter")) self.webView = QtWebKit.QWebView(self.splitter) self.webView.setMinimumSize(QtCore.QSize(0, 0)) self.webView.setUrl(QtCore.QUrl(_fromUtf8("about:blank"))) self.webView.setObjectName(_fromUtf8("webView")) self.verticalLayout.addWidget(self.splitter) self.buttonBox = QtGui.QDialogButtonBox(map) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Save) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.verticalLayout.addWidget(self.buttonBox) self.retranslateUi(map) QtCore.QMetaObject.connectSlotsByName(map) def retranslateUi(self, map): map.setWindowTitle(_translate("map", "map", None)) class Ui_numcps_dlg(object): def setupUi(self, numcps_dlg): numcps_dlg.setObjectName(_fromUtf8("numcps_dlg")) numcps_dlg.resize(354, 232) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/cyclograph.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) numcps_dlg.setWindowIcon(icon) self.verticalLayout_2 = QtGui.QVBoxLayout(numcps_dlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.stackedWidget = QtGui.QStackedWidget(numcps_dlg) self.stackedWidget.setObjectName(_fromUtf8("stackedWidget")) self.menu = QtGui.QWidget() self.menu.setObjectName(_fromUtf8("menu")) self.verticalLayout_4 = QtGui.QVBoxLayout(self.menu) self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) self.label_3 = QtGui.QLabel(self.menu) self.label_3.setText(_fromUtf8("TextLabel")) self.label_3.setObjectName(_fromUtf8("label_3")) self.verticalLayout_4.addWidget(self.label_3) self.automatic = QtGui.QRadioButton(self.menu) self.automatic.setChecked(True) self.automatic.setObjectName(_fromUtf8("automatic")) self.buttonGroup = QtGui.QButtonGroup(numcps_dlg) self.buttonGroup.setObjectName(_fromUtf8("buttonGroup")) self.buttonGroup.addButton(self.automatic) self.verticalLayout_4.addWidget(self.automatic) self.distance_2 = QtGui.QRadioButton(self.menu) self.distance_2.setObjectName(_fromUtf8("distance_2")) self.buttonGroup.addButton(self.distance_2) self.verticalLayout_4.addWidget(self.distance_2) self.number = QtGui.QRadioButton(self.menu) self.number.setObjectName(_fromUtf8("number")) self.buttonGroup.addButton(self.number) self.verticalLayout_4.addWidget(self.number) self.all_ = QtGui.QRadioButton(self.menu) self.all_.setObjectName(_fromUtf8("all_")) self.buttonGroup.addButton(self.all_) self.verticalLayout_4.addWidget(self.all_) self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem) self.proceedButton = QtGui.QPushButton(self.menu) self.proceedButton.setObjectName(_fromUtf8("proceedButton")) self.horizontalLayout_3.addWidget(self.proceedButton) self.verticalLayout_4.addLayout(self.horizontalLayout_3) self.stackedWidget.addWidget(self.menu) self.points = QtGui.QWidget() self.points.setObjectName(_fromUtf8("points")) self.verticalLayout = QtGui.QVBoxLayout(self.points) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.label = QtGui.QLabel(self.points) self.label.setText(_fromUtf8("message")) self.label.setObjectName(_fromUtf8("label")) self.verticalLayout.addWidget(self.label) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.spinBox = QtGui.QSpinBox(self.points) self.spinBox.setObjectName(_fromUtf8("spinBox")) self.horizontalLayout.addWidget(self.spinBox) self.slider = QtGui.QSlider(self.points) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.slider.sizePolicy().hasHeightForWidth()) self.slider.setSizePolicy(sizePolicy) self.slider.setMinimumSize(QtCore.QSize(0, 0)) self.slider.setTracking(True) self.slider.setOrientation(QtCore.Qt.Horizontal) self.slider.setTickPosition(QtGui.QSlider.TicksAbove) self.slider.setTickInterval(10) self.slider.setObjectName(_fromUtf8("slider")) self.horizontalLayout.addWidget(self.slider) self.verticalLayout.addLayout(self.horizontalLayout) self.buttonBox = QtGui.QDialogButtonBox(self.points) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.verticalLayout.addWidget(self.buttonBox) self.stackedWidget.addWidget(self.points) self.distance = QtGui.QWidget() self.distance.setObjectName(_fromUtf8("distance")) self.verticalLayout_3 = QtGui.QVBoxLayout(self.distance) self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) self.label_2 = QtGui.QLabel(self.distance) self.label_2.setText(_fromUtf8("TextLabel")) self.label_2.setObjectName(_fromUtf8("label_2")) self.verticalLayout_3.addWidget(self.label_2) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.spinBox_2 = QtGui.QSpinBox(self.distance) self.spinBox_2.setObjectName(_fromUtf8("spinBox_2")) self.horizontalLayout_2.addWidget(self.spinBox_2) self.slider_2 = QtGui.QSlider(self.distance) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.slider_2.sizePolicy().hasHeightForWidth()) self.slider_2.setSizePolicy(sizePolicy) self.slider_2.setMinimumSize(QtCore.QSize(0, 0)) self.slider_2.setTracking(True) self.slider_2.setOrientation(QtCore.Qt.Horizontal) self.slider_2.setTickPosition(QtGui.QSlider.TicksAbove) self.slider_2.setTickInterval(10) self.slider_2.setObjectName(_fromUtf8("slider_2")) self.horizontalLayout_2.addWidget(self.slider_2) self.verticalLayout_3.addLayout(self.horizontalLayout_2) self.buttonBox_2 = QtGui.QDialogButtonBox(self.distance) self.buttonBox_2.setOrientation(QtCore.Qt.Horizontal) self.buttonBox_2.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox_2.setObjectName(_fromUtf8("buttonBox_2")) self.verticalLayout_3.addWidget(self.buttonBox_2) self.stackedWidget.addWidget(self.distance) self.verticalLayout_2.addWidget(self.stackedWidget) self.retranslateUi(numcps_dlg) self.stackedWidget.setCurrentIndex(0) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), numcps_dlg.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), numcps_dlg.reject) QtCore.QObject.connect(self.slider, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.spinBox.setValue) QtCore.QObject.connect(self.spinBox, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.slider.setValue) QtCore.QObject.connect(self.buttonBox_2, QtCore.SIGNAL(_fromUtf8("accepted()")), numcps_dlg.accept) QtCore.QObject.connect(self.buttonBox_2, QtCore.SIGNAL(_fromUtf8("rejected()")), numcps_dlg.reject) QtCore.QObject.connect(self.slider_2, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.spinBox_2.setValue) QtCore.QObject.connect(self.spinBox_2, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.slider_2.setValue) QtCore.QMetaObject.connectSlotsByName(numcps_dlg) def retranslateUi(self, numcps_dlg): numcps_dlg.setWindowTitle(_translate("numcps_dlg", "number of checkpoints", None)) self.automatic.setText(_translate("numcps_dlg", "Automatic", None)) self.distance_2.setText(_translate("numcps_dlg", "Select the distance rate", None)) self.number.setText(_translate("numcps_dlg", "Select the number of checkpoints", None)) self.all_.setText(_translate("numcps_dlg", "Use every point (discouraged)", None)) self.proceedButton.setText(_translate("numcps_dlg", "Next", None)) class Ui_Frame_Page(object): def setupUi(self, Frame_Page): Frame_Page.setObjectName(_fromUtf8("Frame_Page")) Frame_Page.resize(558, 399) Frame_Page.setWindowTitle(_fromUtf8("Frame")) Frame_Page.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) Frame_Page.setFrameShape(QtGui.QFrame.StyledPanel) Frame_Page.setFrameShadow(QtGui.QFrame.Raised) self.verticalLayout = QtGui.QVBoxLayout(Frame_Page) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.button_close = QtGui.QToolButton(Frame_Page) self.button_close.setObjectName(_fromUtf8("button_close")) self.verticalLayout.addWidget(self.button_close) self.tableWidget = QtGui.QTableWidget(Frame_Page) self.tableWidget.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.tableWidget.setObjectName(_fromUtf8("tableWidget")) self.tableWidget.setColumnCount(3) self.tableWidget.setRowCount(0) item = QtGui.QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(0, item) item = QtGui.QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(1, item) item = QtGui.QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(2, item) self.verticalLayout.addWidget(self.tableWidget) self.retranslateUi(Frame_Page) QtCore.QMetaObject.connectSlotsByName(Frame_Page) def retranslateUi(self, Frame_Page): self.button_close.setText(_translate("Frame_Page", "Close", None)) item = self.tableWidget.horizontalHeaderItem(0) item.setText(_translate("Frame_Page", "Distance [km]", None)) item = self.tableWidget.horizontalHeaderItem(1) item.setText(_translate("Frame_Page", "Altitude [m]", None)) item = self.tableWidget.horizontalHeaderItem(2) item.setText(_translate("Frame_Page", "Name", None)) class Ui_Pref_Dialog(object): def setupUi(self, Pref_Dialog): Pref_Dialog.setObjectName(_fromUtf8("Pref_Dialog")) Pref_Dialog.resize(409, 372) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/pixmaps/cyclograph.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) Pref_Dialog.setWindowIcon(icon) Pref_Dialog.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.gridLayout = QtGui.QGridLayout(Pref_Dialog) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.buttonBox = QtGui.QDialogButtonBox(Pref_Dialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.RestoreDefaults) self.buttonBox.setCenterButtons(False) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 1) self.tabWidget = QtGui.QTabWidget(Pref_Dialog) self.tabWidget.setObjectName(_fromUtf8("tabWidget")) self.General = QtGui.QWidget() self.General.setEnabled(True) self.General.setObjectName(_fromUtf8("General")) self.formLayout_3 = QtGui.QFormLayout(self.General) self.formLayout_3.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow) self.formLayout_3.setContentsMargins(40, -1, 40, -1) self.formLayout_3.setHorizontalSpacing(40) self.formLayout_3.setVerticalSpacing(5) self.formLayout_3.setObjectName(_fromUtf8("formLayout_3")) self.label_11 = QtGui.QLabel(self.General) self.label_11.setObjectName(_fromUtf8("label_11")) self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole, self.label_11) self.olines = QtGui.QCheckBox(self.General) self.olines.setChecked(True) self.olines.setObjectName(_fromUtf8("olines")) self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole, self.olines) self.effect3d = QtGui.QCheckBox(self.General) self.effect3d.setChecked(True) self.effect3d.setObjectName(_fromUtf8("effect3d")) self.formLayout_3.setWidget(1, QtGui.QFormLayout.FieldRole, self.effect3d) self.Resolutionl = QtGui.QLabel(self.General) self.Resolutionl.setObjectName(_fromUtf8("Resolutionl")) self.formLayout_3.setWidget(3, QtGui.QFormLayout.LabelRole, self.Resolutionl) self.res = QtGui.QComboBox(self.General) self.res.setObjectName(_fromUtf8("res")) self.res.addItem(_fromUtf8("")) self.res.setItemText(0, _fromUtf8("800 x 600")) self.res.addItem(_fromUtf8("")) self.res.setItemText(1, _fromUtf8("1024 x 768")) self.res.addItem(_fromUtf8("")) self.res.setItemText(2, _fromUtf8("1280 x 800")) self.res.addItem(_fromUtf8("")) self.res.setItemText(3, _fromUtf8("1600 x 1200")) self.formLayout_3.setWidget(3, QtGui.QFormLayout.FieldRole, self.res) self.Themel = QtGui.QLabel(self.General) self.Themel.setObjectName(_fromUtf8("Themel")) self.formLayout_3.setWidget(5, QtGui.QFormLayout.LabelRole, self.Themel) self.theme = QtGui.QComboBox(self.General) self.theme.setObjectName(_fromUtf8("theme")) self.formLayout_3.setWidget(5, QtGui.QFormLayout.FieldRole, self.theme) self.kmlserverl = QtGui.QLabel(self.General) self.kmlserverl.setObjectName(_fromUtf8("kmlserverl")) self.formLayout_3.setWidget(6, QtGui.QFormLayout.LabelRole, self.kmlserverl) self.serv = QtGui.QComboBox(self.General) self.serv.setObjectName(_fromUtf8("serv")) self.serv.addItem(_fromUtf8("")) self.serv.setItemText(0, _fromUtf8("geonames.org")) self.serv.addItem(_fromUtf8("")) self.serv.setItemText(1, _fromUtf8("earthtools.org")) self.serv.addItem(_fromUtf8("")) self.serv.setItemText(2, _fromUtf8("usgs.net")) self.formLayout_3.setWidget(6, QtGui.QFormLayout.FieldRole, self.serv) self.showinfo = QtGui.QCheckBox(self.General) self.showinfo.setChecked(True) self.showinfo.setObjectName(_fromUtf8("showinfo")) self.formLayout_3.setWidget(2, QtGui.QFormLayout.FieldRole, self.showinfo) self.label = QtGui.QLabel(self.General) self.label.setObjectName(_fromUtf8("label")) self.formLayout_3.setWidget(7, QtGui.QFormLayout.LabelRole, self.label) self.vcheck = QtGui.QCheckBox(self.General) self.vcheck.setObjectName(_fromUtf8("vcheck")) self.formLayout_3.setWidget(7, QtGui.QFormLayout.FieldRole, self.vcheck) self.tabWidget.addTab(self.General, _fromUtf8("")) self.Fonts = QtGui.QWidget() self.Fonts.setObjectName(_fromUtf8("Fonts")) self.formLayout_2 = QtGui.QFormLayout(self.Fonts) self.formLayout_2.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) self.formLayout_2.setContentsMargins(40, -1, 40, -1) self.formLayout_2.setHorizontalSpacing(40) self.formLayout_2.setVerticalSpacing(5) self.formLayout_2.setObjectName(_fromUtf8("formLayout_2")) self.label_8 = QtGui.QLabel(self.Fonts) self.label_8.setObjectName(_fromUtf8("label_8")) self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.label_8) self.fdesc = QtGui.QPushButton(self.Fonts) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.fdesc.sizePolicy().hasHeightForWidth()) self.fdesc.setSizePolicy(sizePolicy) self.fdesc.setObjectName(_fromUtf8("fdesc")) self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.fdesc) self.label_9 = QtGui.QLabel(self.Fonts) self.label_9.setObjectName(_fromUtf8("label_9")) self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_9) self.fgrad = QtGui.QPushButton(self.Fonts) self.fgrad.setObjectName(_fromUtf8("fgrad")) self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.fgrad) self.label_10 = QtGui.QLabel(self.Fonts) self.label_10.setObjectName(_fromUtf8("label_10")) self.formLayout_2.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_10) self.ftitle = QtGui.QPushButton(self.Fonts) self.ftitle.setObjectName(_fromUtf8("ftitle")) self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.ftitle) self.tabWidget.addTab(self.Fonts, _fromUtf8("")) self.Gcolors = QtGui.QWidget() self.Gcolors.setObjectName(_fromUtf8("Gcolors")) self.formLayout = QtGui.QFormLayout(self.Gcolors) self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) self.formLayout.setContentsMargins(40, -1, 40, -1) self.formLayout.setHorizontalSpacing(40) self.formLayout.setVerticalSpacing(5) self.formLayout.setObjectName(_fromUtf8("formLayout")) self.lev_1 = QtGui.QDoubleSpinBox(self.Gcolors) self.lev_1.setDecimals(1) self.lev_1.setMaximum(90.0) self.lev_1.setSingleStep(0.1) self.lev_1.setObjectName(_fromUtf8("lev_1")) self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.lev_1) self.button1 = QtGui.QPushButton(self.Gcolors) self.button1.setText(_fromUtf8("")) self.button1.setObjectName(_fromUtf8("button1")) self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.button1) self.button2 = QtGui.QPushButton(self.Gcolors) self.button2.setText(_fromUtf8("")) self.button2.setObjectName(_fromUtf8("button2")) self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.button2) self.button3 = QtGui.QPushButton(self.Gcolors) self.button3.setText(_fromUtf8("")) self.button3.setObjectName(_fromUtf8("button3")) self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.button3) self.button4 = QtGui.QPushButton(self.Gcolors) self.button4.setText(_fromUtf8("")) self.button4.setObjectName(_fromUtf8("button4")) self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.button4) self.button5 = QtGui.QPushButton(self.Gcolors) self.button5.setText(_fromUtf8("")) self.button5.setObjectName(_fromUtf8("button5")) self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.button5) self.button6 = QtGui.QPushButton(self.Gcolors) self.button6.setText(_fromUtf8("")) self.button6.setObjectName(_fromUtf8("button6")) self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.button6) self.button7 = QtGui.QPushButton(self.Gcolors) self.button7.setText(_fromUtf8("")) self.button7.setObjectName(_fromUtf8("button7")) self.formLayout.setWidget(6, QtGui.QFormLayout.FieldRole, self.button7) self.lev_2 = QtGui.QDoubleSpinBox(self.Gcolors) self.lev_2.setDecimals(1) self.lev_2.setMaximum(90.0) self.lev_2.setSingleStep(0.1) self.lev_2.setObjectName(_fromUtf8("lev_2")) self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.lev_2) self.lev_3 = QtGui.QDoubleSpinBox(self.Gcolors) self.lev_3.setDecimals(1) self.lev_3.setMaximum(90.0) self.lev_3.setSingleStep(0.1) self.lev_3.setObjectName(_fromUtf8("lev_3")) self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.lev_3) self.lev_4 = QtGui.QDoubleSpinBox(self.Gcolors) self.lev_4.setDecimals(1) self.lev_4.setMaximum(90.0) self.lev_4.setSingleStep(0.1) self.lev_4.setObjectName(_fromUtf8("lev_4")) self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.lev_4) self.lev_5 = QtGui.QDoubleSpinBox(self.Gcolors) self.lev_5.setDecimals(1) self.lev_5.setMaximum(90.0) self.lev_5.setSingleStep(0.1) self.lev_5.setObjectName(_fromUtf8("lev_5")) self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.lev_5) self.lev_6 = QtGui.QDoubleSpinBox(self.Gcolors) self.lev_6.setDecimals(1) self.lev_6.setMaximum(90.0) self.lev_6.setSingleStep(0.1) self.lev_6.setObjectName(_fromUtf8("lev_6")) self.formLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.lev_6) self.lev_7 = QtGui.QDoubleSpinBox(self.Gcolors) self.lev_7.setDecimals(1) self.lev_7.setMaximum(90.0) self.lev_7.setSingleStep(0.1) self.lev_7.setObjectName(_fromUtf8("lev_7")) self.formLayout.setWidget(6, QtGui.QFormLayout.LabelRole, self.lev_7) self.tabWidget.addTab(self.Gcolors, _fromUtf8("")) self.tab = QtGui.QWidget() self.tab.setObjectName(_fromUtf8("tab")) self.label_12 = QtGui.QLabel(self.tab) self.label_12.setGeometry(QtCore.QRect(40, 20, 59, 17)) self.label_12.setObjectName(_fromUtf8("label_12")) self.label_13 = QtGui.QLabel(self.tab) self.label_13.setGeometry(QtCore.QRect(40, 70, 59, 17)) self.label_13.setObjectName(_fromUtf8("label_13")) self.aname = QtGui.QLineEdit(self.tab) self.aname.setGeometry(QtCore.QRect(100, 20, 161, 27)) self.aname.setObjectName(_fromUtf8("aname")) self.amail = QtGui.QLineEdit(self.tab) self.amail.setGeometry(QtCore.QRect(100, 70, 161, 27)) self.amail.setObjectName(_fromUtf8("amail")) self.tabWidget.addTab(self.tab, _fromUtf8("")) self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) self.retranslateUi(Pref_Dialog) self.tabWidget.setCurrentIndex(0) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Pref_Dialog.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Pref_Dialog.reject) QtCore.QMetaObject.connectSlotsByName(Pref_Dialog) def retranslateUi(self, Pref_Dialog): Pref_Dialog.setWindowTitle(_translate("Pref_Dialog", "Preferences", None)) self.label_11.setText(_translate("Pref_Dialog", "Visualization", None)) self.olines.setText(_translate("Pref_Dialog", "Orizzontal lines", None)) self.effect3d.setText(_translate("Pref_Dialog", "3D effect", None)) self.Resolutionl.setText(_translate("Pref_Dialog", "Resolution", None)) self.Themel.setText(_translate("Pref_Dialog", "Theme", None)) self.kmlserverl.setText(_translate("Pref_Dialog", "Kml server", None)) self.showinfo.setText(_translate("Pref_Dialog", "Show info", None)) self.label.setText(_translate("Pref_Dialog", "Latest version", None)) self.vcheck.setText(_translate("Pref_Dialog", "Check online", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.General), _translate("Pref_Dialog", "General", None)) self.label_8.setText(_translate("Pref_Dialog", "Description", None)) self.fdesc.setText(_translate("Pref_Dialog", "font | dim", None)) self.label_9.setText(_translate("Pref_Dialog", "Gradient", None)) self.fgrad.setText(_translate("Pref_Dialog", "font | dim", None)) self.label_10.setText(_translate("Pref_Dialog", "Title", None)) self.ftitle.setText(_translate("Pref_Dialog", "font | dim", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.Fonts), _translate("Pref_Dialog", "Fonts", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.Gcolors), _translate("Pref_Dialog", "Gradient colors", None)) self.label_12.setText(_translate("Pref_Dialog", "Name:", None)) self.label_13.setText(_translate("Pref_Dialog", "E-mail:", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Pref_Dialog", "Author", None)) ��������������������������������������������������cyclograph-1.6.1/cyclograph/report_html.py����������������������������������������������������������0000644�0001750�0001750�00000007767�12204123117�022312� 0����������������������������������������������������������������������������������������������������ustar �federico������������������������federico������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- #report_html.py """report_html.py""" # Copyright (C) 2012, 2013 Pierluigi Villani, Federico Brega # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. import codecs TEMPLATE_CSS = """ """ MAP_SCRIPT = """ \n\n' if slopename != '': self.reportdata += ''+ slopename +'\n' self.reportdata += TEMPLATE_CSS self.reportdata += '\n\n\n' def add_image(self, svgstring): """Add image""" self.reportdata += '
\n'+ svgstring def add_map(self, slope, width, height): """Add map with route""" mapstring = '
\n' self.reportdata += mapstring % (str(width), str(height)) (lat, lng)= slope.coords[0] stringc = "%s %s" % (lng, lat) for i in range(1, len(slope.coords)): (lat, lng)= slope.coords[i] stringc += ",%s %s" % (lng, lat) #print(stringc) self.reportdata += MAP_SCRIPT % (stringc,) def addtext(self, label, value): """Add label+value""" self.reportdata += '\n

'+ label +'' + value + '

' def addtitle(self, text): """Add group title""" self.reportdata += '\n

'+ text +'

' def addnote(self, text): """Add comments""" self.reportdata += '\n

'+ text +'

' def save(self, filepath): """Save html report to file""" self.reportdata += '\n
\n\n\n' with codecs.open(filepath, encoding='utf-8', mode='wb') as fid: fid.write(self.reportdata) # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/launcher.py0000755000175000017500000000726112141430343021546 0ustar federicofederico00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """launcher.py """ # Copyright (C) 2008, 2009, 2010, 2011 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. import sys import locale, gettext import os import glal_selected def setup_gettext(): """Application translation system setup""" #Setup translation. langs = [] mylocale = locale.getdefaultlocale()[0] if mylocale: langs = [mylocale] #Other languages in the system. language = os.environ.get('LANGUAGE', None) if language: langs += language.split(':') #If there isn't any better use this. langs += ["en_CA", "en_US"] po_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..','po') if not os.path.isdir(po_path): po_path = "/usr/share/locale" gettext.bindtextdomain("cyclograph", po_path) gettext.textdomain("cyclograph") lang = gettext.translation("cyclograph", po_path, languages=langs, fallback=True) lang.install(unicode=True) def main(): setup_gettext() if len(sys.argv) < 2: #If there has been an error with the commandline specified frontend #try others in the order (PyQt gets first because is the supported #frontend on Mac Os and Windows where users might want a graphical #interface. if glal_selected.use('qt'): import cyclograph cyclograph.main_qt() elif glal_selected.use('gtk3'): import cyclograph cyclograph.main_gtk3() elif glal_selected.use('gtk'): import cyclograph cyclograph.main_gtk() elif glal_selected.use('cli'): import cyclograph cyclograph.main_cli() else: sys.exit(2) else: #also file=* is an argument even if it is not space separed. arguments = set([token.partition('=')[0] for token in sys.argv]) if arguments & set(('-q', '--qt')): if glal_selected.use('qt') != 'qt': sys.stderr.write('Qt backend is not installed correctely\n') sys.exit(3) import cyclograph cyclograph.main_qt() elif arguments & set(('-g', '--gtk')): if glal_selected.use('gtk') != 'gtk': sys.stderr.write('GTK+ 2 backend is not installed correctely\n') sys.exit(3) import cyclograph cyclograph.main_gtk() elif arguments & set(('-G', '--gtk3')): if glal_selected.use('gtk3') != 'gtk3': sys.stderr.write('GTK+ 3 backend is not installed correctely\n') sys.exit(3) import cyclograph cyclograph.main_gtk3() elif arguments & set(('-f', '--file', '-e', '--extension')): if glal_selected.use('cli') != 'cli': sys.stderr.write('Fatal error, cli backend cannot be started\n') sys.exit(3) import cyclograph cyclograph.main_cli() else: glal_selected.use('cli') import cyclograph cyclograph.main_cli() sys.exit(1) if __name__ == '__main__': main() # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/__init__.py0000644000175000017500000000004312033660360021474 0ustar federicofederico00000000000000# vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/version.py0000644000175000017500000000340712206154542021433 0ustar federicofederico00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """version.py """ # Copyright (C) 2009, 2010, 2011, 2012, 2013 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from __future__ import print_function import urllib2 import threading # Version of this software VERSION = '1.6.1' # This url is used to fetch the latest version number directely from # the website LAST_VERSION_URL = 'http://cyclograph.sourceforge.net/latestcg' # This parameter enables or disables the check if the user is running # the latest version. # It is intended for environments where the installable software is controlled # as are distribution. VERSION_CHECK_ENABLED = True class LastVersionQuery(threading.Thread): lastversion = '' def query(self): if not VERSION_CHECK_ENABLED: return try: page = urllib2.urlopen(LAST_VERSION_URL) self.lastversion = page.read().strip() page.close() except urllib2.URLError: self.lastversion = '' def islast(self): if not self.lastversion: return True return version_list(VERSION) >= version_list(self.lastversion) def run(self): self.query() def version_list(version_string): return map(int, version_string.split('.')) if __name__ == "__main__": print(VERSION) cyclograph-1.6.1/cyclograph/map.html0000644000175000017500000000376012204123117021031 0ustar federicofederico00000000000000
cyclograph-1.6.1/cyclograph/openlayers.html0000644000175000017500000000237112065361217022444 0ustar federicofederico00000000000000 CycloGraph: draw on map
cyclograph-1.6.1/cyclograph/gtk_/0000755000175000017500000000000012231302005020277 5ustar federicofederico00000000000000cyclograph-1.6.1/cyclograph/gtk_/glal.py0000644000175000017500000003421212204123117021577 0ustar federicofederico00000000000000# -*- coding: utf-8 -*- #gtk.glal.py """This module provides a graphic library abstraction layer for Cyclograph""" # Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. import math import gtk import cairo import gobject import gui gobject.threads_init() def initapp(*args): return gtk.main() def bind(cgfunc, menuopt): """Connect gui menu option with cg function""" return menuopt.connect("activate", cgfunc) def bind_close(cg_exit, gui): """Connect gui close event with cg exit function""" gui.cg_exit = cg_exit bind(gui.exit, gui.menu_item_exit) def ToolbarBind(fun, button): """Connect gui toolbar button with cg function""" return button.connect("clicked", fun) def OptionCheck(guiopt, option): """Set a gui menu option to selected/unselected """ guiopt.set_active(option) def enable_saving(gui, bool_val): """Enable or disable saving options according to bool_val""" gui.menu_item_save.set_sensitive(bool_val) gui.menu_item_save_as.set_sensitive(bool_val) gui.action_add.set_sensitive(bool_val) gui.action_edit.set_sensitive(bool_val) gui.action_delete.set_sensitive(bool_val) gui.action_plot.set_sensitive(bool_val) gui.action_map.set_sensitive(bool_val) gui.action_properties.set_sensitive(bool_val) def addstatusbartext(maingui, text): """Add text to main gui status bar""" maingui.addstatusbartext(text) maingui.sbtimer.start() def signalbug(event=None): """Open webpage to signal bugs""" bugUrl = 'http://sourceforge.net/project/memberlist.php?group_id=227295' #Looks like gtk hasn't any function to launch an external browser, #the best we can do is use python webbrowser import webbrowser webbrowser.open(bugUrl, new=True, autoraise=True) class Message(): """ gtk message""" def __init__(self): class Messenger(gobject.GObject): __gsignals__ = { str("UPDATE_TAB"): (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, (int, int, )), str("SLOPE_ADD"): (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, (int, int, )), str("SLOPE_DEL"): (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, (int, int, )), } self.gobj = Messenger() def send(self, message, slope_number, row_num): """ Send message""" self.gobj.emit(message, slope_number, row_num) def subscribe(self, function, emitter, message): """ Subscribe message""" self.handler = function emitter.gobj.connect(message, self._reformat_handler_param) def _reformat_handler_param(self, emitter, arg1, arg2): self.handler(arg1, arg2) class Notebook: """Gtk notebook""" def __init__(self, notebook, fun_close): self.notebook = notebook self.fun_close = fun_close self.notebook.set_scrollable(True) def Page(self): """Creates page""" return gui.Page(self.notebook) def set_page_label(self, page_num, text): """Set page label text""" lab = self.notebook.get_tab_label(self.get_page(page_num)) lab.label.set_text(text) def add_page(self, page, title): """Add page to the notebook""" box = gui.tab_label(page, title) page.button_close = box.closebtn page.button_close.connect("clicked", self.fun_close, page) self.notebook.append_page(page, box) self.notebook.show_all() nbpages = self.notebook.get_n_pages() self.notebook.set_current_page(nbpages-1) def remove_page(self, page_num): """Remove page from the notebook""" self.notebook.remove_page(page_num) def getselpagnum(self): """Return current selected page""" return self.notebook.get_current_page() def setselpagnum(self, page_num): """Set current selected page""" self.notebook.set_current_page(page_num) def get_page(self, page_num): """Return page at page_num""" return self.notebook.get_nth_page(page_num) def get_pagenum(self, argument): """Return page_num from page passed as argument""" return self.notebook.page_num(argument[1]) class DeviceContext(): """Device Context gtk class wrapper""" def _convcolor(self, color): """ Convert color""" col = color if isinstance(color, basestring): if color.startswith("rgb"): col = [(int(component)<<8)/65535.0 for component in color[4:-1].split(',')] elif color == "white": col = [1, 1, 1] else: col = [0, 0, 0] return col def init_draw_surf(self, widget, width, height): """Initialize device context""" self.size_x = width self.size_y = height self.devc = widget self.FONT_TYP = { "light" : cairo.FONT_WEIGHT_NORMAL, "normal" : cairo.FONT_WEIGHT_NORMAL, "bold" : cairo.FONT_WEIGHT_BOLD, } #pen color self.pcolor = [0, 0, 0] #brush color self.bcolor = [0, 0, 0] def shear(self, shear): """ device shear""" matrix = cairo.Matrix(yx = shear) self.devc.set_matrix(matrix) def getsize(self): """Return device context dimensions""" return (self.size_x, self.size_y) def gradfill(self, rect, startcolor, endcolor): """Fill context with gradient""" (startx, starty) = (rect[0], rect[1]) scolor = self._convcolor(startcolor) ecolor = self._convcolor(endcolor) lg1 = cairo.LinearGradient(0, 160.0, 0, self.size_y) lg1.add_color_stop_rgb(0, *scolor) lg1.add_color_stop_rgb(1, *ecolor) self.devc.rectangle(startx, starty, self.size_x, self.size_y) self.devc.set_source(lg1) self.devc.fill() def setpen(self, color, size): """Set pen color and size""" self.devc.set_line_width(size) self.pcolor = self._convcolor(color) def setfont(self, font): """Set font""" try: self.devc.select_font_face(font['des'], cairo.FONT_SLANT_NORMAL, self.FONT_TYP[font['typ']]) self.devc.set_font_size(font['dim']) except Exception: pass def drawtext(self, text, pos_x, pos_y): """Draw text""" self.devc.set_source_rgb(*self.pcolor) self.devc.move_to(pos_x, pos_y+12) self.devc.show_text(text) def gettextwidth(self, text): """ Return text length""" return int(self.devc.text_extents(text)[2]) def gettextheight(self, text): """ Return text height""" return int(self.devc.text_extents(text)[3]) def drawline(self, pos_x0, pos_y0, pos_x1, pos_y1): """Draw line""" self.devc.set_source_rgb(*self.pcolor) self.devc.move_to(pos_x0, pos_y0) self.devc.line_to(pos_x1, pos_y1) self.devc.stroke() def setlineargradientbrush(self, colorlist, startp, endp): """ Get a linear gradient from startp to endp, using colors in colorlist. The elments of colorlist are tuple in the format (color, realtive position).""" grad = cairo.LinearGradient(startp[0], startp[1], endp[0], endp[1]) for color in colorlist: grad.add_color_stop_rgb(color[1], *self._convcolor(color[0])) self.pattern = grad def setbrush(self, color): """Set brush color""" self.pattern = cairo.SolidPattern(*self._convcolor(color)) def drawrectangle(self, pos_x0, pos_y0, width, height): """Draw rectangle""" self.devc.set_source_rgb(0, 0, 0) self.devc.rectangle(pos_x0, pos_y0, width, height) self.devc.stroke_preserve() self.devc.set_source(self.pattern) self.devc.fill() def drawrotatedtext(self, text, pos_x, pos_y, angle): """Draw rotated text""" self.devc.save() self.devc.translate(pos_x, pos_y) self.devc.rotate(-math.radians(angle)) self.drawtext(text, 0, 0) self.devc.restore() def drawpolygon(self, sequence): """Draw polygon""" self.devc.set_source_rgb(0, 0, 0) self.devc.move_to(*sequence[0]) for point in sequence: self.devc.line_to(*point) self.devc.close_path() self.devc.stroke_preserve() self.devc.set_source(self.pattern) self.devc.fill() def startpath(self, point): """ Start a path in the specified point,""" (pointx, pointy) = point self.devc.set_source_rgb(0, 0, 0) self.devc.move_to(pointx, pointy) return None def drawpathlineto(self, path, point): """ Draw a straight line from the last point to the given point.""" (pointx, pointy) = point self.devc.line_to(pointx, pointy) def drawpathcubicto(self, path, controlpoints): """ Draw a cubic Beziér from the last point using the given list of three control points.""" points = [] for pnt in controlpoints: points.append(pnt[0]) points.append(pnt[1]) self.devc.curve_to(*points) def endpath(self, path): """ Show the path.""" self.devc.set_source_rgb(0, 0, 0) self.devc.stroke_preserve() self.devc.set_source(self.pattern) self.devc.fill() def end_draw(self): """End drawing not used for gtk gui""" pass class Image(): """Gtk image class wrapper""" def __init__(self, size_x, size_y, plotfnct): (self.size_x, self.size_y) = (size_x, size_y) self.plotfnct = plotfnct self.image = cairo.ImageSurface(cairo.FORMAT_RGB24, self.size_x, self.size_y) def plot(self, settings): """Plot image""" dcwrpp = DeviceContext() dcwrpp.init_draw_surf(cairo.Context(self.image), self.size_x, self.size_y) self.plotfnct(settings, dcwrpp) def savetofile(self, path, format): """Save slope to image""" if format.lower() == 'png': self.image.write_to_png(path) if format.lower() == 'bmp': width, height = self.image.get_width(), self.image.get_height() pixmap = gtk.gdk.Pixmap(None, width, height, 24) cr = pixmap.cairo_create() cr.set_source_surface(self.image, 0, 0) cr.paint() pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width, height) pixbuf = pixbuf.get_from_drawable(pixmap, gtk.gdk.colormap_get_system(), 0, 0, 0, 0, width, height) pixbuf.save(path, "bmp") if format.lower() == 'jpg': width, height = self.image.get_width(), self.image.get_height() pixmap = gtk.gdk.Pixmap(None, width, height, 24) cr = pixmap.cairo_create() cr.set_source_surface(self.image, 0, 0) cr.paint() pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width, height) pixbuf = pixbuf.get_from_drawable(pixmap, gtk.gdk.colormap_get_system(), 0, 0, 0, 0, width, height) pixbuf.save(path, "jpeg", {"quality":"100"}) class Pdf(): """Gtk pdf class wrapper""" def __init__(self, filepath): width, height = 793, 1122 self.dy = 90 self.dx = 300 self.y_incr = 30 self.surface = cairo.PDFSurface(filepath, width, height) self.context = cairo.Context(self.surface) # white background self.context.set_source_rgb(1, 1, 1) self.context.rectangle(0, 0, width, height) self.context.fill() self.context.select_font_face("Arial") self.context.set_font_size(18) def plot_image(self, settings, size_x, size_y, plotfnct): """Plot image""" image = cairo.SVGSurface(None, size_x, size_y) dcwrpp = DeviceContext() dcwrpp.init_draw_surf(cairo.Context(image), size_x, size_y) plotfnct(settings, dcwrpp) self.context.set_source_surface(image, 0, 0) self.context.paint() self.dy += size_y def addtext(self, text): self.dy += self.y_incr self.context.set_source_rgb(0, 0, 0) self.context.move_to(self.dx, self.dy) self.context.show_text(text) def addtitle(self, text): self.dy += self.y_incr self.context.set_source_rgb(0, 0, 0.4) self.context.move_to(self.dx-50, self.dy) self.context.show_text(text+":") def save(self): """Save slope to pdf""" self.context.show_page() self.surface.finish() class ProgressDialog(): """Gtk Progress dialog""" def __init__(self): self.pdialog = gui.ProgressDialog(_("Downloading altitudes"), _("Please wait, Cycograph is downloading altitudes."), 1000.0) def update(self, value): """Update the progress shown and return if user want to abort.""" return self.pdialog.update(value) def destroy(self): """Destroy dialog""" self.pdialog.destroy() class Timer(): """Gtk timer""" def __init__(self, period, callback): self.timer = 0 self.callback = callback self.period = period def start(self): """Start timer""" self.timer = gobject.timeout_add(self.period, self.callback) def stop(self): """Stop timer""" gobject.source_remove(self.timer) self.timer = 0 # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/gtk_/__init__.py0000644000175000017500000000000012065361217022415 0ustar federicofederico00000000000000cyclograph-1.6.1/cyclograph/gtk_/gui.py0000644000175000017500000017760412231301360021457 0ustar federicofederico00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """gtk_.gui.py""" # Copyright (C) 2009, 2010, 2011, 2012, 2013 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from __future__ import print_function import os import StringIO import gtk import pango import webkit import cairo import glal from themes import ThemeManager from version import VERSION pixmap_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..','..', 'pixmaps') ICON_FILENAME = os.path.join(pixmap_dir,'cyclograph.svg') if not os.path.isfile(ICON_FILENAME): pixmap_dir = '/usr/share/pixmaps/' ICON_FILENAME = '/usr/share/icons/hicolor/scalable/apps/cyclograph.svg' class Gui(gtk.Window): """Main window""" def __init__(self, parent, title, size): super(Gui, self).__init__() self.cg_exit = None #check on exit callback self.set_title(title) self.maximized = False self.set_default_size(size[0], size[1]) if size[2]: self.maximize() self.maximized = True try: self.set_icon_from_file(ICON_FILENAME) except Exception: pass #if librsvg2-common is not instaled self.set_position(gtk.WIN_POS_CENTER) self.notebook = gtk.Notebook() self.notebook.set_property('show-tabs', True) agr = gtk.AccelGroup() self.add_accel_group(agr) #Statusbar self.statusbar = gtk.Statusbar() self.context_id = self.statusbar.get_context_id("Statusbar") self.sbtimer = glal.Timer(5000, self.clearstatusbartext) #5000ms timeout #Load icons icons = [('icon_add', os.path.join(pixmap_dir, 'icon_add.png')), ('icon_ckml', os.path.join(pixmap_dir, 'icon_ckml.png')), ('icon_delete', os.path.join(pixmap_dir, 'icon_delete.png')), ('icon_modify', os.path.join(pixmap_dir, 'icon_modify.png')), ('icon_plot', os.path.join(pixmap_dir, 'icon_plot.png')), ('icon_map', os.path.join(pixmap_dir, 'icon_map.png')), ('icon_info', os.path.join(pixmap_dir, 'icon_info.png'))] factory = gtk.IconFactory() for (icon_id, icon_file) in icons: try: pixbuf = gtk.gdk.pixbuf_new_from_file(icon_file) except Exception: continue #if librsvg2-common is not instaled iconset = gtk.IconSet(pixbuf) factory.add(icon_id, iconset) factory.add_default() #Action group self.menu_item_new = gtk.Action("New", _(u"New"), _(u"New Slope"), gtk.STOCK_NEW) self.menu_item_open = gtk.Action("Open", _(u"Open"), _(u"Open Slope"), gtk.STOCK_OPEN) self.menu_item_createkml = gtk.Action("CreateKML", _(u"Create"), _(u"Create KML"), 'icon_ckml') self.menu_item_save = gtk.Action("Save", _(u"Save"), _(u"Save Slope"), gtk.STOCK_SAVE) actiongroup = gtk.ActionGroup("actions") actiongroup.add_action(self.menu_item_new) actiongroup.add_action(self.menu_item_open) actiongroup.add_action(self.menu_item_createkml) actiongroup.add_action(self.menu_item_save) #Toolbar toolbar = gtk.Toolbar() self.action_new = self.menu_item_new.create_tool_item() self.action_open = self.menu_item_open.create_tool_item() self.action_createkml = self.menu_item_createkml.create_tool_item() self.action_save = self.menu_item_save.create_tool_item() self.action_add = gtk.ToolButton('icon_add') self.action_add.set_label_widget(gtk.Label(_(u"Add"))) self.action_add.set_homogeneous(False) self.action_add.set_tooltip_text(_(u"Add a check-point")) key, mod = gtk.accelerator_parse('plus') self.action_add.add_accelerator("clicked", agr, key, mod, gtk.ACCEL_VISIBLE) self.action_edit = gtk.ToolButton('icon_modify') self.action_edit.set_label_widget(gtk.Label(_(u"Edit"))) self.action_edit.set_homogeneous(False) self.action_edit.set_tooltip_text(_(u"Edit a check-point")) self.action_delete = gtk.ToolButton('icon_delete') self.action_delete.set_label_widget(gtk.Label(_(u"Delete"))) self.action_delete.set_homogeneous(False) self.action_delete.set_tooltip_text(_(u"Remove a check-point")) key, mod = gtk.accelerator_parse('minus') self.action_delete.add_accelerator("clicked", agr, key, mod, gtk.ACCEL_VISIBLE) self.action_plot = gtk.ToolButton('icon_plot') self.action_plot.set_homogeneous(False) self.action_plot.set_label_widget(gtk.Label(_(u"Plot"))) self.action_plot.set_tooltip_text(_(u"Plot your slope")) self.action_map = gtk.ToolButton('icon_map') self.action_map.set_homogeneous(False) self.action_map.set_label_widget(gtk.Label(_(u"Map"))) self.action_map.set_tooltip_text(_(u"Show the map of your slope")) self.action_properties = gtk.ToolButton('icon_info') self.action_properties.set_homogeneous(False) self.action_properties.set_label_widget(gtk.Label(_(u"Info"))) self.action_properties.set_tooltip_text(_(u"Informations about the slope")) self.action_save.set_sensitive(False) self.action_add.set_sensitive(False) self.action_edit.set_sensitive(False) self.action_delete.set_sensitive(False) self.action_plot.set_sensitive(False) self.action_map.set_sensitive(False) self.action_properties.set_sensitive(False) toolbar.insert(self.action_new, 0) toolbar.insert(self.action_open, 1) toolbar.insert(self.action_createkml, 2) toolbar.insert(self.action_save, 3) toolbar.insert(gtk.SeparatorToolItem(), 4) toolbar.insert(self.action_add, 5) toolbar.insert(self.action_edit, 6) toolbar.insert(self.action_delete, 7) toolbar.insert(gtk.SeparatorToolItem(), 8) toolbar.insert(self.action_plot, 9) toolbar.insert(self.action_map, 10) toolbar.insert(self.action_properties, 11) #Creating the menubar. menubar = gtk.MenuBar() filemenu = gtk.Menu() self.smenu = gtk.MenuItem(_(u"_File")) self.smenu.set_submenu(filemenu) item_new = self.menu_item_new.create_menu_item() key, mod = gtk.accelerator_parse("N") item_new.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE) filemenu.append(item_new) sep = gtk.SeparatorMenuItem() filemenu.append(sep) item_open = self.menu_item_open.create_menu_item() key, mod = gtk.accelerator_parse("O") item_open.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE) filemenu.append(item_open) item_createkml = self.menu_item_createkml.create_menu_item() key, mod = gtk.accelerator_parse("G") item_createkml.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE) filemenu.append(item_createkml) item_save = self.menu_item_save.create_menu_item() self.menu_item_save.set_sensitive(False) key, mod = gtk.accelerator_parse("S") item_save.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE) filemenu.append(item_save) self.menu_item_save_as = gtk.ImageMenuItem(gtk.STOCK_SAVE_AS, agr) self.menu_item_save_as.set_sensitive(False) key, mod = gtk.accelerator_parse("S") self.menu_item_save_as.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE) filemenu.append(self.menu_item_save_as) sep = gtk.SeparatorMenuItem() filemenu.append(sep) self.menu_item_exit = gtk.ImageMenuItem(gtk.STOCK_QUIT, agr) key, mod = gtk.accelerator_parse("Q") self.menu_item_exit.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE) filemenu.append(self.menu_item_exit) menubar.append(self.smenu) filemenu1 = gtk.Menu() self.omenu = gtk.MenuItem(_(u"_Options")) self.omenu.set_submenu(filemenu1) kmenu = gtk.Menu() kmenum = gtk.MenuItem("_Kml server") kmenum.set_submenu(kmenu) self.menu_item_s1 = gtk.RadioMenuItem( None, (u"geonames.org")) self.menu_item_s2 = gtk.RadioMenuItem(self.menu_item_s1, (u"earthtools.org")) self.menu_item_s3 = gtk.RadioMenuItem(self.menu_item_s1, (u"usgs.net")) kmenu.append(self.menu_item_s1) kmenu.append(self.menu_item_s2) kmenu.append(self.menu_item_s3) filemenu1.append(kmenum) sep = gtk.SeparatorMenuItem() filemenu1.append(sep) self.preferences = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES) filemenu1.append(self.preferences) menubar.append(self.omenu) filemenu2 = gtk.Menu() self.amenu = gtk.MenuItem((u"?")) self.amenu.set_submenu(filemenu2) self.menu_item_about = gtk.ImageMenuItem(gtk.STOCK_ABOUT, agr) self.menu_item_about.connect("activate", onabout) filemenu2.append(self.menu_item_about) self.menu_item_bug = gtk.MenuItem(_(u"Signal a bug")) filemenu2.append(self.menu_item_bug) menubar.append(self.amenu) vbox = gtk.VBox(False, 0) vbox.pack_start(menubar, False, False, 0) vbox.pack_start(toolbar, False, False, 0) vbox.pack_start(self.notebook, True, True, 0) vbox.pack_start(self.statusbar, False, False, 0) self.add(vbox) self.connect("delete-event", self.exit) self.connect('window-state-event', self.on_window_state_event) self.show_all() def exit(self, event=None, param=None): """ Exit from CycloGraph, check if there are unsaved slopes""" if self.cg_exit(): gtk.main_quit() return return True #needed by gtk def getdimensions(self): """Return window width and height""" return self.get_size() def ismaximized(self): """Return true if window is maximized""" return self.maximized def addstatusbartext(self, text): """Add text to the statusbar""" self.statusbar.push(self.context_id, text) def clearstatusbartext(self): """Remove text from statusbar""" self.statusbar.pop(self.context_id) self.sbtimer.stop() def on_window_state_event(self, widget, event): if event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED: self.maximized = True else: self.maximized = False def onabout(event): """ About dialog""" about = gtk.AboutDialog() about.set_program_name("CycloGraph") about.set_version(VERSION) about.set_copyright("Copyright (C) 2008-2013 Federico Brega, Pierluigi Villani") about.set_authors(("Federico Brega", "Pierluigi Villani")) about.set_license(""" CycloGraph is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CycloGraph is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. """) about.set_website("http://cyclograph.sourceforge.net") about.set_logo(gtk.gdk.pixbuf_new_from_file(ICON_FILENAME)) about.set_icon_from_file(ICON_FILENAME) about.run() about.destroy() class Page(gtk.ScrolledWindow): """Notebook page""" def __init__(self, parent): gtk.ScrolledWindow.__init__(self) self.set_shadow_type(gtk.SHADOW_ETCHED_IN) self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.store = gtk.ListStore(str, int, str) self.mylistctrl = gtk.TreeView(self.store) self.mylistctrl.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.mylistctrl.set_rules_hint(True) #rows of alternate color self.mylistctrl.set_rubber_banding(True) #can select multiple cp by dragging the mouse self.add(self.mylistctrl) self.savedfilepath = None self.modified = False self.slopecounternew = 0 self.closebox = None rendererText = gtk.CellRendererText() column = gtk.TreeViewColumn(_(u"Distance [km]"), rendererText, text=0) column.set_sort_column_id(0) self.mylistctrl.append_column(column) rendererText = gtk.CellRendererText() column = gtk.TreeViewColumn(_(u"Altitude [m]"), rendererText, text=1) column.set_sort_column_id(1) self.mylistctrl.append_column(column) rendererText = gtk.CellRendererText() column = gtk.TreeViewColumn(_(u"Name"), rendererText, text=2) column.set_sort_column_id(2) self.mylistctrl.append_column(column) self.mylistctrl.set_headers_clickable(False) #disable column sort def insert_row(self, row_num, chkpnt): """Insert item to this page at position row_num""" self.store.insert(row_num, chkpnt) def delete_row(self, row_num): """Removes row at position row_num in this page.""" itera = self.store.get_iter (path = (row_num,)) self.store.remove (itera) def get_sel_row(self): """Gives the row number that is selected.""" selection = self.mylistctrl.get_selection() model, selected = selection.get_selected_rows() editcp = -1 if len(selected) > 0: path = selected[0] editcp = path[0] return editcp def get_sel_multi_row(self): """Gives a list with the row number of selected items.""" selection = self.mylistctrl.get_selection() model, selected = selection.get_selected_rows() rm_cps = [ path[0] for path in selected] return rm_cps class Managecp(gtk.Dialog): """Add and edit dialog""" def __init__(self, parent, title, dist="", alt="", name=""): gtk.Dialog.__init__(self, title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) self.set_size_request(220, 150) box = gtk.VBox(spacing=10) box.set_border_width(10) self.vbox.pack_start(box) box.show() labelbox = gtk.VBox(spacing=10) labelbox.set_border_width(10) labelbox.pack_start(gtk.Label(_(u"Distance:"))) labelbox.pack_start(gtk.Label(_(u"Altitude:"))) labelbox.pack_start(gtk.Label(_(u"Name:"))) entrybox = gtk.VBox() self.distance = gtk.Entry() self.distance.set_text(dist) self.distance.set_activates_default(True) entrybox.pack_start(self.distance) self.altitude = gtk.Entry() self.altitude.set_text(alt) self.altitude.set_activates_default(True) entrybox.pack_start(self.altitude) self.cpname = gtk.Entry() self.cpname.set_text(name) self.cpname.set_activates_default(True) entrybox.pack_start(self.cpname) obox = gtk.HBox() obox.pack_start(labelbox, False, False, 0) obox.pack_start(entrybox) self.set_default_response(gtk.RESPONSE_ACCEPT) box.pack_start(obox) box.show_all() def show_modal(self): """Shows the dialog and returns True if the value has to be changed.""" return self.run() == gtk.RESPONSE_ACCEPT def destroy(self): """Destroy current managecp""" gtk.Dialog.destroy(self) def getcp(self): """Gives the modified values.""" dist = self.distance.get_text() alti = self.altitude.get_text() name = self.cpname.get_text() return (dist, alti, name) class FormSlopeInfo(gtk.Dialog): """info dialog about the slope""" def __init__(self, parent, slopedata): gtk.Dialog.__init__(self, _(u"Slope Info"), parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) self.set_size_request(300, 420) box = gtk.VBox(spacing=10) box.set_border_width(10) self.vbox.pack_start(box) box.show() table = gtk.Table(8, 2, False) box.pack_start(table, False, True, 0) table.show() table.attach(gtk.Label(_(u"Name:")), 0, 1, 0, 1, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0) self.s_name = gtk.Entry() self.s_name.set_text(slopedata['name']) table.attach(self.s_name, 1, 2, 0, 1, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 5) table.attach(gtk.Label(_(u"State:")), 0, 1, 1, 2, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0) self.s_state = gtk.Entry() self.s_state.set_text(slopedata['state']) table.attach(self.s_state, 1, 2, 1, 2, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 5) table.attach(gtk.Label(_(u"Author:")), 0, 1, 2, 3, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0) self.s_author = gtk.Entry() self.s_author.set_text(slopedata['author']) table.attach(self.s_author, 1, 2, 2, 3, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 5) table.attach(gtk.Label(_(u"E-mail:")), 0, 1, 3, 4, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0) self.s_email = gtk.Entry() self.s_email.set_text(slopedata['email']) table.attach(self.s_email, 1, 2, 3, 4, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 5) table.attach(gtk.Label(_(u"Average gradient:")), 0, 1, 4, 5, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0) table.attach(gtk.Label(slopedata['average_grad']), 1, 2, 4, 5, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 5) table.attach(gtk.Label(_(u"Max gradient:")), 0, 1, 5, 6, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0) table.attach(gtk.Label(slopedata['max_grad']), 1, 2, 5, 6, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 5) table.attach(gtk.Label(_(u"Height difference:")), 0, 1, 6, 7, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0) table.attach(gtk.Label(slopedata['height_difference']), 1, 2, 6, 7, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 5) table.attach(gtk.Label(_(u"Height gain:")), 0, 1, 7, 8, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 0) table.attach(gtk.Label(slopedata['height_gain']), 1, 2, 7, 8, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 5) self.s_comment = gtk.TextBuffer() self.s_comment.set_text(slopedata['comment']) textview = gtk.TextView(self.s_comment) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.set_placement(gtk.CORNER_TOP_LEFT) sw.add(textview) sw.show_all() box.pack_start(gtk.Label(_(u"Note")+":"), False, False, 0) box.pack_start(sw, True, True, 0) box.show_all() def getslopeinfo(self): """Returns the slope infos: name, state, comment""" return {'name' : self.s_name.get_text(), 'state' : self.s_state.get_text(), 'author' : self.s_author.get_text(), 'email' : self.s_email.get_text(), 'comment' : self.s_comment.get_text(*self.s_comment.get_bounds())} def show_modal(self): """Shows the dialog and returns True if the value has to be chenged.""" return self.run() == gtk.RESPONSE_ACCEPT def destroy(self): """Destroy current FormSlopeInfo""" gtk.Dialog.destroy(self) class tab_label(gtk.HBox): """Notebook tab custom label with close button""" def __init__(self, page, title): gtk.HBox.__init__(self) self.label = gtk.Label(title) self.closebtn = gtk.Button() image = gtk.Image() image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) self.closebtn.set_image(image) self.closebtn.set_relief(gtk.RELIEF_NONE) self.pack_start(self.label, True, True) self.pack_end(self.closebtn, False, False) self.show_all() class Plot(gtk.Window): """plot main class""" def __init__(self, parent, slope, plot_settings, exportfunc, exportfunc_pdf, exportfunc_html): super(Plot, self).__init__() title = "CycloGraph" if slope.name: title += " - " + slope.name self.set_title(title) self.settings = plot_settings self.set_default_size(self.settings['width'], self.settings['height']) # set minimum height and width that plot can have self.set_geometry_hints(self, 300, 300) self.set_icon_from_file(ICON_FILENAME) menubar = gtk.MenuBar() filemenu = gtk.Menu() self.menu = gtk.MenuItem(_(u"_Options")) self.menu.set_submenu(filemenu) agr = gtk.AccelGroup() self.add_accel_group(agr) self.menu_item_save = gtk.ImageMenuItem(gtk.STOCK_SAVE, agr) key, mod = gtk.accelerator_parse("S") self.menu_item_save.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE) filemenu.append(self.menu_item_save) self.menu_item_savepdf = gtk.MenuItem(_(u"Save _PDF")) filemenu.append(self.menu_item_savepdf) self.menu_item_savehtml = gtk.MenuItem(_(u"Save _html")) filemenu.append(self.menu_item_savehtml) self.menu_item_olines = gtk.CheckMenuItem(_(u"_Orizzontal lines")) self.menu_item_olines.set_active(self.settings['olines']) filemenu.append(self.menu_item_olines) self.menu_item_3d = gtk.CheckMenuItem(_(u"3D _effect")) self.menu_item_3d.set_active(self.settings['3d']) filemenu.append(self.menu_item_3d) tmenu = gtk.Menu() tmenum = gtk.MenuItem(_(u"_Theme")) tmenum.set_submenu(tmenu) self.themeitems = [] self.radioitem = {} self.thememanager = ThemeManager() for theme in self.thememanager.getthemeslist(): if self.settings['theme'] == theme: self.theme1 = gtk.RadioMenuItem( None, theme) self.themeitems.append(theme) self.theme1.connect("activate", self.changetheme) for theme in self.themeitems: if self.settings['theme'] != theme: rmi = gtk.RadioMenuItem(self.theme1, theme) rmi.connect("activate", self.changetheme) tmenu.append(rmi) self.radioitem[theme] = rmi else: self.radioitem[theme] = self.theme1 tmenu.append(self.theme1) self.theme1.set_active(True) filemenu.append(tmenum) rmenu = gtk.Menu() rmenum = gtk.MenuItem(_(u"Saving _resolution")) rmenum.set_submenu(rmenu) menu_item_r1 = gtk.RadioMenuItem( None, (u"800x600")) menu_item_r2 = gtk.RadioMenuItem(menu_item_r1, (u"1024x768")) menu_item_r3 = gtk.RadioMenuItem(menu_item_r1, (u"1280x800")) menu_item_r4 = gtk.RadioMenuItem(menu_item_r1, (u"1600x1200")) menu_item_r1.set_active(self.settings['width'] == 800) menu_item_r2.set_active(self.settings['width'] == 1024) menu_item_r3.set_active(self.settings['width'] == 1280) menu_item_r4.set_active(self.settings['width'] == 1600) menu_item_r1.connect("activate", self.res1) menu_item_r2.connect("activate", self.res2) menu_item_r3.connect("activate", self.res3) menu_item_r4.connect("activate", self.res4) rmenu.append(menu_item_r1) rmenu.append(menu_item_r2) rmenu.append(menu_item_r3) rmenu.append(menu_item_r4) filemenu.append(rmenum) menubar.append(self.menu) self.menu_item_save.connect("activate", self.saveimage) self.menu_item_savepdf.connect("activate", self.savepdf) self.menu_item_savehtml.connect("activate", self.savehtml) self.menu_item_olines.connect("activate", self.olines) self.menu_item_3d.connect("activate", self.change3d) darea = gtk.DrawingArea() darea.connect("expose-event", self.on_paint) self.myslope = slope self.devc = glal.DeviceContext() self.myslope.calc() self.exportfunc = exportfunc self.exportfunc_pdf = exportfunc_pdf self.exportfunc_html = exportfunc_html vbox = gtk.VBox(False, 2) vbox.pack_start(menubar, False, False, 0) vbox.pack_start(darea, True, True, 0) self.add(vbox) self.show_all() def on_paint(self, widget, event): """Draw graph""" gdkwin = widget.window devc = gdkwin.cairo_create() self.devc.init_draw_surf(devc, widget.get_allocation().width, widget.get_allocation().height) self.myslope.paint(self.settings, self.devc) def showplot(self): """ Show plot""" pass def saveimage(self, event): """ Save plot image""" self.exportfunc(self.myslope, self.settings) def savepdf(self, event): """ Save pdf report""" self.exportfunc_pdf(self.myslope, self.settings) def savehtml(self, event): """ Save html report""" self.exportfunc_html(self.myslope, self.settings) def change3d(self, event): """ If active switch 3d effect off, else turn it on.""" self.settings['3d'] = not self.settings['3d'] self.queue_draw() def olines(self, event): """ If active draws orizzontal lines""" self.settings['olines'] = not self.settings['olines'] self.queue_draw() def changetheme(self, event): """Change the actual slope theme.""" t = self.radioitem.items() for theme in t: if theme[1] == event: self.settings["theme"] = theme[0] self.queue_draw() break def res1(self, event=None): """Set 800x600""" self.settings['width'] = 800 self.settings['height'] = 600 def res2(self, event=None): """Set 1024x768""" self.settings['width'] = 1024 self.settings['height'] = 768 def res3(self, event=None): """Set 1280x800""" self.settings['width'] = 1280 self.settings['height'] = 800 def res4(self, event=None): """Set 1600x1200""" self.settings['width'] = 1600 self.settings['height'] = 1200 FONT_TYP = { "300" : "light", "400" : "normal", "700" : "bold", } class Preferences(gtk.Dialog): """Set program preferences""" def __init__(self, parent, pref, default_pref): gtk.Dialog.__init__(self, _(u"Preferences"), parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR) self.colorlist = [] for color in pref['colors']: components = [int(component)<<8 for component in color[4:-1].split(',')] self.colorlist.append(gtk.gdk.Color(*components)) self.default = default_pref self.set_size_request(300, 480) notebook = gtk.Notebook() notebook.set_tab_pos(gtk.POS_TOP) frame = gtk.Frame() vbox = gtk.VBox(False, 0) vbox.set_border_width(5) hbox = gtk.HBox(False, 0) hbox.pack_start(vbox, False, False, 10) frame.add(hbox) frame.set_shadow_type(gtk.SHADOW_NONE) label = gtk.Label(""+_(u"Visualization")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.olines = gtk.CheckButton(_(u"Orizzontal lines")) vbox.pack_start(self.olines, False, False, 0) self.olines.set_active(pref['olines']) self.effect3d = gtk.CheckButton(_(u"3D effect")) vbox.pack_start(self.effect3d, False, False, 0) self.effect3d.set_active(pref['3d']) self.showinfo = gtk.CheckButton(_(u"Show info")) vbox.pack_start(self.showinfo, False, False, 0) self.showinfo.set_active(pref['sinfo']) label = gtk.Label(""+_(u"Resolution")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.res = gtk.combo_box_new_text() self.res.append_text('800 x 600') self.res.append_text('1024 x 768') self.res.append_text('1280 x 800') self.res.append_text('1600 x 1200') self.res.set_active(0) if pref['width'] == 1600: self.res.set_active(3) elif pref['width'] == 1280: self.res.set_active(2) elif pref['width'] == 1024: self.res.set_active(1) vbox.pack_start(self.res, False, False, 0) label = gtk.Label(""+_(u"Theme")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.theme = gtk.combo_box_new_text() current = 0 for theme in pref['themelist']: self.theme.append_text(theme) if theme == pref['theme']: self.theme.set_active(current) current += 1 vbox.pack_start(self.theme, False, False, 0) label = gtk.Label(""+_(u"Kml server")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.serv = gtk.combo_box_new_text() self.serv.append_text('geonames.org') self.serv.append_text('earthtools.org') self.serv.append_text('usgs.net') self.serv.append_text('google elevation') self.serv.set_active(0) if pref['serv'] == 'usgs.net': self.serv.set_active(2) elif pref['serv'] == 'earthtools.org': self.serv.set_active(1) elif pref['serv'] == 'google elevation': self.serv.set_active(3) vbox.pack_start(self.serv, False, False, 0) label = gtk.Label(""+_(u"Latest version")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.vcheck = gtk.CheckButton(_(u"Check online")) vbox.pack_start(self.vcheck, False, False, 0) self.vcheck.set_active(pref['vcheck']) notebook.append_page(frame, gtk.Label("General")) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_NONE) vbox = gtk.VBox(False, 0) vbox.set_border_width(5) hbox = gtk.HBox(False, 0) hbox.pack_start(vbox, False, False, 10) frame.add(hbox) label = gtk.Label(""+_(u"Description")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) desc = pref['fdesc'] self.fdesc = gtk.Button(desc['des']+' | '+str(desc["dim"])) self.fdesc.desc = desc self.fdesc.connect("clicked", self.font_button_clicked) vbox.pack_start(self.fdesc, False, False, 0) label = gtk.Label(""+_(u"Gradient")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) desc = pref['fgrad'] self.fgrad = gtk.Button(desc['des']+' | '+str(desc["dim"])) self.fgrad.desc = desc self.fgrad.connect("clicked", self.font_button_clicked) vbox.pack_start(self.fgrad, False, False, 0) label = gtk.Label(""+_(u"Title")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) desc = pref['ftitle'] self.ftitle = gtk.Button(desc['des']+' | '+str(desc["dim"])) self.ftitle.desc = desc self.ftitle.connect("clicked", self.font_button_clicked) vbox.pack_start(self.ftitle, False, False, 0) vbox.show_all() notebook.append_page(frame, gtk.Label("Fonts")) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_NONE) vbox = gtk.VBox(False, 0) vbox.set_border_width(5) frame.add(vbox) self.table = gtk.Table(6, 2, True) vbox.pack_start(self.table, True, True, 0) self.table.show() self.tick = 0.1 self.levlist = [] for i in range(len(pref['levels'])): self.levlist.append(gtk.SpinButton()) self.levlist[i].set_range(0.0, 90.0) self.levlist[i].set_value(pref['levels'][i]) self.levlist[i].set_increments(self.tick, 1) self.levlist[i].set_numeric(True) self.levlist[i].set_digits(1) self.levlist[i].connect("value_changed", self.changed_level) hbx = gtk.HBox() hbx.pack_start(gtk.Label(">"), False, False, 5) hbx.pack_start(self.levlist[i], False, False, 5) hbx.pack_start(gtk.Label("%"), False, False, 5) self.table.attach(hbx, 0, 1, i, i+1, 0) self.button1 = gtk.Button("") self.attach_button(self.button1, 0, 1) self.button2 = gtk.Button() self.attach_button(self.button2, 1, 2) self.button3 = gtk.Button("") self.attach_button(self.button3, 2, 3) self.button4 = gtk.Button("") self.attach_button(self.button4, 3, 4) self.button5 = gtk.Button("") self.attach_button(self.button5, 4, 5) self.button6 = gtk.Button("") self.attach_button(self.button6, 5, 6) self.button7 = gtk.Button("") self.attach_button(self.button7, 6, 7) vbox.show_all() notebook.append_page(frame, gtk.Label("Gradient colors")) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_NONE) vbox = gtk.VBox(False, 0) vbox.set_border_width(5) hbox = gtk.HBox(False, 0) hbox.pack_start(vbox, False, False, 10) frame.add(hbox) label = gtk.Label(""+_(u"Name")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.aname = gtk.Entry() self.aname.set_text(pref['aname']) vbox.pack_start(self.aname, False, False, 0) label = gtk.Label(""+_(u"E-mail")+"") label.set_use_markup(True) hhbox = gtk.HBox(False, 0) hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.amail = gtk.Entry() self.amail.set_text(pref['amail']) vbox.pack_start(self.amail, False, False, 0) vbox.show_all() notebook.append_page(frame, gtk.Label("Author")) notebook.show_all() bbox = gtk.HBox() button_k = gtk.Button(None, gtk.STOCK_OK) button_c = gtk.Button(None, gtk.STOCK_CANCEL) button_d = gtk.Button(_(u"Restore Default")) bbox.pack_end(button_k, False, False, 5) bbox.pack_end(button_c, False, False, 5) bbox.pack_start(button_d, False, False, 5) button_k.connect("clicked", self.ok_clicked) button_d.connect("clicked", self.restore_default) button_c.connect("clicked", self.destroy) box = gtk.VBox(False, 0) box.pack_start(notebook, True, True, 5) box.pack_start(bbox, False, False, 5) self.vbox.pack_start(box) self.vbox.show_all() def changed_level(self, event): self.levlist[0].set_range(0.0, self.levlist[1].get_value() - self.tick) for i in range(1, len(self.levlist)-1): self.levlist[i].set_range(self.levlist[i-1].get_value() + self.tick, self.levlist[i+1].get_value() - self.tick) self.levlist[len(self.levlist)-1].set_range( self.levlist[len(self.levlist)-2].get_value() + self.tick, 90.0) def ok_clicked(self, event): self.response(True) def restore_default(self, event): """Restore preferences to default value""" self.olines.set_active(bool(self.default['orizzontal lines'])) self.effect3d.set_active(bool(self.default['effect-3d'])) self.showinfo.set_active(bool(self.default['slopeinfo'])) self.vcheck.set_active(bool(self.default['vcheck'])) self.res.set_active(0) if self.default['width'] == 1600: self.res.set_active(3) elif self.default['width'] == 1280: self.res.set_active(2) elif self.default['width'] == 1024: self.res.set_active(1) current = 0 model = self.theme.get_model() for text in model: if text[0] == self.default['theme']: self.theme.set_active(current) current += 1 self.serv.set_active(0) if self.default['server'] == 'usgs.net': self.serv.set_active(2) elif self.default['server'] == 'earthtools.org': self.serv.set_active(1) elif self.default['server'] == 'google elevation': self.serv.set_active(3) self.fdesc = gtk.Button(self.default['font-des 1']+' | '+self.default['font-dim 1']) self.fdesc.desc = { "des" : self.default['font-des 1'], "typ" : self.default['font-typ 1'], "dim" : self.default['font-dim 1'] } self.fgrad = gtk.Button(self.default['font-des g']+' | '+self.default['font-dim g']) self.fgrad.desc = { "des" : self.default['font-des g'], "typ" : self.default['font-typ g'], "dim" : self.default['font-dim g'] } self.ftitle = gtk.Button(self.default['font-des t']+' | '+self.default['font-dim t']) self.ftitle.desc = { "des" : self.default['font-des t'], "typ" : self.default['font-typ t'], "dim" : self.default['font-dim t'] } self.aname.set_text(self.default['authorname']) self.amail.set_text(self.default['authormail']) colorlist = [self.default["color "+str(i)] for i in range(1, 8)] self.colorlist = [] for color in colorlist: components = [int(component)<<8 for component in color[4:-1].split(',')] self.colorlist.append(gtk.gdk.Color(*components)) self.button1.modify_bg(gtk.STATE_NORMAL, self.colorlist[0]) self.button1.modify_bg(gtk.STATE_PRELIGHT, self.colorlist[0]) self.button2.modify_bg(gtk.STATE_NORMAL, self.colorlist[1]) self.button2.modify_bg(gtk.STATE_PRELIGHT, self.colorlist[1]) self.button3.modify_bg(gtk.STATE_NORMAL, self.colorlist[2]) self.button3.modify_bg(gtk.STATE_PRELIGHT, self.colorlist[2]) self.button4.modify_bg(gtk.STATE_NORMAL, self.colorlist[3]) self.button4.modify_bg(gtk.STATE_PRELIGHT, self.colorlist[3]) self.button5.modify_bg(gtk.STATE_NORMAL, self.colorlist[4]) self.button5.modify_bg(gtk.STATE_PRELIGHT, self.colorlist[4]) self.button6.modify_bg(gtk.STATE_NORMAL, self.colorlist[5]) self.button6.modify_bg(gtk.STATE_PRELIGHT, self.colorlist[5]) self.button7.modify_bg(gtk.STATE_NORMAL, self.colorlist[6]) self.button7.modify_bg(gtk.STATE_PRELIGHT, self.colorlist[6]) levellist = [self.default["level "+str(i)] for i in range(1, 8)] for k in range(len(self.levlist)): i = len(self.levlist) - k-1 self.levlist[i].set_value(float(levellist[i])) def font_button_clicked(self, button): """If a font button is clicked show a font dialog to change font""" dlg = gtk.FontSelectionDialog(_(u"Select Font")) dlg.set_font_name(button.desc["des"]+' '+button.desc["typ"].capitalize()+' '+str(button.desc["dim"])) dlg.set_icon_from_file(ICON_FILENAME) result = dlg.run() if result == gtk.RESPONSE_OK: font = pango.FontDescription(dlg.get_font_name()) res = str(int(font.get_weight())) dlg.destroy() if FONT_TYP.has_key(res): weight = FONT_TYP[res] else: weight = "normal" button.desc = { "des" : font.get_family(), "typ" : weight, "dim" : str(font.get_size()/pango.SCALE) } button.set_label(font.get_family()+' | '+str(font.get_size()/pango.SCALE)) dlg.destroy() def attach_button(self, button, posx, posy): """bind button with changecolor function and set it in the table""" button.num = posx button.modify_bg(gtk.STATE_NORMAL, self.colorlist[posx]) button.modify_bg(gtk.STATE_PRELIGHT, self.colorlist[posx]) self.table.attach(button, 1, 2, posx, posy, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 0, 5) button.connect("clicked", self.changecolor) def changecolor(self, widget): """Change the color used by plot to fill different classes of gradients """ csd = gtk.ColorSelectionDialog(_(u"Select color")) csd.set_icon_from_file(ICON_FILENAME) csd.colorsel.set_current_color(self.colorlist[widget.num]) response = csd.run() if response == gtk.RESPONSE_OK: color = csd.colorsel.get_current_color() self.colorlist[widget.num] = color widget.modify_bg(gtk.STATE_NORMAL, color) widget.modify_bg(gtk.STATE_PRELIGHT, color) csd.destroy() def show_modal(self): """Shows the dialog and returns True if the values have to be chenged.""" return self.run() == 1 def getconfig(self): """Returns selected config options""" res = self.res.get_active_text().split(' ') levels = [] for i in range(len(self.levlist)): levels.append(self.levlist[i].get_value()) settings = { 'olines': self.olines.get_active(), 'theme' : self.theme.get_active_text(), 'sinfo' : self.showinfo.get_active(), '3d' : self.effect3d.get_active(), 'vcheck': self.vcheck.get_active(), 'aname' : self.aname.get_text(), 'amail' : self.amail.get_text(), 'fdesc' : self.fdesc.desc, 'ftitle': self.ftitle.desc, 'fgrad' : self.fgrad.desc, 'width' : res[0], 'height': res[2], 'serv' : self.serv.get_active_text(), 'colors': ['rgb(%d,%d,%d)' % (color.red>>8, color.green>>8, color.blue>>8) for color in self.colorlist], 'levels': levels } return settings def destroy(self, event=None): """Destroy current Preferences""" gtk.Dialog.destroy(self) class Map(gtk.Dialog): """Show map of slopes""" def __init__(self, parent, slopename, stringc, savefnct): gtk.Window.__init__(self) self.set_size_request(640, 480)#FIXME:take webpage dimension self.set_title(_(u"Map")+" - "+ slopename) self.set_icon_from_file(ICON_FILENAME) self.set_resizable(True) self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) self.savefnct = savefnct self.view = webkit.WebView() sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) #sw.set_placement(gtk.CORNER_TOP_LEFT) sw.add(self.view) swframe = gtk.Frame() swframe.add(sw) obox = gtk.HBox() obox.pack_start(swframe, True, True, 0) bbox = gtk.HBox() button_s = gtk.Button(None, gtk.STOCK_SAVE) bbox.pack_end(button_s, False, False, 5) button_s.connect("clicked", self.onsave) box = gtk.VBox(False, 0) box.pack_start(obox, True, True, 0) box.pack_start(bbox, False, False, 5) self.vbox.pack_start(box) self.show_all() MAP_SCRIPT = "" try: fid = open(os.path.join(os.path.dirname(__file__), "../map.html"), 'rb') for line in fid: MAP_SCRIPT += line fid.close() except IOError: print("map.html not loaded\n") return HTML_MAP = MAP_SCRIPT % (stringc,) self.view.load_html_string(HTML_MAP, "file:///") def onsave(self, event): """ Save call""" self.savefnct(self) def saveimage(self, filepath): """ Save map image""" winw, winh = self.get_size() vieww, viewh = self.view.size_request() diff = (winw - vieww) / 2 colormap = self.get_colormap() pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, vieww, viewh) pixbuf = pixbuf.get_from_drawable(self.window, colormap, diff, diff, 0, 0, vieww, viewh) fformat = filepath.rsplit('.', 1)[1] if fformat.lower() == 'png': pixbuf.save(filepath, 'png') if fformat.lower() == 'bmp': pixbuf.save(filepath, "bmp") if fformat.lower() == 'jpg': pixbuf.save(filepath, "jpeg", {"quality":"100"}) class Create_kml(gtk.Dialog): """Create kml routes""" MODE = {_(u'Open Route Service') : 'ORS', _(u'OSRM') : 'OSRM', _(u"Draw on the map") : 'DRAW'} def __init__(self, parent, downloadfunc, savefunc): gtk.Window.__init__(self) self.set_size_request(640, 480)#FIXME:take webpage dimension self.set_title(_(u"Create Kml")) self.set_icon_from_file(ICON_FILENAME) self.set_resizable(True) self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) self.downloadfunc = downloadfunc self.savefunc = savefunc self.handler = None self.mode = 'ORS' self.view = webkit.WebView() sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.set_placement(gtk.CORNER_TOP_LEFT) sw.add(self.view) store = gtk.ListStore(str) store.append([_(u'Open Route Service')]) store.append([_(u'OSRM')]) store.append([_(u'Draw on the map')]) treeview = gtk.TreeView(store) treeview.connect("cursor-changed", self.mode_changed) renderertext = gtk.CellRendererText() column = gtk.TreeViewColumn("Views", renderertext, text=0) column.set_sort_column_id(0) treeview.append_column(column) frame = gtk.Frame(_(u'Modes')) frame.add(treeview) swframe = gtk.Frame() swframe.add(sw) treeview.set_cursor(0) treeview.set_headers_visible(False) obox = gtk.HBox() obox.pack_start(frame, False, True, 5) obox.pack_start(swframe, True, True, 5) bbox = gtk.HBox() button_k = gtk.Button(None, gtk.STOCK_OK) button_s = gtk.Button(None, gtk.STOCK_SAVE) button_c = gtk.Button(None, gtk.STOCK_CANCEL) bbox.pack_end(button_k, False, False, 5) bbox.pack_end(button_s, False, False, 5) bbox.pack_end(button_c, False, False, 5) button_k.connect("clicked", self.import_kml) button_s.connect("clicked", self.save_kml) button_c.connect("clicked", self.cancel) box = gtk.VBox(False, 0) box.pack_start(obox, True, True, 5) box.pack_start(bbox, False, False, 5) self.vbox.pack_start(box) self.show_all() self.webview_init() def webview_init(self): """ Check mode and set webview accordingly""" if self.mode == 'ORS': self.view.open("http://openrouteservice.org/") elif self.mode == 'OSRM': self.view.open("http://map.project-osrm.org/") elif self.mode == 'DRAW': HTML_DRAW = "" try: fid = open(os.path.join(os.path.dirname(__file__),"../openlayers.html"), 'rb') for line in fid: HTML_DRAW += line fid.close() except IOError: print("openlayers.html not loaded\n") exit(1) self.view.load_html_string(HTML_DRAW.replace("file://./draw_on_map.js","file://"+os.path.join(os.path.dirname(__file__), "../draw_on_map.js")), "file:///") def mode_changed(self, widget): """ Change current mode""" selection = widget.get_selection() if selection is None: return model, treeiter = selection.get_selected() if treeiter is None: return newmode = self.MODE[model.get_value(treeiter, 0)] if newmode != self.mode: self.mode = newmode self.webview_init() def import_kml(self, event): """ Import route in CycloGraph""" self.download() self.response(True) def get_ors(self): """ Returns gpx content from ORS service""" self.view.execute_script("oldtitle=document.title;document.title=document.getElementById('gpx').innerHTML") gpxcontent = unicode(self.view.get_main_frame().get_title()) self.view.execute_script('document.title=oldtitle;') from xml.sax.saxutils import unescape return StringIO.StringIO(unescape(gpxcontent)) def get_osrm(self): """ Returns gpx content from ORSM service""" self.view.execute_script("oldtitle=document.title;document.title=document.getElementsByClassName('text-link')[1].getAttribute('onclick')") gpxcontent = unicode(self.view.get_main_frame().get_title()) url = gpxcontent.split('\'') self.view.execute_script('document.title=oldtitle;') return self.downloadfunc(url[1]) def get_draw(self): """ Returns kml content from DRAW mode""" self.view.execute_script("oldtitle=document.title;document.title=createKml()") kmlstring = self.view.get_main_frame().get_title() self.view.execute_script('document.title=oldtitle;') return StringIO.StringIO(kmlstring) def download(self): """ Download selected route""" if self.mode == 'ORS': self.handler = self.get_ors() elif self.mode == 'OSRM': self.handler = self.get_osrm() elif self.mode == 'DRAW': self.handler = self.get_draw() def save_kml(self, event): """Save selected route to file""" self.download() if not self.handler: return self.savefunc(self.handler, self.mode) def cancel(self, event): """ Cancel create kml dialog""" self.destroy() def show_modal(self): """Shows the dialog and returns True if the value has to be changed.""" return self.run() == 1 FONT_TYP = { "300" : "light", "400" : "normal", "700" : "bold", } def preferences(parent, cgpref, defaultpref): """ Show Preference dialog""" pref = Preferences(parent, cgpref, defaultpref) pref_conf = {} if pref.show_modal(): pref_conf = pref.getconfig() pref.destroy() return pref_conf def formslopeinfo(parent, slopedata): """ Show slope's info dialog""" dlg = FormSlopeInfo(parent, slopedata) if dlg.show_modal(): data = dlg.getslopeinfo() dlg.destroy() return data else: dlg.destroy() return {} def FileDialog(parent, title, dirname, filename, other, file_types, rw, fd_open, fd_save): """ Show file dialog for open or save slopes""" if rw == fd_open: dlg = gtk.FileChooserDialog(title, parent, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) elif rw == fd_save: dlg = gtk.FileChooserDialog(title, parent, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) dlg.set_do_overwrite_confirmation(True) if filename: dlg.set_current_name(filename) for elem in file_types: ffilter = gtk.FileFilter() ffilter.set_name(elem[0]) for pattern in elem[1].split(' '): ffilter.add_pattern(pattern) ffilter.add_pattern(pattern.upper()) #print(pattern) #print("----") dlg.add_filter(ffilter) head, tail = os.path.split(dirname) dlg.set_current_folder(head) if tail: dlg.set_current_name(tail) response = dlg.run() if response == gtk.RESPONSE_OK: filename = dlg.get_filename() dlg.destroy() return unicode(filename) else: dlg.destroy() return None class ProgressDialog(gtk.Dialog): """Progress dialog for import Kml function""" def __init__(self, title, label, limit): gtk.Dialog.__init__(self, title, None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) self.set_size_request(330, 150) box = gtk.VBox() self.limit = limit self.label = gtk.Label(label) self.pbar = gtk.ProgressBar() align = gtk.Alignment(0.5, 0.5, 0.5, 0.5) align.show() align.add(self.pbar) self.pbar.show() self.pbar.set_fraction(0.0) self.pbar.set_orientation(gtk.PROGRESS_LEFT_TO_RIGHT) self.pbar.set_text("0"+" %") box.pack_start(self.label, False, False, 10) box.pack_start(align, False, False, 5) self.wanttoabort = False self.connect("response", self.abort) self.vbox.pack_start(box) box.show_all() self.show_all() def update(self, value): """Update the progress shown and return if user want to abort.""" self.pbar.set_fraction(value/self.limit) self.pbar.set_text(str(value/10)+" %") return self.wanttoabort def abort(self, dialog, response): """When the abort button is pressed this method is called and it updates the status of this object to take track of user action""" self.wanttoabort = (response in (gtk.RESPONSE_REJECT, gtk.RESPONSE_DELETE_EVENT)) def destroy(self): """Destroy current FormSlopeInfo""" gtk.Dialog.destroy(self) class NumcpsDialog(gtk.Dialog): """ask cps number you want to import""" def __init__(self, max_num_cps, max_length, file_ext): gtk.Dialog.__init__(self, _(u"number of checkpoints"), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR, None) self.set_size_request(330, 250) box = gtk.VBox() self.notebook = gtk.Notebook() self.notebook.set_show_tabs(False) self.connect("delete-event", self.abort) frame = gtk.Frame() vbox_1 = gtk.VBox() label = gtk.Label(_(u"Choose the type of import you want")) vbox_1.pack_start(label, False, False, 15) hboxr = gtk.HBox() vboxr = gtk.VBox() self.button1 = gtk.RadioButton(None, _(u"Automatic")) self.button1.set_active(True) vboxr.pack_start(self.button1, False, False, 0) self.button2 = gtk.RadioButton(self.button1) self.button2.set_label(_(u"Select the number of checkpoints")) vboxr.pack_start(self.button2, False, False, 0) self.button3 = gtk.RadioButton(self.button1) self.button3.set_label(_(u"Select the distance rate")) vboxr.pack_start(self.button3, False, False, 0) self.button4 = gtk.RadioButton(self.button1) self.button4.set_label(_(u"Use every point (discouraged)")) vboxr.pack_start(self.button4, False, False, 0) hboxr.pack_start(vboxr, False, False, 30) bbox = gtk.HBox() button_n = gtk.Button(_(u"Next")) bbox.pack_end(button_n, False, False, 5) button_n.connect("clicked", self.next_clicked) vbox_1.pack_end(bbox, False, False, 10) vbox_1.pack_end(hboxr, False, False, 5) frame.add(vbox_1) frame.set_shadow_type(gtk.SHADOW_NONE) self.notebook.append_page(frame, gtk.Label("1")) frame = gtk.Frame() label = gtk.Label(_(u"The %s file contains %d points.\nChoose how many will be imported.") % (file_ext, max_num_cps)) self.gpxnum = gtk.HScale() self.gpxnum.set_range(0, max_num_cps) self.gpxnum.set_increments(1, 1) self.gpxnum.set_digits(0) self.gpxnum.set_size_request(160, 38) self.gpxnum.set_value(0) box.pack_start(label, False, False, 5) box.pack_start(self.gpxnum, False, False, 5) bbox = gtk.HBox() button_n = gtk.Button(_(u"Finish")) button_c = gtk.Button(_(u"Back")) bbox.pack_end(button_n, False, False, 5) bbox.pack_end(button_c, False, False, 5) button_n.connect("clicked", self.next_clicked) button_c.connect("clicked", self.back_clicked) box.pack_end(bbox, False, False, 10) frame.add(box) frame.set_shadow_type(gtk.SHADOW_NONE) self.notebook.append_page(frame, gtk.Label("2")) frame = gtk.Frame() boxdist = gtk.VBox() label = gtk.Label(_(u"The %s file contains a route of %d Km.\nChoose what range you want between points.") % (file_ext, max_length)) self.gpxdist = gtk.HScale() self.gpxdist.set_range(0, int(max_length)) self.gpxdist.set_increments(1, 1) self.gpxdist.set_digits(0) self.gpxdist.set_size_request(160, 38) self.gpxdist.set_value(0) boxdist.pack_start(label, False, False, 5) boxdist.pack_start(self.gpxdist, False, False, 5) bbox = gtk.HBox() button_n = gtk.Button(_(u"Finish")) button_c = gtk.Button(_(u"Back")) bbox.pack_end(button_n, False, False, 5) bbox.pack_end(button_c, False, False, 5) button_n.connect("clicked", self.next_clicked) button_c.connect("clicked", self.back_clicked) boxdist.pack_end(bbox, False, False, 10) frame.add(boxdist) frame.set_shadow_type(gtk.SHADOW_NONE) self.notebook.append_page(frame, gtk.Label("3")) self.notebook.set_current_page(0) self.notebook.show_all() carea = self.get_content_area() carea.pack_start(self.notebook, True, True, 0) self.show_all() def next_clicked(self, event): "Show next page" if self.notebook.get_current_page() == 0: if self.button1.get_active(): self.response(True) elif self.button2.get_active(): self.notebook.set_current_page(1) self.notebook.show_all() elif self.button3.get_active(): self.notebook.set_current_page(2) self.notebook.show_all() elif self.button4.get_active(): self.response(True) else: self.response(True) def back_clicked(self, event): "Show initial page" self.notebook.set_current_page(0) self.notebook.show_all() def destroy(self): """Destroy current dialog""" gtk.Dialog.destroy(self) def abort(self, event=None, param=None): """Abort import""" self.response(False) gtk.Dialog.destroy(self) def geterrnoroute(parent): """Get an error message explaining that you should have selected one route""" mdlg = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, _(u"Specify one route first.")) mdlg.set_title(_(u'No route')) mdlg.run() mdlg.destroy() def managecperr(parent): """Get an error message explaining that you should have inserted altitude and distance""" mdlg = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, _("Distance and altitude are required.")) mdlg.set_title(_("Form incomplete")) mdlg.run() mdlg.destroy() def mapcoorderr(parent): """Get an error message explaining that there are no coords in the slope""" mdlg = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, _("there aren't coordinates associated with this slope.")) mdlg.set_title(_("No coordinates")) mdlg.run() mdlg.destroy() def geterrnocp(parent): """Get an error message explaining that you should have at least 2 cps to plot""" mdlg = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _(u"""There aren't enougth check points to plot. At least two points are required to plot.""")) mdlg.set_title(_(u'Not enough check points')) mdlg.run() mdlg.destroy() def numcpsdlg(max_num_cps, max_length, file_ext): """ask what number of cps in a gpx or tcx files have to be imported""" dlg = NumcpsDialog(max_num_cps, max_length, file_ext) response = dlg.run() if response == False: return (-1, 0) if dlg.button1.get_active(): dlg.destroy() return (0, -1) elif dlg.button2.get_active(): val = dlg.gpxnum.get_value() dlg.destroy() return (0, int(val)) elif dlg.button3.get_active(): val = dlg.gpxdist.get_value() dlg.destroy() return (1, int(val)) elif dlg.button4.get_active(): dlg.destroy() return (0, max_num_cps) def save_changes(parent, filename): """Show a message if you close a modified and not saved slope""" response = None text = ""+(_(u"Save changes to %s before closing?") % filename)+"" secondary_text = _(u"If you don't save, all your changes will be " "permanently lost.") mdlg = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, text) mdlg.set_title(_(u'Save changes')) mdlg.set_markup(text) mdlg.format_secondary_text(secondary_text) mdlg.add_buttons(_(u'Close without saving'), gtk.RESPONSE_REJECT, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT) mdlg.set_default_response(gtk.RESPONSE_ACCEPT) response = mdlg.run() mdlg.destroy() if response == gtk.RESPONSE_ACCEPT: return 'SAVE' if response == gtk.RESPONSE_REJECT: return 'DISCARD' if response == gtk.RESPONSE_CANCEL: return 'CANCEL' return response # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/glal_selected.py0000644000175000017500000000227212065361217022536 0ustar federicofederico00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """glal_selected.py """ # Copyright (C) 2011 Federico Brega # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. import os.path import sys INTERFACES = {'qt': 'qt', 'gtk': 'gtk_', 'gtk3': 'gtk3', 'cli': 'glal.py'} if_path = os.path.join(os.path.dirname(os.path.abspath(__file__))) def use(lib): """Set lib to use""" global library if not (lib in INTERFACES and os.path.exists(os.path.join(if_path, INTERFACES[lib]))): sys.stderr.write(lib + ' interface not installed\n') return None library = lib return library def getname(): """Return name of the used interface""" return library # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/themes.py0000644000175000017500000007205412204123117021227 0ustar federicofederico00000000000000# -*- coding: utf-8 -*- #themes.py """This module provides a graphic theme for plotting""" # Copyright (C) 2010, 2011, 2012, 2013 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from __future__ import unicode_literals class ThemeManager: def getthemeslist(self): """Return names associated with classes subclassing Theme.""" return sorted(Theme.themes.keys()) def gettheme(self, name): """Return reference to the given class name.""" if name in Theme.themes: return Theme.themes[name] return None class ThemeMount(type): #from http://martyalchin.com/2008/jan/10/simple-plugin-framework/ def __init__(cls, name, bases, attrs): if not hasattr(cls, 'themes'): # This branch only executes when processing the mount point itself. # So, since this is a new plugin type, not an implementation, this # class shouldn't be registered as a plugin. Instead, it sets up a # list where plugins can be registered later. cls.themes = {} else: # This must be a plugin implementation, which should be registered. # Simply appending it to the list is all that's needed to keep # track of it later. #if cls.themename in cls.themes: # TODO: if user can create/install themes warn if a name is # used by more than one theme #return cls.themes[cls.themename] = cls class Theme: """Model of a theme: every theme must subclass this class.""" __metaclass__ = ThemeMount themename = "" shear = -0.15 @staticmethod def getcolor(colors, levels, grad): """Return gradient relative color""" pass @staticmethod def drawslopeinfo(devc, info, settings, startx, starty): """Draw slope's name and other info background""" pass @staticmethod def paintbackground(devc, width, height): """Draw background""" pass @staticmethod def gradback(devc, width, height, setting_f, startcol="rgb(64, 185, 255)", endcol='white'): """Draw a gradient background""" pass @staticmethod def olines(devc, slope, margins, width, height, metersize): """Draw altitude line""" pass @staticmethod def alttext(devc, slope, margins, max_y, metersize): """draw altitude text aside""" pass @staticmethod def yaxis(devc, slope, margins, max_y, metersize): """Draw y axis""" pass @staticmethod def xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy): """Draw km bar""" pass @staticmethod def fillhslopecontour(devc, spath_back, dx, dy, colorlist): """ Draw horizontal contour.""" pass @staticmethod def fillhpoly(devc, points, color): """fill horizontal polygons of the 3d slope""" pass @staticmethod def fillfirsthpoly(devc, points, color): """fill first horizontal polygon of the 3d slope""" @staticmethod def fillvslopecontour(devc, path_points, pixel_0m, pixel_1000m, vpolygons, colorlist): """Draw a close smooth path thant contais the whole slope.""" pass @staticmethod def fillvpoly(devc, points, color): """fill vertical polygons (2d and 3d) of the slope""" pass @staticmethod def desctext(devc, text, pos_x, pos_y, font): """Draw description text for every cp""" pass @staticmethod def gradtext(devc, text, pos_x, pos_y, font): """Draw gradient text for every cp""" pass class ThemeClassic(Theme): """Classic CycloGraph theme""" themename = "Classic" shear = -0.15 @staticmethod def getcolor(colors, levels, grad): """Return gradient relative color""" gradient = abs(grad) for i in range(len(levels)): if gradient < levels[i]: return colors[i-1] return colors[i] @staticmethod def drawslopeinfo(devc, info, settings, startx, starty): """Draw slope's name and other info background""" name, avp, maxp, eleg, heightg = info devc.setfont(settings['ftitle']) devc.drawtext(name, startx, starty) if settings['sinfo']: devc.setfont(settings['fdesc']) devc.drawtext(avp, startx+10, starty+20) devc.drawtext(maxp, startx+10, starty+40) devc.drawtext(eleg, startx+10, starty+60) devc.drawtext(heightg, startx+10, starty+80) @staticmethod def paintbackground(devc, width, height): """Draw backgroundr""" devc.setbrush("rgb(255, 255, 255)") rec = (0, 0, width, height) devc.drawrectangle(*rec) @staticmethod def gradback(devc, width, height, setting_f, startcol="rgb(64, 185, 255)", endcol='white'): """Draw a gradient background""" area = (0, 0, width, height) devc.gradfill(area, startcol, endcol) devc.setpen('black', 1) devc.setfont(setting_f) @staticmethod def olines(devc, slope, margins, width, height, metersize): """Draw altitude line""" devc.setpen("rgb(150, 150, 150)", 1) (updownmar, leftrightmar) = margins (lef_mar, rig_mar) = leftrightmar (upp_mar, low_mar) = updownmar x0_alt_bar = lef_mar - 3 x1_alt_bar = width - rig_mar - 3 y_alt_base_bar = height - low_mar for i in range(int(slope.min_h / slope.h_incr), int((slope.max_h / slope.h_incr) + 1)): yincr = int((i * slope.h_incr - slope.min_h) * metersize) devc.drawline(x0_alt_bar, y_alt_base_bar - yincr, x1_alt_bar, y_alt_base_bar - yincr) @staticmethod def alttext(devc, slope, margins, max_y, metersize): """draw altitude text aside""" (updownmar, leftrightmar) = margins (lef_mar, rig_mar) = leftrightmar (upp_mar, low_mar) = updownmar devc.setpen('black', 2) x_alt_txt = lef_mar - 40 y_alt_base_txt = max_y - low_mar - 8 for i in range(int(slope.min_h/slope.h_incr), int((slope.max_h/slope.h_incr) + 1)): yincr = int((i * slope.h_incr - slope.min_h) * metersize) alti_t = ("%4d" % (i*slope.h_incr)) devc.drawtext(alti_t, x_alt_txt, y_alt_base_txt - yincr) @staticmethod def yaxis(devc, slope, margins, max_y, metersize): """Draw y axis""" (updownmar, leftrightmar) = margins (lef_mar, rig_mar) = leftrightmar (upp_mar, low_mar) = updownmar linesnum = int(slope.max_h / slope.h_incr) devc.drawline(lef_mar, max_y - low_mar + 4, lef_mar, max_y - low_mar - 8 \ - int(linesnum * slope.h_incr - slope.min_h )* metersize) @staticmethod def xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy): """Draw km bar""" (updownmar, leftrightmar) = margins (lef_mar, rig_mar) = leftrightmar (upp_mar, low_mar) = updownmar for i in range(int(slope.max_d) / d_incr - int(slope.min_d) / d_incr + 1): if i % 2 == 0 : devc.setbrush("rgb(0, 0, 0)") else : devc.setbrush("rgb(255, 255, 255)") rec = (i * d_incr * kmsize + lef_mar + dx, max_y - low_mar + dy, d_incr * kmsize + 1, 5) devc.drawrectangle(*rec) d_label = ("%d" % (i * d_incr +int(slope.min_d))) devc.drawtext(d_label, rec[0], rec[1] + 5) @staticmethod def fillhpoly(devc, points, color): """fill horizontal polygons of the 3d slope""" devc.setbrush(color) devc.drawpolygon(points) @staticmethod def fillfirsthpoly(devc, points, color): """fill first horizontal polygon of the 3d slope""" devc.setbrush(color) devc.drawpolygon(points) @staticmethod def fillvpoly(devc, points, color): """fill vertical polygons (2d and 3d) of the slope""" devc.setbrush(color) devc.drawpolygon(points) @staticmethod def desctext(devc, text, pos_x, pos_y, font): """Draw description text for every cp""" devc.setfont(font) devc.drawrotatedtext(text, pos_x, pos_y, 90) @staticmethod def gradtext(devc, text, pos_x, pos_y, font): """Draw gradient text for every cp""" devc.setfont(font) devc.drawtext(text, pos_x, pos_y) class ThemeBclassic(Theme): """Bezier classic CycloGraph theme""" themename = "Smooth classic" shear = -0.15 @staticmethod def getcolor(colors, levels, grad): """Return gradient relative color""" gradient = abs(grad) for i in range(len(levels)): if gradient < levels[i]: return colors[i-1] return colors[i] @staticmethod def drawslopeinfo(devc, info, settings, startx, starty): """Draw slope's name and other info background""" ThemeClassic.drawslopeinfo(devc, info, settings, startx, starty) @staticmethod def paintbackground(devc, width, height): """Draw backgroundr""" ThemeClassic.paintbackground(devc, width, height) @staticmethod def gradback(devc, width, height, setting_f, startcol="rgb(64, 185, 255)", endcol='white'): """Draw a gradient background""" ThemeClassic.gradback(devc, width, height, setting_f, startcol, endcol) @staticmethod def olines(devc, slope, margins, width, height, metersize): """Draw altitude line""" ThemeClassic.olines(devc, slope, margins, width, height, metersize) @staticmethod def alttext(devc, slope, margins, max_y, metersize): """draw altitude text aside""" ThemeClassic.alttext(devc, slope, margins, max_y, metersize) @staticmethod def yaxis(devc, slope, margins, max_y, metersize): """Draw y axis""" ThemeClassic.yaxis(devc, slope, margins, max_y, metersize) @staticmethod def xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy): """Draw km bar""" ThemeClassic.xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy) @staticmethod def fillhslopecontour(devc, spath_back, dx, dy, colorlist): """ Draw horizontal contour.""" spath_back.reverse() index = 0 for pnts in spath_back: devc.setbrush(colorlist[index]) index = index + 1 path = devc.startpath(pnts[0]) devc.drawpathcubicto(path, pnts[1:]) point = (pnts[3][0]+dx, pnts[3][1]+dy) points = [(pnts[2][0]+dx, pnts[2][1]+dy), (pnts[1][0]+dx, pnts[1][1]+dy), (pnts[0][0]+dx, pnts[0][1]+dy)] devc.drawpathlineto(path, point) pnts = list(pnts) pnts.reverse() devc.drawpathcubicto(path, points) devc.endpath(path) @staticmethod def fillfirsthpoly(devc, points, color): """fill first horizontal polygon of the 3d slope""" ThemeClassic.fillfirsthpoly(devc, points, color) @staticmethod def fillvslopecontour(devc, path_points, pixel_0m, pixel_1000m, vpolygons, colorlist): """Draw a close smooth path thant contais the whole slope.""" index = 0 start_pnt = path_points.pop(0) point = path_points[0] start_pnt = point[0] for pnt in path_points[:-1]: devc.setbrush(colorlist[index]) path = devc.startpath(start_pnt) devc.drawpathcubicto(path, pnt[1:]) devc.drawpathlineto(path, vpolygons[index][1]) devc.drawpathlineto(path, vpolygons[index][0]) devc.drawpathlineto(path, vpolygons[index][3]) devc.endpath(path) start_pnt = pnt[3] index = index + 1 @staticmethod def desctext(devc, text, pos_x, pos_y, font): """Draw description text for every cp""" ThemeClassic.desctext(devc, text, pos_x, pos_y, font) @staticmethod def gradtext(devc, text, pos_x, pos_y, font): """Draw gradient text for every cp""" ThemeClassic.gradtext(devc, text, pos_x, pos_y, font) class ThemeBwhite(Theme): """bezier white theme""" themename = "giro" shear = -0.15 @staticmethod def getcolor(colors, levels, grad): """Return gradient relative color""" ThemeClassic.getcolor(colors, levels, grad) @staticmethod def drawslopeinfo(devc, info, settings, startx, starty): """Draw slope's name and other info background""" ThemeClassic.drawslopeinfo(devc, info, settings, startx, starty) @staticmethod def paintbackground(devc, width, height): """Draw background""" ThemeClassic.paintbackground(devc, width, height) @staticmethod def gradback(devc, width, height, setting_f, startcol="rgb(0, 0, 0)", endcol="rgb(70, 80, 70)"): """Draw a gradient background""" devc.setfont(setting_f)#FIXME: move setfont in a new method @staticmethod def alttext(devc, slope, margins, max_y, metersize): """draw altitude text aside""" ThemeClassic.alttext(devc, slope, margins, max_y, metersize) @staticmethod def yaxis(devc, slope, margins, max_y, metersize): """Draw y axis""" ThemeClassic.yaxis(devc, slope, margins, max_y, metersize) @staticmethod def xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy): """Draw km bar""" ThemeClassic.xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy) @staticmethod def fillhslopecontour(devc, spath_back, dx, dy, colorlist): """ Draw horizontal contour.""" devc.setbrush("rgb(207, 208, 212)") spath_back.reverse() for pnts in spath_back: path = devc.startpath(pnts[0]) devc.drawpathcubicto(path, pnts[1:]) point = (pnts[3][0]+dx, pnts[3][1]+dy) points = [(pnts[2][0]+dx, pnts[2][1]+dy), (pnts[1][0]+dx, pnts[1][1]+dy), (pnts[0][0]+dx, pnts[0][1]+dy)] devc.drawpathlineto(path, point) pnts = list(pnts) pnts.reverse() devc.drawpathcubicto(path, points) devc.endpath(path) @staticmethod def fillfirsthpoly(devc, points, color): """fill first horizontal polygon of the 3d slope""" devc.setbrush("rgb(207, 208, 212)") devc.drawpolygon(points) @staticmethod def fillvslopecontour(devc, path_points, pixel_0m, pixel_1000m, vpolygons, colorlist): """Draw a close smooth path thant contais the whole slope.""" devc.setlineargradientbrush([("rgb(255, 253, 241)", 0), ("rgb(255, 253, 241)", 0.25), ("rgb(222, 234, 190)", 0.50), ("rgb(240, 236, 189)", 0.75), ("rgb(233, 198, 153)", 1)], (0, pixel_0m), (0, pixel_0m + (pixel_1000m - pixel_0m)*1.8)) start_pnt = path_points.pop(0) path = devc.startpath(start_pnt) ctrl_pnts = path_points.pop(0) devc.drawpathlineto(path, ctrl_pnts[0]) devc.drawpathcubicto(path, ctrl_pnts[1:]) for pnt in path_points[:-1]: devc.drawpathcubicto(path, pnt[1:]) devc.drawpathlineto(path, path_points[-1]) devc.endpath(path) @staticmethod def desctext(devc, text, pos_x, pos_y, font): """Draw description text for every cp""" ThemeClassic.desctext(devc, text, pos_x, pos_y, font) class ThemeBlue(Theme): """Blue theme""" themename = "Blue" shear = -0.15 @staticmethod def getcolor(colors, levels, grad): """Return gradient relative color""" gradient = abs(grad) for i in range(len(levels)): if gradient < levels[i]: return colors[i-1] return colors[i] @staticmethod def drawslopeinfo(devc, info, settings, startx, starty): """Draw slope's name and other info background""" name, avp, maxp, eleg, heightg = info devc.setfont(settings['ftitle']) devc.setpen('black', 1) devc.drawtext(name, startx, starty) if settings['sinfo']: devc.setfont(settings['fdesc']) devc.drawtext(avp, startx+10, starty+20) devc.drawtext(maxp, startx+10, starty+40) devc.drawtext(eleg, startx+10, starty+60) devc.drawtext(heightg, startx+10, starty+80) @staticmethod def paintbackground(devc, width, height): """Draw background""" devc.setbrush("rgb(255, 255, 255)") rec = (0, 0, width, height) devc.drawrectangle(*rec) @staticmethod def gradback(devc, width, height, setting_f, startcol="rgb(255, 255, 255)", endcol="rgb(250, 250, 250)"): """Draw a gradient background""" area = (0, 0, width, height) devc.gradfill(area, startcol, endcol) devc.setpen('black', 1) devc.setfont(setting_f) @staticmethod def olines(devc, slope, margins, width, height, metersize): """Draw altitude line""" devc.setpen("rgb(200, 200, 250)", 1) (updownmar, leftrightmar) = margins (lef_mar, rig_mar) = leftrightmar (upp_mar, low_mar) = updownmar x0_alt_bar = lef_mar - 3 x1_alt_bar = width - rig_mar - 3 y_alt_base_bar = height - low_mar for i in range(int(slope.min_h / slope.h_incr), int((slope.max_h / slope.h_incr) + 1)): yincr = int((i * slope.h_incr - slope.min_h) * metersize) devc.drawline(x0_alt_bar, y_alt_base_bar - yincr, x1_alt_bar, y_alt_base_bar - yincr) @staticmethod def alttext(devc, slope, margins, max_y, metersize): """draw altitude text aside""" (updownmar, leftrightmar) = margins (lef_mar, rig_mar) = leftrightmar (upp_mar, low_mar) = updownmar devc.setpen('black', 2) x_alt_txt = lef_mar - 40 y_alt_base_txt = max_y - low_mar - 8 for i in range(int(slope.min_h/slope.h_incr), int((slope.max_h/slope.h_incr) + 1)): yincr = int((i * slope.h_incr - slope.min_h) * metersize) alti_t = ("%4d" % (i*slope.h_incr)) devc.drawtext(alti_t, x_alt_txt, y_alt_base_txt - yincr) @staticmethod def yaxis(devc, slope, margins, max_y, metersize): """Draw y axis""" ThemeClassic.yaxis(devc, slope, margins, max_y, metersize) @staticmethod def xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy): """Draw km bar""" devc.setpen('black', 1) ThemeClassic.xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy) @staticmethod def fillhpoly(devc, points, color): """fill horizontal polygons of the 3d slope""" devc.setpen('black', 1) devc.setbrush("rgb(220, 220, 250)") devc.drawpolygon(points) @staticmethod def fillfirsthpoly(devc, points, color): """fill first horizontal polygon of the 3d slope""" devc.setpen('black', 1) #devc.setbrush(color) devc.setlineargradientbrush([("rgb(250, 250, 250)", 0), ("rgb(200, 200, 250)", 1)], (0, points[3][1]), (0, devc.size_y/2)) devc.drawpolygon(points) @staticmethod def fillvpoly(devc, points, color): """fill vertical polygons (2d and 3d) of the slope""" devc.setpen('black', 1) #devc.setbrush(color) devc.setlineargradientbrush([("rgb(250, 250, 250)", 0), ("rgb(200, 200, 250)", 1)], (0, points[1][1]), (0, devc.size_y/2))#max(points[3][1], points[2][1]))) devc.drawpolygon(points) @staticmethod def desctext(devc, text, pos_x, pos_y, font): """Draw description text for every cp""" devc.setpen('black', 1) devc.setfont(font) devc.drawrotatedtext(text, pos_x, pos_y, 90) @staticmethod def gradtext(devc, text, pos_x, pos_y, font): """Draw gradient text for every cp""" devc.setpen('black', 1) devc.setfont(font) devc.drawtext(text, pos_x, pos_y) class ThemeBlack(Theme): """Black theme""" themename = "Black" shear = -0.15 @staticmethod def getcolor(colors, levels, grad): """Return gradient relative color""" gradient = abs(grad) for i in range(len(levels)): if gradient < levels[i]: return colors[i-1] return colors[i] @staticmethod def drawslopeinfo(devc, info, settings, startx, starty): """Draw slope's name and other info background""" name, avp, maxp, eleg, heightg = info devc.setfont(settings['ftitle']) devc.setpen('white', 1) devc.drawtext(name, startx, starty) if settings['sinfo']: devc.setfont(settings['fdesc']) devc.drawtext(avp, startx+10, starty+20) devc.drawtext(maxp, startx+10, starty+40) devc.drawtext(eleg, startx+10, starty+60) devc.drawtext(heightg, startx+10, starty+80) @staticmethod def paintbackground(devc, width, height): """Draw background""" devc.setbrush("rgb(70, 80, 70)") rec = (0, 0, width, height) devc.drawrectangle(*rec) @staticmethod def gradback(devc, width, height, setting_f, startcol="rgb(0, 0, 0)", endcol="rgb(70, 80, 70)"): """Draw a gradient background""" area = (0, 0, width, height) devc.gradfill(area, startcol, endcol) devc.setpen('black', 1) devc.setfont(setting_f) @staticmethod def alttext(devc, slope, margins, max_y, metersize): """draw altitude text aside""" (updownmar, leftrightmar) = margins (lef_mar, rig_mar) = leftrightmar (upp_mar, low_mar) = updownmar devc.setpen('white', 2) x_alt_txt = lef_mar - 40 y_alt_base_txt = max_y - low_mar - 8 for i in range(int(slope.min_h/slope.h_incr), int((slope.max_h/slope.h_incr) + 1)): yincr = int((i * slope.h_incr - slope.min_h) * metersize) alti_t = ("%4d" % (i*slope.h_incr)) devc.drawtext(alti_t, x_alt_txt, y_alt_base_txt - yincr) @staticmethod def yaxis(devc, slope, margins, max_y, metersize): """Draw y axis""" ThemeClassic.yaxis(devc, slope, margins, max_y, metersize) @staticmethod def xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy): """Draw km bar""" (updownmar, leftrightmar) = margins (lef_mar, rig_mar) = leftrightmar (upp_mar, low_mar) = updownmar for i in range(int(slope.max_d) / d_incr - int(slope.min_d) / d_incr + 1): if i % 2 == 0 : devc.setbrush("rgb(0, 0, 0)") else : devc.setbrush("rgb(255, 255, 255)") rec = (i * d_incr * kmsize + lef_mar + dx, max_y - low_mar + dy, d_incr * kmsize + 1, 5) devc.setpen('black', 1) devc.drawrectangle(*rec) devc.setpen('white', 1) d_label = ("%d" % (i * d_incr +int(slope.min_d))) devc.drawtext(d_label, rec[0], rec[1] + 5) @staticmethod def fillhpoly(devc, points, color): """fill horizontal polygons of the 3d slope""" devc.setpen('black', 1) devc.setbrush(color) devc.drawpolygon(points) @staticmethod def fillfirsthpoly(devc, points, color): """fill first horizontal polygon of the 3d slope""" devc.setpen('black', 1) devc.setbrush(color) devc.setlineargradientbrush([("rgb(0, 0, 0)", 0), (color, 1)], (0, points[3][1]), (0, points[1][1])) devc.drawpolygon(points) @staticmethod def fillvpoly(devc, points, color): """fill vertical polygons (2d and 3d) of the slope""" devc.setpen('black', 1) devc.setbrush(color) devc.setlineargradientbrush([("rgb(0, 0, 0)", 0), (color, 1)], (0, points[1][1]), (0, min(points[3][1], points[2][1]))) devc.drawpolygon(points) @staticmethod def desctext(devc, text, pos_x, pos_y, font): """Draw description text for every cp""" devc.setpen('white', 1) devc.setfont(font) devc.drawrotatedtext(text, pos_x, pos_y, 90) @staticmethod def gradtext(devc, text, pos_x, pos_y, font): """Draw gradient text for every cp""" devc.setpen('white', 1) devc.setfont(font) devc.drawtext(text, pos_x, pos_y) class ThemeGray(Theme): """Gray theme""" themename = "Gray" shear = -0.15 @staticmethod def getcolor(colors, levels, grad): """Return gradient relative color""" graycolors = ["rgb(175,175,175)", "rgb(150,150,150)", "rgb(125,125,125)", "rgb(100,100,100)", "rgb(75,75,75)", "rgb(50,50,50)", "rgb(25,25,25)"] gradient = abs(grad) for i in range(len(levels)): if gradient < levels[i]: return graycolors[i-1] return graycolors[i] @staticmethod def drawslopeinfo(devc, info, settings, startx, starty): """Draw slope's name and other info background""" ThemeClassic.drawslopeinfo(devc, info, settings, startx, starty) @staticmethod def paintbackground(devc, width, height): """Draw background""" devc.setbrush('white') rec = (0, 0, width, height) devc.drawrectangle(*rec) @staticmethod def gradback(devc, width, height, setting_f, startcol="rgb(0, 0, 0)", endcol="rgb(70, 80, 70)"): """Draw a gradient background""" area = (0, 0, width, height) devc.setpen('black', 1) devc.setfont(setting_f) @staticmethod def olines(devc, slope, margins, width, height, metersize): """Draw altitude line""" ThemeClassic.olines(devc, slope, margins, width, height, metersize) @staticmethod def alttext(devc, slope, margins, max_y, metersize): """draw altitude text aside""" (updownmar, leftrightmar) = margins (lef_mar, rig_mar) = leftrightmar (upp_mar, low_mar) = updownmar devc.setpen('black', 2) x_alt_txt = lef_mar - 40 y_alt_base_txt = max_y - low_mar - 8 for i in range(int(slope.min_h/slope.h_incr), int((slope.max_h/slope.h_incr) + 1)): yincr = int((i * slope.h_incr - slope.min_h) * metersize) alti_t = ("%4d" % (i*slope.h_incr)) devc.drawtext(alti_t, x_alt_txt, y_alt_base_txt - yincr) @staticmethod def yaxis(devc, slope, margins, max_y, metersize): """Draw y axis""" ThemeClassic.yaxis(devc, slope, margins, max_y, metersize) @staticmethod def xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy): """Draw km bar""" devc.setpen('black', 1) ThemeClassic.xaxis(devc, slope, margins, max_y, d_incr, kmsize, dx, dy) @staticmethod def fillhpoly(devc, points, color): """fill horizontal polygons of the 3d slope""" devc.setpen('black', 1) devc.setbrush(color) devc.drawpolygon(points) @staticmethod def fillfirsthpoly(devc, points, color): """fill first horizontal polygon of the 3d slope""" devc.setpen('black', 1) devc.setbrush(color) devc.setlineargradientbrush([("rgb(0, 0, 0)", 0), (color, 1)], (0, points[3][1]), (0, points[1][1])) devc.drawpolygon(points) @staticmethod def fillvpoly(devc, points, color): """fill vertical polygons (2d and 3d) of the slope""" devc.setpen('black', 1) devc.setbrush("rgb(100, 100, 100)") devc.setbrush(color) devc.setlineargradientbrush([("rgb(0, 0, 0)", 0), (color, 1)], (0, points[1][1]), (0, min(points[3][1], points[2][1]))) devc.drawpolygon(points) @staticmethod def desctext(devc, text, pos_x, pos_y, font): """Draw description text for every cp""" devc.setfont(font) devc.setpen('white', 1) devc.drawrotatedtext(text, pos_x + 1, pos_y + 1, 90) devc.setpen('black', 1) devc.drawrotatedtext(text, pos_x, pos_y, 90) @staticmethod def gradtext(devc, text, pos_x, pos_y, font): """Draw gradient text for every cp""" devc.setfont(font) devc.setpen('black', 1) devc.drawtext(text, pos_x + 1, pos_y + 1) devc.setpen('white', 1) devc.drawtext(text, pos_x, pos_y) # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/cyclograph0000755000175000017500000000022612065361217021453 0ustar federicofederico00000000000000#!/usr/bin/env python try: from launcher import * except ImportError: from cyclograph.launcher import * main() #TODO: use execfile instead? cyclograph-1.6.1/cyclograph/slope.py0000644000175000017500000004427112210713511021064 0ustar federicofederico00000000000000# -*- coding: utf-8 -*- #slope.py """This module provides a model for Cyclograph""" # Copyright (C) 2008, 2009, 2010, 2011, 2013 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from __future__ import unicode_literals import math import glal from themes import ThemeManager class Slope: """Model of a slope""" def __init__(self): """Create a slope model.""" self.cps = [] self.coords = [] self.grad = [] self.dercp = [] self.name = '' self.country = '' self.author = '' self.email = '' self.comment = '' self.url = '' self.reset_calculated() def __len__(self): return len(self.cps) def reset_calculated(self): self.average_grad = 0 self.max_grad = 0 self.height_difference = 0 self.height_gain = 0 def add_cp(self, distance, altitude, name): """ Adds a check-point to a Slope. A check point must have an altitude and a distance from start, it can have also a name or description. """ new_cp = (distance, altitude, name) #check if there is already a cp with the same distance #and in this case remove it # WARNING: when loading from a file this cause complexity to be O(|#cps|^2) #If slowliness occurs consider using a binary search instead. for i in range(len(self.cps)): if self.cps[i][0] == distance: del self.cps[i] break self.cps.append(new_cp) self.cps.sort() self.grad = [] self.reset_calculated() return self.cps.index(new_cp) def add_coord(self, latitude, longitude): """ Adds a coordinate to a Slope. A coordinate must have latitude and longitude. """ new_coord = (latitude, longitude) self.coords.append(new_coord) def remove_cp(self, num): """ Removes check-point num from current slope and clears data.""" del self.cps[num] self.grad = [] self.reset_calculated() def calc(self): """ Update gradient and altitude bounds""" if len(self.cps) > 1: cps = self.cps[:] #Multithread safe? derivate = lambda p0, p1 : (p1[1] - p0[1])/(p1[0] - p0[0]) self.grad = [derivate(cps[i], cps[i+1])/10 for i in range(len(cps)-1)] self.average_grad = 0 self.max_grad = self.grad[0] for i in range(len(self.grad)): if self.grad[i] > self.max_grad: self.max_grad = self.grad[i] self.height_gain = 0 for i in range(len(cps)-1): self.height_gain += max(cps[i+1][1]-cps[i][1], 0) #find max & min altitude #float("inf") doesn't work on Windows self.max_h = -float("1e1000") self.min_h = +float("1e1000") for cpi in self.cps: if cpi[1] > self.max_h: self.max_h = cpi[1] if cpi[1] < self.min_h: self.min_h = cpi[1] self.height_difference = self.max_h - self.min_h self.max_h += 100 self.min_h = int(math.floor(self.min_h/100)) * 100 #min distance is always in the first item self.min_d = self.cps[0][0] #max distance is always in the last item self.max_d = self.cps[-1][0] if self.max_d != 0: self.average_grad = (self.cps[-1][1] - self.cps[0][1]) / (self.max_d * 10) self.dercp = self.smooth() def smooth(self): # References: # Subroutine PCHIM, F. N. Fritsch, Lawrence Livermore National Laboratory. # F. N. Fritsch and J. Butland, "A method for constructing local monotone # piecewise cubic interpolants", SIAM J. Sci. Stat. Comput., vol. 5, # pp. 300-304, June 1984. if not self.grad: return [] if len(self.cps) < 3: #If less than 3 points draw a rect return [self.grad[0] * 10] * 2 der = [0] * len(self.cps) #Inspired by Octave code in dpchim.f grad1 = self.grad[0] * 10 grad2 = self.grad[1] * 10 (h1, h2) = (self.cps[1][0] - self.cps[0][0], self.cps[2][0] - self.cps[1][0]) w1 = (2 * h1 + h2) / (h1 + h2) w2 = -h1 / (h1 + h2) der[0] = w1 * grad1 + w2 * grad2 if der[0] * grad1 <= 0: der[0] = 0 elif grad1 * grad2 < 0: dmax = 3 * grad1 if abs(der[0]) > abs(dmax): der[0] = dmax # Using brodlie modification of butland's formula for i in range(len(self.cps)-2): (h1, h2) = (float(self.cps[i][0] - self.cps[i-1][0]), float(self.cps[i+1][0] - self.cps[i][0])) grad1 = self.grad[i] * 10 grad2 = self.grad[i+1] * 10 if grad1 * grad2 <= 0: der[i] = 0 continue dmax = max(abs(grad1), abs(grad2)) dmin = min(abs(grad1), abs(grad2)) w1 = (2 * h1 + h2) / (3 * (h1 + h2)) w2 = (2 * h2 + h1) / (3 * (h1 + h2)) der[i+1] = dmin / (w1 * grad1 / dmax + w2 * grad2 / dmax) grad1 = self.grad[-2] * 10 grad2 = self.grad[-1] * 10 (h1, h2) = (self.cps[1][0] - self.cps[0][0], self.cps[2][0] - self.cps[1][0]) w1 = - h2 / (h1 + h2) w2 = (2 * h2 + h1) / (h1 + h2) der[-1] = w1 * grad1 + w2 * grad2 if der[-1] * grad2 <= 0: der[-1] = 0 elif grad1 * grad2 < 0: dmax = 3.0 * grad2 if abs(der[-1]) > abs(dmax): der[-1] = dmax return der depth = 100 def paint(self, settings, devc): """ Paint devc from plot""" #upper, lower, right and left margin of area where draw the slope theme = ThemeManager().gettheme(settings['theme']) updownmar = (180, 30) leftrightmar = (50, 10) margins = (updownmar, leftrightmar) (upp_mar, low_mar) = updownmar (lef_mar, rig_mar) = leftrightmar theme.paintbackground(devc, devc.size_x, devc.size_y) (max_x, max_y) = devc.getsize() if settings['3d']: devc.shear(theme.shear*self.depth/100) min_y = max_x*self.depth/100/10 rig_mar = 10 + 20*self.depth/100 else: min_y = 0 theme.gradback(devc, max_x, max_y, settings['fdesc']) #draw altitude bar metersize = (max_y - upp_mar - low_mar - min_y) \ / (self.max_h - self.min_h) self.h_incr = 100 #draw a line every 100m if settings['olines']: theme.olines(devc, self, margins, max_x, max_y, metersize) theme.alttext(devc, self, margins, max_y, metersize) theme.yaxis(devc, self, margins, max_y, metersize) if settings['3d']: (dx, dy) = (20*self.depth/100, 10*self.depth/100) else: (dx, dy) = (0, 0) #draw km bar devc.setpen('black', 1) increments = [1, 2, 5, 10, 20, 50, 100] #km bar resolutions for d_incr in increments: #draw less than 30 bars if (self.max_d - self.min_d) <= 30 * d_incr: break #this must be float otherwise there are problems with long slopes kmsize = (max_x - lef_mar - rig_mar ) / (self.max_d - int(self.min_d)) theme.xaxis(devc, self, margins, max_y, d_incr, kmsize, dx, dy) #draw slope's name s_info = (self.name, _("Average gradient:")+" "+"%.1f" % self.average_grad+" %", _("Max gradient:")+" "+"%.1f" % self.max_grad+" %", _("Height difference:")+" "+str(self.height_difference)+" m", _("Height gain")+": "+str(self.height_gain)+" m") theme.drawslopeinfo(devc, s_info, settings, lef_mar+20, min_y+upp_mar-140) #draw first info text font = settings['fdesc'] theme.desctext(devc, "%.0f %s" % (self.cps[0][1], self.cps[0][2]), lef_mar + int(self.cps[0][0] * kmsize) + 3, max_y -low_mar -10 \ - int((self.cps[0][1] - self.min_h) * metersize), font) #plot the slope #plot orizzontal polygon in reverse order to prevent bad visualization in 3d mode if (dx != 0) and (dy != 0): linkpoints = [] spath_back = [] colorlisth = [] for i in range(len(self.cps)-1): #i = len(self.cps)-1 - k v_a = ( int((self.cps[i][0]-int(self.min_d))* kmsize) , int((self.cps[i][1]-self.min_h)* metersize)) v_b = ( int((self.cps[i+1][0]-int(self.min_d))* kmsize) , int((self.cps[i+1][1]-self.min_h)* metersize)) points = [(lef_mar +v_a[0], max_y -low_mar - v_a[1]), (lef_mar +v_b[0], max_y -low_mar - v_b[1]), (lef_mar +v_b[0]+dx, max_y -low_mar - v_b[1]+dy), (lef_mar +v_a[0]+dx, max_y -low_mar - v_a[1]+dy)] linkpoints.append(points) spath_back.append(polytoBezier(points[0], self.dercp[i] * (-metersize / kmsize), points[1], self.dercp[i+1] * (-metersize / kmsize))) #theme.fillhslopecontour(devc, spath_back, dx, dy) for k in range(len(self.cps)-1): i = len(self.cps)-1 - k-1 color = (theme.getcolor(settings['colors'], settings['levels'], self.grad[i])) colorlisth.append(color) theme.fillhpoly(devc, linkpoints[i], color) theme.fillhslopecontour(devc, spath_back, dx, dy, colorlisth) #draw the first polygon v_a = ( int((self.cps[0][0]-int(self.min_d))* kmsize) , int((self.cps[0][1]-self.min_h)* metersize)) points = ((lef_mar +v_a[0], max_y -low_mar ), (lef_mar +v_a[0], max_y -low_mar - v_a[1]), (lef_mar +v_a[0]+dx, max_y -low_mar - v_a[1]+dy), (lef_mar +v_a[0]+dx, max_y -low_mar + dy)) color = (theme.getcolor(settings['colors'], settings['levels'], self.grad[0])) theme.fillfirsthpoly(devc, points, color) vpolygons = [] spath_pnts = [] colorlistv = [] for i in range(len(self.cps)-1): v_a = (int((self.cps[i][0]-int(self.min_d))* kmsize) , int((self.cps[i][1]-self.min_h)* metersize)) v_b = (int((self.cps[i+1][0]-int(self.min_d))* kmsize) , int((self.cps[i+1][1]-self.min_h)* metersize)) #points that delimitate the area to color points = [(lef_mar +v_a[0], max_y -low_mar), (lef_mar +v_b[0], max_y -low_mar), (lef_mar +v_b[0], max_y -low_mar - v_b[1]), (lef_mar +v_a[0], max_y -low_mar - v_a[1])] points = [(p[0] + dx, p[1] + dy) for p in points] vpolygons.append(points) spath_pnts.append(polytoBezier(points[3], self.dercp[i] * (-metersize / kmsize), points[2], self.dercp[i+1] * (-metersize / kmsize))) color = (theme.getcolor(settings['colors'], settings['levels'], self.grad[i])) colorlistv.append(color) #add also the two lower points (those near km bar) spath_pnts = [vpolygons[0][0]] + spath_pnts + [vpolygons[-1][1]] theme.fillvslopecontour(devc, spath_pnts, max_y -low_mar +self.min_h*metersize, max_y -low_mar -(1000 - self.min_h)*metersize, vpolygons, colorlistv) infotext_x = [] for i in range(len(self.cps)-1): points = vpolygons[i] color = (theme.getcolor(settings['colors'], settings['levels'], self.grad[i])) theme.fillvpoly(devc, points, color) #draw gradient text font = settings['fgrad'] if (points[1][0] - points[0][0] > devc.gettextwidth("%.1f%%" % self.grad[i])): theme.gradtext(devc, "%.1f%%" % self.grad[i], points[0][0] + 3, points[0][1] - 20, font) infotext_x.append(points[2][0] -dx -4) infotext_x.append(infotext_x[len(self.cps)-2]+50) for i in range(len(self.cps)-1): #another cycle to prevent text to be hidden by polygons points = vpolygons[i] #draw info text font = settings['fdesc'] infotext = "%.0f %s" % (self.cps[i + 1][1], self.cps[i + 1][2]) diffx = infotext_x[i+1] - infotext_x[i] diffx = diffx - devc.gettextheight(infotext) -2 if diffx < 0: diffx = diffx/2 infotext_x[i+1] -= diffx theme.desctext(devc, infotext, infotext_x[i] + diffx, points[2][1] -dy - 10, font) else: theme.desctext(devc, infotext, infotext_x[i], points[2][1] -dy - 10, font) class SlopeList: """Wrapper for a list of slopes, according to MCV""" def __init__(self): """ Wraps a list of slopes, according to MCV""" self._lst = [] self.message = glal.Message() def __len__(self): """"Gives how many slopes are in the list""" return len(self._lst) def new_slope(self): """ Add a new slope to the list. """ self._lst.append(Slope()) return (len(self._lst) - 1) def del_slope(self, slope_number): """ Remove a slope from the list """ del self._lst[slope_number] #It doesen't send a SLOPE CHANGED message because #other slopes are not been modified. def get_slope_copy(self, slope_number): """ Get a copy of a slope in the list. """ return self._lst[slope_number] def set_name(self, slope_number, name): """ Set the name of a slope in the list. """ self._lst[slope_number].name = name #This updates the title in the tab. self.message.send("UPDATE_TAB", slope_number, 0) def set_country(self, slope_number, country): """ Set the country of a slope in the list.""" self._lst[slope_number].country = country def set_author(self, slope_number, author): """ Set the author of a slope in the list.""" self._lst[slope_number].author = author def set_email(self, slope_number, email): """ Set the email of the author of a slope.""" self._lst[slope_number].email = email def set_comment(self, slope_number, comment): """ Ser a comment to a slope in the list. """ self._lst[slope_number].comment = comment def set_url(self, slope_number, url): """ Add a URL referring to a slope in the list """ self._lst[slope_number].url = url def get_name(self, slope_number): """ Get name """ return self._lst[slope_number].name def get_state(self, slope_number): """ Get country """ return self._lst[slope_number].country def get_author(self, slope_number): """ Get author """ return self._lst[slope_number].author def get_email(self, slope_number): """ Get email """ return self._lst[slope_number].email def get_comment(self, slope_number): """ Get comment """ return self._lst[slope_number].comment def get_average_grad(self, slope_number): """ Get average gradient """ return self._lst[slope_number].average_grad def get_max_grad(self, slope_number): """ Get max gradient """ return self._lst[slope_number].max_grad def get_height_difference(self, slope_number): """ Get height difference""" return self._lst[slope_number].height_difference def get_height_gain(self, slopenumber): """ Get height gain""" return self._lst[slopenumber].height_gain def get_url(self, slope_number): """ Get URL """ return self._lst[slope_number].url def get_coords(self, slope_number): """ Get coords """ return self._lst[slope_number].coords def add_coord(self, slope_number, latitude, longitude): """ Add a coordinate to a slope in the list.""" sel_lst = self._lst[slope_number] sel_lst.add_coord(latitude, longitude) def add_cp(self, slope_number, distance, altitude, name=""): """ Add a check point to a slope in the list.""" sel_lst = self._lst[slope_number] orig_len = len(sel_lst) row_num = sel_lst.add_cp(distance, altitude, name) if len(sel_lst) == orig_len: #if the slope isn't grown then a cp has been modified. self.message.send("SLOPE_DEL", slope_number, row_num) self.message.send("SLOPE_ADD", slope_number, row_num) def remove_cp(self, slope_number, cp_num): """ Remove a check point from a slope in the list.""" self._lst[slope_number].remove_cp(cp_num) self.message.send("SLOPE_DEL", slope_number, cp_num) ### Below this line fuctions are part of the view according MCV pattern ### def polytoBezier(p0, m1, p3, m2): """Covert from polynomial function to Beziér curve p0 is the start point (as tuple of dimension 2) of the Beziér curve p1 is the end point of the Beziér curve m1 is the value of the derivate in p0 m2 is the value of the derivate in p3 returns the four control points of a cubic Beziér curve (p1, p2, p3, p4) """ (x0, y0) = p0 (x3, y3) = p3 h = x3 - x0 x1 = x0 + h/3 y1 = m1*(x1 - x0) + y0 p1 = (x1, y1) x2 = x0 + 2*h/3 y2 = m2*(x2 - x3) + y3 p2 = (x2, y2) return (p0, p1, p2, p3) # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/altitude_downloader.py0000644000175000017500000001632012065361217023777 0ustar federicofederico00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """altitude_downloader.py""" # Copyright (C) 2008, 2009, 2010, 2011, 2012 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. import math import threading import urllib2 import xml.dom.minidom import re ALTITUDE_CACHE = {} SERVICES = frozenset(("geonames.org", "earthtools.org", "usgs.net")) _ACTIVE_SERVICE = "geonames.org" def geonames_org(lat, lng): """ Use geonames.org to download data""" url = 'http://ws.geonames.org/srtm3?lat='+lat+'&lng='+lng line = '' tries = 5 # Sometimes geonames retuns an xml header, which is wrong, so try again. # the first character might be a minus sign, we keep it simple while not line.isdigit() and tries > 0: han = urllib2.urlopen(url) line = han.readline().strip() tries -= 1 han.close() alt = float(line) return alt def earthtools_org(lat, lng): """ Use earthtools.org to download data""" #http://www.earthtools.org/height// url = 'http://www.earthtools.org/height/'+lat+'/'+lng han = urllib2.urlopen(url) alt = re.search(r"(-?\d+)<\/meters>", han.read()).group(1) alt = float(alt) han.close() return alt def usgs_net(lat, lng): """ Use usgs.net to download data""" url = 'http://gisdata.usgs.net/XMLWebServices/' + \ 'TNM_Elevation_Service.asmx/getElevation?X_Value=' + \ lng + '&Y_Value=' + lat + \ '&Elevation_Units=METERS&Source_Layer=-1&Elevation_Only=TRUE' han = urllib2.urlopen(url) match = re.search(r"<.+>(-?\d+[\.\d]*)<\/.+>", han.read()).group(1) alt = float(match) return alt SERVER_DOWNLOADER = {"geonames.org" : geonames_org, "earthtools.org" : earthtools_org, "usgs.net" : usgs_net } #WARNING! this module is not thread safe, maybe you can use a lock to use #more threads. def choose_service(newserv): """ Choose the service to use for retreiving altitude data""" global _ACTIVE_SERVICE global ALTITUDE_CACHE if newserv not in SERVICES: return -1 if newserv != _ACTIVE_SERVICE: #Because different services may give different datas #we clear the cache if we change service. ALTITUDE_CACHE = {} _ACTIVE_SERVICE = newserv return 0 class ImporterThread(threading.Thread): """ Download altitude""" def __init__(self, outqueue, slopefile, num, seltype): threading.Thread.__init__(self) self.outq = outqueue self._want_abort = False self.slopefile = slopefile self.service = _ACTIVE_SERVICE self.status = 'OK' self.num_cps = num self.seltype = seltype def run(self): """ Task to execute while running""" if not SERVER_DOWNLOADER.has_key(self.service): self.status = "Error: service unknown" return getalt = SERVER_DOWNLOADER[self.service] cps = self.slopefile.cps usedcp = [] if self.seltype == 0:#using the given number of check points in num max_dist = self.slopefile.max_dist() next_cp = 0.0 if self.num_cps == -1: N = 30 elif self.num_cps == 0: N = len(cps) else: N = self.num_cps for i in range(len(cps)): (dist, alt, name, lat, lng)= cps[i] #create N check points if i == 0 or dist > next_cp or i == len(cps)-1: usedcp.append((dist, alt, name, lat, lng)) next_cp = dist + max_dist/N elif self.seltype == 1:#using the passed minimum distance in metres in num next_dist = self.num_cps for i in range(len(cps)): (dist, alt, name, lat, lng)= cps[i] if i == 0 or dist > next_dist or i == len(cps)-1: usedcp.append((dist, alt, name, lat, lng)) next_dist = dist + self.num_cps for i in range(len(usedcp)): (dist, alt, name, lat, lng) = usedcp[i] if ALTITUDE_CACHE.has_key((lat, lng)): # altitude has already been downloaded alt = ALTITUDE_CACHE[(lat, lng)] else: # try to download the altitude try: alt = getalt(lat, lng) except urllib2.URLError: self.status = 'Error: No network' return ALTITUDE_CACHE[(lat, lng)] = alt progr = 1000 * i / (len(usedcp) - 1) self.outq.put((progr, (dist, alt, name))) if self._want_abort: self.status = 'Aborted' return def abort(self): """abort worker thread. Method for use by main thread to signal an abort. """ self._want_abort = True def point_conversion(lng, lat): """ return radians from coordinates""" return (math.radians(float(lng)), math.radians(float(lat))) def distance(coords): """Calculates the distance from a list of coordinates.""" (lng, lat) = coords[0] (lng_old, lat_old) = point_conversion(lng, lat) dist = 0.0 cps = [] for pnt in coords: if len(pnt) != 2: continue (lng, lat) = pnt (lng_new, lat_new) = point_conversion(lng, lat) dist += lambert_formulae(lat_old, lat_new, lng_old, lng_new) cps.append((dist, lng.strip('\n\t'), lat.strip('\n\t'))) (lng_old, lat_old) = (lng_new, lat_new) return cps R_EARTH = 6367.45 # km def haversine_angle(lat_old, lat_new, lng_old, lng_new): """Haversine formula""" alpha = (math.sin((lat_old-lat_new)/2))**2 \ + math.cos(lat_old) * math.cos(lat_new) * (math.sin((lng_old-lng_new)/2)**2) return 2 * math.atan2(math.sqrt(alpha), math.sqrt(1-alpha)) def haversine(lat_old, lat_new, lng_old, lng_new): return R_EARTH * haversine_angle(lat_old, lat_new, lng_old, lng_new) R_EARTH_EQUATOR = 6378.137 #km WGS 84 r = 298.257223563 # inverse of eccentricity WGS 84 def lambert_formulae(lat_old, lat_new, lng_old, lng_new): red_lat_old = math.atan( (r - 1) / r * math.tan(lat_old) ) red_lat_new = math.atan( (r - 1) / r * math.tan(lat_new) ) sigma = haversine_angle(red_lat_old, red_lat_new, lng_old, lng_new) if sigma == 0.0: return 0.0 P = (red_lat_old + red_lat_new) / 2 Q = (red_lat_new - red_lat_old) / 2 X = (sigma - math.sin(sigma)) * math.sin(P)**2 * math.cos(Q)**2 / ( math.cos(sigma/2)**2 ) Y = (sigma + math.sin(sigma)) * math.cos(P)**2 * math.sin(Q)**2 / ( math.sin(sigma/2)**2 ) distance = R_EARTH_EQUATOR * (sigma - (X + Y) / (2*r)) return distance # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/iofile.py0000644000175000017500000006052312204123117021207 0ustar federicofederico00000000000000# -*- coding: utf-8 -*- """iofile.py""" # Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from __future__ import with_statement import csv import codecs import logging import os import xml.dom.minidom import zlib from altitude_downloader import distance, haversine, point_conversion CSV_VERSION = "1.1" CGX_VERSION = "1.0" STAT_VER = 2 def save_file(filename, slope): """Save .cgx file""" doc = xml.dom.minidom.Document() cg = doc.createElement(u"cyclographxml") cg.setAttribute(u"version", CGX_VERSION) doc.appendChild(cg) sl = doc.createElement(u"slope") cg.appendChild(sl) sl.appendChild(__createTextElement(doc, u"name", slope.name)) sl.appendChild(__createTextElement(doc, u"country", slope.country)) author = doc.createElement(u"author") author.appendChild(__createTextElement(doc, u"name", slope.author)) author.appendChild(__createTextElement(doc, u"email", slope.email)) sl.appendChild(author) sl.appendChild(__createTextElement(doc, u"info", slope.comment)) cps = doc.createElement(u"cps") for cpt in slope.cps: cp = doc.createElement(u"cp") (dist, alt, desc) = cpt cp.setAttribute(u"alt", "%.3f" % alt) cp.setAttribute(u"dist", "%.3f" % dist) if desc != "": cp.setAttribute(u"desc", desc) cps.appendChild(cp) sl.appendChild(cps) coords = doc.createElement(u"coords") for coor in slope.coords: coord = doc.createElement(u"coord") (lat, lon) = coor coord.setAttribute(u"lon", "%.6f" % lon) coord.setAttribute(u"lat", "%.6f" % lat) coords.appendChild(coord) sl.appendChild(coords) with open(filename,"wb") as fid: doc.writexml(fid, encoding='utf-8', newl='\n') def __createTextElement(doc, name, text): elem = doc.createElement(name) ptext = doc.createTextNode(text) elem.appendChild(ptext) return elem #def save_file(filename, slope): # """Save .csv file""" # #Control if the right extension is given by user # if not filename.endswith('.csv'): # filename = filename + '.csv' # #fid = open(filename,'wb') # # Too bad there is no csv unicode writer so open in ASCII mode and convert utf-8 to ASCII # # Be carreful to also encode delimiter and quotechar if they are not ASCII # with open(filename, mode='wb') as fid: # #fid.write ("%s;%s;%s\n" % (slope.name, slope.country, slope.comment) ) # csv_writer = csv.writer(fid, delimiter=';', quotechar='\"') # def to_unicode(item): # if isinstance(item, unicode): # item = item.encode('utf-8') # return item # csv_writer.writerow( map(to_unicode, (str(CSV_VERSION), slope.name, slope.country, # slope.author, slope.email, slope.comment)) ) # for row in slope.cps: # csv_writer.writerow(map(to_unicode, row)) # #for cpt in slope.cps: # # fid.write ("%.3f;%.3f;%s\n" % cpt) # #fid.close() def open_file(filename, slopelist, slopenum, extension=''): """Open generic file""" statusok = True if not extension: if isinstance(filename, basestring): extension = filename.split('.')[-1].lower() else: extension = 'cgx' #when used stdin if extension == 'cgx': try: statusok = __open_cgx(filename, slopelist, slopenum) except IOError: statusok = False elif extension == 'csv': try: statusok = __open_csv(filename, slopelist, slopenum) except IOError: statusok = False elif extension == 'xml': try: statusok = __open_xml(filename, slopelist, slopenum) except IOError: statusok = False elif extension == 'gpx': try: gpxfile = load_gpxfile(filename) gpxfile.newSlope(slopelist, slopenum, -1) statusok = True except IOError: statusok = False elif extension == 'kml': try: kmlfile = load_kmlfile(filename) kmlfile.newSlope(slopelist, slopenum, -1) statusok = True except IOError: statusok = False elif extension == 'fitlog': try: fitlogfile = load_fitlogfile(filename) fitlogfile.newSlope(slopelist, slopenum, -1) statusok = True except IOError: statusok = False elif extension == 'tcx': try: tcxfile = load_tcxfile(filename) tcxfile.newSlope(slopelist, slopenum, -1) statusok = True except IOError: statusok = False elif extension == 'sal': try: __open_sal(filename, slopelist, slopenum) except IOError: statusok = False elif extension == 'crp': try: __open_crp(filename, slopelist, slopenum) except IOError: statusok = False elif extension == 'txt': try: __open_txt(filename, slopelist, slopenum) except IOError: statusok = False else: statusok = False return statusok ### Functions defining how to open a certain file format. #csv unicode implementation, std library doesn't implements it yet :-( #from http://docs.python.org/library/csv.html#csv-examples def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs): # csv.py doesn't do Unicode; encode temporarily as UTF-8: csv_reader = csv.reader(utf_8_encoder(unicode_csv_data), dialect=dialect, **kwargs) for row in csv_reader: # decode UTF-8 back to Unicode, cell by cell: yield [unicode(cell, 'utf-8') for cell in row] def utf_8_encoder(unicode_csv_data): for line in unicode_csv_data: yield line.encode('utf-8') def __open_csv(filename, slopelist, slopenum): """Open a Cyclograph CSV file (legacy)""" if isinstance(filename, basestring): fid = codecs.open(filename, encoding='utf-8', mode='rb') else: fid = filename #with open(filename, 'rb') as fid: csv_reader = unicode_csv_reader(fid, delimiter=';', quotechar='\"') line = csv_reader.next() #Make it more robust: if file has less than the required elements #it considers them as empty strings and doesn't consider exceding ones. if len(line) < 6: line.extend([""] * (6-len(line)) ) (version, slopename, slopestate, slopeauthor, authoremail, slopecomment) = line[:6] status = True #This is a legacy format so always warn about that, regardless the version number status = STAT_VER slopelist.set_name(slopenum, slopename) slopelist.set_country(slopenum, slopestate) slopelist.set_author(slopenum, slopeauthor) slopelist.set_email(slopenum, authoremail) slopelist.set_comment(slopenum, slopecomment) for line in csv_reader: #(dist, alt, name)=line.strip().split(';') try: (dist, alt, name) = line except ValueError: return False slopelist.add_cp(slopenum, float(dist), float(alt), name) fid.close() return status def __open_cgx(filename, slopelist, slopenum): """Open a Cyclograph cgx file""" fid = xml.dom.minidom.parse(filename) slop = fid.getElementsByTagName("slope")[0] slopename = slop.getElementsByTagName("name")[0] if slopename.hasChildNodes(): slopelist.set_name(slopenum, slopename.childNodes[0].data) slopestate = slop.getElementsByTagName("country")[0] if slopestate.hasChildNodes(): slopelist.set_country(slopenum, slopestate.childNodes[0].data) auth = slop.getElementsByTagName("author")[0] author = auth.getElementsByTagName("name")[0] if author.hasChildNodes(): slopelist.set_author(slopenum, author.childNodes[0].data) mail = auth.getElementsByTagName("email")[0] if mail.hasChildNodes(): slopelist.set_email(slopenum, mail.childNodes[0].data) slopecomment = slop.getElementsByTagName("info")[0] if slopecomment.hasChildNodes(): slopelist.set_comment(slopenum, slopecomment.childNodes[0].data) for cpt in slop.getElementsByTagName('cp'): try: slopelist.add_cp(slopenum, float(cpt.attributes["dist"].value) , float(cpt.attributes["alt"].value) , cpt.getAttribute("desc")) except Exception, err: logging.exception(err) fid.unlink() return False for coord in slop.getElementsByTagName('coord'): try: slopelist.add_coord(slopenum, float(coord.attributes["lat"].value), float(coord.attributes["lon"].value)) except Exception, err: logging.exception(err) fid.unlink() return False fid.unlink() return True def __open_xml(filename, slopelist, slopenum): """Open a Cyclomaniac xml file""" fid = xml.dom.minidom.parse(filename) slopename = fid.getElementsByTagName("name")[0] slopename = slopename.childNodes slopelist.set_name(slopenum, slopename[0].data) samples = fid.getElementsByTagName("samples")[0] for sample in samples.getElementsByTagName('sample'): for ent in sample.childNodes: if ent.localName == "distance": dist = ent.childNodes[0].data.replace(',','.') elif ent.localName == "height": alt = ent.childNodes[0].data.replace(',','.') elif ent.localName == "label": name = ent.childNodes[0].data slopelist.add_cp(slopenum, float(dist), float(alt), name) name = u"" fid.unlink() return True def load_gpxfile(xmlfile): """Load a gpx file""" try: if isinstance(xmlfile, basestring) and xmlfile.strip().startswith('<'): fid = xml.dom.minidom.parseString(xmlfile) else: fid = xml.dom.minidom.parse(xmlfile) ptls = fid.getElementsByTagName('trkpt') coords = [(el.attributes["lon"].value, el.attributes["lat"].value) for el in ptls] cps = distance(coords) next_cp = 0 max_dist = cps[-1][0] indices = [] for i in range(len(cps)): dist = cps[i][0] if i == 0 or dist > next_cp or i == len(cps)-1: indices.append(i) next_cp = dist + max_dist/len(cps) #Use waypoints to determine the name of a cp. waypoints = {} for waypoint in fid.getElementsByTagName('wpt'): #find the nearest (filtered) point to this waypont (wpt_lon, wpt_lat) = point_conversion(waypoint.attributes["lon"].value, waypoint.attributes["lat"].value) (min_i, min_distance) = (-1, float(3)) #use minimum accetable distance 3 km. #print cps for i in indices: #calculate distance to point i (lon, lat) = point_conversion(cps[i][1], cps[i][2]) dist = haversine(lat, wpt_lat, lon, wpt_lon) #print (lon, lat, dist) if dist < min_distance: (min_i, min_distance) = (i, dist) if min_i >= 0: #is found a point near enought to the waypoint: use it. waypoints[min_i] = waypoint.getElementsByTagName("name")[0].firstChild.data returncp = [] is_with_alt = True alt_count = 0 for i in indices: #get elevation (dist, lng, lat) = cps[i] sample = ptls[i] elelist = sample.getElementsByTagName('ele') if len(elelist) > 0: ele = elelist[0] node = ele.childNodes alt = float(node[0].data) else: is_with_alt = False alt = 0 if (alt == 0): alt_count += 1 if i in waypoints: name = waypoints[i] else: name = u"" returncp.append((dist, alt, name, lat, lng)) fid.unlink() retfile = SlopeFile(returncp) if len(indices) == alt_count: is_with_alt = False retfile.hasAltitudes = is_with_alt return retfile except Exception, err: logging.exception(err) return None def load_fitlogfile(xmlfile): """Load a fitlog file""" try: if isinstance(xmlfile, basestring) and xmlfile.strip().startswith('<'): fid = xml.dom.minidom.parseString(xmlfile) else: fid = xml.dom.minidom.parse(xmlfile) ptls = fid.getElementsByTagName('pt') coords = [(el.attributes["lon"].value, el.attributes["lat"].value) for el in ptls] cps = distance(coords) next_cp = 0 max_dist = cps[-1][0] indices = [] for i in range(len(cps)): dist = cps[i][0] if i == 0 or dist > next_cp or i == len(cps)-1: indices.append(i) next_cp = dist + max_dist/len(cps) returncp = [] is_with_alt = True alt_count = 0 name = u"" for i in indices: #get elevation (dist, lng, lat) = cps[i] sample = ptls[i] if sample.getAttribute('ele'): elev = sample.attributes["ele"].value if len(elev) > 0: alt = float(elev) else: is_with_alt = False alt = 0 else: is_with_alt = False alt = 0 if (alt == 0): alt_count += 1 returncp.append((dist, alt, name, lat, lng)) fid.unlink() retfile = SlopeFile(returncp) if len(indices) == alt_count: is_with_alt = False retfile.hasAltitudes = is_with_alt return retfile except Exception, err: logging.exception(err) return None def load_kmlfile(xmlfile): """Load a kml file""" try: if isinstance(xmlfile, basestring) and xmlfile.strip().startswith('<'): fid = xml.dom.minidom.parseString(xmlfile) else: fid = xml.dom.minidom.parse(xmlfile) coordlist = [] altlist = [] for linstr in fid.getElementsByTagName("LineString"): coords = linstr.getElementsByTagName("coordinates")[0] node = coords.childNodes[0] data = node.data.strip(' \n') coordlist += [el.split(',')[:2] for el in data.split(' ')] #if LineString is not present try gx:coord (KML 2.2 ext) if len(coordlist) == 0: for gxcoord in fid.getElementsByTagName("gx:coord"): node = gxcoord.childNodes[0] temp = node.data.split(' ') coordlist += [temp[:2]] altlist += [float(temp[2])] if len(coordlist) == 0: return SlopeFile([]) cps = distance(coordlist) next_cp = 0 max_dist = cps[-1][0] is_with_alt = len(altlist) >= len(cps) returncp = [] for i in range(len(cps)): (dist, lng, lat) = cps[i] #create self.num_cps check points #print i if i == 0 or dist > next_cp or i == len(cps)-1: if is_with_alt: # altitude is already in the kml file alt = altlist[i] else: # altitude has to be downloaded alt = 0 returncp.append((dist, alt, "", lat, lng)) next_cp = dist + max_dist/len(cps) fid.unlink() retfile = SlopeFile(returncp) retfile.hasAltitudes = is_with_alt return retfile except Exception, err: logging.exception(err) return None def load_tcxfile(xmlfile): """Load a tcx file""" try: fid = xml.dom.minidom.parse(xmlfile) ptls = fid.getElementsByTagName('Trackpoint') coords = [] is_with_alt = False for sample in ptls: for ent in sample.childNodes: if ent.localName == "Position": #Iterate on child nodes to get latitude and longitude for pos_node in ent.childNodes: if pos_node.localName == "LatitudeDegrees": lat = pos_node.childNodes[0].data elif pos_node.localName == "LongitudeDegrees": lng = pos_node.childNodes[0].data elif ent.localName == "AltitudeMeters": alt = float(ent.childNodes[0].data) if (alt != 0): is_with_alt = True coords.append((lng, lat, alt)) dist = 0.0 (lon_old, lat_old) = point_conversion(coords[0][0], coords[0][1]) returncp = [] for i in range(len(coords)): (lon_new, lat_new) = point_conversion(coords[i][0], coords[i][1]) dist += haversine(lat_old, lat_new, lon_old, lon_new) lon_old = lon_new lat_old = lat_new returncp.append((dist, coords[i][2], u"", coords[i][1], coords[i][0])) retfile = SlopeFile(returncp) logging.info("is with alt " + str(is_with_alt)) retfile.hasAltitudes = is_with_alt return retfile except Exception, err: logging.exception(err) return None (UNSUPPORTED, CPS, AUTHOR, DATA) = range(4) def __open_txt(file_, slopelist, slopenum): """Open a Cyclomaniac TXT file""" if isinstance(file_, basestring): fid = codecs.open(file_, encoding='utf-8', mode='r', errors='replace') else: fid = file_ #with open(filename, 'rb') as fid: mode = CPS for line in fid: line = line.strip() #Find if switching to a different mode. if line.startswith('['): modename = line.strip('[]').lower() #print modename if modename == 'author': mode = AUTHOR elif modename == 'data': mode = DATA else: mode = UNSUPPORTED continue #mode cps import check point to slope. if mode == CPS: #format is dist, alt, name, other. (dist, alt, name) = line.split(',')[:3] (dist, alt) = (float(dist), float(alt)) name = name.strip('\"') slopelist.add_cp(slopenum, dist, alt, name) #mode data imports extra information about the slope elif mode == DATA: try: (lhs, rhs) = line.split('=')[:2] except: continue #print lhs +" <- " + rhs if lhs == 'IDPercorso': slopelist.set_name(slopenum, rhs) elif lhs == 'Stato': slopelist.set_country(slopenum, rhs) elif lhs == 'Url': slopelist.set_url(slopenum, rhs) fid.close() def __open_sal(filepathname, slopelist, slopenum): """Open a Salitaker SAL file""" if isinstance(filepathname, basestring): filename = os.path.split(filepathname)[-1] name = filename.split('.')[0] slopelist.set_name(slopenum, name) fid = codecs.open(filepathname, encoding='utf-8', mode='r') else: fid = filepathname #with open(filepathname, 'rb') as fid: ncp = fid.readline().strip().split(' ')[4] for _ in range(int(ncp)): name = fid.readline().strip() (dist, alt) = fid.readline().strip().split(' ') slopelist.add_cp(slopenum, float(dist), float(alt), name) fid.close() def __open_crp(filepathname, slopelist, slopenum, num_cps=-1): """Open Ciclotour crp The parameter num_cps is the number ok cp to import (at most). Particular values are: 0: import every cp -1: import the default number of cp""" data = "" if isinstance(filepathname, basestring): fid = open(filepathname, mode='rb')#needed byte access not unicode string else: fid = filepathname #with open(filepathname, 'rb') as fid: byte = " " while byte: byte = fid.read(1) data += byte fid.close() if not data: #File not accesible or empty return -1 if data[0] == '\x78' and data[1] == '\xda': plaincsv = zlib.decompress(data) elif data[0] == 'H' and data[1] == 'R': plaincsv = data else: #Invalid file format return -1 #print plaincsv points = plaincsv.split('***') line = points[0].split('\n') #plaincsv.split('\n') #print line[0] next_cp = 0 max_dist = float(line[-2].split('\t')[2])/100 lastline = len(line)-3 if num_cps < 0: N = 20 #default value: often looks good. elif num_cps == 0: N = lastline else: N = num_cps for i in range(lastline): fields = line[i+2].split('\t') #print fields dist = float(fields[2])/100 #create N check points if dist > next_cp or i == lastline or fields[8] != '': alt = float(fields[3]) slopelist.add_cp(slopenum, dist, alt, unicode(fields[8], 'utf-8', errors='replace')) next_cp = dist + max_dist/N return True ### Function that return kml string from gpx def gpxtokml(xmlfile): """Load a gpx file into kml""" if isinstance(xmlfile, basestring) and xmlfile.strip().startswith('<'): fid = xml.dom.minidom.parseString(xmlfile) else: fid = xml.dom.minidom.parse(xmlfile) ptls = fid.getElementsByTagName('trkpt') coords = [(el.attributes["lon"].value, el.attributes["lat"].value) for el in ptls] kmlstring = "\n" kmlstring += "\n" kmlstring += "\n" kmlstring += "" for coord in coords: (lon, lat) = coord kmlstring += lon + "," + lat + " " kmlstring += "\n" kmlstring += "\n" return kmlstring ### class for various formats class SlopeFile: def __init__(self, cps): """Load a track file""" self.cps = cps self.hasAltitudes = False def max_dist(self): """ Maximum distance of the track """ return self.cps[-1][0] def __len__(self): """ Number of points of the track """ return len(self.cps) def newSlope(self, slopelist, slopenum, num, seltype=0): """ Create a new slope in the slopelist""" if seltype == 0:#using the given number of check points in num max_dist = self.max_dist() next_cp = 0.0 if num == -1: N = 30 elif num == 0: N = len(self.cps) else: N = num for i in range(len(self.cps)): (dist, alt, name, lat, lng)= self.cps[i] slopelist.add_coord(slopenum, float(lat), float(lng)) #create approximately N check points if i == 0 or dist > next_cp or i == len(self.cps)-1: slopelist.add_cp(slopenum, dist, alt, name) next_cp = dist + max_dist/N return True elif seltype == 1:#using the passed minimum distance in metres in num next_dist = num for i in range(len(self.cps)): (dist, alt, name, lat, lng)= self.cps[i] slopelist.add_coord(slopenum, float(lat), float(lng)) if i == 0 or dist > next_dist or i == len(self.cps)-1: slopelist.add_cp(slopenum, dist, alt, name) next_dist = dist + num return True else: return False def getCoords(self, slopelist, slopenum): for i in range(len(self.cps)): (dist, alt, name, lat, lng)= self.cps[i] slopelist.add_coord(slopenum, float(lat), float(lng)) # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/gtk3/0000755000175000017500000000000012231302005020223 5ustar federicofederico00000000000000cyclograph-1.6.1/cyclograph/gtk3/glal.py0000644000175000017500000003254612204123117021533 0ustar federicofederico00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- #gtk3.glal.py """This module provides a graphic library abstraction layer for Cyclograph""" # Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Federico Brega, Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. import math from gi.repository import Gtk, GObject, Gdk import cairo import gui GObject.threads_init() def initapp(): return Gtk.main() def bind(cgfunc, menuopt): """Connect gui menu option with cg function""" return menuopt.connect("activate", cgfunc) def bind_close(cg_exit, gui): """Connect gui close event with cg exit function""" gui.cg_exit = cg_exit bind(gui.exit, gui.menu_item_exit) def ToolbarBind(fun, button): """Connect gui toolbar button with cg function""" return button.connect("clicked", fun) def OptionCheck(guiopt, option): """Set a gui menu option to selected/unselected """ guiopt.set_active(option) def enable_saving(gui, bool_val): """Enable or disable saving options according to bool_val""" gui.menu_item_save.set_sensitive(bool_val) gui.menu_item_save_as.set_sensitive(bool_val) gui.action_add.set_sensitive(bool_val) gui.action_edit.set_sensitive(bool_val) gui.action_delete.set_sensitive(bool_val) gui.action_plot.set_sensitive(bool_val) gui.action_map.set_sensitive(bool_val) gui.action_properties.set_sensitive(bool_val) def addstatusbartext(maingui, text): """Add text to main gui status bar""" maingui.addstatusbartext(text) maingui.sbtimer.start() def signalbug(event=None): """Open webpage to signal bugs""" bugUrl = 'http://sourceforge.net/project/memberlist.php?group_id=227295' #Looks like gtk hasn't any function to launch an external browser, #the best we can do is use python webbrowser import webbrowser webbrowser.open(bugUrl, new=True, autoraise=True) class Message(): """ Gtk3 message""" def __init__(self): class Messenger(GObject.GObject): __gsignals__ = { str("UPDATE_TAB"): (GObject.SignalFlags.ACTION, None, (int, int, )), str("SLOPE_ADD"): (GObject.SignalFlags.ACTION, None, (int, int, )), str("SLOPE_DEL"): (GObject.SignalFlags.ACTION, None, (int, int, )), } self.gobj = Messenger() def send(self, message, slope_number, row_num): """ Send message""" self.gobj.emit(message, slope_number, row_num) def subscribe(self, function, emitter, message): """ Subscribe message""" self.handler = function emitter.gobj.connect(message, self._reformat_handler_param) def _reformat_handler_param(self, emitter, arg1, arg2): self.handler(arg1, arg2) class Notebook: """Gtk3 notebook""" def __init__(self, notebook, fun_close): self.notebook = notebook self.fun_close = fun_close self.notebook.set_scrollable(True) def Page(self): """Creates page""" return gui.Page(self.notebook) def set_page_label(self, page_num, text): """Set page label text""" lab = self.notebook.get_tab_label(self.get_page(page_num)) lab.label.set_text(text) def add_page(self, page, title): """Add page to the notebook""" box = gui.tab_label(page, title) page.button_close = box.closebtn page.button_close.connect("clicked", self.fun_close, page) self.notebook.append_page(page, box) self.notebook.show_all() nbpages = self.notebook.get_n_pages() self.notebook.set_current_page(nbpages-1) def remove_page(self, page_num): """Remove page from the notebook""" self.notebook.remove_page(page_num) def getselpagnum(self): """Return current selected page""" return self.notebook.get_current_page() def setselpagnum(self, page_num): """Set current selected page""" self.notebook.set_current_page(page_num) def get_page(self, page_num): """Return page at page_num""" return self.notebook.get_nth_page(page_num) def get_pagenum(self, argument): """Return page_num from page passed as argument""" return self.notebook.page_num(argument[1]) class DeviceContext(): """Device Context Gtk3 class wrapper""" def _convcolor(self, color): """ Convert color""" col = color if isinstance(color, basestring): if color.startswith("rgb"): col = [(int(component)<<8)/65535.0 for component in color[4:-1].split(',')] elif color == "white": col = [1, 1, 1] else: col = [0, 0, 0] return col def init_draw_surf(self, widget, width, height): """Initialize device context""" self.size_x = width self.size_y = height self.devc = widget self.FONT_TYP = { "light" : cairo.FONT_WEIGHT_NORMAL, "normal" : cairo.FONT_WEIGHT_NORMAL, "bold" : cairo.FONT_WEIGHT_BOLD, } #pen color self.pcolor = [0, 0, 0] #brush color self.bcolor = [0, 0, 0] def shear(self, shear): """ device shear""" matrix = cairo.Matrix(yx = shear) self.devc.set_matrix(matrix) def getsize(self): """Return device context dimensions""" return (self.size_x, self.size_y) def gradfill(self, rect, startcolor, endcolor): """Fill context with gradient""" (startx, starty) = (rect[0], rect[1]) scolor = self._convcolor(startcolor) ecolor = self._convcolor(endcolor) lg1 = cairo.LinearGradient(0, 160.0, 0, self.size_y) lg1.add_color_stop_rgb(0, *scolor) lg1.add_color_stop_rgb(1, *ecolor) self.devc.rectangle(startx, starty, self.size_x, self.size_y) self.devc.set_source(lg1) self.devc.fill() def setpen(self, color, size): """Set pen color and size""" self.devc.set_line_width(size) self.pcolor = self._convcolor(color) def setfont(self, font): """Set font""" try: self.devc.select_font_face(font['des'], cairo.FONT_SLANT_NORMAL, self.FONT_TYP[font['typ']]) self.devc.set_font_size(font['dim']) except Exception: pass def drawtext(self, text, pos_x, pos_y): """Draw text""" self.devc.set_source_rgb(*self.pcolor) self.devc.move_to(pos_x, pos_y+12) self.devc.show_text(text) def gettextwidth(self, text): """ Return text length""" return int(self.devc.text_extents(text)[2]) def gettextheight(self, text): """ Return text height""" return int(self.devc.text_extents(text)[3]) def drawline(self, pos_x0, pos_y0, pos_x1, pos_y1): """Draw line""" self.devc.set_source_rgb(*self.pcolor) self.devc.move_to(pos_x0, pos_y0) self.devc.line_to(pos_x1, pos_y1) self.devc.stroke() def setlineargradientbrush(self, colorlist, startp, endp): """ Get a linear gradient from startp to endp, using colors in colorlist. The elments of colorlist are tuple in the format (color, realtive position).""" grad = cairo.LinearGradient(startp[0], startp[1], endp[0], endp[1]) for color in colorlist: grad.add_color_stop_rgb(color[1], *self._convcolor(color[0])) self.pattern = grad def setbrush(self, color): """Set brush color""" self.pattern = cairo.SolidPattern(*self._convcolor(color)) def drawrectangle(self, pos_x0, pos_y0, width, height): """Draw rectangle""" self.devc.set_source_rgb(0, 0, 0) self.devc.rectangle(pos_x0, pos_y0, width, height) self.devc.stroke_preserve() self.devc.set_source(self.pattern) self.devc.fill() def drawrotatedtext(self, text, pos_x, pos_y, angle): """Draw rotated text""" self.devc.save() self.devc.translate(pos_x, pos_y) self.devc.rotate(-math.radians(angle)) self.drawtext(text, 0, 0) self.devc.restore() def drawpolygon(self, sequence): """Draw polygon""" self.devc.set_source_rgb(0, 0, 0) self.devc.move_to(*sequence[0]) for point in sequence: self.devc.line_to(*point) self.devc.close_path() self.devc.stroke_preserve() self.devc.set_source(self.pattern) self.devc.fill() def startpath(self, point): """ Start a path in the specified point,""" (pointx, pointy) = point self.devc.set_source_rgb(0, 0, 0) self.devc.move_to(pointx, pointy) return None def drawpathlineto(self, path, point): """ Draw a straight line from the last point to the given point.""" (pointx, pointy) = point self.devc.line_to(pointx, pointy) def drawpathcubicto(self, path, controlpoints): """ Draw a cubic Beziér from the last point using the given list of three control points.""" points = [] for pnt in controlpoints: points.append(pnt[0]) points.append(pnt[1]) self.devc.curve_to(*points) def endpath(self, path): """ Show the path.""" self.devc.set_source_rgb(0, 0, 0) self.devc.stroke_preserve() self.devc.set_source(self.pattern) self.devc.fill() def end_draw(self): """End drawing not used for gtk gui""" pass class Image(): """Gtk3 image class wrapper""" def __init__(self, size_x, size_y, plotfnct): (self.size_x, self.size_y) = (size_x, size_y) self.plotfnct = plotfnct self.image = cairo.ImageSurface(cairo.FORMAT_RGB24, self.size_x, self.size_y) def plot(self, settings): """Plot image""" dcwrpp = DeviceContext() dcwrpp.init_draw_surf(cairo.Context(self.image), self.size_x, self.size_y) self.plotfnct(settings, dcwrpp) def savetofile(self, path, format): """Save slope to image""" if format.lower() == 'png': self.image.write_to_png(path) if format.lower() == 'bmp': width, height = self.image.get_width(), self.image.get_height() pixbuf = Gdk.pixbuf_get_from_surface(self.image, 0, 0, width, height) pixbuf.savev(path, "bmp", [], []) if format.lower() == 'jpg': width, height = self.image.get_width(), self.image.get_height() pixbuf = Gdk.pixbuf_get_from_surface(self.image, 0, 0, width, height) pixbuf.savev(path, "jpeg", ["quality"], ["100"]) class Pdf(): """Gtk3 pdf class wrapper""" def __init__(self, filepath): width, height = 793, 1122 self.dy = 90 self.dx = 300 self.y_incr = 30 self.surface = cairo.PDFSurface(filepath, width, height) self.context = cairo.Context(self.surface) # white background self.context.set_source_rgb(1, 1, 1) self.context.rectangle(0, 0, width, height) self.context.fill() self.context.select_font_face("Arial") self.context.set_font_size(18) def plot_image(self, settings, size_x, size_y, plotfnct): """Plot image""" image = cairo.SVGSurface(None, size_x, size_y) dcwrpp = DeviceContext() dcwrpp.init_draw_surf(cairo.Context(image), size_x, size_y) plotfnct(settings, dcwrpp) self.context.set_source_surface(image, 0, 0) self.context.paint() self.dy += size_y def addtext(self, text): self.dy += self.y_incr self.context.set_source_rgb(0, 0, 0) self.context.move_to(self.dx, self.dy) self.context.show_text(text) def addtitle(self, text): self.dy += self.y_incr self.context.set_source_rgb(0, 0, 0.4) self.context.move_to(self.dx-50, self.dy) self.context.show_text(text+":") def save(self): """Save slope to pdf""" self.context.show_page() self.surface.finish() class ProgressDialog(): """Gtk3 Progress dialog""" def __init__(self): self.pdialog = gui.ProgressDialog(_("Downloading altitudes"), _("Please wait, Cycograph is downloading altitudes."), 1000.0) def update(self, value): """Update the progress shown and return if user want to abort.""" return self.pdialog.update(value) def destroy(self): """Destroy dialog""" self.pdialog.destroy() class Timer(): """Gtk3 timer""" def __init__(self, period, callback): self.timer = 0 self.callback = callback self.period = period def start(self): """Start timer""" self.timer = GObject.timeout_add(self.period, self.callback) def stop(self): """Stop timer""" GObject.source_remove(self.timer) self.timer = 0 # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/gtk3/__init__.py0000644000175000017500000000000012065361217022341 0ustar federicofederico00000000000000cyclograph-1.6.1/cyclograph/gtk3/gui.py0000644000175000017500000017520512231301360021376 0ustar federicofederico00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """gtk3.gui.py""" # Copyright (C) 2011, 2012, 2013 Pierluigi Villani # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from __future__ import print_function import os import StringIO from gi.repository import Gtk, GObject, Gdk, GdkPixbuf, Pango from gi.repository import WebKit import glal import cairo from themes import ThemeManager from version import VERSION pixmap_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..','..', 'pixmaps') ICON_FILENAME = os.path.join(pixmap_dir,'cyclograph.svg') if not os.path.isfile(ICON_FILENAME): pixmap_dir = '/usr/share/pixmaps/' ICON_FILENAME = '/usr/share/icons/hicolor/scalable/apps/cyclograph.svg' class Gui(Gtk.Window): """Main window""" def __init__(self, parent, title, size): super(Gui, self).__init__() self.cg_exit = None #check on exit callback self.set_title(title) self.maximized = False self.set_default_size(size[0], size[1]) if size[2]: self.maximize() self.maximized = True try: self.set_icon_from_file(ICON_FILENAME) except Exception: pass #if librsvg2-common is not installed self.set_position(Gtk.WindowPosition.CENTER) self.notebook = Gtk.Notebook() self.notebook.set_property('show-tabs', True) agr = Gtk.AccelGroup() self.add_accel_group(agr) #Statusbar self.statusbar = Gtk.Statusbar() self.context_id = self.statusbar.get_context_id("Statusbar") self.sbtimer = glal.Timer(5000, self.clearstatusbartext) #5000ms timeout #Load icons icons = [('icon_add', os.path.join(pixmap_dir, 'icon_add.svg')), ('icon_ckml', os.path.join(pixmap_dir, 'icon_ckml.svg')), ('icon_delete', os.path.join(pixmap_dir, 'icon_delete.svg')), ('icon_modify', os.path.join(pixmap_dir, 'icon_modify.svg')), ('icon_plot', os.path.join(pixmap_dir, 'icon_plot.svg')), ('icon_map', os.path.join(pixmap_dir, 'icon_map.svg')), ('icon_info', os.path.join(pixmap_dir, 'icon_info.svg'))] factory = Gtk.IconFactory() for (icon_id, icon_file) in icons: try: pixbuf = GdkPixbuf.Pixbuf.new_from_file(icon_file) except Exception: continue #if librsvg2-common is not installed iconset = Gtk.IconSet.new_from_pixbuf(pixbuf) factory.add(icon_id, iconset) factory.add_default() #Action group self.menu_item_new = Gtk.Action("New", _(u"New"), _(u"New Slope"), Gtk.STOCK_NEW) self.menu_item_open = Gtk.Action("Open", _(u"Open"), _(u"Open Slope"), Gtk.STOCK_OPEN) self.menu_item_createkml = Gtk.Action("CreateKML", _(u"Create"), _(u"Create KML"), 'icon_ckml') self.menu_item_save = Gtk.Action("Save", _(u"Save"), _(u"Save Slope"), Gtk.STOCK_SAVE) actiongroup = Gtk.ActionGroup('Actions') actiongroup.add_action(self.menu_item_new) actiongroup.add_action(self.menu_item_open) actiongroup.add_action(self.menu_item_createkml) actiongroup.add_action(self.menu_item_save) #Toolbar toolbar = Gtk.Toolbar() context = toolbar.get_style_context() context.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR) self.action_add = Gtk.ToolButton.new_from_stock('icon_add') self.action_add.set_label_widget(Gtk.Label(label=_(u"Add"))) self.action_add.set_homogeneous(False) self.action_add.set_tooltip_text(_(u"Add a check-point")) key, mod = Gtk.accelerator_parse('plus') self.action_add.add_accelerator("clicked", agr, key, mod, Gtk.AccelFlags.VISIBLE) self.action_edit = Gtk.ToolButton.new_from_stock('icon_modify') self.action_edit.set_label_widget(Gtk.Label(label=_(u"Edit"))) self.action_edit.set_homogeneous(False) self.action_edit.set_tooltip_text(_(u"Edit a check-point")) self.action_delete = Gtk.ToolButton.new_from_stock('icon_delete') self.action_delete.set_label_widget(Gtk.Label(label=_(u"Delete"))) self.action_delete.set_homogeneous(False) self.action_delete.set_tooltip_text(_(u"Remove a check-point")) key, mod = Gtk.accelerator_parse('minus') self.action_delete.add_accelerator("clicked", agr, key, mod, Gtk.AccelFlags.VISIBLE) self.action_plot = Gtk.ToolButton.new_from_stock('icon_plot') self.action_plot.set_homogeneous(False) self.action_plot.set_label_widget(Gtk.Label(label=_(u"Plot"))) self.action_plot.set_tooltip_text(_(u"Plot your slope")) self.action_map= Gtk.ToolButton.new_from_stock('icon_map') self.action_map.set_homogeneous(False) self.action_map.set_label_widget(Gtk.Label(label=_(u"Map"))) self.action_map.set_tooltip_text(_(u"Show the map of your slope")) self.action_properties = Gtk.ToolButton.new_from_stock('icon_info') self.action_properties.set_homogeneous(False) self.action_properties.set_label_widget(Gtk.Label(label=_(u"Info"))) self.action_properties.set_tooltip_text(_(u"Informations about the slope")) self.menu_item_save.set_sensitive(False) self.action_add.set_sensitive(False) self.action_edit.set_sensitive(False) self.action_delete.set_sensitive(False) self.action_plot.set_sensitive(False) self.action_map.set_sensitive(False) self.action_properties.set_sensitive(False) toolbar.insert(self.menu_item_new.create_tool_item(), 0) toolbar.insert(self.menu_item_open.create_tool_item(), 1) toolbar.insert(self.menu_item_createkml.create_tool_item(), 2) toolbar.insert(self.menu_item_save.create_tool_item(), 3) toolbar.insert(Gtk.SeparatorToolItem(), 4) toolbar.insert(self.action_add, 5) toolbar.insert(self.action_edit, 6) toolbar.insert(self.action_delete, 7) toolbar.insert(Gtk.SeparatorToolItem(), 8) toolbar.insert(self.action_plot, 9) toolbar.insert(self.action_map, 10) toolbar.insert(self.action_properties, 11) #Creating the menubar. menubar = Gtk.MenuBar() filemenu = Gtk.Menu() self.smenu = Gtk.MenuItem.new_with_mnemonic(_(u"_File")) self.smenu.set_submenu(filemenu) item_new = self.menu_item_new.create_menu_item() key, mod = Gtk.accelerator_parse("N") item_new.add_accelerator("activate", agr, key, mod, Gtk.AccelFlags.VISIBLE) filemenu.append(item_new) # sep = Gtk.SeparatorMenuItem() # filemenu.append(sep) item_open = self.menu_item_open.create_menu_item() key, mod = Gtk.accelerator_parse("O") item_open.add_accelerator("activate", agr, key, mod, Gtk.AccelFlags.VISIBLE) filemenu.append(item_open) item_createkml = self.menu_item_createkml.create_menu_item() key, mod = Gtk.accelerator_parse("G") item_createkml.add_accelerator("activate", agr, key, mod, Gtk.AccelFlags.VISIBLE) filemenu.append(item_createkml) item_save = self.menu_item_save.create_menu_item() key, mod = Gtk.accelerator_parse("S") item_save.add_accelerator("activate", agr, key, mod, Gtk.AccelFlags.VISIBLE) filemenu.append(item_save) self.menu_item_save_as = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_SAVE_AS, agr) self.menu_item_save_as.set_sensitive(False) key, mod = Gtk.accelerator_parse("S") self.menu_item_save_as.add_accelerator("activate", agr, key, mod, Gtk.AccelFlags.VISIBLE) filemenu.append(self.menu_item_save_as) # sep = Gtk.SeparatorMenuItem() # filemenu.append(sep) self.menu_item_exit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, agr) filemenu.append(self.menu_item_exit) menubar.append(self.smenu) filemenu1 = Gtk.Menu() self.omenu = Gtk.MenuItem.new_with_mnemonic(_(u"_Options")) self.omenu.set_submenu(filemenu1) kmenu = Gtk.Menu() kmenum = Gtk.MenuItem.new_with_mnemonic("_Kml server") kmenum.set_submenu(kmenu) self.menu_item_s1 = Gtk.RadioMenuItem.new_with_label( [], (u"geonames.org")) self.menu_item_s2 = Gtk.RadioMenuItem.new_with_label_from_widget( self.menu_item_s1, (u"earthtools.org")) self.menu_item_s3 = Gtk.RadioMenuItem.new_with_label_from_widget( self.menu_item_s1, (u"usgs.net")) kmenu.append(self.menu_item_s1) kmenu.append(self.menu_item_s2) kmenu.append(self.menu_item_s3) filemenu1.append(kmenum) # sep = Gtk.SeparatorMenuItem() # filemenu1.append(sep) self.preferences = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_PREFERENCES, agr) filemenu1.append(self.preferences) menubar.append(self.omenu) filemenu2 = Gtk.Menu() self.amenu = Gtk.MenuItem.new_with_label((u"?")) self.amenu.set_submenu(filemenu2) self.menu_item_about = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_ABOUT, agr) self.menu_item_about.connect("activate", onabout) filemenu2.append(self.menu_item_about) self.menu_item_bug = Gtk.MenuItem.new_with_label(_(u"Signal a bug")) filemenu2.append(self.menu_item_bug) menubar.append(self.amenu) vbox = Gtk.VBox() vbox.pack_start(menubar, False, False, 0) vbox.pack_start(toolbar, False, False, 0) vbox.pack_start(self.notebook, True, True, 0) vbox.pack_start(self.statusbar, False, False, 0) self.add(vbox) self.connect("delete-event", self.exit) self.connect('window-state-event', self.on_window_state_event) self.show_all() def exit(self, event=None, param=None): """ Exit from CycloGraph, check if there are unsaved slopes""" if self.cg_exit(): Gtk.main_quit() return return True #needed by gtk def getdimensions(self): """Return window width and height""" return self.get_size() def ismaximized(self): """Return true if window is maximized""" return self.maximized def addstatusbartext(self, text): """Add text to the statusbar""" self.statusbar.push(self.context_id, text) def clearstatusbartext(self): """Remove text from statusbar""" self.statusbar.pop(self.context_id) self.sbtimer.stop() def on_window_state_event(self, widget, event): "Update maximized variable to the current window state" if event.new_window_state & Gdk.WindowState.MAXIMIZED: self.maximized = True else: self.maximized = False def onabout(event): """ About dialog""" about = Gtk.AboutDialog() about.set_program_name("CycloGraph") about.set_version(VERSION) about.set_copyright("Copyright (C) 2008-2013 Federico Brega, Pierluigi Villani") about.set_authors(("Federico Brega", "Pierluigi Villani")) about.set_license(""" CycloGraph is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CycloGraph is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. """) about.set_website("http://cyclograph.sourceforge.net") about.set_logo(GdkPixbuf.Pixbuf.new_from_file(ICON_FILENAME)) about.set_icon_from_file(ICON_FILENAME) about.run() about.destroy() class Page(Gtk.ScrolledWindow): """Notebook page""" def __init__(self, parent): GObject.GObject.__init__(self) self.set_shadow_type(Gtk.ShadowType.ETCHED_IN) self.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.store = Gtk.ListStore(str, str, str) self.mylistctrl = Gtk.TreeView.new_with_model(self.store) self.mylistctrl.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) #rows of alternate color self.mylistctrl.set_rules_hint(True) #can select multiple cp by dragging the mouse self.mylistctrl.set_rubber_banding(True) self.add(self.mylistctrl) self.savedfilepath = None self.modified = False self.slopecounternew = 0 self.closebox = None rendererText = Gtk.CellRendererText() column = Gtk.TreeViewColumn(_(u"Distance [km]"), rendererText, text=0) column.set_sort_column_id(0) self.mylistctrl.append_column(column) rendererText = Gtk.CellRendererText() column = Gtk.TreeViewColumn(_(u"Altitude [m]"), rendererText, text=1) column.set_sort_column_id(1) self.mylistctrl.append_column(column) rendererText = Gtk.CellRendererText() column = Gtk.TreeViewColumn(_(u"Name"), rendererText, text=2) column.set_sort_column_id(2) self.mylistctrl.append_column(column) self.mylistctrl.set_headers_clickable(False) #disable column sort def insert_row(self, row_num, chkpnt): """Insert item to this page at position row_num""" self.store.insert(row_num, [unicode(chkpnt[0]), unicode(chkpnt[1]), chkpnt[2]]) def delete_row(self, row_num): """Removes row at position row_num in this page.""" itera = self.store.get_iter(path = (row_num,)) self.store.remove(itera) def get_sel_row(self): """Gives the row number that is selected.""" selection = self.mylistctrl.get_selection() model, selected = selection.get_selected_rows() editcp = -1 if len(selected) > 0: editcp = selected[0].get_indices()[0] return editcp def get_sel_multi_row(self): """Gives a list with the row number of selected items.""" selection = self.mylistctrl.get_selection() model, selected = selection.get_selected_rows() rm_cps = [ path.get_indices()[0] for path in selected] return rm_cps class Managecp(Gtk.Dialog): """Add and edit dialog""" def __init__(self, parent, title, dist="", alt="", name=""): GObject.GObject.__init__(self) self.set_title(title) self.set_transient_for(parent) self.set_modal(True) self.set_destroy_with_parent(True) self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT) self.add_button(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT) self.set_size_request(220, 150) box = Gtk.VBox(spacing=10) box.set_border_width(10) vbox = self.get_content_area() vbox.pack_start(box, True, True, 0) box.show() labelbox = Gtk.VBox(spacing=10) labelbox.set_border_width(10) labelbox.pack_start(Gtk.Label(_(u"Distance:")), True, True, 0) labelbox.pack_start(Gtk.Label(_(u"Altitude:")), True, True, 0) labelbox.pack_start(Gtk.Label(_(u"Name:")), True, True, 0) entrybox = Gtk.VBox() self.distance = Gtk.Entry() self.distance.set_text(dist) self.distance.set_activates_default(True) entrybox.pack_start(self.distance, True, True, 0) self.altitude = Gtk.Entry() self.altitude.set_text(alt) self.altitude.set_activates_default(True) entrybox.pack_start(self.altitude, True, True, 0) self.cpname = Gtk.Entry() self.cpname.set_text(name) self.cpname.set_activates_default(True) entrybox.pack_start(self.cpname, True, True, 0) obox = Gtk.HBox() obox.pack_start(labelbox, False, False, 0) obox.pack_start(entrybox, True, True, 0) box.pack_start(obox, True, True, 0) box.show_all() def show_modal(self): """Shows the dialog and returns True if the value has to be changed.""" return self.run() == Gtk.ResponseType.ACCEPT def destroy(self): """Destroy current managecp""" Gtk.Dialog.destroy(self) def getcp(self): """Gives the modified values.""" dist = self.distance.get_text() alti = self.altitude.get_text() name = self.cpname.get_text() return (dist, alti, name) class FormSlopeInfo(Gtk.Dialog): """info dialog about the slope""" def __init__(self, parent, slopedata): GObject.GObject.__init__(self) self.set_title(_(u"Slope Info")) self.set_transient_for(parent) self.set_modal(True) self.set_destroy_with_parent(True) self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT) self.add_button(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT) self.set_size_request(300, 420) box = Gtk.VBox(spacing=10) box.set_border_width(10) vbox = self.get_content_area() vbox.pack_start(box, True, True, 0) box.show() grid = Gtk.Grid() box.pack_start(grid, False, True, 0) grid.show() grid.add(Gtk.Label(label=_(u"Name:"))) self.s_name = Gtk.Entry() self.s_name.set_text(slopedata['name']) grid.attach(self.s_name, 1, 0, 1, 1) grid.attach(Gtk.Label(label=_(u"State:")), 0, 1, 1, 1) self.s_state = Gtk.Entry() self.s_state.set_text(slopedata['state']) grid.attach(self.s_state, 1, 1, 1, 1) grid.attach(Gtk.Label(label=_(u"Author:")), 0, 2, 1, 1) self.s_author = Gtk.Entry() self.s_author.set_text(slopedata['author']) grid.attach(self.s_author, 1, 2, 1, 1) grid.attach(Gtk.Label(label=_(u"E-mail:")), 0, 3, 1, 1) self.s_email = Gtk.Entry() self.s_email.set_text(slopedata['email']) grid.attach(self.s_email, 1, 3, 1, 1) grid.attach(Gtk.Label(label=_(u"Average gradient:")), 0, 4, 1, 1) grid.attach(Gtk.Label(label=slopedata['average_grad']), 1, 4, 1, 1) grid.attach(Gtk.Label(label=_(u"Max gradient:")), 0, 5, 1, 1) grid.attach(Gtk.Label(label=slopedata['max_grad']), 1, 5, 1, 1) grid.attach(Gtk.Label(label=_(u"Height difference:")), 0, 6, 1, 1) grid.attach(Gtk.Label(label=slopedata['height_difference']), 1, 6, 1, 1) grid.attach(Gtk.Label(label=_(u"Height gain:")), 0, 7, 1, 1) grid.attach(Gtk.Label(label=slopedata['height_gain']), 1, 7, 1, 1) grid.attach(Gtk.Label(_(u"Note")+":"), 0, 8, 1, 1) grid.set_row_spacing(7) grid.set_column_spacing(5) self.s_comment = Gtk.TextBuffer() self.s_comment.set_text(slopedata['comment']) textview = Gtk.TextView() textview.set_buffer(self.s_comment) sw = Gtk.ScrolledWindow() sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_placement(Gtk.CornerType.TOP_LEFT) sw.add(textview) sw.show_all() box.pack_start(sw, True, True, 0) box.show_all() def getslopeinfo(self): """Returns the slope infos: name, state, comment""" startnote, endnote = self.s_comment.get_bounds() return {'name' : self.s_name.get_text(), 'state' : self.s_state.get_text(), 'author' : self.s_author.get_text(), 'email' : self.s_email.get_text(), 'comment' : self.s_comment.get_text(startnote, endnote, True)} def show_modal(self): """Shows the dialog and returns True if the value has to be chenged.""" return self.run() == Gtk.ResponseType.ACCEPT def destroy(self): """Destroy current FormSlopeInfo""" Gtk.Dialog.destroy(self) class tab_label(Gtk.HBox): """Notebook tab custom label with close button""" def __init__(self, page, title): GObject.GObject.__init__(self) self.label = Gtk.Label(label=title) self.closebtn = Gtk.Button() image = Gtk.Image() image.set_from_stock(Gtk.STOCK_CLOSE, Gtk.IconSize.MENU) self.closebtn.set_image(image) self.closebtn.set_relief(Gtk.ReliefStyle.NONE) self.pack_start(self.label, True, True, 0) self.pack_end(self.closebtn, False, False, 0) self.show_all() class Plot(Gtk.Window): """plot main class""" def __init__(self, parent, slope, plot_settings, exportfun, exportfun_pdf, exportfun_html): super(Plot, self).__init__() title = "CycloGraph" if slope.name: title += " - " + slope.name self.set_title(title) self.settings = plot_settings self.set_default_size(self.settings['width'], self.settings['height']) # set minimum height and width that plot can have geometry = Gdk.Geometry() geometry.min_width = 300 geometry.min_height = 300 self.set_geometry_hints(self, geometry, 0) self.set_icon_from_file(ICON_FILENAME) menubar = Gtk.MenuBar() filemenu = Gtk.Menu() self.menu = Gtk.MenuItem.new_with_mnemonic(_(u"_Options")) self.menu.set_submenu(filemenu) agr = Gtk.AccelGroup() self.add_accel_group(agr) self.menu_item_save = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_SAVE, agr) filemenu.append(self.menu_item_save) self.menu_item_savepdf = Gtk.MenuItem.new_with_mnemonic(_(u"Save _PDF")) filemenu.append(self.menu_item_savepdf) self.menu_item_savehtml = Gtk.MenuItem.new_with_mnemonic(_(u"Save _html")) filemenu.append(self.menu_item_savehtml) self.menu_item_olines = Gtk.CheckMenuItem.new_with_label(_(u"Orizzontal lines")) self.menu_item_olines.set_active(self.settings['olines']) filemenu.append(self.menu_item_olines) self.menu_item_3d = Gtk.CheckMenuItem.new_with_label(_(u"3D effect")) self.menu_item_3d.set_active(self.settings['3d']) filemenu.append(self.menu_item_3d) tmenu = Gtk.Menu() tmenum = Gtk.MenuItem.new_with_mnemonic(_(u"_Theme")) tmenum.set_submenu(tmenu) self.themeitems = [] self.radioitem = {} self.thememanager = ThemeManager() for theme in self.thememanager.getthemeslist(): if self.settings['theme'] == theme: self.theme1 = Gtk.RadioMenuItem.new_with_label([], theme) self.themeitems.append(theme) self.theme1.connect("activate", self.changetheme) for theme in self.themeitems: if self.settings['theme'] != theme: rmi = Gtk.RadioMenuItem.new_with_label_from_widget(self.theme1, theme) rmi.connect("activate", self.changetheme) tmenu.append(rmi) self.radioitem[theme] = rmi else: self.radioitem[theme] = self.theme1 tmenu.append(self.theme1) self.theme1.set_active(True) filemenu.append(tmenum) rmenu = Gtk.Menu() rmenum = Gtk.MenuItem.new_with_mnemonic(_(u"Saving _resolution")) rmenum.set_submenu(rmenu) menu_item_r1 = Gtk.RadioMenuItem.new_with_label([], (u"800x600")) menu_item_r2 = Gtk.RadioMenuItem.new_with_label_from_widget(menu_item_r1, (u"1024x768")) menu_item_r3 = Gtk.RadioMenuItem.new_with_label_from_widget(menu_item_r1, (u"1280x800")) menu_item_r4 = Gtk.RadioMenuItem.new_with_label_from_widget(menu_item_r1, (u"1600x1200")) menu_item_r1.set_active(self.settings['width'] == 800) menu_item_r2.set_active(self.settings['width'] == 1024) menu_item_r3.set_active(self.settings['width'] == 1280) menu_item_r4.set_active(self.settings['width'] == 1600) menu_item_r1.connect("activate", self.res1) menu_item_r2.connect("activate", self.res2) menu_item_r3.connect("activate", self.res3) menu_item_r4.connect("activate", self.res4) rmenu.append(menu_item_r1) rmenu.append(menu_item_r2) rmenu.append(menu_item_r3) rmenu.append(menu_item_r4) filemenu.append(rmenum) menubar.append(self.menu) self.menu_item_save.connect("activate", self.saveimage) self.menu_item_savepdf.connect("activate", self.savepdf) self.menu_item_savehtml.connect("activate", self.savehtml) self.menu_item_olines.connect("activate", self.olines) self.menu_item_3d.connect("activate", self.change3d) darea = Gtk.DrawingArea() darea.connect("draw", self.on_paint) self.myslope = slope self.devc = glal.DeviceContext() self.myslope.calc() self.exportfun = exportfun self.exportfun_pdf = exportfun_pdf self.exportfun_html = exportfun_html vbox = Gtk.VBox() vbox.pack_start(menubar, False, False, 0) vbox.pack_start(darea, True, True, 0) self.add(vbox) self.show_all() def on_paint(self, widget, event): """Draw graph""" window = widget.get_window() devc = window.cairo_create() self.devc.init_draw_surf(devc, widget.get_allocation().width, widget.get_allocation().height) self.myslope.paint(self.settings, self.devc) def showplot(self): """ Show plot""" pass def saveimage(self, event): """ Save plot image""" self.exportfun(self.myslope, self.settings) def savepdf(self, event): """ Save pdf report""" self.exportfun_pdf(self.myslope, self.settings) def savehtml(self, event): """ Save html report""" self.exportfun_html(self.myslope, self.settings) def change3d(self, event): """ If active switch 3d effect off, else turn it on.""" self.settings['3d'] = not self.settings['3d'] self.queue_draw() def olines(self, event): """ If active draws orizzontal lines""" self.settings['olines'] = not self.settings['olines'] self.queue_draw() def changetheme(self, event): """Change the actual slope theme.""" ritemt = self.radioitem.items() for theme in ritemt: if theme[1] == event: self.settings["theme"] = theme[0] self.queue_draw() break def res1(self, event=None): """Set 800x600""" self.settings['width'] = 800 self.settings['height'] = 600 def res2(self, event=None): """Set 1024x768""" self.settings['width'] = 1024 self.settings['height'] = 768 def res3(self, event=None): """Set 1280x800""" self.settings['width'] = 1280 self.settings['height'] = 800 def res4(self, event=None): """Set 1600x1200""" self.settings['width'] = 1600 self.settings['height'] = 1200 FONT_TYP = { "300" : "light", "400" : "normal", "700" : "bold", } class Preferences(Gtk.Dialog): """Set program preferences""" def __init__(self, parent, pref, default_pref): GObject.GObject.__init__(self) self.set_title(_(u"Preferences")) self.set_transient_for(parent) self.set_modal(True) self.set_destroy_with_parent(True) self.colorlist = [] for color in pref['colors']: components = [int(component)<< 8 for component in color[4:-1].split(',')] self.colorlist.append(Gdk.Color(*components)) self.default = default_pref self.set_size_request(340, 400) notebook = Gtk.Notebook() notebook.set_tab_pos(Gtk.PositionType.TOP) frame = Gtk.Frame() vbox = Gtk.VBox() vbox.set_border_width(5) hbox = Gtk.HBox() hbox.pack_start(vbox, False, False, 10) frame.add(hbox) frame.set_shadow_type(Gtk.ShadowType.NONE) label = Gtk.Label(label=""+_(u"Visualization")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.olines = Gtk.CheckButton(_(u"Orizzontal lines")) vbox.pack_start(self.olines, False, False, 0) self.olines.set_active(pref['olines']) self.effect3d = Gtk.CheckButton(_(u"3D effect")) vbox.pack_start(self.effect3d, False, False, 0) self.effect3d.set_active(pref['3d']) self.showinfo = Gtk.CheckButton(_(u"Show info")) vbox.pack_start(self.showinfo, False, False, 0) self.showinfo.set_active(pref['sinfo']) label = Gtk.Label(label=""+_(u"Resolution")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.res = Gtk.ComboBoxText.new() self.res.append_text('800 x 600') self.res.append_text('1024 x 768') self.res.append_text('1280 x 800') self.res.append_text('1600 x 1200') self.res.set_active(0) if pref['width'] == 1600: self.res.set_active(3) elif pref['width'] == 1280: self.res.set_active(2) elif pref['width'] == 1024: self.res.set_active(1) vbox.pack_start(self.res, False, False, 0) label = Gtk.Label(label=""+_(u"Theme")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.theme = Gtk.ComboBoxText.new() current = 0 for theme in pref['themelist']: self.theme.append_text(theme) if theme == pref['theme']: self.theme.set_active(current) current += 1 vbox.pack_start(self.theme, False, False, 0) label = Gtk.Label(label=""+_(u"Kml server")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.serv = Gtk.ComboBoxText.new() self.serv.append_text('geonames.org') self.serv.append_text('earthtools.org') self.serv.append_text('usgs.net') self.serv.append_text('google elevation') self.serv.set_active(0) if pref['serv'] == 'usgs.net': self.serv.set_active(2) elif pref['serv'] == 'earthtools.org': self.serv.set_active(1) elif pref['serv'] == 'google elevation': self.serv.set_active(3) vbox.pack_start(self.serv, False, False, 0) label = Gtk.Label(label=""+_(u"Latest version")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.vcheck = Gtk.CheckButton(_(u"Check online")) vbox.pack_start(self.vcheck, False, False, 0) self.vcheck.set_active(pref['vcheck']) notebook.append_page(frame, Gtk.Label(label="General")) frame = Gtk.Frame() frame.set_shadow_type(Gtk.ShadowType.NONE) vbox = Gtk.VBox() vbox.set_border_width(5) hbox = Gtk.HBox() hbox.pack_start(vbox, False, False, 10) frame.add(hbox) label = Gtk.Label(label=""+_(u"Description")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) desc = pref['fdesc'] self.fdesc = Gtk.Button(desc['des']+' | '+str(desc["dim"])) self.fdesc.desc = desc self.fdesc.connect("clicked", self.font_button_clicked) vbox.pack_start(self.fdesc, False, False, 0) label = Gtk.Label(label=""+_(u"Gradient")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) desc = pref['fgrad'] self.fgrad = Gtk.Button(desc['des']+' | '+str(desc["dim"])) self.fgrad.desc = desc self.fgrad.connect("clicked", self.font_button_clicked) vbox.pack_start(self.fgrad, False, False, 0) label = Gtk.Label(label=""+_(u"Title")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) desc = pref['ftitle'] self.ftitle = Gtk.Button(desc['des']+' | '+str(desc["dim"])) self.ftitle.desc = desc self.ftitle.connect("clicked", self.font_button_clicked) vbox.pack_start(self.ftitle, False, False, 0) vbox.show_all() notebook.append_page(frame, Gtk.Label(label="Fonts")) frame = Gtk.Frame() frame.set_shadow_type(Gtk.ShadowType.NONE) vbox = Gtk.VBox() vbox.set_border_width(5) frame.add(vbox) self.grid = Gtk.Grid() vbox.pack_start(self.grid, True, True, 0) self.grid.show() self.tick = 0.1 self.levlist = [] self.colblist = [] for i in range(len(pref['levels'])): self.levlist.append(Gtk.SpinButton()) self.levlist[i].set_range(0.0, 90.0) self.levlist[i].set_value(pref['levels'][i]) self.levlist[i].set_increments(self.tick, 1) self.levlist[i].set_numeric(True) self.levlist[i].set_digits(1) self.levlist[i].connect("value_changed", self.changed_level) self.colblist.append( Gtk.ColorButton.new_with_color(self.colorlist[i])) hbx = Gtk.HBox() hbx.pack_start(Gtk.Label(label=">"), False, False, 5) hbx.pack_start(self.levlist[i], False, False, 5) hbx.pack_start(Gtk.Label(label="%"), False, False, 5) self.grid.attach(hbx, 0, i, 1, 1) self.grid.attach(self.colblist[i], 1, i, 1, 1) self.grid.set_row_spacing(10) self.grid.set_column_spacing(10) vbox.show_all() notebook.append_page(frame, Gtk.Label(label="Gradient colors")) frame = Gtk.Frame() frame.set_shadow_type(Gtk.ShadowType.NONE) vbox = Gtk.VBox() vbox.set_border_width(5) hbox = Gtk.HBox() hbox.pack_start(vbox, False, False, 10) frame.add(hbox) label = Gtk.Label(label=""+_(u"Name")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.aname = Gtk.Entry() self.aname.set_text(pref['aname']) vbox.pack_start(self.aname, False, False, 0) label = Gtk.Label(label=""+_(u"E-mail")+"") label.set_use_markup(True) hhbox = Gtk.HBox() hhbox.pack_start(label, False, False, 0) vbox.pack_start(hhbox, False, False, 5) self.amail = Gtk.Entry() self.amail.set_text(pref['amail']) vbox.pack_start(self.amail, False, False, 0) vbox.show_all() notebook.append_page(frame, Gtk.Label(label="Author")) notebook.show_all() bbox = Gtk.HBox() button_k = Gtk.Button(None, Gtk.STOCK_OK) button_c = Gtk.Button(None, Gtk.STOCK_CANCEL) button_d = Gtk.Button(_(u"Restore Default")) bbox.pack_end(button_k, False, False, 5) bbox.pack_end(button_c, False, False, 5) bbox.pack_start(button_d, False, False, 5) button_k.connect("clicked", self.ok_clicked) button_d.connect("clicked", self.restore_default) button_c.connect("clicked", self.destroy) box = Gtk.VBox() box.pack_start(notebook, True, True, 5) box.pack_start(bbox, False, False, 5) carea = self.get_content_area() carea.pack_start(box, True, True, 0) carea.show_all() def changed_level(self, event): "Changed one of the gradient levels" self.levlist[0].set_range(0.0, self.levlist[1].get_value() - self.tick) for i in range(1, len(self.levlist)-1): self.levlist[i].set_range(self.levlist[i-1].get_value() + self.tick, self.levlist[i+1].get_value() - self.tick) self.levlist[len(self.levlist)-1].set_range( self.levlist[len(self.levlist)-2].get_value() + self.tick, 90.0) def ok_clicked(self, event): "Close preferences dialog and save info" self.response(True) def restore_default(self, event): """Restore preferences to default value""" self.olines.set_active(bool(self.default['orizzontal lines'])) self.effect3d.set_active(bool(self.default['effect-3d'])) self.showinfo.set_active(bool(self.default['slopeinfo'])) self.vcheck.set_active(bool(self.default['vcheck'])) self.res.set_active(0) if self.default['width'] == 1600: self.res.set_active(3) elif self.default['width'] == 1280: self.res.set_active(2) elif self.default['width'] == 1024: self.res.set_active(1) current = 0 model = self.theme.get_model() for text in model: if text[0] == self.default['theme']: self.theme.set_active(current) current += 1 self.serv.set_active(0) if self.default['server'] == 'usgs.net': self.serv.set_active(2) elif self.default['server'] == 'earthtools.org': self.serv.set_active(1) elif self.default['server'] == 'google elevation': self.serv.set_active(3) self.fdesc = Gtk.Button(self.default['font-des 1']+' | '+self.default['font-dim 1']) self.fdesc.desc = { "des" : self.default['font-des 1'], "typ" : self.default['font-typ 1'], "dim" : self.default['font-dim 1'] } self.fgrad = Gtk.Button(self.default['font-des g']+' | '+self.default['font-dim g']) self.fgrad.desc = { "des" : self.default['font-des g'], "typ" : self.default['font-typ g'], "dim" : self.default['font-dim g'] } self.ftitle = Gtk.Button(self.default['font-des t']+' | '+self.default['font-dim t']) self.ftitle.desc = { "des" : self.default['font-des t'], "typ" : self.default['font-typ t'], "dim" : self.default['font-dim t'] } self.aname.set_text(self.default['authorname']) self.amail.set_text(self.default['authormail']) colorlist = [self.default["color "+str(i)] for i in range(1, 8)] self.colorlist = [] for color in colorlist: components = [int(component)<<8 for component in color[4:-1].split(',')] self.colorlist.append(Gdk.Color(*components)) for i in range(len(colorlist)): self.colblist[i].set_color(self.colorlist[i]) levellist = [self.default["level "+str(i)] for i in range(1, 8)] for k in range(len(self.levlist)): i = len(self.levlist) - k-1 self.levlist[i].set_value(float(levellist[i])) def font_button_clicked(self, button): """If a font button is clicked show a font dialog to change font""" dlg = Gtk.FontSelectionDialog(_(u"Select Font")) dlg.set_font_name(button.desc["des"]+' '+button.desc["typ"].capitalize()+' '+str(button.desc["dim"])) dlg.set_icon_from_file(ICON_FILENAME) result = dlg.run() if result == Gtk.ResponseType.OK: font = Pango.FontDescription(dlg.get_font_name()) res = str(int(font.get_weight())) dlg.destroy() if FONT_TYP.has_key(res): weight = FONT_TYP[res] else: weight = "normal" button.desc = { "des" : font.get_family(), "typ" : weight, "dim" : str(font.get_size()/Pango.SCALE) } button.set_label(font.get_family()+' | '+str(font.get_size()/Pango.SCALE)) dlg.destroy() def show_modal(self): """Shows the dialog and returns True if the values have to be chenged.""" return self.run() == 1 def getconfig(self): """Returns selected config options""" res = self.res.get_active_text().split(' ') levels = [] for i in range(len(self.levlist)): levels.append(self.levlist[i].get_value()) self.colorlist[i] = self.colblist[i].get_color() settings = { 'olines': self.olines.get_active(), 'theme' : self.theme.get_active_text(), 'sinfo' : self.showinfo.get_active(), 'vcheck': self.vcheck.get_active(), '3d' : self.effect3d.get_active(), 'aname' : self.aname.get_text(), 'amail' : self.amail.get_text(), 'fdesc' : self.fdesc.desc, 'ftitle': self.ftitle.desc, 'fgrad' : self.fgrad.desc, 'width' : res[0], 'height': res[2], 'serv' : self.serv.get_active_text(), 'colors': ['rgb(%d,%d,%d)' % (color.red>>8, color.green>>8, color.blue>>8) for color in self.colorlist], 'levels': levels } return settings def destroy(self, event=None): """Destroy current Preferences""" Gtk.Dialog.destroy(self) class Map(Gtk.Dialog): """Show map of slopes""" def __init__(self, parent, slopename, stringc, savefnct): Gtk.Window.__init__(self) self.set_size_request(800, 600)#FIXME:take webpage dimension self.set_title(_(u"Map")+" - "+ slopename) self.set_icon_from_file(ICON_FILENAME) self.set_resizable(True) self.set_type_hint(Gdk.WindowTypeHint.NORMAL) self.savefnct = savefnct self.view = WebKit.WebView() sw = Gtk.ScrolledWindow() sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.add(self.view) swframe = Gtk.Frame() swframe.add(sw) obox = Gtk.HBox() obox.pack_start(swframe, True, True, 0) bbox = Gtk.HBox() button_s = Gtk.Button(None, Gtk.STOCK_SAVE) bbox.pack_end(button_s, False, False, 5) button_s.connect("clicked", self.onsave) box = Gtk.VBox() box.pack_start(obox, True, True, 0) box.pack_start(bbox, False, False, 5) vbox = self.get_content_area() vbox.pack_start(box, True, True, 0) self.show_all() MAP_SCRIPT = "" try: fid = open(os.path.join(os.path.dirname(__file__), "../map.html"), 'rb') for line in fid: MAP_SCRIPT += line fid.close() except IOError: print("map.html not loaded\n") return HTML_MAP = MAP_SCRIPT % (stringc,) self.view.load_html_string(HTML_MAP, "file:///") def onsave(self, event): """ Save call""" self.savefnct(self) def saveimage(self, filepath): """ Save map image""" winw, winh = self.get_size() minviewh, viewh = self.view.do_get_preferred_height(self.view) minvieww, vieww = self.view.do_get_preferred_width(self.view) diff = (winw - vieww) / 2 dst = cairo.ImageSurface(cairo.FORMAT_ARGB32, vieww, viewh) ctx = cairo.Context(dst) surface = Gdk.cairo_create(self.get_window()).get_target() ctx.set_source_surface(surface, -diff, -diff) ctx.paint() fformat = filepath.rsplit('.', 1)[1] if fformat.lower() == 'png': dst.write_to_png(filepath) if fformat.lower() == 'bmp': pixbuf = Gdk.pixbuf_get_from_surface(dst, 0, 0, vieww, viewh) pixbuf.savev(filepath, "bmp", [], []) if fformat.lower() == 'jpg': pixbuf = Gdk.pixbuf_get_from_surface(dst, 0, 0, vieww, viewh) pixbuf.savev(filepath, "jpeg", ["quality"], ["100"]) class Create_kml(Gtk.Dialog): """Create kml routes""" MODE = {_(u'Open Route Service') : 'ORS', _(u'OSRM') : 'OSRM', _(u"Draw on the map") : 'DRAW'} def __init__(self, parent, downloadfunc, savefunc): Gtk.Window.__init__(self) self.set_size_request(640, 480)#FIXME:take webpage dimension self.set_title(_(u"Create Kml")) self.set_icon_from_file(ICON_FILENAME) self.set_resizable(True) self.set_type_hint(Gdk.WindowTypeHint.NORMAL) self.downloadfunc = downloadfunc self.savefunc = savefunc self.handler = None self.mode = 'ORS' self.view = WebKit.WebView() sw = Gtk.ScrolledWindow() sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_placement(Gtk.CornerType.TOP_LEFT) sw.add(self.view) store = Gtk.ListStore(str) store.append([_(u'Open Route Service')]) store.append([_(u'OSRM')]) store.append([_(u'Draw on the map')]) treeview = Gtk.TreeView.new_with_model(store) treeview.connect("cursor-changed", self.mode_changed) renderertext = Gtk.CellRendererText() column = Gtk.TreeViewColumn("Views", renderertext, text=0) column.set_sort_column_id(0) treeview.append_column(column) frame = Gtk.Frame() frame.set_label(_(u'Modes')) frame.add(treeview) swframe = Gtk.Frame() swframe.add(sw) treeview.set_cursor(0) treeview.set_headers_visible(False) obox = Gtk.HBox() obox.pack_start(frame, False, True, 5) obox.pack_start(swframe, True, True, 5) bbox = Gtk.HBox() button_k = Gtk.Button(None, Gtk.STOCK_OK) button_s = Gtk.Button(None, Gtk.STOCK_SAVE) button_c = Gtk.Button(None, Gtk.STOCK_CANCEL) bbox.pack_end(button_k, False, False, 5) bbox.pack_end(button_s, False, False, 5) bbox.pack_end(button_c, False, False, 5) button_k.connect("clicked", self.import_kml) button_s.connect("clicked", self.save_kml) button_c.connect("clicked", self.cancel) box = Gtk.VBox() box.pack_start(obox, True, True, 5) box.pack_start(bbox, False, False, 5) vbox = self.get_content_area() vbox.pack_start(box, True, True, 0) self.show_all() self.webview_init() def webview_init(self): """ Check mode and set webview accordingly""" if self.mode == 'ORS': self.view.open("http://openrouteservice.org/") elif self.mode == 'OSRM': self.view.open("http://map.project-osrm.org/") elif self.mode == 'DRAW': HTML_DRAW = "" try: fid = open(os.path.join(os.path.dirname(__file__),"../openlayers.html"), 'rb') for line in fid: HTML_DRAW += line fid.close() except IOError: print("openlayers.html not loaded\n") exit(1) self.view.load_html_string(HTML_DRAW.replace("file://./draw_on_map.js", "file://"+os.path.join(os.path.dirname(__file__), "../draw_on_map.js")), "file:///") def mode_changed(self, widget): """ Change current mode""" selection = widget.get_selection() if selection is None: return model, treeiter = selection.get_selected() if treeiter is None: return newmode = self.MODE[model.get_value(treeiter, 0)] if newmode != self.mode: self.mode = newmode self.webview_init() def import_kml(self, event): """ Import route in CycloGraph""" self.download() self.response(True) def get_ors(self): """ Returns gpx content from ORS service""" self.view.execute_script("oldtitle=document.title;document.title=document.getElementById('gpx').innerHTML") gpxcontent = unicode(self.view.get_main_frame().get_title()) self.view.execute_script('document.title=oldtitle;') from xml.sax.saxutils import unescape return StringIO.StringIO(unescape(gpxcontent)) def get_osrm(self): """ Returns gpx content from ORSM service""" self.view.execute_script("oldtitle=document.title;document.title=document.getElementsByClassName('text-link')[1].getAttribute('onclick')") gpxcontent = unicode(self.view.get_main_frame().get_title()) url = gpxcontent.split('\'') print(url) self.view.execute_script('document.title=oldtitle;') return self.downloadfunc(url[1]) def get_draw(self): """ Returns kml content from DRAW mode""" self.view.execute_script("oldtitle=document.title;document.title=createKml()") kmlstring = self.view.get_main_frame().get_title() self.view.execute_script('document.title=oldtitle;') return StringIO.StringIO(kmlstring) def download(self): """ Download selected route""" if self.mode == 'ORS': self.handler = self.get_ors() elif self.mode == 'OSRM': self.handler = self.get_osrm() elif self.mode == 'DRAW': self.handler = self.get_draw() def save_kml(self, event): """Save selected route to file""" self.download() if not self.handler: return self.savefunc(self.handler, self.mode) def cancel(self, event): """ Cancel create kml dialog""" self.destroy() def show_modal(self): """Shows the dialog and returns True if the value has to be changed.""" return self.run() == 1 FONT_TYP = { "300" : "light", "400" : "normal", "700" : "bold", } def preferences(parent, cgpref, defaultpref): """ Show Preference dialog""" pref = Preferences(parent, cgpref, defaultpref) pref_conf = {} if pref.show_modal(): pref_conf = pref.getconfig() pref.destroy() return pref_conf def formslopeinfo(parent, slopedata): """ Show slope's info dialog""" dlg = FormSlopeInfo(parent, slopedata) if dlg.show_modal(): data = dlg.getslopeinfo() dlg.destroy() return data else: dlg.destroy() return {} def FileDialog(parent, title, dirname, filename, other, file_types, rw, fd_open, fd_save): """ Show file dialog for open or save slopes""" if rw == fd_open: dlg = Gtk.FileChooserDialog(title, parent, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) elif rw == fd_save: dlg = Gtk.FileChooserDialog(title, parent, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK)) dlg.set_do_overwrite_confirmation(True) if filename: dlg.set_current_name(filename) for elem in file_types: ffilter = Gtk.FileFilter() ffilter.set_name(elem[0]) for pattern in elem[1].split(' '): ffilter.add_pattern(pattern) ffilter.add_pattern(pattern.upper()) #print(pattern) #print("----") dlg.add_filter(ffilter) head, tail = os.path.split(dirname) dlg.set_current_folder(head) if tail: dlg.set_current_name(tail) response = dlg.run() if response == Gtk.ResponseType.OK: filename = dlg.get_filename() dlg.destroy() return unicode(filename) else: dlg.destroy() return None class ProgressDialog(Gtk.Dialog): """Progress dialog for import Kml function""" def __init__(self, title, label, limit): GObject.GObject.__init__(self) self.set_title(title) self.set_modal(True) self.set_destroy_with_parent(True) self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT) self.set_size_request(330, 130) box = Gtk.VBox() self.limit = limit self.label = Gtk.Label(label=label) self.pbar = Gtk.ProgressBar() align = Gtk.Alignment.new(0.5, 0.5, 0.5, 0.5) align.show() align.add(self.pbar) self.pbar.show() self.pbar.set_fraction(0.0) self.pbar.set_text("0"+" %") box.pack_start(self.label, False, False, 10) box.pack_start(align, False, False, 5) self.wanttoabort = False self.connect("response", self.abort) carea = self.get_content_area() carea.pack_start(box, True, True, 0) self.show_all() def update(self, value): """Update the progress shown and return if user want to abort.""" self.pbar.set_fraction(value/self.limit) self.pbar.set_text(str(value/10)+" %") return self.wanttoabort def abort(self, dialog, response): """When the abort button is pressed this method is called and it updates the status of this object to take track of user action""" self.wanttoabort = (response in (Gtk.ResponseType.REJECT, Gtk.ResponseType.DELETE_EVENT)) def destroy(self): """Destroy current ProgressDialog""" Gtk.Dialog.destroy(self) class NumcpsDialog(Gtk.Dialog): """ask cps number you want to import""" def __init__(self, max_num_cps, max_length, file_ext): GObject.GObject.__init__(self) self.set_title(_(u"number of checkpoints")) self.set_modal(True) self.set_destroy_with_parent(True) #self.add_button(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT) self.connect("delete-event", self.destroy) self.set_size_request(330, 150) box = Gtk.VBox() self.notebook = Gtk.Notebook() self.notebook.set_show_tabs(False) frame = Gtk.Frame() vbox_1 = Gtk.VBox() label = Gtk.Label(label=_(u"Choose the type of import you want")) vbox_1.pack_start(label, False, False, 15) hboxr = Gtk.HBox() vboxr = Gtk.VBox() self.button1 = Gtk.RadioButton.new_with_label_from_widget(None, _(u"Automatic")) self.button1.set_active(True) vboxr.pack_start(self.button1, False, False, 0) self.button2 = Gtk.RadioButton.new_from_widget(self.button1) self.button2.set_label(_(u"Select the number of checkpoints")) vboxr.pack_start(self.button2, False, False, 0) self.button3 = Gtk.RadioButton.new_from_widget(self.button1) self.button3.set_label(_(u"Select the distance rate")) vboxr.pack_start(self.button3, False, False, 0) self.button4 = Gtk.RadioButton.new_from_widget(self.button1) self.button4.set_label(_(u"Use every point (discouraged)")) vboxr.pack_start(self.button4, False, False, 0) hboxr.pack_start(vboxr, False, False, 30) bbox = Gtk.HBox() button_n = Gtk.Button(_(u"Next")) bbox.pack_end(button_n, False, False, 5) button_n.connect("clicked", self.next_clicked) vbox_1.pack_end(bbox, False, False, 10) vbox_1.pack_end(hboxr, False, False, 5) frame.add(vbox_1) frame.set_shadow_type(Gtk.ShadowType.NONE) self.notebook.append_page(frame, Gtk.Label(label="1")) frame = Gtk.Frame() label = Gtk.Label(label=_(u"The %s file contains %d points.\nChoose how many will be imported.") % (file_ext, max_num_cps)) self.gpxnum = Gtk.HScale() self.gpxnum.set_range(0, max_num_cps) self.gpxnum.set_increments(1, 1) self.gpxnum.set_digits(0) self.gpxnum.set_size_request(160, 38) self.gpxnum.set_value(0) box.pack_start(label, False, False, 5) box.pack_start(self.gpxnum, False, False, 5) bbox = Gtk.HBox() button_n = Gtk.Button(_(u"Finish")) button_c = Gtk.Button(_(u"Back")) bbox.pack_end(button_n, False, False, 5) bbox.pack_end(button_c, False, False, 5) button_n.connect("clicked", self.next_clicked) button_c.connect("clicked", self.back_clicked) box.pack_end(bbox, False, False, 10) frame.add(box) frame.set_shadow_type(Gtk.ShadowType.NONE) self.notebook.append_page(frame, Gtk.Label(label="2")) frame = Gtk.Frame() boxdist = Gtk.VBox() label = Gtk.Label(label=_(u"The %s file contains a route of %d Km.\nChoose what range you want between points.") % (file_ext, max_length)) self.gpxdist = Gtk.HScale() self.gpxdist.set_range(0, int(max_length)) self.gpxdist.set_increments(1, 1) self.gpxdist.set_digits(0) self.gpxdist.set_size_request(160, 38) self.gpxdist.set_value(0) boxdist.pack_start(label, False, False, 5) boxdist.pack_start(self.gpxdist, False, False, 5) bbox = Gtk.HBox() button_n = Gtk.Button(_(u"Finish")) button_c = Gtk.Button(_(u"Back")) bbox.pack_end(button_n, False, False, 5) bbox.pack_end(button_c, False, False, 5) button_n.connect("clicked", self.next_clicked) button_c.connect("clicked", self.back_clicked) boxdist.pack_end(bbox, False, False, 10) frame.add(boxdist) frame.set_shadow_type(Gtk.ShadowType.NONE) self.notebook.append_page(frame, Gtk.Label(label="3")) self.notebook.set_current_page(0) self.notebook.show_all() carea = self.get_content_area() carea.pack_start(self.notebook, True, True, 0) self.show_all() def next_clicked(self, event): "Show next page" if self.notebook.get_current_page() == 0: if self.button1.get_active(): self.response(True) elif self.button2.get_active(): self.notebook.set_current_page(1) self.notebook.show_all() elif self.button3.get_active(): self.notebook.set_current_page(2) self.notebook.show_all() elif self.button4.get_active(): self.response(True) else: self.response(True) def back_clicked(self, event): "Show initial page" self.notebook.set_current_page(0) self.notebook.show_all() def destroy(self, event=None, param=None): """Destroy current dialog""" self.response(False) Gtk.Dialog.destroy(self) def geterrnoroute(parent): """Get an error message explaining that you should have selected one route""" mdlg = Gtk.MessageDialog(parent, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _(u'No route')) mdlg.format_secondary_text(_(u"Specify one route first.")) mdlg.run() mdlg.destroy() def managecperr(parent): """Get an error message explaining that you should have inserted altitude and distance""" mdlg = Gtk.MessageDialog(parent, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _("Form incomplete")) mdlg.format_secondary_text(_("Distance and altitude are required.")) mdlg.run() mdlg.destroy() def mapcoorderr(parent): """Get an error message explaining that there are no coords in the slope""" mdlg = Gtk.MessageDialog(parent, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _("No coordinates")) mdlg.format_secondary_text(_("there aren't coordinates associated with this slope.")) mdlg.run() mdlg.destroy() def geterrnocp(parent): """Get an error message explaining that you should have at least 2 cps to plot""" mdlg = Gtk.MessageDialog(parent, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, _(u'Not enough check points')) mdlg.format_secondary_text(_(u"""There aren't enougth check points to plot. At least two points are required to plot.""")) mdlg.run() mdlg.destroy() def numcpsdlg(max_num_cps, max_length, file_ext): """ask what number of cps in a gpx or tcx files have to be imported""" dlg = NumcpsDialog(max_num_cps, max_length, file_ext) response = dlg.run() if response == False: return (-1, 0) if dlg.button1.get_active(): dlg.destroy() return (0, -1) elif dlg.button2.get_active(): val = dlg.gpxnum.get_value() dlg.destroy() return (0, int(val)) elif dlg.button3.get_active(): val = dlg.gpxdist.get_value() dlg.destroy() return (1, int(val)) elif dlg.button4.get_active(): dlg.destroy() return (0, max_num_cps) def assistant_end(parent, value): parent.Close() return (0, 20) def save_changes(parent, filename): """Show a message if you close a modified and not saved slope""" response = None text = ""+(_(u"Save changes to %s before closing?") % filename)+"" secondary_text = _(u"If you don't save, all your changes will be " "permanently lost.") mdlg = Gtk.MessageDialog(parent, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, text) mdlg.set_title(_(u'Save changes')) mdlg.set_markup(text) mdlg.format_secondary_text(secondary_text) mdlg.add_buttons(_(u'Close without saving'), Gtk.ResponseType.REJECT, Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.ACCEPT) mdlg.set_default_response(Gtk.ResponseType.ACCEPT) response = mdlg.run() mdlg.destroy() if response == Gtk.ResponseType.ACCEPT: return 'SAVE' if response == Gtk.ResponseType.REJECT: return 'DISCARD' if response == Gtk.ResponseType.CANCEL: return 'CANCEL' return response # vim:sw=4:softtabstop=4:expandtab cyclograph-1.6.1/cyclograph/google.css0000644000175000017500000000034512065361217021362 0ustar federicofederico00000000000000.olLayerGoogleCopyright{right:3px;bottom:2px;left:auto;}.olLayerGoogleV3.olLayerGoogleCopyright{bottom:0;right:0!important;}.olLayerGooglePoweredBy{left:2px;bottom:2px;}.olLayerGoogleV3.olLayerGooglePoweredBy{bottom:0!important;}cyclograph-1.6.1/pixmaps/0000755000175000017500000000000012231302005016701 5ustar federicofederico00000000000000cyclograph-1.6.1/pixmaps/icon_add.png0000644000175000017500000000237312065361217021173 0ustar federicofederico00000000000000PNG  IHDR szzsRGBbKGD pHYs B(xtIME +(W{IDATXmLSWR^:XGLj?8e ASi&ٖ`0\ 1f! Ӱ-E]H{L1F N =P.Teٓwrysw_IKK{IE&Y8VGGGN H Z,***l6ےVԤ\1U(Jo ͛Y>IQsWWW>p8BH3FJKK *V\9-3׫aPѨa`!<,3>>ʲ|[|u yԩS^~cng~UWKQQNX^^j=TU5LRXXɉa1YiiilooH$"?n0q{`ٲeS>vg>ӌ߾'u_аv$$LMM24c\^qIf5>gMB^bʈʹNǖ-e688Hevw7 Ϭ'R `VjBf3jDmzmM BPmiL9T s]y<8):@D{%5oj`e-0aE=0,phƯ\ B!>Dg^fMbm۪K]~jC1މNa5*" D9!eWo u,d\o3xzz:ء^s{&hXP@ image/svg+xml cyclograph-1.6.1/pixmaps/icon_info.svg0000644000175000017500000006567212065361217021424 0ustar federicofederico00000000000000 image/svg+xml cyclograph-1.6.1/pixmaps/icon_ckml.png0000644000175000017500000000451412065361217021370 0ustar federicofederico00000000000000PNG  IHDR szzsRGBbKGD pHYs B(xtIME;mIDATXŗkU{Ͻs=hp5bUimm6M4jmU/_hx8y2 af38޻Jlkҝ/gk RAX,wU>ovZS|0eJn`is'08j/b6uX]fF")85->o(|KQwH(%2X4yā 4{5 类69BF+[tY=Yn\BHo D"M6ܑ]wtsعoTJi9JoXqhit7Lܩ$[}U<l%qdƭyI (%G ]V4PJtIJHs ڑ lyLmDFPv"Fų9ɮz-2Oh[zիvy 9&o@`uULT(Jilg;c-noSiO礬!*ق!  uU Dׅk:OWEX5-D. c`?_^`=('1= 5  F(Tu}`,sKWD׶O  dG>O4MMh޻GƨQ4n!4zȀD2亮:z8A;,t|*I!/sx֦Mo$(BO7oVFZ(;?}NA:&"xٺ{&(jxay$ ȄT577 ;PH%$bcx;hjT$V;4 hbzG֣(-$cؖyV%;v%糭D" ]K bMuTOB0}E33P a-'Ҳ-`T(J b6˼Vϲ be>6 \J(5NAjB9ʜ"tt~ 2ppz䎵X&PbF*X.3ṔWL<|7|y;xoHϲOf&Z'A O ;B"G 4竃UµH)+ﭥ/ҷelJ4VvR }%A .Hij+RQ@#FU>irre :WPK p WԞH JT,lag)#d1$2}:'[XiJ̒F躸riIzdxH <;p u2 7\UOn~b:LӤT(gt2eȎd1qN%'+ g 2,"NE8 ѩhZ6${3 ~-߆s?y,K6Wa ^L(wB~''[#[:t8n.UnݳnC-]:93*8Qږ{2f8s߼b-A pJ(: 2mN$"3#N8 A XMR1sA OnP5HW V;C9 ay%7&I,|^õq:z@ (B|xƨ~/ơ8>'j%}`BD L yE>B&X:N 6nZB&G?XzM^T *DX<ɒ/:LpүQ Uc5kl\9 Yfmvb ( rUSq62?֒v BC&9 3q7BKglQR_֒.abBD߀DL_c˾ui 4Xr/{h1xjjX\!>aCx| bbddoFT7?E EL+Qxad6QaCy3\FzxܺgH))lݐ*[ujTC5o"&uuOPao>E.jvwTUӎMp6<>mB3-ښY7U Fr>|]?_b\VIENDB`cyclograph-1.6.1/pixmaps/icon_info.png0000644000175000017500000000217412065361217021375 0ustar federicofederico00000000000000PNG  IHDR szzsRGBbKGD pHYs B(xtIME *-&"IDATX_H[WǿILbLHb!`}Z[?GI()djك4 I+ l0FQkn I˟6ٍ$/Wwonbn;#|=ߛ$,))cDcD" ~u(0tuu6666)߿O2 K򭖖ꪔanh@Z#=x* HuսPܶp8c;;;P(< AQvww%2>cv4UVU/0ł˗/add}}ysMMMzk3HRV^WWW XUU---(򹹹F $I갿w\-ZpWVVۗ\.| n7!Dࠀ WdK/u`yy_\. M(,^/') АL ρLE~AXxXh4]H2s•+텇d2P(ȳ7 NI±?9ȑ#6 ZFyy9ϔ2̙'p:OmmnB8>#HZ==aq NV 55G;|П3{fMӼyӉQ#bۂwz <8;WHf}|÷iqZ2m!7g(ʜf]Nv)ke/wOW:=oؾR+b ,i,>TDZbDWunatJ2?` 3rPJy?Ҿfes< ` ^5]j@vVs:q Jr|oa zX̬,ُfƨR>JI1J Q,W%LmOr ;chfvxb͛k@,0 `<Pm;HY`="IENDB`cyclograph-1.6.1/pixmaps/icon_modify.png0000644000175000017500000000272212065361217021730 0ustar federicofederico00000000000000PNG  IHDR szzsRGBbKGD pHYs B(xtIME /%sURIDATXLSWǿ}Pi( j 8آQ9]4bEň2!2DzM2uN-8РVp*F-By RNrϽ}9sF~~~IBPb\l``ip˰Upzg4(H222bcc'6nc44}g\nOjj*&@cc#EӴH]7LzX^dA X\YY.KڽVX{{3زɚZUkSE91C`a }5_=4*1 lSm}0؝GmWd-Vl`zC'>ū @!f,''g;x[2h|R[i{sxN{7(`7^GL,t-#/Łtΰa) Bw+Lȁ3fb4kkkƍwї{ ~؁IhA!jQ܄K 8 ]Ix]"b1ŨJQo {vpdnI?7c9 ӣd(f+*7B~`% Btt4\ n3+)Wl(bv?%S(U555 233<4wBsn!qj.V^ \hnnFLʷ]P*[:0)jOex἖,D#O,6I{gpZ2UY ߂gm7 y YAC§g%8^Slnǰ >} "cZ*[y SFtI;(ő ^qd룡VzA ةmےt:V:^ȱ>vU*Ve)˖K$u)Y+"{\{N{|0r# ` "hoo'Ka "6%FqhM__|L%%% Ab2(,,LWQQDc:Z},~95sm%%eC, Vxdǟw;< HP/GtT7ŝKF_sddYn `1*H_75Xl;zu8}⇥SDgG7j].Tt_בZZIENDB`cyclograph-1.6.1/pixmaps/icon_plot.svg0000644000175000017500000002145112065361217021432 0ustar federicofederico00000000000000 image/svg+xml cyclograph-1.6.1/pixmaps/icon_add.svg0000644000175000017500000005460312065361217021211 0ustar federicofederico00000000000000 image/svg+xml cyclograph-1.6.1/pixmaps/icon_map.svg0000644000175000017500000011261312204123117021220 0ustar federicofederico00000000000000 image/svg+xml cyclograph-1.6.1/pixmaps/icon_modify.svg0000644000175000017500000007035512065361217021752 0ustar federicofederico00000000000000 image/svg+xml cyclograph-1.6.1/pixmaps/icon_plot.png0000644000175000017500000000154612065361217021422 0ustar federicofederico00000000000000PNG  IHDR szzsRGBbKGD pHYs B(xtIME 2(-!nIDATXŖKHTQcƩ s@ *Z M"j%mz- BZ$(h ep=D,#BSLLj83z޹-fFL6gs0 {ҏ^}p`JJJeTU˫ ,Ċe]so[=]5ݢGBa^ڭg ' d/AF ( &~X%myOU H@"G} i_f@5m,N#WLh ]0trYm 5.hAdsOʏtc$A)sAzFX(y_w{Ԥ"cKNVCسYX"]4uY]PtOO=EQb'A# >^VC6=g;#wK<p|pH E)z Ik9:@.=3 #E (=K7LĜQa]D{΋G8fzDs  :`/8%mQI X }!ٴ (@|9H42wa6;9vz HS 0(1f3e Yeȓ7Qlϖ|x߲/t]A+@ @]FO&}RXԊjP²d+Es(,q%ˏ-=_GU}Xxݮ MD\10`IENDB`cyclograph-1.6.1/pixmaps/icon_delete.svg0000644000175000017500000006117712065361217021727 0ustar federicofederico00000000000000 image/svg+xml cyclograph-1.6.1/pixmaps/icon_map.png0000644000175000017500000000331212204123117021200 0ustar federicofederico00000000000000PNG  IHDR szzbKGD pHYs B(xtIME )@v5WIDATXõih\{;fH#lɱkl'8vb MEP!;&6.B n]SH]V6j-XvśK3f{Nh45q8w=Fgggfֱ'٢: 1-\ajaqQ3}3a>%{?9A#HQ) umq xG$.hK}ox9$kMvf atYIurž# ŭ|]ZZ]@?qdJ D6U Ѡ 잝D8Ǻѵå{/R::ͳTѵ  |KҠ擓63am9oכ$X#C|'AN.$0 \)m8\&nGhK5c+7_@ݩe2 ^?T/i{7Mg[x^2$V~*ٚ2P0`a{`w"~i)Y8|"&u?@,}ʤ>XE7ҽ 1Yɠ7eSOOタۡYުqbMv7!8C[4CKM]_=\ϲAl;lZ84+rO1QW~8&W "o?LC?9Bpe*[m| _)aBƂO9_4ϽKK&Dj"P0JߕZ&َ~ |OHUV% ny5>A|h@S(o&1D{3_AyD172|Aͫ] r쑰ѮH c&ob}].5RK/":@yaF;ce= ,jyU/ [ƌRaFMW/G {r[5w~=a&ζSIEHD_G8k>^&W UJz~SN _Xz2>uyI}k>[n/ (Gp: ϴy. image/svg+xml cyclograph-1.6.1/pixmaps/icon_delete.png0000644000175000017500000000216012065361217021677 0ustar federicofederico00000000000000PNG  IHDR szzsRGBbKGD pHYs B(xtIME + 67IDATXmHdU3Ό#"2j":\DK>$.ԇE7JucA1n0k[BaAm*4-:&Λs0cm`/{s.^/mmh4TTĉf[^^CT!Ub++#`4˓1!G޿t?s xq8rzz2Xl ?3=3g4Cֿŋ} CycloGraph User Manual

CycloGraph User Manual

Introduction

1.1 Features

Manual insertion

GPS tracks

Files produced by other applications

KML format and drawing on maps

Basic usage

2.1 Start the application

Qt 4

GTK+

Command Line

2.2 Editing a new file

2.3 Show the plot

2.3.1 Save the plot as Image

Expert Usage

3.1 Command Line

3.2 Editing the CycloGraph CSV file

  1. CSV version
  2. slope name
  3. slope state
  4. author
  5. author's e-mail
  6. comments
  1. distance
  2. altitude
  3. check point name
cyclograph-1.6.1/setup.py0000644000175000017500000000321512204123117016740 0ustar federicofederico00000000000000#!/usr/bin/env python from distutils.core import setup from cyclograph.version import VERSION import glob files = ["openlayers.html", "map.html", "google.css", "draw_on_map.js"] icons = glob.glob('pixmaps/icon_*.png') + glob.glob('pixmaps/icon_*svg') setup(name = "cyclograph", version = VERSION, description = "route altimetry plotting application", author = "Federico Brega, Pierluigi Villani", author_email = "charon66@users.sourceforge.net", url = "http://cyclograph.sourceforge.net", license = "GPL v3 or later", packages = ['cyclograph', 'cyclograph.qt', 'cyclograph.gtk_', 'cyclograph.gtk3'], package_data = {'cyclograph' : files }, scripts = ["cyclograph/cyclograph"], data_files = [('share/icons/hicolor/scalable/apps', ['pixmaps/cyclograph.svg']), ('share/icons/hicolor/32x32/apps', ['pixmaps/cyclograph.png']), ('share/pixmaps', icons), ('share/locale/en/LC_MESSAGES', ['po/en/LC_MESSAGES/cyclograph.mo']), ('share/locale/it/LC_MESSAGES', ['po/it/LC_MESSAGES/cyclograph.mo']), ('share/applications', ['cyclograph-qt.desktop', 'cyclograph-gtk3.desktop', 'cyclograph-gtk.desktop']), ], long_description = \ """CycloGraph is an application for plotting the elevation profile of routes. Its main value is in the graphical visualization of the difficulty of a road, in term of slope, difference in height, etc. Plots like these are often used in cycling competitions, but are also useful in other sports, such as hiking or running.""" )