a
    �Tirr  ã                )   @   s6  U d Z ddlZddlZddlZddlmZmZmZmZm	Z	 ddl
mZmZmZmZmZ ddlmZ e e¡ZG dd„ deƒZe	eeddœd	d
„Ze	eeddœdd„Ze	eeddœdd„Ze	eeddœdd„Ze	eeddœdd„Ze	eeddœdd„Ze	eeddœdd„Ze	eeddœdd„Ze	eeddœdd„Ze	eeddœdd„Ze	eeddœdd„Ze	eeddœdd „Z e	eeddœd!d"„Z!e	eeddœd#d$„Z"e	eeddœd%d&„Z#e	eeddœd'd(„Z$e	eeddœd)d*„Z%e	eeddœd+d,„Z&e	eeddœd-d.„Z'e	eeddœd/d0„Z(e	eeddœd1d2„Z)e	eeddœd3d4„Z*e	eeddœd5d6„Z+e	eeddœd7d8„Z,e	eeddœd9d:„Z-e	eeddœd;d<„Z.e	eeddœd=d>„Z/e	eeddœd?d@„Z0e	eeddœdAdB„Z1e	eeddœdCdD„Z2e	eeddœdEdF„Z3e	eeddœdGdH„Z4e	eeddœdIdJ„Z5e	eeddœdKdL„Z6e	eeddœdMdN„Z7e	eeddœdOdP„Z8e	eeddœdQdR„Z9e	eeddœdSdT„Z:e	eeddœdUdV„Z;e	eeddœdWdX„Z<e=e=eddYœdZd[„Z>eeeeeeeeeeee e9e!e"e#e$e%e&e'e(e)e*e+e,e-e.e/e0e1e2e3e4e5e6e7e7e8e:e;d\œ(Z?e	e=ef e@d]< e	e=ef eeddœd^d_„ZAdS )`zÚ
Command Dispatcher - Table-driven command handling for WebSocket events.

This module extracts all command handling logic from the consumer() function
into a clean, maintainable, O(1) lookup-based dispatcher pattern.
é    N)ÚProtocolÚCallableÚAnyÚOptionalÚDict)ÚsendDictÚsendUserInfoÚsendEventMessageÚ
sendToUserÚComplexHandler)Úconfigc                   @   s,   e Zd ZdZeeef eeddœdd„ZdS )ÚCommandHandlerz5Protocol defining the interface for command handlers.N©ÚeventÚplayerÚ	websocketÚreturnc                 Ã   s   dS )zÑHandle a command event.

        Args:
            event: The parsed JSON event from the client
            player: The player object from playerRecords
            websocket: The WebSocket connection
        N© )Úselfr   r   r   r   r   ú:/var/www/lichun.app/lichun/ws/server/command_dispatcher.pyÚ__call__   s    zCommandHandler.__call__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ústrr   r   r   r   r   r   r      s   r   r   c                 Ã   s"   t ||ƒI dH  tdƒ d|_dS )zHandle game stop command.Nzstopped!Úinactive)r   ÚprintÚ
