Ok folks, I decided it's time we woke this list up again.
*kick*
Right. I've got so many things on my ToDo list that come under the heading
of "can't be done until the FFI library is finalized", it's getting silly.
For the time being, I've been using Marcin's library, which I've found to be
suitable for what I'm doing, but I know there are several other libraries
out there to consider. So that we don't get overwhelmed by choices and
design decisions, I suggest we take this one step at a time.
STEP 1: Addr or (Ptr a) ?
I'm convinced that Ptr a is the way to go. After brief conversations with
Manuel at ICFP, I think he's agreed, and presumably Marcin is too (since his
library is based on Ptr a). What do the rest of you think?
Definition of "Ptr a":
A pointer to an object or array of objects which can be
marshalled to, and from, a haskell object of type "a".
Usually "a" will be an instance of "class Storable", which
provides the marshalling code.
Using "Ptr a" eliminates the need for those annoying dummy arguments to
malloc and friends, and provides some useful type safety. It might also in
the future allow us to typecheck our FFI calls with respect to the foreign
interface, but there are still issues to resolve before this can happen.
I've enclosed my modified version of GHC's Storable module, and a new module
Ptr containing the definitions of Ptr and FunPtr (ripped from Marcin's
library mostly). Comments are most welcome.
Cheers,
Simon
begin 600 Ptr.lhs
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2T*+2T@)$ED)`HM+2`*
M+2T@*&,I(%9A<FEO=7,*+2T@"BTM($UO9'5L92!0='(*"EQB96=I;GMC;V1E
M?0IM;V1U;&4@4'1R("@*("`@("TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM"B`@
M("`M+2!$871A('!O:6YT97)S+@H@("`@"B`@("!0='(H+BXI+"`@("`@("TM
M(&1A=&$@4'1R(&$*("`@(&YU;&Q0='(L("`@("`@+2T@.CH@4'1R(&$*("`@
M(&-A<W10='(L("`@("`@+2T@.CH@4'1R(&$@+3X@4'1R(&(*("`@('!T<E!L
M=7-">71E<RP@+2T@.CH@4'1R(&$@+3X@26YT("T^(%!T<B!B"B`@("!A;&EG
M;E!T<BP@("`@("TM(#HZ(%!T<B!A("T^($EN="`M/B!0='(@80H@("`@"B`@
M("`M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+0H@("`@+2T@1G5N8W1I;VX@<&]I
M;G1E<G,N"B`@("`*("`@($9U;E!T<B@N+BDL("`@("`@+2T@9&%T82!&=6Y0
M='(@80H@("`@;G5L;$9U;E!T<BP@("`@("`M+2`Z.B!&=6Y0='(@80H@("`@
M8V%S=$9U;E!T<BP@("`@("`M+2`Z.B!&=6Y0='(@82`M/B!&=6Y0='(@8@H@
M("`@8V%S=$9U;E!T<E1O4'1R+"`M+2`Z.B!&=6Y0='(@82`M/B!0='(@8@H@
M("`@8V%S=%!T<E1O1G5N4'1R+"`M+2`Z.B!0='(@82`M/B!&=6Y0='(@8@H@
M("`@"B`@("!F<F5E2&%S:V5L;$9U;E!T<BP@+2T@.CH@1G5N4'1R(&$@+3X@
M24\@*"D*("`@("TM($9R964@=&AE(&9U;F-T:6]N('!O:6YT97(@8W)E871E
M9"!B>2!F;W)E:6=N(&5X<&]R="!D>6YA;6EC+@H*("D@=VAE<F4*"FEM<&]R
M="!!9&1R"@HM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2T*+2T@1&%T82!P
M;VEN=&5R<RX*"FYE=W1Y<&4@4'1R(&$@/2!0='(@061D<B!D97)I=FEN9R`H
M17$L($]R9"D*"FYU;&Q0='(@.CH@4'1R(&$*;G5L;%!T<B`](%!T<B!N=6QL
M061D<@H*8V%S=%!T<B`Z.B!0='(@82`M/B!0='(@8@IC87-T4'1R("A0='(@
M861D<BD@/2!0='(@861D<@H*<'1R4&QU<T)Y=&5S(#HZ(%!T<B!A("T^($EN
M="`M/B!0='(@8@IP=')0;'5S0GET97,@*%!T<B!A9&1R*2!D(#T@4'1R("AA
M9&1R(&!P;'5S061D<F`@9G)O;4EN=&5G<F%L(&0I"@IA;&EG;E!T<B`Z.B!0
M='(@82`M/B!);G0@+3X@4'1R(&$*86QI9VY0='(@*%!T<B!A9&1R*2!A(#T@
M4'1R("AA9&1R(&!A;&EG;D%D9')@(&$I"@HM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2T*+2T@1G5N8W1I;VX@<&]I;G1E<G,@9F]R('1H92!D969A=6QT
M(&-A;&QI;F<@8V]N=F5N=&EO;BX*"FYE=W1Y<&4@1G5N4'1R(&$@/2!&=6Y0
M='(@061D<B!D97)I=FEN9R`H17$L($]R9"D*"FYU;&Q&=6Y0='(@.CH@1G5N
M4'1R(&$*;G5L;$9U;E!T<B`]($9U;E!T<B!N=6QL061D<@H*8V%S=$9U;E!T
M<B`Z.B!&=6Y0='(@82`M/B!&=6Y0='(@8@IC87-T1G5N4'1R("A&=6Y0='(@
M82D@/2!&=6Y0='(@80H*8V%S=$9U;E!T<E1O4'1R(#HZ($9U;E!T<B!A("T^
M(%!T<B!B"F-A<W1&=6Y0=')4;U!T<B`H1G5N4'1R(&$I(#T@4'1R(&$*"F-A
M<W10=')4;T9U;E!T<B`Z.B!0='(@82`M/B!&=6Y0='(@8@IC87-T4'1R5&]&
M=6Y0='(@*%!T<B!A*2`]($9U;E!T<B!A"@IF;W)E:6=N(&EM<&]R="`B9G)E
M94AA<VME;&Q&=6YC=&EO;E!T<B(@=6YS869E"B`@("!F<F5E2&%S:V5L;$9U
E;E!T<B`Z.B!&=6Y0='(@82`M/B!)3R`H*0I<96YD>V-O9&5]"@==
`
end
begin 600 Storable.lhs
M)2`M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+0HE("1)9#H@4W1O
M<F%B;&4N;&AS+'8@,2XX(#(P,#`O,#@O,#<@,C,Z,S<Z,C0@<7)C>F%K($5X
M<"`D"B4*)2`H8RD@5&AE($9&22!T87-K(&9O<F-E+"`R,#`P"B4*"D$@8VQA
M<W,@86YD(&%S<V]C:6%T960@9G5N8W1I;VYS(&9O<B!P<FEM:71I=F4@;6%R
M<VAA;&EN9PH*7&)E9VEN>V-O9&5]"B-I;F-L=61E(")-86-H1&5P<RYH(@H*
M;6]D=6QE(%-T;W)A8FQE"@DH(%-T;W)A8FQE*`H)("`@("!S:7IE3V8L("`@
M("`@("`@+2T@.CH@82`M/B!);G0*"2`@("`@86QI9VYM96YT+"`@("`@("TM
M(#HZ(&$@+3X@26YT"@D@("`@('!E96M%;&5M3V9F+"`@("`M+2`Z.B!0='(@
M82`M/B!);G0@("`@("`@("`@+3X@24\@80H)("`@("!P;VME16QE;4]F9BP@
M("`@+2T@.CH@4'1R(&$@+3X@26YT("`@("`M/B!A("T^($E/("@I"@D@("`@
M('!E96M">71E3V9F+"`@("`M+2`Z.B!0='(@82`M/B!);G0@("`@("`@("`@
M+3X@24\@80H)("`@("!P;VME0GET94]F9BP@("`@+2T@.CH@4'1R(&$@+3X@
M26YT("`@("`M/B!A("T^($E/("@I"@D@("`@('!E96LL("`@("`@("`@("`M
M+2`Z.B!0='(@82`@("`@("`@("`@("`@("`@+3X@24\@80H)("`@("!P;VME
M*2`@("`@("`@("`@+2T@.CH@4'1R(&$@("`@("`@("`@("`M/B!A("T^($E/
M("@I"@D)"2`@("`@"@DL(&UA;&QO8RP@("`@("`@("`@("`M+2`Z.B!3=&]R
M86)L92!A(#T^("`@("`@("!)3R`H4'1R(&$I"@DL(&UA;&QO8T%R<F%Y+"`@
M("`@("`M+2`Z.B!3=&]R86)L92!A(#T^($EN="`M/B!)3R`H4'1R(&$I"@DL
M(&UA;&QO8T)Y=&5S+`D@("`@("TM(#HZ("`@("`@("`@("`@("`@26YT("T^
M($E/("A0='(@82D*"0D)("`@("`*"2P@86QL;V-A+"`@("`@("`@("`@("TM
M(#HZ(%-T;W)A8FQE(&$@/3X@("`@("`@("A0='(@82`M/B!)3R!B*2`M/B!)
M3R!B"@DL(&%L;&]C84%R<F%Y+"`@("`@("`M+2`Z.B!3=&]R86)L92!A(#T^
M($EN="`M/B`H4'1R(&$@+3X@24\@8BD@+3X@24\@8@H)+"!A;&QO8V%">71E
M<RP)("`@("`M+2`Z.B`@("`@("`@("`@("`@($EN="`M/B`H4'1R(&$@+3X@
M24\@8BD@+3X@24\@8@H)"0D@("`@(`H)+"!R96%L;&]C07)R87DL("`@("`@
M+2T@.CH@4W1O<F%B;&4@82`]/B!0='(@82`M/B!);G0@+3X@24\@*%!T<B!A
M*0H)+"!R96%L;&]C0GET97,L("`@("`@+2T@.CH@("`@("`@("`@("`@("!0
M='(@82`M/B!);G0@+3X@24\@*%!T<B!A*0H)"0D@("`@(`H)+"!F<F5E("`@
M("`@("`@("`@("`@+2T@.CH@4'1R(&$@+3X@24\@*"D*("`@("`@("`I('=H
M97)E"EQE;F1[8V]D97T*"EQB96=I;GMC;V1E?0II;7!O<G0@4'1R"FEM<&]R
M="!#5'EP97,*:6UP;W)T($-4>7!E<TE33PII;7!O<G0@061D<@D)*"!!9&1R
M+`H)"0DL(')E861);G1/9F9!9&1R+"`@("`@("`@('=R:71E26YT3V9F061D
M<@H)"0DL(')E861!9&1R3V9F061D<BP@("`@("`@('=R:71E061D<D]F9D%D
M9'(*"0D)+"!R96%D1FQO871/9F9!9&1R+"`@("`@("!W<FET949L;V%T3V9F
M061D<@H)"0DL(')E861$;W5B;&5/9F9!9&1R+"`@("`@('=R:71E1&]U8FQE
M3V9F061D<@H)"0DL(')E8617;W)D.$]F9D%D9'(L("`@("`@('=R:71E5V]R
M9#A/9F9!9&1R"@D)"2P@<F5A9%=O<F0Q-D]F9D%D9'(L("`@("`@=W)I=&57
M;W)D,39/9F9!9&1R"@D)"2P@<F5A9%=O<F0S,D]F9D%D9'(L("`@("`@=W)I
M=&57;W)D,S)/9F9!9&1R"@D)"2P@<F5A9%=O<F0V-$]F9D%D9'(L("`@("`@
M=W)I=&57;W)D-C1/9F9!9&1R"@D)"2P@<F5A9$EN=#A/9F9!9&1R+"`@("`@
M("`@=W)I=&5);G0X3V9F061D<@H)"0DL(')E861);G0Q-D]F9D%D9'(L("`@
M("`@('=R:71E26YT,39/9F9!9&1R"@D)"2P@<F5A9$EN=#,R3V9F061D<BP@
M("`@("`@=W)I=&5);G0S,D]F9D%D9'(*"0D)+"!R96%D26YT-C1/9F9!9&1R
M+"`@("`@("!W<FET94EN=#8T3V9F061D<@H)"0DL(')E8613=&%B;&50=')/
M9F9!9&1R+"`@('=R:71E4W1A8FQE4'1R3V9F061D<@H)"0DI"FEM<&]R="!)
M;G0)"2@@26YT."P@($EN=#$V+"`@26YT,S(L("!);G0V-"`@*0II;7!O<G0@
M5V]R9`D)*"!7;W)D."P@5V]R9#$V+"!7;W)D,S(L(%=O<F0V-"`I"FEM<&]R
M="!-;VYA9`D)*"!L:69T32`I"FEM<&]R="!#:&%R("`@("`@("`@("`@("@@
M8VAR+"!O<F0@*0II;7!O<G0@4W1A8FQE4'1R"2@@4W1A8FQE4'1R("D*:6UP
M;W)T($E/17AT<PD)*"!F:7A)3R`I"FEM<&]R="!%>&-E<'1I;VX)*"!B<F%C
M:V5T("D*:6UP;W)T(%!R96Q)3T)A<V4*7&5N9'MC;V1E?0H*4')I;6ET:79E
M(&UA<G-H86QI;F<*"DUI;FEM86P@8V]M<&QE=&4@9&5F:6YI=&EO;CH@<VEZ
M94]F+"!A;&EG;FUE;G0L(&%N9"!O;F4@9&5F:6YI=&EO;@II;B!E86-H(&]F
M('1H92!P965K+W!O:V4@9F%M:6QI97,N"@I<8F5G:6Y[8V]D97T*8VQA<W,@
M4W1O<F%B;&4@82!W:&5R90H*("`@+2T@<VEZ94]F+V%L:6=N;65N="`J;F5V
M97(J('5S92!T:&5I<B!F:7)S="!A<F=U;65N=`H@("!S:7IE3V8@("`@("`Z
M.B!A("T^($EN=`H@("!A;&EG;FUE;G0@("`Z.B!A("T^($EN=`H*("`@+2T@
M<F5P;&%C96UE;G0@9F]R(')E860M+W=R:71E/S\_3V9F061D<@H@("!P965K
M16QE;4]F9B`Z.B!0='(@82`M/B!);G0@("`@("`M/B!)3R!A"B`@('!O:V5%
M;&5M3V9F(#HZ(%!T<B!A("T^($EN="`M/B!A("T^($E/("@I"@H@("`M+2!T
M:&4@<V%M92!W:71H("IB>71E*B!O9F9S971S"B`@('!E96M">71E3V9F(#HZ
M(%!T<B!A("T^($EN="`@("`@("T^($E/(&$*("`@<&]K94)Y=&5/9F8@.CH@
M4'1R(&$@+3X@26YT("T^(&$@+3X@24\@*"D*"B`@("TM("XN+B!A;F0@=VET
M:"!N;R!O9F9S971S(&%T(&%L;`H@("!P965K("`@("`@("`Z.B!0='(@82`@
M("`@("T^($E/(&$*("`@<&]K92`@("`@("`@.CH@4'1R(&$@+3X@82`M/B!)
M3R`H*0H*("`@+2T@8VER8W5L87(@9&5F875L="!I;G-T86YC97,*("`@<&5E
M:T5L96U/9F8@861D<B!O9F8@/2!F:7A)3R`H7'9A;"`M/B!P965K0GET94]F
M9B!A9&1R("AF<F]M26YT96=R86P@*&]F9B`J('-I>F5/9B!V86PI*2D*("`@
M<&]K945L96U/9F8@861D<B!O9F8@=F%L(#T@<&]K94)Y=&5/9F8@861D<B`H
M9G)O;4EN=&5G<F%L("AO9F8@*B!S:7IE3V8@=F%L*2D@=F%L"@H@("!P965K
M0GET94]F9B!A9&1R(&]F9B`]('!E96L@*&%D9'(@8'!T<E!L=7-">71E<V`@
M;V9F*0H@("!P;VME0GET94]F9B!A9&1R(&]F9B`]('!O:V4@*&%D9'(@8'!T
M<E!L=7-">71E<V`@;V9F*0H*("`@<&5E:R!A9&1R(#T@<&5E:T5L96U/9F8@
M861D<B`P"B`@('!O:V4@861D<B`]('!O:V5%;&5M3V9F(&%D9'(@,`I<96YD
M>V-O9&5]"@I3>7-T96TM9&5P96YD96YT+"!B=70@<F%T:&5R(&]B=FEO=7,@
M:6YS=&%N8V5S"@I<8F5G:6Y[8V]D97T*:6YS=&%N8V4@4W1O<F%B;&4@0VAA
M<B!W:&5R90H@("!S:7IE3V8@("`@("`@("`@("`](&-O;G-T(%-)6D5/1E]7
M3U)$,S(*("`@86QI9VYM96YT("`@("`@("`@/2!C;VYS="!!3$E'3DU%3E1?
M5T]21#,R"B`@('!E96M%;&5M3V9F("A0='(@82D@:2`@(#T@9&\@>"`\+2!R
M96%D5V]R9#,R3V9F061D<B!A(&D*"0D)("`@("`@("!R971U<FX@*&-H<B`H
M9G)O;4EN=&5G<F%L('@I*0H@("!P;VME16QE;4]F9B`H4'1R(&$I(&D@>"`]
M('=R:71E5V]R9#,R3V9F061D<B!A(&D@*&9R;VU);G1E9W)A;"`H;W)D('@I
M*0H*:6YS=&%N8V4@4W1O<F%B;&4@0F]O;"!W:&5R90H@("`@<VEZ94]F(%\@
M("`@/2!S:7IE3V8@*'5N9&5F:6YE9#HZ0TEN="D*("`@(&%L:6=N;65N="!?
M(#T@86QI9VYM96YT("AU;F1E9FEN960Z.D-);G0I"B`@("!P;VME('!T<B!B
M("`]('!O:V4@*&-A<W10='(@<'1R.CI0='(@0TEN="D@*&EF(&(@=&AE;B`Q
M(&5L<V4@,"D*("`@('!E96L@<'1R("`@(#T@9&\@:2`\+2!P965K("AC87-T
M4'1R('!T<CHZ4'1R($-);G0I.R!R971U<FX@*&D@+ST@,"D*"FEN<W1A;F-E
M(%-T;W)A8FQE("A0='(@82D@=VAE<F4*("`@('-I>F5/9B`@("`@("`@("`H
M4'1R('@I(#T@<VEZ94]F('@*("`@(&%L:6=N;65N="`@("`@("`H4'1R('@I
M(#T@86QI9VYM96YT('@*("`@('!O:V5%;&5M3V9F(&$@:2`H4'1R('@I(#T@
M<&]K945L96U/9F8@*&-A<W10='(@82D@:2!X"B`@("!P965K16QE;4]F9B!A
M(&D@("`@("`@("`](&QI9G1-(%!T<B`H<&5E:T5L96U/9F8@*&-A<W10='(@
M82D@:2D*"FEN<W1A;F-E(%-T;W)A8FQE("A&=6Y0='(@82D@=VAE<F4*("`@
M('-I>F5/9B`@("`@("`@("`H1G5N4'1R('@I(#T@<VEZ94]F('@*("`@(&%L
M:6=N;65N="`@("`@("`H1G5N4'1R('@I(#T@86QI9VYM96YT('@*("`@('!O
M:V5%;&5M3V9F(&$@:2`H1G5N4'1R('@I(#T@<&]K945L96U/9F8@*&-A<W10
M='(@82D@:2!X"B`@("!P965K16QE;4]F9B!A(&D@("`@("`@("`@("`](&QI
M9G1-($9U;E!T<B`H<&5E:T5L96U/9F8@*&-A<W10='(@82D@:2D*"B-D969I
M;F4@4U1/4D%"3$4H5"QS:7IE+&%L:6=N+')E860L=W)I=&4I"0E<"FEN<W1A
M;F-E(%-T;W)A8FQE("A4*2!W:&5R92"5P*("`@('!E96M%;&5M3V9F("A0='(@82D@
M:2`@(#T@<F5A9"!A(&D["0D)7`H@("`@<&]K945L96U/9F8@*%!T<B!A*2!I
M('@@/2!W<FET92!A(&D@>"!]"@I35$]204),12A);G0L4TE:14]&7TE.5"Q!
M3$E'3DU%3E1?24Y4+`H)(')E861);G1/9F9!9&1R+'=R:71E26YT3V9F061D
M<BD*"E-43U)!0DQ%*$%D9'(L4TE:14]&7U9/241?4"Q!3$E'3DU%3E1?5D])
M1%]0+`H)(')E861!9&1R3V9F061D<BQW<FET94%D9')/9F9!9&1R*0H*4U1/
M4D%"3$4H*%-T86)L95!T<B!A*2Q325I%3T9?5D])1%]0+$%,24=.345.5%]6
M3TE$7U`L"@D@<F5A9%-T86)L95!T<D]F9D%D9'(L=W)I=&53=&%B;&50=')/
M9F9!9&1R*0H*4U1/4D%"3$4H1FQO870L4TE:14]&7T9,3T%4+$%,24=.345.
M5%]&3$]!5"P*"2!R96%D1FQO871/9F9!9&1R+'=R:71E1FQO871/9F9!9&1R
M*0H*4U1/4D%"3$4H1&]U8FQE+%-)6D5/1E]$3U5"3$4L04Q)1TY-14Y47T1/
M54),12P*"2!R96%D1&]U8FQE3V9F061D<BQW<FET941O=6)L94]F9D%D9'(I
M"@I35$]204),12A7;W)D."Q325I%3T9?5T]21#@L04Q)1TY-14Y47U=/4D0X
M+`H)(')E8617;W)D.$]F9D%D9'(L=W)I=&57;W)D.$]F9D%D9'(I"@I35$]2
M04),12A7;W)D,38L4TE:14]&7U=/4D0Q-BQ!3$E'3DU%3E1?5T]21#$V+`H)
M(')E8617;W)D,39/9F9!9&1R+'=R:71E5V]R9#$V3V9F061D<BD*"E-43U)!
M0DQ%*%=O<F0S,BQ325I%3T9?5T]21#,R+$%,24=.345.5%]73U)$,S(L"@D@
M<F5A9%=O<F0S,D]F9D%D9'(L=W)I=&57;W)D,S)/9F9!9&1R*0H*4U1/4D%"
M3$4H5V]R9#8T+%-)6D5/1E]73U)$-C0L04Q)1TY-14Y47U=/4D0V-"P*"2!R
M96%D5V]R9#8T3V9F061D<BQW<FET95=O<F0V-$]F9D%D9'(I"@I35$]204),
M12A);G0X+%-)6D5/1E])3E0X+$%,24=.345.5%])3E0X+`H)(')E861);G0X
M3V9F061D<BQW<FET94EN=#A/9F9!9&1R*0H*4U1/4D%"3$4H26YT,38L4TE:
M14]&7TE.5#$V+$%,24=.345.5%])3E0Q-BP*"2!R96%D26YT,39/9F9!9&1R
M+'=R:71E26YT,39/9F9!9&1R*0H*4U1/4D%"3$4H26YT,S(L4TE:14]&7TE.
M5#,R+$%,24=.345.5%])3E0S,BP*"2!R96%D26YT,S)/9F9!9&1R+'=R:71E
M26YT,S)/9F9!9&1R*0H*4U1/4D%"3$4H26YT-C0L4TE:14]&7TE.5#8T+$%,
M24=.345.5%])3E0V-"P*"2!R96%D26YT-C1/9F9!9&1R+'=R:71E26YT-C1/
M9F9!9&1R*0H*(V1E9FEN92!.4U1/4D%"3$4H5"D@7`II;G-T86YC92!3=&]R
M86)L92!4('=H97)E('L@7`H@("!S:7IE3V8@("`@*%0@>"D@("`@("`@/2!S
M:7IE3V8@>"`[(%P*("`@86QI9VYM96YT("A4('@I("`@("`@(#T@86QI9VYM
M96YT('@@.R!<"B`@('!E96M%;&5M3V9F(&$@:2`@("`@("`](&QI9G1-(%0@
M*'!E96M%;&5M3V9F("AC87-T4'1R(&$I(&DI(#L@7`H@("!P;VME16QE;4]F
M9B!A(&D@*%0@>"D@/2!P;VME16QE;4]F9B`H8V%S=%!T<B!A*2!I('@@?0H*
M3E-43U)!0DQ%*$-#:&%R*0I.4U1/4D%"3$4H0U-#:&%R*0I.4U1/4D%"3$4H
M0U5#:&%R*0I.4U1/4D%"3$4H0U-H;W)T*0I.4U1/4D%"3$4H0U53:&]R="D*
M3E-43U)!0DQ%*$-);G0I"DY35$]204),12A#54EN="D*3E-43U)!0DQ%*$-,
M;VYG*0I.4U1/4D%"3$4H0U5,;VYG*0I.4U1/4D%"3$4H0TQ,;VYG*0I.4U1/
M4D%"3$4H0U5,3&]N9RD*3E-43U)!0DQ%*$-0=')D:69F*0I.4U1/4D%"3$4H
M0U-I>F4I"DY35$]204),12A#5V-H87(I"DY35$]204),12A#4VEG071O;6EC
M*0I.4U1/4D%"3$4H0T-L;V-K*0I.4U1/4D%"3$4H0U1I;64I"@HM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+0HM+2!!;&QO8V%T:6]N("\@9G)E
M96EN9PH*;6%L;&]C(#HZ(%-T;W)A8FQE(&$@/3X@24\@*%!T<B!A*0IM86QL
M;V,@.CH@24\@*%!T<B!A*2`](&UA;&QO8T)Y=&5S("AS:7IE3V8@*'5N9&5F
M:6YE9#HZ82DI"@IM86QL;V-">71E<R`Z.B!);G0@+3X@24\@*%!T<B!A*0IM
M86QL;V-">71E<R!S:7IE(#T@9F%I;%=H96Y.54Q,(")M86QL;V,B("A?;6%L
M;&]C("AF<F]M26YT96=R86P@<VEZ92DI"@IM86QL;V-!<G)A>2`Z.B!3=&]R
M86)L92!A(#T^($EN="`M/B!)3R`H4'1R(&$I"FUA;&QO8T%R<F%Y('-I>F4@
M.CH@24\@*%!T<B!A*2`](&UA;&QO8T)Y=&5S("AS:7IE("H@<VEZ94]F("AU
M;F1E9FEN960Z.F$I*0H*9F]R96EG;B!I;7!O<G0@(F9R964B('5N<V%F92!F
M<F5E(#HZ(%!T<B!A("T^($E/("@I"@HM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+0HM+2!292UA;&QO8V%T:6]N"@IR96%L;&]C0GET97,@.CH@
M4'1R(&$@+3X@26YT("T^($E/("A0='(@82D*<F5A;&QO8T)Y=&5S('!T<B!S
M:7IE(#T@"B`@(&9A:6Q7:&5N3E5,3"`B<F5A;&QO8R(@*%]R96%L;&]C('!T
M<B`H9G)O;4EN=&5G<F%L('-I>F4I*0H*<F5A;&QO8T%R<F%Y(#HZ(%-T;W)A
M8FQE(&$@/3X@4'1R(&$@+3X@26YT("T^($E/("A0='(@82D*<F5A;&QO8T%R
M<F%Y("AP='(Z.E!T<B!A*2!S:7IE(#T*("`@(')E86QL;V-">71E<R!P='(@
M*'-I>F4@*B!S:7IE3V8@*'5N9&5F:6YE9#HZ82DI"@HM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+0HM+2!496UP;W)A<GD@86QL;V-A=&EO;@H*
M86QL;V-A(#HZ(%-T;W)A8FQE(&$@/3X@*%!T<B!A("T^($E/(&(I("T^($E/
M(&(*86QL;V-A("AA8W0@.CH@4'1R(&$@+3X@24\@8BD@/2!A;&QO8V%">71E
M<R`H<VEZ94]F("AU;F1E9FEN960Z.F$I*2!A8W0*"F%L;&]C84)Y=&5S(#HZ
M($EN="`M/B`H4'1R(&$@+3X@24\@8BD@+3X@24\@8@IA;&QO8V%">71E<R!S
M:7IE(&%C="`](&)R86-K970@*&UA;&QO8T)Y=&5S('-I>F4I(&9R964@86-T
M"@IA;&QO8V%!<G)A>2`Z.B!3=&]R86)L92!A(#T^($EN="`M/B`H4'1R(&$@
M+3X@24\@8BD@+3X@24\@8@IA;&QO8V%!<G)A>2!S:7IE("AA8W0@(#HZ(%!T
M<B!A("T^($E/(&(I(`H@("`](&%L;&]C84)Y=&5S("AS:7IE("H@<VEZ94]F
M("AU;F1E9FEN960Z.F$I*2!A8W0*"BTM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM"BTM(%5T:6QI=&EE<PH*9F%I;%=H96Y.54Q,(#HZ(%-T<FEN
M9R`M/B!)3R`H4'1R(&$I("T^($E/("A0='(@82D*9F%I;%=H96Y.54Q,(&YA
M;64@86-T(#T@9&\*("`@861D<B`\+2!A8W0*("`@:68@861D<B`]/2!N=6QL
M4'1R"B`@("`@('1H96X@:6]%>&-E<'1I;VX@*$E/17)R;W(@3F]T:&EN9R!2
M97-O=7)C945X:&%U<W1E9"!N86UE(")O=70@;V8@;65M;W)Y(BD*("`@("`@
M96QS92!R971U<FX@861D<@H*9F]R96EG;B!I;7!O<G0@(FUA;&QO8R(@('5N
M<V%F92!?;6%L;&]C("`Z.B`@("`@("`@("!#4VEZ92`M/B!)3R`H4'1R(&$I
M"F9O<F5I9VX@:6UP;W)T(")R96%L;&]C(B!U;G-A9F4@7W)E86QL;V,@.CH@
H4'1R(&$@+3X@0U-I>F4@+3X@24\@*%!T<B!A*0I<96YD>V-O9&5]"@==
`
end