M 
Posted in reply to Aleksey Bobnev
| Think the Lisp wins this on ;)
In article <cqp7v0$1grl$1@digitaldaemon.com>, Aleksey Bobnev says...
>
>Yesterday I tried to get back to idea of using D templates for meta-programming. Last time I tried it there were some serious bugs which made meta-programming if not impossible at all, still very hard to achieve.
>
>This time it turned out to be a fairly easy task. Though C++ specialization is still much more powerful than D's one. Therefore template meta-programming code in C++ is declarative by nature, while in D it seems to be mostly imperative. But due to unique template syntax introduced in D and some other advantages, D code surely looks cleaner, much more compact, and doesn't require any preprocessor macros.
>
>At this time I have only typelists and related meta functions similar to those from famous Loki library, but it already seems to me - D language has a Bright(sorry for a pun) future in area of meta-programming. Possibly with some more improvements to template facility it will beat C++ completely some day.
>
>I ported a simple lisp program, which finds a solution to hanoi tower
>problem, both to C++ and D.
>Here's an original code(slightly modified code from xlisp examples):
>(defun hanoi(n)
> (eval (cons 'progn (transfer "A" "B" "C" n ))))
>
>(defun print-move ( from to )
> (princ "Move Disk From ")
> (princ from)
> (princ " to ")
> (princ to)
> (princ "\n")
> nil)
>
>(defun transfer ( from to via n )
> (cond ((equal n 1) (list (cons 'print-move (list from to))))
> (t (append
> (append (transfer from via to (- n 1)) (list (cons 'print-move
>(list from to))))
> (transfer via to from (- n 1))))))
>
>Here's C++ meta-program "port"(via Loki):
>#include <iostream>
>#include <typeinfo>
>#include "TypeList.h"
>
>using namespace std;
>
>struct A
>{
> static const char * name()
> {
> return "A";
> }
>};
>
>struct B
>{
> static const char * name()
> {
> return "B";
> }
>};
>
>struct C
>{
> static const char * name()
> {
> return "C";
> }
>};
>
>template <typename From,typename To>
>struct print_move
>{
> static void exec()
> {
> cout<<"Move Disk From "<<From::name()<<" to "<<To::name()<<endl;
> }
>};
>
>template <typename From,typename To,typename Via, int n>
>struct transfer
>{
> typedef typename Loki::TL::Append<typename
>transfer<From,Via,To,n-1>::type,Loki::Typelist<print_move<From,To>,Loki::Nul lType> >::Result type0;
> typedef typename Loki::TL::Append<type0,typename
>transfer<Via,To,From,n-1>::type>::Result type;
>};
>
>template <typename From,typename To,typename Via>
>struct transfer<typename From,typename To,typename Via, 1>
>{
> typedef Loki::Typelist<print_move<From,To>,Loki::NullType> type;
>};
>
>template <typename FnList>
>struct eval
>{
>};
>
>template <typename Fn,typename Fns>
>struct eval <Loki::Typelist<Fn,Fns> >
>{
> static void exec()
> {
> Fn::exec();
> eval<Fns>::exec();
> }
>};
>
>template <>
>struct eval <Loki::NullType>
>{
> static void exec()
> {
> }
>};
>
>int main()
>{
> eval<typename transfer<A,B,C,3>::type>::exec();
>}
>
>And here's D port (via my crazy little library):
>import Thor.typelist;
>import Thor.meta;
>import std.stdio;
>
>class A{}
>class B{}
>class C{}
>
>template PrintMove(From,To)
>{
> struct PrintMove
> {
> static void eval()
> {
> writef("Move Disk From %s to
>%s\n",typeid(From).toString(),typeid(To).toString());
> }
> }
>}
>
>template Transfer(From,To,Via,int n : 1)
>{
> alias TL!(PrintMove!(From,To)) Transfer;
>}
>
>template Transfer(From,To,Via,int n)
>{
> alias
>Append!(Append!(.Transfer!(From,Via,To,n-1),TL!(PrintMove!(From,To))),
> .Transfer!(Via,To,From,n-1)) Transfer;
>}
>
>template Eval(TL_ : TypeList)
>{
> void Eval()
> {
> TL_.H.eval();
> .Eval!(TL_.T)();
> }
>}
>
>template Eval(T : NullT)
>{
> void Eval()
> {
> }
>}
>
>void main()
>{
> Eval!(Transfer!(A,B,C,3))();
>}
>
>Now to implementation details. Here is how my TypeList looks and
>works(complete code may be found in attachment along with hanoi sample in
>C++,
>lisp and prolog):
>
>// end of list marker type
>class NullT
>{
>}
>
>// common base type for all typelists
>class TypeList
>{
> alias NullT H;
> alias NullT T;
> template Length()
> {
> const int Length = 0;
> }
>}
>
>// 1-type typelist constructor
>template TL(T0)
>{
> class TL : TypeList
> {
> public:
> alias T0 H;
> alias NullT T;
> template Length()
> {
> const int Length = 1;
> }
> }
>}
>
>// 2-type length typelist
>template TL(T0,T1)
>{
> class TL : TypeList
> {
> public:
> alias T0 H;
> alias .TL!(T1) T;
> template Length()
> {
> const int Length = 2;
> }
> }
>}
>
>// generated constructors for any arbitary number of types
>// ...
>//
>
>// Cons is similar to cons in lisp
>/*
> Construct type list from head and tail
> typical use :
> Cons!(A,Cons!(B,Cons!(C,NullT)))
>*/
>template Cons(_Head, _Tail : TypeList)
>{
> class Cons : TypeList
> {
> alias _Head H;
> alias _Tail T;
> template Length()
> {
> const int Length = 1 + .Length!(T);
> }
> }
>}
>
>template Cons(_Head : NullT, _Tail : TypeList)
>{
> class Cons : TypeList
> {
> alias _Tail.H H;
> alias _Tail.T T;
> template Length()
> {
> const int Length = .Length!(_Tail);
> }
> }
>}
>
>template Cons(_Head, _Tail : NullT)
>{
> class Cons : TypeList
> {
> alias _Head H;
> alias _Tail T;
> template Length()
> {
> const int Length = 1;
> }
> }
>}
>
>/*
> General meta-functions
>*/
>
>template Equal(T0,T1)
>{
> const bool Equal = false;
>}
>
>template Equal(T0,T1 : T0)
>{
> const bool Equal = true;
>}
>
>template SelectType(bool c, T0,T1)
>{
> alias T0 SelectType;
>}
>
>template SelectType(bool c : false, T0,T1)
>{
> alias T1 SelectType;
>}
>
>template SelectAlias(bool c, alias T0,alias T1)
>{
> alias T0 SelectAlias;
>}
>
>template SelectAlias(bool c : false, alias T0, alias T1)
>{
> alias T1 SelectAlias;
>}
>
>/*
> typelist manipulation
>*/
>template Length(_TL : TypeList)
>{
> const int Length = 1 + .Length!(_TL.T);
>}
>
>template Length(_TL : NullT)
>{
> const int Length = 0;
>}
>
>
>template RemoveAll(_TL : TypeList, T)
>{
> alias SelectType!(Equal!(_TL.H,T),.RemoveAll!(_TL.T,T),
> .Cons!(_TL.H,.RemoveAll!(_TL.T,T))
> ) RemoveAll;
>}
>
>template RemoveAll(_TL : NullT, T)
>{
> alias NullT RemoveAll;
>}
>
>template RemoveAll(_TL, T : NullT)
>{
> alias _TL RemoveAll;
>}
>
>template Remove(_TL : TypeList, T)
>{
> alias SelectType!(Equal!(_TL.H,T),_TL.T,
> .Cons!(_TL.H,.Remove!(_TL.T,T))
> ) Remove;
>}
>
>template Remove(_TL : NullT, T)
>{
> alias NullT Remove;
>}
>
>template Remove(_TL, T : NullT)
>{
> alias _TL Remove;
>}
>
>template IndexOf(_TL : NullT, T, int i = 0)
>{
> const int IndexOf = -1;
>}
>
>template IndexOf(_TL : TypeList, T, int i = 0)
>{
> const int IndexOf = .Equal!(_TL.H,T) ? i : .IndexOf!(_TL.T,T,i + 1);
>}
>
>template TypeAt(_TL : NullT, int i)
>{
> static assert(0);
>}
>
>template TypeAt(_TL : TypeList, int i : 0)
>{
> alias _TL.H TypeAt;
>}
>
>template TypeAt(_TL : TypeList, int i)
>{
> alias .TypeAt!(_TL.T,i - 1) TypeAt;
>}
>
>template TypeAtNonStrict(_TL : NullT, int i, _Default = NullT)
>{
> alias _Default TypeAtNonStrict;
>}
>
>template TypeAtNonStrict(_TL : TypeList, int i : 0, _Default = NullT)
>{
> alias _TL.H TypeAtNonStrict;
>}
>
>template TypeAtNonStrict(_TL : TypeList, int i, _Default = NullT)
>{
> alias .TypeAtNonStrict!(_TL.T,i - 1,_Default) TypeAtNonStrict;
>}
>
>template Append(_TL0 : TypeList, _TL1: TypeList)
>{
> alias Cons!(_TL0.H,.Append!(_TL0.T,_TL1)) Append;
>}
>
>template Append(T: NullT, _T : TypeList)
>{
> alias _T Append;
>}
>
>template Append(T: NullT, _T : NullT)
>{
> alias NullT Append;
>}
>
>template NoDups(_TL : TypeList)
>{
> alias Cons!(_TL.H,Remove!(.NoDups!(_TL.T),_TL.H)) NoDups;
>}
>
>template NoDups(_T : NullT)
>{
> alias NullT NoDups;
>}
>
>template TypeidPrint(_TL : TypeList)
>{
> void TypeidPrint()
> {
> typeid(_TL.H).print();
> .TypeidPrint!(_TL.T)();
> }
>}
>
>template TypeidPrint(_T)
>{
> void TypeidPrint()
> {
> typeid(_T).print();
> }
>}
>
>template TypeidPrint(_TL : NullT)
>{
> void TypeidPrint()
> {
> }
>}
>
>/*
> and finally a little sanity test
>*/
>alias TL!(int,float,char,double) tl0;
>alias TL!(double,char,float,uint) tl1;
>alias Append!(tl0,tl1) tl2;
>alias NoDups!(tl2) tl3;
>
>template TypeidPrint(_TL : TypeList)
>{
> void TypeidPrint()
> {
> typeid(_TL.H).print();
> .TypeidPrint!(_TL.T)();
> }
>}
>
>template TypeidPrint(_T)
>{
> void TypeidPrint()
> {
> typeid(_T).print();
> }
>}
>
>template TypeidPrint(_TL : NullT)
>{
> void TypeidPrint()
> {
> }
>}
>
>void main()
>{
> static assert(IndexOf!(tl0,char) == 2);
> static assert(IndexOf!(tl0,TypeAt!(tl0,IndexOf!(tl0,char))) == 2);
> static
>assert(IndexOf!(tl0,TypeAtNonStrict!(tl0,IndexOf!(tl0,uint),char)) == 2);
> printf("tl0.l == %d\ntl1.l == %d\ntl2.l == %d\ntl3.l = %d\n",
> tl0.Length!(),tl1.Length!(),tl2.Length!(),tl3.Length!());
> printf("types in tl0\n");
> TypeidPrint!(tl0)();
> printf("types in tl1\n");
> TypeidPrint!(tl1)();
> printf("types in tl2\n");
> TypeidPrint!(tl2)();
> printf("types in tl3\n");
> TypeidPrint!(tl3)();
>}
>
>
>begin 666 Thor.zip
>M4$L#! H``````)V.FS$````````````````$````8W!P+U!+`P04````" ":
>M9IDQG@N&IJ8!``"^!0``$ ```&-P<"]H86YO:5]C="YC<'"E4TU/@S 8OI/P
>M'][@10T:C;?2D&PSGJ8'LW@U#72N$5I"RZ(Q^^^^!=)ND#FW<5GW]/GBI;T0
>M,BN:G ,52IN:LS(-`P\B).3'#F2^*R[D4@UXN5"WJVTL6B!Q+K2Y745A$ :-
>M1B>0K.2Z8AD'E"06QX@F,S )@Y\P``#<8$9DD"FI#60K5L-U*[N\ZO8MK7]J
>M;II:0C2)D@[<A,%FVW5ZCNMTG^OL'-?9R-7PLBJ8Z6=KY?!4JS)V_Q8J==E5
>M+:1Y+]6:#TNLE<B!?_%L'(X%&T-I](PR>!3ZLPV B%+[2TA7&0E@E$47RF-<
>MYL4)C?WZ3; 8L#1(_Q:F9E(O>>W>P;)SO@2GFJM/0<AB3LBD0BAW24Y+VTCK
>MCFGRYCXEQ'+B7HG+0FA#_< Z`0ZSI[PT16%I*:#TE>NF,&W^77),I[MXW*PO
>MU>;Y9KLIR:G#'$_QWU_A/AT-_/AI'6XO[;7W-?F:%9C[IR+>6NM=*=!!1V1;
>M$J1'W "T):3;2CQH[:GU<GM[#_JPTV HAZL,G.V%*)F0N&^EKLWX,$WB:3R+
>M']PA\E4WOU!+`P04````" #(NM0J$QCZJF "```Y!@``#@```&-P<"].=6QL
>M5'EP92YHM51-;]LP#+T'R']@L\N&9F[788=EIZ ;AFY9D$.+8:="EFB;B"P)
>M^FAK%/WOH[340;L>&\& ;>KQZ>F1TLDKC^GDY 0N.X25W1*LJ/;"#R5X;MW@
>MJ>TBO)7OX.ST] /4`RR-\DBPU'@G\F>0:4=!`:15"$)*VSMA" -$)JZMW2XR
>MYDG2?,=4P>P79WD#Y\?'\!4#M68!W]&@)PD;;ULO^IY,"YRYFX?"EL=&Q,BY
>M`9;.:4(UJUZ07<%2*0K6O/^-0>-0E?0-^IY"(&L@6D@!YR Y=0Z]5=3PFU.B
>MISI%+$L'U!IBWF6P3;P5'J&QGJ>&O1R7O+,!@4$=>F2[6+V)J."68F=3A 9Y
>M'>?M#2E43"=B\4C4]@9!CM)'1F,C29YW#H4',B"TSKALKC [AMK&KGSM&<9$
>MQA31>XWCOO\G#\DYZV-V6UF9>C111$968Y>(Q/OPP,_>4QUPX/8Q;2\,]&*+
>M3 P>G<?P2!#R#E/9ZUY)2!1%39KB`+9YV=M'2RNXB$!A;]U,!/Z?C6RCPWB7
>M%PY9(O6E*8 )<QE*X5]Y3"=%P$J$",DI$7$!/Y)!;KQY:;X,>$.-4=C ^FJU
>MNORS^79]L3Z_YC#'R."S,..-Z#$X(?\=RNGD_A"Z6;74@HU:)ZTO!X<E=!50
>M`5LKP&D6T%FMT)=BS(R%R+#2V;-'<)-T@1M H[CX?LMP,@6I*<0`A] ^G0#
>M,_EP__!E.GF83@ZQ8+X..V%:!&W;<ID]K?("\KE!E6_(-<DMGY7DR\722@EG
>MU>=/U<<*?B9EP[P`CHZ.#J&3FPJ-H@98X+.V^@M02P,$% ````@`X+OG,#%:
>M4F@N#@``4X(```X```!C<' O5'EP94QI<W0N:-U=;7/;-A+^W,ST/Z"^#[6G
>MM&O)\9N2YL:-TS9WKB\3R].YF9OI0"0D84(1.I!TXNODO]\N(!*B24007Q39
>MF@BAR,7NLXO=);"4H1];?GW[[,<?R7#*R)7XP,D5'TDJ[]7)UV)^+_EDFI!=
>M?X_T#P][9'1/+J) ,DXN0O:)XF'LI]74SY$:R<C/8A2Q\7@AB<?$%P$CU/?%
>M;$XCSF*2@/R1$!\&2%/@[2T$'I"=WZ&7C,CK'WX@ERSFDVA ?F41D]PG[Z28
>M2#J;\6A"H.?B.E'<\/6.)@GTC<G%?!YR%NP<5&AW0"Z"@,<BVO^#Q2&[/U#=
>MWS$YXW',14020=*8><2'KAZ9B8"/X7_HDD@^2A.F1,<L#$F"6L9BG'RDDI&Q
>MD'#IWL"9IW(N8D: :,HD`SL!^BAA`?G(DZE($S)F(&<NQ1T/6 #L:*)L1$?B
>MCA$_@VXX1B+A/ER?SQF5A$>$AB'2H7%IM. P$LE4'QD.NB/2:- &H]&[Q#Q.
>MYW,A$[1V(/QTQJ*$)D!YD#L334$/2>"?L6D8LWOPLF@RHQ&9T0\,&!/)YC#.
>M&8,8-4R5K@9)G/*$CGC(DWLBQM6VS4QZ0-XF8%9CNAT:P^<=PRVS,/N$@F.$
>MR&?**0@PQ&%0`]_RZ]MG"L 5C1.2S@.:L 'Y1QHQ<#Q/.1\2_(V/HX"-R?#?
>M[]Y<O;T9_OGV^O6?<!K.\8@53VOZR ]3"*6=ZS0,A_=S=C#=63Z-IWZ'")NK
>M\UUH!3K-J"]%;-#U/'/<]\C!P8'Y?'RHNKRA/C@B_8#.2:)T-F(21Y;*B?*E
>MF+#_IC3$>.-)C 0JR.-T/.:?<A<SU.@'":A*(CIC\9*XZVLRP0Q!$Y2D:$(>
>MH_N#O_$(_-?X!08,$H#OT#@&;Z"Q$>&!U^O($1*2T('6XA,%QV&#)75W_2F5
>M2)SLE20O2T4RC#FD[,C;2E[3VQWV]LA@@'E^,!@N;/%RV//RDYD;O2HP,-HA
>M[;!O8;(D"&FJ>1PM>,#[R,;'R--T-E[/EWC!^_D>^<^WSP@A%K8&@NEB8WW\
>M@#6\CYW8(ZIB-YN(DPH1\#YQ$H,(RUUMHDXMHN!]ZB0.T5JZ6T2>?4$DO,^<
>MQ")R.PN;Z/,5HN%][B0>M5C!Q@*A=^B `=Z]0R<@J),#+RN:GBL:;'IND%!'
>M5XY68/VU@&'3=T77<T.'S/3+2+"A/5H?+39'KI#[=2 ;,5;<.D\VXHV-8WY%
>M.[4ARZ+,<4O*8'/LJM'S%C12`JUJG;2I%C8GKKH=MZ6;DFI5\+1U!;$Y==7R
>MI%4ME6BKJF?=J(K-F:N^I^WKJ^1;E3[O4&ELSETU/^M(\P4(R]3XL&OUD?FA
>MJPW.N[2!0F(U1&\CAL#&=:+2/^S<&@J.U23]S9D$F[ZK77J;L8O"9#7.T8:-
>M@\V1JX7Z&[20`F8U4UMSN+708//<U59MS/IJH+,9K-5YXEJ0L#EVM5IK,TL;
>MQ$)G&UJK%=N?EM:%B,V)JU7;G=,V@FPU;4<3XKHXL3EUM6\'L^E&N*U&[G(J
>M7A<L-F>NENYJ'M\(O-7<G2\"ZB+&YMS5YIVN(!II8*VJ;V;Y41<VHCITM7[W
>M:Y=&:EB'8%,+GP;8L7%=-1UM8M747!?+8&QJR=54`6SZKB.RB?5:2PI9AF53
>MB[U6M,#FR'5L-K%2;%,KRP!M:IG9GBK8.#_YW<0:M775+$.UJ05N(WU,YPK5
>ML#EV';KM6"@W4M4ZE%NVRJZK'S8GKN.Y14OT1OI:!W4;U_=UE<3FU'5DMZTX
>MT$AIZ_!N;66AKJ;8G+F.\5:6)1II;AWH[:YIU%47FW/7T=[>@D@C]:W?*WP$
>MU92Z.J,ZAZ[CON6EF$8VL [^HZCC-% <&]<BT/.M+P(U-X3%#1Y%!:FI]MCT
>M77UAZ\M/+5G#XA"/HG;5B@FP.7+UBJTO?+5I$HMK/(JJ67MVP.:YJW]L?<FM
>M=;M8G.2)U.MLQBAV+ML%&^<_H7D"Q;Y&=K(ZT5.J%-8U#C8GKI[T5,J,K7O2
>MDRM/UO4D;$Y=W>E)U38;6<SJ6$^S,%K73-B<N7K7TZNJ-C*;U<6><$FVKJVP
>M.7?ULR=:SVUD.^M?@C_U8G!=@Z$=#ET][BE7DIL94+N=VKAB3GV]"\^WS_[J
>M8D\(V++"#VD<DX3-YB%-&,E&*]]38Y3R,, -*D:A\#^HW586)#%^P(U60A9-
>MDJGJ<1LSPG&S%BG2R13^9X6M-_3&((KR4D553."=L$ QC0?YUAN_,1J0W3&7
>M<4)8R'#'#8]0$HEH/Q.ONN"&0KZ([N Z%]%>WG](>4AV8P;7`L/ IQ$9,< L
>M`)C,%=GKPK3*`8Q=7VH[#[V%P6]?:8(XD:F?&+.KDW_EWH,0U?XORB(O2N=O
>ME::+\Y]?9&*-\PRO])D-N<^5<8778C9/$[V3T\)%E,,@=N-B;Z,[X5,</+([
>MO,)AY?$2S9YV"<WVI2)X-1C<T3!EZH)D22HC[.&#.!ZR_83/&+I$G-"HL*U+
>M$89BY8%#(4T:)4"1.P]2,MS]"/<[BF@B)-G]..7^M.AMB#3;'J5#%ZIR(VV(
>MS'FT=5Y4D3^@>9GA77A?[FSFQ:)T1OXBRL3D)W)(/AO&A6-]Y.3D^"KB(.:N
>MX $9<<;3(S]D/&XS3W@`L;-MC2I2Y87VXE]X%"A'UTF))H22"0<_(7"!?8)V
>M3;_'G8"ROB7OYE'")I*&)//8S-^S<-'(=+AXF@W8ZCV+TS!9"AN#& '.1<P5
>MGN]5A^_Q''#(\([)O4C51DB C8@TV1?C_9%(07$MP5/<I!)2`9I)*607`[,B
>M2CR21KCS&PO0;AIJ'A7:4$Y.C?DW\VO,N277SJR>>[;JH6D]<FCS<)/+D9[H
>M02KYLRNJA]JNB9*O1HG_X^TE8Z2E<K)/>KF/+;3XBE%Y+:*;1'*_>7C&'<0G
>MW6LY1#TB9'XO(GQLH&40BA&KSHXJ47CDLBF0RP*"@N N?*!&`O#*OHT^C9-2
>M"GHK*_Z4&]021,;)5@5-@6\Y-FKE'Z^$V@6J-3UY!2Y.N:H]38H#U*YF?#W-
>MC&RX7'R5!9K45Q"R%7GP+?KYO\;%_*>]WTS#:TY,AN:<SFB9M"R3#*LFZ0C
>M9 Z<@]OS%TI0D_,QIHV<K@O3K4P?BP_9I"'3U6TJ7'+;W%29NF MY]GO?J_)
>M=!S]U8['S,CSV!EVNDPHYX%5-K.$N 7F7/([$#>H!(Y@`'?&6,L?5JXHYNDH
>MY/[@B_KO:GYJA/Z.S0!7*DK*WE=:GES,(9$%ZHH^S$(68FTYH!.1%436BW_&
>ML4\E3T@*1JS)"573B@*2*572M-BQ"$/QD06XZ!ZBV#Q![&<+<Q9T8<JU$X+6
>M<X7//Z VX:_4<KLW(663.<30#F*X4GIA-]>]MF[^1JP56E70$P>X%=W:0IT?
>MV^ [9"HWV(:H:L*:2=.83(2]*G7[LN9=A%$Y([V1-&9X01_I"8&N\0K?3R6+
>M?!ANKHK*7@>3%"6U9CK*-@FOPJSF,EV8<-U,I#5T306V%UCC9LY\3D/^/VWC
>M7LZG(&@Y1ILF+]?IRPJD?0O2TN3&"3)2-J_(Y 8OPSVJAKNI[*&$.22/K[F.
>M41@OPG Y;] P?!B#<>>)`S TS!T(;VNS!JCWPG$=4^S59A9PR@%V**YA;M+'
>MKP*=227UC_2>!.)CI#ZH091L)NZR1T>HP(J*00:C%%%5RK8RV2@KCITWJ'N-
>M? -PMSSE7(O+=!YR'XYUI?0]&F.1=X+LDE(+GWW4>J19$%+**U^CT)&E@P(R
>MQT5-49NV%C0U5Q%E0&Y+B'+5P![K1?[(SP3[5>^%2Z)X>=7SE")+/?OELH-+
>MW$''5U\S8-XS^-]GZI(^KI[<VV[-GKI#%KZ7X1))'L&'Q_EOO<08608!!%5.
>ML^I^C7#4$W[K]!XE2\TXT&AON["MX[W;/&'/(C#3NO$#>LW'S.VU`;L+Y<*M
>MW0%7Z1;O"C#O>)LE@+9F]NN@1B8U@)N^*VZQF4"4H 5LZ4U6`\UF]ME'?8\U
>ML_I'D#&*@!]5L@#CMY4O@%7+*2,[;BUU`,1VLH<)-L.X(M[:KS8ZZ;CQ7 ,R
>M'T.ZN6-25Q^SX[C&Q-WTULEBS4* 5'V_RF,+$_L:0\W'E[GZ#QX';,WC`X.O
>MUF.#4FD=J*S^KT45I_\/YO35BF[*ZW^!-F&1NC36Q['"3Z:<22K]Z3U>4[]W
>MNO.'",>_X>/V';([EF)&WM]<7G?RQ=9OX-\W7_32##G8JDC[D, L-I%N,:;0
>MP7*+0:+/AFG1MW+'4KP>R#'NY $!T>*@,;(,A;E%F.XF+WX)2P:EEV/IN:$R
>MPM4?2;PR($LVR;"!Q0<#[>6:1).]?(B]Q)ODNBSW\\K]*NE*H8$@-QD4OXLX
>MN62PS&=!U;<#>53.W_KR3,")0/<D&"'9UPC7F7^:$Y;)Y^IOWR&E1O:]!=B6
>M%):7+%WW=F-8K/NTNJU;C$=<P+7QU912@"[Q+]>47],HX %P<:P9&;8W+&1^
>M4G%GN[E]]^;]S>W/KZ\N;FYV<P'ZEK9GF0YJ?3/B[?CRV\)H0_&+%)$.I LI
>M:311=:G*TBV)A0JI<D!I8OU3UU@;6FNV6$2B@]P>X9()"6)!J"+LY+F\ZSRQ
>MB'Q%Z!@WK^[>6DVXC2EB$5H7U>%2X!8GA>5 &DY9*5F6V%N*/*NXE:K,:Q>9
>M'_*[<EK:?M:/F8I_BU8ZB7_=V%E:>#W%F">AF*AHU+^O?GBN?U]]`'?^3V24
>M3M0WVJD$2 F3^O&7&)=^Q+Q_1!*Q]/%4<52O71]"ED/&2!G27-([4);>AT+N
>MY6)!9"86?RA??Z_MFOL?8+0@_K'?Q/=)_^#\^.#H@/PS#43L*8+OOONN"_/
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
>MRK"2\E#78@7W:0A9RD GY.*)&-KZ_4OQ?FUK<I:EPNE"!1[CW=\@=/Z@(O"K
>M-ZB"J*I]<5SQKGQ<%!CFTNJ^1B^S:4,^K:!V"9?DY;/R7+FP5:GE71F3G*,X
>M-W6B'6).]ERR0EY/=B&W5/__OMX.RLBX1]R*"MQLTA"K_S4OJ^2)NZI(F63P
>MYAH4'1T!S:3H3UC$$L0/((M!"ABX$-.$3IED25H5;A-O>]H=,C[HX0!S\@<U
>M\E=5V62P=6$XPZ"VXW6TV>1X%_)PC$&%)VLJM,G)CD3B)(,Z3]?7:9/3W4G%
>M80;5GKU)K4W.=BH8YQG4?/Y6S38YW[5L'&E0^<4&RFUR\0[B<:I!_9\VTV^3
>M3^]C`0XVZ(+G;FP#'FTQ=BDKFH>;M,,S8@>N[:>Q%@(FTYHW,&8+KIWDN382
>M)@.?=VS4'ER[RH2M1$RF1N_$N$VX=I@LV\F8#)_>Z5;LPK7;A-J!D,D4ZYUM
>MS39<.\^Z74B9#,3>^5;MP_4>N;D3,9/IVKO8NHVXWBF%=R-G,JQ[FZ?U+HQQ
>MO5^J[TC09/H?U*3__P!02P$"% `*``````"=CILQ````````````````! ``
>M`````````! `````````8W!P+U!+`0(4`!0````(`)IFF3&>"X:FI@$``+X%
>M```0````````````( ```"(```!C<' O:&%N;VE?8W0N8W!P4$L!`A0`% ``
>M``@`R+K4*A,8^JI@`@``.08```X````````````@````]@$``&-P<"].=6QL
>M5'EP92YH4$L!`A0`% ````@`X+OG,#%:4F@N#@``4X(```X````````````@
>M````@@0``&-P<"]4>7!E3&ES="YH4$L!`A0`% ````@`R+K4*IFQI(4\!@``
>M;A@```\````````````@````W!(``&-P<"]4>7!E36%N:7 N:%!+`0(4`!0`
>M```(`/>$FS$ACR9840$``$(#```'````````````( ```$49``!H86YO:2YD
>M4$L!`A0`% ````@`+;^8,3,.J<'-````XP$```D````````````@````NQH`
>M`&AA;F]I+FQS<%!+`0(4`!0````(`$:^F#%?U[5G`0$``/H!```(````````
>M````( ```*\;``!H86YO:2YP;%!+`0(4``H``````(N.FS$`````````````
>M```%````````````$ ```-8<``!4:&]R+U!+`0(4`!0````(`#R5F3%W%P8W
>M6@$``"8#```+````````````( ```/D<``!4:&]R+VUE=&$N9%!+`0(4`!0`
>M```(`"J/FS$H6*JGAP(``!@'```-````````````( ```'P>``!4:&]R+W1R
>M86ET<RYD4$L!`A0`% ````@`Y**9,0XG:P*K! ``Z",```\````````````@
>L````+B$``%1H;W(O='EP96QI<W0N9%!+!08`````# `,`*L"```&)@``````
>`
>end
>
|