HEX
Server: LiteSpeed
System: Linux linux31.centraldnserver.com 4.18.0-553.83.1.lve.el8.x86_64 #1 SMP Wed Nov 12 10:04:12 UTC 2025 x86_64
User: salamatk (1501)
PHP: 8.1.33
Disabled: show_source, system, shell_exec, passthru, exec, popen, proc_open
Upload Files
File: //opt/alt/python37/lib/python3.7/site-packages/xray/adviser/__pycache__/cli_api.cpython-37.pyc
B

�V�d̆�@s�dZddlZddlZddlZddlZddlZddlZddlmZddl	m
Z
mZddlm
Z
mZmZmZddlmZddlmZddlmZmZdd	lmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#dd
l$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*ddl+m,Z,ddl-m.Z.d
dl/m0Z0d
dl1m2Z2d
dl3m4Z4d
dl5m6Z6m7Z7m8Z8ddl9m:Z:ddl;m<Z<m=Z=m>Z>m?Z?ddl@mAZAmBZBmCZCddlDmEZEmFZFmGZGddlHmIZImJZJmKZKmLZLddlMmNZNdZOGdd�de�ZPeGdd�d��ZQGdd�d�ZRdS) zB
This module contains X Ray Smart Advice local utility main class
�N)�contextmanager)�asdict�	dataclass)�Any�Tuple�Optional�List)�Enum)�LicenseApproveStatus)�Schema�SchemaError)�is_feature_visible�is_feature_allowed�is_subscription_pending�get_subscription_upgrade_url�get_license_approve_status�approve_license_agreement�get_license_agreement_text�get_subscriptions_info�calculate_cdn_usage�get_user_auth_key�is_feature_hidden_server_wide)�docroot�is_panel_feature_supported�get_user_emails_list�panel_login_link�	getCPName�userdomains)�drop_privileges)�Feature�)�advice_mapping)�WPOSModuleApply)�SmartAdviceProgress)�advice_list_schema�detailed_advice_schema�user_sites_info_schema�)�
get_client)�advice_pending_storage�advice_processed_storage�advice_list_cache�advice_reason_max_len)�XRayAPIError�	XRayError�SmartAdvicePluginError)�user_mode_advice_verification�username_verification�get_xray_exec_user)�	timestamp�	safe_move�get_user_php_version�filelock)�report_usage_action_or_error�;c@seZdZdZdZdS)�
AdviceActions�apply�rollbackN)�__name__�
__module__�__qualname__�APPLY�ROLLBACK�rArA�E/opt/alt/python37/lib/python3.7/site-packages/xray/adviser/cli_api.pyr9Asr9c@s>eZdZUeed<eed<eed<eed<eed<eed<dS)�SmartAdviceOptions�
panel_type�	panel_url�panel_emails�upgrade_url�upgrade_url_cdn�subscriptionN)r<r=r>�str�__annotations__�dictrArArArBrCEs
rCc
@s�eZdZdZdd�Zeedd�dd��Zeed�d	d
��Zee	ed�dd
��Z
e	eed�dd�Zee	ed�dd��Z
e	ed�dd�Ze	ed�dd�Zdd�Zeeed�dd��Zeeed�dd�Zee	eeefd�dd ��Zedfeeedd"�d#d$��Ze	eed%�d&d'�Ze	eeeeefd(�d)d*�Zdged�d+d,�Z e!ed�d-d.��Z"d/d0�Z#dhd1d2�Z$d3d4�Z%e	ed�d5d6�Z&die	eeeeeeeed8�d9d:�Z'djee	eeeeeeed;�d<d=�Z(ed�d>d?�Z)e	ed�d@dA�Z*dBdC�Z+dDdE�Z,e!dFdG��Z-dkdHdI�Z.dldJdK�Z/edLdM��Z0dNdO�Z1edPdQ��Z2edRdS��Z3dTdU�Z4edVdW��Z5dXdY�Z6dmdZd[�Z7e8eee8ed\�d]d^�Z9eee8ee8ed_�d`da��Z:dbdc�Z;ddde�Z<dS)n�SmartAdviceUtilz%Main Smart Advice local utility classcCs<t�d�|_xttfD]}|�|�qWtd�}|�|_dS)NZsmart_advice�adviser)�loggingZ	getLogger�loggerr)r*�
create_dirr(�adviser_client)�selfZstorZadviser_client_objectrArArB�__init__Qs
zSmartAdviceUtil.__init__N)�dpath�returncCstj�|�st�|�dS)zCreate dir if missingN)�os�path�isdir�mkdir)rUrArArBrQZszSmartAdviceUtil.create_dir)rVcKs0dt�d�}|r|�|�t�tt|�����S)z�
        Create JSON response message with result field == success
        and given keyword arguments in other fields
        :return: json packed string
        �success)�resultr3)r3�update�json�dumpsrL�sorted�items)�kwargsZinitialrArArB�response`s
zSmartAdviceUtil.response)�a_idrVcCst�d|��S)z%Per-advice file with results of apply�/)r*)rdrArArB�_apply_datafilelszSmartAdviceUtil._apply_datafilecCs�|�|�}tj�|�r�zpy"t|��}t�|�}WdQRXWnHtk
rRd}Yn2tjk
r�t|��}|�	�}WdQRXYnXWdt�
|�X|SdS)z=Retrieve data stored in per-advice file with results of applyN)rfrWrX�isfile�openr^�load�OSError�JSONDecodeError�read�unlink)rSrdZdatafile�_f�datarArArB�_apply_resultsqs


zSmartAdviceUtil._apply_resultscCst�d|��S)zPer-advice pending flagre)r))rdrArArB�
_pending_flag�szSmartAdviceUtil._pending_flag)�	advice_idrVcCstj�|�|��S)zIs advice in pending state)rWrX�existsrq)rSrrrArArB�is_advice_pending�sz!SmartAdviceUtil.is_advice_pendingcCs|�|�dS)zPer-advice progress storagez	.progress)rq)rSrdrArArB�_progress_file�szSmartAdviceUtil._progress_filecCs.yt|�Stk
r(|j�d�dSXdS)Nz#Error while getting user login link�)r�	ExceptionrP�	exception)rS�usernamerArArB�_get_user_login_link�s
z$SmartAdviceUtil._get_user_login_link)�advice_typerVcCst|S)z>Get appropriate instance of Apply actions class by advice type)r!)r{rArArB�get_advice_instance�sz#SmartAdviceUtil.get_advice_instance)ro�schemarVc
Csby
|�|�Stk
r\}z4|j�d|�|jdp<|jd}td|����Wdd}~XYnXdS)z&Validate given data using given schemaz#Failed to validate API response: %s���zMalformed API response: N)ZvalidaterrP�error�errorsZautosr-)rSror}�e�msgrArArB�	_validate�s
zSmartAdviceUtil._validatecCs,|j|j�|�td�}||�|dd�fS)zu
        Get advice details from API along with an
        appropriate Advice object by obtained advice type
        )ror}�advice�type)r�rR�advice_detailsr%r|)rSrrZ	_responserArArB�get_detailed_advice�s
z#SmartAdviceUtil.get_detailed_adviceF)�dstro�as_jsonrVc	Csl|d}t|d��F}|rJyt�||�WqTtk
rF|�|�YqTXn
|�|�WdQRXt||�dS)z8Dump data inside given dst using .bkp file and then movez.bkp�wN)rhr^�dump�	TypeError�writer4)r�ror�Z_tmp_dstrnrArArB�dump_to_file�szSmartAdviceUtil.dump_to_file)rr�currentrVcs ttd����fdd��}|�S)a
        Smart Advice apply own progress,
        based on current and previous results of 'clwpos get-progress'.
        Returns the maximum progress values among current and previous.
        Previous (latest) is stored inside a pending file-flag.
        )rVc
3s��j�d������}y(t|��}tft�|��}WdQRXWn@ttjfk
r�}z�j�dt	|��t�}Wdd}~XYnX�j�d|��|kr��n|V��
��rֈ|krֈj�d���j|t��dd�dS)z}
            Get progress stored in file and return the maximum one among
            current and stored results
            zCurrent progress value: %sNz%Error during reading stored value: %szStored progress value: %szUpdating stored progress: %sT)r�)
rP�debugrurhr#r^rirjrkrJrtr�r)Zprogress_dstZprevZprev_stagesr�)rrr�rSrArB�resolve_progress�s


z2SmartAdviceUtil.progress.<locals>.resolve_progress)rr#)rSrrr�r�rA)rrr�rSrB�progress�szSmartAdviceUtil.progress)�_id�
advice_obj�advice_datarVc	CsX|�|�r:d}|�||�|dd���
}|}WdQRXn|dd}t�}|t|�fS)z�
        Resolve if advice is in pending status.
        Progress is retrieved for pending advice only.
        Dummy result (0, 0) is returned for other advice states.
        �pending�metadataryNr��status)rtr�Zget_progressr#r)rSr�r�r�r��p�stagesrArArB�get_current_status�s

z"SmartAdviceUtil.get_current_statuscCs`|j|j��td�}|j||d�}y|j|d�Wn tk
rR|j�d�YnX|j	|d�S)z9Load validated advice list and update it before returning)ror})�extended)�current_adviceszDUnable to sync cl-smart-advice plugin during getting list of advices)ro)
r�rR�advice_listr$�prepare_advices_response�sync_advices_wordpress_pluginrwrPrxrc)rSr��api_responseZresponse_advice_listrArArBr��szSmartAdviceUtil.advice_listc	Cs�|j|j�|�td�}i}xP|D]H}|d}||kr<g||<||�|dt|d�|�|d�d��q Wdd�|��D�}|j|d	�S)
N)ror}�domain�websiteZurls�advices)r�Zurls_scannedr�cSsg|]\}}||d��qS))r��websitesrA)�.0r�r�rArArB�
<listcomp>sz5SmartAdviceUtil.get_site_statuses.<locals>.<listcomp>)ro)	r�rRZ	site_infor&�append�lenr�rarc)rSryr�Zsite_statuses_datar�r�r\rArArB�get_site_statusess

