
    _i_                        d dl mZmZmZmZmZmZmZmZ d dl	m
Z
mZ d dlZd dlZd dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlmZmZ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# d dlmZmZm$Z$  ede%dd          Z&d2dZ'd Z(d Z)d Z*d Z+e&,                    d          e
 e#ddg          d                                     Z-e&,                    dddg          e
 e#ddg           e!j.        d          d                                                 Z/e&,                    d           e
 e#ddg          d!                                     Z0e&,                    d"dg          e
 e#ddg           e!j.        d          d#                                                 Z1e&,                    d$dg          e
 e#ddg           e!j.        d          d%                                                 Z2e&,                    d&dg          e
 e#ddg           e!j.        d          d'                                                 Z3e&,                    d(dg          e
 e#ddg          d)                                     Z4e&,                    d*          e
 e#d          d+                                     Z5e&,                    d,dg          e
 e#d          d-                                     Z6e&,                    d.dg          e
 e#d          d/                                     Z7e&,                    d0          e
 e#ddg          d1                                     Z8dS )3    )	Blueprintrender_templaterequestredirecturl_forflashcurrent_appabort)login_requiredcurrent_userN)Message)IntegrityError)
joinedload)func)datetimetimezone	timedelta)UserRapport)dbbcryptmaillimiter)role_required)r   r   AuditLogmanagerz/managerz../templates)
url_prefixtemplate_folder    c                    t           j        t           j        z   dz   d                    fdt	          |           D                       }t          d |D                       rKt          d |D                       r2t          d |D                       rt          d |D                       st          |           S |S )N!@#$%^&* c              3   @   K   | ]}t          j                  V  d S N)secretschoice).0_charss     5/var/www/html/MCyber-Diagnostic/blueprints/manager.py	<genexpr>z+generate_random_password.<locals>.<genexpr>   s-      DDw~e,,DDDDDD    c              3   >   K   | ]}|                                 V  d S r$   )isupperr'   cs     r*   r+   z+generate_random_password.<locals>.<genexpr>   *      ..		......r,   c              3   >   K   | ]}|                                 V  d S r$   )islowerr/   s     r*   r+   z+generate_random_password.<locals>.<genexpr>   r1   r,   c              3   >   K   | ]}|                                 V  d S r$   )isdigitr/   s     r*   r+   z+generate_random_password.<locals>.<genexpr>   r1   r,   c              3      K   | ]}|d v V  	dS )r!   N r/   s     r*   r+   z+generate_random_password.<locals>.<genexpr>    s&      22AZ222222r,   )stringascii_lettersdigitsjoinrangeanygenerate_random_password)lengthpasswordr)   s     @r*   r>   r>      s     6=0:=EwwDDDDeFmmDDDDDH..X..... 0..X.....0..X.....0 22222220 (///Or,   c                 4    d}t          j        ||           d uS )Nz0^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)rematch)emailpatterns     r*   validate_email_formatrF   $   s    AG8GU##4//r,   c                    	 |                      dt          t          j        d                             }t	          d| j        g          }t          d|d          }d	| j        pd
 d| j         d| d|_        t          j
        |           dS # t          $ r7}t          j                            d| j         d| d           Y d}~dS d}~ww xY w)z+Envoie l'email de bienvenue au Client FinalQ 
SECRET_KEYexpires_sec
secret_keyz7Bienvenue sur MCyber Audit - Activation de votre compte
recipientsauth.reset_passwordTtoken	_externalut   Bonjour,

Votre partenaire de sécurité vous invite sur le Portail MCyber Audit.

📋 VOS ACCÈS :
- Entreprise : u   Non renseignéez
- Identifiant : uT   

🔐 Pour définir votre mot de passe et accéder à la plateforme, cliquez ici :
uY   

Ce lien est sécurisé et valide 24 heures.

Cordialement,
L'équipe MCyber Consulting
u!   Erreur envoi email invitation à : exc_infoNF)get_reset_tokenstrr	   configr   rD   r   company_namebodyr   send	Exceptionloggererror)userrQ   msg	reset_urles        r*   send_new_client_emailrc   (   s   $$3{GYZfGgChCh$iiO]a]g\hiii1$OOO	
 !6%6        		#t     !VTZ!V!VST!V!Vae fffuuuuus   BB 
C,CCc                    	 |                      dt          t          j        d                             }t	          d| j        g          }t          d|d          }d	| j         d
| d|_        t          j	        |           dS # t          $ r7}t          j                            d| j         d| d           Y d}~dS d}~ww xY w)uJ   Envoie l'email d'invitation à un membre de l'équipe (Manager secondaire)rH   rI   rJ   u!   Invitation équipe - MCyber AuditrM   rO   TrP   u   Bonjour,