controller©r   r   r   r   r   r   Úhandle_stop)   s    r    c                 Ã   s   t dƒ d|_dS )zHandle game start command.zstarted!ÚactiveN)r   r   r   r   r   r   Úhandle_start0   s    r"   c                 Ã   s`   ddl m}m} ddl}tdƒ |ƒ }|ƒ |_|j|_|j 	|j|¡ t
||ƒI dH  d|_dS )zHandle game restart command.r   )ÚplayerClassÚgetOccupationsNzrestart!T)Ú	functionsr#   r$   Úappr   ÚoccupationsÚuserIDÚidÚplayerRecordsÚsetr   ÚupdateClient)r   r   r   r#   r$   r&   r   r   r   Úhandle_restart6   s    r-   c                 Ã   sB   ddl m} ||| d ƒ t||ƒI dH  t|jd|ƒI dH  dS )zHandle character setup.r   )ÚcharacterSetupÚmessageNZcharacter_created)r%   r.   r   Ú_check_achievements_triggerr)   )r   r   r   r.   r   r   r   Úhandle_character_setupD   s    r1   c                 Ã   s,   | d |_ td|j  ƒ t||ƒI dH  dS )z!Handle device token registration.r/   zdeviceToken: N)ÚdeviceTokenr   r   r   r   r   r   Úhandle_device_tokenM   s    
r3   c                 Ã   s   t |d|jdœƒI dH  dS )z$Handle get extracurriculars request.ÚextraCurriculars)Útyper4   N)r   r4   r   r   r   r   Úhandle_get_extracurricularsT   s    þr6   c                 Ã   s:   ddl m} |j d¡ ||| d ƒ t||ƒI dH  dS )z!Handle apply for extracurricular.r   )ÚapplyForExtracurricularÚextracurricularr/   N)r%   r7   ÚaskedQuestionsÚaddr   )r   r   r   r7   r   r   r   Ú handle_apply_for_extracurricular\   s    r;   c                 Ã   s.   ddl m} ||| d ƒ t||ƒI dH  dS )zHandle quit extracurricular.r   )ÚquitExtraCurricularr/   N)r%   r<   r   )r   r   r   r<   r   r   r   Úhandle_quit_extracurriculare   s    r=   c                 Ã   sf   ddl m}m} ddlm} ||| d ƒ}|||ƒI dH |_||ƒ|_t|tj	|j
td�ƒI dH  dS )zHandle retrieve person request.r   )Ú
get_personÚgetPersonDescription)ÚparseConversationsr/   N)Údefault)r%   r>   r?   ÚconversationEventsr@   ÚavailableConversationsÚdescriptionr
   ÚjsonÚdumpsÚ__dict__r   )r   r   r   r>   r?   r@   Úpersonr   r   r   Úhandle_retrieve_personm   s    
rI   c           	      Ã   s\  ddl m} ddlm}m} | d } |j|_tj|_|j	j
|jk�rL|j	 j|j8  _||j	ƒ t|d|j	j
dœƒI dH  t| d | d	 ƒ d}|jD ]}|j| d
 kr–|} q²q–||| d
 ƒ}|du sÖ|j|jk�r|tdƒ |  dd¡süd| d< tdƒ ntd| d  ƒ ||| d
 | d	 | d d�I dH }td|j› �ƒ t|tj|jtdd�ƒI dH  t|tj|jtdd�ƒI dH  nÎ| d dk�s˜| d dk�rXtdƒ |j| d |j	j|j|jd� | jd7  _||| d
 | d	 | d d�I dH }t|jd jƒ td|j› �ƒ t|tj|jtdd�ƒI dH  t|tj|jtdd�ƒI dH  n|j d¡ dS )zHandle conversation event.r   )ÚconversationInit)r>   ÚgetPeakEnergyr/   Úu)r5   Ú
calcEnergyNÚconversationEventÚcTypeÚcharacterIDzCno conversation found for this character, creating new conversationÚresponseFzNo responsez
response: )r   Ú	characterrO   rQ   z!Sending new conversation to user )rA   Úensure_asciiZfreeResponse)ÚdateÚtimeé   éÿÿÿÿz$Sending conversation update to user z/You don't have enough energy to talk right now.) rB   rJ   r%   r>   rK   Ú	gameSpeedÚpreviousGameSpeedr   ÚSPEED_PAUSEDÚcrM   ÚmessageEnergyCostÚenergyr   r   ÚconversationsrR   r)   Úgetr
   rE   rF   rG   r   Ú
addMessagerT   rU   ÚquestionÚconversationr/   ÚmessageQueueÚappend)	r   r   r   rJ   r>   rK   Úconvrb   rR   r   r   r   Úhandle_conversationz   sP    



ÿ 
ÿ rf   c                 Ã   s   ddl m} ||| d ƒ dS )z!Handle mark conversation as read.r   )ÚmarkConversationAsReadr/   N)r%   rg   )r   r   r   rg   r   r   r   Ú handle_mark_conversation_as_read¬   s    rh   c                 Ã   s8  ddl m}m}m} |ƒ }|j}||_| d dkrè||v r†| |¡}|d }	|	dkrt||	 |_||j||jdd� qät 	d|› �¡ n^t 
d	|› d
�¡ t|ƒD ]B\}
}||kr |
dkr¼|n
||
d  |_||j||jdd�  qäq �n4| d dk�r¤||v �rR| |¡}|d }	|	t|ƒk �r@||	 |_||j||jdd� nt 	d|› �¡ nPt 
d	|› d
�¡ t|ƒD ]4\}
}||k�rl||_||j||jdd�  �q�qlnx| d dk�rö|jtjk�sÎ|jtjk�rØtj|_n|j|_||j||jdd� n&| d }||ƒ|_||j||jdd� t|d|jdœƒI dH  dS )zHandle speed change command.r   )Úget_speed_button_valuesÚvalidate_game_speedÚlog_speed_changer/   Ú-rV   z	button(-))Úsourcez'Speed already at minimum button value: zSpeed z& not in button values, finding nearestú+z	button(+)z'Speed already at maximum button value: ÚresetZdirectrL   )r5   rX   N)r%   ri   rj   rk   rX   rY   Úindexr(   ÚloggerÚdebugÚwarningÚ	enumerateÚlenr   rZ   ÚSPEED_QUESTION_PAUSEÚSPEED_DEFAULTr   )r   r   r   ri   rj   rk   ZbuttonSpeedValuesÚ	old_speedÚcurrent_indexZ
next_indexÚiZ	btn_speedZrequested_speedr   r   r   Úhandle_speed³   sV    