z!SmartAdviceUtil.get_site_statusescCs2yt�|�dStk
r,t�d�dSXdS)NTzGUser %s does not exist anymore on this server, skipping advices for himF)�pwd�getpwnam�KeyErrorrO�info)rSryrArArB�_does_user_exist_on_servers

z*SmartAdviceUtil._does_user_exist_on_serverc
Cs>|��}g}�x*|D�] }|�|dd�s.q|d}|d}|�|�}	|	j|d<|rj|d}
ddd�}n|�|d	|	|�\}
}|r�|	j|d
<|
|d<|	j|d<|	j|d<t|	j|dd�j	|d
<|d�r|�
|	j|dd�}t|t|	j|dd�d�|d<|�
|�t|	j|dd�rt|	j�s|�|�qW|S)Nr�ryr�r��descriptionr�r)Ztotal_stagesZcompleted_stages�id�detailed_descriptionZ
is_premium�module_nameZlicense_status)r�rGrI)�copyr�r|�short_descriptionr�r�Zis_premium_featurer�r�name�_get_subscription_statusrLrr]r
rr�)
rSZfrom_api�status_from_microservicer�r�Zvisible_advices�item�
advice_itselfr{�advice_instancer�r��subscription_statusrArArBr�sD








z(SmartAdviceUtil.prepare_advices_responsecCs$d}t||�rd}t||�r d}|S)zQ
        Determines current subscription status based on feature status.
        ZnoZactiver�)rr)rSr�ryr�rArArBr�Is

