o
    hp                     @   s
  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZmZmZ d dlmZmZmZmZ d dlmZ e dd	Ze d
dZg dZdd Zdd Z dd Z!dd Z"dd Z#e$e%e&e'e(dej)ej*ej+fZ,dd Z-G dd dej.j/j0Z1dd Z2dOddZ3G d d! d!Z4e4 Z5d"d# Z6d$d% Z7dOd&d'Z8d(d) Z9dPd+d,Z:d-d. Z;d/d0 Z<d1d2 Z=d3d4 Z>d5d6 Z?d7d8 Z@d9d: ZAd;d< ZBd=d> ZCd?d@ ZDdAdB ZEdCdD ZFdEdF ZGdGdH ZHdIdJ ZIdKdL ZJdMdN ZKdS )Q    N)
fake_range)_find_builtin)AttributeTypeIsSupportedChecker)_add_script_class_get_script_class
_python_cu)get_class_propertiesget_default_argsget_jit_class_defget_jit_def)ModuleScriptMethodStub)resolution_callbackdef_original_methodPropertyStub)r   r   )_version_parameters_buffers_non_persistent_buffers_set_backward_hooks_backward_pre_hooks_forward_hooks_forward_hooks_with_kwargs_forward_pre_hooks_forward_pre_hooks_with_kwargs_forward_hooks_always_called_state_dict_hooks_state_dict_pre_hooks_load_state_dict_pre_hooks_load_state_dict_post_hooks_modules_initializingdump_patchesc                 C   sF   t | }|s!t| | j}tjj| }tj||||}t	| | |S N)
r   r
   __name__torchjitfrontendget_default_args_for_class_C_jit_script_class_compiler   )objrcbqualified_namescript_classastdefaults r2   h/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/torch/jit/_recursive.py_compile_and_register_class6   s   
r4   c                 C   s$   t | }t| |dd}t||| S NRecursiveScriptModule	self_name)_jit_internal#createResolutionCallbackFromClosurer   r   )funcnamer-   r0   r2   r2   r3   	make_stubD   s   
r=   c                 C   s"   t | |}t|tr|S t||S r$   )getattr
isinstancer   r=   )	nn_modulemethod_namer;   r2   r2   r3   make_stub_from_methodJ   s   


	rB   c                 C   sD   g }t | D ]}t| |d }t|tjju r|t| | q|S r$   )dirr>   r9   get_torchscript_modifierFunctionModifiersEXPORTappendrB   )modstubsr<   itemr2   r2   r3    make_stubs_from_exported_methodsY   s   rK   c                 C   sF   t | dg }dd }|t| }t }|D ]}||v r || q|S )N__jit_ignored_attributes__c                 S   s   dd t |  D S )Nc                 S   s   h | ]\}}t |tr|qS r2   )r?   property).0kvr2   r2   r3   	<setcomp>l   s    zGjit_ignored_properties.<locals>.get_properties_names.<locals>.<setcomp>)varsitems)moduler2   r2   r3   get_properties_namesk      z4jit_ignored_properties.<locals>.get_properties_names)r>   typesetadd)rT   !user_annotated_ignored_attributesrU   
propertiesuser_annoted_ignored_propertiesignored_attrr2   r2   r3   jit_ignored_propertiesf   s   
r^   c                    sz   t |tr|S t |ttfrt fdd|D S ddd tD }ttdt	t
| d d  d| d		)
Nc                 3   s    | ]	}t  |V  qd S r$   )_get_valid_constant)rN   xattr
owner_typer2   r3   	<genexpr>   s    z&_get_valid_constant.<locals>.<genexpr>z, c                 s   s    | ]}t |V  qd S r$   )r&   typename)rN   typr2   r2   r3   rd      s    z

        'z' object in attribute '.zo' is not a valid constant.
        Valid constants are:
        1. a nn.ModuleList
        2. a value of type {z,}
        3. a list or tuple of (2)
        )r?   _constant_typestuplelistjoin	TypeErrortextwrapdedentr&   re   rW   )rb   rP   rc   	constantsr2   ra   r3   r_      s$   
