From 5e92093483fb9c9bd7fd365fdf6ab8b42f365ac4 Mon Sep 17 00:00:00 2001 From: pdeman Date: Thu, 1 Feb 2018 14:49:37 +0100 Subject: [PATCH] first deposit --- DeetoMaison.py | 374 ++ DeetoMaison.ui | 123 + Image Import.xpyqt | 41 + ImageImport.py | 36 + ImageImport.sh | 8 + ImageImportWindow.py | 3375 +++++++++++ ImageImportWindow.ui | 2222 +++++++ ImportTheoreticalImplentation.py | 87 + Logo-F-TRACT.xpm | 2693 +++++++++ MicromedListener.py | 86 + TimerMessageBox.py | 57 + anonymizeTRC.py | 59 + anonymizer.py | 718 +++ autoImportScript.py | 127 + bipoleLabelsDisplay.ui | 146 + bipoleSEEGColors.py | 267 + checkSpmVersion.py | 7 + control_ftract.py | 159 + control_ftract2.py | 40 + cutmeshwidget.ui | 234 + dicomutilities.py | 271 + editor.py | 373 ++ electrode.py | 209 + electrodeEditor.ui | 374 ++ electrodedisplaywidget.py | 1301 ++++ epilepsie-electrodes.ui | 759 +++ externalprocesses.py | 186 + freesurfer_label.txt | 1294 ++++ generate_boundaries.py | 12 + generate_contact_colors.py | 97 + getTRCpatientData.c | 74 + greendot.png | Bin 0 -> 332 bytes groupDisplay.py | 54 + groupDisplay.sh | 8 + groupPlots.ui | 442 ++ identity.trm | 5 + locateContacts.py | 572 ++ locateElectrodes.py | 4460 ++++++++++++++ locateElectrodes.sh | 8 + logoIntrAnat.xpm | 9270 +++++++++++++++++++++++++++++ parcels_label_name.txt | 82 + parcels_label_name_AAL.txt | 116 + parcels_label_name_AALDilate.txt | 116 + parcels_label_name_Hammers.txt | 83 + pathologypatientinfo.py | 326 + patientDataFilter.ui | 740 +++ patientdatafilterwidget.py | 1148 ++++ patientinfo.py | 301 + prepareData.py | 20 + readElecLocalCSVFile.py | 147 + readFreesurferLabelFile.py | 7 + readFunctionalTractography.py | 52 + readSulcusLabelTranslationFile.py | 7 + referentialconverter.py | 441 ++ seegprocessing.py | 51 + standard_fit.py | 116 + templatewidget.py | 235 + templatewidget.ui | 141 + 58 files changed, 34757 insertions(+) create mode 100644 DeetoMaison.py create mode 100644 DeetoMaison.ui create mode 100644 Image Import.xpyqt create mode 100644 ImageImport.py create mode 100644 ImageImport.sh create mode 100644 ImageImportWindow.py create mode 100644 ImageImportWindow.ui create mode 100644 ImportTheoreticalImplentation.py create mode 100644 Logo-F-TRACT.xpm create mode 100644 MicromedListener.py create mode 100644 TimerMessageBox.py create mode 100644 anonymizeTRC.py create mode 100644 anonymizer.py create mode 100644 autoImportScript.py create mode 100644 bipoleLabelsDisplay.ui create mode 100644 bipoleSEEGColors.py create mode 100644 checkSpmVersion.py create mode 100644 control_ftract.py create mode 100644 control_ftract2.py create mode 100644 cutmeshwidget.ui create mode 100644 dicomutilities.py create mode 100644 editor.py create mode 100644 electrode.py create mode 100644 electrodeEditor.ui create mode 100644 electrodedisplaywidget.py create mode 100644 epilepsie-electrodes.ui create mode 100644 externalprocesses.py create mode 100644 freesurfer_label.txt create mode 100644 generate_boundaries.py create mode 100644 generate_contact_colors.py create mode 100644 getTRCpatientData.c create mode 100644 greendot.png create mode 100644 groupDisplay.py create mode 100644 groupDisplay.sh create mode 100644 groupPlots.ui create mode 100644 identity.trm create mode 100644 locateContacts.py create mode 100644 locateElectrodes.py create mode 100644 locateElectrodes.sh create mode 100644 logoIntrAnat.xpm create mode 100644 parcels_label_name.txt create mode 100644 parcels_label_name_AAL.txt create mode 100644 parcels_label_name_AALDilate.txt create mode 100644 parcels_label_name_Hammers.txt create mode 100644 pathologypatientinfo.py create mode 100644 patientDataFilter.ui create mode 100644 patientdatafilterwidget.py create mode 100644 patientinfo.py create mode 100644 prepareData.py create mode 100644 readElecLocalCSVFile.py create mode 100644 readFreesurferLabelFile.py create mode 100644 readFunctionalTractography.py create mode 100644 readSulcusLabelTranslationFile.py create mode 100644 referentialconverter.py create mode 100644 seegprocessing.py create mode 100644 standard_fit.py create mode 100644 templatewidget.py create mode 100644 templatewidget.ui diff --git a/DeetoMaison.py b/DeetoMaison.py new file mode 100644 index 0000000..21a14ac --- /dev/null +++ b/DeetoMaison.py @@ -0,0 +1,374 @@ +# -*-coding:utf-8 -* + +#Import of Usefull Libraries +import struct, time, re, os, json, subprocess +from PyQt4 import QtGui, QtCore, uic, Qt +import pdb +from numpy import * +from math import sqrt + +from soma import aims + +from brainvisa import anatomist +from brainvisa.data.writediskitem import ReadDiskItem, WriteDiskItem + +from referentialconverter import ReferentialConverter +from collections import Counter + + +import matplotlib.pyplot as plt +from scipy import signal, stats +from locateContacts import * +import copy + +#Main Class +class DeetoMaison(QtGui.QDialog): + + def __init__(self, locateData=None): + # UI init + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("DeetoMaison.ui", self) + self.setWindowTitle('Automatic electrodes localization') + self.locaData =locateData #Data from locatesElectrode.py + self.a=self.locaData.a #Anatomist Object + self.dicMeshes={} + self.CT=True + + model= QtGui.QStandardItemModel(len(self.locaData.electrodes), 1) + for i,area in enumerate([self.locaData.electrodes[i]['name'] for i in range(len(self.locaData.electrodes))]): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + self.listViewElectrodes.setModel(model) + + self.connect(self.pushButtonOk, QtCore.SIGNAL('clicked()'), self.verifSelec) + self.connect(self.pushButtonCheckElec, QtCore.SIGNAL('clicked()'), self.check) + self.connect(self.pushButtonUncheckElec, QtCore.SIGNAL('clicked()'), self.uncheck) + self.connect(self.pushButtonElecAppear, QtCore.SIGNAL('clicked()'), self.printElec) + self.connect(self.pushButtonRemoveElec, QtCore.SIGNAL('clicked()'), self.removeElec) + + + + def verifSelec(self): + serpentin=False + if self.checkBoxSerpentins.checkState()==QtCore.Qt.Checked: + serpentin=True + + #dans une sous fonction appelé par un connect + Model=self.listViewElectrodes.model() + #boucle for sur les index Item =Model.item(index) + index=1 + elecSelec=[] + while index + + Form + + + + 0 + 0 + 802 + 349 + + + + Form + + + + + -1 + 9 + 801 + 291 + + + + + + + Deeto Maison + + + Qt::AlignCenter + + + + + + + + + + + Electrode List + + + + + + + + + + + + + + Ok + + + + + + + Print Electrodes + + + + + + + Remove Electrode + + + + + + + + + + + + + 198 + 310 + 151 + 27 + + + + Check all electrodes + + + + + + 380 + 310 + 171 + 27 + + + + Uncheck all electrodes + + + + + + 671 + 310 + 101 + 20 + + + + Serpentins? + + + + + + diff --git a/Image Import.xpyqt b/Image Import.xpyqt new file mode 100644 index 0000000..a96ed8a --- /dev/null +++ b/Image Import.xpyqt @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ImageImport.py b/ImageImport.py new file mode 100644 index 0000000..cb05c70 --- /dev/null +++ b/ImageImport.py @@ -0,0 +1,36 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Import and register images in the database +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# + + +import sys + +# import PyQt4 QtCore and QtGui modules +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +from ImageImportWindow import ImageImportWindow + +if __name__ == '__main__': + + # create application + app = QApplication(sys.argv) + app.setApplicationName('Image Import') + + # create widget + w = ImageImportWindow() + w.setWindowTitle('Image Import - NOT FOR MEDICAL USAGE') + w.show() + + # connection + QObject.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()')) + # Debug -> evite un pb entre ipython, pdb et qt + pyqtRemoveInputHook() + # execute application + sys.exit(app.exec_()) diff --git a/ImageImport.sh b/ImageImport.sh new file mode 100644 index 0000000..15793d8 --- /dev/null +++ b/ImageImport.sh @@ -0,0 +1,8 @@ +#!/bin/bash +cd /Users/admin/Softwares/BrainVISA-4.5/bin/ +. /Users/admin/Softwares/BrainVISA-4.5/bin/bv_env.sh /Users/admin/Softwares/BrainVISA-4.5 +cd /Users/admin/Documents/GIT/IntrAnatElectrodes/epilepsie/ +echo "#############################################################################" >> intranat-imageImport-`whoami`.log +date >> intranat-imageImport-`whoami`.log +python ImageImport.py >> intranat-imageImport-`whoami`.log + diff --git a/ImageImportWindow.py b/ImageImportWindow.py new file mode 100644 index 0000000..9513af6 --- /dev/null +++ b/ImageImportWindow.py @@ -0,0 +1,3375 @@ +# -*- coding: utf-8 -*- +# +# Importation of data in the database + image registration and normalization +#(c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# +#TODO +# +# Tester et finaliser l'import depuis un PACS +# +# Verifier qu'on ne convertit pas une image déjà récupérée (surtout DICOM-> Nifti !) +# +# Améliorer le choix de l'image pre/post dans BrainVisa : afficher des aperçus avec Anatomist après l'import DICOM ? +# Ou coder en C++ un créateur d'aperçu DICOM avec la lib dcmtk, ou utiliser http://sourceforge.net/projects/qdcws/ +# +#Optimisation : on peut supposer que le nombre de slices +# (SliceNumberMR) quand on ouvre un fichier permet de +# sauter les SliceNumberMR-1 suivants car ce sont les +# autres slices de la même image +# +# Onglet registration : mettre en vert les images qui ont déjà un recalage vers la T1pre, en gras l'image normalisée vers le template SPM +# FIXME La version suivante de BrainVisa (post 4.3) devrait corriger un bug dans l'insertion des items dans la base (en insérant les répertoires qui les contiennent) +# Il faudra alors virer la fonction createItemDirs que j'ai créé pour résoudre ce pb. D'autre part pour résoudre le pb pour les fichiers registration +# j'ai ajouté l'insertion des répertoires dans data/neuroDiskItems.py (fonction createParentDirectory) mais ça ne marche pas (import circulaires !) +# Donc à chaque ajout de référentiel ou de transfo, j'ai ajouté une ligne neuroHierarchy.databases.createDiskItemFromFileName A SUPPRIMER quand BrainVisa sera corrigé (après BV 4.3) + #dirItem=neuroHierarchy.databases.createDiskItemFromFileName(d, None) +# import pdb;pdb.set_trace() -> pour lancer le debugger quand on arrive sur cette ligne (sorte de breakpoint) +# ipython -q4thread locateElectrodes.py # Pour avoir ipython et Qt actifs en même temps au cours du debug + + +from PyQt4 import uic, QtGui, QtCore +import os, subprocess, re, pickle, shutil, tempfile, scipy.io, json, numpy +from scipy import ndimage + +from brainvisa import axon, processes + +from soma import aims +from soma.wip.application.api import Application +from brainvisa.data.writediskitem import ReadDiskItem, WriteDiskItem +from brainvisa.data import neuroHierarchy +#import anatomist.direct.api as anatomist +from brainvisa import anatomist +import registration + +from externalprocesses import * +from dicomutilities import * +import seegprocessing, patientinfo, pathologypatientinfo +from checkSpmVersion import * +from freesurfer.brainvisaFreesurfer import * +from TimerMessageBox import * + +import pdb + +# Matlab code : coregister file1 to file2 +def matlab_cellstr(listOfStrings): + """ Converts a list of filenames as a matlab-suitable cell table of strings and adds ',1' at the end of each string (for spm file lists) """ + return "{'"+",1' '".join([str(stri) for stri in listOfStrings])+",1'}" + +# SPM coregistration onto file1 ({'/home/manik/data/epilepsie/IRM-testOD/Pre/3DT1.img,1'}) of file 2 ({'/home/manik/data/epilepsie/IRM-testOD/Post/SagT2.img,1'}) +#spm_coregister = "try, spm('defaults', 'FMRI');spm_jobman('initcfg');\ +#matlabbatch{1}.spm.spatial.coreg.estimate.ref = %s;\ +#matlabbatch{1}.spm.spatial.coreg.estimate.source = %s;\ +#matlabbatch{1}.spm.spatial.coreg.estimate.other = {''};\ +#matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.cost_fun = 'nmi';\ +#matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.sep = [4 2];\ +#matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.tol = [0.02 0.02 0.02 0.001 0.001 0.001 0.01 0.01 0.01 0.001 0.001 0.001];\ +#matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.fwhm = [7 7];\ +#spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;" + +# Coregister two files and saves the matrix in an ASCII file (space-separated) +spm_coregister = """try,addpath(genpath(%s));VF=spm_vol(%s);VG=spm_vol(%s); +centermatF = eye(4); +center_F = %s; +F_orient = %s; +F_orient = reshape(F_orient,4,4)'; +centermatF(:,4) = F_orient*[center_F 1]'; +centermatG = eye(4); +center_G = %s; +G_orient = %s; +G_orient = reshape(G_orient,4,4)'; +centermatG(:,4) = G_orient*[center_G 1]'; +centeredmatF = inv(centermatF)*VF.private.mat; +centeredmatG = inv(centermatG)*VG.private.mat; +VF.mat = centeredmatF; +VF.private.mat = centeredmatF; +VF.private.mat0 = centeredmatF; +VG.mat = centeredmatG; +VG.private.mat = centeredmatG; +VG.private.mat0 = centeredmatG; +x = spm_coreg(VF,VG); +matCoreg = spm_matrix(x(:)'); +trm = centermatG*matCoreg*inv(centermatF); +trm = [trm(1:3,4)';trm(1:3,1:3)]; +dlmwrite(%s,trm, 'delimiter',' ','precision',16); \n +catch, disp 'AN ERROR OCCURED'; end;quit;""" + + +# SPM coregistration onto file1 ({'/home/manik/data/epilepsie/IRM-testOD/Pre/3DT1.img,1'}) of file 2 ({'/home/manik/data/epilepsie/IRM-testOD/Post/SagT2.img,1'}) with reslicing +spm_coregisterReslice = "try,addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg');\ +matlabbatch{1}.spm.spatial.coreg.estwrite.ref == %s;\ +matlabbatch{1}.spm.spatial.coreg.estwrite.source = %s;\ +matlabbatch{1}.spm.spatial.coreg.estwrite.other = {''};\ +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.cost_fun = 'nmi';\ +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.sep = [4 2];\ +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.tol = [0.02 0.02 0.02 0.001 0.001 0.001 0.01 0.01 0.01 0.001 0.001 0.001];\ +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.fwhm = [7 7];\ +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.interp = 1;\ +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.wrap = [0 0 0];\ +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.mask = 0;\ +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.prefix = 'r';\ +spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;" + + +# SPM normalisation of file 1 ({'/home/manik/data/epilepsie/IRM-testOD/Pre/3DT1.img,1'}) onto template +#spm_template_t1 = "{'/home/manik/prog/implantation/matlab/spm8/templates/T1.nii,1'}" +#spm_template_t1 = "{'/matlab_prog/spm8_5236/templates/T1.nii,1'}" +#spm8_normalise = """try, addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg'); +#matlabbatch{1}.spm.spatial.normalise.est.subj.source = %s; +#matlabbatch{1}.spm.spatial.normalise.est.subj.wtsrc = ''; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.template = %s; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.weight = ''; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.smosrc = 8; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.smoref = 0; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.regtype = 'mni'; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.cutoff = 25; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.nits = 16; +#matlabbatch{1}.spm.spatial.normalise.est.eoptions.reg = 1; +#spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm8_normalise = """try, addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg'); +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.source = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.wtsrc = ''; +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.resample = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.template = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.weight = ''; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.smosrc = 8; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.smoref = 0; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.regtype = 'mni'; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.cutoff = 25; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.nits = 16; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.reg = 1; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.preserve = 0; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.bb = [-78 -112 -50 + 78 76 85]; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.vox = [1 1 1]; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.interp = 1; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.wrap = [0 0 0]; +matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.prefix = 'w'; +spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm12_normalise = """try, addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg'); +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.vol = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.subj.resample = %s; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.biasreg = 0.0001; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.biasfwhm = 60; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.tpm = {%s}; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.affreg = 'mni'; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.reg = [0 0.001 0.5 0.05 0.2]; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.fwhm = 0; +matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.samp = 3; +matlabbatch{1}.spm.spatial.normalise.estwrite.woptions.bb = [-78 -112 -70 + 78 76 85]; +matlabbatch{1}.spm.spatial.normalise.estwrite.woptions.vox = [1 1 1]; +matlabbatch{1}.spm.spatial.normalise.estwrite.woptions.interp = 4; +spm_jobman('run',matlabbatch); catch, disp 'AN ERROR OCCURED'; end;quit;""" + +matlab_removeGado = """try, addpath(genpath(%s)); spm('defaults', 'FMRI');spm_jobman('initcfg'); +matlabbatch{1}.spm.spatial.preproc.channel.vols = {%s}; +matlabbatch{1}.spm.spatial.preproc.channel.biasreg = 0.001; +matlabbatch{1}.spm.spatial.preproc.channel.biasfwhm = 60; +matlabbatch{1}.spm.spatial.preproc.channel.write = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(1).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(1).ngaus = 1; +matlabbatch{1}.spm.spatial.preproc.tissue(1).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(1).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(2).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(2).ngaus = 1; +matlabbatch{1}.spm.spatial.preproc.tissue(2).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(2).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(3).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(3).ngaus = 2; +matlabbatch{1}.spm.spatial.preproc.tissue(3).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(3).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(4).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(4).ngaus = 3; +matlabbatch{1}.spm.spatial.preproc.tissue(4).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(4).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(5).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(5).ngaus = 4; +matlabbatch{1}.spm.spatial.preproc.tissue(5).native = [1 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(5).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(6).tpm = {%s}; +matlabbatch{1}.spm.spatial.preproc.tissue(6).ngaus = 2; +matlabbatch{1}.spm.spatial.preproc.tissue(6).native = [0 0]; +matlabbatch{1}.spm.spatial.preproc.tissue(6).warped = [0 0]; +matlabbatch{1}.spm.spatial.preproc.warp.mrf = 1; +matlabbatch{1}.spm.spatial.preproc.warp.cleanup = 1; +matlabbatch{1}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; +matlabbatch{1}.spm.spatial.preproc.warp.affreg = 'mni'; +matlabbatch{1}.spm.spatial.preproc.warp.fwhm = 0; +matlabbatch{1}.spm.spatial.preproc.warp.samp = 2; +matlabbatch{1}.spm.spatial.preproc.warp.write = [0 0]; +spm_jobman('run',matlabbatch); +c1 = spm_vol(%s); +c2 = spm_vol(%s); +c3 = spm_vol(%s); +c4 = spm_vol(%s); +Yc1 = spm_read_vols(c1); +Yc2 = spm_read_vols(c2); +Yc3 = spm_read_vols(c3); +Yc4 = spm_read_vols(c4); +keepC1 = find(Yc1 ~= 0); +keepC2 = find(Yc2 ~= 0); +keepC3 = find(Yc3 ~= 0); +keepC4 = find(Yc4 ~= 0); +all_keep = unique([keepC1; keepC2]); +fullImage = spm_vol(%s); +YfullImage = spm_read_vols(fullImage); +all_remove = [1:1:size(YfullImage(:))]; +all_remove(all_keep)=[]; +YfullImage(all_remove)=0; +fullImage.fname=%s; +spm_write_vol(fullImage,YfullImage); +catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm_inverse_y_field12 = """try,addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.def = {%s}; +matlabbatch{1}.spm.util.defs.comp{1}.inv.space = {%s}; +matlabbatch{1}.spm.util.defs.out{1}.savedef.ofname = %s; +matlabbatch{1}.spm.util.defs.out{1}.savedef.savedir.saveusr = {%s}; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm_MNItoScannerBased = """try,addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +matlabbatch{1}.spm.spatial.normalise.write.subj.def = {%s}; +matlabbatch{1}.spm.spatial.normalise.write.subj.resample = {%s}; +matlabbatch{1}.spm.spatial.normalise.write.woptions.bb = [-150 -150 -150 + 150 150 150]; +matlabbatch{1}.spm.spatial.normalise.write.woptions.vox = [1 1 1]; +matlabbatch{1}.spm.spatial.normalise.write.woptions.interp = 4; +matlabbatch{1}.spm.spatial.normalise.write.woptions.prefix = 'tmpMNItoScannerBased'; +matlabbatch{2}.spm.spatial.realign.write.data = { + %s + %s + }; +matlabbatch{2}.spm.spatial.realign.write.roptions.which = [2 1]; +matlabbatch{2}.spm.spatial.realign.write.roptions.interp = 4; +matlabbatch{2}.spm.spatial.realign.write.roptions.wrap = [0 0 0]; +matlabbatch{2}.spm.spatial.realign.write.roptions.mask = 1; +matlabbatch{2}.spm.spatial.realign.write.roptions.prefix = ''; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + + +(Ui_ImageImportWindow, QDialog) = uic.loadUiType('ImageImportWindow.ui') + + +class ImageImportWindow (QDialog): + """ImageImportWindow is the main dialog class of the Image Importer software""" + + def __init__ (self, parent = None): + QDialog.__init__(self, parent) + #self.setWindowTitle('Image Import Window- NOT FOR MEDICAL USAGE') + self.ui = Ui_ImageImportWindow() + self.seriesUIDbyName = {} + self.studiesUIDbyName = {} + self.ui.setupUi(self) + self.currentProtocol = None + self.currentSubject = None + self.AcPc = {} + self.brainCenter = None + self.defaultAcqDate = QtCore.QDate(1900,1,1) + self.ui.acqDate.setDate(self.defaultAcqDate) + self.modas = {'t1mri':'Raw T1 MRI', 't2mri':'T2 MRI', 'ct': 'CT', 'pet': 'PET','fmri_epile':'fMRI-epile', 'statistic_data':'Statistic-Data', 'flair': 'FLAIR', 'freesurfer_atlas':'FreesurferAtlas', 'fgatir':'FGATIR', 'hippofreesurfer_atlas':'HippoFreesurferAtlas'} + + ## Init brainvisa to access the DB + axon.initializeProcesses() + # Allow calling brainvisa processes + from neuroProcesses import defaultContext + self.brainvisaContext = defaultContext() + + # Get Transformation Manager + self.transfoManager = registration.getTransformationManager() + + # Load anatomist + self.a = anatomist.Anatomist('-b') + + layout = QtGui.QVBoxLayout( self.ui.windowContainer1 ) + layout2 = QtGui.QHBoxLayout( ) + layout3 = QtGui.QHBoxLayout( ) + self.axWindow = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.axWindow2 = self.a.createWindow( 'Sagittal' )#, no_decoration=True ) + self.axWindow3 = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.axWindow4 = self.a.createWindow( 'Sagittal' )#, no_decoration=True ) + self.wins = [self.axWindow, self.axWindow2, self.axWindow3, self.axWindow4] + self.axWindow.setParent(self.ui.windowContainer1) + self.axWindow2.setParent(self.ui.windowContainer1) + self.axWindow3.setParent(self.ui.windowContainer1) + self.axWindow4.setParent(self.ui.windowContainer1) + layout2.addWidget( self.axWindow.getInternalRep() ) + layout2.addWidget( self.axWindow2.getInternalRep() ) + layout3.addWidget( self.axWindow3.getInternalRep() ) + layout3.addWidget( self.axWindow4.getInternalRep() ) + layout.addLayout(layout2) + layout.addLayout(layout3) + + self.dispObj = [] + + self.initialize() + + self.ui.dicomOutputPathEdit.setText(self.dicomOutputPath) + self.ui.niftiOutputPathEdit.setText(self.niftiOutputPath) + + self.threads = [] + self.waitingForThreads={} + # Init the patient informations tab + self.patientInfo = patientinfo.buildUI(self.ui.patGroupBox) + cdate = self.patientInfo['currentDate'].date() + bdate = self.patientInfo['patientBirthday'].date() + page = bdate.daysTo(cdate)/365 + self.patientInfo['patientAge'].setText(str(page)) + + self.patientInfo['comoraucune'].stateChanged.connect(self.checkbox_comor) + + self.patientInfo['patientBirthday'].dateChanged.connect(self.update_patientAge) + #self.pathologypatientInfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + + # Recharge la BDD BrainVisa à chaque changement d'onglet + self.connect(self.ui.tabWidget, QtCore.SIGNAL('currentChanged(int)'), self.analyseBrainvisaDB) + self.connect(self.ui.tabWidget, QtCore.SIGNAL('currentChanged(int)'), self.setTabGuide) + # Brainvisa database tab + self.connect(self.ui.bvProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.bvSubjectCombo)) + self.connect(self.ui.bvSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectBvSubject) + self.connect(self.ui.bvSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.bvImageList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'), self.selectBvImage) + self.connect(self.ui.bvDeleteImageButton, QtCore.SIGNAL('clicked()'), self.deleteBvImage) + self.connect(self.ui.bvDeleteSubjectButton, QtCore.SIGNAL('clicked()'), self.deleteBvSubject) + # Add Subject tab + self.connect(self.ui.subjectSiteCombo, QtCore.SIGNAL('activated(QString)'), self.updatePatientCode) + self.connect(self.ui.subjectSiteCombo, QtCore.SIGNAL('editTextChanged(QString)'), self.updatePatientCode) + self.connect(self.ui.subjectYearSpinbox, QtCore.SIGNAL('valueChanged(int)'), self.updatePatientCode) + self.connect(self.ui.subjectPatientName, QtCore.SIGNAL('textChanged(QString)'), self.updatePatientCode) + self.connect(self.ui.subjectPatientFirstName, QtCore.SIGNAL('textChanged(QString)'), self.updatePatientCode) + self.connect(self.ui.subjectAddSubjectButton, QtCore.SIGNAL('clicked()'), self.storePatientInDB) + # DICOM tab + self.connect(self.ui.chooseDirButton, QtCore.SIGNAL('clicked()'), self.openDicomDir) + self.connect(self.ui.dirImportButton, QtCore.SIGNAL('clicked()'), self.importDataDir) + self.connect(self.ui.dicomOutputButton, QtCore.SIGNAL('clicked()'), lambda :self.selectOutput('Dicom')) + self.connect(self.ui.niftiOutputButton, QtCore.SIGNAL('clicked()'), lambda :self.selectOutput('Nifti')) + # PACS tab + self.connect(self.ui.pacsSearchButton, QtCore.SIGNAL('clicked()'), self.searchPacs) + + self.connect(self.ui.dirPatientList, QtCore.SIGNAL('itemSelectionChanged()'), lambda :self.patientSelectionChanged('dir')) + self.connect(self.ui.pacsPatientList, QtCore.SIGNAL('itemSelectionChanged()'), lambda :self.patientSelectionChanged('pacs')) + self.connect(self.ui.dirStudiesList, QtCore.SIGNAL('itemSelectionChanged()'), lambda :self.studiesSelectionChanged('dir')) + self.connect(self.ui.pacsStudiesList, QtCore.SIGNAL('itemSelectionChanged()'), lambda :self.studiesSelectionChanged('pacs')) + self.connect(self.ui.chooseNiftiButton, QtCore.SIGNAL('clicked()'), self.chooseNifti) + self.connect(self.ui.pacsImportButton, QtCore.SIGNAL('clicked()'), self.downloadPacs) + # Import to BrainVisa for DICOM/NIFTI/PACS + #NIFTI + self.connect(self.ui.niftiImportButton, QtCore.SIGNAL('clicked()'), self.importNifti) + self.connect(self.ui.niftiSetBraincenterButton, QtCore.SIGNAL('clicked()'), self.setBrainCenter) + self.connect(self.ui.ImportFSoutputspushButton, QtCore.SIGNAL('clicked()'),self.importFSoutput) + #PACS + self.connect(self.ui.pacsImportBVButton, QtCore.SIGNAL('clicked()'), self.importPacs) + #DICOM + self.connect(self.ui.dirImportBVButton, QtCore.SIGNAL('clicked()'), self.importDir) + # NIFTI + self.connect(self.ui.niftiProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.niftiSubjectCombo)) + self.connect(self.ui.niftiSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.niftiSeqType, QtCore.SIGNAL('currentIndexChanged(QString)'),self.enable_disable_gadooption) + # Registration tab + self.connect(self.ui.regProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.regSubjectCombo)) + self.connect(self.ui.regSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectRegSubject) + self.connect(self.ui.regSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.regImageList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'), self.selectRegImage) + self.connect(self.ui.regImageList2, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'), self.selectRegImage2) + self.connect(self.ui.registerNormalizeSubjectButton, QtCore.SIGNAL('clicked()'), self.registerNormalizeSubject) + self.connect(self.ui.segmentationHIPHOPbutton,QtCore.SIGNAL('clicked()'),self.segmentationHIPHOP) + self.connect(self.ui.FreeSurferReconAllpushButton,QtCore.SIGNAL('clicked()'),self.runFreesurferReconAll) + self.connect(self.ui.runMarsAtlasFreesurferButton,QtCore.SIGNAL('clicked()'),self.runMarsAtlasFreesurfer) + + self.warningMEDIC() + + def setDictValue(d, k, v,button): + d[k]=v + button.setStyleSheet("background-color: rgb(90, 255, 95);") + self.connect(self.ui.regAcButton, QtCore.SIGNAL('clicked()'), lambda:setDictValue(self.AcPc,'AC',list(self.a.linkCursorLastClickedPosition()),self.ui.regAcButton)) + self.connect(self.ui.regPcButton, QtCore.SIGNAL('clicked()'), lambda:setDictValue(self.AcPc,'PC',list(self.a.linkCursorLastClickedPosition()),self.ui.regPcButton)) + self.connect(self.ui.regIhButton, QtCore.SIGNAL('clicked()'), lambda:setDictValue(self.AcPc,'IH',list(self.a.linkCursorLastClickedPosition()),self.ui.regIhButton)) + self.connect(self.ui.regLhButton, QtCore.SIGNAL('clicked()'), lambda:setDictValue(self.AcPc,'LH',list(self.a.linkCursorLastClickedPosition()),self.ui.regLhButton)) + self.connect(self.ui.regAcPcValidateButton, QtCore.SIGNAL('clicked()'), self.validateAcPc) + # Implantation tab (surgery drawings) + self.connect(self.ui.implProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.implSubjectCombo)) + self.connect(self.ui.implSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectImplSubject) + self.connect(self.ui.implSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.implCoroOpenButton, QtCore.SIGNAL('clicked()'), self.openImplCoro) + self.connect(self.ui.implCoroImportButton, QtCore.SIGNAL('clicked()'), self.importImplCoro) + self.connect(self.ui.implSagOpenButton, QtCore.SIGNAL('clicked()'), self.openImplSag) + self.connect(self.ui.implSagImportButton, QtCore.SIGNAL('clicked()'), self.importImplSag) + self.connect(self.ui.implPptOpenButton, QtCore.SIGNAL('clicked()'), self.openImplPpt) + self.connect(self.ui.implPptImportButton, QtCore.SIGNAL('clicked()'), self.importImplPpt) + self.connect(self.ui.implPdfOpenButton, QtCore.SIGNAL('clicked()'), self.openImplPdf) + self.connect(self.ui.implPdfImportButton, QtCore.SIGNAL('clicked()'), self.importImplPdf) + self.connect(self.ui.implPdfOpenButton2, QtCore.SIGNAL('clicked()'), self.openImplPdf2) + self.connect(self.ui.implPdfImportButton2, QtCore.SIGNAL('clicked()'), self.importImplPdf2) + self.connect(self.ui.implElListPdfOpenButton, QtCore.SIGNAL('clicked()'), self.openImplElListPdf) + self.connect(self.ui.implElListPdfImportButton, QtCore.SIGNAL('clicked()'), self.importImplElListPdf) + # Infos patient tab + self.connect(self.ui.patProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.patSubjectCombo)) + #self._pathologyinfo = lambda :pathologypatientinfo.buildUI() + self.connect(self.ui.patProtocolCombo, QtCore.SIGNAL('activated(QString)'),lambda :pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol)) #lambda :pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol)) self._pathologyinfo(self.ui.patpatGroupBox,self.currentProtocol) + self.connect(self.ui.patSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectPatSubject) + self.connect(self.ui.patSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.patInfoValidate,QtCore.SIGNAL('clicked()'),self.ValidatePatInfo) + + # Importation SEEG tab + self.connect(self.ui.seegProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.seegSubjectCombo)) + self.connect(self.ui.seegSubjectCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.selectSeegSubject) + self.connect(self.ui.seegSubjectCombo, QtCore.SIGNAL('activated(QString)'), self.setCurrentSubject) + self.connect(self.ui.seegManipsBaseCombo, QtCore.SIGNAL('activated(QString)'), self.manipSelected) + self.connect(self.ui.chooseSeegButton, QtCore.SIGNAL('clicked()'), self.chooseSeeg) + self.connect(self.ui.seegImportButton, QtCore.SIGNAL('clicked()'), self.seegImport) + + #Preference tab + self.connect(self.ui.prefSpmTemplateButton, QtCore.SIGNAL('clicked()'), self.setSpmTemplatePath) + self.connect(self.ui.prefANTsButton, QtCore.SIGNAL('clicked()'), self.setANTsPath) + self.connect(self.ui.prefSpmStandaloneButton, QtCore.SIGNAL('clicked()'), self.setSpmStandalonePath) + self.connect(self.ui.prefFreesurferButton, QtCore.SIGNAL('clicked()'), self.setFreesurferPath) + self.connect(self.ui.prefNoDBFileLocationButton, QtCore.SIGNAL('clicked()'),self.setNoDBFilePath) + self.connect(self.ui.prefANTScheckbox, QtCore.SIGNAL('clicked()'), lambda: self.setPrefCoregister('ANTS')) + self.connect(self.ui.prefSPMcheckbox, QtCore.SIGNAL('clicked()'), lambda: self.setPrefCoregister('SPM')) + self.connect(self.ui.prefAimscheckbox, QtCore.SIGNAL('clicked()'), lambda: self.setPrefCoregister('Aims')) + self.ui.radioButtonProject_4.toggled.connect(self.switchProjectButton) + self.ui.radioButtonProject_3.toggled.connect(self.switchProjectButton) + self.ui.radioButtonProject_2.toggled.connect(self.switchProjectButton) + self.ui.radioButtonProject.toggled.connect(self.switchProjectButton) + self.ui.radioButtonProject_4.toggled.connect(self.updatePatientCode) + self.ui.radioButtonProject_3.toggled.connect(self.updatePatientCode) + self.ui.radioButtonProject_2.toggled.connect(self.updatePatientCode) + self.ui.radioButtonProject.toggled.connect(self.updatePatientCode) + self.ui.SavePreferencespushButton.clicked.connect(self.savePreferences) + + #self.connect(self.ui.radioButtonProject_3, QtCore.SIGNAL('clicked()'), lambda: self.switchProjectButton) + #self.connect(self.ui.radioButtonProject_2, QtCore.SIGNAL('clicked()'), lambda: self.switchProjectButton) + #self.connect(self.ui.radioButtonProject, QtCore.SIGNAL('clicked()'), lambda: self.switchProjectButton) + #self.connect(self.ui.radioButtonProject_3, QtCore.SIGNAL('clicked()'), lambda: self.updatePatientCode) + #self.connect(self.ui.radioButtonProject_2, QtCore.SIGNAL('clicked()'), lambda: self.updatePatientCode) + #self.connect(self.ui.radioButtonProject, QtCore.SIGNAL('clicked()'), lambda: self.updatePatientCode) + + # Finds the available protocols in brainvisa database and fills the comboboxes + self.analyseBrainvisaDB() + self.setGuide("Choose on of the tabs to import data in the BrainVisa database") + self.enableACPCButtons(False) + # Disable work-in-progress tabs + #self.ui.tabWidget.setTabEnabled(6, False) + self.ui.tabWidget.setTabEnabled(7, False) + self.ui.tabWidget.setTabEnabled(8, False) + self.ui.tabWidget.setTabEnabled(9, False) + + + + def __del__ (self): + self.ui = None + + def closeEvent(self, event): + QtGui.QFrame.closeEvent(self, event) + self.savePreferences() + # Kill all processes that may still be running (stuck) or better, wait for them to complete + maxTimeToCompletion = 1000*60*20 # 20min in ms -> maximum duration for any thread (it will be killed after that) + qthr = [t for t in self.threads if isinstance(t, QtCore.QThread)] + thr = [t for t in self.threads if not isinstance(t, QtCore.QThread)] + print "Closing all qthreads" + unfinished = [t for t in qthr if not t.wait(maxTimeToCompletion)] + print "Killing %i QThreads still running"%len(unfinished) + [t.terminate() for t in unfinished] + def checkKill(p, timeout): + """ This function checks if the thread is still running. + If so, it waits until timeout (in ms), then kills it if it is still running""" + try: + print "Trying to kill "+repr(p) + t = 0 + while(p.poll() is None and t < timeout): + time.sleep(5) + t = t + 5000 + if p.poll() is None: + p.kill() + except: + pass + + print "Closing all threads" + finished = [checkKill(t, maxTimeToCompletion) for t in thr] + print "Quitting BrainVisa" + axon.processes.cleanup() + print "Quit !" + QtGui.qApp.quit() + + def initialize(self): + """Reads the preference file, checks the available patients and sequences""" + #Localisation du fichier de preference + prefpath = os.path.join(os.path.expanduser('~'), '.imageimport') + + # Chargement du fichier et stockage dans self.prefs + # Basic prefs + self.prefs = {'dicomOutputPath':os.path.join(os.path.expanduser('~'), 'dicomOut'),'niftiOutputPath':os.path.join(os.path.expanduser('~'), 'niftiOut'), 'sites':['Gre',]} + try: + if (os.path.exists(prefpath)): + filein = open(prefpath, 'rb') + #self.prefs = pickle.load(filein) + #fout.write(json.dumps({'mars_atlas':resection_mars_atlas_info})) + try: + self.prefs = json.loads(filein.read()) + except: + filein.close() + filein = open(prefpath, 'rb') + self.prefs = pickle.load(filein) + + filein.close() + except: + pass + + self.dicomOutputPath = self.prefs['dicomOutputPath'] + self.niftiOutputPath = self.prefs['niftiOutputPath'] + + if 'currentProtocol' in self.prefs: + self.currentProtocol = self.prefs['currentProtocol'] + if 'currentSubject' in self.prefs: + self.currentSubject = self.prefs['currentSubject'] + # Grenoble/Lyon/Other sites... + if 'sites' in self.prefs: + self.ui.subjectSiteCombo.clear() + self.ui.subjectSiteCombo.addItems(self.prefs['sites']) + + #check what spm path has been precised in BrainVisa + configuration = Application().configuration + brainvisa_spm12_path = configuration.SPM.spm12_path + brainvisa_spm12_standalone_path = configuration.SPM.spm12_standalone_path + brainvisa_freesurfer_home_path = configuration.freesurfer._freesurfer_home_path + + if 'spm' in self.prefs: + if brainvisa_spm12_path != self.prefs['spm']: + QtGui.QMessageBox.warning(self, u"SPM", u"SPM path different between IntrAnat and BrainVisa, strange, you should check that, by default keep the one precised in IntrAnat") + if os.path.isfile(self.prefs['spm']+os.sep+'Contents.m'): + op_cont = open(self.prefs['spm']+os.sep+'Contents.m') + line = op_cont.readline() + line = op_cont.readline() + spm_version = line.split(' ')[3] + if spm_version == '(SPM12)': + self.setSpmTemplatePath(self.prefs['spm']) #+os.sep+'toolbox/OldNorm/T1.nii') + elif spm_version == '(SPM8)': + QtGui.QMessageBox.warning(self, u"SPM", u"SPM version not supported anymore") + #self.setSpmTemplatePath(self.prefs['spm']) #+os.sep+'templates/T1.nii') + else: + QtGui.QMessageBox.warning(self, u"SPM", u"SPM version unknown") + else: + QtGui.QMessageBox.warning(self, u"SPM", u"SPM path is not defined in tab 'Préférences'\n Normalization and SPM coregistration won't work !") + else: + if len(configuration.SPM.spm12_path)>0: + print("used brainvisa spm path") + self.setSpmTemplatePath(brainvisa_spm12_path) + self.prefs['spm']=brainvisa_spm12_path + else: + QtGui.QMessageBox.warning(self, u"SPM", u"SPM path is not defined (or wrong) in tab 'Préférences'\n Normalization and SPM coregistration won't work !") + + if 'spm_standalone' in self.prefs: + if brainvisa_spm12_standalone_path != self.prefs['spm_standalone']: + QtGui.QMessageBox.warning(self, u"SPM standalone", u"SPM standalone path different between IntrAnat and BrainVisa, strange, you should check that, by default keep the one precised in IntrAnat") + self.setSpmStandalonePath(self.prefs['spm_standalone']) + else: + self.setSpmStandalonePath(brainvisa_spm12_standalone_path) + + if 'freesurfer' in self.prefs: + if brainvisa_freesurfer_home_path != self.prefs['freesurfer']: + QtGui.QMessageBox.warning(self, u"Freesurfer", u"Freesurfer path different between IntrAnat and BrainVisa, strange, you should check that, by default keep the one precised in IntrAnat") + self.setFreesurferPath(self.prefs['freesurfer']) + else: + self.setFreesurferPath(brainvisa_freesurfer_home_path) + + if 'FileNoDBPath' in self.prefs: + self.setNoDBFilePath(self.prefs['FileNoDBPath']) + + + #self.prefs['freesurfer'] = str(self.ui.prefFreesurferEdit.text()) + + if 'ants' in self.prefs: + self.setANTsPath(self.prefs['ants']) + + if 'coregisterMethod' in self.prefs: + self.coregMethod = self.prefs['coregisterMethod'] + + if self.coregMethod == 'ANTs': + self.ui.prefSPMcheckbox.setCheckState(False) + self.ui.prefANTScheckbox.setCheckState(True) + self.ui.prefAimscheckbox.setCheckState(False) + if self.coregMethod == 'spm': + self.ui.prefSPMcheckbox.setCheckState(True) + self.ui.prefANTScheckbox.setCheckState(False) + self.ui.prefAimscheckbox.setCheckState(False) + if self.coregMethod == 'Aims': + self.ui.prefSPMcheckbox.setCheckState(False) + self.ui.prefANTScheckbox.setCheckState(False) + self.ui.prefAimscheckbox.setCheckState(True) + + if 'projectSelected' in self.prefs: + if self.prefs['projectSelected'] != []: + projects= [self.ui.radioButtonProject,self.ui.radioButtonProject_2,self.ui.radioButtonProject_3,self.ui.radioButtonProject_4] + projects[self.prefs['projectSelected'][0]].setChecked(True) + + + + # Test if matlab is available + if 'matlabOk' not in self.prefs or self.prefs['matlabOk'] == False: + if matlabIsPresent(): + self.prefs['matlabOk'] = True + else: + QtGui.QMessageBox.warning(self, u"Matlab", u"The command 'matlab' doesn't work !\nSPM coregistration and normalization won't work") + self.prefs['matlabOk'] = False + # Scanner les dossiers et séquences déjà importées, en faire un dictionnaire : + self.dicomOutContent = self.analyzeDicomOutput(self.dicomOutputPath) + self.niftiOutContent = self.analyzeNiftiOutput(self.niftiOutputPath) + + def warningMEDIC(self): + + shortwarning = TimerMessageBox(5,self) + shortwarning.exec_() + + + def savePreferences(self): + + prefpath = os.path.join(os.path.expanduser('~'), '.imageimport') + + self.prefs['dicomOutputPath'] = self.dicomOutputPath + self.prefs['niftiOutputPath'] = self.niftiOutputPath + self.prefs['currentProtocol'] = self.currentProtocol + self.prefs['currentSubject'] = self.currentSubject + self.prefs['sites'] = [str(self.ui.subjectSiteCombo.itemText(item)) for item in range(self.ui.subjectSiteCombo.count())] + if len(str(self.ui.prefSpmTemplateEdit.text()))>0: + self.prefs['spm'] = str(self.ui.prefSpmTemplateEdit.text()) + else: + self.prefs.pop('spm',None) + if len(str(self.ui.prefANTsEdit.text()))>0: + self.prefs['ants']=str(self.ui.prefANTsEdit.text()) + else: + self.prefs.pop('ants',None) + if len(str(self.ui.prefSpmStandaloneEdit.text()))>0: + self.prefs['spm_standalone'] = str(self.ui.prefSpmStandaloneEdit.text()) + else: + self.prefs.pop('spm_standalone',None) + if len(str(self.ui.prefFreesurferEdit.text()))>0: + self.prefs['freesurfer'] = str(self.ui.prefFreesurferEdit.text()) + else: + self.prefs.pop('freesurfer',None) + + if len(str(self.ui.prefNoDBFileLocationEdit.text()))>0: + self.prefs['FileNoDBPath'] = str(self.ui.prefNoDBFileLocationEdit.text()) + else: + self.prefs.pop('FileNoDBPath',None) + + if self.ui.prefANTScheckbox.isChecked(): + self.prefs['coregisterMethod'] = 'ANTs' + elif self.ui.prefSPMcheckbox.isChecked(): + self.prefs['coregisterMethod'] = 'spm' + elif self.ui.prefAimscheckbox.isChecked(): + self.prefs['coregisterMethod'] = 'Aims' + else: + self.prefs['coregisterMethod'] = 'spm' + + self.coregMethod = self.prefs['coregisterMethod'] + + projects= [self.ui.radioButtonProject.isChecked(),self.ui.radioButtonProject_2.isChecked(),self.ui.radioButtonProject_3.isChecked(),self.ui.radioButtonProject_4.isChecked()] + project_selected = [x for x in range(len(projects)) if projects[x]==True] + + self.prefs['projectSelected'] = project_selected + + fileout = open(prefpath, 'wb') + + pickle.dump(self.prefs, fileout) + #to modify to json + + fileout.close() + + def createItemDirs(self, item): + """ Create the directories containing the provided WriteDiskItem and insert them in the BrainVisa database """ + # Copied from brainvisa.processes, in ExecutionContext._processExecution() + dirname = os.path.dirname( item.fullPath() ) + dir=dirname + dirs = [] + while not os.path.exists( dir ): + dirs.append(dir) + dir=os.path.dirname(dir) + if dirs: + try: + os.makedirs( dirname ) + except OSError, e: + if not e.errno == errno.EEXIST: + # filter out 'File exists' exception, if the same dir has + # been created concurrently by another instance of BrainVisa + # or another thread + raise + for d in dirs: + dirItem=neuroHierarchy.databases.createDiskItemFromFileName(d, None) + + + def analyzeDicomOutput(self, root): + """ Structure of the dicom output directory is supposed to be + root/patient/sequence/dicomfiles. + This returns the dictionary of patients and sequences already imported in there""" + if not os.path.isdir(root): + return {} + return dict([(f, os.listdir(os.path.join(root, f))) for f in os.listdir(root) if os.path.isdir(os.path.join(root, f))]) + + def analyzeNiftiOutput(self, root): + """ Structure of the nifti output directory is supposed to be + root/patient/sequence.nii. + This returns the dictionary of patients and sequences already imported in there""" + if not os.path.isdir(root): + return {} + return dict([(f, [seq.split('.nii')[0] for seq in os.listdir(os.path.join(root, f))]) for f in os.listdir(root) if os.path.isdir(os.path.join(root, f))]) + + def storeImageReferentialsAndTransforms(self, image): + """Stores referential and transformation files for an image from its headers -> native, scanner-based, coregistered to""" + + # Notes : on prend le header de l'image, on crée un objet referentiel pour le référentiel natif, + # puis un pour chaque transformation définie dans le header + # On stocke les transfos entre le natif et chacun de ces référentiels à partir des infos du header. + # Comment alors faire pour lier le 'coregistered to blabla' au 'scanner based' d'une autre image ? Stocker une transfo identité ou utiliser copyReferential ? + # Et est-ce que copyReferential met à jour toutes les transfos stockées qui utilisaient le référentiel écrasé ? + # D'autre part, comment repérer le référentiel Scanner-based d'une image en particulier ? Pour créer la transfo t1post vers t1pre à partir du recalage SPM... + + + att = image.attributes() + refName = att['modality']+'_'+att['acquisition'] + print "Storing refs/transfos for "+str(refName) + + # Create a Referential object in the database to represent the native referential of the image + moda = self.modas[att['modality']] + nativeRef = self.transfoManager.referential(image) + if nativeRef is None: + print '...Creating native ref' + nativeRef = self.transfoManager.createNewReferentialFor(image, name = refName+'native', description = 'Native Anatomist Referential for ' + refName + ' image', referentialType='Referential of '+moda) + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( nativeRef.fullPath() )) + except: + pass + + # Create the scanner-based referential + #wdiScan = WriteDiskItem( 'Scanner Based Referential', 'Referential', exactType=True ) + #refScan = wdiScan.findValue( image ) + refScan = self.transfoManager.findOrCreateReferential('Scanner Based Referential', image, name = refName+'_Scanner-Based', description = 'Scanner-Based referential for ' + refName + ' image') + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( refScan.fullPath() )) + except: + pass + + if refScan is None: + print '...Creating scanner-based ref' + refScan = self.transfoManager.createNewReferentialFor(wdiScan, name = refName+'_Scanner-Based', description = 'Scanner-Based referential for ' + refName + ' image', referentialType='Scanner Based Referential') + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( refScan.fullPath() )) + except: + pass + + # Find where to store the scanner-base transformation + wdiTransformScan = WriteDiskItem( 'Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True ) + transformScan = wdiTransformScan.findValue(image) + + # Read the header of the image and read all transformations available + f = aims.Finder() + f.check(image.fileName()) + trs = list(f.header()['transformations']) + refs = list(f.header()['referentials']) + #print "ATTRIBUTES : "+repr(att) + trm_to_scannerBased = None + + if ("Scanner-based anatomical coordinates" in refs ): + + trm_to_scannerBased = trs[refs.index("Scanner-based anatomical coordinates")] + + if trm_to_scannerBased is None: + print "No Scanner-based transfo in image header, using first available transfo instead." + try: + trm_to_scannerBased = trs[0] + except: + pass + + if transformScan is None: + print "Cannot find path for Scanner-based transform in database -> transformation not stored !" + elif trm_to_scannerBased is None: + print "Cannot find Scanner-based transformation in header !" + else: + print '...storing scanner-based transfo' + #Store information into the trm file + mot = aims.Motion( trm_to_scannerBased ) + image.setMinf('SB_Transform',str(trm_to_scannerBased)) + aims.write( mot, transformScan.fullPath() ) + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( transformScan.fullPath() )) + except: + pass + #set and update database + print ".... setting transfo info : from %s to %s for %s"%(repr(nativeRef), repr(refScan), repr(transformScan)) + self.transfoManager.setNewTransformationInfo( transformScan, source_referential=nativeRef, destination_referential= refScan) + + + def analyseBrainvisaDB(self, tab=None): + """ Analyze the BrainVisa Database to fill the data for the brainvisa and registration tab (provide the tab number to update only the chosen one, 0 or 4) """ + rdi = ReadDiskItem( 'Center', 'Directory' )#, requiredAttributes={'center':'Epilepsy'} ) + protocols = list( rdi._findValues( {}, None, False ) ) + protocols = sorted([str(p.attributes()['center']) for p in protocols]) + if len(protocols) == 0: + rep = QtGui.QMessageBox.warning(self, "Center (former protocol)", u"No center/protocole defined in BrainVisa Database !") + text, ok = QtGui.QInputDialog.getText(self, 'Input Dialog', 'Enter the name of the center/protocole:') + + if (ok & bool(text)): + wdi = WriteDiskItem('Center', 'Directory' ) #'gz compressed NIFTI-1 image' ) + di = wdi.findValue({'center' : str(text)}) + os.mkdir(di.fullPath()) + neuroHierarchy.databases.insertDiskItem( di, update=True ) + + if self.currentProtocol in protocols: + currentIndex = protocols.index(self.currentProtocol) + else: + currentIndex = 0 + + def selectSubj(subjCombo): + " Subfunction to select the current subject " + if self.currentSubject is None: + return + idx = subjCombo.findText(self.currentSubject) + print "search current subj" + if idx != -1: + print "found at "+repr(idx) + subjCombo.setCurrentIndex(idx) + + if tab == 0 or tab is None: # Tab 0 is BrainVisa database tab + self.ui.bvProtocolCombo.clear() + self.ui.bvProtocolCombo.addItems(protocols) + self.ui.bvProtocolCombo.setCurrentIndex(currentIndex) + selectSubj(self.ui.bvSubjectCombo) + if tab == 1 or tab is None: # Tab 1 is Create Subject tab + self.ui.subjectProtocolCombo.clear() + self.ui.subjectProtocolCombo.addItems(protocols) + self.ui.subjectProtocolCombo.setCurrentIndex(currentIndex) + if tab == 3 or tab is None: # Tab 3 is Import Nifti tab + self.ui.niftiProtocolCombo.clear() + self.ui.niftiProtocolCombo.addItems(protocols) + self.ui.niftiProtocolCombo.setCurrentIndex(currentIndex) + selectSubj(self.ui.niftiSubjectCombo) + if tab == 7 or tab is None: # Tab 7 is Implantation tab + self.ui.implProtocolCombo.clear() + self.ui.implProtocolCombo.addItems(protocols) + self.ui.implProtocolCombo.setCurrentIndex(currentIndex) + selectSubj(self.ui.implSubjectCombo) + if tab == 4 or tab is None: # Tab 4 is Registration tab + self.ui.regProtocolCombo.clear() + self.ui.regProtocolCombo.addItems(protocols) + self.ui.regProtocolCombo.setCurrentIndex(currentIndex) + selectSubj(self.ui.regSubjectCombo) + if tab == 2 or tab is None: # Tab 2 is Patient Information tab + #pdb.set_trace() + #self.ui.patProtocolCombo.currentIndexChanged.disconnect(self._pathologyinfo) + self.ui.patProtocolCombo.clear() + self.ui.patProtocolCombo.addItems(protocols) + #self.connect(self.ui.patProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s:self.selectProtocol(s,self.ui.patSubjectCombo)) + #self._pathologyinfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + #self.connect(self.ui.patProtocolCombo, QtCore.SIGNAL('currentIndexChanged(QString)'),self._pathologyinfo) #lambda :pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol)) + self.ui.patProtocolCombo.setCurrentIndex(currentIndex) + self.pathologypatientInfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + selectSubj(self.ui.patSubjectCombo) + #pdb.set_trace() + #self.pathologypatientInfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + if tab == 6 or tab is None: # Tab 6 is SEEG tab + self.ui.seegProtocolCombo.clear() + self.ui.seegProtocolCombo.addItems(protocols) + self.ui.seegProtocolCombo.setCurrentIndex (currentIndex) + selectSubj(self.ui.seegSubjectCombo) + + + def selectProtocol(self, proto, comboToFillWithSubjects): + """ A BrainVisa protocol was selected : query the database to get the list of subjects and put them in the provided QComboBox""" + self.currentProtocol = str(proto) + rdi = ReadDiskItem( 'Subject', 'Directory', requiredAttributes={'center':str(proto)} ) + subjects = list( rdi._findValues( {}, None, False ) ) + comboToFillWithSubjects.clear()#self.ui.bvSubjectCombo.clear() + comboToFillWithSubjects.addItems(sorted([s.attributes()['subject'] for s in subjects])) + + #if self.ui.tabWidget.currentIndex() ==2: + # self.pathologypatientInfo = pathologypatientinfo.buildUI(self.ui.patpatGroupBox,self.currentProtocol) + + def setCurrentSubject(self, subj): + if not subj: # ignore empty values + return + print "current subj : "+str(subj) + self.currentSubject = str(subj) + + + def findAllImagesForSubject(self, protocol, subj): + """ Returns all images for a subject from the brainvisa database. + @return an array of ReadDiskItem + """ + rdi = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images = list( rdi._findValues( {}, None, False ) ) + images = [x for x in images if "skull_stripped" not in x.fullName()] + rdi = ReadDiskItem( 'T2 MRI', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'CT', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'PET', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'fMRI-epile', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'Statistic-Data', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'FLAIR', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'FreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'FGATIR', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + rdi = ReadDiskItem( 'HippoFreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + images += list( rdi._findValues( {}, None, False ) ) + + return images + + def selectBvSubject(self, subj): + """ A BrainVisa subject was selected : query the database to get the list of images""" + # Display "Date : XXXX-XX-XX - Seq: T1 - Acq : T1Pre + self.ui.bvImageList.clear() + images = self.findAllImagesForSubject(self.ui.bvProtocolCombo.currentText(), subj) + #name = modality + acquisition + subacquisition if exist subacquisition key else modality + acquisition + self.ui.bvImageList.addItems(sorted([i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition'] if 'subacquisition' in i.attributes().keys()\ + #i.attributes()['modality'] if 'acquisition' not in i.attributes().keys()\ + else i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] for i in images ])) + + dict_temporaire = {} + for i in images: + if 'subacquisition' in i.attributes().keys(): + dict_temporaire.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition']:i.fileName()}) + else: + dict_temporaire.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition']:i.fileName()}) + #self.bvImagePaths = dict((i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition'], i.fileName() if 'subacquisition' in i.attributes().keys()\ + #else i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'], i.fileName() for i in images)) + self.bvImagePaths = dict_temporaire + + + def selectBvImage(self, item): + """ A BrainVisa image was double-clicked : display it !""" + self.clearAnatomist() + path = self.bvImagePaths[str(item.text())] + mri = self.a.loadObject(path) + self.a.addObjects(mri, self.wins) + self.dispObj.append(mri) + + def removeFromDB(self, file, db=None): + """ + If the file is a directory, recursive call to remove all its content before removing the directory. + Corresponding diskitem is removed from the database if it exists. + Taken from brainvisa-4.3.0/python/brainvisa/data/qt4gui/hierarchyBrowser.py + """ + if db is None: + try: + db=neuroHierarchy.databases.database(neuroHierarchy.databases.getDiskItemFromFileName(file).get("_database")) + except: + pass + + if os.path.isdir(file): + for f in os.listdir(file): + self.removeFromDB(os.path.join(file, f), db) + os.rmdir(file) + else: + os.remove(file) + if db: + diskItem=db.getDiskItemFromFileName(file, None) + if diskItem: + db.removeDiskItem(diskItem) + + def deleteBvSubject(self): + protocol = str(self.ui.bvProtocolCombo.currentText()) + subj = str(self.ui.bvSubjectCombo.currentText()) + rep = QtGui.QMessageBox.warning(self, u'Confirmation', u"ATTENTION
you are gonna Erase ALL subject datas
DELETE THE SUBJECT%s ?
"%subj, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if rep == QtGui.QMessageBox.Yes: + print "Deleting subject %s"%subj + rdi = ReadDiskItem( 'Subject', 'Directory', requiredAttributes={'center':str(protocol), 'subject':str(subj) } ) + di = list( rdi._findValues( {}, None, False ) ) + if len(di) != 1: + print "%s subject(s) found ! Cannot delete if there is more than 1 !"%repr(len(di)) + return + self.removeFromDB(di[0].fullPath(), neuroHierarchy.databases.database(di[0].get("_database"))) + self.setStatus(u"Subject %s deleted from the database"%subj) + # Reset the list of subjects : + self.selectProtocol(str(self.ui.bvProtocolCombo.currentText()),self.ui.bvSubjectCombo) + + + def deleteBvImage(self): + #Delete the current acquisition (including transforms and segmentations : the full acquisition directory + imageName = None + try: + imageName = str(self.ui.bvImageList.currentItem().text()) + except: # Probably no image available or no image selected + return + rep = QtGui.QMessageBox.warning(self, u'Confirmation', u"ATTENTION
You are gonna delete the selected image and all linked data
DELETE THE IMAGE%s ?
"%imageName, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if rep == QtGui.QMessageBox.Yes: + + path = self.bvImagePaths[imageName] # Gives the path of the image + di = neuroHierarchy.databases.getDiskItemFromFileName(path) + acqPath = os.path.dirname(path) + if str(os.path.basename(acqPath)) != str(di.attributes()['acquisition']): + print "CANNOT REMOVE IMAGE : acquisition path does not match acquisition name !" + return + + if "subacquisition" in di.attributes().keys(): + self.removeDiskItems(di,eraseFiles=True) + else: + self.removeFromDB(acqPath) + self.setStatus(u"Image %s deleted from the database"%imageName) + self.selectBvSubject(str(self.ui.bvSubjectCombo.currentText())) + + + def clearAnatomist(self, windows=None): + """ If "windows" is provided, just empties the provided windows. + If not, all loaded objects are closed and all windows are emptied """ + if windows is not None: + self.a.removeObjects(self.a.getObjects(), windows) + return + self.dispObj = [] + self.a.removeObjects(self.a.getObjects(), self.wins) + self.a.deleteObjects(self.a.getObjects()) + + def displayAnatomist(self, win1Path=None, win2Path=None): + self.clearAnatomist() + if win1Path: + im1 = self.a.loadObject(win1Path) + self.a.addObjects(im1, self.wins[0]) + self.dispObj.append(win1Path) + if win2Path: + im2 = self.a.loadObject(win2Path) + self.a.addObjects(im2, self.wins[1]) + self.dispObj.append(win2Path) + + def setStatus(self, text): + """ Sets the status text displayed at the bottom of the dialog""" + self.ui.statusCombo.insertItem(0,QtCore.QTime.currentTime().toString("H:m:s") + ': ' + text) + self.ui.statusCombo.setCurrentIndex(0) + + def setGuide(self, text): + """ Set the text of the User Guide on the top of the window""" + self.ui.guideLabel.setText(text) + + def setTabGuide(self, tabId): + helpTab = [u'Look for images in BrainVisa database. Double click to load an images in anatomist windows on the side',\ + u'Add a new patient in the Database (perform an anonymization as well)',\ + u'Precise patient information (general and pathology specific)',\ + u'Import images (format: Nifti/GIS/Analyse/(mgz in some case). Select the file and fill information needed',\ + u'Coregister all images to the 3DT1 before electrode implantation. Normalize this 3DTI to the MNI, perform grey/white matter segmentation, mesh of the cortex, and MarsAtlas parcellation',\ + u'Set software preferences',\ + u'Import SEEG data' ,\ + u'Importez des images depuis un dossier DICOM : Sélectionnez une image, importez et convertissez en Nifti, puis importez-là dans la base',\ + u'Importez des images depuis un PACS. Sélectionnez une image, importez et convertissez en Nifti, puis importez-là dans la base',\ + u'Importez les schémas d\'implantation scannés',\ + ] + self.setGuide(helpTab[tabId]) + + def patientSelectionChanged(self, t): + """ Update the studies selected when the patient selection changes. t is the list, 'pacs' or 'dir' in the UI""" + + print 'patientSelectionChanged('+t+')' + list = None + if t == 'pacs': + list = self.ui.pacsPatientList + out = self.ui.pacsStudiesList + studies = self.pacsStudies + elif t == 'dir': + list = self.ui.dirPatientList + out = self.ui.dirStudiesList + studies = self.dirStudies + + # Unselect all studies + for s in out.selectedItems(): + out.setItemSelected(s, False) + + # Select all studies that match the selected patients + names = [str(p.text()) for p in list.selectedItems()] + outItems = [out.item(i) for i in xrange(out.count())] + for s in outItems: + if studies[self.studiesUIDbyName[str(s.text())]]['PatientsName'] in names: + out.setItemSelected(s, True) + + + def studiesSelectionChanged(self, t): + """ Update the series selected when the studies selection changes. t is the list, 'pacs' or 'dir' in the UI""" + list = None + if t == 'pacs': + list = self.ui.pacsStudiesList + out = self.ui.pacsSeriesList + series = self.pacsStudies + elif t == 'dir': + list = self.ui.dirStudiesList + out = self.ui.dirSeriesList + series = self.dirSeries + + # Unselect all studies + for s in out.selectedItems(): + out.setItemSelected(s, False) + + # Select all series that match the selected studies + names = [self.studiesUIDbyName[str(s.text())] for s in list.selectedItems()] + outItems = [out.item(i) for i in xrange(out.count())] + for s in outItems: + if series[self.seriesUIDbyName[str(s.text())]]['StudyInstanceUID'] in names: + out.setItemSelected(s, True) + + def selectOutput(self, t): + """ Select the output directories for t='Dicom' or t='Nifti' images""" + if t=='Dicom': + self.dicomOutputPath = str(QtGui.QFileDialog.getExistingDirectory(self, u"Choix d'un répertoire de sortie pour les fichiers DICOM",self.dicomOutputPath )) + self.ui.dicomOutputPathEdit.setText(self.dicomOutputPath) + elif t == 'Nifti': + self.niftiOutputPath = str(QtGui.QFileDialog.getExistingDirectory(self, u"Choix d'un répertoire de sortie pour les fichiers Nifti",self.niftiOutputPath )) + self.ui.niftiOutputPathEdit.setText(self.niftiOutputPath) + + def openDicomDir(self, direc=None, updateUI = True): + """Loads a DICOM directory (direc), organize the files and update the UI""" + if direc is None: + direc = QtGui.QFileDialog.getExistingDirectory(self, u"Choix d'un répertoire de fichiers DICOM")#,"/default/Path") + direc = str(direc) + if not os.path.exists(direc) or not os.path.isdir(direc): + print "OpenDicomDir : %s does not exist or is not a directory"%repr(direc) + return + files = os.listdir(direc) + files = [os.path.join(direc,f) for f in files if os.path.isfile(os.path.join(direc,f))] + self.setStatus('Chargement de '+str(len(files))+" fichiers DICOM...") + # Create executor object, connect the output function to it, then start it + organize = lambda :organizeDicomFiles(files, True) + thread = PythonExecutor(organize) + self.threads.append(thread) + self.connect(thread, QtCore.SIGNAL('dicomFilesOutput(PyQt_PyObject)'), lambda x: self.finishOpenDicomDir(updateUI, x)) + thread.start() + + def finishOpenDicomDir(self, updateUI, dicomFiles): + self.setStatus(u'Fichiers DICOM chargés') + print "dicomFiles ok" + if updateUI: + self.ui.dirSeriesList.clear() + self.ui.dirStudiesList.clear() + self.ui.dirPatientList.clear() + + series = getSeries(dicomFiles) + print "*** Found %d series"%len(series) + + self.dirSeries = series + #Afficher la liste des series + if updateUI: + self.seriesUIDbyName = dict((series[uid]['SeriesDate']+' '+series[uid]['SeriesTime']+' '+series[uid]['SeriesDescription'] , uid) for uid in series if 'SeriesTime' in series[uid] and 'SeriesDate' in series[uid] and 'SeriesDescription' in series[uid]) + self.ui.dirSeriesList.addItems(self.seriesUIDbyName.keys()) + self.ui.dirSeriesList.sortItems() + # Colorer les séries déjà importées: + try: + for i in xrange(self.ui.dirSeriesList.count()): + self.ui.dirSeriesList.item(i).setBackgroundColor(QColor.fromRgb(255,0,0)) + s = self.seriesUIDbyName[str(self.ui.dirSeriesList.item(i).text())] + if patientNameDecode(s['PatientsName']) in niftiOutContent: + if serie2filename(s) in niftiOutContent[patientNameDecode(s['PatientsName'])]: + self.ui.dirSeriesList.item(i).setBackgroundColor(QColor.fromRgb(0,255,0)) + except: + pass + + self.dirStudies = getStudies(dicomFiles) + studies = self.dirStudies + print "Studies : "+repr(studies) + #Afficher la liste des studies + if updateUI: + self.studiesUIDbyName = dict((studies[uid]['name'], uid) for uid in studies.keys()) + self.ui.dirStudiesList.addItems(self.studiesUIDbyName.keys()) + self.ui.dirStudiesList.sortItems() + + self.dirPatients = getPatients(series) + print "Patients : "+repr(studies) + if updateUI: + self.ui.dirPatientList.addItems(self.dirPatients) + self.ui.dirPatientList.sortItems() + + + ## DCMTK retrieve example : + # # get list of studies for patient "John Doe" + #findscu --study -k 0008,0052=STUDY -k 0010,0010="Doe^John" -k 0020,000D server 104 + #now get list of CT series within a certain study identified by a UID returned by the last call to findscu + #findscu --study -k 0008,0052=SERIES -k 0020,000D=1.2.276.1.2.3.4.5 -k 0008,0060=CT -k 0020,000E server 104 + #retrieve a series found by findscu. Note that we need to specify both Study and Series Instance UID. + #movescu --study -k 0008,0052=SERIES -k 0020,000D=1.2.276.1.2.3.4.5 -k 0020,000E=1.2.276.9.8.7.6.5 server 104 + def searchPacs(self): + """ Search the PACS for the patient Name provided""" + # Get the list of patients'names if the provided name is llong enough (2 chars minimum) + name = str(self.ui.patientSearchName.text())+'*' + name.rstrip()#replace(' ', '^') --> spaces are allowed inside names, ^separates first/last/middle names + # Remove wildcards to avoid large matches + name.replace('?', '') + name.replace('*', '') + server = str(self.ui.pacsServerEdit.text()) + port = str(self.ui.pacsPortSpin.value()) + # We want study mode, with tag 0008,0052 set to study, tag 0010,0010 matching the patient, and listing all 0020,000 (studies) + cmd = ['findscu','--study', '-k','0008,0052=STUDY', '-k' , '0010,0010="'+name+'"', '-k','0020,000D', server, port ] + + lines = runCmd(cmd) + print lines + # List of studies + studies = [] + # In all studies get the patient's name and add it to the list + patientsList = [] + + # Maximum number of patients : 10 + patientsList =patientsList[:10] + + # For each study that matches a patient from the list, get all series + for s in studies: + cmd = ['findscu','--study', '-k','0008,0052=SERIES', '-k' , '0010,0010="'+name+'"',\ + '-k', '0020,000D='+s, '-k', '0020,000E', server, port ] + lines = runCmd(cmd) + # Store the results + + + def importDataPacs(self): + """ Get the selected series from the pacs to a local directory and convert to Nifti """ + # Regarder la sélection patient et series + # importer avec findscu dans un répertoire temporaire + # getscu ou movescu + cmd = ['getscu', '--study', '-k', '0008,0052=SERIES', '-k', '0020,000D='+studyId, '-k', '0020,000E='+serieId, server, port] + # puis lancer self.openDicomDir(tmpDir) + + + def importDataDir(self): + # Find selected series + selectedSeries = dict((self.seriesUIDbyName [str(item.text())], self.dirSeries[self.seriesUIDbyName [str(item.text())]]) for item in self.ui.dirSeriesList.selectedItems()) + + # If nothing is selected + if not selectedSeries: + return + + # Copy the dicom series to a directory + copySeriesTo(selectedSeries, self.dicomOutputPath) + + # Convert to Nifti + th = convertSeriesToNifti(selectedSeries, self.niftiOutputPath) + self.threads.extend(th) + + print "Series importees : " + repr(selectedSeries.keys()) + # Regarder la sélection patient et series + # importer avec findscu dans un répertoire temporaire + # puis lancer copySeriesTo(series, dicomOutputPath) + + def chooseNifti(self): + self.ui.niftiFileLabel.setText('') + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open MRI Image", "", "Images (*.nii *.nii.gz *.ima *.img *.ima.gz *.img.gz *.img.bz2 *ima.bz2 *.nii.bz2 *.mgz)")) + if not path: + return + self.ui.niftiFileLabel.setText(path) + # Display the image and remove others + self.clearAnatomist() + print "Loading %s"%path + split_path = os.path.splitext(path) + if split_path[-1] == ".mgz": + try: + tmp_nii_path = "/tmp/tmp_mgz_nii.nii" + #on reslice par rapport au t1 pre + #pdb.set_trace() + di = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.currentSubject } ) + allT1 = list(di.findValues({},None,False)) + idxT1pre = [i for i in range(len(allT1)) if 'pre' in str(allT1[i])] + if len(idxT1pre)==0: + print "to import freesurfer images, the T1pre has to be imported because a reslicing is necessary" + return + + #mri_convert -rl /data/brainvisa/Epilepsy/Gre_2015_BESk/t1mri/T1pre_2015-1-1/Gre_2015_BESk.nii /home/b67-belledone/freesurfer/subjects/Gre_2015_BESk/mri/aparc.a2009s+aseg.mgz /home/b67-belledone/freesurfer/subjects/Gre_2015_BESk/mri/test.nii -rt nearest -ncD + #remplacer par launchFreesurferCommand + context = brainvisa.processes.defaultContext() + context.write("mri_convert from freesurfer") + + launchFreesurferCommand(context, None, 'mri_convert', '-i',path,'-o',tmp_nii_path,'-rl',str(allT1[idxT1pre[0]].fullPath()),'-rt','nearest','-nc') + #mriconvert_call ='mri_convert -i {} -o {} -rl {} -rt nearest -nc'.format(path,tmp_nii_path,str(allT1[idxT1pre[0]].fullPath())) + #mriconvert_call ='mri_convert -i {} -o {}'.format(path,tmp_nii_path) + #runCmd(mriconvert_call.split()) + mri = self.a.loadObject(tmp_nii_path) + except: + print "conversion mgz to nii didn't work" + return + else: + mri = self.a.loadObject(path) + + self.a.addObjects(mri, self.wins) + self.dispObj.append(mri) + + self.brainCenter = None + self.ui.brainCenterLabel.setText('') + self.ui.niftiFileLabel.setText(tmp_nii_path) + + def setBrainCenter(self): + brainCenterCoord = list(self.a.linkCursorLastClickedPosition()) + self.ui.brainCenterLabel.setText("%.1f, %.1f, %.1f"%tuple([float(x) for x in brainCenterCoord][:3])) + self.brainCenter = brainCenterCoord + + def importNifti(self, path = None, patient = None, proto=None, modality = None, acq = None): + """ Imports a Nifti file in the BrainVisa database. + path is the input image, patient is e.g. Dupont_Jean, acq is the acquisition name e.g. 'T1pre_2000-01-01' + If the parameters are empty, the data is taken from the Nifti Tab in the UI""" + + if self.brainCenter == None: + print "brain center not set" + QtGui.QMessageBox.warning(self, "Error",u"You haven't selected the BrainCenter !") + return + + if self.ui.acqDate.date() == self.defaultAcqDate: + QtGui.QMessageBox.warning(self, "Error",u"Acquisition date is not valid!") + return + if path is None: + path = str(self.ui.niftiFileLabel.text()) + if not path: + QtGui.QMessageBox.warning(self, "Error", u"Choose a file to import !") + return + filename = os.path.split(path)[1] + if patient is None: + patient = str(self.ui.niftiSubjectCombo.currentText()) + if proto is None: + proto = str(self.ui.niftiProtocolCombo.currentText()) + if acq is None: + d = self.ui.acqDate.date() + acq = str(self.ui.niftiSeqType.currentText() + self.ui.niftiAcqType.currentText() + '_'+str(d.year()) + '-' + str(d.month()) + '-' + str(d.day())) + if modality is None: + # Determines the BrainVisa file type (depends on the imaging modality) + modality = str(self.ui.niftiSeqType.currentText()) # T1 / T2 / CT / PET /fMRI + + filetype = {'T1':'Raw T1 MRI', 'T2':'T2 MRI', 'CT':'CT', 'TEP':'PET', 'PET':'PET', 'fMRI':'fMRI-epile', 'Statistics':'Statistic-Data', 'FLAIR':'FLAIR', 'FreesurferAtlas':'FreesurferAtlas', 'FGATIR':'FGATIR','HippoFreesurferAtlas':'HippoFreesurferAtlas'}[modality] + + write_filters = { 'center': proto, 'acquisition': str(acq), 'subject' : str(patient) } + + if filetype == 'fMRI-epile' or filetype == 'Statistic-Data': + text, ok = QtGui.QInputDialog.getText(self, 'Input Dialog', 'Enter the name of the test:') + + if (ok & bool(text)): + write_filters.update({'subacquisition':str(text)}) + + + wdi = WriteDiskItem(filetype, 'NIFTI-1 image' )#'gz compressed NIFTI-1 image' ) + print "Finding BV path for acquisition %s and patient %s"%(acq, patient) + di = wdi.findValue(write_filters) + + if di is None: + QtGui.QMessageBox.warning(self, "Error", u"Impossible to find a valid path to import the Image in Brainvisa database (%s, %s)"%(patient, acq)) + return + # Copy the file : lancer l'importation standard de T1 MRI pour la conversion de format et + destination = di.fileName() + if os.path.exists(destination): + reply = QtGui.QMessageBox.question(self, 'Overwrite', u"This image already exists.\nOverwrite the file ?", QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if reply == QtGui.QMessageBox.No: + return + print "Importing file as "+destination + + #current images loaded for this patient: + self.selectBvSubject(str(patient)) + + if filetype != 'fMRI-epile' and filetype != 'Statistic-Data' and filetype != 'FreesurferAtlas': + + if len(self.bvImagePaths) > 0: + ImAlreadyHere = [i for i in range(len(self.bvImagePaths)) if str(self.ui.niftiSeqType.currentText() + self.ui.niftiAcqType.currentText()+'_') in self.bvImagePaths.keys()[i]] + if len(ImAlreadyHere): + QtGui.QMessageBox.warning(self, 'WARNING', u"There is already a %s image, delete it before if you want to import another one"%str(self.ui.niftiSeqType.currentText() + self.ui.niftiAcqType.currentText())) + self.setStatus(u"Sequence %s importation not performed (already one equivalent)"%acq) + return + + # Create directories that do not exist yet + self.createItemDirs(di) + + #we check that there is a Scanner based transformation, if not and if both transformations are equal, we rename one as scanner based transformation + temp_nii = aims.read(path) + refs_nii = temp_nii.header()['referentials'] + if len(refs_nii)>1: + isScannerBased = 0 + sum_transfo = numpy.zeros(16,dtype='float32') + for ii in range(len(refs_nii)): + if refs_nii[ii] == 'Scanner-based anatomical coordinates': + isScannerBased = 1 + sum_transfo = sum_transfo + temp_nii.header()['transformations'][ii] + + mean_transfo = sum_transfo/len(refs_nii) + if isScannerBased == 0: + diff = mean_transfo - temp_nii.header()['transformations'][0] + if numpy.absolute(diff).round(2).sum() <= 0.03: + temp_nii.header()['referentials'][0] = 'Scanner-based anatomical coordinates' + + + else: + if refs_nii[0] == 'Coordinates aligned to another file or to anatomical truth': + temp_nii.header()['referentials'][0] = 'Scanner-based anatomical coordinates' + + aims.write(temp_nii,destination) + + #pdb.set_trace() + if (filetype != 'fMRI-epile') & (filetype != 'PET') & (filetype != 'Statistic-Data'): # or filetype != 'MTT' + ret = subprocess.call(['AimsFileConvert', '-i', str(destination), '-o', str(destination), '-t', 'S16']) + if ret < 0: + print "Importation error" + QtGui.QMessageBox.warning(self, "Error", "Importation error : BrainVisa / AimsFileConvert") + return + elif filetype == 'PET': + #pdb.set_trace() + print "conversion PET float to S16" + ret = subprocess.call(['AimsFileConvert', '-i', str(destination), '-o', str(destination), '-t', 'S16', '-r', 'True']) + if ret < 0: + print "Importation error" + QtGui.QMessageBox.warning(self, "Error", "Importation error : BrainVisa / AimsFileConvert") + return + di.setMinf('ColorPalette','Blue-Red-fusion') + else: + print "no conversion to grayscale" + ret = subprocess.call(['AimsFileConvert', '-i', str(destination), '-o', str(destination)]) + if ret < 0: + print "Importation error" + QtGui.QMessageBox.warning(self, "Error", "Importation error : BrainVisa / AimsFileConvert") + return + + if str(self.ui.niftiSeqType.currentText()) == 'T1': + if self.ui.radioButtonGado.isChecked(): + di.setMinf('Gado',True) + if self.ui.radioButtonNoGado.isChecked(): + di.setMinf('Gado',False) + neuroHierarchy.databases.insertDiskItem( di, update=True ) + + + di.setMinf('brainCenter', self.brainCenter) + + if filetype == 'Statistic-Data': + + textMNI, okMNI = QtGui.QInputDialog.getItem(self,'MNI or not','Is the statistic image generated in the MNI',['True','False']) + if (okMNI & bool(textMNI)): + di.setMinf('MNI',str(textMNI)) + di.setMinf('ColorPalette','Yellow-Red-White-Blue-Green') + + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Sequence %s importation done"%acq) + + if filetype == 'Statistic-Data': + try: + self.StatisticDataMNItoScannerBased(proto, patient, acq) + except: + pass + + if filetype == 'FreesurferAtlas': + self.generateAmygdalaHippoMesh(proto, patient, acq, di) + # Appeler le process SPMnormalizationPipeline.py de la toolbox t1, et ajouter sur ce modèle un process coregister + + def importFSoutput(self,subject=None): + + if subject == None: + subject = self.currentSubject + + #find T1pre of the subject + rT1BV = ReadDiskItem('Raw T1 MRI', 'BrainVISA volume formats',requiredAttributes={'subject':subject}) + allT1 = list(rT1BV.findValues({},None,False)) + idxT1pre = [i for i in range(len(allT1)) if 'pre' in str(allT1[i])] + diT1pre = allT1[idxT1pre[0]] + + acq = str(diT1pre.attributes()['acquisition']).replace('T1','FreesurferAtlas') + write_filters = { 'center': str(self.ui.niftiProtocolCombo.currentText()), 'acquisition': str(acq), 'subject' : subject } + + FreesurferNu = ReadDiskItem('Nu FreesurferAnat', 'FreesurferMGZ',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Nufound = list(FreesurferNu.findValues({},None,False)) + Nufound = [x for x in Nufound if '.mgz' in str(x)][0] + + FreesurferRibbon = ReadDiskItem('Ribbon Freesurfer','FreesurferMGZ',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Ribbonfound = list(FreesurferRibbon.findValues({},None,False)) + Ribbonfound = [x for x in Ribbonfound if '.mgz' in str(x)][0] + + FreesurferPial = ReadDiskItem('Any Type','FreesurferPial',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Pialfound = list(FreesurferPial.findValues({},None,False)) + PialLeft = [x for x in Pialfound if '/lh.' in str(x)][0] + PialRight = [x for x in Pialfound if '/rh.' in str(x)][0] + + PialMeshBV = WriteDiskItem('Pial','aims mesh formats') + diPialMeshBV = PialMeshBV.findValue(write_filters) + + FreesurferWhite = ReadDiskItem('Any Type','FreesurferWhite',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Whitefound = list(FreesurferWhite.findValues({},None,False)) + WhiteLeft = [x for x in Whitefound if '/lh.' in str(x)][0] + WhitelRight = [x for x in Whitefound if '/rh.' in str(x)][0] + + right_grey_white_output=WriteDiskItem('Right Grey White Mask','Aims writable volume formats') + diright_grey_white = right_grey_white_output.findValue(write_filters) + left_grey_white_output=WriteDiskItem('Left Grey White Mask','Aims writable volume formats') + dileft_grey_white = left_grey_white_output.findValue(write_filters) + + WhiteMeshBV = WriteDiskItem('White','aims mesh formats') + diWhiteMeshBV = WhiteMeshBV.findValue(write_filters) + #diWhiteLeftMeshBV = [x for x in diWhiteMeshBV + + FreesurferThickness = ReadDiskItem('Any Type','FreesurferThickness',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Thicknessfound = list(FreesurferThickness.findValues({},None,False)) + ThickLeft = [x for x in Thicknessfound if '/lh.' in str(x)][0] + ThickRight = [x for x in Thicknessfound if '/rh.' in str(x)][0] + + FreesurferDestrieux = ReadDiskItem('Freesurfer Cortical Parcellation using Destrieux Atlas','FreesurferMGZ',requiredAttributes={'subject':subject,'_ontology':'freesurfer'}) + + Destrieuxfound = list(FreesurferDestrieux.findValues({},None,False)) + + pdb.set_trace() + #generer tous les writediskitem + context = brainvisa.processes.defaultContext() + context.write("convert output from freesurfer") + launchFreesurferCommand(context, None, 'mri_convert', '-i',str(Nufound),'-o',os.path.join(os.path.dirname(str(Nufound)),'nu.nii'),'-rl',str(diT1pre.fullPath())) + launchFreesurferCommand(context, None, 'mri_convert', '-i',str(Ribbonfound),'-o',os.path.join(os.path.dirname(str(Ribbonfound)),'ribbon.nii'),'-rl',str(diT1pre.fullPath()),'-rt','nearest','-nc') + + + wdi = WriteDiskItem('FreesurferAtlas', 'NIFTI-1 image' ) + diFSDestrieux = wdi.findValue(write_filters) + #create the folder if doesn't exist + if not os.path.isfile(os.path.dirname(str(diFSDestrieux.fullPath()))): + try: + os.makedirs(os.sep.join(os.path.dirname(str(diFSDestrieux.fullPath())).split(os.sep)[:-1])) + except: + #already exist probably + pass + try: + os.makedirs(os.path.dirname(str(diFSDestrieux.fullPath()))) + except: + #already exist probably + pass + + launchFreesurferCommand(context, None, 'mri_convert', '-i',str(Destrieuxfound[0]),'-o',str(diFSDestrieux.fullPath()),'-rl',str(diT1pre.fullPath()),'-rt','nearest','-nc') + ret = subprocess.call(['AimsFileConvert', '-i', str(diFSDestrieux.fullPath()), '-o', str(diFSDestrieux.fullPath()), '-t', 'S16']) + #pour destrieux + self.generateAmygdalaHippoMesh(str(self.ui.niftiProtocolCombo.currentText()), subject, acq, diFSDestrieux) + + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', WhiteLeft, str(diWhiteleft.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', WhiteRight, str(diWhiteright.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', PialLeft, str(diPialleft.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', PialRight, str(diPialright.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', ThickLeft, str(diPialright.fullPath())) + launchFreesurferCommand(context, None, 'mris_convert', '--to-scanner', ThickRight, str(diPialright.fullPath())) + + #loading the object to get its referential and assign it + self.a.loadObject(diT1pre) + refes=self.a.getReferentials() + for element in refes: + if 'T1pre' in str(element.getInfos()): + ref=element + whiteL=self.a.loadObject(diWhiteleft) + whiteL.assignReferential(ref) + whiteR=self.a.loadObject(diWhiteright) + whiteR.assignReferential(ref) + pialL=self.a.loadObject(diPialleft) + pialL.assignReferential(ref) + pialR=self.a.loadObject(diPialright) + pialR.assignReferential(ref) + + + def importPacs(self): + """ Import the selected images from the pacs to BrainVisa (after the Nifti importation) TODO does not work """ + + #self.importNifti(path, patient, modality, acq) + selectedSeries = dict((self.seriesUIDbyName [str(item.text())], self.pacsSeries[self.seriesUIDbyName [str(item.text())]]) for item in self.ui.pacsSeriesList.selectedItems()) + self.importBV(selectedSeries) + + + def importDir(self): + """ Import the selected image from dicom directory to BrainVisa (after Nifti importation) """ + # Find selected series + selectedSeries = dict((self.seriesUIDbyName [str(item.text())], self.dirSeries[self.seriesUIDbyName [str(item.text())]]) for item in self.ui.dirSeriesList.selectedItems()) + self.importBV(selectedSeries) + + def importBV(self, selectedSeries): + if len(selectedSeries) != 1: + QtGui.QMessageBox.warning(self, "Error", u"Select one (and only one ! ) sequence !") + return + serie = None + for k in selectedSeries: + serie = selectedSeries[k] + + if 'niftiPath' not in serie: + QtGui.QMessageBox.warning(self, "Error", u"You have to convert the sequence in Nifti format before importing in Brainvisa") + return + + acq = str(self.ui.dirSeqType.currentText() + self.ui.dirAcqType.currentText() + '_' + dateDecode(serie['SeriesDate'])) + patient = patientNameDecode(serie['PatientsName']) + self.importNifti(serie['niftiPath'], patient, str(self.ui.dirSeqType.currentText()), acq) + + + #******************************** Add New Subject + # ANONYMIZATION TAKES PLACE HERE + def updatePatientCode(self): + # __ + if self.prefs['projectSelected'][0] == 1 or self.prefs['projectSelected'][0] == 2: + print "neuropsynov or classique" + self.ui.subjectPatientCode.setText(self.ui.subjectSiteCombo.currentText() + '_' + str(self.ui.subjectYearSpinbox.value()) + '_' + str(self.ui.subjectPatientName.text())[:3].upper() + str(self.ui.subjectPatientFirstName.text())[:1].lower()) + if self.prefs['projectSelected'][0] == 0: + print "f-Tract" + self.ui.subjectPatientCode.setText(str(self.ui.subjectPatientName.text()).upper() + str(self.ui.subjectSiteCombo.currentText()).upper()) + if self.prefs['projectSelected'][0] == 3: + print "other" + self.ui.subjectPatientCode.setText(self.ui.subjectSiteCombo.currentText() + '_' + str(self.ui.subjectYearSpinbox.value()) + '_' + str(self.ui.subjectPatientName.text())[:3].upper() + str(self.ui.subjectPatientFirstName.text())[:1].lower()) + + def storePatientInDB(self): + + anon = str(self.ui.subjectPatientCode.text()) + if self.prefs['projectSelected'][0] == 1 or self.prefs['projectSelected'][0] == 2: + if len(anon) < 10: + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier is too short and doesn't match the subject identifier model chosen in preferences") + return + if self.prefs['projectSelected'][0] == 0: + if len(anon) < 16: + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier is too short and doesn't match the subject identifier model chosen in preferences") + return + elif len(anon) > 16: + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier is too long and doesn't match the subject identifier model chosen in preferences") + return + else: + if not (anon[0:4].isdigit() and not anon[4:8].isdigit() and anon[8:].isdigit() and anon[7] == '_'): + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier doesn't match the subject identifier model chosen in preferences: ex: 0001GRE_yyyymmdd") + return + else: + if not int(anon[8:12]) > 1950 and not int(anon[8:12]) < 2100 and not int(anon[12:14]) >0 and not int(anon[12:14]) < 13 and not int(anon[14:16]) > 0 and not int(anon[14:16]) < 32: + QtGui.QMessageBox.warning(self, u"Subject adding", u"Impossible to add the subject, subject identifier doesn't match the subject identifier model chosen in preferences: ex: 0001GRE_yyyymmdd") + return + + + wdi = WriteDiskItem( 'Subject', 'Directory' ) + di = wdi.findValue( { 'center': str(self.ui.subjectProtocolCombo.currentText()), 'subject' : anon } ) + if di is None: + QtGui.QMessageBox.warning(self, u"Error", u"Impossible to find a valid path for the patient") + self.setStatus(u"Subject add failed : the path is not valid") + return + # Create directories that do not exist yet + self.createItemDirs(di) + try: + os.mkdir(di.fileName()) + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Subject %s added to the database"%anon) + self.currentSubject = anon + except: + self.setStatus(u"Subject adding failed : impossible to create subject folder") + + self.ui.tabWidget.setCurrentIndex(2) + + + + # ******************************* Implantation + + def selectImplSubject(self, subj): + """ A BrainVisa subject was selected : query the database to get the available images""" + rdi = ReadDiskItem( 'Electrode Implantation Coronal Image', 'BrainVISA image formats', requiredAttributes={'center':str(self.ui.implProtocolCombo.currentText()), 'subject':str(subj)} ) + coros = list( rdi._findValues( {}, None, False ) ) + coro = None + if len(coros) == 0: + self.ui.implCoroLabel.setText("no image") + elif len(coros) > 1: + QtGui.QMessageBox.warning(self, "Erreur", "Ce sujet a plusieurs implantations enregistrees ! Cette situation n'est pas geree par ce logiciel") + print repr(coros) + else: + self.ui.implCoroLabel.setText(str(coros[0].fullPath())) + coro = coros[0].fullPath() + + rdi = ReadDiskItem( 'Electrode Implantation Sagittal Image', 'BrainVISA image formats', requiredAttributes={'center':str(self.ui.implProtocolCombo.currentText()), 'subject':str(subj)} ) + sags = list( rdi._findValues( {}, None, False ) ) + sag = None + if len(sags) == 0: + self.ui.implSagLabel.setText("no image") + elif len(sags) > 1: + QtGui.QMessageBox.warning(self, "Erreur", "Ce sujet a plusieurs implantations enregistrees ! Cette situation n'est pas geree par ce logiciel") + print repr(sags) + else: + self.ui.implSagLabel.setText(str(sags[0].fullPath())) + sag = sags[0].fullPath() + self.displayAnatomist(coro, sag) + + def openImplCoro(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open Coronal 2D Image", "", "Images (*.gif *.jpg *.jpeg *.png)")) + if not path: + return + self.ui.implCoroLabel.setText(path) + sag = str(self.ui.implSagLabel.text()) + if sag == "": + sag = None + self.displayAnatomist(path, sag) + + def importImplCoro(self): + wdi = WriteDiskItem('Electrode Implantation Coronal Image', 'JPEG image' )#'gz compressed NIFTI-1 image' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()) } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer l'image coro dans BrainVisa") + return + # Copy the file : lancer l'importation standard de T1 MRI pour la conversion de format et + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + # + ret = subprocess.call(['AimsFileConvert', '-i', str(self.ui.implCoroLabel.text()), '-o', str(destination)]) + if ret < 0: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur d'importation BrainVisa / AimsFileConvert") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation coronal importé") + + + def openImplSag(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open Sagittal 2D Image", "", "Images (*.gif *.jpg *.jpeg *.png)")) + if not path: + return + self.ui.implSagLabel.setText(path) + coro = str(self.ui.implCoroLabel.text()) + if coro == "": + coro = None + self.displayAnatomist(coro, path) + + + def importImplSag(self): + wdi = WriteDiskItem('Electrode Implantation Sagittal Image', 'JPEG image' )#'gz compressed NIFTI-1 image' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()) } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer l'image sagittale dans BrainVisa") + return + # Copy the file : lancer l'importation standard de T1 MRI pour la conversion de format et + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + # + ret = subprocess.call(['AimsFileConvert', '-i', str(self.ui.implCoroLabel.text()), '-o', str(destination)]) + if ret < 0: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur d'importation BrainVisa / AimsFileConvert") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation Sagittal importé") + + def openImplPpt(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open PPT implantation schema", "", "Powerpoint file (*.ppt *.pptx)")) + if not path: + return + self.ui.implPptLabel.setText(path) + + + def importImplPpt(self): + wdi = WriteDiskItem('Electrode Implantation Powerpoint report', 'Powerpoint file' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()) } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer le rapport Powerpoint dans BrainVisa") + return + # Copy the file + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + shutil.copyfile(str(self.ui.implPptLabel.text()), str(destination)) + if ret < 0: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur lors de la copie du fichier") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation Powerpoint importé") + + def openImplPdf(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open PDF implantation schema", "", "PDF file (*.pdf)")) + print "Chemin du PDF %s"%path + if not path: + return + self.ui.implPdfLabel.setText(path) + + def openImplPdf2(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open PDF implantation schema", "", "PDF file (*.pdf)")) + print "Chemin du PDF %s"%path + if not path: + return + self.ui.implPdfLabel2.setText(path) + + def openImplElListPdf(self): + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open PDF Electrode List", "", "PDF file (*.pdf)")) + print "Chemin du PDF %s"%path + if not path: + return + self.ui.implElListPdfLabel.setText(path) + + + def importImplPdf(self): + wdi = WriteDiskItem('Electrode Implantation PDF report', 'PDF file' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()), 'planning' : 'True' } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer le rapport PDF dans BrainVisa") + return + # Copy the file + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + try: + shutil.copyfile(str(self.ui.implPdfLabel.text()), str(destination)) + except: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur lors de la copie du fichier PDF") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation PDF importé") + + def importImplPdf2(self): + wdi = WriteDiskItem('Electrode Implantation PDF report', 'PDF file' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()), 'planning' : 'False' } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer le rapport PDF dans BrainVisa") + return + # Copy the file + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + try: + shutil.copyfile(str(self.ui.implPdfLabel2.text()), str(destination)) + except: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur lors de la copie du fichier PDF") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation PDF importé") + + def importImplElListPdf(self): + wdi = WriteDiskItem('Electrode List PDF', 'PDF file' ) + di = wdi.findValue( { 'center': str(self.ui.implProtocolCombo.currentText()), 'subject' : str(self.ui.implSubjectCombo.currentText()), 'planning' : 'False' } ) + if di is None: + QtGui.QMessageBox.warning(self, "Erreur", "Impossible de trouver un chemin valide pour importer la liste PDF dans BrainVisa") + return + # Copy the file + destination = di.fileName() + print "Importing file as "+destination + # Create directories that do not exist yet + self.createItemDirs(di) + try: + shutil.copyfile(str(self.ui.implElListPdfLabel.text()), str(destination)) + except: + print "Erreur d'importation" + QtGui.QMessageBox.warning(self, "Erreur", "Erreur lors de la copie du fichier PDF") + return + neuroHierarchy.databases.insertDiskItem( di, update=True ) + self.setStatus(u"Rapport d'implantation PDF importé") + + # ******************************* Registration + + def selectRegSubject(self, subj): + """ A BrainVisa subject was selected : query the database to get the list of images""" + # Display "Date : XXXX-XX-XX - Seq: T1 - Acq : T1Pre + self.ui.regImageList.clear() + self.ui.regImageList2.clear() + images = self.findAllImagesForSubject(self.ui.regProtocolCombo.currentText(), subj) + #name = modality + acquisition + subacquisition if exist subacquisition key else modality + acquisition + + dict_temporaire1 = {} + for i in images: + if 'subacquisition' in i.attributes().keys(): + dict_temporaire1.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition']:i.fileName()}) + else: + dict_temporaire1.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition']:i.fileName()}) + + dict_temporaire2 = {} + for i in images: + if 'subacquisition' in i.attributes().keys(): + dict_temporaire2.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition']:i}) + else: + dict_temporaire2.update({i.attributes()['modality'] + ' - ' + i.attributes()['acquisition']:i}) + + self.ui.regImageList.addItems(sorted([i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition'] if 'subacquisition' in i.attributes().keys()\ + else i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] for i in images ])) + self.ui.regImageList2.addItems(sorted([i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] + ' - ' + i.attributes()['subacquisition'] if 'subacquisition' in i.attributes().keys()\ + else i.attributes()['modality'] + ' - '+ i.attributes()['acquisition'] for i in images ])) + + + self.regImagePaths = dict_temporaire1 + self.regImages = dict_temporaire2 + + + def selectRegImage(self, item): + """ A BrainVisa image was double-clicked : display it !""" + self.clearAnatomist() + image = self.regImages[str(item.text())] + mri = self.a.loadObject(image) + self.a.addObjects(mri, self.wins[:2]) + self.dispObj.append(mri) + + def selectRegImage2(self, item): + """ A BrainVisa image was double-clicked in the second list: display it !""" + self.clearAnatomist(self.wins[2:]) + #path = self.regImagePaths[str(item.text())] + image = self.regImages[str(item.text())] + mri = self.a.loadObject(image) + self.a.addObjects(mri, self.wins[2:]) + self.dispObj.append(mri) + + def registerNormalizeSubject(self): + """ Registers all images of the subject with SPM, then store the transforms in BrainVisa database, and launch T1pre morphologist analysis (brain segmentation) """ + proto = str(self.ui.regProtocolCombo.currentText()) + subj = str(self.ui.regSubjectCombo.currentText()) + images = self.findAllImagesForSubject(proto, subj) + # Find all images, normalize the T1s, find the T1pre if there is one, read image headers, store their referentials and transformations in the DB + t1preImage = None + for image in images: + patient = image.attributes()['subject'] + acq = image.attributes()['acquisition'] + # Store Scanner-based referential and referential files in the DB + if not image.attributes()['modality'] == 'statistic_data' and not image.attributes()['modality'] == 'freesurfer_atlas' and not image.attributes()['modality'] == 'hippofreesurfer_atlas': + print "do the coregistration" + self.storeImageReferentialsAndTransforms(image) + # If this is a T1, normalize it to MNI (pre or post). If the pre is badly normalized, "using the post" should be stored in the DB + if acq.startswith('T1'): + self.setStatus("Normalization of %s to MNI referential in progress ..."%acq) + self.spmNormalize(image.fileName(), proto, patient, acq) + # If there is a T1pre, remember the image + if acq.find('T1pre') == 0: + t1preImage = image + + # No T1pre : nothing else to do + if t1preImage is None: + return + + for image in images: + # A T1pre is there, coregister all images to it + if image == t1preImage: + continue + elif image.attributes()['modality'] == 'statistic_data' or image.attributes()['modality'] == 'freesurfer_atlas' or image.attributes()['modality'] == 'hippofreesurfer_atlas': + #pdb.set_trace() + print "attribute T1pre referential to this modality {}".format(image.attributes()['modality']) + self.transfoManager.setReferentialTo(image, t1preImage.attributes()['referential'] ) + continue + acq = image.attributes()['acquisition'] + patient = image.attributes()['subject'] + + if self.coregMethod == 'ANTs': + print("ANTs coregistration used") + temp_folder_ants = tempfile.mkdtemp('ANTs_IntrAnat') +'/' + + ants_call = '{}/antsRegistrationSyN.sh -d 3 -f {} -m {} -o {} -t r'.format(self.prefs['ants'],str(t1preImage.fullPath()),str(image.fullPath()),temp_folder_ants) + thr = Executor(ants_call.split()) + thr.finished.connect(lambda:self.taskfinished(u"ANTs Coregister done", thr)) + thr.finished.connect(lambda im = image, tmp_folder=temp_folder_ants:self.setANTstrm_database(im, tmp_folder)) + self.threads.append(thr) + thr.start() + + #to mettre dans la database + #thr.finished.connect(lambda im=image, trm=tmpOutput:self.insertTransformationToT1pre(trm,im)) + + elif self.coregMethod == 'spm': + print("spm coregistration used") + if self.ui.regResampleCheck.isChecked(): + self.setStatus('Coregistration of the image: '+ acq + u" with resampling") + self.spmCoregisterResample(image, t1preImage) + else: + self.setStatus('Coregistration of the image: '+ acq) + self.spmCoregister(image, t1preImage) + + elif self.coregMethod == 'Aims': + print("Aims coregistration used") + pdb.set_trace() + #ret = subprocess.call(['AimsMIRegister', '-r', str(t1preImage.fullPath()), '-t', str(image.fullPath()), '--dir', tmp_trm_path, '--inv',tmp_trm_path2]) + #if ret < 0: + # print "coregistration error: "+ str(image.fullPath())#terminal + # QtGui.QMessageBox.warning(self, "Error", u"The coregistration didn't work") #utilisateur + # return + #self.insertTransformationToT1pre(tmp_trm_path,image) + + + self.mriAcPc = t1preImage # Store the mri for Morphologist + self.runBVMorphologist(t1preImage) + # Check the registrations with anatomist when threads are done + + def segmentationHIPHOP(self): + + proto = str(self.ui.regProtocolCombo.currentText()) + subj = str(self.ui.regSubjectCombo.currentText()) + images = self.findAllImagesForSubject(proto, subj) + # Find all images, normalize the T1s, find the T1pre if there is one, read image headers, store their referentials and transformations in the DB + t1preImage = None + for image in images: + patient = image.attributes()['subject'] + acq = image.attributes()['acquisition'] + # Store Scanner-based referential and referential files in the DB + if acq.startswith('T1'): + # If there is a T1pre, remember the image + if acq.find('T1pre') == 0: + t1preImage = image + + # No T1pre : nothing else to do + if t1preImage is None: + return + + self.mriAcPc = t1preImage + self.runBVMorphologist(t1preImage) + + + def setANTstrm_database(self,im, tmp_folder): + + file_to_open = tmp_folder + '0GenericAffine.mat' + tmp_trm_path = getTmpFilePath('txt') + ants_call ='{}/ConvertTransformFile 3 {} {} --RAS --homogeneousMatrix'.format(self.prefs['ants'],file_to_open,tmp_trm_path) + runCmd(ants_call.split()) + info_mat = numpy.loadtxt(tmp_trm_path) + info_mat = numpy.linalg.inv(info_mat) + rot_mat = info_mat[:3,:3] + tr_mat = info_mat[:3,3] + result_mat = numpy.vstack((tr_mat,rot_mat)) + #info_mat = scipy.io.loadmat(file_to_open) + #matrix_unshaped = info_mat['AffineTransform_double_3_3'] + #matrix_shaped = matrix_unshaped.reshape(4,3) + #matrix_shaped = numpy.roll(matrix_shaped,3) + + numpy.savetxt(tmp_trm_path,result_mat,delimiter =' ',fmt='%8.8f') + self.insertTransformationToT1pre(tmp_trm_path,im) + if 'ANTs_IntrAnat' in tmp_folder: + shutil.rmtree(tmp_folder) + + + + def enableACPCButtons(self, trueorfalse): + """ Enables or disables all buttons for entering AC/PC reference points """ + self.ui.regAcButton.setEnabled(trueorfalse) + self.ui.regPcButton.setEnabled(trueorfalse) + self.ui.regIhButton.setEnabled(trueorfalse) + self.ui.regLhButton.setEnabled(trueorfalse) + self.ui.regACPCLabel.setEnabled(trueorfalse) + self.ui.regAcPcValidateButton.setEnabled(trueorfalse) + + def runBVMorphologist(self, image): + """ Runs the morphologist analysis to get segmented brain and hemispheres. + Just activates the buttons to enter AC/PC. The validate button will run the + analysis itself""" + + # Display + self.clearAnatomist() + mri = self.a.loadObject(image.fileName()) + self.dispObj.append(mri) + self.a.addObjects(mri, self.wins) + self.enableACPCButtons(True) + # Ask the user to provide AC/PC information to launch MRI segmentation + QtGui.QMessageBox.information(self, "AC/PC", "Enter AC, PC, IH, LH then validate to segment the brain", QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) + + return None + + def validateAcPc(self, ): + if not all(k in self.AcPc for k in ('AC','PC','IH','LH')): + # Some values are missing + QtGui.QMessageBox.warning(self, 'Missing points', u"You have entered the following points %s, You have to enter AC, PC, IH and LH"%repr(self.AcPc.keys())) + return + + + # reset buttons color + self.ui.regAcButton.setStyleSheet("") + self.ui.regPcButton.setStyleSheet("") + self.ui.regIhButton.setStyleSheet("") + self.ui.regLhButton.setStyleSheet("") + + + #morphologist = processes.getProcessInstance('morphologist') + #morphologist.executionNode().PrepareSubject.setSelected(False) + #morphologist.executionoNode().BiasCorrection.setSelected(False) + #self.brainvisaContext.runInteractiveProcess(lambda x='':self.hiphopStart() , morphologist, t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + # posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + + + if 'Gado' in self.mriAcPc.attributes().keys(): + if not self.mriAcPc.attributes()['Gado']: + self.brainvisaContext.runInteractiveProcess(lambda x='':self.hiphopStart() , 'Morphologist 2015', t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + self.setStatus(u"Starting segmentation BrainVisa/Morphologist2015 of the image T1 pre-implantation") + # Close the display, disable the buttons and forget AcPc coordinates (they could be mistakenly used for another subject !) + self.clearAnatomist() + self.enableACPCButtons(False) + self.AcPc = {} + + if not 'Gado' in self.mriAcPc.attributes().keys(): + self.brainvisaContext.runInteractiveProcess(lambda x='':self.hiphopStart() , 'Morphologist 2015', t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + self.setStatus(u"Starting segmentation BrainVisa/Morphologist2015 of the image T1 pre-implantation") + # Close the display, disable the buttons and forget AcPc coordinates (they could be mistakenly used for another subject !) + self.clearAnatomist() + self.enableACPCButtons(False) + self.AcPc = {} + + if 'Gado' in self.mriAcPc.attributes().keys(): + if self.mriAcPc.attributes()['Gado']: + morphologist = processes.getProcessInstance('morphologist') + morphologist.executionNode().PrepareSubject.setSelected(True) + morphologist.executionNode().BiasCorrection.setSelected(True) + morphologist.executionNode().HistoAnalysis.setSelected(False) + morphologist.executionNode().BrainSegmentation.setSelected(False) + morphologist.executionNode().Renorm.setSelected(False) + morphologist.executionNode().SplitBrain.setSelected(False) + morphologist.executionNode().TalairachTransformation.setSelected(False) + morphologist.executionNode().HeadMesh.setSelected(False) + morphologist.executionNode().HemispheresProcessing.setSelected(False) + morphologist.executionNode().SulcalMorphometry.setSelected(False) + + self.brainvisaContext.runInteractiveProcess(lambda x='':self.run2ndpartMorphologist() , morphologist, t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + #def spmRegisterPatient(self, protocol, patient, acq): + ## Comment choisir le moment pour recaler les post avec les pre, si l'import est fait dans l'ordre post puis pre ? + ## Solution : + ## - a chaque importation, on regarde les acquisitions existantes pour le patient concerné + #images = self.findAllImagesForSubject(protocol, patient) + #nameAcq=[t.attributes()['acquisition'] for t in images] + #na = [n.split('_')[0] for n in nameAcq] # same without the acquisition date e.g. 'T1pre' instead of 'T1pre_2001_01_01' + #current = [t for t in images if str(t.attributes()['acquisition']) == str(acq)][0] + + #thrs = [] + + ## - si on est en train d'importer la T1pre, on recale toutes les autres vers cette dernière + #if acq.split('_')[0] == 'T1pre': + #thrs.append(self.spmCoregister([t.fileName() for t in images if t != current], current.fileName())) + + ## - si on a une T1pre existante, on recale la nouvelle image vers la T1pre + #if 'T1pre' in na and acq.split('_')[0] != 'T1pre': + #thrs.append(self.spmCoregister([current.fileName(),], images[na.index('T1pre')].fileName())) + + ## - si on a une T1, on la recale vers MNI (que ce soit pre ou post) et on marque dans la base de données le recalage MNI actif + #if acq.startswith('T1'): + #self.setStatus("Normalisation de %s vers le referentiel MNI en cours..."%acq) + #thrs.append(self.spmNormalize(current.fileName(), protocol, patient, acq)) + + #return thrs + + def run2ndpartMorphologist(self): + + print "run segmentation to remove Gado on T1 no bias" + nobiasRDI = ReadDiskItem("T1 MRI Bias Corrected", 'BrainVISA volume formats',requiredAttributes={"center":self.currentProtocol,"subject":self.currentSubject}) + nobiasimages = list( nobiasRDI._findValues( {}, None, False ) ) + id_pre = [x for x in range(len(nobiasimages)) if 'pre' in str(nobiasimages[x])] + #je change le .nii par le segmenté et je le rechange à la fin ? c'est moche ... + pathTPMseg = os.path.join(str(self.prefs['spm']),'tpm','TPM.nii') + import copy + splittedName = str(nobiasimages[id_pre[0]]).split('/') + c1Name = copy.deepcopy(splittedName) + c2Name = copy.deepcopy(splittedName) + c3Name = copy.deepcopy(splittedName) + c4Name = copy.deepcopy(splittedName) + c1Name[-1] = str("c1")+c1Name[-1] + c1Name = '/'.join(c1Name) + c2Name[-1] = str("c2")+c2Name[-1] + c2Name = '/'.join(c2Name) + c3Name[-1] = str("c3")+c3Name[-1] + c3Name = '/'.join(c3Name) + c4Name[-1] = str("c4")+c4Name[-1] + c4Name = '/'.join(c4Name) + splittedName[-1]=str("WithoutGado.nii") + splittedName = '/'.join(splittedName) + call = matlab_removeGado%("'"+str(self.prefs['spm'])+"'","'"+str( str(nobiasimages[id_pre[0]]))+",1'","'"+str(pathTPMseg)+",1'","'"+str(pathTPMseg)+",2'","'"+str(pathTPMseg)+",3'","'"+str(pathTPMseg)+",4'","'"+str(pathTPMseg)+",5'","'"+str(pathTPMseg)+",6'",\ + "'"+c1Name+"'","'"+c2Name+"'","'"+c3Name+"'","'"+c4Name+"'","'"+str(nobiasimages[id_pre[0]])+"'","'"+str(splittedName)+"'") + matlabRun(call) + print "segmentation gado done" + + cmd1 = ['mv', str(nobiasimages[id_pre[0]]), os.path.join('/tmp',self.currentSubject+'backup.nii')] + cmd2 = ['cp',str(splittedName), str(nobiasimages[id_pre[0]])] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + morphologist = processes.getProcessInstance('morphologist') + morphologist.executionNode().PrepareSubject.setSelected(False) + morphologist.executionNode().BiasCorrection.setSelected(False) + morphologist.executionNode().HistoAnalysis.setSelected(True) + morphologist.executionNode().BrainSegmentation.setSelected(True) + morphologist.executionNode().Renorm.setSelected(True) + morphologist.executionNode().SplitBrain.setSelected(True) + morphologist.executionNode().TalairachTransformation.setSelected(False) + morphologist.executionNode().HeadMesh.setSelected(True) + morphologist.executionNode().HemispheresProcessing.setSelected(True) + morphologist.executionNode().SulcalMorphometry.setSelected(True) + + self.brainvisaContext.runInteractiveProcess(lambda x='':self.hiphopStart() , morphologist, t1mri = self.mriAcPc, perform_normalization = False, anterior_commissure = self.AcPc['AC'],\ + posterior_commissure = self.AcPc['PC'], interhemispheric_point = self.AcPc['IH'], left_hemisphere_point = self.AcPc['LH'], perform_sulci_recognition = True) + + def hiphopStart(self): + + if 'Gado' in self.mriAcPc.attributes().keys(): + if self.mriAcPc.attributes()['Gado']: + print "gado has been removed" + nobiasRDI = ReadDiskItem("T1 MRI Bias Corrected", 'BrainVISA volume formats',requiredAttributes={"center":self.currentProtocol,"subject":self.currentSubject}) + nobiasimages = list( nobiasRDI._findValues( {}, None, False ) ) + id_pre = [x for x in range(len(nobiasimages)) if 'pre' in str(nobiasimages[x])] + cmd = ['mv',os.path.join('/tmp',self.currentSubject+'backup.nii'),str(nobiasimages[id_pre[0]])] + line1 = runCmd(cmd) + + self.taskfinished(u'Segmentation et maillages BrainVisa') + self.setStatus(u"Starting of HIP/HOP") + attr = self.mriAcPc.attributes() + #pdb.set_trace() + Lrdi = ReadDiskItem('Labelled Cortical folds graph', 'Graph and data',requiredAttributes={ 'side': 'left','subject':attr['subject'] , 'center':attr['center']}) + Rrdi = ReadDiskItem('Labelled Cortical folds graph', 'Graph and data',requiredAttributes={ 'side': 'right' ,'subject':attr['subject'] , 'center':attr['center']}) + Lrdi = list( Lrdi._findValues( {}, None, False ) ) + + if len(Lrdi) == 0: + print('no left sulci label found, CANNOT RUN HIP HOP') + return + + Rrdi = list( Rrdi._findValues( {}, None, False ) ) + if len(Rrdi) == 0: + print('no right sulci label found, CANNOT RUN HIP HOP') + return + + self.brainvisaContext.runInteractiveProcess(lambda x='':self.taskfinished(u'hip hop done'),'Hip-Hop Cortical Parameterization', Lgraph = Lrdi[0], Rgraph = Rrdi[0], sulcus_identification ='label') + + + def spmCoregister(self, image, target): + """ Coregisters an image (ReadDiskItem) to a target image (filepath) - rigid registration""" + # Temporary txt file to store the trm transformation + tmpOutput = getTmpFilePath('txt') + #pdb.set_trace() + #truc = subprocess.call(['AimsFileInfo', '-i', str(image.fileName())]) + #someinfo_keys = image._minfAttributes.keys() + #IndexDataType = someinfo_keys.index('data_type') + #someinfo_values = image._minfAttributes.values() + imageFileName = image.fileName() + if image.attributes()['data_type'] == 'RGB': + print "it is RGB" + imageFileName = getTmpFilePath('nii') + ret = subprocess.call(['AimsFileConvert', '-i', str(image.fileName()), '-o', str(imageFileName), '-t', 'S16']) + if ret < 0: + print "Conversion to S16 error: "+repr(registeredPath) #terminal + QtGui.QMessageBox.warning(self, "Error", u"The conversion into S16 didn't worked!") #utilisateur + return + + if 'brainCenter' not in image.attributes() or 'brainCenter' not in target.attributes(): + call = spm_coregister%("'"+str(self.prefs['spm'])+"'","'"+str(imageFileName)+",1'", "'"+str(target)+",1'", str([0, 0 ,0]), str([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]), str([0, 0, 0]), str([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),"'"+tmpOutput+"'") + else: + #pdb.set_trace() + call = spm_coregister%("'"+str(self.prefs['spm'])+"'","'"+str(imageFileName)+",1'", "'"+str(target)+",1'", str(image.attributes()['brainCenter']), str(image.attributes()['SB_Transform']), str(target.attributes()['brainCenter']), str(target.attributes()['SB_Transform']), "'"+tmpOutput+"'") + + + # TODO CHECK REGISTRATION AT THE END ! + thr = matlabRunNB(call)#, lambda: self.taskfinished("spm coregister")) #matlabRunNB(call) + thr.finished.connect(lambda:self.taskfinished(u"SPM Coregister done", thr)) + #pdb.set_trace() + thr.finished.connect(lambda im=image, trm=tmpOutput:self.insertTransformationToT1pre(trm,im)) + if image.attributes()['data_type'] == 'RGB': + thr.finished.connect(lambda im=imageFileName:os.remove(im) and os.remove(im+'.minf')) + self.threads.append(thr) + thr.start() + return thr + + + def spmCoregisterResample(self, image, target): + """ Coregisters an image (ReadDiskItem) to a target image (filepath) - rigid registration + !!! Replaces the original image with the resampled image in the database !!! + If the registration is faulty, the image must be imported again. + """ + #pdb.set_trace() + call = spm_coregisterReslice%("'"+str(self.prefs['spm'])+"'","{'"+str(target)+",1'}", "{'"+str(image.fileName())+",1'}") + spl = os.path.split(image.fileName()) + registeredPath = os.path.join(spl[0], 'r'+spl[1]) + thr = matlabRunNB(call)#, lambda: self.taskfinished("spm coregister")) #matlabRunNB(call) + thr.finished.connect(lambda:self.taskfinished(u"SPM Coregister-Resampling done", thr)) + thr.finished.connect(lambda im=image, resamp = registeredPath:self.setResampledToT1pre(im, resamp)) + self.threads.append(thr) + thr.start() + return thr + + def spm_template_t1(self): + #pdb.set_trace() + spm_version = checkSpmVersion(str(self.prefs['spm'])) + if spm_version == '(SPM12)': + return "{'"+str(self.ui.prefSpmTemplateEdit.text())+os.sep+'tpm/TPM.nii'+",1'}" #ou tpm/TPM.nii' parce que pour la normalisation dartel c'est tpm.nii /'toolbox/OldNorm/T1.nii' + elif spm_version == '(SPM8)': + return "{'"+str(self.ui.prefSpmTemplateEdit.text())+os.sep+'templates/T1.nii'+",1'}" + #return "{'"+str(self.ui.prefSpmTemplateEdit.text())+",1'}" + + def spmNormalize(self, image, protocol, patient, acq): + """ Normalize one image (filepath of nifti file) to the T1 template MNI referential""" + spm_version = checkSpmVersion(str(self.prefs['spm'])) + #pdb.set_trace() + if spm_version == '(SPM12)': + print 'SPM12 used' + call = spm12_normalise%("'"+str(self.prefs['spm'])+"'","{'"+str(image)+",1'}", "{'"+str(image)+",1'}", self.spm_template_t1()) + elif spm_version == '(SPM8)': + print 'SPM8 used' + call = spm8_normalise%("'"+str(self.prefs['spm'])+"'","{'"+str(image)+",1'}", "{'"+str(image)+",1'}", self.spm_template_t1()) + #TODO CHECK REGISTRATION AT THE END + #pdb.set_trace() + thr = matlabRunNB(call)#, lambda: self.taskfinished("spm normalize")) #matlabRunNB(call) + # Try to connect the thread signals to a function here that will notice when it finishes + thr.finished.connect(lambda:self.taskfinished(u"SPM Normalize done", thr)) + thr.finished.connect(lambda pr=protocol, pat=patient, a=acq:self.insertSPMdeformationFile(pr, pat, a)) + thr.finished.connect(lambda pr=protocol, pat=patient, a=acq:self.StatisticDataMNItoScannerBased(pr, pat, a)) + self.threads.append(thr) + thr.start() + return thr + + def getScannerBasedRef(self, imageDiskItem): + rdi = ReadDiskItem('Scanner Based Referential', 'Referential') + return rdi.findValue(imageDiskItem) + + def getT1preScannerBasedRef(self, protocol, patient): + rdi = ReadDiskItem('Scanner Based Referential', 'Referential', requiredAttributes={'modality':'t1mri', 'subject':patient, 'center':protocol}) + allT1s = list (rdi._findValues( {}, None, False ) ) + for t1 in allT1s: + if t1.attributes()['acquisition'].startswith(u'T1pre'): + return t1 + return None + + def getT1preNativeRef(self, protocol, patient): + rdi = ReadDiskItem('Referential of Raw T1 MRI', 'Referential', requiredAttributes={'subject':patient, 'center':protocol}) + allT1s = list (rdi._findValues( {}, None, False ) ) + for t1 in allT1s: + if t1.attributes()['acquisition'].startswith(u'T1pre'): + return t1 + return None + + def setResampledToT1pre(self, image, registeredPath): + ret = subprocess.call(['AimsFileConvert', '-i', str(registeredPath), '-o', str(image.fileName()), '-t', 'S16']) + if ret < 0: + print "Importation error of the image resampled by SPM : "+repr(registeredPath) + QtGui.QMessageBox.warning(self, "Error", u"the image has not been resampled by SPM !") + return + # TODO # Should destroy existing referentials for this image + # The referential of this image is the same as the T1 pre + #pdb.set_trace() + self.transfoManager.setReferentialTo(image, self.getT1preNativeRef(image.attributes()['center'], image.attributes()['subject'])) #replace self.getT1preNativeRef(image.attributes()['center'], image.attributes()['subject']) by talairachMNIReferentialId + os.remove(registeredPath) + + def insertTransformationToT1pre(self, trmpath, image): + """Inserts a TRM file in the DB as the transformation between image and the T1pre scanner-based ref from the same subject""" + if not os.path.exists(trmpath): + print "Error : file %s does not exist : cannot insert it as a TRM for image %s"%(trmpath, image.fileName()) + return + # Copy the transformation to the right place and declare it to Brainvisa + t1preRef = self.getT1preScannerBasedRef(image.attributes()['center'],image.attributes()['subject']) + + imageRef = self.getScannerBasedRef(image) + + # + if t1preRef is None or imageRef is None: + print "Cannot find referentials to declare coregister transform : %s %s"%(t1preRef,imageRef) + wdiTransformT1 = WriteDiskItem( 'Transform '+ self.modas[image.attributes()['modality']] +' to another image', 'Transformation matrix', exactType=True, requiredAttributes = {'modalityTarget':t1preRef.attributes()['modality'], 'acquisitionTarget':t1preRef.attributes()['acquisition']} ) + transformT1 = wdiTransformT1.findValue(image) + if transformT1 is None: + print "Cannot find path for T1pre transform in database for %s-> transformation NOT stored !"%(image.fileName()) + else: + #Move the trm file, but remove the old one first + if os.path.exists(transformT1.fullPath()): + os.remove(transformT1.fullPath()) + shutil.move(trmpath, transformT1.fullPath() ) + try: + neuroHierarchy.databases.createDiskItemFromFileName(os.path.dirname( transformT1.fullPath() )) + except: + pass + #set and update database + print ".... setting transfo info : from %s to %s for %s"%(repr(imageRef), repr(t1preRef), repr(transformT1)) + self.transfoManager.setNewTransformationInfo( transformT1, source_referential=imageRef, destination_referential= t1preRef) + self.setStatus(u'Coregister done for '+str(image.attributes()['acquisition'])) + + + def insertSPMdeformationFile(self, protocol, patient, acq): + """ Should be called when a _sn file (SPM normalization transformation file) was created to update it in the database """ + spm_version = checkSpmVersion(str(self.prefs['spm'])) + #pdb.set_trace() + if spm_version == '(SPM8)': + print 'SPM8 used' + wdi = WriteDiskItem('SPM2 normalization matrix', 'Matlab file')#'gz compressed NIFTI-1 image' ) + di = wdi.findValue( { 'center': protocol, 'subject' : patient, 'acquisition':acq } ) + elif spm_version == '(SPM12)': + print 'SPM12 used' + wdi = WriteDiskItem('SPM normalization deformation field', 'NIFTI-1 image' ) + di = wdi.findValue( { 'center': protocol, 'subject' : patient, 'acquisition':acq } ) + if di is None: + QtGui.QMessageBox.warning(self, "Error", "Impossible to find a valid path to import SPM normalization into BrainVisa") + return + + wdi_write = WriteDiskItem('T1 SPM resampled in MNI','NIFTI-1 image') + di_write = wdi_write.findValue({'center': protocol, 'subject' : patient, 'acquisition':acq}) + if not os.path.isfile(di_write.fileName()): + QtGui.QMessageBox.warning(self, "Error", "Impossible dto find a valid path for the T1 coregistered into the MNI") + else: + print "Declaring T1 registered MNI in BrainVisa DB" + di_write.fileName() + neuroHierarchy.databases.insertDiskItem(di_write, update = True) + self.setNormalizedToT1pre(di_write,di_write.fileName()) + + # The file should already be there : if it is not, abort with an error, otherwise declare it in the DB + #pdb.set_trace() + if os.path.isfile(di.fileName()): + print "Declaring SPM normalization in BrainVisa DB : "+di.fileName() + neuroHierarchy.databases.insertDiskItem( di, update=True ) + # Compute deformation fields + #wdi = WriteDiskItem('SPM normalization inverse deformation field','aims readable volume formats') + #di2 = wdi.findValue(di) + #neuroHierarchy.databases.insertDiskItem( di2, update=True ) + + + else: + print "No SPM normalization file found ! The normalization probably failed..." + QtGui.QMessageBox.warning(self, "Error", u"SPM normalization file %s unfound ! \n Normalization probably failed !"%di.fileName()) + return + + def StatisticDataMNItoScannerBased(self, protocol, patient, acq): + + #is there any statistic data to convert to the Scanner-Based space + rdi = ReadDiskItem('Statistic-Data', 'BrainVISA volume formats', requiredAttributes={'center':str(protocol), 'subject':str(patient) }) + di=list(rdi.findValues({}, None, False)) + StatToConvert = [i for i in range(len(di)) if eval(di[i].attributes()['MNI'])] + + if len(StatToConvert)>0: + + diT1 = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':protocol, 'subject':patient } ) + allT1 = list(diT1.findValues({},None,False)) + idxT1pre = [i for i in range(len(allT1)) if 'pre' in str(allT1[i])] + self.mriAcPc = allT1[idxT1pre[0]] + + spm_version = checkSpmVersion(str(self.prefs['spm'])) + for i_stat2conv in range(len(StatToConvert)): + + self.setStatus(u"Start MNI to ScannerBased conversion of %s "%str(di[StatToConvert[i_stat2conv]].fileName())) + + #check if inverse deformation field exist. + rdi_defField_read = ReadDiskItem('SPM normalization inverse deformation field','NIFTI-1 image',requiredAttributes={'center':str(protocol), 'subject':str(patient),'acquisition':self.mriAcPc.attributes()['acquisition']}) + di_defField_read=list(rdi_defField_read.findValues({}, None, False)) + + + tempNameMNI2SB = str(di[StatToConvert[i_stat2conv]].fileName()).split('/') + tempNameMNI2SB[-1]= "tmpMNItoScannerBased"+tempNameMNI2SB[-1] + tempNameMNI2SB = "/".join(tempNameMNI2SB) + + if len(di_defField_read) > 0: + print "inverse deformation field found and used" + matlabRun(spm_MNItoScannerBased%("'"+str(self.prefs['spm'])+"'","'"+str(di_defField_read[0].fileName())+"'","'"+str(di[StatToConvert[i_stat2conv]].fileName())+",1'","'"+str(self.mriAcPc)+",1'","'"+tempNameMNI2SB+",1'")) + + cmd1 = ['mv', str(di[StatToConvert[i_stat2conv]].fileName()), di[StatToConvert[i_stat2conv]].fileName()[:-4]+"_MNI.nii.backup"] + line1 = runCmd(cmd1) + + rname = tempNameMNI2SB.split('/') + rname[-1]="r"+rname[-1] + rname = "/".join(rname) + cmd2 = ['cp',rname, str(di[StatToConvert[i_stat2conv]].fileName())] + line2 = runCmd(cmd2) + + os.remove(tempNameMNI2SB) + os.remove(rname) + os.remove(str(di[StatToConvert[i_stat2conv]].fileName())+".minf") + + write_filters = { 'center': protocol, 'acquisition': str(di[StatToConvert[i_stat2conv]].attributes()['acquisition']), 'subject' : str(patient) } + wdi_new = WriteDiskItem('Statistic-Data', 'NIFTI-1 image' )#'gz compressed NIFTI-1 image' ) + write_filters.update({'subacquisition':di[StatToConvert[0]].attributes()['subacquisition']}) + + di_new = wdi_new.findValue(write_filters) + + ret = subprocess.call(['AimsFileConvert', '-i', str(di[StatToConvert[i_stat2conv]].fileName()), '-o', str(di[StatToConvert[i_stat2conv]].fileName())]) + di[StatToConvert[i_stat2conv]].setMinf('MNI','False') + di[StatToConvert[i_stat2conv]].setMinf('ColorPalette','Yellow-Red-White-Blue-Green') + neuroHierarchy.databases.insertDiskItem( di_new, update=True ) + self.transfoManager.setReferentialTo(di_new, self.mriAcPc) + + else: + #look for a y_file second + rdi_y = ReadDiskItem('SPM normalization deformation field','NIFTI-1 image',requiredAttributes={'center':str(protocol), 'subject':str(patient),'acquisition':self.mriAcPc.attributes()['acquisition'] }) + di_y = list(rdi_y.findValues({}, None, False)) + + if len(di_y) == 0: + print "No deformation field found in database" + self.setStatus(u"MNI to ScannerBased conversion of %s not performed, no deformation field found"%str(di[StatToConvert[i_stat2conv]].fileName())) + return + else: + print "deformation field found and used" + wdi_inverse = WriteDiskItem('SPM normalization inverse deformation field','NIFTI-1 image') + dir_yinv_split = str(di_y[0].fileName()).split('/') + name_yinverse = dir_yinv_split.pop()[2:] + #name_yinverse.replace('.nii','_inverse.nii') + dir_yinverse = "/".join(dir_yinv_split) + di_inverse = wdi_inverse.findValue(di_y[0]) + #on fait l'inversion de la deformation + #pour le moment ce bout de code ne marche qu'avec spm12 + if spm_version == '(SPM12)': + print 'SPM12 used' + matlabRun(spm_inverse_y_field12%("'"+str(self.prefs['spm'])+"'","'"+str(di_y[0].fileName())+"'","'"+str(self.mriAcPc)+"'","'"+name_yinverse.replace('.nii','_inverse.nii')+"'","'"+dir_yinverse+"'")) + neuroHierarchy.databases.insertDiskItem( di_inverse, update=True ) + matlabRun(spm_MNItoScannerBased%("'"+str(self.prefs['spm'])+"'","'"+str(di_inverse)+"'","'"+str(di[StatToConvert[i_stat2conv]].fileName())+",1'","'"+str(self.mriAcPc)+",1'","'"+tempNameMNI2SB+",1'")) + + cmd1 = ['mv', str(di[StatToConvert[i_stat2conv]].fileName()), di[StatToConvert[i_stat2conv]].fileName()[:-4]+"_MNI.nii"] + line1 = runCmd(cmd1) + + rname = tempNameMNI2SB.split('/') + rname[-1]="r"+rname[-1] + rname = "/".join(rname) + cmd2 = ['cp',rname, str(di[StatToConvert[i_stat2conv]].fileName())] + line2 = runCmd(cmd2) + + os.remove(tempNameMNI2SB) + os.remove(rname) + os.remove(str(di[StatToConvert[i_stat2conv]].fileName())+".minf") + + write_filters = { 'center': protocol, 'acquisition': str(di[StatToConvert[i_stat2conv]].attributes()['acquisition']), 'subject' : str(patient) } + wdi_new = WriteDiskItem('Statistic-Data', 'NIFTI-1 image' )#'gz compressed NIFTI-1 image' ) + write_filters.update({'subacquisition':di[StatToConvert[i_stat2conv]].attributes()['subacquisition']}) + + di_new = wdi_new.findValue(write_filters) + + ret = subprocess.call(['AimsFileConvert', '-i', str(di[StatToConvert[i_stat2conv]].fileName()), '-o', str(di[StatToConvert[i_stat2conv]].fileName())]) + di[StatToConvert[i_stat2conv]].setMinf('MNI','False') + di[StatToConvert[i_stat2conv]].setMinf('ColorPalette','Yellow-Red-White-Blue-Green') + neuroHierarchy.databases.insertDiskItem( di[StatToConvert[i_stat2conv]], update=True ) + self.transfoManager.setReferentialTo(di[StatToConvert[i_stat2conv]], self.mriAcPc) + + else: + print "doesn't work with SPM8" + return + + self.setStatus(u"MNI to ScannerBased conversion of %s done"%str(di[StatToConvert[i_stat2conv]].fileName())) + + else: + print "no statistic data to convert from MNI to Scanner-Based" + + + + def generateAmygdalaHippoMesh(self, protocol, patient, acq, diFS): + + print("start generation of amygdala and hippocampus meshes") + #attention ça merde quand l'irm est trop haute résolution + + volDestrieux = aims.read(diFS.fullPath()) + npDestrieux = volDestrieux.arraydata() + + lefthippopx = numpy.where(npDestrieux==17) + notlefthippopx = numpy.where(npDestrieux!=17) + lefthippoposition = [[lefthippopx[1][i]*volDestrieux.getVoxelSize()[2],lefthippopx[2][i]*volDestrieux.getVoxelSize()[1],lefthippopx[3][i]*volDestrieux.getVoxelSize()[0]] for i in range(len(lefthippopx[1]))] + righthippopx = numpy.where(npDestrieux==53) + notrighthippopx = numpy.where(npDestrieux!=53) + righthippoposition = [[righthippopx[1][i]*volDestrieux.getVoxelSize()[2],righthippopx[2][i]*volDestrieux.getVoxelSize()[1],righthippopx[3][i]*volDestrieux.getVoxelSize()[0]] for i in range(len(righthippopx[1]))] + + leftamygdalapx = numpy.where(npDestrieux == 18) + notleftamygdalapx = numpy.where(npDestrieux != 18) + rightamygdalapx = numpy.where(npDestrieux == 54) + notrightamygdalapx = numpy.where(npDestrieux != 54) + + #add here a verification of number of pixel per parcels. if not enough, no point to generate a mesh + AmygdalaLeft = True + AmygdalaRight = True + HippoLeft = True + HippoRight = True + + if len(leftamygdalapx[0]) < 50: + AmygdalaLeft = False + if len(rightamygdalapx[0]) < 50: + AmygdalaRight = False + + if len(lefthippopx[0]) < 50: + HippoLeft = False + if len(righthippopx[0]) < 50: + HippoRight = False + + di = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':protocol, 'subject':patient } ) + allT1 = list(di.findValues({},None,False)) + idxT1pre = [i for i in range(len(allT1)) if 'pre' in str(allT1[i])] + self.storeImageReferentialsAndTransforms(allT1[idxT1pre[0]]) + constraints = { 'center': protocol, 'subject' :patient, 'acquisition':allT1[idxT1pre[0]].attributes()['acquisition'] } + + #il faudrait mettre le referentiel à freesurferatlas la aussi ça serait fait comme ça. + self.transfoManager.setReferentialTo(diFS, allT1[idxT1pre[0]].attributes()['referential'] ) + + if AmygdalaRight: + for ii in range(len(notrightamygdalapx[0])): + volDestrieux.setValue(0,notrightamygdalapx[3][ii],notrightamygdalapx[2][ii],notrightamygdalapx[1][ii]) + + aims.write(volDestrieux,'/tmp/rightamygdala.nii') + volDestrieux = aims.read(diFS.fullPath()) + wdirightamygdala = WriteDiskItem('rightAmygdala', 'GIFTI file' ) + dirightamygdala = wdirightamygdala.findValue(constraints) + if dirightamygdala is None: + print "mesh export : could not find valid path" + else: + if not os.path.isdir(os.path.dirname(dirightamygdala.fullPath())): + os.makedirs(os.path.dirname(dirightamygdala.fullPath())) + ret = subprocess.call(['AimsMeshBrain', '-i', '/tmp/rightamygdala.nii', '-o', dirightamygdala.fullPath()]) + neuroHierarchy.databases.insertDiskItem(dirightamygdala, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirightamygdala, allT1[idxT1pre[0]].attributes()['referential'] ) + + if AmygdalaLeft: + for ii in range(len(notleftamygdalapx[0])): + volDestrieux.setValue(0,notleftamygdalapx[3][ii],notleftamygdalapx[2][ii],notleftamygdalapx[1][ii]) + + aims.write(volDestrieux,'/tmp/leftamygdala.nii') + volDestrieux = aims.read(diFS.fullPath()) + wdileftamygdala = WriteDiskItem('leftAmygdala', 'GIFTI file' ) + dileftamygdala = wdileftamygdala.findValue(constraints) + if dileftamygdala is None: + print "mesh export : could not find valid path" + else: + if not os.path.isdir(os.path.dirname(dileftamygdala.fullPath())): + os.makedirs(os.path.dirname(dileftamygdala.fullPath())) + ret = subprocess.call(['AimsMeshBrain', '-i', '/tmp/leftamygdala.nii', '-o', dileftamygdala.fullPath()]) + neuroHierarchy.databases.insertDiskItem(dileftamygdala, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dileftamygdala, allT1[idxT1pre[0]].attributes()['referential'] ) + + #pour pouvoir decouper les hippocampes en deux + if isinstance(allT1[idxT1pre[0]].attributes()['SB_Transform'],basestring): + import ast + m = aims.Motion(ast.literal_eval(allT1[idxT1pre[0]].attributes()['SB_Transform'])) + else: + m = aims.Motion(allT1[idxT1pre[0]].attributes()['SB_Transform']) + + if HippoRight: + for ii in range(len(notrighthippopx[0])): + volDestrieux.setValue(0,notrighthippopx[3][ii],notrighthippopx[2][ii],notrighthippopx[1][ii]) + + aims.write(volDestrieux,'/tmp/righthippo.nii') + volDestrieux = aims.read(diFS.fullPath()) + wdirighthippo = WriteDiskItem('rightHippo', 'GIFTI file' ) + dirightHippo = wdirighthippo.findValue(constraints) + if dirightHippo is None: + print "mesh export : could not find valid path" + else: + if not os.path.isdir(os.path.dirname(dirightHippo.fullPath())): + os.makedirs(os.path.dirname(dirightHippo.fullPath())) + ret = subprocess.call(['AimsMeshBrain', '-i', '/tmp/righthippo.nii', '-o', dirightHippo.fullPath()]) + neuroHierarchy.databases.insertDiskItem(dirightHippo, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirightHippo, allT1[idxT1pre[0]].attributes()['referential'] ) + + wdirighthippoantero = WriteDiskItem('rightanteroHippocampus', 'GIFTI file' ) + wdirighthippopostero = WriteDiskItem('rightposteroHippocampus', 'GIFTI file' ) + dirighthippoantero = wdirighthippoantero.findValue(constraints) + dirighthippopostero = wdirighthippopostero.findValue(constraints) + + UU, ss, rotation, center = self.fitvolumebyellipse(righthippoposition) + + #comment deviner automatiquement quel bout est antero et quel bout est postero... + + mesh = aims.read(str(dirightHippo.fullPath())) + testhippocut = aims.AimsSurfaceTriangle() + testhippocut2 = aims.AimsSurfaceTriangle() + border = aims.AimsTimeSurface(2) + border2 = aims.AimsTimeSurface(2) + aims.SurfaceManip.cutMesh(mesh, [rotation[2,2], rotation[2,1], rotation[2,0], -numpy.inner(rotation[2,:],center)], testhippocut, border) + aims.SurfaceManip.cutMesh(mesh, [-rotation[2,2], -rotation[2,1], -rotation[2,0], numpy.inner(rotation[2,:],center)], testhippocut2, border2) + planmesh = aims.SurfaceManip.meshPlanarPolygon([rotation[2,2], rotation[2,1], rotation[2,0], -numpy.inner(rotation[2,:],center)], border) + planmesh2 = aims.SurfaceManip.meshPlanarPolygon([-rotation[2,2], -rotation[2,1], -rotation[2,0], numpy.inner(rotation[2,:],center)], border2) + + aims.SurfaceManip.meshMerge(testhippocut,planmesh) + aims.SurfaceManip.meshMerge(testhippocut2,planmesh2) + aims.write(testhippocut,'/tmp/testhippocut.gii') + aims.write(testhippocut2,'/tmp/testhippocut2.gii') + + #ret = subprocess.call(['AimsMeshCut', '-i', str(dirightHippo.fullPath()), '-o', '/tmp/testhippocut.gii', '-a',str(rotation[2,2]),'-b',str(rotation[2,1]),'-c',str(rotation[2,0]),'-d',str(-numpy.inner(rotation[2,:],center)),'-p','/tmp/testplan.nii']) + #ret = subprocess.call(['AimsMeshCut', '-i', str(dirightHippo.fullPath()), '-o', '/tmp/testhippocut2.gii', '-a',str(-rotation[2,2]),'-b',str(-rotation[2,1]),'-c',str(-rotation[2,0]),'-d',str(numpy.inner(rotation[2,:],center)),'-p','/tmp/testplan2.nii']) + + #equivalent à : test = aims.read(-numpy.inner(rotation[2,:],center)) truc = aims.AimsTimeSurface_2() bidule=aims.AimsTimeSurface() aims.SurfaceManip.cutMesh(test1,[rotation[2,2],rotation[2,1],rotation[2,0],-numpy.inner(rotation[2,:],center)],bidule,truc) aims.write(bidule,'/tmp/bidule.gii') + hippogii = aims.read('/tmp/testhippocut.gii') + hippovertex = numpy.array(hippogii.vertex().list()) + centerhippo = numpy.average(hippovertex,axis=0) + + hippogii2 = aims.read('/tmp/testhippocut2.gii') + hippovertex2 = numpy.array(hippogii2.vertex().list()) + centerhippo2 = numpy.average(hippovertex2,axis=0) + + coords1 = m.transform(centerhippo) + coords2 = m.transform(centerhippo2) + + if coords2[1] > coords1[1]: + #2 est l'antero; 1 est posterieur + if dirighthippoantero is None or dirighthippopostero is None: + print "mesh export : could not find valid path" + else: + cmd1 = ['mv', '/tmp/testhippocut2.gii', str(dirighthippoantero.fullPath())] + cmd2 = ['mv', '/tmp/testhippocut.gii', str(dirighthippopostero.fullPath())] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + neuroHierarchy.databases.insertDiskItem(dirighthippoantero, update = True) + neuroHierarchy.databases.insertDiskItem(dirighthippopostero, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirighthippoantero, allT1[idxT1pre[0]].attributes()['referential'] ) + self.transfoManager.setReferentialTo(dirighthippopostero, allT1[idxT1pre[0]].attributes()['referential'] ) + elif coords2[1] < coords1[1]: + #1 est l'antero; 2 est le posterieur + if dirighthippoantero is None or dirighthippopostero is None: + print "mesh export : could not find valid path" + else: + cmd1 = ['mv', '/tmp/testhippocut.gii', str(dirighthippoantero.fullPath())] + cmd2 = ['mv', '/tmp/testhippocut2.gii', str(dirighthippopostero.fullPath())] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + neuroHierarchy.databases.insertDiskItem(dirighthippoantero, update = True) + neuroHierarchy.databases.insertDiskItem(dirighthippopostero, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirighthippoantero, allT1[idxT1pre[0]].attributes()['referential'] ) + self.transfoManager.setReferentialTo(dirighthippopostero, allT1[idxT1pre[0]].attributes()['referential'] ) + + # aims.TimeTexture() puis AimsMeshParcellation2VolumeParcellation + if dirighthippoantero is not None and dirighthippopostero is not None: + #we read it, estimate the number of vertex, and attribute the good value to the good number of vertex + #nb vertex of right antero + voxel_size_T1 = [allT1[idxT1pre[0]].attributes()['voxel_size'][0], allT1[idxT1pre[0]].attributes()['voxel_size'][1], allT1[idxT1pre[0]].attributes()['voxel_size'][2], 1.0] + + hippo_vol_antero=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_postero=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_full=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_antero.header()['voxel_size']= voxel_size_T1 + hippo_vol_postero.header()['voxel_size']= voxel_size_T1 + hippo_vol_full.header()['voxel_size']= voxel_size_T1 + + wdirighthippoNII = WriteDiskItem('rightHippocampusNII', 'NIFTI-1 image' ) + dirightHippoNII = wdirighthippoNII.findValue(constraints) + + meshantero = aims.read(dirighthippoantero.fullName()) + meshpostero = aims.read(dirighthippopostero.fullName()) + aims.SurfaceManip.rasterizeMesh(meshantero,hippo_vol_antero,1) + aims.SurfaceManip.rasterizeMesh(meshpostero,hippo_vol_postero,1) + #fill the insides voxel + from scipy import ndimage + for zslices in range(hippo_vol_antero.arraydata().shape[1]): + hippo_vol_antero.arraydata()[0,zslices,:,:] = ndimage.morphology.binary_fill_holes(hippo_vol_antero.arraydata()[0,zslices,:,:]).astype(int) + + for zslices in range(hippo_vol_postero.arraydata().shape[1]): + hippo_vol_postero.arraydata()[0,zslices,:,:] = ndimage.morphology.binary_fill_holes(hippo_vol_postero.arraydata()[0,zslices,:,:]).astype(int) + + hippo_vol_antero *=5301 + hippo_vol_postero *= 5302 + hippo_vol_full = hippo_vol_antero + hippo_vol_postero + for z in xrange(hippo_vol_full.getSizeZ()): + for y in xrange(hippo_vol_full.getSizeY()): + for x in xrange(hippo_vol_full.getSizeX()): + if hippo_vol_full.value(x, y, z) >5302: + hippo_vol_full.setValue(5302, x, y, z) + + aims.write(hippo_vol_full,str(dirightHippoNII.fullPath())) + neuroHierarchy.databases.insertDiskItem(dirightHippoNII, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dirightHippoNII, allT1[idxT1pre[0]].attributes()['referential'] ) + + + if HippoLeft: + for ii in range(len(notlefthippopx[0])): + volDestrieux.setValue(0,notlefthippopx[3][ii],notlefthippopx[2][ii],notlefthippopx[1][ii]) + + aims.write(volDestrieux,'/tmp/lefthippo.nii') + wdilefthippo = WriteDiskItem('leftHippo', 'GIFTI file' ) + dileftHippo = wdilefthippo.findValue(constraints) + if dileftHippo is None: + print "mesh export : could not find valid path" + else: + if not os.path.isdir(os.path.dirname(dileftHippo.fullPath())): + os.makedirs(os.path.dirname(dileftHippo.fullPath())) + ret = subprocess.call(['AimsMeshBrain', '-i', '/tmp/lefthippo.nii', '-o', dileftHippo.fullPath()]) + neuroHierarchy.databases.insertDiskItem(dileftHippo, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dileftHippo, allT1[idxT1pre[0]].attributes()['referential'] ) + + wdilefthippoantero = WriteDiskItem('leftanteroHippocampus', 'GIFTI file' ) + wdilefthippopostero = WriteDiskItem('leftposteroHippocampus', 'GIFTI file' ) + dilefthippoantero = wdilefthippoantero.findValue(constraints) + dilefthippopostero = wdilefthippopostero.findValue(constraints) + + UU, ss, rotation, center = self.fitvolumebyellipse(lefthippoposition) + + #comment deviner automatiquement quel bout est antero et quel bout est postero... + mesh = aims.read(str(dileftHippo.fullPath())) + testhippocut = aims.AimsSurfaceTriangle() + testhippocut2 = aims.AimsSurfaceTriangle() + border = aims.AimsTimeSurface(2) + border2 = aims.AimsTimeSurface(2) + aims.SurfaceManip.cutMesh(mesh, [rotation[2,2], rotation[2,1], rotation[2,0], -numpy.inner(rotation[2,:],center)], testhippocut, border) + aims.SurfaceManip.cutMesh(mesh, [-rotation[2,2], -rotation[2,1], -rotation[2,0], numpy.inner(rotation[2,:],center)], testhippocut2, border2) + planmesh = aims.SurfaceManip.meshPlanarPolygon([rotation[2,2], rotation[2,1], rotation[2,0], -numpy.inner(rotation[2,:],center)], border) + planmesh2 = aims.SurfaceManip.meshPlanarPolygon([-rotation[2,2], -rotation[2,1], -rotation[2,0], numpy.inner(rotation[2,:],center)], border2) + + aims.SurfaceManip.meshMerge(testhippocut,planmesh) + aims.SurfaceManip.meshMerge(testhippocut2,planmesh2) + aims.write(testhippocut,'/tmp/testhippocut.gii') + aims.write(testhippocut2,'/tmp/testhippocut2.gii') + #ret = subprocess.call(['AimsMeshCut', '-i', str(dileftHippo.fullPath()), '-o', '/tmp/testhippocut.gii', '-a',str(rotation[2,2]),'-b',str(rotation[2,1]),'-c',str(rotation[2,0]),'-d',str(-numpy.inner(rotation[2,:],center))]) + #ret = subprocess.call(['AimsMeshCut', '-i', str(dileftHippo.fullPath()), '-o', '/tmp/testhippocut2.gii', '-a',str(-rotation[2,2]),'-b',str(-rotation[2,1]),'-c',str(-rotation[2,0]),'-d',str(numpy.inner(rotation[2,:],center))]) + + hippogii = aims.read('/tmp/testhippocut.gii') + hippovertex = numpy.array(hippogii.vertex().list()) + centerhippo = numpy.average(hippovertex,axis=0) + + hippogii2 = aims.read('/tmp/testhippocut2.gii') + hippovertex2 = numpy.array(hippogii2.vertex().list()) + centerhippo2 = numpy.average(hippovertex2,axis=0) + + coords1 = m.transform(centerhippo) + coords2 = m.transform(centerhippo2) + + if coords2[1] > coords1[1]: + #2 est l'antero; 1 est posterieur + if dilefthippoantero is None or dilefthippopostero is None: + print "mesh export : could not find valid path" + else: + cmd1 = ['mv', '/tmp/testhippocut2.gii', str(dilefthippoantero.fullPath())] + cmd2 = ['mv', '/tmp/testhippocut.gii', str(dilefthippopostero.fullPath())] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + neuroHierarchy.databases.insertDiskItem(dilefthippoantero, update = True) + neuroHierarchy.databases.insertDiskItem(dilefthippopostero, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dilefthippoantero, allT1[idxT1pre[0]].attributes()['referential'] ) + self.transfoManager.setReferentialTo(dilefthippopostero, allT1[idxT1pre[0]].attributes()['referential'] ) + elif coords2[1] < coords1[1]: + #1 est l'antero; 2 est le posterieur + if dilefthippoantero is None or dilefthippopostero is None: + print "mesh export : could not find valid path" + else: + cmd1 = ['mv', '/tmp/testhippocut.gii', str(dilefthippoantero.fullPath())] + cmd2 = ['mv', '/tmp/testhippocut2.gii', str(dilefthippopostero.fullPath())] + line1 = runCmd(cmd1) + line2 = runCmd(cmd2) + neuroHierarchy.databases.insertDiskItem(dilefthippoantero, update = True) + neuroHierarchy.databases.insertDiskItem(dilefthippopostero, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dilefthippoantero, allT1[idxT1pre[0]].attributes()['referential'] ) + self.transfoManager.setReferentialTo(dilefthippopostero, allT1[idxT1pre[0]].attributes()['referential'] ) + + if dilefthippoantero is not None and dilefthippopostero is not None: + #we read it, estimate the number of vertex, and attribute the good value to the good number of vertex + #nb vertex of right antero + voxel_size_T1 = [allT1[idxT1pre[0]].attributes()['voxel_size'][0], allT1[idxT1pre[0]].attributes()['voxel_size'][1], allT1[idxT1pre[0]].attributes()['voxel_size'][2], 1.0] + + hippo_vol_antero=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_postero=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_full=aims.Volume(*allT1[idxT1pre[0]].attributes()['volume_dimension'][:3],dtype='S16') + hippo_vol_antero.header()['voxel_size']= voxel_size_T1 + hippo_vol_postero.header()['voxel_size']= voxel_size_T1 + hippo_vol_full.header()['voxel_size']= voxel_size_T1 + + wdilefthippoNII = WriteDiskItem('leftHippocampusNII', 'NIFTI-1 image' ) + dileftHippoNII = wdilefthippoNII.findValue(constraints) + + meshantero = aims.read(dilefthippoantero.fullName()) + meshpostero = aims.read(dilefthippopostero.fullName()) + aims.SurfaceManip.rasterizeMesh(meshantero,hippo_vol_antero,1) + aims.SurfaceManip.rasterizeMesh(meshpostero,hippo_vol_postero,1) + #fill the insides voxel + from scipy import ndimage + for zslices in range(hippo_vol_antero.arraydata().shape[1]): + hippo_vol_antero.arraydata()[0,zslices,:,:] = ndimage.morphology.binary_fill_holes(hippo_vol_antero.arraydata()[0,zslices,:,:]).astype(int) + + for zslices in range(hippo_vol_postero.arraydata().shape[1]): + hippo_vol_postero.arraydata()[0,zslices,:,:] = ndimage.morphology.binary_fill_holes(hippo_vol_postero.arraydata()[0,zslices,:,:]).astype(int) + + hippo_vol_antero *=1701 + hippo_vol_postero *= 1702 + hippo_vol_full = hippo_vol_antero + hippo_vol_postero + for z in xrange(hippo_vol_full.getSizeZ()): + for y in xrange(hippo_vol_full.getSizeY()): + for x in xrange(hippo_vol_full.getSizeX()): + if hippo_vol_full.value(x, y, z) >1702: + hippo_vol_full.setValue(1702, x, y, z) + + aims.write(hippo_vol_full,str(dileftHippoNII.fullPath())) + neuroHierarchy.databases.insertDiskItem(dileftHippoNII, update = True) + if 'referential' in allT1[idxT1pre[0]].attributes().keys(): + self.transfoManager.setReferentialTo(dileftHippoNII, allT1[idxT1pre[0]].attributes()['referential'] ) + + + print "generation of amygdala and hippocamp meshes done" + self.setStatus(u"generation of amygdala and hippocamp meshes done") + + + def runFreesurferReconAll(self): + + proto = str(self.ui.regProtocolCombo.currentText()) + subj = str(self.ui.regSubjectCombo.currentText()) + images = self.findAllImagesForSubject(proto, subj) + # Find all images, normalize the T1s, find the T1pre if there is one, read image headers, store their referentials and transformations in the DB + t1preImage = None + FlairpreImage = None + T2preImage = None + FreesurferMethod = 0 + for image in images: + patient = image.attributes()['subject'] + acq = image.attributes()['acquisition'] + # Store Scanner-based referential and referential files in the DB + if acq.startswith('T1'): + # If there is a T1pre, remember the image + if acq.find('T1pre') == 0: + t1preImage = image + + elif acq.startswith('FLAIR'): + if acq.find('FLAIRpre') == 0: + FlairpreImage = image + + elif acq.startswith('T2'): + if acq.find('T2pre') == 0: + T2preImage = image + + # No T1pre : nothing else to do + if t1preImage is None: + print('no T1pre image') + return + + context = brainvisa.processes.defaultContext() + context.write("recon-all from freesurfer") + + if t1preImage and FlairpreImage: + FreesurferMethod = 1 + elif t1preImage and T2preImage: + FreesurferMethod = 2 + elif t1preImage: + FreesurferMethod = 0 + + #prevenir que freesurfer demarre dans la bare de tache + #il faut rajouter le test si le sujet exist déjà dans freesurfer il faut d'abord le supprimer pour pouvoir le relancer. + + if FreesurferMethod == 0: + try: + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath())) + except: + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj) + elif FreesurferMethod == 1: + try: + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath()),'-FLAIRpial', '-FLAIR', str(FlairpreImage.fullPath())) + except: + shutil.rmtree(os.path.join(configuration.freesurfer._get_subjects_dir_path(),subj)) + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath()),'-FLAIRpial', '-FLAIR', str(FlairpreImage.fullPath())) + elif FreesurferMethod == 2: + try: + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath()),'-T2pial', '-T2',str(T2preImage.fullPath())) + except: + shutil.rmtree(os.path.join(configuration.freesurfer._get_subjects_dir_path(),subj)) + launchFreesurferCommand(context, None, 'recon-all', '-all', '-subjid', subj ,'-i',str(t1preImage.fullPath()),'-T2pial', '-T2',str(T2preImage.fullPath())) + + self.importFSoutput(subject=subj) + + def runMarsAtlasFreesurfer(self): + + print("not finished") + return + pdb.set_trace() + + def fitvolumebyellipse(self,volumeposition): + + #cut the hippocampus in two: + # from https://github.com/minillinim/ellipsoid/blob/master/ellipsoid.py + tolerance = 0.015 + if len(volumeposition)>16000: + volumeposition = [volumeposition[x] for x in range(len(volumeposition)) if x & 1 ==0] + + volumeposition=numpy.array(volumeposition) + (N, dd) = numpy.shape(volumeposition) + dd = float(dd) + + # Q will be our working array + Q = numpy.vstack([numpy.copy(volumeposition.T), numpy.ones(N)]) + QT = Q.T + + # initializations + err = 1.0 + tolerance + u = (1.0 / N) * numpy.ones(N) + + # Khachiyan Algorithm + while err > tolerance: + V = numpy.dot(Q, numpy.dot(numpy.diag(u), QT)) + M = numpy.diag(numpy.dot(QT , numpy.dot(numpy.linalg.inv(V), Q))) # M the diagonal vector of an NxN matrix + j = numpy.argmax(M) + maximum = M[j] + step_size = (maximum - dd - 1.0) / ((dd + 1.0) * (maximum - 1.0)) + new_u = (1.0 - step_size) * u + new_u[j] += step_size + err = numpy.linalg.norm(new_u - u) + u = new_u + + # center of the ellipse + center = numpy.dot(volumeposition.T, u) + + # the A matrix for the ellipse + AA = numpy.linalg.inv(numpy.dot(volumeposition.T, numpy.dot(numpy.diag(u), volumeposition)) - numpy.array([[a * b for b in center] for a in center])) / dd + + # Get the values we'd like to return + UU, ss, rotation = numpy.linalg.svd(AA) + radii = 1.0/numpy.sqrt(ss) + + return UU, ss, rotation, center + + def setNormalizedToT1pre(self, image, registeredPath): + + ret = subprocess.call(['AimsFileConvert', '-i', str(registeredPath), '-o', str(image.fileName()), '-t', 'S16']) + if ret < 0: + print "Importation Error of the SPM resampled image : "+repr(registeredPath) + QtGui.QMessageBox.warning(self, "Error", u"The image has not been resampled by SPM !") + return + # TODO # Should destroy existing referentials for this image + # The referential of this image is the same as the T1 pre + self.transfoManager.setReferentialTo(image, registration.talairachMNIReferentialId) #replace self.getT1preNativeRef(image.attributes()['center'], image.attributes()['subject']) by talairachMNIReferentialId + #os.remove(registeredPath) + + + def taskfinished(self, message, threadObj=None): + """ When a task (thread) is finished, display the message and launch the waiting callbacks""" + self.setStatus(u"Task done : "+message) #+' : '+repr(threadObj) + if threadObj is None: + return + # Looking for callback functions waiting + #print "****** WAITING FOR THREADS *******\n"+repr(self.waitingForThreads) # DEBUG + toDelete = [] # Store the dictionary keys to delete (cannot be done while iterating on it) + for callback in self.waitingForThreads: + for thr in self.waitingForThreads[callback]: # All threads this callback is waiting for + if thr not in self.threads: # This one does not exist, it was probably deleted before the callback was set, so just remove it from the list + self.waitingForThreads[callback].remove(thr) + if threadObj in self.waitingForThreads[callback]: # This thread was in the list + self.waitingForThreads[callback].remove(threadObj) # So remove it ! + if self.waitingForThreads[callback] == []: # If there is no thread left + callback() # Call the function ! + toDelete.append(callback) + for tD in toDelete: + del self.waitingForThreads[tD] + + idx = self.threads.remove(threadObj) # Now remove the thread + + + def downloadPacs(self): + """ Import the selected images from the pacs to the Nifti output directory """ + pass + # Preference tab : set the SPM T1 template path + def setSpmTemplatePath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select SPM path") + if path is not None: + self.ui.prefSpmTemplateEdit.setText(path) + + def setANTsPath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select ANTs path") + if path is not None: + self.ui.prefANTsEdit.setText(path) + + def setFreesurferPath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select FREESURFER path") + if path is not None: + self.ui.prefFreesurferEdit.setText(path) + + def setNoDBFilePath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select path for file export not include in database") + if path is not None: + self.ui.prefNoDBFileLocationEdit.setText(path) + + def setSpmStandalonePath(self, path=None): + if path is None: + path = QtGui.QFileDialog.getExistingDirectory(self, u"Select SpmStandalone path") + if path is not None: + self.ui.prefSpmStandaloneEdit.setText(path) + + def setPrefCoregister(self,key): + + if key == 'ANTS': + if self.ui.prefANTScheckbox.isChecked(): + self.ui.prefSPMcheckbox.setCheckState(False) + self.ui.prefAimscheckbox.setCheckState(False) + + elif key == 'SPM': + if self.ui.prefSPMcheckbox.isChecked(): + self.ui.prefANTScheckbox.setCheckState(False) + self.ui.prefAimscheckbox.setCheckState(False) + + elif key == 'Aims': + if self.ui.prefAimscheckbox.isChecked(): + self.ui.prefANTScheckbox.setCheckState(False) + self.ui.prefSPMcheckbox.setCheckState(False) + + + def switchProjectButton(self): + projects= [self.ui.radioButtonProject.isChecked(),self.ui.radioButtonProject_2.isChecked(),self.ui.radioButtonProject_3.isChecked(),self.ui.radioButtonProject_4.isChecked()] + project_selected = [x for x in range(len(projects)) if projects[x]==True] + + self.prefs['projectSelected'] = project_selected + + ################################## Patient Information Tab ##################################### + def selectPatSubject(self, subj): + pass + + + ################################## SEEG Import Tab ##################################### + def selectSeegSubject(self, subj): + # Fill this from the database ReadDiskItems : {"MANIP_20-09-2012-2":ReadDiskItem, ...} + self.seegManips = {} + # Update the list of manips + self.ui.seegManipsBaseCombo.clear() + self.ui.seegManipsBaseCombo.addItems(self.seegManips.keys()) + + def manipSelected(self, manip): + self.ui.seegAvailableProcessingCombo.clear() + methods = seegprocessing.getProcessingMethods(seegprocessing.getManipNameFromDirName(str(manip))) + self.ui.seegAvailableProcessingCombo.addItems([method[0] + ' - '+method[1] for method in methods]) + + def chooseSeeg(self): + """Choose a SEEG file to import""" + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open SEEG File", "", "TRC SEEG file (*.trc)")) + print "Path of the TRC/EEG %s"%path + if not path: + return + self.ui.seegFileLabel.setText(path) + + def seegImport(self, subj = None, proto = None): + """Import a TRC file in the database, anonymize it and convert using ELAN""" + #QtGui.QMessageBox.warning(self, u'Erreur', u"L'importation de fichier SEEG n'est pas encore implémenté !") + path = str(self.ui.seegFileLabel.text()) + if not os.path.isfile(path): + print path + " is not a valid file !" + return + date = self.ui.seegAcqDate.date() + manip = str(self.ui.seegManipName.currentText()) + submanip = str(self.ui.seegSubmanipName.currentText()) + acq = str(self.ui.seegAcqCombo.currentText()) + + if proto is None: + proto = str(self.ui.seegProtocolCombo.currentText()) + if subj is None: + subj = str(self.ui.seegSubjectCombo.currentText()) + # Find the path in the DB + wdi = WriteDiskItem('Raw SEEG recording', 'EEG TRC format' ) + constraints = { 'center': proto, 'experiment': str(manip), 'subject' :subj } + + if len(submanip) > 0: + constraints['subexperiment'] = submanip + if len(acq) > 0: + constraints['expId'] = acq + di = wdi.findValue(constraints) + if di is None: + print "TRC import : could not find valid path" + + # Copy the file + #generate path + + #first I have to anonymize. + + if not os.path.exists(os.path.dirname(di.fullPath())): + try: + os.makedirs(os.path.dirname(di.fullPath())) + except: + print "can't generate folder" + + shutil.copyfile(path, di.fullPath()) + + # Anonymize in-place IL FAUDRAIT REDEMANDER LE NOM ET LE PRENOM DU PATIENT ? + self.anonymizeTRC_Sys98_t4(di.fullPath(),firstname=subj, lastname=subj) + + #anonymizeTRC.anonymizeTRC(di.fullPath(), lastname = subj) #firstname = str(self.ui.firstnameToRemove.text()), lastname = str(self.ui.lastnameToRemove.text()) + neuroHierarchy.databases.insertDiskItem(di, update=True ) + + def checkbox_comor(self): + if self.patientInfo['comoraucune'].isChecked(): + self.patientInfo['comorpsy'].setEnabled(False) + self.patientInfo['comorautre'].setEnabled(False) + self.patientInfo['comorneuro'].setEnabled(False) + else: + self.patientInfo['comorpsy'].setEnabled(True) + self.patientInfo['comorautre'].setEnabled(True) + self.patientInfo['comorneuro'].setEnabled(True) + + def update_patientAge(self): + patAge = self.patientInfo['patientBirthday'].date().daysTo( self.patientInfo['currentDate'].date())/365 + self.patientInfo['patientAge'].setText(str(patAge)) + + def ValidatePatInfo(self): + + patListToCheck = ['previousHistory','previousFamilyHistory','causaleDisease','mriLesion','comorneuro','comorpsy','comorautre'] + patpatListToCheck = {'Epilepsy':['Aura','TraitementTried','TraitementNow']} + + #read choice2 list from intersubject database + write_filters = { 'center': self.currentProtocol, 'subject' : self.currentSubject } + #pdb.set_trace() + wdi_global = ReadDiskItem('PatientInfoTemplate','Patient Template format') + di_global = list(wdi_global.findValues({}, None, False)) + + if len(di_global): + if os.path.isfile(str(di_global[0])): + print "read previous patienttemplate json" + from codecs import open as opencodecs + fin = opencodecs(str(di_global[0]),'r','latin1') + info_dicti = json.loads(fin.read().decode('latin1')) + fin.close() + + previous_lists_not_path = info_dicti['notPathoSpecific'] + previous_lists_path_full = info_dicti['PathoSpecific'] + previous_lists_path_protocol = info_dicti['PathoSpecific'][self.currentProtocol] + + else: + previous_lists_not_path = {} + previous_lists_path_full = {} + previous_lists_path_protocol = {} + + #register non pathology specific patient Info + PatInfo = {} + for kk, vv in self.patientInfo.iteritems(): + if isinstance(vv,QtGui.QDateEdit): + PatInfo.update({kk:unicode(vv.date().toPyDate())}) + if vv.date() == self.defaultAcqDate: + QtGui.QMessageBox.warning(self, "Error",u"The acquisition date is not valid ! " + kk) + return + elif isinstance(vv,QtGui.QComboBox): + #faire deux conditions lorsque c'est une liste checkable et lorsque non + if vv.model().item(1).isCheckable(): + item_checked = [unicode(vv.itemText(x)) for x in range(1,vv.count()) if vv.model().item(x).checkState()] + if len(item_checked) > 1: + if 'Inconnu' in item_checked or 'Aucun' in item_checked or 'Aucune' in item_checked: + QtGui.QMessageBox.warning(self, "Error",u"You can't have 'Inconnu' or 'Aucune' selected whith another choice, it doesn't make sens" + kk) + return + #c est une combo box editable du coup il faut verifier si il faut updater la liste des choix possibles + + else: + item_checked = unicode(vv.currentText()) + PatInfo.update({kk:item_checked}) + elif isinstance(vv,QtGui.QDialogButtonBox): + item_selected = [unicode(vv.children()[i].text()) for i in range(1,len(vv.children())) if vv.children()[i].isChecked()] + PatInfo.update({kk:item_selected}) + elif isinstance(vv,QtGui.QLineEdit): + PatInfo.update({kk:unicode(vv.text())}) + elif isinstance(vv,QtGui.QCheckBox): + PatInfo.update({kk:vv.isChecked()}) + else: + print "qtgui format not recognized" + #pdb.set_trace() + + patPatInfo = {} + for kk, vv in self.pathologypatientInfo.iteritems(): + if isinstance(vv,QtGui.QDateEdit): + patPatInfo.update({kk:unicode(vv.date().toPyDate())}) + if vv.date() == self.defaultAcqDate: + QtGui.QMessageBox.warning(self, "Error",u"The acquisition date is not valid ! " + kk) + return + elif isinstance(vv,QtGui.QComboBox): + #faire deux conditions lorsque c'est une liste checkable et lorsque non + if vv.model().item(1).isCheckable(): + item_checked = [unicode(vv.itemText(x)) for x in range(1,vv.count()) if vv.model().item(x).checkState()] + if len(item_checked) > 1: + if 'Inconnu' in item_checked or 'Aucun' in item_checked or 'Aucune' in item_checked: + QtGui.QMessageBox.warning(self, "Error",u"You can't have 'Inconnu' or 'Aucune' selected whith another choice, it doesn't make sens"+ kk) + return + else: + item_checked = unicode(vv.currentText()) + patPatInfo.update({kk:item_checked}) + elif isinstance(vv,QtGui.QDialogButtonBox): + item_selected = [unicode(vv.children()[i].text()) for i in range(1,len(vv.children())) if vv.children()[i].isChecked()] + patPatInfo.update({kk:item_selected}) + elif isinstance(vv,QtGui.QLineEdit): + patPatInfo.update({kk:unicode(vv.text())}) + elif isinstance(vv,QtGui.QCheckBox): + patPatInfo.update({kk:vv.isChecked()}) + else: + print "qtgui format not recognized" + #pdb.set_trace() + + + wdi = WriteDiskItem('SubjectInfo','Subject Information format') + di = wdi.findValue(write_filters) + if di is None: + print('Can t generate files') + return + + #pdb.set_trace() + full_dictio = {'notPathoSpecific':PatInfo,'PathoSpecific':patPatInfo} + fout = open(di.fullPath(),'w') + fout.write(json.dumps(full_dictio, ensure_ascii=False)) + #fout.write(json.dumps({'PathoSpecific':patPatInfo})) + fout.close() + + neuroHierarchy.databases.insertDiskItem(di, update=True ) + + #update patientinfo list si une nouvelle entree a ete ajoutée dans les choices list + wdi_global = WriteDiskItem('PatientInfoTemplate','Patient Template format') + di_global = wdi_global.findValue(write_filters) + + for ii in range(len(patListToCheck)): + if len(PatInfo[patListToCheck[ii]])>0: + previous_lists_not_path.update({patListToCheck[ii]:PatInfo[patListToCheck[ii]]}) + + for jj in range(len(patpatListToCheck[self.currentProtocol])): + if len(patPatInfo[patpatListToCheck[self.currentProtocol][jj]])>0: + previous_lists_path_protocol.update({patpatListToCheck[self.currentProtocol][jj]:patPatInfo[patpatListToCheck[self.currentProtocol][jj]]}) + + previous_lists_path_full.update({self.currentProtocol:previous_lists_path_protocol}) + full_dictio_inter = {'notPathoSpecific':previous_lists_not_path,'PathoSpecific':previous_lists_path_full} + + fout = open(di_global.fullPath(),'w') + fout.write(json.dumps(full_dictio_inter,ensure_ascii=False)) + fout.close() + neuroHierarchy.databases.insertDiskItem(di_global, update=True ) + + + def enable_disable_gadooption(self): + + if str(self.ui.niftiSeqType.currentText()) == 'T1': + self.ui.radioButtonGado.setEnabled(True) + self.ui.radioButtonNoGado.setEnabled(True) + else: + self.ui.radioButtonGado.setEnabled(False) + self.ui.radioButtonNoGado.setEnabled(False) + + + + def anonymizeTRC_Sys98_t4(filepath, firstname="No", lastname="Name", nowrite=False, overwriteMontage=True, overwriteUndocumentedElectrode = True): # Anonymize Micromed's System 98 type 4 TRC files + """ Anonymize Micromed's System 98 type 4 TRC files """ + fo=open(filepath, "r+b") # Open read-write binary mode + # should check for a TRC header ! + fo.seek(2) + headerTitle = fo.read(26) + fo.seek(175) + headerType = fo.read(1) + trcVersion = struct.unpack('B',headerType)[0] + if headerTitle != "MICROMED Brain-Quick file" or (trcVersion != 4 and trcVersion != 3): + print "Not a MICROMED System 98 Type 3/4 TRC file -> ignoring" + fo.close() + return False + fo.seek(64) # go to patient data offset in header + # get a 22-char string, padding with spaces, convert to integers and pack as 22 unsigned chars in little endian + if nowrite: + fo.close() + return True + fo.write(struct.pack('<22B',*[ord(a) for a in lastname[:22].ljust(22,' ')])) + # Same with 20 chars + fo.write(struct.pack('<20B',*[ord(a) for a in firstname[:20].ljust(20,' ')])) + # Same with date (3 unsigned chars, for example [10, 05, 72] for october 5th 1972 + fo.seek(107) + fo.write(struct.pack(' 128* 4-bytes values (the sample where themontage was changed when viewing) + # We can skip that, then MAX_HISTORY = 128 "specific montage" structures which are identical to the montages above. + # Description string starts at offset 264 of each montage structure and is 64 bytes long,, just like above. + for i in range(30): + newMontageName = "Montage History "+str(i) + fo.seek(historyOffs + 128*4 + sizeMontage*i+264) + desc = fo.read(64) + # To print description string : desc = f.read(64); print desc[:desc.find('\x00')] + if "".join(["\x00" for j in range(64)]) != desc: + fo.seek(historyOffs + 128*4 + sizeMontage*i+264) + fo.write(struct.pack('<64B',*[ord(a) for a in newMontageName.ljust(64,'\x00')])) + + # undocumented string in place of the last electrode in name in HISTORY : find history offset, + fo.seek(192) + if fo.read(8) != 'LABCOD ': + raise Exception ("Incorrect LABCOD header") + elecOffs = struct.unpack('I', fo.read(4))[0] + # There should be 640 electrode structures of 128 bytes. But the last one is not an electrode structure. It seems to be a 32 bits integer and a 64 bytes string that contains a montage name... + if overwriteUndocumentedElectrode: + fo.seek(elecOffs + 639*128 + 4) + fo.write(struct.pack('<64B',*[ord(a) for a in "undocumented montage".ljust(64,'\x00')])) + except: + print "Could not overwrite Montage name" + + fo.close() + return True + + + +if __name__ == "__main__": + print "!!!!!!!!please run ImageImport.py !!!!!!!!!" diff --git a/ImageImportWindow.ui b/ImageImportWindow.ui new file mode 100644 index 0000000..9076a27 --- /dev/null +++ b/ImageImportWindow.ui @@ -0,0 +1,2222 @@ + + + Dialog + + + + 0 + 0 + 809 + 736 + + + + Importation d'images pour BrainVisa + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Horizontal + + + + true + + + + 0 + 0 + + + + + false + + + + 4 + + + + BrainVisa + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + Images existing in the BrainVISA database + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocol + + + + + + + + + + Subjet + + + + + + + + + + + + + + + Delete selected image + + + + + + + Delete selected subject + + + + + + + + Add Patient + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Site (Grenoble, Lyon,...) + + + + + + + Patient entrance in the service + + + + + + + Patient Lastname + + + + + + + Patient Firstname + + + + + + + + + + + + + + 0 + 0 + + + + true + + + + Gre + + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 40 + 20 + + + + + + + + + + + + 1900 + + + 10000 + + + 2013 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 139 + + + + + + + + + + Protocol + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Name in the Database + + + + + + + + 0 + 0 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 172 + + + + + + + + Add subject (in the local Database) + + + false + + + + + + + Add subject to distant database (F-Tract ou Neuropsynov database) + + + + + frame + subjectAddSubjectButton + verticalSpacer_4 + verticalSpacer_5 + subjectAddProjectDatabase + + + + Infos Patient + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocol + + + + + + + + + + Subjet + + + + + + + + + + + + + 0 + 0 + + + + Information générale: + + + + + + + Information spécifique pathologie: + + + + + + + Validate Patient Information + + + + + + + + Importation NIFTI + + + + + + + 10 + 75 + true + + + + Import a NIFTI image or a MGZ image + + + + + + + Choose a file + + + + + + + Import Freesurfer outputs + + + + + + + + 0 + 0 + + + + + + + + + + + + + Protocol + + + + + + + + + + + + + + Patient + + + + + + + + + + + + + + Acquisition Date + + + + + + + + 1790 + 9 + 14 + + + + dd/MM/yyyy + + + + 1950 + 1 + 1 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + T1 + + + + + T2 + + + + + CT + + + + + PET + + + + + fMRI + + + + + Statistics + + + + + FLAIR + + + + + FGATIR + + + + + FreesurferAtlas + + + + + HippoFreesurferAtlas + + + + + DTI - volume + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + pre + + + + + post + + + + + postOp + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + NoGado + + + true + + + + + + + WithGado + + + + + + + + + + + Cliquer sur le centre du cerveau dans l'image puis cliquer sur ce bouton + + + Position Brain Center + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Import in BrainVisa database + + + + + + + Qt::Vertical + + + + 20 + 366 + + + + + + + + + Coregistration and Normalization + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocol + + + + + + + + + + Subjet + + + + + + + + + + + + + + + + + + Resample images (original images will be lost) + + + + + + + true + + + Coregister subject images and normalize the T1 + + + + + + + Run only Segmentation and Hip Hop + + + + + + + Run Freesurfer Recon-All (can take up to 24 hours) + + + + + + + Run Hip Hop on Freesurfer Mesh + + + + + + + + + + + Cliquez sur la commissure antérieure, puis sur ce bouton + + + AC + + + + + + + Cliquez sur un point interhémisphérique au-dessus de CA-CP, puis sur ce bouton + + + IH + + + + + + + Cliquez sur la commissure postérieure, puis sur ce bouton + + + PC + + + + + + + Cliquez dans l'hémisphère gauche (droite de l'image si l'importation a bien fonctionné), puis sur ce bouton + + + LH + + + + + + + + + + + true + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Si AC, PC, IH et LH ont été entrés, lance la segmentation du cerveau + + + Validate + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + false + + + Choisir cette image pour la normalisation vers le template MNI + + + + + + + + Preferences... + + + + + + + + + + + ... + + + + + + + + + + Path spm12 standalone + + + + + + + + + + ... + + + + + + + Nifti folder: + + + + + + + true + + + + + + + ... + + + + + + + ... + + + + + + + ANTs + + + true + + + + + + + Path spm12 + + + + + + + spm + + + + + + + Coregister Method + + + + + + + + + + Path ANTs + + + + + + + true + + + + + + + Dicom folder: + + + + + + + ... + + + + + + + Project + + + + + + + F-Tract + + + + + + + NeuroPsynov + + + + + + + Classic + + + + + + + Other + + + + + + + Aims + + + + + + + + + + Path FreeSurfer + + + + + + + ... + + + + + + + Not databased file location + + + + + + + ... + + + + + + + + + + + + Save Preferences + + + + + + + Qt::Vertical + + + + 20 + 516 + + + + + + + + + Importation SEEG + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocole + + + + + + + + + + Sujet + + + + + + + + + + + + Choisir un fichier SEEG (TRC ou EEG)... + + + + + + + + 0 + 0 + + + + + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + Date de manip + + + + + + + + 1790 + 9 + 14 + + + + dd/MM/yyyy + + + + 1950 + 1 + 1 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Nom de manip : + + + + + + + true + + + + LEC1 + + + + + VISU + + + + + + + + Acquisition (n°, "postcrise"...) + + + + + + + Nom de sous-manip + + + + + + + true + + + + + + + true + + + + + + + + + Importer dans BrainVisa + + + + + + + Qt::Vertical + + + + 20 + 180 + + + + + + + + + + Manips déjà importées + + + + + + + + + + + + Traitements disponibles: + + + + + + + + + + Lancer le traitement + + + + + + + Lancer tous les traitements pour la manip sélectionnée + + + + + + + Lancer tous les traitements pour toutes les manips + + + + + + + + Implantation + + + + + + + 10 + 75 + true + + + + Importation des scans du schéma d'implantation + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + Protocole + + + + + + + + + + Sujet + + + + + + + + + + + + + + + 75 + true + + + + Image Coronale : + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Absente + + + + + + + Ouvrir une image... + + + + + + + Importer + + + + + + + + 75 + true + + + + Image sagittale : + + + + + + + + 0 + 0 + + + + Absente + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ouvrir une image... + + + + + + + Importer + + + + + + + + 75 + true + + + + Rapport Powerpoint + + + + + + + + 75 + true + + + + Schéma d'implantation sans le nom des électrodes (issu des médecins) + + + Schéma PDF + + + + + + + + 0 + 0 + + + + Absent + + + + + + + + 0 + 0 + + + + Absent + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ouvrir un ppt... + + + + + + + Ouvrir un PDF... + + + + + + + Importer + + + + + + + Importer + + + + + + + Absent + + + + + + + + 75 + true + + + + Schéma d'implantation avec le nom des électrodes + + + Schéma Impl. PDF + + + + + + + + 75 + true + + + + Liste Electrodes PDF + + + + + + + Absent + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ouvrir un PDF... + + + + + + + Importer + + + + + + + Ouvrir un PDF... + + + + + + + Importer + + + + + + + + + Qt::Vertical + + + + 20 + 403 + + + + + + + + + Importation dossier DICOM + + + + + + + 10 + 75 + true + + + + Importation d'images depuis un dossier DICOM + + + + + + + Choisir un dossier... + + + + + + + Sélection du Patient + + + + + + + QAbstractItemView::MultiSelection + + + + + + + Sélection de l'examen (study) + + + + + + + QAbstractItemView::MultiSelection + + + + + + + Sélection de la séquence (serie) + + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + T1 + + + + + T2 + + + + + CT-scanner + + + + + TEP + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + pre + + + + + post + + + + + postOp + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 1. Importer et convertir en NIFTI + + + + + + + 2. Importer dans BrainVisa + + + + + + + + Importation PACS + + + + + + + 10 + 75 + true + + + + Importation d'images depuis un serveur d'image PACS + + + + + + + + + Serveur + + + + + + + + + + + + + + Port + + + + + + + 65535 + + + 5000 + + + + + + + + + + + AETitle + + + + + + + + + + + + + + Nom du patient + + + + + + + + + + + + Rechercher + + + + + + + Sélection du Patient + + + + + + + QAbstractItemView::MultiSelection + + + + + + + Sélection de l'examen (study) + + + + + + + QAbstractItemView::MultiSelection + + + + + + + Sélection de la séquence (serie) + + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + T1 + + + + + T2 + + + + + CT-scanner + + + + + TEP + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + pre + + + + + post + + + + + postOp + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 1. Importer et convertir en NIFTI + + + + + + + 2. Importer dans BrainVisa + + + + + + + + + + 0 + 0 + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + + + + + + diff --git a/ImportTheoreticalImplentation.py b/ImportTheoreticalImplentation.py new file mode 100644 index 0000000..b033ea4 --- /dev/null +++ b/ImportTheoreticalImplentation.py @@ -0,0 +1,87 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import sys, os, pickle,numpy, re, string, json, csv, pdb + + +from PyQt4 import QtGui, QtCore, uic, Qt + + + +#self.connect(self.ImportTheoriticalImplantation,QtCore.SIGNAL('clicked()'),self.importRosaImplantation) + + +def importRosaImplantation(locate_env): + fichierRosa = QtGui.QFileDialog.getOpenFileName(locate_env, "Select a file containing electrode coordinates: ", "", "(*.ros )") + electrodes = ecritureCSVetJSON(fichierRosa) + + return electrodes + + +def ecritureCSVetJSON(fichier): + target=[] + nomElec=[] + entry=[] + electrodes={} + kv="" + i=0 + j=0 + + a=open(fichier,"rU") + fjson=open("electrodes.json","w") + + line=a.readlines() + pdb.set_trace() + line0=[nb for nb in line if len(nb)>50] + line1=[nb for nb in line0 if (re.findall("([a-z])",nb[0].lower())!=None) and (nb[2]==" " or nb[1]==" ")] + + + while j c #F05C17", +", c #F05C16", +"' c #F48D59", +") c #EE5004", +"! c #EE4900", +"~ c #F59565", +"{ c #EF530B", +"] c #EE4800", +"^ c #F9BFA2", +"/ c #EE4A00", +"( c #F9C2A6", +"_ c #EE4C00", +": c #EE4B00", +"< c #F8B796", +"[ c #F4844C", +"} c #F05910", +"| c #FDE9DE", +"1 c #FBD5C0", +"2 c #F69B6F", +"3 c #FDEFE6", +"4 c #FCDAC9", +"5 c #EF5003", +"6 c #F4844D", +"7 c #FCE4D6", +"8 c #FDE6D9", +"9 c #FDEDE4", +"0 c #FBCFB8", +"a c #FEF6F2", +"b c #EE4500", +"c c #EF5209", +"d c #F6A279", +"e c #FEEEE5", +"f c #EF5A13", +"g c #F8AC86", +"h c #F4854E", +"i c #FEF9F6", +"j c #F05E19", +"k c #EF5207", +"l c #FEFAF6", +"m c #F05F18", +"n c #EF4E02", +"o c #FBD1BB", +"p c #FFFEFD", +"q c #FBD9C7", +"r c #FCDBC7", +"s c #FBBE99", +"t c #FEF2EA", +"u c #FEFCF9", +"v c #F8B999", +"w c #F8B695", +"x c #F3793E", +"y c #FBD6C4", +"z c #F7A880", +"A c #EF5811", +"B c #F0601C", +"C c #F26C2D", +"D c #EE4F04", +"E c #F4834C", +"F c #F8A673", +"G c #FAB184", +"H c #FBC29E", +"I c #F26F2E", +"J c #EE4F05", +"K c #FCDFD0", +"L c #EE4D01", +"M c #F7A378", +"N c #FACBB5", +"O c #F06320", +"P c #EF5208", +"Q c #FCD4BC", +"R c #FAB78E", +"S c #FEEDE2", +"T c #F48149", +"U c #F58D5B", +"V c #F9BFA3", +"W c #F5905F", +"X c #F8B797", +"Y c #FEF1EA", +"Z c #FCDCCB", +"` c #F26E2F", +" . c #F8AD87", +".. c #FEFFFF", +"+. c #FCE4D8", +"@. c #FEF4EF", +"#. c #FCE2D4", +"$. c #F69B6E", +"%. c #EF5108", +"&. c #F05D19", +"*. c #EF540B", +"=. c #F48954", +"-. c #F9C1A4", +";. c #F8B28F", +">. c #FEF6F0", +",. c #FEFAF8", +"'. c #FBBD95", +"). c #FCBD95", +"!. c #FEF8F3", +"~. c #FCDBC9", +"{. c #FDEADF", +"]. c #F8A67E", +"^. c #EE4E02", +"/. c #EF530A", +"(. c #F05D16", +"_. c #FEF7F1", +":. c #EF5107", +"<. c #F06422", +"[. c #F16523", +"}. c #FFFDFA", +"|. c #F16E2E", +"1. c #EF550D", +"2. c #EF5913", +"3. c #EE4E01", +"4. c #FDE7DB", +"5. c #F5996B", +"6. c #F59463", +"7. c #FEECE0", +"8. c #FBB991", +"9. c #FCBC95", +"0. c #FEE8DA", +"a. c #F8AF8A", +"b. c #EE4C01", +"c. c #FBD2BC", +"d. c #FDEBE1", +"e. c #F16422", +"f. c #F05D18", +"g. c #F4824A", +"h. c #EF540A", +"i. c #F06321", +"j. c #EE4F03", +"k. c #FBCFBA", +"l. c #F69F73", +"m. c #F59161", +"n. c #FDE4D3", +"o. c #FDE2D0", +"p. c #F37A3F", +"q. c #FACEB7", +"r. c #EF560E", +"s. c #F0611E", +"t. c #F26D2B", +"u. c #F8B18D", +"v. c #EE4D02", +"w. c #F05B15", +"x. c #EE5005", +"y. c #F79E72", +"z. c #FAC7AF", +"A. c #F05F1B", +"B. c #F37C42", +"C. c #F7A379", +"D. c #F69566", +"E. c #FEF4ED", +"F. c #F59A6D", +"G. c #F59465", +"H. c #FDE6DA", +"I. c #F0621F", +"J. c #F6A57B", +"K. c #F7A77F", +"L. c #F05911", +"M. c #F05A14", +"N. c #FDEBE0", +"O. c #F16A28", +"P. c #F3773C", +"Q. c #FFFCFA", +"R. c #F7A57D", +"S. c #F6A076", +"T. c #FDEBDF", +"U. c #FDEEE5", +"V. c #FDE6D6", +"W. c #FDDECB", +"X. c #FFFBF8", +"Y. c #EF5309", +"Z. c #F05D17", +"`. c #FDE5D9", +" + c #F27437", +".+ c #F0621C", +"++ c #FCE1D1", +"@+ c #FCE5D7", +"#+ c #FFFDFB", +"$+ c #F69E72", +"%+ c #F58E5C", +"&+ c #FBD9C6", +"*+ c #F05B16", +"=+ c #F2793D", +"-+ c #FEFCFA", +";+ c #F8AE80", +">+ c #F9A97A", +",+ c #F9AA7B", +"'+ c #FAB891", +")+ c #FDDFCC", +"!+ c #FAB385", +"~+ c #FAB58C", +"{+ c #FCCAAA", +"]+ c #FFFFFE", +"^+ c #FEF4EE", +"/+ c #F8B18E", +"(+ c #EF5912", +"_+ c #F59363", +":+ c #F16926", +"<+ c #F27538", +"[+ c #F0560E", +"}+ c #FBC5A4", +"|+ c #F8AC7D", +"1+ c #FAB287", +"2+ c #FAB288", +"3+ c #F9AE81", +"4+ c #FCD8C0", +"5+ c #FAB68A", +"6+ c #FCC19D", +"7+ c #FCCBAC", +"8+ c #FCC8A6", +"9+ c #FDE4D4", +"0+ c #FEFAF7", +"a+ c #F9BEA1", +"b+ c #EF5710", +"c+ c #F6986B", +"d+ c #F16927", +"e+ c #EF5105", +"f+ c #F9B694", +"g+ c #F6986A", +"h+ c #EF560F", +"i+ c #F7AD88", +"j+ c #F05F1A", +"k+ c #F16C2C", +"l+ c #FABB95", +"m+ c #FAB289", +"n+ c #F9B185", +"o+ c #FBCEB1", +"p+ c #FCCDAE", +"q+ c #FEF7F2", +"r+ c #FCC9A8", +"s+ c #FCC9A7", +"t+ c #FDE1CE", +"u+ c #F16825", +"v+ c #EE4E03", +"w+ c #F48853", +"x+ c #F05F19", +"y+ c #EF570F", +"z+ c #F2773C", +"A+ c #F06421", +"B+ c #FDE5D7", +"C+ c #F2773A", +"D+ c #F48E5A", +"E+ c #F37639", +"F+ c #F15F18", +"G+ c #FBD7C4", +"H+ c #EF550C", +"I+ c #EF5006", +"J+ c #F05E18", +"K+ c #FCE1D0", +"L+ c #F7A572", +"M+ c #F9AF83", +"N+ c #F9B084", +"O+ c #F9A978", +"P+ c #FEF1E9", +"Q+ c #FEFBF9", +"R+ c #FDEEE3", +"S+ c #F9BA9A", +"T+ c #F8B492", +"U+ c #FEFBF8", +"V+ c #FCDAC8", +"W+ c #F7A780", +"X+ c #EF5810", +"Y+ c #F8B491", +"Z+ c #F7A37A", +"`+ c #EF5106", +" @ c #F06220", +".@ c #FFFAF5", +"+@ c #FDE3D2", +"@@ c #FABD98", +"#@ c #FAC19E", +"$@ c #FEEDE4", +"%@ c #FBDBCA", +"&@ c #F8B08C", +"*@ c #F37E44", +"=@ c #F26D2C", +"-@ c #F05207", +";@ c #FFDECD", +">@ c #FF9C63", +",@ c #FF691D", +"'@ c #FF6A1E", +")@ c #FFAA77", +"!@ c #FFD7BD", +"~@ c #FF5E12", +"{@ c #FC6924", +"]@ c #F96824", +"^@ c #F56623", +"/@ c #EF5005", +"(@ c #FBDCCA", +"_@ c #FFFCFB", +":@ c #F9C2A7", +"<@ c #FCDDCD", +"[@ c #FFF1E7", +"}@ c #FD641B", +"|@ c #FF6920", +"1@ c #FFA879", +"2@ c #E6F3F9", +"3@ c #B5B4B4", +"4@ c #8B8A89", +"5@ c #6D6C6C", +"6@ c #484645", +"7@ c #323030", +"8@ c #28292A", +"9@ c #111B21", +"0@ c #080C0F", +"a@ c #000609", +"b@ c #00090E", +"c@ c #111010", +"d@ c #1B1A1A", +"e@ c #2D2D2C", +"f@ c #3B3C3D", +"g@ c #5B473D", +"h@ c #6F290A", +"i@ c #984016", +"j@ c #B94D1C", +"k@ c #E45D1F", +"l@ c #FF6E24", +"m@ c #FEE4D7", +"n@ c #FCD2B8", +"o@ c #FAB486", +"p@ c #FAB48A", +"q@ c #FCC5A2", +"r@ c #FDCEB0", +"s@ c #FEE7D8", +"t@ c #FEFFFE", +"u@ c #EF4F03", +"v@ c #F58C59", +"w@ c #FFFEFC", +"x@ c #FACDB6", +"y@ c #E2E5E8", +"z@ c #979C9E", +"A@ c #4E2E1F", +"B@ c #0F0805", +"C@ c #000000", +"D@ c #1A1919", +"E@ c #575555", +"F@ c #969595", +"G@ c #DCE9EE", +"H@ c #FF732B", +"I@ c #FF6A20", +"J@ c #FF6B25", +"K@ c #F76723", +"L@ c #FDE1D3", +"M@ c #FEF3EC", +"N@ c #FDEEE4", +"O@ c #FDE5D6", +"P@ c #FAB286", +"Q@ c #FABD94", +"R@ c #FABC96", +"S@ c #FBB990", +"T@ c #FCD1B6", +"U@ c #FCBD96", +"V@ c #FCC7A4", +"W@ c #FCC09A", +"X@ c #FFFAF7", +"Y@ c #FDEADE", +"Z@ c #FCD3B6", +"`@ c #FDE0CB", +" # c #F2763B", +".# c #FEEFE7", +"+# c #F9C2A8", +"@# c #FDE7DA", +"## c #F37C41", +"$# c #EF5812", +"%# c #F15F1B", +"&# c #FB6219", +"*# c #AAA8A8", +"=# c #4B4A4A", +"-# c #301408", +";# c #7F3513", +"># c #D3581F", +",# c #FF6516", +"'# c #FFD1B3", +")# c #F9B58C", +"!# c #F8A16E", +"~# c #F8A573", +"{# c #F8AA7B", +"]# c #E7E6E7", +"^# c #FCD3BA", +"/# c #FBBD94", +"(# c #FABC97", +"_# c #FCC4A1", +":# c #FEFCFB", +"<# c #FCBE96", +"[# c #FCC5A0", +"}# c #FCC19C", +"|# c #FFFEFE", +"1# c #FDDECA", +"2# c #FCD5BB", +"3# c #F6A278", +"4# c #F16724", +"5# c #FAC6AC", +"6# c #F16A29", +"7# c #FBD4C0", +"8# c #F9C0A3", +"9# c #F7A479", +"0# c #FB9766", +"a# c #FF7834", +"b# c #FF935A", +"c# c #AD9E95", +"d# c #3A3D3F", +"e# c #020101", +"f# c #2B1106", +"g# c #57230A", +"h# c #81888B", +"i# c #9E9FA0", +"j# c #B4B2B1", +"k# c #D6D6D6", +"l# c #D9D7D6", +"m# c #E6E3E3", +"n# c #E8E9EA", +"o# c #E9F1F6", +"p# c #DEE8ED", +"q# c #D8DEE1", +"r# c #C8C8C8", +"s# c #AAA8A7", +"t# c #6D6B6A", +"u# c #4D4C4C", +"v# c #1F1D1D", +"w# c #594E4A", +"x# c #C3C3C3", +"y# c #FCD0B6", +"z# c #F8A372", +"A# c #F8AB7E", +"B# c #F8AA7C", +"C# c #171515", +"D# c #444242", +"E# c #FEEDE3", +"F# c #FAB083", +"G# c #FABC93", +"H# c #FABC95", +"I# c #FBB78D", +"J# c #FDD9C2", +"K# c #FEFDFC", +"L# c #FDE8D9", +"M# c #F0601D", +"N# c #F05F1C", +"O# c #F05B14", +"P# c #F2FCFF", +"Q# c #677379", +"R# c #000001", +"S# c #3A3939", +"T# c #868586", +"U# c #CAD2D6", +"V# c #FA7333", +"W# c #FF6D23", +"X# c #FF6E26", +"Y# c #FF7632", +"Z# c #FFF3EA", +"`# c #FB9F71", +" $ c #FB9562", +".$ c #FFCBAF", +"+$ c #FEFDFD", +"@$ c #C2C1C0", +"#$ c #838181", +"$$ c #403F3E", +"%$ c #595757", +"&$ c #D1D6DA", +"*$ c #FFD8B3", +"=$ c #FFB280", +"-$ c #FCAE80", +";$ c #F8AD80", +">$ c #F9AB7B", +",$ c #C1BFBF", +"'$ c #FDE3D4", +")$ c #FBBC93", +"!$ c #FAB991", +"~$ c #FCD5BC", +"{$ c #FEF6F1", +"]$ c #F9B999", +"^$ c #F58F5C", +"/$ c #FEF2EB", +"($ c #D8D7D6", +"_$ c #373535", +":$ c #110703", +"<$ c #777D7E", +"[$ c #D7DEE1", +"}$ c #FFBA97", +"|$ c #F25912", +"1$ c #F7AB85", +"2$ c #FCDECE", +"3$ c #F58E5B", +"4$ c #EEEDED", +"5$ c #989797", +"6$ c #41403F", +"7$ c #030000", +"8$ c #825942", +"9$ c #FFB082", +"0$ c #FFBE8D", +"a$ c #FFAE7E", +"b$ c #FABF9B", +"c$ c #474545", +"d$ c #F7AF8B", +"e$ c #F1631E", +"f$ c #F05E1A", +"g$ c #F0611D", +"h$ c #F4570D", +"i$ c #DEDFDF", +"j$ c #282726", +"k$ c #00060B", +"l$ c #6E3115", +"m$ c #DF5D20", +"n$ c #FF671E", +"o$ c #FFD0B6", +"p$ c #F58E5D", +"q$ c #F26C2B", +"r$ c #FDE5D8", +"s$ c #F9BC9E", +"t$ c #C6C4C4", +"u$ c #5F5E5E", +"v$ c #493124", +"w$ c #D99E7C", +"x$ c #796860", +"y$ c #FFFBEC", +"z$ c #FDE1CF", +"A$ c #FDDAC3", +"B$ c #FEF0E6", +"C$ c #FDD7C0", +"D$ c #FEF3EB", +"E$ c #F26E2E", +"F$ c #F04F03", +"G$ c #FF7A36", +"H$ c #FADFD1", +"I$ c #3F4446", +"J$ c #2A2827", +"K$ c #BBC1C5", +"L$ c #FFDCBF", +"M$ c #FF6116", +"N$ c #F66723", +"O$ c #FDE8DD", +"P$ c #F7A47B", +"Q$ c #F69E73", +"R$ c #F9C3A8", +"S$ c #FAC9AF", +"T$ c #F05810", +"U$ c #C9C8C7", +"V$ c #514F4F", +"W$ c #252525", +"X$ c #C5C4C3", +"Y$ c #999A9B", +"Z$ c #F3A97C", +"`$ c #FFD4B8", +" % c #FBC39D", +".% c #FCC09B", +"+% c #FCC29F", +"@% c #FCBE97", +"#% c #FEE5D5", +"$% c #FDEDE1", +"%% c #FCD0B4", +"&% c #FCCFB1", +"*% c #7D888D", +"=% c #3D3C3B", +"-% c #E3E2E2", +";% c #F47B40", +">% c #F16C2B", +",% c #F27030", +"'% c #9C9B9A", +")% c #151413", +"!% c #18191A", +"~% c #DEC2B2", +"{% c #2A1A12", +"]% c #2D201A", +"^% c #FFC692", +"/% c #FDE8DB", +"(% c #FBBE97", +"_% c #FDC5A3", +":% c #FDC6A4", +"<% c #FDC6A3", +"[% c #FCC6A3", +"}% c #FCCEB0", +"|% c #FCD3B7", +"1% c #FFFCF9", +"2% c #FBD7C3", +"3% c #F37F45", +"4% c #FBCFB9", +"5% c #DCDADA", +"6% c #060606", +"7% c #333739", +"8% c #E8E9E9", +"9% c #F6996B", +"0% c #F37B40", +"a% c #F59668", +"b% c #EF4D00", +"c% c #F58C58", +"d% c #EF5004", +"e% c #D5D4D3", +"f% c #3D3C3C", +"g% c #0F0907", +"h% c #B67E5E", +"i% c #FFFFFB", +"j% c #FDEADD", +"k% c #FBBD96", +"l% c #FDE7D8", +"m% c #FEFEFC", +"n% c #FEEFE4", +"o% c #FBD6C3", +"p% c #FACAB0", +"q% c #FBD6C2", +"r% c #FDF0E8", +"s% c #6F6D6C", +"t% c #0A1418", +"u% c #C8A18E", +"v% c #FFECD6", +"w% c #F9C2A5", +"x% c #FDECE2", +"y% c #F6996C", +"z% c #F48B58", +"A% c #FCE4D7", +"B% c #F0580F", +"C% c #FAB48D", +"D% c #F89862", +"E% c #F89A65", +"F% c #F89E6A", +"G% c #FDE3D3", +"H% c #686666", +"I% c #FBC7A4", +"J% c #FCBF99", +"K% c #FCC29E", +"L% c #FEEBDF", +"M% c #FCDAC2", +"N% c #FCDCC6", +"O% c #FDEFE4", +"P% c #FAC7AD", +"Q% c #F05A13", +"R% c #EE4D00", +"S% c #FFCAAD", +"T% c #131211", +"U% c #857D79", +"V% c #FF7E39", +"W% c #F95F16", +"X% c #FBD5C2", +"Y% c #F7A87F", +"Z% c #F0570E", +"`% c #FACBB3", +" & c #F0621E", +".& c #F7AA84", +"+& c #FABA94", +"@& c #F89A66", +"#& c #F8A373", +"$& c #F9A474", +"%& c #F8A474", +"&& c #F79964", +"*& c #898888", +"=& c #706F6F", +"-& c #3C3939", +";& c #6E6C6D", +">& c #FDE1D0", +",& c #FDE5D5", +"'& c #FCDEC9", +")& c #FCDCC4", +"!& c #FFFAF6", +"~& c #FACDB5", +"{& c #FEFAF5", +"]& c #F0621D", +"^& c #FF671C", +"/& c #C19782", +"(& c #191717", +"_& c #F5FFFF", +":& c #FF8C50", +"<& c #F15E1A", +"[& c #EF5308", +"}& c #FEF0E7", +"|& c #F9BD9E", +"1& c #F3834D", +"2& c #F4834E", +"3& c #F9BEA0", +"4& c #F59769", +"5& c #F0631F", +"6& c #F16826", +"7& c #F8B592", +"8& c #F89863", +"9& c #F8A171", +"0& c #F9A575", +"a& c #F9A675", +"b& c #F8A170", +"c& c #FBCAAE", +"d& c #3A3839", +"e& c #F0DDD3", +"f& c #FFB98B", +"g& c #FAB78F", +"h& c #FBB88E", +"i& c #FBBA91", +"j& c #FFFDFD", +"k& c #FDDDC9", +"l& c #FEEEE4", +"m& c #FCE0D0", +"n& c #F26F2F", +"o& c #F05A15", +"p& c #F05912", +"q& c #FF6F24", +"r& c #7A7878", +"s& c #FBD1BC", +"t& c #EF540C", +"u& c #F37F46", +"v& c #FEF9F5", +"w& c #FDEEE6", +"x& c #F89964", +"y& c #F8A16F", +"z& c #FBCCB1", +"A& c #313539", +"B& c #23150E", +"C& c #FFD5A7", +"D& c #FBBD97", +"E& c #FCBE98", +"F& c #FBBA92", +"G& c #FCD5BA", +"H& c #FCCCAD", +"I& c #FCC6A4", +"J& c #FCD8BF", +"K& c #FEEEE3", +"L& c #F16625", +"M& c #FFFBF6", +"N& c #FFE0C3", +"O& c #4C2E1F", +"P& c #D3D1D1", +"Q& c #EF560D", +"R& c #FCE1D3", +"S& c #FAC6AB", +"T& c #FAC8AF", +"U& c #F3763A", +"V& c #FBD1BA", +"W& c #FAC1A0", +"X& c #FCD5BD", +"Y& c #FBAA7B", +"Z& c #F7AB7E", +"`& c #704B37", +" * c #8F8078", +".* c #A6A9AB", +"+* c #A4A2A2", +"@* c #545252", +"#* c #0C0A0A", +"$* c #AE8268", +"%* c #FFC79E", +"&* c #FBBC95", +"** c #FCCEAF", +"=* c #FDF1E8", +"-* c #FCC39F", +";* c #FDCBAA", +">* c #FDCCAD", +",* c #FDCCAE", +"'* c #FCC8A7", +")* c #FDE8DA", +"!* c #FCD6BC", +"~* c #FCDAC1", +"{* c #2A3032", +"]* c #141313", +"^* c #F6A075", +"/* c #F26D2D", +"(* c #FDEDE3", +"_* c #F05C14", +":* c #F59362", +"<* c #F59263", +"[* c #F59566", +"}* c #F1621D", +"|* c #FCE0D2", +"1* c #FBC2A2", +"2* c #F89A64", +"3* c #F89962", +"4* c #F9A777", +"5* c #FEECE2", +"6* c #F8A06D", +"7* c #F8AA7D", +"8* c #FCB082", +"9* c #FFB889", +"0* c #FFB381", +"a* c #F9F8F8", +"b* c #959494", +"c* c #1D1B1B", +"d* c #FFCCA4", +"e* c #FEBE97", +"f* c #FBB589", +"g* c #FCC39E", +"h* c #FCD4B8", +"i* c #FCD5B9", +"j* c #181616", +"k* c #3E3D3C", +"l* c #F05C15", +"m* c #F48753", +"n* c #F8B493", +"o* c #F8A677", +"p* c #F8A97C", +"q* c #F9AB7E", +"r* c #F9AD81", +"s* c #F8AB7C", +"t* c #FBCEB2", +"u* c #DDDBDC", +"v* c #454343", +"w* c #543B2D", +"x* c #FFD3AC", +"y* c #FDD1B6", +"z* c #FCC5A1", +"A* c #FEFEFD", +"B* c #0F0D0D", +"C* c #656262", +"D* c #FCDCCC", +"E* c #F16D2F", +"F* c #F8AC7E", +"G* c #FACAAB", +"H* c #FBFAFA", +"I* c #494A4C", +"J* c #E0E5E9", +"K* c #FEECE1", +"L* c #FEF5EF", +"M* c #FDEFE5", +"N* c #FDEDE0", +"O* c #FEFEFE", +"P* c #F16421", +"Q* c #F59464", +"R* c #F38049", +"S* c #FCBC9C", +"T* c #7F7E7D", +"U* c #FBD2BE", +"V* c #FAC3A6", +"W* c #FBC1A0", +"X* c #F99C69", +"Y* c #FAB48E", +"Z* c #F8AD81", +"`* c #F8A472", +" = c #FDD0B4", +".= c #FDDFCB", +"+= c #FFF9F6", +"@= c #FCE2CE", +"#= c #FCE6D3", +"$= c #FDF3EA", +"%= c #FACFB8", +"&= c #F2601B", +"*= c #1F0C04", +"== c #848282", +"-= c #FCDBCA", +";= c #F16623", +">= c #F4854F", +",= c #F16725", +"'= c #FDE8DC", +")= c #F89C6A", +"!= c #F8945D", +"~= c #F89B68", +"{= c #F89A67", +"]= c #F8945C", +"^= c #F9B890", +"/= c #F8A06E", +"(= c #F8A674", +"_= c #F8A371", +":= c #FCD8C2", +"<= c #FCD4BB", +"[= c #FABB91", +"}= c #FABB94", +"|= c #FDD6BE", +"1= c #FBC09B", +"2= c #FCC4A0", +"3= c #FCCFB0", +"4= c #FEF2E9", +"5= c #FDEADC", +"6= c #FCE9D7", +"7= c #F8B08E", +"8= c #FCDECF", +"9= c #FF7228", +"0= c #371608", +"a= c #858383", +"b= c #F37B41", +"c= c #FCE6DA", +"d= c #FBD5C1", +"e= c #F69A6C", +"f= c #FEF2EC", +"g= c #FBCFB5", +"h= c #F8925A", +"i= c #F99C68", +"j= c #F99D6B", +"k= c #F99E6B", +"l= c #F99F6E", +"m= c #F89C69", +"n= c #FDEDE2", +"o= c #FCD8C3", +"p= c #FDE9DC", +"q= c #FBC19D", +"r= c #FAB58B", +"s= c #FBB88F", +"t= c #FCC7A6", +"u= c #FBBE98", +"v= c #FCC29B", +"w= c #FFF7F3", +"x= c #FCC9A9", +"y= c #FCCFB3", +"z= c #FCD1B5", +"A= c #F48048", +"B= c #FF7127", +"C= c #5F280E", +"D= c #716F6E", +"E= c #FBD3BE", +"F= c #F1631F", +"G= c #FEF5F0", +"H= c #F9BC9D", +"I= c #F27133", +"J= c #F48B57", +"K= c #FAB58E", +"L= c #F89661", +"M= c #F89E6D", +"N= c #F89E6B", +"O= c #F9B68C", +"P= c #F9A979", +"Q= c #F9AD7E", +"R= c #FABA92", +"S= c #FBBA94", +"T= c #FBB68B", +"U= c #FCC19A", +"V= c #FFF9F5", +"W= c #FCCFB2", +"X= c #FDD1B7", +"Y= c #FDD4B9", +"Z= c #FCD2B6", +"`= c #FDE8D8", +" - c #FDECDF", +".- c #FAC9B0", +"+- c #F16522", +"@- c #FF681D", +"#- c #953C14", +"$- c #535151", +"%- c #F5905E", +"&- c #FACAB2", +"*- c #FAC09F", +"=- c #F8955F", +"-- c #F89D6B", +";- c #F9A677", +">- c #FBCEB3", +",- c #F9B081", +"'- c #FCD1B7", +")- c #FEEADD", +"!- c #FAB387", +"~- c #FBC5A2", +"{- c #FCBF9B", +"]- c #FDD9C0", +"^- c #FCCEB1", +"/- c #FDEBDD", +"(- c #FDF0E6", +"_- c #FCDCC8", +":- c #FCDFCA", +"<- c #D9D0CC", +"[- c #292727", +"}- c #FCE3D6", +"|- c #F0611C", +"1- c #F88C52", +"2- c #F8935B", +"3- c #FDDBC8", +"4- c #F8AF81", +"5- c #F9B487", +"6- c #FAB992", +"7- c #FCBC96", +"8- c #FCCDB0", +"9- c #FDD6BC", +"0- c #FCDAC0", +"a- c #FCDCC7", +"b- c #FCE0CD", +"c- c #F38149", +"d- c #EF560C", +"e- c #F69D71", +"f- c #FBD6C5", +"g- c #F27031", +"h- c #F59666", +"i- c #F89762", +"j- c #FCD0B7", +"k- c #FAC19F", +"l- c #F89C67", +"m- c #F89B65", +"n- c #FBCEB4", +"o- c #FAC09D", +"p- c #F8AD7F", +"q- c #F9B285", +"r- c #FBC6A7", +"s- c #FAB388", +"t- c #FAB78B", +"u- c #FAB68D", +"v- c #FBB78C", +"w- c #FEF0E8", +"x- c #FEF1E8", +"y- c #FDEBDE", +"z- c #F69769", +"A- c #F7AC88", +"B- c #FDE4D7", +"C- c #FAF8F8", +"D- c #F27335", +"E- c #FFF9F4", +"F- c #F59160", +"G- c #F9B188", +"H- c #F89C68", +"I- c #F8A575", +"J- c #F8A676", +"K- c #FBC9AB", +"L- c #FEF5EE", +"M- c #F9B186", +"N- c #F9AB7A", +"O- c #FDEBDC", +"P- c #FCEADB", +"Q- c #FAC8AD", +"R- c #FBCEB9", +"S- c #F05B13", +"T- c #FFE7D0", +"U- c #7A7F82", +"V- c #C2C0C0", +"W- c #F8AF89", +"X- c #F05A12", +"Y- c #F2763A", +"Z- c #FACCB3", +"`- c #FDF2EA", +" ; c #F7884D", +".; c #F78B50", +"+; c #F78C51", +"@; c #FAB28A", +"#; c #F89660", +"$; c #F9A778", +"%; c #F8A778", +"&; c #F89F6A", +"*; c #FBC6A5", +"=; c #FAB890", +"-; c #FBC8A8", +";; c #FDE9DB", +">; c #FCC5A3", +",; c #FCCDAF", +"'; c #FCE8D7", +"); c #FDF6EF", +"!; c #F37537", +"~; c #EF570E", +"{; c #F96621", +"]; c #D15E28", +"^; c #696867", +"/; c #FACCB4", +"(; c #F06524", +"_; c #FCE0D1", +":; c #F7884C", +"<; c #F79058", +"[; c #F7945F", +"}; c #F79762", +"|; c #F7935C", +"1; c #FDDCC7", +"2; c #F8A16D", +"3; c #FBC5A3", +"4; c #FAB589", +"5; c #FBBC96", +"6; c #FCC19B", +"7; c #FDCBAC", +"8; c #FCCBAB", +"9; c #FDF5EE", +"0; c #FAC8AE", +"a; c #F6A67E", +"b; c #F26523", +"c; c #FF6F26", +"d; c #121211", +"e; c #FBD8C4", +"f; c #F69768", +"g; c #F1621E", +"h; c #F78F56", +"i; c #F8945F", +"j; c #F89965", +"k; c #F7925C", +"l; c #FAC5A6", +"m; c #F9AD7F", +"n; c #FAB58A", +"o; c #FAB88E", +"p; c #FAB88F", +"q; c #FAB185", +"r; c #FCC6A2", +"s; c #FDCBAB", +"t; c #FDCDAF", +"u; c #FCC7A7", +"v; c #FDF9F6", +"w; c #FDDBC5", +"x; c #FCD3B8", +"y; c #FCD6BD", +"z; c #F9BA9C", +"A; c #F4844F", +"B; c #EF4E01", +"C; c #FF6D24", +"D; c #5C260E", +"E; c #F9FEFF", +"F; c #FBCCB5", +"G; c #FACAB1", +"H; c #F16A2A", +"I; c #F5874B", +"J; c #F8935D", +"K; c #F79763", +"L; c #F8A272", +"M; c #FAB38C", +"N; c #F8A473", +"O; c #F89D69", +"P; c #FBCBAD", +"Q; c #FBD5BD", +"R; c #F9B085", +"S; c #FBB98F", +"T; c #FABA93", +"U; c #FAB88D", +"V; c #FDE6D8", +"W; c #FCC4A2", +"X; c #FBC09A", +"Y; c #FCC29C", +"Z; c #FDCAAA", +"`; c #FCC8A8", +" > c #FDDBC4", +".> c #FCD7BE", +"+> c #FC7F42", +"@> c #D0612D", +"#> c #8E411D", +"$> c #FF651B", +"%> c #EF5911", +"&> c #F7A176", +"*> c #F48D5A", +"=> c #F9C4A9", +"-> c #F69C70", +";> c #F27234", +">> c #F27639", +",> c #F58649", +"'> c #F8A271", +")> c #FBC4A4", +"!> c #F89A63", +"~> c #FCD2BA", +"{> c #FBCFB4", +"]> c #FBBA93", +"^> c #FAB386", +"/> c #FDE2D1", +"(> c #FBB88C", +"_> c #FBBF9A", +":> c #FBC29D", +"<> c #FBC19C", +"[> c #FCC7A5", +"}> c #FCD1B4", +"|> c #FDD5BC", +"1> c #FDD7BF", +"2> c #FCD7BD", +"3> c #F4834B", +"4> c #0A1419", +"5> c #200E05", +"6> c #FF7126", +"7> c #FCE3D5", +"8> c #F16928", +"9> c #F8A679", +"0> c #F78F57", +"a> c #F7935D", +"b> c #FAC2A2", +"c> c #FCDBC6", +"d> c #F8A879", +"e> c #FBD1B5", +"f> c #F9AB7C", +"g> c #FBB78E", +"h> c #FBC9A8", +"i> c #FBBB92", +"j> c #FBC099", +"k> c #FCC09D", +"l> c #FBC4A1", +"m> c #FCD3B9", +"n> c #FCD7BF", +"o> c #888686", +"p> c #E96122", +"q> c #F37E45", +"r> c #F7F7F8", +"s> c #8F8D8E", +"t> c #5F5D5E", +"u> c #514E4F", +"v> c #535050", +"w> c #5B595A", +"x> c #D1D3D5", +"y> c #FFFCF6", +"z> c #F68648", +"A> c #F7915A", +"B> c #F7945D", +"C> c #F7945E", +"D> c #FCD1B8", +"E> c #F89F69", +"F> c #F8A87B", +"G> c #F8A675", +"H> c #FABF9C", +"I> c #FAAD7F", +"J> c #FAB285", +"K> c #FBB58A", +"L> c #FDC29E", +"M> c #FDD8C1", +"N> c #FDDAC4", +"O> c #FCD2B7", +"P> c #FEF1E7", +"Q> c #FCE4D1", +"R> c #FCE0CA", +"S> c #774D37", +"T> c #FF681F", +"U> c #F59262", +"V> c #F9C3A7", +"W> c #FBD8C7", +"X> c #A2A1A2", +"Y> c #050102", +"Z> c #140F10", +"`> c #191516", +" , c #1B1718", +"., c #070203", +"+, c #BBBCBC", +"@, c #F89D6A", +"#, c #F7874C", +"$, c #F78C52", +"%, c #F78B4F", +"&, c #F9AA7D", +"*, c #FABA95", +"=, c #F89864", +"-, c #F89E69", +";, c #F8A97A", +">, c #F9A97D", +",, c #FBC3A0", +"', c #FCDCC5", +"), c #FCE2CF", +"!, c #FDF4ED", +"~, c #F37B3F", +"{, c #FCE3D4", +"], c #484745", +"^, c #F05308", +"/, c #FBD8C5", +"(, c #FBD0BA", +"_, c #F38048", +":, c #D0D0D0", +"<, c #020000", +"[, c #221D1E", +"}, c #231F20", +"|, c #211D1E", +"1, c #201C1D", +"2, c #0D0809", +"3, c #D5D4D5", +"4, c #F8925B", +"5, c #F89763", +"6, c #F89761", +"7, c #FABD9A", +"8, c #FDDFCD", +"9, c #FEEFE6", +"0, c #FBBB93", +"a, c #FCE1CC", +"b, c #F8B897", +"c, c #FACFBB", +"d, c #F6570C", +"e, c #DBA991", +"f, c #FBD6C1", +"g, c #F16827", +"h, c #F69D6F", +"i, c #F4824B", +"j, c #444243", +"k, c #1C1718", +"l, c #171314", +"m, c #141011", +"n, c #221E1F", +"o, c #E7E7E7", +"p, c #F9A779", +"q, c #F9A271", +"r, c #FDE4D5", +"s, c #F89D68", +"t, c #FAB488", +"u, c #FAB389", +"v, c #FAB78C", +"w, c #FEEFE5", +"x, c #F3793D", +"y, c #FF7025", +"z, c #250700", +"A, c #292827", +"B, c #FBD2BD", +"C, c #FCDFCF", +"D, c #F69D70", +"E, c #F1601B", +"F, c #090506", +"G, c #6B686A", +"H, c #FEFEFF", +"I, c #F88E55", +"J, c #F99B68", +"K, c #FFA471", +"L, c #FFAB76", +"M, c #FFA771", +"N, c #FFC9A4", +"O, c #FBC5A6", +"P, c #F8A878", +"Q, c #F9B58D", +"R, c #FAB78D", +"S, c #FABC92", +"T, c #FDE0CD", +"U, c #FCC39D", +"V, c #FCD4B9", +"W, c #FDEFE3", +"X, c #FDF0E9", +"Y, c #FACFB9", +"Z, c #FA6824", +"`, c #BE4E1C", +" ' c #E6E5E5", +".' c #FEFAF9", +"+' c #0B0708", +"@' c #100C0D", +"#' c #F88F56", +"$' c #FFA470", +"%' c #A77559", +"&' c #6A5042", +"*' c #715343", +"=' c #6A5349", +"-' c #B2B4B6", +";' c #FBCAAD", +">' c #FAC09C", +",' c #FDC7A4", +"'' c #FDCAA9", +")' c #FDCAAB", +"!' c #FCD6BB", +"~' c #B8B8B9", +"{' c #6A686A", +"]' c #737172", +"^' c #6C6A6C", +"/' c #A3A2A4", +"(' c #FCECDF", +"_' c #FCEDE0", +":' c #FCEDE2", +"<' c #F1621F", +"[' c #180904", +"}' c #494747", +"|' c #F58C57", +"1' c #F58D5A", +"2' c #CFCECE", +"3' c #0E0A0B", +"4' c #1E1A1B", +"5' c #333031", +"6' c #F89560", +"7' c #FFA773", +"8' c #725343", +"9' c #0D1016", +"0' c #18181B", +"a' c #0B090C", +"b' c #7F7F7E", +"c' c #FDF3EC", +"d' c #FAAE80", +"e' c #FDD5BB", +"f' c #FDD8BF", +"g' c #8B8A8B", +"h' c #0A0506", +"i' c #181314", +"j' c #0D090A", +"k' c #686667", +"l' c #FDF0E4", +"m' c #F95A0E", +"n' c #B24716", +"o' c #FAC1A6", +"p' c #F3773B", +"q' c #CCCBCD", +"r' c #0F0A0B", +"s' c #343132", +"t' c #FCD7C2", +"u' c #F88E54", +"v' c #785745", +"w' c #17171B", +"x' c #161213", +"y' c #858584", +"z' c #FAB990", +"A' c #FCC49F", +"B' c #FEEBDE", +"C' c #FCD4BA", +"D' c #919091", +"E' c #151011", +"F' c #181415", +"G' c #6F6D6E", +"H' c #1B1614", +"I' c #545353", +"J' c #F48A55", +"K' c #F7A983", +"L' c #FEF0E9", +"M' c #CDCCCD", +"N' c #FCD1BA", +"O' c #F8955E", +"P' c #FFA068", +"Q' c #785440", +"R' c #FDE6D7", +"S' c #FAC19D", +"T' c #F9BA93", +"U' c #FEFDFB", +"V' c #FECFB2", +"W' c #FAB68B", +"X' c #FBCFB2", +"Y' c #FFE9DA", +"Z' c #FFF4E8", +"`' c #FDEFE8", +" ) c #F9B391", +".) c #C9C8C8", +"+) c #EF4E03", +"@) c #F3844F", +"#) c #F38047", +"$) c #DEDEDF", +"%) c #383536", +"&) c #FFF9E9", +"*) c #FFFFEC", +"=) c #857C78", +"-) c #171416", +";) c #919090", +">) c #FACAAC", +",) c #F9A16E", +"') c #FFBA86", +")) c #FFBB89", +"!) c #FFBB87", +"~) c #FFB983", +"{) c #FFF9F2", +"]) c #EFF0F0", +"^) c #C4C3C4", +"/) c #C7C7C8", +"() c #F8FEFF", +"_) c #E1E1E2", +":) c #C5C4C4", +"<) c #D0CFD0", +"[) c #FBFBFB", +"}) c #F8FCFE", +"|) c #CED0D2", +"1) c #CBCBCB", +"2) c #F8F9F9", +"3) c #9D9D9E", +"4) c #787677", +"5) c #F2783D", +"6) c #2A2928", +"7) c #4F4D4D", +"8) c #F48D5B", +"9) c #F7AC86", +"0) c #EF4D01", +"a) c #F7AC87", +"b) c #676565", +"c) c #191415", +"d) c #242021", +"e) c #747273", +"f) c #202023", +"g) c #232427", +"h) c #221F21", +"i) c #161518", +"j) c #FFF8EF", +"k) c #FAA16D", +"l) c #FFB385", +"m) c #14171D", +"n) c #201D1E", +"o) c #211E1F", +"p) c #0C0D11", +"q) c #F7B790", +"r) c #F3F9FD", +"s) c #3B383A", +"t) c #070304", +"u) c #0F0B0C", +"v) c #8F8F92", +"w) c #FFFCF3", +"x) c #4F4D4E", +"y) c #0F0B0D", +"z) c #0E090A", +"A) c #C3C1C1", +"B) c #9E9D9E", +"C) c #2F2C2D", +"D) c #0A0507", +"E) c #312E2F", +"F) c #A7A6A6", +"G) c #2D2B2B", +"H) c #0C0709", +"I) c #FDFFFF", +"J) c #FCDCCA", +"K) c #E2E1E1", +"L) c #ECEAE9", +"M) c #FEFBF7", +"N) c #666463", +"O) c #151112", +"P) c #727071", +"Q) c #140F11", +"R) c #1F1A1B", +"S) c #131418", +"T) c #FFDDC4", +"U) c #FBA777", +"V) c #FFB586", +"W) c #11151C", +"X) c #1F1C1D", +"Y) c #0E1015", +"Z) c #DEA07C", +"`) c #0E0F13", +" ! c #1B1618", +".! c #141417", +"+! c #97735E", +"@! c #FFBC8D", +"#! c #FCB589", +"$! c #FFC59B", +"%! c #555558", +"&! c #080405", +"*! c #1B1617", +"=! c #1D191A", +"-! c #050306", +";! c #7E6354", +">! c #FFF9E6", +",! c #EAE5E2", +"'! c #0C0809", +")! c #383638", +"!! c #FFF1DE", +"~! c #2D2727", +"{! c #1C181A", +"]! c #F69668", +"^! c #EF580E", +"/! c #4C4B4A", +"(! c #384044", +"_! c #F7A881", +":! c #F8BA9B", +"~ c #E6DBD4", +",~ c #453731", +"'~ c #181618", +")~ c #1B181A", +"!~ c #4B3D37", +"~~ c #FFFAEA", +"{~ c #1E1A1C", +"]~ c #0F0E11", +"^~ c #3D3534", +"/~ c #A4A3A4", +"(~ c #C0BFC0", +"_~ c #9E9C9E", +":~ c #0C0A0D", +"<~ c #DECABC", +"[~ c #FFF6DD", +"}~ c #61534C", +"|~ c #575455", +"1~ c #5D5A5B", +"2~ c #3E3B3C", +"3~ c #353233", +"4~ c #5F5D5F", +"5~ c #595758", +"6~ c #494546", +"7~ c #F8B290", +"8~ c #EF4F05", +"9~ c #EE4700", +"0~ c #7A4125", +"a~ c #120703", +"b~ c #FF6415", +"c~ c #FACBB2", +"d~ c #F7AE8B", +"e~ c #F7B08E", +"f~ c #F8B898", +"g~ c #F8B594", +"h~ c #F0611B", +"i~ c #DADADB", +"j~ c #373435", +"k~ c #FABE9D", +"l~ c #FFA972", +"m~ c #FFB37A", +"n~ c #805C49", +"o~ c #8E8E8D", +"p~ c #FFEADE", +"q~ c #FFAD79", +"r~ c #13161C", +"s~ c #767576", +"t~ c #FFFFF9", +"u~ c #FFBA89", +"v~ c #FFBF94", +"w~ c #FCBE95", +"x~ c #FFC699", +"y~ c #9A9695", +"z~ c #FFD6AB", +"A~ c #2C2828", +"B~ c #929192", +"C~ c #0C0C0F", +"D~ c #947E72", +"E~ c #434042", +"F~ c #D8D8D9", +"G~ c #FEF4EC", +"H~ c #9A9A9B", +"I~ c #181416", +"J~ c #767170", +"K~ c #F69F74", +"L~ c #963F16", +"M~ c #FC6017", +"N~ c #F6A781", +"O~ c #F8B08F", +"P~ c #F16420", +"Q~ c #FACEB8", +"R~ c #FFB286", +"S~ c #130F11", +"T~ c #221E1E", +"U~ c #4C4A4B", +"V~ c #FCC09C", +"W~ c #856C5E", +"X~ c #171518", +"Y~ c #F8F9FB", +"Z~ c #252123", +"`~ c #181517", +" { c #6D5B52", +".{ c #FFEDD0", +"+{ c #181516", +"@{ c #6F6663", +"#{ c #FFFAE9", +"${ c #FCEEE3", +"%{ c #BEBCBC", +"&{ c #F04E01", +"*{ c #FAC3A8", +"={ c #14171C", +"-{ c #B77A59", +";{ c #FF9F69", +">{ c #130E10", +",{ c #100B0C", +"'{ c #CBCBCC", +"){ c #FAB68C", +"!{ c #FAFAFB", +"~{ c #B9B9B9", +"{{ c #8C8A8B", +"]{ c #6F6E6F", +"^{ c #5E5B5C", +"/{ c #5A5758", +"({ c #605F61", +"_{ c #3A393B", +":{ c #F1F2F3", +"<{ c #F4F5F5", +"[{ c #0A0607", +"}{ c #0C080A", +"|{ c #F7F3EF", +"1{ c #6F6765", +"2{ c #3A3937", +"3{ c #5A250C", +"4{ c #FF7C39", +"5{ c #FBC9B0", +"6{ c #F27334", +"7{ c #080304", +"8{ c #0E0D10", +"9{ c #B99E90", +"0{ c #FF985E", +"a{ c #F99C6A", +"b{ c #FFFDFC", +"c{ c #FFEEE5", +"d{ c #F5F5F4", +"e{ c #CFD0D1", +"f{ c #3F3C3D", +"g{ c #1A1517", +"h{ c #F2F3F4", +"i{ c #D3D3D4", +"j{ c #242122", +"k{ c #E3E7EA", +"l{ c #FFFBF9", +"m{ c #F8A982", +"n{ c #090405", +"o{ c #B9C2C8", +"p{ c #FFCBAA", +"q{ c #F89057", +"r{ c #FFA670", +"s{ c #785644", +"t{ c #FBCDB1", +"u{ c #F9A371", +"v{ c #F3F3F3", +"w{ c #F9AF80", +"x{ c #F9AD80", +"y{ c #8F8E8F", +"z{ c #040000", +"A{ c #1C1819", +"B{ c #151417", +"C{ c #101014", +"D{ c #0B080A", +"E{ c #CDD0D1", +"F{ c #302E2F", +"G{ c #EF5910", +"H{ c #FBD8C6", +"I{ c #8D8C8B", +"J{ c #151313", +"K{ c #F9BC9F", +"L{ c #F1641F", +"M{ c #F7A981", +"N{ c #F37A40", +"O{ c #F8B390", +"P{ c #F26A29", +"Q{ c #464343", +"R{ c #575454", +"S{ c #4A4747", +"T{ c #CBCACB", +"U{ c #FAB38B", +"V{ c #785A4A", +"W{ c #17161A", +"X{ c #FCD5BF", +"Y{ c #FAAB7E", +"Z{ c #FFB485", +"`{ c #F3F4F5", +" ] c #F9B589", +".] c #FFCFAE", +"+] c #D4DADF", +"@] c #292527", +"#] c #8E7262", +"$] c #C69C82", +"%] c #E3B497", +"&] c #EDB898", +"*] c #FFFFFD", +"=] c #494748", +"-] c #FFEADA", +";] c #E2B99F", +">] c #0B0B0F", +",] c #181818", +"'] c #918F90", +")] c #FCDECD", +"!] c #F69C6F", +"~] c #F8AF8C", +"{] c #F27435", +"]] c #F48C5A", +"^] c #7C7D80", +"/] c #888787", +"(] c #F4F7FA", +"_] c #FFD8BF", +":] c #F9B083", +"<] c #FFC396", +"[] c #5D5E60", +"}] c #191517", +"|] c #626468", +"1] c #FFF3D9", +"2] c #FFC8A0", +"3] c #FFC9A3", +"4] c #FFC7A3", +"5] c #FFC6A2", +"6] c #FFEBCC", +"7] c #36383D", +"8] c #F2F4F6", +"9] c #FFF7EF", +"0] c #FEC7A6", +"a] c #FFDCBD", +"b] c #111115", +"c] c #B5B5B5", +"d] c #FCE1CD", +"e] c #919192", +"f] c #716F70", +"g] c #F26A28", +"h] c #F4550A", +"i] c #E9E5E4", +"j] c #F16521", +"k] c #FCD3BD", +"l] c #F9AC81", +"m] c #FAB894", +"n] c #7A7879", +"o] c #757375", +"p] c #FBAB7B", +"q] c #FFDBC3", +"r] c #FFC89B", +"s] c #37373A", +"t] c #1D1A1B", +"u] c #D6DBE0", +"v] c #FFD4B4", +"w] c #FFC8A5", +"x] c #FFD1B1", +"y] c #F2F6F8", +"z] c #FFE8D8", +"A] c #FCCAAB", +"B] c #FFDEBE", +"C] c #5C504B", +"D] c #191619", +"E] c #FBFCFC", +"F] c #FFF4ED", +"G] c #FDD5BA", +"H] c #FEDCC3", +"I] c #FFE4C9", +"J] c #8F837C", +"K] c #151113", +"L] c #5D5B5C", +"M] c #F0560D", +"N] c #F37335", +"O] c #FF7835", +"P] c #7D878B", +"Q] c #333130", +"R] c #F4814A", +"S] c #F27336", +"T] c #F78A50", +"U] c #F7955E", +"V] c #F78B51", +"W] c #FBCDB3", +"X] c #161112", +"Y] c #F0F8FD", +"Z] c #FFCCA3", +"`] c #FFB37F", +" ^ c #F1A77B", +".^ c #FFE6CA", +"+^ c #3C3E42", +"@^ c #646568", +"#^ c #FFFFF5", +"$^ c #FFCDA7", +"%^ c #FFD2AB", +"&^ c #FFD7B2", +"*^ c #4A3F3B", +"=^ c #1A181A", +"-^ c #FFF8F1", +";^ c #FCC6A5", +">^ c #FFD2B4", +",^ c #E6BFA6", +"'^ c #06070B", +")^ c #1E191A", +"!^ c #B4B3B5", +"~^ c #FFF1D9", +"{^ c #FFE9D0", +"]^ c #B39F93", +"^^ c #080609", +"/^ c #5E5B5D", +"(^ c #998C82", +"_^ c #141012", +":^ c #E2E2E3", +"<^ c #F9F9FA", +"[^ c #FCFCFD", +"}^ c #EF550E", +"|^ c #F37538", +"1^ c #0F1112", +"2^ c #A4A8AB", +"3^ c #FFFFFC", +"4^ c #FBDAC8", +"5^ c #F8AF8B", +"6^ c #F78D53", +"7^ c #F79966", +"8^ c #AEADAF", +"9^ c #0E0A0C", +"0^ c #212124", +"a^ c #1D1D20", +"b^ c #020C15", +"c^ c #FFB182", +"d^ c #FFB07F", +"e^ c #F3F3F2", +"f^ c #F9AE80", +"g^ c #7C7B7C", +"h^ c #34363A", +"i^ c #836C5F", +"j^ c #896F60", +"k^ c #6D5A50", +"l^ c #161416", +"m^ c #1C1719", +"n^ c #FFDCB9", +"o^ c #8B7C74", +"p^ c #0A0709", +"q^ c #120F10", +"r^ c #222124", +"s^ c #110F11", +"t^ c #716F71", +"u^ c #C6C6C7", +"v^ c #F27436", +"w^ c #E7EAEB", +"x^ c #F2560B", +"y^ c #F37C43", +"z^ c #F68649", +"A^ c #F79A67", +"B^ c #FAB996", +"C^ c #15161B", +"D^ c #FFB789", +"E^ c #FCB185", +"F^ c #FFDFC6", +"G^ c #131318", +"H^ c #120E10", +"I^ c #1B1717", +"J^ c #191719", +"K^ c #211D1F", +"L^ c #7E7C7D", +"M^ c #1A1516", +"N^ c #7B797A", +"O^ c #060103", +"P^ c #BEBDBE", +"Q^ c #7E7C7C", +"R^ c #373F42", +"S^ c #FFBF98", +"T^ c #EF5A14", +"U^ c #C7C6C8", +"V^ c #F7864B", +"W^ c #F99763", +"X^ c #F9AD83", +"Y^ c #B1B0B1", +"Z^ c #1A1618", +"`^ c #050203", +" / c #100B0D", +"./ c #F1F0F0", +"+/ c #F5F5F5", +"@/ c #2F2B2D", +"#/ c #242022", +"$/ c #7B7979", +"%/ c #040001", +"&/ c #100F12", +"*/ c #EFE5E0", +"=/ c #C6C5C6", +"-/ c #292627", +";/ c #0A0608", +">/ c #2F2D30", +",/ c #CDCFD2", +"'/ c #C6C6C6", +")/ c #191818", +"!/ c #A1A9AD", +"~/ c #FFAE84", +"{/ c #F16F2F", +"]/ c #F48C58", +"^/ c #F48650", +"// c #F2F5F7", +"(/ c #BDC5CA", +"_/ c #C3CCD2", +":/ c #C2CBD1", +"( c #FFFEFF", +",( c #FCDAC4", +"'( c #FDFAF6", +")( c #EAEAEB", +"!( c #211E20", +"~( c #120E0F", +"{( c #252122", +"]( c #241F21", +"^( c #CECECE", +"/( c #FEF9F3", +"(( c #F9BDA0", +"_( c #F16624", +":( c #F69C6E", +"<( c #F47835", +"[( c #F5884E", +"}( c #F68A4F", +"|( c #F68B52", +"1( c #F68C53", +"2( c #F58D54", +"3( c #F68B51", +"4( c #F6884C", +"5( c #FDECE1", +"6( c #FBC4A5", +"7( c #FBD0B8", +"8( c #F89760", +"9( c #F9A171", +"0( c #F8A576", +"a( c #F8A574", +"b( c #F8B084", +"c( c #F9B184", +"d( c #FAB284", +"e( c #FBB78B", +"f( c #FCCAA9", +"g( c #050103", +"h( c #EDEDEE", +"i( c #F9B695", +"j( c #F26F30", +"k( c #FBC9AE", +"l( c #F57E3F", +"m( c #F6894F", +"n( c #F78E54", +"o( c #F68345", +"p( c #FBCEB5", +"q( c #F9A678", +"r( c #FBC8A9", +"s( c #F8B184", +"t( c #F9B48A", +"u( c #FEE6D8", +"v( c #FBBB91", +"w( c #FDCFB2", +"x( c #F48955", +"y( c #939293", +"z( c #6B696A", +"A( c #F9B898", +"B( c #F58041", +"C( c #F68549", +"D( c #FCDAC6", +"E( c #FCCFB5", +"F( c #F9B489", +"G( c #FAB487", +"H( c #FCBD97", +"I( c #FBB98E", +"J( c #F59567", +"K( c #F7A67E", +"L( c #F15E18", +"M( c #605E5F", +"N( c #9B9A9A", +"O( c #F9C5AA", +"P( c #F7AA86", +"Q( c #F8B494", +"R( c #FCDDCB", +"S( c #F57A39", +"T( c #F78D54", +"U( c #F57F3F", +"V( c #FAB691", +"W( c #F9A574", +"X( c #F8A777", +"Y( c #F8AD7E", +"Z( c #FAB085", +"`( c #F9AA7A", +" _ c #FBBF98", +"._ c #F8BC9E", +"+_ c #FBDFD0", +"@_ c #696768", +"#_ c #090707", +"$_ c #6F6D6D", +"%_ c #E0DFDE", +"&_ c #F7AA83", +"*_ c #F68E55", +"=_ c #F58246", +"-_ c #F58C53", +";_ c #F68447", +">_ c #F8AB80", +",_ c #FABF9E", +"'_ c #F78F58", +")_ c #F7894D", +"!_ c #FBCBB0", +"~_ c #F9B289", +"{_ c #F89963", +"]_ c #FBD1B8", +"^_ c #FAC3A1", +"/_ c #F26826", +"(_ c #0E0D0D", +"__ c #F3824B", +":_ c #F59768", +"<_ c #FACCB5", +"[_ c #F58F5D", +"}_ c #F7A982", +"|_ c #F6945E", +"1_ c #F47C3B", +"2_ c #F58346", +"3_ c #F58347", +"4_ c #F47E3E", +"5_ c #F8A779", +"6_ c #FCD6C0", +"7_ c #F58448", +"8_ c #FDD8C0", +"9_ c #514F50", +"0_ c #201C1C", +"a_ c #393537", +"b_ c #353333", +"c_ c #565454", +"d_ c #F76D2A", +"e_ c #F69D72", +"f_ c #FAC7AA", +"g_ c #FBCAAF", +"h_ c #F79864", +"i_ c #F69059", +"j_ c #F8945E", +"k_ c #F79560", +"l_ c #F8A97E", +"m_ c #FDC9A9", +"n_ c #FDD3B8", +"o_ c #FDE0CC", +"p_ c #151012", +"q_ c #AB4F23", +"r_ c #421907", +"s_ c #403028", +"t_ c #DD5617", +"u_ c #FEEBE1", +"v_ c #F06420", +"w_ c #F6925C", +"x_ c #FBC39F", +"y_ c #FDC3A0", +"z_ c #FC702D", +"A_ c #FF6B21", +"B_ c #FE6A25", +"C_ c #8D3B15", +"D_ c #0B0301", +"E_ c #411B0A", +"F_ c #EB6222", +"G_ c #FF6E25", +"H_ c #F2621F", +"I_ c #F8B391", +"J_ c #F16320", +"K_ c #F6905A", +"L_ c #F79660", +"M_ c #F8A678", +"N_ c #FCD9C5", +"O_ c #F9A06E", +"P_ c #F8965F", +"Q_ c #FCD9C3", +"R_ c #FEF6F3", +"S_ c #FCBF98", +"T_ c #F9BA9B", +"U_ c #FD631A", +"V_ c #FF600F", +"W_ c #C4BAB4", +"X_ c #252627", +"Y_ c #622910", +"Z_ c #FF661C", +"`_ c #FF9864", +" : c #F0550B", +".: c #F8B693", +"+: c #F5864B", +"@: c #FCDBC8", +"#: c #FCD2B9", +"$: c #F89E6C", +"%: c #F9A270", +"&: c #F8A070", +"*: c #F9B288", +"=: c #FAC3A2", +"-: c #F9B790", +";: c #FAAF81", +">: c #FAB183", +",: c #F3804A", +"': c #F48A56", +"): c #D9D7D7", +"!: c #A5958D", +"~: c #FAC7AC", +"{: c #F59667", +"]: c #FAC4A9", +"^: c #F8AF85", +"/: c #F7864A", +"(: c #F79057", +"_: c #F7925A", +":: c #FABE9C", +"<: c #FCDECA", +"[: c #FBD1B6", +"}: c #FBCBAB", +"|: c #FCBF9A", +"1: c #FEE9DB", +"2: c #F7AF8C", +"3: c #CAC9C8", +"4: c #121110", +"5: c #201E1E", +"6: c #F3F2F1", +"7: c #FAC5AA", +"8: c #F6A379", +"9: c #FDE1D2", +"0: c #F9B38B", +"a: c #F9A77C", +"b: c #FAB791", +"c: c #FEF7F4", +"d: c #F99E6E", +"e: c #FBD5BE", +"f: c #F8AF82", +"g: c #FBCAAB", +"h: c #F9BD9F", +"i: c #F3793F", +"j: c #F69667", +"k: c #FCD9C7", +"l: c #A2A0A0", +"m: c #817F7F", +"n: c #F58A56", +"o: c #F37D44", +"p: c #F8935C", +"q: c #F89B66", +"r: c #F8AF83", +"s: c #F8A978", +"t: c #FAAF82", +"u: c #FEF3ED", +"v: c #F9BFA1", +"w: c #F05E17", +"x: c #5D5B5A", +"y: c #F3F2F2", +"z: c #F48854", +"A: c #F2793F", +"B: c #F69E74", +"C: c #FBC8AB", +"D: c #F89F6D", +"E: c #F9A97B", +"F: c #F9BC94", +"G: c #FCD9C4", +"H: c #FCD9C2", +"I: c #FDE9DF", +"J: c #FDF1E9", +"K: c #E0ECF2", +"L: c #0A161D", +"M: c #959493", +"N: c #FAC0A3", +"O: c #F8AC85", +"P: c #FCE1D4", +"Q: c #FBD4BF", +"R: c #FBCCB0", +"S: c #FAB690", +"T: c #FAC7A8", +"U: c #F8A877", +"V: c #F7A57B", +"W: c #F48E5E", +"X: c #F96E2B", +"Y: c #FF8B4B", +"Z: c #70442E", +"`: c #302E2D", +" < c #F3783B", +".< c #FCDECB", +"+< c #F8B08B", +"@< c #FF6417", +"#< c #E0C4B6", +"$< c #020507", +"%< c #D4DEE2", +"&< c #F26927", +"*< c #FEA579", +"=< c #545352", +"-< c #7E7A78", +";< c #FFA46D", +">< c #F25A13", +",< c #F9B998", +"'< c #FACDB7", +")< c #FBCBB2", +"!< c #F3783C", +"~< c #B8BBBC", +"{< c #2E383E", +"]< c #FAC2A8", +"^< c #EF570D", +"/< c #FFF4E7", +"(< c #F68651", +"_< c #150400", +":< c #F37F47", +"<< c #F5621D", +"[< c #5A250E", +"}< c #AAA9A9", +"|< c #F7AB86", +"1< c #F6A178", +"2< c #A54A20", +"3< c #653F2D", +"4< c #FFAE7B", +"5< c #F2773B", +"6< c #F6A57F", +"7< c #FCE2D5", +"8< c #F16622", +"9< c #F9BB9C", +"0< c #F8B08D", +"a< c #FF8143", +"b< c #F0FCFF", +"c< c #000408", +"d< c #260500", +"e< c #FF6419", +"f< c #FBD0B9", +"g< c #FFB184", +"h< c #270800", +"i< c #EFAC8B", +"j< c #EF580F", +"k< c #F68149", +"l< c #FF6C20", +"m< c #61280F", +"n< c #C9C7C7", +"o< c #FAC1A5", +"p< c #FAD1BB", +"q< c #F05913", +"r< c #9E4218", +"s< c #916D5D", +"t< c #FF600E", +"u< c #F7AC85", +"v< c #FCE5D9", +"w< c #D24D10", +"x< c #55230D", +"y< c #F46623", +"z< c #F59261", +"A< c #F9C7AF", +"B< c #F3834C", +"C< c #FCE2D3", +"D< c #FFBF9C", +"E< c #090909", +"F< c #240F06", +"G< c #FF6D25", +"H< c #F7631D", +"I< c #F16F31", +"J< c #332E2B", +"K< c #EC5D1C", +"L< c #FF8549", +"M< c #F5915F", +"N< c #FFFCF8", +"O< c #F37E46", +"P< c #FFFFF8", +"Q< c #631500", +"R< c #CDA795", +"S< c #F7AE88", +"T< c #ECEBEB", +"U< c #FFE8D0", +"V< c #9E4116", +"W< c #979494", +"X< c #FCD7C4", +"Y< c #F26E2D", +"Z< c #1B1919", +"`< c #2A2D2E", +" [ c #FCD5C1", +".[ c #EF5206", +"+[ c #D8D2CF", +"@[ c #596267", +"#[ c #F4601A", +"$[ c #F48B56", +"%[ c #F48A57", +"&[ c #F68751", +"*[ c #B3B3B4", +"=[ c #D0B5A8", +"-[ c #EF5A11", +";[ c #F9C0A4", +">[ c #F7AD87", +",[ c #FEF7F0", +"'[ c #060404", +")[ c #1C0600", +"![ c #FA6924", +"~[ c #474748", +"{[ c #110704", +"][ c #FF6213", +"^[ c #333231", +"/[ c #D95A20", +"([ c #FF6C25", +"_[ c #FFF7F2", +":[ c #D6D6D7", +"<[ c #943E17", +"[[ c #FD6A24", +"}[ c #F7A47A", +"|[ c #F16D2C", +"1[ c #F1611C", +"2[ c #F26C2A", +"3[ c #71767A", +"4[ c #993F16", +"5[ c #FF6D20", +"6[ c #FBBD9E", +"7[ c #F27439", +"8[ c #F65E17", +"9[ c #FF6A1C", +"0[ c #6F7477", +"a[ c #FF6C27", +"b[ c #F36523", +"c[ c #FFD7B8", +"d[ c #B7B8B8", +"e[ c #4A5358", +"f[ c #F15F19", +"g[ c #F56420", +"h[ c #E86123", +"i[ c #0E0501", +"j[ c #4B1C08", +"k[ c #F7A57C", +"l[ c #FBCFB7", +"m[ c #F9C5AB", +"n[ c #FDF0E7", +"o[ c #F0E8E3", +"p[ c #000102", +"q[ c #020201", +"r[ c #E8E6E6", +"s[ c #FF7227", +"t[ c #E55E20", +"u[ c #652A11", +"v[ c #B46139", +"w[ c #F8560A", +"x[ c #FD9C6C", +"y[ c #3B3939", +"z[ c #F6A177", +"A[ c #B3B4B5", +"B[ c #2A1E1A", +"C[ c #F27235", +"D[ c #F3824C", +"E[ c #96877F", +"F[ c #E7E6E6", +"G[ c #2B2A2A", +"H[ c #302E2E", +"I[ c #F27032", +"J[ c #EE4600", +"K[ c #F8AD88", +"L[ c #FAC3A7", +"M[ c #FAC2A5", +"N[ c #FDEAE0", +"O[ c #FF5D0F", +"P[ c #E35F21", +"Q[ c #0D0502", +"R[ c #585756", +"S[ c #4A4949", +"T[ c #787474", +"U[ c #7E7D7D", +"V[ c #F7A67D", +"W[ c #F0601A", +"X[ c #FDE8DE", +"Y[ c #F8B28E", +"Z[ c #702E11", +"`[ c #686665", +" } c #AE6B4A", +".} c #1A0100", +"+} c #765747", +"@} c #B7B6B4", +"#} c #BEBDBD", +"$} c #F48953", +"%} c #F16B29", +"&} c #F3824A", +"*} c #FF691F", +"=} c #E6804F", +"-} c #1E272C", +";} c #2D2C2C", +">} c #91999D", +",} c #CA5C29", +"'} c #EE5B18", +")} c #EF6322", +"!} c #AD4211", +"~} c #222221", +"{} c #0E0502", +"]} c #0B0402", +"^} c #EBE6E5", +"/} c #F27132", +"(} c #FFD9C4", +"_} c #AD400D", +":} c #F6996A", +"<} c #F47F46", +"[} c #F7A277", +"}} c #FB5E13", +"|} c #FF6F25", +"1} c #A94619", +"2} c #210D05", +"3} c #596063", +"4} c #FF5C08", +"5} c #FAC5AB", +"6} c #FDEDE5", +"7} c #FDE4D8", +"8} c #FA6018", +"9} c #FF5F0E", +"0} c #ED8959", +"a} c #90989D", +"b} c #474747", +"c} c #190A03", +"d} c #0A0000", +"e} c #2D0000", +"f} c #807975", +"g} c #FAFAFA", +"h} c #FFF6E3", +"i} c #F4F3F3", +"j} c #EE4E00", +"k} c #FAD2BD", +"l} c #F69F75", +"m} c #FFBF95", +"n} c #FFAC7B", +"o} c #FFF0DD", +"p} c #858484", +"q} c #363434", +"r} c #F05D15", +"s} c #FBDAC9", +"t} c #FBDCCC", +"u} c #FCD8C6", +"v} c #F26C2C", +"w} c #F3773A", +"x} c #EF4B00", +"y} c #FACDB4", +"z} c #F8AE89", +"A} c #FDF1EB", +"B} c #F69869", +"C} c #F9B897", +"D} c #F16C2D", +"E} c #F9BFA0", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ # $ . . . . . . . . . . % & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * = - . . . . . . . ; > , ' . . . . . . . . . . ) ! - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~ { ] . . . . . . . ^ / / ( . . . . . . . . . . _ : < . . . . . . . . . . . [ } | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 3 . . . . . 4 5 6 . . . . . . . . 7 8 . . . . . . . . . . . 9 0 . . . . . . . . . . . a b c d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e : f } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g h i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 : j k . . . . . . . . . . . . . . . . . . . . l m n o . . . . . . . . . . p q . . . . . . . . . . . . . . . . . . . . r s t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u v p . . . . . w x y . . . . . . . . . . . . . . . . . . . . z A B C . . . . . . . . . i k D E . . . . . . . . . . . . . . . . . . . F G H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I J x . . . . . . . . . . . . . . . . . . . . . . . . . . . . K ! L M . . . . . . . . . N c O P . . . . . . . . . . . . . . . . . . . Q R S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T ] U . . . . . . . . . . . . . . . . . . . . V W X . . . . . . Y Z . . . . . . . . . . . ` ] .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +.. . . . . . . . . @.#.. . . . . . . . . $.%.&.*.=.. . . . . . . . . -.;.>.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,.'.).!.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~.{.. . . . . . . . . . . . . . . . ].^./.(._.. . . . . . . :.<.[.<.D }.. . . . . . . |.1.2.3.4.. . . . . . . . . . . . . . . . 5.6.. . . . . . . . . . . . . . . . . . . . 7.8.9.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a.b./ c.. . . . . . . . . . . . . . d.^.<.e.f.g.. . . . . . . h.i.[.<.j.. . . . . . . k.*.e.[.j 6 . . . . . . . . . . . . . . . l.*.1.m.. . . . . . . . . . . . . . . . . . . . n.o.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p.j 2.$.. . . . . . . . . . . . . . q.r.[.[.s.t.. . . . . . . u.v.w.x.y.. . . . . . . z.r.[.[.A.B.. . . . . . . . . . . . . . . C.c *.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Z @ m E.. . . . >.F.G.H.. . . . . . . k A.I.*.J.. . . . . . . . q K.o . . . . . . . . . L.M.&._ o . . . . . . N.O.D P.Q.. . . . . R.S.. . . . . T.U.. . . . . . . V.W.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X.Y.w.Z._ `.. . . . . . 8 +.+l.. . . . . . . . . . . . . . . ++@+. . . . #+$+%+&+. . . . . . . , A.<.*+=+. . . . . . . . . . -+;+>+,+'+. . . . . )+!+~+{+. . . . . . . . . . . . . . ]+^+. . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . /+(+[.[.f._+. . . . . . . . . . . . . . _.. . . . . . . . . :+c :.<+. . . . . . . . . . . . . U.:.e.[.i.[+. . . . . . . . . . }+|+1+2+3+4+. . . . Q 5+'+6+. . . . . . . . . . . . . . 7+8+9+. . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0+a+. . . . . . . . . . . . < b+[.[.*+c+. . . . . . . . . . . . % d+k e+f+. . . . . . g+2.<.<.h+i+. . . . . . . . . . . . . # I.[.j+k+. . . . . . . . . . l+;+1+m+n+o+. . . . . p+}+q+. . . . . . . . . . . . . . r+s+t+. . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u+v+w+. . . . . . . . . . . . x+y+(+k ^+. . . . . . . . . . . . z+f.<.A+v.B+. . . . . C+B [.[.j D+. . . . | E+F+G.. . . . . G+H+I+J+3 . . . . . . . . . . K+L+M+N+O+P+. . . . . . . . . . . . . . . . . . . . . . Q+R+. . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E+! G.. . . . . . . . . . . . . S+T+U+. . . . V+W+( . . . . . . X+i.[.[.f Y+. . . . . Z+h+e.<./.X . . . ]+`+A. @b+; . . . . . . .@. . . . . . . . . . . . . +@@@#@$@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %@. . . . . . . . . . . . . . . . . . . . &@v+w.*.*@. . . . . =@A.[.e.-@;@. . . . . . >@,@'@)@. . . . !@~@{@]@^@/@. . . . . . (@P+. . . . . . . . . . . . . . . . . . . . . . . _@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -+:@Z . . . . . . . . . . . . . . H+i.[.e.:.<@. . . . [@}@|@'@1@2@3@4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@j@k@l@. . . . m@h.1.v+l.. . . . . . . . . . . . . . . . . . . . n@o@p@q@. . . . . . . 9+r@s@. . . . . . . . . . . . . t@. . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 u@X+I+v@. . . . . . . . . . . . w@:.<.[.[.r.x@. . . . y@z@A@B@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@D@E@F@G@H@I@J@K@u@L@. . . . . . M@N@. . . . . . . . . . O@P@Q@R@S@T@. . . . . _.U@V@W@X@. . . . . . . . . . . Y@Z@`@. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . #A.[.<.D H.. . . . .#+#@#. . . . . ##$#I.%#&#. . *#=#C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@C@-#;#>#,#'#. . . . . )#!#~#{#% . . ]#. . . . . ^#R /#(#9._#. . . . . :#<#[#}#|#. . . . . . . . . . . 1#2#2#. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3#4#5#. . . . . . . . 6#s.[.[.H+7#. . . 8#L A v+9#. . . . . 0#a#b#c#d#C@C@C@C@C@C@C@C@C@e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#F@t#u#v#C@C@C@C@C@C@C@C@C@C@C@w#x#. . . y#z#A#3+B#R . C#C@D#. . . . E#F#G#H#I#J#. . . . . . a t+% . . . . . . . . . . . . K#L#!.. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K L M#3.. . . . . . . . u.I+N#, O#. . . . k i.[.<.v.Y . . . . P#Q#R#C@C@C@C@C@C@C@S#T#U#V#W#X#|@Y#. . . . . Z#`# $.$. . . . . . . +$@$#$$$C@C@C@C@C@C@C@C@C@%$&$*$=$-$3+;$>$. C@C@C@,$. . . . '$)$!$~$. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . {$: y+j+. . . . . . . . . ]$B.^$i . . . /$:.e.[.[.1.y . . ($_$C@C@C@C@C@C@:$<$[$. . . }$|$[.[.[.A 1$. . . 2$L > j c 3$. . . . . . . . . . . 4$5$6$C@C@C@C@C@C@C@7$8$9$0$a$b$. c$C@C@C@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H.d$0+. . . . . . . . . . . . . . . . . e$f$<.g$h$. i$j$C@C@C@C@C@k$l$m$l@n$o$. . . p$j [.[.[.A.6 . . . q$g$[.[.<.D r$. . . . q+s$5#. . . . . . . t$u$C@C@C@C@C@C@C@v$w$. . . C@C@C@x$y$. . . . . . . . . . . z$A$B$. . . . . . . . o.C$D$. . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y E$F$G$H$I$C@C@C@C@C@J$K$L$M$N$[.O ^.O$. . P$f [.[.[.w.Q$. . . `+<.[.[.[.$#R$. . . S$^.(+y+T$Y . . . . . . . . U$V$C@C@C@C@C@C@W$X$. Y$C@C@C@Z$`$. . . . . . . . . %.%+%@%#%. . . . . . $%{+%%&%. . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . *%C@C@C@C@C@=%-%. . ;%B [.[.[.*+P$. . . L.w.B , # Q.. . . >%g$[.[.[.D r$. . . e+i.[.[.A.,%. . . . . . . . . . . '%)%C@C@C@C@C@!%~%{%C@C@]%^%Q.. . . . . . . /%(%_%:%<%[%. . . . . . M@r+}%|%. . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1%2%]+. . . . . . 3%/.x+4%. . . . 5%6%C@C@C@C@7%8%. . . . p.B [.[.[.w.R.. . . Q.9%0%a%0+. . . . <@b%> f$Y.c%. . . c.h+[.[.[.<.d%. . . . . -+/$. . . . . . e%f%C@C@C@C@C@g%C@C@C@h%i%. . . . . . . j%k%_%:%_%V@. . . . . . . M@l%m%. . . . . . . . . . E.n%. . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . | o%. . . . . . . p%n 1./@q%. . . . E f <.I._ r%. . s%C@C@C@C@t%u%v%. . . . . w%I+<.[.O v.x%. . . . . . . . . . . . . x%y%z%w%. . . . A%P e.[.[.i.B%. . . . C%D%E%F%G%. . . . . . . H%C@C@C@C@C@C@C@C@. . . . . . . . . I%J%K%<#L%. . . . . . . . . . . . . . . . . . . 0+M%N%O%. . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . >.: / P%. . . . . . Y.O [.I.Q%. . . . R%<.[.[.(+S%..T%C@C@C@C@U%V%W%y+k X%. . . . Y%`+c Z%`%. . . . . . . . . . . . . . . . . . . . . . . <+(+I. &:..&. . . +&@&#&$&%&&&/$. . . . . *&=&-&C@C@C@C@C@C@C@;&. -+>&,&. . . . . 0.z$_.. . . . . . . . . . . . . . . . . . . . ..'&)&!.. . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . !&_ ! ~&. . . . . {&v+[.[.<.j.. . . . ]&s.[.[.^&/&C@C@C@C@(&_&:&<&e.[.O [&. . . . . . }&. . . . . . . . |&1&2&3&. . . . . . . . . . . . . . 4&5&6&7&. . . . 8&9&$&0&a&b&c&. . . . d&C@C@C@C@C@C@C@C@C@C@C@e&f&g&h&i&j&. . . . . . . . V.k&l&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . Y m&. . . . . . . n&o&I.(+0%. . . . q L p&q&;#C@C@C@C@r&. . *.<.[.[.[.r.s&. . . . . . . . . . . . . *@t&A.A.t&u&. . . . . . . v&w&. . . . . . . . . . . . x&b&$&0&a&y&z&. . . . A&C@C@C@C@C@C@C@C@C@C@C@B&C&D&E&F&G&. . . . . . . H&[%r+I&o.. . . . . . . . -+J&G&K&. . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p w+L&U . . . . . . M&N&O&C@C@C@C@P&. . . Q&i.[.[.[.c R&. . . . . o :@x%. . . . S&{ [.[.[.e./.T&. . . . p U&k Y.(.V&. . . . . . . . . . W&8&#&$&z#E%!.. . X&Y&Z&`& *.*+**&@*#*C@C@C@C@C@$*%*E&&***. . . . . . =*-*;*>*,*'*. . . . . . . . )*!*~*J&. . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . {*C@C@C@]*. . . . . ^**.O i.w./*. . . . (*_*1.(+/@:*. . . <*j [.[.[.[.f.[*. . . . }*&.<.<. @R%|*. . . . . . . . . . 1*2*3*4*5*. . ^#6*7*8*9*0*. . . . . a*b*c*C@C@C@d*e*f*j%. . . . . . /$g*;*>*,*r+. . . . . . . . % h*i*l%. . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . j*C@C@C@k*. . . . . . . R.l*Z%m*. . . . . l*M#[.[.<.{ n*. . 4&f.[.[.[.[.Z.F.. . . x@1.[.[.[.[.j+6 . . . . . . . . . . . . ... . . . o*p*q*3+r*s*t*. . . . . . . u*v*C@w*x*,&. . . . . . . . y*z*'*q@L#. . . . . . . . . A*0+. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B*C@C@C@C*. . . . . . . . . . . . . . . . s&1.[.[.[.[. &d+. . q D <.[.[.<.v+D*. . . /+M.[.[.[.[.s.E*. . . . . . . . . . . . . . . . . #&B#q*3+r*F*G*. . . . . . . . . H*I*J*. . . . . . . . . . K*n.L*. . . . . . . . . . . . . . . . . . . . . M*N*O*. . . . . . . ", +". . . . . . . . . . . . . . . . . . . . |&7#. . . . . . R&P*# u&. . . . . . i Q*R*S*. C#C@C@C@T*. . U*& . . . . . . . . . . . . . V*$#[.[.[.[.O (.. . . P$v+w.w.v+z . . . . k.t&[.[.[.[.j w+. . . . W*X*x&Y*q+. . . . . . . . #@%&q*3+Z*`*L%. . . . . . . . . . . . . . . . O*J# =.=. . . . . . . . . . . . . . . . . . . . . . . . . +=@=#=$=. . . . . . . ", +". . . . . . . . . . . . . . . . . . . c%c : %=. . . . . # M#A+(+=.. . . . . B%*+&=,#*=C@C@C@==. -=h.r./.;=u . . . . . . . . . . . r%d%<.[.[.[.j >=. . . . @#1$1$O$. . . . . . ,=, <.e.s.^.'=. . . )=!=~=)={=]=L*. . . . . . . . ^=/=(=_=:=. . . . . . . . . <=[=}=|=. . . . 1=6+2=6+3=. . . . . . . 4=k&t+i . . . . . . . . . . . . . . 5=6=-+. . . . . . . ", +". . . . . . . . . . . . . . . . . . . n&Z.t&7=. . . . 8=*.[.[.O O#. . . . :@y+[.9=0=C@C@C@a=. . Y.I.[.[.f.b=. . . . . c=( d=. . . . e=c g$I.f.@ f=. . . . . . . . . . . . . . . E k I+;=(@. . . g=h=i=j=k=l=m=m+. . . . . . . . . q+n=. . . )*o=p=. . . . q=r=G#l+s=t=. . )*u=_%:%:%v=w=. . . . . E#x=y=z=&%Q+. . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . #.6#A=. . . . . p D O e.f.p.. . . . R$h+B=C=C@C@C@D=. . E=r.[.[.[.<.e+. . . . h `+(+t&F=G=. . . H=I=<.J=^+. . . . . . . . . . . . . . . . . . 1%. . . . . K=L=i=j=k=l=M=N=. . . . . . . . . . . . . O=P=r*Q=R=. . t G S=/#(#E&T=L*. Y@D&_%:%:%U=V=. . . . . i*W=X=Y=Z=`=. . . . . . -V.0+. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . .-Y.I++->.. . . . . @-#-C@C@C@$-. . . 2$/.e.[.[.A+# . . . 3#h+<.[.[.j+:+. . . . . . . . . . . . . . . . . |&%-Q*&-. . . . . . . . . . . *-=-i=j=k=l=--;-. . . . . . . . . . . . >-{#1+m+r=,-'-. )-!-S=/#(#E&s=R+. . ~-{--*W@Y=. . . . . . ]-^-X=Y=z=/-. . . . . (-~*_-:-. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M@. . . . . . . <-C@C@C@[-. . . . . u+, A+i.H+$.. . . O#O [.[.[.e.c }-. . . . . . . . . . . . . . 1%|-y+j &.*. +. . . . . . . . . . !.1-@&j=k=M=2-3-. . . ,.. . . . . . . . )#4-1+m+r=5-l+. ..G 6-/#(#7-I#. . . . z$C$0.. . . . . . . i H&8-&%9-... . . . . 4=0-a-b-. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C@C@C@e#. . . . . . . c-d-L.e-. . . . r.A+[.[.[.[.r.f-. . . . . . l d.. . . . . . g-f$[.[.[.[.(+h-. . . . . . . . . . $ i-h=!=!=j-. . k-l-m-6*n-. . . . . . o-p-1+m+r=q-r-. . l&s-t-u-v-w-. . . . . . . . . . . . . . . ..R+P+. . . . . . . . x-y-K#. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . z-_+. . . . . . . . . . . . . . . A-S.B-. . v#C@C@C@C-. . . . . . . . . . . . . . . D-B [.[.[.<.:.#+. . . . E-x P *.Y.F-. . . | %.e.[.[.[.[.<./@. . . . . . M@. . . . . N@{.. . . G-H-%&I-J-F%K-. . . . . L-F 3+M-n+N->.. . . . Y@Y@. . . . . . . . . . . . K#. . . . . . . . . . . . . . . . . . . . . . . . . . O-P-0+. . . ", +". . . . . . . . . . . . . . U*: b.Q-. . . . . R-( . . . . . . S-(+, L T-U-C@C@C@V-. . . . . . . . . . . . . . . . 8 u@f$I.M#x.W-. . . . . X-j <.[.<.2.Y-. . Z-A [.[.[.[.[.[.*.`-. . !.%& ;.;+;@;. . . . . . . U.#;$&0&a&$;%;&;]+. . . . . {$*;=;-;* . . . . . . . . . . . . . . . . . ;;[%>;,;% . . . . . . . . . . . . . . . . . . . . . . . Q.';P-);. . . ", +". . . . . . . . . . . . . . . =@6&Q+. . . . !;/.y+~;^+. . . u.A [.[.{;];C@C@C@^;. . . . . . d=/;. . . . . . . . . . N.E (; +S$. . . . . ^*M.[.[.[.[.e.*./;. _;/.[.[.[.[.[.<.D . . 0+:;<;[;i-};|;};. . . . . . 1;@&$&0&a&$;$;2;.#. . . . . . . . . . v&3;4;5;G%. . . . . . . . . . . L*6;{+7;7+8;. . . . . . . ... . . . . . . . . . . . . . . . % 9;. . . . ", +". . . . . . . . . . . . . . . . . . . . . 0;*.[.[., W . . . a;w.[.b;c;C@C@C@d;. . . . . * j+H+y+P e;. . . . . . . . . . . . . . . . . . C s.[.[.[.[.[.f.f;. . g;g$[.[.[.[.> E . . 7*h;=-i;i-D%j;k;l;. . . . . 3 =-$&0&a&$;%;&;]+. . . . . . . . . K#m;n;o;p;q;)+. . . . . . . . . . n.r;s;>*t;u;v;. . . . O*w;x;y;t . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . z;A [.[.f$A;. . . U.B;A.C;D;C@C@C@E;. . . . . D-j [.[. @P . . . . F;F-%-G;. . . . . . . . . . H; &[.[.[.[.[.f.G.. . x%Y.*+g$M#(+B . . . I;J;=-i;i-D%j;K;L;. . . . . . M;H-N;0&J-O;P;. . . . . . . . . . Q;R;s=S;F&T;U;. . . V;W;X;%%X@. . x-Y;Z;>*>*`;. . . . . >x;|=.>h*U+. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . -+[&Z.j+L q.. . . . 2$+>@>C@C@C@#>$>%>&>. . . v+<.[.[.[.r.q%. . *>P j j c =.. . . . . . . . . f;> [.[.[.[.[.1.=>. . . U+->;>>>.&. . . . ,>J;=-i;i-D%j;K;'>. . . . . . . )>F%!>'>~>. . . . . . . . . . . {>M-s=S;F&]>^>. . />(>_>:><>E&A*. . 1#-*I&[>x-. . . . . }>|>1>1>2>M*. . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . r%*>3>~&. . . . . . . 4>C@C@5>6>P*i.*.3#. . /@<.[.[.[.P 7>. s&%.e.[.[.e.c G;. . . . . . . . l Y.M#e.[.<.> 8>. . . . . . . . . . . . . 9>0>=-i;i-D%j;a>b>. . . . . . . . . . . . c>B#z#d>e>. . . . . . T.f>g>S;F&R h>. . i>j>k>-*l>6+W.. . . -+E.... . . . . . A$m>|=n>h*,.. . . . . . >.:#. . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o>C@C@C@p>N$[.[.i.# . . $+*.O i.o&n&. . 4&f.[.[.[.[.j m.. . . . . . . . . (*d+c h+`+q>. . . . . . . r>s>t>u>v>w>x>y>z>A>i;i-};B>C>. . . . . . . . . . . . D>E>F>7*7*G>H>. . . . . . Q;I>^>J>R@. . . K>U=k>-*l>L>M>. . . . . . . . . . . . A*N>O>2#P>. . . . . . Q>:-R>Q+. . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C@C@C@S>T>[.[.[.<./@. . . Z+(.X-=.. . . 9%f.[.[.[.[.&.U>. . . . v&V>3&4.. . . | W>M@. . . . . . . X>Y>Z>`> , ,.,+,. M@@,#,$,%,&,m%. A**,@&=,0&o=. . . . . -,;,>,q*q*3+z#Y . . . . . . 0+/%t . . . . 8;'.k>-*,,U@l&. . . . . . . . . . . . . . . . . . . . . . . ',),b-!,. . . . . . . . . . ", +". . . . . . . . . 0+Z . . . . . ~,k ;.. . . . . . . . . {,. . ],C@C@R#. ^, @[.[., T . . . . . . . . . . /,/@e.[.[.e.:.(,. . . 1$`+A (+:._,. . . . . . . . . . . :,<,[,},},|,1,2,3,. . . l N.#+. . v&4,5,)=M=--6,7,. . . P+F%,+>,q*q*3+%;8,. . . . . . . . P+9,. . . . :>8.(%0,1;. . . . . . . . . . . . . . . . . . . . . . . . x-a,L#. . . . . . . . . . . ", +". . . . . . . . . Q&! b,. . . c,:.I.P . . . . . . . 0 P *.d,e,C@C@C@,$. f,@ r.Y.g,]+. . . . . . . . . . . h,J > > I+6.. . . 3&:.<.[.[.<.f i,. . . . . . . . . . j,k,},},l,m,n,C@o,. . . . . . . . p,8&j=k=l=l=q,#;r,. . |#s,;,>,q*q*3+N;9 . . . . . . M@t,P@u,v,t . . . r%;;0+. . . w;z*I&1;. . . . . . . . q+;;w,. . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . x._ &@. . . % `+:.x,. . . . . . . [& @[.y,z,C@C@A,. . . . B,C,. . . . . . . . . . . . . . D*$+D,2%. . . . E, @[.[.[.[.<.:.d.. . . . . . . . . F,n,},l,G,. . . H,. . . . . . . p I,J,j=k=l=K,L,M,N,. . . O,2;p*q*A#P,Q,. . . . . . . q;R,F&S=S,r=. . . . . . . . T,U,r+{+I&z$. . . . . . K&W=<=V,',. . . . . . . . . . . . . . . % W,% . . ", +". . . . . . . . . X,p%. . . . . 0+Y,. . . . . . . r$/.[.Z,`,C@C@C@ '. . . . . . . . . . 8 S&H.. . . . . . . . . . . . . . .'P <.[.[.[.[.[.(+w%. . . . . . . . o,+'},[,@'. . . . . . . . . . . . % #'J,j=k=$'%'&'*'='-'. . . ;'y&y&y&>'. . . . . . . (*F#S;F&S=/#u-L%. . . . . . . 8;,'''s;)'^-. . . . . . |%|>1>1>!'/$. . . . . . . . ~'{']'^'/'. ('_':'. . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . h.<'B=['C@C@}'. . . . . . . . . . |'I+A /@1'. . . . v@X-%>3>v&. . . . . /.<.[.[.[.[.[.y+q.. . . . . . . . 2'3'},4'5'. . . . . . . . . . . . . 6'{=j=k=7'8'9'0'a'b'. . . . . E.. . . . . . . . . c'd'S;F&S=/#r=x-. . . . . . . e'z*''s;r+f'. . . . . . O>|>1>1>!*`-. . . . . . . . g'h'i'j'k'. v&l'v&. . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . o%m'n'C@C@C@a*. . . . . . . . . o'Y.<.[.<.Y.8#. . &*+i.i.f.%>. . . . . p'A.[.[.[.[.i.Y.. . . . . . . . . q'r'},4's'. . . . . . . . . . . . . t'u')=k=7'v'w'},x'y'. . . . . . . . . . . . . . . . s !-z'T;U;b$. . . . . . . . j&V@A'q@x=:#. . . . . . B'W=<=C'M%. . . . . . . . . D'E'},F'G'. . . . . . ", +". . . . . . . . . . . . . . . . . . . . C,v&. . . . . . H'C@C@I'. . H.3%4#J'a . . . =.f$[.[.[.j v@. |&y+[.[.[.[.2.K'. . . . L'@ f$A+<.s.D 3&. . . . . . . . . M'r'},4's'. . . . . . . . . . . . . . N'h=O'P'Q'w'},x'y'. . . . . . R'S'T't*U'. . . . . . V'W'R,X'. . . . . . . . . . . }&}&. . . . . . . . . L*Y'Z'. . . . . . . . . . D'E'},F'G'. . . . . . ", +". . . . . . . . . . . . . . . . . . `'O#/.u@ ). . . . .)C@C@C@a*. N.+)j+I.f.Q&. . . 4&> [.[.[.> z-. z-f.[.[.[.[.A.@). . . . . /$#)y+d-k+(,. . . . . . . . . . $)r'},4'%). . . . . . . . . . . . . . . . &)*)=)-)},x';). . . . . >),)')))!)~){). . ])^)/)(). . . . . . . _):):)<)[). . . . . . . . . . . . . . })|)^)1)2). . . . . . . 3)E'},F'4). . . . . . ", +". . . . . . . . . . . . . . . . . . 5)j [.A+u@G=. . . 6)C@C@7). . 8)f.[.[.[.2.9). . 9 b%M#i.M#0)x%. a)M.[.[.[.[.> y%. . . . . . . . . . . . . . . . . . b)c)n,},|,},n,|,d)|,l,e). . . . . . . . . . . -)f)g)h)|,},|,n,},|,1,i)j)k)l)m)n)o)p)q)r)s)t)u)C@v)w)w,. . 1)x)y)+'u)u)z)F,%)A). . . . . . . . . . B)C)D)3'u)3'D)E)F). . G)4'},n,|,},[,|,},|,|,H)I). ", +". . . . . . . . . . . y.H+D,. . . . j @[.[.*.J). . K)C@C@C@L). . B.B [.[.[.f.a%. . . 2$/*L.` <@. . M)`+I.[.[.O n x%. . . . . . . . . . . . . . . . . . N)x'1,|,},},},n,1,1,O)P). . . . . . . . . . . Q)4'1,|,},},},|,1,1,R)S)T)U)V)W)X)n)Y)Z)`) !n,},.!+!@!#!$!%!&!*!|,n,1,|,n,n,=!-!;!>!. . . . . . ,!},u)4'n,},},},n,4''!)!!!~!{!1,|,},},},[,1,1,1,&!. . ", +". . . . . . . . . . G=: O : t . . . ]!r.I.j+^!. . . /!C@C@(!. . . _!X+[.[.e./.S&. . . . . . . . . . . C,l**.H+Z%4%. . . . . . . . 2$S.~ :!. . . . . . . 7!8!9!V)0!n,},a!b!c!6!i'd!e!f!g!$!h!i!n,j!u)k!4'}!l!m!},n,n!o!p!. . . . o,q!=!},n,r!s![!m,t!},u!v!w!x!l,}!4'},},},6!}!}!}!7$. . ", +". . . . y!d%+-. . . . O#*.z!. . . . . A!B!C!d.. . D!C@C@C@E!. . . . =@t&O#P [ . . . . . . . . . . . . . . F!}-. . . . . . . . . G!I+> f.A O#H!. . . . . I!J!K!L!|!},|,M!N!O!P!Q!. . . . . . . . . % R!S!T!U!V!5!},6!W!X!O!Y!Z!. `! ~0!n,},},a!Z>.~+~@~#~$~%~&~*~=~-~s);~. . . >~,~'~},)~!~~~. . . . {~=!},n,]~^~/~(~_~6!O):~<~[~}~|~1~2~4'},6!3~4~5~O!6~... ", +". . . . 7~8~9~}&. . . w@5#:#. . . . . . . . . . . 0~C@C@a~b~/+. . . . c~d~1 . . . . . . . . . . . . . . . . E=e~f~{$. . . . . g~{ <.[.[.[.B h~. . . . . . . . i~r'},4'j~. . . . . . . . . . . . . k~#;M,l~m~n~w'},x'o~. . . . . p~q~r~n,},n,@'s~. . t~u~v~F&S=w~x~y~. . . . . . z~A~u!|,k!. . . . B~[!},n,C~D~[~. . . . E~F~. G~. . . H~E'},I~J~. . . . . . ", +". . . . . K~S+. . . . . . . . . . . . . . . . . . C@C@C@L~M~N~. . . . . . . . . . . . L*n*O~F!. . . . . q+F=1.w.2./@;.. . . . P~I.[.[.[.[.[.1.Q~. . . . . . . M'r'},4's'. . . . . . . . . . . . . R~=,j=k=7'v'w'},x'y'. . . . . . . S~T~}, ,U~. . . . s !-z'T;U;V~. . . . . . . . W~X~},F,Y~. . . Z~6!},`~ {.{#+. . . . . . . . . . . D'E'},+{@{#{${. . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . %{C@C@C@T>&{| . . . . (*w@. . . . . *{j.f M./@Q*. . . . ]&A.[.[.[.<.8~(,. . . Z%<.[.[.[.[.[.M.;.. . . . . . . M'r'},4's'. . . . . r'd)d)d)d)d)d)={-{;{j=k=7'v'w'},x'y'. . . . . . . >{T~},,{'{. . . . . ^-){R,W=. . !{~{{{]{^{/{({_{6!},+':{. . <{[{n,n,}{|{. . . . . . . . . . . . . D'E'},+{1{#{q+. . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . 2{C@C@3{4{G+. . . ~.(.c `+:*. . . L*L A+[.[.<.P S&. . 5{r.[.[.[.[.[.M#6{. . . (.O [.[.[.[.[.X+R$. . . . . . . M'r'},4's'. . . . . 7{6!1,1,1,1,1,8{9{0{a{k=7'v'w'},x'y'. . . b{$ c{. S~T~},+'d{. . . L-Q+. . . . e{f{F,@'O)F'g{}!}!6!},},+'h{. . i{z)},1,j{. . . . . . . . . . . . . . D'E'},F']{. . . . . . ", +". . . . . . . . . . . . . . . . . . . Y@. . . . C@C@C@k{. . . . l{/@I.[.<.t&m{. . u.M.[.[.[.[.A._,. . W+, [.[.[.[.[.i.S-. . . 2 2.[.[.[.[.i.Y.. . . . . . . . M'r'},4's'. . . . . 7$}!*!*!*!*!*!n{o{p{q{@&r{s{w'},x'y'. . t{&;9&u{V)r~n,},+'v{. R'w{x{d',,. . y{z{A{n,u!B{C{7!p)D{=!},},+'h{. . E{3'},6!F{. . . . . . . . . . . . . . D'E'},F'G'. . . . . . ", +". . . . . . . . . . . . . . . . . }-G{P H+H{. I{C@C@J{. . . . . K{A [.[.[.I.L{. . M{w.[.[.[.[.B N{. . O{M.[.[.[.[.[. @g$. . . . P{b+g$I.j u@4%. . . . . . . . M'r'},4's'. . . . . Q{R{|~|~|~|~|~S{T{. O@U{q~V{W{},x'y'. X{s,;,>,Y{Z{0!n,},+'`{E-P= ]Q,s=t,.]+]7$n,},x'@]#]$]%]&]*]=]=!},+'h{. -];]>]n,|,s!. . . . . Q+. . . . . . . . D'E'},F'G'. . . . . . ", +". . . . . . . . . . . . . . . . . <'M#[. &} . ,]C@C@']. . . . . s$%>[.[.[.I.L{. . )]/@e.[.[.[.A 1$. . M@D <.[.[.[.[.f !]. . . . . ~]{]O.]]| . . . . . . . . . M'r'},4's'. . . . . . . . . . . . . . . . . . ^]l,},x'/]. 4*J-,+>,Y{V)0!n,},+'(]_]:]5+Q,s=s=<][]}]},`>|]1]2]3]4]5]6]7]4'},+'8]9]0]a]b]|,},@'c]. . ..4+i*d]. . . . . . . e]E'},F'f]. . . . . . ", +". . . . . . . . . o%g]h-. . . . . Y.<.[.e.h]i]C@C@C@. . . . . . U+/@I.[.<.t&M{. . . %-c A.B A 6&. . . . a./@M#i. @f j]. . . . . . . . . . . . . . . . . . . . M'r'},4's'. . . . . . . . k]l]$&m]9,. . . . . n]l,},F'o]. y&4*p]&,Y{V)0!n,},+'(]q]M+5+Q,s=s=r]s]t]},,{u]v]s -*l>w]x]7!n,},+'y]z]A]B]C]D]},1,F'E]. F]G]H]I]K). . . . . . J]K]},}!L]. . . . . . ", +". . . . . . . . . M]A./@x@. . . . N]*+i.f.O]P]C@C@Q]. . . . . . . -=l*c `+:*. . . . . V>R]B.a). . . . . . 0 S]O#|-e-. . . . . . . . . . . . . . . . . . . . . M'r'},4's'. . . . . . . H-T]|;U]B>V]W]. . . . a=X]},|,F'Y]Z]`] ^&,Y{V)0!n,},+'`{*],+5-)#g>J>.^+^=!},`>@^#^%*$^%^&^*^=^},},+'8]-^;^>^,^'^n,},)^F'!^. ~^{^]^^^/^. . . . . (^_^},n,@':^. . <^[^. ", +". . 3&;=G+. . . . ,%}^/ A%. . . . Q.N{X+|^. 1^C@C@2^3^->m.4^. . . . . H!u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5^]]U>q.. . . . . . . M'r'},4's'. . . . . . C%6^i;i-D%j;7^1-(*. . . 8^@'},},1,9^0^a^b^c^Y&d^0!n,},+'e^. D$z'f^J>T@. g^Z>},},E'h^i^j^k^4!l^m^n,},+'h{. j%H&n^o^p^n,},1,[!q^r^B{s^|,3't^. . . . u^j'},},|,3'1,6!C@I). ", +". . ^,h+v^. . . . p ;.V+. . . . . . . . . w^C@C@C@3^x^w.f.R%/;. . . . . . . . . . . . . . . . . . . . . . . . . _;y^Z.I.Q*. . . . . U.B%(+f$j /.u&. . . . . . M'r'},4's'. . . . . . z^C>i;i-D%j;A^#;B^. . . . 7{|,},},n,n)X)C^D^E^F^G^T~},+'e^. . . . . . . . H^I^},},4'X~i)J^}!K^L^M^},+'8]. . . . . N^O^4'n,},[,1,|,},n,=!C@P^. . . . 9^6!},},n,1,1,[{. . ", +". . H=j]d=. . . . . . . . . . . . . . . . Q^C@C@R^S^T^[.[.M#;>. . . . . #+1%. . . . . . . . V>g~7 . . . . . . &-^.A.O @, L.Q+. . . E,M#[.[.[.e.h+K.. . . . . U^C@@'+'j{. . . . . i V^O'i;i-D%j;A^W^X^. . . . Y^z{_^Z^ ,}!x'`^. . . C@r' /C@./. . . . . . . . +/@/[{l,}! ,F''!#/. $/%/&/C@*/. . . . . . =/-/[{O)}! ,g{O);/>/,/. . . . . '/Y>s!`> ,*!F'C@... ", +". . . . . . . . . . . . . . . . . . . . . )/C@C@!/~/w.[.[.g${/. . . . q>`+I+p'. . . . . ++h.X+M.I+]/. . . . . h.i.[.[.[.[.f.^/. . E=H+[.[.[.[.[.O _*. . . . . //(/_/:/i;i-D%j;A^=-}/. . . . . |/1/2/3/4/5/6/. . . 7/8/8/9/I). . . . . . . . . . 0/a/b/c/d/e/. . f/g/h/i/j/k/l&. . . . . . l/m/n/o/w>p/q/r/s/. . . . . . <^s>t/J!u/v//~. . ", +". . . . . . . . . . . . . . . . . . . . C-C@C@C@. w/j.j A.v+^ . . . B.M.<.<.> n&. . . . h.I.[.[.<.*.x/. . . &-y+[.[.[.[.[.<.H+. . b,f [.[.[.[.[.e.H+}.. . . . y/z/A/B/C/% . . . . . D/[/i;i-D%j;E/F/* . . . . . G/H/I/J/K/. . . . . . . . L/M/Y@. . . . . . . . X.N/. . . . . . . . j)O/P/Q/,*'*... . . . . . . . . . . R/S/T/0+. . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . a=C@C@U/. . H.V/y^S&. . . U+W/<.[.[.e.:.3 . . X/y+[.[.[.[.g$Y/. . . Z/2.[.[.[.[.[.<.:.. . ~&r.[.[.[.[.[.i.p&. . . . `/ (.(+(@(I;#(d.. . . . . $(V^<;%(&(*({,. . . . . =(@&z#%&N;E%r . . . . . . ;'~#-(;(r=>(. . . . . ,(!-h&f*z$. . . . . . n.r;s;>*t;u;'(. . . . . . . . . . . . j%P>. . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . )(!(~({(](},^(. . . . . . . . /(/@e.[.[.e.c N.. . (((+[.[.[.[.I._(. . . K c e.[.[.[.[. @E,. . . X-I.[.[.[.[.(+:(. . . U'<([(}(|(1(2(3(4(. . . . . . 5(6(*,7(. . . . . . '$8(9($&0&a&0('>. . . . . '$a(b(1+m+c(l>. . . . {$d(R@E&E&e(l{. . . . . q+6;f(7;7+H&. . . . . . U'L#D$. . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . s!A{},},},t!g(h(. . . . . . . . I=f.<.<.j++-. . . U.^.<.[.[.[., F-. . . . ;>f.e.[.[.<.Y.i(. . . K :., B B r.j(. . . . k(l(m(}(|(1(2(n(o(r$. . . . . . . . . . . . . . . p(l-9($&0&a&q(l-K#. . . . r(F*s(1+m+t(Q=. . . . u(t-(#E&E&v((*. . . . . . 5(8+I&w(i . . . . . . 2#m>z=E.. . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . x(P*X%. . . y(k!},},},},},l,z(. . . . . . . . 0+q$P c ;={$. . . . !]:.B s.w.L.-+. . . . . =@*.w.M./@D,. . . . . !.2 x,q>A(. . . . . *-B(m(}(|(1(2(n(C(D(. . . . . . . . . . . . . . . 8,D%9($&0&a&J-/=. . . . . E({#s(1+m+F(G(. . . . j&!+l+H(k%I(. . . . . . . . . ... . . . . . . . z=~$O>(-. . . . . . . . . . . . . . . . . . . . ", +". . . J(K(. . . . . *{P j+L(. . . M(`>},},},},},|,n)N(4$. . . . . . . . d.{.. . . . . . . O(N{I y%w@. . . . . . . c.P(Q({$. . . . . . . . . . . . . . . . R(S(m(}(|(1(2(T(U(q+. . . }&W*V(D/@.. . . . . . . . '>)=#&W(a(H-'-. . . . . :#X(Y(Z(R;`(z$. . . . . w,}=v- _M@. . . . . . . . . . . . . . . . . . >.k&L#. . . . . . . . . . . . . . . . . . . . . ", +". . ._v+! +_. . . . R&: *.p.. . . @_F'},},},},},d)+{C@C@#_$_%_. . . . . . . . . . . . . . . . . . . . . . . . . . . . l &_g+( . . . . . . . . . . . . . . . *_=_m(|(1(-_;_>_. . . ,_;_*('_<;)_!_. . . . . . . . ~_{_E%-,]_. . . . . . . i ^_q;+&R'. . . . . . . . ... . . . . . . . . . . . ..O@p=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . ^+p&/_. . . . . . 2$Z/. . . . (~&!n,},},},},1,C@C@C@C@C@C@(_I{. . . . . a)__:_c'. . . . . . L'3&o . . . . . . . <_u@w.f.1.=@. . . . . . Z-[_>=}_]+. . . . |_1_2_3_4_5_. . . 6_7_J;=-i;i-};}('$. . . . . . . . |#G=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8_`;'*9+. . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . 9_2,0_n,1,~(a_5$b_C@C@C@C@C@C@C@c_]). d_b+A.> u@3 . . . . &@n (+t&4#. . . . . . k i.[.[.[.(+e_. . . . #)/.j A.T^h.8 . . . . 8 f_g_w-. . . . h_i_j_=-i;i-D%k_l_. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~$m_M>... . . . n_A]{+o_. . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . {{A{u)p_f]. . . . q_r_C@C@C@C@C@C@s_t_c;^@[.j ; . . . u_L <.[.[.o&%-. . . . G;b+[.[.[.[.I.v_. . . }_r.[.[.[.[.s.O#. . . . . . . . . . . . I;w_j_=-i;i-D%};j;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x_X;y_6+Z;. . . . u M>1;... . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . z_A_B_C_D_C@C@C@C@C@E_F_G_H_O.. . . I_M.[.[.[.I.J_. . . . 0;b+[.[.[.[.I. &. . . B! @[.[.[.[.[.r./;. . . . . . . . . . . U]K_j_=-i;i-D%L_M_. . . . N_O_P_~=)>. . . . . . . . . . . . . . . . . j&N>Q_0+. . . . . R_i>l>_%:%S_X@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . '=->#.. . . . . . . . . . . T_W/&=U_V_W_X_C@C@C@C@C@Y_Z_`_. . . =>h+[.[.[.g$` . . . . }./@A+[.[.[.M.a%. . . :<.[.[.[.[.[.M..:. . . . . . . . . . . n-+:J;=-i;i-};+;@:. . . #:h=$:%:&:H-*:. . . . . :#=:N+-:O@. . . . . ,.;:!-n;>:^+. . . . |#S@,,_%_%J%. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . `+T^3.#+. . . . . . . . . . . V>,:':| . . ):j$C@C@C@C@C@!:. . . . Z.Z.i.s.v+~:. . . . . - ^.Z.f$b+P~. . . . J+O [.[.[.[.[.y+T&. . . S${:G.]:. . . . . ^:/:(:A>_:[/::. . . . =-$:l=q,9($&2*$ . . . . N;X(F*A#`*<:. . . . [:s-S;F&p;}:. . . . . 9+0,|:H(1:. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . #+_ j+: L*. . . . U*2:7>. . . . . . . . . . . . 3:4:C@C@C@C@5:6:. . Q.6 p&6&7:. * *{7#. . . B-9%J=I_. . . . . 8:X+[.[.[.[.I.B%. . . g-t&f.f.r.,=. . . . . 9:0:a:b:/%. . . . c:h=d:l=q,9($&N=e:. . . D>%&q*3+r*f:p-. . . . [:!-S;F&p;g:. . . . . . :#w,K#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . h:9). . . . . 5#i:- . . . . j:I+M.L -.. . . . . . . D*k:. . . . l:C@C@C@C@C@m:. . . . . . - +)A *.;=]+. . . . . . . . . . . <+1.A.B *+`+K . . n:T^[.[.[.[.> o:. . . . . . . . . . . . . . p:M=l=q,9($&q:O@. . . r(o*q*3+r*r:s:. . . . ,.t:!-n;G u:. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . B+] v.v:. . . . . . . . . . v&W/<.[.I.w:. . . . . . |.c { P~. . . . . x:C@C@C@C@T%y:. . . G=^.A+[.[.*+z:. . . . . Y,7:q+. . . . ^ A;A:B:v&. . w@x.<.[.[.[.[.e.8~{$. . . . . . . . . . . . . C:J;D:q,9&N=E:. . . . r,6*A#3+r*F*F:. . . . . K#G:H:v&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . %>B;I:. . . . . . . . . . J:I+<.[.O X-. . . . . _!b+[.[.T^{:. . . . . K:L:C@C@C@C@M:. . N:$#[.[.[.O _*. . . <@Q&r.A W/O:. . . . . . . . . . P:1.[.[.[.[.[.[.y+Q:. . . . L*'=. . . . . . . . R:6,8(6,S:. . . . . . T:6*U:I-;+-+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . p.r.j :.V:. . . . . W:j [.[.B A:. . . . 9)X:Y:Z:C@C@C@C@`:. q]1.[.[.[.I.P*. . ]+P I.[.[.<.x.Q~. . . . . . . . . _.I+<.[.[.[.[.e.P x%. . . V . . . . . . T_c <.<.1.K.. . . +<%.I.g;@<#<$y^. . . . . . . . . . . . . . . . f;k :.x(. . . . k+s.[.[.> *<. =. . b,d%b+1.B%2$. . . . 3#;>g-e_]+. . . ]<(+[.[.[.[.I.L{. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . q>*@. . . . . . . . . . ^. . . . . . . . . R&L M.A l*. . . /<(<_ L.p . G++)<.[.[.I.Y.]+. . . . . . . . . . . R&%.e.[.[.[.A.b=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . 0+a%a.. . . r$Y.[.[.i.r.. . . . . . . . . . P+1$i(. . . U.R%<ru.. . . . . . . }*X+$>w <.<.2.E . . Z<`<. . . . . . J:9)9<. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [! ! x%. ( .[j(. . . 7>x@. . . `-L A.s.c J.. . . . . . . . +[C@C@C@C@@[)@#[[.[.[.f$$[. . . . I_%[R.p . . . . . . . ]+x,:.:.&[. *[C@C@=[. . . . . )]L M.y+B!. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H{7 . . -[s.*.;[. . . . . . . >[M.[.[.I.g;. . . . ,[. . . . +$'[C@C@C@)[J@![[.[.j D+. . . q$y+f$T^Q&X.. . . . . . . . w@. . ~[C@C@{[][Y<. . . . C!B [.[.X+O{. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ]//@: x%. . G+. . . . < b+[.[.s.6#. . Y B!/@Q&-=. . . . ^[C@C@C@C@/[([i.^.o%. . |&r.[.[.[., z<. . . . 5#[ G._[. :[C@C@C@C@<[[[A }[. . . :+s.[.[.*+d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B,u:. . |[/ f;. . . . 1[A , _ Q~. . 2[f$[.I.Q&. . . . . 3[C@C@C@C@4[5[6[. . . !]> [.[.[.M#7[. . . T+D j+8[9[0[C@C@C@C@C@a[b[A.E . . . K(/. @s.R%@+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e$v.%+. . Z K.1%T+1<}-. . . *.A+[.[.:.N@. . . 9 z<. . . f[g[G_h[i[C@C@C@C@C@j[G<<.*.;.. . . . k[x+6#l[. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u m[. . n[/ $#x+. . . . . . <+> <.N#l*. . v&y+X+A n$o[p[C@C@C@q[r[. . . d+b+f$w.Y.!&. . . s[t[u[C@C@C@C@C@C@C@v[w[8~J=. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m&L A.u@. . . . . . U+S]D ;={.. . j:*+[.[., x[. y[C@C@C@C@==. . . ~]x(z[#+. . . A[B[C@C@C@C@C@C@C@C@C@. *]*]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z C[Q:. . . .#. . . . . . . . . m*f$[.[.A.D[. . E[C@C@C@C@4:F[. . . . . . . G[C@C@C@C@C@C@C@C@C@C@H[. . . &@!<[_U+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I[J[K[. . . . . . . . L[8~ @ @8~M[. N[O[P[Q[C@C@C@C@R[. . . . . . C@C@C@C@S[T[C@C@C@C@C@U[. . V[P B w.W[. . . /(. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H+:.*>. . . . X[. . . . Y[w:w:/+. . c%f.K@B=Z[C@C@C@C@C@`[H*. . . }.}+}. @}C@C@C@C@C@C@#}. . e$I.[.[./.<@. $}! %}. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5^. . . Q.Q&_ 3$. . . . . . . . . &}A.[.[.*}=}-}C@C@C@C@C@;}>},}'})}!}~}C@C@C@{}]}C@C@^}. . /}B [.<.u@}&. _ <.J & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A>. . . r%x}: w&. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . y}J A.M]. . . . z}e$8=. . 9 _ _ z[. . := self.expectedBytes:# -> is it what we expect + newData = self.tcpSocket.read(self.expectedBytes) # QByteArray + self.expectedBytes = 0 + if self.expectedDatatype == 0: # trcHeader + self.decodeTrcHeader(newData) + elif self.expectedDatatype == 1: + self.analyzeRawData(newData) + else: + print('Received unknow datatype' + repr(self.expectedDatatype)) + else: + print("Waiting for more data : expecting %s, got %s"%(str(self.expectedBytes), str(bytesAvailable))) + + def decodeTrcHeader(self, data): + self.trcHeader = {} + print('Got Trc Header !') + + def analyzeRawData(self, data): + #Separate data from each electrode ? + # Signal filtering + # We have displayable data ! + # Should we send a signal to refresh the display (max 30fps) ? + print('Got raw data') + + def closeSocket(self, message="no reason given"): + print ('Closing socket : '+message) + self.tcpSocket.abort() + self.expectedBytes = 0 + self.expectedDatatype = -1 diff --git a/TimerMessageBox.py b/TimerMessageBox.py new file mode 100644 index 0000000..206f665 --- /dev/null +++ b/TimerMessageBox.py @@ -0,0 +1,57 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +from PyQt4 import QtCore +from PyQt4 import QtGui + + +class TimerMessageBox(QtGui.QMessageBox): + def __init__(self, timeout=3, parent=None): + super(TimerMessageBox, self).__init__(parent) + self.setWindowTitle("NOT FOR MEDICAL USAGE") + self.time_to_wait = timeout + self.changeContent() + #self.setText("wait (closing automatically in {0} secondes.)".format(timeout)) + self.setStandardButtons(QtGui.QMessageBox.NoButton) + self.timer = QtCore.QTimer(self) + self.timer.setInterval(1000) + self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.changeContent) + self.timer.start() + + def changeContent(self): + self.setText("NOT FOR MEDICAL USAGE (closing automatically in {0} secondes.)".format(self.time_to_wait)) + + if self.time_to_wait <= 0: + self.close() + + self.time_to_wait -= 1 + + def closeEvent(self, event): + self.timer.stop() + event.accept() + + +class Example(QtGui.QWidget): + def __init__(self): + super(Example, self).__init__() + btn = QtGui.QPushButton('Button', self) + btn.resize(btn.sizeHint()) + btn.move(50, 50) + self.setWindowTitle('Example') + self.connect(btn, QtCore.SIGNAL("clicked()"), self.warning) + + def warning(self): + messagebox = TimerMessageBox(5, self) + messagebox.exec_() + + +def main(): + app = QtGui.QApplication(sys.argv) + ex = Example() + ex.show() + sys.exit(app.exec_()) + + +if __name__ == '__main__': + main() diff --git a/anonymizeTRC.py b/anonymizeTRC.py new file mode 100644 index 0000000..d07423c --- /dev/null +++ b/anonymizeTRC.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +""" Function to anonymize patient data in TRC files + (c) 2014 - INSERM U836 - Manik Bhattacharjee + License GNU GPL v3 +""" +import struct + +def anonymizeTRC(filepath, firstname="No", lastname="Name", nowrite=False, overwriteMontage=False): + """ Anonymize patient data in TRC files """ + + f=open(filepath, "r+b") # Open read-write binary mode + # should check for a TRC header ! + try: + f.seek(2) + headerTitle = f.read(8) + f.seek(175) + version = struct.unpack('B', f.read(1))[0] + if headerTitle != "MICROMED" or version != 4: + print "Not a MICROMED TRC System 98 v4 file -> ignoring" + f.close() + return False + except: + # Could not read header info -> wrong file type + f.close() + return False + f.seek(64) # go to patient data offset in header + # get a 22-char string, padding with spaces, convert to integers and pack as 22 unsigned chars in little endian + if nowrite: + f.close() + return True + f.write(struct.pack('<22B',*[ord(a) for a in lastname[:22].ljust(22,' ')])) + # Same with 20 chars + f.write(struct.pack('<20B',*[ord(a) for a in firstname[:20].ljust(20,' ')])) + # Same with date (3 unsigned chars, for example [10, 05, 72] for october 5th 1972 + f.write(struct.pack('<3B',1,1,1)) + + if overwriteMontage: + try: + # Read unsigned short int number of montages + f.seek(152) + nbMontages = struct.unpack('H',f.read(2))[0] + # Reading Montage header to get offset of montage data + f.seek(288) + if f.read(8) != 'MONTAGE ': + raise Exception("Incorrect MONTAGE header") + montageOffs = struct.unpack('I', f.read(4))[0] + + for i in range(nbMontages): + newMontageName = "Montage "+str(i) + f.seek(montageOffs + 4096*i+264) + # To print description string : desc = f.read(64); print desc[:desc.find('\x00')] + f.write(struct.pack('<64B',*[ord(a) for a in newMontageName.ljust(64,'\x00')])) + except: + print "Could not overwrite Montage name" + + f.close() + + return True + diff --git a/anonymizer.py b/anonymizer.py new file mode 100644 index 0000000..222d09e --- /dev/null +++ b/anonymizer.py @@ -0,0 +1,718 @@ +# -*- coding: utf-8 -*- +# +# This software and supporting documentation are distributed by +# Institut des Neurosciences de Grenoble - INSERM U836 +# France +# +# License : GNU General Public License version 3 +# +# Upload/anonymizing easy-to-use software for F-TRACT DB +# Anonymizer functions +# + +import os, tempfile, shutil, struct, datetime +import traceback +from struct import pack, unpack +import codecs + +############################### DICOM ############################################### + +import dicom +from anonymizeDicom import anonymize as anonymizePyDicomFile +from dicom.filereader import InvalidDicomError + +def anonymizeDicomFile(path, outputPath, newName="anonymous"): + oldsize = os.path.getsize(path) + try: + anonymizePyDicomFile(path, outputPath, new_person_name=newName, new_patient_id=newName) + except InvalidDicomError: # Not dicom file -> just copy the file + print "Not a dicom file, no anonymization done." + shutil.copy(path, outputPath) + if os.path.exists(outputPath): + newsize = os.path.getsize(outputPath) + if newsize != oldsize: + print('ERROR non-DICOM file copy failed ! '+repr(outputPath)) + raise Exception('ERROR non-DICOM file copy failed ! '+repr(outputPath)) + else: + print('ERROR non-DICOM file copy failed (not created) ! '+repr(outputPath)) + raise Exception('ERROR non-DICOM file copy failed (not created) ! '+repr(outputPath)) + + + except Exception, err: + print ("Other error while anonymizing DICOM file %s : %s"%(path, repr(err))) + traceback.print_exc() + newsize = os.path.getsize(outputPath) + if oldsize > 0 and newsize == 0: + print('ERROR : Dicom file size is 0 after anonymization' + repr(path)) + raise Exception('DICOM anonymization failed : file size is 0 : ' + repr(path)) + return outputPath + + +def anonymizeDicomDir(path,newName="anonymous", outputPath=None): + """Anonymizes a directory containing dicom files. + Non-Dicom files are copied along with the dicom files. + Warning ! This creates a directory that must be erased after use (if outputPath is empty, of course) ! + @return Path of the temporary directory that contains an anonymous copy of the directory + """ + if not os.path.isdir(path): + print "AnonymizeDicom : %s is not a valid directory"%path + return None + if outputPath is None: + tmp = tempfile.mkdtemp(prefix='ftract') + else: + tmp = outputPath + print ('AnonymizeDicomDir will use output directory '+repr(tmp)) + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + print('AnonymizeDicomDir newSubdir') + try: + os.mkdir(os.path.join(tmp, dOut)) + print('Making directory '+repr(os.path.join(tmp, dOut))) + except: + print('Failed to create directory '+repr(os.path.join(tmp, dOut))) + for fileIn in s: + print('Anonymizing file '+repr(os.path.join(r, fileIn)) + ' into '+ os.path.join(tmp, dOut, fileIn) + ' with name = '+newName) + anonymizeDicomFile(os.path.join(r, fileIn), os.path.join(tmp, dOut, fileIn), newName) + + return tmp + +def anonymizeDicomPaths(paths, newName="anonymous"): + out = {} + for p in paths: + if os.path.isdir(p): + print('Anonymizing dicom dir '+repr(p)) + out[p]=tempfile.mkdtemp(prefix='ftract') + anonymizeDicomDir(p, newName, out[p]) + print('Got '+repr(out[p]) + ' from anonymizeDicomDir') + elif os.path.isfile(p): + print('Anonymizing dicom file '+repr(p)) + out[p] = tempfile.mkstemp(prefix='ftract')[1] + anonymizeDicomFile(p, out[p], newName) + print('Got '+repr(out[p]) + ' from anonymizeDicomFile') + + return out + + +############################### SEEG ############################################### + +def anonymizeSeeg(path, newName = "anonymous", filetype = "Micromed"): + if filetype == "Micromed": + return anonymizeTrcPaths(path, newName) + elif filetype == "Nihon Kohden": + return anonymizeNihonKohdenPaths(path, newName) + elif filetype == "EDF": + return anonymizeEdfPaths(path, newName) + elif filetype == "Nicolet": + return anonymizeNicoletEPaths(path, newName) + elif filetype == "xltek" or filetype == "Deltamed": + print "ANONYMIZATION DOES NOT WORK FOR XLTEK/DELTAMED SEEG DATA !" + return dict([(p,p) for p in path]) + else: + print "UNKNOWN FORMAT (should be Micromed, xltek, Nicolet (EDF), or Nihon Kohden)" + return dict([(p, p) for p in path]) + +def anonPaths(paths, newName="anonymous", dirAnonymizer=None, fileAnonymizer = None): + """ A function to anonymize files and dirs in a list of paths using fileAnonymizer and dirAnonymizer functions""" + out = {} + if type(paths) == str: + paths = [paths,] + if dirAnonymizer is None: + dirAnonymizer = lambda p,n:anonDir(path=p, newName = n, fileAnonymizer = fileAnonymizer) + if fileAnonymizer is None: + print "No anonymizer !!!!" + return None + for p in paths: + if os.path.isdir(p): + out[p] = dirAnonymizer(p, newName) + elif os.path.isfile(p): + fileout = tempfile.mkstemp(prefix='ftract')[1] + shutil.copy (p, fileout) + fileAnonymizer(fileout, newName) + out[p] = fileout + + return out + +def anonDir(path, newName = "anonymous", fileAnonymizer = None): + """ A function to anonymize a full directory by running fileAnonymizer on each file on a copy of the directory""" + if not os.path.isdir(path): + print "AnonymizeDir : %s is not a valid directory"%path + return None + tmp = tempfile.mkdtemp(prefix='ftract') + # + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + os.mkdir(os.path.join(tmp, dOut)) + for fileIn in s: + fileout = os.path.join(tmp, dOut, fileIn) + shutil.copy(os.path.join(r, fileIn), fileout) + fileAnonymizer(fileout, newName) + return tmp + +##########################################" Nihon Kohden format + + +anonymizeNihonKohdenPaths = lambda paths, newName="anonymous":anonPaths(paths, newName, None, anonymizeNihonKohdenFile) + + +def anonymizeNihonKohdenFile(filepath, newName = "anonymous"): + nihonKohdenAnon = {'CND':anonNihonKohdenDeviceBlock, + 'CN2':anonNihonKohdenDeviceBlock, + 'PNT':anonNihonKohdenPnt, + 'LOG':anonNihonKohdenDeviceBlock, + 'EEG':anonNihonKohdenDeviceBlock, + 'EGF': anonNihonKohdenEGF, + 'CMT':anonNihonKohdenDeviceBlock,} + # Ignore other files without patient info (.21E, .11D, .REG...) + # Check this is a Nihon Kohden file + extension = os.path.splitext(filepath)[1][1:].upper() + if extension not in nihonKohdenAnon.keys(): + print "Not a Nihon Kohden file with patient name (extension unknown - not anonymized) : "+extension + return filepath + # Better expensive checks : read some headers and anonymize using the appropriate function + nihonKohdenAnon[extension](filepath, newName) + return filepath + + +def anonNihonKohdenDeviceBlock(filepath, newName): + print "Anon Nihon Device block for "+filepath + f = codecs.open(filepath, "r+b", encoding='cp1252') # Open read-write binary mode + # should check for a header ! + deviceType = f.read(16) + filePrev = f.read(16) + fileNext = f.read(16) + name = os.path.splitext(os.path.basename(filepath))[0] + prev = os.path.splitext("".join([a for a in filePrev if a!='\x00']))[0] + next = os.path.splitext("".join([a for a in fileNext if a!='\x00']))[0] + if (prev != '' and prev != name) or (next != '' and next != name) or not deviceType.startswith('EEG-'): + print "Invalid previous/next file name in header or device type is not EEG :\n %s\n %s\n %s"%(repr(filePrev), repr(fileNext), repr(deviceType)) + return + + idNumber = f.read(16) + dateTime = f.read(14) + charType = chr(struct.unpack('B',f.read(1))[0]) # Should be '0' (48) for ascii, '1' (49) for japanese + if charType not in ['0','1'] or len([a for a in dateTime if not a.isdigit()]) != 0: + print "Nihon Kohden -> invalid char type" + return + patientName = f.read(32) + reserved = f.read(12) # Should be all 0x00 + additionalVersion = f.read(5) + if len([r for r in reserved if r != '\x00']) != 0 or [a for a in idNumber if not a.isdigit() and a != '\x00']: + print "reserved should be all 0x00" + return + # Overwrite patient name + f.seek(79) + f.write(newName.ljust(32,'\x00')[:32]) + f.close() + +def anonNihonKohdenPnt(filepath, newName): + print "Anon PNT "+filepath + # First anonymize the device block + anonNihonKohdenDeviceBlock(filepath, newName) + # Go for specific patient block + f=codecs.open(filepath, "r+b", encoding='cp1252') + f.seek(146) + val = struct.unpack(' offset in not 1024 !" + f.seek(val) + if f.read(1) != '\x03': + #print "Invalid value at offset 1024" + return + device = f.read(16) # -> device model "EEG-1100A V01.00" + if f.read(1) != '\x7b': + return + # Information about the rest of the header : [[name length, value length, value type, unit],...[]] - 4 bytes, 123=0x7b times + datainfo = [struct.unpack('BBBB',f.read(4)) for j in xrange(123)] + # Read the data according to the datainfo + data = {} + for i in xrange(len(datainfo)): + k = f.read(datainfo[i][0]).replace('\x00','').lower() + data[k] = (f.tell(), f.read(datainfo[i][1]).replace('\x00',''), datainfo[i][1]) # length of the name of the data type + # Did we find a name ? Overwrite it + if 'name' in data: + f.seek(data['name'][0]) + f.write(newName.ljust(data['name'][2],'\x00')[:data['name'][2]]) + # Did we find a date of birth ? Overwrite it + if 'date of birth' in data: + f.seek(data['date of birth'][0] + 8) # 8 because we leave as is the first 8 chars "YYYY/MM/" and just set the day to 01 + f.write('01') + f.close() + + +def anonNihonKohdenEGF(filepath, newName): + print "Anon EGF "+filepath + #PATNAME=Dupont Jean + #BIRTHD=2003/01/01 + f = codecs.open(filepath,'rb', encoding='cp1252') + lines = f.read().split(u"\r\n") + f.close() + updateNeeded = False + for i in xrange(len(lines)): + if lines[i].startswith('PATNAME='): + lines[i] = 'PATNAME='+newName + updateNeeded = True + elif lines[i].startswith('BIRTHD='): + lines[i] = lines[i][:15]+'01'#Just sets the day to 01 : BIRTHD=2010/05/18 -> BIRTHD=2010/05/01 + updateNeeded = True + if updateNeeded: + import pdb; pdb.set_trace() + f = codecs.open(filepath, 'wb', encoding='cp1252') + f.write(u"\r\n".join(lines)) + f.close() + + +############### Nicolet One .e files ############ EDF files ############ +class NicoletFile: + LABELSIZE = 32 + TSLABELSIZE = 64 + UNITSIZE = 16 + ITEMNAMESIZE = 64 + tagnames = {'ExtraDataTags': 'ExtraDataTags', + 'SegmentStream': 'SegmentStream', + 'DataStream': 'DataStream', + 'InfoChangeStream': 'InfoChangeStream', + 'InfoGuids': 'InfoGuids', + '{A271CCCB-515D-4590-B6A1-DC170C8D6EE2}': 'TSGUID', + '{8A19AA48-BEA0-40D5-B89F-667FC578D635}': 'DERIVATIONGUID', + '{F824D60C-995E-4D94-9578-893C755ECB99}': 'FILTERGUID', + '{02950361-35BB-4A22-9F0B-C78AAA5DB094}': 'DISPLAYGUID', + '{8E94EF21-70F5-11D3-8F72-00105A9AFD56}': 'FILEINFOGUID', + '{E4138BC0-7733-11D3-8685-0050044DAAB1}': 'SRINFOGUID', + '{C728E565-E5A0-4419-93D2-F6CFC69F3B8F}': 'EVENTTYPEINFOGUID', + '{D01B34A0-9DBD-11D3-93D3-00500400C148}': 'AUDIOINFOGUID', + '{BF7C95EF-6C3B-4E70-9E11-779BFFF58EA7}': 'CHANNELGUID', + '{2DEB82A1-D15F-4770-A4A4-CF03815F52DE}': 'INPUTGUID', + '{5B036022-2EDC-465F-86EC-C0A4AB1A7A91}': 'INPUTSETTINGSGUID', + '{99A636F2-51F7-4B9D-9569-C7D45058431A}': 'PHOTICGUID', + '{55C5E044-5541-4594-9E35-5B3004EF7647}': 'ERRORGUID', + '{223A3CA0-B5AC-43FB-B0A8-74CF8752BDBE}': 'VIDEOGUID', + '{0623B545-38BE-4939-B9D0-55F5E241278D}': 'DETECTIONPARAMSGUID', + '{CE06297D-D9D6-4E4B-8EAC-305EA1243EAB}': 'PAGEGUID', + '{782B34E8-8E51-4BB9-9701-3227BB882A23}': 'ACCINFOGUID', + '{3A6E8546-D144-4B55-A2C7-40DF579ED11E}': 'RECCTRLGUID', + '{D046F2B0-5130-41B1-ABD7-38C12B32FAC3}': 'GUID TRENDINFOGUID', + '{CBEBA8E6-1CDA-4509-B6C2-6AC2EA7DB8F8}': 'HWINFOGUID', + '{E11C4CBA-0753-4655-A1E9-2B2309D1545B}': 'VIDEOSYNCGUID', + '{B9344241-7AC1-42B5-BE9B-B7AFA16CBFA5}': 'SLEEPSCOREINFOGUID', + '{15B41C32-0294-440E-ADFF-DD8B61C8B5AE}': 'FOURIERSETTINGSGUID', + '{024FA81F-6A83-43C8-8C82-241A5501F0A1}': 'SPECTRUMGUID', + '{8032E68A-EA3E-42E8-893E-6E93C59ED515}': 'SIGNALINFOGUID', + '{30950D98-C39C-4352-AF3E-CB17D5B93DED}': 'SENSORINFOGUID', + '{F5D39CD3-A340-4172-A1A3-78B2CDBCCB9F}': 'DERIVEDSIGNALINFOGUID', + '{969FBB89-EE8E-4501-AD40-FB5A448BC4F9}': 'ARTIFACTINFOGUID', + '{02948284-17EC-4538-A7FA-8E18BD65E167}': 'STUDYINFOGUID', + '{D0B3FD0B-49D9-4BF0-8929-296DE5A55910}': 'PATIENTINFOGUID', + '{7842FEF5-A686-459D-8196-769FC0AD99B3}': 'DOCUMENTINFOGUID', + '{BCDAEE87-2496-4DF4-B07C-8B4E31E3C495}': 'USERSINFOGUID', + '{B799F680-72A4-11D3-93D3-00500400C148}': 'EVENTGUID', + '{AF2B3281-7FCE-11D2-B2DE-00104B6FC652}': 'SHORTSAMPLESGUID', + '{89A091B3-972E-4DA2-9266-261B186302A9}': 'DELAYLINESAMPLESGUID', + '{291E2381-B3B4-44D1-BB77-8CF5C24420D7}': 'GENERALSAMPLESGUID', + '{5F11C628-FCCC-4FDD-B429-5EC94CB3AFEB}': 'FILTERSAMPLESGUID', + '{728087F8-73E1-44D1-8882-C770976478A2}': 'DATEXDATAGUID', + '{35F356D9-0F1C-4DFE-8286-D3DB3346FD75}': 'TESTINFOGUID'} + def __init__(self, filename, anonymizeName=None): + self.fileName = filename + self.patientInfo = None + self.segments = None + self.sections = None + self.index = None + self.sigInfo = None + self.tsInfo = None + self.chInfo = None + self.notchFreq = None + self.Qi = None + self.Qii = None + self.allIndexIDs = None + self.useTSinfoIdx = 1 + + if os.path.splitext(filename)[1][1:].lower() != "e": + print "ERROR : File extension must be .e. Filename is :"+str(filename) + return + self.filename = os.path.realpath(filename) + filename = self.filename + h = open(filename,'r+b') + #Get init + misc1 = unpack('<5I', h.read(20))#ok + unknown =unpack(' + indexIdx = unpack(' convert to seconds and remove duration until 1/1/1970 (unix base time) + #thetime = datetime.datetime.fromtimestamp(unix_time) # This can crash, and we don't care about dates anyway + #self.segments[i]['dateStr'] = thetime.strftime('%Y-%m-%d %H:%M:%S') + #datestr(unix_time/86400 + datenum(1970,1,1)); + #value = [thetime.day, thetime.month, thetime.year] # Day month year + value = unix_time + if id in [23,24]: + value = unpack('") + value = "".join(map (chr, unpack('<'+str( strSetup[i+1] + 1)+'H', h.read(2*(strSetup[i+1] + 1))))).rstrip(' \t\r\n\0') + info[infoProps[id]] = value; + print " "+str(value) + self.patientInfo = info; + # Close and reopen for write, because writing directly fails in windows XP with no error message... + h.close() + print("Reopening Nicolet file to write inside") + h = open(filename,'r+b') + for offset in toWrite: + h.seek(offset) + h.write(toWrite[offset]) + print("Writing at " + str(offset)) + h.close() + + +def anonymizeNicoletE(filepath, newName = "anonymous"): + """Anonymizes a .e file (from Nicolet) + WARNING overwrites the file ! """ + try: + nf = NicoletFile(filepath, anonymizeName = newName) + except Exception as e: + print "Could not anonymize "+ filepath+" : NicoletFile exception when reading file !"+str(e) + raise + + + +def anonymizeNicoletEPaths(paths, newName="anonymous"): + out = {} + for p in paths: + if os.path.isdir(p): + out[p] = anonymizeNicoletEDir(p, newName) + elif os.path.isfile(p): + fileout = tempfile.mkstemp(prefix='ftract')[1] + shutil.copy (p, fileout) + anonymizeNicoletE(fileout, newName) + out[p] = fileout + return out + +def anonymizeNicoletEDir(path, newName = "anonymous"): + """Anonymizes a directory containing TRC files. + Non-TRC files are copied along with the TRC files. + Warning ! This creates a directory that must be erased after use ! + @return Path of the temporary directory that contains an anonymous copy of the directory + """ + if not os.path.isdir(path): + print "AnonymizeNicoletE : %s is not a valid directory"%path + return None + tmp = tempfile.mkdtemp(prefix='ftract') + # + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + os.mkdir(os.path.join(tmp, dOut)) + for fileIn in s: + fileout = os.path.join(tmp, dOut, fileIn) + shutil.copy(os.path.join(r, fileIn), fileout) + anonymizeNicoletE(fileout, newName) + return tmp + + +############### EDF files ############ +def anonymizeEdf(filepath, newName = "anonymous"): + """Anonymizes a EDF file (from Nicolet One) + WARNING overwrites the file ! + """ + f = open(filepath, 'r+b') + f.seek(88) + if f.read(9) != 'Startdate': + print "No Startdate in file : probably not EDF -> no anonymization !" + return + # reserved header : if it starts with EDF+ this is an EDF+ file + f.seek(192) + isEdfPlus = False + if f.read(4) == 'EDF+': + isEdfPlus = True + # Go to the patient data and overwrite it using EDF+ format (space separated subfields, X for no value) + # patient code (no spaces, use _ instead), sex (F or M), dd-MMM-yyyy birthdate, patient name + f.seek(8) + patientInfo = f.read(80) + if isEdfPlus: + patientInfo = patientInfo.split(u' ') + patId = patientInfo[0] + patId = newName.replace(u' ', u'_')[:30] + patSex = patientInfo[1] + patBirthdate = patientInfo[2] + patName = patientInfo[3] + patName = newName.replace(u' ', u'_')[:30] + if len(patBirthdate) >10: # Should be 21-AUG-2015 + patBirthdate ='01'+patBirthdate[2:] + patientInfo = ' '.join([patId, patSex, patBirthdate, patName]) + else: # EDF + patientInfo = ' '.join([newName.replace(u' ', u'_')[:30], u'X', u'X', newName.replace(u' ', u'_')[:30]]) + f.seek(8) + f.write(patientInfo[:80].ljust(80,' ')) + f.close() + +def anonymizeEdfPaths(paths, newName=u"anonymous"): + out = {} + for p in paths: + if os.path.isdir(p): + out[p] = anonymizeEdfDir(p, newName) + elif os.path.isfile(p): + fileout = tempfile.mkstemp(prefix='ftract')[1] + shutil.copy (p, fileout) + anonymizeEdf(fileout, newName) + out[p] = fileout + return out + +def anonymizeEdfDir(path, newName = u"anonymous"): + """Anonymizes a directory containing TRC files. + Non-TRC files are copied along with the TRC files. + Warning ! This creates a directory that must be erased after use ! + @return Path of the temporary directory that contains an anonymous copy of the directory + """ + if not os.path.isdir(path): + print "AnonymizeEDF : %s is not a valid directory"%path + return None + tmp = tempfile.mkdtemp(prefix='ftract') + # + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + os.mkdir(os.path.join(tmp, dOut)) + for fileIn in s: + fileout = os.path.join(tmp, dOut, fileIn) + shutil.copy(os.path.join(r, fileIn), fileout) + anonymizeEdf(fileout, newName) + return tmp + +#################### MICROMED TRC FORMAT System 98 type 4 +def anonymizeTrcDir(path, newName = "anonymous"): + """Anonymizes a directory containing TRC files. + Non-TRC files are copied along with the TRC files. + Warning ! This creates a directory that must be erased after use ! + @return Path of the temporary directory that contains an anonymous copy of the directory + """ + if not os.path.isdir(path): + print "AnonymizeTRC : %s is not a valid directory"%path + return None + tmp = tempfile.mkdtemp(prefix='ftract') + # + for r,d,s in os.walk(path): + dOut = os.path.relpath(r, path) + if dOut != '.': + os.mkdir(os.path.join(tmp, dOut)) + for fileIn in s: + fileout = os.path.join(tmp, dOut, fileIn) + shutil.copy(os.path.join(r, fileIn), fileout) + anonymizeTRC_Sys98_t4(fileout, newName, newName) + return tmp + +def anonymizeTrcPaths(paths, newName="anonymous"): + out = {} + for p in paths: + if os.path.isdir(p): + out[p] = anonymizeTrcDir(p, newName) + elif os.path.isfile(p): + fileout = tempfile.mkstemp(prefix='ftract')[1] + shutil.copy (p, fileout) + anonymizeTRC_Sys98_t4(fileout, firstname=newName, lastname=newName) + out[p] = fileout + return out + +def anonymizeTRC_Sys98_t4(filepath, firstname="No", lastname="Name", nowrite=False, overwriteMontage=True, overwriteUndocumentedElectrode = True): # Anonymize Micromed's System 98 type 4 TRC files + """ Anonymize Micromed's System 98 type 4 TRC files """ + f=open(filepath, "r+b") # Open read-write binary mode + # should check for a TRC header ! + f.seek(2) + headerTitle = f.read(26) + f.seek(175) + headerType = f.read(1) + trcVersion = struct.unpack('B',headerType)[0] + if headerTitle != "MICROMED Brain-Quick file" or (trcVersion != 4 and trcVersion != 3): + print "Not a MICROMED System 98 Type 3/4 TRC file -> ignoring" + f.close() + return False + f.seek(64) # go to patient data offset in header + # get a 22-char string, padding with spaces, convert to integers and pack as 22 unsigned chars in little endian + if nowrite: + f.close() + return True + f.write(struct.pack('<22B',*[ord(a) for a in lastname[:22].ljust(22,' ')])) + # Same with 20 chars + f.write(struct.pack('<20B',*[ord(a) for a in firstname[:20].ljust(20,' ')])) + # Same with date (3 unsigned chars, for example [10, 05, 72] for october 5th 1972 + f.seek(107) + f.write(struct.pack(' 128* 4-bytes values (the sample where themontage was changed when viewing) + # We can skip that, then MAX_HISTORY = 128 "specific montage" structures which are identical to the montages above. + # Description string starts at offset 264 of each montage structure and is 64 bytes long,, just like above. + for i in range(30): + newMontageName = "Montage History "+str(i) + f.seek(historyOffs + 128*4 + sizeMontage*i+264) + desc = f.read(64) + # To print description string : desc = f.read(64); print desc[:desc.find('\x00')] + if "".join(["\x00" for j in range(64)]) != desc: + f.seek(historyOffs + 128*4 + sizeMontage*i+264) + f.write(struct.pack('<64B',*[ord(a) for a in newMontageName.ljust(64,'\x00')])) + + # undocumented string in place of the last electrode in name in HISTORY : find history offset, + f.seek(192) + if f.read(8) != 'LABCOD ': + raise Exception ("Incorrect LABCOD header") + elecOffs = struct.unpack('I', f.read(4))[0] + # There should be 640 electrode structures of 128 bytes. But the last one is not an electrode structure. It seems to be a 32 bits integer and a 64 bytes string that contains a montage name... + if overwriteUndocumentedElectrode: + f.seek(elecOffs + 639*128 + 4) + f.write(struct.pack('<64B',*[ord(a) for a in "undocumented montage".ljust(64,'\x00')])) + + except: + print "Could not overwrite Montage name" + + f.close() + return True diff --git a/autoImportScript.py b/autoImportScript.py new file mode 100644 index 0000000..f036f66 --- /dev/null +++ b/autoImportScript.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# +# (c) INSERM U836 - Manik Bhattacharjee +# Script to import old databases of patients into new BrainVisa hierarchy + +import os, json,sys +from PyQt4 import QtGui, QtCore + +#Init PyQt4 +app=QtGui.QApplication(sys.argv) + +# Dossier +#root = '/home/lnppeeg/data/LOCA_DATABASE' +root = '/media/My Passport/epiBaseDo/LyonNuit/LOCA_DATABASE' +rootEpi = '/media/My Passport/epiBaseDo/EpiG' + +# readPrefs +pr={} +try: + prfile = open(os.path.join(os.path.expanduser('~'), '.autoImportBrainVisa'),'r') + pr = json.load(prfile) + prfile.close() +except: + pass + +###################### LOCA_DATABASE -> un dossier avec les IRM et schémas d'implantation (MRI_2010), un dossier avec la SEEG (2010). +# Dans chaque dossier, un dossier par sujet +dirs = os.listdir(root) +subjects = [] +if 'oldsubjects' in pr: + subjects = pr['oldsubjects'] +else: + for d in dirs: + if os.path.isdir(os.path.join(root,d)): + subjects.extend([f for f in os.listdir(os.path.join(root, d)) if os.path.isdir(os.path.join(root,d,f))]) + + # Unique subjects, sorted + subjects = sorted(list(set(subjects))) + + pr['oldsubjects'] = subjects + + +# Build a correspondance oldnames -> newNames +newNames={} +if "newNames" in pr: + newNames = pr["newNames"] + +widgets={} + +def updateNewNames(): + for s in subjects: + newNames[s] = str(widgets[s].text()) + pr["newNames"] = newNames + +dialog = QtGui.QDialog() +lay = QtGui.QVBoxLayout(dialog) +#dialog.setLayout( +button=QtGui.QPushButton("Save", dialog) + +for s in subjects: + lay2 = QtGui.QHBoxLayout() + lay2.addWidget(QtGui.QLabel(s)) + widgets[s] = QtGui.QLineEdit() + if s in newNames: + widgets[s].setText(newNames[s]) + lay2.addWidget(widgets[s]) + lay.addLayout(lay2) + +lay.addWidget(button) + +dialog.show() +#fin de l'application lorsque toutes les fenêtres sont fermées +app.connect(app,QtCore.SIGNAL("lastWindowClosed()"),app,QtCore.SLOT("quit()")) +#fin de l'application lorsque l'utilisateur clique sur le bouton +app.connect(button, QtCore.SIGNAL("clicked()"),updateNewNames) +#boucle principale de traitement des évènements +app.exec_() + +output = None +output2 = None + +if 'oldnifti' in pr: # not in pr to use the cache ! + import subprocess + output = subprocess.Popen(['find',root, '-iname', '*.img', '-o', '-iname', '*.pts','-o', '-iname', '*.nii', '-o', '-iname', 'electrode.txt', '-o', '-iname', 'electrodes.txt','-o', '-iname', 'DICOM', '-o', '-iname', '*.jpg', '-o', '-iname', '*.jpeg', '-o', '-iname', '*.pdf', '-o', '-iname', '*.trc'], + stdout=subprocess.PIPE).communicate()[0].split('\n') + #output.extend(subprocess.Popen(['find',rootEpi, '-iname', '*.img', '-o', '-iname', '*.pts','-o', '-iname', '*.nii', '-o', '-iname', 'electrode.txt', '-o', '-iname', 'electrodes.txt','-o', '-iname', 'DICOM'], + # stdout=subprocess.PIPE).communicate()[0].split('\n')) + + ## Trier les .nii et .img + images = [ o for o in output if o[-4:].lower()=='.img'] + [ o for o in output if o[-4:].lower()=='.nii'] + pr['oldnifti'] = images + # Trier les dossiers DICOM et les étiqueter + pr['dicom'] = [ o for o in output if o[-5:].upper()=='DICOM'] + ## Trier les PTS et les electrode(s).txt + pr['oldpts'] = [ o for o in output if o[-4:].lower()=='.pts'] + + pr['oldelectrodestxt'] = [ o for o in output if o[-13:].lower()=='electrode.txt'] + [ o for o in output if o[-14:].lower()=='electrodes.txt'] + pr['impl'] = [ o for o in output if os.path.splitext(o)[1].lower()=='.jpg'] + [ o for o in output if os.path.splitext(o)[1].lower()=='.jpeg'] + pr['trc'] = [ o for o in output if os.path.splitext(o)[1].lower()=='.trc'] + +# What do we have for each subject ? +subjData=dict([(s,{'dicom':[], 'nifti':[], 'pts':[], 'electrodestxt':[]}) for s in subjects]) + +for s in subjects: + subjData[s]['nifti']=[{'path':i,'type':None, 'acq':None} for i in pr['oldnifti'] if i.split(root)[1].split('/')[2] == s and i.split(root)[1].split('/')[3].lower().find('seeg') == -1 and os.path.split(i)[1].find('y_inverse') == -1 ] + # if os.path.split(i)[1].startswith('r') -> image registered, 'w' pour les images normalizée, s pour smooth + subjData[s]['dicom']=[{'path':i,'type':None, 'acq':None} for i in pr['dicom'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['pts']=[{'path':i,'type':None, 'acq':None} for i in pr['oldpts'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['electrodestxt']=[{'path':i,'type':None, 'acq':None} for i in pr['oldelectrodestxt'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['impl']=[{'path':i,'type':None, 'acq':None} for i in pr['impl'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['trc']=[{'path':i,'type':None, 'acq':None} for i in pr['trc'] if i.split(root)[1].split('/')[2] == s] + subjData[s]['comment'] = "Has %d nifti, %d dicom dirs, %d pts, %d electrodes.txt and %d implantation scans"%(len(subjData[s]['nifti']), len(subjData[s]['dicom']), len(subjData[s]['pts']), len(subjData[s]['electrodestxt']), len(subjData[s]['impl'])) + # If not defined, try to extract name of subject from TRC + if len(newNames[s]) < 10 and len(subjData[s]['trc']) > 0: + output = subprocess.Popen(['getTRCpatientData', subjData[s]['trc'][0]['path']], stdout=subprocess.PIPE).communicate()[0].split('\n') + print "Auto name : %s --> oldname %s --> newName %s"%(s, newNames[s], str(output[2])+'+++') + newNames[s] = str(output[2])+'+++' + +# On veut -> trouver le nouveau nom, trouver une T1pre, une T1post, une T2pre/post si dispo, une CT..., tous les TRC et les localizers déjà faits et insérer tout ça dans la db. + + +##### Save preferences + +prfile = open(os.path.join(os.path.expanduser('~'), '.autoImportBrainVisa'),'w') +json.dump(pr, prfile) +prfile.close() +#################### EpiG ############################ \ No newline at end of file diff --git a/bipoleLabelsDisplay.ui b/bipoleLabelsDisplay.ui new file mode 100644 index 0000000..582974c --- /dev/null +++ b/bipoleLabelsDisplay.ui @@ -0,0 +1,146 @@ + + + Form + + + + 0 + 0 + 703 + 364 + + + + Form + + + + + 10 + 30 + 681 + 24 + + + + + 13 + 75 + false + true + true + false + + + + clinical observation labels from bipoles - NOT FOR MEDICAL USAGE + + + Qt::AlignCenter + + + + + + 10 + 60 + 681 + 291 + + + + + QLayout::SetFixedSize + + + + + + + + 11 + + + + 1 Hz + + + true + + + stim_selection_group + + + + + + + 50 Hz + + + stim_selection_group + + + + + + + Both + + + stim_selection_group + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + FontColor (Physiological or Seizure Type) + + + true + + + excelcolor_selection_group + + + + + + + BackColor (je sais pas comment appeler ça) + + + excelcolor_selection_group + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + diff --git a/bipoleSEEGColors.py b/bipoleSEEGColors.py new file mode 100644 index 0000000..83b108f --- /dev/null +++ b/bipoleSEEGColors.py @@ -0,0 +1,267 @@ +# -*-coding:utf-8 -* + +import sys, os, pickle, glob, numpy, re, string, time, subprocess, json, copy, csv + +from PyQt4 import QtGui, QtCore, uic, Qt + +from numpy import * +from math import sqrt +from collections import OrderedDict + +from soma import aims +from brainvisa import axon + +#from soma.aims.spmnormalizationreader import readSpmNormalization +from brainvisa import anatomist +from brainvisa.data import neuroHierarchy +import registration + +from externalprocesses import * +from referentialconverter import ReferentialConverter + + + +import pdb + + +#Main Class +class bipoleSEEGColors(QtGui.QDialog): + + def __init__(self,locateData = None,indv_pat=True,group_subsample=None): + + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("bipoleLabelsDisplay.ui", self) + self.setWindowTitle('Stimulation Observation - NOT FOR MEDICAL USAGE') + self.locaData =locateData #Data from locatesElectrode.py + self.a=self.locaData.a #Anatomist Object + + self.ui.lowHz_radiobutton.toggled.connect(self.updateBipoleDisplay) + self.ui.highHz_radiobutton.toggled.connect(self.updateBipoleDisplay) + self.ui.bothHz_radiobutton.toggled.connect(self.updateBipoleDisplay) + + self.ui.fontColor_radiobutton.toggled.connect(self.updateBipoleDisplay) + self.ui.backColor_radiobutton.toggled.connect(self.updateBipoleDisplay) + + by_default_list = [u'Motor',u'Sensitive',u'Sensory',u'Vegetative',u'Emotional',u'Experiencial','Superior functions'] + self.final_list_color = by_default_list #detect differencies ? but how because there is other column that should not be taken + model= QtGui.QStandardItemModel(len(self.final_list_color), 1) + for index,i_list in enumerate(self.final_list_color): + item = QtGui.QStandardItem(i_list) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(index+1, 0, item) + self.ui.list_backColor_Condition.setModel(model) + + self.ui.list_backColor_Condition.setEnabled(False) + self.ui.list_backColor_Condition.clicked.connect(self.updateBipoleDisplay) + + self.mode_indv = indv_pat + self.subsample_group = group_subsample + self.updateBipoleDisplay() + + + def updateBipoleDisplay(self): + + + infoHztoshow = [self.ui.lowHz_radiobutton.isChecked(),self.ui.highHz_radiobutton.isChecked(),self.ui.bothHz_radiobutton.isChecked()] + infoHzselected = [x for x in range(len(infoHztoshow)) if infoHztoshow[x] == True] + colortoshow = [self.ui.fontColor_radiobutton.isChecked(),self.ui.backColor_radiobutton.isChecked()] + colorselected = [x for x in range(len(colortoshow)) if colortoshow[x] == True] + + if self.mode_indv: + bipoleObjects= dict([(self.locaData.bipoles[x]['name'],self.locaData.bipoles[x]['elecModel'].getAnatomistObjects()[0]) for x in range(len(self.locaData.bipoles))]) + dataSEEG = self.locaData.bipoleLabels['contacts'] + else: + bipoleObjects = self.locaData.bipolesmeshes + dataSEEG = {} + datatomodify = {} + for index_subsample in self.subsample_group: + (subject,bipole) = index_subsample.split(' : ') + if subject not in datatomodify.keys(): + datatomodify.update({subject:[]}) + datatomodify[subject].append(bipole) + for subj in datatomodify.keys(): + #if subj not in dataSEEG.keys(): + #dataSEEG.update({subj:{}}) + for index_bipole in datatomodify[subj]: + matches_bipoles = [x for x in range(len(self.locaData.testDataSubjects[subj]['seeg_label_all'])) if self.locaData.testDataSubjects[subj]['seeg_label_all'][x][0] == index_bipole] + #new_name = subj + ' : ' + self.locaData.testDataSubjects[subj]['seeg_label_all'][index_cont][0] + if len(matches_bipoles)>0: + for index_matches_bipoles in matches_bipoles: + new_name = subj + ' : ' + self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][0] + if new_name not in dataSEEG.keys(): + dataSEEG.update({new_name:{'cell':{}}}) + dataSEEG[new_name]['cell'].update({self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]:{}}) + for x in self.final_list_color: + if x in self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][3]: + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({x:{'value':'something'}}) + else: + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({x:{'value':0}}) + + if self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][2] == u'no response': + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({u'Type of response':{'fontcolor':[255,0,0,0]}}) + elif self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][2] == u'seizure sensation': + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({u'Type of response':{'fontcolor':[255,255,0,0]}}) + elif self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][2] == u'pathological': + dataSEEG[new_name]['cell'][self.locaData.testDataSubjects[subj]['seeg_label_all'][index_matches_bipoles][1]].update({u'Type of response':{'fontcolor':[255,0,0,255]}}) + + + if colorselected[0] == 1: + self.ui.list_backColor_Condition.setEnabled(True) + default_backColor = {'Sensory': [255, 0, 176, 80], 'Sensitive': [255, 0, 112, 192], 'Superior functions': [255, 148, 82, 0], 'Motor': [255, 255, 0, 0], 'Emotional': [255, 112, 48, 160], 'Vegetative': [255, 255, 192, 0], 'Experiencial': [255, 255, 133, 255]} + backColor = {} + Model = self.ui.list_backColor_Condition.model() + for index in range(Model.rowCount()-1): + Item = Model.item(index+1) + if Item.checkState(): + if self.mode_indv: + backColor.update({str(Item.text()):self.locaData.bipoleLabels['title'][str(Item.text())]['title_backcolor'][:]}) + else: + backColor.update({str(Item.text()):default_backColor[str(Item.text())]}) + else: + backColor.update({str(Item.text()):[255,150,150,150]}) + + for index_contacts in range(len(dataSEEG.keys())): + + #if self.locaData.bipoleLabels['contacts'].keys()[index_contacts] == u'R02 - R01': + + if (u'1 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 0):#(self.locaData.bipoleLabels['contacts'][self.locaData.bipoleLabels['contacts'].keys()[index_contacts]]['cell'].keys()[0] == u'1 Hz' ) and (infoHzselected[0] == 0 or infoHzselected[0] == 2): + + #enComp = [self.locaData.bipoleLabels['contacts'][self.locaData.bipoleLabels['contacts'].keys()[index_contacts]]['cell']['1 Hz'][x]['value'] for x in self.final_list_color] + enComp = [True if dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['1 Hz'][x]['value'] != 0 else False for x in self.final_list_color] + try: + indexTrue = enComp.index(True) + indexesTrue = [i for i,j in enumerate(enComp) if j == True] + selected_color = [kk for kk,vv in backColor.items() if vv != [255,150,150,150]] + valueselectedcolor = [self.final_list_color.index(selected_color[i]) for i in range(len(selected_color))] + commonSelect = list(set(indexesTrue) & set(valueselectedcolor)) + if len(commonSelect)>1: + colorn = QtGui.QColor.fromRgb(255,255,255,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + else: + colorn = QtGui.QColor.fromRgb(backColor[self.final_list_color[commonSelect[0]]][1],backColor[self.final_list_color[commonSelect[0]]][2],backColor[self.final_list_color[commonSelect[0]]][3],backColor[self.final_list_color[commonSelect[0]]][0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + except: + #no response after stimulation + colorn = QtGui.QColor.fromRgb(0,0,0,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif (u'1 Hz' not in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 0): + colorn = QtGui.QColor.fromRgb(150,150,150,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif (u'50 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 1): + enComp = [True if dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['50 Hz'][x]['value'] != 0 else False for x in self.final_list_color] + try: + indexTrue = enComp.index(True) + indexesTrue = [i for i,j in enumerate(enComp) if j == True] + selected_color = [kk for kk,vv in backColor.items() if vv != [255,150,150,150]] + valueselectedcolor = [self.final_list_color.index(selected_color[i]) for i in range(len(selected_color))] + commonSelect = list(set(indexesTrue) & set(valueselectedcolor)) + if len(commonSelect)>1: + colorn = QtGui.QColor.fromRgb(255,255,255,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + else: + colorn = QtGui.QColor.fromRgb(backColor[self.final_list_color[commonSelect[0]]][1],backColor[self.final_list_color[commonSelect[0]]][2],backColor[self.final_list_color[commonSelect[0]]][3],backColor[self.final_list_color[commonSelect[0]]][0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + except: + #no response after stimulation + colorn = QtGui.QColor.fromRgb(0,0,0,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif (u'50 Hz' not in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 1): + colorn = QtGui.QColor.fromRgb(150,150,150,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif infoHzselected[0] == 2: + if u'1 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys(): + enComp1Hz = [True if dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['1 Hz'][x]['value'] != 0 else False for x in self.final_list_color] + else: + enComp1Hz = [False for i in range(len(self.final_list_color))] + + if u'50 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys(): + enComp50Hz = [True if dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['50 Hz'][x]['value'] != 0 else False for x in self.final_list_color] + else: + enComp50Hz = [False for i in range(len(self.final_list_color))] + + enCompBoth = numpy.logical_or(enComp1Hz,enComp50Hz).tolist() + try: + indexTrue = enCompBoth.index(True) + indexesTrue = [i for i,j in enumerate(enCompBoth) if j == True] + selected_color = [kk for kk,vv in backColor.items() if vv != [255,150,150,150]] + valueselectedcolor = [self.final_list_color.index(selected_color[i]) for i in range(len(selected_color))] + commonSelect = list(set(indexesTrue) & set(valueselectedcolor)) + if len(commonSelect)>1: + colorn = QtGui.QColor.fromRgb(255,255,255,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + else: + colorn = QtGui.QColor.fromRgb(backColor[self.final_list_color[commonSelect[0]]][1],backColor[self.final_list_color[commonSelect[0]]][2],backColor[self.final_list_color[commonSelect[0]]][3],backColor[self.final_list_color[commonSelect[0]]][0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + except: + #no response after stimulation + colorn = QtGui.QColor.fromRgb(0,0,0,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + #pdb.set_trace() #color = QtGui.QColor.fromRgb(250,0,0,100) r g b alpha + #self.a.setMaterial(newCyl, diffuse=[color.redF(), color.greenF(), color.blueF(), color.alphaF()]) newCyl + + else: + self.ui.list_backColor_Condition.setEnabled(False) + for index_contacts in range(len(dataSEEG.keys())): + #self.locaData.bipoleLabels['contacts'][self.locaData.bipoleLabels['contacts'].keys()[1]]['line']['fontcolor'] + if (u'1 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 0): + fontColorLine = dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['1 Hz'][u'Type of response']['fontcolor'] + if fontColorLine[1] == 0 and fontColorLine[2] == 0 and fontColorLine[3]==0: + fontColorLine = [255,0,0,0] + colorn = QtGui.QColor.fromRgb(fontColorLine[1],fontColorLine[2],fontColorLine[3],fontColorLine[0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + elif (u'1 Hz' not in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 0): + colorn = QtGui.QColor.fromRgb(150,150,150,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + elif (u'50 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 1): + fontColorLine = dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['50 Hz'][u'Type of response']['fontcolor'] + if fontColorLine[1] == 0 and fontColorLine[2] == 0 and fontColorLine[3]==0: + fontColorLine = [255,0,0,0] + colorn = QtGui.QColor.fromRgb(fontColorLine[1],fontColorLine[2],fontColorLine[3],fontColorLine[0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + elif (u'50 Hz' not in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()) and (infoHzselected[0] == 1): + colorn = QtGui.QColor.fromRgb(150,150,150,255) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + if infoHzselected[0]==2: + if (u'1 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()): + fontColorLine1 = dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['1 Hz'][u'Type of response']['fontcolor'] + if fontColorLine1[1] == 0 and fontColorLine1[2] == 0 and fontColorLine1[3]==0: + fontColorLine1 = [255,0,0,0] + else: + fontColorLine1 = [0,0,0,0] + + if (u'50 Hz' in dataSEEG[dataSEEG.keys()[index_contacts]]['cell'].keys()): + fontColorLine50 = dataSEEG[dataSEEG.keys()[index_contacts]]['cell']['50 Hz'][u'Type of response']['fontcolor'] + if fontColorLine50[1] == 0 and fontColorLine50[2] == 0 and fontColorLine50[3]==0: + fontColorLine50 = [255,0,0,0] + else: + fontColorLine50 = [0,0,0,0] + + fontColorBoth =numpy.minimum((numpy.array(fontColorLine50) + numpy.array(fontColorLine1)),255).tolist() + colorn = QtGui.QColor.fromRgb(fontColorBoth[1],fontColorBoth[2],fontColorBoth[3],fontColorBoth[0]) + bipoleObjects[dataSEEG.keys()[index_contacts]].setMaterial(diffuse=[colorn.redF(), colorn.greenF(), colorn.blueF(), colorn.alphaF()]) + + + def closeEvent(self, event): + self.quit(event) + + def quit(self, event=None): + reply = QtGui.QMessageBox.question(self, 'Quit',"Quit bipole colors editor ?", QtGui.QMessageBox.Yes |QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if reply == QtGui.QMessageBox.Yes: + if event is None: + self.a.quit() + else: + event.accept() + else: + event.ignore() + + +if __name__=="__main__": + a=QtGui.QApplication(sys.argv) \ No newline at end of file diff --git a/checkSpmVersion.py b/checkSpmVersion.py new file mode 100644 index 0000000..2eb200c --- /dev/null +++ b/checkSpmVersion.py @@ -0,0 +1,7 @@ +def checkSpmVersion(spm_path): + import os + op_cont = open(spm_path+os.sep+'Contents.m') + line = op_cont.readline() + line = op_cont.readline() + spm_version = line.split(' ')[3] + return spm_version diff --git a/control_ftract.py b/control_ftract.py new file mode 100644 index 0000000..5ed3414 --- /dev/null +++ b/control_ftract.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# This software and supporting documentation are distributed by +# Institut Federatif de Recherche 49 +# CEA/NeuroSpin, Batiment 145, +# 91191 Gif-sur-Yvette cedex +# France +# +# This software is governed by the CeCILL license version 2 under +# French law and abiding by the rules of distribution of free software. +# You can use, modify and/or redistribute the software under the +# terms of the CeCILL license version 2 as circulated by CEA, CNRS +# and INRIA at the following URL "http://www.cecill.info". +# +# As a counterpart to the access to the source code and rights to copy, +# modify and redistribute granted by the license, users are provided only +# with a limited warranty and the software's author, the holder of the +# economic rights, and the successive licensors have only limited +# liability. +# +# In this respect, the user's attention is drawn to the risks associated +# with loading, using, modifying and/or developing or reproducing the +# software by the user in light of its specific status of free software, +# that may mean that it is complicated to manipulate, and that also +# therefore means that it is reserved for developers and experienced +# professionals having in-depth computer knowledge. Users are therefore +# encouraged to load and test the software's suitability as regards their +# requirements in conditions enabling the security of their systems and/or +# data to be ensured and, more generally, to use and operate it in the +# same conditions as regards security. +# +# The fact that you are presently reading this means that you have had +# knowledge of the CeCILL license version 2 and that you accept its terms. +# -*- coding: utf-8 -*- +import anatomist.direct.api as anatomist +from soma import aims +from soma.aims import colormaphints +import sys, os, math +import pdb +from PyQt4 import QtCore, QtGui + +sys.path.insert( 0, '.' ) + + +# determine wheter we are using Qt4 or Qt3, and hack a little bit accordingly +# the boolean qt4 gloabl variable will tell it for later usage +#qt4 = False +#if sys.modules.has_key( 'PyQt4'): + #qt4 = True + # + #qt = QtGui + #from PyQt4.uic import loadUi +#else: + #import qt, qtui + #loadUi = qtui.QWidgetFactory.create + +## do we have to run QApplication ? +#if qt.qApp.startingUp(): + #qapp = qt.QApplication( sys.argv ) + #runqt = True +#else: + #runqt = False + + +class fTract_Action( anatomist.cpp.Action ): + def name( self ): + return 'fTract_Action' + + def resetRadius( self ): + print 'reset radius to 1' + s.setRadius( 1. ) + + def startMoveRadius( self, x, y, globx, globy ): + print 'start move radius', x, y + self._initial = ( x, y ) + self._radius = s.radius() + + def endMoveRadius( self, x, y, globx, globy ): + print 'end move radius', x, y + + def moveRadius( self, x, y, globx, globy ): + print 'move radius', x, y + s.setRadius( math.exp( 0.01 * ( self._initial[1] - y ) ) * self._radius ) + + def takePolygon( self, x, y, globx, globy ): + #print 'takePolygon', x, y + + print 'coucou', x,y + + #w = self.view().aWindow() + #obj = w.objectAtCursorPosition( x, y ) + ##print 'object:', obj + #if obj is not None: + #print 'object:', obj, obj.name() + #poly = w.polygonAtCursorPosition( x, y, obj ) + ##print 'polygon:', poly + #mesh = anatomist.cpp.AObjectConverter.aims( obj ) + ##print 'mesh:', mesh + #ppoly = mesh.polygon()[poly] + #vert = mesh.vertex() + ##print ppoly[0], ppoly[1], ppoly[2] + ##print vert[ppoly[0]], vert[ppoly[1]], vert[ppoly[2]] + #global selmesh, selanamesh + #if selmesh is None: + #selmesh = aims.AimsSurfaceTriangle() + #selmesh.vertex().assign( [ vert[ppoly[0]], vert[ppoly[1]], vert[ppoly[2]] ] ) + #selmesh.polygon().assign( [ aims.AimsVector_U32_3( 0, 1, 2 ) ] ) + #if selanamesh is None: + #selanamesh = anatomist.cpp.AObjectConverter.anatomist( selmesh ) + #a = anatomist.Anatomist() + #a.execute( 'SetMaterial', objects=[selanamesh], diffuse=[0,0,1.,1.] ) + #a.execute( 'AddObject', objects=[selanamesh], windows=[w] ) + #selanamesh.setChanged() + #selanamesh.notifyObservers() + +class ftract_control( anatomist.cpp.Control ): + def __init__( self, prio = 25 ): + anatomist.cpp.Control.__init__( self, prio, 'ftract_control' ) + + def eventAutoSubscription( self, pool ): + + key = QtCore.Qt + NoModifier = key.NoModifier + ShiftModifier = key.ShiftModifier + ControlModifier = key.ControlModifier + AltModifier = key.AltModifier + + pdb.set_trace() + self.keyPressEventSubscribe( key.Key_C, NoModifier, + pool.action( 'fTract_Action' ).resetRadius ) + self.mouseLongEventSubscribe( key.LeftButton, NoModifier, + pool.action( 'fTract_Action' ).startMoveRadius, + pool.action( 'fTract_Action' ).moveRadius, + pool.action( 'fTract_Action' ).endMoveRadius, + False ) + self.mousePressButtonEventSubscribe(key.RightButton, NoModifier, + pool.action( 'fTract_Action' ).takePolygon ) + +#a = anatomist.Anatomist() +#pix = qt.QPixmap('/home/b67-belledone/Desktop/epilepsie-manik/Logo-F-TRACT.xpm' ) +#anatomist.cpp.IconDictionary.instance().addIcon( 'ftract_control', pix ) +#ad = anatomist.cpp.ActionDictionary.instance() +#ad.addAction( 'fTract_Action', lambda: fTract_Action() ) +#cd = anatomist.cpp.ControlDictionary.instance() +#cd.addControl( 'ftract_control', lambda: ftract_control(), 25 ) +#cm = anatomist.cpp.ControlManager.instance() +#cm.addControl( 'QAGLWidget3D', '', 'ftract_control' ) + +#s = aims.SurfaceGenerator.sphere(aims.Point3df(10, 10, 10), 4, 32) +##a.registerObject( s ) +#aw = a.createWindow( '3D' ) +#a.addObjects( [ s ], [ aw ] ) + +## run Qt +#if runqt: + #if qt4: + #qapp.exec_() + #else: + #qapp.exec_loop() \ No newline at end of file diff --git a/control_ftract2.py b/control_ftract2.py new file mode 100644 index 0000000..2a3d23f --- /dev/null +++ b/control_ftract2.py @@ -0,0 +1,40 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +from anatomist import cpp as ana +from PyQt4 import QtGui, QtCore, uic +import pdb + +class ControlFtract(ana.Control): + + def __init__(self, prio = 25): + ana.Control.__init__(self,prio,'ControlFtract') + + def eventAutoSubscription(self,pool): #declare actions dispo et comment + + key = QtCore.Qt + NoModifier = key.NoModifier + ShiftModifier = key.ShiftModifier + ControlModifier = key.ControlModifier + AltModifier = key.AltModifier + + self.mousePressButtonEventSubscribe(key.LeftButton,NoModifier,pool.action('fTract_Action').show) + + +class StimulateResults(ana.Action): + + def show(self,x,y,globx,globy): + + print "Toto" + ww = self.view().aWindow() + obj = ww.objectAtCursorPosition( x, y ) + poly = ww.polygonAtCursorPosition( x, y, obj ) + pdb.set_trace() + if isinstance(obj,ana.MObject): #obj.size() == 2: + vertexselected = obj[0].surface().polygon()[poly] + #obj[1].texture1d()[0][2289] + #obj[1].texture1d()[2289] + #obj[1].texture1d()[0] + #http://brainvisa.info/pyanatomist-4.5/sphinx/pyanatomist_examples.html + + otherwindow = [x for x in ana.Anatomist().getWindows() if x is not ww and x.parent() == ww.parent()] \ No newline at end of file diff --git a/cutmeshwidget.ui b/cutmeshwidget.ui new file mode 100644 index 0000000..8537635 --- /dev/null +++ b/cutmeshwidget.ui @@ -0,0 +1,234 @@ + + + Form + + + + 0 + 0 + 306 + 300 + + + + Form + + + + + + center + + + + + + + Qt::Horizontal + + + + 83 + 20 + + + + + + + + orthogonal + + + true + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + -180 + + + 180 + + + 180 + + + Qt::Vertical + + + + + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + + + + true + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + false + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + false + + + -180 + + + 180 + + + 180 + + + Qt::Vertical + + + + + + + false + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + false + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + false + + + -180 + + + 180 + + + Qt::Vertical + + + + + + + false + + + -180 + + + 180 + + + 180 + + + Qt::Vertical + + + + + + + + + + + diff --git a/dicomutilities.py b/dicomutilities.py new file mode 100644 index 0000000..3757679 --- /dev/null +++ b/dicomutilities.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- + +# Group of functions to read, organize, and convert DICOM files +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# + +import re, shutil +from PyQt4 import QtCore +from externalprocesses import * + + +# Matlab code : convert DICOM files to a NIFTI file with SPM +spm_convert_dicom = "spm_get_defaults; cd('%s'); hdr = spm_dicom_headers(%s);name = '%s';a=spm_dicom_convert(hdr, 'all', 'flat', 'nii');if length(a.files)<1 || isempty(a.files{1}); quit; end;for i=1:length(a.files) if i==1 movefile(a.files{i}, [name '.nii']);else movefile(a.files{i}, [name '_' num2str(i) '.nii']);end;end;quit; " + + +# Construction de la liste des codes: +# - dcmdump d'un fichier DICOM +# - suppression des lignes sans intéret +# -recherche et remplace avec kwrite mode regexp +# (\([\da-f]+,[\da-f]+\)).*#[^a-zA-Z]+(\w+) remplacé par '\1':'\2',\\ + +# The DICOM codes that will be extracted from each image. +keepCodes = {\ +# '(0008,0012)':'InstanceCreationDate',\ +# '(0008,0013)':'InstanceCreationTime',\ +# '(0008,0014)':'InstanceCreatorUID',\ +# '(0008,0016)':'SOPClassUID',\ +# '(0008,0018)':'SOPInstanceUID',\ + '(0008,0020)':'StudyDate',\ + '(0008,0021)':'SeriesDate',\ + '(0008,0022)':'AcquisitionDate',\ +# '(0008,0023)':'ContentDate',\ + '(0008,0030)':'StudyTime',\ + '(0008,0031)':'SeriesTime',\ + '(0008,0032)':'AcquisitionTime',\ +# '(0008,0033)':'ContentTime',\ + '(0008,0050)':'AccessionNumber',\ +# '(0008,0060)':'Modality',\ +# '(0008,0070)':'Manufacturer',\ +# '(0008,0080)':'InstitutionName',\ +# '(0008,1010)':'StationName',\ + '(0008,1030)':'StudyDescription',\ + '(0008,103e)':'SeriesDescription',\ +# '(0008,1040)':'InstitutionalDepartmentName',\ + '(0010,0010)':'PatientsName',\ +# '(0010,0020)':'PatientID',\ + '(0010,0030)':'PatientsBirthDate',\ + '(0010,0040)':'PatientsSex',\ +# '(0018,0015)':'BodyPartExamined',\ +# '(0018,0020)':'ScanningSequence',\ + '(0018,0023)':'MRAcquisitionType',\ + '(0018,0050)':'SliceThickness',\ +# '(0018,0080)':'RepetitionTime',\ +# '(0018,0081)':'EchoTime',\ +# '(0018,0083)':'NumberOfAverages',\ +# '(0018,0087)':'MagneticFieldStrength',\ + '(0018,0088)':'SpacingBetweenSlices',\ + '(0018,1030)':'ProtocolName',\ +# '(0018,1250)':'ReceiveCoilName',\ +# '(0018,1310)':'AcquisitionMatrix',\ + '(0018,9073)':'AcquisitionDuration',\ + '(0020,000d)':'StudyInstanceUID',\ + '(0020,000e)':'SeriesInstanceUID',\ + '(0020,0010)':'StudyID',\ +# '(0020,0011)':'SeriesNumber',\ +# '(0020,0012)':'AcquisitionNumber',\ +# '(0020,0013)':'InstanceNumber',\ +# '(0020,0032)':'ImagePositionPatient',\ +# '(0020,0037)':'ImageOrientationPatient',\ +# '(0020,0052)':'FrameOfReferenceUID',\ +# '(0028,0010)':'Rows',\ +# '(0028,0011)':'Columns',\ +# '(0028,0030)':'PixelSpacing',\ +# '(0028,0100)':'BitsAllocated',\ +# '(0028,0101)':'BitsStored',\ +# '(0032,1033)':'RequestingService',\ +# '(0032,1060)':'RequestedProcedureDescription',\ +# '(0040,0241)':'PerformedStationAETitle',\ +# '(0040,0244)':'PerformedProcedureStepStartDate',\ +# '(0040,0245)':'PerformedProcedureStepStartTime',\ +# '(0040,0250)':'PerformedProcedureStepEndDate',\ +# '(0040,0251)':'PerformedProcedureStepEndTime',\ +# '(0040,0253)':'PerformedProcedureStepID',\ +# '(0040,0254)':'PerformedProcedureStepDescription',\ + '(2001,100a)':'SliceNumberMR',\ + '(2001,100b)':'SliceOrientation'} + +# Regular expression to recognize a dicom tag from a text line +dcmCodeRE = re.compile(r'^\([\da-f]+,[\da-f]+\)') +# Regular expression to get the content of a DICOM tag +dcmValueRE = re.compile(r'\([\da-f]+,[\da-f]+\)\s+\w+\s+\[?([^\]#]*)\]?') + + +def getDcmValue(line): + """Gets the value of a DICOM tag from a text line + If there is no such value, this will throw an exception + """ + m = dcmValueRE.search(line) + if m is None: + print 'No value in DCM line **'+line + return m.group(1) + + +def organizeDicomFiles(files, thread = False): + """ Creates a dictionary of all files provided with DICOM tag data extracted by dcmdump (of DCMTK) + :param thread : If true, a Qt signal 'dicomFilesOutput(PyQt_PyObject)' will be emitted on completion with the result dictionary + Type of result : dcm={'DCM0001':{'StudyDate':'20140101','SeriesDate':'20140101',...}, 'DCM0002':{'StudyDate':'20140101','SeriesDate':'20140101',...},... } + """ + dcm = {} + goodkeys = [] + for k in keepCodes.keys(): + goodkeys.extend(['+P',k[1:-1]]) + + for f in files: + print 'Processing '+f + dcm[f] = {} + # Get dcmdump info for the current file f + lines = runCmd(['dcmdump','-M']+goodkeys+[f, ]) + + # Python 2.7 -> subprocess.check_output(['dcmdump', f]) + for line in lines: + k = line[:11] # Get the key from the line + if k in keepCodes: + dcm[f][keepCodes[k]] = getDcmValue(line) + if thread: + print "emitting signal" + QtCore.QThread.currentThread ().emit(QtCore.SIGNAL('dicomFilesOutput(PyQt_PyObject)'), dcm) + return dcm + +def patientNameDecode(p): + """ Converts DICOM-style patient name LastName^FirstName^SecondName to LastName_FirstName_SecondName""" + return p.replace('^', '_').rstrip('_').replace(' ','-') + +def datetimeDecode(d,t): + """ Decodes DICOM datetime format 20140101, 120531 to human-readable 'Date: 2014-01-01, heure: 12:05:31'""" + if len(d) < 8 or len(t)<6: + print "DICOM Datetime is invalid !" + return '' + return str('Date: '+d[:4] +'-'+d[4:6]+'-'+ d[6:] +', heure: '+ t[:2] + ':'+t[2:4]+':'+t[4:]) + +def dateDecode(d): + """ Decodes DICOM date format 20140101, to human-readable '2014-01-01' """ + if len(d)<8: + print "DICOM Datetime is invalid !" + return '' + return d[:4] +'-'+d[4:6]+'-'+ d[6:] + +def getSeries(dcmFiles): + """ From organizeDicomFiles(f) output, returns a dictionnary of series with the most important DICOM tag values and list of files""" + series={} + + for d,dcm in dcmFiles.iteritems(): + dc = lambda x:dcm[x] if x in dcm else '' + if dcm['SeriesInstanceUID'] in series: + series[dcm['SeriesInstanceUID']]['files'].append(d) + else: + + series[dcm['SeriesInstanceUID']] = {'files':[d,],\ + 'SeriesDescription':dc('SeriesDescription'),\ + 'SeriesDate':dc('SeriesDate'),\ + 'SeriesTime':dc('SeriesTime'),\ + 'StudyDescription':dc('StudyDescription'),\ + 'PatientsName':str(dc('PatientsName')),\ + 'PatientsBirthDate':dc('PatientsBirthDate'),\ + #'SliceThickness':dcm['SliceThickness'],\ + #'PixelSpacing':dcm['PixelSpacing'],\ + 'StudyInstanceUID':str(dc('StudyInstanceUID')) + } + return series + +def serie2filename(s): + """ Generate the filename for the provided serie dictionary""" + seriesName = s['SeriesDate']+'_'+s['SeriesTime']+'_'+s['SeriesDescription'] + return seriesName.replace(' ', '_') + +def getStudies(dcmFiles): + """ Returns a dictionnary of studies available in organizeDicomFiles(f) output""" + studies={} + for dcm in dcmFiles.itervalues(): + if dcm['StudyInstanceUID'] not in studies: + studies[dcm['StudyInstanceUID']]={'name':datetimeDecode(dcm['StudyDate'],dcm['StudyTime']), 'PatientsName':dcm['PatientsName']} + return studies + +def getPatients(series): + """ Returns a list of patients available in organizeDicomFiles(f) output""" + patients = [] + for s in series.itervalues(): + if str(s['PatientsName']) not in patients: + patients.append(str(s['PatientsName'])) + return patients + +def copySeriesTo(series, path, move = False, nifti = False): + """ Copy the series listed as a dictionary to a directory (path) and organize them in a patientName/Serie/ hierarchy + :param series : the series to copy/move + :param path the base directory that will contain the patientName/Serie/ hierarchy + :param move If true, files will be move. If false (default), they will be copied. + :param nifti : if nifti is true, the nifti files listed in the series parameter will be copied/moved. If not, the dicom files will be copied/moved. + """ + for s in series.itervalues(): + try: + patientPath = os.path.join(path, patientNameDecode(s['PatientsName'])) + os.mkdir(patientPath) + except OSError, e: + pass + #if e.errno != os.errno.EEXIST: # DEPEND DE LA VERSION PYTHON + # raise + + seriesName = serie2filename(s) + + try: + seriesPath = os.path.join(patientPath, seriesName) + os.mkdir(seriesPath) + except OSError, e: + #if e.errno != os.errno.EEXIST: + print 'ERREUR : impossible de creer le dossier '+seriesPath+': '+e.strerror + # On oublie cette série ou on écrase ? + #continue + try: + if nifti is False: + files = s['files'] + else: + if 'nifti' not in s: + print "Cannot move unavailable Nifti files : use convertSeriesToNifti first !" + continue + files = s['nifti'] + + if move == False: + for f in files: + shutil.copyfile(f, seriesPath) + else: + for f in files: + shutil.move(f, seriesPath) + + except OSError, e: + print 'ERREUR : impossible de copier/déplacer '+f+' vers '+seriesPath+': '+e.strerror + except IOError, e: + print 'Erreur IO : impossible de copier/déplacer '+f+' vers '+seriesPath+': '+e.strerror + + + +def convertSeriesToNifti(series, path): + """Convert the series of dicom files to nifti files. Files are named by the serie name and in patientName directories. + The conversion is done with matlab/SPM and the returned QThread objects must be kept until completion of the conversion.""" + threads = [] + for i, s in series.iteritems(): + try: + patientPath = os.path.join(path, patientNameDecode(s['PatientsName'])) + os.mkdir(patientPath) + except OSError, e: + pass + #if e.errno != os.errno.EEXIST: # DEPEND DE LA VERSION DE PYTHON + # raise + + seriesName = s['SeriesDate']+'_'+s['SeriesTime']+'_'+s['SeriesDescription'] + seriesName = seriesName.replace(' ', '_') + niftiPath = os.path.join(patientPath, seriesName) # without the '.nii', it will be added in matlab + series[i]['niftiPath'] = niftiPath + '.nii' + print "Creating nifti at "+niftiPath + # spm needs a list of filenames where ALL FILENAMES ARE THE SAME LENGTH (stupid matlab string behaviour grrr) + # So let's make a stupid array with same-length filenames (add spaces at the end) + matfiles = s['files'] + maxcars = max([len(s) for s in matfiles]) + matfiles = [s.ljust(maxcars) for s in matfiles] + mtlb = matlabRunNB(spm_convert_dicom%(patientPath, repr(matfiles).replace(',', ';'), niftiPath)) + mtlb.start() + threads.append(mtlb) + + return threads diff --git a/editor.py b/editor.py new file mode 100644 index 0000000..4dab048 --- /dev/null +++ b/editor.py @@ -0,0 +1,373 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# + + +import sys, os, pickle +from PyQt4 import QtGui, QtCore, uic + +import anatomist.direct.api as anatomist +from soma import aims + +import pdb + + +# Small dialog to create a 3D electrode template for use in BrainVisa/Anatomist +# +# Each electrode is a group of cylinders. +# This software should provide an easy way to create new models of electrodes with realtime visualization +# +# It can also be used from another program that needs electrode models : it can load electrod models and +# create the necessary objects in Anatomist to display them along other objects. +# In that use case, you should : +# dialog = ElectrodeEditorDialog(theCurrentAnatomist) +# dialog.open() +# dialog.setDisplayReferential(electrodeReferential) +# cylinders = dialog.getDisplayed() +# meshes = dialog.getAnatomistObjects() +# +class ElectrodeEditorDialog(QtGui.QWidget): + + def __init__(self, anato = None, app=None): + + # UI init + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("electrodeEditor.ui", self) + self.setWindowTitle('Electrode editor') + + # Init of variables + self.app = app + self.cylinders = {} + self.displayed = {} + #self.elementIndex = 1 + self.currentColorHue = 0 + self.typeColors = {} + + # Linking UI elements to functions + self.connect(self.exitButton, QtCore.SIGNAL('clicked()'), self.quit) + self.connect(self.openButton, QtCore.SIGNAL('clicked()'), self.open) + self.connect(self.saveButton, QtCore.SIGNAL('clicked()'), self.save) + self.connect(self.addButton, QtCore.SIGNAL('clicked()'), self.addCylinder) + self.connect(self.updateButton, QtCore.SIGNAL('clicked()'), self.updateCylinder) + self.connect(self.deleteButton, QtCore.SIGNAL('clicked()'), self.deleteCylinder) + self.connect(self.axisCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.axisChanged) + #self.connect(self.typeCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.updateName) + + self.cylinderList.sortItems(QtCore.Qt.AscendingOrder) + self.connect(self.cylinderList, QtCore.SIGNAL("currentItemChanged(QListWidgetItem*,QListWidgetItem*)"), self.cylinderListClick) #itemClicked + + # Anatomist windows + if anato is None: + self.a = anatomist.Anatomist('-b' ) + else: + self.a = anato + layout = QtGui.QHBoxLayout( self.anatomistBox ) + self.axWindow = self.a.createWindow( 'Axial', no_decoration=True ) + self.sagWindow = self.a.createWindow( 'Sagittal', no_decoration=True ) + self.corWindow = self.a.createWindow( 'Coronal', no_decoration=True ) + self.wins = [self.axWindow, self.sagWindow, self.corWindow] + [w.setHasCursor(0) for w in self.wins] + self.sagWindow.setParent( self.anatomistBox ) + self.axWindow.setParent( self.anatomistBox ) + self.corWindow.setParent( self.anatomistBox ) + layout.addWidget( self.sagWindow.getInternalRep() ) + layout.addWidget( self.axWindow.getInternalRep() ) + layout.addWidget( self.corWindow.getInternalRep() ) + + + # Enable or disable axis values widgets if the axisCombo changes + def axisChanged(self, value): + value = str(value) + if value == "Custom...": + self.xValue.setEnabled(True) + self.yValue.setEnabled(True) + self.zValue.setEnabled(True) + else: + self.xValue.setEnabled(False) + self.yValue.setEnabled(False) + self.zValue.setEnabled(False) + + + # Load an Electrode Definition file + def open(self, model=None): + if model is not None: + if not os.path.isfile(model): + path = '/home/manik/prog/electrophysiology/epilepsie/'+str(model) + else: + path = model + else: + path = QtGui.QFileDialog.getOpenFileName(self, "Open Electrode Definition File", "", "Electrode Definition files (*.elecdef)") + if not os.path.exists(path): + print 'No electrode model at '+str(path) + return + + filein = open(path, 'rb') + self.cylinders = pickle.load(filein) + filein.close() + # Reset colors + self.currentColorHue = 0 + self.typeColors = {} + # If shape is not defined, it's a cylinder + for name in self.cylinders: + if 'shape' not in self.cylinders[name]: + self.cylinders[name]['shape']='cylinder' + # If center of elements was not saved, compute it + if 'center' not in self.cylinders[name]: + pos = self.cylinders[name]['position'] + v = self.cylinders[name]['length'] + vec = self.cylinders[name]['vector'] + self.cylinders[name]['center'] = [pos[0] + v*vec[0]/2.0, self.posYValue.value()+v*vec[1]/2.0, self.posZValue.value()+v*vec[2]/2.0] + # Display the cylinders + self.updateCylinderList() + self.updateDisplay() + + # Save an Electrode Definition file + def save(self): + path = QtGui.QFileDialog.getSaveFileName(self, "Save Electrode Definition File", "", "Electrode Definition files (*.elecdef)") + if path is None or str(path) == "": + return + fileout = open(path, 'wb') + pickle.dump(self.cylinders, fileout) + fileout.close() + + # Get the real orientation vector from the UI + def getAxisVector(self): + # Valeur réelle de l'axe + ax = str(self.axisCombo.currentText()) + if ax == "Custom...": + vec = [self.xValue.value(),self.yValue.value(), self.zValue.value()] + elif ax == "Axe X": + vec = [1.0,0.0,0.0] + elif ax == "Axe Y": + vec = [0.0,1.0,0.0] + elif ax == "Axe Z": + vec = [0.0,0.0,1.0] + else: + QtGui.QMessageBox.warning(self, "Erreur", "L'axe ("+ax+") est inconnu !") + return None + return ax, vec + + + # Add a new cylinder to the current electrode + def addCylinder(self): + # Safety check to avoid overwriting a cylinder + name = str(self.nameEdit.text()) + if name in self.cylinders: + QtGui.QMessageBox.warning(self, "Erreur", "Un élément avec ce nom existe déjà ! Changez le nom !") + return + + # Store the cylinder + (ax, vec) = self.getAxisVector() + v = self.lengthValue.value() + self.cylinders[name] = {'axis':ax, + 'vector':vec, + 'position':[self.posXValue.value(), self.posYValue.value(), self.posZValue.value()], + 'diameter': self.diameterValue.value(), + 'length': v, + 'center': [self.posXValue.value()+v*vec[0]/2.0, self.posYValue.value()+v*vec[1]/2.0, self.posZValue.value()+v*vec[2]/2.0], + 'type': str(self.typeCombo.currentText()), + 'shape':'cylinder'} + + # add an item to the cylinderList + item = QtGui.QListWidgetItem(name,self.cylinderList) + + # Display the cylinder + self.displayCylinder(name) + + # Prepare for the next cylinder + self.posXValue.setValue(self.posXValue.value() + vec[0]*self.lengthValue.value()) + self.posYValue.setValue(self.posYValue.value() + vec[1]*self.lengthValue.value()) + self.posZValue.setValue(self.posZValue.value() + vec[2]*self.lengthValue.value()) + + ## Set an element name that is not used yet + #while ("Element "+str(self.elementIndex)) in self.cylinders: + #self.elementIndex += 1 + #self.nameEdit.setText("Element "+str(self.elementIndex)) + + if self.typeCombo.currentIndex()==0: + self.typeCombo.setCurrentIndex(1) + elif self.typeCombo.currentIndex()==1: + self.typeCombo.setCurrentIndex(0) + + self.updateName() + + # Update the currently selected cylinder + def updateCylinder(self): + # TODO if the name changes ? + name = str(self.cylinderList.currentItem().text()) + (ax, vec) = self.getAxisVector() + v = self.lengthValue.value() + self.cylinders[name] = {'axis':ax, + 'vector':vec, + 'position':[self.posXValue.value(), self.posYValue.value(), self.posZValue.value()], + 'diameter': self.diameterValue.value(), + 'length': v, + 'center': [self.posXValue.value()+v*vec[0]/2.0, self.posYValue.value()+v*vec[1]/2.0, self.posZValue.value()+v*vec[2]/2.0], + 'type': str(self.typeCombo.currentText()), + 'shape':'cylinder'} + self.displayCylinder(name) + + # Display a cylinder selected from the list + def selectCylinder(self, name): + cyl = self.cylinders[name] + self.axisCombo.setCurrentIndex(self.axisCombo.findText(cyl['axis'])) + v = cyl['vector'] + self.xValue.setValue(v[0]) + self.yValue.setValue(v[1]) + self.zValue.setValue(v[2]) + v = cyl['position'] + self.posXValue.setValue(v[0]) + self.posYValue.setValue(v[1]) + self.posZValue.setValue(v[2]) + + self.diameterValue.setValue(cyl['diameter']) + self.lengthValue.setValue(cyl['length']) + self.typeCombo.setCurrentIndex(self.typeCombo.findText(cyl['type'])) + + self.displaySelect(name) + + # Delete the selected + def deleteCylinder(self): + item = self.cylinderList.takeItem(self.cylinderList.currentRow()) + self.undisplayCylinder(str(item.text())) + del self.cylinders[str(item.text())] + item = None + + # Refills the cylinderlist from the stored data + def updateCylinderList(self): + self.cylinderList.clear() + item = None + for name in sorted(self.cylinders): + item = QtGui.QListWidgetItem(name,self.cylinderList) + self.cylinderList.setCurrentItem(item) + + + # Click on an item and column in the list + def cylinderListClick(self, item,prevItem=None): + name = str(item.text()) + self.selectCylinder(name) + + def closeEvent(self, event): + self.quit() + + def quit(self): + reply = QtGui.QMessageBox.question(self, 'Message', + "Are you sure to quit?", QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No, QtGui.QMessageBox.No) + + if reply == QtGui.QMessageBox.Yes: + self.app.quit() + else: + pass + + # Display functions + def displayCylinder(self, name): + # If it is already there, remove it + self.undisplayCylinder(name) + self.displayed[name] = None + t = self.cylinders[name]['type'] + p = self.cylinders[name]['position'] + v = self.cylinders[name]['vector'] + r = self.cylinders[name]['diameter']/2.0 + pEnd = p[0] + v[0]*self.cylinders[name]['length'], p[1] + v[1]*self.cylinders[name]['length'], p[2] + v[2]*self.cylinders[name]['length'] + #print "New cylinder mesh at %.2f, %.2f, %.2f, radius=%.2f" % (p[0], p[1], p[2], r) + newCyl = self.a.toAObject(aims.SurfaceGenerator.cylinder(aims.Point3df(p[0], p[1], p[2]), aims.Point3df(pEnd), r, r, 24, True, True)) + + # Couleur automatique par catégorie + if t not in self.typeColors: + self.currentColorHue = (self.currentColorHue + 40) % 256 + self.typeColors[t] = QtGui.QColor.fromHsv(self.currentColorHue, 245, 220, 255); + color = self.typeColors[t] + self.a.setMaterial(newCyl, diffuse=[color.redF(), color.greenF(), color.blueF(), color.alphaF()]) + self.a.addObjects(newCyl, self.wins) + self.displayed[name] = {'mesh':newCyl, 'type':t} + + def undisplayCylinder(self, name): + if name in self.displayed: + self.a.removeObjects(self.displayed[name]['mesh'], self.wins) + self.a.deleteObjects(self.displayed[name]['mesh']) + + def updateDisplay(self): + self.clearDisplay() + # Add the new ones + for name in self.cylinders: + self.displayCylinder(name) + + def updateDisplayCylinder(self, name): + # Modify + self.a.deleteObjects([self.displayed[name]['mesh'],]) + self.displayCylinder(name) + + def clearDisplay(self): + # Destroy all anatomist objects and reset "displayed" list + if len(self.displayed) != 0: + meshes = [self.displayed[name]['mesh'] for name in self.displayed] + self.a.removeObjects(meshes, self.wins) + self.a.deleteObjects(meshes) + self.displayed={} + + def getDisplayed(self): + return self.displayed + + def getCylinders(self): + return self.cylinders + + def getAnatomistObjects(self): + return [self.displayed[n]['mesh'] for n in self.displayed] + + def plotMeshes(self): + return [self.displayed[n]['mesh'] for n in self.displayed if self.displayed[n]['type'] == 'Plot'] + + def setDisplayReferential(self, referential): + for name in self.displayed: + self.a.assignReferential(referential, self.displayed[name]['mesh']) + + def displaySelect(self, name): + g = self.a.getDefaultWindowsGroup() + if name in self.displayed: + g.setSelection(self.displayed[name]['mesh']) + else: + print "Cannot find %s in self.displayed -> cannot light up selection"%name + + def updateName(self): + + element_number = 1 + last_length = 0 + if self.typeCombo.currentIndex()==0: + for i_index in range(len(self.cylinders.keys())): + if self.cylinders[self.cylinders.keys()[i_index]]['type'] == 'Plot': + element_number += 1 + element_name = 'Plot'+str(element_number) + if 'Plot'+str(element_number-1) in self.cylinders.keys(): + last_length = self.cylinders['Plot'+str(element_number-1)]['length'] + elif self.typeCombo.currentIndex()==1: + for i_index in range(len(self.cylinders.keys())): + if self.cylinders[self.cylinders.keys()[i_index]]['type'] == 'Tube': + element_number += 1 + element_name = 'Element '+str(element_number) + if 'Element '+str(element_number-1) in self.cylinders.keys(): + last_length = self.cylinders['Element '+str(element_number-1)]['length'] + #while ("Element "+str(self.elementIndex)) in self.cylinders: + #self.elementIndex += 1 + self.nameEdit.setText(element_name) + if last_length !=0: + self.lengthValue.setValue(last_length) + + +# Fonction principale qui lance l'interface +def main(noapp=0): + app = None + if noapp == 0: + app = QtGui.QApplication(sys.argv) + window = ElectrodeEditorDialog(app = app) + window.show() + if noapp == 0: + sys.exit(app.exec_()) + +if __name__ == "__main__": + main() + diff --git a/electrode.py b/electrode.py new file mode 100644 index 0000000..b532622 --- /dev/null +++ b/electrode.py @@ -0,0 +1,209 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# (c) Inserm U836 2013 - Manik Bhattacharjee +# +# License GNU GPL v3 + +import os, pickle +from soma import aims +from PyQt4 import QtGui +import pdb + +# TODO : should use JSON, not pickle, but Brainvisa-4.3.0 pack does not contain json module for python + +# Each electrode is a group of cylinders. +# +# This can load electrode models and create the necessary objects in Anatomist to display them +# In that use case, you should : +# el = ElectrodeModel(theCurrentAnatomist) +# el.open('fileOdModel.elecdef') +# el.setDisplayReferential(electrodeReferential) +# cylinders = el.getDisplayed() +# meshes = el.getAnatomistObjects() +class ElectrodeModel: + + def __init__(self, anato = None, typeColors = {}, modelPath=None, dispMode = None, dispParams=None): + # Init of variables -> typeColors is a dict {'Plot':QColor(r,g,b), 'Other':QColor(R,G,B),...} + self.cylinders = {} + self.dispMode = 'real' + self.dispParams = {} + self.displayed = {} + self.typeColors = typeColors + self.a = anato + if modelPath is not None: + self.open(modelPath, dispMode, dispParams) + + # Load an Electrode Definition file + def open(self, path=None, dispMode = None, dispParams=None,bipole=None): + if path is None or not os.path.isfile(path): + print 'No electrode model at '+repr(path) + return False + + filein = open(path, 'rb') + self.cylinders = pickle.load(filein) + filein.close() + + # Reset colors + self.currentColorHue = 0 + self.typeColors = {} + # If shape is not defined, it's a cylinder + for name in self.cylinders: + if 'shape' not in self.cylinders[name]: + self.cylinders[name]['shape']='cylinder' + # If center of elements was not saved, compute it + if 'center' not in self.cylinders[name]: + pos = self.cylinders[name]['position'] + v = self.cylinders[name]['length'] + vec = self.cylinders[name]['vector'] + self.cylinders[name]['center'] = [pos[0] + v*vec[0]/2.0, pos[1]+v*vec[1]/2.0, pos[2]+v*vec[2]/2.0] + # Create the meshes + if dispMode: + self.dispMode = dispMode + if dispParams: + self.dispParams = dispParams + self.updateDisplay() + return True + + # Save an Electrode Definition file + def save(self, path = None): + if path is None or not os.path.isfile(path): + print "Cannot write electrode definition : invalid file path " + repr(path) + return False + fileout = open(path, 'wb') + pickle.dump(self.cylinders, fileout) + fileout.close() + return True + + + # Display functions + + def setDisplayMode(self, mode='real', parameters={}): + """ Mode display : 'real', 'sphere', 'off'... parameters is {'diameter: 2mm} for the sphere mode""" + self.dispMode = mode + self.dispParams = parameters + + + def displayCylinder(self, name): + # If it is already there, remove it + self.undisplayCylinder(name) + self.displayed[name] = None + t = self.cylinders[name]['type'] + p = self.cylinders[name]['position'] + v = self.cylinders[name]['vector'] + r = self.cylinders[name]['diameter']/2.0 + newCyl = None + + if self.dispMode == 'off': + self.displayed[name] = {'mesh':None, 'type':t} + return + if self.dispMode not in ['real', 'sphere', 'bipole']: + print "Unknown dispMode %s for electrode ! Using 'real'..."%repr(self.dispMode) + self.dispMode = 'real' + + if self.dispMode == 'real': + pEnd = p[0] + v[0]*self.cylinders[name]['length'], p[1] + v[1]*self.cylinders[name]['length'], p[2] + v[2]*self.cylinders[name]['length'] + newCyl = self.a.toAObject(aims.SurfaceGenerator.cylinder(aims.Point3df(p[0], p[1], p[2]), aims.Point3df(pEnd), r, r, 24, True, True)) + self.a.releaseObject(newCyl) + elif self.dispMode == 'sphere': + diam = 2.0 + if self.dispParams.has_key('diameter'): + diam = float(self.dispParams['diameter']) + if t == 'Plot': # Ignore the other parts + pCenter = (p[0] + v[0]*self.cylinders[name]['length']/2.0, p[1] + v[1]*self.cylinders[name]['length']/2.0, p[2] + v[2]*self.cylinders[name]['length']/2.0) + newCyl = self.a.toAObject(aims.SurfaceGenerator.sphere(aims.Point3df(pCenter[0], pCenter[1], pCenter[2]), diam, 32)) + self.a.releaseObject(newCyl) + #newCyl = self.a.toAObject(aims.SurfaceGenerator.cube(aims.Point3df(pCenter[0], pCenter[1], pCenter[2]), 2.0)) + elif self.dispMode == 'bipole': + #pCenter = (p[0] + v[0]*self.cylinders[name]['length']/2.0, p[1] + v[1]*self.cylinders[name]['length']/2.0, p[2] + v[2]*self.cylinders[name]['length']/2.0) + #to change one day + newCyl = self.a.toAObject(aims.SurfaceGenerator.ellipse(aims.Point3df(p[0],p[1],p[2]),2.5,1.5,50)) + self.a.releaseObject(newCyl) + #aims.SurfaceGenerator.ellipse() + + # Automatic color for an unknown type + if t not in self.typeColors: + self.currentColorHue = (self.currentColorHue + 40) % 256 + self.typeColors[t] = QtGui.QColor.fromHsv(self.currentColorHue, 245, 220, 255); + color = self.typeColors[t] + if newCyl is not None: + self.a.setMaterial(newCyl, diffuse=[color.redF(), color.greenF(), color.blueF(), color.alphaF()]) + self.displayed[name] = {'mesh':newCyl, 'type':t} + #print "Adding %s mesh for %s : %s"%(t,name,repr(newCyl)) + + def undisplayCylinder(self, name): + if name in self.displayed: + print "electrode : undisplay cylinder "+name + if self.displayed[name]['mesh'] is not None: + self.a.deleteObjects(self.displayed[name]['mesh']) + print "UNDISPLAY cylinder : DELETED %s"%name + self.displayed[name]['mesh'] = None # CURRENT + + def updateDisplay(self): + self.clearDisplay() + for name in self.cylinders: + self.displayCylinder(name) + + def updateDisplayCylinder(self, name): + self.undisplayCylinder(name) + self.displayCylinder(name) + + def clearDisplay(self): + # Destroy all anatomist objects and reset "displayed" list + if len(self.displayed) != 0: + meshes = [self.displayed[name]['mesh'] for name in self.displayed if self.displayed[name]['mesh'] is not None] + print "electrode : Removing all meshes" + #traceback.print_stack(limit=4) + try: + self.a.deleteObjects(meshes) # Does not work from locateElectrodes.py... CURRENT + except: + pass + for n in self.displayed: + self.displayed[n]['mesh']=None + self.displayed={} + + def getDisplayed(self): + return self.displayed + + def getCylinder(self, name): + return self.cylinders[name] + + def getCylinders(self): + return self.cylinders + + def getPlots(self): + return dict([(k,p) for k,p in self.cylinders.iteritems() if p['type'] == 'Plot']) + + def countPlots(self): + return len(self.getPlots()) + + def countCylinders(self): + return len(self.cylinders) + + def getAnatomistObjects(self): + return [self.displayed[n]['mesh'] for n in self.displayed if self.displayed[n]['mesh'] is not None] + + def plotMeshes(self): + return [self.displayed[n]['mesh'] for n in self.displayed if self.displayed[n]['type'] == 'Plot' and self.displayed[n]['mesh'] is not None] + + def setDisplayReferential(self, referential): + for name in self.displayed: + if self.displayed[name]['mesh'] is not None: + self.a.assignReferential(referential, self.displayed[name]['mesh']) + + def setTypeColors(self, typeColors): + self.typeColors = typeColors + # Automatic color for an unknown type + for name in self.cylinders: + t = self.cylinders[name]['type'] + if t not in self.typeColors: + self.currentColorHue = (self.currentColorHue + 40) % 256 + self.typeColors[t] = QtGui.QColor.fromHsv(self.currentColorHue, 245, 220, 255); + color = self.typeColors[t] + pdb.set_trace() + self.a.setMaterial(newCyl, diffuse=[color.redF(), color.greenF(), color.blueF(), color.alphaF()]) + + def displaySelect(self, name): + g = self.a.getDefaultWindowsGroup() + g.setSelection(self.displayed[name]['mesh']) + + diff --git a/electrodeEditor.ui b/electrodeEditor.ui new file mode 100644 index 0000000..b7a2511 --- /dev/null +++ b/electrodeEditor.ui @@ -0,0 +1,374 @@ + + + Form + + + + 0 + 0 + 705 + 837 + + + + Form + + + + + + + + Ouvrir... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Enregistrer sous... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Quitter + + + + + + + + + Orientation + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">L'axe oriente le cylindre : </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- <span style=" font-weight:600;">axe Z</span> : vertical (dorso-ventral) et orienté vers le bas</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- <span style=" font-weight:600;">axe Y</span> : rostro-caudal, orienté vers l'avant (le nez)</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- <span style=" font-weight:600;">axe X</span> : médian-latéral, orienté de la gauche vers la droite</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- <span style=" font-weight:600;">Custom</span> permet de choisir un axe arbitraire (<span style=" font-weight:600;">attention</span>, le vecteur choisi doit être de norme 1 !)</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Axe Z + + + + + Axe Y + + + + + Axe X + + + + + Custom... + + + + + + + + false + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + X + + + + + + + + false + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Y + + + + + + + + false + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Z + + + + + + + + + + Position + + + + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + X + + + + + + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Y + + + + + + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Z + + + + + + + + + + + + + + Diamètre (mm) + + + + + + + + + + Longueur (mm) + + + + + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + + + Plot1 + + + + + + + + Plot + + + + + Tube + + + + + + + + + + + + + + Supprimer + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Appliquer les changements + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ajouter + + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Sagittal - Axial - Coronal + + + Qt::AlignCenter + + + + + + + + diff --git a/electrodedisplaywidget.py b/electrodedisplaywidget.py new file mode 100644 index 0000000..d1ae2f8 --- /dev/null +++ b/electrodedisplaywidget.py @@ -0,0 +1,1301 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Widget to select and display electrode plots on a common referential/template +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# +from PyQt4 import QtGui, QtCore, uic + +import sys, pickle, shutil, traceback, os, json, re, numpy, csv + + +from brainvisa import axon +from brainvisa import anatomist +from soma import aims +import registration + +from locateElectrodes import createElectrode, getPlotsCenters, getPlots, getPlotsNames, createBipole +from referentialconverter import ReferentialConverter +from templatewidget import TemplateMRI, TemplateMNI +from brainvisa.data.readdiskitem import ReadDiskItem +from brainvisa.data.writediskitem import WriteDiskItem +from brainvisa.data import neuroHierarchy +from readSulcusLabelTranslationFile import * +from readFreesurferLabelFile import * +from externalprocesses import PythonExecutor +from checkSpmVersion import * +from readFunctionalTractography import * +from scipy import spatial as sc_sp +#from numpy.matlib import repmat +from collections import OrderedDict +import control_ftract +from locateElectrodes import natural_keys + +from bipoleSEEGColors import bipoleSEEGColors +from control_ftract2 import * + +import pdb + +def loadElectrodeModels(): + """Load electrode models from the database""" + models = {} + rdiEM = ReadDiskItem('Electrode Model', 'Electrode Model format') + result = list (rdiEM._findValues( {}, None, False ) ) + for e in result: + #WARNING if a model is available from multiple protocols, it will use only one + models[str(e.attributes()['model_name'])] = e + return models + + +class ElectrodeDisplayWidget(QtGui.QWidget): + def __init__(self, app=None, ana = None,dataSubjects = None): + QtGui.QWidget.__init__(self) + uic.loadUi("groupPlots.ui", self) + self.subjects = [] + self.subjItems = [] + self.implantations = {} + self.plotsData = {} + self.testDataSubjects = dataSubjects + self.taskCounter = 0 + self.tasks = [] + self.meshes = {} + self.bipolesmeshes = {} + self.dispMode = 'off'#'sphere' + self.dispParams = {'diameter':2.0} + self.transfoManager = registration.getTransformationManager() + # Get ReferentialConverter (for Talairach, AC-PC...) + self.refConv = ReferentialConverter() + + self.electrodeModels = loadElectrodeModels() + self.addSelectionButton.clicked.connect(self.addSelection) + self.removeSelectionButton.clicked.connect(self.removeSelection) + self.removePlotsNotTRC.clicked.connect(self.removeNotTRC) + self.removePlotsLeftSide.clicked.connect(lambda :self.removePlotsLeftRight('Left')) + self.removePlotsRightSide.clicked.connect(lambda :self.removePlotsLeftRight('Right')) + self.addAroundButton.clicked.connect(self.selectAround) + #self.normalizeButton.clicked.connect(self.normalizeCoords) + #self.saveNormalizedButton.clicked.connect(self.saveNormalizedCoords) + self.selectionList.itemDoubleClicked.connect(self.updatePlotSelected) + self.generateStatsButton.clicked.connect(self.generateStatisticsContacts) + + #fill the combo possibility. + loca = ['*'] + parcels_namesMA= readSulcusLabelTranslationFile('parcels_label_name.txt') + loca.extend(parcels_namesMA.values()) + loca.sort() + self.AddMAparcels2SelectioncomboBox.clear() + self.AddMAparcels2SelectioncomboBox.addItems(loca) + self.AddMAparcels2SelectioncomboBox.currentIndexChanged.connect(self.AddMAparcels2selection) + + self.radioButtonbothHemi.toggled.connect(self.changeBothRightDisplay) + #self.radioButtonAllRight.toggled.connect(self.changeBothRightDisplay) + + self.radioButtonContactDisplay.toggled.connect(self.contactSEEGDisplay) + #self.radioButtonsEEGResults.toggled.connect(self.contactSEEGDisplay) + + pix = QtGui.QPixmap('/home/b67-belledone/Desktop/epilepsie-manik/Logo-F-TRACT.xpm' ) + anatomist.anatomist.cpp.IconDictionary.instance().addIcon('ftract_control', pix) + ad = anatomist.anatomist.cpp.ActionDictionary.instance() + #control = ensemble d'action + ad.addAction( 'fTract_Action', StimulateResults ) + cd = anatomist.anatomist.cpp.ControlDictionary.instance() + cd.addControl( 'ftract_control', ControlFtract, 25 ) + cm = anatomist.anatomist.cpp.ControlManager.instance() + cm.addControl('QAGLWidget3D','','ftract_control') + + + + # Anatomist windows and objects + if ana == None: + self.a = anatomist.Anatomist('-b' ) + else: + self.a = ana + + layout = QtGui.QHBoxLayout( self.viewWidget ) + self.axWindow = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.axWindow.setParent(self.viewWidget) + layout.addWidget( self.axWindow.getInternalRep() ) + + self.sagWindow = self.a.createWindow( 'Sagittal' )#, no_decoration=True ) + self.sagWindow.setParent(self.viewWidget) + layout.addWidget( self.sagWindow.getInternalRep() ) + + + self.axWindow.internalRep.otherwindow = self.sagWindow + self.windows = [self.axWindow, self.sagWindow] + #pdb.set_trace() + #self.axWindow.connect() + + + + self.templates = {'MNI':TemplateMNI(self.a)} + #self.templateCombo.clear() + #self.templateCombo.addItems(sorted(self.templates.keys())) + self.setTemplate(self.templates['MNI']) + self.templReferential = None + #self.templateCombo.currentIndexChanged.connect(self.templateChanged) + + self.subjectList.itemSelectionChanged.connect(self.subjectSelectionChanged) + self.electrodeList.itemSelectionChanged.connect(self.electrodeSelectionChanged) + self.selectionList.itemSelectionChanged.connect(self.selectedSelectionChanged) + self.addDisplayButton.clicked.connect(self.displayImage) + self.addMNIImageToDisplayList.clicked.connect(self.addMNIImagetoList) + self.addMNIMeshTextToDisplayList.clicked.connect(self.addMNIMeshTexttoList) + + + def setStatus(self, text): + self.statusLabel.setText(str(text)) + + def incTaskCounter(self): + self.taskCounter = self.taskCounter + 1 + self.setStatus(u"Tasks in progress : "+str(self.taskCounter)) + return self.taskCounter + + def decTaskCounter(self): + self.taskCounter = self.taskCounter - 1 + self.setStatus(u"Tasks in progress : "+str(self.taskCounter)) + return self.taskCounter + + def startTask(self, taskFunction): + pe = PythonExecutor(taskFunction) + self.tasks.append(pe) + # Remove it from the list of threads when finished + pe.finished.connect(lambda th=pe:self.taskFinished(th)) + self.incTaskCounter() + pe.start() + + def taskFinished(self, thread): + self.tasks.remove(thread) + self.decTaskCounter() + + def setTemplate(self, templ): + """Set the template used as a common referential""" + # Un nom, des données (IRM ?) un identifiant de référentiel pour le refconv ? + self.template = templ + if self.template.referentialAnatomist: + self.a.assignReferential(self.template.referentialAnatomist, self.windows) + if self.template.volumes: + self.displayCombo.clear() + #self.displayCombo.addItems(["Image "+str(i) for i in range(len(self.template.volumes))]) + self.displayCombo.addItems([os.path.split(im.fullPath())[1] for im in self.template.volumes]) + + #def templateChanged(self, tpl): + #"""The combo box to select the template was changed""" + ## Read combo, setTemplate, remove selection or reset display (no spheres, no images)... + #pass + + def displayImage(self): + try: + #try: + #self.a.removeObjects([self.currentImage,],self.windows) #self.axWindow.removeObjects(self.currentImage) + ##self.sagWindow.removeObjects(self.currentImage) + #except: + #pass + self.currentImage = self.a.loadObject(self.template.volumes[self.displayCombo.currentIndex()]) + self.a.addObjects([self.currentImage], self.windows) + except: + print "Could not add selected image" + pdb.set_trace() + + def subjectSelectionChanged(self): + """Subject selection changed, update electrode list selection""" + selected = [str(item.text()) for item in self.subjectList.selectedItems()] + for i in xrange(self.electrodeList.count()): + selec = False + for s in selected: + if str(self.electrodeList.item(i).text()).startswith(s): + selec = True + break + self.electrodeList.item(i).setSelected(selec) + + def electrodeSelectionChanged(self): + """Electrode selection changed, update plot list selection""" + selected = [str(item.text()) for item in self.electrodeList.selectedItems()] + for i in xrange(self.plotList.count()): + selec = False + for s in selected: + if str(self.plotList.item(i).text()).startswith(s): + selec = True + break + self.plotList.item(i).setSelected(selec) + + #def plotSelectionChanged(self): + # pass + + def selectedSelectionChanged(self): + """In the selected plots list, the selected items changed -> update the view""" + # Update Anatomist selection -> select all meshes for the selected plots + g = self.a.getDefaultWindowsGroup() + g.setSelection([self.meshes[str(item.text())] for item in self.selectionList.selectedItems()]) + + def plotDataFromFullName(self, name): + """Get the data from a plot using its full name (e.g. Gre_2014_DUPj : A 2)""" + (sub, elec, plot) = self.plotNameFromFullPlotName(name) + return self.plotsData[sub][elec][plot] + + def fullPlotName(self, subj, elec, plot): + """Compute fully qualified plot name from subject, electrode, plot names""" + return subj + ' : ' + elec + ' ' + plot + + def plotNameFromFullPlotName(self, name): + """Get subject, electrode, plot names from the displayed name Subject : Electrode Plot (e.g. Gre_2014_DUPj : A 2)""" + (sub, elecplot) = name.split(' : ') + (elec, plot) = elecplot.split() + return (sub, elec, plot) + + #def normalizeCoords(self): + #"""Get plot coordinates in the selected template referential and store these coordinates in self.plotData""" + + #def miniFunc(myself, coordsSB, s): + #"""Internal mini function to launch in a thread""" + #refId = myself.implantations[s]['ReferentialUuid'] + #normCoords = myself.template.normalizeCoordinates([coordsSB[s][el][p] for el in coordsSB[s] for p in coordsSB[s][el]], refId) + ##pdb.set_trace() + #idx = 0 + #if normCoords is None: + #print "normCoords is None for subject %s : could not convert coordinates to template referential"%s + #return + ##import pdb; pdb.set_trace() + #for el in coordsSB[s]: + #for p in coordsSB[s][el]: + #myself.plotsData[s][el][p][myself.template.name] = normCoords[idx] + #idx = idx + 1 + ##fin de la fonction miniFunc + + #print "go back to locateElectrode for now, we don't manage call to normalisation from locateElectrode for now" + #return + #coordsSB = {} + #for s in self.subjects: + #coordsSB[s] = {} + #for elec, plots in self.plotsData[s].iteritems(): + #sb = dict([(p,plots[p]['Scanner-based']) for p in plots if self.template.name not in plots[p].keys()]) + #if len(sb) > 0: + #coordsSB[s][elec] = sb + ## Compute template coords for this subject + #self.startTask(lambda myself=self, cSB=coordsSB, suj=s:miniFunc(myself, cSB, suj)) + + + #def saveNormalizedCoords(self): + #"""Should save all computed coordinates of plots in elecimplant file for all subject + #with the timestamp of the original data, to avoid recomputation""" + #for s,rdi in zip(self.subjects, self.subjItems): + #self.saveImplantation(s, rdi) + #return + + def selectAround(self): + """Find in the list of selected plots the ones near the linked cursor""" + # Get linked cursor coords (in template referential) + pTempl = self.a.linkCursorLastClickedPosition(self.template.referentialAnatomist).items()[:3] + # Get accepted radius + r2 = self.radiusSpin.value()**2 + meshes = [] + # Compute distance to all selected plots + pdb.set_trace() #need to check if need to take absolute value in x in mni + for i in xrange(self.selectionList.count()): + fullname = str(self.selectionList.item(i).text()) + (sub, elec, plot) = self.plotNameFromFullPlotName(fullname) + coords = self.plotsData[sub][elec][plot][self.template.name][:3] + dist2 = (coords[0]-pTempl[0])**2 + (coords[1]-pTempl[1])**2 + (coords[2]-pTempl[2])**2 + # Select item if in range, deselect if not + self.selectionList.item(i).setSelected(dist2 <= r2) + if fullname in self.meshes and dist2 <= r2: + meshes.append(self.meshes[fullname]) + # Select them in Anatomist + g = self.a.getDefaultWindowsGroup() + g.setSelection(meshes) + + def setSubjects(self, names, diskitems): + """Sets the list of subjects (and corresponding readdiskitems in the database) for the widget""" + self.subjects = sorted(names) + self.subjItems = diskitems + self.loadImplantations() + self.plotsData = dict([(s, self.getPlotDataFromImplantation(s)) for s in self.subjects]) + #remove NonType from plotsData + pat_to_remove = [] + for jj,kk in self.plotsData.iteritems(): + if kk is None: + #self.plotsData.pop(jj,None) + pat_to_remove.append(jj) + + for ii in range(len(pat_to_remove)): + self.plotsData.pop(pat_to_remove[ii],None) + + if len(self.plotsData.keys()) == 0: + print "No data to show" + return + self.updateUIplots() + + def addSelection(self): + """Add the selected plots/subjects/electrodes to the selection """ + current = [str(self.selectionList.item(i).text()) for i in xrange(self.selectionList.count())] # FIXME pas juste les selected ! Tous les items + new = [str(s.text()) for s in self.plotList.selectedItems() if str(s.text()) not in current] + + # Display the new ones + meshes = [] + invalid = set() + for n in new: + if self.template.name in self.plotDataFromFullName(n): + mesh = self.displaySphereAt(self.plotDataFromFullName(n)[self.template.name], self.plotDiameter(), self.template.referentialAnatomist, color=(0.0,0.9,0.1,1.0),name = n) + self.meshes[n] = mesh + meshes.append(mesh) + else: + invalid.add(n) # If there, coordinates are not available in the right template referential + if len(invalid) > 0: + print "Some plots were not added to the selection, because normalized coordinates were not available for them" + new = list(set(new) - invalid) + self.selectionList.addItems(new) + self.a.addObjects(meshes, self.windows) + + def plotDiameter(self): + """Returns the diameter of the spheres used to display plots""" + return 2.0 + + def displaySphereAt(self, center, diameter, referential, color, name = None): + """Returns a spherical mesh (anatomist object) with color = [1.0,0.0,0.0,1.0] for a red, not transparent sphere""" + mesh = self.a.toAObject(aims.SurfaceGenerator.sphere(aims.Point3df(center[0], center[1], center[2]), diameter, 54)) + if name is not None: + mesh.setName(name) + self.a.setMaterial(mesh, diffuse=color)#[color.redF(), color.greenF(), color.blueF(), color.alphaF()] #sortir le setMaterial(diffuse=color) et le mettre à la fin de la boucle for des fonctions qui l'appelle ? + self.a.assignReferential(referential, mesh) + return mesh + + def removeSelection(self): + """Remove plots from the selected list""" + removable = [str(s.text()) for s in self.selectionList.selectedItems()] + meshes = [self.meshes[r] for r in removable if r in self.meshes] + for r in removable: + if r in self.meshes: + del self.meshes[r] + self.a.removeObjects(meshes, self.windows) + self.a.deleteObjects(meshes) + # Reverse loop to remove from the bottom (avoids messing up the index) + for idx in reversed(range(self.selectionList.count())): + if str(self.selectionList.item(idx).text()) in removable: + self.selectionList.takeItem(idx) + + def removeNotTRC(self): + """Remove plots which are not registered in the TRC""" + all_items=[str(self.selectionList.item(i).text()) for i in range(self.selectionList.count())] + #on remplace les ' par des p dans all_items + all_items = [all_items[x].replace("'","p") for x in range(len(all_items))] + full_list_trc=[] + for subj in self.subjects: + #check if exist TRC in DB for this subject + rdi = ReadDiskItem('Raw SEEG recording', 'EEG TRC format' ) + di = rdi.findValue({'subject':subj}) + if di is not None: + data_micromed = neo.MicromedIO(filename = str(di)).read_segment() #all data + taille=len(data_micromed.analogsignals) + ##Normalisation name (between analogsignals' name and plots' name) + number=['01', '02', '03', '04', '05', '06', '07', '08', '09'] + noms=[] + for i in range(taille): + name=data_micromed.analogsignals[i].name + name=name.upper() + if name[len(name)-2:] in number: + name=name[:len(name)-2]+name[len(name)-1:] + setattr(data_micromed.analogsignals[i],'name',name) + noms+=[data_micromed.analogsignals[i].name] + + #re.sub(noms[16],re.findall('\d+',noms[16])[0],subj + " : " + "Plot"+re.findall('\d+',noms[16])[0]) + #noms_remade= [subj + " : " + re.findall('\S+(? 0] + #on remplace les ' par des p dans noms_remade + [full_list_trc.append(noms_remade[x].replace("'","p")) for x in range(len(noms_remade))] + + + to_keep=[all_items[x] for x in range(len(all_items)) for y in range(len(full_list_trc)) if all_items[x]==full_list_trc[y]] + to_remove=list(set(all_items)-set(to_keep)) + + meshes = [self.meshes[r] for r in to_remove if r in self.meshes] + for r in to_remove: + if r in self.meshes: + del self.meshes[r] + self.a.removeObjects(meshes, self.windows) + self.a.deleteObjects(meshes) + # Reverse loop to remove from the bottom (avoids messing up the index) + for idx in reversed(range(self.selectionList.count())): + if str(self.selectionList.item(idx).text()) in to_remove: + self.selectionList.takeItem(idx) + + + + def removePlotsLeftRight(self, side): + + + all_items=[str(self.selectionList.item(i).text()) for i in range(self.selectionList.count())] + + to_remove = [] + for ii in all_items: + MNI_pos = self.plotDataFromFullName(ii)['MNI'] + + if side == 'Left': + if MNI_pos[0] >= 0: + to_remove.append(ii) + elif side == 'Right': + if MNI_pos[0] <=0: + to_remove.append(ii) + + meshes = [self.meshes[r] for r in to_remove if r in self.meshes] + for r in to_remove: + if r in self.meshes: + del self.meshes[r] + + self.a.removeObjects(meshes,self.windows) + self.a.deleteObjects(meshes) + + for idx in reversed(range(self.selectionList.count())): + if str(self.selectionList.item(idx).text()) in to_remove: + self.selectionList.takeItem(idx) + + + + def updateUIplots(self): + self.subjectList.clear() + self.subjectList.addItems(self.subjects) + allElecs = sorted([s + ' : ' + el for s in self.plotsData.keys() for el in self.plotsData[s].keys()]) + self.electrodeList.clear() + self.electrodeList.addItems(allElecs) + allPlots = sorted([self.fullPlotName(s, el, pl) for s in self.plotsData.keys() for el in self.plotsData[s].keys() for pl in self.plotsData[s][el].keys() ]) + self.plotList.clear() + self.plotList.addItems(allPlots) + + def t1pre2ScannerBased(self, subject): + """ Returns a triplet of Anatomist objects (native T1pre referential, scanner-base T1pre referential, Transformation from T1pre referential to T1pre Scanner-Based referential) """ + rdi = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True,\ + requiredAttributes={'modality':'t1mri', 'subject':subject}) + allTransf = list (rdi._findValues( {}, None, False ) ) + for trsf in allTransf: + if trsf.attributes()['acquisition'].startswith(u'T1pre'): + print repr(trsf.attributes()) + srcrDiskItem = self.transfoManager.referential( trsf.attributes()['source_referential'] ) + srcr = self.a.createReferential(srcrDiskItem) + dstrDiskItem = self.transfoManager.referential(trsf.attributes()['destination_referential']) + self.t1pre2ScannerBasedId = trsf.attributes()['destination_referential'] + dstr = self.a.createReferential(dstrDiskItem) + return (srcr, dstr, self.a.loadTransformation(trsf.fullPath(), srcr, dstr)) + return None + + def loadImplantations(self): + self.implantations = dict([(s,self.loadImplantation(rdi)) for s,rdi in zip(self.subjects, self.subjItems)]) + + def loadImplantation(self, rdiSuj): + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format') + impl = rdi.findValue(rdiSuj) + + if not impl: + print "Cannot find implantation for %s"%rdiSuj.attributes()['subject'] + return {} + if (os.path.exists(str(impl))): + filein = open(str(impl), 'rb') + try: + dic = json.loads(filein.read()) + except: + filein.close() + filein = open(str(impl), 'rb') + dic = pickle.load(filein) + + filein.close() + + #we load eleclabel now if exist + rdi_eleclabel = ReadDiskItem('Electrodes Labels','Electrode Label Format') + impl_label = rdi_eleclabel.findValue(rdiSuj) + + if not impl_label: + print("Cannot find implantation label for %s"%rdiSuj.attributes()['subject']) + pass + else: + if (os.path.exists(str(impl_label))): + filein = open(str(impl_label),"rb") + try: + dic2 = json.loads(filein.read()) + except: + filein.close() + filein.open(str(impl_label),"rb") + dic2 = pickle.load(filein) + + filein.close() + dic.update({'label':dic2['plots_label']}) + + return dic + + #print "Exception while reading implantation file for %s"%rdiSuj.attributes()['subject'] + #return {} + + def saveImplantation(self, subj, rdiSubj): + wdi = WriteDiskItem( 'Electrode implantation', 'Electrode Implantation format') + impl = wdi.findValue(rdiSubj) + if impl is None: + print "Could not find electrode implantation file to save to (%s) !"%subj + return + try: + #import pdb; pdb.set_trace() + fileout = open(impl.fullPath()+'.temporary', 'wb') + content = self.implantations[subj] + content['plotsData-timestamp'] = content['timestamp'] + content['plotsData'] = self.plotsData[subj] + fileout.write(json.dumps(content)) + #pickle.dump(content, fileout) + fileout.close() + #to modify to json + shutil.move(impl.fullPath()+'.temporary', impl.fullPath()) + neuroHierarchy.databases.insertDiskItem( impl, update=True ) + except: + print "Exception while writing implantation file for %s"%subj + traceback.print_exc(file=sys.stdout) + return + + + + def getPlotDataFromImplantation(self, subj): + els = self.subjectElectrodes(subj) + #self.addElectrode(e['name'], e['model'], e['target'], e['entry'], refId) + if 'plotsData' in self.implantations[subj]: + if self.implantations[subj]['plotsData-timestamp'] == self.implantations[subj]['timestamp']: + print "Using pre-recorded plots coordinates for %s"%subj + return self.implantations[subj]['plotsData'] + else: + print "PlotsData timestamp was invalid for %s"%subj + res = {} + for e in els: + res[e['name']] = self.getPlotsFromElectrode(e, subj) + + print(subj) + if "plotsMNI" in self.implantations[subj].keys(): + info_plotsMNI = dict(self.implantations[subj]['plotsMNI']) + for kk,vv in res.iteritems(): + for ll,ww in res[kk].iteritems(): + ww.update({"MNI":info_plotsMNI[kk+"%02d"%int(ll[4:])]}) + if "label" in self.implantations[subj].keys(): + try: + ww.update({"label":self.implantations[subj]["label"][kk+"%02d"%int(ll[4:])]}) + except: + pdb.set_trace() + else: + print "Error MNI Coordinates" + QtGui.QMessageBox.warning(self, "Error", "MNI coordinates haven't been generated for electrode contacts of Subject: {}\nThey have to be generated using locateElectrodes".format(subj)) + return + + return res + + def getPlotsFromElectrode(self, el, subj): + print "Creating electrode model for %s"%subj + traceback.print_exc(file=sys.stdout) + (nativeRef, sbRef, t1pre2ScannerBased) = self.t1pre2ScannerBased(subj) + (newRef, transf, elecModel) = createElectrode(el['target'], el['entry'], nativeRef, ana=self.a, model = self.electrodeModels[str(el['model'])].fullPath(), dispMode = self.dispMode, dispParams = self.dispParams) + plots = getPlots(elecModel) + pNames = getPlotsNames(elecModel) + return dict([(n, {'internal':plots[n]['center'], 'native':list(transf.transform(plots[n]['center'])), 'Scanner-based':list(t1pre2ScannerBased.transform(transf.transform(plots[n]['center'])))}) for n in pNames]) + + def getSubjectImplantation(self, subj): + """Returns electrode implantation data for the subject (dictionary from the elecimplant file)""" + return self.implantations[subj] + + def subjectElectrodes(self, subj): + """Returns the list available electrodes for the subject""" + impl = self.getSubjectImplantation(subj) + if 'electrodes' in impl: + return impl['electrodes'] + return [] + + def subjectElectrodesNames(self, subj): + """Returns the list of names of available electrodes for the subject""" + return [el['name'] for el in self.subjectElectrodes()] + + def subjectPlot(self, subj, electrode): + """Returns the list of plots of the chosen electrode for the subject""" + impl = self.getSubjectImplantation(subj) + if 'electrodes' in impl: + els = [e for e in impl['electrodes'] if e['name'] == electrode] + if len(els) > 0: + els[0] # (e['name'], e['model'], e['target'], e['entry'], refId) + return None + + def getPlotsCoordinates(self, subj, referential = None, electrode = None, plot = None): + """Returns the coordinates of the centers of all plots of the subject, or only for the given electrodes/plots + If referential is None, coordinates are returned in the native referential (T1pre of the subject) + """ + return None + + def updatePlotSelected(self, item = None): + try: + if item is not None: + xyz = self.plotDataFromFullName(str(item.text()))[self.template.name] + # setLinkedCursor uses window referential : must apply transform before setting the position + self.windows[0].moveLinkedCursor(xyz) + else: + print "Error moving the cursor to the contact2" + except Exception as e: + print "Error moving the cursor to the contact" + #pdb.set_trace() + + def addMNIImagetoList(self,path_fichier = None): + + if path_fichier is None or path_fichier is False: + fichier = QtGui.QFileDialog.getOpenFileName(self, "Opening file: ", "", "(*.nii *.gii *.img *.nii.gz)") + elif not os.path.isfile(path_fichier): + fichier = QtGui.QFileDialog.getOpenFileName(self, "Opening file: ", "", "(*.nii *.gii *.img *.nii.gz)") + else: + fichier = path_fichier + + image_mni_ref = self.a.loadObject(self.template.volumes[0]) + #image_mni_ref.loadReferentialFromHeader() + #try: + #self.a.removeObjects([self.currentImage,],self.windows) + #except: + #pass + self.currentImage = self.a.loadObject(str(fichier)) + #self.currentImage.loadReferentialFromHeader() + self.a.execute('LoadReferentialFromHeader', objects=[image_mni_ref,self.currentImage]) + all_trans = self.a.getTransformations() + trans_from_vols = [] + tm=registration.getTransformationManager() + tm.referential(registration.talairachMNIReferentialId) + for vol in (self.currentImage, image_mni_ref): + trans_from_vol = [t for t in all_trans if t.source() == vol.referential and not t.isGenerated()] + # hope trans_from_vol1 contains just one transform + # but if there are several, try to select the one going to + # scanner-based + if len(trans_from_vol) > 1: + trans_from_vol_filt = [t for t in trans_from_vol if t.destination().header()['name'].startswith('Scanner-based anatomical coordinates')] + if len(trans_from_vol_filt) == 1: + trans_from_vol = trans_from_vol_filt + if len(trans_from_vol) == 0: + raise RuntimeError('could not find a non-ambiguous transform') + elif len(trans_from_vol) > 1: + print "There is more than one available transformation ... we take the first one and pray" + trans_from_vol[0] = trans_from_vol_filt[0] + trans_from_vols.append(trans_from_vol) + + #pdb.set_traceI() + trans_from_vol1, trans_from_vol2 = trans_from_vols + self.template.volumes.append(str(fichier)) + self.a.execute('LoadTransformation',origin=trans_from_vol1[0].destination(),destination=trans_from_vol2[0].destination(),matrix=[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + self.a.addObjects([self.currentImage,], self.windows) + self.displayCombo.addItems([os.path.split(str(fichier))[1]]) + + def addMNIMeshTexttoList(self): + + #fichierMesh = QtGui.QFileDialog.getOpenFileName(self, "Opening mesh (surface corresponding to the texture): ", "", "(*.gii)") + + ##check if the file exist + #if not os.path.isfile(fichierMesh): + #print("the file doesn't exist") + #return + + #self.addMNIImagetoList(fichierMesh) + + #ask for a texture gii or a functionalTractography file + texture_info = QtGui.QMessageBox(self) + texture_info.setText("Choose the type of texture format (gii or csv to generate the gii)") + texture_info.setWindowTitle("texture format") + gii_button = texture_info.addButton(QtGui.QPushButton('.gii'),QtGui.QMessageBox.AcceptRole) + csvfuncTract_button =texture_info.addButton(QtGui.QPushButton('.csv functionalTractography'),QtGui.QMessageBox.AcceptRole) + #center_seg.setWindowModality(QtCore.Qt.NonModal) + texture_info.show() + texture_info.exec_() + #reply = texture_info.buttonRole(texture_info.clickedButton()) + if str(texture_info.clickedButton().text())=='.gii': + print("texture already gii generated") + fichierTexture = QtGui.QFileDialog.getOpenFileName(self, "Opening texture (corresponding to the mesh): ", "", "(*.gii)") + pdb.set_trace() + elif str(texture_info.clickedButton().text())=='.csv functionalTractography': + print("have to generate the gii texture from the csv data, functionalTractography csv model") + fichierCSV = QtGui.QFileDialog.getOpenFileName(self, "Opening functional tractography data: ", "", "(*.csv)") + if not os.path.isfile(fichierCSV): + print("the file doesn't exist") + full_data = readFunctionalTractography(fichierCSV) + + #ask where to save the data + path_to_save = QtGui.QFileDialog.getExistingDirectory(self,'Directory to save the mesh') + + BrodmannParcels = aims.read('MNI_Atlases/rbrodmann.nii') + BrodmannParcelsArrayData = BrodmannParcels.arraydata() + left_white = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/Gre_2016_MNI1_Lwhite.gii') + right_white = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/Gre_2016_MNI1_Rwhite.gii') + + list_remove = set(['Patient', 'Atlas']) + list_condi_max = set(['ValueNb','PeakDelayMed','PeakDelaySTD','Probability']) + list_condi_present = set(full_data.keys()) + + #condi_intersect = list(list_condi_max & list_condi_present) + condi_intersect = sorted(list(list_condi_present-list_remove), key=lambda s: s.lower()) + nb_time = len(condi_intersect) + + orderTexture = dict([(i,condi_intersect[i]) for i in range(len(condi_intersect))]) #{0:'ValueNb',1:'PeakDelayMed',2:'PeakDelaySTD',3:'Probability'} + + if full_data['Atlas'] == 'MarsAtlas': + #read the marsAtlas parcellation + left_MA = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_Lwhite_parcels_marsAtlas.gii') + right_MA = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_Rwhite_parcels_marsAtlas.gii') + + #for i in range(len(condi_intersect)): + # left_white.vertex(i).assign(left_white.vertex(0)) + # left_white.normal(i).assign(left_white.normal(0)) + # left_white.polygon(i).assign(left_white.polygon(0)) + # right_white.vertex(i).assign(right_white.vertex(0)) + # right_white.normal(i).assign(right_white.normal(0)) + # right_white.polygon(i).assign(right_white.polygon(0)) + + aims.write(left_white,str(path_to_save) + os.path.sep + 'left_white.gii') + aims.write(right_white,str(path_to_save) + os.path.sep + 'right_white.gii') + + try: + os.mkdir(str(path_to_save)+os.path.sep+'Texture') + except: + pass + + #faire un test si all au lieu des noms de parcels. + for i_parcels_stimulated in full_data[orderTexture[0]].keys(): + + if len( full_data[orderTexture[0]][i_parcels_stimulated]) > 0: + new_TimeSurfTextLeft = aims.TimeTexture('FLOAT') + new_TimeSurfTextRight = aims.TimeTexture('FLOAT') + + for i in range(nb_time): #assign the value + textnowLeft = new_TimeSurfTextLeft[i] + textnowRight = new_TimeSurfTextRight[i] + + textnowLeft.reserve(len(left_white.vertex(0))) #left_white.vertex(0))) + textnowRight.reserve(len(right_white.vertex(0))) + marsatlas_label = readSulcusLabelTranslationFile('parcels_label_name.txt') + + #gauche #control lateral lorsqu'étude contro/ipsi + for iter_vert in range(len(left_white.vertex(0))): + #marsatlas_label[left_MA[0].arraydata()[iter_vert]] + #if isinstance(full_data[orderTexture[i]]['L_VCcm'][marsatlas_label[left_MA[0].arraydata()[iter_vert]]], (str, unicode)): + + #join right and left or not + #for now we assume that we are using marsatlas + actual_marsatlas_parcels = [] + + if i_parcels_stimulated.startswith('L_') or i_parcels_stimulated.startswith('R_'): + try: + actual_marsatlas_parcels = [marsatlas_label[left_MA[0].arraydata()[iter_vert]]] + except: + pass #faudrait mieux mettre si c'est == 0 alors c'est un vertex qui n'a pas de correspondance marsatlas. + elif i_parcels_stimulated == 'All': + try: + actual_marsatlas_parcels = [marsatlas_label[left_MA[0].arraydata()[iter_vert]]] + except: + pass #faudrait mieux mettre si c'est == 0 alors c'est un vertex qui n'a pas de correspondance marsatlas. + else: + try: + actual_marsatlas_parcels = [[marsatlas_label[left_MA[0].arraydata()[iter_vert]]][0][2:]] + except: + pass + + try: + if left_MA[0].arraydata()[iter_vert] == 0: + textnowLeft.append(-4) + else: + if full_data[orderTexture[i]][i_parcels_stimulated].keys()[0].startswith('i_') or full_data[orderTexture[i]][i_parcels_stimulated].keys()[0].startswith('c_'): + if full_data[orderTexture[i]][i_parcels_stimulated]['c_'+actual_marsatlas_parcels[0]] == 'NaN': + textnowLeft.append(-4) + else: + textnowLeft.append(float(full_data[orderTexture[i]][i_parcels_stimulated]['c_'+actual_marsatlas_parcels[0]])) + else: + if full_data[orderTexture[i]][i_parcels_stimulated][actual_marsatlas_parcels[0]] == 'NaN': + textnowLeft.append(-4) + else: + textnowLeft.append(float(full_data[orderTexture[i]][i_parcels_stimulated][actual_marsatlas_parcels[0]])) + except: + textnowLeft.append(-4) + #pdb.set_trace() + + #puis droite #ipsi lateral lorsqu'étude contro_ipsi + for iter_vert in range(len(right_white.vertex(0))): + + actual_marsatlas_parcels = [] + + if i_parcels_stimulated.startswith('L_') or i_parcels_stimulated.startswith('R_'): + try: + actual_marsatlas_parcels = [marsatlas_label[right_MA[0].arraydata()[iter_vert]]] + except: + pass + elif i_parcels_stimulated == 'All': + try: + actual_marsatlas_parcels = [marsatlas_label[right_MA[0].arraydata()[iter_vert]]] + except: + pass #faudrait mieux mettre si c'est == 0 alors c'est un vertex qui n'a pas de correspondance marsatlas. + else: + try: + actual_marsatlas_parcels = [[marsatlas_label[right_MA[0].arraydata()[iter_vert]]][0][2:]] + except: + pass + + try: + if right_MA[0].arraydata()[iter_vert] == 0: + textnowRight.append(-4) + else: + if full_data[orderTexture[i]][i_parcels_stimulated].keys()[0].startswith('i_') or full_data[orderTexture[i]][i_parcels_stimulated].keys()[0].startswith('c_'): + if full_data[orderTexture[i]][i_parcels_stimulated]['i_'+actual_marsatlas_parcels[0]] == 'NaN': + textnowRight.append(-4) + else: + textnowRight.append(float(full_data[orderTexture[i]][i_parcels_stimulated]['i_'+actual_marsatlas_parcels[0]])) + else: + if full_data[orderTexture[i]][i_parcels_stimulated][actual_marsatlas_parcels[0]] == 'NaN': + textnowRight.append(-4) + else: + textnowRight.append(float(full_data[orderTexture[i]][i_parcels_stimulated][actual_marsatlas_parcels[0]])) + + except: + textnowRight.append(-4) + #pdb.set_trace() + + + aims.write(new_TimeSurfTextLeft,str(path_to_save) + os.path.sep + 'Texture' + os.path.sep + ('%s_left.gii')%i_parcels_stimulated) + aims.write(new_TimeSurfTextRight,str(path_to_save) + os.path.sep + 'Texture' + os.path.sep + ('%s_right.gii')%i_parcels_stimulated) + + else: + print(('No Data for %s')%i_parcels_stimulated) + + obj1 = self.a.loadObject('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/Gre_2016_MNI1_Lwhite.gii') + obj2 = self.a.loadObject('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_Lwhite_parcels_marsAtlas.gii') + obj1.loadReferentialFromHeader() + obj2.setPalette(palette = 'marsatlas') + MarsAtlas_fusion_obj = self.a.fusionObjects([obj1, obj2], method='FusionTexSurfMethod') + self.a.addObjects(MarsAtlas_fusion_obj,self.axWindow) + self.currentImage = [obj1,obj2] + + + if full_data['Atlas'] == 'Brodmann': + voxel_size_T1 = [BrodmannParcels.getVoxelSize()[0], BrodmannParcels.getVoxelSize()[1], BrodmannParcels.getVoxelSize()[2], 1.0] + sizeOutputnii = BrodmannParcels.getSize().list() + sizeOutputnii[-1] = len(orderTexture.keys()) + + for i_parcels_stimulated in full_data[orderTexture[0]].keys(): + #di.setMinf('ColorPalette','Blue-Red-fusion') + volToGenerate = aims.Volume(*sizeOutputnii,dtype = 'float') + volToGenerate.header()['voxel_size']=voxel_size_T1 + volToGenerate.fill(-4) + + for i_texture in orderTexture.keys(): + + for i_parcels_result in full_data[orderTexture[i_texture]][i_parcels_stimulated].keys(): + #fait chier le droite gauche + if full_data[orderTexture[0]][i_parcels_stimulated][i_parcels_result]=='NaN': + volToGenerate.arraydata()[numpy.where(BrodmannParcelsArrayData==float(i_parcels_result))]=-4 + else: + volToGenerate.arraydata()[numpy.where(BrodmannParcelsArrayData==float(i_parcels_result))]=full_data[orderTexture[i_texture]][i_parcels_stimulated][i_parcels_result] + + aims.write(volToGenerate,str(path_to_save)+os.path.sep+'%s.nii'%(str(int(float(i_parcels_stimulated))))) + + + print("done") + pdb.set_trace() + #try: + # self.a.removeObjects([self.currentImage,],self.windows) + #except: + # pass + + + ##self.displayCombo.addItems([os.path.split(str(fichier))[1]]) + #obj3 = self.a.loadObject(str(path_to_save) + os.path.sep + 'left_white_multipletime.gii') + #obj4 = self.a.loadObject(str(path_to_save) + os.path.sep + 'Texture' + os.path.sep + ('%s_left.gii')%i_parcels_stimulated) + #obj3.loadReferentialFromHeader() + #obj4.setPalette(palette = 'Blue-Red-fusion') + #FunctioTracto_fusion_obj = self.a.fusionObjects([obj3,obj4],method='FusionTexSurfMethod') + #self.a.addObjects(FunctioTracto_fusion_obj,self.sagWindow) + + + + + #pdb.set_trace() + #self.displayCombo.addItems([os.path.split(str(fichier))[1]]) + + #textureContacts = aims.TimeTexture() + + def doubleClickedFunctionalTractography(self): + + pdb.set_trace() + + + def generateStatisticsContacts(self): + + #get selected contacts + current = [str(self.selectionList.item(i).text()) for i in xrange(self.selectionList.count())] + + #il me faut un dictionnaire avec toutes les parcels mars atlas et un dictionnaire avec toutes les parcels freesurfer possible. + dict_marsatlas = {} + dict_freesurfer = {} + dict_dispersion_MA = {} + dict_dispersion_FS = {} + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + freesurfer_parcel_names = readFreesurferLabelFile('freesurfer_label.txt') + missing_marsatlas = [] + missing_freesurfer = [] + all_patients = [] + dict_MNI_PatientName = {} + + for ii in parcels_names.values(): + dict_marsatlas.update({ii:[]}) + dict_dispersion_MA.update({ii:{}}) + + + for ii in freesurfer_parcel_names.values(): + dict_freesurfer.update({ii[0]:[]}) + dict_dispersion_FS.update({ii[0]:{}}) + + #je parcours toutes les "current", je regarde leur parcels et j'ajoute la position mni à la list de cette parcels. + for ii in current: + (sub, elec, plot) = self.plotNameFromFullPlotName(ii) + dataplot = self.plotDataFromFullName(ii) + if 'MarsAtlas' in dataplot['label'].keys(): + if dataplot['label']['MarsAtlas'][1] != u'not in a mars atlas parcel': + dict_marsatlas[dataplot['label']['MarsAtlas'][1]].append(dataplot['MNI']) + else: + #signaler que certains patients n'ont pas marsatlas de généré et que ça va "fausser" les résultats + #print("plot %s without marsAtlas parcellation estimated"%(ii)) + if sub not in missing_marsatlas: + missing_marsatlas.append(sub) + if 'Freesurfer' in dataplot['label'].keys(): + if dataplot['label']['Freesurfer'][1] != u'not in a freesurfer parcel': + try: + dict_freesurfer[dataplot['label']['Freesurfer'][1]].append(dataplot['MNI']) + except: + print sub + print "probleme avec ce patient" + pass + else: + #signaler que certains patient n'ont pas freesurfer de généré et que ça va "fausser" les résultats + #print("plot %s without FreeSurfer parcellation estimated"%(ii)) + if sub not in missing_freesurfer: + missing_freesurfer.append(sub) + if sub not in all_patients: + all_patients.append(sub) + dict_MNI_PatientName.update({str(dataplot['MNI']):sub}) + + #now I calculate the dispersion per parcels: (and I'ld like to normalized it but don't know how) + for iter_MA in dict_marsatlas.keys(): + points_array = numpy.array(dict_marsatlas[iter_MA]) + #array_median = repmat(numpy.median(points_array,axis=0),len(points_array),1) + #diff = points_array - array_median + #list_dist_median = sc_sp.distance.cdist([numpy.median(points_array,axis=0)],points_array) + if len(points_array)>1: + dict_dispersion_MA[iter_MA].update({'nb contact':len(dict_marsatlas[iter_MA]),'average point':numpy.mean(points_array,axis=0),'median point':numpy.median(points_array,axis=0)}) + found_outlier = self.is_outlier(points_array,thresh = 3) + pos_outlier = numpy.where(found_outlier==True) + if len(pos_outlier[0]) == 0: + dict_dispersion_MA[iter_MA].update({'outlier position':None}) + else: + #[dict_MNI_PatientName[str(points_array[pos_outlier[0]][i].tolist())] for i in range(len(points_array[pos_outlier[0]]))] + dict_dispersion_MA[iter_MA].update({'outlier position':points_array[pos_outlier[0]]}) + dict_dispersion_MA[iter_MA].update({'outlier name':[dict_MNI_PatientName[str(points_array[pos_outlier[0]][i].tolist())] for i in range(len(points_array[pos_outlier[0]]))]}) + elif len(points_array)==1: + dict_dispersion_MA[iter_MA].update({'nb contact': 1,'average point':numpy.mean(points_array,axis=0),'median point':numpy.median(points_array,axis=0)}) + else: + dict_dispersion_MA[iter_MA].update({'nb contact': 0}) + + + for iter_FS in dict_freesurfer.keys(): + points_array = numpy.array(dict_freesurfer[iter_FS]) + #array_median = repmat(numpy.median(points_array,axis=0),len(points_array),1) + #diff = points_array - array_median + #list_dist_median = sc_sp.distance.cdist([numpy.median(points_array,axis=0)],points_array) + if len(points_array)>1: + dict_dispersion_FS[iter_FS].update({'nb contact':len(dict_freesurfer[iter_FS]),'average point':numpy.mean(points_array,axis=0),'median point':numpy.median(points_array,axis=0)}) + found_outlier = self.is_outlier(points_array,thresh = 3) + pos_outlier = numpy.where(found_outlier==True) + if len(pos_outlier[0]) == 0: + dict_dispersion_FS[iter_FS].update({'outlier position':None}) + else: + dict_dispersion_FS[iter_FS].update({'outlier position':points_array[pos_outlier[0]]}) + dict_dispersion_FS[iter_FS].update({'outlier name':[dict_MNI_PatientName[str(points_array[pos_outlier[0]][i].tolist())] for i in range(len(points_array[pos_outlier[0]]))]}) + elif len(points_array)==1: + dict_dispersion_FS[iter_FS].update({'nb contact':1,'average point':numpy.mean(points_array,axis=0),'median point':numpy.median(points_array,axis=0)}) + else: + dict_dispersion_FS[iter_FS].update({'nb contact':0}) + + #ecrire le tout dans un csv + fileName = QtGui.QFileDialog.getSaveFileName(self, 'Dialog Title', '/', '*.csv') #str(QtGui.QFileDialog.getExistingDirectory(self, "Select Directory")) + fileName=str(fileName) + testcsv = fileName.split('.') + if len(testcsv)>0: + if testcsv[1] != 'csv': + print("error, the extension should be .csv") + return + else: + fileName = fileName + '.csv' + + with open(fileName, 'w') as csvfile: + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Group Analysis']) + listwrite_allpatients = [u'Patients'] + for ii in all_patients: + listwrite_allpatients.append(ii) + writer.writerow(listwrite_allpatients) #writer.writerow([u'Patients',all_patients]) + listwrite_missingMA = [u'missing marsAtlas info for the following patients (analysis done without their data):'] + for ii in missing_marsatlas: + listwrite_missingMA.append(ii) + writer.writerow(listwrite_missingMA)#writer.writerow([u'missing marsAtlas info for the following patients (analysis done without their data):',missing_marsatlas]) + listwrite_missingFS = [u'missing FreeSurfer info for the following patients (analysis done without their data):'] + for ii in missing_freesurfer: + listwrite_missingFS.append(ii) + writer.writerow(listwrite_missingFS) + #writer.writerow([u'missing FreeSurfer info for the following patients (analysis done without their data):',missing_freesurfer]) + writer.writerow([u'MarsAtlas parcellation analysis']) + writer.writerow([u'parcel name',u'nb contact', u'average point', u'median point', u'outliers positions',u'patient names of the outliers']) + + dictMA_sorted_tmp = OrderedDict(sorted(dict_dispersion_MA.items())) + for kk,vv in dictMA_sorted_tmp.iteritems(): + if vv['nb contact']>0: + listwrite = [kk] + listwrite.append(vv['nb contact']) + if 'average point' in vv.keys(): + listwrite.append([float(format(vv['average point'][i],'.3f')) for i in range(3)]) + listwrite.append([float(format(vv['median point'][i],'.3f')) for i in range(3)]) + if 'outlier position' in vv.keys(): + if vv['outlier position'] is not None: + listwrite.append(vv['outlier position']) + listwrite.append(vv['outlier name']) + writer.writerow(listwrite) + + #writer.writerow(dict_dispersion_MA) + writer.writerow([]) + writer.writerow([u'Freesurfer parcellation analysis']) + writer.writerow([u'parcel name',u'nb contact', u'average point', u'median point', u'outliers positions',u'patient names of the outliers']) + dictFS_sorted_tmp = OrderedDict(sorted(dict_dispersion_FS.items())) + for kk,vv in dictFS_sorted_tmp.iteritems(): + if vv['nb contact']>0: + listwrite = [kk] + listwrite.append(vv['nb contact']) + if 'average point' in vv.keys(): + listwrite.append([float(format(vv['average point'][i],'.3f')) for i in range(3)]) + listwrite.append([float(format(vv['median point'][i],'.3f')) for i in range(3)]) + if 'outlier position' in vv.keys(): + if vv['outlier position'] is not None: + listwrite.append(vv['outlier position']) + listwrite.append(vv['outlier name']) + writer.writerow(listwrite) + + print("csv done") + + def is_outlier(self,list_points, thresh=3): + + #to be changed to the MAD + if len(list_points.shape) == 1: + list_points = list_points[:,None] + median = numpy.median(list_points, axis=0) + diff = numpy.sum((list_points - median)**2, axis=-1) + diff = numpy.sqrt(diff) + med_abs_deviation = numpy.median(diff) + + modified_z_score = 0.6745 * diff / med_abs_deviation + + return modified_z_score > thresh + + def AddMAparcels2selection(self): + + print "select contacts according to marsatlas parcels" + fullPlot_List = [str(self.plotList.item(idx).text()) for idx in range(self.plotList.count())] + + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + + dict_plotMA = {} + for ii in parcels_names.values(): + dict_plotMA.update({ii:[]}) + + for ii in fullPlot_List: + (sub, elec, plot) = self.plotNameFromFullPlotName(ii) + dataplot = self.plotDataFromFullName(ii) + if 'MarsAtlas' in dataplot['label'].keys(): + if dataplot['label']['MarsAtlas'][1] != u'not in a mars atlas parcel': + dict_plotMA[dataplot['label']['MarsAtlas'][1]].append(ii) + + if str(self.AddMAparcels2SelectioncomboBox.currentText()) =='*': + print('unselect all') + for i in xrange(self.plotList.count()): + selec = False + self.plotList.item(i).setSelected(selec) + else: + list_plot2select= dict_plotMA[str(self.AddMAparcels2SelectioncomboBox.currentText())] + for i in xrange(self.plotList.count()): + selec = False + if str(self.plotList.item(i).text()) in list_plot2select: + selec = True + self.plotList.item(i).setSelected(selec) + + + def changeBothRightDisplay(self): + + all_items=[str(self.selectionList.item(i).text()) for i in range(self.selectionList.count())] + refBothHemi = self.template.referentialAnatomist + newRef = self.a.createReferential() + + transf = self.a.createTransformation([0,0,0,-1,0,0,0,1,0,0,0,1], origin = newRef, destination = refBothHemi) + meshesLeft = [] + for ii in all_items: + MNI_pos = self.plotDataFromFullName(ii)['MNI'] + + if MNI_pos[0] >=0: + #on fait classique + pass + elif MNI_pos[0] < 0: + + if self.radioButtonbothHemi.isChecked(): + meshesLeft.append(ii) + self.a.assignReferential(refBothHemi,self.meshes[ii]) + + + elif self.radioButtonAllRight.isChecked(): + meshesLeft.append(ii) + pdb.set_trace() + self.a.assignReferential(newRef,self.meshes[ii]) + + #self.a.assignReferential(newRef,meshesLeft) + + + #to_remove = [] + #for ii in all_items: + #MNI_pos = self.plotDataFromFullName(ii)['MNI'] + + #if side == 'Left': + #if MNI_pos[0] >= 0: + #to_remove.append(ii) + #elif side == 'Right': + #if MNI_pos[0] <=0: + #to_remove.append(ii) + + #meshes = [self.meshes[r] for r in to_remove if r in self.meshes] + #for r in to_remove: + #if r in self.meshes: + #del self.meshes[r] + + #self.a.removeObjects(meshes,self.windows) + #self.a.deleteObjects(meshes) + + + def contactSEEGDisplay(self): + + if self.radioButtonContactDisplay.isChecked(): + pdb.set_trace() + try: + self.bipoleSEEGColors.close() + except: + pass + self.a.removeObjects([self.bipolesmeshes[x] for x in self.bipolesmeshes.keys()],self.windows) + #current = [str(self.selectionList.item(i).text()) for i in xrange(self.selectionList.count())] # FIXME pas juste les selected ! Tous les items + #new = [str(s.text()) for s in self.plotList.selectedItems() if str(s.text()) not in current] + + ## Display the new ones + #meshes = [] + #invalid = set() + #for n in new: + #if self.template.name in self.plotDataFromFullName(n): + #mesh = self.displaySphereAt(self.plotDataFromFullName(n)[self.template.name], self.plotDiameter(), self.template.referentialAnatomist, color=(0.0,0.9,0.1,1.0),name = n) + #self.meshes[n] = mesh + #meshes.append(mesh) + #else: + #invalid.add(n) # If there, coordinates are not available in the right template referential + #if len(invalid) > 0: + #print "Some plots were not added to the selection, because normalized coordinates were not available for them" + #new = list(set(new) - invalid) + #self.selectionList.addItems(new) + + self.a.addObjects([self.meshes[x] for x in self.meshes.keys()], self.windows) + + + elif self.radioButtonsEEGResults.isChecked(): + + meshes = [self.meshes[x] for x in self.meshes.keys()] + + #for ind_mesh in self.meshes.keys(): + #del self.meshes[ind_mesh] + self.a.removeObjects(meshes,self.windows) + #self.a.deleteObjects(meshes) + + + #il faut générer les bipoles + current = [str(self.selectionList.item(i).text()) for i in xrange(self.selectionList.count())] + info_contact={} + for pindex in range(0,len(current)): + (sub, elec, plot) = self.plotNameFromFullPlotName(current[pindex]) + try: + if sub not in info_contact.keys(): + info_contact.update({sub:[]}) + info_contact[sub].append(elec+"%02d"%int(plot.split('Plot')[1])) + else: + info_contact[sub].append(elec+"%02d"%int(plot.split('Plot')[1])) + except: + pdb.set_trace() + info_bipole = {} + for subj in info_contact.keys(): + + contacts_sorted = sorted(info_contact[subj],key=natural_keys) + if subj not in info_bipole.keys(): + info_bipole.update({subj:{}}) + for contact_index in range(1,len(contacts_sorted)): + previous_contact = "".join([i for i in contacts_sorted[contact_index-1] if not i.isdigit()]) + previous_number = "".join([i for i in contacts_sorted[contact_index-1] if i.isdigit()]) + current_contact = "".join([i for i in contacts_sorted[contact_index] if not i.isdigit()]) + current_number = "".join([i for i in contacts_sorted[contact_index] if i.isdigit()]) + + if previous_contact == current_contact: + if int(current_number) - int(previous_number) == 1: + bipole = contacts_sorted[contact_index] + ' - ' + contacts_sorted[contact_index-1] + mni_bipole = ((numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(current_number))]['MNI']) + numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(previous_number))]['MNI']))/2).tolist() + info_bipole[subj].update({bipole:mni_bipole}) + else: + #find previous contact + previous_number = int(current_number)-1 + next_number = int(current_number)+1 + bipole_with_previous = contacts_sorted[contact_index] + ' - ' + "%s%02d"%(current_contact,int(previous_number)) + bipole_wiht_next = "%s%02d"%(current_contact,int(next_number)) + ' - ' + contacts_sorted[contact_index] + if 'Plot'+str(previous_number) in self.plotsData[subj][current_contact].keys(): + if bipole_with_previous not in info_bipole[subj].keys(): + mni_bipole = ((numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(current_number))]['MNI']) + numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(previous_number))]['MNI']))/2).tolist() + info_bipole[subj].update({bipole_with_previous:mni_bipole}) + + if 'Plot'+str(next_number) in self.plotsData[subj][current_contact].keys(): + if bipole_wiht_next not in self.plotsData[subj][current_contact].keys(): + mni_bipole = ((numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(current_number))]['MNI']) + numpy.array(self.plotsData[subj][current_contact]['Plot'+str(int(next_number))]['MNI']))/2).tolist() + info_bipole[subj].update({bipole_wiht_next:mni_bipole}) + + + list_to_show = [] + for subj in info_bipole.keys(): + if 'seeg_label_all' in self.testDataSubjects[subj].keys(): + + for index_bip in info_bipole[subj].keys(): + + rdiEM = ReadDiskItem('Electrode Model', 'Electrode Model format') + listEM = list(rdiEM.findValues({},None,False)) + matches = filter((lambda x: u"bipole" in str(x)), listEM) + if subj + ' : ' + index_bip not in self.bipolesmeshes.keys(): + #la faudrait que je vérifie si le bipole existe vraiment parce que sinon je crée énormément de mesh pour rien ... + mesh = self.displaySphereAt(info_bipole[subj][index_bip],self.plotDiameter(), self.template.referentialAnatomist, color=(0.0,0.0,0.0,0.0),name = subj + ' : ' + index_bip) #je devrais sortir le color de la ? + mesh.setMaterial(front_face='counterclockwise') + self.bipolesmeshes.update({subj + ' : ' + index_bip:mesh}) + list_to_show.append(subj + ' : ' + index_bip) + + #else: + #print "No SEEG stim results" + #QtGui.QMessageBox.warning(self, "Error", "Stim report has not been generated for the subject: {}".format(subj)) + + + self.a.addObjects([self.bipolesmeshes[x] for x in list_to_show], self.windows) + + self.bipoleSEEGColors=bipoleSEEGColors(self,indv_pat = False, group_subsample = list_to_show) + self.bipoleSEEGColors.show() + #removable = [str(s.text()) for s in self.selectionList.selectedItems()] + #meshes = [self.meshes[r] for r in removable if r in self.meshes] + #for r in removable: + #if r in self.meshes: + #del self.meshes[r] + #self.a.removeObjects(meshes, self.windows) + #self.a.deleteObjects(meshes) + + +if __name__ == "__main__": + app = QtGui.QApplication(sys.argv) + axon.initializeProcesses() + from brainvisa.data.readdiskitem import ReadDiskItem + from brainvisa.data.writediskitem import WriteDiskItem + window = ElectrodeDisplayWidget() + window.show() + sys.exit(app.exec_()) diff --git a/epilepsie-electrodes.ui b/epilepsie-electrodes.ui new file mode 100644 index 0000000..4bc2b61 --- /dev/null +++ b/epilepsie-electrodes.ui @@ -0,0 +1,759 @@ + + + EpilepsieElectrodes + + + + 0 + 0 + 1167 + 888 + + + + + 0 + 0 + + + + Dialog + + + + + + Qt::Horizontal + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + Load Patient + + + false + + + + + + + Change Patient + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Image Manipulation + + + + QLayout::SetMinimumSize + + + + + make the fusion of both displayed images and shows it on the right window + + + Fusion displayed images + + + + + + + + + Generate Resection Image + + + + + + + convert ROI to Resection + + + + + + + + + + + Delete MarsAtlas + + + + + + + Generate SEEG Projection Mesh + + + + + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Electrodes + + + + QLayout::SetMinimumSize + + + + + Import theoritical implantation (rosa) + + + + + + + Apply DEETO + + + + + + + + + + 0 + 0 + + + + + 20 + 100 + + + + Ajouter une électrode + + + + + + + false + + + + + + + + 0 + 0 + + + + + 20 + 100 + + + + Supprimer l'électrode courante + + + - + + + false + + + + + + + + 0 + 0 + + + + Name (no digit in the name): + + + + + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + + + + Type + + + + + + + + + + + + + + ArrowCursor + + + Fixer la position de l'extrémité de l'électrode courante + + + Target + + + false + + + + + + + Fixer la position du point d'entrée de l'électrode courante + + + Entrance + + + false + + + + + + + + + + 0 + 2 + + + + Liste des électrodes + + + + + + + + 0 + 4 + + + + Liste des contacts + + + QAbstractItemView::SingleSelection + + + + + + + + 75 + true + + + + Enregistrer l'implantation du patient dans la base de données + + + Save + + + false + + + + + + + QLayout::SetMinimumSize + + + + + Importer une implantation (format PTS, elecimplant...) + + + Import + + + false + + + + + + + Exporter les coordonnées des plots au format PTS et TXT dans le référentiel T1 et MNI + + + Normalize/Export + + + false + + + + + + + + Generate All Dictionaries + + + + + Mars Atlas Contact Position + + + + + Mars Atlas Resection Position + + + + + Export to csv file + + + + + Generate mapping contact - hemi mesh + + + + + Generate Bipole Stimulation excel file + + + + + Generate screenshot + + + + + Generate MP4 + + + + + Compute parcel metrics + + + + + Generate Fiber Contact Distance + + + + + + + + + + + + + + 50 + false + + + + + + + + + + + + false + + + + 10 + true + + + + sEEG Colors + + + false + + + + + + + + 0 + 0 + + + + Mode d'affichage des électrodes + + + + Realistic Display + + + + + 1 mm sphere Display + + + + + 2 mm sphere Display + + + + + 5 mm sphere Display + + + + + Hide Electrodes + + + + + show SEEG Results + + + + + + + + true + + + afficher seulement les élements à +/- 5 mm de la slice actuelle + + + Clipping + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Electrode Referential + + + + + + + -180 + + + 180 + + + true + + + Qt::Horizontal + + + false + + + + + + + + + + + + + + Référentiel utilisé pour les coordonnées affichées ci-contre + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + IRM pre + + + + + IRM pre + hemisphere droit + + + + + IRM pre + hemisphere gauche + + + + + IRM pre + hemispheres + + + + + IRM post + + + + + IRM post-op + + + + + + + + + 0 + 0 + + + + + + + + + + QLayout::SetMaximumSize + + + + + + 0 + 0 + + + + + IRM pre + + + + + IRM pre + hemisphere droit + + + + + IRM pre + hemisphere gauche + + + + + IRM pre + hemispheres + + + + + IRM post + + + + + IRM post-op + + + + + + + + + 0 + 0 + + + + + + + + + + + + + patientList + addElectrodeButton + removeElectrodeButton + nameEdit + typeComboBox + targetButton + entryButton + electrodeList + contactList + electrodeSaveButton + electrodeLoadButton + colorConfigButton + dispModeCombo + electrodeRefCheck + electrodeRefRotationSlider + referentialCombo + windowCombo1 + windowCombo2 + + + + diff --git a/externalprocesses.py b/externalprocesses.py new file mode 100644 index 0000000..d9e9e62 --- /dev/null +++ b/externalprocesses.py @@ -0,0 +1,186 @@ +# -*- coding: utf-8 -*- +# +# +# Library for running matlab commands and external shell commands in blocking and non-blocking ways. +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# License GNU GPL v3 +# + +# TODO : redo using QRunnable instead of QThread with QThreadPool.globalInstancer().start(myRunnable) + +import subprocess, os, types, tempfile, time, random, string,sys +from PyQt4 import QtCore +import pdb + + +# Set the environment for external commands without BrainVisa interference (remove brainvisa-specific paths) +myEnv = os.environ.copy() +for var in myEnv.keys(): + if var.find('BRAINVISA_UNENV_') >= 0: + realvar = var.split('BRAINVISA_UNENV_')[1] + print "On remplace %s par %s"%(realvar, var) + myEnv[realvar] = myEnv[var] + del myEnv[var] + +# Base call for matlab +matlabCall = ['matlab', '-nosplash', '-nodisplay','-r'] #essayer sans le -nojvm + + +def getTmpFilePath(extension='txt'): + """ + Generate a random file name in a temp directory + + file extension (txt by default) can be given as argument + Usage : filepath = getTmpFilePath('jpg') + """ + tmpdir = tempfile.gettempdir() + tmpCmd = ''.join(random.choice(string.letters) for i in xrange(15)) + tmpfile = tmpCmd + '.' + extension + #print "TMPdir : %s, filename : %s"%(repr(tmpdir), repr(tmpfile)) + fullpath = os.path.join(tmpdir, tmpfile) + return fullpath + +class Executor(QtCore.QThread): + """ This class executes a shell command in a thread. + The Executor object must NOT be destroyed until the execution is complete. + Parameters include : + :param commandList (for example ['cat', '/tmp/file1', '/tmp/file2'] + :param parent a parent for the QThread (None by default) + :param objectsToKeep : objets to keep in the Executor object until the end of execution + :param exitFunc : a callback function that will be called at the end of the command execution + + As this is a QThread object, the object is created, then the non-blocking start() function must be called to start the thread. + Do NOT call directly the run() function + """ + def __init__(self, commandList, parent=None, objectsToKeep=None, exitFunc=None): + QtCore.QThread.__init__(self,parent) + self.commandList = commandList + self.objectsToKeep = objectsToKeep + self.exitFunc = exitFunc + + def run(self): + """ + Reimplementation of the run function of the QThread. + This SHOULD NOT BE CALLED DIRECTLY as it would run in the current thread. + Run self.start() to start the execution in a separate thread + """ + #pdb.set_trace() + #self.emit(QtCore.SIGNAL("Started( QString )"),'Command started') + print "######## Calling process in a QThread ####"+' '.join(self.commandList)+"\n\n\n" + try: + lines = subprocess.Popen(self.commandList, stdout=subprocess.PIPE, env = myEnv).communicate()[0].splitlines() + except: + print "Erreur lors de l'exécution de la commande : ", sys.exc_info()[0] + #pdb.set_trace() + if self.exitFunc: + self.exitFunc() + print "QThread finished" + print "*****************LINES"+repr(lines)+"\n\n\n" + #self.emit(QtCore.SIGNAL("Finished( QStringList )"),lines) + + +class PythonExecutor(QtCore.QThread): + """ This class executes a python function with no arguments (can be created with 'lambda(x=myXvalue,y=myYvalue) : myFunc(x,y)') in a thread. + The object must NOT be destroyed until the execution is complete. + After creation, call the start() function to start the execution in a separate thread. + """ + def __init__(self, func, toKeep = None, parent=None): + """:param func : The function that will be run in a separate thread + :param parent : a parent object for the QThread (default is None) + :param toKeep : object or dictionnary or list of objects to keep a reference to. + """ + QtCore.QThread.__init__(self,parent) + self.func = func + self.out = None + self.toKeep = toKeep + + def output(self): + """ Returns the output value of the function when execution is terminated""" + return self.out + + def kept(self): + return self.toKeep + + def run(self): + """ + Reimplementation of the run function of the QThread. + This SHOULD NOT BE CALLED DIRECTLY as it would run in the current thread. + Run self.start() to start the execution in a separate thread + """ + #self.emit(QtCore.SIGNAL("Started( QString )"),'Command started') + self.out = self.func() + #print "*****************OUTPUT"+repr(out)+"\n\n\n" + +def matlabIsPresent(): + """ + Check if the 'matlab' command is available in the path, by running a very small matlab command + Returns True or False + """ + try: + result = subprocess.Popen(matlabCall+['quit;',], stdout=subprocess.PIPE, env = myEnv).communicate()[0].splitlines() + except OSError: + print "matlab is not present : OSError" + return False + except: + print "matlab is not present or fails !" + return False + return True + +def matlabRun(cmd): + """ + Runs the provided matlab code and returns the stdoutput + The call is blocking until command completion. + Use matlabRunNB to get non-blocking command execution + """ + if not isinstance(cmd, types.ListType): + cmd = [cmd,] + # Because the command may be too long for a command line, let's put it in a temp file and run the file + tmpdir = tempfile.gettempdir() + tmpCmd = ''.join(random.choice(string.letters) for i in xrange(15)) + tmpfile = tmpCmd + '.m' + #print "TMPdir : %s, filename : %s"%(repr(tmpdir), repr(tmpfile)) + fullpath = os.path.join(tmpdir, tmpfile) + # os.path.join(tempfile.tempdir,''.join(random.choice(string.letters) for i in xrange(15))+'.m') + f = open(fullpath, 'w') + f.write(' '.join(cmd) + "\n\n") + f.close() + print "Calling matlab in "+tmpdir+" with file "+tmpfile+ " and matlab command : "+repr(matlabCall) + cmd = ["cd '%s';%s"%(tmpdir,tmpCmd),] + result = subprocess.Popen(matlabCall+cmd, stdout=subprocess.PIPE, env = myEnv).communicate()[0].splitlines() + #pdb.set_trace() + os.remove(fullpath) + return result + +def matlabRunNB(cmd, callback = None): + """ Returns a QThread object that can launch the matlab command by calling its start() function. + This allows to run a matlab command without blocking the rest of the program. + A "Finished( QStringList )" Qt signal is emitted when matlab exits. + :param callback is a callback function that will be called at the end of the execution + """ + cmd = [cmd,] + # Because the command may be too long for a command line, let's put it in a temp file and run the file + tmpdir = tempfile.gettempdir() + tmpCmd = ''.join(random.choice(string.letters) for i in xrange(15)) + tmpfile = tmpCmd + '.m' + #print "TMPdir : %s, filename : %s"%(repr(tmpdir), repr(tmpfile)) + fullpath = os.path.join(tmpdir, tmpfile) + # os.path.join(tempfile.tempdir,''.join(random.choice(string.letters) for i in xrange(15))+'.m') + f = open(fullpath, 'w') + f.write(' '.join(cmd) + "\n\n") + f.close() + print "Calling matlab in "+tmpdir+" with file "+tmpfile+ " and matlab command : "+repr(matlabCall) + cmd = ["cd '%s';%s"%(tmpdir,tmpCmd),] + # Create callback function : destroy temporary file and call the provided callback function + if callback is None: + cb = lambda:os.remove(fullpath) + else: + def cb(): + os.remove(fullpath) + callback() + #pdb.set_trace() + return Executor(matlabCall+cmd, objectsToKeep=f, exitFunc = cb) + +def runCmd(cmd): + """ Executes a command and returns the output as an array of strings (the output lines)""" + return subprocess.Popen(cmd, stdout=subprocess.PIPE, env = myEnv).communicate()[0].splitlines() diff --git a/freesurfer_label.txt b/freesurfer_label.txt new file mode 100644 index 0000000..1e8813b --- /dev/null +++ b/freesurfer_label.txt @@ -0,0 +1,1294 @@ +0 Unknown 0 0 0 0 +1 Left-Cerebral-Exterior 70 130 180 0 +2 Left-Cerebral-White-Matter 245 245 245 0 +3 Left-Cerebral-Cortex 205 62 78 0 +4 Left-Lateral-Ventricle 120 18 134 0 +5 Left-Inf-Lat-Vent 196 58 250 0 +6 Left-Cerebellum-Exterior 0 148 0 0 +7 Left-Cerebellum-White-Matter 220 248 164 0 +8 Left-Cerebellum-Cortex 230 148 34 0 +9 Left-Thalamus 0 118 14 0 +10 Left-Thalamus-Proper 0 118 14 0 +11 Left-Caudate 122 186 220 0 +12 Left-Putamen 236 13 176 0 +13 Left-Pallidum 12 48 255 0 +14 3rd-Ventricle 204 182 142 0 +15 4th-Ventricle 42 204 164 0 +16 Brain-Stem 119 159 176 0 +17 Left-Hippocampus 220 216 20 0 +18 Left-Amygdala 103 255 255 0 +19 Left-Insula 80 196 98 0 +20 Left-Operculum 60 58 210 0 +21 Line-1 60 58 210 0 +22 Line-2 60 58 210 0 +23 Line-3 60 58 210 0 +24 CSF 60 60 60 0 +25 Left-Lesion 255 165 0 0 +26 Left-Accumbens-area 255 165 0 0 +27 Left-Substancia-Nigra 0 255 127 0 +28 Left-VentralDC 165 42 42 0 +29 Left-undetermined 135 206 235 0 +30 Left-vessel 160 32 240 0 +31 Left-choroid-plexus 0 200 200 0 +32 Left-F3orb 100 50 100 0 +33 Left-lOg 135 50 74 0 +34 Left-aOg 122 135 50 0 +35 Left-mOg 51 50 135 0 +36 Left-pOg 74 155 60 0 +37 Left-Stellate 120 62 43 0 +38 Left-Porg 74 155 60 0 +39 Left-Aorg 122 135 50 0 +40 Right-Cerebral-Exterior 70 130 180 0 +41 Right-Cerebral-White-Matter 245 245 245 0 +42 Right-Cerebral-Cortex 205 62 78 0 +43 Right-Lateral-Ventricle 120 18 134 0 +44 Right-Inf-Lat-Vent 196 58 250 0 +45 Right-Cerebellum-Exterior 0 148 0 0 +46 Right-Cerebellum-White-Matter 220 248 164 0 +47 Right-Cerebellum-Cortex 230 148 34 0 +48 Right-Thalamus 0 118 14 0 +49 Right-Thalamus-Proper 0 118 14 0 +50 Right-Caudate 122 186 220 0 +51 Right-Putamen 236 13 176 0 +52 Right-Pallidum 13 48 255 0 +53 Right-Hippocampus 220 216 20 0 +54 Right-Amygdala 103 255 255 0 +55 Right-Insula 80 196 98 0 +56 Right-Operculum 60 58 210 0 +57 Right-Lesion 255 165 0 0 +58 Right-Accumbens-area 255 165 0 0 +59 Right-Substancia-Nigra 0 255 127 0 +60 Right-VentralDC 165 42 42 0 +61 Right-undetermined 135 206 235 0 +62 Right-vessel 160 32 240 0 +63 Right-choroid-plexus 0 200 221 0 +64 Right-F3orb 100 50 100 0 +65 Right-lOg 135 50 74 0 +66 Right-aOg 122 135 50 0 +67 Right-mOg 51 50 135 0 +68 Right-pOg 74 155 60 0 +69 Right-Stellate 120 62 43 0 +70 Right-Porg 74 155 60 0 +71 Right-Aorg 122 135 50 0 +72 5th-Ventricle 120 190 150 0 +73 Left-Interior 122 135 50 0 +74 Right-Interior 122 135 50 0 +77 WM-hypointensities 200 70 255 0 +78 Left-WM-hypointensities 255 148 10 0 +79 Right-WM-hypointensities 255 148 10 0 +80 non-WM-hypointensities 164 108 226 0 +81 Left-non-WM-hypointensities 164 108 226 0 +82 Right-non-WM-hypointensities 164 108 226 0 +83 Left-F1 255 218 185 0 +84 Right-F1 255 218 185 0 +85 Optic-Chiasm 234 169 30 0 +192 Corpus_Callosum 250 255 50 0 +86 Left_future_WMSA 200 120 255 0 +87 Right_future_WMSA 200 121 255 0 +88 future_WMSA 200 122 255 0 +96 Left-Amygdala-Anterior 205 10 125 0 +97 Right-Amygdala-Anterior 205 10 125 0 +98 Dura 160 32 240 0 +100 Left-wm-intensity-abnormality 124 140 178 0 +101 Left-caudate-intensity-abnormality 125 140 178 0 +102 Left-putamen-intensity-abnormality 126 140 178 0 +103 Left-accumbens-intensity-abnormality 127 140 178 0 +104 Left-pallidum-intensity-abnormality 124 141 178 0 +105 Left-amygdala-intensity-abnormality 124 142 178 0 +106 Left-hippocampus-intensity-abnormality 124 143 178 0 +107 Left-thalamus-intensity-abnormality 124 144 178 0 +108 Left-VDC-intensity-abnormality 124 140 179 0 +109 Right-wm-intensity-abnormality 124 140 178 0 +110 Right-caudate-intensity-abnormality 125 140 178 0 +111 Right-putamen-intensity-abnormality 126 140 178 0 +112 Right-accumbens-intensity-abnormality 127 140 178 0 +113 Right-pallidum-intensity-abnormality 124 141 178 0 +114 Right-amygdala-intensity-abnormality 124 142 178 0 +115 Right-hippocampus-intensity-abnormality 124 143 178 0 +116 Right-thalamus-intensity-abnormality 124 144 178 0 +117 Right-VDC-intensity-abnormality 124 140 179 0 +118 Epidermis 255 20 147 0 +119 Conn-Tissue 205 179 139 0 +120 SC-Fat-Muscle 238 238 209 0 +121 Cranium 200 200 200 0 +122 CSF-SA 74 255 74 0 +123 Muscle 238 0 0 0 +124 Ear 0 0 139 0 +125 Adipose 173 255 47 0 +126 Spinal-Cord 133 203 229 0 +127 Soft-Tissue 26 237 57 0 +128 Nerve 34 139 34 0 +129 Bone 30 144 255 0 +130 Air 147 19 173 0 +131 Orbital-Fat 238 59 59 0 +132 Tongue 221 39 200 0 +133 Nasal-Structures 238 174 238 0 +134 Globe 255 0 0 0 +135 Teeth 72 61 139 0 +136 Left-Caudate-Putamen 21 39 132 0 +137 Right-Caudate-Putamen 21 39 132 0 +138 Left-Claustrum 65 135 20 0 +139 Right-Claustrum 65 135 20 0 +140 Cornea 134 4 160 0 +142 Diploe 221 226 68 0 +143 Vitreous-Humor 255 255 254 0 +144 Lens 52 209 226 0 +145 Aqueous-Humor 239 160 223 0 +146 Outer-Table 70 130 180 0 +147 Inner-Table 70 130 181 0 +148 Periosteum 139 121 94 0 +149 Endosteum 224 224 224 0 +150 R-C-S 255 0 0 0 +151 Iris 205 205 0 0 +152 SC-Adipose-Muscle 238 238 209 0 +153 SC-Tissue 139 121 94 0 +154 Orbital-Adipose 238 59 59 0 +155 Left-IntCapsule-Ant 238 59 59 0 +156 Right-IntCapsule-Ant 238 59 59 0 +157 Left-IntCapsule-Pos 62 10 205 0 +158 Right-IntCapsule-Pos 62 10 205 0 +159 Left-Cerebral-WM-unmyelinated 0 118 14 0 +160 Right-Cerebral-WM-unmyelinated 0 118 14 0 +161 Left-Cerebral-WM-myelinated 220 216 21 0 +162 Right-Cerebral-WM-myelinated 220 216 21 0 +163 Left-Subcortical-Gray-Matter 122 186 220 0 +164 Right-Subcortical-Gray-Matter 122 186 220 0 +165 Skull 120 120 120 0 +166 Posterior-fossa 14 48 255 0 +167 Scalp 166 42 42 0 +168 Hematoma 121 18 134 0 +169 Left-Basal-Ganglia 236 13 127 0 +176 Right-Basal-Ganglia 236 13 126 0 +170 brainstem 119 159 176 0 +171 DCG 119 0 176 0 +172 Vermis 119 100 176 0 +173 Midbrain 242 104 76 0 +174 Pons 206 195 58 0 +175 Medulla 119 159 176 0 +177 Vermis-White-Matter 119 50 176 0 +178 SCP 142 182 0 0 +179 Floculus 19 100 176 0 +180 Left-Cortical-Dysplasia 73 61 139 0 +181 Right-Cortical-Dysplasia 73 62 139 0 +182 CblumNodulus 10 100 176 0 +193 Left-hippocampal_fissure 0 196 255 0 +194 Left-CADG-head 255 164 164 0 +195 Left-subiculum 196 196 0 0 +196 Left-fimbria 0 100 255 0 +197 Right-hippocampal_fissure 128 196 164 0 +198 Right-CADG-head 0 126 75 0 +199 Right-subiculum 128 96 64 0 +200 Right-fimbria 0 50 128 0 +201 alveus 255 204 153 0 +202 perforant_pathway 255 128 128 0 +203 parasubiculum 255 255 0 0 +204 presubiculum 64 0 64 0 +205 subiculum 0 0 255 0 +206 CA1 255 0 0 0 +207 CA2 128 128 255 0 +208 CA3 0 128 0 0 +209 CA4 196 160 128 0 +210 GC-DG 32 200 255 0 +211 HATA 128 255 128 0 +212 fimbria 204 153 204 0 +213 lateral_ventricle 121 17 136 0 +214 molecular_layer_HP 128 0 0 0 +215 hippocampal_fissure 128 32 255 0 +216 entorhinal_cortex 255 204 102 0 +217 molecular_layer_subiculum 128 128 128 0 +218 Amygdala 104 255 255 0 +219 Cerebral_White_Matter 0 226 0 0 +220 Cerebral_Cortex 205 63 78 0 +221 Inf_Lat_Vent 197 58 250 0 +222 Perirhinal 33 150 250 0 +223 Cerebral_White_Matter_Edge 226 0 0 0 +224 Background 100 100 100 0 +225 Ectorhinal 197 150 250 0 +226 HP_tail 170 170 255 0 +250 Fornix 255 0 0 0 +251 CC_Posterior 0 0 64 0 +252 CC_Mid_Posterior 0 0 112 0 +253 CC_Central 0 0 160 0 +254 CC_Mid_Anterior 0 0 208 0 +255 CC_Anterior 0 0 255 0 +257 CSF-ExtraCerebral 60 60 60 0 +258 Head-ExtraCerebral 150 150 200 0 +259 SkullApprox 120 120 120 0 +260 BoneOrAir 119 159 176 0 +261 PossibleFluid 120 18 134 0 +262 Sinus 119 159 176 0 +263 Left-Eustachian 119 159 176 0 +264 Right-Eustachian 119 159 176 0 +331 Aorta 255 0 0 0 +332 Left-Common-IliacA 255 80 0 0 +333 Right-Common-IliacA 255 160 0 0 +334 Left-External-IliacA 255 255 0 0 +335 Right-External-IliacA 0 255 0 0 +336 Left-Internal-IliacA 255 0 160 0 +337 Right-Internal-IliacA 255 0 255 0 +338 Left-Lateral-SacralA 255 50 80 0 +339 Right-Lateral-SacralA 80 255 50 0 +340 Left-ObturatorA 160 255 50 0 +341 Right-ObturatorA 160 200 255 0 +342 Left-Internal-PudendalA 0 255 160 0 +343 Right-Internal-PudendalA 0 0 255 0 +344 Left-UmbilicalA 80 50 255 0 +345 Right-UmbilicalA 160 0 255 0 +346 Left-Inf-RectalA 255 210 0 0 +347 Right-Inf-RectalA 0 160 255 0 +348 Left-Common-IliacV 255 200 80 0 +349 Right-Common-IliacV 255 200 160 0 +350 Left-External-IliacV 255 80 200 0 +351 Right-External-IliacV 255 160 200 0 +352 Left-Internal-IliacV 30 255 80 0 +353 Right-Internal-IliacV 80 200 255 0 +354 Left-ObturatorV 80 255 200 0 +355 Right-ObturatorV 195 255 200 0 +356 Left-Internal-PudendalV 120 200 20 0 +357 Right-Internal-PudendalV 170 10 200 0 +358 Pos-Lymph 20 130 180 0 +359 Neg-Lymph 20 180 130 0 +400 V1 206 62 78 0 +401 V2 121 18 134 0 +402 BA44 199 58 250 0 +403 BA45 1 148 0 0 +404 BA4a 221 248 164 0 +405 BA4p 231 148 34 0 +406 BA6 1 118 14 0 +407 BA2 120 118 14 0 +408 BA1_old 123 186 221 0 +409 BAun2 238 13 177 0 +410 BA1 123 186 220 0 +411 BA2b 138 13 206 0 +412 BA3a 238 130 176 0 +413 BA3b 218 230 76 0 +414 MT 38 213 176 0 +415 AIPS_AIP_l 1 225 176 0 +416 AIPS_AIP_r 1 225 176 0 +417 AIPS_VIP_l 200 2 100 0 +418 AIPS_VIP_r 200 2 100 0 +419 IPL_PFcm_l 5 200 90 0 +420 IPL_PFcm_r 5 200 90 0 +421 IPL_PF_l 100 5 200 0 +422 IPL_PFm_l 25 255 100 0 +423 IPL_PFm_r 25 255 100 0 +424 IPL_PFop_l 230 7 100 0 +425 IPL_PFop_r 230 7 100 0 +426 IPL_PF_r 100 5 200 0 +427 IPL_PFt_l 150 10 200 0 +428 IPL_PFt_r 150 10 200 0 +429 IPL_PGa_l 175 10 176 0 +430 IPL_PGa_r 175 10 176 0 +431 IPL_PGp_l 10 100 255 0 +432 IPL_PGp_r 10 100 255 0 +433 Visual_V3d_l 150 45 70 0 +434 Visual_V3d_r 150 45 70 0 +435 Visual_V4_l 45 200 15 0 +436 Visual_V4_r 45 200 15 0 +437 Visual_V5_b 227 45 100 0 +438 Visual_VP_l 227 45 100 0 +439 Visual_VP_r 227 45 100 0 +498 wmsa 143 188 143 0 +499 other_wmsa 255 248 220 0 +500 right_CA2_3 17 85 136 0 +501 right_alveus 119 187 102 0 +502 right_CA1 204 68 34 0 +503 right_fimbria 204 0 255 0 +504 right_presubiculum 221 187 17 0 +505 right_hippocampal_fissure 153 221 238 0 +506 right_CA4_DG 51 17 17 0 +507 right_subiculum 0 119 85 0 +508 right_fornix 20 100 200 0 +550 left_CA2_3 17 85 137 0 +551 left_alveus 119 187 103 0 +552 left_CA1 204 68 35 0 +553 left_fimbria 204 0 254 0 +554 left_presubiculum 221 187 16 0 +555 left_hippocampal_fissure 153 221 239 0 +556 left_CA4_DG 51 17 18 0 +557 left_subiculum 0 119 86 0 +558 left_fornix 20 100 201 0 +600 Tumor 254 254 254 0 +601 Cbm_Left_I_IV 70 130 180 0 +602 Cbm_Right_I_IV 245 245 245 0 +603 Cbm_Left_V 205 62 78 0 +604 Cbm_Right_V 120 18 134 0 +605 Cbm_Left_VI 196 58 250 0 +606 Cbm_Vermis_VI 0 148 0 0 +607 Cbm_Right_VI 220 248 164 0 +608 Cbm_Left_CrusI 230 148 34 0 +609 Cbm_Vermis_CrusI 0 118 14 0 +610 Cbm_Right_CrusI 0 118 14 0 +611 Cbm_Left_CrusII 122 186 220 0 +612 Cbm_Vermis_CrusII 236 13 176 0 +613 Cbm_Right_CrusII 12 48 255 0 +614 Cbm_Left_VIIb 204 182 142 0 +615 Cbm_Vermis_VIIb 42 204 164 0 +616 Cbm_Right_VIIb 119 159 176 0 +617 Cbm_Left_VIIIa 220 216 20 0 +618 Cbm_Vermis_VIIIa 103 255 255 0 +619 Cbm_Right_VIIIa 80 196 98 0 +620 Cbm_Left_VIIIb 60 58 210 0 +621 Cbm_Vermis_VIIIb 60 58 210 0 +622 Cbm_Right_VIIIb 60 58 210 0 +623 Cbm_Left_IX 60 58 210 0 +624 Cbm_Vermis_IX 60 60 60 0 +625 Cbm_Right_IX 255 165 0 0 +626 Cbm_Left_X 255 165 0 0 +627 Cbm_Vermis_X 0 255 127 0 +628 Cbm_Right_X 165 42 42 0 +640 Cbm_Right_I_V_med 204 0 0 0 +641 Cbm_Right_I_V_mid 255 0 0 0 +642 Cbm_Right_VI_med 0 0 255 0 +643 Cbm_Right_VI_mid 30 144 255 0 +644 Cbm_Right_VI_lat 100 212 237 0 +645 Cbm_Right_CrusI_med 218 165 32 0 +646 Cbm_Right_CrusI_mid 255 215 0 0 +647 Cbm_Right_CrusI_lat 255 255 166 0 +648 Cbm_Right_CrusII_med 153 0 204 0 +649 Cbm_Right_CrusII_mid 153 141 209 0 +650 Cbm_Right_CrusII_lat 204 204 255 0 +651 Cbm_Right_7med 31 212 194 0 +652 Cbm_Right_7mid 3 255 237 0 +653 Cbm_Right_7lat 204 255 255 0 +654 Cbm_Right_8med 86 74 147 0 +655 Cbm_Right_8mid 114 114 190 0 +656 Cbm_Right_8lat 184 178 255 0 +657 Cbm_Right_PUNs 126 138 37 0 +658 Cbm_Right_TONs 189 197 117 0 +659 Cbm_Right_FLOs 240 230 140 0 +660 Cbm_Left_I_V_med 204 0 0 0 +661 Cbm_Left_I_V_mid 255 0 0 0 +662 Cbm_Left_VI_med 0 0 255 0 +663 Cbm_Left_VI_mid 30 144 255 0 +664 Cbm_Left_VI_lat 100 212 237 0 +665 Cbm_Left_CrusI_med 218 165 32 0 +666 Cbm_Left_CrusI_mid 255 215 0 0 +667 Cbm_Left_CrusI_lat 255 255 166 0 +668 Cbm_Left_CrusII_med 153 0 204 0 +669 Cbm_Left_CrusII_mid 153 141 209 0 +670 Cbm_Left_CrusII_lat 204 204 255 0 +671 Cbm_Left_7med 31 212 194 0 +672 Cbm_Left_7mid 3 255 237 0 +673 Cbm_Left_7lat 204 255 255 0 +674 Cbm_Left_8med 86 74 147 0 +675 Cbm_Left_8mid 114 114 190 0 +676 Cbm_Left_8lat 184 178 255 0 +677 Cbm_Left_PUNs 126 138 37 0 +678 Cbm_Left_TONs 189 197 117 0 +679 Cbm_Left_FLOs 240 230 140 0 +690 CbmWM_Gyri_Left 122 135 50 0 +691 CbmWM_Gyri_Right 122 135 50 0 +701 CSF-FSL-FAST 120 18 134 0 +702 GrayMatter-FSL-FAST 205 62 78 0 +703 WhiteMatter-FSL-FAST 0 225 0 0 +1000 ctx-lh-unknown 25 5 25 0 +1001 ctx-lh-bankssts 25 100 40 0 +1002 ctx-lh-caudalanteriorcingulate 125 100 160 0 +1003 ctx-lh-caudalmiddlefrontal 100 25 0 0 +1004 ctx-lh-corpuscallosum 120 70 50 0 +1005 ctx-lh-cuneus 220 20 100 0 +1006 ctx-lh-entorhinal 220 20 10 0 +1007 ctx-lh-fusiform 180 220 140 0 +1008 ctx-lh-inferiorparietal 220 60 220 0 +1009 ctx-lh-inferiortemporal 180 40 120 0 +1010 ctx-lh-isthmuscingulate 140 20 140 0 +1011 ctx-lh-lateraloccipital 20 30 140 0 +1012 ctx-lh-lateralorbitofrontal 35 75 50 0 +1013 ctx-lh-lingual 225 140 140 0 +1014 ctx-lh-medialorbitofrontal 200 35 75 0 +1015 ctx-lh-middletemporal 160 100 50 0 +1016 ctx-lh-parahippocampal 20 220 60 0 +1017 ctx-lh-paracentral 60 220 60 0 +1018 ctx-lh-parsopercularis 220 180 140 0 +1019 ctx-lh-parsorbitalis 20 100 50 0 +1020 ctx-lh-parstriangularis 220 60 20 0 +1021 ctx-lh-pericalcarine 120 100 60 0 +1022 ctx-lh-postcentral 220 20 20 0 +1023 ctx-lh-posteriorcingulate 220 180 220 0 +1024 ctx-lh-precentral 60 20 220 0 +1025 ctx-lh-precuneus 160 140 180 0 +1026 ctx-lh-rostralanteriorcingulate 80 20 140 0 +1027 ctx-lh-rostralmiddlefrontal 75 50 125 0 +1028 ctx-lh-superiorfrontal 20 220 160 0 +1029 ctx-lh-superiorparietal 20 180 140 0 +1030 ctx-lh-superiortemporal 140 220 220 0 +1031 ctx-lh-supramarginal 80 160 20 0 +1032 ctx-lh-frontalpole 100 0 100 0 +1033 ctx-lh-temporalpole 70 70 70 0 +1034 ctx-lh-transversetemporal 150 150 200 0 +1035 ctx-lh-insula 255 192 32 0 +2000 ctx-rh-unknown 25 5 25 0 +2001 ctx-rh-bankssts 25 100 40 0 +2002 ctx-rh-caudalanteriorcingulate 125 100 160 0 +2003 ctx-rh-caudalmiddlefrontal 100 25 0 0 +2004 ctx-rh-corpuscallosum 120 70 50 0 +2005 ctx-rh-cuneus 220 20 100 0 +2006 ctx-rh-entorhinal 220 20 10 0 +2007 ctx-rh-fusiform 180 220 140 0 +2008 ctx-rh-inferiorparietal 220 60 220 0 +2009 ctx-rh-inferiortemporal 180 40 120 0 +2010 ctx-rh-isthmuscingulate 140 20 140 0 +2011 ctx-rh-lateraloccipital 20 30 140 0 +2012 ctx-rh-lateralorbitofrontal 35 75 50 0 +2013 ctx-rh-lingual 225 140 140 0 +2014 ctx-rh-medialorbitofrontal 200 35 75 0 +2015 ctx-rh-middletemporal 160 100 50 0 +2016 ctx-rh-parahippocampal 20 220 60 0 +2017 ctx-rh-paracentral 60 220 60 0 +2018 ctx-rh-parsopercularis 220 180 140 0 +2019 ctx-rh-parsorbitalis 20 100 50 0 +2020 ctx-rh-parstriangularis 220 60 20 0 +2021 ctx-rh-pericalcarine 120 100 60 0 +2022 ctx-rh-postcentral 220 20 20 0 +2023 ctx-rh-posteriorcingulate 220 180 220 0 +2024 ctx-rh-precentral 60 20 220 0 +2025 ctx-rh-precuneus 160 140 180 0 +2026 ctx-rh-rostralanteriorcingulate 80 20 140 0 +2027 ctx-rh-rostralmiddlefrontal 75 50 125 0 +2028 ctx-rh-superiorfrontal 20 220 160 0 +2029 ctx-rh-superiorparietal 20 180 140 0 +2030 ctx-rh-superiortemporal 140 220 220 0 +2031 ctx-rh-supramarginal 80 160 20 0 +2032 ctx-rh-frontalpole 100 0 100 0 +2033 ctx-rh-temporalpole 70 70 70 0 +2034 ctx-rh-transversetemporal 150 150 200 0 +2035 ctx-rh-insula 255 192 32 0 +3000 wm-lh-unknown 230 250 230 0 +3001 wm-lh-bankssts 230 155 215 0 +3002 wm-lh-caudalanteriorcingulate 130 155 95 0 +3003 wm-lh-caudalmiddlefrontal 155 230 255 0 +3004 wm-lh-corpuscallosum 135 185 205 0 +3005 wm-lh-cuneus 35 235 155 0 +3006 wm-lh-entorhinal 35 235 245 0 +3007 wm-lh-fusiform 75 35 115 0 +3008 wm-lh-inferiorparietal 35 195 35 0 +3009 wm-lh-inferiortemporal 75 215 135 0 +3010 wm-lh-isthmuscingulate 115 235 115 0 +3011 wm-lh-lateraloccipital 235 225 115 0 +3012 wm-lh-lateralorbitofrontal 220 180 205 0 +3013 wm-lh-lingual 30 115 115 0 +3014 wm-lh-medialorbitofrontal 55 220 180 0 +3015 wm-lh-middletemporal 95 155 205 0 +3016 wm-lh-parahippocampal 235 35 195 0 +3017 wm-lh-paracentral 195 35 195 0 +3018 wm-lh-parsopercularis 35 75 115 0 +3019 wm-lh-parsorbitalis 235 155 205 0 +3020 wm-lh-parstriangularis 35 195 235 0 +3021 wm-lh-pericalcarine 135 155 195 0 +3022 wm-lh-postcentral 35 235 235 0 +3023 wm-lh-posteriorcingulate 35 75 35 0 +3024 wm-lh-precentral 195 235 35 0 +3025 wm-lh-precuneus 95 115 75 0 +3026 wm-lh-rostralanteriorcingulate 175 235 115 0 +3027 wm-lh-rostralmiddlefrontal 180 205 130 0 +3028 wm-lh-superiorfrontal 235 35 95 0 +3029 wm-lh-superiorparietal 235 75 115 0 +3030 wm-lh-superiortemporal 115 35 35 0 +3031 wm-lh-supramarginal 175 95 235 0 +3032 wm-lh-frontalpole 155 255 155 0 +3033 wm-lh-temporalpole 185 185 185 0 +3034 wm-lh-transversetemporal 105 105 55 0 +3035 wm-lh-insula 20 220 160 0 +4000 wm-rh-unknown 230 250 230 0 +4001 wm-rh-bankssts 230 155 215 0 +4002 wm-rh-caudalanteriorcingulate 130 155 95 0 +4003 wm-rh-caudalmiddlefrontal 155 230 255 0 +4004 wm-rh-corpuscallosum 135 185 205 0 +4005 wm-rh-cuneus 35 235 155 0 +4006 wm-rh-entorhinal 35 235 245 0 +4007 wm-rh-fusiform 75 35 115 0 +4008 wm-rh-inferiorparietal 35 195 35 0 +4009 wm-rh-inferiortemporal 75 215 135 0 +4010 wm-rh-isthmuscingulate 115 235 115 0 +4011 wm-rh-lateraloccipital 235 225 115 0 +4012 wm-rh-lateralorbitofrontal 220 180 205 0 +4013 wm-rh-lingual 30 115 115 0 +4014 wm-rh-medialorbitofrontal 55 220 180 0 +4015 wm-rh-middletemporal 95 155 205 0 +4016 wm-rh-parahippocampal 235 35 195 0 +4017 wm-rh-paracentral 195 35 195 0 +4018 wm-rh-parsopercularis 35 75 115 0 +4019 wm-rh-parsorbitalis 235 155 205 0 +4020 wm-rh-parstriangularis 35 195 235 0 +4021 wm-rh-pericalcarine 135 155 195 0 +4022 wm-rh-postcentral 35 235 235 0 +4023 wm-rh-posteriorcingulate 35 75 35 0 +4024 wm-rh-precentral 195 235 35 0 +4025 wm-rh-precuneus 95 115 75 0 +4026 wm-rh-rostralanteriorcingulate 175 235 115 0 +4027 wm-rh-rostralmiddlefrontal 180 205 130 0 +4028 wm-rh-superiorfrontal 235 35 95 0 +4029 wm-rh-superiorparietal 235 75 115 0 +4030 wm-rh-superiortemporal 115 35 35 0 +4031 wm-rh-supramarginal 175 95 235 0 +4032 wm-rh-frontalpole 155 255 155 0 +4033 wm-rh-temporalpole 185 185 185 0 +4034 wm-rh-transversetemporal 105 105 55 0 +4035 wm-rh-insula 20 220 160 0 +3201 wm-lh-frontal-lobe 235 35 95 0 +3203 wm-lh-cingulate-lobe 35 75 35 0 +3204 wm-lh-occiptal-lobe 135 155 195 0 +3205 wm-lh-temporal-lobe 115 35 35 0 +3206 wm-lh-parietal-lobe 35 195 35 0 +3207 wm-lh-insula-lobe 20 220 160 0 +4201 wm-rh-frontal-lobe 235 35 95 0 +4203 wm-rh-cingulate-lobe 35 75 35 0 +4204 wm-rh-occiptal-lobe 135 155 195 0 +4205 wm-rh-temporal-lobe 115 35 35 0 +4206 wm-rh-parietal-lobe 35 195 35 0 +4207 wm-rh-insula-lobe 20 220 160 0 +1100 ctx-lh-Unknown 0 0 0 0 +1101 ctx-lh-Corpus_callosum 50 50 50 0 +1102 ctx-lh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 0 +1103 ctx-lh-G_cingulate-Isthmus 60 25 25 0 +1104 ctx-lh-G_cingulate-Main_part 25 60 60 0 +1200 ctx-lh-G_cingulate-caudal_ACC 25 60 61 0 +1201 ctx-lh-G_cingulate-rostral_ACC 25 90 60 0 +1202 ctx-lh-G_cingulate-posterior 25 120 60 0 +1205 ctx-lh-S_cingulate-caudal_ACC 25 150 60 0 +1206 ctx-lh-S_cingulate-rostral_ACC 25 180 60 0 +1207 ctx-lh-S_cingulate-posterior 25 210 60 0 +1210 ctx-lh-S_pericallosal-caudal 25 150 90 0 +1211 ctx-lh-S_pericallosal-rostral 25 180 90 0 +1212 ctx-lh-S_pericallosal-posterior 25 210 90 0 +1105 ctx-lh-G_cuneus 180 20 20 0 +1106 ctx-lh-G_frontal_inf-Opercular_part 220 20 100 0 +1107 ctx-lh-G_frontal_inf-Orbital_part 140 60 60 0 +1108 ctx-lh-G_frontal_inf-Triangular_part 180 220 140 0 +1109 ctx-lh-G_frontal_middle 140 100 180 0 +1110 ctx-lh-G_frontal_superior 180 20 140 0 +1111 ctx-lh-G_frontomarginal 140 20 140 0 +1112 ctx-lh-G_insular_long 21 10 10 0 +1113 ctx-lh-G_insular_short 225 140 140 0 +1114 ctx-lh-G_and_S_occipital_inferior 23 60 180 0 +1115 ctx-lh-G_occipital_middle 180 60 180 0 +1116 ctx-lh-G_occipital_superior 20 220 60 0 +1117 ctx-lh-G_occipit-temp_lat-Or_fusiform 60 20 140 0 +1118 ctx-lh-G_occipit-temp_med-Lingual_part 220 180 140 0 +1119 ctx-lh-G_occipit-temp_med-Parahippocampal_part 65 100 20 0 +1120 ctx-lh-G_orbital 220 60 20 0 +1121 ctx-lh-G_paracentral 60 100 60 0 +1122 ctx-lh-G_parietal_inferior-Angular_part 20 60 220 0 +1123 ctx-lh-G_parietal_inferior-Supramarginal_part 100 100 60 0 +1124 ctx-lh-G_parietal_superior 220 180 220 0 +1125 ctx-lh-G_postcentral 20 180 140 0 +1126 ctx-lh-G_precentral 60 140 180 0 +1127 ctx-lh-G_precuneus 25 20 140 0 +1128 ctx-lh-G_rectus 20 60 100 0 +1129 ctx-lh-G_subcallosal 60 220 20 0 +1130 ctx-lh-G_subcentral 60 20 220 0 +1131 ctx-lh-G_temporal_inferior 220 220 100 0 +1132 ctx-lh-G_temporal_middle 180 60 60 0 +1133 ctx-lh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 0 +1134 ctx-lh-G_temp_sup-Lateral_aspect 220 60 220 0 +1135 ctx-lh-G_temp_sup-Planum_polare 65 220 60 0 +1136 ctx-lh-G_temp_sup-Planum_tempolare 25 140 20 0 +1137 ctx-lh-G_and_S_transverse_frontopolar 13 0 250 0 +1138 ctx-lh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 0 +1139 ctx-lh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 0 +1140 ctx-lh-Lat_Fissure-post_sgt 61 60 100 0 +1141 ctx-lh-Medial_wall 25 25 25 0 +1142 ctx-lh-Pole_occipital 140 20 60 0 +1143 ctx-lh-Pole_temporal 220 180 20 0 +1144 ctx-lh-S_calcarine 63 180 180 0 +1145 ctx-lh-S_central 221 20 10 0 +1146 ctx-lh-S_central_insula 21 220 20 0 +1147 ctx-lh-S_cingulate-Main_part_and_Intracingulate 183 100 20 0 +1148 ctx-lh-S_cingulate-Marginalis_part 221 20 100 0 +1149 ctx-lh-S_circular_insula_anterior 221 60 140 0 +1150 ctx-lh-S_circular_insula_inferior 221 20 220 0 +1151 ctx-lh-S_circular_insula_superior 61 220 220 0 +1152 ctx-lh-S_collateral_transverse_ant 100 200 200 0 +1153 ctx-lh-S_collateral_transverse_post 10 200 200 0 +1154 ctx-lh-S_frontal_inferior 221 220 20 0 +1155 ctx-lh-S_frontal_middle 141 20 100 0 +1156 ctx-lh-S_frontal_superior 61 220 100 0 +1157 ctx-lh-S_frontomarginal 21 220 60 0 +1158 ctx-lh-S_intermedius_primus-Jensen 141 60 20 0 +1159 ctx-lh-S_intraparietal-and_Parietal_transverse 143 20 220 0 +1160 ctx-lh-S_occipital_anterior 61 20 180 0 +1161 ctx-lh-S_occipital_middle_and_Lunatus 101 60 220 0 +1162 ctx-lh-S_occipital_superior_and_transversalis 21 20 140 0 +1163 ctx-lh-S_occipito-temporal_lateral 221 140 20 0 +1164 ctx-lh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 0 +1165 ctx-lh-S_orbital-H_shapped 101 20 20 0 +1166 ctx-lh-S_orbital_lateral 221 100 20 0 +1167 ctx-lh-S_orbital_medial-Or_olfactory 181 200 20 0 +1168 ctx-lh-S_paracentral 21 180 140 0 +1169 ctx-lh-S_parieto_occipital 101 100 180 0 +1170 ctx-lh-S_pericallosal 181 220 20 0 +1171 ctx-lh-S_postcentral 21 140 200 0 +1172 ctx-lh-S_precentral-Inferior-part 21 20 240 0 +1173 ctx-lh-S_precentral-Superior-part 21 20 200 0 +1174 ctx-lh-S_subcentral_ant 61 180 60 0 +1175 ctx-lh-S_subcentral_post 61 180 250 0 +1176 ctx-lh-S_suborbital 21 20 60 0 +1177 ctx-lh-S_subparietal 101 60 60 0 +1178 ctx-lh-S_supracingulate 21 220 220 0 +1179 ctx-lh-S_temporal_inferior 21 180 180 0 +1180 ctx-lh-S_temporal_superior 223 220 60 0 +1181 ctx-lh-S_temporal_transverse 221 60 60 0 +2100 ctx-rh-Unknown 0 0 0 0 +2101 ctx-rh-Corpus_callosum 50 50 50 0 +2102 ctx-rh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 0 +2103 ctx-rh-G_cingulate-Isthmus 60 25 25 0 +2104 ctx-rh-G_cingulate-Main_part 25 60 60 0 +2105 ctx-rh-G_cuneus 180 20 20 0 +2106 ctx-rh-G_frontal_inf-Opercular_part 220 20 100 0 +2107 ctx-rh-G_frontal_inf-Orbital_part 140 60 60 0 +2108 ctx-rh-G_frontal_inf-Triangular_part 180 220 140 0 +2109 ctx-rh-G_frontal_middle 140 100 180 0 +2110 ctx-rh-G_frontal_superior 180 20 140 0 +2111 ctx-rh-G_frontomarginal 140 20 140 0 +2112 ctx-rh-G_insular_long 21 10 10 0 +2113 ctx-rh-G_insular_short 225 140 140 0 +2114 ctx-rh-G_and_S_occipital_inferior 23 60 180 0 +2115 ctx-rh-G_occipital_middle 180 60 180 0 +2116 ctx-rh-G_occipital_superior 20 220 60 0 +2117 ctx-rh-G_occipit-temp_lat-Or_fusiform 60 20 140 0 +2118 ctx-rh-G_occipit-temp_med-Lingual_part 220 180 140 0 +2119 ctx-rh-G_occipit-temp_med-Parahippocampal_part 65 100 20 0 +2120 ctx-rh-G_orbital 220 60 20 0 +2121 ctx-rh-G_paracentral 60 100 60 0 +2122 ctx-rh-G_parietal_inferior-Angular_part 20 60 220 0 +2123 ctx-rh-G_parietal_inferior-Supramarginal_part 100 100 60 0 +2124 ctx-rh-G_parietal_superior 220 180 220 0 +2125 ctx-rh-G_postcentral 20 180 140 0 +2126 ctx-rh-G_precentral 60 140 180 0 +2127 ctx-rh-G_precuneus 25 20 140 0 +2128 ctx-rh-G_rectus 20 60 100 0 +2129 ctx-rh-G_subcallosal 60 220 20 0 +2130 ctx-rh-G_subcentral 60 20 220 0 +2131 ctx-rh-G_temporal_inferior 220 220 100 0 +2132 ctx-rh-G_temporal_middle 180 60 60 0 +2133 ctx-rh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 0 +2134 ctx-rh-G_temp_sup-Lateral_aspect 220 60 220 0 +2135 ctx-rh-G_temp_sup-Planum_polare 65 220 60 0 +2136 ctx-rh-G_temp_sup-Planum_tempolare 25 140 20 0 +2137 ctx-rh-G_and_S_transverse_frontopolar 13 0 250 0 +2138 ctx-rh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 0 +2139 ctx-rh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 0 +2140 ctx-rh-Lat_Fissure-post_sgt 61 60 100 0 +2141 ctx-rh-Medial_wall 25 25 25 0 +2142 ctx-rh-Pole_occipital 140 20 60 0 +2143 ctx-rh-Pole_temporal 220 180 20 0 +2144 ctx-rh-S_calcarine 63 180 180 0 +2145 ctx-rh-S_central 221 20 10 0 +2146 ctx-rh-S_central_insula 21 220 20 0 +2147 ctx-rh-S_cingulate-Main_part_and_Intracingulate 183 100 20 0 +2148 ctx-rh-S_cingulate-Marginalis_part 221 20 100 0 +2149 ctx-rh-S_circular_insula_anterior 221 60 140 0 +2150 ctx-rh-S_circular_insula_inferior 221 20 220 0 +2151 ctx-rh-S_circular_insula_superior 61 220 220 0 +2152 ctx-rh-S_collateral_transverse_ant 100 200 200 0 +2153 ctx-rh-S_collateral_transverse_post 10 200 200 0 +2154 ctx-rh-S_frontal_inferior 221 220 20 0 +2155 ctx-rh-S_frontal_middle 141 20 100 0 +2156 ctx-rh-S_frontal_superior 61 220 100 0 +2157 ctx-rh-S_frontomarginal 21 220 60 0 +2158 ctx-rh-S_intermedius_primus-Jensen 141 60 20 0 +2159 ctx-rh-S_intraparietal-and_Parietal_transverse 143 20 220 0 +2160 ctx-rh-S_occipital_anterior 61 20 180 0 +2161 ctx-rh-S_occipital_middle_and_Lunatus 101 60 220 0 +2162 ctx-rh-S_occipital_superior_and_transversalis 21 20 140 0 +2163 ctx-rh-S_occipito-temporal_lateral 221 140 20 0 +2164 ctx-rh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 0 +2165 ctx-rh-S_orbital-H_shapped 101 20 20 0 +2166 ctx-rh-S_orbital_lateral 221 100 20 0 +2167 ctx-rh-S_orbital_medial-Or_olfactory 181 200 20 0 +2168 ctx-rh-S_paracentral 21 180 140 0 +2169 ctx-rh-S_parieto_occipital 101 100 180 0 +2170 ctx-rh-S_pericallosal 181 220 20 0 +2171 ctx-rh-S_postcentral 21 140 200 0 +2172 ctx-rh-S_precentral-Inferior-part 21 20 240 0 +2173 ctx-rh-S_precentral-Superior-part 21 20 200 0 +2174 ctx-rh-S_subcentral_ant 61 180 60 0 +2175 ctx-rh-S_subcentral_post 61 180 250 0 +2176 ctx-rh-S_suborbital 21 20 60 0 +2177 ctx-rh-S_subparietal 101 60 60 0 +2178 ctx-rh-S_supracingulate 21 220 220 0 +2179 ctx-rh-S_temporal_inferior 21 180 180 0 +2180 ctx-rh-S_temporal_superior 223 220 60 0 +2181 ctx-rh-S_temporal_transverse 221 60 60 0 +2200 ctx-rh-G_cingulate-caudal_ACC 25 60 61 0 +2201 ctx-rh-G_cingulate-rostral_ACC 25 90 60 0 +2202 ctx-rh-G_cingulate-posterior 25 120 60 0 +2205 ctx-rh-S_cingulate-caudal_ACC 25 150 60 0 +2206 ctx-rh-S_cingulate-rostral_ACC 25 180 60 0 +2207 ctx-rh-S_cingulate-posterior 25 210 60 0 +2210 ctx-rh-S_pericallosal-caudal 25 150 90 0 +2211 ctx-rh-S_pericallosal-rostral 25 180 90 0 +2212 ctx-rh-S_pericallosal-posterior 25 210 90 0 +3100 wm-lh-Unknown 0 0 0 0 +3101 wm-lh-Corpus_callosum 50 50 50 0 +3102 wm-lh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 0 +3103 wm-lh-G_cingulate-Isthmus 60 25 25 0 +3104 wm-lh-G_cingulate-Main_part 25 60 60 0 +3105 wm-lh-G_cuneus 180 20 20 0 +3106 wm-lh-G_frontal_inf-Opercular_part 220 20 100 0 +3107 wm-lh-G_frontal_inf-Orbital_part 140 60 60 0 +3108 wm-lh-G_frontal_inf-Triangular_part 180 220 140 0 +3109 wm-lh-G_frontal_middle 140 100 180 0 +3110 wm-lh-G_frontal_superior 180 20 140 0 +3111 wm-lh-G_frontomarginal 140 20 140 0 +3112 wm-lh-G_insular_long 21 10 10 0 +3113 wm-lh-G_insular_short 225 140 140 0 +3114 wm-lh-G_and_S_occipital_inferior 23 60 180 0 +3115 wm-lh-G_occipital_middle 180 60 180 0 +3116 wm-lh-G_occipital_superior 20 220 60 0 +3117 wm-lh-G_occipit-temp_lat-Or_fusiform 60 20 140 0 +3118 wm-lh-G_occipit-temp_med-Lingual_part 220 180 140 0 +3119 wm-lh-G_occipit-temp_med-Parahippocampal_part 65 100 20 0 +3120 wm-lh-G_orbital 220 60 20 0 +3121 wm-lh-G_paracentral 60 100 60 0 +3122 wm-lh-G_parietal_inferior-Angular_part 20 60 220 0 +3123 wm-lh-G_parietal_inferior-Supramarginal_part 100 100 60 0 +3124 wm-lh-G_parietal_superior 220 180 220 0 +3125 wm-lh-G_postcentral 20 180 140 0 +3126 wm-lh-G_precentral 60 140 180 0 +3127 wm-lh-G_precuneus 25 20 140 0 +3128 wm-lh-G_rectus 20 60 100 0 +3129 wm-lh-G_subcallosal 60 220 20 0 +3130 wm-lh-G_subcentral 60 20 220 0 +3131 wm-lh-G_temporal_inferior 220 220 100 0 +3132 wm-lh-G_temporal_middle 180 60 60 0 +3133 wm-lh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 0 +3134 wm-lh-G_temp_sup-Lateral_aspect 220 60 220 0 +3135 wm-lh-G_temp_sup-Planum_polare 65 220 60 0 +3136 wm-lh-G_temp_sup-Planum_tempolare 25 140 20 0 +3137 wm-lh-G_and_S_transverse_frontopolar 13 0 250 0 +3138 wm-lh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 0 +3139 wm-lh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 0 +3140 wm-lh-Lat_Fissure-post_sgt 61 60 100 0 +3141 wm-lh-Medial_wall 25 25 25 0 +3142 wm-lh-Pole_occipital 140 20 60 0 +3143 wm-lh-Pole_temporal 220 180 20 0 +3144 wm-lh-S_calcarine 63 180 180 0 +3145 wm-lh-S_central 221 20 10 0 +3146 wm-lh-S_central_insula 21 220 20 0 +3147 wm-lh-S_cingulate-Main_part_and_Intracingulate 183 100 20 0 +3148 wm-lh-S_cingulate-Marginalis_part 221 20 100 0 +3149 wm-lh-S_circular_insula_anterior 221 60 140 0 +3150 wm-lh-S_circular_insula_inferior 221 20 220 0 +3151 wm-lh-S_circular_insula_superior 61 220 220 0 +3152 wm-lh-S_collateral_transverse_ant 100 200 200 0 +3153 wm-lh-S_collateral_transverse_post 10 200 200 0 +3154 wm-lh-S_frontal_inferior 221 220 20 0 +3155 wm-lh-S_frontal_middle 141 20 100 0 +3156 wm-lh-S_frontal_superior 61 220 100 0 +3157 wm-lh-S_frontomarginal 21 220 60 0 +3158 wm-lh-S_intermedius_primus-Jensen 141 60 20 0 +3159 wm-lh-S_intraparietal-and_Parietal_transverse 143 20 220 0 +3160 wm-lh-S_occipital_anterior 61 20 180 0 +3161 wm-lh-S_occipital_middle_and_Lunatus 101 60 220 0 +3162 wm-lh-S_occipital_superior_and_transversalis 21 20 140 0 +3163 wm-lh-S_occipito-temporal_lateral 221 140 20 0 +3164 wm-lh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 0 +3165 wm-lh-S_orbital-H_shapped 101 20 20 0 +3166 wm-lh-S_orbital_lateral 221 100 20 0 +3167 wm-lh-S_orbital_medial-Or_olfactory 181 200 20 0 +3168 wm-lh-S_paracentral 21 180 140 0 +3169 wm-lh-S_parieto_occipital 101 100 180 0 +3170 wm-lh-S_pericallosal 181 220 20 0 +3171 wm-lh-S_postcentral 21 140 200 0 +3172 wm-lh-S_precentral-Inferior-part 21 20 240 0 +3173 wm-lh-S_precentral-Superior-part 21 20 200 0 +3174 wm-lh-S_subcentral_ant 61 180 60 0 +3175 wm-lh-S_subcentral_post 61 180 250 0 +3176 wm-lh-S_suborbital 21 20 60 0 +3177 wm-lh-S_subparietal 101 60 60 0 +3178 wm-lh-S_supracingulate 21 220 220 0 +3179 wm-lh-S_temporal_inferior 21 180 180 0 +3180 wm-lh-S_temporal_superior 223 220 60 0 +3181 wm-lh-S_temporal_transverse 221 60 60 0 +4100 wm-rh-Unknown 0 0 0 0 +4101 wm-rh-Corpus_callosum 50 50 50 0 +4102 wm-rh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 0 +4103 wm-rh-G_cingulate-Isthmus 60 25 25 0 +4104 wm-rh-G_cingulate-Main_part 25 60 60 0 +4105 wm-rh-G_cuneus 180 20 20 0 +4106 wm-rh-G_frontal_inf-Opercular_part 220 20 100 0 +4107 wm-rh-G_frontal_inf-Orbital_part 140 60 60 0 +4108 wm-rh-G_frontal_inf-Triangular_part 180 220 140 0 +4109 wm-rh-G_frontal_middle 140 100 180 0 +4110 wm-rh-G_frontal_superior 180 20 140 0 +4111 wm-rh-G_frontomarginal 140 20 140 0 +4112 wm-rh-G_insular_long 21 10 10 0 +4113 wm-rh-G_insular_short 225 140 140 0 +4114 wm-rh-G_and_S_occipital_inferior 23 60 180 0 +4115 wm-rh-G_occipital_middle 180 60 180 0 +4116 wm-rh-G_occipital_superior 20 220 60 0 +4117 wm-rh-G_occipit-temp_lat-Or_fusiform 60 20 140 0 +4118 wm-rh-G_occipit-temp_med-Lingual_part 220 180 140 0 +4119 wm-rh-G_occipit-temp_med-Parahippocampal_part 65 100 20 0 +4120 wm-rh-G_orbital 220 60 20 0 +4121 wm-rh-G_paracentral 60 100 60 0 +4122 wm-rh-G_parietal_inferior-Angular_part 20 60 220 0 +4123 wm-rh-G_parietal_inferior-Supramarginal_part 100 100 60 0 +4124 wm-rh-G_parietal_superior 220 180 220 0 +4125 wm-rh-G_postcentral 20 180 140 0 +4126 wm-rh-G_precentral 60 140 180 0 +4127 wm-rh-G_precuneus 25 20 140 0 +4128 wm-rh-G_rectus 20 60 100 0 +4129 wm-rh-G_subcallosal 60 220 20 0 +4130 wm-rh-G_subcentral 60 20 220 0 +4131 wm-rh-G_temporal_inferior 220 220 100 0 +4132 wm-rh-G_temporal_middle 180 60 60 0 +4133 wm-rh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 0 +4134 wm-rh-G_temp_sup-Lateral_aspect 220 60 220 0 +4135 wm-rh-G_temp_sup-Planum_polare 65 220 60 0 +4136 wm-rh-G_temp_sup-Planum_tempolare 25 140 20 0 +4137 wm-rh-G_and_S_transverse_frontopolar 13 0 250 0 +4138 wm-rh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 0 +4139 wm-rh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 0 +4140 wm-rh-Lat_Fissure-post_sgt 61 60 100 0 +4141 wm-rh-Medial_wall 25 25 25 0 +4142 wm-rh-Pole_occipital 140 20 60 0 +4143 wm-rh-Pole_temporal 220 180 20 0 +4144 wm-rh-S_calcarine 63 180 180 0 +4145 wm-rh-S_central 221 20 10 0 +4146 wm-rh-S_central_insula 21 220 20 0 +4147 wm-rh-S_cingulate-Main_part_and_Intracingulate 183 100 20 0 +4148 wm-rh-S_cingulate-Marginalis_part 221 20 100 0 +4149 wm-rh-S_circular_insula_anterior 221 60 140 0 +4150 wm-rh-S_circular_insula_inferior 221 20 220 0 +4151 wm-rh-S_circular_insula_superior 61 220 220 0 +4152 wm-rh-S_collateral_transverse_ant 100 200 200 0 +4153 wm-rh-S_collateral_transverse_post 10 200 200 0 +4154 wm-rh-S_frontal_inferior 221 220 20 0 +4155 wm-rh-S_frontal_middle 141 20 100 0 +4156 wm-rh-S_frontal_superior 61 220 100 0 +4157 wm-rh-S_frontomarginal 21 220 60 0 +4158 wm-rh-S_intermedius_primus-Jensen 141 60 20 0 +4159 wm-rh-S_intraparietal-and_Parietal_transverse 143 20 220 0 +4160 wm-rh-S_occipital_anterior 61 20 180 0 +4161 wm-rh-S_occipital_middle_and_Lunatus 101 60 220 0 +4162 wm-rh-S_occipital_superior_and_transversalis 21 20 140 0 +4163 wm-rh-S_occipito-temporal_lateral 221 140 20 0 +4164 wm-rh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 0 +4165 wm-rh-S_orbital-H_shapped 101 20 20 0 +4166 wm-rh-S_orbital_lateral 221 100 20 0 +4167 wm-rh-S_orbital_medial-Or_olfactory 181 200 20 0 +4168 wm-rh-S_paracentral 21 180 140 0 +4169 wm-rh-S_parieto_occipital 101 100 180 0 +4170 wm-rh-S_pericallosal 181 220 20 0 +4171 wm-rh-S_postcentral 21 140 200 0 +4172 wm-rh-S_precentral-Inferior-part 21 20 240 0 +4173 wm-rh-S_precentral-Superior-part 21 20 200 0 +4174 wm-rh-S_subcentral_ant 61 180 60 0 +4175 wm-rh-S_subcentral_post 61 180 250 0 +4176 wm-rh-S_suborbital 21 20 60 0 +4177 wm-rh-S_subparietal 101 60 60 0 +4178 wm-rh-S_supracingulate 21 220 220 0 +4179 wm-rh-S_temporal_inferior 21 180 180 0 +4180 wm-rh-S_temporal_superior 223 220 60 0 +4181 wm-rh-S_temporal_transverse 221 60 60 0 +5001 Left-UnsegmentedWhiteMatter 20 30 40 0 +5002 Right-UnsegmentedWhiteMatter 20 30 40 0 +5100 fmajor 204 102 102 0 +5101 fminor 204 102 102 0 +5102 lh.atr 255 255 102 0 +5103 lh.cab 153 204 0 0 +5104 lh.ccg 0 153 153 0 +5105 lh.cst 204 153 255 0 +5106 lh.ilf 255 153 51 0 +5107 lh.slfp 204 204 204 0 +5108 lh.slft 153 255 255 0 +5109 lh.unc 102 153 255 0 +5110 rh.atr 255 255 102 0 +5111 rh.cab 153 204 0 0 +5112 rh.ccg 0 153 153 0 +5113 rh.cst 204 153 255 0 +5114 rh.ilf 255 153 51 0 +5115 rh.slfp 204 204 204 0 +5116 rh.slft 153 255 255 0 +5117 rh.unc 102 153 255 0 +5200 CC-ForcepsMajor 204 102 102 0 +5201 CC-ForcepsMinor 204 102 102 0 +5202 LAntThalRadiation 255 255 102 0 +5203 LCingulumAngBundle 153 204 0 0 +5204 LCingulumCingGyrus 0 153 153 0 +5205 LCorticospinalTract 204 153 255 0 +5206 LInfLongFas 255 153 51 0 +5207 LSupLongFasParietal 204 204 204 0 +5208 LSupLongFasTemporal 153 255 255 0 +5209 LUncinateFas 102 153 255 0 +5210 RAntThalRadiation 255 255 102 0 +5211 RCingulumAngBundle 153 204 0 0 +5212 RCingulumCingGyrus 0 153 153 0 +5213 RCorticospinalTract 204 153 255 0 +5214 RInfLongFas 255 153 51 0 +5215 RSupLongFasParietal 204 204 204 0 +5216 RSupLongFasTemporal 153 255 255 0 +5217 RUncinateFas 102 153 255 0 +6000 CST-orig 0 255 0 0 +6001 CST-hammer 255 255 0 0 +6002 CST-CVS 0 255 255 0 +6003 CST-flirt 0 0 255 0 +6010 Left-SLF1 236 16 231 0 +6020 Right-SLF1 237 18 232 0 +6030 Left-SLF3 236 13 227 0 +6040 Right-SLF3 236 17 228 0 +6050 Left-CST 1 255 1 0 +6060 Right-CST 2 255 1 0 +6070 Left-SLF2 236 14 230 0 +6080 Right-SLF2 237 14 230 0 +7001 Lateral-nucleus 72 132 181 0 +7002 Basolateral-nucleus 243 243 243 0 +7003 Basal-nucleus 207 63 79 0 +7004 Centromedial-nucleus 121 20 135 0 +7005 Central-nucleus 197 60 248 0 +7006 Medial-nucleus 2 149 2 0 +7007 Cortical-nucleus 221 249 166 0 +7008 Accessory-Basal-nucleus 232 146 35 0 +7009 Corticoamygdaloid-transitio 20 60 120 0 +7010 Anterior-amygdaloid-area-AAA 250 250 0 0 +7011 Fusion-amygdala-HP-FAH 122 187 222 0 +7012 Hippocampal-amygdala-transition-HATA 237 12 177 0 +7013 Endopiriform-nucleus 10 49 255 0 +7014 Lateral-nucleus-olfactory-tract 205 184 144 0 +7015 Paralaminar-nucleus 45 205 165 0 +7016 Intercalated-nucleus 117 160 175 0 +7017 Prepiriform-cortex 221 217 21 0 +7018 Periamygdaloid-cortex 20 60 120 0 +7019 Envelope-Amygdala 141 21 100 0 +7020 Extranuclear-Amydala 225 140 141 0 +7100 Brainstem-inferior-colliculus 42 201 168 0 +7101 Brainstem-cochlear-nucleus 168 104 162 0 +8001 Thalamus-Anterior 74 130 181 0 +8002 Thalamus-Ventral-anterior 242 241 240 0 +8003 Thalamus-Lateral-dorsal 206 65 78 0 +8004 Thalamus-Lateral-posterior 120 21 133 0 +8005 Thalamus-Ventral-lateral 195 61 246 0 +8006 Thalamus-Ventral-posterior-medial 3 147 6 0 +8007 Thalamus-Ventral-posterior-lateral 220 251 163 0 +8008 Thalamus-intralaminar 232 146 33 0 +8009 Thalamus-centromedian 4 114 14 0 +8010 Thalamus-mediodorsal 121 184 220 0 +8011 Thalamus-medial 235 11 175 0 +8012 Thalamus-pulvinar 12 46 250 0 +8013 Thalamus-lateral-geniculate 203 182 143 0 +8014 Thalamus-medial-geniculate 42 204 167 0 +9000 ctx-lh-prefrontal 50 100 30 0 +9001 ctx-lh-primary-motor 30 100 45 0 +9002 ctx-lh-premotor 130 100 165 0 +9003 ctx-lh-temporal 105 25 5 0 +9004 ctx-lh-posterior-parietal 125 70 55 0 +9005 ctx-lh-prim-sec-somatosensory 225 20 105 0 +9006 ctx-lh-occipital 225 20 15 0 +9500 ctx-rh-prefrontal 50 200 30 0 +9501 ctx-rh-primary-motor 30 150 45 0 +9502 ctx-rh-premotor 130 150 165 0 +9503 ctx-rh-temporal 105 75 5 0 +9504 ctx-rh-posterior-parietal 125 120 55 0 +9505 ctx-rh-prim-sec-somatosensory 225 70 105 0 +9506 ctx-rh-occipital 225 70 15 0 +11100 ctx_lh_Unknown 0 0 0 0 +11101 ctx_lh_G_and_S_frontomargin 23 220 60 0 +11102 ctx_lh_G_and_S_occipital_inf 23 60 180 0 +11103 ctx_lh_G_and_S_paracentral 63 100 60 0 +11104 ctx_lh_G_and_S_subcentral 63 20 220 0 +11105 ctx_lh_G_and_S_transv_frontopol 13 0 250 0 +11106 ctx_lh_G_and_S_cingul-Ant 26 60 0 0 +11107 ctx_lh_G_and_S_cingul-Mid-Ant 26 60 75 0 +11108 ctx_lh_G_and_S_cingul-Mid-Post 26 60 150 0 +11109 ctx_lh_G_cingul-Post-dorsal 25 60 250 0 +11110 ctx_lh_G_cingul-Post-ventral 60 25 25 0 +11111 ctx_lh_G_cuneus 180 20 20 0 +11112 ctx_lh_G_front_inf-Opercular 220 20 100 0 +11113 ctx_lh_G_front_inf-Orbital 140 60 60 0 +11114 ctx_lh_G_front_inf-Triangul 180 220 140 0 +11115 ctx_lh_G_front_middle 140 100 180 0 +11116 ctx_lh_G_front_sup 180 20 140 0 +11117 ctx_lh_G_Ins_lg_and_S_cent_ins 23 10 10 0 +11118 ctx_lh_G_insular_short 225 140 140 0 +11119 ctx_lh_G_occipital_middle 180 60 180 0 +11120 ctx_lh_G_occipital_sup 20 220 60 0 +11121 ctx_lh_G_oc-temp_lat-fusifor 60 20 140 0 +11122 ctx_lh_G_oc-temp_med-Lingual 220 180 140 0 +11123 ctx_lh_G_oc-temp_med-Parahip 65 100 20 0 +11124 ctx_lh_G_orbital 220 60 20 0 +11125 ctx_lh_G_pariet_inf-Angular 20 60 220 0 +11126 ctx_lh_G_pariet_inf-Supramar 100 100 60 0 +11127 ctx_lh_G_parietal_sup 220 180 220 0 +11128 ctx_lh_G_postcentral 20 180 140 0 +11129 ctx_lh_G_precentral 60 140 180 0 +11130 ctx_lh_G_precuneus 25 20 140 0 +11131 ctx_lh_G_rectus 20 60 100 0 +11132 ctx_lh_G_subcallosal 60 220 20 0 +11133 ctx_lh_G_temp_sup-G_T_transv 60 60 220 0 +11134 ctx_lh_G_temp_sup-Lateral 220 60 220 0 +11135 ctx_lh_G_temp_sup-Plan_polar 65 220 60 0 +11136 ctx_lh_G_temp_sup-Plan_tempo 25 140 20 0 +11137 ctx_lh_G_temporal_inf 220 220 100 0 +11138 ctx_lh_G_temporal_middle 180 60 60 0 +11139 ctx_lh_Lat_Fis-ant-Horizont 61 20 220 0 +11140 ctx_lh_Lat_Fis-ant-Vertical 61 20 60 0 +11141 ctx_lh_Lat_Fis-post 61 60 100 0 +11142 ctx_lh_Medial_wall 25 25 25 0 +11143 ctx_lh_Pole_occipital 140 20 60 0 +11144 ctx_lh_Pole_temporal 220 180 20 0 +11145 ctx_lh_S_calcarine 63 180 180 0 +11146 ctx_lh_S_central 221 20 10 0 +11147 ctx_lh_S_cingul-Marginalis 221 20 100 0 +11148 ctx_lh_S_circular_insula_ant 221 60 140 0 +11149 ctx_lh_S_circular_insula_inf 221 20 220 0 +11150 ctx_lh_S_circular_insula_sup 61 220 220 0 +11151 ctx_lh_S_collat_transv_ant 100 200 200 0 +11152 ctx_lh_S_collat_transv_post 10 200 200 0 +11153 ctx_lh_S_front_inf 221 220 20 0 +11154 ctx_lh_S_front_middle 141 20 100 0 +11155 ctx_lh_S_front_sup 61 220 100 0 +11156 ctx_lh_S_interm_prim-Jensen 141 60 20 0 +11157 ctx_lh_S_intrapariet_and_P_trans 143 20 220 0 +11158 ctx_lh_S_oc_middle_and_Lunatus 101 60 220 0 +11159 ctx_lh_S_oc_sup_and_transversal 21 20 140 0 +11160 ctx_lh_S_occipital_ant 61 20 180 0 +11161 ctx_lh_S_oc-temp_lat 221 140 20 0 +11162 ctx_lh_S_oc-temp_med_and_Lingual 141 100 220 0 +11163 ctx_lh_S_orbital_lateral 221 100 20 0 +11164 ctx_lh_S_orbital_med-olfact 181 200 20 0 +11165 ctx_lh_S_orbital-H_Shaped 101 20 20 0 +11166 ctx_lh_S_parieto_occipital 101 100 180 0 +11167 ctx_lh_S_pericallosal 181 220 20 0 +11168 ctx_lh_S_postcentral 21 140 200 0 +11169 ctx_lh_S_precentral-inf-part 21 20 240 0 +11170 ctx_lh_S_precentral-sup-part 21 20 200 0 +11171 ctx_lh_S_suborbital 21 20 60 0 +11172 ctx_lh_S_subparietal 101 60 60 0 +11173 ctx_lh_S_temporal_inf 21 180 180 0 +11174 ctx_lh_S_temporal_sup 223 220 60 0 +11175 ctx_lh_S_temporal_transverse 221 60 60 0 +12100 ctx_rh_Unknown 0 0 0 0 +12101 ctx_rh_G_and_S_frontomargin 23 220 60 0 +12102 ctx_rh_G_and_S_occipital_inf 23 60 180 0 +12103 ctx_rh_G_and_S_paracentral 63 100 60 0 +12104 ctx_rh_G_and_S_subcentral 63 20 220 0 +12105 ctx_rh_G_and_S_transv_frontopol 13 0 250 0 +12106 ctx_rh_G_and_S_cingul-Ant 26 60 0 0 +12107 ctx_rh_G_and_S_cingul-Mid-Ant 26 60 75 0 +12108 ctx_rh_G_and_S_cingul-Mid-Post 26 60 150 0 +12109 ctx_rh_G_cingul-Post-dorsal 25 60 250 0 +12110 ctx_rh_G_cingul-Post-ventral 60 25 25 0 +12111 ctx_rh_G_cuneus 180 20 20 0 +12112 ctx_rh_G_front_inf-Opercular 220 20 100 0 +12113 ctx_rh_G_front_inf-Orbital 140 60 60 0 +12114 ctx_rh_G_front_inf-Triangul 180 220 140 0 +12115 ctx_rh_G_front_middle 140 100 180 0 +12116 ctx_rh_G_front_sup 180 20 140 0 +12117 ctx_rh_G_Ins_lg_and_S_cent_ins 23 10 10 0 +12118 ctx_rh_G_insular_short 225 140 140 0 +12119 ctx_rh_G_occipital_middle 180 60 180 0 +12120 ctx_rh_G_occipital_sup 20 220 60 0 +12121 ctx_rh_G_oc-temp_lat-fusifor 60 20 140 0 +12122 ctx_rh_G_oc-temp_med-Lingual 220 180 140 0 +12123 ctx_rh_G_oc-temp_med-Parahip 65 100 20 0 +12124 ctx_rh_G_orbital 220 60 20 0 +12125 ctx_rh_G_pariet_inf-Angular 20 60 220 0 +12126 ctx_rh_G_pariet_inf-Supramar 100 100 60 0 +12127 ctx_rh_G_parietal_sup 220 180 220 0 +12128 ctx_rh_G_postcentral 20 180 140 0 +12129 ctx_rh_G_precentral 60 140 180 0 +12130 ctx_rh_G_precuneus 25 20 140 0 +12131 ctx_rh_G_rectus 20 60 100 0 +12132 ctx_rh_G_subcallosal 60 220 20 0 +12133 ctx_rh_G_temp_sup-G_T_transv 60 60 220 0 +12134 ctx_rh_G_temp_sup-Lateral 220 60 220 0 +12135 ctx_rh_G_temp_sup-Plan_polar 65 220 60 0 +12136 ctx_rh_G_temp_sup-Plan_tempo 25 140 20 0 +12137 ctx_rh_G_temporal_inf 220 220 100 0 +12138 ctx_rh_G_temporal_middle 180 60 60 0 +12139 ctx_rh_Lat_Fis-ant-Horizont 61 20 220 0 +12140 ctx_rh_Lat_Fis-ant-Vertical 61 20 60 0 +12141 ctx_rh_Lat_Fis-post 61 60 100 0 +12142 ctx_rh_Medial_wall 25 25 25 0 +12143 ctx_rh_Pole_occipital 140 20 60 0 +12144 ctx_rh_Pole_temporal 220 180 20 0 +12145 ctx_rh_S_calcarine 63 180 180 0 +12146 ctx_rh_S_central 221 20 10 0 +12147 ctx_rh_S_cingul-Marginalis 221 20 100 0 +12148 ctx_rh_S_circular_insula_ant 221 60 140 0 +12149 ctx_rh_S_circular_insula_inf 221 20 220 0 +12150 ctx_rh_S_circular_insula_sup 61 220 220 0 +12151 ctx_rh_S_collat_transv_ant 100 200 200 0 +12152 ctx_rh_S_collat_transv_post 10 200 200 0 +12153 ctx_rh_S_front_inf 221 220 20 0 +12154 ctx_rh_S_front_middle 141 20 100 0 +12155 ctx_rh_S_front_sup 61 220 100 0 +12156 ctx_rh_S_interm_prim-Jensen 141 60 20 0 +12157 ctx_rh_S_intrapariet_and_P_trans 143 20 220 0 +12158 ctx_rh_S_oc_middle_and_Lunatus 101 60 220 0 +12159 ctx_rh_S_oc_sup_and_transversal 21 20 140 0 +12160 ctx_rh_S_occipital_ant 61 20 180 0 +12161 ctx_rh_S_oc-temp_lat 221 140 20 0 +12162 ctx_rh_S_oc-temp_med_and_Lingual 141 100 220 0 +12163 ctx_rh_S_orbital_lateral 221 100 20 0 +12164 ctx_rh_S_orbital_med-olfact 181 200 20 0 +12165 ctx_rh_S_orbital-H_Shaped 101 20 20 0 +12166 ctx_rh_S_parieto_occipital 101 100 180 0 +12167 ctx_rh_S_pericallosal 181 220 20 0 +12168 ctx_rh_S_postcentral 21 140 200 0 +12169 ctx_rh_S_precentral-inf-part 21 20 240 0 +12170 ctx_rh_S_precentral-sup-part 21 20 200 0 +12171 ctx_rh_S_suborbital 21 20 60 0 +12172 ctx_rh_S_subparietal 101 60 60 0 +12173 ctx_rh_S_temporal_inf 21 180 180 0 +12174 ctx_rh_S_temporal_sup 223 220 60 0 +12175 ctx_rh_S_temporal_transverse 221 60 60 0 +13100 wm_lh_Unknown 0 0 0 0 +13101 wm_lh_G_and_S_frontomargin 23 220 60 0 +13102 wm_lh_G_and_S_occipital_inf 23 60 180 0 +13103 wm_lh_G_and_S_paracentral 63 100 60 0 +13104 wm_lh_G_and_S_subcentral 63 20 220 0 +13105 wm_lh_G_and_S_transv_frontopol 13 0 250 0 +13106 wm_lh_G_and_S_cingul-Ant 26 60 0 0 +13107 wm_lh_G_and_S_cingul-Mid-Ant 26 60 75 0 +13108 wm_lh_G_and_S_cingul-Mid-Post 26 60 150 0 +13109 wm_lh_G_cingul-Post-dorsal 25 60 250 0 +13110 wm_lh_G_cingul-Post-ventral 60 25 25 0 +13111 wm_lh_G_cuneus 180 20 20 0 +13112 wm_lh_G_front_inf-Opercular 220 20 100 0 +13113 wm_lh_G_front_inf-Orbital 140 60 60 0 +13114 wm_lh_G_front_inf-Triangul 180 220 140 0 +13115 wm_lh_G_front_middle 140 100 180 0 +13116 wm_lh_G_front_sup 180 20 140 0 +13117 wm_lh_G_Ins_lg_and_S_cent_ins 23 10 10 0 +13118 wm_lh_G_insular_short 225 140 140 0 +13119 wm_lh_G_occipital_middle 180 60 180 0 +13120 wm_lh_G_occipital_sup 20 220 60 0 +13121 wm_lh_G_oc-temp_lat-fusifor 60 20 140 0 +13122 wm_lh_G_oc-temp_med-Lingual 220 180 140 0 +13123 wm_lh_G_oc-temp_med-Parahip 65 100 20 0 +13124 wm_lh_G_orbital 220 60 20 0 +13125 wm_lh_G_pariet_inf-Angular 20 60 220 0 +13126 wm_lh_G_pariet_inf-Supramar 100 100 60 0 +13127 wm_lh_G_parietal_sup 220 180 220 0 +13128 wm_lh_G_postcentral 20 180 140 0 +13129 wm_lh_G_precentral 60 140 180 0 +13130 wm_lh_G_precuneus 25 20 140 0 +13131 wm_lh_G_rectus 20 60 100 0 +13132 wm_lh_G_subcallosal 60 220 20 0 +13133 wm_lh_G_temp_sup-G_T_transv 60 60 220 0 +13134 wm_lh_G_temp_sup-Lateral 220 60 220 0 +13135 wm_lh_G_temp_sup-Plan_polar 65 220 60 0 +13136 wm_lh_G_temp_sup-Plan_tempo 25 140 20 0 +13137 wm_lh_G_temporal_inf 220 220 100 0 +13138 wm_lh_G_temporal_middle 180 60 60 0 +13139 wm_lh_Lat_Fis-ant-Horizont 61 20 220 0 +13140 wm_lh_Lat_Fis-ant-Vertical 61 20 60 0 +13141 wm_lh_Lat_Fis-post 61 60 100 0 +13142 wm_lh_Medial_wall 25 25 25 0 +13143 wm_lh_Pole_occipital 140 20 60 0 +13144 wm_lh_Pole_temporal 220 180 20 0 +13145 wm_lh_S_calcarine 63 180 180 0 +13146 wm_lh_S_central 221 20 10 0 +13147 wm_lh_S_cingul-Marginalis 221 20 100 0 +13148 wm_lh_S_circular_insula_ant 221 60 140 0 +13149 wm_lh_S_circular_insula_inf 221 20 220 0 +13150 wm_lh_S_circular_insula_sup 61 220 220 0 +13151 wm_lh_S_collat_transv_ant 100 200 200 0 +13152 wm_lh_S_collat_transv_post 10 200 200 0 +13153 wm_lh_S_front_inf 221 220 20 0 +13154 wm_lh_S_front_middle 141 20 100 0 +13155 wm_lh_S_front_sup 61 220 100 0 +13156 wm_lh_S_interm_prim-Jensen 141 60 20 0 +13157 wm_lh_S_intrapariet_and_P_trans 143 20 220 0 +13158 wm_lh_S_oc_middle_and_Lunatus 101 60 220 0 +13159 wm_lh_S_oc_sup_and_transversal 21 20 140 0 +13160 wm_lh_S_occipital_ant 61 20 180 0 +13161 wm_lh_S_oc-temp_lat 221 140 20 0 +13162 wm_lh_S_oc-temp_med_and_Lingual 141 100 220 0 +13163 wm_lh_S_orbital_lateral 221 100 20 0 +13164 wm_lh_S_orbital_med-olfact 181 200 20 0 +13165 wm_lh_S_orbital-H_Shaped 101 20 20 0 +13166 wm_lh_S_parieto_occipital 101 100 180 0 +13167 wm_lh_S_pericallosal 181 220 20 0 +13168 wm_lh_S_postcentral 21 140 200 0 +13169 wm_lh_S_precentral-inf-part 21 20 240 0 +13170 wm_lh_S_precentral-sup-part 21 20 200 0 +13171 wm_lh_S_suborbital 21 20 60 0 +13172 wm_lh_S_subparietal 101 60 60 0 +13173 wm_lh_S_temporal_inf 21 180 180 0 +13174 wm_lh_S_temporal_sup 223 220 60 0 +13175 wm_lh_S_temporal_transverse 221 60 60 0 +14100 wm_rh_Unknown 0 0 0 0 +14101 wm_rh_G_and_S_frontomargin 23 220 60 0 +14102 wm_rh_G_and_S_occipital_inf 23 60 180 0 +14103 wm_rh_G_and_S_paracentral 63 100 60 0 +14104 wm_rh_G_and_S_subcentral 63 20 220 0 +14105 wm_rh_G_and_S_transv_frontopol 13 0 250 0 +14106 wm_rh_G_and_S_cingul-Ant 26 60 0 0 +14107 wm_rh_G_and_S_cingul-Mid-Ant 26 60 75 0 +14108 wm_rh_G_and_S_cingul-Mid-Post 26 60 150 0 +14109 wm_rh_G_cingul-Post-dorsal 25 60 250 0 +14110 wm_rh_G_cingul-Post-ventral 60 25 25 0 +14111 wm_rh_G_cuneus 180 20 20 0 +14112 wm_rh_G_front_inf-Opercular 220 20 100 0 +14113 wm_rh_G_front_inf-Orbital 140 60 60 0 +14114 wm_rh_G_front_inf-Triangul 180 220 140 0 +14115 wm_rh_G_front_middle 140 100 180 0 +14116 wm_rh_G_front_sup 180 20 140 0 +14117 wm_rh_G_Ins_lg_and_S_cent_ins 23 10 10 0 +14118 wm_rh_G_insular_short 225 140 140 0 +14119 wm_rh_G_occipital_middle 180 60 180 0 +14120 wm_rh_G_occipital_sup 20 220 60 0 +14121 wm_rh_G_oc-temp_lat-fusifor 60 20 140 0 +14122 wm_rh_G_oc-temp_med-Lingual 220 180 140 0 +14123 wm_rh_G_oc-temp_med-Parahip 65 100 20 0 +14124 wm_rh_G_orbital 220 60 20 0 +14125 wm_rh_G_pariet_inf-Angular 20 60 220 0 +14126 wm_rh_G_pariet_inf-Supramar 100 100 60 0 +14127 wm_rh_G_parietal_sup 220 180 220 0 +14128 wm_rh_G_postcentral 20 180 140 0 +14129 wm_rh_G_precentral 60 140 180 0 +14130 wm_rh_G_precuneus 25 20 140 0 +14131 wm_rh_G_rectus 20 60 100 0 +14132 wm_rh_G_subcallosal 60 220 20 0 +14133 wm_rh_G_temp_sup-G_T_transv 60 60 220 0 +14134 wm_rh_G_temp_sup-Lateral 220 60 220 0 +14135 wm_rh_G_temp_sup-Plan_polar 65 220 60 0 +14136 wm_rh_G_temp_sup-Plan_tempo 25 140 20 0 +14137 wm_rh_G_temporal_inf 220 220 100 0 +14138 wm_rh_G_temporal_middle 180 60 60 0 +14139 wm_rh_Lat_Fis-ant-Horizont 61 20 220 0 +14140 wm_rh_Lat_Fis-ant-Vertical 61 20 60 0 +14141 wm_rh_Lat_Fis-post 61 60 100 0 +14142 wm_rh_Medial_wall 25 25 25 0 +14143 wm_rh_Pole_occipital 140 20 60 0 +14144 wm_rh_Pole_temporal 220 180 20 0 +14145 wm_rh_S_calcarine 63 180 180 0 +14146 wm_rh_S_central 221 20 10 0 +14147 wm_rh_S_cingul-Marginalis 221 20 100 0 +14148 wm_rh_S_circular_insula_ant 221 60 140 0 +14149 wm_rh_S_circular_insula_inf 221 20 220 0 +14150 wm_rh_S_circular_insula_sup 61 220 220 0 +14151 wm_rh_S_collat_transv_ant 100 200 200 0 +14152 wm_rh_S_collat_transv_post 10 200 200 0 +14153 wm_rh_S_front_inf 221 220 20 0 +14154 wm_rh_S_front_middle 141 20 100 0 +14155 wm_rh_S_front_sup 61 220 100 0 +14156 wm_rh_S_interm_prim-Jensen 141 60 20 0 +14157 wm_rh_S_intrapariet_and_P_trans 143 20 220 0 +14158 wm_rh_S_oc_middle_and_Lunatus 101 60 220 0 +14159 wm_rh_S_oc_sup_and_transversal 21 20 140 0 +14160 wm_rh_S_occipital_ant 61 20 180 0 +14161 wm_rh_S_oc-temp_lat 221 140 20 0 +14162 wm_rh_S_oc-temp_med_and_Lingual 141 100 220 0 +14163 wm_rh_S_orbital_lateral 221 100 20 0 +14164 wm_rh_S_orbital_med-olfact 181 200 20 0 +14165 wm_rh_S_orbital-H_Shaped 101 20 20 0 +14166 wm_rh_S_parieto_occipital 101 100 180 0 +14167 wm_rh_S_pericallosal 181 220 20 0 +14168 wm_rh_S_postcentral 21 140 200 0 +14169 wm_rh_S_precentral-inf-part 21 20 240 0 +14170 wm_rh_S_precentral-sup-part 21 20 200 0 +14171 wm_rh_S_suborbital 21 20 60 0 +14172 wm_rh_S_subparietal 101 60 60 0 +14173 wm_rh_S_temporal_inf 21 180 180 0 +14174 wm_rh_S_temporal_sup 223 220 60 0 +14175 wm_rh_S_temporal_transverse 221 60 60 0 +1701 ctx_lh_AnteroHippocampus 0 0 0 0 +1702 ctx_lh_PosteroHippocampus 0 0 0 0 +5301 ctx_rh_AnteroHippocampus 0 0 0 0 +5302 ctx_rh_PosteroHippocampus 0 0 0 0 diff --git a/generate_boundaries.py b/generate_boundaries.py new file mode 100644 index 0000000..10d869e --- /dev/null +++ b/generate_boundaries.py @@ -0,0 +1,12 @@ +from soma import aims +import pdb + +mesh_filename = '/home/b67-belledone/Desktop/epilepsie-manik/MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/inflatedGre_2016_MNI1_Lwhite.gii' +regions_texture_filename = '/home/b67-belledone/Desktop/epilepsie-manik/MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_Lwhite_parcels_marsAtlas.gii' +boundaries_filename = '/tmp/inflated_marsatlas_boundariesL.mesh' + +mesh = aims.read(mesh_filename) +regions_texture = aims.read(regions_texture_filename) +boundaries = aims.SurfaceManip.meshTextureBoundary(mesh, regions_texture, -1) +boundaries.header()['material'] = { 'diffuse': [1., 0., 0., 1.], 'line_width': 6} +aims.write(boundaries, boundaries_filename) \ No newline at end of file diff --git a/generate_contact_colors.py b/generate_contact_colors.py new file mode 100644 index 0000000..350cb44 --- /dev/null +++ b/generate_contact_colors.py @@ -0,0 +1,97 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import openpyxl, json, os +import pdb +import difflib #to get closest match + + + +class generate_contact_colors: + """to present results of cognition/stimulation""" + + def __init__(self): + + self.output = {} + + def from_excel_files(self,filename,save=False): + + excel_data = openpyxl.load_workbook(filename) + + worksheet_names = excel_data.get_sheet_names() + + output_info = {worksheet_names[x]:{} for x in range(len(worksheet_names))} + + #pour les fréquences + freq_possible = ['1 Hz', '50 Hz'] + amplitude_possible = [] + + for worksheet_index in worksheet_names: + datasheeti = excel_data[worksheet_index] + + #always assume first line is "title condition" and first column is "contact or bipole" as written in the IntrAnat Electrodes software + title_condi={} + contact_labels = {} + for i_row in range(1,datasheeti.max_row+1): + skip_this_line = 0 + for i_column in range(1,datasheeti.max_column+1): + + + #print(i_row,i_column) + actual_cell = datasheeti.cell(row=i_row, column = i_column) + backcolor = actual_cell.fill.start_color.index + fontcolor = actual_cell.font.color.rgb + if i_row == 1: + title_condi.update({actual_cell.value:{}}) + title_condi[actual_cell.value].update({'title_backcolor':self.hexa2irgbtupple(backcolor),'title_fontcolor':self.hexa2irgbtupple(fontcolor)}) + else: + second_label = datasheeti.cell(row=i_row, column = 2) + if i_column == 1: + if actual_cell.value not in contact_labels.keys(): + contact_labels.update({actual_cell.value:{'cell':{},'line':{'backcolor':self.hexa2irgbtupple(backcolor),'fontcolor':self.hexa2irgbtupple(fontcolor)}}}) #second_label.value:{} + else: + #find row and column title + row_title_cell = datasheeti.cell(row = i_row, column = 1) + column_title_cell = datasheeti.cell(row = 1, column = i_column) + row_title = row_title_cell.value + column_title = column_title_cell.value + + if i_column == 2: + if actual_cell.value in contact_labels[row_title]['cell'].keys(): + if 'Type of response' in contact_labels[row_title]['cell'][actual_cell.value].keys(): + #bipole already stimulated with this "frequency/task", data overwrite only if there was a clinical response + #should check the mA ? + if (contact_labels[row_title]['cell'][actual_cell.value]['Type of response']['value'] != u'Absent') and (contact_labels[row_title]['cell'][actual_cell.value]['Type of response'] != 0): + skip_this_line = 1 + continue + else: + contact_labels[row_title]['cell'][actual_cell.value].update({}) + else: + pdb.set_trace() + else: + contact_labels[row_title]['cell'].update({actual_cell.value:{}}) + #[second_label.value].update({column_title:{'value':actual_cell.value,'backcolor':self.hexa2irgbtupple(backcolor),'fontcolor':self.hexa2irgbtupple(fontcolor)}}) + else: + if skip_this_line == 0: + contact_labels[row_title]['cell'][second_label.value].update({column_title:{'value':actual_cell.value,'backcolor':self.hexa2irgbtupple(backcolor),'fontcolor':self.hexa2irgbtupple(fontcolor)}}) + + if save: + path_to_save = os.path.dirname(filename) + filename_wh_ext = os.path.basename(filename).split('.')[0] + new_filename = path_to_save + os.path.sep + filename_wh_ext + '.json' + fout = open(new_filename,'w') + fout.write(json.dumps({'title':title_condi,'contacts':contact_labels})) + fout.close() + + else: + return (title_condi,contact_labels) + + def hexa2irgbtupple(self,string_hexa): + + try: + rgbtupple = (int(string_hexa[0:2],16),int(string_hexa[2:4],16),int(string_hexa[4:6],16),int(string_hexa[6:8],16)) + except: + rgbtupple = (255,0,0,0) #default is black + + return rgbtupple + \ No newline at end of file diff --git a/getTRCpatientData.c b/getTRCpatientData.c new file mode 100644 index 0000000..498835a --- /dev/null +++ b/getTRCpatientData.c @@ -0,0 +1,74 @@ +#include +#include +/** + * ANONYMIZATION Of patient data in Micromed TRC files + * + * (c) Inserm U836 2014 - Manik Bhattacharjee + * + * License GNU GPL v3 +*/ + +/** + From TRC format description "System 98 - Type "4" EEG FILE STRUCTURE DESCRIPTION (Micromed) + Offset of patient data, offset of acquisition date/time +*/ +#define PATIENT_DATA_OFFSET 64 +#define PATIENT_DATA_NAME_SIZE 22 +#define PATIENT_DATA_FIRSTNAME_SIZE 20 +#define PATIENT_BIRTH_DATE_SIZE 3 +#define DATE_OFFSET 128 +#define TIME_OFFSET 131 +#define SPACE_CHAR 32 //Ascii code + +int main(int argc, char **argv){ + int length, remains, i; + char name[PATIENT_DATA_NAME_SIZE +1 ] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + char firstname[PATIENT_DATA_FIRSTNAME_SIZE +1 ] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + unsigned char month, day, year, hours, minutes, seconds; + if (argc != 2){ + printf("Usage : getTRCpatientData file.trc\n"); + return -1; + } + // Opening file read binary mode + FILE *const fp = fopen(argv[1], "rb"); + if (!fp){ + printf("Cannot open TRC file\n"); + return -1; + } + if (fseek(fp, PATIENT_DATA_OFFSET, SEEK_SET) != 0){ + printf("Cannot go to Patient data section in TRC file !\n"); + return -1; + } + // Patient Last name + fread (name, 1, PATIENT_DATA_NAME_SIZE, fp); + + //Patient First name + fread (name, 1, PATIENT_DATA_FIRSTNAME_SIZE, fp); + + //Patient birth date + month = fgetc(fp); + day = fgetc(fp); + year = fgetc(fp); + printf("Subject : %s %s, born %d/%d/%d\n", firstname, name, day, month, year/100 > 0?2000+year%100:1900+year); + + if (fseek(fp, DATE_OFFSET, SEEK_SET) != 0){ + printf("Cannot go to Date data section in TRC file !\n"); + return -1; + } + day = fgetc(fp); + month = fgetc(fp); + year = fgetc(fp); + + if (fseek(fp, TIME_OFFSET, SEEK_SET) != 0){ + printf("Cannot go to Time data section in TRC file !\n"); + return -1; + } + hours = fgetc(fp); + minutes = fgetc(fp); + seconds = fgetc(fp); + + printf("Acquisition : %d/%d/%d %d:%d:%d\n", day, month, year/100 > 0?2000+year%100:1900+year, hours, minutes, seconds); + printf("GRE_%d_%c%c%c%c\n", year/100 > 0?2000+year%100:1900+year, name[0], name[1], name[2], firstname[0]); + + fclose(fp); +} diff --git a/greendot.png b/greendot.png new file mode 100644 index 0000000000000000000000000000000000000000..733432d6f209222aa75bb2af138e26e6dc542f5e GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z8pdfpRr>`sfJyvl6WkwUX%X&Z|$r9Iy66gHf+|;}h2Ir#G#FEq$h4Rdj z3QvV-O}#cx?2 z#x=8gUibXJ_NELg{C?hiK2Pz{xi{}^c?7lN8G9eveAuF527349m_Q=Qe86JwUZ@*n#SN2o4{V==x> intranat-locateElectrodes-`whoami`.log +date >> intranat-locateElectrodes-`whoami`.log +python groupDisplay.py >> intranat-locateElectrodes-`whoami`.log + diff --git a/groupPlots.ui b/groupPlots.ui new file mode 100644 index 0000000..ea65965 --- /dev/null +++ b/groupPlots.ui @@ -0,0 +1,442 @@ + + + Widget + + + + 0 + 0 + 869 + 862 + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Patients + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Electrodes + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Plots + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + Implantation Statistics: + + + + + + Generate Stats with Selection + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + Ajouter les plots choisis à la sélection + + + -> + + + + + + + + 0 + 0 + + + + Supprimer de la sélection + + + <- + + + + + + + MarsAtlas Parcels + + + + + + + + + + FreeSurfer Parcels + + + + + + + + + + Broadmann Parcels + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Selection + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + + Rm Left Plots + + + + + + + Rm Right Plots + + + + + + + + + Remove Plots not in TRC + + + + + + + + + both Hemi + + + true + + + buttonGroupBothOrRightHemi + + + + + + + All contacts to Right + + + buttonGroupBothOrRightHemi + + + + + + + + + + + Contact Display + + + true + + + buttonGroupContactOrsEEG + + + + + + + sEEG Results Display + + + buttonGroupContactOrsEEG + + + + + + + + + Select around the cursor + + + + + + + + + + + + + + + + + radius : + + + + + + + mm + + + 1 + + + 20.000000000000000 + + + + + + + + + + 0 + 0 + + + + Display + + + + + + + 0 + 0 + + + + + + + + Add + + + + + + + Add Image (in MNI) to List + + + + + + + Add mesh/texture (in MNI) to List + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + diff --git a/identity.trm b/identity.trm new file mode 100644 index 0000000..9dc071a --- /dev/null +++ b/identity.trm @@ -0,0 +1,5 @@ +0 0 0 +1 0 0 +0 1 0 +0 0 1 + diff --git a/locateContacts.py b/locateContacts.py new file mode 100644 index 0000000..508d7cd --- /dev/null +++ b/locateContacts.py @@ -0,0 +1,572 @@ +import math +import pdb +from scipy import ndimage +from numpy import * +from soma import aims + + + +def norme3D(vect): + return math.sqrt(vect[0]**2+vect[1]**2+vect[2]**2) + +def vecteur(a,b): + return (b[0]-a[0],b[1]-a[1],b[2]-a[2]) + +def findMoyMax(npCT,sizex,sizey,sizez,volCT,entry,d,s1n,coteRegionX,coteRegionY,coteRegionZ,CT): + #initialization of variables + maxi=0 + inc=0 + if CT==True: + compX1=s1n[0]/sizex-coteRegionX + compX2=s1n[0]/sizex+coteRegionX + compY1=s1n[1]/sizey-coteRegionY + compY2=s1n[1]/sizey+coteRegionY + compZ1=s1n[2]/sizez-coteRegionZ + compZ2=s1n[2]/sizez+coteRegionZ + if compZ1 <=0: + compZ1=0 + if compY1 <=0: + compY1=0 + if compX1 <=0: + compX1=0 + if compX2>= len(npCT[0][0])-1: + compX2= len(npCT[0][0])-1 + if compY2>= len(npCT[0][0])-1: + compY2= len(npCT[0][0])-1 + if compZ2>= len(npCT[0][0])-1: + compZ2= len(npCT[0][0])-1 + else: + compX1=s1n[0]-coteRegionX + compX2=s1n[0]+coteRegionX + compY1=s1n[1]-coteRegionY + compY2=s1n[1]+coteRegionY + compZ1=s1n[2]-coteRegionZ + compZ2=s1n[2]+coteRegionZ + if compZ1 <=0: + compZ1=0 + if compY1 <=0: + compY1=0 + if compX1 <=0: + compX1=0 + if compX2>= len(npCT[0][0])-1: + compX2= len(npCT[0][0])-1 + if compY2>= len(npCT[0][0])-1: + compY2= len(npCT[0][0])-1 + if compZ2>= len(npCT[0][0])-1: + compZ2= len(npCT[0][0])-1 + + print "compX1",compX1,"compX2",compX2,"compY1",compY1,"compY2",compY2,"compZ1",compZ1,"compZ2",compZ2 + + #we will do the computation until we find a value higher than 1500 + while maxi==0 and inc<1000: + #print "compX1",compX1,"compX2",compX2,"compY1",compY1,"compY2",compY2,"compZ1",compZ1,"compZ2",compZ2 + #computation in a CT + if CT==True: + #we take out any values less than 2500 + newnpCT=npCT[0,round(compZ1):round(compZ2),round(compY1):round(compY2),round(compX1):round(compX2)] + newnpCT=newnpCT.clip(1500) + newnpCT[newnpCT==1500]=0 + #We make an opening + CTopened=ndimage.grey_opening(newnpCT, size=(int(round(1.4/sizez)),int(round(1.4/sizey)),int(round(1.4/sizex)))) #en mm ca soit isotropic + newnpCT=npCT[0,round(compZ1):round(compZ2),round(compY1):round(compY2),round(compX1):round(compX2)] + newnpCT=newnpCT.clip(1500) + newnpCT[newnpCT==1500]=0 + else: + #we take out any values above 50 + newnpCT=npCT[0,round(compZ1):round(compZ2),round(compY1):round(compY2),round(compX1):round(compX2)] + newnpCT=newnpCT.clip(0,50) + newnpCT[newnpCT==50]=0 + #We make an opening + CTopened=ndimage.grey_opening(newnpCT, size=(int(round(1.4/sizez)),int(round(1.4/sizey)),int(round(1.4/sizex)))) #en mm ca soit isotropic + newnpCT=npCT[0,round(compZ1):round(compZ2),round(compY1):round(compY2),round(compX1):round(compX2)] + newnpCT=newnpCT.clip(0,100) + newnpCT[newnpCT==100]=0 + try: + maxi=CTopened.max() + except: + pdb.set_trace() + #if the opening was too strong and didn't keep any values but the original array had value>1500 we keep the newnpCT (original one) + if maxi==0 and newnpCT.max()!=0: + CTopened=newnpCT + maxi=newnpCT.max() + #if there is nothing near we open the ROI + if (maxi<2500 and CT==True) or (CT==False and maxi>50 ) or maxi==0: + compX1-=sizex + if compX1<= 0: + compX1= 0 + + compX2+=sizex + if compX2>= len(npCT[0][0][0])-1: + compX2= len(npCT[0][0][0])-1 + + compY1-=sizey + if compY1<= 0: + compY1= 0 + + compY2+=sizey + if compY2>= len(npCT[0][0])-1: + compY2= len(npCT[0][0])-1 + + compZ1-=sizez + if compZ1<= 0: + compZ1= 0 + + compZ2+=sizez + if compZ2>= len(npCT[0])-1: + compZ2= len(npCT[0])-1 + + maxi=0 + + inc+=1 + + #calculation of the center of mass + (lbl,numfeatures)=ndimage.label(CTopened) + centre=ndimage.measurements.center_of_mass(CTopened,lbl,range(1,numfeatures+1)) + #if there is one center + if numfeatures==1: + moy = ndimage.measurements.center_of_mass(CTopened) + #if there are more than 5 centers of mass we put moy to none + elif numfeatures>5: + print "trop de centres de masse" + moy=None + #if there are between 3 and 5 centers of mass we take the 2 bigger ones + elif numfeatures>2 and numfeatures<6: + p=1 + to={} + suppr=[] + #we determine the size of each centers + while p<=lbl.max(): + val=where(lbl==p) + tailleVal={p:len(val[0])} + to.update(tailleVal) + p+=1 + #sort the sizes and only keep the 2 biggest ones + tailles=[x for x in to.values()] + tailles.sort() + del tailles[-2:] + + #then we know wich centers to suppress... + for el in tailles: + for cle, valeur in tailleVal.items(): + if valeur==el: + suppr.append(cle) + #...and suppress them + for el in suppr: + lbl[lbl==el]=0 + #we then compute the centers of mass, since we do not know on wich axis they are, we first try with [0,1], if one of the centers is (nan,nan,nan) we try with [1,2] + centre=ndimage.measurements.center_of_mass(CTopened,lbl,[0,1]) + if isnan(centre[0][0])==True: + centre=ndimage.measurements.center_of_mass(CTopened,lbl,[1,2]) + + #we calculate the coordinates in the CT native space in order to calculate the distance with the first approximation + centre0=(centre[0][2]+compX1*sizex,centre[0][1]+compY1*sizey,centre[0][0]+compZ1*sizez) + centre1=(centre[1][2]+compX1*sizex,centre[1][1]+compY1*sizey,centre[1][0]+compZ1*sizez) + entCentre0=vecteur(entry,centre0) + dist0=norme3D(entCentre0) + entCentre1=vecteur(entry,centre1) + dist1=norme3D(entCentre1) + #we only take the one that is nearest to the point we first approximated + if dist0>dist1: + moy=centre[1] + else: + moy=centre[0] + #here is the case where nothing goes wrong + else: + centre0=(centre[0][2]+compX1*sizex,centre[0][1]+compY1*sizey,centre[0][0]+compZ1*sizez) + centre1=(centre[1][2]+compX1*sizex,centre[1][1]+compY1*sizey,centre[1][0]+compZ1*sizez) + entCentre0=vecteur(entry,centre0) + dist0=norme3D(entCentre0) + entCentre1=vecteur(entry,centre1) + dist1=norme3D(entCentre1) + if dist0>dist1: + moy=centre[1] + else: + moy=centre[0] + #if we have a center we will also calculate its distance with the previous plot + if moy is not None: + moyverif=((moy[2]+compX1)*sizex,(moy[1]+compY1)*sizey,(moy[0]+compZ1)*sizez) + verif=norme3D(vecteur(entry,moyverif)) + emVect=vecteur(entry,moyverif) + #if the plot found is too far we put moy to none + if d!=0 and verif>d*1.3: + moy=None + print "too far" + #this is the case where we approximate the target, we want it at most 2mm far from the theoretical target + elif d==0 and verif>2: + moy=None + print "verif:" ,verif + #if the plot is too close + elif d!=0 and verif0.04 and ite<10000: + #initialization of variables + npCTtempo=None + aa=0 + + #We launch the approximation a first time in order to know if moy is none + if j==0: + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,entry,d,s1n,coteRegionX,coteRegionY,coteRegionZ,CT) + else: + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,entry,d,replace,coteRegionX,coteRegionY,coteRegionZ,CT) + + #print "moy",moy + #if moy is none we want to get out of the while + if moy is None: + error=0 + else: + error=abs(norme3D(moyt)-norme3D(moy)) + replace=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + moyt=moy + ite+=1 + j+=1 + #we lauch the approximation of the center of mass once + if moy is None: + if s1n==point: + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,point,0,s1n,coteRegionX,coteRegionY,coteRegionZ,CT) + else: + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,point,0.2,s1n,coteRegionX,coteRegionY,coteRegionZ,CT) + #if the computations fail at this point, we will give it the first approximation + if moy is None: + appPointret=s1n + + #transformation of the center of mass found to the CT natif space + else: + appPointret=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + else: + appPointret=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + #print "appPointret: ",appPointret + return appPointret + + +def locateContacts(target,entry,npCT,volCT,nbContacts,sizex,sizey,sizez,do,transfo_pre_to_postopInv,brainMask,sizeT1,dicPoints,serpentin,transfo_pre_to_postop,CT): + #entry et target dans le repere CT natif + #variables' initialization + targetH=target + entryH=entry + contacts={} + i=0 + theta=0 + signex={} + signey={} + signez={} + angles={} + theta=0 + #counts the number of times moy is returned none + compteurMoy=0 + + #Approximation for each contacts, we start at the theoretical target, wich will also be approximated + #it has to be noted that the entry is after the first iteration the current approximated plot, and target the previous one + while i1: + aa=1.0005 + b=0.9994 + enS1=vecteur(entry,s1n) + enS1Norm=norme3D(enS1) + while enS1Norm<(do[i]-0.4) or enS1Norm>(do[i]+0.4): + if enS1Norm1: + prepre=target + target=entry + #print "target 312 : ", target + if i>0: + entry=appPoint + #print "entry 315: ",entry + vect11=vecteur(target,entry) + #Calculation of the angle between the two vectors joining 3 consecutive points, last one being the current approximated point. + if i>1: + try: + theta=math.acos(vdot(vect11,vect12)/(norme3D(vect11)*norme3D(vect12))) + #print theta + #if it can't be done it is often because the vectors are identical, so we instanciate theta to 0 + except: + theta=0 + + + #We store the angles in order to be able to reduce deviations + if i>1: + signex.update({i:((appPoint[0]-target[0])/abs(appPoint[0]-target[0]))}) + signey.update({i:((appPoint[1]-target[1])/abs(appPoint[1]-target[1]))}) + signez.update({i:((appPoint[2]-target[2])/abs(appPoint[2]-target[2]))}) + angle={i:theta} + angles.update(angle) + + #target becomes the approximated one + if i==0: + target=appPoint + #print "target 338: ", target + if i>0: + vect12=vect11 + entry=appPoint + #print "entry 342: ",entry + + #print entry + #Transformation of the found plot to the T1 natif referential + appPointtemp=(appPoint[0],appPoint[1],appPoint[2]) + appPointtemp=list(appPointtemp) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + appPointT1nat=tuple(point) + contact={i:appPointT1nat} + contacts.update(contact) + + if serpentin==True: + if i>2: + if (signex[i-1]-signex[i]!=0 or signey[i-1]-signey[i]!=0 or signey[i-1]-signey[i]!=0) and angles[i]>0.05 and angles[i-1]>0.05: + prepreNorm=norme3D(vecteur(prepre,entry)) + coef=do[i-1]/prepreNorm + target=((entry[0]-prepre[0])*coef+prepre[0],(entry[1]-prepre[1])*coef+prepre[1],(entry[2]-prepre[2])*coef+prepre[2]) + #print "target 363 : ", target + appPointtemp=(target[0],target[1],target[2]) + appPointtemp=list(appPointtemp) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + appPointT1nat=tuple(point) + contacts[i-1]=appPointT1nat + print "modif 410" + + else: + if appPoint==s1n: + #increases the number of times moy is none + compteurMoy+=1 + if compteurMoy>1: + print "trop de moy=None" + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,dicPoints[i+1],0.2,dicPoints[i+1],coteRegionX,coteRegionY,coteRegionZ,CT) + if moy is not None: + appPoint=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + print "appPoint: ", appPoint + #print "entry 383: ", entry + else: + appPoint=dicPoints[i+1] + #print "entry 386 :",entry + compteurMoy=0 + #Transformation of the found plot to the T1 natif referential + appPointtemp=(appPoint[0],appPoint[1],appPoint[2]) + appPointtemp=list(appPointtemp) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + appPointT1nat=tuple(point) + contacts[i]=appPointT1nat + print "modif 437" + try: + coef1=(do[i-1]+do[i-2])/norme3D(vecteur(contacts[i-3],contacts[i])) + contacts[i-1]=(coef1*(appPointT1nat[0]-contacts[i-3][0])+contacts[i-3][0],coef1*(appPointT1nat[1]-contacts[i-3][1])+contacts[i-3][1],coef1*(appPointT1nat[2]-contacts[i-3][2])+contacts[i-3][2]) + coef2=do[i-2]/norme3D(vecteur(contacts[i-3],contacts[i])) + contacts[i-2]=(coef2*(appPointT1nat[0]-contacts[i-3][0])+contacts[i-3][0],coef2*(appPointT1nat[1]-contacts[i-3][1])+contacts[i-3][1],coef2*(appPointT1nat[2]-contacts[i-3][2])+contacts[i-3][2]) + except: + try: + coef2=do[i-1]/norme3D(vecteur(contacts[i-2],contacts[i])) + contacts[i-1]=(coef2*(appPointT1nat[0]-contacts[i-2][0])+contacts[i-2][0],coef2*(appPointT1nat[1]-contacts[i-2][1])+contacts[i-2][1],coef2*(appPointT1nat[2]-contacts[i-2][2])+contacts[i-2][2]) + except: + print "modif 450" + #print "a" + entry=appPoint + #print "entry 408: ", entry + #Transformation of the found plot to the T1 natif referential + appPointtemp=(contacts[i-1][0],contacts[i-1][1],contacts[i-1][2]) + appPointtemp=list(appPointtemp) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postop.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + target=tuple(point) + appPointT1nat=contacts[i] + #print "target 418: ", target + + #we make shure that the new point isn't at an angle>10 degrees + if i>=nbContacts-2: + v0=vecteur(contacts[i-2],contacts[i-1]) + v1=vecteur(contacts[i-1],contacts[i]) + try: + theta=math.acos(vdot(v0,v1)/(norme3D(v0)*norme3D(v1))) + except: + theta=0 + if theta> 0.174533: + #we lauch the approximation of the center of mass once + moy=findMoyMax(npCT,sizex,sizey,sizez,volCT,entry,do[i],dicPoints[i+1],coteRegionX/1.1,coteRegionY/1.1,coteRegionZ/1.1,CT) + #if the computations fail at this point, we will give it the first approximation + if moy is None: + appPoint=dicPoints[i+1] + else: + appPoint=(moy[2]*sizex,moy[1]*sizey,moy[0]*sizez) + #Transformation of the approximated contact to the T1 natif referential + appPointtemp=list(appPoint) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + contacts[i]=tuple(point) + print "modif 490" + v0=vecteur(contacts[i-2],contacts[i-1]) + v1=vecteur(contacts[i-1],contacts[i]) + try: + theta=math.acos(vdot(v0,v1)/(norme3D(v0)*norme3D(v1))) + except: + theta=0 + if theta> 0.174533: + appPoint=dicPoints[i+1] + c#Transformation of the approximated contact to the T1 natif referential + appPointtemp=list(appPoint) + appPointtemp.append(1) + appPointtemp=array(appPointtemp) + appPointT1nat=transfo_pre_to_postopInv.dot(appPointtemp.T) + point=list(appPointT1nat) + del point[-1] + contacts[i]=tuple(point) + print "modif 507" + #print "theta sup 0.17" + + #print "target 445: ", target + #print "entry :", entry + #Suppression of the located contact so it doesn't interfear with the approximation of the next one + #Calculation of the size of the npCT matrix we are going to remove + if i==0: + a=round(appPoint[2]/sizez-do[i+1]/(2.2*sizez)) + b=round(appPoint[2]/sizez+do[i+1]/(2.2*sizez)) + c=round(appPoint[1]/sizey-do[i+1]/(2.2*sizey)) + d=round(appPoint[1]/sizey+do[i+1]/(2.2*sizey)) + e=round(appPoint[0]/sizex-do[i+1]/(2.2*sizex)) + f=round(appPoint[0]/sizex+do[i+1]/(2.2*sizex)) + else: + a=round(appPoint[2]/sizez-do[i]/(2.2*sizez)) + b=round(appPoint[2]/sizez+do[i]/(2.2*sizez)) + c=round(appPoint[1]/sizey-do[i]/(2.2*sizey)) + d=round(appPoint[1]/sizey+do[i]/(2.2*sizey)) + e=round(appPoint[0]/sizex-do[i]/(2.2*sizex)) + f=round(appPoint[0]/sizex+do[i]/(2.2*sizex)) + #Removal of the contact + try: + npCT[0,a:b,c:d,e:f]=zeros(npCT[0,a:b,c:d,e:f].shape) + except: + pdb.set_trace() + print "contacts : ", contacts + + #approximation of the contacts with only the first approximation :newS1=(a*(entry[0]-target[0])+entry[0],a*(entry[1]-target[1])+entry[1],a*(entry[2]-target[2])+entry[2]) if the contact is near the bone + #Only starts running after the nb of contacts/2-th- contact + if i>nbContacts/2: + #if no brainMask is found, this computation doesn't take place + if brainMask is None: + pass + else: + #We see if we still are in the brain: the value will be !=0 + if brainMask[0,appPointT1nat[2],appPointT1nat[1],appPointT1nat[0]]!=0: + pass + else: + #if we weren't in brain, we are going to look around if we find some + if brainMask[0,appPointT1nat[2]-(do[i]/sizeT1[2]):appPointT1nat[2]+(do[i]/sizeT1[2]),appPointT1nat[1]-(do[i]/sizeT1[1]):appPointT1nat[1]+(do[i]/sizeT1[1]),appPointT1nat[0]-(do[i]/sizeT1[0]):appPointT1nat[0]+(do[i]/sizeT1[0])].max()!=0: + pass + else: + #no brain is found, the contact will then be approximated in the continuation of the 2 contacts that come before + i+=1 + while i problème de référentiel ? +# En normalisant et exportant : si un fichier va être écrasé, demander confirmation ! +# RemoveElectrode : remove also the label objects +# Exportation : classer les plots pour que l'exportation comporte A0 A1 A2 B1 B3 et pas B3 A1 B1 A0... +# AimsMIRegister -> utilisation des fichiers TRM ou utilisation du recalage SPM ? +# Valider les templates d'electrodes avant de les utiliser : un plot doit TOUJOURS se nommer "Plot152" et pas "Element 21" ou "Plot 152" -> modifier l'éditeur de template + + +# for DTI : ./AimsMeshDistance --help + + +import sys, os, pickle, glob, numpy, re, string, time, subprocess, json, copy, csv, gc #gc.get_referrers pour trouver où est encore déclarer une variable (pour problem quand variable déclarer en python et en c++) +import openpyxl + +from PyQt4 import QtGui, QtCore, uic, Qt +from PyQt4.QtGui import QVBoxLayout + +from numpy import * +from math import sqrt, cos, sin +from collections import OrderedDict + +from soma import aims +from brainvisa import axon + +#from soma.aims.spmnormalizationreader import readSpmNormalization +from brainvisa import anatomist +from brainvisa.data import neuroHierarchy +import registration + +from externalprocesses import * +from MicromedListener import MicromedListener as ML +from referentialconverter import ReferentialConverter +from checkSpmVersion import * +from readSulcusLabelTranslationFile import * +from readFreesurferLabelFile import * +from neuroProcesses import defaultContext +from TimerMessageBox import * +from generate_contact_colors import * +from bipoleSEEGColors import bipoleSEEGColors +from DeetoMaison import DeetoMaison +#from neuroProcesses import * + +import ImportTheoreticalImplentation +from scipy import ndimage +from brainvisa.processes import * +from PIL import Image + +import pdb + +#import objgraph #if not install in a terminal : pip install objgraph --prefix /brainvisa_4.50/ + +#name = 'Anatomist Show MarsAtlas Parcels Texture' +#roles = ('viewer',) +#userLevel = 0 + +#def validation(): +# anatomist.validation() + +#signature = Signature( +# 'texture_marsAtlas_parcels', ReadDiskItem('hemisphere marsAtlas parcellation texture', 'aims Texture formats', requiredAttributes={ 'regularized': 'false' }), +# 'white_mesh',ReadDiskItem( 'Hemisphere White Mesh', 'aims mesh formats' ), +#) + + +########## SPM calls +# Convert SPM normalization _sn.mat to vector field +spm_SnToField8 = """try, addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +FileNameSN = '%s'; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.matname{1}=FileNameSN; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.vox=[NaN NaN NaN]; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.bb=NaN*ones(2,3); +matlabbatch{1}.spm.util.defs.comp{1}.inv.space{1}=['%s' ',1']; +matlabbatch{1}.spm.util.defs.ofname='%s'; +matlabbatch{1}.spm.util.defs.fnames=''; +matlabbatch{1}.spm.util.defs.savedir.saveusr{1}=spm_str_manip(FileNameSN,'h'); +matlabbatch{1}.spm.util.defs.interp=1; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" # %(FileNameSN, FileSource, ofname) -> '_sn.mat' file and source image FileSource (normalized with the _sn). For the Database, we want y__inverse.nii, so we need ofname = '_inverse' --> Maybe should provide also the output dir ? Right now, same as _sn.mat + +# API changed in SPM12... +spm_SnToField12 = """try, addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +FileNameSN = '%s'; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.matname{1}=FileNameSN; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.vox=[NaN NaN NaN]; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.bb=NaN*ones(2,3); +matlabbatch{1}.spm.util.defs.comp{1}.inv.space = {'%s'}; +matlabbatch{1}.spm.util.defs.out{1}.savedef.ofname = '%s'; +matlabbatch{1}.spm.util.defs.out{1}.savedef.savedir.saveusr{1}=spm_str_manip(FileNameSN,'h'); +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +#spm_SnToField = spm_SnToField12 + +spm_inverse_y_field12 = """try,addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.def = {%s}; +matlabbatch{1}.spm.util.defs.comp{1}.inv.space = {%s}; +matlabbatch{1}.spm.util.defs.out{1}.savedef.ofname = %s; +matlabbatch{1}.spm.util.defs.out{1}.savedef.savedir.saveusr = {%s}; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm_inverse_y_field8 ="""try,addpath(genpath(%s));spm('defaults', 'FMRI');spm_jobman('initcfg'); + +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +# Read deformation field y__inverse.nii, apply the vector field to scanner-based coordinates of electrodes +spm_normalizePoints = """ +try, addpath(genpath(%s));P='%s'; +P1=spm_vol([P ',1,1']); +P2=spm_vol([P ',1,2']); +P3=spm_vol([P ',1,3']); +[V1,XYZ]=spm_read_vols(P1); +V2=spm_read_vols(P2); +V3=spm_read_vols(P3); + +%% Apply tranformation to electrodes +PosElectrode = dlmread('%s'); +wPosElectrode=PosElectrode; +for i1=1:size(PosElectrode,1) +D=(XYZ(1,:)-PosElectrode(i1,1)).^2+(XYZ(2,:)-PosElectrode(i1,2)).^2+(XYZ(3,:)-PosElectrode(i1,3)).^2; +[tmp,order]=sort(D); +tmp=tmp(1:18); %% cubic neighborhood +order=order(1:18); +W=1./tmp; %% weight inverse to distance +if sum(isinf(W))>0 +W=[1 zeros(1,length(W)-1)]; +end +wPosElectrode(i1,:)=[sum(V1(order).*W)./sum(W) sum(V2(order).*W)./sum(W) sum(V3(order).*W)./sum(W)]; +end +dlmwrite('%s',wPosElectrode,'precision',18); +catch, disp 'AN ERROR OCCURED'; end;quit; +""" + + +#coregister and reslice and segmentation (for resection estimation) +spm_resection_estimation = """try, addpath(genpath(%s)); spm('defaults', 'FMRI'); spm_jobman('initcfg'); +clear matlabbatch; + +final_directory = %s; +if isdir(final_directory) == 0 + mkdir(final_directory) +end +matlabbatch{1}.spm.spatial.coreg.estwrite.ref = %s; +matlabbatch{1}.spm.spatial.coreg.estwrite.source = %s; +matlabbatch{1}.spm.spatial.coreg.estwrite.other = {''}; +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.cost_fun = 'nmi'; +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.sep = [4 2]; +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.tol = [0.02 0.02 0.02 0.001 0.001 0.001 0.01 0.01 0.01 0.001 0.001 0.001]; +matlabbatch{1}.spm.spatial.coreg.estwrite.eoptions.fwhm = [7 7]; +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.interp = 4; +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.wrap = [0 0 0]; +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.mask = 0; +matlabbatch{1}.spm.spatial.coreg.estwrite.roptions.prefix = 'r'; +matlabbatch{2}.spm.spatial.preproc.channel.vols = %s; +matlabbatch{2}.spm.spatial.preproc.channel.biasreg = 0.001; +matlabbatch{2}.spm.spatial.preproc.channel.biasfwhm = 60; +matlabbatch{2}.spm.spatial.preproc.channel.write = [0 0]; +matlabbatch{2}.spm.spatial.preproc.tissue(1).tpm = %s; +matlabbatch{2}.spm.spatial.preproc.tissue(1).ngaus = 2; +matlabbatch{2}.spm.spatial.preproc.tissue(1).native = [1 0]; +matlabbatch{2}.spm.spatial.preproc.tissue(1).warped = [0 0]; +matlabbatch{2}.spm.spatial.preproc.warp.mrf = 1; +matlabbatch{2}.spm.spatial.preproc.warp.cleanup = 1; +matlabbatch{2}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; +matlabbatch{2}.spm.spatial.preproc.warp.affreg = 'mni'; +matlabbatch{2}.spm.spatial.preproc.warp.fwhm = 0; +matlabbatch{2}.spm.spatial.preproc.warp.samp = 3; +matlabbatch{2}.spm.spatial.preproc.warp.write = [0 0]; +matlabbatch{3}.spm.spatial.preproc.channel.vols = %s; +matlabbatch{3}.spm.spatial.preproc.channel.biasreg = 0.001; +matlabbatch{3}.spm.spatial.preproc.channel.biasfwhm = 60; +matlabbatch{3}.spm.spatial.preproc.channel.write = [0 0]; +matlabbatch{3}.spm.spatial.preproc.tissue(1).tpm = %s; +matlabbatch{3}.spm.spatial.preproc.tissue(1).ngaus = 2; +matlabbatch{3}.spm.spatial.preproc.tissue(1).native = [1 0]; +matlabbatch{3}.spm.spatial.preproc.tissue(1).warped = [0 0]; +matlabbatch{3}.spm.spatial.preproc.warp.mrf = 1; +matlabbatch{3}.spm.spatial.preproc.warp.cleanup = 1; +matlabbatch{3}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; +matlabbatch{3}.spm.spatial.preproc.warp.affreg = 'mni'; +matlabbatch{3}.spm.spatial.preproc.warp.fwhm = 0; +matlabbatch{3}.spm.spatial.preproc.warp.samp = 3; +matlabbatch{3}.spm.spatial.preproc.warp.write = [0 0]; +matlabbatch{4}.spm.util.imcalc.input = { + %s + %s + }; +matlabbatch{4}.spm.util.imcalc.output = %s; +matlabbatch{4}.spm.util.imcalc.outdir = %s; +matlabbatch{4}.spm.util.imcalc.expression = 'i1-i2'; +matlabbatch{4}.spm.util.imcalc.var = struct('name', {}, 'value', {}); +matlabbatch{4}.spm.util.imcalc.options.dmtx = 0; +matlabbatch{4}.spm.util.imcalc.options.mask = 0; +matlabbatch{4}.spm.util.imcalc.options.interp = 1; +matlabbatch{4}.spm.util.imcalc.options.dtype = 4; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + + +region_grow="""try,addpath(genpath(%s)); +imgresec = %s; +iSeed = %s; +reseccenter = %s; +f_orient = %s; +f_orient = reshape(f_orient,4,4)'; +centermatF = eye(4); +centermatF(:,4) = f_orient*[reseccenter 1]'; +VF = spm_vol(imgresec); +reseccenter_pix = inv(VF.mat)*centermatF(:,4); +mat_to_grow=spm_read_vols(VF); +new_image = regiongrowing(mat_to_grow,iSeed,reseccenter_pix(1:3)); +VF.fname = %s; +VF.private.mat0 = VF.mat; +spm_write_vol(VF,new_image); +catch, disp 'AN ERROR OCCURED'; end;quit;""" + +def viewFile(filepath): + """ Launches an external app to display the provided file (windows/linux/mac-specific methods) """ + if sys.platform.startswith('darwin'): + subprocess.call(('open', filepath)) + elif os.name == 'nt': + os.startfile(filepath) + elif os.name == 'posix': + subprocess.call(('xdg-open', filepath)) + + +# Functions to sort the contacts A1,A2...,A10 and not A1, A10, A2.. +def atoi(text): + return int(text) if text.isdigit() else text +def natural_keys(text): + """alist.sort(key=natural_keys) sorts in human order""" + return [ atoi(c) for c in re.split('(\d+)', text) ] + +##################### Electrode functions (to be exported in another file FIXME needs natural_keys function ################################## + +from electrode import ElectrodeModel + +def moveElectrode(target, entry, referential, newRef, a, meshes): + # a is anatomist object + if entry is None or target is None: + print("entry or target is None") + return + + + #print "entry : "+repr(entry)+"target : "+repr(target) + + if newRef is None: + newRef = a.createReferential() + transl = target#[-target[0], -target[1], -target[2]] + i = array([[1,0,0]]) + z = array([target,]) - array([entry,]) + if z[0][1] < 0.001 and z[0][2] < 0.001:# si i est colinéaire avec z, changer i car on n'obtiendra pas un vecteur perpendiculaire aux deux + i = array([[0,1,0]]) + if linalg.norm(z) == 0: + return + z = -z / linalg.norm(z) + #print "z = "+repr(z) + y = cross (i,z) + y = -y/linalg.norm(y) + #print "y = "+repr(y) + x = cross(y,z) + #print "x = "+repr(x) + #m = [x[0][0], x[0][1], x[0][2], y[0][0],y[0][1], y[0][2], z[0][0], z[0][1], z[0][2]] + m = [x[0][0], y[0][0], z[0][0], x[0][1],y[0][1], z[0][1], x[0][2], y[0][2], z[0][2]] + try: + transf = a.createTransformation(transl+m, origin = newRef, destination = referential) + except: + print("problem transformation") + return + pdb.set_trace() + a.assignReferential(newRef, meshes) + #print " Electrode moved : target = "+repr(target) + ", entry = "+repr(entry) + " and Matrix "+repr(transl+m) + #pdb.set_trace() + return (newRef, transf) + +def createElectrode(target, entry, referential, ana=None, windows=None, model = None, dispMode=None, dispParams=None): + elecModel = ElectrodeModel(ana) + elecModel.open(model,dispMode, dispParams) + #elecModel.setDisplayReferential(newRef) + meshes = elecModel.getAnatomistObjects() + (newRef, transf) = moveElectrode(target, entry, referential, None, ana, meshes) + #pdb.set_trace() + if windows is not None: + ana.addObjects(meshes, windows) + return (newRef, transf, elecModel) + +def createBipole(target, entry, referential, ana=None, windows=None, model = None, dispMode=None, dispParams=None): + + elecModel = ElectrodeModel(ana) + elecModel.open(str(model),dispMode, dispParams) + #elecModel.setDisplayReferential(newRef) + + meshes = elecModel.getAnatomistObjects() + #mesh = self.a.toAObject(aims.SurfaceGenerator.cylinder(aims.Point3df(p[0], p[1], p[2]), aims.Point3df(pEnd), r, r, 24, True, True)) + (newRef, transf) = moveElectrode(target, entry, referential, None, ana, meshes) + + if windows is not None: + ana.addObjects(meshes, windows) + return (newRef, transf, elecModel) + + +# Récupération des plots dans l'ordre plot1 -> plot n +def getPlots(elecModel): + cyls = elecModel.getCylinders() + return dict((name,cyls[name]) for name in cyls if cyls[name]['type'] == 'Plot') + +def getPlotsNames(elecModel): + cyls = elecModel.getCylinders() + plots = [n for n in cyls if cyls[n]['type'] == 'Plot'] + return sorted(plots, key=natural_keys) + + +# Récupération des coordonnées des centres des plots dans le référentiel électrode +def getPlotsCenters(elecModel): + plots = getPlots(elecModel) + return dict((p, plots[p]['center']) for p in plots) + + +############### 3D text annotations from anagraphannotate.py #############" + + +byvertex = False +# This intermediate class is only here because I cannot (yet) make SIP +# generate a non-abstract class for TextObject binding. One day, I'll find out! +class TObj ( anatomist.anatomist.cpp.TextObject ): + def __init__( self, message='', pos=[0,0,0] ): + anatomist.anatomist.cpp.TextObject.__init__( self, message, pos ) + +class Props( object ): + def __init__( self ): + self.lvert = [] + self.lpoly = [] + self.usespheres = True + self.colorlabels = True + self.center = aims.Point3df() + +def makelabel( a, label, gc, pos, ref, color, props ): + """ Create a text label designating gc at position pos, using anatomist instance a, a color and stores the generated elements in props""" + objects = [] + # create a text object + to = TObj( label ) + to.setScale( 0.1 ) + to.setName( 'label: ' + label ) + a.releaseObject(to) + + # If we want to show a sphere at the target point + if props.usespheres: + sph = aims.SurfaceGenerator.icosphere( gc, 2, 50 ) + asph = a.toAObject( sph ) + asph.setMaterial( diffuse=color ) + asph.setName( 'gc: ' + label ) + a.registerObject( asph, False ) + a.releaseObject(asph) #registerObject le "dérelease" + objects.append( asph ) + # Choose the color of the label text + if props.colorlabels: + to.GetMaterial().set( { 'diffuse': color } ) + # texto is the label (2D texture on a rectangle), but defined to always face the camera + texto = anatomist.anatomist.cpp.TransformedObject( [ to ], False, True, pos ) + texto.setDynamicOffsetFromPoint( props.center ) + texto.setName( 'annot: ' + label ) + objects.append( texto ) + # Add to the polygons a line (to link the label and the target position) + props.lpoly.append( aims.AimsVector_U32_2( ( len( props.lvert ), + len( props.lvert ) + 1 ) ) ) + props.lvert += [ gc, pos ] + a.registerObject( texto, False ) + a.assignReferential(ref, objects) + a.releaseObject(texto) + + return objects + +############################### Useful functions + +def createItemDirs(item): + """ Create the directories containing the provided WriteDiskItem and insert them in the BrainVisa database """ + # Copied from brainvisa.processes, in ExecutionContext._processExecution() + dirname = os.path.dirname( item.fullPath() ) + dir=dirname + dirs = [] + while not os.path.exists( dir ): + dirs.append(dir) + dir=os.path.dirname(dir) + if dirs: + try: + os.makedirs( dirname ) + except OSError, e: + if not e.errno == errno.EEXIST: + # filter out 'File exists' exception, if the same dir has + # been created concurrently by another instance of BrainVisa + # or another thread + raise + for d in dirs: + dirItem=neuroHierarchy.databases.createDiskItemFromFileName(d, None) + + + +######################### FENETRE PRINCIPALE ############################ + +class LocateElectrodes(QtGui.QDialog): + + def __init__(self, app=None, loadAll = True): + + # UI init + if loadAll == True: + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("epilepsie-electrodes.ui", self) + self.setWindowTitle('Epilepsie - localisation des electrodes - NOT FOR MEDICAL USAGE') + # Widget 0 (buttons panel) will be at minimum size (stretch factor 0), the windows will fill up the rest + self.splitter_2.setStretchFactor(0,0) + self.splitter_2.setStretchFactor(1,1) + # Equal size for both views + self.splitter.setStretchFactor(0,1) + self.splitter.setStretchFactor(1,1) + + + self.nameEdit.setText('A') + + # Load the list of protocols, patients and electrode models from BrainVisa + if loadAll == True: + self.modalities = ['Raw T1 MRI', 'T2 MRI', 'CT', 'PET', 'Electrode Implantation Coronal Image', 'Electrode Implantation Sagittal Image','fMRI-epile', 'Statistic-Data','FLAIR', 'resection', 'FreesurferAtlas', 'FGATIR','HippoFreesurferAtlas'] + # Electrode models + self.elecModelList = [] + self.elecModelListByName = [] + self.loadFromBrainVisa() + + + + # Init of variables + self.app = app + self.dispObj = {} # All displayable objects "t1mri-pre", "t2"... + self.objtokeep = {} #all object we must keep alive for anatomist but not in other variables + self.diskItems = {} # For each dispObj, a list of dictionnaries {'refName', 'refObj', 'refId', 'transf'} + # Coordinates displayed using referential : 'Natif' par defaut + self.coordsDisplayRef = 'Natif' + self.referentialCombo.clear() + self.referentialCombo.addItems(['Natif',]) + self.dispMode = 'real' + self.dispParams = None + self.t1preMniFieldPath = None + self.t1pre2ScannerBasedId = None + self.electrodes = []# {Les objets electrodes avec les coordonnées, les meshes + self.bipoles = [] #{Les objects bipoles} + self.electrodeTemplateStubs = [] # Un objet electrode par template disponible dans la base de données (chargé à la demande par getElectrodeTemplates) + self.contacts = [] # {name:n, number:2, electrode: e, mesh:m} + self.transfs = [] # identity transforms (must be stored) + self.currentWindowRef = None # Referential used by windows (because pyanatomist AWindow.getReferential is not implemented yet) + self.linkedRefs = [] # Referentials linked by a identity transform + self.transf2Mni = {} # Transformation from T1 pre referential to MNI referential + self.threads = [] # List of running threads + self.t1pre2ScannerBasedTransform = None #Transfo from T1pre native to scanner-based referential (Anatomist Transformation object) + self.brainvisaPatientAttributes = None # Attributes of a BrainVisa ReadDiskItem MRI of the loaded patient + self.spmpath = None + + #self.MicromedListener = ML() + + # list of objects to display in window for each scenario (MNI, pre, post, etc) + self.windowContent = { 'IRM pre':['T1pre','electrodes',],\ + 'IRM pre T2':['T2pre','electrodes',],\ + 'IRM pre + hemisphere droit':['T1pre','T1pre-rightHemi','electrodes',],\ + 'IRM pre + MARS ATLAS droit':['T1pre','right MARS ATLAS BIDULE','electrodes',],\ + 'IRM pre + hemisphere gauche':['T1pre','T1pre-leftHemi','electrodes',],\ + 'IRM pre + MARS ATLAS gauche':['T1pre','left MARS ATLAS BIDULE','electrodes',],\ + 'IRM pre + hemispheres':['T1pre','T1pre-rightHemi','T1pre-leftHemi','electrodes',],\ + 'IRM pre + hemispheres + tete':['T1pre','T1pre-rightHemi','T1pre-leftHemi', 'T1pre-head','electrodes',],\ + 'IRM post':['T1post','electrodes',],\ + 'IRM post T2':['T2post','electrodes',],\ + 'CT post':['CTpost','electrodes',],\ + 'PET pre':['PETpre','electrodes',],\ + 'FLAIR pre':['FLAIRpre','electrodes',],\ + 'FGATIR pre':['FGATIRpre','electrodes',],\ + 'fMRI pre':['fMRIpre','electrodes'],\ + 'Statistic Data':['Statisticspre','electrodes'],\ + 'IRM post-op':['T1postOp','electrodes',],\ + 'Resection':['Resection','electrodes',],\ + 'FreeSurferAtlas':['FreesurferAtlaspre','electrodes',],\ + 'HippoFreeSurferAtlas':['HippoFreesurferAtlaspre','electrodes',],\ + } + self.windowCombo1.clear() + self.windowCombo1.addItems(sorted(self.windowContent.keys())) + self.windowCombo2.clear() + self.windowCombo2.addItems(sorted(self.windowContent.keys())) + + # Anatomist windows + if loadAll == True: + self.wins=[] + self.a = anatomist.Anatomist('-b') #Batch mode (hide Anatomist window) + self.a.onCursorNotifier.add(self.clickHandler) + + layoutAx = QtGui.QHBoxLayout( self.windowContainer1 ) + self.axWindow = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.axWindow.setParent(self.windowContainer1) + layoutAx.addWidget( self.axWindow.getInternalRep() ) + + layoutSag = QtGui.QHBoxLayout( self.windowContainer2 ) + self.sagWindow = self.a.createWindow( 'Axial' )#, no_decoration=True ) + self.sagWindow.setParent(self.windowContainer2) + layoutSag.addWidget( self.sagWindow.getInternalRep() ) + + self.wins = [self.axWindow, self.sagWindow] + + # Get Transformation Manager + self.transfoManager = registration.getTransformationManager() + # Get ReferentialConverter (for Talairach, AC-PC...) + self.refConv = ReferentialConverter() + + if loadAll == True: + # Linking UI elements to functions + self.connect(self.loadPatientButton, QtCore.SIGNAL('clicked()'), self.loadPatient) + self.connect(self.changePatientButton, QtCore.SIGNAL('clicked()'), self.changePatient) + self.connect(self.patientList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem*)'), lambda x:self.loadPatient()) + self.connect(self.protocolCombo, QtCore.SIGNAL('currentIndexChanged(int)'), self.updateBrainvisaProtocol) + self.connect(self.filterSiteCombo, QtCore.SIGNAL('currentIndexChanged(int)'), self.filterSubjects) + self.connect(self.filterYearCombo, QtCore.SIGNAL('currentIndexChanged(int)'), self.filterSubjects) + self.connect(self.addElectrodeButton, QtCore.SIGNAL('clicked()'), self.addElectrode) + self.connect(self.removeElectrodeButton, QtCore.SIGNAL('clicked()'), self.removeElectrode) + self.connect(self.nameEdit, QtCore.SIGNAL('editingFinished()'), self.editElectrodeName) + self.connect(self.targetButton, QtCore.SIGNAL('clicked()'), self.updateTarget) + self.connect(self.entryButton, QtCore.SIGNAL('clicked()'), self.updateEntry) + self.connect(self.electrodeList, QtCore.SIGNAL("currentRowChanged(int)"), self.electrodeSelect) + self.connect(self.electrodeList, QtCore.SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self.electrodeGo) + self.connect(self.contactList, QtCore.SIGNAL("itemClicked(QListWidgetItem*)"), self.contactSelect) + self.connect(self.contactList, QtCore.SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self.contactGo) + self.connect(self.typeComboBox, QtCore.SIGNAL('currentIndexChanged(QString)'), self.updateElectrodeModel) + # itemClicked(QListWidgetItem*) , currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous ), currentRowChanged ( int currentRow ) + self.connect(self.electrodeLoadButton, QtCore.SIGNAL('clicked()'), self.loadElectrodes) + self.connect(self.electrodeSaveButton, QtCore.SIGNAL('clicked()'), self.saveElectrodes) + self.connect(self.normalizeExportButton, QtCore.SIGNAL('clicked()'), self.normalizeExportElectrodes) + #self.connect(self.marsatlasExportButton, QtCore.SIGNAL('clicked()'),self.parcelsExportElectrodes) + self.connect(self.colorConfigButton, QtCore.SIGNAL('clicked()'), self.configureColors) + self.connect(self.dispModeCombo, QtCore.SIGNAL('currentIndexChanged(int)'), self.updateDispMode) + self.connect(self.windowCombo1, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s: self.windowUpdate(0,s)) + self.connect(self.windowCombo2, QtCore.SIGNAL('currentIndexChanged(QString)'), lambda s: self.windowUpdate(1,s)) + self.connect(self.referentialCombo, QtCore.SIGNAL('currentIndexChanged(QString)'), self.updateCoordsDisplay) + self.connect(self.electrodeRefCheck, QtCore.SIGNAL('stateChanged(int)'), self.updateElectrodeView) + self.connect(self.electrodeRefRotationSlider, QtCore.SIGNAL('valueChanged(int)'), self.updateElectrodeViewRotation) + + self.connect(self.Clipping_checkbox,QtCore.SIGNAL('clicked()'),self.clippingUpdate) + self.connect(self.makefusionButton,QtCore.SIGNAL('clicked()'),self.makeFusion) + self.connect(self.generateResectionArray,QtCore.SIGNAL('clicked()'),self.generateResection) + self.connect(self.validateROIresection,QtCore.SIGNAL('clicked()'),self.ROIResectiontoNiftiResection) + self.connect(self.deleteMarsAtlasfiles,QtCore.SIGNAL('clicked()'),self.DeleteMarsAtlasFiles) + self.connect(self.generateDictionariesComboBox,QtCore.SIGNAL('activated(QString)'),self.generateDictionaries) + self.connect(self.ImportTheoriticalImplantation,QtCore.SIGNAL('clicked()'),self.importRosaImplantation) + self.connect(self.approximateButton,QtCore.SIGNAL('clicked()'),self.approximateElectrode) + + prefpath_imageimport = os.path.join(os.path.expanduser('~'), '.imageimport') + try: + if (os.path.exists(prefpath_imageimport)): + filein = open(prefpath_imageimport, 'rb') + prefs_imageimport = pickle.load(filein) + self.spmpath = prefs_imageimport['spm'] + self.fileNoDBpath = prefs_imageimport['FileNoDBPath'] + filein.close() + except: + print 'NO SPM path found, will be unable to export MNI position' + pass + + self.warningMEDIC() + + # Reload options, check brainvisa and matlab/SPM + + def closeEvent(self, event): + self.quit(event) + + def quit(self, event=None): + reply = QtGui.QMessageBox.question(self, 'Message', + "Quit the software without saving ?", QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No, QtGui.QMessageBox.No) + #if self.brainvisaPatientAttributes is not None: + #self.saveElectrodes() + # Remove the vector field to MNI if it was computed + #self.clearT1preMniTransform() + if reply == QtGui.QMessageBox.Yes: + axon.processes.cleanup() + if event is None: + self.app.quit() + else: + event.accept() + else: + event.ignore() + + + def warningMEDIC(self): + + shortwarning = TimerMessageBox(5,self) + shortwarning.exec_() + + #messagebox = QtGui.QMessageBox(self) + #messagebox.setWindowTitle("NOT FOR MEDICAL USAGE") + #messagebox.setText("NOT FOR MEDICAL USAGE\n (closing automatically in {0} secondes.)".format(3)) + #messagebox.setStandardButtons(messagebox.NoButton) + #self.timer2 = QtCore.QTimer() + #self.time_to_wait = 3 + #def close_messagebox(e): + #e.accept() + #self.timer2.stop() + #self.time_to_wait = 10 + #def decompte(): + #messagebox.setText("NOT FOR MEDICAL USAGE\n (closing automatically in {0} secondes.)".format(self.time_to_wait)) + #if self.time_to_wait <= 0: + #messagebox.closeEvent = close_messagebox + #messagebox.close() + #self.time_to_wait -= 1 + #self.connect(self.timer2,QtCore.SIGNAL("timeout()"),decompte) + #self.timer2.start(1000) + #messagebox.exec_() + + def loadFromBrainVisa(self): + # Find available patients in BV database + print "LOADING DATA FROM BRAINVISA" + rdi = ReadDiskItem( 'Subject', 'Directory',requiredAttributes={'_ontology':'brainvisa-3.2.0'} ) #, requiredAttributes={'center':'Epilepsy'} ) + subjects = list( rdi._findValues( {}, None, False ) ) + protocols = list(set([s.attributes()['center'] for s in subjects if 'center' in s.attributes()])) + # Fill the combo + self.protocolCombo.clear() + self.protocolCombo.addItems(sorted(protocols)) + self.allSubjects = subjects + self.updateBrainvisaProtocol() + + def updateBrainvisaProtocol(self, idx=None): + """Updates the UI when the selected protocol changes""" + self.currentProtocol = str(self.protocolCombo.currentText()) + self.subjects = [s.attributes()['subject'] for s in self.allSubjects if 'center' in s.attributes() and s.attributes()['center'] == self.currentProtocol] + print 'all subjects:' + repr(self.subjects) + self.patientList.clear() + self.patientList.addItems(sorted(self.subjects)) + # Update the filters + sites = ['*',] + sorted(set([s.split('_')[0] for s in self.subjects])) + years = ['*',] + sorted(set([s.split('_')[1] for s in self.subjects if len(s.split('_')) > 1])) + self.filterSiteCombo.clear() + self.filterSiteCombo.addItems(sites) + self.filterYearCombo.clear() + self.filterYearCombo.addItems(years) + # Loading electrode models + rdiEM = ReadDiskItem('Electrode Model', 'Electrode Model format', requiredAttributes={'center':self.currentProtocol}) + self.elecModelList = list (rdiEM._findValues( {}, None, False ) ) + elecNames = [e.attributes()['model_name'] for e in self.elecModelList] + self.elecModelListByName = dict((e.attributes()['model_name'], e) for e in self.elecModelList) + self.typeComboBox.clear() + self.typeComboBox.addItems(elecNames) + + def filterSubjects(self, value=None): + """Filtering subject list""" + subs = self.subjects + if str(self.filterSiteCombo.currentText()) != '*': + subs = [s for s in subs if s.split('_')[0] == str(self.filterSiteCombo.currentText())] + if str(self.filterYearCombo.currentText()) != '*': + subs = [s for s in subs if len(s.split('_')) > 1 and s.split('_')[1] == str(self.filterYearCombo.currentText())] + self.patientList.clear() + self.patientList.addItems(sorted(subs)) + + def getT1preMniTransform(self): + """Returns the path of the transformation to MNI (vector field) and compute it if necessary (from _sn.mat)""" + #pdb.set_trace() + if self.t1preMniFieldPath is not None: + return self.t1preMniFieldPath + # Find _sn.mat + + + if 'T1pre' not in self.dispObj: + print "No T1pre loaded : cannot get MNI transform from it" + return None + + #look for a y_file_inverse first + rdi_inv_read = ReadDiskItem('SPM normalization inverse deformation field','NIFTI-1 image') + di_inv_read = rdi_inv_read.findValue(self.diskItems['T1pre']) + + if di_inv_read is None: + print "No inverse deformation field found in database" + else: + print "inverse deformation field found and used" + #pdb.set_trace() + self.t1preMniFieldPath = di_inv_read.fileName() + return self.t1preMniFieldPath + + spm_version = checkSpmVersion(self.spmpath) + + #look for a y_file second + rdi_y = ReadDiskItem('SPM normalization deformation field','NIFTI-1 image') + di_y = rdi_y.findValue(self.diskItems['T1pre']) + #pdb.set_trace() + if di_y is None: + print "No deformation field found in database" + else: + print "deformation field found and used" + wdi_inverse = WriteDiskItem('SPM normalization inverse deformation field','NIFTI-1 image') + dir_yinv_split = str(di_y.fileName()).split('/') + name_yinverse = dir_yinv_split.pop()[2:] + #name_yinverse.replace('.nii','_inverse.nii') + dir_yinverse = "/".join(dir_yinv_split) + di_inverse = wdi_inverse.findValue(di_y) + #on fait l'inversion de la deformation + #pdb.set_trace() + #pour le moment ce bout de code ne marche qu'avec spm12 + if spm_version == '(SPM12)': + print 'SPM12 used' + matlabRun(spm_inverse_y_field12%("'"+self.spmpath+"'","'"+str(di_y.fileName())+"'","'"+self.dispObj['T1pre'].fileName()+"'","'"+name_yinverse.replace('.nii','_inverse.nii')+"'","'"+dir_yinverse+"'")) + if spm_version == '(SPM8)': + print 'SPM8 used' + matlabRun(spm_inverse_y_field8%("'"+self.spmpath+"'","'"+str(di_y.fileName())+"'","'"+self.dispObj['T1pre'].fileName()+"'","'"+name_yinverse.replace('.nii','_inverse.nii')+"'","'"+dir_yinverse+"'")) + + self.t1preMniFieldPath = di_inverse.fileName() + neuroHierarchy.databases.insertDiskItem( di_inverse, update=True ) + return self.t1preMniFieldPath + + #look for a _sn.mat if no y_file + rdi = ReadDiskItem( 'SPM2 normalization matrix', 'Matlab file' ) + di = rdi.findValue(self.diskItems['T1pre']) + #pdb.set_trace() + if di is None: + print "SPM deformation _sn.mat not found in database" + return None + + # Convert to field + #pdb.set_trace() + wdi = WriteDiskItem( 'SPM normalization inverse deformation field', 'NIFTI-1 image' ) + diField = wdi.findValue(di) + if diField is None: + print "Cannot find path to save MNI vector field in the DB" + return None + #For a file /database/y_SubjectName_inverse.nii, get SubjectName_inverse + ofname = os.path.basename(diField.fullPath()).lstrip('y_').rsplit('.',1)[0] + + #pdb.set_trace() + + if spm_version == '(SPM12)': + print 'SPM12 used' + matlabRun(spm_SnToField12%("'"+self.spmpath+"'",str(di.fullPath()), str(self.diskItems['T1pre'].fullPath()), ofname) ) + if spm_version == '(SPM8)': + print 'SPM8 used' + matlabRun(spm_SnToField8%("'"+self.spmpath+"'",str(di.fullPath()), str(self.diskItems['T1pre'].fullPath()), ofname) ) + + if os.path.exists(diField.fullPath()): + self.t1preMniFieldPath = diField.fullPath() + return self.t1preMniFieldPath + else: + print "Matlab did not convert the MNI transform to vector field !" + return None + + + def clearT1preMniTransform(self): + """Reset MNI transform field if it was generated""" + if self.t1preMniFieldPath is not None: + try: + os.remove(self.t1preMniFieldPath) #to change with: self.removeDiskItems(di,eraseFiles=True) + except: + pass + self.t1preMniFieldPath = None + + def changePatient(self): + + self.loadPatientButton.setEnabled(True) + self.patientList.setEnabled(True) + self.a.removeObjects(self.a.getObjects(),self.wins[0]) + self.a.removeObjects(self.a.getObjects(),self.wins[1]) + self.a.config()[ 'linkedCursor' ] = 0 + referentials=self.a.getReferentials() + for element in referentials: + if element.getInfos().get('name') not in ('Talairach-MNI template-SPM', 'Talairach-AC/PC-Anatomist'): + self.a.deleteElements(element) + + #for element in self.electrodes: + #for elecKeys in element.keys(): + #del element[elecKeys] + #variablesG=globals() + #variablesL=locals() + self.electrodeList.clear() + self.contactList.clear() + self.currentWindowRef = None + listEl=[] + #for el , value in self.dispObj.items(): + # listEl.append(value) + #self.__init__(self,loadAll=False) + #for el in listEl: + # if type(el)==list: + # listElec=el + # else: + # self.a.deleteObjects(el) + + #del self.electrodes + self.electrodes = [] + #del self.dispObj + #parcourir les objets, détruire les fusions avant + #for obj in self.dispObj: + self.currentElectrodes = [] + self.currentContacts = [] + + #todelete = [] + #for name,obj in self.dispObj.items(): + # if isinstance(obj.internalRep,anatomist.anatomist.cpp.MObject): + # todelete.append(name) + #for name in todelete: + # del self.dispObj[name] + + self.dispObj={} + + #if hasattr(self,"objtokeep"): + self.objtokeep = {} + + self.__init__(loadAll = False) + + + def loadPatient(self, patient=None): + + if patient is None: + patient = str(self.patientList.selectedItems()[0].text()) + + volumes = [] + self.t1pre2ScannerBasedTransform = None + self.clearT1preMniTransform() + + pre_select_1 = self.windowCombo1.currentText() + pre_select_2 = self.windowCombo2.currentText() + + + + for moda in self.modalities: + rdi2 = ReadDiskItem( moda, 'aims readable volume formats', requiredAttributes={'subject':patient, 'center':self.currentProtocol} ) + volumes.extend(list( rdi2._findValues( {}, None, False ) )) + + + dictionnaire_list_images = {'IRM pre':['T1pre','electrodes',],\ + 'IRM pre + hemisphere droit':['T1pre','T1pre-rightHemi','electrodes',],\ + 'IRM pre + hemisphere gauche':['T1pre','T1pre-leftHemi','electrodes',],\ + 'IRM pre + hemispheres':['T1pre','T1pre-rightHemi','T1pre-leftHemi','electrodes',],\ + 'IRM pre + hemispheres + tete':['T1pre','T1pre-rightHemi','T1pre-leftHemi', 'T1pre-head','electrodes']} + + + #pdb.set_trace() + + for t in volumes: + if "skull_stripped" in t.fullName(): + continue + self.brainvisaPatientAttributes = t.attributes() + if (t.attributes()['modality'] == 't2mri') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'IRM pre T2':['T2pre','electrodes']}) + elif (t.attributes()['modality'] == 't2mri') and ('post' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'IRM post T2':['T2post','electrodes']}) + elif (t.attributes()['modality'] == 't1mri') and ('post' in t.attributes()['acquisition']) and not ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'IRM post':['T1post','electrodes']}) + elif (t.attributes()['modality'] == 'ct') and ('post' in t.attributes()['acquisition']) and not ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'CT post':['CTpost','electrodes']}) + elif (t.attributes()['modality'] == 'ct') and ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'CT post-op':['CTpostOp','electrodes']}) + elif (t.attributes()['modality'] == 'pet') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'PET pre':['PETpre','electrodes']}) + elif (t.attributes()['modality'] == 'flair') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'FLAIR pre':['FLAIRpre','electrodes']}) + elif (t.attributes()['modality'] == 'fgatir') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'FGATIR pre':['FGATIRpre','electrodes']}) + elif (t.attributes()['modality'] == 'fmri_epile') and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'fMRI pre'+ ' - ' + t.attributes()['subacquisition']:['fMRIpre','electrodes']}) #mettre le nom de la subacquisition + elif t.attributes()['modality'] == 'statistic_data' and ('pre' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'Statistic Data' + ' - ' + t.attributes()['subacquisition']:['Statisticspre'+t.attributes()['subacquisition'],'electrodes']}) #mettre le nom de la subacquisition + elif t.attributes()['modality'] == 'statistic_data' and ('post' in t.attributes()['acquisition']) and not ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'Statistic Data' + ' - ' + t.attributes()['subacquisition']:['Statisticspost'+t.attributes()['subacquisition'],'electrodes']}) #mettre le nom de la subacquisition + elif (t.attributes()['modality'] == 't1mri') and ('postOp' in t.attributes()['acquisition']): + dictionnaire_list_images.update({'IRM post-op':['T1postOp','electrodes']}) + elif (t.attributes()['modality'] == 'resection'): + dictionnaire_list_images.update({'Resection':['Resection','electrodes']}) + elif (t.attributes()['modality'] == 'freesurfer_atlas'): + dictionnaire_list_images.update({'FreeSurferAtlas pre':['FreesurferAtlaspre','electrodes']}) + elif (t.attributes()['modality'] == 'hippofreesurfer_atlas'): + dictionnaire_list_images.update({'HippoFreeSurferAtlas pre':['HippoFreesurferAtlaspre','electrodes']}) + + + try: + nameAcq = t.attributes()['acquisition'] + #print "Loading %s as %s"%(t.fileName(), nameAcq) + #print repr(t.attributes()) + # We try to get the acquisition name without the date (if there is one) : T1pre_2000-01-01 -> T1pre + if 'Statistics' in nameAcq: + na = nameAcq.split('_')[0] + t.attributes()['subacquisition'] + else: + na = nameAcq.split('_')[0] + except: + if moda == 'Electrode Implantation Coronal Image': + na = 'ImplantationCoro' + elif moda == 'Electrode Implantation Sagittal Image': + na = 'ImplantationSag' + else: + print "CANNOT find a nameAcq for ",repr(t) + na = 'unknown' + + self.loadAndDisplayObject(t, na) + if na == 'T1pre': + # Load standard transformations (AC-PC, T1pre Scanner-based, BrainVisa Talairach) + try: + self.refConv.loadACPC(t) + except Exception, e: + print "Cannot load AC-PC referential from T1 pre MRI : "+repr(e) + try: + self.refConv.loadTalairach(t) + except Exception, e: + print "Cannot load Talairach referential from T1 pre MRI : "+repr(e) + try: + tr2sb = self.t1pre2ScannerBased() + if tr2sb is not None: + self.refConv.setAnatomistTransform("Scanner-based", tr2sb, toRef=True) + # Add the AC-centered Scanner-Based (for PTS importation using AC-centered Olivier David method + if self.refConv.isRefAvailable('AC-PC'): + acInScannerBased = self.refConv.anyRef2AnyRef([0.0,0.0,0.0],'AC-PC', 'Scanner-based') + inf = tr2sb.getInfos() + rot = inf['rotation_matrix'] + trans = [inf['translation'][0] - acInScannerBased[0], inf['translation'][1] - acInScannerBased[1], inf['translation'][2] - acInScannerBased[2]] + m = aims.Motion(rot[:3]+[trans[0]]+rot[3:6]+[trans[1]]+rot[6:]+[trans[2]]+[0,0,0,1]) + self.refConv.setTransformMatrix('AC-centered Scanner-Based', m.inverse(), m) + except Exception, e: + print "Cannot load Scanner-based referential from T1 pre MRI : "+repr(e) + # Get the hemisphere meshes for the acquisition : name = na + filename base : for example, if the acquisition is T1pre_2000-01-01 and the file head.gii, we want T1pre-head + rdi3 = ReadDiskItem( 'Hemisphere Mesh', 'Anatomist mesh formats', requiredAttributes={'subject':patient, 'acquisition':nameAcq, 'center':self.currentProtocol} ) + hemis = list(rdi3._findValues( {}, None, False ) ) + + + for hh in hemis: + #pdb.set_trace() + self.loadAndDisplayObject(hh, na + '-' + hh.attributes()['side'] + 'Hemi', color=[0.8,0.7,0.4,0.7]) + print "Found hemisphere "+ str(na + '-' + hh.attributes()['side'] + 'Hemi') + + atlas_di = ReadDiskItem('hemisphere marsAtlas parcellation texture', 'aims Texture formats', requiredAttributes={ 'regularized': 'false','subject':patient, 'center':self.currentProtocol, 'acquisition':nameAcq }) + atlas_di_list = list(atlas_di._findValues({}, None, False )) + #probleme + wm_di = ReadDiskItem( 'Hemisphere White Mesh', 'aims mesh formats',requiredAttributes={'subject':patient, 'center':self.currentProtocol }) + + + if len(atlas_di_list) > 0: + for atl in atlas_di_list: + wm_side = wm_di.findValue(atl) + self.loadAndDisplayObject(wm_side, na + '-' + atl.attributes()['side'] + 'MARSATLAS', texture_item = atl, palette = 'MarsAtlas', color=[0.8,0.7,0.4,0.7]) + print "Found hemisphere "+ str(na + '-' + atl.attributes()['side'] + 'MARSATLAS') + dictionnaire_list_images.update({'IRM pre + MARS ATLAS ' + atl.attributes()['side']:['T1pre','T1pre-'+ atl.attributes()['side'] + 'MARSATLAS','electrodes']}) + #pdb.set_trace() + + # Get head mesh for the acquisition + #probleme + rdi3 = ReadDiskItem( 'Head Mesh', 'Anatomist mesh formats', requiredAttributes={'subject':patient, 'acquisition':nameAcq, 'center':self.currentProtocol} ) + head = list(rdi3._findValues( {}, None, False ) ) + if len(head) > 0: # Only if there is one ! + self.loadAndDisplayObject(head[0], na + '-' + 'head', color=[0.0,0.0,0.8,0.3]) + + self.windowContent = dictionnaire_list_images; + self.windowCombo1.clear() + self.windowCombo1.addItems(sorted(dictionnaire_list_images.keys())) + self.windowCombo2.clear() + self.windowCombo2.addItems(sorted(dictionnaire_list_images.keys())) + + self.windowCombo1.setCurrentIndex(max(self.windowCombo1.findText(pre_select_1),0)) + self.windowCombo2.setCurrentIndex(max(self.windowCombo2.findText(pre_select_2),0)) + + # Display referential informations + self.setWindowsReferential() + self.loadElectrodes(self.brainvisaPatientAttributes) + self.refreshAvailableDisplayReferentials() + # Display all + self.allWindowsUpdate() + # Disable the button because no cleanup is attempted when loading a patient when one is already loaded -> there may be a mixup + self.loadPatientButton.setEnabled(False) + self.patientList.setEnabled(False) + + + + # Chargement d'un objet (IRM, mesh...) dans Anatomist et mise à jour de l'affichage + def loadAndDisplayObject(self, diskitem, name = None, color=None, palette=None, texture_item = None): + + if name is None: + return + + #Already exists ! Remove it. + if name in self.dispObj: + self.a.removeObjects([self.dispObj[name],], self.wins) # Remove from windows + self.a.deleteObjects(self.dispObj[name]) # CURRENT + del self.dispObj[name] + del self.diskItems[name] + + print "loading "+repr(diskitem)+ ' as '+name + + obj = self.a.loadObject(diskitem) + # Read all available transforms in the image header (for example the coregistration by SPM to the T1 Pre MRI) + #obj.loadReferentialFromHeader() + if 'ColorPalette' in diskitem.attributes(): + obj.setPalette(palette = diskitem.attributes()['ColorPalette']) + elif palette is not None and texture_item is None: + obj.setPalette(palette = palette) + + if texture_item is not None: + texture = self.a.loadObject(texture_item) + if palette is not None: + texture.setPalette(palette = palette) + #pdb.set_trace() + textured_mesh = self.a.fusionObjects((obj,texture),method = 'FusionTexSurfMethod') + #we need to keep the texture and the mesh as well as the fusion of both + self.objtokeep[name + '_mesh'] = obj + self.objtokeep[name + '_texture'] = texture + obj = textured_mesh + + + # Store the object + self.dispObj[name] = obj + self.diskItems[name] = diskitem + #print "Referential of object %s : %s"%(repr(name), repr(obj.getReferential().uuid())) + # If this is a volume, smooth it : + try: + self.a.execute('TexturingParams', objects=[obj], filtering='linear') + except: + pass + #pdb.set_trace() + if color is not None: + self.a.setMaterial(obj, diffuse=color) + return obj + + + + + def setWindowsReferential(self, ref=None): + """ Get all available referentials from anatomist and tries to match identical referentials from SPM""" + # If the T1pre image is already loaded + if ref is None: + if self.preReferential(): + # Assign the T1pre native referential to the windows + self.currentWindowRef = self.preReferential() + self.a.assignReferential(self.currentWindowRef, self.wins) + + else: + self.currentWindowRef = ref + self.a.assignReferential(ref, self.wins) + + + # Get the click events + def clickHandler(self, eventName, params): + #pos=params['position'] + #currentwin=params['window'] + coords = [0.0,0.0,0.0] + if 'T1pre' in self.dispObj: + pT1Pre = self.a.linkCursorLastClickedPosition(self.dispObj['T1pre'].getReferential()).items() + #pdb.set_trace() + if self.coordsDisplayRef == 'Natif': + coords = pT1Pre + elif self.coordsDisplayRef == 'Scanner-based': + infos = self.t1pre2ScannerBased().getInfos() + rot = infos['rotation_matrix'] + trans = infos['translation'] + m = aims.Motion(rot[:3]+[trans[0]]+rot[3:6]+[trans[1]]+rot[6:]+[trans[2]]+[0,0,0,1]) + coords = m.transform(pT1Pre) + else: + try: + coords = self.refConv.real2AnyRef(pT1Pre, self.coordsDisplayRef) + except: + coords = [0.0,0.0,0.0] + #print type(coords) + if coords is None: + coords = [0.0,0.0,0.0] + self.positionLabel.setText("%.2f, %.2f, %.2f" % tuple(coords)) + + + def preReferential(self): + if 'T1pre' in self.dispObj: + return self.dispObj['T1pre'].getReferential() + else: + return None + + def positionPreRef(self): + return list(self.a.linkCursorLastClickedPosition(self.preReferential()).items()) + + def t1pre2ScannerBased(self): + """ Returns a Transformation object that transforms T1pre referential to T1pre Scanner-Based referential """ + if self.t1pre2ScannerBasedTransform is not None: + if "dead" not in self.t1pre2ScannerBasedTransform.getInfos(): + return self.t1pre2ScannerBasedTransform + rdi = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True,\ + requiredAttributes={'modality':'t1mri', 'subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']}) + allTransf = list (rdi._findValues( {}, None, False ) ) + for trsf in allTransf: + if trsf.attributes()['acquisition'].startswith(u'T1pre'): + print repr(trsf.attributes()) + srcrDiskItem = self.transfoManager.referential( trsf.attributes()['source_referential'] ) + srcr = self.a.createReferential(srcrDiskItem) + dstrDiskItem = self.transfoManager.referential(trsf.attributes()['destination_referential']) + self.t1pre2ScannerBasedId = trsf.attributes()['destination_referential'] + dstr = self.a.createReferential(dstrDiskItem) + self.t1pre2ScannerBasedTransform = self.a.loadTransformation(trsf.fullPath(), srcr, dstr) + return self.t1pre2ScannerBasedTransform + return None + + + def mniReferentialId(self): + return aims.StandardReferentials.mniTemplateReferentialID() + + def mniReferential(self): + return self.a.mniTemplateRef + + def refreshAvailableDisplayReferentials(self): + curr = str(self.referentialCombo.currentText()) + self.referentialCombo.clear() + refs = self.refConv.availableReferentials().keys() + ['Natif',] + print "Available referentials from refConv : "+repr(refs) + self.referentialCombo.addItems(sorted(refs)) + #if curr in refs: + #self.set + + def updateCoordsDisplay(self, text): + self.coordsDisplayRef = str(text) + self.clickHandler(None, None) + + def updateDispMode(self, index): + """ Update the display mode of all electrodes """ + mode = 'sphere' + params = {} + isbipole = False + if index == 0: + mode = 'real' + self.colorConfigButton.setEnabled(False) + elif index == 1: + params = {'diameter':1.0} + self.colorConfigButton.setEnabled(False) + elif index == 2: + params = {'diameter':2.0} + self.colorConfigButton.setEnabled(False) + elif index == 3: + params = {'diameter':5.0} + self.colorConfigButton.setEnabled(False) + elif index == 4: + mode = 'off' + self.colorConfigButton.setEnabled(False) + elif index == 5: + mode = 'bipole' + isbipole = True + #is there a json file about the seeg results in the database. + rdi_seeglabel = ReadDiskItem('Electrodes SEEG Labels','Electrode sEEG Label Format',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']}) + di_seeglabel = list(rdi_seeglabel.findValues({},None,False)) + #if not, ask for one + if len(di_seeglabel) == 0: + load_new_file = True + else: + #ask if you want to replace the loaded data + rep = QtGui.QMessageBox.warning(self, u'Use database or Import?', u"Use sEEG stim result from the database ? (if no, it will ask for a file)", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel) + if rep == QtGui.QMessageBox.Yes: + load_new_file = False + elif rep == QtGui.QMessageBox.No: + load_new_file = True + elif rep == QtGui.QMessageBox.Cancel: + return + + if load_new_file: + wdi_seeg = WriteDiskItem('Electrodes SEEG Labels','Electrode sEEG Label Format') + di_seeg = wdi_seeg.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']} ) + + fichierseegLabel = QtGui.QFileDialog.getOpenFileName(self, "Select a file containing seeg labels: ", "", "(*.xlsx *.csv *.json)") + if os.path.basename(str(fichierseegLabel)).split('.')[-1] == 'json': + fin = open(str(fichierseegLabel),'rb') + new_label = json.loads(fin.read()) + fin.close() + + try: + os.mkdir(os.path.dirname(str(di_seeg))) + except: + pass + fout = open(str(di_seeg),'w') + fout.write(json.dumps({'title':new_label['title'],'contacts':new_label['contacts']})) + fout.close() + + neuroHierarchy.databases.insertDiskItem(di_seeg, update=True ) + + elif os.path.basename(str(fichierseegLabel)).split('.')[-1] == 'xlsx': + + contact_label_class = generate_contact_colors() + + inter_label = contact_label_class.from_excel_files(str(fichierseegLabel)) + + #write the json and include it in the database + try: + os.mkdir(os.path.dirname(str(di_seeg))) + except: + pass + fout = open(str(di_seeg),'w') + fout.write(json.dumps({'title':inter_label[0],'contacts':inter_label[1]})) + fout.close() + + neuroHierarchy.databases.insertDiskItem(di_seeg, update=True ) + new_label = {'title':inter_label[0],'contacts':inter_label[1]} + + else: + fin = open(str(di_seeglabel[0]),'rb') + new_label = json.loads(fin.read()) + fin.close() + + bipole_label_sorted = sorted(new_label['contacts'].keys(),key=natural_keys) + plotsT1preRef = self.getAllPlotsCentersT1preRef() + info_plotsT1Ref= [] + for k,v in plotsT1preRef.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotsT1Ref.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v.list())) + #plots_label[k]=(label,label_name) + + plotsT1Ref_sorted = dict(sorted(info_plotsT1Ref, key=lambda plot_number: plot_number[0])) + + #remplir self.bipole + for i_bipole in bipole_label_sorted: + #get the name of both contact from the bipole name + try: + pos_bipol = (numpy.array(plotsT1Ref_sorted[i_bipole.split()[0].title()]) + numpy.array(plotsT1Ref_sorted[i_bipole.split()[2].title()]))/2 + except: + print("problem plotsT1Ref") + pdb.set_trace() + entry_bipole = numpy.array(plotsT1Ref_sorted[i_bipole.split()[0].title()]) + #orient_vector_bip = (numpy.array(plotsT1Ref_sorted[i_bipole.split()[0]]) - numpy.array(plotsT1Ref_sorted[i_bipole.split()[2]]))/linalg.norm((numpy.array(plotsT1Ref_sorted[i_bipole.split()[0]]) - numpy.array(plotsT1Ref_sorted[i_bipole.split()[2]]))) + #il faut un orient vector + self.addBipole(i_bipole,pos_bipol,self.preReferential().uuid(),entry_bipole) #on rajoute pour finir un vecteur + + + self.colorConfigButton.setEnabled(True) + #show bipole instead of contacts ? + #remove all contacts (mesh and in the list), and set the bipoles instead + + contact_labels_seeg = {} + params.update({'contact_colors':contact_labels_seeg}) + + self.bipoleLabels = new_label + self.configureColors() + + #self.dispObj['electrodes'][0].__getattr__('name') + + #pdb.set_trace() + if mode == self.dispMode and params == self.dispParams: + print "already using the right display mode" + return + self.updateElectrodeMeshes(clear=True) + for elec in self.electrodes: + elec['elecModel'].setDisplayMode(mode, params) + elec['elecModel'].updateDisplay() + elec['elecModel'].setDisplayReferential(elec['ref']) + self.dispMode = mode + self.dispParams = params + self.updateElectrodeMeshes(bipole = isbipole) + # Update the contact list meshes of the current electrode (so they can be selected) + self.electrodeSelect(self.electrodeList.currentRow()) + + + def updateElectrodeMeshes(self, clear=False, bipole=False): + if clear: + print "UPDATE CLEAR -> remove electrodes from windows and delete them" + #traceback.print_stack(limit=4) + self.a.removeObjects(self.dispObj['electrodes'], self.wins) + #self.a.deleteObjects(self.dispObj['electrodes'])# Should be destroyed in electrode.py CURRENT + self.dispObj['electrodes'] = [] + return + if not bipole: + self.dispObj['electrodes'] = [mesh for elec in self.electrodes for mesh in elec['elecModel'].getAnatomistObjects() if mesh is not None] + self.setElectrodeMeshesNames() + elif bipole: + self.dispObj['electrodes'] = [mesh for elec in self.bipoles for mesh in elec['elecModel'].getAnatomistObjects() if mesh is not None] + self.setBipoleMeshesNames() + + #self.dispObj['electrodes'][0].__getattr__('name') + self.allWindowsUpdate() + + # Add an electrode from a template + def addElectrode(self, name=None, model=None, target=[0,0,0], entry=[0,0,-1], refId = None): + if name is None: + name = str(self.nameEdit.text()) + if model is None: + model = str(self.typeComboBox.currentText()) + if refId is not None: + if self.preReferential().uuid() != refId: + print "ERROR : the electrode is not defined in reference to the T1 pre image (%s) but in reference to %s !\nGoing on anyway..."%(self.preReferential().uuid(), refId) + for el in self.electrodes: + if name == el['name']: + name = self.findFreeElectrodeName() + (newRef, transf, elecModel) = createElectrode(target, entry, self.preReferential(), self.a,\ + model = self.elecModelListByName[str(model)].fullPath(), dispMode = self.dispMode, dispParams = self.dispParams) + self.electrodes.append({'name': name, 'ref':newRef, 'transf':transf, 'elecModel':elecModel,\ + 'target':target, 'entry':entry, 'model':model}) + self.electrodeList.addItem(name) + #index = self.elecCombo.findText("Electrode "+str(self.elecname)) + self.electrodeList.setCurrentRow(self.electrodeList.count() - 1) + self.addElectrodeLabel(name, [0,0,-10], newRef, len(self.electrodes) - 1) + self.updateElectrodeMeshes() + + def addBipole(self, name=None, positionbip=[0,0,0], refId = None,entry_bipole = None): + if name is None: + print("error, bipole must have a name") + return + pdb.set_trace() + if refId is None: + print("error, bipole has to be assigned to a referential") + return + pdb.set_trace() + if refId is not None: + if self.preReferential().uuid() != refId: + print "ERROR : the electrode is not defined in reference to the T1 pre image (%s) but in reference to %s !\nGoing on anyway..."%(self.preReferential().uuid(), refId) + #if refId is not None: + #if self.preReferential().uuid() != refId: + #print "ERROR : the electrode is not defined in reference to the T1 pre image (%s) but in reference to %s !\nGoing on anyway..."%(self.preReferential().uuid(), refId) + #check is name is already taken + if len(self.bipoles)>0: + for bip in self.bipoles: + if name == bip['name']: + print("error, bipole name already taken") + + #je met un objet elecmodel ici ou juste le mesh ? un objet elecmodel de 1 contact ? + rdiEM = ReadDiskItem('Electrode Model', 'Electrode Model format', requiredAttributes={'center':self.currentProtocol}) + listEM = list(rdiEM.findValues({},None,False)) + matches = filter((lambda x: u"bipole" in str(x)), listEM) + + (newRef, transf, elecModel) = createBipole(positionbip.tolist(), entry_bipole.tolist(), self.preReferential(), self.a, model = matches[0], dispMode = 'bipole', dispParams = None) + self.bipoles.append({'name': name, 'ref':newRef, 'transf':transf, 'target':positionbip.tolist(), 'entry': entry_bipole.tolist(), 'elecModel':elecModel}) #to change target and entry + #on ne touche pas à electrodeList + #self.electrodeList.addItem(name) + #index = self.elecCombo.findText("Electrode "+str(self.elecname)) + #self.electrodeList.setCurrentRow(self.electrodeList.count() - 1) + + self.addElectrodeLabel(name, [0,0,-10], newRef, len(self.bipoles) - 1, True) + #self.updateElectrodeMeshes(bipole=True) + + + # Setting names on meshes to get a nice tooltip for each mesh + def setElectrodeMeshesNames(self, electrode = None): + if electrode is None: + electrodes = self.electrodes + else: + electrodes = [electrode,] + for el in electrodes: + for name, element in el['elecModel'].getDisplayed().iteritems(): + if element['mesh'] is not None: + if element['type'] == 'Plot': + element['mesh'].setName(name.replace('Plot', el['name'])) + else: + element['mesh'].setName(el['name']) + #element['mesh'].setChanged() + #element['mesh'].notifyObservers() #Should be needed to refresh display, but it works without it + + def setBipoleMeshesNames(self, bipole = None): + if bipole is None: + bipoles = self.bipoles + else: + bipoles = [bipole,] + for bp in bipoles: + for name, element in bp['elecModel'].getDisplayed().iteritems(): + element['mesh'].setName(bp['name']) + + def findFreeElectrodeName(self): + if len(self.electrodes) == 0: + return 'A' + n = [el['name'] for el in self.electrodes] + newName = n[-1] + firstletter = newName[::-1][-1] + if firstletter in string.ascii_uppercase: + newName = string.uppercase[(string.uppercase.find(firstletter)+1)%len(string.uppercase)] + newName[1:] + if newName in n: + while newName in n: + newName = newName+'_' + return newName + + def currentElectrode(self): + idx = self.electrodeList.currentRow() + print "Electrode %i is selected"%idx + if idx < 0: + return None + return self.electrodes[idx] + + def removeElectrode(self): + """Remove an electrode (and all contacts)""" + elec = self.currentElectrode() + idx = self.electrodes.index(elec) + if elec is None: + return + # Remove meshes from Anatomist + self.updateElectrodeMeshes(clear=True) + elec['elecModel'].clearDisplay() + item = self.electrodeList.takeItem(idx) + del item + del self.electrodes[idx] + self.updateElectrodeMeshes() + + def updateElectrodeModel(self, model): + elec = self.currentElectrode() + if elec is None: + return + if str(elec['model']) == str(model): + return + #import pdb; pdb.set_trace() + self.updateElectrodeMeshes(clear=True) + elec['elecModel'].clearDisplay() + del elec['elecModel'] + (newRef, transf, elecModel) = createElectrode(elec['target'], elec['entry'], self.preReferential(), self.a,\ + model = self.elecModelListByName[str(model)].fullPath(), dispMode = self.dispMode, dispParams = self.dispParams) + elec['elecModel'] = elecModel + elec['model']=str(model) + self.electrodeSelect(self.electrodeList.currentRow()) + self.updateElectrodeMeshes() + + + def updateEntry(self, e=None): + """ Updates the current electrode entry point from the cursor position""" + el = self.currentElectrode() + pos = self.positionPreRef() + # Just ignore if new entry is identical to target + if pos == el['target']: + return + + (newRef, transf) = moveElectrode(el['target'], pos, self.preReferential(),\ + el['ref'], self.a, el['elecModel'].getAnatomistObjects()) + el['entry'] = pos + el['transf'] = transf + + def updateTarget(self, t=None): + """ Updates the current electrode target point from the cursor position""" + el = self.currentElectrode() + if el is None: + return + pos = self.positionPreRef() + # Just ignore if new target is identical to entry + if pos == el['entry']: + return + + (newRef, transf) = moveElectrode(pos, el['entry'], self.preReferential(),\ + el['ref'], self.a, el['elecModel'].getAnatomistObjects()) + el['target'] = pos + el['transf'] = transf + print repr(self.a.getReferentials()) + + + def editElectrodeName(self): + """Update the electrode name of the selected contact""" + name = str(self.nameEdit.text()) + idx = self.electrodeList.currentRow() + sameNameItems = self.electrodeList.findItems(name, QtCore.Qt.MatchFixedString) + if len(sameNameItems) != 0: + if sameNameItems[0] == self.electrodeList.item(idx): # Name was not changed + return + else: + QtGui.QMessageBox.warning(self, u'Error', u"The name %s is already used by another electrode. Choose an other one !"%name) + self.nameEdit.setText(self.electrodeList.item(idx).text()) + self.electrodes[idx]['name'] = name + self.setElectrodeMeshesNames(self.electrodes[idx]) + self.electrodeList.currentItem().setText(name) + self.electrodeSelect(idx) # updates the contacts' display + + + def electrodeSelect(self, idx): + """Electrode/contact selection changed""" + el = self.electrodes[idx] + self.nameEdit.setText(el['name']) + self.typeComboBox.setCurrentIndex(self.typeComboBox.findText(el['model'])) + #import pdb;pdb.set_trace() + # Select the contacts in anatomist + g = self.a.getDefaultWindowsGroup() + g.setSelection(el['elecModel'].plotMeshes()) + self.currentContacts = dict((name.replace('Plot', el['name']), element['mesh']) for name, element in el['elecModel'].getDisplayed().iteritems() if element['type'] == 'Plot' and element['mesh'] is not None) + self.currentElectrodes = [el,] + #Update contact list + self.contactList.clear() + self.contactList.addItems(sorted(self.currentContacts.keys(), key=natural_keys)) + self.updateElectrodeView() + + def electrodeGo(self, idx = None, electrode = None): + if idx is not None: + if type(idx) == int: + electrode = self.electrodes[idx] + else: + electrode = self.currentElectrodes[0] + elif electrode is None: + return + self.contactGo(el = electrode) + + def contactSelect(self, item): + # Select the contacts in anatomist + print "Click on the contact " + str(item.text()) + g = self.a.getDefaultWindowsGroup() + #print "CurrentContacts = "+repr(self.currentContacts.keys()) + g.setSelection([self.currentContacts[str(item.text())],]) + + def contactGo(self, item = None, el=None): + # Put the cursor on the contact in anatomist + #print "Double clic sur le contact " + str(item.text()) + try: + if el is None: + el = self.currentElectrodes[0] + if item is not None: + name = str(item.text()).replace(el['name'], 'Plot') + else: + name = 'Plot1' + xyz = getPlotsCenters(el['elecModel'])[name] + # setLinkedCursor uses window referential : must apply transform before setting the position + if self.currentWindowRef == self.preReferential(): + xyz = el['transf'].transform(xyz) + self.wins[0].moveLinkedCursor(xyz) + #self.a.execute('LinkedCursor', window=self.wins[0], position=xyz) + elif self.currentWindowRef == el['ref']: + self.wins[0].moveLinkedCursor(xyz) + else: + print "Warning : Current window referential is not T1pre referential ! Cannot set the linkedCursor on the selected electrode contact..." + except: + print "Error moving the cursor to the contact" + + + def addElectrodeLabel(self, label, position, ref, elecId,bipole=False): + props = Props() + props.usespheres = False + props.center = [0, 0, 0] + gc = aims.Point3df(position) + if not bipole: + self.electrodes[elecId]['labelObjects'] = makelabel( self.a, label, gc, gc+aims.Point3df([5,0,0]), ref, (0, 0, 0, 0), props ) + self.electrodes[elecId]['props'] = props + elif bipole: + self.bipoles[elecId]['labelObjects'] = makelabel( self.a, label, gc, gc+aims.Point3df([5,0,0]), ref, (0, 0, 0, 0), props ) + self.bipoles[elecId]['props'] = props + + def getElectrodeTemplates(self): + """Returns a list of Electrode objects, one for each available electrode template model available in the DB""" + if self.electrodeTemplateStubs == []: + self.electrodeTemplateStubs = dict([(n,ElectrodeModel(modelPath=model.fullPath(), dispMode='off')) for n, model in self.elecModelListByName.iteritems()]) + return self.electrodeTemplateStubs + + def fitElectrodeModelToLength(self, target, entry): + """ Tries to find a match between the length of the electrode and a model, but prefering uniform electrodes (no variable spacing between contacts""" + length = linalg.norm(array(entry)-array(target)) + + models = self.getElectrodeTemplates() + uniformModelsLength = {} + for n,model in models.iteritems(): + interPlotsM=[] + plotsM = sorted([[int(''.join(e for e in namePlot if e.isdigit())), ] + content['center'] for namePlot, content in model.getPlots().iteritems()], key=lambda p:p[0]) + + for p in range(len(plotsM)-1): + interPlotsM.append(math.sqrt((plotsM[p][1]-plotsM[p+1][1])**2 + (plotsM[p][2]-plotsM[p+1][2])**2 + (plotsM[p][3]-plotsM[p+1][3])**2)) + lengthM = sum(interPlotsM) + if len(set(interPlotsM)) == 1: # All intervals are identical + uniformModelsLength[n] = lengthM + if length >= max(uniformModels.values()): + return [m for m,l in uniformModels.iteritems() if l == max(uniformModels.values())][0] + else: + largerModels = dict([(m,l) for m,l in uniformModels.iteritems() if l >= length]) + return [m for m,l in largerModels.iteritems() if l == min(largerModels.values())][0] + + + def fitElectrodeModelToPlots(self, plots): + """ Tries to find a match between a list of plots [[numPlot, x, y, z],[...], ...] and available electrode templates. + Return None if it fail, [ModelName, [targetX, targetY, targetZ], [entryX, entryY, entryZ]] if it works + """ + + plots = sorted(plots, key=lambda p:int(p[0])) + # Compute inter-contact distances + interPlots=[] + for p in range(len(plots)-1): + interPlots.append(math.sqrt((plots[p][1]-plots[p+1][1])**2 + (plots[p][2]-plots[p+1][2])**2 + (plots[p][3]-plots[p+1][3])**2)) + # Find electrode models with a similar number of plots + models = dict([(n,tpl) for n,tpl in self.getElectrodeTemplates().iteritems() if tpl.countPlots() == len(plots)]) # identical number + if len(models) == 0: + print "Cannot find a template with the right number of contacts (%i), trying longer ones"%len(plots) + nbPlotsModels = dict([(n, tpl.countPlots()) for n,tpl in self.getElectrodeTemplates().iteritems() if tpl.countPlots() > len(plots)]) + if len(nbPlotsModels) == 0: + print "Cannot find a template with enough contacts for this electrode ! (available : %s)\nWill match with the largest available electrodes !\n THIS WILL LOSE SOME PLOTS"%repr(nbPlotsModels.values()) + nbPlotsModels = dict([(n, tpl.countPlots()) for n,tpl in self.getElectrodeTemplates().iteritems()]) + models = dict([(n,tpl) for n,tpl in self.getElectrodeTemplates().iteritems() if tpl.countPlots() == max(nbPlotsModels.values())]) + else: + models = dict([(n,tpl) for n,tpl in self.getElectrodeTemplates().iteritems() if tpl.countPlots() == min(nbPlotsModels.values())]) + + # Now, check the interPlots distance in the model and compare with the template + distanceFromModel = {} + for n,model in models.iteritems(): + interPlotsM=[] + plotsM = sorted([[int(''.join(e for e in namePlot if e.isdigit())), ] + content['center'] for namePlot, content in model.getPlots().iteritems()], key=lambda p:p[0]) + + for p in range(len(plotsM)-1): + interPlotsM.append(math.sqrt((plotsM[p][1]-plotsM[p+1][1])**2 + (plotsM[p][2]-plotsM[p+1][2])**2 + (plotsM[p][3]-plotsM[p+1][3])**2)) + distanceFromModel[n] = sum([(interPlotsM[i]-interPlots[i])**2 for i in range(min([len(interPlotsM), len(interPlots)]))]) + + # Choose the model with the smallest distance, or the first one if a few are equally good, reject if sum is more than 1mm per contact + minDist = min(distanceFromModel.values()) + if minDist > 1.0*len(plots): + print "Cannot match a template : minimum distance found is %f mm, should be %f or less !"%(minDist, 1.0*len(plots)) + return None + # We have a winner ! + goodModel = [m for m in distanceFromModel if distanceFromModel[m] == minDist][0] + print "Found model %s, match distance = %f"%(goodModel, minDist) + #import pdb; pdb.set_trace() + entry = plots[-1][1:] + # Target is not the center of the first contact, but its end ! -> coords - lengthOfPlot/2*vector(plot0->plotLast) + target = array(plots[0][1:]) - (array(plotsarr[-1][1:])-array(plots[0][1:]))/linalg.norm(array(plots[-1][1:])-array(plots[0][1:])) * 0.5 * self.getElectrodeTemplates()[goodModel].getCylinder('Plot1')['length'] + return [goodModel, target.tolist(), entry] + + + def comboMessageBox(self, text, choices): + """ Displays a message box with a choice (combobox), Ok and Cancel button + Returns the selected value or None if it was cancelled""" + if choices is None or choices == []: + return None + msgBox = QtGui.QMessageBox() + msgBox.setText(text) + combo = QtGui.QComboBox() + combo.addItems(choices) + msgBox.layout().addWidget(combo,1,0) + msgBox.addButton(QtGui.QPushButton('Ok'), QtGui.QMessageBox.AcceptRole) + msgBox.addButton(QtGui.QPushButton('Annuler'), QtGui.QMessageBox.RejectRole) + ret = msgBox.exec_(); + if ret == QtGui.QMessageBox.Cancel: + return None + return str(combo.currentText()) + + def loadPTSbasic(self, path): + """Load a PTS file, creating an 'electrode model' for each contact (VERY slow with > 50 contacts) """ + refId = self.preReferential().uuid() + els = [] + elecs = {} + try: + f = open(path, 'r') + lines = f.readlines() + f.close() + lines.reverse() + if not lines.pop().startswith('ptsfile'): + print 'This is not a valid PTS file !' + return (refId, []) + lines.pop() # Useless line 1 1 1 + nb = int(lines.pop()) # Number of contacts + for i in range(nb): + l = lines.pop().rstrip().split("\t") # name x y z 0 0 0 2 2.0 (last ones may be contact length/diameter ?) + name = ''.join(e for e in l[0] if not e.isdigit()) + if name not in elecs: + elecs[name]=[] + plot = int(''.join(e for e in l[0] if e.isdigit())) + coords = list(self.refConv.anyRef2Real([float(l[1]), float(l[2]),float(l[3])], 'Scanner-based')) + nameplot = l[0] + elecs[name].append ( [plot,] + coords) + els.append( {'name':nameplot, 'model':'plot2mmD1mmCentered', 'target': coords, 'entry':coords[0:2]+[coords[2]+1.0,]} ) + except: + print "Error reading PTS file %s"%path + return (refId, els) + + def loadPTS(self, path): + """Load a PTS file (tries to find a suitable electrode model in the available templates) """ + refId = self.preReferential().uuid() + els = [] + elecs = {} + #try: + f = open(path, 'r') + lines = f.readlines() + f.close() + + # The coordinates in the PTS are expressed in which referential ? + refOfPts = self.comboMessageBox(u'Importation d\'un fichier PTS. Choisissez le référentiel utilisé (Scanner-based...)', sorted(self.refConv.availableReferentials().keys())) + if refOfPts is None: + print "User cancelled PTS importation, or no valid referential found" + return + print "PTS import referential : %s"%repr(refOfPts) + lines.reverse() + if not lines.pop().startswith('ptsfile'): + print 'This is not a valid PTS file !' + return (refId, []) + lines.pop() # Useless line 1 1 1 + nb = int(lines.pop()) # Number of contacts + for i in range(nb): # All lines (= all plots) + l = lines.pop().rstrip().split() # name x y z 0 0 0 2 2.0 (last ones may be contact length/diameter ?) + name = ''.join(e for e in l[0] if not e.isdigit()) + + print l[0] + plot = ''.join(e for e in l[0] if e.isdigit()) + if plot == '': + continue + plot = int(plot) + + if name not in elecs: + elecs[name]=[] + + coords = list(self.refConv.anyRef2Real([float(l[1]), float(l[2]),float(l[3])], refOfPts)) + nameplot = l[0] + elecs[name].append ( [plot,] + coords) + #els.append( {'name':nameplot, 'model':'plot2mmD1mmCentered', 'target': coords, 'entry':coords[0:2]+[coords[2]+1.0,]} ) + # Iterate over all electrodes + for k,l in elecs.iteritems(): + # Try to get a real model from l [[numPlot, x,y,z], [...], ...] + res = self.fitElectrodeModelToPlots(l) + if res is not None: + els.append( {'name':k.lower(), 'model':res[0], 'target': res[1], 'entry':res[2]} ) + else: + print "Could not find model matching electrode %s, adding individual contacts."%k + for pl in l: + coords = pl[1:] + els.append( {'name':k+str(pl[0]), 'model':'plot2mmD1mmCentered', 'target': coords, 'entry':coords[0:2]+[coords[2]+1.0,]} ) + + #except: + # print "Error reading PTS file %s"%path + return (refId, els) + + def loadElectrodeTXT(self, path): + """Load an electrode.txt file with triplets of lines : nameOfElectrode\n X1 Y1 Z1\n X2 Y2 Z2 such as used by ImaGIN""" + els=[] + f = open(path, 'r') + lines = f.readlines() + f.close() + lines.reverse() + + # The coordinates in the TXT are expressed in which referential ? + refOfTxt = self.comboMessageBox(u'Importation d\'un fichier electrode TXT. Choisissez le référentiel utilisé (Scanner-based a priori)', sorted(self.refConv.availableReferentials().keys())) + if refOfTxt is None: + print "User cancelled electrode TXT importation, or no valid referential found" + return + print "TXT electrode import referential : %s"%repr(refOfTxt) + + while (len(lines) >= 3): + try: + name = lines.pop() + targ = map (float,lines.pop().replace(',','.').split()) + entr = map (float,lines.pop().replace(',','.').split()) + if len(targ) == 3 and len(entr) == 3 and len(name)>0: + targ = list(self.refConv.anyRef2Real(targ, refOfTxt)) + entr = list(self.refConv.anyRef2Real(entr, refOfTxt)) + els.append( {'name':name.lower(), 'model':fitElectrodeModelToLength(targ, entr), 'target': targ, 'entry':entr} ) + else: + print "Invalid lines in electrode txt file : %s, %s, %s"%(repr(name), repr(targ), repr(entr)) + except: + pass + + refId = self.preReferential().uuid() + return (refId, els) + + + def loadElectrodes(self, patient=None): + """Load electrode implantation (if already entered) from BrainVisa or from a file""" + path = None + #import pdb;pdb.set_trace() + if patient is not None: + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format', requiredAttributes={'subject':patient['subject'], 'center':patient['center']} ) + elecs = list(rdi._findValues( {}, None, False ) ) + if len(elecs) == 1: + path = elecs[0].fileName() + elif len(elecs) > 1: + print "CAREFUL : more than one electrode implantation are available, strange -> load the first found one" # TODO Dialogue de choix + path = elecs[0].fileName() + else: # No implantation available + print "no electrode implantation found" + return + if not path: + path = str(QtGui.QFileDialog.getOpenFileName(self, "Open electrode implantation", "", "All implantations(*.elecimplant *.pts *.txt);;Electrode implantation (*.elecimplant);;PTS file (*.pts);;Electrode.txt (*.txt)")) + + if not path: + return + # Check if we have a PTS/TXT/elecimplant file + extension = os.path.splitext(path)[1].lower() + els = [] + refId = None + if extension == '.elecimplant': + filein = open(path, 'rb') + try: + dic = json.loads(filein.read()) + except: + filein.close() + filein = open(path, 'rb') + dic = pickle.load(filein) + + filein.close() + els = dic['electrodes'] + refId = dic['ReferentialUuid'] + + elif extension == '.txt': + (refId, els) = self.loadElectrodeTXT(path) # Verifier que c'est un electrode.txt, si c'est un electrode_Pos ou electrode_Name on peut zapper ? + elif extension == '.pts': + (refId, els) = self.loadPTS(path) + # Demander le référentiel, ou deviner si le nom contient _MNI ? + else: + print "file format unknown : %s !"%extension + QtGui.QMessageBox.warning(self, u'Erreur', u"the file format has not been recognized : %s"%extension) + + if refId != self.preReferential().uuid(): + print "CAREFUL: electrodes load are defined in an other referential that the one of the T1 pre, problem possible !" + #indices = [3,7,11, 0,1,2, 4,5,6, 8,9,10] + #if dic['2mni'] is not None and 'T1pre' not in self.transf2Mni: + #trsf = dic['2mni'] + #self.transf2Mni['T1pre'] = self.a.createTransformation([trsf[i] for i in indices], self.preReferential(), self.mniReferential()) + for e in els: + self.addElectrode(e['name'], e['model'], e['target'], e['entry'], refId) + + + def saveElectrodes(self): + """Save electrode implantation in BrainVisa Database""" + # Saving : electrode model, name, target and entry point + els = [dict((k,el[k]) for k in ['name', 'target', 'entry', 'model']) for el in self.electrodes] + # Save Referential UID which is the base of electrode coordinates + refId = self.preReferential().uuid() + print 'Sauvegarde electrodes'+repr(els)+"\nReferential UUID : "+refId + path = None + di = None + if self.brainvisaPatientAttributes is not None: + wdi = WriteDiskItem( 'Electrode implantation', 'Electrode Implantation format' ) + di = wdi.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']} ) + if not di: + print "Cannot find a valid path to store the electrode implantation for the current patient !" + QtGui.QMessageBox.warning(self, u'Erreur', u"Cannot find a valid path to store the electrode implantation for the current patient !") + else: + path = di.fileName() + createItemDirs(di) + if not path: + path = str(QtGui.QFileDialog.getSaveFileName(self, "Save electrode implantation", "", "Electrode implantation (*.elecimplant)")) + if not path: + return + # If there is no extension, add the standard one ! + + if os.path.splitext(path)[1] == '': + path = path+'.elecimplant' + + plotsT1preRef = self.getAllPlotsCentersT1preRef() + info_plotsT1Ref= [] + for k,v in plotsT1preRef.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotsT1Ref.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v.list())) + #plots_label[k]=(label,label_name) + + plotsT1Ref_sorted = sorted(info_plotsT1Ref, key=lambda plot_number: plot_number[0]) + #previous_data.update({'plotsMNI':info_plotMNI}) + + fileout = open(path, 'wb') + fileout.write(json.dumps({'electrodes':els, 'ReferentialUuid':refId, '2mni':None, 'timestamp':time.time(),'plotsT1Nat':plotsT1Ref_sorted})) + #pickle.dump({'electrodes':els, 'ReferentialUuid':refId, '2mni':None, 'timestamp':time.time()}, fileout) + fileout.close() + if di is not None: + neuroHierarchy.databases.insertDiskItem( di, update=True ) + QtGui.QMessageBox.information(self, u'Implantation saved', u"Implantation has been saved in database. Careful, it deleted MNI information if there was any. you'll have to do the normalization again") + + def convertT1ScannerBasedToMni(self, points): + """Converts an array of points [x,y,z] in scanner-based coords to MNI coords if deformation field is available""" + field = self.getT1preMniTransform() + if field is None: + print "MNI deformation field not found" + return None + #pdb.set_trace() + tmpOutput = getTmpFilePath('csv') + arr = numpy.asarray(points)#([ [1,2,3], [4,5,6], [7,8,9] ]) + numpy.savetxt(tmpOutput, arr, delimiter=",") + matlabRun(spm_normalizePoints % ("'"+self.spmpath+"'",field, tmpOutput, tmpOutput)) + out = numpy.loadtxt(tmpOutput, delimiter=",") + #pdb.set_trace() + os.remove(tmpOutput) + + if numpy.array_equal(out, arr): + print "Points to MNI : Error, result read is identical to input" + return None + if out.shape != arr.shape: + print "Points to MNI : Error, result (%s) has not the same number of elements as input (%s)"%(repr(out),repr(arr)) + return None + return out.tolist() + + # Non blocking wrapper of getAllPlotsCentersMNIRef + def getAllPlotsCentersMNIRefNB(self, plots, toKeep=None): + """ Computes the MNI coordinates of plots from t1 pre scanner-based coordinaotes in a thread (non-blocking) + then call finishAllPlotsCentersMNIRef with the toKeep elements : these will determine how the data is saved + + """ + pe = PythonExecutor(lambda myself=self, thePlots=plots: myself.getAllPlotsCentersMNIRef(thePlots), toKeep=toKeep) + self.threads.append(pe) + # Remove it from the list of threads when finished + pe.finished.connect(lambda th=pe:self.finishAllPlotsCentersMNIRef(th)) + pe.start() + + + def finishAllPlotsCentersMNIRef(self, thread): + """ Callback function when MNI coordinates of plots are computed. Will save to basepath + or to provided diskItems (in 'kept' objects of the thread - which must be a PythonExecutor) + """ + plotsMNI = thread.output() + kept = thread.kept() + try: + self.threads.remove(thread) + except: + pass + if plotsMNI is None: + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nMNI normalization failed !.") + return + + if 'basepath' in kept:# custom path + self.saveTXT(path=kept['basepath']+'_MNI.txt', referential='MNI') + self.savePTS(path=kept['basepath']+'_MNI.pts', referential='MNI') + elif all (k in kept for k in ('wdiptsmni','timestamp','wditxtmnipos', 'wditxtmniname')): # find and save in DB + try: + self.savePTS(path = kept['wdiptsmni'].fullPath(), contacts = plotsMNI) + kept['wdiptsmni'].setMinf('referential', self.mniReferentialId()) + kept['wdiptsmni'].setMinf('timestamp', kept['timestamp']) + neuroHierarchy.databases.insertDiskItem(kept['wdiptsmni'], update=True ) + self.saveTXT(pathPos=kept['wditxtmnipos'].fullPath(), pathName=kept['wditxtmniname'].fullPath(), contacts = plotsMNI) + neuroHierarchy.databases.insertDiskItem(kept['wditxtmniname'], update=True ) + kept['wditxtmnipos'].setMinf('referential', self.mniReferentialId()) + kept['wditxtmnipos'].setMinf('timestamp', kept['timestamp']) + neuroHierarchy.databases.insertDiskItem(kept['wditxtmnipos'], update=True ) + except: + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nThe saving of the MNI normalization failed.") + return + else: + print "Erreur lors de l'exportation PTS/TXT dans le référentiel MNI" + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nMNI normalization failed.") + return + + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nMNI normalization has been applied") + + #add to the elecimplant file + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format' ,requiredAttributes={'center':self.brainvisaPatientAttributes['center'],'subject':self.brainvisaPatientAttributes['subject']}) + di=rdi.findValues({},None,False) + ldi = list(rdi.findValues({},None,False)) + + if len(ldi) >0: + if (os.path.exists(str(ldi[0]))): + filein = open(str(ldi[0]), 'rb') + try: + previous_data = json.loads(filein.read()) + except: + filein.close() + filein = open(str(ldi[0]), 'rb') + previous_data = pickle.load(filein) + + filein.close() + + info_plotMNI= [] + for k,v in plotsMNI.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotMNI.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + #plots_label[k]=(label,label_name) + + plotMNI_sorted = sorted(info_plotMNI, key=lambda plot_number: plot_number[0]) + previous_data.update({'plotsMNI':info_plotMNI}) + + #resave as json file + fout = open(str(ldi[0]),'w') + fout.write(json.dumps(previous_data)) + fout.close() + #pdb.set_trace() + neuroHierarchy.databases.insertDiskItem([x for x in di][0], update=True ) + print ".elecimplant done with MNI" + + print("start generate dictionaries") + self.parcelsExportElectrodes(Callback=lambda:[self.marsatlasExportResection(),self.exportCSVdictionaries(),self.generateMappingContactCortex(),self.generateTemplateBipoleStimulationFile(),self.screenshot(),self.makeMP4(),self.calculParcel()]) + + # Normalize the coordinates and export them in PTS format and TXT format + def normalizeExportElectrodes(self, saveInDB=True): + timestamp = time.time() + plots = self.getAllPlotsCentersT1preScannerBasedRef() + if not saveInDB: # Choose the output file name + basepath = str(QtGui.QFileDialog.getSaveFileName(self, 'Choose a file name for exported files', "", "Electrode implantation TXT files (*.txt)")) + if not basepath: + return + basepath = os.path.splitext(basepath)[0] + self.saveTXT(path=basepath+'.txt', contacts=plots) + self.savePTS(path=basepath+'.pts', contacts=plots) + plotsMNI = self.getAllPlotsCentersMNIRefNB(plots, toKeep={'basepath':basepath}) + return + else: # Find the right places in the Database + # T1-pre scanner-based referential + wdipts = WriteDiskItem('Electrode Implantation PTS', 'PTS format', requiredAttributes={'no_ref_name':'True'}).findValue(self.diskItems['T1pre'])#,_debug= sys.stdout requiredAttributes={'ref_name':'default'} + wditxtpos = WriteDiskItem('Electrode Implantation Position TXT', 'Text file', requiredAttributes={'no_ref_name':'True'}).findValue(self.diskItems['T1pre']) + wditxtname = WriteDiskItem('Electrode Implantation Name TXT', 'Text file', requiredAttributes={'no_ref_name':'True'}).findValue(self.diskItems['T1pre']) + if wdipts is None or wditxtpos is None or wditxtname is None: + print "Cannot find a path to save PTS or TXT files in the database !" + return + if plots is None: + print "Cannot get the scanner-based plots coords" + return + self.savePTS(path = wdipts.fullPath(), contacts=plots) + wdipts.setMinf('referential', self.t1pre2ScannerBasedId) + wdipts.setMinf('timestamp', timestamp) + neuroHierarchy.databases.insertDiskItem(wdipts, update=True ) + self.saveTXT(pathPos=wditxtpos.fullPath(), pathName=wditxtname.fullPath(), contacts=plots) + neuroHierarchy.databases.insertDiskItem(wditxtname, update=True ) + wditxtpos.setMinf('referential', self.t1pre2ScannerBasedId) + wditxtpos.setMinf('timestamp', timestamp) + neuroHierarchy.databases.insertDiskItem(wditxtpos, update=True ) + + # MNI referential + if self.getT1preMniTransform() is None: + QtGui.QMessageBox.information(self, u'Implantation sauvegardée', u"Implantation has been exported in PTS/TXT file formats in database\nMNI normlization is not available (not found in database).") + return + wdiptsmni = WriteDiskItem('Electrode Implantation PTS', 'PTS format', requiredAttributes={'ref_name':'MNI'}).findValue(self.diskItems['T1pre']) + wditxtmnipos = WriteDiskItem('Electrode Implantation Position TXT', 'Text file', requiredAttributes={'ref_name':'MNI'}).findValue(self.diskItems['T1pre']) + wditxtmniname = WriteDiskItem('Electrode Implantation Name TXT', 'Text file', requiredAttributes={'ref_name':'MNI'}).findValue(self.diskItems['T1pre']) + if wdiptsmni is None or wditxtmnipos is None or wditxtmniname is None: + print "Cannot find a path to save MNI PTS or TXT files in the database !" + else: + plotsMNI = self.getAllPlotsCentersMNIRefNB(plots, toKeep={'wdiptsmni':wdiptsmni, 'timestamp':timestamp, 'wditxtmnipos':wditxtmnipos, 'wditxtmniname':wditxtmniname}) + + # AC-PC referential + if self.refConv.isRefAvailable('AC-PC'): + wdiptsacpc = WriteDiskItem('Electrode Implantation PTS', 'PTS format', requiredAttributes={'ref_name':'ACPC'}).findValue(self.diskItems['T1pre']) + if wdiptsacpc is None: + print "Cannot find a path to save AC-PC PTS file in the database !" + else: + plotsACPC = self.getAllPlotsCentersAnyReferential('AC-PC') + self.savePTS(path = wdiptsacpc.fullPath(), contacts=plotsACPC) + wdiptsacpc.setMinf('referential', 'AC-PC') + wdiptsacpc.setMinf('timestamp', timestamp) + neuroHierarchy.databases.insertDiskItem(wdiptsacpc, update=True ) + + #return + + #print("start generate dictionaries") + #self.marsatlasExportElectrodes(Callback=lambda:[self.marsatlasExportResection(),self.exportCSVdictionaries(),self.generateMappingContactCortex()]) + + def generateDictionaries(self): + + if self.generateDictionariesComboBox.currentIndex()==1: + self.parcelsExportElectrodes() + elif self.generateDictionariesComboBox.currentIndex()==0: + #Pour que l'exportResection et l'exportCSVdictionaries attendent que export electrodes soit fini + self.parcelsExportElectrodes(Callback=lambda:[self.marsatlasExportResection(),self.exportCSVdictionaries(),self.generateMappingContactCortex(),self.generateTemplateBipoleStimulationFile(),self.screenshot(),self.makeMP4(),self.calculParcel()]) + #self.marsatlasExportResection() + #self.exportCSVdictionaries() + elif self.generateDictionariesComboBox.currentIndex()==2: + self.marsatlasExportResection() + elif self.generateDictionariesComboBox.currentIndex()==3: + self.exportCSVdictionaries() + elif self.generateDictionariesComboBox.currentIndex()==4: + self.generateMappingContactCortex() + elif self.generateDictionariesComboBox.currentIndex()==5: + self.generateTemplateBipoleStimulationFile() + elif self.generateDictionariesComboBox.currentIndex()==6: + self.screenshot() + elif self.generateDictionariesComboBox.currentIndex()==7: + self.makeMP4() + elif self.generateDictionariesComboBox.currentIndex()==8: + self.calculParcel() + elif self.generateDictionariesComboBox.currentIndex()==9: + self.generateFiberContactDistance() + + def screenshot(self): + #Check if all the volumes are available. + #self.verifParcel allows us to know if the verification has already been made, in that case we won't do it again + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = Mask_left.findValue(self.diskItems['T1pre']) + + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = Mask_right.findValue(self.diskItems['T1pre']) + + MaskGW_right = ReadDiskItem('Right Grey White Mask','Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskGW_right = MaskGW_right.findValue(self.diskItems['T1pre']) + + MaskGW_left = ReadDiskItem('Left Grey White Mask','Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskGW_left = MaskGW_left.findValue(self.diskItems['T1pre']) + + if diMaskleft is None or diMaskright is None or diMaskGW_right is None or diMaskGW_left is None : + #if a parcellation is missing we won't be able to make the screenshot, so we exit the function + print "No parcellisation found." + return + else: + #we take out the cursor + self.a.config()[ 'linkedCursor' ] = 0 + #and replace the electrodes realistic model with 2mm spheres, which are more visible + self.updateDispMode(2) + + #Right hemisphere + #opens an Anatomist window and loads the parcellation and the electrodes + w2=self.a.createWindow("Sagittal") + contWin=self.windowContent['IRM pre + MARS ATLAS right'] + content=[x for x in contWin if "rightMARSATLAS" in x] + ele=[x for x in contWin if "electrode" in x] + elec=self.dispObj[ele[0]] + for el in elec: + w2.addObjects(el) + image = self.dispObj[content[0]] + w2.addObjects(image) + time.sleep(1) + w2.windowConfig(snapshot="/tmp/"+self.brainvisaPatientAttributes['subject']+"RightHemiSagittal.png") + #rotates the view by 180° + w2.camera(view_quaternion=[-0.5, 0.5, 0.5, -0.5]) + #waits a second so that the window has the tame to be updated before the next screenshot, they are saved in the tmp repertory + time.sleep(1) + w2.windowConfig(snapshot="/tmp/"+self.brainvisaPatientAttributes['subject']+"RightHemiSagittalRot.png") + + w2.close() + + #Left hemisphere + w21=self.a.createWindow("Sagittal") + contWin=self.windowContent['IRM pre + MARS ATLAS left'] + content=[x for x in contWin if "leftMARSATLAS" in x] + ele=[x for x in contWin if "electrode" in x] + elec=self.dispObj[ele[0]] + for el in elec: + w21.addObjects(el) + image = self.dispObj[content[0]] + w21.addObjects(image) + time.sleep(1) + w21.windowConfig(snapshot="/tmp/"+self.brainvisaPatientAttributes['subject']+"LeftHemiSagittal.png") + w21.camera(view_quaternion=[-0.5, 0.5, 0.5, -0.5]) + time.sleep(1) + w21.windowConfig(snapshot="/tmp/"+self.brainvisaPatientAttributes['subject']+"LeftHemiSagittalRot.png") + w21.close() + + #puts the cursor back + self.a.config()[ 'linkedCursor' ] = 1 + #opens the pictures of the left and right brain which were taken previously + images1 = map(Image.open, ["/tmp/"+self.brainvisaPatientAttributes['subject']+"RightHemiSagittal.png", "/tmp/"+self.brainvisaPatientAttributes['subject']+"RightHemiSagittalRot.png"]) + images2 = map(Image.open, ["/tmp/"+self.brainvisaPatientAttributes['subject']+"LeftHemiSagittal.png","/tmp/"+self.brainvisaPatientAttributes['subject']+"LeftHemiSagittalRot.png"]) + + #calculates the width and height of the new picture we are going to make + widths1, heights1 = zip(*(i.size for i in images1)) + widths2, heights2 = zip(*(i.size for i in images2)) + + total_width1 = sum(widths1) + max_height1 = max(heights1) + total_width2 = sum(widths2) + max_height2 = max(heights2) + + #opens new empty images of the size calculated before + new_im1 = Image.new('RGB', (total_width1, max_height1)) + new_im2 = Image.new('RGB', (total_width2, max_height2)) + + #we are then going to paste the two images from right and left hemispheres together by the x axis + x_offset = 0 + for im in images1: + new_im1.paste(im, (x_offset,0)) + x_offset += im.size[0] + + new_im1.save('/tmp/associated1.png') + + x_offset = 0 + for im in images2: + new_im2.paste(im, (x_offset,0)) + x_offset += im.size[0] + + new_im2.save('/tmp/associated2.png') + + #pastes the two images obtained previously by the y axis + images = map(Image.open, ["/tmp/associated1.png","/tmp/associated2.png"]) + new_im=Image.new('RGB', (total_width1, max_height1*2)) + + y_offset = 0 + for im in images: + new_im.paste(im, (0,y_offset)) + y_offset += im.size[1] + + + new_im.save('/tmp/associated.png') + #verification that the path is creatable + wdi = WriteDiskItem('Screenshot of Mars Atlas','PNG image') + di=wdi.findValue(self.diskItems['T1pre']) + + if di is None: + print "Can't generate file" + return + else: + try: + os.mkdir(os.path.dirname(di.fullPath())) + #line0 = runCmd(cmd0) + except: + line0=1 + cmd1 = ['mv', '/tmp/associated.png', str(di.fullPath())] + line1 = runCmd(cmd1) + #updates the database with the image of the 2 views of the 2 parcellation + neuroHierarchy.databases.insertDiskItem(di, update=True ) + #puts back the realistic electrode model + self.updateDispMode(0) + + def makeMP4(self): + + + from brainvisa import quaternion + + #takes the voxel size of the T1 + volume = aims.read(str(self.diskItems['T1pre'])) + sizeT1=volume.getVoxelSize() + + #verification that a CT or MRI is present, if both are, we take the CT + T1post=None + diCT = ReadDiskItem( 'CT', 'BrainVISA volume formats', requiredAttributes={'center':self.brainvisaPatientAttributes['center'], 'subject':self.brainvisaPatientAttributes['subject'] } ) + path = list(diCT.findValues({}, None, False )) + #check if it is a CT post + + idCTpost = [x for x in range(len(path)) if 'CTpost' in str(path[x]) and not 'CTpostOp' in str(path[x])] + + try: + path=path[idCTpost[0]].fullPath() + volCT = aims.read(path) + npCT = volCT.arraydata() + PresCT = True + except: + diMRI = ReadDiskItem( 'Raw T1 MRI', 'BrainVISA volume formats', requiredAttributes={'center':self.brainvisaPatientAttributes['center'], 'subject':self.brainvisaPatientAttributes['subject'] } ) + pathMRI = list(diMRI.findValues({}, None, False )) + id_post = [x for x in range(len(pathMRI)) if 'post' in str(pathMRI[x]) and not 'postOp' in str(pathMRI[x])] + pathMRI=pathMRI[0].fullPath() + volCT = aims.read(pathMRI) + npCT = volCT.arraydata() + PresCT=False + if id_post!=[]: + T1post = pathMRI[id_post[0]] + + #if both CT and MRI are absent, we won't do the computation + + if T1post is None and idCTpost==[]: + warning = QtGui.QMessageBox(self) + warning.setText("No CT post or MRI post found") + warning.setWindowTitle("Warning") + return + + #finding the brainMask if there is one + try: + brainMask = ReadDiskItem('Brain Mask', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diBrain = list(brainMask.findValues({}, None, False )) + diBrain0=diBrain[0].fullPath() + volBrainMask = aims.read(diBrain0) + brainMaskArray = volBrainMask.arraydata() + except: + brainMaskArray=None + + #if the brainMask is present, the gif will be made taking only the brain tissues + if brainMaskArray is not None: + z=0 + while z0: + maxi=brainMaskArray[0,z,:,:].max() + if maxi != 0: + limit=round(z*sizeT1[2]) + z=0 + z-=1 + else: + i=1 + limit=npCT.shape[1] + + #Erase all previous files + os.system('find /tmp/gif*.png -type f -exec rm -f {} \;') + + #Take out the cursor + self.a.config()[ 'linkedCursor' ] = 0 + #put the realistic electrode model back + self.updateDispMode(2) + + #Electrodes GIF + #load the window + w21=self.a.createWindow("Axial") + w21.windowConfig(fullscreen=1) + #if it is a CT + if PresCT==True: + contWin=self.windowContent['CT post'] + content=[x for x in contWin if "CTpost" in x] + ele=[x for x in contWin if "electrode" in x] + #if it is an MRI + else: + contWin=self.windowContent['IRM post'] + content=[x for x in contWin if "T1post" in x] + ele=[x for x in contWin if "electrode" in x] + #add the image and electrodes + image = self.dispObj[content[0]] + elec=self.dispObj[ele[0]] + w21.addObjects(image) + for el in elec: + w21.addObjects(el) + #get all referentials + refs=self.a.getReferentials() + #choose the T1 pre referential... + for el in refs: + info=str(el.getInfos()) + if 'T1pre' in info and 'native' in info: + r1=el + #...and assign it + w21.assignReferential(r1) + #activate the clipping + self.a.execute('WindowConfig',windows = [w21],clipping=2,clip_distance=5.) + if brainMaskArray is None: + limit=npCT.shape[1] + #take pictures of slices following the z axis + snapShots=[] + while i16000: + volumeposition = [volumeposition[x] for x in range(len(volumeposition)) if x & 1 ==0] + + volumeposition=numpy.array(volumeposition) + (N, dd) = numpy.shape(volumeposition) + dd = float(dd) + + # Q will be our working array + Q = numpy.vstack([numpy.copy(volumeposition.T), numpy.ones(N)]) + QT = Q.T + + # initializations + err = 1.0 + tolerance + u = (1.0 / N) * numpy.ones(N) + + # Khachiyan Algorithm + while err > tolerance: + V = numpy.dot(Q, numpy.dot(numpy.diag(u), QT)) + M = numpy.diag(numpy.dot(QT , numpy.dot(numpy.linalg.inv(V), Q))) # M the diagonal vector of an NxN matrix + j = numpy.argmax(M) + maximum = M[j] + step_size = (maximum - dd - 1.0) / ((dd + 1.0) * (maximum - 1.0)) + new_u = (1.0 - step_size) * u + new_u[j] += step_size + err = numpy.linalg.norm(new_u - u) + u = new_u + + # center of the ellipse + center = numpy.dot(volumeposition.T, u) + + # the A matrix for the ellipse + AA = numpy.linalg.inv(numpy.dot(volumeposition.T, numpy.dot(numpy.diag(u), volumeposition)) - numpy.array([[a * b for b in center] for a in center])) / dd + + # Get the values we'd like to return + UU, ss, rotation = numpy.linalg.svd(AA) + radii = 1.0/numpy.sqrt(ss) + + return radii #UU, ss, rotation, center, + + + def calculParcel(self): + import copy + + infos={} + parcels={} + tailleG=0 + + #take the parcellations + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = Mask_left.findValue(self.diskItems['T1pre']) + + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = Mask_right.findValue(self.diskItems['T1pre']) + + #take the parcels names in one list + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + + try: + #transform the images to matrices + Maskleft = aims.read(diMaskleft.fullPath()) + npleftMarsAtlas = Maskleft.arraydata() + + Maskright = aims.read(diMaskright.fullPath()) + nprightMarsAtlas = Maskright.arraydata() + except: + print "No parcellation found" + return + #take voxel size of T1 pre + volume = aims.read(str(self.diskItems['T1pre'])) + sizeT1=volume.getVoxelSize() + + print 'verif done' + #pdb.set_trace() + #calculate the total volume of the parcels + for key, value in parcels_names.items(): + if value[0].lower()=='l': + parcel1 = numpy.where(npleftMarsAtlas == key) + else: + parcel1 = numpy.where(nprightMarsAtlas == key) + coord=zip(parcel1[1],parcel1[2],parcel1[3]) + tailleG+=len(coord) + + print 'tailleG Done' + + t=1 + #we do the computations for each parcel + for key, value in parcels_names.items(): + print 'doing parcel ' ,value ,t + t+=1 + par=0 + #we locate the parcel in the right or left hemispheres (if they begin with 'L':left, 'R':right) + if value[0].lower()=='l': + parcel1 = numpy.where(npleftMarsAtlas == key) + try: + #we take only the parcel + parcel=copy.deepcopy(npleftMarsAtlas[0,parcel1[1].min():parcel1[1].max()+1,parcel1[2].min():parcel1[2].max()+1,parcel1[3].min():parcel1[3].max()+1]) + except: + #if the parcel is absent we update it with the value 'not found' + print 'no parcel found' + parcels.update({value:"not found"}) + par=None + else: + parcel1 = numpy.where(nprightMarsAtlas == key) + try: + parcel=copy.deepcopy(nprightMarsAtlas[0,parcel1[1].min():parcel1[1].max()+1,parcel1[2].min():parcel1[2].max()+1,parcel1[3].min():parcel1[3].max()+1]) + except: + print 'no parcel found' + parcels.update({value:"not found"}) + par=None + #if the parcel has been computed + if par is not None: + #take the coordinates of the points + coord=zip(parcel1[1],parcel1[2],parcel1[3]) + #volume of the parcel + taille=len(coord) + infos.update({"volume":int(taille)}) + parcelPositionN=[] + parcelPositionNT=[] + parcelPosition = [[round(parcel1[1][i]*sizeT1[2]),round(parcel1[2][i]*sizeT1[1]),round(parcel1[3][i]*sizeT1[0])] for i in range(len(parcel1[1]))] + i=0 + #we take one over 3 values (downsampling by 3) + while i10000: + downSamp=int(math.ceil(float(len(parcelPositionN))/10000)) + while d0: + meshFSRight = aims.read(str(diFSWhite[indexFSWhiteRight[0]])) + meshFSLeft = aims.read(str(diFSWhite[indexFSWhiteLeft[0]])) + + #get plots information + plots = self.getAllPlotsCentersT1preRef() #coordonnées en mm à convertir en voxel + if len(plots)==0: + print("no contact found") + return + + print "start matching contacts with vertexes" + + info_plot= [] + for k,v in plots.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plot.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + #plots_label[k]=(label,label_name) + + plot_sorted = sorted(info_plot, key=lambda plot_number: plot_number[0]) + + #montage bipolaire + info_plot_bipolaire= [] + for pindex in range(1,len(plot_sorted)): + previous_contact = "".join([i for i in plot_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plot_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plot_bipolaire.append((plot_sorted[pindex][0]+' - '+ plot_sorted[pindex-1][0],(plot_sorted[pindex][1]+plot_sorted[pindex-1][1])/2 )) + + #here I have to calculate distances: vertex to each contacts. + meshRight_vertex_np = numpy.array(meshRight.vertex()) + meshLeft_vertex_np = numpy.array(meshLeft.vertex()) + + meshFSRight_vertex_np = numpy.array(meshFSRight.vertex()) + meshFSLeft_vertex_np = numpy.array(meshFSLeft.vertex()) + + dist_contact_meshRight = {} + dist_contact_meshLeft = {} + + #coordonnées longitude et latitude marsAtlas + wdi_longitude = ReadDiskItem( 'Longitude coordinate texture', 'aims Texture formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol} ) + di_longitude = list(wdi_longitude.findValues({},None,False)) + wdi_latitude = ReadDiskItem( 'Latitude coordinate texture', 'aims Texture formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol} ) + di_latitude = list(wdi_latitude.findValues({},None,False)) + + indexLongRight = [i for i in range(len(di_longitude)) if 'pre' in di_longitude[i].fullPath() and 'Rwhite' in di_longitude[i].fullPath()] + indexLongLeft = [i for i in range(len(di_longitude)) if 'pre' in di_longitude[i].fullPath() and 'Lwhite' in di_longitude[i].fullPath()] + + indexLatRight = [i for i in range(len(di_latitude)) if 'pre' in di_latitude[i].fullPath() and 'Rwhite' in di_latitude[i].fullPath()] + indexLatLeft = [i for i in range(len(di_latitude)) if 'pre' in di_latitude[i].fullPath() and 'Lwhite' in di_latitude[i].fullPath()] + + MatLongLeft = aims.read(di_longitude[indexLongLeft[0]].fullPath()) + MatLatLeft = aims.read(di_latitude[indexLatLeft[0]].fullPath()) + + MatLongRight = aims.read(di_longitude[indexLongRight[0]].fullPath()) + MatLatRight = aims.read(di_latitude[indexLatRight[0]].fullPath()) + + if len(diFSWhite)>0: + FSThickRight = aims.read(diAllFSThick[indexThickRight[0]].fullPath()) + FSTHickLeft = aims.read(diAllFSThick[indexThickLeft[0]].fullPath()) + + import copy + for ii in range(len(plot_sorted)): + + print "{} on {}".format(ii+1,len(plot_sorted)) + + np_plot = numpy.array(plot_sorted[ii][1]) + diffRight = meshRight_vertex_np - np_plot #la je sais pas si il y en a pas un en voxel et un en mm. + diffLeft = meshLeft_vertex_np - np_plot + if len(diFSWhite)>0: + diffFSRight = meshFSRight_vertex_np - np_plot + diffFSLeft = meshFSLeft_vertex_np - np_plot + + + distRight = [numpy.linalg.norm(diffRight[i]) for i in range(len(diffRight))] + distLeft = [numpy.linalg.norm(diffLeft[i]) for i in range(len(diffLeft))] + if len(diFSWhite)>0: + distFSRight = [numpy.linalg.norm(diffFSRight[i]) for i in range(len(diffFSRight))] + distFSLeft = [numpy.linalg.norm(diffFSLeft[i]) for i in range(len(diffFSLeft))] + + + #it's too big, I should keep only the indexes of the one nearest than 2 times SizeHorizon + indexvertexLeft = numpy.where(numpy.array(distLeft) numpy.array(distLeft).min(): + MarsAtlasCoordinate = ('L',MatLatLeft[0][distLeft.index(numpy.array(distLeft).min())],MatLongLeft[0][distLeft.index(numpy.array(distLeft).min())]) + pdb.set_trace() + if len(diFSWhite)>0: + ValueThickness = FSTHickLeft[0][distFSLeft.index(numpy.array(distFSLeft).min())] + ValueThickness = (ValueThickness,) + else: + ValueThickness = (0,) + MarsAtlasCoordinate = MarsAtlasCoordinate + ValueThickness + elif numpy.array(distRight).min() < numpy.array(distLeft).min(): + MarsAtlasCoordinate = ('R',MatLatRight[0][distRight.index(numpy.array(distRight).min())],MatLongRight[0][distRight.index(numpy.array(distRight).min())]) + if len(diFSWhite)>0: + ValueThickness = FSThickRight[0][distFSRight.index(numpy.array(distFSRight).min())] + ValueThickness = (ValueThickness,) + else: + ValueThickness = (0,) + MarsAtlasCoordinate = MarsAtlasCoordinate + ValueThickness + + pdb.set_trace() + + + pdb.set_trace() + #test2 = [i for i in range(len(dist_contact_mesh1[1])) if dist_contact_mesh1[1][i] <= SizeHorizon] + + + #generate the texture + #textureContacts = aims.TimeTexture() + print "contacts vertexes matching done" + + + + + + + def exportCSVdictionaries(self): + + #test si eleclabel et resection sont générés + #il faut au moins eleclabel, si pas resection pas grave + + #eleclabel + rdi_eleclabel=ReadDiskItem('Electrodes Labels','Electrode Label Format',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + wdi_eleclabel=list(rdi_eleclabel.findValues({},None,False)) + + #reseclabel + rdi_reseclabel=ReadDiskItem('Resection Description','Resection json',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + wdi_reseclabel=list(rdi_reseclabel.findValues({},None,False)) + + wdi = WriteDiskItem('Final Export Dictionaries','CSV file') + di=wdi.findValue(self.diskItems['T1pre']) + + if len(wdi_eleclabel)==0: + print('no ...') + else: + di_eleclabel=rdi_eleclabel.findValue(self.diskItems['T1pre']) + + fin = open(di_eleclabel.fullPath(),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + + plots = self.getAllPlotsCentersT1preScannerBasedRef() + + #look for mni position, are there already calculated ? + rdi_elecimplant = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + impl = list(rdi_elecimplant.findValues({},None,False)) + + if len(impl) == 0: + print "Cannot find implantation" + plotsMNI = self.getAllPlotsCentersMNIRef(plots) + info_plotMNI= [] + for k,v in plotsMNI.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotMNI.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + + elif os.path.exists(str(impl[0])): + filein = open(str(impl[0]), 'rb') + try: + dic_impl = json.loads(filein.read()) + except: + filein.close() + filein = open(str(impl[0]), 'rb') + dic_impl = pickle.load(filein) + + filein.close() + + if 'plotsMNI' in dic_impl.keys(): + print "MNI position already estimated, ok" + plot_dict_MNIinter = dict(dic_impl['plotsMNI']) + info_plotMNI = [(k, v) for k, v in plot_dict_MNIinter.iteritems()] + + else: + plotsMNI = self.getAllPlotsCentersMNIRef(plots) + + info_plotMNI= [] + for k,v in plotsMNI.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotMNI.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + #plots_label[k]=(label,label_name) + + plotMNI_sorted = sorted(info_plotMNI, key=lambda plot_number: plot_number[0]) + + #montage bipolaire + info_plotMNI_bipolaire= [] + for pindex in range(1,len(plotMNI_sorted)): + previous_contact = "".join([i for i in plotMNI_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plotMNI_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plotMNI_bipolaire.append((plotMNI_sorted[pindex][0]+' - '+ plotMNI_sorted[pindex-1][0],(numpy.array(plotMNI_sorted[pindex][1])+numpy.array(plotMNI_sorted[pindex-1][1]))/2 )) + + plotMNI_sorted=dict(plotMNI_sorted) + info_plotMNI_bipolaire=dict(info_plotMNI_bipolaire) + + + plotsSB = self.getAllPlotsCentersT1preScannerBasedRef() + info_plotSB = [] + for k,v in plotsSB.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plotSB.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + + plotSB_sorted = sorted(info_plotSB, key=lambda plot_number:plot_number[0]) + + #montage bipolaire + info_plotSB_bipolaire = [] + for pindex in range(1,len(plotSB_sorted)): + previous_contact = "".join([i for i in plotSB_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plotSB_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plotSB_bipolaire.append((plotSB_sorted[pindex][0]+' - '+ plotSB_sorted[pindex-1][0],(numpy.array(plotSB_sorted[pindex][1])+numpy.array(plotSB_sorted[pindex-1][1]))/2 )) + + plotSB_sorted=dict(plotSB_sorted) + info_plotSB_bipolaire=dict(info_plotSB_bipolaire) + + + with open(di.fullPath(), 'w') as csvfile: + #fieldnames=['MarsAtlas','GreyWhite','Resection'] + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Contacts Positions']) + writer.writerow([u'Use of MNI Template','MarsAtlas',info_label_elec['Template']['MarsAtlas'],'Freesurfer',info_label_elec['Template']['Freesurfer'],'HippoSubfieldFreesurfer',info_label_elec['Template']['HippocampalSubfield Freesurfer']]) + + #add a row with "MNI or Patient for MarsAtlas and Freesurfer + list_to_write = set(info_label_elec['plots_label'][info_label_elec['plots_label'].keys()[0]].keys()) + list_by_default = set([u'contact','MarsAtlas','MarsAtlasFull', 'Freesurfer', 'Hippocampal Subfield','GreyWhite','AAL', 'AALDilate', 'Broadmann', 'BroadmannDilate', 'Hammers', 'Resection', 'MNI','T1pre Scanner Based']) + diff_list = list(list_to_write.difference(list_by_default)) + full_list = [u'contact','MarsAtlas','MarsAtlasFull', 'Freesurfer', 'Hippocampal Subfield','GreyWhite', 'ALL', 'AALDilate', 'Broadmann','BroadmannDilate', 'Hammers', 'Resection', 'MNI','T1pre Scanner Based'] + full_list.extend(diff_list) + writer.writerow(full_list) + + #pdb.set_trace() + dict_sorted_tmp = OrderedDict(sorted(info_label_elec['plots_label'].items())) + + for kk,vv in dict_sorted_tmp.iteritems(): + listwrite = [kk] + listwrite.append(vv['MarsAtlas'][1]) + listwrite.append(vv['MarsAtlasFull']) + listwrite.append(vv['Freesurfer'][1]) + listwrite.append(vv['Hippocampal Subfield'][1]) + listwrite.append(vv['GreyWhite'][1]) + listwrite.append(vv['AAL'][1]) + listwrite.append(vv['AALDilate'][1]) + listwrite.append(vv['Broadmann'][1]) + listwrite.append(vv['BroadmannDilate'][1]) + listwrite.append(vv['Hammers'][1]) + listwrite.append(vv['Resection'][1]) + #[listwrite.append(x[1]) for x in vv.values()] + listwrite.append([float(format(plotMNI_sorted[kk][i],'.3f')) for i in range(3)]) + listwrite.append([float(format(plotSB_sorted[kk][i],'.3f')) for i in range(3)]) + if len(full_list)>12: + for i_supp in range(len(full_list)-14): + listwrite.append(vv[full_list[14+i_supp]]) + writer.writerow(listwrite) + + writer.writerow([]) + writer.writerow([]) + + dict_sorted_tmp = OrderedDict(sorted(info_label_elec['plots_label_bipolar'].items())) + + for kk,vv in dict_sorted_tmp.iteritems(): + #pdb.set_trace() + listwrite = [kk] + listwrite.append(vv['MarsAtlas'][1]) + listwrite.append(vv['MarsAtlasFull']) + listwrite.append(vv['Freesurfer'][1]) + listwrite.append(vv['Hippocampal Subfield'][1]) + listwrite.append(vv['GreyWhite'][1]) + listwrite.append(vv['AAL'][1]) + listwrite.append(vv['AALDilate'][1]) + listwrite.append(vv['Broadmann'][1]) + listwrite.append(vv['BroadmannDilate'][1]) + listwrite.append(vv['Hammers'][1]) + listwrite.append(vv['Resection'][1]) + #[listwrite.append(x[1]) for x in vv.values()] + listwrite.append([float(format(info_plotMNI_bipolaire[kk][i],'.3f')) for i in range(3)]) + listwrite.append([float(format(info_plotSB_bipolaire[kk][i],'.3f')) for i in range(3)]) + if len(full_list)>12: + for i_supp in range(len(full_list)-14): + listwrite.append(vv[full_list[14+i_supp]]) + writer.writerow(listwrite) + + writer.writerow([]) + writer.writerow([]) + + if len(wdi_reseclabel)==0: + print('no ...') + else: + di_reseclabel = rdi_reseclabel.findValue(self.diskItems['T1pre']) + fin = open(di_reseclabel.fullPath(),'r') + info_label_resec = json.loads(fin.read()) + fin.close() + + with open(di.fullPath(), 'a') as csvfile: + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Resection Information']) + #pdb.set_trace() + for kk,vv in info_label_resec.iteritems(): + #writer.writerow([kk]) + if type(vv) == type(float()): + listwrite = [kk,format(vv,'.1f')] + writer.writerow(listwrite) + else: + writer.writerow([kk]) + for ll,bb in vv.iteritems(): + listwrite = [ll, format(float(bb[1]),'.1f')] + writer.writerow(listwrite) + + neuroHierarchy.databases.insertDiskItem(di, update=True ) + print "export csv done" + + + #wdi = WriteDiskItem('PatientInfoTemplate','Patient Template format') + #di = wdi.findValue(self.diskItems['T1pre']) + + def marsatlasExportResection(self): + + wdi_resec = ReadDiskItem('Resection', 'NIFTI-1 image', requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + di_resec = list(wdi_resec.findValues({}, None, False )) + + if len(di_resec)==0: + print('no resection image found') + return + + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = Mask_left.findValue(self.diskItems['T1pre']) + + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = Mask_right.findValue(self.diskItems['T1pre']) + + FreesurferMask = ReadDiskItem('FreesurferAtlas', 'BrainVISA volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diFreesurferMask = list(FreesurferMask.findValues({}, None, False )) + + if diMaskleft is None: + print('left gyri volume failed, perform export mars atlas export contact first') + #return + else: + vol_left = aims.read(diMaskleft.fileName()) + + if diMaskright is None: + print('right gyri volume failed, perform export mars atlas export contact first') + #return + else: + vol_right = aims.read(diMaskright.fileName()) + + Vol_resec = aims.read(di_resec[0].fileName()) + + + Vox_size_resection = Vol_resec.getVoxelSize().arraydata() + Vol_resection_mm = Vol_resec.arraydata().sum()*Vox_size_resection.prod() #choppe les trois premiers + + #intersection avec mars atlas label + if diMaskleft is not None and diMaskright is not None: + Vol_mask_tot = vol_left.arraydata()+vol_right.arraydata() + + inter_resec_mars_atlas = numpy.multiply(Vol_resec.arraydata(),Vol_mask_tot) + label_resec_mars_atlas = numpy.histogram(inter_resec_mars_atlas,bins = 255, range = (0,255)) + total_label_mars_atlas = numpy.histogram(Vol_mask_tot,bins = 255) + percent_resec_mars_atlas = numpy.divide(label_resec_mars_atlas[0],total_label_mars_atlas[0],dtype=float)*100 + non_zero_inter = numpy.add(numpy.nonzero(label_resec_mars_atlas[0][1:-1]),1) + + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + + #pdb.set_trace() + list1 = [parcels_names[label_resec_mars_atlas[1][x]] for x in non_zero_inter.tolist()[0]] + list2 = [(label_resec_mars_atlas[1][x],percent_resec_mars_atlas[x]) for x in non_zero_inter.tolist()[0]] + resection_mars_atlas_info = dict(zip(list1,list2)) #{parcels_names[label_resec_mars_atlas[1][x]]:(label_resec_mars_atlas[1][x],percent_resec_mars_atlas[x]) for x in non_zero_inter.tolist()[0]} + + else: + resection_mars_atlas_info = {"MarsAtlas not calculated":[0,0]} + + if len(diFreesurferMask)>0: + vol_FS = aims.read(diFreesurferMask[0].fileName()) + inter_resec_FS = numpy.multiply(Vol_resec.arraydata(),vol_FS.arraydata()) + label_resec_FS = numpy.histogram(inter_resec_FS,bins = 20000, range = (0,20000)) + total_label_FS = numpy.histogram(vol_FS.arraydata(),bins = 20000, range = (0,20000)) + percent_resec_FS = numpy.divide(label_resec_FS[0],total_label_FS[0],dtype=float)*100 + #we keep only value between 1 and 100 to not display the thousands freesurfer parcels... + interesting_percent_resec_FS = numpy.where((percent_resec_FS >1) & (percent_resec_FS < 100)) + + parcels_names_FS = readFreesurferLabelFile('freesurfer_label.txt') + + list1 = [parcels_names_FS[unicode(x)][0] for x in interesting_percent_resec_FS[0]] + list2 = [(float(x),percent_resec_FS[x]) for x in interesting_percent_resec_FS[0]] + + resection_freesurfer_info = dict(zip(list1,list2)) + + else: + resection_freesurfer_info = {"Freesurfer not calculated": [0,0]} + + #write into database + wdi = WriteDiskItem('Resection Description','Resection json') + di = wdi.findValue(self.diskItems['Resection']) + if di is None: + print('Can t generate files') + return + + fout = open(di.fullPath(),'w') + fout.write(json.dumps({'mars_atlas':resection_mars_atlas_info,'Volume resection (mm3): ':Vol_resection_mm,'Freesurfer':resection_freesurfer_info})) #ici il faut ajouter l'ajout de la key volume mais je sais pas pourquoi des fois ca fait planter l'export en csv + fout.close() + + neuroHierarchy.databases.insertDiskItem(di, update=True ) + + print "export resection info done" + + + + def parcelsExportElectrodes(self, saveInDBmarsatlas = True, Callback = None): + + #check presence of marsatlas data + + LeftGyri = ReadDiskItem('hemisphere parcellation texture','Aims texture formats',requiredAttributes={ 'side': 'left' ,'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol, 'parcellation_type':'marsAtlas' }) + #LeftGyri = list(LeftGyri.findValues({}, None, False )) + LeftGyri = LeftGyri.findValue(self.diskItems['T1pre']) + + #check the presence of freesurfer data + freesurferdi = ReadDiskItem('FreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + rdi_freesurfer = list(freesurferdi.findValues({}, None, False )) + + #check the presence of Hippo subfield freesurfer data + HippoSubfielddi = ReadDiskItem('HippoFreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + rdi_HippoSubfield = list(HippoSubfielddi.findValues({},None,False)) + + #if either marsatlas and freesurfer are not found. stop (for now but later has to go throw the MNI) + if LeftGyri is None: + print('no hemisphere parcellation texture found') + TemplateMarsAtlas = True + #return + else: + TemplateMarsAtlas = False + + if len(rdi_freesurfer) == 0: + print('no freesurfer atlas found') + TemplateFreeSurfer = True + else: + TemplateFreeSurfer = False + + if len(rdi_HippoSubfield) == 0: + print('no hippo subfield atlas found') + TemplateHippoSubfieldFreesurfer = True + else: + TemplateHippoSubfieldFreesurfer = False + + + #if TemplateMarsAtlas or TemplateFreeSurfer or TemplateHippoSubfieldFreesurfer: #plus besoin de if vu qu'il faut maintenant forcément passer par le mni pour les atlas mni + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + impl = list(rdi.findValues({},None,False)) + + if len(impl) == 0: + print "Cannot find implantation" + QtGui.QMessageBox.warning(self,"Error","Can't find implantation, you have to click on save and after on normalize/export to generate MNI position first") + return + elif os.path.exists(str(impl[0])): + filein = open(str(impl[0]), 'rb') + try: + dic_impl = json.loads(filein.read()) + except: + filein.close() + filein = open(str(impl[0]), 'rb') + dic_impl = pickle.load(filein) + + filein.close() + + if 'plotsMNI' in dic_impl.keys(): + print "MNI position already estimated, ok" + plot_dict_MNIinter = dict(dic_impl['plotsMNI']) + else: + print "you have to click on normalize/export to generate MNI position first" + QtGui.QMessageBox.warning(self,"Error","A template will have to be used, you have to click on normalize/export to generate MNI position first") + return + #else: + #plot_dict_MNIinter=None + + #pdb.set_trace() + brainvisaContext = defaultContext() + + #pour que lorsque le thread Brainvisa ça appelle parcellationdone ET les autres export si il y a besoin + if Callback is not None: + Callback2= lambda x=None,plotMNI = plot_dict_MNIinter, templateHPSub = TemplateHippoSubfieldFreesurfer, templateMA = TemplateMarsAtlas,templateFS=TemplateFreeSurfer:[self.parcellationDone(useTemplateMarsAtlas = templateMA,useTemplateFreeSurfer=templateFS,useTemplateHippoSubFreesurfer=templateHPSub,plot_dict_MNI=plotMNI),Callback()] + else: + Callback2 = lambda x=None,plotMNI = plot_dict_MNIinter, templateHPSub = TemplateHippoSubfieldFreesurfer, templateMA = TemplateMarsAtlas,templateFS=TemplateFreeSurfer:self.parcellationDone(useTemplateMarsAtlas = templateMA,useTemplateFreeSurfer=templateFS,useTemplateHippoSubFreesurfer=templateHPSub,plot_dict_MNI=plotMNI) + + try: + brainvisaContext.runInteractiveProcess(Callback2,'2D Parcellation to 3D parcellation', Side = "Both", left_gyri = LeftGyri) #, sulcus_identification ='label') + except: + Callback2() + + + def parcellationDone(self,useTemplateMarsAtlas = False, useTemplateFreeSurfer = False, useTemplateHippoSubFreesurfer = False,plot_dict_MNI=None): + + #pdb.set_trace() + print "export electrode start" + timestamp = time.time() + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = Mask_left.findValue(self.diskItems['T1pre']) + + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = Mask_right.findValue(self.diskItems['T1pre']) + + MaskGW_right = ReadDiskItem('Right Grey White Mask','Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskGW_right = MaskGW_right.findValue(self.diskItems['T1pre']) + + MaskGW_left = ReadDiskItem('Left Grey White Mask','Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskGW_left = MaskGW_left.findValue(self.diskItems['T1pre']) + + + #here put if on use template or no + if diMaskleft is None: + print('left gyri conversion surface to volume failed') + useTemplateMarsAtlas = True + #return + + if diMaskright is None: + print('right gyri conversion surface to volume failed') + useTemplateMarsAtlas = True + #return + + GWAtlas = True + + if diMaskGW_left is None: + print('not found left grey/white label') + GWAtlas = False + else: + volGW_left = aims.read(diMaskGW_left.fileName()) + + if diMaskGW_right is None: + print('not found right grey/white label') + GWAtlas = False + else: + volGW_right = aims.read(diMaskGW_right.fileName()) + + + #on s'intéresse à la résection + wdi_resec = ReadDiskItem('Resection', 'NIFTI-1 image', requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + di_resec = list(wdi_resec.findValues({}, None, False )) + #careful, if we use templates, the resection has to be deformed in the mni template + + if len(di_resec)==0: + print('no resection image found') + DoResection = False + else: + DoResection = True + vol_resec = aims.read(di_resec[0].fileName()) + + #is there any statistic-Data + wdi_stat = ReadDiskItem('Statistic-Data','NIFTI-1 image',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol}) + di_stat = list(wdi_stat.findValues({}, None, False )) + + #number of different subacquisition #not used for now, subacquisition has to be all different + subacq_existing = [di_stat[i].attributes()['subacquisition'] for i in range(len(di_stat))] + + if len(subacq_existing) >0: + subacq_stat=[] + for i_subacq in range(len(subacq_existing)): + subacq_stat.append(aims.read(di_stat[i_subacq].fileName())) + + plots = self.getAllPlotsCentersT1preRef() #coordonnées en mm à convertir en voxel + if len(plots)==0: + print("no contact found") + return + + if not useTemplateMarsAtlas: + vol_left = aims.read(diMaskleft.fileName()) + vol_right = aims.read(diMaskright.fileName()) + else: + vol_left = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_L_gyriVolume.nii.gz') + vol_right = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/mesh/surface_analysis/Gre_2016_MNI1_R_gyriVolume.nii.gz') + + if not useTemplateFreeSurfer: + freesurferdi = ReadDiskItem('FreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + rdi_freesurfer = list(freesurferdi.findValues({}, None, False )) + vol_freesurfer = aims.read(str(rdi_freesurfer[0])) + freesurfHippoAntPostleft = ReadDiskItem('leftHippocampusNII', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + freesurfHippoAntPostright = ReadDiskItem('rightHippocampusNII', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + difreesurfHippoAntPostleft = list(freesurfHippoAntPostleft.findValues({}, None, False )) + difreesurfHippoAntPostright = list(freesurfHippoAntPostright.findValues({}, None, False )) + + if len(difreesurfHippoAntPostright)>0: + vol_hippoanteropostright = aims.read(str(difreesurfHippoAntPostright[0])) + if len(difreesurfHippoAntPostleft)>0: + vol_hippoanteropostleft = aims.read(str(difreesurfHippoAntPostleft[0])) + vol_hippoanteropost = vol_hippoanteropostright + vol_hippoanteropostleft + else: + vol_hippoanteropost = vol_hippoanteropostright + else: + if len(difreesurfHippoAntPostleft)>0: + vol_hippoanteropostleft = aims.read(str(difreesurfHippoAntPostleft[0])) + vol_hippoanteropost = vol_hippoanteropostleft + + if len(difreesurfHippoAntPostleft) == 0 and len(difreesurfHippoAntPostright) == 0: + vol_hippoanteropost = False + + else: + vol_hippoanteropostleft = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/leftHippocampusGre_2016_MNI1.nii') + vol_hippoanteropostright = aims.read('MNI_Brainvisa/t1mri/T1pre_1900-1-3/default_analysis/segmentation/rightHippocampusGre_2016_MNI1.nii') + vol_hippoanteropost = vol_hippoanteropostright + vol_hippoanteropostleft + vol_freesurfer = aims.read('MNI_Freesurfer/mri/freesurfer_parcelisation_mni2.nii') + + if not useTemplateHippoSubFreesurfer: + HippoSubfielddi = ReadDiskItem('HippoFreesurferAtlas', 'BrainVISA volume formats', requiredAttributes={'center':self.currentProtocol, 'subject':self.brainvisaPatientAttributes['subject'] }) + rdi_HippoSubfield = list(HippoSubfielddi.findValues({},None,False)) + vol_hipposubfieldFS = aims.read(str(rdi_HippoSubfield[0])) + else: + vol_hipposubfieldFS = aims.read('MNI_Freesurfer/mri/bhHippoMNI.nii') + + #chargement des atlas dans le MNI (broadman, aal etc ...) + vol_AAL = aims.read('MNI_Atlases/rAALSEEG12.nii') + vol_AALDilate = aims.read('MNI_Atlases/rAALSEEG12Dilate.nii') + vol_BroadmannDilate = aims.read('MNI_Atlases/rBrodmannSEEG3spm12.nii') + vol_Broadmann = aims.read('MNI_Atlases/rbrodmann.nii') + vol_Hammers = aims.read('MNI_Atlases/rHammersSEEG12.nii') + + info_image = self.diskItems['T1pre'].attributes() #['voxel_size'] #ca devrait etre les meme infos pour gauche et droite "probem when freesurfer is indi and mars atlas is template + + info_plot = [] + for k,v in plots.iteritems(): + plot_name_split = k.split('-$&_&$-') + info_plot.append((plot_name_split[0]+plot_name_split[1][4:].zfill(2),v)) + #plots_label[k]=(label,label_name) + + plot_sorted = sorted(info_plot, key=lambda plot_number: plot_number[0]) + + matrix_MNI_Nativ = numpy.matrix([[ -1., 0., 0., 90.],[0., -1., 0., 91.],[0., 0., -1., 109.],[0., 0., 0., 1.]]) + plot_dict_MNI_Native = {} + for vv,kk in plot_dict_MNI.iteritems(): + inter_pos = [kk[0], kk[1], kk[2], 1] + inter_pos = numpy.matrix(inter_pos).reshape([4,1]) + result_pos = numpy.dot(matrix_MNI_Nativ,inter_pos) + plot_dict_MNI_Native.update({vv:[result_pos.tolist()[0][0],result_pos.tolist()[1][0],result_pos.tolist()[2][0]]}) + + #montage bipolaire + info_plot_bipolaire= [] + for pindex in range(1,len(plot_sorted)): + previous_contact = "".join([i for i in plot_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plot_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plot_bipolaire.append((plot_sorted[pindex][0]+' - '+ plot_sorted[pindex-1][0],(plot_sorted[pindex][1]+plot_sorted[pindex-1][1])/2 )) + + #if useTemplateMarsAtlas or useTemplateFreeSurfer or useTemplateHippoSubFreesurfer: #on fait le mni dans tous les cas à cause des atlas mni + info_plot_bipolaire_MNI = {} + for pindex in range(1,len(plot_sorted)): + previous_contact = "".join([i for i in plot_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plot_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plot_bipolaire_MNI.update({plot_sorted[pindex][0]+' - '+ plot_sorted[pindex-1][0]:(numpy.array(plot_dict_MNI_Native[plot_sorted[pindex][0]])+numpy.array(plot_dict_MNI_Native[plot_sorted[pindex-1][0]]))/2}) + + + parcels_names = readSulcusLabelTranslationFile('parcels_label_name.txt') + freesurfer_parcel_names = readFreesurferLabelFile('freesurfer_label.txt') + Hammers_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_Hammers.txt') + AAL_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_AAL.txt') + AALDilate_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_AALDilate.txt') + #parcels_AAL_names = + #parcels_Broadmann_names = + #parcels_Hammers_names = + + #conversion x mm en nombre de voxel: + sphere_size_stat = 10 + nb_voxel_sphere_stat = [int(round(sphere_size_stat/info_image['voxel_size'][i])) for i in range(3)] + + sphere_size = 3 #en mm + nb_voxel_sphere = [int(round(sphere_size/info_image['voxel_size'][i])) for i in range(3)] + #if useTemplateMarsAtlas or useTemplateFreeSurfer or useTemplateHippoSubFreesurfer: + nb_voxel_sphere_MNI = [sphere_size, sphere_size, sphere_size] #because mni has a 1 mm isotropic resolution #int(round(sphere_size/info_image['voxel_size'][i])) for i in range(0,3)] + + print("start contact estimation") + plots_label = {} + for pindex in range(len(plot_sorted)): + + print(plot_sorted[pindex][0]) + #pdb.set_trace() + plot_pos_pix_indi = [round(plot_sorted[pindex][1][i]/info_image['voxel_size'][i]) for i in range(3)] + + plot_pos_pix_MNI = [round(plot_dict_MNI_Native[plot_sorted[pindex][0]][i]) for i in range(3)] + + #mars atlas: + if not useTemplateMarsAtlas: + plot_pos_pixMA = plot_pos_pix_indi + nb_voxel_sphereMA = nb_voxel_sphere + elif useTemplateMarsAtlas: + plot_pos_pixMA = plot_pos_pix_MNI #because MNI has a 1 mm istropic resolution #/info_image['voxel_size'][i]) for i in range(3)] + nb_voxel_sphereMA = nb_voxel_sphere_MNI + + #on regarde si une sphère de x mm de rayon touche une parcel + voxel_within_sphere_left = [vol_left.value(plot_pos_pixMA[0]+vox_i,plot_pos_pixMA[1]+vox_j,plot_pos_pixMA[2]+vox_k) for vox_k in range(-nb_voxel_sphereMA[2],nb_voxel_sphereMA[2]+1) for vox_j in range(-nb_voxel_sphereMA[1],nb_voxel_sphereMA[1]+1) for vox_i in range(-nb_voxel_sphereMA[0], nb_voxel_sphereMA[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_within_sphere_right = [vol_right.value(plot_pos_pixMA[0]+vox_i,plot_pos_pixMA[1]+vox_j,plot_pos_pixMA[2]+vox_k) for vox_k in range(-nb_voxel_sphereMA[2],nb_voxel_sphereMA[2]+1) for vox_j in range(-nb_voxel_sphereMA[1],nb_voxel_sphereMA[1]+1) for vox_i in range(-nb_voxel_sphereMA[0],nb_voxel_sphereMA[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + + voxel_to_keep = [x for x in voxel_within_sphere_left+voxel_within_sphere_right if x != 0 and x !=255 and x != 100] + + if GWAtlas: + voxelGW_within_sphere_left = [volGW_left.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxelGW_within_sphere_right = [volGW_right.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + + voxelGW_to_keep = [x for x in voxelGW_within_sphere_left+voxelGW_within_sphere_right if x !=255 and x !=0] + else: + GW_label = 255 + + #freesurfer: + if not useTemplateFreeSurfer: + plot_pos_pixFS = plot_pos_pix_indi + nb_voxel_sphereFS = nb_voxel_sphere + elif useTemplateFreeSurfer: + plot_pos_pixFS = plot_pos_pix_MNI #I have to apply the transfo Scanner-Based to Native #because MNI has a 1 mm istropic resolution #/info_image['voxel_size'][i]) for i in range(3)] + nb_voxel_sphereFS = nb_voxel_sphere_MNI + + voxel_within_sphere_FS = [vol_freesurfer.value(plot_pos_pixFS[0]+vox_i,plot_pos_pixFS[1]+vox_j,plot_pos_pixFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereFS[2],nb_voxel_sphereFS[2]+1) for vox_j in range(-nb_voxel_sphereFS[1],nb_voxel_sphereFS[1]+1) for vox_i in range(-nb_voxel_sphereFS[0],nb_voxel_sphereFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_FS = [x for x in voxel_within_sphere_FS if x != 0 and x != 2 and x != 41] #et 2 et 41 ? left and right white cerebral matter + + #HippoSubfield + if not useTemplateHippoSubFreesurfer: + plot_pos_pixHippoFS = plot_pos_pix_indi + nb_voxel_sphereHippoFS = nb_voxel_sphere + elif useTemplateHippoSubFreesurfer: + plot_pos_pixHippoFS = plot_pos_pix_MNI + nb_voxel_sphereHippoFS = nb_voxel_sphere_MNI + + #pdb.set_trace() + voxel_within_sphere_HippoFS = [vol_hipposubfieldFS.value(plot_pos_pixHippoFS[0]+vox_i,plot_pos_pixHippoFS[1]+vox_j,plot_pos_pixHippoFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereHippoFS[2],nb_voxel_sphereHippoFS[2]+1) for vox_j in range(-nb_voxel_sphereHippoFS[1],nb_voxel_sphereHippoFS[1]+1) for vox_i in range(-nb_voxel_sphereHippoFS[0],nb_voxel_sphereHippoFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_HippoFS = [x for x in voxel_within_sphere_HippoFS if x != 0 and x != 2 and x != 41] #et 2 et 41 ? left and right white cerebral matter + + #MNI Atlases + #AAL + voxel_within_sphere_AAL = [round(vol_AAL.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAAL = [x for x in voxel_within_sphere_AAL if x != 0 and not math.isnan(x)] + + #AALDilate + voxel_within_sphere_AALdilate = [round(vol_AALDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAALDilate = [x for x in voxel_within_sphere_AALdilate if x != 0 and not math.isnan(x)] + + #Broadmann + voxel_within_sphere_Broadmann = [round(vol_Broadmann.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmann = [x for x in voxel_within_sphere_Broadmann if x != 0 and not math.isnan(x)] + + #Brodmann dilate + voxel_within_sphere_Broadmanndilate = [round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmannDilate = [x for x in voxel_within_sphere_Broadmanndilate if x != 0 and not math.isnan(x)] + + #Hammers + voxel_within_sphere_Hammers = [round(vol_Hammers.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepHammers = [x for x in voxel_within_sphere_Hammers if x != 0 and not math.isnan(x)] + + if DoResection: + voxel_resec = [vol_resec.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + + if len(subacq_existing)>0: + voxel_substat=[] + for i_substat in range(len(subacq_stat)): + voxel_substat_all = [subacq_stat[i_substat].value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere_stat[2],nb_voxel_sphere_stat[2]+1) for vox_j in range(-nb_voxel_sphere_stat[1],nb_voxel_sphere_stat[1]+1) for vox_i in range(-nb_voxel_sphere_stat[0],nb_voxel_sphere_stat[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_stat] + voxel_substat.append(numpy.mean([x for x in voxel_substat_all if abs(x) >= 0.1])) + + #prendre le label qui revient le plus en dehors de zero (au cas où il y en ait plusieurs) + from collections import Counter + + if not voxel_to_keep: + label_name = 'not in a mars atlas parcel' + label = max(vol_left.value(plot_pos_pixMA[0],plot_pos_pixMA[1],plot_pos_pixMA[2]), vol_right.value(plot_pos_pixMA[0],plot_pos_pixMA[1],plot_pos_pixMA[2])) + full_infoMAcomputed = [] + else: + most_common,num_most_common = Counter(voxel_to_keep).most_common(1)[0] + full_infoMA = Counter(voxel_to_keep).most_common() + label = most_common + full_infoMAcomputed = [(parcels_names[iLabel[0]],float(iLabel[1])/len(voxel_within_sphere_left)*100) for iLabel in full_infoMA] + label_name = parcels_names[label] + + if not voxel_to_keep_FS: + label_freesurfer_name = 'not in a freesurfer parcel' + label_freesurfer = vol_freesurfer.value(plot_pos_pixFS[0],plot_pos_pixFS[1],plot_pos_pixFS[2]) + else: + most_common,num_most_common = Counter(voxel_to_keep_FS).most_common(1)[0] + #check if it's in the hippocampus + if (most_common == 53 or most_common == 17) and vol_hippoanteropost != False: + voxel_within_sphere_FS = [vol_hippoanteropost.value(plot_pos_pixFS[0]+vox_i,plot_pos_pixFS[1]+vox_j,plot_pos_pixFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereFS[2],nb_voxel_sphereFS[2]+1) for vox_j in range(-nb_voxel_sphereFS[1],nb_voxel_sphereFS[1]+1) for vox_i in range(-nb_voxel_sphereFS[0],nb_voxel_sphereFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_FS = [x for x in voxel_within_sphere_FS if x != 0 and x != 2 and x != 41] + try: + most_common,num_most_common = Counter(voxel_to_keep_FS).most_common(1)[0] + except: + pdb.set_trace() + label_freesurfer = most_common + if label_freesurfer == 3403: + pdb.set_trace() + label_freesurfer_name = freesurfer_parcel_names[str(label_freesurfer)][0] + else: + label_freesurfer = most_common + label_freesurfer_name = freesurfer_parcel_names[str(label_freesurfer)][0] + + if not voxel_to_keep_HippoFS: + label_hippoFS_name = 'not in a hippocamp subfield' + label_hippoFS = vol_hipposubfieldFS.value(plot_pos_pixHippoFS[0],plot_pos_pixHippoFS[1],plot_pos_pixHippoFS[2]) + else: + most_common,num_most_common = Counter(voxel_to_keep_HippoFS).most_common(1)[0] + label_hippoFS = most_common + label_hippoFS_name = freesurfer_parcel_names[str(int(label_hippoFS))][0] + + if GWAtlas: + if not voxelGW_to_keep: + GW_label = max(volGW_left.value(plot_pos_pix_indi[0],plot_pos_pix_indi[1],plot_pos_pix_indi[2]), volGW_right.value(plot_pos_pix_indi[0],plot_pos_pix_indi[1],plot_pos_pix_indi[2])) + else: + most_common2,num_most_common2 = Counter(voxelGW_to_keep).most_common(1)[0] + GW_label = most_common2 + + if not voxel_to_keepAAL: + label_AAL_name = "not in a AAL parcel" + label_AAL = round(vol_AAL.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAAL).most_common(1)[0] + label_AAL = most_common + label_AAL_name = AAL_parcels_names[label_AAL] + + if not voxel_to_keepAALDilate: + label_AALDilate_name = "not in a AALDilate parcel" + label_AALDilate = round(vol_AALDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAALDilate).most_common(1)[0] + label_AALDilate = most_common + label_AALDilate_name = AALDilate_parcels_names[label_AALDilate] + + if not voxel_to_keepBroadmann: + label_Broadmann_name = "not in a Broadmann parcel" + label_Broadmann = round(vol_Broadmann.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmann).most_common(1)[0] + label_Broadmann = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_Broadmann_name = unicode(label_Broadmann+100) + else: + label_Broadmann_name = unicode(label_Broadmann) + + if not voxel_to_keepBroadmannDilate: + label_BroadmannDilate_name = "not in a Broadmann parcel" + label_BroadmannDilate = round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmannDilate).most_common(1)[0] + label_BroadmannDilate = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_BroadmannDilate_name = unicode(label_BroadmannDilate+100) + else: + label_BroadmannDilate_name = unicode(label_BroadmannDilate-48) + + if not voxel_to_keepHammers: + label_Hammers_name = "not in a Hammers parcel" + label_Hammers = round(vol_Hammers.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepHammers).most_common(1)[0] + label_Hammers = most_common + label_Hammers_name = Hammers_parcels_names[label_Hammers] + + if DoResection: + most_common_res,num_most_common_res = Counter(voxel_resec).most_common(1)[0] + Resec_label = max(voxel_resec) #most_common_res + else: + Resec_label = 255 + + GW_label_name={0:'not in brain matter',100:'GreyMatter',200:'WhiteMatter',255:'Not Calculated'}[GW_label] + Resec_label_name = {0:'not in resection',1:'in resection',255:'resection not calculated'}[Resec_label] + + plots_label[plot_sorted[pindex][0]]={'MarsAtlas':(label,label_name),'MarsAtlasFull':full_infoMAcomputed,'Freesurfer':(label_freesurfer,label_freesurfer_name),'Hippocampal Subfield':(label_hippoFS,label_hippoFS_name),'GreyWhite':(GW_label,GW_label_name),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name), 'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(Resec_label,Resec_label_name)} + # add subacq_stat dictionnaries + if len(subacq_existing)>0: + for i_substat in range(len(subacq_stat)): + plots_label[plot_sorted[pindex][0]].update({di_stat[i_substat].attributes()['subacquisition']:float(format( voxel_substat[i_substat],'.3f'))}) + + plot_name = [x[0] for x in plot_sorted] + plots_by_label = dict([(Lab,[p for p in plot_name if plots_label[p]['MarsAtlas'][1]==Lab]) for Lab in parcels_names.values()]) + plots_by_label_FS = dict([(Lab,[p for p in plot_name if plots_label[p]['Freesurfer'][1]==Lab]) for Lab in [x[0] for x in freesurfer_parcel_names.values()]]) + plots_by_label_BM = dict([(Lab,[p for p in plot_name if plots_label[p]['Broadmann'][1]==Lab]) for Lab in [unicode("%1.1f"%x) for x in range(0,100)]]) + plots_by_label_HM = dict([(Lab,[p for p in plot_name if plots_label[p]['Hammers'][1]==Lab]) for Lab in Hammers_parcels_names.values()]) + plots_by_label_AAL = dict([(Lab,[p for p in plot_name if plots_label[p]['AAL'][1]==Lab]) for Lab in AAL_parcels_names.values()]) + plots_by_label_AALDilate = dict([(Lab,[p for p in plot_name if plots_label[p]['AALDilate'][1]==Lab]) for Lab in AALDilate_parcels_names.values()]) + + print("start bipole estimation") + #conversion x mm en nombre de voxel: + sphere_size_bipole = 5 + nb_voxel_sphere = [int(round(sphere_size_bipole/info_image['voxel_size'][i])) for i in range(0,3)] + #if useTemplateMarsAtlas or useTemplateFreeSurfer or useTemplateHippoSubFreesurfer: + nb_voxel_sphere_MNI = [sphere_size_bipole, sphere_size_bipole, sphere_size_bipole] #[int(round(sphere_size_bipole/info_image['voxel_size'][i])) for i in range(0,3)] + + plots_label_bipolar = {} + for pindex in range(len(info_plot_bipolaire)): + plot_pos_pix_indi= [round(info_plot_bipolaire[pindex][1][i]/info_image['voxel_size'][i]) for i in range(3)] + plot_pos_pix_MNI = [round(info_plot_bipolaire_MNI[info_plot_bipolaire[pindex][0]][i]) for i in range(3)] + + #on regarde si une sphère de x mm de rayon touche une parcel + #mars atlas: + if not useTemplateMarsAtlas: + plot_pos_pixMA = plot_pos_pix_indi + nb_voxel_sphereMA = nb_voxel_sphere + elif useTemplateMarsAtlas: + plot_pos_pixMA = plot_pos_pix_MNI #because MNI has a 1 mm istropic resolution #/info_image['voxel_size'][i]) for i in range(3)] + nb_voxel_sphereMA = nb_voxel_sphere_MNI + + voxel_within_sphere_left = [vol_left.value(plot_pos_pixMA[0]+vox_i,plot_pos_pixMA[1]+vox_j,plot_pos_pixMA[2]+vox_k) for vox_k in range(-nb_voxel_sphereMA[2],nb_voxel_sphereMA[2]+1) for vox_j in range(-nb_voxel_sphereMA[1],nb_voxel_sphereMA[1]+1) for vox_i in range(-nb_voxel_sphereMA[0],nb_voxel_sphereMA[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + voxel_within_sphere_right = [vol_right.value(plot_pos_pixMA[0]+vox_i,plot_pos_pixMA[1]+vox_j,plot_pos_pixMA[2]+vox_k) for vox_k in range(-nb_voxel_sphereMA[2],nb_voxel_sphereMA[2]+1) for vox_j in range(-nb_voxel_sphereMA[1],nb_voxel_sphereMA[1]+1) for vox_i in range(-nb_voxel_sphereMA[0],nb_voxel_sphereMA[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + + voxel_to_keep = [x for x in voxel_within_sphere_left+voxel_within_sphere_right if x != 0 and x !=255 and x != 100] + + if GWAtlas: + voxelGW_within_sphere_left = [volGW_left.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + voxelGW_within_sphere_right = [volGW_right.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + + voxelGW_to_keep = [x for x in voxelGW_within_sphere_left+voxelGW_within_sphere_right if x !=255 and x !=0] + else: + GW_label = 255 + + #freesurfer: + if not useTemplateFreeSurfer: + plot_pos_pixFS = plot_pos_pix_indi + nb_voxel_sphereFS = nb_voxel_sphere + elif useTemplateFreeSurfer: + plot_pos_pixFS = plot_pos_pix_MNI #because MNI has a 1 mm istropic resolution #/info_image['voxel_size'][i]) for i in range(3)] + nb_voxel_sphereFS = nb_voxel_sphere_MNI + + voxel_within_sphere_FS = [vol_freesurfer.value(plot_pos_pixFS[0]+vox_i,plot_pos_pixFS[1]+vox_j,plot_pos_pixFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereFS[2],nb_voxel_sphereFS[2]+1) for vox_j in range(-nb_voxel_sphereFS[1],nb_voxel_sphereFS[1]+1) for vox_i in range(-nb_voxel_sphereFS[0],nb_voxel_sphereFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_FS = [x for x in voxel_within_sphere_FS if x != 0 and x != 2 and x != 41] + + #HippoSubfield + if not useTemplateHippoSubFreesurfer: + plot_pos_pixHippoFS = plot_pos_pix_indi + nb_voxel_sphereHippoFS = nb_voxel_sphere + elif useTemplateHippoSubFreesurfer: + plot_pos_pixHippoFS = plot_pos_pix_MNI + nb_voxel_sphereHippoFS = nb_voxel_sphere_MNI + + voxel_within_sphere_HippoFS = [vol_hipposubfieldFS.value(plot_pos_pixHippoFS[0]+vox_i,plot_pos_pixHippoFS[1]+vox_j,plot_pos_pixHippoFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereHippoFS[2],nb_voxel_sphereHippoFS[2]+1) for vox_j in range(-nb_voxel_sphereHippoFS[1],nb_voxel_sphereHippoFS[1]+1) for vox_i in range(-nb_voxel_sphereHippoFS[0],nb_voxel_sphereHippoFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_HippoFS = [x for x in voxel_within_sphere_HippoFS if x != 0 and x != 2 and x != 41] #et 2 et 41 ? left and right white cerebral matter + + #MNI Atlases + #AAL + voxel_within_sphere_AAL = [round(vol_AAL.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAAL = [x for x in voxel_within_sphere_AAL if x != 0 and not math.isnan(x)] + + #AALDilate + voxel_within_sphere_AALdilate = [round(vol_AALDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAALDilate = [x for x in voxel_within_sphere_AALdilate if x != 0 and not math.isnan(x)] + + #Broadmann + voxel_within_sphere_Broadmann = [round(vol_Broadmann.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmann = [x for x in voxel_within_sphere_Broadmann if x != 0 and not math.isnan(x)] + + #Brodmann dilate + voxel_within_sphere_Broadmanndilate = [round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmannDilate = [x for x in voxel_within_sphere_Broadmanndilate if x != 0 and not math.isnan(x)] + + #Hammers + voxel_within_sphere_Hammers = [round(vol_Hammers.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepHammers = [x for x in voxel_within_sphere_Hammers if x != 0 and not math.isnan(x)] + + + if DoResection: + voxel_resec = [vol_resec.value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_bipole] + + if len(subacq_existing)>0: + voxel_substat=[] + for i_substat in range(len(subacq_stat)): + voxel_substat_all = [subacq_stat[i_substat].value(plot_pos_pix_indi[0]+vox_i,plot_pos_pix_indi[1]+vox_j,plot_pos_pix_indi[2]+vox_k) for vox_k in range(-nb_voxel_sphere_stat[2],nb_voxel_sphere_stat[2]+1) for vox_j in range(-nb_voxel_sphere_stat[1],nb_voxel_sphere_stat[1]+1) for vox_i in range(-nb_voxel_sphere_stat[0],nb_voxel_sphere_stat[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size_stat] + voxel_substat.append(numpy.mean([x for x in voxel_substat_all if abs(x) >= 0.1])) + + #prendre le label qui revient le plus en dehors de zero (au cas où il y en ait plusieurs) + from collections import Counter + + if not voxel_to_keep: + label_name = 'not in a mars atlas parcel' + label = max(vol_left.value(plot_pos_pixMA[0],plot_pos_pixMA[1],plot_pos_pixMA[2]), vol_right.value(plot_pos_pixMA[0],plot_pos_pixMA[1],plot_pos_pixMA[2])) + full_infoMAcomputed = [] + else: + most_common,num_most_common = Counter(voxel_to_keep).most_common(1)[0] + label = most_common + full_infoMA = Counter(voxel_to_keep).most_common() + full_infoMAcomputed = [(parcels_names[iLabel[0]],float(iLabel[1])/len(voxel_within_sphere_left)*100) for iLabel in full_infoMA] + label_name = parcels_names[label] + + if not voxel_to_keep_FS: + label_freesurfer_name = 'not in a freesurfer parcel' + label_freesurfer = vol_freesurfer.value(plot_pos_pixFS[0],plot_pos_pixFS[1],plot_pos_pixFS[2]) + else: + most_common,num_most_common = Counter(voxel_to_keep_FS).most_common(1)[0] + #check if it's in the hippocampus + if (most_common == 53 or most_common == 17) and vol_hippoanteropost != False: + voxel_within_sphere_FS = [vol_hippoanteropost.value(plot_pos_pixFS[0]+vox_i,plot_pos_pixFS[1]+vox_j,plot_pos_pixFS[2]+vox_k) for vox_k in range(-nb_voxel_sphereFS[2],nb_voxel_sphereFS[2]+1) for vox_j in range(-nb_voxel_sphereFS[1],nb_voxel_sphereFS[1]+1) for vox_i in range(-nb_voxel_sphereFS[0],nb_voxel_sphereFS[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keep_FS = [x for x in voxel_within_sphere_FS if x != 0 and x != 2 and x != 41] + most_common,num_most_common = Counter(voxel_to_keep_FS).most_common(1)[0] + label_freesurfer = most_common + label_freesurfer_name = freesurfer_parcel_names[str(label_freesurfer)][0] + else: + label_freesurfer = most_common + label_freesurfer_name = freesurfer_parcel_names[str(label_freesurfer)][0] + + if not voxel_to_keep_HippoFS: + label_hippoFS_name = 'not in a hippocamp subfield' + label_hippoFS = vol_hipposubfieldFS.value(plot_pos_pixHippoFS[0],plot_pos_pixHippoFS[1],plot_pos_pixHippoFS[2]) + else: + most_common,num_most_common = Counter(voxel_to_keep_HippoFS).most_common(1)[0] + label_hippoFS = most_common + label_hippoFS_name = freesurfer_parcel_names[str(int(label_hippoFS))][0] + + if GWAtlas: + if not voxelGW_to_keep: + GW_label = max(volGW_left.value(plot_pos_pix_indi[0],plot_pos_pix_indi[1],plot_pos_pix_indi[2]), volGW_right.value(plot_pos_pix_indi[0],plot_pos_pix_indi[1],plot_pos_pix_indi[2])) + else: + most_common2,num_most_common2 = Counter(voxelGW_to_keep).most_common(1)[0] + GW_label = most_common2 + + if not voxel_to_keepAAL: + label_AAL_name = "not in a AAL parcel" + label_AAL = round(vol_AAL.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAAL).most_common(1)[0] + label_AAL = most_common + label_AAL_name = AAL_parcels_names[label_AAL] + + if not voxel_to_keepAALDilate: + label_AALDilate_name = "not in a AALDilate parcel" + label_AALDilate = round(vol_AALDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAALDilate).most_common(1)[0] + label_AALDilate = most_common + label_AALDilate_name = AALDilate_parcels_names[label_AALDilate] + + if not voxel_to_keepBroadmann: + label_Broadmann_name = "not in a Broadmann parcel" + label_Broadmann = round(vol_Broadmann.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmann).most_common(1)[0] + label_Broadmann = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_Broadmann_name = unicode(label_Broadmann+100) + else: + label_Broadmann_name = unicode(label_Broadmann) + + if not voxel_to_keepBroadmannDilate: + label_BroadmannDilate_name = "not in a Broadmann parcel" + label_BroadmannDilate = round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmannDilate).most_common(1)[0] + label_BroadmannDilate = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_BroadmannDilate_name = unicode(label_BroadmannDilate+100) + else: + label_BroadmannDilate_name = unicode(label_BroadmannDilate-48) + + if not voxel_to_keepHammers: + label_Hammers_name = "not in a Hammers parcel" + label_Hammers = round(vol_Hammers.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepHammers).most_common(1)[0] + label_Hammers = most_common + label_Hammers_name = Hammers_parcels_names[label_Hammers] + + + if DoResection: + most_common_res,num_most_common_res = Counter(voxel_resec).most_common(1)[0] + Resec_label = max(voxel_resec) #most_common_res + else: + Resec_label = 255 + + GW_label_name={0:'not in brain matter',100:'GreyMatter',200:'WhiteMatter',255:'Not Calculated'}[GW_label] + Resec_label_name = {0:'not in resection',1:'in resection',255:'resection not calculated'}[Resec_label] + + plots_label_bipolar[info_plot_bipolaire[pindex][0]]={'MarsAtlas':(label,label_name),'MarsAtlasFull':full_infoMAcomputed,'Freesurfer':(label_freesurfer,label_freesurfer_name),'Hippocampal Subfield':(label_hippoFS,label_hippoFS_name),'GreyWhite':(GW_label,GW_label_name),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(Resec_label,Resec_label_name)} + #plots_label_bipolar.append((info_plot_bipolaire[pindex][0],label,label_name,GW_label)) + # add subacq_stat dictionnaries + if len(subacq_existing)>0: + for i_substat in range(len(subacq_stat)): + plots_label_bipolar[info_plot_bipolaire[pindex][0]].update({di_stat[i_substat].attributes()['subacquisition']:float(format( voxel_substat[i_substat],'.3f'))}) + + plot_name_bip = [x[0] for x in info_plot_bipolaire] + #plots_by_label = {Lab:[p for p in plot_name if plots_label[p]['MarsAtlas'][1]==Lab] for Lab in parcels_names.values()} + plots_bipolar_by_label = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['MarsAtlas'][1]==Lab]) for Lab in parcels_names.values()]) + #do the same for freesurfer, broadmann, hammers, all and alldilate + plots_bipolar_by_label_FS = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Freesurfer'][1]==Lab]) for Lab in [x[0] for x in freesurfer_parcel_names.values()]]) + plots_bipolar_by_label_BM = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Broadmann'][1]==Lab]) for Lab in [unicode("%1.1f"%x) for x in range(0,100)]]) + plots_bipolar_by_label_HM = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Hammers'][1]==Lab]) for Lab in Hammers_parcels_names.values()]) + plots_bipolar_by_label_AAL = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['AAL'][1]==Lab]) for Lab in AAL_parcels_names.values()]) + plots_bipolar_by_label_AALDilate = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['AALDilate'][1]==Lab]) for Lab in AALDilate_parcels_names.values()]) + wdi = WriteDiskItem('Electrodes Labels','Electrode Label Format') + di = wdi.findValue(self.diskItems['T1pre']) + if di is None: + print('Can t generate files') + return + + UseTemplateOrPatient = {'MarsAtlas':useTemplateMarsAtlas,'Freesurfer':useTemplateFreeSurfer,'HippocampalSubfield Freesurfer':useTemplateHippoSubFreesurfer} + + fout = open(di.fullPath(),'w') + fout.write(json.dumps({'Template':UseTemplateOrPatient,'plots_label':plots_label,'plots_by_label':plots_by_label, 'plots_by_label_FS':plots_by_label_FS, 'plots_by_label_BM':plots_by_label_BM, 'plots_by_label_HM':plots_by_label_HM, 'plots_by_label_AAL':plots_by_label_AAL, 'plots_by_label_AALDilate':plots_by_label_AALDilate, 'plots_label_bipolar':plots_label_bipolar, 'plots_bipolar_by_label':plots_bipolar_by_label, 'plots_bipolar_by_label_FS':plots_bipolar_by_label_FS, 'plots_bipolar_by_label_BM':plots_bipolar_by_label_BM, 'plots_bipolar_by_label_HM':plots_bipolar_by_label_HM, 'plots_bipolar_by_label_AAL':plots_bipolar_by_label_AAL, 'plots_bipolar_by_label_AALDilate':plots_bipolar_by_label_AALDilate})) + fout.close() + + neuroHierarchy.databases.insertDiskItem(di, update=True ) + #fin = open(di.fullPath(),'r') + #dictée = json.loads(fin.read()) + #dictée['plots_label'] + + print "export electrode done" + + + + def getAllPlotsCentersT1preRef(self): + """Return a dictionary {'ElectrodeName-$&_&$-PlotName':[x,y,z], ...} where x,y,z is in the T1pre native referential""" + return dict((el['name']+'-$&_&$-'+plotName, el['transf'].transform(plotCoords)) for el in self.electrodes for plotName, plotCoords in getPlotsCenters(el['elecModel']).iteritems()) + + def getAllPlotsCentersT1preScannerBasedRef(self): + """Return a dictionary {'ElectrodeName-$&_&$-PlotName':[x,y,z], ...} where x,y,z is in the T1pre scanner-based referential""" + transfo = self.t1pre2ScannerBased() + return dict((key, transfo.transform(coords)) for key, coords in self.getAllPlotsCentersT1preRef().iteritems()) + + def getAllPlotsCentersAnyReferential(self, referential): + """Return a dictionary {'ElectrodeName-$&_&$-PlotName':[x,y,z], ...} where x,y,z is in the provided referential (must be available in referential converter self.refConv)""" + if not self.refConv.isRefAvailable(referential): + print "Trying to convert to unknown referential %s"%repr(referential) + return None + return dict((key, self.refConv.real2AnyRef(coords, referential)) for key, coords in self.getAllPlotsCentersT1preRef().iteritems()) + + def getAllPlotsCentersMNIRef(self, plots=None): + """Return a dictionary {'ElectrodeName-$&_&$-PlotName':[x,y,z], ...} where x,y,z is in the MNI referential""" + if plots is None: + plots = self.getAllPlotsCentersT1preScannerBasedRef() + coords = [plots[k] for k in sorted(plots.keys())] + newCoords = self.convertT1ScannerBasedToMni(coords) + if newCoords is None: + return None + return dict(zip(sorted(plots.keys()), newCoords)) + + def saveTXT(self, contacts=None, path=None, pathPos=None, pathName=None): + """ Saves two txt files electrode_Name.txt and electrode_Pos.txt. Path should be supplied as /myPath/electrode.txt + or as an alternative, both file path should be supplied as pathPos and pathName + contacts should be a dictionary {'ElectrodeName-$&_&$-PlotName:[x,y,z],...} in the appropriate referential + """ + # Get a valid path + if not path and not (pathPos is not None and pathName is not None): + path = str(QtGui.QFileDialog.getSaveFileName(self, "Save TXT files", "", "Electrode implantation TXT files (*.txt)")) + if not path: + return None + if not contacts: + return None + if path is not None: + path = os.path.splitext(path)[0] + pathName = path+'_Name.txt' + pathPos = path+"_Pos.txt" + fileName = open(pathName, 'wb') + filePos = open(pathPos, 'wb') + # Iteration over electrodes + for contactName in sorted(contacts.keys(), key=natural_keys): + (elName, plotName) = contactName.split('-$&_&$-') + # Name of each contact is name of electrode (p for prime) + number of the plot (electrode A' contact 5 is "Ap5") + fileName.write(elName.replace('\'', 'p') + plotName.replace('Plot','') + "\n") + filePos.write("%f %f %f\n"%tuple(contacts[contactName])) + fileName.close() + filePos.close() + return pathPos + + def savePTS(self, contacts=None, path=None): + """ Save a PTS file with all contacts coordinates. + contacts parameter should be a dictionary {'ElectrodeName-$&_&$-PlotName:[x,y,z],...} in the appropriate referential + """ + # Get a valid path + if not path: + path = str(QtGui.QFileDialog.getSaveFileName(self, "Save PTS file (%s referential)"%referential, "", "PTS Electrode implantation (*.pts)")) + if not path: + return None + if contacts is None: + return None + + plots=[] + for contactName in sorted(contacts.keys(), key=natural_keys): + coords = contacts[contactName] + (elName, plotName) = contactName.split('-$&_&$-') + # Name of each contact is name of electrode (prime ' replaced by the letter p) + number of the plot (electrode A' contact 5 is "Ap5") + plots.append("%s\t%.2f\t%.2f\t%.2f\t0\t0\t0\t2\t2.0\n"%(elName.replace('\'', 'p') + plotName.replace('Plot',''), coords[0], coords[1], coords[2])) + + fileout = open(path, 'wb') + fileout.write("ptsfile\n1\t1\t1\n%s\n"%str(len(plots))) + for p in plots: + fileout.write(p) + + fileout.close() + return path + + # Open configuration dialog + def configureColors(self): + + self.bipoleSEEGColors=bipoleSEEGColors(self) + self.bipoleSEEGColors.show() + + + + def allWindowsUpdate(self): + self.windowUpdate(0, self.windowCombo1.currentText()) + self.windowUpdate(1, self.windowCombo2.currentText()) + + # Update a window content + def windowUpdate(self, winId, key): + key = str(key) # Can be a QString ! + if key not in self.windowContent: + return #when QT interface but, there was a variable generated in "frame" and we were not able to delete it, then we were not able to load another patient, there was leftover from previous patient + w = self.wins[winId] + for obj in self.dispObj: + if obj in self.windowContent[key]: + #print "Adding %s"%obj + self.a.addObjects(self.dispObj[obj], w) + else: + #print "Removing %s"%obj + self.a.removeObjects([self.dispObj[obj],],w)#CURRENT + + def updateElectrodeView(self, checkStatus=None): + """Sets the view to electrode referential or back to native T1 referential + checkStatus is Qt.CheckState""" + if checkStatus is None: + checkStatus = self.electrodeRefCheck.checkState() + if checkStatus == QtCore.Qt.Checked: + if self.electrodeList.count() > 0 and self.electrodeList.currentRow() <= len(self.electrodes): + #Change to electrode referential + el = self.currentElectrode() + if el is None: + return + if 'refRotation' in el: + self.electrodeRefRotationSlider.setValue(el['refRotation']) + if 'ref' in el: + self.setWindowsReferential(el['ref']) + self.electrodeGo(electrode = el) + else: + # Change back to T1pre native ref + self.setWindowsReferential() + + def updateElectrodeViewRotation(self, degrees): + """Sets the angle of an electrode referential, degrees is the angle in degrees""" + if self.electrodeList.count() > 0 and self.electrodeList.currentRow() <= len(self.electrodes): + #Change angle of electrode referential + el = self.currentElectrode() + if el: + el['refRotation'] = degrees + + def clippingUpdate(self): + + if self.Clipping_checkbox.isChecked(): + print "clipping activated" + self.a.execute('WindowConfig',windows = [self.wins[0]],clipping=2,clip_distance=5.) + + else: + print "clipping not activated" + self.a.execute('WindowConfig',windows = [self.wins[0]],clipping=0) + + + + def makeFusion(self): + + #get objects + Text_win1 = self.windowCombo1.currentText() + Text_win2 = self.windowCombo2.currentText() + + for obj in self.dispObj.keys(): + if obj in self.windowContent[str(Text_win1)][0]: + #print "Adding %s"%obj + obj1 = obj + + for obj in self.dispObj.keys(): + if obj in self.windowContent[str(Text_win2)][0]: + #print "Adding %s"%obj + obj2 = obj + + #pdb.set_trace() + if 'obj1' in locals() and 'obj2' in locals(): + print "do the fusion" + fusion_obj = self.a.fusionObjects((self.dispObj[obj1], self.dispObj[obj2]), method='Fusion2DMethod') + self.a.addObjects(fusion_obj, self.wins[1]) + + #add the fusion in the disObj and the windowCombo + self.dispObj[obj1+'+'+obj2] = fusion_obj + + self.windowContent.update({obj1+'+'+obj2:[obj1+'+'+obj2,'electrodes']}) + self.windowCombo1.clear() + self.windowCombo1.addItems(sorted(self.windowContent.keys())) + self.windowCombo2.clear() + self.windowCombo2.addItems(sorted(self.windowContent.keys())) + + self.windowCombo1.setCurrentIndex(max(self.windowCombo1.findText(Text_win1),0)) + self.windowCombo2.setCurrentIndex(max(self.windowCombo2.findText(obj1+'+'+obj2),0)) + + #self.allWindowsUpdate() + + else: + print "one of the image is not recognized" + return + + + def generateResection(self): + + #look for T1 pre and T1 postop + T1 = ReadDiskItem('Raw T1 MRI', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diT1 = list(T1.findValues({}, None, False )) + for t in diT1: + if 'pre' in t.attributes()['acquisition']: + T1pre = t.fullPath() + try: + SB_transf = t.attributes()['SB_Transform'] + except: + SB_transf = t.attributes()['transformations'][0] + + elif 'postOp' in t.attributes()['acquisition']: + T1postop = t.fullPath() + + if not T1pre: + print('don t find the t1pre') + return + + if 'T1postop' not in locals(): + print('don t find the t1postop') + print('look for a CTpostop') + CTs = ReadDiskItem('CT', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diCTs = list(CTs.findValues({},None,False)) + for t in diCTs: + if 'postOp' in t.attributes()['acquisition']: + CTpostop = t.fullPath() + method = 'CT' + if 'CTpostop' not in locals(): + print("can't find a CTpostop either") + return + else: + method = 'T1' + + T1pre = None + T1postop = None + + id_pre = [x for x in range(len(diT1)) if 'pre' in str(diT1[x])] + T1pre = diT1[id_pre[0]] + + if method == 'T1': + id_postop = [x for x in range(len(diT1)) if 'postOp' in str(diT1[x])] + T1postop = diT1[id_postop[0]] + elif method == 'CT': + id_ctpostop = [x for x in range(len(diCTs)) if 'postOp' in str(diCTs[x])] + CTpostop = diCTs[id_ctpostop[0]] + + + if method == 'T1': + + try: + self.refConv.loadACPC(T1pre) + except Exception, e: + print "Cannot load AC-PC referential from T1 pre MRI : "+repr(e) + return + + Ac = self.refConv.Ac + Pc = self.refConv.Pc + Ih = self.refConv.Ih + Ac.append(1) + Pc.append(1) + Ih.append(1) + + Ac_vector = numpy.array([Ac]) + Pc_vector = numpy.array([Pc]) + Ih_vector = numpy.array([Ih]) + + wdiTransform = ReadDiskItem('Transform Raw T1 MRI to another image', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) #pourquoi la suite marche pas ?, requiredAttributes = {'modalityTarget':T1pre.attributes()['modality'], 'acquisitionTarget':T1pre.attributes()['acquisition']} + diTransform = list(wdiTransform.findValues({}, None, False )) + + for t in diTransform: + if t.attributes()['modality'] == 't1mri' and 'postOp' in t.attributes()['acquisition']: + trmpostop_to_pre = t + #transfo_postop_to_pre = aims.read(trmpostop_to_pre.fullPath()).toMatrix() + #transfo_pre_to_postop = numpy.linalg.inv(transfo_postop_to_pre) + + wdiTransform2 = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diTransform2 = wdiTransform2.findValues({}, None, False ) + + for t in diTransform2: + if t.attributes()['modality'] == 't1mri' and 'postOp' in t.attributes()['acquisition']: + trmpostop_to_SB = t + #transfo_postop_to_SB = aims.read(trmpostop_to_SB.fullPath()).toMatrix() + if t.attributes()['modality'] == 't1mri' and 'pre' in t.attributes()['acquisition']: + trmpre_to_SB = t + #transfo_pre_to_SB = aims.read(trmpre_to_SB.fullPath()).toMatrix() + + if method == 'CT': + + wdiTransform = ReadDiskItem('Transform CT to another image', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) #pourquoi la suite marche pas ?, requiredAttributes = {'modalityTarget':T1pre.attributes()['modality'], 'acquisitionTarget':T1pre.attributes()['acquisition']} + diTransform = list(wdiTransform.findValues({}, None, False )) + + for t in diTransform: + if t.attributes()['modality'] == 'ct' and 'postOp' in t.attributes()['acquisition']: + trmpostop_to_pre = t + + wdiTransform2 = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diTransform2 = wdiTransform2.findValues({}, None, False ) + + for t in diTransform2: + if t.attributes()['modality'] == 'ct' and 'postOp' in t.attributes()['acquisition']: + trmpostop_to_SB = t + #transfo_postop_to_SB = aims.read(trmpostop_to_SB.fullPath()).toMatrix() + if t.attributes()['modality'] == 't1mri' and 'pre' in t.attributes()['acquisition']: + trmpre_to_SB = t + #transfo_pre_to_SB = aims.read(trmpre_to_SB.fullPath()).toMatrix() + + + + + import copy + trmpre_to_SBinvpath = trmpre_to_SB.fullPath().split('/') + trmpre_to_SBinvpath[-1] = 'inv'+trmpre_to_SBinvpath[-1] + trmpostop_to_pre_path = copy.deepcopy(trmpre_to_SBinvpath) + trmpostop_to_pre_path[-1] = 'postop_to_pre.trm' + trmpre_to_postop_path = copy.deepcopy(trmpre_to_SBinvpath) + trmpre_to_postop_path[-1] = 'pre_to_postop.trm' + trmpre_to_SBinvpath = '/'.join(trmpre_to_SBinvpath) + trmpostop_to_pre_path = '/'.join(trmpostop_to_pre_path) + trmpre_to_postop_path = '/'.join(trmpre_to_postop_path) + + + ret = subprocess.call(['AimsInvertTransformation','-i',trmpre_to_SB.fullPath(),'-o', trmpre_to_SBinvpath]) + ret = subprocess.call(['AimsComposeTransformation', '-o',trmpostop_to_pre_path, trmpre_to_SBinvpath, trmpostop_to_pre.fullPath(), trmpostop_to_SB.fullPath()]) + ret = subprocess.call(['AimsInvertTransformation','-i',trmpostop_to_pre_path,'-o',trmpre_to_postop_path]) + + print 'select the center of the resection' + center_seg = QtGui.QMessageBox(self) + center_seg.setText("Enter the center (approximatly) of the resection") + center_seg.setWindowTitle("resection center") + center_seg.setWindowModality(QtCore.Qt.NonModal) + center_seg.show() + center_seg.exec_() + + #convert brainvisa voxel position into spm_voxel position + ResecCenterCoord = list(self.a.linkCursorLastClickedPosition(self.preReferential()).items()) + print ResecCenterCoord + + if method == 'T1': + transfo_pre_to_postop = aims.read(trmpre_to_postop_path).toMatrix() + + Ac_vector_postop = transfo_pre_to_postop.dot(Ac_vector.T) + Pc_vector_postop = transfo_pre_to_postop.dot(Pc_vector.T) + Ih_vector_postop = transfo_pre_to_postop.dot(Ih_vector.T) + vect1 = numpy.array(Ac_vector_postop[0:3])-numpy.array(Pc_vector_postop[0:3]) + vect2 = numpy.array(Ih_vector_postop[0:3])-numpy.array(Pc_vector_postop[0:3]) + + result_cross = cross(vect1.T.tolist(),vect2.T.tolist())/numpy.linalg.norm(cross(vect1.T.tolist(),vect2.T.tolist()))*40 + Lh_postop = numpy.array(Ac[0:3]) + result_cross + + brainvisaContext = defaultContext() + morphologist = processes.getProcessInstance('morphologist') + morphologist.executionNode().PrepareSubject.setSelected(True) + morphologist.executionNode().BiasCorrection.setSelected(True) + morphologist.executionNode().HistoAnalysis.setSelected(True) + morphologist.executionNode().BrainSegmentation.setSelected(True) + morphologist.executionNode().Renorm.setSelected(False) + morphologist.executionNode().SplitBrain.setSelected(False) + morphologist.executionNode().TalairachTransformation.setSelected(False) + morphologist.executionNode().HeadMesh.setSelected(False) + morphologist.executionNode().HemispheresProcessing.setSelected(False) + morphologist.executionNode().SulcalMorphometry.setSelected(False) + brainvisaContext.runInteractiveProcess(lambda x='',trm=trmpostop_to_pre_path,resec_coord=ResecCenterCoord,methodo=method:self.resectionStart(trm,resec_coord,methodo) , morphologist, t1mri = T1postop, perform_normalization = False, anterior_commissure = Ac_vector_postop[0:3].T.tolist()[0],\ + posterior_commissure = Pc_vector_postop[0:3].T.tolist()[0], interhemispheric_point = Ih_vector_postop[0:3].T.tolist()[0], left_hemisphere_point = Lh_postop.tolist()[0], perform_sulci_recognition = False) + + if method == 'CT': + self.resectionStart(trmpostop_to_pre_path,ResecCenterCoord,method = 'CT') + + + def generateFiberContactDistance(self): + + print("not finished") + return + pdb.set_trace() + + + def resectionStart(self,trm_postop_to_pre,resec_coord,method = 'T1'): + + wdi_resec = WriteDiskItem('Resection', 'NIFTI-1 image') + di_resec = wdi_resec.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol, 'acquisition':'Resection'}) + + #if the path doesn't exist, create it + if not os.path.exists(os.path.dirname(di_resec.fullPath())): + os.makedirs( os.path.dirname(di_resec.fullPath())) + + + if method == 'T1': + brainMask = ReadDiskItem('Brain Mask', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diBrain = list(brainMask.findValues({}, None, False )) + + id_pre = [x for x in range(len(diBrain)) if 'pre' in str(diBrain[x])] + id_postop = [x for x in range(len(diBrain)) if 'postOp' in str(diBrain[x])] + + fullname_postop = diBrain[id_postop[0]].fullPath() + fullpost_split = fullname_postop.split('/') + fullpost_split[-1] = 'brainpostop_on_pre.nii' + fullpost = '/'.join(fullpost_split) + + ret = subprocess.call(['AimsResample', '-i', str(diBrain[id_postop[0]].fullPath()), '-m', trm_postop_to_pre, '-o', fullpost, '-t', 'n', '-r',diBrain[id_pre[0]].fullPath()]) + ret = subprocess.call(['AimsLinearComb', '-i',str(diBrain[id_pre[0]].fullPath()),'-j',fullpost, '-c', '-1', '-o', di_resec.fullPath()]) + ret = subprocess.call(['AimsThreshold', '-i',di_resec.fullPath(),'-m', 'ge','-t','250' , '-o', di_resec.fullPath()]) + ret = subprocess.call(['AimsMorphoMath', '-m','ope', '-i', di_resec.fullPath(), '-o', di_resec.fullPath(), '-r', '2']) + ret = subprocess.call(['AimsConnectComp', '-i',di_resec.fullPath(),'-o',di_resec.fullPath(),'-c','6',]) + + + if method == 'CT': + + brainMask = ReadDiskItem('Brain Mask', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diBrain = list(brainMask.findValues({}, None, False )) + + id_pre = [x for x in range(len(diBrain)) if 'pre' in str(diBrain[x])] + + CTs = ReadDiskItem('CT', 'aims readable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diCTs = list(CTs.findValues({},None,False)) + for t in diCTs: + if 'postOp' in t.attributes()['acquisition']: + CTpostop = t.fullPath() + + #id_ctpostop = [x for x in range(len(diCTs)) if 'postOp' in str(diCTs[x])] + + #fullname_postop = diCTs[id_ctpostop[0]].fullPath() + #fullpost_split = fullname_postop.split('/') + #fullpost_split[-1] = 'CTpostop_on_pre.nii' + #fullpost = '/'.join(fullpost_split) + + ret = subprocess.call(['AimsResample', '-i', str(CTpostop), '-m', trm_postop_to_pre, '-o', di_resec.fullPath(), '-t', 'c', '-r',diBrain[id_pre[0]].fullPath()]) + + ret = subprocess.call(['AimsThreshold', '-i',di_resec.fullPath(),'-m', 'be','-t','-20','-u','25','-b','-o', di_resec.fullPath()]) + ret = subprocess.call(['cartoLinearComb.py','-i',str(di_resec.fullPath()),'-i',str(diBrain[id_pre[0]]),'-o',str(di_resec.fullPath()),'-f','(I1/32767*I2/255)']) + + #apply brainmask +#./cartoLinearComb.py -i /data/brainvisa_4.5/Epilepsy/Gre_2015_CETo/t1mri/T1pre_2015-1-1/default_analysis/segmentation/brain_Gre_2015_CETo.nii -i /data/brainvisa_4.5/Epilepsy/Gre_2015_CETo/Resection/Resection/Gre_2015_CETo-Resection.nii -f 'I2/32767*I1/255' -o /tmp/test.nii + ret = subprocess.call(['AimsMorphoMath', '-m','ope', '-i', di_resec.fullPath(), '-o', di_resec.fullPath(), '-r', '2']) + + #la faut passer par numpy ... + + ret = subprocess.call(['AimsConnectComp', '-i',di_resec.fullPath(),'-o',di_resec.fullPath(),'-c','6',]) + + vol_connectcomp = aims.read(di_resec.fullPath()) + #a small sphere here as for plots: + sphere_size = 4 + nb_voxel_sphere = [int(round(sphere_size/vol_connectcomp.getVoxelSize()[i])) for i in range(0,3)] + voxel_within_sphere = [vol_connectcomp.value(resec_coord[0]/vol_connectcomp.getVoxelSize()[0]+vox_i,resec_coord[1]/vol_connectcomp.getVoxelSize()[1]+vox_j,resec_coord[2]/vol_connectcomp.getVoxelSize()[2]+vox_k) for vox_k in range(-nb_voxel_sphere[2],nb_voxel_sphere[2]+1) for vox_j in range(-nb_voxel_sphere[1],nb_voxel_sphere[1]+1) for vox_i in range(-nb_voxel_sphere[0],nb_voxel_sphere[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + + voxel_to_keep = [x for x in voxel_within_sphere if x != 0] + from collections import Counter + most_common,num_most_common = Counter(voxel_to_keep).most_common(1)[0] + + #value_connectcomp = vol_connectcomp.value(resec_coord[0],resec_coord[1],resec_coord[2]) + ret = subprocess.call(['AimsThreshold', '-i',di_resec.fullPath(),'-m', 'eq','-t',str(most_common) , '-o', di_resec.fullPath()]) + + #resave as the resection Image and do the .minf + #ret = subprocess.call(['AimsFileConvert', '-i', str(di_resec.fullPath()), '-o', str(di_resec.fullPath()), '-t', 'S16']) + if ret < 0: + print "Importation error" + QtGui.QMessageBox.warning(self, "Error", "Brainvisa Importation error/ AimsFileConvert") + return + + neuroHierarchy.databases.insertDiskItem( di_resec, update=True ) + self.transfoManager.setReferentialTo(di_resec, self.diskItems['T1pre'].attributes()['referential'] ) + + wdi_resec_roi = WriteDiskItem( 'ROI IntrAnat', 'Graph' ) + di_resec_roi = wdi_resec_roi.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol, 'acquisition':'Resection'}) + + brainvisaContext = defaultContext() + + brainvisaContext.runInteractiveProcess(lambda x='',di_roi=di_resec_roi,di_res=di_resec:self.roiconversionDone(di_roi,di_resec),'Volume To ROI Graph Converter', read = di_resec, write = di_resec_roi) #, sulcus_identification ='label') + + + def roiconversionDone(self,di_resec_roi,di_resec): + + + neuroHierarchy.databases.insertDiskItem( di_resec_roi, update=True ) + self.transfoManager.setReferentialTo(di_resec_roi, self.diskItems['T1pre'].attributes()['referential'] ) + obj_roi = self.a.loadObject(di_resec_roi) + + Text_win1 = self.windowCombo1.currentText() + obj = self.a.loadObject(di_resec) + self.diskItems['Resection'] = di_resec + self.dispObj['Resection']=obj + self.windowContent.update({'Resection':['Resection','electrodes']}) + self.windowCombo1.clear() + self.windowCombo1.addItems(sorted(self.windowContent.keys())) + self.windowCombo2.clear() + self.windowCombo2.addItems(sorted(self.windowContent.keys())) + + self.windowCombo1.setCurrentIndex(max(self.windowCombo1.findText(Text_win1),0)) + self.windowCombo2.setCurrentIndex(max(self.windowCombo2.findText('Resection'),0)) + + self.allWindowsUpdate() + + def ROIResectiontoNiftiResection(self): + + wdi_resec = WriteDiskItem('Resection', 'NIFTI-1 image') + di_resec = wdi_resec.findValue({'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol, 'acquisition':'Resection'}) + + wdi_resec_roi = ReadDiskItem( 'ROI Intranat', 'Graph', requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol} ) + di_resec_roi = list(wdi_resec_roi.findValues({}, None, False)) + + brainvisaContext = defaultContext() + brainvisaContext.runInteractiveProcess(lambda x='',di_roi=di_resec_roi[0],di_res=di_resec:self.roiconversionDone(di_roi,di_resec),'Graph To Volume Converter', read = di_resec_roi[0], write = di_resec) #removeSource, False, extract_contours, 'No' + + def removeFromDB(self, file, db=None): + """ + If the file is a directory, recursive call to remove all its content before removing the directory. + Corresponding diskitem is removed from the database if it exists. + Taken from brainvisa-4.3.0/python/brainvisa/data/qt4gui/hierarchyBrowser.py + """ + if db is None: + try: + db=neuroHierarchy.databases.database(neuroHierarchy.databases.getDiskItemFromFileName(file).get("_database")) + except: + pass + + if os.path.isdir(file): + for f in os.listdir(file): + self.removeFromDB(os.path.join(file, f), db) + os.rmdir(file) + else: + os.remove(file) + if db: + diskItem=db.getDiskItemFromFileName(file, None) + if diskItem: + db.removeDiskItem(diskItem) + + def DeleteMarsAtlasFiles(self): + + rep = QtGui.QMessageBox.warning(self, u'Confirmation', u"ATTENTION
You are gonna delete MarsAtlas files, are you sure?
DELETE MARSATLAS ?
", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if rep == QtGui.QMessageBox.Yes: + atlas_di = ReadDiskItem('hemisphere marsAtlas parcellation texture', 'aims Texture formats', requiredAttributes={ 'regularized': 'false','subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + atlas_di_list = list(atlas_di._findValues({}, None, False )) + Mask_left = ReadDiskItem('Left Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskleft = list(Mask_left.findValues({}, None, False )) + Mask_right = ReadDiskItem('Right Gyri Volume', 'Aims writable volume formats',requiredAttributes={'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + diMaskright = list(Mask_right.findValues({}, None, False )) + + if len(atlas_di_list)>0: + for i,infoi in enumerate(atlas_di_list): + self.removeFromDB(infoi.fullPath(), neuroHierarchy.databases.database(infoi.get("_database"))) + + + if len(diMaskleft)>0: + self.removeFromDB(diMaskleft[0].fullPath(), neuroHierarchy.databases.database(diMaskleft[0].get("_database"))) + + if len(diMaskright)>0: + self.removeFromDB(diMaskright[0].fullPath(), neuroHierarchy.databases.database(diMaskright[0].get("_database"))) + + print("MarsAtlas resulting files suppressed") + + + def importRosaImplantation(self): + + TheoElectrodes = ImportTheoreticalImplentation.importRosaImplantation(self) + #wdiTransform2 = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True, requiredAttributes = {'subject':self.brainvisaPatientAttributes['subject'], 'center':self.currentProtocol }) + #self.t1pre2ScannerBasedTransform + print("not finished") + return + for cle, valeur in TheoElectrodes.items(): + + pdb.set_trace() + rdi = ReadDiskItem('Transformation to Scanner Based Referential', 'Transformation matrix', exactType=True, requiredAttributes={'modality':'t1mri','subject':self.brainvisaPatientAttributes['subject'], 'center':self.brainvisaPatientAttributes['center']}) + newvalTarget=[float(x) for x in valeur["target"]] + newvalTarget=tuple(newvalTarget) + newvalEntry=[float(x) for x in valeur["entry"]] + newvalEntry=tuple(newvalEntry) + volume = aims.read(str(self.diskItems['T1pre'])) + size=volume.getVoxelSize() + sizex=size[0] + sizey=size[1] + sizez=size[2] + xt=float(newvalTarget[0])/sizex + yt=float(newvalTarget[1])/sizey + zt=float(newvalTarget[2])/sizez + xe=float(newvalEntry[0])/sizex + ye=float(newvalEntry[1])/sizey + ze=float(newvalEntry[2])/sizez + #correctTarget=(xt,yt,zt) + #correctEntry=(xe,ye,ze) + #di = rdi.findValue(self.diskItems['T1pre']) + #matriceTransfo = aims.read(di.fullPath()) + #newXYZentry = matriceTransfo.transform(correctTarget) + #newXYZtarget= matriceTransfo.transform(correctEntry) + #matriceTransfoT = numpy.array([[-volume.getSizeX()/2, -volume.getSizeY()/2, -volume.getSizeZ()/2, 0]]) + #correctTarget=numpy.array(newXYZtarget) + #correctTarget=numpy.insert(correctTarget,3,1) + #newXYZtarget=numpy.add(correctTarget,matriceTransfoT) + #correctEntry=numpy.array(newXYZentry) + #correctEntry=numpy.insert(correctEntry,3,1) + #newXYZentry=numpy.add(correctEntry,matriceTransfoT) + #xtf=newXYZtarget[0][0] + #ytf=newXYZtarget[0][1] + #ztf=newXYZtarget[0][2] + #xef=newXYZentry[0][0] + #yef=newXYZentry[0][1] + #zef=newXYZentry[0][2] + #self.t1pre2ScannerBasedTransform.transform((xt,yt,zt)) + self.addElectrode(unicode(cle), "Dixi-D08-12AM",[xt,yt,zt],[xe,ye,ze]) + + def approximateElectrode(self): + + + self.deetoMaison=DeetoMaison(self) + self.deetoMaison.show() + + # Fonction principale qui lance l'interface +def main(noapp=0): + app = None + if noapp == 0: + print "NO APP" + app = QtGui.QApplication(sys.argv) + print "CREATE DIALOG" + window = LocateElectrodes(app = app) + window.show() + if noapp == 0: + sys.exit(app.exec_()) + +if __name__ == "__main__": + print "LAUNCHING ELECTRODE LOCATE" + axon.initializeProcesses() + from brainvisa.data.readdiskitem import ReadDiskItem + from brainvisa.data.writediskitem import WriteDiskItem + + print "MAIN" + # Allow pdb to work for debugging ! + QtCore.pyqtRemoveInputHook() + main() + +#if __name__ == "__main__": +# from PyQt4.QtGui import qApp +# app = qApp +# main(0) + + diff --git a/locateElectrodes.sh b/locateElectrodes.sh new file mode 100644 index 0000000..525bf0b --- /dev/null +++ b/locateElectrodes.sh @@ -0,0 +1,8 @@ +#!/bin/bash +cd /Users/admin/Softwares/BrainVISA-4.5/bin/ +. /Users/admin/Softwares/BrainVISA-4.5/bin/bv_env.sh /Users/admin/Softwares/BrainVISA-4.5 +cd /Users/admin/Documents/GIT/IntrAnatElectrodes/epilepsie/ +echo "#############################################################################" >> intranat-locateElectrodes-`whoami`.log +date >> intranat-locateElectrodes-`whoami`.log +python locateElectrodes.py >> intranat-locateElectrodes-`whoami`.log + diff --git a/logoIntrAnat.xpm b/logoIntrAnat.xpm new file mode 100644 index 0000000..3ad7d99 --- /dev/null +++ b/logoIntrAnat.xpm @@ -0,0 +1,9270 @@ +/* XPM */ +static char * logoIntrAnat_xpm[] = { +"642 465 8802 3", +" c None", +". c #FFFFFF", +"+ c #FEFEFE", +"@ c #FDFDFD", +"# c #FBFBFB", +"$ c #FCFCFC", +"% c #F9F9F9", +"& c #F5F5F5", +"* c #F4F4F4", +"= c #F3F3F3", +"- c #F6F6F6", +"; c #F8F8F8", +"> c #FAFAFA", +", c #F7F7F7", +"' c #F2F2F2", +") c #EAEAEA", +"! c #E5E5E5", +"~ c #E4E4E4", +"{ c #E8E8E8", +"] c #EBEBEB", +"^ c #EDEDED", +"/ c #F0F0F0", +"( c #ECECEC", +"_ c #E6E6E6", +": c #E7E7E7", +"< c #E9E9E9", +"[ c #EFEFEF", +"} c #DBDBDB", +"| c #D3D3D3", +"1 c #D0D0D0", +"2 c #D1D1D1", +"3 c #D4D4D4", +"4 c #D7D7D7", +"5 c #DADADA", +"6 c #DEDEDE", +"7 c #E1E1E1", +"8 c #EEEEEE", +"9 c #DFDFDF", +"0 c #D6D6D6", +"a c #D2D2D2", +"b c #D5D5D5", +"c c #D9D9D9", +"d c #DCDCDC", +"e c #E2E2E2", +"f c #F1F1F1", +"g c #E3E3E3", +"h c #CCCCCC", +"i c #C1C1C1", +"j c #BDBDBD", +"k c #C0C0C0", +"l c #C4C4C4", +"m c #C7C7C7", +"n c #CACACA", +"o c #CECECE", +"p c #D8D8D8", +"q c #CBCBCB", +"r c #BFBFBF", +"s c #BCBCBC", +"t c #BEBEBE", +"u c #C5C5C5", +"v c #C8C8C8", +"w c #DDDDDD", +"x c #E0E0E0", +"y c #C9C9C9", +"z c #CFCFCF", +"A c #DCE1D9", +"B c #809471", +"C c #8D9C82", +"D c #98A390", +"E c #949D8E", +"F c #9CA199", +"G c #A5A6A4", +"H c #B0B0B0", +"I c #B4B4B4", +"J c #B6B6B6", +"K c #B7B7B7", +"L c #BBBBBB", +"M c #C2C2C2", +"N c #858585", +"O c #9A9A9A", +"P c #9C9C9C", +"Q c #A0A0A0", +"R c #AFAFAF", +"S c #B3B3B3", +"T c #B9B9B9", +"U c #BABABA", +"V c #C6C6C6", +"W c #CDCDCD", +"X c #F9F8F8", +"Y c #AEAEAE", +"Z c #A9A9A9", +"` c #ADADAD", +" . c #B1B1B1", +".. c #C6CEBF", +"+. c #406328", +"@. c #3E6027", +"#. c #3D5F26", +"$. c #3C5B26", +"%. c #466333", +"&. c #4D673C", +"*. c #596F49", +"=. c #657858", +"-. c #717F66", +";. c #848E7D", +">. c #969B93", +",. c #9EA19B", +"'. c #B5B5B5", +"). c #C3C3C3", +"!. c #000000", +"~. c #090909", +"{. c #151515", +"]. c #262626", +"^. c #333333", +"/. c #454545", +"(. c #5D5D5D", +"_. c #737373", +":. c #8F8F8F", +"<. c #979797", +"[. c #A3A3A3", +"}. c #B8B8B8", +"|. c #F3EBE9", +"1. c #B37062", +"2. c #A86253", +"3. c #A4766C", +"4. c #A07C75", +"5. c #8B7772", +"6. c #7D7876", +"7. c #848180", +"8. c #8D8D8D", +"9. c #919191", +"0. c #989898", +"a. c #9E9E9E", +"b. c #A7A7A7", +"c. c #C9D1C3", +"d. c #3D5E26", +"e. c #3A5A24", +"f. c #3B5C25", +"g. c #3C5D25", +"h. c #3B5C24", +"i. c #466233", +"j. c #546C44", +"k. c #627553", +"l. c #6D7D61", +"m. c #7E8A76", +"n. c #868F81", +"o. c #949990", +"p. c #A1A3A0", +"q. c #020202", +"r. c #040404", +"s. c #141414", +"t. c #2B2B2B", +"u. c #424242", +"v. c #565656", +"w. c #686868", +"x. c #777777", +"y. c #8B8B8B", +"z. c #A5A5A5", +"A. c #EDDFDC", +"B. c #98321E", +"C. c #9A1E04", +"D. c #941D04", +"E. c #901B04", +"F. c #861F09", +"G. c #822915", +"H. c #87301D", +"I. c #853829", +"J. c #754034", +"K. c #74524A", +"L. c #81635E", +"M. c #816D69", +"N. c #7C7573", +"O. c #828282", +"P. c #959595", +"Q. c #999999", +"R. c #ABABAB", +"S. c #3A5B24", +"T. c #3B5B24", +"U. c #3B5B25", +"V. c #3E6026", +"W. c #3E5F26", +"X. c #425F2E", +"Y. c #4A6538", +"Z. c #536B43", +"`. c #617454", +" + c #707F65", +".+ c #808B78", +"++ c #91978D", +"@+ c #989C95", +"#+ c #A2A4A1", +"$+ c #030303", +"%+ c #0F0F0F", +"&+ c #1C1C1C", +"*+ c #2F2F2F", +"=+ c #464646", +"-+ c #5C5C5C", +";+ c #6D6D6D", +">+ c #878787", +",+ c #EEE1DE", +"'+ c #9C3C29", +")+ c #931C04", +"!+ c #8D1B04", +"~+ c #8E1B04", +"{+ c #911C04", +"]+ c #951D04", +"^+ c #961D04", +"/+ c #921C04", +"(+ c #8E1C06", +"_+ c #851E0A", +":+ c #7B2311", +"<+ c #7F3121", +"[+ c #833F31", +"}+ c #78493E", +"|+ c #70554E", +"1+ c #78635E", +"2+ c #817270", +"3+ c #7F7B79", +"4+ c #868686", +"5+ c #A1A1A1", +"6+ c #A4A4A4", +"7+ c #A8A8A8", +"8+ c #3C5E26", +"9+ c #43602F", +"0+ c #516A40", +"a+ c #5E7350", +"b+ c #6A7B5F", +"c+ c #76836D", +"d+ c #828C7B", +"e+ c #A3A4A2", +"f+ c #AAAAAA", +"g+ c #B2B2B2", +"h+ c #010101", +"i+ c #101010", +"j+ c #393939", +"k+ c #4D4D4D", +"l+ c #5F5F5F", +"m+ c #707070", +"n+ c #888888", +"o+ c #A2A2A2", +"p+ c #EDE0DD", +"q+ c #8C1B04", +"r+ c #8B1B04", +"s+ c #8F1B04", +"t+ c #8F1C04", +"u+ c #941C04", +"v+ c #901C04", +"w+ c #8C1B05", +"x+ c #87200C", +"y+ c #7B2816", +"z+ c #793526", +"A+ c #7D4135", +"B+ c #7A4B42", +"C+ c #735650", +"D+ c #7B6A66", +"E+ c #847977", +"F+ c #828180", +"G+ c #8A8A8A", +"H+ c #929292", +"I+ c #9F9F9F", +"J+ c #395924", +"K+ c #405E2B", +"L+ c #546B42", +"M+ c #627655", +"N+ c #6E7E63", +"O+ c #7C8874", +"P+ c #8C9487", +"Q+ c #93988F", +"R+ c #A0A29F", +"S+ c #0A0A0A", +"T+ c #161616", +"U+ c #282828", +"V+ c #414141", +"W+ c #535353", +"X+ c #7F7F7F", +"Y+ c #9D9D9D", +"Z+ c #E9DCD9", +"`+ c #993B28", +" @ c #8A1B04", +".@ c #971D04", +"+@ c #891B04", +"@@ c #8A1F09", +"#@ c #85230F", +"$@ c #7A2D1C", +"%@ c #783C2E", +"&@ c #7D483D", +"*@ c #7D534B", +"=@ c #765D57", +"-@ c #786D6A", +";@ c #857C7B", +">@ c #888685", +",@ c #3C5E25", +"'@ c #415E2D", +")@ c #4E673C", +"!@ c #667858", +"~@ c #728167", +"{@ c #7C8875", +"]@ c #8F968A", +"^@ c #0D0D0D", +"/@ c #212121", +"(@ c #313131", +"_@ c #696969", +":@ c #DFD3D0", +"<@ c #933726", +"[@ c #861A04", +"}@ c #881A04", +"|@ c #891A04", +"1@ c #8A1A04", +"2@ c #88230E", +"3@ c #892A17", +"4@ c #7D301F", +"5@ c #743C30", +"6@ c #7B4C41", +"7@ c #825B53", +"8@ c #78655F", +"9@ c #787471", +"0@ c #828080", +"a@ c #909090", +"b@ c #3D5C28", +"c@ c #4F683E", +"d@ c #5E7351", +"e@ c #697B5D", +"f@ c #78866F", +"g@ c #869080", +"h@ c #8F968B", +"i@ c #9DA09B", +"j@ c #060606", +"k@ c #111111", +"l@ c #222222", +"m@ c #3D3D3D", +"n@ c #505050", +"o@ c #656565", +"p@ c #7B7B7B", +"q@ c #CFC4C1", +"r@ c #8A3525", +"s@ c #831904", +"t@ c #7E1804", +"u@ c #801904", +"v@ c #811904", +"w@ c #841904", +"x@ c #851A04", +"y@ c #951C04", +"z@ c #821C06", +"A@ c #832612", +"B@ c #852E1D", +"C@ c #7F3629", +"D@ c #744034", +"E@ c #775149", +"F@ c #7E625C", +"G@ c #7A6B68", +"H@ c #797775", +"I@ c #818181", +"J@ c #8E8E8E", +"K@ c #939393", +"L@ c #3C5C25", +"M@ c #3F5D2A", +"N@ c #607451", +"O@ c #6C7C60", +"P@ c #78856F", +"Q@ c #9DA09A", +"R@ c #A1A29F", +"S@ c #0C0C0C", +"T@ c #1B1B1B", +"U@ c #3C3C3C", +"V@ c #525252", +"W@ c #B8AEAC", +"X@ c #7B2F20", +"Y@ c #761603", +"Z@ c #721603", +"`@ c #751703", +" # c #761703", +".# c #781703", +"+# c #791703", +"@# c #7B1803", +"## c #7D1804", +"$# c #871A04", +"%# c #821F0B", +"&# c #7C2714", +"*# c #812E1D", +"=# c #81392C", +"-# c #75453B", +";# c #765851", +"># c #7C6460", +",# c #7E6F6C", +"'# c #7C7977", +")# c #4B6539", +"!# c #5C714D", +"~# c #67795A", +"{# c #76836C", +"]# c #838D7C", +"^# c #8D9488", +"/# c #9A9E98", +"(# c #1D1D1D", +"_# c #373737", +":# c #4C4C4C", +"<# c #626262", +"[# c #727272", +"}# c #ACACAC", +"|# c #ABA2A0", +"1# c #722B1E", +"2# c #6B1503", +"3# c #671403", +"4# c #681403", +"5# c #691403", +"6# c #6C1503", +"7# c #6D1503", +"8# c #6F1503", +"9# c #731603", +"0# c #771703", +"a# c #791704", +"b# c #7B1804", +"c# c #7F1904", +"d# c #821904", +"e# c #841A04", +"f# c #8E1C04", +"g# c #831F0B", +"h# c #7C2816", +"i# c #823826", +"j# c #824235", +"k# c #754B42", +"l# c #725A54", +"m# c #7D6863", +"n# c #857774", +"o# c #817E7D", +"p# c #949494", +"q# c #A6A6A6", +"r# c #50683E", +"s# c #5B714C", +"t# c #6E7E61", +"u# c #5E6B55", +"v# c #12190B", +"w# c #080D05", +"x# c #050803", +"y# c #272727", +"z# c #3A3A3A", +"A# c #736C6A", +"B# c #5A2319", +"C# c #571103", +"D# c #5B1203", +"E# c #611303", +"F# c #651303", +"G# c #661403", +"H# c #661303", +"I# c #6B1403", +"J# c #6E1503", +"K# c #701503", +"L# c #741603", +"M# c #961C04", +"N# c #8B1C05", +"O# c #8E1F09", +"P# c #87220E", +"Q# c #792919", +"R# c #7B392B", +"S# c #81463B", +"T# c #7C5148", +"U# c #735B54", +"V# c #796C69", +"W# c #857D7B", +"X# c #848383", +"Y# c #8C8C8C", +"Z# c #375623", +"`# c #314D1F", +" $ c #293F19", +".$ c #223515", +"+$ c #1B2911", +"@$ c #15210E", +"#$ c #0F180A", +"$$ c #070B04", +"%$ c #040100", +"&$ c #0D0200", +"*$ c #1B0501", +"=$ c #260701", +"-$ c #310901", +";$ c #3A0B02", +">$ c #430D02", +",$ c #511003", +"'$ c #5C1203", +")$ c #5F1203", +"!$ c #631303", +"~$ c #711603", +"{$ c #751603", +"]$ c #7A1703", +"^$ c #7C1803", +"/$ c #7D1903", +"($ c #831A04", +"_$ c #851904", +":$ c #8A200C", +"<$ c #882816", +"[$ c #793021", +"}$ c #7D493F", +"|$ c #7E564F", +"1$ c #77625D", +"2$ c #78726F", +"3$ c #827F7E", +"4$ c #385723", +"5$ c #355120", +"6$ c #304A1E", +"7$ c #2A401A", +"8$ c #203114", +"9$ c #1B2A11", +"0$ c #131E0C", +"a$ c #0D1408", +"b$ c #080C05", +"c$ c #020301", +"d$ c #030000", +"e$ c #0A0200", +"f$ c #110300", +"g$ c #1C0501", +"h$ c #2A0802", +"i$ c #320A02", +"j$ c #400C02", +"k$ c #4A0E02", +"l$ c #5A1203", +"m$ c #601203", +"n$ c #651403", +"o$ c #6A1503", +"p$ c #6F1603", +"q$ c #841C06", +"r$ c #82210E", +"s$ c #842918", +"t$ c #7D3324", +"u$ c #743D31", +"v$ c #7B5047", +"w$ c #7F5F58", +"x$ c #786965", +"y$ c #7B7775", +"z$ c #858282", +"A$ c #385623", +"B$ c #2E471D", +"C$ c #283E1A", +"D$ c #294019", +"E$ c #314B1E", +"F$ c #334F1F", +"G$ c #314C1F", +"H$ c #2C441B", +"I$ c #243917", +"J$ c #1E2F13", +"K$ c #18250F", +"L$ c #111B0B", +"M$ c #020201", +"N$ c #020000", +"O$ c #0B0200", +"P$ c #180501", +"Q$ c #210601", +"R$ c #2C0801", +"S$ c #350A02", +"T$ c #4F1002", +"U$ c #5A1103", +"V$ c #5C1103", +"W$ c #601303", +"X$ c #621303", +"Y$ c #6A1403", +"Z$ c #701603", +"`$ c #7B1703", +" % c #7D1803", +".% c #7F1804", +"+% c #801804", +"@% c #931D04", +"#% c #831E0A", +"$% c #822815", +"%% c #842F1F", +"&% c #7B372A", +"*% c #734338", +"=% c #7A564E", +"-% c #846761", +";% c #7E6D6A", +">% c #797876", +",% c #9B9B9B", +"'% c #385722", +")% c #355321", +"!% c #3A5924", +"~% c #375721", +"{% c #385922", +"]% c #3B5D25", +"^% c #243717", +"/% c #0F130B", +"(% c #080A07", +"_% c #030502", +":% c #121C0B", +"<% c #365422", +"[% c #3E6127", +"}% c #365421", +"|% c #2A421A", +"1% c #213415", +"2% c #1D2D12", +"3% c #0E1609", +"4% c #090E06", +"5% c #020402", +"6% c #010000", +"7% c #060100", +"8% c #0E0200", +"9% c #190501", +"0% c #280801", +"a% c #3E0C02", +"b% c #480E02", +"c% c #591103", +"d% c #641303", +"e% c #631403", +"f% c #731703", +"g% c #741703", +"h% c #7C1804", +"i% c #8C1C05", +"j% c #811E0A", +"k% c #843424", +"l% c #834032", +"m% c #73483F", +"n% c #7F6A65", +"o% c #807471", +"p% c #7F7D7C", +"q% c #35551F", +"r% c #2E4B1B", +"s% c #213512", +"t% c #14210A", +"u% c #192910", +"v% c #37492B", +"w% c #445636", +"x% c #2B421C", +"y% c #2D471B", +"z% c #2B421A", +"A% c #101909", +"B% c #010002", +"C% c #000001", +"D% c #16220E", +"E% c #335020", +"F% c #345121", +"G% c #2D471C", +"H% c #273D18", +"I% c #213314", +"J% c #1A2910", +"K% c #080E05", +"L% c #030501", +"M% c #010200", +"N% c #040000", +"O% c #140401", +"P% c #200601", +"Q% c #270701", +"R% c #340A02", +"S% c #4D0F03", +"T% c #911B04", +"U% c #8A1E07", +"V% c #81220E", +"W% c #7A2A19", +"X% c #7D3729", +"Y% c #7E4439", +"Z% c #765148", +"`% c #725E58", +" & c #7C6B68", +".& c #827977", +"+& c #818080", +"@& c #969696", +"#& c #3B5727", +"$& c #485A3A", +"%& c #3D4836", +"&& c #3B4038", +"*& c #191818", +"=& c #030403", +"-& c #242622", +";& c #787A76", +">& c #747872", +",& c #1E241A", +"'& c #060B03", +")& c #101809", +"!& c #1C2A11", +"~& c #2B431B", +"{& c #3B5D23", +"]& c #3A5C22", +"^& c #395A22", +"/& c #375720", +"(& c #35541F", +"_& c #314D1E", +":& c #2B431A", +"<& c #203313", +"[& c #1B2C0F", +"}& c #131E0B", +"|& c #0F1809", +"1& c #0A1007", +"2& c #040502", +"3& c #030100", +"4& c #160401", +"5& c #250701", +"6& c #3C0B02", +"7& c #440D02", +"8& c #4C0F02", +"9& c #581103", +"0& c #611203", +"a& c #621203", +"b& c #7A1704", +"c& c #8E1A04", +"d& c #8F1A04", +"e& c #891D08", +"f& c #832410", +"g& c #7B301F", +"h& c #7A3E30", +"i& c #7F4B40", +"j& c #7A544D", +"k& c #75605B", +"l& c #7D716F", +"m& c #878180", +"n& c #3A5A23", +"o& c #3F5C2B", +"p& c #5E6D53", +"q& c #A0A39E", +"r& c #C3C2C3", +"s& c #B1B1B2", +"t& c #8D8D8E", +"u& c #737273", +"v& c #777677", +"w& c #828182", +"x& c #302F30", +"y& c #0B1007", +"z& c #395923", +"A& c #35561E", +"B& c #446330", +"C& c #6C835C", +"D& c #698159", +"E& c #536D41", +"F& c #5B6F4D", +"G& c #6E7F64", +"H& c #647857", +"I& c #536B42", +"J& c #466232", +"K& c #3E5C29", +"L& c #365521", +"M& c #345221", +"N& c #314C1E", +"O& c #2B441C", +"P& c #263A18", +"Q& c #1C2B11", +"R& c #14200D", +"S& c #060904", +"T& c #080100", +"U& c #3C0C02", +"V& c #4A0E03", +"W& c #531003", +"X& c #5E1203", +"Y& c #711503", +"Z& c #7A1803", +"`& c #881904", +" * c #871904", +".* c #861903", +"+* c #871903", +"@* c #8B1A04", +"#* c #602004", +"$* c #462605", +"%* c #412705", +"&* c #4A2605", +"** c #5E2105", +"=* c #741D04", +"-* c #871B04", +";* c #861C06", +">* c #8A2410", +",* c #842917", +"'* c #783325", +")* c #744033", +"!* c #804D43", +"~* c #805B53", +"{* c #766560", +"]* c #7A7573", +"^* c #868382", +"/* c #375820", +"(* c #546E42", +"_* c #ABB3A4", +":* c #E3E2E3", +"<* c #EBEAEB", +"[* c #7A7A7A", +"}* c #323232", +"|* c #0F1709", +"1* c #375821", +"2* c #516C3D", +"3* c #99A690", +"4* c #CFD3CC", +"5* c #CFD4CD", +"6* c #C0C5BD", +"7* c #C0C3BF", +"8* c #CBCDCB", +"9* c #C2C3C0", +"0* c #AEB2AC", +"a* c #9DA399", +"b* c #818B7A", +"c* c #495B3D", +"d* c #2A4319", +"e* c #355221", +"f* c #253A17", +"g* c #1E2D12", +"h* c #17240F", +"i* c #121B0B", +"j* c #0C1208", +"k* c #030202", +"l* c #020102", +"m* c #080807", +"n* c #1B1E1B", +"o* c #080200", +"p* c #130301", +"q* c #210701", +"r* c #370A02", +"s* c #480E03", +"t* c #731503", +"u* c #751401", +"v* c #721400", +"w* c #651601", +"x* c #631802", +"y* c #711800", +"z* c #7D1901", +"A* c #801801", +"B* c #7F1401", +"C* c #871703", +"D* c #6C1C04", +"E* c #232D06", +"F* c #0E3707", +"G* c #0F3707", +"H* c #113707", +"I* c #173407", +"J* c #233006", +"K* c #472505", +"L* c #801B04", +"M* c #911A04", +"N* c #8D1A04", +"O* c #831D07", +"P* c #852713", +"Q* c #872F1E", +"R* c #7D3728", +"S* c #734134", +"T* c #7B544B", +"U* c #82635D", +"V* c #796C68", +"W* c #7A7978", +"X* c #273C18", +"Y* c #263B17", +"Z* c #324D1F", +"`* c #3C5C26", +" = c #597347", +".= c #B7BFB1", +"+= c #787878", +"@= c #121212", +"#= c #4B4B4B", +"$= c #898989", +"%= c #4E4E4E", +"&= c #15210D", +"*= c #395A23", +"== c #3F5E29", +"-= c #698058", +";= c #B5BDAE", +">= c #E2E2E1", +",= c #E9E8E9", +"'= c #EAE9EA", +")= c #E7E7E8", +"!= c #E8E7E8", +"~= c #E5E4E5", +"{= c #949693", +"]= c #262B22", +"^= c #050C00", +"/= c #0C1408", +"(= c #213214", +"_= c #3D6026", +":= c #324D1E", +"<= c #2B441B", +"[= c #243817", +"}= c #16230E", +"|= c #090D05", +"1= c #050703", +"2= c #161715", +"3= c #424740", +"4= c #555C53", +"5= c #4E534C", +"6= c #343732", +"7= c #242723", +"8= c #474D46", +"9= c #798375", +"0= c #0E0300", +"a= c #220601", +"b= c #310A02", +"c= c #380B02", +"d= c #470E02", +"e= c #4F0F03", +"f= c #551103", +"g= c #5D1203", +"h= c #671301", +"i= c #671A03", +"j= c #5B2407", +"k= c #352B07", +"l= c #222A02", +"m= c #4F3B14", +"n= c #7E5231", +"o= c #865232", +"p= c #733718", +"q= c #521B01", +"r= c #312002", +"s= c #0F2E04", +"t= c #0F3406", +"u= c #113506", +"v= c #113606", +"w= c #103606", +"x= c #0E3807", +"y= c #113507", +"z= c #432505", +"A= c #741C04", +"B= c #7F1B04", +"C= c #8B1802", +"D= c #8C1903", +"E= c #7F1F0A", +"F= c #7F2816", +"G= c #813021", +"H= c #7C3C30", +"I= c #74493E", +"J= c #755850", +"K= c #7E6662", +"L= c #7C7B7A", +"M= c #243816", +"N= c #090E05", +"O= c #040802", +"P= c #0C1505", +"Q= c #203611", +"R= c #2B4319", +"S= c #223613", +"T= c #223814", +"U= c #2B4619", +"V= c #365620", +"W= c #587146", +"X= c #B9C1B4", +"Y= c #1E2E13", +"Z= c #3A5A25", +"`= c #3C5D24", +" - c #36571F", +".- c #43622F", +"+- c #819474", +"@- c #CACFC7", +"#- c #E7E6E7", +"$- c #E6E6E7", +"%- c #949394", +"&- c #1D1D1E", +"*- c #1C2C12", +"=- c #2F481D", +"-- c #395823", +";- c #3A5B25", +">- c #30491D", +",- c #283D18", +"'- c #203214", +")- c #1A2911", +"!- c #141F0D", +"~- c #0C1307", +"{- c #131711", +"]- c #535951", +"^- c #848E81", +"/- c #8D9789", +"(- c #8E978A", +"_- c #8F988C", +":- c #858D81", +"<- c #868F83", +"[- c #98A494", +"}- c #717A6D", +"|- c #222320", +"1- c #10110F", +"2- c #2A2D29", +"3- c #1B1D1B", +"4- c #353A34", +"5- c #232723", +"6- c #2D312B", +"7- c #52584F", +"8- c #575D54", +"9- c #393E38", +"0- c #171917", +"a- c #0D0E0C", +"b- c #030404", +"c- c #1D0601", +"d- c #320901", +"e- c #3B0B02", +"f- c #460E02", +"g- c #551002", +"h- c #5E1403", +"i- c #693219", +"j- c #745A43", +"k- c #746B57", +"l- c #69725F", +"m- c #596D52", +"n- c #6E7862", +"o- c #7D8072", +"p- c #7C8171", +"q- c #797C68", +"r- c #294113", +"s- c #0F3101", +"t- c #143908", +"u- c #0E2F03", +"v- c #102F06", +"w- c #103006", +"x- c #0E2F04", +"y- c #0F2F03", +"z- c #0F3306", +"A- c #133106", +"B- c #212B06", +"C- c #332605", +"D- c #661C04", +"E- c #861904", +"F- c #8E1B05", +"G- c #8F1904", +"H- c #8D1802", +"I- c #8E1F03", +"J- c #8A1D01", +"K- c #871700", +"L- c #881500", +"M- c #891600", +"N- c #8A1801", +"O- c #8B1A03", +"P- c #891B05", +"Q- c #83220F", +"R- c #7C2C1A", +"S- c #813627", +"T- c #7F4235", +"U- c #744D44", +"V- c #775F59", +"W- c #816E6B", +"X- c #817775", +"Y- c #80807F", +"Z- c #385622", +"`- c #2D451C", +" ; c #040703", +".; c #010201", +"+; c #41453E", +"@; c #71786C", +"#; c #575C54", +"$; c #31342E", +"%; c #242C1D", +"&; c #2B401D", +"*; c #35531F", +"=; c #385821", +"-; c #3A532A", +";; c #90978B", +">; c #E4E3E4", +",; c #363636", +"'; c #080A06", +"); c #3F4F34", +"!; c #597148", +"~; c #4C6839", +"{; c #728664", +"]; c #CBCFC8", +"^; c #EBEAEC", +"/; c #3A393A", +"(; c #263917", +"_; c #385921", +":; c #36561F", +"<; c #395922", +"[; c #375522", +"}; c #375524", +"|; c #476235", +"1; c #546D44", +"2; c #5D7250", +"3; c #607355", +"4; c #718068", +"5; c #798771", +"6; c #7D8977", +"7; c #869081", +"8; c #6E746B", +"9; c #626860", +"0; c #747B72", +"a; c #575D55", +"b; c #050505", +"c; c #262925", +"d; c #3A3E38", +"e; c #141613", +"f; c #2E322D", +"g; c #798274", +"h; c #A5B4A0", +"i; c #9AA695", +"j; c #A0AD9B", +"k; c #BDCDB8", +"l; c #BECDB9", +"m; c #AEBBA8", +"n; c #939E8F", +"o; c #848F80", +"p; c #697166", +"q; c #313530", +"r; c #150701", +"s; c #272018", +"t; c #3D413D", +"u; c #434944", +"v; c #4F564C", +"w; c #5C6158", +"x; c #686C67", +"y; c #737772", +"z; c #787E75", +"A; c #7F8480", +"B; c #576D4D", +"C; c #546A4A", +"D; c #63745A", +"E; c #38522A", +"F; c #0B2A01", +"G; c #0C2902", +"H; c #153709", +"I; c #153809", +"J; c #0D2D02", +"K; c #0C2D04", +"L; c #0C3006", +"M; c #0A3006", +"N; c #252705", +"O; c #661803", +"P; c #7D1703", +"Q; c #861804", +"R; c #74290B", +"S; c #592E0B", +"T; c #712C0A", +"U; c #954620", +"V; c #A87553", +"W; c #A17858", +"X; c #985F3D", +"Y; c #914622", +"Z; c #923714", +"`; c #912708", +" > c #891700", +".> c #871702", +"+> c #901A04", +"@> c #8D1D06", +"#> c #891F0A", +"$> c #7F2310", +"%> c #792D1C", +"&> c #813E30", +"*> c #824A40", +"=> c #75544C", +"-> c #72625D", +";> c #7F706C", +">> c #877E7C", +",> c #848484", +"'> c #3A5923", +")> c #29401A", +"!> c #1D2C12", +"~> c #040602", +"{> c #404040", +"]> c #CCCCCD", +"^> c #DBDBDC", +"/> c #D7D7D8", +"(> c #C8C8C9", +"_> c #B3B2B3", +":> c #7D827B", +"<> c #304224", +"[> c #33521E", +"}> c #253C15", +"|> c #50564B", +"1> c #D2D1D2", +"2> c #EAEAEB", +"3> c #121211", +"4> c #2C3129", +"5> c #7D8477", +"6> c #C1C6BD", +"7> c #E1E2E1", +"8> c #474747", +"9> c #233516", +"0> c #4D653C", +"a> c #547042", +"b> c #3D5D27", +"c> c #36581F", +"d> c #3D5B27", +"e> c #435F2F", +"f> c #4C663B", +"g> c #576E48", +"h> c #617653", +"i> c #66795B", +"j> c #6F7E66", +"k> c #727E6D", +"l> c #353A33", +"m> c #222421", +"n> c #687066", +"o> c #899385", +"p> c #6E756C", +"q> c #313431", +"r> c #070707", +"s> c #121411", +"t> c #4D534A", +"u> c #909C8C", +"v> c #A0AB99", +"w> c #B1BEAB", +"x> c #B6C4B0", +"y> c #B9C8B4", +"z> c #C0CFBA", +"A> c #C2D0BB", +"B> c #C4D3BE", +"C> c #C6D6C1", +"D> c #C9D9C3", +"E> c #C1D0BA", +"F> c #A3AF9E", +"G> c #444A43", +"H> c #000300", +"I> c #090D07", +"J> c #20221F", +"K> c #393A39", +"L> c #4B4D4B", +"M> c #757375", +"N> c #686F62", +"O> c #264319", +"P> c #314C25", +"Q> c #637259", +"R> c #627357", +"S> c #39552C", +"T> c #133208", +"U> c #0A2701", +"V> c #0C2904", +"W> c #0C2C05", +"X> c #2C2004", +"Y> c #661603", +"Z> c #721503", +"`> c #7B1603", +" , c #7D1D07", +"., c #61300E", +"+, c #304211", +"@, c #1B4510", +"#, c #29460F", +"$, c #50662C", +"%, c #708B5F", +"&, c #739064", +"*, c #7E9467", +"=, c #909671", +"-, c #A4997E", +";, c #AD8A73", +">, c #985A34", +",, c #6C2B06", +"', c #5A1A00", +"), c #612005", +"!, c #6B1F04", +"~, c #881D07", +"{, c #8D230D", +"], c #852815", +"^, c #763020", +"/, c #784034", +"(, c #804E44", +"_, c #7B5A52", +":, c #74635E", +"<, c #7B7473", +"[, c #848282", +"}, c #324E1F", +"|, c #18260F", +"1, c #020300", +"2, c #EEEEEF", +"3, c #DEDDDF", +"4, c #737671", +"5, c #1F3013", +"6, c #253C16", +"7, c #13210A", +"8, c #373935", +"9, c #1F1F1F", +"0, c #010001", +"a, c #908F90", +"b, c #555555", +"c, c #040403", +"d, c #626661", +"e, c #A9B2A5", +"f, c #6F8460", +"g, c #365720", +"h, c #35571E", +"i, c #446031", +"j, c #465E36", +"k, c #596F4B", +"l, c #66795A", +"m, c #75846B", +"n, c #6D7B66", +"o, c #475042", +"p, c #191B18", +"q, c #1A1C1A", +"r, c #5B6259", +"s, c #929D8D", +"t, c #9FAC9B", +"u, c #96A292", +"v, c #97A293", +"w, c #9DA898", +"x, c #98A493", +"y, c #A2AF9D", +"z, c #B1BEAC", +"A, c #B2BFAC", +"B, c #A7B4A2", +"C, c #AFBDA9", +"D, c #BAC9B5", +"E, c #C3D2BD", +"F, c #AEBDAA", +"G, c #3D423C", +"H, c #040304", +"I, c #161617", +"J, c #1D2119", +"K, c #33372E", +"L, c #5B595A", +"M, c #5B5E57", +"N, c #425239", +"O, c #254019", +"P, c #112E07", +"Q, c #0B2804", +"R, c #0C2805", +"S, c #331C03", +"T, c #6B1303", +"U, c #641C06", +"V, c #47330E", +"W, c #214010", +"X, c #17410F", +"Y, c #1A410E", +"Z, c #18420E", +"`, c #17440E", +" ' c #1A460C", +".' c #1B470D", +"+' c #245017", +"@' c #315D25", +"#' c #547B49", +"$' c #94A591", +"%' c #B2AEA5", +"&' c #808361", +"*' c #253E0B", +"=' c #112B00", +"-' c #1E2F06", +";' c #5A2204", +">' c #831C07", +",' c #862410", +"'' c #832C1B", +")' c #773829", +"!' c #744337", +"~' c #7D5047", +"{' c #7E5E58", +"]' c #776966", +"^' c #7D7977", +"/' c #868585", +"(' c #2F4A1E", +"_' c #15200D", +":' c #040701", +"<' c #0E0E0E", +"[' c #D6D6D7", +"}' c #545653", +"|' c #050A03", +"1' c #5E5E5E", +"2' c #030203", +"3' c #161516", +"4' c #666566", +"5' c #AAAFA7", +"6' c #728864", +"7' c #385822", +"8' c #3A5B23", +"9' c #37581F", +"0' c #405F2B", +"a' c #476433", +"b' c #3D572C", +"c' c #2A401C", +"d' c #213215", +"e' c #17230E", +"f' c #10190A", +"g' c #080C06", +"h' c #0A0D0A", +"i' c #0F110E", +"j' c #434741", +"k' c #838B80", +"l' c #949C90", +"m' c #8A9387", +"n' c #899386", +"o' c #889284", +"p' c #8F998A", +"q' c #8D9989", +"r' c #9EA999", +"s' c #A1AD9C", +"t' c #9BA796", +"u' c #94A191", +"v' c #A4B29F", +"w' c #B9C7B3", +"x' c #A8B4A2", +"y' c #484E46", +"z' c #09080A", +"A' c #141315", +"B' c #161A12", +"C' c #0D1809", +"D' c #081503", +"E' c #061903", +"F' c #0B1803", +"G' c #381403", +"H' c #541F08", +"I' c #2C310B", +"J' c #163A0D", +"K' c #15390C", +"L' c #17390C", +"M' c #18390C", +"N' c #173A0C", +"O' c #17390A", +"P' c #173B0B", +"Q' c #163B0A", +"R' c #143A08", +"S' c #143D05", +"T' c #355A24", +"U' c #869483", +"V' c #A8ABAB", +"W' c #6E8664", +"X' c #1E4911", +"Y' c #073100", +"Z' c #1B2F05", +"`' c #422605", +" ) c #691E05", +".) c #8C1A04", +"+) c #832915", +"@) c #822F1F", +"#) c #79382B", +"$) c #74453B", +"%) c #7E5A51", +"&) c #826762", +"*) c #796F6C", +"=) c #7D7C7B", +"-) c #365321", +";) c #1D2D11", +">) c #000200", +",) c #0D0C0D", +"') c #2A292A", +")) c #575757", +"!) c #838383", +"~) c #ADACAD", +"{) c #121213", +"]) c #1A1A1A", +"^) c #434343", +"/) c #666667", +"() c #BABDB9", +"_) c #86987B", +":) c #3F602B", +"<) c #3A5C23", +"[) c #345122", +"}) c #375028", +"|) c #465B38", +"1) c #5A6C4E", +"2) c #6A7B60", +"3) c #6C7B63", +"4) c #6E7B68", +"5) c #777F72", +"6) c #80887D", +"7) c #889385", +"8) c #8D9689", +"9) c #90998B", +"0) c #929C8E", +"a) c #959F90", +"b) c #8A9587", +"c) c #8C9687", +"d) c #99A594", +"e) c #9CA998", +"f) c #ACB9A7", +"g) c #A5B2A0", +"h) c #5B6157", +"i) c #0B0B0A", +"j) c #090B09", +"k) c #000100", +"l) c #0D0501", +"m) c #1B0702", +"n) c #280902", +"o) c #1D1907", +"p) c #0D2409", +"q) c #0E2608", +"r) c #122B0A", +"s) c #14330B", +"t) c #16360B", +"u) c #16370C", +"v) c #17380C", +"w) c #18390D", +"x) c #16380B", +"y) c #113406", +"z) c #244815", +"A) c #66765D", +"B) c #999998", +"C) c #798672", +"D) c #294C1A", +"E) c #082F00", +"F) c #0B3205", +"G) c #212F06", +"H) c #671F05", +"I) c #8F1701", +"J) c #8B1500", +"K) c #8C1801", +"L) c #7F220E", +"M) c #812E1C", +"N) c #823627", +"O) c #7F3F32", +"P) c #734A40", +"Q) c #785C56", +"R) c #826B67", +"S) c #817673", +"T) c #7E7F7E", +"U) c #375622", +"V) c #283E19", +"W) c #18260E", +"X) c #0D1407", +"Y) c #1D1C1D", +"Z) c #747474", +"`) c #181818", +" ! c #3D3C3E", +".! c #8F928E", +"+! c #677C59", +"@! c #3C5B25", +"#! c #385A21", +"$! c #3C5B27", +"%! c #405E2C", +"&! c #476234", +"*! c #4E673E", +"=! c #596F4C", +"-! c #65785A", +";! c #6A7B61", +">! c #788571", +",! c #7D8A78", +"'! c #7E897A", +")! c #7C867A", +"!! c #868E83", +"~! c #889183", +"{! c #919C8D", +"]! c #AAB7A5", +"^! c #B5C3AF", +"/! c #838D7E", +"(! c #282B27", +"_! c #0E0F0C", +":! c #343832", +"~ c #755952", +",~ c #766662", +"'~ c #7F7370", +")~ c #86807F", +"!~ c #2F4A1D", +"~~ c #1D2E12", +"{~ c #0D1606", +"]~ c #070A05", +"^~ c #181718", +"/~ c #2E2E2E", +"(~ c #4F4F50", +"_~ c #808080", +":~ c #797979", +"<~ c #717171", +"[~ c #6B6B6B", +"}~ c #636363", +"|~ c #0A0A0B", +"1~ c #363537", +"2~ c #919A8C", +"3~ c #546E41", +"4~ c #34561D", +"5~ c #72806B", +"6~ c #8A9386", +"7~ c #A2AF9E", +"8~ c #AFBDAA", +"9~ c #CBDBC5", +"0~ c #BFCEB9", +"a~ c #7E877A", +"b~ c #3B3F39", +"c~ c #0A0B0A", +"d~ c #212420", +"e~ c #434840", +"f~ c #1D201C", +"g~ c #010100", +"h~ c #020C00", +"i~ c #2E4722", +"j~ c #6E7667", +"k~ c #91918F", +"l~ c #718366", +"m~ c #325823", +"n~ c #1B4E0C", +"o~ c #799772", +"p~ c #B9BFBB", +"q~ c #8F795A", +"r~ c #7A2803", +"s~ c #8B1700", +"t~ c #881B04", +"u~ c #871F09", +"v~ c #89230E", +"w~ c #822817", +"x~ c #773527", +"y~ c #7B463A", +"z~ c #81544A", +"A~ c #7A5C55", +"B~ c #786B67", +"C~ c #8D8C8C", +"D~ c #283F18", +"E~ c #0E1908", +"F~ c #0F0E0F", +"G~ c #7D7D7D", +"H~ c #9FAB97", +"I~ c #466432", +"J~ c #72816C", +"K~ c #899285", +"L~ c #8F9A8B", +"M~ c #AAB8A5", +"N~ c #C1D0BB", +"O~ c #CCDBC5", +"P~ c #D5E5CE", +"Q~ c #C5D4BF", +"R~ c #879183", +"S~ c #333732", +"T~ c #070807", +"U~ c #222521", +"V~ c #0E100E", +"W~ c #010401", +"X~ c #0D2A04", +"Y~ c #213E13", +"Z~ c #5A6B4F", +"`~ c #92968D", +" { c #A4A99F", +".{ c #6E8960", +"+{ c #396723", +"@{ c #719065", +"#{ c #B6BDB5", +"${ c #A29478", +"%{ c #923E1A", +"&{ c #7A2A18", +"*{ c #787372", +"={ c #355121", +"-{ c #1F3112", +";{ c #0C1207", +">{ c #272628", +",{ c #676767", +"'{ c #3B3B3B", +"){ c #484848", +"!{ c #545454", +"~{ c #D9D9DA", +"{{ c #D5D8D4", +"]{ c #708562", +"^{ c #71806A", +"/{ c #8C9588", +"({ c #98A393", +"_{ c #9DA998", +":{ c #B5C2AF", +"<{ c #B0BEAC", +"[{ c #BCCBB7", +"}{ c #CDDCC6", +"|{ c #D1E1CA", +"1{ c #B8C5B1", +"2{ c #5F665C", +"3{ c #1D1F1C", +"4{ c #0C131D", +"5{ c #264A47", +"6{ c #0F2D02", +"7{ c #133604", +"8{ c #365826", +"9{ c #788A6E", +"0{ c #AFB2AB", +"a{ c #A3AC9C", +"b{ c #6D8E58", +"c{ c #739260", +"d{ c #A6B7AA", +"e{ c #B19B85", +"f{ c #963411", +"g{ c #8C1500", +"h{ c #7B200E", +"i{ c #625D5D", +"j{ c #304B1E", +"k{ c #15230B", +"l{ c #0B0E09", +"m{ c #8C8C8D", +"n{ c #5A5A5A", +"o{ c #E0DFE0", +"p{ c #D8DBD7", +"q{ c #798D6C", +"r{ c #606D5A", +"s{ c #8C9689", +"t{ c #9BA696", +"u{ c #A9B6A4", +"v{ c #B6C5B1", +"w{ c #B9C7B4", +"x{ c #ABB9A6", +"y{ c #BFCEB8", +"z{ c #CEDDC7", +"A{ c #CEDEC8", +"B{ c #8C9788", +"C{ c #191B19", +"D{ c #363934", +"E{ c #020302", +"F{ c #0E1725", +"G{ c #2C5158", +"H{ c #143106", +"I{ c #15360A", +"J{ c #123906", +"K{ c #174408", +"L{ c #426930", +"M{ c #92A288", +"N{ c #BBBBB8", +"O{ c #839A74", +"P{ c #6D8F57", +"Q{ c #A4B4A1", +"R{ c #A38061", +"S{ c #871E01", +"T{ c #8C1702", +"U{ c #921B03", +"V{ c #6E1A09", +"W{ c #403F41", +"X{ c #0B1504", +"Y{ c #5F5F60", +"Z{ c #3E3E3E", +"`{ c #7A797A", +" ] c #CED0CC", +".] c #33551D", +"+] c #34531E", +"@] c #374032", +"#] c #81897D", +"$] c #95A190", +"%] c #B4C1AF", +"&] c #B1C0AD", +"*] c #BDCCB7", +"=] c #C2D0BC", +"-] c #B7C5B1", +";] c #C8D7C2", +">] c #D4E4CD", +",] c #858F81", +"'] c #535B51", +")] c #3C423B", +"!] c #0E1623", +"~] c #2B5055", +"{] c #193F0E", +"]] c #1A430D", +"^] c #154307", +"/] c #215010", +"(] c #6C895B", +"_] c #B2B6AD", +":] c #A2AC99", +"<] c #A1AE9D", +"[] c #A4AF9A", +"}] c #755122", +"|] c #891A00", +"1] c #8D1903", +"2] c #6F1A08", +"3] c #334F20", +"4] c #060C02", +"5] c #868586", +"6] c #2C2C2C", +"7] c #383838", +"8] c #252525", +"9] c #0B0B0B", +"0] c #929392", +"a] c #94A28B", +"b] c #3E5D2A", +"c] c #34551E", +"d] c #3E5D28", +"e] c #355520", +"f] c #1B2216", +"g] c #686F66", +"h] c #8C9889", +"i] c #B6C4B1", +"j] c #ACBAA6", +"k] c #B4C2AF", +"l] c #B7C5B2", +"m] c #C9D8C2", +"n] c #C6D5BF", +"o] c #CFDEC8", +"p] c #C4D4BE", +"q] c #99A595", +"r] c #B8C7B3", +"s] c #869183", +"t] c #0D0E0D", +"u] c #1D460F", +"v] c #1F4B10", +"w] c #1A470C", +"x] c #184A06", +"y] c #5D8048", +"z] c #B5B7B3", +"A] c #BCBABD", +"B] c #A7B3A4", +"C] c #6C854A", +"D] c #793B0F", +"E] c #901A03", +"F] c #8C1A03", +"G] c #414042", +"H] c #030601", +"I] c #080709", +"J] c #A3A5A2", +"K] c #A3AF99", +"L] c #738966", +"M] c #7A8C6E", +"N] c #85957A", +"O] c #567044", +"P] c #385823", +"Q] c #080D04", +"R] c #3F423E", +"S] c #949F8F", +"T] c #BAC8B4", +"U] c #BBC9B5", +"V] c #BBCAB5", +"W] c #B8C6B3", +"X] c #ACB9A6", +"Y] c #C3D1BD", +"Z] c #B7C4B1", +"`] c #747D71", +" ^ c #838C7E", +".^ c #171916", +"+^ c #1E4B10", +"@^ c #214E12", +"#^ c #1B490D", +"$^ c #285914", +"%^ c #678B52", +"&^ c #849C74", +"*^ c #6C8E56", +"=^ c #336B22", +"-^ c #514913", +";^ c #8E2208", +">^ c #2D461C", +",^ c #131C0B", +"'^ c #010301", +")^ c #202020", +"!^ c #353435", +"~^ c #989797", +"{^ c #CDD0CB", +"]^ c #D8DAD7", +"^^ c #BBC2B6", +"/^ c #42612C", +"(^ c #070D03", +"_^ c #0C0B0C", +":^ c #676F64", +"<^ c #ABB7A5", +"[^ c #BDCBB6", +"}^ c #BFCDBA", +"|^ c #C4D2BD", +"1^ c #D7E7D0", +"2^ c #8B9587", +"3^ c #141513", +"4^ c #2C2F2B", +"5^ c #575E55", +"6^ c #1D4A0F", +"7^ c #1E4C0F", +"8^ c #1D4E0D", +"9^ c #417128", +"0^ c #70925B", +"a^ c #7D976B", +"b^ c #4F7B40", +"c^ c #45460F", +"d^ c #892106", +"e^ c #8E1A03", +"f^ c #030401", +"g^ c #646464", +"h^ c #8E8D8E", +"i^ c #A5A4A5", +"j^ c #989798", +"k^ c #898C86", +"l^ c #5C6D50", +"m^ c #43612E", +"n^ c #080E04", +"o^ c #31352F", +"p^ c #8B9586", +"q^ c #C2D1BC", +"r^ c #B1BFAC", +"s^ c #ADBAA8", +"t^ c #C3D3BE", +"u^ c #666E62", +"v^ c #2C302C", +"w^ c #143105", +"x^ c #16370B", +"y^ c #163C0B", +"z^ c #164108", +"A^ c #194709", +"B^ c #1B4B0A", +"C^ c #184907", +"D^ c #184C05", +"E^ c #728D63", +"F^ c #BABAB9", +"G^ c #B8BAB6", +"H^ c #AFB9AD", +"I^ c #736638", +"J^ c #7E1900", +"K^ c #901903", +"L^ c #121E0A", +"M^ c #010300", +"N^ c #515151", +"O^ c #7C7C7C", +"P^ c #131313", +"Q^ c #252425", +"R^ c #2E2F2D", +"S^ c #344329", +"T^ c #2B3426", +"U^ c #2D2F2C", +"V^ c #6F786C", +"W^ c #BDCBB7", +"X^ c #6B7469", +"Y^ c #373C35", +"Z^ c #333731", +"`^ c #2F332E", +" / c #4A4F47", +"./ c #252824", +"+/ c #090908", +"@/ c #262824", +"#/ c #383D37", +"$/ c #3E423C", +"%/ c #51574F", +"&/ c #424741", +"*/ c #0D1623", +"=/ c #2D5356", +"-/ c #143206", +";/ c #1E4610", +">/ c #426730", +",/ c #587A44", +"'/ c #5E814A", +")/ c #628451", +"!/ c #79936C", +"~/ c #B9B9B7", +"{/ c #A5AE9F", +"]/ c #5C8049", +"^/ c #A1AF9E", +"// c #ACA694", +"(/ c #763810", +"_/ c #7F1200", +":/ c #8C1E06", +"( c #292929", +",( c #060A04", +"'( c #717F69", +")( c #7E867B", +"!( c #7D8679", +"~( c #272A25", +"{( c #020101", +"]( c #0F110F", +"^( c #0A1420", +"/( c #385D61", +"(( c #676E5E", +"_( c #8D8A8F", +":( c #7F8B79", +"<( c #50723F", +"[( c #2D581B", +"}( c #1A4409", +"|( c #174107", +"1( c #0F3A00", +"2( c #0E3501", +"3( c #123806", +"4( c #153A07", +"5( c #113605", +"6( c #103A01", +"7( c #3A6428", +"8( c #7D9671", +"9( c #A0AF98", +"0( c #A8B49F", +"a( c #AFB9AA", +"b( c #B5BDB2", +"c( c #B4A38C", +"d( c #A3512E", +"e( c #8F1A01", +"f( c #8E1903", +"g( c #304C1E", +"h( c #15210C", +"i( c #666666", +"j( c #616161", +"k( c #050802", +"l( c #1E2E12", +"m( c #365322", +"n( c #707E69", +"o( c #899286", +"p( c #97A393", +"q( c #676E63", +"r( c #000101", +"s( c #111210", +"t( c #282A26", +"u( c #282B26", +"v( c #10120F", +"w( c #07111D", +"x( c #536D80", +"y( c #7C7B77", +"z( c #5F7054", +"A( c #264A17", +"B( c #0B3300", +"C( c #0C3101", +"D( c #0A3200", +"E( c #0D3700", +"F( c #0E3600", +"G( c #0C3400", +"H( c #0D3400", +"I( c #123705", +"J( c #133806", +"K( c #0D3501", +"L( c #133F03", +"M( c #275316", +"N( c #3D652C", +"O( c #527540", +"P( c #67865A", +"Q( c #799A71", +"R( c #798049", +"S( c #5A3008", +"T( c #631C02", +"U( c #801C04", +"V( c #0B0F08", +"W( c #0A0A0C", +"X( c #444444", +"Y( c #606060", +"Z( c #6F6F6F", +"`( c #6C6C6C", +" _ c #020401", +"._ c #365221", +"+_ c #707F6A", +"@_ c #8B9689", +"#_ c #99A494", +"$_ c #575E54", +"%_ c #1B1E1A", +"&_ c #8D9788", +"*_ c #B4C1AE", +"=_ c #8E9888", +"-_ c #373B35", +";_ c #07121C", +">_ c #5B718A", +",_ c #636C58", +"'_ c #1C3C0D", +")_ c #092A00", +"!_ c #0D2E02", +"~_ c #0C3300", +"{_ c #164305", +"]_ c #355F23", +"^_ c #5F7F4E", +"/_ c #678258", +"(_ c #376026", +"__ c #164107", +":_ c #0E3502", +"<_ c #143907", +"[_ c #113705", +"}_ c #0B3400", +"|_ c #0E3800", +"1_ c #144104", +"2_ c #19460D", +"3_ c #153C09", +"4_ c #1C3206", +"5_ c #3B2905", +"6_ c #731D04", +"7_ c #314E1E", +"8_ c #17240E", +"9_ c #252623", +"0_ c #4D4C4D", +"a_ c #3F3F3F", +"b_ c #2A2A2A", +"c_ c #848D81", +"d_ c #565D54", +"e_ c #040504", +"f_ c #CFDFC9", +"g_ c #D0E0C9", +"h_ c #D1E0C9", +"i_ c #3A3F39", +"j_ c #5B7289", +"k_ c #475839", +"l_ c #092600", +"m_ c #0B2A02", +"n_ c #153D06", +"o_ c #3C6429", +"p_ c #7C936D", +"q_ c #AFB5AA", +"r_ c #BEBFBC", +"s_ c #B1B9A9", +"t_ c #AAB5A2", +"u_ c #B3B9AF", +"v_ c #758F67", +"w_ c #1D490C", +"x_ c #143A07", +"y_ c #133907", +"z_ c #113704", +"A_ c #103604", +"B_ c #113806", +"C_ c #0F3906", +"D_ c #292F06", +"E_ c #652004", +"F_ c #0D100A", +"G_ c #2B2B2C", +"H_ c #646465", +"I_ c #687662", +"J_ c #777F74", +"K_ c #AEBCA9", +"L_ c #6F786B", +"M_ c #919C8C", +"N_ c #C6D5C0", +"O_ c #B7C6B1", +"P_ c #C9D7C3", +"Q_ c #BECDB8", +"R_ c #CADAC4", +"S_ c #D3E3CD", +"T_ c #A2AE9D", +"U_ c #1D1E1C", +"V_ c #101210", +"W_ c #333631", +"X_ c #4A5A3C", +"Y_ c #072500", +"Z_ c #1B3F0D", +"`_ c #6C845D", +" : c #ADB1A8", +".: c #BFBDBE", +"+: c #9FAB96", +"@: c #698859", +"#: c #446C31", +"$: c #446D31", +"%: c #8EA084", +"&: c #C4C3C3", +"*: c #758F66", +"=: c #144006", +"-: c #0E3601", +";: c #0F3900", +">: c #103A00", +",: c #0B3804", +"': c #223005", +"): c #652005", +"!: c #365522", +"~: c #090D06", +"{: c #060506", +"]: c #595959", +"^: c #040405", +"/: c #6B7964", +"(: c #80887C", +"_: c #838D7F", +":: c #A8B5A3", +"<: c #9FAB9A", +"[: c #3B4039", +"}: c #B4C3AF", +"|: c #CEDEC7", +"1: c #CCDCC6", +"2: c #5E645A", +"3: c #1B1D1A", +"4: c #848F7F", +"5: c #596057", +"6: c #1F211E", +"7: c #5F6956", +"8: c #113604", +"9: c #556E49", +"0: c #B0ADAF", +"a: c #A7ABA2", +"b: c #648551", +"c: c #2D5C19", +"d: c #174806", +"e: c #164608", +"f: c #154405", +"g: c #24550F", +"h: c #889B7D", +"i: c #557746", +"j: c #103704", +"k: c #123E04", +"l: c #345F22", +"m: c #608050", +"n: c #738F64", +"o: c #4E733C", +"p: c #1B470C", +"q: c #083600", +"r: c #182E01", +"s: c #522206", +"t: c #171718", +"u: c #020203", +"v: c #0C1308", +"w: c #283F19", +"x: c #868E82", +"y: c #899585", +"z: c #9FAC9A", +"A: c #8D9889", +"B: c #222522", +"C: c #5E665C", +"D: c #B2C1AE", +"E: c #CADAC3", +"F: c #848E80", +"G: c #777F73", +"H: c #D3E3CC", +"I: c #474C45", +"J: c #07121D", +"K: c #526D7E", +"L: c #73766D", +"M: c #526746", +"N: c #848C7F", +"O: c #AAA8A8", +"P: c #587B46", +"Q: c #154804", +"R: c #19470A", +"S: c #1F4C10", +"T: c #204E11", +"U: c #164506", +"V: c #325F1F", +"W: c #ADB4A7", +"X: c #98A690", +"Y: c #103503", +"Z: c #103603", +"`: c #164306", +" < c #5F814E", +".< c #A8B2A2", +"+< c #BDBEBA", +"@< c #B9BBB4", +"#< c #B8BAB3", +"$< c #93A389", +"%< c #5D804C", +"&< c #1D5012", +"*< c #112F00", +"=< c #522204", +"-< c #841C04", +";< c #141F0C", +">< c #030402", +",< c #070C04", +"'< c #263A17", +")< c #3B5A24", +"!< c #6F7D68", +"~< c #8A9487", +"{< c #94A08F", +"]< c #A0AC9B", +"^< c #BECCB7", +"/< c #9BA797", +"(< c #C7D6C1", +"_< c #AFBCAA", +":< c #B8C6B2", +"<< c #BECCB8", +"[< c #C8D8C2", +"}< c #CAD9C3", +"|< c #8A9586", +"1< c #070706", +"2< c #1F221E", +"3< c #707A6D", +"4< c #BECCB9", +"5< c #D2E3CC", +"6< c #BCC9B6", +"7< c #565D53", +"8< c #091320", +"9< c #3F6168", +"0< c #6F7368", +"a< c #888787", +"b< c #9C9A9D", +"c< c #919C89", +"d< c #2E5B1B", +"e< c #174609", +"f< c #1E4B0F", +"g< c #1A4D09", +"h< c #819774", +"i< c #A9B1A3", +"j< c #275116", +"k< c #0E3401", +"l< c #133E03", +"m< c #668555", +"n< c #BDBDBA", +"o< c #BCBCBB", +"p< c #799269", +"q< c #466E34", +"r< c #678556", +"s< c #99A98E", +"t< c #C0C0BD", +"u< c #93A48A", +"v< c #29591C", +"w< c #0B3100", +"x< c #412605", +"y< c #841B04", +"z< c #921A04", +"A< c #223616", +"B< c #0D1508", +"C< c #757575", +"D< c #7E7E7E", +"E< c #293F1A", +"F< c #717F6A", +"G< c #858F82", +"H< c #919D8D", +"I< c #9CA897", +"J< c #BFCDB9", +"K< c #C3D3BD", +"L< c #B8C7B2", +"M< c #C6D6C0", +"N< c #CAD9C4", +"O< c #050504", +"P< c #5A6158", +"Q< c #B6C3B0", +"R< c #BFCFBA", +"S< c #BECEB8", +"T< c #D2E2CB", +"U< c #C7D7C1", +"V< c #778074", +"W< c #1B1C19", +"X< c #2A5153", +"Y< c #3B512B", +"Z< c #6D7765", +"`< c #7F8A77", +" [ c #527441", +".[ c #1E4B0D", +"+[ c #1F4B0F", +"@[ c #1E4C10", +"#[ c #1C4D0B", +"$[ c #7E946F", +"%[ c #A2AD9A", +"&[ c #234E13", +"*[ c #0D3201", +"=[ c #0F3901", +"-[ c #51763F", +";[ c #B6B8B2", +">[ c #5E814C", +",[ c #1C4E0A", +"'[ c #164606", +")[ c #194907", +"![ c #265512", +"~[ c #6E8B5E", +"{[ c #BFBEBC", +"][ c #9DAC93", +"^[ c #376628", +"/[ c #0B3200", +"([ c #3D2402", +"_[ c #781C04", +":[ c #1B2910", +"<[ c #070B05", +"[[ c #09090A", +"}[ c #181819", +"|[ c #6B7864", +"1[ c #818A7D", +"2[ c #8E998A", +"3[ c #B1BEAA", +"4[ c #CDDBC6", +"5[ c #ABB8A5", +"6[ c #C0CEB9", +"7[ c #C5D3BE", +"8[ c #798477", +"9[ c #B7C6B2", +"0[ c #BFCEBA", +"a[ c #C1CFBB", +"b[ c #323631", +"c[ c #0E1723", +"d[ c #2A4F54", +"e[ c #123003", +"f[ c #1D3E0E", +"g[ c #244A14", +"h[ c #1D480D", +"i[ c #1D490F", +"j[ c #204D11", +"k[ c #1D4C0F", +"l[ c #1F500E", +"m[ c #8D9E83", +"n[ c #98A68E", +"o[ c #1D480C", +"p[ c #092F00", +"q[ c #214C10", +"r[ c #9AA98F", +"s[ c #C0BEBF", +"t[ c #5C7E4B", +"u[ c #164805", +"v[ c #1B4A0C", +"w[ c #1A4D07", +"x[ c #5F814D", +"y[ c #B9BBB5", +"z[ c #487239", +"A[ c #0D3D01", +"B[ c #2D2701", +"C[ c #781C05", +"D[ c #1C2C11", +"E[ c #1E1D1E", +"F[ c #585858", +"G[ c #1A2810", +"H[ c #6D7A66", +"I[ c #80897D", +"J[ c #A5B1A1", +"K[ c #B0BDAB", +"L[ c #B2C0AC", +"M[ c #C5D3BF", +"N[ c #BAC9B4", +"O[ c #737C6F", +"P[ c #C8D6C1", +"Q[ c #AFBDAB", +"R[ c #132F05", +"S[ c #123407", +"T[ c #153B0A", +"U[ c #1B440E", +"V[ c #1C4B0E", +"W[ c #245512", +"X[ c #9AA890", +"Y[ c #889C7B", +"Z[ c #154005", +"`[ c #072E00", +" } c #385C28", +".} c #B7BAB1", +"+} c #1E500B", +"@} c #1B490C", +"#} c #214E11", +"$} c #174906", +"%} c #4D733A", +"&} c #ABB2A5", +"*} c #B9BCB4", +"=} c #6D8E61", +"-} c #18460B", +";} c #282701", +">} c #671F04", +",} c #355220", +"'} c #080708", +")} c #6D7A65", +"!} c #A0AC9C", +"~} c #B3C1AD", +"{} c #C9D7C2", +"]} c #545A51", +"^} c #121312", +"/} c #939F8F", +"(} c #D1E2CC", +"_} c #BAC8B5", +":} c #B9C8B3", +"<} c #D4E5CE", +"[} c #A9B7A5", +"}} c #232623", +"|} c #1A4A0A", +"1} c #3B6728", +"2} c #B0B6A9", +"3} c #79916B", +"4} c #103B00", +"5} c #406031", +"6} c #B2B8AB", +"7} c #164706", +"8} c #1D4B0E", +"9} c #174706", +"0} c #3A6626", +"a} c #C7C4C8", +"b} c #718E64", +"c} c #0C3F00", +"d} c #1F2B01", +"e} c #6C1F05", +"f} c #3C5B24", +"g} c #121D0C", +"h} c #10180A", +"i} c #63705D", +"j} c #929D8E", +"k} c #CBDAC4", +"l} c #BBCAB6", +"m} c #C3D2BE", +"n} c #333531", +"o} c #121412", +"p} c #B3C1AE", +"q} c #B2C0AD", +"r} c #C5D5BF", +"s} c #C0CFBB", +"t} c #C9D8C3", +"u} c #D1E2CB", +"v} c #95A191", +"w} c #204E10", +"x} c #557844", +"y} c #6C895E", +"z} c #0A3100", +"A} c #436535", +"B} c #AEB6A5", +"C} c #476C37", +"D} c #164707", +"E} c #1F4D11", +"F} c #154506", +"G} c #2B5B17", +"H} c #92A487", +"I} c #5E7F4E", +"J} c #0A3A00", +"K} c #262A03", +"L} c #6F1E05", +"M} c #345020", +"N} c #3B5B26", +"O} c #798276", +"P} c #C8D8C3", +"Q} c #CBDBC6", +"R} c #2A2E29", +"S} c #20231F", +"T} c #95A090", +"U} c #204D10", +"V} c #5B7E4C", +"W} c #BEBEBB", +"X} c #597A4B", +"Y} c #0C3500", +"Z} c #486A3A", +"`} c #AFB6A8", +" | c #476D37", +".| c #174708", +"+| c #356222", +"@| c #A1AC99", +"#| c #BFBEBB", +"$| c #597D49", +"%| c #0C3B01", +"&| c #2B2B04", +"*| c #662005", +"=| c #851B04", +"-| c #4F4F4F", +";| c #1E1E1E", +">| c #2D2D2D", +",| c #121E0C", +"'| c #6C7A66", +")| c #838B7F", +"!| c #96A191", +"~| c #C6D4BF", +"{| c #C1D0BC", +"]| c #869083", +"^| c #383D36", +"/| c #A4B09F", +"(| c #B2C1AD", +"_| c #D2E2CC", +":| c #1E4C0E", +"<| c #235311", +"[| c #859B78", +"}| c #BCBDB9", +"|| c #4C6F3D", +"1| c #0A3300", +"2| c #113C04", +"3| c #6C885C", +"4| c #B4B8B0", +"5| c #456C35", +"6| c #99A78F", +"7| c #B9BCB5", +"8| c #442805", +"9| c #14220C", +"0| c #324F1E", +"a| c #65735F", +"b| c #A0AD9C", +"c| c #BBC8B4", +"d| c #C1D1BC", +"e| c #CBDAC5", +"f| c #5C6359", +"g| c #010202", +"h| c #C3D2BC", +"i| c #CCDBC4", +"j| c #CCDAC5", +"k| c #C4D3BF", +"l| c #B0BEAB", +"m| c #D1E1CB", +"n| c #A9B6A3", +"o| c #1A4809", +"p| c #3F6A2B", +"q| c #B1B6AB", +"r| c #AFB6AA", +"s| c #3B642A", +"t| c #073000", +"u| c #1F490F", +"v| c #B1B5AB", +"w| c #3C652A", +"x| c #184709", +"y| c #134505", +"z| c #366223", +"A| c #B3B7AE", +"B| c #8FA084", +"C| c #154206", +"D| c #0B3704", +"E| c #143706", +"F| c #442706", +"G| c #7C1C04", +"H| c #030602", +"I| c #5B5B5B", +"J| c #111310", +"K| c #253519", +"L| c #626E5B", +"M| c #7A8478", +"N| c #8E9A8A", +"O| c #B0BDAA", +"P| c #CBD9C4", +"Q| c #CADAC5", +"R| c #677065", +"S| c #C8D7C1", +"T| c #BCCBB6", +"U| c #B9C6B3", +"V| c #AAB7A4", +"W| c #6E776B", +"X| c #0B0C0B", +"Y| c #174808", +"Z| c #4A7138", +"`| c #BABCB6", +" 1 c #8FA186", +".1 c #1E4A0D", +"+1 c #255014", +"@1 c #A6AFA1", +"#1 c #2B5A18", +"$1 c #174A06", +"%1 c #7A926D", +"&1 c #B8BBB2", +"*1 c #3A6328", +"=1 c #103806", +"-1 c #123807", +";1 c #332B05", +">1 c #7A1C04", +",1 c #192710", +"'1 c #575657", +")1 c #6E726B", +"!1 c #2B3F1C", +"~1 c #6A7863", +"{1 c #7E877B", +"]1 c #A0AC9A", +"^1 c #C2D2BC", +"/1 c #C7D7C2", +"(1 c #CDDDC7", +"_1 c #161916", +":1 c #727C6F", +"<1 c #B6C5B0", +"[1 c #AFBEAA", +"}1 c #7B8477", +"|1 c #174709", +"11 c #426A2F", +"21 c #B6BBB0", +"31 c #809576", +"41 c #123D04", +"51 c #376125", +"61 c #B2B7AE", +"71 c #275713", +"81 c #1B4A0D", +"91 c #174807", +"01 c #4A7139", +"a1 c #95A58B", +"b1 c #376224", +"c1 c #0E3A00", +"d1 c #0D3703", +"e1 c #103907", +"f1 c #3A2A05", +"g1 c #7D1C04", +"h1 c #060A03", +"i1 c #656566", +"j1 c #191F15", +"k1 c #284018", +"l1 c #6B7965", +"m1 c #868F82", +"n1 c #A7B4A3", +"o1 c #AFBCA9", +"p1 c #6B7368", +"q1 c #3D413B", +"r1 c #B6C5B2", +"s1 c #ACBAA7", +"t1 c #B8C5B2", +"u1 c #BCCAB5", +"v1 c #CEDDC8", +"w1 c #D0E0CA", +"x1 c #060605", +"y1 c #1C4A0D", +"z1 c #275616", +"A1 c #9FAA97", +"B1 c #819676", +"C1 c #103A03", +"D1 c #0B3500", +"E1 c #5E7E4F", +"F1 c #C0C0BF", +"G1 c #819873", +"H1 c #1F500D", +"I1 c #21520F", +"J1 c #6D8C5C", +"K1 c #B3B8AF", +"L1 c #618151", +"M1 c #174405", +"N1 c #093400", +"O1 c #402805", +"P1 c #821C04", +"Q1 c #6C7A65", +"R1 c #94A090", +"S1 c #B5C4B0", +"T1 c #C0CEBA", +"U1 c #666E63", +"V1 c #424640", +"W1 c #6C7368", +"X1 c #0E0F0E", +"Y1 c #0A0B09", +"Z1 c #1E4E0C", +"`1 c #95A58D", +" 2 c #7E9371", +".2 c #0F3801", +"+2 c #0C3600", +"@2 c #6F8B62", +"#2 c #B8BBB4", +"$2 c #4A7237", +"%2 c #1D4B0D", +"&2 c #4B723A", +"*2 c #A1AC98", +"=2 c #BFBFBC", +"-2 c #829974", +";2 c #2F591F", +">2 c #0B3900", +",2 c #123304", +"'2 c #4B2302", +")2 c #871902", +"!2 c #2F2E2F", +"~2 c #232323", +"{2 c #345120", +"]2 c #C7D6C0", +"^2 c #B4C2AE", +"/2 c #CFDEC9", +"(2 c #464B44", +"_2 c #232622", +":2 c #A9B5A4", +"<2 c #CDDCC7", +"[2 c #ADBBA8", +"}2 c #BCCAB6", +"|2 c #C2D2BD", +"12 c #C1D1BB", +"22 c #CFDFC8", +"32 c #757D70", +"42 c #0C0D0C", +"52 c #1E221E", +"62 c #144504", +"72 c #3F6A2A", +"82 c #AFB6A9", +"92 c #7D926F", +"02 c #0C3700", +"a2 c #708B63", +"b2 c #B2B6AC", +"c2 c #376124", +"d2 c #154605", +"e2 c #2F5D1B", +"f2 c #7D9570", +"g2 c #BFBEBD", +"h2 c #ADB4A6", +"i2 c #4D723B", +"j2 c #164B09", +"k2 c #324D13", +"l2 c #682706", +"m2 c #8C1904", +"n2 c #0B1107", +"o2 c #030304", +"p2 c #8B9588", +"q2 c #939E8E", +"r2 c #9AA696", +"s2 c #899485", +"t2 c #4D534B", +"u2 c #0F100E", +"v2 c #697165", +"w2 c #B1C0AC", +"x2 c #B5C3B0", +"y2 c #131412", +"z2 c #265613", +"A2 c #597D47", +"B2 c #A5AE9E", +"C2 c #C5C2C4", +"D2 c #688758", +"E2 c #547545", +"F2 c #BCBEB8", +"G2 c #5D7F4D", +"H2 c #1D4E0B", +"I2 c #547A41", +"J2 c #ACB3A5", +"K2 c #B1B6AC", +"L2 c #6F905B", +"M2 c #789761", +"N2 c #64632F", +"O2 c #6E2002", +"P2 c #233715", +"Q2 c #12170F", +"R2 c #060903", +"S2 c #65725E", +"T2 c #838D80", +"U2 c #CFDEC7", +"V2 c #C5D4BE", +"W2 c #C4D3BD", +"X2 c #525950", +"Y2 c #1C4B0D", +"Z2 c #275614", +"`2 c #BDBCBB", +" 3 c #859C77", +".3 c #2A561A", +"+3 c #103703", +"@3 c #0F3402", +"#3 c #245014", +"$3 c #A2AE9A", +"%3 c #A7B0A0", +"&3 c #2F5D1C", +"*3 c #194809", +"=3 c #1C4A0E", +"-3 c #144604", +";3 c #3F692D", +">3 c #AEB3A8", +",3 c #B8B9B4", +"'3 c #94A985", +")3 c #4B7536", +"!3 c #312F03", +"~3 c #761B03", +"{3 c #284019", +"]3 c #0E1708", +"^3 c #3B3D3B", +"/3 c #B7B7B8", +"(3 c #0A1006", +"_3 c #7F887D", +":3 c #4A5049", +"<3 c #4A5048", +"[3 c #C6D5C1", +"}3 c #484E45", +"|3 c #184909", +"13 c #577B45", +"23 c #BDBDBB", +"33 c #A8B0A1", +"43 c #597D45", +"53 c #1C480B", +"63 c #0F3702", +"73 c #143806", +"83 c #5A7B49", +"93 c #789169", +"03 c #1B4C09", +"a3 c #154604", +"b3 c #537541", +"c3 c #BCBCBA", +"d3 c #9DAA92", +"e3 c #295916", +"f3 c #083200", +"g3 c #3C2905", +"h3 c #17230D", +"i3 c #6E7C67", +"j3 c #656D62", +"k3 c #8E9889", +"l3 c #BDCBB8", +"m3 c #194908", +"n3 c #6C885D", +"o3 c #C3C1C2", +"p3 c #6F8C61", +"q3 c #0C3A00", +"r3 c #0E3402", +"s3 c #0D3401", +"t3 c #204B0F", +"u3 c #B6B9B2", +"v3 c #40692F", +"w3 c #194808", +"x3 c #184807", +"y3 c #6C895D", +"z3 c #819773", +"A3 c #1E4E0F", +"B3 c #0D3101", +"C3 c #4B2606", +"D3 c #121D0B", +"E3 c #192610", +"F3 c #97A392", +"G3 c #BAC7B4", +"H3 c #D4E3CD", +"I3 c #9CA797", +"J3 c #181A17", +"K3 c #808A7C", +"L3 c #C4D2BE", +"M3 c #B1BFAB", +"N3 c #2C302B", +"O3 c #1F4C11", +"P3 c #628251", +"Q3 c #C3C0C2", +"R3 c #7E9570", +"S3 c #144004", +"T3 c #628252", +"U3 c #C2BFC0", +"V3 c #678658", +"W3 c #194A08", +"X3 c #1F4D10", +"Y3 c #1F4F0D", +"Z3 c #7A936C", +"`3 c #C5C3C5", +" 4 c #839976", +".4 c #17470A", +"+4 c #163004", +"@4 c #5A2205", +"#4 c #121C0A", +"$4 c #616061", +"%4 c #191819", +"&4 c #BFCDB8", +"*4 c #5E655C", +"=4 c #737B6F", +"-4 c #BAC8B3", +";4 c #CCDAC4", +">4 c #C3D1BC", +",4 c #798376", +"'4 c #1A4909", +")4 c #3B6628", +"!4 c #3D652B", +"~4 c #083100", +"{4 c #0B3600", +"]4 c #587C47", +"^4 c #6D8A5D", +"/4 c #1A4B09", +"(4 c #19480A", +"_4 c #20510E", +":4 c #859A79", +"<4 c #C1C0BE", +"[4 c #527641", +"}4 c #053400", +"|4 c #222F06", +"14 c #681F04", +"24 c #0F1808", +"34 c #696869", +"44 c #97A292", +"54 c #C7D5C0", +"64 c #C0D0BA", +"74 c #CDDEC7", +"84 c #3E433D", +"94 c #3B413A", +"04 c #C9D9C2", +"a4 c #555C52", +"b4 c #769169", +"c4 c #C7C2C7", +"d4 c #8DA081", +"e4 c #255212", +"f4 c #184507", +"g4 c #849B76", +"h4 c #C1BEC0", +"i4 c #698858", +"j4 c #1A4B08", +"k4 c #315F1E", +"l4 c #9EAA95", +"m4 c #245214", +"n4 c #083400", +"o4 c #2E2D06", +"p4 c #751E04", +"q4 c #1F3014", +"r4 c #050902", +"s4 c #66735F", +"t4 c #838C7F", +"u4 c #ADBAA7", +"v4 c #BDCAB6", +"w4 c #D0E1CA", +"x4 c #3F433D", +"y4 c #3D423B", +"z4 c #CCDBC6", +"A4 c #CFE0CA", +"B4 c #40443E", +"C4 c #1A490A", +"D4 c #32601F", +"E4 c #9CAA93", +"F4 c #C5C1C4", +"G4 c #8CA180", +"H4 c #3A6327", +"I4 c #124002", +"J4 c #597C48", +"K4 c #B5B7B1", +"L4 c #B7B9B4", +"M4 c #51773D", +"N4 c #1A490B", +"O4 c #1B490B", +"P4 c #164507", +"Q4 c #164605", +"R4 c #6A8959", +"S4 c #C3C2C0", +"T4 c #859A77", +"U4 c #0B3402", +"V4 c #3A2A06", +"W4 c #7E1C04", +"X4 c #253916", +"Y4 c #757D72", +"Z4 c #D1E0CA", +"`4 c #818B7D", +" 5 c #879283", +".5 c #AEBBA9", +"+5 c #BBC8B5", +"@5 c #909B8C", +"#5 c #60675D", +"$5 c #4F564D", +"%5 c #889484", +"&5 c #184908", +"*5 c #3E692A", +"=5 c #9DAA93", +"-5 c #C6C2C7", +";5 c #ACB3A6", +">5 c #749064", +",5 c #AEB3A9", +"'5 c #C3BFC5", +")5 c #899E7B", +"!5 c #265612", +"~5 c #1C4A0C", +"{5 c #1E4F0C", +"]5 c #295816", +"^5 c #1A490C", +"/5 c #1F4E0E", +"(5 c #386324", +"_5 c #40692E", +":5 c #21500F", +"<5 c #21530F", +"[5 c #839975", +"}5 c #C6C2C4", +"|5 c #758E66", +"15 c #104003", +"25 c #123204", +"35 c #552305", +"45 c #7F887C", +"55 c #A7B3A1", +"65 c #BECBB6", +"75 c #393E37", +"85 c #383C36", +"95 c #646C61", +"05 c #184808", +"a5 c #32611E", +"b5 c #7B946B", +"c5 c #AFB5A9", +"d5 c #BBBCB8", +"e5 c #BFBEBE", +"f5 c #96A78C", +"g5 c #396625", +"h5 c #19490A", +"i5 c #718E60", +"j5 c #97A78D", +"k5 c #628352", +"l5 c #235312", +"m5 c #1A4A0B", +"n5 c #3D672A", +"o5 c #9DAB91", +"p5 c #AFB5A7", +"q5 c #738F62", +"r5 c #21510F", +"s5 c #8E9F83", +"t5 c #BDBEB9", +"u5 c #446A32", +"v5 c #073400", +"w5 c #2E2C06", +"x5 c #1E3013", +"y5 c #7C8479", +"z5 c #C9D9C4", +"A5 c #A8B5A2", +"B5 c #585F56", +"C5 c #292C28", +"D5 c #7D887A", +"E5 c #949F90", +"F5 c #0C0C0B", +"G5 c #5B6158", +"H5 c #587C44", +"I5 c #6C8A5B", +"J5 c #7C956B", +"K5 c #678654", +"L5 c #326120", +"M5 c #4A7236", +"N5 c #8FA183", +"O5 c #C1BEC1", +"P5 c #BABAB7", +"Q5 c #B3B8AE", +"R5 c #C1BFBD", +"S5 c #8B9F7F", +"T5 c #2F5F1B", +"U5 c #134303", +"V5 c #154705", +"W5 c #5B7F45", +"X5 c #B8BAB4", +"Y5 c #B6B7B4", +"Z5 c #B0B6AA", +"`5 c #476F34", +" 6 c #0D3F00", +".6 c #3C672A", +"+6 c #B4B7B0", +"@6 c #0E3102", +"#6 c #472605", +"$6 c #424042", +"%6 c #324F1F", +"&6 c #11190B", +"*6 c #6F7F69", +"=6 c #96A291", +"-6 c #A3B09F", +";6 c #A9B6A5", +">6 c #BBC9B6", +",6 c #A9B7A4", +"'6 c #636A60", +")6 c #717A6E", +"!6 c #393D37", +"~6 c #8C9888", +"{6 c #060706", +"]6 c #1B4B09", +"^6 c #1E4D0C", +"/6 c #1A4C09", +"(6 c #1B4A0B", +"_6 c #2B5917", +":6 c #769165", +"<6 c #B6B8B1", +"[6 c #C3C0C4", +"}6 c #547741", +"|6 c #759166", +"16 c #BFBFBD", +"26 c #50753E", +"36 c #2B5C16", +"46 c #376820", +"56 c #8CA07F", +"66 c #BBBABA", +"76 c #BDBBBC", +"86 c #819973", +"96 c #204F0D", +"06 c #134401", +"a6 c #6B885B", +"b6 c #C3C2BF", +"c6 c #618051", +"d6 c #0B3A00", +"e6 c #173204", +"f6 c #562305", +"g6 c #1B2B10", +"h6 c #3C3B3C", +"i6 c #4C4C4D", +"j6 c #0D1608", +"k6 c #5C6956", +"l6 c #C1CFBA", +"m6 c #CADBC4", +"n6 c #7F897B", +"o6 c #181A18", +"p6 c #C9DAC3", +"q6 c #474C44", +"r6 c #265713", +"s6 c #7F9870", +"t6 c #BEBDBC", +"u6 c #879C7A", +"v6 c #335F21", +"w6 c #ACB5A5", +"x6 c #B7BBB1", +"y6 c #9CA991", +"z6 c #295C13", +"A6 c #829873", +"B6 c #BABBB6", +"C6 c #A1AD98", +"D6 c #2E5A1E", +"E6 c #144404", +"F6 c #2A5917", +"G6 c #9FA998", +"H6 c #B1B7AB", +"I6 c #305B1F", +"J6 c #243006", +"K6 c #701E04", +"L6 c #090F05", +"M6 c #BFBFC0", +"N6 c #0E1807", +"O6 c #304C1D", +"P6 c #365520", +"Q6 c #3A4435", +"R6 c #9AA595", +"S6 c #A4B1A0", +"T6 c #C2D1BB", +"U6 c #CDDDC6", +"V6 c #C7D8C1", +"W6 c #767E72", +"X6 c #C0D0BB", +"Y6 c #A2AD9C", +"Z6 c #1E201D", +"`6 c #194A0A", +" 7 c #487234", +".7 c #B3B6AE", +"+7 c #B8B8B6", +"@7 c #738E60", +"#7 c #204D0D", +"$7 c #0F3504", +"%7 c #103B02", +"&7 c #2D5919", +"*7 c #638355", +"=7 c #B3B6AD", +"-7 c #ADB3A5", +";7 c #3C6728", +">7 c #2C5B17", +",7 c #698A55", +"'7 c #698B56", +")7 c #275417", +"!7 c #154606", +"~7 c #497039", +"{7 c #BBBDB7", +"]7 c #7D956F", +"^7 c #103F02", +"/7 c #0F3304", +"(7 c #C9D2C3", +"_7 c #2E2E2F", +":7 c #172210", +"<7 c #2F4B1C", +"[7 c #3D4738", +"}7 c #7A8277", +"|7 c #B0BEAA", +"17 c #5C6259", +"27 c #818B7E", +"37 c #547A42", +"47 c #95A589", +"57 c #20500D", +"67 c #0C3200", +"77 c #093700", +"87 c #557A44", +"97 c #78916A", +"07 c #225210", +"a7 c #194B08", +"b7 c #7E9472", +"c7 c #C0C0BC", +"d7 c #4D713B", +"e7 c #083500", +"f7 c #1F3005", +"g7 c #263C17", +"h7 c #6C6B6C", +"i7 c #495542", +"j7 c #2E4C1C", +"k7 c #525F4D", +"l7 c #ACB8A6", +"m7 c #CAD8C3", +"n7 c #B9C6B2", +"o7 c #BFCFB9", +"p7 c #BDCCB8", +"q7 c #4E534B", +"r7 c #0E0F0D", +"s7 c #7C8679", +"t7 c #194909", +"u7 c #456F32", +"v7 c #B4B7AF", +"w7 c #A5B09F", +"x7 c #366123", +"y7 c #083300", +"z7 c #0E3403", +"A7 c #133906", +"B7 c #466B36", +"C7 c #79926B", +"D7 c #1A4B0A", +"E7 c #1D4B0F", +"F7 c #325F20", +"G7 c #A5AD9D", +"H7 c #ADB5A7", +"I7 c #366126", +"J7 c #432705", +"K7 c #243915", +"L7 c #2E322B", +"M7 c #A09FA0", +"N7 c #E1E1E0", +"O7 c #8B9883", +"P7 c #3A5726", +"Q7 c #6A7763", +"R7 c #869282", +"S7 c #A5B1A0", +"T7 c #CBDBC4", +"U7 c #CFE0C9", +"V7 c #828C7E", +"W7 c #646B61", +"X7 c #474D45", +"Y7 c #1D1F1B", +"Z7 c #050605", +"`7 c #98A595", +" 8 c #363A34", +".8 c #245410", +"+8 c #899C7B", +"@8 c #C6C1C7", +"#8 c #426A2E", +"$8 c #204D0E", +"%8 c #164105", +"&8 c #0D3500", +"*8 c #0D3301", +"=8 c #093200", +"-8 c #567748", +";8 c #C4C2C2", +">8 c #7C946D", +",8 c #164903", +"'8 c #174608", +")8 c #B7BAB3", +"!8 c #9AA992", +"~8 c #244D12", +"{8 c #3C2201", +"]8 c #C9D2C4", +"^8 c #233614", +"/8 c #5C605A", +"(8 c #DDDCDD", +"_8 c #E8E9E8", +":8 c #E0E1E0", +"<8 c #98A58E", +"[8 c #869084", +"}8 c #AAB8A6", +"|8 c #C4D4BF", +"18 c #A6B3A0", +"28 c #70786D", +"38 c #818C7D", +"48 c #396425", +"58 c #98A78D", +"68 c #C3C0C3", +"78 c #B3B7AF", +"88 c #7F9670", +"98 c #648451", +"08 c #4C7238", +"a8 c #376226", +"b8 c #275216", +"c8 c #0D3C00", +"d8 c #345E23", +"e8 c #AFB4AB", +"f8 c #B2B6B1", +"g8 c #748F65", +"h8 c #3F692C", +"i8 c #1D4D0E", +"j8 c #70845B", +"k8 c #472400", +"l8 c #3E5230", +"m8 c #91948F", +"n8 c #DEDFDD", +"o8 c #8F9D84", +"p8 c #3D5B28", +"q8 c #7B8379", +"r8 c #B3C0AE", +"s8 c #B0BFAB", +"t8 c #444942", +"u8 c #323630", +"v8 c #B1BDAB", +"w8 c #2E312D", +"x8 c #34611F", +"y8 c #728E63", +"z8 c #95A58C", +"A8 c #BABBB7", +"B8 c #B2B7AD", +"C8 c #A3AE9B", +"D8 c #6F8C5F", +"E8 c #305F1C", +"F8 c #4E7838", +"G8 c #91A484", +"H8 c #BEBEBD", +"I8 c #9CAA91", +"J8 c #2D5C1B", +"K8 c #1A4A0C", +"L8 c #255413", +"M8 c #94A78F", +"N8 c #B1AB9C", +"O8 c #743C13", +"P8 c #831600", +"Q8 c #C7CFC1", +"R8 c #41602C", +"S8 c #819276", +"T8 c #D8DAD6", +"U8 c #DBDDDA", +"V8 c #89997F", +"W8 c #3B5926", +"X8 c #A3B09E", +"Y8 c #434841", +"Z8 c #295914", +"`8 c #3B6827", +" 9 c #4C7239", +".9 c #5D814D", +"+9 c #738E62", +"@9 c #849976", +"#9 c #A9B0A3", +"$9 c #799568", +"%9 c #899F7A", +"&9 c #174707", +"*9 c #47723B", +"=9 c #AEAA91", +"-9 c #9A4E2A", +";9 c #881600", +">9 c #5F784D", +",9 c #B7BFB2", +"'9 c #E7E6E6", +")9 c #D9DAD7", +"!9 c #88987D", +"~9 c #64715E", +"{9 c #828A7F", +"]9 c #ADBBA9", +"^9 c #41463F", +"/9 c #174607", +"(9 c #1A4A08", +"_9 c #1C4C0B", +":9 c #1E4E0B", +"<9 c #376324", +"[9 c #6E8D5E", +"}9 c #90A185", +"|9 c #9BA993", +"19 c #A2AE98", +"29 c #5D804A", +"39 c #205312", +"49 c #79834B", +"59 c #A44F2B", +"69 c #8C1700", +"79 c #C8D1C2", +"89 c #788F69", +"99 c #D1D5CE", +"09 c #E9E7E9", +"a9 c #D7D9D4", +"b9 c #839376", +"c9 c #677561", +"d9 c #838C80", +"e9 c #859082", +"f9 c #C6D6BF", +"g9 c #CCDCC5", +"h9 c #ADBBA7", +"i9 c #A6B2A0", +"j9 c #1D4A0E", +"k9 c #22520F", +"l9 c #386524", +"m9 c #356321", +"n9 c #1D4D0D", +"o9 c #194D0E", +"p9 c #4A5B1D", +"q9 c #99421B", +"r9 c #8D1902", +"s9 c #C8D0C3", +"t9 c #6B815C", +"u9 c #C3C8C0", +"v9 c #D5D7D2", +"w9 c #829475", +"x9 c #3D5C27", +"y9 c #889285", +"z9 c #A1AE9C", +"A9 c #B7C6B3", +"B9 c #343933", +"C9 c #1C490D", +"D9 c #1A480B", +"E9 c #1B4F11", +"F9 c #465419", +"G9 c #953A15", +"H9 c #C6CEC1", +"I9 c #3A4F2C", +"J9 c #888C85", +"K9 c #E0E0E1", +"L9 c #CFD3CD", +"M9 c #707E6A", +"N9 c #95A291", +"O9 c #929E8E", +"P9 c #5B6258", +"Q9 c #697266", +"R9 c #D2E1CB", +"S9 c #C3D4BE", +"T9 c #ABB8A6", +"U9 c #194A09", +"V9 c #235410", +"W9 c #396726", +"X9 c #466F33", +"Y9 c #396526", +"Z9 c #2D5C1A", +"`9 c #20500C", +" 0 c #1C4F11", +".0 c #485219", +"+0 c #943714", +"@0 c #8E1902", +"#0 c #C6CEC0", +"$0 c #637755", +"%0 c #BABCB8", +"&0 c #E6E5E6", +"*0 c #D0D4CD", +"=0 c #6E835F", +"-0 c #80897E", +";0 c #A9B5A3", +">0 c #70796C", +",0 c #202320", +"'0 c #939F8E", +")0 c #2C5D18", +"!0 c #4D7738", +"~0 c #819A73", +"{0 c #B5B9B0", +"]0 c #ABB4A4", +"^0 c #809873", +"/0 c #5B7D49", +"(0 c #474E17", +"_0 c #923412", +":0 c #678155", +"<0 c #C1C8BC", +"[0 c #E7E7E9", +"}0 c #BBBFB8", +"|0 c #596D4A", +"10 c #B4C3B0", +"20 c #6B7367", +"30 c #343833", +"40 c #262825", +"50 c #2D5B1B", +"60 c #738E63", +"70 c #728E60", +"80 c #C2BFC2", +"90 c #92A485", +"00 c #8EA083", +"a0 c #A3AE9C", +"b0 c #8C9F7F", +"c0 c #305D1D", +"d0 c #1D4F12", +"e0 c #454813", +"f0 c #8E2E0E", +"g0 c #8D1904", +"h0 c #C7D0C1", +"i0 c #40612A", +"j0 c #7A8E6C", +"k0 c #CDD1CA", +"l0 c #C2C2C3", +"m0 c #7E827C", +"n0 c #475C3A", +"o0 c #ACBAA8", +"p0 c #232522", +"q0 c #3C413B", +"r0 c #3C6828", +"s0 c #93A488", +"t0 c #BFBDBD", +"u0 c #C1C0C0", +"v0 c #BEBDBA", +"w0 c #BABAB6", +"x0 c #80996F", +"y0 c #426B2F", +"z0 c #1F4B0D", +"A0 c #1A480A", +"B0 c #265614", +"C0 c #386722", +"D0 c #7E966F", +"E0 c #C3BFC1", +"F0 c #7C946E", +"G0 c #1D4F11", +"H0 c #3E400F", +"I0 c #8B280B", +"J0 c #395B22", +"K0 c #466331", +"L0 c #9AA791", +"M0 c #E1E2E2", +"N0 c #C1C0C1", +"O0 c #717271", +"P0 c #485141", +"Q0 c #4D643C", +"R0 c #889185", +"S0 c #BDCDB9", +"T0 c #60685C", +"U0 c #899384", +"V0 c #A8B5A4", +"W0 c #C2D1BD", +"X0 c #305E1C", +"Y0 c #95A58A", +"Z0 c #C4BFC5", +"`0 c #ADB3A7", +" a c #789369", +".a c #567A46", +"+a c #497138", +"@a c #3B6529", +"#a c #1A470A", +"$a c #305B1E", +"%a c #668456", +"&a c #899B7C", +"*a c #A3AE9A", +"=a c #184B0D", +"-a c #4E4712", +";a c #932A0D", +">a c #8E1803", +",a c #3B5D24", +"'a c #7F9172", +")a c #565556", +"!a c #1F211D", +"~a c #293A1D", +"{a c #3E5C28", +"]a c #8B9488", +"^a c #B4C3AE", +"/a c #373B36", +"(a c #656D61", +"_a c #CCDDC6", +":a c #B6C3B1", +"b c #8F8E90", +",b c #363836", +"'b c #323E29", +")b c #385028", +"!b c #3D582B", +"~b c #395624", +"{b c #395A24", +"]b c #292C27", +"^b c #30332E", +"/b c #0C0D0B", +"(b c #4F554C", +"_b c #636A5F", +":b c #4E544C", +"c c #839A70", +",c c #B9BAB9", +"'c c #A6B1A0", +")c c #68682D", +"!c c #7A2200", +"~c c #8A1803", +"{c c #405D2C", +"]c c #76846C", +"^c c #CACBCB", +"/c c #EBEBEC", +"(c c #0E0E0F", +"_c c #E6E7E7", +":c c #E5E6E6", +"d c #839A72", +",d c #61844A", +"'d c #718C62", +")d c #778F6B", +"!d c #638056", +"~d c #50743D", +"{d c #3B6528", +"]d c #5A7F47", +"^d c #B4B7B1", +"/d c #46772D", +"(d c #678C4F", +"_d c #B3B8B2", +":d c #BCBFBA", +"e c #EBEBEA", +",e c #C1C1C0", +"'e c #40403F", +")e c #676668", +"!e c #101D07", +"~e c #0D1409", +"{e c #5D635A", +"]e c #7C8578", +"^e c #BBCBB6", +"/e c #8E9A89", +"(e c #61685D", +"_e c #596157", +":e c #5B635A", +"f c #B2BDB6", +",f c #9F9B83", +"'f c #6A320A", +")f c #841500", +"!f c #5D754B", +"~f c #ACB2A7", +"{f c #D5D6D4", +"]f c #878584", +"^f c #12100E", +"/f c #191411", +"(f c #120D0A", +"_f c #211E1A", +":f c #181511", +"g c #818F78", +",g c #D7D9D6", +"'g c #E6E3E0", +")g c #E7E2E0", +"!g c #E4DEDA", +"~g c #BBB5B0", +"{g c #928B85", +"]g c #AAA29C", +"^g c #C7BFB8", +"/g c #756D65", +"(g c #292019", +"_g c #120800", +":g c #110700", +"h c #889D7C", +",h c #1F5208", +"'h c #114101", +")h c #355E22", +"!h c #93A388", +"~h c #608250", +"{h c #235212", +"]h c #8FA280", +"^h c #967A5C", +"/h c #6E1E00", +"(h c #2C461B", +"_h c #040B00", +":h c #A1A0A0", +"i c #E7DDD4", +",i c #1A2513", +"'i c #C5D3C0", +")i c #656C61", +"!i c #2B5A19", +"~i c #9CA994", +"{i c #B5B8B1", +"]i c #497036", +"^i c #063600", +"/i c #002D00", +"(i c #1D5008", +"_i c #9BAA8F", +":i c #2A5818", +"j c #DFE0DF", +",j c #EAE9EB", +"'j c #C2C2C1", +")j c #969594", +"!j c #A6A4A2", +"~j c #D4D1CF", +"{j c #E4E0DD", +"]j c #E7E0DB", +"^j c #E7DDD7", +"/j c #E8D7C9", +"(j c #E9D4C5", +"_j c #E9D2C0", +":j c #ECD2BE", +"k c #345320", +",k c #CDDBC5", +"'k c #D3E2CB", +")k c #6C7469", +"!k c #5F675C", +"~k c #666F63", +"{k c #40453F", +"]k c #030302", +"^k c #20500E", +"/k c #708D5F", +"(k c #849B77", +"_k c #8A9F7D", +":k c #51763E", +"l c #E3D7CD", +",l c #E4D4C8", +"'l c #ECD8C9", +")l c #ECD4C1", +"!l c #E3C6B0", +"~l c #A5856B", +"{l c #785437", +"]l c #684122", +"^l c #512706", +"/l c #4F2401", +"(l c #643611", +"_l c #AC7D58", +":l c #EDBD97", +"m c #4B514A", +",m c #757E72", +"'m c #2C5B19", +")m c #477234", +"!m c #577D45", +"~m c #718C61", +"{m c #597D46", +"]m c #2D5D1A", +"^m c #527A3E", +"/m c #7A946D", +"(m c #3F6A2C", +"_m c #1E500A", +":m c #275813", +"n c #EFB88D", +",n c #EFB88C", +"'n c #EFB98E", +")n c #EFBA8F", +"!n c #EFBB91", +"~n c #EEBC93", +"{n c #EEBE96", +"]n c #EDC3A1", +"^n c #ECC6A8", +"/n c #EBCAAF", +"(n c #EACEB7", +"_n c #020500", +":n c #233615", +"o c #662004", +",o c #657957", +"'o c #CACCC6", +")o c #E8E5E5", +"!o c #E6DED7", +"~o c #E7DCD2", +"{o c #E8D8CB", +"]o c #EDD3BE", +"^o c #E3C3AA", +"/o c #977155", +"(o c #572D0E", +"_o c #562905", +":o c #572600", +"p c #1E4D0D", +",p c #4D743A", +"'p c #829A74", +")p c #94A488", +"!p c #BBBDB8", +"~p c #B4B9AE", +"{p c #A3AF9A", +"]p c #567A45", +"^p c #42692F", +"/p c #A7AE9F", +"(p c #134503", +"_p c #758E68", +":p c #A8B2A0", +"

Q c #18450A", +",Q c #315F1D", +"'Q c #446E30", +")Q c #BDBCBD", +"!Q c #0F3D00", +"~Q c #3E642B", +"{Q c #BABCB7", +"]Q c #5A7D49", +"^Q c #BDBDBC", +"/Q c #4F7639", +"(Q c #184508", +"_Q c #103E00", +":Q c #809773", +"R c #5F804E", +",R c #375F27", +"'R c #113706", +")R c #771D04", +"!R c #FAFAF9", +"~R c #EEF0EC", +"{R c #DDE2DB", +"]R c #C0CABA", +"^R c #ACB9A4", +"/R c #8E9F81", +"(R c #7A8F6B", +"_R c #657D54", +":R c #4B6938", +"S c #A9B0A5", +",S c #4B7139", +"'S c #0E4200", +")S c #376424", +"!S c #93A489", +"~S c #134501", +"{S c #1E5209", +"]S c #769164", +"^S c #C5C2C5", +"/S c #6A885D", +"(S c #0A3700", +"_S c #163606", +":S c #5F2205", +"T c #8E9989", +",T c #0B1824", +"'T c #3A404C", +")T c #504427", +"!T c #888A8B", +"~T c #838D81", +"{T c #4B6F3B", +"]T c #1C4C0E", +"^T c #1D4D10", +"/T c #1F4F11", +"(T c #1C4D10", +"_T c #1A4B0D", +":T c #124301", +"U c #62300B", +",U c #422504", +"'U c #DFE3DC", +")U c #CCD3C7", +"!U c #B6C1AE", +"~U c #778D68", +"{U c #678056", +"]U c #567143", +"^U c #3A5C24", +"/U c #1A2A0E", +"(U c #111410", +"_U c #B1B2B2", +":U c #010400", +"V c #8B2108", +",V c #901B05", +"'V c #941E06", +")V c #952308", +"!V c #922B0A", +"~V c #85300C", +"{V c #682C08", +"]V c #6C4219", +"^V c #9C8969", +"/V c #BBBCB1", +"(V c #8EA687", +"_V c #467038", +":V c #2F6019", +"W c #203213", +",W c #395822", +"'W c #641302", +")W c #7E1904", +"!W c #891701", +"~W c #821600", +"{W c #892201", +"]W c #91633E", +"^W c #ACB1A1", +"/W c #BDBFBE", +"(W c #ABB3A3", +"_W c #96A68D", +":W c #254F14", +"X c #811D01", +",X c #8D3712", +"'X c #9A512A", +")X c #AC7050", +"!X c #A85A37", +"~X c #912307", +"{X c #EDEFEC", +"]X c #D4DAD0", +"^X c #C1CABA", +"/X c #B0BDA8", +"(X c #819574", +"_X c #637C52", +":X c #4C6A39", +"Y c #0C141C", +",Y c #070C11", +"'Y c #040709", +")Y c #0F1A24", +"!Y c #6C859B", +"~Y c #B0B1B6", +"{Y c #B6BAC1", +"]Y c #BCC2C9", +"^Y c #B5BCC1", +"/Y c #A3A5AD", +"(Y c #8C818C", +"_Y c #7A6C73", +":Y c #775955", +"Z c #817379", +",Z c #76585E", +"'Z c #653F3D", +")Z c #672F25", +"!Z c #6E1D12", +"~Z c #7B1F10", +"{Z c #7E1F0B", +"]Z c #871D06", +"^Z c #951C03", +"/Z c #961C03", +"(Z c #941C02", +"_Z c #931B02", +":Z c #921B01", +"` c #E1E4DE", +",` c #FAFEFF", +"'` c #E5EEF6", +")` c #CAD8E6", +"!` c #BCCEDE", +"~` c #A1B9CF", +"{` c #86A0B6", +"]` c #687F94", +"^` c #435A70", +"/` c #284055", +"(` c #1D3246", +"_` c #0F1A23", +":` c #060B0F", +"<` c #728AA0", +"[` c #F7F9FF", +"}` c #E2E7EF", +"|` c #D0D7DF", +"1` c #BBC4CB", +"2` c #A9ABB4", +"3` c #908792", +"4` c #796C6F", +"5` c #715452", +"6` c #6C3E3C", +"7` c #6A2A23", +"8` c #651E10", +"9` c #731D0B", +"0` c #861D08", +"a` c #8F1D07", +"b` c #921C03", +"c` c #921B02", +"d` c #6F1A09", +"e` c #484649", +"f` c #F0F7FF", +"g` c #E0ECF7", +"h` c #CDDDEA", +"i` c #98ADC0", +"j` c #738EA7", +"k` c #55728C", +"l` c #40576E", +"m` c #26394A", +"n` c #192A3B", +"o` c #13222F", +"p` c #080E13", +"q` c #010203", +"r` c #7A92A8", +"s` c #F1F3F9", +"t` c #E0E4ED", +"u` c #CDD4DB", +"v` c #B5BCC0", +"w` c #9D9DA5", +"x` c #867B85", +"y` c #746267", +"z` c #6C4E4A", +"A` c #6A3A34", +"B` c #6E2620", +"C` c #6E1F12", +"D` c #7A1E09", +"E` c #8A1D06", +"F` c #931D06", +"G` c #921D04", +"H` c #941B00", +"I` c #941A01", +"J` c #701B09", +"K` c #555458", +"L` c #EAF1F8", +"M` c #D2DFEC", +"N` c #C7D8E7", +"O` c #ABC2D6", +"P` c #91A8BD", +"Q` c #6F869C", +"R` c #4C647B", +"S` c #2F495F", +"T` c #20364A", +"U` c #172837", +"V` c #101C26", +"W` c #04080B", +"X` c #020305", +"Y` c #0C161E", +"Z` c #849CB2", +"`` c #EFF1F6", +" . c #D9DEE8", +". . c #BCC6D1", +"+ . c #A8AFB5", +"@ . c #928F96", +"# . c #7C6C75", +"$ . c #735A5E", +"% . c #664541", +"& . c #6A332A", +"* . c #701D14", +"= . c #781F10", +"- . c #7E1E08", +"; . c #881D05", +"> . c #931B01", +", . c #971B02", +"' . c #741C0A", +") . c #696A70", +"! . c #FEFFFF", +"~ . c #F5FCFF", +"{ . c #E8F2FA", +"] . c #D4E2EE", +"^ . c #BCCCDB", +"/ . c #A1B5C8", +"( . c #7B96AF", +"_ . c #617D96", +": . c #485F75", +"< . c #283C4E", +"[ . c #192D3D", +"} . c #89A3BB", +"| . c #F6F8FC", +"1 . c #E6EAEF", +"2 . c #CCD2DD", +"3 . c #B0B7C4", +"4 . c #9CA1A7", +"5 . c #8A8488", +"6 . c #78666D", +"7 . c #735157", +"8 . c #673F3B", +"9 . c #692E21", +"0 . c #711E10", +"a . c #7E1F0F", +"b . c #871E07", +"c . c #6F1F0F", +"d . c #7A7B86", +"e . c #EDF4FA", +"f . c #D8E5F1", +"g . c #CADAE9", +"h . c #ACC1D3", +"i . c #91AAC2", +"j . c #BBCBDB", +"k . c #FAFBFF", +"l . c #F1F4FA", +"m . c #E0E5E9", +"n . c #C5CCD5", +"o . c #A9ACB9", +"p . c #92929B", +"q . c #837C7E", +"r . c #6C6068", +"s . c #A0A4B0", +"t . c #F8F9FE", +"u . c #F7F8FA", +"v . c #E7EBE4", +"w . c #687F58", +"x . c #587245", +"y . c #ABB7A2", +"z . c #FBFBFA", +"A . c #FBFBF9", +"B . c #637B52", +"C . c #3B5A26", +"D . c #CBD4C6", +"E . c #879A7A", +"F . c #526D40", +"G . c #EBEEE9", +"H . c #E7EBE5", +"I . c #BAC4B2", +"J . c #768B67", +"K . c #F9FAF9", +"L . c #647D54", +"M . c #456232", +"N . c #E1E6DE", +"O . c #3C5B28", +"P . c #A3B29A", +"Q . c #869979", +"R . c #667E56", +"S . c #F8F9F7", +"T . c #E9ECE6", +"U . c #486535", +"V . c #3A5926", +"W . c #D0D8CB", +"X . c #A7B59E", +"Y . c #FAFBF9", +"Z . c #647C53", +"` . c #F2F4F0", +" .. c #BCC6B5", +"... c #87997A", +"+.. c #7D9170", +"@.. c #476434", +"#.. c #446131", +"$.. c #A7B59D", +"%.. c #F7F8F6", +"&.. c #567145", +"*.. c #677E56", +"=.. c #FCFDFB", +"-.. c #3E5C2A", +";.. c #CFD6CB", +">.. c #425F2D", +",.. c #D3DBCF", +"'.. c #859878", +").. c #60784F", +"!.. c #C2CBBC", +"~.. c #E8ECE6", +"{.. c #4A6637", +"].. c #516C3E", +"^.. c #546F43", +"/.. c #A5B29B", +"(.. c #D7DED3", +"_.. c #7C916E", +":.. c #C1CAB9", +"<.. c #637B53", +"[.. c #B7C3B0", +"}.. c #7E916F", +"|.. c #7F9371", +"1.. c #DDE2D9", +"2.. c #7C906E", +"3.. c #AFBCA7", +"4.. c #B5C0AC", +"5.. c #6C835D", +"6.. c #A4B39B", +"7.. c #E2E7DF", +"8.. c #D8DED4", +"9.. c #F6F8F5", +"0.. c #607950", +"a.. c #E4E9E2", +"b.. c #738964", +"c.. c #C8D0C2", +"d.. c #798E6C", +"e.. c #FDFEFD", +"f.. c #ADBBA5", +"g.. c #5B754B", +"h.. c #F3F5F1", +"i.. c #809473", +"j.. c #B4BFAC", +"k.. c #405E2D", +"l.. c #4A6638", +"m.. c #EDF0EB", +"n.. c #FCFDFC", +"o.. c #728964", +"p.. c #849878", +"q.. c #A5B39B", +"r.. c #819473", +"s.. c #A8B59E", +"t.. c #4D683A", +"u.. c #ECEFE9", +"v.. c #F9FAF8", +"w.. c #617950", +"x.. c #C0CAB9", +"y.. c #DAE0D6", +"z.. c #446231", +"A.. c #556F43", +"B.. c #FEFEFD", +"C.. c #69805A", +"D.. c #879A7B", +"E.. c #405F2C", +"F.. c #DCE1D8", +"G.. c #4B6638", +"H.. c #C7D0C0", +"I.. c #DADFD5", +"J.. c #9CAB92", +"K.. c #A6B49D", +"L.. c #597247", +"M.. c #688059", +"N.. c #5F784E", +"O.. c #9AAA90", +"P.. c #CED5C8", +"Q.. c #D4DBD0", +"R.. c #3F5D2B", +"S.. c #819674", +"T.. c #4E693B", +"U.. c #496535", +"V.. c #9BAB91", +"W.. c #98A88E", +"X.. c #D8DED5", +"Y.. c #D0D7CB", +"Z.. c #738965", +"`.. c #FBFCFB", +" +. c #F3F5F2", +".+. c #5F774E", +"++. c #C5CEBE", +"@+. c #B0BCA7", +"#+. c #829474", +"$+. c #9BAB90", +"%+. c #BBC6B4", +"&+. c #B7C2B0", +"*+. c #BCC7B5", +"=+. c #627A51", +"-+. c #3A5825", +";+. c #CDD5C8", +">+. c #8A9D7F", +",+. c #C5CEC0", +"'+. c #BDC8B7", +")+. c #829675", +"!+. c #798E6B", +"~+. c #E5E9E2", +"{+. c #415F2E", +"]+. c #456231", +"^+. c #E4E8E0", +"/+. c #F6F8F6", +"(+. c #607A50", +"_+. c #D0D7CA", +":+. c #CAD2C5", +"<+. c #C4CEBE", +"[+. c #587147", +"}+. c #D2D9CD", +"|+. c #91A285", +"1+. c #E6EAE3", +"2+. c #D5DBD0", +"3+. c #577145", +"4+. c #A1AF96", +"5+. c #587246", +"6+. c #BDC8B6", +"7+. c #617A51", +"8+. c #3B5D26", +"9+. c #8C9E7F", +"0+. c #809372", +"a+. c #3B5B27", +"b+. c #E5EAE3", +"c+. c #FDFDFC", +"d+. c #F3F4F1", +"e+. c #526C40", +"f+. c #ACB9A3", +"g+. c #AAB8A1", +"h+. c #869879", +"i+. c #6B825C", +"j+. c #A3B299", +"k+. c #C5CDBE", +"l+. c #D4DACF", +"m+. c #7C906D", +"n+. c #EBEFE9", +"o+. c #516C3F", +"p+. c #839677", +"q+. c #F3F6F2", +"r+. c #B2BFAA", +"s+. c #B3BFAC", +"t+. c #B9C5B3", +"u+. c #F1F3EF", +"v+. c #B4C0AC", +"w+. c #B5C1AD", +"x+. c #B5C1AE", +"y+. c #F0F3EF", +"z+. c #EBDED6", +"A+. c #DECBBE", +"B+. c #DFCDC0", +"C+. c #DFCCBF", +"D+. c #E1D0C4", +"E+. c #FBF9F7", +"F+. c #AF8061", +"G+. c #8A400E", +"H+. c #843D0D", +"I+. c #873F0D", +"J+. c #8D4A1D", +"K+. c #F0E8E2", +"L+. c #AD7E5E", +"M+. c #8C400D", +"N+. c #863D0C", +"O+. c #893F0C", +"P+. c #8C4719", +"Q+. c #AE7F60", +"R+. c #8A3F0D", +"S+. c #873E0C", +"T+. c #8D491C", +"U+. c #883E0C", +"V+. c #8C471A", +"W+. c #893E0C", +"X+. c #8C400C", +"Y+. c #894213", +"Z+. c #F0E7E1", +"`+. c #8B471A", +" @. c #BE977D", +".@. c #C5A38C", +"+@. c #C4A28B", +"@@. c #C39F88", +"#@. c #C8A892", +"$@. c #F8F4F1", +"%@. c #94552B", +"&@. c #F9F5F2", +"*@. c #935329", +"=@. c #F2EAE5", +"-@. c #94542A", +";@. c #F6EFEC", +">@. c #925127", +",@. c #EADDD5", +"'@. c #F6F1ED", +")@. c #F4EEEA", +"!@. c #F7F3F1", +"~@. c #863F0F", +"{@. c #95562C", +"]@. c #985B32", +"^@. c #965930", +"/@. c #98572C", +"(@. c #B18365", +"_@. c #FDFCFB", +":@. c #8F410D", +"<@. c #A16A44", +"[@. c #FCFBFA", +"}@. c #8B3F0D", +"|@. c #A46E4A", +"1@. c #8C3F0D", +"2@. c #A46D49", +"3@. c #90410E", +"4@. c #A06843", +"5@. c #8C481B", +"6@. c #C09A82", +"7@. c #C7A690", +"8@. c #C6A58F", +"9@. c #C4A18A", +"0@. c #D5BCAC", +"a@. c #F9F6F3", +"b@. c #F4EDE9", +"c@. c #925228", +"d@. c #EFE5DF", +"e@. c #FBFAF8", +"f@. c #FCFAF8", +"g@. c #874011", +"h@. c #9C623B", +"i@. c #A06842", +"j@. c #9F6741", +"k@. c #9F643D", +"l@. c #C29F88", +"m@. c #8F410E", +"n@. c #B18466", +"o@. c #AB7A5A", +"p@. c #B88F73", +"q@. c #965327", +"r@. c #925329", +"s@. c #BA9378", +"t@. c #F3EDE8", +"u@. c #ECE2DB", +"v@. c #EEE3DD", +"w@. c #F5EEEA", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ # # # $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ $ # $ $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + $ % & * = * - ; % > # $ $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ > - & & & , ; % > # $ @ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ @ $ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ ; ' ) ! ~ ! { ] ^ / ' * & , ; % # # $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ % = ( { _ : < ( [ / ' & - , ; > > $ $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ > , - & , ; > # $ $ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + $ , < } | 1 2 3 4 5 6 7 ! : < ( 8 / ' * & , ; % # $ $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ , ( 9 0 a | b c d 9 e ! { ) ^ [ f * & - ; % > # # $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + % ' ) ~ g ! { ^ [ f * - , % # # $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + # = ] 6 h i j j k l m n o a b p d 9 e ~ { ] ^ [ f = & - ; ; # # $ @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . & 6 q r s t i u v h 1 | 0 5 w x g _ < ( 8 / ' * & , ; > # # $ $ @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + # ^ c y u m y z b c 6 e _ < ^ f ' & , % > # # $ @ + + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A B C D E F G H I J K L j t k M l v h 1 | 0 5 w x g _ { ] ^ / ' = & , % % > # $ $ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . } N O P Q R I S I K T U L j r M V n W 2 3 p } 6 e ! : ) ( [ f = * - ; ; % > # $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . + X { | t Y Z Z ` . J s i V h a 0 5 x ~ : ] [ f = & , % % # $ @ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. +. @. #. $. %. &. *. =. -. ;. >. ,. G ` '. s L L L j k ). V y W 1 3 p } 6 7 ~ : ) ] 8 / ' * - , % > # # $ @ @ + + + + . . . . . . . . . . . . . . . . K !. !. ~. {. ]. ^. /. (. _. :. <. [. Y K T T T }. L j i l m q z | b p d 9 e ! { ] ^ [ ' = - - ; % > # # $ @ + + + . + . . . . . . . . . . . . . . . . |. 1. 2. 3. 4. 5. 6. 7. 8. 9. 0. a. [. b. Z ` S }. j l v o 3 p w 7 ! < ( [ = * - ; > > # $ @ @ + + . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. g. #. #. d. g. h. $. i. j. k. l. m. n. o. p. ` H S }. L s t t i l m q o a b p w x g ! { ] ^ / ' = & , ; % > # $ $ @ @ + + + . . . . . . . . . . s q. !. !. !. !. !. !. !. !. r. s. t. u. v. w. x. y. z. ` R S J T L L j t i u v h 1 | 4 5 6 7 g _ < ( 8 / ' = - , ; % # # $ @ @ @ + + + . . . . . . . . . . A. B. C. D. E. F. G. H. I. J. K. L. M. N. O. :. P. Q. a. [. b. R. R '. U k u q 1 b 5 6 e _ ] ^ / = & - ; > # $ $ @ @ + @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. S. T. U. g. d. V. W. g. $. X. Y. Z. `. + .+ ++ @+ #+ ` K U U U U s r ). V y h 1 | 0 5 w 7 ~ : < ] 8 / ' = & - ; > > # $ @ @ @ + + . . . . s $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. $+ %+ &+ *+ =+ -+ ;+ >+ 9. Q ` J }. }. }. }. U j i ). V n W 2 b c d 9 7 ~ : ) ( [ f = & - , % > > # $ @ @ @ + + + . . . ,+ '+ )+ !+ ~+ {+ ]+ ^+ ^+ /+ {+ (+ _+ :+ <+ [+ }+ |+ 1+ 2+ 3+ 4+ 9. 0. P 5+ 6+ 7+ ` . J s M m W a 4 d x ~ { ( [ f = - , % > $ $ $ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. f. g. 8+ d. 8+ g. g. e. 9+ 0+ a+ b+ c+ d+ ++ e+ f+ ` g+ K s j j j r M V n W 2 b p } 6 7 ~ : ) ^ [ / = * - , % % # $ $ @ . L $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ i+ ]. j+ k+ l+ m+ n+ o+ 7+ ` g+ J U L L L j i l v q o a b c w x g _ { ] ^ [ f * - , ; % > # $ $ $ . p+ '+ )+ q+ q+ q+ q+ r+ q+ !+ s+ t+ /+ u+ ^+ ]+ v+ r+ w+ x+ y+ z+ A+ B+ C+ D+ E+ F+ G+ H+ O I+ o+ b. R. R I T t l n o 3 p w e _ ) ^ / ' * , , % > $ @ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. f. d. V. V. g. J+ K+ i. L+ M+ N+ O+ P+ Q+ R+ R. J }. T U L j r M l m q o a 0 c d 9 g _ { ] ^ [ f = & , . }. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ S+ T+ U+ V+ W+ w. X+ y. Y+ R. '. K K }. }. U j r M V y W 1 3 4 5 w 7 ~ : < ( 8 f = * - , . Z+ `+ v+ @ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ q+ ~+ t+ v+ {+ u+ .@ ]+ v+ +@ @@ #@ $@ %@ &@ *@ =@ -@ ;@ >@ 8. P. Y+ Q [. 7+ R. . '. s i V q 2 0 } 9 ~ : ) 8 ' = & ; % > # $ $ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. U. f. g. ,@ d. d. #. T. '@ )@ *. !@ ~@ {@ ]@ R+ G f+ . }. s s s j r M V v h 1 3 4 } 6 7 ~ _ ) & H q. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ /@ (@ /. v. _@ 4+ Y+ o+ R. . J U U U U s k ). V n z a 3 p d 6 7 ~ { ] * :@ <@ r+ [@ }@ }@ |@ +@ 1@ 1@ @ @ r+ r+ r+ r+ r+ r+ q+ q+ q+ q+ !+ ~+ t+ v+ /+ D. ^+ ]+ v+ [@ 2@ 3@ 4@ 5@ 6@ 7@ 8@ 9@ 0@ G+ a@ <. a. 5+ z. Z ` S }. s M v W | p d x ! < ( [ ' * - ; > # # $ @ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. f. d. V. V. g. S. b@ 9+ c@ d@ e@ f@ g@ h@ i@ Z I J }. T L j t M l V n o 2 b x o+ q. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. j@ k@ l@ m@ n@ o@ p@ >+ Q. Y I I J K T s j t i l v q z | 0 x q@ r@ s@ t@ u@ v@ s@ w@ x@ [@ [@ }@ }@ |@ |@ @ @ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ q+ q+ ~+ v+ )+ u+ u+ y@ ]+ t+ z@ A@ B@ C@ D@ E@ F@ G@ H@ I@ J@ K@ O I+ [. b. f+ R '. U r u n z b 5 6 e _ ] 8 / = & , ; > # $ @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. T. f. g. g. d. #. V. L@ M@ Y. j. N@ O@ P@ P+ Q@ R@ 7+ H T L s s s t y 9. q. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ S@ T@ *+ U@ V@ w. I@ <. a. 7+ . }. U U T T s r y W@ X@ Y@ Z@ `@ # .# +# @# ## t@ u@ v@ s@ w@ x@ [@ $# }@ |@ |@ 1@ 1@ @ @ r+ r+ r+ r+ r+ r+ q+ q+ q+ q+ !+ !+ ~+ /+ u+ u+ u+ )+ )+ !+ %# &# *# =# -# ;# ># ,# '# N H+ <. P 5+ z. Z ` . J s i m h 2 4 } x ~ { ] [ f = - ; ; > # $ @ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. f. d. #. #. g. f. U. K+ )# !# ~# {# ]# ^# /# 7+ g+ U 4+ q. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ S@ (# _# :# <# [# I@ <. }# H g+ L |# 1# 2# 3# 4# 5# 6# 7# 8# Z@ 9# `@ 0# a# b# ## ## c# v@ d# e# e# [@ [@ $# }@ |@ @ +@ @ @ r+ r+ r+ r+ q+ q+ q+ r+ q+ q+ q+ !+ ~+ t+ /+ u+ ]+ D. {+ f# |@ g# h# i# j# k# l# m# n# o# G+ p# O I+ 5+ q# R. R I }. t ). y z 3 p 6 e _ < ^ / ' * - ; % > # @ @ @ + + . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. U. f. g. #. V. #. e. M@ %. r# s# t# u# v# w# x# h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ~. T+ y# z# W+ w. A# B# C# D# E# F# G# G# F# H# 3# 5# I# 6# J# K# Z@ L# # 0# +# @# ## t@ u@ v@ s@ w@ x@ [@ $# }@ }@ |@ |@ |@ @ @ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ !+ ~+ s+ {+ u+ .@ M# t+ N# O# P# Q# R# S# T# U# V# W# X# Y# P. Y+ Q [. b. R. . '. U k V n 1 b 5 6 g _ ] 8 f = & , % % # # @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. f. ,@ d. d. g. g. f. Z# `# $ .$ +$ @$ #$ $$ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. %$ &$ *$ =$ -$ ;$ >$ ,$ '$ )$ E# !$ F# H# 3# 3# 3# 5# I# 7# 8# ~$ Z@ {$ # .# ]$ ^$ /$ c# v@ d# ($ e# _$ [@ $# }@ }@ +@ +@ @ @ r+ r+ r+ r+ q+ q+ q+ r+ q+ q+ r+ q+ ~+ v+ {+ /+ y@ .@ y@ ~+ [@ :$ <$ [$ 5@ }$ |$ 1$ 2$ 3$ >+ J@ <. Y+ o+ z. Z Y g+ K s M m W | 4 d x ! < ] [ ' * - ; % > # $ @ @ @ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. S. f. g. #. @. V. f. 4$ 5$ 6$ 7$ 8$ 9$ 0$ a$ b$ c$ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. d$ e$ f$ g$ h$ i$ j$ k$ ,$ l$ m$ F# n$ n$ n$ F# 3# 4# o$ 2# 7# p$ Z@ 9# # .# +# b# ## t@ c# v@ d# w@ x@ [@ $# $# }@ |@ |@ |@ @ r+ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ !+ f# v+ /+ )+ D. ]+ ^+ s+ q$ r$ s$ t$ u$ v$ w$ x$ y$ z$ 8. H+ O Q [. b. f+ Y I U r u n z b c w e _ ) ^ / = * , ; % # $ $ @ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. T. T. e. S. f. f. g. A$ B$ C$ D$ E$ F$ G$ H$ I$ J$ K$ L$ b$ M$ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. N$ O$ P$ Q$ R$ S$ j$ T$ U$ V$ W$ X$ F# G# G# G# G# 5# Y$ 7# J# Z$ Z@ L# # 0# ]$ `$ % .% +% d# d# w@ _$ [@ $# }@ }@ |@ 1@ 1@ 1@ @ @ r+ r+ q+ r+ r+ r+ q+ q+ q+ !+ !+ ~+ {+ )+ @% @% D. D. !+ #% $% %% &% *% =% -% ;% >% N 9. P. ,% Q 6+ Z }# H J L i V h 1 0 d x g { ] 8 / = - , % % > @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. '% )% 4$ !% ~% {% ]% U. ^% /% (% _% w# :% 8$ <% +. [% L@ J+ }% G$ |% 1% 2% 0$ 3% 4% 5% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 6% 7% 8% 9% 0% -$ a% b% T$ c% X$ d% e% n$ H# F# 3# 3# 5# Y$ 6# 8# Z$ f% g% 0# .# b# h% ## c# u@ d# s@ x@ x@ [@ $# }@ |@ |@ @ @ r+ r+ r+ r+ r+ r+ q+ q+ q+ q+ q+ q+ q+ !+ f# /+ y@ ]+ D. )+ {+ i% j% h# k% l% m% U# n% o% p% G+ P. 0. Y+ 5+ z. f+ Y S }. r l y W | 4 d x _ ) ( [ ' * - , > > # $ @ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. q% r% s% t% u% v% w% x% y% z% A% B% C% !. !. !. M$ D% E% e. L@ f. f. g. ,@ d. #. #. !% F% G% H% I% J% 0$ K% L% M% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. N% e$ O% P% Q% R% a% S% C# l$ )$ !$ F# G# 3# H# G# 4# o$ 6# J# p$ ~$ g% `@ 0# +# @# ^$ t@ .% v@ d# w@ _$ x@ $# }@ }@ |@ |@ 1@ 1@ @ @ r+ r+ r+ r+ r+ q+ q+ q+ q+ !+ s+ E. T% )+ M# .@ ]+ v+ q+ U% V% W% X% Y% Z% `% & .& +& Y# @& P I+ 6+ 7+ ` H I T r u n 1 b 5 9 g _ ) 8 / = & , ; > # $ $ @ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. '% #& $& %& && *& =& -& ;& >& ,& '& !. !. !. !. !. !. !. h+ )& !& ~& e. T. e. e. e. e. e. T. g. #. {& ]& ^& /& (& _& :& <& [& }& |& 1& 2& !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 3& O$ 4& 5& -$ 6& 7& 8& 9& 0& a& !$ d% F# H# 3# 4# 5# Y$ 6# J# K# 9# 9# # .# b& h% ## c# u@ v@ s@ e# x@ [@ $# $# |@ |@ @ @ r+ r+ r+ r+ q+ q+ @ +@ c& d& d& !+ q+ ~+ v+ v+ /+ ]+ .@ u+ q+ $# e& f& g& h& i& j& k& l& m& >+ J@ <. I+ 5+ z. 7+ ` g+ }. s M v W a 4 d 7 ~ { ( [ f = - ; % > # $ $ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. S. e. e. e. e. e. e. e. e. e. n& o& p& q& g+ r& s& t& u& v& w& x& C% t. &+ !. !. !. !. !. !. !. !. y& H$ g. e. e. e. e. e. e. z& A& B& C& D& E& F& G& H& I& J& K& L& M& N& O& P& Q& R& y& S& _% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. N$ T& f$ g$ =$ R% U& V& W& 9& X& !$ H# G# G# H# H# 4# Y$ 6# 7# 8# Y& 9# L# 0# +# Z& h% ## c# u@ d# _$ `& * .* +* }@ @* x@ #* $* %* &* ** =* -* ~+ q+ q+ q+ q+ q+ q+ !+ ~+ v+ v+ /+ D. .@ D. !+ ;* >* ,* '* )* !* ~* {* ]* ^* y. 9. Q. I+ o+ q# f+ R I T t l y z 3 c 6 7 _ < ( / ' = , ; % # # $ @ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. U. e. e. T. S. e. S. e. e. e. e. e. /* (* _* :* <* ] ^ < e R. l+ /. _# [* _@ ~. !. ~. }* T+ !. !. !. !. |* N& g. e. e. e. e. {% 1* 2* 3* 4* 5* 6* 7* 8* 9* 0* a* b* c* d* F$ e* F% !% L@ !% e* B$ f* g* h* i* j* _% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. k* l* !. !. m* n* ~. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. o* p* q* R$ r* j$ s* C# )$ m$ X$ d% F# 3# 3# 3# 4# Y$ 2# 7# ~$ Z@ t* u* v* w* x* y* z* A* B* C* D* E* F* G* H* I* J* K* L* M* N* r+ r+ r+ r+ q+ q+ r+ r+ q+ q+ q+ q+ ~+ {+ /+ D. ]+ ]+ ^+ !+ O* P* Q* R* S* T* U* V* W* 4+ :. p# O I+ 6+ 7+ R. H J L k V n 1 0 5 9 ~ { ) 8 / = * - ; > > # $ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. T. S. E% X* Y* Z* S. n& z& `* f. S. e. e. 1* = .= { : ! ! _ { : w h s '. += @= ^@ #= $= %= k@ !. !. !. !. &= e* f. *= e. {% == -= ;= >= ,= '= <* { )= != )= ~= c {= ]= ^= /= 3% (= J+ W. g. ,@ _= V. d. !% <% := <= [= 9$ }= /= |= 1= !. !. !. !. !. !. 2= 3= 4= 5= 6= 7= 8= 9= 3= h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 6% 7% 0= P$ a= b= c= d= e= f= g= X$ F# n$ G# n$ H# h= i= j= k= l= m= n= o= p= q= r= s= t= u= v= w= x= y= z= A= B= |@ |@ |@ |@ @ @ r+ r+ r+ r+ r+ q+ !+ q+ @* C= D= N* !+ ~+ /+ ]+ ]+ u+ )+ @% r+ E= F= G= H= I= J= K= l& L= n+ p# 0. Y+ o+ q# f+ ` g+ K t M v W | 4 d x ! < ( 8 f * - , % > # $ @ + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. T. T. 4$ E$ M= }= N= O= P= Q= R= S= T= U= V= T. e. V= W= X= != _ ! ! ! ! _ < ) ] { m G+ 9. i K ,% p# n@ T+ !. !. c$ Y= Z= `= - .- +- @- != #- ! ! ! ! ! ! _ $- < 6 %- &- !. !. 1= *- =- -- ;- e. e. S. U. L@ d. d. 8+ g. g. f. <% >- ,- '- )- !- ~- {- ]- ^- /- (- _- :- <- [- }- |- 1- 2- 2= !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 3- 4- 5- 6- 7- 8- 9- 0- a- b- !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 7% f$ c- 0% d- e- f- g- h- i- j- k- l- m- n- o- p- q- r- s- t- u- v- w- x- y- z- A- B- C- D- E- w@ x@ E- [@ }@ }@ +@ +@ 1@ N* F- G- H- I- J- K- L- M- N- O- !+ !+ ~+ ~+ t+ /+ ]+ ]+ )+ {+ s+ P- Q- R- S- T- U- V- W- X- Y- Y# <. O I+ o+ 7+ R. H I U r u n z 3 c 6 e _ ) ^ / = & , % > # $ $ @ + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. f. h. Z- `- '- :% ; .; !. !. s. +; @; #; $; %; &; *; h. =; -; ;; >; : ! ! ! ! ! ! ! ! _ ) < { ) { : _ b z. ,; h+ !. '; ); !; ~; {; ]; ^; _ ! ! ! ! ! ! ! ! ! ! { ] 6+ /; $+ !. !. 4% (; S. _; :; <; e. e. e. e. e. e. e. T. f. ,@ V. @. d. e. [; }; |; 1; 2; 3; 4; 5; 6; 7; <- 8; 9; 0; a; b; !. c; d; e; !. !. !. !. !. !. !. !. !. !. !. !. b; f; g; h; i; j; k; l; m; n; o; p; q; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. %$ e$ r; s; t; u; v; w; x; y; z; A; B; C; D; E; F; G; H; I; J; K; L; M; N; O; P; b# ## t@ u@ v@ d# Q; P- R; S; T; U; V; W; X; Y; Z; `; > .> N* s+ +> !+ q+ q+ q+ !+ !+ ~+ t+ /+ ]+ .@ D. t+ @> #> $> %> &> *> => -> ;> >> ,> :. 0. Y+ 5+ 6+ b. ` . J s k V h a 0 } 9 ~ { ] [ f = & , % > # $ @ $ @ + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. U. '> <% )> !> |* ~> !. !. !. b; {> [. ]> ^> /> (> _> :> <> [> h. }> |> 1> 2> ! ! ! ! ! ! ! ! ! ! _ : ! _ _ : ) 8 u :# h+ !. 3> 4> 5> 6> 7> : ! ! ! ! ! ! ! ! ! ! ! ! : ) l 8> !. !. !. w# 9> 0> a> b> {% e. e. e. e. e. e. e. e. e. e. e. S. T. f. h. _; /* /* c> 1* d> e> f> g> h> i> j> k> l> m> n> o> p> q> r> !. !. !. !. !. !. !. !. !. s> t> u> v> w> x> y> z> A> B> C> D> E> F> G> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. H> I> J> (@ K> L> -+ M> N> O> P> Q> R> S> T> U> V> W> X> Y> Z> Z$ 9# `@ Y@ `> , ., +, @, #, $, %, &, *, =, -, ;, >, ,, ', ), !, }@ ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ ~+ t+ v+ )+ y@ .@ u+ r+ ~, {, ], ^, /, (, _, :, <, [, $= a@ Q. I+ o+ z. f+ R I }. j ). v o 3 p d 7 ! < ( / ' * - ; % > # $ @ @ + . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. U. -- }, (; |, K% 1, !. !. !. !. !. }* I 8 ) { ) ( 2, 3, 4, 5, 6, 7, 8, y 8 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ [ R 9, !. !. 0, a, <* : ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ^ t b, ~. !. !. c, d, e, f, g, /& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= <; _; - h, /* *= `* K+ i, j, k, l, m, n, o, p, !. !. !. !. !. !. !. q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 0, H, ~. I, J, K, :# L, M, N, O, P, Q, R, S, E# 4# 3# 5# T, U, V, W, X, Y, Z, `, ' .' +' @' #' $' %' &' *' =' -' ;' 1@ c& q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ r+ !+ t+ {+ /+ )+ ]+ ^+ )+ @ >' ,' '' )' !' ~' {' ]' ^' /' 8. K@ O 5+ z. 7+ R. H '. U k u q 2 b 5 9 g : ] ^ / = & , % > # $ $ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. U. f. e. 4$ (' I% _' :' !. !. !. !. !. !. !. <' >+ ! < ! ! ! ! _ ] [' }' |' M% S@ p@ e : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < w 1' !. !. 2' 8. ] : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ( 5 O. l@ !. !. 3' 4' 5' 6' ;- 7' e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. n& z& <; {% *= 8' 9' - <; 0' a' b' c' d' e' f' g' h' i' j' k' l' m' n' o' n; p' q' r' s' t' u' v' m; w' x' y' r. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. z' A' B' C' D' E' F' G' 9& V$ X$ H' I' J' K' L' M' N' N' O' P' Q' R' S' T' U' V' W' X' Y' Z' `' ) @* N* .) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ !+ s+ {+ )+ @% u+ D. ]+ r+ %# +) @) #) $) %) &) *) =) n+ H+ <. Y+ o+ z. Z ` . K s M v h a p } x ! < ] 8 f * - ; # @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. J+ -) M& H$ ;) |& >) !. ,) ') )) m@ j@ !. !. !. S+ !) { { ! ! ! ! ! ! = ~) {) !. !. ]) S ( ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ( Q {. !. !. ^) v < ! ! ! ! ! ! ! ! ! ! ! ! _ ! ! ! ! < ~ o+ v. &+ !. h+ /) () _) :) 1* e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= {% _; <) W. d. U. e. Z# [) }) |) 1) 2) 3) 4) 5) 6) 7) 8) 9) 0) a) b) c) d) e) f) g) h) i) !. !. !. !. r> j) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. k) M% l) m) n) o) p) q) r) s) t) u) u) v) L' L' w) x) y) z) A) B) C) D) E) F) G) H) I) J) K) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ !+ t+ /+ u+ u+ @% /+ /+ $# L) M) N) O) P) Q) R) S) T) Y# P. Q. a. o+ b. R. R I T r l y o 3 c 6 g < f % + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. f. U) V) W) D% X) !. h+ Y) &+ o@ l } v %= !. !. !. !. &+ 5+ < _ ! ! ! ! ! ) 4 v. !. !. T+ R. ( ! ! ! ! ! ! : { _ ! ! ! ! ! ! ! ! ! ) a =+ !. !. !. Z) ! { ! ! ! ! ! ! ! ! ! ! { { ! ! ! ! ! : : ! [. k+ `) !. ! .! +! @! {% e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. T. f. f. h. #! c> =; $! %! &! *! =! -! ;! >! ,! '! )! !! ~! {! ]! ^! /! (! !. !. !. _! :! ~ ,~ '~ )~ >+ 9. Q. a. 6+ }# M 6 ' $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. e. !~ ~~ {~ ]~ ^~ ,; /~ (~ _~ k < [ < ! ! _ ( I+ k@ !. !. $+ :~ _ : ! ! ! ! ! ! _ ] }# ^. }* t ] ! ! ! ! | q# <~ [~ l < ! ! ! ! ! ! ! ! _ _ H+ S@ !. !. q. (. | ( { : ! ! ! ! ! { 9 m+ ^. s ( ! ! ! ! ! ! _ ) ] V }~ |~ 1~ 2~ 3~ - e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= *= z& _; /* 4~ g, 5~ 6~ u, 7~ 8~ 9~ 0~ a~ b~ c~ !. d~ e~ f~ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. g~ H> h~ i~ j~ k~ l~ m~ n~ o~ p~ q~ r~ s~ .) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ t+ v+ {+ )+ y@ .@ /+ t~ u~ v~ w~ x~ y~ z~ A~ B~ C~ Z q ] > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. 4$ D~ E~ !. F~ o@ [. M n 4 ! : : ! ! ! ! ! ) h v! !. !. h+ [# _ { ! ! ! ! ! ! ! : : q J p : ! ! : 0 G~ ]) h+ b; o@ 5 ) ! ! ! ! ! ! ! _ ) Y T@ !. !. !. M! n@ T : e ! ! ! ! ! < c v. r. n+ ( _ ! ! ! ! ! ! ! : ) b [~ {> ). H~ I~ =; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= J~ K~ L~ t' M~ N~ O~ P~ Q~ R~ S~ !. T~ U~ V~ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. W~ X~ Y~ Z~ `~ { .{ +{ @{ #{ ${ %{ J) .) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ v+ {+ /+ @% ]+ ^+ /+ ~+ &{ *{ <. s g ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. U. ={ -{ ;{ ~. >{ Y# p ] ) ( < : _ ! ! ! ! ! ! { x ,{ !. !. !. ^) q ) ! ! ! ! ! ! ! ! _ ) ) _ ! ! ! < ). '{ !. !. !. ]) o+ ) _ ! ! ! ! ! ! ! < 1 ){ !. !. !. !. !. t. ,{ Q 7 < ! ! ! < 0 !{ !. /. 3 < ! ! ! ! ! ! ! _ ~ K 5+ }# ~{ {{ ]{ - *= e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= ^{ /{ ({ _{ g) :{ <{ [{ }{ |{ 1{ 2{ ~. h+ 3{ M! !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 4{ 5{ 6{ 7{ 8{ 9{ 0{ a{ b{ c{ d{ e{ f{ g{ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ !+ .@ h{ i{ Y# S 6 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. h. e. j{ k{ l{ ^) m{ T ! { _ ! ! ! ! ! ! ! ! ! ! ! _ ) 5+ i+ !. !. S@ G+ ) : ! ! ! ! ! ! ! ! ! _ ! ! ! _ { s ,; !. !. !. !. n{ d { ! ! ! ! ! ! ! < ! [~ !. !. !. !. !. !. !. *+ p# g < ! ! { g G~ b; S@ z. ( < ! ! ! ! ! ! ! ! b u u o{ p{ q{ - z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. n& '% r{ s{ t{ u{ f) v{ w{ x{ y{ D> z{ A{ B{ C{ d~ D{ E{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. F{ G{ H{ I{ J{ K{ L{ M{ N{ O{ P{ Q{ R{ S{ T{ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ V{ W{ $= R } & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. 4$ D~ X{ s> Y{ i ^ ] _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) y }* !. !. !. Z{ 2 ^ ! ! ! ! ! ! ! ! ! ! ! ! ! _ : K (@ !. !. !. !. k+ p < ! ! ! ! ! ! : 6 [. (@ !. !. !. !. !. r> <' !. {. <. ) : ! _ ) K ]. !. (. p p e ! ! _ : _ { : / M ,; `{ ] {; .] 7' <; {% n& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. +] @] #] $] x{ %] &] Q~ *] N~ =] -] ;] >] ,] '] u> )] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] ]] ^] /] (] _] :] <] [] }] |] 1] q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] W{ n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. T. 3] '- 4] /@ 5] 3 ] : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ N %+ !. !. $+ _~ ) { ! ! ! ! ! ! ! ! ! ! ! ! _ _ . 6] !. !. !. $+ l+ d { ! ! ! ! ! ! ) i v! !. !. !. !. !. !. ,; <. 7] !. 8] ` ) _ ! { d ,{ !. l@ [. R. b ] : x } 9 q 7 < P. 9] s. 0] a] b] c] ;- d] {% z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. e] f] g] h] g) i] j] v{ k] l] m] n] ;] o] p] q] r] s] t] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] v] w] x] y] z] A] B] C] D] E] F] q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. J+ G% |, H] I] n+ g ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] a 8> !. !. !. T@ R. ( _ ~ ~ ! ! ! ! ! ! ! ! ! _ _ f+ y# !. !. !. @= :. { _ ! ! ! ! ! ! < | !{ !. !. !. !. !. s. $= / Y /@ !. b, 9 ) ! _ < b. ^@ U+ g+ a 3 2 ! b P T 0. 0. ,> 9, !. !. /~ J] K] L] M] N] O] 1* _; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. P] Q] R] S] ]! T] U] V] W] X] w' Y] ;] A{ Z] `] 7; ^ .^ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ @^ #^ $^ %^ &^ *^ =^ -^ ;^ 1] q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. T. >^ ,^ '^ !. k+ 2 < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { 9. @= !. !. !. j+ u ( ! g ~ ! ! ! ! ! ! ! ! _ ! [. )^ !. !. r. k+ y ] ! ! ! ! ! ! ! : _ 4+ $+ !. !. !. !. s. P 8 ) _. !. T@ ` ^ ! ! : x J@ y. 9 ^ 4 Y m <. n@ m@ ^) )^ M! !. !. !. !. !^ ~^ {^ ]^ ~ ^^ ]{ /^ <; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ (^ _^ :^ <^ [^ }^ N~ |^ =] T] W] J! 1^ 2^ 3^ 4^ 5^ e; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] 6^ v] 7^ 8^ 9^ 0^ a^ b^ c^ d^ e^ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. T. N& K$ f^ !. ]. }# < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < c [~ b; !. !. !. V@ 2 < ~ ~ ! ! ! ! ! ! ! ! : ~ a. T@ !. !. S@ G+ ) _ ! ! ! ! ! ! ! { ~ :~ h+ !. !. !. !. !. 1' g 8 g+ ]. !. '{ 1 ) ! ! : ! x ! : ! '. <# s. !. !. !. !. !. !. !. !. !. !. T+ g^ h^ i^ j^ k^ l^ m^ h. f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ n^ 0, o^ p^ T] E, q^ r^ z, w' w> s^ t^ u^ !. h+ v^ U~ !. !. $+ C% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] w^ x^ y^ z^ A^ B^ C^ D^ E^ F^ G^ H^ I^ J^ K^ !+ N* N* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. 4$ <= L^ M^ !. !. N^ e { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ( z V@ h+ !. !. h+ O^ < ) ! ! ! ! ! ! ! ! ! _ { K }* !. !. i+ Q. 8 _ ! : { : _ ! _ ] _ _. !. !. !. !. !. !. )) e ) _ H+ P^ r> Q. ( _ ! ! : : _ ~ q# u. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. r. 9] @= Q^ R^ S^ =- )% T. T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. b> T^ U^ V^ x, ^! W^ i] X^ Y^ S~ Z^ `^ / ./ !. !. +/ @/ #/ $/ %/ &/ m* !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. */ =/ -/ y) ;/ >/ ,/ '/ )/ !/ ~/ {/ ]/ ^/ // (/ _/ C= :/ ^ T. T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& b> 5/ 6/ u, 8~ -] 7/ 8/ 9/ !. !. !. !. !. !. !. !. !. q. 0/ a/ b/ c/ d/ 0- h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. */ e/ f/ g/ h/ i/ j/ k/ l/ m/ n/ o/ p/ q/ r/ s/ t/ u/ v/ w/ x/ J) .) q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. z& $ y/ !. 7] !) :# g^ 5 < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { g [* r. !. !. $+ /~ 7+ ] ! ! ! ! ! ! ! ! ! _ { b. z/ !. !. _# R. 0 w y f+ J@ 9. U g+ _. u. 8] q. !. !. !. !. U+ !) 2 : : : X+ !. w! Y ) _ ! ! ! < 4 !{ !. !. !. !. !. T@ A/ _~ N l+ y# !. !. !. !. !. !. !. !. !. !. !. g~ X) Y* e. f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& U. B/ C/ L~ x{ D/ E/ 1- !. !. !. !. !. !. !. !. !. !. !. !. F/ G/ H/ I/ J/ K/ h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. */ L/ M/ N/ O/ P/ Q/ R/ S/ T/ U/ V/ W/ X/ Y/ Z/ `/ ( .( +( @( #( $( 1] !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. %( |% &( k) *( (@ I@ =( f+ ( ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ 4+ M! !. !. !. !. )) ~ ) ! ! ! ! ! ! ! ! ! < j j+ !. !. !. T+ -( v. [# 0. 8. }~ H+ g^ j@ !. h+ q. !. !. !. !. n@ q x ! _ < Y T@ !. ;( x { ! ! ! ) 2 A/ !. !. !. (# N^ a. d ! _ g Y >( !. !. !. !. !. !. !. !. !. !. !. !. ,( I$ -- T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& B! '( )( L~ m; !( ~( {( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T~ ]( $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^( /( (( _( :( <( [( }( |( 1( 2( 3( 4( 5( 6( 7( 8( 9( 0( a( b( c( d( e( f( ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. g( h( !. !. r. $+ '{ i( S ( ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g K@ @= !. !. !. !. &+ 7+ < ! ! ! ! ! ! ! ! ! < I /~ !. !. !. !. !. !. !. {> y 4 | n{ !. !. !. !. !. {. z# l+ q# _ { ! ! < w W+ !. x! M < ! ! ! { 5 j( q. !. t. ,% 0 ) ) : : ) ( Q. 1/ !. !. !. !. !. !. !. !. s. ^@ !. !. k( l( m( g. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. n( o( p( m; q( r( !. !. !. !. !. s( t( u( v( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. w( x( y( z( A( B( C( C( D( E( F( G( H( I( J( K( L( M( N( O( P( Q( R( S( T( U( c& !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. e. M= V( W( r. !. !. l@ N^ '. ( _ _ ! ~ _ { ) ) < { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ | W+ !. !. !. !. !. v! '. _ _ ! ! ! ! ! ! ! < V X( !. !. !. !. !. !. r> Y( 0 [ < Z( !. !. !. h+ u! Z u d : _ ! ! ! _ < R u. =( | : ! ! ! _ { ,% ^@ !. `( 6 ( _ ! ! ! ! { 7 [# $+ !. !. !. !. q. %+ _# p# I@ T@ b; !. _ !> ._ h. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. +_ @_ #_ f) $_ !. !. !. !. %_ %/ &_ I! *_ =_ -_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;_ >_ ,_ '_ )_ !_ ~_ {_ ]_ ^_ /_ <( (_ __ :_ <_ [_ :_ G( }_ |_ 1_ 2_ 3_ 4_ 5_ 6_ ~+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. 7_ 8_ 9_ 0_ ]) &+ 9] !. }* U ( w 6 < < e b ). . H u 7 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ^ Q P^ !. !. !. !. r> n+ g : ! ! ! ! ! ! ! : _ Y+ z/ !. !. !. !. &+ :~ z _ _ ) u a_ !. !. r> @& [ ] < _ ! ! ! ! ! _ ~ a 9 : ! ! ! ! _ < g+ b_ T@ :. 7 : ! ! ! ! ! _ { @& S+ !. !. !. !. T+ $= ). ! e '. K@ 8> !. k) &= G$ g. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& B! n, c_ [- m; d_ !. !. e_ 9- G! 0~ f_ g_ h_ >] r^ i_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ :_ x_ x_ x_ y_ 3( z_ A_ B_ C_ B_ D_ E_ d& s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. L@ -) J% F_ G_ H_ v. i( o@ X( X+ p ) k I 9 q !) N^ b_ 8] /~ 8> H+ 7 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : Y+ ]) !. !. !. !. *+ f+ ~ _ ! ! ! ! ! ! ! ! { x O. s. !. !. ,; Y+ x ] ! ! _ ( s z# !. 9] P ( _ ! ! ! ! ! ! ! ! : ( { ! ! ! ! ! ! _ d I Q. m ~ ! ! ! ! ! ! : ! G+ j@ !. !. !. ]) += } ^ : { ( 8 r 7] !. !. R& (' h. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& U. I_ J_ o> K_ L_ $+ !. K/ M_ N_ O_ *] P_ Q_ R_ S_ T_ U_ !. !. !. !. !. !. !. V_ W_ f~ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;_ j_ X_ Y_ Z_ `_ : .: +: @: #: $: %: &: *: =: z_ x_ x_ x_ x_ 3( -: ;: >: E( ,: ': ): @* ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. S. U. !: .$ ~: {: j@ /~ _@ @& 0 5 x : g T J@ 2/ =+ %+ !. !. !. !. !. 9, ,% : : ! ! ! ! ! ! ! ! ! ! ! ! ! : e 1' !. !. !. !. ]) y. 9 _ ! ! ! ! ! ! ! ! ! ! < 3 `( l@ ]: j < < ! ! ! ! : ( Q @= ~. [. ] _ ! ! ! ! ! ! ! ! _ { < ! ! ! ! ! ! ! : ] ! ! ! ! ! ! ! ! ! { e G~ q. !. !. j@ i( 6 ) ! ! ! ! : < v j( ^: !. X) >^ 8+ T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. /: (: _: :: <: u( !. [: }: B> N~ m] C> i] N~ |: 1: 2: !. !. !. !. !. !. 3: 4: ^! <: 5: 6: !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;_ j_ 7: 8: 9: 0: a: b: c: d: e: f: g: h: m/ i: E( y_ x_ x_ j: k: l: m: n: o: p: q: r: s: 1@ T% q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. T. *= N& Q& b$ $+ h+ !. k@ _@ n ) ) : : x n+ (# !. !. !. !. !. !. !. !. !. }* . : _ ! ! ! ! ! ! ! ~ ! ! ! ! { ~ ]: !. !. !. j@ Z( 6 ) ! ! ! ! ! ! ! ! ! ! ! _ { 1 . 1 < ! ! ! ! ! ! ! < 6 ;+ 1/ }# ( _ ! ! ! ! ! ! ! _ i G~ s : ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! { e m+ !. !. !. y# R ( _ ! ! ! ! ! _ f a -+ t: u: v: w: -- T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. /: x: y: z: Q_ A: B: C: C> U] D: J! E, Y] B> E: |: F: E{ !. !. !. !. 1- G: =] D> H: A{ g) I: r( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. J: K: L: M: N: O: P: Q: R: S: T: T: U: V: W: X: p: Y: x_ Z: `: < .< +< @< #< $< %< &< *< =< -< s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. f. Z- |% ;< >< !. C% !. !. $+ [* < : ! ! _ ! T ]: &+ 9] !. !. !. !. !. !. !. !. %= V : _ ! ! ! ! ! ! ! ! _ < { { M 7] !. !. !. ~. K@ [ g ! ! ! ! ! ! ! ! ! ! ! ! ! { < : ~ ~ ! ! ! ! ! ! ! ] q %= O 8 _ ! ! ! ! ! ! : _ O. !. o@ 9 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { d o@ !. !. !. 7] v ] ! ! ! ! ! ! ! _ : a q# '{ !. ,< '< )< T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= !< ~< {< ]< ^< D> /< t, (< Q_ _< :< x> << D> [< }< |< 1< !. !. !. 2< 3< 4< B> r^ q^ 1: 5< 6< 7< e_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 8< 9< 0< a< b< c< d< e< T: T: T: T: f< g< h< i< j< k< 5( l< m< n< o< p< q< r< s< t< u< v< w< x< y< z< q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. S. f. e* A< B< !. !. !. !. !. !. $+ G~ ] : ! ! ! _ < W 6+ O. ){ @= !. !. !. !. !. !. T+ Q. ~ : ! ! ! ! ! ! ! _ w 3 : 9 Z( r. !. !. h+ /~ Y { x ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! ! ! ! ! ! ! ! ! ! < c N^ m@ o ) ! ! ! ! ! ! _ _ t C< J@ } : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < v =+ !. !. !. U@ v ] ! ! ! ! ! ! ! ! ! ] ] D< h+ !. 3/ E< U. f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= F< G< H< I< 8~ B> z{ m] E, p] J< K< L< :< R_ M< N< _: O< !. !. g~ P< l; Q< R< l] i] S< (< T< U< V< W< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. */ X< Y< Z< `< [ .[ +[ T: T: T: T: @[ #[ $[ %[ &[ *[ =[ -[ @< ;[ >[ ,[ '[ )[ ![ ~[ {[ ][ ^[ /[ ([ _[ s+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. N& :[ <[ !. [[ `) q. q. !. !. j@ 4+ ( _ ! ! ! ! _ : { _ h I@ {> b_ {. M! h+ !. T@ 0. g : ! ! ! ! ! ! ! ] K b, i( i( &+ !. !. !. b; m+ x : ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { h 8> !. j( c { ! ! ! ! ! ! ! ) { 7 ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < T }* !. !. !. V+ h ] ! ! ! ! ! ! ! ! ! ! < 2 Z( }[ !. [/ V) [; T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= J+ |[ 1[ 2[ ]< <: 3[ 4[ }< ^! U] N_ R_ l; 5[ 6[ 7[ }< 8[ r( !. !. 1- ,] o] [^ 9[ 0[ a[ l] r^ *] 1: o] i; b[ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. c[ d[ e[ f[ g[ h[ i[ j[ T: T: T: T: k[ l[ m[ n[ o[ p[ q[ r[ s[ t[ u[ v[ T: @[ A^ w[ x[ y[ W: z[ A[ B[ C[ z< !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. S. <% D[ _% !. E[ O^ ;+ !. h+ h+ !. M! J@ 8 _ ! ! ! ! ! ! _ : ) d r R. K@ x. F[ Z{ w. ). ! _ ! ! ! ! ! ! ! ^ H w! !. !. !. !. !. !. M! I@ ) : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! : } 4+ l@ U+ . ] ! ! ! ! ! ! ! ! : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { S 6] !. !. !. #= | ] ! ! ! ! ! ! ! ! ! ! ! { ~ 8. k@ !. N= G[ }, g. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= H[ I[ o> J[ K[ L[ ;] 1: [{ M~ O_ B> M[ w{ N[ N_ 1: O[ !. !. !. P! _{ T< 0~ U] W] J< P[ T] Q[ r^ J< f_ ]! q; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] R[ S[ T[ U[ v] j[ T: T: T: T: V[ W[ X[ Y[ Z[ `[ } .} Y[ +} @} T: T: T: #} V[ $} %} &} *} =} -} ;} >} N* ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. T. ,} &= !. '} C< g K@ S+ !. !. !. b; X+ ( : ! ! ! ! ! ! ! ! ! : < < _ d o M 2 g ! ! ! ! ! ! ! ! ! < p !{ !. !. !. !. !. !. h+ o@ w { ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : { ] : ! ! ! ! ! ! ! ! { b Y g+ a : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { d 4+ T+ !. !. r> _@ } < ! ! ! ! ! ! ! ! ! ! ! ! ] ! Z( j@ !. k) D% F$ U. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& !% )} m' c/ !} D, E, [< O~ [< N[ ~} W] << {} T] B> B> ]} !. !. !. ^} /} (} N~ _} N~ m] O~ O~ m] Q_ :} U< <} [} }} !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: |} 1} 2} 3} 4} E) 5} 6} O( 7} T: T: T: T: T: T: 8} 9} 0} n[ a} b} c} d} e} +> !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. f} }, g} !. T@ o@ H+ 9. }* h+ !. !. !. _# J ] ] < : : _ ! ! ! ! ! _ _ _ { < ) < _ ! ! ! ! ! ! ! ! ! { 6 g^ !. !. !. !. !. !. S@ }~ | ) ! ! ! ! ! ! ! ! ! ! ! ! : ) { e d H ` g ) { _ ! _ { ] _ e 8 = : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) q )) q. !. !. k@ n+ e : ! ! ! ! ! ! ! ! ! ! ! ! _ [ 0. ^@ !. !. h+ h} H$ T. T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= J+ i} <- j} t' w' (< }< k} k} Q~ 0~ l} K[ W^ T] m} 9[ n} !. !. !. o} o' D> Y] p} q} m] k} k} }{ r} s} t} D> u} v} 2< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: w} C^ x} m/ y} E( z} A} B} C} D} T: T: T: T: T: T: T: E} F} G} H} t< I} J} K} L} M* E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. M} 5, ,( !. j+ [# /~ >( T+ !. !. !. !. ]. K@ }# g+ 4 ! : { { : < ) < : : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! < 5 _@ j@ !. !. !. !. !. X( T ! _ ! ! ! ! ! ! ! ! ! ! ! _ x q z. O^ n@ /@ Z{ H d ~ { _ : p n S N 9. k ! _ ! ! ! ! : : : { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) W V@ !. !. !. P^ J@ g : ! ! ! ! ! ! ! ! ! ! ! ! ! ] I 6] !. !. !. !. f' >- f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& N} 5/ O} S] <] :< N_ }< k} R_ P} N~ l; R< *] Q_ Q} p} R} !. !. !. S} I< 9~ N~ T] r^ 7[ O~ O~ P} r] T] m] M< M< g_ T} 3{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: U} d: V} W} X} Y} D( Z} `} | .| T: T: T: T: T: T: T: T: T: '[ +| @| #| $| %| &| *| =| s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. T. -- f* g' !. !. U@ $= b_ !. !. !. !. !. !. ]. Z 1' 8] V@ =( :. }# o _ 1 M a g { : : ! ! ! ! ! ! ! ! ! ! ! ! ! _ { o+ /@ !. !. !. !. !. #= o ) ! ! ! ! ! ! ! ! ! ! ! _ < R. -| ;| r. !. !. $+ /~ F[ =( S ! J i( {> ^. <' !. >| H { _ ! ! g x ) { 6 : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w <# !. !. !. 6] f+ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! : g 6+ -+ T@ !. !. k) ,| G$ L@ e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. '| )| !| [} U] ~| }< k} [< N_ Q_ 0[ O~ [< {| (< ]| s( !. !. !. ^| /| [< ;] ;] n] (< R_ 9~ M< :< (| U] B> W^ M< _| V^ $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: :| <| [| }| || 1| 2| 3| 4| 5| .| T: T: T: T: T: T: T: T: T: T: .| +| 6| 7| | }_ 4_ 8| y< T% q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. T. 4$ 1% _% !. !. T+ _. )) q. !. !. !. M! }* y# i( W+ !. !. $+ P^ >( k+ N ,{ Z{ !{ Z) G+ f+ 4 : ! ! ! ! ! ! ! ! ! ! ! ! ! < 3 ,{ M! !. !. !. !. U@ s ) ! ! ! ! ! ! ! ! ! ! ! < 1 -+ j@ !. !. !. !. !. !. !. r. w. 6 2/ !. !. !. !. !. !. i( 6 { ! { } >+ <~ !) Z) L { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w j( !. !. !. )) b { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < g K@ i+ !. !. r( 9| 0| L@ e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= !% a| K~ v} b| c| N_ }< k} N< D> B> d| k} ;] e| E, f| !. !. !. g| 4= A, l} h| i| j| B> z> k| l; U] r} N~ U] q} l| m| n| n* !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: o| p| q| r| s| t| u| X: v| w| x| T: T: T: T: T: T: T: T: T: T: E} y| z| A| B| C| D| E| F| G| d& !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. T. -- 1% H| !. !. !. >| X( j@ !. !. !. _# }# U b. y. ]) !. !. !. !. !. S+ S+ !. !. r. i+ >| n+ 7 < ! ! ! ! ! ! ! ! ! ! ! ! _ < i #= !. !. !. !. a_ L ) ! ! ! ! ! ! ! ! ! ! : w G+ T@ !. !. !. !. !. !. !. w! ,; O { 5+ V+ <' !. !. !. !. >| }. ) _ ) } :# !. b; j@ }* }# : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) w I| !. !. !. i( e { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ) e K@ b, k@ !. J| K| U) U. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= U. L| M| N| S] O| N_ P| k} O~ O~ O~ Q| k} a[ Q~ Q| R| !. !. !. !. y' l] M< Q~ k} e| S| Q~ M< T| U| (< 1: P} W^ V| A> t} W| X| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: Y| Z| `| 1 .1 z} +1 @1 +: #1 @} T: T: T: T: T: T: T: T: T: T: T: 7^ $1 %1 &1 *1 Y' =1 -1 ;1 >1 M* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. S. F$ ,1 .; !. !. !. !. S+ h+ !. !. s. $= { 8 ] c [* 1/ !. !. !. !. !. !. !. !. !. !. !. z/ a. _ : ! ! ! ! ! ! ! ! ! ! ! ! : { H v! h+ !. !. X( r < ! ! ! ! ! ! ! ! ! ! { V u! h+ !. !. !. !. !. 9, [~ Q. s W ~ _ q [~ ^@ !. !. !. {. Q < _ ) ). Z{ !. !. !. !. i( d { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) 8 q ){ !. !. !. X( h ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { d <~ S+ '1 )1 !1 7' U. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& B! ~1 {1 2[ #_ ]1 x> D> [< ^1 M< k} /1 q^ << t} (1 V^ !. !. !. _1 :1 L[ <1 [1 Q~ O~ k} O~ k} Q~ K< R_ k} O~ R_ -] L[ 1: Q~ }1 2< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: |1 11 21 31 41 /[ 51 61 X[ 71 81 T: T: T: T: T: T: T: T: T: T: T: T: 91 01 }| a1 b1 c1 d1 e1 f1 g1 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. U. M} D[ h1 !. r. v. [~ s. !. !. !. !. '{ y ] ! _ { e Y+ X( )^ 9] r> b; !. !. !. !. !. !. !. '{ j < _ ! ! ! ! ! ! ! ! ! ! ! ! : ~ Z -+ '{ _# G~ a { ! ! ! ! ! ! ! ! ! _ { r z# !. !. !. !. r. -( [. e ! { g g : ^ v 8> !. !. !. &+ f+ ] ) s X( M! !. !. !. !. j( p { ! ! ! ! ! ! ! ! ! ! ! ! ! { y y. ]: s. !. !. !. %+ O ^ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ^ c v. (@ i1 j1 k1 U. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. l1 m1 M_ T_ n1 l| D> m] w' o1 T| m} R< E, }{ O~ p1 !. !. !. q1 r1 q^ l} s1 t1 9~ k} k} k} k} k} k} k} (< p] P} q} u1 v1 w1 ]! y' x1 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: y1 z1 A1 B1 C1 D1 E1 F1 G1 H1 8} T: T: T: T: T: T: T: T: T: T: T: T: k[ I1 J1 `| K1 L1 M1 N1 v= O1 P1 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. U. `- a$ !. ]) += 0 9 m+ j@ !. !. !. /~ L ] ! ! ! { ~ v ` @& O. ,{ /~ h+ !. !. !. !. !. P^ <. : _ ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ 2 s U a g ! ! ! ! ! ! ! ! ! ! _ : U ,; !. !. !. !. (# Y ^ { _ ! _ ! ! : _ 8. ^@ !. $+ A/ l ] ( 5+ j@ !. !. !. !. k@ p@ } { ! ! ! ! ! ! ! ! ! ! ! ! : a l+ S+ h+ !. !. !. !. !. #= W ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ^ V a_ r. 2' |& 6$ h. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. Q1 ~< R1 F> S1 T1 }< i| }< *] ~} B> k} 9~ |{ }{ U1 !. !. !. V1 {| p] 0~ x> K_ N_ 1: k} R_ q^ ;] i| D> l; A, E, z> U] Q~ n] T< q^ W1 X1 !. Y1 O< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: y1 Z1 `1 2 .2 +2 @2 #2 $2 .| j[ T: T: T: T: T: T: T: T: T: T: T: T: T: %2 #[ &2 *2 =2 -2 ;2 >2 ,2 '2 )2 s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. T. |% ;{ !2 Y+ : ) ^ y '{ !. !. !. ~. 4+ : : ! ! ! : ) ] ) e 4 U [* ]) !. !. !. !. ~2 Q : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { < ) : ! ! ! ! ! ! ! ! ! ! ! _ : '. (@ !. !. !. !. 6] q ( ! ! ! ! ! ! ! : 1 x. v! ]: I e _ { w D< /~ i+ 9, W+ 4+ r g _ ! ! ! ! ! ! ! ! ! ! ! _ { S >( !. !. !. !. !. !. !. $+ m+ x { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ) H l@ !. !. 8_ {2 f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& e. n( s{ R1 t, T] ]2 }< k} O~ e| Z] ^2 k} /2 (< l| (2 !. !. !. _2 :2 <2 z> ^< [2 I! 0~ l} B> k] }2 }< h| |2 s} V] ^! 12 0~ -] m] 22 R_ 32 42 F/ 52 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: y1 62 72 82 92 .2 02 a2 b2 c2 .| T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 8} d2 e2 f2 g2 h2 i2 j2 k2 l2 m2 ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. h. D$ n2 o@ _ ] ! < c V@ !. !. !. M! 4+ < : ! ! ! ! ! _ _ : { ^ ! q# Y( ^. ]) t. [* z : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ` b_ !. !. !. !. v! z ] ! ! ! ! ! ! ! ! ) ~ n | _ _ ! ! < ! L 4+ H+ o e ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! { t _# !. !. !. !. !. !. !. !. z# i ] ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { { Q ^. o2 L% l( 4$ f. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= !% Q1 p2 q2 r2 :< N_ }< k} k} O~ Q~ l} p] s2 t2 d; u2 !. !. !. e_ v2 1: (< S| z> w2 Q< *] n] =] q^ }< U] Q_ ;] [< w' x2 << m; l} D> z{ E: :^ y2 J| 0, !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: y1 z2 A2 B2 C2 D2 |_ }_ E2 F2 G2 d2 j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E} x| H2 I2 J2 K2 L2 M2 N2 O2 f( !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] $= Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. S. J+ P2 Q2 C< ! { ! : ~ I@ r. !. !. h+ l+ w ] ! ! ! ! ! ! ! ! ! ! _ ) 0 }. Q Z 3 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ R. 8] !. !. !. !. (@ h ] ! ! ! ! ! ! ! _ 4 7+ J ~ : ! ! ! ! : { ~ ~ { : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w ;+ b; !. !. !. !. !. !. !. j+ }. ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ [ J 9, !. R2 M= S. h. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= e. S2 T2 {! i; W] N_ }< k} k} E, t^ U2 V2 I: !. !. !. !. !. !. !. n* H! P| D> R_ N~ :< 0~ E> (< W2 C> J< ^! w> w' E, w' W^ q^ *_ T] W2 (< 0~ X2 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ Y2 Z2 -2 `2 n< 3 .3 +3 @3 #3 $3 %3 &3 *3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: =3 -3 ;3 >3 ,3 '3 )3 !3 ~3 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ R 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. T. '> {3 ]3 ^3 /3 < _ ! ! ) U l@ !. !. !. k@ $= { { ! ! ! ! ! ! ! ! ! ! _ < ] { _ : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ). {> !. !. !. !. ~. 4+ { : ! ! ! ! ! : ! P. &+ -( T { _ ! ! ! ! _ : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < R 6] !. !. !. !. !. !. !. u. t ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) 9 F[ !. !. (3 |% f. S. e. e. e. e. e. e. e. e. e. e. e. e. e. z& U. |[ _3 G! q] T] N_ }< O~ }< w' x> (1 (< :3 !. !. !. !. !. !. !. !. <3 W] 9~ R_ }< N_ M< Q~ (< E, C> [3 0~ l; =] E, D, o1 p] S| :{ ^! 0[ N< T] }3 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ E} |3 13 23 33 43 53 63 x_ 73 E( 83 m/ 93 03 7^ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 7^ a3 b3 c3 d3 e3 f3 g3 P1 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ R } & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. m( h3 k) b, d < ! ! ! : 7 p@ r. !. !. !. (# 7+ ' < ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 7 O^ r> !. !. !. !. ;+ : : ! ! ! ! ! { _ =( !. P^ I+ < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { x G+ (# !. !. !. !. !. i+ m+ a { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ] I+ ~2 !. !. f' !~ f. e. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= i3 c_ c) n; w> M[ }< }{ }< 0~ w' }< |: j3 !. !. !. !. !. !. !. !. y2 k3 B> D> O~ N_ J! O~ O~ t} S| e| (< U] ;] D> l; _< Q_ U2 t} w{ l3 N~ 9~ Q_ 8= 6% !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ S: m3 n3 o3 p3 q3 r3 x_ x_ x_ s3 t3 X[ u3 v3 w3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: f< x3 y3 =2 z3 A3 B3 C3 t~ s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y } & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. U. {2 D3 !. ]: } < ! ! ! ! ) 4 i( 9] !. !. !. >| Z x ) : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) l X( !. !. !. w! @& < _ ! ! ! ! ! < n v. !. r. ,{ 4 ) ! ! ! ! ~ ~ { < : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w 0. m@ i+ b; !. b; :# J _ _ ! ! ! ! ! ! ! ! ! ! ! ! { ] { ! ! ! ! ! _ { < : x 7+ b_ !. k) E3 !: U. e. e. e. e. e. e. e. e. e. e. e. e. z& Z= B/ o> u> F3 /| G3 0[ =] P} r} T] n] H3 I3 J3 !. !. !. !. !. !. !. T~ K3 0[ B> U< L3 Q~ k} O~ Q~ L< q^ }< M3 r] p] 0~ L[ [2 n] 9~ ;] J! Q~ B> m| A, N3 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ O3 C^ P3 Q3 R3 S3 A_ x_ x_ x_ J( X/ T3 U3 V3 W3 X3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: v[ Y3 Z3 `3 4 .4 +4 @4 N* !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. U. 5$ #4 !. $4 6 < ! ! ! ! ! < 6 K@ {> %+ !. !. {. m+ V : ) ) < : : _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! _ { ] < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < Y :# z/ ^. !) | : ! ! ! ! ~ _ [ ,% w! !. !. @= G~ } < _ < { _ : 6 b 6 { < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < ~ J O. <# =+ <# Y x : ! ! ! ! ! ! ! ! ! ! ! _ < c n 6 < ! ! ! { b a@ Z : ) ^ P %4 !. w# ~& f. S. e. e. e. e. e. e. e. e. e. e. e. z& Z= 5~ ~< M_ F> ^2 &4 E> Q_ J! t} z> U] ;] ;] *4 !. !. !. !. !. !. !. X| =4 Q~ R_ -4 Z] R_ ;4 k} }< >4 E, e| z> -] Q~ N~ Q_ [2 r^ ^1 q} T| Q~ m] }< w1 ,4 r> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ '4 )4 >3 K2 !4 ~4 y_ x_ x_ y_ {4 ]4 g2 ^4 /4 X3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: (4 _4 :4 <4 [4 }4 |4 14 d& !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. Z* 24 h+ 34 7 { ! ! ! ! ! ! < { o 4+ }* P^ !. q. '{ _~ I+ '. q 9 < { { { { : _ _ ! ! ! ! ! ! ! < g V j z ~ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g l Z I c : ! ! ! ! ! ! ] b w. r. !. !. !. k@ [# 4 ) c x ) L ;+ l+ O^ Y+ q : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : 7 c W 2 e : ! ! ! ! ! ! ! ! ! ! _ : { 0 += V+ G~ z { : : ! 5+ *+ k+ b < ) 5 n@ !. !. _' F$ f. e. e. e. e. e. e. e. e. e. e. e. z& e. F< s{ 44 <^ W^ 54 k} k} N< R_ R_ 64 -] 74 S1 84 q. !. !. !. !. !. 94 g) q} T1 << o1 N~ |: e| B> E, R< (< [< q} U] N< 04 >4 x> W^ x> K[ w> T] }< |: T1 a4 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ @[ 03 b4 c4 d4 e4 1| [_ J( s3 f4 g4 h4 i4 j4 X3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: D} k4 W: l4 m4 n4 o4 p4 E. q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ R 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. S. M} q4 r4 g| m+ g { ! ! ! ! ! ! ! _ ( g b. _~ ^) q. !. b; `) /~ %= <~ :. 6+ T a 6 e { ) < ) < : { ) ] x 5+ #= (@ n{ S { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < ) < _ ! ! ! ! ! _ { s !{ @= !. !. !. ~. q. x! t J n{ ,{ p@ 7] r. r. S+ `) )) H 7 _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : < < { _ ! ! ! ! ! ! ! ! ! ! _ { } R I| <' !. j@ ){ n / 8 c I+ Y+ p@ 6+ : : : I+ 1/ !. c$ Q& }% U. e. e. e. e. e. e. e. e. e. e. z& e. s4 t4 q] u4 v4 Q~ }< k} O~ }< :< :< *] s} w4 I! }- x4 0- h+ 2= y4 O[ N_ =] v{ N~ a[ A, V] n] E, N~ N~ ]2 n] w' s^ N~ g_ z4 k} W2 Q_ l3 }: p} U< U< A4 T] B4 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: C4 D4 E4 F4 G4 H4 L( X/ I4 J4 K4 L4 M4 m3 X3 T: T: T: T: T: T: T: T: T: T: 7^ N4 O4 S: T: T: T: T: E} (4 P4 Q4 R4 S4 T4 N4 U4 V4 W4 d& q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. U. -- X4 b$ !. !. C< ! { ! ! ! ! ! ! ! ! ! : { e t N^ q. !. !. !. !. $+ k@ z/ 7] V@ ;+ y. 6+ J } c 6 < 9 d W [* (# !. !. $+ :# l < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! _ : R a_ !. !. !. /~ I@ I@ z. 9 x. !. !. !. !. !. !. !. !. r. m@ ` { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! q n+ (@ !. !. !. !. !. %= z. '. p 6 _ Y+ _@ } : : ! ,> M! !. ,( f* e. T. e. e. e. e. e. e. e. e. e. z& U. a| Y4 A: u{ [^ ~| }< k} 9~ O~ N~ O| &4 k] q^ Z4 O~ }2 7~ `4 5 .5 r1 +5 =] Z] U] O~ N~ x{ ^! p] ;] O~ 9~ S| k} @5 #5 i; E, Q~ N~ << p] F> $5 %5 {} 9~ H: p( o} !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: &5 *5 =5 -5 ;5 &, ]4 >5 ,5 '5 )5 !5 ~5 T: T: T: T: T: T: T: T: T: j[ N4 {5 d< ]5 j4 ^5 T: T: E} /5 (5 _5 :5 <5 [5 }5 |5 15 25 35 c& !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. f. 4$ 5, M$ !. 8] I+ : _ ! ! ! ! ! ! ! ! ! ! _ { / q# &+ !. !. !. !. !. !. !. !. !. $+ w! 9, z/ I| N^ I| O. ,{ %= u! S@ !. !. !. !. S+ D< e : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { Q 1/ M! k+ I _ ) ) < K j+ !. !. !. !. !. !. !. !. q. }~ c < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { b [* ;| !. !. !. !. !. !. !. s. ]. :. { ) H ,> } : ! ( p U@ !. !. ;< M} f. e. e. e. e. e. e. e. e. e. z& Z= ~1 45 2[ 55 65 54 k} k} [< N< [< y> << T] K[ ^1 <2 /2 H: Z4 ]2 R_ o] Q~ =] 12 B> k} 1: W^ 5[ 0~ N< }{ M< E, ]< 75 =& 7= A: 1: r} s} N< w' 85 .^ H! U< O~ U< 95 h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: E} 05 a5 b5 c5 d5 }| l/ e5 f5 g5 h5 T: T: T: T: T: T: T: T: T: 8} d2 ]5 i5 +: j5 k5 l5 *3 j[ m5 n5 o5 p5 q5 /4 r5 s5 t5 u5 v5 w5 >1 M* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. f. -- x5 k) !. -+ 4 { ! ! ! ! ! ! ! ! ! ! ! ! ! 8 Z y# ,; #= 6] %+ >( z# )^ m@ n@ T+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. j@ ;+ d { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : : _ ! ! ! ] 3 A/ >| ). / { _ _ ! : h g^ r. !. !. !. !. !. !. !. >| g+ ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < ). =+ !. !. !. !. !. !. !. !. !. !. z/ I+ ! x c g ! ! _ { 8. 9] !. 1= I% -- S. e. e. e. e. e. e. e. e. z& U. /: y5 v} 5[ -4 >4 ;] N< Q_ l3 Y] t1 *_ z5 z> Q< z> t} r} m] 0~ ^! Q~ k} m] z> M< k} 9~ R_ v{ l| (< (1 A5 B5 C5 !. !. !. p, D5 N_ R_ e| 22 E5 F5 G5 *] << (1 w' `^ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: j[ C4 H1 *5 H5 I5 J5 K5 L5 C4 E} T: T: T: T: T: T: T: T: N4 Y3 M5 N5 O5 P5 Q5 R5 S5 T5 U5 V5 W5 X5 Y5 Z5 `5 6 .6 +6 j5 Y2 @6 #6 }@ s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] $6 $= Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. #. S. %6 8_ !. r. [~ 9 { ! ! ! ! ! ! ! ! ! ! ! ! _ [ P *+ Q. } V Z I y '. n 7 :. -( `) b; !. !. !. !. !. !. !. !. !. !. !. !. r> Z) 6 : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ~ e : { ! _ _ j X( k@ y. e _ ! ! ~ _ / a W+ <' !. !. !. !. !. !. `) <. : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < W W+ !. !. !. !. !. !. !. !. !. !. z/ ,% ~ { { ! ! ! ! { x 2/ r. !. &6 Z* f. e. e. e. e. e. e. e. e. z& )< *6 <- =6 -6 ;6 ^2 Q_ Q~ ^< T] J< G3 o1 C> 1: Q~ >6 r] L[ w{ ]2 L< M3 h| [< %] A> O~ k} O~ }< B> (< ,6 '6 T~ !. !. !. !. !. T~ <3 M_ 0~ m] (1 )6 !6 8~ U< z5 H: ~6 {6 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: 8} x| m3 ]6 ^6 /6 (6 j[ T: T: T: T: T: T: T: T: v[ _6 :6 <6 [6 +: }6 (5 |6 16 v> 26 36 46 56 66 76 86 96 06 a6 b6 c6 d6 e6 f6 @ ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. #. 3] g6 x# h6 P. L 7 _ ! ! ! ! ! ! ! ! ! ! ! : ) _ n+ W+ t / ! 9 ^ ) ^ ) ) 7 v I 0. =( 6] !. !. !. !. !. !. !. !. !. !. P^ n+ 7 : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ V 8. N z. 1 ! < } ;( ~. !. T+ [* w { ! ! ! _ ! i G~ 6] !. !. !. !. !. *+ R. { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g P ~2 !. !. !. !. !. !. !. !. !. A/ 3 ^ _ ! ! ! ! ! ! ( 2 i6 !. j6 6$ f. e. e. e. e. e. e. e. e. *= '% k6 ~< d) b| x{ l; Q~ (< A> *] l6 E, r] (< O~ O~ U< l} << E, R_ m6 B> Q~ N~ p} L3 e| }< e| ;] E, K< n6 o6 !. !. !. !. !. !. !. !. u2 r, w' w1 n] T_ O| 0~ p6 g_ m] q6 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: E} 7^ 8} S: T: T: T: T: T: T: T: T: T: 8} r6 s6 h4 t6 u6 v6 X/ /[ 1_ E1 w6 x6 y6 $2 z6 A6 B6 C6 D6 E6 F6 G6 H6 I6 v5 J6 K6 M* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. #. ~& L6 !. Y# [ { ! ! ! ! ! ! ! ! ! ! ! : ] ! y C< 8] 8] F[ X+ @& R. 6 { ! ! ! : ] ^ ] _ ` o@ :# U+ !. !. !. !. !. !. (# ;+ u _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 5 += `) k@ l@ ;+ } ( x ;+ !. !. !. 8] r ) ! ! ! ! ! { 9 f+ :# w! 9] !. k@ _. b { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w a@ {> U+ w! j@ !. !. !. !. !. V+ l ~ { : ! ! ! ! ! ! ^ M6 _# N6 O6 f. e. e. e. e. e. e. e. e. S. P6 Q6 y5 R6 B, S6 :< N< M< N~ -4 ^! T6 ;] N< ;] D> D> L< z> U6 O~ ]2 Q~ D> T1 r^ E, O~ B> 0~ V6 U< d| V^ j@ !. !. !. !. !. !. !. !. !. !. W6 U< X6 N< q^ p} }: Q~ >] Y6 Z6 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: `6 7 .7 +7 @7 #7 Y} J( <_ $7 %7 &7 *7 =7 -7 ;7 >7 ,7 '7 )7 8} !7 ~7 {7 ]7 ^7 /7 &* @ ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (7 #. w: Q] _7 J ) _ ! ! ! ! ! ! ! ! ! ! < ! 1 0. m@ h+ !. !. !. !. S@ 8] $= _ ] ! ! ! ! ! _ { ] < w ` V@ X( X( b_ 1/ 7] Y# 3 _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { d ;( h+ !. !. 8] r / ] t '{ !. !. i+ p# _ _ ! ! ! ! _ { < u 9. [# )) Z( j : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 9 i b. a@ =( I| ){ 8> ;| !. ~. Z{ (. O^ y { ! ! ! ! ! : ] O. :7 <7 f. e. e. e. e. e. e. e. e. S. e] [7 }7 p( s1 u{ |7 P| k} m} ^< -] T] r} 9~ {| a[ ^1 M3 q} (< }< }< ;] e| t} r^ :< 1: N_ I! << [< (1 _: 1< !. !. !. !. !. !. !. !. !. .; 17 E, ^2 S1 Q~ W2 M3 s^ U< g_ 27 u2 !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: |3 37 d5 47 57 z} <_ x_ x_ x_ J( 67 77 87 F2 97 C^ #[ 07 w} T: k[ a7 b7 c7 d7 e7 f7 ): c& q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (7 8+ g7 |= h7 : : ! ! ! ! ! ! ! ! ! : ( 0 4+ u! ]) !. !. h+ !. !. !. !. !. T+ n+ } [ ) _ ! ! ! ! _ : < : 3 z V f+ <. . w < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : K j+ !. !. h+ I| } ) : N ~. !. 1/ 0. ~ : ! ! ! ! ! ! _ : ~ w b 0 e _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { { : 7 a m 3 Q. }* &+ $+ $+ V@ y < ! ! ! ! ! ! '= t i7 j7 T. e. e. e. e. e. e. e. e. e. V= k7 #] j} l7 m; T] k} }< {| l} W^ m7 }< R_ t} (< B> }2 n7 W^ }2 L3 O~ R_ B> :< o7 O~ O~ p7 x2 {| <2 -] q7 T~ !. !. !. !. !. !. !. !. r7 s7 m| ]2 8~ a[ O~ }< :{ O| 1: O~ :^ r. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: t7 u7 v7 w7 x7 y7 z7 [_ 3( A7 x_ <_ 1| B7 7| C7 D7 y1 E7 T: T: T: (4 F7 G7 H7 I7 f3 J7 -* ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (7 h. K7 L7 M7 < _ ! ! ! ! ! ! ! ! : : M n{ i+ !. !. !. !. !. !. !. !. !. ~. T+ @= b, b. ). x _ ! ! ! ! ! ! _ ) ) { : : { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : : a. y# !. !. j@ <~ 9. (. (@ $+ !. ;| q# ) : ! ! ! ! ! ! ! ! : { < : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ : { < ) ( 9 }. Z p@ $= | _ ! ! ! ! ! ! ! #- N7 O7 P7 {% e. e. e. e. e. e. e. e. z& J+ Q7 T2 R7 S7 B, x2 k} T7 d| x2 l] k} k} k} k} i| (< B> }< {} N_ M< 9~ S| }^ l| q} m} O~ t} l] i] N_ U7 0~ V7 W7 X7 Y7 }/ Z7 !. !. !. M$ !6 `7 e| M< n] k} }{ 54 x{ T] _| w' 8 !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: %2 .8 +8 @8 a1 #8 $8 %8 1( E( &8 *8 =8 -8 ;8 >8 ,8 '8 j[ T: T: T: T: 7} q< )8 !8 ~8 {8 =| s+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ]8 8' ^8 /8 (8 _8 ! ! ! ! ! ! ! : ) n !) -( !. !. !. !. !. !. !. !. q. 1/ %= O. }# b. /. %+ ^. '. ] ! ! ! ! ! ! ! ! ! ! _ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 6 P. %= 6] j@ q. j@ !. !. !. !. S@ p@ d < ) ) _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { < ! { < ! ~ ! ! ! ! ! ! : :8 <8 %! =; e. e. e. e. e. e. e. e. z& Z= i3 [8 q2 T_ }8 f) n] ;] B> a[ _} }< O~ O~ k} i| B> N~ O~ k} O~ k} O~ ]2 ^< N~ q} s1 V2 o] [< N[ {| |8 /1 z{ z4 n] 18 `4 28 d_ F/ Z7 !. !. c~ V^ e| }{ k} R_ q^ :< A, Q~ h_ 38 c~ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: C4 48 58 68 78 j5 88 98 08 a8 b8 c8 d8 e8 f8 g8 h8 i8 j[ T: T: T: 7^ -3 T3 ). j8 k8 .* ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. <; l8 m8 >; : ! ! ! ! ! ! _ { W ;+ r> !. !. !. !. !. !. !. %+ a_ Z( ,% u : ( / J v! 9, ` ( ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ a }# Y( 8] S+ !. !. !. !. !. ]. =( 5+ J W ~ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ : : ! ! ! ! ! ! ! ! ! : n8 o8 p8 {% e. e. e. e. e. e. e. e. z& U. Q7 q8 v} 18 q} z> t} N~ r8 N~ *_ v{ n] N_ m] R_ J< T] i| O~ k} k} O~ k} U] << =] l| _< a[ Q~ &4 (< (< [{ l} ;] A{ 9~ R_ 1: t} s8 ,4 t8 u8 S+ q1 i] z{ D> D> T1 T] ^! }2 w1 v8 w8 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E} `6 x8 y8 z8 ;5 A8 `| @< B8 C8 D8 E8 F8 G8 H8 I8 J8 N4 T: T: T: T: K8 L8 M8 N8 O8 P8 !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q8 R8 S8 T8 != ! ! ! ! ! ! ! ] 1 j( ^@ !. !. !. q. S+ @= >( X( G~ r 7 ! { : _ _ ! u I p : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ) : W R I@ v! 9] !. !. !. !. 9] 1/ y# b, I ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : < ( ) { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= U8 V8 W8 {% e. e. e. e. e. e. e. e. z& e. |[ m1 {! V| [2 }2 1: [< 9[ w' U] i] Q_ *] W^ E, [{ x{ T| U< O~ D> N_ k} }< n] 0~ T1 G3 q} w{ K[ :< M< C> >6 U] B> T] :{ B> z4 m| A{ ^< -] X8 /| *_ Q~ p7 z> M< 9[ [{ ^! /1 k] Y8 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: N4 03 Z8 `8 9 .9 +9 @9 #9 Q3 %3 $9 %9 76 J2 +| *3 T: T: T: T: T: &9 *9 =9 -9 ;9 .) q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q8 >9 ,9 '9 _ ! ! ! ! ! ! < 6 I@ s. !. !. !. 1/ F[ >+ ,% '. n x < { _ ! ! ! ! _ ] ^ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ) < _ ! ! ! ! ! ! ! ! _ < ( 9 . _. >( r. q. !. !. !. !. r. Z( 5 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ : ! ~ d L }. u 4 _ ) _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= )9 !9 $! {% e. e. e. e. e. e. e. e. *= !% ~9 {9 o' B, %] i] [< R_ k} E, z> }< }< S| U< P} /1 x> s1 ]9 N[ Q~ Q< x> k} m] z> k] B> n] }2 }2 O_ J< ;] t} E, M< p7 p} V] n7 k] K< f_ g_ w1 k} i] J< q^ >6 D> D, V] r} R_ K_ ^9 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 7^ y1 A^ /9 (9 _9 :9 <9 [9 }9 |9 %3 19 29 :5 7^ T: T: T: T: T: 8} 39 49 59 69 .) q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 89 99 09 ! ! ! ! ! ! : [ Y+ ]. h+ !. !. 6] $= 1 ) < { ) { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ 0 ). h ! : _ ! ! ! ! ! ! ! ! ! : { 5 b. C< -+ {> y# >| V+ A/ a@ } : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : g < _ b 6+ =( -( /~ ){ i( N M ) _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= a9 b9 $. {% e. e. e. e. e. e. e. e. *= !% c9 d9 e9 b| ^< Q~ *] ^! *] q^ l| U] }< k} f9 P[ /1 64 Q_ Z] C, W^ q^ U] W2 z> n] T| W] N_ n7 0~ U6 R_ Y] E, }< g9 r} D, z> Q~ ^! h9 z> z5 e| ;] q} x2 l6 z> O~ N_ D, D> 9~ i9 i_ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: w} T: T: T: T: T: j[ S: f< j9 (4 H2 k9 ]5 l9 m9 n9 E7 T: T: T: T: T: T: T: o9 p9 q9 r9 .) q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s9 t9 u9 #- ! ! ! ! ! _ e b. _# r. !. q. Z{ f+ 9 < : _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { o O^ m@ :# 0. w < : ! ! ! ! ! ! ! ! ! _ { { w 1 r ` R k V } ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : W p# >+ X+ C< Z{ $+ !. !. !. !. !. -( }. { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= v9 w9 x9 {% e. e. e. e. e. e. e. e. z& Z= '| y9 s, z9 u1 N_ L3 y> k] z> N[ [2 8~ 0~ U] y> 0~ Q_ Q_ Q_ ^1 Q_ U< N_ W] 0~ R_ R_ B> U< T] T] 9~ }{ D> r} R_ |^ N~ |2 S1 :< V2 V] r^ A9 [< 1: a[ %] w> *] }{ t} p7 m] O~ <: B9 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: X3 =3 N4 05 R: O4 8} E} T: T: T: T: T: T: 7^ =3 C9 D9 D9 7^ T: T: T: T: T: T: T: T: E9 F9 G9 f( q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H9 I9 J9 K9 { ! ! ! _ { a. T@ !. !. !. ,; I < { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < J ,; !. !. w! <~ V ~ { ! ! ! ! ! ! ! ! ! ! _ : < ) ) : { < : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ 7 T i( ]) M! S@ S+ b; !. !. !. !. $+ k@ q. ]: } { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! )= L9 q{ N} {% e. e. e. e. e. e. e. e. z& Z= M9 ~< N9 <: U| (< ;4 }{ {| U] d| 64 k] J< S| h| 0~ J< >6 :< U< T1 T] z> :< ^! (1 Z4 f_ S| O9 P< P9 Q9 44 q^ R9 Q_ w> *] >4 :{ -] (< S9 E, }< O~ k} Q~ S1 T9 N~ |8 z> U< (< ]< G/ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: X3 7^ 7^ @} U9 V9 W9 X9 Y9 Z9 `9 9} @} T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: #} 0 .0 +0 @0 q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . #0 $0 %0 &0 _ ! ! ! : o )) !. !. !. !. 1' g ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < W ]: !. !. !. b; =+ [. 6 ) _ ! ! ! ! ! ! ! ! ! ! ! ! _ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { h }~ ~. !. !. !. !. !. !. !. !. 9] j( ` Y# J@ c : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < *0 =0 e] *= e. e. e. e. e. e. e. e. z& U. i3 -0 O9 =6 ;0 {| t} 9~ 54 }2 l] z> B> R_ O~ O~ (< 0~ s} w' *] N~ W2 Q_ }2 z: X] ~} S] >0 ,0 !. !. h+ u2 -_ '0 K< q^ M< /1 T| l} B> X6 t} O~ k} k} 1: ;] ^! *_ 0~ N_ E, U| s, J/ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: @} x3 m3 ]6 )0 !0 ~0 #9 {0 ]0 l4 ^0 /0 ]5 h5 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: #} 0 (0 _0 f( q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q8 :0 <0 [0 &0 ! ! : : a@ (@ 7] b; !. !. j( e < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : I {> h+ !. !. !. ]. D< z < < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { L U@ !. !. !. !. !. !. !. !. !. l@ J = < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! _ ) }0 |0 q% e. e. e. e. e. e. e. e. e. z& e. n( c_ v} F> i9 [1 10 d| Y] ^< w' &4 N_ R_ m] [< /1 -] T] /1 [{ :< T7 Q_ 20 c; S} 30 6: c~ !. !. !. !. !. !. V_ V7 Q| (1 R_ T| }2 (< O_ ^< O~ 1: k} |8 z> q^ N_ ;] N~ T1 n] O9 40 !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: U} C4 50 t[ 60 70 a1 ;[ 80 q| 90 00 a0 B8 d5 b0 c0 ^5 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: d0 e0 f0 g0 q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . h0 i0 j0 k0 #- ! ! _ < O 7] p# V+ !. $+ ;( g { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ! ! _ : { < < { _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ~ '. n@ b; !. !. !. S@ -| Z p : < : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : < { < ) { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { L U@ !. !. !. !. !. !. !. !. !. i+ 9. ) { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! : : { { l0 m0 n0 1* e. e. e. e. e. e. e. e. e. *= !% /: p2 R6 o0 :< U] D, N_ t} N~ a[ k} T7 k} N_ E, N~ i] f) l; Y] ;] (1 x{ U~ !. !. !. !. !. !. !. !. h+ u2 p0 r> q0 l| z{ g9 Q~ |7 z> E, 9[ 0~ N_ M< 0~ 9[ ^2 E, B> w{ *] }< j} m> !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: |} r0 s0 t0 u0 v0 w0 r| x0 y0 z0 A0 B0 C0 D0 E0 F0 Z1 k[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: G0 H0 I0 G- q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. J0 K0 L0 M0 : ! ! < p o@ 9. 2/ !. ]. Y+ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { : < { : < < { g W n } _ < { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ) q N^ h+ !. !. !. h+ U+ }~ g+ 9 ! { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { < x q '. s 1 d ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 1 -+ !. !. !. !. !. !. !. !. r. !. m@ z ] _ _ ! ! ! ! ! ! ! _ { _ _ < ) c '. t N0 O0 P0 Q0 S. e. e. e. e. e. e. e. e. e. z& e. Q7 R0 R6 ]! q} x> E, |8 |^ }< [< k} k} k} }< }< r} S0 }2 }2 W^ O~ :< 95 }/ !. !. !. !. !. !. !. !. Z7 T0 ^2 o' U0 V0 W0 O~ z4 Q~ Q~ e| N_ A9 :{ &4 Y] /1 E, (< ;] B> [< }< B{ 3{ !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: v[ X0 Y0 Z0 `0 a .a +a @a #a Y} r3 s3 $a %a &a k/ *a J8 N4 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: =a -a ;a >a q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. ,a U. 'a U8 ,= ! _ 7 l 9. t $= /. n+ ). ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! { ! 5 ). K } e z t y. [# n{ V@ ;+ $= Z 4 < : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 8 }. ^. !. !. !. !. !. h+ 6] l+ 9. | ] _ ! ! ! ! ! ! ! ! ! ! _ _ _ { < : 9 l >+ W+ v! x! /. Z) j ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ Q. {. !. !. !. !. r. (@ n{ D< j( -| }# ) e ! { _ ) 8 ^ ] < _ e _ { 3 k J P P. )a !a ~a {a g. f. e. e. e. e. e. e. e. e. z& Z= F< ]a i; ]! -] ^a I! l} {| D> m] O~ k} k} k} T7 D> T] >4 N~ S1 Q| i] /a !. !. !. !. !. !. !. !. !. q. (a _a T< k} q} T] 04 E> N_ Q~ N< O~ (< N~ T1 :a L3 1: D> B> B> N< z4 s] P! !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: &5 /1 ka !. !. !. !. !. !. !. !. !. !. 7- t1 k} }{ -4 ^! N_ L[ p} J< (< N< g9 R_ }< T] w' t} q^ :< *] >4 [2 la ma !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: E} C^ na e5 oa pa r3 J( y_ x_ x_ <_ *[ qa ra sa ta ua va f< T: T: T: T: T: T: T: T: T: T: T: T: U} E7 wa Q4 xa ya za Aa C= q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. {% $. Ba ]^ : ) q z# '{ 5 f j N q { ! ! ! ! ! ! ! ! ! ! ! : _ l i( 9, r> !. !. w! w. C< :# ^. /@ <' !. !. !. !. ^@ (@ Y# 6 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < 7 p@ ~. !. !. !. !. !. !. !. !. v! T ) ! : : 7 4 p ~ e a }. I Y+ <~ N^ ^. b; !. !. !. !. !. !. !. ,; K ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : | 7+ a@ K@ [. a ( ) _ : < { : i D< G~ '. W+ !. T+ /~ >( T+ 9] T+ s. !. !. =( b ` t Ca >+ Da Ea Fa U= 1* {% S. e. e. e. e. e. 7' Ga Ha P9 p' &4 N~ W^ u4 v{ D> :} ]! -] N~ B> U< (< k] [2 D> s} [^ (1 Ia !. !. !. !. !. !. 6% Ja r7 !. Ka La N_ Q~ N_ W^ U< r} :< Ma N~ i] R_ |{ (1 |: v1 Na w> i; A: Oa +; #/ Pa !. !. !. !. !. !. !. !. !. !. !. !. c[ Qa Ra x^ {] u] +^ j[ T: T: T: T: T: T: T: T: T: E} x3 t[ Sa Ta Ua [_ x_ x_ Va A_ -: Wa Xa Ya Za `a b 8} T: T: T: w} T: T: T: .b 8} 7^ S: V[ C4 (6 +b @b #b $b %b &b *b i! q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. n& :; =b -b ,= : : O. '{ 0 e w. P^ <. ] _ ! ! ! ! ! ! ! ! _ : ~ Z /. 9] !. !. /@ ^) H+ 0 : e z J a. !{ b; !. !. !. !. z/ P ~ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ( k v! !. !. !. !. !. !. !. !. !. %= q ) 3 <. :~ l+ )) =( :~ !{ 6] 9, {. j@ !. !. !. !. !. !. !. !. !. !. 7] }. ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : : _ ] ] { _ ! ! ! ! ! ! ) 3 o+ ). 6+ u. l@ !. !. !. !. !. !. !. 7] 9. p# z. 9 { 9 ;b >b ,b 'b )b !b ~b {b e. e. e. U. J+ (^ !. .; ]b q' a[ Q_ L< T9 =] <2 z> *_ v8 I! 0~ E, ^< ,6 r^ B> V] T7 K_ ^b !. !. !. !. /b (b n; I< _b :b ;0 << D, E, }2 m] 9~ N~ a[ ;] o1 I< 8~ r] Z] t{ v} L~ [- -6 d; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. S@ y. 9 $= 1/ M! !. !. $+ M! !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ 1' y ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : _ _ ! ! ! ! ! ! ! ! ! { < { _ a r _@ 1/ 9] !. !. r. m@ q# 2 Y+ 1 ) _ { ] ~ qb rb sb tb ub vb f. e. e. U. J+ wb !. !. !. xb i; e| L3 v8 D/ {} }{ M< U] D, C> M< =] J< [2 T] N_ R_ w1 yb zb b[ J/ / Ab v{ (1 5< m] *] m} T1 5[ @5 Bb N~ F: Cb Db Eb Fb d~ R} e~ Gb u2 q, Hb ia Ib Jb q0 ./ Kb !. !. !. !. !. !. !. !. !. !. !. !. ;_ Lb Mb Nb y^ u] +^ j[ T: T: T: T: T: T: T: T: T: T: V[ .8 Ob Pb Qb Rb Sb Tb X9 Ub Vb W} Wb 4| Xb I2 Z1 Yb Zb `b c .c +c @c #c $c %c &c *c h: =c -c ;c >c ,c 'c )c !c g{ ~c ~+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. {% {c ]c ^c /c ( / 0. a_ 7] !. `) Q ) _ ! ! ! ! ! ! _ g i J@ 8] !. !. (c {> t & ) _c ! ! ! ! :c ) 5 v. !. !. !. !. !. T+ J@ _ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] u ,; !. !. !. !. !. !. !. !. !. 1' t Z{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. $+ 9, w. L e _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! _ ) 8 w '. a@ x! @= =( G~ ;( v _ ! ! ! ! ! : ) /c i] X6 1: T1 3c T1 |: }{ l; B> ^< p^ M_ 0[ 1[ m* !. h+ !. !. !. !. !. !. !. 4c ({ W^ ;] ^! 5c V7 (! !. !. !. !. !. !. !. !. !. !. !. ;_ 6c 7c 8c 9c 0c +^ j[ T: T: T: T: T: T: T: T: T: T: T: t7 ac bc 68 cc 4 dc ec e5 fc gc hc ic 87 jc kc lc mc nc oc pc qc rc c5 sc m/ tc uc vc wc +7 xc yc zc Ac Bc Cc Dc Ec Fc N* q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. S. <7 Gc a Hc z N !. !. !. U@ L ) ! ! ! ! ! ! : ~ R. k+ {. !. Ic Jc a@ Kc Lc w '9 ! Mc Mc ! ! ! ] 2 V@ !. !. !. !. !. `) J@ _ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ~ =( $+ !. !. !. !. !. !. !. !. V@ R t. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 8] g^ <. z { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ] { S Z ( Y+ 8] K@ ^ : ! ! ! ! ! ! _ _ ] r Nc Oc '% U. U. J+ wb !. !. !. r> E/ T6 B> << m} D> k} k} O~ k} k} E, l; k} g9 }< p} o1 k| B> k} Pc N~ y> >4 Q_ l} 0~ {| {| U] p} q^ K< 4< <2 7[ Qc Rc !. !. !. !. !. !. ~. Sc P< Tc L< N~ [< U7 T< s^ 5: ,0 V~ q. !. !. !. !. !. !. !. Uc Vc Wc Xc Yc Zc +^ j[ T: T: T: T: T: T: T: T: T: T: T: X3 bb X9 `c d ;[ .d +d @d !5 C^ #d 7} w3 $d %d &d *d =d -d ;d >d ,d 'd )d !d ~d x} {d ]d ^d Ya /d (d I8 _d :d q} D, O~ k} k} k} k} O~ E, z> k} P| O~ {} A, r8 (< kd d| B> 0~ ^1 w' U] J! y> J< E, *] L3 9~ << N~ |: |: i] ld md Kb !. !. !. X| nd I! W] N< T1 :< 0~ S| (1 k| y, od pd 0- !. !. !. !. !. !. qd rd sd td Yc ud vd j[ T: T: T: T: T: T: T: T: T: T: T: T: S: t7 wd 48 y0 xd yd W3 @} S: w} j[ E} j[ zd Ad Bd Cd Dd Z5 Ed >5 Fd Gd Hd Id Jd Kd Ld Md Nd Od Pd Qd y0 Rd Sd Td Ud Vd Wd Xd Yd .) q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. <; Zd :& `d H> !. Z7 F[ z ] ! ! ! ! ! ! '9 e .e +e !. 6% !. @e #e $e %e &e !. *e =e -e ;e ;e ;e >e ,e bd 'e += p# >( !. r> u! U < _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < f+ w! !. !. !. !. !. !. !. ~2 . 6 F[ !. !. !. !. !. !. !. !. !. !. !. !. h+ }* :. W x ! { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! g _ ( 8 < < ) _ ! ! ! _ { r 8> /@ u. Z{ _. d ] ! ! ! ! ! ! ! ! ! { != )e !e ,} g. P] ~e <' c; {e ]e ^2 e| Q~ W^ A, n] O~ k} k} k} O~ E, 0~ k} N_ W0 9~ ;] :{ l} Q~ x2 E, U6 9~ 0~ *] U< W^ E, 1: B> Q~ k} }2 k] ^e [< 9~ g_ T| /e (e _e :e 3^ S~ ,6 v{ l; p] a[ w' J< T| ]2 |{ o] N_ 4+ 1 u! !. !. !. !. !. !. !. !. !. !. !. !. (@ . : ] { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : i O^ 8. . 8. [# H : _ ! ! ! ~ R. T@ !. !. !. {. O^ x < ! ! ! ! ! ! ! ! { :* Me Ne }% f. Oe Pe Qe W| yb :} }2 t} O~ k} q} L< O~ g9 O~ O~ g9 t^ z> k} B> W^ m] }{ U< v{ *] N_ (< }< D> U< }< a[ x2 N~ z{ 0~ .5 z> T7 E, r] *] l} V2 22 Re U2 >] Re Se t] `4 l6 i] t} O~ q^ y> p} 6[ g9 }{ |{ {| Te !. !. !. !. !. ;_ Ue Ve We Xe Ye +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: X3 7^ E7 '8 Ze `e f .f +f @f #f }. $f %f &f *f :| X3 T: E} $d &9 =f -f ;f >f ,f 'f )f s+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. *= ^& !f ~f {f _8 _ ! ! ! Mc ed ed ;e Je Fe ]f ^f !. !. N$ /f (f _f :f | !. !. !. 9] >+ ! : ! ! ! ! ! ! ! : >; ^ 6$ 7' n& z& 9f 0f b/ af Q_ M< bf :< M< s} [2 i] Q_ N~ B> t} cf V] T7 04 B> k} O~ }{ B> .5 l6 N< T1 U] :< h| W0 x2 p} E, |: W] q} k} }{ }< B> U] E, k} <2 }< j; t' `4 y2 df t} z, 0[ O~ }{ (< S1 T9 T] U< k} H3 X] S} !. !. !. !. = fd Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : x w. !. !. !. !. !. !. !. S+ $= e m+ !. !. !. !. !. !. !. !. !. !. r> %= u { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 5 Z( q. !. !. !. !. F[ 5 < ! ! ! ! ! I }* !. !. !. ]) R. ] _ ! ! ! ! ! ! _ >; Rf Sf 1* z& Z= Tf 6~ Uf n; .5 N~ s} 8~ L< Q~ 0~ W] w' -] x2 2c :< s^ U] Ma E, Q~ (< N< D> S1 p7 k} m} B> q^ W^ z> Y] Z] R1 l| P} [} Q< g_ Vf M< p7 ^! }2 e| x2 Wf Xf Z6 q. Yf t' B> *] V2 k} ;] X6 Q< K_ x> J< }{ u} Zf h+ !. !. !. c[ Qa `f x^ {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 7^ g j4 D} 7} C^ 91 @} T: T: T: 7^ ee .g $9 *2 +g @g #g $g %g (4 T: T: T: T: T: T: T: %2 &g *g =g -g ;g c& q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. <; 9+ >g ,g < ! ! Mc ed ;e Fe yf 3f 'g )g !g ~g {g ]g ^g /g (g _g :g _g _g :g U] w{ o7 g9 k} {} N_ ]2 V2 V] w' x> 9g :< T] w' E, %] :< V2 m] O~ z4 T1 -] B> z, ^9 Y8 0g 0/ ag M_ A{ E, _} W] r] 0~ }< 5: !. !. !. !. u( bg 9~ :< N_ t} B> 0~ -] -] k] ;] U7 cg Z7 !. !. !. !] dg H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: .b eg fg gg hg ig jg kg lg x| T: T: U} mg ng og pg qg rg sg tg y8 g< y1 T: T: T: T: T: T: ug .| v6 vg wg xg yg !+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. T. [> zg Ag : { Mc ed ;e Fe 3f 'g Of Bg Cg Dg Eg Fg Gg Hg Ig Jg Kg Lg Lg Mg Ng Og Pg Qg Rg Sg Tg Ug Vg Cg 4g Wg 'g 3f Fe ;e ed ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ~ N S+ !. !. !. !. !. !. <' 0. 7 ]: !. !. !. !. !. !. !. !. !. X( u ^ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : T [~ ){ v! ;( b ) ! ! ! ! ! ! ] 0 1' M! !. b; w! Q ) _ ! _ { ! ! < { Xg Yg Zg n& e. /: `g 44 u{ ^! N~ k} U< E, w{ l] h k} O~ O~ O~ M< 7[ O~ }< U< N_ V2 l3 2c T] T] V] r^ T] M< N_ T] m} T] `^ !. !. !. !. .h +h 1: W^ w' q^ t^ Re r1 I: !. !. !. !. @h :< 1: ;] O~ k} E, L< l] q} K< Q~ '6 Z7 !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: t7 #h w6 $h %h &h +f *h fc ta (6 E} X3 =h -h ;h >h ,h 'h )h !h <4 ~h a7 7^ T: T: T: T: T: T: 8} {h ]h ^h /h yg q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. {% 1* (h _h I, :h U6 qh Z7 !. !. !. !. 3= Y] z> Q_ B> W] z> H: -] x4 !. !. !. !. f| r} z{ k} T7 ;] {| q^ |8 R_ << ka r. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 9} rh g2 sh M5 th uh vh #2 S/ Y3 k[ T: k[ wh xh k/ yh zh Ah Bh Ch y[ Dh Eh T: T: T: T: T: T: 7^ Fh Gh Hh Ih O- q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. Jh Kh Lh !. Mh Nh Oh re Ph 3f 'g 5g Cg Qh Tg Rh Sh Th Uh Vh Wh Xh Yh Zh `h i .i +i @i #i $i %i &i *i =i -i ;i >i Qh Cg lh 'g 3f Fe ;e ed Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ) }. y# !. !. !. !. !. !. F[ a / T &+ !. !. !. !. !. !. !. )^ o+ { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { < ) { ! ! ! ! ! ! ! ! ! _ ! } f+ l+ `) {> n ] < n O. U J ,> j( y. 1' ,i <7 f. 5~ /{ T} !| B, B> j| O~ W2 Q< 2c O~ k} k} k} O~ q^ [^ O~ }{ k} k} k} R_ z> s^ k] L3 i] 12 z4 R_ 0[ E, A{ U< 20 .^ M! !. !. Fb 'i >6 q} ~| &4 p7 9~ >] f) J/ !. !. !. p, <: |{ O~ D> W0 N_ R_ z{ z{ M< )i $+ !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: v[ !i ~i {i ]i ^i /i (i _i @| :i 81 T: T: i8 m] h| I! q} t} O~ 9~ O~ O~ Q~ r^ -] E, k} D> D> [< E, << D, ^1 }2 ~} U] E, a[ x> N_ Re R_ Mi Ni d_ Oi af Re M[ l| w' 9~ Pi }2 e| m| =6 Qi !. !. q. Ri d| O~ N< J< B> *] 0~ f_ Si t' p, !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: j[ &9 Ti 23 Ui Vi ;3 Wi )8 Xi Yi =3 T: T: E} Zi `i j .j *c +j @j #j 16 ic 91 $j T: T: T: T: N4 %j &j *j =j -j q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. 1* a' ;j >j ,j u Z 'j )j !j ~j {j ]j ^j |h Ei /j (j _j :j ( !. !. !. !. K$ {2 L@ hj ij u, yb m; s1 t1 N~ 0~ l} f) v{ Q~ n] [< 9~ 9~ jj C, X] J< 0~ y> z> N_ N< O~ k} 9~ z> v{ 0~ (< p} -] 1: t} kj f_ /1 U] a[ O~ k} *] k; N_ W^ l; z5 U6 |: R6 lj +/ !. q; |7 (1 }< Y] Q_ q^ X] y, T| [< B5 !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: mj nj oj pj qj rj h4 H6 sj |} T: T: T: T: T: pf tj )8 y[ t[ uj fb vj wj V9 V[ T: (6 (4 05 xj yj zj Aj Bj Cj N* Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. 1* Ej X[ N7 '= < ! Fj Gj Hj Ij Jj Vg Kj Lj /j Mj Nj Oj Pj Qj Rj Sj Tj Uj Vj Wj Xj Yj Zj `j k .k +k @k #k $k %k &k *k =k Sh |h -k 3g Of 3f Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { f+ 8] !. !. !. !. !. M! O. ! ^ Y+ ^@ !. !. !. !. !. !. i+ ,> 9 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ~ h I }# 9. p# i _ _ ! ! ! ! ! ! ! _ d P N^ n@ Z) J@ o+ 3 ^ a $= !) k t q e _ ! ! ! ! ) ^ L j+ !. !. .; ;k >k T. !< p2 [- ;0 i] _} L3 K< W^ J< t1 q} ^< *] w' 0~ n] h| 0~ l] W^ E, U] t^ 1: O~ t} Q~ }< 9~ k} 9~ O~ z> [2 0~ N_ Y] N_ ;] O~ e| ,k k} T] Q< W^ o1 D, ;] k} 9~ 'k z> )k K/ ./ z: U7 r} K_ 0g !k 7- d~ 85 ~k {k ]k !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: Y2 ^k M5 /k (k _k :k i [h Hi Pf yf ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : [. )^ !. !. !. !. !. /@ z. { ( R ]) !. !. !. !. !. !. 1/ O : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ e }. }~ 6] ]. T@ `) A/ r 8 _ ! ! ! ! ! ! { 1 1' !. !. j@ s. ;| v. _~ A/ {. @= U@ g+ 8 _ ! ! ! ! ! ! { ( z. 1/ !. c$ 9$ Jk e. Kk p2 F3 55 V] k| t} ;] N~ 12 << 4< t} R_ A> :< }2 *] N[ t^ 9~ t} :{ :{ z> }< (1 (1 z{ O~ [< S| E: Y] l; L[ }2 C> z> Q~ M[ B> f_ _| O~ z> l6 9[ s1 ~} B> m} Lk H: T| Mk Nk X8 << T7 12 Ok e; !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: X3 @[ S: j[ T: T: T: T: T: T: 8} t7 03 Pk Qk C4 Rk R: @} 7^ j[ T: T: T: @} {5 Sk Tk Uk Vk Wk Xk #: pf Yk Zk B8 `0 `k l .l +l @l #l +* $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. /& %l &l *l #- Mc ;e =l -l ;l 4g Ug >l ,l 'l )l !l ~l {l ]l ^l /l (l _l :l !. !. !. !. !. !. !. !. !. !. k+ 5 ) ! ! ! ! ! ! ! < c n@ !. M^ g* dl e. el R0 !| ]< :< N_ }< k} D> D> [< m] k} k} O~ m] N_ q^ ^2 }: D> ;] N~ -4 K_ q} a[ Q< J< 22 E, J< R_ [{ U] W^ .5 y> fl m} |2 8g 38 gl 8~ [{ J! A{ |: 7[ K[ <: [2 a[ ^! l| z> p] W^ }< (1 (1 yb hl !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: X3 #^ il bb H2 bb jl y1 T: T: T: T: T: T: U} 7^ 8} @} kl ll ml nl ol 05 x| E7 @} pl Y3 ql rl sl tl ul vl L8 K8 wl xl c4 yl zl Al Bl I7 Cl Dl r+ $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. /& El Fl ! $- ed ;e Fe 3f lh Cg Gl Hl Il Jl Kl Ll Ml Nl Ol Pl Ql Rl Sl Tl Ul Ul Ul Ul Ul Ul Vl Vl Wl Xl Yl Zl `l m .m +m _j @m #m Kj [h Bg Pf yf ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ P. w! !. !. !. !. j@ x. 9 { : g Y( !. !. !. !. !. !. ;| q# : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { W )) !. !. !. !. !. !. M! u! '. : _ ! ! ! ! _ : m b, ]) y# l@ %+ !. !. !. !. !. !. S@ 8. { : ! ! ! ! ! ! _ { <. *( k) $m %m U. s4 m1 44 &m :< N_ }< k} t} t} N< i| k} k} k} i| O~ (< A> Q[ T] q^ N~ ^! 1c 3= *m !6 =m [- Re U< r} U< (< ]2 << y> A, << q^ Cb e_ -m ./ ;m j3 F> 6[ 44 >m Sc ,m >6 64 z> q} N_ D> T| Q~ z5 Z4 [2 b~ !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: X3 (6 'm )m !m jg ~m {m ]m A0 E} T: T: T: T: T: T: X3 l[ ^m 58 qc Ya /m 29 (m _m :m K< !( Cm !. !. !. !. 2= k3 A{ U] =] B> o7 (< Y] W^ J! |: Dm !. !. !. !. !. C{ b[ Em !. !. Fm ,] 9~ T7 a[ ]2 9~ w' q} Q~ N_ m| S7 3: !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: (6 Gm Hm K2 Kc Im =2 n< H} Ad /9 j[ T: T: T: T: T: O4 Jm Km Lm Mm #g Nm Om 82 Pm $< e5 o3 o3 Qm Rm Sm ^k Tm T: T: T: il Um C7 m/ Vm S3 Wm Xm Ym N* Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. *= 7' Zm t_ `m '9 Fe yf 5g 3g Gi n =k .n +n @n #n $n hm %n &n *n =n -n ;n >n ,n ,n ,n ,n >n >n 'n )n !n ~n {n xk ]n ^n /n (n li =k Ei Tg Cg 5g Pf Fe Mc Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 5 [* <' !. !. !. !. ]) z. : _ ! ) S 8] !. !. !. !. ~. x. b : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { V u! !. !. !. !. !. !. /@ ;+ ,% p : ! ! ! ! ! ! ! < ] < { : 6 h m ,> M! !. !. !. =+ k _ < ! ! ! ! : : J@ l* _n :n D, S1 w> Q~ O~ k} e| O~ k} N_ N_ O~ |n N[ Q} 1n !. !. !. !. !. !. 2n I3 }2 l] W^ o1 w{ B> 0~ [{ /2 :< H/ !. !. !. !. !. !. !. !. !. !. 3n 4n 'k }{ k} R_ (< l] r] N~ D> S_ 5n $+ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: 81 if 6n 7n 8n 9n 0n an z8 @8 5i e2 /9 T: T: T: T: T: t7 bn _* 61 ]d cn uh dn 5e en h2 xc G2 fn c3 gn hn '8 ug T: T: T: T: x| in jn kn ln +j mn nn c& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. *= - on pn e Ph 'g lh qn Kj rn sn tn un vn wn xn yn zn An Bn Cn Dn En ,n Fn Fn Fn Fn ,n ,n >n >n om Gn ~n Hn In Jn Kn Ln Hk Mn Nn hi qn lh Pf Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ S U@ q. !. !. !. !. z# t : _ ! < c !{ !. !. !. !. k@ Q. _ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 3 i( h+ !. !. !. !. !. }* u 8 ! ! ! ! ! ! ! ! ! ! _ _ _ : { < 8 W l+ w! !. !. q. b_ >+ 0 ^ { _ < < ) '. On M% A< 7' U. [n s{ p( e) ~} 54 S| B> }2 U] O| r8 N~ q^ B> N_ m] l} &4 O~ k| Q~ (1 a/ h+ !. !. !. !. !. !. R} s, 0~ [< L3 x2 W] << U] /1 Pn d) Qn Rn Sn Tn .^ r. !. !. !. !. !. md U] Pn k} N< P} N< 0~ :{ z> >] H! e; !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: jl Un _] og Vn Wn Xn 1a %j )5 c4 Yn kc ^5 T: T: T: T: v[ fe X[ t0 Zn `n o .o yj +o @o #o $o %o >8 sc &o $} X3 T: T: T: T: T: !7 @a *o =o -o ;o >o d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. z& ~% ,o 'o )o 'g 4g !o ~o {o %i ]o ^o /o (o _o :o n nm Ul |l 5o ]n ^n .m +m 6o Th 7o Ug 3g Pf yf ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! P ]) !. !. !. !. M! X+ 7 : ! ! { d ]: !. !. !. !. s. a. ! : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : U Z{ !. !. !. !. !. i+ q# ^ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : p 0. {> S@ !. !. w! ,> 1 9 5 j | ( x !{ !. 8o ne f. !< `g p( Bm O| N_ P| D> q^ T| << q^ ^1 N~ &4 l; T6 ~} :{ 7[ :a B> A{ 9o !. !. !. !. !. !. !. !. 0o S1 |: R_ q^ ^1 ^< T1 R_ g9 }{ [^ l] x> r] ao bo co do !. !. !. !. eo B> T< O~ k} k} m] w' ^! 22 :: fo !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: jl go ho io jo w< 5( ko G( lo p_ mo F0 Z1 7^ T: T: T: X3 bb no oo %0 %3 po d4 qo ro so to uo E) vo C6 wo xo yo X3 T: T: T: T: 7^ zo Ao Ed Bo Co Do ~+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. z& n& Eo Fo Go 'g 3g Ho Rh /j 6o xi Io Jo Ko Lo Mo No Oo Po Qo Ro So To To To To To To Uo Vo Wo Dn 'n Gn Xo Yo Zo `o p wi _j =k ii Gi 3g Ii yf .p ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g <. w! !. !. !. !. 1/ a. { _ ! ! < 3 %= !. !. !. !. `) 6+ _ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : { b. b_ !. !. !. !. r. _~ ! : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < _ o 0. z# T@ z# b, b, K@ L u. u. L r }* !. )& !~ +p !< c_ p( Bb I! Q~ P| N_ z> Q_ p} q^ O~ D> k} t} r} T] I! N~ W^ W2 |: V< !. !. !. !. !. !. u2 I/ @p l} 1: #p T| [< w' r^ k| p] ]2 D> e| }{ z{ 1: U6 m] G< J> !. !. !. {6 $p x> |: kj k} }{ k} Q~ g_ %p &p !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: 05 &2 y[ *p =p z_ x_ x_ 3( +j -p #< Ed ;p N4 T: T: T: T: 7^ >p ,p 'p )p rc W: 0b !p ~p {p ]p 1( Y' ^p vc /p b1 (p E7 T: T: T: X3 &5 _p :p

n )n Vl hp ip `j jp kp lp mp #m Tg Cg 5g 3f Am ;e ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : e a@ s. !. !. !. r. N^ m : ! ! ! { 5 <# q. !. !. !. )^ R. : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ! P. &+ S+ S@ !. !. ^) 4 ^ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : ] ( j Y# m+ b_ S+ j+ 6+ <# !. {> -+ H, !. np op L@ 5~ pp v, B, l} ~| P| ;] N[ d| Q_ p7 k} Q~ m] (< E, 0~ i] z> D> V2 22 qp c~ !. !. !. !. !. 3^ u, 0[ z> R_ |8 Q~ R_ Q~ w' N[ B> N~ E, rp 6[ W2 J< >6 9~ m| T} sp !. !. !. tp up vp wp 9~ B> 1: 5< T< r] H/ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: 05 xp yp zp #a Z: x_ x_ :_ Ap Bp .: Cp 7a k[ T: T: T: T: T: f< C4 Dp 71 Ep Fp Gp Hp Ip c3 Vb Jp Kp Lp Mp Np *2 Op Pp A0 X3 V[ Qp D} Rp Sp Tp Up Vp s+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. S. /* Y. Wp Xp Ge 3f 5g [h Tg fh Yp Zp `p q .q +q @q #q )n $q %q &q *q =q -q -q -q -q -q -q ;q >q ,q 'q ,n om )q |l xk !q ~q Ln {q (j rn Kj [h lh 3f Fe ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : x $= %+ !. !. !. <' X+ ~ : ! ! ! : { @& `) !. !. !. /~ K { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < 7 N Z( I@ ;| !. ^. I 6 { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { ! Z U+ !. r. !{ l+ i+ x! v! !. !. 0$ _& L@ [n /- !| ]< w' ]2 P| }< O_ Q_ z4 }< k} }< R_ }< (< z> k] u4 E, C> z4 a[ <3 !. !. !. !. !. q. ]q Q~ ;] k} 9~ m] D> z4 N_ w> :< W^ A> l; z> N_ W0 w{ r] O~ g_ K_ $p 3{ ]k !. !. Yf b/ U] l7 A: x{ U6 w4 $5 !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: h5 Y9 ;5 ^q /q }_ Va x_ G( (q *h _q :q @} T: T: T: T: T: T: T: X3 E7 y1 $d (4 05 91 *f q qq 'q ,n 'n Gn rq sq tq uq vq yi bl Nn ~o wq Bg Pf Fe ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 6 D< ~. !. !. !. ~2 O _ _ ! ! ! ! ) y =+ !. !. !. z/ f+ : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < d V p [# !. r> b_ _@ y ( : ! ! ! ! ! ! ! ! ~ _ { : : ! ! ! ! ! _ < _ 6+ -( !. !. h+ >( 6+ _@ !. !. _' %6 L@ '( ~< $] F3 xq Y] t} D> l] L[ T1 O~ k} i| k} k} N< 64 s} :< *_ E, t} |{ m; d; !. !. !. !. !. lj .5 M< O~ 9~ T| 9g J! t} Q_ << << T| (< yq B> U] q^ >4 zq q^ (1 T< T9 Aq Bq p, !. Cq Dq M_ =m p, Eq g) Y^ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: Fq Gq Hq Iq y6 Jq D( v= k< Kq Lq yh $} 7^ T: T: T: T: T: T: T: T: T: T: T: T: j[ X3 81 $} Mq Nq t< Oq Pq G} Qq Rq F^ Sq Tq Uq s< Vq Wq t6 Xq Yq Dl r+ $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. S. %( Zq @] `q r e Fe 'g lh wq |h Nn bl .r jq ~q ]n +r rq !n 'n @r #r $r %r pq -q -q -q -q -q -q pq >q qq 'q Fn 'n !n &r *r um uq .m yi %i {o ~o wq Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : e J@ ^@ !. ~. /@ w. q { ! ! : : ! { 9 _. r> !. !. r> += d : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : _ { b. s. !. !. b; Z{ 5+ ~ _ ! ! ! ! ! ~ ~ ~ c 5 _ : { _ ! ! ! ! ! : < L j( S@ !. `) _. ){ !. !. }= ha `* =r `g 8g e) -r ;r N~ B> T| (| La z> R_ N< k} k} ;] Q_ U< k} W^ Q< K< R_ R9 o1 >r _2 T~ !. !. ,r 'r ;] (1 O~ N_ ~} v{ Q_ Q_ z4 m] r^ Z] K< N~ z> Q< 0~ r} Z] l} U] t} Na q^ F: Yf !. !. :^ )r !. X1 #/ X| !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: @} !r >h -5 ~r {r ]r =8 ^r /r J2 (r |1 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: S: 05 _r :r q ,q 'q Fn 'n nm &r Yo Zo .k gr hr Ik ir gj wq Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : u l+ /. [# Q. u ~ _ _ ~ 6 x _ : _ P. `) !. !. h+ g^ b { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < W A/ !. !. !. !. 6] I < _ ! ! ! ! ~ ~ _ o+ v. <# 9. p ) _ ! ! ! ! ! _ ] d a. (. i+ !. q. !. h+ K$ ne f. ^{ 6~ u, g) r] N~ N_ 54 0~ p7 x2 x> ^< << a[ n] =] l| N[ q^ z> ^2 jr w' z> m| S| s^ ,m .^ !. !. kr ]1 w1 22 E: V2 0~ V] o1 T] ~| W0 :< -] U] }{ B> B> [< N_ J! ^! [2 =] T< g9 p1 M$ !. K/ Gb t] lr mr !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: il E8 nr 7n Y0 or pr >2 qr rr E^ sr tr T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: U} @} !7 G} R4 e8 ur vr ;c wr xr yr zr Ar Br Cr U} Dr Er -* 7r 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. U. F$ Fr Gr Hr r ;e Fe 'g lh Vg |h {o %i yi gr ^n um *r &r nm 'n ,n cr Ir Jr Kr -q -q -q -q -q -q pq >q ,q 'q Fn 'n nm Vl Yo Zo .k 9j hr Ik Th gj Vg Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ a V p ! { _ ! { 5 0. $= o { < o l+ b; !. q. m+ c { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : e [* j@ !. !. !. M! ,> _ : ! ! ! ! ! ! < 7+ T+ !. {. 1' T : ! ! ! ! ! ! _ ( 1 _@ '{ X( %+ !. .; J% Jk U. Lr Mr u, <] w{ (< k} T7 E, w' p7 m] N_ L3 W0 V2 N~ :< }2 0~ q^ U< (< J< q} ^1 z{ R9 Z4 Nr !. !. !. c; Or z> B> ^< T] << U] O| A, w{ p] T] i] g_ z{ 1: e| N< d| k| 9[ X] w' O~ _} P9 +/ !. !. Y1 `] U1 !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: &9 Pr kf Qr Pb Rr Sr ![ Tr Ur Vr Wr |3 7^ T: T: T: T: T: T: T: T: T: E7 k[ X3 T: T: T: E} D9 d: Xr dc Yr !h Zr `r s .s +s @s ng #s $s %s +@ 7r 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. }, &s -( l0 r ;e Fe 'g lh Vg gj ir %i *s gr ^n um *r &r nm 'n ,n =s -s ;s >s -q -q -q -q -q -q pq >q ,q 'q Fn 'n nm Vl Yo Zo .k 9j ,s Ik /j zm Ug Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { { { : ! ! _ : S U@ T@ a@ : : < j =+ r> '{ q# 7 _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 7 _~ S+ !. !. !. S@ >+ _ : ! ! ! ! ! ! { w !{ !. !. !. !{ 4 < ! ! ! ! ! _ ) . }~ [. W V+ !. .; 's )s f. !s ~s M_ v, q} B> }< T7 ]2 x> v{ O~ O~ O~ 9~ k} (< E, }< }< N< 9~ O~ N< N~ q^ R_ O~ H: i9 {s !. !. !. E{ j3 l; 6[ U] U] J< *] Y] :< <1 *] r' ]s ]9 [< e| t} t1 l] W0 << ^2 w' }{ [< E/ p, !. !. q; 6= !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: E} t7 Pr ^s /s (s _s :s q ,q 'q Fn 'n nm Vl Yo Zo .k 9j ,s Ik /j zm Ug Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : g $= @= !. -| z < : ~ g+ G~ Y 6 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : _ [. l@ !. !. !. r> !) { : ! ! ! ! ! ! _ ) 5+ %+ !. !. x! U ] ! ! ! ! ! ! _ x 0 _ ] :. gs k) l( }% `* hs is s, d) M~ L< t^ D> J! T| r^ N_ }< }< k} 9~ W2 N~ k} k} k} k} k} [3 N_ t} }< n] R_ kj js q. !. !. !. y2 d) V2 0~ ;] l6 9[ ks (< s} (< B{ 3: Wf v2 u4 1: 0~ }2 _} U] B> z> U< A{ _| I< Y^ $+ !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: N4 j4 ls ms ,e ns os ps qs c3 _* rs t7 T: T: T: T: T: T: mj ss ts us vs ws {5 N4 T: T: T: T: (4 4e xs wo #f ys zs As $< Bs Cs Ds 35 q+ $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. h. 6$ Es !. Fs Gs re Fe 'g lh Vg |h {o %i yi gr ^n um *r &r nm 'n En #r Hs Is fr -q -q -q -q -q -q pq >q ,q 'q Fn 'n nm Vl Yo Zo .k 9j hr Ik Th gj Vg Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { x p@ 9] !. z/ 7+ : _ _ : e ~ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : w [* ^@ !. !. !. b, 6 ( _ ! ! ! ! ! ! < w Z( <' !. i+ =( } { ! ! ! ! ! ! _ < < x I@ M! >) Js Oe U. n, 6~ !| z: S1 s} (< }< A> K< Ks O| w{ 0~ N~ Q~ N[ }2 T7 k} k} k} m] P[ J! x> B> E, 0~ 'k H! Ls !. !. !. !. ]} << E, m6 a[ Q< (< }2 E, Re Ms K/ !. ]k 8 i; >4 ;] M< :{ Q< << (< P} 9~ o] x{ Ns U~ !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: w} Fq Os Ps W} =o Qs Rs Ss Ts Q3 Us _4 8} T: T: T: T: X3 Vs Ws 0b Xs 6} wo qg Ys v[ T: T: T: T: #^ Zs `s t .t +t @t #t ]r $t %t &t N* Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. *t ~- !. /. =t -t Fe 'g lh wq |h {o ar yi vq ^n um *r &r Gn 'n cr ;t >t ,t =q -q -q -q -q -q -q pq >q ,q 'q Fn 'n nm &r Yo Zo .k gr hr Ik ir gj wq Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ~ Y# P^ !. 9, Q _ _ ! _ : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) | ,{ S@ !. !. k@ Y# 7 ) _ ! ! ! ! ! ! { } p@ k@ !. >| j ( ! ! ! ! ! ! ! : : }# ~2 !. H| I% '% U. a| I[ s, v} ,6 a[ 54 }< =] }2 q^ T1 l; E, A> Q~ >6 x> E: k} k} k} B> x> T1 A, :{ N_ N~ g_ f) Yf !. !. !. !. J/ M~ O~ g9 ~| q} Q_ x2 A, R_ e| 5^ !. !. !. 't x{ Q~ D> (< ^! -] <1 :} k} e| D> k} k] )t !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: N4 !t ~t {t ]t k< B( ^t /t (t !i K8 T: T: T: T: E} t7 J4 n< *: ;7 _t :t q qq 'q Fn 'n !n &r *r um uq vq yi %i {o ~o wq Hi 'g Fe ;e Mc ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ < K x! !. ]. f+ : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < | [* {. !. !. `) [~ R e : ! ! ! ! ! ! ( p ]: !. _# M ] ! ! ! ! ! ! _ ] 1 !{ !. !. bt P2 ct U. F< o( $] ]< f) :< ^e Q_ q^ S1 :< O~ 9~ O~ O~ O~ (< r^ p7 }{ k} O~ R_ a[ T6 B> .5 }2 z4 22 *] dt !. !. !. !. f; ,6 9~ O~ T7 U< h| W^ _< 0~ T< s1 et !. !. c~ }1 *] |2 O~ Q~ z> Pi :< R_ P} Q~ S| ft u, Kb !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: y1 gt ht #2 it D( jt kt lt pg Ys K8 T: T: T: T: T: mt V: J2 nt ot Fq Y0 23 pt 9} T: T: T: T: T: 81 qt rt st tt ut vt wt xt yt ~+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. f. H$ L6 h+ V@ zt At Fe Pf lh [h >i fh &i Bt Ln Ct Dt lq |l Gn om ;n Et Ft Gt pq -q -q -q -q -q -q ;q >q Ht 'q ,n 'n Gn It sq kq uq .m Jt bl Nn |h -k Bg Pf Fe ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) V u. !. t. . { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] } _. M! !. !. $+ 6] f+ ^ _ ! ! ! ! ! _ ) J _. I+ 9 : ! _ ! ! _ < { u ,{ ^@ !. !. x# Kt 7' U. [n Lt 44 S6 Mt kd (< B> z> Q_ N~ k} k} k} k} [< Q~ ^! [} h| ;] t} O~ =] w' O~ l; r^ Q_ s} U6 p^ J3 !. !. !. fo j; Nt |: O~ O~ g9 t^ :< T1 N_ u} =6 Z6 !. !. Ot Pt A{ 0[ l; D> Q} [< N_ D, Q_ z> A{ L~ V_ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 7^ zo Qt 3a Rt Xn c! St Tt Ut (r P4 T: T: T: T: T: 7^ a7 Vt Wt Xt Yt Zt kn `t u V[ T: T: T: T: T: :| .u +u @u 5a }s #u $u %u c& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. U. &u *u !. {: =u dk -e 3f 5g Cg Tg -u ;u >u ,u 'u .q ip 1l Ul om En )u !u ~u {u -q -q -q -q -q -q ;q >q ]u ^u En )n )q |l xk !q ~q Ln {q (j rn Kj [h lh 3f Fe ;e ed ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { L '{ !. (@ K { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) 2 )) h+ !. !. !. 7] M ^ ! ! ! ! ! ! ! : 7 : ( ) ] ] ) ( 8 ~ Z %= 6] x! i+ !. .; /u {2 U. [n Mr (u T_ w' N_ _u T7 E> B> O~ k} k} k} k} D> N_ Pi r^ :< J< 0~ |8 V] f) q^ ]2 T| >6 (| z> T< :u S} !. !. !. t8 [- N~ }< K< l} N~ A, ~} }2 t} n mu nu ou pu qu qu qu qu qu qu ru su tu uu -n vu wu 2l In `j xu kp lp yu #m Tg Cg 5g 3f ;e ;e ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : w $= ;| !. 7] j { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ( L ]. !. !. !. !. n@ 3 ] ! ! ! ! ! < c @& 8. k 2 . Z r Q 9. O^ t. r> >( _. {> !. !. f' !~ U. n( p2 $] zu 1{ U< j| }< :< l; O~ k} k} k} k} k} k} X6 q^ ;] M< r} U< a[ :{ T] z> J< u1 N[ z> 1: g_ O9 Au !. !. !. p, Bu *] q^ l] T] *] v{ w> l] (1 Z4 ]e o} Cu r2 w1 B> 0~ U< << {| U< N~ E, 0~ B5 !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E} W3 Du ^q }q Eu Fu Gu _s Pb Hu Iu U9 X3 T: T: T: j[ &9 p| Ju c3 Ku Lu Mu Nu 91 j[ T: T: T: T: j[ Ou Pu Qu Sa t[ Ru Su K6 c& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. )< Tu h1 !. !. !. Uu Vu Hj Wu Xu Yu Rh Zu Ik xi gr `u um *r rq Gn om >n v .v +v @v @v @v @v @v @v #v $v %v &v *v =v -v ;v >v ,v 'v wi _j =k ii Gi 3g Ii yf .p ed ! : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { w _. M! !. a_ M { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! < x j( !. !. !. !. b; [# e { ! ! _ { ^ [. z/ j@ >| m@ b_ &+ 8] s. S@ ~. !. !. $+ v! (@ !. !. L$ )v f. 5/ _3 @5 n; !v l; ;] D> :< Q_ 1: O~ k} k} k} k} k} w' [{ 1: O~ O~ g9 E, y> n] ;] Q~ z> ^! l} J< N_ A{ U0 <' !. !. !. o} ~v Pc ;] {v 9[ d| ^e M3 Q_ z5 r} F: ]v V] g_ N_ x> L3 o] v1 Z4 W^ _< A: K/ !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: :| cb 13 og ^v /v e7 (v _v ;8 %[ :v 7} E} T: T: T: X3 u[ f) x> B> l} 0[ r} N_ O~ 9~ O~ O~ 9~ W] U] 9~ k} k} O~ C> }: E, g9 k} k} M[ 9[ p} U] E, A{ j3 !. !. !. !. ,r M_ T< Q~ Q~ ;] R_ C> |2 l} m] [< q^ <2 Pc T7 z> W0 U6 N_ G3 zv ./ Av o^ T~ !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 1s Bv Cv vj #2 Dv Ev .[ D2 Fv Gv x8 &9 T: T: T: T: 8} a7 Hv .f Iv Jv Ys Kv Lv e< /9 9} Mv Nv Ov Pv Qv fb +j Rv Sv K6 d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. n& P] Tv Uv Vv 1/ {( !. !. !. Wv Xv Yv Zv `v w .w +w @w `o zk #w rq $w %w &w *w =w -w -w -w -w -w -w -w ov Po ;w >w ,w 'w )w !w ~w {w ]w ^w Nn /w (w _w :w Fe ;e '9 [{ y> l} _< -] U] Q_ q^ [< :< c| O~ 9~ O~ O~ e| _} N~ 9~ k} k} }{ }< x2 w' *] t} 9g Ka !. !. !. !. c; s' z4 1: R_ ^1 N_ g9 R_ }2 |w 5: 27 1w :^ Or cg 2w ]- -_ X1 !. 3w ]} up h+ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E7 a3 4w |t sg 5w `[ 6w 7w c7 8w ![ D9 T: T: T: @^ %2 Bv 9w 0w aw 8 gw hw iw jw kw I6 lw mw nw @* $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. S. z& ow J3 {: i+ {. !. +/ pw N$ qw rw sw tw uw vw ww xw yw Dt ip Hn rq zw Aw Bw lv nv nv nv nv nv nv nv Po Cw Dw Ew Fw Gw Hw Iw Jw Kw Lw Mw Nw Ow Pw Qw Rw Sw ed < i Z{ @= l+ 1 9 } ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : 7 Q. v! r. !. #= W < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! g+ g^ ]. h+ !. !. !. }~ r C< 1/ r. ^@ <' !. !. !. !. !. S@ ]. 7] ^) <# #= s. !. !. !. !. !. e' ha f. Tw Uw !| %p T] =] v4 }2 W^ :< W^ :} }2 U] :< p} 9[ i] r^ W^ W^ 0~ Q~ 1: S1 p} m6 O~ k} k} O~ T1 ^2 L3 S| _| Ia !. !. !. !. !. Vw Ww U7 e| *] J< g_ H3 Xw Ls !. =& Yw h+ h+ =& !. !. !. !. !. !. c; 't e_ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E7 $1 Hq C2 Zw X/ `w x g8 .x vt +x 8} T: T: @[ '[ @x #x v7 $x %x W: &x *x vc `| @< =x -x ;x >x ,x 'x )x !x ~x {x 7r 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. S. 4$ ]x >) !. -( @& Y( ^x /x (x 6% _x :x w cx dx ex fx gx fm hx ix jx kx lx mx Qh nx ox px se Q_ T1 M< 9~ k} E: S| 0~ D, ^! S1 r^ _< Q[ q^ ^< Pt N[ (< k} O~ sx Q~ r^ s} 1: Si T} T~ !. !. !. !. !. tx N~ A{ ux 22 54 T] vx !. !. !. !. !. !. !. !. !. !. !. !. !. !. c, M$ !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: 05 3m wx xx L( $7 s3 ab yx sc zx a3 E7 il qf Ax Qu e5 >8 Bx Cx Dx Ex Fx Gx Hx Ix Jx Kx Lx )3 Mx Nx Ox Px Qx -* 7r 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. T. 4$ 2% M% !. g^ _ d Rx Sx !. %$ o* Tx Ux Vx Wx Xx Yx Zx wm `o ]n `x y .y +y Ew @y #y #y #y #y #y An ,w $y %y &y *y =y -y ;y >y ,y 'y )y !y ~y {y ]y ^y /y 9d h ^) ~. {. >( ~2 -+ I+ h : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 3 4+ 1/ !. i+ n+ e : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ) e g+ W+ b; !. 1/ Z) ){ s. v! P^ !. b; =+ P 2 ^ ) ) ] { { _ p K@ >| u: k) J% Jk U. (y 0f #_ 5[ v4 ~| }< k} k} l; *] k} k} k} k} O~ (< << a[ U< (< E, ^e T| z> 1{ K_ r^ -] p7 6[ [< :< :< R_ U7 }2 _y q. !. !. !. !. y2 G! J< :y 95 X2 t8 P! !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: ~5 U< S| D> z> _a s} Or Sn c~ !. !. !. ~( a/ }1 .^ .; Y1 h+ !. !. !. !. !. U~ tx Qy Ry G: Sy 3n !. !. !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: @[ Ty Uy e5 $b Vy Wy D( Xy Yy {7 }9 Zy Tr }q X5 `y z H( ko `w z} c1 .z +z @z #z 7( $z %z 67 &z x_ *z =z -z r+ $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. S. e. ;z H] !. 1' b w { >z ,z 'z d$ )z !z ~z {z ]z ^z /z xi jq xu uq (z _z :z k] .A O~ k} k} i| [< w2 +A O~ k} k} O~ p7 T] R_ k} R_ M< k] :{ 6< N_ <} l6 @A 1< !. t] <3 #A $+ -m e_ !. !. $A :: U< Re k| l] z> 9[ Pi H: e| %A U~ !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: Y2 &A *A D0 2} =A -A ;A >A ,A ul l 'A )A !A ~A :_ {A ]A ^A /A J2 (A _A :A ( I+ j+ !. !. r. Z) } : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { { C< b; !. !. !. !. r. ,{ p < ! ! ! ! ! ! ! ! ! ] k >| !. H| vA Z- U. !s a~ B{ j} O| P[ P| O~ }< 9[ :< R_ k} k} O~ }{ V2 ^! wA O~ k} k} k} 1: w' S1 }< k} k} k} q^ E, k} k} O~ O~ O~ N_ y> m; :{ f_ B> xA !. !. !. yA !. !. !. !. h+ zA >] 22 k} M< y> V] D, q} q^ |: AA R~ BA !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E7 Y| Gq {d CA qj sg DA EA [| FA GA r6 HA IA C| JA .t KA Vi LA .g mg (6 MA !r NA L0 <4 qs OA PA QA N* Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. T. 4$ RA SA I+ 4+ 5 ) ! Mc re Je TA UA 7% VA 7A WA XA YA ZA `A B .B +B @B #B $B %B %B %B %B %B &B *B =B -B ;B >B ,B 'B )B 0= !B ~B {B ]B ^B /B (B Mc _ ! { ] ). Y# F[ x. 5 < ! ! ! ! { ). n{ V+ [* K@ += I@ b. 4 : ! ! ! ! _ { ). ^) !. q. ;( $= T@ !. !. w. 4 { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { 4 Z) S+ !. !. !. !. ){ j { _ ! ! ! ! ! ! ! ! _ ) }. l@ !. x# :n 7' U. F< _B :B t' zu x2 k} }{ t} 9[ i] P| O~ 04 |2 M< h| [2 0~ }{ O~ k} k} 9~ U] x2 t} i| k} k} Q_ L3 T7 }< ;] R_ 9~ O~ k} {| s^ }: AA I< 3n !. !. !. !. !. !. !. 2= _{ Z4 9~ C> N~ 0~ :< q^ [< P} q^ 4< T] et !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: E7 ee ( >+ } : ! ! ! ! : } _. r> !. {. N^ )^ !. !. [# d { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { v <# T@ q. !. !. !. U+ q# _ : ! ! ! ! ! ! ! ! ! _ ) S ;| !. x# GB 7' U. [n p2 d) X] [2 X8 w' 1: 1: l; }2 O~ O~ N_ S1 r] T1 *_ 5[ y> /1 O~ k} 1: p7 i] m] i| k} k} Q_ E, O~ S| k] T] 9~ e| R_ Q~ _} s} f_ N~ HB !. !. !. !. !. !. r. :b M< Re k} Q~ [{ p7 ~} 8~ E, }{ (< z> p' IB !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: ^5 x] JB KB LB t| @3 MB <_ r3 NB G1 m/ OB (p E7 T: T: T: T: T: w} n9 PB QB +6 RB SB TB d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. f. UB VB WB XB I| W { _ '9 '9 C ,C 'C ii )C !C ~C {C ]C d$ !. ^C /C (C _C `m ! : 4 >+ ~2 !. !. !. #= b ) ! ! ! : ) P {. !. !. !. !. !. !. a_ t { _ ! ! ! : x O^ M! !. !. !. !. !. !. w. 5 < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ) { _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { ) G+ q. !. !. !. !. )^ a. x : ! ! ! ! ! ! ! ! ! ! _ ) R. w! !. v: :C z& U. [n p2 #_ u4 }2 1{ K_ r] ]2 V2 U] N_ z{ N< T1 }2 [{ a[ p7 O~ }< [^ -4 E: t} W0 J< M3 W^ 9~ g_ =4 =& !. !. !. !. !. R} !| n] p] m] B> N~ X6 [^ ^! q} =] o] W2 / !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: Ou [C ec v_ }C MB x_ I( 02 |C 16 l4 c: N4 T: T: T: T: T: T: j[ |} 1C (s Qm E} 2C cu ~+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. f. E% 3C 4C 5C Z( ` ] 2 6C ! fd ed 7C 8C 9C 0C AB d$ aC bC O$ cC dC eC fC gC Kg Kg Kg Kg gC Vx hC iC jC }h Ug kC lC mC nC oC !. pC qC -t ed :c : 2 ,{ ~. !. !. !. !. &+ R. 8 ! ! _ { 8 p u. !. !. !. !. !. !. -( J { _ ! ! ! _ ! P. i+ !. !. !. !. !. !. U+ [. ~ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ g ). r 9 < : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ { : 6 o@ !. !. !. !. S+ _. 9 { ! ! ! ! ! ! ! ! ! ! ! _ ] '. 9, !. 9$ ={ n& Z= [n p2 #_ T9 U] J! Q~ I! ^! C> 0~ *_ T| r} Q~ z> l} w{ >4 {| [2 U| 1: kj E, rC m] 9~ E: p] _< -] k} e| 1: k} M< =] B> ;] 0~ K[ W0 N_ U1 sC !. !. !. !. tC uC w' k] *_ << N_ k} R_ E, y> x> N[ o] l6 vC !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: /9 wC #f xC yC oz J( Y} zC AC |t BC &9 X3 T: T: T: T: T: T: T: 05 CC ec DC >2 EC FC ~+ Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. f. ne GC HC q 7 c < ). I@ k IC fd 6f JC KC LC MC NC N% OC VA PC QC RC [g SC SC SC SC SC SC Ux PC TC UC VC 4g 4g ;l WC XC YC ZC `C D .D ! _ _ 1 Z) 6] b; !. !. !. !. _@ ] f ^ : s [. 1 X( !. !. !. !. !. !. Z{ k < _ ! ! ! ! < V V+ r. !. !. !. $+ l@ ){ Q. 6 : ! < ) { : _ ! _ _ ! ! ! ! ! ! ! ! ! < w w. _# o@ q# { ) ! ! ! ! ! ! ! ! ! _ : _ ! ! ! ! ! ! ! ! ! ! ! : ! R O. X+ x! !. !. !. @= l+ n < ! ! ! ! ! ! ! ! ! ! ! ! : ] v X( !. +D -- n& Z= [n p2 d) @D :{ L3 ~| &4 N_ }< ;] z> r] y> =] }< q^ l; i] T| Q_ K_ N~ 9~ E, }2 R_ 9~ r} &4 1{ <^ T] (< l; Q~ B> Z] Q~ O~ R_ k| [^ #D Cu !. !. !. g~ $D %D :{ L3 Pi *] 9[ B> O~ k} k} J< z> M< f_ *_ &D !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: ~5 *D =D 3v +d -D jt &8 ;D >D .t ,D 'D 8} T: T: T: T: T: T: T: T: 05 )D !D ~D e7 {D ]D d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. S. -- ^D /D (D 8 _ _ 7 R }. : `m `m -t IC JC Ee _D :D d$ _x )z 6 R_ N~ w> B> e| (< B> i] =] q^ 2c p7 W^ u4 W^ t} A> K< (< Z] p} Q~ x2 :< E: r] 4< }{ o] P~ Ww d~ !. !. !. !. o} 4D N~ |^ J< N_ D> k; K< j| k} {} ;] D> N_ A{ :: fo !. !. !. !. !. !] ~] H{ x) gf 5D K{ D9 X3 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: f< -3 6D sc 2b 7D 8D 9D 0D aD bD lt cD D9 T: T: T: T: T: T: T: T: T: 05 -[ dD pr Wa 6v =* d& Dj 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. n& eD fD gD < _ ! _ _ e ! _ Gs Lc hD iD jD qC kD 6% %$ lD mD nD Yz G[ E$ !% *= !% =r R0 M_ ;0 _< o1 q^ -] 9= _: U] x> << P| Z] f) L3 W2 k} s} l] Y] q^ T1 d| p7 |7 y{ V] *_ ;] p] W] l; J< V] R_ R_ k} [< N~ m] >0 j@ !. !. !. !. G, Q< u} r} d| k} R_ i] *] }{ P} W] N~ p] << 9~ q} 2- !. !. !. !. !. !] ~] H{ x) wD xD yD zD C^ Zi S: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: S: A0 Q: AD +: BD 9 E( *[ CD DD Pb ED FD t7 X3 T: T: T: T: T: T: T: T: T: 05 N^ '. e ) { ! ! ! ! ! ! ! ! ! ! ! ! ! < q V@ !. !. h} WD U. e. z& e. F< <- R~ !v [^ W^ E, -] XD i) #/ ]v YD ]2 T6 q} q} 0[ D> [< l] k] O| W^ 9~ k} *] L< E> u4 x> 0~ q^ :< N~ k} 9~ |: B> ZD *m t2 F/ !. !. !. Kb 84 S] }< 9~ E, E, T7 ,k T] X] N~ (< w' T] k| V2 w1 -] R} !. !. !. !. !. !] ~] H{ `D E .E +E @E #E $E /4 V[ T: T: T: T: T: T: T: T: S: 8} f< T: T: T: T: T: T: T: T: T: T: T: @[ B^ l9 %E &E *E =E -E ;E Xn .9 {i >E ,E xj zd T: T: T: T: T: T: T: T: T: E} 'E )E !E ~E {E ]E c& !+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. U. ^E /E (E _E f : ! ! ! ! _ ! P G~ b ) IC :E ( (# k+ O 9 { ! ! ! : g !) M! !. !. !. !. !. !. @= I@ o+ w. =( W { ! ! ! ] q O. ]: a_ )^ #= M : _ ! ! ! ! _ ] 5+ r> m@ o < < : ! ! < 4 l+ !. !. !. !. !. %+ l+ q < : _ ! ! ! ! ! ! ! ! ! ! ! ! ! _ ^ 0. @= !. >) D[ [; U. e. z& e. Q1 _B A: s' T| C> Re Li &p !. !. j@ 4E rC V2 N_ :< y> k} g9 N_ E, l3 @5 5E E, 0~ :< p7 E> z> 0[ Q~ E, (< /1 e| g_ 6E p0 !. !. !. q. c; Qn Or k] D> O~ R_ B> ]2 9~ O~ D> Z] :{ }2 l6 E, m] U< l] Qc 7E !. !. !. !. !. !] ~] H{ 8E 9E 0E aE C8 bE cE dE H1 v[ T: T: T: T: T: T: j[ eE zs _4 Y2 T: T: T: T: T: T: T: T: 1s ^5 d: fE gE s[ hE h2 iE c8 jE kE rj lE mE nE y1 T: T: T: T: T: T: T: T: T: X3 .| Ax oE +< pE SB qE T% q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. S. z& rE sE tE P b : ! ! ! : 9 V W 7 :c 8 u x& uE Ic vE wE !. g~ g~ g~ g~ g~ g~ !. !. xE yE zE b, r. !. !. p@ n Z( f+ : _ ! ! ! ! ! ! ! ! ] ). _# `) += z / ] y. S+ ~. }~ l : _ ! ( o _# !. !. r> 1/ /~ ){ V+ P^ !. !. !. !. !. 1/ Y# : _ : : : 8 2 Z{ !. !. !. !. !. !. q. l@ b_ h+ r. N ~ : ! ! ! { ] ~ 2 J t g _ ! ! ! ! ! < d x. r. !. k+ T b d ! ! { 6 2/ q. !. !. !. !. A/ v ^ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { / >+ ^@ AE BE CE e. e. e. z& Z= DE Uw v} Ww T] p7 (1 yb J3 !. !. !. q. EE YD [< 0~ w' }{ }< z> S| R_ Fb FE _{ C> J< W] D, R_ O~ N~ s} N~ GE d) t' q; !. !. !. Y1 y4 HE V] [< f_ U6 9~ N~ 0~ N< D> N~ q^ N_ E, z> l} S| R_ t' !6 {6 !. !. !. !. !. !. !] ~] IE JE KE LE ME NE OE PE QE ~[ H1 f< T: T: T: T: X3 y1 RE SE TE #1 ~5 T: T: T: T: T: T: v[ ]6 UE VE WE XE YE {m ZE Ax D8 `E F o< .F +F v[ T: T: T: T: T: T: T: T: T: T: t7 @F |9 #F $F %F &F *F s+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. f. [; 9$ h+ |/ ` ] _ { { { O -+ t ] _ : z. A/ 4+ k [ y. !. !. !. !. !. !. !. !. !. I - I 6] !. !. !. ;+ ). Z( H : _ ! ! ! ! ! ! ! ! ) o }~ $= e ^ 9 !) ~2 !. ,; | ^ ! ! ! ^ q ^. !. !. !. !. !. !. !. !. !. !. !. !. !. !. Z{ b ( e 7 ! ~ y A/ !. !. !. !. !. !. !. !. !. !. !. z# z ) ! ! ! ! : { < ] ) ! ! ! ! ! ! _ ! z. l@ !. !. l@ J@ Q. g+ : { ) < P (# !. !. !. q. j( c < ! ! ! ! ! ! ! ! ! ! ! ! ! { { < _ g+ ){ X( a, =F -F /* e. e. n& J+ ;F `g S] u4 W^ W^ M[ p] p1 y2 !. !. !. b; >F K< N_ s^ ^< 9~ T1 ,F 9~ 'F !. 2{ E, a[ 9[ w' ;] T7 *] i] V< p0 2= J> r> !. !. !. md y, A> -] ^! l; |2 ;] }2 o1 p7 p] Y] M[ N_ Q~ << t^ v1 W2 )F r( !. !. !. !. !. !. !. !] ~] IE Dr !F ~F {F @j ]F ^F /F (F _F 05 T: T: T: T: X3 W3 :F mo g2 ( R. g ) < ] & s y# !. !. !. !. !. !. !. !. !. !. !. !. !. !. 8> c 7 p# 2/ N O^ #= S@ !. !. !. !. !. !. !. !. !. !. $+ b, 2 < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) h :# !. !. r> p@ p W o : ! ~ V m+ P^ !. !. !. q. <# 4 < ! ! ! ! ! ! ! ! ! ! ! _ < x 7 9 O 6] S@ z# bF cF dF {% e. e. T. P] eF 6d c/ Ww :< >4 A> 9~ T7 fF nd gF hF &/ r2 T| E, w' l7 *] U< i| m| |< E{ 3^ n6 N< E, -] 0[ S| p] M< 2{ !. !. !. !. !. T~ 85 /< k} f9 T| r] :< *_ }2 Q~ [{ r^ s} M< Q~ 0~ ^1 N_ D> T< |7 0/ !. !. !. !. !. !. !. !. !] ~] H{ y) iF jF kF lF (v mF nF oF ]/ C^ X3 T: T: T: X3 d: 'd 4i pF #f Mq qF 8} T: T: k[ u s6 l/ rF sF tF uF v5 vF 1y XE wF ,E xF bb 8} T: T: T: T: T: T: T: T: T: T: j[ xj Ti yF zF 9} AF BF +@ s+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. U. =- CF DF EF 3 < $= += 9 } d _ _ < 8. }* a@ 7 { , >+ !. !. !. !. !. !. !. !. !. I & V 8> M! ]. :# ` < < _ ! ! ! ! _ ! ! ! ! ! : ~ 9. _. w ] 7 G~ M! !. !. 1/ p@ J a W }# m+ ,; m@ >( `) (@ 1' _~ ,{ {> r> !. !. !. !. !. %= ! s >| q. k@ 9] !. !. ;| ;| q. !. !. !. !. !. !. !. w! b. ! _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! : / L ]. !. !. h+ 2/ g f { M a@ C< 8> P^ !. !. !. !. $+ [~ } { ! ! ! ! ! ! ! ! ! _ { ^ h x. l+ }~ ^) 9] !. !. !. FF GF f. e. e. U. J+ 4] o2 js <: 55 Z] =] 0~ (< |{ z{ B> ^2 l; z5 [< z> }2 HF L[ B> }{ |{ od e_ !. 6: }1 w' B> N~ q^ T| U6 y: c~ !. !. !. !. 3n F: p7 U< X6 J< k} [< q^ p] ;] (< l] U] W^ w' N~ k} }{ 22 >] IF ^b JF 3{ !. !. !. !. !. !. c[ d[ A- KF x_ LF MF NF OF }A wo PF QF t7 T: T: T: T: y1 .g RF SF TF UF [y VF WF X3 T: v[ >7 XF YF X9 ZF =[ `F G .G O5 =D +G d2 @} X3 T: T: T: T: T: T: T: T: T: T: @G V[ #G fn $G %G &G *G =G c& !+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. T. !% Y* O= -G N^ '. G~ 8] s 8 { ! ! _ 0 h x ! ~ , >+ !. !. !. !. !. !. !. !. !. I = e R. 4+ . z ~ _ ! ! ! ! ! ! < { ! ! ! ! ! : w v x _ < 3 n{ %+ (@ /~ -+ ;( n{ Z{ k+ 9. '. b t o+ r 9 { g h `( U+ T@ M! !. i+ 7] K@ x. 9] !. !. !. r. N^ R. 5+ _# !. !. !. !. !. !. !. `) I ] _ ! ! ! ! ! ! ! ! ! ! ! ! ! ) 9 | }. 6] !. !. !. ]) G~ 0. ,> %= P^ j@ !. !. !. !. ~. 9, =+ [. g : ! ! ! ! ! ! ! ! : { ] T n@ ~. !. !. j@ h+ !. !. !. ;G <% f. e. e. U. J+ n2 !. et _{ p} C, S1 T] (< O~ O~ |: Z4 9~ D> N_ N_ N~ w' 0[ t} |: w2 lj !. !. V~ >G {! S| w1 g9 p] w1 /| p, !. !. !. !. 7= l7 Q_ :< q^ 7[ 9~ ,G -] N~ l; =] |8 Q_ Q_ ^2 U] O~ z4 J< 'G t2 J> t2 >r T~ !. !. !. !. !. )G Qa !G v) ~G z^ {G ]G ^G /G (G _G Yk 7^ T: T: T: T: x3 :G W} !. I| K [# L ] ! ! ! ~ { ) _ ! ! , n+ !. !. !. !. !. !. !. !. !. I f _ _ ~ { ) _ ! ! ! ! ! _ } J h ! ! ! ! ! _ ) ) ! ! _ < n [. u i W a [. w. Y _ ^ ) ] ] ] { _ { ) 7 v ` >+ i( o+ 6+ 4+ [~ (# !. !. !. b, h ] < 0. i+ !. !. !. !. !. j@ l+ o : ! ! ! ! ! ! ! ! ! ! ! ! ! : 4 _~ V+ X( T+ !. !. !. !. ^@ P^ j@ !. !. !. r. )^ {> =+ Z) 6+ m 9 ! ! ! ! ! ! ! ! _ { 6 b. Z( ^. !. !. !. $+ 9, T@ <' >( @/ cG *= S. e. e. U. J+ n2 !. f~ 8g r] >6 a[ ~} q^ e| =] N~ O~ (< ;] N~ w' (< y> s} |: D> )6 b; !. !. d; [2 u1 7[ Q~ p} 5[ 3c dG -m !. !. !. !. Ka A, D> x> T6 O~ P} t^ W^ T] W] T] Q_ 0~ z> N~ -] <^ eG )F d~ g~ !. 3n Ka -m !. !. !. !. !. )G fG gG hG {] u] w] Zi *3 bb /6 t7 7^ T: T: T: T: 81 Z2 iG *h jG kG ^_ lG mG nG +x 91 _m oG wc 2} pG s3 MB qG rG sG tG uG E} T: T: T: T: T: T: T: T: T: T: v[ C^ U9 _4 vG &} wG xG &^ yG zG J- C= q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. g. {2 {~ `) H+ ! 5 d _ ! ! ! ! ! g g ! _ & G~ !. !. !. !. !. !. !. !. !. I f ! _ _ _ ! ! ! ! ! ! ! ] q V+ Z) 7 { ! ! { : x ~ ! ! ! ! < ( < ) < ] { w : : ! ! ! _ ! ! ! ! ! { ) ] < g ) ] ~ 9 a. :# ;| ]) [. ] : ) | 8> !. !. !. !. !. P^ R. ( _ ! ! ! ! ! ! ! ! ! ! ! ! : 9 :~ <' !. !. !. !. !. !. !. !. !. !. !. >( (. Z) 7+ 1 W d < ) : ! ! ! ! ! ! ! ! { e J@ /@ !. !. r. b_ n@ D< R. Y 0. AG BG CG DG *= e. e. U. J+ (3 0, $5 T_ _< 6[ P| 0~ S1 Pi ^! v{ }{ O~ Q~ << z> D> m] ;] U7 [{ lj !. !. !. c; ]< U7 o1 zb u8 EG `^ Kb !. !. !. !. !. bB ^! R_ x> A> O~ B> 2c M[ q^ V2 ]2 ]2 M< m} FG GG Rc _2 FE g~ !. !. !. !. h+ !. !. !. !. !. )G fG gG x) {] u] +^ j[ T: X3 @[ X3 T: T: T: T: X3 HG IG KB >h 1i 1( G1 JG KG LG MG gg NG wc OG >D PG *8 /[ QG RG H6 72 h5 T: T: T: T: T: T: T: T: T: E7 .| ]5 A2 3} io ~/ hw SG TG UG VG WG XG C= q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. f. 9, !. !. M! ,> < { ! ! ! ! ! ! ! ! ! ! ! : ! [. 9, !. !. !. !. !. !. !. !. M! 1/ k+ [* }# } g ) < < { _ ! ! ! ! ! ! ! ! ! < q y. x! !. !. M! Y( s 5 g < 8 ^ ( K9 `G H =; e. e. U. J+ n^ .H `] w' =] ~| e| Q~ E, 4n ./ !. !. !. h+ &D +H 85 E{ !. !. !. !. !. $+ c~ Cu o^ 9o Q~ }{ z> Q_ T7 p] l} E, }< T7 f_ o] s^ @H bB !. !. !. q. !. !. !. !. !. !. !. !. !. !. !. c[ d[ A- x) {] u] +^ j[ T: T: T: T: T: T: T: 8} 7} #H $H N{ %H f3 ]r p3 .t &H *H =H -H ;H >H ,H 48 'H |_ ^F ]d K2 )H !H C4 T: T: T: T: T: T: T: @[ (4 'D ~H {H kn ]H {/ ^H +t /H (H _H :H O~ }{ [< :< |2 1: O~ Q~ m} (1 0~ 3H mr K/ !. !. r. &p 30 N3 (! 4H p0 h+ !. !. !. !. !. !. c[ dg H{ x) {] u] +^ j[ T: T: T: T: T: T: 81 ^k 5H Xi Iq ^A 6H 7H 8H 9H 0H Np 7| aH bH an +{ cH dH eH Tq fH [v [6 gH hH y1 T: T: T: T: T: T: y1 B^ iH jH Ui Q3 kH !4 !r lH mH pa nH oH pH qH d& !+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. U. )s J% rH h < ! ! ! ! ! ! ! ! _ 9 z. >( !. !. !. !. !. !. !. !. !. !. I f ! _ d 1 1 i ~ ) _ ! ! _ ( :. %+ :~ ! : < K U@ ,; Y ) _ ! ! ! ! ! $- $- #- sH } d tH != _ `m ! ! _ uH ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ! ~ o ). b. 4 ( ^ f u =+ !. j@ ^) H ! { ! _ _ ! _ { _ x 0 ~ < | Z( )^ $+ !. !. !. !. !. ,; l f ) : _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ : Y z/ 1/ P. i j ~ : ! ! ! ! ! _ ~= vH wH ~% e. e. T. 7' j* xH M_ ,6 y> p] ks l; }2 Q_ x> D, T| z> R_ O~ R_ N_ >0 !. !. !. !. !. !. !. !. !. !. !. ^} S~ $p %A .5 W2 z{ >] T< A{ 1: 9~ E, 0~ +5 I! Y] N_ E> k] 0~ yH y2 !. !. Z7 75 O[ I< U] T] l| T] 8g 7= !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: mj r5 zH d5 u3 AH BH CH 3( <_ 63 DH EH FH GH HH IH JH KH gw Nm QE Ur LH MH 2k NH T: T: T: T: T: T: %2 ,[ 29 ;5 ut i< OH PH QH RH xl -A SH TH UH VH WH H- q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. S. e. XH YH ZH ( _ ! ! ! ! ! ! : ~ 6+ U+ !. !. !. !. !. !. !. !. !. !. !. I ' : v G~ u. U@ j+ 4+ i : : ! ! ] z. s. {> | ) _ ~ ). M ~ _ ! ! ! ! ! `H I g g .I +I @I #I $I ! %I $- )= )= &I ,= != #- _ ! ! ! ! ! ! ! ! ! ! uH < $- H+ 9. 7 0 W o+ q 8 b. T+ !. !. y# y. ! 8 ) ) { } a. =( [* k+ `( L _ x j O. 1' ^) (# !. !. V+ 1 ] ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ g a. _~ 3 [ : c g ! ! ! ! ! ! : *I =I -I =; e. U. P] Q] Ha E5 ]< A, K[ *] S| E, << 0~ |2 p7 E, i| k} v1 J< vC !. !. !. !. !. !. !. k) ;I o^ >G p^ x2 S| (1 [3 J< p7 V] r} D> ^1 Pi l; K[ p7 t1 *_ U] m] K_ >I ,I !. !. !. 'I _< (1 |{ |{ g_ U6 |{ E, 1H !. !. !. !. !. !. !] ~] H{ x) {] u] +^ j[ T: T: T: T: T: il )I A8 .l Dh !I %7 ~I x_ x_ 3( 1| {I ]I OB ^I /I g2 ^q Qm (I _I :I de Dp v[ E} T: T: T: T: T: f< {5 E 1I 2I 3I 4I 5I 6I J) .) q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. T. Zg 7I 8I < : ! ! ! ! ! ! < | v. !. !. !. !. !. !. !. !. !. !. !. !. I ' < j {> !. !. !. r> }* S ] _ ! { d I@ Z( 0 < ! _ ] ] _ ! ! ! ! : 9I 0I mf aI $3 bI cI dI c@ eI fI gI hI iI jI kI lI mI ~ : 9I ,= )= #- ! : 9I ,= )= #- sH d _ U _~ y f+ Y# p@ }# ] 5 b, !. !. !. ]) 0. 0 [. g+ 8 k }* !. j@ !. w! I+ < < ( ! 0 n }# #= $+ w! a. { _ ! ! ! : < : { ] ) { ! ! ! ! ! ! ! ! ! _ { g g _ g n b _ ! ! _ ! ! _ nI tl oI /* e. U. J+ (^ <' pI _{ ~} l] ~} E, t^ N_ k} }{ O~ P} g_ U6 A{ l} hF !. !. !. !. !. !. !. 7E Ry l} W2 U6 (1 B> {| << q^ 0~ l| L[ V] rC U] k} W0 :< qI W^ J< w1 $] p0 !. t^ m} f| !. !. !. !. !. !. !] sI IE x) {] u] +^ j[ T: X3 7^ E7 =3 m3 tI #| uI vI C( ko x_ x_ J( wI xI yI zI -H L4 Y0 AI BI :i H2 Gq m3 (4 j9 U} T: T: T: T: T: E} bb CI DI Ac EI FI GI KA 68 wF HI II JI qt KI LI MI NI OI .) q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. z& PI QI RI /c ! ! ! ! ! ! : x >+ U+ -( -( !. !. !. !. !. !. !. !. !. I f _ ~ q# ~2 !. !. !. !. a_ u ) ! ! : x p g _ ! ! ! ! ! ! ! ! _ d SI $b TI UI bk U. 1* {% =; $! 9+ bI 5a VI WI XI YI ZI $b `I J .J +J g ,j @J #J $J %J &0 -b &J YF >j y *J u a@ o 7 ! < v l+ <' !. !. s. '{ ;| ^. P a@ `) !. !. !. T+ P < _ ! : < ] [ o :~ V@ 0. ~ : _ { ) p z e 3 M h d _ ! ! ! ! ! ! ! ! ! _ : _ ! _ 6 d _ ! ! { : : _ != =J -J 7' *= T. J+ (3 !. 3: `] K_ ^< S1 Q~ }< P} O~ D> V2 s1 vp q} N~ 9~ R~ u( ;J !. !. !. !. !. FE <: <} N_ |^ ;] kd [{ :< Q_ =] z> T| 0[ _} .5 l; >J Pi p} Mt n] f_ N[ f| q; o; -] &4 D> l; p7 R_ l| v{ p] N_ ;] ,m m* !. !. !. !. !. ,J e/ 'J I{ {] u] +^ j[ N4 &5 )J [G 03 !J an t< ~J {J +2 ]J &8 8: s3 ^J /J Pb (J ^4 .c _J W3 &9 N4 E7 7^ X3 T: T: T: T: T: T: T: T: X3 Mv :J e5 P^ j@ !. !. h+ V@ M { _ ! ! ! ! ! < ! w 9 ! _ ! 7 q :. I| I@ n{ v! %= $= z : ! ! ! ! ! ! ! ! ! ! ! ! : p i d { 5 L p } 7 9I qJ rJ sJ ^& T. tJ uJ !. !. o6 )k Q_ N< t} Re w1 *] Or vJ f; 0- t8 af (1 22 _< 6E %D wJ 6: !. !. p, xJ m| }2 p} U] [< R< U] E, B> << :} 0[ m} i] Z] r} /1 U] k] Q~ Q~ yJ B> H! Q< z{ ^< p] N_ D> [< p7 ^! x2 N~ o] v{ zJ g~ !. !. !. !. AJ BJ CJ DJ y_ EJ ' wa xa FJ 93 GJ CA HJ IJ JJ g2 Y0 JH _5 KJ LJ MJ NJ oF Hu OJ Zs '4 #^ X3 T: T: T: T: T: T: T: T: T: T: T: T: T: E} &5 ]p PJ #9 QJ RJ SJ TJ Pk R: S: T: T: T: j[ UJ VJ WJ XJ YJ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. f. ZJ `J K 9I { ! ! ! ! ! ! : ) @ $= !. !. !. !. !. !. !. !. !. I+ / ! ! < 9 a@ 6] !. !. T@ b. ^ ! ! ! ! ! ! ! ! ! ! ! ! ! { .K +K @K :; /& e. e. e. e. e. e. e. e. e. z& =; 7' e. e. z& 7' 1* g, - {% #K $K %K &K /* A& :; e. e. 1* *K =K -K != _ { ! ! ! ! _ 8 o+ w! !. !. !. !. !. !. !. !. !. /@ <# g+ ~ _ ! ! ! ! ! ! ! : < : : w O I| 7] &+ b; r> !. !. !. /@ :. 7 : ! ! ! ! ! ! ! ! ! ! ! : w T ` a w :. Y+ q# M { ;K >K ,K 'K 8' )K !K C% !. !. b; 7- V7 a~ T9 g_ Pt ~( !. !. !. Z7 ~K {K m] f_ Z4 z{ (< u{ G5 42 !. f| J! t} X6 Q_ D> 1: {| z{ >] N< h| l; N_ k} P} R_ 9~ N_ w' l} l| W2 22 B> q} N_ }< X6 E, 9~ T1 x2 M< [^ *] }{ g_ ]K ^K !. !. !. !. ;_ Lb /K (K _K :K F] q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. d. e. e. e. e. e. e. e. e. e. e. e. e. e. 8' ha bK 9. ~ _C : : _ ! ! ! ! , >+ !. !. !. !. !. !. !. !. !. O^ 8 _ ! ! { < R. )^ !. T@ ` ^ ! ! ! ! ! ! ! ! ! ! ! ! : w cK dK eK <; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& =; 1* - =; e. e. z& <; z& z& 7' fK gK 2> 9I < _ ! ! ! ! ] 1 8> !. !. !. !. !. !. !. !. v! Z 5 g _ ! ! ! ! ! ! ! ! ! ! ! < 1 j+ !. !. !. !. !. !. !. !. !. o@ p { ! ! ! ! ! ! ! ! ! ! ! ! : 6 '. y { m R. v z P hK 9, iK Y* L& b> jK kK E{ !. !. !. T~ lK Yf mK 5^ y2 !. !. !. Z7 Dm A{ ,G [< k} }{ |: _| nK O} oK ~K K_ E, f_ k} (< G3 V0 pK w, %A X8 N_ f_ U< N~ B> << (< k} Q~ K_ W^ }{ k} Q~ t} E: [{ |2 9~ T1 T9 9[ 9~ N< m] g_ qK rK !. !. !. !. + !. !. !. !. !. !. !. !. !. O. 8 _ ! ! ! { { . {> ]. H ( ! ! ! ! ! ! ! ! ! ! ! ! '= W TK UK ~% e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. z& 1* VK gK WK XK h ! ! ! ! ! : : >+ ^@ !. !. !. !. !. !. /~ Q { < _ ! ! ! ! ! ! ! ! ! ! ! ! _ g >+ ~. !. !. !. !. !. !. !. i+ C< } { ! ! ! ! ! ! ! ! ! ! ! ! ! _ _ ~ ! _ ~ ] w (. !. !. !. v: y% L@ YK ZK 8 !. !. !. !. !. !. S+ T~ !. !. !. !. .h R1 T< O~ >4 << U< N~ ~| o] }{ U< U< q} l| *] w> Mr y' ./ 3{ P! `K 3: B5 x> m] L[ J< t^ S| O~ 9~ p} L[ U< m] z4 kj }< }: 8~ W0 D> D, R6 ^2 J! i] q^ }2 ^9 !. !. !. !. )G L .L +L @L #L $L Yr %L &L Ah *L =L !p -L ^6 ~5 (4 *3 Gq +o ;L >L ,L |I 'L )L il W3 @b !L ~L xc }J {L l4 ]L ^L /L 8} T: T: T: T: T: T: T: 7^ D9 v[ E} T: T: #} w} S: j[ @G NK (L Fq w3 _L :L + !. !. !. !. !. !. !. !. !. Q / ! ! ! ! ! : ^ i p# n { ! ! ! ! ! ! ! ! ! ! ! ! '= W 2L -- z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. 7' dJ 3L 4L 5L k+ (> < ! ! ! _ ] z. &+ !. !. !. !. b; Z{ 5+ ~ { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ { ! x. {. r. !. b; S+ P^ t. [~ t ~ _ ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ ! ! _ : : ! @& @= !. !. |= :& U. 6L 0) 9o Pa !. !. !. !. !. !. !. !. {6 &D lj js -] z{ L3 << Q_ [< T| V] 9~ z{ o] 1: p] C, 7L 8L p, !. !. !. !. !. !. k) Fb P[ W0 N_ N_ m] e| }{ r} w> i] ~} :} k} }{ q^ &m -r z4 |8 a/ Qc K_ l; [{ w{ gF h+ !. !. !. 9L 0L aL bL cL F( dL eL fL f3 gL hL iL 23 jL m3 T: T: U} 7^ @} x3 kL lL mL {h h5 Y9 nL oL ut Qr pL Xk qL r[ A8 lG /G HK @[ T: T: T: T: T: T: T: T: T: T: T: X3 z1 rL sL U} tL uL vL ]m -3 wL xL yL zL N* q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AL d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. f. J+ BL CL (c q. 9] `) o@ 2 < > $= !. !. !. !. !. !. !. !. !. '. f ! ! ! ! ! ! _ { : ! ! ! ! ! ! ! ! ! ! ! ! ! ! 2> DL EL J+ z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. !% FL GL HL IL JL ) : ! ! _ ] b. ]) !. !. r> u. x. T : { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) c K@ i( V@ o@ x. N ` | ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { : : x Z) q. !. 3/ (h f. hs KL q2 up !. !. !. !. !. !. !. !. ^9 B, v{ K_ [2 6[ W^ [{ Q~ O~ m] N_ N_ Q_ M< }< (1 P[ 7- !. !. !. !. !. !. !. !. !. 6- x> [{ {| A> l} W^ 0~ LL >4 T] S1 }8 A, ^1 (1 n] }2 m} /1 l| z: D: 9[ ]< <3 .^ .; !. !. !. )G ML NL OL PL 8E *8 z} Y' QL %9 t6 |F RL e3 SL T: T: T: T: T: X3 N4 !7 jl R: %d gn W} TL yh UL VL WL U/ XL Wq L4 33 xa C4 T: T: T: T: T: T: T: T: T: T: T: 7^ YL ZL `L M .M +M @M #M $M %M ,e &M *M yg q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . =M d. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. f. 4$ -M H> !. !. !. 8> r ^ - I@ !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! _ : _ ! ! ! ! ! ! ! ! ! ! ! ! : M0 ;M >M <; e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. 7' 7' Oe ,M 'M )M #- &0 ! ! ) k x! !. S+ [# q 7 : : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ! d | 3 d x < { _ ! ! ! ~ g ~ ~ ! ! ! ! ! ! ! ! ! ! ! : 6 g+ o < 4 <~ $+ !. :% O6 U. !< p2 <: Qc V~ !. !. !. !. !. !. P! 5 g_ !M B> U] r] << E, p} &4 1: 1: U< O| p} <1 0[ m| d) y2 !. !. !. !. !. !. !. !. Av T| w' O_ t} *] r] w' w' 6[ 0~ 0~ l3 8~ s^ r} 1: ]2 Q_ X6 V2 N_ R_ 64 5 42 !. !. !. !. !. ~M {M ]M V! v- ^M /M `F Rb (M @8 ,5 _M >7 (6 T: T: T: T: T: T: T: T: T: T: hf :M vj %[ zD 2u | !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! '= $I cM z& z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. n& dM eM fM x '= _ : e P. 9, 9, V 8 { _ ! ! ! ! ! ! ! ! ! ! ! ! ! _ : _ ! ! ! ! ! : < < { { : _ ! ! ! ! ! ! { : 6 w ! ! ! ! ! ! ! { < : : x . v ( '. ;| !. H| Kt {% e. H[ p2 <: A: U~ !. !. !. yA r7 gM A: h| O~ r} 12 R_ p] *] >4 I! -] R_ M< p] q^ Q_ *_ o1 [3 9~ Or hM Z7 T~ iM IB J3 V_ _2 ld (1 Q~ -] N_ l; V] [< C> 0~ *] Q_ Pi N~ l| J< O~ N_ z> }2 z> N_ 9~ jM _< kM !. !. !. !. !. AJ lM mM nM oM pM E( qM rM sM 2b tM uM @} T: T: T: T: T: T: T: T: T: T: T: 7^ H2 vM y[ wM xM }_ yM zM AM BM nL CM Iv `8 h5 T: T: T: T: T: T: T: T: T: T: T: T: X3 DM T: #} Fq 3e EM FM GM Z5 HM 77 IM JM y< KM 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . LM d. #. [% #. g. f. S. e. e. e. e. e. e. e. e. e. e. e. e. MM 4$ NM OM PM m@ QM RM SM L% !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ TM UM VM 7' e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. {% z& WM XM 0 YM ) 9 W @& _@ z < ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ g ~ { : ! ! ! ! ! ! ! ! ! ! ! ! _ _ _ ] { 4 7 g 9 ~ ! ! ! ! ! g 4 o d : < : _ ) f+ w! !. ZM z% 8' U. |[ `M t{ B{ J> !. !. JF d/ N l| (1 z{ D> V] y> }< R_ R_ R_ q^ :{ W] N_ l; (< }{ N_ y> X6 (1 m7 .N HE +N HE x, g) F3 A: s^ =] [< /1 m] N_ M3 2c N< N~ J< W^ 0~ D> }2 p} q^ |8 ;] T] +5 9~ P} (< (1 h) !. !. !. !. !. AJ @N #N $N %N &N *N =N -N y6 ;N )[ j9 T: T: T: T: T: T: T: T: T: T: T: T: T: C4 >N *2 e5 7G ,N Dd 'N )N !N 1t tg a k9 mj T: T: T: T: T: T: T: T: T: T: T: T: T: w} w} T: X3 f< j9 x3 ~N +f {N Y} ]N ^N /N KM 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (N _N :N ) !. 3N ~~ 8_ !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! _ >; {t 4N 7' e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. =; S. 5N 6N 7N ,= k F[ `( u ~ ! ! ! ! ! ! ! ! ! ! ! ! ! ! { x b. G~ z. 9 { ! ! ! ! ! ! ! ! ! ! ! e ! < p '. 1' (. 1 ] ! ! ! ! ! ) b }~ X( P { z I@ 7+ 1 g^ j@ !. b$ z% 8' U. 8N 9N @5 t, 0N !. !. #5 7[ y> A> 2c v{ |2 e| N~ 8~ L3 R_ N_ m] 9~ M< -] E, U6 u} |{ 1: (1 f_ f_ e| m} :} 8~ l| 0~ e| Q~ q^ Q~ B> l; (< q^ p] U< J< T| >6 U] L< B> a[ B> (< y> A4 9o q. !. !. !. !. aN x( bN cN dN eN fN ,3 Qb m9 &5 @[ T: T: T: T: T: T: T: T: T: T: T: T: T: T: E} Y| 4k ht gN lG Sa |F t6 G^ :] hN e3 81 T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: T: U} lo iN x| jN 4| xx %8 5v kN {x KM 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . lN mN nN oN pN qN rN sN tN Jh e. #. [% #. g. f. S. e. f. J+ uN D[ K$ vN S. :n !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! #- >; wN #K xN e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. *= =; yN zN AN BN @= !. C< _ : ! ! ! ! ! ! ! ! ! ! ! _ { e I 8> ~. l@ J@ ) ] ! ! ! ! ! ! ! ! _ _ ). O. Z) b, /~ $+ !. l+ } < ! ! ! ! { 6 G+ y# j+ '. I@ M! 6] g^ 9, !. !. |= CN 8' e. )} ]| q2 8~ d) 8L x1 |< g_ }{ R_ m] ;] >4 -] 2c |^ W^ x> q^ D> ;] :< l| 9~ D> s} DN 1: U] Z] (< Q| t} E, l} W^ W^ 0[ *] p] Q_ w' s1 N~ J< i] ^1 E, J< t} Q~ E, N_ .5 w' T7 <2 V] Q< w{ r1 t} r} t^ ]} !. !. !. !. !. ;_ EN FN GN HN IN 2 tG `n il X3 T: T: T: T: T: T: T: T: T: T: X3 7^ X3 T: T: T: E} |} fe ,E JN KN LN %< MN NN #[ v[ T: T: T: X3 8} X3 T: T: T: T: T: T: T: T: 7^ y1 f< U} T: ON PN C4 QN v7 =o ^] RN SN .) $l 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + TN UN VN WN XN YN ZN `N O L@ g. g. #. #. e. A$ J+ .O .$ !. !. !. !. !. !. !. !. !. I f ! ! ! ! ! ! ! ! : { )= _ _ ! ! ! ! ! ! ! ,= +O @O #K 1* e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. #O $O Z{ /@ !. %= x { ! ! ! ! ! ! ! ! ! < ( ) 0 Q. V+ r> !. !. T@ p# w : ! ! ! ! ! ! ! _ { I 6] !. !. !. !. !. 7] V ] ! ! ! ! ! { 4 }~ b; =+ =+ !. !. !. !. !. c$ }= %O S. e. &O I[ @5 *O (< Mk N3 B, v1 O~ k} K< J< T| 6[ ]2 R_ 0~ ^! &4 U< k} ;] q} :< J< [< S| }< [< << E, N< D> (< l; T| W^ 0~ r^ T| N< t} Q_ U] y> q} x2 w' ]2 R_ Q~ w' |8 [{ I! o1 |7 z4 N< << s^ N< =O ~} ]b !. !. !. !. !. -O ;O >O ,O 0. 'O )O !O y1 T: T: T: T: T: T: T: T: T: T: T: @[ ~O ,[ {O hf X3 T: T: E} 81 w3 '4 Z1 H2 m3 &5 (4 7^ S: f< y1 il W3 ]O /4 %2 T: T: T: T: T: T: X3 eE z2 nj t7 ^5 ^O Gq /O (O _O Nu :O ~{ aO &I != _ ! ! != ,= ,= 8d bO cO *= z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. h. dO eO v! h+ 1' ! { ! ! ! ! ! ! ! _ 7 m j r O^ ]. !. !. !. !. !. @= :~ 7 { ! ! ! ! ! ! ! : w X+ 9] !. !. !. `) Y# ~ : ! ! ! ! ! ( H t. !. j@ @= h+ !. !. !. !. 3A fO U. S. -- [7 gO ~v L~ hO md iO T9 W] D> (< N_ N~ jO W^ 0~ U] d| l} q^ ;] O~ z{ u4 js kO lO }2 O~ B> Q_ U< Q_ E, O~ D> r} ;] ]2 Pi n| u4 }2 t' p; mO nO K_ Q_ (< D> R_ Q~ S| N< h| ]v Ka O[ t} ]! 7< oO k] oO i) !. !. !. !. !. qd pO qO rO ]# sO Kx O3 T: T: T: T: T: T: T: T: T: T: T: =3 _9 tO uO vO wO |3 7^ T: T: T: T: X3 7^ 7^ X3 E} T: 7^ B^ xO hn yO zO AO gc BO y1 ug T: T: T: X3 (6 CO DO EO FO :q GO HO IO JO |I KO LO MO y< E. U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % NO OO PO QO RO !. !. !. !. !. !. !. !. !. SO TO UO pJ &I VO ,= { < 7t WO O+ XO YO ZO `O >; '= != P .P +P @P #P U. *= e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. f. [; $P m* !. :# p < ! ! ! ! ! ! ! { w [* >( }* T+ !. !. !. !. !. !. !. z/ I ) ! ! ! ! ! ! ! ! < 5 J@ ]. !. !. 8> 2 ] ! ! ! ! _ ! ) K ,; !. !. !. !. !. !. !. _% .$ f. T. U. -- (3 9] d; %P u: !. &P 4< -] y> a[ W^ [< Q_ i] Q_ Z] N[ N< }{ O~ 22 z{ F: 2H !. c~ 28 [< M< ~} M< N[ [2 V2 (1 D> N_ [< A{ u4 $A 85 FE !. !. C% 2{ n] N< kd z5 Lk k} 9~ U6 oO !. O< !k *P =P h+ 6: 3{ !. !. !. !. !. !. ;_ -P ;P >P ,P 1e 'P j[ T: T: T: T: T: T: T: T: T: T: $d 03 )P ]0 !P 4u ~P {P u[ 8} T: T: T: T: T: T: T: T: k[ +b ]P ]A ^P 8n t5 /P pj (P _P 8} T: T: T: 8} ^6 Hu s[ o< |u :P og `| B8

0~ 12 A> jP |{ o] E, :u f; !. !. !. u2 kP r} O~ k} t} p} C, t} kd 9g x2 54 ;] Hb !. !. !. !. !. lP F> m| t} 0~ 0~ N< R_ Pc ^2 8 !. mP nP ~. !. !. !. !. !. !. !. !. !. oP pP qP rP sP tP uP j[ T: T: T: T: T: T: T: 7^ wa U: vP wP +6 xP [y yP %f {i zP W3 8} T: T: T: T: T: T: j[ t7 I2 pL AP BP CP DP EP FP Rr GP 05 T: T: T: 7^ ]6 g8 HP IP JP KP LP MP NP OP PP QP RP SP {x s+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <. !. !. !. !. !. !. !. !. !. TP UP VP WP XP YP ZP f, `P Q .Q +Q {& J0 _; N} @Q #Q bI m^ 1* 7' {% e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. [; J% .; !. !. F[ } { ! ! ! ! ! ! : x += $+ !. !. !. !. /~ =+ >( k@ !. !. }* M ) _ ! ! ! ! ! ! ! ! _ ' f+ u! w. I+ x : _ ! u n+ }. < } 7 d !{ !. !. !. !. !. h* -- T. e. U. J+ wb !. h+ $Q Pa !. m> T9 |{ R_ E, ia B> (1 ~| w{ v{ Y] T9 /} o> B5 Ka h+ !. !. !. !. i) d/ z> Re N< M< 9g q} (< T] w> q^ m| -6 -& !. !. !. !. S~ I! Z4 }< T] p7 N< 9~ U2 q^ *m !. C% m* $+ !. !. !. !. !. !. !. !. !. %Q &Q *Q =Q -Q ;Q >Q j[ T: T: T: T: T: T: @[ 7a ,Q 'Q 86 )Q s[ xh <9 !Q ~Q Ed {Q ]Q Pp .b T: T: T: T: T: T: C^ {m ^Q J2 /Q (Q +2 _Q :Q +f N_ r] B> *_ W^ N~ x2 %] Y] Pc t' J/ !. !. X1 iQ *] N~ m] J< /1 |: }< O~ R_ @p r. !. !. !. !. !. !. !. !. !. !. !. !. */ jQ kQ lQ mQ nQ au j[ T: T: T: T: T: 7^ I1 oQ pQ 61 qQ rQ sQ {r &8 tQ D1 uQ sl u3 vQ 91 T: T: T: T: T: T: y1 wQ xQ yQ zQ AQ BQ CQ pc DQ EQ N4 T: T: X3 X3 d: Nu FQ GQ HQ @o ab z_ [_ [_ IQ JQ wz r+ !+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . KQ LQ MQ NQ OQ PQ QQ RQ SQ b> f. @. @. d. L@ T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. Ny J% TQ <. v Mc )= != != : #- $- : { : < 5 U 3 6 6 ~ ( 8 J n{ 7] !. >| j ] _ ! ! ! ! ! ! ! ! : 5 R. }. `( b, 6 4 1' !. !. U@ s H Q. m+ z/ UQ p, !. ; D% 3] f. e. e. U. J+ wb !. !. !. !. !. q. E/ Pc 1: 9~ Q~ l; W^ [^ D> z{ R_ Ry !. !. !. !. !. !. !. !. !. !. !. VQ u{ B> M3 L< 6[ N~ }2 << 0[ :< W^ S_ [2 d; !. V_ #_ C> 3c T| E, t1 q^ N~ 2c }{ &4 8- h+ !. !. !. !. !. !. !. !. !. !. !. 9L WQ XQ YQ ZQ `Q R S: T: T: T: T: T: mt dH .R hE IP q5 gz +R @R &8 &8 #R Y' $R mo %R I1 8} T: T: T: T: T: T: t7 &R sh m/ S/ *R =R -R ;R a3 T: T: @} &9 8a 62 >R Q3 WE ,R Y' 'R x_ x_ x_ $t {D )R z< q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . !R ~R {R ]R ^R /R (R _R :R e. d. 8+ 8+ d. ,@ g. f. T. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. *= ~ ! 2R (8 3R < ] [ | n+ ` < _ : p R 0. -( !. v. p 8 : : ! ! ! ! ! ! : ) b. b, y# b_ <. 9. 1/ !. !. q. (@ /@ M! Kb 4R 5R 6R |, <& E$ S. S. e. e. U. J+ wb !. !. !. !. !. !. 7R p7 z{ Q~ 0~ R_ w' w' E: O~ T< .5 m> !. j@ /b ]( x4 :^ Bq 3> !. !. Y1 p^ Q~ << A> U] l] N~ U] T] W0 _} 8R A{ :: )t !. Hb T7 N~ i] *] lO +H q} N~ ;] 9R -] `^ !. !. !. !. !. !. !. !. !. !. !. 9L 0R aR bR cR dR eR j9 T: T: T: T: T: h5 fR Iv 82 gR hR @j Fu iR 4k jR kR +j lR 4s t6 $2 &9 T: T: T: T: T: T: E} jl mR nR -N oR &E 1t y} pR 7^ h5 Ep qR o: B^ V: yI hE `E rR k< x_ x_ sR tR uR @* ~+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . vR wR xR yR zR AR BR CR DR x9 T. ER V. #. g. U. S. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. L& FR GR HR IR lJ JR KR M{ }v LR MR NR OR PR w / 6 R. I < : ! { 8 l '{ !. <' O^ a ! _ { _ _ _ _ : { j v. r. !. S@ (@ 8] 0, !. !. !. !. !. >) QR RR SR #K )% 4$ U. S. e. e. e. U. J+ wb !. !. !. !. h+ !. N3 18 Q_ ^e q} Q~ }2 w> E, O~ kj O~ O9 !k TR t4 M_ W^ <2 T1 s2 UR !. !. :b &4 << p] [< r^ k] M< _} T| m} VR N_ g_ X] +; tC WR }< U< ]< 0/ q. XR 9~ w1 T7 D> YR !. !. !. !. !. !. !. !. !. !. !. )G ZR `R DJ S .S +S *3 T: T: T: T: T: y1 qt @S 23 #S $S 83 %S s0 )8 &S 2I Wq *S =S -S ;S UJ 7^ T: T: T: T: T: T: j[ P4 {h m[ )Q >S Za Iv ,S 'S )S !S W} .} Tq ~S {S ]S ^S /S (S 3( x_ *z _S :S M* !+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vR D |S 1S 2S d] L@ L@ g. #. d. g. f. U. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. (& 3S 4S 5S I~ /* <; aJ 6S 7S )> XH 9$ 8S 9S gD 0S [ c ). _ ( ) ) ` 1/ !. !. ~. %= !) _~ c / ( < : f b N^ `) ^@ !. >( W+ $Q aS h1 >< bS :% 8_ cS =- {% =; *= U. T. e. e. e. e. e. U. J+ wb !. !. !. !. P! dS p^ <1 eS B> M< Q~ E, V] &4 22 9~ C> A{ U< t} A{ T< (1 R_ (1 _| K_ j' !. fS x, z> << }{ m] h| t} U< (< N_ Z] Q~ k} z{ gS hS o} z: (< iS j@ !. T~ jS ]e U1 ld kS K/ r. !. !. !. !. !. !. !. !. !. lS mS nS oS pS qS rS N4 T: T: T: E} f< j9 .| sS C8 pj tS A8 #g Rq uS nf '5 t6 D0 vS wS xS .6 F} T: T: T: T: T: T: T: T: !7 yS zS AS BS CS DS ES FS -N GS HS 7f IS ng JS )Q KS LS MS NS OS 6v 6_ d& q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PS QS RS SS TS H} US VS WS XS e. [% V. d. g. f. U. T. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. n& 1* =; 7' z& z& =; /& =; YS 7' Jk ZS `S T .T n (8 J@ @& j 0 ( [. S+ !. !. !. U+ X( S+ W+ 4+ +T @T %- #T $T %T ]) /; &T 8I Y *T =T Tu l( 1% Z* <% !: e. S. e. e. e. e. e. e. e. e. e. U. J+ wb !. !. !. !. 2= <: A{ p7 :} 0~ |8 1: w4 R_ Q< -] U< k} ]2 B> p] *_ q^ T7 N_ l; ;] >] K[ 2- !. Gb -T (< |: O~ O~ e| Q_ Q_ B> N~ k} D> Xw q7 S+ !. ;T >T `^ !. !. !. !. m* .; Cu Sc 84 Pa !. !. !. !. !. !. !. !. !. ,T 'T )T !T ~T {T ]T ^T /T G0 (T _T HK Dp B^ :T R. v n@ 9] !. !. oT pT qT !. !. rT sp sT ^K }/ tT uT vT wT xT yT zT n& e. 4$ -- U. U. T. e. e. e. e. e. e. e. e. e. e. e. U. J+ wb !. !. !. !. !. zJ AT t{ ]v U1 zA A: BT :^ /a kr >r T} << N< k} K_ bg z> N~ E> V] ;] CT 5^ !. !. DT y, E, H: f_ Q| Q~ S1 J< A{ Re -] [: !. !. h+ t] p, }/ !. !. !. !. !. !. !. !. V_ S+ !. !. !. !. !. !. !. !. !. ET FT GT HT IT `6 JT KT LT MT NT OT PT QT RT ST TT UT Zs VT WT 4e XT ee YT ZT 7f ur `T hN Iq U u u[ x| 8} T: T: T: O3 P4 .U Za +U KA @U )5 ae #U ;3 f3 U ,U 14 -* ~+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . lN ~R 'U )U !U s< ~U {U ]U R8 S. @. #. d. g. L@ f. T. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. T. ^U nh /U (U ^~ !. !. !. x! _U /3 (@ :U ;] E, q^ Q[ `^ !. !. h+ 6: t8 Eb ^! W0 t} f_ t} z{ z> Db c; u2 !. ./ X7 p, !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET aU bU cU dU eU fU gU hU iU jU kU lU mU nU oU pU qU .g [G rU sU {5 m3 tU H2 z3 /A uU ^k N5 Qr vU wU :v G p; {! -] A{ m; f~ !. !. !. !. !. !. kr 95 ]q #V $V Ok %V K/ Yf }3 85 ZD :: kr !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET &V *V =V -V ;V >V d& d& ,V 'V )V !V ~V {V ]V ^V /V (V _V :V }G F yV ./ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET &V zV AV BV CV * @ q+ .) yg DV YJ ;9 EV FV GV HV IV JV KV LV 2T MV >D D =W sN -W |N e. g. ER V. 8+ f. T. e. e. e. e. e. e. e. T. ;W j{ 2N h+ x# >W ,W g. T. e. e. e. T. z& 1* z& e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ wb !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. gQ S6 Jb tC !. !. -m :b eo Sc 0- h+ !. !. !. !. !. !. h+ -& K/ 1< E{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET &V zV 'W Y& )W [@ @ q+ q+ q+ q+ q+ q+ !+ c& !W ~W {W ]W ^W /W (W f2 jn `| ^d 1E _W :W 9 I~ U. g. g. 8+ d. ,@ g. f. T. S. S. lW mW nW `- T. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ y/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. c; zJ s( !. !. !. E{ oW f| Fb 2= !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET &V zV 'W Y& )W [@ @ q+ q+ q+ q+ q+ q+ q+ q+ !+ N* pW qW rW sW tW uW 1_ vW ~P wW xW yW zW AW BW CW DW EW FW GW HW IW JW KW LW MW NW OW PW Ih D= !+ !+ ~+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ QW RW SW WN TW PQ UW VW bQ x9 g. ER V. WW XW W8 J+ S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. U. J+ YW !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. {s ZW X| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ET `W X .X Z> )W [@ @ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ ~+ m2 +X @X #X $X Z: ]r %X &X *X =X -X ;X >X ,X 'X )X !X ~X -j D= }@ =| .) D= 2d J) s~ @* q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + {X ]X ^X /X :N (X _X :X f. f. f. 8+ #. d. g. U. S. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. S. Z= Y ,Y 'Y !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y !Y S ~Y {Y ]Y ^Y /Y (Y _Y :Y . . . . . . . iY jY kY lY mY nY oY pY qY rY sY tY uY 3X !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y vY R U 3 / . . . wY xY yY zY AY BY CY DY EY FY GY HY IY JY u+ M# KY LY MY U{ RX SX !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PS RW VN NY OY /F PY QY RY x9 T. #. [% #. g. f. e. e. e. e. e. e. e. U. N} SY n 1 7 / > + . . . . . . . . . . . . . TY UY VY WY XY YY ZY `Y Z .Z +Z @Z #Z $Z r( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y %Z Y K o _ & @ . . . . . . . . wY &Z *Z =Z -Z ;Z >Z ,Z 'Z )Z !Z ~Z {Z ]Z ^Z /Z (Z _Z :Z + . . . . . . . . . . . . . . . . . . . . 6Z 7Z 8Z 9Z 0Z aZ bZ cZ dZ eZ fZ gZ hZ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y %Z R }. z _ & $ . . . . . . . . . . . . . . . iZ jZ kZ lZ mZ nZ oZ pZ qZ rZ sZ tZ uZ vZ wZ xZ yZ _Z MY RX ~+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] G] n+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zZ AZ BZ NU CZ DZ rN EZ FZ 0' U. 8+ GZ = ] ' ; $ . . . . . . . . . . . . . . . . . . . . . . . . . . . HZ IZ JZ KZ LZ MZ NZ OZ PZ QZ RZ SZ uY TZ yA !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y UZ S L 1 _ & $ . . . . . . . . . . . . . . . . . . . . . iZ VZ WZ XZ YZ ZZ `Z ` .` +` @` #` $` %` &` *` =` yZ Dj RX aX ~+ !+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ q+ U{ 2] -` G+ Y 5 & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . zZ ;` Q8 !U TW >` # , % $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,` '` )` !` ~` {` ]` ^` /` (` RZ _` :` 4X h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )Y <` t M 3 { - $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . [` }` |` 1` 2` 3` 4` 5` 6` 7` 8` 9` 0` a` NX b` =` 6Y c` RX aX aX !+ r+ r+ q+ q+ q+ q+ q+ q+ q+ U{ d` e` H+ S w & + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # $ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iY f` g` h` 9Z i` j` k` l` m` n` o` _` p` q` !. !. !. !. !. !. !. !. !. !. )Y r` z o d ] , @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s` t` u` v` w` x` y` z` A` B` C` D` E` F` G` 4Y H` I` U{ E. !+ q+ q+ q+ q+ U{ J` K` q# r 7 - + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iY L` M` N` O` P` Q` R` S` T` U` V` p` W` X` !. !. !. Y` Z` _ 9 : f > + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . `` .. .+ .@ .# .$ .% .& .* .= .- .; .D. ^Z (Z > .:Z , .' .) .V 2 < ; + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ! .~ .{ .] .^ ./ .( ._ .: .< .[ .fZ (` } .% [ f , # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ! .| .1 .2 .3 .4 .5 .6 .7 .8 .9 .0 .a .b .c .d .] _ ' # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e .f .g .h .i .j .$ % > # @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . k .l .m .n .o .p .q .r .s .@ - # + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ @ @ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t .u .@ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . !R kV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v .w .x .pN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . y .,@ 8+ jJ z .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A .B .;- -- C .D .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (7 b@ J+ 4$ g. Ao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E .g. 4$ 4$ ;- F .G .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c a@ L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H .%K e. 4$ 4$ 4$ U. I .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; L G+ ( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , '. l+ 1/ !. <. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OU U. 4$ 4$ 4$ 4$ U. J .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e 8. V+ !. )^ < . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W >+ /~ r. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K .L .U. 4$ 4$ 4$ 4$ e. M .N .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f I Y( P^ !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % [~ k@ !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c. O .%( 4$ 4$ 4$ 4$ P] ;- P .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v ^. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f z/ !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q .;W 4$ 4$ 4$ 4$ 4$ 4$ f. R .S .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [. !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T .U .!% 4$ 4$ 4$ 4$ 4$ 4$ -- V .W .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X .S. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ U. /F . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y .Z .f. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ ;- (* ` .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AL b@ z& 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ P] gY ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...f. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ g. +..+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T .@..J+ 4$ 4$ 4$ 4$ -- 4$ 4$ 4$ 4$ 4$ J+ #..MU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; (@ !. !. !. !. !. !. !. 5+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X .e. -- 4$ 4$ 4$ 4$ tJ 4$ 4$ 4$ 4$ 4$ P] ;- $... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ` !. !. !. !. !. !. !. >| f . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . + [ < ] ] { f . . . . . . . . . . 6 5+ 4+ m+ b, /. /. }~ [~ H+ 0 * . . . . . . . . . . . . . . . . . > ] ) ] ] 6 6] !. !. !. !. !. !. !. :. ] ] ] ] ] ] ] ] ] ] < ^ $ . . . . . . . . . . + 8 < ] ] ] ] ) { % . . . . . . . ^ k !) )) /. /. /. 1' [# @& U d # . . . . . . . . . . . . . . . . . %..R .f. 4$ 4$ 4$ 4$ U. (X &..J+ 4$ 4$ 4$ 4$ f. *..=... . . . . . . . . . . . . . . . . . . . . $ ( < ] ] { , . . . . . . . . . > a 0. !) `( %= /. u! ,{ ;( o+ x > . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) n 8. m+ }~ ){ /. /. n{ ;+ 2/ K@ q { $ . . . . . . . . . . . . . . . . . . . . . = < ] ] ] ,% !. !. !. !. !. !. !. U+ 4 ] ] ] ] ] ] ] ] ] ] { * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . % b, /@ 8] 8] )^ V+ ) . . . . . . ^ 5+ I| @= !. !. !. !. !. !. !. !. !. j@ '{ N : . . . . . . . . . . . . . . . n /~ ~2 8] ]. ~2 r> !. !. !. !. !. !. !. w! y# 8] 8] 8] 8] 8] 8] 8] 8] 8] /@ {> g . . . . . . . . . . = :# /@ 8] 8] 8] 8] 8] 9, i . . . . . 6 O^ b_ !. !. !. !. !. !. !. !. !. !. /. * . . . . . . . . . . . . . . . . . =M b@ %( 4$ 4$ 4$ z& -..;..N5 f. 4$ 4$ 4$ 4$ J+ >..,... . . . . . . . . . . . . . . . . . . . . x 7] ~2 8] 8] ;| <# > . . . . . . w H+ #= M! !. !. !. !. !. !. !. !. !. <' u! O - . . . . . . . . . . . . . . . . . . . . . . . 7 <. Y( ~2 h+ !. !. !. !. !. !. !. !. !. !. h+ ;| N^ J@ x . . . . . . . . . . . . . . . . . . . G~ )^ 8] 8] y# `) !. !. !. !. !. !. !. j@ l@ ]. 8] 8] 8] 8] 8] 8] 8] 8] 8] )^ N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; }* !. !. !. !. !. 0. . . . . . L v! !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 8] <. # . . . . . . . . . . . . . r $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. `) w . . . . . . . . . . f ]. !. !. !. !. !. !. !. '. . . . + p# &+ !. !. !. !. !. !. !. !. !. !. !. !. Q. . . . . . . . . . . . . . . . . . . '..L@ 4$ 4$ 4$ 4$ U. )..@ !..U. 4$ 4$ 4$ 4$ 4$ f. lt . . . . . . . . . . . . . . . . . . . . . 5 %+ !. !. !. !. q. V . . . . . a. ;| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. z# S . . . . . . . . . . . . . . . . . . . + v _@ ;| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. (# [~ 3 . . . . . . . . . . . . . . . . . <# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. [~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. _# ; . . , I@ 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 2/ # . . . . . . . . . . . . i 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9, 6 . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . / j( !. !. !. !. !. !. !. !. !. !. !. !. !. 8] [ . . . . . . . . . . . . . . . . . ~..{..J+ 4$ 4$ 4$ 4$ U. s< . T .]..Z= 4$ 4$ 4$ 4$ Z= ^..0Y . . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. <# . . . ! j( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b; H+ . . . . . . . . . . . . . . . . . a v. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T+ a. . . . . . . . . . . . . . . . . ,{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. m+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. g+ . # o@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. [~ % . . . . . . . . . . . i 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9, 6 . . . . . . . . . . f >| !. !. !. !. !. !. !. J . = V@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. _~ . . . . . . . . . . . . . . . . . . /..)< -- 4$ 4$ 4$ -- C .(... . _..f. 4$ 4$ 4$ 4$ %( %( :... . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. P^ p . [ Z{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ p# . . . . . . . . . . . . . . > :. s. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ , . . . . . . . . . . . . . . ,{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. m+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. V@ . K@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. :. . . . . . . . . . . . i 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9, 6 . . . . . . . . . . f >| !. !. !. !. !. !. !. s . Y( !. !. !. !. !. !. !. !. !. !. !. !. !. !. @= p . . . . . . . . . . . . . . . . . zZ <..f. 4$ 4$ 4$ 4$ f. w .K .. . [..J+ %( 4$ 4$ 4$ 4$ f. }... . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. N . o@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r> L . . . . . . . . . . . . . ; W+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. x. . . . . . . . . . . . . . . ,{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. m+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. s. ,> T+ !. !. !. !. !. !. !. !. !. M! !. !. !. !. !. !. !. !. !. !. !. !. !. {. | . . . . . . . . . . t !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. P^ d . . . . . . . . . . f >| !. !. !. !. !. !. !. l o+ !. !. !. !. !. !. !. !. !. r. !. !. !. !. !. l+ . . . . . . . . . . . . . . . . . . AL -- -- 4$ 4$ 4$ 4$ U. zR . . . G .J& J+ 4$ 4$ 4$ 4$ e. {..AZ . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. *+ G~ !. !. !. !. !. !. !. !. !. r. r. !. !. !. !. !. !. !. !. !. !. !. !. !. v! / . . . . . . . . . . . . . q 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. $+ 7+ . . . . . . . . . . . . . l+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. w. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. !. !. !. !. !. b; z# O^ 6+ t V . I+ o@ 8] !. !. !. !. !. !. !. !. !. !. F[ + . . . . . . . . . e :. $= G+ Y# O. ]) !. !. !. !. !. !. !. !{ a@ G+ G+ G+ G+ G+ G+ G+ G+ G+ $= 0. / . . . . . . . . . . f >| !. !. !. !. !. !. !. $= l@ !. !. !. !. !. T+ ,{ ` s ). z. G~ >| !. !. j . . . . . . . . . . . . . . . . . . |..U. 4$ 4$ 4$ 4$ e. Sf 1... . . + 2..f. 4$ 4$ 4$ 4$ 4$ f. 3... . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. !. !. !. !. !. 9] A/ ,> f+ M M R P. )) `) !. !. !. !. !. !. !. !. !. !. >+ . . . . . . . . . . . . . . 1' !. !. !. !. !. !. !. !. %+ t. {> I| ,{ g^ ,{ )) ~2 j@ !. !. !. !. !. !. !. !. !. !. 1/ 9 . . . . . . . . . . . . T n+ G+ G+ J@ I| !. !. !. !. !. !. !. `) D< 8. G+ G+ G+ G+ G+ G+ G+ G+ G+ n+ j . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. !. !. !. r> -+ J # . . . . . . . ^ n+ T+ !. !. !. !. !. !. !. !. %+ 4 . . . . . . . . . . . . . . # }* !. !. !. !. !. !. !. [. . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. T+ !. !. !. !. j@ ;( g . . . . . . f 4+ }~ > . . . . . . . . . . . . . . . . . AZ @..e. 4$ 4$ 4$ 4$ ;- 'O . . . . . 4..U. 4$ 4$ 4$ 4$ 4$ U. 5... . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. !. !. !. T+ m+ y + . . . . . . . d `( b; !. !. !. !. !. !. !. !. >| & . . . . . . . . . . . . . q 9] !. !. !. !. @= Y( O | ; $ . . . . . ' }. (. M! !. !. !. !. !. !. !. !. !. 4+ . . . . . . . . . . . . . . . . . R !. !. !. !. !. !. !. /~ * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. !. !. 6] J . . . . . . . . . . . . U T+ !. !. !. !. !. !. !. !. 8. . . . . . . . . . . . . . . ' x! !. !. !. !. !. !. !. Y+ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. !. !. !. i+ Z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6..MM 4$ 4$ 4$ 4$ 4$ T. 3... . . . . 7..0J e. 4$ 4$ 4$ 4$ J+ {c 8... . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. !. !. 8> 1 . . . . . . . . . . . . @& r. !. !. !. !. !. !. !. !. T . . . . . . . . . . . . . + 1' !. !. ^@ _. 3 . . . . . . . . . . . . . g+ (# !. !. !. !. !. !. !. !. y# / . . . . . . . . . . . . . . . . Z !. !. !. !. !. !. !. 6] ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. !. l+ _ . . . . . . . . . . . . . . P !. !. !. !. !. !. !. !. U@ + . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. !. !. P^ S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9..0..U. 4$ 4$ 4$ 4$ '> %. a... . . . . . b..f. 4$ 4$ 4$ 4$ 4$ f. lt . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. r. O. , . . . . . . . . . . . . . . ;+ !. !. !. !. !. !. !. !. w. . . . . . . . . . . . . . . q !. t. V . . . . . . . . . . . . . . . . n w! !. !. !. !. !. !. !. !. 5+ . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. !. -+ @ . . . . . . . . . . . . . . . - z# !. !. !. !. !. !. !. T+ g . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. !. h+ 5+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c..-- -- 4$ 4$ 4$ 4$ g. d..e... . . . . . f..e. P] 4$ 4$ 4$ 4$ U. g..h... . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. !. >+ . . . . . . . . . . . . . . . . w T@ !. !. !. !. !. !. !. U@ # . . . . . . . . . . . . . @ P w . . . . . . . . . . . . . . . . . . P q. !. !. !. !. !. !. !. i( . . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. u! [ . . . . . . . . . . . . . . . . . 9. !. !. !. !. !. !. !. r> L . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. !. -+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i..f. 4$ 4$ 4$ 4$ %( J+ j... . . . . . . 7..k..J+ 4$ 4$ 4$ 4$ P] J+ YX . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. <~ + . . . . . . . . . . . . . . . . . 1' !. !. !. !. !. !. !. /@ 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % 7] !. !. !. !. !. !. !. m@ * . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. f+ . . . . . . . . . . . . . . . . . . y <' !. !. !. !. !. !. !. 9. . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. s. } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7..U .e. 4$ 4$ 4$ 4$ e. l..m... . . . . . . n..o..f. 4$ 4$ 4$ 4$ 4$ MM p... . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. } . . . . . . . . . . . . . . . . . . I+ h+ !. !. !. !. !. !. r. r . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p# !. !. !. !. !. !. !. P^ 6 . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. f+ . . . . . . . . . . . . . . . . . . * b_ !. !. !. !. !. !. !. ;( . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. !. _@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . q..L@ 4$ 4$ 4$ 4$ 4$ U. r... . . . . . . . . s..f. P] 4$ 4$ 4$ 4$ e. t..u... . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. c . . . . . . . . . . . . . . . . . . 0 ~. !. !. !. !. !. !. !. 5+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | $+ !. !. !. !. !. !. !. L . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . X( !. !. !. !. !. !. !. j( . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. S+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v..w..U. 4$ 4$ 4$ 4$ P] e. x... . . . . . . . . y..z..J+ 4$ 4$ 4$ 4$ %( e. 2O . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . f T@ !. !. !. !. !. !. !. K@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] >( !. !. !. !. !. !. !. 6+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. )) . . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. ]. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 4$ -- 4$ 4$ 4$ 4$ U. A..~R . . . . . . . . . B..C..U. 4$ 4$ 4$ 4$ 4$ L@ 6' $ . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . > {> !. !. !. !. !. !. !. 4+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # A/ !. !. !. !. !. !. !. <. . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . ,> !. !. !. !. !. !. !. :# $ . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. l+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |..f. 4$ 4$ 4$ 4$ 4$ L@ D... . . . . . . . . . . OY T. 4$ 4$ 4$ 4$ 4$ %( E..F... . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . F[ !. !. !. !. !. !. !. :~ . . . . . . . . . . . . . . . . . . . . . . . . . & 4 q l }# R. K y : . . F[ !. !. !. !. !. !. !. n+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . N !. !. !. !. !. !. !. 8> % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. ,> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AZ G..e. 4$ 4$ 4$ 4$ %( %( H... . . . . . . . . . . I..K& %( 4$ 4$ 4$ 4$ 4$ U. J... . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . ]: !. !. !. !. !. !. !. _. . . . . . . . . . . . . . . . . . . . . . 7 T X+ %= 6] 1/ k@ ^@ !. !. b; i+ ~2 n@ K@ X( !. !. !. !. !. !. !. :~ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 9. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. 0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K..f. 4$ 4$ 4$ 4$ 4$ e. L..0Y . . . . . . . . . . . v..M..U. 4$ 4$ 4$ 4$ 4$ f. N..%... . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . o@ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . . . . . . k [~ ]) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . Q. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. Z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v..5S e. 4$ 4$ 4$ 4$ 4$ g. [k . . . . . . . . . . . . . O..f. 4$ 4$ 4$ 4$ 4$ J+ #K c... . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . `( !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . . . . }. ^) 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. }. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . h0 %( -- 4$ 4$ 4$ 4$ %( K+ P... . . . . . . . . . . . . Q..R..!% 4$ 4$ 4$ 4$ 4$ ]% [m . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . . _ `( $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S..g. 4$ 4$ 4$ 4$ 4$ f. B .S .. . . . . . . . . . . . . $ jJ e. 4$ 4$ 4$ 4$ 4$ e. T..~R . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . j t. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7..U..!% 4$ 4$ 4$ 4$ P] U. V... . . . . . . . . . . . . . . W..f. 4$ 4$ 4$ 4$ 4$ P] {b !U . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . f+ k@ !. !. !. !. !. !. !. !. !. !. !. h+ @= 1/ -( Z{ m@ y# k@ b; !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . . K..f. 4$ 4$ 4$ 4$ 4$ -- W8 X... . . . . . . . . . . . . . . Y..b@ -- 4$ 4$ 4$ 4$ 4$ f. Z..+ . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . b. 9] !. !. !. !. !. !. !. !. !. !. _# x. f+ 7 * % # # - x }. n+ z/ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . [Z ba e. 4$ 4$ 4$ 4$ 4$ U. C& `... . . . . . . . . . . . . . . +..+.U. 4$ 4$ 4$ 4$ 4$ J+ @..RW . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . i ^@ !. !. !. !. !. !. !. !. !. 8> I / . . . . . . . . . . . }~ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . ++.$! -- 4$ 4$ 4$ 4$ -- U. @+.. . . . . . . . . . . . . . . . . >D f. P] 4$ 4$ 4$ 4$ 4$ g. 8Q . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . ' v! !. !. !. !. !. !. !. !. i+ G+ ; . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . . #+.g. 4$ 4$ 4$ 4$ 4$ %( b] $+.%+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.&+.*+.^P tJ -- 4$ 4$ 4$ 4$ 4$ e. =+.[Z . . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . [* !. !. !. !. !. !. !. !. i+ H . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . MU a' z& 4$ 4$ 4$ 4$ 4$ 4$ 4$ J+ e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. e. %( 4$ 4$ 4$ 4$ 4$ 4$ 4$ -- -+.;+.. . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . x w! !. !. !. !. !. !. !. %+ g+ . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . . OQ U. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ f. >+.. . . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . <. !. !. !. !. !. !. !. !. $= . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. 6] ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. Y+ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . %..5S U. 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ S. 5N m... . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . ; A/ !. !. !. !. !. !. !. 7] ; . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. >| ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . f x! !. !. !. !. !. !. !. p# . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . ,+.b@ %( 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ 4$ P] e. '+.. . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . { k@ !. !. !. !. !. !. !. Q. . . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . 7+ !. !. !. !. !. !. !. z/ _ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . / x! !. !. !. !. !. !. !. G+ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . . )+.]% 4$ 4$ 4$ 4$ 4$ 4$ -- S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. S. %( 4$ 4$ 4$ 4$ 4$ 4$ U. !+.. . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . 4 $+ !. !. !. !. !. !. @= 4 . . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . b. !. !. !. !. !. !. !. &+ 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . * }* !. !. !. !. !. !. !. :~ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . ~+.9J !% 4$ 4$ 4$ 4$ 4$ P] {+.w..ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba w..ba 9+ -- 4$ 4$ 4$ 4$ 4$ e. ]+.^+.. . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . T h+ !. !. !. !. !. !. /~ ) . . . . . . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . R. !. !. !. !. !. !. !. S@ 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . + U@ !. !. !. !. !. !. !. n{ . . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . . zR U. P] 4$ 4$ 4$ 4$ 4$ ^U /F kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX kX xx g. 4$ 4$ 4$ 4$ 4$ P] ;- zR . . . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . Z !. !. !. !. !. !. !. z# ' . . . . . . . . . . . . . . . . . . 1' !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . j !. !. !. !. !. !. !. !. k . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . u! !. !. !. !. !. !. !. j+ * . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . /+.(+.U. 4$ 4$ 4$ 4$ 4$ P] b@ _+.. . . . . . . . . . . . . . . . . . . . . . . :+.b] -- 4$ 4$ 4$ 4$ 4$ f. w .S .. . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . '. h+ !. !. !. !. !. !. v! 8 . . . . . . . . . . . . . . . . . . !{ !. !. !. !. !. !. !. ;( . . . . . . . . . . . . . . . 2 !. !. !. !. !. !. !. !. p# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . -+ !. !. !. !. !. !. !. ~. o . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . <+.B! %( 4$ 4$ 4$ 4$ 4$ f. 0..(N . . . . . . . . . . . . . . . . . . . . . . . h..[+.S. 4$ 4$ 4$ 4$ 4$ -- tJ }+.. . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . n h+ !. !. !. !. !. !. w! d . . . . . . . . . . . . . . . . . Q 9] !. !. !. !. !. !. !. o@ . . . . . . . . . . . . . . . c S@ !. !. !. !. !. !. !. -| . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . J@ !. !. !. !. !. !. !. !. x. . . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . . (X g. 4$ 4$ 4$ 4$ 4$ P] f. >D . . . . . . . . . . . . . . . . . . . . . . . . . Ao U. 4$ 4$ 4$ 4$ 4$ 4$ S. |+.. . . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . g {. !. !. !. !. !. !. !. Y . . . . . . . . . . . . . . . . Z ^@ !. !. !. !. !. !. !. !. %= . . . . . . . . . . . . . . . / -( !. !. !. !. !. !. !. k@ | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . 1 $+ !. !. !. !. !. !. !. i+ m . . . . . . . . . . . . . . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . 1+.M .J+ 4$ 4$ 4$ 4$ 4$ J+ -..2+.. . . . . . . . . . . . . . . . . . . . . . . . . ]8 %( P] 4$ 4$ 4$ 4$ 4$ ;- 3+. +.. . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . $ -| !. !. !. !. !. !. !. Z{ , . . . . . . . . . . . . . @ @& ~. !. !. !. !. !. !. !. !. !. ,; . . . . . . . . . . . . . . . . ;+ !. !. !. !. !. !. !. !. V@ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . * ^. !. !. !. !. !. !. !. !. U+ q . . . . . . . . . # 3 < . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . . 4+.U. 4$ 4$ 4$ 4$ 4$ 4$ ;- *..@ . . . . . . . . . . . . . . . . . . . . . . . . . ` .5+.S. 4$ 4$ 4$ 4$ 4$ -- `* 6+.. . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . K@ !. !. !. !. !. !. !. !. m+ @ . . . . . . . . . . . w (. !. !. !. !. !. !. !. !. !. !. !. `) } . . . . . . . . . . . . . . . ` h+ !. !. !. !. !. !. !. !. [# - . . . . . . . . . ^ a + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. !. !. k@ C< r : $ . % e h a. #= M! ` . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . %..7+.f. 4$ 4$ 4$ 4$ 4$ 4$ 8+.K... . . . . . . . . . . . . . . . . . . . . . . . . . . 9+.,@ 4$ 4$ 4$ 4$ 4$ 4$ g. 0+.+ . . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . _ l@ !. !. !. !. !. !. !. !. n@ k . . . . . . . . h I@ )^ !. !. !. !. !. !. !. !. !. !. !. !. !. 5+ . . . . . . . . . . . . . . . , 7] !. !. !. !. !. !. !. !. !. z# a. 3 / . . [ 5 s O^ z/ b_ # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . = >| !. !. !. !. !. !. !. !. !. !. r> y# _# ^) -( ~2 @= !. !. !. y. . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . Q8 x9 P] 4$ 4$ 4$ 4$ 4$ !% a' 1... . . . . . . . . . . . . . . . . . . . . . . . . . . NU a+.J+ 4$ 4$ 4$ 4$ 4$ J+ @..b+.. . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . n+ !. !. !. !. !. !. !. !. !. M! U@ ,{ Y# I+ Z y. Z( #= @= !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. {> - . . . . . . . . . . . . . . . f+ !. !. !. !. !. !. !. !. !. !. !. `) /~ {> a_ >| (# b; !. !. P^ 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . . H r> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. g^ . . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . nV U. 4$ 4$ 4$ 4$ 4$ 4$ f. kT c+.. . . . . . . . . . . . . . . . . . . . . . . . . . . d+.e+.;- 4$ 4$ 4$ 4$ 4$ 4$ e. f+.. . . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . / V+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. [# }~ !. !. !. !. !. !. !. !. n+ . . . . . . . . . . . . . . . , v. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r> s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. !. v . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . . . !) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. Z{ $ . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . ~+.M .!% 4$ 4$ 4$ 4$ 4$ -- e. g+.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . h+.S. 4$ 4$ 4$ 4$ 4$ 4$ f. i+.c+.. . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . 6 y# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;( + c ^@ !. !. !. !. !. !. !. j@ p@ - . . . . . . . . . . . . . . : >| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K@ !. !. !. !. !. !. !. !. !. V . . . . . . . . . . . ; 7] !. !. !. !. !. !. !. 7+ . . . . . . . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. ){ % . . . . . . . . . . . . . . . . # ;( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 1/ / . . . . . . . f >| !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . j+.U. 4$ 4$ 4$ 4$ 4$ 4$ !% #..1+.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . k+.J+ 4$ 4$ 4$ 4$ 4$ 4$ z& '@ l+.. . . . . } T+ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. Z) . . . . . . . . . . . . z *+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. S+ !) . . . `( !. !. !. !. !. !. !. !. !. y . . . . . . . . . . . . . . . a >( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. =( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I j@ !. !. !. !. !. !. !. b_ e . . . . . . . . . . . ; ,; !. !. !. !. !. !. !. b. . . . . . . . . . . . . . . . . . . . <. !. !. !. !. !. !. !. =+ % . . . . . . . . . . . . . . . . . . D< b; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b; h . . . . . . . f t. !. !. !. !. !. !. !. J . . . . . . . . . . . . . . . . . . . (N N..g. -- -- -- -- -- -- g. m+.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . n+.o+.U. -- -- -- -- -- -- d. lt . . . . . } P^ !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . _@ !. !. !. !. !. !. !. [# . . . . . . . . . . . . . e n@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. %= m . . . . ^ =+ !. !. !. !. !. !. !. b; u . . . . . . . . . . . . . . . . 4 j+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. n@ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 9, !. !. !. !. !. !. !. C< . . . . . . . . . . . . ; ,; !. !. !. !. !. !. !. b. . . . . . . . . . . . . . . . . . . . <. !. !. !. !. !. !. !. =+ % . . . . . . . . . . . . . . . . . . . }. ^) h+ !. !. !. !. !. !. !. !. !. !. !. !. !. $+ %+ '. . . . . . . . f t. !. !. !. !. !. !. !. J . . . . . . . . . . . . . . . . . . . SS e. %( P] P] P] P] P] z& ;- _N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p+.;W P] P] P] P] P] P] ;- O] q+.. . . . } s. !. !. !. !. !. !. !. 4 . . . . . . . . . . . . . . . . . . . 2/ !. !. !. !. !. !. !. _. . . . . . . . . . . . . . . ; P 6] !. !. !. !. !. !. !. !. !. !. !. !. {. N^ }# . . . . . . . ) [# k@ !. !. !. !. !. h+ u . . . . . . . . . . . . . . . . . ] I@ 1/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. r> 8> * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = }# a. 5+ 5+ 5+ 5+ 5+ ,% q . . . . . . . . . . . . @ '. a. 5+ 5+ 5+ 5+ 5+ ,% 9 . . . . . . . . . . . . . . . . . . . c a. Q 5+ 5+ 5+ 5+ Y+ L @ . . . . . . . . . . . . . . . . . . . . % . g^ }* (# 9] ~. S+ 1/ 8] ~2 v! 8> }~ a@ }. e ; . . . . . . . > . a. 5+ 5+ 5+ 5+ 5+ Y+ ~ . . . . . . . . . . . . . . . . . . . |O r+.!U !U !U !U !U !U s+.t+.u+.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . wR v+.}S !U !U !U !U !U w+.x+.y+.. . . . ' Z I+ 5+ 5+ 5+ 5+ Q 5+ / . . . . . . . . . . . . . . . . . . . v Y+ 5+ 5+ 5+ 5+ 5+ Y+ q . . . . . . . . . . . . . . . . [ o+ n{ >| ]) S+ ~. T+ z/ (@ u. ,{ ` _ @ . . . . . . . . . . p $= V@ -( (# S+ %+ v . . . . . . . . . . . . . . . . . . . 6 y. ){ ]. s. ~. ~. <' /@ ~2 >( m@ -| Z) [. q [ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 5 n v y 4 e x / . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . < 4 y v 3 7 ^ @ . . . . . . . . . . . . . . . . . f } y n = . . . . . . . . . . . . . . . . . . . . . . g a v v h 6 x ! ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . / q q q q q q n a + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . { v q q q q q n } . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J ~. ~. ~. ~. ~. ~. ~. y# > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p# ~. ~. ~. ~. ~. ~. ~. N^ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z+.A+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.B+.C+.D+.E+.. . . . . . . . . !. !. !. !. !. !. !. ]) > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J@ !. !. !. !. !. !. !. =+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . F+.G+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.H+.I+.J+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . L+.M+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.N+.O+.P+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q S+.T+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q S+.T+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q S+.T+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . w >+ ){ q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq U+.V+.K+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [ S -+ P^ !. h+ v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q pq W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.X+.Y+.Z+.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ a p@ ^. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q N+.`+. @..@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.+@.@@.#@.$@.. . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c T+ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.%@.&@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z M! !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ * ^ _ ! ) f & @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + ; f 8 _ ! ] ' # . . . . . . . . . . . . . . . . . . . . . 6 <' !. !. !. !. !. !. i+ b . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . & { ! ! : [ & . . . . . . . . . . . . . . . . . . . . . . + , f ) ! _ 8 = > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > = ] ! ! < f - . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . . . . @ & [ : ! { / = $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . & 8 : ! ! ] ' @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . . . . g f+ _. k+ -( l@ 9] S+ 1/ 6] 7] V@ p@ R. d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g Y :~ W+ V+ 6] ~2 9] S+ T@ (@ u! m+ 7+ d . . . . . . . . . . . . . 9 H . g+ S 9. ~. !. !. !. !. !. !. 9] Y# S g+ g+ g+ g+ g+ g+ g+ g+ g+ ` m @ . . . . . . . . . . / J H g+ g+ g+ g+ H I , . . . . . . ) Z ;+ 7] P^ S+ S+ ^@ ]. j+ I| G~ S . . . . . . . . . . . . . . . . $ ). n+ b, Z{ /~ `) S+ 9] z/ }* A/ Y( @& h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [ ` ,{ A/ }* T@ S+ S+ T+ 6] m@ Z) a. } . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . . . ^ '. D< V@ j+ ]. %+ S+ P^ t. }* k+ <~ [. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . l 8. o@ j+ 8] ^@ S+ S+ 1/ (@ V@ X+ q# 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . . @ g+ n@ l@ !. !. !. !. !. !. !. !. !. !. !. !. !. (# Z{ O ( . . . . . . . . . . . . . . . . . . . . . . . . . . . . _ p# ){ l@ !. !. !. !. !. !. !. !. !. !. !. !. !. (# u. J@ w . . . . . . . . . . p# !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ !. !. !. !. !. !. !. !. !. !. =+ % . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . / y. y# !. !. !. !. !. !. !. !. !. !. !. I@ . . . . . . . . . . . . . . } p@ ^. S@ !. !. !. !. !. !. !. !. !. !. !. !. @= z# O. 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . h ;( b_ !. !. !. !. !. !. !. !. !. !. !. !. &+ <# m . @& !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . . . v j( >( q. !. !. !. !. !. !. !. !. !. !. !. !. T+ -( !) 7 . . . . . . . . . . . . . . . . . . . . . & Y+ V+ ^@ !. !. !. !. !. !. !. !. !. !. !. !. ;| A/ :. 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . . . i N^ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. /~ a@ < . . . . . . . . . . . . . . . . . . . . . . . . ( $= z/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. s. j( k . . . . . . . . H+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^) % . . . . . . . . . . h ~. !. !. !. !. !. !. j@ ! . . . u _# !. !. !. !. !. !. !. !. !. !. !. !. &+ e . . . . . . . . . . . . [ $= &+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. )^ y. / . . . . . . . . . . . . . . . . . . . . . . . . . f I@ <' !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9] <. n+ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . . b _@ 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. &+ [* 4 . . . . . . . . . . . . . . . . . . k a_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ F[ [. ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . . * ;( 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. }* M . . . . . . . . . . . . . . . . . . . . . $ H+ U+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 9] l+ 0 . . . . . . p# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. =+ % . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . z. <' !. !. !. !. !. !. !. !. !. !. !. !. !. ;( . . . . . . . . . . . . I (@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. *+ J . . . . . . . . . . . . . . . . . . . . . . . L _# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. P^ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . . Y# {. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T@ [. . . . . . . . . . . . . . . . . P 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. :. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . . 9 ){ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. s. Q . . . . . . . . . . . . . . . . . . . [ Y( !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;| 6 . . . . . p# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. =+ % . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ _ . f+ S@ !. !. !. !. !. !. !. !. !. !. !. !. !. M! o . . . . . . . . . . . 5+ <' !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. k@ q# . . . . . . . . . . . . . . . . . . . . . I+ 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . * 2/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r. G~ # . . . . . . . . . . . . . Y+ r> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b; T . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . . W (@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. _~ . . . . . . . . . . . . . . . . . 7 8> !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. -+ & . . . . . H+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. u. % . . . . . . . . . . W ^@ !. !. !. !. !. !. ~. = o @= !. !. !. !. !. !. !. !. !. !. !. !. !. !. V@ . . . . . . . . . . . H+ b; !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. j@ <. . . . . . . . . . . . . . . . . . . . a. r. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . : -| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. n{ - . . . . . . . . . . . y 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b_ * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . . | )^ !. !. !. !. !. !. !. !. !. !. !. ^@ P^ 6] z# )^ P^ S+ !. !. !. !. !. !. !. !. !. !. !. !. Q. . . . . . . . . . . . . . . . z >( !. !. !. !. !. !. !. !. !. !. !. !. 9] P^ l@ U@ ~2 P^ S@ !. !. !. !. !. !. !. !. !. t. ) . . . . . . 0. ~. ~. ~. 9] M! h+ !. !. !. !. !. !. h+ M! 9] ~. ~. ~. ~. ~. ~. ~. ~. ~. ~. k+ % . . . . . . . . . . W ^@ !. !. !. !. !. !. k@ 4 m@ !. !. !. !. !. !. j@ P^ *+ U+ %+ q. !. !. !. H . . . . . . . . . . H+ q. !. !. !. !. !. !. !. !. !. !. i+ -( W+ l+ (. A/ t. S+ !. !. !. !. !. !. !. !. !. !. r. [. . . . . . . . . . . . . . . . . . I+ M! !. !. !. !. !. !. !. !. !. !. !. h+ ^@ s. /~ (@ P^ 9] !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . ( {> !. !. !. !. !. !. !. !. !. !. !. ~. P^ ]. '{ ]. P^ ^@ !. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . , /. !. !. !. !. !. !. !. !. !. !. !. i+ (# _# l@ P^ b; !. !. !. !. !. !. !. 2/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.-@.;@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . . ^ _# !. !. !. !. !. !. !. !. !. S+ V@ p# 4 / - % = / W y. %= r> !. !. !. !. !. !. !. !. !. 9] U . . . . . . . . . . . . . / -( !. !. !. !. !. !. !. !. !. !. P^ !{ K@ a 8 = % = / b o+ _@ ,; !. !. !. !. !. r> L . . . . . . . < q q q z q# 9] !. !. !. !. !. !. S@ 5+ 1 q q q q q q q q q n 5 + . . . . . . . . . . W ^@ !. !. !. !. !. !. k@ <# !. !. !. !. !. s. ,{ t / - & x H v. !. /~ = . . . . . . . . . M ^@ !. !. !. !. !. !. !. !. !. }* >+ c , . . . $ & h O. >| !. !. !. !. !. !. !. !. !. ]) p . . . . . . . . . . . . . . . ` j@ !. !. !. !. !. !. !. !. !. !. >( ,{ ` 5 / - , / a 4+ 7] !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . $ j( !. !. !. !. !. !. !. !. !. !. /. 4+ q / * % * / p Q. I| s. !. !. !. !. !. !. !. !. !. !. 9. . . . . . . . . . }. q. !. !. !. !. !. !. !. !. q. A/ o+ ~ ' ; = 8 L =( z# !. !. !. !. !. I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.>@.,@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.'@.)@.!@.. . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . @ )) !. !. !. !. !. !. !. !. h+ 1' y . . . . . . . . . . . i n@ !. !. !. !. !. !. !. !. !. U+ ! . . . . . . . . . . . . <# !. !. !. !. !. !. !. !. !. b; }~ | . . . . . . . . . . . / t (. i+ !. !. [* . . . . . . . . . . . . . c <' !. !. !. !. !. !. i+ 1 . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. h+ q. !. !. !. !. ){ W . . . . . . . . g+ '. . . . . . . . . . ( ^. !. !. !. !. !. !. !. !. b; += ^ . . . . . . . . . . < [# $+ !. !. !. !. !. !. !. !. %= > . . . . . . . . . . . . . 5 (# !. !. !. !. !. !. !. !. !. 1/ Y# _ . . . . . . . . . ' y. ~. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . !) !. !. !. !. !. !. !. !. !. =+ I @ . . . . . . . . . . 3 ,{ b; !. !. !. !. !. !. !. !. S@ m . . . . . . . . <~ !. !. !. !. !. !. !. !. w! 7+ @ . . . . . . . . = q# 7] !. !. 9, : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q qu ~@.{@.]@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@.^@./@.(@._@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . . !) !. !. !. !. !. !. !. !. {. [. . . . . . . . . . . . . . . . y. M! !. !. !. !. !. !. !. !. >+ . . . . . . . . . . . H+ !. !. !. !. !. !. !. !. !. ;| I . . . . . . . . . . . . . . . . 2 {> z# f . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. !. !. !. l+ * . . . . . . . . . . . . . . . . . . . . `( !. !. !. !. !. !. !. !. ~. b. . . . . . . . . . . . . . . Y+ r> !. !. !. !. !. !. !. !. p# . . . . . . . . . . . . > N^ !. !. !. !. !. !. !. !. !. )) p . . . . . . . . . . . . . j `) !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . Y j@ !. !. !. !. !. !. !. r. _~ > . . . . . . . . . . . . . . ` ]) !. !. !. !. !. !. !. !. b, @ . . . . . . = _# !. !. !. !. !. !. !. ~. . . . . . . . . . . . . . - 8. ~. W+ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.U+.:@.<@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . 0 S@ !. !. !. !. !. !. !. T@ k . . . . . . . . . . . . . . . . . 6+ j@ !. !. !. !. !. !. !. ;| < . . . . . . . . . 3 <' !. !. !. !. !. !. !. !. U+ W . . . . . . . . . . . . . . . . . . & ~ . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. !. !. I| ; . . . . . . . . . . . . . . . . . . . . y j@ !. !. !. !. !. !. !. r. 0. . . . . . . . . . . . . . . . . a@ q. !. !. !. !. !. !. !. y# ^ . . . . . . . . . . . 8. !. !. !. !. !. !. !. !. !. i( $ . . . . . . . . . . . . . . . . 9] !. !. !. !. !. !. !. u! . . . . . . . . . . . = t. !. !. !. !. !. !. !. b; I+ . . . . . . . . . . . . . . . . . u &+ !. !. !. !. !. !. !. b; u . . . . . . ) /@ !. !. !. !. !. !. !. /. . . . . . . . . . . . . . . . s L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q }@.|@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . . ,{ !. !. !. !. !. !. !. k@ T . . . . . . . . . . . . . . . . . . . O. !. !. !. !. !. !. !. !. !) . . . . . . . . . <# !. !. !. !. !. !. !. !. 9, | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. !. *+ [ . . . . . . . . . . . . . . . . . . . . . i( !. !. !. !. !. !. !. !. o@ . . . . . . . . . . . . . . . . . . %= !. !. !. !. !. !. !. !. 7+ . . . . . . . . . . w {. !. !. !. !. !. !. !. !. ,{ % . . . . . . . . . . . . . . . . . C< !. !. !. !. !. !. !. u! . . . . . . . . . . . 0. !. !. !. !. !. !. !. h+ 9. . . . . . . . . . . . . . . . . . . . ` j@ !. !. !. !. !. !. !. b, . . . . . . e S@ !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q }@.|@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . a @= !. !. !. !. !. !. !. 9. . . . . . . . . . . . . . . . . . . . . # V+ !. !. !. !. !. !. !. 7] - . . . . . . . c s. !. !. !. !. !. !. !. r. }# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. M! U . . . . . . . . . . . . . . . . . . . . . 6 @= !. !. !. !. !. !. !. &+ g . . . . . . . . . . . . . . . . . . y 9] !. !. !. !. !. !. !. 8> + . . . . . . . . . !) !. !. !. !. !. !. !. !. j+ & . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. u! . . . . . . . . . . [ /~ !. !. !. !. !. !. !. <# . . . . . . . . . . . . . . . . . . . . . ;( !. !. !. !. !. !. !. P^ 6 . . . . . g ^@ !. !. !. !. !. !. !. v. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q }@.|@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . . 2/ !. !. !. !. !. !. !. {> ; . . . . . . . . . . . . . . . . . . . . . K $+ !. !. !. !. !. !. k@ | . . . . . . . x. !. !. !. !. !. !. !. !. <# + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. !. b, . . . . . . . . . . . . . . . . . . . . . . X+ !. !. !. !. !. !. !. !. J@ . . . . . . . . . . . . . . . . . . . . n{ !. !. !. !. !. !. !. ~. u . . . . . . . . ^ ~2 !. !. !. !. !. !. !. <' m . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . Q. !. !. !. !. !. !. !. ;| x . . . . . . . . . . . . . . . . . . . . . 6 w! !. !. !. !. !. !. q. 7+ . . . . . ] l@ !. !. !. !. !. !. !. /~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq pq 1@.2@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . : @= !. !. !. !. !. !. h+ . . . . . . . . . . . . . . . . . . . . . . . , /~ !. !. !. !. !. !. !. 5+ . . . . . . ! T+ !. !. !. !. !. !. !. @= w . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. S+ s . . . . . . . . . . . . . . . . . . . . . * z# !. !. !. !. !. !. !. 1/ 9 . . . . . . . . . . . . . . . . . . . . o+ q. !. !. !. !. !. !. !. Y# . . . . . . . . P. !. !. !. !. !. !. !. !. Z) . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . + 7] !. !. !. !. !. !. !. X+ . . . . . . . . . . . . . . . . . . . . . . . F[ !. !. !. !. !. !. !. Z( . . . . . ; /. !. !. !. !. !. !. !. ~. S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q U+.U+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.3@.4@.[@.. . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . g+ !. !. !. !. !. !. !. 6] ^ . . . . . . . . . . . . . . . . . . . . . . . Z( !. !. !. !. !. !. !. 2/ . . . . . . f+ !. !. !. !. !. !. !. !. (. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. 7] > . . . . . . . . . . . . . . . . . . . . . 3 <' !. !. !. !. !. !. !. W+ . . . . . . . . . . . . . . . . . . . . . _ (# !. !. !. !. !. !. !. j( . . . . . . . * {> !. !. !. !. !. !. !. %+ | . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . c @= !. !. !. !. !. !. <' z . . . . . . . . . . . . . . . . . . . . . . . a. !. !. !. !. !. !. !. a_ - . . . . . G~ !. !. !. !. !. !. !. !. 7] / . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q N+.5@.6@.7@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.8@.9@.0@.B... . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . . ;( !. !. !. !. !. !. !. ,{ . . . . . . . . . . . . . . . . . . . . . . . . I+ !. !. !. !. !. !. !. n@ . . . . . . <~ !. !. !. !. !. !. !. b; I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. ,{ . . . . . . . . . . . . . . . . . . . . . . b. !. !. !. !. !. !. !. !. 6+ . . . . . . . . . . . . . . . . . . . . . . u! !. !. !. !. !. !. !. v! f . . . . . . 0 9] !. !. !. !. !. !. !. b, . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . I+ !. !. !. !. !. !. !. 7] . . . . . . . . . . . . . . . . . . . . . . . . o q. !. !. !. !. !. !. b_ < . . . . . r j@ !. !. !. !. !. !. !. !. F[ ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.%@.a@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . , j+ !. !. !. !. !. !. !. Q . . . . . . . . . . . . . . . . . . . . . . . . s !. !. !. !. !. !. !. {> @ . . . . % V+ !. !. !. !. !. !. !. >( ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. !. I+ . . . . . . . . . . . . . . . . . . . . . . [# !. !. !. !. !. !. !. b; c . . . . . . . . . . . . . . . . . . . . . . Z( !. !. !. !. !. !. !. 9] 5 . . . . . . 7+ !. !. !. !. !. !. !. !. R . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . ,{ !. !. !. !. !. !. !. Z( . . . . . . . . . . . . . . . . . . . . . . . . { i+ !. !. !. !. !. !. (# g . . . . . @ N^ !. !. !. !. !. !. !. !. !. {> L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . o i+ !. !. !. !. !. !. q. _. q# 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ q# x. q. !. !. !. !. !. !. y# ; . . . . 4 w! !. !. !. !. !. !. !. %= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. h+ L . . . . . . . . . . . . . . . . . . . . . . z# !. !. !. !. !. !. !. ]. 8 . . . . . . . . . . . . . . . . . . . . . . @& !. !. !. !. !. !. !. !. I . . . . . . 2/ !. !. !. !. !. !. !. <' w . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . 8 /~ !. !. !. !. !. !. !. )) q# 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ 6+ z. a@ k@ !. !. !. !. !. !. r> 4 . . . . . . a T+ !. !. !. !. !. !. !. !. !. r. Y( u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . g+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ]) , . . . . s !. !. !. !. !. !. !. !. X+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. b; h . . . . . . . . . . . . . . . . . . . . . # /@ !. !. !. !. !. !. !. N^ # . . . . . . . . . . . . . . . . . . . . . . j !. !. !. !. !. !. !. !. Q . . . . . # }* !. !. !. !. !. !. !. {> - . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . w S@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. 2 . . . . . . . [. $+ !. !. !. !. !. !. !. !. !. !. ^@ V@ K - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . 6+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;| , . . . . R. !. !. !. !. !. !. !. h+ R. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. M! w . . . . . . . . . . . . . . . . . . . . . ] (# !. !. !. !. !. !. !. `( . . . . . . . . . . . . . . . . . . . . . . . h q. !. !. !. !. !. !. !. H+ . . . . . ! ;| !. !. !. !. !. !. !. <~ . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . | !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ | . . . . . . . . $= !. !. !. !. !. !. !. !. !. !. !. !. !. V+ Y+ = . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . 9. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. t. > . . . . ,% !. !. !. !. !. !. !. $+ i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ : . . . . . . . . . . . . . . . . . . . . . d w! !. !. !. !. !. !. !. _. . . . . . . . . . . . . . . . . . . . . . . . 2 j@ !. !. !. !. !. !. !. I@ . . . . . b T+ !. !. !. !. !. !. !. N . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . k !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. S+ c . . . . . . . . . $= 9] !. !. !. !. !. !. !. !. !. !. !. !. !. >| <. ( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . D< !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^) + . . . . 4+ !. !. !. !. !. !. !. j@ o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . W i+ !. !. !. !. !. !. !. X+ . . . . . . . . . . . . . . . . . . . . . . . p k@ !. !. !. !. !. !. !. Z( . . . . . m <' !. !. !. !. !. !. !. 9. . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . }# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ;| ~ . . . . . . . . . . J t. !. !. !. !. !. !. !. !. !. !. !. !. !. !. (@ 7+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . [~ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. [# . . . . . Z) !. !. !. !. !. !. !. S+ 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . j ~. !. !. !. !. !. !. !. J@ . . . . . . . . . . . . . . . . . . . . . . . } T+ !. !. !. !. !. !. !. o@ . . . . . I r. !. !. !. !. !. !. !. Q . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . 0. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. X( > . . . . . . . . . . . _ m+ i+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. I| 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . l+ !. !. !. !. !. !. !. M! }~ [~ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ g^ V . . . . . `( !. !. !. !. !. !. !. S@ : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . u S@ !. !. !. !. !. !. !. n+ . . . . . . . . . . . . . . . . . . . . . . . 5 {. !. !. !. !. !. !. !. w. . . . . . b. !. !. !. !. !. !. !. !. [. . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . y. !. !. !. !. !. !. !. !. W+ ;+ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ _@ }~ Z . . . . . . . . . . . . . . z }~ ^@ !. !. !. !. !. !. !. !. !. !. !. !. !. ]. j . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . <~ !. !. !. !. !. !. !. k@ ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . G~ !. !. !. !. !. !. !. M! 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . | P^ !. !. !. !. !. !. !. G~ . . . . . . . . . . . . . . . . . . . . . . . | 9] !. !. !. !. !. !. !. [* . . . . . z. !. !. !. !. !. !. !. !. ,% . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . Y+ !. !. !. !. !. !. !. !. i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . n }~ k@ !. !. !. !. !. !. !. !. !. !. !. !. k@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . O. !. !. !. !. !. !. !. S@ b . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . :. !. !. !. !. !. !. !. b; v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . e 1/ !. !. !. !. !. !. !. <~ . . . . . . . . . . . . . . . . . . . . . . . z r. !. !. !. !. !. !. !. $= . . . . . . $+ !. !. !. !. !. !. !. 8. . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . H !. !. !. !. !. !. !. !. }# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | `( @= !. !. !. !. !. !. !. !. !. !. !. {. m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . 0. !. !. !. !. !. !. !. r> ). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [. !. !. !. !. !. !. !. q. U . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . f )^ !. !. !. !. !. !. !. w. . . . . . . . . . . . . . . . . . . . . . . . ). !. !. !. !. !. !. !. !. 0. . . . . . t ~. !. !. !. !. !. !. !. O. . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . m !. !. !. !. !. !. !. !. 0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . z j( j@ !. !. !. !. !. !. !. !. !. !. 7] ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . b. !. !. !. !. !. !. !. q. ` . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g+ !. !. !. !. !. !. !. !. ,% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . + z/ !. !. !. !. !. !. !. -| # . . . . . . . . . . . . . . . . . . . . . . 6+ !. !. !. !. !. !. !. !. Z . . . . . n i+ !. !. !. !. !. !. !. [~ . . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . b q. !. !. !. !. !. !. !. I@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ). '{ !. !. !. !. !. !. !. !. !. !. 8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . T h+ !. !. !. !. !. !. !. += . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u j@ !. !. !. !. !. !. !. [~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . /. !. !. !. !. !. !. !. 6] / . . . . . . . . . . . . . . . . . . . . . . =( !. !. !. !. !. !. !. h+ y . . . . . b {. !. !. !. !. !. !. !. {> - . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . 7 T+ !. !. !. !. !. !. !. ){ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ( -+ !. !. !. !. !. !. !. !. !. *+ / . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. 9, > . . . . . . . . . . . . . 9 ;| !. !. !. !. !. !. !. =+ $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . { >( !. !. !. !. !. !. !. m@ # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. %+ y . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . G~ !. !. !. !. !. !. !. 9] 7 . . . . . . . . . . . . . . . . . . . . . . u! !. !. !. !. !. !. !. 9, { . . . . . / 8] !. !. !. !. !. !. !. @= e . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . , ^) !. !. !. !. !. !. !. ;| { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g^ !. !. !. !. !. !. !. !. $+ T . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. )^ # . . . . . . . . . . . . . + k+ !. !. !. !. !. !. !. ]) 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . !{ !. !. !. !. !. !. !. T+ 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 ^@ !. !. !. !. !. !. r> r . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . !. !. !. !. !. !. !. !. K . . . . . . . . . . . . . . . . . . . . . < 9, !. !. !. !. !. !. !. N^ $ . . . . . . v. !. !. !. !. !. !. !. !. '. . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . D< !. !. !. !. !. !. !. b; K . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 x! !. !. !. !. !. !. !. !. Y# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . S !. !. !. !. !. !. !. (# * . . . . . . . . . . . . . . $= !. !. !. !. !. !. !. !. <. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $= !. !. !. !. !. !. !. !. n+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 ^@ !. !. !. !. !. !. q. T . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . 0 k@ !. !. !. !. !. !. !. m+ . . . . . . . . . . . . . . . . . . . . . z. q. !. !. !. !. !. !. !. p@ . . . . . . . H+ !. !. !. !. !. !. !. !. I| . . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . J b; !. !. !. !. !. !. !. w. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6+ q. !. !. !. !. !. !. !. i( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g+ !. !. !. !. !. !. !. w! ~ . . . . . . . . . . . . . . q !. !. !. !. !. !. !. !. b_ * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . l q. !. !. !. !. !. !. !. ]. & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 %+ !. !. !. !. !. !. !. q# . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . = j+ !. !. !. !. !. !. !. x! = . . . . . . . . . . . . . . . . . . . . v. !. !. !. !. !. !. !. !. f+ . . . . . . . ). !. !. !. !. !. !. !. !. w! 9 . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . ^ (# !. !. !. !. !. !. !. S@ b . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . d k@ !. !. !. !. !. !. !. W+ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . T b; !. !. !. !. !. !. S@ v . . . . . . . . . . . . . . & x! !. !. !. !. !. !. !. !. P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - 7] !. !. !. !. !. !. !. !. 8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] {. !. !. !. !. !. !. !. 4+ . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . O. !. !. !. !. !. !. !. r> I . . . . . . . . . . . . . . . . . . . h 9] !. !. !. !. !. !. !. z/ ^ . . . . . . . ( b_ !. !. !. !. !. !. !. !. p@ . . . . . . . . . . . . . . . . . . . . a@ !. !. !. !. !. !. !. u! . . . . . . . . . . I| !. !. !. !. !. !. !. !. ;( . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % ~2 !. !. !. !. !. !. !. /. > . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m <' !. !. !. !. !. !. !. p# . . . . . . . . . . . . . . . 6+ h+ !. !. !. !. !. !. !. &+ 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6+ !. !. !. !. !. !. !. !. ^@ u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , 9, !. !. !. !. !. !. !. !{ . . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . w k@ !. !. !. !. !. !. !. {> $ . . . . . . . . . . . . . . . . . . V@ !. !. !. !. !. !. !. !. D< . . . . . . . . . G~ !. !. !. !. !. !. !. !. S@ i . . . . . . . . . . . . . . . . . . . 9. !. !. !. !. !. !. !. u! . . . . . . . . . . o i+ !. !. !. !. !. !. !. j@ ` . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . < 1/ !. !. !. !. !. !. !. !{ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.*@.=@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . b w! !. !. !. !. !. !. !. =+ % . . . . . . . . . . . . . . ; m@ !. !. !. !. !. !. !. !. _# { . . . . . . . . . . . . . . . . . . . . . % . . . . . . . . . . . . . . / 6] !. !. !. !. !. !. !. !. >| 7 . . . . . . . . . . . . . . . . . . . . - 8 . . . . . . . . . . . . . # 7] !. !. !. !. !. !. !. s. _ . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . j( !. !. !. !. !. !. !. !. Y+ . . . . . . . . . . . . . . . . . Z j@ !. !. !. !. !. !. !. k@ p . . . . . . . . . c k@ !. !. !. !. !. !. !. !. /~ e . . . . . . . . . . . . . . . . . . P. !. !. !. !. !. !. !. u! . . . . . . . . . . . 2/ !. !. !. !. !. !. !. !. w! W . . . . . . . . . . . . . . . . . . . . . ; . . . . . . . . . . . . . . . ). 5 . . . . . . . . . . . . . . . . M r> !. !. !. !. !. !. !. 2/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.-@.b@.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ( y# !. !. !. !. !. !. !. h+ <. . . . . . . . . . . . . . . . }# !. !. !. !. !. !. !. !. !. ){ x . . . . . . . . . . . . . . . . . . 8 o@ j( . . . . . . . . . . . . . . . p# !. !. !. !. !. !. !. !. !. -( | . . . . . . . . . . . . . . . . . . 5 :# W+ . . . . . . . . . . . . . . _. !. !. !. !. !. !. !. !. O. . . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . k r. !. !. !. !. !. !. !. s. l . . . . . . . . . . . . . . . m 1/ !. !. !. !. !. !. !. !. j( . . . . . . . . . . . j( !. !. !. !. !. !. !. !. !. _# 0 . . . . . . . . . . . . . . . . ; :# !. !. !. !. !. !. !. u! . . . . . . . . . . . b <' !. !. !. !. !. !. !. !. b_ l . . . . . . . . . . . . . . . . . . # !) =+ ^ . . . . . . . . . . . . . ' >| &+ I+ # . . . . . . . . . . . . . . I@ !. !. !. !. !. !. !. !. !) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q U+.c@.d@.e@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.f@.E+._@.. . . . . . . . . . )) !. !. !. !. !. !. !. !. <' f+ . . . . . . . . . . . . . . > n@ !. !. !. !. !. !. !. !. !. 8] K . . . . . . . . . . . . . . . $ '. ,; !. h+ J . . . . . . . . . . . . . . & 8> !. !. !. !. !. !. !. !. !. ;| Z # . . . . . . . . . . . . . . 8 :. &+ !. h+ k . . . . . . . . . . . . . . !. !. !. !. !. !. !. !. %+ M . . . . . . . . . . . . . . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . $ ,{ !. !. !. !. !. !. !. !. )^ u . . . . . . . . . . . . . v z/ !. !. !. !. !. !. !. !. 1/ 4 . . . . . . . . . . . h k@ !. !. !. !. !. !. !. !. !. )^ }# # . . . . . . . . . . . . . x b, !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . D< !. !. !. !. !. !. !. !. !. P^ P $ . . . . . . . . . . . . . . . n N^ !. !. n+ . . . . . . . . . . . . . U !. !. !. A/ I $ . . . . . . . . . . . u @= !. !. !. !. !. !. !. M! s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q qu g@.h@.i@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.j@.k@.l@.. . . . . . . . . . Q. !. !. !. !. !. !. !. !. !. r. x. 0 . . . . . . . . . . . . . _ v! !. !. !. !. !. !. !. !. !. r. (. M @ . . . . . . . . . . : ` ){ $+ !. !. !. 7] - . . . . . . . . . . . . . . 6 ]. !. !. !. !. !. !. !. !. !. !. =+ R { . . . . . . . . . . b G+ ]. !. !. !. !. l+ + . . . . . . . . . . . . : 8] !. !. !. !. !. !. !. !. 9, }# + . . . . . . . . l :. ^ . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . { >( !. !. !. !. !. !. !. !. k@ n+ [ . . . . . . . . . & y. k@ !. !. !. !. !. !. !. !. h+ a. . . . . . . . . . . . . . 8. !. !. !. !. !. !. !. !. !. !. h+ /. . ) . . . . . . . . . } n+ /@ !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . > ]: !. !. !. !. !. !. !. !. !. !. =+ H = . . . . . . . . . . ' j (. S+ !. !. !. 1/ 5 . . . . . . . . . . . . j( !. !. !. !. $+ =+ R. ] . . . . . . . + . 6] !. !. !. !. !. !. !. !. b_ f . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q pq U+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.m@.Q+.. . . . . . . . . . ~ ;| !. !. !. !. !. !. !. !. !. !. ]) k+ ,{ [. . . . . . . . . . . . 2 (# !. !. !. !. !. !. !. !. !. !. M! U@ w. b. j 1 e b t L $= -| >( !. !. !. !. !. !. !. K@ . . . . . . . . . . . . . . . s S+ !. !. !. !. !. !. !. !. !. !. !. b_ v. $= I r } x M ` [* X( 1/ !. !. !. !. !. !. S+ z . . . . . . . . . . . . . G+ !. !. !. !. !. !. !. !. !. !. X( $= }. b 7 M z. O. X( ~. !. 3 . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . '. r. !. !. !. !. !. !. !. !. !. x! m+ k g ( / [ : | D< ,; !. !. !. !. !. !. !. !. !. !. n{ $ . . . . . . . . . . . . . > -| !. !. !. !. !. !. !. !. !. !. !. !. t. N^ $= R j | e V Q I| ;| !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . 8 z# !. !. !. !. !. !. !. !. !. !. !. ^. (. ,% s y e } k t <. F[ }* $+ !. !. !. !. !. !. g^ . . . . . . . . . . . ~ T@ !. !. !. !. !. !. !. 6] i( q# V 7 n R. a@ A/ !. !. !. !. !. !. !. !. !. !. O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q R+.n@.. . . . . . . . . . . !) !. !. !. !. !. !. !. !. !. !. !. !. !. n@ . . . . . . . . . . . . J <' !. !. !. !. !. !. !. !. !. !. !. !. !. h+ r. r> b; h+ h+ !. !. !. !. !. !. !. !. !. !. &+ d . . . . . . . . . . . . . . . P 9] !. !. !. !. !. !. !. !. !. !. !. !. !. !. q. j@ r> q. !. !. !. !. !. !. !. !. !. !. !. ;+ . . . . . . . . . . . . . ( z/ !. !. !. !. !. !. !. !. !. !. !. !. b; r> q. !. !. !. !. !. R . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . O. !. !. !. !. !. !. !. !. !. !. !. q. S+ z/ 6] b_ P^ b; !. !. !. !. !. !. !. !. !. !. !. 7] ~ . . . . . . . . . . . . . . . 6 y# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. h+ b; r> $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . p z/ !. !. !. !. !. !. !. !. !. !. !. !. !. h+ $+ r> j@ q. h+ !. !. !. !. !. !. !. !. !. !. j@ T . . . . . . . . . . P !. !. !. !. !. !. !. !. !. !. !. $+ r> $+ !. !. !. !. !. !. !. !. !. !. !. !. 6] [ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q R+.n@.. . . . . . . . . . . < x! !. !. !. !. !. !. !. !. !. !. !. !. v. . . . . . . . . . . . . . '. ;| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. X+ . . . . . . . . . . . . . . . . }# s. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. k@ z . . . . . . . . . . . . . I j@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. >+ . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . y. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. X( ! . . . . . . . . . . . . . . . . . a >| !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . b j+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. :# + . . . . . . . . # A/ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ }. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q R+.n@.. . . . . . . . . . . . 0 ~2 !. !. !. !. !. !. !. !. !. !. !. )) . . . . . . . . . . . . . . | '{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. =+ b . . . . . . . . . . . . . . . . . y b_ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. M! R. . . . . . . . . . . . . . . $= !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. l+ . . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q. M! !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. -| < . . . . . . . . . . . . . . . . . . . } _# !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. M! y# !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . { n{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. >| r . . . . . . . . . W !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. %+ R. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Q+.R+.-q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q -q R+.n@.. . . . . . . . . . . . . v ,; !. !. !. !. !. !. !. !. !. !. )) . . . . . . . . . . . . . . . / ;( ^@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ]. 9. - . . . . . . . . . . . . . . . . . . . x }~ S@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r> )) y % . . . . . . . . . . . . . . . !) h+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. m@ + . . . . . . . W ^@ !. !. !. !. !. !. S+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . '. '{ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T+ _~ , . . . . . . . . . . . . . . . . . . . . . < j( j@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ^@ 7+ H+ !. !. !. !. !. !. !. u! . . . . . . . . . . . . . . . . . $ n+ ]) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T@ :~ { . . . . . . . . . . w F[ <' !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. ~2 g+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o@.:@.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.W+.:@.Q+.. . . . . . . . . . . . . . ^ =( %+ !. !. !. !. !. !. !. !. )) . . . . . . . . . . . . . . . . . u (. r. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. r. m@ P. < . . . . . . . . . . . . . . . . . . . . . . . ). v. $+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. w! <# L . . . . . . . . . . . . . . . . . . . 0. `) !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. T+ g . . . . . . . q b; !. !. !. !. !. !. q. ~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , O U+ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. b; 1' 2 . . . . . . . . . . . . . . . . . . . . . . . . . T u. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. q. k+ l . :. !. !. !. !. !. !. !. V+ . . . . . . . . . . . . . . . . . . . p _. k@ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. $+ t. I@ c . . . . . . . . . . . . . . m i( P^ !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. !. S+ g^ 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p@.q@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.r@.q@.s@.. . . . . . . . . . . . . . . . c X+ -( ~. !. !. !. !. !. N^ . . . . . . . . . . . . . . . . . . . ). 2/ 7] S+ !. !. !. !. !. !. !. !. !. !. !. !. b_ W+ :. h - . . . . . . . . . . . . . . . . . . . . . . . . . . + ). [# m@ %+ !. !. !. !. !. !. !. !. !. !. !. !. @= (@ )) b. _ . . . . . . . . . . . . . . . . . . . . . . c _@ &+ !. !. !. !. !. !. !. !. !. !. !. !. ]) v! 1' e . . . . . . . | >( (# ;| ;| ;| ;| (# y# { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . { Q. b, 8] !. !. !. !. !. !. !. !. !. !. !. <' U@ Z) ). . . . . . . . . . . . . . . . . . . . . . . . . . . . . , 7+ -+ U+ !. !. !. !. !. !. !. !. !. !. j@ 6] l+ k # . . b. v! ,; ,; ,; ,; ,; -( m+ . . . . . . . . . . . . . . . . . . . . . 0 :~ {> P^ !. !. !. !. !. !. !. !. !. !. !. !. /@ A/ I@ i / . . . . . . . . . . . . . . . . . . ~ Y+ V@ z/ b; !. !. !. !. !. !. !. !. !. !. !. S@ ,; G~ 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t@.u@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.v@.u@.w@.. . . . . . . . . . . . . . . . . . * l o+ C< (. u! x! G~ . . . . . . . . . . . . . . . . . . . . . , V <. Z) l+ :# ,; 7] :# (. ;( !) 9. L { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ n <. D< o@ b, U@ 7] j+ W+ l+ j( Y# . o [ . . . . . . . . . . . . . . . . . . . . . . . . . . . c 5+ _@ %= 7] 7] '{ b, l+ Y( O^ @& '. 4 ' . . . . . . . . . ; w 5 } } } } 5 d # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . g Y $= Z( 1' =+ ,; '{ b, g^ D< <. n # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ! . >+ C< (. ^) j+ b, 1' m+ Q. i ) . . . . . # = & & & & & * ; . . . . . . . . . . . . . . . . . . . . . . . . 1 I+ O^ j( W+ _# 7] =+ (. w. O. y. S 6 . . . . . . . . . . . . . . . . . . . . . . . . . 7 k 5+ <~ (. :# 7] j+ 7] #= (. += q# m & . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ , # . . . . . . . . . . . . . . . . . . . . . . . . . . @ ; % @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . > % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ ; % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ % % % @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "}; diff --git a/parcels_label_name.txt b/parcels_label_name.txt new file mode 100644 index 0000000..9fcf3a0 --- /dev/null +++ b/parcels_label_name.txt @@ -0,0 +1,82 @@ +1 L_VCcm +2 L_VCl +3 L_VCs +4 L_Cu +5 L_VCrm +6 L_ITCm +7 L_ITCr +8 L_MTCc +9 L_STCc +10 L_STCr +11 L_MTCr +13 L_IPCv +14 L_IPCd +15 L_SPC +16 L_SPCm +17 L_PCm +19 L_Sv +20 L_Sdl +21 L_Sdm +12 L_ICC +18 L_PCC +30 L_MCC +40 L_ACC +22 L_Mv +23 L_Mdl +24 L_Mdm +25 L_PMrv +26 L_PMdl +27 L_PMdm +28 L_PFcdl +29 L_PFcdm +31 L_PFrvl +32 L_Pfrdli +33 L_Pfrdls +34 L_PFrd +35 L_PFrm +36 L_OFCvl +37 L_OFCv +38 L_OFCvm +39 L_PFCvm +41 L_Insula +101 R_VCcm +102 R_VCl +103 R_VCs +104 R_Cu +105 R_VCrm +106 R_ITCm +107 R_ITCr +108 R_MTCc +109 R_STCc +110 R_STCr +111 R_MTCr +113 R_IPCv +114 R_IPCd +115 R_SPC +116 R_SPCm +117 R_PCm +119 R_Sv +120 R_Sdl +121 R_Sdm +112 R_ICC +118 R_PCC +130 R_MCC +140 R_ACC +122 R_Mv +123 R_Mdl +124 R_Mdm +125 R_PMrv +126 R_PMdl +127 R_PMdm +128 R_PFcdl +129 R_PFcdm +131 R_PFrvl +132 R_Pfrdli +133 R_Pfrdls +134 R_PFrd +135 R_PFrm +136 R_OFCvl +137 R_OFCv +138 R_OFCvm +139 R_PFCvm +141 R_Insula diff --git a/parcels_label_name_AAL.txt b/parcels_label_name_AAL.txt new file mode 100644 index 0000000..9bdadb3 --- /dev/null +++ b/parcels_label_name_AAL.txt @@ -0,0 +1,116 @@ +2001 Precentral_L +2002 Precentral_R +2101 Frontal_Sup_L +2102 Frontal_Sup_R +2111 Frontal_Sup_Orb_L +2112 Frontal_Sup_Orb_R +2201 Frontal_Mid_L +2202 Frontal_Mid_R +2211 Frontal_Mid_Orb_L +2212 Frontal_Mid_Orb_R +2301 Frontal_Inf_Oper_L +2302 Frontal_Inf_Oper_R +2311 Frontal_Inf_Tri_L +2312 Frontal_Inf_Tri_R +2321 Frontal_Inf_Orb_L +2322 Frontal_Inf_Orb_R +2331 Rolandic_Oper_L +2332 Rolandic_Oper_R +2401 Supp_Motor_Area_L +2402 Supp_Motor_Area_R +2501 Olfactory_L +2502 Olfactory_R +2601 Frontal_Sup_Medial_L +2602 Frontal_Sup_Medial_R +2611 Frontal_Med_Orb_L +2612 Frontal_Med_Orb_R +2701 Rectus_L +2702 Rectus_R +3001 Insula_L +3002 Insula_R +4001 Cingulum_Ant_L +4002 Cingulum_Ant_R +4011 Cingulum_Mid_L +4012 Cingulum_Mid_R +4021 Cingulum_Post_L +4022 Cingulum_Post_R +4101 Hippocampus_L +4102 Hippocampus_R +4111 ParaHippocampal_L +4112 ParaHippocampal_R +4201 Amygdala_L +4202 Amygdala_R +5001 Calcarine_L +5002 Calcarine_R +5011 Cuneus_L +5012 Cuneus_R +5021 Lingual_L +5022 Lingual_R +5101 Occipital_Sup_L +5102 Occipital_Sup_R +5201 Occipital_Mid_L +5202 Occipital_Mid_R +5301 Occipital_Inf_L +5302 Occipital_Inf_R +5401 Fusiform_L +5402 Fusiform_R +6001 Postcentral_L +6002 Postcentral_R +6101 Parietal_Sup_L +6102 Parietal_Sup_R +6201 Parietal_Inf_L +6202 Parietal_Inf_R +6211 SupraMarginal_L +6212 SupraMarginal_R +6221 Angular_L +6222 Angular_R +6301 Precuneus_L +6302 Precuneus_R +6401 Paracentral_Lobule_L +6402 Paracentral_Lobule_R +7001 Caudate_L +7002 Caudate_R +7011 Putamen_L +7012 Putamen_R +7021 Pallidum_L +7022 Pallidum_R +7101 Thalamus_L +7102 Thalamus_R +8101 Heschl_L +8102 Heschl_R +8111 Temporal_Sup_L +8112 Temporal_Sup_R +8121 Temporal_Pole_Sup_L +8122 Temporal_Pole_Sup_R +8201 Temporal_Mid_L +8202 Temporal_Mid_R +8211 Temporal_Pole_Mid_L +8212 Temporal_Pole_Mid_R +8301 Temporal_Inf_L +8302 Temporal_Inf_R +9001 Cerebelum_Crus1_L +9002 Cerebelum_Crus1_R +9011 Cerebelum_Crus2_L +9012 Cerebelum_Crus2_R +9021 Cerebelum_3_L +9022 Cerebelum_3_R +9031 Cerebelum_4_5_L +9032 Cerebelum_4_5_R +9041 Cerebelum_6_L +9042 Cerebelum_6_R +9051 Cerebelum_7b_L +9052 Cerebelum_7b_R +9061 Cerebelum_8_L +9062 Cerebelum_8_R +9071 Cerebelum_9_L +9072 Cerebelum_9_R +9081 Cerebelum_10_L +9082 Cerebelum_10_R +9100 Vermis_1_2 +9110 Vermis_3 +9120 Vermis_4_5 +9130 Vermis_6 +9140 Vermis_7 +9150 Vermis_8 +9160 Vermis_9 +9170 Vermis_10 diff --git a/parcels_label_name_AALDilate.txt b/parcels_label_name_AALDilate.txt new file mode 100644 index 0000000..cf33639 --- /dev/null +++ b/parcels_label_name_AALDilate.txt @@ -0,0 +1,116 @@ +1 Precentral_L +2 Precentral_R +3 Frontal_Sup_L +4 Frontal_Sup_R +5 Frontal_Sup_Orb_L +6 Frontal_Sup_Orb_R +7 Frontal_Mid_L +8 Frontal_Mid_R +9 Frontal_Mid_Orb_L +10 Frontal_Mid_Orb_R +11 Frontal_Inf_Oper_L +12 Frontal_Inf_Oper_R +13 Frontal_Inf_Tri_L +14 Frontal_Inf_Tri_R +15 Frontal_Inf_Orb_L +16 Frontal_Inf_Orb_R +17 Rolandic_Oper_L +18 Rolandic_Oper_R +19 Supp_Motor_Area_L +20 Supp_Motor_Area_R +21 Olfactory_L +22 Olfactory_R +23 Frontal_Sup_Medial_L +24 Frontal_Sup_Medial_R +25 Frontal_Med_Orb_L +26 Frontal_Med_Orb_R +27 Rectus_L +28 Rectus_R +29 Insula_L +30 Insula_R +31 Cingulum_Ant_L +32 Cingulum_Ant_R +33 Cingulum_Mid_L +34 Cingulum_Mid_R +35 Cingulum_Post_L +36 Cingulum_Post_R +37 Hippocampus_L +38 Hippocampus_R +39 ParaHippocampal_L +40 ParaHippocampal_R +41 Amygdala_L +42 Amygdala_R +43 Calcarine_L +44 Calcarine_R +45 Cuneus_L +46 Cuneus_R +47 Lingual_L +48 Lingual_R +49 Occipital_Sup_L +50 Occipital_Sup_R +51 Occipital_Mid_L +52 Occipital_Mid_R +53 Occipital_Inf_L +54 Occipital_Inf_R +55 Fusiform_L +56 Fusiform_R +57 Postcentral_L +58 Postcentral_R +59 Parietal_Sup_L +60 Parietal_Sup_R +61 Parietal_Inf_L +62 Parietal_Inf_R +63 SupraMarginal_L +64 SupraMarginal_R +65 Angular_L +66 Angular_R +67 Precuneus_L +68 Precuneus_R +69 Paracentral_Lobule_L +70 Paracentral_Lobule_R +71 Caudate_L +72 Caudate_R +73 Putamen_L +74 Putamen_R +75 Pallidum_L +76 Pallidum_R +77 Thalamus_L +78 Thalamus_R +79 Heschl_L +80 Heschl_R +81 Temporal_Sup_L +82 Temporal_Sup_R +83 Temporal_Pole_Sup_L +84 Temporal_Pole_Sup_R +85 Temporal_Mid_L +86 Temporal_Mid_R +87 Temporal_Pole_Mid_L +88 Temporal_Pole_Mid_R +89 Temporal_Inf_L +90 Temporal_Inf_R +91 Cerebelum_Crus1_L +92 Cerebelum_Crus1_R +93 Cerebelum_Crus2_L +94 Cerebelum_Crus2_R +95 Cerebelum_3_L +96 Cerebelum_3_R +97 Cerebelum_4_5_L +98 Cerebelum_4_5_R +99 Cerebelum_6_L +100 Cerebelum_6_R +101 Cerebelum_7b_L +102 Cerebelum_7b_R +103 Cerebelum_8_L +104 Cerebelum_8_R +105 Cerebelum_9_L +106 Cerebelum_9_R +107 Cerebelum_10_L +108 Cerebelum_10_R +109 Vermis_1_2 +110 Vermis_3 +111 Vermis_4_5 +112 Vermis_6 +113 Vermis_7 +114 Vermis_8 +115 Vermis_9 +116 Vermis_10 diff --git a/parcels_label_name_Hammers.txt b/parcels_label_name_Hammers.txt new file mode 100644 index 0000000..3e09999 --- /dev/null +++ b/parcels_label_name_Hammers.txt @@ -0,0 +1,83 @@ +1 Hippocampus_r +2 Hippocampus_l +3 Amygdala_r +4 Amygdala_l +5 Ant_TL_med_r +6 Ant_TL_med_l +7 Ant_TL_inf_lat_r +8 Ant_TL_inf_lat_l +9 G_paraH_amb_r +10 G_paraH_amb_l +11 G_sup_temp_cent_r +12 G_sup_temp_cent_l +13 G_tem_midin_r +14 G_tem_midin_l +15 G_occtem_la_r +16 G_occtem_la_l +17 Cerebellum_r +18 Cerebellum_l +19 Brainstem +20 Insula_l +21 Insula_r +22 OL_rest_lat_l +23 OL_rest_lat_r +24 G_cing_ant_sup_l +25 G_cing_ant_sup_r +26 G_cing_post_l +27 G_cing_post_r +28 FL_mid_fr_G_l +29 FL_mid_fr_G_r +30 PosteriorTL_l +31 PosteriorTL_r +32 PL_rest_l +33 PL_rest_r +34 CaudateNucl_l +35 CaudateNucl_r +36 NuclAccumb_l +37 NuclAccumb_r +38 Putamen_l +39 Putamen_r +40 Thalamus_l +41 Thalamus_r +42 Pallidum_l +43 Pallidum_r +44 Corp_Callosum +45 FrontalHorn_r +46 FrontalHorn_l +47 TemporaHorn_r +48 TemporaHorn_l +49 ThirdVentricl +50 FL_precen_G_l +51 FL_precen_G_r +52 FL_strai_G_l +53 FL_strai_G_r +54 FL_OFC_AOG_l +55 FL_OFC_AOG_r +56 FL_inf_fr_G_l +57 FL_inf_fr_G_r +58 FL_sup_fr_G_l +59 FL_sup_fr_G_r +60 PL_postce_G_l +61 PL_postce_G_r +62 PL_sup_pa_G_l +63 PL_sup_pa_G_r +64 OL_ling_G_l +65 OL_ling_G_r +66 OL_cuneus_l +67 OL_cuneus_r +68 FL_OFC_MOG_l +69 FL_OFC_MOG_r +70 FL_OFC_LOG_l +71 FL_OFC_LOG_r +72 FL_OFC_POG_l +73 FL_OFC_POG_r +74 S_nigra_l +75 S_nigra_r +76 Subgen_antCing_l +77 Subgen_antCing_r +78 Subcall_area_l +79 Subcall_area_r +80 Presubgen_antCing_l +81 Presubgen_antCing_r +82 G_sup_temp_ant_l +83 G_sup_temp_ant_r diff --git a/pathologypatientinfo.py b/pathologypatientinfo.py new file mode 100644 index 0000000..9837c90 --- /dev/null +++ b/pathologypatientinfo.py @@ -0,0 +1,326 @@ +# -*- coding: utf-8 -*- +# +# Functions to create UI, read and write patient data +# such as type of epilepsy, disease history... +#, and dictionary of available processing methods for each manip type +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 + +from PyQt4 import QtGui, QtCore +import pdb, os, json +from brainvisa.data.writediskitem import ReadDiskItem, WriteDiskItem + +# Types : Text, Line (short text) Int (integer), Float, Bool, Choice, MultiSelectChoice, EditableChoice (list of values, but a new one may be entered) +EpilepsyInfoTable= ('AgeDebutCrise',('Choice',[str(i) for i in range(-1,100)], u'Age du début des crises'), + 'Aura',('Choice2',[u'Inconnu',u'Aucune', u'Abdominal', u'Auditory', u'Autonomic', u'Gustatory', u'Olfactory', u'Psychic', u'Somatosensory', u'Visual'], u'Aura'), + 'Seizure',('Choice',[u'Inconnu', u'Automotor', u'Autonomic', u'Dialeptic', u'Dyscognitive', u'Hypermotor', u'Hypomotor', u'Simple Motor'],'Seizure Type'), + 'seizureFrequency', ('Choice', [u'Inconnu',u'quotidienne', u'hebdomadaire', u'mensuelle', u' < 1/mois'], u'Fréquence des crises'), + 'TraitementTried', ('Choice2', [u'Inconnu',u'carbamazépine', u'phénytoine', u'phénobarbital', u'valproate'], u'Traitement essayés (DCI)'), + 'TraitementNow', ('Choice2', [u'Inconnu',u'carbamazépine', u'phénytoine', u'phénobarbital', u'valproate'], u'Traitement actuel'), + ) + +AlzheimerInfoTable = ('AgeDebutCrise',('Choice',[str(i) for i in range(-1,100)], u'Test'), + 'Aura',('Choice2',[u'Inconnu',u'Aucune', u'Abdominal', u'Auditory', u'Autonomic', u'Gustatory', u'Olfactory', u'Psychic', u'Somatosensory', u'Visual'], u'Test'), + 'Seizure',('Choice',[u'Inconnu', u'Automotor', u'Autonomic', u'Dialeptic', u'Dyscognitive', u'Hypermotor', u'Hypomotor', u'Simple Motor'],'Test'), + 'seizureFrequency', ('Choice', [u'Inconnu',u'quotidienne', u'hebdomadaire', u'mensuelle', u' < 1/mois'], u'Test'), + 'TraitementTried', ('Choice2', [u'Inconnu',u'carbamazépine', u'phénytoine', u'phénobarbital', u'valproate'], u'Test'), + 'TraitementNow', ('Choice2', [u'Inconnu',u'carbamazépine', u'phénytoine', u'phénobarbital', u'valproate'], u'Test'), + ) + +#ParkinsonInfoTable + +#DepressionInfoTable + +#DystonieInfotable + +#TOCInfoTable + +#AVC + + +def buildInt(parent, mini, maxi, label): + lay = QtGui.QHBoxLayout() + sp = QtGui.QSpinBox(parent) + sp.setRange(mini, maxi) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(sp) + return (lay, sp) + +def buildChoice(parent, values, label): + lay = QtGui.QHBoxLayout() + combo = QtGui.QComboBox(parent) + combo.clear() + combo.addItems(values) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combo) + return (lay, combo) + +def buildChoice2(parent, values, label): + lay = QtGui.QHBoxLayout() + combo = QtGui.QComboBox(parent) + combo.clear() + model = QtGui.QStandardItemModel(len(values), 1)# 5 rows, 1 col + + for i,area in enumerate(values): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + + combo.setModel(model) + combo.setEditable(True) + combo.activated.connect(lambda index, comb=combo: validatenewCombo(comb, index)) + #pdb.set_trace() + + #combo.addItems(values) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combo) + return (lay, combo) + +def buildChoiceSub(parent, values, label): + lay = QtGui.QHBoxLayout() + + combosub = QtGui.QMenu(parent) + combosub.setTitle(u'Comorbitité menu') + + for i,area in enumerate(values): + menu = QtGui.QMenu(area) + + combosub.addMenu(menu) + + #pdb.set_trace() + if i<2: + menu.addAction(QtGui.QAction(area, menu, checkable = True)) + else: + #for ii, area2 in enumerate(subvalues) + menu.addAction(QtGui.QAction("pouet", menu, checkable = True)) + + + + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combosub) + return (lay, combosub) + +def buildDate(parent, date, label): + lay = QtGui.QHBoxLayout() + qdate = QtGui.QDateEdit(parent) + qdate.setDisplayFormat('dd/MM/yyyy') + if date is None: + qdate.setDate(QtCore.QDate.fromString('1900-01-01', 'yyyy-MM-dd')) + else: + qdate.setDate(date) + lay.addWidget(QtGui.QLabel(label,parent=parent)) + lay.addWidget(qdate) + return (lay, qdate) + + +def buildText(parent, label): + lay = QtGui.QHBoxLayout() + text = QtGui.QTextEdit(parent) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(text) + return (lay, text) + +def buildLine(parent, defaultValue, label): + lay = QtGui.QHBoxLayout() + line = QtGui.QLineEdit(parent) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + if defaultValue: + line.setText(str(defaultValue)) + lay.addWidget(line) + return (lay, line) + +def buildCompound(parent, values, label): + lay = QtGui.QHBoxLayout() + frame = QtGui.QGroupBox(parent) + frame.setLayout(lay) + if label is not None: + frame.setTitle(str(label)) + widgets = buildUI(frame, values) + for wid in reversed(widgets.values()): + lay.addWidget(wid) + return (frame, [frame,]+widgets.values()) + +def buildButtonBox(parent,values,label): + lay = QtGui.QHBoxLayout() + buttbox = QtGui.QDialogButtonBox(parent) + for i,area in enumerate(values): + buttbox.addButton(area,3) + + for test in buttbox.findChildren(QtGui.QPushButton): + test.setCheckable(True) + + buttbox.clicked.connect(lambda index, comb=buttbox: MRIlesionbox(comb, index)) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(buttbox) + return (lay,buttbox) + +def buildLabel(parent,label): + lay = QtGui.QHBoxLayout() + labe = QtGui.QLabel(parent) + labe.setText(label) + + lay.addWidget(labe) + return (lay, labe) + + + +def buildCheckbox(parent, label, label2, checkbox_connect): + #function_mapping = {'checkbox_comor':checkbox_comor} + lay = QtGui.QHBoxLayout() + qcheck = QtGui.QCheckBox(parent) + qcheck.setText(label) + + #qcheck.clicked.connect(lambda index, ChecK=qcheck: function_mapping[checkbox_connect](ChecK, index)) + + lay.addWidget(QtGui.QLabel(label2, parent=parent)) + lay.addWidget(qcheck) + return (lay, qcheck) + + +uiBuild = {'Int': buildInt, + 'Float':lambda:(None, None),# Not implemented + 'Line':buildLine, + 'Text':buildText, + 'Bool':lambda:(None, None),# Not implemented + 'Date':lambda p, value,label:(None, None),# Not implemented + 'Date2':buildDate, + 'Choice':buildChoice, + 'Choice2':buildChoice2, + 'ChoiceSub':buildChoiceSub, + 'ButtonBox':buildButtonBox, + 'MultiSelectChoice':lambda p, values, label:(None, None),# Not implemented + 'EditableChoice':lambda p,v,l : buildChoice(p,v,l,True), + 'Compound':buildCompound, + 'Label':buildLabel, + 'Checkbox':buildCheckbox, + } + +def buildUI(parent, infoTabletext=EpilepsyInfoTable): + """ Generates a UI from infoTable) and returns a dictionary with the generated widgets""" + #remove all children remove + #pdb.set_trace() + if parent.children(): + lay = parent.children()[0] + clearLayout(lay) + #pdb.set_trace() + #for i in reversed(range(lay.count())): + #pdb.set_trace() + #widgetToRemove = lay.itemAt(i).widget() #la widget serait à lay.itemAt(i).itemAt(j).widget() + # remove it from the layout list + #lay.removeWidget( widgetToRemove ) + # remove it from the gui + #widgetToRemove.setParent( None ) + + else: + lay = QtGui.QVBoxLayout(parent) + + + #si c est un choice2 c'est editable du coup faut aller chercher sur le json la derniere version de la liste + wdi_global = ReadDiskItem('PatientInfoTemplate','Patient Template format') + di_global = list(wdi_global.findValues({}, None, False)) + + if len(di_global) > 0: + if os.path.isfile(str(di_global[0])): + print "read previous patienttemplate json" + from codecs import open as opencodecs + fin = opencodecs(str(di_global[0]),'r','latin1') + info_dicti = json.loads(fin.read().decode('latin1')) + fin.close() + + previous_lists_path_full = info_dicti['PathoSpecific'] + if infoTabletext in info_dicti['PathoSpecific'].keys(): + previous_lists_path_protocol = info_dicti['PathoSpecific'][infoTabletext] + else: + previous_lists_path_protocol = {} + + else: + previous_lists_path_full = {} + previous_lists_path_protocol = {} + + else: + previous_lists_path_full = {} + previous_lists_path_protocol = {} + + output = {} + CorresPatho={'':EpilepsyInfoTable,'Epilepsy':EpilepsyInfoTable, 'Alzheimer':AlzheimerInfoTable} + if infoTabletext is None: + infoTable=EpilepsyInfoTable + else: + #pdb.set_trace() + if infoTabletext in CorresPatho.keys(): + infoTable = CorresPatho[infoTabletext] + else: + infoTable=EpilepsyInfoTable + #infoTable = var()[infoTableText] + + for i in range(int(len(infoTable)/2)): + key = infoTable[2*i] + value = infoTable[2*i+1] + if key in previous_lists_path_protocol.keys(): + default_list = set(value[1]) + update_list = set(previous_lists_path_protocol[key]) + diff_list = update_list-default_list + final_list = value[1] + list(diff_list) + item1 = value[0] + item3= value[2] + value = (item1,final_list,item3) + if value is not None: + (l,wid) = uiBuild[value[0]](parent, *(value[1:])) + if l is not None: + if isinstance(l, QtGui.QLayout): + lay.addLayout(l) + elif isinstance(l, QtGui.QWidget): + lay.addWidget(l) + else: + print "Neither a layout nor a widget : cannot add object to the layout !" + if wid is not None: + output[key]=wid + return output + +def clearLayout(layout): + for i in reversed(range(layout.count())): + item = layout.itemAt(i) + + if isinstance(item, QtGui.QWidgetItem): + print "widget" + str(item) + item.widget().close() + # or + # item.widget().setParent(None) + elif isinstance(item, QtGui.QSpacerItem): + print "spacer " + str(item) + # no need to do extra stuff + else: + print "layout " + str(item) + clearLayout(item.layout()) + + # remove the item from layout + layout.removeItem(item) + + +def dumpState(structuredWidgets): + """Generates a dumpable object that represents the content of the patient info from the widgets""" + pass + + +def validatenewCombo(combo_modified, selectedIndex): + + AllItems = [unicode(combo_modified.itemText(i)) for i in range(combo_modified.count()) if unicode(combo_modified.itemText(i)) != ''] + + model = QtGui.QStandardItemModel(len(AllItems), 1) + + for i,area in enumerate(AllItems): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + + combo_modified.clear() + combo_modified.setModel(model) + combo_modified.setEditable(True) diff --git a/patientDataFilter.ui b/patientDataFilter.ui new file mode 100644 index 0000000..b8ba920 --- /dev/null +++ b/patientDataFilter.ui @@ -0,0 +1,740 @@ + + + Form + + + + 0 + 0 + 1157 + 783 + + + + Form + + + + + + 10 + + + + + QLayout::SetNoConstraint + + + + + Protocol : + + + + + + + + + + Center : + + + + + + + + + + Year : + + + + + + + + + + Atlas : + + + + + + + + MarsAtlas + + + + + Freesurfer + + + + + Brodmann + + + + + + + + Localisation : + + + + + + + QComboBox::AdjustToContents + + + + + + + Cognition Localisation : + + + + + + + + + + Cognition Type : + + + + + + + + + + Resection : + + + + + + + + + + Stim localisation : + + + + + + + + + + Stim Frequence : + + + + + + + + + + Stim Type : + + + + + + + + + + Engel Score (<) : + + + + + + + + * + + + + + Ia + + + + + Ib + + + + + Ic + + + + + Id + + + + + IIa + + + + + IIb + + + + + IIc + + + + + IId + + + + + IIIa + + + + + IIIb + + + + + IVa + + + + + IVb + + + + + IVd + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600;">Available subjects</span></p></body></html> + + + Qt::RichText + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 8 + true + + + + Select all + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 8 + true + + + + Unselect all + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Add green subjects to the selection + + + background-color: rgb(150, 255, 150); + + + -> + + + + + + + Add selected subjects to the selection + + + -> + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Remove selected subject of the selection + + + <- + + + + + + + Remove red subjects of the selection + + + background-color: rgb(255, 100, 100); + + + <- + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600;">Selected subjects</span></p></body></html> + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + QAbstractItemView::MultiSelection + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 8 + true + + + + Select all + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 8 + true + + + + Unselect all + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + Montrer pour quels patients la T1pre est disponible + + + T1pre + + + false + + + + + + + Montrer pour quels patients la T2pre est disponible + + + T2pre + + + false + + + + + + + Montrer pour quels patients la PETpre est disponible + + + PETpre + + + false + + + + + + + Montrer pour quels patients la T1post est disponible + + + T1post + + + false + + + + + + + Montrer pour quels patients la T2post est disponible + + + T2post + + + false + + + + + + + Montrer pour quels patients la CTpost est disponible + + + CTpost + + + false + + + + + + + + + Montrer pour quels patients l'implantation des électrodes est disponible + + + Implantation + + + false + + + + + + + Montrer pour quels patients le référentiel MNI est disponible + + + MNI + + + + + + + generateMNIparcels + + + + + + + Identify parcel outliers + + + + + + + + + Montrer pour quels patients la manip SEEG sélectionnée est disponible + + + SEEG + + + false + + + + + + + manip SEEG + + + + + + + + + + + + + + diff --git a/patientdatafilterwidget.py b/patientdatafilterwidget.py new file mode 100644 index 0000000..685a4f2 --- /dev/null +++ b/patientdatafilterwidget.py @@ -0,0 +1,1148 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Widget to select patients from the DB using available data as filters : needs an access +# to brainvisa database that is already set up ! (brainvisa axon.initializeProcesses() +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# +from PyQt4 import QtGui, QtCore, uic + +import sys, json, pickle, numpy, csv +import math +from collections import OrderedDict +import pdb + +from soma import aims +from brainvisa import axon +from brainvisa.data.readdiskitem import ReadDiskItem +from brainvisa.data.writediskitem import WriteDiskItem +from readElecLocalCSVFile import readElecLocalCSVFile +from readSulcusLabelTranslationFile import * + +class PatientDataFilterWidget (QtGui.QWidget): + def __init__(self, app=None): + QtGui.QWidget.__init__(self) + self.ui = uic.loadUi("patientDataFilter.ui", self) + self.pushedWidgets = [] + self.subjects = {} + #self.selectedSubjects=[] + self.filters=[] + self.filtersAtlases = {} + self.pushedWidget = [] + self.greenDotIcon = QtGui.QIcon('greendot.png') + self.filterProtocolCombo.currentIndexChanged.connect(self.updatePatientFilters) + self.filterSiteCombo.currentIndexChanged.connect(self.updatePatientFilters) + self.filterYearCombo.currentIndexChanged.connect(self.updatePatientFilters) + self.filterLocaMarsAtlas.currentIndexChanged.connect(self.updatePatientFilters) + + self.filterCognitionLoca.currentIndexChanged.connect(self.updatePatientFilters) + self.filterCognitionType.currentIndexChanged.connect(self.updatePatientFilters) + + self.filterResection.currentIndexChanged.connect(self.updatePatientFilters) + + self.filterStimulationLoca.currentIndexChanged.connect(self.updatePatientFilters) + self.filterStimulationFreq.currentIndexChanged.connect(self.updatePatientFilters) + self.filterStimulationType.currentIndexChanged.connect(self.updatePatientFilters) + + self.FilterAtlascomboBox.currentIndexChanged.connect(self.changeAtlasfiltration) + + self.filterAddPatientButton.clicked.connect(lambda:self.moveSelectedItemsToOtherListWidget(self.filteredPatientList, self.selectedPatientList)) + self.filterRemovePatientButton.clicked.connect(lambda:self.moveSelectedItemsToOtherListWidget(self.selectedPatientList, self.filteredPatientList)) + self.filterAddGreenPatientButton.clicked.connect(lambda:self.moveFilteredItemsToOtherListWidget(self.filteredPatientList, self.selectedPatientList, self.filters, reverse=False)) + self.filterRemoveRedPatientButton.clicked.connect(lambda:self.moveFilteredItemsToOtherListWidget(self.selectedPatientList, self.filteredPatientList, self.filters, reverse=True)) + + self.patientSelectAllButton.clicked.connect(lambda:self.selectAllListItems(self.filteredPatientList, True) ) + self.patientDeselectAllButton.clicked.connect(lambda:self.selectAllListItems(self.filteredPatientList, False)) + self.selectedSelectAllButton.clicked.connect(lambda:self.selectAllListItems(self.selectedPatientList, True)) + self.selectedDeselectAllButton.clicked.connect(lambda:self.selectAllListItems(self.selectedPatientList, False)) + + self.t1preButton.clicked.connect(lambda: self.toggleFilterWidget('T1pre', self.t1preButton)) + self.t1postButton.clicked.connect(lambda: self.toggleFilterWidget('T1post', self.t1postButton)) + self.t2preButton.clicked.connect(lambda: self.toggleFilterWidget('T2pre', self.t2preButton)) + self.t2postButton.clicked.connect(lambda: self.toggleFilterWidget('T2post', self.t2postButton)) + self.petpreButton.clicked.connect(lambda: self.toggleFilterWidget('PETpre', self.petpreButton)) + self.ctpostButton.clicked.connect(lambda: self.toggleFilterWidget('CTpost', self.ctpostButton)) + + self.implantationButton.clicked.connect(lambda: self.toggleFilterWidget('implantation', self.implantationButton)) + self.mniButton.clicked.connect(lambda: self.toggleFilterWidget('MNI', self.mniButton)) + self.mniParcelsButton.clicked.connect(self.mniParcelsGeneration) + self.seegButton.clicked.connect(self.toggleSeeg) + self.seegManipCombo.currentIndexChanged.connect(self.seegManipChanged) + + self.t1preButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.t1postButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.t2preButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.t2postButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.petpreButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.ctpostButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.implantationButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.mniButton.setStyleSheet("background-color: rgb(90, 90, 90);") + self.seegButton.setStyleSheet("background-color: rgb(90, 90, 90);") + + + self.populateFromDB() + + + def getSelectedPatientsNames(self): + """Returns a list of names (string) of all selected patients""" + return sorted([str(self.selectedPatientList.item(i).text()) for i in xrange(self.selectedPatientList.count())]) + + def getSelectedPatients(self): + """ Returns a list of ReadDiskItems representing the selected subjects""" + return [self.subjects[p]['rdi'] for p in self.getSelectedPatientsNames()] + + def findExistingVolumeAcquisitions(self, volType, subjectName, subjectData): + """For a subjectName, find all acquisitions in the DB of the type volType ('Raw T1 MRI') and store them in subjectData[acquisition]""" + rdi = ReadDiskItem( volType, 'aims readable volume formats', requiredAttributes={'subject':subjectName, 'center':subjectData['center']} ) + volumes = (list( rdi._findValues( {}, None, False ) )) + for v in volumes: + try: + acq = v.attributes()['acquisition'].split('_')[0] + subjectData[str(acq)] = v + except: + print "Acquisition not defined for "+repr(v.fullPath()) + + + def populateFromDB(self): + """Fills the list of patients and necessary information about patients to be able to filter""" + rdi = ReadDiskItem( 'Subject', 'Directory',requiredAttributes={'_ontology':'brainvisa-3.2.0'} ) + subjects = list( rdi._findValues( {}, None, False ) ) + self.subjects = dict([(s.attributes()['subject'], {'rdi':s, 'center':s.attributes()['center']}) for s in subjects]) + + protocols = list(set([s.attributes()['center'] for s in subjects])) + + # Fill the combos + self.filterProtocolCombo.clear() + self.filterProtocolCombo.addItems(['*',]+sorted(protocols)) + + # Update the basic filters + sites = ['*',] + sorted(set([s.split('_')[0] for s in self.subjects])) + years = ['*',] + sorted(set([s.split('_')[1] for s in self.subjects if len(s.split('_')) > 1])) + + loca = ['*'] + loca_FS = ['*'] + loca_BM = ['*'] + cogniType = ['*'] + resec = ['*'] + resec_FS = ['*'] + resec_BM = ['*'] + stimFreq = ['*'] + stimType = ['*'] + + self.filterSiteCombo.clear() + self.filterSiteCombo.addItems(sites) + self.filterYearCombo.clear() + self.filterYearCombo.addItems(years) + + #self.filterLocaMarsAtlas.addItems(loca) + #self.filterCognition.addItems(cogni) + + # Get info for all filters + + seegManips = set() + for s,subj in self.subjects.iteritems(): + print(s) + # Find the T1s/T2s/CT/PET + for modality in ['T2 MRI', 'CT', 'PET', 'Raw T1 MRI']: + self.findExistingVolumeAcquisitions(modality, s, subj) + + # Find MNI transform if T1pre is there + if 'T1pre' in subj: + rdi = ReadDiskItem( 'SPM2 normalization matrix', 'Matlab file' ) + di = rdi.findValue(subj['T1pre']) + rdi2 = ReadDiskItem('SPM normalization deformation field', 'NIFTI-1 image') + di2 = rdi2.findValue(subj['T1pre']) + if di is not None: + subj['MNI'] = di + if di2 is not None: + subj['MNI'] = di2 + + # Find Electrode Implantation + rdi = ReadDiskItem( 'Electrode implantation', 'Electrode Implantation format', requiredAttributes={'subject':s, 'center':subj['center']} ) + elecs = list(rdi._findValues( {}, None, False ) ) + if len(elecs) > 0: + subj['implantation'] = elecs[0] + + else: + wditxtmnipos = ReadDiskItem('Electrode Implantation Position TXT', 'Text file', requiredAttributes={'ref_name':'MNI'}) + dimnipos=wditxtmnipos.findValue(subj['rdi']) + wditxtmniname = ReadDiskItem('Electrode Implantation Name TXT', 'Text file', requiredAttributes={'ref_name':'MNI'}) + dimniname = wditxtmniname.findValue(subj['rdi']) + + if dimnipos is not None: + subj['implantationMNI'] = (dimnipos,dimniname) + else: + wdi_csvnew = ReadDiskItem('Final Export Dictionaries','CSV file') + rdi_csvnew= wdi_csvnew.findValue(subj['rdi']) + subj['implantationCSV'] = rdi_csvnew + + # Find Electrode Label + rdi_elec = ReadDiskItem('Electrodes Labels','Electrode Label Format',requiredAttributes={'subject':s, 'center':subj['center']}) + list_di_elec = list(rdi_elec.findValues( {}, None, False ) ) + #loca_patient = [] + loca_patient = {} + loca_patient_FS = {} + loca_patient_BM = {} + loca_bipole_patient = {} + loca_bipole_patient_FS = {} + loca_bipole_patient_BM = {} + + info_label_elec = None + + if len(list_di_elec) > 0: + di_elec = rdi_elec.findValue(subj['T1pre']) + #subj['elec_label'] = di_elec + #read the json file + fin = open(di_elec.fullPath(),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + if 'plots_by_label' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_by_label'].iteritems(): + if len(vv): + loca.append(kk) + #loca_patient.append(kk) + loca_patient.update({kk:vv}) + + if 'plots_by_label_FS' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_by_label_FS'].iteritems(): + if len(vv): + loca_FS.append(kk) + #loca_patient_FS.append(kk) + loca_patient_FS.update({kk:vv}) + if 'plots_by_label_BM' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_by_label_BM'].iteritems(): + if len(vv): + loca_BM.append(kk) + #loca_patient_BM.append(kk) + loca_patient_BM.update({kk:vv}) + + #on fait la meme chose avec les bipoles pour les stims (puis la cognition) + if 'plots_bipolar_by_label' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_bipolar_by_label'].iteritems(): + if len(vv): + #loca_patient.append(kk) + loca_bipole_patient.update({kk:vv}) + if 'plots_bipolar_by_label_FS' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_bipolar_by_label_FS'].iteritems(): + if len(vv): + #loca_patient.append(kk) + loca_bipole_patient_FS.update({kk:vv}) + if 'plots_bipolar_by_label_BM' in info_label_elec.keys(): + for kk,vv in info_label_elec['plots_bipolar_by_label_BM'].iteritems(): + if len(vv): + #loca_patient.append(kk) + loca_bipole_patient_BM.update({kk:vv}) + + #add freesurfer and broadmann + subj['rdi_elec_label'] = list_di_elec[0] + else: + subj['rdi_elec_label'] = None + + subj['elec_label'] = loca_patient + subj['elec_label_FS'] = loca_patient_FS + subj['elec_label_BM'] = loca_patient_BM + subj['bipole_label'] = loca_bipole_patient + subj['bipole_label_FS'] = loca_bipole_patient_FS + subj['bipole_label_BM'] = loca_bipole_patient_BM + + + rdi_resec_label = ReadDiskItem('Resection Description','Resection json',requiredAttributes={'subject':s, 'center':subj['center']}) + list_di_resec_label = list(rdi_resec_label.findValues( {}, None, False ) ) + resec_patient = [] + resec_patient_FS = [] + if len(list_di_resec_label) > 0: + di_resec_label = rdi_resec_label.findValue(subj['T1pre']) + fin = open(di_resec_label.fullPath(),'r') + info_label_resec = json.loads(fin.read()) + fin.close() + + if 'mars_atlas' in info_label_resec.keys(): + for kk,vv in info_label_resec['mars_atlas'].iteritems(): + if len(vv): + resec.append(kk) + resec_patient.append(kk) + + #add freesurfer + if 'Freesurfer' in info_label_resec.keys(): + if 'Freesurfer not calculated' in info_label_resec['Freesurfer']: + pass + else: + for kk,vv in info_label_resec['Freesurfer'].iteritems(): + if len(vv): + resec_FS.append(kk) + resec_patient_FS.append(kk) + + subj['rdi_resec_label'] = list_di_resec_label[0] + else: + subj['rdi_resec_label'] = None + + subj['resec_label'] = resec_patient + subj['resec_label_FS'] = resec_patient_FS + + # Find SEEG manips + rdi = ReadDiskItem( 'Raw SEEG recording', ['EEG TRC format', 'Elan EEG format'], requiredAttributes={'subject':s, 'center':subj['center']} ) + records = list(rdi._findValues( {}, None, False ) ) + if len(records) > 0: + for rec in records: + subj['seeg_'+str(rec.attributes()['experiment'])] = rec + manips = [str(rec.attributes()['experiment']) for rec in records] + seegManips.update(manips) + + rdi_stimresult_label = ReadDiskItem('Electrodes SEEG Labels','Electrode sEEG Label Format',requiredAttributes={'subject':s, 'center':subj['center']}) + list_di_stimresult_label = list(rdi_stimresult_label.findValues( {}, None, False ) ) + seeg_label_loca = [] + seeg_label_type = [] + seeg_label_freq = [] + seeg_label_all = [] + + + if len(list_di_stimresult_label)>0: + + by_default_list = [u'Motor',u'Sensitive',u'Sensory',u'Vegetative',u'Emotional',u'Experiencial','Superior functions'] + by_default_list2 = [u'no response', u'pathological', u'seizure sensation'] + full_list = by_default_list + by_default_list2 + + di_stimresult_label = rdi_stimresult_label.findValue(subj['T1pre']) + fin = open(di_stimresult_label.fullPath(),'r') + info_seeg_label = json.loads(fin.read()) + fin.close() + + #la il faut que je retourne les infos dans tous les sens c'est la merde ... + for kk,vv in info_seeg_label['contacts'].iteritems(): + #seeg_label_loca = + + for freqVal in info_seeg_label['contacts'][kk]['cell'].keys(): + if freqVal not in stimFreq: + stimFreq.append(freqVal) + #seeg_label_freq.append(freqVal) + list_inter = [x for x in by_default_list if info_seeg_label['contacts'][kk]['cell'][freqVal][x]['value'] != 0] + list_inter2 = info_seeg_label['contacts'][kk]['cell'][freqVal][u'Type of response']['fontcolor'] + max_index = list_inter2[1:].index(max(list_inter2[1:])) + try: + if list_inter2[max_index+1] == 0: + resp1 = by_default_list2[0] + elif max_index == 0: + resp1 = by_default_list2[2] + elif max_index == 2: + resp1 = by_default_list2[1] + except: + pdb.set_trace() + seeg_label_all.append((kk.title(),freqVal,resp1,list_inter)) + try: + if 'MarsAtlas' in info_label_elec['plots_label_bipolar'][kk.title()].keys(): + seeg_label_all[-1] = seeg_label_all[-1] + (info_label_elec['plots_label_bipolar'][kk.title()]['MarsAtlas'][1],) + else: + seeg_label_all[-1] = seeg_label_all[-1] + (u'not estimated',) + except: + pdb.set_trace() + + if 'Freesurfer' in info_label_elec['plots_label_bipolar'][kk.title()].keys(): + seeg_label_all[-1] = seeg_label_all[-1] + (info_label_elec['plots_label_bipolar'][kk.title()]['Freesurfer'][1],) + else: + seeg_label_all[-1] = seeg_label_all[-1] + (u'not estimated',) + + if 'Broadmann' in info_label_elec['plots_label_bipolar'][kk.title()].keys(): + seeg_label_all[-1] = seeg_label_all[-1] + (info_label_elec['plots_label_bipolar'][kk.title()]['Broadmann'][1],) + else: + seeg_label_all[-1] = seeg_label_all[-1] + (u'not estimated',) + #[True if info_seeg_label['contacts'][kk]['cell'][freqVal][x]['value'] != 0 else False for x in by_default_list] + #pdb.set_trace() + + + subj['seeg_label_all'] = seeg_label_all + + if 'full_list' in locals(): + stimInter = set(stimType) + full_listInter = set(full_list) + newstimtype = stimInter.union(full_listInter) + stimType = sorted(list(newstimtype)) + #stimType = stimType + full_list + + #remove duplicate #la on récupère les clés ? ou après ? où est-ce que je gère les infos des contacts ? + locas = list(set(loca)) + locas.sort() + locas_FS = list(set(loca_FS)) + locas_FS.sort() + locas_BM = list(set(loca_BM)) + locas_BM.sort() + + + + self.filterCognitionLoca.clear() + self.filterCognitionType.clear() + + + self.filterCognitionLoca.addItems(locas) + self.filterCognitionType.addItems(cogniType) + + self.filterStimulationLoca.clear() + self.filterStimulationType.clear() + self.filterStimulationFreq.clear() + + self.filterStimulationLoca.addItems(locas) + self.filterStimulationType.addItems(stimType) + self.filterStimulationFreq.addItems(stimFreq) + + resecs = list(set(resec)) + resecs.sort() + resecs_FS = list(set(resec_FS)) + resecs_FS.sort() + resecs_BM = list(set(resec_BM)) + resecs_BM.sort() + + self.filtersAtlases.update({'locaMA':locas,'locaFS':locas_FS,'locaBM':locas_BM,'resecMA':resecs,'resecFS':resecs_FS,'resecBM':resecs_BM}) + + self.filterLocaMarsAtlas.clear() + self.filterLocaMarsAtlas.addItems(locas) + + #self.filterCognition.clear() + #self.filterCognition.addItems(cognis) + + self.filterResection.clear() + self.filterResection.addItems(resecs) + + if len(seegManips) > 0: + self.seegManipCombo.clear() + self.seegManipCombo.addItems(sorted(list(seegManips))) + + self.updatePatientFilters() + + def toggleSeeg(self): + """If SEEG is clicked, select the manip as a filter""" + manip = str(self.seegManipCombo.currentText()) + if manip is None or manip == "": + return + self.toggleFilterWidget('seeg_'+manip, self.seegButton) + if 'seeg_'+manip in self.filters: + self.seegManipCombo.setItemIcon(self.seegManipCombo.currentIndex(), self.greenDotIcon) + else: + self.seegManipCombo.setItemIcon(self.seegManipCombo.currentIndex(), None) + + def seegManipChanged(self, idx): + self.toggleWidget(self.seegButton, 'seeg_' + str(self.seegManipCombo.currentText()) in self.filters) + + + def toggleFilterWidget(self, filterName, widg): + """Adds/Removes a filter and push/unpush the widget""" + onOrOff = self.toggleFilter(filterName) + self.toggleWidget(widg, onOrOff) + + def toggleWidget(self, widg, on = True): + """Sets the background color of the widget to green and add it to pushedWidgets, or reverse if it is already pushed""" + if not on: + widg.setStyleSheet("background-color: rgb(90, 90, 90);") + self.pushedWidget.remove(widg) + else: + widg.setStyleSheet("background-color: rgb(120, 255, 120);") + #widg.setStyleSheet("border: 2px solid #88ff88;") + self.pushedWidget.append(widg) + + def toggleFilter(self, filterName, updateUi = True): + """Sets or unsets a filter, then update the ui""" + if filterName in self.filters: + self.filters.remove(filterName) + else: + self.filters.append(filterName) + if updateUi: + self.updatePatientFilters() + return filterName in self.filters + + def getFilters(self): + return self.filters + + def matchFilters(self, subj, filters): + return all([subj.has_key(f) for f in filters]) + + def filterSubjectsBasic(self): + """Filtering subject list using basic factors (protocol, year, site)""" + subs = self.subjects.keys() + if str(self.filterProtocolCombo.currentText()) != '*': + subs = [s for s in subs if self.subjects[s]['center'] == str(self.filterProtocolCombo.currentText())] + if str(self.filterSiteCombo.currentText()) != '*': + subs = [s for s in subs if s.split('_')[0] == str(self.filterSiteCombo.currentText())] + if str(self.filterYearCombo.currentText()) != '*': + subs = [s for s in subs if len(s.split('_')) > 1 and s.split('_')[1] == str(self.filterYearCombo.currentText())] + if self.FilterAtlascomboBox.currentIndex() == 0: + if str(self.filterLocaMarsAtlas.currentText()) != '*': + subs = [s for s in subs if 'elec_label' in self.subjects[s] and str(self.filterLocaMarsAtlas.currentText()) in self.subjects[s]['elec_label'].keys()] + if str(self.filterResection.currentText()) != '*': + subs = [s for s in subs if 'resec_label' in self.subjects[s] and str(self.filterResection.currentText()) in self.subjects[s]['resec_label']] + elif self.FilterAtlascomboBox.currentIndex() == 1: + if str(self.filterLocaMarsAtlas.currentText()) != '*': + subs = [s for s in subs if 'elec_label_FS' in self.subjects[s] and str(self.filterLocaMarsAtlas.currentText()) in self.subjects[s]['elec_label_FS'].keys()] + if str(self.filterResection.currentText()) != '*': + subs = [s for s in subs if 'resec_label_FS' in self.subjects[s] and str(self.filterResection.currentText()) in self.subjects[s]['resec_label_FS']] + elif self.FilterAtlascomboBox.currentIndex() == 2: + if str(self.filterLocaMarsAtlas.currentText()) != '*': + subs = [s for s in subs if 'elec_label_BM' in self.subjects[s] and str(self.filterLocaMarsAtlas.currentText()) in self.subjects[s]['elec_label_BM'].keys()] + if str(self.filterResection.currentText()) != '*': + subs = [s for s in subs if 'resec_label_BM' in self.subjects[s] and str(self.filterResection.currentText()) in self.subjects[s]['resec_label_BM']] + if str(self.filterStimulationLoca.currentText())!= '*' or str(self.filterStimulationFreq.currentText()) != '*' or str(self.filterStimulationType.currentText()) != '*' : + subs = [s for s in subs if 'seeg_label_all' in self.subjects[s]] + CondiLoca = str(self.filterStimulationLoca.currentText()) == '*' + CondiFreq = str(self.filterStimulationFreq.currentText()) == '*' + CondiType = str(self.filterStimulationType.currentText()) == '*' + subs_toremove = [] + inter_stim = {} + for ind_sub in subs: + isthereloc = [x for x in self.subjects[ind_sub]['seeg_label_all'] if (str(self.filterStimulationLoca.currentText())==x[4+self.FilterAtlascomboBox.currentIndex()] or CondiLoca) and (str(self.filterStimulationFreq.currentText())==x[1] or CondiFreq) and (str(self.filterStimulationType.currentText())==x[2] or str(self.filterStimulationType.currentText()) in x[3] or CondiType)] + if len(isthereloc)==0: + subs_toremove.append(ind_sub) + else: + inter_stim.update({ind_sub:isthereloc}) + #for bipole_info in self.sub + [subs.remove(x) for x in subs_toremove] + + + + + if str(self.filterCognitionLoca.currentText()) != '*': + print "no cognition load in the data base for now" + + subs = [s for s in subs if s not in [str(self.selectedPatientList.item(idx).text()) for idx in range(self.selectedPatientList.count())]] + self.filteredPatientList.clear() + self.filteredPatientList.addItems(sorted(subs)) + + def colorFilterListWidget(self, listwidget, selected): + for idx in range(listwidget.count()): + it = listwidget.item(idx) + if str(it.text()) in selected: + it.setBackground(QtGui.QColor(150,255,150)) + else: + it.setBackground(QtGui.QColor(255,150,150)) + + def updatePatientFilters(self): + """Colors the 'patient list' and 'selected patient list' items in green if they match the filters and updates the content of patient's list""" + # Apply basic filters to the main patient list first and update the UI + self.filterSubjectsBasic() + # Filter the list of subjects and filter them + filteredPatients = [s for s,subj in self.subjects.iteritems() if self.matchFilters(subj, self.filters)] + # Color the patients according to the filters + self.colorFilterListWidget(self.filteredPatientList, filteredPatients) + self.colorFilterListWidget(self.selectedPatientList, filteredPatients) + + def moveSelectedItemsToOtherListWidget(self, lwFrom, lwTo): + """Takes the selected items of the list 'from' and adds them to the 'to' list""" + for idx in reversed(range(lwFrom.count())): + it = lwFrom.item(idx) + if lwFrom.isItemSelected(it): + lwTo.addItem(str(it.text())) + lwFrom.takeItem(idx) + lwTo.sortItems() + + def moveFilteredItemsToOtherListWidget(self, lwFrom, lwTo, filters, reverse=False): + """Takes the items from lwFrom (QListWidget) and move those that match the filters to lwTo. If reverse is true, the items that don't match will move""" + filtered = [s for s,subj in self.subjects.iteritems() if self.matchFilters(subj, filters)] + for idx in reversed(range(lwFrom.count())): + it = lwFrom.item(idx) + if (not reverse and str(it.text()) in filtered) or (reverse and str(it.text()) not in filtered): + lwTo.addItem(str(it.text())) + lwFrom.takeItem(idx) + + lwTo.sortItems() + + def selectAllListItems(self, listwidget, select = True): + """Selects or deselects all items of a QListWidget (select = False to deselect)""" + for idx in range(listwidget.count()): + listwidget.setItemSelected(listwidget.item(idx), select) + + def mniParcelsGeneration(self): + + #patient selected + PatsSelected = self.getSelectedPatientsNames() + subject_to_perform = [] + subjects_ok = [] + + for ind_pat in PatsSelected: + + #first we look if it's not already done + if 'rdi_elec_label' in self.subjects[ind_pat].keys(): + if self.subjects[ind_pat]['rdi_elec_label'] is not None: + fin = open(str(self.subjects[ind_pat]['rdi_elec_label']),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + if 'plots_label' in info_label_elec.keys(): + if "BroadmannDilate" in info_label_elec['plots_label'][info_label_elec['plots_label'].keys()[0]].keys(): + subjects_ok.append(ind_pat) + print("BrodmannDilate already estimated for this patient %s"%ind_pat) + else: + subject_to_perform.append(ind_pat) + else: + subject_to_perform.append(ind_pat) + else: + subject_to_perform.append(ind_pat) + else: + subject_to_perform.append(ind_pat) + + #if not we look if MNI position have been estimated already + subject_possible_to_perform = {} + subject_not_performable = [] + + for ind_pat in subject_to_perform: + + if 'implantation' in self.subjects[ind_pat].keys(): + + fin = open(str(self.subjects[ind_pat]['implantation']),'r') + try: + info_implant = json.loads(fin.read()) + except: + fin.close() + fin = open(str(self.subjects[ind_pat]['implantation']),'r') + info_implant = pickle.load(fin) + fin.close() + + if 'plotsMNI' in info_implant.keys(): + subject_possible_to_perform.update({ind_pat:info_implant['plotsMNI']}) + else: + print("MNI estimation has to be done in locateElectrodes for %s, to sensitive to duplicate these functions at differente place"%ind_pat) + subject_not_performable.append(ind_pat) + + elif 'implantationMNI' in self.subjects[ind_pat].keys(): + #pdb.set_trace() + MNI_pos = numpy.loadtxt(str(self.subjects[ind_pat]['implantationMNI'][0])) + a=open(str(self.subjects[ind_pat]['implantationMNI'][1]),"rU") + MNI_name=a.read().splitlines() + a.close() + info = [[MNI_name[x],MNI_pos[x].tolist()] for x in range(len(MNI_name))] + subject_possible_to_perform.update({ind_pat:info}) + #MNI_name = + #subject_possible_to_perform.update({ind_pat:info_implant['plotsMNI']}) + + elif 'implantationCSV' in self.subjects[ind_pat].keys(): + # pdb.set_trace() + print("refaire %s"%str(ind_pat)) + #subject_possible_to_perform.update({ind_pat:info_implant['plotsMNI']}) + else: + subject_not_performable.append(ind_pat) + + + matrix_MNI_Nativ = numpy.matrix([[ -1., 0., 0., 90.],[0., -1., 0., 91.],[0., 0., -1., 109.],[0., 0., 0., 1.]]) + #la blague maintenant c'est d'ouvrir un csv et de rajouter des infos mni sans perdre les infos "patients specifique" + for ind_pat in subject_possible_to_perform.keys(): + + print(ind_pat) + plotMNI_sorted = sorted(subject_possible_to_perform[ind_pat], key=lambda plot_number: plot_number[0]) + plotMNI_Dict = dict(plotMNI_sorted) + #make bipolar montage + + + plot_dict_MNI_Native = {} + for vv,kk in plotMNI_Dict.iteritems(): + inter_pos = [kk[0], kk[1], kk[2], 1] + inter_pos = numpy.matrix(inter_pos).reshape([4,1]) + result_pos = numpy.dot(matrix_MNI_Nativ,inter_pos) + plot_dict_MNI_Native.update({vv:[result_pos.tolist()[0][0],result_pos.tolist()[1][0],result_pos.tolist()[2][0]]}) + + info_plotMNI_bipolaire= [] + for pindex in range(1,len(plotMNI_sorted)): + previous_contact = "".join([i for i in plotMNI_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plotMNI_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plotMNI_bipolaire.append((plotMNI_sorted[pindex][0]+' - '+ plotMNI_sorted[pindex-1][0],(numpy.array(plot_dict_MNI_Native[plotMNI_sorted[pindex][0]])+numpy.array(plot_dict_MNI_Native[plotMNI_sorted[pindex-1][0]]))/2 )) + + info_plotMNI_bipolaireSB= {} + for pindex in range(1,len(plotMNI_sorted)): + previous_contact = "".join([i for i in plotMNI_sorted[pindex-1][0] if not i.isdigit()]) + current_contact = "".join([i for i in plotMNI_sorted[pindex][0] if not i.isdigit()]) + if previous_contact == current_contact: + info_plotMNI_bipolaireSB.update({plotMNI_sorted[pindex][0]+' - '+ plotMNI_sorted[pindex-1][0]:(numpy.array(plotMNI_Dict[plotMNI_sorted[pindex][0]])+numpy.array(plotMNI_Dict[plotMNI_sorted[pindex-1][0]]))/2 }) + + info_plotMNI_bipolaire_Dict =dict(info_plotMNI_bipolaire) + #open MNI filtersAtlases + #pdb.set_trace() + + Hammers_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_Hammers.txt') + AAL_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_AAL.txt') + AALDilate_parcels_names = readSulcusLabelTranslationFile('parcels_label_name_AALDilate.txt') + vol_AAL = aims.read('MNI_Atlases/rAALSEEG12.nii') + vol_AALDilate = aims.read('MNI_Atlases/rAALSEEG12Dilate.nii') + vol_BroadmannDilate = aims.read('MNI_Atlases/rBrodmannSEEG3spm12.nii') + vol_Broadmann = aims.read('MNI_Atlases/rbrodmann.nii') + vol_Hammers = aims.read('MNI_Atlases/rHammersSEEG12.nii') + + sphere_size = 3 #en mm + nb_voxel_sphere_MNI = [sphere_size, sphere_size, sphere_size] + #c'est là que ça va pas ... + #il faut que je recharge celui du patient + plots_label = {} + if 'rdi_elec_label' in self.subjects[ind_pat].keys(): + if self.subjects[ind_pat]['rdi_elec_label'] is not None: + fin = open(str(self.subjects[ind_pat]['rdi_elec_label']),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + plots_label = info_label_elec['plots_label'] + else: + plots_label = {} + else: + plots_label = {} + + for pindex in range(len(plotMNI_sorted)): + + plot_pos_pix_MNI = [round(plot_dict_MNI_Native[plotMNI_sorted[pindex][0]][i]) for i in range(3)] + + ##MNI Atlases + ##AAL + voxel_within_sphere_AAL = [round(vol_AAL.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAAL = [x for x in voxel_within_sphere_AAL if x != 0 and not math.isnan(x)] + + ##AALDilate + voxel_within_sphere_AALdilate = [round(vol_AALDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAALDilate = [x for x in voxel_within_sphere_AALdilate if x != 0 and not math.isnan(x)] + + ##Broadmann + voxel_within_sphere_Broadmann = [round(vol_Broadmann.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmann = [x for x in voxel_within_sphere_Broadmann if x != 0 and not math.isnan(x)] + + #Brodmann dilate + voxel_within_sphere_Broadmanndilate = [round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmannDilate = [x for x in voxel_within_sphere_Broadmanndilate if x != 0 and not math.isnan(x)] + + ##Hammers + voxel_within_sphere_Hammers = [round(vol_Hammers.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepHammers = [x for x in voxel_within_sphere_Hammers if x != 0 and not math.isnan(x)] + + ##prendre le label qui revient le plus en dehors de zero (au cas où il y en ait plusieurs) + from collections import Counter + + if not voxel_to_keepAAL: + label_AAL_name = "not in a AAL parcel" + label_AAL = round(vol_AAL.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAAL).most_common(1)[0] + label_AAL = most_common + label_AAL_name = AAL_parcels_names[label_AAL] + + if not voxel_to_keepAALDilate: + label_AALDilate_name = "not in a AALDilate parcel" + label_AALDilate = round(vol_AALDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAALDilate).most_common(1)[0] + label_AALDilate = most_common + label_AALDilate_name = AALDilate_parcels_names[label_AALDilate] + + if not voxel_to_keepBroadmann: + label_Broadmann_name = "not in a Broadmann parcel" + label_Broadmann = round(vol_Broadmann.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmann).most_common(1)[0] + label_Broadmann = most_common + #label_Broadmann_name = unicode(label_Broadmann) + + if plot_pos_pix_MNI[0]>90: + label_Broadmann_name = unicode(label_Broadmann+100) + else: + label_Broadmann_name = unicode(label_Broadmann) + + if not voxel_to_keepBroadmannDilate: + label_BroadmannDilate_name = "not in a Broadmann parcel" + label_BroadmannDilate = round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmannDilate).most_common(1)[0] + label_BroadmannDilate = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_BroadmannDilate_name = unicode(label_BroadmannDilate+100) + else: + label_BroadmannDilate_name = unicode(label_BroadmannDilate-48) + + if not voxel_to_keepHammers: + label_Hammers_name = "not in a Hammers parcel" + label_Hammers = round(vol_Hammers.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepHammers).most_common(1)[0] + label_Hammers = most_common + label_Hammers_name = Hammers_parcels_names[label_Hammers] + + + #la j'ecrase les infos marsatlas etc ... sans raison + #plots_label[plotMNI_sorted[pindex][0]]={'MarsAtlas':(0,'not calculated'),'Freesurfer':(0,'not calculated'),'Hippocampal Subfield':(0,'not calculated'),'GreyWhite':(0,'not calculated'),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(0,'not calculated')} + try: + plots_label[plotMNI_sorted[pindex][0]].update({'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name)}) + except: + plots_label[plotMNI_sorted[pindex][0]]={'MarsAtlas':(0,'not calculated'),'Freesurfer':(0,'not calculated'),'Hippocampal Subfield':(0,'not calculated'),'GreyWhite':(0,'not calculated'),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(0,'not calculated')} + #je remets l'ancienne ligne ? + + plot_name = [x[0] for x in plotMNI_sorted] + plots_by_label_BM = dict([(Lab,[p for p in plot_name if plots_label[p]['Broadmann'][1]==Lab]) for Lab in [unicode("%1.1f"%x) for x in range(0,100)]]) + plots_by_label_HM = dict([(Lab,[p for p in plot_name if plots_label[p]['Hammers'][1]==Lab]) for Lab in Hammers_parcels_names.values()]) + plots_by_label_AAL = dict([(Lab,[p for p in plot_name if plots_label[p]['AAL'][1]==Lab]) for Lab in AAL_parcels_names.values()]) + plots_by_label_AALDilate = dict([(Lab,[p for p in plot_name if plots_label[p]['AALDilate'][1]==Lab]) for Lab in AALDilate_parcels_names.values()]) + + sphere_size_bipole = 5 + nb_voxel_sphere_MNI = [sphere_size, sphere_size, sphere_size] + + plots_label_bipolar = {} + if 'rdi_elec_label' in self.subjects[ind_pat].keys(): + if self.subjects[ind_pat]['rdi_elec_label'] is not None: + fin = open(str(self.subjects[ind_pat]['rdi_elec_label']),'r') + info_label_elec = json.loads(fin.read()) + fin.close() + plots_label_bipolar = info_label_elec['plots_label_bipolar'] + else: + pass #pdb.set_trace() + else: + pass #pdb.set_trace() + + for pindex in range(len(info_plotMNI_bipolaire)): + plot_pos_pix_MNI = [round(info_plotMNI_bipolaire[pindex][1][i]) for i in range(3)] + + ##MNI Atlases + ##AAL + voxel_within_sphere_AAL = [round(vol_AAL.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAAL = [x for x in voxel_within_sphere_AAL if x != 0 and not math.isnan(x)] + + ##AALDilate + voxel_within_sphere_AALdilate = [round(vol_AALDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepAALDilate = [x for x in voxel_within_sphere_AALdilate if x != 0 and not math.isnan(x)] + + ##Broadmann + voxel_within_sphere_Broadmann = [round(vol_Broadmann.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmann = [x for x in voxel_within_sphere_Broadmann if x != 0 and not math.isnan(x)] + + #Brodmann dilate + voxel_within_sphere_Broadmanndilate = [round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepBroadmannDilate = [x for x in voxel_within_sphere_Broadmanndilate if x != 0 and not math.isnan(x)] + + ##Hammers + voxel_within_sphere_Hammers = [round(vol_Hammers.value(plot_pos_pix_MNI[0]+vox_i,plot_pos_pix_MNI[1]+vox_j,plot_pos_pix_MNI[2]+vox_k)) for vox_k in range(-nb_voxel_sphere_MNI[2],nb_voxel_sphere_MNI[2]+1) for vox_j in range(-nb_voxel_sphere_MNI[1],nb_voxel_sphere_MNI[1]+1) for vox_i in range(-nb_voxel_sphere_MNI[0],nb_voxel_sphere_MNI[0]+1) if math.sqrt(vox_i**2+vox_j**2+vox_k**2) < sphere_size] + voxel_to_keepHammers = [x for x in voxel_within_sphere_Hammers if x != 0 and not math.isnan(x)] + + ##prendre le label qui revient le plus en dehors de zero (au cas où il y en ait plusieurs) + from collections import Counter + + if not voxel_to_keepAAL: + label_AAL_name = "not in a AAL parcel" + label_AAL = round(vol_AAL.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAAL).most_common(1)[0] + label_AAL = most_common + label_AAL_name = AAL_parcels_names[label_AAL] + + if not voxel_to_keepAALDilate: + label_AALDilate_name = "not in a AALDilate parcel" + label_AALDilate = round(vol_AALDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepAALDilate).most_common(1)[0] + label_AALDilate = most_common + label_AALDilate_name = AALDilate_parcels_names[label_AALDilate] + + if not voxel_to_keepBroadmann: + label_Broadmann_name = "not in a Broadmann parcel" + label_Broadmann = round(vol_Broadmann.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmann).most_common(1)[0] + label_Broadmann = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_Broadmann_name = unicode(label_Broadmann+100) + else: + label_Broadmann_name = unicode(label_Broadmann) + + if not voxel_to_keepBroadmannDilate: + label_BroadmannDilate_name = "not in a Broadmann parcel" + label_BroadmannDilate = round(vol_BroadmannDilate.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepBroadmannDilate).most_common(1)[0] + label_BroadmannDilate = most_common + #label_Broadmann_name = unicode(label_Broadmann) + if plot_pos_pix_MNI[0]>90: + label_BroadmannDilate_name = unicode(label_BroadmannDilate+100) + else: + label_BroadmannDilate_name = unicode(label_BroadmannDilate-48) + + + if not voxel_to_keepHammers: + label_Hammers_name = "not in a Hammers parcel" + label_Hammers = round(vol_Hammers.value(plot_pos_pix_MNI[0],plot_pos_pix_MNI[1],plot_pos_pix_MNI[2])) + else: + most_common,num_most_common = Counter(voxel_to_keepHammers).most_common(1)[0] + label_Hammers = most_common + label_Hammers_name = Hammers_parcels_names[label_Hammers] + + + #plots_label_bipolar[info_plotMNI_bipolaire[pindex][0]]={'MarsAtlas':(0,'not calculated'),'Freesurfer':(0,'not calculated'),'Hippocampal Subfield':(0,'not calculated'),'GreyWhite':(0,'not calculated'),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(0,'not calculated')} + try: + plots_label_bipolar[info_plotMNI_bipolaire[pindex][0]].update({'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name)}) + except: + plots_label_bipolar[info_plotMNI_bipolaire[pindex][0]]={'MarsAtlas':(0,'not calculated'),'Freesurfer':(0,'not calculated'),'Hippocampal Subfield':(0,'not calculated'),'GreyWhite':(0,'not calculated'),'AAL':(label_AAL,label_AAL_name),'AALDilate':(label_AALDilate,label_AALDilate_name),'Broadmann':(label_Broadmann,label_Broadmann_name),'BroadmannDilate':(label_BroadmannDilate,label_BroadmannDilate_name),'Hammers':(label_Hammers,label_Hammers_name),'Resection':(0,'not calculated')} + + plot_name_bip = [x[0] for x in info_plotMNI_bipolaire] + plots_bipolar_by_label_BM = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Broadmann'][1]==Lab]) for Lab in [unicode("%1.1f"%x) for x in range(0,100)]]) + plots_bipolar_by_label_HM = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['Hammers'][1]==Lab]) for Lab in Hammers_parcels_names.values()]) + plots_bipolar_by_label_AAL = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['AAL'][1]==Lab]) for Lab in AAL_parcels_names.values()]) + plots_bipolar_by_label_AALDilate = dict([(Lab,[p for p in plot_name_bip if plots_label_bipolar[p]['AALDilate'][1]==Lab]) for Lab in AALDilate_parcels_names.values()]) + + wdi_csv = ReadDiskItem('Final Export Dictionaries','CSV file',requiredAttributes={'subject':ind_pat}) + rdi_csv = list(wdi_csv.findValues({},None,False)) + + if len(rdi_csv)>0: + #print c'est la galère + info_previous_csv = readElecLocalCSVFile(infile=str(rdi_csv[0])) + + else: + + info_previous_csv = None + + wdi_csvnew = WriteDiskItem('Final Export Dictionaries','CSV file') + rdi_csvnew= wdi_csvnew.findValue(self.subjects[ind_pat]['rdi']) + + with open(str(rdi_csvnew), 'w') as csvfile: + #fieldnames=['MarsAtlas','GreyWhite','Resection'] + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Contacts Positions']) + if info_previous_csv is not None: + info_mniMarsAtlas = info_previous_csv[0]['MarsAtlas'] + info_mniFreesurfer = info_previous_csv[0]['Freesurfer'] + info_mniHippoFS = info_previous_csv[0]['HippoSubfieldFreesurfer'] + else: + info_mniMarsAtlas = 'not performed' + info_mniFreesurfer = 'not performed' + info_mniHippoFS = 'not performed' + + writer.writerow([u'Use of MNI Template','MarsAtlas',info_mniMarsAtlas,'Freesurfer',info_mniFreesurfer,'HippoSubfieldFreesurfer',info_mniHippoFS]) + + #add a row with "MNI or Patient for MarsAtlas and Freesurfer + try: + list_to_write = set(info_previous_csv[1]['monopolar'][info_previous_csv[1]['monopolar'].keys()[0]].keys()) + except: + list_to_write = set([]) + + list_by_default = set([u'contact','MarsAtlas', 'MarsAtlasFull', 'Freesurfer', 'Hippocampal Subfield','GreyWhite','AAL', 'AALDilate', 'Broadmann', 'BroadmannDilate', 'Hammers', 'Resection', 'MNI','T1pre Scanner Based']) + diff_list = list(list_to_write.difference(list_by_default)) + full_list = [u'contact','MarsAtlas', 'MarsAtlasFull', 'Freesurfer', 'Hippocampal Subfield','GreyWhite', 'ALL', 'AALDilate', 'Broadmann', 'BroadmannDilate', 'Hammers', 'Resection', 'MNI','T1pre Scanner Based'] + full_list.extend(diff_list) + writer.writerow(full_list) + + try: + dict_sorted_tmp = OrderedDict(sorted(info_previous_csv[1]['monopolar'].items())) + except: + dict_sorted_tmp = OrderedDict(sorted(plots_label.items())) + new_dict_sorted_tmp = {} + for kk,vv in dict_sorted_tmp.items(): + new_dict_sorted_tmp.update({kk:{}}) + [new_dict_sorted_tmp[kk].update({jj:ll[1]}) for jj,ll in vv.items()] + dict_sorted_tmp = OrderedDict(sorted(new_dict_sorted_tmp.items())) + + + try: + for kk,vv in dict_sorted_tmp.iteritems(): + listwrite = [kk] + if 'MarsAtlas' in vv.keys(): + listwrite.append(vv['MarsAtlas']) + else: + listwrite.append('not performed') + if 'MarsAtlasFull' in vv.keys(): + listwrite.append(vv['MarsAtlasFull']) + else: + listwrite.append('not performed') + if 'Freesurfer' in vv.keys(): + listwrite.append(vv['Freesurfer']) + else: + listwrite.append('not performed') + if 'Hippocampal Subfield' in vv.keys(): + listwrite.append(vv['Hippocampal Subfield']) + else: + listwrite.append('not performed') + if 'GreyWhite' in vv.keys(): + listwrite.append(vv['GreyWhite']) + else: + listwrite.append('not performed') + if 'AAL' in vv.keys(): + listwrite.append(vv['AAL']) + else: + listwrite.append(plots_label[kk]['AAL'][1]) + if 'AALDilate' in vv.keys(): + listwrite.append(vv['AALDilate']) + else: + listwrite.append(plots_label[kk]['AALDilate'][1]) + #if 'Broadmann' in vv.keys(): + # listwrite.append(vv['Broadmann']) + #else: + listwrite.append(plots_label[kk]['Broadmann'][1]) + #if 'BroadmannDilate' in vv.keys(): + #listwrite.append(vv['BroadmannDilate']) + #else: + listwrite.append(plots_label[kk]['BroadmannDilate'][1]) + if 'Hammers' in vv.keys(): + listwrite.append(vv['Hammers']) + else: + listwrite.append(plots_label[kk]['Hammers'][1]) + if 'Resection' in vv.keys(): + listwrite.append(vv['Resection']) + else: + listwrite.append('not performed') + #[listwrite.append(x[1]) for x in vv.values()] + listwrite.append([float(format(plotMNI_Dict[kk][i],'.3f')) for i in range(3)]) + listwrite.append('not performed, csv generated from groupDisplay') + if len(full_list)>12: + for i_supp in range(len(full_list)-14): + listwrite.append(vv[full_list[14+i_supp]]) + writer.writerow(listwrite) + except: + pdb.set_trace() + + writer.writerow([]) + writer.writerow([]) + + try: + dict_sorted_tmp = OrderedDict(sorted(info_previous_csv[1]['bipolar'].items())) + except: + dict_sorted_tmp = OrderedDict(sorted(plots_label_bipolar.items())) + new_dict_sorted_tmp = {} + for kk,vv in dict_sorted_tmp.items(): + new_dict_sorted_tmp.update({kk:{}}) + [new_dict_sorted_tmp[kk].update({jj:ll[1]}) for jj,ll in vv.items()] + dict_sorted_tmp = OrderedDict(sorted(new_dict_sorted_tmp.items())) + + #dict_sorted_tmp = OrderedDict(sorted(info_previous_csv[1]['bipolar'].items())) + + for kk,vv in dict_sorted_tmp.iteritems(): + #pdb.set_trace() + listwrite = [kk] + if 'MarsAtlas' in vv.keys(): + listwrite.append(vv['MarsAtlas']) + else: + listwrite.append('not performed') + if 'MarsAtlasFull' in vv.keys(): + listwrite.append(vv['MarsAtlasFull']) + else: + listwrite.append('not performed') + if 'Freesurfer' in vv.keys(): + listwrite.append(vv['Freesurfer']) + else: + listwrite.append('not performed') + if 'Hippocampal Subfield' in vv.keys(): + listwrite.append(vv['Hippocampal Subfield']) + else: + listwrite.append('not performed') + if 'GreyWhite' in vv.keys(): + listwrite.append(vv['GreyWhite']) + else: + listwrite.append('not performed') + if 'AAL' in vv.keys(): + listwrite.append(vv['AAL']) + else: + listwrite.append(plots_label_bipolar[kk]['AAL'][1]) + if 'AALDilate' in vv.keys(): + listwrite.append(vv['AALDilate']) + else: + listwrite.append(plots_label_bipolar[kk]['AALDilate'][1]) + #if 'Broadmann' in vv.keys(): + # listwrite.append(vv['Broadmann']) + #else: + listwrite.append(plots_label_bipolar[kk]['Broadmann'][1]) + #if 'BroadmannDilate' in vv.keys(): + # listwrite.append(vv['BroadmannDilate']) + #else: + listwrite.append(plots_label_bipolar[kk]['BroadmannDilate'][1]) + + if 'Hammers' in vv.keys(): + listwrite.append(vv['Hammers']) + else: + listwrite.append(plots_label_bipolar[kk]['Hammers'][1]) + if 'Resection' in vv.keys(): + listwrite.append(vv['Resection']) + else: + listwrite.append('not performed') + + #[listwrite.append(x[1]) for x in vv.values()] + listwrite.append([float(format(info_plotMNI_bipolaireSB[kk][i],'.3f')) for i in range(3)]) + listwrite.append('not performed, csv generated from groupDisplay') + if len(full_list)>12: + for i_supp in range(len(full_list)-14): + listwrite.append(vv[full_list[14+i_supp]]) + writer.writerow(listwrite) + + writer.writerow([]) + writer.writerow([]) + + if info_previous_csv is not None: + if len(info_previous_csv[2])>0: + with open(str(rdi_csvnew), 'a') as csvfile: + writer = csv.writer(csvfile, delimiter='\t') + writer.writerow([u'Resection Information']) + + for kk,vv in info_previous_csv[2].iteritems(): + #writer.writerow([kk]) + if type(vv) == type(float()): + listwrite = [kk,vv] + writer.writerow(listwrite) + else: + writer.writerow([kk]) + for ll,bb in vv.iteritems(): + listwrite = [ll, format(float(bb),'.1f')] + writer.writerow(listwrite) + + else: + pass + else: + pass + #neuroHierarchy.databases.insertDiskItem(di, update=True ) + print("generation of csv done for %s"%ind_pat) + print("everything done") + + def changeAtlasfiltration(self): + + + #self.filtersAtlases.update({'locaMA':locas,'locaFS':locas_FS,'locaBM':locas_BM,'cogni':cognis,'resecMA':resecs,'resecFS':resecs_FS,'resecBM':resecs_BM}) + if self.FilterAtlascomboBox.currentIndex() == 0: + self.filterLocaMarsAtlas.clear() + self.filterLocaMarsAtlas.addItems(self.filtersAtlases['locaMA']) + + #self.filterCognition.clear() + #self.filterCognition.addItems(self.filtersAtlases['cogni']) + + self.filterResection.clear() + self.filterResection.addItems(self.filtersAtlases['resecMA']) + + self.filterCognitionLoca.clear() + self.filterCognitionLoca.addItems(self.filtersAtlases['locaMA']) + + self.filterStimulationLoca.clear() + self.filterStimulationLoca.addItems(self.filtersAtlases['locaMA']) + + + elif self.FilterAtlascomboBox.currentIndex() == 1: + + self.filterLocaMarsAtlas.clear() + self.filterLocaMarsAtlas.addItems(self.filtersAtlases['locaFS']) + + self.filterResection.clear() + self.filterResection.addItems(self.filtersAtlases['resecFS']) + #change font color depending on patient who has the information about the filtersAtlases + + self.filterCognitionLoca.clear() + self.filterCognitionLoca.addItems(self.filtersAtlases['locaFS']) + + self.filterStimulationLoca.clear() + self.filterStimulationLoca.addItems(self.filtersAtlases['locaFS']) + + elif self.FilterAtlascomboBox.currentIndex() == 2: + + self.filterLocaMarsAtlas.clear() + self.filterLocaMarsAtlas.addItems(self.filtersAtlases['locaBM']) + + self.filterResection.clear() + self.filterResection.addItems(self.filtersAtlases['resecBM']) + + self.filterCognitionLoca.clear() + self.filterCognitionLoca.addItems(self.filtersAtlases['locaBM']) + + self.filterStimulationLoca.clear() + self.filterStimulationLoca.addItems(self.filtersAtlases['locaBM']) + #change font color depending on patient who has the information about the filtersAtlases + + +if __name__ == "__main__": + app = QtGui.QApplication(sys.argv) + axon.initializeProcesses() + from brainvisa.data.readdiskitem import ReadDiskItem + from brainvisa.data.writediskitem import WriteDiskItem + QtCore.pyqtRemoveInputHook() + window = PatientDataFilterWidget() + window.show() + sys.exit(app.exec_()) diff --git a/patientinfo.py b/patientinfo.py new file mode 100644 index 0000000..bb1e349 --- /dev/null +++ b/patientinfo.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- +# +# Functions to create UI, read and write patient data +# such as type of epilepsy, disease history... +#, and dictionary of available processing methods for each manip type +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 + +from PyQt4 import QtGui, QtCore +import pdb, os, json +from brainvisa.data.writediskitem import ReadDiskItem, WriteDiskItem + +# Types : Text, Line (short text) Int (integer), Float, Bool, Choice, MultiSelectChoice, EditableChoice (list of values, but a new one may be entered) +#function_mappings = {'checkbox_comor':checkbox_comor} + +defaultInfoTable= ('currentDate',('Date2', QtCore.QDate.currentDate(),u'Date:'), + 'patientBirthday',('Date2',None , u'Date de Naissance'), + 'patientAge',('Line',u'0','Age patient'), + 'sex',('Choice',[u'Inconnu', u'Féminin', u'Masculin'], u'Sexe'), + 'handedness', ('Choice', ['Inconnu', 'Droitier', 'Gaucher', 'Ambidextre'], u'Latéralité manuelle'), + 'Consentement', ('Date2', None, u'Consentement Date Signature'), + 'ProtocolsRecherche',('Line',None,u'Protocol'), + 'ProtocolDate',('Date2',None, u"Date d'entrée dans le protocol"), + 'previousHistory', ('Choice2', [u'Inconnu', u'Aucun', u'Crises fébriles', u'Infection SNC', u'Souffrance néonatale', u'TC grave', u'Vasculaire'], u'Antécédents Personnels'), + 'previousFamilyHistory', ('Choice2', [u'Inconnu', u'Dépression', u'Epilepsie', u'Parkinson', u'TOC'], u'Antécédents Familiaux'), + 'causaleDisease', ('Choice2', [u'Inconnu', u'Génétique', u'Inflammatoire', u'Métabolique', u'Phacomatose'], u'Maladie neurologique causale'), + 'mriLesion', ('Choice2', [u'Inconnu', u'Aucune', u'Cicatrice', u'Malformation vasculaire', u'MCD', u'Sclérose hippocampique', u'Tumeur', u'Multiple'], u'Lésion IRM'), + 'mrilesionDroite',('ButtonBox',[u'T', u'F',u'P', u'O', u'Ins'], u'Droite'), + 'mrilesionGauche',('ButtonBox',[u'T', u'F',u'P', u'O', u'Ins'], u'Gauche'), + 'neurologiqueExam', ('Choice', [u'Inconnu', u'Normal', u'Anormal'],u'Examen Neurologique'), + #'comorbiditylabel', ('Label',u'Comorbiditépouet'), + 'comoraucune', ('Checkbox',u'Aucune',u'Comorbidité','checkbox_comor'), + 'comorneuro', ('Choice2', [u'Inconnu', u'AVC', u'Dystonie', u'Epilepsie', u'Migraine', u'Parkinson'], u'comorbidité neurologique'), + 'comorpsy', ('Choice2', [u'Inconnu', u'Anxiété', u'Dépression', u'TOC'], u'comorbidité psychiatrique'), + 'comorautre', ('Choice2', [u'Inconnu', u'Parasomnies', u'SAS'], u'comorbidité autre') + #'comorbidity', ('ChoiceSub', [u'Inconnu', u'Aucune', u'Neurologique', u'Psychiatrique', u'Autre'],u'Comorbidité'), + #'medication', ('Compound',( + # 'antiseizure',('Line', None, u'Antiépileptique'), + # 'other',('Line', None, u'Autre'),), u'Traitement'), + #'seizureFrequency', ('Choice', [' < 1/mois', 'mensuelle', 'hebdomadaire', 'quotidienne'], u'Fréquence des crises'), + #'diseaseHistory': ('Text', u'Histoire de la maladie'), + #'exams', ('Compound', ( + # 'checkExams', ('MultiSelectChoice', ['Evaluation neuropsy', 'Evaluation psy', 'Test de Wada', 'IRMf', 'SPECT', 'PET'], ''), + # 'veegExam', ('Date', None, 'VEEG'), + # 'megExam', ('Date', None, 'VEEG'), + # 'fmriEegExam', ('Date', None, 'VEEG'), + # ), u'Examens réalisés'), + #'epilepsyType', ('Line',None, u'Type d\'épilepsie (avant SEEG)') + ) + + +def buildInt(parent, mini, maxi, label): + lay = QtGui.QHBoxLayout() + sp = QtGui.QSpinBox(parent) + sp.setRange(mini, maxi) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(sp) + return (lay, sp) + +def buildChoice(parent, values, label): + lay = QtGui.QHBoxLayout() + combo = QtGui.QComboBox(parent) + combo.clear() + combo.addItems(values) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combo) + return (lay, combo) + +def buildChoice2(parent, values, label): + lay = QtGui.QHBoxLayout() + combo = QtGui.QComboBox(parent) + combo.clear() + model = QtGui.QStandardItemModel(len(values), 1)# 5 rows, 1 col + + for i,area in enumerate(values): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + + combo.setModel(model) + combo.setEditable(True) + combo.activated.connect(lambda index, comb=combo: validatenewCombo(comb, index)) + #pdb.set_trace() + + #combo.addItems(values) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combo) + return (lay, combo) + +def buildChoiceSub(parent, values, label): + lay = QtGui.QHBoxLayout() + + combosub = QtGui.QMenu(parent) + combosub.setTitle(u'Comorbitité menu') + + for i,area in enumerate(values): + menu = QtGui.QMenu(area) + + combosub.addMenu(menu) + + #pdb.set_trace() + if i<2: + menu.addAction(QtGui.QAction(area, menu, checkable = True)) + else: + #for ii, area2 in enumerate(subvalues) + menu.addAction(QtGui.QAction("pouet", menu, checkable = True)) + + + + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(combosub) + return (lay, combosub) + +def buildDate(parent, date, label): + lay = QtGui.QHBoxLayout() + qdate = QtGui.QDateEdit(parent) + qdate.setDisplayFormat('dd/MM/yyyy') + if date is None: + qdate.setDate(QtCore.QDate.fromString('1900-01-01', 'yyyy-MM-dd')) + else: + qdate.setDate(date) + lay.addWidget(QtGui.QLabel(label,parent=parent)) + lay.addWidget(qdate) + return (lay, qdate) + + +def buildText(parent, label): + lay = QtGui.QHBoxLayout() + text = QtGui.QTextEdit(parent) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(text) + return (lay, text) + +def buildLine(parent, defaultValue, label): + lay = QtGui.QHBoxLayout() + line = QtGui.QLineEdit(parent) + if label is not None and len(label) > 0: + lay.addWidget(QtGui.QLabel(label, parent=parent)) + if defaultValue: + line.setText(str(defaultValue)) + lay.addWidget(line) + return (lay, line) + +def buildCompound(parent, values, label): + lay = QtGui.QHBoxLayout() + frame = QtGui.QGroupBox(parent) + frame.setLayout(lay) + if label is not None: + frame.setTitle(str(label)) + widgets = buildUI(frame, values) + for wid in reversed(widgets.values()): + lay.addWidget(wid) + return (frame, [frame,]+widgets.values()) + +def buildButtonBox(parent,values,label): + lay = QtGui.QHBoxLayout() + buttbox = QtGui.QDialogButtonBox(parent) + for i,area in enumerate(values): + buttbox.addButton(area,3) + + for test in buttbox.findChildren(QtGui.QPushButton): + test.setCheckable(True) + + buttbox.clicked.connect(lambda index, comb=buttbox: MRIlesionbox(comb, index)) + lay.addWidget(QtGui.QLabel(label, parent=parent)) + lay.addWidget(buttbox) + return (lay,buttbox) + +def buildLabel(parent,label): + lay = QtGui.QHBoxLayout() + labe = QtGui.QLabel(parent) + labe.setText(label) + + lay.addWidget(labe) + return (lay, labe) + + + +def buildCheckbox(parent, label, label2, checkbox_connect): + #function_mapping = {'checkbox_comor':checkbox_comor} + lay = QtGui.QHBoxLayout() + qcheck = QtGui.QCheckBox(parent) + qcheck.setText(label) + + #qcheck.clicked.connect(lambda index, ChecK=qcheck: function_mapping[checkbox_connect](ChecK, index)) + + lay.addWidget(QtGui.QLabel(label2, parent=parent)) + lay.addWidget(qcheck) + return (lay, qcheck) + + + +uiBuild = {'Int': buildInt, + 'Float':lambda:(None, None),# Not implemented + 'Line':buildLine, + 'Text':buildText, + 'Bool':lambda:(None, None),# Not implemented + 'Date':lambda p, value,label:(None, None),# Not implemented + 'Date2':buildDate, + 'Choice':buildChoice, + 'Choice2':buildChoice2, + 'ChoiceSub':buildChoiceSub, + 'ButtonBox':buildButtonBox, + 'MultiSelectChoice':lambda p, values, label:(None, None),# Not implemented + 'EditableChoice':lambda p,v,l : buildChoice(p,v,l,True), + 'Compound':buildCompound, + 'Label':buildLabel, + 'Checkbox':buildCheckbox, + } + +def buildUI(parent, infoTable=defaultInfoTable): + """ Generates a UI from infoTable) and returns a dictionary with the generated widgets""" + + #si c est un choice2 c'est editable du coup faut aller chercher sur le json la derniere version de la liste + wdi_global = ReadDiskItem('PatientInfoTemplate','Patient Template format') + di_global = list(wdi_global.findValues({}, None, False)) + + if len(di_global) > 0: + if os.path.isfile(str(di_global[0])): + print "read previous patienttemplate json" + from codecs import open as opencodecs + fin = opencodecs(str(di_global[0]),'r','latin1') + info_dicti = json.loads(fin.read().decode('latin1')) + fin.close() + + previous_lists_not_path = info_dicti['notPathoSpecific'] + else: + previous_lists_not_path = {} + else: + previous_lists_not_path = {} + + lay = QtGui.QVBoxLayout(parent) + output = {} + for i in range(int(len(infoTable)/2)): + key = infoTable[2*i] + value = infoTable[2*i+1] + if key in previous_lists_not_path.keys(): + default_list = set(value[1]) + update_list = set(previous_lists_not_path[key]) + diff_list = update_list-default_list + final_list = value[1] + list(diff_list) + item1 = value[0] + item3= value[2] + value = (item1,final_list,item3) + + if value is not None: + (l,wid) = uiBuild[value[0]](parent, *(value[1:])) + if l is not None: + if isinstance(l, QtGui.QLayout): + lay.addLayout(l) + elif isinstance(l, QtGui.QWidget): + lay.addWidget(l) + else: + print "Neither a layout nor a widget : cannot add object to the layout !" + if wid is not None: + output[key]=wid + + return output + +def dumpState(structuredWidgets): + """Generates a dumpable object that represents the content of the patient info from the widgets""" + pass + +def validatenewCombo(combo_modified, selectedIndex): + + AllItems = [unicode(combo_modified.itemText(i)) for i in range(combo_modified.count()) if unicode(combo_modified.itemText(i)) != ''] + + model = QtGui.QStandardItemModel(len(AllItems), 1) + + for i,area in enumerate(AllItems): + item = QtGui.QStandardItem(area) + item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + model.setItem(i+1, 0, item) + + combo_modified.clear() + combo_modified.setModel(model) + combo_modified.setEditable(True) + + +def MRIlesionbox(buttbox_modiffied,selectedIndex): + + button_sender = buttbox_modiffied.sender().text() + #print button_sender + #buttbox_modiffied.sender().font().setBold(True) + + if buttbox_modiffied.sender().isChecked(): + buttbox_modiffied.sender().setStyleSheet("background-color: rgb(90, 255, 95);") + else: + buttbox_modiffied.sender().setStyleSheet("") + + +#def checkbox_comor(qcheck, qindex): + #self.patientInfo['comoraucune'].isChecked() + #pdb.set_trace() diff --git a/prepareData.py b/prepareData.py new file mode 100644 index 0000000..3633ebf --- /dev/null +++ b/prepareData.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +# +# Importation et preparation des images et donnees necessaires +# a la localisation des electrodes +# +# (c) Inserm U836 2012 - Manik Bhattacharjee +# +# License GNU GPL v3 + +# 1) Choisir le patient/date +# 2) Trouver l'IRM preop et la postop +# 3) Segmenter le (ou retrouver la segmentation du) cortex preop +# 4) Recaler le preop et le postop +# 5) Sortir un dictionary avec les fichiers d'interet (base de donnes BV) + + + + + diff --git a/readElecLocalCSVFile.py b/readElecLocalCSVFile.py new file mode 100644 index 0000000..9a10413 --- /dev/null +++ b/readElecLocalCSVFile.py @@ -0,0 +1,147 @@ +# +# From Electrodes localisation, read CSV file coming from INTRANAT +# + +import csv, sys, os, re +from datetime import date +import pdb + +def readElecLocalCSVFile(infile = None): + + data = csv.reader(open(infile), delimiter = '\t') + contents = [] + for row in data: + contents.append(row) + + saveSpaceL = 0 + #find the string 'contact' to identify the starting line + for i1 in range(len(contents[1])): + for i2 in range(10): + try: + if contents[i2][i1] == 'contact': + savec = i1 + savel = i2 + if contents[i2][i1] == 'Use of MNI Template': + saveSpaceL = i2 + except: + continue + + props = {} + + if saveSpaceL == 0: + props['MarsAtlas'] = 'specific' + props['Freesurfer'] = 'empty' + props['HippoSubfieldFreesurfer'] = 'empty' + else: + if contents[saveSpaceL][contents[saveSpaceL].index('MarsAtlas')+1] == 'True': + props['MarsAtlas'] = 'MNI' + else: + props['MarsAtlas'] = 'specific' + + if contents[saveSpaceL][contents[saveSpaceL].index('Freesurfer')+1] =='True': + props['Freesurfer'] = 'MNI' + else: + props['Freesurfer'] = 'specific' + + if contents[saveSpaceL][contents[saveSpaceL].index('HippoSubfieldFreesurfer')+1] == 'True': + props['HippoSubfieldFreesurfer'] = 'MNI' + else: + props['HippoSubfieldFreesurfer'] = 'specific' + + startl = savel + 1 + #extract monopolar and bipolar contacts, assuming each list is separated by a two-lines blank + stimpolarity = ['monopolar', 'bipolar'] + ContactsInfos = {'monopolar':{},'bipolar':{}} + i = -2 + for pol in stimpolarity: + i = i + 2 + while contents[startl+i]: + # standard name : 'Ap12' (not A'12, Ap21, a'1a'2...) + nametmp = contents[startl+i][savec] + + testpol = re.search(" - ",nametmp) + if testpol is not None: + polarity = 'bipolar' + else: + polarity = 'monopolar' + + resection = [] + if contents[startl+i][contents[savel].index('Resection')] == 'not in resection': + resection = False + elif not contents[startl+i][contents[savel].index('Resection')] == 'resection not calculated': + resection = True + + #if not Contact.objects.filter(CRF = crf, name = name, polarity = polarity): + if nametmp not in ContactsInfos.keys(): + ContactsInfos[polarity].update({nametmp:{}}) + #newcontact = Contact(CRF = crf, name = name, polarity = polarity, resection = resection, segmentation = greywhite) + + for index_column in contents[savel]: + if index_column != 'contact': + + ContactsInfos[polarity][nametmp].update({index_column:contents[startl+i][contents[savel].index(index_column)]}) + + i += 1 + + ResectionInfos={} + i=i+2 + try: + while contents[startl+i]: + if contents[startl+i]==['Resection Information']: + actualAtlas = '' + elif contents[startl+i]==['mars_atlas']: + actualAtlas = 'mars_atlas' + ResectionInfos.update({'mars_atlas':{}}) + elif contents[startl+i]==['Freesurfer']: + actualAtlas = 'Freesurfer' + ResectionInfos.update({'Freesurfer':{}}) + elif contents[startl+i][0] == 'Volume resection (mm3):' : + ResectionInfos.update({'Volume resection (mm3):':contents[startl+i][1]}) + else: + ResectionInfos[actualAtlas].update({contents[startl+i][0]:contents[startl+i][1]}) + i += 1 + + except: + pass + + return (props,ContactsInfos,ResectionInfos) + + #try: + #ContactsInfos[nametmp].update({'MarsAtlas':contents[startl+i][contents[savel].index('MarsAtlas')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'Freesurfer':contents[startl+i][contents[savel].index('Freesurfer')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'HippoSubfieldFreeSurfer':contents[startl+i][contents[savel].index('HippoSubfieldFreeSurfer')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'MNI':contents[startl+i][contents[savel].index('MNI')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'ALL':contents[startl+i][contents[savel].index('ALL')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'ALLDilate':contents[startl+i][contents[savel].index('ALLDilate')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'Broadmann':contents[startl+i][contents[savel].index('Broadmann')]}) + #except: + #pass + + #try: + #ContactsInfos[nametmp].update({'Hammers':contents[startl+i][contents[savel].index('Hammers')]}) + #except: + #pass \ No newline at end of file diff --git a/readFreesurferLabelFile.py b/readFreesurferLabelFile.py new file mode 100644 index 0000000..868fc69 --- /dev/null +++ b/readFreesurferLabelFile.py @@ -0,0 +1,7 @@ +def readFreesurferLabelFile(freesurfer_label_file): + dict_label = {} + with open(freesurfer_label_file,'r') as inf: + for line in inf: + info_line = line.split() + dict_label.update({info_line[0]:info_line[1:]}) + return dict_label diff --git a/readFunctionalTractography.py b/readFunctionalTractography.py new file mode 100644 index 0000000..e476e79 --- /dev/null +++ b/readFunctionalTractography.py @@ -0,0 +1,52 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import csv, sys, os +import pdb + +def readFunctionalTractography(functional_result_file): + + if os.path.isfile(functional_result_file): + + if functional_result_file.split(".")[-1] == 'csv': + + full_dictionnary = {} + lastParam = None + with open(functional_result_file, 'r') as csvfile: + + spamreader = csv.reader(csvfile, delimiter='\t') + for row in spamreader: + if len(row)<1: + continue + if row[0] == 'Patient' or row[0] == 'Atlas': + full_dictionnary.update({row[0]:row[1]}) + elif row[0] == 'Param': + lastParam = row[1] + full_dictionnary.update({row[1]:{}}) + elif row[0] == 'Parcel_name': + import copy + row_parcel_names = copy.deepcopy(row[1:]) + row_parcel_names = [x.strip() for x in row_parcel_names] + #for i_parcels in range(len(row)-1): + #full_dictionnary[lastParam].update({row[i_parcels+1].strip():{}}) + elif row[0] == 'EndParcelsNames': + lastParam = None + else: + if lastParam is not None: + if row[0].strip() not in full_dictionnary[lastParam].keys(): + full_dictionnary[lastParam].update({row[0].strip():{}}) + else: + pdb.set_trace() + #if row[0].strip() in full_dictionnary[lastParam].keys(): + for i_parcels_bis in range(len(row_parcel_names)): + full_dictionnary[lastParam][row[0].strip()].update({row_parcel_names[i_parcels_bis]:row[i_parcels_bis+1]}) + + + return full_dictionnary + + else: + print("error, wrong file extension") + + else: + print("error, the file doesn't exist") + diff --git a/readSulcusLabelTranslationFile.py b/readSulcusLabelTranslationFile.py new file mode 100644 index 0000000..aba1ac7 --- /dev/null +++ b/readSulcusLabelTranslationFile.py @@ -0,0 +1,7 @@ +def readSulcusLabelTranslationFile(sulcus_label_file): + sulc_labels = [] + with open(sulcus_label_file,'r') as inf: + for line in inf: + sulc_labels.append(line.split()) + sulc_labels_dict = dict((int(value), key) for (value, key) in sulc_labels) + return sulc_labels_dict diff --git a/referentialconverter.py b/referentialconverter.py new file mode 100644 index 0000000..732e13b --- /dev/null +++ b/referentialconverter.py @@ -0,0 +1,441 @@ +# -*- coding: utf-8 -*- +from soma import aims +from soma.aims import apctools +from numpy import * +from brainvisa.data.writediskitem import ReadDiskItem +import pdb + +# Conversion de coordonnées d'un référentiel à un autre. +# Les transformations linéaires (matrices), le référentiel AC-PC, +# le référentiel pseudo-Talairach de BrainVisa et le référentiel +# Goetz peuvent être utilisés. +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +class ReferentialConverter: + """ This class allows to load linear transformations (matrices) from a referential to the "real" anatomist coordinates (image-based) + All declared referentials/transformations can then be used to convert coordinates from one referential to another. + Functions are provided to define the Goetz mesencephalon/PPN referential, the AC-PC referential (from the APC file in BrainVisa, brainvisa database access must be initialized by the caller), + the BEN referential (Benabid normalization, AC-PC with height normalization using Thalamus height and AC-PC length, no Y normalization). Any matrix transformation can be loaded.""" + def __init__(self): + self.availableRefs = {} + self.withMatrixFromReal = {} + self.withMatrixToReal = {} + + #def saveToFile + #self.availableRefs, self.Hthal, self.Ac, self.Pc, self.Ih, self.withMatrixFromReal, self.withMatrixToReal + #self.Oppn,self.XDppn, self.XGppn, self.Yppn, self.Zppn + + def availableReferentials(self): + return self.availableRefs + + def isRefAvailable(self, ref): + return self.availableRefs.has_key(ref) + + + ############################ Generic transformation matrices #################### + def setAnyRef2AnyRef(self, refFrom, refTo, transf, inverse = False): + if not self.isRefAvailable(refFrom): + if self.isRefAvailable(refTo): # If only the refTo is already known, just switch inputs + tmpRef = refTo + refTo = refFrom + refFrom = tmpRef + inverse = not inverse + else: + raise Exception("%s and %s are not known by referentialConverter ! Cannot set transform between them."%(str(refFrom), str(refTo))) + transf = self.anyMatrix2AimsMotion(transf) + if inverse: + transf = transf.inverse() + # Ok, now refFrom is a known referential, we just have to setup a T2 matrix such that fromRef --T1--> MainRef --T2-->toRef = transf + # T2 = transf*inv(T1) + if refFrom in self.withMatrixToReal: + t1inv = self.withMatrixToReal[refFrom].inverse() + elif refFrom in self.withMatrixFromReal: + t1inv = self.withMatrixFromReal[refFrom] + else: + raise Exception("Referential %s is not defined with a matrix !"%refFrom) + t2 = transf*t1inv + self.setTransformMatrix(refTo, t2, t2.inv()) + + def anyMatrix2AimsMotion(self, mat): + if type(mat) == aims.Motion: + return mat + elif type(mat) == list: + return aims.Motion(mat) + elif mat.__dict__.has_key('getInfos'): + infos = anaTransf.getInfos() + rot = infos['rotation_matrix'] + trans = infos['translation'] + return aims.Motion(rot[:3]+[trans[0]]+rot[3:6]+[trans[1]]+rot[6:]+[trans[2]]+[0,0,0,1]) + else: + raise Exception("Unknown transformation type : %s"+type(mat)) + + + def setAnatomistTransform(self, refName, anaTransf, toRef=True): + """ Adds a referential to the converter from an Anatomist Transformation object + :arg refName name of the new referential + :arg anaTransf anatomist transformation object (anatomist.Transformation) + :arg toRef if true, the provided transformation goes from the native referential to refName referential. If false, the opposite. + """ + infos = anaTransf.getInfos() + rot = infos['rotation_matrix'] + trans = infos['translation'] + m = aims.Motion(rot[:3]+[trans[0]]+rot[3:6]+[trans[1]]+rot[6:]+[trans[2]]+[0,0,0,1]) + #pdb.set_trace() + if toRef: + self.setTransformMatrix(refName, m.inverse(), m) + else: + self.setTransformMatrix(refName, m, m.inverse()) + + + def setRawTransformMatrix(self, refName, matrix, toRef=True): + """ Adds a referential to the converter from a raw transformation matrix ([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] for identity)""" + m = aims.Motion(matrix) + if toRef: + self.setTransformMatrix(refName, m.inverse(), m) + else: + self.setTransformMatrix(refName, m, m.inverse()) + + + + def setTransformMatrix(self, refName, matrixFromReal, matrixToReal): + """ Adds a referential to the converter from an aims.Motion matrix """ + #pdb.set_trace() + if matrixFromReal is not None: + self.availableRefs[refName] = True + self.withMatrixFromReal[refName] = matrixFromReal + if matrixToReal is not None: + self.availableRefs[refName] = True + self.withMatrixToReal[refName] = matrixFromReal + + def applyMatrix(self, x, y, z, matrix): + return matrix.transform( aims.Point3df(x,y,z) ).items() + + ############################ AC-PC intra-subject referential (no normalization) + def loadACPC(self, image): + """ Loads the .APC file linked to the provided Image Disk Item and sets AC-PC referential""" + print "****refConv**** Loading ACPC referential" + rdi = ReadDiskItem( 'Commissure coordinates', 'Commissure coordinates' ) + apcfile = rdi.findValue( image ) + points = apctools.apcRead(apcfile.fullPath()) + self.setACPC(points['acmm'], points['pcmm'], points['ihmm']) + + def setACPC(self, ac, pc, ih): + """ Set AC, PC and InterHemispheric points to define the AC-PC referentials """ + self.Ac = ac + self.Pc = pc + self.Ih = ih + self.availableRefs['AC-PC'] = True + + ####### AC-PC patient referential : no normalisation, origin at AC, X left to right, Y towards front, Z up + def real2AcPc(self, x, y, z): + """Convert 'real' native coordinates to AC-PC with origin at AC coordinates""" + # Compute axes + ac = array([self.Ac,]) + pc = array([self.Pc,]) + ih = array([self.Ih,]) + # Y axis is AC-PC axis towards the front + nacpc = linalg.norm(ac - pc) + taly = (ac-pc)/nacpc + + # X axis is perpendicular to the plane containing PC, AC and IH, so cross(Y axis, pseudoZ axis) + talx = cross(taly, ih - pc)# x = y^z + talx /= linalg.norm(talx) + talz = cross(talx, taly) + posT = array([[x, y, z]]) - ac + return [dot(posT[0], talx[0]), dot(posT[0], taly[0]), dot(posT[0], talz[0])] + + + def AcPc2Real(self, x, y, z): + """Convert AC-PC with origin at AC coordinates to 'real' native coordinates """ + # Compute axes + ac = array([self.Ac,]) + pc = array([self.Pc,]) + ih = array([self.Ih,]) + # Y axis is AC-PC axis towards the front + nacpc = linalg.norm(ac - pc) + taly = (ac-pc)/nacpc + + # X axis is perpendicular to the plane containing PC, AC and IH, so cross(Y axis, pseudoZ axis) + talx = cross(taly, ih - pc)# x = y^z + talx /= linalg.norm(talx) + + talz = cross(talx, taly) + + pos = -x*talx + y*taly + z*talz + ac + print " "+repr(pos.tolist()[0]) + return pos.tolist()[0] + + ############################### Anatomist Talairach Referential : bounding box normalizatiokn + def loadTalairach(self, image): + """From a DiskItem of an image, loads the pseudo-talairach transformation from BrainVisa database""" + rdi = ReadDiskItem( 'Transform Raw T1 MRI to Talairach-AC/PC-Anatomist', 'Transformation matrix' ) + di = rdi.findValue(image) + trans = aims.read( di.fullPath() ) # read a Motion object + self.setTransformMatrix('Talairach', trans, trans.inverse()) + + + ##############################" Goetz Referential for the PPN region (pons/mesencephalon) + # Conversion des coordonnées réelles vers les coordonnées Goetz : PROJECTION PERPENDICULAIRE AUX AXES (la projection utilisée pour les publis) + def setGoetz(self, Oppn, XDppn, XGppn, Yppn, Zppn): + """ Best referential for PPN studies according to Laurent Goetz ; PPNorthoGoetz -> orthoprojection on axes + PPN parallel Goetz is also available (points are projected onto each axis parallel to other axes) + Define the referential from the reference points : ponto-mesencephalon junction, + """ + self.Oppn = Oppn + self.XDppn = XDppn + self.XGppn = XGppn + self.Yppn = Yppn + self.Zppn = Zppn + self.availableRefs['PPNorthoGoetz'] = True + self.availableRefs['PPNparaGoetz'] = True + + def real2Gorth(self, x, y, z): + """ Convert native coordinates to normalized orthogonal Goetz referential""" + u = array([x - self.Oppn[0], y - self.Oppn[1], z - self.Oppn[2]]) + # Vecteurs de la base + oxg = array([self.XGppn[0] - self.Oppn[0], self.XGppn[1] - self.Oppn[1], self.XGppn[2] - self.Oppn[2]]) + oxd = array([self.XDppn[0] - self.Oppn[0], self.XDppn[1] - self.Oppn[1], self.XDppn[2] - self.Oppn[2]]) + oy = array([self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]) + oz = array([self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]) + # Normes des vecteurs de la base + nxg = linalg.norm(oxg) + nxd = linalg.norm(oxd) + ny = linalg.norm(oy) + nz = linalg.norm(oz) + # vecteurs unitaires + oxg /= nxg + oxd /= nxd + oy /= ny + oz /= nz + # Produit scalaire entre vecteurs unitaires des axes et la position u pour avoir les coordonnées orthogonale, + # division par la norme des vecteurs pour rapporter aux longueurs de reference + if not self.isRightSideGoetz(u[0], u[1], u[2]): # Selon le coté + return [dot(u, oxg)/nxg, dot(u, oy)/ny, dot(u, oz)/nz, 1] + else: # Right side -> negative X + return [dot(u, oxd)/nxd, dot(u, oy)/ny, dot(u, oz)/nz, -1] + + # Conversion des coordonnées réelles vers les coordonnées Goetz : PROJECTION PARALLELE AUX AXES : résolution d'un système d'équations (m*X+n*Y+o*Z = U) + def real2G(self, x, y, z): + """ Convert native coordinates to normalized parallel Goetz referential""" + u = array([[x - self.Oppn[0], y - self.Oppn[1], z - self.Oppn[2]]]) + # Vecteurs de la base + oxg = array([[self.XGppn[0] - self.Oppn[0], self.XGppn[1] - self.Oppn[1], self.XGppn[2] - self.Oppn[2]]]) + oxd = array([[self.XDppn[0] - self.Oppn[0], self.XDppn[1] - self.Oppn[1], self.XDppn[2] - self.Oppn[2]]]) + oy = array([[self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]]) + oz = array([[self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]]) + # Normes des vecteurs de la base + nxg = linalg.norm(oxg) + nxd = linalg.norm(oxd) + ny = linalg.norm(oy) + nz = linalg.norm(oz) + # vecteurs unitaires + oxg /= nxg + oxd /= nxd + oy /= ny + oz /= nz + + if not self.isRightSideGoetz(u[0][0], u[0][1], u[0][2]): # Left side + matrice = vstack((oxg, oy, oz)) + #print "MATRICE : " + repr(matrice) + #print "SOLUTION : " + repr(linalg.solve(matrice, u[0])) + #print "CHECK U : " + repr(dot(matrice, linalg.solve(matrice, u[0]))) + return (linalg.solve(matrice, u[0])/array([nxg, ny, nz])).tolist() + [1,] + else: + matrice = vstack((oxd, oy, oz)) + return (linalg.solve(matrice, u[0])/array([nxd, ny, nz])).tolist()+[-1,] + + + + # Conversion des coordonnées Goetz vers les coordonnées réelles : PROJECTION PARALLELE AUX AXES u=x_u*X+y_u*Y+z_u*Z + def g2Real(self, xg, yg, zg, side): + """ Convert normalized parallel Goetz referential to native coordinates""" + if side == -1: # Right side + return [self.Oppn[0] + xg*(self.XDppn[0] - self.Oppn[0]) + yg*(self.Yppn[0] - self.Oppn[0]) + zg*(self.Zppn[0] - self.Oppn[0]),\ + self.Oppn[1] + xg*(self.XDppn[1] - self.Oppn[1]) + yg*(self.Yppn[1] - self.Oppn[1]) + zg*(self.Zppn[1] - self.Oppn[1]),\ + self.Oppn[2] + xg*(self.XDppn[2] - self.Oppn[2]) + yg*(self.Yppn[2] - self.Oppn[2]) + zg*(self.Zppn[2] - self.Oppn[2])] + elif side == 1: # left side + return [self.Oppn[0] + xg*(self.XGppn[0] - self.Oppn[0]) + yg*(self.Yppn[0] - self.Oppn[0]) + zg*(self.Zppn[0] - self.Oppn[0]),\ + self.Oppn[1] + xg*(self.XGppn[1] - self.Oppn[1]) + yg*(self.Yppn[1] - self.Oppn[1]) + zg*(self.Zppn[1] - self.Oppn[1]),\ + self.Oppn[2] + xg*(self.XGppn[2] - self.Oppn[2]) + yg*(self.Yppn[2] - self.Oppn[2]) + zg*(self.Zppn[2] - self.Oppn[2])] + else: + print "ERROR : side value in invalid in g2Real : "+repr(side) + + # Est-on à droite de la ligne médiane ? + def isRightSideGoetz(self, x, y, z): + """ Check which side of the brain we are on, from PPN Goetz referential landmarks """ + oy = array([self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]) + oz = array([self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]) + pseudoX = cross(oy, oz) + return dot(pseudoX, array([x,y,z])) > 0 + + # Conversion des coordonnées Goetz vers les coordonnées réelles : PROJECTION PERPENDICULAIRE AUX AXES + # Résolution du système d'inconnu u tel que u.X = x_u, u.Y = y_u et u.Z = z_u ('.' est le produit scalaire) + # OLD VERSION (slightly slower than the newer one using solve) + def g2RealOrth2(self, xg, yg, zg, side): + """ Convert normalized orthogonal Goetz referential to native coordinates (old, slow version)""" + u = array([[xg, yg, zg]]) + # Vecteurs de la base + oxg = array([[self.XGppn[0] - self.Oppn[0], self.XGppn[1] - self.Oppn[1], self.XGppn[2] - self.Oppn[2]]]) + oxd = array([[self.XDppn[0] - self.Oppn[0], self.XDppn[1] - self.Oppn[1], self.XDppn[2] - self.Oppn[2]]]) + oy = array([[self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]]) + oz = array([[self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]]) + # Normes des vecteurs de la base + nxg = linalg.norm(oxg) + nxd = linalg.norm(oxd) + ny = linalg.norm(oy) + nz = linalg.norm(oz) + # vecteurs unitaires + oxg /= nxg + oxd /= nxd + oy /= ny + oz /= nz + # MATLAB : ([norm(OXg), norm(OY), norm(OZ)].*[xg, yg, zg])*inv([OXg'./norm(OXg), OY'./norm(OY), OZ'./norm(OZ)]) + Oppn + if side == -1: # Right side + matrice = hstack((oxd.T, oy.T, oz.T)) + result = dot(array([[nxd, ny, nz]])*u, linalg.inv(matrice)) + array(self.Oppn) + + elif side == 1: # left side + matrice = hstack((oxg.T, oy.T, oz.T)) + result = dot(array([[nxg, ny, nz]])*u, linalg.inv(matrice)) + array(self.Oppn) + else: + print "ERROR : side value is invalid in g2RealOrth : "+repr(side) + + return result.tolist()[0] + + + # Conversion des coordonnées Goetz vers les coordonnées réelles : PROJECTION PERPENDICULAIRE AUX AXES + # Résolution du système d'inconnu u tel que u.X = x_u, u.Y = y_u et u.Z = z_u ('.' est le produit scalaire) + def g2RealOrth(self, xg, yg, zg, side): + """ Convert normalized orthogonal Goetz referential to native coordinates""" + u = array([[xg, yg, zg]]) + # Vecteurs de la base + oxg = array([[self.XGppn[0] - self.Oppn[0], self.XGppn[1] - self.Oppn[1], self.XGppn[2] - self.Oppn[2]]]) + oxd = array([[self.XDppn[0] - self.Oppn[0], self.XDppn[1] - self.Oppn[1], self.XDppn[2] - self.Oppn[2]]]) + oy = array([[self.Yppn[0] - self.Oppn[0], self.Yppn[1] - self.Oppn[1], self.Yppn[2] - self.Oppn[2]]]) + oz = array([[self.Zppn[0] - self.Oppn[0], self.Zppn[1] - self.Oppn[1], self.Zppn[2] - self.Oppn[2]]]) + # Normes des vecteurs de la base + nxg = linalg.norm(oxg) + nxd = linalg.norm(oxd) + ny = linalg.norm(oy) + nz = linalg.norm(oz) + # vecteurs unitaires + oxg /= nxg + oxd /= nxd + oy /= ny + oz /= nz + # MATLAB : ([norm(OXg), norm(OY), norm(OZ)].*[xg, yg, zg])*inv([OXg'./norm(OXg), OY'./norm(OY), OZ'./norm(OZ)]) + Oppn + if side == -1: # Right side + matrice = vstack((oxd, oy, oz)) + result = linalg.solve(matrice, array([nxd, ny, nz])*u[0]) + array(self.Oppn) + elif side == 1: # left side + matrice = vstack((oxg, oy, oz)) + result = linalg.solve(matrice, array([nxg, ny, nz])*u[0]) + array(self.Oppn) + else: + print "ERROR : side value is invalid in g2RealOrth : "+repr(side) + return result.tolist() + + + ############################### Ben's coordinates Benabid AC-PC with thalamus normalization + ###### NORMALIZED BEN'S COORDINATES (normalized along Y and Z axis) + def setBens(self, ac, pc, ih, hthal): + """Set reference points for Ben's normalization : Anterior Commissure, + Posterior Commissure, InterHemispheric point (above AC-PC), + Thalamus height (top of the thalamus, bottom of lateral ventricle, up from AC-PC axial slice). + Origin is at PC, no normalization on X axis, + AC-PC normalization on Y (y/norm(ac-pc)*12.0), Thalamus Height normalization on Z (z/norm(thal-pc)*8.0) + """ + self.setACPC(ac,pc,ih) + self.Hthal = hthal + self.availableRefs['Bens'] = True + + def real2Bens(self, x, y, z): + """Convert native coordinates to normalized Ben's coordinates (IMPLEMENTATION NEVER USED/TESTED)""" + # Compute axes : + ac = array([self.Ac,]) + pc = array([self.Pc,]) + ih = array([self.Ih,]) + hthal = array([self.Hthal,]) + u = array([[x, y, z]]) + # Y axis is AC-PC axis towards the front + nacpc = linalg.norm(ac - pc) + thaly = (ac-pc)/nacpc + # X axis is perpendicular to the plane containing PC, AC and IH, so cross(Y axis, pseudoZ axis) + thalx = cross(thaly, ih - pc)# x = y^z + thalx /= linalg.norm(thalx) + thalz = cross(thalx, thaly) + thalHeight = dot((hthal - pc)[0], thalz[0]) + return [dot(u, thalx), dot(u, thaly)*12.0/nacpc, dot(u, thalz)*8.0/thalHeight] + + def bens2Real(self, xb, yb, zb): + """Convert normalized Ben's coordinates to native coordinates""" + # x is not normalized, so the value is just the distance from the AC-PC line, with X<0 for the right hemisphere + # Compute axes : + ac = array([self.Ac,]) + pc = array([self.Pc,]) + ih = array([self.Ih,]) + hthal = array([self.Hthal,]) + + # Y axis is AC-PC axis towards the front + nacpc = linalg.norm(ac - pc) + thaly = (ac-pc)/nacpc + + # X axis is perpendicular to the plane containing PC, AC and IH, so cross(Y axis, pseudoZ axis) + thalx = cross(thaly, ih - pc)# x = y^z + thalx /= linalg.norm(thalx) + thalz = cross(thalx, thaly) + thalHeight = dot((hthal - pc)[0], thalz[0]) + + pos = (-xb * thalx) + (yb * nacpc / 12.0) * thaly + (zb * thalHeight / 8.0) * thalz + pc # -xb because the sign should ne changed for a direct referential + + return pos.tolist()[0] + + #############################" Generic Conversion ###################################### + # UNIVERSAL REFERENTIAL CONVERTER TO REAL MRI COORDS + def anyRef2Real(self, coords, referential): + """Convert coords [x,y,z] or [x,y,z,side] to native coordinates from any defined referential""" + if not self.isRefAvailable(referential): + print "Referential %s not available"%referential + return None + withSide = {'PPNparaGoetz':self.g2Real, 'PPNorthoGoetz':self.g2RealOrth} + noSide = {'Bens':self.bens2Real, 'AC-PC':self.AcPc2Real,'real':lambda x,y,z:[x,y,z]} + if referential in self.withMatrixToReal: + return self.applyMatrix(coords[0], coords[1], coords[2], self.withMatrixToReal[referential]) + if referential in withSide and size(coords)>3: + return withSide[referential](coords[0], coords[1], coords[2], coords[3]) + elif referential in noSide: + return noSide[referential](coords[0], coords[1], coords[2]) + else: + print "anyRef2Real : no such referential or invalid coords : "+repr(referential)+" -> "+repr(coords) + return None + + # UNIVERSAL REFERENTIAL CONVERTER from REAL MRI COORDS + def real2AnyRef(self, coords, referential): + """Convert coords [x,y,z] or [x,y,z,side] to any defined referential from native coordinates""" + if not self.isRefAvailable(referential): + print "Referential %s not available"%referential + return None + withSide = {} + noSide = {'Bens':self.real2Bens, 'AC-PC':self.real2AcPc,'real':lambda x,y,z:[x,y,z], 'PPNparaGoetz':self.real2G, 'PPNorthoGoetz':self.real2Gorth} + #pdb.set_trace() + if referential in self.withMatrixFromReal: + return self.applyMatrix(coords[0], coords[1], coords[2], self.withMatrixFromReal[referential]) + elif referential in withSide and size(coords)>3: + return withSide[referential](coords[0], coords[1], coords[2], coords[3]) + elif referential in noSide: + return noSide[referential](coords[0], coords[1], coords[2]) + else: + print "anyRef2Real : no such referential or invalid coords : "+repr(referential)+" -> "+repr(coords) + return None + + # Converts coords from any ref to any other referential + def anyRef2AnyRef(self, coords, referentialFrom, referentialTo): + """Convert coords [x,y,z] or [x,y,z,side] from any referential to any other referential""" + reals = self.anyRef2Real(coords, referentialFrom) + if reals is None: + print "Cannot convert to real !" + return None + if size(coords) > 3: # There is side information in coords[3] + reals = reals[:3]+coords[3:] # Keep the side information in case it is needed by the destination referential + return self.real2AnyRef(reals,referentialTo) diff --git a/seegprocessing.py b/seegprocessing.py new file mode 100644 index 0000000..69f2822 --- /dev/null +++ b/seegprocessing.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# +# Functions to process SEEG files, and dictionary of available processing methods for each manip type +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# Define all functions to process SEEG data like this: +#---------------------------------------------- +# def extractBetaFunction(seegfilepath): +# try: +# doSomething(seegfilepath) +# return True +# else: +# return False +# extractBeta = ('Extract Beta', 'Extracts the beta band from the seeg signal and saves it in the DB', extractBetaFunction) +#--------------------------------------------------- +# Then you can add the processing method to 'processors' and add the name of each 'manip' it can be applied to + + +from externalprocesses import * + +# --------------------- Specific Functions ---------------------------- +def localizeFunction(seegfilepath): + try: + matlabCallNB("localize('%s')"%seegfilepath) + return True + except: + return False + +localize = ('Localizer processing', 'Launches JP Lachaux\'s localize matlab process', localizeFunction) + +# --------------------- Linking functions to manips ---------------------------- +processors = { localize:['VISU', 'MVEB', 'MLAH'], } +# ---------------------- Dependencies ------------------------------ +# if "advancedAnalysis" needs "basicAnalysis", add advancedAnalysis:[basicAnalysis,] to dependencies +dependencies = {localize:[],} +# ------------------------ Generic functions -------------------------- +def getProcessingMethods(currentManip = None): + """ Returns all processing methods availables for the manip name provided. If no manip is provided, returns a dictionnary with all processors""" + allManips = set([m for manips in processors.itervalues() for m in manips]) + allProcessorsByManip = dict([(m,[p for p in processors if m in processors[p]]) for m in allManips]) + if currentManip is not None: + return allProcessorsByManip[currentManip] + else: + return allProcessorsByManip + +def getManipNameFromDirName(dirname): + return dirname.split('_')[0] + \ No newline at end of file diff --git a/standard_fit.py b/standard_fit.py new file mode 100644 index 0000000..e7aa33d --- /dev/null +++ b/standard_fit.py @@ -0,0 +1,116 @@ +#!/usr/bin/env nosetests -vs +# coding=utf-8 +""" +Linear algebra standard fitting module + +(C) 2013 hashnote.net, Alisue +""" +__author__ = 'Alisue (lambdalisue@hashnote.net)' +__version__ = '0.1.0' +__date__ = '2013-10-28' +__all__ = ['standard_fit', 'projection', 'distance', 'function'] + +import numpy as np + +def standard_fit(X): + """ + Find (n - 1) dimensional standard (e.g. line in 2 dimension, plane in 3 + dimension, hyperplane in n dimension) via solving Singular Value + Decomposition. + + The idea was explained in the following references + + - http://www.caves.org/section/commelect/DUSI/openmag/pdf/SphereFitting.pdf + - http://www.geometrictools.com/Documentation/LeastSquaresFitting.pdf + - http://www.ime.unicamp.br/~marianar/MI602/material%20extra/svd-regression-analysis.pdf + - http://www.ling.ohio-state.edu/~kbaker/pubs/Singular_Value_Decomposition_Tutorial.pdf + + Example: + >>> XY = [[0, 1], [3, 3]] + >>> XY = np.array(XY) + >>> C, N = standard_fit(XY) + >>> C + array([ 1.5, 2. ]) + >>> N + array([-0.5547002 , 0.83205029]) + + Args: + X: n x m dimensional matrix which n indicate the number of the dimension + and m indicate the number of points + + Returns: + [C, N] where C is a centroid vector and N is a normal vector + """ + # Find the average of points (centroid) along the columns + C = np.average(X, axis=0) + # Create CX vector (centroid to point) matrix + CX = X - C + # Singular value decomposition + U, S, V = np.linalg.svd(CX) + # The last row of V matrix indicate the eigenvectors of + # smallest eigenvalues (singular values). + N = V[-1] + import pdb + pdb.set_trace() + return C, N + +def projection(x, C, N): + """ + Create orthogonal projection matrix of x on the plane + + Args: + x: n x m dimensional matrix + C: n dimensional vector whicn indicate the centroid of the standard + N: n dimensional vector which indicate the normal vector of the standard + + Returns: + n x m dimensional matrix which indicate the orthogonal projection points + on the plane + """ + rows, cols = x.shape + NN = np.tile(N, (rows, 1)) + D = distance(x, C, N) + DD = np.tile(D, (cols, 1)).T + return x - DD * NN + +def distance(x, C, N): + """ + Calculate an orthogonal distance between the points and the standard + + Args: + x: n x m dimensional matrix + C: n dimensional vector whicn indicate the centroid of the standard + N: n dimensional vector which indicate the normal vector of the standard + + Returns: + m dimensional vector which indicate the orthogonal disntace. the value + will be negative if the points beside opposite side of the normal vector + """ + return np.dot(x-C, N) + +def function(x, C, N): + """ + Calculate an orthogonal projection of the points on the standard + + Args: + x: (n-1) x m dimensional matrix + C: n dimensional vector whicn indicate the centroid of the standard + N: n dimensional vector which indicate the normal vector of the standard + + Returns: + m dimensional vector which indicate the last attribute value of + orthogonal projection + """ + Ck = C[0:-1] # centroid for known parameters + Nk = N[0:-1] # normal for known parmeters + Cu = C[-1] # centroid for unknown parameter + Nu = N[-1] # normal for unknown parameter + return np.dot(x-Ck, Nk) * -1.0 / Nu + Cu + +#=============================================================================== +# +# Unittest +# +#=============================================================================== +if __name__ == '__main__': + import doctest; doctest.testmod() diff --git a/templatewidget.py b/templatewidget.py new file mode 100644 index 0000000..74676a9 --- /dev/null +++ b/templatewidget.py @@ -0,0 +1,235 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Widget to choose or create a common template for group studies +# Examples include MNI referential with Colin27 of MNI152 templates, custom SPM/Dartel templates... +# +# (c) Inserm U836 2012-2014 - Manik Bhattacharjee +# +# License GNU GPL v3 +# +# +from PyQt4 import QtGui, QtCore, uic + +import sys, os + + +from brainvisa import axon +from brainvisa.data.readdiskitem import ReadDiskItem +from brainvisa.data.writediskitem import WriteDiskItem +import registration +import numpy + +from externalprocesses import * +from checkSpmVersion import * + +########## SPM calls +# Convert SPM normalization _sn.mat to vector field +spm_SnToField8 = """try, spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +FileNameSN = '%s'; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.matname{1}=FileNameSN; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.vox=[NaN NaN NaN]; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.bb=NaN*ones(2,3); +matlabbatch{1}.spm.util.defs.comp{1}.inv.space{1}=['%s' ',1']; +matlabbatch{1}.spm.util.defs.ofname='%s'; +matlabbatch{1}.spm.util.defs.fnames=''; +matlabbatch{1}.spm.util.defs.savedir.saveusr{1}=spm_str_manip(FileNameSN,'h'); +matlabbatch{1}.spm.util.defs.interp=1; +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" # %(FileNameSN, FileSource, ofname) -> '_sn.mat' file and source image FileSource (normalized with the _sn). For the Database, we want y__inverse.nii, so we need ofname = '_inverse' --> Maybe should provide also the output dir ? Right now, same as _sn.mat + +# API changed in SPM12... +spm_SnToField12 = """try, spm('defaults', 'FMRI');spm_jobman('initcfg'); +clear matlabbatch; +FileNameSN = '%s'; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.matname{1}=FileNameSN; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.vox=[NaN NaN NaN]; +matlabbatch{1}.spm.util.defs.comp{1}.inv.comp{1}.sn2def.bb=NaN*ones(2,3); +matlabbatch{1}.spm.util.defs.comp{1}.inv.space = {'%s'}; +matlabbatch{1}.spm.util.defs.out{1}.savedef.ofname = '%s'; +matlabbatch{1}.spm.util.defs.out{1}.savedef.savedir.saveusr{1}=spm_str_manip(FileNameSN,'h'); +spm_jobman('run',matlabbatch);catch, disp 'AN ERROR OCCURED'; end;quit;""" + +spm_SnToField = spm_SnToField12 + +# Using a vector field, transform points MRI Scanner-based coordinates to MNI coordinates +spm_ConvertPointsToMNI = """try, +P='%s'; +P1=spm_vol([P ',1,1']); +P2=spm_vol([P ',1,2']); +P3=spm_vol([P ',1,3']); +[V1,XYZ]=spm_read_vols(P1); +V2=spm_read_vols(P2); +V3=spm_read_vols(P3); + +%% Apply tranformation to electrodes +wPosElectrode=%s; +for i1=1:size(PosElectrode,1) + D=(XYZ(1,:)-PosElectrode(i1,1)).^2+(XYZ(2,:)-PosElectrode(i1,2)).^2+(XYZ(3,:)-PosElectrode(i1,3)).^2; + [tmp,order]=sort(D); + tmp=tmp(1:18); %% cubic neighborhood + order=order(1:18); + W=1./tmp; %% weight inverse to distance + if sum(isinf(W))>0 + W=[1 zeros(1,length(W)-1)]; + end + wPosElectrode(i1,:)=[sum(V1(order).*W)./sum(W) sum(V2(order).*W)./sum(W) sum(V3(order).*W)./sum(W)]; +end +dlmwrite(%s,wPosElectrode, 'delimiter',' ','precision',16); +;catch, disp 'AN ERROR OCCURED'; end;quit; +""" # %(field_inverse.nii,matrixOfCoords(plots, [1,2,3]), fileOut) + +# Read deformation field y__inverse.nii, apply the vector field to scanner-based coordinates of electrodes +spm_normalizePoints = """ +try, P='%s'; +P1=spm_vol([P ',1,1']); +P2=spm_vol([P ',1,2']); +P3=spm_vol([P ',1,3']); +[V1,XYZ]=spm_read_vols(P1); +V2=spm_read_vols(P2); +V3=spm_read_vols(P3); + +%% Apply tranformation to electrodes +PosElectrode = dlmread('%s'); +wPosElectrode=PosElectrode; +for i1=1:size(PosElectrode,1) +D=(XYZ(1,:)-PosElectrode(i1,1)).^2+(XYZ(2,:)-PosElectrode(i1,2)).^2+(XYZ(3,:)-PosElectrode(i1,3)).^2; +[tmp,order]=sort(D); +tmp=tmp(1:18); %% cubic neighborhood +order=order(1:18); +W=1./tmp; %% weight inverse to distance +if sum(isinf(W))>0 +W=[1 zeros(1,length(W)-1)]; +end +wPosElectrode(i1,:)=[sum(V1(order).*W)./sum(W) sum(V2(order).*W)./sum(W) sum(V3(order).*W)./sum(W)]; +end +dlmwrite('%s',wPosElectrode,'precision',18); +catch, disp 'AN ERROR OCCURED'; end;quit; +""" + + +class TemplateMRI: + def __init__(self, name="", refId=-1, volRefId=-1, anatomist=None): + self.name = name + self.refId = refId + if refId != -1 and volRefId == -1: + self.volRefId = refId + else: + self.volRefId = volRefId + self.referentialDiskItem = None + self.referentialAnatomist = None + if self.refId != -1: + try: + self.referentialDiskItem = registration.getTransformationManager().referential(self.refId) + if anatomist is not None: + self.referentialAnatomist = anatomist.createReferential(self.referentialDiskItem) + except: + pass + self.volumes = None + self.findVolumesInDB(volRefId) + + def findVolumesInDB(self, volRefId=None): + if self.volumes: + return self.volumes + if volRefId is None: + volRefId = self.volRefId + rdi = ReadDiskItem( 'anatomical Template', 'aims readable volume formats', requiredAttributes={'referential':str(volRefId)} ) + self.volumes = list( rdi._findValues( {}, None, False ) ) + return self.volumes + + def normalizeCoordinates(self, coords, referential): + """ Fonction that normalizes a list of (x,y,z) to the template referential if sufficient data is available for the provided referential (MUST BE REIMPLEMENTED BY EACH KIND OF TEMPLATE) """ + print "TemplateMRI : normalization not implemented for generic class !" + return [] + pass + def denormalizeCoordinates(self, coords, referential): + """ Fonction that denormalizes a list of (x,y,z) from the template referential if sufficient data is available to the provided referential (MUST BE REIMPLEMENTED BY EACH KIND OF TEMPLATE) """ + print "TemplateMRI : denormalization not implemented for generic class !" + return [] + pass + + def resampleVolume(referential, readPath, writePath): + """ Resamples the provided volume (Nifti...) in the template referential """ + print "TemplateMRI : resampling not implemented for generic class !" + return [] + pass + + +class TemplateMNI(TemplateMRI): + + def __init__(self, anatomist = None): + TemplateMRI.__init__(self, name="MNI", refId=registration.talairachMNIReferentialId, volRefId='19bfee8e-51b1-4d9e-8721-990b9f88b12f', anatomist=anatomist) #registration.talairachMNIReferentialId + + def normalizeCoordinates(self, coords, refId): + """Normalize the coordinates in MNI referential. refId is the uuid of a referential of the T1pre used to store the coords""" + return self.convertT1ScannerBasedToMni(coords, refId) + + def getT1preMniTransform(self, refId): + """Returns the path of the transformation to MNI (vector field) and compute it if necessary (from _sn.mat)""" + # Get referential file + transfoManager = registration.getTransformationManager() + refDiskitem = transfoManager.referential( refId ) + # Find _sn.mat + rdi = ReadDiskItem( 'SPM2 normalization matrix', 'Matlab file' ) + rdiT1 = ReadDiskItem( 'Raw T1 MRI', 'aims readable volume formats') + diT1 = rdiT1.findValue(refDiskitem) + di = rdi.findValue(diT1) + if di is None: + print "SPM deformation _sn.mat not found in database" + return None + # Convert to field + wdi = WriteDiskItem( 'SPM normalization inverse deformation field', 'NIFTI-1 image' ) + diField = wdi.findValue(di) + if diField is None: + print "Cannot find path to save MNI vector field in the DB" + return None + #For a file /database/y_SubjectName_inverse.nii, get SubjectName_inverse + ofname = os.path.basename(diField.fullPath()).lstrip('y_').rsplit('.',1)[0] + if not os.path.exists(diField.fullPath()): + matlabRun(spm_SnToField%(str(di.fullPath()), str(diT1.fullPath()), ofname) ) + else: + print "Deformation field already present : not recomputed in %s"%diField.fullPath() + if os.path.exists(diField.fullPath()): + return diField.fullPath() + else: + print "Matlab did not convert the MNI transform to vector field !" + return None + + def convertT1ScannerBasedToMni(self, points, refId): + """Converts an array of points [x,y,z] in scanner-based coords to MNI coords if deformation field is available""" + field = self.getT1preMniTransform(refId) + if field is None: + print "MNI deformation field not found" + return None + tmpOutput = getTmpFilePath('csv') + arr = numpy.asarray(points)#([ [1,2,3], [4,5,6], [7,8,9] ]) + numpy.savetxt(tmpOutput, arr, delimiter=",") + print "Launching SPM NORMALIZE POINTS with %s"%tmpOutput + matlabRun(spm_normalizePoints % (field, tmpOutput, tmpOutput)) + out = numpy.loadtxt(tmpOutput, delimiter=",") + os.remove(tmpOutput) + if numpy.array_equal(out, arr): + print "Points to MNI : Error, result read is identical to input" + return None + if out.shape != arr.shape: + print "Points to MNI : Error, result (%s) has not the same number of elements as input (%s)"%(repr(out),repr(arr)) + return None + return out.tolist() + + + +class TemplateWidget(QtGui.QWidget): + def __init__(self, app=None): + QtGui.QWidget.__init__(self) + + + + +if __name__ == "__main__": + app = QtGui.QApplication(sys.argv) + axon.initializeProcesses() + from brainvisa.data.readdiskitem import ReadDiskItem + from brainvisa.data.writediskitem import WriteDiskItem + window = TemplateWidget() + window.show() + sys.exit(app.exec_()) diff --git a/templatewidget.ui b/templatewidget.ui new file mode 100644 index 0000000..9037e11 --- /dev/null +++ b/templatewidget.ui @@ -0,0 +1,141 @@ + + + Form + + + + 0 + 0 + 432 + 657 + + + + Form + + + + + + + + Choix d'un template + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Créer un template Dartel + + + + + + + + Nom du template + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Générer le template + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 341 + + + + + + + + +

q c #723102", +",q c #CF976B", +"'q c #F6BE92", +")q c #EEBA92", +"!q c #EDC3A3", +"~q c #ECC7AA", +"{q c #E9D0BC", +"]q c #727A6E", +"^q c #B5B8B0", +"/q c #466D33", +"(q c #446B32", +"_q c #92A188", +":q c #295915", +"r c #535950", +",r c #161815", +"'r c #889384", +")r c #5C645A", +"!r c #255512", +"~r c #889E7D", +"{r c #265313", +"]r c #0E3900", +"^r c #133E04", +"/r c #899D7D", +"(r c #315E1E", +"_r c #295815", +":r c #5F7F4D", +"s c #823809", +",s c #EACFB8", +"'s c #1D2B12", +")s c #365420", +"!s c #677460", +"~s c #81897E", +"{s c #191A18", +"]s c #97A492", +"^s c #5F824D", +"/s c #789568", +"(s c #B9BAB6", +"_s c #9DAA94", +":s c #1E4C0C", +"t c #885024", +",t c #6F3001", +"'t c #333832", +")t c #454A43", +"!t c #2E5B1A", +"~t c #A2AD99", +"{t c #ABB3A5", +"]t c #2B551B", +"^t c #295317", +"/t c #A5AF9E", +"(t c #A1AB98", +"_t c #92A187", +":t c #C4C2C3", +"u c #E9D0BD", +",u c #EACDB4", +"'u c #EBC8AB", +")u c #F1B98D", +"!u c #C89164", +"~u c #834416", +"{u c #833A09", +"]u c #D09A6D", +"^u c #F9C195", +"/u c #19260F", +"(u c #96A192", +"_u c #CBD9C5", +":u c #909A8A", +"v c #F0C4A3", +",v c #EEC7A9", +"'v c #ECCAAF", +")v c #304A1D", +"!v c #A6B2A1", +"~v c #828D7F", +"{v c #BBCAB4", +"]v c #6F776B", +"^v c #BEC0BB", +"/v c #5C7D4B", +"(v c #335C22", +"_v c #91A386", +":v c #406A2D", +"w c #592500", +",w c #552300", +"'w c #532400", +")w c #663A17", +"!w c #825A3B", +"~w c #916E51", +"{w c #B2947C", +"]w c #E0C7B3", +"^w c #EAD6C6", +"/w c #E6DBD3", +"(w c #E9E1DB", +"_w c #EAE5E1", +":w c #E7E3E1", +"x c #698E51", +",x c #8AA474", +"'x c #557C40", +")x c #0F3A04", +"!x c #123606", +"~x c #452705", +"{x c #861B04", +"]x c #1D2F11", +"^x c #1A1A19", +"/x c #0B0A09", +"(x c #020100", +"_x c #080300", +":x c #140C06", +"y c #311600", +",y c #260F00", +"'y c #342214", +")y c #887A6F", +"!y c #D0C6BD", +"~y c #EBE3DD", +"{y c #CBC6C3", +"]y c #514E4B", +"^y c #4A4847", +"/y c #C2C1C0", +"(y c #6A7864", +"_y c #495047", +":y c #899484", +"z c #EDEDEC", +",z c #A9A8A7", +"'z c #363433", +")z c #060200", +"!z c #0D0600", +"~z c #100600", +"{z c #170A00", +"]z c #665547", +"^z c #D7C3B2", +"/z c #EDD5C1", +"(z c #ECC4A5", +"_z c #FBD1B0", +":z c #AD8260", +"A c #2B5918", +",A c #9CAA92", +"'A c #426B2E", +")A c #1A4F07", +"!A c #3B6D24", +"~A c #234F13", +"{A c #2A5619", +"]A c #749164", +"^A c #AEB5A7", +"/A c #C1BFBF", +"(A c #8EA283", +"_A c #7E9672", +":A c #78916B", +"B c #CDB8A7", +",B c #695546", +"'B c #231306", +")B c #140600", +"!B c #1E150F", +"~B c #938C87", +"{B c #E0DBD7", +"]B c #9A9693", +"^B c #312E2D", +"/B c #312F2F", +"(B c #A2A2A0", +"_B c #879184", +":B c #96A090", +"C c #180700", +",C c #BEAEA1", +"'C c #F3E4D8", +")C c #E9DDD3", +"!C c #E9DFD6", +"~C c #E1D8D1", +"{C c #CCC4BE", +"]C c #5A544F", +"^C c #3F3D3B", +"/C c #CFCECC", +"(C c #F1F0EF", +"_C c #EAEBEA", +":C c #29411A", +"D c #98A88D", +",D c #759165", +"'D c #1C4E09", +")D c #486F38", +"!D c #AEB6A7", +"~D c #476D36", +"{D c #272F06", +"]D c #711D04", +"^D c #1E3211", +"/D c #474A44", +"(D c #D1D0D1", +"_D c #9D9B98", +":D c #181512", +"E c #B7B9B5", +",E c #4F763C", +"'E c #124302", +")E c #5A7D47", +"!E c #B2B9AC", +"~E c #3F6830", +"{E c #172C00", +"]E c #602005", +"^E c #2E471C", +"/E c #060D01", +"(E c #151416", +"_E c #B0B0B1", +":E c #908F8F", +"F c #798275", +",F c #C9D7C1", +"'F c #636B61", +")F c #636B60", +"!F c #576F4C", +"~F c #AAABA6", +"{F c #547443", +"]F c #012A00", +"^F c #1E4B0C", +"/F c #8C9E80", +"(F c #B7BBB2", +"_F c #476F35", +":F c #6E8A5D", +"G c #51584F", +",G c #C5D6C0", +"'G c #9FAA9A", +")G c #0E1724", +"!G c #123105", +"~G c #193E0E", +"{G c #214E10", +"]G c #355F26", +"^G c #4F743F", +"/G c #698957", +"(G c #779268", +"_G c #587D46", +":G c #52773F", +"H c #B0B4AD", +",H c #869B78", +"'H c #093600", +")H c #ADB4A9", +"!H c #3C6928", +"~H c #3B6727", +"{H c #8FA085", +"]H c #B6BAAF", +"^H c #A9AFA4", +"/H c #2E5C1C", +"(H c #0E3B01", +"_H c #164509", +":H c #275115", +"I c #788175", +",I c #292B27", +"'I c #4B5148", +")I c #4C743B", +"!I c #194807", +"~I c #123907", +"{I c #134002", +"]I c #305B1D", +"^I c #92A287", +"/I c #B3B6B0", +"(I c #819876", +"_I c #769168", +":I c #577C44", +"J c #C8D7C3", +",J c #0D1624", +"'J c #102F01", +")J c #1B4D09", +"!J c #124601", +"~J c #708B62", +"{J c #1A460A", +"]J c #0D3600", +"^J c #315A1F", +"/J c #A4B09B", +"(J c #9DA994", +"_J c #295A16", +":J c #759066", +"K c #737A70", +",K c #334C22", +"'K c #3A5A22", +")K c #3E5E28", +"!K c #343D2F", +"~K c #767F73", +"{K c #CDDEC8", +"]K c #7C8678", +"^K c #080907", +"/K c #787970", +"(K c #455E38", +"_K c #355826", +":K c #3A5F28", +"L c #9BA991", +",L c #BBBBB7", +"'L c #648552", +")L c #1C4C0C", +"!L c #718D61", +"~L c #90A282", +"{L c #A9B1A4", +"]L c #8DA07F", +"^L c #60824E", +"/L c #235210", +"(L c #1F4E10", +"_L c #517B43", +":L c #ACA086", +"M c #4C6639", +",M c #344F21", +"'M c #87947E", +")M c #DADCD9", +"!M c #CFDFCA", +"~M c #0C1521", +"{M c #3B5D64", +"]M c #142E06", +"^M c #123406", +"/M c #113305", +"(M c #94A688", +"_M c #6A8B58", +":M c #345F23", +"N c #346120", +",N c #5B7E49", +"'N c #789467", +")N c #869C78", +"!N c #A7B0A1", +"~N c #6C885F", +"{N c #4E723D", +"]N c #0F3A07", +"^N c #352C06", +"/N c #831B04", +"(N c #F4F6F3", +"_N c #B9C4B1", +":N c #97A88B", +"O c #787873", +",O c #7C8177", +"'O c #6D845F", +")O c #1F4F0B", +"!O c #174506", +"~O c #1B490A", +"{O c #184A07", +"]O c #1D4D0B", +"^O c #1C4D0C", +"/O c #124400", +"(O c #597C47", +"_O c #BABEB5", +":O c #093900", +"P c #898788", +",P c #6A7C5E", +"'P c #1B480E", +")P c #587D44", +"!P c #C1BFC2", +"~P c #A9B2A1", +"{P c #4F773D", +"]P c #587E44", +"^P c #8FA184", +"/P c #ADB4A5", +"(P c #779069", +"_P c #215111", +":P c #92A386", +"