z(SmartAdviceUtil._get_subscription_statuscCs@|�|�\}}|d}|j|d<|j|d<|j|d<|j|d�S)z<Load validated advice details and update it before returningr�r�r�Z
fix_action)ro)r�r�r�Zapply_button_textrc)rSrrr�r�r�rArArBr�Ts


zSmartAdviceUtil.advice_details�
ACCELERATE_WP)rr�
ignore_errors�
async_mode�source�reason�accept_terms�analytics_datarVc		Csht|�|�d���|r.t��}	|	r.|�|�S|�|||||||�}
|dk	r\t||||
|�|rdd}
|
S)Nr�)rhrq�closerW�fork�manage_advice_status�_exec_advice_managingr7)rS�actionrrr�r�r�r�r�r�Zchild�outputrArArB�
manage_advice`s

zSmartAdviceUtil.manage_advice)r�rrr�r�r�r�r�rVcCs�z�|�|�\}}	|tjjkr�|r6t|	j|dd�t|	j|dd�tjkr`t	�
ddd��S|	jf|dd|i��\}
}|
r�|j�
d�|jj|d|d	�y*|�|dd|dd
|dd�Wn tk
r�|j�d�YnXn�|tjjk�r�|	jf|d�\}
}|
�r�|j�
d
�|�rD|jj|d||dt�d�n|jj|d|d	�y*|�|dd|dd
|dd�Wn"tk
�r�|j�d�YnXntd|����Wdtj�|�|���r�t�|�|��X|�r�|�|�|�|�|S|SdS)z:Execute managing advice with passed action: apply/rollbackr�ryZLICENCE_TERMS_APPROVE_REQUIREDz�License approve required to use this feature. Open AccelerateWP plugin in your control panel, apply advice and accept terms and conditions to proceed with installation.)r\�textr�zApplied successfully�applied)rrr�r�r�r�z:Error while syncing cl-smart-advice plugin on advice applyzRollback successfullyZreviewN)rrr�r�r�z=Error while syncing cl-smart-advice plugin on advice rollbackz/Unsupported action with advice, passed action: )r�r9r?�valuerr�rr
ZNOT_APPROVEDr^r_r:rPr�rRZ
update_advice�_sync_advicerwrxr@r;r,�
ValueErrorrWrXrgrqrmr�rf)rSr�rrr�r�r�r�r�r�r�Z
action_resultr�rArArBr�vsf


