PCollection[pyarrow.[RecordBatch](https://arrow.apache.org/docs/python/data.html#record-batches)].
+
+Each logical data format will have its own encoding convention,
+[discussed](#logical-data-encoding-in-arrow) in the detailed design.
+
+We chose Apache Arrow because:
+
+* It’s Expressive enough.
+ * Lossless encoding of (conformant) tf.Example, tf.SequenceExample
+ * Can encode structured data (proto)
+* It’s a columnar format. It works well with common TFX workloads:
+ * Column (feature)-wise analysis
+ * Feed a batch of columns (features) to TensorFlow.
+* It’s OSS friendly.
+ * Community support for more storage format I/O (e.g. Apache Parquet)
+ * Friendly to other OSS data formats, both in-memory and on disk (e.g.
+ Pandas)
+ * Friendly to numpy / TF: many Arrow array types share the same memory
+ layout with numpy ndarrays and certain type of TF (composite) Tensors.
+* TF neutral.
+ * Leaves the possibility of supporting other ML libraries open.
+
+## Translation from Arrow to TF feedables
+
+The analogy to this is parsing tf.Examples into TF feedables -- extra
+information is needed in this translation because a
+[`Feature`](https://github.com/tensorflow/tensorflow/blob/abfba15cd9734cec7ecd3d0661b146fc251c842d/tensorflow/core/example/feature.proto#L76)
+can be converted to a Tensor, a SparseTensor or a
+[RaggedTensor](https://www.tensorflow.org/guide/ragged_tensor) depending on the
+[feature specs](https://github.com/tensorflow/tensorflow/blob/635e23a774936b5fe6fa3ef3cb6e54b55d93f324/tensorflow/python/ops/parsing_ops.py#L46-L49).
+Currently this extra information is implicitly contained in the pipeline schema
+(an instance of the
+[TFMD Schema](https://github.com/tensorflow/metadata/blob/master/tensorflow_metadata/proto/v0/schema.proto))
+proto.
+
+Similarly, an Arrow column can be translated to various TF feedables.
+[An extension to the pipeline schema](#tensorrepresentation) is proposed to for
+a user to express the intention for conversion.
+
+The conversion can be efficient (zero-copy) in certain cases. It is
+[discussed](#efficient-arrow-tensor-conversion) in the detailed design.
+
+## Standardized Inputs APIs
+
+We propose a set of APIs that TFX components will call, and need to be
+implemented for each of the supported combination of {physical, logical} format.
+
+```py
+class TFXIO(object):
+ """Abstract basic class of all Standardized TFX inputs API implementations."""
+ def __init__(
+ self, pipeline_env,
+ schema: Optional[tfmd.Schema]=None
+ ):
+ pass
+
+ @abc.abstractmethod
+ def BeamSource(self,
+ projections: Optional[List[ColumnName]]=None
+ ) -> beam.PTransform:
+ """Returns a beam PTransform that produces PCollection[pa.RecordBatch].
+
+ May NOT raise an error if the TFMD schema was not provided at construction time.
+
+ Args:
+ specified number of rows. Otherwise, beam will try to adjust the batch
+ size automatically.
+ projections: if not None, only the specified subset of columns will be
+ read.
+ """
+
+ @abc.abstractmethod
+ def TensorAdapter(self) -> TensorAdapter:
+ """Returns a TensorAdapter that converts pa.RecordBatch to TF inputs.
+
+ May raise an error if the TFMD schema was not provided at construction time.
+ """
+
+ @abc.abstractmethod
+ def ArrowSchema(self) -> pyarrow.Schema:
+ """Returns the schema of the Arrow RecordBatch generated by BeamSource().
+
+ May raise an error if the TFMD schema was not provided at construction time.
+ """
+
+ @abc.abstractmethod
+ def TFDataset(self, ...) -> tf.data.Dataset:
+ """Returns a Dataset of TF inputs.
+
+ May raise an error if the TFMD schema was not provided at construction time.
+ """
+```
+
+Where `TensorAdapter` is:
+
+```py
+class TensorAdapter(object):
+
+ def __init__(
+ self,
+ tensor_representations: Dict[str, TensorRepresentation]):
+ """Initializer.
+
+ Args:
+ tensor_representations: keys are the names of the output tensors; values
+ describe how an output tensor should be derived from a RecordBatch. See
+ this section for details.
+ """
+ pass
+
+ def TypeSpecs(self) -> Dict[str, tf.TypeSpec]:
+ """Returns tf.TypeSpec for each tensor to be produced by ToBatchTensors().
+
+ TypeSpecs can be used to construct placeholders or tf.function signatures.
+ """
+
+ def ToBatchTensors(
+ self, record_batch: pyarrow.RecordBatch,
+ projections: Optional[List[TensorName]]=None
+ ) -> Dict[str, TFFeedable]: # TFFeedable: np.ndarrays or tf.EagerTensor
+ # (or compositions of them, i.e.
+ # CompositeTensors).
+ """Converts a record batch to batched tensors.
+
+ Each will conform to the corresponding TypeSpec.
+
+ Args:
+ projections: if not None, only specified subset of tensors will be
+ converted.
+ """
+```
+
+Note that we will provide a default implementation of `TensorAdapter`, but TFXIO
+implementations can implement their own `TensorAdapter`. A custom
+`TensorAdapter` would allow a `TFXIO` implmentation to rely on a TF graph to
+do parsing -- the same graph can be used in both `BeamSource` and
+`TensorAdapter`.
+
+# Detailed Design
+
+## Logical data encoding in Arrow
+
+On a high level, a batch of logical entities (“examples”) is encoded into a
+[`pyarrow.RecordBatch`](https://arrow.apache.org/docs/python/generated/pyarrow.RecordBatch.html#pyarrow.RecordBatch).
+Features or fields (from structured records) are encoded as columns in the
+RecordBatch.
+
+Note that
+[`pyarrow.Table`](https://arrow.apache.org/docs/python/data.html#tables) offers
+an abstraction similar to RecordBatch with the key difference being that a
+column in a Table might contain multiple chunks of contiguous memory regions
+while a column in a RecordBatch contains only one chunk. RecrodBatch is chosen
+because we want to enforce that TFXIO implementations produce batched data in
+the most efficient way (one chunk per batch). Users of TFXIO may construct a
+Table from one or more RecordBatches since easy conversion from one to the other
+is supported by Apache Arrow.
+
+This design aims to support the logical structure of tf.Example,
+tf.SequenceExample or structured data like Protocol Buffers. Thus only a subset
+of Arrow array types are needed. All TFX components will guarantee to understand
+those types, but no more. Below is a summary of supported encodings:
+
+| Logical representation | Arrow encoding |
+| :--------------------- | :------------- |
+| Feature with no value | `NullArray` |
+| Univalent feature (one value per example) | `FixedSizeListArray` (list_size = 1) |
+| Multivalent feature (multiple values per example) | `[FixedSize]ListArray` |
+| Sequence feature (list of lists of values per example) | `[FixedSize]ListArray<[FixedSize]ListArray>` |
+| Proto-like structured data | `ListArrayRN3iRS z8|m2GBYX0QDuDAab_1`ZOf~&z1NJR~XuG6Cedp~tOmoS4gm3JE}l`1ZzUC>~N z`205E0o_3RsjLPbNZ8dQn;?I%7T)P*)!AN(53RLv_Ea0zN_5N+E9y@oNIjo_xh6RQ z(D-yZqw%>?L)ub=K{?vP%IEs{JJCFFCM#k!oHJ}8$=B1V?aL Acid zUxIsDURm}A%nl&z{ALU2NNy8mocuIuOQrk<3Ys8392JjiGKrD{#Tr44GvMu&SqxpN z1Yr{J$lUc9VtmLvBY$zc;8e0K+V7UJYLVrfo$Ny#7E)Fkz?Of1Sj9BiOZ7)9jnt3N zy9XQ9LZ#A|;;bV7r09BuR0Lbk#qeC9z4+mXcGVV^EiN?8vLuUW&-!sM=tH;S{I}A7 zoQ+yGif4u6_@^$UGjUu5Nr!C 19ky_- zA(Xvm`sAiRD~ps2($U_7&`qa& I#)2h{z^X{vMW2GlO3yc6Z{Os9PfybDZOC?x0!e+e^} 2Tf0Qdx_CK>WrPJ;Znq<^5r4l?GSZ}}jUg$$`H7gu#T0vj2_bY9p4 zBkWmhk1?n8%({@LGg7%~X<$$f&K$yKe?~XG&8F dU^u$$xCK+8kUMLOA(9fPViWA{9i` ze}_odqRgro-}+nwwStj+!>6F}3Nfw_Ca+$8L!@7E^M8wR1;z-P;&(t97%Q#+ifcg? zi#+`v=z>4|0~!}u)1M$3zFbx1s P4 z`HtWaOw_-gdU-%#kZbr?`Wr }sAnj?(T??%cEM?a)_x>b^cf z+-!4=EGgKOq^akyWOP~K8=vy_@Omc2S`Rzs2mU6~^;cl-h$MxvQ=k>0p#k{ &tH3zO)aOutM%av3G)|eMTKz*+zXfGB=VdROMtt~@AAA 3xcXkSS5$LBYoQGZM*Uwkv>L3}H1y4c1zHoTU#QNz`fL7WRdH=c{z~v%GFtzY zN)t*Zy3 kv1(EJL zDm@6MhqSP1Au$vtNHD|@<-9jvY@8~}`ghGf5e%}YZ|fX1i&3%JdLoJx3wN{YG@i)w zBGEEnv+nMV7u%gk#~;yuLmEW)l|{oa2jWg@#Jcy{2voLecoU9_K)ENn!Q+Tn5=*;H z$~lDeNf+v*VlaAl3PHisC?Sx3Dy#fZQ6yWlu!qPtJh8)(kL~&Fol=hNf`<*9Pjo15 zQi+;rN){^D)w?;@him{P9QTSn_GIXYcZ%`U165KXNS*8$ys!R}-`8r2>8-mHH8RfP z> UUi#0sgPT6=c1a|E4i c2w0ir(yE7Ne!@XXM}3laOwFx;Y@p#>DCJ;P z0Fp5aQW0^a(S0_iXpAwRLy`s!ZOxGfjshBuI63*5iz(Ur*?-mc-;cU-@R7)ylOncL z0%V2Zy^dlW$wX;1a;Xq|v}`ZV`;xnzi&{!=6CbLLuECh_>!{srlp$=A%M!{hXau$N zm_D}`<kcmAK@Ra^S^@hjr?pLpTFw)1)WGhIEHy!`<|C^(`axf@F{K{i?rXv1` zFNhgQZ#{N7T`v_di-R6e(uX+XC6QgQLq6NHT867)T%JeqhghEnYg=Yq>xe#v2zp?B zHXn}pd`e~c0{OxISocY}c>^nzgO6;_fLd8&X#I|XxnthJLHLS%lbcceN|JO!kO4J2 z+O}s>IjC#+dC!ge<8WpOc3emC=*5G!GoG@#c OR5#I+Fs377txOTa(ZexP{Up1Z #jKHgP z$vHEhT01`)v)hkUDc#DBUcl|6UEzbY?2*INvjgE!o8GwOgaSE`ar*@qn@OS>#euLb z=@dmW#l6tFT*Z`@h4C)qWq?yHWTB-KdXhFI;Ie;s);XJMwi~b7_Q6TSHjd{W{ob+# z^8wzUmUt{mW(j3v9eTm;dd~i=os)z+S|y&&m?5I+=ii^8VLDrnu6(>f^T9Xgc>)gC zpBh<%qb|gI>yt+}{)|h?@1(3cL*Oz9M?_*OxcKcsTQ7@F21L~P0BM-#-ABduzjEl) zB=wJvK&0MRyU7L%QqLnKqPQvLqIiAq_)(m9Iu}m&9bi<0Z$Rvh{bj~kw$T693Dt>q zIq4|OerH*q&7gl?3x%XGz=0L1IJP2XRkeKi#(ld^PhWf(k8rtLHeo)vui62V2Dkim z^RaXbk&vxsYD$4BRp}OzgUH(MVX?xfBJ-t!CN$Ju;+)h~D~%p)z)$55Cq%@X*EcOv zx|Khq9V}gzKL8q_z`NcMH}jFLF+cYEP;d>^>ZM&>rw_4hnKX1?P9E^tJ~ZS3<-+rx zcV~(lh@9ahgeRoay#{7b{aA710{IQ9mBF)L(sp8+v_Yn&%$^%n4Y!F(sYcrr<@R^e z(1JI7Hy~@SNgI#xCbCAvoN@XfMLIMt=RiNjxfdj$J<`KEwQG55=>(?Yxr^4n&+iK| z1aK8RI#-W)?Gcm4q(x(aqNvB`7*RMgHR!nSiq3FZ)qO#*1+C!lNg(aQZ(W<7iXYs4 zAQe>d5qJw?5PCsr4>08@^)i$nN6SQCL3ma_AJMIv_7doDE1jE;j>ReNt3D7!Q~_1A z_f-t{#GQF%sLiuD5_39H5V6-%%sLuSwET2vMywme!itsEk0i^M4~s?_aElz!{l z2TbYZwfp0d?|rmx>qPqAas-v(k!*4}w@^v+9nDw+wHn1lx ASQ~8X z#&=yn?@iqchrBZwZn=z4Sw{zo`sHM$?(0Oj540Rk=Tp&|$s*ux{vfnDK+ %xIFX8Sy3&ra+fssd$sTXuVnq)b94Ly4mB zae14&Y_i5I9^8em0_CqROkXnkYSj;bqSM#O{x*+1QYlbE&FvonN|~!m+>E(oFS|Vh zgG*YvAz{`D^5gEEM=(mtZsYTcU^z)2(mDPd#|)eT;SSUZpk^4P83OiVf21n(#KA-; zoFN3|ILZF9zogmH=iD%V710Ovi4sx?Izan{z5F9cZLwQb%b+|PZ4F|_fo=Ft5o;5g zh8xix@PAJJrE5U?IXGb>6@lO!D8248qB)g_v!1Opn~ayA-&5q9%%04}!SqG|4Vt6% zk6j)?`x)8-ZLhiVGi^XolB!Q!?zBkvifX<1Pu>Ha*ccaL=n XkJVP(Vqyi%)dLtNom21?&$-2L$6-kfrn+WcR#Ujb!ir=tZOT{^J6f8 z$gkr02BG9P_{?Tnk9N4;aEja57G6$P^3U20SXI9F?Y#Y{xg=>{XaC?nV6VAN9T#N% z#<&Cb;l>D%!qB5$!dn9KBhPV&=U->_K5)4aENc09cHBV&%Ee(RA!<$|+dRA8ZUcPK z2E)3YWB7Qr^_|TcDXEaykf<8aBa7!}Xz#{DP5#)ZHoq@A!~QpWkdLwRc{ Vj;- z`iw|_b<2kZLP(8Qqx}(Y_L1P(PO<(?kHAVIsko}RNqc#Tf~t|Idr`&%*7w8LpF`{; zQ3Fm@pEx^SfcL({H6C -~1Fbr8=ONkq_~S2d;rd9!&C6`qh&Y>a+9ztbGp+<3O9 fnO&Y=gXE$0Iafp;406)z56th2Kw9Q8?nJP3Rvo73PQ62W zVTo$zXnK-ek2XxBXTRYCkfqEEIclC!{WCTOe)~9Hv3VX}D@;hh9nsroDSwF$h!q92 zfWKEo6n#z2g{ksx
{rI~POYKdvVhf)BZ#nF( z7f6FK9eUnwaXnLdHdaWB)VGaIVU=h^8(5%K>@tvA-617NE!I4jxLHZCkH?+mr`bz; zbU 1@$rz+OO)=U=PyUI1}2A?Z# zUsiQ)JSf?9F4viK=s!Rx3t56xxR)J-?uDNbnqj`$VuEStL!Yc1Nbqvt-|2UrCFpea ztASge6PNgQ>D^h{keQc${l)gl<1KCcP~1@V{E&jpY8P*heB}RC< *{u)DLo`!A zFEMELIdD3&CnvlF^@+?`Y~|e(tkhK$&~ $N;H?G z^)gSe|6BT|RoNBU-+^Y=oe)G6Pzl~jb8x9=n?D3pPzf33@&ssBj*56yIpGLw(o(&* zpHc@V?gX;sSCjbxfQSb~`s6(@Z}H;N`*p|Kn}4Pq0k>VENB9MXvt^PHa1VUc40~R# zp-j780NX&!h5ho$Lu#s;YJ;R-e*GkXNIvR)oNV#BN+vF{w E3lP(|Y#E6QEFhuhh_N 2ljt5aiKt?XOm=yj04#^0ltt z!5z!ohY}zKBAl*^&8D1P7Y0}$f|#zWM-z6rJu@B=Y-hLRJXDK`TbgM+(c~^P%dhcv zRN(6! 2rO;==gZP zM!z00I`x%Ry%yGkeZCKVUf9Kg-v(iN?1lH?4o}V~9zOrU AT*>c<)eHR%_dycbzm` z@n{x_RW<#t`Vw=fZXYNn7=H!D8^wV?0!&gPG#}7N{=+9D>FBdgk+djPB~i82HD4!{ z5c2YaV2#M;LPGzdb|iK0?j-eHUH=%g#x-3 y7#>pQZ~JyUs_lj)?6sj=X3=CUhFa9kMut*@`tN&f2Ih8_Ff< zBrJkX#{#aaZG$woV2!jhZ>&UTiC8H6gNZd0`1zIHjOm2-o3CU~aFgVjx@VNRfjAPy zjljGi&MH`$&h)>P rRKS!hJ`?fu8T5W&3x`-^EQ+()p`N!y4)K52Vx@ z>Glu&6G(-9_dX?&u3yU0o+z88-<~ w%25f} z5&ki;?&jv2@s7-Ij~CPT0k{x8Etv0grg?CrZaX-lBf-E$uF(q=@oVJ&%5SccoNJ!o zZ~4ADu2t?BxR|gDv>32$AV{eJNmvCT3%NRjYu5fX7XlR~3=e dZTw0I$` zHQCgSTzBou=c!yo)TIfQ4f%>i?c86RX(W?6KSw4*!DDN5$9PDwku~E*DA&;1xR%o$ zMvJasJI=-iGclpWpM;*&@4bXs9jJl7Ma}En0{F~5NNkq&TnS-LTgW*|5;Gm;Br-j3 zg}O`p;EA2Z`1SjCPf>7YUWDlZCbnMd#_gCd#K7G1=mreESjO{YDCz16Wys;3M=!j+ zJGGRoqFkp;tH3lwvlXEm-3gqrdd3HIA2%;Ux6~M7IEctexOJU}~NrCsG}|1=PdZQUiC} z--F3Vx+#|P$TN^6b{9N=5=Pz+7qP@@zw6}khzg!c4O-a4AY9(KSEsqHd5>87MuQF! zL6!{e64niyK;@n|GgvO)R!XW4fD7VfZ2v9a^Kq+gbK8^kkfuDh71{}v9h{r>8@28m zjXju3%nGiMR8UtAJso>4Q5a%CgCRjdllfX_DbjTbq# rJh=%D!pZ+ageNW8)K|tV|ce8Orz)9G0^CC H4s@aQDiWZkyn0 zDlrsp|Fgglz=~Hj_CL-U2S-OaD`>gc^>YcvsOag6MztYeRA8`$M`B)d@=Zg#&sfkJ zm#3>siAZ I_RzS+y``nGg*M23SXZk7b8(c$-5^xm0?-D^ z32tVr)#Cy+E@F8xzS?lOmWLZZ#8r#`@k?uIMDEq&yf;St@esxeIdbk5$E4nvzk&}X z$_%q6w+9t%K}7x*OKNp0FNs@uEp36KKp5wuDuzas_AG-2UZ#x|7#1$C5YpUc0QW&g z&%%<+ x4{hr<=NaM)LBJ@gEbP#yOO-cv7kE31VB*aSL+Q?uc zuoDG!=7FvOWZOMoS2xBhUKr~qL#mGv>}+^T3a2FXlTOl!phJMoCfjzdglJo|$;li5nhu*cqCHgz1YXp4r< zJ>-sYHmc#CtoPyR%(W%#x$&S0EQtk97MK47`lDbpz4}{>Qws#rJg+dM{UoI8-6S>* z{DkHGYJg8mG{aockEaK!Z0X8Ieg?f=1vVe sjpOx5}aquw1p@y6c;x#5N`Z?~x9^|eYr5(->!`gWGU!Dqro!w?H`O73~ z`9Cer`F$bb_~4by%-e=|h1rhH52MuPDTdgE@l!BHW#Z`%85G_1Z835_LBGdD5#dW4 zw}fCfp2vNBrgY?i_7`-YCP-$^B{)dPfO2pAt*U}@C0XhGgX;dY)=sPocH = zbB_%(e&wfTc%V?7@K-@b Y<$nay>KUzk9Zl9ahw z7-mLc{A!qeux*wV#plu3S2zfmQ}Bmitl!9sR;R+8$lsU<8C3jSL_De?XrRh(_>F=y z8^h;?8HaT0_2$Np?e69HBg?^R_BsL26iWk{mLI>mX0SdKRxZf4ruL!89>ZX=#Z>eU z3D3-4x-?kh+xsb07P*B-nCxxTj`Xb6NhBO#JL(VfsbRK^B`SXaY7L&B04{G2$c>1l z` UCH9QWs`x+~x5 kVP2FQz_3`udtLW_V_Mlw3$A_K`hN6Z`Qd5koqWOwYhluiX zXL%rh mrhkHguNNISA|o3$ykC)xvnW(_tPOpYz}Hfp^rYw#PU zPDMq;m n{#;7;4;TzxIoJ5^06QTC`U;f$1{IQ!R11VDG wLdWhxEQV7)YF$A%*U;23 zVL>aQ&G2kU!;00bI^9;j@(Ik0E%HoYlLftJsM+@JM}s|>*d0+9!#;qPBH(n`d64ms zH%d`CSB{0fnk;ngN1i)7e3f478pdq`-#C>6Dxy^>`m*sZ#$7bKVx+-q2bs-6IfFaS zakX*GDf-G?mv6W!^GA`c%juR6Ojm9~OL`-WR!?w1k&8F{-qph$)UovGsiM&lyB*i& zvPxpvrj@dH=Cd2=m=m@970Djv+X2b`!e3{d>v;(>_|73)! Mh~GjF%4FqB^lWxqItgE8U7+=?11YDBkCDkc!uNYl zmuMQ&_n$i}@Zp(2y43xMA+O{obOyox`Ff|n&u!_gMB{y_PKGl_3syo X zuXgePcq-^gOR=CBY4-LSt1p1Lf!cXFg_yeNPXF+tM{Y5->|caPK$O02VK676B0RFw zzr>$#v<3F`8+HdzWbGy!VOK&TMxp%ITrdd-leR>^l^;&@1X7A=6^uBI)vyHS+J4 ovC|5up9gH z9Gqf_m}^{&0Ferus86qqu`nEZvJEK{y#bi zAI3?4PI9NY{A+N>&1ILABfI!C-Hj&X1o}-BXc!5dFAfxAxbb|uGtKW+Cgi?a!iCVl zQ%MIzck*^E#)#D^fTw~_&j;SF{1wPI6<^bCq9x|Q4|VGk7Lq?QWIlKR+m0S=N2$Kv zBJyBm)7QCGTdMoz!_UBbmFq UuTa 3{wv>A9JI6&Q8cM&8c?`ZP^ z+!EjJWOGS;nu0fmAK4F 9!4L5YZnK zr|e6e`$=ibrpz0yDk@(NVX<+s=$O#@T +N}Zj6z3R*`hJ6^lgf5(Z>COAVXS`9M(S$%8 km*nH3Ce z<+|mp`v!HKwm}k&&;L}YQWj43Ci; GGHOvN&!M zDqvw-2stHgzFT0oryBqb^Aq*i#tHH-58p@`8c`hG UwMi2;pVsPkYo}CHpD8w#Jkx#<+E8M-Ap~jkkPE)17|GPALx%~ZrAPu zi&n1A#|Q^B4rsixnc*(C$OYR0Y3ScabRuTDDAV^+(czgW>cJP{ho$@k1k3hv`##m= z+Z0xO{K`@ycx3C4gR;JeebkUV5F1AyG{^=cpI|Klt{Q*=BRfLQ-MZ~h<3t=KNgFlv zrIpE#kMB(`>5hw-tmK+9a`+y}+QmsnRe#rn<2{U}?#;V(ZpxqbO~Zwb)o=bW{XwAv z>*q}D#Dakajt8Dwq=M&Bs}=0}EQD4J))EemUIM>nK{jTci_KLrUK+D)>o!^57rKtZ zmkP*C_V>vN(KtVo+fqM&j@}A>%*JO4ITXk38m(}v3pfX)g|%Z{jsr>bb>N4q0uq6V zi1^v-Pw??yUdxq?$8N@?8DE$0Fq&)IY=Lr*rX ?oX>*tJH|-(zVoc1t z!1So{T^J;LKcC3(K|WD30Lvh}53~2n1Cw%IRT5?y-s il2wZyGR;zO6BRIY%@GHyn5E{ z(?U|!aA6rL8Vq?omEFnDDGy#eR6}eLhzOHT5FpSULx (LY7OC+}FP zrOq_=6W#Z|Is Z?UpX+soKktA3L(s@@^gB1|@+>cnYQm8Gq{+NBXC@N`bwfDbi?hQ2b-9|x6r zr?5W2+T3$|y&rg5bhqXcYe?BX7;CI9=`bb0owDhLxHC@~r3j=0n#ixZtW(W`fG0Lg zL2*7=A=}e7=U>#$JKZ)k;;J6{Wluu8I052TCa$-nzu5|`Mlm9XlDVx26on&xN-Cr( z*(R#PfuPi9L^`)ZmW{4DJ-&B}y(m~l0dgW;@88@hwNEj{$XZoNo{=R^{WNwl<4e*G zh$F1Tji5 vRwT1|=fL-PFU$O}y>m9LvGiWeT6nfgopVpaWBo{{g?pUq7GFaVW-CH4u zpN|(sY-Qg}IiqEF+l%fL2F0cg0=x)zGA1aLUh`GLU#<(7 Pp%LOadY>em3YC#(KrtX@QA07pq2OO-$a=X-_ z%T`?vZHv%Df+#qY*m{}0gU$jiHmuVC8jI!JQz+Hn5f%{k>JPkRT!$b!oY|0Y s5e!Kf*%-i7{IS7U*9^W>MSthj~^&T5ql1Jhtdqf@I=#4+X~gYR>0eF*i2XEFP8 zJH2p!B-i%kpRH{aqo5$tRb1LV(Y*0bUIWraZXS_?hBRtN!{L5?HVqTeQlco~Ghji! zc9D19PK7sC2(ndDnK*x5i;by =co=geo@<|xokuKn8`Szz2z+l;NyH&}a zUJn8+SMU=H+Hg|Hl7Md^BU&TL^;B8dvcLc{bz$MW4}!SO1G9?cAQ;HMmyF&wsu~O% ztl_M5wxXxdv*jz-h8z4SRX)toah8hF%1dCq&`bm?fJ8Xj$ho5sXDhi=%0@YI>^At3 zfaTAoJ#g%N4{8cuZvx*uGd6#sZ^T1#w@(~mzbC87^7q5>? rB*@bL;=C zRAqOLs#a=xbv|rWc6N`Wx87onSw86Am|zF;%)~&sc>2JT*3O1UJ2hcCsu#9hl*>!9 zmkP%Px)e64gGWF)Y5>j~nsElQ=X89Y=`X !dV81r&O;LG zH|_lG$D}L!e)w7Dxm%K*M&8*c62JZ`C3fr&2eW5(iJ3o?{9aVlbE@DE>wsdrH~lq7 zakQhdv9-IywkG?&s7<%_Jw+|}iH_j8y4X|^a3j?0BsT(u%Zpjb&8}t-`XkW<@Sp&K z>Ox+=^i$c;+;jcF^)7a*MeSIr3-WzqY|;p)Z>AdBS>gdFZ{9*Tgj)YJ5)(lm+}lw< zyIZ9g!EKR?$%~$m^yJtvVdJhI>`t5bh7D;tWFyv$V`&MQ|GCt&9D)7Vp dH2NwZb1`)_-`Fcy$w?8j}$}x6AQV7Ju%Qjf|p-#;!A>5A1wJ>|Z~=hCR=l zA#n)$=4W*uTQ>jc)4(Uj)$9_tgjdhU97|8qmrANq>eO -2O zEjy_stF~0I(9@#eSKD#N^RfjLn>ap+JFB8YPJ+ ?-YX2wf``V zbgc`M*1Z7*sZ@DPnv;Hk)ty`;=kwA`X^53{=KDVjm(FpQK1sOE=u6l}&ERMwwY#z{ zU#8hkw0V1;I|C28_zXO?3*FwivrBX*)#AfDkuE)Cd~C10I#F-mfk-PLO(Y+`5CuBG zVsQhh2lC>oJ(}iSr#u#(`i*q5asJ)%MdD_3>OB#0LUO_mrL9mA+qWZ@`bF|}`C&Ha z0h#E)x6JmfW<12H(x+KL+#DHf{4~R}_`ICVhTk*GBj(+FMbdnAWV`YJjRTL~4{De~ zI}kOpdx@&qQ{Z9R7qOY?T2QI`;%0>8gMFfTH6y;Jaf~do+r4hxiLl-4%nIIzXqel+ zWoaHr7>w9~-)df<_Yhd0Ehl1l^q`1np2OREOMJ%vMcH=-G?jJj9-4|`85|2Lpre3v zrAh}o9YuN{gwR1LA%p-T%FKwM(xe8J-b-i+O`HL#L8_EcL_i1xB!m#^-3c-}^S<}H z-~BTVC+F Z(q@24`S&g(zP|YAPpJ!3ZIHEflJJsx~#>dgT7QK*N&C}T|*z)4*V+jl9j7i@c zae>$ u&pTRjxh(8!aAPX%_StbBcs(JsNXd z1GM+a;u?!~SG-|9f-nT|4uXD%iA7jGZXHnp7-n zB>E)2pshlMt3^P~u;I89oY=g`cfqN>mTUHN$>dl6bcx5eh7}@Wr;CRkVxO=FB_6yN zHXP5S$2C8dYPIr6=+Da4*H0dYT;U3lW71A`4ktw79z~O^v!V<9?W8Sr*%1=8tSXKc zOJ$m3{f8D(Ic1Xk*T43Vx#lwvp@pp1HcUC$gX(C93LmoADgujUZQ{YigFivq-Ox2? zd#x}uNb;F7ce;Nd@!;D72k0)!{%wu%k|pHh0fArM(}0edZ4~&mr@)ZK1g1(HN)xd? zOaLOo;Ncxu>l+T^q-NjiTxX{r-8l7CeD`cMRhOD1IhAEUCkbn>ZBJ5KYwB)=DU;O` zE-+T;w_5iEm0j8B0nE JMAMEO+PiKZ85_nD zWaz|GR}Mk0f2|gv*UY{9iiRvi;9?3hH2l^yNz#7ZYbGDJ=`{~iA~uG$qPNh8XB4M` zSn| N!PXMr9CYonFg*rIOsJ}?PSm+O03+?v+`L? zKYiV$AWm|N%Ct61PGSSCZc?HSkv|P%O@?wRWzL=whZHW+b#Sm)nNu$EEZ@~iF1NU^ zPUX{#StrgaQT-RW^fNYFfY|l>5` #0C&BryFjw>FC|BMS4FuB}?? zY=0nP_EqR6bzi`QQNTiei}+RxzLr|8dsi{Bc5PC&@ooqCp*SjQrrsOu_(U=DEzCk4 z%a(GUpAWJ@a+3;LY%c5CXW>4J!j$+) A?ouMN&_b04|d >Dc<#`qzw@JO zD(j1}Id5M|&PP}VqNv=$Mw?x1uw)usGhA`eeK|paT4a%~MT>RBkyfcV6>{82vW)l4 zZe$C#xMVZjl=PDApA8d@QhRocGSh8o(Vf#%jV(2TQ=AA Pm)C%IRXtmlv!s-gCK{_?m!wk0$#h)w$)obE@?G0>@_&=HG&}T#<^E~iYNVL zR5dY`vDu8!P4sW*58PUR7vZny{hn;O5NT2}wLYF)Vy|+`DME?5+DL$rzOG=VaT{-3 zkGqVR-7@{uTHtI0LlG0zN((RMnPoj>tW^HGqN@%iY?K=#t7MWZ+I(>1DRHC=MSFA% z9)bLzzE!pLVE0zn62S*~KLd1|wnVUBzdOl;44|5LCT~o{Nm472eHIyZLr>P{{WoI+ zt`)>c*Eone_ pupPehe?RlkREitWHa&>uyc+Alp_4QOko{)C}FgNoOQ+@ z6=K_zy4QbmbaSh~X{==Fb621Ys+^EKVB0&3o(&ug9wFw|K527Fc>2RPf7&*M9PqFC z+A-qgPJ2J^jmM3?CM8y`Z7#*(@aq|fHQtpQxVf@5HtuoCCEnn *~$zO&wzTmj;KlCCJ zTTt`4IXg|u&0Tqz8C^=O(f20GQ;gb)q_V*<^c*EuE)d?~d30FGdv&P`$$Kwe`z`H| z%Sg~T8<1N3l%l(vuR_~VUj<>CYsWS}iKCV~-bJkPN+wsX=^`oaja3WR2xM{7e$-SO zZ?0+gXP+;&X_`iEEddkW^E1g_GvaXSN9SJs>eUQ3JZhL1pCmiq8SZBBeey<)C4@>M z%oaZxp*=bUc~#cGjMpg8r~e%WrnN=O?f2Xi&3hC;IU<~`03(3Ke+T|y^^@$@py5Hk z-i_(4?BEPK1oR&9_)D5#CBHFCday5ft;E8opE9*J3$Kef%H#7V?@|o$({OP+HKT0* zyGunWMk)p6bKQ~E@xPV=xdS?S+_~`uLj2OqNAj`SFR9d1$a?XBY0y(Yht1$Cn{EXr zo}1G1vM>^etsJey&!cL#4Q)&-i2RUJ^Liw#DC5vly{@S5v-M5>guEF zfp_SGQ&;#ir $$&?sw%w z5}&Gg5F=~Xm1=K{Y;Cgt6!qDCqv(k^Y1nV
I4O%o}3c+;fd$$e) ztMJ!Xp*{x_C1KqUnv63;WZLB2-Ud6-MgoQrS9rDty!)PBDsZ<5+~6k I%hc}GRo+Tsm*u5z6e2<)OKkK2n-4*cr~Dx+x} zu_@;{72e{i3WfYIeJAuBzee^Ekdz*R^c31^Bk`imKv!Dn&2;U3FEK~u<}1dr=*rn* zA&;i X zFt2jyFGMTgVOXzyE^cROYZ+;J%2$R}(1K{~9|!N!o*>TqscS|7?Z;NLaI?3)*-!rb zbCSpVGbbCu)StbuKCL3)ay|lmA9#hGIpyyLNCL9m<%f#{m 1~L=HX&7bsPcFtSx=V&NIg^c*uk^YH47<*B z? _2rTn$bE+MnGpP0J+Q=TaoK=5v((<0|Edv@|V*2=UA-b;*y-e(y1D zN3YuHkua=6qJhQj#iWG!grnE_q8!`B3$$BO{mY6si(3)?QWiLkn|(YUxPGDYWbHk7 zHbKnoHZ-zj|M zPXhVFE6C5w}pgSfkush2PD$Qt-=@b|F z`3L!?cpa#`=hU5JypC!7rY|IVpVRzYt3z41;F+syEdd}5m84ax%0Euyz|Q%xTXFsx zWq6TYLc=5K^m&WM_yVq *kuwhk>}>`)f-f`iNTlXk2FW1y{Xe z#l?vmZffYG%IuxRRc)i0RqnOD3U)*35@mXzau+Av*c3<1;En0vUJio+CM%)5GI^E; zkgDgq6jt2DoWgmE!>G;81av8)ND|y)Fkh`1o3$9vc`mg_bC-+`^nCREI7?c>t@Ngs zQf+SPZ`gyHC8#Ge(pj|=4nxw7Yg~8IaDxsYu=l`Wp^1_hZ#0x1)~7!V80Ilh)_R^s zY_ZzBLZ|3(Nxp;y`>;l4r@K=0QNy{~>Tk;as4;Wd*hNk#tyJ9 ;Q2Pz{Rlf>r5mEm|6V1NtVjc~6MZkOlQ<}n4lFdWrln=vfBBH2) zK)eoG>_OY1dmXM5Y;+qFP+sYW%zPbmK2KHN+bCVFE6PwH?XUNfyHwNcG)$K;Qx+tz zo*JYlA$$IYGRbbUfFsjc~D_7wC*>Y*0hek?w!C#uDt#^ZFI$hnQ znDo-M5A}&hsjui;S_Q{|#!$7M8P&g1W74Zn^I~aPJ+%~f_?Kvf7t**b?-|_F(hU4) zR~z-{k2Cfd%vivZGgsFE4-MbqN{}uuMB>nW$LYw%&Ob7&&PRIija|u*w%4sh8r0r% zz3zE(g;R#_s`{Q6LWI`U{Vs~;P?V|=lL6LAT1DSPwhb>ea8#AOobz>RseXyG0gtA0 z=3)(P9Wf7*V0sC{HCt-uaDVKd8IDGLE`goAsTxCx4kW{ykdyO02L@&~O8wCO!@2Jy zYHrsSJ@`?+%#VU-!BNRN&)}djH}>S9Gd8M1D(-I39p+Gp6^}`M=Hwx^+>K$bp-Qbj z7u0R+Iq56mZR|mu$>&&`J=rharpZM}o1K1Iw$I4)YBUo%0S(MV@uD`@K^}XAWZ5l~ zn${A1_?DBHRj*xKzE&i)-On+<1z2hp1MKvseI`mb8Z?_d9UY?%3C)}I+9h^p;R z=__X`A9^H8ZmxYtXs!-XqM5-&UR9-A>7Dy#EMh>cFhCY}RnL3@vT=#zyxZ1+e*{B6 z0GNUCGZftZsvowD4I_>Qh(ll*uw^f^VGz$fhRXH=U4PU#*!3kh@X!rD6)vq78cc-t zFn}H7`P^~H8*}cqLdrz=508&;hu3@;uOQJ9)3blVJ31ZUM?eRv{Na@Rzu~`c+i4sB zxgG_0H=OU|V@C1c>ZcFJf7HKCc-l6t(O)p$jwAZsKoG;VW2M?gV}POh `H@I-Tj_8SojLO4R#(qt{^+4r;Vlv{9}mk z^!#yHcb2DYB%sGx#k1eemVd=}CB`iK(3@_%j3h(R@lY!&c7FsNb-rsK$M@!PNkqi* z2ChH$NbT;+$GHuGU5))$!xOsS%m)U-CzqxPOX%4>HD1j#jll$rfx!HBeL zIy`H=l)ea%b^~_FqdjrI1y;v@n2a6qZB&o}(P)ax{hs)lO8;cZ2zjTQ9*a4RJcFnf z6PUr)Buy(8|6)SC%YX9^VJtpQ0sij(XPUimqW@-Y3n5)6FBxBZEXk|$S>buK0#Uf- z1-0q^Q{Zg6pBB&55uJgq8IzotfA&oGhrPaVjw2}EwlQ@=BRGL|cbg-KzV1~kubMF+ zjDYmj`)xofYt|dJwBlHUE*^kF4Zb|Pa8B)Ny6&^*Bs0EDhw#eC!n0%qP<`BdMbtEz zlRjV|jY9_Y;jGu$BRXF=wv%vF*Sv0VEkW{o&p3F))#j<2 Sxj zg;b_0Syk9w7LDTqFGpjdxU?b6mmn6I>9Uv@g*dCr5g%Ap9kcXJ@lhH TDb{jH(N2!D; m?*z+}<=K^o_cgvf2H|A1w`gDe`7 zj!BUZ&@Dml`CJ@!DX<4=XvU7!zvTQ4)7Sw*v~qxw=Wfb1p>#O++;Ko82!2x)csWvH z&Ve~4K XF;ZFr4ze zCccxCu_K`%ajrvJi&=1nM7yrC(dA^d@naM7g?Y>=%gEALqaT+V>%pMTnT)OsoS`FE z6v!vg47^^P0iTPOEiyESv7Nv0iQei=63V-)krTh3c!>X@xK-iZrc98X_~r)o3E%tX zxw#u%Y$6Yg6ui_Yj*=(btbp&yQN6p04;7rWSScB!TXN)%Cl8nV`3L})LFS~nTGw8E zEcHj>n|ux^Y%v&U2HryEJRN0ihXKA8qyU`5x$F;hc<$ti-1M&KKK@ie+fV0mZ}t^p z5(URe0F`PON9n!cl8;tMh}N@9y}(C&4f1hXwp|PYs;ovG$O_$AEeyZZ;&+}!S+);B z%8WUb6ZShs8icr4T&KApwkAie|6?RTrd%z|!}x#)mn$Fk0Lb0B_q>|U^zG DSM+&iiRfle(9mVA|D*u>s|_c*Q|m>bX6RwRnf& zlCbJXF)PQ?Zg*&UvY2vGGE*tSM>ti)2w7u?h$qzCH!29xjnkd%J5W;G-o+>KN~^LB zsc@%RV%cmmz#vAj#i$pgj!SOw)7_T?S~j0z{SQr@mE*sgnShm#ZVd}#*r>t>87Amc znuYs89!xsv@oyv61^S`S3H@kl`VW-zZy5CdXV>~({C}$-fT({L{~z^(_~-8?q< f*;t7&86y5ipSg@Z_M- z1I&e;C~#OCgM6F}pahNjUs7gHkpn?6H8+JzExzM!0PS5Gp_@ AX$#UF4{|9l~cVOL|6JmBO#3a<1BMx&O8^r>=;sXn=0@g}YSq* *9DOPynr z;AK4BzB#;We{eu6=wE`0=9eu+y~Ds2tYtD*V$i8KOb`VA^`JlTuY{~GJwbXG*-AlB z;hUBFOoek=#GX7#(Q=k0_vG>Y5H!1|#vF1nJLn}d{A$V)7*-(b8w(T6)`O-Wa|Dpy zx&@PR*I6J)Az1tvG&p>D`-Q~`=DLd~APBq|WHUQPFDJ~KUQV1Bu^GY>>5T{~YLDF) z)Fzo`)aTQCaMqkeDy^q~bG!w#>Ui~E)qaH~7gyAkdU6cHKR{5O@nj2I-TQQklQs !NR^s}&lU}{movE>GgVQ_R za2Rxd6;~}OwSuTBncIc*`8E_EnI?UDLzU%phAp;8j5ce6Hgov66|~=He5mkW#_zb* zQOZnvds*#M9DNW$m30RSvyF6n8f$wPt+)#wUFbI-=JIo h4Mn(nsK>78rq@`8jTM^b-9AFgIFSWIr(A$zOW>=^Y2N81%cH9c+WU zx|vW-VoWg@@R!H$A1f$;%j{A~bDQgt+IjP y^g7k)=5=|Vv8La`WI^0rO?U$?Eka|CXiZFb#Q|Bh%=gJJQ z_yoO;fZz4>P8IiNKUpdbbDdaM9LSN(J@KtBYk#wkIo?UyW*b8TIb4PjjICrV@}&oV z!m2ZQw&&*@wvSqJZn@bJXWB-mURjD3`IYTuIs`Tc=B{Emy3a~1z}g!!J8iovwc9Ts z+o+G~6mL+{vnL2#mYl(t7u38pFhYOf%h2kj#W_pSV)-)p?aw#vZA| cp*ot!ViSaiQ)jN{ z)R*mtD$YaD)VtqdHU&KME>$J5Z u>o;cp(IMm<^94nC fQ0x!9$v1uin z?Uuyc1K*# gpDUv-xkh0`uF3;S|vYk7}(E|*bF0b9?$n5$~}=3WBLyxM#j=* zu29`ICg>7xxI5Xew5-H22aQ8Y56%=ZI(l4a>xy4x4_)?#n|J3lDqMMpzJc_9Y+wtT z%fER|?Q&SpyY8z8A@ @x4(n zS(c8=NglaajV-rSIS7C3LvF?sXZ(sS#fc}pHPLoeWkozCVZy}51h*{b>l^d7-g(oK zqM(oT8Rs9p_Vy-IM{)bA#~G%M#rD-h TBKk~79rGf%5dv%`MWyD3sNLv zs5KQO$|BRppa~k%uQc1T!Hn34!bw|LQmr>C=d(u0Z&x>BySqf@Tuvo?`MOG*{HQf| z@c}7&3hug5E{Lw={y8rvb_(e|;jT~G P;HKCasV2JR~z)3;J)e?*O@ z$_2D1B|Uwpc@)_lK^XRRaohM9|5FSx*AE+=*C 4d6`)E7=o&xoRhbjJHh0=q z17^GL^~5`KOnO3pBq|wC)D(^fVRUn1cOBU=`CpOKn>`$8w`rGw{UT~jwx}3Kpoloy zN!6C})DU0;yLYvErb1uB{WdUtaQ4UTPNHySU7W&D5)fSbm{wjWE>C>i(u0lf-*31U zImp<=XSu{6`SJj 6btVVA88a3>y@*e8??dE>`TBnqM4Wtu_j~ zZ@~ tiP`u8lhKZz2TeiH}Ffl0JFp#8X3lXGSrv!;G()mpp=F Oa JDz53>Z>*9v-_x=%t{k|V=@1aSHJ|+} zhS1O1D}Y2+Sa^L})RB{Uf1iVxo(=@v_@sVS?M^g^E^1%_7K{+l*uGj>GbrtdX6?N_ z?Q G9!l2uA2y*OTTQP%R@ zs@!g&@h^L2j+Mr^yP+r4A#!ztqNj}tGNiVxs-a4Je#u=>s 0x z+pFOG8h;zLYP@;Zg1jLZcbak5Sa%+m+9L&idY)f>(C6{6_M&p2hB=W5oSzNHm<|Pz zZB!gZ<4>Mc?BP1Gd3UJd(PmUdFAF#!!^8&_p#jG!3m!KVLQf-$+YqpE#slSe!yO!9 z ~e7yZidn+Zs=QA9y>JS`?t%x^fS`%-((< z)=1Nd+b$aL4uM&_fl9j|du!#M@JdtC8KX;2$4n1`Qy4G+fsH%<5|f_fdL>SB(c;Wo zM)`ni3CI*u?d_rLD4x7`r# >4-ga;K`X9@>h!5@Z^F|c_Z1Zczx$Q9l^h=Ny=kUD0uQUBDuj$JX)Y1I0 z)%?9QkAQ;Y%n_u;4WkSH_-N7J_f~
fxedz@+ts!6DtL&6~C6@Ka+q8eLdYYp43@whH< zvk@Gp1PT4fdD&F^)}b6fw^)k|pApQYegegA{-M=|4OK3b*NE-rL{ZMj7H ix6}wyRNZlZ@ngMj0bs2lA$Ht}G!*#R&l!dqeHp tUZ}Q z6;y6eapfr5?sqld@;)y~9O<1^uIXvl2=UVCPcakDp|-UfyGQbr&0_3QC)yPyTrDMU z=VZ5vqwl3o7uOV XiRPj(i|j z*;7Hp%!lMGBcd- **xz>&)`3NR-P4}QM;Lr99K}e( gEQB0RVW`#xO>hN!xVcuAGExgH|(A;863T{i^-xXqtdX3&v!(2_B)`(lt-! z>%fjSpOnQgHxn0)$z;1E`vDQ%-ahw$#fThAY$K-&F!YJQ8ho4m+Wj03^yWoDnS0^A z-8Q *~h}-z8dZ?_=vBkR+Lf(?v>H)MHu6!G_{*8Y6`Z;j3~eyCe7jpPev&qG+En zu1C8*ROd~P_T}`}S|tmimgkNj)e_+f^9xq44bw%AzGA*J+Ue@n-7ZI>JoqAFJ<|MR zSTD3eU!o=oMgVChPQO 6?mu&tAoKewuMO0S8iy3Hbz4I{D;|^J6K<7+|jfi z4XkzaG%$P)*l3$P=6rVUnIpbd&R#pYMM9e81?Qg95$6hUgvBh zx7mYaV0!Lp{I{SewIp8GQ@a5u_s{rwTRyxz#H45XThu*2jWlnK+GnRD(*Dv54v`qW zhZU1H%W@%E)WtKYvl~mGYQ-Ge95q!tlYM~W-m&ct7Rl$OemV*t+t`duB^pWQa=Fno z%5yNk2-$v(Dnbqbo3L!=$Y_6>oi5FPW0$9xMP KL} zo`=xR);t2ax}Da;3Z)se3X9hUM3S`3&O$SN*Rlu}v(w oIQ (W?I&awvRJRuK>p*)iT3BatM>bwnoLl`xT6|7ALVlGjjp}HoFn2XG#`nOF#~za zyU&3O0CyJ*H3`F)OvitIuzeCoia{C+w@KNhat5ZfrIW3fqA&V)3h_UJtN;@SVx%zB2a=%i$a)RILUvPRk4%DE%;5(bAMn8h3|+#B(x7 zcL?O&>wGFIdS7CG$TgQ$2B93ClEW&op=<>xM )lm5YX_ovLOdeVJ2NzopqbjiV#!B&941UWAw~KPufGN zJt`_6bKWKL@1PAStu&kw2-?w%3Si*^iGgneBT4*7j &+EtJPqJSr7YD+a^Yel&|^gA-ix_2CEBlajIJuUYUFKwkA+CD$% z;759sB_+Druj v6^=on3?LeZ1ecBvZo`^`SDeALXLph zTl|%3(^>!DzQd~%BS63`D}LO|Ft=H1dosQR2Nu&a@g$9`-#;*aX}`V_selsQ=@`8O zPQS9LB9~@9Smw ^30{q+N8%WCpG>APd CnzP2N~6*e*%dR zNr`5au>Kp8g&@`74hE
_+}|F2Ng z=+x|!fNF)nv7Zz~Sb@KLXQk46J(!ulwr~u$#)I*AN2rdm!UFd4&JF;Rq8$Q#Vc>QE zSLR6=a@77YU8k| gLOV-QRZ(Jw0zq#s`WsUJhwA9~Vg1KWy*+dvcSn^DUVG z+?##DA(!;;mBKpmukt|SKtu_{bVFaPPK#`+yq45s1W(JYlLY!UqlcMon}F##T)MCB z3(BXf7<335Z`42qHwFB-+W3v3rPZEt*NVI~9R=O#nsIoI(BI+~NF{KNV#KV$s<}_s z1_(!ts?GNOs{)RofVG1)gVl(+hr1s5{J3x{_r0WRnmcl##(ytg_se}j4Qol&fP=B4 z(b6ZMrK~Yxc 6~QpZXZB-{3cLSfD*L<$T)EK>V uUr+BJZ^D+@#sc>=CrlVGeiYN)KxU=r`oHf;@x;I^Zk`*-?My zEgsBD7W1p7j@27~OTv_kT+jvxTQJBAR9=Yh^TI36WRk$O59Li#bS_Y~M&YwV{9EbB zTg;E?K@221Wr_qs14?aH6=O&@ Ve zZoTYGyn*ApQy*RB9wUl}p(tkIUUDs-S?fauI16R7X}_3}!Mx;Rv0~+x`-(}xl*H@2 zi7LAWz;?1Oa)Qr*;kla=ws5LtlsVsAknI3bx~MdxzOfP{`}#*@$O66H{< z&pOT#au$^l`HJXicSKK)jF#ubbcXxO#(LCp*08{QA4g}hB;2jEro?U0Jw`S{_FYu5 zj(*%$j1Lpw-$%STD4%JXzg{DXU74u1pRXQyHVT`O^dZ(PE)oT_b9leY)dr9c0{C(b z>hy!3g~(1&L9PZ`I?}lQQ730+$Pvfs7l+P{T?RU8OpHX@qg$85S#Q!dUPtO=*FTq- zZ_!c6+ba++8ey2|`|FWsVd?vfFUPVfx5Zossbxfe1$R0WbFh0gFPR)PX;(BfJ;SHi zL}YMl(wkr!$D>9L8&1$LkA=vnHN=!b%dOyC|Avq&6Vz6PF|EyAX?%K T DWH(>re z-z8&qI$FWe4%_(x 8dP3!XfpgyTB?tEgZDUDQNGgUorL$OID@G$H21H(1 zFZ! SC^F}>1`S)JlnPb?)TVeM|$s-|M(Pl#y= zwmdVGWxo;M ?)n2j?Ul_U$-Mhs@Yhc zUBC0!Ow3I>BhFCNYWRMy$rbExPx&DY&BSHQ^yQd*2S8flN;qGeF`*w*U@=j>NE@^m z2O8(}VvL6{P|yv9UKu)a_Z$FJDMuumYTHrG!9|&cWwjqx<4x#}=|idAr`_QF&DO1e zyPw9U%i|nTtsflPnJ1EG)A@;?kfs68z+3{>YgXBZ4O!FFWcFtRqMn`E{BJcq3#XrB zgGzB0c04BGA+jJ0fV1q}RUwO-__5oU^E!*O l$TM-C(~eVKEuo*k$Je zyc?unWBQ^B&$c|X2DeWy*aH$(gx#uyvMx3&8WCkE1%|~WT?<{9feI~=7?BwDjDwl( z<6F`=-*t-BPY>!Ycyyb60nqZ};9L>s)xg+UIRjercVMJl2W4We)93+6AHP1}Jbq5~ zxGU6M)q|){k_gwq{#xp;V%c!Q>3~d9%%!=v={EqKp2IECPP-#2Muk>Bl;?~of1o=W z*+?G1=x9irb _p7hwtUm?ysG&m%5%HvZo*KR z&k8*o?%yjV4461 k_NYdjRpm)jWZas8 zN%|zVWmS+UNK~2cvFxMspLQ^0{5d$2KAoBT_pC7toPgl+O)p|xIk1)j?b(s)+uRxk zsQB2 P->pu%=3-{$SDuSB^Kd3Se|>q<@B)@ v_E zG<6eIzgu-{11syZ^|{!{o7bQ0Tz(Dma;ny0I>xrSS>wgH5*5@0l(m r>KV}hoWstXY^pg( zN(zD5{O4^Af{|LG&+kGdbBb?vNzGr{W(`A?X$S6eo)S5}uzKz3G-tCG@h~Ks`7rL< zSrJY4)ZPP<+NK4HLpj7ycDd^~^oZPO$w3fG;gVcl`}t4O;#u?vYT`qvcVA*@?uqgY z?)Ux g7l&-U^)OY^gb9jQgmn6v9~yGF zw()W1rx Qf$xDy`OF6n%KEg+ao5jIy!`PG(b OkujGLcwt@n{8c5 2mIA9gkFK%1 zYFLw}jer#$zF7ZI26I}Y!*gL)NfyZ7)pMtsotte<9*bxup9Iirf%JR3503)-w +0))?6jD0W6~wAjh6x34R@-JeP0V29gHq2IxA! zT2?$PKT)YAc^UG8aTor_7^X1kkx5qNeGz;d4kJ3K>oD8Cf*#aNQ+osHS88u9mHg*X z;Oli!gQVV2XuZp{R?Qj5sWKj2cxj_)gy@N%p=wGuUr%La|K1D>G_nnG#gwH~IL}w( zQk0kldD(Z8zw2(;D|>Lf9ZyTs<8kio7xyJS?!A7NRaJ$=!E@;(eM}a2_8gF8hfhOJ zW(F$B&|TB |EV~Lgb@m^IxO@B8^S%Eiur3`8`b27PC<^$a zllcqjRx1wEJ1v{uI&O9x63v-HG+yY^%3;ZFEQ3Q)3W0XR==IVP8Fm*EVq=jcJB<1D ziflo&xV(L&BVbBnLz613w`QnQ_#}%*@^jOjPjkC6*z~ZEUB_HUJ#lNHa|iw*b1Qlu zHXVc7NG?^lzE2I~2YVyRaiM8z-Q@~IvxDC9C(V9J8i*%NhcVq5R%yZ9ts|#Jcg)Oj zL(wFQjrt^x14+G#m7+*2BKkpGg7*{+b^w8D*xx*FRrxvkN_tCDy*#P`(tsB%D+ZFo z(hQ!wX4QSis@i|RtyJM}a|m6{`eb^L-wOJ9VtICi=;G4k8L;tj08m0;6Ya)U?rh4) zZnaycF(SFV2}Yq;=O735jWv@u#*?f!b-TS0O8A?y=@J1SuArE+b!;mqBkpgsy0r%W z32tPS%@2`FGtixW9ep7k;Y UlVa=IPQkOjeKRXR =8g7{UYM)2mo?fmfdW+{+wD(HMy_2QRzGVDQ%HI1{iaEdQGs#&q+ B7^we?E=P_?Z zC0dZ;3{oXl7fX&Fuo#qtgqU<2n40HCC07 rUg43tgv+9 z@qKm|rd29u4HC2xplMM7w4QdtLZ%#^38aTIxK9;l_@Td_UrZoYTguQmWU!9qU$PSd zxMKS-|Ar{&_9E7AFVU|N09Ki>{ec@3c+vG76;tF?Y9?}PJbtc7hZnKN_hfU*%qah4 zOSBz^@{sPS{*E*f)IT*+^DS2U0x@L@>N7tD-eWknxB0wugXU9uMgQ6eEOglSt?hKY z0jx{b%)3 !W`Bde)C{_jcmh{!2)eaI*THk^wDt_; z&Loh)j$m-C%KTqo=VO`84PXevc2 |LKY zrqZ`DYG!EAb$6hOza@4`0$*NDs&|spQP`}QK{Xp+nUJhn#6;#a;}N=m-SJNZXWt0| zy?nvVF9g`Ep?A*eqbuk>rBBb;dMfS4);AKEnjb^wBk=v65!nfSmVgIcO)3{dzALna zqNy*jL=gNwe(eUk+-HIHXWt-tKnuMQbJWecs^QJSR1PT+W@LwYt~B@LAZ9w8a%S z{7XYoBZNiF{HDS%u=CPqWZ*<;Uvf$FF}<`h&9>yqP!tGCDs%m~7Z}{z&Ye^D?Q|(3 z_a_YBVpCw(2ig&ja~W37Z|sc0$J?Ysy$6Dtk*y=Jd7(@}vgXT3s_!@g=Dx_|$kcsG z|2$b``sLZ(K*d)CzFNu8-f@AGg4=b{`55#?)t0(HXxQ_w<{8DsO DuS7Ug9kuubPC5BwXBHmQf(efo>O+ z%mP6p*%?1Yahz%q=(2B33V5ZJK{_Gx#ha#7z Z2o#EeJe z)TdOrJ2rJ!aid6=V(>Azh-v0s|Ln<0i0{1mlVrBFIh;*vqQqmJdh~r9b@FtF *{Ya zHhq!( Xs*5q|btwoH#H3XqykV?aBix|1G)` zal2bUFW(*zFu*Q@h0?9Wo^@sE_p?7Gk0hsa7%z8Y^42XS%Rcxw0-NWQ(N;dP1-4~I zeP^|r {Qiid>%KXol{;UIUBq^mO!c%y1rWmoZb1J8AAdg zC&Q28P_TS_oT=j>DrPIjQpr%Iw(?BJr&VuZaI%X0pZ31|AL{P?|AoRkNp4$NTkfLU zcFUG^q+5zC-O4@**&0i-?^Eh_8(UEb85GJGjNJ%DxKYNE84O0mVC)QLY~M58@9xk2 z{TDuukKe}YoO7LXopYUYo$EZW>w+|^#u{A*5BmNX+HLY53j&bN`SCggZP#(?7$0&` ze0it2n`wDA$$L6H?GUmWJd7hsi9@^pW=CK+bmQTZ0if%~&E0!Fn(XYo8(hybBpHzN zj4?8XnR-cgW~_%TBo`is0B+Ocd|+>RXrl#ZIB|_e@N?eH&=Ngq4p45kT*rcl=zIs+ z)D7x2+1DFe7a8GHVi!=4Bf(`U0eJcjYRi_?)`d+NE6gZp(W*v`DSIo6?WEn7C%>L; zqOPP6>S{B*8Ldn6V;hg9Hh8_qcBC53O={ND6pL>u%RtP(()O#jhcP~w0^=!ayh!D7 zHgh}`?zP$SueC6^!q!t18g;=r9dZxY-QHpQdc8u(1aG-pThRzYyS(rr^@leI<;h7H zlqnBGGhuX<{<-(Lc3c-tEI`u6bi*_f%njczN-F^VuT`rz8s=SgUN2QOzdS=nD35X^ z5E%Dlk9OUM*%H=bL-Eq0U;E40dh94s4&Pstz(X%FV)3iuyyS9L3x@WPD#6I(J!$?h zdv)s_2in0TZMIOyxn{9+pGXB)`TyKMKUy&@S>}k3*nr(hfo4Y0%+diBttIXJ`tcrz zH^0E#_Rd&~o`imhQs>Z{{9C5J>zTm)%Dq+zNvtfO^g-^n5`o&ohc2cPAN0J$B2TR8 z&^$QxL }B44dk{;&!qa5`mvsAyyPhNPPdSad2fND?y_E zB3S9U6Rw?>+{n}*PQJgw4JAI!<6d;>Ht}~BBL-e25PA+fEn=k*)fe!XBOeM9PC>Q< zwtuu}UaIeS>98N^i=L8)cL~=Jr MqQYER^P`uR7x52P4B)@*^?lS<|C~a(~rBl zY2*P}Lc@BM5BaEIeyiDb;F3=`%`oPGo=@ErABG~JQbi4E>ryPuHa?-M4^>tx-=``3 zBOpMiu;P%8ZOpmPMpsrkx(i01R;xg^7W )BdN12@a2!hFI5o}}SB_(vMR1Pzdk*7_mEHZQEQ>vxzG2>|2%eZQf* zhW7Q}%Yp*UJax=A3wmAI{bCn*HLv0g?Ho-ignb;LN)7DQpQ`VKXNS=!#_G7%SBH_Q ziASMPjoT3_)cVl(_>p-4xUA$ns3+pEmU}m2hrGlv)wyLJX{wG}^$RPb0*l0$I-Ky6 zC>_Jk4#MNOlIj2O2pkn{rodvsCO`5CnkhEj7uJjMYIUI`Lo(i8k8F=4nYsMU7!VM} zTYTCtTlIt>84!cloHy|k&z=s}K29z4Co!wK#&muiJU7~s-LQ0V;CAonDkyZSQ>=*M z7gQz>KuJUbN1)a}+b*yL-~^!0Z_r`o6~3Rc0^NP-$g+uH%fajTTX3Bdg0-a;46Htw zDa`_$+-~YDc-3(8XC?`Ku@8#T83oazwElBv*csCCn=UR=HEUbD+Lhgsqy?~(XQTCl zM57JR_d2__t7SSDMl*rgUOSay7B<^yGW}xFF@*97Y%Vg WS;emC@f35842Zh|~0Uw`_YGQZ^>#y&&Ku*fmF4n)MX_sNqNucxkf4zG1!_ zyjHz>oTp$!p~2d^iC_Q{ozHziFT^q%s8!i^BU>XpYRUk)qfWt4Bknrm OxJF*QKqL+h 4nCUuCk&VW7WY) zE|)vbiMi?NTIN}=KO}d1sB(!>;-WNW{)t_ 3^o`^*;Z__6V=sf*6@DOIFa` zF;nmg3-xGP)yuK+pm-7QFI1U~lqARIN6})`$|5KG@W=CMvsS}}Rve^XYoDUmp6O4q zm54FnYW^iRK%!x6q?6IsF#(x2riZ&_*)b6rVtXJif++gt-KmjSo0hy*bN@}$P_xrJ zv{AH)p?c-aLt%2NRK){G#y0Zvy4evQ;5kP-SzGg9)A-u9q`co HM^373LOk1n zG2j|Ux^&NngLbp>O{}m{FIFCpc{v~m#m!*aCuX@qK9ERVgl5-k)U3{ZiRXgk6OG zsdOntd- 4`)H@+nnF*-pKuKI=#?M3YF$hKs% zL(8Gui(Z58BN<;hV~x?_${x~mX<+R5@nu*7I4P(DM?Ct`O|?p2;BNMJ_ZPj~CyA;M z9x>~XETtIggeC7z^jh^TMDF#R2fF)@RpfbvCJHTpoUnaE6~yXM_0rv|_|X?4_Elr- zFPHW ;qAz5n)R zgxr%(7lN=$s6`iF3E(XAqsP{9;gJ6(hvM17Y qF6V37WN_w@LG6W~goV1af@V{1SyemOQyywb2}5i@)=j^z z0VIfZJ@s?!^3N0}YVwl&wdj}J7M&b9)~P-L6$>-I9)roBk6KCsn#XDxmLBFQ5{k`P z7uw^80IW07o$Z;Fg-jwWlGGqJ&o12lrwappawBfCUFqM0H0FmsZ#PeQ+*@@Jxz%vl zs(9w15Unw4I~wy?c?w>i7hom_TYOz1%c<9^DI;l>QH7w6ZeF!p_^qa#`}yicv&K9v zE8(phhmd(>Te su&O-Usb7#jtkVeFtDs`nPW15W z8z9iulA~Qto_V#2wQ9}~8>DLwjca5C$^xtGO)~` bR3@Yf zKIi7u $??m~jj9IZIfjDvDSL*uM@ z@$0z8Ct_MMuuLmJB*3_S#!j8;wq`_-AhX0k $=D%O=voi^@qN!UAN 6h?#3{bae|+W7+clhyU lKe>Jm0gb9S<--)Izym)^goiig9C2*@qS6#E!27&MSZ6 z)N*Wzn{Q$`Qjpw+b2egHqj?g5^Yf3%?cmb;Y%`Ruw-OK`z7J0YF3|twBB6ZY)GYVj c#bvkkC!(c~ZqyU=nFlHb&@1 99D$vah@Iu$f!>C25@HjqFToD);xeKYQE_?2QQRZXz5O6}g&b5SJWB?KUCp zuNPq~$(v6zeN4L<>xKORE2@+tnT`6H%Ko{e`uWD~IZ~^y6J;AD+(l8n=4)BZ`Fk`y znw)y|@e-NWC}B&Lc7uzPZD&%>UVGzE6SBY8k ~(00Y0jUT`CcN)U5Jz42)vPnRv_H{(q1kVS{G99>A$uRDvmaJq~! zCeoB1Ddljw_U#u G2(Dy{zq4zPu3rvhsqM3g`YJ7%F z&CXPaQ*gn_HNmr_?I_mJjoDfyVUT?Tf^795|89dctKu_BP1e4 -`TpDa8Qr&A*X`)+mJ8V2cWVC9625_ zpROPV|GM6h^TCb?yS3iaPj_s66q_=a7PT`d@EBxozs o&S#qlm>*_H*eBVE<7bj|Yc#AIII3!zQe=lYnL`(7n z@9X#gRh3N3;y9vS@9)yEt^1XO9cGlhnEFLquZT)<6jDY^1^>=zSI5esp$*yXD`BHv z@y7<@-)ro<#JvCG5ONj%zB?o8?NI=~WHA
`f emV2XniwEBG)VL@g9wIUp|E6Brn5AfUe@jJHR<|yJ~ISJfsNjkSBCqcBY|Wc?HnIU`zt1KKxeqlqEJM% zC}VEU4TCA#n^WV2az1nEDUq!{F@*+3at$w4#NRB^O4}>>@S=T{6ucSTBm#kCEozp8 zk%*x3tqer+QdZDddA}=RZ;~x+k?{=(q$H&{YG1nk3$fAq=1saK?v^4^xs@`dh^l&H zZ6!j>Y}LeA7m6TU-?|DSoJu%L^F!+r*dX_QwjQfe{K?s>>+tf?biOl}{z$me=+|$S zp}Kxy@pWBC ^YXh52@LhQd5N&>PydU zK%R|4z9dn4jBY>xVc>>UX>myrbDK+d`2iQIsZdIY*43)nXdN@no@HAD!n5ewzw3hB zd&cEcDyALqWBN(c0CA~F%>%(^kkFgQB;z=dLTreF=I%NvDP5C3wD1RSSOLOo0R{rI zjlFqW#Jsr@ `*YHD7F+liMHwCP;AmpOPle+qE%dlr{i6*VlPQQr_ zklvwcApAQ}?P#q{*;yuhbLX$SZ07SK+jrVO2Qg643`%OmGHT2S`&9H0a^gY)e2LT) z=8RXEYwju)U=7!`$YC_t`Tp(>qvJmyJBe5G1{p@FcO$s;!ZCh@rb&X90lk{}))qV% z+Z70cmfWCck5A%uTwux_H^U*|)H*H!K@mb>ev1 YlizMNnq522POwQ)YhWCWVSk_YKD^d22`=z4zO@;-k1rF*TQu9527Wud@-n{miD~`@!Jd zG+(ZwXA?+?kk|Yc;xgO!ZSNpYvRLEl^KYLt{KnGX^_zBa(rKIb18xq$w1Vc=J=-%f z$SBxE-Q%0`q1C>|5Tqx|jZ|pZm{u9@u &cm>tk&JSfB#^9$>;Bk({Ht;R z8%IX}6Q>3^Gf0B&in~iJC$zN==UT^XU@=-g6??lr$9oD1r+b|WE}48LH-xSSE3@Za zoosJXr6D )ORr>_gj*d(4zCqh$MrN}Y1P(N&?f)9RG0Y$~dPVA{R)rEpBcY3|FE zvthh-b;o6~hM!>0H45;(k*exIN5_FJZDnIvT!|gnhLSmQ!ey@OZd*N4i%^$%!l`Z( zFgvWe&?rQ1(`5wk3%i^&BPL*SA(`fU?$}cwV;>Z*k?eFi&GVPv{0<3{T}bAU4MR|0 zuhBWqy2N{TFMU3B7J8^g{llrjf?2bBLs`7k;oObb#oybH%#b%Rt$3`pvD)aJ6zR}F za5XG>snx_!rTuQVZAro7)z!%U{iOE8QhS|=uP$TbGa5I?WJNI&mlMMSw!gNdB^^8e zO-gKYu_4c`#(Q? r(+S-vD=ShZ;94{657pn@sbhn3z$v11+04Hc z1)Xu|EkDbHJoQ&cX @Rk-sCI+|M)7J&UJ;m_N5TxKa7JDZG=-VFD9jyHoav2_`Bsh!niTxAq2 z>M~HgG{#7f%)=Km(>EKnG2G^&85(lzsWZQ)2CSea@35IaQg6AOSVU37hY10D%&B*= zmRA_Rz6JcPj$Iq6TMt6)hP<+~^Vf>AyvTkc=lF;nv!>yd!$A-M=vG51n>q2mv@Pu; zvXj5|x40Znxc>_3LAJ9^aa_qwn|lJeX7eI6C;RMho}3G2j|} g@XDO-M zx}}XP-U+watO$ReG$qg;PfJ(?D8Q*nYn+^Z5pOTu7&_oJmKzDiq~~W1GC#4-BnXm^ z{`)+FDlbO!VA!LJE!BKse`~J*%~w9;l9!E`&;^-}fo=lzpv3Kqtqx%xM$ YL5qNCl9;*al= z{^!ReD;qN)my;k+T^xho{y>o?Q6ha-=}TkjS$@4!9V~8&2lb77E3;`o+kfQ6(`)G$ z&J8*4D0uLSY5Xz^yH}xF6g1lAQ?CPth@3uA79vu${x&T|OjzNn!n+;3%3!RybaU3l z=$dOqh`Y&>I$;eBQ^b~AqkESo_cbF)I@!ZsrRVsr4R5|TNZHid%8208oiFF$LkG-# zMQ?p^JCdP<=r-Jd1*6Tx{U*8@zZ8pps!t;efIhn)VSicmB`+r1v@vvmx1(1&D|KEs zgmP!u@>2g3x1MRcce+eKq_X{)$EIZPOnYg(9(DOu;uyBf+xb`4gcJwqXWQ#6w@-Db z!WyMDzQPDsTe2H7k6ghA(l#~%o!fMp$gd+JH+qvk?@a*P>!#e^*xeCLP*V@lyLbsL zw;bymq8T*1y7akvaBkpb5G8E3u|MfTP&*vFtO>J7*wzPX==mM~qz%rD*LItd`;x!9 zuL(^CX4D3!H57!q&J5zj>d%0J$m)X8%GFq<@XPU{DgLv=bO& mQdv!Z{a`wftwc zY9>hPe|Rddwu0%a@*GQ3Fl{H;>||2aw$|s>ib+R9QM&Su~$r3!@O!>`df+q?T7ylOUyeh literal 0 HcmV?d00001 diff --git a/rfcs/20191017-tfx-standardized-inputs/oss_lib_org.png b/rfcs/20191017-tfx-standardized-inputs/oss_lib_org.png new file mode 100644 index 0000000000000000000000000000000000000000..1e706c8da871e79941da5446428d82620eccd789 GIT binary patch literal 49047 zcmeFZXH-*R^DnwVK#CMaKtaF?N>fC7iHe9)MS7@$fPggVB?Lu8ML 1ndF^0NW}!2a;T zy~hA>tO)? w?kAKV_)NkzsWdtDQ?2j zS0QuYrvC50|I2~@;~Y32?+#tp?xu8O6hbG?LP%pWrq;gOSq*I0_np_VjI24v8rUJ8 zW2TT7c$u{A)JX^V(Cod+oRoL8ok0s$7jPV~or<