From 2b87d51d0c17901b4223f8b6d1462328a29cfbd5 Mon Sep 17 00:00:00 2001 From: Caspar Jungbacker Date: Wed, 14 Jun 2023 10:00:54 +0200 Subject: [PATCH 01/10] Update .gitlab-ci.yml --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3658980..ed854e6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,7 +52,7 @@ push-html: - publish before_script: - apt-get update -y - - apt-get install rsync -y + - apt-get install rsync git -y - git config --global user.name "$GITLAB_USER_NAME" - git config --global user.email "$GITLAB_USER_EMAIL" - git fetch origin publish-html From c8443ed4fec3d8495be308b535867ee0a2d5aea1 Mon Sep 17 00:00:00 2001 From: Caspar Jungbacker <74240267+CasparJungbacker@users.noreply.github.com> Date: Sat, 10 Jun 2023 17:10:10 +0200 Subject: [PATCH 02/10] Add Dockerfile --- Dockerfile | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4a05cdd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +FROM httpd:latest + +COPY ./book/_build/html /usr/local/apache2/htdocs \ No newline at end of file From aca17cb7eabaa08ca47dbb96987b57f3028fadd0 Mon Sep 17 00:00:00 2001 From: Caspar Jungbacker <74240267+CasparJungbacker@users.noreply.github.com> Date: Mon, 26 Jun 2023 09:44:12 +0200 Subject: [PATCH 03/10] Fix merge conflict --- .gitlab-ci.yml | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ed854e6..c9f2f74 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,7 +7,10 @@ stages: variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" - + REGISTRY_HOST: localhost:5000 + TAG_LATEST: $REGISTRY_HOST/$CI_PROJECT_NAME/$CI_COMMIT_REF_NAME:latest + TAG_COMMIT: $REGISTRY_HOST/$CI_PROJECT_NAME/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA + cache: paths: - .cache/pip @@ -31,34 +34,28 @@ test-build: - jupyter-book clean book/ - jupyter-book build book/ -# This job builds the HTML when it gets pushed to the publish branch build-book: stage: build - only: - - publish + rules: + - if: $CI_COMMIT_BRANCH == "publish" && $CI_PIPELINE_SOURCE == "push" script: - - pip install -r requirements.txt - jupyter-book clean book/ - jupyter-book build book/ artifacts: + expire_in: 30 days paths: - book/_build/html/ -# This job commits the built HTML to the publish-html branch -push-html: - image: ubuntu:20.04 - stage: deploy - only: - - publish +build-container: + image: docker + stage: build + rules: + - if: $CI_COMMIT_BRANCH == "publish" && $CI_PIPELINE_SOURCE == "push" + needs: + - build-book before_script: - - apt-get update -y - - apt-get install rsync git -y - - git config --global user.name "$GITLAB_USER_NAME" - - git config --global user.email "$GITLAB_USER_EMAIL" - - git fetch origin publish-html - - git checkout publish-html + - docker info script: - - rsync -av --delete-after --exclude=".git/" --exclude=".cache/" --exclude="venv/" ./book/_build/html/ . - - git add --all -- ':!.cache/*' - - git commit --allow-empty -m "$CI_COMMIT_MESSAGE" - - git push https://gitlab-ci-token:$ACCESS_TOKEN@gitlab.tudelft.nl/$CI_PROJECT_PATH.git publish-html + - docker build -t $TAG_COMMIT -t $TAG_LATEST + - docker push $TAG_COMMIT + - docker push $TAG_LATEST From 07b0009a45c7701167efdb64badf55dd1e113eb3 Mon Sep 17 00:00:00 2001 From: Caspar Jungbacker Date: Mon, 26 Jun 2023 10:36:13 +0200 Subject: [PATCH 04/10] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c9f2f74..3d4117d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -56,6 +56,6 @@ build-container: before_script: - docker info script: - - docker build -t $TAG_COMMIT -t $TAG_LATEST + - docker build -t $TAG_COMMIT -t $TAG_LATEST . - docker push $TAG_COMMIT - docker push $TAG_LATEST From ba12b0c3f71a1271bd91a27d41fb0e26a30706b2 Mon Sep 17 00:00:00 2001 From: Caspar Jungbacker Date: Mon, 26 Jun 2023 17:42:18 +0200 Subject: [PATCH 05/10] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3d4117d..71a1abe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -59,3 +59,15 @@ build-container: - docker build -t $TAG_COMMIT -t $TAG_LATEST . - docker push $TAG_COMMIT - docker push $TAG_LATEST + +update-website: + image: docker + stage: deploy + rules: + - if: $CI_COMMIT_BRANCH == "publish" && $CI_PIPELINE_SOURCE == "push" + script: + - docker-compose pull $CI_PROJECT_NAME + - docker-compose up -d + environment: + name: production + url: https://interactivetextbooks.citg.tudelft.nl/ \ No newline at end of file From e04e274eee85addbf348379459f508856b3cf61e Mon Sep 17 00:00:00 2001 From: Caspar Jungbacker Date: Mon, 26 Jun 2023 18:06:09 +0200 Subject: [PATCH 06/10] Move before_script --- .gitlab-ci.yml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 71a1abe..6e523a7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,22 +15,19 @@ cache: paths: - .cache/pip -# Before running other jobs, setup the Anaconda environment -before_script: - - python -V - - conda env create -f environment.yml - - conda init bash - - source ~/.bashrc - - conda activate jupyter-book-env - # This job tests if the book compiles gracefully after a new addition test-build: stage: test rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push" + before_script: + - python -V + - conda env create -f environment.yml + - conda init bash + - source ~/.bashrc + - conda activate jupyter-book-env script: - - pip install -r requirements.txt - jupyter-book clean book/ - jupyter-book build book/ @@ -38,6 +35,12 @@ build-book: stage: build rules: - if: $CI_COMMIT_BRANCH == "publish" && $CI_PIPELINE_SOURCE == "push" + before_script: + - python -V + - conda env create -f environment.yml + - conda init bash + - source ~/.bashrc + - conda activate jupyter-book-env script: - jupyter-book clean book/ - jupyter-book build book/ From 9a141481421a4e6be3911b5ac71220af47c631ad Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Thu, 6 Jul 2023 14:57:48 +0200 Subject: [PATCH 07/10] Instruction how to integrate Grasple into Jupyter Book --- book/_toc.yml | 1 + book/cookbook/grasple.md | 55 ++++++++++++++++++++++++++++++++++++ book/images/Grasple_pdf.png | Bin 0 -> 37897 bytes 3 files changed, 56 insertions(+) create mode 100644 book/cookbook/grasple.md create mode 100644 book/images/Grasple_pdf.png diff --git a/book/_toc.yml b/book/_toc.yml index f04c1ac..6fe2561 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -22,6 +22,7 @@ parts: - caption: Cookbook chapters: - file: cookbook/recipes.md + - file: cookbook/grasple.md - file: cookbook/jupyterlite/jupyterlite sections: - file: cookbook/jupyterlite/configuration diff --git a/book/cookbook/grasple.md b/book/cookbook/grasple.md new file mode 100644 index 0000000..19d27ae --- /dev/null +++ b/book/cookbook/grasple.md @@ -0,0 +1,55 @@ +# Embedding Grasple question + +[Grasple](https://app.grasple.com/) gives you an embed code for each exercise which looks like this, which can be added cirectly to your markdown-file. +```html + +``` + +The embed link is created for an exercise under 'More'- 'Embed Exercise' + +This iframe can be embedded into your Jupyter book. Remark: it doesn't display locally in VScode or in the build file, only on the hosted version. The code shown above gives: + + +More information on Grasple and the support of TU Delft can be found on: [Teaching Support - Educational Tools - Grasple](https://www.tudelft.nl/en/teaching-support/educational-tools/grasple) + +## Replace iframe by QR code for printed version +Dani Balague Guardia created an [extension](https://github.com/dbalague/sphinx-grasple) which allows you to easily add Grasple question with some formatting and, more importantly, the creation of QR codes in the PDF version of the page. This leads to the source link of the iframe. + +The grasple exercise as shown above can now be added as follows in your markdown file: +```markdown +::::{grasple} +:url: https://embed.grasple.com/exercises/767782d5-023a-4b49-a1f3-874fca626c8e?id=79907 +:label: grasple_exercise_1 +:dropdown: +:description: Example of exercise which goes along + +:::: +``` + +This leads to the following html in the Jupyter book. Remark: again, the iframe doesn't locally in VScode or in the build file, only on the hosted version. +
+ +

Grasple Exercise 1

+
+
+
+

Example of exercise which goes along

+