z%SmartAdviceUtil._exec_advice_managingcCshy|j|j��td�}Wn$tk
r<t�ddgd�}Yn Xtt|�tdd�|D��d�}|j|d�S)	z#Return advice counters for a server)ror}�totalr�NcSs g|]}|dddkr|�qS)r�r�r�rA)r�r�rArArBr��sz3SmartAdviceUtil.advice_counters.<locals>.<listcomp>)r�r�)ro)	r�rRr�r$r.rL�fromkeysr�rc)rSr�r\rArArB�advice_counters�szSmartAdviceUtil.advice_countersc	Cs�|�|�\}}|�|||�\}}|�|j|dd�}|dkr�|�|�}|�|�}tj�|�rht�	|�|r�|j
f|t|d�t|j|dd�d�|d|i��S|j
f|t|d�t|j|dd�d�|��S)zS
        Return current status and progress of managing particular advice.
        r�ryr�)�object_cache)r�rIrGro)
r�r�r�r�rprurWrXrgrmrcrLr)	rSrrr�r�r�r�r�r\Z	_progressrArArBr��s8




z$SmartAdviceUtil.manage_advice_statusc
Cs�|j|j��td�}|�|�}y |�||||j|ddd��Wn&tk
rd|j�	dt
|��dSX|��}|�t�|�t�|��}||kr�i||<||||<|�
|�dS)N)ror}T)r�r�z/Smart Advice plugin sync failed for website: %s)r�rRr�r$�!group_alive_advice_ids_by_website�_run_smart_advice_scriptr�rwrPrxrJ�_read_advices_cache�advice_cache_separator�_update_advices_cache)rSryr�r�r��current_advices_by_site�cached_advices_by_site�keyrArArBr��s 

zSmartAdviceUtil._sync_advicecCs&ddlm}t|�}|�j�|�}|S)Nr)�AWPProvisionAPI)�xray.adviser.awp_provision_apir�rZawp_client_api�	get_usage)rSryr�Zacc_idZ	cdn_usagerArArB�_get_cdn_usage_statistics
sz)SmartAdviceUtil._get_cdn_usage_statisticscCs�yt|�dd}t||�}Wn$tk
rB|j�d�d}YnXyt|�}Wn$tk
rt|j�d�i}YnX|jfttt	�|�
|�|td|�td|�|d���S)a'
        gets options:
        "panel_type": "cpanel",
        "panel_url": "https:/cpanel-foo.com/", # or https://plesk-bar.com/
        "panel_emails": "root@hosting.com,manager@hostring.com,foo@bar.com",
        "upgrade_url": "https://...",
        "upgrade_url_cdn": "https://...",
        rzUnable to get user emailsrvzCannot obtain subscription infor�Zcdn)rDrErFrGrHrI)rrrwrPrxrrcrrCrrzr)rSryr��emailrIrArArB�get_optionss"


