
    _iC_              	          d dl mZ d dlmZmZ d dlmZmZ d dlm	Z	m
Z
mZmZ d dlmZmZmZmZmZmZmZ d dlmZ d dlmZ d dlmZ d d	lZd d	lZd d	lZd d	lZd d
lm Z   ej!        e"          Z# ed          Z$ ed          Z% ed          Z& ed          Z' ed          Z( ed          Z) ed          Z* ed          Z+ ed          Z, ed          Z-dZ.dZ/dZ0dZ1i dddddddd d!d"d#dd$d%d&d'd(d)d*d)d+d'd,dd-d.d/d%d0d%d1d%d2dZ2g d3g d4g d5d6d7gg d8d9Z3d:d;d<d=d>d?d@dAdBZ4i dCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcddi dedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dd~ddddddddddZ5ddZ6ddZ7e/fdZ8d Z9d Z: G d de          Z; G d de          Z<ddZ=d Z>ddZ?d	S )    )A4)getSampleStyleSheetParagraphStyle)cmmm)	TA_CENTERTA_LEFTTA_RIGHT
TA_JUSTIFY)SimpleDocTemplate	ParagraphSpacerTable
TableStyle	PageBreakFlowable)colors)HexColor)BytesION)current_appz#0f0f23z#1a1a2ez#1f1f3e#333366z#6366f1z#ffffffz#94a3b8z#10b981z#f59e0bz#ef4444   i        
points_2fa
   points_filtrage   
points_edr   points_gestionnaire_mdp   points_sauvegarde_types   points_3211points_frequence   points_cloud   points_os_postes   points_os_serveurspoints_hyperviseurpoints_parefeu
points_vpn   points_phishingpoints_formationpoints_pra_pcapoints_audit))q_2faz%Authentification Double Facteur (MFA))q_gestionnaire_mdpz.Utilisation d'un gestionnaire de mots de passe)q_filtrage_mailzSolution de filtrage des emails)q_edrzProtection Antivirus / EDR))q_sauvegarde_typesTypes de sauvegarde)q_architecture_editeuru'   Architecture (si éditeur spécialisé))q_3211u   Respect de la règle 3-2-1-1)q_frequence   Fréquence des sauvegardes)q_cloud_rgpdu   Conformité Cloud RGPD))q_os_postesu    Système d'exploitation (Postes))q_os_serveursu"   Système d'exploitation (Serveurs))q_hyperviseuru   Mise à jour Hyperviseur)	q_parefeuzType de Pare-feu)q_vpnu#   Sécurisation Accès Distants (VPN)))
q_phishingzCampagnes de test Phishing)q_formationzFormation des utilisateurs)	q_pra_pcau!   Plan de Reprise d'Activité (PRA))q_auditu   Audit externe récurrent)u   PROTECTION DES ACCÈSu   SAUVEGARDES & DONNÉESu   INFRASTRUCTURE & SYSTÈMESu   RÉSEAU & ACCÈS DISTANTSzHUMAIN & ORGANISATIONq_filtrage_mail_editeurq_edr_editeurq_gestionnaire_mdp_nomq_sauvegarde_editeurq_os_postes_editeurq_os_serveurs_editeurq_hyperviseur_editeurq_parefeu_editeur)r7   r8   r6   r9   r@   rA   rB   rC   ouizOui / En placenonzNon / AbsentpartielPartiellementn_azNon ApplicableaucunzAucun dispositifoutil_specialiseu   Solution dédiéemicrosoft_basezMicrosoft 365 (Base)edru   EDR Managé	antiviruszAntivirus classiqueediteur_specialiseu   📦 Éditeur spécialisécloudu   ☁️ Cloudnasu   🗄️ NASbandeu   📼 Bandes magnétiquesusbu   💾 Disque USBaucuneu   ❌ Aucune sauvegardehybrideu   🔁 Hybride (Local + Cloud)multi_sitesu   🏢 Multi-sites
full_cloudu   ☁️ Full CloudjournaliereQuotidiennehebdomadaireHebdomadaire	mensuelle	MensuelleannuelleAnnuelle
sans_cloudzPas de Cloudrecentu   ✅ Récents et à jourunsupported_soonu   ⚠️ Fin de vie procheobsoleteu   ❌ Obsolètes	ngfw_gereu   Pare-feu Nouvelle Générationrouteur_baseu   Box Opérateur / Routeur simplevpn_gereu   VPN Sécurisé
rdp_directzRDP Ouvert (Critique)
rdp_ouverttrimestrielTrimestrielannuelAnnueljamaisJamaisu   Oui, testé régulièrementu   Oui, mais non testé
Inexistant)testeexiste
inexistantc                 n    	 t          t          |                     S # t          t          f$ r |cY S w xY wN)intfloat
ValueError	TypeErrorvaldefaults     7/var/www/html/MCyber-Diagnostic/services/pdf_service.pysafe_intr      sB    5::	"   s    44 c                 (    | |S t          |           S r   )strr   s     r   safe_strr      s    
{s88O    c                    | dS t          |           d |         } t          j        |           } t          j        dd|           } t          j        dd|           } t          j        dd|           } |                                 S )Nr   z [\x00-\x08\x0B\x0C\x0E-\x1F\x7F]z<[^>]*>z\s+ )r   htmlescaperesubstrip)text
max_lengths     r   sanitize_textr      sw    |rt99[j[!D;tD65r4@@D6*b$''D6&#t$$D::<<r   c                 F   t          | t                    si S i }g d}|D ]F}t          |                     |d                    }t	          dt          |d                    ||<   Gt          |                     dd          d          }|r|nd|d<   |                                 D ]C\  }}|                    d          s|                    d	          rt          |d
          ||<   D|                                 D ]\  }}|	                    d          r|||<    |S )N)nb_postes_fixesnb_postes_portablesnb_postes_critiquesnb_serveurs_physiquesnb_serveurs_virtuelsnb_serveurs_critiquesr   i'  