ÿ

r{   c                 Ã   s<   ddl m} ||| d d | d d ƒ t||ƒI dH  dS )zHandle focus update.r   )Úupdate_focusr/   Z
activityIdZnewFocusN)r%   r|   r   )r   r   r   r|   r   r   r   Úhandle_focus_updateõ   s    r}   c                 Ã   s.   ddl m} ||| d ƒ t||ƒI dH  dS )zHandle quit habit.r   )Ú	quitHabitr/   N)r%   r~   r   )r   r   r   r~   r   r   r   Úhandle_quit_habitý   s    r   c                 Ã   s.   ddl m} ||| d ƒ t||ƒI dH  dS )zHandle stop quit habit.r   )ÚstopQuitHabitr/   N)r%   r€   r   )r   r   r   r€   r   r   r   Úhandle_stop_quit_habit  s    r�   c                 Ã   s.   ddl m} ||| d ƒ t||ƒI dH  dS )zHandle purchase item.r   )ÚpurchaseItemr/   N)r%   r‚   r   )r   r   r   r‚   r   r   r   Úhandle_purchase_item  s    rƒ   c                 Ã   s.   ddl m} ||| d ƒ t||ƒI dH  dS )zHandle purchase in-app item.r   )ÚpurchaseInAppItemr/   N)r%   r„   r   )r   r   r   r„   r   r   r   Úhandle_purchase_in_app_item  s    r…   c                 ƒ   sD   ddl m} ‡ fdd„}||j|  di ¡|d� t|ˆ ƒI dH  dS )zHandle purchase energy refill.r   )Úhandle_purchase_energy_refillc                    s   t  tˆ |ƒ¡ d S ©N©ÚasyncioÚcreate_taskr   ©Ú	player_idr/   ©r   r   r   Úsend_to_client_wrapper!  s    z=handle_purchase_energy_refill.<locals>.send_to_client_wrapperr/   ©rŒ   Úmessage_dataÚsend_to_clientN)Úmonetization.energy_refillsr†   r)   r_   r   )r   r   r   r†   rŽ   r   r�   r   r†     s    
ýr†   c                 ƒ   sD   ddl m} ‡ fdd„}||j|  di ¡|d� t|ˆ ƒI dH  dS )zHandle purchase time skip.r   )Úhandle_purchase_time_skipc                    s   t  tˆ |ƒ¡ d S r‡   rˆ   r‹   r�   r   r   rŽ   0  s    z9handle_purchase_time_skip.<locals>.send_to_client_wrapperr/   r�   N)Úmonetization.time_skipsr“   r)   r_   r   )r   r   r   r“   rŽ   r   r�   r   r“   ,  s    
ýr“   c                 Ã   s,   ddl m} |ƒ }t|d|dœƒI dH  dS )zHandle get energy refill tiers.r   )Úget_refill_tiersZenergyRefillTiers©r5   ÚtiersN)r’   r•   r   )r   r   r   r•   r—   r   r   r   Úhandle_get_energy_refill_tiers;  s    r˜   c                 Ã   s,   ddl m} |ƒ }t|d|dœƒI dH  dS )zHandle get time skip tiers.r   )Úget_skip_tiersZtimeSkipTiersr–   N)r”   r™   r   )r   r   r   r™   r—   r   r   r   Úhandle_get_time_skip_tiersC  s    rš   c                 Ã   s0   ddl m} ||jƒ}t|d|dœƒI dH  dS )zHandle get achievements.r   )Úget_player_achievementsZachievementsList)r5   ÚachievementsN)Úretention.achievementsr›   r)   r   )r   r   r   r›   rœ   r   r   r   Úhandle_get_achievementsK  s    
rž   c                 Ã   s0   |   di ¡  d¡}|r,td|j› d|› �ƒ dS )zHandle acknowledge achievement.r/   ZachievementIdzPlayer z acknowledged achievement N)r_   r   r)   )r   r   r   Zachievement_idr   r   r   Úhandle_acknowledge_achievementS  s    rŸ   c                 ƒ   s(   ddl m} ‡ fdd„}||j|ƒ dS )zHandle get daily rewards.r   )Úhandle_daily_login_checkc                    s   t  tˆ |ƒ¡ d S r‡   rˆ   r‹   r�   r   r   rŽ   _  s    z8handle_get_daily_rewards.<locals>.send_to_client_wrapperN)Úretention.daily_rewardsr    r)   )r   r   r   r    rŽ   r   r�   r   Úhandle_get_daily_rewards[  s    r¢   c                 Ã   sT   ddl m} |  di ¡ dd¡}||jƒ}t|d|dœƒI dH  t||ƒI dH  dS )	zHandle claim daily reward.r   )Úclaim_daily_rewardr/   ÚdayrV   ZdailyRewardClaimed©r5   ÚresultN)r¡   r£   r_   r)   r   r   )r   r   r   r£   r¤   r¦   r   r   r   Úhandle_claim_daily_rewarde  s
    
