/ src / __pycache__ / fastapi_api.cpython-312.pyc
fastapi_api.cpython-312.pyc
  1  2  Iw�i�_�
  3  ��dZddlmZddlmZmZmZmZmZm	Z	ddl
  4  mZddlm
Z
ddlmZmZmZmZmZmZmZddlmZddlmZmZdd	lZdd	lZdd	lZdd
  5  lmZdd	l Z ddl!m!Z!ddl"m#Z#dd	l$Z$dd	l%Z%dd
l&m'Z'ddlm(Z(ddl)m*Z*dd	l+Z+ddlm,Z,ddl-m.Z.ddl/m0Z0ejbjeejbjgejbjgejbjie5����e�e jle jnd��e jpe9�Z:ejvjydd�Z=e'e=�Z>e>jd�Z@Gd�de�ZAGd�de�ZBGd�de�ZCGd�deC�ZDGd �d!e�ZEGd"�d#e�ZFGd$�d%e�ZGe#d&efd'��ZHed(d)d*d+d,eH�-�ZIeIj�ed.gd/d.gd.g�0�d1eKd2eFd3eKfd4�ZLd5ed3eMfd6�ZNeIjyd7eeMeMf�8�d9��ZOeIjyd:eB�8�d;��ZPdd<lQmRZReIj�eR�d=e	d>eRfd?��ZTeIj�d@�d2eFfdA��ZVeIjydBeF�8�dCeMfdD��ZWeIjydE�dFeMfdG��ZXeIj�dB�dCeMfdH��ZZeIjydIe(eF�8�dJeMfdK��Z[eIjydLe(e�8�dCeMfdM��Z\eIj�dN�edOdP�Q�edOdR�Q�edOdS�Q�edOdT�Q�fdCeMdUeMdVedWefdX��Z]eIjydY�dZ��Z^eIj�e�d=e	d>efd[��Z_eIj�e`�d=e	d>e`fd\��Zad]�Zbe9d^k(r:e:j�d_�e:j�d`�ej�dadbdcddde�f�y	y	)gz�
  6  FastAPI Wrapper for AI HR Automation
  7  Integrates with hr_automation.py LangGraph workflow
  8  Handles Forms submissions with CV file processing
  9  �)�ObjectId)�FastAPI�
HTTPException�
 10  UploadFile�File�Form�Request)�CORSMiddleware)�JSONResponse)�	BaseModel�EmailStr�Field�model_validator�
 11  ConfigDict�field_serializer�field_validator)�to_camel)�Dict�AnyN)�load_dotenv)�datetime)�asynccontextmanager)�AsyncMongoClient)�List)�
BeautifulSoup)�Optional)�Config��
generate_ulidz4%(asctime)s - %(name)s - %(levelname)s - %(message)s)�level�format�MONGODB_URLzmongodb://localhost:27017zai-hr-automationc��eZdZUdZeed<eed<eed<eed<eed<eed<eed<eed	<eed
 12  <gZe	eed<y)
�ProcessingResultz$Model for processing result response�success�message�candidate_name�candidate_email�summary�score�	reasoning�cv_link�	timestamp�errorsN)
 13  �__name__�
 14  __module__�__qualname__�__doc__�bool�__annotations__�str�intr.r����/Users/furqan/Documents/AI HR Automation/LangGraph Solution/AI HR Automation - LangGraph Python Project/PythonProject/agentic-ai-hr-automation/src/fastapi_api.pyr$r$DsB��.�
�M�
�L�����
�L��J��N�
�L��N��F�D��I�r8r$c�R�eZdZUdZeed<eed<eed<dZeed<eeefed<y)	�HealthResponsezHealth check response�statusr-�service�1.0.0�version�configN)r/r0r1r2r5r4r?rr7r8r9r;r;Rs,����K��N�
�L��G�S����c��N�r8r;c�t�eZdZUeed<eed<eed<eedd��Zed�de	ede	efd��Z
 15  y	)
 16  �User�id�name�emailT��alias_generator�populate_by_name�from_attributes�value�returnc�@�|rt|t�rt|�S|S�z+Convert ObjectId to string when serializing��
 17  isinstancerr5��selfrJs  r9�serialize_idzUser.serialize_ide����Z��x�0��u�:���r8N)r/r0r1r5r4rr�model_configrrrRr7r8r9rBrBZsS���G�
 18  
�I��J�� ����L��d���(�3�-��H�S�M���r8rBc�"�eZdZUdZeeed<y)�HRUserz
 19  hr manager�roleN)r/r0r1rWrr5r4r7r8r9rVrVms��&�D�(�3�-�&r8rVc��eZdZUeed<edd��Zeed<dZeeed<e	e
 20  dd��Zed	�
 21  �dd��Z
y)
�JobApplication�title�descriptionHTML��validation_alias�serialization_alias�description_htmlN�descriptionTrF�after��modec���|j�rVt|jd�}gd�}|j|�D]$}|jd�|j	d��&|jd�D]}|jd��|jd�D]}|jd��|jdd	g�D]$}|jd
 22  �|j	d
 23  ��&|j
�}tjdd|�}tjd
d|�}djd�|jd�D��}|j�}||_|S)Nzhtml.parser)
�p�div�h1�h2�h3�h4�h5�h6�ul�ol�
 24  blockquote�pre�hrz
 25  
 26  �liu
 27  • �br�
 28  �strong�b�z[ \t]+� z\n{3,}c3�<K�|]}|j����y�w)N)�strip)�.0�lines  r9�	<genexpr>z7JobApplication.strip_html_and_assign.<locals>.<genexpr>�s����G�6F�d�T�Z�Z�\�6F�s�)
r_r�find_all�
insert_before�insert_after�replace_with�get_text�re�sub�join�splitrzr`)rQ�soup�block_elements�tagrrrsru�texts        r9�strip_html_and_assignz$JobApplication.strip_html_and_assigns7��� � � ��!6�!6�
�F�D�E�N��}�}�^�4���!�!�&�)�� � ��(�5��m�m�D�)��� � ��*�*��m�m�D�)������%�*��-�-��3��8���$�$�R�(��#�#�B�'�9�
 29  �=�=�?�D��6�6�)�S�$�/�D��6�6�)�V�T�2�D��9�9�G�d�j�j��6F�G�G�D��:�:�<�D�#�D���r8)rKrY)r/r0r1r5r4rr_r`rrrrTrr�r7r8r9rYrYqs[���J�!�*�-���c��"&�K��#��%�� ����L��'�"�'�#�'r8rYc��eZdZUeddd��Zeeed<ee��Z	eeed<edd��Z
 30  eed	<eed
 31  <dZ