r_   c                       s   e Zd Z fddZ  ZS )SourceContextc                    s   t  |||| d S r$   )super__init__)selfsourcefilenamefile_linenoleading_whitespace_len	__class__r2   r3   rr      rV   zSourceContext.__init__)r%   
__module____qualname__rr   __classcell__r2   r2   rx   r3   rp      s    rp   c                    sR   t jdk rt| di S t| }|r|S  fdd t| tr!| nt| } |S )N)   
   __annotations__c                    s6   t | }|r	|S | jD ]} |}|r|  S qi S r$   )inspectget_annotations	__bases__)clscls_annotationsbaseget_cls_annotationsr2   r3   r      s   

z,get_annotations.<locals>.get_cls_annotations)sysversion_infor>   r   r   r?   rW   )r,   annotationsr   r2   r   r3   r      s   


r   Tc                    s0  t jt| }t| t jjr|  t| t jjt jj	fr"|
  t| t jjr-|  t| t jjr8|  t|  t| t jjjrFi  t| dg }|| t| } fdd}t }| j D ]+\}}||v rlqc|du sxt|t jsxJ |||\}	}
|||	 dd || qc| j D ]+\}}||v rq|du st|t jsJ |||\}	}
|||	 dd || q| j D ]E\}}||v rq|||\}	}
|du r|||	 dd q|	 r|	  sJ t jj !|	 }nt"||}|#|| || qtt| dd}  D ]\}}t j$%|r'|| q|D ]]}||v r_|| jv r;d	}n|| jv rDd
}n|| jv rMd}nt&dt'(d| d| d q+t)| |spt'(d| d q+t| |}|*|t+||t| j, || q+t| di }|-t.t/| | | D ]\}}|0|| q| j1 D ]\}}|t2v s|3drq||v rƐq||v r͐qt|t j4j5}|r|j6}t78|rzt j9:|}|;|t j<| | W n t=y } zd| }|>|| W Y d}~nd}~ww qt?|}|r%|@|| qt|t j9jAr<|;|t j<| | q|||\}	}|	 rT|||	 dd q|rYdnd}|	B  d| }dt Ct| d| d}|>|| q| jDE D ]}|F| q| jGE D ]}|H| q|S )z
    Build a ConcreteModuleTypeBuilder from an nn.Module.

    This ConcreteModuleType doesn't have a JIT type associated with it yet, it
    must be filled in by the caller.
    rL   c              
      s   d}zP|  v r$ |  t jjjd kr$t jj |  t }t j	|}n%t
|t jjr<t jj|jt }t j	|}nt j|}d}W ||fS W ||fS W ||fS  tyl } ztd|  d| d| |d }~ww )NFforwardTzError inferring type for z: )r&   nnr   r   r'   r   ann_to_typer   r*   InferredTyper?   	AttributerW   _jit_try_infer_typeRuntimeError)r<   rJ   inferredr   	attr_typereclass_annotationsr2   r3   
infer_type   s0   

z/infer_concrete_type_builder.<locals>.infer_typeNTF__constants__r2   	submodulebuffer	parameterz3added_names must be submodule, parameter, or buffer'zA' was found in ScriptModule constants,  but it is a non-constant z. Consider removing it.zb' was found in ScriptModule constants, but was not actually set in __init__. Consider removing it.__overloads____z(This function exists as an attribute on the Python module, but we failed to compile it to a TorchScript function. 
The error stack is reproduced here:
zFIts type was inferred; try adding a type annotation for the attribute. z. zT(This attribute exists on the Python module, but we failed to convert Python type: 'z' to a TorchScript type. ))Ir&   r*   ConcreteModuleTypeBuilderrW   r?   r   
ModuleDictset_module_dict
ModuleList
Sequentialset_module_listParameterListset_parameter_listParameterDictset_parameter_dictr   aoquantizationQuantWrapperr>   add_ignored_attributesr^   rX   r   rS   Tensoradd_attributerY   r   r!   successis_interface_typeConcreteModuleTypefrom_jit_typeget_module_concrete_type
add_moduler9   is_finalAssertionErrorwarningswarnhasattradd_constantr_   r%   updateget_overload_name_mappingget_overload_annotationsadd_overload__dict__ignored_attributes
startswith_opsOpOverloadPacketopr   
isfunctionr'   scriptadd_function_attributer   	Exceptionadd_failed_attributer   add_builtin_functionScriptFunctionreasonre   r   valuesadd_forward_hookr   add_forward_pre_hook)r@   share_typesconcrete_type_builderrZ   ignored_propertiesr   added_namesr<   rJ   r   _sub_concrete_typeconstants_setannhintvalue	overloadsoverloaded_namesisoverloadpacketscripted_fnebuiltin_symbol_namer   inferred_msgadditional_infohookpre_hookr2   r   r3   infer_concrete_type_builder   s  