+
+
+
+
+ +In the PDF this leads to: +```{figure} ../images/Grasple_pdf.png +``` + + +The extension requires an extension of the `config.yml` file: +```markdown + extra_extensions: + - sphinx_grasple + - sphinx.ext.imgconverter +``` + +The extension should be installed both locally and on the server. \ No newline at end of file diff --git a/book/images/Grasple_pdf.png b/book/images/Grasple_pdf.png new file mode 100644 index 0000000000000000000000000000000000000000..667954851bc121906c0f2e9defc6278ce0b69838 GIT binary patch literal 37897 zcmd43cTiJn+b@i|)r|_eiONPqkP@UTy`z8{Na+#qcNe0A&7QoY3xMNX?jG5>CiGS}Te*jZH- zqbRI4?~Y2^H*GD$$SXW*mn}0>m2YyYCI8uL$ux6sdqRrhXVof2A(nYr&7X>G+gjbM zp7&{`3>36kCQ4B@tfaBm!Q1bDSy%nNOuYl@mt+&VoqAp1>*19fii`)}(xm)BYx?Wk z=M0?ghYr4HQ+@q^JXkrsleT%qaFl<5i{_zHx_Vsm+5HzZz?kCOxwK9myn5K)OI)EL z>OQS$MA@%%w{lstFR9V}ek<5hk)<=pa@l0&d0rnoMw%3e*uh)>DJU1@6y~ic(KX%C zcbZ0W88&&CdWzQDJUaoBa)Cju?ZLPbp&$8w5xHot2miXI1U~I$8AnwjWNIjxBc`2> zTZ-8x&RK%hMvCG0?RT&bTr`(#;wn*3b&dN=W%60%`=U|Oc*e@x%9+D77BAoYUDx#o z^_`THu5Z*9a=JgMlHh7ezZ(xJe?+`wZ|3jsKT_xxcfF}UV&(`<0uy@k_Mg zD2P{cR`nX6$Fr_4YjeP92k$v~v=VG9u+kols?&+GKEf_c3;EQe!PgnvO!#~0$iluA z<19uK=Nlu16yxmHImwJ@35{2Gx!skx9(W`UilY2RYH3lSp#>3TeX|)Jy6-&>(XYYzWK}M2`$BuGPyA`RLiMYes*}%DKlLq(+GfqIFO9mc zOlr-nmdtI9O|ayVJBeRAMmiWeNYkNQ#$RX;t_s`-cJ=LaW~A%L`ZfH8NR@o+Hb*WG zvF}+ZLm8 z5ZU}I&dx-SXePc^cd6&P9X8veQ{kztf7FkTlZ$rnES*lG$vk1+t=cZ`sd;^vA$~wV z*1?6#Z6<~vCj2WluXnw`C*0&TrkC=ZEkzDojW!V!6ZoPr`K;hbtL4g+Nlu*K;-Z!h zr6g!<7@rznHr@DOqvaqT!8T^7Gn%kv6j;UTWM~*lX;t_>YDo;c`&c4780Xl$@guj+ z)2&W?(6$9O11VQ8~e z>GcHWe2Hus9Fr}4y0x#eZKZsy!SzwxexOpb%j-r=ZH7CR*2sESl%eCU>*aQhsY3C= z4RaT6(!-3dU&qlTxIK7Ki&69#*ThP76~dMv<)6jv7orNjaTkPJo){C+`E?yw zwnp~N+D=qPse0g#F4SRjTd8%3`ZaMxpyX|bh)}$}qQqV8p81n2b`l4Fp^;?uUQTKK z(K}n+1?z^C;~n^mWPZQ-cflOm{yW-H?R13@>9$^B%SH>|S~0p`ubhyU(X?~Z@Z%yd zs>dTIrF&&&?0@~qS>AbE3A>@?gzJ*RYTxH}f8tO}WU5dQkU8?}i0{pDd~}>S8=ZF* zlCvtAOT2n|fBj|H|6YdDlQ9?vT8J*bovxUCXL(hOLFV_Ze6Ne+F1jgf9sdDDn9P|> z?5}F{(8hW~t;(kh2GhYGJ;$HNJjL?6k`*)dMjl8B1OAp`=sT{ZvlHz2_EqGMUuU5S@|?em!1~;^o=sq--tX^4I((8_ z1;g-{=HxBk9MzJwY?_D#XWcPnGQj&*RO>Z9OdHnOz;LXVLtY_TfAVQe(dO34|WD#-rsZf-e zL{zj|K3C8eVdCZ9LK3%O(7ghFZ@+y0P>})$!z{Hd4GGn$H~y|us{~kYf<@Y3Yku(j zybpOc;E81%ty0AuBf3DHKK*9fk!7vQi@hsFFTH)o@U{Ha$G@(Wx-!-d@f!5YO7d<#rMg-guM!O zX=?G~WgHeODW=sp8&8YKZAn~>`{d4z;UtIsZGK48ngjN3k5sTA-cWK|CpJoMbLhO! zM!f@hh^cj|ZedqfezITJ_thIdOp7ed#EF3Ezz?UUh`MHPD%Bgt_M`G)lw=4)IrmtS zZctO9k}dPtY(s01MMwHOXrs-NtHr2wN6A+a^7s4ztHg4H3-SX>zNZt}3Tif0t5xkq zEWQj|rxL!>rM)y{_|B!D^;x*d1778@;$!A`<6QI%>--hECJXqRR$fcT8J@uzMvBKx zNWkGjz^KzD5v$Vpc=I8L{z7O4Qza;VZ zU-u1*zr1<-rPd%WmR*a2_fXag54z=BB_5+Jxc{!ONH@-8KO=gFey&jVyYg%9vt}EX zPR9r-uZEzA)2xCBDAaF7r8a|S+RN&6Ye(7a4YP(g+QPln ze0AF_#}95Kc;ceUWMYJaAAJ)oByI4TVevBTkHj@P{mP4mG6?w{yp~n6y4uv5bIuii zhQF@g<4XJawJLS!IgjvY+E$upZ>5#|{)w)y3u86zrJGj%PPtsYoa(;39bYm@1@x~s zv*B|5gNzP^G0X8?<%w}Gg1?em5)hUv)rH+{9*t(Wh?kjKFu|)Xn|<7B&)m_0Zj?9c z+O}frT(*d7475oc`MxF+Q(``$|72giMQ3=Y#R?zmhN`T|_Q#ih6BQew(AT454e4q5 zHamj7<-vY?_6>mgiS-U`JBmHsk4cc`~ive+Ys&?p|>0u z3w(-heve19(dLM}?cn6CvhTUGH&4tZa<>sB3}WK$ASX2(5n5k-aMFPU*{QwudmB7U zm*<&N32(U5ZfNasmsT}d<$PDG+eRGWnI7D@%j#sez-Rp4Z)%Ma$akQpo5scsVMOrQa?g^6Q|+C zy=TZ5dav zZfgr?gPA|M?gtUtA|w*GK4BYH`(%|i<+k#&HFWa@G(3fvINH|e^XT~UB-G6=RT+3D zp%cvXc#QTg*?Q$+JK#T(rbH~i3sN-do#MHjxXp&LwbQ$IT#XGUbSkG@D(?^IZ+21Y z+ESfDtVtX-3Jj@Q@$+RiWxEI0KcT8fS>ciL?a-%Z-%N-K=r4Z0(c$sf#MNg?@qWNj z1&`ebsiZ(IOo3jkUR(HUTSNdCB0%isE%(efA1zM{Shvp{WxD3z`9-+gL=hvdnCPS{ zH^rl6DAYNTjaGtoqz)!0DMa57^ZitP=xsV@&S(~s@cl)Rj+vjl5%v5KlP|l~dwKkk z!8>ze2GC~lnKyDbj#2Emy0JcuEjpw*p*@u!PohvmtJqUPKDRm`Sl@x2S-0ir=ETK# zcYE)=sh5#0h-yAaV3@ihd68sBt}%9sHhxlgepHWp;4=L+M!W;oNRQsG{Hs2O zU6Ehb**gJn_+qvEa%!%xs(bX;YXTx(tOky)l8ch5zUxt^ru7miznK19{j zuFcB!I>gZ1huafPw2kQeRr?5nNQQv2wAoh#mEKx@SNY7I8PhoN4;h6vudfanI*D2v zW)9*a-7~d5HNzwy-$afj)n<>X^e!*N1i#Dgju9MOK=@`laf-nbBSKcuZyC zfZKP^oqdG%X=8o>Hd$BKxT#|$txeAw;o$Opv&)H`FJ7rXuj=@zh@GGkdTi{Xig@^& zFRr#@+EAFYcc^{8wY9rBr@q-lxmQz<>7lIIXFORZ1M`P$%>>(rk?{le?5D-~?MMCy z5{j`zseHX!I?Xs!JdfTybc`wT&B-*!Wu!VAL&-3=p~s|pz=C}4UHjFKg}mkq6TD0c zbNW(eYn09hkkfoR?y3oJ@{d-vPI*`2iTWWu4GB|WuBSFhi(iW#pR$P6wk@4VA#d)( z?uX00Qm@-z#qN2|$JVHyy|xrWq6~7YzfKfZ!&PoH7j9~b+b?&ezIy+~)qJjr^Nz3R zN2PpQJVDrrD4W&7M9CJdD#~=fSk<`VXBndyt9N$m;iVsu|` zcB^r@y&FfX;Xd3;?>;2uEjjSHaAd6gLz2af5l60)oM!E}q^BxlM@IDUeL)>&mQqxR z!I#JXFbLCE{a~2PEF~0M=hb~iX7z6guYC0j3WAxl*B@%1obs#059$-=&c{4EExsfx zm2f_@YNB=fpXi2J-fd0jylwFeYD4)E7wp!ti&tdL5Gsm7?9) z6^xjH(Z;zNxQ0vFd++xWwM}TaLPM!_e?v}5aa7ojS?uR0$Bi8(NtR)`#mCRjD7>^Nwm_}jr?v;g%$~WkSXH^hog<|O!*w#)HAo!>FU#C-Ob8cD9OMxqF|J(P!MwZFuDK&I}SL?c}P58i;+iS?L)fU!Zx_kLH;X?wKY-1xQH z6KRtglZn!7%drlzLF#|IWSnj!jmeN|+y&E^bxNb6yrSl0BUhycId&2JC9BLr1v#I; zUw|EPz#YntNPZGC_+94~ocZ#OZ(+nVF+UYk6ZP2?5u3@}8Q=9P);#YxSEl4GdY&k5 zOdLH|)>(mo{;8 ziOF3i#F#;>%G8YhaL^e`JNB(*t2NkLDt}YN$1Pv3-QYftPM!Sxs_;fjo5d>n4!8Kb zFoLn31$KK^KRZt2cxLrP%GB@V)Qy6=YvSi?dhoA3Lb!I4%;k8p0{4{Ui7|NHkss8j`q?a>1vf$oKTKWh{y~nD)h6+E%7K!KgKk>>zv`n8pERT#M1WV#9(Vc| zZ2YVeZ@69Byp+0GrAX141ZrtCE*BdjNY#1=;U{8uaT@=l)S;>bb#XJZeE8 zu;SNiA`?*_GVI8SmWb$zCoA=&*a%BE4BJINi+R6D3zbi+ED^5|8qrgj$jyABffDZ+ z{a$exj}CkqVV|^0D)tbUx{@XK(}~rq=Yp&LXcL#$_Y1CGBauXxe4kBq!@{NjesBwe z{qP?ZNyJErjNH(6oyp9aiInBv%WoJZpNugiTQymvi`)vEHN1%LS$VDdq9+KJ=n~e& zTB0sLJ$OT!e&g==#;XoiDoBo!g2+cqsVFUEXx%6)G?Eg*UQZ%lTq?59k1W3}j*rOv zI#%|1NJjPIdg#z**~)x7qOQg8N){HM2Y90|(PG1<{GEx?REM^#_49t`aYjto zp{6x_{&!6nCD?C^x!$8_Va7+N9^cjdGs90OpzY@1?@X^y&w#wKWn8d-HRrQ=fptO6 zb25viKbKoGF$!pM_}w30I|9DnLQ3VT99n#5E z@!(MtL#XS7@)cE#N>&d*|z*&*%018rFiad^Nj=`b_P5t<1u_IgbIR^!BL z`-IJM8Cuq^r?iwh3@zmu{b$DM3+YRVO${>(`AXw*{VK_U#a95^-QXT2YM&r;W!qG%guMo7Gx z;6QqmO%zR}Vfo^iVH!OB>spk^ra-}%XH{k~8QT$M_h0Zp#VS@}3GUivg zXWPw|U!n5a20ocMldp5q`nOuc^RQ*shD#qkb0wm#|S(9!X^&O z5_;v@iMd*L73uK5l}hW-Wpj(9=CZLqy%eq z1Jgv!^I^LKhH~$Qe_iHv_hBa8UzhbCW{-t5_LF*rw>8qft&_06?u|4;%>4+I^C72R zl<`zwtG^U8A1ZFtHo@g`hW1?I1TQror1*P3;oM0V)F9D_#S`B_WNrkT zlP9N%7#$tWu?;9P-&!T%BVA{ITvUyG`Y=1;;&kfZed{?I}*^{*1-NJ)?y2p;TP72WT zoc(d1JqT=GO;?tFn=*TWbz4lPPDVT|_13Eko0Z~OUF10qZ{;rT#*#GnTcW_eadL|T02cO4o1o;Aw~=ZZnY@0 zQwH3^yK)gj$~<1AhQFpd(n3-G&w#io9KuN*o8(_gzey*Ydkt3koy3%O?LBYL}Cl$2KVoLOYwQB3gBSi&(vMpKSlE zTwQBDR2=~4bX};TG}fXZaMHq1&|Y*$ni{5oTToB~_>2$O(M^IC>ODEe*6cwXx5M1I z>=8a==cYO{!codbC605dyn=@L%68o!EK?S<4GV7JN=HsWPy>NmbL6pDL_CZ%S27e+ z&l)tK%${4bTfQdG< zO|fmtJQ-Ug^~7m;nZ3!6u4AfYo6}ifKQBl)+VA{4C`oK`mdc8;5x-1mnloI#yki=g z>rrn>ic!lkChbPao98I7&Bd>$El2B8XWn!~oHQ=BM=y=mV_>A=&rkGx4s$!#WW8nzN(BUx>5$cFby>%MVv`l>h17L&=c86 z0!}*>_7?=D{^sgu-DB)-Km;DA+E1es( zyODv~rrbatm#}I7q|6?)y%eGzC;Ux$H|&xeuTaf)KFYt6i}6@?)c~LE!P)4C* zy9@n_(IyQs0vOp1QY7@n%QUrEBe7QwQ6>lFo$1kq@;~vIb_W6uTe-Kp1&%OwEW25~ zyNQIP$tG9Wd}jyo8-_Z(40W%%AZEwuHqk1EuE|IWG&)9q(S|*U80@$-^38HP5O#HpT$91C$Un@(<6zn41xJpZ zx{8LiCPrZ#<3i)Ebq`)=+gZTE9GXDpGLDHE7KMlm{a31(*s_;F_C0CcIL!6 zUe1z1PYg;qj8(xg+R~W}0!#Q%`NC%#Q^dsTD)?zRef7D{15yLJM=W1%YqlWYXW0s} z(dl55L%gT0<9eelG%?9pH%kwWt0b#Jv|JAYIDx6F{U$7#q5LGHU=*lBaaUxS#qD3K z36|9=^Jq>!)BbRmr?=cA3w5|+HowW_$m^Ckk=qx<)yu6f1*~W>iP=S=wjt%LLECxJ zZ;QIK4LdJnHx--L)AMMh1f%@JE=sXeiwN3)R*~fgzqb1s2{^gWyX;Oa;yLGqB z)v^zpNYtKU>awP~=*lT_`tW4O~wybm;FT?ah~aSgHV#45iMly(NlXxt-$@RyaT&YVZf z_QVV2<(hc9+FQSF-5Hni?02NH{q-MR96g_J)neBjTV(uJ`*>@hL!5}UxSagvIe+UQ zP%zZPH9_*|D)cz6jn45T7a_3yi}OlXhyjb@PCiEkG)GM91d$K=%iJ=Cgj>_MCI=?` zH^^~b$6~nD&J)PK&9-U%?l_U4-R<-P1(*hXOObJEz7Lrjonu@A70=0&RqDQv|_ge2vW`sZ~ zHWWtD6UY7Ay7dtbzWzqV_ESdn#!gk1zUm%Q!o7B>ROmMe#&N z^TSm-DXFy}*h!#mq67dIEUE@R)Tizs;QZ;=6yI5qYxS5EPXNA@$xNq%G*&*KZ#8hx zdV<_nS=ry^A?Z`X^udRs;uE{%C;}QrAPDezCD+4P#)-`$AE{Wvcopkm(*@Y_ywdyg z)3OH(oxs=d_~1Lx+t`wSw>+)K!Shm9n=4b=$%;>(i#yE`R_^3IxJeMd9d?mtrYA?u z-ebD!n%ZXN;+K=S-GMT<3gXba+ouaG)(fq0ZY*CzPJ21LGpq8YrXMbMd1tWPLqra} zJozrXyf|6RvyLrG;gdqu9JW2 z-4h?Fts?R4LoW4Gz!+Atq(fU$Ew;=C5*I&}M8p!g4ufrYN>M%Q0GqjQ# zmMAfC&91-Hz%}woQA5Q3|V(? zq^U-$leSLmg6{o*J P#R>TIY~ibX;*tcwrg*^yYiN3Q5~F!GTdpD#XWZH;tXP!ti}M1!0G1Y^{I}fqb|@HFc2ej4ug~HdZWChV{5&D3F3?Q+gfL#Lg;sMn z8BGEFY{5u0B?ax;vZL8=zJNvZ>Z)@xFf$`f!(XOOlmiS1J(!_^v4Zm@t$wf+H2)7@ zR!Nc3b{szWjNwW$^9zaOnbnm}&8AO}j=)Jm3BkBn=qm!w6uA#Wu4IB?JqF(7nKYFa zM9@yRa&>vl(Ua#z(c#eH<*_Df_JceK=Hp-}{|$fs%Y-8rW2=i%r$_tS8_*NsF?ZU_ zGm1foHiAZZpB=q5U!ghOm1&;R&c!HLMq-#6tSCV#Ya~cs=F`UkAVCE_axWY^SLgbQ zn)ac;MzQ*n9vhDsk;OhxpZ#|?CZH#BNnZeXvWw>YXq(du8au!wZf`A_zNC$vOV>scSoezA8k^+o(3}6wBeC$7BY^gBQr4EtgW5kK8^t~oSg-g7%6d&fbxy~HvJ4HZ z@b|dnG!9VJEDzvzbl9I`AF^-}tyme%!88+F0Dw%k#m+w!Gxc*5QC|w~e?7)Wi>w%n zG0r~p)!w}BC7PZ^`pp%0Mg8NFTU4mSNd|FS9uda-zd`zxhLhaMGag%WB~7u2K--kU zlTq#POq^*&`7yDX{|(hOARZk)%AjClzp*?K3kvv~$>#RY695=lum=ek7e`Ua(Un4Q z$4!6;{KH7z|5K=7%KsWbb-|q&u~3=x^o9Z zkO0Ky-}`(RvcYGVpIV3{v?{ZgxlP1aC;HSW|721KtlS2e4yr1X^A|vAZSf7ao49N? zX#15;%aJ}AjE`#YZjHxUb3 zO;imlAwBLnPs}q90nqT0oLxX`u$r2;7E?Ep#TaN zb-0tcxjGR*FuHG;c50eij?|){jep0p%~QG6HWkT5uge;b;UjN@{RGJesF^9?e-`X{ z3}f-NbkMtsB_QQ4ABUWbZts3HNQKCdv;_L+UZ5Ldu3U9e)Zcsf(Y{w05R*7zuHL>+ z2RUPX_}A1e_!0H5%J_>cUD3xS=$d^>M;PatRuluS5co7`vOQTZN4FpFBMvGXK{t31 zOec8p!vbZ_JF5gW5Vq=P69JAi496aSx9U>jG~~#RM&?%OHO2}#vF}BkG%6wZ3>-ai z_O-Of^cxtb-`Z?PrH>nA!=H@j)@%8BZ@N3nx_gAq3S?XUgKsAQXhwejc%MwE>M7|? zV(HJyt>$Gk^G-%7AEUcK;*EQ2`R6_%1!u0=CWm^+Ic$)}3L2e%0Pr=fU;fG1^(Uxz zMXgEjwg3jtWa_W0iMgczjD`o0qj#GL)|@wGXT9GQm$4uc&{7-y%wpKPIPS& zAg>Y-7??%#n`<4(O2;7^-0nI`#}79}aD}3_#q7FZaEI~p{>MvidV2kd*nj-WYP zcBHC68Nfs@s_TPplkx*DPAu(%Xc21-ByY;_eCH%iNUz)48X3T419m>_F5;!H6+bLj&AyA&xYwOGMuum_lZTx`o#@x*qZG_N^ctV#JGW~QE8IN)nw z(DgSJprK(?HED0#2-rF69D`V_hQ^pam${5^=yhtLl;_%M)9IxWLFwkI@SKYP*wZ)% zs3tgulK@SIXZ@j6Y~P!myW8J{%reMJ(VcJyOL3?lv=$yfR$wM($PaedyZs>I9lC!M zZ57GqP>|cnHuz%!X9v@ZY$P1|&bqTw0qo3@TSX9n3wmXLR3MPF$QGjt1R<^7hJrLT zG7TBbbr>jh!S}RxYaeZOutWW6jU|BkuQlF+v1UiK41ltNTz5q2_BTcZKM(?v4Et_3Aan%$gf#ZZ4?wJT`D46#E1q|6elWbzO*%*cW*kD!&(gqa_pTzHs> z3&bW{n#@vcd`?xd+HdX#Y^{~`{IvI-Q|uNx7>|YVRU}xyC7*Z{e`4*zDKYmp7eGcV z8>8|fd^O@>9?-VR@wOzP)fs|>md!u3=jRf*weK=1a5bpM|1c*aTEM5aZJS*3vf=RSf z5+D(75LC8FS%<27KY6@m=0k7R2}VJFkZodU1s3HNnK#V)q4p{6H_HM7&VLfjTV+Zi z^oC=O0Y!yBAO&C<0X_O{pjxi(@&OR?d#Ckbu&UB^U-QC_WooP49*9bYy z>gk|E`CL{RBkbIv&D=V6qzJ;T@g^;xP|xA**lc?Jl>7F&i+&C9U26cZcItCLTjn#| zn4CI&MO(*KOR<1;k4zH+4)#!z@s5&2Bf!Oogweht(2d0Yj4yfS$QDoXps&@f_V+=4 zEOM3u3ZU@4Pc)D;+%sG(y{m4r;!!Y}7{R5M{iw)3{_H??Kn2QQRLYJKr*T^P??Gw} zU`NaOtr_6eGwz7FD=`UMJYSja24KaD=#!z2mF`yF75#4b@!pLCmC*P|QLpHsY+7G# zISJ|aCRahjc4vw05eghZajTQEoB%JdhM+_p2MnxQ;w=yG)x(wlmhB$^y?q|y7ZwNT z8IV0V@@!w3=A1;90No^xE0WY0-L#qr7;rfe@?q+sWhdg3{7{4(qBNkabHCO8P)hxK%Oyx&&?H`;XPd* z^PQkv!NWB}&kLCBEL1LsO)X7__Wnp)6K$MPS<-tQ4CrT3r ziGB-m1bKjnn=3_BGPTo8n!Njg)N2)UDjRs8I0p@kc*`$6L0N*KeBy7GVfEvw1sM7} z01>a%rsMU60E44;8DGu!ZHLKjRIIV26e5vG8hR%3%oat8f(Nb&^t3u!aKU2c;&QH<7 zXOVS}VhW67_zg|AQd`t0ofR(&e8T&iDozvq&g>@%o6-OIsUGm44spSq`M{v)-aS!C zWi%fU%Y@vU3;$~p^?=W`Unrxh!RVTDkC{fVp#W?4A^o*ID&ji22IMtEkGo$%m-oVh zzyuOtF{O^#3FzG~_;9ZQQtVZ(&Zik`ij~m17qquilBNFm(gXl!AdZ&HgZ2Ue58=Jr z@Ie77i~fRn3)Uy=hto#mZkdqW6{)Pm8k3ukp=PXc>yymcQS^@J?-I*~S64uY9q4yyKp zg7MqyhaelFuUrfuYQ_+f@g%r%H+vjcKCE%=GZ$XR4dh|Kv5wfBk2Oo_4z@Kuk@*c(|9+^__&J zFOD%1L-s^{3uVMK#GVn{*X)26$Cq2F-Lp@I;#2(r5CIV8xK#yUEpSq<^Up8&eiTQ@ z25>&=qea)^ubDp+we0|EVTu2SYo=aKJjx%hZ!N4h)|P~zzbJVxr4ZRyXq%7kaW-*l z5zGG#3BO%nYh5EnYBs*T@kE`J>oQtLbw?lvq&YSGC2UgrmqZC3p!m0!6J_$;l`2t! zwu5Ove13d14YYPZvPwu_0GZ3VQ22QpXllSbV1S@ZJbNuWKHl$G9Rvkz^_&l;r((6o zVbvEbhG`K3BZh>6Zgvgb@bUgvQj<`PC|V&WZnH~AGp<4Z)>{B6q2z9topFqlI%ye5 zybXY2fFR?-m<03zI@kbsjU#)WD$Tx|k*p?Y(GssaO~?fy0v>n(5}~0w*sxikNOvi- zFH~>gniHftm3Qq3IEU!kkG2j!Z-$-+oXuenpf@NvP9dmT7unkb3Srh7E(g$hoST$g z*Od*x5!6XSfC>nBB#XI5c7D+1Be>}280o%X6aqk3VR!wjZmfP2-{flHZ&BCc54*{c zmy1w$vCk85S?Q|vkx;#eHqYNa3#Z=UJRrqE8F+L*M2USea24gLbQ}cyy*W;#KAJOd z<@@a%@y=*j0MxC?glT+)B#Y#mkcQJf|5JDbu zwAg)0n=g( z`f^eT&@8vx zQRQ2NQU)7t+kK>1H&gqYuCZQ|UNdMn;Jg5ERs!D$dSW&?j^ zt}z7#N8Xfay6-*ZB8@zhYgD9Ky|?QJV&47xO;^CF|4rC0Q~Uqs>Wp8%u+*m;3}Fp4 zIC1vMJ@z0Y5eh(stjyWM|M^L)7N51ptmhNA-rS~ zvG|^H6HvFY3-c8V^5Bh+XbzED=pf$BkNjkw7L%qPO#}oI};urIs(cIB#f%AYI%z?eRz^}l&YFG z0(lwKQviZ+%EkI`!3G+*ks5&L^t-5o5NIy~EvrSj`g84k^_C+D8NazA+~-kITSKao zxKUeIrwVjJAar!=>Kh*Mzo`m#cMOP#Vp{j&l|7*WMe{iN_4DeWKayTa5U-+hako|9*E%d{^zVj=n>f?twK@Kl>);*vDK4Ho!oN?DG0nvKBDn z4#2j?dJ%2Ady95JB9l8c72;qPK#$+oR*s5;!d>g9npQ~q0*qe4Xg+;$G&S}2n*lk4 z>*ysP61Wv_H9;Hr;C?$!p4zoT{ekJB_e=~46{$<5qCNYCF&nRcjBd~SQ%3f@U2Dy^_$tcuz8Zq zl+R7ZuE}6wal&WJLg-l{G7^0omF1P5okH99=7SlBv{bH$;G&m_&xXNkHT981?jk0fFpq1X}LV!0%gF1qGRGal?Ek87sGJ# zfQeRben4V#E6Fbg{FlK2K7fi^P^B|+1|@d>V7TfZrKZ0K$qg_A|T0L<=)ZdCsR zzEoHG0{3>j2oK$pZ4^uObIqV+Mh!);z1b-i zl;cO>P5-wl#|A8?@7j!;Vu2M?gb5`V!Q45})zj-I0Mfz* z0oJ@arm zE8oNY00APw1sZ;pcun<`iz=bsUcle~aVzYiZOo}8`tmW85c5Fp2@+_nCt?_bG2WSbTrk+?bI@OoYlX* zD4e(k7$k=4pa8TA{Ewqb`yX*o80uAAweM9`elKU zkrArv2RxtZxqS^f@7P*nqFe>)FyN_}A)0%5JQ&eHzUCdQo)2+ojN<9Y)ZqqNG{E-R z26h=H0;0NVkhBfxw3(Q)-CX)s&@uWUQQB<=oQc6;$F z@QjWNna1Ke)5W|%^s7QPCTZN(+Tu0=8cKce?FEScqTt&v{|0?V(6qdP>Z+WLr;qpQ zwTz8xum)6*=fYhaz_h{u(Lzuj8fN}WHzA<>bnAEEOl2S&Ng=X6WCM?Atm}9)513^Y zMl0<2t2hqJRw=B?9}FTkz@%xaI!uh!)n7&rEmliosG1abOj-)gHV(>8o=>Df{ED>y zx^upO*Zcs^BiOFh0@tCOUZT+MIh&4`ogn`dgXap4W4Ce)eBpDEAgrEVcp90$vR z22-eK`}NtpTdtUqQouJkE?_#1en_qWM6JfRgjk+q2K3m7P{HyBWp>bUBY?sMEI{Bb zYEzjk3P71#ME_+t@Zvt`s+D`r*`+ji13EaiwNL}b%Rtbi-TV9)sw$PkGLtRG3E7nkF6VhV#YD++5eD-+aidwWVJI1~H161;}?EL}@j`4C<>_W3VL6D18h18ECo z@+Ata!?i^~U$Zv4)z!|G?3ehxHeN(4{?dFE#f&OPp_BpZv*7a483Bq?6!56tTq)Ey z^SKE+8kp|_?m<(kN+g&@0(cZ`##k(HgW%Qk#HxOfo_&Rx`$Uo5scJPw?2OUXf5w_T zL@y)KRL=pO%!z0szcniYv^DAwmS$le7#`pOvoB&=HlULi@4{ZsU!*lTatPZ7%`GWP(1FrLrk2iMLM^8gG9!$8{wGeMS zIR?5a06Dnw>YwYN!&w3w7c}PCy!ve6Q$LMr0;_blx?|!G%$nJOIMJ7Sz$;G$_y9^S z0h3BuCXePomoBy&?sJ`JWyu%)7R94uBIa6TmFtEvs#ymYAc3v{hIxZqn;c+11K>Xf zW{fBsu-?ApTQ+6)RTTpRO_S=mvIj+(NGc>WAqvL$Y9)MB${f1TR_VvyFnF8acU168C6TM6p-J5F8a>(8o+8McotMw(gwh%Az z{?49To05ETWd_WTpA zD{Rl$F!$uOL_KAWNTd&czF%1x*aS0xoS|oJ-)rw&aUtlY;xMj7oQTWRKFu zm5EIC)A2;ayPe6~>Vl1VEY>(Zu>AT36}Bol&mAk-TlOGv!mN9|0%3h@edAB>@J-qk zkzs>{FLVsE*qG--;Y$n^i#OeNStC%)*@v4SO+EB03fSti8rgiSkh{bTRmC{>#IglW zoQRu~Vl0w59owdq5VF`>Brrzk;49jS)9&$0w>}kR^$?B zw6}a1VDSqTqC^T_b*ILXhvCsO(_}S#rs~{xKTv2AB7s->sh3S(*OsvAiBIoj=5EO9 z+&i(YW--gaB<5UgBhA%Mmy>#P%)ferH?V@=f5|Mf{{v=ahLYa=V^XEuKH;*`mgnnn zQ*JzX_XT~-ADsF}Bs^Z-%A%%oI~B=qC+H+-w5 z`C+H8(#3%t?{rU2U0jprz75fcOxqi5NmCkPw3vM9VO0$;p(uWlvJ>>8B=ImSnnl7? zzDhl>4X{IzJlg$=atDUY-|xvSoT*vn_9SCcTdc;<@t z!SfCJs)7mF!m!!xjb-Y%LA{+^9|^j>ypQg6Zl;4o71o-JI7ywHTP^Z8rjGZ5 zssJS~#hBOtT1aY30vZ*l^~FT%PU-wD$^z)WK$ptSUF!$bvk>YG#3aDi!Sr_4yq#-e zz?z}Hz)v7#>4VWj^L-DzfKt#V55$kVpP!tTw@F!46_j17g}82)PB6xbmI8%p4CqtB zXoLRF`1)edN(>1yQoe!|Fp!*57;CZ)Ea$OkeY0z57!WPSfY&U6)_fmv68IJ#(T}bG z6Y4C#LAx?Lb&6C|VW&%33w#7oU}*Df?~ToXBvLaaR6<;k zkWD9apw4kvB!eLwaoBH*+fHRGBVGj?znZFgtut5iGW^nIA^Hx))dH2WwXYWb6VoHx z>>uPUNn7!Dm&MoYApkQEwT=!XVeV&dqx zlj9WfaN?7QCZMNQ8ONrCM{aI0E`8`QC--+0S4JOmSLw5oDqGl)vFOZF8k?}2OKVf| zQW@p_<{#wI_5W4(o>5J$YumPKp|a2gEWw5dC{m;=y@P^E3n)krpaLQtLX&O*6&t;m zh*CsIP$2YTrw62kUZi)Wh0c4;fNSryzx_Pp8{_@;`pba{&Y8^ny03Dc$L+iIU581e zadUWSpS8l0{W$tdB8MxU?+3|l@yN79icWBKn@~rGO;G`3g-fgk>sgh(h868c!kAZ| zMV>?nY7Cpn_jH9}P^p#o>r+19bbUs(!%5735i4fC{MntOxowQXo2_~nYr!pn2lDw& z7y6HW_5~ZLTca1Z5d{D)Y*HyZA=Z&naAi{M?+-wieUfRr)-lAUj$9 zx0U*RhAUd~MVT&CJR|Y8Df1ggD@?h1yEGr*Wdu9o=pv=I^z|3go9(mtr~I)CG1rr3 z_urP&ZNl`rt(ZOOpkZ4NRwsGKtM=T%Qhx~MOjwg8kc7k5m{@()%ChsutTx|2sUe4ksr!RM|ZnKmZ`Zb4pF{7K8W;@C@n8K=*4roLkFi z8cL${V30-=piiA74+~)&lG()P&z{No_P@W|3}vO<2JG@lrW=*T&9q;MH0@3|!JeTI z7pawR-~RRk|FjOM1ogKlvd;!+uAw)2kzq+Z=Y7ynsJ|z7+7pkH<>tY7QMd|L3hU-U z5$h%neSe!y=$Y1a`Z$zKi|cP8LmV$3Q}1ap{VnLrSbF*RZLV19`-7etr4@##AEQ)l zOJJB#A4jFW973~PKGX?1-}(|?Xq&P+NtKA%cee14&%^I2T7?#btydT_%p%l*hT+%1 z5h>foe=^DY6lPYy*d&cRG10)!%b>?5JySQ+y?EyBaJp7Z2amH&*VE=6n{jEIM2E9> zbHUs*i5rX|GYo=xy?wV{>V=s8Ema7WS0 znCP!%9kyU5y0zoJ$fQS8w~u5jGHMp&M`gGbF9x{%);8R8lh8~ku9qwm=%2w#``+rg zlrCdfiET8}k}T`ZMK={2C9vjqdye>o5zU0VqzKas9#lqa`3L%s2i6jBnrw-tM;79a zE0oz^oNXp#Z7fxcpkb1 z4 z!;dwgl6h=YKd`i+*-7A35q7}Iq|ZX03Jn>E_1AHhw1&eo#UEE>opF2wvdOWTwYSPs zeK}_~1s;u!y3ExU;oa_d^L1}vaF>klP-47c+>zFN|E&zEit+uEe0cesnxF*!;`}1!nJr?GkA*J=9Xaz zldjl0oH$ny`u2HEK`*bW(qYq+)7X+rZ+5retotIC;=IR~mt2^&_MLl0rbR+8S1ek8 zuV@s*ZypL4F(zK=uKuNOgwO?wQR}#dGl7$LvJ#{_r2VTMxYGh!tb5u$d@B7T9HVD* zZ>B$WF)mQSS{d*5c~i@s8F8!IaJBn|md&`>mUh&av?adJ$;vawQ#R#M4<|38IycZKUo0hb-{Gn)`BLcbq5M4v-{*W&X=3`!91 z`O4F=AM4@0l`Cd*imcn}_+=_uL40deKk4L8$=uec_&0}t)c={%?K_8Fd-Gd^l19*j zCaIsJ9)VdsiA|ji2TG&Hi?O`x4R=zosn^(7JQ-rw1Q*G^G3?8Zu@x#w4ZE~`9WTr! zK~rY*{r>FJBRHT>7@W84f6d8|X|{!yQvYgf=B%}RVK(F9U4I&S zr4fcB)w*ph4lCyB+8qo9-P$-m!i%m)JjSZ{0>5z0%L95vt=aN#4(Mp}nwT|7l-XAt zS6d?Y+i4H{)YGn<&Fs~DzFRlP?Htvk4V3(rN(Jk2FB#RKu|(m~u2z~+g+PXa$hU-x z&xSAR7v0@;L#_ImN892CCTW5LbClhSPTLcEab21tYxKEs3g&Hq#`;aexxnnJn*B!Q z){NmY70WX}7;^@(ECZyX`WI_w$F1Dr`Hcwm^Ya+AIL_$g!-df@Bm1J2v`!jt#<5_b zB@B%qFCXW9u8Q;M{nhMWY9deuYW89N`Nm8ieq5L`N}Kn4bI^A$$2xycyTP#)@iCz= zNOX#4wSD_8UB0~)wdb$u`EhPqvL44Q6I6(%e{3p9DF;FWt`@vZ_rx!J|F{bx7+-ZP9_KL=mSOTA5)ICRad)vGU>RS39-}u{xYY$S}ES5ws$DWwN@xP zn&;>oTWZSgR_B$`?CI;=4BtH*q7<_F5f`Cl>SoXITK@KS?tggx8e^&TPmSOs;b$8 zInHP{Pn%`Zb=ste>tyqh{i$>HMusAaFU8NE^U7!`effH*Xv!udZN5y4j!Q5a#Vd+G zd4#&BBMjr48diN={pnCuyxBe4^uuaHc+1t9bhV#Wig*T0^@Y2+E}`qPK`p+~oon)L zO>>l0rRASdQLw!+&nvyzl6ji@2{t+0-Mo7Q5CT<#x<050D)b_w*8vU?8BJ z;vGXQaS<8mq;X?hL&V@wsFymEfcRWZMlGvCPNs27vJ43}7EgoLTLK0Lt+U6^2!t?j zsuf20kEcd!Xf1;bYSaiZl1)mwHOgA~!{DG!=GBF#LvJv_vZT$&0pkQ=d}VVR>FNFG zb1DoKE`fE&dkt;$E83p^)!RTSePww`CF;B<=fhad_yq0Kj_x9fPwOrWz0C9prhbU+ zejNR&OT1d4Z9y~k+pFvS!bgK}84JdCUvKt#D{AZg_Mr%OCRla2ijT{KoqLHjBEsjc zr0lpeowgS?tx}%D<9TA&{;lAHJPa;DqW;NGT5{%iy)Azh_BOql!8LgDn+@}@1kfM&CUqwBb8!ROu9fy}8RUue`17NKp7REx#tCb7>CEYLefS8RTx59UjC zt{1i%Q+Un_?zb=#7rkY-L-|?C6)6=LUv_@eODC!qtc4)GMm@TXY0}N_ENQ z(hGXbg___Hd9QI$s>pbArAJomaQ@NiSfL74>4@+p^CNo&?;m*0sekNLq6J@=7A9`I zN;TUhBy3Hz7_X%E`CukHN}4{J?PhS~Zw&kvahFPCi|e^8`E=jyjg#K2yxC!G@`*9WWuA-gTZE72q22jrbf1%i zo2@RwT@KBbMD&oaOV@4*sAC(f(nb7{WO?kpfBk?JOp=7bVfeNyPOSW#TGI{aLgL+6 zr6YVkj=)UHO`yW2mA82?7aSw{Tleg@|CmWCJ9Ap;lA}fQEkQttA@`d^HE()eMN0KOVejDQ!8|k#amX?s^{aW9CH6z zTV4Q!oIesp2)n`4srTL4GW>}k&w-UIgU#c|Q>NtWt0rG)dkQouGNKD4Ciy@4qfdlW z%S9|iE+i{itnQVWO#C*Q{1$y>UfY)U>=ouU{f`x|XtszWc=pJeIDYiKy6CG>@nV#e zDe-MZ(4xyHoJ5?d@TO5(l8YI+c2nv4)z5UR58tTxC8hNF9_jUEOIp|{n6lgOc|Ifu z-Fe~>4%dNn*z%fQUU>4h3!1=nGCJ8HU&XsQbmiAC>`tS~l#1R0t1wKxV1(5_F$;2h z@X~!w%QfqQ!7A!7^uk zzP)H2nyNEK72>$qDfGp@!3CIH6|Gu86$Brj`R@VI}RO@fIDRdn*&TVbH`RWt(h%Elh zUOu%{*vJm{r89Z6T&>BzkTMiHCn3k1T|OT&_QKgHdg%#gJY%qgd4rO8QQ^oly_}xt z*K%RED=bTja?sz`PuA#Maj;3b{~8y~X-noo=0@Z@5JcnlCPyQP1l*!Mm(ub zG*dIu>9Y9t#{Ois<9eEI&S@0~!Qo1l^?8ns*^;5zwZ^8cz8pvoRUU7DL-a7M>(64~ z?y5K{NLA6t7dCx(d|stKz$|oLb@(uDXzvE6>)>ur=kB=(|7Wc^T2cOM=5Z6$X;`J4 zQc(1O>er%$Z57o>Qv17^N2b*`CwRo_HkZn)hpNA`2-M z&1kJBm&jmsK#n@2R7+$|`t?DxCn}Fa(VS}P&bF(Cc3u9GJgVUk97et$Yid9CLxYhp zS+{X`EThW@VeH5`>?@M6Wf;-p%&6NI0NhLsD?0|FPdSVG1p&*Bke)`Lk8B8(S4K+n&s# zqkNMJ$EMUza2>Y}tTa|lJjfZdPi65Y%17%N3sz8zyup53?uOg#vbu!j`zbSahr*W^ufe_ct-D&`~bu(lRD-4#X9#VXtZytcHZjP-m2A>0UIYj&u^3DXS#A z+Em$wVz~8*QPq?86$X#6c`GhFU-W+|d%r>H`yDI5(Jd-eH90c09sCi@9-CTqNY^J- zq}=dyb2MJ1FpNgQQA{YBy?hVx#X?!sfkQ5#Efu4C`>b*{oz2HQ(zxD5`w0d|9I3>K zIiElhpE}>@)iwEur^^LX{IH(4KQd|#*H>snu?32xpy`)S1cl|~jh^UD)^m~G=;0=e zF6G;mZ>e=5W&wTw0HAz7bdVXZoupg?`>quA=5Y8^DsARkZ(%* zXdRVAG{#58Dw5$DTUaHI`*x|Bb#SO`t7Eu#jdh>tieG=`9I=2ojN#QoiK>r5RH-__ z4aznqqidF%Svo5COkFiUmer8FNrfwi9aPi~f1X936nRJvbyuo5A}0n#>?x(0BGJID zJ6}}ryyPkuJ=Hq_eS;OV+ycdP(G5qWiQ%8Q6W*{{jC|f~%5ktAFR;MIVlk>g^#S$* ztQ@#5+K`}JeM!G_Wc$ha0lCx*3aF%E_`LZZ%%XaFeFe1W2cX`DrmanWB93({3^)@6Z^t_ znS5DuRNe_&;#{1@J~__~BnMz$U35#exufuyL!RgMtp`unF00Q-QftcOHZ2-mjMzNx z8YM3=wiW%n_Um|qTKaEy0LC=5-sG$(BLQ6K&>}T%N)*ob7oqR9<<2@DEz6MaAqO0rX zhHGoV*kZ~4ZX&-8VRo?7%PoX}VXaMh^B?0!4n!FisscLmtaG*6FCn=W_LxC4u6V=D z-V%CZTxx8{_)+YdfsG01zbIP`0c<+))OQgv6Zl~$F)aY;GAK?vV!Ji)j!p-2xcZDpphp?yrI75AU+FTp217nL`a z*8g@=Z$b4%`ABpnAHzsR;+Z~Ug);-ub%#!+nmjz4bH)FIor1b*stRco~)lP4?D!z|T>6_9|Q9Vlz!`nYUb~>`c$J9%Me(6F}fcdS?OQxPLo!?&} ze(KzU;gQ|Yu5sa;&L2HBHBV-=4$^uOrX#J7?&8*T7hF@^>*^^{CH77?Buz{9B#W_b z^o?^ld#;$5w@I4 zeKUe?Pgas{xK~%Lo!uG88Zh&6p&n|6Y-KW!xhxgh#k8v$(VEQc=UWJ=X3LM9J5VU0 zB*5HTtnGnxtFFtGUgVN*HF+SoB$qwWu&I&BZi}_y+c?Y?W`}xMldzRJ$rG5&PWEId z!d6&tc=U1ez1kFz5y3W`jDEHqts)>ZXz(fnVtSU3@xRbXTWgqDR-t*v+jP!Un9>M&4v;XRRs;`}A5cb!G?WWe=++McVSpW!VE})HYmW zjTdyL780+73T?Cph z;Q3Oge`E-Ij^!p{xB9WxhWmyikKgPRxQFGoE}d=i+4*qQ6|kqgkVM;sNoy?09L^Bg z_z~bRk)W>yvtITkj^n$OGv8J$?mF5Hw1R}z+vks*WRde~DZT=N6j$7J+X7k7ZnO7I z%#|J4^(%h%as6(OpFMM1gp9qzk%br~<56Slg&5EgC;FK4?#`&5^Q{K0^WV`R@>+w2 z^5wPu)GiGNHpCM`nnnA+@ckj})PHAEE;(-V+?OKMETPeS-$J=cKG+>%a4QzoVUV?h zat|YrJ^BIuPw#H8jf6b$yj(Mdv4mL?J<6)0_Y+)c zXP%X&=QJ5oNJA~*&S}_3qCtPim5;~DQK?zjU_6{H?xp`X9y*AlcP08?J zA&P_F7_wB5>#YR5jT5$1dvD)?DBQvGA0=oqVYGEfe|hh2=O*rliM3hAN3x!$H-O)L zrt={pnPg@2(mRsUmlHOi9y&X_dsn|5!}gpo^Z8_| z_Wa|IZRit{Gtk#kq=;B0MZRxE?rA=}x|ciC=~YWgAK#H4BF(mU^?)nLAemOC z_e$A)e}BVrq8@lSoWwo!6RPBlkFf2%v?^L2vK51ED71pB+4t|bG<_By)p3NH zD1GM}RB9IfQ`g7KZ@nTUkh-av<9Jdoz|&zuF#cP9=yU%ri+sXD!6qmnRdGfHjiFam zm!)t9@6Lm^931apdVITgJ;&O07aM!dAw)H=kv;&48g((9CZoHAopiC-$C*ZG-~@KDEj6g7ItD zhib| zBHJw6qzeY%GUF{8l6sVH*v}?;&wy4Q(fk6q;%unn9g!X(Zd`1PR@LE5yp@PZ8hIC z6gw~1JEAedi?Z+{joT4-Tb}WpA91rk1>&+M3zHZ2du#`$l#Hy;fAjpaclXQ96EbUM z)#%h9`%%A1>4aID)&=U`6+g%3`4O~fgZJs=8EQutE|*BI=I}0RIeO@P_1a5^7u9&1 zCcwMMuXC{$g1b(fvcxwTmM6;T?OpIT^%BKh8{w+f%Pf=an?1xN<6XLL#?0W-k36b8 zpZww3vwFJu`&v(qB^YoHCK2~IX$JA=U2t%0(&*gmO9^O@+(=NjQJ|aUua6TA;r-I> z&r!L8tomI6PyUUIWCOT;=(5&;zXg2#pXe2;K+S{V&@S_GW0G;t3Q`t#?BzdV;u;ES z#JAV)qcPQ-AjKI9y)-n6^%oDV0RN^MnC8Gl6T4a`(hyUHZ4*IU_o$&0|uDaB#xq$S!s4zg-Kt0l|IP>bnIOF>_Ddm1T@f5EsT9rD&JT#24AyR z(YBZx(w(eH816Z@?V-z~H_{<_D%_?$CaU59%n`;QBs)T|BaAC00CclJ_*2_fL=`rs zD@xG_31xlx=iGZL`WTfIP~gq=c=RD^91~Q6FANhw0uAb+qP^b{7+5N-MzAf>-AD~G zjptfNEafk&Y99s6AX+#W-4_I{9}+|xxX8r0pK<--!`~uAI93PbvxO%uuwNg0`yGkK$$Q0O5xEPQ@ zBydIm9w$_E8HDDZU^9XUW4U|bolAVwZKo*KF;X^`qCI5~mRpJ;n0@d8KnK2w3bcJ8 z6e9vVxOH+T>ZQl^=Lkue(_pyDS3A)Ttb-VU<+&kY%RU@J3-HN)k3@r+Nhk};2Abv` zG$FvY<@NQ*CvP`^+yq(28i<9U1Dm6`3$uieRJU%>2JF}``t6iyO;Tcj6QY}@!Bp|#>jFsjUCTs0 zjbTpA7$m#UsD!`UrXANPfS9OW8>-!!b4TDR3`|m(6fpziGl*KBPt_pzCd#n%_PZc$ z?yKj?pquaj!;Ko)GDy1mCWkPM!s(Z3OtL}iVMybi4laQbhC-f2zy}xxja}o_$MaWg zECKY3j#W11`}8k|jMe{atZ;b>qBPEEG`mT$>)B8P(oN8XfY&K5ty-=ICw7@Y%s{E{ zk+iKf_2_Za&eRhC!|%}fY|}FIqHS58gB=u$8XRy87i-Y7XJVn*GqYQpWCd_e8y66D zSqGs1q=zy#?k)8k28!Sr5b4=(AyVWyGRW>~VQp(1EFL-!wjea=2JHR_>jkvFvb{M6 z5ZSzLA4%N#yK+Z~M>c5M04)doeeuxjO=r--LkJ<*=<1h(mq)+sJIuOk8MS1uv-f#Y z%mqGq9G5VhlG3hY*COw|wVv(=GaXU+Mys^@SNP9zYFyhFHj6-lhdO9ly{Ak80f8|F zO?48~>Dc7$z-d23VYu9Aedf@SlM1@h+X#i=7qakm@{@x=q!TL|)xcY8|3pf7z`STL zKG=6LJXKmH)*grodfGxUEgY`!wm3UsH)y9Kon-fM&*s* zg(3^-IN^JTEF?@ze&w_B4cd^j>e-=NVbY*c=9(krS?k0~xuk&-+9r|4I~!~gMK<*| zA4##xe{uk6tF7Pq!>!-R&t+x+GzY?2^!)_Sad}%|*%&8=;$PSVl`IQHl@H!bXe_q% z`);pjrl9{0O}LC1IL`Ry!A!aDS_;grx#nneF$2)%eP`3uSqiK&pnY(Zc+84}0Nbm~ zgAEqpSo^zIXup+Vu6-s-B=yOU@QN1Y^2%OdQJJ%2!TntZ5~T8#5$0I1f(9uAJ%$q` z_+p{{v^|ROFHJ^D5?A2>Gcnh-h4DdNIp+pBvI-D<;9&u;c~s761WLF*ZuP(vJA~M> zb&Vyj(weAkBhK!K098=stmAo!n zuUf?E>n~ft8&f8~v7l3g_*D1-|Rhj4rlT{rUQe{rq3XxOL;j*;ecv@zGg z&4Q0BmM(LjHUhn7roNWf!WcjaI&!U|!LS-z1tZ6(Hebd%==|V{Gx950z3UuVG(no0 zQ=Z0F2l>5@Pf{s}V~5{NPNt5+nN%RTQUUh}&c*!6lPBT8d1_LY=K%xa2BI1Z`pj$J zSndn{KYjpWngS$~VuMzR6SucvH>2%An3BqOt)~az>j7U3Y{yYhSi}RJBRKb~19H`# z-{#Gm-6U;k$TL00h?$8!6auOlMQ0p@cK&im8$ucQaz2rm5S=;XwA6^ARXZG*JwQ7( zpfc}3RQ=;!1=&I8n=Qb|VhkTYsu#>OB;{m+Lyr*x5q-Ik>}KTlzR(HjIp_(u04Ga| znpuYjHC7H`4}Wg<{5P*cWIqd4*~a~RYz0<}{#;8YVDaW)XNW_#QyyC>n}tE^mT)8@q^-BuvEb8|`&mv` z2~J{uiXrPWFZObdg(@^g7B)d^L_s#en@)qD7JR0l$BVb~d<>>=HN;{%BxF|ZqfPOe zL+;F`C$%p=O2(kjDH&ir$Ev}PAr@*de9&)WQJ-Wg@AlF7;4iUy z6&#{R^ZpX6=V#?j`ORf>2usf(8xbuV|Ij59P{#tY3Xx@Q7?D~gO6#VWi3VvuXnuoM&>j*1W%*~)57CfHRv}Tt%2yUhJ2Gn~P|DkM|a7 zdHq@aZ8&kZfE0Rs)|19fa8Xt=S_?JLnvQQ)Z76f`Eb~vO^^V6k6#2j$xlh`90zJGv*$*V6dQ%OjOJi zPiFmAaZikeLqLjCE#i-5c`I9R>Db02MhMS>V7i>)sab$HjsLU;*Pg8}40ooUzjeRcRA3-DQQon7w8@3Jd?p`#or(mf=4ogeMxSYrXNQ*jnIiW%XhofyHPdwerRIy8m zo9pvhw&h3y7=@VgRE9vS8bSfnWl3j4k|+{d1v&39GNlSt0Sy7p^TY1WhY&%H*KC^a z;=$Bz$sWq1lU9Y2=mBOGk|RUXg5n5+&~HIq-sG)K?Vmfol#d{yu#j|d_718A?-=o9 zJ#)G#PJ9J=uLc?F^J`Ev41b_z6Ae`X7aAwxWt?kmbilQu8_qbLA% zZ_2p?Spec`cF<=dy*~3ybWx5ESg;|zH*Ems3K-`<2GCGU*(wOOcRS%s`4!Qs`ViYB z$RMEX9aYXQ2yZJRD42gtCZvF50-#M0q^c-OZTtIp`V#_;VRl@@x8pH%cV>Ml)c>PN zjn6Pp$cMlHmrERVY~q=@1elbp!|HZgOS@c`Y(F-3%xc`=MV*$3CVkEV)ag7_ne!W+ zP*x(E9g;Lu{?%7!r4#C7>u4`hKXh^U6sw|}y!63439JzyYy{P5H#e%+E3lK=Bt5q; zwobQqz8~sd6D+Vp@_^-7(l)MfI{ir5rQfI3-=?WLjmk?iPEsy=7h>Am{@Z_Gk`ces zWDTXs&4BPDp0dhyD&HL!)&#@{XctxiDg%9q3|)s4F$mp_!uEMr{<|3^R3df78|%0P z1SDFsA2G&22@0eS2(c=k9;lL^E=_mjRw{40u2A@E?D{5dkrX;H17M&a@zprk4*Jck zwf3~pFNRbS2L&?TI-56bAYx~uMJszFx^t5aT$d)7Cfq;47YQfa0Sb40+>;rkD?uOU z;Ss5YRQMLVSz<3-EkF#X$KCBA`=L;*RZ>8sM9G2yXw*76^RyKhX6CK*bcn}-2V%Z( zD3S=F*U-Q)vzT1n4sgo%qV8Rdn^nm^R?Okra28O;5Fv+4X3N3)idaCQ0a65K1wk2| z!(dbWtvCztUC)2)S+MTS()bFzUW`2B)ageuKP(iLTxo;v8n)7%Z#92m6J^%uhjEx zzqT~fGs(O5;wObo#