L'administrateur de votre compte MCyber Audit vous a ajouté à l'équipe.

📋 VOS ACCÈS MANAGER :
- Identifiant : u[   
- Rôle : Membre d'équipe

🔐 Cliquez ici pour définir votre mot de passe personnel :
uK   

Ce lien est valide 24 heures.

Cordialement,
L'équipe MCyber Consulting
u   Erreur envoi email team à rS   rT   NF)rV   rW   r	   rX   r   rD   r   rZ   r   r[   r\   r]   r^   )r_   temp_passwordrQ   r`   ra   rb   s         r*   send_team_invitation_emailrf   E   s    $$3{GYZfGgChCh$ii9tzlSSS1$OOO	
       		#t     !Ptz!P!PQ!P!P[_ ```uuuuus   BB 
C	,CC	c                    t           j                            |                               t	          t           j                                                            }d |D             }g }|D ]}t          |j        d d          }|r|d         nd}d}|r	 t          j	        t          j                  }|j        }	|	j         |	                    t          j                  }	||	z
  j        }nA# t           $ r4}
t"          j                            d	|j         d
|
            Y d}
~
nd}
~
ww xY w|                    |t-          |j                  |r|j        nd|d           t          j	        t          j                  t/          d          z
  }d}|r]t0          j                            t0          j                            |          t0          j        |k                                              }d}d}|r.t:          j                            t0          j        t?          j        t0          j                                       d                                        t0          j                            |                    !                    t0          j                  "                    t?          j        t0          j                  #                                          $                                }|r3|\  }tK          fd|D             d          }|r|j&        p|j'        }|}tQ          d |D                       }t          j	                    tQ          fd|D                       }|t-          |          |||||ddS )u7   Retourne les données consolidées pour la Console MSP.
manager_idc                     g | ]	}|j         
S r7   idr/   s     r*   
<listcomp>z&get_msp_fleet_data.<locals>.<listcomp>f   s    (((1!$(((r,   c                     | j         S r$   )date_creation)rs    r*   <lambda>z$get_msp_fleet_data.<locals>.<lambda>k   s    q r,   T)keyreverser   NtzinfozDate warning for report rS   r_   nb_rapportslast_report_datedays_since_audit   daysAucuntotalc              3   2   K   | ]}|j         k    |V  d S r$   rk   )r'   r0   user_ids     r*   r+   z%get_msp_fleet_data.<locals>.<genexpr>   s)      !H!H!!H!Hr,   c              3   >   K   | ]}t          |j                  V  d S r$   )lenrapportsr/   s     r*   r+   z%get_msp_fleet_data.<locals>.<genexpr>   s*      881s1:888888r,   c              3   h   K   | ],}|j         	|j                             d           k     (dV  -d S )Nrt      )engagement_end_datereplace)r'   r0   nows     r*   r+   z%get_msp_fleet_data.<locals>.<genexpr>   sK      {{0E{!J_JgJgosJgJtJtwzJzJz!JzJzJzJz{{r,   )total_clientstotal_audits_clientsaudits_this_monthtop_user_nametop_user_countclients_expired)clients_datastats))r   query	filter_byoptionsr   r   allsortedr   r   r   utcro   ru   r   r|   r\   r	   r]   warningrl   appendr   r   r   filterr   in_countr   sessionr   labelgroup_byorder_bydescfirstnextrY   rD   sum)ri   clients
client_idsclients_data_listclientsorted_reportslast_report
days_sincenow_utcreport_daterb   thirty_days_agor   r   r   champion_datar~   champion_usertotal_auditsr   r   r   s                       @@r*   get_msp_fleet_datar   b   s;    j""j"99AA*T]B[B[\\``bbG(((((J  @ @5N5NX\]]]+9CnQ''t
 	]]",x|44)7%-"-"5"5X\"5"J"JK%39

 ] ] ]"**+[kn+[+[XY+[+[\\\\\\\\] 	  &V_AUAU  IT  l^kv  lE  lE  Z^  t~  "  "  	@  	@  	@  	@ l8<009"3E3E3EEO D#M001D1DZ1P1PRYRgkzRz{{  B  B  D  D MN '
