ó
    v´jž  ã                  ó(  • S r SSKJr  SSKrSSKJs  Jr  SSK	r	SSK
r
SSKJr  SrSrSr\R                   " SS	\S
SS9rSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jrSS jr SS jr!SS jr"g)a  The session cookie and sign-in state the app and the wake function share.

These are the pure parts of the sign-in: what a cookie or a ``state`` holds,
and which ones are refused. The call to WorkOS is exercised end to end on a
running playground, not here.
é    )ÚannotationsN)Úsessionztest-secretÚ
org_quberag   €tÒÚAÚuser_1zperson@example.comÚmemberÚ	session_1)Úuser_idÚemailÚorganization_idÚroleÚsidc                 ó²  • [         R                  " [        [        [        S9n [         R
                  nSn[        U-   o1" [        [        XS9oD[        :H  oU(       Gds  [        R                  " SU4SU[        45      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS	[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS	[        R                  " U5      [        R                  " U5      S
[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS
S.	-  nSSU0-  n[        [        R                  " U5      5      eS =n=n=n=pEg )N©Únowé<   ©ú==)zz%(py11)s
{%(py11)s = %(py2)s
{%(py2)s = %(py0)s.verify
}(%(py3)s, %(py4)s, %(py5)s, now=(%(py6)s + %(py8)s))
} == %(py13)sr   ÚSECRETÚORGÚtokenÚNOWÚIDENTITY)	Úpy0Úpy2Úpy3Úpy4Úpy5Úpy6Úpy8Úpy11Úpy13úassert %(py15)sÚpy15)r   Úissuer   r   r   Úverifyr   Ú
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanation)r   Ú@py_assert1Ú@py_assert7Ú@py_assert9Ú@py_assert10Ú@py_assert12Ú@py_format14Ú@py_format16s           Ú7/home/mande/repo/quber/tests/playground/test_session.pyÚ;test_a_cookie_checks_back_to_the_identity_it_was_issued_forr6      sV  € Ü�MŠMœ&¤(´Ñ4€EÜ�>‰>ÐG¸ÐG´#¸±(ÐGˆ>œ&¤# uÑ;ÐG¼xÑG×G×G×GÓGÐ;¼x×G×G×G×G×GÕGŒ7×G×G×GÑGŒ7×G×GÕGˆ>×G×G×G×G×GÔGœ&×G×G×GÑGœ&×G×G×G×G×GÖG¤#×G×G×GÑG¤#×G×G×G×G×GÖG u×G×G×GÑG u×G×G×G×G×GÖG´#×G×G×GÑG´#×G×GÕG¸×G×GÓGÐ;×G×G×G×G×GÔG¼x×G×G×GÑG¼x×G×G×G×G×G×G×GÒGó    c                 óZ  • [         R                  " [        [        [        S9n [         R
                  n[         R                  n[        U-   nSoCU-
  oQ" [        [        XS9of[        :H  ow(       GdÛ  [        R                  " SU4SU[        45      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS	[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS	S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S
[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS
S.-  nSSU0-  n	[        [        R                  " U	5      5      eS =n=n=n=n=n=pg[         R
                  n[         R                  n[        U-   o1" [        [        XS9nS odUL oU(       Gdƒ  [        R                  " SU4SXF45      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS	[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS	S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.
-  n
SSU
0-  n[        [        R                  " U5      5      eS =n=n=n=n=pV[         R                  nSnSoËU-  o!U:H  oÝ(       d×  [        R                  " SU4SX45      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=n=n=pÂg )Nr   é   r   )z¬%(py15)s
{%(py15)s = %(py2)s
{%(py2)s = %(py0)s.verify
}(%(py3)s, %(py4)s, %(py5)s, now=((%(py6)s + %(py9)s
{%(py9)s = %(py7)s.SESSION_SECONDS
}) - %(py12)s))
} == %(py17)sr   r   r   r   r   r   )r   r   r   r   r   r   Úpy7Úpy9Úpy12r#   Úpy17úassert %(py19)sÚpy19©Úis)zŸ%(py12)s
{%(py12)s = %(py2)s
{%(py2)s = %(py0)s.verify
}(%(py3)s, %(py4)s, %(py5)s, now=(%(py6)s + %(py9)s
{%(py9)s = %(py7)s.SESSION_SECONDS
}))
} is %(py15)s)
r   r   r   r   r   r   r:   r;   r<   r#   úassert %(py17)sr=   é   é  )zC%(py2)s
{%(py2)s = %(py0)s.SESSION_SECONDS
} == (%(py5)s * %(py7)s))r   r   r   r:   zassert %(py10)sÚpy10)r   r$   r   r   r   r%   ÚSESSION_SECONDSr   r&   r'   r(   r)   r*   r+   r,   r-   )r   r.   Ú@py_assert8r1   Ú@py_assert11Ú@py_assert13Ú@py_assert14Ú@py_assert16Ú@py_format18Ú@py_format20r4   Ú@py_assert4Ú@py_assert6Ú@py_assert3Ú@py_format9Ú@py_format11s                   r5   Útest_a_cookie_lives_two_hoursrS      s‰  € Ü�MŠMœ&¤(´Ñ4€EÜ�>‰>Ð`¼×8OÑ8OÐ`´#Ð8OÑ2OÐ`ÐRSÐ`ÐRSÑ2SÐ`ˆ>œ&¤# uÑTÐ`ÔX`Ñ`×`×`×`Ó`ÐTÔX`×`×`×`×`×`Õ`Œ7×`×`×`Ñ`Œ7×`×`Õ`ˆ>×`×`×`×`×`Ô`œ&×`×`×`Ñ`œ&×`×`×`×`×`Ö`¤#×`×`×`Ñ`¤#×`×`×`×`×`Ö` u×`×`×`Ñ` u×`×`×`×`×`Ö`´#×`×`×`Ñ`´#×`×`×`×`×`Ö`¼×`×`×`Ñ`¼×`×`Õ`Ð8O×`×`Ó`ÐRS×`×`Ó`ÐT×`×`×`×`×`Ô`ÔX`×`×`×`Ñ`ÔX`×`×`×`×`×`×`×`Õ`Ü�>‰>ÐX¼×8OÑ8OÐX´#Ð8OÑ2OÐXˆ>œ&¤# uÑPÐXÐTXÐXÐTXÐX×X×X×XÓXÐP×X×X×X×X×XÕXŒ7×X×X×XÑXŒ7×X×XÕXˆ>×X×X×X×X×XÔXœ&×X×X×XÑXœ&×X×X×X×X×XÖX¤#×X×X×XÑX¤#×X×X×X×X×XÖX u×X×X×XÑX u×X×X×X×X×XÖX´#×X×X×XÑX´#×X×X×X×X×XÖX¼×X×X×XÑX¼×X×XÕXÐ8O×X×XÓXÐP×X×XÓXÐTX×X×X×X×X×X×X×XÑXÜ×"Ñ"Ð. aÐ.¨$Ð.¨$¡hÐ. hÑ.×.×.×.Ò.Ð"×.×.×.×.×.Õ.Œ7×.×.×.Ñ.Œ7×.×.Õ.Ð"×.×.Ó. a×.×.Ó.¨$×.×.×.×.×.×.×.Ð.r7   c                 óä  • [         R                  " S[        [        S9n [         R                  o" [
        [        U [        S9nS o2UL oD(       Gd  [        R                  " SU4SX#45      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [
        5      (       a  [        R                  " [
        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS	[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS	[        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n[        [        R                  " U5      5      eS =n=n=pCg )Núother-secretr   r@   ©zl%(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s.verify
}(%(py3)s, %(py4)s, %(py5)s, now=%(py6)s)
} is %(py11)sr   r   r   r   r   ©r   r   r   r   r   r   r   r    úassert %(py13)sr!   )r   r$   r   r   r%   r   r   r&   r'   r(   r)   r*   r+   r,   r-   ©r   r.   r/   r1   r0   Ú@py_format12r3   s          r5   Ú3test_a_cookie_signed_with_another_secret_is_refusedr[   #   s(  € Ü�MŠM˜.¬(¼Ñ<€EÜ�>‰>Ð>ˆ>œ&¤# u´#Ñ6Ð>¸$Ð>¸$Ð>×>×>×>Ó>Ð6×>×>×>×>×>Õ>Œ7×>×>×>Ñ>Œ7×>×>Õ>ˆ>×>×>×>×>×>Ô>œ&×>×>×>Ñ>œ&×>×>×>×>×>Ö>¤#×>×>×>Ñ>¤#×>×>×>×>×>Ö> u×>×>×>Ñ> u×>×>×>×>×>Ö>´#×>×>×>Ñ>´#×>×>Õ>Ð6×>×>Ó>¸$×>×>×>×>×>×>Ö>r7   c                 ón  • [         R                  " [        [        [        S9n [         R
                  nSo!" [        X [        S9nS oCUL oU(       GdÝ  [        R                  " SU4SX445      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=n=n=pTg )Nr   Úorg_someone_elser@   )zl%(py9)s
{%(py9)s = %(py2)s
{%(py2)s = %(py0)s.verify
}(%(py3)s, %(py5)s, %(py6)s, now=%(py7)s)
} is %(py12)sr   r   r   r   )r   r   r   r   r   r:   r;   r<   zassert %(py14)sÚpy14)r   r$   r   r   r   r%   r&   r'   r(   r)   r*   r+   r,   r-   )r   r.   rN   rG   rH   r1   Ú@py_format13Ú@py_format15s           r5   Ú1test_a_cookie_for_another_organization_is_refusedra   (   s  € Ü�MŠMœ&¤(´Ñ4€EÜ�>‰>ÐMÐ"4ÐMˆ>œ&Ð"4ÄÑEÐMÈÐMÈÐM×M×M×MÓMÐE×M×M×M×M×MÕMŒ7×M×M×MÑMŒ7×M×MÕMˆ>×M×M×M×M×MÔMœ&×M×M×MÑMœ&×M×MÕMÐ"4×M×M×M×M×MÔM°e×M×M×MÑM°e×M×M×M×M×MÖMÄ×M×M×MÑMÄ×M×MÕMÐE×M×MÓMÈ×M×M×M×M×M×M×MÐMr7   c                 ó@  • [         R                  " [        [        [        S9n U R                  S5      u  p[        R                  " [         R                  " U5      5      nSUS'   [        R                  " [        R                  " U5      R                  5       5      R                  5       R                  S5      n[         R                  nSod SU 3ou" [        Xg[        S9nS o˜U	L oª(       Gd§  [         R"                  " SU
4SX‰45      S[$        R&                  " 5       ;   d  [         R(                  " [         5      (       a  [         R*                  " [         5      OS[         R*                  " U5      S	[$        R&                  " 5       ;   d  [         R(                  " [        5      (       a  [         R*                  " [        5      OS	[         R*                  " U5      [         R*                  " U5      S
[$        R&                  " 5       ;   d  [         R(                  " [        5      (       a  [         R*                  " [        5      OS
[         R*                  " U5      [         R*                  " U	5      S.-  nSSU0-  n[-        [         R.                  " U5      5      eS =n=n=n=n=p©g )Nr   Ú.r]   r   Ú=r@   )zn%(py10)s
{%(py10)s = %(py2)s
{%(py2)s = %(py0)s.verify
}(%(py3)s, %(py5)s, %(py7)s, now=%(py8)s)
} is %(py13)sr   r   r   )r   r   r   r   r:   r   rE   r!   r"   r#   )r   r$   r   r   r   ÚsplitÚjsonÚloadsÚ	b64decodeÚbase64Úurlsafe_b64encodeÚdumpsÚencodeÚdecodeÚrstripr%   r&   r'   r(   r)   r*   r+   r,   r-   )r   ÚbodyÚsigÚrecordÚforgedr.   rN   rO   r0   r2   rH   r3   r4   s                r5   Ú test_an_edited_cookie_is_refusedrs   -   s€  € Ü�MŠMœ&¤(´Ñ4€EØ—‘˜CÓ �I€DÜ�ZŠZœ×)Ò)¨$Ó/Ó0€FØ 2€FÐÑÜ×%Ò%¤d§j¢j°Ó&8×&?Ñ&?Ó&AÓB×IÑIÓK×RÑRÐSVÓW€FÜ�>‰>ÐYÐ"4ÐY¸ÀÀ#ÀÐ6GÐYˆ>œ&Ð"4ÌSÑQÐYÐUYÐYÐUYÐY×Y×Y×YÓYÐQ×Y×Y×Y×Y×YÕYŒ7×Y×Y×YÑYŒ7×Y×YÕYˆ>×Y×Y×Y×Y×YÔYœ&×Y×Y×YÑYœ&×Y×YÕYÐ"4×Y×YÓYÐ6G×Y×Y×Y×Y×YÔYÌS×Y×Y×YÑYÌS×Y×YÕYÐQ×Y×YÓYÐUY×Y×Y×Y×Y×Y×Y×YÒYr7   c                 ó¾  • S GHV  n [         R                  o" [        [        U [        S9nS o2UL oD(       Gd  [
        R                  " SU4SX#45      S[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OSS[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OSS[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OSS	[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OS	[
        R                  " U5      [
        R                  " U5      S
.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=pCGMY     g )N)NÚ zno-dotza.b.cznot-base64!.abcr   r@   rV   r   r   r   r   r   rW   rX   r!   ©r   r%   r   r   r   r&   r'   r(   r)   r*   r+   r,   r-   rY   s          r5   Ú"test_malformed_cookies_are_refusedrw   6   s$  € ÜAˆÜ�~‰~ÐBˆ~œf¤c¨5´cÑ:ÐB¸dÐB¸dÐB×B×B×BÓBÐ:×B×B×B×B×BÕBŒw×B×B×BÑBŒw×B×BÕBˆ~×B×B×B×B×BÔBœf×B×B×BÑBœf×B×B×B×B×BÖB¤c×B×B×BÑB¤c×B×B×B×B×BÖB¨5×B×B×BÑB¨5×B×B×B×B×BÖB´c×B×B×BÑB´c×B×BÕBÐ:×B×BÓB¸d×B×B×B×B×B×B×BÐBò Br7   c                 ó¬  • Sn [         R                  o" [        [        U [        S9nS o2UL oD(       Gd  [
        R                  " SU4SX#45      S[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OSS[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OSS[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OSS	[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OS	[
        R                  " U5      [
        R                  " U5      S
.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=pCg )Nz&playground.1900000000.0123456789abcdefr   r@   rV   r   r   r   Úoldr   rW   rX   r!   rv   )ry   r.   r/   r1   r0   rZ   r3   s          r5   Ú%test_the_old_cookie_format_is_refusedrz   ;   s  € Ø
2€CÜ�>‰>Ð<ˆ>œ&¤# s´Ñ4Ð<¸Ð<¸Ð<×<×<×<Ó<Ð4×<×<×<×<×<Õ<Œ7×<×<×<Ñ<Œ7×<×<Õ<ˆ>×<×<×<×<×<Ô<œ&×<×<×<Ñ<œ&×<×<×<×<×<Ö<¤#×<×<×<Ñ<¤#×<×<×<×<×<Ö< s×<×<×<Ñ< s×<×<×<×<×<Ö<´×<×<×<Ñ<´×<×<Õ<Ð4×<×<Ó<¸×<×<×<×<×<×<Ö<r7   c                 óŽ  • [         R                  " [        [        [        S9n [        [         R
                  -   S-   n[         R                  o"" [        [        XS9nS oCUL oU(       Gd  [        R                  " SU4SX445      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS	[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	[        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n[        [        R                  " U5      5      eS =n=n=pT[         R                   " [        U 5      n/ nS o˜U	Loªoº(       a  UR"                  nSoÄU:H  oÝnU(       GdŠ  [        R                  " SU
4SX‰45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U	5      S.-  nSSU0-  oòR%                  U5        U
(       a­  [        R                  " SW4SUW45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  nUR%                  U5        [        R&                  " US5      0 -  nSSU0-  n[        [        R                  " U5      5      eS =n=n=n
=n	=n=pÜ[         R                   nSo¢" X 5      nS nUUL nU(       Gd8  [        R                  " SU4SUU45      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      [        R                  " U
5      S[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S.-  nSS U0-  n[        [        R                  " U5      5      eS =n=n
=n=nng )!Nr   rD   r@   rV   r   r   r   r   ÚlaterrW   rX   r!   r   ©úis not)z%(py2)s is not %(py5)sÚfound)r   r   ú%(py7)sr:   r   )z.%(py11)s
{%(py11)s = %(py9)s.sid
} == %(py14)s)r;   r    r^   z%(py16)sÚpy16r   r>   r?   rU   )z_%(py7)s
{%(py7)s = %(py2)s
{%(py2)s = %(py0)s.signed_identity
}(%(py4)s, %(py5)s)
} is %(py10)s)r   r   r   r   r:   rE   úassert %(py12)sr<   )r   r$   r   r   r   rF   r%   r   r&   r'   r(   r)   r*   r+   r,   r-   Úsigned_identityr   ÚappendÚ_format_boolop)r   r|   r.   r/   r1   r0   rZ   r3   r   rN   rP   Ú@py_assert0rI   r2   Ú@py_format6Ú@py_format8r`   Ú@py_format17rL   rM   rO   rG   rR   r_   s                           r5   Ú9test_sign_out_reads_the_session_id_from_an_expired_cookierŠ   @   sí  € Ü�MŠMœ&¤(´Ñ4€EÜ”'×)Ñ)Ñ)¨DÑ0€EÜ�>‰>Ð@ˆ>œ&¤# uÑ8Ð@¸DÐ@¸DÐ@×@×@×@Ó@Ð8×@×@×@×@×@Õ@Œ7×@×@×@Ñ@Œ7×@×@Õ@ˆ>×@×@×@×@×@Ô@œ&×@×@×@Ñ@œ&×@×@×@×@×@Ö@¤#×@×@×@Ñ@¤#×@×@×@×@×@Ö@ u×@×@×@Ñ@ u×@×@×@×@×@Ö@°%×@×@×@Ñ@°%×@×@Õ@Ð8×@×@Ó@¸D×@×@×@×@×@×@Õ@Ü×#Ò#¤F¨EÓ2€EÙ9˜Ð9˜Ð×9 §¡Ð9¨kÐ9¨kÑ!9×9×9×9Õ9ˆ5×9×9×9×9×9Õ9ˆ5×9×9×9Ñ9ˆ5×9×9Õ9˜×9×9×9×9×9×9×9Ò9 ¨k×9×9×9×9×9Õ9 ×9×9×9Ñ9 ×9×9Õ9 ×9×9Ó9¨k×9×9×9×9×9×9×9×9×9×9×9×9×9Õ9Ü×"Ñ"ÐA >ÐAÐ" >Ó9ÐA¸TÐAÐ9¸TÐA×A×A×AÔAÐ9¸T×A×A×A×A×AÕAŒ7×A×A×AÑAŒ7×A×AÕAÐ"×A×AÓA >×A×A×A×A×AÔA°5×A×A×AÑA°5×A×AÕAÐ9×A×AÓA¸T×A×A×A×A×A×A×AÑAr7   c                 ót  • [         R                  " [        S[        S9n [         R                  nSn[        U-   o1" [        XS9nSoTU:H  of(       GdÝ  [
        R                  " SU4SXE45      S[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OSS[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OSS	[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OS	[
        R                  " U5      [
        R                  " U5      [
        R                  " U5      S
.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=n=n=peg )Nz/?doc=12r   r   r   )zz%(py10)s
{%(py10)s = %(py2)s
{%(py2)s = %(py0)s.next_from_state
}(%(py3)s, %(py4)s, now=(%(py5)s + %(py7)s))
} == %(py13)sr   r   Ústater   )r   r   r   r   r   r:   rE   r!   r"   r#   ©r   Ú	state_forr   r   Únext_from_stater&   r'   r(   r)   r*   r+   r,   r-   )	rŒ   r.   rO   rG   r0   r2   rH   r3   r4   s	            r5   Ú(test_state_returns_the_page_it_was_givenr�   I   s$  € Ü×Òœf j´cÑ:€EÜ×"Ñ"ÐM¸BÐM´c¸B±hÐMÐ"¤6¨5Ñ?ÐMÀ:ÐMÀ:ÑM×M×M×MÓMÐ?×M×M×M×M×MÕMŒ7×M×M×MÑMŒ7×M×MÕMÐ"×M×M×M×M×MÔM¤6×M×M×MÑM¤6×M×M×M×M×MÖM¨5×M×M×MÑM¨5×M×M×M×M×MÖM´c×M×M×MÑM´c×M×MÕM¸B×M×MÓMÐ?×M×MÓMÀ:×M×M×M×M×M×M×MÒMr7   c                 óL  • S GH  n [         R                  " [        U [        S9n[         R                  o"" [        U[        S9nSoCU:H  oU(       GdÈ  [
        R                  " SU4SX445      S[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OSS[        R                  " 5       ;   d  [
        R                  " U5      (       a  [
        R                  " U5      OSS	[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OS	[
        R                  " U5      [
        R                  " U5      S
.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=pTGM      g )N)zhttps://evil.example/z//evil.example/z/\evil.exampler   Ú/r   )zl%(py7)s
{%(py7)s = %(py2)s
{%(py2)s = %(py0)s.next_from_state
}(%(py3)s, %(py4)s, now=%(py5)s)
} == %(py10)sr   r   rŒ   r   ©r   r   r   r   r   r:   rE   r‚   r<   r�   )ÚtargetrŒ   r.   rO   r0   rG   rR   r_   s           r5   Ú/test_state_never_returns_a_page_on_another_siter•   N   s  € ÜQˆÜ×!Ò!¤&¨&´cÑ:ˆÜ×&Ñ&ÐEÐ&¤v¨u¼#Ñ>ÐEÀ#ÐEÀ#ÑE×E×E×EÓEÐ>×E×E×E×E×EÕEŒw×E×E×EÑEŒw×E×EÕEÐ&×E×E×E×E×EÔE¤v×E×E×EÑE¤v×E×E×E×E×EÖE¨u×E×E×EÑE¨u×E×E×E×E×EÖE¼#×E×E×EÑE¼#×E×EÕEÐ>×E×EÓEÀ#×E×E×E×E×E×E×EÐEò Rr7   c                 óª  • [         R                  " [        S[        S9n [         R                  n[         R
                  n[        U-   o1" [        XS9nS oTUL of(       Gd0  [        R                  " SU4SXE45      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S	.	-  nS
SU0-  n[        [        R                  " U5      5      eS =n=n=n=n=pe[         R                  nSo‘" X�[        S9nS oBUL o3(       GdŠ  [        R                  " SU4SX$45      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      S.-  n
SSU
0-  n[        [        R                  " U5      5      eS =n=n	=n=p4g )Nr’   r   r@   )z�%(py11)s
{%(py11)s = %(py2)s
{%(py2)s = %(py0)s.next_from_state
}(%(py3)s, %(py4)s, now=(%(py5)s + %(py8)s
{%(py8)s = %(py6)s.STATE_SECONDS
}))
} is %(py14)sr   r   rŒ   r   )	r   r   r   r   r   r   r   r    r^   zassert %(py16)sr�   rU   )zl%(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s.next_from_state
}(%(py4)s, %(py5)s, now=%(py6)s)
} is %(py11)s)r   r   r   r   r   r   r    rX   r!   )r   rŽ   r   r   r�   ÚSTATE_SECONDSr&   r'   r(   r)   r*   r+   r,   r-   )rŒ   r.   r/   r0   r1   rI   r2   r`   r‰   rP   rZ   r3   s               r5   Ú%test_stale_or_forged_state_is_refusedr˜   T   s5  € Ü×Òœf c¬sÑ3€EÜ×"Ñ"ÐZ¼G×<QÑ<QÐZ´cÐ<QÑ6QÐZÐ"¤6¨5ÑRÐZÐVZÐZÐVZÐZ×Z×Z×ZÓZÐR×Z×Z×Z×Z×ZÕZŒ7×Z×Z×ZÑZŒ7×Z×ZÕZÐ"×Z×Z×Z×Z×ZÔZ¤6×Z×Z×ZÑZ¤6×Z×Z×Z×Z×ZÖZ¨5×Z×Z×ZÑZ¨5×Z×Z×Z×Z×ZÖZ´c×Z×Z×ZÑZ´c×Z×Z×Z×Z×ZÖZ¼G×Z×Z×ZÑZ¼G×Z×ZÕZÐ<Q×Z×ZÓZÐR×Z×ZÓZÐVZ×Z×Z×Z×Z×Z×Z×ZÑZÜ×"Ñ"ÐJ >ÐJÐ" >¼cÑBÐJÀdÐJÀdÐJ×J×J×JÓJÐB×J×J×J×J×JÕJŒ7×J×J×JÑJŒ7×J×JÕJÐ"×J×JÓJ >×J×J×J×J×JÔJ°5×J×J×JÑJ°5×J×J×J×J×JÖJ¼c×J×J×JÑJ¼c×J×JÕJÐB×J×JÓJÀd×J×J×J×J×J×J×JÐJr7   c                 ó	  • [         R                  " [        S[        S9n [         R                  " [        [
        [        S9n[         R                  o"" [        [        U [        S9nS oCUL oU(       Gd  [        R                  " SU4SX445      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS	[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS	[        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n[        [        R                  " U5      5      eS =n=n=pT[         R                   o"" [        U[        S9nS oXUL o™(       GdÈ  [        R                  " SU	4SX…45      S[        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS	[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS	[        R                  " U5      [        R                  " U5      S.-  n
SSU
0-  n[        [        R                  " U5      5      eS =n=n=p•g )Nr’   r   r@   rV   r   r   r   rŒ   r   rW   rX   r!   )zl%(py7)s
{%(py7)s = %(py2)s
{%(py2)s = %(py0)s.next_from_state
}(%(py3)s, %(py4)s, now=%(py5)s)
} is %(py10)sr   r“   r‚   r<   )r   rŽ   r   r   r$   r   r%   r   r&   r'   r(   r)   r*   r+   r,   r-   r�   )rŒ   r   r.   r/   r1   r0   rZ   r3   rO   rG   rR   r_   s               r5   Ú8test_a_state_cannot_stand_in_for_a_cookie_or_the_reverserš   Z   s0  € Ü×Òœf c¬sÑ3€EÜ�MŠMœ&¤(´Ñ4€EÜ�>‰>Ð>ˆ>œ&¤# u´#Ñ6Ð>¸$Ð>¸$Ð>×>×>×>Ó>Ð6×>×>×>×>×>Õ>Œ7×>×>×>Ñ>Œ7×>×>Õ>ˆ>×>×>×>×>×>Ô>œ&×>×>×>Ñ>œ&×>×>×>×>×>Ö>¤#×>×>×>Ñ>¤#×>×>×>×>×>Ö> u×>×>×>Ñ> u×>×>×>×>×>Ö>´#×>×>×>Ñ>´#×>×>Õ>Ð6×>×>Ó>¸$×>×>×>×>×>×>Õ>Ü×"Ñ"ÐBÐ"¤6¨5´cÑ:ÐB¸dÐB¸dÐB×B×B×BÓBÐ:×B×B×B×B×BÕBŒ7×B×B×BÑBŒ7×B×BÕBÐ"×B×B×B×B×BÔB¤6×B×B×BÑB¤6×B×B×B×B×BÖB¨5×B×B×BÑB¨5×B×B×B×B×BÖB´c×B×B×BÑB´c×B×BÕBÐ:×B×BÓB¸d×B×B×B×B×B×BÖBr7   c                 ó   • [         R                  " SS[        [        S9n [         R                  " U SSSS5      n/ o!R
                  nSoCU:H  oUoe(       a  UR                  nS o‡UL o™nU(       Gdž  [        R                  " S	U4S
X445      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  n
SSU
0-  o²R                  U5        U(       a¬  [        R                  " SW	4SWW45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  oÒR                  U5        [        R                  " US5      0 -  nSSU0-  n[        [        R                   " U5      5      eS =n=n=n=n=n=n=p˜/ o!R"                  nS oCULoUoe(       a  SnUR"                  nUU;   nUnU(       Gdž  [        R                  " SU4SX445      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  n
SSU
0-  o²R                  U5        U(       a¬  [        R                  " SW4SWU45      [        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S.-  nSSU0-  oÒR                  U5        [        R                  " US5      0 -  nSSU0-  n[        [        R                   " U5      5      eS =n=n=n=n=n=n=nng )NÚ	sk_unusedÚclient_unused©Úapi_keyÚ	client_idr   Úsession_secretzhttps://playground.testÚcode_1zforged.stateú	/mark.pngi�  r   )z.%(py4)s
{%(py4)s = %(py2)s.status
} == %(py7)sÚoutcome)r   r   r:   z%(py9)sr;   r@   )z1%(py13)s
{%(py13)s = %(py11)s.token
} is %(py16)s)r    r!   r�   z%(py18)sÚpy18r   zassert %(py21)sÚpy21zSign in againr}   )z0%(py4)s
{%(py4)s = %(py2)s.page
} is not %(py7)s©Úin)z0%(py12)s in %(py16)s
{%(py16)s = %(py14)s.page
})r<   r^   r�   )r   ÚWorkOSr   r   Úcomplete_sign_inÚstatusr   r&   r'   r(   r)   r*   r+   r„   r…   r,   r-   Úpage)Úconfigr¤   r.   rP   rO   Ú@py_assert5r†   r2   Ú@py_assert15rJ   rˆ   Ú@py_format10r‰   Ú@py_format19rM   Ú@py_format22rH   rI   s                     r5   Ú9test_a_return_with_bad_state_fails_without_calling_workosr³   a   s  € Ü�^Š^Ø ÌÔ\bñ€Fô ×&Ò&ØÐ)¨8°^À[ó€Gñ ;�>‰>Ð:˜SÐ:˜SÑ ×: W§]¡]Ð:°dÐ:°dÐ%:×:×:×:Õ:ˆ>×:×:×:×:×:Õ:ˆ7×:×:×:Ñ:ˆ7×:×:Õ:ˆ>×:×:Ó:˜S×:×:×:×:×:×:×:Ò: ]°d×:×:×:×:×:Õ: W×:×:×:Ñ: W×:×:Õ: ]×:×:Ó:°d×:×:×:×:×:×:×:×:×:×:×:×:×:Ö:ÙG�<‰<ÐG˜tÐG˜tÐ#×G¨ÐG¸7¿<¹<ÐG¨¸<Ñ(G×G×G×GÖGˆ<×G×G×G×G×GÕGˆ7×G×G×GÑGˆ7×G×GÕGˆ<×G×GÓG˜t×G×G×G×G×G×G×GÒG¨¸<×G×GÔG¨×G×G×G×G×GÔG¸7×G×G×GÑG¸7×G×GÕG¸<×G×G×G×G×G×G×G×G×G×G×G×G×G×GÐGr7   c                 ó¸  • [         R                  " SS[        [        S9n [         R                  " U SS[
        S9nUR                  nSo2" U5      oD(       d¯  SS	[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	[        R                  " U5      [        R                  " U5      [        R                  " U5      S
.-  n[        [        R                  " U5      5      eS =n=p4SofU;   ow(       d¥  [        R                  " SU4SXa45      [        R                  " U5      S	[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	S.-  nSSU0-  n	[        [        R                  " U	5      5      eS =pg/ nSowU;   oªoj(       a  So»U;   oÌnU(       Gdt  [        R                  " SU
4SXq45      [        R                  " U5      S	[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	S.-  n	SSU	0-  oÒR                  U5        U
(       a—  [        R                  " SW4SWU45      [        R                  " U5      S	[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	S.-  nSSU0-  oòR                  U5        [        R                   " US5      0 -  nSSU0-  n[        [        R                  " U5      5      eS =n=n=n=n
=p¼g )NÚskÚclient_1rž   zhttp://192.168.1.237:8101r’   r   z1https://api.workos.com/user_management/authorize?zLassert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.startswith
}(%(py4)s)
}Úurl)r   r   r   r   z9redirect_uri=http%3A%2F%2F192.168.1.237%3A8101%2Fcallbackr§   ©z%(py1)s in %(py3)s©Úpy1r   úassert %(py5)sr   zprovider=authkitzclient_id=client_1©z%(py3)s in %(py5)s©r   r   r€   r:   ©z%(py10)s in %(py12)s©rE   r<   ú%(py14)sr^   r   rB   r=   )r   r©   r   r   Úauthorize_urlr   Ú
startswithr(   r)   r&   r*   r+   r,   r-   r'   r„   r…   )r­   r·   r.   rP   r®   Ú@py_format7r†   Ú@py_assert2Ú@py_format4r‡   rN   r0   rH   rˆ   r_   r`   r4   rL   s                     r5   ÚAtest_the_authorize_url_returns_to_the_host_the_request_came_in_onrÆ   l   sÏ  € Ü�^Š^ D°JÔPSÔdjÑk€FÜ
×
Ò
 Ð(CÀSÌcÑ
R€CØ�>‰>ÐNÐMÐNˆ>ÐMÓNÐNÕN×N×N×N×N×NÑNˆ3×N×N×NÑNˆ3×N×NÕNˆ>×N×NÓNÐM×N×NÓNÐN×N×N×N×N×NÔNØFÐMÈ#ÑM×M×M×MÒMÐF×M×MÔMÐF×M×M×M×M×MÔMÈ#×M×M×MÑMÈ#×M×M×M×M×M×MÓMÙDÐÐD Ñ$×DÐ)=ÐDÀÑ)D×D×D×DÕDÐ×D×DÔDÐ×D×D×D×D×DÔD ×D×D×DÑD ×D×D×D×D×D×D×DÔDÐ)=À×D×DÔDÐ)=×D×D×D×D×DÔDÀ×D×D×DÑDÀ×D×D×D×D×D×D×D×D×D×D×D×D×DÕDr7   c                 óœ  • [         R                  " SS5      n SoU:H  o"(       d¦  [        R                  " SU4SU U45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =p!g )
Nr   úhttps://playground.qubera.aiz{https://api.workos.com/user_management/sessions/logout?session_id=session_1&return_to=https%3A%2F%2Fplayground.qubera.ai%2Fr   )z%(py0)s == %(py3)sr·   )r   r   r»   r   )
r   Ú
logout_urlr&   r'   r(   r)   r*   r+   r,   r-   )r·   rÄ   r.   rÅ   r‡   s        r5   Ú4test_the_logout_url_names_the_session_and_the_returnrÊ   t   s¹   € Ü
×
Ò
˜[Ð*HÓ
I€Cð	Pðð	Pñ÷ ó ïé ôˆ3ð	P÷ò ïé ÷õ ïé ðˆ3÷ ö ïé ðˆ3÷ ò ïé ðð	P÷÷ ÷ ñ ïé ÷ö r7   c                 ól  • [         R                  " SSS5      n SoU ;   o"(       d¥  [        R                  " SU4SX45      [        R                  " U5      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS.-  nS	S
U0-  n[        [        R                  " U5      5      eS =pSoU ;   o"(       d¥  [        R                  " SU4SX45      [        R                  " U5      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS.-  nS	S
U0-  n[        [        R                  " U5      5      eS =pSoU ;   o"(       d¥  [        R                  " SU4SX45      [        R                  " U5      S[
        R                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OSS.-  nS	S
U0-  n[        [        R                  " U5      5      eS =pg )Nz<b>x</b>@example.comz%https://api.workos.com/logout?a=1&b=2r£   z &lt;b&gt;x&lt;/b&gt;@example.comr§   r¸   r¬   r¹   r»   r   z0href="https://api.workos.com/logout?a=1&amp;b=2"z Sign in with a different account)
r   Úrefusal_pager&   r'   r+   r(   r)   r*   r,   r-   )r¬   r†   rÄ   rÅ   r‡   s        r5   ÚFtest_the_refusal_page_escapes_the_email_and_offers_a_different_accountrÍ   |   s0  € Ü×ÒÐ 6Ð8_ÐalÓm€DØ-Ð5°Ñ5×5×5×5Ò5Ð-×5×5Ô5Ð-×5×5×5×5×5Ô5°×5×5×5Ñ5°×5×5×5×5×5×5Ó5Ø=ÐEÀÑE×E×E×EÒEÐ=×E×EÔEÐ=×E×E×E×E×EÔEÀ×E×E×EÑEÀ×E×E×E×E×E×EÓEØ-Ð5°Ñ5×5×5×5Ò5Ð-×5×5Ô5Ð-×5×5×5×5×5Ô5°×5×5×5Ñ5°×5×5×5×5×5×5Ô5r7   c                 ó  • [         R                  " SS[        [        S9n [         R                  " U SSS5      nSo"U;   o3(       d¥  [
        R                  " SU4S	X!45      [
        R                  " U5      S
[        R                  " 5       ;   d  [
        R                  " U5      (       a  [
        R                  " U5      OS
S.-  nSSU0-  n[        [
        R                  " U5      5      eS =p#/ nSo3U;   owo'(       a  SoˆU;   o™nU(       Gdt  [
        R                  " SU4SX145      [
        R                  " U5      S
[        R                  " 5       ;   d  [
        R                  " U5      (       a  [
        R                  " U5      OS
S.-  nSSU0-  o¦R                  U
5        U(       a—  [
        R                  " SW	4SWU45      [
        R                  " U5      S
[        R                  " 5       ;   d  [
        R                  " U5      (       a  [
        R                  " U5      OS
S.-  nSSU0-  oÆR                  U5        [
        R                  " US5      0 -  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=n=n=p‰g )Nrµ   r¶   rž   rÈ   r’   r£   zproperty="og:title"r§   r¸   r¬   r¹   r»   r   zhttp-equiv="refresh"zuser_management/authorizer¼   r½   r€   r:   r¾   r¿   rÀ   r^   r   rB   r=   )r   r©   r   r   Ú
login_pager&   r'   r+   r(   r)   r*   r,   r-   r„   r…   )r­   r¬   r†   rÄ   rÅ   r‡   r.   rN   r0   rH   rˆ   r_   r`   r4   rL   s                  r5   ÚCtest_the_login_page_carries_the_preview_tags_and_moves_on_to_workosrÐ   ƒ   sZ  € Ü�^Š^ D°JÔPSÔdjÑk€FÜ×Ò˜fÐ&DÀcÈ;ÓW€DØ Ð( DÑ(×(×(×(Ò(Ð ×(×(Ô(Ð ×(×(×(×(×(Ô( D×(×(×(Ñ( D×(×(×(×(×(×(Ó(ÙQÐ!ÐQ TÑ)×QÐ.IÐQÈTÑ.Q×Q×Q×QÕQÐ!×Q×QÔQÐ!×Q×Q×Q×Q×QÔQ T×Q×Q×QÑQ T×Q×Q×Q×Q×Q×Q×QÔQÐ.IÈT×Q×QÔQÐ.I×Q×Q×Q×Q×QÔQÈT×Q×Q×QÑQÈT×Q×Q×Q×Q×Q×Q×Q×Q×Q×Q×Q×Q×QÕQr7   )ÚreturnÚNone)#Ú__doc__Ú
__future__r   Úbuiltinsr(   Ú_pytest.assertion.rewriteÚ	assertionÚrewriter&   ri   rf   Úquber.playgroundr   r   r   r   ÚIdentityr   r6   rS   r[   ra   rs   rw   rz   rŠ   r�   r•   r˜   rš   r³   rÆ   rÊ   rÍ   rÐ   © r7   r5   Ú<module>rÜ      s©   ðñõ #ç  „ ƒÛ å $à	€Ø€Ø€Ø×ÒØÐ0À#ÈHÐZeñ€ô
Hô
/ô?ô
Nô
ZôCô
=ô
BôNô
FôKôCôHôEôô6õRr7   