
    i`                        d dl mZ d dlmZmZmZmZmZmZ d dl	m
Z
 d dlmZmZ d dlmZ d dlmZmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZmZ d dlm Z  d dl!m"Z"m#Z# d dl$m%Z%m&Z& d dl'm(Z( d dl)m*Z*m+Z+ d dl,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2 d dl3m4Z4m5Z5m6Z6 d dl7m8Z8m9Z9m:Z: d dl;m<Z< d dl=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZE d dlFmGZGmHZH d dlImJZJmKZKmLZL d dlMmNZN d dlOmPZPmQZQmRZR d dlSmTZTmUZUmVZVmWZWmXZXmYZYmZZZ d dl[m\Z\m]Z]m^Z^ d dl_m`Z` d dlambZbmcZcmdZdmeZemfZfmgZgmhZhmiZimjZjmkZk  e       Zldemdz  d e d!emfd"Znd#e8e:z  d!eoepeqf   fd$Zrd%epd!epfd&Zsd#e4e6z  d!eoepeqf   fd'Ztelj                  d(      d!eoepepf   fd)       Zvelj                  d*ewe<   +       ee      fd e d!ewe    fd,       Zxelj                  d-ewe5   +      d ee       ee      fd.emdz  d/ed e d!ewe5   fd0       Zyelj                  d-e5ej                  1       ee       ee      fd#e4d/ed e d!e5fd2       Z|elj                  d3e5+       ee       ee      fd4emd#e6d/ed e d!e5f
d5       Z~elj                  d6e5+       ee       ee      fd4emd/ed e d!e5fd7       Zelj                  d8e"+      d ee       ee      fd.emdz  d/ed e d!e"fd9       Zelj                  d:e++       ee      fd#e*d/ed!e+fd;       Zelj                  d<e"+       ee       ee      fd.emd#e#d/ed e d!e"f
d=       Zelj                  d>ewe9   +      d ee       ee      fd4emdz  d/ed e d!ewe9   fd?       Zelj                  d>e9ej                  1       ee       ee      fd#e8d/ed e d!e9fd@       Zelj                  dAe9+       ee       ee      fdBemd#e:d/ed e d!e9f
dC       Zelj                  dA       ee       ee      fdBemd/ed e d!eoepeqf   fdD       Zelj                  dEewe&   +       ee       ee      fd/ed e d!ewe   fdF       Zelj                  dEe&ej                  1       ee      fd#e%d/ed!efdG       Zelj                  dHe0+       edI       eddJK       ee       ee      fdLedz  dMedz  d/ed e d!e0f
dN       Zelj                  dHe1ej                  1       ee       ee      fd#e/d/ed e d!e1fdO       Zelj                  dPe1+       ee       ee      fdQemd/ed e d!e1fdR       Zelj                  dPe1+       ee       ee      fdQemd#e2d/ed e d!e1f
dS       Zelj                  dP       ee       ee      fdQemd/ed e d!eoepeqf   fdT       Zelj                  dUe-+       ee       ee      fdQemd/ed e d!e-fdV       Zelj                  dW       ee       ee      fd#e.d/ed e d!eofdX       Zelj                  dYe(+       edZ       edZ       ee       ee      fd[ed4emd/ed e d!e(f
d\       Zelj                  d]       ee      fd/ed!eofd^       Zelj                  d_eD+       ee       ee      fd/ed e d!eDfd`       Zelj                  dae?+       ee       ee      fd/ed e d!e?fdb       Zelj                  dceC+       ee       ee      fd#eBd/ed e d!eCfdd       Zelj                  deeweA   +       edfdgdhi       ee       ee      fdjemd/ed e d!eweA   fdk       Zelj                  dlewe@   +       edmdgdni       ee       ee      fdjemd/ed e d!ewe@   fdo       Zelj                  dpewe>   +       edqdgdhi       ee       ee      fdrepdjemd/ed e d!ewe>   f
ds       Zelj                  dtduv      dwed!e
fdx       Zelj                  dteEduy       ee      fdwed/ed!eEfdz       Zy){    )date)	APIRouterDependsHTTPExceptionQueryRequeststatus)PlainTextResponse)or_select)Session)get_current_venueget_db)get_settings)Customer)ReservationReservationStatus)Room)TableTableCombination)Venue)VenueBookingSettingsReadVenueBookingSettingsUpdate)CustomerCreateCustomerRead)FloorPlanResponse)PortalContextSyncRequestPortalContextSyncResponse)AssignmentResultRecalculateDayRequestReservationCreateReservationListResponseReservationReadReservationUpdate)
RoomCreateRoomRead
RoomUpdate)TableCreate	TableReadTableUpdate)	VenueRead)WhatsAppAssistantTurnRead WhatsAppConfigValidationResponseWhatsAppConversationSummaryReadWhatsAppEventLogReadWhatsAppSendTestRequestWhatsAppSendTestResponseWhatsAppStatusResponseWhatsAppWebhookAck)recalculate_day_assignmentsreassign_single_reservation)get_booking_settingsserialize_booking_settingsupdate_booking_settings)build_floor_plan)meters_to_unitsserialize_roomserialize_table)create_reservationdelete_reservationget_default_roomget_reservation_or_404list_reservationsserialize_reservationupdate_reservation)ensure_room_for_venuereset_room_layoutseed_demo_data)sync_venue_name_from_portal)
get_whatsapp_statuslist_whatsapp_assistant_turnslist_whatsapp_conversationslist_whatsapp_logsparse_webhook_bodyprocess_webhook_payloadsend_test_whatsapp_messageverify_webhook_handshakevalidate_webhook_signaturevalidate_whatsapp_configrequested_venue_idNcurrent_venuereturnc                 v    | |j                   S | |j                   k7  rt        t        j                  d      | S )Nz'Locale non trovato per il tenant attivostatus_codedetail)idr   r	   HTTP_404_NOT_FOUND)rR   rS   s     )PRENOTAZIONI_IA/backend/app/api/routes.pyensure_current_venue_matchesr\   L   s<    !]---(A(AJstt    payloadc                    | j                   j                         }|st        t        j                  d      | j
                  |t        | j                  d      t        | j                  d      t        | j                        t        | j                        | j                  t        | j                  d      | j                  | j                  | j                   | j"                  dS )NzNome tavolo obbligatoriorV   T
