diff --git a/Les02-OpenCode/Les02-Bijlage-B-Huiswerkopdracht.md b/Les02-OpenCode/Les02-Huiswerk.md similarity index 100% rename from Les02-OpenCode/Les02-Bijlage-B-Huiswerkopdracht.md rename to Les02-OpenCode/Les02-Huiswerk.md diff --git a/Les02-OpenCode/Les02-Huiswerk.pdf b/Les02-OpenCode/Les02-Huiswerk.pdf new file mode 100644 index 0000000..33554ae --- /dev/null +++ b/Les02-OpenCode/Les02-Huiswerk.pdf @@ -0,0 +1,149 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R /F5 6 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/BaseFont /Symbol /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/BaseFont /ZapfDingbats /Name /F5 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/Contents 14 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 13 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/Contents 15 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 13 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +9 0 obj +<< +/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 13 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 13 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/PageMode /UseNone /Pages 13 0 R /Type /Catalog +>> +endobj +12 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Huiswerk) /Trapped /False +>> +endobj +13 0 obj +<< +/Count 4 /Kids [ 7 0 R 8 0 R 9 0 R 10 0 R ] /Type /Pages +>> +endobj +14 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1891 +>> +stream +Gb!;d>>s9G'RnZ;36`-$Pg*M[m>@eG&e[f/#e8*c_olLB7Tbrj=b?;'pT3es@:Nt`MENk\G0bWpflQu?$n/hlq)OrH*"Lo_0a#F(E!sl9/e#J0a+r@\24BK0Y:B&!*TJ'Pbmb(4?7/5rFto\Y'O6/VLm6&TN86.!#.t;u-B.+T^T7^BX9dfWZN1@lZN/A;Q,uKBK;luOCMMk(A7RTq!ud?2H=/f+#IJdCq6V13h4`rjL,m,D,t-UUXCaX"TrKPt^3\*A$4J/;ft+@F;V&Op.m5n["5QH^@+8;agY-92[^"7#(\($l9q:N_[WWMs!P/s>UEZ0BZd&9S28>*"9GLO'^GQZqHD_Qn$kH6.5WKt4f,YMB1[ZicUUho-tUq,h7>JgiUDTLs/S0Q=SB+I7Z"i:ds3.r(V:HS0l_%n;VS0K,1`4+HV5ZI-9iCU3$3N1bul92#81"ra@7=aY_cjjhS^LPak>AJlehN%QBg`/r9EY!%kYJAF93*0Z%Nmf((b`'ilIVaJoq`7H$NUU\K__f#epWNLlqo`3S_D"K8=XdYq*fch1TJ$f7F:)/ZPNcM>-kJ_QiUcCSIi;drhLtV]CD#Vac(AYsXj#]?$JgkLb7)pb!o"I'e]mQO8\#T^$G/n@mO1.$J#BDB4&eulr;1#Je0"i67ZS]nhP89;NHG.e2S09q1kgj`aA'+3b$#\";24]ujQ.\[+2C_dhhL/81FV4OmXoh(2T_-s&F&=&@`mR[M-TQh42oeF8se*6pMQg?D3X\uD!;FVoR%*/Hj`"5"a'0,e'N#sB_6tPa!16rI)HeJG,'+m,%NDE[srPKb?`2%meI7%X*t,JiA?3d:-:MU/3nnL7]@9N<_1HBM9.mQ\qqjGi%RG#2@\\cWc_iXKM=%TnI0-kbu0M6UmHNs8R$i]30,nr;X;qF$9#+0&OrPpZPu;Ji[n[kj7F51k(DpSYr@_#NYd@lZ_rR#^Uuf.FE-m+klH1E(*8BL<<.9""VgKjT=08BqAdd]u$^^&U5k7/'Nou[Sn20^54cXp0""iqFRf_\S.8%SdfX$Ha#fi=;k09?J"m6uP$mr.~>endstream +endobj +15 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1477 +>> +stream +Gb!Sm>?BfT&:X@TeG,iG)Uk8&"lIg8#C"2B%dOc]9i?_cONr#1G\2F'FqP@>!J03S:6aKnL/`SDqYg%f"n)4i9]E9OJ":0_,,7nHAk^8#t3d^no=k'31F2;kugM'Nh>#+ku.c*h7odm:8>6G#^[fW0&$]#N#XT5<1chE8,$K:OH*WaIYCd2<8"iU'8DrH/cngHAqRH8a$C]=;f^7^/2ZFhnQ"1*Fp@HJM>Ct+ABLKQNTI2=q334QMI\:V/J0b=.Z-Le3>)"oh/.J;Zd$N@sU-8Ir2#b;!<5*lUgKJJTjSo=M0KshAO5GNP)V;1TCU`ATWKR;ar"^GBWZNA`j`qAK"?!XU-W.JDY6(fkSR+rd6'@aLm#g*Qd)d!F;jH<8KG?;/=2HKbijZT\O8E&/c8Ac@A\UI_Z#2+(_BU_b+;-8qL$pG@!p;"##]8W7Wr8ce9Kq.uBDGNY2O6GEnnZOC.a-SF,ifeW+cRF;6f2"7L_R[1lkN^I1gatj4'K=_dATEJ62(8I%Za?th[a<3Io1SFFDAT"(rJ466ngmI.R3+C'8')Gl7&Y6p_ur9)*e-h&8>T%Xc0$e#n.>IPM/`8_ec=E/95,"uf0@Jq'sCCOlI4W:c,D-e.1qm=Vo*j37\V>IaHkk'"'FSK2KjiFNG:FW`ZmlX23u[^-8VGLidP?C)AIpHBQh9!2eXiin?s/@Ve34A8l0F:RV0DEDi227efk9)KPhU>[mrgVC.d7MbjN\WXE',A=ru;3aBh!640SVocTHsf<$sk`rn7ltXOPgk+gQ\+ZPQD^KP!V>B_*/IJK^m^+mT7EjFR_NX)a@eTSpNN&e7o)/s";_&Wp?h>n5nuLET'5QeMf$Nfcq3m*ef`,G'`[T*n$3t^e\RZagJc-O8Sk4c=#Q-Z'K!U1FS@A8dI`:1`1UWa=e/_,[Wl9/@%;/#cTbsTGWPIL2O#&'e)!WCn%efl,^:$d^~>endstream +endobj +16 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2024 +>> +stream +Gb!#\>?BQ=&:Vs/R,s1u*/#WqA7"to/M+S4g8=LNf`rl?NY:+;au4'Cp:'M3:2D9YP-D`)&dXVr\^*2jU0urG#YpdU*V%WQ0C,)1IMN4Q)Hqa;-a)aMUrbTNSmLh]YVop-j))\T/'Qlf8s.*Ds]9D]Qap75[]u\0g+4Z4CB2h8jCZZ?mI1GS8Q^/Q?L'[;t.rR4_G;ON8=+rME"c$4P'^'s^g8kM@,l0.VE52YXf'H-bf02L;KSY"E35HIBM87g(HE@KKI/@hjiI[I1R%rKu>:q;5b/-.7HP\;@*et1oj*3>cXh@QYDg/D'>(]Li6)l73^6UJVPr,IQ$UQ0JPgt+j@pu!7HGYq[LKNCWXBNQ9!SL[5d4ZbH_!E$=E-;&)&nm79H9"X%=no33a>"^k0'8bVupBZn"\IqiV@9Wl9=GXcAe!nJYp"o1fOkPBD>ge#*"d4I?Ol4>j;GB%R[Ec9`&f6)3VlJ-:fd%r@a12IjD>XVa3u7B/&-_^GS_,pF.!atbW1%M/*oU`,B#8e9g/rr1s9qmVcmkANPT*2[bF*Fr&I\)Lf`C4_rD7a)$GL'BMChD-/:0H3gGi"Mo[bT8s\pfs?6:!at]$].pjg_j]VGM4b**;M+8o(a2%;8PErhMPcCWX!"FKm8qe4f1;+]^mC.8@QB#kA`b3.MDi(KQi_(>qsr8_>a6DG_8le;2rHr^:)\i5V[MP6H=6tF?<[bRn,7."bPVEl90?>Z_+A6eWh(p9Af30HRkR!Y^V=D=kPhFSQZN[(q'ioE0&q0b&`]4c2fPO*fFQMcInf`\=B>FM^;YieSZ*]KIdNhgsibdcjX"QM2G$`m/ZG:eH5in?S&,MIqc.r;OiYL6HJ$O0XGuNUuH])f%IldYtXd2B8=0EBs)RFdiM[VUsd^+NG[g07i%(1\83(>)JPeV"Dfk*4L,*[l7`s^9$`MO?N2Y"[(qn7X&>d&.<3F^=@Am"e;bTobU:ffHfi`=XiM0`bIh=H]EcJ=%[,uur'MWm=]L_WC\-V6!OlNkGp,EgON8C2bNcO9oXJrEj/h(@I8kK/<7SH/Cu53SOUfVn#s3_p6@2_ViX@[c^Bf`2-@X,X`9][F4:-/`pN4GDI4-s1qs!h$S.R9s5INF71eK78Y@>1l?F3Bo0tNW"Bq,AC1Ui9@k'LW`J5`&2:-,;B[q8IEW[^mP;'fTeg6u8o6P_>ZDQuQOW;I/ht#Ne3"IS=_U_iWestYXLFm`$Ibf/>"uP!Xo<_R[_SC#2Q4T!W7VuVIc*JbdU+pDendstream +endobj +17 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1152 +>> +stream +Gb!krgMYb*&:O:Sbe?*V/gEt&7HJ+.1eeu5kQS$S^A(.*)4?U\WY4]nrVDO,[cKLB>%nRbYeJ25.*e>=B.g"Bh(r^'oh@h15;d4Q1OY$RGAE(DOtVK?ji7h2m5-![7[M9Mcp$.)sf9p3VJ)0"PZ5k<+.%^VqQMGTl#t3eZ16cknr4>>cE@*[;0f"!=6@%,ZR0HikUWaDs=#-A0'M+fBAhA(M1JoaP0JQ-;oSM_g1W+aR-KkSRm$&fs$KY0kWpQ!\*b2HE#]M:+,_NeL7G_ED-)7TfEq_pIGL;_L'DC(Zt>"Eu*,H9XmLBsnunV$#BOE8d4VWK'%-i38HIkO+`?@o0TP*LZO)_p$s7c[iC`YQAFhU_dmL4!.b`-Ls_+MZXa`p[W$7fTn\Hb$!m9.\j+C3S[,$PjDhV^bRHcc>KmiLdd/*4WkKEnEE5%K<.pbB'X7;/?Y.[h0^s`[PM=+p>f+H<3rEW[o=o0endstream +endobj +xref +0 18 +0000000000 65535 f +0000000061 00000 n +0000000132 00000 n +0000000239 00000 n +0000000351 00000 n +0000000456 00000 n +0000000533 00000 n +0000000616 00000 n +0000000821 00000 n +0000001026 00000 n +0000001231 00000 n +0000001437 00000 n +0000001507 00000 n +0000001793 00000 n +0000001872 00000 n +0000003855 00000 n +0000005424 00000 n +0000007540 00000 n +trailer +<< +/ID +[<6c12062d6887b7f1fec7c33b3fc62987><6c12062d6887b7f1fec7c33b3fc62987>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 12 0 R +/Root 11 0 R +/Size 18 +>> +startxref +8784 +%%EOF diff --git a/Les02-OpenCode/Les02-Bijlage-A-Lesopdracht.md b/Les02-OpenCode/Les02-Lesopdracht.md similarity index 100% rename from Les02-OpenCode/Les02-Bijlage-A-Lesopdracht.md rename to Les02-OpenCode/Les02-Lesopdracht.md diff --git a/Les02-OpenCode/Les02-Lesopdracht.pdf b/Les02-OpenCode/Les02-Lesopdracht.pdf new file mode 100644 index 0000000..7e1199b --- /dev/null +++ b/Les02-OpenCode/Les02-Lesopdracht.pdf @@ -0,0 +1,168 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R /F5 6 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /ZapfDingbats /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/BaseFont /Symbol /Name /F5 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/Contents 15 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +9 0 obj +<< +/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/PageMode /UseNone /Pages 14 0 R /Type /Catalog +>> +endobj +13 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Lesopdracht) /Trapped /False +>> +endobj +14 0 obj +<< +/Count 5 /Kids [ 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R ] /Type /Pages +>> +endobj +15 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1699 +>> +stream +GauHL>Beg[%"?g3^gl)h0YE2Xq5n@s[QE;ko=C:$W",<pYAt/^CUqM?H+n^dl0K.)&gT^/tK-cf+5R!TPm6$nNYIb[89VoAE8,\DfQ65_PgTi]n^Hrh-b-16@BlLdqj^e\pY_6GnU6OTCL>Zt:3`$_O$q%#@q`Rh1Ba;AjV]?P(1:WXakb.b`e;iA1sM6r\pO@CH1a$s0[Y-neSRKJKMQbh$h)f:.i)i+7@IbJe=iVsnn1fYq\2=.F&Np'NG==.A=k>A\P]-@P?q^I$8(qY^qm[kf'Y<`B.a*0VTd@d//$u3)I,'*J@V)I\i.c+IGi,KZWb5;\8V9rW&,+o2d`V47upYf^=l@Raj&!enZ\3Se/#)?m/`1T%1cZUp;UsN^e44f-(.SXhCO1J=tR@eK-qgl64cd5u:m?RXUm7s#oOtjk#_a;3dM_I6$8`a8qm%7RX%cu+@",hC!0aM.1Br2%MTFiBE3nf4jOh@.`%54r?(W;l-,8,"Y0VDgtVs!l`KkFtbPZ=5R,pXAd`28>lTS\Z&"K]k!m]g]=WF$O]03Pc?DYRZb@!*o`G<42'RmmWD>=)6:4@!,hS:$r't"p?Mut.k"QDkGnHp/a(e2Lu\FUd!EKKaHcs4#lFjNQpdo##s)R\;Hpn0G<1QGOED$F-PlYjiYm7iJFZ*a"c,'2g<];T+S.n:k'2E#>!k/*Fb.c8%Jc%a"U/kg(YNE3D`Brp3+DZ3oje+TZ0R4$SClMkfKI'!FPSc3#PAThK*L=L")n;qNfAX+KZ9%6)sJ1:l4JKDiXN+0]^<6&FhWan'J>8&:+usW:0;Q;;]NrV*l;A87XJFDk:sXZ[)]c6n#bihG-0,/.hb8!S-:5$Yi"*A)425[rC50+)ibgQ9pFF6eY\k-S`.e0rJ<)rp";+(^R`rP/MaE3gJM$G&7"o"G(6Q(f[MIT@CZ-I(5=9s_r8Z:4N@GLO]4"":YWL.6=GMC0WNq5rWendstream +endobj +16 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1486 +>> +stream +Gb"/'D,]1Y&H8h>Z/q15[)]lE,l()fP'Y!,f;[5B3rU>i!t3;8.g]ndlaqA(:,9gsJgX8S_&ajBGIu2h55QN@;#E$EHb'@TE=@UI#)pIp*1.ua`c'e5Z1j#D\Di)3JV]DFL]`Keq17PBbJ71I76G#jdX["%";rs-L/A3rcNO=WT[7ZWgg`SN7>"D<$(7t`[;fLa`Asra`)eG"ID3N6)L)ik%6B/FIo.'N@#\#YWfVlh5O`*oKYb:p^RW+*r'Hb!H(Lr'W@IO^?GVBP>/-arEne&Rf8l<6P('mZ%T1\aiEAFScHMb9k(BnN;*fc2OCnO,TLquY`hV$1stD'KKDJ-*/G\j('J'171/)9Y'%BOS3.32iBFD7Yk2H;e1l,^W@(&J%X(L*#`;GMKDnKqm[8B=9lMVYI6oXs\_'Lh$Ck#,a)gC+HAhu8BU>YZ6]J1H7lrRW4ua8$OUc#J48%a-V5j@@Sj+2dLodL'#oh=c!YUWO1ToN`0Hs^Q+fPS7&-nFA3qkk("$]k,;.95OLR1'&T[^sR)O\'sJ8ld/o"U;p^Eb511)#_(8Dm"d\_g@jW4uQ2Ni6VsU2AE;A%':fW`I$T__e"*kr^W"TqIXe%reN,mmL7>HDAg/Use-`bQ^:.4ZJoBC;lKf(.\ri%$'Ls\le&c9QVm1ttdSUCs@TMg%U'X%Jmfp0nco_(,G0-Eh];GX@b4IopLT+"1\WnTr5f8iV8YIp'mU7VHfR8!5m,4/T%(/jX(M3q>cWnrM3?.6IDGP0Zo-qJA,AnZ>O&i#L]g=d.nm5VI?n6ri,,:um)a7Y93:7>^644X_,r5lM5]mLrbsD'@8$jK9uf#&2K];Z'f.;N#<+p8>lAb^BN$LA2]n/2fTBVEnH0,oPGup9HAk)tl&\MBR@>Wj>#>1E7I%\i4+n"t4fkJ_OtL"!%_8\PW3.RJPoSW[$4+6elc(!j?ZNkH3u37=J6Fs*;/%*Aba&EP-g4!?-#09D$aD2RWD]MTDlCqTk%(Q7pk"!T$&V/D1g~>endstream +endobj +17 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1760 +>> +stream +Gb!SlbBDVu&DcY&VE6(u@/pErd&SL5S>L:rUfOhML8GN=&g&Sp.>bgR"$Ri"Q7?(_EI)BaQm)g[>R^%*%`!VSLK4Al"Q76)c7Ttg%\q@c";*?!Jle_`?N\.kpOipm;:P+r&Do3lOA?*1\<9CTq[=23M"1ZS`J@F+!fl;'O*Qh&q##6LJ9[6'8cV`4PtKmPmh!T$\e`5Ldbc)&i)9iO:Lo(f@FedBL-8Wp.;RHGKJM/#@?eRsqYds/[D772K]8&Dhg+.1@m#eH.3BB:#@W0H:8*9iF,c#[%4C&EHYt9+W$DD0e3:YM.GZh&5!)O.S\:@2]7t3BenVMf-0dO:MN)j67\Zm;>:9n`oE8p$4j!r;QC0?B#tlV6J1MA6Au^$;+QpT6_XQj9(M3`8kMJ7qD^B%:=4kJ8>Nh$B&"VWJ7,UQ:mb]\;kY;5of4-4>f+1=Sk@*e]GWI^2NT(+C>dM(F#"neS2#3*cN*E67t86*U'`@u[Gm#54.?m&XCPCpOW;+GGZde$scO4ukjkh$T]'Bu`<;*nRPV^:;_cG.[lH[=AdfI#fQo1XA,gdUC(*9JPl!YbLW8MXp['>F"sDitlsT`gk3"in+n&]8/Z-,[4UdSE,[Tf28K)4nH=BFBW&noU+ed:@k8a^<`0r&[&;e5D2nr9<>>`[9duS?Oa4^,M^7]+-M3E]Xg#-D=Kk>C'JREC]Pmi("DQXW4#J]Y\alRN3meBL7uo",jq81AnW^&BW#\6bXUqm5D:$Z>MIsp6kN6D:Qjp&.dsP?L'Aurs`ac?L-?n'eNf-7.HTlS\WF<)d$`UNdCORhQaJ\0)2KDbGhjjqToj*2l?QVXSi*3WMQ*385u<9j0EcYFW5A(U>gEBMprr\OUDd-K7$QZK1T;:`6l4GT,FnNZkg,$a&p6-frjI];,u#BC)X1KC!]Q532sEc3\X=gY3<]-k2QeilMc&!8rn3j\tVi+BfP'OVa@e2O#N"0N?oJ-p0E>UlW[li/t/\MJ)@+AVU8'BR!^9[ppL*)P'I(0`fD]*N_28dd*hOERt[7?(X"@%bO^'"L'O7_RIcG675ra'Q?jkT>XpAM_CS?e=iqf]ekj[dBR^8Bfadt)@aaO,Fhl,.p#eXpj6U!pP>=4Mn\%%+iXD#!m;nf-!CAkendstream +endobj +18 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1590 +>> +stream +Gb!Sl>>s<8'Roe[38pPu1/f@F7lloXZHtXb?^aS6MZup:&)b]ZGUK\*VFt(*K\6OQ?5WbgVS]+HF%*=YoRj5f3Nlo8kTio'&VCoTq2AYH\bNg9%:)4#j09kR#brsAd7*c_]%X[86(\eXiHPL9,D)S2Y8te+&Q1tU%+uKmKF/WV8&B^Min-!3_iQRp=028'OALrjka?cp2p#fB8!)9jO?!`o$:fTpJJfJ=,n:r[amd.3g@VB@>,JU/Dfj4Z7@af5W;/Z%tW$7IC;:pi[FdD(THYjKU3&Z/eIb&JGT+cAiR^D:"P?mkEbm%8f%:4jP2t4)7R$H/3;*==FfiNa0Y9$"%5.aR%le(D5IUl^oLmVI]Xk.<8\9!\S$H$(/d+i_7DCr*N6_.;?P.P*ekMF)\+a\LLKDa:?]ogg&];b+:3R\$P9s%"C"QT?H,.H-ud)&)G0^kJ=54f#e$l)Ka*h$VTK-$]<+,ca?RB.r1b(G3HgSA(Md.HP?&r1f@ge'c<73JrMWVf:pIb^9f.m_&kh^2d4FbhYRD-\+<`X9uS!,/t'M,""9^B!PcsXDKNYMCU2-;Hod5MN%Wr#iCmqYA+q;uFH*Bn"[M>7"G3i^FnNSRaeg5bI1gY7_f<'tfT/dnPD:1"J"97e;?>Y7"o8c&gT/Yt7'DI.l!M*)VJHrQ1$)Eu<\CclK(j]Q`*Q?%&iCc,ULZoW%!l:2B%,n]f42ElEu5%2YGQp#a,5rWN)TH>mY&,*g\4kL?-0Va9%B0LWD4%=I#=32NOeOj+Th!.%-F>[dt5GfMAI#R*^=csOU2SC3.Q#:,DQH9U:+O,=gs.Y1%%MtL?4VAeD`KMi*+P3[E;HIg;iBD>b(*emM!N"c,#G\nS!p1[G`eFRLf,sL;pBGnfZ'`FUC2'X*ouo*/@Dqf:CD=3K]tnD!Nj&[k@b_MQZ"_,p-#;:^b:>/=iu4DKWf$okgb72BX@3em^B$0Vk`l~>endstream +endobj +19 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1324 +>> +stream +Gb!;c;/b2I&:W67\@9!P`fLm';L@(8Cr$1Kh26LB_m0MN523@hd?EXekc`l8Z=UYISN%&[,W6j9(@U\'n+b^1!2l/ss!KhBq%1h(":,=O#meKa%'STu@IRX>Um=J=^d?5^=9=Dujq#UK:dChENb'cWEl4tUTWDPP`YKie1I`30&LMDu!R,4pX9*!&UohA?5@dqiEiiH>Fo:q3FaUV(04oMN*JN1[aV`hWet@>iTjh7p-A#Y9K+EH:?c)8\MH)G'5(gW9&sHH-2c:Q=G6u%D/S9HgjVo&^@JI9NY[^X$S40,,qaRcno#l%;H:*1nBj*KPG)UgE/8hP&\IQl;P1bXAb'oObd3\JOlTQp2WcZM?t%"BFI$C8dhM8tTg)F3+L"N4&$cn+Z=kfaHiu.r1gnp;hPKfN$Kk$K@1E""_uaA#"^T)5/*'SIG0@/Jd920_7:;?L5&2fM0.9_<*BUEpN%%ORLY1!-/sucS3?"WhOLE`CULh_.*X!?P),D:LQCU93Y<.#PQ!.,(@Qr=.X7g?61P,"hOOI:*471DO1ue?AESLp5:$o,kB\nr'[b(q24!Mr`)KpNp`4&ZR7P_?B)dSbHOT/.jIdLi0*P6@>4[I\K3mI-p8md;;>is3endstream +endobj +xref +0 20 +0000000000 65535 f +0000000061 00000 n +0000000132 00000 n +0000000239 00000 n +0000000351 00000 n +0000000434 00000 n +0000000539 00000 n +0000000616 00000 n +0000000821 00000 n +0000001026 00000 n +0000001231 00000 n +0000001437 00000 n +0000001643 00000 n +0000001713 00000 n +0000002002 00000 n +0000002088 00000 n +0000003879 00000 n +0000005457 00000 n +0000007309 00000 n +0000008991 00000 n +trailer +<< +/ID +[] +% ReportLab generated PDF document -- digest (opensource) + +/Info 13 0 R +/Root 12 0 R +/Size 20 +>> +startxref +10407 +%%EOF diff --git a/Les02-OpenCode/Les02-Lesstof.md b/Les02-OpenCode/Les02-Lesstof.md new file mode 100644 index 0000000..985542f --- /dev/null +++ b/Les02-OpenCode/Les02-Lesstof.md @@ -0,0 +1,332 @@ +# Les 2 β€” Lesstof +## OpenCode β€” AI Code Assistants in de terminal + +**Vak:** AI Fundamentals +**Opleiding:** NOVI Hogeschool Utrecht +**Vorige les:** Les 1 β€” Introductie AI + LLMs +**Volgende les:** Les 3 β€” Cursor Basics + +--- + +## Inhoud + +1. [Het idee β€” AI als pair-programmer](#1-het-idee--ai-als-pair-programmer) +2. [Wat is OpenCode](#2-wat-is-opencode) +3. [OpenCode vs Cursor vs Claude Code](#3-opencode-vs-cursor-vs-claude-code) +4. [Installatie + setup](#4-installatie--setup) +5. [Basis-workflow in OpenCode](#5-basis-workflow-in-opencode) +6. [AGENTS.md β€” context geven](#6-agentsmd--context-geven) +7. [Plan mode vs Act mode](#7-plan-mode-vs-act-mode) +8. [Slim werken β€” context-management](#8-slim-werken--context-management) +9. [Limitaties + valkuilen](#9-limitaties--valkuilen) +10. [Productie-workflow tips](#10-productie-workflow-tips) + +--- + +## 1. Het idee β€” AI als pair-programmer + +In Les 1 zag je hoe AI je kan helpen prototypes maken (v0.dev β†’ website in 10 minuten). Vandaag een ander gebruik van AI: **in je terminal, naast je code, als pair-programmer**. + +Dit type AI-tool noemt men een **coding agent**. Verschil met chat-AI: + +- Chat-AI (ChatGPT): typ prompt β†’ antwoord in browser. Jij implementeert handmatig. +- Coding agent: typ prompt β†’ AI **bewerkt direct je files**, runt commando's, ziet errors, fixt zelf. + +OpenCode is zo'n coding agent β€” open-source, in je terminal, werkt met elk model (OpenAI, Anthropic, Gemini, lokale modellen). + +--- + +## 2. Wat is OpenCode + +**OpenCode** is een open-source CLI coding agent. GeΓ―nstalleerd via npm, je runt 'm in je project-folder en chat met AI die direct in je codebase werkt. + +### Kernfeatures + +- **Multi-model** β€” kies OpenAI, Anthropic, Google, OpenRouter, Ollama (local) +- **Tool calling** β€” AI kan files lezen/schrijven, terminal commands runnen, tests draaien +- **AGENTS.md** β€” een markdown-file in je repo die AI als project-context gebruikt +- **Plan mode** β€” AI maakt eerst een plan voor je akkoord geeft (veiliger) +- **Open-source** β€” gratis, audit-baar, geen vendor lock-in + +### Wat krijg je niet (vs. paid tools) + +- Geen visuele editor zoals Cursor +- Geen IDE-integratie (werkt in terminal) +- Geen background agents zoals Cursor's cloud agents + +Voor: developers die in terminal werken, willen experimenteren met models, of geen subscription willen. + +--- + +## 3. OpenCode vs Cursor vs Claude Code + +Drie populaire coding-agents in 2025. Allemaal anders. + +| | OpenCode | Cursor | Claude Code | +|---|----------|--------|-------------| +| **Type** | CLI (terminal) | Full IDE (VS Code fork) | CLI (terminal) | +| **Cost** | Gratis (API-cost zelf) | $20/mnd Pro | $20/mnd Pro | +| **Model** | Elk (provider keuze) | Cursor's models + own keys | Alleen Claude | +| **Best voor** | Backend, scripts, experimenteren | Frontend, IDE-flow, leerlingen | Diepere code-tasks, agents | +| **Curve** | Steiler β€” terminal | Vlakker β€” IDE | Steiler β€” terminal | + +**In deze leerlijn:** +- Les 2: OpenCode (begrijpen wat een coding agent doet, terminal-flow) +- Les 3: Cursor (full IDE-ervaring) +- Later: combineer beide naar smaak + +Veel pro-devs gebruiken **beide** β€” Cursor voor IDE-werk, OpenCode/Claude Code voor swift terminal-tasks. + +--- + +## 4. Installatie + setup + +### Installeren + +EΓ©n command: + +```bash +npm install -g opencode-ai +``` + +Of via brew: +```bash +brew install opencode-ai/tap/opencode +``` + +### API key + +OpenCode heeft een model nodig. Twee opties: + +**Optie A β€” OpenRouter** (aanbevolen voor leerlingen) +- Account op openrouter.ai +- $5 credit toevoegen β€” werkt met alle modellen, prepaid +- EΓ©n key voor OpenAI, Anthropic, Google, etc. + +**Optie B β€” Direct provider** +- OpenAI key, Anthropic key, etc. β€” directe billing + +### Configureren + +```bash +opencode auth login +# kies provider, plak key +``` + +Of via env: +```bash +export OPENROUTER_API_KEY=sk-or-v1-... +``` + +### Starten + +In je project-folder: + +```bash +cd ~/projects/mijn-app +opencode +``` + +Terminal opent een chat-interface. Type je vraag. + +--- + +## 5. Basis-workflow in OpenCode + +### Workflow 1 β€” Quick file edit + +``` +[opencode] > Voeg een README.md toe met basic install instructions + +AI: [maakt README.md aan] +Je accepteert. +``` + +### Workflow 2 β€” Multi-file feature + +``` +[opencode] > Voeg een /about pagina toe in Next.js. Match de styling + van de homepage. + +AI: [leest app/page.tsx voor stijl, maakt app/about/page.tsx] +Diff getoond. Je accepteert per file. +``` + +### Workflow 3 β€” Bug fix + +``` +[opencode] > De Send button werkt niet. Console toont een TypeError. + +AI: [leest console output, vindt de bug, fixt 'm] +``` + +### Slash commands + +- `/init` β€” genereer AGENTS.md voor dit project +- `/clear` β€” clear conversation history +- `/model` β€” switch tussen models +- `/plan` β€” toggle plan mode + +### Approval-flow + +OpenCode vraagt approval voor: +- File-edits (per file, diff zichtbaar) +- Terminal commands (per command) + +Goeie gewoonte: lees diff voordat je accepteert. + +--- + +## 6. AGENTS.md β€” context geven + +**AGENTS.md** = een markdown file in je project-root die AI gebruikt als "project context". Vergelijkbaar met `.cursorrules` (Cursor) of `CLAUDE.md` (Claude Code). + +### Wat zet je erin? + +```markdown +# AGENTS.md + +## Project +- Naam: QuickPoll +- Stack: Next.js 16, TypeScript, Tailwind, Supabase +- Hosting: Vercel + +## Conventies +- Use Tailwind classes, geen CSS-files +- Server Components by default, "use client" alleen waar nodig +- Maak geen comments tenzij gevraagd +- Run `pnpm lint` na elke file-edit + +## Belangrijke files +- `app/` β€” Next.js App Router pages +- `lib/supabase.ts` β€” DB client +- `types/database.ts` β€” generated DB types +``` + +### Effect + +AI gebruikt deze context bij elke prompt. Geen "ik gebruik Next.js met App Router" herhalen β€” AI weet het al. + +### Best practice + +Genereer eerst met `/init`, edit daarna handmatig. Hou 'm tussen 50-200 regels. + +--- + +## 7. Plan mode vs Act mode + +OpenCode heeft twee werkmodes. + +### Act mode (default) + +AI doet direct wat je vraagt. Snelle iteratie. Voor: kleine taken, je weet wat je wilt. + +### Plan mode + +AI maakt eerst een **plan** in tekst β€” welke files, welke wijzigingen, welke risk. Jij keurt af/goed. Pas daarna doet AI de wijzigingen. + +``` +[opencode] > /plan +[plan-mode] > Refactor /lib/auth.ts naar gebruik van Supabase auth + +AI Plan: +1. Lees lib/auth.ts huidige logic (~80 regels) +2. Vervang door @supabase/ssr client +3. Update import in 3 files: app/login, app/api, middleware +4. Genereer types via supabase gen types + +Akkoord? (y/n) +``` + +Voor: complexe refactors, onbekend gebied, code je niet wilt breken. + +**Vuistregel:** plan mode bij twijfel. Kost je 30 seconden extra, voorkomt uren herstelwerk. + +--- + +## 8. Slim werken β€” context-management + +AI heeft een **context window** β€” wat het tegelijk kan onthouden. Bij OpenCode meestal 128k-200k tokens. Voelt veel, maar in een groot project ben je er snel doorheen. + +### Tips + +**Start nieuwe sessie per feature** β€” `/clear` na elke voltooide feature voorkomt context-pollution. + +**Geef expliciet de juiste files** β€” AI hoeft niet je hele repo te lezen. "Werk in app/auth/login.tsx" is beter dan "fix de login". + +**Houd AGENTS.md compact** β€” meer is niet beter. AI leest dit bij elke prompt. + +**Skip large generated files** β€” node_modules, .next/, dist/. OpenCode doet dit by default maar check. + +### Wanneer crasht context + +- Mega-files (>5000 regels) +- Veel back-and-forth in één sessie (>50 berichten) +- Veel terminal-output (test-failures, log-dumps) + +Symptoom: AI vergeet eerdere instructies, hallucineert files die niet bestaan. β†’ `/clear`, herstart, kleinere scope. + +--- + +## 9. Limitaties + valkuilen + +### AI maakt fouten + +- Verzint imports die niet bestaan +- Gebruikt verouderde APIs (Next.js 14 syntax in een Next.js 16 project) +- Hallucineert function-signatures + +**Maatregel:** lint na elke change, draai tests, lees diff. + +### AI is overtuigd van fout + +Een fout antwoord klinkt soms net zo overtuigend als een goed. AI presenteert beide met evenveel zelfvertrouwen. + +**Maatregel:** vraag "weet je dit zeker?", "geef bronnen", "test dit met de runtime". + +### Over-engineering + +AI maakt soms te veel β€” wrapper-classes, abstracties, type-gymnastics. Voor productie OK, voor leren niet. + +**Maatregel:** "houd het simpel, kortste werkende versie". + +### Onveilige commands + +AI kan `rm -rf` voorstellen, of `git push --force`. Standaard moet je goedkeuren β€” maar dat is jouw veiligheidsmechanisme. + +**Maatregel:** lees commands voor accepteren. Bij twijfel: weiger. + +--- + +## 10. Productie-workflow tips + +### Tip 1 β€” Klein per commit + +AI kan een uur aan code in 10 minuten schrijven. Verleidelijk om alles tegelijk te doen. **Commit per logische eenheid** β€” kleinere PRs, makkelijker review, makkelijker rollback. + +### Tip 2 β€” Test direct + +"AI heeft het gemaakt, maar werkt het?" β€” runnen. Lint, build, unit tests. AI ziet eigen fouten via test-output en kan ze fixen β€” als je 'm de output geeft. + +### Tip 3 β€” Lees diffs + +Sla geen diffs over door snelheid. Aandachtig lezen voorkomt dat verkeerde wijzigingen in main belanden. + +### Tip 4 β€” AGENTS.md als living doc + +Update AGENTS.md als project evolueert. Nieuwe afspraken, nieuwe libraries, nieuwe gotchas β†’ erin. AI-output verbetert. + +### Tip 5 β€” Combineer met handmatig denken + +AI is sneller, maar jij snapt de business. Architectuurkeuzes, productdecisies, security-tradeoffs β€” daar ben jij verantwoordelijk. AI is een hulp, geen vervanger. + +--- + +## Bronnen + +- **OpenCode docs:** https://opencode.ai/docs +- **OpenCode GitHub:** https://github.com/sst/opencode +- **OpenRouter:** https://openrouter.ai +- **AGENTS.md spec:** https://github.com/openai/agents.md +- **Cursor rules vs AGENTS.md:** https://docs.cursor.com/context/rules +- **Anthropic β€” Building effective agents:** https://www.anthropic.com/research/building-effective-agents diff --git a/Les02-OpenCode/Les02-Lesstof.pdf b/Les02-OpenCode/Les02-Lesstof.pdf new file mode 100644 index 0000000..9ed7c9e --- /dev/null +++ b/Les02-OpenCode/Les02-Lesstof.pdf @@ -0,0 +1,200 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 7 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /Symbol /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +6 0 obj +<< +/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +7 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +8 0 obj +<< +/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +9 0 obj +<< +/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 15 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +13 0 obj +<< +/PageMode /UseNone /Pages 15 0 R /Type /Catalog +>> +endobj +14 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Lesstof) /Trapped /False +>> +endobj +15 0 obj +<< +/Count 7 /Kids [ 5 0 R 6 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R ] /Type /Pages +>> +endobj +16 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2096 +>> +stream +GauHL>BcPr&:XAWQuhtpBcBnp5X=5ToThYn?FJ_W_e'trTkK,q=QfN%+l%"EI>4:8O48Sk54eq8:lGQ5IC>-VZ?2*nE(r!b$]T+e?rNuT>QHSki^#rSGB;mQ4qnGaM8-'o+0>mP_$k,*jUko@/F!_]ANnC$A'r3L?!ZRqOdsr^D]tRHuAh4$W]MU*q6<%Nl;mRWEm^-4PUo``tt-46AsIC@@5Ru3^X9YK5/%[Y%:PXpL'N.d?h$QBCIpRMB\YRGliJ/-/t>I9?)?=3J7(c<[@K-W0]3PJak6H6-#tJ",+JgFf4Ds.!0oD3VaFbAJP=63;ALBXupZ(LW(9Kq4Zsoo/l1WE?(=*>i2SA[3]:J/7l(;rnP*<*9^*HP)=DLV1&*c7bO-)o(nt;jc^J=O)K16A<'q4"ot+Ns:gjQh@CC>WB>]0=FgctX<@19L,h1=f?jW*[C;q/=MmXL[("a/6a?bIU-F)rdHM4*C"4](iWffQgG">8Z3F]KFNE8pt@*/72.uK5+""oA%W]K1d9Rk^i?43$6F6CA#U1g@`jl1Y%[En?:/)K:Ia@s"FLZ6rK/$b,6^];ka3)4SjbpRF&lS&e[cfa_a?'d]@gGc,ep5Y_*MG%O$Gk8]4bd#G`W%9W<@JL!\"sJaO0(Fq@Q[n&B)a"KOHaX1]l];go*pQ`Kq)P2DZP@9;M2\Q\;h#);C@0]e9)5e_/Z48JO-bP6jX:9*k#kF!+cBUIeY.5T=2M/XQc762TfmNcB,:>CW(Ac;\bqj+O+8X)MEVtiocb@^q0-O]8bBqmtJcTib/S[K_RDPLkF-3RV1eFGN(YG7Y%/>>eBLjVjG/7CXSMV=`VM,+cfXIZIb>`4T[gK3M[o"nfb,!I28G'nNN8p7nJ._2&Q0DI%nln/^$S?72hR^\6FJ;DS5m5\Q*L#$5Z%fj\I3_>XLWko.#popoVP`6u2ldiE"EVXE[KK\>6jr)l,jeO)]Mq(ce^#5ZsPR:Z'0Y0Ad\bNH!@#I_&.H9]+sBRM_H!WVin1b(=!^%EK7Pk%;g\5Z95>ds_<$mAH-IJ\JhIH.nD8o4Z#ff[TJW0\`dcM,YZOZgo#YU1.'Pa.S_9auN7;GFmkKMIX/_W,JA/Y41OVi\Bk-,hLdEpQkEDXG^E[Lnq$p\HSk@38kVB5(A\\2_1qdD%=gdaHnBr1:(,;.bH(<75?OB@gVGLGWe&KL6Gendstream +endobj +17 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2092 +>> +stream +Gb!Sl=a/Rh'Roe[\.:_M,R%f$6okg(K+Gf4f20^QT^6NT_jWuho%UC:DRn3Rak&=C0Dp^T97AHY:9!5W`jDttLm9\pdm@/->X#7_T%ja)LPjLf>SKV3#!E'5jZ5@ui;'EIY?7Ah4t2n)dqP=L+>!e)&Aaff7k1ooLD[J[\VU/!!n1ojG']gXT*_+;kkG3Fe1_L%_[\EZ%k8aJiU`RN+*b_)eCuD/o?EU!'d8HYMJc>)[4G7u1._'gVU/J.USCH1FHd8oAUkV1]pomJbi$B=+3$F#ZRO6MbG50*ChUG0Q:mYlN/7fU0njG8G2]$D-o)*I;M[.%BeK0D)p@)k-P7$-ZJ)V0p^U"nR8eWp@YR\N[B,C^4>rooK*N`8dPq5eQG:ce:&0SpI]-t//f43"QQiqio&\q#m<=G`+E:K*]N\OrBnr$Iaj7"Wj3R4]FDZ@ga2WL!3NOA7IT57MLh1tmnMW\c.>Z\UhV4bZh"rIW;)XpG@W:%G0;N-Qc'2[ND@&k+pH42<$%l[`!XH6tW'#t@FrWXH*Lm#iU`bMYO/3"FQ,W_FR]*Q5\'C:gO"cJRhb/DTD,-QgFMa7*NCcn1qR0kG(]F2*&@bD\tMNqbQ^qm+0&/d#OZX3PdDn^&R*3L%SA">u0nJPs6<&l@bRJ'9k^mrCV8?<[(%du4p`GpNsFd.BN,.,"lOh%mBr)1-Vc3oB[cHq:/Z:D'\r'MWJ/q1$hIYi4GZZ?O?a`O=6MuZ#YW7"_ur#[IY?Xi)PNb;;,M_$?5_L0=\DfQ[B]VrS,4;f0[>a_UaV:[BN_\7jk*?j#dU]n@O-<5hLLiI=WJ:0eb3(4:E:n7m@hD1g:&5C'WsH$._Weh[`mS"k=%^WLp*+u?54:?!+HSmJ5\iH4'D\Fm@\[3j4G&464SYt;s0\%C>2*plE+)MC)Y=^%5^PQem0j#CTl9fd+car-SOED"FKs-h)=M`5h9.+b@;Um=)W^eQXu)"L>sN)MP@FcpM>s*>]W6P#oiF_ot!S.HbSH@^:bfK(lR^^/_jch=YB;un+/+<0(#W/e_W@RCok/dmAc1P'M5$631dgsd2KoUMqPQ192hH/ecW"gR[iP]O$ONBV4N'rpZZfB7q%no+'CAPCKGZT-Xn-p=KSb1hdaa$#pj.3r\F@j%J94ple].f1[a-2:ndO$%D!g:a(c2BmqrZUsf$A;=H"<2(n$A5V/^_E9BdrNN[2WAU*6?6BRMg9<3(1g]p_b,d\H95n+sGr>/oOX0`p=bKJ,BaB@:5_W;r"T5WObrfM$4W-qL&2h'6WIqMDL3;(boh0OPq)g\[q2gHr[DpG382%!4OlB1YaaOW-b?^Xp]N'TnMr9>rpJsFL6LdD^+I<>M[=J&#nrjgI1LMCZHpYnqVJ<[/+B".#[]u91A%_SpFJ(+uoE,Y[ff'~>endstream +endobj +18 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1500 +>> +stream +Gb"/'hf%7-&:W5:nJh#qGs/N,/<(@SuLn)NpT"r(FGr/@NR7g%tH0OPk),@H*/(qbL]JbQ'4\E$6b5^Z<)O95f;pBUNHb92m7L-0">W?PLP&=O356Ob$u.E*"^#"GdZ#"2%_ZiHh'+LU!nmhJD7`2=WgON8_/KNZ"9(d>d%5rD\k5q!+?!.u^?]KcA.&&6c%RE#tV;ts2M-Ctojagm"0+5WH?8aXa_Y@);YK@eC7bG^L@6]c'=kW:Sm(Nraq3K(mK(4k?uE/kg;/P*U/V77d3TE6qLq#n1^;io:5pB5P:Aq?9_*=)`FCgKMD)AS*[+(/uDgY!KsHSNT<[kY,0kN6n#K4lrp;CK,pYQS?SPO7:1XZ=CGbP)+1:m/2KAEi@RdLTFaZ(4XbD#!$#hN4i^e>5+@-jq=NZ+3mAG=qL(\qC;J*l?D?8l[?Y`_oTGl6`Zg)Q?@r"]aq%>sB!Lc'ZgM,P<(G@CY$+X1j8,.=T<_mZMmT.':Z9g&0k[%9/]-dZs1;f@?jg&V5&X&53/t8ojHo@H\;Gdpp1#S5:@QQE;.!\M]P0&H<]t$?J_'4`o.Q;Q5&0E;qHm+.BM17_K?0WBk>I8U4B\'[WC^mJ^c?[L2RMdq+'(!'LViOmAWfdL1iCJf*JE`&rdm1n1GaAm,48HFN6h@1*'WT;@c2[)lL!H*guP`)P$KNW2);)8&SfIn*7;q_7'!L:a^MWj^DTpHLXgs2)X&:V'2S=2f!781-tS3OAOKhqHA(OWPq\4(^CV>kCa?"SZ0[Yn\+elt>Fo]R)D]l0LEMB0`Rd'LK4]G&_DCe2ba\.N6mhE](5O2r',YWQ!oLrJ.lZ\s`$F#']EGAR[r!URSB/i]b)UW;6G@-Iu^c*EiUf+C8E'I:<)$>$1CJbiT)!SfPS\3;kNj^A*LIjMtVgs7g;We$412_)d72`tZ=o&h]#dC8q$2M"5#A.YHu$q:nbgr=#ig;u/B&f$;@6W:q>)a+Agi'n-6tW;g+6MhgeGG=gH"4&)la:,JI-?JK]eNA4ct'^mWSJ]Xf](0,"`lendstream +endobj +19 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1785 +>> +stream +Gb!#\gN)%,&:N/3m,Y!`a+aWaSsd%Ipl`4P9@GF8@34q-+,9c5`g*]0'-D/V&n\k]=6GaKY_JHrb$mf$APgepnKX)^-?o3MpMjJA.iHL]J3h&`E_AfUF2Uuc_Gm$Y#E$CUBP]NPl?uuRIT8eDn;Ep,fKeQ\3qFoDHQBOe[T4qV2.JQ%0YAaYH)FE;tMEFYnJGQeHAq=*kTV%k.IA5X=K84)ONGO\cZO"I`V7N7_nchN6L0'9W]7rmS$4u5aYQB6bi2R+1^&Sm(?!]P_2\r1TZs5LP4Rs)qfB.FqJ%SV]q%Vn/@o;;DS%Aj5seE55ul0uoP`5VtIZVAbPpl&e(6gt0jH;SL"k8bmRQ-$:U&&5tc.<5uoK"k'A:7e)@fbh(10G>?We%3VnW+qlhV*1kJV@-PWRko1ubOZ!O)Rm_p96"3N6T#89kkm0JS#,AWmbp^clM]P)E[K.n+TDnQ8g.pYl$RqnNTg3@/>Z;O]soQdTjaM&D*<&/pRpA70pt9Z[$9+.^`!dcpGKQ5lssWlR:F$VA#.^1o#W(G&0H)Ed.\q[I/aGE@1Zha_C4m%0Sg%sGW6TG8Lrj5\.M(qGN!6!7VJ]YG.&HZLAd';VraQ3pUcUDVqgCc[jLq:19II1CGnhdEP46=];Chi4knKC?A/bS8$-OoqX;s^9U`2>]=fHH!k6QkHhu\)Mk[9Q%r,EJ.)H!n)9h0U]6ekC:jDR@C6(]#Fq'$'2b/6//$[VrFZ/Z0]Z/qVjd^TIkA+/HF0g72T@F^Q9)CUb4aqQ>5tFP*.4.^H%f9N-)=pHrrZSh?%VRUJEe\o"YD[(Y8Qgi`n+q!6DuW>('%Xl[PZ+lY5D*hc_MPDA0t_q"J$dEQWD8:7%53#`$'7%M,[LF@6fZELKW"$\'Eh6>Q\N$$]ijC0RpV*eao@"5Ih^;i2:oL,bm5+&^p_Okmoka~>endstream +endobj +20 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1931 +>> +stream +Gb!#[968iG&AII3lo9bM)&iWB&gVm=lb(\<*@Fm.8NL@KKIBrMQ%\KNL]7!"pla\tVV5WC[3SCs(;#KC?QU+]I'Da_PQ=>^I+F*(8a!kGUE^Y@C(hKC+G_Yr.AdcofnKco-oanEclh`9@_cf*@")9c4Q3R6jTe?#I=+Xa*RV\_:3H9\%2l_Ti(]=bZ/6h5+McON\?s#]pRkO#Z&O-Q0I\n&qFCQhid#Bh1IMmP#p2<^4q%uhlP9u@WUCHta\I2i0YET/q7Vi5Z,U$f*!2l'k'O@s5H2oZ`:N5OVq"Jga3W%9h0.PATeK#f/d*+'ko_7fAh[Lmrj'(NJpoYE2rmkjJk\oLG8a5Wq31;V8:JUV`-Yt&)hnAb"Gm<&a_1p)6hu(QUPb5SfGWQklf%7["Tad>DTNQM`d?=BieB6BQu`71@GViSHGNTYk3_p!_*t'>a4YMq#b0,joX3qi`F?%@;4#g:Y70!u(JOiQ2]+0W`)LSOXK8X.%"T3QR1JqiQQMrj.C0cB"'DR<.8prK-gls\M5;+#7N9N+-$u03U#-=8a/V%B)AsD5WBEq]D:;kXDpd@5]+kO;^9DmY0[K9C<\6_!76A[rn``a1?.j+;9FnrT1W7pfYf)k`O#(Kl6Eit`iJ.ic)I"?T.=-[-%QRI^dWuE@S^8a9$HJb"D?7QXJU=rc%Lus`\KPe%6"K6o35a#B=V30o`i>(no6Cj*ST)W-Dre"R!I6)RbeDs[KF@\9""Z>n7gScQVS.44i#Z65[X#>)X4E@Z";i#iO>QdMt]>836jc.gYK4\n=_81@p#R"k6d/QWVk,c2l56q^!Wh4"#hj&mtTSY2g^qRgUV>phn-?]&ZlHh[-?l)[^N=QH!cFTqJs2160C5I=*8_V\/Am4ZBFq)NP>7`nTp:!5hi,-f.-p;?p@qrF_*fjAkA\*X:eZ[Q/3U,g4[h-E_"S";=K]^;qM$kgbfoa0lo^eIFhjZZ6MYfiNC"%V\L+4(fp!/A,%h7222jW;+!h\f-(/+[b7X`c+0dt3XUq6%-Udk'/AF&_@.G+S:0dr~>endstream +endobj +21 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2034 +>> +stream +Gb!SlgN)%,&:O:Sm-%#4-(9$TH"\R>dj1-8PHjDcGbtS*.gdU0YTRW4rq\6?q#r62&eK^s3-N=P7/"]Z7R$U0@n"d)!gfJtNLUS/K\>rA#HUd9O!5[Ia9f^3gj.b_6J&'/I4GT@n_NApp`]fYCkYN("LJ'#c"Mg;$u3JVk?GA.Muo@\d/S3.p(#s%'WZI2AIa3(L%/Ec\a,:6jZE5>0/8e>Wb4#rJB;kR^t,B3(f:Rtkk:kqYc>(#[@;PU.2NE0XUW!@#$3m>mLn*l$`th]IEHr$?tb%-#@W7':2!b7>?4GIrA,nQ$]&@kk'2TESf*Ho<7LuEQstdoJJ>"%P6!7-&2"Ls7h#itCR?TX_R]ni5=?mQK")2h"`sU>]*,SX"@9,77EJ7YJ'jdnM4kGkc3+gcfT]`n?LWjjjqbUrPr;H%)_-fC85K:mBuL9q8HEJ0cql7hE/psHQnM9I?,Eg5bO`WeKX#_e33q-Dma_09'SJ%o'RV,r[q-nli&'U#(i4l4OT^B4.?7iQ"A?!bTcXIZP/9,EDB3Q=gEb\0Q[D^%*-%hV$,\Os/!g$)3$\]jaMeWL%HI]A["AR"#ild>AAfJ,B3216Qg30n3YHK5uTsETM+pm]N0crZsQi\lYBW7.m6`K,M`["7SK]ko0Q,"@Pigcb,U==.?@Ud\u)8#e7J_G.6>gAeN&q^j(7,];<*j1K$c'1+$=YGl4?<%tr49oK>1^SOo--K*_eYgH-N_JiA-1AZ46`QMY9?E$^jfY'k>3W;VH!Y8=]4a#+j]"7/-Y=MQ;j5p5m7,4:%.g)GIfBX'[pB7AN;SBlh2m5G?:9>^S*1NIEJ&##Qb$],HD1Gh;$+[#f8@WQ]ZJh)VVC6R'm,[*^Y0r8qO>E.G2%tOuBh[q>9TU(g9s.gOM?-h2,^)9mi0?L72J/(B>Xid/1sB&r`m@gS4NFsiSblpo]@HaZ-A9KeXB7>e(WJ`Ll^>Wa[P?FZfBnE!XkI'A:TNY'n=mr\R18NMp4)Lh7L)5*NYONKjD:C[W7g/TVJOo3%-RRr"5B^"9GaYQT,g%X7QpXh"h$GWEC1DI+.0>n)`!NaB2\!)EK5)nE6KE/EoJE\.R:se1.6,3fKV(TD\&;.-ZHT(8eMWq"b_6LX$YThsf4FhbWGeN%7"6eBh&%phhRH21;E67[PVPK%Y3*g/9`flpX80q?`LbR944bp3meIAtus*n2:)6+W.2"74bf@cGXcg@cOE2mZERJC0WlN*8)]_q]Q[#\#49s'>rXK8RYAll%LJ,MgGRf7eSRsfY,UM:C1Z$KOB<&CrUmY0YnX1H$S<ne@U]8>=4`J,]s4P?BO5)5/!K"A5BWJmk(Y;4VRF!*4.L1Q72>..eYn"9RYJuH9+aV%9L9EUXK'KT_PT/eYiV7HY=fk4f7dUtk&L"@6Rq,68MeH'antch(=ei,1rR,m"!(8X[>Jq<[j6:^NDB)FVkWTihTo`078_k-)m$t'5g`]H_`Jk:$Z04.Rf~>endstream +endobj +22 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1789 +>> +stream +GauHKgN)%,&:O:Sm,Y!X`hI]*Q'Y7:ju.@'E30>CjRE<$1-cDZ\sMB0)^+i1TLL.-89c5J`jqH!&&F\Qs@M/ak=FANZ\-i(kE?rDD:e#)$f:/jQrt&.!FUT5P?4B'.6L@#ZK&@dr>^Ym7S'F!JsW85P)Z^@Q-kGE)J?He+gr^^kmK3>_c&ga5b)9S+okphUmZDd8?:e*uUgghBo5(eKAs=01mFU<%rRsiS-G=.qY`c\I^'7eIo4!L@;jK^n:)R03hp7)O/"SA-%nW`kd\_0MX'N38$6:M+VJZF@JI")6Xo'3sIk\K"Zljhh76t^6;$(8B;a#]aiE,n,8b]#`ZaLCP.`q.5`4V51D+D-(c>kU8h=dX$,p\qN&\]NrM6i`bK'J>]t^jQQ,^,JqA]d>_eh34TkW$sL;Q@!$kEe,n3p8VN6*%hJJo:01P,?7>D[KXHUVirB,\:3KkT($!eUuO3V$ET`&4SUI6/eVPe+m8$?u%1Do:`[`^j5g/7704UI8'cSh)_6Z4%\3P`#V[Hi\Q<(Bs2[2%lnZP[I(M5o<*=f\74(h"h1uf(34BnQ'P9k^8lj^iLOk-q3!)RcA?=jK^2Q)DlA-d@D6E#4`nm:O#6F/cC0caD7Hc[Ersmo0B%gh$N/6"b7l5[Nu.Bs%MJZ'EkP@Ghm+\79rCR`QI]H%4-^qA'#N[&/?n!"pN^o`&uEQ\M3>-HKeEeG\PWXSX))\`Jg!l1u=4pDb/(rZ8@B!VVpKIF\_&'>ZspVOMhmSot`F]Q;a)$:XE8ZqN&dlho.ZCV'5$OO&$qF:&!_]A`blpYG(2/*BYS?k(n_g:CT+UhQbSn>mjf1>h\@j4R;!iD-\)i/pU0,VCaImF(f@K6rV%H0uq9K-Te2+CFFjII`:!+0=,OeO.2FNeQ+V1FJ/.GIICXA1+hn&$:mIPKejD"$#G9oql"<6>tCgJU8kITl6_$Un#'*Qc_u+q)0"j=;H2BDHeP\lP_:$!bpuPeYG$O4Y[[5Z`KGBXIj_$(4Kbj)buF5qebdH)VogU9-!sN"P[X:WJ:d;Y7/jS;FR[(o,K56A$udN8Q;H$?]][qM&Qk_Fad2(BY.H&-T1UFjWpQ"l:^'meBW6iD."I?IQ2;%;!!OB9XSNAO"1S.J^45Cb$E*Ajr:WL#"l*G@_PJ>ubI9fJHJMP=%Hc,a_H23CDl%1PL&L6nc!KlbJJZ:$.c>06Ge6S2H$_GlcEd`bHjr23L9`X/?bC;$KRlAd1Fas\6.NUsSpcF^rhALgfR2MVEai2!&rHk,\qA@pcnF3'%LVDTHTC3p,W8U\XYCL;9:!r4fG?YS+GcIlUJQ)NTaDARh&+_d#;#eG5r2-:Bs.(^['t(<[o#EA8CTA.s69=+326_\)Lpt5[;cEih@k(FgXNHWpUXW?[@U%=n>n_+0$Hk(L+4_]3Ze*SL)EY]+ZT2blg\,]f+.*U=bJ%MA9>nQVAk0*XheFYn4#m>ln=n-%uVIUHi~>endstream +endobj +xref +0 23 +0000000000 65535 f +0000000061 00000 n +0000000122 00000 n +0000000229 00000 n +0000000341 00000 n +0000000418 00000 n +0000000623 00000 n +0000000828 00000 n +0000000933 00000 n +0000001138 00000 n +0000001343 00000 n +0000001549 00000 n +0000001755 00000 n +0000001961 00000 n +0000002031 00000 n +0000002316 00000 n +0000002415 00000 n +0000004603 00000 n +0000006787 00000 n +0000008379 00000 n +0000010256 00000 n +0000012279 00000 n +0000014405 00000 n +trailer +<< +/ID +[<073ba7643d43bab714be89d42b8b18e5><073ba7643d43bab714be89d42b8b18e5>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 14 0 R +/Root 13 0 R +/Size 23 +>> +startxref +16286 +%%EOF diff --git a/Les02-OpenCode/Les02-Slides.pdf b/Les02-OpenCode/Les02-Slides.pdf new file mode 100644 index 0000000..099c337 Binary files /dev/null and b/Les02-OpenCode/Les02-Slides.pdf differ diff --git a/Les02-OpenCode/Les02-Slides.pptx b/Les02-OpenCode/Les02-Slides.pptx new file mode 100644 index 0000000..fddd30b Binary files /dev/null and b/Les02-OpenCode/Les02-Slides.pptx differ diff --git a/Les03-Cursor-Basics/Les03-Bijlage-B-Huiswerkopdracht.md b/Les03-Cursor-Basics/Les03-Huiswerk.md similarity index 100% rename from Les03-Cursor-Basics/Les03-Bijlage-B-Huiswerkopdracht.md rename to Les03-Cursor-Basics/Les03-Huiswerk.md diff --git a/Les03-Cursor-Basics/Les03-Huiswerk.pdf b/Les03-Cursor-Basics/Les03-Huiswerk.pdf new file mode 100644 index 0000000..76ca434 --- /dev/null +++ b/Les03-Cursor-Basics/Les03-Huiswerk.pdf @@ -0,0 +1,225 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 7 0 R /F5 13 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 17 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +6 0 obj +<< +/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 17 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +7 0 obj +<< +/BaseFont /Symbol /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +8 0 obj +<< +/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 17 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +9 0 obj +<< +/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 17 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 17 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 23 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 17 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/Contents 24 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 17 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +13 0 obj +<< +/BaseFont /ZapfDingbats /Name /F5 /Subtype /Type1 /Type /Font +>> +endobj +14 0 obj +<< +/Contents 25 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 17 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +15 0 obj +<< +/PageMode /UseNone /Pages 17 0 R /Type /Catalog +>> +endobj +16 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Huiswerk) /Trapped /False +>> +endobj +17 0 obj +<< +/Count 8 /Kids [ 5 0 R 6 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 14 0 R ] /Type /Pages +>> +endobj +18 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1821 +>> +stream +Gau`T8TWWE'Ya0?]VCr6,?RJ:bcQlb`0iGrC*eX1/i8:'Zmefu.D+iJmfPLFX(A,!/ScL8]_-Uj),P^cjtiP1r&0,hk6r2_a]Djn$"5#_o_cdT.f+s0f)gU>nf;HW_8O^fC4K8"i"BZRCP8%YqY8m0Y)bV1WNlk1mEqi7F`m82p8:K0]d.EjcetC46tKD&W4O]:h)%oG7DcNPr'?6c@_/1YX1K1lC"IL758i\m.PX1DA=<2>R0Im_R/G,Fm"Phd9oA;2?#\n\NlM(iAui9nc($HS1mo:e-[E+`%Jl\<-+pS`Z?fdT6cj8h^F`/t#_/B'MgT.'e3Im]dGQDV*9P-So94)#F.&?IU>Fi$EK0,]egSDHUbQW9_!3k3@b@nfoDX,sM[rO0CRAU'M;-Cse,ksu#\#"A$/TOHYgpqOEb#\?3A\c6c`Ci_l&BZaT>(X\gq/6Z,Wj9<"i1OqZlmZFRmNX5X5sar?71#9m**6o]JXY4AiI%7N3R>k/;bA&S%i`Z;o,1ZDG5q3/BeK#__o/$ZUd\e\g>"(;\+.YQS?FLK*?Lt)oG2W)tp^*.s@!VXIDD-[ue5+F]hD)Bq:Xo,ia9jG_N^RlHRP]qE%'NoGpM(6%[K`<\R6!bfiFO=@`gY05Q0caS3];21p)olkcN#WSqGcoYeA^6K[k8Wr0GR@V4MB:GPr16ngAnR4M&Z9d5Er=E<>Vfd:$rt'ggs:C0r^7K^Mo<=M(A-)<+S.uPm09U$Jo`*&LVcTaqZ+:qu/f%D>c#0k)YGXP;4HF[Zlc'5kWgpIqf)c*,Q6K;cASSfbEf[.kG*Ba@4W-uJ"g`S2T>r-I#eoXendstream +endobj +19 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1764 +>> +stream +Gb"/'>Bedj&:WeDbZgXF=gY6[NRRU.EH1A&[2YTA*rJi;/@')sU8s"#aiT&$lll`E"p6#/H&1E%H*oa.q.<)1*;iY1Rg]=(p7Qh%JMQEuJ9&N#pDUWVepf9gHkpZ3L`8Bm`.17Yq#cnj,^;NC,8O,^SUc@o#9HbUL/A3bcNO=Y5RA8iDc%X.mfXd=&lR$drMB*2saj.MVOC7fm?/Ia?.lP:8u<8BAN,8LDRhjPap?3=V=C4kX?=7/(hiCp[a*EK^"6$ROe#05Z/BW4n!c>cD^dX!*["a-0sl.\r0;C`a$bS0We6]"D7CoGnA#=@&orFHF_"TiJ-X7r8qf[rEn=9j,P+&nD)c1&`.E\&0WD[DEf,A&u59ni)$KPgOClKX^mF\m!M"qC0k*gc1tIbQ9n`7L7lO!nRJk"]?dG2::e+On.$+J=[*9bLdX[]S-tF4L-[P[r=1AE^qgaN(%4>c/Vs7DFO^!b!.Q7kecL+IG%qc!&u`TjnSXQC=tn-Ot?Pq3A2@PI-c9QWYO*In5<'P1NZ=*u_#$O6=_5Dc%.#Tj;]-1QJ/o+E2uil(".UeWH8iZeM9uh6MHiq:(Md6=fKLOKcTl3B'>O@[-]5e[-,>gbXeCSEHpti"9=8XHBnDp/iPB#;5G@Npjb9QA@EpIT2P63NCMqjFt;43%`_^cqI8S?I75*[!D'*+t>JS&$CU'BFq[3&LnOL4KLquFn(M)'8cg$\6Wf&\nk3Z\/Xigo?6K4667Z*nS$DnRCYG[bVas(%C4<>3,uLtIEfM)A`*6Z>Cq%1Baj=Sq=1H^F#!]0Dere5#:;X30j/DRHC#3kia6!+8(Ugun/bnr[4W_PJ:T2)nBFbr)I#hiSj*%k7#6DS%a:M-)'CnKf09)m>qj1.)7)!/$f81QC)UJg/(/H.2(_q=?7j\7K`8sXLU"3l(YTXZ[L;uL]'(`^U`'S<>6e0U(P(nK:jFBVBjaF&1L6q4WgDR?_dB=*Da"(>?K:Z]bs8HcT)iOU.W(p_`gJ`APD_74Eq:oP@DVurA::21DK;#RI(*>ih0h8?Y3peL;n_poESAQ2^L]@5+O(i0oS4'Ya?biA=$kRoD"@2f..m8.*SWh@IlHc]1u?:"]+Wc!bPiDcpg/&^2pd9IVTWBk[463*>Vkb6!0oA=EbW@3*Eqeu2nji\CcC11Z9)9l=23D*ZF:>b]FAt%G:IkSnO+4LBT0=chN4g,39n_3#^`$Wh%#rG;ek5Whrhl#Mo3CA@29)oEL+AY6G(@4(g6rcoVi&6k5FP=4\I$q&+ABh69]d!,*Ip4N>abt`+:C?7E7d]J)=\WL&~>endstream +endobj +20 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1892 +>> +stream +Gb!SlD0+/q&H;*)Ylc(%[(4t]FJhf@#"!jI"U]86Q[DZ+Mk`\+<(V?cPQ0LigW=Ui4392'Bq-;fhL0SADP,as@mKS%l@4F(^oIcX^L=o;9TFZq,%:%(lqKs!NsKs?Oq&%sWUMkY:K0Q?:Ib^N/oa&B1!il3XX$H^Lt8.%Nd=;P"hB3EB-RUK\Q!8L6o2m6mO`iQ>gCa(,`_2:bPJ>j\oQ+ADX/=Sg&*$29!C3%M^g!GbY\jDAha5Rn]O,/9;eWm:=:tR5Khgb-RBaQY2JD*]J^QQ:,A(uKukc;SlH!W5c)Y[X/K2)Idk=4-79JLH*'b4Ze%$B9[[QDKF0b$o_LcU1SG=05#K1Yu:(Co)&&oa#b\"jo9G..^\K48Wi7TN\r>/iF'r\-K@&<2s)F3u3mQVNkUTA$TgMA&)g'T@AO3jq-b*ddiE\MBm011kOm!#8#4Y'\&q3iE&Ptio-E*cj"s8fa2bR`Cr11lknAYk3,'G&r3IJ7k66J$c&P>M\3fE`IFMf\'bk@%L%%&-Jg]k=KHNm+hLOD:]N?i30or?Od[JrcP7e2.?Di/$9=0[ooO8KK*KO>5h4**N\/3a0biW9B=BCeK!;?d-2d?7AI/c:#(cDGIX&t0dD<'9%oTchNFG2Q-a=ZqI=+M3&)^!RA0>;E6o.oqjYO@mgr-)BfJ!&Wmj!^YmF$4EX9plo%t/l6HIErXh6ZOe)5%:m/3?k0('94Iou'@oCK:ml/!]\R]sLt<:UMr4Y/T@f9s2*P$ikjb.p\lnWs/HHD9tCB=hp5`j8+C/TKWofB!(#rfKdk+!>K[hH?Ugr%6gbj/Z96A3bL]0tV@DMiItlc&2.W?`fn(hFT.9RbkhiM65E%=6h[AdkKQV:<(>p6%&rI80lT[W[A@,sY;"I(q1nbn=/[_=P[(:IoL-J.DNo1.K""%UhBC$o>H0oAP+D+%+.'i3Qn@Ja^`"Jq0.j;+p`=uq'9rL`lX1'gQSej[X?dIHlm3/,Q2cc@H>9*%cb,89N2]6uhUWbU;UjeCr^GMK$C5l48_J`$?-L?G8Tqd(W!K%"N'3`+/_4did`[WZj6/L,!J=0Ic1??PKU@/8Ji8\#_,dg%"BmRCTl19(enEb1UG\9r]u2-'E,@"f<21cDSWr,'2NmGZ&igV/O@RWL6[gVQ.,F][NCSQVQ/%4Qs/VYT8`MSn/E9=5YVL_\VWYYLXOSLi5'%!VCMVck^INY#ZOn2]69-[%]e&@g6+h]m57NR'j9m1,OTPf2WD/;Q08csZY69"7>Z`,m8Jf^i5=WFn/%=u)P&mRWn.-+J#Bfkd@(FoC0YI%lAJc(AI^o=*>&N/D:P*JCoq#R3#Jgk9J@Y)mS'j$Xqm\I$=I.N9c[Mg%eg01Za/FdN;)l_GC7q<$02T/O,="\#lCqZc-'S#`*6;bm0S3nA^"M1H2A(`&%eUMCkYO+ck<5#]hAa=l6q`^VA_K0NiLp:p8Q4e)b0i/$W'G\~>endstream +endobj +21 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1651 +>> +stream +Gb"/'968iG&AIa;CickO-4g0?!9nYf9q6Hk),F2_8kutE1*k>C5QrE5HTM,o?19/_Q7U/*A9s&<,XGo0mI%FoL]PIR.t:&FJ@>XET.s^n#%M$^nR-;Gmg%->LN()+k6#]+l@p9Lkh6i?M5.m'7"d[5&5Yq"l%'X)&d2VC*9To8,T$^FQOX*A"dOWD,[e=l`2!,\&Y.n0*q=pi+3q(["VtE87#_[bFuYRr%'ND$j7"?uM*oQ\!S#R/P3AYo5"B4qfj2($!8QjNEA`jZ3$,r\nYE6+hMrnB(Jm253Rk?$&F*-G*=80I7SZ&-qa_>hGq#a2$OGkhJk!6ledo.og(>%,]LX#sC'C0_F=E/$f,?Yk#q!KH(2H'_WQk!UjP2^@]C!3STlin.7M-q4c-q].6P=FZ"h61I0'>OB,'>h?9b,ci*#2$Tj$Jgt37Z+$R2YdRa7.E$:,]sK)Td_,.1@n@o"o)8oh7f!U.uqSSO*97kkALs.*b)u.Yij!]"X\;$qcrRT:TAj3SLn?h8XQqe!@2eRP@jG(`MFn,!':_W.e`*%^`PZ":mo`Nn(Q\ZIW3B^6%tdrl5/ZG(BOkpGQH,:i#-Csj1@rSAWmGZ-,`BDn)Hn]S@OmPE]\C@@.W4ISU&8+Y>j1c;K(flj/4p4OG/XBPDXEHApB,sb.LoIb,P?mkG@j4[(V731lej^9aIm9&-d,Z9BrO,,o'7+rOo=8phfB.e'Z)Y5&($N(%r=E^&>aHTi/CiVFrJGI.H;Z%ZR@7d]+;-@CX*m3(3HWT_HB"hp+[b`$Y6`(N)@&rG&R9Ed>1t0JD5!4qB]K[gG(Z=9<=u\O686K\opJO7l;XLZmXJAj:RJr\L9OC!T!W3a&G*adUX>MmFtc':;:bBf&]?nG%k=KQdumq$nm$cVsZ1?K]_lAo6F4T#WmA"o8*ZI9KX"&67O,<9;G)org^F1%#6)HT&Pi&d@CR0uXU`.qj<923:W"Ih;:d*RoS9U\"AY<$f]p[8-U$g[-e?CA5hR;K(?q0NT;R.=*B23E('1%&Z$]?KK(-Wo>;endstream +endobj +22 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1859 +>> +stream +Gb!;d=``=U&:W67fU4p*aj_"*hL9/Pa(a=KP%Lf,R7;Ip8Q^R5!=T7eZ%%1gVeA`Q&Sp0&dYJNr4[/4d-",`%']7:Hi:RWcD[?s^_^ck<@DhRC:56H#4bL>qZQ1_Nhm&1ORLQgF%aE#kBXuJ`Sg#mO+?3"VWZ]Apr%0#GA4g'\Q;mhha'=;UZm^;g#\t&*XlOLc)c7d[6JjST8HK^uBq?Wr3BfS/e=[;3#;GJsSl]CUN$UXA2tN#eU#l>[_mE.A4lY(/U>B@EB6_@;m"/2"()R)FMSh!%H_aip8C3;i1EKiCB$Vi`QtJAknSr;^WZ3i]X8k1%+[95as:.d)rN[i6>F$i,)2MEk6ZcnA019.*@_goqHuHXMEp@USWiDHlV+W^VO.#mXP\T<:Vqoi0@SWR/W.^r?2<09FI)G3a"=k`M%I5Q!$f42VAY=9an/uUMj;CFIc::"/NB0V#*u)Z\hL8Ve'lpObKG[UnIas`:#\8:iOK=XBa6kkmZ'HT]=g,;t^,R`$u2+L3k@YVFn&73[I2gh?sU2$P4)DFu"f5.2+D_3^"Ai&fHDF6tZ;:1/2hLAcr2&!n[MQXD/bJlo[=2V1=A$S537%/_&P8*VN67pp>BId*?LR?B/>Cao/1h!'.tTnjJ+6XIRW.Bf3XgS8JFA;>eel=XH8[E"e+4EB+,hJnC+c/7W.1`3^Q"/^R7s2hBtW_5joKP;8o1F.r+`0T,-I_Pfn-r-*skKUDY@aV"'U:*D2u3/%';_/.._q?=UaQ:K[qP`&51j0cd84-gr)/+cH$nLW]EY>[+j`CrZ>4a"tPSGnM`@`s,29J'p)@F9E@ZcC*?`l[V.kQY^7D#P"d\=HUcTehc)Y,_;[(b*2lFW9t0!)#3[.llM6@9sH11#b62m$h&ZP:?Ss*faF$hD[AW`]go+R?)XkTSBOG;.>*+RWb6=23#I8H5JBNDO@`U/"OgU3SKb)]U]E=BoB#t6ra2'9$be8@mdMqKbKSqeM[Z*0Yn;oIC^CK)&/anhl%F60?9eK&NHs/h5J=2eU\Y\GJBK<2)iUSZ?7\=lhRK[4V6nD\]^l_#[DZbbgWVendstream +endobj +23 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1789 +>> +stream +Gb!#]=`<%S&:XAW(uuunV5-"8dJpr1D+ClV]34UV6'T`;IWLT<'>Wm-o&!1Bn8&6j0*r0sUF?b/(l[=gMp^JK!)\B;9F%A5XB?7!V.DiQMrP;ej1u.sN\\#sVT#Glj`o0RAs4=:r[aJd`<^lU"sV?Mn*M73Ucf4nCuZN"lYk'SJ'M9T:7!A#>o#+63:Z_M()X3"H(m6W!;'<""^<0j1au"3YLCIn;/QGuTQ/@[_'JY1ffdU_CU:V5c,NOO?Zg[/?%B(g][?+sUG#$").0&b/;mWGu\Z,MVh)H_Ch-Do],=+c&N16L[<\e&b#QU1/h>=0$ReNq[]>SfAo,N`o2*]&S`8/&3lD!?@4'Y.N$)n?ErsT#::_MBlG\^)%-d:2YLA6"q]N-QH(@-pP6eU;gSN(i%5'^1MYCFf23L4jpOP7&JfBCd7I(\Yer0n1p.*j#?"^MiC3Uq.a)fB7*uakp`&lPf]D\7Hl8W7@o^?]ZVu([p)Rmo#YS4O<$^('p$;B>u'-dW%DB#XAmFW7>g90aqZh>HI4JR,4_.a,dlU/TpI:YO:Vnc%B8n1R9.+n*&I'P&XXTKUMXF!_GSNsoqV)f#h84[Tf.mqk.:WJgmK/ID7iKM`ORId9[c*4elmJX7WbMuPk2-2\M"br^&X!B*t1q"8LdXb_Q$87TM<(%48rfaA?8XL?l`2[j&=am4$M.V&mEedUV*[_@GS;)%2(H!,=D"-i~>endstream +endobj +24 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1994 +>> +stream +Gb!;d>?BQ=&:Vs/R+%t?]-rsr>;e-]-sIJ4[^7U=mR,G.j+p+]=C0[3dU0a6a1%.'$-R?)P(OE:)U149q.;Gt*.60)IlmgX4+tE^"j14t$'Z)5_tWY;E8UaC5nF79E1IP>J<=gHVFQ1Ch[oko&l?mbr0?q-nJT6H3UqJ]]YD2/0:)XYeW;.A*>k8g=lf$"mqg'tsOl+bAfq1d1j)PWpfDPYQ0i-a:Sop%eZu]3)AX.34Zoi)[t9&Z]K/DXCB.UgR7mmSr-0SQ<]]KX=&PX57FirSLRo4MQD7V:XfM/Y5/%;.STW_H:-g-PJLpbigPp(E8XU;tM>[f`U`La5K1BNKe-@e\qmNRjb[XmHK_sfRC?OdbQ12Sk-8c\u,:KSjP4U.76.#G\Bn\S7?83'^csgrt?*!WMReC7HS+]Gm[]c-7>R8O5JRh`"9ul]G#oR;RU2P\,jV9e)='$hUg47h=&J3L!6*9n8S/(8!XC./K!El6"":\t7,#R-sA;ILI,#uF&N=9:I*SG!3#l]2eB_U66f5$R57^l,E>rG\KXGtn>$[MaCiGJ>C)=Le)DfbPXXOCE%[bNm;D"P;*4Mbdsa0'Q;kC_LV[56;C.TNf'9!E&6:(1\:a%bD=$f=!DCo_`OOhTK.faDSCRo!bm:cWh99lReRLjqlnrruGNEC!,5#-'7CL,,4"*n617.EB%D(T\m?[1h=LBI5js,(=$ao)?fJ>//VP4Pto)BRO)X9/ViG>NfJMl)[_V=XI@U(9M2cmqB-Se"9)@fp#M`0VgKUn1RTYSPATKSJOM#'d+l)c&210n+KC<=B9hr0bdgZ56-8DCtkM@^r]^$OmBRBk)Gi+K_`9ed15ik$clH=ck3HVj_^U1U-KJY=-I`t]n.5FPEIR\4-eG.nY"UiqB35_nHpo27A3YiLs4&f7jYZd]J/H4Z]p-27&!^`QZ?lII0!KK"?2QjTk6>c;1]YFaQRn%PF%e`8m"RgB6AHa%Z=dI"ikjGGK;k)q`@X34bUl1fX3"gLHU[iSu.59OHsIidnX6ER%YH/D=XrCl_o;8R,k1:WOaX03r/66EY%D/4q?0lK:%Nrf5<]>TgM3jrWd9tlF1p>5CH,N)I6"BeT[P]KQ$Wk,endstream +endobj +25 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1676 +>> +stream +Gb!#\a`?,q&A@B[H?+k*8hgGS!h_2FYoQo9UrGtp=_brtTI?2%7=bdP3KCk')Vi$IVUl_Z1*mLqj`R?qJHT5*On+"/"PB<]lTG<&_W1t.Eu7S7_V<2rkK'?e$Kd!$8_4=u3.Y`B+HK#2I.$KS"pC_P*%;^Y8K9/]#o(tt5m66UNa@_O3.eb/12nN/\`B+.HOcqf!K^/;:8S=4,g=+f,7sm),te;/*I:q$WQ0_rRXockFP]EO]u,H(j]X8b#I8Mb;-i0MZ]qZ7"Te6?pU)iOP!@?&$_dD7@/`\PNLH/V?=C&2`]!Gh%[e@a_U8"_MV!]gj$(AQ6^g3G2^V6KZk5[>LW'DidZ<97@OCC1TYE0WHgn[!]T\NRJ(B6@3t4V"B7#gR2@aYZbh;oH,#8lZB\?j"]t+>useZS@'#b6d8iiarI7CD3I(d:K(8$_O3g4Qt+Tf$ub`"bDViajW.-9SD[IF[V)V';[H@'YL7cN`%_d[j1r'O+;T3\"F"HI7E96'e-siF8k;e"tA-%^_Yd$;Hm:R,a-8oa6/N1P;%\#i:(,!E#:#(.&\S:bQ`dN;&Lab9B.r`s^7&QikLTM95nGL>u!AX+m[OEQimNMB?7Z/s$TG(lZ!J#Y-Qi!%a%e[\#%G!IG8[;$E>&AL_R1a^baUfa0Rl3Js;8dgbtdJ9.<0=M/KgDs,fW6KRF+0!M@miHUF1_\WEV+n?[NYHT\4`c)fo^C_hEouKR2"DDG=(MN$X4>`PN;JVJ/&JEN\j:IX\*!pG.X`gEbYTm\k%eXg(JE;Rn;3BaZ/0-J0g4e?ZbE09p10=*SOFgH`G#kqINWYl27J;TM,=2G-?-aa_s,:KShOcJq#PeGgh-d:t"79G@WkC_OB>-ID-l+TW^q5@j#p=5CH%tZQendstream +endobj +xref +0 26 +0000000000 65535 f +0000000061 00000 n +0000000133 00000 n +0000000240 00000 n +0000000352 00000 n +0000000457 00000 n +0000000662 00000 n +0000000867 00000 n +0000000944 00000 n +0000001149 00000 n +0000001354 00000 n +0000001560 00000 n +0000001766 00000 n +0000001972 00000 n +0000002056 00000 n +0000002262 00000 n +0000002332 00000 n +0000002618 00000 n +0000002724 00000 n +0000004637 00000 n +0000006493 00000 n +0000008477 00000 n +0000010220 00000 n +0000012171 00000 n +0000014052 00000 n +0000016138 00000 n +trailer +<< +/ID +[<523578e4abc2fdb4125b5ff1e456104b><523578e4abc2fdb4125b5ff1e456104b>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 16 0 R +/Root 15 0 R +/Size 26 +>> +startxref +17906 +%%EOF diff --git a/Les03-Cursor-Basics/Les03-Bijlage-A-Lesopdracht.md b/Les03-Cursor-Basics/Les03-Lesopdracht.md similarity index 100% rename from Les03-Cursor-Basics/Les03-Bijlage-A-Lesopdracht.md rename to Les03-Cursor-Basics/Les03-Lesopdracht.md diff --git a/Les03-Cursor-Basics/Les03-Lesopdracht.pdf b/Les03-Cursor-Basics/Les03-Lesopdracht.pdf new file mode 100644 index 0000000..f743516 --- /dev/null +++ b/Les03-Cursor-Basics/Les03-Lesopdracht.pdf @@ -0,0 +1,263 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 5 0 R /F4 6 0 R /F5 7 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +5 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/BaseFont /Symbol /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/BaseFont /ZapfDingbats /Name /F5 /Subtype /Type1 /Type /Font +>> +endobj +8 0 obj +<< +/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +9 0 obj +<< +/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 23 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 24 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/Contents 25 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +13 0 obj +<< +/Contents 26 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +14 0 obj +<< +/Contents 27 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +15 0 obj +<< +/Contents 28 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +16 0 obj +<< +/Contents 29 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +17 0 obj +<< +/PageMode /UseNone /Pages 19 0 R /Type /Catalog +>> +endobj +18 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Lesopdracht) /Trapped /False +>> +endobj +19 0 obj +<< +/Count 10 /Kids [ 4 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R ] /Type /Pages +>> +endobj +20 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1720 +>> +stream +Gb!#\?!H&A'Ya=F3*1ITNiJ7Y=Yb1OK9eZK=M(Hd9l+n)eMA#pL3bX="bp/m*e[d3Y'+26m2X$o()<*Z/"lc&Y0c@SS`DEuu[-8?%QZn--Q5gd*3h-U:rR=Bua@#:2kcilp\`E;;%Ol4/47BRRFdO,D:f8a]2PGH_XUSJXFo<8-M/SF+PTFQS@H^h)qoWO:ZE`DZXn!`Dke)eZE[M:8!I^.%eci,FEW,VH^T%7AMRfGYdgU0#\]upO1;+3N-PASqZDE<%W&Sg5MkD^?(L-c((c-rPN#\Ri6uk#5pW#:YNlV%Z67,@=AO$H&/^tm<;aA:./rK5Xu0H%D80i6]ariXD0J'M,LEcbSlVh^_-C=_X7W7jZ[ag_).pCHl*6F"^:9Nc#AU4b6McuF9TEI=89:=D[cj1$YtQ-$5>_=c&(AQ!t89h'DP2b^-@C\m1g&-SG'>UTT>G?6%_Ns"H_N4s.T^lQCdpQ0_=rrTs78o6]Je3,ClloaM^YN(iaI1&d,3jGsL_(+5kr34%TEUbWX+l)@W9_Horendstream +endobj +21 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1731 +>> +stream +Gb"/'968iG&AIa;m&?bU'b#U'JA/CI*N*U-:/\(YFN0*1'J._-8;;fgkb5c)$bi`5/31/:LIrVOKRh%^DnfR/^jtF2fk#TkckhbafIGJ-7#+)+Z65'HVL^&Lg'R*6/B%";Db,T/mC:#cNh+&BXi8"rlT.&o`k0Hc-GHE.*+d:Khud#o[mkZi3=%fRl%7eQI#X6CBKSQnDfhroU[kn7+B.ATX2K$2eNF*F0Pmi*=((=)b0(kTn>onH>`@0R[[`(`;pn8po5(2iYQ&AX:XLeJW\6k&IDO%ue.g(0`9iDkICX&F!+(g&EhL!sfSB46b-1nl.?[.lWG77chFGiGF]_lc=TSku'*T$;56oAW4]"N5@>F=%9)(:MrGP$8)VG&0.aeXC'SqGo\lJ;NVrL,7*a#euOkqbq,:I!YCrW(8nFj"-C"n#RRO1Fs'$jdosd,Ji>^82:VjCTTZ(6Cq3O0b`]BX%:hJ(CP_I$aXN=N1tEEWS?.T'.j3+!(Jg(c5fb>c2?FF5@?cHH9"qpg?F>r?0Lc?BYs!c:isAS<9@oIhStpO;hpfVE5c@2lYXQ!K,,]5JI1.i"H"F!mPD!uS5\o-cRnauUXp%Pm%uJ3n[H-7Yg)Hgc>`hC#0F9pb=I\jZg[qt;F6-B3_1$0,*hBhQKZgp-@W8lF`<@NuFN78?ZuKCW_Y-64D/eRUk*X:\1csJXHaVnsgSDJN-GJQ39^X@8pb>_TmkfC'=FE-D>iu%k`9Q3@.Ag.k=KbU]kk0f,o)ZpUQ.Q2/chHF\D<%jXf9u'(>GJ0+[AA@p@Z'7$5<$*d)#^;*Ko)SD?7V710f#Qjru^n-(\DG@$)1$gitMYS7Q(.+i)=??^j'ZZk?)R:1"I6;T]5$BN0VH9G.T>#\0:7PFg/TOCR(?L=]Wa3-&I?eKpjs^i4?Arcm9%`F&Ne`jL&2h?$X\K*+5SmcRkDfio8chU)blfQ$-!WgW/q?).#!?G(OfRnJROlS*NJb\@H&W.1_3seFa((j7lVLlo;1(-e4?+FcHosUH\T[T'DW@KCU8*^5$0uR^!j^hW4YUuLI=WM9+-3(m']D6"FdNaJ4sS5$J3p!U/Z[in/aG>mU:;ko1U3'Mt>1s]Ie-p^*Zo2Sa3+M$U`i"%=cEH7F4Nu#`Fn+M#M:eQT[(F;V[+nHZ[Q<:;mPC_.;eBDf$\-/)Zh5q&3PY=LFM_l[:0l4qT!?.,;O3[ZmZ'2kajmYsKFAS,.X\:)BiJHY.ND-C7U(^<&gY5Dr555pI*0nCp7M)Mendstream +endobj +22 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2057 +>> +stream +GauHL>BcPr&:XAWR!m\![oJM$8E;?sYIj$VhY*I&I]*=*6];T\OZ*123s(@\@OI2*ZaLB&6CR`45%=p@^1hYJk5`iJE:B"lAM?:QapEjn$+q+9^5WC+RG\)W?[@1>J4.+u5rftI&;2H$Jk3_/91l"=,VV>.";OaJ3<*JVJV_YdOoph'#\A8H]MCl6O>SCO(e-I1GPItd(QkphLG7Hn'#P`s'<7tqF5kS4">HFbhRiNShnX"`eQ%!*9EtOL;TBRh-B&6jH3;LdQ-N'sbC(47_Y=Y^?pKq]*XR3Ha4Q)5m@i;JXN0AYXZdD]BoM5ofRGu3(oj$Z\k?s:(akfggB7P2GQGt^?8s7.Dp^@H"^K.oXhAc`&Y6*^c^s*_Qh4"BekZgN7Ag&cAPBNeDsg6nqMZQ>FM_$oIC*U;C-Ec??jBE9[41,16H?FLUq$[/n.s6C/6c0#$@\k=3F8qCT/gOWF1B`hgc_Xb7%`F9djS2VL@[LCFKWnESSSn+!G3+>LOkY%r<=bK%GNs7fK2UP)_o&8>n#Li0&%dJ,B8p/au[udbVA3!?_DNhHPApGEfIL1Q/0Tu9L,E+RD#ADhrAi:6U1.N)S0D/3C`r)#hdRE6k%O5o>e[CI4siUC_()rjrV/2nP#ffHDf]oa'\)/jqeqoP<-99@"V`0(m+Z83HQLpAjUA@tgk9mRbcqFn!6h.7hRp^o#*COp6E2fK7/h.CrUp7Xh$Mq%ME6K^NQ%<\D[V;%:X'9!:c&H`!6gb)4b$Lj"=3B#2dU>O'Q]cKeT=%:mY_elGobI0I8G7\9@[.t79"2?FWJ`,8X1996EbOn&)$o5tTaNHA/4&I#Cg"feY"Ri#TSh_8*"3]*AEhcqKR#gL?c\6[p)WbE@+_*]U#DP32OTcsDCW@rKT?GA,P/BfgAIuAl`X^DIeT@ER!7=-0mA!5inL__?e_;mkF*oRNE23;p"D*R=m"Ei1O!>+Cl7PVKu/Zo?S,Aq1,Oub5!qQE4FClBW\HroEr95Ef#[;nltq&..d2uc@hd't\gjjg_)@;8[QkGOh<")dX_BS+@\;uQ'Xo[]H8BE5(A+l&!M/Ka'<]OAb-g?US31LIZ6SPuGh[="X`goR_h9m'7I!Vjpheqt)LQ(rnO%Q%eEjp?ZXIeeXoAS9*ZY3hs4MQOjel]aRUta-"W//\1rdCXRh/e&B$TeTZ"h0-#c%D"@1Rap~>endstream +endobj +23 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2020 +>> +stream +GauHL8QXq3&AI=/e1d69bm5unQ5^:X1iI\obk*1ta&[eKA%?/2d$ORq;j&0U=TF5t2"2-P86):^^=mCTJ\S(2NKsS5`c-6`!rf`"Q/^)mnoal8UNbl_8:8bB6k[;bh`b%+J*@n4pBr8NpF;=kAB3^(947MESY%"I#ZHRn,hV#kR_A!LVe"c=^S1kC/\T/Np"3&$,b(rrjdUkI*RW5QLbgiQ@_Q7&giq+_:]Q.YSBfVcGVGrmpQ&_.Hh&6N^4YSHCI5cZ@_8E#TH':_g.E!5W_\1$O='R&I]gV%h8/]^=E6BM?%B#P9]kL$3;AH1bqk/g+a;nP$5^m\oriV9ZL"7/*bmd1=`Q'nR%1:UhU$\$,?$%d4)MD91td(o6.M-69XXQX^mgHE?^>@b9V5>"_4Z/#Vb:A.^_"<$@c#Pc(;LNC2RH%mm"B%*@Z-BK14!Qu`=Oe>L'>)U]a](jJVch@7r[\VWCIKprL8+7tG5`$D41X(E26>Z)g`uT[\JY9OWq=9?sgiHh@AIq(F\\-Zl,(jkA3;LK`HA?JFN6#l\@NL=O&#U5WX"FF2Z4!4H[Vg_P09Z%9DSDp"3.T`SuDEnr/*F'+_3M;sF9n:Jl3hX3\%^o$TR-508)I@X,?gigUc'mma`,H\pMe^gZ9Ur6pCZ2/N<1=d/bmK>C5GSCFGeW)2g1Z0XXf_rqYi"EE6[B-D#p*]+H8#>GJ?^pLuHI@X(A82?!W+$8/U:2DJ!\EK\R:E:f]t$bh:.EX1d=^HHm4U>ZXs]C&k^9f]=eksfNi-?#%%X]U=g>-^SJ:$9nc?J`R_Rhgik"V`FWe`O3=B64=@0dlJB]&'Jm3^/11.4*;:mMX"[W[ZA8IY;m^Nd:_/(^g%d`^3f8=H*d9M0B&RFiCh)nWt\OR.:JaE@tY*+,0ZN2d6toa;cek?U`3hbCTa,mAEGugcMn.cBT#RXAM!i`8c10muRC5gPgTh`kMW=%h183nNZWp?PMirCBH;oiW8O,E\;IZ5j8H#]5l-pZLWDZi&V$a1-NH>5C[@Z$,_@Z(%H&;H94bGip=C^!3-q,a&^."+NaOZ5:OD$(]/U9A***C>ctXb:P4M@//S5.Xo;1hdUBYq.VL*UuA1Q@H()bFuX&:g_eI]G9c1)Go^D1DQD=?o-RHa@TflKq)SD>P#RiU4IX[9!;_*&G>N/m:_TQ9."R1tIkC+IG)oXI0E.K$XK.M!#j_]BfmPW1.tendstream +endobj +24 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1769 +>> +stream +Gau`T>BALf'Ro4HSB2GiAZ`X:]AbD^il4nU(PfFT*?MeX(/PR*+t\!/dbioV$^/;5+QI/F@u3X$^@0k'6G^JSXo8PuJ2^st^SF+4N2JoE&MUqRGN6NK!F[%5_?IfA_gMa-kN*fHZU"Yq7m*F>'U0i!Oog<26n)ID_gPE\$+YWOo)T"=4\$t&6rDQ7hLkcsG`3fQ+Kjo'g\Vq=WheekY@32ClSf0g-YT8S/!UM%:fk4^?Gc3La$6`bI6'/Q0Mg.7I^ciojq];&8U,XeDp=i0e'-lc0`DF>k9WAhW,Nd:EZmAq?CN.`_HaR%53Z47BQ/;b5,/kE;EWN,P7Ah[FTbnJE?k3+35D'tp&#F3)d]_VOO$gBstojkA>G[k=p\3#tf%(r;iP:qpNejc;UV_)o9S=,].6T>Q\67:Z=b]^!0W:[=-Vd).(rXIdptj:$mk>#I,9q&4RFuaK4e=gmZ+F,i%k+N[AC7D(@g8.VP..SNTZ!$VhtNZ[u#/qB!)]p0%]?f`h]62[OPFh1t)W86NFKFtFa@F?XU/QJ+Og&P"gd^S9<*"G:lWQF5I7fXS[CM'F=%[;[TqrD:\1>sV?DLNl(@<3#]#dg:(VX8jcWl?$u+Y0Hr@S*i0ObQl\2:qkLeQ**uG!Fr3I:b5Ss2`EN+HJ;T&oNXRO7`Y32VKb4jf(t0a7+uU,t0JLDFTo0$?/W9Q.0s^-mKdBo/Lm)Ob,DnVX@1.)(b*YbJGNb'-/"dSioA6+j/l@eDM*KBbPNZotn\$h1ea5SU"#X>!H1<=jlHZ^tY;=\ZEEj&.aDhs,T?0bYIqSTX_fnZBGR;/Epi_hCqg1Ge!m`2q(_0c21FBTbdLjDgk%92%@[QU2eaF`T-sJ&1%F*QP&J=YEVSe:S_ZVE&_P6@8:ud?aHn8PG.Jg8^:E'TVB9ba3bUVs$'K"L!Hn*7JMem%^3*P^b8Tc0_B5,K&h,hJUHU(dn'oD%&P\>UA&#j*2e6O5RnQT+?m]"MWkuC6]TL%V(^_=\6Z$Q.N!IfeQ0htupPb:&sDel''121<+jgHAls7Z[:=]>l@3rPuUb?Rh4TM1acVUq:A?`d@2.Z:Z.:q$a!7m@@Q&>,qid629$W@*#o6Y^@3+u0&#SCSZNT'QI"BbjmM]D9X=WAOYibQ\>A]q:DToR)Np?+G(![4G:0pXbs%$6,-9M@!2DYqSmsIC*np@N73tZf9Il[&Anm]kF/H4b!j*eKq),;fOlRqQ$K`hV[!^`H1JH~>endstream +endobj +25 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1810 +>> +stream +Gau`T=``=U&:W67fZ?eIF9I.;#a23WRF[3B:,5C>.qp*t&;l&b7_D&SZJA:UHPa?VMmDY_7?'lif\LK7Kaj]")9#rI!r-=6j&6$g#1Fk8S8ak0LY("kpAn]Sg"ZX<3n/6h&D,DRaB!p1/4"s4>QYs\'?B7N*J6>3lMs:5gGWlh,V3:2$mmUV]\1-:*P2jh>+!]j#c7>YSrH_9PLR4%5Co,:*5HE/1^5]iB@67^Vl"KS3K-6nO>3Efc/fdMi+rP#HO"g3Q>:UQ`#7lf97_fOq9+G_b'O/\)sX-]^De6>M=o#n4`5]2?dlp3oR(Z.;bA!#%m8.+%R!X1k"h^#:e8/>,#,moDl[IS,8T@8Ll,V1598ZZI(%KI^Jj&Q+'Z^ho9[(s5rQ06,gBUB6m-0u8T!gQ*LAhW#.#Ho<\V*=VGA]>fZoR[UNmcEM='Ri2FS$F4DrKEHkZNmi8J>@t7-jUZ#4-H$u8er%2lVLA(AlTnBfoMp3XHtn7;G`EE7WZ<)b]>R/&![Gi2(>?.:ll\oa9Yh[9-*YUV#bI6bTAX1;m`idurV;M`Q\pNi/VrLL]Z]bCH>8qk'/*SN\+/k"n)]VXX5cV>^LrmeL=N\7UQCfGMM5;]gJG_,)uD*U@]YKMS..2*s6:3Q7Im?h;%Sf>UYO1kN1[fMiF^_qg=0uL+htlgj$#eE&OT[59:3oN!$*WTeVI(iY=>S:],Ffd(1+G;eA#9]qZ+2S`a\=ZW'87[@+U[<$O%G7Ae87.]WFdK]c?Q+esLc\`N_CG=X3Mqlge*I;N:H_#YPjeRO@%qUA5(aHh"tn5a0m-QW:!Ga5]&C&M%,'\`9p[@eZV-chs)'1j!6b/7Z%[%jAE<0Q!`R[W1E<*_Om,fP"D\H9Bc@f0dN]^?OmWU7*+qjC*Jgg]-\Wr1*;SUd)BNS9m>Sflj*qn;$Vgd/gB#F@B9d;m]_L!`SGqJ/LJqP)F^+@_)r%/KV+g=UZ\4/5J$cRpi/__?3sh"r`MlVXshs:6Tgi-B=/2^f7DGR\K28poO?Rb*&E'YD1%V\*Io(u**60?d/.Cs;qX(+5HOD-bs(#oFFfC`u)s/2n!h8u7aA3)"]Q>UR(NR$?$6;pAmPK+_hE.P;7Q&*@%9S.?%P[hAZKE3+u,PB'Kui:-\^1M2JZ5cZj:306M`LN"jK'7=(^%mc8=F,6+7D,ri'97N-P!D]]hjG"h-Qh*>dj)jF/39,e9`q)M^^D%SrgPVj(L;:9L3WuCcMOpbthS+QOc%^QUSU3tdVG7jR6cRkAAP_5h?%i:hkeG4c2VL]_jk@@[0s4,n]a47tDHME8AW&qQm-"F4n=87MHsg'+fYU8+ZYcp41LA-`>&*4/42>aDUFQ-/E(&G,=:$p[e9gdZ793Xc'VHqTuH?/1c9QqRX[`ToN6:]LIFdm^70Jhh:BFd[li[%P+JCsku7Dc",&k2h['>lq31$a%a_PIoUu'T/dsX?$R'gFsaa#Rp]Q-,S;e#22W_*?Q%S;7~>endstream +endobj +26 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1595 +>> +stream +Gb"/'bBDVu&Dcq.k%(=$?iU=$:qOZFe"!4.;lNoF6W4QepN6WJ1nbpKen@ai])9,jXn;A_p(`PHrgk-D]i0??)WQnN6(m^e%q4oo&!>Q(jN\.oeT^PjZo2QA25X,ELOp0c<5X(hWHPDfje6GeBUR7,![g8bQGL8js[<6WZ+q&fk\:a04Cb=UkXa>i3e.Rqq"378^"tlU$HIEY_pBdt,QUa1#3hh2jgO/"%YDHm"m]iqD^gLhAW:;4Bn<]B'^Zc"n7pDZU7kuOM$s^F7j(u`-TbUd+0%KDKj@:RUpeB%3,.jqD"Kf,V\;S0JY3j=XA084:5cG0$IBEoRla7'/(p+nd10>tbX,PHZr8oj"&T+"^2Wl[QF'+)]Wh<%L-oU;nS0_$cfX`kZ3tt2_f?)l8*QLG]+c@Ju7"qeL'neWu"dE5n9q5PF%b=ukX;@p;2\&LnA7]3_SaAtm@F\b5L=H-;dH9oSgZWq:\=4!4U)u&)DF`J[0d_Q&7M\Q:Sa[]+WAub(0(GDd'XV(iK-=nm4-8-,jIatJU;#+h/h7?+BbL(I2JKIJ(La7_F3X-./,%$&bMA#1#]&UIot#LaU1)U5lYL!]*'D+$E#]Q/XZ0GI0-t#WS113?Q0i\6&24>0o:UWEh^i6MV<`(Pa@LCc<1(AFELf#Oog3RYb^qrA$M?=/REA3KFJ8h8'rpt68PJsG:,5pN%PhD*a*bkD;KSU1/4QWl9/uIG:5DnjI`m]F6"XZr0dH\%#ehdg9cq4.lKm.;l-m,N9^+mR(2:K]gKuF_qLIXJKYVG?/Ra")]+AI-rgVF9^)AVk47U3S1u+Z)PI->WaD_LJbF,U*:)Ki->m54665lijOnQs7=0G+3FL/il3;4KcU"K&3%WQOtk+WioWcu3PG];F8W2i^gLiT`GN+&`,01],8_GYNh^bKJa:dblM:+qk("1fCkZP>A$+.P]7%4e!nZM^gX^&SCq^ro7)YpUO0mi+9`XWCf!e#k&PL^c,2NL)5)##"j%^-NJa*PA:bN[6%D3@mgAZ(UXVTWe"b3"cRJ0\QEBEWgY/)610YKR\Ah1H'(;E:*O0B-MZT"_q)Hq=O_endstream +endobj +27 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1742 +>> +stream +Gb!#\?$k9`'Ya=F39q;r2q=(.=jC;FRl5,mAI2RZE\V&,\/:^VVHJ)IhnC?2!s<^?\m?pQK_:jr=%>dL3J)jB05CJVCOk"MG]c<'176::]#9J?sIHlHJ0RmM.+?m8_i;sV@j+8B;4+oDEY$L%,*ZXHHpk4A<&72%tR,o9HT`hJ5eQ?s!@T1VI@'YO70>IL+$1G3SbbJa8-1H8TA@*oGQ8'K,0B%og.[+ZneT7+*J]S;eTOlXGCuRIX^Mib.bd5PfKoMe,E"SukLmF1\0T*7Qc73MA_hdeu(Se0d9Zs(MNr/.J_:;:f?0F89N=n8`URNI_J0=1enCp8rQm<0bHXELZGGUWXkaUj^"!0R+-UpQf`mbJ!9;5;1NK7WeO6N!JiLoY'W1C:GW&l_.;m-]aQ>0TgXVG[\5:;jRq4]8?Ci5W,/^J@J_Q4S%Wc8RCWkgC8*>4BK_nI-+kP\D_&cLOn-pbRC]!K:;9M@.1ZpH%UjbWd'Ig5ol>UF,icio$6XipP$Xoq!7`X)g,0SiR8arE>;5ro$m_20AdP?c[?Y/S2>rWC_=PH5Cgt(2BJ-:fdhMdnJjt\L5i:T!'B(0-,$ntQ;![kHLN^G\IF`qT,<2N(opMmHknQ+b>K!CompK4S>dlcN)2XNRPY'[%ZA',:ZN9@U^5EV,coWlTn[&@$^-7'q1Q"I:hXL5_>gij6-WbIiY/>3Yr,@6`.S^B\h@Z-;Q#bkl-#"=')B5eL^CqOYI:JqIm:BB.!,OJKdsW.Mf*JQmIBn[FF%W.dRaDG7(>gueQU`>,0cG*X.QuK9B>*>#rKtB[.=@[TR(5+pRE'WS1ioV`9q>Sk)L.7WIkB^4nns@E1MhMQ$bVTqnFjPQe&?:46%,X7ie^AUG%"$(4hftUUOT!lJF]I!BrZYuLf`%Z<"Pt[?iDW#Oa6tlWG+6l^ZtJfBf>t*p!kQG.i2VXFT*c3ahsuGEd.@Qam4,sT3P[&,93-2Wj]DdfNG+MKu8=(IJS9unf^fUa#V#lhT#5"m3I^:]H/.+"oW&%^nb\L"?u3D!j$kPQ4KP3~>endstream +endobj +28 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1847 +>> +stream +Gb!;d=``=U&:W67f_W]]`WuSd!<(KY3S^JleT@\KLX7:l;l0g)K]FJp^<@e\W2.9Q@>bMV7ui7Ss=^7[_/N$gk2ikY=H4A7,.I`8TL9&m!(/op.0hG5np!QRE6mO\!@"K.$#`2g-6?[,[6n3Fo@NYNI%l/S'UM=.Z8Dq)L<2nj"pbNBB23FEkrDn%<2&d+7)(3Ws/c;qF;ONu%BPZ^-4s.qg%WO'q\''%>B_hSZ_AJP)DS@H;3X'RPKA/O[C@meL@ANM=Y)W*l1`'ID3Sd>P[)dDU6XOi`K]u:*5Zgltm&u;;2Am($0fSUeQ\=&R97X2TT*^doGFpa@b1I@$FnG3L/je:,iJ\5L,g;YG9mhCrp_5WBeM1j_e^[TJ-%[jb(c2K2%<"%"p*nR(;*b1;OK0''/kX?nQN1OnpCqA:!o^"3+_S]+bpJF#I.PNj)]<_^"6M&Lo.ih<$?UDbd@Xf&)7Da!jA(RV]dQjnp)nr`%8hOcV$p'=CB+F%@'T*6BugK@$,.JBM98[HB*mo&OYRW'!TMLY8Q\aQ=Q+NR*NB#dpW"+e?+2eJT'2f*H"AC^moB_gLNa?I=)2QAg]B7)a&CjaN7mNlClGU6,aPm@%Muhf<"+RVLD96E/#+,Un`E>,Xg8XFpaFhV+WU$dj<;FiLM#Y7M"@F?WeIejdFIVY_3jDFPQIVd7Vj((m$7SPOW&R0O0!.W-VFG>5D(`+a+@,[!^"mB*oRdC_CRoHJu[/dH8'h)W*A4m/T^iTg'#e-K"mR)rer^sR0O2;inZkJ\3?fYh3&I2ibsE6YnNA"cR)kQ%dh&JfmjbH?0l/D>l%gi0N)DuK\8[m\ro1E"2r=Pb7;3%[IaB`r5XI$4=YT&gg05f5J9)1iuj.KVeA;II-JqM7`%-YTV0T5Ztr.1:r!Q'S2_#r\]X8g5R>?ptG;8`JFjNqE2T)Xtj5$?IX'%!GbUF8RJ)S0(*=B*Re"^,:W!9e&__9Fk_Fq[Q'H]>d)IL,(Ojb7:[I'[317Y]endstream +endobj +29 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1944 +>> +stream +Gb!Sm=``=U&:W67fM5e<:.,,ql'G0)`(ai!3?$G=8_*(@,V2e:!>^@L1r$a48j$W)[N(?kf$[)98F5m*gVkd5J`)GeT5bA1Hj%=p$IjgX2,MnF@Isb1Nd?3L/DIW9f)s2&M%eQM7?70G29Jq+&u3*cL5UL46h#soH0OEuB>Dp9rin9qcKM.>pU!7aQK?8Hf2g3`8-aN3sM[?JC2O=Fl#Sc?g.04H&`c)6#Zg^Y@p.+eM4*!+22cu#]-QU#K_7-@Y8Qpo>SB`r8lRqh>/\EFW.fTGqOto\ActQ1(Klfn>@H\QBn_[M=55%&0c=:S[]\f&hR*=&]kOYoPBj:]I!FU8<0k-]`#M]$j6T!9u@>P>SU'M9`=]X?=fYiBCK4W%1XNa=G@m4KO:]I3o;W'[lK+LcplElVm,Jh&b/!;V(fn>V1(ZK$G4.NU"4gA`)*tSBIMYpOB*34Fe+o:)gpt5"pP/H'P7C1rH\,^]IUMMiXD\f(MCW/P+H5`=mE=tJp+<0(YI!T59:Dd8N#:B2:isKY4(MFkA==PHW0UoYEl85[n?%u'O"(-XNpNSC,Q\`E]]^\Fh:sB>0F=C4gU_%JeQ_TmG15"@I'9b_-S?,C3c%u[*c95E$_A=[0%09T5t#hD?<&]0O(?L`Z8,m$!0>YV:>!U26UBB,jV.-<$-/&[1Q4`3TIANc\4%:9^K/)lN;/g?trt;","^ckq*IJ8ZK6rfSJ'-esL-14l>c(tjDW.1H"TZ/hV3K-t3R8O@kcNLPC/&`QD8.sqLtlC%PK!U5?^dd[df4h^X1Xr0r4lm)'k`sG"TPP.X=.J=l3UfiY*&nZVVqgfhGJI'VrnFf+osmQdgQ>&gjb6"@O_'dIcW-3:LV2ilmoj/lk$c2rg<"H*Os0JM:t/OW10EO`gRdH.'\8)5D"q5]%FPs#1&8GZaGo0QpZUs%^IY,%o;cW_5@-71if%',d92op%rV;,`:[ihqO==c;O*ZpOQbRb0$c^@DJa+B&;0NE:\*M#I$7@Y]PTM0CA3#F_`Y\FKF(g3`[[!N#tND>ihUPG*9m)U\[;OX$g\Kc\\MAEB<-c*,mnu;GN8_eP71)s,F/>\d/rEg8]FuX2\m,AVh)1(dIiAg7S[OJ=,hG$-kqF1a%sN:?;9a*E31cS/:ARN0ep6HPNamr901;eQMX\jP;6G9=ur2:j*9@H!TCR&!]hW&.#P)cmKYCi*9&jMR##7-)C$m@"!1U-n&dWcpR6mc%<;bRkR79UV%0V"#tG??U$,L1>YAg(0E!QNMr15Mj*=Mh^biPUFLkP(QD9K:7-?;[AB5*hYD#2D^ddMWf(H74[agEf^/k3&]?Vie4[`Jf$P$WYJ.-l6mIb9(JJHCKtOp$h+fehlUh$QBFubl~>endstream +endobj +xref +0 30 +0000000000 65535 f +0000000061 00000 n +0000000132 00000 n +0000000239 00000 n +0000000351 00000 n +0000000556 00000 n +0000000661 00000 n +0000000738 00000 n +0000000821 00000 n +0000001026 00000 n +0000001231 00000 n +0000001437 00000 n +0000001643 00000 n +0000001849 00000 n +0000002055 00000 n +0000002261 00000 n +0000002467 00000 n +0000002673 00000 n +0000002743 00000 n +0000003032 00000 n +0000003154 00000 n +0000004966 00000 n +0000006789 00000 n +0000008938 00000 n +0000011050 00000 n +0000012911 00000 n +0000014813 00000 n +0000016500 00000 n +0000018334 00000 n +0000020273 00000 n +trailer +<< +/ID +[<459a20e2e948bef44ee56942063a15ff><459a20e2e948bef44ee56942063a15ff>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 18 0 R +/Root 17 0 R +/Size 30 +>> +startxref +22309 +%%EOF diff --git a/Les03-Cursor-Basics/Les03-Lesstof.md b/Les03-Cursor-Basics/Les03-Lesstof.md new file mode 100644 index 0000000..b992bad --- /dev/null +++ b/Les03-Cursor-Basics/Les03-Lesstof.md @@ -0,0 +1,354 @@ +# Les 3 β€” Lesstof +## Cursor β€” AI-Powered Code Editor + +**Vak:** AI Fundamentals +**Vorige les:** Les 2 β€” OpenCode +**Volgende les:** Les 4 β€” TypeScript Fundamentals + +--- + +## Inhoud + +1. [Wat is Cursor](#1-wat-is-cursor) +2. [Setup + eerste keer opstarten](#2-setup--eerste-keer-opstarten) +3. [De vier kern-features](#3-de-vier-kern-features) +4. [Chat (Cmd+L)](#4-chat-cmdl) +5. [Inline Edit (Cmd+K)](#5-inline-edit-cmdk) +6. [Composer / Agent (Cmd+I)](#6-composer--agent-cmdi) +7. [Tab β€” predictive completion](#7-tab--predictive-completion) +8. [@-mentions β€” context erbij halen](#8--mentions--context-erbij-halen) +9. [.cursorrules β€” project-context](#9-cursorrules--project-context) +10. [Debug-flow met AI](#10-debug-flow-met-ai) +11. [Wanneer Cursor vs Console](#11-wanneer-cursor-vs-console) + +--- + +## 1. Wat is Cursor + +**Cursor** is een AI-first code editor β€” een fork van VS Code met AI-features verweven in elk onderdeel. Geen plugin, geen sidebar β€” AI is overal: tab-completion, chat, inline edit, agent mode. + +### Waarom Cursor? + +- Vertrouwde VS Code interface (alle extensies werken) +- AI features die Γ©cht in je workflow zitten +- Multi-file edits met diff-preview +- Background Agents (later in de leerlijn β€” Les 15) +- Werkt met OpenAI, Anthropic, of eigen API keys + +### Cost + +- **Hobby (gratis)** β€” limited, Tab completion, basic chat +- **Pro ($20/maand)** β€” alles, onbeperkt, Background Agents +- **Business** β€” teams, SSO, audit + +Voor deze leerlijn: Pro aanrader. Hobby werkt voor leren maar je raakt rate-limits. + +--- + +## 2. Setup + eerste keer opstarten + +### Installatie + +Download van cursor.com β€” installeer net als VS Code. + +### Eerste opstarten + +1. Sign in met email of GitHub +2. Cursor vraagt: "Import VS Code settings?" β€” Ja +3. Kies thema, snelkoppelingen +4. Opt-in op AI training of opt-out (privacy keuze) + +### Model kiezen + +Settings β†’ Models. Defaults: +- Cursor Auto (default β€” Cursor kiest beste model) +- Claude Sonnet 4.6 (default voor code) +- GPT-5 (alternatief) +- o3 (reasoning β€” trager maar slimmer) + +Vuistregel: Sonnet voor 90%, o3 voor complex. + +### Een project openen + +Twee opties: +- File β†’ Open Folder (zoals VS Code) +- Terminal: `cursor .` in je project-folder + +--- + +## 3. De vier kern-features + +Cursor heeft veel features. Vier die je dagelijks gebruikt: + +| Feature | Shortcut | Wanneer | +|---------|----------|---------| +| **Tab** | (auto) | Voltooi-suggesties tijdens typen | +| **Inline Edit** | `Cmd+K` | Korte edit op selectie of cursor-positie | +| **Chat** | `Cmd+L` | Vragen stellen, code uitleggen | +| **Composer/Agent** | `Cmd+I` | Multi-file edits, refactors | + +Deze leren = 80% van Cursor's waarde gebruiken. + +--- + +## 4. Chat (Cmd+L) + +**Wat:** sidebar-chat. Type vraag, krijg antwoord. Net als ChatGPT maar mΓ©t je code als context. + +### Wanneer + +- Code uitleggen ("wat doet deze functie?") +- Algemene vragen tijdens coden ("hoe gebruik je useMemo?") +- Debug-hulp ("waarom werkt dit niet?") + +### Context erbij + +- `@filename` β€” voeg specifieke file toe als context +- `@Codebase` β€” hele repo (gebruikt embeddings) +- `@Web` β€” search het web +- `@Docs` β€” geΓ―mporteerde documentatie +- Sleep een file naar chat β€” toegevoegd als context + +### Agent-mode binnen Chat + +Switch knop bovenaan: Ask | Agent. Met Agent mode kan Chat ook files bewerken β€” vergelijkbaar met Composer. + +--- + +## 5. Inline Edit (Cmd+K) + +**Wat:** edit-popup op je cursor-positie. Beschrijf wat je wilt, AI past selectie of nieuwe code aan. + +### Voorbeelden + +Selecteer een functie + `Cmd+K`: +> "Voeg error handling toe" + +AI past selectie aan, diff zichtbaar, accept/reject. + +Lege regel + `Cmd+K`: +> "Genereer een TypeScript interface voor een User met name, email, role" + +AI inserts code. + +### Wanneer + +- Snelle wijziging op één plek +- Code generaten tussen bestaande regels +- Selectie aanpassen + +Voor multi-file edits β†’ Composer. + +--- + +## 6. Composer / Agent (Cmd+I) + +**Wat:** de zwaarste AI-feature. Multi-file edits met preview van alle diffs. + +### Voorbeeld + +`Cmd+I` opent Composer panel: + +> "Voeg een /about pagina toe met team-leden in een grid. Match styling van homepage. Gebruik Tailwind. Maak een aparte component voor team-member." + +Composer: +1. Leest `app/page.tsx` voor stijl +2. Maakt `app/about/page.tsx` +3. Maakt `components/TeamMember.tsx` +4. Toont alle diffs + +Jij accepteert per file of "Accept All". + +### Wanneer + +- Nieuwe features (multi-file) +- Refactors +- Bugfixes die meerdere files raken + +### Terminal commands + +Composer kan ook terminal-commands runnen β€” vraagt approval. "Run pnpm install" β†’ Composer doet het. + +--- + +## 7. Tab β€” predictive completion + +Cursor's Tab-completion ziet **wat je gaat typen voordat je 't typt**. Vergelijkbaar met GitHub Copilot maar slimmer (gebruikt je hele file + recent edits). + +### Hoe gebruiken + +- Type β€” suggesties verschijnen grijs +- `Tab` β€” accepteer +- `Esc` β€” afwijzen + +### Cursor Tab vs Copilot + +Cursor Tab kan: +- Multi-line suggesties (hele functie ineens) +- Cursor verplaatsen naar volgende edit-locatie (handig bij refactors) +- Suggesties op basis van wat je net hebt geschreven elders + +Verschil voelbaar na een dag gebruik. + +### Wanneer uitzetten + +Soms ga je sneller zonder. Cmd+Shift+P β†’ "Cursor Tab" β†’ toggle. + +--- + +## 8. @-mentions β€” context erbij halen + +`@` in chat of Composer = context kiezen. + +### Soorten + +| Mention | Wat | Voorbeeld | +|---------|-----|-----------| +| `@File` | Specifieke file | `@app/page.tsx` | +| `@Folder` | Hele folder | `@components/` | +| `@Codebase` | Repo via embeddings | `@Codebase` | +| `@Docs` | GeΓ―mporteerde docs | `@Next.js` | +| `@Web` | Web search | `@Web "Next.js 16 caching"` | +| `@Git` | Recent commits | `@Git` | +| `@Definitions` | Symbols | `@Definitions:UserController` | + +### Goede prompts + +Zonder mentions: AI gokt welke files relevant zijn (langzamer, soms fout). +Met mentions: AI heeft exact wat 't nodig heeft. + +``` +@app/api/auth/route.ts @lib/supabase.ts + +Voeg een endpoint toe /api/user dat de logged-in user returnt. +Gebruik supabase auth.getUser(). +``` + +--- + +## 9. .cursorrules β€” project-context + +**`.cursorrules`** = markdown-file in project-root die Cursor leest bij elke prompt. Net als AGENTS.md in Les 2. + +### Voorbeeld + +```markdown +# Cursor Rules β€” QuickPoll + +## Stack +- Next.js 16 App Router +- TypeScript strict mode +- Tailwind v4 +- Supabase (DB + Auth) + +## Conventies +- Server Components default, "use client" alleen waar nodig +- Tailwind classes inline, geen CSS-files +- Geen comments tenzij gevraagd +- Volg bestaande naming (camelCase functions, PascalCase components) +- Throw geen errors uit RSCs β€” return { error } object + +## Verboden +- Gebruik geen Next.js Pages Router (alleen App Router) +- Geen any-types in TypeScript +- Geen inline styles +``` + +### Effect + +AI checkt deze rules bij elke prompt. "Maak een Server Component" wordt automatisch "use client"-vrij. "Voeg comment toe" wordt overgeslagen. + +### Beperkingen + +- Cursor's parsing is niet 100% strikt β€” soms vergeet AI rules +- Hou 'm tussen 30-200 regels (te lang = vergeten) +- Test of rules echt werken β€” soms moet je expliciet refereren + +--- + +## 10. Debug-flow met AI + +### Pattern 1 β€” Console error + +Console error β†’ kopieer β†’ in chat plakken: + +``` +TypeError: Cannot read property 'name' of undefined + at UserCard (components/UserCard.tsx:12) +``` + +AI: leest UserCard.tsx, vindt waar `name` undefined kan zijn, suggereert fix. + +### Pattern 2 β€” Onverwachte output + +``` +Mijn fetchData() returnt undefined ipv users. Hier is de code: + +@lib/api.ts + +Wat gaat er mis? +``` + +AI: leest code, identificeert (vaak) async/await issue of missende return. + +### Pattern 3 β€” Tests falen + +Run test β†’ copy output β†’ chat: + +``` +Test "should return user list" faalt: +Expected: Array(3) +Received: undefined + +@__tests__/api.test.ts +@lib/api.ts +``` + +AI: traceert, fixt. + +### Pattern 4 β€” Refactor + +``` +Refactor @app/api/users/route.ts naar gebruik van Supabase +in plaats van mock-data. + +Gebruik @lib/supabase.ts voor de client. +``` + +Composer doet multi-file edit. + +--- + +## 11. Wanneer Cursor vs Console + +Cursor is geweldig maar niet altijd het antwoord. + +### Cursor wel + +- Code schrijven, refactoren, debuggen +- Nieuwe features +- Boilerplate +- Documentatie + +### Cursor niet + +- Git workflow (gebruik gewoon `git`) +- File-management buiten project (Finder/Explorer) +- Terminal-heavy taken (gewone shell) +- Browser debuggen (DevTools) +- Een quick lookup (ChatGPT/browser) + +### Hybride + +Veel pro devs: **Cursor voor IDE-werk, Claude.ai voor brainstormen, Terminal voor git**. Gebruik niet één tool voor alles. + +--- + +## Bronnen + +- **Cursor docs:** https://docs.cursor.com +- **Cursor Tab features:** https://docs.cursor.com/tab +- **Cursor Composer:** https://docs.cursor.com/composer +- **.cursorrules examples:** https://github.com/PatrickJS/awesome-cursorrules +- **Cursor changelog:** https://www.cursor.com/changelog +- **Cursor forum (community):** https://forum.cursor.com diff --git a/Les03-Cursor-Basics/Les03-Lesstof.pdf b/Les03-Cursor-Basics/Les03-Lesstof.pdf new file mode 100644 index 0000000..79cc03a --- /dev/null +++ b/Les03-Cursor-Basics/Les03-Lesstof.pdf @@ -0,0 +1,219 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 5 0 R /F4 6 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 16 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +5 0 obj +<< +/BaseFont /Symbol /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 16 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 16 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +9 0 obj +<< +/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 16 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 16 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 16 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/Contents 23 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 16 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +13 0 obj +<< +/Contents 24 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 16 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +14 0 obj +<< +/PageMode /UseNone /Pages 16 0 R /Type /Catalog +>> +endobj +15 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Lesstof) /Trapped /False +>> +endobj +16 0 obj +<< +/Count 8 /Kids [ 4 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R ] /Type /Pages +>> +endobj +17 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1919 +>> +stream +GauHL?$E&%&:N_CbW1*nDBfo'OMnl?g[%FO]'\oDDYBdg"2V91N55nShY,QFKJ6dqFpRClcERo.0JdopB/C5)#=#TlNog=+NSqc[$C&A?!n=P>(qk\`,O:8!1X:[:KC):O%2d`KX8a<7=t07%joGi<84V<1Gi2/.9,U9.pmr$r5d"McgnJ0amKi'./ZI&Bhg=7g3FcaVZ[L,Oh=k^bUinDqH0lW`C&UsI9$eJUUXf$RL\elCd2^G\qf$ri5A*np7!De"^`R-jU:V%U(_cE(&mhW(9!X/nT>B_47aJJnN`(p2KYYR8deBaib%tOOHjlom)?T:Spk077B],t8Mn@ISJa[(/O+u9GptjfsKPt>b5_9MtboEm!3jIhqAaM:/aD)bEF`#1nWID;sj0gIO!0&m/"!c>5CITMK1S%XUZ"Cpg[5k@oaE#Xe"M\aJqF?Sjj/bI/RDpf0JM4m.S(5"hb&7H,Sm%t[(IF:rhQY+r`Jl70s:7Cd'sduM\-XM0bmPf,E8+_rUd\W+E(*r,Uo**cPO04BlF9OMl]CCOMh:l(BFU[ZG/#S!ppQCW8BW8,DO%!FT9[D564/jg[U4,_I6=,2j)n9nE;ZqBrgpNMsD=2WkroLk'"-C!0b2q3J\i!J6G*:7FJilN-?NKGEf2HP/IN\WhGnp#E<5++\r0$o`3W!oe_2#Wa%17HVc1F8d.$KKksVN@:#s5"(n@U,(pd>U*W>TE?%2-$%B>oIQe>CCB^aU1!`gjP)0OhAZcB"gEg>uoG#uI3Y'e($"0qI?uI1GM`[a,c.U'`r;HM^B,[a>+rhiTI%20Ha%h63mt6W07!G%GEG@P=)WWOUUefubMC>"C=D,[ZSu+F95$3TkVMf9)a9q"r$[@@EcN`m8!R+,7cP$rVBam*e$MlU@9(]n]Zs&I+>I0#9Yh>&310uEV0G@I+=]MU-.Do@Vg3M,l*sI._=s\NG+'P[n,e?i<*/058Pbk5Q>(Xn8j*S9D'2u+]C#fQ!AOn+7.[d&/3)'D]H:21TrNa\fRkM%ig2J4I=&HNEWacU%Ng+.nQGh/VS>OA)Vb^ALGgEs,:<=d'ehC/Op9dn1io#R!)+Omq,Wq[cVnq&aq\n7:V5\?&lD+%[gG%]1QDb.nDT&RNHE##dd-Iaq++Se/@)L>a-@C9HV.Pb>#^gD\9l8Nt-m.pQ.@2(@>:-`>7ufkU/)?s+g/fcSf+sPeHTE]'G\Bt)V1m#>4ZgdV)6C[hY-6'OL7qf"#f0-pCHN6-&>u1a).\!aai@""%3s0TBgmqj3K;L/R-KGN7ZrMN]npnY6UbGS&p2rIC\9^OVW8`@Y$HU&TG;#a%]K7Ns49Ze3q6=NiqW3Ujl:Fendstream +endobj +18 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1629 +>> +stream +Gb!;dgJSt\&:N^l\m.fAG/U[BHPJ1_Y`0fG!\Pq_KpRqO&qa4@l^:l]rqc9Tl3?fg8QPWg.X7?:Sj(u.:Nq_J:VX"-gReJ9FQ)_R!TVNI!Xl[Q]'nTpGOOR`a((]o&U6V,#AjrW4",ToN:mrRYnslpRmHiA)JZOH9#X+eK8HdiUm/MKRFUi&1KXQB*FU%k*KDc_of:44-Hk()a%PsZNGmW;2ke8N"=>Cf7.7&cRa%"s][8%6J,F;jbPlSO/hucDe`N=dpS47ruOf)^(3j'&o3Uj'hn9G4Mmo*']qNY]6ZK/8$@Hlh2.A,:pZFYP1P2qa`b>&8cM\o+?dTo\!)N;#C`_T!P4>OKE"#q?qEYbhP1Z?]2<%pSY&5=Ki?q&;ZW$LtlE`XX?Zi$([6I,9Hbj_g%&A\SC:%?qP335.M10g=5)00VMg-K\6m:m!<6`+([]VuN7VLR!p7jl:,n>pK>/04Q&Aa3,V(G"J.Y[;)p(ZS9"U8(^&T^"rj2EFa`dG07;uXSnTKR@Hg'K,/Pt&,LU8BBZ-l/a*Kkqp<(ic!gN6jgee:/rc_Nr5/EMM%FFK'F0b3BSjF&LNuJ[(9H$Y%oonS7cC/I;NZ!L*kXip+n2&J712L!0%4@M=2t2\LX;td#b\4.Lk/W(a8*n#`]-)Ofd4P^q%K_48+7[N_5?ss$5qs+':b*nN<^LbN:ZKmQh(`Oi)*&#d$IW7-Y1A[n[cqC(5@h^?j*GM;l(?CGT^#'%aX\4h>mEbeDL!.aqi,G="U10NK-Re>9%3XPG9,TrkaYTsqtl;?RX^.V<.63&K/LI8mD/]MBtACFPeIo8L"TSk3G*s5)/@VOZO9ak)Q:(HFcj9AkfM;"3ptJM3Mn?DpLZ?7:6fOaK9!&6F,Kcp,d)3.b9Zl9V]=NEO[9uqS),5>]*NdK@)g_#en7oi*'?]M4diX&eIs9R/L^9BhBFe2+]JKJr=)K#i)M>ol9)\%Sh1uZ&:t7+5C&FNpfgP^.,dpdIX$U!&E.lolN(Oh1gA\:_6j5@nQ0[L\CCG?UV`Pm`']_a@@c(%@5dcUjF$JJE(>X85&;;VC2LeH,nA8h!]\')mh]ND#F-&kofu5";Q-Kd`Q8'A@3+h`)Cghu[;ol4j>+Dhk5E;aoF8~>endstream +endobj +19 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1971 +>> +stream +Gb!;dgN)%,&:N/3m!'jU2mEqr]P"+j3mOR>S2@3FkJ])"[A#'HKZ]5'B);%'JGEH""##H=uJ(`1JD-Uo1el[Gs'0`G*q:tT7^ddb]>A?4O-(8pH[(bfB"XG#ihfb%a9&(f<^!QgibgC`d!\-6I=-rZQ7*D*oGoI'Ki!J%6B)D^M,I/i/L\$=\XelgidNOcJe91YErnkZ])/F-;p`1H^SA#.H*l)(J`96'jbB"(RT[__^Q"dWWcRi>)l**3,WrgF"E2HNpB8##'#e0@(%EW6k%q&jd68DCr7IZpCU*ZKX"tY=BK?*eZ5tFSR!Sd=%&O^I;K2!@dgsqpOIOCFmH\d-Y]=b*GM8$aVN86I:m87hdB8]3UY`7mLYr+pXdt4':G1aZBjR-gKa!Sc/Bca#CL&71E\*\Q%-RK9>XdBe%DTJ`V8LgpR`WBi/0^_A$1#F#6dPnu2??H==as7AUQ\CN0*Jpl9PQA"XQ&%9LM1(Rj7Th$;23,TAieVVa*(6XIMq3,!'Yi#`FMPEL$'Q&hOC4M\3^(msq!II!fs"_Xr-X]@FI0iJWQh?$i](DD35VOa3EM*EgOSpCAY::Tl??<28J%+NqOje9=!&*2YODodME-h!""F$Z\.18Rea`-7!QuV,Bd7'qo.$/:`]E\#'92B`N7;5,_R46!D/cP-G0i<.H4hh-+18^]eMVUJ`J-:9XD)jtL3WJ%0sTpOF$GR-_n_D'&l,=97T86HGSGn@na0[#Yo$pdoHV9DF<5%"[_>%l,u57V*soYUOK[!;sVXFji-+3CV&5Kg[CD03k[20ms.Skp!Pfs.FHI$^j^g3j0/^&)[C#%p#.YINolJi#Ko3FtQnXaB0IBh*CrYRZs5?R&-(2c?V1XtliB59ASmCK*S;hp0Wo>5*(0,`Qf(R>t;/l0=L26)aaRaE?LCi2d95O)qkXnSdXc"8+:Jio+dZZs'M;BrtZ5qia']ZXAePjAqW5f+MRA()S@X"DkD=FrU^!35##rguE]=X=%g_VOVO&=c7[Z=VP7C>s/ZRXEch(jVLlDYItqI7XpA_pq8:_[i)1;!R--5[8W\o[B4E7I#BuMNYDtF1@9q*#P#57#;'eFJ_j;X;PY1J++G_4HPg=E@P0nI$_;HEY\8bX~>endstream +endobj +20 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1727 +>> +stream +Gb!;d>B?8n'RnB330TcUUmDW(69sGVm^AV@[_$Bjnrae,+$1b'(1a?1YMURU0m;mlp:?f/@N,]NF2*+C%bUFBR*R_oGSS'J)[@>ed0(G,EJWJfn'TOt7huc^k8m`C@(RQa.s1G+<7@T^4CO).Kan6oDZr<0*]R13KE3bfkPL8M'uK%bOTUn&Cd6ic"car3n_h&q$-%cY[lbhNp%,;5JJKoG6n9:7ft<+Xm;Q7*3iXgACrc-1Lb^scnFu#Jr)$.mNc0e!KeKICpdW(W@m6Di^i)3QZm`2*$ILFncSU7q;(_oJ627KKhdKfk@aYh`7o#7Q!q-`r8/>H,&?HViGD-cV2CH\siuS^M\>JO.lPk?+>%*>sYA1't:6CJj`>"nriH4dJ[i8+LBB/0)[5So":L:3Fe!I!hPR)P1U*h0276nslW`d:Ji\W*l]BE2ug_Ys2D+JA,mdOJpkkj3ObG>I6E^>hOp/W6fPV7m?X.rGI@ld8L[&%HGZq"q,.Ai"nO6q*Xo4].(A%7)jB942u_0l/G(Ful1JFp697c>34[>Ac7Q*ufb+lb"'RNStsfpZ#Ig/mH2Rk"lYOossOZ";7*)a)rO@XNWFr"a@T&1^#i+o57!kI=,V"\Gl$R`H=S?51Z50/[Ui:dH]iHi]VV,^f\nOlGm5O+1F+Hl%^Xn&OFJdSeXA3D#oZLl3uk>6A`aNX'uU:/ag:Y?SLm_j@k5Npgm$dWI+eE<<&YCF9pGc7u0:^/&X]-^:u:-q_!m4\*8.-r[e5b*isnrd">lH0qEbCPjX0lD0N!@U@=ERP#hdQ'D*SXb?@W3rVM^p[]N)<0e.";Q,g`^#@Z1q=ag@H`7BE2G7%j3_:`SE1B`K\)"r-1B@$b>$l!9_!<0p$Ru2[ZJY6TbN6UiibmVg=LV_KcU?qPK+D'/R'8X!i!dm[L8`^n%XE'mFF^I$h%O@HP@g;QoT`B/f@quU[!ocVZDnWPhDh(!<3lo`Ge`YJ?.6t(k6^"_>im/OL6%P?U`NoRm]W#IIoTSk+X=pI4FjQS#+:Bf17*"'"+(Uq,FN78K'gM.O3Sa"fb^`A/K=;Q&t%bKsgOAa$2.3+?Yq57G_K3BA]YM][I\FLZ,g1RA8?%9,?OULH\Yh#LtcTS[ZB1-83M9H2&AHJc)%`fq$4`A^VoDlIVf3Wj8W%-]Glb?GrdZ_VAO-P:p$q]n+ujIIG<93G,L`B%sY*C9rb).jau,H=^)i$6ha<[uOXc)Z]W!E%#GJM6icJ5LuHL^*$YY:SIHkFDdSSHfpFedj)B=dE^?UT4=i+S1T1C6dSOO#2$/&B3<&`VFt?l[[cl\B0J*os]IHa"I&MZ\[&tI?Sf7X*P=Oq#F.F]i$j?$E>Ap:-?1@0OO0R62jPq6,kXFMC'>nT[X2U:adZ0HuAAiH(#cb^]fZ%#K$^t-SHhQp8_rC^uY/3_:_!EdK[_AKIrNmq@S8R92&W`E$Adl<58'5okHCU,[\YLj$_o:XN%3D&%STm9&AqjB0!gm=Rnj^AV>Y5%8\gK@CP!9adrqk+^8>VLS4)A8JT2b6(pc"dtIp$bp]:Wk#]cP-0:@`?!14I>c&8VJ"#Iqk%1E>lqp^`O7s_/@9fJj^tTV"`Kqpaj,k4t#<\Tqr^/VrJdYlr91iW(/<6n^;~>endstream +endobj +21 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1831 +>> +stream +Gb!SlD/[lo&H:Nn1$TPV>dsF\?E]Jdlc.b!dksjofX!B[bg+D<[_]hI?%,6l^n2i2IVj^3@5J)@,qb/5_Q2)#f)n>Woj&)a__!7/5Q]"(5oq+Yi%`(M)VDhWT5`ZkQeR2bJ-3c5^2Nn1$^a(=Y^uSno!o-]gE,DAc?b7"9$t"=4N.Y2m\KR:/R*b[oO(!"=apXJ!.:mIr'T#L^Oi)DTMb1XGQ_j8`89!`;IQYY6N'sO/9VjA]:WZ(RG".8kmTP:"?)??MpZAV_i0r;`cF[X+EtcO/\O-V:n/o2sPoYOf$(F]W!M*q$3%^oH$^kfW!@MSrDNNV^BLh_0*?;;Su9U(6X(f5bl;,JcTfesOF*>)cNFa`Jf<.[i!;?fiEeJFKdR?F+npAhX!2gS=[r>M8IGM3^Ygbf"gANsAZ$?=a`J#.uHACr$(U!e9">A(t0637\FQ>F?@-="9%q2AP>@3D*6b)P8_e@5aB*9]Q9Gt&ktJtYdEA6ie/MG,9%R_DXdS2l/LFS^AEQS\U<6UTIqXk]TkgZnA&*B:_!HA<#g@\;"o(3*UA);fWGi#/4#fY:Bf]/M$uV\LaXi8c:TJqttdW2<^n1+g3`A'@[#cGO1b%7A,bC:-t"]l>7?oenKWQa@r&(Q,p(a+_bj^+sc6YD=S(-N=@a7I^1gmj+\0MOWq[W!-8n$2VL7>E]%c`b:$Le/,C=qV"4&7HX)HN:-]L;Oo5C4dp&VNJiQ?&5"3e';JoosBNia\UHn$;?1RlFsLpC1g?jf1Ri^R4Lj5%utD@n9[2n8Y>snb$TP93H^3H.T_@IXK=Eki\,[4E!UGY*LmAakH7`IRc?@Ni7$?[n_guqpuuXj1HuNiFq[?7=bQT7m:6X66X,*`SV(QI@+m5S/6La,\=ti$E)Jhl]V!;Gcee)oVLM4p"qIIT+ZC(gjDK<>_j9gS8WX)Bcj8k*reVqVTcTI'\MOcE:>NN66#I~>endstream +endobj +22 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1936 +>> +stream +Gau`T>BA7Q'RnB33)aFE^_0Y1jkBknP]E='=eMHaI;p7GF^nWY=_WGXrU5(Yhi_f.F_!tYHZ4OBr`T%O4&dC1O"H\H85nr*6mu`-A<%WnJ"S)0VXaQ,Q\GSfj9nTb#Tb`p`piI1'sm-L:;/W<,7&/^nbCB:O`roG1cS93J3Ye;n!`!Ro(i_1kbu7-HrKD@:k?le8:+,NM4Tj])AuL4G=%_+m>4>I/oX@$"KLOWP0)=WCgoqTgM42EW4C-fI7la&%da(cJ)Tf8>]HW'**kp$iOu'f=]NM7Pk7B\4&_O9N@;U:Rb"`&r.PCkRSFh:,ZUYFqiQ9/4;uU1iRA*JDg+=$!(.0a3$jD/IT0h@+n2U[sVK,Pu6(IJ?E"m-9k!W3(l8KNZQY#9\C,G[][]odj7J%[0nAR&nR.TiPqRM5fH:Oj=O'odZ@U[9^;U!]kn(7m`8X-h6V1*5cJ`f]bP!1'8sUOO\`To#cJ[&tC96>&'EP#3HO*Q"=u"aX_>2>+2k%%,#JmpM'<5Q8?5"QdGO0ek_H#o,6Y\NR&Z.]sS^\`'t,-oCh>gm@NdbL(-L)_:H-6=4lB4J[n.7ED1nYCL&Hmf7g;q*a39#+]C0g_\VEAo!)tX.8\Q=(a5DeF-?s&9Rfhn.a#50B_W#ROn"r!iDg#:+M#)b9\.?o2%t\)jo_'+H*)'gWGd)n6R#(MAhL]^O/7/+ls\TF<4TK5a8m9K0r*^iiJ"+p!;q9(Oa5UlO_Yi=GBGoUb([*[^BB$,b/W]gl/nSt+tb7CU$G%1Qe&Wca7OGQjZBIk'5&)bAOl#O7<(1E"QkO-ColhZM_(H&DsN`I\*A9%7%Z.VbU"6.@`BI-?eY2i0So9Fm\kWC_!Wk$n0+qUn:3tY%j>ijKU0#aE'50'1ISa)CK)pcMWT#:#9KFiG&BTEEbRu+g7Y`)'t%YHsLa/Z_8Q-&-ZJ\kM[BLk5*:8GTloKPeR;&,\+EAT50F^^lW!R:j>M]>e/&6T?%;Qc0N6`&pj[RU^K[%"h^_Nu$0?"9Ge*)W.CB9%U;m%=C2sDB#gJ`UJ*C'`J+jZ]ee+%R25i-apX'2@0^kc)K2Km"Oa(,fE-c)>qd2Y!%o.@U>Pl`7VKj13Dls&8b:32S2QRF^hS#D7sb-nbjn//#T@)D#UWm7<[uNiYL%u@J$h7jc/YR/\J+hskjjBbB=?WKUeg,dT$+Z6uOp;t@e)O6/@3;C8ST#MW52uMl.%Cn"%OL''f=VNh@937Y\_'JTA"l@Q*P7NMdJQ:Y=(J&(;[DFG^)ogJ\J^M6Ck_-n~>endstream +endobj +23 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1809 +>> +stream +Gb!#\?$"^Z'Rf.Gh!%IG-P_pu96OXMh6c!]VVA;NgD=HWMClW[f[L\4fjDKq[ZO:Q"Hr._)_tfSFMDqCnWbPJpnIG.]EJ"X%&;Dg."h%(-mp"Sn)2`@n81FX@$1a[r6Y$["sid,+-a)t%Y5`H@M+=@P9cA4GXtCC7NjHj-RG$SC7%1*:`rY\1?:\e)Mh5fYhgaZ0m(Z3+@Ltt45R&oK_XRMZ^Ycnt@]$2N?5+9)0r9on"t#:#GjuPUlAa)HPqJ]Ep`.:LXb33B/j`5taBbS0FB+`c$>qF$eqPK!6,LFt=S]PDd/<>Zi;pD/l':%a75oQ^*3a.Y^g6,[Su0%nY"/HAqY&AV#=',RWHj%t&D+BG^^)p93H*WJrd%bnC0q8i`:1G59MII0JQHXp2+,3W,)4k=8@NB/N1'cCob(kA>b6s#5V4h"\e_9@#-fBdr)ZBg!PEAjg0BeVGIel59*;Mq9S`Cu6,F3`FM^+i5nN(/dkNd]@(J#0Xhkr=rr^6b&<1A.3;Ah>0:7`U*bdu"m%r(9C")C;A7GpmtHCS#tBS_R7+5b@3*Y@;Rd!E9KP4'(K1KMg?50qZ`O]nSPNn[;&-0-a/pkhZt;tu(b/CWmnI<5u:F/ZbCSZeg#/^k<-$#33r:#h\=PMo!1"kHjWQ[(\k(Fh:EeS;4gb[GIU`o=HhE<)VV`;?8-'L)C'T?!L'q9P$`^\p;#/QXjTFgYn?_\f;![\#sf;Qc2.$VS_<"u^'>Qer_C6\VT1s1f&SM@>>otVIl,/SUBZDKplTQjG\Mfk>mS>bNTZEuBJ&=Y.*H\?'&o3QiPl.G4\(g`H'\ss3-SU:D(3]?o;A"@N(l3#e'^:kVbB>`o1Vj7Y>l"QoHGeI/iqbhXOMI)A0^j!<&Qcb^oeY74tHOk1J=Q/)>n+!<3'lV%UZ_"2L']o<:(q./MoR;@W6V&E##^Due_JZ6PO/S%X'VB!#MnkLSdN-Utt#H%)FJ!rNPkA%E1+E+IId^4K^endstream +endobj +24 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1122 +>> +stream +Gb!;c>B?8n'Roe[30-h4&Vu>VH/%K4lu]i'/DDPe#V9J#5ctZlq=cCW%Sd("4?FUfit.9JF8=+*oGn*fWIJmYN&#oZ!>ma4YQ_iMY_*o$^;+kFq`."ZYrp&1A5gtN/O7$U^HffF**e)ODtt6Kkoo=Pi)#@\odO"scL\7FP/HS&$j6'VktqZs`@dkFKtWJ%Aa.POEXD9.gNWJ@3^"RI/j#V9qps'b%buWhH*nZ'@b5ZEaC,#?YO?])=i@t/ej?2%O-2V/.p,o>#CkOF'n>/@fQ)6A_%-f8e,]bK*C;UdipAi+_M^a;a6"c81cmR+Enr@@8O8_cDX:4OX)&2rmUaNU's+<(JVhn_3V[Gb8HY$ZEglVKF^Y?ZYr1#`g8mWks@rC3p'F.UrQ;cEQi>kIU:1XN3!K@#[kX6]A7bKWPe9NepeLaDFT-s;`!CPC9Yr?LsTTj<"6h[nRdRQ)9&o7cSkqDSXZ?[!E(QDV;[Dl<[`aEEADfAP0g%Q/GLhVO<(a%UQ:ZZ_*Ic[#Ne.;'<,&G-uAc9L=!l!o]K3U=)eko+%\U>k/m_6?sT>?i"7]o&Or-]1;M+V^h3f;B/b/;+aNWg*GKa:6,*'-$4lTt_;pV33aA$:A>hR=_^)$rek@BFGbOLHL!>&nD?#JomHT,DhD'&&/d\S\2pm!_-oJ=X]Z_2ImrDfH;mnPf+Yj:8R3>H6ba8>bk/;/j3#M,;3-XAnN&LrV\HDL>/9K3G#IMW~>endstream +endobj +xref +0 25 +0000000000 65535 f +0000000061 00000 n +0000000122 00000 n +0000000229 00000 n +0000000341 00000 n +0000000546 00000 n +0000000623 00000 n +0000000728 00000 n +0000000933 00000 n +0000001138 00000 n +0000001343 00000 n +0000001549 00000 n +0000001755 00000 n +0000001961 00000 n +0000002167 00000 n +0000002237 00000 n +0000002522 00000 n +0000002628 00000 n +0000004639 00000 n +0000006360 00000 n +0000008423 00000 n +0000010242 00000 n +0000012165 00000 n +0000014193 00000 n +0000016094 00000 n +trailer +<< +/ID +[<3aca6d13cd74b57d5c4397c35a55e608><3aca6d13cd74b57d5c4397c35a55e608>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 15 0 R +/Root 14 0 R +/Size 25 +>> +startxref +17308 +%%EOF diff --git a/Les03-Cursor-Basics/Les03-Slides.pdf b/Les03-Cursor-Basics/Les03-Slides.pdf new file mode 100644 index 0000000..cd809d9 Binary files /dev/null and b/Les03-Cursor-Basics/Les03-Slides.pdf differ diff --git a/Les03-Cursor-Basics/Les03-Slides.pptx b/Les03-Cursor-Basics/Les03-Slides.pptx new file mode 100644 index 0000000..0e1ad27 Binary files /dev/null and b/Les03-Cursor-Basics/Les03-Slides.pptx differ diff --git a/Les04-TypeScript-Fundamentals/Les04-Bijlage-B-Huiswerkopdracht.md b/Les04-TypeScript-Fundamentals/Les04-Huiswerk.md similarity index 100% rename from Les04-TypeScript-Fundamentals/Les04-Bijlage-B-Huiswerkopdracht.md rename to Les04-TypeScript-Fundamentals/Les04-Huiswerk.md diff --git a/Les04-TypeScript-Fundamentals/Les04-Huiswerk.pdf b/Les04-TypeScript-Fundamentals/Les04-Huiswerk.pdf new file mode 100644 index 0000000..078fbde --- /dev/null +++ b/Les04-TypeScript-Fundamentals/Les04-Huiswerk.pdf @@ -0,0 +1,181 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/BaseFont /ZapfDingbats /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/Contents 15 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +7 0 obj +<< +/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +9 0 obj +<< +/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/PageMode /UseNone /Pages 14 0 R /Type /Catalog +>> +endobj +13 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Huiswerk) /Trapped /False +>> +endobj +14 0 obj +<< +/Count 6 /Kids [ 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R ] /Type /Pages +>> +endobj +15 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1944 +>> +stream +GauHLD0)1+&H9tYfREF7Y)6NcM104mbr)'#f,%dYh+WQ2`PKRP!_tBDosXuRYT73>b9ZeK+JdhASqsBpLEBQ6b(I=lN%TTMLYd8K_^7JlD3A6`".+.5Z(+;FMUt9-l"/g\5#XC+kL]3g0m7B:Si)_.-C?JhcVUgcT/"KM^[,N0TQE%SriNEs8+6jB5Jf0AM,a2`<1a-Buu>3farP;.`=3.uh![,);m1$2ujSRu8.QauMBjmODX;EIlb&1.,"\;'Nq(0#5>.k7SS1Rd&-PK(0\lD;mXNXaQ=O%3Bir=$mT+_idVER_H!$gU7dq11gBk$e'6`^!pHNZeY)7?*$S3qs*Ti`$i5ajZh*>.p^G\quG!VKQ\/&o$.58>(@A4hnYJQ:5Jsh@m::/:oE0G#"`%=001A(UKNg"^fF'++S]S(tkTu:(;JM/O@L1VJ>(h+^,Q9!6IB/YI&Y&^)m5/)W0)Wl<-S!K^i$6R1?YgKf$Z^Hhg_5e2kQ1o728u".2'5t3.Y86=\;79Tj4OR'](T#[j!["c!*L't[:0SKn_Se^`(([u-EIAa[Go,:(L>9qF>'P'?m&K]l)7"j/ZqqZ2?0/,3hW1un_'@COcZ[o6RBaAI+A^>C&oQ95N%:IbGZ*p)jdg2o'p!j"4+hO]Z&-K"hfXbCSVFXGkejG\702WaPC9&o4J;=EgD/45Gk-[#!R\C8?Cg,$%Io3+=3Fp>g9Vd^*L288!!\ZIbf[ti''jb29:H%B>19XaF^Xd\!qRtT99UosCiaBIU.B(oc'f)[Ad&B.HE6X8kN!dmmOZ*^;]+h>d9g5L[.Gopi<,V1+6T/ti>bm<\H<lu!;t[HqJqRd8B7VQ;^ib]jH]])?a^9j:U6h_aV@dFXD>8$n\!.!X7Hf@mc846O$]N9TWg<`(2K,qO$S]A)P7U'/qePe%(g=k8^Dpbrl2BC^f#DZSa[3Lp7h+hbA?npQ@r*FMLrT0[k!09^fPAA]EjSh)5chYW_M)-@G]h.;30++Z&6IK~>endstream +endobj +16 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1939 +>> +stream +Gb"/(gN)%<%"7kOTRKd"%P;!T;LW\%4%Yo"8Y`XK*Bf'&+ds%Ob:]-%jlsf%bDRR$UeE4t;g2u'I$&T/`;sq.ZdtgGT6gLmT*)_C_7@;G;(D\;WR&RMg$#?t=n]crPY(lURH]aKK0QqEDCa>WBC>.04S\n/RZ[/G(#ZF-uSjn[ltQ:nQWT>@F)pnq8P,1U6#WP^H\ojcKgl+(_X7eW*9bp^=p#e_;ljr>].AkoPRE_WaA5>B>QX1^[So/i0L))0AM/_afQS(>Cb]>"rueKN]*lPJZJ_fqA#?UgDL&0X^Zm]orH`":U\c]Od+RU;mM(!9E+PR'Nd=47a.U.7t6nD3*'7VQR+OW"og(4N%-PF'O7dq,V/.+43iZ"#6]kIiD(SJ^4XETeO"GKkmKSDN*)XaW86pi]e)XkJ>ega"!%Un3r9KFlN4M*m1hCSg`7JEDg#9R`PH.E_a;t))\,b(I`%8T_GW@RU'kbG>t=8+;$Il7+=COU47.Y:.3jr?"7,XW"c*c65)H(AV((+j^bb$$0sm=0KUCch2=[fL0aCsju'&"r!b38lg%2C(-;_J@d41a`ThurB1ol$:Z$Ql8-Ltk6&?tf(o?L^6i[:"-h'Gd2S"OXBuU\\9jY%)=i`V/m?:$6djgj)pnWLopLN*$erKd=M_(<^l<.-c*JSid>9Lr$(R30qqEs%a,dN@!:-1uro.()GUD0Y`i'HMKNZ-IG)B*a@KY:s^g>NQ=WogcjWlBNpWP0n";i0$m6pCS=l(*oojTuYhlAI'Q&SE-G/!LWqq?#5@P'D6aV*<3B+]S;,+JJ:eaW67&nPTZL/nDmeO;sn$E",ZNrfrT?UnP$:QZNB9$2SqchPn/%6_dJ+,T\^l9XVLrMUVq4QO"B`Klh05-'+!hpAgDjG`7S<#:0^A[`tjbK9`5%gmF90CCAH9ul"4M2iW1a6DJXq?]=J]Trp6,WVP/pMno04l)C\9H]VFoAT;qp9&5WZ%N?(%>eKIQJ"2ZUb>K?2!FX=0D5aHHGhPhVjZ']T&PS<1'jNa$*&^cgE_lP]hZoQHcV`X]8qD#HKl12n^Y"+Eo<0Oo>k=LWBlPemT0+@Pj*#E`d\hQe-;P`r6XTK>k1r#V[DA:\N<(`j1B2/QGg+`O+fD=lARj)?T.8gV[X]TE8iEYXC683%GG)EAK&34/hLgB8d94EI;?3PPB$2Km;Ttj5Du].pA~>endstream +endobj +17 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2056 +>> +stream +Gb!SmD,]1Y&H9tYf^_UELp12:an.qJN'fr[Y>_?i:7R_WUpW3e5.T)J#29(Nm[[n-[NsUX99L1t@rZk)pZut5q]$Ankf_C=_\p8C!)CfkY\Y/8^iE-c"u"s2i8Do`e+RV8m=OR**N*P&flPXNdd_m=Y%N&D]4XFVn]ejn_$qqO#^QO(AEWiU%k5BZaajVmmreQD"Z*Bo?JsB#*Rh?3>1tjGT%@2U0Du9CHTfh.]d#IoDjlVS=QQE[=WQ,\=C&ZLK,GN0hu%Wu09S&%iFS1jn6Vt/?:l'g[L^\:TT<.k-Z_tB?nd/J'=GX(Uon?uT&9'>-[h-Kll+>e1!.H,u)#L:<-c?JhThoJmRU#gaU8\V#up_r56D(J7Nh];PF0-=P@@7CNek6NHdU1):1$S[NX9PGchW@cUB6BAe8s8$,UO#99;,&0hl7.:0X'gGh*>:V<'f8cc+UF[\8^^H))5L!pQ[#QRh-rA=JWq]!QHK)>VVp<.BQIcoMf]nVJAC;1/8KEKM2o0TeWdkAA5aIRI5ipLD_jV8b)K]6U$JdoBqo@o0)i,&2aI`++Y'/C%9#<3WaG-7g2MMMEC\66a8jgIS"q/3@6?nb@.4j#A3g1':-mFPt+oDe)'[mW"D"06ljRYB$oQq>,_['b$727r5,=3_DN+;^k.Dn4DJC`BSg+Osnc;`B[e,t:4(i9@EMf(IIB(HjZ'4^aA.sHbS2=Y7i!r9AUfe@EPcB02l0*eZI[OIqNrn:'V]qd]NbYN!omGmU`M&/m\Ai/<6M1F1ocNhrFh-rL(<"QCiA8dCJ5('G'-[7p0kue^q;-YD-F]1+knp,he#H_[C3\Np`#"YdW\31A%]NEodj-5c_mih=nT!rq*m$>dSQTX,%3'4j`J)OY6IqRTME4[1g5*mN`MG7D$N[.k._a8-[;BAcrK?gD,?E1Mn0kS$#T_j7gl/>7hmWST=8pceu1FDuua+oB^*R44&F^##u#&?,_M%6*;#U*KkjF/Smn:S==bCI\EJDelFM=,>uW:^Hp2%&*ZD!7>0mO.0q;/;)1`i0l=SsHSOXc65hYH$1u#\AT7V`$sO_;as?XSl(j,L6"*iaAR-Y,T"u9,fYY!ZJbYJ*iV.2j/O`;/1fMqP6_u>Ib.ab:%J*0HE@E'9lR6idpr&N!tBa+9t?!^LpBr.3f2Zs/:7'\q`e0;Q5eV_A9`H8Is4cFhU_[M9>RR9$pp,S*Qpo8hIqK*W_N-l9bp/]XkAedcSljKG:s6Y>B/Mrbgc>eJAG^:-db+4H$lUdOJ:2*9+r@XFh':Nhi>e5:i,DP/YeV86Hh4,a-jjfFLOt?YEsS-lMa-AN/(-0]t43W9Q1?M"bs#Abj59]=jNsFG3eDRk4J)3h&`oL4'REe?(ffk?iAH=i)6TJ$-(FA<8VD3;:mghc18SdIGWoqXC'f25fUir;endstream +endobj +18 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2026 +>> +stream +Gau`TD/\/e&H;*)EUA:m/M]ek.#H*\/8^`]^sH/l+$/kC,1DQ]=`c)A7C)6_sC1oI5^mV+j=R"pOKcjEC0pUFNkokeKb7C-[s-'$Gm+*#WQchM%H?\L2oRF"4.[H:F?iIi&cMJ5Qpb-iU=n#`+KLFk/?lin@!^]T.oD]`36:11TNGa_\oi<<3+R2`1^Mq_/'5&f5EjdJsU3uoCtYO'L!:9`YSg&)%5Bp'tfW010%PXT>9e+Al$YQ4f-r3`"/AG=6[m`ahLH]Y-bj$<_4&-mqI$%&FS3d:nJ$>i:V#$Id7_B='CmDB@g16\!JPFjLHn,FTG+:nKF)WM=VCZk;B9:b;,!66tO`s1S%=*6>gc=m'"0b?nJQXb_KB=D#WLkfuis#N0R`9mHiZ2*Vuj\JfflA'D>jMp;r'_q1k3fT(Pt3CqPmu4rQl$ZU=N+jh>Bo(nTYGm=^8,hJZ\!rO!8r02MjtOW,$hW!0dG6%ee2\Ykc!imMj5XYEXiPu`^\N`>1\^grMa\c7`ba0`2uF+#3/Di2p%<1+nUFNF(rc4L`/ur54*;XE>ZT5%^\=YgEP[UI[bP-eSk+KadY@M%#Ja?j0T.H0c_B\gS#(TWrBAmcD!)D"ueGed`OMX!n77T7REG-M6UoflUClsd&!3I+kUEoJc21n_\L-C=Z]0a>=-;6C<_E8eK@5Hk.:gHJrA*Lr(&h)BA[C6l7EOZ\S7mo-\T!VunB^R8gc`1aBiOA+s8<%ZKers8Fg(@<74er``![2kS4.S.)>:[^j7s')s3a6CqDE$Cdn`4.gDdCSfBpW'1Xb.T;l@,_qa,kt5@M!ken[Rm_Hb8e]4BG[Z<@X+QHCRhGb^DOS2?\F7sm8"7C_'A_+/,8TM[=h1QI]^rT=DeqXl_-o@/A.(f"<0Er)JOL]")NDu);e[f'aI2s7,S54)"/f<9/Cf=Z0gE+0e?7FO0&7VpI>`Z4f%3EemUe7-Rn_ElO(DQPEZtp1$d?3.6>=@C+X*h$r=;B/Pif":8c>#eiGK\L+_`sKoML7)[a$eJq*3#'njL_*,@tDP/R`,V=:[4bPR4BRA_7>S:i_?@!TYS"dKb['=W7?4o)u'Kr#WC4D4=8^V\mHU."/8f3/Oqf`-:tr+P%/EYJk3qJk8n^H\D:'rSLB0^uU!YLendstream +endobj +19 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2010 +>> +stream +Gb"/'D/\/e&H;*)EQb8]=;d6q-n3%fXA,0rmJ=-"*AA05A;Ra_aHT1d$/0P%I7NSA:2IsG)?frA]]b(/*KSP&4ZnmZLVM>Edi#rb+WNVB5T(!N5WRdWHj.iNK>.VD#o<(3L`^nkb^dXGr;e\lBF"_Q0oIJK?:^fP"-4jeU,W4/Ea_L+0G;Bd"r'TV]J/>1+rZ8.XN:9,0SVr9&dT(VQZ)8LXEcN4X`\;ho7tJm#Akj=C\9^XBFkA%SAG3j2]kiR759p93\?4/5#b"KdgA8n(;_^PE$R)I?Hf8A*en;]Ht3Ia;T].h,4raQ8mg)J]ThQkdIK2`.%NW-Uu<=\fVoF`[4>dH7"NAjHMkE4#l[=p06R%34@_Y!4(Z:_5;Rk=7c:+(3sV<%#,VR`;sUegZ@q7N:O`=_no>#&Kup-6AiR7\-2[1D/i@/P.Toe+<]Q$c%;e&=lZRSh^R(jr#:g/:/2JRq:F]?:7H)3hE$i1GmoQ.EW-234gVH3$21_H$Lu$B6G(mVM0%7N&Y+W-;-P:^_JC@5q08i=>"TL]h_YbTkW4Z,$;*mgW(Fr#Qt(&/JZ#%'osF_hK-,[X>k8cO):nH3+\sj'K7N&p8WN6/Uf\VkeZ,2&&'Pe*7>)#K:>?ZaY"glg3N(Ln(6b!^`g9OaOrD_Q%Qq^ST1&q5Eq9\0^/Zj0t.fbCD:bO2d.Wqfn3mb)n%UT])=':m9.a1!/"nW6$-3^6fFmt5:Ja=X-^$,6A%&jp!f0Z$M-6+')<+LMlTMr=WN\\Gp/?+:l_.D=9p!KVOCgtLq@+JT[XT4*PlqE?cO?7d!MWN.3pB(I#&_/eRI@W_2b0C@"^kCm1P,R-7c0]HMmHUWmLT'B<:^KGf"*@,>bi6?4QXcY6!>1k!IIL1:j]n_?K"f2N6N>K36f6lTP^/1l*]Q)t?@ID,]B$c8?CGks8pG-/XA1;@H[U1k8W/sT*_":E"/p$A@]bb#65$f]2KCjHaW2Zf,3FYX.l]I;77ge27ac+8oR.AKN-1j4;7[b>WlR&!'rcA(.S//-GrgF1.(7@t+F.>V9++G!Nu@d.CZP]QP4@gXi3!mFjedW;%mW9QC'op_OJ5!f^LPoI1u3uIpQL>bTHI7aQ5,MJ3dRGI'fG5Dr`XJmh9gm7TOXP"Lsk;T]DlueeJNL&Nq(HpRG(Lu999sSPsX(afo!O_qG9+m0jSO#$F@;=#5\>aU\h:An9?F+0bWRCAUQs)jendstream +endobj +20 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 621 +>> +stream +GauHG9lHLT(r#074M,`!\@+-#3CTFKWn!h]":gF=?%1/2%Y"*l=J/n-)/%XY(hUZQWC6qR7.+nT3oKn`%]HeA`Wc*hA:k,bnhY8(f9GKqYp>On*\-UM)a8gWmuJhd>Y#!dgA2[F30POD.,kUm6a6Adc@>PItd^qq>SEWP4,%(rQPW^6N'lnj:<;qU(+qadjT6W6[[/A$fj`tB^)(S"mTY_n_oH)Vqqd=*W?#)rC\UUXo60qmMsc[`jFM\r6=ED&@Y%XUnnSKFoHQ3GbsHg5gSkPC:4(.:QdR^>,'lL.Fj3<(d%n^Pendstream +endobj +xref +0 21 +0000000000 65535 f +0000000061 00000 n +0000000122 00000 n +0000000229 00000 n +0000000341 00000 n +0000000446 00000 n +0000000529 00000 n +0000000734 00000 n +0000000939 00000 n +0000001144 00000 n +0000001349 00000 n +0000001555 00000 n +0000001761 00000 n +0000001831 00000 n +0000002117 00000 n +0000002209 00000 n +0000004245 00000 n +0000006276 00000 n +0000008424 00000 n +0000010542 00000 n +0000012644 00000 n +trailer +<< +/ID +[<00f9ff5fdbba45abbce8b22e24867ac8><00f9ff5fdbba45abbce8b22e24867ac8>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 13 0 R +/Root 12 0 R +/Size 21 +>> +startxref +13356 +%%EOF diff --git a/Les04-TypeScript-Fundamentals/Les04-Bijlage-A-Lesopdracht.md b/Les04-TypeScript-Fundamentals/Les04-Lesopdracht.md similarity index 100% rename from Les04-TypeScript-Fundamentals/Les04-Bijlage-A-Lesopdracht.md rename to Les04-TypeScript-Fundamentals/Les04-Lesopdracht.md diff --git a/Les04-TypeScript-Fundamentals/Les04-Lesopdracht.pdf b/Les04-TypeScript-Fundamentals/Les04-Lesopdracht.pdf index aebc797..ff8b474 100644 --- a/Les04-TypeScript-Fundamentals/Les04-Lesopdracht.pdf +++ b/Les04-TypeScript-Fundamentals/Les04-Lesopdracht.pdf @@ -2,7 +2,7 @@ %“Œ‹ž ReportLab Generated PDF document (opensource) 1 0 obj << -/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R /F5 6 0 R /F6 8 0 R +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R >> endobj 2 0 obj @@ -17,22 +17,27 @@ endobj endobj 4 0 obj << -/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +/BaseFont /ZapfDingbats /Name /F3 /Subtype /Type1 /Type /Font >> endobj 5 0 obj << -/BaseFont /ZapfDingbats /Name /F4 /Subtype /Type1 /Type /Font +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font >> endobj 6 0 obj << -/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font +/Contents 23 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> endobj 7 0 obj << -/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Contents 24 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -42,12 +47,17 @@ endobj endobj 8 0 obj << -/BaseFont /Symbol /Name /F6 /Subtype /Type1 /Type /Font +/Contents 25 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> endobj 9 0 obj << -/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Contents 26 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -57,7 +67,7 @@ endobj endobj 10 0 obj << -/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Contents 27 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -67,7 +77,7 @@ endobj endobj 11 0 obj << -/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Contents 28 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -77,7 +87,7 @@ endobj endobj 12 0 obj << -/Contents 23 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Contents 29 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -87,7 +97,7 @@ endobj endobj 13 0 obj << -/Contents 24 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Contents 30 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -97,7 +107,7 @@ endobj endobj 14 0 obj << -/Contents 25 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Contents 31 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -107,7 +117,7 @@ endobj endobj 15 0 obj << -/Contents 26 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Contents 32 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -117,115 +127,208 @@ endobj endobj 16 0 obj << -/PageMode /UseNone /Pages 18 0 R /Type /Catalog +/Contents 33 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> endobj 17 0 obj << -/Author (\(anonymous\)) /CreationDate (D:20260305162606+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260305162606+00'00') /Producer (ReportLab PDF Library - \(opensource\)) - /Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False +/Contents 34 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> endobj 18 0 obj << -/Count 8 /Kids [ 7 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R ] /Type /Pages +/Contents 35 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> endobj 19 0 obj << -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1201 +/Contents 36 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 22 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> -stream -Gau`R968iG&AII3Ci4:56i[c$_-B#r,<*oXE]g&]M_9qobEPRb"t?DAoZ).^;R@]QEA!Z>B'^*NbP`LZ;%+k%R/8ru!'\?jm[O=<&DmL%6pQ,+PBc^Z@bjVTLbCcDd.`A04MYa-l^.;_lh;Jk6n$0p!!qb]#T/YZ7fo;l(F+;QlauX3`!*TbJZGXO/;+IO6"Ic_#S4j&N%];Wi]Y6[XRt,TbuQ\qWd1nuesPG"i[)N]_:u_W&?]AV;^tP,0B=i)1/RrKcbiR2$6PXW7(+K\OabZP37%SY<'uWn.KW[_?'WM=elgh14sYij\9r(.$h;O1Cn-b"e%)Vn-h&d2a0uf(%H52CT9:t34B!:^Y2OckncrHh1g?dM3n<>rb3s+M)2g):>r7/JR@Tj7X=^lHjJO[hW@#gRV7O.i5&?00L*^?#'GYGI'):#[^$+'<`#$QD66>m8TRtN]\.S^ko1O;0QTpFb+&Z(Oo`/dGlkS]CY`7Y*W(uq)H*NrOh/-,:I!ZXH+(t(g!["Tme)0kL%GSjKKSCs=#06I,^OP/kmUCsNel?PEWm;Ttl*:N">3IFpNIT;AJ$Y:F8e@>e"Qj;lm90CKmD42Rq7Ear2;*W*OupG,q0dh:4g+kj5`01,.1-dD6g`qm;o_30)6,V/l.q0I*op]$fE=id$T\GN8@ko6+rI=G/FVibfO61eWRj?f.1>'/JP?<(tFkBHGmN^<;E:T6qL1>pWkCW/&,urI1imBEtF]2b-NBPOdNJBFR%pJ;UH]bp3H]e1aV%=fhT*Q^8\A/S$7Ik?Y0Z[@HDJMr8UL-CU*)*R8\q!Q\UMGendstream endobj 20 0 obj << -/Filter [ /ASCII85Decode /FlateDecode ] /Length 774 +/PageMode /UseNone /Pages 22 0 R /Type /Catalog >> -stream -Gau0@9i'Ou&A@P9(cZ@uF`#0+iDq@,WDEsHlCm2MZGYZJRtN&6.)2?FS6`Q2-l7]9=IpCkhg=Cg!)>oRs(i!\SA:K[!ec6f(5--(P&iTW-4^bE6lO)i,:-H/Qkls'D3N/pr/ob/+"!4r*?[@%8EOOUcAJJno,P#i)-0k`YfJpb7t#W&d,D]d*?-_[`l;I>@jQY;j%MkI;3i/Q1+>8k*-=k@#R**&mD08Kh/cGEMh\_DaFk8]`&&ENSH@@o?'g\p<(l]]paAnt@_t]YhpC"XZ13=*`e.D(k365hiFGqIAIW"m@--.VE>H]7Tc@-<36SgihFm@%jm;L%cJQ'c(MboUlj?=]f2A*SU&T2Lr\r`12`\#Y-gAnT3*du$k#)%gdC@p*5H&6CGF74(!eILWh,\+I>E@f]TcN#W2I7fTR=*>hW)j.5*V=?I.V;GE(QC_//Sl[Wd/5nsUCqbu!coh(OTf@.cNYj='YuY]`A/4uR21>adoOmWKT_MG?;:k\]05IM12&:I4HW%$XLmTU@!YO@cp[;&GC#3n>0Lcs\3J]HlP+dl4F1a*XR!00i*&_\Za9nnd*i4Y3%H`X`I&1ko6UmCSI_uUCA%@X3QsV&_Co;";OXo6bGN+-]hnR2*s9F-%%OkZ,#a)H,V9_d"AR_f>6JMJd9[BsEFTfh$$Epbh="Tq#=^#6>QHMPVfC(q:n=uL`PMML8*fLp"g_VE\/Y"M?!o_:XoD~>endstream endobj 21 0 obj << -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1175 +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Lesopdracht) /Trapped /False >> -stream -Gau`ShfG8V&:W5m,h]J>i'c\k0S@`Xp[.CXH`'XR#[XmK-Zaes1&US]"j.t%!m2MnnJ%^BF>KX1:D#Rh?jo7%LBdjtAKuR6bkJn]bi^#N-Y+Aj%$Q]nZcj)W[ScN]a7T`F^aQ^=KqS*mDG=Aj&Y$;I#rZeN^($$GJo4W0Eu9CaIZL@u?UFZ2i`EPVa/?68YQg`i3m6@R=;pjplO6'rk[KljpWg%L%TrEt\`JC]DYCXPa`>;)^po@,U2#G^PIpe7RS=#>?P[GAR$culkV@Q=5[,`;?SG9NF>m])._7cA?sFc^s#/M*@c_`W1-^eUi9);Zu?=VsuTi-hd!=f,,o+]gmm[\2[uWf%H`AEi6*C[I+artbo7tTa4h]T8f;;[VO/e\DjFOpk,Pd2m21,VOgZuk)tR1sgHEmQ%]dQrh>%[5KjT;-/FR76Y4op,;&Usk9L2SIpSN(e*@4%;]AHWXAL'SVt6XBcX#9Gr4[8I\SDlK9doK'21YSUt",.)"^J:R>>/Wl.V>'HT$[MiO"_Njg5YfLFW7,#p.i?T^s?j'FKF;8F,k-klKH@f+m@bjdhLr83ad];Vn%cdT5a;kH6oCQ1j$G'ud#]gKOuU(=UAGuDfg:\qHa,L6FT*JPI*6]/bmh/5V"3>I@f"j]uH)[DQ=9f@WCh\J7MMlINJo`N5ZDE&('4Bj8Fr%B8=Z\c9&c`%(L6ZCr(1.rb(?$+/MHbP5&Lh(ecWP-pa:hE#6&DW][R-:UI(FN&qN!p$@a%//ie*SMn#jar\b$<',Aib\)f2S91WEH["G;19G5kBFoL;7+HWiXQ&LC^7a-rX\8e-lXo8W>e3g?YZV4^9@q^M%.iI?q[pE11FFZls'Q"Vr>(32j'KR);e!)/^Uf(X"W.G\!lZi8t7nD#DDG!-:+g'bGo5\PH&h@;n'M]nh8W7A3)ILXN.;BN&_#J)/WG3AK3]JuD?gmY(`B,@7+QK(Fo('E$USW\XC^..Xe9K1n'Q@J?FHdD,Ht=;L~>endstream endobj 22 0 obj << -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1095 +/Count 14 /Kids [ 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R + 16 0 R 17 0 R 18 0 R 19 0 R ] /Type /Pages >> -stream -Gat=+9p=$c&A@7.oP#h['-YK',gU6$c]iRo^cN'fW2-A[3E*P>'95=TH0M2P%r49?rGdBS^N?ZXt/jk\#R-r(qOOsE.u0Sq3B(?SC_,Z2(.!D+P:>3t74PMq!Vb0(?kPMrn5!CJb^d\]`fga(GrgW&s]YUs&td`"D'p(1a,"O[NGT6d^PGjPL9(>0B8!h2A+/_l`!/:M4!XtrSD1l5q2"Qal?82/j=g:Ac#)G1a*q>]HK[L=QUN&Ttl$b&H!b3N\\iL`@M'=Kcmh;B@="t93Q&*+[o0f8>Y17hoXAqS27B&J@!KCPuYG*1G'"ul_4^sd+D7pkp)Q2'Ye!ns=oPpTtr1gV[H48O_a/.Dmr9.pLj7Cuo46"a8@u?k8ko=7ChpYn*atLVr\ed+_hoY#+S=-$DklEFM57i$;fkuB"&W+kUKL)Nh6aq5YWeoXg%tjjjl3$*?X9K?tElIibld^"U;^'dJ/2B/7WY"M5`D;g:k4T-;=4O7n=7FNM^RM&#Cr_qg[dWd@.R-6agqURJpHC[gN0g0Q<38Xcr$(lW6Pu66p(uX^T;$Z3C*3=TEc+,qb1%endstream endobj 23 0 obj << -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1281 +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2106 >> stream -Gatm;hf%7-&:Vr4EU]/n`/7)_^C1N>M`G!GYK[uhHeAcY;\!Z4E[f[EKDk=%dW4F$(8M@nJB6[iGose^G=N6anKIUEZ3#88JX]jFKYeu<_AicD0oRG\hlfT4)+9K$:l=__@8TF4g(jSmB]t(9BukZ':/#/PCZtSZZIA^o0Ok7&f^V;[NBdkBhr(6k5rTaL@RM.oE2"g7Npd)1H3(!W:KGjBleM]`UX<0<3.a5>IoJH^=?lW9#:$_?'(NAh_KNGmd?`J]_GL$GrjW6lbfABm&0>l,@G\+1Uh&Ii]Unrf=p<+J<"[p7-#=63D>V,/sfWcXZhs'.k$;+W3*;2P7-53?^jFefdh_O%Yj;`o[oSZd`*a/Oc?2TVpZS[eEgTF#a6Q2=QTogUQ0MU't?Eb!X%f,L)K!D84^GZMu+bTtB,G`m,mOpb74Ash:_)'f_:=k\ODQNnIr6YOiBNlRa9QP%7[_Oh0\maQIY_8c7n;Zs9-kE31Ynr$$bdYc[nYc>9BX\Z2Dj_?ERR@FYd6X7qU>EGt!pK5Qr"oJclljbgf8NlhbHGtMAYJmSeXDb^/1rf5SBp1G3GW&nuRpZM3M8]JdVMdLO+PV0cdYBSUUO>kA\pY_h'lks_d:ms_=qY.t1]=*i,/s+K,18k=M/3!"(_G&=q'2Ju(LP&jf93.1"IpgcHfO*#Q?c$hJ-i@il$b3EK=3Zm`*I.gCK&ls:WN&tWZ5Sh08j\Lb5]*+@eR/nI,9Wt2Ge7X(K>K,dA?!'biN`^89I&q(Q$a:\E%m[K'n&jN`YoZ,#t)]i>O7Rb0+?&ki#')_RK[h%t44u]q[]TMXen+^-;%fQKX\G?_HAVh'~>endstream +Gb!;dD0+Dj&H9tYf]LB):/EOW]3dU56^lkRde:QNDJo#6_$_t7MomA\q=V4[NGTf"Uq()`#t':qmE;iJc`Z26d4[HI_\p7Z!PCPR^hjpIJ@j$Z_$B073aXtmp?fZgJ2s=b6oM9jd6F;DSI@WQq2l\;#d&W2JI?A:=VsUOfQ8_OGQ8(ZoV06S"hk_)0!LFaIct^@GF3='UtTCOmmil1/,MYM?Guca3\n$hOYGM*/#R-]Nls!A"We(acoq:$jZT-V1$6A(.9$#J:cQ*;i52o)3-l+UG`A\mUO!E&#n1-R"YHFNB/._PK6NYq.'@Pk*nt,/Es]V2f0>L0'V'iH&jUi!HSFm9FjNUW!Q[!6(15(jf`IT.(EOU[iL&BK,KE0&%%][c,Y0V-?(,T.0#[he6bp`8<+ZNB3XqIM,abk1lGVIG90LMQ1I1G#2le%PQd\\p=;q@I8\(g#(,V]s;U"C/!2;$Ns*==^](-$71\&"nbJJOJ$W6F@%'=9n8E9T_qKUPW%c>R#T[b@Hce0s`=:mOG*aqFYo)&1C7HO;fWk@&oAVS01Yh0[=)R0hISN'G]Co($bj_`J#EAh9n;U^4Ai(.L/d!8NF2C7"RH=L=3`Zk"1H/$@4rW:pWf=,Su[dS*%#giMRgeK"nCO^$m,+]+f!iG#\]IGZe'<.eDY]MF(N?HfdpqE*.Wm'QQ[]:'2jp&rKou1+TLr2E"-Z>I]oK1]V@g=&K_I6]Ju0hB^$?)DmUh7bP(XZQd`6]QeT17,78DL`DUO8If7$OEi"JLC"]J`"A+3\S)D3b<;>TNlp3ImXqYcm'%ZPTnop1Q6W@WUNU]Q4Y#-&RqqFT.YT/,@GH*Slb;:CYgZ.3:s6[uV/';n^;PADiiFZb$t$ET(%-8mlS.1Sp+,@)e#KEj[d&O;-!AY8?KlLV`b9TNabC.:2PAicP7aY[+t^OtF>@YAL-Hd%Q*)K$nlTAT)l$#+[tQ[rWD7An!:0Z5oQC3n,0Pe_FWF4U?($GD0"SuN/\ZRTnU(k3c#igRTj6i.+t-6D3:kub%2p),#&))V\8^Y,IJg@"G%gZR^&"H&:]G5QHr#RTPCf]N2cB<<.\V2UqL'=#:T-ao'jka\FA!M3V-5-CTIpZ7l/-M@HJ][8-l*.30_X62?,qS\_J\2FBc(,mGjMMWNl>I&7H8)kddteVEbPpfr&"QtF>;410:Gb(HGC284]#l%X(gT,a#&D9^6:E$\8)pDWXYP`*Pc$uZ+S1V.:Nt:C=]u.+bmuJ07%S)r:Oco)B34U=`50,#:O1E:a71t::J4_;\nLgT`6nFG1TXO'$W7:?T[&.].)l[cV0:0GjI<^-FQV1^D)/]YZO,HWGu5$12(4K!t=jY`=:82R)ZU_2,ge!FT)Fe%^cT~>endstream endobj 24 0 obj << -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1224 +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1774 >> stream -Gatm:?$"IU&:O#N=C.B1UoM.GkCj3RTTGiY4?W;UFjsB)D!,!I0YP7#Y2mMYD0&Ea(j4h-d`Q4K3P,V#MM$W/]E!2G_V#.uN'hn#9G.Zr*+nHW5::9^;o_:>c68>WM,c)\$s,0DF[mlO$Xg4M4o<$G$%EfN8PDPSKJ='Y"[p=-0F@CZ7UNI=r#YYQ4EEeCoa#r-amrNpl[]QU4W>fUm):":46mrrDHYQhVpZmhRO]4Isf25:3L=f3*"H(j73_L+/`I1^A0AT-]h9n*D/iB1;dY6o`8@o"'oh=ILBonY0!-'K1i;5Q.ZjS@oon99_m]=eRVJoWFbPs,Z1.,jAbAG$[c\,;;H99I:P`;@'6?5#Ep5Z7^a&,+:/4h3)eNIN2BH';)RKs%L#dK$`J:5/>($<;Q6nc@Wmu-*d-epX-!(aJYoHi#-uLn5`204Ok4d2JAJ7a*FQL1:p:'d<<`e7/odao*5`4\/T#rh<+$rrtuPTO`sJgK7L1N,=]LMqVW]3jBI>AK"#_90ZbBT9J;Ja(/Xml7i5<82!n\$]MFr"^Q)hu4/_N7rsSaJF0,[ga:2a(Pa]*d(*QM;fJQ!&!_!TObc<8o0eb*-:)2<8i=^Agr)_neAjG\e46%U:uMj7&/UD,b4,%F`ula+8mTSI2W&LZg%c1W.S79=V_;1;$6i%A3.nc?^Fc1ORd@[/odq7IeT-'A_6?)BA^VZ6Oc4hZto5#@SYS+dFSt18XJN,5W.H27Mendstream +Gb"/'D/\/e&H;*)EU,!]=BUc42mf@`s#oWQ5q_'Trl'pV%Wm48%aq;'EZH*Ja\+&:_En>!"@3L54q3]=?`0M+MMLaJHI0jXqu>Xo/?+U6e;ff4YJo[ho$>pn3Z+ld:&F8$]X*Tg3fjEWpL@U]"SRD!iE`IH2e4Xb*87_9$/.QX;$^s'jNNV_p_]VSF:_U[p2(Lq&8CV["Ep,a0g_=48sAt(VH!e6q*Z?5GBtJ&[6hK[tnL/`FDVU^p&CYi'Zir@?2d7mW'C]h98u\s^0T;]X`s]"8%$p^1mEomh1+l\LK_@MTf4r/dcAa&Wf/=)MVO,g,Ns9;si_g]AcI^]VD5Ii/Yi_c[Ql7LgjGqFtXu%WJsO.nY_a4^J0:KA,R_YUmHE!J^^3,1]Wie,1&,\3-bh,A*[fG7RZ-6]jt)a`GuY=k[$jc.B[f5'AkBbIds;`Y'^u`uN,*;=R:Ia%Hr6$\M;e<^0X>V0WAB1Y;7+`%-ls[9-\T8T@QU1Y5<&%tRqa;n?L`8])`sUPFU@gE4*?j-T]`N6a<0S)TN,<_u=nkm^OaV@h1FO(D1].*FOHl!C+P).)9q,-$ad45;1k]ssD,iFcen(LL&;ilq]7LD8$n)r@(5lullL_jUHiQ5("G3F)g:7h^&%Seh,Z:=RJ:),,,',mD.L=[F&NPdD+/IbEo'\MH%TUFU$m,N7Q.$3Ub\^O6k\lL\c/'Q7eiuCG)(=M[9#1EQCiX@\T4Une"M_a)(!gssi:K)qFmi*=E3+;mddse9q<_WZD?#jrkN3`G9DmT4Lf;Va^%0$Q.J/+KC5mU^hTnI[&qMi,'?,(0H/:Bk5#RdG#NRiHSc~>endstream endobj 25 0 obj << -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1075 +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2111 >> stream -Gau`R_/A9k&A@rkVO,0UU0NkU,cd758N5I5K5A+r>G126.utG!P,M2t]Zo&P8D.n3N?S0u(n`/banPH"Ajuh]rBqK\)W2fp[oWWaKRWHN8[Q$kVS:EG+;9J\C*5^\E*U8-]/Ds,e%(HV5D/j9=#>F;,@_4_*@@CQ\h8?^`J%EAlE;ps>9??#c/\f"h2Pru9V=J/(NCV)Sr]&j[3j96DJHBR/aTKXME@Mg\+EfG/5j,5$)S8b2fRh"tnN1Z]:$.NFstEM+WdW(anQ3I\).S_;tb7/$_R"pDW_]P%9T_D2J2c$9%0"5rj8mq%&2KF(gF1]Bp$CEQLGc]rWGs;k_b$TVQ%^MqtPH*7\jbeWp_Sk6c'JJSfH4=&gB9+$@(LM&![G\LeYYd>=4J@D!:l7,!:rj-)n4)NBq[X_4/$(RhD;DV2\jO),"V./T#d]%Gc0?VA0@?\TV4PV9"3eOcHFjZ[Ma62&1`OUc/gTWEZIDRIKE>UdH#B9o1?KOJL[;+[J'@e\Q:8Lp_G1DjGI3C[L%5.^fo374GcAna)Wl;8W(toCRqYr./_h*AM9JGsppsS-/F:YbN+m/#pE/2ga%sM2eo+K:EPi>-FElWPOrZqPm(e,M.sBl\LaSU.?9QLYCKHI\&_0K.HNs$JcGCf13iE<@778GR$:cgUd!9KC\G5lW$_R6bi,:be7Ql"p6AOM#>`jqO@5I=o)[,9O;YWI3gmR3M%8Y]gATT7mm3(q2fk$gW^boIf0$endstream +Gb"/'>Bed\&:WeD9_1Z!;TJ>KEcQK[VEN%=e'"%o+.>A!,JZU2W%@,?BE.jhN,;5oJRm6:gTuu\&[q>rS!e1a6bp\h.:2$Ki'e0"?5"FkoS,UnbCeXjGh$SXCKXEjKUr^?)qf,L!NY7L#H1KmJ0.lZa6=.km*LVV&%m^#;:LH<_>D*2KV0.jT'0l,_QU:T:]2+3$+@du@a&6sQ;_&WE2&n\Q#gX#iT:I_iVbB7.h?ihGQj"ClHG47lXqr]cqM&R%3`*2TkWKq4JqDaEj9)\ibn;u^1o.no%:aD3ZA;49!E)n3c_r`9[?+>1nSu2DC!-n%)85\[Dg@I^DO_6f2@(kgZbtor<*^0Hl7q0dP7ZItVQ.W[bBE@Ue`;1W]Vn:rO5O"/0>'_m>>aEnHTmi\?Rp$IF"eTKe6'okkI[.3N*G=CiCi;n1\o=3%m#Ejg/_1!7DidZX5aa=!8"VFf5[P%At3QH1hElr>L.R-Z`RL]+$2P\(iJNE]/XY3PiGi2CVs#4_$L3l0kE%6R!Nqhqc$*+ACu-MNJ*@2UC#3.N"';.tFMl-d"ZaGo,7!0c&CI5GVp'?]n>#_GaD-!s4nkY7*pTL5/jXq:[\j$6T.T*A"n7B>sPa*YX8JnT5kn;/e,U/5UC@b[l3E_a)psm5jieg=M@2/-.VP&02&m_"V,uk/+J=!ghUme9$o`M#R_&-=*f5&C6M9m[igj&T3eM*5uL1E17R(r!CUMdfsGG4HO]#p=48$"6UVYT="?h3J6$iL1)S5PoOhhs7`*kO=U%B'e>5c`u,P_j7PY@ku!!'L_?64+k@af%nKFY7MMO8BcpA?&L16rA:GAisX`Y=R5u7aWAL[p`A:Taf'0_Kon0j2W+7CbP;Gc$5jpO\A6c%<1>mldN=U#JY$M7QQ2V\YW`oR6bPiAP.)s^/>f]1>%(;jgOp2l?++M'q3"hPa#sB""43N/sDJ<2u42!b\L5U,G'u#_]jB1SFQ:q9gk.BXKrW\jC1B.:6sAMb1u/LpD8ec$snrgaY-+&,Vh;\WMo+n)@'s9r[cH"QusD;s!GRCBbJ?>(V0tu:\uP[Hf-o,UYsFQoQTL@I3TBZ:!L=-c8%"_j;.-8=:-VCbG.h-M6M-<31"2Xj547W>mhh'/BtcQQ]a-S^3hfO"Kc^Q%7A8op3$,DYZr8#k_)s;gfi!pZa@&GuG3Pq$,fH?Z-mq-E"jJ%]mJ\7oqo'(2dDImgJA_.ruj$"A[DANcd7`gb3CkI11B86!YRo1cK;J_HUkrlDLgo!_<^iE3X>5nSHcKP?~>endstream endobj 26 0 obj << -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1269 +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1900 >> stream -Gau`S?#SIU'Re<2\9j*;FGrbIqUeHGY0Pb\WH?`=,.'o6R_KADQC0t,s&P(]10.2G'e=pk0H3#hs%ZV?l1T>ZbusY2pTAZIiJL(..)"-.U@R*9h344_gOl`4g:,B41#B\,@"XBP]F]_$+cl+\I]&]839nkKP0D%K07(TaEYl'4s&]ONq(0[nA1P&>'IXn6W9*[FSR2I2]"!gSR8ZQr2-XfV*k)](T7jSQBJ),OF&^;aV]LQAn@t$<1k:SitJIuI18j"K$nV>o_%a(!rXGac4$"hW;AC4%"b2o8H5/b&r2>%.?d&bm3Nq^`qWUN^G+=;!<2#:Ab6Y0-P81i1f$GVqia=$c!#0W'(_S6*h([2R-?*&abO'-WCF_l"TG+OB'9S`%^NH)j+Npf*B<%2XG$nsr'1R%d8V&rLY#e9RF@nV8)Wgi9Firat[Q9$PT^W\,aso(#QCJ+`Ni3f@k0?Vl_[A516aj_$>nI=lY!/ZsJN9350;DW)O`_djcT_<;4WU.ULVY_W]iAjCbP%IB$aKId>*,#o4,Z?)!CV'#X=reCkqU"VJnG.C^bRQfL#^R`&l2fqp(q9kYA+8heS8h3Fsb7BX4"`0r(C&~>endstream +Gb!;d=``=U&:W67f]l&MUbG&c,cFD69kq:sS&@n#Ub@1j.%#V16R?G.a5k!Z_-8;S1iZ\l,?Z/_?@9?m"r(FGq",e]B+m6aB#"hB>QEf;_rN*`9a6(XLg_54[t'itR]Z\02>&&e_&rs*-FR^"$j:^/E&_gQL_-]h"6ge\3KQkCGW9(r*1K!@!tib_KtTcj'&,*:1aeT+]Bf*SIR:*u'"cR%eL]V!%!SquW.q@p$"]E4_'FW[ldPS]i->sVbb$7S#k.=`qXY]P%E!ap0AoZ5b:m)AoDqW$0R9T#FI7*,'$K@].as_>99up6CDabT!Yp't4&"M*(MbY3;5r]F2A$_dk^Di/<]YC%Hds_UVA=JsN.,5ITX5q5LPZF@jDC5SGt6j$>:)2aP$=%Q<-'EVohGV]hA$/7/0oV+i<9qD$9a9;,8KAs^$pE;!I?\)Mea23HYRFC\5&2$P3G=0\Vpj-BPF?LTn8\ciH:;Q6b)i!OLS2O'^i***8S^*;Sk3>n]DTPR*-JD"@)$h3^k6?Q[A:a97/j#Z?ek64_5#]S&OMC0@sM<4T#\#>.J46pa0cng.`#[4>)>qhUDe<3hS@D5Rs(!]8u<9`k9]dFu2BqNjDYUP7`^-_&?IG%/6Vr-g3@3Tji.^=seQ,>c/:n81AeMaV6o@+U#OG<(qfkma(`5efCkW;Lsc]e\1&Wo@&WX,kl>iBm]28\=2NYMM"&-)ta+\DIk^!Ch:mmRD5%j/na!mg)T<>7fc>r8'AWhYg^ID$p4Zl%f/n"4PO>tgKdWc$3'>7J:uhB?5UgEOSp;Wng9[l.7)/+&oJ#GW's\m/ohEcNJkgTRW64gVSu93).Ac?2KfVUGF8`JHPg/&5n".Q?&/^?EQZS%=UPI>:efRp2=65p.&Tga7FZ\^6*nR-'8(@,Y\M`o_C`raRQ88Z.Q0.&1b6YIr=KMVEJ3O@d4/TL?BMdnoj\ph2mkNP=C=(_s"d+JhYVLb+Y#X:lN^j7t+&:fc+8,"^(,t,lUt(Ga;%lM?U=h.^NsH-Z9G'5keAYjs]hdLH0ODpW;g^J>W'@r__]WKPaIFoD2jj$OoYaF-]lMU(;Ct%fW0Ei>UkgL!b_"-EMobZLuKX`p0J9j,]mNcI0Jp:nFEh=oSJ4:t?5(LB6VR56;fES#aEWa5gu\FZL"3*$]Vr38WqOq"a1=n_qZdalM[3^:@qu;]e<,ONVO9X)-l!jSq/ZgtK[7olWZF2!R,sCS`*(f2'WYV#:n#b'-IgZ]B+oIFsl`Y7[D3D:$be(ado"5DCGUbOeMA@<4io3W(SOr!I+O*QSWU72,@>n&EH!D'SfX9h9hriH2'hcO8]+1Rn(s($-j9Y$er+1NaFLFAgF=EP6TUq^/7El5s8G?gs\OaqGZG"4""V9_Q`r_h653_((ZoHedhDY=r1jB6=s\h7GAMN3oT3>:Z)(Z1p[Kp&Hd3]u/g6>*oL`C5O;Bjqk]f?5)qU.*OihWd<\b^Sb(7]QEH-j&A&hO*pYleirrD6kU5A~>endstream +endobj +27 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1812 +>> +stream +Gb!SlgN)%,&:N/3D"XT7;MY<=&p1&3EU%)oe8CGSge9MQTdX#p7?IpJfo;L!HPa=fZ=GCYdknANZuB0<]q&GjJqZEGru95`SdqFnS-!7U\,seZLVYE%)g'q\#]lES*?_epCnCauD=[ckm_n%n`:]No6!,0?*X=;G&],@"E1c;j&%%"j`uPN*F"L1,+G)YWE7ag<`+9@;8-'UJ,EGY%p$U'bh1*>bR(A'X)X#L*W-0,M=E=JB&]0nUo8*f3BPtr3"jF4=R5HriLeU@P-.(3s^9+/-2gu.N`B9g]rZb9#sGtS_'+Dj^j8d2?C=r1:sBqQ)>rou61?Hk9k`%mK0f>aJOP3E#.a7Z(rE_!='qf$c[K+E%6&IlaCp%;:ecIu4Y(G^U^WA1bZ"PFtnA\=o0+s+iV(!BH7;$lLg0(-^d70Go(/+:ut]?M7$d2:D2[AN]@VTZ8PlX6/11kgTO.No3uRDNP(.abRkUnj=H'0(;dJsi1TP8GZ#+0@hSZNA6[0ST`$@Bp4kr<1HO.'ng7ZM&[#Qk=p-884c@9=^";qgo5(r;a+e[j5=?r%eYYFE8(@6`B>3mdAW>Ko8oFq!7nl;Jl)D4Pgmn^X?m9j2k-5V9!@-/-(*f'&.q$\st.Kbr&QtS&EfalhG3$'e$Td>Y*1d['l&]b(Rj:60H:R'VLi0Kb8(&mTiD4>c.A'OFNCVQZ*iEj:ITMN#ahssmiY=,3_`P8TD;Y=$h5'6XA[Ji[q@=L^r2)]E&>SmjEA..W[qK)[pnbdANUE*+*hBn.ZnR0$m2f8O.F'2uIh?7!c6]CA3UDYOH)N^'2;:%4,5m[[SK=pBX`CDkr=g>]18,N-Ggk6AqO*PEDFWNU@J/mc\q3(SK9Fr_kf:uha31U;q"[!`@m$*l.SiJ+^V`7r]`_NC7XSgp"Pb06&Nd$FN'._C3+/1H.`QQ1,K;_M]I!r42L(<`OKAcW_/S^Kb+5pQgO09-*lcDcrr@?&u=^J$=(endstream +endobj +28 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1790 +>> +stream +Gb!Sk>Ar7S'RnZ;3:N,1Zns4o''5f(g*K&6os1=[qVi;pVJX;XPY/71G2%N(&TtK%--_Me`F:3R..ZE/Icldn`=FbSK+5Wf$&m.I0H2>H@%;2']RmJHouSDdCO9:dE?o[S)i3qs5EIM"(kbOeht@pYl4N9#i0"[$I0hh"o/u/$WaYG=@R*&BHBJAm9XrM6g@#U)[de$+K^8Jiq^_JQ+eDKb8idZmr#uu\@$OV!Wl#-S_@nWV_!oV'5;1q`ZIE$]8s0HDjJ`Vi3D=;EK4c!>WcpKrY&nskP=q9*.LtZmE^>P$\@3"F8nZ8r4B2j;+)2\5$JZ-441&IVinBZ2/h5)UP\>K'0ZnbZ:"5,uW='ABBN&@JSG-H%ER-/[gWW)%QaGDt:,P4S$0B\&cH(<+?o<#LnHn6iCS9rQcA:LY4Jr6ngaO$s&i;BMeNQA:,G(-jf@A_'BOn7=\(\4h#1gpPYuH*CQ]KEPpa0T%O]>A&SE:LBB!r)+H%^Ln2a/1?i(V11E=-Ir6^FWY]S*cW&8sK`S\j"J1;5aO)DioLEs4L9Oj7C)l1AFKL0oE25kLs3khd-;m;Tdl$Mr2dorg^63.bZ"F]?G&Q#AGa1Jgpi?I!!E#ZglCYX?t'qQ#?dV:)og6R12A_.YbGQ,ju*#$3jWUJ:njC(MY[.pSpq_a9'>Se#^'5^9(9T&$Oo(W:GYfi>9k^Z2<6Pt`>:/t68nCOC96cQ%^bNbt-8MesHp@1pI%8N/,k%X0DVC=IEQ19Q'"fBmf@AkKm9#1(rcA[9"(>cIB5^?R!OStcBqK7jnlQYR'+QReVTK;A0B!<7*VNX\ld6;22=)ZZI.hd6WN[Js?hs``kI)&CKjYf'1oPNWD2t;rhOj0Lm-4IKDtQ!fIbfG*`ep,h0i+L(T,H/SZPEAdV"D*Z@LaAnVQAgTu>_,OXY\\:CRKGd=9X%%]Z%S1dfL0Klsr2I%C'KK77#N3/.RB+pXTr;.TGY:qP-9pqYs_n]^SJ9etZd0(-V0WaVD%`eOVJV#%HP6@uRK*qJb?\EEjou:q!CiIG\*(eE@g*Ln$'`D%^=4R0o345"LS^qdi\#EP&3G"f6/#:(=?qdlgXSX`kkhOiU/3Y20C)YrYM0&?8>dFa?q4_gl_dZK%Fu;H+!K,bPjcEITO.1aRkVk-,CTjSZ,m4,TFf^HD%9IQPp7b/3hSC?!mEeeGg&Q0Ebl2PN7<.r)g(m$jGuf80uqU;#(7I!fJKC?!T5I;XA5kM^T*e9jC1fRLp>n81Rk_.[*k_0r%MmE$qZh&=*%*iqDm-9D!X'-5J5E[L6ke39llf'$fVb+bep(A"i&Hns<30Fm\N_bTNrm`P+@YYdhNB%jK30ZE/sRHl)-(Y@U__:q&gE2?J81c*C#HKYP7Vc_ZtXWoV:Hk7g9_:*Th*e;+Vr3C']aZ!=V3=k81O(I<''onDOpMN,WWb]!]YW[FgKh)T-S)\I9l:(uTTV?)N4KnHj:(LTj^fM1bo!Kp'ZO-Pr_s'jSpGR.$G.QTTtH>6maJ;I@+iiC-/PVUhc;4aFM-t$U\86,f::aE!&#i@6]P>!($3,fR-]^UlLf"[cBjkK~>endstream +endobj +29 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1685 +>> +stream +Gb!;cbBDVu&Dcq.VHGW62,*KC:cV\2Z$kugNLNm]2r;mq,h&JY"bc6RD>q3N5!V7^b&Q7-eC$'?J=*mWF"oJHi8BAks-">9i=P]Y-r:_7A"Z$U@<`:&6gM'IgsBV]!6!oX(V)dT:]H!9=?-L-#pVC'^`>m(o>0USE#s"E!H%5Mr2h<[$ZY)\LraJ4t.qDCB^'-bM_:eNl8'@MReg%@<_ml=5(KR;*T"ji;%3>kd`+"q+/NFcnFo7c!t-S7QqrQXd.7MTEPb5iA$AZ>D,$o$BZNRXf9kc=i`%3"!!A0B).D9oU<&/o!tM3G!dS\+`Vmb/W]DpRD^jj'JW%M'3;!S=?n:0kbg.1_m"U2+>>$RWk6A(8f6_adnXQ"l$OeCdt,X1`aEZ7GJ!*g-J#S)BhORJh:&650A#]E\I'XWZa/p0OG'i&fgC3SargJrKbFp4G0_DWF'[Xtp3OV;cj'$cR(AZHF?,(/Y/$=ThA(r1:oL`%S;fq>dW(]]%&FYZTi..b`Mtc)2\P.-:GqJO6sbeXdUakJZ3'Q)OC#:&P1C@srOS$BX"e,3VG!:Pdp//B?(03C924TtWM\F7DHLjP(XfJLi#+#Rp*C5(l`N!i8K$7id\A(\PZ-UXdpR$iK=VcL.[d@tCNIU$FQ(jK>fD1$^ndEF\j"[5nK;1tL\g0Q3(VOCcLfBIXf/MfEkWPOSZf4ooV8BGBZ(9[!rJs%CKcNl@1Ae7"Tn-g0.p"[cB!auj,\VQHp^C&;aQLBKupEXdpf3478h@upZ?IpRe&`r(/!X@2F)`DG2iJ9HbtX.kj^0>gh^E`hJ?Wn0cPR.78%"j32ofW-p\5%hjp@Cgb"*5IMglG%\ruD+jqpTR9g7pibRW/?1hP66G>#[XYo>9=Bdi9lHH_a0Sd9)ao56q_=kkX&#:R]FsKo\CcV?j&D:r^*fIJS:9-Fjk?uca\VJ`2Xu@TZ>.nVVGB#1=X&+!Kh`t.WnY"X6/26,_*f&`OHO&uY&l&cLk=l"(\V+Mp`2;Bdh%TIflJ90nT:C,4G3.Xjho[$f+h*YV!Yojd-F5@Q:]Q)NJlfE`]C-KalU^*Y3a(+XFIH=/dZpW[WOf<5@:f*rHnSD)[-%TS7PcA12V6mk"'mY(>V]IX4oV+oUM38^\$7c;AOIa_HBpq@%FbJ?c_bsp\Ds`J@F.O^HcCTkiQ.*,>\p@(68I]g6^&(]Ngoaenjpnn~>endstream +endobj +30 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1845 +>> +stream +Gau`T>BA7_'Roe[36_$2Tjb8d8Lo!5"&6Y/!=H@+J=/]hf8^JH16Ou$Abb^WX1KA+1+f;A&kT.[F8=,;$n-R,rnh&a4;u,b.0IRu49m3iK^fqMN!GsZK\P:E((d12IH.s_2Wr.b'$I`>p%,#-b)#3n]9EfE/:N]umU2kh2,te+AX6iBGR;8(0AesI-h0O$rcoK=n7S&#s#bo?k70V%$HN"L%c`gL%UaYbj1C%3Ml=!2Z%R517*frnY@`Vm'DfUN"H`qh7H>2X=Ac>K.@T=\.,/?irdZ]F>eFpV"k3aN!Fe[2L$L?B#L[T!GjDbV+;Ha=S#+gC2PH9pm1iXgnH\`U?k./Z(HJI@bpBM,(0&3UB>p`OJpISl2%SXGDj5"MV@>96nF?gk&LPGO>1W7lUJ5gq&'bEj0:>UEntT+iDXOiqW7!2"7RP1cE>uE'&_dqPc&Rf,\'EC#kaieajn]n?+["=:K']\+:@E#mNgc(C`/uP41V\hF/;PP?B!]V+4+ukZ!5A)qGL-DS(P2]LIs.)"!VdP0^\"&'n4kt=_66"+V'8mCSB6ds_C"F!;.Uf%R8.'n/Z1X$-c7(UbOcAD31:$5r>l4PU"F\O_C<%I@(EfDlHUOqnMhRaW-dPY**':5Jo3^B4iU4:ERJ@@t8)Qn\M^ZY%,XL!A]6TpF?Z:l?72Eh=X*pR>!]OrV"$8e0<,Fj???"$Htr8@CP^B/1N3-26o/_.dc)BBEcf)\6=N8n[Bq_/F>k8*:H,a!FiZ/8u;=W#rKgK7O,>P8.p!GE7AcaKJ8+1X0$q2Ji$,PBOQ!8me-oK/3:rG%KA$LWp>YSgK_k"?!$SmD/p>25@JgjQ$6.X-?D:@Xf@)2"RPFkgH"Q8e@6!rXbHuXo&K;otoiWqA@HAf6@qK!4@+5d:U[S>34VtO)s4\+*2%:ZDL/o7&Y!VWT%8ikT<(g&kQo:ahW8!D[Kf6k__s$+`:GF@)u\4gkCsX33RXK>>!=QM4/Dfu$p^7irhg$+bBG[P5V6L$>cZf7cc]AZ(c/FC+D+g3I[7@DuW[IdPDbfRk+4o$CjbY`kE^-UEun>N;QO-oeP;/8>*pEe,\ebn*kb:Xs`E'M9g`O&Iu98!Z[L+H#Yo$E@`N.9@)i:m2ERP,6Qpkf$VHek2@2<+l^l+pHo.j"h/]4-lW04jPsqdAUj@#9fJH.dK'3s^qOmmPm\[f*)\D:gjjge;Dap47c^##B17(tjWM9&j/(EB5K\oXj"Om\u`G#[_j*979*.&7Lft&lLXj;0Kn4e>_o2l6+E,g0+KA#HX:Y!P=Z!+NZDABPuD;-;+AmVj86Z(I4nW,:3=R+`WTcuR5;$2?U^K^LqNchi:a&][Z#!#Vq^$]l:[fbqUc%F(F22(*B\94kY4OZ80/Z/Vm"\An/ESc'Ff@X;4B[\Toi1NGb1P6g%M6NBCMf>,@is\s[I%gLt5fqdaR/,endstream +endobj +31 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 869 +>> +stream +GauI39lo#B&;KZOMB,GKdjgY7>BXpZe$S@Mg89"6kiAJ*`Ae]kb(<=dI:\lY",.m,'C^MVTm-7a?+gq7pSRUr3X3)bi;AH6AWR=NEl'!1JPSl#DhkQY#p'*:,L;DgOP$aC@'YfE+=(C>@LA5F80g1aLls0D,@Kr0&6+0G(n>^s&.s44i]n\+KMf7%hBsIV/i4qA(ri'.kP7PHH8,`hfsrr/a,.?VcoKTRe`XlGJI!A96gre(]5.291G%"Kecku[#1K9"Hc?29\;!YH@A,&^hE^W;a]T@O--?=N"?mXfU,Q3>8`.UccjuQ+8j_;G\TLp-8hGuh&d9>#eT]bS^"lN7IIQMcY[nUdk9KJkk/a..['KCU=*^BEZ%ZfGg"nk,@P,QBP!1/mV%IR`K'(`0:=mIgQ,UsHr**EX:?-]EN552k^]Bk4`J"rfW_QAHj63eI\\gGLEZ=#ORHB_BO@r(n(:VZ[f1[>0XD^gWqZ(T1b)%IL?\^j,DL"h2=U4P=!uS2WHFR!H]">8iW,/An\aYS=5^`oR:H$9/d+Z43e:%rtKNCaj(U22g;l&Ui!Y3A0os03V7cs6W_W#@fj1s"uD>i2YV^?eoUh`%J18/dRkpiRAP.BE1]qqPG#5ad.q\FM7YPQpL("!kD'#3DWY`,EL[0\56-lfL\Vf0bVUEX<97:@7e,&endstream +endobj +32 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1595 +>> +stream +GauHK92jk?&AII3FDb]K)Wpu@Pll]$ASX5-Wgm=[4Xe`d$Y5)b@^elXs#mK^NPUq5WWc>04J%"Lh*#->0VJ2Mc$Qf!31[t732Q7a!niiK(#.dB\?Sc4-:K^mY5^e,7K-#;EoDq4$*RL/KHXTiRZ'9&KM$^Pe"h;"QJI,ZtD3DJ6T!0_T6,nOH7Z&K>d=7!-lCO"i.MH7)HFZnC6OIO=0@3o2[pf:/#[4],n1\Geo(CZf?3=2fo(H":kObHlo+*q$&/KB),&V)Kio77`.l-DNCK9/oZ;`J6,T(VYEL8#3769OdtPdK"K:=dAIiI/ZO=rQ#hj&)j7ji;\=-DhQ23k(nuVCbFU6rS[EOQ0K2HP%-'Be8kl\^4'1,0AKI*#;hMM8%G&odr9TB-@mP<;c3\aVlYk%GFUd[&.N/2M+LQK1TO`4DVcKJtuKX&JSj*jB_S!nPISZtt=jkFV%7<&p#@hDm#/o_PA:Zg<)J?FU+cE3r(`NB[cQS1%%7hb<>J`Orp8te5-0-ZJsOaP@8)t3RpXqI8Z(Lc@F<:tc*%9rkCIF+T,N1&_D?sI&'T`'@&i_sNRgtZ%GHY7&+s"(,l.IkgtVFao:39nC_?ec9=kM`$9>JN#g:fB^f*lkf>?eqP"Qck/inpUbOpK<7:M^0p'7NT,:]X*?13m66hdIub3n"TIqY<-R7t5S"KR\G_cPGmVfd$:?8tsl-:7(EtRPq,CIIhg$'bW!K,j7Z!lrEl)WS9,@c.Gho[^EHG!h*$545&(j^7[%6cH'`^:_HiD(aP#lAq1=PN[)OdOa;0#ghMW3>ZrW(R!U)T$8MI6HZ)XeuMQN'3PffM"g71H)E<)%M!Gp9Cn1Z`:!\@3BBqca(.t'_ck'QTi":(ReEab]bXqNWW@n:X\=dp(185Lo2H-JOLDVbog9d3;2#9:HZ>G`H-8CV4,#Nk:QiBrWd8e-R&~>endstream +endobj +33 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1889 +>> +stream +Gb!Sl?!#c?&:Mm.(jO\-5>WY/[VT:D:eD+"^=oC=Z`!/BE>6IOfVr]>h>[6kfoBl>+G&pRH^4dS/(Vq0FD("M$n/hlof&<@]H4qj[gX+/i>@q)!euK72sbt[&ajWf>Tf&&SU^eK*:j7nmUb=&`!^h*^o*@j;Ln6Snbp6.Nq9&W'"!8\o,[uX4Xtj\`+Q79HOKEcic1!]"`Z[Y\37UCk8SXHnJZKTZ[SZ(I"F56Z;qu3.!)3m_^Y5=:Hfl9INGO6RcJ`$T1Z5[8I9%"9@u7T2sOSCq+U$c0YDqpF5rp''.8'Q5O[AkIufr>>2S]ddjBX5r$$mD`@O7L2t.h?T\NKmOIV!`Hg3(,ft5L,V%NG_@ba'kbNBR[ZTTXVh$YSQ^#[Bt)6MU(Bli3kg=K[?6[>L'_iV!Dg/ii-aH7]jnPcY4ZWLB#Z>#b&MJ0ns"S(sRTdOe'9Di#pUAid\';$g)`SL(75\hjI*.lFJ_EMV`/Gr*3B0+TFhe1K/J2:U&/72+,8`tQd_6o*('?2Aj/4D!%XeA`eM*jQ(F204@>Jo>opBFhl4+lMKa">-ZQa*qDVuKMOBIBJ.^5P`P8&MiAuQYQlS+8@T44jecL+p/'<_0$90QH_nj/Qg=d'V2PpmA1H+&7__k"V>q4gPfo8f8[V:*a0>0]rNI"C\C&(bj\OFXnplY=!"#\0H:Y0on]Ua=:#PpZJqC"gn:EJ(EViim'A<&dcE&]SPp0b%mI.t`4`\c,fhjZ7_-Jm+Xo0"tXendstream +endobj +34 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1766 +>> +stream +Gb!;dgN)%,&:N/3D"D*^D.!DJ8PjiV,ehc'4gib;ktFT#'Eq@@-r;'9GNq$bh?A-9D;D:Ma,M[3-pbXXY@eA2_87!Gn)4]5>osPP.8U6I0i1V)oIo-uhtc%Nb[hi>JCq`EI0RX!ocI^A7tK\5f4R8N@7oqs,d2KN?DHDP\AR=oP0MS3\[#)Q>VB(3M_EqD7@7G5:ABcI,8Gi?V,2pnPo@3%87NQj7QUiE4sX,b<-F-1nC7s%74V'$@aX/E(o!KjMh_SWC(L&TeaUYmSj?/L_dgNO9Uijlu`WZ>Xp-+#&2[b:$:e@n#G<&K,C3kU[*pj*;GJ*%Bg*lf`_@X1K&od\G!b,]hcP;Qr695d=&oq+\"4Y!bua.jmiVj1/eRam*X2]]e6eT1:q2Hi=nn.O/08?&9/qPQ+t,i$E7I?I3ia9!PG1.Fj'N?HNgDTc;$+"\=WcX:!hkn#_+PEXlgp>IZmN&U%V,dqL!/U]5BF/e!D;7`'o)Qq["PYddX\Z.TU=NWH4mLH2YD,er\`1^/Wem;&hX;+M!$GVZXLQR6DS^!r[?;G$1j:EgTg7c`K5`I[>0#/5uBAmm7]du:3C'lHS_2CO1!Ya'cG.i]Q9Os^CDdI7bO',7khf>p6m(3TsPCc&:1ZSl0fS*FL/RhFb3/&4g;H5?Q+\9jjO=_0"HH+,$+#]gO,=EJ^p35dM:ma1-#"OS&:[p0Ur!AN+XsN/J!js%X`B4.h*7oKn]Q/LP.Dh;GpeMIP15u)mDjn*_saI,DolPL?C[A`O3o'=!]$uZb*A/nVE&lEe.O6.lo%G=_SeH:90oAqfgGUp`RPBT-SD-jJVo[K6UdfuK"@XoW,TTK>+^.*794?ClY7R1b=P@.7Ffj4JX]^)]4-P]`LAFoZ0+P_<(6!Lg^KU1$M9dSk!U[05gt6SM_aEWp*aeV54u8A2'';Iq@,YQre^]cu=f`hB(XunPgr/YrdB68)(P3OPj+Rhu3)qZYdST*%TR.=t$],SY$[gb_a74sq>_@&Tcf4.\gCoPek>sgnm@ack'S0m2(\%-mJ,]FLKB_:a2NEma>cTgXU^l,%['kqK_tlqPfg1h8On)769I,;_i,9?q4lW4M4P$%8*&;!\<5.GM9Nn$h#Bh$M*170&GqIC>306"hk9i58M'TBWm!%P:TA5#H3/HO'DU-J1ENn,7:#o(e'j0"$^#7)GA8"@`2qmVUVc(r^V]#;PD)rM%Ku]NN!V]C7`J.$AJjBZEu`-*0fZ,YUcgnG541.qboj5pfeUN4l+QLjiO/LLRedjYY45!V(StA`&c>eT=d_XF/]G8VMiSGkO74Per%Hl,rPTs+&_hCSS@.j@13r]5ti_,I~>endstream +endobj +35 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1886 +>> +stream +Gb!;d>?BQ=&:Vs/R.:ACTNLcUmcA8YZou)R?*`:AV@UNUM23`pD'^ahZi>GD19hj5;P7[UQ3;$bdAOP>du5`#pn@+o3GCe.7H-L0Ou_h?XCUC=GU5.7(EDPEu7$J$ZnXd+>4;k7>*n_ZN'rNrN[gDhPDesj`SXs",%A`3nKQrt;.t+JX?[JHNPOr[&iG,X4,_Y#5LjLT_81ff\\M$@2C*d?P/E+gALZ+RE/OCNr7-)XCA8_&L-W34#K_l"GOkDK>U^gg3#>t&`q5Yh6Bi3Y`2UQq?oI6VpZJt]0G8nma(GH/NV?K5d;W_7VK6>3.m8X(@Z@`kqmXqAXgjqQDSCR*T8nIY,O)`:PuSjQI5mTq7Mg$B$SKs]2"A6UHgn]s5=l"[*@0^u\k*\>#=dKNY=O@u(KJG>JV@&JlcW4P^*)p7a<^37?$J0/A-U(7^W^8#G2YHM!ADti.&4sYgsuag`*:CUZh83Qa>"**a-\rMURsXg0sk`Pak-Mu=?H/6B;4+uESit-ZTTDM!m06U.6Ub#Odds!elhm0<0\&q6BSgA>(Ji75bHS.SkFO]]X=7MiX,WlE!,e,iOMdZPZ\11V-$9.nR[.Tdbt-&cn+o_Sh&H6Vg!Qd\_A\;LXL^S!:(d6GG3sMd4qr,EH:cc_qOB6Pj69qM'D3l,=4P^7T_c2f/dDXn^t`oPHYV=;^crX*7omW1R@ce`3U-3Tr'li;D.IumRXXJaa22K`M,3YIHmJoZ&h@>i561t@ccp/)@`,IKPLP/H^)H?dWt2e?s^HGL3/ch2L)@,=7]X3g=r\fl+&:uI[3A>5jC]"OlVBK4-<90as`/JmIEVLfN#9Vr\CaE]6PJN6od,L-5mHk'R3dOb<6g:cWA4]fI/%3OgRC2D"PZ!M"a2ZWfp4k66[0p3:>A3155SmKsB!W8rlS\IHoAUH%?j3.i!o!n9Tj)d'ACe+0m4O=0As_>A%Sl;A*,>>Z$%k`pHNMj+h?_X,P9@?emo]FsIVN/&lVl@?Hu3SE-uuj0,sTX5*)t2*/G3%E^2I"4bq1$/@P)[0r^6RoMgj3]5m^p@L1OXJd7D2\_6^`J4i$(O(95`CUg=o;s&A?k/dZ"qc7%7n92n,jfba*/n)C0P>eKg"3M+39@$9pFAi2*3`+Ge46GBg$Bc8oB\9g*Nq:*seeS5S%7d@OPc#"=O*PWck+p'c.*d8Rm>WDqe;S3W%52&[I6>R/H7.&nKb2FP,rpn"NHqWITiZVXF37.1InBesu0?#O1)7?l1hkp8tetn$NuoP*tU`TOC9?`uGq591Nmh[rOK6BH_GB5/m6\B;?QZa0:oGr)KA74&gE'd/+W(Da(f~>endstream +endobj +36 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1827 +>> +stream +GauHK?$"IU&:O#Nf^cf\#fbbFqSKU)5:@E[S$XVQBKL&YQF5lqm@ITd@+)MarJiX`P[D9)A56B"c>j-Zh&,h,f#DVX#Ja7mGKVm5)_<qeUgo0`Q7qi9Xi2MH;`chDd1hd>@N28#O>0@:BUqM-u(("SOIZ`E+)VW@t&oJ>]Yrc3Dfk;'k9)G?L8O$[83/mr)A!?>I^H^nRqB;f-%IffS83^@IZfC]S/oRlg25@H0WZ!tsI="N<^&WbKq?V/8f2SQlC(-&`7HDX@+e)OIO'3r5Y'l&nM::2F;[:.Ushu0SgkVrd:85\M>n9li(n/V:lVJ?/i6a58U$p*/.B3i_-S16VE3]f1&c8cACJe0.8F_HTN/59!']T?OFR!9!?1+sd4#Z=D.@F3+@KdcMs/3o6RN#1[=&5k-XK,6V"2,1u.I8>LO\A7jpB#0+6]11)Lak;s9,Hts(5?S"/&VsotB:'mCpi1u$CTdb`P+8-^8U5qRfuYWIV9E>'M;j^:WI4>_E%c#4?Op7YXQ/*UD;h6cSTQc`$@!(,/3gS0+*UI^c6MQQSmd*2NQr-sL#O<@JgdrKW\3Ci9Tb/a0W!FjI'qWLL=SZL6B"a7M"#lc"VZL5XTJ5[;LDM1TlIpYVB_H`Z-p"s7OdmF`L_T47"K*kU.nP,i<5p-6>-Z%#5U)*\.gLM&8.lIJJF\glFP/`:1hNq,1Y]TDg2=BI'R\g++h?gl>8QZB/(c(FDU+S@TGVg)i&j3EgCX$c/=j/T1j)3n2Y.KX)b'c`ZG>^LfnnP#udY]!;t4oY:;,!(lf^^&0(hK1C%8+7TnJ5>.[Qka78I:t+im619+O5M8K6H5D@^+n,Lq;K6#n,:BPNFn*Z,Vc?#0."1(]2I`gWUM?u!_68Ze]CR-d1V-J+V\P:8N'dGk[$`ZQ#7d6`k47r:qW[X#A<(NaJja"iQX:'%b/Zc(0mHu1;\O8uV+Fn%&oV>K'A8]/*J/6Wkot3ag40O@]Q\/d`H96^[Q=.OH3,ffJ_M4NUk-N:6^"7TU&SY,p$W@U"tR\@u+-?Rl1DX&,=CTf!ah`?KLK(*G'A[LnDj))A6*M*"@i:kLKiSlQM-b@[!Ypda9j2)6e]C!o57G@druJjSX=*RcVcs68Gn.kL\QX[Vk/hYcf701V5G\0HCqo3hZutcI;GuD$[]p9JD4pcKCLrskT3(0_DC]uMd2f?p_Z[$.5rY7BIJ#dOda3H$)\2iPM/^TG~>endstream endobj xref -0 27 +0 37 0000000000 65535 f 0000000061 00000 n -0000000142 00000 n -0000000249 00000 n -0000000361 00000 n -0000000476 00000 n -0000000559 00000 n -0000000664 00000 n -0000000869 00000 n -0000000946 00000 n -0000001151 00000 n -0000001357 00000 n -0000001563 00000 n -0000001769 00000 n -0000001975 00000 n -0000002181 00000 n -0000002387 00000 n -0000002457 00000 n -0000002738 00000 n -0000002846 00000 n -0000004139 00000 n -0000005004 00000 n -0000006271 00000 n -0000007458 00000 n -0000008831 00000 n -0000010147 00000 n -0000011314 00000 n +0000000122 00000 n +0000000229 00000 n +0000000341 00000 n +0000000424 00000 n +0000000529 00000 n +0000000734 00000 n +0000000939 00000 n +0000001144 00000 n +0000001349 00000 n +0000001555 00000 n +0000001761 00000 n +0000001967 00000 n +0000002173 00000 n +0000002379 00000 n +0000002585 00000 n +0000002791 00000 n +0000002997 00000 n +0000003203 00000 n +0000003409 00000 n +0000003479 00000 n +0000003768 00000 n +0000003920 00000 n +0000006118 00000 n +0000007984 00000 n +0000010187 00000 n +0000012179 00000 n +0000014083 00000 n +0000015965 00000 n +0000017742 00000 n +0000019679 00000 n +0000020639 00000 n +0000022326 00000 n +0000024307 00000 n +0000026165 00000 n +0000028143 00000 n trailer << /ID -[] +[] % ReportLab generated PDF document -- digest (opensource) -/Info 17 0 R -/Root 16 0 R -/Size 27 +/Info 21 0 R +/Root 20 0 R +/Size 37 >> startxref -12675 +30062 %%EOF diff --git a/Les04-TypeScript-Fundamentals/Les04-Lesstof.md b/Les04-TypeScript-Fundamentals/Les04-Lesstof.md new file mode 100644 index 0000000..900959d --- /dev/null +++ b/Les04-TypeScript-Fundamentals/Les04-Lesstof.md @@ -0,0 +1,449 @@ +# Les 4 β€” Lesstof +## TypeScript Fundamentals + +**Vak:** Technical Foundations +**Vorige les:** Les 3 β€” Cursor Basics +**Volgende les:** Les 5 β€” Next.js Basics + +--- + +## Inhoud + +1. [Waarom TypeScript](#1-waarom-typescript) +2. [Setup β€” TS in een project](#2-setup--ts-in-een-project) +3. [Basic types](#3-basic-types) +4. [Object types + interfaces](#4-object-types--interfaces) +5. [Arrays + tuples](#5-arrays--tuples) +6. [Union + literal types](#6-union--literal-types) +7. [Functies typeren](#7-functies-typeren) +8. [Generics β€” herbruikbare types](#8-generics--herbruikbare-types) +9. [Type vs interface](#9-type-vs-interface) +10. [Type narrowing](#10-type-narrowing) +11. [Veelvoorkomende fouten](#11-veelvoorkomende-fouten) + +--- + +## 1. Waarom TypeScript + +JavaScript heeft geen type-checks. Code als `user.naem` (typo) draait, crasht pas in productie. + +**TypeScript** = JavaScript + types. De compiler vangt veel fouten vΓ³Γ³r runtime. + +### Voorbeelden van wat TS vangt + +```typescript +const user = { name: "Tim", age: 30 }; +console.log(user.naem); // ❌ Property 'naem' does not exist on type ... + +function greet(name: string) { return `Hi ${name}`; } +greet(42); // ❌ Argument of type 'number' is not assignable to parameter of type 'string' + +const ids: number[] = [1, 2, 3]; +ids.push("four"); // ❌ Type 'string' is not assignable to type 'number' +``` + +### Waarom in deze leerlijn + +- Industrie-standaard sinds 2020 +- Next.js + React + Supabase werken alle met TS +- AI-tools (Cursor, OpenCode) geven betere suggesties met types +- Zelf-documenterende code + +Hobby projects mag JS. Productie = TS. + +--- + +## 2. Setup β€” TS in een project + +### Nieuw project + +```bash +pnpm create next-app # vraagt "TypeScript? Yes" +``` + +`tsconfig.json` wordt automatisch gemaakt. + +### Bestaand JS project + +```bash +pnpm add -D typescript @types/node +npx tsc --init +``` + +Rename `.js` β†’ `.ts` (of `.jsx` β†’ `.tsx`). + +### Belangrijke tsconfig opties + +```json +{ + "compilerOptions": { + "strict": true, // Aanrader β€” vangt veel fouten + "noImplicitAny": true, // Geen any zonder expliciet maken + "strictNullChecks": true, // null en undefined apart behandelen + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler" + } +} +``` + +`strict: true` is **de** belangrijkste β€” zet 'm aan. + +--- + +## 3. Basic types + +### Primitives + +```typescript +const name: string = "Tim"; +const age: number = 30; +const isAdmin: boolean = true; +const nothing: null = null; +const notSet: undefined = undefined; +``` + +### Inferentie + +Vaak hoef je type niet te zetten: + +```typescript +const name = "Tim"; // TS weet: type is string +let count = 0; // count is number +``` + +**Regel:** alleen type expliciet maken als TS het niet kan afleiden, of als signature documenteren. + +### `any` β€” vermijd + +```typescript +let data: any = ...; // ❌ Alles mag, types check niet +``` + +`any` zet TS effectief uit voor die variabele. Gebruik alleen als laatste redmiddel. + +Alternatief: `unknown` β€” moet je expliciet checken voor je hem gebruikt. + +--- + +## 4. Object types + interfaces + +### Inline object type + +```typescript +const user: { name: string; age: number } = { name: "Tim", age: 30 }; +``` + +### Interface β€” herbruikbaar + +```typescript +interface User { + name: string; + age: number; + email?: string; // optional + readonly id: number; // alleen lezen +} + +const tim: User = { id: 1, name: "Tim", age: 30 }; +tim.id = 2; // ❌ Cannot assign to 'id' because it is a read-only property +``` + +### Nested objects + +```typescript +interface Post { + title: string; + author: { + name: string; + email: string; + }; + tags: string[]; +} +``` + +--- + +## 5. Arrays + tuples + +### Array + +```typescript +const numbers: number[] = [1, 2, 3]; +const names: string[] = ["Tim", "Lisa"]; + +// Alternatieve syntax: +const items: Array = ["a", "b"]; +``` + +### Tuple β€” vaste lengte, vaste types + +```typescript +const point: [number, number] = [10, 20]; +const userRecord: [string, number, boolean] = ["Tim", 30, true]; + +// Useful voor React state: +const [count, setCount] = useState(0); // [number, (n: number) => void] +``` + +--- + +## 6. Union + literal types + +### Union β€” meerdere mogelijke types + +```typescript +let id: string | number = "abc-123"; +id = 42; // ook OK + +function format(value: string | number) { + if (typeof value === "string") return value.toUpperCase(); + return value.toFixed(2); +} +``` + +### Literal types β€” vaste waarden + +```typescript +type Status = "pending" | "active" | "archived"; +let s: Status = "active"; +s = "deleted"; // ❌ Type '"deleted"' is not assignable to type 'Status' +``` + +Heel handig voor finite states. + +### Discriminated unions + +```typescript +type Result = + | { ok: true; data: User } + | { ok: false; error: string }; + +function handle(r: Result) { + if (r.ok) { + console.log(r.data.name); // TS weet: data bestaat hier + } else { + console.log(r.error); // TS weet: error bestaat hier + } +} +``` + +--- + +## 7. Functies typeren + +### Parameters + return type + +```typescript +function greet(name: string): string { + return `Hi ${name}`; +} +``` + +### Arrow function + +```typescript +const greet = (name: string): string => `Hi ${name}`; +``` + +### Optional + default parameters + +```typescript +function log(msg: string, level: string = "info") { ... } +function find(id: number, includeDeleted?: boolean) { ... } +``` + +### Function type as variable + +```typescript +type Handler = (event: string) => void; +const onClick: Handler = (e) => console.log(e); +``` + +### Void vs undefined + +- `void` = function returnt niets relevants (mag ook iets returnen, wordt genegeerd) +- `undefined` = explicit returnt undefined + +Voor handlers: `void`. Voor functies die niets returnen: `void` of laat weg. + +--- + +## 8. Generics β€” herbruikbare types + +Generics = types met een "parameter" β€” flexibel maar nog steeds type-safe. + +### Voorbeeld + +```typescript +function first(arr: T[]): T | undefined { + return arr[0]; +} + +const num = first([1, 2, 3]); // type: number | undefined +const str = first(["a", "b"]); // type: string | undefined +``` + +`` is een type-parameter β€” TS infereert per call. + +### Use cases + +**Array helpers**: +```typescript +function map(arr: T[], fn: (item: T) => U): U[] { ... } +``` + +**API responses**: +```typescript +interface ApiResponse { + ok: boolean; + data: T; + error?: string; +} + +const res: ApiResponse = await fetch(...); +``` + +**React components**: +```typescript +function List({ items, render }: { items: T[]; render: (i: T) => ReactNode }) { ... } +``` + +In het begin verwarrend, na een week tweede natuur. + +--- + +## 9. Type vs interface + +Twee manieren om custom types te maken β€” wat is verschil? + +```typescript +type User = { name: string; age: number }; +interface User { name: string; age: number; } +``` + +90% van de tijd: **uitwisselbaar**. + +### Verschillen + +| | Type | Interface | +|---|------|-----------| +| Unions | βœ“ | βœ— | +| Intersection | `A & B` | `extends` | +| Declaration merging | βœ— | βœ“ | +| Style | "modern" | "classic OOP" | + +### Aanrader + +- **Interface** voor objecten + classes (extends-pattern) +- **Type** voor unions, primitive aliases, complex types +- In team: kies één conventie, blijf consistent + +--- + +## 10. Type narrowing + +TS volgt je control-flow β€” types worden "smaller" binnen if-blocks. + +### typeof guard + +```typescript +function fmt(v: string | number) { + if (typeof v === "string") { + v.toUpperCase(); // OK + } else { + v.toFixed(2); // OK β€” v is number hier + } +} +``` + +### in guard + +```typescript +type Cat = { meow: () => void }; +type Dog = { bark: () => void }; + +function speak(animal: Cat | Dog) { + if ("bark" in animal) animal.bark(); + else animal.meow(); +} +``` + +### Null check + +```typescript +const user: User | null = getUser(); +if (user) { + user.name; // OK β€” user is User hier +} +``` + +### Type predicates + +```typescript +function isString(v: unknown): v is string { + return typeof v === "string"; +} + +if (isString(input)) { + input.toUpperCase(); // TS weet: input is string +} +``` + +--- + +## 11. Veelvoorkomende fouten + +### `any` overal + +```typescript +// ❌ +function process(data: any) { ... } + +// βœ“ +function process(data: unknown) { ... } +function process(data: { id: number; name: string }) { ... } +``` + +### Missing return type + +```typescript +// ❌ Return type onduidelijk +function fetchUser(id) { ... } + +// βœ“ +function fetchUser(id: number): Promise { ... } +``` + +### Optional chaining vergeten + +```typescript +const name = user.profile.name; // ❌ profile kan undefined zijn +const name = user.profile?.name; // βœ“ +``` + +### Non-null assertion misbruik + +```typescript +const el = document.getElementById("foo")!; // ⚠ "Ik beloof: niet null" +// Als 't wel null is β†’ runtime crash +``` + +Vermijd `!`. Liever: check expliciet. + +### `as any` om type-error te "fixen" + +```typescript +const data = response as any; // ❌ Verbergt fout, vangt 'm niet +``` + +Liever: fix het type, of gebruik `unknown` + check. + +--- + +## Bronnen + +- **TypeScript Handbook:** https://www.typescriptlang.org/docs/handbook/intro.html +- **TS Playground:** https://www.typescriptlang.org/play +- **Total TypeScript (Matt Pocock):** https://www.totaltypescript.com +- **Type Challenges:** https://github.com/type-challenges/type-challenges +- **React TypeScript Cheatsheet:** https://react-typescript-cheatsheet.netlify.app diff --git a/Les04-TypeScript-Fundamentals/Les04-Lesstof.pdf b/Les04-TypeScript-Fundamentals/Les04-Lesstof.pdf new file mode 100644 index 0000000..9c3bec5 --- /dev/null +++ b/Les04-TypeScript-Fundamentals/Les04-Lesstof.pdf @@ -0,0 +1,244 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 6 0 R /F5 7 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +6 0 obj +<< +/BaseFont /ZapfDingbats /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/BaseFont /Symbol /Name /F5 /Subtype /Type1 /Type /Font +>> +endobj +8 0 obj +<< +/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +9 0 obj +<< +/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 23 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/Contents 24 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +13 0 obj +<< +/Contents 25 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +14 0 obj +<< +/Contents 26 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +15 0 obj +<< +/Contents 27 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +16 0 obj +<< +/PageMode /UseNone /Pages 18 0 R /Type /Catalog +>> +endobj +17 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Lesstof) /Trapped /False +>> +endobj +18 0 obj +<< +/Count 9 /Kids [ 5 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R ] /Type /Pages +>> +endobj +19 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1701 +>> +stream +Gatn'>F3es&BE],.H[/7/@62(fTP$2q>dlql/=nl#5Z^6K@d.LAfWtS::>QINblaZY*]doFs>&'q2PA0*l3Bd(TW$5$\0$,G]q>^EL9FN"XJW?)u+:0IJ*r5>Ql8^TrEi-O@Zm2?tWdUTd2DQ&Hb`Bd40Z31ST#fJ`CfD0a6.DoVol]-qT[6J7o]j/bbhQ6un;l#:,Nhg3p^.:HS:p,$XN_c/ot)iablq":LN`"-;WG%"/CFsL`k6Vd5RpRX('d"q(nV=GmnLsi&sPK@mT\:/L_N6;(+-h-c>7AHu@mH.VrQd+i=g&iDdCV6*-mu]`0N+n[]6i#suOk\S(do8VCObFOh:eRT80Uh+6N7VDGF3X;dkH2;2u7GSJuTn9;LYrSp@EESfKg6R>EA/s)X!0LRK)NR>6U3u;R.-p;,(MGR#7h6Z^O?.EfCNB$Y"6c\&Cd,#].2u@K9B.P;OA"*'u!T>2[0JbTnjh;Yh5J+ouUe;.2(2n8(+C33(V?@^.cp^Q,[#lsDNGr):D[X=_#HY'5ihY+\7%CgddHKZ7dbH*+>ukpXb4"AEaf@BO^R>aJ9Y("N))5CCATB25\)=S_lfej@\jC0kGuq@2cVkCdGm"GBn*O#(8ofBm#e!4fb'3M5Ie\33l(M/j$HE1.[EZ-s:U'3HBbG&t?+:_OBp"`P2a]1DZOgHGCq2%1:,1>t%`OQf\``m9i@hL)amT[LAdlLY!)EQ&U]7gc^P[CgiC."Kao5/Mhq>K&D&D8J8n/Y*aL5FeLi1'./+B`D3;?V=]7pL'@A5+!Z.-S6&VF1&2?lAfTPW9WGRe1<&9T(Q.laIsBUr1Nd@m;H%'8:ASUZW1:fe#2:dVM?OG1s%p%c6F3FZqHZpICe>8eqs0@*d4H$f=-II%-a`F,5sR4pJB2@0Tqa;ssSTG9#@H!I_NYp\*kWk!.G7IYG[N4ad.fW"[fmk_ju^&YOcY^('_S<3'T*b/k*g3>dstdMAHK;DWC/F=VaR.fD3uERo&@:SZ*kTSkPgnkA[:qk-,G7k4Eu2p`Q4Bt3(FE5-iP<2V&:YSa]*Ba^SR:;s^5b;2s!T9_S&rus2(!<;R0W.4Gi-S[:7UWD3r-Git1`ps]r!pUSh-p;=f5^[0%!,pU(!KoMe)c(p2n=gnGWZ4="A"~>endstream +endobj +20 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2062 +>> +stream +Gau`Tq/>"G'`Qp<`Ig)lmZoOhFLE$poNF$b^#En]joJt&g/0%kRRFPTMuN0lPcVb_m'O`04,@F)qVLrfhaK;npgs-u-j=iTL&InX(l.>WQpVj\5)1N7dD$pC4mkBa&.q_NEZh'[+"3F"%B`46OG=5GlBB#-^^1haJhR1bn+f0=ThqugDT%)#*q]U?8AJI`n?0DWLrVN5G)5I0iT9f8quTME,i4D!dVSmo$tlf0;B;cV#\C1-_DHtgMjM1!_R"'Xb31+o')9uk.QT:gC3p:WbQ6ofm+Ksi]ee7`Xi&+]B7I^)0()iEV(QB-*,Jki:4Z#rYD9Qh@1I?HJ6lZ^\*BCjkR'mr,7SZ59Mu?IbIudE]qSSGgSJ.!o0udHB"Kk3L*:o$Q=?.mN`kl=ca.OA;W;]:B@`/e/_.22Od9]j1U-4nIIrnpsn+YQ.\'aDM<;VgV2Trf6<'XR_.j`$S,6eMkP)qKf5q$JX48!ngR4\qJV(1C.p]+Kpl9:0)EB;q[\\rh\iT#RV4eMsH6ODA\&82*N7$/a!c6ad$k?/5NI]uU4rpp+RDW]of`"RSr$Wu@Kr%i22:b8YHBsbaOZ,2O(dUQ;D5ht!_Q=[_Yni0KS1<=$X*"B&l2nr4%B/=*BLbC^u2Of_:XP!G-n>UY=hM6j6?[nhlrP`r2mt1=]M`8%FMhDomYKE'^AA$!`@f2XkRL[l]hE5Qhgm5/!0^S?F('N2&JBQR;*)*%9\G`<`Vq:PZEkb7MA1>G8k3BX37&_Ae:\>W[+c.h<]4gf-"K`cTGlVmeX_%")Cpi^:Lp5leF!8/HGCs%b_T@c4rf&0,,;*I,)p!Wnmfma>%XtA>Q!H#M;gZQIq"\)"YAigkK=L8bkHtrNfK';^I@8Go"pZ)AUbC"VL$J7Gd?'Er.+L`A#D]ReUOKnaQeD7U04FIh@/6Fa!3h@Eerr)#-bA3g"_k`2@5Tg-c'HDVM#T6nl2>]DMR'iQXb]QkQWpXuM@GNt+od0JMfarTQp9;P1,!5PiioG(fQs[$PpUiGB*MW)(;l,X6+*?:J5;4L[>-!>n=0R`C77?KUtBTcDsF/HBQV3Ima,h).V*h_[cuG%'cj46H^F$TV9Wdpg!ZV_[aBW<@0eD3Wm.D=*jkQDV"+1f**Z2@'*sG[SkY$4W>@<<1[q?2a"Gb.efZ0P"-lL3\/f-U,\-.!$tYoC_:G?#FWcPi#^n]CSFG08R+=WW[/Qd/endstream +endobj +21 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1537 +>> +stream +Gb"/&968iG&AIa;m,V&%otYea"QemaR5V0[1/6K$3VoIM)K!&?^7'6Qe]o&T])"n/j(1JV-c2(%[fDV@h4<"K<9d3nD)d>njOL8dh\t!?b(noGF-0[";&mHeIt`eud2U>F4St=4Oa%rD-Y8=#h,XaFX*+rTB=LWC$(R;$EfhT^^&33f%);fGi/+A*2#gbQNK0VFhN#5J4>QC$1_T;qnC]Faq&B>7S)Q_Z8NFIT<7j>,QT-fYsp<&pM@M-&f-3@EoBn)nF;j!(fM%M"2DR5XnVoQU-o@;H(>L'Fgj9KM!.W-+_]"JjC0kSk:hUTR&a@L#=-Hi*(4pK*R#3TuMj=?mO0HnsYSHFL7;9FEAkILV_S[r>@\tf)^UgasX`YF.=$)J37+^n9YWWm*V3sSOl[t\h[aWf!%>TN!JO!6rc7&21QArRXFTAS?80a'W?+9[N(k>R&@\mFNuS&6fn)/C5/GcI>8ijbi!i(`5\l4&L-h8qE?n\YZtIQRUUD6[:2h9rH(B9rl\bcabVW_hn&V]X*Y)n3,LF`hHFi"A,U4-mXVLAJdUtE9tE@GA*+%1"#LtK$4'I>"_-s^S8lK[NPY3oZ`g1Kp]f+rOMpnp(lJ55S2hC+pmUNAJ;^@"dcYHX#pe?-aqFNQddDGIaQh>C!cdfbq..^;W>(5i3#EAXBKRuP[$h1f%('*_Lg0Z;'t[HUqOK>M-QF@kEPm2"$GbEd&hojqfJP&m()meaQBP=IML))aEMN8C(5T.qO'`;VDYs'7'gYO[*Qb;oKCd%+Ma[+QP+9_IkD)ulX\/LZ!/fqC2!\"l6ua!XWKYUpqU[VVmcCJ9",K-9q.pRh(@~>endstream +endobj +22 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1499 +>> +stream +Gb"/&hc&;g&:X@\Z,93W]aF_B-(-USd%j>k_k_!moEBIN5<dm&R6u8i-D6?2=4l_Ehnb4S8'WB:\bNeS;j;AHik+XT"hC!5=r>mK!F0@NtY[aANNbm2((#&>%*UPb.0(9%S:$eTq&j"G?0LLP/%jJ"%X3-(ii/f^C#Y$h8]]WkNr/!dX!Ja"IST6gefcqnI^JlM'/LUO3fESc5Y2tJjb&<6a>_@1SnP.+jk((h.4!](o07Th8s4oMc[ZVOAIq'8)>nJE$-W)Su7IOkjn9tfL>eE:0O)H&F6dG:<Phhd_q-0D#jOJAmq01U%g9gn]i(TZMAU249Oc;W`*Xb+A/*VlQ0-AXk9dHQ<7qmJhS%O3Be7VZX;b)ggaqe5<3Apdq2>,%0q!KG7;HW"BUGt=B=?T'-o#)&f"\/3%tM&QV)>S'c`SF^oo[a;-HiL8+gZ[Nr-lR<,#Tgp"5_ft<=#<%kOmV+cf/&HT&hh=;WO)FQS/!#Xa(3plWDi9c26'K?#36(mi=`\GjHP!?HcZ\0*h^Y[DG]!#aE+#[qS`eoulco#p\U+AkrIfM.9PZJN4cSc+%BkgtgC]#8Z8C/JHj+Dqbj5G1/9E`Bs!/J]SSr\.J%35V$W%?Kqh$,Q`p2Nd6L^pT%kZL,I0BM)=-*?X=-%f`%UaDJopO??NKHr1Cg))6p%%-Alu'kr/,9=dVWo7eZpd?:O4`Ktg31)NQr[g7'B7p5pXk5p1Xs7r\.h`q:gN80r4_oEhDULoc7UgA\no,qidXs`Dg_%el]L(1b#7l.r)EA`4_'t:JLcBO(lq\mgt>8GkH:-^iA3jWNYqYc>lPPLQ3F_\4ZI>h2/,)%:lHU=ki3P8#K?7d9o9RE[)Yn3G.82F_rjm4nhKS9qJkW>r]A?A'DD5OK<(^piIa"E6g>V'+3hO[Ufc_r!gRo3rAVIm>j9QUlsuTWm(Di.m66RYgNb/K-Tghg'aBcF:,`cL8Ob+.nL+2ej&&&"WVom236Ld]$JTKRg/=C+Tra6=%mm=H6:[IUC)pGZ>L%&!@8Y6cQendstream +endobj +23 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1601 +>> +stream +Gb!ksD/\/e&H8h>Em826I'Rb8Q6PH\*[8rC$T)!_Nf?/B(J;BSAA6qnu+kfb#G0E["-!]a+(dT_d[M`a]VJOE)N$7E`U)Fo*F3cK=C!kAAs6OG@:&%N*b0@3hS7X\:lWj"?eM?<>VtGjF&dZo)r"ti"(e))Bn/l[mCZ?(+P0'%g\p]%P^*Fg4\.6-bss>Y&HLX73JA($*>;m!i`.VCkmE96UE)Y\g)MaB+jtoL1-E80F-^['FCTMYQe`b[Vh9&^lKU;qiCu?6s=e`VC`X%f9uiLFXG!2n*A-1h+`5X$-iUm,PuA=HZpk\G'p,SY8GYIYaEA!nITYH6K,fL]JWP;HanK4f(Q.2lNdlE2=@GWg(ngE:ZR!Oa7,"as>NV,1/TR3njW^\EK?GNERQDH*n%eVV9++$0_0LY?O[8KhC+6;;#VI`>U`@VkXnq88e]A;jV=rXeKjU7+0c1I%pn4DKXP9q?0d1Z^-QU_B^h]jl=FO,I:;]GAMblJ.mYIeRc_&KSDjFR:[K*#[`P;ul[Z/=T>4rL2Dp;$f=#D2g$T@3k!fUOCA_*4"u*@[g\)K=OB.GZ2'c1ecL^*R1JemJ]!1"8]%s8)`J%s*/bm\?*Y=5]#YgZD*',o'K+;Pj&7M0ZF<_3@<%OhZL])'#dIjHaPWJ#ZYWG*\2fT:tVbfW&$B3XiK`>=-(rDD*;3dck_SKCV?rU):p-o6J8C3:K&jO)@dgT&RuEH&WKjljYL./EP;[#\MX1;:$Q7":+@gV2a&kIOgm`_#r>5[$?8aB(8\4;2grig@&d>Pa349J"6/XWPtZq_'N])Dhd=5Z>)uYi01g0?DqXM>ck9`<_C.0,Z=7]+D"pPm/.<;*YZY]4!NqB\pKV+be=`7o)U?cd]&WZk(P!GY(tC!W-?ku$BAsnPYHE*;V^JuuX#'"6b**_TJ_53i8`\_7>Ur%tdD&[#GqS`7cMdLr:"#",$ltJ75HthN^SE=;aF]EScUtS5P7lQ#D,LP@f+"K\Sa49W53qm_p&=CYj'`9Z>[,.9O'f5sB,JrP?(O^C2jc2"?laqSTIStrV>B=R'cSD5#_Tj:Nf(&P-f/'6il*\dn#E]GemV]96K)Yg0a^6V~>endstream +endobj +24 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1607 +>> +stream +Gb"/&9lo&I&A@[:m-#^-<#>U,!0lMcd\^nEPA-5[m#0s-76r[JMGuma8LEhSn+$j\*3)or)^ARF=&Cp75Q\Fm"1*)In-'C)%i?]EM38p)M@lZd"WZ,caWq]4Me,13LB7+&mjgLSRcMQ:13W?9V.LR3hW'@\-4%"6/Ulg0=""UnhsamBaCF8n.$\q+pd&8,m%*F_T4fl;&0EGO1j+Q0#Q^W4:1b%4Fi^W8Qgi"N[9^`BXr(DAE,cQ(bYt:]7c;I3=j`J#TQXe)E';s"c,j"j2[r;h03*g'Ikm;_A64!M<:Q*drHegE^Lsu0A(sg6aDH8Q17M)IpZC1#[3miYQs#>`N;Gi3`YF0k188?8!fu`MqI!FIA#Rl1Hf]bhm?rb.FGRZ<07uL/Y%:Kb@To$ZiU3E-kGCsnp]>"#(LS(*SeR?-$ds7YsnoQo\ihf/f>\):Y$b4OBq:Y:sNNtAo+A72Ziop>c(VBr'B-:,EPrC[GG)3'1ngm'JbL:7^%G^-N8`q"59$d8&dn7CDnW%lu4`3WIiMRDO[oKS:O+iKM*q-:ZHT\GcX3*Gm1+DrYkq_6SVO4da-"%0\ZD3.#]_S!B%*QPj^pdMci`TF;0tQ#)["(!a7?2SjCgi49;"2=JAD)cSo!Gk\t0J).7?BW2-n"[ZsQhf`$HRF&9fEoUi6!-BDG\Bm`6fAes/H_`]7Au9^V?PT\GQW#G)r;.;t!-=Z'?Z_3Li"G9(.;[BAr+;,b^lFXJgYUSWD+Ee*N,EJqER>O&nNr(NQQZELGs#PHiu(indGLn:THau*AIO-*?.GHC3cEP/Kn]eh)6KE@b'0(XieBRGJM7_c]%\\+t:pr^o#G)IrPgQendstream +endobj +25 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1925 +>> +stream +Gb!#[lYkN9&HAoJiXfLMdj9rD8JL9f/Q-]D1'DIG])=DQK<3F[&j9-LN`uY^hfklfG5Xs8+Ic`D:3Xb=nUC5*@,m`Fh^AYQ21hT%$C&A?$Ig@SN6^CkOnIBON&0AaJ2kDh!X9ohoF$PEQ%?s^%p2(_fKKn]$a--jLd1r-3T$_u'G@:h/.0>Y[P(l.JpL\kDr_qU)8i:Vic-$@b1H=nD-fJPD&o'JI8Cf%d!AWm.1G(GrH&6nj>0q.Q[,1<7odXo;Se_T+&:,>[ChbrINsc!(gXuAR9lPaeE$b@_#7i@kHZX=5-:'^$YOGpK&9Mr(OE=5^fbLiG61+AkG%,k6>[W[FAI7cgoT=ATg&kTO<-Z%\\;F][\Y:9.r6fiO]qd+@_9)+Vhg'TZLJXupc=T.+*JaD"A!QEZG$]nNY#2'A2fgiXXY<(c.>24l>k6dm;ALqD3J<;E<\Tdg\f;4d+liO]SQJ-%)D$:(05on8j-%o&U8(X\%CSH9_WjoOK>DmP7LGkP75JJO9!ao,@to1]>ZuRCqOZ#)5b7oU(*1sr+_DT]0c`2V*T"UCs(gQOV1fog[p'_Sl[!$)oqQ%YcQX+e)4\aD6?%nhG7Z9mQ3S6ffnD!8IL%e;_=71`a#/8Nj$AWgnNK'b!TnL]j;/HsO`1OB:iO0"SiffUkGaA@)_Gi7X,E2lap)Jr>Y5/5M0U(YA[)LKD:eks&TaN^oJIu/kf,QeIDW^UTZThDG+YAh/3l\ZRo>L.&W'O+-;4[/C@O\V\%+X,c76]NY7S*G)[#+Kj993!I"5o@Foi`^n)dmG>G/H?U'5Fr0b*QpI0I]ac%,'C^,q,g\\:DIhj4$i+V:?<;N0?KQ.UCBD105s0Lg4m-mMUpuqCQk]c_iG\$b]t^^'cgY\)95@T(7:G$.i!eH&)Qq[I9#;c/X[XcJ/D@ENQ;iIn\+A1joh$9K#$aA]dm'e7abK;"NNG27;XApkCi>*hC1_QY=iM&dIJ^0#TbGD;pq=ODKN!h^.=pG3m[17a@$6'7^K\X/7>(EC!ug#BnA41T[@*!iokZ)PKHN403[RL;p.X9^JFB(QOh:qNu:FVToe3MM_Xit[Vj`&^9_?.#&9r^J+Q8j#]LD:a*pgp9t0Ni$+KrJK8Ph#3eZg$+0OX$rQT;6fe!]NYrmP.&mn?jTu8)_C#>;`&^V4^.,,Q-!DOGI)1H[8_1o=c=>HDSo#5VVhdiBs0endstream +endobj +26 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1275 +>> +stream +Gb"/&;3T]l&:XAWfXWBNKpP&8k`H9TYtda#58@(]%fY'.Qu-"CoE)k6;0#Op1^-8ubqJb]X,724mfi9.ZBLP#jWSGIauiHbM*'R9HXq:\EVB8?^:^`ZmB"K+Kg7R@4ZLml@Ek)`5<4``;"cacKEgL#p!?&=<3q>Zhc((2$2BfZD\g50(ugdo,Wcr^NohlI`^0HLc/D%^hoL_BN)d"&.Uq=KGX2-PADoD1!G-&q(qE2"%ntX947Z3oT^tb10[a$^P1u5%7,(9hPpuB#`R8AEK;7$]2W?J-Q#nk4hmSkaT\[b:2Y069Tb!'_PmCFQcf@)&E_.L^DB$hlm'`%iu)8A#>>lP?E4.n_DnQYM"o+6^s8XD=%0O*`1b&u'3g[&4@:`DH.O7/0p,s_=;@?P*]?jGjs*?p#7WXnX>5EE"P0)]Xn14_C!4q'eYMENS,P^AK`+o>Mk*`Dn`il(Lar(/LW,GP.:QZ6;Fl3MB,B*^Ec?\u)i-]1L,D_r%h4M&)g_=rAPo`_hQH)bQ]aVB.;4,A80U\@EIFY%`GDS,TRYGm[K>.K,i!N;S<'QKD_fUo)&iD897aO_U"Mu;7;MqT,SgrLHLEqFa,GT+jE'6EN5#r?sET&[5\7o1giA-rkDU*#4361\7)hGD1iS#5$>\e=`0Xp`JSV>fEI[$Zt$&:k0;n,ibAqsB?S&&9og@,B*SM8sj?K:]/k)A)A&k^'4]KY#tZrq<_-G'1ND%PT)O0H9D.c9F#C$fuPN2*VA76g#Cp@S4]"f21Em8g[Oa2L,]$8cD>6b6!u]6#d!/pdq%K0hZJb~>endstream +endobj +27 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1820 +>> +stream +Gb!l_>BALX'S,*:'rQ=+l*`pAD_g.l[,#>_R9n=-p5+Pc7Y$,RW%F0E48nVpA:/q2#UDKGB/VFuQ@5nsTB'Jd'L/\o+&;p/pRlTGJ8sc^J[r^QhJ7AhCOL%3mdn6eJ2i-A+U8W@p(+H+97c7>5NEsi5m&;4(L4e4&>9)aE^@JBa"@Vh&f<#j1s"^F&C\T5ujV'$p^TBdhSI@-C9/O0!mYV62I*"@$!gqHE$ldDL[$PA$2Z#f7kkmkKH[#+q6"q&Ub;THRp]72TU0O6NX)M_s2\ZnS,*HT3(`[,hM.,.7)Gg2[A)K$@,_J"KQ(#0S6c\gMCG@j*'<%m7U'04l9_:!qhOY]#U/\II9fkL>`\YT+KW0!2`WdeS;S=qEV>?Fj4%;g[`1((';[A3Y45K3D(<:f1?a=Y:JYQq'N?oS?-#a+W"Jr0CM,e*go5;1onk?PVlRkg-%]TCTkBo@]AsYd>%I%qP3:DD-I"YO?nQ)4`V`mE465sLCZ$"ATYCO)@cY`I(9J'p8QmW!(->/O5l"mAF-qui'Pfp/c:'S=NZ&J147/hD'YD%!CN!dW)@2DZo4\]tm]=mq$Xu(HheM,dD`cj6)@$Eu?NY5p64I=_l)Q@V/dWKP0E'j<^6]$hVeFVmMX04HB#>T9sL5++#(ap+h6qNP>i/Vp(ZF#e^5fnp&N"*t5P@kTSn#'0*t>71XCs:*`k!QH?u28>+(;BatX_>bIQTN?rl3Km1L>T6pPa8$]Z\$%`n);*M^.O)Q(9QfQaU!3i3r//hE$bn+31ZOsQ/bA!-piO]eP;0G4kMaZ$1/DK^g4/j=**^Au.]?`"Wd@Eo^niH:HT6tamg3_PI+A,F&6L0@mW9]u*)^c!BmB.!3fSkE20ea6b_b/>[*Ob'3tS&]Ih.K'-`>(Cl3&ffN+C52IPU8i8c-Q(kf@&rWKkTPmqYt821VG^A4N+0+u*A>Df1AP$EZT0n2'me;-"m2Nl,"e:\).&J>2S8,Cqr.^[IfUNkR5+~>endstream +endobj +xref +0 28 +0000000000 65535 f +0000000061 00000 n +0000000132 00000 n +0000000239 00000 n +0000000351 00000 n +0000000456 00000 n +0000000661 00000 n +0000000744 00000 n +0000000821 00000 n +0000001026 00000 n +0000001231 00000 n +0000001437 00000 n +0000001643 00000 n +0000001849 00000 n +0000002055 00000 n +0000002261 00000 n +0000002467 00000 n +0000002537 00000 n +0000002822 00000 n +0000002936 00000 n +0000004729 00000 n +0000006883 00000 n +0000008512 00000 n +0000010103 00000 n +0000011796 00000 n +0000013495 00000 n +0000015512 00000 n +0000016879 00000 n +trailer +<< +/ID +[<4d415ea91cae7983bc552f3a1da04e2d><4d415ea91cae7983bc552f3a1da04e2d>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 17 0 R +/Root 16 0 R +/Size 28 +>> +startxref +18791 +%%EOF diff --git a/Les04-TypeScript-Fundamentals/Les04-Slides.pdf b/Les04-TypeScript-Fundamentals/Les04-Slides.pdf new file mode 100644 index 0000000..9db966d Binary files /dev/null and b/Les04-TypeScript-Fundamentals/Les04-Slides.pdf differ diff --git a/Les04-TypeScript-Fundamentals/Les04-Slides.pptx b/Les04-TypeScript-Fundamentals/Les04-Slides.pptx new file mode 100644 index 0000000..7458584 Binary files /dev/null and b/Les04-TypeScript-Fundamentals/Les04-Slides.pptx differ diff --git a/Les05-NextJS-Basics/Les05-Huiswerk.md b/Les05-NextJS-Basics/Les05-Huiswerk.md new file mode 100644 index 0000000..eff9e72 --- /dev/null +++ b/Les05-NextJS-Basics/Les05-Huiswerk.md @@ -0,0 +1,75 @@ +# Les 5 β€” Huiswerk +## QuickPoll uitbreiden + Next.js verkennen + +**Deadline:** Voor volgende les +**Inleveren:** GitHub repo link via Teams + +--- + +## Opdracht 1 β€” Push naar GitHub + +Als je dat nog niet hebt gedaan: + +```bash +cd quickpoll +git init +git add . +git commit -m "QuickPoll Part 1 β€” Les 5" +# Maak nieuwe repo op github.com/new (public) +git branch -M main +git remote add origin https://github.com/JOUW-USER/quickpoll.git +git push -u origin main +``` + +--- + +## Opdracht 2 β€” Voeg 3 polls toe + statistiek + +Pas `lib/data.ts` aan: voeg minstens **3 polls** toe met diverse opties. Op de homepage: toon het totale aantal stemmen per poll (sum van votes). + +--- + +## Opdracht 3 β€” Detail-pagina aanvulling + +Voeg op de poll-detailpagina toe: +- Aantal totaal stemmen (boven de buttons) +- Percentage per optie (bv. "45%") naast votes-aantal +- Een "Terug naar overzicht" link naar homepage + +--- + +## Opdracht 4 β€” Eigen polish (vrij) + +Kies minstens **één**: +- Mooie skeleton in `app/loading.tsx` +- Custom 404 in `app/not-found.tsx` +- Hover-animatie op poll-items +- Mobile-vriendelijke styling (responsive grid) + +--- + +## Opdracht 5 β€” Reflectie (200 woorden) + +Schrijf een korte reflectie: +- Wat snap je nog niet over Server vs Client Components? +- Welke onderdelen voelden makkelijk? Welke lastig? +- Wat zou je willen leren over Next.js dat we nog niet hebben gedaan? + +Plak in een `REFLECTIE.md` in je repo. + +--- + +## Inleveren + +GitHub repo URL via Teams. Aan het eind moet je `pnpm dev` runnen en alles werken β€” geen broken pages. + +--- + +## Tips + +- **Commit per opdracht** β€” kleinere commits = makkelijker review +- **Test mobile** β€” Chrome DevTools β†’ toggle device toolbar +- **Vraag hulp** in Teams als je vastloopt +- **Tijdsindicatie:** ~1,5 uur + +Volgende les bouwen we Server Actions in β€” Part 2 van QuickPoll. diff --git a/Les05-NextJS-Basics/Les05-Huiswerk.pdf b/Les05-NextJS-Basics/Les05-Huiswerk.pdf new file mode 100644 index 0000000..a5ebd07 --- /dev/null +++ b/Les05-NextJS-Basics/Les05-Huiswerk.pdf @@ -0,0 +1,105 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 6 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/Contents 11 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 10 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +6 0 obj +<< +/BaseFont /Symbol /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/Contents 12 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 10 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/PageMode /UseNone /Pages 10 0 R /Type /Catalog +>> +endobj +9 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Huiswerk) /Trapped /False +>> +endobj +10 0 obj +<< +/Count 2 /Kids [ 5 0 R 7 0 R ] /Type /Pages +>> +endobj +11 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1876 +>> +stream +GauHK=``=U&:WfGfQ!fFE]SekO9Cr[[(.Q`SO@I)oKl-*`0c>(6_n5k2bWhaIV9q\1B\)))QLDnoW;_XmrCRQ>X&iBEU2#=Ksi!Y-Iejq%$JPChs25MuPE73tgZ"]mFQ<1nc:SrB21qJQ"T-j(UYL/)CC',--\&C)C>qBY9"W&FpcGKsE+D)+BL\$1iYR-H@cT%6%G`ed)94;pLeqKBcuBk/S,^'CrOd\AfSh1A)auoq`Ce0On^XVj&Te;VJ("M^))(I`mK^s>B$;!A3fP-V?&Y\&l4g6H8WkXB2*/Bas4JoeIg=nBqWd5)\pU-:TdIdIIFLt2486PVr:neG6X^e[;9@jPNI?pYI'(/G_fO11nGX1W60H:/;?IWGbW.ZRYb0qP:pTBG7J/&BW9-C-D4;/ffK0q#maH?ZZirh".)HrWt2;_c2f'7RW*at#U?f5E2hO6:'mWDIaf`ogQ\sa;>2G*R)bXS(:*_2.Aj_;[8-P+&(ZL6$00O:bgr"5)G8l#h9bV8WL@"iZmA>QHHPiWJeh68NT:%V[I;+CEUnb0h*^\;Qb4B"Uf@1SLDF_F?6FOUjlo*Mk;OHd]bCRC-;P_0Gn;-K2F4li+KaapBVQ=0;h7`\,S`jA-]"bE]`+FC5s6uTr-IZF:\bRE9/An;hF/c[+QNV=8.SKp6"*+Q1C96*MGn9kl2FE[;d=eP,9T6B(c3U`=3Fbr.FV8&URWkq_:A?K2oJ/usaKjK4So+"T6(:qeM*q;endstream +endobj +12 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1429 +>> +stream +Gb!;d968iG&AJ$ClqtmS0EFAfR81bES_=`)YoUipkQ6Sp"UP<6&sCZaqV/WT*iEhejJUMpXqs?]a4FGQ=F&2l7R_mI!$C!i&$T&t,U_e!=*rL"C=N'2A"QCf#hdo'a^AEO45L9s2,jMZfKuAm@&dJsnPU&gZ!J^L2R)Vr/\:&]hJ]*Ze-NT<^L/AT>g[C>^0iT0T0T*H2q\SrPcFbcd(=o1Io*^92$G(1k-.NN^8&I<>["-H"cSt$+Ao^`ZL;kY:C+D"U>3I[V_sobb-Dj+t;H.QW*C9PQ.;0"s,"eT^Mqlf?0A\_WeZ$1G]cr+kO$X(5$Eq=-;cE>#Ec[H1m2Wr@>WHR_Db\&6VHc9IMn>@g:[P'kSkW9dT)QkZU^bjH[rtnBTQ:re["4r#c?;>?]S)CID0"!$=E$,$?UX#T9ku^cR"Q5M9S#cjGP/T"bo,Dl_J1i.=."@B;dsKp_DHptO2jts]n?,!`G7!q#Mjgm7,e:GQ^PAYcD5L;.T,/;'B;mJ]-X3j10cYO-,<@Lqm[sh)<^k1q`DnG8>9.]m+Jj#'d(&Jjbe/dCL*RH^GnAJcVI,pD,*$-ccB+.Buoi0\;=VZe5d#)0lT"D\\.;O7Pt@X8R>C8.uo!ABJT;hLRUnOpd^\VjG%1?1Ir3[MhWrs<-'P:lD(,ha+?5P/"bIP_J4/9_U,/"1*j>N;b)J_AVBckM2@J;5`sOleh&?Ds?\NYU[_Ah4@Z*B!b8a,7C;&lU5kY@]uTMFB"0MhU*OX6gao$nG6^G>:m&r44q%"WKA*0\Y0oGQQIW\Iu':j?VW^U\_WL@6J[-cu(>YEu7YO\W)%WW^2B<*Oe_IBe!UbqkDg,^.BM==cJ@h#CJBS[[mDerY34[E^-QcHQrp92+$&uMr,A:]7U)C%doh.%%.nNp0pKQ`^(B$""k4ET1:AhISZ+%Y9n9D^;M8D-7?^I56MZr3W~>endstream +endobj +xref +0 13 +0000000000 65535 f +0000000061 00000 n +0000000122 00000 n +0000000229 00000 n +0000000341 00000 n +0000000446 00000 n +0000000651 00000 n +0000000728 00000 n +0000000933 00000 n +0000001002 00000 n +0000001287 00000 n +0000001353 00000 n +0000003321 00000 n +trailer +<< +/ID +[<9039fd2d998a3bef32f6fb1a7e765539><9039fd2d998a3bef32f6fb1a7e765539>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 9 0 R +/Root 8 0 R +/Size 13 +>> +startxref +4842 +%%EOF diff --git a/Les05-NextJS-Basics/Les05-Lesopdracht.md b/Les05-NextJS-Basics/Les05-Lesopdracht.md new file mode 100644 index 0000000..0a5a45f --- /dev/null +++ b/Les05-NextJS-Basics/Les05-Lesopdracht.md @@ -0,0 +1,168 @@ +# Les 5 β€” Lesopdracht +## QuickPoll Part 1 β€” bouw de basis + +**Duur:** ~120 minuten klassikaal bouwen + +--- + +## Doel + +Aan het einde heb je een werkende **QuickPoll Part 1**: lijst van polls op homepage, click β†’ detail-page, voting met lokale state (data verdwijnt bij refresh β€” dat lossen we Les 7 op). + +--- + +## Stap 1 β€” Setup + +```bash +pnpm create next-app@latest quickpoll \ + --typescript --tailwind --app --no-src-dir --import-alias "@/*" +cd quickpoll +pnpm dev +``` + +Check: localhost:3000 toont Next.js welcome. + +--- + +## Stap 2 β€” In-memory data + +`lib/data.ts`: + +```typescript +export const polls = [ + { + id: "1", + title: "Beste taal?", + options: [ + { id: "a", text: "TypeScript", votes: 0 }, + { id: "b", text: "Python", votes: 0 }, + { id: "c", text: "Go", votes: 0 }, + ], + }, +]; + +export function getPoll(id: string) { + return polls.find(p => p.id === id); +} +``` + +--- + +## Stap 3 β€” Homepage + +`app/page.tsx`: + +```tsx +import { polls } from "@/lib/data"; +import Link from "next/link"; + +export default function Home() { + return ( +
+

QuickPoll

+
    + {polls.map(p => ( +
  • + + {p.title} + +
  • + ))} +
+
+ ); +} +``` + +--- + +## Stap 4 β€” Detail-page + +`app/poll/[id]/page.tsx`: + +```tsx +import { getPoll } from "@/lib/data"; +import { notFound } from "next/navigation"; +import { VoteForm } from "@/components/VoteForm"; + +export default async function PollPage({ + params, +}: { params: Promise<{ id: string }> }) { + const { id } = await params; + const poll = getPoll(id); + if (!poll) notFound(); + return ( +
+

{poll.title}

+ +
+ ); +} +``` + +--- + +## Stap 5 β€” VoteForm (Client Component) + +`components/VoteForm.tsx`: + +```tsx +"use client"; +import { useState } from "react"; + +export function VoteForm({ poll }) { + const [votes, setVotes] = useState(poll.options); + const [voted, setVoted] = useState(false); + + function vote(optionId: string) { + setVotes(prev => prev.map(o => + o.id === optionId ? { ...o, votes: o.votes + 1 } : o + )); + setVoted(true); + } + + return ( +
+ {votes.map(o => ( + + ))} + {voted &&

Bedankt voor je stem!

} +
+ ); +} +``` + +--- + +## Eisen + +- [ ] Next.js project draait lokaal +- [ ] Homepage toont lijst polls +- [ ] Klik op poll β†’ detail-pagina +- [ ] Voting werkt lokaal (visuele update) +- [ ] not-found.tsx voor onbekende poll IDs +- [ ] Tailwind styling β€” leesbaar + +--- + +## Bonus + +- Voeg een 2e poll toe in `lib/data.ts` +- Maak een `app/loading.tsx` met een mooi skeleton +- Voeg basic styling polish toe (hover effects, transitions) + +--- + +## Klaar? + +Volgende les: Server Actions + form handling + voorbereiding op Supabase. Daarna Les 7 = echte database. diff --git a/Les05-NextJS-Basics/Les05-Lesopdracht.pdf b/Les05-NextJS-Basics/Les05-Lesopdracht.pdf index 60579f6..2cfc0fe 100644 --- a/Les05-NextJS-Basics/Les05-Lesopdracht.pdf +++ b/Les05-NextJS-Basics/Les05-Lesopdracht.pdf @@ -2,7 +2,7 @@ %“Œ‹ž ReportLab Generated PDF document (opensource) 1 0 obj << -/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 7 0 R +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R >> endobj 2 0 obj @@ -17,22 +17,17 @@ endobj endobj 4 0 obj << -/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +/BaseFont /Symbol /Name /F3 /Subtype /Type1 /Type /Font >> endobj 5 0 obj << -/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << -/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ->> /Rotate 0 /Trans << - ->> - /Type /Page +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font >> endobj 6 0 obj << -/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << +/Contents 14 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 13 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -42,12 +37,17 @@ endobj endobj 7 0 obj << -/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font +/Contents 15 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 13 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page >> endobj 8 0 obj << -/Contents 23 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << +/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 13 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -57,7 +57,7 @@ endobj endobj 9 0 obj << -/Contents 24 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << +/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 13 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -67,7 +67,7 @@ endobj endobj 10 0 obj << -/Contents 25 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << +/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 13 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << @@ -77,220 +77,86 @@ endobj endobj 11 0 obj << -/Contents 26 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << -/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ->> /Rotate 0 /Trans << - ->> - /Type /Page +/PageMode /UseNone /Pages 13 0 R /Type /Catalog >> endobj 12 0 obj << -/Contents 27 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << -/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ->> /Rotate 0 /Trans << - ->> - /Type /Page +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Lesopdracht) /Trapped /False >> endobj 13 0 obj << -/Contents 28 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << -/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ->> /Rotate 0 /Trans << - ->> - /Type /Page +/Count 5 /Kids [ 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R ] /Type /Pages >> endobj 14 0 obj << -/Contents 29 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << -/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ->> /Rotate 0 /Trans << - ->> - /Type /Page +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1580 >> +stream +Gatm;968iG&AIa;m,[5<.Mr[/!.@J.e?*@=Bj@]!q*J#a7>i@(P-UQMIsVuZ!0h$IXqOAo$/jgt#JY\C!Q@"`Y3?k_f/XhC112*af>']c_Yc4f2@o3W_Bi8l"@QoQ@LaY!p'(+`:d?:_N-WW4;an&#+k2Ha*GaSX:+<'52K8UI?pKsP8r#YgMklYck67!F<13$7;ES6qJXj[12uc1hF(n'*n.e\]K^3fEC7TUH"u=5+!Z#,:\]V7fURA#85@bK2>!b>UeaDL^C!-hO2;dC;KjP65m?;@tN&U@eQn\P=-f7K0s-"m\QF/\!%#[gNbJ$F$%mH;6MM[.%6:YFc[]Zln5Rr=9eP.$.G=NoUR3e6q7oMdJ/"$F+KE>l)F,V&ZTQ@^$e')Ums3L@srP/kI]KB*fYJW5O>ucMb(dRB&9eSn;,&N*Fi"#GL-6J;q)t-H6BKfO<5/4@SS^*\,_40;QA`=^(BtUSM5=N!P5kX]"0#U7#jj_RC*'HcSo"^rk4Bb`JfSbO.o!-ZBmKme.J+1lHN(F'$H&o+ZlGO.\H1B=iO6Z`FZqU'!qf%?J4LX-5-1VcLc-,jYA$Z.V&/*(s.kV+D/pjec-*D,qFs6"S+HqC3:FDX(i_4R^6^iHMpo:dt,;IpMimr5KGlT%pusK3('@o0N(Th-i"pds/U%fb$0#Y^'s,lQ+u2JP\=WrPnWan$r2?<<*JD#\Dd=58G?N2unc2@Ka>j`6[:%+43YZi98X%;tohSiAcF=)00,U'qu%Yil1`&LWHi!or7<72(83G!$;,98YQ;1SD%m8I`ik=l:N3mkG@CXINsfOJ@dO;+oU/XXb&E+uK5eptTp4ICHFnT'HE)!&@K\/XHAaKsWuKmQ4j:oo5RJn;JNIBpO/ci-d`91nCDM8Us,`0Ahp/`1(Q/ClphN!IW6hi(#58d3dDrAhHchWLgRp:e_'mX;etm`Q!eWke;Bg\hPK&NRpoMC8Vs(_1LBnI`mcrKSEH#GP!:>R8Kb(MTI9:c7%,L;q6lW4h+sROL)ai+I$6o!WLMnEgqA/l?1bl7=-,T[rj\!^%"=Ba^ohi#U/UQ8;Z1F&&tRkN(>lFg$,.ZW\pT[YnSb55OC#$WqSNV0H9Frf%>(pbKIpRnI\XV,U5;;+TZ2]p3VM2I@XB??!nF1@'8Kb7)s(?cC-eb/[?92ft&YKe=1)B")m$<^O,RZ/ri`HrZUNJV$h5'e&S=1;5'D-:=cJ&+[>gBR7/:U/'T+G749)AVUH#4mp:JY/+A][,NB@^\2\ZMnb-:\"QSnXkWHj)>)/+04aRG'.WOOLEgmd6"?Op^\EhD3F~>endstream endobj 15 0 obj << -/Contents 30 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << -/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ->> /Rotate 0 /Trans << - ->> - /Type /Page +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1461 >> +stream +Gau`S@;jmY&H/b=EA7+&.;G0p;HV1f'lTVBjTiBS!AhA1ZVDb\bCH>K"-[ATU'ZQn"Bkd/`/&9u)tle7!q1A#kYdd:,]]iMFF$58?HgDC+--d^@2KV)][n3!0l2QGGkTEZ/'eDRGE&(JSM+CgAD,V$+iS%pQ7@m'N#Ni4fB,a?/^YmDGN7UJ'(5XP`Z[2/)!r.Fg1D5P)TR<'1lhN/CE33dg4I_\ephKUS0J<;Q.\[no's;n:#c^!H+JaHcf7!r*7'6])"]oqpd&/.!-T,(=#Ea)MM4mK#J8C@,JK(E]c..0,)'j/#:Ij)Ru1WE2+R_jmCmC\?nSaB>cMcp>IdtYu%F.0kn8]E~>endstream endobj 16 0 obj << -/Contents 31 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << -/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ->> /Rotate 0 /Trans << - ->> - /Type /Page +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1117 >> +stream +GasJRD3(GM&BE]".AhC0Sf2)X5I'$M[CnK`8Z02&RbfROGR6s?GY#Z]9=;od58slim:lqU"QT=&h_Tm4"L($[qjeE$^TJ_^&Khe=>9F>/=FZ"]fA=7`U4Q"W!JLl9&Hrl&mK<.-.tJ'R+rV%i=<]%/0L_($OTK:bUa-T<'XmHm!_"LVHQS-@5hLV%S7Q!5G@;e%@`;oaS#&Jb;+f?ijmZ,9AUc%K2YPeR;DB!VE=7=fER75lS,f]MJauV/_A)+dh!IH\c&B#ofVtg4e77aKmTiPhY^6$BId3Km+BW4f5G>*/B7g#_X(]dh-_jPB^T7-q-fYg7j\U<4crh_L#]:"R'k(j;gY!<4n8b\R?MZ%?)hop&6crTidhZ2=F@fH\RZ"po";XD_=lq8:G)8A)E+h4lroM9!`oFEm&r9ZGj_f><+I,aj]ieYU;5u(e5d7C?fJW;]P&9jddQ^iIiA;+f-FI/oZB/Z(cE:F:G7ZRSS'UD/Jg%hmgdck@^KMfmm/Q#3gD)l7D4p]!#F!5*)R6NCWrI@f-j"lCh#'f#+T.Ll^~>endstream endobj 17 0 obj << -/Contents 32 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << -/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] ->> /Rotate 0 /Trans << - ->> - /Type /Page +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1872 >> +stream +Gb!#\gN)%,&:N/3D#KHXdg-"?&--"ZSYh5kSu-3XVS[N6aQ8g6Fd1!il3XTSpSLt8.%Nq8KE$8M^ak9C1!8ZK,tU7!O>]JJFgP&iH3Lb#=25C^^LQh3BaGO1E'rC&C[_0/S]W/`!b\]TVO%-)QHHoQa;G&?g3-Yjt%]u\Fg;ZR9O(&W"TYKWi"Chg7CQs[Z,H"ioV.U5SN8#Y18DbY,u+S/g1?i>,7p`Ol*mkK\/MW>4(mSs`Mit5^aGnM@O*pZ@`&K5(K$$YpR#Ot>5Z^GY3i#WkIR>#pl8KBp,sAn*gAN5$@PP)<'f.h3)KEm%jqg7nC@=^5g-AJ*W!51m`Bg+6QhY9C;N"?26+\/m=S*5[tF]+2'P8RB3Q916p05]2Gl1]IPhX]LF##u,5>R`lS'6Z+oC3/Y#Rpd'f[gr<^s;/V,>R7DoE6h/%-j18Q,^("(6?nngT3"(`h0=!97%u6'i/s3!*6FUV.Q@o:_Ai",1_=q&0KFn$T,+Th7OQlt_7A(U8lN%q3=0:C$ji-1dE4Lm>NnX4_=H&/S4.I6B1nbCp9\p2:FsJMt%jmH\>j%V8OI7Q+=TXNO!&QTuNX*@>&74AMp@J3Q+.LqLT)))9\XN#?TgVaM"SG/9;qG"b\kEWt@9O<\4*M2;)4b](_Bo@@PpEN1`N>O.)fmmK/dl86^eBW#=4s'\P96Q=\X?_V``W$"^i!!li8S\]dcK,;eNT`Nbl..S"LBR;K=h>q?-W(gp%%^"ZJ&b0/'O>h&t)`#l,8-oRft-kb\iW["RsN>RdB6c4]uFse\n:9M'Ir3%?%7f&mX%8:7oHi2)'cu>1%cXa&l*Y$"g!oHZMbeLU5DPaf>jHRFJt9aD"h9c,qS4b>8bL"8cZmHW:0EcruG_uG&3j0^V'WEoa2P'lXCr+Z`H*plsg-6"a4\:V"[r-!7.7QES:rm/r7Lm'1lmOgOk]V-Ld3nJSW/8E+*^\0_%*Be+@1dZ@e.miOgsp4N6/5e7Gj_Qa1cnBs>oAa)^t"YbGZ]Tlqh1j];\+mC!*;O]CGj`?HX7kYs+S&SZPDopVt3"p"'BTCD1e?]KgIE.]pHUDPrH,m>Ccsfr./m$a_e50MRd*>PEuF+E',fH"5q1S"+7PKCVt77$ok6Q'>>/(oXrp14V=+.;3B%n08u&PBZW@[fp(MVGJ)6FP=IGf!,f%+[.OrnNr@eg$PFq`$G/s1N4U1;&_'C=i$%D>t_GIQt"9.\Bo$Sl>q]k"qSZ&p:e>"ses.VdI!nK%GeR!E-r5"gZTKiOlX2Vpo#a;,GM;=\A'V8*?62F^$s/T%GUq8kgrha^[h`j>"V^R0"/DY?7mWIGB`29Kq`R]d*Dm2UbI_k<922qM9<-?RM~>endstream endobj 18 0 obj << -/PageMode /UseNone /Pages 20 0 R /Type /Catalog ->> -endobj -19 0 obj -<< -/Author (\(anonymous\)) /CreationDate (D:20260311071405+01'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260311071405+01'00') /Producer (ReportLab PDF Library - \(opensource\)) - /Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False ->> -endobj -20 0 obj -<< -/Count 12 /Kids [ 5 0 R 6 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R - 16 0 R 17 0 R ] /Type /Pages ->> -endobj -21 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1904 +/Filter [ /ASCII85Decode /FlateDecode ] /Length 596 >> stream -Gat=,a`?-*&A@ZcqVi4V:nsGp@+-E5/+Q`$(6`<2--cMo7heL1!^P2b+lAk4llZo_;,l_S3\`rD_Z$>LJe!;1F@C:Hu4ZR]d/U>5jG$mA)HB20HDT'KpYKKs-g/\bq/P;[MECPV.pRonIM:7a9qm(-T4rGhC;.G%l3RBuN3,gsrQot>S_K"seU#Qsh(,BjJY?c@YsPu%=TocgE+\LK?9BE]jbd%%3G&+K6,KTd3->b15;fUBp)baWGl,6K"nAh6o1>O9]*,*?jEC-ian&_Nm^XVQ)Jk$7Pc8S^ie9IO-EF?>B,/Yr_bWWc##K`dcn-#8lsFY[&\Y`Z.X=ig*A4S)8q-%b@rMT(R,fU&!g;9cpsP!DWAb@S!N[PCEq8.+*W(uiE/gj5Hl$tkZ61'lA7]Gl/0_\L6bCfA@\!sbM&51]_=$[<]4n2]3617>s`-@;/r06$0&13)XmmD%_ga<.ftZr%p#s60.MQ@eItFZXH%+1+Ob:;/'X-G;qs2dZPpR#6_/EZ-2KTe@I0ae,A[oeT)4UTS.tYV@Vo=!*9I4"=EE%BK;,hWgUn%Q>cbOHT\lXY5Ne6Z;4i%#MT_XG5`9duW"37@9+'YE856>4/G"W5#5m6]IME8>gQ_=,!-eC_pGD(^JuQ=FtsNQNml"XPdl&#]RY3--k%Ksc?!%LIsJ*0a%2Ij`^j6d.)cIi'%We!HS[nFFMOZYEMWQs*5ELLl927^/P2mM_pG3jsQg#649eO,,"'LZ?W?`.2X7X]9!#=\&AbSN>!N4FeM2&)`>e/W%'!Ym"eiKq>Xq0GEDLnaJ&D1;JWh$RQ\0;i'+p]~>endstream -endobj -22 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 395 ->> -stream -GarVJb>,r/&A7ljjp75+I`LS?&PlER6H"^R:VdcGW!Bi7aZ&0]B`s\j#ZODoX/ueAM2ed3OZ&#KJuT[<3jcF'akC7Y,:k\XP!$XY&L%_ki;Wp!W>3_T?+\j]UL'\_*D)3a`X0\lnn.:0>E<4E2#&!8(@Cm=R8fJm?0PU;h)*utQnR1\rg`37.==cTXg:\^:rfrN,.rMCj7%@jW5_UgbHUiLgu'aa`H]endstream -endobj -23 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1962 ->> -stream -Gat=,gN)%,&:N_CCofa`%%q1I-8*8+%$=o7\'uAEKfQ0`"F.=\2mJ%?F']2sO.=TMu+m^+N<[.ep)o<;*VN6K^uVCU1P2$>+'u,fj(YU>ZE\0<3XHoXBqd0p2Ga4Zi):&erXF@Su+ug75f`i6*-nVcn><#.TgPn$9+G%=f*s$LT3^P\.65pAD!SK5)HH,H@\#kVh^l))&EJ:Q9mE'_ms9hTG?D:^"VS1Uo\0keeg"C"S=_WRlfEu6@=+'%g5?(VnEMP^Dj[-W#u%OaRRR"6<-,-L1E*5;iWaL)`Udu-W>B($4dH]`B!XsSCUL)O*,l;"53h>N`rBP#3C$MF,Lj6H&:ZkS8r2l;04>OCcs<6gahrFMjY9mJ3GoMZJ6#XBZpWV\`$_E-8g]6C99l%ga6qI0-`i(D/"%nAUr*arfr(o[6JH#[<15f$Jous^FjfL&9RoJtX#$g^=Aa,&Jl:A>a4NcLh:$/Q9G35j>M+5EO3u5[U.#ZD^B%L_R=3Ofjm-:=[&-l5-]`[_Acr%Jg4'q&Be!*2=_00U>-_4s@5P"<1]j^8YEEG/?;EQsbkE_nk!XqF/nnd1>]DF\gAiHMQZK8l<+/YNK5F[!$USg?:cc%hmhgUBkr$\.4'A[^Int+!![fNFtfWX!M=6@?mkX?K7tWO^<6QC?5ng?'X!FOo`]/ERe7HiQ5hWtq6#NlNF=p&PMiASG[=a-UK/L*?\"nPi9VH%Bt*86:_QD;\j6_ml:;(t64XGR+-`TKaZ>I:MJoUuVQ#2?hOs%Fl7Jbf.>XC\P2=^iIe)dN41S-j]o.Q]Bh(BUAMaB3!,rtLJu$=Enl:*?lL@0mmC#g3M(&*THZ5@B]%C!-fkl)G%"l=seg*4d0!P>lk4F(M`m[e6IKHsI;"fuEmnB*X;JDV_A1cCbN:X&ZH1@Jd6$duMqS[d'.=htF(QBuKkMOD)i-O]o(mYRbI8-iH1CXSl]>/lnip>%9FcqghM."QWmc/(KCIW6OXMKP6LLDPYd)?h&P$&k`l#-tBT>1;J!WV5%nt8*`-8-\AJ:pK)'3P8:b;i*W~>endstream -endobj -24 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1741 ->> -stream -Gatm;D/\/e&H8h>E*7BYX>#/CCa9>')/R:,;1Nmmp*Wjd3IZ$3QT=8)?E':/UNM8*tf7!-g__iC=7)L[bd$,7MRnn6t\=41*ZY`afe[5(j4e1l)2qjq&;`5/%ZeO'"Yu,_!U,L+8_9@/n,HI^>Z<;gX%C+i],et).ZLO#SRhr?Bgh`/M3\BTeo?6P89.H?(J9]K!MfmiAA\MgSW#TD[^"UtAO^Ulu+"Pj8hdYG,!FigP\\:^bcXa0RX`j[XNA#.m"$UO-CR)Xsh_,5XuFSu$&K!Yp5LY,uRIUnOB9-RldTN9`">qUmVI?H*TFT'hoG>s!@)8_R+,WsuMq"MB;4MY>KL5fr;O.Lp^fq0a%n-=_#&1D>83@H=6X;-?J$6IV&DE5qOi.)LCmtBUVXA`uX-#S"j)CC*:Fo,C1T`D5BYMk&53h)JFPm4d8c*Xa`0Ete;EEK),=f%Fr75uE?cl+*DM>s5&OXjc:]>#AP8hM(\)hDm0c/gF1]]?:Ll^A2Uc?n7Q0tQ6*Pc'-nl1k!Jlc-Z^UJ96B,Fboe7u&ZA[pI6(YC8Qk,m`1blCr]4hmgP-'c8b:R9V:fV:/C0=ma4TJP=?>W-6AGniWr"Xp9-cp^N\@\Mg-YAE==%5+q':kl.kr,,!3(Y6RA5,W*M_f[ltNR$QDFe#cHPaoR>tWH,/sWRP*(cJ(_HT4-&G=l%Vp+ClXN]$t!#`QbF,m]NAt(H)L%ma107%)fm=_m:ao')`6'?TG^?^dK_,6.tr,A8kt9W%YBHNs'5#Z$CoAmc=\LHHe4ZZAmWM7,d:?"YUmnAiU[Ses,LhJ?g][-Xo'8FTfP=H3gGFuI,UiFeXie7SQ#;KA<2l@tZ[](9O*W5.6bBrb(R?7>Fa`meUFn^+9;b3QC^HR;Op]-5/s]CLc;i``m9hCc37^c7gZk$T3j%tjM/mYe]D[8=]]_&_>J:ntr;S]Y4s>rli%Ro!Yq@bd16LS+X3^N\+)"CCb@NpUcf_e,\U*DVOoPsle>&Mol6$e)@!HlSH5EJ%Di7?TbkZVe!(bV2NNU1VFtbIh(>d"bp8=TZJs"ZD-/EfKtEqC]"bKj!lp+N8tTAGo6S&qT&t(\er,G]Zk^=\lZ:T+57XZh:'LmJE)\9M6>q4P7JbY,KmRjbRh!!6$2:rFQT^6*a[\9qC"]75+'mGF4RE_mK(g"SY84N]d-ZCu?.HNV4h4Lof/R)Dp;@]+]"SDlGq4&ScrdFWo&N-[
ZEf1>uC78F)3/fEiUj.NIJ-9Z08XHHIs'0\*2`44?Lu^^[dfPp"\=nVb4+-XpFsIiE<;n08B2gMT"Zjs31/Z[,H>GrA?BCo=*V:RG4Sq9X54#HA>9gY2mOm%;ir/Q;1OP>ha0,k")re9=p&j'c"O;LEhU&)~>endstream -endobj -25 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1879 ->> -stream -Gatm.KpDp5gc,?e"K`TYMh&UuhpES!2)#,i9GE`4-5(W5S'2/c\F"eWo^uPi/:'NWZZX)hl`-*^?gqY'[odF\s&BAuHr(/H_F/TBjYQ>&@Pf\Fd*8Hhj*7lL$ig9`aG'r;[QCMqWUDZ"IkPP7imm&_n4)R;G_sd`<[i=p4&t!8B5VLBggJtqmIKX5a45$9,erLY`BuX=Z1dLqW[F#lD2KBMj)Cu*a1W2_2n>$CP4GT])F,Ad@LZ9Cu3(I[5I$2D:h;nB9Y[E?m_-6#oemoe(@b*`O?V;Xn'Z[aAtPDJD7%*F`f4=c&?)@KnfYiMN5jgk23p-5;16hcgT$cQJ2i+ldl>P7kAN710E?NX(,UnK3#^3V6[d)[L4:mZZuA<7!Fm+63=:8DG5.)_\#b6!7D=pMMKZ^t22(3JOo%o=MF!K'\E!d;&ZDc0."_2-!Y1m`hI5E4H%Z*X4mkA"HG[%CgL%3^(q6h\D9N_t%4dBE#cM73D9/`;qko!1+fO;.*V6]i&P?o&h!KBpmH[Y]UE$GE<&'WC_@X.X9M)aKY3O:`^s1?O0\H_\ZKp3g=/tY)Q#69i(F:?KX+FDA2ZCC/i?+2D55t>H+6Z/?U4P5qoD*r0b"Y[WV@GWSJ]bdeZa^&\:A?HM[5!cT/`8SM=Zu(g93KaU)[XiHgG1;&$[",*jekLQ4aXmC?gL9X^qbH0pFhM=e4b_ZUY;IdSZ_De`=0[,C\Bmt`fAD#,A-HlddG1[.C#:DYQVq-G2h6kI/ar-!hWQ)7u:>-E8B87M[56Qrs6Q6[3\\tP9`K9Z8bHLZr0?s?oPV6HBZMDJqa0G:"pnp48ehmC"n_7ZQlo!V.nI]3t\m]E&CUMWP]3m8KrJ,8AlU]NJ$&b%+_dRId-F#XDO!%-Fp;e<#["@b>9Eeurno-I'H12Y'C(kFliGCPK)dfnS(VSS1RJj;EU-`dm/?Gj1@EpK#Am#`1>%bt@o-+oC)_?o9a"/9[an2u0);erue]?98Q%XAWJA51B@lU:l`dn4N/g?d'!#'o?0+i\cjB6YGGMRFIduo=J&\e33QtCl3;BB9ZgP*gI0$G/rAa"aX\lPHsbY<(po`$]Ya$_V0+:^_/&M7bUJ9gTAm\8$NLnXg^OoIdRiM2!r_f_M>9DNsRC=P9C]`/XO(RPrbU+"a3[uJ4G__rA0&+gendstream -endobj -26 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1670 ->> -stream -Gau`SCN%rc'`G1AEEf)d'6H&[Oa;6hL3Dl-?-t^8Yl^Eh6'3!gM(C]NS?s1-hfhXT/6Qt_[MT2nECbtRLZb7MF2`[hLRI&I$K1^g`\/2`)eS9K38lQ<$SQ,CQ,W#9?(X*ZD1`dH_Ls:URmjjUgA!&#D3#&/,d7B21%L$`=WFoQ/FL);#b7ZOikQq5C[2`'d;#6bchID*QpYDl"#h>DV-]hh2KKoa!FnCqD)BS$C+0aG^&U9au5i%rS=eM-j2:o*ooR-:Al%[XuoIfs<+e0LsjTg%5D2W(e]gnERt$A9KD#$#>g'7khQ*fs-Q[H<2;D_im6BH42,plgXoZsrrG')si72/Z;-4f!:2&L\P=\9kL7ZsCH3!ht5@76hRt,>kI\;=hmG0R=sP&V_S_AI7\,ba$?/3m>BIdeB[uN4.)[W4*p?0H]NfKP>2b0BPc$._-%I6=unA+CuMBDYD"UZ>c'Cd8CIK@:C0^7b*XjWuSq'4:\eH)8m05<>s%C$c<_7W&u[AJ9@67.p:#b*%%5fR!%[&8@PXBiJ;[Ub'J(T(O0g8StZ(&)3kc0akFmrk#]q&0g*h'gO\\T>od#$9L$rDR!#LRoLAeE2DI?q\^PAh3`oq*R)0o"_@f$Q6Y8KD=Zj2+#oq8,k_-`?6uHSqb`m]2`#ir[@g\5J_O-)hDN1E8o:U5TP;QW,G=j2<=WU2(Z`^+kJY[cg/hSm3Gu4WT5<%$)<[p=t16!CCW5[udrE9[G5;_b6jl>bb=d5Bm:PGX.>(505kF4"P'+$TQ^FT\5]QPgSo2rF&Dk3fSL!6.*9&krZL8`Wi\inlE?X^Pl5jn@]%7,VirQ8m=lVm1NeZ@`>/n^gG%P*7S0(>`1Aj7C0')-\7XPjcglOtN43XerN`8(hJnK8KIB/W=ad8aRC8o^>(:X&O.0N:egKdB5QRNG66j*'sBH&J-p64\rpGb\/t1``^!TWh;0Wa$rD45759?]>#s*0U9c@jMIjfTANM4$rFM40hKe0.3pAE**4NI?CNt12Yh=TJQ@FgdL6f;*NZuE;RnRr<*4eH3?b"\HFZ#IhrX2GV<\#DdBr>K*J'43>T$@4A9n)W[&K.PS%+A"0mQ-Dg2_%[s#7oD+gnFWKho8FL/6=b62CQ/]\Q'SY$.C6BXR1(H'3XubkUFuSV`U2'e\8eNOP)":O9g:n1oTY&;2BE'heg[siII.gln%38Gk-V64C[9B<_Z^Rr;W[?1/1U/X99%8k(f\/fBnrendstream -endobj -27 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1595 ->> -stream -Gat=+lYkN9&HAoJib"j^'/VNp;_J[#OKRu6+ipE5dK.NT0JXY!OX45+qH/jZI7NR2.>m:H&/(C$o'U_j'*F+&1]P?=^q2%S4u-M(9]s2Ni@mEG%o[7\Z0J.NPHeoXi!,]*a)ga=7C_g?plj@=`uP@0YQKnJZkQNE1mbVSk5/g.rLg%-FJoF'VK7T$R1AJhm;UBk.d#2+$nnN6kK)s-bm&sda7(N0PaoPbg#Wog-'rs4]n>R`k&U!^$[eH=bR_&gT&"U]Aq0c/:23/'_:R=/+#sHn'2RpKbd276<\+*+7]SA+o?lICm%;[l<68"7@2"oMi'%Oi_3j24]+qPES,IIK'a8\4U+4!H#c/FZ2,AB'_tW_/#mLYd6o't21)=-;"N6hGHO4+#a[B'c,#]V(_q95`'c>k4j-&`t!Rd6jdc;5_I@EK"/8o&'O4CL=p^iP-9\*AX[0MW?9H]"VCnsSt$m8Q3h=dNpHARZkfuNW8Aq+[Jb'+i-R^gVm@WRN`!6Y]4!7*G,riAHA*PMluSD@FNfV-]J!`q"j.n#d]rZ#5EA@kB"jGV?Ij$L1uf$K6LFdFh#hlVHdOZ^-cXjppRLA?U`IU;]18Dj_8`u]\`O.Vbq[mDAhPKiaPU>9#T+Nb%q,VhMVoH&nrXu5M\#ab$<^B^7W_Z?#rQg[L/`H6omKc+7=CfVV*%GEuTH[Ygi!T`uP.j-uCnaH]Rjh?CbFm;h('\;kmAoscf``kM&]"Q0DE]Nk+2?T6ARm&AT=,2^2b:oM%^:';`'h(W.26C876_`3DTG)K&V7BD1+\&\WEc(d]#CO24@TStkgPjcUPDO^61lFMm5&Oj-jLDBeh<\7Da.3MHJ5;1>XGGDBZ11mW>GjTP+*qO])D8!NC\(K5r\;>>u$'cP`<`ho:U^QQ](Og>Oh(5dR`3#;_Kg[#^g$!c?J,G9Bodd1jRc1Wf6oD;ed8X@o#Nfd)]GFe^u3C2+S'=]Hbn6T1pnl+ZBm-5FJdT`,pM_qPlk5pi6JChXBepg>&C2a~>endstream -endobj -28 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1594 ->> -stream -Gb!ks>Ar7S'RnZ;3%.V=$"fX%86rND6^ouLLFc)!,6^!oJWUgSN@[(FSYdA&hfhUsHr4--!VS>U0[8?4+$Y3:4Cg_IA*u:D!PB>fi.M-k0Y@T:Lk+G5]GZ%)*ihd8&b,tK+c$;116acC,9dISr["(i68BZZ(H'Q!uQKenMlA'MiYHQS3ZPN#)`u2lP)[s!3L<].,F=$=hXR@][J/H(UJCLleL"gNR])/;iR(mMoC(D<+Z-t@+/[qoLVp*@+79`;OkA)1-0+$TGD=HeG345L;:!KBrm8GUGA5#;GVBm-Mto[!H&nMGEF8J\F%'()DX3R%''hSem@h/#A%:DBEK>rTnUdAg5AB(i`gi99ja7.[`TtXcqGa3>%G\^UlJ6OqfVG]eV#"ah&:],U?2qMo_?dfnX_d&@RdEkj*g[HQD=I*9AIQ&;kes4I&iXsR:.ImeXbSDe#4@MA6H=<$n7ibu_@8;\kNi6\dlO58.Q\D$sHp?=4.n^HKh&S6Ypo[S2Z?8e6X3$^ERWB*7)](4karh%=/-EP(!dBiZ]=ilrmhSA)--Gr.RGA:G0dG-:b\_Xj3/d.\CESQl)8oV]1lMPAA7f+-nk3hcA]7`S,.ff!\^E+(Br[(5Wa_LTD)/XWnNNGbWk<-b'*S9qVH=!>o1'9?f>_VBQZZiV>Au..G]Z#eIN^VCU"?g_C5jMlkK71&-3dEDE!X#K*+M9I73qRo/nKBo=`p+26d\0cA#261KWu'nXqE$B>JtB5f1$n>8WB,GN4\YJ-KakobWWo^>Ki-h&bJrZ[Ri&K9L_XLFZBZ=FLsI#n-sD\QVNc.,MQh1k`7a?'J\,MgjB@(^lo1>31##/Do8.U,;V0_8>Zo+m9a)%D3DEsV5*+0D+-CHou6r/Z;,EcNq%,qX`E5tnTEYcmc3,WHDNBS39o+.Id$fu\ilYMjJFH^T,$EZPoWFiNL:jt#$I(eCg&C6O\[F.SeS9,_d>7uD3L$_Mg[a>2#:fm=uBKk2pll:^hP3rV[[L8BLFPM3!(:c=G\"iM@FAP$#)5QP,.O-CS,RDH3*RB/s^3lj.:5X0mE?GjZ@]k9JdfMU8T$WX!^KGL(1eF!HC0!ir~>endstream -endobj -29 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1885 ->> -stream -GatU4gN)%,&:N/3Cc%OiSOO;bOVFeEm5RkiUm&enXmm&H%$?W>M^2sKoHbFUHPa=dOEG=oRLt5-mb(n(/64fFpsI9'56c?sLAj[`F9BN]cqW&DnJCtAgpub7oh*t9#I\&km@(%m%5$Ad;,,(hn>C"<6dsILFUcqj);2*TFA1I*G>-al/ITTULp5p<6e`/.k"r+uF`ln-cDkf7he>0\Wt%"(k_d'ufMGXT?$BRfV%!\&W`E7aK!JFJW)G3^8$nO)P:;e%3E(iXr4,Z=Vd&@TTF456^Vh]9o2YA@!i@B2aZ0+D38cGe^5C=6t5JpD7/tZqdQsne,W!(m!gk./I`U*F-JfYq`]p:QI(QdUC$d[iE$dk)QE4W[Vcl(.8?I'?,iu\WLQI%=pF/LNV.[o;F1*u_a?D;QmAUSDAJr1$47J6cRqG7:SLHk[J6>(+dp\JX@Nn9PgTu;7H3p#k3tOH9n5WNcWCC\'G_9(fo1BX>WqFSc,Q,cK3`B&*4MKRlSLehrB%)ih0>V'p'5[XS;lGN/O=F9&GQu\[)0kY8X"eZ/DFFYrDMbFM#Kb>@/&l[3WNb*!5HTO1V[Ja?A?6tP.ueb_Mee(TGtefKOj;mKV^+l7L&r)*.8:#l<<1fi#T(=`u\W(,Q67@YYN_4@%d=*OhEQ$0PW4J[,[Yq8i%36+cV(QkT5$2^-Y]*&T#jI9F1FGa*;8E\nIBBCg6B[;TPcJb/6pgn@r@dlqc[kdI&K[(=oH-h1`h%j[s&d//0gWnqQdHf1;*!H%o6$*VOAOdjV;.\ib"\M(@6_`lQhOi[\M+G`qtKNV1.!Qdi9'XSLunO=^uhY8Orh$rTo9eja%EA@@"3D6q=@I2K*@DS-YlL1d3YA2@h0U[XD-Z9)TFn\*.ZBhueU&&EjA5,;^hQ;+_<*JRp&QIFm,?sVYpWI&CU]EZ2!tdX5V&9#8B;:/*S18F7]3QiS0lXif1Yt0IrOY8DWS^X!<`!Mt@62nfNXjB*n1W%E8CS&>rSmO8KTr\p1T)l@2^3i`U's%8]dT[5A1g'8bC/)RVCAco97+D:D_6<429m(@c=Z(JIcY#eh&KGS[3eZKUVnok4'endstream -endobj -30 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 564 ->> -stream -Gar>CbAQ&g&A7(hZf`4c-0mMUDY=?=lDG`JXf@[,K$klG5/[;(S+L6H+/pWZo&^hQ>'o/[Y[\K_,0^*15n!7q3de)Y['^blI]hU`R6fF+`sgF2"mSFD]/2un'kCXkCUWWWa9%jf?RU!e,q>+oL'h>)+lHom\m';59bT%_nWu_6@J2i&9[42@mr@R_n4;]h'\6@luo2u_\qa:WbW^:_N!IQE,endstream -endobj -31 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 1710 ->> -stream -Gb"/'>Ar4d'Roe[39"B.<+5:Kj'/osBm\ZA7C`]40;T0`-8<:035-Z7B!q:@9K9$_F%AQRhN%c*>^k\%lD9umk(D+WnD=Bk]W9_(*boeS,D#?k@gLi,B'&"MH1\/)=)@X)$#4jt:\gXm-`^)k;cW2jG[q[oLILlXO0nZI1*dAju/^"[ThH&c;&lKX&YWgB\E#@tAI<1,k6J9'_-S\VNs^hQK5$`jkm%l9\r"iqoM4nQPRu9lCiMmdMde"m`8YN7K$7WBJPR(.LT*s?Umo.I505=[":]GAOYq?M;(@a-jSc0;$f4Rc!).ga4;V)VH)mMsMa:4VkTd3VE0@Bd81/6b85ZmpY'M8l;KROuIUBDDSG%&9r')>mdX2.tpGr_`8p:?/9$:8?47cX'"MjNpO2M#>VHI)S?%mp+/IP8!6RB_:&tppd1$'!kUO9^60ba`obnfj.joDS*cDDiRlq0dA)M#o$s3Oio`M2OIY'Z./A;8oY8@N,%]UXKiXH2]gEk5$^a#qFIuu8B@(c)2!,J-mCDGQkDJUd?lO?C286d$`^f'aT::ZO(,Bpj^oplWsDBZdXDZ[?nPL3VF8.0&u^jDn1XQ(Oa7hXnUMh@I*aTLFgqlTn;"3(kc,Ml"+[+0obU&]^Sl0j=!krb;B2<`Z]@_nD:[;T/\X?7(a@?JT("5nXQ%0,_iE&n+"^q*pU!iM!]m_rYS=mpqU'<4BXBE*2U$$)sGO8%_pM^tOCRL"8GT)TUA%Rt@o/cDlI,n^V9]cb>O/7B\4hJJ'_$`XZ<<n/=_m_b_%e`D@aVY`I0<^4FnCL_$5Sr_&nF59#XJ>^P)B(e.u-rH$$%W]hVT=-Y2\D's@I\3u+D6>QDCKR4V';,*t$-slAn=BXTU2p&(/0fFB2h@>Ces#bG8Ygus<0H,7endstream -endobj -32 0 obj -<< -/Filter [ /ASCII85Decode /FlateDecode ] /Length 2067 ->> -stream -Gat=,=``=U&:WfGfXd9'P8Q^f$"!%AHKD@E2g/rdm7c=@MLm*W,U&A5SR_6J]AN^Q[Ugd+ND2#@HXO,RYY,07J#rJgB)o\A@If9VZXLEF`X.Fb$+ud3f+r.6H3&"JgBK=lKXngT@M[pRBB(MID4eEK88*buFVIJ![lB7V(ABrN\iPl@_%f=sljW^g3oX0>K(IFoV;AO&9M0pp`+h&p7krd(S,!R'Woq5aF-B*`:4icoXcS;XUs4SZ*kYXR["Q:N3gP8N;/JPF,q[[KO.XKPOE&G]%V9FL#2fg%lCBkBl%.p9Hhl>8fUKS]86*21>7bo2kc*L'8J@O.lYl!,6iTbj9`lr_Ym8@k\qPiU^XTU&_!P&4/\k#^R[U*GXD4[e!#tT(J,):5:gk]E5gmJ(8AfI/5a(#-+"tucS_I0?8mVoY!2YLbR7c[F2_b0.^PUai=3s1/_>YAq.,0EMK9$!i\7#<+Vm>;Lu;5]P?"dDTEUsWj@m[D93oPZ/gU>%(6NK"O1AWFD%)3R"-JKLQuL0EUJ]=^SVCUPG0p$*;a5)2hW\%[gj-R)^-kI!1cA%I^-50Bo@C3?VU6puJ4(4T`W>G^LA#Km]6DegT$)`YtXL?mCE(&KKMDgqqZq2S`RAT*,T4IriUih)uM?f.-'Xo/P;97`.c3h)oL&/;8D&ShQ'_Oa)+-LZbmWU%RDs9A:&kj47F-%\Z(9)O9FuY(>OKLE:iV?bIZ$mY8S/*5iP#(RTL_%Crkc=Ifra"J7L0'=deX;2ZOW0bP+0R7qEbk+"XB1?(RDO6gU4!4d%+F(OhNT%9H(?^=7JBqU[Of(ZHQ8hb#2[*X##[#T0A7HLWLCZ5?gjKX_@W8j=L-MOeU0`kr:`;<+7RIDB!-nL`H7flYleCf(7KdPmjiVVTmjWc2ZpXHE+VYYT;XPQ069A8A:k3-2BU<;7]2h_#n0OOkAi6rlf0l?\_R31nH9<7C!a45BA3PT/AHS`GONFGU5T?L_*K\\B$DX4_afCJi=ZTYGCGcn:thU:gf`%583=9heZr7KD%7qW<5qeHP,13-'VQPMrdW#rHURScmf@]WH9V9ch3/e'-PVo6SNRf.3uX3-^Ia+,>TN#B3#o0l8kG4+;MiUFqOZR@=psp&q=O8"(($r#=@;Q6cj'I>FSr(Pi,G4`*F7,R0ul3MC[9)9/?t.6]"#Y1)Co*&DD^_2Gh_Pei@DP+*g:AH\9b$L1UcZX`Z%KQl&;Z<3JALP1T]Nendstream +GasbV>Ap#c&;B$;($BS#<":h#&ZMd.V,=!WBqs$;m0`r9WE?ejFJ]!6)VEm4-!LO(,ik@LhjbRAd(a]#AddO_#4'N+)u(8&GF1"tbKR11i7p%MdBKK54)dN]!3M;i3%aKAo"d+A.A\EtD'"eFG"P,*FZfRM-iUI$h\2dfWoMjI4A(:sj;P=5V"_J;&TC;:"QDVhTCE*3HXit4s,:Lo3WpNY05oN5EZFF^:6jNXgguEm&X7&,=pi_=ThY9hT<0R4P'1u&Y5d8+D2G*+lE3Hl%Hb">Y)Iu^$Bt/=#P9Wc]=P1_gWe')QlZdj,hr+73/P-Z"6,dN;X828qsBPN]>di\;bQ#:1j,Ec)YR?5Ye?JQHlKHM1p/9%Ri=2]]>BbOK2:+PBFQRj=LUP\[eXV$"]j3c(ZS2[&-$g0Va&ASqec[W4K`$X^RS-qLgeQQL45Gdr=jG%%t];<\b@]~>endstream endobj xref -0 33 +0 19 0000000000 65535 f 0000000061 00000 n 0000000122 00000 n 0000000229 00000 n 0000000341 00000 n -0000000456 00000 n -0000000661 00000 n -0000000866 00000 n -0000000971 00000 n -0000001176 00000 n -0000001381 00000 n -0000001587 00000 n -0000001793 00000 n -0000001999 00000 n -0000002205 00000 n -0000002411 00000 n -0000002617 00000 n -0000002823 00000 n -0000003029 00000 n -0000003099 00000 n -0000003380 00000 n -0000003518 00000 n -0000005514 00000 n -0000006000 00000 n -0000008054 00000 n -0000009887 00000 n -0000011858 00000 n -0000013620 00000 n -0000015307 00000 n -0000016993 00000 n -0000018970 00000 n -0000019625 00000 n -0000021427 00000 n +0000000418 00000 n +0000000523 00000 n +0000000728 00000 n +0000000933 00000 n +0000001138 00000 n +0000001343 00000 n +0000001549 00000 n +0000001619 00000 n +0000001908 00000 n +0000001993 00000 n +0000003665 00000 n +0000005218 00000 n +0000006427 00000 n +0000008391 00000 n trailer << /ID -[<4a95945443b3266c457c35d632c7f433><4a95945443b3266c457c35d632c7f433>] +[<72c3ab2d07f22178abbf649f639f9ed7><72c3ab2d07f22178abbf649f639f9ed7>] % ReportLab generated PDF document -- digest (opensource) -/Info 19 0 R -/Root 18 0 R -/Size 33 +/Info 12 0 R +/Root 11 0 R +/Size 19 >> startxref -23586 +9078 %%EOF diff --git a/Les05-NextJS-Basics/Les05-Lesstof.md b/Les05-NextJS-Basics/Les05-Lesstof.md new file mode 100644 index 0000000..d430c3c --- /dev/null +++ b/Les05-NextJS-Basics/Les05-Lesstof.md @@ -0,0 +1,441 @@ +# Les 5 β€” Lesstof +## Next.js Basics β€” het React framework + +**Vak:** Technical Foundations +**Vorige les:** Les 4 β€” TypeScript Fundamentals +**Volgende les:** Les 6 β€” Next.js QuickPoll deel 2 + +--- + +## Inhoud + +1. [Waarom Next.js](#1-waarom-nextjs) +2. [App Router vs Pages Router](#2-app-router-vs-pages-router) +3. [Setup β€” eerste project](#3-setup--eerste-project) +4. [Folder-structuur](#4-folder-structuur) +5. [Pages + Layouts](#5-pages--layouts) +6. [Server Components vs Client Components](#6-server-components-vs-client-components) +7. [Routing β€” dynamic + nested](#7-routing--dynamic--nested) +8. [Data fetching basics](#8-data-fetching-basics) +9. [Styling met Tailwind](#9-styling-met-tailwind) +10. [Loading + Error states](#10-loading--error-states) +11. [QuickPoll β€” het project van deze les](#11-quickpoll--het-project-van-deze-les) + +--- + +## 1. Waarom Next.js + +React alleen is een UI-library β€” niet meer. Voor een echte website heb je nodig: +- Routing (welke URL β†’ welke pagina) +- Server-side rendering (SEO + snelle first paint) +- API endpoints +- Image optimization, fonts, caching +- Deployment + +**Next.js** voegt dit allemaal toe bovenop React. Standaard framework van Vercel. + +### Waarom Next.js voor deze leerlijn + +- Industrie-standaard sinds 2022 +- Werkt naadloos met Vercel deploy (Les 15) +- Server Components + Client Components β€” modern paradigm +- TypeScript first-class +- AI tools (Cursor, v0) zijn geoptimaliseerd voor Next.js + +Andere keuzes (Remix, Astro, SvelteKit) bestaan, maar Next.js is de breedst gebruikte. + +--- + +## 2. App Router vs Pages Router + +Next.js heeft twee router-systemen β€” historisch gegroeid: + +### Pages Router (legacy, sinds 2016) + +- `pages/` folder +- File = route. `pages/about.tsx` β†’ `/about` +- `_app.tsx`, `_document.tsx`, `getServerSideProps`, ... + +### App Router (sinds Next.js 13, default sinds 14) + +- `app/` folder +- File = route. `app/about/page.tsx` β†’ `/about` +- Server Components by default +- Layouts, nested routing, loading states als file +- React Server Components paradigm + +**In deze leerlijn: App Router.** Alle nieuwe projecten = App Router. + +--- + +## 3. Setup β€” eerste project + +### Create + +```bash +pnpm create next-app@latest quickpoll \ + --typescript --tailwind --app --no-src-dir --import-alias "@/*" +cd quickpoll +pnpm dev +``` + +Open `localhost:3000` β†’ werkt. + +### Wat krijg je out-of-the-box + +- TypeScript geconfigureerd +- Tailwind CSS v4 +- ESLint +- Hot reloading +- File-based routing +- Optimized fonts (Geist) + +--- + +## 4. Folder-structuur + +``` +quickpoll/ +β”œβ”€β”€ app/ +β”‚ β”œβ”€β”€ layout.tsx # Root layout β€” wraps every page +β”‚ β”œβ”€β”€ page.tsx # Homepage (/) +β”‚ β”œβ”€β”€ globals.css # Tailwind imports +β”‚ β”œβ”€β”€ about/ +β”‚ β”‚ └── page.tsx # /about +β”‚ └── poll/ +β”‚ └── [id]/ +β”‚ └── page.tsx # /poll/123 (dynamic) +β”œβ”€β”€ components/ # Herbruikbare components +β”œβ”€β”€ lib/ # Utility code +β”œβ”€β”€ public/ # Static files +β”œβ”€β”€ next.config.ts +β”œβ”€β”€ tsconfig.json +└── package.json +``` + +### File-conventies + +| Filename | Wat | +|----------|-----| +| `page.tsx` | De pagina-component voor deze route | +| `layout.tsx` | Wraps children met persistent UI | +| `loading.tsx` | Loading state | +| `error.tsx` | Error boundary | +| `not-found.tsx` | 404 voor deze route | +| `route.ts` | API endpoint | + +--- + +## 5. Pages + Layouts + +### Page + +```tsx +// app/about/page.tsx +export default function AboutPage() { + return

About us

; +} +``` + +### Layout + +```tsx +// app/layout.tsx +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + + + {children} +
...
+ + + ); +} +``` + +Layouts zijn **persistent** β€” niet ge-remount tussen pagina-navigaties. State blijft. + +### Nested layouts + +``` +app/ +β”œβ”€β”€ layout.tsx # Root β€” alle pagina's +β”œβ”€β”€ (marketing)/ +β”‚ β”œβ”€β”€ layout.tsx # Layout voor marketing pages +β”‚ β”œβ”€β”€ page.tsx +β”‚ └── about/page.tsx +└── dashboard/ + β”œβ”€β”€ layout.tsx # Layout voor dashboard + └── page.tsx +``` + +`(marketing)` = "route group" β€” geen URL-segment, alleen voor file-organisatie. + +--- + +## 6. Server Components vs Client Components + +App Router's grootste paradigm-shift. + +### Server Component (default) + +```tsx +// app/page.tsx β€” runt op de server +export default async function Home() { + const data = await fetch("https://api.example.com/posts").then(r => r.json()); + return
    {data.map(p =>
  • {p.title}
  • )}
; +} +``` + +- Draait alleen op server +- Geen `useState`, geen `useEffect`, geen browser-APIs +- Mag `async` zijn β€” `await` data fetching direct +- Geen JavaScript naar client (kleinere bundle) + +### Client Component + +```tsx +// components/Counter.tsx +"use client"; +import { useState } from "react"; + +export function Counter() { + const [count, setCount] = useState(0); + return ; +} +``` + +- `"use client"` directive bovenaan +- Gewoon React β€” hooks, events, state +- Wordt JavaScript naar browser + +### Wanneer welke + +| | Server | Client | +|---|--------|--------| +| Data fetching | βœ“ | (kan, niet ideaal) | +| Hooks (useState, etc.) | βœ— | βœ“ | +| Event handlers (onClick) | βœ— | βœ“ | +| Browser APIs (localStorage) | βœ— | βœ“ | +| SEO content | βœ“ | (werkt, minder ideaal) | + +**Vuistregel:** Server by default. `"use client"` alleen als nodig. + +--- + +## 7. Routing β€” dynamic + nested + +### Static route + +``` +app/about/page.tsx β†’ /about +``` + +### Dynamic route + +``` +app/poll/[id]/page.tsx β†’ /poll/abc-123 +``` + +In de component: +```tsx +export default async function Poll({ params }: { params: Promise<{ id: string }> }) { + const { id } = await params; + return
Poll {id}
; +} +``` + +Vanaf Next.js 16: `params` is een Promise (was object). + +### Catch-all routes + +``` +app/docs/[...slug]/page.tsx β†’ /docs/a/b/c +``` + +`params.slug` = `["a", "b", "c"]`. + +### Link tussen pages + +```tsx +import Link from "next/link"; + +About +Bekijk poll +``` + +`Link` = client-side navigatie (geen full page reload). + +--- + +## 8. Data fetching basics + +### In Server Component + +```tsx +async function getPolls() { + const res = await fetch("https://api.example.com/polls", { + next: { revalidate: 60 }, // cache 60 sec + }); + return res.json(); +} + +export default async function Home() { + const polls = await getPolls(); + return ; +} +``` + +### Cache opties + +```tsx +fetch(url, { cache: "force-cache" }) // permanent (default) +fetch(url, { next: { revalidate: 60 } }) // ISR β€” herval na 60s +fetch(url, { cache: "no-store" }) // nooit cachen (live) +``` + +### In Client Component + +```tsx +"use client"; +import { useEffect, useState } from "react"; + +export function Live() { + const [data, setData] = useState(null); + useEffect(() => { + fetch("/api/data").then(r => r.json()).then(setData); + }, []); + return data ?

{data.value}

:

Loading...

; +} +``` + +Voor interactiviteit. Of via TanStack Query (komt later). + +--- + +## 9. Styling met Tailwind + +Tailwind = utility-first CSS framework. Class per CSS-property. + +### Basics + +```tsx +
+

Hello

+

World

+
+``` + +### Responsive + +```tsx +
+``` + +- Default = mobile +- `md:` = tablet+ (768px+) +- `lg:` = desktop+ (1024px+) + +### Hover, focus, dark + +```tsx + +
+ ); +} +``` + +Vangt errors in deze route subtree. + +### not-found.tsx + +```tsx +export default function NotFound() { + return

404 β€” Pagina niet gevonden

; +} +``` + +Custom 404 voor deze route. Trigger met `notFound()` helper. + +--- + +## 11. QuickPoll β€” het project van deze les + +We bouwen **QuickPoll** β€” een mini-app voor snelle peilingen. Stack: Next.js + TypeScript + Tailwind. + +### Wat we deze les bouwen (Part 1) + +- Setup van het project +- Homepage met form om nieuwe poll te maken +- Hardcoded poll-data in een TS-file (in-memory) +- Detail-pagina voor een poll +- Voting werkt via button-click (lokaal in state) + +### Volgende les (Les 6 β€” Part 2) + +- Server actions voor vote submission +- Loading + error states +- Polish van de UI +- Setup voor database (komt in Les 7) + +### Architectuur + +``` +app/ +β”œβ”€β”€ page.tsx # Homepage β€” lijst polls + create form +β”œβ”€β”€ poll/ +β”‚ └── [id]/ +β”‚ └── page.tsx # Detail page met voting +β”œβ”€β”€ components/ +β”‚ β”œβ”€β”€ PollForm.tsx # Client β€” create poll form +β”‚ └── VoteForm.tsx # Client β€” stemmen +└── lib/ + └── data.ts # In-memory poll store +``` + +In Les 7 vervangen we `lib/data.ts` door echte Supabase queries β€” en QuickPoll wordt productie-ready. + +--- + +## Bronnen + +- **Next.js docs:** https://nextjs.org/docs +- **App Router intro:** https://nextjs.org/docs/app/getting-started +- **Server Components:** https://nextjs.org/docs/app/getting-started/server-and-client-components +- **Tailwind v4 docs:** https://tailwindcss.com/docs +- **Next.js Learn (interactief):** https://nextjs.org/learn +- **shadcn/ui (component library):** https://ui.shadcn.com diff --git a/Les05-NextJS-Basics/Les05-Lesstof.pdf b/Les05-NextJS-Basics/Les05-Lesstof.pdf new file mode 100644 index 0000000..01ff5b8 --- /dev/null +++ b/Les05-NextJS-Basics/Les05-Lesstof.pdf @@ -0,0 +1,263 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 6 0 R /F5 8 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /Symbol /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +6 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/BaseFont /ZapfDingbats /Name /F5 /Subtype /Type1 /Type /Font +>> +endobj +9 0 obj +<< +/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 23 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 24 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/Contents 25 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +13 0 obj +<< +/Contents 26 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +14 0 obj +<< +/Contents 27 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +15 0 obj +<< +/Contents 28 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +16 0 obj +<< +/Contents 29 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 19 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +17 0 obj +<< +/PageMode /UseNone /Pages 19 0 R /Type /Catalog +>> +endobj +18 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Lesstof) /Trapped /False +>> +endobj +19 0 obj +<< +/Count 10 /Kids [ 5 0 R 7 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R ] /Type /Pages +>> +endobj +20 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1889 +>> +stream +GauHLh/f>L&:`lHfU9J75,:OIK]q0=V9M]2GF/*-%o",OQ5pSH"E;fE?f)U8J=W&PS6O`X)sqBaJ#hDU8doN`Zhcae!PFout0T`_=V=0!d)3lt=^i>t71EQr-MjG1]l3l@5/l9YP+iU5P%MbM/C6s65"M=7EqkQ,'TVA\$bqpLVL)d8qeOjshC,=31@((Z^5ZAkAj:5Y^(`6!g+qhS/3:,EdOcD*lfXXdpBm[/'c@^kPBm-E@Vm1#G*q^A6X97T_m]caJA!9acD;tQ>1$T<22))7ZP8h3^`I):3_]A6o7,.Ef:$@1A!k4$GmD,pk!NYO;1FP,R!G>TN:,;K<7B]@/(RB&?)X1>'Jhn-2'eG5]V=(\Lk(ah+_L5]c0LP[FD.\.3DAd=D]-_HdJYq,.ft8nGS,"s%dS)qpk-J>S0XmZS+Kf?ba);VbO^d-9fB&&jN"s*[@S[/UAGe:YB?=&JEs7C=K4#;lSI`S*m$Di7h0dM2"A=&Bk6*.-Z1u-1*eB9X!cPPf19#gCGb%KSDX#,_kDgd31*E9!gPE['.H4oW7J[Y(04!V]fgDpfUE[u637brI.]pSK.<2sm]IV>[c=SZ^;U[5K>cHe@`HpT#2o)O82rMB-jPmo`_dE_Vj_iJ#DV_1/'36LFQ%HZiY#SG8j:3UrR1M_0%;?ZdHP"Ql(sq\=d)T9Ea0dJ!@NAJ7FhPpM=mV(W_rM&Rl&C89-c.]kr!H3:#7T0EF1ioH8Rf\o0cm2OM(ojF(8l4RggSpNcW5=WipKe2%"=heppW2\TaM9@btFdS=D)\SoC`@n?#lK8!JmD2D2ABUKK4#3g_h&J.Vj=RYl64P/=*QouKlM,TVtKbZtUS0gSj%:?'[5E?E$T-ZORAk[qRi\l["5K!/gbS)^3K@g;\GcIoFqJ=2kX=0TT1/,qhh9Y:rm*=40)4:W2(:g=k3S:CHiorCb$`Z?[?Co@qbS.9blh0mRuO*BmFdH;0.R!FEgp1LSq/p@4!,a3bKXKXR:/?e&5r4Tg'Gn#Z?6+r"$XBUHC2&*-A!EuJT%f~>endstream +endobj +21 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1827 +>> +stream +Gb!;dD0+Dj&H9tYfXXdl%hqU$h`B5Sk0iR#juV+\E:"HR3fYeJ'4JGW+JHRLei).j"<*FuOoko)=k\;t7F*Sq5k3+!ms#3/`t/a<0jkuU@pjlo(qtbiLV<.>_EI;p(Pi`$-fdNZVgO&`oJ1AKie9L*&5\u%^&Sa!&d2VC*7t!Mo>*s7^[*Zt^.8,e!"#%Y"l@7FLNo>aC-c+N$eNu`nHC5OOEaE?#daN'0V#tF7Q"'a5q$f&(PYjJpufP]'DP3rA.bGLXl*Q%A:/9'`46CK-h(0^V:)n2049#*_j@3ON_n[CF%9U?^8`3KtT#\mYHTld;^)MB*l)!2^l2LkkHo8n8[dK+[_R)[O%m*Ca;R!nOB'qQiUK].*WZb`uL.AS*kXHs5"[nWc$eh-+`5.]GkGAoo/(;!#)2(Ib1&7<8HM/LMDiCI.nA,kUA&764:/O7/i:@UbjR7aL8s"'$CaKr=[9iO-a"OY.[a!,YMa'25qQ0:"5%W9+'UAo;ua0oZlLMf':u4[]e+a>0*Ed;-FbiQ$/RIQiQ6&Jl,)r^td=q*JQVkiu-S9g<7iAC$*jZZ(C)=6^B.YG;rVP??O:<17d\uRLJc.6qKG-m]`208#/S"0>!!t>b8q^bq4lQ;qOC;U8$:OdrT/J/=73R-jK"qG\.;"qCnhB([qN`$78[62P!;e/WdT-R`i9AIAas?qV7kD8&D*mrK&>HcZ5I\pYcB,7/,XS9>-U?V\Tl:8L0NKlN:1E"sp&KmQENc;C7)dK?h[l]sR>?28Sr6EJ3M@Y]$/L75Noj+nh?9=%s70c/]"fEi`o"AoV2&Mm7En.^b@gi!&8hcOe6*Vi>`%I_>alb+]81)>,KEBT0j:k%50lC[!&!l\Y/"/MAQ5gHn]IDY;X@"YV)S3MX+41o(Ft6gt"sVV1T7:\u;l7ac83()X?-r)S=8$GH$bp]$PA5tBd,b[SStn*I3<'aEOQ\l#J9M572[+H*?EWtZ/Rk-oW^<5URAD\$=VpH"N!NP56?+fmX3>+_&TujI69r6r_)LN1qVK"LF&'F&VL!7qu3q@C(EJ6o!50)n"U%UVs$L&D59k*6qO^V+-aeF/_L92\[:":7+`uM0peJ3-.p\tlI5qpA%D7sg/b*5I^ee$o??AC]6Q%"Wm_$5NW"'sE!'aPS6\_-NP:LZ`Q%QC`gWIC.!J#k#en!MkM0bu4LD#1#l<3!o"'0;,;HH(d!lOjKl.^KK8STlOdNe*d)hgCoG:L?7Tnq0BRae6PfLI#!J58,a$Z6fK^[M_`Qae8M1Cm"gS*alfcsHm^H3(0k/=rVQ;;nj\Y9_E)@K-XrT\41(@JNjU]s+@Jtgsi/`6?H0\M??Il,^/nTjJ?\T.-,HkrkQIm7bd[np-(a-%ea[^Pj\pu9-m8UsgAr(c2l\,C$f>T2I$ncH?o5In8:)Z1EJX(&?Aeq'%.#1)7=AEl2c6TXYg(!WP`FXh*Y]qB,cSVL'Nr5E?Bmt`r:]:Bj_qbREK!M8ZKp\(:Kg3O6SL.98Kie@@3u.u.%!n5=a9T)5Y=&+oi'OE0FQ~>endstream +endobj +22 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1745 +>> +stream +GauHL>BcQ-%"@rScoHMo]>kRsQlD+BD:<)m:2b-]&"@tiGjLN"Dulk2J,O*d%+mE\c>FXaE=A#E:DtBjL4Y16lMa7GJD[8DE_:mQF<%k6DDdi7f?p(S_[t,Via."mmb5'aLljd5oXi:erO?+?)!(0qpptoT\K'1_ip3TCdOU)+/(4KTsMWU:>fh!GI"-%kB"=Ha(2I1;PK(&.^gki#k$FQkZsUe:-LUlJ5s?DB#5)YKTG"a/]gg-Hab^]NF@:jKi/\%>l7RXVU4V\&(-#(8it`j5L..p]JeIGs#_CXFm$gI;p=+jT@^AqKP32=9nZk2Cl%%-!<3ce&;El0^j7hZrdRDEZ-<-35WPV+NIA8i6N"kH'1,T=(T%'J"SUh/1h7>*5=4J;-lHd$1QsbE)W\]on^qjYkWPKK]8!,j's7%=L`h".__FgBpQt:4t4X%*L5r5hA_ocF_r2qO3)f:GuY0/]k:&s%C>HUVj`U/B\70igVN(JMEl(f>j&2(R\q7gg]o0PIV^WV/t?U-r_O\a?fE]G<$7VPRK=]U!?8hg3cN)i_!jDBuKj9tTEs\D6V1Y5;L;aT<(t]#=9i6sr\oli4PVUYAe7,U`HoL.4a++p)$tWS#3.VePGGIpt*dE4$T>/\0&W*n,Ol!U;`OO@d<9/.&+'^-hkj$pJ6)ql1Uc!;%iRaPQc!Z0>rNPD'u-.CsnftYdt`a6^&E3`IXp/0pb9%.8QHBD`>@8`2c-lT*[duTir/2)n^Z:pHIa^`7H]Y_&u8lD[FVnE$_G/#XaT#$9TBYYce&1YXrnohOU"?tDErpnL`#+icsms+QP!$eTE^>RZWAXn[XUB\@b<5Z[l#u"d-OI#:$G'=%OD!Jj4mG1+_Gkju?0I3:6SG\&7QOkgXu58[Y`H6]kq>O4`KGK0dYS7^snQFPo0\57\64(u[/B#o!8T3td+6+_NJ;Zh3r?8&dccXpCg3Gdq2TGs-N`+bPHlWMQ?bd\o!kL>snY>r*Q+1iNCH9.2Fg=hptKO90f"-_#2g%KuWXWr>TmgW;JCp6)=%&PlUh0H6E&d"]^N/3"&9gr0m:Q,1?^d\;&SGE96SFu?sWK4BAY@Xn&+RFMri%`^[%D3hW"P=FX)k=N&hCY`]qA8&&7l^~>endstream +endobj +23 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1542 +>> +stream +Gb!#\hf%7-&:W5I,ZqbZDRbj[%>c:d#K5JpCLPRVc<,#VZV!$?ZXETJr0#kNO?4`RedQ(rpVP[u>Yba"N%*)!*a#\OjI'h>a).'P$]f,Pir]-5%eJ8I[WoU70S$d#Js/[gt(6gC^=cF#m[cRH9[bRaRsV>ZPU0ifknO9>U@#r$kF!Wq8+E%d'f??=Z*Jqj5Ym]n@mVbR7pZ("Z;FqkmpquJQZU_):9Y"#aapN+f'^HUq+:2Bq-1TC9aR4%&jhC$(&`>]UHlOk.p:)0aXjWW2@1q@e&OK5?k%6gXl65=_YlVXGPJ@"n`h"Hq3?Q\CEZjmZ&fP5>obP\8/Dj&P>&1/D,NX(c#_YLS+=dCJink+TSR\bi6NSq1gJ)Kc*AJPWp0A/Db6!gl:[*e=?n/7q7(A*.?lQRr=9S]$d1N-"3"l^GYHh7K_GP?`lYm#aMs)M2I1HBqF0:XUd&Osi7`n:7[^HB!=8"R=Hb>Q"E&+G7Xk[Ome08'3md4[lM*X,J,dpk#npE_Y$L7M@M[%:endYM;_lL:q,b?"DV[nOb!*Xq1V>H~>endstream +endobj +24 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1994 +>> +stream +Gb!;d=``=U&:WfGf^Y/q3Y2V\F"qX8Ef7ja@B8E_8;%3A?s>">kX6_XNCNJHW\-E#/eXT$RA3q$up46e*gZHp:l+?eNK-Gp2].ld3lH#Jj5g<_bNNN_=3R"WmQacH2)p'9bc*@KO<4Rr_(%`@Oi5JoF,qiel9k:sG]eek8d0a'MY0YK!5F;\(08i/._\2%*(r`HSY6FD%,?Q2cX>7u>:LW1n(jV$9Rta+]Vg4S:f&NfWH7%7sHU!=j:%[lDWI/JZ@i$kr?n>)OrmS:h)dIJl&e?`1eO8]_-2i#%l2'7@$(m-Gc%genY3.S(Yj'3jhX&l0iZ']14K,-=:W,X,L^D=@bbJR1EUh4P+SO=g)]Z`+7;eLlis_pg1+-5"uc&',X7gA:Cd9"):*Q,JFh1K."E0Z>2G:B3^!LXTb;[U&s/srqF29a@^m]:Dcf^*\:>&IZ>.3+OChQW=Lt.li"EsVu#j+fs)sL2Y;9ETG(R.."_!*uVX'Fl-'hKT\W\\TCrT9�:&uK$EZjA)h5l@5)l/<)m)2Z_d'b+`Uf5R@+kP%<8n4\h_,3%.e9D41Q'QhoJf4?htf?^6IYgWYAX'V7;_`oDNH7+7bFq9tt31_Cn0:D&cfM2e3rj]H>9Y*+Z/DcFah^pplj#];k8*drr9CQsLA3?nonY,hCZ@-gS$]mMqQ2k1"%WZ-!Q6#Jfq?&+IMm4!/ORTdKfghY8tO#AU4u<\3M/S^?n?/)q`&$,;?SPqn+fR@LIAD6qo_4f21*kAY&*V6SZ^MX*>Ccm"%pYH>`FYNe11c4mQCZSnpc-DtpB0\jQrt9W&tS%la'=B'VFNP]-)YG`0:'IoK1U63:\(M[7T\oH)-P8L*dMV`NmlLWf'!>(/'UTo7Ci_r3%HjhSjX%_^>of#*f'NkRKo3s_BoUs1lp\75]:$>NjEA7Q>$r=0e9)3qKkA34p7uH$>?rZ?5L>,7+LcKei`3aY[0uU5%in3H80l5*bJd"ioqI+aTGOXpDX0_nDR74kROtN7mBasrn-h/RgAEg&*OnViL0Hqqgbm*]oCd5V,)oOGQ[Ec(^&\'uVn=,_YDS0-*jT>RVZ`2BnH,F(q=/d%W&TZi0(.o'S@4l`VQ8K1fn@CHNnf05bm-e?\$^nSiTE~>endstream +endobj +25 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1360 +>> +stream +Gb"/&?#SIU'ReT:\1mX7'FR?-&kRA/J[S_.!'ur[?=2[nV.J@],"o'aV^W&SpQ>=C8%dK,LBZ=B)l?/ik?d"l/e:YVlSg9,K,MJ:51ip>#_i6pLl5O%hn[Qdl`5^fUYPMB3X3mc9X&0q*Q0AVVHr7;k3oIVr"I(5+0isMm:Q1A@!W$V2V"H]0#GQe*qX*lrqO[7C\Wub<#//k,_FqF,;+8T3V.\/iL]/6&?j"ni6>qGFD9s5eAU-$`6#Pd0N$Y\;J7!F%CBR*W[lD4Fo5uU9R=tnn51AJ)g+pl!4I2!TU7NG#@:m'?Q_A99,0L_R/6i]CnRi->QuA"@H;7j*@h((UlCN_RRK>@H_k8`aTCk7o6l&'nLggWKCTtV^/A*kSkt^8-[:J[fqD#4O*B4PTA+CR/96(i-OStg',5/bYFKI.p4.IjqJ!uB)bPoRq.#"7q9oL6b(A8_[lK<DDmAFr57)k5A)H^R%"Q,`:s#E:ir_q@kW((n;9)*+TWn9e+CB$g$PIBVTd-bHn`5FWJ@j6'0=Q8Z^paF-ntZUWmfKqSZe^EPah^P6-%r$'A9f*5'3Op82)p6MI[-oRE#ce:8kT[['.(qE0K?:g$]s7VQrdmKH5VP($lL@oJ5VXcdMTQjn?HV2LLiGKF`#Sj!45mKX$a;R;-]=Xl^i,FMdTg))oVpH:GS5Gpo'd)FIrSB*GEU'SD>eV?B*MQD$Vpo.^#NVKD%6l5r-)S5s@7qLF^UAl.YCN<8kO7KB]qrnL\i+42SMNO9tBVQhS6f(IguXflm^q/6Y_B'Sc`_g-[q]7":P\3ghYKhq^g&P2(c+cPV-$X;()+ZLoHLL?:""IGS7L%-oWSqg'1HDo28MnjSl/.Q!8OK(b3?dGcq\lFd/#a]^YSA?Er+=endstream +endobj +26 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1820 +>> +stream +Gb!#\gN)%,&:N/3m-%$d=:i7U8@l)fNK[$uj2oP\q@Mb>Tcf0u8Z3oqbBWsR?'#ak.ZU>^SM[pF`!Y.&/9]?BRK:Ad/,r'f^sa`k?8,b&9GbJaikY0fSkj]_pP?d?cZ+Ng5.(J#87:a"jNCj6/gicc!X:j]M!m@^pl+usi.HaL4HFcL$WoOU0d%O8T'l[LREL$XeU!^(b:.1BOrIX_h\j\cf?9$.;9<4Rfc$>,Uc_&qk09O*EBY!mdBe'B^rU(+Jo3o%b-E3H>7655-:Mb;*\E#E:3GV');0nNU=goB1N"%HN#@i2%*_C,dOLOa^BP4aQ'P;!'8SI[q(Q!t.Y-0oKO:q]t[@;k@&mgh%-L2HchbRDDe"2_ms^fjJt+G7Pe.dDJ(54W9Q2!$[gG$F@'h;[BSE=M[>&BJgb$=%]TQPL1d`a$e^9krKD%P3HY^/bP2!g7^--gi[?n!1C>o-ZFjLY/2HULJ"':Vf7+oUCfn&Zk@[eM!/il!M4r`pfkH+Z_QD!?[rGkQYBVTaG&@/RGK[o>f]ToCl\W=&BFK\N)*.MOgWR4FY_7CYo'm%!E8R>O@,e[CF+/,eafN[\[I]4c]0TY+cT^^OH&r(Mg2;toWGj^_e?>Gh=eE!^P>[?gBLXh[TNd_]@SZ5;CL"&oKjd@=\<6K%F3+tP%tejU1m9\30tH[cd`bX-dK^&Pj)QlQb#"ME1u362;oqFt&Lf[Zdp/(dJ:Y$a>)\q7&;2Tf]ClXtDFD)Uj$$3="L@f8HOggTA*/LflnE;fCI6:C*@hd.c`">#-n/lUus,)l5qD3ORBN*PtH@Cuu=jp*SHLR#?-pAo%g4N8^74iis!>'ga5D.YY:"PjQ6:1A?->f8YRdFmV-Q@5-XCRKYqa9#dIB[5-m%+i%=]Mu?F`/k.n&H*.Z4Umod8I08<*0a6H79"!c1rA-Rd=N.a+3BOg?U'2TY:`q/s4q$2!&'rK8jJ!#O+^nOM\@3fr[_D5@,*RN\>bMi+$ItM!DZFQ>5P9gpDE%\?kPOF+:n]GV$<7o>&Xd]G/1/l(d17:KY>3=f20VGd;Gq"nEN^kU8O.@;e*3[+4;ku#$Y1EQendstream +endobj +27 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1686 +>> +stream +Gb"/&>Ar7S'RnZ;3!_4RBks05,Z;bt"7$CJ;"T?ch8?l1=f*4IZKUS:"tfE'G=5$0i];7o'\ONC)mMfqI-8B%O?/^5KK0d#/23(j<9/+8eOZ*]RZ+e#Qs!u-RFt<.p+oQ(_A-p$p5X5o0je9ZZh8a**mp0(F%YCDrV5jn3S>QkV16CMdUc7CQl'&Y"'o3V%8b)$sp^En.K'kV(1JGX],#.bZ0$s_N]*J^V,;ul9_=nXn#thI"]Uog-H8!'*4sQjE8gNW[LKQBL(EDb9VugkQ/?6$?c],[p_itM'$1YifukJAYHp1f\`RMFa4t.-fI7lLTke].@\c>[FF^J=rV@FD#FO2*gQ\hTXuRpm$c*,89]eB$sTAlFTkmFG`6h=:[0VXK>9$8CI;m=fV'6C.A#0?>*D[NS&*eAT4T<rB&]T-%Xm&3mMjfhk'C49V%B2P?F>rF(pnnC"5G*3jR/j>^5[Vc'_a,T5_#mO[747:Kh!n=\ClKJg;Xs5'9XB6#s/*5'W7.XqR/*EU3)Qq-tM)_5@qqZ/(I-iF!Un0cB:X=?l6op'L)*6uu)%=Lk-]\]NLDFNK@fs-`'ad,;3pBo)AS>HHF[ddho.!c$(7B/Y7us.`G2D-\^:iM!dNr_obq-i'd'1@EQ&b"Z#4N1qjgi[1.&0ZTLBI3sfoP/g/W_kFOKuAYm+@T;R5t:iq%/][-@E!M,,/\G1_Xj2/m3ObNPM^HMIKA_Y1OK#!M^T@pFJ(k:P:5#,;Q#+11WOOlSKX\REY[LmG>8l.'?4=bBX2b0%W-;nKHHl,E"%0CU/)B3#t\RiS/goRNqKPK#%P:="(+3KC)gGiNX<(X0b\nj0$eqp^&+A,J8I&l[D?PNP.@uMQSVE`n^<]B=f5W'QaPtL0cbWDZi,rHMZl:IY>,R)Qn_12UgZo)@sudu*=@^67;F@=aH$g,^rXOK(bTnc5=B6&CK_7aL=M(0#5c:14ljF:[@%Nu>G6:g?4cVW$B.*,pY2?ke;fp(6*#&jI\YKu(:57;8ehM%_U[lVYO%&1Mg(*1cA=T/Os]^sZYu^e=6$d#T%.;Ff/OUI?VX,9I0]8Fah!$F*R8Xt];N\6;h>n4Kq5IGn6G`3b*HVfM$5.BpA.ho\ZTls/?2j@X4tj:N/E&eG>cpaQc"N[ZM=u1"m9gDEd/H~>endstream +endobj +28 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1906 +>> +stream +Gb!;d>Ar7S'Roe[35AkU(840RP,PN#d*%"F.(U16gP9>NMT".>,Z9okUtr9T^-h0pg$pB6\dYj'.&*ZXmp,YXS3t-/0=?:n!oVTC-H?h!$e#KVN%gX5K3tOOY9W$2DTI2J*d>9<"VQ+C"4_35_%0'J\If#5KS5*h(oN&YLkCWSKcpo!&odA_7"L#B'64;1;a93VXnOsk\1TDYL`ZcIqYMj.DW!r/B[J!Ik(gfm#&TXjV0\([e.6tp(,14;gZK5pX(J)$k"=b)8QR+(CH-Ck&71sD)f[HM&"E"STeL.&q<`4k^F_DJ^H2;;dAn.DEg69$1N^lp)=;WrnmDnc0j,SD)3RleJ+:`J0i<\o7,boh4pX(#2ENQ0WN"a7N%s5\eW1DE_kXSJ!ng5GUI3RA>1k+iP![[C*D'4n_"TNCNBW#!aRXI#u2u^0L5<*P42pUIpigkM$04Q%5W"+A1HYu$-rX"9e?#b$V+BG=99JB=8s/5'S-_dF<6*,2F*K@PBl[@o1RNVE`G&4]V)C8PQJZ4.]n:D(E5hOXZ1[s9h=dqZ4gTL`m`=pb=Mp-^mG"Ui2Z=9J2Pb0uD1^6#3"+C>Naj/T"ONRYS6PB+e\0;&gDP3pStuXNbU.Y]BGbUjku$G=b3<<9hVB-)doGA)a;q+:^d1A+>n*2ZGW:tSCE95!>?-J7SdER](TJqbBa0D*r=5[WJ/TNK=$l=Oe)Lt:k&RTAe;UFb;5m*g;FbH&A&tJ%W704jM[]@Bff50cKd]pnI7Kf;WoQ:4[`c&gde8[Ia<*o`F0&LG17FLL@;Sm.!VO$j>+_'LnjJ)0Y4*FP@Q7_.XlN?B,9*EXEci,;\aaI;@kBT`n`)M?AM!Ub,l1[*aREo]TP#V7`07@K1QY&]]rpIfl@TZqoS9cO?,S!J`$=W?X7(kVW5kB>gril]&&.uoAG7R.FpHl7T\"B>8_k>>ZYAF?I)mg\"@mPFFHP0>C8d_Q`4_A+d$+u?aJ<*BXI#J*:C6dCrL+&N.DPPc`)Z)mGfGj[JTjt5SG!iI@.#O;$BM\6aT_7pCI#f5%c):FBX?$2T^GV07l)LDr/%&ECf[nlP53i`R[5JESHi#?Am@aoT(1MlHag5\JXLGKo79[X=\h9s6EKW>:dcmKB:@t^t;.V'V[iH>HkUG>d.dbFQ0p_@o!cq4YKX$nn^I-%q17+@;[&k9:SY1?/Djt1=.OF2:id9%7a!JXen:KWXZaK1+3-S;CF<.Yd-2$la4\W!$qY=YGERn\q<&L/4M-I8E)#XPKWlD(~>endstream +endobj +29 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 654 +>> +stream +GauI2?#SI?'Sc)J/'_^0.2X`Cgq3!L>,A0%4)\32nJpOJEkhd?D?#([,AF`fdBZ=uQ>b]okC&tT$/i$YpFXqrD_d.:#S7?r!XM.%Z73H47c-^lE[k/m.$chf.A/M8+0ait6c'F2BhCX"JYZ\h,XG>*&nn3WJdARf(=sc488p+*"!gIT,sSDj&Z7ImAglV#rNgtB-X1pHie+jNZ[[U03'i9qHe"K,9G3IQ[YF=ia057,_3E(W94M`3iiO\r*bLWD\@mZAC9)*u.!l-N$F9!+_1=#p%)kVlQ_IF?S2Z@4jATAc3X:6I'HR@n,@?sN,SSB'qQPskm63iq"PaH;mROL^QQV$G'14daN.JA`UH?'9m)D)X&KtI_4>[ohPRo%\^=TVt0Cp`Qkj[:=`j\YE:M/XPKh?]-DRrTh\]1lG^2Z)/Ut&8UElclgR[_/_H.,0Xo"NQ6`;/2721O/Q$ns>i@b9p>'VCZH"q5Fp\hRB&n,A56j>shCY32"CY(GN+fINQo(!FdOg@[K?<0gVYO%R`,bFjjp3[[.^/=]'NI0](+G)@r>IFmf/ljmOqB]WX%EiWV,%R5rYH/U9]QsK[@KrNhL;\1S&i1CRjANhbh[&HCirKW,KqIXgGlP,"HL&0Ns/f_EKlkYP/"5-\MMu~>endstream +endobj +xref +0 30 +0000000000 65535 f +0000000061 00000 n +0000000132 00000 n +0000000239 00000 n +0000000351 00000 n +0000000428 00000 n +0000000633 00000 n +0000000738 00000 n +0000000943 00000 n +0000001026 00000 n +0000001231 00000 n +0000001437 00000 n +0000001643 00000 n +0000001849 00000 n +0000002055 00000 n +0000002261 00000 n +0000002467 00000 n +0000002673 00000 n +0000002743 00000 n +0000003028 00000 n +0000003150 00000 n +0000005131 00000 n +0000007050 00000 n +0000008887 00000 n +0000010521 00000 n +0000012607 00000 n +0000014059 00000 n +0000015971 00000 n +0000017749 00000 n +0000019747 00000 n +trailer +<< +/ID +[<2814d2269da3e51bbaeeb9604badd1d5><2814d2269da3e51bbaeeb9604badd1d5>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 18 0 R +/Root 17 0 R +/Size 30 +>> +startxref +20492 +%%EOF diff --git a/Les05-NextJS-Basics/Les05-Slides.pdf b/Les05-NextJS-Basics/Les05-Slides.pdf new file mode 100644 index 0000000..be23ef0 Binary files /dev/null and b/Les05-NextJS-Basics/Les05-Slides.pdf differ diff --git a/Les05-NextJS-Basics/Les05-Slides.pptx b/Les05-NextJS-Basics/Les05-Slides.pptx new file mode 100644 index 0000000..994c205 Binary files /dev/null and b/Les05-NextJS-Basics/Les05-Slides.pptx differ diff --git a/Les06-NextJS-QuickPoll-Part2/Les06-Huiswerk.md b/Les06-NextJS-QuickPoll-Part2/Les06-Huiswerk.md new file mode 100644 index 0000000..d6a78c7 --- /dev/null +++ b/Les06-NextJS-QuickPoll-Part2/Les06-Huiswerk.md @@ -0,0 +1,64 @@ +# Les 6 β€” Huiswerk +## QuickPoll polish + voorbereiding Supabase + +**Deadline:** Voor Les 7 +**Inleveren:** GitHub repo via Teams + +--- + +## Opdracht 1 β€” Polish je app + +Kies minstens **drie**: + +- **Better empty states** β€” als er geen polls zijn, mooie message + CTA +- **Dark mode** β€” toggle button + Tailwind dark classes +- **Toast notifications** β€” `pnpm add sonner` voor vote feedback +- **Animatie** β€” Framer Motion voor vote-count count-up +- **Validation** β€” toon errors inline (geen throw) +- **Optimistic UI** β€” `useOptimistic` voor instant vote-feedback + +Per gekozen item: korte uitleg in REFLECTIE.md wat je hebt gedaan. + +--- + +## Opdracht 2 β€” Maak een Supabase account + +Volgende les koppelen we Supabase. Bereid je alvast voor: + +1. Account op **supabase.com** (mag met GitHub) +2. New project β€” naam `quickpoll`, region `Europe (Frankfurt)` +3. Sla password op (lange random string) +4. Wacht 1-2 min op provisioning +5. Noteer in REFLECTIE.md: + - Project URL (eindigt op `.supabase.co`) + - Anon key (Settings β†’ API) + +Je hoeft NIETS in te bouwen β€” alleen account klaar. + +--- + +## Opdracht 3 β€” Reflectie (250 woorden) + +Schrijf in `REFLECTIE.md`: + +- Wat is volgens jou het verschil tussen een Server Action en een traditionele API route? +- Hoe vond je werken met `useFormStatus` + `useOptimistic`? +- Welke onderdelen voelden nog onnatuurlijk of onduidelijk? +- Wat verwacht je dat met Supabase makkelijker wordt? + +--- + +## Inleveren + +GitHub repo URL via Teams. Vermeld in je commit-messages welke polish-items je gekozen hebt. + +--- + +## Tips + +- **Commits klein houden** β€” één polish-item per commit +- **Loop niet vast op één feature** β€” als iets niet werkt, kies een ander item +- **Vraag hulp** in Teams als nodig +- **Tijd:** ~2 uur + +Volgende les: Γ©chte database, Γ©cht persistent. QuickPoll wordt productie-klaar. diff --git a/Les06-NextJS-QuickPoll-Part2/Les06-Huiswerk.pdf b/Les06-NextJS-QuickPoll-Part2/Les06-Huiswerk.pdf new file mode 100644 index 0000000..2d29b5d --- /dev/null +++ b/Les06-NextJS-QuickPoll-Part2/Les06-Huiswerk.pdf @@ -0,0 +1,105 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/BaseFont /Symbol /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +6 0 obj +<< +/Contents 11 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 10 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +7 0 obj +<< +/Contents 12 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 10 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/PageMode /UseNone /Pages 10 0 R /Type /Catalog +>> +endobj +9 0 obj +<< +/Author (NOVI Hogeschool Utrecht) /CreationDate (D:20260607080655+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260607080655+00'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Huiswerk) /Trapped /False +>> +endobj +10 0 obj +<< +/Count 2 /Kids [ 6 0 R 7 0 R ] /Type /Pages +>> +endobj +11 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 2010 +>> +stream +Gb!#\gNM%*'Re;/SB&EqZ/dub"^:+`.>H;_qj&!N2./j%,q'F\E0"_po3WK'!s9&(9,Z#0YS6O*Uq6h9fKJ"OeZclZt0[SEDlMJX"(.b7Od"Z$")E6$%lo]68,,U"P[id\^X0[^SH8o$:>(H(&#aLMiDb1km5G"fehBR$pc$a+?kcj3')7kO;'gGimmV)8c,1jo0Z<\!/pmEXj2d'+\Zkdha]`JB:Hl5f]g;'?t]BB@Z4DKufQBSX3B[fM'3l8B8SKUp)ace&j>u+I_=n##`4$hiWoiU64\B-)iqYGi<@9\(-ZPfsY\Cp=]_#e6EPoBY%ae27L83CPG2=BWMg*Q(seeRQLMIo/I^iM`#_NesbGJk)XV+,K/JSI.^:k`K2%pO)S/Xik!W)lkC\^-t:+`2NEQ`)JIQVt*&4*k[:D\r<.fTe0aZNtPB$d@,!76F8'3ht3&%/`%s\;%,+!s=H^ajGrN9PEE&e,T_Ze9/e^@eYIekYMl$FVq<:ISg\J;%\bhAj+D66ofcu^Fk1(^QN"2M$ugr%tDFg,%4E9EHmX%Sar#'5fC!AP6B,lWhs0eF9aYUD:s4ki,PP/O)$r+3PBC%2MJ6(YCkf";\2n'>qI-8>RH<3[5(WZ_sn2*^Kkijl]m71UaXmG2HdFN_,:sTT7q52(NI62+ldBX0anTk+:.EPBsu*S8$T,j2&$-m[-.?qoZM3nj+'M0^YM:UTc@aVb?pDTAZGEeWbn)Vl@B%1qE*MW`A0NX%.d1OnbnM67O&LX3KLKfYsBl73i0a!hU+?jj3c/;cioKua62U/]HrRokTk>IZB<[Qm2;ScGb4L@Ga.8R+Nmp5ZX1un]?%htE8Z]H=LB3_qC*KFa1A291G*n?gW":G.hW3A5lVTbZN+f]DP^RhBMXZ_M%M+**q$q/6@as,&scVcLM@Xmd?"NdA4ID)?I[1'DtiR]k^YI,_[2_5Z>S/TNcK[/%GVAY1lF[ESY(H!JQ:Z_0@`A[M+&cG#R^Eg@G7$\3&^7Xk[+cD;gZSq!%C0h;NUkk;P4;ei("uTICq-F-iWi5E.q%G\Xj?._rF.$LK/jpcO)7g%0:hc]kL1EK"cUFSoDRK1/OH#61i43t;2`p+Ni#6Y\K@F]RtD'_7Xm2.aMd9?VPm/!DXBl/='[&K8]!i:@`]QR1jE)lg^9G`5,eUbU1":L67fh1f,j4q23*f,A9c9l]m>rBYI(3p4"7WCAC=Cs=\YA=UOM?b,;qn\P#l[LCR)/c_?/PE"oBth0)6-C<'G99HC5O)(A/$XUO"SdFP/\oYOJbM;[mDg`p"\dK-ZV6I4CiG/^f"s:ZbN!13VTT?"pJV]+,](W4nQQ%91F(N^FSW,Xlg+N)89+,+`Xi3(JO5mJr@j#4^UA=S8,_,EBWsEUb;0gthW>5&4'](q?XfE#f/K&j%+0f=O\joW@l#[KI67YS-_D.BJNnIoW?EpMUibdMu%$@b*,f9g3?`R^cZ,r\0nNmsD5TbL`9a5lB5Y>fBf`NqVV((Y#bBYZFWYjQ_*p$\L4W.l<(D*TZ_IW/2e7bMi$iFE4Jb)`?,E/sb/]X2B%X6qF.;?lh(hmNA'*"/R$CX4Kendstream +endobj +12 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1190 +>> +stream +Gb!;b962"3&AI`dqFIos4OQ@^-0f<1_3_TZ#oR(%ajL@>RXQS:RkXhZT5@?cQoJf66aJ.#`0B+O?H4^G:(PY$TNA1@aiP<=G#pTs_`;Lec?L2l=+9[DlQlcIEh>POp,+Do""j?6\c,H0BOTf)-[J&m3bi+$76X2nNYNprE>cJ+!d8[(b^=F2mdi*s-KQ',*5B)XnW_e1qGR!\.)dpR_(N:.C::T]`ZB=8UFggd[P>#MTJCs@19+\72"Cdd#-it1[N^qI2NpoMc#6Gk7ZqhgP0SoF]]%9r^'3g7(aPdWL3K@j20^K/(JL@:9MWO?F<`8hDEkIC=[UOSA2K'hK4E50A9J#(I!oY:dQ-K*t_UbMQ>Q\n;8s>+]7HU5cOMp?)T;c[IEbQ\8Z3O3#4Y!./L3(HrW8%s]!59[`%Hk<.`CZ.>)mdn?\;$3D[4s:XQ+PYH%nSO+Z4UAJB\hkeFl_=#q_JH;581mbHgZ31[-k3Sd1f3'::\'o`>;k9fjA!,YF?Eah*^o,7BLm/3S>Wj1bXd)Ll!.4RR.4W2&MD6[R-P&TT^@/Ib:_>2a3"ldKUjp7@t)$C3Q%gI@4/)jTRo%>.9R[';RfP:TKB]fUJ4o,jll61t~>endstream +endobj +xref +0 13 +0000000000 65535 f +0000000061 00000 n +0000000122 00000 n +0000000229 00000 n +0000000341 00000 n +0000000446 00000 n +0000000523 00000 n +0000000728 00000 n +0000000933 00000 n +0000001002 00000 n +0000001287 00000 n +0000001353 00000 n +0000003455 00000 n +trailer +<< +/ID +[] +% ReportLab generated PDF document -- digest (opensource) + +/Info 9 0 R +/Root 8 0 R +/Size 13 +>> +startxref +4737 +%%EOF diff --git a/Les06-NextJS-QuickPoll-Part2/Les06-Lesopdracht.md b/Les06-NextJS-QuickPoll-Part2/Les06-Lesopdracht.md new file mode 100644 index 0000000..9840c76 --- /dev/null +++ b/Les06-NextJS-QuickPoll-Part2/Les06-Lesopdracht.md @@ -0,0 +1,197 @@ +# Les 6 β€” Lesopdracht +## QuickPoll Part 2 β€” Server Actions + polish + +**Duur:** ~120 minuten klassikaal + +--- + +## Doel + +Aan het einde heeft QuickPoll: +- Server actions voor vote submission +- Een /create pagina voor nieuwe polls +- Loading + error states +- Optimistic updates + +--- + +## Stap 1 β€” Server Action voor voting + +`app/poll/[id]/actions.ts`: + +```typescript +"use server"; +import { polls } from "@/lib/data"; +import { revalidatePath } from "next/cache"; + +export async function vote(pollId: string, optionId: string) { + const poll = polls.find(p => p.id === pollId); + if (!poll) throw new Error("Poll niet gevonden"); + + const option = poll.options.find(o => o.id === optionId); + if (!option) throw new Error("Optie niet gevonden"); + + option.votes += 1; + revalidatePath(`/poll/${pollId}`); +} +``` + +--- + +## Stap 2 β€” VoteForm met server action + +Refactor `components/VoteForm.tsx` om `vote()` server action te gebruiken in plaats van useState: + +```tsx +"use client"; +import { vote } from "@/app/poll/[id]/actions"; +import { useFormStatus } from "react-dom"; + +function VoteButton({ option }) { + const { pending } = useFormStatus(); + return ( + + ); +} + +export function VoteForm({ poll }) { + return ( +
+ {poll.options.map(o => ( +
+ + + ))} +
+ ); +} +``` + +--- + +## Stap 3 β€” /create pagina + +`app/create/page.tsx`: + +```tsx +import { createPoll } from "./actions"; + +export default function CreatePage() { + return ( +
+

Nieuwe poll

+
+ +