volumetrie   Non spécifié2   r   _editeur_nomd   q_)

isinstancedictr   getmaxminr   itemsendswith
startswith)donnees	validated	champs_nbkeyr   vols         r   validate_form_datar      sJ   gt$$ 	I  I  0 0w{{3**++QC//	#
L2BCCPR
S
S
SC%(>cc.>IlMMOO A AS<<
## 	As||F';'; 	A+CC@@@Ys^MMOO ! !S>>$ 	! IcNr   c                     t          | t                    r%| sdS d | D             }d                    |          S | rt                              | d          ndS )u   
    Convertit une liste de réponses (checkboxes) en texte lisible.
    Exemples:
    - ['cloud', 'nas'] → "☁️ Cloud, 🗄️ NAS"
    - ['journaliere'] → "Quotidienne"
    - 'oui' → "Oui / En place"
    r   c                 D    g | ]}t                               ||          S  )MAP_REPONSESr   ).0vs     r   
<listcomp>z)format_liste_reponses.<locals>.<listcomp>   s(    DDD\--a33DDDr   z, )r   listjoinr   r   )valeurelements_lisibless     r   format_liste_reponsesr      sq     &$ Z 	$##DDVDDDyy*+++ >DY|(8999IYYr   c                       e Zd ZddZd ZdS )
CyberGaugex   c           	          t          j        |            t          dt          dt	          |                              | _        || _        || _        d| _        d S )Nr   r   -   )	r   __init__r   r   r   scorewidthheightradius)selfr   r   r   s       r   r   zCyberGauge.__init__   sM    $CXe__5566

