a fŸWc†}ã@s*dZddlmZddlZddlZddlmZddlZddlm Z m Z ddl m Z m Z ddlmZmZmZddlmmZddlmZmZdd lmZeeƒZd d „ZGd d „d eƒZGdd„deƒZGdd„deƒZ Gdd„dej!ƒZ"Gdd„dej#ej$ƒZ%edƒZ&Gdd„deƒZ'Gdd„deƒZ(dS)z>tests for passlib.hash -- (c) Assurance Technologies 2003-2009é)Úwith_statementN)Ú getLogger)Úldap_md5Ú sha256_crypt)ÚMissingBackendErrorÚPasslibHashWarning)Ú str_to_uasciiÚ uascii_to_strÚunicode)Ú HandlerCaseÚTestCase)Úucs‡‡fdd„‰tˆ|ƒƒS)z1generate all strings of given size using alphabetc3sD|dkrˆD] }|Vq n&ˆD] }ˆ|dƒD]}||Vq.qdS)Néé©)ÚsizeÚcharÚtail©ÚalphabetÚhelperrúE/usr/lib/python3.9/site-packages/passlib/tests/test_utils_handlers.pyrs  z_makelang..helper)Úset)rrrrrÚ _makelangsrc@speZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„ZdS)Ú SkeletonTestztest hash support classescsžG‡fdd„dtjƒ‰| ˆ tdƒ¡¡| ˆ d¡¡| ˆ tdƒ¡¡| ˆ tdƒ¡¡| ˆ d¡¡| ˆ tdƒ¡¡| ˆ td ƒ¡¡| ˆ td ƒ¡¡| tˆjd ¡| tˆjd ¡| ˆ  ¡ˆ  d ¡¡| ˆ  dd¡¡| ˆ  dtdƒ¡¡| ˆ  dd¡¡| ˆ  dtdƒ¡¡| ˆj dddd¡| t ˆj dd¡| t ˆj dtdƒ¡| ˆ  d¡d¡| ˆj dddd¡d S)ztest StaticHandler classcsDeZdZdZdZedƒZedƒZdZd ‡‡fdd„ Z d d „Z ‡Z S) z/SkeletonTest.test_00_static_handler..d1Úd1©ÚflagÚ_ÚabrFcs tˆ|ƒjfi|¤Ž||_dS©N)ÚsuperÚ__init__r)ÚselfrÚkwds)Ú __class__rrrr"9sz8SkeletonTest.test_00_static_handler..d1.__init__cSs|jrtdƒStdƒS)NÚbÚa)rr ©r#ÚsecretrrrÚ_calc_checksum=sz>SkeletonTest.test_00_static_handler..d1._calc_checksum)F) Ú__name__Ú __module__Ú __qualname__ÚnameZ context_kwdsr Z _hash_prefixÚchecksum_charsÚ checksum_sizer"r*Ú __classcell__r©r)r%rr2srZ_as_aZ_bZ_cs_cr'r&ÚcNrÚÚss_bTr) ÚuhÚ StaticHandlerÚ assertTrueÚidentifyr Ú assertFalseÚ assertRaisesÚ TypeErrorÚ assertEqualÚ genconfigÚhashÚverifyÚ ValueError©r#rr2rÚtest_00_static_handler/s*z#SkeletonTest.test_00_static_handlercCsŽGdd„dtjƒ}| d¡| d¡}Wdƒn1s<0Y| |d¡| | d|¡¡| | d|¡¡|`|  t |jd¡dS)ztest StaticHandler legacy attrc@s4eZdZdZedd„ƒZedd„ƒZedd„ƒZdS) z3SkeletonTest.test_01_calc_checksum_hack..d1rcSs<|rt|ƒdkrdSzt|dƒWnty6YdS0dS)Né(FéT)ÚlenÚintrA©Úclsr?rrrr9fs z.d1.identifycSsP|durtdƒ‚t|tƒr$| d¡}|dur>| |¡s>tdƒ‚t d|¡ ¡S)Nzno secret providedúutf-8z invalid hashsxyz) r<Ú isinstancer Úencoder9rAÚhashlibÚsha1Ú hexdigest©rIr)r?rrrÚgenhashps  z;SkeletonTest.test_01_calc_checksum_hack..d1.genhashcSs$|durtdƒ‚| ||¡| ¡kS)Nzno hash specified)rArQÚlowerrPrrrr@{sz:SkeletonTest.test_01_calc_checksum_hack..d1.verifyN)r+r,r-r.Ú classmethodr9rQr@rrrrrcs  rz%d1.*should be updated.*_calc_checksumÚtestNZ(7c622762588a0e5cc786ad0a143156f9fd38eea3Zxtest) r6r7ÚassertWarningListr?r=r8r@r:rQr;ÚNotImplementedError)r#rr?rrrÚtest_01_calc_checksum_hack]s ( z'SkeletonTest.test_01_calc_checksum_hackcCsGdd„dtjƒ}| t|jd¡| t|jd¡| | d¡¡| | d¡¡| | d¡¡t t dƒ¡|_ | t|jd¡| t|jd¡| | d ¡¡| | d¡¡|` t d ƒ|_ | t|jd¡| t|jd¡| | d ¡¡| | d¡¡|` dS) ztest GenericHandler.identify()c@seZdZedd„ƒZdS)z)SkeletonTest.test_10_identify..d1cSs2t|tƒr| d¡}|tdƒkr*||dSt‚dS)NÚasciir'©Úchecksum)rKÚbytesÚdecoder rArHrrrÚ from_string“s     z5SkeletonTest.test_10_identify..d1.from_stringN)r+r,r-rSr]rrrrr’srNrr4r'r&z@.z@aú!z!a) r6ÚGenericHandlerr;r<r9r:r8ÚreÚcompiler Ú _hash_regexÚident)r#rrrrÚtest_10_identifys$  zSkeletonTest.test_10_identifycs¬Gdd„dtjƒ‰d ‡fdd„ }| t|tdƒ¡| |tdƒƒtdƒ¡| |tdƒƒtdƒ¡| t|td ƒ¡| t|td ƒ¡| t|d ¡| ˆƒjtdƒ¡dS) z%test GenericHandler checksum handlingc@seZdZdZdZedƒZdS)z.SkeletonTest.test_11_norm_checksum..d1réÚxzN)r+r,r-r.r0r r/rrrrr¶srNcsˆfd|i|¤ŽjS)NrZrY)rZÚkr2rrÚ norm_checksum»sz9SkeletonTest.test_11_norm_checksum..norm_checksumÚxxxZxxxxZxzxzZxxxxxÚxxyxsxxyx)N)r6r_r;rAr r=r<Ú_stub_checksum©r#rhrr2rÚtest_11_norm_checksum³s z"SkeletonTest.test_11_norm_checksumcsXGdd„dtjtjƒ‰‡fdd„}| |dƒd¡| t|tdƒ¡| ˆƒjd¡dS) z*test GenericHandler + HasRawChecksum mixinc@seZdZdZdZdS)z2SkeletonTest.test_12_norm_checksum_raw..d1rreN)r+r,r-r.r0rrrrrÙsrcsˆ|i|¤ŽjSr rY)r'rgr2rrrhÝsz=SkeletonTest.test_12_norm_checksum_raw..norm_checksums1234rjsN)r6ZHasRawChecksumr_r=r;r<r rkrlrr2rÚtest_12_norm_checksum_raw×s  z&SkeletonTest.test_12_norm_checksum_rawcsPGdd„dtjtjƒ‰‡fdd„}‡fdd„}tddƒ}tdd ƒ}tdd ƒ}| t|¡|jt|d d | |d d|¡tjd d”}|jt |dd |jt |dd |  |¡|  |dd d¡|  |dd d¡|  |dd d¡|  |¡|jt |dd |  |¡Wd ƒn1s"0Ytjd dª}| t |d¡| t |d¡|  |¡| |dƒ|¡| |d ƒ|¡| |d ƒ|¡|  |¡| t |d¡|  |¡| |dd d|¡|  |dg¡Wd ƒn1sê0Yˆ` |  g¡8|  t|d ƒƒd ¡|  t|dƒƒd¡Wd ƒn1sB0Yd S)z#test GenericHandler + HasSalt mixinc@s$eZdZdZdZdZdZdZdZdS)z*SkeletonTest.test_20_norm_salt..d1r©ÚsaltrreérN) r+r,r-r.Ú setting_kwdsÚ min_salt_sizeÚ max_salt_sizeZdefault_salt_sizeÚ salt_charsrrrrrïs rcsˆfi|¤ŽjSr ro©rgr2rrÚ norm_salt÷sz1SkeletonTest.test_20_norm_salt..norm_saltcsˆjfd|i|¤ŽddjS)NZ salt_sizeT©Z use_defaults)Zusingrp)Zszrgr2rrÚgen_saltúsz0SkeletonTest.test_20_norm_salt..gen_saltrrrqreNroTrx©Úrecordr4r'ZabaZabbaZaaaabbrré)Zrelaxedzsalt_size.*above max_salt_size)r6ÚHasSaltr_rr;r<ZassertInÚwarningsÚcatch_warningsrAÚconsumeWarningListr=rtrUrF)r#rwryZsalts2Zsalts3Zsalts4Úwlogrr2rÚtest_20_norm_saltìsF        *   . zSkeletonTest.test_20_norm_saltcsGdd„dtjtjƒ‰‡fdd„}| t|¡|jt|dd| |ddd ¡|jt|d dtjdd „}|jt|d d|  |¡| |d dd ¡| |d dd ¡| |ddd¡|  |¡|jt|dd|  |¡Wdƒn1sö0Ydˆ_ |jt|dddS)z%test GenericHandler + HasRounds mixinc@s eZdZdZdZdZdZdZdS)z,SkeletonTest.test_30_init_rounds..d1r©ÚroundsrrqrN)r+r,r-r.rrZ min_roundsÚ max_roundsÚdefault_roundsrrrrr8s rcsˆfi|¤ŽjSr rƒrvr2rrÚ norm_rounds@sz5SkeletonTest.test_30_init_rounds..norm_roundsNrƒTrxrgø?rzrrrqre) r6Z HasRoundsr_r;r<r=r~rrAr€r†)r#r‡rrr2rÚtest_30_init_rounds5s"    (z SkeletonTest.test_30_init_roundscCsRGdd„dtjtjƒ}| t|j¡| t|j¡| t|jd¡| t|jd¡| | ¡¡d|_ |ƒ}|  |  d¡d¡| d¡| d¡|  |  d¡d¡| t|jd¡|  | d¡¡| | d¡¡d|_ |  | ¡¡| d¡|  |  d¡d¡| t|jd ¡| t|jd ¡| d¡Gd d „d |ƒ}| t|jd¡d S) z+test GenericHandler + HasManyBackends mixinc@sHeZdZdZdZdZdZdZedd„ƒZ edd„ƒZ d d „Z d d „Z d S)z)SkeletonTest.test_40_backends..d1rr©r'r&FcSs|jr| |j¡dSdSdS©NTF)Ú _enable_aÚ_set_calc_checksum_backendÚ_calc_checksum_a©rIrrrÚ_load_backend_ajs z9SkeletonTest.test_40_backends..d1._load_backend_acSs|jr| |j¡dSdSdSrŠ)Ú _enable_brŒÚ_calc_checksum_brŽrrrÚ_load_backend_brs z9SkeletonTest.test_40_backends..d1._load_backend_bcSsdS©Nr'rr(rrrrzsz:SkeletonTest.test_40_backends..d1._calc_checksum_acSsdS©Nr&rr(rrrr‘}sz:SkeletonTest.test_40_backends..d1._calc_checksum_bN) r+r,r-r.rrÚbackendsr‹rrSrr’rr‘rrrrras  rÚanyÚdefaultTr5r&r'r3c@seZdZdZdS)z)SkeletonTest.test_40_backends..d2TN)r+r,r-Ú_has_backend_arrrrÚd2¦sr™N)r6ÚHasManyBackendsr_r;rÚ get_backendÚ set_backendr:Ú has_backendrr=r*r8r‹rAÚAssertionError)r#rÚobjr™rrrÚtest_40_backends_s0     zSkeletonTest.test_40_backendscCs8tjdtddGdd„dtjtjƒ}| t|j¡| t|j ¡| t|j d¡| t|j d¡|  |  ¡¡d|_ |ƒ}|  | d ¡d ¡|  d ¡|  d¡|  | d ¡d ¡| t|j d ¡| |  d ¡¡|  |  d ¡¡d|_| |  ¡¡|  d ¡|  | d ¡d ¡| t|j d ¡| t|j d ¡d S)z.d1rrr‰FcSsdSr“rr(rrrrºsz:SkeletonTest.test_41_backends..d1._calc_checksum_acSsdSr”rr(rrrr‘½sz:SkeletonTest.test_41_backends..d1._calc_checksum_bN) r+r,r-r.rrr•r˜Ú_has_backend_brr‘rrrrr±srr–r—Tr5r&r'r3N)r~ÚfilterwarningsÚDeprecationWarningr6ršr_r;rr›rœr:rr¤r=r*r8r˜rA)r#rrŸrrrÚtest_41_backendsªs2þ   zSkeletonTest.test_41_backendscshGdd„dtjtjƒ‰‡fdd„}| t|¡|jt|dd| |ddtd ƒ¡| |td ƒdtd ƒ¡| |td ƒdtd ƒ¡|jt|td ƒd| |td ƒdtd ƒ¡|jt|td ƒd| ˆ  tdƒ¡¡| ˆ  tdƒ¡¡|  ˆ  tdƒ¡¡|  ˆ  td ƒ¡¡|  ˆ  tdƒ¡¡| tˆj d¡| tˆj d¡dˆ_ |jt |dddS)z#test GenericHandler + HasManyIdentsc@s<eZdZdZdZedƒZedƒedƒfZedƒedƒiZdS)z+SkeletonTest.test_50_norm_ident..d1r©rcú!Aú!BÚAN) r+r,r-r.rrr Ú default_identÚ ident_valuesZ ident_aliasesrrrrrçs rcsˆfi|¤ŽjSr r¨rvr2rrÚ norm_identîsz3SkeletonTest.test_50_norm_ident..norm_identNr¨Trxr©rªz!Cr«ÚBz!Axxxz!Bxxxz!Cxxxr4r) r6Z HasManyIdentsr_r;r<r=r rAr8r9r:r¬rž)r#r®rr2rÚtest_50_norm_identäs&  zSkeletonTest.test_50_norm_identc CsBddlm}|j d¡}| |tdƒtdƒdœ¡d}tdƒ}td ƒ}|j |¡}| |t|d d |d ¡|jj|d d}| |t|d d d¡|jj|d d}| |td d tdƒtdƒd¡|j d¡}| |ttdƒtdƒdd¡d}|j |¡}| |tdddd¡|jj|d d}| |ttdƒdtdƒd¡d S)!ztest parsehash()r©r?Z OgAwTx2l6NADIZ AwTx2l6NADIZOg©rZrpz?$5$LKO/Ute40T3FNF95$U0prpBQd4PloSGU0pnpM4z9wKn4vZ1.jsrzQfPqxph9zLKO/Ute40T3FNF95z+U0prpBQd4PloSGU0pnpM4z9wKn4vZ1.jsrzQfPqxph9iˆT)rpr„Úimplicit_roundsrZFrY)rpr„r³)ZsanitizezLK**************z+U0pr***************************************)r„r³rprZzL$5$rounds=10428$uy/jIAhCetNCTtb0$YWvUOXbkqlqhyoPMpN8BMe.ZGsGx2aBvxTvDFI613c3z+YWvUOXbkqlqhyoPMpN8BMe.ZGsGx2aBvxTvDFI613c3zuy/jIAhCetNCTtb0i¼()rZrpr„z@$pbkdf2$60000$DoEwpvQeA8B4T.k951yLUQ$O26Y3/NJEiLCVaOVPxGXshyjW8ks;n˜ßóI"ÂU£•?—²£[Éi`ês0¦ôÀxOé=ç\‹Q©rZr„rpzO26************************zDo********************N) Úpasslibr?Ú des_cryptZ parsehashr=r rÚdictÚ pbkdf2_sha1)r#r?ÚresultÚhr5r3Úh1rrrÚtest_91_parsehashsH    ÿ þ ý ýýzSkeletonTest.test_91_parsehashcCs”ddlm}| |j ¡dddœ¡| |j ¡dddœ¡| |jdd ¡| |j ¡d d d d œ¡| |jdd¡| |j ¡dddd œ¡dS)ztest bitsize()rr±éBé r²éºé„r†iiéé`r´ié é é€N) rµr?r=r¶ZbitsizeZbcryptZ patchAttrrr¸©r#r?rrrÚtest_92_bitsizeJs  ÿ ÿ  ÿ  ÿzSkeletonTest.test_92_bitsizeN)r+r,r-Ú__doc__rCrWrdrmrnr‚rˆr r§r°r¼rÇrrrrr)s.3#$I*K:.8rc@s(eZdZdZdd„Zdd„Zdd„ZdS) Údummy_handler_in_registryz6context manager that inserts dummy handler in registrycCs(||_td|tjft|ddƒ|_dS)NZdummy_r)r.rr)r.Útyper6r_r·Údummy)r#r.rrrr"ps þz"dummy_handler_in_registry.__init__cCsDddlm}|j|jdd| |j¡| |j¡|jus>J‚|jS©Nr)ÚregistryF)Z locations)rµrÍÚ_unload_handler_namer.Zregister_crypt_handlerrËZget_crypt_handler)r#rÍrrrÚ __enter__ws   z#dummy_handler_in_registry.__enter__cGs ddlm}|j|jdddSrÌ)rµrÍrÎr.)r#Úexc_inforÍrrrÚ__exit__~s z"dummy_handler_in_registry.__exit__N)r+r,r-rÈr"rÏrÑrrrrrÉnsrÉc@sPeZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z dS)ÚPrefixWrapperTestztest PrefixWrapper classcCs†tjdddddd}| |jd¡| |jd¡| |jt¡| |jt¡tdƒ}| |jt¡Wdƒn1sx0YdS)z*test PrefixWrapper lazy loading of handlerrrú{XXX}ú{MD5}T)ZlazyN) r6Ú PrefixWrapperr=Ú _wrapped_nameÚassertIsÚ_wrapped_handlerÚwrappedrrÉ©r#rrËrrrÚtest_00_lazy_loading…s z&PrefixWrapperTest.test_00_lazy_loadingcCstt dddd¡}| |jd¡| |jt¡| |jt¡tdƒ}| |jt¡Wdƒn1sf0YdS)z,test PrefixWrapper active loading of handlerrrrÓrÔN) r6rÕr=rÖr×rØrrÙrÉrÚrrrÚtest_01_active_loading•s  z(PrefixWrapperTest.test_01_active_loadingcCstt dtdd¡}| |jd¡| |jt¡| |jt¡tdƒ}| |jt¡Wdƒn1sf0YdS)z4test PrefixWrapper with explicitly specified handlerrrÓrÔNr) r6rÕrr=rÖr×rØrÙrÉrÚrrrÚtest_02_explicit¢s  z"PrefixWrapperTest.test_02_explicitcCstt dddd¡}| |jd¡| |jtj¡| dt|ƒv¡t ddd¡}| |jt j¡|  dt|ƒv¡dS)NrrrÓrÔr…r™r) r6rÕr=r.r×rrrr:Údirrr8)r#rr™rrrÚtest_10_wrapped_attributes°sz,PrefixWrapperTest.test_10_wrapped_attributescCsºt dddd¡}d}d}| | ¡d¡| t|jdd¡| | d|¡|¡| t|jd|¡| | d¡|¡|  |  |¡¡|  |  |¡¡| t|j d|¡|  |  d|¡¡dS) NrrrÓrÔz{XXX}X03MO1qnZdYdgyfeuILPmQ==z{MD5}X03MO1qnZdYdgyfeuILPmQ==z{XXX}1B2M2Y8AsgTpgAmY7PhCfg==Úpassword) r6rÕr=r>r;r<rQrAr?r8r9r:r@)r#rZdphZlphrrrÚtest_11_wrapped_methodsºsz)PrefixWrapperTest.test_11_wrapped_methodscCsÔt ddd¡}| |jtdƒ¡| |jd¡t ddd¡}| |jd¡| |jd¡t dddd¡}| |jd¡| |jd¡tjdddd d }| |jtd ƒ¡| |jd¡tjdddd d }|jttjdddd d |jttjdddd d t ddd¡}| |jd¡| |jtdƒtdƒf¡tjddddd }| |jtdƒ¡| |jd¡|jttjdddd |  d¡"tjddddd}Wdƒn1sª0Y| |jd¡| |jd¡dS)NÚh2rrÓz {XXX}{MD5}r¶r»rÔZh3z{Xr¨z{XXX}Az{XYz{XXXXZh4Zphpassz{XXX}$P$z{XXX}$H$Zh5TZh6z#orig_prefix.*may not work correctlyZh7ú$ú?)Ú orig_prefixÚprefix) r6rÕr=rcr r×r­r;rArU©r#rºrrrÚ test_12_identÒs<ÿÿ 2zPrefixWrapperTest.test_12_identcCs&tjddddd}| t|ƒd¡dS)z test repr()râÚ md5_cryptrÓz$1$©råzÀ(?x)^PrefixWrapper\( ['"]h2['"],\s+ ['"]md5_crypt['"],\s+ prefix=u?["']{XXX}['"],\s+ orig_prefix=u?["']\$1\$['"] \)$N)r6rÕZ assertRegexÚreprrçrrrÚ test_13_reprs ÿzPrefixWrapperTest.test_13_reprcCs$tjdddd}| t|jd¡dS)ztest orig_prefix sanity checkrâréz$6$rêrTN)r6rÕr;rAr?rçrrrÚtest_14_bad_hash sz"PrefixWrapperTest.test_14_bad_hashN) r+r,r-rÈrÛrÜrÝrßrárèrìrírrrrrÒ‚s  / rÒc@s&eZdZdZdZejZdZdd„Z dS)Ú UnsaltedHashz!test algorithm which lacks a saltZunsalted_test_hashrDcCs.t|tƒr| d¡}d|}tt |¡ ¡ƒS)NrJsboblious)rKr rLrrMrNrO©r#r)Údatarrrr*s  zUnsaltedHash._calc_checksumN) r+r,r-rÈr.r6ÚLOWER_HEX_CHARSr/r0r*rrrrrîs rîc@sXeZdZdZdZdZdZdZdZe j Z Z e  edƒ¡Zedd „ƒZd d „Zd d „ZdS)Ú SaltedHashztest algorithm with a saltZsalted_test_hashrorrerDz^@salt[0-9a-f]{42,44}$cCsF| |¡stj |¡‚t|tƒr*| d¡}||dd…|dd…dS)NrXr|iØÿÿÿ)rprZ)r9r6ÚexcZInvalidHashErrorrKr[r\rHrrrr]0s     zSaltedHash.from_stringcCstdƒ|j|jf}t|ƒS)Nz @salt%s%s)r rprZr rÆrrrÚ to_string8szSaltedHash.to_stringcCsBt|tƒr| d¡}|j d¡||j d¡}tt |¡ ¡ƒS)NrJrX)rKr rLrprrMrNrOrïrrrr*<s  zSaltedHash._calc_checksumN)r+r,r-rÈr.rrrsrtr0r6rñrur/r`rar rbrSr]rôr*rrrrrò$s  ròuΙωαννηςc@s$eZdZeZdedfgZdd„ZdS)ÚUnsaltedHashTest)ràZ(61cfd32684c47de231f1f982c214e884133762c0Z(96b329d120b97ff81ada770042e44ba87343ad2bcCs&|jttdd|jttjdddS)NÚxrorrƒ)r;r<rîr>rBrrrÚ test_bad_kwdsSszUnsaltedHashTest.test_bad_kwdsN)r+r,r-rîÚhandlerÚ UPASS_TEMPÚknown_correct_hashesr÷rrrrrõKs þrõc@s$eZdZeZdedfgZdd„ZdS)ÚSaltedHashTest)ràz/@salt77d71f8fe74f314dac946766c1ac4a2a58365482c0z1@salt9f978a9bfe360d069b0c13f2afecd570447407fa7e48cCs4tddj}|jtt|dd|jtt|dddS)NTrxr²ri)ròrkr;r<rA)r#Zstubrrrr÷_s zSaltedHashTest.test_bad_kwdsN)r+r,r-ròrørùrúr÷rrrrrûWs þrû))rÈZ __future__rr`rMZloggingrr~Z passlib.hashrrZ passlib.excrrZpasslib.utils.compatrr r Zpasslib.utils.handlersZutilsÚhandlersr6Zpasslib.tests.utilsr r r r+ÚlogrrÚobjectrÉrÒr7rîr}r_ròrùrõrûrrrrÚs4   I %