r   c                   @   sL   e Zd ZU eee eejj	 f e
d< eejj	 e
d< d	ddZdd ZdS )
ConcreteTypeStore
type_storemethods_compiledreturnNc                 C   s   i | _ t | _d S r$   )r   rX   r   )rs   r2   r2   r3   rr     s   zConcreteTypeStore.__init__c                 C   sf   t |}t|}|| jvrg | j|< | j| }|D ]}||r$|  S q| }| j| | |S )zbInfer a ConcreteType from this `nn.Module` instance. Underlying JIT types are re-used if possible.)r   rW   r   equalsbuildrG   )rs   r@   r   nn_module_typeknown_types
known_typeconcrete_typer2   r2   r3   get_or_create_concrete_type  s   



z-ConcreteTypeStore.get_or_create_concrete_type)r   N)r%   rz   r{   dictrW   r   rj   r&   r*   r   r   rX   rr   r   r2   r2   r2   r3   r     s
   
 
r   c                 C   s\   dd |D }dd |D }dd |D }dd |D }dd |D }|  ||||| d S )Nc                 S      g | ]}|j qS r2   r   rN   mr2   r2   r3   
<listcomp>      z<create_methods_and_properties_from_stubs.<locals>.<listcomp>c                 S   r   r2   r   r   r2   r2   r3   r     r   c                 S   s   g | ]}t |jqS r2   )r	   r   r   r2   r2   r3   r         c                 S   r   r2   r   rN   pr2   r2   r3   r     r   c                 S   r   r2   r   r   r2   r2   r3   r     r   )_create_methods_and_properties)r   method_stubsproperty_stubsmethod_defsmethod_rcbsmethod_defaultsproperty_defsproperty_rcbsr2   r2   r3   (create_methods_and_properties_from_stubs  s   
r  c                 C   sL   dd |D }dd |D }dd |D }dd |D }|  |||| d S )Nc                 S   r   r2   r   rN   hr2   r2   r3   r     r   z+create_hooks_from_stubs.<locals>.<listcomp>c                 S   r   r2   r   r  r2   r2   r3   r     r   c                 S   r   r2   r   r  r2   r2   r3   r     r   c                 S   r   r2   r   r  r2   r2   r3   r     r   )_create_hooks)r   
hook_stubspre_hook_stubs	hook_defs	hook_rcbspre_hook_defspre_hook_rcbsr2   r2   r3   create_hooks_from_stubs  s
   r  c                 C   s\   t | tsJ t | tjjrt| dr| jS |rt| }|S t	| |}|
  | }|S )a  
    Get a concrete type for nn_modules.

    If share_types is True, the concrete type is fetched from concrete_type_store.
    If it is False, a new concrete type is created without first searching concrete_type_store.

    Args:
        nn_module:  The original Python nn.Module that we are creating a ScriptModule for.
        share_types = Whether to share underlying JIT types between modules (if possible).

    Returns:
        A concrete type for nn_module.
    _concrete_type)r?   r   r&   r'   ScriptModuler   r  concrete_type_storer   r   set_poisonedr   )r@   r   r   r   r2   r2   r3   r     s   

r   c                 C   sj   t t| }t t| }tt| || t|}tj	|}| j
 D ]
\}}||| q&t|S )z
    Create and return a RecursiveScriptClass instance from a Python object.

    Arguments:
        obj: A Python object.
    )r9   _qualified_namerW   'createResolutionCallbackForClassMethodsr4   r   	get_classr&   r*   _create_object_with_typer   rS   setattrwrap_cpp_class)r,   qualified_class_namer-   class_ty