(($*WZ:P:P:V:VW^:_:_``gghohwh{h{  }G  iH  iH  I  I  R  R  SZ  Sb  c  c  l  l  mq  mw  x  xB  mC  mC  mH  mH  mJ  mJ  K  K  Q  Q  S  S 	'*NGU !H!H!H!HW!H!H!H$OOM ' - : Qm>Q!& 8888888L ,..C{{{{W{{{{{O-#g,,p|  Te  xE  Yg  |K  9L  9L  M  M  Ms   AC11
D/;*D**D/z
/dashboardadminc            
      r
   	 t           j                            ddt                    } t           j                            dd          }t           j                            dd                                          }d}t
          j        }t          j        	                    |	          }|rZ|
                    t          j                            d
| d
          t          j                            d
| d
          z            }|dk    r2|                    t          j                                                  }n|dk    ry|                    t"                                        t          j                                      t)          j        t"          j                                                            }n1|                    t          j                                                  }|                    | |d          }g }|j        D ](}t"          j        	                    |j                                      t"          j                                                                                  }	t"          j        	                    |j                                                  }
d }|	rat9          j        t<          j                  }|	j        j         &|	j        !                    t<          j                  }n|	j        }||z
  j"        }|#                    ||
|	r|	j        nd |d           *t          j        	                    |	                                          }d t          j        	                    |	          $                    t          j                  %                                D             }d}d}|rt"          j        
                    t"          j&        '                    |                                                    }t9          j        t<          j                  tQ          d          z
  }t"          j        
                    t"          j&        '                    |          t"          j        |k                                              }|||d dd}tS          d|||||t9          j                              S # tT          $ rZ}tV          j,        -                    d| d           t]          dd           t_          ta          d                    cY d }~S d }~ww xY w)Npager   typesortdatesearchr"   
   rh   %namereportsFr   per_page	error_outr   rt   rv   c                     g | ]	}|j         
S r7   rk   r/   s     r*   rm   z%manager_dashboard.<locals>.<listcomp>   s    ppp1!$pppr,   r   rz   r{   )r   r   r   r   r   zmanager_dashboard.html)r   r   
paginationcurrent_sortcurrent_searchr   zErreur Dashboard MSP: TrT   u,   ❌ Erreur lors du chargement de la console.dangerzmain.dashboard)1r   argsgetintstripr   owner_idr   r   r   r   rY   ilikerD   r   asc	outerjoinr   r   rl   r   r   r   
created_atpaginateitemsro   r   r   r   r   r   ru   r   r|   r   with_entitiesr   r   r   r   r   r\   r	   r]   r^   r   r   r   )r   sort_byr   r   	target_idr   r   r   r   r   report_countr   r   r   r   all_client_idsr   r   r   r   rb   s                        r*   manager_dashboardr      s   Q3|44,""6622!!(B//5577 )	 
$$	$::  	LL"((V77!!-f---002 E fNN4#4#8#8#:#:;;EE	!!OOG,,55dg>>GG
SZS]H^H^HcHcHeHeffEENN4?#7#7#9#9::E ^^E^RR
  & 	 	F!-11&)1DDMMgNcNhNhNjNjkkqqssK"=22692EEKKMMLJ :",x|44,3;"-";"C"C8<"C"X"XKK"-";K%39
+AL$VK$=$=RV$.	! !     
,,	,BBHHJJpp
(<(<	(<(R(R(`(`aeah(i(i(m(m(o(oppp 	L"=//0C0CN0S0STTZZ\\L&l8<889";M;M;MMO ' 4 4W_5H5H5X5XZaZo  tC  [C  !D  !D  !J  !J  !L  !L +$0!2!
 
 7#(*6(2*1,2!)1 1 1 	1  3 3 3  !=!!=!= MMM<hGGG 011222222223s   SS 
T6AT1+T61T6z/new_clientGETPOST)methodsz100 per hourc            
      p   t           j        dk    rt           j                            dd                                                                          } t           j                            dd                                          }| r|st          dd           t          d          S t          |           st          dd           t          d          S t          |          d	k    rt          d
d           t          d          S t          j                            |                                           r#t          d|  dd           t          d          S t          d          }t          j        |                              d          }t          | |d|t$          j        dd          }	 t(          j                            |           t(          j                                         t0          j                            dt$          j         d|  d| dt           j                    t;          |          rt          d| dd           nt          dd           t=          t?          d                    S # t@          $ r5 t(          j        !                                 t          d|  dd           Y nhtD          $ r\}t(          j        !                                 t0          j        #                    d| d           t          dd           Y d }~nd }~ww xY wt          d          S ) Nr   rD   r"   
nom_clientu    ❌ Tous les champs sont requis.r   zmanager_new_client.htmlu   ❌ Format d'email invalide.   u   ❌ Nom client trop long.rD   u   ❌ L'email u    est déjà utilisé.r   r   utf-8r_   T)rD   r@   rolerY   ri   	can_auditis_active_accountu   ➕ Manager u    crée client z (z) | IP:    ✅ Client u    créé et invité par email.successu(   ⚠️ Client créé, mais erreur email.manager.manager_dashboardu   Erreur création client: rT      ❌ Erreur technique.)$r   methodformr   r   lowerr   r   rF   r   r   r   r   r   r>   r   generate_password_hashdecoder   r   r   r   addcommitr	   r]   inforD   remote_addrrc   r   r   r   rollbackr\   r^   )rD   r   re   hashed_passwordnew_userrb   s         r*   manager_new_clientr      s`   
 ~  "--3355;;==\%%lB77==??
 	>J 	>4h???"#<===$U++ 	>0(;;;"#<===z??S  -x888"#<===:e,,2244 	>====yIII"#<===044 7FFMMgVV $##,"
 
 
	5JNN8$$$J##  %H<3E  %H  %HUZ  %H  %H^h  %H  %Hry  sF  %H  %H  I  I  I$X.. NMJMMMyYYYYA9MMMG$?@@AAA 	I 	I 	IJ!!!====xHHHHH 	5 	5 	5J!!!$$%D%D%Dt$TTT)844444444	5
 4555s    7CJ <L&	L&
AL!!L&z#/client/<string:client_id>/rapportsc           	         t           j                            |           }t          j        dk    ru|j        t          j        k    r`t          j        	                    dt          j
         d|j
                    t          dd           t          t          d                    S t          j                            ddt"          	          }t          j                            d
d                                          }d}t&          j                            |           }|r6|                    t&          j                            d| d                    }|                    t&          j                                                                      ||d          }t9          d||j        ||t=          j                              S )Nr   u0   ⚠️ Tentative accès non autorisé : Manager u    → Client u   ❌ Accès non autorisé.r   r   r   r   r   r   r"   r   r   r   Fr   zmanager_client_rapports.html)r   r   r   r   r   ) r   r   
get_or_404r   r   ri   r   r	   r]   r   rD   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ro   r   r   r   r   r   r   )	client_idr   r   r   r   r   r   s          r*   client_rapportsr   )  s    Z""9--F I%%&*;|?T*T*T""  $EVbVh  $E  $Ev|  wC  $E  $E  	F  	F  	F)8444 ;<<=== <FAC00D\h++1133FH M##I#66E  FW/55m&mmmDDEE  5 : : < <==xTHxNN  9"($.$4&0*0'|~~/ / / /r,   z(/client/<string:client_id>/toggle_accessc                 :   t           j                            |           }t          j        dk    rA|j        t          j        k    r,t          dd           t          t          d                    S |j
         |_
        |j
        rdnd}t          j                                         t          j                            dt          j         d| d	|j                    t          d
|j         d| dd           t          t          d|j                            S )Nr      ❌ Action non autorisée.r   r   u
   réactivésuspenduu   🔒 Manager  a z le compte u   ✅ Le compte de u	    a été .r   manager.client_rapportsr   )r   r   r   r   r   ri   r   r   r   r   r   r   r   r   r	   r]   r   rD   rY   rl   r   r   actions      r*   toggle_client_accessr  P  s   
 Z""9--FI%%&*;|?T*T*T*H555 ;<<===#)#;;F#5E\\:FJg|/AggfggY_Yegghhh	
Ef1
E
EF
E
E
EyQQQG5KKKLLLr,   z'/client/<string:client_id>/toggle_auditc                 *   t           j                            |           }t          j        dk    rA|j        t          j        k    r,t          dd           t          t          d                    S |j
         |_
        |j
        rdnd}t          j                                         t          j                            dt          j         d| d	|j                    t          d
| dd           t          t          d|j                            S )Nr   r   r   r   u
   autoriséeu   bloquéeu   📝 Manager r   u    la création d'audit pour u   ✅ La création d'audit est r   r   r   r   )r   r   r   r   r   ri   r   r   r   r   r   r   r   r   r	   r]   r   rD   rl   r   s      r*   toggle_audit_permissionr  b  s   
 Z""9--FI%%&*;|?T*T*T*H555 ;<<===!++F#-=\\:FJtL,>tt6ttflfrttuuu	
3&
3
3
3Y???G5KKKLLLr,   z!/client/<string:client_id>/deletec                 H   t           j                            |           }t          j        dk    rA|j        t          j        k    r,t          dd           t          t          d                    S |j
        }t          j                            dt          j
         d|            	 t          j                            |           t          j                                         t          d| dd	           t          t          d                    S # t$          $ r}t          j                                         t          j                            d
|  d| d           t          dd           t          t          d|j                            cY d }~S d }~ww xY w)Nr   r   r   r   u   🗑️ Manager z supprime client r   u    supprimé définitivement.r   zErreur suppression client rS   TrT   r   r   r   )r   r   r   r   r   ri   r   r   r   r   rD   r	   r]   r   r   r   deleter   r\   r   r^   rl   )r   r   client_emailrb   s       r*   delete_clientr  t  s   
 Z""9--FI%%&*;|?T*T*T*H555 ;<<===<Le,2DeeWceefff	Q

&!!!

ELEEEyQQQ ;<<=== Q Q Q

  !Ni!N!N1!N!NY] ^^^%x000 9VYOOOPPPPPPPP	Qs    (A,D 
F!A7FF!F!z,/client/<string:client_id>/update_engagementc                 <   t           j                            |           }t          j        dk    rA|j        t          j        k    r,t          dd           t          t          d                    S t          j                            dd                                          }|r	 t          j        |d          |_        t"          j                                         t(          j                            dt          j         d	|j         d
|            t          dd           nU# t0          $ r t          dd           Y n9w xY wd |_        t"          j                                         t          dd           t          t          d|j                            S )Nr   r   r   r   engagement_dater"   z%Y-%m-%du   📅 Manager z modifie engagement pour rS   u#   ✅ Date d'engagement mise à jour.r   u   ❌ Format de date invalide.r   u!   ✅ Date d'engagement supprimée.r   r   r   )r   r   r   r   r   ri   r   r   r   r   r   r   r   r   r   strptimer   r   r   r   r	   r]   r   rD   
ValueErrorrl   )r   r   date_strs      r*   update_client_engagementr    s    Z""9--FI%%&*;|?T*T*T*H555 ;<<===| 1266<<>>H ;	=)1):8Z)P)PF&J##${L4F${${agam${${qy${${|||7CCCC 	= 	= 	=0)<<<<<	= &*"

16:::G5KKKLLLs   &A?D& &EEz/teamc                     t           j        r,t          dd           t          t	          d                    S t
          j                            t           j                  	                                } t          d|           S )u)   Affiche la liste des membres de l'équipeu@   ❌ Seul le titulaire principal du compte peut gérer l'équipe.r   r   )	parent_idzmanager_team.htmlmembers)r   r  r   r   r   r   r   r   rl   r   r   r  s    r*   manage_teamr    st      >PR[\\\ ;<<=== j""\_"==AACCG.@@@@r,   z	/team/addc            	         t           j        r,t          dd           t          t	          d                    S t
          j                            dd                                          	                                } t
          j                            dd                                          }| s,t          dd           t          t	          d                    S t          j                            | 	                                          r,t          d
d           t          t	          d                    S t          d          }t          j        |                              d          }t          | |dt           j        |p|                     d          d         dd          }	 t(          j                            |           t(          j                                         t1          ||          rt          d|  dd           nt          dd           t2          j                            dt           j         d|             ni# t:          $ r\}t(          j                                         t2          j                            d| d           t          dd           Y d}~nd}~ww xY wt          t	          d                    S )zAjouter un collaborateur   Action non autorisée.r   r   rD   r"   r   zL'email est requis.manager.manage_teamr   u   Cet email est déjà utilisé.   r   r   @r   Tr   )rD   r@   r   r  rY   r   max_concurrent_sessionsu   ✅ Invitation envoyée à r   r   u6   ⚠️ Utilisateur créé mais erreur d'envoi d'email.r      👥 Manager z ajoute membre zErreur ajout team member: rT   z!Erreur technique lors de l'ajout.N) r   r  r   r   r   r   r   r   r   r   r   r   r   r   r>   r   r   r   rl   splitr   r   r   r   rf   r	   r]   r   rD   r\   r   r^   )rD   nomre   	hashed_pw
new_memberrb   s         r*   add_team_memberr    s     >&111 ;<<===LWb))//117799E
,

62
&
&
,
,
.
.C 8#X... 566777z%((..00 8.999 566777 -R00M-m<<CCGLLI //EKK,,Q/ !  J=

