From 3d5ba4ed7b6f0d79ea02f44eca51d13b03663510 Mon Sep 17 00:00:00 2001 From: lempinen Date: Fri, 7 Oct 2011 13:46:18 +0000 Subject: [PATCH] Issue view update: more checks working for dependencies. Issues are not updated when simply changing an equation. You need to change also the equation type. git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@22573 ac1ea38d-2e2b-0410-8846-a27921b304fc --- org.simantics.sysdyn.ontology/graph.tg | Bin 68105 -> 68458 bytes .../graph/Sysdyn.pgraph | 4 +- .../graph/Validation.pgraph | 18 +- .../org/simantics/sysdyn/SysdynResource.java | 21 +- org.simantics.sysdyn.ui/adapters.xml | 2 +- org.simantics.sysdyn.ui/plugin.xml | 6 + .../sysdyn/ui/project/SysdynProject.java | 97 ++----- .../sysdyn/ui/properties/EquationTab.java | 6 + .../widgets/expressions/BasicExpression.java | 16 +- .../widgets/expressions/StockExpression.java | 6 +- .../expressions/WithLookupExpression.java | 16 +- .../simantics/sysdyn/ui/utils/ModelUtils.java | 11 +- .../ui/validation/ActiveIssueSources.java | 43 --- .../ui/validation/DependencyFunction.java | 261 ++++++++++++++++++ .../ui/validation/DependencyIssueSource.java | 78 ------ .../ui/validation/DependencyIssues.java | 30 -- .../ui/validation/DependencySynchronizer.java | 111 -------- .../ui/validation/DependencyValidator.java | 69 ----- .../mdlImport/mdlElements/Variable.java | 30 +- 19 files changed, 382 insertions(+), 443 deletions(-) delete mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ActiveIssueSources.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java delete mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyIssueSource.java delete mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyIssues.java delete mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencySynchronizer.java delete mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyValidator.java diff --git a/org.simantics.sysdyn.ontology/graph.tg b/org.simantics.sysdyn.ontology/graph.tg index bb64744d19f0db3ad0cc8a960dbe9c681887a957..75a536254a291bf81c15887ebe1d0322e376c9ad 100644 GIT binary patch literal 68458 zcmd752bg44)iqqVs(NxB7=~yufDAC9b0AKJRwgjhLq@3Su9+#Q?rN&5CxM8P%mX5l z44|keiinC5L`;ZTF(%JrRSyi6K%1MNKkFILbEaH)bW zfJ+o~0_;-I0kBg+JHQSFZ2;R9v;u5X&;l^3pc$QcLcl)jOBaupYo!5}S0383VYpNp zfOL(p<5t#c)fzi-oZ#sWpIjO$q2m-LKNMmD!&g*?N|0V7ExFC@OnJ2eq|8fmst#5vC~&|z8c0)4l7M`ZfLuqf?*)~rHD z2N(t7q&u-Bu}FTT0ArCnr2u1*{6GQ5BKfR< zsq}2+f80Dxo>UFbhPwpFDZjaj^%70rSDtg@eFB;oPWYfeIj39o2qy1uXqfgh0{0zj zPLO`|*=c6@w9tph?0JqEnS57t*#WF0$#?ud&XeTZejl?b`Ig_uWJ?<;Zf=_`ju2f3_p zZk0xGN+cg>M76|GSvkZvA4E$zVwf&_F3ZXHV3Ga7n6>FS`DKypGu9v@_MgJ$23mPq z{zCyz%fBn&Y56w=JT3o60Z+?k6ks&7|E&PSnU%%h2UBp?42<^I%iHA2kjps9=2q(e zrGWb137E+qui_ll0SEP0r|WN}j%Pyl2m852YNqH1jmZZ~qIlJO_Eu2|Tzh-=G#vmrOJuT~ry!N?8*?ITUo zPAQITIQ`@m=#Cqz`~z&?XMFF_wo+{b-OK!sm`&;(EN&^adcRfDHnDePWVGa)UWle- z)xImjCb#bwf|#hs;EvvbHC#J22&wL|r4rMd+-Qki3$lu65c7Zs;l{tS`RK%sHZ- zu%cKmy5pUBg|ti@**Q2^s@KZ>2%hOguspT6sf2SP{~%jtHY!i{6Un6BkyFb<7rDao zx1ufC&xqb5qFlX*lOlhwfax1XQA&;7#jKKHa>G4&1CkGISz4sn^2 zw2nWuys1{KQFgdAaIE@DxGh27*A;7cG{Iv92mE2sxx*V3Wq1TK*(tr4euKl+k~kl{mQ4lx-%DAMuEs?|!Vh`E=U zBMswR_YiS~V4S;aw-1#DmZ29JIV-X}2iM>#NqXF*pxr*sEez81QP;F=XT9Xd zExBHrCg^CO`-`2(%|bbo^Y=>=PlqsN8tct;=g>Q}73()2lrrw@nYv+glRa+vheSA8 z4k(`jrKGc5Bdi-!EO(ML&N2scX?=Bdq>e+Hd%kc@C)bL@Tan96es{X*q|Li|G+{+` zuvnHklj(Afx;hmrass*Dy-m1rYcLI@q?ZVuRILq^aDr?oae(iWwmH2RfcO++OwRl7 z$)dzpNvs?#q=5J^X<*HbVb6aIjk&|j#BgOzT5HP4^+@CltQ!4zc6O_P>jbA!uE&H= z5-G12D@r5%wX!@%qbIkpeUcH*cEVoh^nxhE;Bt*yQ5}`bX69hg<%UYQ%4OW?HUaLs zD!!j|xA8q)^fRjd0bYj&s&j>z$kOBpq4Ji{w00Apx1lkph*2?=L~HQE2vDHK53pP>*bK# z&1GIEO#kcbZaPd_#2r8bZn|Qoqxs2m{bp z^@9TWDZ)+H^!~m8#J_~tSC34*MjS`_UsKUr`&uuN+mnBdllyO+ZOMGdk|XRyOLz@S zju^M9TEQg-yGI&{J7Db!Z4N_;sZht;x+KSl4P8l z12}$n3&twKdmWq;!4%w^g*(Dzlp`?afq`6ZH4fOfG2o&O4?|xNw@LkB7U3>yhO`~L zr=yu{7?fQin}~PL!Hv%{nFF|L@)5+ZrJ296HJRi(?a$@~Z2Q|d*M{9DJgq^qVdn^5 zzWP(|NVYZ2*{~IFqX+c7H_s1zHF6)$qQ1stvLCW23unU9;5_1&VG zz5;i*JMkb>!`olEnrHYTDAP1G1g|Rd$u-ZX&&+3x0bi12n(#&zx3c}XjF=Z9kn=$| z^I;=@lgL@qsnzO5qr;$ID@~Ic*M79UNZKYhD&j@w5;nfbn6-$Ci}TviI^K24yLr50 zhn8=RGc88DRkTh1{Xm8SdFr0jS zxP`|PyWEXzW2=31deU#xY*e zjwbuh@vfPxZ!;Q_qvx(EZBLJFcqB|XkCUUPti{bQU)pTKnSq95q;)Fd8pDBRe(R7N zJqyj+$%fG);U*gn+J(|M4UMUDGqV8gnI_H}+zQs}?j?7gUsYrlGzKL(MP!rR`lK&Q z?v=)aHf*h0(_XwJ+tE9;9LpA;!t&Qrb+7Sq>(*rdG6o9`$7elM$;pQfgnNHkK^u20 z+D)j|iF8gw8oe2Mf$)XKQqs6qjHF*Ktr6wyhLd?gl(`dRrfGIq8B!p6&FaOavxYY_{(6BgO_A#+;hOONNS5)d32$l~nG6p? zrfC*#S&O(*r0*ByFgD5iHk<;`-6~=}J+8cX)ZbO+uVLe@#`0KEjc@eqJ<>44E&Qo5 zebO1q%WbEJ7ry|@G)+!VT7Kb#MNrSizQ)bz8N%>1mt|V!BDb5rJxLe4^;dimuxmi;i^8GenHX`1FznQ=Hy+V^qojT!3iPHz{M#}Z## zo`nv+iVe4$4)QH|MvgWVXF~A`HoV0sJ|T+fGH-Dh!#nc~mmeH4nBy`#>=zV%5t>_m#}q{vD@xsZha0DmtTF#9Hr^n&Bm5r z*x^znHzAEm(I%H7USwPdTDU;r{wsBhhnB~kLpbe2(wl{tAPWy}10Zda7T#)Ys8;Z5 z9vzT++e`;8a9JAt#L5lbi`jgE(Y;-CeAV5!LzFdyHM^THL~IsS6AtAz9Lmgl1@3c3 zxxRIbbN)VIr>-vzl=^YH>BH%Vq6fc)-9(X6i1 zNKMJ}EkAbnRVXfY(bDi*w!Y8!4U3HL2~6U~QX=Qvu+iTm`dMR&cayuvi0>EioUk~g zR(5D_5kAi=3(zkG?K9T34D9EG<;>-6iJ4+g3o%RXgBF&D3VP+h>5%l1dwRy{{JoRG z6jKC~^ySa)U2!&cxMD)Qp?3{FIq3nGuib!8t`km#qj&SCDWAa5&@Q!X=y(qbY>HgMk|u*zp^Y zdTOQO>~_~BS~FHH8Mwy>37+-Bau z#ylU2vDk%sRDSW9nJ5$%AbxEeZc)PxO7dIb`K0T=#Fnp;^6x@(@>^5ZWumk1lQKJ` zY04_RzQ*(AHvGaK6RwihBh4Kyjt{;x+ce6zy~yKAX;kpE1aMgkUzfWY-VGvox=};& z7ncx9^A&aOkJ5_Dl{H8_lA?oSecOEJIf;M;KdmAqfNOt6txAsCIjnCX{|Oqrb` z!7WjxS~HXE88#`3GIi?j7>6L zh>13ve69Kne(|s|^Grlez7l)}-@3Zr!Z4A!x4|s;Rt}W1sIo~i%m{XkDK5W|@yyIU zMl6##Y6tpw6HWm9Ze0FeY`~T7g&ddhByn&_Omqhro2){VO zmqz%K2A1*RUAsSik`GH=3gZ|nmi&Cwvd4Q{ghwOHhe@l)@}9yMH?Y(b<6-ch!*&%W z?Rbm_@q~Zj2l$T;=l*~;%$wXiU_Qw|h7Dtzo9S@wPuR!CSmA9vu1_g{;)oCaha#T8 z*r)yz9S;7872d}4IY;Yn0#6+A!T)*S@g_U?Pjxu>BUX4Df1&YbJ;V_o{0|0Sj{Jdx zKVpTq@mr1mbnwIxAN&sl&&MDgpUDmff5ZxJ3c6^8vBKMU zKJlqP>miQ#;J+XEe&f&i1|0nP7)0L2Z!-QIf8vM_{`-P2M*hITAF;yQ_zR4G4m@$h z2Y;>?=Y!YrVg10tAF;yQ_!mL%&rdo3ux6(4xe-1m!g&9Y(&Ireh4I+;ocIjz{`h3? zL4CxwK49%%_WR&Z2k-lr#kGex^bcC$ZTv>#Pd#zO2mkMZ?=$|lIUM{EE4+>0VEl2d z%M(X@@P88gdgFhK!@(c1!rS=MjQ<h!6f)m-F4mpY;F- zf5ZxJCyw~w z|1kJPkw0+oN38HRexdQ_`bHe_!T%xf3yeSe3mp6rE4+vBKN< zBaHuB!4pS(@c$tA!y|v-;E!10ZTw-z|CQj0BR=@w3x1yQXMcf%KVpTq@rOds^A53c ze_Dv}^CEmmgb$AJK@mPM!Usfn{|L{G@O}}V6XAU$yibH@|1WqJ_|IXx3cqfdU>u0; z_yC9T#krE73H~u`SKy`2-y9C(3$5@reg?GOU-ZNgAN+ByAN+A{%U67l zL34$l|2SuYKVpTq@sR5L&!Vp^KjjY?{INFVP=l?XIQUab-uUPK3H&*1IDZq&f58zS z{IRy={sFD8KZ|2ctp1D@-p2pE;m`5U5l4LR$J&&`n5)0k104JjE4+>WpN4 zxj#4jr5@nmk67Vt{O_PQ*QeZXBmA2P|2o1?NBCF&3;rc|&3`890nVL;d3z7qF~98Qk+deq7Ik~0#)rJt&+&RP@&^w7OB|o_2cPmMw&O!={l6Re0|)<; zz!BT}fm8m(c6^Af|92vP;NX8EIAZG$9Q+qLKKLKxvGxCU~Q9O;BOc` zuG_@9&*FT43-a)M{kq}l2dsXgCH8(v9{XQ2dinteKi2oS;pqn){HP^XKOUd28a@4h zgCFbris9)89Q>#yRzHr{myMo&z`>8_$CnIGKj7d;EwLTHFB(1lfP)|F`-0)=2ORvU zCD!`pV*m3-Pe0(4AMeHd{E*`d9Q>#yRzI#UpNaIqs!t|3KIl2#k4Adnpg+v1Q-zTAfSa;U?hz6XFm75M?HpTrVty*xgj#HM})hf{u^i2Q(qA7hEtkK_4qZ0h$s zhf{u!M1H`*kFmt+$MM8Dlg#$#)4?9k^5;{Z$1^?8@q}LUB{P6OV&cbn?Bf&a$!k2v z12`4`;Rep#4*tG|Uk;pL^)#LiA2j~th_$~wUx>9{ zjyG`1{{syy_13l#OhB!V(Sl_@_$zYi$8G6|4!pij@bGW>-bD@e9Hfwkw0+C{~gAk9I^Uye2A?- zaLWJf4J`BV4&w(dN9_F))<>-4akRrJzuS!8V(`G>{`yxQH@o}&%uT?!uI74xd7k{# zVfD-Lewus-c%I8AVS6(+)iWMAr6;fYZtTAaJTcB2zHi(EztO~>2_85+&s^p48Th;s zx*y{6)<_Q=^jA1OJpWLCi{W4IaHyC0ZZ`a@9ZvD+W2*ib-x$>c9O_~H#9IH8*ndN$ z2M&7HPi*x!7@qY5r|M(dSr}ig8>}BV#a|C>$3Moei}b+3kM$F4Jx^f&x=0Tk^sJxQ z>aR6CYXwf#x7+ZnA2`Lo7TDGwl4bS?4Q}r>2_Mi0wr}&ql zt;eqqpTRzG;JX|S=R4Pjmm2+}4yW|wIUXOzC-s+OQ-6*%a7s^J_1)NiNyGz(_>W`% zGJ_{Mobn^De$4-3qi25Ll%Blmng3Fwf5_pKp1jpxV)XO}PU*>8{Vtaji=s$#g;FO-c)sGsU*DK&~z2f~C zv0kt4#eN-|oiD&CfAZFU#OQCwK5$A;-s)>ce;f9JQ+o1Nf3eZO1^d7$J$b7iHhNww zfm3?&R$n!GUh9BUdh%93Wb|*sK5$A;-s%STsr}X5l{vxAi{lF48&v@>ah!(gUaT-(ewTuIHf1AdY+G)js9APQ+o2M=lNJN z`WqZh>B(FDfYINKec+Uyyy{s`KQ=vISPyVYPhRz`XA?HnvmW4-p1jo;js7O=1E=)l zt^NX|=lTYm(gO!Q>p$P2Ruk^0xjB#*gbEa99tyRuMO&fA>SjwP<~$ z2M&6!J;bUsc510|$SuCB)6X9{R71^uR&SwS-vpTr1XK(|UL; zfm8L6*LqIE{%WJ=`~gns$y@!YM$de}DLr|sf1%+y{=lJrt|i1;Kl}TFNDmzJTpNh3 zzBkeX2R+YqVyiy|SjUI+7dTZvd99!4@5x5b@c~Zh$*Z2@xytByZUd+E8{R*SM0Qt6ye#9xvc9o@aZk<9QbFQfziSfm8nEt^X3E z=XnpD(v!FP6ODc&_JLD+@~Y?YI>GR)A2`&{z7T8utnK(n4;=LEjt}}a;N!4qe_I_+ z)kEIabF9&~U>`W8CvWx08F<#u8e07ON5xwIB5)RdJ2SuFwz3(5#4mk4$@V8^DdOpEE z*Is-I@86GSeg=GK!!P?Uhf{vwgWsU%)sMN!Tfc(AIL^7}0pEoDS7RTXV6E>Whgp}@ z2QTue{ES!sUpijZGiooo0W z;QdTKaDp{ozr!IPb3vcV$9S6$IOO{uXy+K7`SvyWzzNoTMTbK^=7K(zkMTAiaLD%z zwEGyI`DUAZ-~?;F^BoTPm<#$;KE~U8z#-p%Lp!U%C&V-HzVt7c@9%J&;6DSu6LEia ze8|UK&>c=Wy_Y7x|PQ?imz|-$dib`w3$8d)ndP2QTs(FYjw7G_d%M zH-6yw{~!jxpF14<;6*<8eGzzE1B+ji@dKA5*7|1ze6; z{ho3-_`!>O$}em13E;8T>hnm3*N`!A@Pilklb>OJz89Yy58|H!-;MeD10TN|p4jvn z6Y`(r^?v|&C-zYb%M1K19^Zhr*TawgHnq>8YRgdE>SoMhKH6iF<>#^4- zn7_iS9>*h#H9e&#wt8aKGauIEl%81Y`JLyzp66c{YideQZ1u$I&w8*Xru4+BXa9&* z&wNYsuhYf{i(2#mEW;5op5Hu#+mXa9ub{UYq+Q}|nf zufaZIrA>Ln5(hsYW9O&vI={&O(dd~Ub1TF%KXCT<$akLm6khWqmR#VyHpJ5(d@4V& z=BFpdJm?1;PTuS8zsL!HCi3rcUfJIoJ?s6A!FPH5MjsC?`RuO|f3ExFe!!j!`B^Xc zRK3JnFFkO~gMO>Sp(x*{mSTBFYdXrzd$|bxKHBX$MGiC@kK1PLGNROp7nxH z)l01PG6&{(&~J7))XVu#Uh8G9pBX*t#oCnp3Fs!%EYr?;7~92h1Yr!$2C6WTLb)kY%`FLxvp{8-Vc!v&kLtJKE!jp8UJ#` zBL_dTTqD)*YKK#P;DcYE<5PZ&S3i0`iB0{kayaD&KKQM7e9DjU>PPSIVpG2>9Zvay z4}R+$pYmh8`qBG4*wpU|hf{vwgCED6Snn@6evDT?dVd?6`n}BIlppxucdFx4evDT? zdVdR>`n}ZQlppxu_X5YK{1~r(^u|4F@VngMlppxucZ%avevDT?dVdp}*7p*JQ-0us z-zvwa{1~r(^!^6)I=(%?UkAPk^OJKCoZvSA-;QmC!>N4KYdqIG;NZ_(#9HrV*#DZ* zGvDJTA2`99Z<)iXeAL@~z#$)V5o^8|WB;p0&wO7o`M?R*d`lco<)hx_0}lC^i+Bdc zhU>wl*uHG^%=aae51e4lccR0oeAL@~z#$)V5o^9nu>VD)XTC3(eBcCYzT+KE<)hx_ z0}lC^i&*pR!v5!tp7}m!@_`eq`Hposm5+Lx4>;swE@I8M6Z@Yvdggn~UC+P?)_jW`PUWNC<^vA-n2T8RjbQ(y zM$dc?nS9^`YrX{zr}9y6^8tr^%tfsEF2??YM$dc?n0(*_Yrdl$PUWNC<^vA-n2T8R z)v$lR(KFviOg?aeHQ#)PQ~9X3`G7+{<|5X7!`T0@(KFwDCLcJ#n(z4zr}9y6^8tr^ z%tfsEs@VUK(KFu%O+IjfHQ(V5r}9y6^8tr^%tfsEhOqwuqi4Q*O+IjfHQzjkQ~9X3 z`G7+{<|5X7gV=w6L(lgq{2Mg-K82j%KjZrKPV8444*tA9fIj%s`+bq$-Np}GmRS8R zayaD&KKRl5y^-I0j32lxvHBGq4t|e29Q^2gSLF9@;|DHFtbXS?obm%7{E$2QuE_6B z;|DHF?EMms7jViCIQY>Un?{tS%pJ9K&2S0khJ@UK5_<_q3t6!VL zDL?SRkKS*K{N8H(z-5WmZ?VHEKk&hi-neg6Uiy2R@dKA7R=@QQtDf&G$p=4rza{c} zv+)C$C04&R4yXLU2S0khDe`-x@dKA7_I?TL0Z#b=2S0k>+Tf+Xw-`TgSz@j4WQS9J z;DaB%Z;t$KGJfE)#Ok-);o!&nKk&hi-Zw^mSZl(104__cekVDc@&h0I=zT-v_j=<8 zE=#O_$2pwx10Ve8eSPHjI^zc}ORRof4yXLU2S0jW7x`Ul{J>?2ytt^#t&SUSpB}{ zaLNyS@T2!D8h)7*92a=6weQEth4l4>H)WUZz zpSabdpV_fC^c?I}t>}x*iiB-SeW7RYMsz^_)dY-Sus%QOIMtWk^EAREP zeq0ghiLIVk{nx<%Ws#m(^~$TB=hsUkJ+bPQSN%oMUmod+y=u9e`2kN`7Vj{#8ywNdXDd|NKdSK zjwi9|d41g(>4~kLSoIvQ9g&_`^~$TB^L2ZqC$@TG)t?9bwn$H`dd_!Zub1_2G}04W zJ+bP4i1>P>CssZ46RZ9S;E_mAZ1u#d=XzI*^u$(Atom<2e{rNI_IkNLBlh|%=jU*w zC$@TG)pPu-k)GJmI!Z-aLM2~@EeG5KiW27y*|`^W`Q%e1M}L0+=6cd=CuR41-}KDYddla z#(h*C*MTf@3x1RTeh9e*>-zIvk8g$k8tkJM<_`INEusG}a$M?q1AVwYvF4)b5B-3{ z_XF4$9@jDXev7#-FnW&1`Ph&rUvQtqA^$raAHIJSYd`V?ob) zfkVAK|Hx~-^gGw+S?@Upvp(SL*{J_{?o)UjU&N9N`RGU70sX!Byu;(&*vA$;)Q{e0 znRw<$ZNZQEfwN~I_7L|eyyizNxu9o$Vw;~>^Q(vY(ff20&+!5dy8XT9sN ztwlWtxliKY$NGu2e#BB6^gcG|Io{w?^%C!Po8-VXGw4|_aHtpi#Gzj1T5a^K_f%{z zM7;;PPvYRmdWp4O#8MmdJ~rrCFZfiw#9A+NyukP~f3LyJ2b?_x^&H?nh1dLuB^P+F zP2~rl%1^BM>3Oorx7Fb=Uf_h+pqEtAL}L7{vbBH1X%mS<4J7K zcVewiJ<%rq%yklYjc2{Upd!o^^-V?AL55N7~Cvos&y~J8CVyO*!9~<!oLx$;WzuL%rA+{!HZG<#Tl!J>zjKL%us5&bC9pFZS^%yw;0YX;U7t#37#JOKj%{ zvDQn^HlrVKIMfSHc&!()*;b=xy)D?9QQto9lQ`sO{lr=?VyO*!9~<PnT}6>g8kXZgHQ6Q_s@*i z^XZq4*Z0lIe*qt3c;-9W ztobH79P-f%`cyu~+kC(w-}kY9nBkdkp2-JJu;v@@aL7k5=u`O^Z}S0%d{1KkP{T7{ z!Q=xcSo1YG9P-f%`cyu~+kC(w-*>V9Ji{~JA;5Y*fD^3wat?=l^nyN>kMTAiaLD%^ z>>q4+<~zvb11DJXB@Tyt^nyN>kMTAiaLD&<>>p@&<~zXT11H$$%l*sYkdI!_r}8o0 z<^vA-zJ>k$4bOaYO+IjfHQzrR4*BQ>eJUU0Z9d?T@0-}iH8SwbH^<}yCs_0S&Eb%b zUeKrVG2Z3_4*9;0eOxmF&wN;u!+hcOgjn-E<8a7FFYu{+)Z2W(A>ZTJ$GRJM=9^{m zffKCx{_1eZM=$78`515W0f&5F!9Ldfz%w7#XU9c;O~wx# z|E6c~`?SL;Kk`5E;|K3-KJvqw7wQAYzquOxKId@od))Kt2k&e)^23@I{J`;VJO{rA z9Zva?S3j=5uv4D%g?}SA_<<6PdCBjulMg$rdVXIjy!z4mpOGKdB=sYg5Ubw@98UR> z_kQC2_s9=xPVfVl5Ubz&9ag{OM$fAsz5gfj!g4=(wY z@%td~&$0a$e(%C3vA2k-X-&c{>@2e8#B-Z|N ztmwDfZF*0v`7vvzg%0ceJGH!L&fM(BOYse8dp$VL z7xKEEzSiSw(e`TWZ<+Y7dTis#+jwG)|1|XIbC^HuKR2B}9*6mJw%4oQ0Pr_We(H%e zKaU@=>N$UiH9zOiHw@3?3mo!u|Lfp&ek#5JZ9KmiPu}_yt3SsVV;Xq+bBwir+{ZO0 z_$#*lpT|J`x&Ia8uh{yNxBkTH&*SrDU_HOFPaOO`4#($DUax*U zK3_8VsVCO_^e0w5j}Nit=lSzR!_NW!g2B9I6W@yUv}C7IEF#b{_vRU_;R1TU*9Ab*36*42t3zN)pH+fT8ifyr#$y@&Zl^;0m^e9 zb2`Oyjw{c7jA@GJ7%R{HPZ^%$`ALJ{?{M-6#_zY-$EWbG!uY-o`-n|GVf2juxWSAE z4)O37UgHrfp6c(lq27BOpE@4UhU3ASK4$V&Jsw7VFLklW!-i*l9|hL=0Zy>aw>uq9 z9zuVAgMEB*OXVk4J?D$ph#uae-wh2mX?xJk!hj{Lj z*LcJx?{4TN{#^#I0Z*)YXcLTis@``RjB_U;Ry~i;I}G0g{PqaryifVP)nJ};z{zbm z{=agc#JRIEei(<`FVS{;qz4Xq#sUZZFB}*0UFLCzna{|Tnjgfw-4<#~9$yNKerA6F{AR;%_t^8SlYDX$^gP#jyxs)8&Zn0;9P0m>!wKel?&sLYXY$5K z4;=JAb$rmnTVgaGTH=t8<3Vi4V=S!W!5T2fQ~f9Q{o}j-#lIrLFE@VB zCdBFotzheSO%#81gs(Dw&?dy{2d!Z1cV!fRMTB2w{Gd&U)el<1)(_{Pj;D;@`f zu#O+kS7P;pRR->MDaL> zQuS^#e$Xbw>c{hq*!qncJO@0^`@j?9ybt|_R*Ee$WcG ze$^;`D8hrr588xS{h$?W{VGxXMG?Nx_(7Wxs~@z2tzS8c-x}d9#t+(rSpA?CZ2dMz z@udh47(ZweV)cVou=VSY;x|ROX#Ai}h}92T!Pf7BDE|BizX({*H)s=L^@CQh^*b+$ zKR3eX0IMIg39A@snxR$LE0g3ljC_`f3j;|Tu*_!Q&U3w&}TpIon2 z8qD=zMTD0}cv*y(MtDhtPm1t~5k4Wp-4X5t*83N532^xLY+5`v|6Y#p`tR8s>3Ci5 zk}lx3$R8eoUjV*2!iyt}dw`UFVT6x~@X-w{<9(>X9PdJepBLeS8aQc!{(uP2jqpAO z?+ZO}f;{;*qWx*?V{V0ie}o*d{(A*^kNv+_z<YK@E0Qdr3il|!jDJz>k-Xi zIBzn4jqqQ9AAle3*E7@-PXfLLpVShoKgaXW2Gj3P5&k2v`cX@)e$*0MzdsmEzu!mr zcfjgLEwTDhOKkmqYcTzO6X9P2s~@$*>PIcH^?TZ2T>mn^GPno(zr=N{6XSIsKHnVS zw>YfVzs%1)-wHkEYVJ1A{{on?uf_H=Y&h@a`JZ}X<#|kgicRao`Y(7lKC$I*^0*uO z@5es-PkjgQz4%0(nV(?O_?J2yp6|J)lE-y8hxLG;nIB`bdf=eH)$^+Nu_2zZ^w9Xr zJl1;dcoyvYBQ^ZU#IrwGv-J9zAxAtL+j-blJFL&+nXL|o@!S#NooSpq-Q!C!UT?=f zYkvxx*3a<*4*kE;;mr5Z#<9m|25W9g4;=Jw@Vx4u0%nY2#u973%RIK@MLxzlUaaAJ zCZ6MkYepC^a>RDLfWvsJ35=Xg=CnB!%zj2H2xe!N&4u34deju-K_F$UMW zPvS5huS45+uxWp(CssXUfrI`!#|7SNLp;X|v8nMH3+s5Xrf*@>{2Z?*u+2n&9`qcs z9WUT8UKe`3jt|F+dc`}_SjLOIju&hDCN|B_{uARmkmFjw>j7}+|7(E1fz9fPRnJ)9 zpntXF!uv+`)Od~;bJ+Pb7FK`e`WiNkpM(9!vFUh`BevrO9L8(F^Ey5pFX|O@ybPA{ zBG&O@ZC}Nv`8i&|p}#Np{Fl-83hd)E!)vb90|)&zo>x7+8KZiR53wDevG8tau!Wq^ z$Ubv_37h(HyuOG{$BP`X9WUT8UYk8X-JFlqE9Q6^EaOG2UZY=dS{O44cKD zY2ZvJ_KCZZ@BR2>y~MlSmcJ37k7CpDpq|+3iB-Vp|Wf%}1>Dz0T{;#eCqi0Oka@(En`_-tINi{rqSDKZMQZ zC${;CZGK|Se;xLTZT=4cYy1bXf3Lw^9&7xy9&3Kp+k8B4Y`wste|2!gt?183@Hq;6 z4>pbG{SdLnzs+OK&(HT^vwGs`etf7W-tD$L*ZaG%X}xdvSo_QVkypP?k2U@^9_x7Z z1HaewXDGte2oFd2;t1CwJmPTZ59`G|3F9~DaEian@D=dDDgNDt=luWNkVO6ZC$@TG)xRA3Z^Aa+_y1OpRnPvuG2)3W z&lp=Dam;JJYrx%N#=jKd%?^ipZUnv=oBD0=*q$%sH9!4{_59%Zb`v(MC)Rqd_PqM@ zc#&5>o_{wquw1WsjZlBqL#%q9pTz3N{KT(w?>qQ=?1Hbucyk^d=drIxa&b-bev%I! zVZIi@S-dI2Tn{YI`#aX4$Cu;DIcw`Dw)GR+`iZsv>#nGOwSv%%zsQ3H`U*K@4 zXDTp{fgT^uM`Hi`xw22J_3`*#1^+8Bemu_14IJ`+&STZ{cwC81{a@;ExZlJ$2#@=S z+>5Z!`w4gle;zyF;QyG%)}Nj_zMseb<=AXK;E?Ye&uc!`#+-_w6|C`>d93;F@Ys*H z)O-orRL}EuJGPk^p9k?t4mjMu);+KF?uhWtG?x2U`dtdYx8swwZo{Vae8gj&FZX%u z>&vr$$QkBCUxYV09LA44uQ}SE4`QF!B=uLUe3$37o=%T7|I0kq`CbL)HBaL?Uc4r% z|2-ZnPk-|2f1bzc&tp&C`ZLFLjMqc>IkoKIMp9sv$cObUi8!ctc~zGk1-GA-$;9Xgm3WJ zp3n4COg-)aavINmT70d?s^@w@Ua^l4^>Tc{2h93;5254B@#Z~)_OCy})PoQGeWAx% zAJ-)EigB$Ito5)y@`_m>??G(-&A>Ll#mo;J^1r}i&BwKnyyB}p)_lxQUNQ5Ru-W_r zz&5|d%nuy$_j;`PUK!z6d93-EpYe*BzaJR$Ql3YbM|eeqS4MbMgins}DGrDJ@c8qZ zY0n2@d%h5Jo?*+s1fRU-T0ODV6RV!<^#$0hp4jS%RnPU5*GQ`;Rz2qR_2c!1*!pcW{0{6B$Gqm__>fnB%p+NIr~C2Xd_|36ew`TMB@tfgv94#! zfVoDiAJ;Rk;TCg^RJ<1Z7E{kPRmWo@_BlrtbAA%{`uoF^u+KTKJm)*{D$mo);_<+& z@r9m0)nkq4`asX+o@Xqv*1N>va6X>^%uRWY*Kyd??|AGVYw%R;w;Rmk(PnU$$Gh=~ zEx+Akd;F-k#}8v4@-d!RQIPsS2!e`jES3O3Eh`90ZS=BJ1Dha9o$ zCt`nGgqsZJcoH9i{2#(6`}PEm3)?4r?EahigK={I=A6NEBc63wJ^Gu%>=%#ixRZW| z|Bmsa?Mqf&F6@$xOS~$_G5Ggl&woT?IhK1Dd#;OFa@OS<%W>bk*ghAtJeTJVSS?%;z?E)A7x z#Y$mItvI~3+>gEf>fms7s5Df^Lc)LSDRa<)XH;t!ZLZe(OB?Fd{)>)YSE~+;_SehX z%5_|P#gY8Cu*~u|nB-q6I_}u{j95i? zwOE+Wchus(@?fd2y0lWM_804rjZ{Y=XMH~tGc3RIPx53FEK=ETpv_F|?AIdv)d+t% z!e5N==Og^t2!AHRpN{Y+BmD6Qe=NcujW8D(+n@U*{NV_5QLy?CMEL!{dpBt+k3fnE z7fx*X!|8h$d(P!9)_>x-ycZ377rWWV7TqUe@7n8FAG0J(^z6I#I`(v**MB1KJNG)a z4@&%)yl)5GyZ-8leZdl1;3vzQ@V$%G6Z^Ew8Hk_k?fB2$#p*aWj_+IcI<~(6Df-(u zzHb8DySxJunptv|`$WyR?scrM)x_Ss*RdBqB?--ZzHzT(bzU{*oH@D^gjZ;tp9aN&8ET++Ot z-)D3rqcVUZIu_R!4{G z3kuDPnva6~0?5xjN91}Tv)94}g|S-us`X+;E|bouaCBi^b!4QxsZz4RqCk#wk>m7@ z<;_|~@5uU6abRcR_(DsezO^(|2-WsgS5y}i+=X)mG?g-|UtQc$9vmIC)<+dem61|` z*JDnxBMu)d?wH@apg_%X+zM1m^>THHMpDGWI`-JzjS#!b_-SEpb=Z3W_GZo8W3Uji z3e3_a^FyJ}Ijn_+QBRL5EarIQ*(SRTM*GcKS*ulRBa7X~DjbjjmJ0er&<7thzeR2) zP8%&&aIVXSxIDH5Q;_Nf+g~a zvD*8)_5KSa#$0Un{%+kboJ(GGxp*M&-rudSTjKKiMHsPrf45$|&BZnr!M(p*cWE7ligM_T0-QX354!H1@C9*}K@YmPpK!ULWfIl24ML_%EVq!7*d4*)3zXVi8C_ zg_x#%U#W%#Nd87aQ+{=|Rt0z%Og`7eB|`pZ`&_oA1-tj58M__Wy%)RVnz-E1>7IZn zyBlcIL~`;JhL(4uWxqLWSzR3{RhCzWHkY@I){0!KLEi~_@}!kJhD$Z9hC_8Uy#q}X zmSEv@Kkk3ARs^1RoRcTfu^^UcdJUSEFDu}u%m+DK!0>pu@hqhg4D^|8t zYvuaZK}YW@9D72cQr$9t$5F?@>eaBi>Wa*%Yk-|#eW^ZL8yewdt1wi=KD?nXibtWk zxv*nV!6|!(3WMwTZ|Ry-#_ZYFoj3%Ws;Iqype;BQu4|~`8btm_qYFb{#MQ8R{t+l* z%o^gvSN^Bn@2`$%_pg9gOY`!z8~)esBM7%3q4zKSPkRqP-}}p9b;RMQVa(n~c`t+b zKRWj4g?1h{iJ8TVHuV1Q$3E5dOAz)S9eB9;uJ3}?Ve?SIm|ah0-SMAhE$tZgS+~P# z{5W@VVj_(cDCiCmK9S=4~`PG>UK0!Q7jQZM0Crt;*QMwpM30H~rOINR(FIjn%eAx@M zL`|$0ko4h#IyzorG*TEH-d?N?_(O}TBGuMvWncvFK8KKSsLrE`%Xa2{@6E7(@!{L^ z2yHJ9)VJ>0{G3yo&SM|A#X&o9VdxXD+>D-NsWl zteh`{x4@~RY0faA@vgQ|^kXIs?iyMgsguF|26|sF)wbdCELj)v`HPoUcOH}m7+uAg zQIioJ;m}o3!&zrWBUjvWcsBW_y}6gbEx`QZg2E=bowx`ImM&SncE!e1*Sc0Wr*uy6 zrlM9FES84`P}g=o85dde0Nz;-pyW+E3!4@dP-z)P|Jmi>;#%D=i+m4p%+VW8Ti-YK zYJBl%v4*m$)y6%*W`z7lmxAIZy$a%%GqZ5P(q&^`1)-}}M(d>lj^k+KD%_8tv(Nhf z_CW383zKl9HX%cI*O|R5&bG(t>{6{-z$`b%V;7nh6pD*CxyiJ>JW}FRx&ZOR)xEFK zoT~rMovOT!V9^T-?uPaJblq%rQ*6iH)qNh~H<$Ll?!7q$FknS2)tlUjUv#JaCSKn7 zUZ{ETYTO6N!26}yo(&^|#YzR|0&c8}a)xi>=$`$5s>&0`s*+FQix;h4dgilMSt-`G z>`~+y2)p6>Ok*sURjZX!afqw+z@Cdrb*Nq&9pl1_N2DUIQ~$=2gYjkxH{8zFjk#K3 z1W!kCr>*Niq<(k4uuDUL0LBU6GM=}@u3|e?1r_ggc!+0f(=kB**E7pvG!m80B zeBXxmPp6hQ)rz&9;8%d3Ib#fB`Lhwro{d-vV&Vj~g7=cR;iS0XL^Mp9ymDxC5Z@m9 zht3nmXyfzdw5e-{u>kYYa#OX6r8{Xu>-cea%p9%oN%>H~3F93c0WJW~oDp@M1YdSd zny7`Mh5vJNe)ApE8*@XRQAZ2&+&bV^yZM{TwUIhTyfQjC#515?#QW8w=IuFmggEEe z1%+eJE6fv6s8{i$ANTQFRqT9vt`&9=0!Q4Bif$uJ6SI-vOa;o-|)qY zapWtt57(-7yo$#3a4S=&#P>__P+=a9(*D`erGzCvoA&O86HbeBd4C9&8fn8tXlZMhAQ|l)#w-p zK_*0)YHZ;T?C>DlkGDj)aT@ktj_|~)Z^dLTl=uZeD#@Nl)*GX@^LMu5A!cXGQAf`o z#m;EUQH$rJ7TGg{5JsK_c!1T0FBT6uxDPj%n@1}Za}?O%R%j^xjO~|qCJZ%qBmZ~S zr2l+X3FoytHZpW(aax6r&mUdj&VdDmR^E=wpNm+$$R2bZ4tap6Z?7&K;Csjs%vL-{ z$eD_;KVUoW+-RKs!^Z@FBex0P;x$Wczekd}`#sAIC%E5Yd(*9%F{+qojvk*>EatuC zL_65gE6|CU>6@@r@L37da}(AN?z%ZYk;&u*X%Sy%iM5-v4MO}I6Yn=Da^HQ<9OKp# z#ILYTI4S(%m;3>RaZU28I$*wsZCq0?U*KZzTY{EXs-ygR;A_|>O(uv0( zx?=6}zO&Y?ER1a1QdqZf*{QwD3-cB(UVKK|^2Li+^sOjtIQ`^8%c7RWi&w6hSD0r; zYI~au(aG+YzeW~AxR^o&ErwZ3%c6n$z`PTWr!h(!8aZK%=+@@uW~%2EswjPPrMmru zdE3hJ9ririnHCsrLHRo?sC;v|QaSc8MB?W-f`!%LVn4p4J+|ezk$SCqQR&zrbP*xL z#roF5zzOpP3+;MuYHe=oZbM@$b~{^;2Ygp+M`u?n8k@VDJK8$B*x1qC z+JdkGj8I2+JMy5o&W_I3_8v5Lb@reVRMfVpr?s`avzf}y=B}=mu9gK0+vx<*g~s-d zmd>_jX>7qaNZsOzhSqkDMEjx^^cLNRvZVu~(}wIAsg{=J9yGQr>gjH6ZS6sJG`6S}ntw0mq?vK^KlgcUN~$OQFB8uwzkkM`>Xv*5sCs=C+=e9xjG$EjTo2YVGdE zh;*~5r=ttaXlrl5Ahx%%4gKlCfkS9(M_X%WJK9>hI@;lb1CAcGwsdxPp%DkLr?Z)} zU{PyNb4P1e8>72hn_HO#wmr@CYwc)NPYJ+D1gYk(6gu&Ge#6Rx!c-h+?zQl5Fu?_Cr%U8!>-99(AvzY&xz99+}SPO?Jek5 zw?tx=bch?yGn|2P%y62wNvKRpH%(f)TTwhxv^96O%bJ3IV1BlDu@N&tPI+__Cn9GL zEADLR!f{1n?)CU?;q+_k#HoO_qocL8P0IG8fX0rFW~@;?63(8uY1`b<+}(+rQ4V-l zJI-k++gq{bVQR6Y&epc(c201NJJz!n32$!iZs}$skm!gj2@3}%1EVoha3;{QrMrtw zIK?&0@V3Ey_|;Xa3}b@ovR4#svMwy7DVa9@VM@C+?lGdb+K z8wmX3z1XnT{~RE<858`k6Y;*|K(-t(tMPTU{+9(vx;$Ip^izr>r(mS;n*yjx?v(ZmL?1@P5EDow(>CCxR=<2p?(a?}vVFo#IPH;> z|2!3{Ox^e##J22Y$XDQL(HA#U8YlJ2mmdA4wR|0&m$qEJ$lJ4N;xu_hxrpBnAH+40 z_fY$@aoVijk#!ZkVE5UpHHn@j+{Dlb<-XE1WofPCTT8t4oGz^_e<>c|w%Y*Sqs?HT z{~wO#cs$$VeLVJm08-{7HT!!$hkfGxJf7>Z)l)Ow^UOs&#p9_SPxN>)u>Z*|z|L%J zxoEnh~qX!ITw>?Hp_`OW$f8JgNJ5HYBtLWJSCpZQ$;xDY%aipv&+sV;;DXi zO~XDnI~$4ZY$vv}muG<06YFfJH?ci?0Qr+U8vl8g*?SaL3@*`H&g3y?@5DW3?{h4c zvJNMFYQ*pE3~ll2mRpa9K_rVPRO3F}Ln@nG4jxTf!Y*WPQ_I(r)K`0@S!&)3g$rp|A#wcfS%KKtww zs%K_$#{V?Utd+*9g9U5G&W_jx@D)R8$E_fTgxNxsE$nc z4*C4%YPH^Q&yN&`OOs&C*LRP~&XhH~>ZRI9vC?pwG+L}76%>Q}l#Qd5bzV(V`bHWt zO_^z9^K9%jTU?tzA@DUmYq{3f_q3>u9@bDs5td))8#FZlP})uV6q& zwwAYz*NW^B9FB!U_J}!NWOJ!Fw0op9hD_O|Vwuj+Q^$*ya(y=%cS>V!sJ#cUL!lcm zuFwUjD|7^z6sI6M^v4$nmj9G(jmI6P$q4$pQ4=G~^i;n}KyB9hMu z?7yixHdfwJDcLIeMn=c$@ZTsdvj)n;rGe^d9OO!weNMh8?a!KMFbAsjV#UWN-xI&N zewHx9%3+?Fkbb_Ha$DQjvC9?MvC9C!q&%BobVgMMx&Uyyd0{HvfpJjXzXndF1&l@VF@c%X zY~>$ro+jT=AD#_&3CJnGwTkr;P2W;G=f*t(O$;Z#OHj_~Ry~5r+ZsMh`-tGa6U_;l zKl0ROX85p}pCz;BX=Y^db@9s%VI4`n=J#=)BwzLWm`%x7{5~dA@+H5|@q5(obND{* z_c?l>_4_RI(|(^deN^^kAY05peq5UOpQxi!J|Z6wmwn_Aq^A&!?-k?hH6!E0Tvj-@ zN@F-BlD9XaTH>gz9OCN^qNE%#OqV^E<>Z@?$UZhrbUs&VCut z{(5!rA{>R+qCL588q>Nl2Hq%bv!lU>;dbY|X4hz`hEts@TXGHCuG(i1SIqN=N~5I_ z+=2}5KEGDliuPBCF+Wh;hRPClF?q$Tl|#ejk-o9h%d!xo>1WbD$G5Mo4vvo%u|&i2 zN{Po!i|V3{{Y$QD5^wBXEjT;M55u)Cmc8iTJ-nq_LEEdPEx)x=-3fZV3l05Lw@e~8 z6mxg(+_`+LJY2*r)!^9jYHb^CH*z#3lTT`0y{u(9*Oou9AvblPRva0_$PR<%OVg~A zi(~z#pR^j?aYL2Aj_va&_l@i*)yB}h%>Rhkw7%iuwoZt<|S@r`~GuKQncn~9udnldrUJ~QJJ=` zxVuzqb_$t;*p{8Laim_YRJY+SCv%jvOe&6zm1>v?nRA7wu9kx}wh{MDx#iNd57QQF zLuK3?;xyP?9NC86=O2JEx7-ZJ;o_Y;ZF3(CrwdF+=%!j}N4YwV8I&29#wnw?;7meyHgxZA3faPs>)GtZOuDXWY1;s9=| z;rViDnL4(6c(_!rl?Tx@*EvCQU2#hZ6E^=KTjn+@PZo;Hw7#)*<&leA;rScTmMk<* zZx*Lqy@(l`zgJ*(|2RsivAbA;Wtg5NhUxuCKC*3PtyW~OTBLD?Ib2wDGBc%h^1AYt zTCqmAgQbCEHBiDm1Ny$HSi^Gz?)f?3?}j;daHFEkd!1|_rr+>rb*wbR3NmtspPkk> zf~SL#!IHFHC7wAf8E|kVa@y)zwyJ{ph79-7?O7(nyCiP%iPdVQRK(oNERcptu6u~s zC5#hm%#G(-a*I zbbqmPaP(Gqb zNoTo6NH?Zfu3H-CnS;5qzP>tE$05xgsT@EORE) z4Wy(O2v4ilhDzvde~ANpzqBpr!vMsm7-Mqo^qIG( z6(zn>Vkh%xAqAY>lEfvVG3@#Gz$9tia;+jY2dl;)9&Ftz;5zXRhPRsV zY2wPoe06DTuvV6bT=e82wofyT`#8rw`03S3hM`B=C#|lI%QY?IPMzFH374RZJ3>>S zuB+l}>E3O0-9k90>YuK4XyA2@C{JZ+a)eO%k)dhh7CsEa>p(Uo(-Fr8znUM)#sla2 zn+zGyvC$&$jPq}&>Ci?2iCppyobLrz%7Mqo)#a2)0?GP9r5It%A4?wRoTU2)~+FJb$BQ=mKIp71m4q-EcJEF43)w8-NG zma)yaOT?*@yIjn&IP1EE*3Ht|bYgjAh-=8(1hFEV$cGoM2)R?GX`WAnDRFwSR(3Zd z`PYkWvRo9HB=Z_+n9rNAoxHBHHiWqKJ%1~$uW5{9=GEdplWU;3`peEHZ4N7_Oq&5| zo+|6*h}>#r9-Jq1GVzDZKWDJnfzKBr=c+4 z3LhDdh12nrSt(!QA5t^Ni{s>m*8yxuW@u0Sw0;p=514|h5NwaZt-{}m^ohHyaW0{s!gsh7VE_iI zeo!#5CyQ;iruTONF#KB#`|6R2SA=6|{`XAu*1lm&^au zY0}zi1s4=pk1#Io3`yjSJYZjUBX5qJ@6T<_eZawuk)B|LAuPAQ2ZSEPE1uj49x%zx z0UW=3L=|fW?`&`e1X0-DAhyFzMmYi#9vHaGP0RuNHU?b0!*j_OL~Yt&m_@iFpX&Ow zr=po`=(Vh%2TaB5-=KDiL~@Nhu{c)pD`)2KY)z)QPP@}8S<1G*PjYS8ZNh^SeEN5f z;XSB7_4p1o)3l&}J6;SA>HUFuTHrg!Ow&QB zUdMY#d2f#Q-|)SVrWWJNSDl%rCjac7`II0R{BY^;UFLIc=2Iq;Z{FO{$PKIBY`mDw zcN)Ly7PCisE2YDUZbNXKGA31ZzA3y5xl46^w?2qbQj()q46EY`)=``vjGpv z#fo*!w2FnZaR7Jlc$$`*5xxV?*xRvxh@0Mw#EZ**wEkn?^duY$E5^ZMUVyH-mr3|y zp}uN+xiZAbj~P8f?6bAYjlcuMFw+G#nh%m@UW5>@=T$OETK93STzPDYDX~$W^nCuj z80VZgUar*3BcTlR>4UU1&Bo}g@!!SxBh5D?nGc!~=8Mft)AUu9>iCeBl#z1?-^q*( z6w4L4z4({7={Uwq+>x~YYqD$Ra@>rDFYPn1oRX*$?-9*3b+!OMz0#y!KYY_RmM9N$&0l;tTuQ;?>4 zeYmjI@Rr1{=J<9Io_tA&wFvKWWRc}J7nvIy!<5qh2L4|@r&4Shta*wdYlQ5E7)+G z@!*#_SngyZlktV38N@AO;L0Tz z$~)?-S<*VYNst^$@;E?0H^lK)({2KhZ@C*3XHRGnb3B znPR^Y!#uf5Symn?=%oawLn2q8-^@9kzp*i#vYd^mWPSeZzSU=Ahld}|{e2toxy!+- zjr{=LGA8S@>uBKIK}`Rtn+LGN`I@Ys*0*-xeJS3#4ayG zh=A0|*x|{EENjl(gio$!Fb%BSKojRFr3co~cCK?=c_J&|ast!lmFsEZRRDCRtD9>F z!}>&Iz=f@sUT|tA>zg*6<|^YO0&*iAK2P%`1&rkDBa zGNZUm$Qu-X6`A?XY}2@Qyuu6R?_KOAE|%XiXPVOA-N+qtQ$8@YMSI0A+VghO?Z>#&msSUOxCKJnU2Sa(Ej?E z=ia375t+}*ZX{iG!i%66E+9b91 z<##iBhml(>a{h_Q9bk8xw^hF5%gft<>HY{VYvos-nb)x~&qr1)cHySAise5eZzJ+p zfcS-LxMvM_EXgktFevC(kcpl3$pzo-cm(^-o5=zsb*7i+9U-oxB6T>c)g? z#qkJp%ZuZKZ?v|I^HnVJxKbJw{8R$Ctc5R{T@C!wEct1phU9nRDNm$$9Q9xB=3Ea@ znY_u9PP?YmYtiIK65J&3Kv8C|;AB6Jc+o7cP4kl*@6*V0noM8NCQrB)bjy!b{%*7+Pc(XxzeQXin4WGTI7e*Lc?}L@ znfs+Q;!@0SBKWFWewppZ(u%tY_o4!$!8duyj~kgXyTt{!M3rjIOtL50oXkAET-rHW z#iHzAi^*hva;klTmoF@zoIB{(2xH3plOj*fj9*z~*!<5KeYhbXtc(wphWhYLVIp7s z{Zn4`hwoc-Qls!2B?!M`DIvJ<=J<_k=AR2Nj5rYZEdfrFa2h~xme_eqEN>$st9-5Z z+lEUGT#gQn8}QWWmephl z8Z%GshecX`XMtY?Vc98fEthKkEr@(M_vF0d1Rc+PRHEmid|88~A{UnX7)-g3nmY40 zvE^fp!<)3bXuL)6J#Ew~^XSRB6AjK>L?v^$+~N5hZ;VW5=81_5tppkizYR?0aH;p@ zv6#%0`|^3K!qJajJ;}FpPtL}#zSOJ3=7mx2A&Cn;HZv;6x5c@K*kftMyttVy?`rfo z$8SS3Pwq3}oX9;)@AvSaH44wYR~j3IC(}gYz?%QnflwQ7y2G2b!^A1fdvjcpeVs`U zS%}B@EPyH5mmQE+bbyzZWI>|?$^H_(FMf}8!eLt^WJIO5R; z%lPrh*!xR9tmi4_uZUSa-q%~kd(#wO7;!mb{`!WE=Wo_{mU?35gY)OG;W+c=FAvWB z96PVY=YfthQ~r$~@Gro)mCgOqZS*B)K7$SOAUDmk^&f=I>Vt#+0r02Y`foA%u;sx) zAAeUs*!mY6`q_WM4i5VJIZo+cVD#ae2M7I0o~{1*4gDPRgMYr=$r@$W^^yfQH`JZF-;hP5s{k&(Z|Gb92j1M^I&x1eh)*sK~;rPOq2dDJO)*lZp z;rKE?IOxxDobtzGOwfmK9vt+sD{S@8F!~&SaL}LSIHiv@E9k>F4^HWmt^R2Z{p>&B z4-Wb>9H;#8?jh*IHxEwfldXO~*q(ozBR(}^yk$uF<2^=-H$=Stf8lko`|~gRR@4jD z{$;=AI92Z{rho9wgSCIz*Lb%5d#=%^9USz(={Tj|XY}El2M7H(c((c{8+}|W^WdQW z4aX_{lZ-xm^WdP5HBH#+uQmENzzz=jUw53+Ut{#)n+FGd)Nw@U(&)oC4-WdQk8JgOjsD%RgMcn-f>F5%jm;54^HWmt$wG` zXMS+d|E%Mbe}~bBZyp@s(EqsOl>Z8&58pgErBAl{%Z)zQKXB0hsNcn#Bs|1D5DSGJUFFKw)#gJea=sC(EpI*l>ZW=58pgE=)cCZ z)n9D%d47R|{s$bV^p7z5@Xdo$`edvB9HV~+{J}y0eU4N9hZ}wP=D|Uq<4d;shZ+4V zVFw5OhaIQ<4>kJm&4W|=WUIf(=yQDo2mNNa2YvRRZ1oF9|7Ea)gZ@K~ zQ~u93`tZ$zgFeTHZ1tZ7*7cwB9~|@_be!@(*yzJI4-WdQpKSFHGWxf{4i5VFJ5Ko@ zX!PNm2dDJOR{sE_e>42SLH|C-DgXVAK78}wls?(&?`QO141aLYzt?fff1%NbZyp@< z*?+RtUjW9M&G!%Te7JAK^CR9T;&~Czjd)JPvm>4r@yv*4L_9s>X%SD2c*_66lVSJs zFZmyg12~K?&Si3Hye66Pg)I-(@lF2QvmM_iqfa|H=;K@_r}XniAGSPL^|Qz&Z1ra!NmI^kK_`gFbQzTm7V=pM@{K0t)&#m*p!V>ks$vd<0*XulmV9JRASq zzl}a)!9kzrI_=i~Uk!cn1zY_b+4}zztj8DmbKs!QbDehUPoH1ZirtN&-C&tnG;`dCZIDSy_e`t${-^vPELPevc}KL-x_Sc}Lh zfBL9CeZi{FQ$g73|H0^U{J}vVYZ*DE|9iBlK7GNepD;Js>i^E@b8NvuA8R2w<^Nl> zsXl$dDSfil$D9rGpX1Lt{ByLu7QZcywUnIl{|(wypT6LfKH2L38m#9R{lP&WYcDzF z|0}eqK7GMKpY@Tg{!hUjSU2v4?R0EEiTKA6|0v=gM*PJ8!aqQcP1r7n-%fmjLp`TD z&TU3LZ$tZ);O}Fz{@|29?dtzx?0*k-+n<;pkMzJPJ=#@|`M(?agH!&rt3UI92llzB z|3Q3dvBq)k%kKSd((dhk{F5%n$+6zv?D=TVxWAxY(&HKT!?|x8{nd_B`m|epaL`}j z{1dOAIl{Bmf6VBwf*qXFr`_s-gZ_h4Cr< zZyNoTu!B?jv|D{}&|mKSRbR%3b{!v%*EfuQuj7Nxi?oc}i=FVELUv3b1&H*4gS9_?O_TDdP6JN3XpkM(^Xo9c1=!6`l3RgbZsGj{5M zgC6VqEH>5Scz{!Sw5uLtKV$6F0|z~xAD_l%#}Ay+qh0kF`zd3m9ysW+zE5J)`u202 z(xYAV82gDx51i8bI9T<#et=VYw5uLtA2I$MZ*a<=cJH4|!Tv{#KaV#!H0|&ilW1r`U>Tx{5DLvX%kFoDWzxMIx&%vJO`SWeS^IUJ|c*9@yk~!c9P5dO! zK0cv8?HbSV0;l31XmIW(*za%XwpV6m{ zto`NrLe_eDJisaaw>Mboz1Qf$mLqGuj3=uej|VuV_qGP-ST8u#J01IPHTtxXwO$@e zvg&hwgH!tVG+6Y(DgC>RK5b;x=lmsGeQ-+uEe#fZa7zEpMxQpa>a%{b*UvB?IHiAA zgGC>l(tnfDr;V)o)FWGca7zEq28%v8rGJOfr;Tj&$vQqfzTlMp?F|-va7zC+qfZ-I z^*KIds}D};zp=qGA8$2!u;s{JFJXOT9S@#A;FR7Q&~~Ih|9_2r@)E3n*TU~c$LgP3 z3})MM*mH?am&5Oe z_yh;NQyqurfh)n+W3&F?lt1m8k&ox)i?RRO$PNy6`d$~=!NLA2?7s$fTYt>g!bj_Q z9Q)u@J+x~*tpA$GADr^1UHw`A)sY<>?5zLQksTcDtRGvd{+M40AFUtv{yA`}9@@1Y z*8hsgADr^1UHw`A%Og8D*jfKoksTcDtp8=O+wqV2rSQ@Ezlwcusvg?49@fvz`h!#c zw5vbse@SEq2RrMBPb!`<8qfM)1iP(2<`=?8>vj-{i2T7Rf7;cbwY(s* zgM*#*KR>dAgPrwXicQaVt`Fdlui4vM{rd1}@FkHyIOR{f`hN=hyNy5B6L89(cJ=36 z+!fiu!TwR~@5E;71*i0ASG{T2-(mcjADr^1UHzGVJn{#p{ApKz-tW~Te{jm5cJ-(J znDOU$gH!&rt3T_n8GqIfPWjWW{_n^B#gRWa*t$!)<2dDgLSN~hEKNR_cQ~tE8KkFZi{J|-I+O7YV$RC{Yr``G&BY$wppLXki zf$``02u}Hfga4h_Ki~Lseu7i}w5$HL*gr4w2dDgLSN|KZf3ERoJ>Zl-?ds2azjKT~ z>j9_yX;**N^SsC(obsn#{aMf1kv}-)PrLfxi2bvSKkEml{ApKzu5V`=f7TC9`O~ic zJm1fNy~EsZo`$wf*e*vq*M4w_Kh<%#-tqc6fX(`YQ~tDXHusksjJ+8)aHxmZj`i5= z`U4Jn^rv0xpNsu<*mOPQT2I#Xu;w_#b3Hr-oBChuS^e2}*i-(`MVqY$9PF%zcCBX= z`+e9{f5fxZhdsozo|BC~*J85zbFBrZ{7*ug*2DP#4tCZVXDv4C4^H{huKt`q zYa)Me%Aa=iXML-&X@AR}wSJB#>>-~0U1j{awvw$sIOTt$@h@SYZ2iG0|CO+7e>wlb z!OroaUF+w$(2Gs|IiBE@Kke$z@i`dDgLSN|>8KR)sYr~GMG|04E}i~PYUf7;dm z0_-0f`GZsbw5vbo!!g+OcyX;E>v(c40f%@VucNWq@c{=r$CGx|=Xmx+{@|29?dp%U zC)Z{CdAz_Wf7;cb^QjY?*3Y>>*7|vD!6BaYcVJWhcF*eH<~Zd~AMG#e0S7z#OS{&C z&m1+ZKRD%2yZTda88)qFg=eh?I<$v)*1y#FGnTCW+{c#kKf>^{V1JI`XM+znO#5Mm zX+P93?TZZ4eu!b(3x;VwkpD^<*8AJ=`K05_>%g~QEu4E`tv~Z~$JzgZ z?^eX)Gk1W|`LmLqGva~y|! zfA*~Ts7-&H51h)kkFj$+=b3!432VNy9fy4X?OF3toAEXuIF)a%u`}NslMgmw&3C5b zknc~PH6OJZZ}Wju`DPnC^UX5(U=!ASr#lY${^(irQJe8LA2^k7rm-{M43iHwVa+$- zIOO|-XU#`##@l@0RKDpAd%}2J-#ZR^-*OzzFKXl5SG(v< zF?z7&$X+k`repQbJnlH?@p?Ns(wk)TV9SwJ?=y~r-d7z5J>NH1&jVB_B@3wl3w9Q1zZIOsuJ{`p;hykz_!AC5-?J6Y>vJUHk*>Nw~j zclO^6JN5W?#8i(qVb%Md_6u9^!zvh{G_Sp zCeJsZ?RxApp7v|8y$bs{AF_Xo{K@K%<1KdeXFRSUVLYz(?EMqWU$Lt{kH=pkf3o!_ zt3UJoIr1la|19RS*u6i`zbw|^R6S(tPgZ@_gEchePgZ~SkF5U8hcz(ePqzMK^=JK< zqbYx~^(U)8=hyFz|AkbJ#N+x*TWUU% zb^cM~HzptRV=iZLUy$GIKFL9k^^mn5#L_qT``F;m{II9;lQlncV9b-Zxce(P-rx{F zRIbWT=ofLXT4Z^g8w~^v)@O(8?ld1v1`4El{U2_mK@^G^K9#2e&tGgIp7VjM^&&R=xUsX|?_&E7>f7Kx$swNgleJ#N(l_|~*x=84VNZ=WS?gsE zoYSFRp5NF)JnJQEz0CEPu`?d`B-t0D-u3QNcq;fd@D z^{7o&y%#tRdVP*ldhk!_eFHwKM=i4IJ>PNAJIQfM5B@2=ufs?6s6|%2%N+;3HI7qy z@K5P|4L+(zEwbuy%>)O%RgP17wCnYhRswM=&f{|(u03W?ALqZV29b~_Gw$2m^v!9S(<#&Jpy{wcjL z8t#Grqu?7cpE-803BL}^HQC!kzMak<>R~O6*W<%$4LFtm3&u{p&zpR(32VMC$06Si z&)R=zi@(hWy;Q!>MfpB!^1+rRYrYQ0A>X)X%?EAqxA_pC%J-Ql-=|GJ*s^5J*XB6n zt9#ab&=!B25AmsdpNjH*(&U3JOV)fXjzhjN&zcX~;&1aIK9%niQNE9xe6VH7ns0^U zkgw)h^FdquZ9c@O@_j7I_feA%wk%omEpr_5UF=!&L0kN7KE$W;Jrd>nh{*?AmaO@X zavbuFde(f<7Jr)$@u_?tj`DrTo~`%FIAvSiJ7xZ{v-*t6z?w)oq8h)?BvZ>b{z7RJ!?K_i@(i>_*A|JqI~z8 ze6VH7n(sizA>Ve-nh)CIZ}TBOmG2!$(2R#ZnSCtsSOT#@D)})-e1G6@fqs9rNN^2X0)juwZTCTzQU?^w&S43`?b3w zy*Hsv^{5RFdhiuiz0)11^zMxGI4-J3ZE(ox4Gwzn6;{2aj#GNL&r_EAZZ>+<1_wR(3aj2?#~PpE@wh3{djr~Z z{HP5Mdhiuiy;B?qy&r;cZ>lWyy&i3gRijao#a^KGt|SmrYw3lpiT9t4Gwzn z74~|`cN}ZH=v^P_z1HYa8yxiDE3EbPI!@_b7wNsm=usOS^x!M3ddE5rdXIvyjr6WT zoA#I5;GhRzVb$w)oYK2G(tEYhqc%9`!B<%I+8w9#UKQ!R(&$ke9Q5ETta{CkQ+lt6 z^j>cCs0|K!@D=uY$@d%wy~n{rYnwlc0ZT|{;75S4@U+wDO3;&(Q|7y?bf3|1uFZp&v{$%SmE z{W<<*t%v#Qkw4k`lhvQ&I~Mtq)t}=@R{y2oTI5f*{$%xUhX2KpKUw|NuKt{_qme(^ z`jgfFbof^zf3o^>zLUMbtal@kKiT?|)&Dz)ACCOV>d*XS_5U)s68V#@KUw{`zFidg zldV5l{l5tR3nPEB_m}%IviHyS!oLjG_2FvI)}MCu=lE}r{K?jzto|F}zb*17TYs|p zFNXit$e--}v(zJd|Ktl`tZ|`!^eu~XI>m#Adtl!ZaWUcxB0fLj^9(P5-nkK<1HJ?6 zH?IxIl_lQ}#&sc!T*9}3ufYBVo^fBA$2y!vF0tPV#=4tDE@3@B_j$&BqkO-H+_Yz( z2WBn!)J@pi!gx>*KB?;!`5L!L4AzK5zu)3|fi1*yy(FKBd^m3;*ICBS8ej|lcRS9W z0snomk594R?CVD?+k!vqBX_`lFFx<`to5me>LFJa=UAv0`{bavW^#XZ7_D$yB^y*)H~08l0!U>neZ*JUygmm(l_|~ z*x=84VNcadzQ%2m18Yt=zFdE>g?Owr!dfqLJ=fS-Z=Ye-2hN_1`sTV%v1`4Er7hUK zZ^*}bVNcad)_SRVlBpN_mf&*qM)P&tJ0UQ%%)pu3j@<*e3@)ju%H0JdSOr1OV)a+*>38^J~_m*Ub5E9Ty4hA zdRq;%Ub5B)Uvjnu^-p)7+z;$+As_37JykDR>!n7ssTcd?5YKwaS}$|0Fm~3v9NRL~ zGtGUHL;O9?9_mLdeS^P`4gRbb_Ef!Ot(Q5LntHKM4)H^twO-~r%Gg=&k=T}?-l^`B z9O79oS;rf(^bK~_N5*jr*LSkkrcu`e=&@e1){8hkGY9(y@N*3FTsj4OtoibeL%#1i z)_lw*{x%=tQ~4G}`3^DpV9Sy4Otoi=tIOO}9^Zmtf$oEypAs@8G-{wPnD&PDl zAMSa>e1R=X)_ni%IOO|^cLl7^&W7X()(+q_ZRql-{0R*i>!L^6;{2sJ5K5S zInu+L8uX||Rz3I%tKQojt6p*~_)n1@*36(sEwbvtS6KD#ah%e_8W{Kwu>Th}?Ju>+ zss~?T)w|1ah<`m8YmPF%4@!Os?!frni+!vQ!q@nJ9}KqSXU6_>&uWJ)`H9iv@&93i zlOH)wegS>fLOs}%pMu|vPsWpf41Nnfp~b%G_fxEuto8AI+Jt-!e6Z;~Zt?{7?}jh6 zsrLgg$M#OoI(~jE!+4wk`}eT<_lL3%4)%+jJyU_+IL_@s@Z+$*!H*YX$v0rT9{Zdh zWL;0M_KbPL@3#_;*LSh6@!#>R@gMVSv}m4*jG5 zx1;=I&Hqtv*Lc=XyXNPZJ_fdSvc_|LA*=r*;BQ6#Wb02>|Bt}`o5r8x4-WNn{~NID z_$jL%=L_w&KCo-Wj{Z1rik`efDT@%ao`j}P{R_4si8qFv*8eCVV3x&LX{ zb^MeyKlN$X_^Ul@ex5&{GWG@FPh$H7?g_Dm^OGFnx#p5@#`<#^_7N*S>hEKN|9Q@y zTHoQT?^7fPkD>O5``AMKkY_(0k_&5Qu=99u4b^z=V@*rhxyGrT`;SC+aIkY9b2=5z zIj-^C$C#$<9AmX}|3k*k@%$jR_hCGL;y%eC{y}HYyb|O2M(iUt`GB!A{{7fAo?75k zJXzxrOW$CBz;g%m??wAvp0B|^wosGmGuL}feAV+P;&-^%!V%kQ%%)pE?!f0yt$7p=yAS~b-o}jdC1sV?>h~%K5&BLko%GQ z6uZuE#L^b*-Z$i9{jjIzH(BeaCXa#E%YAGip7oNoUgo;r*jev846|Nvav$pbq5BlO z){9u$g5CRue5@DtRJ~-amzrGjv|jFG3-PR%to1S%=asH6toLo$G@kp|)SkT7^IXg) z_7$JQ)KHe>Gr<2=`TGUQtfQxC^7*k9;4hwF46edYgEKzs5A>_6c? zlba%caPa>=e89oq#|HMcknj1!WuB9nc1k1=T+VFW#HH2{`4_0K7)Oy zS~sE^|T4*h!^e1r27f5w7S{@~#MUFRG0eQfY& z|B*A*--%fJ&l)kOL;vcYwf{$euY+CZ!!4edqyJ^>V{V9jDR?{fF*nG`t^R%=b5HDg zel79#h45!Tnyuo3-dH&I^%fT;gu$=)pH3s~&uXt=>o!KOAwz=)pH3 zs~&uXt=>gZ{Dl!?T?xk*z6n|N;45tPuwr>xQM$W?gVRpU`xQ^|DS2`Z2o^6 zvG@4<4PI{<@5eLg0=G3-uAk5d_NA~lN4z59?A%;2Lg@~UW@j(qv zn&5vx#QQ}&-|)Wh2Pepre;wL?gMG|}@c)I-M%MpdAn)1ye+9IM@tFhr48yEvis7l? zNroqbp&8=opKWmFpN^9bf4p$4XjkU{MU>*NM*OvizaH^7BK~H?--`ILh`$~2cRZsD z`5UpH!_L3)Im_42u`-;yHR9VMz9Zr{Mf~Q7?~eGb5#Jl}eG%Uu@q-a#jbQzHym)-b zxp%w%$^S)T`2&&tLlJ)@;zuI>c*LKK_|p-8Hsa4m{Ak2qa-85pju&_Sg-zF2_U|7N z|IIMYo6KJ${tNj1(0c_w=}Y$OxA>A(AJ@~&pAA#*za#z=SoP>jRz3QXt==CEQ|}KE z{~oM*^d+kveaTkucZR9=+lc=Qta|h%s~&yHRu5}TU|g>1{a<05jq&4L`-S7& z3h@1yXRnVK=a~E(lvq>quYvsyjx)ambN^~=KgVYE$ZEd{`#-~`^pjm!{~p9XeQBQ!=JD7S@$NL|Hagbl?+osr zCH^wR^Vo4bp1`L0IbPt<-)kLbzK=E>Pkv^8fX(`YgFpL4yZS%j_5*uci061w(~j3f ztmDNRzK2cobG#nMX2*-H<3(Sx9WToqFT*lk;4oendHZF4yja_Jv3(nTewF(a)_OR8 zu!r$@CHOnWpRr`?4-WpXaK1s`#|D3n7jmb@Ya-V1VvUbs(|jDSZ(+0JMb`16FWHWl zWsa9&882`cuM53h$BVUn6PxDe_>ghk&%Mljl0*MrinecHv;JiDXDm4QU+HY&{jq9l zJjV;MsqvbKRiC-OhE3xaVE?Pw?0AuNyy#1|<7JuSWmv`w9L8(N+jYEH+gGq@evTLU zOX%~9+$TBopY|_fv;JiDXDm4QU*T-QpW_4H)c8!q*T4r`r~y8*&s<-`rujKuk7Bdq zMV{-|FZz;aoAt{w$IGyc7dVX9R&UqwLLKsd19w0V>wo?d@Mo}D{&a)o`arhV4>I~D z*B4%&K84N4i$B@=lhyy#*#9Ip?ax~rhwCHz1AAcBXZcd_C$MS!N3j3#h(8wbN5NX( zd$CW}`dABD>*M)PP1S$Iaj0h(_`}9N({Zrxh)!{kX?~6m zIOx|S9tXc4o6e^$&#K4uk#^0;`9`+&ybo;ifkVEFVY6I|cnth7Hr20sw)N0%^O3c_ zmwW$nFc;s1{rC9I)`PZC5A`jNg5QnJ<|o_yWSgI?`LDu0+2(%;tnu%{{yPnGe90Qm z^^>gm)!*iO(9}N+UvO%?X+H}6e+@oIV0!?Y#`AuNtmDBkB5VGaV*h?@)}L(s$=A3o ze=W`E%0_d9xn#p5&4tVzsK9v|3%>2u~~hx^(U+U3$cG2HtSEe{$%yP z0{d^oX8p<5pRE2b!2Yd~KUw|RU$Xi?AN#jpv-)J~PgeiSv43;qPqzMK^}h`JH({HN z^O5KE>m7&Vb6&*fgWrHn_4+;A^NDt?m+J-j9KYW2`gtQZ>rd8tF7}{X z&|tZqUk_G&)>}#D|3TG{?B<CeGoGzJHMPH=$Nm-AY(BE)V{UNBH{fi+4jcDFJkLk6=DW+YuSfd8Ijs43KJUaf z7vu9FK4~LseY+ywoo2beg@3ret$RDio98NP*?~>#d9P=kFYoc}>&sK08k(Q|1&8^t zKH?4FF>KnOcVWMVP4$)4-sSCDPp4?RsUSi zs?V{Y-RdJp=-+c;W6s$aKdyINFK9msjB_Y=O2q5HBiJ-Q>l-%A^{HZ*^^vb}8-GVz zSo@>?T0h6eiQ=Z9siCBpXnqFwoVXHWG9_P_%^eg*n>KjPLzyf)&KJRjx9 zjmw~>`xh+9q;W%?>g8lbNwT0JoPM74;<>{ z{fuSSOMmU}YVbB}Hvd+WpXa}2UeC!kzh&kJr}A57e)?ZQ?zS^(U)8&wsM|bM4|ilKS7}dA2`4-sD;Rxi;}0 zL60x*56;A<`qUz;o$Co%^|{`WRj=y#9OPpzu4iXpQ@#5=TRqyX9$EFc){(8=X~xdA zj~v@IAIFDw)#v(#n!|8&|YrUOXmM4RG4xQrd>pZLebHUVHHJlV#t0Bbz;mm6k1WYy!fgKYK4R&N>D>Mb=)J+kWYT0ypY zWUIHt%x{jJWgZJ~IDSWZyUu57(O;RhSw^1BVr;Yhd_M^LM@0M_u=eM0>>n2KBEy^y z1#Hux_Ygj5BWwI2o)3ln?bxSQ0h=;&JsX?)Q*Ymh=S4gVJRf@3d0+BA*tnMQd?C+; z{Xu*(maP4qgZ&xUG#}^pbi>R~4ebwYWc8nl{Yeow8RmGBpN0JQ;gfxP498=Cd`|hu z``*Bxo4^YrmOdLh`(yplpA@4%DP}*cKkMdPnRLSM@#h3T+TOeN3bFQ{*6Y1;?BjnH zd;TLD%dy(K*mGP=?^#!9EXQr{Vh3DI@43Aio7?NyGh9sXX+G5b|6_ZXcY}**#Ag4! z*Lis*#!s*BH-1qZLri|uMS>xnkGnUr?97+?4$Z_KrDvF(cMe zT_u*K^DS91P#!J~R999i)xlyNZe!JPxQ{{N2@%7}n|)mNu!d*9h&?k$vtNk#a}j?g z;!j2ViHJWI@gos`IN}dR{QijF8}WN0epkfrjQD|w-w`p_LpvUC1Ml5@s5}B!%%yP7 zX72&+UF`F&U}&b-f8w~j1-N&yTd!bfrnl%m5qlSK?_zyS@8(Ak!k_G&_+#&4Prrfz znO^^i*xP}77dya6#5VH25x94;dd^bJS3r+-m}~%YQBE2V|}eA_PV`}z3>T1Xy)^^dmXFusxc?8 z-s{*4eBQ=by=t#x&+mmR#^p={@BNO5i6uh(D(EUeim!Pj(Cbn9@66fLtUifiEB%`}vWb zqfvPFrI$7@?YMmDrOnGbmbT%uWhwUX*(#rxL+4!h9r2u9<)KUD61BQIQd(NT#q7e; zV4YW}mBZEXk^0g?^YUig`eu26&Uv1=>xIl-3zrrqY8|N7ixs&{I-SCig-zA5vGSHm z$p(uDa`0y2^wY{)wT!;8&86bd?!vK!mO_1dX`~RU9jLCZE-knV=W6&=%B+5UaaVbG zeAr4aDU>Q>r2?~}PC44;F2d$Bz%;zbb`B7RoHywSIM2SmJI#C))@{ya@A&x?3Y#Iquv5%IK$_x?tF z@B)NlQMjO2J~38J*x9>9VekTpF&CS?zY+HfXYYAehz9Z|*x9?hn|dXt*Du2OLgU|i z9b3HJ#fC*N`R888_DX1`x8Hpt@89=2cJm_=)ax&@h<$ReV~1{cvHs$Y*uVbAv1dLa z8i@V#UdQrvB7S;@3i65AKVfI@j?p<+NKEf(kH{xte~+ELi#@AXVtV_0sQX8G5=@Zf zQ)pUx)I@7`%Y?11i1`p=n(_ms8Wte==LVYc>#MaY;9*$uxh^gd^7rO**%mysB=@5k zyB*lQ7rT?1xZF_bt%2xvH)z^a+TC>oK5J@!gg1_p-0)EPTki!M6SSjo} zX67_DRmbb0?Gm&VE8D8Ia((--Ghb3T`nW=+x^3~UC3x@0zwep3^2M2T8^F$CbE!UF z8yVwet1wc;KD6Oq6pcc4Yhl;&g7fSfDGald<-wv?ER-jT+qQkUP#hVePfIiM&}&N( z*S3~suMCgnDCWf|X7#FP(64%NWV`R!i=froGO%*P$rJW$`)(Y9EmhQBK+rZE3fDDM zaRnlu(da_Z7x4l}J?C%~F<}jH;>+RvjJiKq9n3_f3^h#H`zY_uXWDu6LOZ_$S}T_K_x1?y`W}`f^29 zCJIYYva-l6cFiwbPKWEsMc7t;BpVIDSfx6ueM$AdSgTJw03~sxPqi}$EpSM z)jh$vnZ6BWUv}xH)7JH`SuBIM)OknKoMB?dyV^q0kC`;MYiMz-P7Cfg(EEC+wgZ=E z$-11+U%a%s^Pn`u=qk>PnvCcehYq(tnX}G}My|N$@NDr-dvh;=TY$yIrG+hWJHdO~ zmA&gXu0CzuM%U`*l+Fp>RMbkt#q!7y>e|UC<05Mw!aM6Bl)PnkVaxIYD%}F1XLKzb zySP^O%VH5)M;+OJ>gIuoSL2Jvi#3#0tv2of&PT{Ix(6t3(W@ZeYAjp2^2CX+g7B+W z#_Od5j^lXaDtr!t&OYn^+XHn8Uzmg=#XI}%t~2{qpKXuR*`->wfLU&i$0cZ5S}3mA z;wID1@>q#eiBE5%)xEFKoT~rHovOT!V9`qp?uPZublq%rQ*77X)qOhRx0d$4?!7q$ zFknS2)mz+&Uv#Ja7GB=?UZ{D+dfW%d!26}yo(*He#YzR|0&c8}a)xi==<@mU|45a` zPgLb*WLvR({mL_+vdT)awr!6hHzDkX*Jc`Hd1AF%DHTV!S`Y2Hs8mPlweblqym&+^ z;yU#oEIAl&rf|dUWZjsn6h?3(iaT{v-`c{!$!j(g)^OEzK}!ohf;*DA;AhaX<2i+% zRvE(UAiQkpTC8ALfO%ai<6Z=h5BQo*p7O@zC=QiIaV;y243$r8!FQHJ>9{^zQaRDfkS{EXay(76T_tw2UR;@d0)La@ zix=TYS85-vRqJ?vjp^Z*vrviem-0wq5suRqcQV$hJIBHhXiwarwfHzkt(JDDY`bX- zFA0415xylDD_>GtEaSGc(6YoU;0zhzosN62?P}!#+sz0!;w?*M{Lb|e>HEnQM;7`^ z#oFNZ#_h|ID;hG8AE$g!YB^U<^M;4a4kpuHupylzxM;W8z@MGl%M~1ctkt;hzzIBF zINoO}ql@R_ZA5i6orzIpW-AwtN@b*hcdH`ld&)Nc_<&`p06Leq!n2V8V{uZcZl)s_ zg`r}-Sg=Df-qILaDbr*dZ#6bn$Zi<>?sP0?U&_2^cvS$V%j64hQfYpX?P@i@10PaY)j#nz?D6qk;(D2~9(qG+^Fx1?_ z{NGuVp82X0&TDsUWa!M|v=$v-JigSO14|37yoZ;6eqzOPd(d?_gnS5#ND{w41XHgXlLV-fvOlzVpwV z;C>Z`Ut^ncLik0o%#Xm6n&kI;u=hQoKECzE-eW?mD%Ej5cYO`pw5cn{caud;%>NTx0>)WPYcN8*=$QzQYbh1*V=c(O>SI^_QREyDyH|o8PqGu_x>r zt`v5ZYCKVnTZEDqVf7iT4&nLzxJ9Q8tX!XsL&XZd!ai=%NOjQ(#~*vh>W!-g z&f2u5Ft%e`Vbf_RuIpP>ShQ@#iZj|)tyr;oV0EGY^pgrL%Uf2gShHbKVUZcBoozBi zC)J9h+c91%;JAX02wDNLmX_s1^`S+_A4_4BHZpeH1ktU{&CT>)RH&l#t(EG|;}-2G z%NO5^Y-d^^v<>C&uAuU*w^`g?zBj_SRMvL|B zg`wjX4Hw#%w|4gQ^mMi^UDmq1rMV!%M8@t-t+MC(d-r3XK-rml(o{sLG z?v55Twzc=Pw{&zaUDmd|rK`2Mt-B44t=R2sK_1w}>ApYUyfOx~!c_fG#w)ceHf2 zHA`a)zIN&sO*FK&b0pfAx1hJ^K0I4GFgk6>j*)69c^gq=xFP1XPIzpZ^Ln6bX!M9XLGA>?CR*~Mq3L;tEDrvvF8;Y zhqj*1b|~ODG%xMKap>;q?rA9u7M67^Z|*29>%^Me($U=3)6&Dmu&o7$22HKq-58N> zHuZFLp&4!MEf~c1R<@x(JveX(ZS81l?QBO|OIJrbba24Yqt=$r?k+Uq0QPh?a~3Rb z?P>04?P_CmcWZMilR&nonR=}q?U3YehBS9|v|w)FS4CPnTUw-v)1|wW)wOo=Fte2A zj`q%OR@dIy(bLr_V%_a+EoeblH^+f_y1P5OFbd58OsO_#7BG$-Jc!-M1_LLmw+te< zrL_wK%hu-Ro)*fr;qYKaNfXL%X9qeko?WdtqP`IJl(n_DV2Ywm{n}AcPa6&i+B#c0 zS|zruJULL%rsn=9Uf-Y-z^{(8htnA?|3$c+eHIyA3l3 zt<7B+J~<9Ke?54$L4x}RXj#{C92J}r9cIpOh%iwQ z)sBJbX<6E{ycIJ>JaBTiwad6Sb5P)fv~8U@O;8WJCW}C8Gp9Z$N^^5(w`jMwpj+J% ziCNMiYB*48#D+m8YoJ35-NM)gQId*Y^Tb4PP`CvHYL;9c!F zr{US&iZu^YizRiowl%kNf@9pVp0!ALb9;A7Hxt2#j<}Mra9}bp8Z!lF0wr6zyV!(N zjFZxxvF)gw3!BVOEI&9W+d6s*-OJnCdl1kK!zGIfD~>;Q#WrkM z>DUfF=%msJ-UCz$+uVf&dxQ9WBdp&eb=)Q7j)2qt*z$6dkl&79V#?QxjUSx{@MJ3*x9LSaf<~6~weWLepevpX1xtRtLw&`04-_xh=}f-Q#ux zrfCdHrlsyBrn7C@eAl+BIx>Qr1YF|>TyJKGHFS9&!PzGl$4W*JXq9{ky+~nacJlbD^|HPWjcDWLoO(=pedhr^9_U9w~isbER=wpM0G% zSlYN1K6z=&)r-7`n?*>buPzsH_=j=f~En`esSgtNH-3C=D%o5(Z$?3#srZgw`3?QAF8*~>G)`jd6GQ=4qh9w2{m zhvJW?n7w!+O1MO8InyVcy;Jv?y-%}P$~v6z(GtHEG_uXFTW&p`w7xhxDhq+E!_kr| z%k1RISR6QgP?ao#(!gaC4HGSKauDK4A;~-f36U$r a(~a*8 +L0X = ISSUE = SYSDYN = @@ -6,5 +7,18 @@ VALIDATIONS = SYSDYN.Validations : L0.Library SYSDYN.SysdynIssue - none 0 fill 1 + none 0 fill 1 \ No newline at end of file diff --git a/org.simantics.sysdyn.ui/plugin.xml b/org.simantics.sysdyn.ui/plugin.xml index f6fb712b..bec90398 100644 --- a/org.simantics.sysdyn.ui/plugin.xml +++ b/org.simantics.sysdyn.ui/plugin.xml @@ -1529,4 +1529,10 @@ name="Export Function Library"> + + + + + + diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java index ca0af77e..377d91d6 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java @@ -13,7 +13,6 @@ package org.simantics.sysdyn.ui.project; import java.io.File; import java.util.HashMap; -import java.util.Map; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.IEclipsePreferences; @@ -26,19 +25,21 @@ import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.WriteGraph; -import org.simantics.db.common.procedure.single.SingleSetSyncListener; +import org.simantics.db.common.changeset.GenericChangeListener; import org.simantics.db.common.request.Queries; +import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.WriteRequest; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.RuntimeValuations; import org.simantics.db.layer0.adapter.TrendVariable; +import org.simantics.db.layer0.genericrelation.DependenciesRelation.DependencyChangesRequest; +import org.simantics.db.layer0.genericrelation.DependencyChanges; import org.simantics.db.layer0.service.ActivationManager; import org.simantics.db.request.Read; import org.simantics.db.service.GraphChangeListenerSupport; import org.simantics.db.service.LifecycleSupport; import org.simantics.db.service.VirtualGraphSupport; -import org.simantics.issues.common.IssueSource; +import org.simantics.issues.common.IssueUtil; import org.simantics.layer0.Layer0; import org.simantics.modeling.services.CaseInsensitiveComponentNamingStrategy2; import org.simantics.modeling.services.ComponentNamingStrategy; @@ -54,7 +55,6 @@ import org.simantics.simulation.project.IExperimentManager; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.ui.Activator; import org.simantics.sysdyn.ui.editor.SysdynEditorNamingService; -import org.simantics.sysdyn.ui.validation.ActiveIssueSources; import org.simantics.ui.workbench.IEditorNamingService; import org.simantics.ui.workbench.action.ChooseActionRequest; import org.simantics.ui.workbench.project.UIModelManager; @@ -196,76 +196,16 @@ public class SysdynProject extends AbstractProjectFeature { // Issues - try { - - session.syncRequest(new ActiveIssueSources(project.get()), new SingleSetSyncListener() { - - Map sources = new HashMap(); - Map listeners = new HashMap(); - - @Override - public void add(ReadGraph graph, final Resource source) throws DatabaseException { - final IssueSource is = graph.adapt(source, IssueSource.class); - if(is != null) { - - Runnable listener = new Runnable() { - - @Override - public void run() { - - project.getSession().asyncRequest(new WriteRequest() { - - @Override - public void perform(WriteGraph graph) throws DatabaseException { - is.update(graph); - } - - }); - - } - - }; - - is.addDirtyListener(listener); - sources.put(source, is); - listeners.put(source, listener); - - } else { - - System.err.println("Issue source " + source + " does not have adapter!"); - - } - - } - + session.syncRequest(new ReadRequest() { @Override - public void remove(ReadGraph graph, final Resource source) throws DatabaseException { - - IssueSource is = sources.get(source); - Runnable listener = listeners.get(source); - if(is != null && listener != null) { - is.removeDirtyListener(listener); - } - sources.remove(source); - - } - - @Override - public void exception(ReadGraph graph, Throwable t) { - Logger.defaultLogError(t); + public void run(ReadGraph graph) throws DatabaseException { + onActivated(graph, getProject()); } - - @Override - public boolean isDisposed() { - return false; - } - }); } catch (DatabaseException e) { - e.printStackTrace(); + throw new ProjectException(e); } - } @Override @@ -339,5 +279,24 @@ public class SysdynProject extends AbstractProjectFeature { } } } + + public void onActivated(final ReadGraph graph, final IProject project) throws DatabaseException { + + GraphChangeListenerSupport changeSupport = graph.getService(GraphChangeListenerSupport.class); + changeSupport.addMetadataListener(new GenericChangeListener() { + + @Override + public void onEvent(ReadGraph graph, DependencyChanges event) throws DatabaseException { + + WriteGraph w = (WriteGraph)graph; + w.addMetadata(event); + + } + + }); + + + IssueUtil.listenActiveProjectIssueSources(graph, project.get()); + } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java index ba68d2c9..ea0808eb 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java @@ -198,6 +198,7 @@ public class EquationTab extends LabelPropertyTabContributor implements Widget { graph.claimLiteral(expression, sr.HasInitialEquation, ""); } OrderedSetUtils.add(graph, expressions, expression); + graph.claim(variable, l0.ConsistsOf, expression); VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); final Session session = graph.getSession(); @@ -305,6 +306,8 @@ public class EquationTab extends LabelPropertyTabContributor implements Widget { throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource activeExpression = graph.getPossibleObject(input, sr.HasActiveExpression); if(activeExpression == null) return; @@ -315,6 +318,8 @@ public class EquationTab extends LabelPropertyTabContributor implements Widget { Resource prev = OrderedSetUtils.prev(graph, expressionList, activeExpression); OrderedSetUtils.remove(graph, expressionList, activeExpression); + graph.deny(input, l0.ConsistsOf, activeExpression); + if(prev.equals(expressionList)) { Iterator iterator = OrderedSetUtils.iterator(graph, expressionList); prev = iterator.next(); @@ -365,6 +370,7 @@ public class EquationTab extends LabelPropertyTabContributor implements Widget { graph.claim(newExpression, l0.InstanceOf, sr.NormalExpression); } OrderedSetUtils.add(graph, expressions, newExpression); + graph.claim(input, l0.ConsistsOf, newExpression); } }); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java index e36ffbad..18083697 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java @@ -36,6 +36,7 @@ import org.simantics.db.common.request.WriteRequest; import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; import org.simantics.layer0.utils.direct.GraphUtils; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.ui.utils.ExpressionUtils; @@ -125,6 +126,8 @@ public class BasicExpression implements IExpression { public void perform(WriteGraph g) throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + if(ExpressionUtils.isParameter(currentText)) { if(!expressionType.equals(sr.ConstantExpression)) expressionType = sr.ParameterExpression; @@ -146,18 +149,21 @@ public class BasicExpression implements IExpression { if(arrayRange != null) g.claimLiteral(newExpression, sr.HasArrayRange, arrayRange); + final Resource variable = g.getSingleObject(ownerList, sr.HasExpressions_Inverse); OrderedSetUtils.replace(g, ownerList, expression, newExpression); + g.deny(expression, l0.PartOf); + g.claim(newExpression, l0.PartOf, variable); + - final Resource activefor = g.getPossibleObject(expression, sr.HasActiveExpression_Inverse); VirtualGraph runtime = g.getService(VirtualGraph.class); g.syncRequest(new WriteRequest(runtime) { @Override public void perform(WriteGraph graph) throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(graph); - if(activefor != null) { - if(graph.hasStatement(activefor, sr.HasActiveExpression)) - graph.deny(activefor, sr.HasActiveExpression); - graph.claim(activefor, sr.HasActiveExpression, newExpression); + if(variable != null) { + if(graph.hasStatement(variable, sr.HasActiveExpression)) + graph.deny(variable, sr.HasActiveExpression); + graph.claim(variable, sr.HasActiveExpression, newExpression); } } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java index fbee902c..4f9698b3 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java @@ -147,7 +147,11 @@ public class StockExpression implements IExpression { g.deny(expression, predicate); } g.claim(expression, l0.InstanceOf, null, sr.StockExpression); - OrderedSetUtils.replace(g, expressionList, temp, expression); + + Resource variable = g.getSingleObject(expressionList, sr.HasExpressions_Inverse); + OrderedSetUtils.replace(g, expressionList, temp, expression); + g.deny(expression, l0.PartOf); + g.claim(expression, l0.PartOf, variable); } g.claimLiteral(expression, sr.HasInitialEquation, currentText); } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java index c60fca19..9af73a64 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java @@ -57,6 +57,7 @@ import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.Listener; import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; import org.simantics.layer0.utils.direct.GraphUtils; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.tableParser.ParseException; @@ -265,6 +266,8 @@ public class WithLookupExpression implements IExpression { public void perform(WriteGraph g) throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + if(!g.isInstanceOf(expr, sr.WithLookupExpression)) { @@ -278,16 +281,19 @@ public class WithLookupExpression implements IExpression { if(arrayRange != null) g.claimLiteral(newExpression, sr.HasArrayRange, arrayRange); - OrderedSetUtils.replace(g, ownerList, expr, newExpression); - final Resource activefor = g.getPossibleObject(expression, sr.HasActiveExpression_Inverse); + final Resource variable = g.getSingleObject(ownerList, sr.HasExpressions_Inverse); + OrderedSetUtils.replace(g, ownerList, expression, newExpression); + g.deny(expression, l0.PartOf); + g.claim(newExpression, l0.PartOf, variable); + VirtualGraph runtime = g.getService(VirtualGraph.class); g.syncRequest(new WriteRequest(runtime) { @Override public void perform(WriteGraph graph) throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(graph); - if(graph.hasStatement(activefor, sr.HasActiveExpression)) - graph.deny(activefor, sr.HasActiveExpression); - graph.claim(activefor, sr.HasActiveExpression, newExpression); + if(graph.hasStatement(variable, sr.HasActiveExpression)) + graph.deny(variable, sr.HasActiveExpression); + graph.claim(variable, sr.HasActiveExpression, newExpression); } } ); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelUtils.java index f1fb5d89..088d67fe 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelUtils.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelUtils.java @@ -73,9 +73,14 @@ public class ModelUtils { l0.PartOf, project, l0.HasName, modelName, l0.HasLabel, modelName, - L0X.IsActivatedBy, project, - L0X.Activates, sr.Validations_DependencyConnections - ); + L0X.IsActivatedBy, project + ); + + GraphUtils.create2(g, + sr.Validations_DependencyConnectionsIssueSource, + L0X.IsActivatedBy, model, + l0.PartOf, model + ); Resource conf = GraphUtils.create2(g, sr.Configuration, diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ActiveIssueSources.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ActiveIssueSources.java deleted file mode 100644 index 06229d9a..00000000 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ActiveIssueSources.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.simantics.sysdyn.ui.validation; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.common.request.ObjectsWithType; -import org.simantics.db.common.request.ResourceRead; -import org.simantics.db.exception.DatabaseException; -import org.simantics.issues.ontology.IssueResource; -import org.simantics.layer0.Layer0; -import org.simantics.operation.Layer0X; -import org.simantics.sysdyn.SysdynResource; - -public class ActiveIssueSources extends ResourceRead> { - - Resource project; - - public ActiveIssueSources(Resource project) { - super(project); - this.project = project; - } - - @Override - public Set perform(ReadGraph graph) throws DatabaseException { - - SysdynResource sr = SysdynResource.getInstance(graph); - Layer0 l0 = Layer0.getInstance(graph); - Layer0X l0X = Layer0X.getInstance(graph); - IssueResource ISSUE = IssueResource.getInstance(graph); - - HashSet result = new HashSet(); - - for(Resource model : graph.syncRequest(new ObjectsWithType(project, l0.ConsistsOf, sr.SysdynModel))) { - result.addAll(graph.syncRequest(new ObjectsWithType(model, l0X.Activates, ISSUE.IssueSource))); - } - - return result; - } - -} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java new file mode 100644 index 00000000..e7190584 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java @@ -0,0 +1,261 @@ +package org.simantics.sysdyn.ui.validation; + +import java.io.StringReader; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.issues.ontology.IssueResource; +import org.simantics.layer0.Layer0; +import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.expressionParser.TokenMgrError; + +public class DependencyFunction { + + + private static String getMissingLinkLabel(String name, String dependency) throws DatabaseException { + String label = "Missing link " + dependency + " in " + name; + return label; + } + + private static String getUnusedDependencyLabel(String name, String dependency) throws DatabaseException { + String label = "Unused dependency " + dependency + " in " + name; + return label; + } + + /** + * + * One issue is enough. The first encounter of a new issue returns Boolean.FALSE. + * + * @param _graph + * @param _resource + * @param _existing + * @return + * @throws DatabaseException + */ + @SCLValue(type = "a -> b -> c -> d") + public static Object dependencyValidator(Object _graph, Object _resource, Object _existing) throws DatabaseException { + + ReadGraph graph = (ReadGraph)_graph; + Resource variable = (Resource)_resource; + Collection existing = (Collection)_existing; + + Set references = getReferences(graph, variable); + Set dependencies = getDependencies(graph, variable); + + String name = graph.getRelatedValue(variable, Layer0.getInstance(graph).HasName, Bindings.STRING); + + for(String reference : references) { + if(!dependencies.contains(reference) && match(graph, existing, variable, getMissingLinkLabel(name, reference)) == null) + return Boolean.FALSE; + } + + for(String dependency : dependencies) { + if(!references.contains(dependency) && match(graph, existing, variable, getUnusedDependencyLabel(name, dependency)) == null) + return Boolean.FALSE; + } + + + /* + * See if there are any unnecessary issues in existing + * + * FIXME: Currently there are no other issues, so this can check ALL issues. + */ + IssueResource ISSUE = IssueResource.getInstance(graph); + + for(Resource exist : existing) { + if(variable.equals(graph.getSingleObject(exist, ISSUE.HasIssueContext))) { + return Boolean.FALSE; + } + } + System.out.println("NOTHING"); + return Boolean.TRUE; + } + + @SCLValue(type = "a -> b -> c -> d -> e -> f") + public static Object dependencySynchronizer(Object _graph, Object _resource, Object _source, Object _model, Object _existing) throws DatabaseException { + + WriteGraph graph = (WriteGraph)_graph; + Resource variable = (Resource)_resource; + Resource model = (Resource)_model; + Resource source = (Resource)_source; + Collection existing = (Collection)_existing; + Layer0 L0 = Layer0.getInstance(graph); + + Set references = getReferences(graph, variable); + Set dependencies = getDependencies(graph, variable); + + + String name = graph.getRelatedValue(variable, L0.HasName, Bindings.STRING); + + System.out.println("SOME CHANGE IN " + name + "(existing: " + existing.size() + ")"); + + Set labels = new HashSet(); + String label; + Resource issue; + + for(String reference : references) { + label = getMissingLinkLabel(name, reference); + if(!dependencies.contains(reference)) { + labels.add(label); + if(match(graph, existing, variable, label) == null) { + createIssue(graph, model, source, variable, label); + } + } + /*else { + if((issue = match(graph, existing, variable, label)) != null) { + removeIssue(graph, model, source, variable, issue, existing); + } + }*/ + } + + for(String dependency : dependencies) { + label = getUnusedDependencyLabel(name, dependency); + if(!references.contains(dependency)) { + labels.add(label); + if(match(graph, existing, variable, label) == null) { + createIssue(graph, model, source, variable, label); + } + } + + /*else { + if((issue = match(graph, existing, variable, label)) != null) { + removeIssue(graph, model, source, variable, issue, existing); + } + }*/ + } + + Set toBeRemoved = new HashSet(); + for(Resource exist : existing) { + String l = graph.getRelatedValue(exist, L0.HasLabel); + Resource i = graph.getSingleObject(exist, IssueResource.getInstance(graph).HasIssueContext); + if(variable.equals(i) && !labels.contains(l)) + toBeRemoved.add(exist); + } + + for(Resource r : toBeRemoved) { + removeIssue(graph, model, source, variable, r, existing); + } + + + return Boolean.TRUE; + + } + + private static Resource createIssue(WriteGraph graph, Resource model, Resource source, Resource variable, String label) throws DatabaseException { + System.out.println("CREATE ISSUE: " + label); + Layer0 L0 = Layer0.getInstance(graph); + IssueResource ISSUE = IssueResource.getInstance(graph); + + Resource issue = graph.newResource(); + graph.claim(issue, L0.InstanceOf, null, ISSUE.Issue); + graph.claim(issue, ISSUE.HasIssueContext, null, variable); + graph.claim(issue, ISSUE.HasSeverity, ISSUE.Severity_Error); + graph.claimLiteral(issue, L0.HasLabel, label, Bindings.STRING); + graph.claimLiteral(issue, L0.HasName, UUID.randomUUID().toString(), Bindings.STRING); + DateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); + String created = format.format(Calendar.getInstance().getTime()); + graph.claimLiteral(issue, ISSUE.HasCreationTime, created, Bindings.STRING); + graph.claim(source, ISSUE.Manages, issue); + graph.claim(model, L0.ConsistsOf, issue); + return issue; + } + + private static void removeIssue(WriteGraph graph, Resource model, Resource source, Resource variable, Resource issue, Collection existing) throws DatabaseException { + System.out.println("REMOVE ISSUE: " + graph.getRelatedValue(issue, Layer0.getInstance(graph).HasLabel)); + graph.deny(issue, Layer0.getInstance(graph).PartOf); + graph.deny(source, IssueResource.getInstance(graph).Manages, issue); + existing.remove(issue); + } + + @SCLValue(type = "a -> b -> c") + public static Object dependencyBaseRealizationFunction(Object _graph, Object _model) throws DatabaseException { + ReadGraph graph = (ReadGraph)_graph; + Resource model = (Resource)_model; + return graph.getSingleObject(model, SimulationResource.getInstance(graph).HasConfiguration); + + } + + + private static Resource match(ReadGraph graph, Collection existing, Resource variable, String description) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + IssueResource ISSUE = IssueResource.getInstance(graph); + for(Resource exist : existing) { + Resource source = graph.getSingleObject(exist, ISSUE.HasIssueContext); + String desc = graph.getRelatedValue(exist, L0.HasLabel); +// if(source.equals(variable) && desc.startsWith(description.substring(0, description.lastIndexOf(" ")))) return exist; + if(source.equals(variable) && desc.equals(description)) return exist; + } + return null; + } + + // Returns the names of the related variables (dependencies) + private static HashSet getDependencies(ReadGraph graph, Resource r) throws DatabaseException { + HashSet variables = new HashSet(); + if(graph != null && r != null) { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Collection dependencies = graph.getObjects(r, sr.IsHeadOf); + + for(Resource d : dependencies) { + if(graph.isInstanceOf(d, sr.Dependency)) { + Resource tail = graph.getPossibleObject(d, sr.HasTail); + if(tail != null) { + Object name = graph.getPossibleRelatedValue(tail, l0.HasName); + if(name != null) + variables.add((String)name); + } + } + } + } + return variables; + } + + private static HashSet getReferences(ReadGraph graph, Resource r) throws DatabaseException { + HashSet references = new HashSet(); + ExpressionParser parser = new ExpressionParser(new StringReader("")); + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource hasExpressions = graph.getPossibleObject(r, sr.HasExpressions); + if(hasExpressions != null){ + List expressionList = OrderedSetUtils.toList(graph, hasExpressions); + for(Resource expression : expressionList) { + for(Resource s : graph.syncRequest(new ObjectsWithType(expression, sr.HasEquation, l0.String))) { + String value = graph.getValue(s, Bindings.STRING); + parser.ReInit(new StringReader(value)); + try { + parser.expr(); + references.addAll(parser.getReferences().keySet()); + } catch (ParseException e1) { + // TODO: Issue + System.out.println("SYNTAX ERROR"); +// ef.setSyntaxError(e1.currentToken, "Syntax Error"); + } catch (TokenMgrError err) { + // TODO: Issue + System.out.println("UNSUPPORTED CHARACTERS"); +// ef.setSyntaxError(0, textString.length(), ExpressionField.SYNTAX_ERROR, "Expression contains unsupported characters"); + } + } + } + } + return references; + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyIssueSource.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyIssueSource.java deleted file mode 100644 index 93b75a54..00000000 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyIssueSource.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.simantics.sysdyn.ui.validation; - -import java.util.concurrent.CopyOnWriteArraySet; - -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.changeset.GenericChangeListener; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.genericrelation.DependenciesRelation.DependencyChangesRequest; -import org.simantics.db.layer0.genericrelation.DependencyChanges; -import org.simantics.db.layer0.util.Simantics; -import org.simantics.db.service.GraphChangeListenerSupport; -import org.simantics.issues.common.IssueSource; -import org.simantics.issues.common.IssueSourceUtils; -import org.simantics.operation.Layer0X; -import org.simantics.sysdyn.SysdynResource; - -public class DependencyIssueSource implements IssueSource { - - private Resource source; - private Resource model; - private Resource baseRealization; - - private CopyOnWriteArraySet listeners = new CopyOnWriteArraySet(); - private boolean tracking = false; - - public DependencyIssueSource(ReadGraph graph, Resource source) throws DatabaseException { - Layer0X L0X = Layer0X.getInstance(graph); - this.source = source; - this.model = graph.getSingleObject(source, L0X.IsActivatedBy); - this.baseRealization = graph.getSingleObject(model, L0X.HasBaseRealization); - } - - @Override - public void addDirtyListener(Runnable runnable) { - - boolean added = listeners.add(runnable); - if(added && !tracking) { - - GraphChangeListenerSupport changeSupport = Simantics.getSession().getService(GraphChangeListenerSupport.class); - changeSupport.addMetadataListener(new GenericChangeListener() { - - @Override - public void onEvent(ReadGraph graph, DependencyChanges event) throws DatabaseException { - if(IssueSourceUtils.hasChanges(graph, event, model, baseRealization)) { - for(Runnable r : listeners) { - r.run(); - } - } - - } - - }); - - } - - } - - @Override - public void removeDirtyListener(Runnable runnable) { - listeners.remove(runnable); - } - - @Override - public void update(WriteGraph graph) throws DatabaseException { - - SysdynResource sr = SysdynResource.getInstance(graph); - - for(Resource unit : IssueSourceUtils.getChangedDependencies(graph, source, model, baseRealization, sr.Variable)) { - if(!graph.syncRequest(new DependencyValidator(unit, model))) new DependencySynchronizer(unit, model).perform(graph); - } - - IssueSourceUtils.claimUpdated(graph, source); - - } - -} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyIssues.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyIssues.java deleted file mode 100644 index 3ed195ab..00000000 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyIssues.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.simantics.sysdyn.ui.validation; - -import java.util.HashSet; -import java.util.Set; - -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.common.request.ResourceRead; -import org.simantics.db.exception.DatabaseException; -import org.simantics.issues.common.AllVisibleIssues; -import org.simantics.issues.ontology.IssueResource; - -public class DependencyIssues extends ResourceRead>{ - - public DependencyIssues(Resource resource) { - super(resource); - } - - @Override - public Set perform(ReadGraph graph) throws DatabaseException { - IssueResource ISSUE = IssueResource.getInstance(graph); - HashSet result = new HashSet(); - for (Resource issue : graph.syncRequest(new AllVisibleIssues(resource))) { - if (ISSUE.Severity_Error.equals(graph.getPossibleObject(issue, ISSUE.HasSeverity))) - result.add(issue); - } - return result; - } - -} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencySynchronizer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencySynchronizer.java deleted file mode 100644 index 84be096b..00000000 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencySynchronizer.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.simantics.sysdyn.ui.validation; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.simantics.databoard.Bindings; -import org.simantics.db.Resource; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.request.WriteRequest; -import org.simantics.db.exception.DatabaseException; -import org.simantics.issues.ontology.IssueResource; -import org.simantics.layer0.Layer0; -import org.simantics.structural.stubs.StructuralResource2; -import org.simantics.utils.datastructures.Pair; - -public class DependencySynchronizer extends WriteRequest { - public static final boolean DEBUG = true; - - final private Resource unit; - final private Resource model; - - public DependencySynchronizer(Resource unit, Resource model) { - this.unit = unit; - this.model = model; - } - - @Override - public void perform(WriteGraph graph) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - - StructuralResource2 sr = StructuralResource2.getInstance(graph); - IssueResource ISSUE = IssueResource.getInstance(graph); - - if(DEBUG) System.out.println("Running DependencySynchronizer for " + unit); - - Set set = graph.syncRequest(new DependencyIssues(model)); - - if(DEBUG) System.out.println(set.size() + " issues"); - - /* - Collection removed = new HashSet(); - - boolean unitExists = graph.hasStatement(unit); - if(unitExists) { - - removed.addAll(map.values()); - - for(Resource predicate : graph.getPredicates(unit)) { - if(graph.isSubrelationOf(predicate, FB.Parameter)) { - boolean hasIssue = false; - Resource literal = graph.getPossibleObject(unit, predicate); - Boolean required = graph.getPossibleRelatedValue(literal, FB.IsRequired, Bindings.BOOLEAN); - if(required != null && required && !DependencyValidator.excluded(graph, unit)) { - Boolean def = graph.getPossibleRelatedValue(literal, FB.IsDefault, Bindings.BOOLEAN); - if(def != null && def) { - hasIssue = true; - } - } - Resource issue = map.get(Pair.make(unit, predicate)); - if(hasIssue != (issue != null)) { - - if(hasIssue) { - - issue = graph.newResource(); - graph.claim(issue, L0.InstanceOf, null, FB.ParameterIssue); - graph.claim(issue, ISSUE.HasIssueContext, null, unit); - graph.claim(issue, ISSUE.HasIssueContext, null, predicate); - graph.claim(issue, ISSUE.HasSeverity, ISSUE.Severity_Error); - graph.claimValue(issue, L0.HasDescription, "= Missing connection =", Bindings.STRING); - graph.claimValue(issue, L0.HasName, UUID.randomUUID().toString(), Bindings.STRING); - DateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); - String created = format.format(Calendar.getInstance().getTime()); - graph.claimValue(issue, ISSUE.HasCreationTime, created, Bindings.STRING); - graph.claim(model, L0.ConsistsOf, issue); - - } else { - - graph.deny(issue, L0.PartOf); - - } - - } - - } - } - - } else { - - for(Map.Entry, Resource> entry : map.entrySet()) { -// System.err.println("entry " + entry.getKey()); - if(entry.getKey().first.equals(unit)) { - graph.deny(entry.getValue(), L0.PartOf); - } - if(entry.getKey().first == null) { - graph.deny(entry.getValue(), L0.PartOf); - } - } - - } -*/ - - } - -} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyValidator.java deleted file mode 100644 index ffac712a..00000000 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyValidator.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.simantics.sysdyn.ui.validation; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.simantics.databoard.Bindings; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.common.request.ResourceRead2; -import org.simantics.db.exception.DatabaseException; -import org.simantics.issues.common.impl.DependencyIssue; -import org.simantics.layer0.Layer0; -import org.simantics.sysdyn.SysdynResource; -import org.simantics.utils.datastructures.Pair; - -public class DependencyValidator extends ResourceRead2 { - - public static final boolean DEBUG = true; - - public DependencyValidator(Resource resource, Resource resource2) { - super(resource, resource2); - } - - static boolean excluded(ReadGraph graph, Resource component) throws DatabaseException { - SysdynResource sr = SysdynResource.getInstance(graph); - return !graph.isInstanceOf(component, sr.Variable); - } - - @Override - public Boolean perform(ReadGraph graph) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - - if(DEBUG) System.out.println("Running DependencyValidator for " + resource); - - //if(!graph.hasStatement(resource, L0.Represents)) return false; - - if(!graph.hasStatement(resource)) return false; - - Set resources = graph.syncRequest(new DependencyIssues(resource2)); - if(DEBUG) System.out.println(resources.size() + " resources"); - - /* - Set resources = graph.syncRequest(new DependencyIssues(resource2)); - HashMap, Resource> existing = new HashMap, Resource>(existing_); - - for(Resource predicate : graph.getPredicates(resource)) { - if(graph.isSubrelationOf(predicate, FB.Parameter)) { - boolean hasIssue = false; - Resource literal = graph.getPossibleObject(resource, predicate); - Boolean required = graph.getPossibleRelatedValue(literal, FB.IsRequired, Bindings.BOOLEAN); - if(required != null && required && !excluded(graph, resource)) { - Boolean def = graph.getPossibleRelatedValue(literal, FB.IsDefault, Bindings.BOOLEAN); - if(def != null && def) { - hasIssue = true; - return false; - } - } - if(hasIssue != existing.containsKey(Pair.make(resource, predicate))) return false; - } - } - */ - - return true; - - } - -} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java index 40528043..126dd35e 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java @@ -53,17 +53,6 @@ public abstract class Variable extends Element { getExpressions().add(e); } - for(Expression e : getExpressions()) { - - // Get expression from the variable. They have different types - Resource expression = getExpression(graph, e); - - if(e.getRange() != null) { - graph.claimLiteral(expression, sr.HasArrayRange, "[" + e.getRange().trim() + "]"); - } - OrderedSetUtils.add(graph, expressionList, expression); - } - Resource arrayIndexList = OrderedSetUtils.create(graph, sr.ArrayIndexes); @@ -72,11 +61,22 @@ public abstract class Variable extends Element { l0.HasName, ImportUtils.escapeName(name), sr.HasExpressions, expressionList); graph.claim(variable, mr.Mapped, variable); - - + + for(Expression e : getExpressions()) { + + // Get expression from the variable. They have different types + Resource expression = getExpression(graph, e); + + if(e.getRange() != null) { + graph.claimLiteral(expression, sr.HasArrayRange, "[" + e.getRange().trim() + "]"); + } + OrderedSetUtils.add(graph, expressionList, expression); + graph.claim(variable, l0.ConsistsOf, expression); + } + if(subscripts != null) { - for(Subscript sub : subscripts) { - if(sub.getResource() != null) + for(Subscript sub : subscripts) { + if(sub.getResource() != null) OrderedSetUtils.add(graph, arrayIndexList, sub.getResource()); } graph.claim(variable, sr.HasArrayIndexes, arrayIndexList); -- 2.47.1