cpp_objectr<   r   r2   r2   r3   create_script_class  s   
r  Fc                 C   s@   t | tjjr	J t|  t| |}|st |  t| ||S )a  
    Create a new ScriptModule from an nn.Module.

    Args:
        nn_module:  The original Python nn.Module that we are creating a ScriptModule for.
        stubs_fn:  Lambda that takes an nn.Module and generates a list of ScriptMethodStubs to compile.
        share_types:  Whether to share underlying JIT types between modules (if possible).
            NOTE: Only set to False this when we cannot guarantee type sharing will work
                correctly. This only happens today for traced modules, where the same
                module can produce different traced methods depending on the inputs.
        is_tracing: Whether this function is called during tracing or scripting. If tracing,
                we don't need to do AttributeTypeIsSupportedChecker because all the unsupported
                attributes will be baked as constant in the tracing graph. In addition,
                this check significantly slows down the traced modules when the module size is big.
    )	r?   r&   r'   r6   check_module_initializedr   r   checkcreate_script_module_impl)r@   stubs_fnr   
is_tracingr   r2   r2   r3   create_script_module  s   
r#  c                    s`  t j j}t}t\}}t fdd}t jj	|} t
jvrHt || t || t j t
j  t|j D ]	\}	}
|
|j|	< qOt|j D ]	\}	}
|
|j|	< q`tt jjt jjt jjfrd vr|dt d tt jjrd vrt rtt  }|d| d n|d |D ]'}|j!d	u rq|j!j"}||j#$ j$krq%|}t&'|j!|}||j(|< q|D ])}|j#$ j$}%|j#) j$}|j#* }|r%|j$nd	}t+||||j(|< qt,D ] }|v rqt-|d	}t./|t.j0j1u r,t2|| q|S )
aR  
    Convert an nn.Module to a RecursiveScriptModule.

    Args:
        nn_module:  The original Python nn.Module that we are creating a ScriptModule for.
        concrete_type:  The fully initialized ConcreteType of the module.
        stubs_fn:  Lambda that takes an nn.Module and generates a list of ScriptMethodStubs to compile.
    c           	         sJ      D ]}t|}t|tjjr|jn|}|| q 	 D ]B\}}t|}t|t
s;J dt| |j}t|tjjrKt||}nt|tjjrU|}nt||}|| || j|< q$tD ]4}|v rrqkt|d }t|rt|rt|j}|| }t| || qk |rt| || qk | _d S )NzExpected Module but got )get_attributeskeysr>   r?   r&   r'   r   r   r  get_modulesr   rW   jit_typer*   InterfaceTypeinterface_scriptr  r   r!   rC   r   ismethodr9   is_ignored_fn__func____get__is_ignored_attributer  )	script_moduler<   
orig_valuer   module_typescriptedrJ   unbound_functionbound_methodr   
cpp_moduler   r@   r!  r2   r3   init_fn>  sH   




z*create_script_module_impl.<locals>.init_fn__len__zdef __len__(self):
   return 
__contains__z3def __contains__(self, key: str):
   return key in z2def __contains__(self, key: str):
   return False
N)3r&   r*   _create_module_with_typer'  get_property_stubsget_hook_stubsr^   r'   r6   
_constructr  r   r  r  _run_emit_module_hookrY   	enumerate_c_get_forward_pre_hooksr   _get_forward_hooksr   r?   r   r   r   r   _method_namesdefinelenr%  reprrj   r   r%   r   r<   _get_method	functoolswrapsr   getter_namesetter_namerM   rC   r>   r9   rD   rE   COPY_TO_SCRIPT_WRAPPER!add_python_attr_to_scripted_model)r@   r   r!  r   r   r	  r
  r7  r/  idxfnr%  method_stubr<   script_methodwrapped_script_methodproperty_stubproperty_namefgetrL  fsetrJ   r2   r5  r3   r   /  sx   	3







r   c                 C   s<   t | |d }|d u rdS t tjj|d }|d u rdS ||kS )NF)r>   r&   r'   r6   )script_modelrb   script_attrdefault_attrr2   r2   r3   script_model_defines_attr  s   r[  c                 C   s2   t ||rt| |rt| |t|| d S d S d S r$   )r   r[  r  r>   )rX  origrb   r2   r2   r3   rN    s   rN  c                    s   i }t t| D ]L  |v rqt|  d }t|sqt|drT|jd urTt|| j}|d u r0q|j	|v r>t
td|j	 fddtt|D }tt||||< q|S )Nrz   methodc                    s   g | ]
} d  t | qS )r   )str)rN   ir<   r2   r3   r     s    z,get_overload_annotations.<locals>.<listcomp>)rC   rW   r>   callabler   rz   r9   _get_overloaded_methodsry   r,  r   ,get_overload_no_implementation_error_messagerangerF  rj   zip)rH   r^   r   rJ   method_overloadsnamesr2   r`  r3   r     s.   
r   c                 C   sL   i }|   D ]\}}|j}||vrg ||< |D ]\}}|| | qq|S r$   )rS   r%   rG   )overload_infooverload_name_mappingsorig_fnr   original_nameoverload_namer   r2   r2   r3   r     s   r   c                 C   s@   t jj| d t t| }|d u rt| }t	d| d S )Nz>Must explicitly add type annotations to overloaded functions: )
r&   r'   r   get_signaturer   r   r*  r9   r  r   )r;   	signature	qual_namer2   r2   r3   _check_no_signature  s   
rp  c           
      C   s   g }|   D ]7\}}t||jdd}|D ](\}}t| t||jdd}tj| ||}t	|}	|