allow_zero   )room_idnamexywidthheightshaperotation_degrees	min_seats	max_seats
join_group	is_active)rd   stripr   r	   HTTP_422_UNPROCESSABLE_ENTITYrc   r:   re   rf   rg   rh   ri   roundrj   rk   rl   rm   rn   )r^   normalized_names     r[   build_table_storage_payloadrs   T   s    ll((*O(L(LUopp??WYY48WYY48 /!'..1!'":":A>&&&&((&& r]   raw_namec                 `    | j                         }|st        t        j                  d      |S )NzNome area obbligatoriorV   )ro   r   r	   rp   )rt   
normalizeds     r[   normalize_room_namerw   h   s+    !J(L(LUmnnr]   c                    t        | j                        }t        | j                        }| j                  t        | j                        nt	        d|      }| j
                  t        | j
                        nt	        d|      }t        ||z
  d      }t        ||z
  d      }| j                  t        | j                  d      n|}| j                  t        | j                  d      nt	        d|      }| j                  t        | j                        nt	        d|      }	| j                  t        | j                        nt	        d|      }
t        ||	z
  d      }t        ||
z
  d      }| j                  t        | j                  d      nt        ||	z
  dz  d      }| j                  t        | j                  d      nt        ||
z
  d	z
  d      }i d
t        | j                        d|d|d| j                  xs dj!                         xs ddt	        ||      dt	        ||      dt	        ||      dt	        ||      d| j"                  d| j$                  xs dj!                         xs ddt	        ||      dt	        ||      dt	        |	|      dt	        |
|      d| j&                  d| j(                  xs dj!                         xs d S )N   i  r   Tr`      i     <   rd   rg   rh   counter_nameBanco	counter_x	counter_ycounter_widthcounter_heightcounter_visibleentrance_nameEntrata
entrance_x
entrance_yentrance_widthentrance_heightentrance_visiblebackground_image_data_url )r:   rg   rh   r   minr   maxr   r   r   r   r   r   rw   rd   r}   ro   r   r   r   r   )r^   width_unitsheight_unitscounter_width_unitscounter_height_unitsmax_counter_xmax_counter_ycounter_x_unitscounter_y_unitsentrance_width_unitsentrance_height_unitsmax_entrance_xmax_entrance_yentrance_x_unitsentrance_y_unitss                  r[   build_room_storage_payloadr   o   sE   !'--0K"7>>2L292G2G2S--.Y\]`bmYn  4;3I3I3U../[^_bdp[q  &991=M';;Q?M?F?P?P?\))d;bo  @G?P?P?\))d;befikxby  4;3I3I3U../[^_bdo[p  5<4K4K4W//0]`adfr]s  ';;Q?N(==qAN ) 	**t<+ 44:A>  ) 	**t< 55:A> #GLL1 	, 	--8??ALW	
 	S-8 	S-8 	0+> 	#2LA 	722 	'//<9CCER 	c*N; 	c*N; 	#2K@ 	34lC 	G44  	$g&G&G&M2%T%T%V%^Z^! r]   z/healthc                  
    ddiS )Nr	   ok r   r]   r[   health_checkr      s    dr]   z/venues)response_modelc                     | gS Nr   )rS   s    r[   
get_venuesr      s
    ?r]   z/roomsvenue_iddbc                    t        | |      }t        t              j                  t        j                        }|j                  t        j                  |k(        }t        |j                  |            }|s0t        ||      }|j                          |j                  |       |g}|D cg c]  }t        |       c}S c c}w r   )r\   r   r   order_byrd   wherer   listscalarsrD   commitrefreshr;   )r   r   rS   allowed_venue_idstmtroomsrooms          r[   	get_roomsr      s     4HmL$<  +D::dmm'778DD!"E$%5r:
		


4-23TN4 333s   +C )r   rW   c                     t        dd|j                  it        |       }|j                  |       |j	                          |j                  |       t        |      S )Nr   r   )r   rY   r   addr   r   r;   )r^   r   rS   r   s       r[   create_roomr      sM     Q))Q-G-PQDFF4LIIKJJt$r]   z/rooms/{room_id}rc   c                 N   |j                  t        |       }||j                  |j                  k7  rt	        t
        j                  d      t        |      j                         D ]  \  }}t        |||        |j                          |j                  |       t        |      S NSala non trovatarV   )getr   r   rY   r   r	   rZ   r   itemssetattrr   r   r;   )rc   r^   r   rS   r   fieldvalues          r[   update_roomr      s     66$ D|t}}(8(88(A(AJ\]]27;AAC $ueU#$ IIKJJt$r]   z/rooms/{room_id}/reset-layoutc                 
   |j                  t        |       }||j                  |j                  k7  rt	        t
        j                  d      t        ||       |j                          |j                  |       t        |      S r   )r   r   r   rY   r   r	   rZ   rE   r   r   r;   )rc   r   rS   r   s       r[   
reset_roomr      sh     66$ D|t}}(8(88(A(AJ\]]dBIIKJJt$r]   z/booking-settingsc                     	 t        |t        | |            \  }}|j                          |j                  |       t        ||      S # t        $ r*}t        t        j
                  t        |            |d }~ww xY wNr   rV   )
