
    Mh?X                         d dl mZ d dlZd dlmZ d dlmZ  G d de          Z G d de          Z G d	 d
e          Z	 G d de          Z
 G d de          ZdS )    )TestCaseN)
exceptions)_LATEST_VERSIONc                       e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdS )TestBestMatchc                    t          t          |                              |                    }d| d|d}|                     ||           t	          j        t          |                    }t	          j        t          |                    }|                     |	                                |	                                d| d|            |S )NzNo errors found for z under !)msgzNo consistent best match!
Got: z

Then: )
listr   iter_errors
assertTruer   
best_matchiterreversedassertEqual	_contents)selfinstanceschemaerrorsr
   bestreversed_bests          `/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/jsonschema/tests/test_exceptions.pybest_match_ofzTestBestMatch.best_match_of	   s    of--99(CCDDBhBBvBBBC((($T&\\22"-hv.>.>??NN##%%NtNN}NN	
 	
 	

     c                     ddddddiidii}|                      ddg ii|          }|                     |j        d	           d S )
N
propertiesfoo   bartypeobject)minPropertiesr   r   r   r#   r   r   	validatorr   r   r   s      r   (test_shallower_errors_are_better_matchesz6TestBestMatch.test_shallower_errors_are_better_matches   so    %&#(68*<"= 
 !!EE2;+?!OO99999r   c                     dddiddigddiddigd}|                      i |          }|                     |j        d           dS )	zn
        A property you *must* match is probably better than one you have to
        match a part of.
        r   r!   stringnumber)r#   anyOfoneOfr$   r#   Nr%   r'   s      r   %test_oneOf_and_anyOf_are_weak_matchesz3TestBestMatch.test_oneOf_and_anyOf_are_weak_matches$   so     x(68*<=x(68*<=
 

 !!2f!==99999r   c                     dddddiddddiiigiii}|                      dddii|	          }|                     |j        d           d
S )aL  
        If the most relevant error is an anyOf, then we traverse its context
        and select the otherwise *least* relevant error, since in this case
        that means the most specific, deep, error inside the instance.

        I.e. since only one of the schemas must match, we look for the most
        relevant one.
        r   r   r,   r!   r*   r    array   r$   Nr   r   validator_valuer'   s      r   8test_if_the_most_relevant_error_is_anyOf_it_is_traversedzFTestBestMatch.test_if_the_most_relevant_error_is_anyOf_it_is_traversed2        *%/@'AB	
 !!EE2;+?!OO-w77777r   c                     dddiddiddigi}|                      g |          }|                     |j        d           dS )z
        We don't traverse into an anyOf (as above) if all of its context errors
        seem to be equally "wrong" against the instance.
        r,   r!   r*   integerr"   r$   Nr%   r'   s      r   3test_no_anyOf_traversal_for_equally_relevant_errorszATestBestMatch.test_no_anyOf_traversal_for_equally_relevant_errorsI   c     "#"
 !!2f!==11111r   c                 x    dddigi}|                      g |          }|                     |j        d           dS )z
        We *do* traverse anyOf with a single nested error, even though it is
        vacuously equally relevant to itself.
        r,   r!   r*   r$   Nr%   r'   s      r   6test_anyOf_traversal_for_single_equally_relevant_errorzDTestBestMatch.test_anyOf_traversal_for_single_equally_relevant_errorY   S     "

 !!2f!==00000r   c                     ddddiigi}|                      ddg|          }|                     |j        d           dS )z|
        We *do* traverse anyOf with a single subschema that fails multiple
        times (e.g. on multiple items).
        r,   itemsconst%   r1   r$   Nr%   r'   s      r   .test_anyOf_traversal_for_single_sibling_errorsz<TestBestMatch.test_anyOf_traversal_for_single_sibling_errorsg   [     7B-(

 !!B8F!CC11111r   c                     dddidddiigi}|                      ddg|          }|                     |j        d           d	S )
zg
        We *do* traverse anyOf with multiple subschemas when one does not type
        match.
        r,   r!   r"   r>   r?   r@   r1   r$   Nr%   r'   s      r   9test_anyOf_traversal_for_non_type_matching_sibling_errorszGTestBestMatch.test_anyOf_traversal_for_non_type_matching_sibling_errorsu   c     "7B-(
 !!B8F!CC11111r   c                     dddddiddddiiigiii}|                      dddii|	          }|                     |j        d           d
S )aL  
        If the most relevant error is an oneOf, then we traverse its context
        and select the otherwise *least* relevant error, since in this case
        that means the most specific, deep, error inside the instance.

        I.e. since only one of the schemas must match, we look for the most
        relevant one.
        r   r   r-   r!   r*   r    r0   r1   r$   Nr2   r'   s      r   8test_if_the_most_relevant_error_is_oneOf_it_is_traversedzFTestBestMatch.test_if_the_most_relevant_error_is_oneOf_it_is_traversed   r5   r   c                     dddiddiddigi}|                      g |          }|                     |j        d           dS )z
        We don't traverse into an oneOf (as above) if all of its context errors
        seem to be equally "wrong" against the instance.
        r-   r!   r*   r7   r"   r$   Nr%   r'   s      r   3test_no_oneOf_traversal_for_equally_relevant_errorszATestBestMatch.test_no_oneOf_traversal_for_equally_relevant_errors   r9   r   c                 x    dddigi}|                      g |          }|                     |j        d           dS )z
        We *do* traverse oneOf with a single nested error, even though it is
        vacuously equally relevant to itself.
        r-   r!   r*   r$   Nr%   r'   s      r   6test_oneOf_traversal_for_single_equally_relevant_errorzDTestBestMatch.test_oneOf_traversal_for_single_equally_relevant_error   r<   r   c                     ddddiigi}|                      ddg|          }|                     |j        d           dS )z|
        We *do* traverse oneOf with a single subschema that fails multiple
        times (e.g. on multiple items).
        r-   r>   r?   r@   r1   r$   Nr%   r'   s      r   .test_oneOf_traversal_for_single_sibling_errorsz<TestBestMatch.test_oneOf_traversal_for_single_sibling_errors   rB   r   c                     dddidddiigi}|                      ddg|          }|                     |j        d           d	S )
zg
        We *do* traverse oneOf with multiple subschemas when one does not type
        match.
        r-   r!   r"   r>   r?   r@   r1   r$   Nr%   r'   s      r   9test_oneOf_traversal_for_non_type_matching_sibling_errorszGTestBestMatch.test_oneOf_traversal_for_non_type_matching_sibling_errors   rE   r   c                     dddddiddddiiigiii}|                      dddii|	          }|                     |j        d           d
S )z
        Now, if the error is allOf, we traverse but select the *most* relevant
        error from the context, because all schemas here must match anyways.
        r   r   allOfr!   r*   r    r0   r1   r$   Nr2   r'   s      r   8test_if_the_most_relevant_error_is_allOf_it_is_traversedzFTestBestMatch.test_if_the_most_relevant_error_is_allOf_it_is_traversed   s     *%/@'AB	
 !!EE2;+?!OO-x88888r   c           
          dddddidddiddddiiigigiii}|                      dddii|	          }|                     |j        d           d
S )zp
        We traverse into nested contexts (a oneOf containing an error in a
        nested oneOf here).
        r   r   r-   r!   r*   r    r0   r1   r$   Nr2   r'   s      r   test_nested_context_for_oneOfz+TestBestMatch.test_nested_context_for_oneOf   s     *#!' 2$0(-/@3&!"&	
& !!EE2;+?!OO-w77777r   c                    ddddddddd	giii}|                      dd
i|          }|                     |j        d           dddddd	dddgiii}|                      dd
i|          }|                     |j        d           d S )Nr   r   r,   r0   r   r!   minItemsr*   
   r!   	minLengthr    r$   rZ   r%   r   r   r   	reordereds       r   "test_it_prioritizes_matching_typesz0TestBestMatch.test_it_prioritizes_matching_types  s    !(a88!);;	
 !!E5>&!II555 !);;!(a88	
	 !!E5>)!LL55555r   c                    dddddgdddd	gd
dgiii}|                      ddi|          }|                     |j        d           dddd	d
ddddgiii}|                      ddi|          }|                     |j        d           d S )Nr   r   r,   r0   r"   r   rV   r7   r*   rX   rY   r    r$   rZ   r%   r[   s       r   (test_it_prioritizes_matching_union_typesz6TestBestMatch.test_it_prioritizes_matching_union_types   s    ")8!4!DD"+X!6RHH	
 !!E5>&!II555 !);;!(a88	
	 !!E5>)!LL55555r   c                 x    dddii}|                      ddi|          }|                     |j                   d S )Nr   r   Fr    r$   )r   assertIsNoner&   r'   s      r   test_boolean_schemasz"TestBestMatch.test_boolean_schemas;  sH    /!!E5>&!II$.)))))r   c                     t          ddi          }|                    i           \  }|                     t          j        |                    i                     j        d           d S )Nr#   r   )r   r   r   r   r   r&   )r   r&   errors      r   test_one_errorzTestBestMatch.test_one_error@  sm    #_a$899	&&r**!)"7"7";";<<F	
 	
 	
 	
 	
r   c                     t          i           }|                     t          j        |                    i                                d S )N)r   ra   r   r   r   )r   r&   s     r   test_no_errorszTestBestMatch.test_no_errorsH  sB    #B''	*/	0E0Eb0I0IJJKKKKKr   N)__name__
__module____qualname__r   r(   r.   r4   r8   r;   rA   rD   rG   rI   rK   rM   rO   rR   rT   r]   r_   rb   re   rg    r   r   r   r      sE         
: 
: 
:: : :8 8 8.2 2 2 1 1 12 2 22 2 28 8 8.2 2 2 1 1 12 2 22 2 29 9 9&8 8 886 6 666 6 66* * *

 
 
L L L L Lr   r   c                   &    e Zd Zd Zd Zd Zd ZdS )TestByRelevancec                 0   t          j        ddg          }t          j        dddg          }t          ||gt           j                  }|                     ||           t          ||gt           j                  }|                     ||           d S )NOh no!bazpathOh yes!r   r    key)r   ValidationErrormax	relevanceassertIs)r   shallowdeepmatchs       r   #test_short_paths_are_better_matchesz3TestByRelevance.test_short_paths_are_better_matchesN  s    ,XUGDDD))5%.IIIWdO)=>>>eW%%%T7O)=>>>eW%%%%%r   c                 `   t          j        dg           }t          j        ddg          }t          ||gt           j                  }|                     d |D             dgg g           t          ||gt           j                  }|                     d |D             dgg g           d S )Nro   rq   rs   r   rt   c                 6    g | ]}t          |j                  S rk   r   rr   .0rd   s     r   
<listcomp>zNTestByRelevance.test_global_errors_are_even_better_matches.<locals>.<listcomp>]  "    222%T%*222r   c                 6    g | ]}t          |j                  S rk   r   r   s     r   r   zNTestByRelevance.test_global_errors_are_even_better_matches.<locals>.<listcomp>c  r   r   )r   rv   sortedrx   r   )r   rz   r{   r   s       r   *test_global_errors_are_even_better_matchesz:TestByRelevance.test_global_errors_are_even_better_matchesW  s    ,XB???))5'BBB$Z-ABBB226222WbM	
 	
 	

 wZ-ABBB226222WbM	
 	
 	
 	
 	