t|	|| qq|S r5   )rS   r   r%   rp  r&   r*   _replace_overloaded_method_decldeclr9   r:   rG   r   )
rh  overload_stubsrj  r   orig_astrl  overload_fnover_astnew_ast_rcbr2   r2   r3   make_stubs_for_overloads  s"   


ry  c                 C   s   t | tjjs	J t| dstdtt|  dt| dsj| j	 D ]\}}|d urDtjj
|rDtdtt|  d| dq%| j	 D ]!\}}|d uritjj
|ritdtt|  d| dqJd S d S )Nr   r   z=' has not been initialized, did you forget to call 'super()'?remote_parametersz' has uninitialized parameters z'. Did you forget to run a forward pass?z' has uninitialized buffers )r?   r&   r   r   r   r   re   rW   r   rS   r   is_lazyr   )rH   r<   parambufr2   r2   r3   r  )  s(   

r  c                    s:  t   t }g }t dr+t js+t jdd}ttjj	dd}||kr+dg}g }t
 D ]}||v r8q1t |d}t|tjju rL|| q1|| }tt di t |}t| t|}	 _fdd}
t|
|}t }g }|D ]}||v rq~|| || q~ fdd|D }|	| S )	zImplement the default rules for which methods should act as starting points for compilation.

    (TODO add a link when the rules are published).
    r   r,  Nr   c                    s   |  vS r$   r2   )rA   )ri  r2   r3   ignore_overloadedd  s   z3infer_methods_to_compile.<locals>.ignore_overloadedc                       g | ]}t  |qS r2   rB   rN   r]  r@   r2   r3   r   s  r   z,infer_methods_to_compile.<locals>.<listcomp>)r  r^   r   r9   r+  r   r>   r&   r   r   rC   rD   rE   rF   rG   r   r   r   r   ry  r   filterrX   rY   )r@   r   methodsforward_funcmodule_forwardexportedr<   rJ   rh  rs  r~  filtered_methodsuniqueruniqued_methodsrI   r2   )r@   ri  r3   infer_methods_to_compile>  sJ   



r  c                 C   s   t |  i }g }| j D ]0}|j|v r/t|t||j kr.td|j dt| j dn|||j< |t||j qg }| j	 D ]0}|j|v rgt|t||j krftd|j dt| j dn|||j< |t||j qE||fS )z3Return forward hook and pre_hook ScriptModuleStubs.zHook 'z' on zV has at least two different python definitions. Please use unique names for all hooks.z
Pre-hook ')
r  r   r   r%   idr   rW   rG   r=   r   )r@   hook_mapr	  r   r
  r   r2   r2   r3   r=  w  s.   



