JFIF$        dd7 

Viewing File: /usr/share/cagefs/__pycache__/cagefs_without_lve_lib.cpython-311.opt-1.pyc

�

s�X�G[ce�
�\�ddlZddlZddlZddlZddlmZmZmZddlZddl	Z	ddl
Z
ddlmZddl
Z
ddlZddlmZddlmZmZmZmZddlmZddlmZmZddlmZdd	l
mZmZd
ZdZ dZ!d
Z"dZ#dZ$dZ%dZ&dZ'dZ(eded��ed���Z)Gd�de*��Z+Gd�de*��Z,Gd�de*��Z-Gd�de*��Z.Gd�d e*��Z/Gd!�d"e*��Z0d#Z1d$Z2d%Z3Gd&�d'e*��Z4d(e5d)e5d*e6fd+�Z7d,e5d-e5fd.�Z8d*ee5e5ffd/�Z9d(e5d0e5d*ee:fd1�Z;d2e:d3e5d0e5d*eee:fd4�Z<d5ee:fd6�Z=d7e5d*e:fd8�Z>d9e:d*dfd:�Z?d;e5d<ej@d*e6fd=�ZAd,e5d*e6fd>�ZBd,e5d*e6fd?�ZCdFd@eDe5d*e:fdA�ZEdFd@eDe5d*e6fdB�ZFd*ee5e5ffdC�ZGdD�ZHdE�ZIdS)G�N)�Optional�List�Dict)�Path)�	cledition)�run_command�ExternalProgramFailed�get_file_lines�write_file_lines)�is_da)�	CLLIB_DSN�init_sentry_client)�get_pkg_version)�write_file_via_tempfile�loggingz/usr/sbin/cagefs-mountz
/usr/bin/lsnsz
/bin/mountz/bin/umountz/bin/nsenterz	/bin/grepz/var/cagefs/%s/%s.lockz/usr/share/cagefs-skeletonz/var/cagefs.uid/%s/%d/ns.mntz/var/cagefs.uid/%s/%d/ns.id�cagefsF)�release�dsn�handlec��eZdZdS)�LockFailedExceptionN��__name__�
__module__�__qualname__���j/builddir/build/BUILDROOT/cagefs-7.6.28-1.el9.cloudlinux.x86_64/usr/share/cagefs/cagefs_without_lve_lib.pyrr7��������Drrc��eZdZdS)�NsNotFoundExceptionNrrrrr!r!;rrr!c��eZdZdS)�MountCommandFailedExceptionNrrrrr#r#?rrr#c��eZdZdS)�CagefsMountInvalidUserExceptionNrrrrr%r%Crrr%c��eZdZdS)�CagefsMountPIDWriteFailedNrrrrr'r'Grrr'c��eZdZdS)�CagefsMountJailCallFailedNrrrrr)r)Krrr)���c��eZdZdd�Zd�ZdS)�CagefsMountNotStartedException�c�`�|�|_tj��r|xjdz
c_dSdS)Nz�
The Virtuozzo host mounting limit may have been reached.
Check for the presence of the kernel error "reached the limit on mounts" on VZ host.
More info at https://docs.cloudlinux.com/cloudlinux_installation/#known-restrictions-and-issues)�msgr�is_container)�selfr1s  r�__init__z'CagefsMountNotStartedException.__init__UsD���8����!�#�#�	r��H�H�r�
r�H�H�H�H�	r�	rrc��|jS)N)r1)r3s r�__str__z&CagefsMountNotStartedException.__str__\s	���x�rN)r/)rrrr4r6rrrr.r.Ts;������r�r�r�r�����rr.�ns_id�
cmd_to_search�returnc���	tddddd|g}t|��}|�d��D]*}|���}|dksd|vr�!||krd	S�+n#tf$rYnwxYwd
S)z�
    Find proposed command in proposed NS id
    :param ns_id: NS id to search command
    :param cmd_to_search: Command to search
    :return: True - command found in NS, False - not found
    �--type�mnt�--list�--output�command�
r/�COMMANDTF��_LSNS_BIN_FILEr�split�stripr	)r7r8�cmd�stdout�lines     r�_find_command_in_nsrI`s���
��x���*�i�QV�W���S�!�!���L�L��&�&�	�	�D��:�:�<�<�D��r�z�z�Y�$�.�.���}�$�$��t�t�%�
	��
"�$�
�
�
���
�����5s�AA �A � A.�-A.�username�filename_to_writec���t�d|��}tdddddg}t|��}g}|�d��D]{}|���}|dksd	|vr�!|�dd
��\}}|���|krt||d��dS|�|���||D]&}t||��rt||d
��dS�'td|�d����)z�
    Find user's NS id and write it to file
    :param username: User name
    :param filename_to_write: File name to write
    � r;r<r=r>z
ns,commandr@r/�NSr*�NizNS not found for user z when save NS id to file)	�_CAGEFS_MOUNT_BIN_FILErCrrDrEr�appendrIr!)	rJrKr8rFrG�
ns_id_listrHr7�
ns_commands	         r�_find_save_ns_id_for_userrT|s7��.�:�:��:�:�M��8�U�H�j�,�
O�C�
��
�
�F��J����T�"�"�!�!���z�z�|�|���2�:�:������!�J�J�s�A�.�.���z�������.�.�#�E�+<�e�D�D�D��F�F����%� � � � ������u�m�4�4�	�#�E�+<�e�D�D�D��F�F�	��Y�x�Y�Y�Y�
Z�
Z�Zrc�h�i}	tdddddg}t|��}|�d��D]j}|���}|dksd|vr�!|���}|d	���||d
���<�kn#tf$rYnwxYw|S)zc
    Get all NS with processes in system
    :return: Dict: {'some_ns_id', 'some_pid_from_ns'}
    r;r<r=r>zns,pidr@r/�PIDr*rrB)�ns_dictrFrGrH�
line_partss     r�_get_all_nsrY�s���
�G�
��x���*�h�O���S�!�!���L�L��&�&�	C�	C�D��:�:�<�<�D��r�z�z�U�d�]�]�������J�-7��]�-@�-@�-B�-B�G�J�q�M�'�'�)�)�*�*�	C��
"�$�
�
�
���
�����Ns�BB!�!B/�.B/�user_homedirc	�L�t��}||vrgS||}	tj�t|��}tjtdd|t|dgt
j	t
j	d���}|j
dkrgSg}tddd	d
d|g}t|��}|�
d��D]C}	|	���}	|	d
ksd|	vr�!|�t!|	�����D|S#t"t$t&f$rYnwxYwgS)z�
    Retrieves PID list for user in proposed NS id
    :param ns_id: NS id to retrieve PID list
    :param user_homedir: User homedir
    :return: list PIDs in NS, [] - NS not found/has no processes
    z-mz-tz/proc/mountsF)rG�stderr�shellrr;r<r=r>�pidr@r/rV)rY�os�path�join�_CAGEFS_SKELETON_DIR�
subprocess�run�_NSENTER_BIN�	_GREP_BIN�PIPE�
returncoderCrrDrErQ�intr	�OSError�IOError)
r7rZ�all_ns_id_dict�ns_pid�user_home_is_skeleton�proc�pid_listrFrGrHs
          r�_get_pid_list_by_ns_idrq�s=��!�]�]�N��N�"�"��	�
�E�
"�F�
�!#����-A�<� P� P���~�|�T�4���La�cq�r�%/�_�Z�_�TY�[�[�[���?�a����I����x���*�e�U�S���S�!�!���L�L��&�&�	'�	'�D��:�:�<�<�D��r�z�z�U�d�]�]���O�O�C��I�I�&�&�&�&����!�7�G�6�
�
�
���
����
�Is�A.D�
A9D�D!� D!�user_uid�cagefs_user_prefixc���	tt||fz��}|d���}t||��S#tt
tf$rYnwxYwdS)z�
    Retrieve pid list from user's NS
    :param user_uid: User's uid
    :param cagefs_user_prefix: User's cagefs prefix
    :param user_homedir: User's homedir
    :return: List of user's PIDs or None if user has no NS
    rN)r
�_NS_ID_FILE_NAME_PATTERNrErqrjrk�
IndexError)rrrsrZ�linesr7s     r�_get_pid_list_for_userrx�sq��
��7�;M�x�:X�X�Y�Y���a���� � ��%�e�\�:�:�:���W�j�+�
�
�
���
�����4s�AA�A�Arpc�4�|D�]}	tj|��}n(#tj$rtd|�d���Y�=wxYw|�d���}|�|��|D],}	|����#tj$rY�)wxYwtj|d���\}}|s��|D],}	|����#tj$rY�)wxYwtj|d���\}}|rtd|������dS)	zH
    Kill processes from list
    :param pid_list: PID list to kill
    zProcess with PID z! is already dead, nothing to killT)�	recursiver,)�timeoutzASome processes are still alive after sending the SIGKILL signal: N)	�psutil�Process�
NoSuchProcessr�childrenrQ�	terminate�
wait_procs�kill)rpr^�parentr�p�_�alive�still_alives        r�_kill_processes_in_listr��s���
�:�:��	��^�C�(�(�F�F���#�	�	�	��N��N�N�N�O�O�O��H�	�����?�?�T�?�2�2����������	�	�A�
����
�
�
�
���'�
�
�
���
�����$�X�q�9�9�9���5��	���	�	�A�
����������'�
�
�
���
���� �*�5�!�<�<�<���;��	:��9�+6�9�9�
:�
:�
:��7:�:s3��"A�A�4B	�	B�B�?C�C&�%C&�filenamec�(�	tjtj�|��dd���tj|tjd��}t
j|tj��|S#t$rtd���wxYw)za
    Creates a lock file and acquire lock on it
    :return: File descriptor of created file
    �T��mode�exist_okrOz$IO error happened while getting lock)r_�makedirsr`�dirname�open�O_CREAT�fcntl�flock�LOCK_EXrkr)r��lock_fds  r�
_acquire_lockr�s���
J�
��B�G�O�O�H�-�-�E�D�I�I�I�I��'�(�B�J��6�6��
��G�U�]�+�+�+�����J�J�J�!�"H�I�I�I�J���s�A4A7�7Br�c�l�tj|tj��tj|��dS)zS
    Release lock and close lock file
    :param lock_fd: Lock file descriptor
    N)r�r��LOCK_UNr_�close)r�s r�
_release_lockr�s.��

�K����'�'�'��H�W�����r�pid_filename�processc���td��D]\}	tj|��dS#ttf$r/|����YdSt
jd��Y�YwxYwdS)z�
    Waits for cagefs-mount pid file appears up to 60 seconds
    :param pid_filename: PID filename
    :param process: subprocess that creates the PID file
    :return: True - appears; False - Not
    i`�TNFg����MbP?)�ranger_�statrjrk�poll�time�sleep)r�r��is   r�!_is_pid_file_created_successfullyr�(s����5�\�\�	�	��	��G�L�!�!�!��4�4����!�	�	�	��|�|�~�~�)��u�u�u��J�u������	�����5s�*�%A*�A*�)A*c�2	�ddlm}d}g}d}d}d}	||��}tj�|��}t
||fz}	tj�|	��r\	t|��|rF||krB|
�
��\}}t�|
�d|d�d|�d|�d	���dSdSdSt
j
tj�|	��d
d���t|	�����d
|�d|�d�}
	t
j|
��n#t$t&f$rYnwxYwt)jt,|gt(jt(jdd���}
|
j}|�|��t5j��}t7|
|
��}t5j��|z
}|s�t|��|
�
��\}}|���|���}}|
jt<krt?d|�d|�d|�d	����|
jt@krtCd|	�d|�d|�d|�d	�	���|
jtDkrtGd|�d|�d|�d	����tI|
�d|�d|�d	����t)j%tLdd|�d�|	gddd���}|jdkr&tOd|	�d|�d|j(�d|j)�d	�	���tT||fz}tW||��n�#tHtNt>tBtFf$rA}d}tYt[|����t�.��Yd}~nVd}~wt^$rFd}taj1��}tYd|�d|����t�.��YnwxYwt|��|rD||kr>|
�
��\}}t�|
�d|d�d|�d|�d	���n\#t|��|rE||kr@|
�
��\}}t�|
�d|d�d|�d|�d	���wwwxYw|S)z]
    Create namespace for single user
    :param username: User name to create namespace
    r��get_user_prefixF�z file was created after z.2f�.
STDOUT: "�"
STDERR: "�"r�Tr�z/var/cagefs.uid/�/z/cagefs-mount.pid)rGr\r]�textz;Input arguments validation failed in cagefs-mount for user=zCan't create namespace �
 for user z(cagefs-mount created namespace for user=z,, but was unable to write pidfile.
STDOUT: "z: was not created within the expected time frame.
STDOUT: "z--bindz/proc/z/ns/mnt)�capture_outputr�r]zCan't mount Nz>General error while attempting to create a namespace for user �. Error is: )2�	cagefsctlr��secureio�clpwd�get_uid�_NS_MNT_FILE_NAME_PATTERNr_r`�existsr��communicate�
sentry_client�captureMessager�r�r�touch�unlinkrjrkrc�PopenrPrgr^rQr�r�rErh�_EXIT_VALIDATION_ERRORr%�_EXIT_JAIL_MOUNT_ERRORr)�_EXIT_PID_WRITE_ERRORr'r.rd�_MOUNT_BIN_FILEr#rGr\rurTr�str�captureException�	Exception�	traceback�
format_exc)rJr��error�background_processes�pid_file_created�cagefs_mount_time_taken�cagefs_mount_timeoutrsrr�ns_mnt_filenamerorGr\�cagefs_pid_file�cagefs_mount_pid�
start_time�res�ns_id_filename�er1s                    r�_create_namespace_userr�@s���
*�)�)�)�)�)��E���������f�,�_�X�6�6���>�)�)�(�3�3��4�7I�8�6T�T��
�7�>�>�/�*�*�	��d	 � 4�5�5�5��	� 7�:N� N� N�!�-�-�/�/�N�F�F��(�(�"�:�:�<S�\�:�:�"�:�:�06�:�:�:�
�
�
�
�
�	�	� N� N�e	��B�G�O�O�O�4�4�5�4�P�P�P�P��_���#�#�%�%�%�]�-?�]�]�(�]�]�]��	��I�o�&�&�&�&����"�	�	�	��D�	������
#�X�.��?��?���
�
�
�� �8���#�#�$4�5�5�5��Y�[�[�
�<�_�d�S�S��"&�)�+�+�
�":���	�#�$8�9�9�9�!�-�-�/�/�N�F�F�#�\�\�^�^�V�\�\�^�^�F�F���"8�8�8�5�>�RZ�>�>� &�>�>�4:�>�>�>������$:�:�:�/�>�o�>�>��>�>� &�>�>�4:�>�>�>������$9�9�9�/�>�x�>�>� &�>�>�4:�>�>�>����1�"�:�:�"�:�:�06�:�:�:���
��n�
�h�(J�1A�(J�(J�(J�O�\����	
�
�
���>�Q���-�B��B�B�(�B�B��J�B�B�47�J�B�B�B���
�2�5G��4R�R��!�(�N�;�;�;�;��*�'�+�%�%��	)�	)�	)�����A�������&�&�(�(�(�(�(�(�(�(������)�)�)����"�$�$���l�QY�l�l�gj�l�l�m�m�m��&�&�(�(�(�(�(�	)����	 � 4�5�5�5��	� 7�:N� N� N�!�-�-�/�/�N�F�F��(�(�"�:�:�<S�\�:�:�"�:�:�06�:�:�:�
�
�
���	 � 4�5�5�5��	� 7�:N� N� N�!�-�-�/�/�N�F�F��(�(�"�:�:�<S�\�:�:�"�:�:�06�:�:�:�
�
�
�
�	� N�����Lsj�AL0�AL0�"D7�6L0�7E�L0�
E�G$L0�/P;�0#O"�7N�
P;�AO"�P;�!O"�"P;�;ARc��ddlm}d}d}	||��}tj�|��}tj�|��}t||fz}tj�	|��sdStt||fz��}tj�	|��sdSt|||��}|rt|��tjt |gddditj�ddi����}	|	jdkr/d	|	jvr&t)d
|�d|�d|	j�d
|	j�d�	���tj|��n�#t($r?}
t/t1|
����t2���Yd}
~
n�d}
~
wt6f$rG}
t/d|�dt1|
������d}t2���Yd}
~
nVd}
~
wt8$rFt;j��}t/d|�d|����d}t2���YnwxYw|rt?|��|S)z]
    Delete namespace for single user
    :param username: User name to delete namespace
    rr�NFT�LC_ALL�C)r�r�r]�envznot mountedz