r   c                 0   t          j        dg d          }t          j        dg d          }t          j        d          }t          ||g|          }|                     ||           t          ||g|          }|                     ||           d S )Nro   arr   r&   rs   b)weakrt   r   rv   by_relevancerw   ry   )r   r   normalr   r|   s        r   %test_weak_keywords_are_lower_priorityz5TestByRelevance.test_weak_keywords_are_lower_priorityg  s    )(sKKK+IB#NNN,#666
T6N
333eV$$$VTN
333eV$$$$$r   c                 d   t          j        dg d          }t          j        dg d          }t          j        dg d          }t          j        dd          }t          |||g|	          }|                     ||           t          |||g|	          }|                     ||           d S )
Nro   r   r   rs   r   zOh fine!c)r   strongrt   r   )r   r   r   r   r   r|   s         r   (test_strong_keywords_are_higher_priorityz8TestByRelevance.test_strong_keywords_are_higher_prioritys  s    )(sKKK+IB#NNN+JR3OOO,#cBBB
T66*
;;;eV$$$VVT*
;;;eV$$$$$r   N)rh   ri   rj   r}   r   r   r   rk   r   r   rm   rm   M  sP        & & &
 
 
 
% 
% 
%% % % % %r   rm   c                   \    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd ZdS )TestErrorTreec                     d t          d          D             }t          j        |          }|                     |j        d           d S )Nc                 :    g | ]}t          j        d |          S )	Somethingr&   )r   rv   )r   is     r   r   zQTestErrorTree.test_it_knows_how_many_total_errors_it_contains.<locals>.<listcomp>  s8     
 
 
 &{a@@@
 
 
r      )ranger   	ErrorTreer   total_errorsr   r   trees      r   /test_it_knows_how_many_total_errors_it_containsz=TestErrorTree.test_it_knows_how_many_total_errors_it_contains  sW    
 
1XX
 
 
 #F++*A.....r   c                     t          j        ddg          g}t          j        |          }|                     d|           d S )N	a messager    rq   )r   rv   r   assertInr   s      r   1test_it_contains_an_item_if_the_item_had_an_errorz?TestErrorTree.test_it_contains_an_item_if_the_item_had_an_error  sF    ,[wGGGH#F++eT"""""r   c                     t          j        ddg          g}t          j        |          }|                     d|           d S )Nr   r    rq   r   )r   rv   r   assertNotInr   s      r   9test_it_does_not_contain_an_item_if_the_item_had_no_errorzGTestErrorTree.test_it_does_not_contain_an_item_if_the_item_had_no_error  sH    ,[wGGGH#F++%%%%%r   c                     t          j        dd          }t          j        |g          }|                     |j        d|i           d S )Nr   r   r   r   rv   r   r   r   r   rd   r   s      r   /test_keywords_that_failed_appear_in_errors_dictz=TestErrorTree.test_keywords_that_failed_appear_in_errors_dict  sK    *;%HHH#UG,,uen55555r   c                     t          j        ddg          t          j        dddg          g}t          j        |          }|                     d|d                    |                     d|d                    d S )Nza bar messager    rq   za bar -> 0 messager      )r   rv   r   r   r   r   s      r   1test_it_creates_a_child_tree_for_each_nested_pathz?TestErrorTree.test_it_creates_a_child_tree_for_each_nested_path  s    &eWEEE&';5!*MMM
 #F++ae%%%DK(((((r   c                     t          j        ddddg          t          j        ddddg          }}t          j        ||g          }|                     |d         d         j        ||d           d S )	N1r   r    r   )r&   rr   2quux)r   r   r   r   e1e2r   s       r   +test_children_have_their_errors_dicts_builtz9TestErrorTree.test_children_have_their_errors_dicts_built  s    &se5!*MMM&sfE1:NNN  #RH--eQ.B0G0GHHHHHr   c                     t          j        ddddgd          t          j        ddd	d
gd          }}t          j        ||g           d S Nr   r   r    bar2i1r&   rr   r   r   r   foobarr   i2)r   rv   r   )r   r   r   s      r   "test_multiple_errors_with_instancez0TestErrorTree.test_multiple_errors_with_instance  sr    &V_	  
 & ]	    	b"X&&&&&r   c                     t          j        ddg           }t          j        |g          }|                     t                    5  |d          d d d            d S # 1 swxY w Y   d S )N123r   )r&   r   r   )r   rv   r   assertRaises
IndexErrorr   s      r   >test_it_does_not_contain_subtrees_that_are_not_in_the_instancezLTestErrorTree.test_it_does_not_contain_subtrees_that_are_not_in_the_instance  s    *5EBOOO#UG,,z** 	 	GG	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   	AA!$A!c                     t          j        ddi dg          }t          j        |g          }|                     |d         t           j                   dS )z
        If a keyword refers to a path that isn't in the instance, the
        tree still properly returns a subtree for that path.
        r   r   )r&   r   rr   N)r   rv   r   assertIsInstancer   s      r   9test_if_its_in_the_tree_anyhow_it_does_not_raise_an_errorzGTestErrorTree.test_if_its_in_the_tree_anyhow_it_does_not_raise_an_error  s]     *52UG
 
 
 #UG,,d5k:+?@@@@@r   c                     t          j        ddddgd          t          j        ddd	d
gd          }}t          j        ||g          }|                     t	          |          dd	h           d S r   )r   rv   r   r   setr   s       r   	test_iterzTestErrorTree.test_iter  s    &V_	  
 & ]	    #RH--TUH$566666r   c                     t          j        ddddgd          }t          j        |g          }|                     t	          |          d           d S )Nr   r   r    r   r   r   z<ErrorTree (1 total error)>r   rv   r   r   reprr   s      r   test_repr_singlezTestErrorTree.test_repr_single  s`    *	
 
 
 #UG,,d%BCCCCCr   c                     t          j        ddddgd          t          j        ddd	d
gd          }}t          j        ||g          }|                     t	          |          d           d S )Nr   r   r    r   r   r   r   r   r   r   r   z<ErrorTree (2 total errors)>r   r   s       r   test_repr_multiplez TestErrorTree.test_repr_multiple  s    &V_	  
 & ]	    #RH--d%CDDDDDr   c                 t    t          j        g           }|                     t          |          d           d S )Nz<ErrorTree (0 total errors)>)r   r   r   r   )r   r   s     r   test_repr_emptyzTestErrorTree.test_repr_empty  s5    #B''d%CDDDDDr   N)rh   ri   rj   r   r   r   r   r   r   r   r   r   r   r   r   r   rk   r   r   r   r     s        / / /# # #
& & &
6 6 6
) ) )I I I' ' '  
A 
A 
A7 7 7 D D DE E E E E E E Er   r   c                   P    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd ZdS )TestErrorInitReprStrc                 z    t          ddddddi          }|                    |           t          j        di |S )Nhellor!   r*      )messager&   r3   r   r   rk   )dictupdater   rv   )r   kwargsdefaultss      r   
make_errorzTestErrorInitReprStr.make_error  sU    $H%
 
 
 	)55H555r   c                    t          j        |                              d          } | j        di |}t	          |                              d          \  }}}|                     ||j                   |                     ||           d S )N
rk   )textwrapdedentrstripr   str	partitionr   r   )r   expectedr   rd   message_line_rests          r   assertShowsz TestErrorInitReprStr.assertShows  s    ?8,,33D99))&)) #E

 4 4T : :au}555x(((((r   c                 ~    |                                  }|                     t          |j                  d           d S )Nr   )r   assertGreaterlenargs)r   rd   s     r   !test_it_calls_super_and_sets_argsz6TestErrorInitReprStr.test_it_calls_super_and_sets_args  s5    !!3uz??A.....r   c                 r    |                      t          t          j        d                    d           d S )NzHello!r   z<ValidationError: 'Hello!'>)r   r   r   rv   r   s    r   	test_reprzTestErrorInitReprStr.test_repr  s@    +H===>>)	
 	
 	
 	
 	
r   c                    t          j        d          }|                     t          |          d           dddddid}|D ]H}t	          |          }||= t          j        di |}|                     t          |          d           Id S )Nr   r!   r*   r   )r&   r3   r   r   r   )r   rv   r   r   r   )r   rd   r   attrks        r   test_unset_errorz%TestErrorInitReprStr.test_unset_error  s    *955UY///  'x(	
 
  	4 	4DVA$.>>A>>ESZZ3333		4 	4r   c                 6    |                      dg g            d S )Nz
            Failed validating 'type' in schema:
                {'type': 'string'}

            On instance:
                5
            rr   schema_pathr   r   s    r   test_empty_pathsz%TestErrorInitReprStr.test_empty_paths+  s6      	 
	
 
	
 
	
 
	
 
	
r   c                 :    |                      ddgdg           d S )Nz
            Failed validating 'type' in schema:
                {'type': 'string'}

            On instance[0]:
                5
            r   r>   r   r   r   s    r   test_one_item_pathsz(TestErrorInitReprStr.test_one_item_paths8  s:      	 	 
	
 
	
 
	
 
	
 
	
r   c                 >    |                      dddgg d           d S )Nz
            Failed validating 'type' in schema['items'][0]:
                {'type': 'string'}

            On instance[0]['a']:
                5
            r   r   )r>   r   r   r   r   r   s    r   test_multiple_item_pathsz-TestErrorInitReprStr.test_multiple_item_pathsE  s>     S' 	 
	
 
	
 
	
 
	
 
	
r   c                     |                      dt          t          d                    t          t	          t          d          t          d                              d           d S )Na?  
            Failed validating 'maxLength' in schema:
                {0: 0,
                 1: 1,
                 2: 2,
                 3: 3,
                 4: 4,
                 5: 5,
                 6: 6,
                 7: 7,
                 8: 8,
                 9: 9,
                 10: 10,
                 11: 11,
                 12: 12,
                 13: 13,
                 14: 14,
                 15: 15,
                 16: 16,
                 17: 17,
                 18: 18,
                 19: 19}

            On instance:
                [0,
                 1,
                 2,
                 3,
                 4,
                 5,
                 6,
                 7,
                 8,
                 9,
                 10,
                 11,
                 12,
                 13,
                 14,
                 15,
                 16,
                 17,
                 18,
                 19,
                 20,
                 21,
                 22,
                 23,
                 24]
                  	maxLength)r   r   r&   )r   r   r   r   zipr   s    r   test_uses_pprintz%TestErrorInitReprStr.test_uses_pprintR  se    1d %))__E"IIuRyy1122!k 	 6	
 6	
 6	
 6	
 6	
r   c           	      J    |                      ddddddddddd           d S )	Nz
            Failed validating 'type' in schema:
                {'do': 3, 'not': 7, 'sort': 37, 'me': 73}

            On instance:
                {'here': 73, 'too': 37, 'no': 7, 'sorting': 3}
                  r@   I   )donotsortme)heretoonosorting)r   r   r   r   s    r   test_does_not_reorder_dictsz0TestErrorInitReprStr.test_does_not_reorder_dicts  s^     	  	  	 	
 	
 	
 	
 	
r   c                       G  fdd          } |            }t          j        dd|dd          }                     t          |          t	          |                     dS )	z
        Check for #164 which rendered exceptions unusable when a
        `ValidationError` involved instances with an `__eq__` method
        that returned truthy values.
        c                   $    e Zd Z fdZ fdZdS )dTestErrorInitReprStr.test_str_works_with_instances_having_overriden_eq_operator.<locals>.DontEQMeBroc                 2                         d           d S NzDon't!failthisotherr   s     r   __eq__zkTestErrorInitReprStr.test_str_works_with_instances_having_overriden_eq_operator.<locals>.DontEQMeBro.__eq__      		(#####r   c                 2                         d           d S r  r  r  s     r   __ne__zkTestErrorInitReprStr.test_str_works_with_instances_having_overriden_eq_operator.<locals>.DontEQMeBro.__ne__  r  r   N)rh   ri   rj   r  r!  r   s   r   DontEQMeBror    sG        $ $ $ $ $$ $ $ $ $ $ $r   r"  r   r   somer   )r&   r   r3   r   N)r   rv   r   r   r   )r   r"  r   rd   s   `   r   :test_str_works_with_instances_having_overriden_eq_operatorzOTestErrorInitReprStr.test_str_works_with_instances_having_overriden_eq_operator  s    	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ ;==*"
 
 
 	d8nnc%jj11111r   N)rh   ri   rj   r   r   r   r   r   r   r   r   r  r  r$  rk   r   r   r   r     s        	6 	6 	6) ) )/ / /
 
 
4 4 4"
 
 

 
 

 
 
7
 7
 7
r
 
 
.2 2 2 2 2r   r   c                       e Zd Zd ZdS )TestHashablec                 Z    t          j        d          h t          j        d          h d S )N )r   rv   SchemaErrorr   s    r   test_hashablezTestHashable.test_hashable  s0    		#B	'	'((			#	#$$$$r   N)rh   ri   rj   r*  rk   r   r   r&  r&    s#        % % % % %r   r&  )unittestr   r   
jsonschemar   jsonschema.validatorsr   r   rm   r   r   r&  rk   r   r   <module>r.     sL          ! ! ! ! ! ! 1 1 1 1 1 1BL BL BL BL BLH BL BL BLJ
1% 1% 1% 1% 1%h 1% 1% 1%hxE xE xE xE xEH xE xE xEv|2 |2 |2 |2 |28 |2 |2 |2~% % % % %8 % % % % %r   