zSmartAdviceUtil.get_optionscCsj|s|j|j��td�}|�|�}|s2|jdd�S|��}|j|||j|dd�d�}|�	|�|jdd�S)N)ror}zNo advices found on the server)roT)r�)�current_advices_jsonzPlugin installed)
r�rRr�r$r�rcr��_sync_sa_pluginr�r�)rSr�r�r�Z
updated_cacherArArBr�1s

z-SmartAdviceUtil.sync_advices_wordpress_pluginc
	s�d}i}x�|��D]�\}}|�t�\}�}	|�||�|��sF|||<q|r\�fdd�|D�}y|��|	||�Wn(tk
r�|j�dt	|	��wYnX|||<qW|S)Ncs&g|]}|�di��d��kr|�qS)r�ry)�get)r�r�)ryrArBr�Msz3SmartAdviceUtil._sync_sa_plugin.<locals>.<listcomp>z/Smart advice plugin sync failed for website: %s)
ra�splitr��_should_sync_websiter�r�rwrPrxrJ)
rSr�Zcached_advicesr�Zfiltered_advices_by_userZupdated_advicesr�Zid_status_hashr�r�rA)ryrBr�Bs zSmartAdviceUtil._sync_sa_plugincCsZtt�d�d��@}t|��,ttd��}tj||dd�WdQRXWdQRXWdQRXdS)Nz.lockza+r�r')Zindent)rhr+r6r^r�)Znew_cached_advicesZlock_fd�frArArBr�Ys
z%SmartAdviceUtil._update_advices_cachec	Cs\i}tj�t�rXy"tt��}t�|�}WdQRXWn$tk
rV|j�	d�i}YnX|S)Nz!Unable to read advices cache json)
rWrXrsr+rhr^rirwrPrx)rSr�r�rArArBr�`s

z#SmartAdviceUtil._read_advices_cachecCs||kS)NrA)Zcurrent_hashZcached_hashrArArBr�ksz$SmartAdviceUtil._should_sync_websitecCsBt��}x0|D](\}}|�t|����|�|���qW|��S)N)�hashlibZmd5r]rJ�encodeZ	hexdigest)�id_status_pairs�hrrr�rArArB�	make_hashos
zSmartAdviceUtil.make_hashc	s�i}x�|D]�}|d}|d}��|d�}|j}t|�r<q
|d�t�|d�t�|d��}||krpg||<||�|d|df�q
W�fd	d
�|��D�S)Nr�r�r�r�ryr�r�r�c	s,i|]$\}}��tt|dd�d���|�qS)cSs|dS)NrrA)r�rArArB�<lambda>��zNSmartAdviceUtil.group_alive_advice_ids_by_website.<locals>.<dictcomp>.<lambda>)r�)r��tupler`)r�r�r�)rSrArB�
<dictcomp>�szESmartAdviceUtil.group_alive_advice_ids_by_website.<locals>.<dictcomp>)r|r�rr�r�ra)	rSr�r�r�r�r�r�r�r�rA)rSrBr�ws
$
z1SmartAdviceUtil.group_alive_advice_ids_by_websitec	Cs$t|d��}|�|�WdQRXdS)z"
        For easy mocking
        r�N)rhr�)rXZcontentr�rArArB�_save_custom_php�sz SmartAdviceUtil._save_custom_phpc
	Cs0t�|�j�d�}d}tj�||�}d}d}tj�|�r<dStjd|�d�dddd�}|j	�
dt|j��|jr�||jkr�|j�
��d	|��}n|js�||jkr�d
|��}|�r,|j	�
d||�t|��,tj�|�s�tj|dd
�|�||�WdQRXtjdddd|d|gddd�}	|j	�
dt|	j��dS)Nz/.clwposz.php-iniz/opt/alt/php-xray/z-/usr/sbin/plesk bin site --show-php-settings z | /usr/bin/grep open_basedirT)r��capture_output�shellz!Current open_basedir settings: %s�:zopen_basedir = z/Updated open_basedir setting: %s for domain: %si�)�modez/usr/sbin/plesk�binZsitez--update-php-settingsz	-settings)r�r�z Plesk settings update result: %s)r�r��pw_dirrWrX�joinrs�
subprocess�runrPr�rJ�stdout�striprrYrZr�)
rSryr�Z
clwpos_dirZ
custom_phpZcustom_php_fullZsa_lineZupdated_settingZopen_basedir_settingr\rArArB�_prepare_php_for_plesk�s0