Can't umount r�r�r�r�zCan't acqure lock for user r�z'Error during delete namespace for user z. Error is:
) r�r�r�r�r��get_homedirr�r_r`r�r��_LOCK_FILE_NAME_PATTERNrxr�rcrd�_UMOUNT_BIN_FILE�environrhr\r#rGr�rr�r�r�rr�r�r�r�)rJr��lock_objr�rsrrrZr��	user_pidsr�r�r1s            r�_delete_namespace_userr��s���
*�)�)�)�)�)��H��E�.)�,�_�X�6�6���>�)�)�(�3�3���~�1�1�(�;�;��3�7I�8�6T�T���w�~�~�o�.�.�	��5� �!8�<N�PX�;Y�!Y�Z�Z���w�~�~�o�.�.�	��5�*�8�5G��V�V�	��	/�#�I�.�.�.��n�
��/����1�2�:�1�(�C��1�
�
�
���>�Q���=��
�#B�#B�-�B��B�B�8�B�B��J�B�B�47�J�B�B�B���
�	�	�/�"�"�"�"��&�)�)�)�	��A�������&�&�(�(�(�(�(�(�(�(������"�)�)�)��L�h�L�L�C��F�F�L�L�M�M�M����&�&�(�(�(�(�(�(�(�(������)�)�)��"�$�$���V�(�V�V�QT�V�V�W�W�W����&�&�(�(�(�(�(�	)����
� ��h�����Ls8�A4E�8E�<B E�
I�'5F!�!I�/=G1�1AI�I�
username_listc�`�d}|D](}|rtd|��t|��r|dz
}�)|S)z�
    Create namespace for users from list
    :param username_list: username list for prosess
    :param verbose: prints log in stdout if set
    rzCreating NS for user:r*)�printr�)r��verbose�errorsrJs    r�create_namespace_user_listr��sP���F�!�����	5��)�8�4�4�4�!�(�+�+�	��a�K�F���Mrc�Z�d}|D]%}|rtd|��t|��rd}�&|S)z�
    Delete namespace for users from list
    :param username_list: username list for prosess
    :param verbose: If True, print messages to stdout
    FzDeleting NS for user:T)r�r�)r�r�r�rJs    r�delete_namespace_user_listr�sL��
�E�!�����	5��)�8�4�4�4�!�(�+�+�	��E���Lrc��d}tj�|d��}d�tj|��D��}tj�|d��}|�d�tj|��D����ddg}|D]�}tj�tj�||����sKt
��rRtj�tj�d|����r|�|����d	�|D��}|S)
a1
    Get list of all php-fpm services override files on server
    :return Dict. Example:
        {'ea-php74-php-fpm.service': '/etc/systemd/system/ea-php74-php-fpm.service.d/override.conf',
         'ea-php56-php-fpm.service': '/etc/systemd/system/ea-php56-php-fpm.service.d/override.conf'
        }
    z/usr/lib/systemd/systemzea-php*-fpm.servicec�L�g|]!}tj�|����"Sr�r_r`�basename��.0�xs  r�
<listcomp>z=_get_httpd_php_fpm_service_override_files.<locals>.<listcomp>s(��L�L�L�Q�R�W�%�%�a�(�(�L�L�Lrzalt-php*-fpm.servicec�L�g|]!}tj�|����"Srr�r�s  rr�z=_get_httpd_php_fpm_service_override_files.<locals>.<listcomp>s(��Q�Q�Q�!�"�'�*�*�1�-�-�Q�Q�Qrzphp-fpm.servicez
httpd.servicez/etc/systemd/systemc��i|]}|d|z��	S)z(/etc/systemd/system/%s.d/zzz-cagefs.confr)r��service_names  r�
<dictcomp>z=_get_httpd_php_fpm_service_override_files.<locals>.<dictcomp>(s1��=�=�=�*�'�(R�Ua�(a�=�=�=r)r_r`ra�glob�extendr�rrQ)�systemd_dir�mask_to_search�
service_names�add_services_namesr��override_file_dicts      r�)_get_httpd_php_fpm_service_override_filesr�s0��,�K��W�\�\�+�/D�E�E�N�L�L�$�)�N�2K�2K�L�L�L�M��W�\�\�+�/E�F�F�N����Q�Q�t�y��7P�7P�Q�Q�Q�R�R�R�,�_�=��*�/�/��
�7�>�>�"�'�,�,�{�L�A�A�B�B�	/��G�G�	/�����r�w�|�|�4I�<�'X�'X�Y�Y�	/�
� � ��.�.�.��=�=�.;�=�=�=���rc��	t��}gd�}|���D]G}tjtj�|��dd���t
||d���Htjd��|���D]}tjd|�d����d	S#ttf$rYd	SwxYw)
z�
    Reconfigure httpd and ea-php-fpm services to work in without LVE
    Write to each systemd service file directives:
            PrivateDevices=false
            PrivateMounts=false
            PrivateTmp=false
    )	z