r§   c                 ƒ   s(   ddl m} ‡ fdd„}||j|ƒ dS )zHandle get daily quests.r   )Úhandle_daily_quest_checkc                    s   t  tˆ |ƒ¡ d S r‡   rˆ   r‹   r�   r   r   rŽ   s  s    z7handle_get_daily_quests.<locals>.send_to_client_wrapperN)Úretention.daily_questsr¨   r)   )r   r   r   r¨   rŽ   r   r�   r   Úhandle_get_daily_questso  s    rª   c                 ƒ   s|   ddl m}m} |  di ¡ d¡}|rx||j|ƒ}tˆ d|dœƒI dH  |d rxt|ˆ ƒI dH  ‡ fd	d
„}||j|ƒ dS )zHandle claim quest reward.r   )Úclaim_quest_rewardr¨   r/   ZquestIdZquestRewardClaimedr¥   NÚsuccessc                    s   t  tˆ |ƒ¡ d S r‡   rˆ   r‹   r�   r   r   rŽ   „  s    z9handle_claim_quest_reward.<locals>.send_to_client_wrapper)r©   r«   r¨   r_   r)   r   r   )r   r   r   r«   r¨   Úquest_idr¦   rŽ   r   r�   r   Úhandle_claim_quest_rewardy  s    r®   c                 Ã   s0   ddl m} ||jƒ}t|d|dœƒI dH  dS )zHandle get player statistics.r   )Úget_player_statisticsZplayerStatistics)r5   Ú
statisticsN)Zretention.statisticsr¯   r)   r   )r   r   r   r¯   Ústatsr   r   r   Úhandle_get_player_statistics‰  s    
r²   c           	   
   Ã   sÈ   ddl m} ddlm} d}z˜z6|ƒ }||d�}| |j¡}t|d|dœƒI dH  W nP ty¤ } z8t 	d|› �¡ t|d	d
t
|ƒdœƒI dH  W Y d}~n
d}~0 0 W |rÄ| ¡  n|rÂ| ¡  0 dS )zHandle data export.r   ©ÚDataManagementService©Úget_database_connectionN©Zdb_connectionZdataExportComplete)r5   ÚdatazData export error: ÚerrorZEXPORT_FAILED©r5   Ú
error_coder/   )Úapi.data_managementr´   Údatabaser¶   Zexport_player_datar)   r   Ú	ExceptionÚloggingr¹   r   Úclose)	r   r   r   r´   r¶   ÚconnÚserviceZexport_dataÚer   r   r   Úhandle_export_data‘  s,    
þý&
ÿrÄ   c           
   
   Ã   s   ddl m} ddlm} |  di ¡ dd¡}|dkrNt|dd	d
dœƒI dH  n®d}zšz8|ƒ }||d�}| |j¡}t|dd|dœƒI dH  W nP tyÜ }	 z8t	 
d|	› �¡ t|ddt|	ƒdœƒI dH  W Y d}	~	n
d}	~	0 0 W |rü| ¡  n|rú| ¡  0 dS )zHandle account deletion.r   r³   rµ   r/   ÚconfirmationÚ ÚDELETEr¹   ZINVALID_CONFIRMATIONzMust type DELETE to confirmrº   Nr·   ZaccountDeletionScheduledé   )r5   ZgracePeriodDaysr¦   zAccount deletion error: ZDELETION_FAILED)r¼   r´   r½   r¶   r_   r   Zdelete_player_accountr)   r¾   r¿   r¹   r   rÀ   )
r   r   r   r´   r¶   rÅ   rÁ   rÂ   r¦   rÃ   r   r   r   Úhandle_delete_account«  s<    ý
ýý&
ÿrÉ   c                 Ã   sB   ddl m} ||| d ƒ t||ƒI dH  t|jd|ƒI dH  dS )zHandle apply for job.r   )ÚapplyForJobr/   NZjob_applied)r%   rÊ   r   r0   r)   )r   r   r   rÊ   r   r   r   Úhandle_apply_for_jobÎ  s    rË   c                 Ã   s.   ddl m} ||| d ƒ t||ƒI dH  dS )zHandle quit job.r   )ÚquitJobr/   N)r%   rÌ   r   )r   r   r   rÌ   r   r   r   Úhandle_quit_job×  s    rÍ   c                 Ã   sB   ddl m} ||| d ƒ t||ƒI dH  t|jd|ƒI dH  dS )zHandle romance action.r   )Úromancer/   NZrelationship_started)r%   rÎ   r   r0   r)   )r   r   r   rÎ   r   r   r   Úhandle_romanceß  s    rÏ   c                 Ã   sT   ddl m} ||| d ƒ}|dur4t||ƒI dH  ndddd	œ}t||ƒI dH  dS )
zHandle date night.r   )Ú	dateNightr/   FNr¹   úDate Night Failedz.Not enough energy or money for the date night.©r5   Útitler/   )r%   rÐ   r	   )r   r   r   rÐ   r¦   Úfailure_messager   r   r   Úhandle_date_nightè  s    ýrÕ   c                 Ã   s.   ddl m} ||| d ƒ t||ƒI dH  dS )zHandle break up or divorce.r   )ÚbreakUpr/   N)r%   rÖ   r   )r   r   r   rÖ   r   r   r   Úhandle_break_upø  s    r×   c                 Ã   sT   ddl m} ||| d ƒ}|dur4t||ƒI dH  ndddd	œ}t||ƒI dH  dS )
zHandle partner gift.r   )ÚpartnerGiftr/   FNr¹   rÑ   z(Not enough energy or money for the gift.rÒ   )r%   rØ   r	   )r   r   r   rØ   r¦   rÔ   r   r   r   Úhandle_partner_gift   s    ýrÙ   c                 Ã   s   |j |_dS )zHandle reset speed.N)rY   rX   r   r   r   r   Úhandle_reset_speed  s    rÚ   c                 Ã   sb   |j j d¡ d|j _|j d|j j d |j j d ¡ |j  jd7  _|j |j ¡ d|_ dS )	zHandle swipe match.Údating_matchzDating MatchzYou matched with Ú ú!é(   FN)	ÚswipeCharacterÚrelationshipsrd   rÓ   rc   Ú	firstnameÚlastnameÚaffinityÚrr   r   r   r   Úhandle_swipe_match  s    $rå   c                 Ã   s¨   ddl m} ddl}|jjdkr$dnd}|||ddd�}d	}td
|jj| ƒ}|jj| }	| ||	¡}
|
|_||_t	d|j
 d |j ƒ t|| d |dœƒI dH  dS )zHandle get swipe character.r   )Úcreate_characterNÚFemaleÚMaleÚrandom_adultsÚnone)ÚageÚrelationshipé   é   zsending character: rÜ   r5   )r5   rß   )r%   ræ   Úrandomr[   ÚsexÚmaxÚageYearsÚrandintrß   r   rá   râ   r   )r   r   r   ræ   rï   rð   rR   Zage_range_widthZlower_boundZupper_boundZ
random_ager   r   r   Úhandle_get_swipe_character  s    rô   c              
   Ã   sŽ  ddl m}m} ddlm} ddlm} d| d< d| d v rh| d  d¡d	 | d< | d  d¡d | d< |jj	}|jj
}|jj}	z´d
| v rôt| d
 tƒrô| d
 }
d|
v r¼|j j	|
d 8  _	d|
v rØ|j j
|
d 8  _
d|
v rô|j j|
d 8  _|| d |d|  d¡|  d
¡ƒ d|_|j|_|j | d ¡ W nð |�y¦ } zX||j_	||j_
|	|j_td|› �ƒ ddlm} ||d| d › �ƒI dH  W Y d}~nˆd}~0  t�y$ } zf||j_	||j_
|	|j_td|› �ƒ tjd| d › �dd� ddlm} ||dƒI dH  W Y d}~n
d}~0 0 |j�rŠt|jƒdk�rŠ|j d¡|_|j |j¡ td|j ƒ |||d|j|dƒƒI dH  d|_dS )zBHandle generic event with event handler system and cost deduction.r   )Úcall_event_handlerÚInvalidEventError)r	   )ÚmessageFunctionFÚkeyz---r5   rV   r/   Ú
energyCostÚ	moneyCostÚdiamondCostÚanswerTzInvalid event rejected: )r¹   zInvalid event type: NzEvent handler error: zHandler crashed: )Úexc_infoz)An error occurred processing your requestzsending message from queue ZanswerQueuerÆ   )Úevent_handlersrõ   rö   Úserver.websocket_messagingr	   r%   r÷   Úsplitr[   r]   ÚmoneyÚdiamondsÚ
isinstanceÚdictr_   r,   rY   rX   r9   r:   r   r&   r¹   r¾   rq   rc   ru   Úpopr/   Ú
messageLogrd   )r   r   r   rõ   rö   r	   r÷   Zoriginal_energyZoriginal_moneyZoriginal_diamondsr/   rÃ   r¹   r   r   r   Úhandle_generic_event4  sX     .&r  )rŒ   Ú
event_typer   r   c                 ƒ   sD   ddl m} ‡ fdd„}|| |ƒ}|r@|D ]}|| d|dœƒ q*dS )z*Auto-check achievements when events occur.r   )Úcheck_achievementsc                    s   t  tˆ |ƒ¡ d S r‡   rˆ   )Úpidr/   r�   r   r   rŽ   w  s    z;_check_achievements_trigger.<locals>.send_to_client_wrapperZachievementUnlocked)r5   ÚachievementN)r�   r	  )rŒ   r  r   r	  rŽ   Zunlocked_achievementsr  r   r�   r   r0   s  s    
þr0   )(ÚstopÚstartÚrestartr.   r2   ÚgetExtraCurricularsr7   ZquitExtracurricularZretrievePersonrb   rg   ÚspeedZ
resetSpeedZfocusUpdater~   r€   r‚   r„   ZpurchaseEnergyRefillZpurchaseTimeSkipZgetEnergyRefillTiersZgetTimeSkipTiersZgetAchievementsZacknowledgeAchievementZgetDailyRewardsZclaimDailyRewardZgetDailyQuestsZclaimQuestRewardZgetPlayerStatisticsZ
exportDataZdeleteAccountrÊ   rÌ   rÎ   rÐ   rÖ   ZdivorcerØ   Z
swipeMatchZgetSwipeCharacterÚCOMMAND_REGISTRYc                 Ã   s|   d}|   d¡dv r| d }nd| v r,| d }|sDt d| › �¡ dS t  |¡}|rf|| ||ƒI dH  nt| ||ƒI dH  dS )aÌ  
    Dispatch a command to the appropriate handler using O(1) dictionary lookup.

    This function replaces the massive if/elif chain in consumer() with a clean,
    table-driven approach that's easier to maintain and extend.

    Args:
        event: The parsed JSON event from the client
        player: The player object from playerRecords
        websocket: The WebSocket connection

    Raises:
        Exception: Any exception raised by the handler
    Nr/   )r  r  r  r5   z No command type found in event: )r_   rq   rs   r  r  )r   r   r   Zcommand_typeÚhandlerr   r   r   Údispatch_command×  s    

r  )Br   rE   r‰   r¿   Útypingr   r   r   r   r   rÿ   r   r   r	   r
   r   r   Ú	getLoggerr   rq   r   r    r"   r-   r1   r3   r6   r;   r=   rI   rf   rh   r{   r}   r   r�   rƒ   r…   r†   r“   r˜   rš   rž   rŸ   r¢   r§   rª   r®   r²   rÄ   rÉ   rË   rÍ   rÏ   rÕ   r×   rÙ   rÚ   rå   rô   r  r   r0   r  Ú__annotations__r  r   r   r   r   Ú<module>   s¶   
		2B


#		
?¹O