r   c                    | j                                          | j                             | j        dz  | j        dz             | j        dk    rt          }n| j        dk    rt          }nt          }| j         	                    t          d                     | j                             d           | j                             dd| j        dd           | j        dk    rd	| j        d
z  z  }| j         	                    |           | j                             d           | j                                         }|                    | j         | j         | j        | j        d|            | j                             |dd           | j                             t$          j                   | j                             dd           | j                             ddt-          | j                             | j                             t.                     | j                             dd           | j                             ddd           | j                                          d S )Nr)   P   r   r   r+   r      )strokefillih  r   Z   Helvetica-Bold   i	Helvetica	   iz/ 100)canv	saveState	translater   r   r   COLOR_SUCCESSCOLOR_WARNINGCOLOR_DANGERsetStrokeColorr   setLineWidthcircler   	beginPatharcdrawPathsetFillColorr   whitesetFontdrawCentredStringr   COLOR_SUBTEXTrestoreState)r   colorangleps       r   drawzCyberGauge.draw   s   		DJqL$+a-888:]UUZ2}uu"e	  )!4!4555	q!!!	At{11===:>>4:+,EI$$U+++I""1%%%	##%%AEE4;,dk4;UFSSSIq333	v|,,,	*B///	##Ar3tz??;;;	}---	+q)))	##AsG444	     r   N)r   r   __name__
__module____qualname__r   r   r   r   r   r   r      s7           ! ! ! ! !r   r   c                       e Zd ZddZd ZdS )CyberProgressBarr   r+   c                     t          j        |            || _        t          dt	          |d                    | _        || _        || _        d S )Nr   r'   )r   r   r   r   r   	max_scorer   r   )r   r   r   r   r   s        r   r   zCyberProgressBar.__init__   sG    $
QA 6 677
r   c           	      :   | j         t          d          }d}n]t          dt          | j                             }t	          d|| j        z            }|dk    rt          }n|dk    rt          }nt          }| j	        
                    t          d                     | j	                            dd| j        | j        ddd	           | j        |z  }|dk    rB| j	        
                    |           | j	                            dd|| j        ddd	           d S d S )
Nz#4b5563r   g      ?皙?皙?z#111122r"   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   	roundRectr   r   )r   r   pctr   
fill_widths        r   r   zCyberProgressBar.draw   s   :Y''Eqa$*--..Cc3/00Cczz=55]UU&%	x	22333	Aq$*dk11QOOOZ#%
>>I""5)))I1j$+qqQRSSSSS >r   N)r   r+   r   r   r   r   r   r      s<           T T T T Tr   r   MCyber Consultingc                 n   |                                   |                     t                     |                     ddt          d         t          d         dd           |                     t                     |                     d           |                     ddt          d         d           | 	                    dd           |                     t          d	                     |                     t          d         dz  dt          z  | d
|j                    |                                  d S )Nr   r   TFr   r)   r   r    z#444466z - Page )r   r   COLOR_BG_PAGErectr   r   COLOR_ACCENTr   liner   r   r   r   pager   canvasdoccompany_names      r   draw_backgroundr    s   

&&&
KK1beRUeK<<<
,'''

KK1beQ
NN;"""
++,,,
RU1Wad|,O,OSX,O,OPPP
r   c                    d}d}| j         dk    s| j         dk    r+| j        r| j        r| j        }| j        r| j        r| j        }na| j         dk    rV| j        rO| j        rH| j        j        r| j        j        r| j        j        }| j        j        r| j        j        r| j        j        }|rNt          j        	                    t          j        d|          }t          j                            |          r||fS t          j        	                    t          j        d          }t          j                            |          r||fS d|fS )u   
    Détermine le chemin du logo à utiliser selon la hiérarchie white-label.
    Retourne le chemin absolu du logo ou None.
    Nr   manageradminuserzstatic/uploads/logoszstatic/images/logo.png)roleshow_logo_on_reportslogo_filenameshow_company_name_on_reportsr  use_manager_brandingr	  ospathr   r   	root_pathexists)r  r  r  	logo_pathdefault_logos        r   get_logo_pathr     sW   
 M&LyIg!5!5$ 	/); 	/ .M, 	-1B 	-,L	f		$ 	9 	9|0 ;T\5O ; $ :|8 9T\=V 9#|8  +GLL!68NP]^^	7>>)$$ 	+l** 7<< 57OPPL	w~~l## *\))r   c                    R |i }nt          |          }ddlm} t          | j        t
                    }|sd}	 t          |dd          }t          |dd           }|dk    r| j        |k    rt          d	          |d
k    r?| j        |k    r4ddl	m
} |j                            | j                  }	|	r|	j        |k    rd}n# t          $ r Y nw xY wt                      }
t!          |
t"          dt$          z  dt$          z  dt$          z  dt$          z  d|           }g }t'          dddt(          j        d          }t'          dddt,          d          }t'          dddt(          j        dd           }t'          d!dd"t,          dd#           }t'          d$ddt/          d%          d          }t'          d&dd't/          d(          d)*          }t'          d+dd,t/          d-          .          }t'          d/dd,t(          j        t0          0          }dd1lm} | j        r| j                            d2          nd3}t;          | j                  d d'                                         }ddl	m
} |j                            | j                  }|rtA          |          nd4\  }Rg }|r	  ||dt$          z  dt$          z  d56          }|!                    |g           |!                    tE          dd'          g           n4# t          $ r'}tF          $                    d7|            Y d }~nd }~ww xY w|%                    tM          d8|          gtM          |                                |          gtE          dd#          gtM          d9| d:| |          gtM          d;R d<|          gg           tO          |dt$          z  g=          }tQ          tS          | j*                  d>d>?          }tO          ||ggdt$          z  d#t$          z  g=          }|+                    tY          d@dAdBtZ          fdCdDdEdFdAdBdt/          dG          fg                     |!                    |           |!                    tE          ddt$          z                       |!                    tM          dH|                     i dIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidj} t]          |/                                          }!g }"ta          dtc          |!          d          D ]}#g }$ta          d          D ]}%|#|%z   tc          |!          k     r|!|#|%z            \  }&}'|                     |&|&          }(td                              |&d#          })|'tS          |'          nd}*|'|* dk|) nd3}+tg          |'|*nd |)dlm          },|)dk    r|'|*|)z  nd}-|-dnk    rth          n$|'|-dok    rtj          ntl          nt/          d(          }.tO          tM          |(t'          dpd,t/          d-          q                    tM          dr|+ dst'          dtd,|.t0          u                    ggd>dvg=          }/tO          |/g|,ggdwg=          }0|0+                    tY          d@dAdBtn          fdxdydAdBdtp          fg                     |$!                    |0           |$!                    d           |"!                    |$           |"r\tO          |"d,t$          z  d,t$          z  g=          }1|1+                    tY          g dz                     |!                    |1           |!                    tE          ddt$          z                       |!                    tM          d{|                     |stO          tM          d||          ggd}t$          z  g=          }2|2+                    tY          d@dAdBt/          d~          fdFdAdBdth          fdg                     |!                    |2           n|d tr                   }3tc          |          tr          k    r_|!                    tM          dtj           dtr           d|                     |!                    tE          ddt$          z                       |3D ])}4t          |4                    dd          d          }5t          |4                    dd          tt                    }6t          |4                    dd          tv                    }7|5dk    rtl          t/          d          d}:}9}8n7|5dk    rtj          t/          d          d}:}9}8nt,          t/          d          d}:}9}8tO          tM          d|8 d|: d|          tM          dr|6 dst'          ddt(          j        q                    tM          d|8 d|5                                 d<t'          dd't0                              ggdt$          z  dt$          z  dt$          z  g=          };tO          |;gtM          |7|          ggd}t$          z  g=          }<|<+                    tY          d@dAdA|9fd@ddBtn          fdFdAdBd|8fddydAdAd|8fg                     |!                    |<           |!                    tE          ddot$          z                       +|!                    ty                                 |!                    tM          d|                     	 tS          |                    dd                    tS          |                    dd                    z   }=tS          |                    dd                    }>tS          |                    dd                    tS          |                    dd                    z   }?tS          |                    dd                    }@t          |                    dd          d          }An:# t          $ r-}tF          $                    d|            d}=d}?d}AY d }~nd }~ww xY wdt;          |=          gdt;          |>          gdt;          |?          gdt;          |@          gd|Agg}Bg }C|BD ]8\  }D}E|C!                    tM          |D|          tM          |E|          g           9tO          |Cdt$          z  d#t$          z  g=          }F|F+                    tY          d@dAdBtn          fdFdAdBdtz          fddAdBdtz          fdxg                     |!                    tM          d|                     |!                    |F           |!                    tE          ddt$          z                       t|          /                                D ]\  }G}Hg }I|HD ]\  }J}K|                    |J          }Lt          |L          }Mt                              |J          }N|Nr0t          |                    |Nd          d          }O|Or	|Md|O dz  }M|I!                    tM          t          |K          |          tM          |M|          g           |Ir|!                    tM          t          |G          |                     tO          |Idt$          z  d#t$          z  g=          }P|P+                    tY          d@dAdBtn          fdFdAdBdtz          fddAdBdtz          fdxg                     |!                    |P           |!                    tE          ddt$          z                       	 Rfd}Q|A                    ||Q|Q           |
B                    d           tF          C                    d| j                    |
S # t          $ r4}tF          D                    d| d           t          d          |d }~ww xY w)Nr   )current_userr   zClient Inconnur  r   idr  u   Accès non autorisér	  )UserzCLIENT CONFIDENTIELg      ?r   r)   zAudit - )pagesizerightMargin
leftMargin	topMarginbottomMargintitleT1r          )fontNamefontSize	textColorleadingT2r   r$      )r%  r&  r'  
spaceAfterH2   r   r   )r%  r&  r'  spaceBeforer+  H3   r'   Nz#cbd5e1Lr    z#64748b	uppercase)r%  r&  r'  textTransformQCr   z#e2e8f0)r%  r&  r'  RC)r%  r&  r'  	alignment)Imagez%d/%m/%YzN/A)Nr   proportional)r   r   kindzImpossible de charger le logo: zRAPPORT DE DIAGNOSTICu   Réf: #u    • z<font size=8 color=#64748b>z</font>)	colWidthsr   )r   r   
BACKGROUNDr   r   r?  )VALIGNr=  r>  MIDDLE)ALIGNr   r   rC  CENTER)PADDINGr=  r>  r   BOXz#333355u   ANALYSE DÉTAILLÉEr   zDouble authentificationr   zFiltrage des mailsr   zProtection Endpointsr!   zGestion mots de passer#   r:   r%   u   Règle 3-2-1-1r&   r>   r(   zCloud / RGPDr*   z	OS Postesr,   zOS Serveursr-   Hyperviseurr.   zPare-feur/   u   Accès distantr1   zTest phishingr2   zFormation continuer3   zPRA/PCAr4   u   Audit récurrentz /    )r   r   r   r   CT)r&  r'  z<b>z</b>CS)r&  r'  r7  (   r   )rE  r=  r>  r    	LINEBELOW))r@  r=  r>  TOP)rB  r=  r>  rD  )BOTTOMPADDINGr=  r>  r'   zPLAN D'ACTIONu,   Aucune anomalie critique détectée. Bravo !   z#064e3b)rE  r=  r>  r*  z<font color=z>Note : Seules les u3    premières préconisations sont affichées.</font>g333333?graviteMoyennetitrez
Sans titredetailsCritiquez#450a0au   ✕u   Élevéez#451a03!z#1e1b4biz size=12><b>z</b></font>PT>PG)r&  r7  r"   )r   r   g      ?)rE  r=  r>  r   u%   ANNEXE : RÉCAPITULATIF DES RÉPONSESr   r   r   r   r   r   r   r   r   u   Erreur extraction volumétrie: ?zPostes de travail (Total)zDont postes critiqueszServeurs (Total)zDont serveurs critiquesu   Volume de données estimé	INNERGRIDg      ?u   Volumétrie & Parcr   z <font color='#94a3b8'>(z)</font>c                 *    t          | |           d S r   )r  r  s     r   draw_bg_with_companyz1generer_pdf_rapport.<locals>.draw_bg_with_company,  s    FC66666r   )onFirstPageonLaterPagesu(   PDF généré avec succès pour rapport zErreur PDF: T)exc_infou%   Erreur lors de la génération du PDF)Fr   flask_loginr  r   
nom_clientMAX_NAME_LENGTHgetattruser_idPermissionErrormodelsr  queryr   
manager_id	Exceptionr   r   r   r   r   r   r   r   r   r
   reportlab.platypusr8  date_creationstrftimer   r  upperr  appendr   loggerwarningextendr   r   r   r   score_totalsetStyler   COLOR_BG_HEADERr   r   rangelenSCORE_MAP_CONFIGr   r   r   r   COLOR_BG_CARDr   MAX_PRECONISATIONSMAX_TITLE_LENGTHMAX_TEXT_LENGTHr   COLOR_BORDERSTRUCTURE_QUESTIONSr   CHAMPS_DETAILSbuildseekinfoerrorr   )Srapportscores_blocspreconisationsdonnees_formulairer  rb  r  uidr  ownerbufferr  storys_titre_gross_sous_titre	s_sections_h3s_normals_labels_q_cells_r_cellRLImagedate_strshort_idauthorr  header_itemslogo_imge
col_gauchegauge
tbl_banner	label_mapr   	rows_datarV  	row_cellsjr   r   nommax_ptsval_inttxt_valbarr   c_sctop_linet_cellt_gridmsgpreconisations_limiteesr   rP  rR  rS  borderbgiconheadcard	nb_postesnb_critiques_pnb_serveursnb_critiques_sr   volumetrie_datarows_volqrt_vol	categorie	questionsrowsq_keyq_label	val_bruteval_lisible
detail_key
detail_valt_catr]  r  sS                                                                                     @r   generer_pdf_rapportr  F  sr   !/0BCC((((((w1oNNNJ4$4z
|VR00lD$//6>>go44!"89999C!7!7######JNN7?33EWE,33BWZ    YYF
FRSVPSTVPVbcdfbfuvwyuy  BY  MW  BY  BY  Z  Z  ZCE "$1ABZ`ZfprsssL!$rUanpqqqLt.>W]Wcqs  AC  D  D  DI$)9BR^ln{|}}}DcK"PXYbPcPcmopppHS+;aS[\eSfSf  wB  C  C  CGd[1PXYbPcPcdddHd-=U[UamuvvvH
 433333=D=R]w$--j999X]H7:rr"((**H Z^^GO,,F7=^mF333C^I| L  B	BwyBs2vN[[[H
+++1//// 	B 	B 	BNN@Q@@AAAAAAAA	B 	*G	4	45	:##%%|	4	45	1	6X66H66	E	EF	FFFF	Q	QR    |2w777Jx 344CLLLE U+,B"FFFJ
	ug7,)'	w8I#6#67$      
LL	LL3r6""###
 
LL0)<<===// 	, 	"#:	
 	"#8 	' 	8 	 	K 	m 	m 	* 	& 	? 	0  	)!" 	*#I( ##%%&&EI1c%jj!$$ $ $	q 	% 	%A1us5zz!!"1Q3Z
UmmC--*..sA66-2->(5///A6;6GW22222U&%2CwwY`hklll+2Q;;5;Lg''RS(+s

}}kpk|#QT**ZfZf  CK  LU  CV  CV 9S.PQ]efo]p]p2q2q2q#r#rt}  R  EL  R  R  R  Tb  cg  rs  C  OW  TX  TX  TX  uY  uY  #Z  "[  hk  mo  gp  q  q  q
SE2seDDD
\5'=,Y[y  }H  JO  QX  Z[  ]j  |k  ,l  !m  !m  n  n  n  ((((  $$$$#### yQrT1R4L999
  $R  $R  $R  S  S  	T  	T  	TV	LL1R4!!! 
LL?I66777 ,i NPXYYZ[hjkmhmgnoooZ,w@S@S!TW\^celnoq~V  Ba  !b  c  c  	d  	d  	dS"01D2D1D"E~!333LL  $\-  $\  $\Tf  $\  $\  $\  ^f  g  g  h  h  hLL3r6**+++( 	, 	,A#AEE)Y$?$?BOOOG!!%%">">K[\\\E#AEE)R$8$8_UUUG*$$xPYGZGZ\a$bffJ&&=(S\J]J]_bD%18I3F3Fd"&9%YF%Y%Y%Y%Y%Y[cddfo  qBv{  qB  qB  qB  DR  SW  bd  pv  p|  D}  D}  D}  g~  g~  @I  Jz  Y_  Jz  Jz  bi  bo  bo  bq  bq  Jz  Jz  Jz  |J  KO  Z[  go  |p  |p  |p  @q  @q  r  s  @A  BD  @D  FH  IK  FK  MN  OQ  MQ  R  S  S  SD4&9Wh#?#?"@AbQSeWUUUDMM*|UE2&FW\^egtHux}  @E  GN  PS  U[  x\  ^}  @K  MR  TY  [^  `f  g  &h  i  i  j  j  jLLLL3r6**++++ 
LL	LLBINNOOO/334EqIIJJXVhVlVl  nC  EF  WG  WG  NH  NH  H	!"4"8"89NPQ"R"RSS1556MqQQRRU]^p^t^t  vL  NO  _P  _P  VQ  VQ  Q!"4"8"89PRS"T"TUU.22<AQRR_abbb   <<<===		 
%c)nn5	 #n"5"56	S--.	"C$7$78	%s+O H J J11h//1h1G1GHIIII(r"uadm444E	NN:eWmLuV[]dfikwNx  |G  IN  PW  Y]  _k  {l  nL  M  N  N  O  O  O	LL/66777	LL	LL3r6""### !4 9 9 ; ; , ,	9' 	i 	iNE7*..u55I 0	::K (++E22J S*+=+A+A*b+Q+Q^`aaa
 S#Rj#R#R#RRKKK=#9#98DDiP[]eFfFfghhhh 	,LL=#;#;TBBCCC$2b5!B$-888ENN:eWm'TW\^celnqs  WA  DO  QV  X_  ae  gs  Ct  vT  'U  V  V  W  W  WLLLL3r6**+++I	7 	7 	7 	7 	7 			%%9H\	]]]AKwzKKLLL I I I'A''$777@AAqHIsa   BC 
CC.AL 
L9L44L9C9p; ;
q2#q--q24A
 

A@/A@@A@)r   )r   )r   r   )@reportlab.lib.pagesizesr   reportlab.lib.stylesr   r   reportlab.lib.unitsr   r   reportlab.lib.enumsr   r	   r
   r   rk  r   r   r   r   r   r   r   reportlab.libr   reportlab.lib.colorsr   ior   r   r   loggingr  flaskr   	getLoggerr   rp  r   ru  ry  r}  r   
COLOR_TEXTr   r   r   r   rz  r|  r{  rc  rx  r~  r  r   r   r   r   r   r   r   r   r  r  r  r   r   r   <module>r     s   ' & & & & & D D D D D D D D & & & & & & & & H H H H H H H H H H H H k k k k k k k k k k k k k k k k k k             ) ) ) ) ) )        				  				      		8	$	$
 (9%%(9%%(9%%(9%%(9%%(9%%
(9%%######   "',8!=VXYr#0!5GLZ\]  0 5I! a	 &q	
 q
 -a
 2B1
 GUVW     # # # 	*8"  /  @ 120(,,$	 	,	,"N,4=, 
, %&8, +	, .>?U	,
 
=,
 &'<, 6, ^, 
=, ', 
, %,  -!," %#, ,$ %%,* =+,, N-,. /,2 
3,4 .5,: ';,< 2=,>  ?,B 1C,D 5E,F  G,H )I,J )K,L =M,N hO,P hQ, ,R +$W, , ,d      
 $3      6Z Z Z,!! !! !! !! !! !! !! !!FT T T T Tx T T T4
 
 
 
$ $ $LoI oI oI oI oI oIr   