eeed<eedd�
�Zed�deedeefd��Zedd��ed���Zy)�	HRJobPostN�_idrC)�defaultr]r^)�default_factory�ulid�jobApplicationr\�job_applicationrq�
 32  created_atTrFrJrKc�@�|rt|t�rt|�S|SrMrNrPs  r9rRzHRJobPost.serialize_id�rSr8�beforerbc�(�|�|dk(r
 33  t�S|S)zGenerate ULID if not providedrwr)�cls�vs  r9�generate_ulid_if_missingz"HRJobPost.generate_ulid_if_missing�s��
�9��R�� �?�"��r8)r/r0r1rrCrr5r4rr�r�rYrVr�rrrTrrRr�classmethodr�r7r8r9r�r��s������ ��B���
�� �
�>�D�(�3�-�>�&+�)�,�'�O�^��	�J� $�J���
�$�� ����L��d���(�3�-��H�S�M�����V�(�+����,�r8r�c�V�eZdZUedd��Zeed<eed<eed<ee	dd��Z
 34  y)	�CandidateSubmittedApplication�jobIdr\�job_idrDrETrFN)r/r0r1rr�r5r4r
rrrTr7r8r9r�r��s:��� �#��F�C���I��O�� ����Lr8r��appc�0K�tjd�tjd�tjd�tjdtj�dtj���tjd�	tj
 35  �tjd�d���tjd	�y#t$r7}tjd|���tjd�Yd}~�Vd}~wwxYw�w)
 36  z(Lifespan events for startup and shutdown�P================================================================================u"🚀 Starting AI HR Automation APIzHost: �:u(✅ Configuration validated successfullyu%❌ Configuration validation failed: u5⚠️  API will start but may not function correctlyNu'👋 Shutting down AI HR Automation API)	�logger�infor�HOST�PORT�validate�
 37  ValueError�error�warning)r��es  r9�lifespanr��s������K�K���
 38  �K�K�4�5�
 39  �K�K���
 40  �K�K�&����
�Q�v�{�{�m�4�5�
 41  �K�K���P��������>�?�
 42  
 43  ��K�K�9�:���P����<�Q�C�@�A����N�O�O��P�s0�BD�)C�8D�	D�-D�	D�D�D�AI HR Automation APIzSAutomated CV review and candidate evaluation system powered by LangGraph and OpenAIr>�/docsz/redoc)rZr`r?�docs_url�	redoc_urlr��*T)�
allow_origins�allow_credentials�
allow_methods�
allow_headers�candidate_data�hr_job_postrKc	��K�ddlm}		tjd|d�d|d�d��|||��d{���}tjd|d	�d
 44  |dj	dd��d
��|S7�8#t
 45  $rA}tj
dt|���d��tddt|������d}~wwxYw�w)Nr)�"process_job_application_submissionzProcessing candidate: rD� (rE�)u✅ Successfully processed: r'z
 46   - Score: �
 47  evaluationr*�/100u ❌ Error processing candidate: T��exc_info���Processing failed: ��status_code�detail)	�src.hr_automationr�r�r��get�	Exceptionr�r5r)r�r�r��resultr�s     r9�process_candidate_asyncr�s�����D�	�
 48  ����,�^�F�-C�,D�B�~�V]�G^�F_�_`�a�b�:�.�+�V�V�����2�6�:J�3K�2L�J�W]�^j�Wk�Wo�Wo�pw�yz�W{�V|�}A�B�	C��
�W��
 49  �
 50  ����7��A��x�@�4��P���(��Q���1�
 51  �	
 52  ��
 53  �s8�C�.A4�A2�7A4�1C�2A4�4	B>�=<B9�9B>�>C�upload_filec�N�	tjj|j�d}t	j
 54  d|��}t
j|j|�|j�tjd|j���|j|jj�S#t$r?}tjdt|����t!ddt|������d	}~wwxYw#|jj�wxYw)
 55  z�
 56      Save uploaded file temporarily and return path
 57  
 58      Args:
 59          upload_file: FastAPI UploadFile object
 60  
 61      Returns:
 62          Path to saved temporary file
 63      �F)�delete�suffixzSaved uploaded file to: zError saving uploaded file: r�zFailed to save uploaded file: r�N)�os�path�splitext�filename�tempfile�NamedTemporaryFile�shutil�copyfileobj�file�closer�r�rDr�r�r5r)r�r��	temp_filer�s    r9�save_uploaded_filer�5s���!����!�!�+�"6�"6�7��:���/�/�u�V�L�	�	���;�+�+�Y�7��������.�y�~�~�.>�?�@��~�~�	����� ���
 64  ����3�C��F�8�<�=���3�C��F�8�<�
 65  �	
 66  ��
 67  ��	����� �s$�B B=�=	D�:D�D�D�D$�/)�response_modelc��K�dddddd�S�w)z"Root endpoint with API informationr�r>r��/healthz<Automated CV review and candidate evaluation using LangGraph)r=r?�
documentation�healthr`r7r7r8r9�rootr�Ys!����*�� ��U���s�	r�c��K�tdtj�j�ddtj
 68  i��S�w)zK
 69      Health check endpoint
 70      Returns system status and configuration
 71      �healthyzAI HR Automation�llm_provider)r<r-r=r@)r;r�now�	isoformatr�LLM_PROVIDERr7r8r9�health_checkr�es=�������,�,�.�*�*�,�"��F�/�/�
 72  �	����AA)�RequestValidationError�request�excc���K�td�t|j��td|j�td|j�|jd���S�w)zDebug validation errorszValidation Error Details:zBody:i�)r��body�r��content)�printr.r�r�r�r�s  r9�validation_exception_handlerr�wsO����
 73 74  %�&�	�#�*�*�,��	�'�3�8�8�����:�:�<����:���s�A#A%z	/api/jobsc��K�|jddh��}tj�j�|d<tj
 75  j
|��d{���}t|j�}d|d�S7��w)z�
 76      Create a new job posting
 77      - Accepts camelCase from frontend (Next.js)
 78      - Stores in MongoDB as camelCase
 79      - Python variables are snake_case
 80      TrC)�by_alias�exclude�	createdAtN)r%r�)	�
 81  model_dumprr�r��db�hr_job_posts�
 82  insert_oner5�inserted_id)r��hr_job_post_datar�r�s    r9�
 83  create_jobr��s|����#�-�-�t�d�V�-�L��$,�L�L�N�$<�$<�$>��[�!��?�?�-�-�.>�?�
?�F�
��#�#�
$�F�����@�s�AA?�A=�A?z/api/jobs/{job_id}r�c��(K�	tjjd|i��d{���}|s
tdd���t	|d�|d<t
 84  j
|�}|S7�;#t$r }td|���tdd���d}~wwxYw�w)z�
 85      Get a job posting by ID
 86      - Retrieves from MongoDB (camelCase)
 87      - Returns camelCase to frontend
 88      - Python variables are snake_case
 89      r�N��
Job not foundr�r��Error fetching job: )	r�r��find_onerr5r��model_validater�r�)r��jobr�r�s    r9�get_jobr�s�����E��O�O�,�,�f�f�-=�>�>����C��H�H���U��_��E�
 90  � �.�.�s�3����?���E�
�$�Q�C�(�)���O�D�D��E�s8�B�$A&�A$�:A&�#B�$A&�&	B�/B
 91  �
 92  B�Bz&/api/reports/candidate-evaluation/{id}rCc���K�	tjjd|i��d{���}|s
tdd���t	|d�|d<|S7�&#t
 93  $r }t
d|���tdd���d}~wwxYw�w)z7
 94      Get Candidate Evaluation Report - Agent State
 95      r�Nrrr�r�r)r��candidates_evaluation_reportrrr5r�r�)rCrr�s   r9�get_candidate_evaluation_reportr
 96  �s�����
 97  E��3�3�<�<�f�b�\�J�J����C��H�H���U��_��E�
 98  ��
 99  �
K���E�
�$�Q�C�(�)���O�D�D��E�s8�A=�$A�A�%A�A=�A�	A:�A5�5A:�:A=c���K�	tjjdt|�i��d{���}|jdk(rddd�Sddd�S7�#t
100  $r}t
d|���ddd�cYd}~Sd}~wwxYw�w)	Nr�rFzFailed to delete job)r%r&TzJob deleted successfullyzError deleting job: )r�r��
101  delete_oner�
deleted_countr�r�)r�r�r�s   r9�
102  delete_jobr�s�����
103  ����1�1�5�(�6�:J�2K�L�L�����1�$�!�1��
��1�
104  �	
105  �M���
106  �
�$�Q�C�(�)��-�
107  �	
108  ��
109  �sP�A:�-A�A�A�	A:�
110  A�A:�A�	A7�A2�,A7�-A:�2A7�7A:z /api/jobs/applications/{user_id}�user_idc��K�	tjjd|i�jdd�}|j	d���d{���}|sgSg}|D]P}d|vr$t|dt�rt|d�|d<tj|�}|j|��R|S7�a#t$r }td|���tdd	�
111  ��d}~wwxYw�w)Nzhr.idr�������d��lengthr��Error fetching jobs: r��Internal Server Errorr�)r�r��find�sort�to_listrOrr5r�r�appendr�r�r)r�cursor�	jobs_list�processed_jobsrr�r�s       r9�get_jobs_by_userr�s�����M����%�%�w��&8�9�>�>�{�B�O�� �.�.��.�4�4�	���I����C���|�
112  �3�u�:�x� @� ��U��_��E�
113  �$�2�2�3�7�K��!�!�+�.����%5��(�M�
�%�a�S�)�*���4K�L�L��M�sH�C�AB.�
114  B,�B.�C�AB.�+C�,B.�.	C�7C�C�Cz)/api/jobs/candidates/submissions/{job_id}c��K�	i}|dk7rd|i}tjj|�jdd�}|j	d���d{���}|sgSg}|D],}d|vs�t|dt�s�t|d�|d<�.|S7�=#t$r }td|���td	d
115  ���d}~wwxYw�w)N�0r�r�rrrr�rr�rr�)r��!candidates_submitted_applicationsrrrrOrr5r�r�r)r��filterrrrrr�s       r9�get_candidates_job_submissionsr#s�����M����S�=��v�&�F��5�5�:�:�6�B�G�G��UW�X�� �.�.��.�4�4�	���I����C���|�
116  �3�u�:�x� @� ��U��_��E�
117  ��
118  ��5�� �M�
�%�a�S�)�*���4K�L�L��M�sS�B?�AB�B�B�B?�B�(B�<B�B?�B�	B<�B7�7B<�<B?z!/api/candidate-application-submit.zJob Id)r`zCandidate's full namezCandidate's email addresszCV PDF filerDrE�cv_filec��	K�d}	tjd�tjd|�d|�d��tjd|j���|jj�j	d�s
tdd	�
119  ��t
|�}t|||��}|jd�
�}tj�j�|d<tjj|��d{���}t|j �}|||d�}	tj"j%d|i��d{���}
120  |
121  s
tdd�
122  ��t|
123  d�|
124  d<|
125  d=t'd/i|
126  ��}t)|	|��d{���}|dD�
cgc]}
|
j*��}}
||d<|dj�|d<|jd�
�}t-�}|||||d�}tj.j|��d{���}t|j �}tjj1dt3|�id||d�i��d{���t5dd|d|d|j7dd�|dj7d d!�|dj7d"d�|j7d#d�|d$|j7d%g��&�
127  }tjd'|j8�d(��tjd�||rOt:j<j?|�r/	t;j@|�tjd)|���SSS7��Y7��7���cc}
w7��_7��#tB$r+}tjEd*t|����Yd}~Sd}~wwxYw#t
128  $r�tB$rA}tjGd+t|���d�,�td-d.t|����
129  ��d}~wwxYw#|r�t:j<j?|�rf	t;j@|�tjd)|���w#tB$r+}tjEd*t|����Yd}~wd}~wwxYwwwxYw�w)0a
130      API endpoint for Job Form submissions
131  
132      Receives form data with file upload:
133      - name: Candidate's full name
134      - email: Candidate's email address
135      - cv_file: Uploaded CV PDF file
136  
137      Returns complete processing results including evaluation
138      Nr�u📥 New submission received: r�r�u📄 CV file: z.pdfi�z*Only PDF files are accepted for CV uploadsr�)r�rDrET)r�r�)rDrE�cv_file_pathr�rrr�rC�messages�
139  job_skills)r�r��submitted_application_id�state�jobPostz$set)�evaluationReportId�evaluationReportUlidz'CV successfully processed and evaluatedr'r(r)rwr�r*rr+r,r-r.)
140  r%r&r'r(r)r*r+r,r-r.u!✅ Processing complete - Score: r�u$🗑️  Cleaned up temporary file: z!Failed to delete temporary file: u%❌ Error in job_application_submit: r�r�r�r7)$r�r�r��lower�endswithrr�r�r�rr�r�r�r!r�r5r�r�rr�r�r�rr	�
141  update_onerr$r�r*r�r��exists�unlinkr�r�r�)r�rDrEr$�temp_file_path�candidate_submitted_application�$candidate_submitted_application_data�result_submitted_applicationsr)r�r��hr_job_post_model�agent_state�msg�messages_content�job_model_dumpr��agent_result�db_result_evaluation�db_result_evaluation_id�responser�s                      r9� candidate_job_application_submitr@#sv����"�N�_M����H�����4�T�F�"�U�G�1�E�F����n�W�%5�%5�$6�7�8����%�%�'�0�0��8���C��
�,�G�4��+H�v�\`�hm�*n�'�/N�/Y�/Y�cg�/Y�/h�,�<D�L�L�N�<T�<T�<V�,�[�9�.0�.R�.R�.]�.]�_C�/D�)D�%�#&�'D�'P�'P�#Q� �
142  ��*�
143  ���O�O�4�4�f�f�5E�F�F����C��H�H���E� 2�3��D�����%�4��4��3�N�DU�V�V��3>�z�3J�K�3J�C�C�K�K�3J��K�"2��J��$/��$=�$H�$H�$J��L�!�*�5�5�t�5�D��!�O�� $�v�Sk�wB�O]�^��%'�%D�%D�%O�%O�P\�%]�]��"%�&:�&F�&F�"G���2�2�=�=�
�H�5�6�7��*A�,0��
�
144  �	
145  �	
146  �$��=�&�'7�8�'�(9�:��O�O�I�r�2��l�+�/�/���;�!�,�/�3�3�K��D��O�O�I�r�2�!�+�.��?�?�8�R�0�
147  ��	���7����7G�t�L�M����H����b�g�g�n�n�^�<�
M��	�	�.�)����B�>�BR�S�T�=�>�M)D��G��W��K� ^��	
148  ��T�
M����!B�3�q�6�(�K�L�L��
M����
��
149  ����<�S��V�H�E�PT��U���(��Q���1�
150  �	
151  ��
152  ���b�g�g�n�n�^�<�
M��	�	�.�)����B�>�BR�S�T���
M����!B�3�q�6�(�K�L�L��
M��	=�>�s��R�C;N%�M�AN%�M�AN%�M �N%�M#�&A#N%�	M(�
153  AN%�M+�B1N%�!R�*-M.�R�N%�N%� N%�#N%�+N%�.	N"�7!N�R�N"�"R�%O8�7<O3�3O8�8O;�;"R�-Q�R�	R�!Q;�6R�;R�R�Rz/api/configc��K�tjtjtjtjd�S�w)z=
154      Get current configuration (non-sensitive data only)
155      )�model_provider�extraction_temp�summary_temp�evaluation_temp)rr��EXTRACTION_TEMP�SUMMARY_TEMP�EVALUATION_TEMPr7r8r9�
156  get_configrI�s6����!�-�-�!�1�1��+�+�!�1�1�	��r�c��K�t|jd|jt|j�tj�j�d���S�w)zHandle HTTP exceptionsF)r%r�r�r-r�)rr�r�r5�urlrr�r�r�s  r9�http_exception_handlerrL�sI������O�O���Z�Z�����$�!����1�1�3�	
157  ���s�AAc���K�tjdt|���d��tdddtj
158  rt|�ndt
j�j�d��	�S�w)
159  zHandle general exceptionszUnhandled exception: Tr�r�FzInternal server errorz)An error occurred processing your request)r%r�r�r-r�)	r�r�r5rr�DEBUGrr�r�r�s  r9�general_exception_handlerrO�sa�����L�L�(��S��
160  �3�d�L�C����,�"(�,�,�c�#�h�4_�!����1�1�3�	
161  ���s�A1A3c�B�tj�xsd}d|zdzS)Nr��)r��	cpu_count)�coress r9�get_optimal_workersrT�s"���L�L�N��a�E�
��I��?�r8�__main__zStarting FastAPI server...z-API Documentation: http://127.0.0.1:8000/docszfastapi_api:appz	127.0.0.1i@Fr�)�host�port�reload�	log_level)er2�bsonr�fastapirrrrrr	�fastapi.middleware.corsr
162  �fastapi.responsesr�pydanticrr
rrrrr�pydantic.alias_generatorsr�typingrrr��sys�uvicorn�dotenvr�loggingr�
163  contextlibrr�r��pymongorr�bs4rr�r�
164  src.configr�utils.ulid_helperrr�r�dirname�abspath�__file__�basicConfig�INFO�	getLoggerr/r��environr�r"�client�get_databaser�r$r;rBrVrYr�r�r�r��add_middleware�dictr�r5r�r�r��fastapi.exceptionsr��exception_handlerr��postr�rr
165  r�rrr#r@rIrLr�rOrTr��runr7r8r9�<module>rys�����K�K�2�*�o�o�o�.��	�
166  �����*��
�$���	���+����������������������0I� J�K�L��
�����
167  �,�,�A��
168  ��	�	�8�	$���j�j�n�n�]�,G�H��	�+�	&�����+�,���y���Y���9��&'�T�'�6�Y�6�r"�	�"�J
�I�
�(�;��;��;�6�
169   �e��
��
�
�������%���%��%���
170  �$�
171  �Y�
172  �SW�
173  �>!�J�!�3�!�H����T�#�s�(�^��,��-������>��2��3��6����-�.����>T��/�����+���)����*���	�i��8�E�#�E�9�E�4���	1�2�E�c�E�3�E�&��� �!�
174  �S�
175  �"�
176  �4���	+�D��O��L�M�C�M�M�M�<���	4�T�#�Y��O�M��M�P�M�>���
177  -�.��s��1��S�&=�>��3�,G�H��s�
�>�	qM��qM�
178  
�qM��qM��	qM�/�qM�h�����	��	� ���}�%�
179  �'�
180  �
�
181  �&�
182  ����y�!��W��9��"��$��z��
183  �K�K�,�-�
184  �K�K�?�A��G�K�K�!� ��� �	�r8