+V%~WU5o=Afn!@(1on>&AF%a?agma<70PhDBbg2LEUU?1j zYgw7-58!#vayg^{y{(}j?j*>SA$J%;(C1ffa~?rTcarBA4AKz*3HWIN`K^!ZM-Z4u z2!f&^kY0XS5!nIQL%{-GGST6sE|}-oXSzwQ*aCoAlG5lRY2FE8DySf!Aq?2tVyh~R zG3SCm817Y8=N}Uz{Jp`_?i3WCoB`Xde_o=DGI2YX`}+!H0I2|@03tQi5@PRSPFD6x~H?HW#`j_g{F8gQgU}Z#A6? zh@BuzY{M7)iyMH`0T~qZMu%a>0|=};(z8pY(1y5yaE+DO;jqF`gp~b@c`YgPzksj- zUT9RG4~G2}2vNWsn2fd&Fi3~k%C&Zy{OG_b3m~9@|I^KM+n}`$Hm|vFm)O8b2(>kW z9cK*G#|%Iu&07+Sfw*35^V(|zGMqW!m_dk#3bKu~Y`^-bq=0L7X}YUEA~;H^DnTkY z$S1gtjRH-8{mvtj?nhJDf$GRhjSTb%OeM&N0(f9C6PlIp21k>2x+V)`r%~WY+{48% zIqC$KFfN7;pk-<#NPbhk5gBt7S+hQQ#{)NVSs$53Pj%!%Pe}M=QCzLpEQP2!mq>!H zcAxSMmWCe#p8&J5JQ!S3V|Ghm4038Pj+-}`=UPAO1sg_O6&vUFo~U^7AB4r^NFJSw zK<8v*47|jc4|OLYXdQv@;8XemL~$BA8DgQ1in#zw`=C6)3EV7b7WBQhsYVcdVk)r+ zQOu8~8?eMRz^z7cKvH_F==)^>K6>mOZ9v^c4hPVPkQX&HhTR^p_p8Lt_sPGGT}J@!I|2G1n7zxGlQq^f zcc5^IKP|fPcw@g%>9v(_ z>hdc?jEpNpb&%+33?T^*Vr~W`NJbC^c$xwf1H92EWJccF(t4}{@S_k4XL?F3=Z31e z=2+%|GXPy|0Be^J?KcJ62Z#jlLqkq_?epXg!&4+< z%yo#Elw>tf4`{~YPy+8TOPZ*~Tn`-jyV6lcX0D|7#t@D%oJ{JGyqpl2fRlmb;z-*B zn2J`+;(u->t-!;Sim;^^Y0fKGw)7wm0+;GO=30hefu<}zr03Aur=UHcgb z5QWULx8a-!0U+>#+x#Y=SG+~992dk*cHxXAAWZ)xp8NJOdGsd4GOjtToh&)w+5gPX zNr>WfisGvJ1EKGtZw~~*H^G&e`}rfFJWiK+EeZqcbPuj*4LWMT@x*zo!UhqCwAE;t z#jBvH1s3nX{YPqGK;yt}MnjF$ia(C)@`7LoJy&0H4}LWd?B3x}+{VH|1^3$am{Q^! zY(4|Lj3E%h5pOUMM&cl@8e5@EaQ4PXA8G}r$-xwE96Mk!om!9S0TwfivhGrlLRoD8 z#mQ!yM6@xOj*QF=vx5bo{f`0qLL3r^uY<`{8(4PGZZch5-n7?p25igzg)R5TOfIQBz8G=8fZAKoVUu5XnA7t&W-$% znc`ZpKa6Y`ilxWmM9z+w5E8AV*Ouil+Y@qrGglu=e~UygE2iY&Ah{y z?`VYMdP+Pbu8alDK$?eB*w^lQrx@YaR>3ta!ZZvHn)>!pd2^xDb*8%mIz%<%{|3VP zpGsIjTZhBQBLmFZ%7|U8u2Y8_#)iL<;=|GiW`u=1J$YB}g!^6SD=N+X>R5;n=sPch zu^v5H7tS3Ff)kY~1pWT_$rG39d1&X?g~=Nc-xsYz&2Zxvf4osr3KqS`bn_v7^mVU$ z%^U9Jmx8x@ApJhdv^}RsamigkG7F)4p4uW%(9KSXciN^(5)7^{@UU$_-V6IB<*<^f zJ|M91BU8646SwY>V(m&dmb!*1%q{2>U1q6W~Z08G~G>J9Qt>GD8;|feG6F zC7P|$0-#!;=^qFFB(%NUXwMwkx5JTrAFH?n#)mQ4Kaq_|gHRA~f-OVyN^Y%nz$EN6 zcrvo1EG(zoWGfW_>b0JLSqVg=jx0I1g>P=7t9hvrZP~PW*&it92FUp4DF=Blm1G5> zCh29!S88J=qe+(*6E}Kc8xzk>d;fdlLzt`<=7%<|ec%%#^?9?F=B22=Aa~Sz({HCk z34AJJNrSN0a=_=Id8MoHtW(e6HB;Y3UD8_FqFXe-;r9tGRI|}Lh;V9lkcYf5^qx4# zr&mXiw}&V4OxeIV>;&(9Y1? zoaD^DE>o{@&RmOYuu3i8lckIyt*dL2hk1GEd@Xq8rW0;jU-7PAe)Cht!Wlwj04^+~2Q5teA zpX-W(d)4{u7>!Y+9SCozxu0g}0ce>xoYD*cLr@fQ}=-xl|HVROHHE>wtvtYx&b z5)z7%sD@aPbVCNp1@(8s`3O53>OTtSSj|ZfJk<|kTYFM^_RpU`+wu_J$A3Asdz+Ow z_6y(44m)Bv>{g)p`7ft+uorY=o@Dw>frBjtyl*gf`x_5G$+t%75h~-$S8bT&yz-#m zjDd9ogCzm07pY8kP;5tl83NK<(a1KPYLw!SDg3^9HOhFx*uG+AT^51extb{z;n# z>6#vcWEj*aZWM<5`Q~HAM)cxRaiwl_{o-&0lyy@|5HKy=rzh0d!Aq;Nm!1`hQ|PCu zB4bdbJ55rj=0G^$kXVydsWWoNra5VqGu2L^Zy+k*!K?0={Q{?cA`@U01f!Ja|c?h*C}qlt@N`q>*aRH8?v;0BT9N3NUw~ zgX$Hbr<|o8UN4TiY6h)tn9Kk*2jSzx&@fD!dVb#s&`CmpNlaAEP#^OezvfICunE!h zP!ONp@KRy7iK~=@61tDwu1}+S(!nPB;VRCk^%z=!QZjQTxV@0249|d$137}rEB`;< zj-T*o&D0059s)0+?EgDmHN~$`SL_6jf1L7y;4gc__9KHYoBoSU2nR*%suJ?GFTycS zl~D3Pi^2yGj&O()oF&+(O+%R)XFo@_KU739q)*|C@cBXm8cs#ZGACF|1u{F9epB8Q zwj%PwXj~+8cC^ZPrXM*d3?d_}SfE(rbN)2aG>7;DJ+LUZDE2BK4(T2trMdaeBH;Ix zXmsN+LHRr;&mHH7dcOq4UKN7KpfS7}d=wt!BNiIPLZJba*$Jl1b3<QZ zvBOsZ6K#VbM^ofxT?jNwpk{?SU=G>hPRk;uGk&C8=DD;J#}TgPuP(R_^bB}|35YEl^VuHSaW8}@Z zWsnfzJKyoRA*T!IXvsk{0>Zc|(xQNF{{94*v-SFtO;*6@gs31$`IM{?#uDt1Op0E) zjqIpACdGLaV8}RcY-5h4dJ*i)s3Aw_0|+BWJ_JSZ>Z&1d0H{v0Tan@`0%K&nil7~T zDFXiW)G5>a4>$YYH?@E32LCE3|KmuE{~zb{{MYUB|Ha=t9@kh8NA<++JS}(T8=&J| zf7Rm0-x*d)xQfC;+(>|+*1*n-6u&-dXDoKV5xrYzXW^%45k-5{1Vh?)j^cEZuYUB< z^pob8*Ap^VfezEV!JQX6<*Uvn+)~Ciy3O$KaHzoM8ve8@_(5VLs+w*r2RV^%{jm;GBZsW&Xf6jmNR}e~whx19U z4=a}yH7Pa|J$WM2!uH>FCpxsjL8BtI&r;`NO$%N*bJri-xg_NRaN-xwrS^`i1l^)F z;YN*_!cn!_>2?Q-*tNt(B&tWYZv5-T*`U(Oyddn%tkD?YfMNEy867E-Z#Es^fS>9} z>CsK)G`mSo^XuBg{{4xLrKBDPS;Vd3^V6~!BKi}FR`Y`9S`WiU!uD(S(srr#H0_zM z+E0p(p4>N*H|tLB(Z zZhGQ;Daz9<(nUJvEn{)b^Tk$~X*+jek`yl6eO_=79b7MkD?PjO{uJF89B)KACZ@<- z4$~tEqdq8n$2}Bv_(TAH15%UAAH^?EC8SSzijU^aecgG_Up#jiGFK-O-NhZhx5anU zF3H>HUu*ur5#LDYcp`bE)q2#&3L{=LWd9;9p_#Y+m(oXB`-QU2i_e+4oY8f(EmOO* zo7z`w=D*%eIh~w2Wj$&OuU17T>MiA!J?(L<{MY+Zq7`ZM9Orb+s5l)H=ck4f>NUqY zH)`M}oKGCk8rvIpzI;{ zcQNuDRMbvv)Lnw)x1PDHekA~(f4N!n*h7~yHEX6jw|IGAsgiJ|?JIHJdAU-fGVp!vi3gz?^5>4qz9?nds5`CtR{KST8hvE)rPA$@ckm$h z=If@}l}#K;w5q&o8tHOu`z^Z=9_9q$&~fkD6l>YKc$w#?dVt)5Pu*2i_Cq50k*<-`iG> z&B%^sVl=ycuiwvgfyTtUGpaj}<>A_!gyww3`JGpukh>k8c{l7Gk)$~Pds%1cyM3ZU zF$cL_Bj*Kr3v7?SR_OMGTi+%M?o#wp6Qr3;%pX*&l^o4bti46oQi8@bB{b^Zy)jxk z6s6@Ll|Hok>o*Jh&Z%2ApWyt~`Vb?dd0O}HWtZlYddb|}Spg0wdJ8y@JQT6tFRHaC ze!E+;YgecRw*eKW5f!JU?ptf)*PBik_>*m2i1gyPur52yudg=bz&%dWviWJr#<>qs zDBL5s)&ilcQxP>iJ6Cz<(Y`1j+Q>rMR_tMGwJ~WA_C}j~IBCw>op|>?_Au}D%rN!N zq@Mu}XOi`zJL^M#?1ZL}1KM#uDAYX(0^Aj_ zo<06k8Ba2dZrpkQom=4tV5lWX)8iDnyz{faXzy{_iB-m4sYV|%HwCk(?B$)`@F?#o z(K+ec-zNy~8jyMQtCO~C*T-Mm|9^nU|L^yu*C*z-rr0crAu4nCkV{d$ps9>Mf9>A? E0Y9V@%K!iX literal 0 HcmV?d00001 From f61c2fbdc29588c207d52d851b37fe4d69424f4a Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Thu, 6 Jul 2023 15:00:02 +0200 Subject: [PATCH 08/10] H5p cookbook --- book/_toc.yml | 2 +- book/cookbook/h5p.md | 31 ++++++++++ book/images/Truss1.svg | 135 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 book/cookbook/h5p.md create mode 100644 book/images/Truss1.svg diff --git a/book/_toc.yml b/book/_toc.yml index f04c1ac..abe8715 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -26,4 +26,4 @@ parts: sections: - file: cookbook/jupyterlite/configuration - file: cookbook/jupyterlite/including-jupyterlite - + - file: cookbook/h5p.md diff --git a/book/cookbook/h5p.md b/book/cookbook/h5p.md new file mode 100644 index 0000000..234252e --- /dev/null +++ b/book/cookbook/h5p.md @@ -0,0 +1,31 @@ +# adding interactive h5p elements + +## Instruction +H5p elements are interactive HTML-blocks which can be imbeded in a Jupyter Book using an iframe. H5p element can be created in the [TU Delft portal on the H5p website](https://tudelft.h5p.com/content) (sign in via Brightspace to H5p required first). The iframe code can be copied at Edit - Publish - Public - Embed code. This html code can be directly added to your markdown file: + +```html + +``` + +A full list of all available interactive elements is available on the website of [H5p](https://h5p.org/content-types-and-applications), these include among others: +- Multiple choice questions +- Fill in the blanks +- Drag and drop +- Interactive video +- Image hotspot + +More information on H5p: [Teaching Support - Educational Tools - H5P](https://www.tudelft.nl/teaching-support/educational-tools/h5p) + +## Example +Truss structures are modelled as rigid bars (so elements which cannot deform) connected by hinges (so elements can rotate with respect to one each other). In our model, hinges are indicate with a circle, and bars with a line. For example, the structure you've seen in the second example (with two diagonal bars removed) is modelled as follows: + +```{figure} ../images/Truss1.svg +:name: truss structure + +Bars and hinges in truss structure +``` + +Now that you've been introduced to truss structures, answer the following question: + + + \ No newline at end of file diff --git a/book/images/Truss1.svg b/book/images/Truss1.svg new file mode 100644 index 0000000..e9b2179 --- /dev/null +++ b/book/images/Truss1.svg @@ -0,0 +1,135 @@ + + + + + + + + + + Pagina-1 + + + Vakwerk, 1 pt.16 + + + + Vakwerk, 1 pt.17 + + + + Vakwerk, 1 pt.18 + + + + Vakwerk, 1 pt.19 + + + + Vakwerk, 1 pt.20 + + + + Vakwerk, 1 pt.14 + + + + Vakwerk, 1 pt.15 + + + + Vakwerk, 1 pt.12 + + + + Vakwerk, 1 pt.13 + + + + Vakwerk, 1 pt + + + + Vakwerk, 1 pt.2 + + + + Scharnier + + + + Scharnier.4 + + + + Scharnier.5 + + + + Scharnier.6 + + + + Scharnier.7 + + + + Scharnier.8 + + + + Scharnier.9 + + + + Scharnier.10 + + + + Blad.21 + + + + Blad.22 + + + + Blad.23 + + + + Blad.24 + + + + Blad.25 + hinges + + + + hinges + + Blad.26 + bars + + + + bars + + From 75f902e5e3816b62b63ac2cfb07cc8da305691d9 Mon Sep 17 00:00:00 2001 From: Robert Lanzafame Date: Tue, 11 Jul 2023 17:04:35 +0200 Subject: [PATCH 09/10] add local server instructions --- book/cookbook/grasple.md | 8 +++++++- .../jupyterlite/including-jupyterlite.md | 5 +++++ .../jupyter-book-setup.md | 20 ++++++++++++++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/book/cookbook/grasple.md b/book/cookbook/grasple.md index 19d27ae..1a598a3 100644 --- a/book/cookbook/grasple.md +++ b/book/cookbook/grasple.md @@ -7,7 +7,13 @@ The embed link is created for an exercise under 'More'- 'Embed Exercise' -This iframe can be embedded into your Jupyter book. Remark: it doesn't display locally in VScode or in the build file, only on the hosted version. The code shown above gives: +This iframe can be embedded into your Jupyter book. + +```{admonition} Note +:class: tip +This feature doesn't display in a book that is viewed locally via your browser, unless you set up a local webserver (instructions [here](setup-local-server)). +``` +The code shown above gives: More information on Grasple and the support of TU Delft can be found on: [Teaching Support - Educational Tools - Grasple](https://www.tudelft.nl/en/teaching-support/educational-tools/grasple) diff --git a/book/cookbook/jupyterlite/including-jupyterlite.md b/book/cookbook/jupyterlite/including-jupyterlite.md index 0d00108..6e3f569 100644 --- a/book/cookbook/jupyterlite/including-jupyterlite.md +++ b/book/cookbook/jupyterlite/including-jupyterlite.md @@ -9,6 +9,11 @@ There are three different `JupyterLite` directives that you can include in your Below are examples demonstrating how to include each variant. Note that the `jupyterlite-sphinx extension` is designed for use with `.rst` files (Restructured Text). Luckily, `MyST` provides a convenient directive that allows us to include Restructured Text content in a regular `.md` file. +```{admonition} Note +:class: tip +This feature doesn't display in a book that is viewed locally via your browser, unless you set up a local webserver (instructions [here](setup-local-server)). +``` + ## `retrolite` To embed a Jupyter Notebook environment in your book, include the following directive: diff --git a/book/installation-and-setup/jupyter-book-setup.md b/book/installation-and-setup/jupyter-book-setup.md index b9d7326..50e4247 100644 --- a/book/installation-and-setup/jupyter-book-setup.md +++ b/book/installation-and-setup/jupyter-book-setup.md @@ -4,4 +4,22 @@ Jupyter Book is just a regular Python package, so it can be installed by using ` pip install jupyter-book -Nevertheless, it's always a good idea make a fresh `conda` environment when starting a new project. \ No newline at end of file +Nevertheless, it's always a good idea make a fresh `conda` environment when starting a new project. + +## View the book locally + +Once the build process is completed successfully, you will see the file location in your terminal output. Simply open this in the browser (you may have to copy/paste). + +```{admonition} Tip +:class: tip, dropdown +Bookmark the (local) file location for easy access! +``` +(setup-local-server)= +## View the book using a local webserver + +Some features like JupyterLite and Grasple only work when a webserver serves the HTML content for a book. Rather than building the book in your repository and updating the website on the internet, you can use a local webserver to view the book: +1. Start a server from the command line with: `python -m http.server -b 127.0.0.1` (add ` &` if you want to keep using the terminal for other tasks). +2. Port 8000 is usually used by default, but depending on your OS it will tell you in the output. +3. To visit your site, just enter the address in your web browser, followed by a colon, and then the port number. By default, that would be: `127.0.0.1:8000`. +4. You will get a website that looks like a file browser, to visit your site just navigate to `book/_build/html/`. +5. The JupyterLite consoles or Grasple iframe exercises should now work as well. From 66eadfa8c7042e12c0dbce8975fda3c65687f670 Mon Sep 17 00:00:00 2001 From: Tom van Woudenberg Date: Mon, 17 Jul 2023 16:01:51 +0200 Subject: [PATCH 10/10] Added capital A to title --- book/cookbook/h5p.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/cookbook/h5p.md b/book/cookbook/h5p.md index 234252e..8ae0bfd 100644 --- a/book/cookbook/h5p.md +++ b/book/cookbook/h5p.md @@ -1,4 +1,4 @@ -# adding interactive h5p elements +# Adding interactive h5p elements ## Instruction H5p elements are interactive HTML-blocks which can be imbeded in a Jupyter Book using an iframe. H5p element can be created in the [TU Delft portal on the H5p website](https://tudelft.h5p.com/content) (sign in via Brightspace to H5p required first). The iframe code can be copied at Edit - Publish - Public - Embed code. This html code can be directly added to your markdown file: