From 74e6cf18939891738c0f9b0e91e86c177d04db6b Mon Sep 17 00:00:00 2001 From: Alvin Raihan Date: Thu, 10 Oct 2019 22:49:09 +0700 Subject: [PATCH 1/4] deploy --- superlists/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superlists/settings.py b/superlists/settings.py index b0a0d7f..675b69f 100644 --- a/superlists/settings.py +++ b/superlists/settings.py @@ -25,7 +25,7 @@ SECRET_KEY = '4o%--sf57&nkwk%o=d29#zdccko+ms^pepk_#4ah8k92c_52ut' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = ['testch1-3.herokuapp.com','localhost'] +ALLOWED_HOSTS = ['alvinraihanhome.herokuapp.com','localhost'] # Application definition -- GitLab From 31af65d5fa70aba6cc1596e793b66c0d1ed0c665 Mon Sep 17 00:00:00 2001 From: Alvin Raihan Date: Thu, 14 Nov 2019 23:02:57 +0700 Subject: [PATCH 2/4] FT for login via email --- functional_tests/test_login.py | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 functional_tests/test_login.py diff --git a/functional_tests/test_login.py b/functional_tests/test_login.py new file mode 100644 index 0000000..0799a52 --- /dev/null +++ b/functional_tests/test_login.py @@ -0,0 +1,48 @@ +from django.core import mail +from selenium.webdriver.common.keys import Keys +import re + +from .base import FunctionalTest + +TEST_EMAIL = 'edith@example.com' +SUBJECT = 'Your login link for Superlists' + + +class LoginTest(FunctionalTest): + + def test_can_get_email_link_to_log_in(self): + # Edith goes to the awesome superlists site + # and notices a "Log in" section in the navbar for the first time + # It's telling her to enter her email address, so she does + self.browser.get(self.live_server_url) + self.browser.find_element_by_name('email').send_keys(TEST_EMAIL) + self.browser.find_element_by_name('email').send_keys(Keys.ENTER) + + # A message appears telling her an email has been sent + self.wait_for(lambda: self.assertIn( + 'Check your email', + self.browser.find_element_by_tag_name('body').text + )) + + # She checks her email and finds a message + email = mail.outbox[0] + self.assertIn(TEST_EMAIL, email.to) + self.assertEqual(email.subject, SUBJECT) + + # It has a url link in it + self.assertIn('Use this link to log in', email.body) + url_search = re.search(r'http://.+/.+$', email.body) + if not url_search: + self.fail(f'Could not find url in email body:\n{email.body}') + url = url_search.group(0) + self.assertIn(self.live_server_url, url) + + # she clicks it + self.browser.get(url) + + # she is logged in! + self.wait_for( + lambda: self.browser.find_element_by_link_text('Log out') + ) + navbar = self.browser.find_element_by_css_selector('.navbar') + self.assertIn(TEST_EMAIL, navbar.text) -- GitLab From 309efe66766a5cec2a69b608bc3af4ab87a4db8a Mon Sep 17 00:00:00 2001 From: Alvin Raihan Date: Thu, 14 Nov 2019 23:13:22 +0700 Subject: [PATCH 3/4] 18.3 --- .../__pycache__/base.cpython-38.pyc | Bin 1531 -> 1531 bytes .../__pycache__/test_login.cpython-38.pyc | Bin 0 -> 1696 bytes functional_tests/test_login.py | 1 + lists/__pycache__/models.cpython-38.pyc | Bin 553 -> 553 bytes lists/__pycache__/views.cpython-38.pyc | Bin 1047 -> 1047 bytes lists/templates/base.html | 10 ++++++++++ .../__pycache__/settings.cpython-38.pyc | Bin 2399 -> 2405 bytes superlists/__pycache__/urls.cpython-38.pyc | Bin 368 -> 368 bytes 8 files changed, 11 insertions(+) create mode 100644 functional_tests/__pycache__/test_login.cpython-38.pyc diff --git a/functional_tests/__pycache__/base.cpython-38.pyc b/functional_tests/__pycache__/base.cpython-38.pyc index 11a3958d80ba6f5832b5886830e62cdde4a4196f..f7e6983780b5a8120870e4316e2f1174e2a58820 100644 GIT binary patch delta 19 Zcmey({hOOBgqN3#0SGqbZ{+&O3II0N1z`XH delta 19 Zcmey({hOOBgqN3#0SE-sH*$Ss1pqSW1h@bI diff --git a/functional_tests/__pycache__/test_login.cpython-38.pyc b/functional_tests/__pycache__/test_login.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95895928dd7000d1792c964062b2ebde8da3bab8 GIT binary patch literal 1696 zcmb7EU2hvj6rI@*d+j(*nudk~suqNhtO~bC&_YzAKrpD#TBva!SOtyNJL6=X*9-EzY zaS$dGDY{XXOmBRZ<;s`YcAWY$PIvuLru@x(B9x4^(Gey(|5)IxL(|L92@+6F0*g~_ zoshuhHehm!#sf@;I3k4i>~X=sW<%4zLH9iwlNp8HIt5Zn&*t=$&K%=jiqyvSDmL@J zBO_Rl+b14IOk>>S&UJDOnPzjwJ)+~*sfGDw^I*5l!kIV6@!KML=E`h|*DCMWI*01Liqrc%1PyoW}_k ztY5eSi*kur5D>YF%v>v(nSop&7oAxg(2QYam~Ho`iyJ#4+Vu~yYGtCr8D{(tSocD$ zg);ZkqCQmFKG?y_qd4VENRf!tu;C#y;WkUdL==t@2j&TR0@Bbzj#LX4{p0Q@t6N`g zz4PAfJ9pmy;P%~j-=3%tL=}mx(Q|b%17+1)*t1eK-N|9$-IHN5Z(y zntu3P3Egr=6sBxj7*--@s5fRZ%){cedrxLjDD@f`RW^l6nXWw6!Z$myuJma#RI4AS z)A=1^Cabq@b#KD|&FLE(SuVMsX2!>D`?-=Zsv^lpj#itONXG?A(sBP~=_m>isJ8mk zI)L}H+;l93=RCN6k2?P9tP*8if*Z(M8s|xOUktf| w>MOj3lPv9GdCQWjS7ENg>s7si9p?Qn0C4Im$ZL4XYUHX#@#k4B%b||_4-81V5dZ)H literal 0 HcmV?d00001 diff --git a/functional_tests/test_login.py b/functional_tests/test_login.py index 0799a52..92a652e 100644 --- a/functional_tests/test_login.py +++ b/functional_tests/test_login.py @@ -1,3 +1,4 @@ +from .base import FunctionalTest from django.core import mail from selenium.webdriver.common.keys import Keys import re diff --git a/lists/__pycache__/models.cpython-38.pyc b/lists/__pycache__/models.cpython-38.pyc index b7fec9e670e052c9ae2a8eff0df2774ca09f7d8d..0f82ec9bf001a8dd922d4b624d0882f40b59ed26 100644 GIT binary patch delta 19 ZcmZ3gqN3#0SJQJH*(1{0RSbj15yA0 delta 19 ZcmZ3gqN3#0SK0vZ{(6^0stpj1C{^) diff --git a/lists/__pycache__/views.cpython-38.pyc b/lists/__pycache__/views.cpython-38.pyc index 5a803dfc2b75600d004059d438df3ee50b66d17a..c30262a3f8ba05bcfccaf440c3a1594cb31dd8c9 100644 GIT binary patch delta 20 acmbQvF`a`ugqN3#0SJDDo!!XI!vX*++!vX*+0R##F diff --git a/lists/templates/base.html b/lists/templates/base.html index 5eb8d7d..5925731 100644 --- a/lists/templates/base.html +++ b/lists/templates/base.html @@ -9,6 +9,16 @@
+

{% block header_text %}{% endblock %}

diff --git a/superlists/__pycache__/settings.cpython-38.pyc b/superlists/__pycache__/settings.cpython-38.pyc index 2dce4ffa4d4fb0c998dbfe54cdd849b53177a55e..e9c5eebfe903bb6e8bf1948be9e4dc448afc5e39 100644 GIT binary patch delta 44 ycmcaF^i+s9gqN3#0SKm6osD(c$Xm}OAe)#|mYG+Sn3<87myw^Fx_KJYNj3l~FAk*u delta 38 scmaDVbYF-!gqN3#0SHQ*=EvG>+M$_M~B4h04P -- GitLab From ca56678496b7093c8c9d9bfbe3df1913844a1aca Mon Sep 17 00:00:00 2001 From: Alvin Raihan Date: Fri, 22 Nov 2019 22:52:00 +0700 Subject: [PATCH 4/4] submit --- accounts/__pycache__/__init__.cpython-38.pyc | Bin 136 -> 136 bytes accounts/__pycache__/models.cpython-38.pyc | Bin 1839 -> 1839 bytes accounts/__pycache__/urls.cpython-38.pyc | Bin 370 -> 337 bytes accounts/__pycache__/views.cpython-38.pyc | Bin 1359 -> 1381 bytes accounts/authentication.py | 24 ++-- .../__pycache__/0001_initial.cpython-38.pyc | Bin 1625 -> 1625 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 147 -> 147 bytes accounts/tests/test_authentication.py | 0 .../tests/{tests_models.py => test_models.py} | 0 accounts/tests/test_views.py | 109 ++++++++++++++++++ accounts/urls.py | 7 +- accounts/views.py | 33 +++--- lists/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 133 bytes lists/__pycache__/models.cpython-38.pyc | Bin 0 -> 553 bytes lists/__pycache__/urls.cpython-38.pyc | Bin 0 -> 364 bytes lists/__pycache__/views.cpython-38.pyc | Bin 0 -> 1532 bytes lists/templates/base.html | 59 +++++----- .../__pycache__/settings.cpython-38.pyc | Bin 2405 -> 2969 bytes superlists/__pycache__/urls.cpython-38.pyc | Bin 368 -> 433 bytes superlists/settings.py | 2 +- 20 files changed, 173 insertions(+), 61 deletions(-) create mode 100644 accounts/tests/test_authentication.py rename accounts/tests/{tests_models.py => test_models.py} (100%) create mode 100644 accounts/tests/test_views.py create mode 100644 lists/__pycache__/__init__.cpython-38.pyc create mode 100644 lists/__pycache__/models.cpython-38.pyc create mode 100644 lists/__pycache__/urls.cpython-38.pyc create mode 100644 lists/__pycache__/views.cpython-38.pyc diff --git a/accounts/__pycache__/__init__.cpython-38.pyc b/accounts/__pycache__/__init__.cpython-38.pyc index 41d93e6c9a5dcabe7e615fa96edba5706d77ec40..7b41a35df1666494d4b3263dad2cfe17fe4a0658 100644 GIT binary patch delta 19 ZcmeBR>|o>$;pOFG0D^VjuTSKz1pp|{1uFmm delta 19 YcmeBR>|o>$;pOFG00JT5GZVRM0U(A0pa1{> diff --git a/accounts/__pycache__/models.cpython-38.pyc b/accounts/__pycache__/models.cpython-38.pyc index 14ccae5ac3f214c95c4f440763bc6c9dcfd810ff..db6123b273ee930c6c643eb74d2f7ec43d916eee 100644 GIT binary patch delta 23 dcmZ3_x1NtLgqN3#0SMNAzaGoWvXM`b9RNlR1=9ck delta 23 dcmZ3_x1NtLgqN3#0SJVI&&0lB-pHrO4gfs31tS0e diff --git a/accounts/__pycache__/urls.cpython-38.pyc b/accounts/__pycache__/urls.cpython-38.pyc index 4cdf15b637821cfa8f7c6918092f72e947298d58..b3c1c87e17556987a9ecd4b4067018419afd15e8 100644 GIT binary patch delta 146 zcmeywbdgCrgqN3#0SG4ix*mHDNIwQ~kO3Qz;{e3PHWRhYb<&xl*itxx88kUxf)r^o z-eN8-$^lZWWtpkv#Z^La#i@BI@j3bFnRyeZ88Z86vQNBYAa;uzsHz~bq$IT{uXrUx Z5y;9SuF2|*wmcj_CJ!SIGan=0KLC$GBS!!L delta 179 zcmcb}^odD3gqN3#0SJVI&%}NJ(vLwLWWWyOH~?|6*FwiM13)?Vgx z<|y_Qu3!dD?w24fnvA!YON(-V6l+;#YI$)LPh4?oUdqHiL(wXZxSag-{L&JYTWk=9 zpC-q|Lk7}CAoFi=1GN<-mXxFx(4IV6^1}IgW>shnbHN2>${AvRx`9 diff --git a/accounts/__pycache__/views.cpython-38.pyc b/accounts/__pycache__/views.cpython-38.pyc index f62937f7402a3843006c4d94b2d6cedc57d01984..49c3e12dcba2ed418cb533e04f2a21eab06057f7 100644 GIT binary patch delta 855 zcmY*X&ubGw6rQ&`*=#nOHceYgTY?J;5?U(?f*$+-R#zx*-FZm z9^z3CWiNsV?cKk?e?rhpnS(d~20;XUyNQA`%r`TS@4b2Nee>D*?$mZ`HHYB%YF<1a zoz|N0=5&o+C(I6KhxK-SIM<#7!Ya&pP1+4sWiIX(tFal}YYcWsYxeZxvy+ygX*W@O z+8%N#yL~Qw$iq%Y3HN+$;*vdtlne-iWpWG(2FAclff;Y%*htA4RV8MQfzc(Rtkf8k z$FM}s;n-xQ)O=4q7{^rE%t|RMr_hHn1)^?M&YTpJJ~!}EWtDNBn6s@*eAo@b7Kkdo zDJa5G`GJb}d2}!P0nO|Jypu*03w{ue9?Il^i!hK%9^K#E@UBz{y zmjof}bbIne943l)5)tUK;D=mDu1%?gHj{vfylEmANS9^e``BAy;jLB5$uAR*#Jn_J zDvClM5o&iTL8lk9QTEB$I>{;0Lm=S53{Y73O-%=k>7>7?Wr2Ycbuq+7l=hlAm(- zE4XA{0|6TfOKV=!1lx;^9?9$-z3sN0zX5|N`$F%oUPgL*h7Gz=Ki=@;NQs~~$=k`? V(%K4^MQn`cPG=o(8g|3B{s5xl$&vs7 delta 826 zcmZ8fPiqrF6rVRcyV*>#Y3LuCwidT1Sqj#J7A>d;DISC>G=c~c)6O>Cbi2`+*@|UD z4)G>AgguJT9{mn}go5|IhzGxfc<{}di_Y-=&UFXsdoHI$C13lF6yV4nny>DL#dLoi9R!%$X`9wDhdvW)bJfE6+X4Vqq9 zmt+h>s#)LeI~inD&iE5bsZWuV=DRoD|7F!O>7C!?RpXL<=kOV>n2xS3^aQO%$S zV}_aSdPW2vQ*5WUSJ>fcH;Mx)tN880N+WU3Rrf4PdcM)CM+51XAzz?iM^PM}FK%@Y z4+m+Y)mA*{Mae^qyPyAnjkVS1D)jYnr2IHaPJBJ^F~Ev78x78jNr<8Ry^W?#NiGg^U1)Iy7MsiQ;vU*l*^@HGKOA zBMTh{rxK$FsAxn;Lw|+^B4%AMVd2g}+ZhNpLBtRpa#EGs+Q~>p$A2-i$0PF_ID6;3 z+=YJ@h3{kyOO{;*P>Nr$6}WQ2coz*@LRMIhcX36%P)pNJ!MmwG?vzEOgO0$G%O`}D0t6GJ@dQmd lhoWpS|H$sx@;aLN6}tx;xo>Z_Oy@2}*Jrm0P3ksW_Yc0$v=smV diff --git a/accounts/authentication.py b/accounts/authentication.py index e899cfb..d9be272 100644 --- a/accounts/authentication.py +++ b/accounts/authentication.py @@ -1,22 +1,20 @@ import sys from accounts.models import ListUser, Token +from accounts.models import User, Token class PasswordlessAuthenticationBackend(object): def authenticate(self, uid): - print('uid', uid, file=sys.stderr) - if not Token.objects.filter(uid=uid).exists(): - print('no token found', file=sys.stderr) - return None - token = Token.objects.get(uid=uid) - print('got token', file=sys.stderr) try: - user = ListUser.objects.get(email=token.email) - print('got user', file=sys.stderr) - return user - except ListUser.DoesNotExist: - print('new user', file=sys.stderr) - return ListUser.objects.create(email=token.email) + token = Token.objects.get(uid=uid) + return User.objects.get(email=token.email) + except User.DoesNotExist: + return User.objects.create(email=token.email) + except Token.DoesNotExist: + return None def get_user(self, email): - return ListUser.objects.get(email=email) \ No newline at end of file + try: + return User.objects.get(email=email) + except User.DoesNotExist: + return None diff --git a/accounts/migrations/__pycache__/0001_initial.cpython-38.pyc b/accounts/migrations/__pycache__/0001_initial.cpython-38.pyc index 4bf8a84389ea0ae2c778dbfc73e8eff572013b3a..df8adaae319e78f546db04d4d4b35abef748c56c 100644 GIT binary patch delta 20 acmcb~bCZWVgqN3#0SMNAzrK;%j|~7jx&_++ delta 20 acmcb~bCZWVgqN3#0SI00{|*(1x)|| delta 19 ZcmbQtIGK?g`k0^egju^{>}h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2DD#VRHs#?aKj z%*?{lz}!T)peQl9Br`cRCMUDFq&Ox%J~J<~BtBlRpz;=nO>TZlX-=vg$c)cG%m4s^ Cf*W-J literal 0 HcmV?d00001 diff --git a/lists/__pycache__/models.cpython-38.pyc b/lists/__pycache__/models.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f82ec9bf001a8dd922d4b624d0882f40b59ed26 GIT binary patch literal 553 zcmZuu%SyvQ6rERICEfTDViuMPwLTE(LRv&EqFsf^5PQdxlC(8RLD#zV8(jMh{>f}z z`3tVRllUm;g?n<(&CHo|XGYCtgJ4_?p08f<`)0^$2qZnsqJsbgXi72~Qc4B{81P2| zT+u0e;33D301G?TS4V(-Ndo5`canf=JDY<_i?N}rL6P(@3m-v|kOB!AP~6J2I8BOj z7;x=MIg2wTrEW-xLd(?DzLdAiIIaJ@klaCq3O+WD_M`J?YrEa;?(VgBI-83;9+$~j zMJXy4QSGI*xX(H6FB6`u;Az@BJmVQni1I5HNxz|p@9@N)+Xx^pL^w}Ew1k-SCxBvhE literal 0 HcmV?d00001 diff --git a/lists/__pycache__/urls.cpython-38.pyc b/lists/__pycache__/urls.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3270aac417b1f4e7ccbcdf8f2058bb8a9d9ca115 GIT binary patch literal 364 zcmYjN%}T>S5Z=uuY5FI9h$03tR?t>O#DgafBIqf^mXKLXO8(eQTg*H74BiA^X|JBV zdlCd^N(E=xZ|0kyZ`gh4_d5*jZSwl~h5m!ce`_JR!mDo(fC0}~&O^>AwlXUhq2Nq% z5K=5`u)%o|$XsL&w6@Gc=0cm;T!by?+%v!XiF(ZEMl4l^&RL~$ts7@r$o0^8h_fu! zHCF5*&Sm3G_afN$4~M2rott7a*d}9uSz5~+2miub-!lVP#KpV}lCpRTaE(?L?lcYw zYb7vNHi1h(4>euvs^Yqqs?hIDb*Vt`y?cEg-9<+yqw)CkY&1DOs8pQPX(FSISVZbU Z^=!P0yo6;YFF8(W`r01vi5-sT=NIvsT$lg= literal 0 HcmV?d00001 diff --git a/lists/__pycache__/views.cpython-38.pyc b/lists/__pycache__/views.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5415537b323356dee4dffdf77e3d230c0118d9c0 GIT binary patch literal 1532 zcmZuxOOG2x5bo#9*t>ST0T#m3JQGXc4G5Np5Q+o`kRlT)IUsA1H9Ote9eZZH)U*j3 zjZd3vegPoCaZmglq`7k1Ux4HjRXq;zN@;0ox@u~w>#O>z?{zwDhU>3?|NikpG4>BB zn@gf{3!id~!Z5=#mh&;s#aM9CMJ97KR(>y=eXhqEb!GG;HV#bBgeH2#$DwJNHd-RH zWw!C%G9A;!ciUXK%LY3a7@rM99f36|*u>QV*uq#C@LGN6Y(5Zx39?$mc8kF2KC1PaEXg|cP|1%I*v+)!wr z)DO6EY|5vi;)XxwOX(zPs**;arkt+S88>pKU})4*7rSeVo@uyc0<~rVZc&`Z{X+{G`oO~$1!?Lfp^HD)VKUEiTew!{cL?{at-cZsJK*>DlD{s*>?$|W+1HJR8{8-d`2kse%NR3)Y% zg41ho!3ehSZ+M-=8zkN&@fM0f -<<<<<<< HEAD +
-
- +

{% block header_text %}{% endblock %}

-
+ {% csrf_token %}
-======= - -
- -
{% block table %} @@ -53,5 +57,4 @@
- diff --git a/superlists/__pycache__/settings.cpython-38.pyc b/superlists/__pycache__/settings.cpython-38.pyc index e9c5eebfe903bb6e8bf1948be9e4dc448afc5e39..a374c52617cca61a8036de0b84a46881528a91b7 100644 GIT binary patch delta 862 zcmY*WTTc@~6z)!EyA^t&2I2b%ccJ5T-+&Ac1qt4}^zr{(HS&e=2jedn8R&i)90j09xAzstp+MfdkNKZ8es zC|VMZW>*ivuS%o~0;C&)sz7|u10e`QFZ4k_3~HUq3Zp941Q<`hhK^6gHZ(F7HfUWk)EIJ`sp0h0k9 z5gvnZmkhxy8RlXmCsCMd3S<-#WQ=3uFc0@&0q(;Cc-WSQMR)`Ys-W=&kKqZ=$zzek z;3>H>^Q?)u$%#vIOHD*30hL_w=gPd`I*kcYBonVvt(yCWW7qu`RibQDtDd~vD*Mh3 zH5{#~IGSlBHWk}`XIh|B+fMxlEi2Wx)PU0^cL*N_?3%NeP-}{&C#q(x9yPb=2QK7L z+tCbFH5KQ@B}xLBjZ`jQ*-Vv6uZmk~Z5_E>zXbl*R*6(K4cpWy6VsXHa<<;Do2tqc z5+%o?N^MOsxD_jon5feOsxz^wbB8aP2X+-hHJNwkjA2_ruE%h$uv(0ZOgf;J&F{k} zui47BPAl}i*0EM;AHYE?%=tt*-!W{NrqjqvF=47vlQNrEkgS#<8E$nHCH(t*nEMURM1A90Jb$EYq3$=S({M|yL=eH+>k*|f_{{Uq(_woP$ delta 273 zcmbO!{#1xBgqN3#0SKm6osD(koyaG{^oC)gj$3^?TNGCcZwg-ue~LhgV2V(Ra5{Sw zcZx_9Pl{+dLkdfZSc-UxM2cjJR60v0V~X?~mUPA_-V~WAz7*LMxm3n1rUm?|Y$@^! znNk$yFl91E38W~dC;?R}rYM6+6)>rq$(YU(C77ZXC6uBbC7i+%B?82vDcUSiVksI? z;&6jB7cv1Ykbv{G7BWRirZ5FFXlifHVN_t+{D4`IW%6+jc}A(p&pBM#Z?U?#I)%DV xHsn;8T+KOias`(Tn>x^+Me37RaXB+qO@7BE#r%_nd$KThBs&`m6VHDZW&q#qL;L^$ diff --git a/superlists/__pycache__/urls.cpython-38.pyc b/superlists/__pycache__/urls.cpython-38.pyc index 5d7c283aedc2a818328daa45c5532be50733fe7e..75f6a0dd97e5aea74e14424bd59c0b4fcf184a3e 100644 GIT binary patch delta 188 zcmeysw2@gmgqN3#0SMZET#xl&WMFs<;vfSyAjbiSi<2g5YultSq%h}j