From cbcff7d1b46721e22cd8fee5fbe9d2797c634374 Mon Sep 17 00:00:00 2001 From: csh Date: Tue, 17 Jun 2025 13:12:53 +0800 Subject: [PATCH] fix and improvements --- test/test.tsl | 5 +- vim/tsl.vim | 143 ++++++++++-------- vscode/CHANGELOG.md | 5 + vscode/package.json | 2 +- vscode/syntaxes/tsl.tmLanguage.json | 28 +++- ...evkit-1.3.0.vsix => tsl-devkit-1.4.0.vsix} | Bin 18541 -> 18571 bytes 6 files changed, 112 insertions(+), 71 deletions(-) rename vscode/{tsl-devkit-1.3.0.vsix => tsl-devkit-1.4.0.vsix} (64%) diff --git a/test/test.tsl b/test/test.tsl index 3767c1c..c66a36e 100644 --- a/test/test.tsl +++ b/test/test.tsl @@ -49,7 +49,9 @@ f(a, b); f(a: 1; b: 's'); -// 三元表达式(不应该有冲突) +// 类变量声明,三元表达式(不应该有冲突) +a: string; +[weakref]b: MyClass; a ? b : c; a ? b : c ? d : e; @@ -62,4 +64,3 @@ select distinct ["test"] from table where ['a'] = 1 end; a := array(1, 2); b := array((1, 2), (3, 4)) - diff --git a/vim/tsl.vim b/vim/tsl.vim index 36ee631..8a2f5ee 100644 --- a/vim/tsl.vim +++ b/vim/tsl.vim @@ -11,47 +11,61 @@ set cpo&vim syn case ignore # Keywords -syn keyword tslHeader program function procedure nextgroup=tslFuncName skipwhite -syn keyword tslBuiltinVar paramcount realparamcount params -syn keyword tslBuiltinVar system thisfunction tslassigning -syn keyword tslBuiltinVar likeeps likeepsrate +# 程序结构声明 +syn keyword tslProgramStructure program function procedure nextgroup=tslFuncName skipwhite +syn keyword tslModuleStructure unit uses implementation interface initalization finalization -syn keyword tslConditional else if -syn keyword tslStatement begin end then -syn keyword tslStatement this with exit -syn keyword tslStatement weakref autoref namespace -syn keyword tslInterface unit uses implementation interface initalization finalization -syn keyword tslRepeat for while do downto step until repeat to -syn keyword tslBranch break continue +# 数据类型 +syn keyword tslPrimitiveType string integer boolean int64 real array + +# 类型系统和面向对象 +syn keyword tslClassType type class fakeclass new +syn keyword tslClassModifier override overload virtual property self inherited +syn keyword tslAccessModifier public protected private published +syn keyword tslConstructor create destroy operator +syn keyword tslReferenceModifier weakref autoref +syn keyword tslPropertyAccessor read write + +# 变量和常量修饰符 +syn keyword tslVariableModifier external const out var +syn keyword tslScopeModifier global static + +# 控制流 +syn keyword tslConditional if else then case of +syn keyword tslLoop for while do downto step until repeat to +syn keyword tslBranch break continue goto label exit syn keyword tslReturn return debugreturn debugrunenv debugrunenvdo -syn keyword tslLabel case of goto label -syn keyword tslOperator write read -syn keyword tslOperator union minus union2 -syn keyword tslShiftOperator ror rol shr shl +# 程序块结构 +syn keyword tslBlock begin end with +syn keyword tslNamespace namespace + +# 异常处理 +syn keyword tslException except raise try finally exceptobject +# 运算符 syn keyword tslLogicOperator and in is not or syn keyword tslArithmOperator div mod +syn keyword tslBitwiseOperator ror rol shr shl +syn keyword tslSetOperator union minus union2 +# SQL相关关键字 +syn keyword tslSqlCommand select vselect sselect update delete mselect +syn keyword tslSqlClause sqlin from where group by order distinct join +syn keyword tslSqlOperator like on set +# 系统相关 +syn keyword tslSystemKeyword setuid sudo +syn keyword tslCallingConvention cdecl pascal stdcall safecall fastcall register +# 内置变量 +syn keyword tslBuiltinVar paramcount realparamcount params +syn keyword tslBuiltinVar system tslassigning +syn keyword tslBuiltinVar likeeps likeepsrate +# 内置函数 +syn keyword tslBuiltinFunction echo mtic mtoc -syn keyword tslException except raise try finally exceptobject +# 常量 syn keyword tslBoolean false true -syn keyword tslNil nil +syn keyword tslNull nil +syn keyword tslMathConstant inf nan -syn keyword tslType string integer boolean int64 real array -syn keyword tslBuiltins echo mtic mtoc this -syn keyword tslBuiltins inf nan -syn keyword tslBuiltins external const out var - -syn keyword tslSql select vselect sselect update delete mselect -syn keyword tslSqlOperator sqlin from where group by like order -syn keyword tslSqlOperator distinct join on set - -syn keyword tslOther setuid sudo -syn keyword tslCallFunc cdecl pascal stdcall safecall fastcall register -syn keyword tslScope global static -syn keyword tslClass type class fakeclass new -syn keyword tslClassModifier override overload virtual property self inherited -syn keyword tslConstruct create destroy operator -syn keyword tslAccess public protected private published syn keyword tslTodo FIXME NOTE NOTES TODO XXX contained # Function definitions @@ -73,8 +87,8 @@ syn match tslReturnType ':\s*[^;]*' contained contains=tslColon syn match tslParamSep '[;,]' contained syn match tslColon ':' contained -syn match tslVarDecl '^\s*\h\w*\s*:=\@!\s*[^;?]*;' contains=tslVarName,tslVarType -syn match tslVarName '^\s*\h\w*\ze\s*:=\@!' contained +syn match tslVarDecl '\(?\s*\)\@' # Highlight links +hi def link tslProgramStructure Statement +hi def link tslModuleStructure Statement +hi def link tslPrimitiveType Type +hi def link tslClassType Statement +hi def link tslClassModifier Identifier +hi def link tslAccessModifier Statement +hi def link tslPropertyAccessor Operator +hi def link tslConstructor Special +hi def link tslVariableModifier StorageClass +hi def link tslScopeModifier StorageClass +hi def link tslReferenceModifier StorageClass +hi def link tslConditional Conditional +hi def link tslLoop Repeat +hi def link tslBranch Conditional +hi def link tslReturn Statement +hi def link tslBlock Statement +hi def link tslNamespace Statement +hi def link tslException Exception +hi def link tslLogicOperator Operator +hi def link tslArithmOperator Operator +hi def link tslBitwiseOperator Operator +hi def link tslSetOperator Operator +hi def link tslSqlCommand Keyword +hi def link tslSqlClause Special +hi def link tslSqlOperator Special +hi def link tslSystemKeyword Special +hi def link tslCallingConvention Special +hi def link tslBuiltinVar Constant +hi def link tslBuiltinFunction Constant +hi def link tslBoolean Boolean +hi def link tslNull Constant +hi def link tslMathConstant Number + +# 其他元素的高亮链接保持不变 hi def link tslClassName Type hi def link tslDot Operator hi def link tslPropertyName Special -hi def link tslHeader Statement hi def link tslFuncName Function hi def link tslTypeNameInFunc Type hi def link tslParam Identifier @@ -153,38 +200,14 @@ hi def link tslCallParam Identifier hi def link tslCallValue Type hi def link tslCallSep Delimiter -hi def link tslBuiltinVar Constant -hi def link tslConditional Conditional -hi def link tslStatement Statement -hi def link tslInterface Statement -hi def link tslRepeat Repeat -hi def link tslBranch Conditional -hi def link tslReturn Statement -hi def link tslLabel Label hi def link tslOperator Operator hi def link tslDelimiter Delimiter -hi def link tslException Exception -hi def link tslBoolean Boolean -hi def link tslNil Constant -hi def link tslBuiltins Constant -hi def link tslShiftOperator Operator -hi def link tslLogicOperator Operator -hi def link tslArithmOperator Operator -hi def link tslSql Keyword -hi def link tslSqlOperator Special -hi def link tslOther Special -hi def link tslScope StorageClass -hi def link tslClass Statement -hi def link tslClassModifier Identifier -hi def link tslConstruct Special -hi def link tslAccess Statement hi def link tslTodo Todo hi def link tslComment Comment hi def link tslString String hi def link tslRawString String hi def link tslQuotes String hi def link tslNumber Number -hi def link tslType Type b:current_syntax = "tsl" diff --git a/vscode/CHANGELOG.md b/vscode/CHANGELOG.md index 2251b9f..a126d56 100644 --- a/vscode/CHANGELOG.md +++ b/vscode/CHANGELOG.md @@ -2,6 +2,11 @@ Notable changes to the `TSL` extension will be documented in this file. +## [1.4.0]: 2025-6-17 + +- 修复:`[weakref]typename: type;`时,变量和类型高亮失效 +- 调整关键字分类 + ## [1.3.0]: 2025-06-17 - 支持关键字大小写不敏感 diff --git a/vscode/package.json b/vscode/package.json index 2cad9b9..af6af4e 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -1,7 +1,7 @@ { "name": "tsl-devkit", "displayName": "TSL", - "version": "1.3.0", + "version": "1.4.0", "description": "TSL syntax highlighter support for VSCode.", "publisher": "csh", "homepage": "https://git.mytsl.cn/csh/tsl-devkit", diff --git a/vscode/syntaxes/tsl.tmLanguage.json b/vscode/syntaxes/tsl.tmLanguage.json index 52cae37..c77d997 100644 --- a/vscode/syntaxes/tsl.tmLanguage.json +++ b/vscode/syntaxes/tsl.tmLanguage.json @@ -189,7 +189,7 @@ }, "variable-declarations": { "name": "meta.variable.declaration.tsl", - "match": "^\\s*(\\w+)\\s*(:)(?!=)\\s*([^;?]*)(;)?", + "match": "(?=W}atvXJ^0j+1+$-QU;jQ!~jCf3<8mpgJ5=JHUb-l zUl|}EPz)sq#EOJNfp*Jz<2h-1zzxvJyk8?a+Z{80#X>F4Qn=xX3N7?BC;0JBA0hJz zaQ>0P$RLu2a;3m@W#K&hIP7EUdh9K?CDWU8MmHa+8+GZIHVn5uWWj~lj~6bK=I`kD zmG>>1S*emz_x~_ki`dl_imIJ965-E`&nwK+;7@0<36A&T0c zcy|JokGJC8sUlQK%KYb+(u;4-2oV=((;qmCw3;|X(DTSDV*F*0<|1+)C8^}_H;~5Ud@d<;HCuKQ~VvNfAwM# z*&l1W;CQ*(p7}KPgp%gE*e%V)+ zwt*LV1}1gy3-~ANoqwXA*zbQ}`k|Ao|9go>h(!#AJ~1y#AP7&yB}C z!h1r7Y2!~|rsKXYp2%SO3Xo+PfxY?Fw(*1Y@hm~W@G2T;S0sc{sJh(~ZwTa1Zj5IZ z7^^KCVtN>QuX;q}`l=^|>7YuR{?7}d|Lhu+3FH?M#1f@XEDj|7>6LcEUGkS6O8khc zA?^fv zk$0bLbvg|{0+c{reDa*8qYUwpY3WrfY=^$5#B3ce*tU6dl&kQH$PU`h)7L-UwIyE6 zEjxq(Nf)og_)E11++^xxm%2DC7T#_mH$`$~T{DEQzFn?z``GwXb4BN9mof!L9l=(h z*@%^~{(bbr@visDJB4Z<;uMAB>RFX=`SH&+N(s)|H-L7(HlYf++nRDm*ExfI;L0+o z`UXu*HgVY;Nos4%h3)32OO9hbKI_A>uVc)t9=jF{Ofz0375XM7@cz&)KQjBt1zM)NQ7O0Qh~i#cxgxwwG2&s6g6nzx3wTVN(BMn24PaK`us?O-zWM3P z#vxsH<#NJI1C24;aEJo%0fnevws|q){&aHYTfnLc*2tLfxLe{ntZ|6i1v+|!-aVJ1 zxH}S5=fT}$a;@G<4IrcZEAHff#9hh`#U!r;aGrawHvKq0V^MlDH*@Rtm&d(v!sw^= zk~Ia};B6XmhZc~Kse%-;OhEMJg3RgMvEEFbi>a(o3!=8W7kP5fvA7x{cz&|--S3Fx z`0fpOVe8diR%qLqXQ&v zKrt&pptOGj9%*cn%(6qL9*S1mC|*A8#^(CO*TlIww?ECV#*-C2_DWI3X1tvA>HDn zpB&R^=I`a5Unx})rlzlh^T8w_MsjV;nZksXlc26A*ePDLD7%qF7v_TTx<-)gKhy()iTO<6d!^-83Y zM@wzJ$}rq(>DwC6y`a;0s4p>MzM|ElROq$y7KC1YZaIiBUT~|4Sh;}u?Qmw45b95*HDC-ON)`12a z8_WYw&vZr~FX_e#7~FoAsIkG$_Qy_gaS>m=)V8nH8U;(sT~@4?2LqZ8)@TwcbkpqD z0Q8P%g1m%S);(m8s0$m1elteNDRqMB64g=30Sq`zZPued-`k zv#0>BlwhCOWLqQHb+Ck7Pnhg-R4djT5DR{&+5N0AMy0dmr9?Ok%!v_`A{K#YKlDMZ zaqYM!)E0RM;#S^?3*cpm^N&?OOH>H=WE5 z)(>_jvZXubR9aVKTTY=Q}_^%K2M8>zZ z_9nw4?|3iAm{q=lt9o)xL=3 zwii$KTIUkwH;Vz-PKFnyM{QxVDKL2p=F zXrtE_giJGUBOf~6%H7KbO!iaG;TL)l^RYeQI`y*2@3Xul5&M+b=kEeZ9A-WCAcP0_ zX3*ICr-O{DXhKdskLtFCrs-{lz#|&l5)L!_=%U^B20*maBQ`t_EtfPSxaWksrKPac zMC2y7)zLLe-6l1Jn++r%C8Zl*O11e|+rL<>KgvXt1%o>wRE3od>}Ey=ZmK&zafrRB92m4y#sBj9)NhlmMP@#xMsYx z&PT@H1Y~*5k}pPz3TR7=6P!L?w6KrZw-)NCUiOKGoDQ-*8|(h5Sx3;^NOg;df*x>h zQMvT_56)?NuOF$B9}OQJCvBeuGGtq?IS{^T&N1Lv!r>-J)GxUO0-gkW&SBK8Zq%tt zYI_X-;Lx;6*|CH$S{C+sN}{2iY;6QW!@ z2Hb4vY7>;(xcArlf@8(6U+r+g$)JO!thtM~lVM0=a_Wq<;))Ry?Th?otrp8rOaS90 zAR|ITN<|wEmld}S5jDSS+cz7B3w`*BSyBeYQ_KL*`LGx!1chg4Cl~C3+-b=ocQec0 zo6$Yz5B_js8>M(|f|ujtkJK4sRYf@C^dgFb!E97tbENw$1X_$+h47~2Nb5*W7>{&% zb*R)Zj*jp6O2;dhgVj1DNWep|<})`CI+2Ck;!b*1Qns_(Xin_L(3isafqqE2rrgIN z_7hoAmw$vK?fgL4gscgLPDW@B= zw(&yk3?3qHDXX2yROi_dq-zUc0>9#6sx6Boir@N#4ys;(iFBenC|+kXN15Z_T4_-` zn!a|T<{u^s)R<&6bmh}eOQ1;@$IbA8BAW#5Wqu`*uB^S4#9S-(OMlr*@AUTbzCEqK z^F=?rGTkSFq5sETf8dA&&G$y>58o0FCkvcvu8_OXXNY7q(H?jhtgGt)4rBaPN%og9t8|GCwT<%5eMSf~>GGermxh&Kqow#W0?UIyCI(<4b;y5>$EYoxn|yx>aEwN+ zr~eNDBL5H|)1UL-t07Vcf^vYcplsmO6cEcXn|~4{${WrCR!7CcwTR3~QJ$nCwEzEi z)Fqq?Jc#1b)c}j55W0fA{|lM_b^ro3L|&q>xzXaA^djJ7f`-mQG;_K^kFUC8T=^DQQ7KKtiRFhNWwzI|T{p zeEMeI{NB8G?wmPuXTEdJ`R9J;b7PY+4w5kFp%6?g3IG5P58wkGH?3V`4k5(^0K)MB z04gMt8ZDyLXi;Zgh!o*~P)&8L;SJ1$nuZVdjSYs+B=oV`S?O0NFkaEO6qj zQB;(9qPft#eAqTRJKiERKq%wv*z6Q}PzrjnoBH*Q#OF@`LrB2XO+C^ABuOc0j$hID zmbKBcoT28fOht&Qd6y&nB*`oF5f4_a66A0!9utAATETa)HV1teecgucKMK3k-nP7h zzQU*}1^BqpGt_!>H;1#N;;{wq+f(Daj@cv=h7W^13$jBOZzQ#l1cd}JJZtf3R*S|d zo4g{3@$~2Mrx?r6IkhLkCEjw=LD;F5RWVw}Und=(g{c9d0TwvG*aSvfUXJl}CemBN z2}D`?N+*u64wqCO%{BHB$mr!RT%&h{8{O5W-+>o|J(HiPk|0|fm;v>5ce7@4TSK3` z(sK8EP2b+3h7hrInQ96mWAU@ZJg;g&wesL=dehSlU1q6#_7I4}Xn!h7R+JDmbQ#vg zV-!oyR>H++I3K3UxQh};qUpdk5e0g4h%a*}{cIP4R1BNP_*2!yzxL53{Z{eyr`K4T zHK_s5w(2|FG2)1h1QeF*4f&xZeup`EGnBOur+J|NO0m#2Ntt-8yU1jW8Rp*iDczm| zA)Ss_GM3?T#S>`qB%=CUHu|PPl;NP=Jo{Nt6(*R-4Es9`taTwG&ZM! zei+x3s0TTI(!p##F`a<9vX06qXhx9?k6iYSp>V=&$pQ{8H^XA@cQ00X3H~GHwK;4GnVYX;GK)5DIMwRZVlhnozv#g zluD?4u1BIo*@1t?ux{ji2O2hSO4&#RZJtzLY_$j$^u@WnI~NH5a-PJ-CPkI@hAlo3 zb#`U%(8AB^oEd36uw?bWUky?h^AczVMMAK^2$uyR($>RjQaQ9|Iw#cA*@-oy1WPY~ zmlt+mViL~}im$f^-7HIA*PydqS#jqthqEQz)r!!Rc4<`X27Z+%Pp23eKBQI4skZ3D za6N8yJLQ?b(aOJ7e(Bvk1MhOjr?2rDye4NA?*(tRl zNRm@eJT^HE19v9>q?d6t^B$)Ek#7PETLL~cWbQ)E@j+F-YK*5F;7>(oKtP8qslFhY z&x)|3Hzo;H%MLVt#nevcR*-mqxvWa~_{xSu0*O z&ogFx>667#4b1la8zdpPfWpYaq)g;1R*WL3rC;Ny-dL1$a_gb=9iYYEIge^T7pI*s zE&0xea?i2a{C;gZ(k6t(a@bu^S*r{bM<+7{;mqA72qY6xIvXVat$3w2q25q~j= zzwBssbw4KDdvLVwEsll{gO#%XF!JpXdsn1$pKmHONW*rJF%Ppx^PYaFkK5p6+i$m` z%Q+Xs^#%dF=?&yQ!)OT?@|cZjr!x{L1Q(C4j%9tcP75a*1Ly;-L*t6@k^ghbf~R7M zGXMbK_-|4HknQR;NYN)I2-;t?-KM-Wv^1G}bnkcRvb;QYAIoId-ka#GPtFVrmR1Hf z`Cd6YThH%T@d?~n^o#NNwK9kA*y1HBVW^_x(zt%Uwt?7|hZ+Ed;QupoyuW770Y&D@ zNFvOF+}FR-KFH^>ZTm<|N2fJc{TwUKyqE#fH!;;Ly#=I`%tqXcMb!f2F7LunfAj z7-Bk1IM{MZ-#C2`D9sxE<PXZD1!%H2U9?&*(e1ykLQym2Q`YT3v=;SIYbss2$ScKFpY;bGyez5GwzG%Z1$ z*$dyY7j|1bq5J}CO-q-}?XvglW>;O!7qfkdCwI;5ZOFvL#78j3T!1Sf64Clv{RIm* z_clX+!`>AAwk$`t3N!A?0wCLpKH#=w{9-u^F5lO~8uv+yhb5cwh!;A1?<`V(yuWG* zw2jBEay%|qx}|$XIrf}H1hkRA^D|hQ)RsntK_{*9T3XQu+8PG}VvSXV& zb7xAm82(Mi=K_3AD)9FN z_ykuJXXUF>O-UD`Ndwuv5w#$6&usCr(zu~4Gu-7+{MH$sVX?*h8{y7H5?hf{6+fcy zl@sb=smLrW0V>|&!A@4mbS}r;rr1NlYm$GuXGa;5t2NxHUS*-a*}CJ5)2Y4paZ0L< zu{0e^@<>hEmbgIn=swnLSp?G)Ozss(%=25|^r zB5WQwy`8QJg+32!Ql%R(P42xtWh@V_ZScp$Q%Gy#PwLi~U1ISPjj` z;GTL1D6N~xul`8TWBHjzr|t$_V>Qcai9cJuHC(L*9Zb6)5j9lOE%DcNRp)h_b)rLz zlm%43BJdxkqwya|SMs087G0T9ty}Ef)JCUqJuS&H!~DH!*YGY+{E=vN-fS4woCV8y zHb1zFMyBWU^sWVH%K5wsODlFLXorFSjEY0*sk=$x_KCSyV^Lsk*0WTXF4;C4r}Ba= zF^#z;NH%`65n`{;=ULtR=W7B1IZx~{-NCkMMZY1H!yPvht~sZ~taB@hSqtMxugc$k znM^wg5xh#7cGDSNfjgUhCXUZiL!{;{;TCf?Gw{@xeT9yLxfF z&=O(azjS}{&i1rMM&o<|W6=)h@q4o6f;NQ+sc$XBrw-c7AqvY{i1zOv5X_;OhQ8j~ zziSvh%-0>U^gYRQw{C8~1HM`n?VjjN9*%S_gz<{b=dS&_qrGgCB~Y$NPS|!YwGuR! z_@3g<<%qD}({HG~SQw%BX)!8)A0!+%EmExULa1|DU<<7;RulKDgUqznaPkKK*TBA` zT`=|#C4>N=CNDpVQzcc^1uNrP1Gjqeyx6O7{_1lPQ)V%L+?H55`uZh4QZUnVsKipm zC~&8#Fo^@_Eo8&))0QI-$HT~nF7MBmBD);->&XZT20pbT(auV~15T}6Csum;I1}f| zD5Lk!5+_L6LklDc`0K+!8HH^^#CVLs1?e{ZO-P|CY$!_vkgveQ(j5QJ`TSk@k|(7e z36tlh)x8jIq)UE=uj!;iLL?t2v1B?6>cutQ?;TH?hop(_(Bl-5Mhhfqs^Y32Jpq1K zAE;YRQR!#_>j@_|BTla!&-wgF>E>%0p*RG035DVs1&R{;DeK8=o?}t6E(Lot7b=!o z>K{_A-iD1jb`0)=7eAnlJD6rvwz_pdkg7Zl-l`|0+tf`_k5G_P^9RXFx&IMX$`2up z%h|qxfiTua>Q8>0$|{)x^Dm>h7X~U>=O=b(4bNFI_Wf1iU}hy2rX=!y?vE=Ij75lN z@xoY-z9a}?0ST5cW;LReF--zgToqHrx$xZx=2GCpD}oID8S7t_Y78P2UXg{^d44)< zXXsC_XY4~Yx*4VzP^##xZut(&&;BGWb`UaYoVB{T&*D-{uT~<=;0cs6*fDymu*UjE z4|^$T-&OKbhxKwaWgJfr7;)|21It2akdQwi$S)(ni>x7ByVQvMq3eah-J_*H74{P1#edUiN4$r_$E21RUE58m+cYWJDrxbdcd9 z9zQ?Vs3+curID!^Ugig6bJgRLIUtF%%W-#YV@nwOEVgM&KN8K@MF@lV zw+16Qy}OQ6O>fI`G%bPZ>KW7gAbY}E9TwrkB;^vPP!1mL7wq# zr-IZoeUWs;MDdF1UT6z=a3fP=yVw0wR3fQGS$jt81MnZu;T7~p-QxiO`cD9L6k-V6 zM;JhP%>VNPM&hYSv;3pHaU!|yfxm>8f&lO)j8kv5o=NPjg#X0yM-|E9#h zB0a2sIQX9^4v|9^sVM_>aggpf+(;62!oL)WWK?Is7(hy?D`4;<1Jya0|36Uvr$c?n z9kNZGlZE5&l>fCmfa^aJz(WYG81lKsW8|zl570yoDJ;fB1%+Va{F8wGo=_kFFs=IU F_FwhtkBa~R