r=  c                    s   t | }t|dd}i  t|D ]$}t||d}t|tr4|js,td| d| j dt	
|j |< q fdd|D }|S )	zjCreate property stubs for the properties of the module by creating method stubs for the getter and setter.r6   r7   Nz	Property z of z must have a getterc                    s    g | ]}t  | j |qS r2   )r   r<   )rN   r0   rcbsr2   r3   r     s     z&get_property_stubs.<locals>.<listcomp>)rW   r   rC   r>   r?   rM   rV  r   r%   r9   r:   )r@   	module_typroperties_astsr<   rJ   rI   r2   r  r3   r<    s   
r<  c                    s0   t |tjjr	|S t|  fdd}t||S )a   
    Make a ScriptModule from an nn.Module, using the interface methods rule for determining which methods to compile.

    Args:
        mod_interface: the interface type that the module have
        nn_module:  The original Python nn.Module that we are creating a ScriptModule for.
    c                    s    fdd  D }|S )zRule to infer the methods from the interface type.

        It is used to know which methods need to act as starting points for compilation.
        c                    r  r2   r  r  r  r2   r3   r     s    zPinterface_script.<locals>.infer_interface_methods_to_compile.<locals>.<listcomp>)getMethodNames)r@   rI   mod_interfacer  r3   "infer_interface_methods_to_compile  s   
z<interface_script.<locals>.infer_interface_methods_to_compile)r?   r&   r'   r  r  r#  )r  r@   r  r2   r  r3   r)    s
   
r)  c                 C   sz   t | rd S t| tjjrd S t| s%t| s%t	d|  d|  dt
| dr.|  n| } t | }tjj| |dS )N`z|` is not a function. Recursive scripting only supports Python functions or methods currently.
Consider manually annotating `z` with @torch.jit.script.__prepare_scriptable__)rx  )r9   r+  r?   r&   r   r   r   r   r*  r   r   r  r:   r'   r   )rP  locr-   r2   r2   r3   try_compile_fn  s   

r  c                 C   s   t j| S )z;Wrap this torch._C.Object in a Python RecursiveScriptClass.)r&   r'   RecursiveScriptClass)	cpp_classr2   r2   r3   r    s   r  c                 C   s   dd }t jj| |S )zYWrap this torch._C.ScriptModule in a Python ScriptModule, recursively for all submodules.c                 S   s   t j| j D ]\}}t| |t| q	t jj| j	 | _
t| j D ]	\}}|| j|< q(t| j D ]	\}}|| j|< q9d S r$   )r&   r*   r   rA  rS   r  wrap_cpp_moduler   r   _typer  r@  rB  r   rC  r   )r/  r<   r6  rO  rP  r2   r2   r3   r7    s   z wrap_cpp_module.<locals>.init_fn)r&   r'   r6   r>  )r6  r7  r2   r2   r3   r    s   r  c                 C   sX   t |rd S t||j}tj   t| |fd W d    |S 1 s%w   Y  |S )Nr2   )r9   r+  r=   r%   r&   _disable_emit_hooksr  )r   rP  stubr2   r2   r3   compile_unbound_method  s   

r  c                    s.    fdd}|_ j|_tj| |S )z
    Return a function that lazily binds `unbound_method` to a provided Module IValue, then invokes the method.

    We do this so that any Python shenanigans that
    will poison type sharing are impossible at compile time.
    c                    s0    fdd}t jj| |}t|}|| S )Nc                    s\    j }t|D ]}t||d }t|rt| || q   D ]
\}}t| || q!d S r$   )py_classrC   r>   r9   r+  r  get_constantsrS   )r/  
orig_classr<   rJ   r   )r   r2   r3   r7    s   
z7lazy_bind.<locals>.lazy_binding_method.<locals>.init_fn)r&   r'   r6   r>  types
MethodType)r6  argsr7  r/  r]  r   unbound_methodr2   r3   lazy_binding_method  s   z&lazy_bind.<locals>.lazy_binding_method)original_fnr%   r&   r9   copy_torchscript_modifier)r   r  r  r2   r  r3   	lazy_bind  s
   r  )T)TF)LcollectionsrI  r   r   rm   r  r   r&   torch._jit_internalr9   torch._sourcesr   torch.jit._builtinsr   torch.jit._checkr   torch.jit._stater   r   r   torch.jit.frontendr   r	   r
   r   torch.nnr   
namedtupler   r   r   r4   r=   rB   rK   r^   boolfloatintr^  rW   devicelayoutdtyperh   r_   r*   _jit_tree_viewsSourceRangeFactoryrp   r   r   r   r  r  r  r   r  r#  r   r[  rN  r   r   rp  ry  r  r  r=  r<  r)  r  r  r  r  r  r2   r2   r2   r3   <module>   s   
 o

!
  
 9"