z&SmartAdviceUtil._prepare_php_for_pleskc	Cs�|dkr|jgd�}n|j|d�}|�||||�}|�||�}tj|ddd�}|jdkr�|j�dt|j�t|j	�t|j
��td��dS)N)roT)r�r�rzESmart advice plugin failed with exit code: %s, stdout: %s, stderr: %sz'Smart Advice plugin installation failed)rc�!_prepare_smart_advice_script_args�_get_smart_advice_script_cmdr�r��
returncoderPrrJr��stderrr/)	rSryr�r��advices_jsonZjson_string�attrs�commandr\rArArBr��s
z(SmartAdviceUtil._run_smart_advice_script)r�rrVcCsBd}d|��}|�|�}t�}|�d|��}	|j�d|	�yt||�}
Wn$tk
rl|j�d�d}
YnXt|�d|}t|�}xH|D]}
|
�	d�|kr�|
�	d	�}Pq�W|j�
d
|t|��td|����|s�|j�
d|�td
|����|dk�r.y|�
||�Wn"tk
�r,|j�d�YnX|||||
|	g}|S)Nzrun.shz*/opt/alt/php-xray/php/smart-advice-plugin/�|zPANEL LOGIN LINK %szUnable to get user emailsrvrZvhostZ
php_binaryz*Php data for domain %s was not found in %sz%Unable to get php version for domain z)Php version for user: %s was not obtainedz)Php binary was not identified for domain ZPleskz-Setting up php for Plesk for SA plugin failed)rzrrPr�rrwrxrr5r�rrJr/r�)rSryr�r�rZscript_nameZscript_pathZuser_login_linkZpanelZpanel_user_login_linkr�Zfull_website_pathZphp_infoZphp_dataZphp_binary_path�resrArArBr��sF





z1SmartAdviceUtil._prepare_smart_advice_script_args)ryrrVcCsXttj�r d|dg}|�|�n4d|dd|d<dd�|�}dd|d	dd
|g}|S)Nz/sbin/cagefs_enter_userz	/bin/bash�'�z
/bin/bash � Zsudoz-uz-sz-c)rrZCAGEFS�extendr�)ryrrZcommand_strrArArBr��s

z,SmartAdviceUtil._get_smart_advice_script_cmdcCs,t�}|std��t�dt�t||�d��S)z;
        Method with handles work with agreements.
        z)This command can only be executed as userr[)r\r3r�)r2r/r^r_r3r)rS�feature�user_contextrArArB�get_agreement_text�sz"SmartAdviceUtil.get_agreement_textc
Cs�t�}|std��|�|�\}}tjddt|�dddt|�d|jg	ddd	�}|jd
kr�|j�	dt|j�t|j
�t|j��td|j��d
S)z�
        Proxy method to AWP which creates subscription
        listening for the status of module and automatic advice appy.
        z)This command can only be executed as userzcloudlinux-awp-userz--userrIz--listenz--advice-idz	--featureT)r�r�rzESmart advice plugin failed with exit code: %s, stdout: %s, stderr: %sz"cloudlinux-awp-user call failed %sN)r2r/r�r�r�rJr�rrPrr�r)rSrrr�_r�r\rArArB�create_subscription
s$

z#SmartAdviceUtil.create_subscription)F)F)FF)FFr�NFN)FFr�NF)N)N)N)=r<r=r>�__doc__rT�staticmethodrJrQrc�intrfrrprq�boolrtrurzr"r|rrr�r0rrL�objectr�r�r#r�r�r�r1r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rr�r�r
rrArArArBrMNst		

%
/""G*


/
rM)Srr^rOrWr�r�r�Z
contextlibrZdataclassesrrZtypingrrrrZenumr	Zclwpos.user.configr
r}rrZclwpos.papir
rrrrrrrrrrZclcommon.cpapirrrrrrZclcommon.clpwdrZclcommon.constrZadvice_typesr!Zadvice_types.wpos_baser"r�r#Zschemasr$r%r&Z	apiclientr(Zinternal.constantsr)r*r+r,Zinternal.exceptionsr-r.r/Zinternal.user_plugin_utilsr0r1r2Zinternal.utilsr3r4r5r6Zanalytics.utilsr7r�r9rCrMrArArArB�<module>
s<4