From 0776f8af4c9fc131db299c2cf615bce75dcccad7 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Fri, 8 Aug 2008 16:37:58 +0000 Subject: --- LaTeX/chapters/implementierung.tex | 4 +- LaTeX/chapters/simulator.tex | 4 +- LaTeX/diplomarbeit.pdf | 2342 ++++++++++++----------- ROADMAP | 3 +- sources/core/VSAbstractProcess.java | 24 +- sources/core/VSInternalProcess.java | 18 +- sources/core/VSTaskManager.java | 26 +- sources/events/internal/VSProtocolEvent.java | 2 +- sources/protocols/VSAbstractProtocol.java | 4 +- sources/simulator/VSLogging.java | 12 +- sources/simulator/VSSimulator.java | 62 +- sources/simulator/VSSimulatorCanvas.java | 1820 ------------------ sources/simulator/VSSimulatorFrame.java | 16 +- sources/simulator/VSSimulatorVisualization.java | 1820 ++++++++++++++++++ 14 files changed, 3082 insertions(+), 3075 deletions(-) delete mode 100644 sources/simulator/VSSimulatorCanvas.java create mode 100644 sources/simulator/VSSimulatorVisualization.java diff --git a/LaTeX/chapters/implementierung.tex b/LaTeX/chapters/implementierung.tex index b24cbe8..fc70eeb 100644 --- a/LaTeX/chapters/implementierung.tex +++ b/LaTeX/chapters/implementierung.tex @@ -446,11 +446,13 @@ registerEvent("protocols.implementations.VSMyProtocol", \section{GUI sowie Simulationsvisualisierung} +Vektor-Lamport Paint-Pos + \section{Serialisierung von Simulationen} \subsubsection{R\"{u}ckw\"{a}rtskompatibel} -\section{Noch nicht Erw\"{a}hntes} +\section{Helfer- und Ausnahmeklassen} Es wurden noch nicht die Klassen der Pakete \textit{utils} (Abbildung \ref{fig:PackageUtils}) sowie \textit{exceptions} (Abbildung \ref{fig:PackageExceptions}) vorgestellt. \textit{utils} fasst lediglich einige Helferklassen zusammen, die vom restlichen Quelltext verwendet werden. diff --git a/LaTeX/chapters/simulator.tex b/LaTeX/chapters/simulator.tex index 230d124..5596b53 100644 --- a/LaTeX/chapters/simulator.tex +++ b/LaTeX/chapters/simulator.tex @@ -1053,7 +1053,7 @@ Bisher wurden alle verf\"{u}gbaren Protokolle anhand von Beispielen aufgef\"{u}h \label{fig:Lamportzeit} \end{figure} -Die Vektor- und Lamportzeitstempel lassen sich sehr gut am bereits behandeltem Beispiel des Berkeley-Protokoll's demonstrieren. Nach Aktivierung des Lamportzeit-Schalters erscheint bei jedem Ereignis die zum jeweiligen Prozess geh\"{o}rigen Lamportzeitstempel (Abbildung \ref{fig:Lamportzeit}). Jeder Prozess besitzt einen eigenen Lamportzeitstempel, der bei jedem Versenden oder Erhalten einer Nachricht inkrementiert wird. Jeder Nachricht wird die aktuelle Lamportzeit $t_l(i)$ des Senderprozesses $i$ beigef\"{u}gt. Wenn ein weiterer Prozess $j$ diese Nachricht erh\"{a}lt, so wird der aktuelle Lamportzeitstempel $t_l(j)$ von Prozess $j$ wie folgt neu berechnet: +Die Vektor- und Lamportzeitstempel lassen sich sehr gut am bereits behandeltem Beispiel des Berkeley-Protokoll's demonstrieren. Nach Aktivierung des Lamportzeit-Schalters erscheint bei jedem Ereignis eines Prozesses der aktuelle Lamportzeitstempel (Abbildung \ref{fig:Lamportzeit}). Jeder Prozess besitzt einen eigenen Lamportzeitstempel, der bei jedem Versenden oder Erhalten einer Nachricht inkrementiert wird. Jeder Nachricht wird die aktuelle Lamportzeit $t_l(i)$ des Senderprozesses $i$ beigef\"{u}gt. Wenn ein weiterer Prozess $j$ diese Nachricht erh\"{a}lt, so wird der aktuelle Lamportzeitstempel $t_l(j)$ von Prozess $j$ wie folgt neu berechnet: \begin{equation*} t_l(j) := 1 + max(t_l(j), t_l(i)) @@ -1081,7 +1081,7 @@ Wie bereits beschrieben gibt es in den Simulationseinstellungen die boolschen Va \newpage \subsection{Simulation langsamer Verbindungen} -Mit dem Simulator lassen sich auch langsame Verbindungen zu einem bestimmten Prozess simulieren. F\"{u}r die Demonstration wird das Beispiel aus Kapitel 2.5.5 wieder aufgegriffen, wo das Protokoll zur internen Synchronisation (P1) mit der Christians-Methode (P3) parallel simuliert wurden. P2 stellt den Server beider Protokolle zur Verf\"{u}gung. In diesem Szenario soll P3 eine schlechte Netzwerkverbindung besitzen, sodass Nachrichten von- und an P3 stets eine l\"{a}ngere \"{U}bertragungszeit haben. +Mit dem Simulator lassen sich auch langsame Verbindungen zu einem bestimmten Prozess simulieren. F\"{u}r die Demonstration wird das Beispiel aus Kapitel 2.5.5 wieder aufgegriffen, wo das Protokoll zur internen Synchronisation (P1) mit der Christians-Methode (P3) parallel simuliert wurden. P2 stellt den Server beider Protokolle zur Verf\"{u}gung. In diesem Szenario soll P3 eine schlechte Netzwerkverbindung besitzen, sodass Nachrichten von- und an P3 stets eine l\"{a}ngere \"{U}bertragungszeit ben\"{o}tigen. Die Ereignisse sind so wie bereits auf Tabelle \ref{tb:InterneSync2Tasks} dargestellt wurde programmiert. In den Simulationseinstellungen ist hier die Einstellung ``Mittelwerte der \"{U}bertragungszeiten bilden'' aktiviert. In den Prozesseinstellungen von P3 wurde ``Minimale \"{U}bertragungszeit'' auf \textit{2000ms} und ``Maximale \"{U}bertragungszeit'' auf \textit{8000ms} gesetzt. P1 und P2 behalten als Standardeinstellungen f\"{u}r die minimale und maximale \"{U}bertragungszeiten jeweils \textit{500ms} und \textit{2000ms} eingestellt. Die Simulationsdauer wurde auf \textit{20000ms} gesetzt. diff --git a/LaTeX/diplomarbeit.pdf b/LaTeX/diplomarbeit.pdf index 2f1e6be..9df44da 100644 --- a/LaTeX/diplomarbeit.pdf +++ b/LaTeX/diplomarbeit.pdf @@ -261,7 +261,7 @@ endobj << /S /GoTo /D (section.3.8) >> endobj 180 0 obj -(\376\377\0003\000.\0008\000\040\000N\000o\000c\000h\000\040\000n\000i\000c\000h\000t\000\040\000E\000r\000w\000\344\000h\000n\000t\000e\000s) +(\376\377\0003\000.\0008\000\040\000H\000e\000l\000f\000e\000r\000-\000\040\000u\000n\000d\000\040\000A\000u\000s\000n\000a\000h\000m\000e\000k\000l\000a\000s\000s\000e\000n) endobj 181 0 obj << /S /GoTo /D (section.3.9) >> @@ -748,19 +748,17 @@ endobj /ProcSet [ /PDF /Text ] >> endobj 255 0 obj << -/Length 1914 +/Length 1911 /Filter /FlateDecode >> stream -x]o6+ti3k[Q]hvZl~(Qt/H G< - -Xa$ԩ8=gvīXO4+,qZM5':= zqY}\-KU7uuXu})ZBJ /VppW1IuU쯋p4#a\GST~,WZOU\qc϶o7嶬UOʌ&JJQıRAd)3i!r14dlq"hYCr> .6i:I2&~wdt_-l 丩ꪬ9Ki5Ʃ5Yt/i?F8{Sk4 pnzf j p,7ڋWqOpiɌzU7C,Xn#:ܦ5yBqx -{0 -eH˼S -eש;iSKI=^]Lx(*ci3L,hnr`bQS[K"f'=<ٔ$aH>*Mq^E=)SbF=]P$Ciaߗ54%MEZ)A[`*֌L|d#,  X l\$UAdk|䮾=VtwReuѦuׁt˪%JGQ&wA  :9>"F4ch9g($$c+S=aM4M? i@,<2 - j.i45^eoZ܉/r#NE=kftQ ?Ɨn&C ׋=v˛)xKb}]׀)0gf|Ɍ&Ty -L?VyD":tD5O"ҧ\ 23KqCFq1Gd@E=':-*LP-J5kt[޼FPqV2J!ђ";Q";UfV]tY}%yD:t 49GJsb݋ZfqwUu٤EQZ8q(UIn|?F_b5IGk(vcQϬwTgs_fgI EIN1Ʃ/YLE$JGˑE=D?ыZ u|ɓ/wubwMudB'' -Uv&T\ bc_sX`9pQi{I&q,tX8NK1 Sp\U6Hbٌ`EzV Ր2qXv>]޴,l<%4p":q٩2Y1X#ZDhŢE0&dNӲ70om۩ZM +pi "Mcl}k҉7o2VG 9 muBg$dNHY^'!,>Fw~t'KFtT;CNc?='e29ߙZ S* 9W)<*JoMYluJ0"EcuX9b\:eatBSSi,ΠSxԥX;[wUsy陝zA~e 鍽Y6^q7,9Ks0xTrgKS4i`endstream +x[o6)h31.6k˃_i}JDaZX5yhXa$ԩ8Wg߽쾳VE~~8eqf}v]wsf9oeGqJaRË\h.\T F`6/M.r:Lh]RBk=* nb\CU77seF%(XXR 2zR8joc 2`84h!V9@EYl5II|j3:5l73䰪6UI,aFc O8vVf־Ï1A5Nxq8:^3C7D''|QC(o =6CZ ,7溹8](H Nfԩ28gDXdž lbDsVj ŢJᕒ*0()"-N)]&Nu-u6&u}Wyw(S01_;X#`W0F`MGˁE= Lm-ڊ w`f]&'m#Q~TX6bAzyzS4=x|5zX㵡I.A* ++hJ)!(S4Uxd> $  X5l\$UAdk|~sw\{IվmF{n\{-D+EU3dp#}E,chr8bQOQH!HF:z*WUtR746THPC tI}vE,K} *|?ʕKGt89 i"D l]+[_@Tv@7 \v/^^Lo}8ƻ3Ngfy sfƗh)A3ouЙG$3OGIT$bQO+},S:Y1ajy=ĬUWs`AT4=x2QOt9P,zF7]s} +.'l%:B-,b#%UefՖH7g^"љG3OGɛ> Br4'.֝NowsXUUZ%̏HbPet~#m5(F_tb7M1)}'Ke~Y !=um/^]$-70El'[Q4{^+$bHDS#z"\C*x $~T= r5Ue #q=,+zhV|V9=a&2z"sC}`)w#D*F4*VX + OB/_:Z a |T5@v׋ѓ/ebUdB'' +UvFlU\ bC_SXVc9pQOi{I&q,ҴXn9K!# Sp\U6Hbٌ`EzR Ր2qXն~_r8ۙ~]w蛈*,+b)A1[}xbٌDz@_Y[M WW~KyW~}S[),԰" +D)lzjgIt"UiDBdBdП 68SI6m|WUpr%юG#:> 2j`oE-)VSک ݮn.7atqݪ2VtX:NX  ++̧LpY&AMա-~{Jg:T3;30 7K#X{l2 nXsj =&Dv!N&/di:Hendstream endobj 254 0 obj << /Type /Page @@ -892,7 +890,7 @@ endobj 277 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [86.8628 453.8342 196.6839 462.399] +/Rect [86.8628 453.8342 229.0344 462.6052] /Subtype /Link /A << /S /GoTo /D (section.3.8) >> >> endobj @@ -1515,8 +1513,8 @@ endobj 425 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807232201Z00'00') -/ModDate (D:20080807232201Z00'00') +/CreationDate (D:20080808140051Z00'00') +/ModDate (D:20080808140051Z00'00') >> endobj 426 0 obj @@ -1614,8 +1612,8 @@ endobj 434 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807232201Z00'00') -/ModDate (D:20080807232201Z00'00') +/CreationDate (D:20080808140051Z00'00') +/ModDate (D:20080808140051Z00'00') >> endobj 435 0 obj @@ -5651,19 +5649,18 @@ endobj /ProcSet [ /PDF /Text ] >> endobj 731 0 obj << -/Length 1817 +/Length 1800 /Filter /FlateDecode >> stream -xn6=_X.$]ЭA[-lC)r,;6(ć(qYdW]Ox_pgl}zq+2Ǽ:ΤL.^L~.n63dә|rjxUOw/N/zFr欕'֖icl&C]rr%u aQ@Ƴ"E]m(&z -kSZ3Ø3۝0ұ\sׇH}q[95 'hs1/v ƎjڰRLZf0hNs\6Lygɛw<ꋓ{ ΄2[HϙT^t;W' 8L.r .1p`d1#3%ĵI=i y=})&Y7gy4Esɤ2a.){,%ᬜpVfx=KLryiس(dET6/L0{P.!tLa92ۛ`ޛUA9 -o#Ь?+ RhcE#L=B.#ضkb -4jC:z*鶩օ~ 7X ]iS5m\L~+=iˏeⓢJ$ 3ղjr%+"x/2]GiPQwV"AI4@OA{Z[emR3^NT-7|7p"E۔X!LV/cݕHJ=LJ=+|!GAv>F4 pUMFZ24e3o@K:b'с7ӊ cT#=-zx/1>ʕ0S(\-[:.:CҰB]YO0锢v<`X= 7c$zGA=WQUN* 4ܬ-;ֹhc<5PrVh! - 8T5Ќ}9R0^]/1h Y .T +5 zD aS$ôt-C^ 5$WZ7$적bb(rr7l5>=e ˹rl - -ڎҲRI M}xw}`dX-ZZVaKegcL|_r^hh?FAm:YLBv4T9uht)0 /kPVCJK ؙ9VP (om:WY8A7F:-⠏ uW">wUJp> SKV~X4"1K:xkraD{` D x[ >_ŏ$xeY#"K3)(rOMI0ܡ.7 -smvr \%TZѥ0,v V`BW<&xk+?#yQo=IӨ_pn endstream +xn6=_X.$]-A[-gl#*-;6 +ćѹHqYdW,Ox6_N}zy;+2Ǽ:ͤL.^Nߏ~,&,d|tjڸ(cGEѬ7'c#9sϓRk˴y6Y>.`ELH慰Lg Y2"mx7Vf@:"\ߗavx"3}FIzhyeLzT74T %Bc ַW*׳NoUK>ZuE5/iU|:bⰹHuaax F? aLÒP+Xuy3OOІ` )s\zZV5p~T erti,@媀5%2VV?+5y@Krx]V5݀\]DVd UP$ї-v(`ULiL c lJr]Ƣ d$ϔk凱⣴}l@;LOc +s -nrH1ij0LR3:$sل3A?NPߜLx/IEY\g'f01>&pPCj9w>bLc 2qfҤ?,!V@<{/8D&D:Ϝ߳h.B"%%{/D03 ׿Cp~}t].0S @%.>}asQCaRBs 3 e<77ǫrX9FY3', ~Vb'޵ ? JvRAG +zb]Fhi({ hhB{z*aօ~WXCҪZ77P'PΎ~)brf)ʖO*܍ 0dͼ9t@]AYU*],sxC]k60]q÷e7Ev"$o7Y=[?0'7K:4{"iE͆ ]Z&L$lNga]6:ET> _z#=s~;*۸yf` 9jJsAìU +Fo7P54΀XSF( ܧ@t:C! p9Ij1]FzϠrIq, By \ tFkͬraZ'⃐&Z o ÀilqFS;NNfB{+5y@a?$Q,Ҩnց( +Rϯ֋W\YQFJRp"B +n1NtW%BjH)UiBSU;ǹŠ("T,P"խicUe,ItKZPW"/oNW# +EC WJp>A)ek{Q] Y$YvlF[Jd%z*w{oɼhx+D*gSQ VEKSo/ Kf$ ¥[#W* rM 0{, Z :paFm'9rG^S\>E]i;(QpTendstream endobj 730 0 obj << /Type /Page @@ -5802,7 +5799,7 @@ endobj 733 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [264.3954 311.9708 283.8362 322.553] +/Rect [234.0218 311.9708 253.4627 322.553] /Subtype /Link /A << /S /GoTo /D (figure.2.25) >> >> endobj @@ -6008,15 +6005,24 @@ endobj /ProcSet [ /PDF /Text /ImageC ] >> endobj 745 0 obj << -/Length 2233 +/Length 2239 /Filter /FlateDecode >> stream -xڭ]sݿBDIᮾ\2鸱'@Ę.$k뻋(ls3o-VUY@6pWx8 c쏷}Nʲ,Iq%uƔH51Zeej#ֱ<*[ڸvkCvnFrfDMJMb)XtK*XtJp,Aei*.%,K7M7.~Y}fAѲ+yd2ezEImGhI0 SկceT;λds]@4_vݓp˪!N2/@?ʮ#.Rm0|Rҍ*b`X,Wnt}HoU[T˪Za*F~{K\Hf p~xܔd uVKG{"<ƾ`.6LԔ^6vT] qï/p+}MT}Q9cuy;#HI£?װRݗ 8%FLTWNuc 2o sQ T{ݑVueY't =yC?r:BfѻDr/$]rSZkkN)}dsN%ZʑNIZ 䥝 $M0O -1iˋo_ +r@gFqyF _nqp43Z&83Le WpwaRg"主S;ſ%Ybt1W4,֑[\mkv4vƭkc҄_]H_Z)ݎ,?ci3f5wL+pRȥ) Yf4<~l)zހC3*4ɔ}TIjW9LԱmjCY2WІKȭ fB`1fYf^ݔ0&/n<. rg;%S t o z5܉Ǘ"6^2=rS+fRDz 5K %$Rhcސ_z[qhʕ&#V01TX~zS1aj۝kxxbi FQӏ},a{47 l4G97>qw~6G/߸/iryrtuf'F;g{kApfKcUfT*xO̚Hgs'~rXVCҏ{χ}[4eIKe`03[jiqLFLt5@>$Np|`& - F7X!7Nv 0k`GG\7+#/W'잜+fI=7YHȾoiC?W',*~P}2\iԖԪklwK&7qhKԅr}wERznł?H5<34Sx]ȫ!ۋ>[p,V/nRgL.Do_UWn+Dp\ mTawfn{Fr欕oRk˴b%֥C]RR%u Yj22KTz]$,Kפ6m4<).zEzQʔSX$x%9/OU\)-! &FgۼmA6V^3e=<j$ݮRl[Bh(Uٔ5w* (-fXe2xkrp6V5AEگ)hądH,uFRWK> x'=?P?ah췁!džI2H|aj5fu+wk \d +$/9yݮ~*;(לz+˕IX\ˀ vD(7^E꾬z G)6Zg{XXC!g/G7SuvKZ/Ff8{lˇM,g͒H< HUX]F6p׳=%<]K ˝^[wJ)%ک% 18뾬]F! =izIғ6Ԕպ кx[DnߗIF-t $Y4Epc5rt)K0Մ$FXڔi1"oe|XjCA'vbt1!0H[Or-p%"r7ߟN6D>Ɲ +j2"x-|}uU5/uAAkO j 3+jo+iO:ߪxZBE2L:hUyWyI E!.!ykA(%ҌKomf-mty !_L8zEl~m2no +5 +BQ[mCi,`ى38J+󱠁YQ>t;|!1s`aT .4tFs&33S{8S3ůE?\oԙ 9.dT&_=A|ƙeC>K.r ʘyr?eaLco7&MccU&<ʿ0V-\N pzESj(Af߮KZbK?vD aK|=jxi&"NhS%)g:ub"I$PC4נQb"6}eݯ|i8)ؓheC穣<=Xjn[ƭ 3M(0X.㨵h~"hJ=Nt~ +~mT{ +Aܰq_c4^f*N?Z ͨ7T:9D&`OÀ#b}Zœ5H? +=MQ%-qBzA/vő2r&Np}vDMOCp~/;^:A0랷hGG|7#/W/잜+z~}I'~OXT62E^eܣ +o-U ؾ~jЋĽ(9s#pQqXe)E:d&v*1'R R`&oR-V4>>SJa +'[g`=Kh̨)"L +cɅe]rLhbVs0Yr0\32/92p<#Q&A%{Yԛ5oQTH8t,yM`l=j*Rosa<L0}GQ> stream xڅXKs6WHX 8N7qsH%jQ PDy.> 1 'fiGA<!l}J>V'?_&AfY$Z"GQLZo߼ɌXyn"Mw] /dXf'I45ch82ZjzOY3]&"Z^Mo"vMBR>j9uf=YVͮ$>…Z~.SiNs#k6Sx_㟹A.NW}Uu> +[6mZU1GkFCU48.Ңm_r.L#;LxUU弛}Y,^ ( JtYRhqOCnM4ͷmA-&VwovKb=9kޖ5̑UcN[.GjfcLqp x8>FY7`=IzٱJ_ubXYW^ұ_T5UޅQTI"(BV˶wge -n"I+i[m&]mz*{GY3]-QTHxsL;ic([$8_#߮<JPLT},D6;7pƋDxwa5 1!8F5dAʨomʥ!g2X"둓И/ٹf1A.y Q S{-Lf 3TI'SZ/-{ydAm56n͖CQu$O&I X̹2U¢aG>d|u:S EZOj%:CϼGPwT~T˸ 1 h8r#4e@qaM鿭jZiui5]#:1>!GST|teM՚șam^ˢSڜ0 +n"I+i[m&]mz*{GY3]-QTHxsL;ic([$8_#߮<JPLT},D6;7pƋDxwa5 1!8F5dAʨomʥ!g2X"둓И/ٹf1A.y Q S{-Lf 3TI'SZ/-{ydAm56n͖CQu$O&I X̹2U¢aG>d|u:S EZOj%:CϼGPwT~T˸ 1 h8r#4e@qaM鿭jZiui5]#:1>!GST|teM՚șam^ˢSڜ0 KoNaEWlx,.w9BgHMnň|_[M(Hw9ח8huTCVPlT0%kt])VjK{g GÐݟ\F* ӧcpHp*qneCnl]ƒ%9xXx6DX 0!aX0aTM}1.dhh;t$RmҚ(Sر\,!#lB/z>v: 3[[fz -Gv pp[8V]1iyLt#| 9ʼ{0;0_Z/ة◬Q|l V-xzؕVw޳b\j>vJ#T#E?U?N_g' J8Noi|.K="h'!z /Xendstream +Gv pp[8V]1iyLt#| 9ʼ{0;0_Z/ة◬Q|l V-xzؕVw޳b\j>vJ#T#E?U?N_g' J8Noi|.K="h'!z /X endstream endobj 751 0 obj << /Type /Page @@ -6302,8 +6308,8 @@ endobj 770 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807232200Z00'00') -/ModDate (D:20080807232200Z00'00') +/CreationDate (D:20080808140050Z00'00') +/ModDate (D:20080808140050Z00'00') >> endobj 771 0 obj @@ -6453,8 +6459,8 @@ endobj 784 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807232200Z00'00') -/ModDate (D:20080807232200Z00'00') +/CreationDate (D:20080808140050Z00'00') +/ModDate (D:20080808140050Z00'00') >> endobj 785 0 obj @@ -6600,8 +6606,8 @@ endobj 803 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807232201Z00'00') -/ModDate (D:20080807232201Z00'00') +/CreationDate (D:20080808140051Z00'00') +/ModDate (D:20080808140051Z00'00') >> endobj 804 0 obj @@ -6762,8 +6768,8 @@ endobj 828 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807232202Z00'00') -/ModDate (D:20080807232202Z00'00') +/CreationDate (D:20080808140052Z00'00') +/ModDate (D:20080808140052Z00'00') >> endobj 829 0 obj @@ -6861,8 +6867,8 @@ endobj 837 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807232201Z00'00') -/ModDate (D:20080807232201Z00'00') +/CreationDate (D:20080808140051Z00'00') +/ModDate (D:20080808140051Z00'00') >> endobj 838 0 obj @@ -7000,8 +7006,8 @@ endobj 857 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807232200Z00'00') -/ModDate (D:20080807232200Z00'00') +/CreationDate (D:20080808140051Z00'00') +/ModDate (D:20080808140051Z00'00') >> endobj 858 0 obj @@ -7213,20 +7219,18 @@ endobj /ProcSet [ /PDF /Text ] >> endobj 893 0 obj << -/Length 1601 +/Length 1649 /Filter /FlateDecode >> stream -xڭXKsH+T>AU{F;\L@k!Iػۭ d*ӌzu`?I$Udbc|=h?Y6.oEZ[ą"rz2~ܧ&SnXTQ:~:j}˫)Sm|y=i+N՚Rj"6є[B}+zD %,yI6}leRXX}\GAV u Jpb3V0jZvNY݊QӘaXD-p˴\qὥ^j3d%I'UK_Ӌ'(fD T4LZ$_b4$}vZM >݋9^D@{Iٯl{V TD:D2 k겢hU%LU -Ӛ%imt1(BG-RÈĆ2eS0Qɨ H]ZMB)('oAnƫ :Z -!$}9ϿWPa-/ -*Ů}%9cƹ[9,<V1%`gWj(Q;725)Ezx%զϒF -1 ^(p:$ jڬ[pJ*^:s?~L |t-=O$|ܺ,{BW@]:_i.H -{J΅Gsc^oU ymaU%uϠ-z]4?~cW,\uw+sM -iPvBQPTق{:kPu.h@9HN`z~}9.}F7\s?-a@`I[e.?_O"oJQFJp,kZ#P>Nd* ;4Z -G)j -A'҂a/Hcm+ji5I詊{O>a㜣wBJ&; z沣FK ц#3ug2~:g3]oCoXԫSjb*|rؤNV)Kf,f -Lʓ~`&KʲaS I=\Ʀ=`[Y9*b.{kf| . F윪[eԐ:jL!41=4 K-9=i!Gz׎A>%>sF5):R}I;ganΩIv=6.I0*2s@!%h}[lft=Nd-tKtKǶLp|{י9n.[aKK^5r(9. iF;RilםWk(xv`+Qa!؟:G9, +M,k|4Z 3! Uҷ:gKO&`%0ea o7,tv8>6e}}؞ph\#P߼qendstream +xڭXKsF Wprf)I$K-md吔%)JtLZb|HP#N% X0Wg4Y³_ZY_o%8er-Bn9*Z|I7v"t(|xu錩ɦXN^~vqW59gD*mJiQٗ4YggU?(adujv˳N +7 (jS%81F+ћ0jZuu[0Ju gL*H:9ˬ}y^SEܗz=_Z:[|'O1cD 44L۴Xb4}qU\w<@K9? <6~3\g*{)x11Rhljdq iEɬ9dW!Dcs#R褓B 5G̔I_d+t$h#wY= Vq +:S6ѡz% Ӣ9>_GAw~m_.|Zh]0囦 +% R[äO-@ut;0uTYCI爰}#hJ*|ieé 7dR㐯21 +%)5'n8NM@Ke@'s 097>?4̲:!T{gΈܜ@_X =]~b)+x ]VaQjD&#L\ TIˤ]~՝ n5pB@{QNhk`ma, Y=_sJhir^F3'n=0ia>I2;ж vh55|&`Pkꄓ +S9rіyß>+eB%ޖǦJq}SPu{(LuLz|h f; mgt|(PrMta +Snx>X5Y`e fub]~4g e@5,Je }yю;wlj~)a +;09eoܡ 72_4?ts,N Tx1Px[hendstream endobj 892 0 obj << /Type /Page @@ -7265,8 +7269,8 @@ endobj 900 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807232200Z00'00') -/ModDate (D:20080807232200Z00'00') +/CreationDate (D:20080808140050Z00'00') +/ModDate (D:20080808140050Z00'00') >> endobj 901 0 obj @@ -7288,14 +7292,14 @@ endobj 898 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [323.231 349.9102 337.6866 360.4925] +/Rect [323.231 349.3851 337.6866 359.9674] /Subtype /Link /A << /S /GoTo /D (figure.3.7) >> >> endobj 899 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [458.4512 349.9102 472.9068 360.4925] +/Rect [458.4512 349.3851 472.9068 359.9674] /Subtype /Link /A << /S /GoTo /D (figure.3.8) >> >> endobj @@ -7306,22 +7310,22 @@ endobj /D [892 0 R /XYZ 74.4095 692.0192 null] >> endobj 896 0 obj << -/D [892 0 R /XYZ 74.4095 623.6833 null] +/D [892 0 R /XYZ 74.4095 628.7596 null] >> endobj 170 0 obj << -/D [892 0 R /XYZ 74.4095 573.4271 null] +/D [892 0 R /XYZ 74.4095 586.8755 null] >> endobj 174 0 obj << -/D [892 0 R /XYZ 74.4095 521.204 null] +/D [892 0 R /XYZ 74.4095 499.3815 null] >> endobj 897 0 obj << -/D [892 0 R /XYZ 74.4095 432.7696 null] +/D [892 0 R /XYZ 74.4095 421.4327 null] >> endobj 178 0 obj << -/D [892 0 R /XYZ 74.4095 432.7696 null] +/D [892 0 R /XYZ 74.4095 421.4327 null] >> endobj 364 0 obj << -/D [892 0 R /XYZ 298.9871 159.38 null] +/D [892 0 R /XYZ 298.9871 161.6556 null] >> endobj 891 0 obj << /Font << /F61 259 0 R /F83 820 0 R /F28 209 0 R /F26 206 0 R >> @@ -7372,8 +7376,8 @@ endobj 909 0 obj << /Producer (GPL Ghostscript 8.61) -/CreationDate (D:20080807234916Z00'00') -/ModDate (D:20080807234916Z00'00') +/CreationDate (D:20080808140052Z00'00') +/ModDate (D:20080808140052Z00'00') >> endobj 910 0 obj @@ -7732,7 +7736,7 @@ endobj >> stream xڬeT^%;΃www݃Nnsqn?}{j͚UڛDIA(ao Pٚ:1-\N@c  4M -@ICGG_B&w3@ hc` s QX  @TQI[ZA@-mJ&6 Sh ;lۙ)͙/340:8lA g@v6fk7!'}]M@.Y$ΠnH3{SJ/_1p' `rv1/_4\Avŀ0v2:;OwNVv+q8mXX4udϠHۙXm7su>7ӿD%alfog 0#0)ػM SO[ovpQ0;`o{;nl ?l@MIHm_Am9KO{}(c,Nϕs#,4u!/`n. &r _r{P:*e0lNph܊0PLӛ1{P[/(OF&FBSA!SF8 W{Gd"vCmP@AGe+dQi%%ȟ,$qTu8/<˳J!J02$mlre6'?P + ^dwh7IQH/1 X,{fDGbW bI?Y|/*$OѓN(g%dxw;sT)5cWǯfpPj OnBwGqcB5-Hs1 ioI6QQ{=KqDlق],Y׽PFՓh ~ELn^'%)fd'S1{ TCc0JL6,+8Uocj`l`NWߍ +@ICGG_B&w3@ hc` s QX  @TQI[ZA@-mJ&6 Sh ;lۙ)͙/340:8lA g@v6fk7!'}]M@.Y$ΠnH3{SJ/_1p' `rv1/_4\Avŀ0v2:;OwNVv+q8mXX4udϠHۙXm7su>7ӿD%alfog 0#0)ػM SO[ovpQ0;`o{;nl ?l@MIHm_Am9KO{}(c,Nϕs#,4u!/`n. &r _r{P:*e0lNph܊0PLӛ1{P[/(OF&FBSA!SF8 W{Gd"vCmP@AGe+dQi%%ȟ,$qTu8/<˳J!J02$mlre6'?P + ^dwh7IQH/1 X,{fDGbW bI?Y|/*$OѓN(g%dxw;sT)5cWǯfpPj OnBwGqcB5-Hs1 ioI6QQ{=KqDlق],Y׽PFՓh ~ELn^'%)fd'S1{ TCc0JL6,+8Uocj`l`NWߍ =Q,slwL˰S;DV%&E% ;GL =EAqA4ߡfJi0>zq{q'ӘEWX@vҊ7ș%. 㬇\Q[Ku(Tkz=y/'٘6k "g\p4ʩ.2oHtmu\  ^1 h'^7[ f8@9O7!);6 JMjѻ[05"E]3_l(u8}CSi+5"ϕG!LĂb]UkC{@P9[~ue&F=nZWYtL+ͧK 1ƽ6z&_l}=ˬ+qm^7X.0?k*]@QF\TH+{+[h&b5 貆v|,G5#$=oyzY|qŃtH]STKN),8ɭI*mq3zΎmJCzCsxj+<| ˅^rp_ ͜^4eIo:)oN迵Tr|ާ`q,:@txM,:*Wp]?p [ @@ -7784,7 +7788,7 @@ Odo' MhV7ٮ)vܨ;2`Ɖ˜;xz$$)8[]n6=@d.Z5eyLּgKFAgR8+ZȎwnƧO'=+"O}4H t8 DriňRbHoګ1{۲B }y '#)_kb[-U),dY/rU̹Py>~fjh6<|y ;- őK2wT 5 GV ȩ[ Z Ṃe_ e\>c )-"iF 9B302wGS'` pl:XKmEiO2R d&L`7q~AB 뭴PXr.`8s|cmnqʓ `3ƇvK.A(x3=+ ?X~M^ ^{n$l־"x/!GBRH/κ.͑Q4|e#^j%x/Moi? &J$C*de%U' -wb\;Į2%zdbU{)5帗T(۷\KkpC8Eb@+xQRB5@#\\d!ȷ+VjȢ(Ze%r> endobj 818 0 obj << /Ascent 625 /CapHeight 557 /Descent -147 -/FontName /HYBVLE+NimbusMonL-Regu +/FontName /HYBYGV+NimbusMonL-Regu /ItalicAngle 0 /StemV 41 /XHeight 426 @@ -7820,14 +7824,18 @@ endobj /Filter /FlateDecode >> stream -xT{Tgo46ZCy%+Hx(TaH$S'3R`u%BHWJ5l,NU?rJq6Fpv1p!EXa 6yϼ۾EQBZVƮ=4lӾ.o>m61m+?[?> '4ڻ[@NAv>g=6\t:L$K6˭[kCt_ju})]Tri5SeC{ǂTD[Z\/6Y?xc=K%J>Ӱ2"#iM}3 |hus.}w@[.Pg?#룼yN}ᲇzOޕ^.~=$2UdZcùbAn$T3x1Ct.ǧ$U\[MlޥIVtzk=}}OZ[> 7z#w+-zQ*Q{ו%Ks -yemk{u#b'swl/bfzGŮt#ĹIҞJZ\Q5?xPh(Њos2R"(&'-7-[2y :6q Mn~|&FXTf\]-fpQ]ʗ㙘zբ'kI4ͬtɻxیmfO3[&X ->vT}eC?z u+sq.P9)/NfX٬/Jnzaw{J'º˭1ʅn^j堝]M -roJ)M?[ qu;(:HDy#pw l+rb Gi0f_lCendstream +xT{Tgo46ZCy%ZW!Hx(Ta|INf &(*. +BHW L&H)W81:<6"xc YiO 8ց w[7Z'_ J2C4tL^,IdTf +`,( )kwC <=(GO3;%0nQV1wM |\˲hLulZ u\qwKKc7ȒΝִ$`EQacq^oupfVS;w鼾 gs2č6_9еo*aIwۗ0K\ [ʘzڛ8)"MG|SX׾2؁;s>㣹_\ln:pBc g H;f~}㒋Α$rVZ]_}ݾ0;wZ(xfo^!0>]i?Q0ykؖ;MX|wuv/*bn,YULݴn♆o?)j|?Qۿ-GXpDQn^ ^rppm=}'J4EdZcù"QNΚDLg3p!Cr.ǧ$V\KMLI Lzkl +=}}OZS> 7z#w+-z*IkוKsm +emik{uy#b'rvl/âcgzFƬt#رI➯ +WU ))pIyV`!:GT( +Hl[$;O +}Fi.-SkE/Bz6eW%!y֑ؤ޺ҦdEWM=&0=VlΫ몮DRMEkf$CgL0}PʆŇt:Zd]zrpCn6Y)]RS[)Xi7Bf NOu[uR ErKuN;!ȦgoJ)M?/ꕕ\k%:*w.?8QxiF$I^g('pb,Ok0v_flRendstream endobj 649 0 obj << /Type /Font @@ -7836,14 +7844,14 @@ endobj /FirstChar 229 /LastChar 229 /Widths 972 0 R -/BaseFont /WMRVJF+StandardSymL +/BaseFont /WYHTIV+StandardSymL /FontDescriptor 647 0 R >> endobj 647 0 obj << /Ascent 504 /CapHeight 687 /Descent -228 -/FontName /WMRVJF+StandardSymL +/FontName /WYHTIV+StandardSymL /ItalicAngle 0 /StemV 0 /XHeight 400 @@ -7867,33 +7875,32 @@ endobj /Filter /FlateDecode >> stream -xvg4ֶD]L5щnBц 1-END !zD%QCtAD{&gyΧw̺o MF!b +xvg4ֶD]L5щnBFt 1-END !zD%QCtAD{&gyΧw̺o MF!b UG!:X)40BjB09 -Є9|  >wF0)ǁ&080!聎 40aHwaH LB($5K 00G8>  xp  ch#^N?yQxw<'0X#ೂ4΍a E9znX`a߹`(぀s3I!{YtN(_v?0oπD0' -q ?SY?'@yw]oSk{!wu }~_4p+G;*7߱ՐxED%$21p_: ͐PG'>HRo {2 :\dai*? +Є9|  >wF0)ǁ&080!B0$ o倀;0$&pBG +F ϥ@#uyn<`hw81g4/v'ԟ<(;ÓP, YAՉu`0~Q,0_\0@@dh20p*@Ü!h(iܿ>{O4?kc10>#,:H'@R/;7 g@wF_B"P +O ,? D;q{ߩ;~d[g/q#Ma_jHg"Rbm/ +c]N~XfH( #axQ$)7=}? {xT.gbaa ? `M<`S> ouu/ @TRV z[B ))! or!YE}Vb?:F 鈂^, ? aG/4/W?69RLecs4>KwGx1-d^2Bpol|YWx !Ж zO7$+&n[LiYoRF0`dltM{,;!#Mj -66֎:{?vw]y.Oћ?g6YY@l=QrGvzw< 7+z)'$ɚ{}pI,?t@6]#k4潉uOYg7  (ÚyhMȧ3,©7flhIsmrk%D?q{F -qP\];btYqIWmKnBr!,)nۜaɐG?~Hx}}1 ͇cRDg͆&ݖcG56 QjGnl٬ӅFp@/r*LD#ie\&̴UИ(se<̏FjfW@-A6CdяpoJ_n ޞڰ"Š'9 I7$U]n`P{>k#?Y xzlh;J!zp;aRQBu@x(]|zrZyZ -!܊R{F]c݉${8G?c ]Sy_Hߔy~cl -|{$"A$v&ZU-|!'~@{qrY۫MNIjD姂g7y֫\BX?Kh -t{,jTa$u+q׼Fa<:Lr䵳,^^C!2>Dkh?3lQw~*PB=s%LO~ -*)ݜ2}kKc?OԒvx \Fʠ/KZ_{?}J,YhCRm~APMeʃ\@C8*W%}Q'✴+ /Qbk|41=%eǤ͕mk CYb\p8qV=w!;-c%\g݈Lu))Džps1"{`K!TJ8Q >/Ա /BqUӼ&ĺS[gg7B3='= 1kwS>&'@dzf+([ZU꾝4 bJ$*gRVTWC1{z_`W@J[CBI7ÇMעHXX^0)qc#OcC_4}6cq~o"_ߪQݹv"#JT#s:#'HҠڴh ,ò+2BvȐ=DVi撔SXâvǷbg^Sf'E'V.|+#lG>=AQcjJecҥ`u8yÓ'C~A,J E{9^oL| r~vX62n.4дYji59 j&B_nט$ 0}5fo!ݫ_~({4xϔ\je.hGCx a[4ګ3diKv U3?Lk:_ڻ}#ڔDuH$~JY.w臽 K:F{<~÷l(쿪UF ? Dʅ} ţɬٚ\~'%,Dr@ӯ8X$#Cy -{[#:PCu=#^]y̋)Lˀ-h_қ ,[s, F1QjYDښ~9 Lm pi^̃` -bk%7iv\VΧW>B[UTKUink*r]sT `5thgcOtUQ|ܻ60~xlp>f۸:'ՁJۏy*?, #MN䝮ǪPyvimWk:'p~IJH]Af[>,/$<0{ǧ}P_F88f@GLCy'N7F+4r/OWc&)=ּ(]{w^*m#|:͡Ga /OwgZOyd s!/ O ;3i;߯qJk+B_f .mEyZDM4G[r5X:clIcH ղ➇hy_;rL"G@$;(~~uEX#˙ẏFr>Ygʟ3Yў(ǥ;VNkLO1 Q|t] <Ng~B˹>WF-z;tNecBX4FU<SHߥ@dJs{ڃ/,=I4fX;?AS]`n1$ zOFj(jkc [n@}D4-OLD.ȶ>AE_t|՟V3p&$l.b n?kzH|ZT洭qv[C3>Dr\uӯd_6VC#lZvlWSB[2;e:}{HY}t{j)#*H(ŧVEkw rҧ -~l2Y6jYVk$]H}WG}m&S&acwOHuTL.)Wluʟc6#.zW;ĦWz*a0A1KmC}:f5Fs0!cC +ŭ[|SPU^U?XꎔFfB)09TjK:Ֆ_PگTG%>v?IQ|ַ^ֱbc>/BYׇ[qi^PRwҌxKk<ʼnQ8Īf%T`czm>]ʂUQp3?skqrkj^q,h[5x}_|y2dMV4YʪS*6f#%~a'B -6#M"R?{tތQ2Vg63D۵gO'\}GcFMH:-5ƌh;LG /Kt? J*m!t0/4 |z~Pe*nk]]&&^CM+8m+`ؗ-cpR>:EޗYPHìO! GU܆2n'ժ r;n_qJ\,Oj (㩪}so[8`v"nƟ1Otm~ѭ06!u]3[EAA8I'r^wo)aak&zeEq ?| -^Ǿ\;I]BRgR?'R ]V [j8&䛢YW9*epNkWqYAL=64Jz6Wkb9]o]SЬtKZSӀl:EKQޡڀ^S~IssDڰMx꽼a]T]E##J {żY="yr oGڽZtvVr8DĨ+ &#h>e/_a0m={ |EjQ`IX~wT˨oEKHh*c%I}$g"T&ܾb*4,|:σF#cyE^8CT&պ b*'FO~ -lKn%)H^Q4:gK_r8U{zrɱ̅ruW -8醎"v!*CPNo%NNw%VHW}8{S%&w|B'ׅ|;2Z34ˊzc08ʯ7Su]:>rܿc2)tUwk5 |QMJXh}^0]oէdzXZۃud9eOASt,E<ͲqI/? G Ƣ!h7xendstream +66֎:{?vw]y.Oћ?g6YY@l=QrGvzw< 7+z)'$ɚ{}pI,?tn!m[Fxŧ̬ݳDq[~EݩJ +C]SJ[1 nΛVcs u>i ˽p.eٸ*i=m+b\[櫜Z~=i Q!|&:jV\Uq3lhw[꒛\:Kʰ6gfGv}2yyAϬ^:F{_u̧B!%$Qjęh#jI.lMCjT[6+"tQ\rЋ\9J;Hj 3mt4>dwY91cxyA7q6b qеP$Y#ܽgH+|gz|6H1IFNl*"+qIUX)T9~ީOOV?m$=})+ڎs^?>NTzg+q^F%~8FgekH:<ԞAט}Ew")^9໾9~"}+Y{*2O;q@Sow@D6>ܕW+74r՗'XUސE:䐽2bH&MB۰?jlyvU? 'CR vWՂY6ȋ; :Bc>l+ s׵-\xg5K{)NN}(%&)JȡW.5ڸ/\n \췣֫!Ʀzl q,WZ _"`Y`"'ڤ$|Xڝgg6.vNsMe_%>xaIr \tǒxTjKy8ڣe"jBkHeiz4ߨϬ^sg~CT!'~@{qrY۫MNIjD姂g\ h:'[hi.ĺֱ{ڙ[[˛`8/(Y& pʦ,/Gg?é(PԶS (q(;/w;UT^WI5ۯ6^ޏ] {e 3BǑ;8hUNi[C*=P|p6,z9BE}w&[ǎ:]%]K:O^S9S I!btE,\Bljq5/Ա /BqUӼ&ĺS[gg7B3='= 1kwS>&'@dzf+([ZU꾝4 bJ$*gRVTWC1{z_`W@J[CBI7ÇMעHXX^0)qc#OcC_4}6cq~o"_ߪQݹv"#JT#s:#'HҠڴh ,ò+2BvȐ=DVi撔SXâvǷbg^Sf'E'V.|+#lG>=AQcjJecҥ`u8yÓ'C~A,J E{9^oL| r~vj0d CWPki4)\ю}¶n(iWgTQҖI[mf0ku>wG)ƳCH$~JY.w=BH%K\սY[~N _Չ*k ">ygdOlF.ac"kv`WZuNAAq}Fg|<z{!ʺnRڑ /ˮ}}feq/̈́9BWS5@"mM?؜l6ŅV8ٴB Cx@v/dX5ZiM׮Մ&aЖ/fu%`DUzۚ\\9c8E ڙS]9ym'?LùO6nIuva>Hy*TvqZ<՚"s|k)BvWO9K )}iԻŗ!ĻYi4>'Pމ +XhJfϴ5/s~ ^y +`궎gsoo ]홀n?Yx\H2GuC<)P!}}s&ma~G"nW)vMyEK[Q0:{p>Q!{4QVGM@a9[8<|Ffg,!7ZSȑr>-._]|Hx `y#9,3O_dhOIb+'5~ט(>]`O߮KE'S3?!C+kcq:1!,n*Ys)Z|AR 29sBqý zOR=#FOT?c'ؾF}-qs8Lɡj"9LW/Roak6- +o+)!̭}2=H$ˬ>otxu=5͔iRJ$y+"ds򻄆K9Sv?c66jYpC5.$澫#g>6~}ձ'P:*@\ɔm}ګE:1~IZbSCVEMZ0࠘%ڶ!Ǿ # XW9ؐ1ϡr-)Lu*ɟ k[uGJ#3SrΜRq*a5yxK%WRZZj/(W g$}(W>T[GjTX1x\[!íSU84UeCWE;[ViuݥBĈ(XbmG֒l*01@r@ .UeA]9굸wy9 +5A/8FTح/<2&r~+ +e)}0ϓq!A&h=:oƨEMtC +ƙ dZ@zJa_aof@1#z8gΦ"DW'} D2;Pӊ;gߊt=oKk賔O`!Ne7T(+0Sd{o}uU>aIB\Nwǽ Sڽ:cx*d}v9HagjG۩tt멁5uAq$߻?$哬Qk"ezoStGlRe?~RL$.C@ [%*9k XMfy8Oo٫"}s5I<@!HHGӌ@4Zg㙣!_j #DL9khow[$w`0~ 4 "7hC.`" ˜ºjX~WC}/cIf_ˤ.@3).wkB^C-5r uMQ,P^ܫM^P8S,C g} \&ren%=5U +1eϊ.tѷ@FZ +hV%ni@6b Pm@)Duj\vBޤ9t"mXݦuSf^J.V.ϢQr{Gd=b,rR<oGڽZtvVr8DĨ+ &#h>e/_a0m={ |EjQ`IX~wT˨oEKHh*c%I}$g"T&ֹ}UhXOu'GfF +qMo3uYliT%Ol7p٤1:r[KVSpA itΖ \Ap +|uc  qT +E +BTw7ݡ:Kv% KR40R3rq0J}KL +1Ճ _VLhl,+Vlh(+LewyjS]cäғ>q!uFbߨ[APHyo~ɇ#&)Is O2r8(0P}޿4+ k K,m{pnɤUݭ]K 'E7*a᳢{xS_wWRciMl_4j9UЖq>ͿkNѱdm4b%P'0r( yendstream endobj 580 0 obj << /Type /Font @@ -7902,14 +7909,14 @@ endobj /FirstChar 46 /LastChar 117 /Widths 973 0 R -/BaseFont /QPXNDT+NimbusSanL-BoldItal +/BaseFont /MLSYYN+NimbusSanL-BoldItal /FontDescriptor 578 0 R >> endobj 578 0 obj << /Ascent 722 /CapHeight 722 /Descent -217 -/FontName /QPXNDT+NimbusSanL-BoldItal +/FontName /MLSYYN+NimbusSanL-BoldItal /ItalicAngle -12 /StemV 145 /XHeight 532 @@ -7929,13 +7936,15 @@ endobj /Filter /FlateDecode >> stream -xRkTSWFa$bׅ cH0]h'pBiП!@"_.@4|*tW1= &0i:.JJ<  (ɈD_C.&!t -` r D"2OC` -FH H%P5B 0p}* ezQqA&E*N0"$P`n^CbdS%"qo L"M#8`0ۑw8,J,Άb&Bs@np,X@\ | Y^D߂6^x ;.$#"TK"~&"Q 'E͂P$@g> O D((+RPLB 'ϕRh0xUI$!l[1E+ސ`2F8ޱP7A r>:xvo2H_,UUVyQ {ělkɰTXȸgsRsL5&o˟ -/.ԵJR\N'mrz鑴e 'hJ|o~Qd?(!,?HǛ05궊fWM݁;&*VA9Jh)чYr=Wغߌ:&}Z8OV]'ƈ? ~$d{kk+5kޛl ]sqgf)t4iS1)2_M휛~ h`]tGo#rdFOz\ 6+$jh֭O,n[&<_Iq:l|0`\D?|b{A)=>8`pB+oЩL:мnNMspھy64oE1ZBm瀢q,3+e\+٦ivS.{gmJ!1ocö~S˖a^փ)kjJҟVײ db7/,Nj@cXF%Ү+u嫋"*(xok{Wi] _|#Ve~]Oѡ14(D6ЦTcӠZtVu=kl뽣Olii?Յn*eB%$RRgA-t$Gc~!tմH I߾9.*uC~݉3(wCYFwf~)M㟖a9Rީ}Q1=r}6+?s9owp_tY|+|ҧ_Z5fDI>8']c׹U_s,s4g _.'孻fnmy/YO:0靥{QYy*'P' vUN"d]@rT@%Ƿ?]SUJOK Xucر 稫afkClBnkH9qR5wߘߣ2? YPɦM]n-,/yIƜߝ_rnM`fo쨺4eAO7Ͷw);yO72|]QBd}!Ly,QxnhDM7sꃖ}3Ғ;{ *,,tt)~ù2#əD'щ} ׎`MS]pqpu|+t/]_ƒ ֫ -j5qum.2?\( #|\Ix -endstream +xRkTSWFa H,A5̯YsΟC!|X"p\n3( 08Wa0vg9$ +Ǥ8L{< |%0(dX! 0Nb1! `!`!" @"$T;X*}JqN_I:B !,"ѷ`nNCAbdS%87&0;q\XJgCIb81\h;!rXd eJt-;6څd8At) 1XgA Qߟv.j +0!&&qN}"] BX`N1b +904?WKu;L" q] d 3\7 aXO:"Dg2 aIsx|tEvUfi==07]qG%'BY,u&;d62V|[T(.~iwUuZiO-k<`WZM ~"%ps]} SanoMXuHcso)=_rh/QN}!}ͨ#JO2ګ9du*g@gKl{DPV칩j .B;i~f<6S"^lιo ڟ +2zK;z;<@Vn1 _aCK>Ѭ.&iGnfWqr=NEg/2w 'F:tםP3ةn +R6,^kVi#Ars@^8| kqwײlS7MV(=س68rcк~SvYN[ +IYY\i|?u~ʷ{Q9^C7R/Qv]{N. +L1ޭ](j_e1[v<~8Ze.6w G8VۜCR {vhZ؞GS{FnqgX cR-:3LOXB,Qu`oA)UI]9J&6T !g5R;Zv#}HNEx싊Yϑ볩^3W}W`![uǓ^jԪ97_V4$@K +c,sŻ?$`Kq5>RGse)xJu7-(%IX6v/嗕W:)zb`gQ䚉*R8+7HJsUoQp=YP0 'ű[7fɟpjx6z.JmV^+4vS=*\7aumz8ݤ +Q %1+LO2|ck;{dGե) ~qHs~iחq"2svї`cԎsC#Z`⭭Sq82-Gh@{H7.3Iq@Nhv+Plmꂋ{iN[ ~R8`VMOkT.E1 LSHjendstream endobj 573 0 obj << /Type /Font @@ -7944,14 +7953,14 @@ endobj /FirstChar 58 /LastChar 60 /Widths 975 0 R -/BaseFont /UTODAR+CMMI10 +/BaseFont /SCUCBC+CMMI10 /FontDescriptor 571 0 R >> endobj 571 0 obj << /Ascent 694 /CapHeight 683 /Descent -194 -/FontName /UTODAR+CMMI10 +/FontName /SCUCBC+CMMI10 /ItalicAngle -14.04 /StemV 72 /XHeight 431 @@ -7978,30 +7987,27 @@ stream xteT6 "!0tw RJ03P ݥtHw]C /Y{Ηsw֬7Cm=^y5H A H4֮]&TRWd -ӋⳲ*AVH0dI A6% $g(Bap=k/o?,wvrœA8P A[mLSPA@p+'PA` @(5<`@@@]6` 3;y7$\m~p)y8$ÐJՉB΍ߙP;O(wKlw0wV A߹A0dy )dgq!w0wؿ>{+O4?k# '[>|A@]n;04)<-Ic"r aUȕ'Ȓ7 `<0r.jɿլJ$6 E t ^"_-ITMz**=K̦u"2pQ)Z+ -i0[h9FF-Oē{-]\VQX3FE=s/u~^/]%vo›$>D_ :9Se{Ҷ4:>\y .F}$ճ*};ev^YtrX'63ћYq{;jv{6^7ښs7Cc'rn_eX*Jy>HCŒQD^)U`qT?=_qvMҪtgC%iYqc1 %_.v˖R"=aH ٵKEPs'/szjq`Fd*0WyT/ۆaӈ EqLWtI0Wpz Q lgr/Mg̅ ky 73_W>*ތ^5JZ+'}h[tb@jI\5#! Y4ȆOX8cbN)?%dy~zv n)X#;YC囂 =:xc봣;umѴg4ƀТL-ʧ/u{oR`fgg̓)b]BI-1 :e1[bf~,iXɨesBVrށf&NeHɯTh-Yj`$Zse6ۉzl -d'P ]L᫯b3" {Ozع~=k²tEra \~ 5|p3v+R%\$\O 8d߱9$)&  5 -`v[wsui˧ȥF;QCuWp5Xu/RՔ8 z'(ڲ ʹPу qç=滛$mҏ4U>bpQmema׶X -ժ<3uNt?*Jc'Ѧkj崓;KS7O0X*!W^|EPJҨ1`@U)Lb9[:Cp":LEq埅|OGM7(XGV -ߜŻ|j3V#51*^ W#.E-g!رAuPJ&^?Bm '@.9nz#Jn= D#<"+ktRRNuxH[ʙ79StڀZ"}]Vچn%g{mkAf 5 {y2>8uSeS0%W$,O׶ vwzt5~(&_=ywu_Ҧ i|@wg׶7!pu3J'ֳUr>חп$ˢ(ϟp&7٭EV8 0IcJ~GǎLYF;܍sЏ*uN=Cp]`mu,غ}$WK~PCqB&k|*^ȥ}XcbB*4RZK+WW$Ɣxg?GoJ)&>Jg&m#pR{bJ0,ze[elBʛ}B֕FҶ#›]W"R@<9tO%cP(Ej. %yXSҽ1n%{CUmi[eoaJvΜסBȪs Kٍ ڇʺr˸ -Z&ƶYcYg|ޙPPcm=U,r,nl_0[G]J`2Ϣ[Ԧ&SBxoLƽҟ[caXŎK^I8"SwM]"m& =2|7M6_SCqhȢ閊S8 ŬFB Yu@MkHmEBY 'z *Tҭ]))~pr ;Spê}h^pkVOunMg ei+c!T&Ev&KJ6Z" RA5^,iϵ3r+#sQ/*[=5? яqz11,m~# ;MJ2բrd {ֻFأ46^>< hFjgvȻB{0(?S? -m*)yhh,:xʯ宒hMТe֙};Vi(7qe6v~$ˊjlܜ>gg)~Mzö/|i>g6&Ai&Ӷ5l(y4~y[rS({c_oF;XKGFp>qљڞ۬ +]&8 A}daWZak7 R՞]ŲLcWu5Ȩ(I9uag<6EqSMLl6`6ю\ZOmoduWI"72F'MQ5$ߨyүKL$sT ;K2aejNāh;!Qrn\",eF׫G=DU.}xeCAc+XqR:UISgzih,"EA;݁(v2eΦ2#0jW$ ׷y)yx)3+sw6k+_ pUK|N_OUmna'1>AݹԮ -Y ):n?ش%rai$*Qg4kVq!QNc%g|:coCkjLW] %Dحu/񩥻fxصL?Nn.2ma.+K')"T͈ VB`Uu<T|H"|(wRYКggZ -hXҙ].Ql'3|44!NtsIl3:qTlWv5IiBXӢ5 JG #c>?Mz`\omz3aWN+\~owM67 r>t7^ GU^3&Xti p%ȶ `U]AꆹnefꇴnB0ّN-`BNN뭅0^Wl':ܧ@G29 -/  -:[i endstream +ӋⳲ*AVH0dI A6% $g(Bap=k/o?,wvrœA8P A[mLSPA@p+'PA` @(5<`@@@]6` 3;y7$\m~p)y8$ÐJՉB΍ߙP;O(wKlw0wV A߹A0dy )dgq!w0wؿ>{+O4?k# '[>|A@]n;0N+3#0(/Tك$oCd ?u}J{B+}BZ`UYlPXiՖ1S90댪~d蛅XALJQ9DjVc%Ck:P{IsI$`M ֏j=Ҟ% f:H(}ϕ n- ##ߖ'Tkɽى.}T.+(w{"X^x˞ƹA:XR/揗7MK"/?2 z=i[A?}m4I=<8}rZu~)θzpcFu+"^]@O-UUݸuX?@ƴl͊~Œ=_R:Aw1_5U{xsp\dç,ׂU}11'[I6ߟP]12TW'Bĺm <}5AM& :16{+~PnGҽEe~dHm|]H.Q.'[bF 2zknAX JH-;ĉ9fGW832d4 ⨡E+z YjJPZ=vmYvho\(SzIVG*gUrs8F2E0ksOsjPEFlaI'ch5o5r̥)', |bNKBBw/"(%i0sju&1oy]ʭmDšL8O&"8Vv~B>ާJcK,׍Y+oQoq]E>vQuL^/[˖n؊L:`Ufl^}6pROK%B_^Mj|A5 :)CSfp'u:I W3kao:YR*Y@9K _e?]8tԢv Tu$Zy HcGt,#TB͹uR ^KL:'刞!.EgݺFl>%]fh!ѵa>v/ FҾZ@ck11!k)-k1mt+WAWÊ)Z`hF޸@$뷡KŝbgpBY)kw˝3m0ȄM1*@C6QYju{j82A޲9.F$&j $Y$!_\6,7Pp|TY|uadGcVf2}cM_ }mѡiUVAf‡dQuO&e !ƉC9_{ V)#~pD`ʶyzZr]Aq#Z\+{cv%+tfpvO\6ViDt9=am E1e!X|rkЪ^2ԇ\"` DmXk7ZWopՑV";:.@t\}g׮4oj@Kyj/ *l_< #,Nv t7ջiY|" ')1H?M`BgV]#U<]1e+w4mv \4J!Fv-ޠB u$HV%kafa?xqֻ *z̫+YudcI#~B7Dh3r6ۀ8)A=1G%ICq6!>_!J#^iܤ<ڼV[hNuw_Vivwq"veYKքqhC\ZunZ[۟9XĚ-JPD“ШUTdu\fr' :G}%nܥL{ wIY.W俽w8vBQ`8܋J ΍uړ{fpǠQqJnR"t9 !Z9=[@*7@YwK w=[2TGζTi6wsx$Fc7!yom7+&XGIȥʠdΎ2n568|l ٓꠎn(ef)L/JMiiL̐v.`fv'`NgJ.kydUʢBCH82V3&qWA\fu!?͇7Yyܵ9ʷyM:xBʃkV~r#m~RKVC1#M5lDF)&8(=H|. ٠7G+3 E){ Hʓ4MX利I>jj`TK= 1 vt ե%(,81siy [o\_b[ߴO 6YKhf%vУD>'Yly4٣MSI,]5"wO.jnWUS3V~\n+];p2s+dX$`OI00X *DD04#cjY˃Ve?.[ GgUHc*<{P +a?_ |nAOÝE& )'6 :v^f&^Bsq*Xդi Əz%*?'ɩR8MsJJä~`"Q<]i,jHkb͈ +xV1%.GZ"҇Nf8|ٜ|ɉ6FqߘJH,0$0fQqj'[}eQ$fc*Eb9ck~;yjٰ`>=h4`DlQs_,0KEԺfb$IL._ +Jgy:ŧ1n"5IW< ^,)ޘD7=!k*6470_|L;g΂l th !_Frd9%FQCae]e\qHXdYY}c[ ,1f3>L(q 1Ҷ?[n xF76G/A-\#.cCeqq0g-jS)!7ifD^˭1gz0\DbG%/ؤ~ELݦ.Do~Նf&e፯)cnGȡ8\4dtK)bVU#!c:5H$vg= +څ?hv*.Ôge?x8{~~k3~~R١`4#G^.s(7IE>CYF(Bj? g/lb=ng%w[R͒fk Nj].^9nDR泌ahWXtԓq}G_kI.FOW⣲cshQZxŴ>L݋j~nCkT֦$9&JCYd~dJMHe&l|~`N 5¹,ISNI )aU>j4/5^:34畱?*D];q@O%k|c) /ɴڙWrZ (UlwM᭞w^8T^O|6Ki lg&NRjQV9GNQgm=]#c IQj/`af5\3eg=^D{[G)6 }t+42|;seE56nNdz?qZ&D_aM׍x3{z[ڠtiBt[q|5ЛbE)jϮBbY1ɫdT^tźt)ZFw&&q y{0GjhG~M-7+$ Xd (Goe *߀[D۶F{7̰Z٘z爈dfjW,kٟvlʼn435ܸO(3>Hڱ\ 5Z&.g"ֿɗ]3a$b~>;u)Ҭ`Mhͳ3-SU,. (gRCƙ >UC 'm9$t68*+b⤴}!Y,iS%# ߌƑOS&W=0FXӷݶz0ȫwd'ڕK.`w7Y};¦T{Ht~l9ER/ӣ*Zux,ܴzd[@au jucݲہJQJCZ7WfzHSU!^JBh+^6rS| #\? dGB&endstream endobj 570 0 obj << /Type /Font @@ -8010,14 +8016,14 @@ endobj /FirstChar 48 /LastChar 58 /Widths 976 0 R -/BaseFont /SJUURH+NimbusRomNo9L-Regu +/BaseFont /CUWMQS+NimbusRomNo9L-Regu /FontDescriptor 568 0 R >> endobj 568 0 obj << /Ascent 678 /CapHeight 651 /Descent -216 -/FontName /SJUURH+NimbusRomNo9L-Regu +/FontName /CUWMQS+NimbusRomNo9L-Regu /ItalicAngle 0 /StemV 85 /XHeight 450 @@ -8033,19 +8039,17 @@ endobj /Length1 807 /Length2 1423 /Length3 532 -/Length 2004 +/Length 2003 /Filter /FlateDecode >> stream -xR{8Tf4KSYSH̸Jn2!i. 1ki\Kl5(%ݙ] j樘9ж<9笵|~>3Z2`HY\K p' x`ǻLL9 ,*t! suF0;Ep3$5@t* Q1`ՖGӯzQtN|Uo$[ VAod;EMmd\ۜ=ZEG _z\d\׾+%yoܱc|Pxc{GٮBEG!%1 --8oƱwvtًӉ[nc3vwb^BYQѸBaG0dzMT\,v8>1p+yaeB*'3+K.?>eT[[ǽ cZ`jʳ]w*f7V6fqWTj{30|=W"|< H3\iPjuX_B[+Tu⅂ڕ+灃mXXImY ]}L\ ,BwͨͶ[M}28bקewF>wnY֬QSm+OE}o]߾zW7]Vv\{Nyku,2n t`('0nk}.mm:u6=7<3𘳏]S.\9G:_\UdrSdֺ0Fugq#0Vk(FxqzלRaRUB_GiGLd[gg0%1|!;u+~?1ۖ07sbGm!iloǴ y}I'Xw9Y=jliG@y:SsYi;Y/RޣI'\yh>uݎzwtT|$mmo]7PawN 6x-dߗD՝@94l1sШ@ê;=_jvcnϪX R eWM>)3)ZߩG618`DU,~M3| - j\G;QUP,qJ(?|+Dͷ$XwVxĝ RFN 4d|NvNv(s(>`~Ƃ\Ne$*? +E4T!oXy~ <+V(`@t>@#!6 +7oɋ̈́E!|n A.1-\ &00@& + #ʼn˗;/?_X'   .z# Hu׋OeAtWv$ #B"Q 8f|mInӋb8Ӆ?b9_T 5_5ax$^BDϫ`aĎ*KG!DEa#[$$ sQ8 Y ?ZD  0K#<0Npknn(ڎ ?8;&."' !Ƀ ӝӢMU++E6ޫ+R(*C>TKeJ2ýr}ޡ};'R> $ !o%a44=~mpNU>LgWefGUh6;%Mmdta\UmF^t~*-Ϧ6ևrҼ]uj m/u#.+d5.~%ZDpU]^%=I=LpbCk[w3۟O5YfUƀmyLeܵ>T m =I O sMFJl&UPKhd? +GK0%>d gu[vtpW&I;k&ZRV MSREi^.e%(tDjPz~VRC,ʮ4Kkڶu%&8U;v o(ٽRXV]z4b<\4mˍf\lg7~r(خ~msnS̊+;#W; =}@rŖ(MB)e,>QqDl^n\wB>8qc'Z]]ݝwXnIFg::yf#/g'ʬO;:ئfLa]zMߋ&$@ /_dR3lB֡9#Vlv +F W&Qh-ʴu*Mfսw~~2q-ԷѵQm 7za% +17+M֙eݚ:[اZV8ڈ߈}#k<%@kvisEHD00%PN`f݌|.@C6ǺiW|n~zyXԹ.Ӊ.Kw/[C:_\ޕorCbּ Jvgi=0ZР•1^s"KKgv̝ޖ1$t Ē#LvMcͺ^?Js0+\X;Mq60cRم=,jIP >ov8lYv@y2KsoyI;/kZM<|żrgtT|$jmS3PtdgOmj# /Kn9\`lU+u?Qkq4RlAH;=&IaJr'w76lPwY'ODQ'cstMF3j=cΧHA~BM'l$e;Nvڿ\Δ2Od̥\')б@KS^Uc'!t53}& h>* | a_M{"^wb꒬a#-ې}$Nk޷&<(̙ : rp,gendstream endobj 567 0 obj << /Type /Font @@ -8054,14 +8058,14 @@ endobj /FirstChar 40 /LastChar 61 /Widths 978 0 R -/BaseFont /RLRNPR+CMR10 +/BaseFont /GIRGPX+CMR10 /FontDescriptor 565 0 R >> endobj 565 0 obj << /Ascent 694 /CapHeight 683 /Descent -194 -/FontName /RLRNPR+CMR10 +/FontName /GIRGPX+CMR10 /ItalicAngle 0 /StemV 69 /XHeight 431 @@ -8081,48 +8085,35 @@ endobj /Length1 1647 /Length2 7179 /Length3 532 -/Length 8042 -/Filter /FlateDecode ->> -stream -xweTݶ.w)Pܵ^HH@w8N)Z@ѓ;{3{ϟs;nHƻ33\Zseeí!*pG_uvsՃ;j%4x njಲ*@(D@$0@  -$$$pYp'/ag/o?d+`C>CNI?ԇ@;(j똨i8T لЀ 0W'pka`\y\ " oqq"PW @@n 6?9H IwE\N2_u"쀈߹]HAz -4H\'w.k uurz!s#ɜ\pslU7b t;@\]4H߻>{ןhEBlxq9Adn[( yQnN!.6Da^0O @pTo"E\};y3Y6@@Gwoc_U'Rl -e@=!`(d: 78@a7 -VC/n:{jb fL?:S0r3&o*'G@T#(Ə(!(IH_kM  0 o40#00 3 c@ 4$2-3QCUɬ]7̩]~`s@ZDMuoð]ԮS!yt~̜$ĸ6, c}&5ME6VY`>nr> dv$c9w"#@܀BZSǖ}q=c+'U-&9V԰CMቌ^ytᎴ_-(%KmR$4f)*;H:ъ͖"ܟӾ_>yp5r-П.q,5 H8e> ($Oќa06o,Ϸ3Co鑳UG=! -)2*:^\ӠE 1+mJPrƴ1l'g.:FGBFLL^؞uD=ĦJ5 L>Ȏٗ)eR e]@:χ'h> -eWCo{pI3Qu@;}vSܜ&;;#(4=}O0fִ?rPӟcl`Ϩ?/r>XygK &ϴPšnPF"/=#œ04X$-sqڝē[ݿ)v:9< W]'8ؑ%\lёJ 5}dLnM -hoxa HiȼLT&C'yA~* V:d:7Qw(Ve&3{2U\@˙YK~72)/n%G>[*9؟DSlbHIV>FEy//i&T#m{v{ٽ\-h%Ʃk!H4M>ʎȬXr\[ veP YcY^E"gV;(UsBo[?y׷N8 -*)׫5OBrd=jr xfӤ4xms$ec;븞֡/%Tې[TwCkDr.೥gt$91۝3_Zp$5-3 ҙ7"ޕێv/ћz8=tj/ׁIQXx4ũ@4'ti3G}!EICzJ/o1wRb50Mc♳2a2||/f/vb} -W-VEqTaWWU\+^:*k҈PԔ&k&;ݬPk^|LjYOw OkӬ{Ԫ?&¬8x b={4NeEj(RQ myLVozL3Ҍ.BFjOLzCϷB>* JGL\MK{ 5Tgi:Oz뎇Z{4TkJd~^O;HN -űe=)(Q+JGs2Ao rbTQ#¦ash-OsCqZ$?e_5ᆵ^x1w~*wPSsx2e&L ; ^2s%h={%h3mK.jԩ)Y`"6 -xy[Vqe,j:Pw*0e .1|@NF#nuH -~*xppqX-DAmpk)4ql5DXx0ƘϘbx2kcT\,aZcėZ8N_fʲ -D_0,e+<,;y!FkdH&>A=#6]+[>}#vFKa-cN5AJ+*y&k$/)%e:CI}_WIDV6ގ>Kz#^iLxP3]_YRm~MM9\\{B9h/t>,yI79]MkFf|缜Żh家G.^QhKWVޢ,O rw8[Kٌ<~d)t%4ڑM\:Qvн -WA\?ebt^DO[t y%gBrB̓|X,ˉa41Ĵ\4Zj"6u8'2$JWsf|4 Ca5B rRY(E>HJȜjp"j\{$#K؃nKNV -)1d&8ic|*Fə'˶MٍhjۤE[E~_fQ?JAU6K Z!"qלj{q'E1zsYd7Gha {a5zeD؏d؛:Bޏ²Y{('?TQkL/+$~ #{kLN*C5,T$cC-lCjh2,}m _ܡǑ7{Yl)Ky'z21θfNJ7hZUcjMs<3LHs,֊o;ZK)KkshWϽG]vIQȻ>u]R,Vոǧ͒ĨW -G{䗓Ӎ6b_1k'J`eqEێu]*-"aRrVtOt^#\(o]bFtE@-!?-w -w86-#pZִ9%3Aե%93*چ>oANDpA9\EHՅ{6vkKCćڒm - 珟ioY\Ldw=s/*65R1dJ40(h Z ՏsĎxXaRpQDܙ#Y}Y*<2#m$}8p{4 ,yTEHt?;Ξwru},y6Q[ik$?SAVkSX9اgNx흝YE;Սh0L5T򖦕ĠV8Ҫs-%J篨j"v TTљf6[AM>& _\zfM΅No" -Ȋ~ Zwlmپ,"Ʃ&>f~]X\bh6@Cu_ĥvi -a" $W*Bҋmf+#*y޳M],{3pCċR[6wߪ`ۘël~c,z)8D -s('3o~Iw -K[~QV=f>IuTSfuB1,aH9ocYĽ E 3tw~% [x%JG3(_Hkz{Պ#$o :F_$'"8 ȵ:l=,*x>h|Tv -|ueVKS,OEX@}ȼڷ44lVt%Ӈㆮz訏 >❤2a^&f/Ԡl- 4*/\OEb0k]2Rj_jQ?ٵ"ŏpaʨBxxׅZ#gbuX%!9_],;J-#\RY{_?ڈms"1Jz;isBHFwDxfDFυ|&?,KJG4e&6x4˺$XQNO$d);["^v!Y;z]X!32 ԋZLeGZI .}Kz"F-*Oɋjtzܔ;"U>箥 `AӁK~HS -J$pdзKu\Lm -5m4?|Q/}Tb\b -kse/р$`xqHbq:C`%㝡V~tyO7ň?; dxD͏U2[#%b~FOnnwxM 7.kyΜ9+siys)AKeXPMo]@r%:.'fx"xF'YMB0wJ}}1TeBc=-'/E{ϗbg$HZu2 ~gŔê?ј -[]kOx?۟}EQ7N;,D[,l y^a!T>"f0wngb)ٹwM[k }vA$EjꉣLZ+7.Lɦ'b΋Ρ?mM 8O2@`vtrҙjg(ݼbG9ڱ/7{ЪO"aꄆȜܵ>L 1yVnãڒxRi -Y oӁ쵛Fl#X/m/`y{缵FV'jhM@u:;gK)\$ ܘѵSx?_wȲd{O U˄ܕ.&yp?>ɍxB~q~mm :V#z-rb[f׵B ĉ6hE*'9C2;03U%$j Q -?yȳry$.Xpk!`mc)Xq%w`EOZ<ӒtjJ9㥽سϊz ,@#S<tK~. 8vRf23?,^C 0"7RI S1W\!JKG'^27g!\]"ɩ{8Z|q@ [FEC)HK6x9Ec(TW{2okI#P]C‘?=f~Mb59X7|zl^{->|7w+a"Gscӭ,@XW~`x `E}%3=,1_#Zh^F!?FZ_qZǩM] lR#La`V4{./Y'&7V7a>\ITk[YqHtxC)i O퉶~ܨk.U:wSۭzވ^x5Xd+N]KW=X}Q>W m/:MDat өu),3OOGW!&U,4G$ꊨ&行rI> h{pq"+sn35*h1z װGѐ3g߳=3 ܘw<5/RjX-O0 CR6cB> +stream +xweTݶ.w)Pܵ"!  ][(BwJq"{{q3F2599z֚#/;"a UC|B UDHiCm4  +ggWv0\JL + IIIN^.0[;$H߄_.k HW-zp: p$hvP  +P5ԁFu(jBhP+`p8pwk(.EWPaPO07 p8\]Q+G`7Pvğ\(G"E"].0'$UWE:v ܮ0 @ؠ!1~0W5' C6 !PjAᐿOZ@#-]=fqE +L.~S))!<>|BR>a AeD]G)aQK?DBZk.0O VQ CPG0i? +g`iܞ*fmB=aNo"ʭo{M8ݬ=yF9zݞOUg=X(}$pBk󙸠W=}kC".܁lgNuqHk +vv98{{?a˸cq:?3*yu_[|h{p?73/r-6H8a݇GRI{c8GS>p ]oF޲ç}OCStx,E: +bR[U`$5i7NO"\\KuyEbpp]ӫzM3>5L1 HꞴώۓ+gV ߙG;υ'h?SŴoxv2c'$5ˈdfwR^b'Lxġ =t/kィ: Nɼ&*t:'Yw(Vc&7γweΙЙP{##c{<^}5H%6D1%$y }\> CO7S\D7#<;U,+J'J||Y9﷨VחAtT-Ϭ67q$փS<焞>o)EbI%7Mcdnd\H)z呕 +VKI g +[InGvWq-_JE>#i7!7qWokC{<WhI"#\|NHM>7IfȭmI  +@$=Oێ)\XֿǗ!rF;A2_7]z +. noȊ; cDA"9Ey_^&USrݫxP#2" gvJ#GP xtCGCy'::?=9X+06:׬eN& Ѩ@ ?"o\5}evR0@ +.ɀQ`SJZzkz2 3dc +9m+y IX?߈#?#X 2@/1~a6/5P*Md=;lP |V(ycF!?Y =.G/uDIV&Q6*Ӟ%}SOu&|n ¥cd? {01y0c]<}"vɸ(2+9,6aR$-DdPɜ'̜P'KaCݨ0am tNz  QI@u ! Wlƫϛ߲2H+#gЋwxAg')1Ճ{ JtSQK bdS%7Ud0'p5ɒDZ?c>HIKd#T1rQ`&ˇ2] xA(30Ȕ4 ?gZTս_6]3>Ѡu}fFlr5/'0ӹ^='v}aGjTJџ/ (MH_hRJi=_I$V6& EӒ.J2`Sy9 Ѫ\Zн0/*Fn+qW,00F2mx[>+sXAkrC귾>v+Ai7o yM?=m11= ?&v3(؊4s-%Ɔu嚛@ӊriI8<4u7xˑ_ښ XE$Ƈ|dJ#~%S;զDʽ("M6)G`-T2.)Lτ+FԌΓ3͏_}o:伋%ہQֶ u6*+͠)L %3j 'pd3uLB=Cv.qck*粆"n1ΘBwôj6Ft_ Ipap6uxesz(c&?TSmg{H/+"xcNz'}*siny5aG4B@е nt"ݞH m U#}$w\Lv7 U 6h9 +~b%&;0 .0QҶ(tJxRA+`sQ>ocZT5W.ngMLYC3f`g!ia$1*̧‘nťtؗ,ژl?\1"~8G].7 .1i%9Bb>J)O{++흹zʈN(LFЧ_艷br=df(a$dRetN6GS)Aw]緍T7w_/>S#': Fa({ٝO܋+$79FܯSs8/"[O.ξQ(sѕ5K=O>qd"cdfl~k?|Wט Zd͟(Lŷ)!s 'W 8u<|eV@♖ڣ 9a|~އ/L4jS&;.Dlش?jʗƪ(WgIpR-rm] *-$linJos5I=nYFI8'JF3=pՇm&.7%'z6(tYR )3gQڀGu&D.'K^sJϞWk:(3~bȬT+`}e~L_U҇1Kf'S7ctm`kX~=K' ۪ONHN-R ~Z;?韶铋|FY ЏfiŽ/UG8%/NS잫^`Sa3}% +85Jms^rKgh~+Vlq>~ ݇- Dzi8f7X\b\nC:Rmò_96lY)_S2JR~S^Ч?P)&/W/@MlhDG:@&Y)u`:v{Sߞu7E66<r#1876>}_G_!'k.lOyHc]&=KW䅯Ǥ`BfRG:f N->8B; + +?ҔZ 8C(6ENɊ2;w{o57dmt9xdJТi~%zKuVhnO ~j:mhciހ?ӞeyV垙E)x(O󝩚}04+q;QE?*&WRk:P5zKjdA/ю~: ܚ' Ti' f]`lSȶai <+|=FV) m=%ETα8侓?L0XMݧvD@s:D1В5D[i#C=eGWZjJΎ}?%A˦vB5V!!!MEqjvXl%23C=Ċy+ o2%ZL_ڇvZ&){#,Sp/OwJL&QRj|e\I1g<ttܦ0bJkVn+ \B*p\5v+3{ھ`]*\7 +tKjFax ?s/6;WEO7cSRo&`rNozo~i@5g`f\ yUl0Qv[}D Ĉ,ݵX}yXX* sa6EGeΜnRkCG5x݈5 A:P01Ǹk'6FʳIӠ}.\x"[X-?Zkv]-b@NaQ$xVx;$po*$Ku~krhV?-#|lw܇zOqovSч^=ԟZ$y ZgO!xVrεR1?]x{YyJg QxxOG_J`kv5XF[U_}*K`ߠsN]GXb5>4@(v.`oLL6Yn + q=' zDdKk68\ʳuk"DMKPz-aU~ХG^qJnsMCFP\q Vn:C+UXp8U'wپtF"x|Q +;N"3MWQeQS B߾H/&}_rxv{XϒӉ$/SkFYw.KViɵXuelC_bU3WE "ЭȫRTlO*1ϾF[ָqmyeV\645{K>sE?x"o^n +Z|`/31mǸRyPd#gHACR$fsfDJK oT֗ 0/P~$5d);S݇^0ira45/igSu`MTntխyjW$ ;@A.H#?S^_endstream endobj 564 0 obj << /Type /Font @@ -8131,14 +8122,14 @@ endobj /FirstChar 97 /LastChar 120 /Widths 979 0 R -/BaseFont /HYTAIZ+NimbusRomNo9L-ReguItal +/BaseFont /LNULPQ+NimbusRomNo9L-ReguItal /FontDescriptor 562 0 R >> endobj 562 0 obj << /Ascent 668 /CapHeight 668 /Descent -193 -/FontName /HYTAIZ+NimbusRomNo9L-ReguItal +/FontName /LNULPQ+NimbusRomNo9L-ReguItal /ItalicAngle -15.5 /StemV 78 /XHeight 441 @@ -8158,7 +8149,7 @@ endobj /Filter /FlateDecode >> stream -xzUX]ݲ%$la]o`.@ps=}O~zXs֨U5fͷEE$bfosabe&ΪvL* Wc;aDEvGwP d7vyQt(;؀V /} d/@ lkPlv-E 2S9ۻ:y1{O' V]E_V?8la~_lN!9n寶..,,Ơw9ȅX ;31{ۿO2}o̓?ihmgn!s홹:ہ]A2nBy#ajWj5O _fc;3_o{3lz y;.N _;$VV`x?A+8=@f x]`QPVgO;-+7Ogo=Vec +xzUX]ݲ%$la]o`.@ps=}O~zXs֨U5fͷEE$bfosabe&ΪvL* Wc;aDEvGwP d7vyQt(;؀V /} d/@ lkPlv-E 2S9ۻ:y1{O' V]E_V?8la~_lN!9n寶..,,Ơw9ȅX ;31{ۿO2}o̓?ihmgn!s홹:ہ]A2nBy#ajWj5O _fc;3_o{3lz y;.N _;$VV`x?A+8=@f x]`RQSdO;-+7Ogo=Vec =-k϶@N {_l k z!jc23@*6/eG-?& #Y2SZcv)l 늿pf 69;ߒJؙڛ,.#jd߆`SW'w>%@ SK|!V!"L{wobm w?r+OX @@ -8196,7 +8187,7 @@ A{O =1AO7XFqo?rX&,Mw>1y7t L9mM|8\*7DyCyNw}lMNT/WzL}NGW>ijFsfv^ip"iRe|'VAl/-~Ui4}@+4&Z#P0(ss# ©}:˦mnZte"O%pXtT}tЅ9 ğ_zX>2%Q#'Kwd#92骾v\OɠlJJ;fb`fX$c]4;ܶ}Ă#%"_1cy0~:qԔ,w ƒz-"r\OSj?2$[ĂC¾BD/ "DpwVn@ 3eu㚦Bz+F'6Ϊtb.5p^ZZSFY*9srhⰛ,@P G?nejo7AALNn!x ֨etJ:*z+BSQTPؘ|TwdҏG<N[)uZH -)h 4+Ƨ,ru3N[n a>t}̳cOhhN!́P נvHUNj[S8Ye[B:sE'sR2A5=8+Y nFZjezr ͔ -ssFIA)w iUk~e0ԇ}ѱ=X_Dz%-?TL2LV%HYB4{Ӡ^1cZ%> ]QY  R{dsae"xpnvZ:4U1@\;: *7_{eH󼔹mR$R]<#qa ;[ H+zS1cF: QslBwEgjuQ )ʔVVY}IzTxruBB28D`tU֙9#Ya?&IZl=֘>'᝝` hl%2l/w;A.wAxlBةX FO:3\nu嗻3|5U8Z-m{r+))Qr _ZPo^\[2L.0W)d8\1]&Mq浥t?cmZvr5B ]QY  R{dsae"xpnvZ:4U1@\;: *7_{eH󼔹mR$R]<#qa ;[ H+zS1cF: QslBwEgjuQ )ʔVVY}IzTxruBB28D`tU֙9#Ya?&IZl=֘>'᝝` hl%2l/w;A.wAxlBةX FO:3\nu嗻3|5U8Z-m{r+))Qr _ZPo^\[2L.0W)d8\1]&Mq浥t?cmZvr5B> endobj 257 0 obj << /Ascent 712 /CapHeight 712 /Descent -213 -/FontName /MUYUAL+NimbusSanL-ReguItal +/FontName /HGRPCN+NimbusSanL-ReguItal /ItalicAngle -12 /StemV 88 /XHeight 523 @@ -8232,10 +8223,14 @@ endobj /Filter /FlateDecode >> stream -xRXuO{H~q-bATPEvn0 \,G QI@āD@G{?}}ޗaH R WDq!(rRK$0H,"1(&q 0{$2-N(B9ZhB 1 Lzqڈc @*ZB( ~cݳ(091Ԙ8PJ QÛ4PD;~ȥ-1?ePZi 0&SWOq0hg0@eZ/W$}a±pA -!'RX#cb=u($i=ŬK4a!,}}HFj-M#f{Al$I0 H 7* -HaKkM2PQ4gpj ҠD? i AJv8'8*ɦsz`~/)[$~Nb(9"jidNuY"؍ G9-)tnpZGR>&dhrw5cZQ~ 7aRtN׮Эku*8*'MT-I5;ns%5o(osǫjxo֎݃]):t=fL|6…kn8-uh !K¹̙ cw>;'Velh\%;t#a2z[ƌ-bSofʫI'tܳ,Fsפf->2O)jg.<0ӔH|ށn'Y{+dʏoZjƜ;`tQrCE_-kBn S[/i_뚿ay% e9ٞuLӼ˕ذQzGD4KĶ^ FyWfΫJۖw\ƽW=5|GiAbfy*\0B|VazTߓѽœ6V=M{2b;^(3L^[Kn?jRܭ۝M矚LLĸvƾ?(5F0bΤTJ^ L4\=XW5`Zŋ.I¾hbCQeWzNڕN;WMFݙQ.nl%촧Jx߻X=wB'#.f^V˼w?>97$Iasԑm^>s2`ŋ!{=^y[>ܻnoTB?>r+QcQ6[XMWqvNp5lB~Zyu!s(.Rlk;Z.?q '^X4[_9M,8Ĺ :|% . */;*&6#K7 VL_G+< -3;G$D1`%&糜R?˦~e uiN`yץ4tWxrr߉D[þ.j غ I"Ҫ}l +ÇDT#4Ci:Vc3endstream +xRXuO{$DE +cnKP(6Ny 䇆I0 $dQ<=Z M2EāQTP }?y_{KQJ<"/XKA\,8|~# AK,@fPX >tfP1`fAȴ8M k( + +%p,2D VAi# 80 0eW$G8(TQ@ g)#NYQ`&+r`%b1 Wq; g76h4vK#ZBc~ʠ:@Na8Maφ2@eZ/W$}0a±HA +!'RXDx>P2!HfY/P .ф D};lXRA 49$ 1pX( )-5@EќB@%H~P1٣*̟㨄'~fiAS$/o :aŢ爨q:=g`7&崜9vV[TTKk˯8|L` +ў%jzn|E]-[TVIqtNZp^5;vsƵК?1YZM_͖{W`Wco?7fGv-;p.7NcKy|}BXh$W9A5gĪ KdGt$L#V2p˘sTQlL|B=qRػ!b4X[}MavCnaSj/>3'J?bendstream endobj 221 0 obj << /Type /Font @@ -8244,14 +8239,14 @@ endobj /FirstChar 0 /LastChar 48 /Widths 982 0 R -/BaseFont /TYZZHP+CMSY10 +/BaseFont /QDFICO+CMSY10 /FontDescriptor 219 0 R >> endobj 219 0 obj << /Ascent 750 /CapHeight 683 /Descent -194 -/FontName /TYZZHP+CMSY10 +/FontName /QDFICO+CMSY10 /ItalicAngle -14.035 /StemV 85 /XHeight 431 @@ -8275,7 +8270,7 @@ endobj /Filter /FlateDecode >> stream -x{Ux]RK-fffbfffffbf`l1zܙ;si۪:'#+23NOMA l`pwa`ad(Xٙ:1-\jV. \ o 2Xyy9X(J@ $`jwQuut\A@g^*@deaVWѤW` tPYmBhi\%scq3+P[8219.L47u/Ĭ@@?Cy2n667HfLVN@iJBW`feaf@SKJy:67vtp:}́n@ }02u-ÿ<̌,&Ee)IY""(X 򇑇?t[Td#A i_u9σGc{ W[ۿBw9pRvV <.ƶVYhdbjwCe}@%gd ˿ajV6@g?g7hoo%M̬-.\i 2g/#ϻ؛[i"8X7t?53β q?v%aGgT$d/NSӅK ra ŀ$`lWErg[MfKmxPixʸ98&UƫEb"( i-}߳\T5gLY[Q Gh*Ga'fZHcYEzR3,I5ɋO_ )ϻ@ny+N>٩9'BYtɸ6C2I@(#/r<=?^Aw@s*0B8JꪋXDQv{SZrRo=;g57zgÏ"YPK@~Y/IyY6T$(np)/UDq_>M_\Q wZ&gZcX]\SR -ٻ\"g_'߆ .$&D _|grF\蛧z'8'ԐvY8r6ӻo6Dr*MhBՐˆ6'Լg4ImZh;AƣiFC:>cHX&d"%r2Jy k[hs$XǂAh(WHnrWܵۋ_^kWƻ3v_lT׬b9*LuS&Sfwx fϡ GtY!q >kLswϢWxnA9UB; r1=8 j2/7k!,"7"hwM ސ5T {|0hJAk@T^y)˫~\O;ƂG "5Jhǒ O[Q7\{xK7 M1j?K3Qk2L(G*6 {S+4CU %DS~*bݾv)\[7pjF3ZVNNeX3Ƨ|/>$zj:jq +8FXǼᅦ5E%'!CgfYKe/x[,GF}=DTodS'aS4\i @@ -8318,7 +8313,7 @@ D6 zrM7'c[L!?%M8gq3HhHJФe#/kv@갆4~IkG?rJeDP%P Q1RÔKe?ftR ϻ;oN/]tG;'C+~+|aYR ݺ.xWu2lI?J%8?/"+qQx }ʚe 9icA^@;Yw a2HPo+a P_M<ٞ0O8vr&D<;MECӖcT٨3Dg[wDoo/JBd>uHP PZ&8Y@dcQ  Xd'$Z*L qwb49R Nw=|AٞAfjX>:%w+KnszbM}Yr!b4cXDc9PfWؤ2ڟb_'J,Α7B⣍sqOi_/+gU.֔9/;rSL=wlf5DJJEwɖ=$0BH}? pR&S~BT։o:B&tO&X˸ OXF Mtn}y/$!Zrq8&' _xy׊1Kwoh(Kf*mf:QzNm̉)nreK25 jcsZmX_mVqvo{`Ç-\ N0.Z\4lFaU50{1|Iw1٬ w^kZslg'U8S>*rkA!ӤV]eAy'#>>۴g&UKYHԮB3ٚ~bC'M)}~5߰==_H{Sݶ)cQle~(׶M1&AB<PGRôO$3WO۔uj9&M[t/H>DZ87ԏ) .˭8ROzCoߛ@w9؈LDce(qʽiq_JY -vC{LA]eڊ |>y{ ${ZW:wMs_|zzjC&+\oy+&Nt 旳 o<*i5iR/]o0/ #ci Ld\Ҵߊ~m0=b>`=$d+"@҆}7mazU3?HĹ3i`'D|0|C,˳fOl2{0`4/)@Rba˥˷ ဥ1#+i):}W'?㷜 M0ugSAJ|ۻZ|EQxJY;ER7S `XOގP҂T///O-`g A]@ gendstream +vC{LA]eڊ |>y{ ${ZW:wMs_|zzjC&+\oy+&Nt 旳 o<*i5iR/]o0/ #ci Ld\Ҵߊ~m0=b>`=$d+"@҆}7mazU3?HĹ3i`'D|0|C,˳fOl2{0`4/)@Rba˥˷ ဥ1#+i):}W'?㷜 M0ugSAJ|ۻZ|EQxJY;ER7S `XOގP҂T///O-`g A]@ endstream endobj 209 0 obj << /Type /Font @@ -8327,14 +8322,14 @@ endobj /FirstChar 2 /LastChar 252 /Widths 983 0 R -/BaseFont /OZQNHG+NimbusSanL-Regu +/BaseFont /EJFWLR+NimbusSanL-Regu /FontDescriptor 207 0 R >> endobj 207 0 obj << /Ascent 712 /CapHeight 712 /Descent -213 -/FontName /OZQNHG+NimbusSanL-Regu +/FontName /EJFWLR+NimbusSanL-Regu /ItalicAngle 0 /StemV 85 /XHeight 523 @@ -8358,54 +8353,63 @@ x -: S$ @Hٻ9- *+`-dmgou|oT -(`QTȀlA@k5lfv;[S_AX߰ b2 ؃l7 ;mfhۚX;Eof7!{ bwUUOG _!0-鯖E`[W-c ~wM 5'9a5 O>mwp;B@f(o5MjmQZY[3;?Ns9= v ` 2CaSs|+ `'+?_5OzZZhx`o/ mnE&juAM -vV8i+T hb0Zo)l z1X8xx%f6k@My)hh+)3kwқjno;0sxpqX.;@[뿨7?m4;߭Hؙٚ'@[ӷ_a'7Eo-@ 9;˟)Iݝ5j>v?o=W֎ ir=ٖc$HfzQ3vecҵ1'i{|^eUV1F or@:cvfXߊU SsxDwK;4qߵMœL+ N5DDG#8#<3KkuႠn \SlqTwd|ϋ;x)/мDoDI}m6CۏnYS߫oG~Wr<J/JGhN>jJX#1vY/90dsCxy z7걣;ڧa{!|Vi UU-WWs[< ->#ǒǔ`*Ƽr" - -flu !{'dfZAatoxDH[ -"NJl^0huÛ"dss,><f\i.ϙ{j4k%6OhlO.~v.P΍:1c\"waJz?/&'}-D"|l(kQsa)ħd#B^%Eɐ0A(9PrJrg6(KAx@8Y̎pX*](a;i^l+E"9|^KKF/=˳O.kB)55&_b ->rmqSHCXd&4a>dvave6=ua(PvW@q "o?cQ|^^l]{\9;~*\zoOV|8ep*ɳ>~94~m*}JfC<:]fA,'/ [̴Cke -lR-yu }PNTcluC_V.T&S~.G7ؔvђOdXWI9:/E}x?۬=7MJTT2&U!N.DjOme\ӢPq*sѦHGտ|be9o47RT -_HJd*ḄپjoLX-)}FN)4M0Z[("@@h6*l.۸bz)xAZ-NM>G/"5f7A]0͈]59rO*"uٟ˦N\m-OJy,tV1oܽ=?"ezUW*>oҺ*:r<zLdg9(xT| GD@*| g\L,7N\6PK 5d6)F>..N"Hv9,tJ\MR{>c֪ r]a?COVIEgF.JpSd^D<@MŊ[6n[O^E~iO a_%/ [_:_ÎzLk*G2Wʊ{:?< / t'3gڠ ѺU/&>\QƭT%D;OD3.7k*^"_ORnIk| x &d>|R^O$7O~>˗vz0Jl5SV^|()͟X_ :?-]AQ{05ȉ|ֳ>!n`p骪sZ(5B z?bw؄MHҮ.N |xe T_Fuya͓ͥ; ~͋WNQ]%j_Sxnջ4M|~Y LJ#~A Y*oٸVʣ@f9b}S+"k>v pripE G5 q<Ƭl5L"R?X -*c_Lê-ORdrKwli[EOo| O`Taȅч 3osx%/^NsH`}¸q~ hxyFcGϝ:2Lwu]fvdIf3x]$e}P,BO~ l_e2^Uy^ndע /Sm87RsΦf/kaQ` -zXԉkVܣ'qc|ǿ>Bcdov^0u[N,* RjP (:+LPxE ^{oJ@bcH:!Pi=7퀢Y7蝫k~sShjlg!tauƮCJRxZRy0v?)qOƯ΂wGnU]k>:#EdڮDܥȈp41vZ_W(z፵;Tu^Ng΄JaJ6zV%+!5Y^cEΖJ~xw^ (.MvQ*3ګPLNs3#\? Y#n\CW"tRTdTԱ3d9zuԆ\f>⇯_b؇cwes[OrW;~[H* -o8JW/A"!2fK?G9Wh5ߪ̍1[1 '[1JrОnBl'E]4 ǓKvgUB+4S5TIh؁޻ׅvCM<2~?5"ɞ\(9TITx-\! -3K]~+?s^hdu]hQnaw֗wl3ii@ChTtm7BʟJ kBH.:bg0@k -N%#f5U:6+^ܲsL4g-Fkc/-d;re/ "K'$/ hǑrS}+WԶZi˺c%H#rkn Qw*jn%MXݿ & -+VSL$?FWEqm[R7$`WHsOn4`齺 9)[VDEhQ~>~=5Ж)r-xpCX7"[.,u&M+q0O[RBeB:U`I!H0=U{zq,̛әUSN D+eP\ޫxi7ύ.B>ؠwmٗG9zxsTh ʈ7rH3;z#xReSZc =a{0u.숓SǗϚj'y3:2`rqC]Ƭ~8W8 -$&ͮ|4Wܗ0X㆖^|blqA+WĴ,$f&b0fw-_ravne5 z kkσ&(1ZDq3. _tR&4:|g`c239|gM|3#I 309R5Z=4`]YjgGyR% !q3ܔg؎R͊q$}B҆iJ ex@7Z/]\W-DY$3S.+3>L\:Cwq*:HmM -ÜsyjMQAƲDDe }[1Q+2i/5Ƞ!B8ebJ%=g_˃8,[SX<`-W_<;>>YRe<}5EQRM`씌 4Y=R{8Y^}'դXU?Nƃ9t' -rXgWpvo0vT4Ӛ c1KwwФļMNE"Zז|>#My쾋CqCsg"F.NM -,r:\}vqWp|Ul -(Þp&*jvÙy5"dZc$?gAifj'<:*RtLj0ϋ -LLP<346GewK?R6X֗H^^k3eir>eۙMvdwen=ƽgqᢚWEV"ʀo~ġ7UL<^*b ,ls۫:@Bf]-T}FdzEq@/pdDs:e:9*вجP̗g"#Zp:6=IJSńa~K<6g\V;$xIƎ)#aEgSSI]՗CY+"uUc2]6)H9*1)㪿w & Om!=R;=AM}/a/\g4(܌᡼?d*W+XM@X'Bhf/u\O_ר2!>gWlëHzoT7 t#0v0(2j$P ~(* Q1Pl&&J*j9@TMmuFl)PBGDofu( ~BR0^9LWKbtQ~?׆*ݨk%CJ U"]mӄdqҸ˰qanצ8`?]01z$íztj7U|,vM씮Em -+b44_$DCht,i^)H {hc?$ -ŧ/ .Ih|%+DX+q}-_^ -{%~ݪ-EP$`'k,Bq{{rAj@&EvŰSYLgi#zIc.;bp[bIBD9^dyQڽLY}uaQP8|bʩ@쩒6^l#Х s$#fc'4~C:& es(*j'A䬺 T>-VJ_qW<&kb ga XJ5-bV>AKp…q%ᑓ}}KV1ٗ! _ -5k*%!]=!Uߒ07֯d2Љm#9gߚ5*F(谮+ !9 ^;7K:Pz2VH9,k;GC{12aѶ??ذe -ǩ),.Ël6)x[c0jHKbdXUv)f;\P*Fh\W遷2C0D1ny -%kyx:2F]z6*O}0a:lo2 xbSp:g8!轖v^}e6P!ɰo}RqMqͼ("zS} ,P`s]ϳW^ ɟ8 -HVV fO>*bjq:gQ~?^O{lk8_H!]\sIqRX/~}t#^gb{lWw:}XzUgt -+zIUjޯ+Z?o¸$p}mP,E=TqYi̼c5,OUefOU~9uՌ=B-eTT`3#W;eөՓoVG)45 -?u!c1X2JvT坟J4)[oy"QnpmL9=_Q["6N\Hm\M=I3qd8s{jW)1-vҦ>֔F& B9ܫ[y{ ,^>] m#cxW:kTi-dWE\t!QE?fkV)kf2< [24;_ÊWH`]j29Ib0kvUuK*G)ν~aY1k Smj:ڥx߷y_k3IbRD%FMVpI9Kv\|š*=}>9?S AКs롢j&?ed~qyxA!Uhٷ~?4⣸)ՀH7[h4(BF^5ʪe.eÆ6yC2 ^'.ctV-!#Os&bxMS2xxz>]0jNX;D($ q]/k-KLT [M%YkF%Vmwdvad &4MB 䟌ǒ)ϼ$4|sce4Dy"zjk) :F+IDED Fw7)foݦʶӒ U FB'k -z%9mv떊["3?\63S1ZNk7*[_w1x獨\q|W r.MZr S_L4C{O8 ]lݽ4dy;=1'.R?8B>U¦[I'2o/qMZJ8ݸTg@_6? #m)8zh\o> -Xta`0::|[/T ,H?^Z33}I1ԸSt"Gϻ|m d3*B:rCz]7+4@ -D-O\9KA)-}≫` ArUQ6SQ D.ؒID_Ԍ> "}`{LTD| --ƪxyIE/d:uR6ONSnuLӌSug|3AF^T9=W1z`wmg|Zsp'a/ KɊrK *R>dq3pⓐVL_Srm%wcbkSPb/x4˸6%x$¬⳩3j8=[.?p;MqTsiS. F=% -Fd^h2d'XKy|K3hʹ-6HvdyM9(|5;BH9>"^uu|ӏCfOVrxb3r]d5@lTwv@~qH ei'B5O bxh2cV@ -{D>K ȓxZnA4O.Y yekznuŖge˪_~p|K: /~J\@5A -b-)Gݐvwmꆎ&cNP;qfK1 ˛fi&)EgN5^pLl0r%bYk9B%\J@iPNb̓fI",Cy9&0Z -ϠfK`![1g &^"HhG.]~gH ;C6)boKxlez+$-_z(J$ts[9Hd^'}mvS?:IBRpMp"_e廯N=Y ]hh$Dٓ/jCύITdsRbefljʼnxcF´2EE.ܢcP=t;;`뛒5\L -^&_osO| e?|1 0xXTo!L׃{v}ڏ^N+-ަ}AÑ&)TJX<_ gQg,GիKTNU:`Jh_zϯozNٮ74GSw\դpE' ZQA@,?RBLk’Q._ b$<ٷ"ba=eTj0ŭW>@/`JACbsN@wy1o+8F*mn*,XC3_q(Xb̒>y?/T9J;v r8_%(T* 'f0+H:*%F昈PWy:nȇ"\ AaQ+'q`sx0pSDƊ߯kA9ʇ7>J𢥠 H*x3zŘ^Xᚢq>8DNN.WǮ1ǥ:Z׶, -׀V-QBF0 `'z8ת(=k5FC*eM: ծ\@ B aAOԪ4?.S׎4 ^o]rqlzd0^>BrT?YH~mMVEFd-SO86Դ0cc&+p>^є@䗠St yQir9r[Ȼ瘲A;-b[Q.uYt9ԙ ]?ӧ@}z/&d If\͋~5K=^%m!ۈrk%7BV:I7wq> Ŵpjxxѱ+#~}"C,Ùuץ;%C4/̄)e`'r( 1[*k{˼y5NG̰CR>_G}o^U OѐEİz[gL|*$l<&ߓ)(uo_|*O1-^mUQaϟɧҏ"p1IYoYw:NS#ÌYm.Z XQAe 2ġ,G/#EVsNi[N)uũ8En5mYE"JL^ e!=Iռts_ hY<̬?d'N̂%2GjX|js4S/KCT0OԐ; wҗi -K;o'XUx>E[FECR[=YY稅9 $ H= $Vdzjm{mr|] wAtu 'ypdzt–\ۺr "HлMfX0m˥xbN9' j #yJ)Uek +a-3LӦp:Qgf)_H -+z#/WƓ)kܧ!Ki~$P~ n?T`aO?)KMf(do%Qٻ}# nAzS<#<ȹRЮsˆ ^{Wݳ( k`Erendstream +vV8i+T hb0Zo)l z1X8xx%f6k@My}Qa,7߈[ +va!.n +`p]6v.Qo  +@G+@iv[?-53kOTo&No}Zw%\A&(sv&B?S+ 3G%u;9` jr}:~(1zd6{h-Ǵ3I`Mߑ:"f^kcc3(@O: 8ˮ9b@6tvCGsk$: +2.vwhk9=V.k:zGq>Gloy\gP:A:@gd +T`&+KwR^W?4˱y8THa5P8w&N!Zg}VD(rDGdӗҗ4_&{26g\.2"R>k-k +L(0,}dۢ84.hO +`[Mh&}jlz ++gFÜQ4쮀xJADW5E$5&D|Ǣȯ$ +/=ٺ +wsv(NoU:׹xb#Ä ](y7Λq؉,Dԡ2LM0M18B:EƭOQ wHt:mCV_fe$T> +]XmWge2NSwP|$;)Tq1L Uғg}F rB1f_hUl̆xDuvûPXN8^șiinMU,UؤU[& AhY7B*\L\61+v`o)%CsRu_8Z +6(~4Y{ndM~WC4>] 3ո;(?`d=EUy:<Ğ:C\ ݵYW{䧅$oȮT%7Q3v?v2}UMq-[sb;!ai !n`H;&%| #*|׫UG}ޘZ>RC6rSh`;`PD&H^mT\ʷq?7"SZJy|^EjT6t}&ޤuUE-uIE/y  +ΔsP 1;TMMwXaAΦ HX.;>? * nlmBڗAeAklS8v}]]bEOrX7i}{||3[ ԣ=J<^j-nw4ǟ;]g\oJUD.S# J *,M̡0} ӟHo22}/Q#K1O4QR?uZ :akg }B9vUU3^#!#Qkh~q k6]]C˩86_ÚKݛ'woSC񣺒Kf|B߉=nr<wi)سGVA`ށ2YT@ՠQuVPS4\oߜ5.3ƐtCzF!oREIb9o;W>tw &e '/,.U/l˗k B4.9]%"dI ϵzd}aZŏsR6>_-Q$ zZN|tG5Ȁ]nKHic#7, ӯFQ::.kw6*? _4”XmD)JDWC.jٽ>NJ +-@&0yj_<`uՅbHUwoP$~ȃS8O)z=z7şR'cd$sp!@ 㬬ʋڍ3Ŝo?YףZ ƬlOʠ$sK[)wZSW qz788l +JXc~]HuHYUL]? NR䚌~Ckaq]"чi?Tv# ugW -5:gF~Fܞ&bZkD'UɕTc g6 +sbg e. #t}_Ģ-涞0ݯv]3T|5opV^EBGeB5~4rkUkb -cNc6=NmIGN*6,6_Y;ƻsi'# >z䫄v=Vh +j^cдw- _1:ܛyd}~~kD +=p-QsީD%HῩ[BgVs0^WQ`ТtIš'|]/f`ρ +Ѩ.ڂo*'ޅ?0,]u}}'va.rJp OIG,jXϷu6mx N1i%<&Dvd17WY.GP %Yu]A3hpK%"r1kU3r~0m6,ג$+IQP' Zz!mƴ#h, vfUPA ;?ӓ ]klXjA׍͚ Y*\~ۙ>GUwf۲x}uQ&Gz.( ~:ϕb7 N`|h W^eh^Z^Z>ZqKw%H^E,qoOHiU_3.g#2tVm3ae Py1u$JF:TܜKgܱ,ALWZIPB靯:۶n*IIDJ_4h>"{uArS[Ѣ>|zҗk-/SHZ>3(R-oDZ]Xc LW8K`ʟz݃c%%^uɧCZ`z%rY7=ǭ13-tA .!Vʠ,Wqs= +o6͟]|XUA4`/rд 9c9ndّfv. +F@mZ8l/ϧ8 +s{(̥%`?8f]'/5_N fteㆺYtq"%-dѯRq(H>M]ח,h5/a"k25 ->%ރW䯈iYHRSLlaZk(AO)~מGM1Pb ։ |s]/g\>"Lh(puN6Tegs^gF<@f`rjziߗ'ǏJ$Dk n/Bf +)r֛cI䅎 $~rˀ6ko^'Dy[5Iby1If\Vpg|jttcPIy8̝ DN-a}zG}E \.4*3 7 -Xtjj߯RQǭ=c3ZMu=&]qUF3jbEhQH~&Ky%&N 8ytT"`ox/47gim&؟̗~v3dm/`19fЗt}H˶3\z{+nXE5͋ԭEC5foT{16Syֽn[UżXW35ṵZ(=4Vԏg=%^ȈttrUeYG/5DFtm{f mGyl|ϸLÏ^w(H\h_SnG&Êή( +/VDf{elPSL#sTX#{c"SBUkL.!AU=Cz-{wzz*_: +^2iQ!Cy!UW~ϱ~Go-YO0 _jc>k'3QeBL?A5|ήZ.Wb|o-HϽ8Fa$`:QNeH满Qn3Ub'L M͕T4sخS|D$$PL?9*`sחR)">U~ U(<*رQ:x4v; +4,#֑˾5={lF_Ϡ<l*@Hz ;[ +0Q~p#~]*x yώsc3_%UZa{Ly+.)Et.Jk2<.DòWy>W-5*&Bz1S Eȗ9d' U- *:ʃ?6"xQ<`t/B=ķQKv#&{|qd3lԗqAOgEy2.DZ)V5F1[k*VpXrJTS&ײͽV -Iq0%VH1?m%L@F8\p޵9}}J~A *Щ=D. bɧ !Ȣqwa]ܢMq~aFcH[e*Iy( Uѽo2fy;X4)]VWc^tO9;;/F2B%mخ5guB5#jW(ݗ?ռ_W?~\߄q)HHkڠ!Xz.u祩⨳ҘyA 5džk~YV%˖*jr<*Ꮻ{Zʨ JgGد2"w˦S'0RiZaUkD9BzbdBӕZ=ȉ;?*iRRU Dܶsz}Elz.&$zyzg2pƹ2DSbH/ZR1:7M})IFM`rW'Y(}ԡ@G+zikZE1uRҾ[(yV?4e'[ʹ-z C6U~֬!SdxdOiw.jơdsjK ĂkGa f1)zU4HS{-=i!b:(Z)I'wf[tKo3diD3 אg xj冘l/LEӳC#llX-PukgD,ܶœWlS&XF|aNGJ=யBsj35# .Uz}r6518CE +*Lz77"BVR5#Woz=|h*yȂH"uYIAz\M;\3>忢M ~ݗ`^t-?DKf-b>2~N_M.F4EeШ1u"(nR؁ݝ~A,)H]ʊQp)5{u_7ޓѮպ-s* I0 e~@0N]ZBF$rM,^eC/,t|a&qvQ;HۑV_Z1Η8(j+ف?2J.Jȸ5`(IM~i>A??%9Ry#!HhriT)|D: S +%tޛNW=O5$PoRQS}Mm]'%A2nO(ה)Kr0M-+ݷEf plf^c8oT+2 c,ihQc}y0\<.R]yˋ"A:h q03zٺ{i) ?e{i_%㚴qqn)l~@Gf=CSqѸ\5iW{|5ux-b V`?tT1.tlMQO)5^ YyjgY$_ Nbgfbq4YDLw-Z )fU6ug#q,=noVhց [%r<>SZ@WH!l@Y\l!%_2}"E,*(;=(@ZU*&鍓nJ'^t*{> >XZm+ܖd'% +A͖l9o{qCb @MD8f/ю8x}]8b(U JwlR/ߖf+W; $1WHv Z1FAQI2r ɼN8$uR3%ZEw_zh0ANH'_Ԇ(T)~礔N*9[͈Ԋ1M=06i)eq]EEǠ&B4 Ny0854W=-ZҽM`#MR,Key*,Q?΢*W)XWvp3u:Ѣ,",._ 4ڳ]ohz۽5A︪I*$zO<*ԁYbܥb4ׄ%],:H|EyoSEn{X`ً[|$;)G^ts5;最% =cf!Z ސWqVUd)TX㇂gPŘ%}-Za_*ٱ#)+4rtv,S%FpJ4QTN`"W̑tT% 狛K1uݐE73 âWNԏanյ_װ!p{Yso +}ڕEKA @xaO1W/^;j(AKAr}`4MUgX1V5ED |*pԝ\h]cKupmYuX +W3[ԣ<` ANpUyQzjTpʚu] +22@ÂUi\i2>t!Lca|r~4 n5;M[Чpmia RM2 W}H);)!/AQs嶐w#z)K51e/v[z)2]k)׳Ds3~'V3Ou7&\_L LS̸sYGjqɗ{VKPC'Z :[7Knt8 +=n@Ay|m#A(<cWG41DX3%t={KwJh0$^ qSiNQ@bTDG Byk?͹ 4a18}^2˕!|ca& Θ5/TAdCY‘_FƋ6wɭ(dS,Sqj۲J3kDt:AX?B1~!{Xys; ҳxY%iOFSuK8e5հԒh^ޣ ש`^i!Qw@V/ +ZӗwnwO|ҍ54dz2Q KsA.@Iz +@Hڶm/.DNt7(|ytTn~NT*nّР-}f}-5{uhEw̰`/:K1:!j[/!sNRASEGo͕RV"O[geM,#tRtW2!G +^';%o3R,ĹO/CZI48"x7 +3ܟ&~S:RAQJvwGB3z7܂2x$FxxǑs]> GI71 #gP?& +urendstream endobj 206 0 obj << /Type /Font @@ -8414,14 +8418,14 @@ endobj /FirstChar 2 /LastChar 252 /Widths 984 0 R -/BaseFont /MVYBPQ+NimbusSanL-Bold +/BaseFont /OGGPIZ+NimbusSanL-Bold /FontDescriptor 204 0 R >> endobj 204 0 obj << /Ascent 722 /CapHeight 722 /Descent -217 -/FontName /MVYBPQ+NimbusSanL-Bold +/FontName /OGGPIZ+NimbusSanL-Bold /ItalicAngle 0 /StemV 141 /XHeight 532 @@ -8910,7 +8914,7 @@ endobj >> endobj 994 0 obj << /Author(Paul Btow)/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords() -/CreationDate (D:20080808000134Z) +/CreationDate (D:20080808140111Z) /PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4) >> endobj xref @@ -8921,1002 +8925,1002 @@ xref 0000000004 00000 f 0000000000 00000 f 0000000009 00000 n -0000088545 00000 n -0000986127 00000 n +0000088575 00000 n +0000986198 00000 n 0000000054 00000 n 0000000143 00000 n -0000088606 00000 n -0000986055 00000 n +0000088636 00000 n +0000986126 00000 n 0000000190 00000 n 0000000290 00000 n -0000092249 00000 n -0000985982 00000 n +0000092279 00000 n +0000986053 00000 n 0000000338 00000 n 0000000438 00000 n -0000110483 00000 n -0000985857 00000 n +0000110513 00000 n +0000985928 00000 n 0000000484 00000 n 0000000592 00000 n -0000110545 00000 n -0000985783 00000 n +0000110575 00000 n +0000985854 00000 n 0000000640 00000 n 0000000875 00000 n -0000190896 00000 n -0000985696 00000 n +0000190926 00000 n +0000985767 00000 n 0000000923 00000 n 0000001038 00000 n -0000228936 00000 n -0000985609 00000 n +0000228966 00000 n +0000985680 00000 n 0000001086 00000 n 0000001186 00000 n -0000234809 00000 n -0000985485 00000 n +0000234839 00000 n +0000985556 00000 n 0000001234 00000 n 0000001349 00000 n -0000234871 00000 n -0000985411 00000 n +0000234901 00000 n +0000985482 00000 n 0000001402 00000 n 0000001557 00000 n -0000255507 00000 n -0000985324 00000 n +0000255537 00000 n +0000985395 00000 n 0000001610 00000 n 0000001790 00000 n -0000272080 00000 n -0000985237 00000 n +0000272110 00000 n +0000985308 00000 n 0000001843 00000 n 0000002084 00000 n -0000279123 00000 n -0000985163 00000 n +0000279153 00000 n +0000985234 00000 n 0000002137 00000 n 0000002353 00000 n -0000280676 00000 n -0000985038 00000 n +0000280706 00000 n +0000985109 00000 n 0000002401 00000 n 0000002501 00000 n -0000280738 00000 n -0000984964 00000 n +0000280768 00000 n +0000985035 00000 n 0000002554 00000 n 0000002756 00000 n -0000445292 00000 n -0000984877 00000 n +0000445322 00000 n +0000984948 00000 n 0000002809 00000 n 0000002990 00000 n -0000516193 00000 n -0000984790 00000 n +0000516223 00000 n +0000984861 00000 n 0000003043 00000 n 0000003224 00000 n -0000539261 00000 n -0000984703 00000 n +0000539291 00000 n +0000984774 00000 n 0000003277 00000 n 0000003711 00000 n -0000566953 00000 n -0000984616 00000 n +0000566983 00000 n +0000984687 00000 n 0000003764 00000 n 0000004076 00000 n -0000596774 00000 n -0000984529 00000 n +0000596804 00000 n +0000984600 00000 n 0000004129 00000 n 0000004474 00000 n -0000622220 00000 n -0000984442 00000 n +0000622250 00000 n +0000984513 00000 n 0000004527 00000 n 0000004751 00000 n -0000652811 00000 n -0000984355 00000 n +0000652841 00000 n +0000984426 00000 n 0000004804 00000 n 0000005033 00000 n -0000681573 00000 n -0000984268 00000 n +0000681603 00000 n +0000984339 00000 n 0000005086 00000 n 0000005329 00000 n -0000706345 00000 n -0000984194 00000 n +0000706375 00000 n +0000984265 00000 n 0000005383 00000 n 0000005651 00000 n -0000743620 00000 n -0000984080 00000 n +0000743633 00000 n +0000984151 00000 n 0000005699 00000 n 0000005838 00000 n -0000743682 00000 n -0000984002 00000 n +0000743695 00000 n +0000984073 00000 n 0000005892 00000 n 0000006190 00000 n -0000801523 00000 n -0000983924 00000 n +0000801542 00000 n +0000983995 00000 n 0000006244 00000 n 0000006476 00000 n -0000804407 00000 n -0000983793 00000 n +0000804426 00000 n +0000983864 00000 n 0000006523 00000 n 0000006662 00000 n -0000804470 00000 n -0000983714 00000 n +0000804489 00000 n +0000983785 00000 n 0000006711 00000 n 0000006872 00000 n -0000811893 00000 n -0000983582 00000 n +0000811912 00000 n +0000983653 00000 n 0000006921 00000 n 0000007108 00000 n -0000811956 00000 n -0000983503 00000 n +0000811975 00000 n +0000983574 00000 n 0000007162 00000 n 0000007318 00000 n -0000819639 00000 n -0000983424 00000 n +0000819658 00000 n +0000983495 00000 n 0000007372 00000 n 0000007498 00000 n -0000823109 00000 n -0000983292 00000 n +0000823128 00000 n +0000983363 00000 n 0000007547 00000 n 0000007648 00000 n -0000823172 00000 n -0000983213 00000 n +0000823191 00000 n +0000983284 00000 n 0000007702 00000 n 0000007919 00000 n -0000833535 00000 n -0000983134 00000 n +0000833554 00000 n +0000983205 00000 n 0000007973 00000 n 0000008245 00000 n -0000837001 00000 n -0000983002 00000 n +0000837020 00000 n +0000983073 00000 n 0000008294 00000 n 0000008622 00000 n -0000837064 00000 n -0000982923 00000 n +0000837083 00000 n +0000982994 00000 n 0000008676 00000 n 0000008807 00000 n -0000847164 00000 n -0000982844 00000 n +0000847183 00000 n +0000982915 00000 n 0000008861 00000 n 0000009190 00000 n -0000851417 00000 n -0000982712 00000 n +0000851436 00000 n +0000982783 00000 n 0000009239 00000 n 0000009340 00000 n -0000851480 00000 n -0000982633 00000 n +0000851499 00000 n +0000982704 00000 n 0000009394 00000 n 0000009626 00000 n -0000854039 00000 n -0000982540 00000 n +0000854058 00000 n +0000982611 00000 n 0000009680 00000 n 0000009947 00000 n -0000862277 00000 n -0000982461 00000 n +0000862296 00000 n +0000982532 00000 n 0000010001 00000 n 0000010213 00000 n -0000866682 00000 n -0000982368 00000 n +0000866749 00000 n +0000982439 00000 n 0000010262 00000 n 0000010494 00000 n -0000866745 00000 n -0000982275 00000 n +0000866812 00000 n +0000982346 00000 n 0000010543 00000 n 0000010755 00000 n -0000866870 00000 n -0000982182 00000 n +0000866938 00000 n +0000982253 00000 n 0000010804 00000 n -0000010964 00000 n -0000874808 00000 n -0000982103 00000 n -0000011013 00000 n -0000011164 00000 n -0000880176 00000 n -0000982010 00000 n -0000011211 00000 n -0000011292 00000 n -0000881724 00000 n -0000981917 00000 n -0000011340 00000 n -0000011421 00000 n -0000883757 00000 n -0000981838 00000 n -0000011469 00000 n -0000011610 00000 n -0000012569 00000 n -0000012691 00000 n -0000055096 00000 n -0000011662 00000 n -0000054970 00000 n -0000055033 00000 n -0000978654 00000 n -0000965805 00000 n -0000978484 00000 n -0000964516 00000 n -0000950663 00000 n -0000964346 00000 n -0000979750 00000 n -0000056374 00000 n -0000056189 00000 n -0000055217 00000 n -0000056311 00000 n -0000057514 00000 n -0000057329 00000 n -0000056459 00000 n -0000057451 00000 n -0000950130 00000 n -0000948267 00000 n -0000949970 00000 n -0000064623 00000 n -0000059988 00000 n -0000057612 00000 n -0000064497 00000 n -0000064560 00000 n -0000060330 00000 n -0000060485 00000 n -0000060642 00000 n -0000060797 00000 n -0000060952 00000 n -0000061108 00000 n -0000061265 00000 n -0000061422 00000 n -0000061579 00000 n -0000061742 00000 n -0000061905 00000 n -0000062068 00000 n -0000062231 00000 n -0000062388 00000 n -0000062550 00000 n -0000062713 00000 n -0000062876 00000 n -0000063039 00000 n -0000063200 00000 n -0000063362 00000 n -0000063525 00000 n -0000063688 00000 n -0000063851 00000 n -0000064014 00000 n -0000064171 00000 n -0000064334 00000 n -0000070571 00000 n -0000066702 00000 n -0000064708 00000 n -0000070508 00000 n -0000947188 00000 n -0000936023 00000 n -0000947013 00000 n -0000067012 00000 n -0000067166 00000 n -0000067323 00000 n -0000067480 00000 n -0000067643 00000 n -0000067805 00000 n -0000067962 00000 n -0000068124 00000 n -0000068287 00000 n -0000068443 00000 n -0000068605 00000 n -0000068768 00000 n -0000068925 00000 n -0000069088 00000 n -0000069251 00000 n -0000069414 00000 n -0000069571 00000 n -0000069728 00000 n -0000069884 00000 n -0000070041 00000 n -0000070196 00000 n -0000070352 00000 n -0000077826 00000 n -0000073136 00000 n -0000070669 00000 n -0000077700 00000 n -0000077763 00000 n -0000073486 00000 n -0000073640 00000 n -0000073795 00000 n -0000073951 00000 n -0000074107 00000 n -0000074263 00000 n -0000074419 00000 n -0000074575 00000 n -0000074731 00000 n -0000074887 00000 n -0000075043 00000 n -0000075198 00000 n -0000075355 00000 n -0000075512 00000 n -0000075668 00000 n -0000075825 00000 n -0000075981 00000 n -0000076138 00000 n -0000076294 00000 n -0000076451 00000 n -0000076607 00000 n -0000076764 00000 n -0000076919 00000 n -0000077076 00000 n -0000077232 00000 n -0000077388 00000 n -0000077544 00000 n -0000092374 00000 n -0000095616 00000 n -0000110607 00000 n -0000120698 00000 n -0000155593 00000 n -0000155657 00000 n -0000164526 00000 n -0000164590 00000 n -0000176106 00000 n -0000176169 00000 n -0000185178 00000 n -0000190832 00000 n -0000218487 00000 n -0000226203 00000 n -0000255443 00000 n -0000269132 00000 n -0000445354 00000 n -0000445418 00000 n -0000516255 00000 n -0000539323 00000 n -0000567015 00000 n -0000596836 00000 n -0000622282 00000 n -0000652873 00000 n -0000681635 00000 n -0000706407 00000 n -0000743745 00000 n -0000080867 00000 n -0000079030 00000 n -0000077911 00000 n -0000080804 00000 n -0000079244 00000 n -0000079401 00000 n -0000079557 00000 n -0000079713 00000 n -0000079869 00000 n -0000080025 00000 n -0000080181 00000 n -0000080337 00000 n -0000080493 00000 n -0000080649 00000 n -0000979867 00000 n -0000775941 00000 n -0000801586 00000 n -0000812019 00000 n -0000819702 00000 n -0000827275 00000 n -0000837127 00000 n -0000841305 00000 n -0000851353 00000 n -0000866933 00000 n -0000870952 00000 n -0000086244 00000 n -0000082884 00000 n -0000080952 00000 n -0000086118 00000 n -0000086181 00000 n -0000083170 00000 n -0000083324 00000 n -0000083479 00000 n -0000083634 00000 n -0000083789 00000 n -0000083944 00000 n -0000084099 00000 n -0000084254 00000 n -0000084409 00000 n -0000084564 00000 n -0000084720 00000 n -0000084875 00000 n -0000085031 00000 n -0000085187 00000 n -0000085341 00000 n -0000085497 00000 n -0000085652 00000 n -0000085808 00000 n -0000085963 00000 n -0000167660 00000 n -0000234682 00000 n -0000279060 00000 n -0000448354 00000 n -0000448418 00000 n -0000516129 00000 n -0000541752 00000 n -0000569470 00000 n -0000600083 00000 n -0000624117 00000 n -0000655059 00000 n -0000658067 00000 n -0000660174 00000 n -0000706281 00000 n -0000708615 00000 n -0000711772 00000 n -0000713807 00000 n -0000807234 00000 n -0000815419 00000 n -0000088668 00000 n -0000088180 00000 n -0000086342 00000 n -0000088482 00000 n -0000088322 00000 n -0000883946 00000 n -0000090842 00000 n -0000094244 00000 n -0000092564 00000 n -0000090700 00000 n -0000088766 00000 n -0000092186 00000 n -0000092311 00000 n -0000092030 00000 n -0000092438 00000 n -0000092501 00000 n -0000091759 00000 n -0000091890 00000 n -0000091937 00000 n -0000092009 00000 n -0000095680 00000 n -0000094122 00000 n -0000092690 00000 n -0000095490 00000 n -0000095553 00000 n -0000095219 00000 n -0000095350 00000 n -0000095397 00000 n -0000095469 00000 n -0000098136 00000 n -0000097648 00000 n -0000095806 00000 n -0000097947 00000 n -0000098010 00000 n -0000098073 00000 n -0000097790 00000 n -0000099632 00000 n -0000110671 00000 n -0000099474 00000 n -0000098234 00000 n -0000110420 00000 n -0000109953 00000 n -0000110107 00000 n -0000110263 00000 n -0000979984 00000 n -0000112739 00000 n -0000122246 00000 n -0000152700 00000 n -0000120825 00000 n -0000112589 00000 n -0000110805 00000 n -0000120572 00000 n -0000120635 00000 n -0000120258 00000 n -0000120762 00000 n -0000120415 00000 n -0000155721 00000 n -0000122124 00000 n -0000120959 00000 n -0000155530 00000 n -0000157386 00000 n -0000161810 00000 n -0000164654 00000 n -0000157244 00000 n -0000155868 00000 n -0000164400 00000 n -0000164463 00000 n -0000164243 00000 n -0000167787 00000 n -0000167135 00000 n -0000164801 00000 n -0000167597 00000 n -0000167285 00000 n -0000167724 00000 n -0000167441 00000 n -0000169410 00000 n -0000172086 00000 n -0000176233 00000 n -0000169268 00000 n -0000167885 00000 n -0000175980 00000 n -0000176043 00000 n -0000175823 00000 n -0000178384 00000 n -0000187967 00000 n -0000185242 00000 n -0000178226 00000 n -0000176382 00000 n -0000185115 00000 n -0000184645 00000 n -0000184802 00000 n -0000184958 00000 n -0000980101 00000 n -0000192988 00000 n -0000190958 00000 n -0000187809 00000 n -0000185364 00000 n -0000190706 00000 n -0000190769 00000 n -0000190236 00000 n -0000190392 00000 n -0000190549 00000 n -0000218677 00000 n -0000192846 00000 n -0000191093 00000 n -0000218424 00000 n -0000218551 00000 n -0000218266 00000 n -0000218614 00000 n -0000220722 00000 n -0000226330 00000 n -0000220600 00000 n -0000218812 00000 n -0000226140 00000 n -0000226267 00000 n -0000229124 00000 n -0000228751 00000 n -0000226465 00000 n -0000228873 00000 n -0000228998 00000 n -0000229061 00000 n -0000231769 00000 n -0000231458 00000 n -0000229222 00000 n -0000231580 00000 n -0000231643 00000 n -0000231706 00000 n -0000236931 00000 n -0000234933 00000 n -0000234321 00000 n -0000231880 00000 n -0000234619 00000 n -0000234746 00000 n -0000234463 00000 n -0000980218 00000 n -0000257579 00000 n -0000255568 00000 n -0000236789 00000 n -0000235031 00000 n -0000255380 00000 n -0000255222 00000 n -0000269195 00000 n -0000257457 00000 n -0000255716 00000 n -0000269069 00000 n -0000272142 00000 n -0000271895 00000 n -0000269343 00000 n -0000272017 00000 n -0000275518 00000 n -0000275333 00000 n -0000272253 00000 n -0000275455 00000 n -0000935670 00000 n -0000927329 00000 n -0000935492 00000 n -0000926889 00000 n -0000924605 00000 n -0000926729 00000 n -0000924312 00000 n -0000916496 00000 n -0000924139 00000 n -0000916147 00000 n -0000914091 00000 n -0000915986 00000 n -0000279185 00000 n -0000278534 00000 n -0000275681 00000 n -0000278997 00000 n -0000913641 00000 n -0000906350 00000 n -0000913466 00000 n -0000278684 00000 n -0000278841 00000 n -0000280800 00000 n -0000280491 00000 n -0000279361 00000 n -0000280613 00000 n -0000980335 00000 n -0000282440 00000 n -0000313639 00000 n -0000445482 00000 n -0000282290 00000 n -0000280898 00000 n -0000445229 00000 n -0000444917 00000 n -0000445075 00000 n -0000448482 00000 n -0000447828 00000 n -0000445631 00000 n -0000448291 00000 n -0000447978 00000 n -0000448134 00000 n -0000450579 00000 n -0000516319 00000 n -0000450457 00000 n -0000448580 00000 n -0000516066 00000 n -0000517815 00000 n -0000517288 00000 n -0000516454 00000 n -0000517752 00000 n -0000517438 00000 n -0000517596 00000 n -0000520548 00000 n -0000539386 00000 n -0000520390 00000 n -0000517900 00000 n -0000539198 00000 n -0000538729 00000 n -0000538886 00000 n -0000539043 00000 n -0000541878 00000 n -0000541567 00000 n -0000539586 00000 n -0000541689 00000 n -0000541815 00000 n -0000980452 00000 n -0000544676 00000 n -0000567079 00000 n -0000544510 00000 n -0000542002 00000 n -0000566890 00000 n -0000566263 00000 n -0000566424 00000 n -0000566580 00000 n -0000566734 00000 n -0000883883 00000 n -0000569534 00000 n -0000569108 00000 n -0000567279 00000 n -0000569407 00000 n -0000569250 00000 n -0000572145 00000 n -0000596900 00000 n -0000572023 00000 n -0000569645 00000 n -0000596711 00000 n -0000906021 00000 n -0000903913 00000 n -0000905852 00000 n -0000600210 00000 n -0000599556 00000 n -0000597113 00000 n -0000600020 00000 n -0000599706 00000 n -0000599864 00000 n -0000600147 00000 n -0000602498 00000 n -0000622409 00000 n -0000602348 00000 n -0000600334 00000 n -0000622157 00000 n -0000621842 00000 n -0000622000 00000 n -0000622346 00000 n -0000624181 00000 n -0000623932 00000 n -0000622544 00000 n -0000624054 00000 n -0000980569 00000 n -0000626693 00000 n -0000652937 00000 n -0000626527 00000 n -0000624292 00000 n -0000652748 00000 n -0000652125 00000 n -0000652281 00000 n -0000652436 00000 n -0000652592 00000 n -0000655185 00000 n -0000654874 00000 n -0000653072 00000 n -0000654996 00000 n -0000655123 00000 n -0000658131 00000 n -0000657882 00000 n -0000655296 00000 n -0000658004 00000 n -0000660238 00000 n -0000659989 00000 n -0000658229 00000 n -0000660111 00000 n -0000662344 00000 n -0000681699 00000 n -0000662194 00000 n -0000660336 00000 n -0000681510 00000 n -0000681195 00000 n -0000681353 00000 n -0000684314 00000 n -0000706471 00000 n -0000684148 00000 n -0000681834 00000 n -0000706218 00000 n -0000705590 00000 n -0000705748 00000 n -0000705905 00000 n -0000706061 00000 n -0000980686 00000 n -0000708993 00000 n -0000708430 00000 n -0000706606 00000 n -0000708552 00000 n -0000708678 00000 n -0000708741 00000 n -0000708804 00000 n -0000708867 00000 n -0000708930 00000 n -0000711836 00000 n -0000711587 00000 n -0000709104 00000 n -0000711709 00000 n -0000713934 00000 n -0000713622 00000 n -0000711934 00000 n -0000713744 00000 n -0000713871 00000 n -0000716084 00000 n -0000746342 00000 n -0000743809 00000 n -0000715942 00000 n -0000714045 00000 n -0000743557 00000 n -0000743400 00000 n -0000776005 00000 n -0000746176 00000 n -0000743996 00000 n -0000775878 00000 n -0000775240 00000 n -0000775398 00000 n -0000775556 00000 n -0000775717 00000 n -0000778629 00000 n -0000801650 00000 n -0000778479 00000 n -0000776166 00000 n -0000801460 00000 n -0000801147 00000 n -0000801303 00000 n -0000980803 00000 n -0000804532 00000 n -0000803886 00000 n -0000801837 00000 n -0000804344 00000 n -0000804036 00000 n -0000804190 00000 n -0000883820 00000 n -0000807298 00000 n -0000807049 00000 n -0000804643 00000 n -0000807171 00000 n -0000810139 00000 n -0000812083 00000 n -0000809973 00000 n -0000807409 00000 n -0000811830 00000 n -0000811204 00000 n -0000811361 00000 n -0000811518 00000 n -0000811674 00000 n -0000810933 00000 n -0000811064 00000 n -0000811111 00000 n -0000811183 00000 n -0000815483 00000 n -0000815234 00000 n -0000812210 00000 n -0000815356 00000 n -0000817919 00000 n -0000819766 00000 n -0000817777 00000 n -0000815594 00000 n -0000819576 00000 n -0000819419 00000 n -0000819068 00000 n -0000819199 00000 n -0000819246 00000 n -0000819318 00000 n -0000819398 00000 n -0000825223 00000 n -0000823235 00000 n -0000822584 00000 n -0000819893 00000 n -0000823046 00000 n -0000822734 00000 n -0000822889 00000 n -0000980920 00000 n -0000827464 00000 n -0000825101 00000 n -0000823333 00000 n -0000827212 00000 n -0000827339 00000 n -0000827402 00000 n -0000826860 00000 n -0000826991 00000 n -0000827038 00000 n -0000827110 00000 n -0000827190 00000 n -0000830655 00000 n -0000830231 00000 n -0000827591 00000 n -0000830529 00000 n -0000830592 00000 n -0000830373 00000 n -0000833598 00000 n -0000833350 00000 n -0000830753 00000 n -0000833472 00000 n -0000903082 00000 n -0000885982 00000 n -0000902911 00000 n -0000835493 00000 n -0000837191 00000 n -0000835343 00000 n -0000833722 00000 n -0000836938 00000 n -0000836627 00000 n -0000836783 00000 n -0000836356 00000 n -0000836487 00000 n -0000836534 00000 n -0000836606 00000 n -0000839483 00000 n -0000841368 00000 n -0000839361 00000 n -0000837331 00000 n -0000841242 00000 n -0000840970 00000 n -0000841101 00000 n -0000841148 00000 n -0000841220 00000 n -0000845132 00000 n -0000844772 00000 n -0000841482 00000 n -0000845069 00000 n -0000844914 00000 n -0000981037 00000 n -0000849355 00000 n -0000847226 00000 n -0000846979 00000 n -0000845217 00000 n -0000847101 00000 n -0000851543 00000 n -0000849213 00000 n -0000847337 00000 n -0000851290 00000 n -0000851133 00000 n -0000850782 00000 n -0000850913 00000 n -0000850960 00000 n -0000851032 00000 n -0000851112 00000 n -0000854102 00000 n -0000853854 00000 n -0000851683 00000 n -0000853976 00000 n -0000856350 00000 n -0000856102 00000 n -0000854226 00000 n -0000856224 00000 n -0000856287 00000 n -0000858261 00000 n -0000858076 00000 n -0000856461 00000 n -0000858198 00000 n -0000860310 00000 n -0000860062 00000 n -0000858359 00000 n -0000860184 00000 n -0000860247 00000 n -0000981154 00000 n -0000862655 00000 n -0000862092 00000 n -0000860421 00000 n -0000862214 00000 n -0000862340 00000 n -0000862403 00000 n -0000862466 00000 n -0000862529 00000 n -0000862592 00000 n -0000864610 00000 n -0000866995 00000 n -0000864460 00000 n -0000862779 00000 n -0000866493 00000 n -0000866556 00000 n -0000866619 00000 n -0000866807 00000 n -0000866180 00000 n -0000866336 00000 n -0000865909 00000 n -0000866040 00000 n -0000866087 00000 n -0000866159 00000 n -0000869717 00000 n -0000871016 00000 n -0000869595 00000 n -0000867135 00000 n -0000870889 00000 n -0000870618 00000 n -0000870749 00000 n -0000870796 00000 n -0000870868 00000 n -0000874934 00000 n -0000873882 00000 n -0000871143 00000 n -0000874745 00000 n -0000874048 00000 n -0000874871 00000 n -0000874221 00000 n -0000874396 00000 n -0000874572 00000 n -0000879585 00000 n -0000876573 00000 n -0000875058 00000 n -0000879522 00000 n -0000876827 00000 n -0000877000 00000 n -0000877183 00000 n -0000877351 00000 n -0000877529 00000 n -0000877713 00000 n -0000877887 00000 n -0000878085 00000 n -0000878256 00000 n -0000878427 00000 n -0000878628 00000 n -0000878802 00000 n -0000878981 00000 n -0000879161 00000 n -0000879339 00000 n -0000880239 00000 n -0000879991 00000 n -0000879696 00000 n -0000880113 00000 n -0000981271 00000 n -0000882731 00000 n -0000881539 00000 n -0000880324 00000 n -0000881661 00000 n -0000881787 00000 n -0000881850 00000 n -0000881913 00000 n -0000881976 00000 n -0000882039 00000 n -0000882102 00000 n -0000882165 00000 n -0000882228 00000 n -0000882291 00000 n -0000882354 00000 n -0000882417 00000 n -0000882480 00000 n -0000882543 00000 n -0000882606 00000 n -0000882669 00000 n -0000884009 00000 n -0000883572 00000 n -0000882816 00000 n -0000883694 00000 n -0000884094 00000 n -0000903565 00000 n -0000906258 00000 n -0000906234 00000 n -0000913893 00000 n -0000916398 00000 n -0000916366 00000 n -0000924551 00000 n -0000927189 00000 n -0000927117 00000 n -0000935921 00000 n -0000947713 00000 n -0000950501 00000 n -0000950372 00000 n -0000965107 00000 n -0000979090 00000 n -0000981364 00000 n -0000981482 00000 n -0000981600 00000 n -0000981685 00000 n -0000981763 00000 n -0000986236 00000 n -0000991333 00000 n -0000991372 00000 n -0000991410 00000 n -0000991562 00000 n +0000010996 00000 n +0000874878 00000 n +0000982174 00000 n +0000011045 00000 n +0000011196 00000 n +0000880246 00000 n +0000982081 00000 n +0000011243 00000 n +0000011324 00000 n +0000881794 00000 n +0000981988 00000 n +0000011372 00000 n +0000011453 00000 n +0000883827 00000 n +0000981909 00000 n +0000011501 00000 n +0000011642 00000 n +0000012601 00000 n +0000012723 00000 n +0000055128 00000 n +0000011694 00000 n +0000055002 00000 n +0000055065 00000 n +0000978725 00000 n +0000965876 00000 n +0000978555 00000 n +0000964587 00000 n +0000950734 00000 n +0000964417 00000 n +0000979821 00000 n +0000056406 00000 n +0000056221 00000 n +0000055249 00000 n +0000056343 00000 n +0000057546 00000 n +0000057361 00000 n +0000056491 00000 n +0000057483 00000 n +0000950201 00000 n +0000948338 00000 n +0000950041 00000 n +0000064655 00000 n +0000060020 00000 n +0000057644 00000 n +0000064529 00000 n +0000064592 00000 n +0000060362 00000 n +0000060517 00000 n +0000060674 00000 n +0000060829 00000 n +0000060984 00000 n +0000061140 00000 n +0000061297 00000 n +0000061454 00000 n +0000061611 00000 n +0000061774 00000 n +0000061937 00000 n +0000062100 00000 n +0000062263 00000 n +0000062420 00000 n +0000062582 00000 n +0000062745 00000 n +0000062908 00000 n +0000063071 00000 n +0000063232 00000 n +0000063394 00000 n +0000063557 00000 n +0000063720 00000 n +0000063883 00000 n +0000064046 00000 n +0000064203 00000 n +0000064366 00000 n +0000070601 00000 n +0000066731 00000 n +0000064740 00000 n +0000070538 00000 n +0000947259 00000 n +0000936094 00000 n +0000947084 00000 n +0000067041 00000 n +0000067195 00000 n +0000067352 00000 n +0000067509 00000 n +0000067672 00000 n +0000067834 00000 n +0000067991 00000 n +0000068153 00000 n +0000068316 00000 n +0000068472 00000 n +0000068634 00000 n +0000068797 00000 n +0000068954 00000 n +0000069117 00000 n +0000069280 00000 n +0000069443 00000 n +0000069600 00000 n +0000069757 00000 n +0000069914 00000 n +0000070071 00000 n +0000070226 00000 n +0000070382 00000 n +0000077856 00000 n +0000073166 00000 n +0000070699 00000 n +0000077730 00000 n +0000077793 00000 n +0000073516 00000 n +0000073670 00000 n +0000073825 00000 n +0000073981 00000 n +0000074137 00000 n +0000074293 00000 n +0000074449 00000 n +0000074605 00000 n +0000074761 00000 n +0000074917 00000 n +0000075073 00000 n +0000075228 00000 n +0000075385 00000 n +0000075542 00000 n +0000075698 00000 n +0000075855 00000 n +0000076011 00000 n +0000076168 00000 n +0000076324 00000 n +0000076481 00000 n +0000076637 00000 n +0000076794 00000 n +0000076949 00000 n +0000077106 00000 n +0000077262 00000 n +0000077418 00000 n +0000077574 00000 n +0000092404 00000 n +0000095646 00000 n +0000110637 00000 n +0000120728 00000 n +0000155623 00000 n +0000155687 00000 n +0000164556 00000 n +0000164620 00000 n +0000176136 00000 n +0000176199 00000 n +0000185208 00000 n +0000190862 00000 n +0000218517 00000 n +0000226233 00000 n +0000255473 00000 n +0000269162 00000 n +0000445384 00000 n +0000445448 00000 n +0000516285 00000 n +0000539353 00000 n +0000567045 00000 n +0000596866 00000 n +0000622312 00000 n +0000652903 00000 n +0000681665 00000 n +0000706437 00000 n +0000743758 00000 n +0000080897 00000 n +0000079060 00000 n +0000077941 00000 n +0000080834 00000 n +0000079274 00000 n +0000079431 00000 n +0000079587 00000 n +0000079743 00000 n +0000079899 00000 n +0000080055 00000 n +0000080211 00000 n +0000080367 00000 n +0000080523 00000 n +0000080679 00000 n +0000979938 00000 n +0000775954 00000 n +0000801605 00000 n +0000812038 00000 n +0000819721 00000 n +0000827294 00000 n +0000837146 00000 n +0000841324 00000 n +0000851372 00000 n +0000867001 00000 n +0000871022 00000 n +0000086274 00000 n +0000082914 00000 n +0000080982 00000 n +0000086148 00000 n +0000086211 00000 n +0000083200 00000 n +0000083354 00000 n +0000083509 00000 n +0000083664 00000 n +0000083819 00000 n +0000083974 00000 n +0000084129 00000 n +0000084284 00000 n +0000084439 00000 n +0000084594 00000 n +0000084750 00000 n +0000084905 00000 n +0000085061 00000 n +0000085217 00000 n +0000085371 00000 n +0000085527 00000 n +0000085682 00000 n +0000085838 00000 n +0000085993 00000 n +0000167690 00000 n +0000234712 00000 n +0000279090 00000 n +0000448384 00000 n +0000448448 00000 n +0000516159 00000 n +0000541782 00000 n +0000569500 00000 n +0000600113 00000 n +0000624147 00000 n +0000655089 00000 n +0000658097 00000 n +0000660204 00000 n +0000706311 00000 n +0000708645 00000 n +0000711802 00000 n +0000713837 00000 n +0000807253 00000 n +0000815438 00000 n +0000088698 00000 n +0000088210 00000 n +0000086372 00000 n +0000088512 00000 n +0000088352 00000 n +0000884016 00000 n +0000090872 00000 n +0000094274 00000 n +0000092594 00000 n +0000090730 00000 n +0000088796 00000 n +0000092216 00000 n +0000092341 00000 n +0000092060 00000 n +0000092468 00000 n +0000092531 00000 n +0000091789 00000 n +0000091920 00000 n +0000091967 00000 n +0000092039 00000 n +0000095710 00000 n +0000094152 00000 n +0000092720 00000 n +0000095520 00000 n +0000095583 00000 n +0000095249 00000 n +0000095380 00000 n +0000095427 00000 n +0000095499 00000 n +0000098166 00000 n +0000097678 00000 n +0000095836 00000 n +0000097977 00000 n +0000098040 00000 n +0000098103 00000 n +0000097820 00000 n +0000099662 00000 n +0000110701 00000 n +0000099504 00000 n +0000098264 00000 n +0000110450 00000 n +0000109983 00000 n +0000110137 00000 n +0000110293 00000 n +0000980055 00000 n +0000112769 00000 n +0000122276 00000 n +0000152730 00000 n +0000120855 00000 n +0000112619 00000 n +0000110835 00000 n +0000120602 00000 n +0000120665 00000 n +0000120288 00000 n +0000120792 00000 n +0000120445 00000 n +0000155751 00000 n +0000122154 00000 n +0000120989 00000 n +0000155560 00000 n +0000157416 00000 n +0000161840 00000 n +0000164684 00000 n +0000157274 00000 n +0000155898 00000 n +0000164430 00000 n +0000164493 00000 n +0000164273 00000 n +0000167817 00000 n +0000167165 00000 n +0000164831 00000 n +0000167627 00000 n +0000167315 00000 n +0000167754 00000 n +0000167471 00000 n +0000169440 00000 n +0000172116 00000 n +0000176263 00000 n +0000169298 00000 n +0000167915 00000 n +0000176010 00000 n +0000176073 00000 n +0000175853 00000 n +0000178414 00000 n +0000187997 00000 n +0000185272 00000 n +0000178256 00000 n +0000176412 00000 n +0000185145 00000 n +0000184675 00000 n +0000184832 00000 n +0000184988 00000 n +0000980172 00000 n +0000193018 00000 n +0000190988 00000 n +0000187839 00000 n +0000185394 00000 n +0000190736 00000 n +0000190799 00000 n +0000190266 00000 n +0000190422 00000 n +0000190579 00000 n +0000218707 00000 n +0000192876 00000 n +0000191123 00000 n +0000218454 00000 n +0000218581 00000 n +0000218296 00000 n +0000218644 00000 n +0000220752 00000 n +0000226360 00000 n +0000220630 00000 n +0000218842 00000 n +0000226170 00000 n +0000226297 00000 n +0000229154 00000 n +0000228781 00000 n +0000226495 00000 n +0000228903 00000 n +0000229028 00000 n +0000229091 00000 n +0000231799 00000 n +0000231488 00000 n +0000229252 00000 n +0000231610 00000 n +0000231673 00000 n +0000231736 00000 n +0000236961 00000 n +0000234963 00000 n +0000234351 00000 n +0000231910 00000 n +0000234649 00000 n +0000234776 00000 n +0000234493 00000 n +0000980289 00000 n +0000257609 00000 n +0000255598 00000 n +0000236819 00000 n +0000235061 00000 n +0000255410 00000 n +0000255252 00000 n +0000269225 00000 n +0000257487 00000 n +0000255746 00000 n +0000269099 00000 n +0000272172 00000 n +0000271925 00000 n +0000269373 00000 n +0000272047 00000 n +0000275548 00000 n +0000275363 00000 n +0000272283 00000 n +0000275485 00000 n +0000935741 00000 n +0000927398 00000 n +0000935563 00000 n +0000926958 00000 n +0000924675 00000 n +0000926798 00000 n +0000924382 00000 n +0000916566 00000 n +0000924209 00000 n +0000916217 00000 n +0000914161 00000 n +0000916056 00000 n +0000279215 00000 n +0000278564 00000 n +0000275711 00000 n +0000279027 00000 n +0000913711 00000 n +0000906420 00000 n +0000913536 00000 n +0000278714 00000 n +0000278871 00000 n +0000280830 00000 n +0000280521 00000 n +0000279391 00000 n +0000280643 00000 n +0000980406 00000 n +0000282470 00000 n +0000313669 00000 n +0000445512 00000 n +0000282320 00000 n +0000280928 00000 n +0000445259 00000 n +0000444947 00000 n +0000445105 00000 n +0000448512 00000 n +0000447858 00000 n +0000445661 00000 n +0000448321 00000 n +0000448008 00000 n +0000448164 00000 n +0000450609 00000 n +0000516349 00000 n +0000450487 00000 n +0000448610 00000 n +0000516096 00000 n +0000517845 00000 n +0000517318 00000 n +0000516484 00000 n +0000517782 00000 n +0000517468 00000 n +0000517626 00000 n +0000520578 00000 n +0000539416 00000 n +0000520420 00000 n +0000517930 00000 n +0000539228 00000 n +0000538759 00000 n +0000538916 00000 n +0000539073 00000 n +0000541908 00000 n +0000541597 00000 n +0000539616 00000 n +0000541719 00000 n +0000541845 00000 n +0000980523 00000 n +0000544706 00000 n +0000567109 00000 n +0000544540 00000 n +0000542032 00000 n +0000566920 00000 n +0000566293 00000 n +0000566454 00000 n +0000566610 00000 n +0000566764 00000 n +0000883953 00000 n +0000569564 00000 n +0000569138 00000 n +0000567309 00000 n +0000569437 00000 n +0000569280 00000 n +0000572175 00000 n +0000596930 00000 n +0000572053 00000 n +0000569675 00000 n +0000596741 00000 n +0000906091 00000 n +0000903983 00000 n +0000905922 00000 n +0000600240 00000 n +0000599586 00000 n +0000597143 00000 n +0000600050 00000 n +0000599736 00000 n +0000599894 00000 n +0000600177 00000 n +0000602528 00000 n +0000622439 00000 n +0000602378 00000 n +0000600364 00000 n +0000622187 00000 n +0000621872 00000 n +0000622030 00000 n +0000622376 00000 n +0000624211 00000 n +0000623962 00000 n +0000622574 00000 n +0000624084 00000 n +0000980640 00000 n +0000626723 00000 n +0000652967 00000 n +0000626557 00000 n +0000624322 00000 n +0000652778 00000 n +0000652155 00000 n +0000652311 00000 n +0000652466 00000 n +0000652622 00000 n +0000655215 00000 n +0000654904 00000 n +0000653102 00000 n +0000655026 00000 n +0000655153 00000 n +0000658161 00000 n +0000657912 00000 n +0000655326 00000 n +0000658034 00000 n +0000660268 00000 n +0000660019 00000 n +0000658259 00000 n +0000660141 00000 n +0000662374 00000 n +0000681729 00000 n +0000662224 00000 n +0000660366 00000 n +0000681540 00000 n +0000681225 00000 n +0000681383 00000 n +0000684344 00000 n +0000706501 00000 n +0000684178 00000 n +0000681864 00000 n +0000706248 00000 n +0000705620 00000 n +0000705778 00000 n +0000705935 00000 n +0000706091 00000 n +0000980757 00000 n +0000709023 00000 n +0000708460 00000 n +0000706636 00000 n +0000708582 00000 n +0000708708 00000 n +0000708771 00000 n +0000708834 00000 n +0000708897 00000 n +0000708960 00000 n +0000711866 00000 n +0000711617 00000 n +0000709134 00000 n +0000711739 00000 n +0000713964 00000 n +0000713652 00000 n +0000711964 00000 n +0000713774 00000 n +0000713901 00000 n +0000716097 00000 n +0000746355 00000 n +0000743822 00000 n +0000715955 00000 n +0000714075 00000 n +0000743570 00000 n +0000743413 00000 n +0000776018 00000 n +0000746189 00000 n +0000744009 00000 n +0000775891 00000 n +0000775253 00000 n +0000775411 00000 n +0000775569 00000 n +0000775730 00000 n +0000778648 00000 n +0000801669 00000 n +0000778498 00000 n +0000776179 00000 n +0000801479 00000 n +0000801166 00000 n +0000801322 00000 n +0000980874 00000 n +0000804551 00000 n +0000803905 00000 n +0000801856 00000 n +0000804363 00000 n +0000804055 00000 n +0000804209 00000 n +0000883890 00000 n +0000807317 00000 n +0000807068 00000 n +0000804662 00000 n +0000807190 00000 n +0000810158 00000 n +0000812102 00000 n +0000809992 00000 n +0000807428 00000 n +0000811849 00000 n +0000811223 00000 n +0000811380 00000 n +0000811537 00000 n +0000811693 00000 n +0000810952 00000 n +0000811083 00000 n +0000811130 00000 n +0000811202 00000 n +0000815502 00000 n +0000815253 00000 n +0000812229 00000 n +0000815375 00000 n +0000817938 00000 n +0000819785 00000 n +0000817796 00000 n +0000815613 00000 n +0000819595 00000 n +0000819438 00000 n +0000819087 00000 n +0000819218 00000 n +0000819265 00000 n +0000819337 00000 n +0000819417 00000 n +0000825242 00000 n +0000823254 00000 n +0000822603 00000 n +0000819912 00000 n +0000823065 00000 n +0000822753 00000 n +0000822908 00000 n +0000980991 00000 n +0000827483 00000 n +0000825120 00000 n +0000823352 00000 n +0000827231 00000 n +0000827358 00000 n +0000827421 00000 n +0000826879 00000 n +0000827010 00000 n +0000827057 00000 n +0000827129 00000 n +0000827209 00000 n +0000830674 00000 n +0000830250 00000 n +0000827610 00000 n +0000830548 00000 n +0000830611 00000 n +0000830392 00000 n +0000833617 00000 n +0000833369 00000 n +0000830772 00000 n +0000833491 00000 n +0000903152 00000 n +0000886052 00000 n +0000902981 00000 n +0000835512 00000 n +0000837210 00000 n +0000835362 00000 n +0000833741 00000 n +0000836957 00000 n +0000836646 00000 n +0000836802 00000 n +0000836375 00000 n +0000836506 00000 n +0000836553 00000 n +0000836625 00000 n +0000839502 00000 n +0000841387 00000 n +0000839380 00000 n +0000837350 00000 n +0000841261 00000 n +0000840989 00000 n +0000841120 00000 n +0000841167 00000 n +0000841239 00000 n +0000845151 00000 n +0000844791 00000 n +0000841501 00000 n +0000845088 00000 n +0000844933 00000 n +0000981108 00000 n +0000849374 00000 n +0000847245 00000 n +0000846998 00000 n +0000845236 00000 n +0000847120 00000 n +0000851562 00000 n +0000849232 00000 n +0000847356 00000 n +0000851309 00000 n +0000851152 00000 n +0000850801 00000 n +0000850932 00000 n +0000850979 00000 n +0000851051 00000 n +0000851131 00000 n +0000854121 00000 n +0000853873 00000 n +0000851702 00000 n +0000853995 00000 n +0000856369 00000 n +0000856121 00000 n +0000854245 00000 n +0000856243 00000 n +0000856306 00000 n +0000858280 00000 n +0000858095 00000 n +0000856480 00000 n +0000858217 00000 n +0000860329 00000 n +0000860081 00000 n +0000858378 00000 n +0000860203 00000 n +0000860266 00000 n +0000981225 00000 n +0000862674 00000 n +0000862111 00000 n +0000860440 00000 n +0000862233 00000 n +0000862359 00000 n +0000862422 00000 n +0000862485 00000 n +0000862548 00000 n +0000862611 00000 n +0000864677 00000 n +0000867065 00000 n +0000864527 00000 n +0000862798 00000 n +0000866560 00000 n +0000866623 00000 n +0000866686 00000 n +0000866875 00000 n +0000866247 00000 n +0000866403 00000 n +0000865976 00000 n +0000866107 00000 n +0000866154 00000 n +0000866226 00000 n +0000869787 00000 n +0000871086 00000 n +0000869665 00000 n +0000867205 00000 n +0000870959 00000 n +0000870688 00000 n +0000870819 00000 n +0000870866 00000 n +0000870938 00000 n +0000875004 00000 n +0000873952 00000 n +0000871213 00000 n +0000874815 00000 n +0000874118 00000 n +0000874941 00000 n +0000874291 00000 n +0000874466 00000 n +0000874642 00000 n +0000879655 00000 n +0000876643 00000 n +0000875128 00000 n +0000879592 00000 n +0000876897 00000 n +0000877070 00000 n +0000877253 00000 n +0000877421 00000 n +0000877599 00000 n +0000877783 00000 n +0000877957 00000 n +0000878155 00000 n +0000878326 00000 n +0000878497 00000 n +0000878698 00000 n +0000878872 00000 n +0000879051 00000 n +0000879231 00000 n +0000879409 00000 n +0000880309 00000 n +0000880061 00000 n +0000879766 00000 n +0000880183 00000 n +0000981342 00000 n +0000882801 00000 n +0000881609 00000 n +0000880394 00000 n +0000881731 00000 n +0000881857 00000 n +0000881920 00000 n +0000881983 00000 n +0000882046 00000 n +0000882109 00000 n +0000882172 00000 n +0000882235 00000 n +0000882298 00000 n +0000882361 00000 n +0000882424 00000 n +0000882487 00000 n +0000882550 00000 n +0000882613 00000 n +0000882676 00000 n +0000882739 00000 n +0000884079 00000 n +0000883642 00000 n +0000882886 00000 n +0000883764 00000 n +0000884164 00000 n +0000903635 00000 n +0000906328 00000 n +0000906304 00000 n +0000913963 00000 n +0000916468 00000 n +0000916436 00000 n +0000924621 00000 n +0000927258 00000 n +0000927186 00000 n +0000935992 00000 n +0000947784 00000 n +0000950572 00000 n +0000950443 00000 n +0000965178 00000 n +0000979161 00000 n +0000981435 00000 n +0000981553 00000 n +0000981671 00000 n +0000981756 00000 n +0000981834 00000 n +0000986307 00000 n +0000991404 00000 n +0000991443 00000 n +0000991481 00000 n +0000991633 00000 n trailer << /Size 995 /Root 993 0 R /Info 994 0 R -/ID [<3EE0758FC54B3B201367817866E791DA> <3EE0758FC54B3B201367817866E791DA>] +/ID [<1B9D2A4E1C2D929653D0E9F8274BF03F> <1B9D2A4E1C2D929653D0E9F8274BF03F>] >> startxref -991829 +991900 %%EOF diff --git a/ROADMAP b/ROADMAP index 0904cee..149174d 100644 --- a/ROADMAP +++ b/ROADMAP @@ -1,9 +1,10 @@ Must do: - pakete serialize, simulator, utils beschreiben + pakete serialize, simulator beschreiben ausblick schreiben Warn if a file does not exists while trying to open! Literaturangaben komplettieren UML for wrapping ..process(prioqueue(vstask(messagereceive(message)))) + alle API methoden beschreiben About-Text aendern Evtl.: setClassname wegmachen? -> instanceof diff --git a/sources/core/VSAbstractProcess.java b/sources/core/VSAbstractProcess.java index 638ad53..0fc8462 100644 --- a/sources/core/VSAbstractProcess.java +++ b/sources/core/VSAbstractProcess.java @@ -82,7 +82,7 @@ public abstract class VSAbstractProcess extends VSPrefs protected VSRandom random; /** The simulator canvas. */ - protected VSSimulatorCanvas simulatorCanvas; + protected VSSimulatorVisualization simulatorVisualization; /** The random crash task. May be null if there is no such random task. */ protected VSTask randomCrashTask; @@ -196,13 +196,13 @@ public abstract class VSAbstractProcess extends VSPrefs * * @param prefs the simulator's default prefs * @param processNum the process num - * @param simulatorCanvas the simulator canvas + * @param simulatorVisualization the simulator canvas * @param logging the logging object */ public VSAbstractProcess(VSPrefs prefs, int processNum, - VSSimulatorCanvas simulatorCanvas, + VSSimulatorVisualization simulatorVisualization, VSLogging logging) { - init(prefs, processNum, simulatorCanvas, logging); + init(prefs, processNum, simulatorVisualization, logging); } /** @@ -210,21 +210,21 @@ public abstract class VSAbstractProcess extends VSPrefs * * @param prefs the simulator's default prefs * @param processNum the process num - * @param simulatorCanvas the simulator canvas + * @param simulatorVisualization the simulator canvas * @param logging the logging object */ protected void init(VSPrefs prefs, int processNum, - VSSimulatorCanvas simulatorCanvas, VSLogging logging) { + VSSimulatorVisualization simulatorVisualization, VSLogging logging) { /* May be not null if called from deserialization */ if (this.protocolsToReset == null) this.protocolsToReset = new ArrayList(); this.processNum = processNum; this.prefs = prefs; - this.simulatorCanvas = simulatorCanvas; + this.simulatorVisualization = simulatorVisualization; this.logging = logging; - processID = simulatorCanvas.processIDCount(); + processID = simulatorVisualization.processIDCount(); random = new VSRandom(processID*processNum+processID+processNum); tasks = new VSPriorityQueue(); @@ -258,7 +258,7 @@ public abstract class VSAbstractProcess extends VSPrefs vectorTimeHistory = new ArrayList(); crashHistory = new ArrayList(); - final int numProcesses = simulatorCanvas.getNumProcesses(); + final int numProcesses = simulatorVisualization.getNumProcesses(); for (int i = 0; i < numProcesses; ++i) vectorTime.add(new Long(0)); } @@ -274,7 +274,7 @@ public abstract class VSAbstractProcess extends VSPrefs vectorTimeHistory.clear(); crashHistory.clear(); - final int numProcesses = simulatorCanvas.getNumProcesses(); + final int numProcesses = simulatorVisualization.getNumProcesses(); for (int i = numProcesses; i > 0; --i) vectorTime.add(new Long(0)); } @@ -431,8 +431,8 @@ public abstract class VSAbstractProcess extends VSPrefs if (getRandomPercentage() < getInteger("process.prob.crash")) { /* Calculate the random crash time! */ final long crashTime = random.nextLong( - simulatorCanvas.getUntilTime()+1) % - simulatorCanvas.getUntilTime(); + simulatorVisualization.getUntilTime()+1) % + simulatorVisualization.getUntilTime(); return crashTime; } diff --git a/sources/core/VSInternalProcess.java b/sources/core/VSInternalProcess.java index 9311d0a..1da5f20 100644 --- a/sources/core/VSInternalProcess.java +++ b/sources/core/VSInternalProcess.java @@ -48,13 +48,13 @@ public class VSInternalProcess extends VSAbstractProcess { * * @param prefs the simulator's default prefs * @param processNum the process num - * @param simulatorCanvas the simulator canvas + * @param simulatorVisualization the simulator canvas * @param logging the logging object */ public VSInternalProcess(VSPrefs prefs, int processNum, - VSSimulatorCanvas simulatorCanvas, + VSSimulatorVisualization simulatorVisualization, VSLogging logging) { - super(prefs, processNum, simulatorCanvas, logging); + super(prefs, processNum, simulatorVisualization, logging); } /** @@ -80,7 +80,7 @@ public class VSInternalProcess extends VSAbstractProcess { /** * Syncs the process' time. This method is using the clockOffset and * clockVariance variables. This method is called repeatedly from the - * VSSimulatorCanvas in order to update the process' local and global + * VSSimulatorVisualization in order to update the process' local and global * time values. * * @param globalTime the global time. @@ -151,7 +151,7 @@ public class VSInternalProcess extends VSAbstractProcess { */ public synchronized void createRandomCrashTask() { if (!isCrashed) { - VSTaskManager taskManager = simulatorCanvas.getTaskManager(); + VSTaskManager taskManager = simulatorVisualization.getTaskManager(); long crashTime = getARandomCrashTime(); if (crashTime < 0) @@ -303,7 +303,7 @@ public class VSInternalProcess extends VSAbstractProcess { /* Calculate the random outage time! */ long outageTime = globalTime + random.nextLong(durationTime+1) % - simulatorCanvas.getUntilTime(); + simulatorVisualization.getUntilTime(); return outageTime; } @@ -341,7 +341,7 @@ public class VSInternalProcess extends VSAbstractProcess { buffer.append("; "); buffer.append(message.toStringFull()); logg(buffer.toString()); - simulatorCanvas.sendMessage(message); + simulatorVisualization.sendMessage(message); } /** @@ -349,8 +349,8 @@ public class VSInternalProcess extends VSAbstractProcess { * * @return the simulator canvas */ - public VSSimulatorCanvas getSimulatorCanvas() { - return simulatorCanvas; + public VSSimulatorVisualization getSimulatorCanvas() { + return simulatorVisualization; } /** diff --git a/sources/core/VSTaskManager.java b/sources/core/VSTaskManager.java index 2161469..17caba7 100644 --- a/sources/core/VSTaskManager.java +++ b/sources/core/VSTaskManager.java @@ -43,7 +43,7 @@ public class VSTaskManager implements VSSerializable { private static final long serialVersionUID = 1L; /** The simulator canvas. */ - private VSSimulatorCanvas simulatorCanvas; + private VSSimulatorVisualization simulatorVisualization; /** The global tasks. */ private PriorityQueue globalTasks; @@ -64,21 +64,21 @@ public class VSTaskManager implements VSSerializable { * Instantiates a new task manager object. * * @param prefs the simulator's default prefs - * @param simulatorCanvas the simulator canvas + * @param simulatorVisualization the simulator canvas */ - public VSTaskManager(VSPrefs prefs, VSSimulatorCanvas simulatorCanvas) { - init(prefs, simulatorCanvas); + public VSTaskManager(VSPrefs prefs, VSSimulatorVisualization simulatorVisualization) { + init(prefs, simulatorVisualization); } /** * Inits the task manager. * * @param prefs the simulator's default prefs - * @param simulatorCanvas the simulator canvas + * @param simulatorVisualization the simulator canvas */ - private void init(VSPrefs prefs, VSSimulatorCanvas simulatorCanvas) { + private void init(VSPrefs prefs, VSSimulatorVisualization simulatorVisualization) { this.prefs = prefs; - this.simulatorCanvas = simulatorCanvas; + this.simulatorVisualization = simulatorVisualization; /* May be not null if called from deserialization */ if (globalTasks == null) @@ -104,7 +104,7 @@ public class VSTaskManager implements VSSerializable { long globalTime; final long globalOffsetTime = lastGlobalTime + step; boolean redo; - ArrayList processes = simulatorCanvas.getProcesses(); + ArrayList processes = simulatorVisualization.getProcesses(); do { redo = false; @@ -232,7 +232,7 @@ public class VSTaskManager implements VSSerializable { * Resets the task manager. */ public synchronized void reset() { - ArrayList processes = simulatorCanvas.getProcesses(); + ArrayList processes = simulatorVisualization.getProcesses(); PriorityQueue tmp = null; synchronized (processes) { @@ -366,7 +366,7 @@ public class VSTaskManager implements VSSerializable { */ public synchronized ArrayList getLocalTasks() { ArrayList localTasks = new ArrayList(); - ArrayList processes = simulatorCanvas.getProcesses(); + ArrayList processes = simulatorVisualization.getProcesses(); for (VSTask task : fullfilledProgrammedTasks) if (!task.isGlobalTimed()) @@ -476,7 +476,7 @@ public class VSTaskManager implements VSSerializable { buffer.append(prefs.getString("lang.tasks.local")); buffer.append(": "); - ArrayList processes = simulatorCanvas.getProcesses(); + ArrayList processes = simulatorVisualization.getProcesses(); synchronized (processes) { for (VSInternalProcess process : processes) { VSPriorityQueue tasks = process.getTasks(); @@ -517,7 +517,7 @@ public class VSTaskManager implements VSSerializable { serializeThoseTasks.add(task); } - ArrayList processes = simulatorCanvas.getProcesses(); + ArrayList processes = simulatorVisualization.getProcesses(); synchronized (processes) { for (VSInternalProcess process : processes) { @@ -554,7 +554,7 @@ public class VSTaskManager implements VSSerializable { globalTasks.clear(); - ArrayList processes = simulatorCanvas.getProcesses(); + ArrayList processes = simulatorVisualization.getProcesses(); synchronized (processes) { for (VSInternalProcess process : processes) process.getTasks().clear(); diff --git a/sources/events/internal/VSProtocolEvent.java b/sources/events/internal/VSProtocolEvent.java index 4563493..b33ad89 100644 --- a/sources/events/internal/VSProtocolEvent.java +++ b/sources/events/internal/VSProtocolEvent.java @@ -29,7 +29,7 @@ import core.VSInternalProcess; import events.*; import protocols.VSAbstractProtocol; import serialize.VSSerialize; -import simulator.VSSimulatorCanvas; +import simulator.VSSimulatorVisualization; /** * The class VSProtocolEvent, this event is used if a protocol (server or diff --git a/sources/protocols/VSAbstractProtocol.java b/sources/protocols/VSAbstractProtocol.java index cea2856..c812367 100644 --- a/sources/protocols/VSAbstractProtocol.java +++ b/sources/protocols/VSAbstractProtocol.java @@ -30,7 +30,7 @@ import core.*; import events.*; import events.internal.*; import serialize.*; -import simulator.VSSimulatorCanvas; +import simulator.VSSimulatorVisualization; import utils.*; /** @@ -314,7 +314,7 @@ abstract public class VSAbstractProtocol extends VSAbstractEvent { else clientSchedules.add(scheduleTask); - VSSimulatorCanvas canvas = internalProcess.getSimulatorCanvas(); + VSSimulatorVisualization canvas = internalProcess.getSimulatorCanvas(); canvas.getTaskManager().addTask(scheduleTask); } diff --git a/sources/simulator/VSLogging.java b/sources/simulator/VSLogging.java index 4570b0f..e867c6b 100644 --- a/sources/simulator/VSLogging.java +++ b/sources/simulator/VSLogging.java @@ -54,7 +54,7 @@ public class VSLogging { private ArrayList loggingLines; /** The simulator canvas. */ - private VSSimulatorCanvas simulatorCanvas; + private VSSimulatorVisualization simulatorVisualization; /** The logging messages are filtered. */ private boolean isFiltered; @@ -81,10 +81,10 @@ public class VSLogging { /** * Sets the simulator canvas. * - * @param simulatorCanvas the simulator canvas + * @param simulatorVisualization the simulator canvas */ - public void setSimulatorCanvas(VSSimulatorCanvas simulatorCanvas) { - this.simulatorCanvas = simulatorCanvas; + public void setSimulatorCanvas(VSSimulatorVisualization simulatorVisualization) { + this.simulatorVisualization = simulatorVisualization; } /** @@ -102,10 +102,10 @@ public class VSLogging { * @param message the message */ public void logg(String message) { - if (simulatorCanvas == null) + if (simulatorVisualization == null) logg(message, 0); else - logg(message, simulatorCanvas.getTime()); + logg(message, simulatorVisualization.getTime()); } /** diff --git a/sources/simulator/VSSimulator.java b/sources/simulator/VSSimulator.java index feaf197..48959f5 100644 --- a/sources/simulator/VSSimulator.java +++ b/sources/simulator/VSSimulator.java @@ -130,7 +130,7 @@ public class VSSimulator extends JPanel implements VSSerializable { private VSPrefs prefs; /** The simulator canvas. */ - private VSSimulatorCanvas simulatorCanvas; + private VSSimulatorVisualization simulatorVisualization; /** The simulator frame. */ private VSSimulatorFrame simulatorFrame; @@ -548,7 +548,7 @@ public class VSSimulator extends JPanel implements VSSerializable { Integer current[] = { (Integer) model.getValueAt(row, col) }; final JComboBox comboBox = new JComboBox(current); - Integer pids[] = simulatorCanvas.getProcessIDs(); + Integer pids[] = simulatorVisualization.getProcessIDs(); for (Integer pid : pids) comboBox.addItem(pid); @@ -559,7 +559,7 @@ public class VSSimulator extends JPanel implements VSSerializable { if (model.rowExists(row)) { VSTask task = model.removeTaskAtRow(row); VSInternalProcess process = - simulatorCanvas.getProcess(index); + simulatorVisualization.getProcess(index); task.setProcess(process); taskManager.addTask(task, VSTaskManager.PROGRAMMED); if (allProcessesAreSelected()) @@ -629,7 +629,7 @@ public class VSSimulator extends JPanel implements VSSerializable { splitPane1.setDividerLocation((int) (getPaintSize()/2) - 20); - int numProcesses = simulatorCanvas.getNumProcesses(); + int numProcesses = simulatorVisualization.getNumProcesses(); for (int i = 0; i <= numProcesses; ++i) { localTextFields.add("0000"); globalTextFields.add("0000"); @@ -639,7 +639,7 @@ public class VSSimulator extends JPanel implements VSSerializable { localPIDComboBox.setSelectedIndex(0); globalPIDComboBox.setSelectedIndex(0); - thread = new Thread(simulatorCanvas); + thread = new Thread(simulatorVisualization); thread.start(); } @@ -653,15 +653,15 @@ public class VSSimulator extends JPanel implements VSSerializable { splitPaneV = new JSplitPane(); /* Not null if init has been called from the deserialization */ - if (this.simulatorCanvas == null) - simulatorCanvas = new VSSimulatorCanvas(prefs, this, logging); + if (this.simulatorVisualization == null) + simulatorVisualization = new VSSimulatorVisualization(prefs, this, logging); - taskManager = simulatorCanvas.getTaskManager(); - logging.setSimulatorCanvas(simulatorCanvas); + taskManager = simulatorVisualization.getTaskManager(); + logging.setSimulatorCanvas(simulatorVisualization); JPanel canvasPanel = new JPanel(); canvasPanel.setLayout(new GridLayout(1, 1, 3, 3)); - canvasPanel.add(simulatorCanvas); + canvasPanel.add(simulatorVisualization); canvasPanel.setMinimumSize(new Dimension(0, 0)); canvasPanel.setMaximumSize(new Dimension(0, 0)); @@ -722,7 +722,7 @@ public class VSSimulator extends JPanel implements VSSerializable { AbstractButton abstractButton = (AbstractButton) ce.getSource(); ButtonModel buttonModel = abstractButton.getModel(); - simulatorCanvas.showLamport(buttonModel.isSelected()); + simulatorVisualization.showLamport(buttonModel.isSelected()); if (buttonModel.isSelected()) vectorTimeActiveCheckBox.setSelected(false); } @@ -737,7 +737,7 @@ public class VSSimulator extends JPanel implements VSSerializable { AbstractButton abstractButton = (AbstractButton) ce.getSource(); ButtonModel buttonModel = abstractButton.getModel(); - simulatorCanvas.showVectorTime(buttonModel.isSelected()); + simulatorVisualization.showVectorTime(buttonModel.isSelected()); if (buttonModel.isSelected()) lamportActiveCheckBox.setSelected(false); } @@ -752,7 +752,7 @@ public class VSSimulator extends JPanel implements VSSerializable { AbstractButton abstractButton = (AbstractButton) ce.getSource(); ButtonModel buttonModel = abstractButton.getModel(); - simulatorCanvas.isAntiAliased(buttonModel.isSelected()); + simulatorVisualization.isAntiAliased(buttonModel.isSelected()); } }); toolsPanel.add(antiAliasing); @@ -834,11 +834,11 @@ public class VSSimulator extends JPanel implements VSSerializable { globalPIDComboBox = new JComboBox(); lastSelectedProcessNum = 0; - int numProcesses = simulatorCanvas.getNumProcesses(); + int numProcesses = simulatorVisualization.getNumProcesses(); String processString = prefs.getString("lang.process"); for (int i = 0; i < numProcesses; ++i) { - int pid = simulatorCanvas.getProcess(i).getProcessID(); + int pid = simulatorVisualization.getProcess(i).getProcessID(); processesComboBox.addItem(processString + " " + pid); localPIDComboBox.addItem("PID: " + pid); globalPIDComboBox.addItem("PID: " + pid); @@ -883,7 +883,7 @@ public class VSSimulator extends JPanel implements VSSerializable { localPIDComboBox.setSelectedIndex(processNum); globalPIDComboBox.setSelectedIndex(processNum); - if (processNum == simulatorCanvas.getNumProcesses()) { + if (processNum == simulatorVisualization.getNumProcesses()) { tabbedPane.setEnabledAt(1, false); if (tabbedPane.getSelectedIndex() == 1) tabbedPane.setSelectedIndex(0); @@ -892,7 +892,7 @@ public class VSSimulator extends JPanel implements VSSerializable { tabbedPane.setEnabledAt(1, true); } - if (processNum != simulatorCanvas.getNumProcesses()) { + if (processNum != simulatorVisualization.getNumProcesses()) { VSInternalProcess process = getSelectedProcess(); VSProcessEditor processEditor = new VSProcessEditor(prefs, process); @@ -1269,7 +1269,7 @@ public class VSSimulator extends JPanel implements VSSerializable { */ private VSInternalProcess getSelectedProcess() { int processNum = getSelectedProcessNum(); - return simulatorCanvas.getProcess(processNum); + return simulatorVisualization.getProcess(processNum); } /** @@ -1286,11 +1286,11 @@ public class VSSimulator extends JPanel implements VSSerializable { ? localPIDComboBox.getSelectedIndex() : globalPIDComboBox.getSelectedIndex(); - if (processNum == simulatorCanvas.getNumProcesses()) - return simulatorCanvas.getProcessesArray(); + if (processNum == simulatorVisualization.getNumProcesses()) + return simulatorVisualization.getProcessesArray(); ArrayList arr = new ArrayList(); - arr.add(simulatorCanvas.getProcess(processNum)); + arr.add(simulatorVisualization.getProcess(processNum)); return arr; } @@ -1318,11 +1318,11 @@ public class VSSimulator extends JPanel implements VSSerializable { * Update the processes combo box */ private void updateProcessesComboBox() { - int numProcesses = simulatorCanvas.getNumProcesses(); + int numProcesses = simulatorVisualization.getNumProcesses(); String processString = prefs.getString("lang.process"); for (int i = 0; i < numProcesses; ++i) { - int processID = simulatorCanvas.getProcess(i).getProcessID(); + int processID = simulatorVisualization.getProcess(i).getProcessID(); processesComboBox.removeItemAt(i); localPIDComboBox.removeItemAt(i); @@ -1368,8 +1368,8 @@ public class VSSimulator extends JPanel implements VSSerializable { * * @return the simulator canvas */ - public synchronized VSSimulatorCanvas getSimulatorCanvas() { - return simulatorCanvas; + public synchronized VSSimulatorVisualization getSimulatorCanvas() { + return simulatorVisualization; } /** @@ -1385,8 +1385,8 @@ public class VSSimulator extends JPanel implements VSSerializable { * Update from prefs. */ public synchronized void updateFromPrefs() { - simulatorCanvas.setBackground(prefs.getColor("col.background")); - simulatorCanvas.updateFromPrefs(); + simulatorVisualization.setBackground(prefs.getColor("col.background")); + simulatorVisualization.updateFromPrefs(); } /** @@ -1416,7 +1416,7 @@ public class VSSimulator extends JPanel implements VSSerializable { * @param index the index */ public synchronized void addProcessAtIndex(int index) { - int processID = simulatorCanvas.getProcess(index).getProcessID(); + int processID = simulatorVisualization.getProcess(index).getProcessID(); String processString = prefs.getString("lang.process"); localTextFields.add(index, "0000"); @@ -1460,7 +1460,7 @@ public class VSSimulator extends JPanel implements VSSerializable { tabbedPane.setSelectedIndex(selectedIndex); /* Update the 'Variables tab' */ - if (getSelectedProcessNum() != simulatorCanvas.getNumProcesses()) { + if (getSelectedProcessNum() != simulatorVisualization.getNumProcesses()) { VSInternalProcess process = getSelectedProcess(); VSProcessEditor editor = new VSProcessEditor(prefs, process); tabbedPane.setComponentAt(1, editor.getContentPane()); @@ -1502,7 +1502,7 @@ public class VSSimulator extends JPanel implements VSSerializable { /** For later backwards compatibility, to add more stuff */ objectOutputStream.writeObject(new Boolean(false)); - simulatorCanvas.serialize(serialize, objectOutputStream); + simulatorVisualization.serialize(serialize, objectOutputStream); /** For later backwards compatibility, to add more stuff */ objectOutputStream.writeObject(new Boolean(false)); @@ -1526,7 +1526,7 @@ public class VSSimulator extends JPanel implements VSSerializable { /** For later backwards compatibility, to add more stuff */ objectInputStream.readObject(); - simulatorCanvas.deserialize(serialize, objectInputStream); + simulatorVisualization.deserialize(serialize, objectInputStream); /** For later backwards compatibility, to add more stuff */ objectInputStream.readObject(); diff --git a/sources/simulator/VSSimulatorCanvas.java b/sources/simulator/VSSimulatorCanvas.java deleted file mode 100644 index 106e2f8..0000000 --- a/sources/simulator/VSSimulatorCanvas.java +++ /dev/null @@ -1,1820 +0,0 @@ -/* - * Copyright (c) 2008 Paul C. Buetow, vs@dev.buetow.org - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * All icons of the icons/ folder are under a Creative Commons - * Attribution-Noncommercial-Share Alike License a CC-by-nc-sa. - * - * The icon's homepage is http://code.google.com/p/ultimate-gnome/ - */ - -package simulator; - -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import java.io.*; -import java.util.*; -import javax.swing.*; - -import core.*; -import core.time.*; -import events.*; -import events.implementations.*; -import events.internal.*; -import prefs.*; -import prefs.editors.*; -import serialize.*; -import utils.*; - -/** - * The class VSSimulatorCanvas. An instance of this object represents the - * graphical paint area of a simulator. It contains all graphic calculations. - * Also the simulator thread takes place in this class in a loop! This class - * is probably the most cryptic of the whole simulator source code. This is - * this way in order to gain more performance of the painting area! - * - * @author Paul C. Buetow - */ -public class VSSimulatorCanvas extends Canvas - implements Runnable, VSSerializable { - - /** The serial version uid */ - private static final long serialVersionUID = 1L; - - /** The highlighted process. */ - private VSInternalProcess highlightedProcess; - - /** The simulator. */ - private VSSimulator simulator; - - /** The prefs. */ - private VSPrefs prefs; - - /** The logging. */ - private VSLogging logging; - - /** The num processes. */ - private volatile int numProcesses; - - /** The seconds spaceing. */ - private int secondsSpaceing; - - /** The thread sleep. */ - private int threadSleep; - - /** The until time. Until then goes the simulator? */ - private long untilTime; - - /** The simulator is paused. */ - private volatile boolean isPaused = true; - - /** The simulator thread is stopped. */ - private volatile boolean hasThreadStopped = false; - - /** The simulator is finished. */ - private volatile boolean hasFinished = false; - - /** The simulator is resetted. */ - private volatile boolean isResetted = false; - - /** The simulator is anti aliased. */ - private volatile boolean isAntiAliased = false; - - /** The simulator's anti aliasing has changed. */ - private volatile boolean isAntiAliasedChanged = false; - - /** The simulator shows the lamport time. */ - private volatile boolean showLamport = false; - - /** The simulator shows the vector time. */ - private volatile boolean showVectorTime = false; - - /** The pause time. */ - private volatile long pauseTime; - - /** The start time. */ - private volatile long startTime; - - /** The global time. */ - private volatile long time; - - /** The last global time. */ - private volatile long lastTime; - - /** The task manager. */ - private VSTaskManager taskManager; - - /** The message lines. */ - private LinkedList messageLines; - - /** The message lines to remove. */ - private LinkedList messageLinesToRemove; - - /** The processes. */ - private ArrayList processes; - - /** The clock speed. */ - private double clockSpeed; - - /** The clock offset. */ - private double clockOffset; - - /** The simulator time. */ - private long simulatorTime; - - /** The x paint size. */ - double xPaintSize; - - /** The paint size. */ - double paintSize; - - /** The y distance. */ - double yDistance; - - /** The global time x position. */ - double globalTimeXPosition; - - /** The xoffset_plus_xpaintsize. */ - int xoffset_plus_xpaintsize; - - /** The xpaintsize_dividedby_untiltime. */ - double xpaintsize_dividedby_untiltime; - - /** The paint processes offset. */ - int paintProcessesOffset; - - /** The paint secondlines seconds. */ - int paintSecondlinesSeconds; - - /** The paint secondlines line. */ - int paintSecondlinesLine[] = new int[4]; - - /** The paint secondlines y string pos1. */ - int paintSecondlinesYStringPos1; - - /** The paint secondlines y string pos2. */ - int paintSecondlinesYStringPos2; - - /** The paint global time y position. */ - int paintGlobalTimeYPosition; - - /* GFX buffering */ - /** The strategy for buffering. */ - private BufferStrategy strategy; - - /** The graphics object to paint at. */ - private Graphics2D g; - - /** The Constant LINE_WIDTH. */ - private static final int LINE_WIDTH = 5; - - /** The Constant SEPLINE_WIDTH. */ - private static final int SEPLINE_WIDTH = 2; - - /** The Constant XOFFSET. */ - private static final int XOFFSET = 50; - - /** The Constant YOFFSET. */ - private static final int YOFFSET = 30; - - /** The Constant YOUTER_SPACEING. */ - private static final int YOUTER_SPACEING = 15; - - /** The Constant YSEPLINE_SPACEING. */ - private static final int YSEPLINE_SPACEING = 20; - - /** The Constant TEXT_SPACEING. */ - private static final int TEXT_SPACEING = 10; - - /** The Constant ROW_HEIGHT. */ - private static final int ROW_HEIGHT = 14; - - /* Constats, which have to get calculated once after start */ - /** The processline color. */ - private Color processlineColor; - - /** The process secondline color. */ - private Color processSecondlineColor; - - /** The process sepline color. */ - private Color processSeplineColor; - - /** The message arrived color. */ - private Color messageArrivedColor; - - /** The message sending color. */ - private Color messageSendingColor; - - /** The message lost color. */ - private Color messageLostColor; - - /** The background color. */ - private Color backgroundColor; - - /** The message line counter. */ - private long messageLineCounter; - - /** The process counter. Needed for the unique process id's. */ - private int processCounter; - - /** - * The class VSMessageLine, an object of this class represents a message - * line drawn into the painting area. - * - * @author Paul C. Buetow - */ - public class VSMessageLine { - /** The serial version uid */ - private static final long serialVersionUID = 1L; - - /** The receiver process. */ - private VSInternalProcess receiverProcess; - - /** The color. */ - private Color color; - - /** The send time. */ - private long sendTime; - - /** The recv time. */ - private long recvTime; - - /** The sender num. */ - private int senderNum; - - /** The receiver num. */ - private int receiverNum; - - /** The offset1. */ - private int offset1; - - /** The offset2. */ - private int offset2; - - /** The message has arrived. */ - private boolean isArrived; - - /** The message is lost. */ - private boolean isLost; - - /** The x1. */ - private double x1; - - /** The y1. */ - private double y1; - - /** The x2. */ - private double x2; - - /** The y2. */ - private double y2; - - /** The x. */ - private double x; - - /** The y. */ - private double y; - - /** The outage time. */ - private long outageTime; - - /** The z. */ - private long z; - - /** The message line num. */ - private long messageLineNum; - - /** The task. */ - private VSTask task; - - /** - * Instantiates a new VSMessageLine object. - * - * @param receiverProcess the receiver process - * @param sendTime the send time - * @param recvTime the recv time - * @param outageTime the outage time - * @param senderNum the sender num - * @param receiverNum the receiver num - * @param task the task - */ - public VSMessageLine(VSInternalProcess receiverProcess, long sendTime, - long recvTime, long outageTime, int senderNum , - int receiverNum, VSTask task) { - this.receiverProcess = receiverProcess; - this.sendTime = sendTime; - this.recvTime = recvTime; - this.outageTime = outageTime; - this.senderNum = senderNum; - this.receiverNum = receiverNum; - this.isArrived = false; - this.isLost = false; - this.messageLineNum = ++messageLineCounter; - this.task = task; - - if (senderNum > receiverNum) { - //offset1 = 1; - offset2 = LINE_WIDTH; - } else { - offset1 = LINE_WIDTH - 1; - //offset2 = 1; - } - - /* Needed if the message gets lost after 0ms */ - this.x = getTimeXPosition(sendTime); - this.y = getProcessYPosition(senderNum+1) + offset1; - - recalcOnChange(); - paint(); - } - - /** - * Recalc on change. - */ - public void recalcOnChange() { - x1 = getTimeXPosition(sendTime); - y1 = getProcessYPosition(senderNum+1) + offset1; - x2 = getTimeXPosition(recvTime); - y2 = getProcessYPosition(receiverNum+1) + offset2; - - if (isLost) { - x = getTimeXPosition(z); - y = y1 + ( ( (y2-y1) / (x2-x1)) * (x-x1)); - } - - } - - /** - * Draws the message line. - * - * @param g the grpahics object to draw at - * @param globalTime the global time - */ - public void draw(final Graphics2D g, final long globalTime) { - if (isArrived) { - g.setColor(color); - g.drawLine((int) x1, (int) y1, (int) x2, (int) y2); - - } else if (isLost) { - g.setColor(messageLostColor); - g.drawLine((int) x1, (int) y1, (int) x, (int) y); - - } else if (globalTime >= recvTime) { - checkIfMessageIsRelevant(); - isArrived = true; - - if (receiverProcess.isCrashed()) - color = messageLostColor; - else - color = messageArrivedColor; - - draw(g, globalTime); - - } else if (outageTime >= 0 && outageTime <= globalTime) { - checkIfMessageIsRelevant(); - isLost = true; - draw(g, globalTime);; - - } else { - z = globalTime; - x = globalTimeXPosition; - y = y1 + ( ( (y2-y1) / (x2-x1)) * (x-x1)); - g.setColor(messageSendingColor); - g.drawLine((int) x1, (int) y1, (int) x, (int) y); - } - } - - /** - * Checks if the message is relevant. If it's not relevant, then it will - * get removed. - */ - private void checkIfMessageIsRelevant() { - if (prefs.getBoolean("sim.messages.relevant")) { - VSMessageReceiveEvent event = - (VSMessageReceiveEvent) task.getEvent(); - event.init(receiverProcess); - if (!event.isRelevantMessage()) - removeMessageLine(this); - } - } - - /** - * Called if a process within the simulator has been removed at a - * specified index. - * - * @param index the index - * - * @return true, if the sender or the receiver of the message has been - * removed from the simulator. Else false is returned. - */ - public boolean removedAProcessAtIndex(int index) { - if (index == receiverNum || index == senderNum) - return true; - - if (index < receiverNum) - --receiverNum; - - if (index < senderNum) - --senderNum; - - recalcOnChange(); - - return false; - } - - /** - * Gets the message line num. - * - * @return the message line num - */ - public long getMessageLineNum() { - return messageLineNum; - } - - /** - * Checks one line to another if they equal (have the same message line - * id) - * - * @param line the line to compare against - * - * @return true, if they equal - */ - public boolean equals(VSMessageLine line) { - return messageLineNum == line.getMessageLineNum(); - } - - /** - * Gets the task. - * - * @return the task - */ - public VSTask getTask() { - return task; - } - } - - /** - * Instantiates a new VSSimulatorCanvas object. - * - * @param prefs the prefs - * @param simulator the simulator - * @param logging the logging - */ - public VSSimulatorCanvas(VSPrefs prefs, VSSimulator simulator, - VSLogging logging) { - init(prefs, simulator, logging); - } - - /** - * Instantiates inits the VSSimulatorCanvas object. - * - * @param prefs the prefs - * @param simulator the simulator - * @param logging the logging - */ - private void init(VSPrefs prefs, VSSimulator simulator, - VSLogging logging) { - this.prefs = prefs; - this.simulator = simulator; - this.logging = logging; - this.messageLines = new LinkedList(); - this.messageLinesToRemove = new LinkedList(); - - /* May be not null if called from deserialization */ - if (this.taskManager == null) - this.taskManager = new VSTaskManager(prefs, this); - - /* May be not null if called from deserialization */ - if (this.processes == null) { - this.processes = new ArrayList(); - - numProcesses = prefs.getInteger("sim.process.num"); - - for (int i = 0; i < numProcesses; ++i) - processes.add(createProcess(i)); - } - - updateFromPrefs(); - - final VSPrefs finalPrefs = prefs; - final VSSimulator finalSimulator = simulator; - - addMouseListener(new MouseListener() { - public void mouseClicked(MouseEvent me) { - final VSInternalProcess process = getProcessAtYPos(me.getY()); - - if (SwingUtilities.isRightMouseButton(me)) { - ActionListener actionListener = new ActionListener() { - public void actionPerformed(ActionEvent ae) { - String command = ae.getActionCommand(); - if (command.equals( - finalPrefs.getString("lang.process.edit"))) { - editProcess(process); - - } else if (command.equals( - finalPrefs.getString("lang.process.crash"))) { - VSAbstractEvent event = - new VSProcessCrashEvent(); - - taskManager.addTask(new VSTask( - process.getGlobalTime(), - process, event, - VSTask.GLOBAL)); - - } else if (command.equals( - finalPrefs.getString("lang.process.recover"))) { - VSAbstractEvent event = - new VSProcessRecoverEvent(); - - taskManager.addTask(new VSTask( - process.getGlobalTime(), - process, event, - VSTask.GLOBAL)); - - } else if (command.equals( - finalPrefs.getString("lang.process.remove"))) { - removeProcess(process); - - } else if (command.equals( - finalPrefs.getString("lang.process.add.new"))) { - addProcess(); - } - } - }; - - JPopupMenu popup = new JPopupMenu(); - JMenuItem item = null; - - if (process != null) - item = new JMenuItem( - finalPrefs.getString("lang.process.selected") + - ": " + process.getProcessID()); - else - item = new JMenuItem( - finalPrefs.getString("lang.process.not.selected")); - - item.setEnabled(false); - popup.add(item); - popup.addSeparator(); - - item = new JMenuItem( - finalPrefs.getString("lang.process.edit")); - if (process == null) - item.setEnabled(false); - else - item.addActionListener(actionListener); - popup.add(item); - - item = new JMenuItem( - finalPrefs.getString("lang.process.crash")); - - if (process == null || process.isCrashed() || isPaused || - time == 0 || hasFinished) - item.setEnabled(false); - else - item.addActionListener(actionListener); - popup.add(item); - - item = new JMenuItem( - finalPrefs.getString("lang.process.recover")); - - if (process == null || !process.isCrashed() || isPaused || - time == 0 || hasFinished) - item.setEnabled(false); - else - item.addActionListener(actionListener); - popup.add(item); - - item = new JMenuItem( - finalPrefs.getString("lang.process.remove")); - - if (process == null) - item.setEnabled(false); - else - item.addActionListener(actionListener); - popup.add(item); - - popup.addSeparator(); - - final long xPosTime = getXPositionTime(me.getX()); - String timeString = finalPrefs.getString( - "lang.event.add.time") + - " " + xPosTime + "ms"; - - JMenu subMenu = new JMenu( - finalPrefs.getString("lang.event.add.local") - + " " + timeString); - - ArrayList createTasks = - finalSimulator.getCreateTaskObjects(); - - if (process == null) { - subMenu.setEnabled(false); - } else { - JMenu subSubMenu = null; - for (final VSCreateTask createTask : createTasks) { - if (createTask.isDummy()) { - if (subSubMenu != null) - subMenu.add(subSubMenu); - subSubMenu = new JMenu( - createTask.getMenuText()); - } else { - item = new JMenuItem(createTask.getMenuText()); - item.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - VSTask task = - createTask.createTask(process, - xPosTime, - true); - taskManager.addTask( - task, VSTaskManager.PROGRAMMED); - finalSimulator.updateTaskManagerTable(); - } - }); - subSubMenu.add(item); - } - } - } - - popup.add(subMenu); - - subMenu = new JMenu( - finalPrefs.getString("lang.event.add.global") - + " " + timeString); - if (process == null) { - subMenu.setEnabled(false); - } else { - JMenu subSubMenu = null; - for (final VSCreateTask createTask : createTasks) { - if (createTask.isDummy()) { - if (subSubMenu != null) - subMenu.add(subSubMenu); - subSubMenu = new JMenu( - createTask.getMenuText()); - } else { - item = new JMenuItem(createTask.getMenuText()); - item.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - VSTask task = - createTask.createTask(process, - xPosTime, - false); - taskManager.addTask( - task, VSTaskManager.PROGRAMMED); - finalSimulator.updateTaskManagerTable(); - } - }); - subSubMenu.add(item); - } - } - } - - if (finalPrefs.getBoolean("sim.mode.expert")) - popup.add(subMenu); - - popup.addSeparator(); - - item = new JMenuItem( - finalPrefs.getString("lang.process.add.new")); - - item.addActionListener(actionListener); - popup.add(item); - - - popup.show(me.getComponent(), me.getX(), me.getY()); - - } else { - editProcess(process); - } - } - - public void mouseExited(MouseEvent e) { - if (highlightedProcess != null) { - highlightedProcess.highlightOff(); - highlightedProcess = null; - paint(); - } - } - - public void mouseEntered(MouseEvent e) { } - - public void mousePressed(MouseEvent e) { } - - public void mouseReleased(MouseEvent e) { } - - }); - addMouseMotionListener(new MouseMotionListener() { - public void mouseDragged(MouseEvent e) { } - - public void mouseMoved(MouseEvent e) { - VSInternalProcess p = getProcessAtYPos(e.getY()); - - if (p == null) { - if (highlightedProcess != null) { - highlightedProcess.highlightOff(); - highlightedProcess = null; - } - - if (isPaused) - paint(); - - return; - } - - if (highlightedProcess != null) { - if (highlightedProcess.getProcessID() != p.getProcessID()) { - highlightedProcess.highlightOff(); - highlightedProcess = p; - p.highlightOn(); - } - } else { - highlightedProcess = p; - p.highlightOn(); - } - - if (isPaused) - paint(); - } - - }); - - addHierarchyBoundsListener(new HierarchyBoundsListener() { - public void ancestorMoved(HierarchyEvent e) { } - - public void ancestorResized(HierarchyEvent e) { - recalcOnChange(); - } - }); - } - - /** - * This method gets called if the window border of the simulator canvas - * has changed. This method contains very ugly code. But this has to be in - * order to gain performance! - */ - private void recalcOnChange() { - synchronized (processes) { - if (processes.size() == 0) - return; - } - - processlineColor = prefs.getColor("col.process.line"); - processSecondlineColor = prefs.getColor("col.process.secondline"); - processSeplineColor = prefs.getColor("col.process.sepline"); - messageArrivedColor = prefs.getColor("col.message.arrived"); - messageSendingColor = prefs.getColor("col.message.sending"); - messageLostColor = prefs.getColor("col.message.lost"); - backgroundColor = prefs.getColor("col.background"); - - paintSize = simulator.getPaintSize(); - xPaintSize = simulator.getWidth() - - (3 * XOFFSET + simulator.getSplitSize()); - yDistance = (simulator.getPaintSize() - - 2 * (YOFFSET + YOUTER_SPACEING))/ numProcesses; - xpaintsize_dividedby_untiltime = xPaintSize / (double) untilTime; - - - synchronized (messageLines) { - for (VSMessageLine messageLine : messageLines) - messageLine.recalcOnChange(); - } - - /* paintProcesses optimization, precalc things */ - { - xoffset_plus_xpaintsize = XOFFSET + (int) xPaintSize; - if (numProcesses > 1) - paintProcessesOffset = - (int) ((paintSize-2* (YOFFSET+ - YOUTER_SPACEING+YSEPLINE_SPACEING))/ - (numProcesses-1)); - else - paintProcessesOffset = - (int) ((paintSize-2*(YOFFSET+ - YOUTER_SPACEING+YSEPLINE_SPACEING))); - } - - /* paintSecondlines optimization, precalc things */ - { - int yMax = YOFFSET + YOUTER_SPACEING + - (int) (numProcesses * yDistance); - paintSecondlinesSeconds = (int) untilTime / 1000; - paintSecondlinesLine[1] = YOFFSET; - paintSecondlinesLine[3] = yMax; - paintSecondlinesYStringPos1 = paintSecondlinesLine[1] - 5; - paintSecondlinesYStringPos2 = paintSecondlinesLine[3] + 15; - } - - /* paitnGlobalTime optimization, precalc things */ - { - paintGlobalTimeYPosition = YOFFSET + YOUTER_SPACEING + - (int) (numProcesses * yDistance); - } - - if (strategy != null) { - synchronized (strategy) { - g = (Graphics2D) strategy.getDrawGraphics(); - g.setColor(backgroundColor); - if (isAntiAliased) - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - } - } - } - - /** - * Updates the simulator. - * - * @param globalTime the global time - * @param lastGlobalTime the last global time - */ - private void updateSimulator(long globalTime, long lastGlobalTime) { - if (isPaused || hasFinished) - return; - - long lastSimulatorTime = simulatorTime; - long offset = globalTime - lastGlobalTime; - - clockOffset += offset * clockSpeed; - - while (clockOffset >= 1) { - --clockOffset; - ++simulatorTime; - } - - if (simulatorTime > untilTime) - simulatorTime = untilTime; - - offset = simulatorTime - lastSimulatorTime; - - for (long l = 0; l < offset; ++l) - taskManager.runTasks(l, offset, lastSimulatorTime); - - synchronized (processes) { - for (VSInternalProcess process : processes) - process.syncTime(simulatorTime); - } - } - - /** - * Paints the simulator. - */ - public void paint() { - while (getBufferStrategy() == null) { - createBufferStrategy(3); - strategy = getBufferStrategy(); - - if (strategy != null) { - g = (Graphics2D) strategy.getDrawGraphics(); - g.setColor(backgroundColor); - } - } - - synchronized (strategy) { - if (isAntiAliasedChanged) { - if (isAntiAliased) - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - else - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_OFF); - isAntiAliasedChanged = false; - } - - g.fillRect(0, 0, getWidth(), getHeight()); - long globalTime = simulatorTime; - - globalTimeXPosition = getTimeXPosition(globalTime); - paintSecondlines(g); - paintProcesses(g, globalTime); - paintGlobalTime(g, globalTime); - - synchronized (messageLines) { - synchronized (messageLinesToRemove) { - if (messageLinesToRemove.size() > 0) { - for (VSMessageLine removeThis : messageLinesToRemove) - messageLines.remove(removeThis); - messageLinesToRemove.clear(); - } - } - - for (VSMessageLine line : messageLines) - line.draw(g, globalTime); - } - - g.setColor(backgroundColor); - strategy.show(); - } - } - - /** - * Paints the processes. - * - * @param g the graphics object - * @param globalTime the global time - */ - private void paintProcesses(Graphics2D g, long globalTime) { - /* First paint the horizontal process timelines - * Second paint the processes - */ - final int yOffset = YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; - final int xPoints[] = { XOFFSET, xoffset_plus_xpaintsize, - xoffset_plus_xpaintsize, XOFFSET, XOFFSET - }; - final int yPoints[] = { yOffset, yOffset, yOffset + LINE_WIDTH, - yOffset + LINE_WIDTH, yOffset - }; - - synchronized (processes) { - for (VSInternalProcess process : processes) { - final long localTime = process.getTime(); - - g.setColor(process.getColor()); - g.fillPolygon(xPoints, yPoints, 5); - - if (process.hasCrashed()) { - g.setColor(process.getCrashedColor()); - final Long crashHistory[] = process.getCrashHistoryArray(); - final int length = crashHistory.length; - - for (int i = 0; i < length; i += 2) { - final int crashStartPos = - (int) getTimeXPosition( - crashHistory[i].longValue()); - int crashEndPos; - - if (i == length - 1) - crashEndPos = xoffset_plus_xpaintsize; - else - crashEndPos = (int) getTimeXPosition( - crashHistory[i+1].longValue()); - - final int xPointsCrashed[] = { - crashStartPos, crashEndPos, - crashEndPos, crashStartPos, crashStartPos - }; - g.fillPolygon(xPointsCrashed, yPoints, 5); - } - } - - g.setColor(process.getColor()); - g.drawString("P" + process.getProcessID() + ":", XOFFSET - 30, - yPoints[0] + LINE_WIDTH); - - final long tmp = localTime > untilTime ? untilTime : localTime; - final int xPos = 1 + (int) getTimeXPosition(tmp); - final int yStart = yPoints[0] - 14; - final int yEnd = yPoints[0]; - - g.setColor(processlineColor); - g.drawLine(xPos, yStart, xPos, yEnd); - g.drawString(localTime+"ms", xPos + 2, yStart + TEXT_SPACEING); - - if (showLamport) - paintTime(g, process.getLamportTimeArray(), process, - yStart, 25); - else if (showVectorTime) - paintTime(g, process.getVectorTimeArray(), process, - yStart, 20 * numProcesses); - - for (int i = 0; i < 5; ++i) - yPoints[i] += paintProcessesOffset; - } - } - } - - /** - * Paints the time. (e.g. lamport time or vector time) - * - * @param g the graphics object - * @param times the times - * @param process the process - * @param yStart the y start - * @param distance the distance - */ - private void paintTime(final Graphics2D g, final VSTime times[], - final VSInternalProcess process, final int yStart, - final int distance) { - - final int lastPos[] = { -1, -1, -1, -1 }; - - for (VSTime time : times) { - int xPos = (int) getTimeXPosition(time.getGlobalTime()); - int bestRow[] = { -1, -1 }; - - for (int i = 0; i < 4; ++i) { - if (lastPos[i] != -1) { - int diff = xPos - lastPos[i]; - if (diff > distance) { - bestRow[0] = i; - bestRow[1] = -1; - break; - } else if (bestRow[0] == -1) { - bestRow[0] = i; - bestRow[1] = diff; - } else if (diff > bestRow[1]) { - bestRow[0] = i; - bestRow[1] = diff; - } - } else { - bestRow[0] = i; - bestRow[1] = -1; - break; - } - } - - final int row = bestRow[0]; - if (bestRow[1] != -1) - xPos += distance - bestRow[1]; - - g.drawString(time.toString(), xPos + 2, yStart + 3 * - TEXT_SPACEING + row * ROW_HEIGHT); - lastPos[row] = xPos; - } - } - - /** - * Paint the second lines. - * - * @param g the graphics object - */ - private void paintSecondlines(Graphics2D g) { - g.setColor(processSecondlineColor); - - int i; - for (i = 0; i <= paintSecondlinesSeconds; i += secondsSpaceing) { - paintSecondlinesLine[0] = paintSecondlinesLine[2] = - (int) getTimeXPosition(i*1000); - g.drawLine(paintSecondlinesLine[0], paintSecondlinesLine[1], - paintSecondlinesLine[2], paintSecondlinesLine[3]); - - final int xStringPos = paintSecondlinesLine[0] - 5; - g.drawString(i+"s", xStringPos, paintSecondlinesYStringPos1); - if (!showVectorTime && !showLamport) - g.drawString(i+"s", xStringPos, paintSecondlinesYStringPos2); - } - - if (i > paintSecondlinesSeconds) { - paintSecondlinesLine[0] = paintSecondlinesLine[2] = - (int) getTimeXPosition(untilTime); - g.drawLine(paintSecondlinesLine[0], paintSecondlinesLine[1], - paintSecondlinesLine[2], paintSecondlinesLine[3]); - } - } - - /** - * Paints the global time. - * - * @param g the graphics object - * @param globalTime the global time - */ - private void paintGlobalTime(Graphics2D g, long globalTime) { - g.setColor(processSeplineColor); - final int xOffset = (int) globalTimeXPosition; - - final int xPoints[] = { - xOffset, xOffset + SEPLINE_WIDTH, - xOffset + SEPLINE_WIDTH, xOffset, xOffset - }; - final int yOffset = YOFFSET - 8; - final int yPoints[] = { - yOffset, yOffset, paintGlobalTimeYPosition, - paintGlobalTimeYPosition, yOffset - }; - - g.fillPolygon(xPoints, yPoints, 5); - g.drawString(globalTime+"ms", xPoints[1]+1, yPoints[0]+TEXT_SPACEING); - } - - /** - * Gets the process at a specified y pos. - * - * @param yPos the y pos - * - * @return the process at y pos - */ - private VSInternalProcess getProcessAtYPos(int yPos) { - final int reachDistance = (int) (yDistance/3); - int y = YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; - - int yOffset = numProcesses > 1 - ? (int) ((paintSize-2* - (YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))/ - (numProcesses-1)) - : (int) ((paintSize-2* - (YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))); - - for (int i = 0; i < numProcesses; ++i) { - if (yPos < y + reachDistance && yPos > y - reachDistance - - LINE_WIDTH) { - VSInternalProcess process = null; - synchronized (processes) { - process = processes.get(i); - } - return process; - } - y += yOffset; - } - - return null; - } - - /** - * Gets the x position of the given time. - * - * @param time the time - * - * @return the time x position - */ - private double getTimeXPosition(long time) { - return XOFFSET + xpaintsize_dividedby_untiltime * time; - } - - /** - * Gets the time of a given x position - * - * @param xPos the x position - * - * @return the time - */ - private long getXPositionTime(double xPos) { - xPos -= XOFFSET; - - if (xPos <= 0) - return 0; - - else if (xPos >= xPaintSize) - return untilTime; - - return (long) ((untilTime/xPaintSize) * xPos); - } - - /** - * Gets the process y position. - * - * @param i the process num - * - * @return the process y position - */ - private int getProcessYPosition(int i) { - int y; - - if (numProcesses > 1) - y = (int) ((paintSize - - 2 * (YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING))/ - (numProcesses-1)); - else - y = (int) ((paintSize - - 2 * (YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING))); - - return y * (i - 1) + YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; - } - - /** - * Gets the time. - * - * @return the time - */ - public long getTime() { - return simulatorTime; - } - - /** - * Gets the until time. - * - * @return the until time - */ - public long getUntilTime() { - return untilTime; - } - - /** - * Gets the start time. - * - * @return the start time - */ - public long getStartTime() { - return startTime; - } - - /** - * Gets the next process id. - * - * @return the next process id - */ - public int processIDCount() { - return ++processCounter; - } - - /** - * Gets the task manager. - * - * @return the task manager - */ - public VSTaskManager getTaskManager() { - return taskManager; - } - - /** - * Gets the num of processes. - * - * @return the num of processes - */ - public int getNumProcesses() { - return numProcesses; - } - - /** - * Gets the specified process. - * - * @param processNum the process num to get the process of - * - * @return the process - */ - public VSInternalProcess getProcess(int processNum) { - synchronized (processes) { - if (processNum >= processes.size()) - return null; - - return processes.get(processNum); - } - } - - /* (non-Javadoc) - * @see java.lang.Runnable#run() - */ - public void run() { - while (true) { - while (!hasThreadStopped && (isPaused || hasFinished || - isResetted)) { - try { - Thread.sleep(100); - paint(); - - } catch (Exception e) { - System.out.println(e); - } - } - - if (hasThreadStopped) - break; /* Exit the thread */ - - while (!isPaused && !hasThreadStopped) { - try { - Thread.sleep(threadSleep); - } catch (Exception e) { - System.out.println(e); - } - - updateSimulator(time, lastTime); - - if (simulatorTime == untilTime) { - finish(); - break; - } - - paint(); - lastTime = time; - time = System.currentTimeMillis() - startTime; - } - - updateSimulator(time, lastTime); - paint(); - } - } - - /** - * Starts/plays the simulator. - */ - public void play() { - logging.logg(prefs.getString("lang.simulator.started")); - final long currentTime = System.currentTimeMillis(); - - synchronized (processes) { - for (VSInternalProcess p : processes) - p.play(); - } - - if (isResetted) - isResetted = false; - - else if (hasFinished) - hasFinished = false; - - if (isPaused) { - isPaused = false; - startTime += currentTime - pauseTime; - time = currentTime - startTime; - - } else { - startTime = currentTime; - time = 0; - } - - paint(); - } - - /** - * Called if the simulator has finished. - */ - public void finish() { - synchronized (processes) { - for (VSInternalProcess p : processes) - p.finish(); - } - - simulator.finish(); - hasFinished = true; - logging.logg(prefs.getString("lang.simulator.finished")); - paint(); - - if (prefs.getBoolean("sim.periodic")) { - VSSimulatorFrame simulatorFrame = simulator.getSimulatorFrame(); - simulatorFrame.resetCurrentSimulator(); - simulatorFrame.startCurrentSimulator(); - } - } - - /** - * Call this, in order to pause the simulator. - */ - public void pause() { - isPaused = true; - synchronized (processes) { - for (VSInternalProcess p : processes) - p.pause(); - } - - pauseTime = System.currentTimeMillis(); - logging.logg(prefs.getString("lang.simulator.paused")); - paint(); - } - - /** - * Call this, in order to reset the simulator. - */ - public void reset() { - if (!isResetted) { - logging.logg(prefs.getString("lang.simulator.resetted")); - - isResetted = true; - isPaused = false; - hasFinished = false; - startTime = System.currentTimeMillis(); - time = 0; - lastTime = 0; - clockOffset = 0; - simulatorTime = 0; - - synchronized (processes) { - for (VSInternalProcess process : processes) - process.reset(); - } - - /* Reset the task manager AFTER the processes, for the programmed - tasks */ - taskManager.reset(); - - synchronized (processes) { - for (VSInternalProcess process : processes) - process.createRandomCrashTask(); - } - - synchronized (messageLines) { - messageLines.clear(); - } - - synchronized (messageLinesToRemove) { - messageLinesToRemove.clear(); - } - - paint(); - logging.clear(); - } - } - - /** - * Stops the thread of the simulator. - */ - public void stopThread() { - hasThreadStopped = true; - } - - /** - * Checks if the thread has been stopped. - * - * @return true, if is thread has stopped - */ - public boolean hasThreadStopped() { - return hasThreadStopped; - } - - /** - * Sets, if the the lamport time should be shown. It implicitly disables - * the vector time. - * - * @param showLamport true, if the lamport time should be shown - */ - public void showLamport(boolean showLamport) { - this.showLamport = showLamport; - if (isPaused) - paint(); - } - - /** - * Sets, if the vector time should be shown. It implicitly disables the - * lamport time. - * - * @param showVectorTime true, if the vector time should be shown - */ - public void showVectorTime(boolean showVectorTime) { - this.showVectorTime = showVectorTime; - if (isPaused) - paint(); - } - - /** - * Sets if the simulator graphics are anti aliased. - * - * @param isAntiAliased true, if the simulator is anti aliased - */ - public void isAntiAliased(boolean isAntiAliased) { - this.isAntiAliased = isAntiAliased; - this.isAntiAliasedChanged = true; - if (isPaused) - paint(); - } - - /** - * Sends a message. - * - * @param message the message - */ - public void sendMessage(VSMessage message) { - VSTask task = null; - VSAbstractEvent receiveEvent = null; - VSInternalProcess sendingProcess = message.getSendingProcess(); - long deliverTime, outageTime, durationTime; - boolean recvOwn = prefs.getBoolean("sim.message.own.recv"); - - synchronized (processes) { - for (VSInternalProcess receiverProcess : processes) { - if (receiverProcess.equals(sendingProcess)) { - if (recvOwn) { - deliverTime = sendingProcess.getGlobalTime(); - receiveEvent = new VSMessageReceiveEvent(message); - task = new VSTask(deliverTime, receiverProcess, - receiveEvent, VSTask.GLOBAL); - taskManager.addTask(task); - } - - } else { - durationTime = sendingProcess.getDurationTime(); - - if (prefs.getBoolean("sim.message.sendingtime.mean")) { - durationTime += receiverProcess.getDurationTime(); - durationTime /= 2; - } - - deliverTime = sendingProcess.getGlobalTime() + - durationTime; - - if (prefs.getBoolean("sim.message.prob.mean")) - outageTime = sendingProcess.getARandomMessageOutageTime( - durationTime, receiverProcess); - else - outageTime = sendingProcess.getARandomMessageOutageTime( - durationTime, null); - - receiveEvent = new VSMessageReceiveEvent(message); - task = new VSTask(deliverTime, receiverProcess, - receiveEvent, VSTask.GLOBAL); - - /* Only add a 'receiving message' task if the message will - not get lost! */ - if (outageTime == -1) - taskManager.addTask(task); - - synchronized (messageLines) { - messageLines.add( - new VSMessageLine(receiverProcess, - sendingProcess.getGlobalTime(), - deliverTime, outageTime, - sendingProcess.getProcessNum(), - receiverProcess.getProcessNum(), - task)); - } - } - } - } - } - - /** - * Edits the process. - * - * @param processNum the process num - */ - public void editProcess(int processNum) { - synchronized (processes) { - VSInternalProcess process = processes.get(processNum); - /* May be null if another thread changed the processes arraylist - before this process actually called editProcess */ - if (process != null) - editProcess(process); - } - } - - /** - * Edits the process. - * - * @param process the process - */ - public void editProcess(VSInternalProcess process) { - if (process != null) { - process.updatePrefs(); - new VSEditorFrame(prefs, simulator.getSimulatorFrame(), - new VSProcessEditor(prefs, process)); - } - } - - /** - * Gets the processes array. - * - * @return the processes array - */ - public ArrayList getProcessesArray() { - ArrayList arr = new ArrayList(); - - synchronized (processes) { - for (VSInternalProcess process : processes) - arr.add(process); - } - - return arr; - } - - /** - * Gets the processes IDs. - * - * @return the processes IDs - */ - public Integer[] getProcessIDs() { - Integer pids[] = null; - - synchronized (processes) { - pids = new Integer[numProcesses]; - for (int i = 0; i < numProcesses; ++i) - pids[i] = new Integer(processes.get(i).getProcessID()); - } - - return pids; - } - - /** - * Gets the processes. - * - * @return the processes - */ - public ArrayList getProcesses() { - return processes; - } - - /** - * Updates from the prefs. Called by the VSSimulatorEditor if values - * have been saved. - */ - public void updateFromPrefs() { - untilTime = prefs.getInteger("sim.seconds") * 1000; - clockSpeed = prefs.getFloat("sim.clock.speed"); - - secondsSpaceing = (int) (untilTime / 15000); - if (secondsSpaceing == 0) - secondsSpaceing = 1; - - threadSleep = (int) (untilTime / 7500); - if (threadSleep == 0) - threadSleep = 1; - - recalcOnChange(); - } - - /** - * Removes a specific message line from the painting area. - * - * @param messageLine the message line to remove - */ - private void removeMessageLine(VSMessageLine messageLine) { - synchronized (messageLinesToRemove) { - messageLinesToRemove.add(messageLine); - } - } - - /** - * Removes a process from the simulator. - * - * @param process the process - */ - private void removeProcess(VSInternalProcess process) { - if (numProcesses == 1) { - simulator.getSimulatorFrame().removeSimulator(simulator); - - } else { - int index = 0; - synchronized (processes) { - index = processes.indexOf(process); - processes.remove(index); - - for (VSInternalProcess p : processes) - p.removedAProcessAtIndex(index); - - numProcesses = processes.size(); - } - - taskManager.removeTasksOf(process); - simulator.removedAProcessAtIndex(index); - recalcOnChange(); - - ArrayList removeThose = - new ArrayList(); - - synchronized (messageLines) { - for (VSMessageLine line : messageLines) - if (line.removedAProcessAtIndex(index)) - removeThose.add(line); - - for (VSMessageLine line : removeThose) { - VSTask deliverTask = line.getTask(); - - if (deliverTask != null) - taskManager.removeTask(deliverTask); - - messageLines.remove(line); - } - } - } - } - - /** - * Creates a process with the specified num. - * - * @param processNum the process num - * - * @return the new process - */ - private VSInternalProcess createProcess(int processNum) { - VSInternalProcess process = - new VSInternalProcess(prefs, processNum, this, logging); - logging.logg(prefs.getString("lang.process.new") + "; " + process); - return process; - } - - /** - * Adds a new process to the simulator. - * - * @return The process which has been added - */ - private VSInternalProcess addProcess() { - VSInternalProcess newProcess = null; - //int foo = -1; - //System.out.println("ADD " + ++foo); - synchronized (processes) { - //System.out.println("ADD " + ++foo); - numProcesses = processes.size() + 1; - //System.out.println("ADD " + ++foo); - newProcess = createProcess(processes.size()); - //System.out.println("ADD " + ++foo); - //System.out.println("ADD " + ++foo); - } - - //System.out.println("ADD " + ++foo); - addProcess(newProcess); - //System.out.println("ADD " + ++foo); - return newProcess; - } - - /** - * Adds a the given process to the simulator. - * - * @newProcess The process to add - */ - private void addProcess(VSInternalProcess newProcess) { - //int foo = -1; - //System.out.println("ADD_ " + ++foo); - synchronized (processes) { - //System.out.println("ADD_ " + ++foo); - processes.add(newProcess); - - for (VSInternalProcess process : processes) - if (!process.equals(newProcess)) - process.addedAProcess(); - //System.out.println("ADD_ " + ++foo); - } - - //System.out.println("ADD_ " + ++foo); - recalcOnChange(); - //System.out.println("ADD_ " + ++foo); - simulator.addProcessAtIndex(processes.size()-1); - //System.out.println("ADD_ " + ++foo); - } - - /** - * Checks if the simulation is paused. - * - * @return true, if the simulation is paused - */ - boolean isPaused() { - return isPaused; - } - - /** - * Checks if the simulation is resetted. - * - * @return true, if the simulation is resetted - */ - boolean isResetted() { - return isResetted; - } - - /** - * Checks if the simulation has finished - * - * @return true, if the simulation has finished - */ - boolean hasFinished() { - return hasFinished; - } - - /* (non-Javadoc) - * @see serialize.VSSerializable#serialize(serialize.VSSerialize, - * java.io.ObjectOutputStream) - */ - public synchronized void serialize(VSSerialize serialize, - ObjectOutputStream objectOutputStream) - throws IOException { - /** For later backwards compatibility, to add more stuff */ - objectOutputStream.writeObject(new Boolean(false)); - - objectOutputStream.writeObject(new Integer(processCounter)); - - synchronized (processes) { - objectOutputStream.writeObject(new Integer(numProcesses)); - for (VSInternalProcess process : processes) - process.serialize(serialize, objectOutputStream); - } - - taskManager.serialize(serialize, objectOutputStream); - - /** For later backwards compatibility, to add more stuff */ - objectOutputStream.writeObject(new Boolean(false)); - } - - /* (non-Javadoc) - * @see serialize.VSSerializable#deserialize(serialize.VSSerialize, - * java.io.ObjectInputStream) - */ - @SuppressWarnings("unchecked") - public synchronized void deserialize(VSSerialize serialize, - ObjectInputStream objectInputStream) - throws IOException, ClassNotFoundException { - if (VSSerialize.DEBUG) - System.out.println("Deserializing: VSSimulatorCanvas"); - - /** For later backwards compatibility, to add more stuff */ - objectInputStream.readObject(); - - processCounter = ((Integer) objectInputStream.readObject()).intValue(); - - int num = ((Integer) objectInputStream.readObject()).intValue(); - logging.clear(); - - if (num > numProcesses) { - for (int i = numProcesses; i < num; ++i) - addProcess(); - } else { - int oldNum = numProcesses; - for (int i = num; i < oldNum; ++i) - removeProcess(getProcess(0)); - } - - for (int i = 0; i < num; ++i) - processes.get(i).deserialize(serialize, objectInputStream); - - taskManager.deserialize(serialize, objectInputStream); - - /** For later backwards compatibility, to add more stuff */ - objectInputStream.readObject(); - } -} diff --git a/sources/simulator/VSSimulatorFrame.java b/sources/simulator/VSSimulatorFrame.java index b4985ff..a6d261c 100644 --- a/sources/simulator/VSSimulatorFrame.java +++ b/sources/simulator/VSSimulatorFrame.java @@ -158,11 +158,11 @@ public class VSSimulatorFrame extends VSFrame { } else if (sourceText.equals( finalPrefs.getString("lang.save"))) { - VSSimulatorCanvas simulatorCanvas = + VSSimulatorVisualization simulatorVisualization = currentSimulator.getSimulatorCanvas(); - boolean flag = !simulatorCanvas.isPaused() - && !simulatorCanvas.isResetted() - && !simulatorCanvas.hasFinished(); + boolean flag = !simulatorVisualization.isPaused() + && !simulatorVisualization.isResetted() + && !simulatorVisualization.hasFinished(); if (flag) pauseCurrentSimulator(); @@ -175,11 +175,11 @@ public class VSSimulatorFrame extends VSFrame { } else if (sourceText.equals( finalPrefs.getString("lang.saveas"))) { - VSSimulatorCanvas simulatorCanvas = + VSSimulatorVisualization simulatorVisualization = currentSimulator.getSimulatorCanvas(); - boolean flag = !simulatorCanvas.isPaused() - && !simulatorCanvas.isResetted() - && !simulatorCanvas.hasFinished(); + boolean flag = !simulatorVisualization.isPaused() + && !simulatorVisualization.isResetted() + && !simulatorVisualization.hasFinished(); if (flag) pauseCurrentSimulator(); diff --git a/sources/simulator/VSSimulatorVisualization.java b/sources/simulator/VSSimulatorVisualization.java new file mode 100644 index 0000000..ed38004 --- /dev/null +++ b/sources/simulator/VSSimulatorVisualization.java @@ -0,0 +1,1820 @@ +/* + * Copyright (c) 2008 Paul C. Buetow, vs@dev.buetow.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * All icons of the icons/ folder are under a Creative Commons + * Attribution-Noncommercial-Share Alike License a CC-by-nc-sa. + * + * The icon's homepage is http://code.google.com/p/ultimate-gnome/ + */ + +package simulator; + +import java.awt.*; +import java.awt.event.*; +import java.awt.image.*; +import java.io.*; +import java.util.*; +import javax.swing.*; + +import core.*; +import core.time.*; +import events.*; +import events.implementations.*; +import events.internal.*; +import prefs.*; +import prefs.editors.*; +import serialize.*; +import utils.*; + +/** + * The class VSSimulatorVisualization. An instance of this object represents the + * graphical paint area of a simulator. It contains all graphic calculations. + * Also the simulator thread takes place in this class in a loop! This class + * is probably the most cryptic of the whole simulator source code. This is + * this way in order to gain more performance of the painting area! + * + * @author Paul C. Buetow + */ +public class VSSimulatorVisualization extends Canvas + implements Runnable, VSSerializable { + + /** The serial version uid */ + private static final long serialVersionUID = 1L; + + /** The highlighted process. */ + private VSInternalProcess highlightedProcess; + + /** The simulator. */ + private VSSimulator simulator; + + /** The prefs. */ + private VSPrefs prefs; + + /** The logging. */ + private VSLogging logging; + + /** The num processes. */ + private volatile int numProcesses; + + /** The seconds spaceing. */ + private int secondsSpaceing; + + /** The thread sleep. */ + private int threadSleep; + + /** The until time. Until then goes the simulator? */ + private long untilTime; + + /** The simulator is paused. */ + private volatile boolean isPaused = true; + + /** The simulator thread is stopped. */ + private volatile boolean hasThreadStopped = false; + + /** The simulator is finished. */ + private volatile boolean hasFinished = false; + + /** The simulator is resetted. */ + private volatile boolean isResetted = false; + + /** The simulator is anti aliased. */ + private volatile boolean isAntiAliased = false; + + /** The simulator's anti aliasing has changed. */ + private volatile boolean isAntiAliasedChanged = false; + + /** The simulator shows the lamport time. */ + private volatile boolean showLamport = false; + + /** The simulator shows the vector time. */ + private volatile boolean showVectorTime = false; + + /** The pause time. */ + private volatile long pauseTime; + + /** The start time. */ + private volatile long startTime; + + /** The global time. */ + private volatile long time; + + /** The last global time. */ + private volatile long lastTime; + + /** The task manager. */ + private VSTaskManager taskManager; + + /** The message lines. */ + private LinkedList messageLines; + + /** The message lines to remove. */ + private LinkedList messageLinesToRemove; + + /** The processes. */ + private ArrayList processes; + + /** The clock speed. */ + private double clockSpeed; + + /** The clock offset. */ + private double clockOffset; + + /** The simulator time. */ + private long simulatorTime; + + /** The x paint size. */ + double xPaintSize; + + /** The paint size. */ + double paintSize; + + /** The y distance. */ + double yDistance; + + /** The global time x position. */ + double globalTimeXPosition; + + /** The xoffset_plus_xpaintsize. */ + int xoffset_plus_xpaintsize; + + /** The xpaintsize_dividedby_untiltime. */ + double xpaintsize_dividedby_untiltime; + + /** The paint processes offset. */ + int paintProcessesOffset; + + /** The paint secondlines seconds. */ + int paintSecondlinesSeconds; + + /** The paint secondlines line. */ + int paintSecondlinesLine[] = new int[4]; + + /** The paint secondlines y string pos1. */ + int paintSecondlinesYStringPos1; + + /** The paint secondlines y string pos2. */ + int paintSecondlinesYStringPos2; + + /** The paint global time y position. */ + int paintGlobalTimeYPosition; + + /* GFX buffering */ + /** The strategy for buffering. */ + private BufferStrategy strategy; + + /** The graphics object to paint at. */ + private Graphics2D g; + + /** The Constant LINE_WIDTH. */ + private static final int LINE_WIDTH = 5; + + /** The Constant SEPLINE_WIDTH. */ + private static final int SEPLINE_WIDTH = 2; + + /** The Constant XOFFSET. */ + private static final int XOFFSET = 50; + + /** The Constant YOFFSET. */ + private static final int YOFFSET = 30; + + /** The Constant YOUTER_SPACEING. */ + private static final int YOUTER_SPACEING = 15; + + /** The Constant YSEPLINE_SPACEING. */ + private static final int YSEPLINE_SPACEING = 20; + + /** The Constant TEXT_SPACEING. */ + private static final int TEXT_SPACEING = 10; + + /** The Constant ROW_HEIGHT. */ + private static final int ROW_HEIGHT = 14; + + /* Constats, which have to get calculated once after start */ + /** The processline color. */ + private Color processlineColor; + + /** The process secondline color. */ + private Color processSecondlineColor; + + /** The process sepline color. */ + private Color processSeplineColor; + + /** The message arrived color. */ + private Color messageArrivedColor; + + /** The message sending color. */ + private Color messageSendingColor; + + /** The message lost color. */ + private Color messageLostColor; + + /** The background color. */ + private Color backgroundColor; + + /** The message line counter. */ + private long messageLineCounter; + + /** The process counter. Needed for the unique process id's. */ + private int processCounter; + + /** + * The class VSMessageLine, an object of this class represents a message + * line drawn into the painting area. + * + * @author Paul C. Buetow + */ + public class VSMessageLine { + /** The serial version uid */ + private static final long serialVersionUID = 1L; + + /** The receiver process. */ + private VSInternalProcess receiverProcess; + + /** The color. */ + private Color color; + + /** The send time. */ + private long sendTime; + + /** The recv time. */ + private long recvTime; + + /** The sender num. */ + private int senderNum; + + /** The receiver num. */ + private int receiverNum; + + /** The offset1. */ + private int offset1; + + /** The offset2. */ + private int offset2; + + /** The message has arrived. */ + private boolean isArrived; + + /** The message is lost. */ + private boolean isLost; + + /** The x1. */ + private double x1; + + /** The y1. */ + private double y1; + + /** The x2. */ + private double x2; + + /** The y2. */ + private double y2; + + /** The x. */ + private double x; + + /** The y. */ + private double y; + + /** The outage time. */ + private long outageTime; + + /** The z. */ + private long z; + + /** The message line num. */ + private long messageLineNum; + + /** The task. */ + private VSTask task; + + /** + * Instantiates a new VSMessageLine object. + * + * @param receiverProcess the receiver process + * @param sendTime the send time + * @param recvTime the recv time + * @param outageTime the outage time + * @param senderNum the sender num + * @param receiverNum the receiver num + * @param task the task + */ + public VSMessageLine(VSInternalProcess receiverProcess, long sendTime, + long recvTime, long outageTime, int senderNum , + int receiverNum, VSTask task) { + this.receiverProcess = receiverProcess; + this.sendTime = sendTime; + this.recvTime = recvTime; + this.outageTime = outageTime; + this.senderNum = senderNum; + this.receiverNum = receiverNum; + this.isArrived = false; + this.isLost = false; + this.messageLineNum = ++messageLineCounter; + this.task = task; + + if (senderNum > receiverNum) { + //offset1 = 1; + offset2 = LINE_WIDTH; + } else { + offset1 = LINE_WIDTH - 1; + //offset2 = 1; + } + + /* Needed if the message gets lost after 0ms */ + this.x = getTimeXPosition(sendTime); + this.y = getProcessYPosition(senderNum+1) + offset1; + + recalcOnChange(); + paint(); + } + + /** + * Recalc on change. + */ + public void recalcOnChange() { + x1 = getTimeXPosition(sendTime); + y1 = getProcessYPosition(senderNum+1) + offset1; + x2 = getTimeXPosition(recvTime); + y2 = getProcessYPosition(receiverNum+1) + offset2; + + if (isLost) { + x = getTimeXPosition(z); + y = y1 + ( ( (y2-y1) / (x2-x1)) * (x-x1)); + } + + } + + /** + * Draws the message line. + * + * @param g the grpahics object to draw at + * @param globalTime the global time + */ + public void draw(final Graphics2D g, final long globalTime) { + if (isArrived) { + g.setColor(color); + g.drawLine((int) x1, (int) y1, (int) x2, (int) y2); + + } else if (isLost) { + g.setColor(messageLostColor); + g.drawLine((int) x1, (int) y1, (int) x, (int) y); + + } else if (globalTime >= recvTime) { + checkIfMessageIsRelevant(); + isArrived = true; + + if (receiverProcess.isCrashed()) + color = messageLostColor; + else + color = messageArrivedColor; + + draw(g, globalTime); + + } else if (outageTime >= 0 && outageTime <= globalTime) { + checkIfMessageIsRelevant(); + isLost = true; + draw(g, globalTime);; + + } else { + z = globalTime; + x = globalTimeXPosition; + y = y1 + ( ( (y2-y1) / (x2-x1)) * (x-x1)); + g.setColor(messageSendingColor); + g.drawLine((int) x1, (int) y1, (int) x, (int) y); + } + } + + /** + * Checks if the message is relevant. If it's not relevant, then it will + * get removed. + */ + private void checkIfMessageIsRelevant() { + if (prefs.getBoolean("sim.messages.relevant")) { + VSMessageReceiveEvent event = + (VSMessageReceiveEvent) task.getEvent(); + event.init(receiverProcess); + if (!event.isRelevantMessage()) + removeMessageLine(this); + } + } + + /** + * Called if a process within the simulator has been removed at a + * specified index. + * + * @param index the index + * + * @return true, if the sender or the receiver of the message has been + * removed from the simulator. Else false is returned. + */ + public boolean removedAProcessAtIndex(int index) { + if (index == receiverNum || index == senderNum) + return true; + + if (index < receiverNum) + --receiverNum; + + if (index < senderNum) + --senderNum; + + recalcOnChange(); + + return false; + } + + /** + * Gets the message line num. + * + * @return the message line num + */ + public long getMessageLineNum() { + return messageLineNum; + } + + /** + * Checks one line to another if they equal (have the same message line + * id) + * + * @param line the line to compare against + * + * @return true, if they equal + */ + public boolean equals(VSMessageLine line) { + return messageLineNum == line.getMessageLineNum(); + } + + /** + * Gets the task. + * + * @return the task + */ + public VSTask getTask() { + return task; + } + } + + /** + * Instantiates a new VSSimulatorVisualization object. + * + * @param prefs the prefs + * @param simulator the simulator + * @param logging the logging + */ + public VSSimulatorVisualization(VSPrefs prefs, VSSimulator simulator, + VSLogging logging) { + init(prefs, simulator, logging); + } + + /** + * Instantiates inits the VSSimulatorVisualization object. + * + * @param prefs the prefs + * @param simulator the simulator + * @param logging the logging + */ + private void init(VSPrefs prefs, VSSimulator simulator, + VSLogging logging) { + this.prefs = prefs; + this.simulator = simulator; + this.logging = logging; + this.messageLines = new LinkedList(); + this.messageLinesToRemove = new LinkedList(); + + /* May be not null if called from deserialization */ + if (this.taskManager == null) + this.taskManager = new VSTaskManager(prefs, this); + + /* May be not null if called from deserialization */ + if (this.processes == null) { + this.processes = new ArrayList(); + + numProcesses = prefs.getInteger("sim.process.num"); + + for (int i = 0; i < numProcesses; ++i) + processes.add(createProcess(i)); + } + + updateFromPrefs(); + + final VSPrefs finalPrefs = prefs; + final VSSimulator finalSimulator = simulator; + + addMouseListener(new MouseListener() { + public void mouseClicked(MouseEvent me) { + final VSInternalProcess process = getProcessAtYPos(me.getY()); + + if (SwingUtilities.isRightMouseButton(me)) { + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent ae) { + String command = ae.getActionCommand(); + if (command.equals( + finalPrefs.getString("lang.process.edit"))) { + editProcess(process); + + } else if (command.equals( + finalPrefs.getString("lang.process.crash"))) { + VSAbstractEvent event = + new VSProcessCrashEvent(); + + taskManager.addTask(new VSTask( + process.getGlobalTime(), + process, event, + VSTask.GLOBAL)); + + } else if (command.equals( + finalPrefs.getString("lang.process.recover"))) { + VSAbstractEvent event = + new VSProcessRecoverEvent(); + + taskManager.addTask(new VSTask( + process.getGlobalTime(), + process, event, + VSTask.GLOBAL)); + + } else if (command.equals( + finalPrefs.getString("lang.process.remove"))) { + removeProcess(process); + + } else if (command.equals( + finalPrefs.getString("lang.process.add.new"))) { + addProcess(); + } + } + }; + + JPopupMenu popup = new JPopupMenu(); + JMenuItem item = null; + + if (process != null) + item = new JMenuItem( + finalPrefs.getString("lang.process.selected") + + ": " + process.getProcessID()); + else + item = new JMenuItem( + finalPrefs.getString("lang.process.not.selected")); + + item.setEnabled(false); + popup.add(item); + popup.addSeparator(); + + item = new JMenuItem( + finalPrefs.getString("lang.process.edit")); + if (process == null) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + item = new JMenuItem( + finalPrefs.getString("lang.process.crash")); + + if (process == null || process.isCrashed() || isPaused || + time == 0 || hasFinished) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + item = new JMenuItem( + finalPrefs.getString("lang.process.recover")); + + if (process == null || !process.isCrashed() || isPaused || + time == 0 || hasFinished) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + item = new JMenuItem( + finalPrefs.getString("lang.process.remove")); + + if (process == null) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + popup.addSeparator(); + + final long xPosTime = getXPositionTime(me.getX()); + String timeString = finalPrefs.getString( + "lang.event.add.time") + + " " + xPosTime + "ms"; + + JMenu subMenu = new JMenu( + finalPrefs.getString("lang.event.add.local") + + " " + timeString); + + ArrayList createTasks = + finalSimulator.getCreateTaskObjects(); + + if (process == null) { + subMenu.setEnabled(false); + } else { + JMenu subSubMenu = null; + for (final VSCreateTask createTask : createTasks) { + if (createTask.isDummy()) { + if (subSubMenu != null) + subMenu.add(subSubMenu); + subSubMenu = new JMenu( + createTask.getMenuText()); + } else { + item = new JMenuItem(createTask.getMenuText()); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + VSTask task = + createTask.createTask(process, + xPosTime, + true); + taskManager.addTask( + task, VSTaskManager.PROGRAMMED); + finalSimulator.updateTaskManagerTable(); + } + }); + subSubMenu.add(item); + } + } + } + + popup.add(subMenu); + + subMenu = new JMenu( + finalPrefs.getString("lang.event.add.global") + + " " + timeString); + if (process == null) { + subMenu.setEnabled(false); + } else { + JMenu subSubMenu = null; + for (final VSCreateTask createTask : createTasks) { + if (createTask.isDummy()) { + if (subSubMenu != null) + subMenu.add(subSubMenu); + subSubMenu = new JMenu( + createTask.getMenuText()); + } else { + item = new JMenuItem(createTask.getMenuText()); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + VSTask task = + createTask.createTask(process, + xPosTime, + false); + taskManager.addTask( + task, VSTaskManager.PROGRAMMED); + finalSimulator.updateTaskManagerTable(); + } + }); + subSubMenu.add(item); + } + } + } + + if (finalPrefs.getBoolean("sim.mode.expert")) + popup.add(subMenu); + + popup.addSeparator(); + + item = new JMenuItem( + finalPrefs.getString("lang.process.add.new")); + + item.addActionListener(actionListener); + popup.add(item); + + + popup.show(me.getComponent(), me.getX(), me.getY()); + + } else { + editProcess(process); + } + } + + public void mouseExited(MouseEvent e) { + if (highlightedProcess != null) { + highlightedProcess.highlightOff(); + highlightedProcess = null; + paint(); + } + } + + public void mouseEntered(MouseEvent e) { } + + public void mousePressed(MouseEvent e) { } + + public void mouseReleased(MouseEvent e) { } + + }); + addMouseMotionListener(new MouseMotionListener() { + public void mouseDragged(MouseEvent e) { } + + public void mouseMoved(MouseEvent e) { + VSInternalProcess p = getProcessAtYPos(e.getY()); + + if (p == null) { + if (highlightedProcess != null) { + highlightedProcess.highlightOff(); + highlightedProcess = null; + } + + if (isPaused) + paint(); + + return; + } + + if (highlightedProcess != null) { + if (highlightedProcess.getProcessID() != p.getProcessID()) { + highlightedProcess.highlightOff(); + highlightedProcess = p; + p.highlightOn(); + } + } else { + highlightedProcess = p; + p.highlightOn(); + } + + if (isPaused) + paint(); + } + + }); + + addHierarchyBoundsListener(new HierarchyBoundsListener() { + public void ancestorMoved(HierarchyEvent e) { } + + public void ancestorResized(HierarchyEvent e) { + recalcOnChange(); + } + }); + } + + /** + * This method gets called if the window border of the simulator canvas + * has changed. This method contains very ugly code. But this has to be in + * order to gain performance! + */ + private void recalcOnChange() { + synchronized (processes) { + if (processes.size() == 0) + return; + } + + processlineColor = prefs.getColor("col.process.line"); + processSecondlineColor = prefs.getColor("col.process.secondline"); + processSeplineColor = prefs.getColor("col.process.sepline"); + messageArrivedColor = prefs.getColor("col.message.arrived"); + messageSendingColor = prefs.getColor("col.message.sending"); + messageLostColor = prefs.getColor("col.message.lost"); + backgroundColor = prefs.getColor("col.background"); + + paintSize = simulator.getPaintSize(); + xPaintSize = simulator.getWidth() - + (3 * XOFFSET + simulator.getSplitSize()); + yDistance = (simulator.getPaintSize() - + 2 * (YOFFSET + YOUTER_SPACEING))/ numProcesses; + xpaintsize_dividedby_untiltime = xPaintSize / (double) untilTime; + + + synchronized (messageLines) { + for (VSMessageLine messageLine : messageLines) + messageLine.recalcOnChange(); + } + + /* paintProcesses optimization, precalc things */ + { + xoffset_plus_xpaintsize = XOFFSET + (int) xPaintSize; + if (numProcesses > 1) + paintProcessesOffset = + (int) ((paintSize-2* (YOFFSET+ + YOUTER_SPACEING+YSEPLINE_SPACEING))/ + (numProcesses-1)); + else + paintProcessesOffset = + (int) ((paintSize-2*(YOFFSET+ + YOUTER_SPACEING+YSEPLINE_SPACEING))); + } + + /* paintSecondlines optimization, precalc things */ + { + int yMax = YOFFSET + YOUTER_SPACEING + + (int) (numProcesses * yDistance); + paintSecondlinesSeconds = (int) untilTime / 1000; + paintSecondlinesLine[1] = YOFFSET; + paintSecondlinesLine[3] = yMax; + paintSecondlinesYStringPos1 = paintSecondlinesLine[1] - 5; + paintSecondlinesYStringPos2 = paintSecondlinesLine[3] + 15; + } + + /* paitnGlobalTime optimization, precalc things */ + { + paintGlobalTimeYPosition = YOFFSET + YOUTER_SPACEING + + (int) (numProcesses * yDistance); + } + + if (strategy != null) { + synchronized (strategy) { + g = (Graphics2D) strategy.getDrawGraphics(); + g.setColor(backgroundColor); + if (isAntiAliased) + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + } + } + } + + /** + * Updates the simulator. + * + * @param globalTime the global time + * @param lastGlobalTime the last global time + */ + private void updateSimulator(long globalTime, long lastGlobalTime) { + if (isPaused || hasFinished) + return; + + long lastSimulatorTime = simulatorTime; + long offset = globalTime - lastGlobalTime; + + clockOffset += offset * clockSpeed; + + while (clockOffset >= 1) { + --clockOffset; + ++simulatorTime; + } + + if (simulatorTime > untilTime) + simulatorTime = untilTime; + + offset = simulatorTime - lastSimulatorTime; + + for (long l = 0; l < offset; ++l) + taskManager.runTasks(l, offset, lastSimulatorTime); + + synchronized (processes) { + for (VSInternalProcess process : processes) + process.syncTime(simulatorTime); + } + } + + /** + * Paints the simulator. + */ + public void paint() { + while (getBufferStrategy() == null) { + createBufferStrategy(3); + strategy = getBufferStrategy(); + + if (strategy != null) { + g = (Graphics2D) strategy.getDrawGraphics(); + g.setColor(backgroundColor); + } + } + + synchronized (strategy) { + if (isAntiAliasedChanged) { + if (isAntiAliased) + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + else + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + isAntiAliasedChanged = false; + } + + g.fillRect(0, 0, getWidth(), getHeight()); + long globalTime = simulatorTime; + + globalTimeXPosition = getTimeXPosition(globalTime); + paintSecondlines(g); + paintProcesses(g, globalTime); + paintGlobalTime(g, globalTime); + + synchronized (messageLines) { + synchronized (messageLinesToRemove) { + if (messageLinesToRemove.size() > 0) { + for (VSMessageLine removeThis : messageLinesToRemove) + messageLines.remove(removeThis); + messageLinesToRemove.clear(); + } + } + + for (VSMessageLine line : messageLines) + line.draw(g, globalTime); + } + + g.setColor(backgroundColor); + strategy.show(); + } + } + + /** + * Paints the processes. + * + * @param g the graphics object + * @param globalTime the global time + */ + private void paintProcesses(Graphics2D g, long globalTime) { + /* First paint the horizontal process timelines + * Second paint the processes + */ + final int yOffset = YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; + final int xPoints[] = { XOFFSET, xoffset_plus_xpaintsize, + xoffset_plus_xpaintsize, XOFFSET, XOFFSET + }; + final int yPoints[] = { yOffset, yOffset, yOffset + LINE_WIDTH, + yOffset + LINE_WIDTH, yOffset + }; + + synchronized (processes) { + for (VSInternalProcess process : processes) { + final long localTime = process.getTime(); + + g.setColor(process.getColor()); + g.fillPolygon(xPoints, yPoints, 5); + + if (process.hasCrashed()) { + g.setColor(process.getCrashedColor()); + final Long crashHistory[] = process.getCrashHistoryArray(); + final int length = crashHistory.length; + + for (int i = 0; i < length; i += 2) { + final int crashStartPos = + (int) getTimeXPosition( + crashHistory[i].longValue()); + int crashEndPos; + + if (i == length - 1) + crashEndPos = xoffset_plus_xpaintsize; + else + crashEndPos = (int) getTimeXPosition( + crashHistory[i+1].longValue()); + + final int xPointsCrashed[] = { + crashStartPos, crashEndPos, + crashEndPos, crashStartPos, crashStartPos + }; + g.fillPolygon(xPointsCrashed, yPoints, 5); + } + } + + g.setColor(process.getColor()); + g.drawString("P" + process.getProcessID() + ":", XOFFSET - 30, + yPoints[0] + LINE_WIDTH); + + final long tmp = localTime > untilTime ? untilTime : localTime; + final int xPos = 1 + (int) getTimeXPosition(tmp); + final int yStart = yPoints[0] - 14; + final int yEnd = yPoints[0]; + + g.setColor(processlineColor); + g.drawLine(xPos, yStart, xPos, yEnd); + g.drawString(localTime+"ms", xPos + 2, yStart + TEXT_SPACEING); + + if (showLamport) + paintTime(g, process.getLamportTimeArray(), process, + yStart, 25); + else if (showVectorTime) + paintTime(g, process.getVectorTimeArray(), process, + yStart, 20 * numProcesses); + + for (int i = 0; i < 5; ++i) + yPoints[i] += paintProcessesOffset; + } + } + } + + /** + * Paints the time. (e.g. lamport time or vector time) + * + * @param g the graphics object + * @param times the times + * @param process the process + * @param yStart the y start + * @param distance the distance + */ + private void paintTime(final Graphics2D g, final VSTime times[], + final VSInternalProcess process, final int yStart, + final int distance) { + + final int lastPos[] = { -1, -1, -1, -1 }; + + for (VSTime time : times) { + int xPos = (int) getTimeXPosition(time.getGlobalTime()); + int bestRow[] = { -1, -1 }; + + for (int i = 0; i < 4; ++i) { + if (lastPos[i] != -1) { + int diff = xPos - lastPos[i]; + if (diff > distance) { + bestRow[0] = i; + bestRow[1] = -1; + break; + } else if (bestRow[0] == -1) { + bestRow[0] = i; + bestRow[1] = diff; + } else if (diff > bestRow[1]) { + bestRow[0] = i; + bestRow[1] = diff; + } + } else { + bestRow[0] = i; + bestRow[1] = -1; + break; + } + } + + final int row = bestRow[0]; + if (bestRow[1] != -1) + xPos += distance - bestRow[1]; + + g.drawString(time.toString(), xPos + 2, yStart + 3 * + TEXT_SPACEING + row * ROW_HEIGHT); + lastPos[row] = xPos; + } + } + + /** + * Paint the second lines. + * + * @param g the graphics object + */ + private void paintSecondlines(Graphics2D g) { + g.setColor(processSecondlineColor); + + int i; + for (i = 0; i <= paintSecondlinesSeconds; i += secondsSpaceing) { + paintSecondlinesLine[0] = paintSecondlinesLine[2] = + (int) getTimeXPosition(i*1000); + g.drawLine(paintSecondlinesLine[0], paintSecondlinesLine[1], + paintSecondlinesLine[2], paintSecondlinesLine[3]); + + final int xStringPos = paintSecondlinesLine[0] - 5; + g.drawString(i+"s", xStringPos, paintSecondlinesYStringPos1); + if (!showVectorTime && !showLamport) + g.drawString(i+"s", xStringPos, paintSecondlinesYStringPos2); + } + + if (i > paintSecondlinesSeconds) { + paintSecondlinesLine[0] = paintSecondlinesLine[2] = + (int) getTimeXPosition(untilTime); + g.drawLine(paintSecondlinesLine[0], paintSecondlinesLine[1], + paintSecondlinesLine[2], paintSecondlinesLine[3]); + } + } + + /** + * Paints the global time. + * + * @param g the graphics object + * @param globalTime the global time + */ + private void paintGlobalTime(Graphics2D g, long globalTime) { + g.setColor(processSeplineColor); + final int xOffset = (int) globalTimeXPosition; + + final int xPoints[] = { + xOffset, xOffset + SEPLINE_WIDTH, + xOffset + SEPLINE_WIDTH, xOffset, xOffset + }; + final int yOffset = YOFFSET - 8; + final int yPoints[] = { + yOffset, yOffset, paintGlobalTimeYPosition, + paintGlobalTimeYPosition, yOffset + }; + + g.fillPolygon(xPoints, yPoints, 5); + g.drawString(globalTime+"ms", xPoints[1]+1, yPoints[0]+TEXT_SPACEING); + } + + /** + * Gets the process at a specified y pos. + * + * @param yPos the y pos + * + * @return the process at y pos + */ + private VSInternalProcess getProcessAtYPos(int yPos) { + final int reachDistance = (int) (yDistance/3); + int y = YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; + + int yOffset = numProcesses > 1 + ? (int) ((paintSize-2* + (YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))/ + (numProcesses-1)) + : (int) ((paintSize-2* + (YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))); + + for (int i = 0; i < numProcesses; ++i) { + if (yPos < y + reachDistance && yPos > y - reachDistance - + LINE_WIDTH) { + VSInternalProcess process = null; + synchronized (processes) { + process = processes.get(i); + } + return process; + } + y += yOffset; + } + + return null; + } + + /** + * Gets the x position of the given time. + * + * @param time the time + * + * @return the time x position + */ + private double getTimeXPosition(long time) { + return XOFFSET + xpaintsize_dividedby_untiltime * time; + } + + /** + * Gets the time of a given x position + * + * @param xPos the x position + * + * @return the time + */ + private long getXPositionTime(double xPos) { + xPos -= XOFFSET; + + if (xPos <= 0) + return 0; + + else if (xPos >= xPaintSize) + return untilTime; + + return (long) ((untilTime/xPaintSize) * xPos); + } + + /** + * Gets the process y position. + * + * @param i the process num + * + * @return the process y position + */ + private int getProcessYPosition(int i) { + int y; + + if (numProcesses > 1) + y = (int) ((paintSize - + 2 * (YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING))/ + (numProcesses-1)); + else + y = (int) ((paintSize - + 2 * (YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING))); + + return y * (i - 1) + YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; + } + + /** + * Gets the time. + * + * @return the time + */ + public long getTime() { + return simulatorTime; + } + + /** + * Gets the until time. + * + * @return the until time + */ + public long getUntilTime() { + return untilTime; + } + + /** + * Gets the start time. + * + * @return the start time + */ + public long getStartTime() { + return startTime; + } + + /** + * Gets the next process id. + * + * @return the next process id + */ + public int processIDCount() { + return ++processCounter; + } + + /** + * Gets the task manager. + * + * @return the task manager + */ + public VSTaskManager getTaskManager() { + return taskManager; + } + + /** + * Gets the num of processes. + * + * @return the num of processes + */ + public int getNumProcesses() { + return numProcesses; + } + + /** + * Gets the specified process. + * + * @param processNum the process num to get the process of + * + * @return the process + */ + public VSInternalProcess getProcess(int processNum) { + synchronized (processes) { + if (processNum >= processes.size()) + return null; + + return processes.get(processNum); + } + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void run() { + while (true) { + while (!hasThreadStopped && (isPaused || hasFinished || + isResetted)) { + try { + Thread.sleep(100); + paint(); + + } catch (Exception e) { + System.out.println(e); + } + } + + if (hasThreadStopped) + break; /* Exit the thread */ + + while (!isPaused && !hasThreadStopped) { + try { + Thread.sleep(threadSleep); + } catch (Exception e) { + System.out.println(e); + } + + updateSimulator(time, lastTime); + + if (simulatorTime == untilTime) { + finish(); + break; + } + + paint(); + lastTime = time; + time = System.currentTimeMillis() - startTime; + } + + updateSimulator(time, lastTime); + paint(); + } + } + + /** + * Starts/plays the simulator. + */ + public void play() { + logging.logg(prefs.getString("lang.simulator.started")); + final long currentTime = System.currentTimeMillis(); + + synchronized (processes) { + for (VSInternalProcess p : processes) + p.play(); + } + + if (isResetted) + isResetted = false; + + else if (hasFinished) + hasFinished = false; + + if (isPaused) { + isPaused = false; + startTime += currentTime - pauseTime; + time = currentTime - startTime; + + } else { + startTime = currentTime; + time = 0; + } + + paint(); + } + + /** + * Called if the simulator has finished. + */ + public void finish() { + synchronized (processes) { + for (VSInternalProcess p : processes) + p.finish(); + } + + simulator.finish(); + hasFinished = true; + logging.logg(prefs.getString("lang.simulator.finished")); + paint(); + + if (prefs.getBoolean("sim.periodic")) { + VSSimulatorFrame simulatorFrame = simulator.getSimulatorFrame(); + simulatorFrame.resetCurrentSimulator(); + simulatorFrame.startCurrentSimulator(); + } + } + + /** + * Call this, in order to pause the simulator. + */ + public void pause() { + isPaused = true; + synchronized (processes) { + for (VSInternalProcess p : processes) + p.pause(); + } + + pauseTime = System.currentTimeMillis(); + logging.logg(prefs.getString("lang.simulator.paused")); + paint(); + } + + /** + * Call this, in order to reset the simulator. + */ + public void reset() { + if (!isResetted) { + logging.logg(prefs.getString("lang.simulator.resetted")); + + isResetted = true; + isPaused = false; + hasFinished = false; + startTime = System.currentTimeMillis(); + time = 0; + lastTime = 0; + clockOffset = 0; + simulatorTime = 0; + + synchronized (processes) { + for (VSInternalProcess process : processes) + process.reset(); + } + + /* Reset the task manager AFTER the processes, for the programmed + tasks */ + taskManager.reset(); + + synchronized (processes) { + for (VSInternalProcess process : processes) + process.createRandomCrashTask(); + } + + synchronized (messageLines) { + messageLines.clear(); + } + + synchronized (messageLinesToRemove) { + messageLinesToRemove.clear(); + } + + paint(); + logging.clear(); + } + } + + /** + * Stops the thread of the simulator. + */ + public void stopThread() { + hasThreadStopped = true; + } + + /** + * Checks if the thread has been stopped. + * + * @return true, if is thread has stopped + */ + public boolean hasThreadStopped() { + return hasThreadStopped; + } + + /** + * Sets, if the the lamport time should be shown. It implicitly disables + * the vector time. + * + * @param showLamport true, if the lamport time should be shown + */ + public void showLamport(boolean showLamport) { + this.showLamport = showLamport; + if (isPaused) + paint(); + } + + /** + * Sets, if the vector time should be shown. It implicitly disables the + * lamport time. + * + * @param showVectorTime true, if the vector time should be shown + */ + public void showVectorTime(boolean showVectorTime) { + this.showVectorTime = showVectorTime; + if (isPaused) + paint(); + } + + /** + * Sets if the simulator graphics are anti aliased. + * + * @param isAntiAliased true, if the simulator is anti aliased + */ + public void isAntiAliased(boolean isAntiAliased) { + this.isAntiAliased = isAntiAliased; + this.isAntiAliasedChanged = true; + if (isPaused) + paint(); + } + + /** + * Sends a message. + * + * @param message the message + */ + public void sendMessage(VSMessage message) { + VSTask task = null; + VSAbstractEvent receiveEvent = null; + VSInternalProcess sendingProcess = message.getSendingProcess(); + long deliverTime, outageTime, durationTime; + boolean recvOwn = prefs.getBoolean("sim.message.own.recv"); + + synchronized (processes) { + for (VSInternalProcess receiverProcess : processes) { + if (receiverProcess.equals(sendingProcess)) { + if (recvOwn) { + deliverTime = sendingProcess.getGlobalTime(); + receiveEvent = new VSMessageReceiveEvent(message); + task = new VSTask(deliverTime, receiverProcess, + receiveEvent, VSTask.GLOBAL); + taskManager.addTask(task); + } + + } else { + durationTime = sendingProcess.getDurationTime(); + + if (prefs.getBoolean("sim.message.sendingtime.mean")) { + durationTime += receiverProcess.getDurationTime(); + durationTime /= 2; + } + + deliverTime = sendingProcess.getGlobalTime() + + durationTime; + + if (prefs.getBoolean("sim.message.prob.mean")) + outageTime = sendingProcess.getARandomMessageOutageTime( + durationTime, receiverProcess); + else + outageTime = sendingProcess.getARandomMessageOutageTime( + durationTime, null); + + receiveEvent = new VSMessageReceiveEvent(message); + task = new VSTask(deliverTime, receiverProcess, + receiveEvent, VSTask.GLOBAL); + + /* Only add a 'receiving message' task if the message will + not get lost! */ + if (outageTime == -1) + taskManager.addTask(task); + + synchronized (messageLines) { + messageLines.add( + new VSMessageLine(receiverProcess, + sendingProcess.getGlobalTime(), + deliverTime, outageTime, + sendingProcess.getProcessNum(), + receiverProcess.getProcessNum(), + task)); + } + } + } + } + } + + /** + * Edits the process. + * + * @param processNum the process num + */ + public void editProcess(int processNum) { + synchronized (processes) { + VSInternalProcess process = processes.get(processNum); + /* May be null if another thread changed the processes arraylist + before this process actually called editProcess */ + if (process != null) + editProcess(process); + } + } + + /** + * Edits the process. + * + * @param process the process + */ + public void editProcess(VSInternalProcess process) { + if (process != null) { + process.updatePrefs(); + new VSEditorFrame(prefs, simulator.getSimulatorFrame(), + new VSProcessEditor(prefs, process)); + } + } + + /** + * Gets the processes array. + * + * @return the processes array + */ + public ArrayList getProcessesArray() { + ArrayList arr = new ArrayList(); + + synchronized (processes) { + for (VSInternalProcess process : processes) + arr.add(process); + } + + return arr; + } + + /** + * Gets the processes IDs. + * + * @return the processes IDs + */ + public Integer[] getProcessIDs() { + Integer pids[] = null; + + synchronized (processes) { + pids = new Integer[numProcesses]; + for (int i = 0; i < numProcesses; ++i) + pids[i] = new Integer(processes.get(i).getProcessID()); + } + + return pids; + } + + /** + * Gets the processes. + * + * @return the processes + */ + public ArrayList getProcesses() { + return processes; + } + + /** + * Updates from the prefs. Called by the VSSimulatorEditor if values + * have been saved. + */ + public void updateFromPrefs() { + untilTime = prefs.getInteger("sim.seconds") * 1000; + clockSpeed = prefs.getFloat("sim.clock.speed"); + + secondsSpaceing = (int) (untilTime / 15000); + if (secondsSpaceing == 0) + secondsSpaceing = 1; + + threadSleep = (int) (untilTime / 7500); + if (threadSleep == 0) + threadSleep = 1; + + recalcOnChange(); + } + + /** + * Removes a specific message line from the painting area. + * + * @param messageLine the message line to remove + */ + private void removeMessageLine(VSMessageLine messageLine) { + synchronized (messageLinesToRemove) { + messageLinesToRemove.add(messageLine); + } + } + + /** + * Removes a process from the simulator. + * + * @param process the process + */ + private void removeProcess(VSInternalProcess process) { + if (numProcesses == 1) { + simulator.getSimulatorFrame().removeSimulator(simulator); + + } else { + int index = 0; + synchronized (processes) { + index = processes.indexOf(process); + processes.remove(index); + + for (VSInternalProcess p : processes) + p.removedAProcessAtIndex(index); + + numProcesses = processes.size(); + } + + taskManager.removeTasksOf(process); + simulator.removedAProcessAtIndex(index); + recalcOnChange(); + + ArrayList removeThose = + new ArrayList(); + + synchronized (messageLines) { + for (VSMessageLine line : messageLines) + if (line.removedAProcessAtIndex(index)) + removeThose.add(line); + + for (VSMessageLine line : removeThose) { + VSTask deliverTask = line.getTask(); + + if (deliverTask != null) + taskManager.removeTask(deliverTask); + + messageLines.remove(line); + } + } + } + } + + /** + * Creates a process with the specified num. + * + * @param processNum the process num + * + * @return the new process + */ + private VSInternalProcess createProcess(int processNum) { + VSInternalProcess process = + new VSInternalProcess(prefs, processNum, this, logging); + logging.logg(prefs.getString("lang.process.new") + "; " + process); + return process; + } + + /** + * Adds a new process to the simulator. + * + * @return The process which has been added + */ + private VSInternalProcess addProcess() { + VSInternalProcess newProcess = null; + //int foo = -1; + //System.out.println("ADD " + ++foo); + synchronized (processes) { + //System.out.println("ADD " + ++foo); + numProcesses = processes.size() + 1; + //System.out.println("ADD " + ++foo); + newProcess = createProcess(processes.size()); + //System.out.println("ADD " + ++foo); + //System.out.println("ADD " + ++foo); + } + + //System.out.println("ADD " + ++foo); + addProcess(newProcess); + //System.out.println("ADD " + ++foo); + return newProcess; + } + + /** + * Adds a the given process to the simulator. + * + * @newProcess The process to add + */ + private void addProcess(VSInternalProcess newProcess) { + //int foo = -1; + //System.out.println("ADD_ " + ++foo); + synchronized (processes) { + //System.out.println("ADD_ " + ++foo); + processes.add(newProcess); + + for (VSInternalProcess process : processes) + if (!process.equals(newProcess)) + process.addedAProcess(); + //System.out.println("ADD_ " + ++foo); + } + + //System.out.println("ADD_ " + ++foo); + recalcOnChange(); + //System.out.println("ADD_ " + ++foo); + simulator.addProcessAtIndex(processes.size()-1); + //System.out.println("ADD_ " + ++foo); + } + + /** + * Checks if the simulation is paused. + * + * @return true, if the simulation is paused + */ + boolean isPaused() { + return isPaused; + } + + /** + * Checks if the simulation is resetted. + * + * @return true, if the simulation is resetted + */ + boolean isResetted() { + return isResetted; + } + + /** + * Checks if the simulation has finished + * + * @return true, if the simulation has finished + */ + boolean hasFinished() { + return hasFinished; + } + + /* (non-Javadoc) + * @see serialize.VSSerializable#serialize(serialize.VSSerialize, + * java.io.ObjectOutputStream) + */ + public synchronized void serialize(VSSerialize serialize, + ObjectOutputStream objectOutputStream) + throws IOException { + /** For later backwards compatibility, to add more stuff */ + objectOutputStream.writeObject(new Boolean(false)); + + objectOutputStream.writeObject(new Integer(processCounter)); + + synchronized (processes) { + objectOutputStream.writeObject(new Integer(numProcesses)); + for (VSInternalProcess process : processes) + process.serialize(serialize, objectOutputStream); + } + + taskManager.serialize(serialize, objectOutputStream); + + /** For later backwards compatibility, to add more stuff */ + objectOutputStream.writeObject(new Boolean(false)); + } + + /* (non-Javadoc) + * @see serialize.VSSerializable#deserialize(serialize.VSSerialize, + * java.io.ObjectInputStream) + */ + @SuppressWarnings("unchecked") + public synchronized void deserialize(VSSerialize serialize, + ObjectInputStream objectInputStream) + throws IOException, ClassNotFoundException { + if (VSSerialize.DEBUG) + System.out.println("Deserializing: VSSimulatorVisualization"); + + /** For later backwards compatibility, to add more stuff */ + objectInputStream.readObject(); + + processCounter = ((Integer) objectInputStream.readObject()).intValue(); + + int num = ((Integer) objectInputStream.readObject()).intValue(); + logging.clear(); + + if (num > numProcesses) { + for (int i = numProcesses; i < num; ++i) + addProcess(); + } else { + int oldNum = numProcesses; + for (int i = num; i < oldNum; ++i) + removeProcess(getProcess(0)); + } + + for (int i = 0; i < num; ++i) + processes.get(i).deserialize(serialize, objectInputStream); + + taskManager.deserialize(serialize, objectInputStream); + + /** For later backwards compatibility, to add more stuff */ + objectInputStream.readObject(); + } +} -- cgit v1.2.3