From 3931a1f24e037a3e266883b3e6f4db084b21cffe Mon Sep 17 00:00:00 2001 From: anggoro dwi Date: Tue, 16 May 2023 00:26:33 +0700 Subject: [PATCH 1/5] bugfix moodle xml file in curent dokumen file, test file, and migrate to showprogress bar --- Scripts/Python/Library/gquiz.py | 7 ++- Scripts/Python/Library/moodleQuiz.py | 6 +- Scripts/Python/migration_gdrive_link.py | 64 ++++++++++++++++++++++ Scripts/Python/quiz_generator.py | 48 +++++++++------- Scripts/Python/test_gquiz.py | 29 ++++++++++ Scripts/Python/test_quiz.py | 33 ----------- myedu.ods | Bin 42128 -> 42341 bytes secret/place_the_client_secretes_here.txt | 13 ++++- 8 files changed, 143 insertions(+), 57 deletions(-) create mode 100644 Scripts/Python/migration_gdrive_link.py create mode 100644 Scripts/Python/test_gquiz.py delete mode 100644 Scripts/Python/test_quiz.py diff --git a/Scripts/Python/Library/gquiz.py b/Scripts/Python/Library/gquiz.py index cde4489..b32022d 100644 --- a/Scripts/Python/Library/gquiz.py +++ b/Scripts/Python/Library/gquiz.py @@ -26,6 +26,7 @@ class gquiz: self.infoPrint = self._defaultPrint self.progress = -1 self.resultUri = "" + self.savePath = './' self.submition["requests"].append({ "updateSettings": { @@ -40,6 +41,10 @@ class gquiz: def setProgress(self, i : int): self.progress = i + + def setSavePath(self, path): + self.savePath = path + def AttachProcessInfo(self, callback): self.infoPrint = callback @@ -71,7 +76,7 @@ class gquiz: self.infoPrint("refresh token",self.progress) else: flow = InstalledAppFlow.from_client_secrets_file( - './secret/client_secrets.json', SCOPES) + self.savePath+'/secret/client_secrets.json', SCOPES) creds = flow.run_local_server(port=0) self.infoPrint("generate token",self.progress) # Save the credentials for the next run diff --git a/Scripts/Python/Library/moodleQuiz.py b/Scripts/Python/Library/moodleQuiz.py index 850821c..c8152f2 100644 --- a/Scripts/Python/Library/moodleQuiz.py +++ b/Scripts/Python/Library/moodleQuiz.py @@ -9,6 +9,10 @@ class moodleQuiz: self.progress = -1 self.resultUri = "" self.data = ET.Element('quiz') + self.savePath = '.' + + def setSavePath(self, path): + self.savePath = path def setProgress(self, i : int): self.progress = i @@ -82,6 +86,6 @@ class moodleQuiz: def update(self): ET.indent(self.data) print(ET.tostring(self.data)) - ET.ElementTree(self.data).write("./moodleXMLMultichoiceQuestion.xml") + ET.ElementTree(self.data).write("{}/{}".format(self.savePath, "moodleXMLMultichoiceQuestion.xml")) diff --git a/Scripts/Python/migration_gdrive_link.py b/Scripts/Python/migration_gdrive_link.py new file mode 100644 index 0000000..aede89f --- /dev/null +++ b/Scripts/Python/migration_gdrive_link.py @@ -0,0 +1,64 @@ +# coding: utf-8 +from __future__ import unicode_literals +import sys, os +import requests +import importlib + +# to run separatly from soffice +# $ soffice --calc --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager" + +sys.path.append("/lib64/libreoffice/program/") + +from scriptforge import ScriptForge, CreateScriptService +from unohelper import fileUrlToSystemPath + +sys.path.insert(0, '{}/{}'.format(os.getcwd(),'Library')) +ScriptForge(hostname='localhost', port=2002) + +from gquiz import gquiz + +ui = CreateScriptService("UI") +doc = CreateScriptService("Calc") +bas = CreateScriptService("Basic") + +q = gquiz() +q.generateService() + +def get_file_id_from_link(link): + # Find the starting index of the file ID + start_index = -1 + if "/d/" in link: + start_index = link.index("/d/") + 3 + elif "id=" in link: + start_index = link.index("id=") + 3 + elif "rs/" in link: + start_index = link.index("rs/") + 3 + + if start_index != -1: + # Find the ending index of the file ID + end_index = link.index("/", start_index) + if end_index == -1: + # If there is no trailing "/", use the end of the string + end_index = len(link) + + # Extract the file ID + file_id = link[start_index:end_index] + return file_id + else: + # Return None if no file ID is found + return None + +cells = doc.getValue("") + +for col in range(0, len(cells)): + for row in range(0, len(cells[0])): + if(str(cells[col][row]).startswith("https://")): + print("found the culprit!!") + url = cells[col][row] + print(url) + Id=get_file_id_from_link(url) + file = q.drive_service.files().get(fileId=Id).execute() + newCell = "/asset/{newname}".format(newname=file["name"]) + print("{new} <- {old}".format(new=newCell, old=cells[col][row])) + doc.setValue(doc.Offset("A1",col,row),newCell) + diff --git a/Scripts/Python/quiz_generator.py b/Scripts/Python/quiz_generator.py index e087768..2cf2580 100644 --- a/Scripts/Python/quiz_generator.py +++ b/Scripts/Python/quiz_generator.py @@ -13,27 +13,26 @@ import importlib from scriptforge import ScriptForge, CreateScriptService from unohelper import fileUrlToSystemPath -#[start] comment for run separatly from soffice -if (not 'gquiz' in sys.modules) or (not 'moodleQuiz' in sys.modules): - doc = XSCRIPTCONTEXT.getDocument() - url = fileUrlToSystemPath('{}/{}'.format(doc.URL,'Scripts/python/Library')) - sys.path.insert(0, url) -else: - importlib.reload(gquiz) - importlib.reload(moodleQuiz) - -#[end] -#[start] uncomemnt for run separatly from soffice -#sys.path.insert(0, '{}/{}'.format(os.getcwd(),'Library')) -#ScriptForge(hostname='localhost', port=2002) -#[end] - -from gquiz import gquiz -from moodleQuiz import moodleQuiz - ui = CreateScriptService("UI") doc = CreateScriptService("Calc") bas = CreateScriptService("Basic") +url = fileUrlToSystemPath(XSCRIPTCONTEXT.getDocument().URL ) +curpath = '/'.join([url.split('/')[x] for x in range(0,len(url.split('/'))-1)]) +if not ui.Activate(url) : + bas.MsgBox("Error no window active",bas.MB_OK) + +def _load_module(): + #[start] comment for run embeded module + if (not 'gquiz' in sys.modules) or (not 'moodleQuiz' in sys.modules): + doc = XSCRIPTCONTEXT.getDocument() + urlem = '{}/{}'.format(url,'/Scripts/python/Library') + sys.path.insert(0, urlem) + _statusBarInfoUpdate("Load embedded modul link form {}".format(url),0) + #[end] + #[start] uncomemnt for run separatly from soffice + #sys.path.insert(0, '{}/{}'.format(os.getcwd(),'Library')) + #ScriptForge(hostname='localhost', port=2002) + #[end] def MakeTemplate(): doc.SetArray(doc.CurrentSelection, \ @@ -45,11 +44,11 @@ def MakeTemplate(): "", "", "", ),)) def _statusBarInfoUpdate(text : str, progress : int): - ui.SetStatusbar("{}% {}".format(progress,text), progress) + ui.ShowProgressBar("loading...", "{}% {}".format(progress,text), progress) def _updateQuestion(q): selctedCell = doc.CurrentSelection - cwd = os.getcwd() + cwd = curpath maxRow = doc.LastRow(selctedCell)+1-doc.FirstRow(selctedCell) for nrow in range(0, maxRow): q.setProgress(int(((nrow+1)/maxRow)*100)) @@ -82,21 +81,28 @@ def _updateQuestion(q): q.update() def GoogleQuiz(): + _load_module() + from gquiz import gquiz q = gquiz() + q.setSavePath(curpath) q.AttachProcessInfo(_statusBarInfoUpdate) q.setProgress(0) q.generateService() q.createForm("Demo Soal") _updateQuestion(q) ui.SetStatusbar("creating google form quiz done!") + _statusBarInfoUpdate("Finish!!",100) bas.InputBox("Open link to edit your form:","Your Google Form Quiz, done!", "{}".format(q.resultUri)) def MoodleQuiz(): + _load_module() + from moodleQuiz import moodleQuiz q = moodleQuiz() + q.setSavePath(curpath) q.AttachProcessInfo(_statusBarInfoUpdate) q.setProgress(0) _updateQuestion(q) ui.SetStatusbar("Done!") - bas.MsgBox("Check *.xml file in curent folder!") + _statusBarInfoUpdate("Check *.xml file in curent folder!",100) g_exportedScripts = (MakeTemplate, GoogleQuiz, MoodleQuiz) diff --git a/Scripts/Python/test_gquiz.py b/Scripts/Python/test_gquiz.py new file mode 100644 index 0000000..c36fdc9 --- /dev/null +++ b/Scripts/Python/test_gquiz.py @@ -0,0 +1,29 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import sys, requests +from unohelper import fileUrlToSystemPath + +def gquiz_test(): + if not 'gquiz' in sys.modules: + doc = XSCRIPTCONTEXT.getDocument() + url = fileUrlToSystemPath('{}/{}'.format(doc.URL,'Scripts/python/Library')) + sys.path.insert(0, url) + from gquiz import gquiz + + q = gquiz() + + q.generateService() + + q.copyFile("16-rh3W-NwYzdKVBZJmi574sTWe_rMIdE-FQSw_33qXI", "Soal Masuk Penjara") + opt = [ q.createOption("A.","./asset/option1.png"), + q.createOption("B.","./asset/option2.png"), + q.createOption("C.","./asset/option3.png"), + q.createOption("D.","./asset/option4.png"), + q.createOption("E.","./asset/option5.png") ] + + qq = q.createQuestion(title = "Soal No 1",\ + description = "Dari gambar dibawah ini, ada bagian gambar yang hilang. Dari pilihan dibawah, manakah gambar yang benar?",\ + indexAnswer = 4, options = opt, itemImage='./asset/test_image.png') + q.submitQuestion(0,qq) + q.update() diff --git a/Scripts/Python/test_quiz.py b/Scripts/Python/test_quiz.py deleted file mode 100644 index 6db6933..0000000 --- a/Scripts/Python/test_quiz.py +++ /dev/null @@ -1,33 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -import sys, requests, os -from unohelper import fileUrlToSystemPath - -sys.path.insert(0, "{}/{}".format(os.getcwd(),"Library")) -from gquiz import gquiz -from moodleQuiz import moodleQuiz - -def test(q): - opt = [ q.createOption("A.","./asset/option1.png"), - q.createOption("B.","./asset/option2.png"), - q.createOption("C.","./asset/option3.png"), - q.createOption("D.","./asset/option4.png"), - q.createOption("E.","./asset/option5.png") ] - qq = q.createQuestion(title = "Soal No 1",\ - description = "Dari gambar dibawah ini, ada bagian gambar yang hilang. Dari pilihan dibawah, manakah gambar yang benar?",\ - indexAnswer = 4, options = opt, itemImage='./asset/test_image.png') - q.submitQuestion(0,qq) - q.update() - -os.system("mkdir asset && mkdir secret") -os.system("cp ../../asset/* ./asset") -os.system("cp ../../secret/client_secrets.json ./secret") - -q = moodleQuiz() -test(q) - -q = gquiz() -q.generateService() -q.createForm("test") -test(q) diff --git a/myedu.ods b/myedu.ods index eea97892730d73fa479dd11b85eedd95d7ac6c33..6328a25616f92d4d19abceeee7d6fc0a8307b97c 100644 GIT binary patch delta 6096 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 abur^#8H55$kygb_;KO?=Vv+YJMgIfH!tNyi delta 5927 zcmaKQbx_<%xAx574uL^KkQrQpyGw8w5*&iN2S|bhemDcc2X_y!B)AhSxH}0XNFX=^ z1Pij^vQ=MwyZ7Gr?)j^$&vUx_Ij5?-&+}shk~j=WG=bvc;(}ZNX9Lhb>>;WrpP@FM z6T*puJN*qt#0~+0rZ7Mtga!sC1?WFTz(FX&0#@MA@SDf72q|!B(c?@FFRV)jDf8RD zNRnw$3_gQ7;=4NHhor?5^T+6MIBQXE0;@?WuIdKq(q}J%`29K(R_Tx8-{q@TaPl_4 zD-m?P8Vz;QM-^G-?g~+0t-ma8V9MPb!iiYJ7J?oYz4LG+cx*w~-fpsKDJ0iPi3k%~ zYynssSoZh(izpi0)ZXi{tW|CR`MkKlIV~OIHQZyEo#bogW)COby?HaQ3tEM2f8b%o zOlecAJUkUKaT6{`g&OC@CM3oRbfv(x75&mrK|)i|HkZlU0TU2B|LtcLAW$rPIP z%@oF9j;|odT|7*!0V`Tpi26cmve=b76F~R9TCku~95uy6e80ll+vQKuLlW`a-8N?s zNd;Iu0Urp{vwuKbS1VXPM#(k&Cq@yJ3JKdpc|WpOT^4{=xQZT-~+;Q zUk8leP)z29o(YFMl<6Y*Y}R5Bc(I+G{x}C0jz(a-pK>=3DenJJ(`(C_^r`!1z?0>s z{8m{RCqqy8Tkl?OvXx`GE8Cao6psQ7J=No>%(7B_ItRE+o}Fj2eS(J;4}^H)fkSSU zfi0x_O1h0oFN)Tc;=2#-6Q6~|n0;Vg3m)4U&6keGTAO(ExMI!JPaTu*bYJUiZ~f$; z+^=zzY5UJd_(;m3&r*sQmEc`|`=k}jFUK1v%A4Y?G`kEz(=^r1CG#xmdHF!g?b&jF zyC_xq{^@CPl**iXL=Snh4-ttddyQ?;2DEUXyw?xmDq%L-OS8&uw&=KkWe2RFNjXLG ze;DbU;$Sc(%uEhi4Dg>G`aCV=_2E|irE5v@>7iioh)9N*G~rc1X;xEU(@`_+@$)1R zda7Cfmc0TZ&R$Pg4Kt^s#`yCJ+YImp!^sQdo^LLOSS|bri!tcLqWOlr$K@vD6;5(B znfI!tMzqU8Qb&h=M|h!sK0Yv1fCF2lXqszPqhF?UkC#zYM?rx6U3NA1NZCN~t^4ip4vw ze%;<2|M+~i*IfP8Id;{&T$cNY?~)}>k7ekgh_EP%b-(CPa>pmKLGfg^Q*zjIhfCkP zEB_*8%aoTuk`mf6@)dAer(Ib$<4C1PM(f6phI(E7kfko_R$62f$q3?RUz1FZ3uanB}f)T9-Q$maui%obGX%@ae<1@7oFet-o*(8aTL(pJ{89FhL+a zqJO)581ApGXEt6=o+$Ey2dIPsT;Q8=fX7A)+1<@g4x=&xwfBbZ?xqENmK09OZbS{u z3AQBcW{L>-(v~u1BOK}>a{T&;kYhN7TO9p}lAV*0BeCs;8Xk9dt+@Ha*XM#*vOB3UifW@|!9x@FxisbFKyatcP zIOlmDI}X8=Mr5gVoS&UNurfK3%xw@;C6j);zZu(&s$=;Twr!@8RBhBmcpxT|w=H~U zF_OwmKGU&L{H1Kjdfc94tSW=mpUAYVZz$>HHsp4E=a<2d*5hYiA8%&+_A_rnIanF| zdYKc`HSwN@5zX03Eo55{3zjJ`8QSoD{&iw)Mwy9xwp1e_n`+$335+6YW8{sh2$s@R zQZMN~v<_L#3%-xjU_0&qpw)uexc5Bxf-R|DM4s~swvR{@8D`z`3y<}uIex>jLN};$ zD2IuT8P&}05piScR~PU^r*w2W>h$ncUBShdLh^{pC0F;`a5su9{q|&=Z?#65v0kqV zyk{!yftN@hP2CC_03>`mfXeVr;uHD}OLjiF1oSMz>m2MDvZb9COE`1r??9}w3~OJj z8h$`}9cX8RVu$rI9rTcB5BNy;WY4FY3=Y#$!}$a;x(uWqfRb*+{B{IhJhzxVuyg8{ z?^mmTOpE!{Bwm$A!B8fQP9|{WBlD!BGqc!2kd~VtX8Z&fkcRQ7cvOq<5`@`0&(AoP z>uV`~hmT%b_85nEhX|C{#N{I?DdCB8FH*oUconCDb_v|%SSZdaOG&cq7n~35o-#mS zeu$Rs7T+0{q)W)?;e7k0XtQOTAL?@XP{ftdkfsc|Z_^Nhf24e^L;_1qq*}~|-$6AL z!<#JXA3X)20=#8!Bm2(@&+e|aHoA)TUmNmX7(bV+3Rp}TL|m3YMXYBz zuJ=4vg6;L1Ny@5(@U1e~nUg0t;lv;B^ESr=HtI9@#ItgJjSMqWe_XML8zbwubn+dg zm=qMG*$-{*qFonB1%}AZDU*RXBDw5PLJ10**%}t0+yR+p#(8+$x5DJQa#e@sRJe%1 z_7g1vdV)`{Lk5lI78$)7$wu>Fe}^P8b*uM;p-J| zjbq4s(LqP`(reR*RW5!Zi)YaVQjq;x;qx-!4~~Y?cvh5tQ{Pz%+&AZ8HrrcN?n4Z} z8=i*qiIbFu>Aj!PJ-;|i*)0tu(ZGng_62v*$Gv+}ly~NR)1(W$yEs}QEf*1Dm+06) z3I&^_j_U|yH}TQDnn$|nDvAdZ>>Kk*wACifxZajo%-i$dB-iwcD;1EeznOj&=7tSe z`g*{)cSIAXq<=gdb(y6yN*UqR8rj%S+^Im+btRaUYb+#4 za|Yk^)?7HVnmXP@PNLxmtop$5_!9{rE7nBSKWiG!VdGaW&!vZf&72oM=4xBw(!PN| z0RF=*nqMRodgE-F^Ig@z*h=98|JKlt8)KC3!xut2IsM@cr5TA|gvrVb^aWp{Ec?8v z(ESnEkM8F7xvdnhl6IeN@sJ&HL!)SITNLA-mhK9r*@@Ie@r3;F8cl_9ztoWfaHjgw zJ6EG{n@;g+5ZBUCUCt6>;i@#B(3=BF7!BN=I3LvsVMGOsQkt{h#l>TFCYmy2J-hQR zK&ejjTCt(Ew=z3&p~e!2*lN%*>W@BkuX}iRHm1qH{`x%RhIzYn8wv~Q65=i+su%yk z@w~<9Jn&~Ff#XqC0(Xf#ot{Df(Djwf(4IKC{oq_OO6uyRgo zOPZ!!iU#q0YH0QPvOFzboYiC5#RRXcCA-o}4Hz^f3|OwG>TMGyRP<^9v{f%?lq!#u zdllFNmL9b@&}N2*j|n)mMIV+E?hc_Y&1(qSEHSDSm-)t}5Af7~@Q`Xtkr#ZMMUquu zu%|lP;tXA&&E%yw1pJN?_~Qe43hXNO$hX za2M%7llcpwBXX}l?Di*cq7lK;8J{+Aw}iO!g`Ddv{<(#@w;y?(z=l{Angbwv%GK#psmQF4L0NkIFLv@d<=WWyHD3xu z1bql~!=}4%uu~MsY4Bko%IHX3hyWd2wN@rmsXP@SL(Gx8ZS15pyvMb=X*EUClj}_j zzlNNh_gkA!^M=v`#&29IN#=HKc?yEw_)hyq8p%RM#AM9PCs(GYkK-<7bXbK63E#eQ z?w8#M_Ia*i=fL0})-?ul%V<&GGYi90|EMzVz&kJV(Q5!PLsE4q9V0>Oif%n#=h@?2 z1-_l!D%`xCyi?unYP;G+Z*7QD-Tlt|CV!$rCt*=E#?}sKpNsn1X#{LDZ!IJ)tAkaJ zx58Fy)ji%Ghp*X{#*v!E;as6##%IbQTko(EKdbK@tVAOJ9DGteq2RG&Q{0~j`%#ug z^xXaiPog&Tl95Nb$8#n1Xo@6$x82Fc&cn-|PbX$8`>XkLF(;9gKNPx7Io`J~vz7Ed z>?c3rH%|%w_%`E0oy5}e7JB7D03&YnaXoEyfbHbUobJT88o7T?G zvbU4v;SBVX_)#4Yhmk&eFgdJ2&4`Bx1S>;2(?_m z47@jR`>SpJEp>-)@Z73W*H&`8jp;oOT-yZGF{?>ClDNW(Z{`atbF_fk`-{-qOL{dm z13S_EsJ$>A`lClH(w7P{EJ;W|5n1Mlyu-WcOtqxsT_1xTg*w!Y%P+nt^uIEBth5jibs*4+ zz9z2LhD=hZYTbl<={=Gw>J~RxG+<{U<1Q1?11?QWly_mN8FRyt(+t(I^fHa1gM#V|Fb?^}XsbZYN_XP#pN@ma+y z=i&=h8haDxWUn4Me-${Fjw3H?(cSIigHat2e_$LZpDWHz?xCC;d|KByep#OQK*Np@ zPbupyH={+B^*LhiV`pe8>ns0)-hA`5k1}1prUZOXTjbL+EaEC9&S_6@13zp|E_HJXkwPqd=*9k_K<|;+D z9MxX<@Tn{7httm`x^(BTqK3XYp)lfVMrX3L;}2F^1+04&&sPcA{h{;S1#r5I=ZLdt2-!Iz zx)`6K<85B#4t2WIWX7J59~L;!bM?eAm2k|nE0+VUxH-CCVLdXyRd#t7%eLwZrT$vLKp5I{L?orj)B8=+ImA48R5s=kr}1;c zudPufHjzSlM*HI;G9dk&LWgMMFfJpJiMBayIY4=pe}ztS2*q?Fb%%5X7hKNwv=PE2 zEzIn)IPtUfDR|(4el1j2@^}G!Cm5Q)%s*;`QJlI?MCLbJxe$DEYS=dV2B(I399t(( zS!)Y?2+nyw<~D$q>a8G&)Rda4?SpA$G+x|VEPbA%oEndu1w4#(wg*aMQhUlco4$Cq z9Vuh4qHE2HTE3T|)yH2#TGryQG^Q$t^^A{u(s`O}JVluV>!T)4f7?bqnzS~WPt~hm z%saA!kc~f7`9*0o=Iu>O$p5J8OM1WC$jienx4a)SPTY#3-t0eJ9HvZ}w$L?I+B}M( z(iTp3URAm|MEqB30SC?gum zRD8F7yU9Eh?h{iXl$Vc=VpA)|O!IAgs$5jfQca9{d;JVDvnk}J3Q*R{s!uz;MG^=% z3&m2BeoNY3=hQmLogeEjPefbi_A$okI>U6lW zVuL{CjQ{szQLidg^B2}MQ#v~L9_y&_FIZy9ajbi49uZRRt@jDZhTl{BA~$FDAE?!L zHMP&Rt;(mleEfv5}R>codq(#IKS}K%$p%Mf^g>s^P zg!BJ4MpYFuL6B6aLTVP&Ss^E+gdN3Lqy$-FN7)xW0Y5;!FVckQaG-9ARKd|Gh9WAI zX)zz9hXWN?%zDrFh?5F6T8vL~!vO-hS-Cse+j;x&dfD3l|0AN%#Y|8Mu6wVYj}@=4 zo9o{mcnK2~lm`Uz_VIJI^ZxHXvl1qVw;&2Af!=TOrvw$MsstabhH5Sm2TP$&N?`Z1 aA9ATs+@<(ne3WP@9RJ;Y&1UodBL82Dc8Hk( diff --git a/secret/place_the_client_secretes_here.txt b/secret/place_the_client_secretes_here.txt index 9766475..ecc68a2 100644 --- a/secret/place_the_client_secretes_here.txt +++ b/secret/place_the_client_secretes_here.txt @@ -1 +1,12 @@ -ok +Authorize credentials for a desktop application +To authenticate as an end user and access user data in your app, you need to create one or more OAuth 2.0 Client IDs. A client ID is used to identify a single app to Google's OAuth servers. If your app runs on multiple platforms, you must create a separate client ID for each platform. + + In the Google Cloud console, go to Menu menu > APIs & Services > Credentials. + + Go to Credentials + Click Create Credentials > OAuth client ID. + Click Application type > Desktop app. + In the Name field, type a name for the credential. This name is only shown in the Google Cloud console. + Click Create. The OAuth client created screen appears, showing your new Client ID and Client secret. + Click OK. The newly created credential appears under OAuth 2.0 Client IDs. + Save the downloaded JSON file as credentials.json, and move the file to your working directory. -- 2.40.1 From b3c669502ccac998605baaa6e86c48af9c13349e Mon Sep 17 00:00:00 2001 From: anggoro dwi Date: Tue, 16 May 2023 07:03:09 +0700 Subject: [PATCH 2/5] migrasi folder --- Scripts/{Python => python}/Library/gquiz.py | 0 Scripts/{Python => python}/Library/imageprovider.py | 0 Scripts/{Python => python}/Library/moodleQuiz.py | 0 Scripts/{Python => python}/migration_gdrive_link.py | 0 Scripts/{Python => python}/quiz_generator.py | 0 Scripts/{Python => python}/test_gquiz.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename Scripts/{Python => python}/Library/gquiz.py (100%) rename Scripts/{Python => python}/Library/imageprovider.py (100%) rename Scripts/{Python => python}/Library/moodleQuiz.py (100%) rename Scripts/{Python => python}/migration_gdrive_link.py (100%) rename Scripts/{Python => python}/quiz_generator.py (100%) rename Scripts/{Python => python}/test_gquiz.py (100%) diff --git a/Scripts/Python/Library/gquiz.py b/Scripts/python/Library/gquiz.py similarity index 100% rename from Scripts/Python/Library/gquiz.py rename to Scripts/python/Library/gquiz.py diff --git a/Scripts/Python/Library/imageprovider.py b/Scripts/python/Library/imageprovider.py similarity index 100% rename from Scripts/Python/Library/imageprovider.py rename to Scripts/python/Library/imageprovider.py diff --git a/Scripts/Python/Library/moodleQuiz.py b/Scripts/python/Library/moodleQuiz.py similarity index 100% rename from Scripts/Python/Library/moodleQuiz.py rename to Scripts/python/Library/moodleQuiz.py diff --git a/Scripts/Python/migration_gdrive_link.py b/Scripts/python/migration_gdrive_link.py similarity index 100% rename from Scripts/Python/migration_gdrive_link.py rename to Scripts/python/migration_gdrive_link.py diff --git a/Scripts/Python/quiz_generator.py b/Scripts/python/quiz_generator.py similarity index 100% rename from Scripts/Python/quiz_generator.py rename to Scripts/python/quiz_generator.py diff --git a/Scripts/Python/test_gquiz.py b/Scripts/python/test_gquiz.py similarity index 100% rename from Scripts/Python/test_gquiz.py rename to Scripts/python/test_gquiz.py -- 2.40.1 From 95290bb69b68edc518415abac270807de0b52e32 Mon Sep 17 00:00:00 2001 From: a2nr Date: Tue, 12 Mar 2024 22:15:06 +0700 Subject: [PATCH 3/5] gdoc init --- Scripts/python/Library/gdoc.py | 239 ++++++++++++++++++++++++++++++++ Scripts/python/Library/gquiz.py | 2 +- Scripts/python/test_gquiz.py | 53 ++++--- 3 files changed, 270 insertions(+), 24 deletions(-) create mode 100644 Scripts/python/Library/gdoc.py diff --git a/Scripts/python/Library/gdoc.py b/Scripts/python/Library/gdoc.py new file mode 100644 index 0000000..d33e7b7 --- /dev/null +++ b/Scripts/python/Library/gdoc.py @@ -0,0 +1,239 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import os.path, time +from google.auth.transport.requests import Request +from google.oauth2.credentials import Credentials +from google_auth_oauthlib.flow import InstalledAppFlow +from googleapiclient.discovery import build +from googleapiclient.errors import HttpError +from pprint import pprint +import requests +from urllib.parse import urlparse + +class gdoc: + def __init__(self): + ''' + Args : + templateId : get the id from link GoogleForm + ''' + self.image_temp_service_url = "https://tmpfiles.org/api/v1/upload" + # self.image_temp_service_url = "https://uguu.se/upload.php" + self.submition = {"requests":[]} + self.form_service = None + self.drive_service = None + self.main_form = None + self.infoPrint = self._defaultPrint + self.progress = -1 + self.resultUri = "" + self.savePath = './' + + self.submition["requests"].append({ + "updateSettings": { + "updateMask": "*" , + "settings": { + "quizSettings": { + "isQuiz": True + } + } + } + }) + + def setProgress(self, i : int): + self.progress = i + + def setSavePath(self, path): + self.savePath = path + + def AttachProcessInfo(self, callback): + self.infoPrint = callback + + def _defaultPrint(self, text : str, progress: int): + print("{}% {}".format(progress, text)) + + def generateService(self): + ''' Start Tokenizing + here is the way to get token + link : https://developers.google.com/docs/api/quickstart/python + ''' + SCOPES = ["https://www.googleapis.com/auth/forms.body", + "https://www.googleapis.com/auth/drive", + "https://www.googleapis.com/auth/drive.file", + "https://www.googleapis.com/auth/drive.appdata"] + DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1" + + creds = None + # The file token.json stores the user's access and refresh tokens, and is + # created automatically when the authorization flow completes for the first + # time. + if os.path.exists('token.json'): + creds = Credentials.from_authorized_user_file('token.json', SCOPES) + self.infoPrint("token already exist",self.progress) + # If there are no (valid) credentials available, let the user log in. + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + self.infoPrint("refresh token",self.progress) + else: + flow = InstalledAppFlow.from_client_secrets_file( + self.savePath+'/secret/client_secrets.json', SCOPES) + creds = flow.run_local_server(port=0) + self.infoPrint("generate token",self.progress) + # Save the credentials for the next run + with open('token.json', 'w') as token: + token.write(creds.to_json()) + + try: + self.infoPrint("creating service",self.progress) + service = build('docs', 'v1', credentials=creds) + self.form_service, self.drive_service = \ + build('forms', 'v1', credentials=creds, discoveryServiceUrl=DISCOVERY_DOC, static_discovery=False),\ + build('drive', 'v3', credentials=creds) + + except HttpError as err: + print(err) + ''' End Tokenizing + ''' + + def createForm(self, name): + """ Create Form + Args: + name : name form + """ + try: + self.infoPrint("creating form",self.progress) + self.main_form = self.form_service.forms().create(body={"info":{"title":name}}).execute() + except HttpError as error: + print('An error occurred: %s' % error) + + def copyFile(self,origin_file_id, copy_title): + """Copy an existing file. + Args: + service: Drive API service instance. + origin_file_id: ID of the origin file to copy. + copy_title: Title of the copy. + + Returns: + The copied file if successful, None otherwise. + """ + + try: + if((self.drive_service == None) or (self.form_service == None)): + raise Exception('please generate service first') + + newFormId = self.drive_service.files().copy(\ + fileId=origin_file_id, body={"name":copy_title})\ + .execute() + print(newFormId) + self.main_form = self.form_service.forms().get(formId=newFormId["id"]).execute() + + except HttpError as error: + print('An error occurred: %s' % error) + + def createOption(self, value, image=None): + ''' + return {"value" : "A. option 1"} + return {"value": "Option", + "image": { + "sourceUri": "", + "properties": { + "alignment": "LEFT" + } + }} + ''' + self.infoPrint("creating option",self.progress) + opt = {"value" : "{}".format(value)} + if(image != None): + self.infoPrint("uploading option image... ",self.progress) + req = requests.post(self.image_temp_service_url,files={"file": open(image,'rb')}) + if(req.json()['status'] == 'error'): + raise Exception("upload failed : {}".format(req.json())) + time.sleep(3) + self.infoPrint("uploading option image... ok",self.progress) + u = urlparse(req.json()['data']['url']) + opt.update({"image" : { + "sourceUri": u._replace(path="/dl"+u.path).geturl(), + "properties": { + "alignment": "LEFT" + } + }}) + time.sleep(3) + return opt + + def createQuestion(self, title, description, options, indexAnswer, itemImage=None): + ''' + Args: + "title" : String + "desc" : String + "indexAnswer" : Integer, index for "options" + "options" : + [{"value" : "A. option 1"}, + {"value" : "B. option 2"}, + {"value" : "C. option 3"}, + {"value" : "D. option 4"}, + {"value" : "E. option 5"},] + ''' + item = { + "title" : title, + "description" : "{}".format(description), + "questionItem" : { + "question" : { + "grading" : { + "pointValue": 1, + "correctAnswers": { + "answers" : [ {"value": "{}".format(options[indexAnswer-1]["value"])} ] + } + }, + "choiceQuestion" : { + "type" : "RADIO", + "options" : options + } + } + } + } + self.infoPrint("create question...",self.progress) + if (itemImage != None): + self.infoPrint("uploading question image...",self.progress) + req = requests.post(self.image_temp_service_url,files={"file": open(itemImage,'rb')}) + if(req.json()['status'] == 'error'): + raise Exception("upload failed : {}".format(req.json())) + time.sleep(3) + self.infoPrint("uploading question image... ok",self.progress) + u = urlparse(req.json()['data']['url']) + item['questionItem'].update(\ + {"image": { + "sourceUri": u._replace(path="/dl"+u.path).geturl(), + "properties": { + "alignment": "CENTER" + } + } + }) + return item + + def submitItem(self, index, item): + """ Submit item to submition + Args: + index : location item in form + item : object item + """ + self.submition['requests'].append({ + "createItem" : { + "location": {"index": index}, + "item": item + } + }) + self.infoPrint("submit question",self.progress) + print(self.submition) + + + def update(self): + self.infoPrint("Updating Form...",self.progress) + # Adds the question to the form + question_setting = self.form_service.forms().batchUpdate(formId=self.main_form["formId"], body=self.submition).execute() + print(question_setting) + + # Prints the result to show the question has been added + get_result = self.form_service.forms().get(formId=self.main_form["formId"]).execute() + self.resultUri = get_result['responderUri'] + print(get_result) + self.infoPrint("Updating Form... Done",self.progress) diff --git a/Scripts/python/Library/gquiz.py b/Scripts/python/Library/gquiz.py index b32022d..0e29fca 100644 --- a/Scripts/python/Library/gquiz.py +++ b/Scripts/python/Library/gquiz.py @@ -210,7 +210,7 @@ class gquiz: }) return item - def submitQuestion(self, index, item): + def submitItem(self, index, item): """ Submit item to submition Args: index : location item in form diff --git a/Scripts/python/test_gquiz.py b/Scripts/python/test_gquiz.py index c36fdc9..5a148db 100644 --- a/Scripts/python/test_gquiz.py +++ b/Scripts/python/test_gquiz.py @@ -1,29 +1,36 @@ # coding: utf-8 +# run it under boring_edu_doc folder +# $ python Scripts/python/test_gquiz.py from __future__ import unicode_literals +import os, sys, requests -import sys, requests -from unohelper import fileUrlToSystemPath +def gquiz_form_test(): + if not 'gquiz' in sys.modules: + sys.path.insert(0, os.getcwd()+"/Scripts/python/Library/") + from gquiz import gquiz -def gquiz_test(): - if not 'gquiz' in sys.modules: - doc = XSCRIPTCONTEXT.getDocument() - url = fileUrlToSystemPath('{}/{}'.format(doc.URL,'Scripts/python/Library')) - sys.path.insert(0, url) - from gquiz import gquiz - - q = gquiz() + q = gquiz() + q.setSavePath("./secret/") + q.setProgress(0) + q.generateService() + q.setProgress(20) + q.createForm("test quiz") + q.setProgress(50) + opt = [ q.createOption("A.","./asset/option1.png"), + q.createOption("B.","./asset/option2.png"), + q.createOption("C.","./asset/option3.png"), + q.createOption("D.","./asset/option4.png"), + q.createOption("E.","./asset/option5.png") ] + q.setProgress(80) + qq = q.createQuestion(title = "Soal No 1",\ + description = "Dari gambar dibawah ini, ada bagian gambar yang hilang. Dari pilihan dibawah, manakah gambar yang benar?",\ + indexAnswer = 4, options = opt, itemImage='./asset/test_image.png') + q.setProgress(85) + q.submitItem(0,qq) + q.setProgress(90) + q.update() + q.setProgress(100) + print("Open link : {}".format(q.resultUri)) - q.generateService() - q.copyFile("16-rh3W-NwYzdKVBZJmi574sTWe_rMIdE-FQSw_33qXI", "Soal Masuk Penjara") - opt = [ q.createOption("A.","./asset/option1.png"), - q.createOption("B.","./asset/option2.png"), - q.createOption("C.","./asset/option3.png"), - q.createOption("D.","./asset/option4.png"), - q.createOption("E.","./asset/option5.png") ] - - qq = q.createQuestion(title = "Soal No 1",\ - description = "Dari gambar dibawah ini, ada bagian gambar yang hilang. Dari pilihan dibawah, manakah gambar yang benar?",\ - indexAnswer = 4, options = opt, itemImage='./asset/test_image.png') - q.submitQuestion(0,qq) - q.update() +gquiz_form_test() -- 2.40.1 From 8a1292ebdeb8e168a66efed523ab6b11b64711a0 Mon Sep 17 00:00:00 2001 From: a2nr Date: Thu, 14 Mar 2024 23:07:12 +0700 Subject: [PATCH 4/5] sudah bisa update text menggunakan test_gquiz.py --- Scripts/python/Library/gdoc.py | 179 ++++++----------------------- Scripts/python/Library/gquiz.py | 37 +----- Scripts/python/Library/gservice.py | 1 + Scripts/python/quiz_generator.py | 51 ++++---- Scripts/python/test_gquiz.py | 44 ++++++- 5 files changed, 110 insertions(+), 202 deletions(-) create mode 100644 Scripts/python/Library/gservice.py diff --git a/Scripts/python/Library/gdoc.py b/Scripts/python/Library/gdoc.py index d33e7b7..cf309be 100644 --- a/Scripts/python/Library/gdoc.py +++ b/Scripts/python/Library/gdoc.py @@ -20,24 +20,13 @@ class gdoc: self.image_temp_service_url = "https://tmpfiles.org/api/v1/upload" # self.image_temp_service_url = "https://uguu.se/upload.php" self.submition = {"requests":[]} - self.form_service = None - self.drive_service = None - self.main_form = None + self.docs_service = None + self.main_docs = None self.infoPrint = self._defaultPrint self.progress = -1 self.resultUri = "" self.savePath = './' - - self.submition["requests"].append({ - "updateSettings": { - "updateMask": "*" , - "settings": { - "quizSettings": { - "isQuiz": True - } - } - } - }) + self.questionKey = [] def setProgress(self, i : int): self.progress = i @@ -56,11 +45,7 @@ class gdoc: here is the way to get token link : https://developers.google.com/docs/api/quickstart/python ''' - SCOPES = ["https://www.googleapis.com/auth/forms.body", - "https://www.googleapis.com/auth/drive", - "https://www.googleapis.com/auth/drive.file", - "https://www.googleapis.com/auth/drive.appdata"] - DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1" + SCOPES = ["https://www.googleapis.com/auth/documents",] creds = None # The file token.json stores the user's access and refresh tokens, and is @@ -76,7 +61,7 @@ class gdoc: self.infoPrint("refresh token",self.progress) else: flow = InstalledAppFlow.from_client_secrets_file( - self.savePath+'/secret/client_secrets.json', SCOPES) + self.savePath+'/secret/client_secret.json', SCOPES) creds = flow.run_local_server(port=0) self.infoPrint("generate token",self.progress) # Save the credentials for the next run @@ -85,155 +70,57 @@ class gdoc: try: self.infoPrint("creating service",self.progress) - service = build('docs', 'v1', credentials=creds) - self.form_service, self.drive_service = \ - build('forms', 'v1', credentials=creds, discoveryServiceUrl=DISCOVERY_DOC, static_discovery=False),\ - build('drive', 'v3', credentials=creds) + self.docs_service = build('docs', 'v1', credentials=creds) except HttpError as err: print(err) ''' End Tokenizing ''' - def createForm(self, name): - """ Create Form - Args: - name : name form - """ + def createDocs(self, name): try: - self.infoPrint("creating form",self.progress) - self.main_form = self.form_service.forms().create(body={"info":{"title":name}}).execute() + self.infoPrint("creating document",self.progress) + self.main_docs = self.docs_service.documents().create(body={"title":name}).execute() except HttpError as error: print('An error occurred: %s' % error) - def copyFile(self,origin_file_id, copy_title): - """Copy an existing file. - Args: - service: Drive API service instance. - origin_file_id: ID of the origin file to copy. - copy_title: Title of the copy. - - Returns: - The copied file if successful, None otherwise. - """ - - try: - if((self.drive_service == None) or (self.form_service == None)): - raise Exception('please generate service first') - - newFormId = self.drive_service.files().copy(\ - fileId=origin_file_id, body={"name":copy_title})\ - .execute() - print(newFormId) - self.main_form = self.form_service.forms().get(formId=newFormId["id"]).execute() - - except HttpError as error: - print('An error occurred: %s' % error) - def createOption(self, value, image=None): - ''' - return {"value" : "A. option 1"} - return {"value": "Option", - "image": { - "sourceUri": "", - "properties": { - "alignment": "LEFT" - } - }} - ''' self.infoPrint("creating option",self.progress) - opt = {"value" : "{}".format(value)} - if(image != None): - self.infoPrint("uploading option image... ",self.progress) - req = requests.post(self.image_temp_service_url,files={"file": open(image,'rb')}) - if(req.json()['status'] == 'error'): - raise Exception("upload failed : {}".format(req.json())) - time.sleep(3) - self.infoPrint("uploading option image... ok",self.progress) - u = urlparse(req.json()['data']['url']) - opt.update({"image" : { - "sourceUri": u._replace(path="/dl"+u.path).geturl(), - "properties": { - "alignment": "LEFT" - } - }}) - time.sleep(3) + opt = { + 'insertText' : { + 'location':{ + 'index': 1, + }, + 'text': "\t{}\r\n".format(value) + } + } return opt def createQuestion(self, title, description, options, indexAnswer, itemImage=None): - ''' - Args: - "title" : String - "desc" : String - "indexAnswer" : Integer, index for "options" - "options" : - [{"value" : "A. option 1"}, - {"value" : "B. option 2"}, - {"value" : "C. option 3"}, - {"value" : "D. option 4"}, - {"value" : "E. option 5"},] - ''' - item = { - "title" : title, - "description" : "{}".format(description), - "questionItem" : { - "question" : { - "grading" : { - "pointValue": 1, - "correctAnswers": { - "answers" : [ {"value": "{}".format(options[indexAnswer-1]["value"])} ] - } - }, - "choiceQuestion" : { - "type" : "RADIO", - "options" : options - } - } - } - } self.infoPrint("create question...",self.progress) - if (itemImage != None): - self.infoPrint("uploading question image...",self.progress) - req = requests.post(self.image_temp_service_url,files={"file": open(itemImage,'rb')}) - if(req.json()['status'] == 'error'): - raise Exception("upload failed : {}".format(req.json())) - time.sleep(3) - self.infoPrint("uploading question image... ok",self.progress) - u = urlparse(req.json()['data']['url']) - item['questionItem'].update(\ - {"image": { - "sourceUri": u._replace(path="/dl"+u.path).geturl(), - "properties": { - "alignment": "CENTER" - } - } - }) + item = [{ + 'insertText' : { + 'location':{ + 'index': 1, + }, + 'text': "{}\r\n".format(description) + } + }] + item = list(reversed(options)) + item + self.questionKey.append(indexAnswer) return item def submitItem(self, index, item): - """ Submit item to submition - Args: - index : location item in form - item : object item - """ - self.submition['requests'].append({ - "createItem" : { - "location": {"index": index}, - "item": item - } - }) self.infoPrint("submit question",self.progress) + self.submition['requests'].append(item) + question_setting = self.docs_service.documents().batchUpdate(documentId=self.main_docs["documentId"], body=self.submition).execute() print(self.submition) - - - def update(self): - self.infoPrint("Updating Form...",self.progress) - # Adds the question to the form - question_setting = self.form_service.forms().batchUpdate(formId=self.main_form["formId"], body=self.submition).execute() print(question_setting) + def update(self): + self.infoPrint("Updating Docs...",self.progress) # Prints the result to show the question has been added - get_result = self.form_service.forms().get(formId=self.main_form["formId"]).execute() - self.resultUri = get_result['responderUri'] + get_result = self.docs_service.documents().get(documentId=self.main_docs["documentId"]).execute() + # self.resultUri = get_result['responderUri'] print(get_result) self.infoPrint("Updating Form... Done",self.progress) diff --git a/Scripts/python/Library/gquiz.py b/Scripts/python/Library/gquiz.py index 0e29fca..0605c6d 100644 --- a/Scripts/python/Library/gquiz.py +++ b/Scripts/python/Library/gquiz.py @@ -21,7 +21,6 @@ class gquiz: # self.image_temp_service_url = "https://uguu.se/upload.php" self.submition = {"requests":[]} self.form_service = None - self.drive_service = None self.main_form = None self.infoPrint = self._defaultPrint self.progress = -1 @@ -56,10 +55,7 @@ class gquiz: here is the way to get token link : https://developers.google.com/docs/api/quickstart/python ''' - SCOPES = ["https://www.googleapis.com/auth/forms.body", - "https://www.googleapis.com/auth/drive", - "https://www.googleapis.com/auth/drive.file", - "https://www.googleapis.com/auth/drive.appdata"] + SCOPES = ["https://www.googleapis.com/auth/forms.body",] DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1" creds = None @@ -76,7 +72,7 @@ class gquiz: self.infoPrint("refresh token",self.progress) else: flow = InstalledAppFlow.from_client_secrets_file( - self.savePath+'/secret/client_secrets.json', SCOPES) + self.savePath+'/secret/client_secret.json', SCOPES) creds = flow.run_local_server(port=0) self.infoPrint("generate token",self.progress) # Save the credentials for the next run @@ -85,10 +81,7 @@ class gquiz: try: self.infoPrint("creating service",self.progress) - service = build('docs', 'v1', credentials=creds) - self.form_service, self.drive_service = \ - build('forms', 'v1', credentials=creds, discoveryServiceUrl=DISCOVERY_DOC, static_discovery=False),\ - build('drive', 'v3', credentials=creds) + self.form_service = build('forms', 'v1', credentials=creds, discoveryServiceUrl=DISCOVERY_DOC, static_discovery=False) except HttpError as err: print(err) @@ -106,30 +99,6 @@ class gquiz: except HttpError as error: print('An error occurred: %s' % error) - def copyFile(self,origin_file_id, copy_title): - """Copy an existing file. - Args: - service: Drive API service instance. - origin_file_id: ID of the origin file to copy. - copy_title: Title of the copy. - - Returns: - The copied file if successful, None otherwise. - """ - - try: - if((self.drive_service == None) or (self.form_service == None)): - raise Exception('please generate service first') - - newFormId = self.drive_service.files().copy(\ - fileId=origin_file_id, body={"name":copy_title})\ - .execute() - print(newFormId) - self.main_form = self.form_service.forms().get(formId=newFormId["id"]).execute() - - except HttpError as error: - print('An error occurred: %s' % error) - def createOption(self, value, image=None): ''' return {"value" : "A. option 1"} diff --git a/Scripts/python/Library/gservice.py b/Scripts/python/Library/gservice.py new file mode 100644 index 0000000..f41c3eb --- /dev/null +++ b/Scripts/python/Library/gservice.py @@ -0,0 +1 @@ +# TODO jadikan satu semua code yang berhubungan dengan autentikasi dan generate service diff --git a/Scripts/python/quiz_generator.py b/Scripts/python/quiz_generator.py index 2cf2580..7db26f2 100644 --- a/Scripts/python/quiz_generator.py +++ b/Scripts/python/quiz_generator.py @@ -47,37 +47,48 @@ def _statusBarInfoUpdate(text : str, progress : int): ui.ShowProgressBar("loading...", "{}% {}".format(progress,text), progress) def _updateQuestion(q): - selctedCell = doc.CurrentSelection + selctedCell = doc.CurrentSelection # cwd = curpath maxRow = doc.LastRow(selctedCell)+1-doc.FirstRow(selctedCell) for nrow in range(0, maxRow): q.setProgress(int(((nrow+1)/maxRow)*100)) item = doc.getValue(doc.Offset(doc.FirstCell(selctedCell),nrow,0,1,17)) - opt = [] - theAnswer = -1 - c = 1 - for o in range(2,17,3): - if (item[o] == 1): - theAnswer = c - if (item[o+1] != ""): - opt.append(q.createOption("{}. {}".format(chr(64+c),item[o+2]),cwd+item[o+1])) - else: - opt.append(q.createOption("{}. {}".format(chr(64+c),item[o+2]))) + # item[0] + # item[1] + # item[2] + # item[3] + # item[4] + # item[5] + # item[6] + # item[7] + # item[8] + # item[9] + # item[10] + # item[11] + # item[12] + # item[13] + # item[14] + # item[15] + # item[16] + opt, theAnswer, c = [], -1, 1 + for o in range(2, 17, 3): # mengambil kolim jawaban saja + theAnswer = c if (item[o] == 1) else -1 + opt.append(\ + q.createOption(\ + "{}. {}".format(chr(64+c),item[o+2]),\ + cwd+item[o+1] if (item[o+1] != "") else None)) c = c+1 if (theAnswer == -1): raise Exception("Chose the correct answer") - - if( item[1] != ""): - img = cwd+item[1] - else: - img = None - - qq = q.createQuestion(title = "Soal No {}".format(nrow+1),\ + + img = cwd+item[1] if ( item[1] != "") else None + qq = q.createQuestion(\ + title = "Soal No {}".format(nrow+1),\ description = item[0],\ indexAnswer = theAnswer, \ options = opt, itemImage=img) - q.submitQuestion(nrow,qq) + q.submitItem(nrow,qq) q.update() def GoogleQuiz(): @@ -88,7 +99,7 @@ def GoogleQuiz(): q.AttachProcessInfo(_statusBarInfoUpdate) q.setProgress(0) q.generateService() - q.createForm("Demo Soal") + q.createForm("Demo Soal") #TODO : put this mundane inside generateService() _updateQuestion(q) ui.SetStatusbar("creating google form quiz done!") _statusBarInfoUpdate("Finish!!",100) diff --git a/Scripts/python/test_gquiz.py b/Scripts/python/test_gquiz.py index 5a148db..8c1d35e 100644 --- a/Scripts/python/test_gquiz.py +++ b/Scripts/python/test_gquiz.py @@ -3,14 +3,20 @@ # $ python Scripts/python/test_gquiz.py from __future__ import unicode_literals import os, sys, requests +if (len(sys.argv) < 2): + print("arg[1] : form, docs, moodle") + quit() def gquiz_form_test(): + ''' + arg[1] = form + ''' if not 'gquiz' in sys.modules: sys.path.insert(0, os.getcwd()+"/Scripts/python/Library/") from gquiz import gquiz q = gquiz() - q.setSavePath("./secret/") + q.setSavePath(".") q.setProgress(0) q.generateService() q.setProgress(20) @@ -32,5 +38,39 @@ def gquiz_form_test(): q.setProgress(100) print("Open link : {}".format(q.resultUri)) +def gquiz_docs_test(): + ''' + arg[1] = docs + ''' + if not 'gdoc' in sys.modules: + sys.path.insert(0, os.getcwd()+"/Scripts/python/Library/") + from gdoc import gdoc -gquiz_form_test() + q = gdoc() + q.setSavePath(".") + q.setProgress(0) + q.generateService() + q.setProgress(20) + q.createDocs("test quiz") + q.setProgress(50) + opt = [ q.createOption("A. asokdjoqwe akls d asj ooijk okiasj "), + q.createOption("B. alskdjl ka aklsdoqwieo q we1i231 kjco23ij"), + q.createOption("C. kasojd skadj0o1042k j 2k3lj2lk 1l2k4k4j"), + q.createOption("D. askdjo2 3 12lk3j kjsdlakoi324o 12kj 4k"), + q.createOption("E. aksdjl io123jo1 kjsdl k l kjlk12j3lkj ksj") ] + q.setProgress(80) + qq = q.createQuestion(\ + title = "Soal No 1",\ + description = "Dari gambar dibawah ini, ada bagian gambar yang hilang. Dari pilihan dibawah, manakah gambar yang benar?",\ + indexAnswer = 4, options = opt ) + q.setProgress(85) + q.submitItem(0,qq) + q.setProgress(90) + q.update() + q.setProgress(100) + print("Open link : {}".format(q.resultUri)) + +if (sys.argv[1] == 'form'): + gquiz_form_test() +elif (sys.argv[1] == 'docs'): + gquiz_docs_test() -- 2.40.1 From 33431c275a8b3bb5d50af51e6e4a31a9d774aa68 Mon Sep 17 00:00:00 2001 From: a2nr Date: Fri, 15 Mar 2024 20:30:18 +0700 Subject: [PATCH 5/5] its works --- .gitignore | 4 +- Scripts/python/Library/gdoc.py | 63 ++++++++++++++++++++----------- Scripts/python/quiz_generator.py | 24 ++++++++++-- Scripts/python/test_gquiz.py | 15 ++++---- myedu.ods | Bin 42341 -> 42313 bytes 5 files changed, 69 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index deff153..139c0ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -client_secrets.json +client_secret.json token.json -__pycache__/ \ No newline at end of file +__pycache__/ diff --git a/Scripts/python/Library/gdoc.py b/Scripts/python/Library/gdoc.py index cf309be..d10194d 100644 --- a/Scripts/python/Library/gdoc.py +++ b/Scripts/python/Library/gdoc.py @@ -86,41 +86,58 @@ class gdoc: def createOption(self, value, image=None): self.infoPrint("creating option",self.progress) - opt = { - 'insertText' : { - 'location':{ - 'index': 1, - }, - 'text': "\t{}\r\n".format(value) - } - } + opttxt = "\t{}\r\n".format(value) + opt = [{'insertText' : { + 'location':{ 'index': 1, }, + 'text': opttxt }}] + if(image != None): + self.infoPrint("uploading option image... ",self.progress) + req = requests.post(self.image_temp_service_url,files={"file": open(image,'rb')}) + if(req.json()['status'] == 'error'): + raise Exception("upload failed : {}".format(req.json())) + time.sleep(3) + self.infoPrint("uploading option image... ok",self.progress) + u = urlparse(req.json()['data']['url']) + opt.append( { 'insertInlineImage' : { + 'uri' : u._replace(path="/dl"+u.path).geturl(), + 'location' : { 'index' : len(opttxt)-1}} + }) return opt def createQuestion(self, title, description, options, indexAnswer, itemImage=None): self.infoPrint("create question...",self.progress) - item = [{ - 'insertText' : { - 'location':{ - 'index': 1, - }, - 'text': "{}\r\n".format(description) - } - }] + itemtxt = "{}\r\n".format(description) + item = [{'insertText' : { + 'text': itemtxt, + 'location':{'index': 1,}}}] + if (itemImage != None): + self.infoPrint("uploading question image...",self.progress) + req = requests.post(self.image_temp_service_url,files={"file": open(itemImage,'rb')}) + if(req.json()['status'] == 'error'): + raise Exception("upload failed : {}".format(req.json())) + time.sleep(3) + self.infoPrint("uploading question image... ok",self.progress) + u = urlparse(req.json()['data']['url']) + item.append( { 'insertInlineImage' : { + 'uri' : u._replace(path="/dl"+u.path).geturl(), + 'location' : { 'index' : len(itemtxt)-1 }} + }) item = list(reversed(options)) + item self.questionKey.append(indexAnswer) return item def submitItem(self, index, item): self.infoPrint("submit question",self.progress) - self.submition['requests'].append(item) - question_setting = self.docs_service.documents().batchUpdate(documentId=self.main_docs["documentId"], body=self.submition).execute() - print(self.submition) - print(question_setting) + for _item in item : + submition = {} + submition["requests"] = _item + print(submition) + r = self.docs_service.documents().batchUpdate(documentId=self.main_docs["documentId"], body=submition).execute() + print(r) def update(self): self.infoPrint("Updating Docs...",self.progress) # Prints the result to show the question has been added - get_result = self.docs_service.documents().get(documentId=self.main_docs["documentId"]).execute() - # self.resultUri = get_result['responderUri'] - print(get_result) + # get_result = self.docs_service.documents().get(documentId=self.main_docs["documentId"]).execute() + self.resultUri = self.main_docs["documentId"] self.infoPrint("Updating Form... Done",self.progress) diff --git a/Scripts/python/quiz_generator.py b/Scripts/python/quiz_generator.py index 7db26f2..87cdeab 100644 --- a/Scripts/python/quiz_generator.py +++ b/Scripts/python/quiz_generator.py @@ -46,11 +46,12 @@ def MakeTemplate(): def _statusBarInfoUpdate(text : str, progress : int): ui.ShowProgressBar("loading...", "{}% {}".format(progress,text), progress) -def _updateQuestion(q): +def _updateQuestion(q, isReverse = False): selctedCell = doc.CurrentSelection # cwd = curpath maxRow = doc.LastRow(selctedCell)+1-doc.FirstRow(selctedCell) - for nrow in range(0, maxRow): + rnge = reversed(range(0, maxRow)) if isReverse else range(0, maxRow) + for nrow in rnge: q.setProgress(int(((nrow+1)/maxRow)*100)) item = doc.getValue(doc.Offset(doc.FirstCell(selctedCell),nrow,0,1,17)) # item[0] @@ -72,7 +73,8 @@ def _updateQuestion(q): # item[16] opt, theAnswer, c = [], -1, 1 for o in range(2, 17, 3): # mengambil kolim jawaban saja - theAnswer = c if (item[o] == 1) else -1 + if (item[o] == 1) + theAnswer = c opt.append(\ q.createOption(\ "{}. {}".format(chr(64+c),item[o+2]),\ @@ -105,6 +107,20 @@ def GoogleQuiz(): _statusBarInfoUpdate("Finish!!",100) bas.InputBox("Open link to edit your form:","Your Google Form Quiz, done!", "{}".format(q.resultUri)) +def GoogleDocs(): + _load_module() + from gdoc import gdoc + q = gdoc() + q.setSavePath(curpath) + q.AttachProcessInfo(_statusBarInfoUpdate) + q.setProgress(0) + q.generateService() + q.createDocs("Demo Soal") #TODO : put this mundane inside generateService() + _updateQuestion(q, True) + ui.SetStatusbar("creating google form quiz done!") + _statusBarInfoUpdate("Finish!!",100) + bas.InputBox("Open link to edit your form:","Your Google Form Quiz, done!", "{}".format(q.resultUri)) + def MoodleQuiz(): _load_module() from moodleQuiz import moodleQuiz @@ -116,4 +132,4 @@ def MoodleQuiz(): ui.SetStatusbar("Done!") _statusBarInfoUpdate("Check *.xml file in curent folder!",100) -g_exportedScripts = (MakeTemplate, GoogleQuiz, MoodleQuiz) +g_exportedScripts = (MakeTemplate, GoogleQuiz, GoogleDocs, MoodleQuiz) diff --git a/Scripts/python/test_gquiz.py b/Scripts/python/test_gquiz.py index 8c1d35e..b66faa4 100644 --- a/Scripts/python/test_gquiz.py +++ b/Scripts/python/test_gquiz.py @@ -53,16 +53,15 @@ def gquiz_docs_test(): q.setProgress(20) q.createDocs("test quiz") q.setProgress(50) - opt = [ q.createOption("A. asokdjoqwe akls d asj ooijk okiasj "), - q.createOption("B. alskdjl ka aklsdoqwieo q we1i231 kjco23ij"), - q.createOption("C. kasojd skadj0o1042k j 2k3lj2lk 1l2k4k4j"), - q.createOption("D. askdjo2 3 12lk3j kjsdlakoi324o 12kj 4k"), - q.createOption("E. aksdjl io123jo1 kjsdl k l kjlk12j3lkj ksj") ] + opt = [ q.createOption("A.","./asset/option1.png"), + q.createOption("B.","./asset/option2.png"), + q.createOption("C.","./asset/option3.png"), + q.createOption("D.","./asset/option4.png"), + q.createOption("E.","./asset/option5.png") ] q.setProgress(80) - qq = q.createQuestion(\ - title = "Soal No 1",\ + qq = q.createQuestion(title = "Soal No 1",\ description = "Dari gambar dibawah ini, ada bagian gambar yang hilang. Dari pilihan dibawah, manakah gambar yang benar?",\ - indexAnswer = 4, options = opt ) + indexAnswer = 4, options = opt, itemImage='./asset/test_image.png') q.setProgress(85) q.submitItem(0,qq) q.setProgress(90) diff --git a/myedu.ods b/myedu.ods index 6328a25616f92d4d19abceeee7d6fc0a8307b97c..6258b2610961d7b3ea5c440c8dccb832ae638b7f 100644 GIT binary patch delta 39162 zcmY(qb8u!))GhqPwrx9^i7~Nl+qUz>6FZsMnAo;$+qRv2^Ly|8s_t7|r@K$@{ok%r zd!4mbAC7^Jj)5X7NP~f+0|3wf0Hc|`Mm(Yd>VGSRAhV|-H~=t#0058!65(?x>(Rli z!T%?=j-~Cq_b-2y5C9tVZ$bI$c*UTf4=K!6x4Y8HWi~*!Ot3|0 zXl5EERA>n$mTs7gq_>i!m1DmFUc=LjCed@9=0TzVtjS3Ak(fGX6F$l$Cp~=i5|Zll zdM>F?M%P9aEm!)JAd0fPE+ip4mI)RkinA;;l*Y|dP8kdvsbMcBa?em-zAOZ+V8a|L z+6vYhY85h|UR_S0sXQYPSii2M0A2PWqD&~FU&fy*omKx$;w~BtM_Nz6KkkqmuG?vp zLPubZBh3`K#~0N;z86S^^ZTmOWaua#LChND?Z2skc2*cA1K4KU*5iDdf<(_EYS0OGRIK5B%+by+ zHjNJ~uuofxn=pW%%XSAce}^sdP0VjAvT_goRp!A44?P-n#wAzJ0l=m5XtJ_~tv^rU z$2N&S^=c*(5kCx%fl!Ky1q=5CC1&cJwuLvRY^%lmO(83CUFPoUJMF)duG}{P10}Dy zhYu`XBL{iY92)g?C*!EHnlNlui&N#XeEKU$QbZA^Rywmd%^U-i&v~{Vz0XcxiEY#` zxFifPuKzh6Fv?;g#lHgVCr1uv^{I=@3Byd$Lq6kNQ2}s_c<8{{IJ&hjmra65&>mSb0X5Q>DjM}urVmGOr zDAqt3vH-(i6nz7Vh)0?Qo#WWt&QBf##g>VxboOd*ro_5!X$P<`{(i%E(~OLq_CxTQ z&|%Uq9>zI4K`jaDHMqe5)qZJ8!L1BqSAkpIp@*YI;h`SWphsZH*wGXEgc|E`@$?Dq z)Ft_Qfo_bm_+*dRfvF7>C|Z-eHm}qal!oRC$Fm@a2YLY^8}^he&E@Gg4DYk5&k_jh z#1W(Ry`fI|sD9~mW}V?1*@jyQYT)LjplIba&i=hKo>{BTBIIwpMK{lNeG`e|by<)) z=utFj68a=&Hh%d7wlmN3?c0P})U>P3e`Lm0LDuq!Qw;{AdIzkj!9NtTGj+0ntyRc;&X2QmR<| zGU2h{(kC}G&_hd;71tP^#}- zCpcO%IvULUiXFNSmnnub3C8E5Ev(&Sz-f`3jW?2!-4_&+TWXL3U+Z2uWR*8_C~ULkX1DV-zfZ8EVVajw)OtK}iT-W<>iizS-@E$NiD)@)Hp( z{g33w0Bq@8)%hLyT2w?G6@M71G~r`AOa*2jS0_A4k<4UU?mG$b&V^?~iS5r4#ODgB zB-EhPeMY`>1n3U%&hVp)kS0vn9`0?Sz8y1Qw$F5WB#TrAcnW~A<);`eFmfnk->I~k33h&6OJ`xJu!UN4rnA2!L?CuFGFciqgED= z@dFh8dN5`dvE3cE`ZQi;NMrZgq0JPBJ+no?vJDkpT>z|MA(%(|g5iiz#w+p(my@*N z5BGPg6o?b6%O)>%zeF8rWZv_zo4pip*ix*UPWBor*jlD*0_n|p(B^5(hh;_mNapjj z8#Nt=it?>fX%=#&SXw=YnHDM7^aM?cKso$iNV8zfQUTzZT{k?gbBVptnrmfm&UC9K zFIkG+_R1eXmu#b3h#U-x&kRN^PH6S3UZ=hh1<_n)UWo2=y~$QA)mDaw1T5^avxX`Sv*O$#DKHC@E04Rjs%%Yv4Rxgk-O%{tA2?+PsIm zWb*qGm-=3ujCJS80Xp7Z=d2Q802}h|yR5fnXA>UJnVpgu&a>Y4Dg%IPw0RJgdOPx} zp4$FY;5l?QE<0A)&Gzw-;b;;}<2eB#l}S^lwqBeaU*4{eUc%MiDFSjy>00bAe=aFb z24J`P>(C+kJ=MF6i8#%!i=&b|NB{KV)1-@E1-13A_ByMsxNjA=m-q^zA5rPu%R8=d zwaO^JzpNFqdaQOtv~>Z?s0z-iNvN)m#x5G(+I@PB|2 z(A>n{n9;#=Q)AnHogLXv?h95Gn(*0wkjN82pJ)Euz7pc{vJc68?RzYniDHwX>RY=nrYccF3Cz~Tk4sBTuYzS zR5$@Kaw`Hm{xk9Du5L{s6mxmbneM;tByGtegW{ z2mG7q4v`{r03$`PiSa7q>mo_;9s=&vD`mN9q~0`RRn;meY+u!`T?5aZ)7V4&o>znM z4Sf+%8HecI(%wQmvHc49bWOyV;l+&aa|6|ufQ<|S16iWgIO{I$vT$7n45D*2anNr* z#Iw6zw68Ed1;v->y#xPM7FF2OL?cb~9=gW4#OiHLpg<>`BA^L9qJdDQO7gJp3?3PH zd4;ih1u5&<(>oPZQo zk^YlgqA*?f*4tTul-;1qJn(GgW!J2c1rc z%Z4(kBvfZ2{agoj6$(!TSOYvP!zG=KVZwg6*?(u#Om+q3kVf zq2JoGv03g6IWNj%kxSH}f_+I#kMrB;HTdprpA0JB@p`eH&8gWp$Gtcp8QjNMa{@jF1WU4Z)KyTr~@dEqxgq z_Nd9lMUWff2gxv_bltf6Iyw)AZwdzH)&7BUDndlg`&-!6*@?=6aAb${nIh0lmuPY* zy;$v=zO(vwM_ca0uH?5v8=<678y8f>($HAdPfOk$zuOO@4?4p9_<_gSkaB$4AywczXYLhpsW|oYJ}pRwY(6JvJt#>S z04+=ub$kt}MEp=*{$Ar)^`!D7CAbX+%Y3emfZmpH;c-rEGgc4XHW4P zHqRp^hc%)zrw-!yXyodI<@vY&Hq?nPQYe|hw`7F6D;z#miKO1FU|%E@IK1)ST}_pEj+jxP zHI>6%q7Z?5*bj2U#++iT{H*&265b9{Td-lT-{>Z zd^1vfbM_*leY@edk7MC1%06dRAF$MTS@!-`gzYv?h3GKaRqAhnm0`hVN2y~gY&83HvZ05Agv0N^L~ z<`C7!u!16D`53(Gssw=z!c(52pV;t{!jz5b%?K>HjlrYG^yJH=+8) z_(2He#Ejq;GrA=Za-2mm@DRxFb4OpuO}F48$OxetCBy-kQ!++@*NnfElKyh~T9!CJ z7{IIyHa`#cd6Os9j+hOTbIb=_YbjGGv!=;7C(`k!A;&WovXW1O-`q+9N#WJ$XDf~L z1+1h@8dZGKoNdb*-=zk0%Nxa`$Z4m;j^K(@B?-fmiw<3ANf95ule$NH1qTwKyEM>m zLvTE_#GW^1S{KaXB#8HzB36R@n%BSi)g!OPLrdwr`SBeeQM#Bkhs<<5sd=YK)9!w- znb0oId-==m2BvwAV8Ues2fLO*!1M@r^#=*m&GQaqY8&<;7>-#9Xlj}L`Sy#Z#oW#j z>=ap5GI6e&U>`Snc@v$p>04-HWkvh!Rh$^aW7lpT2rTBT4g=xc3}3b;Ax@CTPoy76 zJWx5WQom4#Y34ySost3Lh__$%1-tK&?#un7 z5TF7ubJfs~q-65N00{L0q1o@(b7;ra-mVTC2{T%ade=?Anb9T z@}M%tx!ZkVG-z+@CVhZ^wxK4m2v#H6O-a5f;Pa>J- zWm7G$eoD_enG90G)AMr}+{eJlcWgnFJ((jCyYsRW!k!Drq2fmzK5{iHO7r@#T7HT$ zW2f+fMr+n_y4J1Z^|XNK+I*3M`-#ps;P-1ixijQLYxZ@8oHgZ6u>B0jR;sM3Hm`Ov zPTFm{+Oth!21K-iSZ+psB3$WWc6g9k9d?gx59YT>A`V5jdiFrlpGnY``v5 ztXDM?Bd`L8$%mMWKaw&SPEKw zJk)1)8mQcQm=vjnpsW{^A~%4rUq#SO-Gw42&mUy!>B1=80qcoa z`9I}J`}axYYwoY47>|?q#u0FkbVLgpd1$mde}^8&beXR8j8z9fzITF=ccPR@)I4gTCLv_D*#b&;D<|-5W zte*qjf?NdxamW~=0)@VlDY%-Gp_+Mqy(WuV424RfJ6isEvba`7u%9N~avPp*g1uj5 zmqyZXQ#oVTCR$l4YLn%o|1~zYSxl7drQ;j0D~j;dAn4l)vTZ-3Z`;R#(^cM!gtzc* z*F(g9(s@Psg&3nJ+oPGdu^s2IV8XePR1*Z;|4X^sA?a63vMZXndsrNd3x%IIFwxpy z49;}A&O!mjC*_5KW!A1U&ElKenSa2{2?^uiIj!MEh3dqF7N3B05wOY9@~{FW#_mOc zh^|J&MHvKgx>y`^r)(LR+${(pIu7#qJXC9ny(&4K)*J*PFtgm}r5|}T2J~zof>;33 zG;R|?xjZXch`vK8+w0VWsZT=<+=DLD`laAhW90Kiq+IZ*SJ4q7TNNYrY-&#_$N;up zVYk675;%g-GYfzQEQ>q(T1#HSi>}jJeYJDps#NxGeb9*p z-w$F56aYnc^Vxkj59Xt*Mt=k|g(qM!fe-W4ohrtcmJ++BZt;GYJsLI(Q;jP^51940 zFx}L(k|CqN&11oMQ30c{yY=e{U&o+dlGBmdiWBl0eva<^@ad#n|Ka{1BR=Vgk-8rZ zh}UzN@4=I(;)W5$=>Rt7KjZ^xjS3Q7!X<;?dX` zXQ<{qu*Kn)%z~qrdQPZ@z#LeHuN%5Ez{|oRl_Z?R16_^$x!ALhRvg9ir8i8V_8n29 z&Gr>jqwG}a^aaHF7(Y9FYuu^cZZUx^*wCIW&&+>noLsbfZC?NbVLO-#CmN*fi z01^KGW%(1ev56Bs^5OsYVGa#(q9`^h_<#I=Vh#=K|JnSPT1boje_jx1Ine(5*|paw z99tFGKn4ID0ssKA#CTe?#CmLOAZN_=Go4dux%YaZcU99>nSGsd41qgq22$*$%k|Va zCK(Ak2Wx2&b;*3UABa*@@=Bec;;Cn9wj3@%5P1Mg@a$N>i=nQ7B2~!B)$QZhDJ8HSvHf~2RC$}1pp;*(s{vOD8gtbOF|2IP4DB%wU#rVLVX;)f>ZYYwSmp2*MzlLfQqwNBI@Q zX{9r)fI1llFNO*hs%!Bjq&0D5EUpZ{;yuvN-^pk=tRT7^*D;$k=P!)(gW#go2J4}S z97bm%!aKlClV6DS3FKVO4No$WVOqkcVOsKZzU?9O|B8^A#wHg6zL2Ild)!#}|BhM} zj}g*8W@^f#b181JwqgK@(Uh=v~$9FkgT3bBtrkb%+0rQYK`PnWaK5(M>D zy&~A$vVV~ln1~V7Lz<-?iBwr@gbpGb@=mU^S;ua1;0lvaSGv34^ZXUF7ujd`exv&< z5g!$vbnjtSu}wX8jXtFjhh#NU+@xh zpujMTw33cC!W^6b>(u{j=Ig%4F@g;P38#Y~d9bjbJ|E)4x^<-F4YSc^5H=PjR-E4& zNe`ROPtW)hpER^UaTia=Ow( zzf-^Lp^$nJC}|kN<(Wk5i+nVX%;(LrDEv)E*9$OA@buws!q|rU85xZ^LrAehvw4za ziA&}DsS{0Dx!Oq{u;C_JS&j7)8G%1P<&D5kA7&tj?4v7geD;Eny2?J)uI1`obT`+= z)hx~CxUbHd)OK%!<~!P`A}`9bbw&84*-A2XAcV6HRK~L+>h$a7HSa76Dp=NzsACm3 zwib+*prA7$2*=^YMwZvXB?-*1%F5d$pLu+iKMfl*qeuDe+?OpD{)>5Wq_#j97)HoQg*dNmkG(jzPYHqr9Oo z@eGXws&AaQe%|s;k}?F3V=x}tWbXpi%5e0rs+B{7x*AH7#0G`#TXiX*S&yj6-Z8+? zCTWx55qjLQVO(1{cLjB$uu3Q!S%mxMakUtr{p7o;l?_7O3+XUkg4t=x&ptIxaIn?7 z{OD4g#BA!98dRo`a?b5_wrEarPUgrR?3l5Ezb_qyz&YsaZ4!2zN`<)}+m|9aO-W%7 zDm=Iw0>5aLd5#M<4%HY%d|<^JzCH}WLlHk;`oFJpf)x4vpoxx*;gD*So+NW+4ThxNma;Z}1gwoE-*gCeIpXij93E=rAqj$6z zV_!2)ugA|p#jeFD6I(}uXfb(iX(Fm;ElLALLdw0-{S;naW4#}#9TN-l!gOAoUl@DA zk@jap>(nUulJ-w8Op8@-B*)9$H&$*pI=)GJ2Ru+;Dw8 zm3W}r;=&cuc!8`FI+9Zzf?mVWo*0&DuCh&39T<^S^G5+F)5>lHJ(_Q>Ll|d$iZg); zy?MKn#(xeP>ZaFtRlk-LqoUfF^qrV3EV6~v`|0j`AEt@6b{p)2JqHoRA*i=TGoAFCR2e{;sZ9 z5VPLcMW*Q94g+Gh%pXKT>0^Vv`=@!q^mPV@!!E&LlT3XQy^MN`ak|kA*w(p;r45?v zT57_gYk%OqX$h=kDT~_siz8ft4PcH+-Iz!l#wzK^^ZH69>&1JH056%J7x!~olMUbt zS>wf9%N7dm!cc_Qe+EBD{Kv~7k}orm`-TXs(tl=F-3^ty0yI{xvJfY4^j zQE9+f*pZD2npi5l0G{rVE_I;x3jYwi7@Ip{V-g2hu$-{dpOIyn(idu=%tK3}PFb8R zx1>XprtN`8q}CupxgYl*W;egBnwFb)?#VIuU!e$`=L; znR|(2&o!1Mz;x?6ZwGK+!P`vQBHN3INcF^}quLa2O{Q!s>4|WA!G32)st8ev?-or8ErzFjbo{k+icX2$mfvkj z>H}DZ2x3s&j5j{MZ$)1!#y! zip{c_Nxad3>8^NXW?D(wzX85oXBp>WdR1u6L7`McS+;*~&Cp=4xx1mieq%$Kz7E5a z74j5Z1tTZnsF-CmzHiEQIYLd|fO!nikH(+l7!2ih{y-Q2=JuHpj{#U~)-yZzX`dT~ z*eM8RmxK@@N%@#|SU6`sTZ^d>a&r~hZ5`K;j?YZuA*T#%M#uj~XG$hbiujp_LJM~b z;vx6#1xDJdl%Q)$gl9etOHf{!QFGKyBA^eR>y-$HO3?2j2o-MU3tzUVJ}%FA+f&^Q zH$T7FQL1bK)!kw+@N}=M^ndo<%SMm;Y==5tsxH0@FfnWwD|PFk=@$|Np+-jdO;Dhy z`wQ|Mj5%-Wo1B)KR87j^yvrRTWKp4eQhA zwxH*^Y?g*eHsW^^IWCDg`H=rXa2EUv4O^f#Lg8bA-#SYSjSK7chh1Jn=vj8W3**R$ zi1I5fFiPlEY(6grtB7GBk}6eVrjwM^C8wmX?{$2TqjrQ%?RQdtd&sd_VQ#48ANzpP z;jBxB^mBhJ`?0bkCeDvKk;UQS9J2clge>Qt8=k+%ku_ei8Ge%zC0epu-DWd`6|_pb zXywQ}IT_aX7Z#oPl{b=|Lf*sa;ni~&3kPB+z_oWQ{I%-rPKzX7PwT(vuO4b1Cw)YL&lCPEJA;tZE`i8p^h9s`Q$C1ziN6^V(%qKT(}RpIbk%Sq&*7 zqbn0MQd}KNut(t^*q&)wgkoQ**unj#C)JRb2p;S6NdwEvhQ7Rj(eMC89hx%*hyXA13lYl=||?44{ZlYMsCna)dkF%VG+ zO1fRZSxwts)PhxAbJQ8V9?kyPI_vVx171SWUxQoxy~h#bOn2@!`m;=~#*}guP?B;U z)xO?ZQ@V9Uf1Xd1wwLhe6uMljqtYKaLV0CE36ji8q(K5sJI`SN4#7P_<)sQgxRF-$ zjz?x9_?J_4JF4BP%j+jQ(R%miN*Ml88@r3I%4!T%ou2lb&vs@c{>e_qQ5TYp0q}Wd zmy7PW&vLeR6`K&@;v{e{TfSP~DQq5(s3ht@X&r#a6)IvPNv*c%P!qDaDAg66!3>v+ zM`wb*A1p#-PtE4mzKxs7nB3J*1@53Uezu2?$hPkXcDu z&uY4z;AYnClWJ6vdMkx%@>79X7kFGf@O#j<-N4b2EGe~j+pcOg++)Vsy}|R!X{;;o zYHXh7Lxm&R8`ms)OwFR%1S*K#eMeOnE_~eqMBH}r*dxF`bdUe9hxyeVe6ZyZG+vg@ z27unz#y@MPBQ#d#iW-Y<26liSUH%vvTR7xLP6Zx$N{t~|@GtrBi=w!}O<+O0LnSJ7 z@0GPN@%ok&)NBd^WI+>&Xx0X42K~uCOh8@V1`Lar#n)_CFma5bn6G+3Vy0YPjbOA$ z9(4C_(uZTGyJ{tDXfp)a+QP^SJHJ7DZ?diB7h1^<4e!-1qkKdS!8=b3V-ckVQ*N}d#lxFbyz>{bBvg* zR&4AVdUda}M^GNiE_sfG4zRMq2f(R}PjiNI?+==Y^zU?=N$qD|Yvwd*6MU;_iL#}k z!;zQxtzAF?Ak*hEE=@kZJzE`g-lm_46qilpkT_&I9ulvy(eFLvP{74twA3?&xI?}9 zJ$~m#G3Y~|pjDD@a>V8NK0bq6)qo+K-$M-xcGYGs6aB#O?eh;me%xZOqLid9*FOw$ zsKnAGzCsu`*^7)wGM)W>FB1b1)hs6YBS$OCU0Rj;y6KTuh-5}mlp zBh$s0?tb!;Om7fCq!!8SDCc8kR38`mhaQJOa?>1+N|4Jl+PGu~W=&kMSH(K1;f9eo z9ozY!D}&9*iWg!Tyia3p_pyEB0G|~Nz++9*yJ~BiPzDSWQ+J1tGFn^*7D17?0GchgsV zWA_e^1)40xJG*^o({w|1jz4OiYeI@Q8b?PceG;v4?gG`fN$*8hANgHw%f_O&D50`uY8RrM|yN*zbDi4pcfWt5TYO)E4I&q&t{5V!|O z$$imFG;)}q&*vak-9Q1H7r`%LS&Mt$&ZD$2s#G;1PkT13J^?M1oz>_yB&5EN!|ng8 zR6zY-7v(>Gh4r5v@jpaL2Q54BzfDp|00t@y0Iyy`2K*{ty>`FA$YgiSh zo)_boRH`uPrYdS9BNV4WWAX8y0r2&%FmMA)yn2bS$tfV z%0g@df;UjGTyH}FuzrQUxMfdya(Sg{mnLse#VY)K4l~Xk%0}yr2wdUwaThDHx`0bH zJ-m}F7Fj7W5gfPQ>$q=uI@(m3g0BX@5PYEUuZYpcp>E#0VySloSH5emvyLADVngs! zK(T{>l@j&~>hLT%;Uamcrw*IFLOH=Ch7#&KwfLOF(eL{jpq#lR)!ceZq?v1Hk%>BG zn_9#7jBp5b3UMmkKkr%4IfrUl;=K}S`$EU;F*VDz1m)=iI+}|j16ssP?D5K&x`Z8g z$yh>5etT;KrAxdFl|DHmL*+|Y_8)#xjJyuSAzyYb^yk%I6a(54R8XQM&7`yh99)Gp zWbME3w zDsg=TNK&fgn#-${-wO{!+hP9OqBU-qc4p z4?DRH99kU|DF@Epj^L3DHlyj(LobnTi<+`rsL?nSgro?oN}sxHQ?zNhj7ZCVuqv~f zW^kBTh-YI+igzQOahLMz-v&(4u%hPkmmSmqo`_s*@ep$ddeRb(x-KW|#Wh)I9ZCs1 zpyM59v4{l2Vl6`mm#}M81@h8B=k(F-**XjOzykSZMQ{edsZDqZn{?3m^mCg7gR4V7 z+$~w|#60Pr$Zu=Dc@``8_Y2>#HZ7<+EM?4jEnC>t=23_RT4D7(RJEx^IC`ZI@ALPY z^uxoKkxF@acYP!NBT$&jLN1!cMq$1Y_$K3(U3KV2*D2kxY*8P8d4!}4`<+X|T3wa< zh6~wTYs6&5@Sh(SW$_HbBM#v_<8_P5uOJ>c~17kXS25 z$)UC_4wgHPr?0g``xN4c`Vfq`Y|+9%?iuU#H;&pVM}zr;LgN!W7%-IU;IQOjEB-h$ zym)hG3O^>N`uK5;#rD_PwJQ~oaCZBlWMul5saFbrQ~EsJ$?31&ilBqE63{47_>Mfi}-rdBcfP zHv=#hsP;uk&Ueh{1i;PSmvU@EH`6&nzCB7mW-^M2UR^}aR^`-P?lXt$faggGo0M)y{e5G$P*le*f5%PEseqo2RUq!{&z-zme5kNW0RHlCP z`jjM!Gb$H}=v0lTfyYnw9FBJW-XpZ5;(J@YsI?9c+YGeFG`kV1fgz+>`Rai!$7_h; z{3AEun57oZ4_-$?9%j0`t6yGT0*+VwkB8Zk!CTe~a>a|BW#t>@)~~j;MByFG51>r2 z9iq9*i5aWE6)Fyifk~0;)GtR}lB#7tm=uZ%;6@zb>32?&<$t&wCgx&e?RAhX#GtgN zg{$r8Kt>D8chM$Pr}^I?t=^`15tWf=qRJ$Qa z;9WdAGsmj^fpey!@5_QoZDp`yTJzp}Dsw*X&`OWg18UF}0H>a37Pd0o7j4Q9hz5*= z;0wO%vD=Qn9Q;=C-?PSr@85nYLa65zouz?;y()W;^de)V~!ML-WNM zdBQf)FL9M-1P&$<2rt@IV0`}hvCb<2=Q_O|toGCV@|X5_8AcAw8t#On?Pt&lKHLh` zz3f=LhbYwToILtJGb4`Dv$F7CtdB{e$8OG}*2uD)ZjbOYDdE`HzN(<>iX|Jw>u z|3pg%@;|5wqaiQ9{2$a(lm!6b{-G*kdpj3XJD2}p)uoQMa{)WL-*vUYMw&0}5H?S3 zr=(j`M$o2N5PUZ>mz36FOIHgyBTK zfEE`XA2yEx1{#S00fI_*TBQ+YQPuvYWuE*ZJFH8B@5!|$fm20K7qjnp5ry+yISthC zno2s+(`s#)CLwp7n;#vh^??J0nP3pRZEhX<6oYKUeR67TNLUq8*@2vIdR)Go1ZK4h zf-tjSpekTpHtg(ch13jt5aS+{sBve(31j}yQbVO&qZNX)+;zeqYg&(&`okgAZdYDu zI^G5nmjM}rwN#ldqi1LD^!lS?&1*cc_8^u;tz{mzRAg#uLMq3d&iedR4|(30b}dK& z;w)VyYY3`y2w!?2vXU~@&k~WB52$VP1M0SyViiq#JSnaPD!#?PCFC~C0^2bGT5wqi z{4@k^oN!&#%aSkI4o7!`2@w!0ieB8BargU5c%U{Llw48!Qj_|g@&L@Tb2;2WQ~T6L^d%PO@K@ zdH9@GF4STtk25b0AC%2~qoPt@L-IJdWZ&7W-A&TCfv{8Q&V{lChti2wX$-F710@mI zG^W*5A-#fDN3q{wl4p}3){A?))SG*@sZO(RC}PmgXJ$rRhF8(3?3`v+s_P)8?r9&V zhHQudmVJgIgVZt-JVLQ|1|)@0gU36qA9Cbs>$OUT5gj7PEek8%84(4OA!HQ4{xvf2 z9-+g{$@(N??Kv;5!XT67N;)KTAsMXER>o@!GAucz75mE=k3QPE0RsI+ssu+{v<9IC zibU}S-=&*n6qPngzWc*!!`Dhg9fOyp4fA6WrW;$ToQAgE5m~Z$4TyP>9-c+2lepaZ zvvqShTlDj!Id>H!-(TdeA z#oSpY5hCdZAC!X+gVVc1hx>T5hpWWc&W%0I4UB__pyhPnw59SMjn$m#!ft0u4$7`p z!>!-VuTM8?iYIhq4;Z|Y`C0+Tx#cq9h^Zb|8qZqcB86m!{KTQ;-8}Dn!F(V=oEU-% z<)3Qmii8}{Mr_XsmJ|Hp)9S(MFj^qjf)_Jf!s6#gyMekOF2#@iHwE314V<42|qDMHCs=nBM@vO}R5}sB%IKyd^WM5&P1Q-iFYA)3C=&du_FW941 znh?tZWhhj775gZRWg|O$!cwDX<`%N7(xDILDtmZaxS$!`X~JG>c4O#n2&<|mR4XW< zr&|b8z0D9V;nc|jk-$B5ud}lHz#KveVl5)#_rr{pJB#Zs8N#kCl0aN&d;YA@NG2DK z6TMwWo+@!!2FQGPA_vyse8}p}eJ$P0M`%&zp%7YTSHkmrYJy#ML_iwgn||ov*zt$h zWU*?x;gN74iidM}JJPoVfxsO!(td0|;Mc=8?XA#Y&wO%^FQ7q?i}I?8G&=v z2}Qf4eE-fOAMmPI#i5sW&EAXKZvry@8{Y$yO>Za-3F{pE+7r_$lR#cKz>>=oz6R52 zEpNj5Vz$BSxKj}jqxKo1(}(#JR{u-o^S6ciH|YOvb-X#3T%{lYfZRVD<3Dx*U~B4P z_+NL6RtCz(&NHKT+|!ZPs}I*^9ra7qqY8!flg3e_Hq$n4Lk3x^$JEn&Xa6AD)IAB% z-ZB|tv)@yBJ}wB)?r~pRWyp67B(0gFv0Z0)YkK#GbJ6cE-PkWkAx=vCM6u}+hnD>z zWlN=1owS-yM3M9d;C{#z4Jm#eST<87)=b4a6KrUB5FU_Fy+#M(Sp{3&^bG% z*8`}eb`WaBUjzZy1v9mb^tQ8mZz6oh8Og!Y?mg2aaNUiy$}e4j75q8cow?XMsn(fOx1@jaPVhdm zO7-Mg`||rviv}nSrki!&eFDdySl!$Jw-3b8oncMCnZbuQIQ7CCI+}%-Vm2GRvjN%M zRqBDI3R}SNe2gEdB+CB+``;x!+xs@*{D)a$r~v@@|Ck_C7Z*!A^Z((3F156s*ErGr zw)Nw8U8x4+*zr<>V_LB#5&=ytI~=Q+xunv1l0$L&-E{%L9~7LD2v-+Vp;$igUCu5p zS9g!g$+6QZagHLRvUv}ZG?{{XN=WgmvW6B`$Lb-~jROD56rrQ>_!sXjF3cG*Bu@Ax zEmO{8vB)IiAUH0b76Sj47KHymbyv+2Flwju_NdbcaH&oFka2HB^n;EgH1R*L+w40vbok^fV!g~%~w#a ziewV>gLy%e8zebM$p3Kt@dE8>xjX7K_<6sh-weg1=mbv-EXEa(su2Bki; zUIJ0jkC!|VFV(+vy^AfTYac7in7R-s#IO`T$K;3`baiV9N)z9V{plIO@>?NkD=#=Y z&T;H5iHyY7z(-+i)$PvwU=$`^RXvyD2WV6<;t2fJxSyP6Meu5mJA8?zoLI(2@0lgH zFZmVFl5YgDQ7$C+3nsu;%2zobf2)q{7lVJl??P6|I5ik^P_1ougkKuUM(X_E$(gQo z2kJrOI3d{@WV0WLds2o%)4_DJiFvjWmM&1{J-Q{c>7WyAsQ)C2xkW>d-_Q%xC@7|p z_!2*G?6u^9cJRnjJ0dq;2ETUNj2K=|dnj|P33q9^`Cs?e4jK&blOkVHu>FmW& z1Giy25m$N(eXPqgJK=Z26BG34p_bY^up(9h@T|Aku3Zy+kxQ}$e^4C z%{_8Y?5WhckN4Nze?sV{F1ne)ApXyy@^6+;^aVRMV<0ZGB?uGh4uaL~<*O^FFnNq( z8j99{x9eAJ_7}q&R|-oVYTQVkybG=?@r}_XckASVj@^q=qUkMvh>V%Qq~CM!%L$ z6ykolO5XDiO%>jYmnGb&EA##-+Z|+rcD6_TS3KHmv%NOMPCl2yvgfli;4pVvnHkdI zcOTB*vR(DKt)-;!yeiy6#^tYnH-R@J^qPdceeh(K9s|zzXRNi)L-pgY89Xa#3{+s= z)qGD;efe+M~FSlqD`ZS0(y#<_|}(8_z`9`sWyo#igv|bGQ6aomN_Zb{NYo79->)*oe@-Y&VWnJGD`4L-KlPQLr>7iP}CFS^5{KYQrb z=8$1VwZ3W*)-i4!|DoRZw~k6kP@#s$7)3glJ)f>hK!@OQc_kOPyrJPw->=nz%|G?Z z)OJlx%+R?;x~glmzQj4$A+_H%>N}r+GdqpC_M|JEzPjAOS$JzHhpxsrZQ!-Pl&{o8 z4^B#3U_4}+f1QmhUeuU5Cl3$#Cc86e9YCHXDI zT=Dn+|GW90fvEn$NIMOA^=cZDbRnZef{cuejg3u2L_|qR$-uzC!NI}D$Csog3xTq1 zY|X!V_2$)E1z8>Mr4!=_i>+o{owE+I)R&iE=wEc)Vme%IZwEGwg%Xteet`3oaf3kH z2LEm>veMT3_c>X>EMS`l>3(I{mVnw8>%ZfZ%?s&&o&Kq=7S}A_4%Vu^oi?aF9=T1X zYFzIO^k2*`+&)hhsQrHQ_OOmHHXejpKZ?S9|J35#w=~aL-rT&aRTKI<1Z3*mE|O3C zS$DDEZv5L)_|NXV@Qeejj@RzFo{xeJ{m&&;{W1mbP&CmH#g8`E#7(TDpTZ-#y(Jvy zhLrWKOc&ouKd6vyxQ0-5aqHay`%LXAi<~6Tc(}iHVQ3l?fa4Z7{(f%7AXx8)O1?b) zo==ggf9Owk0RyMVFkvd{U^J*8xakL^i16K)p&RNn_$)@0ZZWAd5r1~F`BqLyGNt(b(o6R|JZ zWWR=~tfI5k@zw(VxrFZa&%0B ze8il={0TX{t|r-&&I|2T?X)iRF^YHn^hOJb%!cnFazT^{eJx4Im(?Pa8$&s!$(-1r z{&Xpsc5z4I=6t;HOz$;f1CdDYsY*;0&(K%&0V1)aCE}*3QZDy0 z>gI7}7|SUDmK`NXS>6gwU^Vu3A)HRT!`FXA?+UOUb?Pg*K$bLu(!rW{9&^q%RyH=d zh`ID$Ny)zrOb(xR^{4&A_=B3?0R@QTeRLZR(2h;8MX7#tfvE^Pq=7;PDD-^)n)UHx zO39Ff9tO$fu2$A?QU8fOmi*H*?gWtNhde-7vpcWO{lwNeIAK)27%t8HKi?Q(6tC~X z&dNX|7u=)Ii$);m$N^K~mhhQBjbKhv{cJp^$Jy}6m5}s^@g;9BhHrBr4s4-A(^6n# z$bl=Cz+Yv)ynoG`>izY$b|B;ONElt2Rrq75dJLIvfUkROqOVX}{(Py;9R3oo%NuE| zo|H{wkP4Ltj*+0I0}@N?%6e@m96JMz0zQ&YnUS%cD%A@Ou|!K1lYKdLSph0?fa&u1 z7+rr168QG$o6iLC+}%r*<;}-iy|Q^q-X%Y$+xnWLv>@HR#UTSzZEiw)Xi_<|8HryP z>-$|$Ut1hB!OU*CAQd2Qtcj;LeP~UEDcVRAZk=O>1^*e&LSZKGZNcnvrU{S!m^jAg zGl0sNF>w)E_=+rSkAUCae;IV5w6)Dlbhf#d(^m~U!kvIG-q4qSJ#Tcm*QBKLSk6by z!OQL-0KY2utZiuiD!|WCVfnN>f_^QV1e}V0=|oC#=xiTM8Ndj$`rJC1{Rujx;iPB( z;eM3&wFgRV2i22UcjT!QZIMWly-yWMdBj|(W@8m}OT^5w&UGy+6gC##22l6=jASeK z4tOU=G(QsP%%yC5{gm2cMVZTbu0zrA8<%U@AfQ*s8T|+KzhEJLfjvi_8OFDx zmpt+cNv#HIp)+k)oh!Su_Xp*TT!9Pul8>VPrUF4%Qi5aOxaY~Qv+!vp1sF|>jE>`- zhG_Mn)ow8_djqvzv8K#dj>35t9e*z8ewO@uQB)p2SHq^|+;~AoBv|43jtN%__f#h{ z#-dMI+&MC1WPL-sr~5%H$R^7YRK^V-9J5VdJS^PbqoJVP==#c(^3X^_`CnFtErj&- z${yRQ$D5XZwEjEl-}g=Y?97HnIp5Smb9og5W$Q5v(nfmzi7d&{?2SqU0~hJtluJsW z!Q$Mon75Tu_dvac%!cbKR1*hQBucU*r5~hRpGR^LtEmvq#8H>U2#R7&xn9M!RvGFm>>&kHp=%u@0Ujf-UdN-4cMv%dd~@-{-b8BOZQgbdVJDw2EqE z{+(T97gObBaa~f~$5g2t?NXvzU?KoE37_THO-|)B8en*jYhue*>09c&z2q+-VwU`= z7d-pa2)I;c#_R}D{53iHJ&dATnfl@x+P{w}ZSjK^ow;(z9_EZmfQAI8?(bBLf1K6^ zqUwnM2`u0!@rfFniswGG+~wEsU1?}sGY?e?J&u~%+MBY1DevJ7(l8k1p$uUVdgrBM zG3c3ZZydT%589&&PE6rGOyvijm+L>qvNYsd^e9&VGmfv})k7Zn*V^8PXS{?^z94DK z5T6#}pw@pU?vVXLH83S z8`HZ{vA*T;M2+SRw~V<+gEvrPzEZ3r_B-?O%-F=HB9;p+%)c_)1ODXffJ) zhHp2F=IZRssvh?5w@m9Z;7R(VLV*lGGCw-;>K*CWDFbzwI_zI_}L`@?Gc1=)vPD=&D-8;kMG3vRX4T*nO@CSyXL|)j9h&DH`@B)o$(G zHsg~(!uye^Z+by&GiDlU%^}2ee837A2^om>hpY?UWIs>HtYMb8XKsrpdf@A>2J?zY zm-*9uzU6@7?{(V2)X=t>+dYk2_=t5~qxG^!T!X?VPzJ?SUSu?uD5~Y@MoCR6TdL&E z`tb6u#CN8=-C)00UbX3wdiH`kjQ3l?8+JCp)%47*GKXC*PXT+#*T3H1Ka=*fht2i?o zhIJm4Ee!JMq8v}O@es3zoHI{BBVyRt7i|nJ8SDmC9ki= z!b3t44e{(c0W>5iAlqv|G7nF+ypbC0*EblQ0K25`F>6V=l96Wrp}B%LSke$?Rone8 z?63YOUKuq7G>Lpx0T#w3xrWwvOC^}!DG(+oAiKOdTJrAI-1NW_4cyMjyRXCx#5lV$ zjBj0+d<+!;CvC*>HCT$%OIyTI_Rq}_KnQl!iDeaIph_mZnXAf(>r2o#ISUrymCRpM z9jRK-VaJ1FHKg1PLx)NicKYv2HqB|hYxv!)l#k<2kG5wpVFnqgc`tGF?;}gh&KL54 z_+k|KY-2hLDw2~117>ClKXd#hiRLmGjIIVhj}rR_9}n22-{Z#;IM#prQU817YnHui z(=YyCP^5SuY@9-2TdD(XfKRF2>ZOmDut|M(gQ(iS-;B75QtE{jbNN8=shG9{R-yk- z`d3%Tl)*nVa3+)OG|vMvC{~YvR0&+b#NgZf%#jRfNg&y5MBj*-A_4oJ zPqG%6E_ED7%AFe5yzE__|96EUxm3ZS4g-u zR}*Tn&){Q5TNXB8)|D3Ey_FvHfdc+%3oBIcv7Zz6OFR2n`3vpICetg1S_h5uXuAuB zkM7GZgcNYEW3A3Z&5-EQp7ALZDP=B!TN zn;-X0SiYuCBa@m%J+MMDCA~nrW7_>cB$^;gI2Y=03pC#QN4n+=Xtd28W?dv@0Y}tk zi{dmjaGGff@4xc^cz8n-H1Hz?nB{g?^@RHS+BI_{2=syoU2$9|Wr-amHRKOmTWUBe zof(N!LpAi;QD_bX;U5tD`donza{YV|Z3qm25B*bnN$p@CxP9K#9H`Xnt^npKGuCh|c5Ip9_5I_m>*`~0XTS@nLKjgoO zjz(rZ_b&#b-E%~AwMwql;HGRy-N z7P21lcdI26{m|h;nJDra{LG?j&{XZmb~(&F=rj*JeOYzDL}%KM$H9K#FL=cZKFDvLmt5Wkhtc z_P$=r1^8@5mO^bzV9Pk=j^r@qO$Lw-q)7-ReXB$k5zI=TApXloLs4x#3G+1IY*^TK zm41y-in@R%wOs?aV>4c2;1*fYoFP2Y@lE(p8>AIPxKR8l3Xgm#f#_tsNi4h|a*^7PbGSL3J-VS*o z2HU(Dc=<*fMbsi}sgNAn-5h zvsIfNl%~bKFIs9XPOaA0sT0C~@IcT^X9u9k3S)MM|N43D544eaoHRdP1$3geBd2A< z8$3&Q{`f>0*aA1B+;W`Peu~N-n4v--VtER1c)4CN8wP5BAT_RI_g<)EE>Sx%dUWVy zH#eQ9rW-tauh2AZQjO;AdBFf2YsR$l+%xVEjU^xw+OeRwiVSTg)5|v;`vE=R&q&Hr zNC@pY_TkQ&v=JElx^-A7+zjrvKW2SCrUoj8Sw)@ACkDP}y+1^!Zr47JkX&9;FLlZb zD1AHV+0wGqt<*TVG-O(E9+0IugXAxDerKC1%jC0*zAmEp&5vL!i2R~1Ux+P)y9ise zwu#0R^BWnI1&MXin4ML!AISfyFc| zI8kPHPLAI!4gL4*G=y6y^DpHa!tpl&P`g-Nw2c|V%7z$BB5l#1IvEW0aLBH(@2rgF zYmW|y2Cw2##b*WeesVOP1QIHr1l3C2yz;Qs1%oianCrEqL<|~xJv9_%StJuz)Ukfn zV#igWw=-O0+k4FH8(!M4R+ga;u-heER}N2N#cP`E)-tJg3Je zEhfEbo81jf=oaozm%iePRthQqq1VeKk7Q2=l$&4+h=EzOI?UJ2SPWoL;gboW5q$sOa*B@UH1r-r3@)8tK+wNF_$vcIJ;^McNeWwSJVDQqsfTcM;Rj%4*K9i~ zNFEBfwKjgxSiOcawC~h%yO0~bH%hB`s}RUJMtmCJ-H|7tYXVmgeFc}X{Qf-b5SjZ) z5d4i6$Cm2~GMT}9*cCJN1rq-hiP`*kKAIni=@VIgev24GgPgRSkYyYugVCq3T~UDH zo^3w)S2HeB*n(d#qlg5DZ}ZO#q&|vfski+u4f_HNDris-B9kB6b3Yn*8A_&gRz76V zJ<|9IhhGUb9}eSPp|z>*@;1L(XU^b|Cp&{2A|Wy4KKf2|lM!M>Q1Ex(d-I8Hj!d?^ zVgQ)HMxA0i5ZgG!wuFi3hx8k%-a2n6p=So48E&B8vG5WvV!@F=;qK?pl4qmX{b=W{ zU9|FcCQpRkeZ}Fr88b(7ntU=zFraQKp#Nb*F7^?St!g#@*>497v0YryepkT(qgSb{ z;H&S&-ayJF^Na>b6jJxxjg*)USMs4|$%%7qVB>&$^N7e*MN~Fqi=J5lYAmeI?}p6K zK3b@kRbPGl$mp^j>13|3GCmfG`JiKjiX$veh?EN@ZhCd1^T?9Tp~B?c3$`TaN{pQe@)}o}^v1~&N9~iM+`#F^vP5hUja~p%JD7bYTRurCy zjESxJGrJ}OLh-G88cu&D2$1A>U9a$E;fxiECHI#tPH=Qxv1WFS@O3`sOkIbdk@_BD zmH3xDJRvR2si7L!)%C|wXphGtBJ^3or{Bp!VXJ>SeJ87!H-a*vDod)(7yKjl9x!8Y9&9 z7ppAa9n(9HF9{C4lfs`+{ib@E8{-Y;%(tnx)FbiP^Xac0NLJY2V}uf-8yundn`gbN zzH%|pB$qo9$1!!9N+x3gdkq1os^eyLti=VD)O;$3kx5cKCOPgvN`}TVijJ$$>15Nx zw$dN3o}|96ZjZM#Qius6Lc*7cr9Rqg0ZXyNpOr0nt)_peRkshOzbg@JGai_3M}Y;$ zJT9VZM6U;JeLf+BA;&H(&If>QtIUp9e)f}(OgfB=#oNKlP(p@IHAAhNj*eX6>4f|J zdGwkj$vSJc;<*y^!k28uhm=rq3KWTXKJw4u?xtyWY7f8TX(r6KcmZxOwx|xBWVTbV z@iapI3+eO6KdTaxp9&2`OC_njf7)PO)Rir~E|A*d#b29Gi*m34GOoL{|JcKfWzOe{ z`vcNb@ynae*4m@(MvPRm3WZzIyjnRuu9^P4= z9hDc}p|3eUp2$3FYyV?{DcGf`UMAW`bx!OglO_p{v~=^!OB2L?X+RY$Z0ukVq>HFn zkCl;fhay2MP7m@G*za(^#&p83maeS>h66pF3^8)5BH3nIEwa2q- z+)=(W)lI2Jcc)vc>7+w8L|yqTmUGC{$>E<*WYq9O%oE4!cG-#lT?NIDylkVoze!`p zU0w2+5jgwHJ!F$U(vkN7M26nH*`!~-;bB|r$_d1hXI+fc*)h2>XicXwT83z+Tsd8f(XbxiOLwl5}Na9f)%E! zkqDFvYv+@d>{qPSK$Nz{{U5t$&!Zs(gDLa{y0{@>P^%X>=nw!*A|FUMa4$84pQ2c* zlRzNki^&<-j#K1z-i>f(xq58?nwDR_*EY?hw?Xxs;TZnNV4_lAOn-ru5E_PpA8tsa z?MwX-fc`>BG*niAU8Uf%PwE>g0g1t>a3C-1QbDxO;Z*;Dj2dHfkC|ib9=pKZD~|(P z4GTC_G8`7TD&L!cAK4 zeMQaI?vX<1Y<_8s7Hcm=j*eE%W6~~4|HY6$%`u=|;RkNYuA~)qwtPtas~f(J-i+ze z((%Lz#bg*G^d~=Y-b3OurMh^~P|F6ca6yTMxj{Mw=W%!pJ_MNpU~^!K!#uol16R%` zgAe(|4o>;OMfk^s$xYN0DmWe;<7gxYlG<{|`zwADb4KOvI?>Bw8wAMCP2P_vU>pqW zb;GW&F;hTUr%J-GKh5LtXznW!0epP@Zx+lmYW^I$ybuvPaNl^`_l>u#qWRph5=t(X zN#Kg=J`NcT_9)f+ER?j1OVu@VfFd}n+5Gr2!ia)>BeQ!x&@Ux0hZ-~WVtBh@3?v5# zV!MwQc`^}bewZIhsXIVskT%|8S}59x(UCXxVI(-}0a2uTW`(Av$rR9y;&Ki;S<|lG zOBi0+oirnlb{1xY$(u%qhWzl3f+|*1wwyPr7brIB+(_q7ixpcr|_b?oY-z7y&3ZM^NLR2C4C{?Mc^o%#$h2x7`2V^cE z>(#szn@Ek(JZ(C+g&2NiRTF+n1+d6>=u)?LR9GQG0`ftDzx`Cx2_ESn# z$)0edeazg2eiu0#EGDHP$s8z z?d1m!k+dHC35)Ab$4~^shmQ8Tkw4{b^481Ri-{#`4^w_aPEAoCji(|InQ_24kVVsi zOy;6e6Fp_;6Q$GkDp56tI_wAJy{_t}n+R%@?Zx|2DEeRIC~^W*Q!Prrj1UcHBA~Oep1Igig^^ z5@Em+$~P6SNn&Rt5+zuk6y3Tm=A>hOatV$yHYs6pnz6Ciu5R7VKCql~rB)!Q+7s;4 zY^CAeI<|Ooi%4AKm)xktr>rL4fOsuS+N14{t0mCQufi%N>#(qadn1^TnveJCYj9;S ztJrBJkgZp42E3kkJd@+JU(M?pH$}v$CjmCU=k8i(#DFXLz%{iy7uco97)V%yTDO5} zxMVDYl~N9(rj?%mER!&uqEBgWrOuE3b(SMi7f z3Y6%-%Ymppy!QkEf=f`nLh%GosA7ynPSUXVgfMLRefz*TQe1n;_|t2Xo|9vJrNEix z2}(tue9!9p^;%(6l{dmY+G|R)BL4w>H3l{#;b1!LeYk>DQ}8CsPoc8+!-a zaUpp5`Ku!H(H7`+NQueyNUb^m$HaLG-VNW*epHbJyUyIcu}b7}0%3=DYW;z)2QQh` znK6r10KO?!8;#Z}nJYIta2bMSe;-VM2(4o%8~UvV(+G$RWyyU)<&6|8qA*3GJ&aKA zDph&EiNKaGVy3zI>Qn2bLLek6S{6bPlcS8BrlAVVKwIY%cwAmozQCvTZOw;$JU zbhlsE2^|~F>8X$F-N=_%R#9e#S>=!!WKf;F5ug-p3$*p<6-1m7w%Y?0bXP`r+Eb3F77<(I?oaD^6 zj9Q{cv*xTHmhjbu`6=C-;2FyjoZG_n{+9HcR-0-ZKC39r6JO|}C!DbJ3(`!P!v=;~ zIwaqJHaWNEw;SK5pi0(c?)J17>g=5<3qlX?YA6Hq=zHuZh|xfi-YHS3?4qjS@1eZW z9l$4Z;RlmyqsN{PgKjvF%J1shqTX*9@A%@hdwiNzJPBhA-nhQw4W82!PV=$A+83{Z zmc>#v#+-a-$1c<}c~DtyZM03|5@xOpb4(z;Rc7;bs0^#DV%sGMd0N&22t*4AuTA&f zmO+uUx7K3PCk+=0@7`3&JtR;zdi-XmFlS!m@BnYKqbFZ7RPh>WIR-T4O*ZbOPOd3K z9#V%GCnWg8{|Txke((7uWFlUn&)eHNr(6z@0a~E16kewAMQxMQXN*jijWV|Q;6H2A9AvoHo=?XrP%#Vo zg{P^N=4hD*2uiLc?+BhPj3|BhFYF-tbMS|&4JaEV*M`&~x<$Tb(fnotA>Uu17& z*q=PV(Q{iHU5-)0oP)|x4FaQhwZX-hxAi1Py_$#~9Wq{QJ1&A^xn17wTJlxL%AbA; zf7BQwa`8L4mR-2KsYNW%CVEGUpzcnQQz9(~5L91D;T9yD@_I$AfNv?iJyym^NFX#O=y8G0lVhZ;YCG3X&G5xt=s7GX^OmPYjL zN2ro^&Y$`CnLT>uK{9@!zx~k_3tm|&Xg+UU#@tuncqNC|^iiu6<!0l}-j@S54_im>k5fFC3?^wGJuYiWzIZD?%)wZ zjaPx_vv)9x^rNLWU^lOH^T#FCoNkQiBxv>_!G)>}&Q?I1e^ zy)C&F37{4D_N%9&o1sSoMq{P`OEq{mgkw%@>K&-hzUlI#gZGC`97)P(M?Ye>(x%Wo zb>ht0toMq$elx;+f1ok+F%3%jtJ61QW?R1hUd^HDk-J*@H+m}bQW{RNgoXzEjyFTg zhJh6GXTV)Go0!ikIIBzzIr_l*Q5fdDo7=r0xppuDXxw-VMT7RB?=eX-zvSO@i`sXd+V)Qd-rCmU@}o8EZEN zfC<;N0uTE@FCWGikY#$5lAC#H3L_tm&njS{*a+f0NpwA!q*1R1e4n zK)EGR84rt6mX7zlNdk7gC3nBOpC1KL6#m$m|<6|1{vI zl70MUoVC%WIkP=1Cv}P4l7^7v%p3;%0V>;%SF85dPs0Z+(oOmO`fh_|!L~hK>n@R-5dt6?ifmD~iBEAP z7QIzR*bjYBFVIR&Z9!b6V6{0q+vH({NkX)pN=03^YUofcBWsmH?z+Xb`HJE5m`qH%Qt!0M;n#ACA`%OkrnBOID$WUW|_g@%VQGW=g|HA_{I8z#lSpf zxdgh9o-*$Z_UKr@FLY*;3ucamlDzoeugr1V_^G(XPuG#cb=G=)-q>%9Mbka(yJScI zUO@eHZrqM8A#@*Swa^?!eN)2+yv*!3V_=@mb{hP0{^2<6kI5q46X}ZsjD{1FSc7ph zu-^;-UKQK;eK!9n41`{-{rcK&qt@uh+`3N?0+Ly|diVP6$k_s-bT{!h+XDDkZFy~* zajkKCTEfZudn+W zmp_GpAs^P=h2Swi&?TdFY_Pc?_cJS@`A?+e1(RTINzP^Z~% zgoqaTx@;hd8ROffVM)7sBf*De^n;tNTDR*fhIiafKc~@Qik~PUSz~mXGFgEBcZ$Ig z#4?8x|EJw`rF$nMK97}?5Z2c`5ERx!od9taIlH*mw?vA9GdHr@s}x={ zeFc3<%mzjD-{vr|cK<6mbOe6CvkR-X%DI8O*MUT+2E}#S@BK&^@ySYX}fD zhde5f9z;e{ujM@}vmkb=RD|v_dnAWpKJ+N+7IQhxTpRrtc=&xjPKn+s+7HQ+H_2bK(WeWz7Mx97U1=AQv_4ly|+w&ST4=d;;8*Cn;ei9h3&ysqGL-g9~0K z=uGjrx$qRAu(Vb|^mv@s=0}9$^wGr}s#_1uj3b1sXPgIxTfi20GdtL)Wq9 zucSk!++0Z9p1a>gS}!C@50uF4GRIv(Nxxb@<&$F_V^m+Si9h|plZD=Y045N=PC$vk zkKnRE=ACvSQBVh*j5SA(^w@)JDe}`QP6Wn4)dDD%-?xnmirl}GZmnvTt()^ix0dy` zER&`Bso%c*o(E-x#xWC(gDiTr35ZI@+Xmlz>$#A$resm`TTOd0l*>@i9ai!}YkUEr zJ^Y#0n!Y<7*lJ4QF8`boE@QBM60TJ<{S9up!+&hXbdLL5lUBKtT-RmzwesVA=Iuci zUOxI=^6<0bh(Na0+|cJSi;DF_{>V{;O<#|Q+-th=D5=L5_RXzWOo<~Pn$>n8X$Hg{ z2`2pnStEO)>j`?eIu|i!nvcgpeRmok;<8J7$-kdzR8Eb&$ucZY@dTxiCaLqi-yJ@- zO@4@dHLxxSV`ey{geT<-Uz6Tsl~g$R1$;!~8VuW?_-ZJ>wQyeei|s)x{_iK4*oVo^ z{(#6nQV?BEbh)PCLZBvD&|9dh+{Cb=sPV&lLD62BP$XtABbTY$y-rP{z24e~8(DBPA)oly{r1H5%^?s@Ovx1se*H>`$?>lowl23zh+7=u!Ad0DH-d>FA_G5ne`dP2? zFa}Os+|kjoihVz{zj@T0cJMt6%eGm+Wh-Q!A$GDYhjQJ7e#q@8%o^d>^pGqUu8mvG zxo%p`NtJZZ{1mM{mZPH=2Cv~C0m5ol^QW^XZwe;sLY|qVE&7#qbrUlF@>zFxj_U?w zlk7sQVq+8fgBV(wX{wl!CjD=n_KKv{FIhYF z6=(*<u@iibM~%p-7N27Z&M%Un^E#&PMZRn zZT&cE7@K#7uIX*zMEp@OB{7Sls((iCQ;RO`d#rsuxJ_GRF-RrpL(>hu(!l)0%%0)j zjxd9ZYb|Ky{VL^3WhT|UN3oZsd+J^4!GpKL7EaTS!N1s>R-(k*efO7O+E~*H3z%1g zLIHt1N5tt*J-m|}(_&g-9NjuM% z^HEck5vOq?WbTf{Z-w~$5G_7) zvwt51mTP^mn$eDAtKT%K-)x-n=iuCe$9ZrwiGWm0PM&Y%rU*KmY^j%nn`|HidU|t@`8;l8TGNdaJ35ptM=TPcjnl+ z3g}$1=gTSlQPG$UMhH(g&)&w89ThGf`c@}EvPL+2!x%-lkJb8wzqSM%ra=En&`Sqn zQ?&&Z2kYYc?$k#vcS{at-EM6ZN3n%DTSBpn0L&|^;-i8`F)^sv zQ|nNGF+N(Va9`L2d}btiEFO(Pg+6A-n&6{#EjB0^B6r}!r%e)rjW~A!bp!#Py6g;= z!Fz^u+9K*)eBb}FzL)Z{8b)~V0I(4Smnc_uueXEgt_WF zXX*E~RqU`&J%&gpxHl&Nw;rt^cGok;?A#GEjVs@x0oFr_Pe$~}80Y;8H3Ypw|Dr2oRH z0W(3Y*+;!o14=$cY0d>MEQL5A9Hda-mp_&pk(g`I>4wyrGob~DPUD_G7NS88@_7*< zDYUqY4F*^AbKZ2S=>ZmusnKOJ3oOe8{oQgMOFcq`c(;ozPY}CCSH5yK*{Qi^`&jEp zn2$_BZy5i4^B2r2(Ve= z?Zm02Y)+2*1zcIhU2y98H)KCjt_kQ?8fNW{y&}3K2w~#@5Y*VKec&`)@H_1JzH-jR z^}Ck(E{~fXP55RhGsuufAs}!3vd7u+GoDzNrl+c7M3~jfOtP@#1V1#>@F-;~-JF4) zS6_}=FvjFTPO>?uZ9fH0d$G{5PO}`+s8V@L07mai!KM7hIq2Zo04J6o)z+5U_|3WB zYkrNj++NyuJ|4j@*Ge))T4XB>^PCBJ2SA$!=Xbf1v{e||j(yzc_EUSvHn&U)zv2KO zMYd;WFLFT3FUQ{jOQD*8)`_hzzNs=qBxpmgkN~fL0#1}RgMB0A{N>C|_Z*DEc4>Hj zSr%4&G}NXEH1u;4F%{g&C%blunC`)ikx#L{3;|KVtVoHYWz*~gHYIrXvYiFmw-Mgcc{1RcSyI7SgfW zGcG|Wf4S(p;~{pW2`FIXRYnPS@>m+lAN$M3Va7S%-E3c?2(O!^E{QNioQ8b(eR5g8 ziR*n$nPRihlI7xKx2Es4oEYvu9Aygxe`J71IlU@|NNgNf=No}_+1 z|3xJj*0mU}v_M4yhs|F9aB7NQv%K@N6`Hqc*;{UWF$b=+FFrhvmhVE2)1GjPeze-m z6@IQ}ZnxUndTeFMm-vNOU0POUYddEQs7_{J03{||OsM`Rl#@%o$uZe}sexeX(bOMa zoQOmUE(g)mmtn9Jo7rV2OXZE;ow?W@`9~%EJK|9Dfx4wXj(WHIn2?JK?ySWmtUUxq z*g1wZxuA08$Xn-6cp5HTSA!fc2;Y|D|E2Y~YBe49wMXQTAL62uYzmHQ-nh?uM4Z)Zfmj=guPfucA6C~Xzq2$Ay-8@>0AxdC; zw4w>p(^t7%V!>3RfbSIC&n3&>w1F!&w1|$RYJLI#LsnLcArgF!y!5azo05^}s%t2z zGN_ErF<%5AFntL9`DIgp)J;b!I^h1{rgbkPY_CZmko4)CA4uIC+%_8A9F*W)uu)u# zCw-;I%h=5(<)B+NtwtI35v_RY9q%zsdHS_E8ryA z<~>8}$e}xfQ*zs{6ORnxL;nA@Zs%i|Idc4rvG#(R5RndxEj-JZz5-vR&{BIx`22cG z7TpBvvLH-x#|WhdVEo>pK8i+mky(9?@j(qo}{Vu=4sJYCw;mQ|;Mz&-Rd7 z#?amXJYMGEsyZ>rBw>}V&5)s022_>N<`|YSXMxHaPS!7SRG8Q%7bpQeR=gGE$VpgH zBIi(C3(;Vc#Mvh}SKVetJEY5XcEhQ1o@otm|8Kh;0u4`S4sbTLm-kQ0@auo~eA}*h zcEv!~6;MjkdCTt;)wMX^L0L-#mu3}vy(!*<-$ZjC+=X5CU@srfI&8E5^8@wc=szM@ zf2H&%zrP=i29~TuxBsS8R>m*yd0-)SeN4r^46Ul{wWd+u3t$oRTJPC$O@^9T23m+maij1|U45s2|iUu%OvNjr3 zb`{x^8aXwTvZUuQFBgop>USvvL!rj%mb9$smb4&Q7n0=Y*Eb_~LHJL)wJSe+DvE)b z8EB(0Yy+HMGGnwtah%7mO%xXV1fy?)| zy%o7hm&24ncTVB~_h~l4GLM$kWsafrL(b+|Z^mM=xb<>;g_D(Y2QfNO&i9`15h&PCsF#0x%p;m^ z%cb6Ecrya=G|)%sd=nY9J8AP(AKw}}*&Dv6{G3XMBf*iGku@FE=9vB|wv%+mSoSCWo#2! zqDYdRO#FwwzP{zZ{{LLp%sF%BS>E@|d(Cy8^W4wy7$1<(}p>DuyCU4?-m8sBshB)9bZuj^tNb zyL#=NLq*6rQaxeKz8@s3HSjPv);Am*@+XeZ`OMkZBn z{WuVa0enPE(9CIf((<_;DwHeuMSwOgv|?OI)mGL(J;vG(>Jt3LJ({g0E6me)PK;E2 zrDIx4XJGrg7EP+z(glnLtVKk?K;sM&T!*}5oR&$BtmjiT+w3m-rmXSw#r7QU#KA9Etn~hxhxEpBr9WmmOl4k}ASP7#Th{SJK^+qqhZ~ z(3dcB9^l)~+8Erkf4<4aB7opP^8@&FStZ7A#fzdB&S3p2FI<%yJQbXT6w}@Nay_qb ztGk@;)wNqx(dMZ-4~NhAsn~UjLJz{8EXoA+3?-^va83HU{EX9G5fNmMbYp6a4}H6oc8BtgsxgVCAb>7p{v3@(2=N^23|{`;E;mR!;HR<(do z3qH`<2R2wQCk(XV+Llr#L1r7m7};MzhWQ5Dj|O6q&3KEug2${2=zV>WNW@2cG7E zu~Ev6^Q$(uDV!;EX7G7};TN@H-XN#5?ItpmUIq=6=iflm$3rjE+k}uN?xLb9%TG6% zG0=O`cb?a0ttE-!PErGfOWvX~DD{!_6n(F^QQ0QC;Gp73uEm! zaNluv&Z(l-+ngS?N@j)4t)v)#k5zIZXauxUl9z5VzrK#%*xEw~FU$r=1FV6no97}c zzC~~EabJaFlwPywdIDh=hXA{9Vu$#rklYLnW1WDE^BGk97tv3%U#BcSzUEP=PJ8V- zs<>IUU2%UDfQ-M%<@TL%-+H-H`mr|Ct)EFUp0d)`Z-zx#*TY-rYF}G8ba0{KiUWO& z0U@ZAZS4J}jb7Ex$v1sEAFp4lmB^(yTi$|nowCUe8{+Qk%V~O1andbh zXmP=*#vyuz2G)T#6Bm71g>CVUuuzl=SiC5WNy$Rqw6pS&n6diOZL>%PwF*)H_^|m; z(72oSiVo;P-}noEoZLc9z?Isx=pPoWnTm!Gp_kyjr>^erK(`s$h1tfmg7X8F)Zzdr|oUu-sZK>Cc0s= zk^Tk7k04xPVlGiio{+}%mM<@CM_{i8;>+Ta3(hn*fwSf7Hu?v`to8~jiJI2N$t}X{ zH-=%t)eyzAL$I?owM)_txW{DQK*%7FczwpRU^L4y zrH(_#r}B&-j9PhleZu)=>n*L5INIYc2v-~Be=K2T?uoglo%9{?P|`L(TIZqp-KjBP zdRO0~TAw+y=jgn%uqCyq3WYj6klW~bs~IO3R=6lbd$`?-tSAZT7VGuRziQ9aI?o#W zp-S0!jdg&vbA^BQ)<0q4=p$TsJxo1zjK6=~Sn^4OMCXRV!8>T$!gRY+z@*Vsw#4`q zhQNC&d;ugl{~e-!{i)qTV~P3aq4YXEwGw#yd!%4OE*2Q-_;aBtv|4BzLo;P%eXs$V&h#}$@O;Qeu^Fwp zT%*_QE)zFz>0Ggw6o~`MeqTv($}Zm7LOi5*3EnpCQDqZ|em|pU@(0Nfi);^KUQ7$gY`2vOW?*mz8rtos4{3GhpRuha+G*PPz zKK4?}d!WTCpE4&*m&Oe;`9KeVJsYrqZWIiSS#wuX%44k_g@GmMLrKlQ z6=rE-CLYBUY<4%Q53=5ETnF;1&fR&Vf;$@p!=oIS**NVn8LqjW+ zrZYL4rN);!iX6#Dn&b%kaozk!1g$dS1!b~`Eb9a-fByudA{mnxgWP6i&%7u~9~wtT zN|w%}2kB_u99*=+v&AGw+xCk8ajgWo6D*YnWSOH~yL-c`7ir}h2uP;j2~mm@1&xa# zcQ1Un!6h+D@EV4xvRm1WrNnsVP%0H`?WZd{&_}3t^U-D@k&Mhp6&ilAib;2(jR{WG zAXZ2ZfAtFH|a(KDNZa0 zZ0yyYs*h_6*sY>{qxAB{>e-1eV*zxu9bpL*>sYz-dp$kk(lYgK`}g@2eq1WNhqf+@ zRk4xGaPvD@`JBpk^-GQPY1L+3j7-~{YRjccGS>rvrkSowA_8b9fXcuvlSm^X3e+E~ zQ2NYf;H8d`-&<%{kqj&l$HgpT(aRu$!Ef1hsVGm`TmP?=&Qs) zKPE&13#6$;u2_`ZNc_qjx<}~s=0ET-`P9qal#i@$2Ab%~0T{J}lN7)+lRhL}1lRrx zJE`y1Jt_?}0uNB7w-a0_CdhU9o9p6}!+xQ@3yt-zX_RTcMV39I)lt$@|HPtL0d9A9 z{E7G`0TADAG4Yjeps|5m4rCezEx8y<0)ZDO{!c8*C8D#8o8&Jx&H>rvhJ-)>A5wI$OGDhc5A4 z^hYHW8jKw`dFZ}&sxw~qZSvfgwnY!+-n#XLD#Gq8G3;~~OD3;dy1{1KQ#H&ZuS0G0 ze549|tNZNNb){g&dQhZ$7!E_Tlvp-m)m~s61V!0pw1qy6uuOD&6YBfv6Mq27yF$!|X4K1Oyk-2{~(!D|w=q(rBR!W_Cv#icIldBJ<$R_h4Uq7+Lj zk-I%d70$<&+HX`Arj3PaEydNg<4ZH?>Ln^NLeW<_$AUY~d`69)%+%Qw z;4nJJs;4doU=G5VorGDtU~TI{v!;Pi%JtsjC!y zlG(TzvQKNXt;Npobc-j8sb?>Tk;QVt7%U2yPTgJ>7x-;jbG{M1R;PRk5IbWCRQlJ? zOmCd}!GcE6tHY{th&pdza-T|RPMU8@s#Xrj2Cd*S4~kl*Khw%sSxS>tKOq2!Dw?RvrY zTB8-6LS=>Sh4459&2uG&>d(+=i2E#Mj&?=fUq`g>058D6r+}$t!2=<=oj3kCtJjwr z{DP*l_gf*QGK&dG^y_a`I{-dI)qqTHO-syh>_HK~%Ix<;qv$4xae2eGs^_3JW{@vx zIAB&{PE3N7Z?wwQXQw6V3}t+PGH&o0o3doLKREysJ5Gt_BN3CRz@j4i4S6tsh%wS)mJ1;Go8qK?NiZWeVU3I3K_|q zip@rFMiEzYc^k^$O7m_!6^TM)eji6u-5(7WO1QxsOlQTTeN6fBF_Vd%BUT zg*E-PCN5jynYuXARt~hiKE?H+{c|@%>Yrn&6!zUrC_EgMnuZ%o%35KNPV+W0EhMj0 zrht%0X~?L>YMW7Uz(Va-vbju$&W!E%^Ws3vJJaEZhb5J7SktkFj1irr4Wv?IZZnGF z*Hy(}@0y@7_pc&ir<30$&;}|fo$Kv(+(oUnIFT7{d%$dM^U%fzyrs6oE!z?J3|FC& zB|H6(UKBj`5VP?i@WJrfWDitr>}vuoQ>dKwDB<(v7n2<;%W@W&piSwBMg!+=5&I9W z#_k+4ej_h1K0uyAKPu0ANf}e5A2g4+HT5zQkxVn~w8a)z#Hqh$Wf*k1YRg)8(5j7U z)xOzDcCX@&F`5@~A2UpkDBu!w&>Nah6FhN5g5b}AFiK`#he}Bm01;%F#bX}J4kOnR z=9+ML>9dmp@u$gaXq??^`bp$?5z4!9^>;}ReS*6IAz#)e+sJw0Ja$Ar)!`&ebQ$5(2Lb`i8cp{D{}NG51*?amI|P38xR z+g}^=_6@M#g0MH_^y=UE&SMwfBsTnJX2!z zr?~t5hTM1|$+pZ+%*mF;AdB{<1WX`&6Bpq`ok$iWk*zWuU&V8waxyABx@SBcIZae0 z!`wwbawfdF64X{u=3LU{J5urHeeBI81vLZqDSLku^^~7e=Xt{2Bp%Ow#ixgLn25D@ zAo|iv>2PMZHYG4tJ||hL9y^eyA)@yf0xv!tu{Cf$=oT}Pa*UXf8yV~ z{q*;j)Gu%U6#B2X<8cFazRNA3?Lz`>bTH(10Fq(QWi36;QgxendkPFg8T*C#vnzb^rQ5qu~AwGi>9un`sxv~#0|ldX-7RIIuX0u&jXx#BHyltR z+|a|l7^bF43Q@GM+6d(v~iE=;LhHvK#Nu ztus`NRuJwFP0p|3W$IqnpN0F)_p1}LSo=TdZOvBNcgnC8eh&@s8eN!(wvgMwdU&li zJ9rIJ_3nL7Z5qD%4)4~L5fj;&vx(;n=C*NR*AIjnUjIDI(s0BZO+v~HVm@a6K5i!F zkuJ@9bReiE>5n1-M_YLAS`W$koa%SpY7V;LCn490RHd^ZV-s)FX5wu z9Wp?H4I7(5^&h3nKnoBNN)U(y0s;Ygf7@8;j+A5^?cMDpJpBLdY;a28ln5yZGyrgx zbN)>W1PWk@^WetLq|@@UWVxH9QhobG0En=|nT|?@pvRKHS_EYWPeQQoGK2*bwKs3v z@uLBekSzkHj^BR!`m?{9Cyt$zo(H?1CHAvLy-OxLsWuPRAxq@=O8wpaPY=J&gz#Y1 zGKKyhp;{g+Z&m=VcY*#g=Bl_~L`<5a<@l&Dr6G_iYI;dxw7u{kyx$Z{y~0EIOO*_!|71q5ikfSq&^hHmljuF#pYY z{#)ok^PddpzsK-z`dZMROXQcX%@yo=wh+&e`M>>*fmnWhf4q0X%IEOXv4U7ZG{8y| INk2OIKab~)Z2$lO delta 39219 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 VE}A8q^E5s1?|0xqvrIeQ`9J5Rp(FqR -- 2.40.1