r6   r\   
ValueErrorr   r	   rZ   strr   r   r7   )r   r   rS   venuesettingsexcs         r[   read_booking_settingsr      st    ].r<XYacp<qrx IIKJJx%eX66  ](A(A#c(SY\\]s   A	 		A<%A77A<z/portal-context/syncc                 t    t        | j                  |      }t        d|j                  |j                        S )N)session_tokenr   T)syncedr   
venue_name)rG   r   r   rY   rd   )r^   r   r   s      r[   sync_portal_contextr     s/    'g6K6KPRSE$D588PUPZPZ[[r]   z/booking-settings/{venue_id}c                     	 t        t        | |      ||      \  }}t        ||      S # t        $ r*}t        t        j
                  t        |            |d }~ww xY w)NrV   )r8   r\   r   r   r	   rZ   r   r7   )r   r^   r   rS   r   r   r   s          r[   write_booking_settingsr   	  sb    ]12NxYf2giprtux &eX66  ](A(A#c(SY\\]s   ( 	A%AAz/tablesc                 0   t        t              j                  t        j                        }| o|j	                  t
        |       }||j                  |j                  k7  rt        t        j                  d      |j                  t        j                  | k(        }nBt        |j                  |      }|j                  t        j                  |j                  k(        }t        |j                  |            }|D cg c]  }t!        |       c}S c c}w r   )r   r   r   rd   r   r   r   rY   r   r	   rZ   r   rc   r?   r   r   r<   )rc   r   rS   r   r   tablestables          r[   
get_tablesr     s     %=!!%**-DvvdG$<4==M,<,<<F,E,EN`aazz%--723 0 0"5zz%--47723"**T"#F067uOE"777s   >Dc                 P   |j                  t        | j                        }||j                  |j                  k7  rt        t        j                  d      t        di t        |       }|j                  |       |j                          |j                  |       t        |      S )Nr   rV   r   )r   r   rc   r   rY   r   r	   rZ   r   rs   r   r   r   r<   )r^   r   rS   r   r   s        r[   create_tabler   +  s     66$(D|t}}(8(88(A(AJ\]]9/89EFF5MIIKJJu5!!r]   z/tables/{table_id}table_idc                 t   |j                  t        |       }|t        t        j                  d      |j                  t
        |j                        }||j                  |j                  k7  rt        t        j                  d      |j                  t
        |j                        }||j                  |j                  k7  rt        t        j                  d      t        |      j                         D ]  \  }}t        |||        |j                          |j                  |       t        |      S )NTavolo non trovatorV   r   )r   r   r   r	   rZ   r   rc   r   rY   rs   r   r   r   r   r<   )	r   r^   r   rS   r   r   target_roomr   r   s	            r[   update_tabler   ;  s     FF5(#E}(A(AJ^__66$&D|t}}(8(88(A(AJ^__&&w/Kk22m6F6FF(A(AJ\]]3G<BBD %uue$%IIKJJu5!!r]   c                 @   |j                  t        |       }|t        t        j                  d      |j                  t
        |j                        }||j                  |j                  k7  rt        t        j                  d      t        |j                  t        t              j                  t        j                  |j                  k(        j                  t        j                                    }|D cg c]  }| |j                  xs g v s| }}|D cg c]  }|j                   }}|j!                  t        t"        j                        j                  t"        j                  |j                  k(  t"        j                  j%                  t&        j(                  t&        j*                  t&        j,                  g      t/        t"        j0                  |j                  k(  |rt"        j2                  j%                  |      nd            j5                  d            }	|	t        t        j6                  d      t        |j                  t        t"              j                  t"        j                  |j                  k(  t/        t"        j0                  |j                  k(  |rt"        j2                  j%                  |      nd                        }
|
D ]8  }|j0                  |j                  k(  rd |_        |j2                  |v s2d |_        : |D ]  }|j9                  |        t;        |      }t;        |
      }|j<                  }|j9                  |       |j?                          d| d}|r	|d| d	z  }|r	|d
| dz  }| |||dS c c}w c c}w )Nr   rV   Frb   zkQuesto tavolo e ancora assegnato a prenotazioni attive. Sposta o riassegna prima le prenotazioni collegate.zTavolo "z" eliminato.z Rimosse anche z combinazioni collegate.z Ho liberato z! prenotazioni storiche collegate.)
deleted_idremoved_combinationscleared_reservationsrX   ) r   r   r   r	   rZ   r   rc   r   rY   r   r   r   r   r   r   	table_idsscalarr   in_r   pending	confirmedseatedr   assigned_table_idassigned_combination_idlimitHTTP_409_CONFLICTdeletelenrd   r   )r   r   rS   r   r   room_combinationscombinationcombinations_to_removecombination_idsblocking_reservationreservations_to_clearreservationr   r   deleted_table_namerX   s                   r[   delete_tabler   R  s>    FF5(#E}(A(AJ^__66$&D|t}}(8(88(A(AJ^__


6*+112B2J2Jdgg2UV__`p`s`stu (9#HI^I^Idbd<e  :PP+{~~POP99{~~	  M$4$44"""**,=,G,GIZIaIab --9L[3377Haf	

 
q '00F
 	
 !


;%%$$(8(8811UXX=P_K77;;OLej	

 - 7((EHH4,0K)../A26K/	7 . 
		+ 5645IIeIIK*+<8FO$8#99QRRM"6!77XYY  4 4	 y Qs   <NNNz
/customersc                 8   t        t              j                  t        j                        j	                  t
        j                  |j                  k(        j                  t        j                        j                         }t        | j                  |            S r   )r   r   joinreservationsr   r   r   rY   r   rd   distinctr   r   )r   rS   r   s      r[   get_customersr     sg     	x	h##	$	{##}'7'77	8	(--	 	 	 

4 !!r]   c                     t        di | j                         }|j                  |       |j                          |j	                  |       |S )Nr   )r   
model_dumpr   r   r   )r^   r   customers      r[   create_customerr     s>    /',,./HFF8IIKJJxOr]   z/reservations)defaultr	   )r   aliasreservation_datestatus_filterc                     t        || ||j                        }|D cg c]  }t        ||       }}t        |t	        |            S c c}w )N)r  r  r   )r   total)rA   rY   rB   r"   r   )r  r  r   rS   r   r   r   s          r[   get_reservationsr    sZ     %R:JZgr  sC  sC  DLGST";3TET"c%jAA Us   A	c                     | j                   |j                  k7  r| j                  d|j                  i      } t        | |      }t	        ||      S )Nr   )update)r   rY   
model_copyr=   rB   )r^   r   rS   r   s       r[   post_reservationr	    sM    =+++$$Z9I9I,J$K$Wb1K b11r]   z/reservations/{reservation_id}reservation_idc                 J    t        | ||j                        }t        ||      S Nr   )r@   rY   rB   )r
  r   rS   r   s       r[   get_reservationr    s%     )mFVFVWK b11r]   c                 L    t        | |||j                        }t        ||      S r  )rC   rY   rB   )r
  r^   r   rS   r   s        r[   put_reservationr    s'     %^Wb=K[K[\K b11r]   c                 h    t        | ||j                        }|d   d|d    d|d    d|d    d	d
S )Nr   rY   zPrenotazione eliminata: customer_namez il r  z alle 
start_time.)r   rX   )r>   rY   )r
  r   rS   deleteds       r[   remove_reservationr    sX     !m>N>NOGdm&w'?&@)*+6',2G1HK r]   z'/reservations/{reservation_id}/reassignc           	      \   t        | ||j                        }t        ||      }|j                          |j	                  |       t        ||      }t        |j                  |j                  |j                  |r|j                  nd |j                  |j                  |j                        S )Nr   )r
  r   r   assignment_labelrequires_table_joinservice_summaryservice_steps)r@   rY   r5   r   r   rB   r   r   r   labelr  r  r  )r
  r   rS   r   	candidate