[Service]
zPrivateDevices=false
zPrivateMounts=false
zPrivateTmp=false
zProtectSystem=false
zReadOnlyDirectories=
zReadWriteDirectories=
zInaccessibleDirectories=
zProtectHome=false
r�Tr��w�)/bin/systemctl daemon-reload 2> /dev/null�/sbin/service � restart 2> /dev/nullN)r��valuesr_r�r`r�r�system�keysrjrk)�override_files_dict�lines_to_write�
override_filer�s    r�fix_httpd_php_fpm_servicesr-s���
�G�I�I������1�7�7�9�9�	A�	A�M��K�����
�6�6�U�T�R�R�R�R��]�N�C�@�@�@�@�
�	�=�>�>�>�/�4�4�6�6�	L�	L�L��I�J�|�J�J�J�K�K�K�K�	L�	L���W��
�
�
����
���s�B1B5�5C
�	C
c���	t��}|���D]x}	tj|��n#tt
f$rYnwxYw	tjtj�|�����b#tt
f$rY�uwxYwtj	d��|�
��D]}tj	d|�d����dS#tt
f$rYdSwxYw)Nr�r�r�)r�rr_r�rjrk�rmdirr`r�rr)rrr�s   r�restore_httpd_php_fpm_servicesr	Gs8��
�G�I�I��1�7�7�9�9�
	�
	�M�
��	�-�(�(�(�(���W�'�
�
�
���
����
��������7�7�8�8�8�8���W�'�
�
�
���
����
�	�=�>�>�>�/�4�4�6�6�	L�	L�L��I�J�|�J�J�J�K�K�K�K�	L�	L���W��
�
�
����
���sV�$C"�<�C"�A�
C"�A�C"�1B�C"�B�C"�B�AC"�"C7�6C7)F)Jr_r�rc�signal�typingrrrr�r�r��pathlibrr�r|�clcommon.libr�clcommon.utilsrr	r
r�cldetectlibr�clsentryr
r�clsentry.utilsrrrrPrCr�r�rerfr�rbr�rur�r�rr!r#r%r'r)r�r�r�r.r��boolrIrTrYrirqrxr�r�r�r�r�r�r��listr�r�r�rr	rrr�<module>rs$��
�	�	�	���������
�
�
�
�'�'�'�'�'�'�'�'�'�'�����������������������
�
�
�
�"�"�"�"�"�"�_�_�_�_�_�_�_�_�_�_�_�_�������2�2�2�2�2�2�2�2�*�*�*�*�*�*�5�5�5�5�5�5�5�5�2�� ���� �����	�2��3��;��8��"�"���O�H�%�%���	���
�	�	�	�	�	�)�	�	�	�	�	�	�	�	�)�	�	�	�	�	�	�	�	�)�	�	�	�	�	�	�	�	�i�	�	�	�	�	�	�	�	�	�	�	�	�	�	�	�	�	�	�	�	�	�������	�	�	�	�	�Y�	�	�	��s��3��4�����8 [�� [�� [� [� [� [�F�T�#�s�(�^�����,"�#�"�S�"�T�#�Y�"�"�"�"�J�S��c��QT��Ya�bf�gj�bk�Yl�����&!:�d�3�i�!:�!:�!:�!:�HJ�C�J�C�J�J�J�J��3��4��������
�
��
�����0s�S�s�T�s�s�s�s�l9�S�9�T�9�9�9�9�x��d�3�i��S�������d�3�i��T������4��S��>�����:
�
�
�4
�
�
�
�
r
Back to Directory  nL+D550H?Mx ,D"v]qv;6*Zqn)ZP0!1 A "#a$2Qr D8 a Ri[f\mIykIw0cuFcRı?lO7к_f˓[C$殷WF<_W ԣsKcëIzyQy/_LKℂ;C",pFA:/]=H  ~,ls/9ć:[=/#f;)x{ٛEQ )~ =𘙲r*2~ a _V=' kumFD}KYYC)({ *g&f`툪ry`=^cJ.I](*`wq1dđ#̩͑0;H]u搂@:~וKL Nsh}OIR*8:2 !lDJVo(3=M(zȰ+i*NAr6KnSl)!JJӁ* %݉?|D}d5:eP0R;{$X'xF@.ÊB {,WJuQɲRI;9QE琯62fT.DUJ;*cP A\ILNj!J۱+O\͔]ޒS߼Jȧc%ANolՎprULZԛerE2=XDXgVQeӓk yP7U*omQIs,K`)6\G3t?pgjrmۛجwluGtfh9uyP0D;Uڽ"OXlif$)&|ML0Zrm1[HXPlPR0'G=i2N+0e2]]9VTPO׮7h(F*癈'=QVZDF,d߬~TX G[`le69CR(!S2!P <0x<!1AQ "Raq02Br#SCTb ?Ζ"]mH5WR7k.ۛ!}Q~+yԏz|@T20S~Kek *zFf^2X*(@8r?CIuI|֓>^ExLgNUY+{.RѪ τV׸YTD I62'8Y27'\TP.6d&˦@Vqi|8-OΕ]ʔ U=TL8=;6c| !qfF3aů&~$l}'NWUs$Uk^SV:U# 6w++s&r+nڐ{@29 gL u"TÙM=6(^"7r}=6YݾlCuhquympǦ GjhsǜNlɻ}o7#S6aw4!OSrD57%|?x>L |/nD6?/8w#[)L7+6〼T ATg!%5MmZ/c-{1_Je"|^$'O&ޱմTrb$w)R$& N1EtdU3Uȉ1pM"N*(DNyd96.(jQ)X 5cQɎMyW?Q*!R>6=7)Xj5`J]e8%t!+'!1Q5 !1 AQaqё#2"0BRb?Gt^## .llQT $v,,m㵜5ubV =sY+@d{N! dnO<.-B;_wJt6;QJd.Qc%p{ 1,sNDdFHI0ГoXшe黅XۢF:)[FGXƹ/w_cMeD,ʡcc.WDtA$j@:) -# u c1<@ۗ9F)KJ-hpP]_x[qBlbpʖw q"LFGdƶ*s+ډ_Zc"?%t[IP 6J]#=ɺVvvCGsGh1 >)6|ey?Lӣm,4GWUi`]uJVoVDG< SB6ϏQ@ TiUlyOU0kfV~~}SZ@*WUUi##; s/[=!7}"WN]'(L! ~y5g9T̅JkbM' +s:S +B)v@Mj e Cf jE 0Y\QnzG1д~Wo{T9?`Rmyhsy3!HAD]mc1~2LSu7xT;j$`}4->L#vzŏILS ֭T{rjGKC;bpU=-`BsK.SFw4Mq]ZdHS0)tLg