z"""

 &j-@@ 	X8888)DDDDKYWWW Z0B Z ZSX Z Z[[[[ = = =

  !Aa!A!AD QQQ18<<<<<<<<=
 G122333s   -B!I 
J5AJ00J5z/team/delete/<string:member_id>c                    t           j        rt          d           t          j                            |           }|j        t           j        k    r,t          dd           t          t          d                    S 	 |j
        }t          j                            |           t          j                                         t          d| dd           t          j                            dt           j
         d	|            ng# t$          $ rZ}t          j                                         t          j                            d
|            t          dd           Y d}~nd}~ww xY wt          t          d                    S )zSupprimer un collaborateuri  r  r   r  u   ✅ Membre u    supprimé.r   r  z supprime membre z Erreur suppression team member: zErreur lors de la suppression.N)r   r  r
   r   r   r   rl   r   r   r   rD   r   r   r  r   r	   r]   r   r\   r   r^   )	member_idmemberrD   rb   s       r*   delete_team_memberr"    sv     c


Z""9--F <?**&111 566777	:

&!!!

.E...	::: \0B \ \UZ \ \]]]] : : :

  !GA!G!GHHH.99999999:
 G122333s   =BD 
E)AE$$E)z/logsc                     t           j        } d t          j                            t          j        | k    t          j        | k    z                                            D             }d t          j                            |                                           D             }||z   }t          j
                            ddt                    }t          j
                            dd          }t          j
                            d	d
          }t          j
                            dd                                          }t          j                            t          j                            |          t          j                            ddg                    }|d
k    rtt          |                    d                    }	t'          j        t*          j                  t/          |	          z
  }
|                    t          j        |
k              }|d
k    r5|                    t          j        |                                k              }|rN|                    t                                        t          j                            d| d                    }|                    t          j                                                                       |dd          }tC          d|j"        ||||          S )uS   Affiche les logs d'activité de toute l'organisation du manager (Équipe + Clients)c                     g | ]	}|j         
S r7   rk   r'   us     r*   rm   z!activity_logs.<locals>.<listcomp>#  s    llllllr,   c                     g | ]	}|j         
S r7   rk   r%  s     r*   rm   z!activity_logs.<locals>.<listcomp>$  s    PPP1!$PPPr,   rh   r   r   r   period7dcategoryr   r_   r"   INFOWARNINGdr{   r      Fr   zmanager_logs.html)logsr   r(  r*  user_search)#r   r   r   r   r   rl   r  r   r   r   r   r   r   r   r   r   r   levelrstripr   r   r   r   r   	timestampr*  upperr;   rD   r   r   r   r   r   r   )r   team_idsr   allowed_user_idsr   r(  r*  r0  r   r|   cutoffr   s               r*   activity_logsr8    s|    $H mldj//H1D[cIc0deeiikklllHPP
 4 4 4 I I M M O OPPPJ  *, <FAC00D\h--F|
E22H,""62..4466K N!!-..FI.// E 6==%%&&hl++iT.B.B.BBX/69::5X.(..2B2BBCC N

4  ''
(8(89K[9K9K9K(L(LMM  2 7 7 9 9::xTB%xHH     r,   )r   )9flaskr   r   r   r   r   r   r	   r
   flask_loginr   r   r%   r8   rB   
flask_mailr   sqlalchemy.excr   sqlalchemy.ormr   
sqlalchemyr   r   r   r   modelsr   r   
extensionsr   r   r   r   
decoratorsr   r   __name__r   r>   rF   rc   rf   r   router   limitr   r   r  r  r  r  r  r  r"  r8  r7   r,   r*   <module>rE     s   d c c c c c c c c c c c c c c c c c c c 4 4 4 4 4 4 4 4   				       ) ) ) ) ) ) % % % % % %       2 2 2 2 2 2 2 2 2 2 !               0 0 0 0 0 0 0 0 0 0 0 0 $ $ $ $ $ $ * * * * * * * * * *
)IxJP^
_
_
_   0 0 0  :  :1M 1M 1Mn 	|	7#$$R3 R3 %$  R3h 	}ufo66	7#$$~26 26  %$  7626j 	455	7#$$/ / %$  65/H 	9F8LL	7#$$~M M  %$  MLM 	86(KK	7#$$~M M  %$  LKM 	2VHEE	7#$$~Q Q  %$  FEQ* 	=xPP	7#$$M M %$  QPM6 	wyA A   A 	{VH--y34 34   .-34j 	06(CCy4 4   DC4> 	w	7#$$5 5 %$  5 5 5r,   