serializeds         r[   reassign_reservationr    s     )mFVFVWK+K<IIIKJJ{&{B7J"~~%77 + C C,54&::"22 .. r]   z/reservations/recalculate-dayc                     t        | j                  |j                  |      }|D cg c]&  }|j                  |j                  |j                  ( }}| j                  t        |      |dS c c}w )N)r  	processedunassigned_reservation_ids)r4   r  rY   r   r   r   )r^   r   rS   r   r   
unassigneds         r[   recalculate_dayr#    s~     /w/G/GIYIY[]^L (((0[5X5X5` 	J  $44&&0 s   +A,z/floor-plan.r   c                     	 t        | |||j                        S # t        $ r*}t        t        j
                  t        |            |d }~ww xY wr   )r9   rY   r   r   r	   rZ   r   )r   rc   r   rS   r   s        r[   get_floor_planr%    sK    ]grM<L<LMM ](A(A#c(SY\\]s    	A%A		Az
/seed-democ                 v    t               j                  st        t        j                  d      t        |       S )NzEndpoint demo non abilitatorV   )r   seed_demo_enabledr   r	   rZ   rF   )r   s    r[   	seed_demor(  +  s,    >++(A(AJghh"r]   z/whatsapp/statusc                 0    t        | |j                        S )N)r   r   )rH   rY   r   rS   s     r[   whatsapp_statusr+  2  s    "}/?/?@@r]   z/whatsapp/validate-configc                 0    t        | |j                        S r  )rQ   rY   r*  s     r[   whatsapp_validate_configr-  7  s    #B1A1ABBr]   z/whatsapp/test-messagec                 \    t        | j                  | j                  ||j                        S r  )rN   tomessagerY   )r^   r   rS   s      r[   whatsapp_test_messager1  <  s$     &gjj'//2P]P`P`aar]   z/whatsapp/logs   rb      )r   geler   c                 2    t        || |j                        S )N)r   r   )rK   rY   )r   r   rS   s      r[   whatsapp_logsr7  E  s     b8H8HIIr]   z/whatsapp/conversations   d   c                 ~    t        ||j                  |       D cg c]  }t        j                  |       c}S c c}w )N)r   r   r   )rJ   rY   r.   model_validate)r   r   rS   items       r[   whatsapp_conversationsr=  N  s?     02@P@PX]^ 	(66t<  s   :z-/whatsapp/conversations/{contact_phone}/turnsr|   contact_phonec                 \    t        ||j                  | |      }t        t        |            S )N)r   r   r>  r   )rI   rY   r   reversed)r>  r   r   rS   turnss        r[   whatsapp_conversation_turnsrB  Z  s1     *!!#	E   r]   z/webhooks/whatsappF)include_in_schemarequestc                     t        | j                  j                  d      | j                  j                  d      | j                  j                  d            }t        |      S )Nzhub.modezhub.verify_tokenzhub.challenge)modeverify_token	challenge)content)rO   query_paramsr   r
   )rD  rH  s     r[   whatsapp_webhook_verifyrK  j  sV    (!!%%j1))--.@A&&**?;I
 Y//r]   )r   rC  c                    K   | j                          d {   }t        || j                  j                  d             t	        |      }t        ||      }t        d|      S 7 Mw)NzX-Hub-Signature-256T)receivedprocessed_events)bodyrP   headersr   rL   rM   r3   )rD  r   rO  r^   rN  s        r[   whatsapp_webhook_receiverQ  t  sX     DtW__%8%89N%OP &G.w;t>NOO	  s   A&A$AA&)datetimer   fastapir   r   r   r   r   r	   fastapi.responsesr
   
sqlalchemyr   r   sqlalchemy.ormr   app.api.depsr   r   app.core.configr   app.models.customerr   app.models.reservationr   r   app.models.roomr   app.models.tabler   r   app.models.venuer   app.schemas.bookingr   r   app.schemas.customerr   r   app.schemas.floor_planr   app.schemas.portalr   r   app.schemas.reservationr   r    r!   r"   r#   r$   app.schemas.roomr%   r&   r'   app.schemas.tabler(   r)   r*   app.schemas.venuer+   app.schemas.whatsappr,   r-   r.   r/   r0   r1   r2   r3   app.services.assignmentr4   r5   %app.services.booking_settings_servicer6   r7   r8   app.services.floor_plan_servicer9   app.services.layout_unitsr:   r;   r<    app.services.reservation_servicer=   r>   r?   r@   rA   rB   rC   app.services.seed_servicerD   rE   rF    app.services.tenant_sync_servicerG   app.services.whatsapp_servicerH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   routerintr\   dictr   objectrs   rw   r   r   r   r   r   r   postHTTP_201_CREATEDr   putr   r   r   r   r   r   r   r   r   r   r   r   r  r	  r  r  r  r  r#  r%  r(  r+  r-  r1  r7  r=  rB  rK  rQ  r   r]   r[   <module>rv     sn    M M / " " 2 ( ( A   4 " T = 4 R  > = A A '	 	 	 ] 
 = V V   _ ^ H   
S4Z PU Z] {)B tCQWKGX (# # 5
Z(? 5DfDU 5p Id38n   Id9o6&-.?&@ e T%[  7 HT(^4&/"#454Dj44 4 
(^	4 54" XhF<S<ST &/"#45	 	 	  	  		  U	  x8 &/"#45	    	  	 
   9 $ ,XF &/"#45      	  G  0HI&/"#457Dj77 7 	7 J7 #4MNIPQW \!9 \w \]v \ O\
 *;ST &/"#45	77'7 	7 	7
 7 U7 Id9o6&/"#4584Z88 8 
)_	8 78$ Yyf>U>UV &/"#45""" " 	" W"  ; &/"#45	""" 	" 	"
 " <", #$ &/"#45QQQ Q 
#v+	Q %Qh Ll);< 'PaHb "g " "gkltgu " =" \,FD[D[\;B6? ^  x  ] O,CD$)$$7.3D.Q&/"#45	BTkB$t+B 	B 	B
 B EB __&JaJab?Fvgn  pA  hB 2/ 2W 2_d 2  GV 2 c2 ,_M &/"#45222 2 	2 N2 ,_M &/"#45	222 	2 	2
 2 N2 /0 &/"#45  
#v+	 1 6GWX &/"#45  	 Y* ,- &/"#45"  
	 .$ M*;<s:&/"#45		]
	]	] 		] 		]
 	] =	] \#FO '    /EF")&/'RcJd A A% Ai A GA (9YZ+26?SZ[lSm C C5 C  sS C [C %6NO &/"#45b$bb b 	b Pb T2F-GHraC0&/"#45JJJ J 

	J IJ %d;Z6[\raC0&/"#45  

)*	 ] ;DQjLkl raC0&/"#45	!!! 	! 	!
 

#$! m!  E:0W 01B 0 ;0 !2DX]^CJ6? PG P PWi P _Pr]   