From f1e78627fc1c77e2c9364d905e25ab32b98cbaba Mon Sep 17 00:00:00 2001 From: He Zhao <32693629+zhaohehuhu@users.noreply.github.com> Date: Sat, 6 May 2023 19:30:50 +0800 Subject: [PATCH] [feature][plugin] Add snowflake datasource in datasource plugin (#13729) --------- Co-authored-by: weitong --- docs/configs/docsdev.js | 8 + docs/docs/en/guide/datasource/snowflake.md | 21 ++ docs/docs/zh/guide/datasource/snowflake.md | 17 ++ docs/img/new_ui/dev/datasource/snowflake.png | Bin 0 -> 146143 bytes dolphinscheduler-bom/pom.xml | 7 + .../common/constants/DataSourceConstants.java | 4 +- .../dolphinscheduler-datasource-all/pom.xml | 5 + .../pom.xml | 50 +++++ .../snowflake/SnowflakeDataSourceChannel.java | 31 +++ .../SnowflakeDataSourceChannelFactory.java | 37 ++++ .../snowflake/SnowflakeDataSourceClient.java | 30 +++ .../param/SnowflakeConnectionParam.java | 38 ++++ .../param/SnowflakeDatasourceParamDTO.java | 43 ++++ .../param/SnowflakeDatasourceProcessor.java | 132 ++++++++++++ ...SnowflakeDataSourceChannelFactoryTest.java | 39 ++++ .../SnowflakeDataSourceChannelTest.java | 40 ++++ .../SnowflakeDataSourceClientTest.java | 49 +++++ .../SnowflakeDataSourceProcessorTest.java | 187 ++++++++++++++++ .../SnowflakeJDBCDataSourceProviderTest.java | 65 ++++++ dolphinscheduler-datasource-plugin/pom.xml | 1 + .../licenses/LICENSE-snowflake-jdbc.txt | 202 ++++++++++++++++++ .../dolphinscheduler/spi/enums/DbType.java | 3 +- .../src/locales/en_US/datasource.ts | 2 + .../src/locales/zh_CN/datasource.ts | 2 + .../src/service/modules/data-source/types.ts | 2 + .../src/views/datasource/list/detail.tsx | 15 ++ .../src/views/datasource/list/use-form.ts | 16 +- tools/dependencies/known-dependencies.txt | 2 +- 28 files changed, 1044 insertions(+), 4 deletions(-) create mode 100644 docs/docs/en/guide/datasource/snowflake.md create mode 100644 docs/docs/zh/guide/datasource/snowflake.md create mode 100644 docs/img/new_ui/dev/datasource/snowflake.png create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/pom.xml create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannel.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelFactory.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceClient.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeConnectionParam.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDatasourceParamDTO.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDatasourceProcessor.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelFactoryTest.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelTest.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceClientTest.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDataSourceProcessorTest.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/provider/SnowflakeJDBCDataSourceProviderTest.java create mode 100644 dolphinscheduler-dist/release-docs/licenses/LICENSE-snowflake-jdbc.txt diff --git a/docs/configs/docsdev.js b/docs/configs/docsdev.js index e005b7a63d..6e8a3d58c0 100644 --- a/docs/configs/docsdev.js +++ b/docs/configs/docsdev.js @@ -271,6 +271,10 @@ export default { title: 'HIVE', link: '/en-us/docs/dev/user_doc/guide/datasource/hive.html', }, + { + title: 'SNOWFLAKE', + link: '/en-us/docs/dev/user_doc/guide/datasource/snowflake.html', + }, { title: 'KYUUBI', link: '/en-us/docs/dev/user_doc/guide/datasource/kyuubi.html', @@ -972,6 +976,10 @@ export default { title: 'HIVE', link: '/zh-cn/docs/dev/user_doc/guide/datasource/hive.html', }, + { + title: 'SNOWFLAKE', + link: '/zh-cn/docs/dev/user_doc/guide/datasource/snowflake.html', + }, { title: 'KYUUBI', link: '/zh-cn/docs/dev/user_doc/guide/datasource/kyuubi.html', diff --git a/docs/docs/en/guide/datasource/snowflake.md b/docs/docs/en/guide/datasource/snowflake.md new file mode 100644 index 0000000000..db6f61dcce --- /dev/null +++ b/docs/docs/en/guide/datasource/snowflake.md @@ -0,0 +1,21 @@ +# SNOWFLAKE + +## Use Snowflake + +![snowflake](../../../../img/new_ui/dev/datasource/snowflake.png) + +## Datasource Parameters + +| **Datasource** | **Description** | +|----------------------------|--------------------------------------------------------------| +| Datasource | Select SNOWFLAKE. | +| Datasource name | Enter the name of the DataSource. | +| Description | Enter a description of the DataSource. | +| IP/Host Name | Enter the SNOWFLAKE service IP. | +| Port | Enter the SNOWFLAKE service port. | +| Username | Set the username for SNOWFLAKE connection. | +| Password | Set the password for SNOWFLAKE connection. | +| Database name | Enter the database name of the SNOWFLAKE connection. | +| Datawarehouse name | Enter the datawarehouse name of the SNOWFLAKE connection. | +| Jdbc connection parameters | Parameter settings for SNOWFLAKE connection, in JSON format. | + diff --git a/docs/docs/zh/guide/datasource/snowflake.md b/docs/docs/zh/guide/datasource/snowflake.md new file mode 100644 index 0000000000..9ef6007cd5 --- /dev/null +++ b/docs/docs/zh/guide/datasource/snowflake.md @@ -0,0 +1,17 @@ +# SNOWFLAKE 数据源 + +![snowflake](../../../../img/new_ui/dev/datasource/snowflake.png) + +## 数据源参数 + +- 数据源:选择 SNOWFLAKE 数据源 +- 数据源名称:输入数据源的名称 +- 描述:输入数据源的描述 +- IP 主机名:输入连接 SNOWFLAKE 数据源 的 IP +- 端口:输入连接 SNOWFLAKE 数据源 的端口 +- 用户名:设置连接 SNOWFLAKE 数据源 的用户名 +- 密码:设置连接 SNOWFLAKE 数据源 的密码 +- 数据库名:输入连接 SNOWFLAKE 数据源 的数据库名称 +- 数据仓库: 输入数据 SNOWFLAKE 的数据仓库名称 +- Jdbc 连接参数:用于 SNOWFLAKE 数据源 连接的参数设置,以 JSON 形式填写 + diff --git a/docs/img/new_ui/dev/datasource/snowflake.png b/docs/img/new_ui/dev/datasource/snowflake.png new file mode 100644 index 0000000000000000000000000000000000000000..1ba54cf98bae4d4590ed0f649ba46dc5415732cb GIT binary patch literal 146143 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�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 =q%swdsz?R<3ORDy8OeqD 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

Bpw2&K1=rtAkS0ju=v+1lm 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%0AZ);nHe3I%XK0(_y!NPmw_T_7b9^dDt*N5os zw8k0O0l_p=e(%HLvRhhsgajY;HXqMkodhpw6SLO|d!^TdSgxyU#Cbg~OPAN{tOvoZ z{x@w_w{wjy^q*FxYh5|PRhZm(Yt$OIuXn^y4*_;e_8Fz-<$&Yss>k<6tZS++i|qWf zNmm^)bKCY+q&Vt|p1c)TVsF$E###Dp*z~21df>s&4l;@7!^@j*S)?R@Dl(!$ar(uP ztRh_rS+raTbP-+ODIpHgGIr+S<(B9;+TM(ZAIIR?HIIR@Po)|LJnK%BFvqerU zIuBlN`^V^6UU^4GamvM0>x(Hvy&WN~h2wMQ0bXzWe00IqjQFY!S;+#Nb#IfR-kyUd zg^wHF*UOgPFFG{L0S$O}06Mn?u5}p2=Q5k}va_p9@5bbRJcbo2B7m@8rz zkmoKHXXWQ;=e^Lx^S=;$DEI0%vA#pb$|fho#4CH=;#k!ctS{#}U{0O0(kSf^vlMxl z;%0kBXr~Eg&GXix_&>3qxX3c;WrV4o5j{X2cMEInf}!NMZ=}DE z+Wh}?bUJOgaW*I|mk}~C=VsO+)qHsEfvwA#O9Gx$&Tai;&mv{=Ej}CCq@!cIRN(n0 zgxK2quB(Z)Xa#$c?V zWv#u~WKlu;ZbP=XNH8d~9#8S1V%J9wrm6z=R@X>LIU|)3vILKHHcMY=Q95}hweWQRF82E9RNj9lO!R*{VOR(75ZA>_&Psaf z!_pyy%-q%Q&Ajk_qCY7>MLu=@q8KIVqKQCW%OwI7d1ygC<>*Opih?LNg?Jj^$y!kLBJS;i zB$O;oaOb<6lt8V$+=36K|KOG@8Vc`}u=R^ZGMD9oYa`l5#eNH`vTm?BeK_%Pqa$~9 zy^p;GUwb?i{-xDa06Fl5KZLhXh!4{fqwuczHb!16kFAvq+MSu@{Anz(ubDj{g2u>3 z?$3z%XQKd!?>BOPH^}{3^PR$s+nIOlPQH%ZLE$N>y~E&+9#6WKW;(d+8WQ$LT;XDe z3c}NZ5Ai{Nj!<8BX%5&oRZDS+0iWhB1sQoUzJu(z*T?|lh@4zS2BVTWp2YGBOSTN# zqqukX{Q@eZ^3i(hf1POPD*cMKzrU2(4NUI1+cRT5ZvN)<8(5<`+vP4lPVnW<6r7aQ zIW?Ep{z^7}eM;f*DQEnAk|0gX{E1Llc^BM+wtWlZ`C4N2b*I$)jP>`tH7ZkD_1tG7 zklfXA8FsDv^CXn-@Nj0!K27y#2l#A5o$=-4u$ewlJ1vr?TRs;Y;fwj|*X3tb2m-ou z&G{dQ&dCfHc6q`Owi7U+_M2WIiyKdT#~aIi zxmWZi*N^c@4L)jYA76W4O3IfXUvx?;x>qsN+2b@9kGi!FY>g5>e&=MGDeSS(&^wt! zoeyxHN8X0;6{Zz5Hy-(OG-h6}Jl&iQF2mIpF8WdFi>M_F&o1i))Y^kZa?mVdG^P#Z zXyo^zAcuX|)c{|1-6o-0g7h|WC$hb}Y+k(7>cd-xA;I5gs?G1SR!7%)xmU)p)x^E( z<6~1M-3wZvI?ud-#H1oKq2eiT~vj(`y>(GNu?PcGs+!J9}wqr?_v7t z+vdo|2#Fl5CCRU=MwTu%eYMo2`^-)+ePyQl z6u?IAg(tL;UIja)%eIah!}f%juDL@QTC^!=U7MUO<{!#~hbClQQe=#BD+pk8$l3C1 z*po!%60v{40ZQDZCI($y{>w$OcPc8kqd@niLR_b*Tdwq8VXm9@Y1$+2%85kO`J}k$ z%rm+TS)rcN2us?*yO(mTk8|4?0|TMyNdGnWWn{;1z^mzjq5|IFazf;HncJQ3i-l;} zogLEJ7tah`zx*UvOD5L&b|=lL57yW4N#e%nlZR&_b~hc+I;%*$Q&JR_Fd5o)5z=&A zxa?M+(dolx&KaLeQ-URAoQ&_bpKT=VyqvIlN!KBUOu3?fweXEkVUMrP!Y1j(43 zH^!NH!Q_)VMzrfjhT{4ROx7D^F@KAj8j|fvR39TsrX5ARyC!j+&pAzuR?``92I}0z z?8#`~Wg=4kZtZh%!kN$>qw_R+y)bFcMM^@PF+oXCJ0miSbY0&#?EY5vdSEDt(RPII z2!WM__iQ@Q7LkY|!t~hkw|b-6|FL$n0V^AM(?Ug__vN_pr7Vd=#{Po8jDNgCIOc=Y z8yS&m*e1`6Py(AVT41eDsqBem3HiTk8!#P>Y?I)V&`U=h%kb0Wo)CPRkBy1O z5PM~DDy;4pX6UIG?%2udXs;j6Iw9rxY;Ti_%%Z!ROY0roS19k)dVTq&x9pYrpm={| zaws>S78`!$5Pa_b9Vhb+x^pJYxZ+*8$Cr`BD={Ro!Lsp@xXE`CjsHNo-~7qd6&K&p zfc$gr93}G7b}qrIPP6ht5fP)7j=UEIQ+`2>U%dfY_ob4Bg-F)T3;EagaKAH+3I61) zaGsZCJSUwnesx(g(AoGO=ah|@dlSCRx#`vqTS8r=qtA|~`bSemzYz78LY&jzM(&+j zV*V;)y@LZt$h9tiXXihTk7kQVO2-0T%2XFXsM2Xq!XyKOHvNIEfB%8suR9v;czU&s^BO36?K)4lf-)xm@JZjXf*;i_sI1 zeK`XoI@!41+j=^Jd!z{e7|Z{(2f_~=ys2k!g&%dGc2EBQ7W3zshg*pJw)KFw%O;ff z=95bn-Uousa>gUa&;9c78~@#gI$pV}t83r2`diAIUViiV@A-V}c?B80iCVq;F&Ns+ z&)Y&X5+luif1E1vzxIT`|8?(pEa*6ho5)litK7Tk*)DAa`fPZq($$w<_jotGEN%Or zk&_)wiADYrIvYBKzZwqjw~QF}c^Z~f`e5iYCot7^ja+5|1}`>0>*)*OK?w;eM*2F(fpZ^JrH~Y47LCz1u8)YRz z`XV6CKdf@72G?vLv{|BM3Vx#m+U&X|q<6}jc7~&|7T{5OROE&K#Xjj(E*LTA za?!F)ZM>~J?#Y2`NCt8z>i=b?y995#+dzx}^UG0r35~XERL2kaAC9= znzr)u9(aNSem)gCOl@|>kd8m=?T_TzJWE@)waRrkY)8euuLeFkK_4VdhD#hP`gWtw zU3kiF=xI@W57hl$v}vEE8Hb69YcNOIUs_9Go%?YOT(u$C6G`U_LWhCsi$3^XWooJY z`@}>|Ftq)d!iy^?>xFaMP=98f9KNkJb25cV3MeRm&()5gt*YYQsV4l=9s-@v+u=RC zOzhLt%`^4~I9k)z4Sn#;-dyY8m#rxmo8-wAqj#wO<7XGjcbJ^LcB}eWk?a$Pthir) zU5{Kx?shq{F=9zO#k-eWcIR$PYHa|?5%@xD35%HlXS1OUL~)Szi;`qYWv@qO1e%of zOlYVf&!J5$g~_6;c&@kidMtc$rKiE72A)o=A%O2t^h0bA{&@hia_L}2;X_=dHrq+L zJMV@-Gu?*?jCrE(op()aWgWxiJ`up6Z}6*fOufI@2c{<@ogS{M5j+mT%%@;dABkrt z*{hGrpn)$_bCu6KUX7=w=&LdJrihk>>&}g0&HLBIP3*03AKgXLyF~^(I#)Q67CxPd2q&rdhSa8>;12@*6_gXE*`o*j}D@}Ti&@#YlCOfC>pn?60dTX8ILig9>MGvy?l9sKy zgOp&fs!s>o*)>hu2ICNV#i`NP{yC2wJ9i9(+T^ID`!0_@P(%$A`2)0r%c^4m`=RWv z%2Msi1@?g9HEnJU&MdtXpXMrje+?hJ?3ALl9t=!_OtBKBrGDD%lX7!|ij~c9lM3Y- zhN~qo4SLf+(Lpo!-+-E9aRN=QgOtvZzULY@t{!VKZL$KUK~{9_ce645>QD#R8BdCF z%GpH&R508)jaMCgrVl6X>omhZ`f(s%IL*U)lt-G_JRNUOwg$MQi6rZUYl^IHld)p0(&(x|T z{@H%(t)~{IEIpGg`2QdF-aH)2{_h{Ys!NJcAw{@UQr40sdnJjI?E4n7?~P>`l29pR zEkgEXFk|0`C_?sSn6V_g!PsWT7{l{%UDx-%+wSL&-*X(#@jS`b=bZo;_B6>3hE}ksmouruC{IK! zU$VH=B}Cs^r~ZOJL)R#^ z|B54qwP)M8XFL)4Xv~cdSB&Ex@vB)Dk^Mb$ndd*^rCd0g&>y)Wv$I zW|N+eUwvNqe<5C_`1LW3Aus&(20EPy@y`gw+KwmBni=z*)>MzVsB!Z3ktdBXRzbq% zdKC?+aD}q)Mypd=C|S8pgvo3Go`YsZ56%Z)Aw2Q;CiRIW>I>keG>(dnd5u_IAt{>B zH<|NUrhiq8xYAk9*u%^NvvaHo4%7+N(JPTk@sH{`NWSrYa|B;+)7S5*p@AHloFdmz zwhykG+3ey}65U*u?hkg#;59h}znJNfF>ndk5aGF;r~?0&Immo$J@H9Gy)@&CG|xE? zT+&;aj@=CM==l`?VoJXq`~ngqawz|aXP&-G&{e;6T6wGTEHmdzn=`9sPd_YOW&?&ig3T~;oYz@ zGKezi#9PfSc|LRgNS8<$YMNL+g^y0nG#dsBbX)2NmQP?gIO|x;s2OLOUir3eaCzPV zic6>l{v#rfD7HKB7vgA9_}odtRdT~agw72d2*u?k}jSEFU^=&Wo)viuD z4W4ECRL6r6si-B$&OUi5^Jq<_<&)yLw6j>hG``Y9>~uk>P5{v?kf{L5VCC-}3TlLRx6nsisnby*Jrh5gJfJIGaB^p%(IrwgVr2R}f&t5FH zl-FLcK=m5cU106E1M=onIswc`QMwZ`Or-Mpa+#*WS6@?irRK;i0DMc(1#DOv%B4?< zQ|7b3Svu4;p7gQPAActzk3N&gMKE1ke@(bLnLl^4Op%D8ZAwY#b#8@0?g5ddL47Pn zG4%)T1c9#K6|->JGJh?0_YHJ5xAN#}7S^A^ERig) z!!c70rb5+=o4dJk(#|Jfd}(@w$akv^u;qaPtq&$*FLjz|VLeCn7`U}HY)9SJg$k&m z?bW{7YoBKG*9P?LC0{LcOD-(U_;T7?tc}nq%P3KBrf@%kwT*VoI%2m5kBt;hOLoxF zC2wERC73RG85r4eT?_t-DxCvGo8vzOvhUUCOUVuPoqXKb{yX*ucshLhX2X5IaaTwk zfZLj;J`d$)>9XmE;Hmk2E*0&Suk*%yuvsP^N=wBbncCWRYi;{n>RJnMm8)5UOWkKh zi36t2)T(%IEP*`$E%lczT8L@ z**36#E?=vh#4bAT8_C;r*NL0aL;J5R(}2R8q)#7%NMYFQ^?Mp!@X<6Llj|B^ug-t8 zobW+gMv<>tXj1GzBeq=mb@+I_$tae2$X@)GZ5n}JdXL~&ll_#>Sjubbnn zu`?+3b(4UT>{WRCek0Mz*4Q4e2j5GiHZ)T0#S=TKP^3#2y)YTV zC0L=v(#=@^K}<}Wmu$k&Wm41$9i&z=&*F6`X{j->B6UYa;C;+Obi}N80p&W%9?`ky zLI=tL!ceLC1N|saLI?z1aIp0`Zdu^?dY4NFBzjh|4@`2L(K81g44k@QA&{gfn7-a- zI#RDc{k9zNIksSma((jv(w}%+;hfG$cU?)Rz+7Yk-sanNO0^T~Ap)1D!!0JhfTJCV z44*jd>gBQs2u6ZkRQuXn_vVYMk=ds4rmO^i!?aG*1W8-XjRPi1iVM(p(1*2ZC!gBx zWZpA!WJRpI%-odwEOt{>Y5kntrh)zfeSQMQ*}|N+$yjlrQQF!Uk*#%4eo5U~r`#g2 zBqcoLz?esc(Kw+&(YWg*?0y6r4GsTNylIw1{ufaTFa55mZ9O%H7mc2pOtOTJ4tMP| z<E3UCp&pjR+=w$q2ug@o_HGtf_kFc_-zuZ zJ(*I;6|vRb8*pdjF!{TtAK)KYdu`!>Kp8Tm@u@Y4!+ZM5QDLD2c1ejRrP!ft3LOH5 zaRSH$azkBDcTGU0qUR{zf=QX$Lp*=QnJsn2=&W(sFR*-kOTlYeIv?z;QXcuyC65O}$E?ji zXrho%x%Fo~Kgpq={v-8Tc)4p`znJVr<<%yU=s@+8Pp3e!w3_#TNKzrHAuo67#KG$c zf+lt8>_*=#k`{PkPM$c)NP8so!A05o&)!EJxe!Hgl`8_%kRRq;cNTiaLXU(}xvuf( zDKe>%mZdUC@@sw8;MpU|8-KP6*WfKU(|CXpFZ?0upCfOYa_?!tS@z>c9WFQy&?Yby zNHpB-^qA>N5_qY}^hKqGbJ|eQh)J;E&H4mIg0OaHM8d>#*K(ZGpG)Q^RUnnGv<4ju0)xl%g-A1Hfh#cai`v9J$;Bdup{gY=G)k`H@f_ z`xax!ptKp@3V*twU3Vj+TBT(NgUyY!#9f7^CC{AHJRB5>I?Mem^m29V`YwHwwA`tJ z7P|mOJv1oOl>u+mymg|CVZ59_1LGBb%?4VUWV&wcMvFiw|GOJ5+>%jJ_xQpVHItVZCt1d|{NX^nHDl<28^L7xXh&1O zTXY9*!`7ZiDNV+aQeQ(k^3WFL$B7B_zL&{PI6?tXLT4oVfk!{D=?P~mhVjl+rTRPFx z_ZRa-jDr6rCLvGXgu$KcNwUB6{QEwRl^YF zH=aah9n@6=u=J69tDJ1=d~U!*-~Q~I%zZf7WmMf#;Y+T&7KaAp5-!!BSx||AZ%*36 zPCBz5X9@mrFT22>qXXx8%`f2w=Hl4Zu0*gb(8i@<$oPS~>R}GI-)?75IxSanj|z{fUmfNj zG_2`d2K8g|ez>bL0rQrM&rX|o!qgJxJMJ2dvpCL}+9nyQQ){U>c2n-!NW{8rir+e6 zO2&%k`faTP@T_tp4_e)cKS}H-hWs;QCnp}azQ65x1z+FtP|m=29F&!ctL&4n_~dS! za?@jZ4DrOn?q@^_>fxa*ZSDWj0;qBo#aqeI+3|U$L3bSN<=i<<(Z+;@c8STcnu3Qr zr%e~^a#Xekv~tD49ID6ycJR^XqM3qLS`biJ%tc`Q($SEov>Ue>Hu(dS5>vZ321Z~E zK%serhwc>god%^JHI=$CX;2rT-R4VtlzP3Hxjb!*JE7&G(Od7$4|_qg5on;;I%cY+ zb4ra<+f+tfCocP=THUv(O0T%{YUrtXjQTn>H-~f&&*9>RaK8SnzDj}0B9!Y!(5a)p zIPr9LLW?1q(wQiBIWM3emtUI{OTu#_gwGwayKO$;J0$el2eG*c?Thj3+v(ucH-MC> zbw_ig|E0w9;M0P`$EJNHYO>r1X`D?n!qTgrx3%k(y*y6ryoj%lB%o$OykT>vJ9&Wb zZ{6Xbx;VQ01nr2=PNrhxiK;&R*xM6E#ZT1@7fXjv3=-aBd_EXX$`c@0x3f43I!{!iwW8G3$gLd zA2ccy86#%eF<+b}`JU>zoTCxgIqbai#})2M5lesgC1iqIi<1O}Y%`jbR6aadyx=axQ;f3t{4bVj*wue2&Z>G9r9f;_9@fjR2!tricvrw+yB#~|=t8}) z@;>H2d`&!cWW6HCD}ZC(-RQs?r{fkTC(SoHF29AqK)+6p_XxZ>#TcRHSn-f4KaF3l zo^W2$SZnEh_Gkxnf^y+=`;oWb?mSE8k^)iUH;S-P7l)jR+uGrlk9F`UxuQl>!{KEk z!geCaoK|a9gjn^(Gr8DzB$ui&DqqA~p&%g4_2BN>#sx{>R+UeiY>qm-qV!kjY3&z~ zqayawr_@G#y@KZu{k?X>E6855;hM|yaP=QK=)k*Ss=@rv*l``^hoxrAw^5tr9XafRVCBR)-a=;%!rE4zSTR`&B*T%s0- z1CX6m&wMp`Dw?mwZXBeP#hw7)_feqQUg0L!kgM{=^kS2b&W1r9)#Rto^+nHVvqWm= zSD+FjYk)Qr{AGw{l~n8uKC&RbYg-3mc6?t_Vb$aoM?&(9jYhX7VO3d|{B3>Jzcn?c z+DyYCB3MwDH>Tg*R}0%L2@pZBIg0sSywWYu(COGuf$(hm1{lElWr3R!PsH z!Wt!GiS0t%3>QsW+9(@E3tc-7u|1cH65d`Jm6q(;wd*OrE>fH4HCAkgHl82EDG=lr zj>^5dpSjiEH44K;6j<-QgIuoXUp1K9yfBYEY&4h|!UkZAiY6wCDcI%W;?6R~GX<>6 zT1i@&7lAH2Te64x#R0dGy3-~pGtr5Xmesl0N%dW2rkOx^dkf+^l5Nv1+{bQA=ry^Qxj2Q<)emYkeW%~$nR$Kkfar(f?DO})HgbN=t$a_ zFZo5t5n}CEO*YSS6^Z_R3>rD>s_t&vRg(UNnoYEx{77FKg+*hF}urH>S>-Sy;lr1Mt^btz7}CC zvwxl`zrSXFP=;e5?aK0Li;@)I<|QnM)<>DEqi8iZFRzP`YQ{89;nH|a=^je&`s+ys z=rmW)HPs$w9zkX;?81_YRO^(gmDZQE>&Vp|+Z07-lP(Wo*E;1!2Ev~o=DkLj{l!As z2TF3A>=j2Ye>3HsIM_p}8i#RoXo>X_`fukKGr|iWnh=MuV*PoSGaoh|NhE)TNl+9- z1`ji1go<-yJj+#PCi!NR_=G^JFE*vX#jWa(4TQ*b=CyTZOV7ta)6FI?G?`PBIbgezsf#La_2e-^J*gZMWuIQ{KmYBSyfh+9{^e^M)FTOD$6(&*cVp)3cVG7^(K84P0F0@{y&REQ# z6xV&Ztz{#QW@lpdV!{8a{8MkLciK7Zj<7-IjmV@fo*e+){Mtk#- z1m-+g{`x|lW`jQu;f{kWT1|%uI$E=G(qqb`Bziw?=o(BHW(!8Bq+<)D_@#DFPSjd4 zEDeLRv)ZFvs^=zA1Cj4ZO(VCZHDq;*y0lp(lGeL=sF)hh!V>dM^VAmG@Ff7b(lkID zuKSFmdR9K8g7xh7jb{hzYBSx)c`Gr{mQK_$*Ky1QhdK-PlP32MGnN$;q;xH2&KPm0@y`S*>wAvf&~{!{8T*XghGW#d=aSD4Hzy5y{*Er3;Aqm&sP791cuY z`&{+z^+CJ#f;+1(a<2Sb{_5ZdmGk^}r;h|~(KJ>CZV$3|4&#d9b0*W*e?S011<$q* zl=Gab$yJ*)JdwxrmDbgC^2@>@GT-L%)i;ce5+>h$kK}^ac1X|`JP6I`{&)3Dhi@`3 zcD*`(SOll95yNa-QFn0S#ZM)?7eHJtZ^-cJ)=%nodw<;9+wxwG|6wfu^8)~H6i4vA zJ`JAfr~S3eXgj(0owpBuUHj=~pk^2NfEg71%TJ`r|NOmyEjkrbZoeo{%3=ETA-bDEffBRH&@la* z`s*jaq|$K|x&ix5rBPz9^`Y724`J?KpZy&opOHX#Ici3Ue9q0Sn6sFs3A2#$<6rMOvIBVH0Vz zLGzPuCxCQ^$5L*9+!8-|kRv@G{HheVyY$Owyw}(dE+a8yYsn$$YU*zIB-COSXB z71o41)eXcAme_Q?!xpDq{WBcs6i{XrQXa*U!TFqDTU&dT|CZ3N7c`*3IGVHa7Z$Iz zNw`lX4c6!(TrcCp?tX)&oj0A#(t+WNNN0thv??{yKl_RVAL`>@|4!<+J_)L zBn8iD2Z(dw@vB*tdouwpm&5S$Oc3IY+-k6Yt#qOYZAw+wtp_wj>@j6d%M=)~$|&IL zJ_^<#K>jQaNDi!knN5#k$l3SvB?@@<3ZnZ0RzI@@;!5RnCd`lI;0VDN-I;u+1Ljo;7wOucR{EA_5wIN@mcXofJ*L zp}P(;8uJ%21;)lt|B&v0_Y?SN4@p+-s97S)G}q;i`B8OnK&n9V3^Cqh2mD_;)3^)A%R!BIPp6we3RnUQ;IJJ-0XphaWCMBrh?<_WPOcdT+n> zu1hWktSm2#P{k`(+$3uchnjKyu0LhySSa_*lS0>|F+?$jUHC56dvbgzlg-SwCCN1k z^e19hA3}RmZd^3Gb#u0gSdE+fqfzSi^sq|$x@5yt&~kL&cNPCV%`)^scxOMN z$RyL7>_ap_f7$ilQZaHKwjQM@bNi0mySl3GlW3;M$hu#sb2kg1Zl+)hduhMIiu{}V8?eWu*(5r!Rq|9oZgR@ z>d;(+SD2*5(+L2Y7V5CugWm!no z(qwhMD%1PUljL1;Lz{@!(aI)9Y?Y}o9TMoBU6FjcIvsCT1Ow(4E)N5SV3Js?=vOA{ zl1a0Hw7d2TkP|0>zkJYdhT?q(tuDTnQn*x&1GW`emu7=VW8tBnE*fhf_+ksnM|z#>tSf!-yL}_~d>6|qaBdkMs8x)B z^LX=eHcu!mr(cfDwvZ$fU}0f;Q`(jTzFwCUyli^3&WA9~=2Z0QL>OBV6myD*4&9lN z-z7yesjaI8d-&RYY6_sh3yPW}y}9eiQ+?`Ap`2df@p8n^<4(Y#{*^*#U~Gu`n0FIo z)lb|1EQ6G>(`Q4sOWs>{*+Z$Jrx*2V(0CMO%)e%oaaF<)c&=Xm_=_s1ChuMmfi&hj z9v(5Hv(_~Ix7yN9B_=X2QWrIY!7XiZI6q1ZQ9R80U}>{vyk;8fR8hbX_9WqkswJr} z14kFC-Jgi-vPtGj>16WKMr88skTd9E!u5;Cu}bhx{9F(9vp7C4(F=EJLqip znN!)=5447|tZp??MJL!O3+;$+Jidmx&p)_44x_diVn4%p%IXx9?IN;uUlW z!XfKTzbXDmsiZHn_m$9B!@5AuZ;_~aT)7RSz2tyAt2ZsQm>0dZc-`r$$HnT z5aH$dILhR_;>qT!*be~{I}0Y6rn;!j2K(;!)lEmK61)C01~Q8)7-H32`AC1%BaLQ#+uEjJEND!V6$pC z&W?COGlvU?n>2zIqHH#i7OQgNd)-=6-duiq`JMhwl}&PaW<1wa`M6(u0pJ_nsv(*A z5uYbIw83s~XY;_?1to`s23DFY#{GoG8fkSEL!GTiBQTpbU;2<^!ppPsvOX&=4gcm+C^EjxXW#8XBX5n8Wgx1OKxsLiw?*>?u~wsK8jF&o;OE zkWa_W@vhKBnKLLEqdc4xgq5D|H zxE-5`pGvK2)0VEW8&asW`-VnWj`Lu;FOy^{d3fYpLFHYHC4ndE9mMiP(;+^(AmjoMp>)EhFscOP+Prz~|i#+#q zG|wkGPt2@fT*hIGBOaYE;73F5r@*#e^B$0^PYt;xT(kXR*|N7fvSFdwqG>4)?hwi+ z@472jz5~UP712HnDKodtbwWdb=~c_P1&#(~t>v8-xh23G^>o13%{pUkn-~@xbI0@~ z$KByZ$s$NPuXm!>FD_11ucVnZU6Ol?1irl!4rpyICjvHre4VHeLKp+HJ$>8m1>SIxVCF{$z{0Aq|^F%=LHa01fv&FzQsAJC2c z91KS8`4bANN&6BVjohXOMiQRkXkcxvBle-%0EkQ!-z)WByO>?| zRh6#_*LkeGwVA^RY;c#glV6_KQCN60IpRymliqz2ws3?%S!s&6TbHlhpT01%F6@d| z*!pUM8!SllMeK%*KMFH(o7Pz_!M|b!RlBDiHg@im=zFsArbf2`LX0UK(;5$UvRK+*idVGMnimycsv)g;4Fv4QE?pOX50hikMwgL6zrHq_osa|=%X7T$EY)HJ2YAm;B|_!l@uM_th_MWP+BktgPk^xHwP37gMDs7S_n%X&hqL2B?{0U5|O_TidSu>?YF3I3g4mHa}hm}me3--O6$#TBc7H_2^m`b;c<}Idqf44vXsVjxip6D^9 zEY3m=tg$!c5I|+sh(l`4v_cwKA%Df-oRPS~dLC@yYVq};gBZ0Y=Pz%#^NJ|spfT6U zOEp^wxNT+1R60}so%qgGo4UiHjMZK0vdiaVx`u3bLKB@)pM>kvJZ;U(35Ic}>E1b@R&EgG~U#&P(z5Y-Zi=O zQX$1U;iRk}cE^)Lh7hALd`G0t5qQp_j0hhUxXNPn3@?s+8S`5gs@Yf*0OGP^UHXO6 zPUXW{o^7psN*0>&FCkmqL)214C+OO)!4=>PGP!hHMSa#-j4TTvBM)d?z;>EP9~6Zp zchN;VR}myAGl@O^uYCs~r~Os}%Soob50kRnX>}8wi;Jw`%FQ3rn3$+bcwxuB`(Kdn zfYx|92;ngRYqf}w+hMAB(ZJ90?I$CfKlaZb2mQSR?>aJkQkq|$au^u!aC{C@DR$9m znH1vgG6nB6_{E@SC(P!q^Vo69w9G?Gv|VBDb7nrw=4ySV;sy?l?!fD0y`4@h`jRNw z<-bF=Nj#baS0-_l4?PHbnDn&nlzMCGuleZby}U91dJf~y#~F}t8r(w=wm2IIzd;a` z_7DUsh8vJyF8N1b`5uBWi2tMTcL;(g*u%~^9L@V3f&c-ZmHX4WQh$RWyxv0)41(@+ z{ssmq*h3HqGLLb;LlFL_)OrsDG689K!T3I7gZHFB5*jAizL%2;A4zeaIqcS8SBE&a2&35`lwzHHTAs)R6M#4QU&Ns-MtdVZYv}`A|-Ltow1b=!|z6F?U*N zbuF8>zi!7H+81d$(=PmmWg}+rmypz9Ap7J(!?>5k{&d{4go1bORvMI<$@AiAwEa(? z0z~mJeFl&X3)MM1{#2XuSFG+3SiLu1(QL{KF%36==^5c-2hAZzU4lY`W;2VYd3yF+_`w{9|Ba&NTl(> zUmhMX?{&_RuKmLx`}N}(w^3XxUSHNpZH2C75ljV+*JQB zV;6b+Ujo!hNPc0V1Qni}TeOF24Z{^f86k1JY<}CTEfRJ>u-_ZVt{|O9t9d0S{s!8w zom&~uGaHUj*qIa5)wiHAvP}(k{eIa5?g#rh-8K7HYKCwgAP>aKraN7e1r(Y0q{kc^ z9`73jiagSZ{y;TL0+cCX#1Uu)rB%@m!pVr-9L<9wm*Ru5Kv6 zckw;H8U~QRXx3Pd>ys5@BtI{Y-!xgM^bGQakLtG$ z2SnXWNMK$uU4DNS3n(3Mg84P*HY51ogFDY`TktL;b9&A~=RFc6(d`cbxM)C1ko75s zt+n#)fxs0g2XtX!cI^0@hPFE~%>salQ_5U+HyccKX>2U~#((V_wm#tUagxGwfYNX@ z_)p!um8XZ97yHx|Uf~K|+nIPBZkuOT6=tcYEYEaku4Gmf(Jf6}@me-c1WCjmiM-ki zzf2@Ro(aTFzG{@9ad|bYN4c9Q(LoRcI&NVyEiV zI{%sU!9qz%sa91uZ%=E?dcn7?j!MLyzY_}?G~gpLMX+&u?<9tlCo06BUn4EafB-o0 zs#{u3=hpcIMugTN88e)62RmiYHaxd2UFZkdovJY<2=@maTI19b+ZmaF*!$=Q1aOsM zMe4V|5$CZLE=j3n7!d<^&X$VM@B(6|M1}F1{#L$2R4@@O55VPe&n1jCRtzV)1ou@7 zse=;uy~l45;a$cMv;@D3iKZwfOq}di#h7@s;G*vnCGe)n%YUXJldqq{dVgB-UAJ1h*y<1t-pajmB-;1k>e3G`>d8 z^{iqP%z99C>`@buP>WiiZ9w*f$UPb~@fy9#(pKY!)ReonarUawAG4BLb%TZu1=9O& z4jrUZVM&tp zDn*R{eJTTL+F+ZCXcuNXWp9JBQ`|4Gd)72`Fv5@KFhA%cyHwj(Sw6+uA0WEbb>;>zICSm;R`)85*L*pnU8 zOxidw%qFC#&aivdq-D?ta)eObtH40kIIPH19{@uv%uo4N&xMvfQK0r6Ju}cjYarSy zK0gq@(ozz4aa)5)d&*T$PjVq-iNpa8UJl>A$NrwYMD^Qh`U=uYC{)Ou7hd~ zFKIvuVqBJ3t8GIgL4L6Sr*z1;AU_;*KB@1{J<7eqrEmF4+?c~IF~xtY6$KR1ygf$Y z_KJk8sG=wGF7K-^dTSePe!~;|CJa+Sr(xDIcUf@fB%ZHc80}D8SC&+GeVm6zyZXea zBx>%o`=LADM@-;E9V48759!)Ol*q(=Ga;=m{$0)ia-6}#Q*52{7}n0sue|g9Z>T8p z3?n=uPcVLL_SqYjrPyk zI=*Ah7|`&LK7{3}?S40I*{75c1+J1{13D=dRWf(v1j^!lOo5lWx8s13TocQF7R^R3 zOFCheJ;gDI&{p80q5!AlqR)vPZ{6GPU2g;$={IgU6y{91wr`y`aj~xf%0N@DRmei} zm_ua}{(9VzD`jRw4tKAA0exP0Mm|NFd#DSi>3mJ?e5|cA9Rj$Y@mAP%HmEMe6tJZr z%ur}#T^S%K3NJvXpHeQA()r$>mzfDA1(Wjj^D#vCIp{Y|#JBnm@4~u??2K$7*@h>G zP&$&+7ypIl+4u}qQE#oU>9h(@tpT#{u`j{wgnxzK(f-qWQ=W_wJuRI>(Xc2fCn*Iu zJQCcMRBngKQ6*~6e7~1C@6CL7^n0H{pdfHfdACVZA)f_fB|rz?uV+2mqLwH{f3lLx1O2# zK))yb0k|J27U5Eeb`8&Q{9tkQ^rh1KB3C*H8BvI(CMdt`k=c6t&IWr>@$~YzIbGf9 z*WN_zeE5~bz_)fU%aWWO%It~PkEg^Vm}ZkeamBn-hyMwp&d!9@4h1l%&ngp-uek6fA0^1j;&XQ)?tJ8hq(3U z)5NR<1Q&ucxI-)={-Ek>BiY^IO@D&b0z-#!^wqnz6rt2bk5>k zv5g-bd7Qn!G%vG_`A#4$17r!cy>gir{@|*&$Kxz+5C1)@sxYG4ow+R;A#Y~*CrA+u z{PD-zzYFnm1iB5SR7S5z;(_`B>)d?66l-zS{(WkHE(h(aS1)YfKW#r%QGgdWiuj9x zwwFn}V<4UDK3(31hyg$uaq`p+ElG7CG#v~ejWqbAXjy_YwsSwDk!~c>#Y-k)_2_=NKg)&>1GZSyzIVfg9#nJzHLtPGX zuZ~tH;R>>i?e5@g6x@H9xGv{cJQ`6=5;Kc!GzspeQ!jyqMg{5=(z4CDJVwE{80W&QjN_`kOiSSU#4o1a%ksh*6q!pftIjTNk#mYTSvCf2sbLKQjb$*Uv()#_eo z&VQOQ2iRWYTH=vAz`X#PlpN$QQx_8046M&a|0Eikz6^}zp2^y>7C?0xvW-Oq%P#eB zivZb{svGABPqe#Z3og`Z4rRA~ZR&kPZ8Uu*U(1NY`wo*G2!T1MS-L6hMhTa2-_%IF z@ut^VtgK~f824C?HISq@^1V04XOX>$uwy6&6OzlP6Wa*X(VAgzW7Q9~cnsy7Gb>Ds zRBC$JZ?q?7w#btS+0w{2Ror@Qe2ihdH^N}|W8Geld&&(K>f=FUgI4Y_i`yrNNX@J9 zcsoy2CtZzLOc5$-(L&tyYs0&mO-qLZ4A~oX7`pEUBDPTB2&bR}7- zUz1?{s{lev&+MhSmB8C5ywb^Q=Vu`T8A*PeYjq(lt>Uw9iF%cAe6i|K6aQjS2BbPd zEdSm(4=iBAVEnLCc9am(T_9~2^xE#o%%WRW6gMA@SlP|_CwQA&&#Y%0KdV9@sP88P zcx*^2dN`0<$D@}9{+=QhM^Bn&H;M*7ghI!=g2TaCnpE-n|FY- zho2aE2H6(O-f5OGW-{EE?%GHM1OsnI>dC>35jtJJp8Lwd78CcgrtV*Z=p&0Q_4(BtX)>)?H_L%uBdcT1r3;t-1eY^c?2jmeKKkTbYrDA7=z zoDaU=rQ>vLdkNtRySVe6y`5qZEWXWj(Zx?O`3e3X^VmXO_&dVU%4>G8s$}yy90CR! z4%Wx!DnWf5X6v)5eVO3d`?Pn$PYNs!E>4tJH1Tj4G;2<|co04o9JA75f3;tv3US^o zE)e=QNBN~l@V56LgmQQmvecS=B?NMauben*t6DRE611!bUr%{A5Tx`WO||^_Y*V*J z-4x5sT%l;*Mc9<@!lu)WSy#r(^`;1mlTk;48mS(^rzeWs>zE><@iHvLTSpYDFKrM~ z9oLL4B2q3PqiXQ4a*p02Jt%&vctyM-2AV7GsSvP;*ki~r5n#m|+AB77hPrZkiFqfd zpGl8uPL#XU$lbKFX_!4B>;Ft+=uQ(_4I85Fx=slR42%PeW&Lbp#Yc@3<`YbJ70#)& z^fN(dh9TZTCKeh0Mm`kHUZ`~e{#BSP*L~Updf~~7 z-DL?+1+Pf*Zm`@)=>_oD#jZIy^6;m1QyW!M%fU#HyIOC0DUxz_9tNAzHR;&E>iu|- zYsbG2XYSWubC^CyKxfz)?L{*R+;rBI>-t}LM*6BY4w&)+mrE%i!)8!-ljW~mbR<;s zCAWh7^5INrTY2`~vt33-tfzRuMtlEEOReOvA_i=b^l z2W;9mVy-1~=GK~0%K#G$L`)x^5w+^dA{I_3gY%U;Am0&T@$9{W?&#LW{G`7zu3B5c zEQ#?NInw8Ds0U?u; z8!BbNA{KLL)@!RCaJvBR-pwT=0nnkZZ8j=WEdoiQj6FA;^_7~hdl7uL z=EF$VqD$3I>hlKOIn`#2wLSC>DniEB5ecd8d!e7Yn6-5F7H?{hi7!x5CG&b+Q|0HI$+q96oF7 zZzw|kBgLk0TAW3_F8xuyqmlyuK$v2kN|e&|=l+iT|0Tty_#Y{@KU$A72DORHUIb#T zhbx;bTa}!S6IsAHfTLV)!?-MKY{x^TurHZj0qssk#r@@hrv2nw598B5zK--r>ciuQ&q9{5GgiHTNS< zdE@n24aBFw9@qN@{(G^%TY0xKDQ9_L%Im%ikm<&6aNdgpElHD4Nl1D4tabVQ%SSHb zaPvb$zNx8Bx%DbgOim$>;Fj=$f1g(yZNyehHm&CU@5@#1{R1ys`nz%nmGwU$xEOyl z0u?5^$qRq=FxgPQ>YB#@iy^(Tvbz1}7;-hb-*dMyT*R0uydQw8$i=f4*Ecc_7*O~} zy2(wZf(*IJ?nWjNH>83eEKHyZi6sqmAm`+^*GfR9H^0etAJEla95MKgV60a8C z&W0wR&{Xay%JRLIs(AIVKMzI1I?>8}IwEsx&R;iCd@5OE^L$u{A8A{Pz^}*v>)R0( zEEV&tzY#GWxs(7EVSx&lz0UVT#^+I{Hget23X)1LTOpbD?5>9y-& zGh><>e;nkpuNr0PGIwCeOyt5O;7K7zcK$e9l7EDK%#XFBd@ zw!{*F6jBwWO5*!l***h-r(&t0D;8*d(I0o4i=p4%=u;UG~8`)@b}{A3H;gMcNwpv~asgJG6D`)Lks9-be7=XJM|>8}bV{!}rEdH-+C z;A@9+?DyZ}-$Kz|)Az9UiH71m*#7-w%zq=x|Nayy`tJ}8ziOTS>EfUqg9Vya{88ng z;PJnTZ$DMX{!x769dEK<9O5nj?G^`*==TG&IMvO#w1r>B`SG<$nwW?Sd>Zm;|5nlz zcCL=)<<02t?!Z7_!M)6p6aBv_c-fXVe0f^}s*%riHF`drFewd4kI*_I6X$0x4p}&o zC}yYHf0DKQ^BLH@wayVQR>)6Z60`#Avfjt%xlNwGnFP(t_rfO+rYoa$UE%Pjap2@P(WNad>am-M7n)d14!d$KCn&!+|wy zPCNFTq!@B;`85B}EmxrSSNh~}W8S|tQlkk+A>S9;f9fXRZaM&DT@Lj1lmPQT0D*J|v$D^qlD@e^b4U$SiS{50(ZrS-pZsC7 z{2Sf+UtPTaZ|LIv@5}oRZ2h;5;Qu$GhX4EW{tsVX@YC|K|7ZbxACmoZsQtgMPWgZT zBIz74RUWg3ph0!8puO#jwAb=Gh)J$6@GY)b{G1*E8K~b(qj$s=lnV~ru^WVjlCHOe zvkrn@qbK1C4ugX5+{?J`RM-YW@j3;0?B}i6N$0)VpSpd@BM&^}x4NqrQK66#TibNZ zR*y1w3G+Q^DLiVAobo{+-yAqkM>|!wHtT9=y!N6zFeUc}>{wE`U6Jr_;(8_%g}HBV zSVIUsKFBGc<`o0Cr(#`pGAQXY7~f55KO-Ks6`C z_`?$SLDs+d4+b!T_jp^|u!Qr7I`IQ7H>M@U@3;s$F-%x?oH#NWajHFGvguWmb1}RS z)y%noU>b7)0_mO}rzPYM2I|~>y?VZuY5T=)?Pje|)ztAF%Ot)1aOrb`KgU;pA+GTs zfaj6M%k1<_<8~X<$8>;9(L-yRPC3?ttY~9c=2C4RzL;w_T3rF~zvR)tI*;m2os5uk zgcla8ZdXZ-9n}{Peb5wfY>d|5B{-OA#7n)CoPQ|4mgRd)>+jH<<$PpYgKE4yDcenA zJ-J40Lg&`=^R3IZql|+-K#VtEEBmDmS^nvDB~*iIOHO`%>14PRGv60Q4vu&Fqkyn zq#9j6n{cSM+hgv16;yxE&ufR&At}Mfu3H8AFo&b=2wGStKv0i+BiH$u00hHA`4%QJ zQfuBWT=No`N()t~40eh4+?`d}UQyh@D<^81IE4vS-|pwIZ+&;mfa$p45qyw&QIbFA zBA`~4dH4sn6Hq*XvBt^~rz|J^Pum=bWB=;sF)CSIeyXQiFZNzf-3SWiOEPuZn9trV zQ#xVr5m4dsI?EQg*snayS9^2m1L!02!J!c;SOjV}0b7h(FZvER-pjb&FVSU4AbZaa z^P7<)fX;#UEnFOF$p&aWe!z&7I5w|s?TsTWFg9G=Zp{j7k8?7)@V<*_cL@RfbQL!w z(q#dE%Cmske);SGBWEg`$UuZD*){dW0L|)E^^wO__x*hg0U5YT&U;0 zgSx;cFu~-}Dlc)HUgY6vBM+M-|E=8eiGw&BK_&&UnQi|71wHhTOFbcM1o!yDBWZlC z$H)}%l)w|FJRGZ@sZPtC>zzHyoEE-IRmw<+g-a9V>$4`N63~XsJGR=&$5p|qclvYy z(FL?iqqY|WWGIX4iv-EBm6}h8M3?eh6ThC|@|8yVPwgAG_Kitkm%qjV>RO6p9Ryug z(j_Hgsh_u;-Y!z}@zD_)or;_5$tGT~nVYL?-Q7A)(eToz)`cEL-wEpfoxTQYAJiR4 zuP?IGGqYGffA8~fBd4xOM>V&X=7+lc#`kHF4XS*)Z`{bNWz3G;e%<>tHXi{$x=ty) zALzm!duiRuv`0*lR8mh{mwQn@_E1Kv@-_UN@0QriX=%@s`kWpc8lEjlUZ3iGijyeM z17z(55T%+)IFVhU!x#s%8XExcA zvRtB9nKMS3fL+>d#w}5DX5*g7#!knX42o@Q)g?7*nwb;kEF-Xo`F1XjWOn)ntCGTN z+d(yc-g^|-S6bA+g3{+*@S~vncEby9_162`J5OFC@ zX?BpVQj~5%1f&y6LMS4=L`vvIR6s>QMLMQl;O zl*#TLpvdZBesQUrbn&QT;anw%Ne>q5ZJ}1|b^SE&`e`^OKx<-Fe=Ky`sG2P2*VzR_ zn0YQ1_|Cl+c>k3}FO%3#5jGMP=F65^5?j?P{KP=2qV1>Wee<6qcSltTD$bY~#OVpt zgSy!cT7Orq|z*wxEVc5der7eou9(63!eIm-@TG#Y#kwwk2MUy}- zeTyA>@nfMxg|qi#*Pt!$oXR%Zl$Vx}1D*?5HIJ7bH+1t!^ z8X3L&QMblnZ5R-@GT+2Dc`tgCYG)zb`eX^|)gnUe>~;*$;fNaMm|ngRx)@__lG${ettUb=*VjZyo8@>xHKW4vv=Q|$Sp+0MI` zPZn%Ti4^qUn2lK915|e380`J*b|AaQ9rh%z-Ob6(V{h^n=3NJ0kR+$o(jR8i$r^a{ zFfF-gs1-kgP#)ZGAk^f0_vqg9&~)Q_XTyay0ZT!pf{4l~5tLbH0Sr0BX&N0`Y<@Tl zQ7S#CyZ-^su}YDsmo%I>e$QKQ_@F-4Z=y@6)Ot2J4Z};_icH0B=eqz zMv~m1H@4GaMtAbpFw2LY$9-c(keYpErdf#O(}RZq>x(1w#`?y_dlR)R;9oT}&Pb!f z<+Gt-P%E5U&vbXX*J}~uE49?@HuPP^O=$XkMPXs;Kf|v6ECeo4Yu*Ti)V!}X-#Xp| z*Pde6`2#0VK1Yk8@yHrb7Ltk7U_<-PqKgK$6%ge+Av+=q+%ea!G`n6D5H`1hUU?(f zUBci@jZUda?tvnE>bSOUr)N%j9KQWmT>A4`KN#PrH;Xi~il$Q>&r{g72Md;UnVD(x z9z~fF>bbzwJUY&hVTvdm4#3Uh`nt0~HXciD4n-F{AiW&7Q4rtEXDGa<(qYPP=nUjR z(G$n{Ql63gCUSdS`g(8F7v@Z4^*%ri)y%u@Ac@@}lD3Nx44@iy-H7!mN``wjLXfJd zFIE+TJsJ%?=aJ-HGS^&Wh7SmP44T9(OG@odRpVx|utbg~AtaEyM8!eh^J`?7D{we{ zfO+)^i1z@<;7$L9(cyi29?M5yCjR3CVgh#h>F0i_-i#|iuh*~W7OOVkLRmdoMFYF4 z*t0hh*H)+7=L@gx+G;Soe`4M8zB23bBnS)U6C`xF>=2B&pR4IykG{0Wo^}P3lsTsSVAww zcHeKFlZMHkMyDEq|BNZl$B74f5HeU^2~i}?(tA}w3&~G{Wp_ryGmUVv#rU2 zYg2;*$E3IK0sn^&eQ8$!$)M>E8l75p?{~3ox9o&CjP|~ZM)UXk3qsdJYq=bNzK@*t z!H7)0>NLUcxf!l&fG7kG0g0+PDB({>JgH-yN0x9(5r%rZ#SjPtY(s|Qgs;0jvQxWG z;l8E6VflftGYfuUj}{Rf8o<^8{!q$<{n>X*dJ zPF08c#ClrRyoy?KM8}Iv6OZ7lvo_MJtzsS?ndGQne^;3ncm6~53=l0V$H|PYRFJt? zjhX>LyC0txCp&uZ1w*TFeYEUCo~u_APs+=p=K)GJ4Wf$>r^xRz_nJ(`n=d{^;|9er zwGdq+HUh&Wu5G<^$0XEkfG;OxIq-`cJ@@lwQIPNxQ?FBXBRgL@Sd;wB3F7ahhb=V2 zZRP)x^l+r`g(5K~Idd<*oV+hA>C4ddT`HHzlryw<4{8YSKM+9m(b>H6@e-n`KC0kB z&D^Qx?1NNE51MX#_@jWeiT(J|GZ}}Kj*)YUBCV}GEnF;IT_R$KVa?~;+w->CrO5^a zT?hva69mv`+zif!GN2fxN-#zaqIU^vI%RYHA17;9s$VFEUHUw$&7=p$4Bc>At23_l zFclv);^ZaO>_0;j~-=}t8nSCqdwfNDR(9lrS$7yd3x5)v~!yfpn zp6hdMfFF5zOKljMcCn11jasLd2x_N4h}A@ecrg7rtu*j@RwqSluFU`sV60i%M0Vgm zWg@v_Kon)>)>xfz4kR3^*VD%tp2oe>Yyl#Hpuw`VYJU^utS)8RvQ={#F3qWH`u3mz zbK9h5G5lcgVeJawL)8wM6-g^GEkBbVsun*LFbor$yl&T9xY55FP-)~F%g8Afy*rg0 zI*P0sok4q)dmv5=u}RF~X#1MtWeKbAwA4b0nfz`__Uwa)Aa>#pzvOPP?m|I@v_3zZ zwc>2*bCE&UV@04SqE7)%qf>&*ew6?9=Ut(3;yzP7$kc@>kGt1hS|j%QtI9L&T4TPO zH%2oBi;9|mRS?^)?x%7Q6jw768+w3p8vynVy;~(kgIL7SpbUB2$@AOC zz^~LN$8m}wCTq(Ld!j5ZpJ(Svn+Ll*M-975R`9Jp`OZjj?ouTVB+n1(?gL{xzRhTz{Cl5usmmQaHB1# zSzkj#qs+(ba=M!SeRGH85q_&HZ%y@LofeGS6V`Yon&GY-#sj6uYb+Z* zK|j0nKBL04_i?{3ZYAmo^UFj#5 zLs}Rx@lt6s-2`7Fwkr=F7G_|m_&7v#BkG*SC4cVn7(ND?4eh1PjgxB8vrXYH0@QS< z?EHLmPi7c>w>$T2C(6SA_{EYu=tKI7Z&kGD%w5s%hb3pe__@qjJ)J9=G|SK4Y_MswTa2-(SumIasU^G$v{Q|04GKNKy_W#HYc&csR{b;6tJI{ytz>VS9+f z`7su19wpEAP?%}(P*J~EvR%=<7{ngfS(naTt;AF;gYM4#Xpx>KDKfif9X5kjd1$_< zpj}P!v!VAIQgU&dE=gWZW+?+{=sIAz6@wsP?TThuRJe0WhnfqTr4b68$os3vjoh5={JMv5&nHv1f{GSR_{kfU?&p&?t6l(uB9rehnB@CUOhDIJ5 zZw=!U6vXJDJJxK$37rn*pLt76xcQW}&%*O4q1sXw(`P#UL=#j8Otw*G&@K6JA9K%b z!tPcBR%h#Tw3v-G3TJ0S&nA|=>Nb2!{E`l%Tglm)Y~<{Czc0G_^O`x7=+Ixh1Qa+1 zHnUB6K&rl$W?yk`^TG6N1NT4gvz!lz+!>!l{uYe+2wr2FOCA68OBZgR-!>3k)i=-n zHpb@(1)1$uZg}wvT(|GQCW!wDk0<^%rHC426hLw#BToKY3WLtyGDtV#mCgBWjt?z} z8_F^k65#$#{?8aiY~*A3+n6H8Z1CDgL#XO6i{8QGU(^8Fy6czKZR_*mKU%qtACE*9mZXVP*dFg&gRo2_LCv18g zFWdAM=3O>P`32$Mcfg-Nfz$k&MH4PlYtN44G#)&pQ-OrUh&4b9%vG{HrS*R& znm+7z>Y91U*|1%n=Q=v>TzbJ=vS&{lm%~fLE#Z*kvO=l{{&jx;US6%wCFtnXD~jBI z>-g47kn$NelJeM4#ZLXE7e~e~(<{)tV&xLYE*#X+AEKT6w-D~%Uw1r%i!yJFO6VmT zJoorrsN9)QYFeO2^@ni&H$Cd->u?^H2UkuwTK+QTc#iwss#CNyft(S)kp8Rc@-R?i zgn1^Y3*M0id4Io*yw|k{{6R)x6>sQ&%d~s&LGT@29_x`CBLAFsz^!3?PC5U=T;A7g zZ`=QK-v9m!(9!Co)p=Nw;(ixu_r>(DgAcF$Z+h4(sx0;Xdas_b|C*&ndnZBN@dQ+l z=?i_G)o;cgxcFn7Jn!f<)UId#Du^A+`|IHANB>)<9&0+?_$~gsw~qaqkw$$^o#)08 zf$XbgXD1tDEVgnA3p>CQ!fOjLFfcGNbgbFiCCLJLqmoFeLMSJ$LsR*p?y%&68z(n_ zwql;5j9ec|Q(=R7&SRZivU>-Y`b(VV=Zl6yTuN8llqoBz4f*)oKUnL>c@Bel%fs>1 z?98pQr5ZL3JxGt0xLt1tw9wLoVgYwaC0bi=Z8TICXVso2zfy{vWk$nHE}EZteclhG zZ4b!oZLe4^qM_J)K{$SF>K>NRM-h(#kmuyQ9-)9q6;C8oWV>q*`DFW7xy=mYe)eO7?IUt1~!@diwgp~Aa>-Pp+1kub?}N#&$tbZ=Y^=a~(FGkfL-0d6V{vE_I^iZXOneO@`M z{#t23{lR6q=MK1kJ{)7r#ds^wFV(Vx9gBM%MyRV*Q;Gv8zM9nI3__^OyC%Bw0&P^Zx`_ss!$ajYcD`L}?t?%4_pC&mc zTgE2}+WqB@Ko3yhv&ZV@H>4Wr#-BbjbSUuR#fwYlN-{!Df0v2PL|i6;@;ZheBGzk} z+%4O0R5t2=va{TNSMT(fA)}$`_Vhk3-|atQCzl(9;-&6{4`IujG?0j%d^4$HUpIt~ zXh8T(Dp?MFsPlmm$v7*?bc#T6#wd0eO@fT!n5>r-|p@N4Cj4?qZRLA{UKFfI#*+@*QeclC$ItMcuIKkt_b@e?7l+Cih!B$Me6_4C-*GKPxgD730J<+Y~g)4<`s$PP^T6ztz08^w~APBkax}}{X_W{)Or?~L+=H{06;ckEj zZy3@>TH!B|?m2SREsB;mhmkX1fIKCzy_PQpgG_6c+(!C7*jk?ST~mx!1KGG;{HWp> zRKY&erxu!?=1aA`yZJ)|ps^w_-pJzCEyD=jK?2ipz1jURd4>l7ShE#@Lx5iOTOgOu z^DY%q=mF*-kBbJAeF%c6^nG0&#>W{l9&Sg0hx&RrlO3vscT+txuq9MxD2s0>yU+4#Pl{op~`hIlSCyX0Fl{m z*B$|lgmgT&vu_HYbyS4)H&QgGQSBxe_9{;sbalqsfrz;n`vDmGlb#RB3|Ocvt~~M; z6+I%|k)?``Z(|y;nGxg&&>zO*iA({PU=Ph!#Lx80w*RnL@+%%dhKG&yzGK!oMXSr5 zOAFJpD;^GTc(17sJnvbu-a-p_K4{KT322G48TA$+5MUx+F-m3@MG$sew&8tQs9?@> zomYXYr_W2+0FPx06;khRC?|*PHcDPQ@EAu@mo{N%J;uuR99M-E!TQQX(8R2YM}_?B zb@Zq;mo+kVZ=1@Rm3DI;wWY1hO?`#e`eMpAwY}+&ddQWV5wDz8w^lEDy(UUYA4iP` z%3UkVALQi0%?#!Qg>q4 z?R#s6;_=*LS(@#pmVIFKx-xA}Ng?5oL$MaDTNHi14%8|&KYW1D!*1k5tLCk723OCE zx&tP>H6joHx(wcYi+=NMSyShx9oajDoIMSujmTg{R=v%gI(fns>YlB>VU=x1Y7bBx zK3EmMMS`&A&&sqe3iJ1D(;p^P|5%PFzXjU>>5^W`j7*;`5)u03n333kvzDyYG#J($ zm&cYFTs;!B*IZ-&UcE*pRP_=d7uHP zP`mhtal_Rqw`l#HOpcJyo7Sh&a?gjIz_DuWOZE=#iy^d8Rnw&{NV+K6;L@Vsr1|nuv*z*S&owx+A$a8jhuu z#*#aHJ8a%NE?Ds@7>;3C^|Z>J9t|wi^{45Y0?VUwUTcvx6kWI)*Aa4sTDw2^Q5YX# z{BtcY{Ch1|G70C*_xhgF#RdBLhF;H{DWcL$oA;bEnoP)Ytw#w-T~}y1t_lo4_1Z8# zB_o_hd#-KX2<^@|mBGW>?KT?RfPJ*wXVuRc9GaZu5HGT;bxB^JW?S!m#hR9*BsNXs zecD@RI<7H*E1AK7!uf4Xq>V!u?-YtRw|*TDv@llsM*X{JJuYW_j?* zK1m-pf(;xSpv4FL+z$xQDO<(`4Y}C$Pnvj#wTDN6Dhn^n%g&{YX77Yw*RL9iB48x! zalTY zd`){RtD5!x)P(w?_2s_lYe3o~Z7ZF$Sdn29_Jkh!2VLo?m3udRYmQN8I(~f(6e(Gq zyv`T19H090Ww1r$SZti(axpzhVhTWt9{KC6Ap`sB;sdKRv3E2yu4hHqPrroXGe5^D z;YTmKX_j}yY9;#ZDnq<-zePg0bF=Cw9a?w;uq~QrfDd1@?TpMK8>)l|9l}m%NmnH$ zX#1g|@XM?#qaQYr`Q-}RK5gDzHQpF+;wLah+OTtU&9dyxLQ?VCevo`glVTsU_Tiz& z^p^Oj1l4Fb>c+P)E9wpJW+HM?rWnJVGp`w*Vg(jYG0;j!X%9cp zt8EdrEs1Dc!usxrtxBTig2U?Ub9x5P54)#EH?7Mw*8txhh}|~*z46adKkOtU4*KDN z*xXK$4t3Pu+c)q45>DwpXA{`54#S^jJg^gYjq?^N%(VfU<}Xa>5TmP6gc zi$8XBhPMzLgdjkLksj!cZEMrh_jpgQ%=*?}Ae*rX(luXC)HjLrEr1pejXCEd<+B_R z+hRULTNpvz3J46xu-t3Zy?k4s+Dk9pj2E1)u%05#Ju`)jt)WN!d09|Sf4EXuEnO{L zn?@&6ne=*r!}L-QX>_^9B$&B)Me@;2m3NB(#G#>bul>5BCj z%ol9|M$t>rO03p_$V}U#C}%Rp+DDA!j=NNHG~0RjA`p?NWy4LM z%PuoFQ!MSd{t6~;6_cBRjew?RRAjkcx_C6G3gc5}$8_S096G*ge{6yKYf|mu+1J+F zv9_3)5Dgd*yn1`djW&Put-p7vqQQbyZ)ba@SwlDzSuN=71M|KFE7R_(QX<}@vJJf0 zXA0yg^lq5E&bRWD={mP}ayp* zPTM(dcroV^n2dD1emHew#XtTmSn-sZ*^8IXKkJ+#@uKi%E}M(#GP&bv?jUZmbS;xE z4yu*8fw$_F<+16F%nc8mpr|gnk@6k0qd-9_RtWa43W)(-t!Fx{{Zo?yov>dOU1I2J z@k%TKcO>s^uKD0pRQm z5e+M%MNG3@Gr!-VqSjFDd9H6X5Y4LP|Dh) z5xaF|GVWFQtCAtJoYL=5mbPc@(mib0I&Vn1L<+)_@bY{X-_^Pu?@eao1xn}gHTalg zBb%Bd!*!r_5-xL7guCb$UgaqAnMKzVF3BBIv9KU!f%~;>YZ`SE_)Z<;RAH^Bp5&GA z@CCMkL$udB%~br9^uQFpva^G>@(;!P7BblJ+4wG6l_<4oe@s1a->AwvgYScqSZzzm zyVjiUNgL!;`z1!pQKCpWeN$xgpF>ESfm$p-YmT$U_*>W|m6utu zKs30&XUE+?eit3-^LPn>KS-_eKhy@~JlAHJ=6PdGfmrg^xz1|h#q9KW;8_-K2VBp- z8x_b@EZn57h71JJ&NvHQDkXNUa$a^laJk~4XS{`z%FMak`U!*_t)Tf2UH#lUhdUsu zZ*A^_>50dn&kq9nPRY!->#Aoz>Y$@FrC*`^)zVdCHAARUg_YoYRm_)qi#QXQ)U94S zQw#IfMQ}%_=eewYkG54zPEdj`bx0_Yl^`8ecLrR&NR^K`q>EAGVF%tuGscGEcT{4; z&{Y%Gt*K}DJK1Qfzh8h9C&f-1cfI?eXM}vqz~va7nSXs+O3IxfgDI>^3448oq|2*y%Ib^{b%xA!U{zup zl9+H0t_5+H#Qng8~a2$5x0;>hu*%o7v9TlaL6KOfz5N-AMrm97pp&q%S+InyyrMGY=n+n zHO@Y?I<}!wx3=So&IxowwrjP#7JRro%Pos7f5Je0(7HrBcAhCev#D1HKH=;|eHg3Z zEJHia`111O)(US_d~dfeg#2B=gYmw$xn}#UPUjM;z<^<+qV%E4!v0tkw13(F$-py} zW#5Wy!-CAcoeRo#?6=7s-ic0~H~5^jm8pF6 zUcdPJE5@t~eq)LH`p}=3=^RtNe+Ksl?VqtV01N5;)x{lO`ftXBuiE_`&oZAs8+iBU zM!VmEKX~4Kc*d+l4NMt-ZE{mg8Kp}O(T?BhIQctgLU;bZy12_5mr{Nwtm6Tp+t&Ow z)3-{F2fcZH`&VB?zr&15s<-G+2TIP~p#Pz+`ui#aTq~}h3LN~*5$?_(HW`1NhMyGk zUkC60UyTt*odJaK`QDerUv5!?+`+#f1i${*AAW6eQ%oV%7W}}$ul?2#laubRgO{o} zk}2^+k^A?(Jr3YQ|I5*=>&;ZgXz_g*=2QXL2o?`%H* z6F(WMvaWhoCuY%PVAF1{4_cgxGDdX2bM@@dGp>21FXq0?rK727%ZKhrt08AHuuXUy zi`w-%gARIDDeFbt$jgS-`Yf4#NXO6S()$n2Xv?8dmsGb0L}#K*L3g{5SsJQP)IoXm;QlW|47~e)80h~%>|f@V|05vw|5ynB zKW8EQ?*{&#zJc}M+W>cQ2%x)Rj`KA1U!%qBq8(3NTTw8c_!@{7*%o@evlD?#iqV ze+K$!@le6VLb~RH5+iS`Mv`=8^y)k!)oJqX3L7Jfh1ce_BiU846mL$K>b1Q*Lut=| z0vo%n1t6O^dpkg$T)I>bInu(FSNu!hMWZw5~Gz51S zh$NLckRMdI9AX-GHqP7lfT+~m&ir+ffH+i?Q;gOGS5LPb|OtjMjer@*2I zFj{(RxqKh&fdCt~ic26S?LeQ!VtIWdDp*Lo->m?SToY}@EN~%1?Fw51uz7tKJ-EQ( ztd38P{d_oYD2GE4a_-`nhr+L-kPuW%0QBk6+BlGMVuPt@qnRtys^9SiR@E*|B~R_X zz7HK450zcdMb5Wf+%;r7c~A$NsOJN|eq4IvAE-H~@hV47@O-IMdcWcuYk6$}-_B?l z&KG=IzuiYtuRYckOQRC~4yN4`c^^n8OxNdnT(*yJ_c%2Zj?d?Vn>zP-G9DX1&vti6 zYv&pOz{v}xi}Q=qzOY(g(k*7!n*wbV5iX{AOc?Jv>oTfRbZ7P`m)NJ>yj=fq8eha% z(-lbF7;A4)Na9<2ql#k^@c=(gm3X(aLmF!J3LXu&=Fcg?z$O?*YkEE%If;goU2xWY zILOA=LTb7R7!a(A>bng%%fx$aWyTntjwM9+rvi?K&*nG_Y3N{#Bq9!7*7g#R{ZVOa zia;ZT0ReyRg|omlx{m_Bb6%P+&1O_8g@t3$SjTu^#Qo1r zz|5@#V=6vU2clret#P+vEzL0m_;J}ObGarlpzsVOE%6?WDuk7KDVAG@_p^G zEl`=yR~F14Rg>xgf>dup_n@amA=Z9CVt04h*C>wFM0#QK9JfIsd;eF1X z(gRHYBQ7)3Pv@{iLlWvvJez&4Pe&)f+==|+L%#aC#(wl%Ak0j{Sr_UH8eY#(Hm=jh1Q(l{LwolDOmV&~^#`crLr3S@hI} zpg|wErXC9@Xh*#bN?OdS7TqgpT3~n3^&g+1McMQ;`TP8GryMV7oq_I9^WR+JrKB0o+X8R5Z1M7iJAQ}e5Ko&Wxd$UJQBo|+ z#e1aU(!1ca(N!mCc#DR__&rRMA_7hHihZu5<*de@OWFpD>M&R+AQrU}QgSUrY?fB* zxZ@*WoFH6{up7YfsO9W<1UKP>?1q%2@t$`><1s2!MIXXKc6UR||4Q994Q(8!hw(cK zGrakw?4I{#xCULZ+ufHhwEa5beO0lXZ11Rb$csfe@JGAumvJJcdwz%JS8rO}ZCK#E zQRRW?=QCW~VUQ_&dQ3)ymNXLe;>f8`ylV;;LB#Z*z+Py_B@cO&_HTa=s>%ZM{_`%K zv$Q{g?367eR*-UmpVWof*1xEYwyAp1$Z)-T0&nl5}!W-P68Vopjx%!H~x&nNA(v44=>#Rq64E6ngj41ojWT`MgQP zv=*iDmfOd0JL>~|P&~%V<80-Z(#0!SoR%Vu`Aop|saFL_!uK22y6U9Yy9c^vdp}p~ zEJ%9JEpg8QZ}W~M%g4U{FEjBTclo~m5~tfkTYRYV3BQxfX0h{byzkvfv9*yEW#2y6 z=C-J2>66~^2=oO!_HwwzSuyU={q4S|K5v@3kjb2%!c??3|K88*Re*xN6 zVnb?UF?7r8zv}HE5IbUbXm>V)wjqZwoaR> z3B!i2HAIX%A##{n44v{pPwJy^m(wgdMZ_t zzFQQkK;+5xbn`96WTyi0*-DIjJZ24&iAgUiclz|jv0?KGrAzRyE(7>W&W_gd@#GUB z-(xb8wAtoTyOzPtqFxEjAP(vyEP{L)RDNGoU zQZ3S@?ZGAXLWh)DzD8-87T}L%cO-o-3edRsnjehaRLKCS(5CT75|ETIpqX#`R6q?k zBeXFn{W8_5F`B^8NnO!IVg94p{j892u_eDw*`nSwF!wa5h!3403Q+)fjHjn**`Su1 z^t?qRP~Xh8GhqdnkJ-zuyJ5Z82V~>okM@s*_djD}<1-YJQpNdovb*|{J*HQHfJX?4 z(8z94;?E9BGg~Zb7e!}htc7=};8?S5*&=>!5UIocp0HQ*_SwJ9#O2hn>MT6yp5Y+A zbV>i1W#m1c>R8(4SU#cAmDQuiDmKK$t$j9_s~;UjNe^tO>{ZOY z9ZPE^eK#x~T{ppPn#ahm>~tG#Ew4q!hkKTq7FJdHt}=fVl|XZNYjF(ulF*iTv6@^w za5DIc-ABj3QvTT?NI)!kwnmmF|RV&0@r=+UBg) zfEkwc>mKwXVF;(-2H8?LQ_3Fh^+X0$s)JJmHitBDr|5 z9h-m2*HHEP{GMows^r?(hGhkHnE8~Qqvy_09ByldBOB1@HBjNq7^bg(2p-kkNFKQz zJQYOd4rA8oVIL(g*7oZ3*|Kn`BHCw%2aSt&1EiA|)ueXstuo&b7cN51=9!2r#+52` zThI5w7FEPTD~6m$*Sd)1@a9O9YJ|A>LinC_=^_q=E@9kjskPdXa)bP|MGU46hI4o8=KDFb998`{*y)`SjUU$LkNd(J|;QnC@;!>x>w@t*D9z>R!~Bf@Cca8=s!i2Lk2U9j~g$;Ied8h!h4;55=hPu$^- zjs!nKwyUm3v-vF9M-x}L*!00HTmAW$_NqD`W&B*#5zpNMylGnyfB3Q#FTMMIb_6FZ z7j?xn4Y|-OAd`>y$k?oRJ#SRC^b`7F7MosY%@r@3%gC77-qeB;@q>4Vd%3y1jlpvN z%DRLkLso#FX8LmZvBbj0$>hyCr(UNV@1%uL==EicBwB4TIC-tgw_|H20v33u0I(Sb z+}Z_P#v!^2eMZRfaonsRRn>s*jaWNlEU2<#*m7kgnhMlpt!&U(^Lo<|Ht{B0w_}VY zh^-u$A3n4gng#$m>jB~rPxPQe;I7L6)(kEaCb`*+CC0FQla7W1o}zuaw=AU`Zv7l| z>o&5-b^wp{-w*AUztSIP^~;t-yE53}PMzEt_WNa7MF*{0mTxm~u`)a?uMVNAr}vtN zmVat!;_&jRPgaW-xooKL)PP(0`jp4UC0T+Yz@w1ud62#KL$Rk+X0P#ku*G$?8uweo zI~j_UH`seVL%nPIaN}BZ&KfV92)v;%WLH^yYU@uC+|Y0&;BgBL?sku=9%c!T0pW`- z(`vFij634qTd&;o!A~qpjfVH%aT6+Ao&cu%+w6_wi#|5^XK*Z zzx6IH(+QScFDWh*3t1Wo68c>G9Wm{>6=l)Dp*%U!+?kUsETHePHYfsB12hcbcVJKB zXj8^DpL5ACe9&bwG})WyzA`g0n#aR4E@uTW$WG?GwKEoVnd^3({04=6Ca<5w%Wmhb zZ32?;mV9gafg6NvFkmki0Z?3=-MSnwOE$)f$``iScx_Rqfa`%{iH`N-E?X;}BgM-9IA;K?V74mtu_daIt6X^q#z zQNXv3%Xwjg!B^27?Jnt;^6u$JvaHV97p!%4OD>zRy?p<_t;*jOF>7JdN4 z?-C}eFmB=Aq#nuB4H-^Aqqfsgb7ghCVhxWt&UO1Fm-j{-*0$$r+@$^Wz6^^+M?|RS zSmL4VQnnRd{>cxL-FFAQ)kILB9fO<2P-S}-*-tzX^;}Ag9GCM}riN|EVFd)aJuDXW%2>V@%$P%VGzfIca{wVe-Va zed5erWG=7w28_N#z69@i%o|sQAz%!Dt!fE9LVw~U<(`NSx!v}^f}3cHwF%@{5(0`B z;z`)MJ&%qzR4RyL##Krc}=99nZHvC``42=kS?N+ojJw*hOc^I`^hR7Vo1!jbvXHLnw^=h_+s zi5UKpMawkuHy<+Aw(g{ShKKC@Hyk)@kW(2dgV8HIGga!~X#Bz87(HG|7?m5u>vz_Vzlx*RRU zZ_h7O3PiX`He5}_yuE4Yp&7gI#%NJGme1`N*h9wRf$0PHsNGC7jNP~MYEz_!9!aPD z)IL1^1!ymMVIQI0hH%>2QjCMV{AbV;vqKjb7ehTeVS|i<88BVYDAA-j+rya*Wy*SB z*6I2$aVj8?_kK@#Iq1uB-vrgMuOW!$ewOxVUn2;Rf zYjE}Onb$L767A&>Mk0+>y?2*8OP3MYL$O(&=^((xuGTU_(S@2Z zWwPUCK!-;EsQz8%!jpI1FZl!&)WbyIp34~ z!V&P!w8ng}LWj*5s&)N9lKj^rLVJrstFZr)B1@YT4gsRs(OR|VG5`jMbM~V7H*{^^r)|6|fu+qG_v0+Bb3h+M?9P;!@IQsdd{TGoQ2EM{OhO#aM zqW-p_^pSWv>gZz6g1!f3;!X}{mn-}sg6iEr5;FV+69NYd`m2R*LK2OvnuJ&m&|(B# z62lKX!SigD^JbsR$fBFymI-*mN1cU4A|^D0K*AD!j_n8fr3Y_rHGRQh)XX$C5xRLc zp=GAdG`d64%+;BoTa_h|DERy-PoYOr$U>vR6X5rx8R`84%R`-kx8WG4*|Y zrg=JL$D#Uv=m~VeolSqlGH6f={iyp_drV&NyK4!2xfVw`m@fb5&HzQIPX7 z8%vbvWqbAH(~Yjp!M@GB*@3k*ArDqW+4R%L+4TB!=+8$QrHA)=%6@g-6UcaTlC4wC z&mizX$wqlvm_d%+?b(T4n<85(o33I%6-Uw>ksz4MA`_2TSsuel7rVY$o9+Dq6|*tk z3Q8gH_ZeQ}lNe9N@!;SdA}`YvDy}szuuBU?3wHQAdLt%!gDZK7RdfHg5y%KUK*!9V z3j}*LcVCs&)`W1xe>+d2aQVg%&Jiu)}DhBl6mGP-i>SJQ8ofVo=jKZ`>#qOA@0c6sB1(){MZT4iKxk| zSv~HPAIv1@T4a-vky*rprdDE|qqo zzK=Vfet*5g)<-L#DZ9$e6t`)#!?5oyvMF$J&j9r%7U%7t-ASy7Lqy7i^}W7GOnl4$ zb2Rg9I`$c-pDr?OJ(6JR%ZD{xjI}G6wW?0B2(ft}Pp38>I-R;cL!`6qU!yymd$Dcbv0n^6XcX&9Ijz}~fW3?rCjWb(n~ADCWf5m5RI%!4fKu67 z#SH+bwB90E=Wd+LK*iRKjpyzr%Un50_Brv!_s2VP?~_Ac5`^ji*qxcPyTHaM4}bAi zS=XwwQU|%0nb9}2=abpJrY69_tlL13ed5t8J+`$q@95M>h4N%T*rFq$j5<5hO|yBS zlYNr}{#-KyQVM;qc;O&QyfC%DSfaw~hJzp7zKM+-udXMRsspEc@?a6vI$R+}#_6)} zU_+Fldo;Ug!H69RUz>A+V^%)cD6Un^;v`&eX4-XEys;~U-X@}vt96cW!@NW|fmF5YU?0ZiBZNJ#(4=}pCmc_=Kyc6yx%6&*7eiOrdKd>`nk3^Px@l;KyiDn+TVI%>^cv0`u@4 z!Vut~14cpv-tvCbayl><74Nd{(V@@=x>6MN8zKuOp~Z6Kt<6az+hqiy2e>lXaOl7U zvJ@bFR-0w+D@k^gHn~lIaUQyOgcest%a=0nu98Jkbkt^KoQY@6&{sPg$66#C zqJuO1YdWHsij)@=hD7bdZ{^%IE6NMrwfBo9xs5Y4h%drMnsRKZknkG-O2|ikp5D`}@ zf5cGg8;+?erts!|Jc~4hnZ4-)EILf*X2~&X$Ihymkf&@4#5<~Zwe`~ylBuW&)U(8F zjG-^_i6S9PTi(DD(A zBLg{oJ_(XZOs(6)w-G?L&)wHpbTn^iv^EmvN*Zv*nubWU0Y0#yeZ}4~SX%pDC*G!j zw;TFP7De{6Jp>v~6ACLrO6Y_7V^`4N01mcq(sBj(XECKA9G+iWFBe_RrA^I>!`K_A zMzDL@X){Xm1b7l}kD(y16bh4PX~iBDJZNX5t4>l-E00<%tDX3SRygK}IMG*R@!<2L z^Ww2q>bc=;#@;PeSHeU%i5T(5{3s?i-S9s0X}iANgwd}AnBmht~-?>wWL z+PZ$PARr(`X=Ho*x{nV3st?tzkg|Y)nFY#Cl2I8W zL*s#c@oSul9(^I)LzS*tD*Hh7{dk&B-k6(1YKXZ1q3B%Knw7Y!`Qfe6?TBwIFAvr| zhWI_|5k~3V{`k8aV%sbgTlponA!v?gf3`5i1I6zRSp_p;oWeHZsD8aFu-ooA1~q&9 zvQYjVjMz@_nZ}4AzjZIpp5%-Nc^I(BdD{Au6(*aW+CE>O4@3R2I#|2B%I%8sM|8ji zpt{FoJGX!9(EW*>2q2e+jo<~%MNhTHDAb@m!f&oJ@um_LKv8BTRy9=BkU)c*uVV3= zA_on5QBpRl;NcX&nm7~HX;CwyK#Zx%opX!X1Mg^TY}>rkE?+B#SxmXWhp{cD&(Q(v zwo-9g{<5TnM2wt9z$qz(t+McsHPN5|VrA|r0DE%*3l;}Ry~fqj5NN%*g<&|!8MiiY zisLXw=p@-iJP#6Hd*k1@x8~C<-Sr4`iVfNf*u1q=^cV#H($60b>Ao)uz$48fUa*sK zUxQmmG&DTzd#9~xsQxA*7o>MYO~Scb8#eOx>LXXHYg~~9PuN-8nDxz|%>{S4$4Su$ zFN_ZQ`Qob8T)o)Js)a|8w|1eHYoLZFiXCtH4 zZ-&IFp=IUESvm(P6B(U6iKHdmT6TLQW`1m&^yv(n_M}m0Gh5r;k!>G~zcD+_kD(8)6*^B}+!xVI2Z5BKJ$cG%Kg2haAfXW28!?<00#@^NzrN74(FBx-FNebo(2Mmz4xYV)td7?Y zS`=W<-|I178GPd(!wUnH zpm7cSYmE)N*e5s~{BeTeLMWze>T&s55D7Y?0G_DV)C@Z{4lwggT+#ldbzgJvr%Loa zGQZ;2DrH=BjG(zQ=j}euJSx%uV_vQh2Lp{gB2yiHX$W<~HSMQ4ztM)!)yBAa6H(4f zi27tXolsOOR!Yr%M$m3FKtwc}z#`V}z@2&vU6S47r~}iR=Qi%WajkYvqPXiSp>e7cD8QU?eLny*I1_>$XC0SD|syuYv%FB{iO!a=R*Rbhp zSrT_23vmcXGNRP)Z7x-AeTA#Mh?RAkscRhuyH%a6v-5l~!K73h4m6@tMKPOJLel#_ zyV7O{W$t^+U78#DnX5FjmjhZm%H1GsE!l*q~6#@|=GzBNw|?QPRn8+HFI zpO?M?>LbC09PNDP7GP2R$BA*?AO7jh>H;4B9 z?9g{6+zkOwjI`0^WU2*^f{cQ;U{x{Q1)YuRYIlEkVARt!qoYAQFr8F zqj?^^J!mB8C(!g8=lhD8%}9`^9SQ&0@HH+yPlyy?N!GELoL70VG->PGte@~w;}B#l zZZ1E!b}#ELBln)A;1yDR>v-0k$d;I?C~PbiP5QIyGt9j#?8(p=+e;;T;(H7Ambtex zcM`)$a;^H=t4i^^GE<1VsVV|G-IU6fO0k25#Hr;kFQ=|B`+Z~uV0#D(mIawjsGh{S zDd;h8T*26v-184e=# z@*3S-YR?5WGj*m+6{_(LR#wRlRR3@Q@dWf?W4Eu|qaCq_yIdZ2Y)$9W^SF;5H@VX{ zz6&m4$ce+_A^ z^O3X!w1d|7gM#k?yP&=l-@U|)-Mt*(c z^7o#roT$6K$}wg%d6`c}oO%1DKmUCK@nOO>^v?7NsHh%v;O>ySldp=(do4Kbbl^w( zwW}EAV&;?C4BZF1Gud&!qxrvMa%Or!9=M~o1{#3u>zTVMIMHGsyZUgNNujk$A~ zAA3C36>?&ANut3|d6GCB9g!^PV{+r$+2wD>r^Wm1HI6t~AcVglHe%uf4k6*zVBN%a z!R1IA#*M-gEq_?Qf`l9Vh=0}^LoahuCDrwseam?K(t80a4U>de6fft>2Kaq0N<8$X zWLe!_Q_R#&48gnprdM~5w|QMkV)$mE)~>6NL6Sg!Nhd!)$XwH^_fML(SL%lmfLa1~ zTU`@ol%_ZzL~FR5j!%6YEK}X7zsxe@6nQvvniUUQd4DbuxEUx1R3v0?qW`H#oY}h{ z&tUaY7vHToZ*N>L2wK9#iG0m8qUuuSv-)rV8%K(`-uY#c_9SBHj8B%Y0kh7u;pAH~ zAX5mOCs)|1sVW|v!-j)6l#{NPq3ml9xdNPCSN4PqEFHF<=52#Vj)j3;0mBuJdC+0& zYS_;wABwV2qa*KN^4N=>$(Cwc4c2@ZE2Mgb7&KKe*#V2$9D84z6fKcN7yLn7^QB49 z(s!hSetrxN7^UY?D|8LKVe$)tUu%L8CXdvUm4*&^8ANWrU-nF|6nT#nSz<4#=!z zY!>iMQ4Y!%Lu~0p_K7ZJbardg0FT|ljI02zG)%7MPX8lrM}jI**K4=5VA{8uH{u;9 zL{0tGF@~>M_ zeTnnD&p@&Q$}AmwqY>c5;Ck_mI6 znOC|v+}O#7aiHxCgN9nE3fPNK9NNHguy@}C5d(3gjUnyz(ZGbp@3nhN*Bl7@n$9ea z_~R}Et2adT+wbFp;L&CnAlcF8n zBK$?bu(o)ijjxnVb*bgkuEt_Uo_!Cl&*2K_lGkhm?upE{32nW30+>qiM2fZtAMtot z_#C09V4SeIZws*oaw?&N^HX=u@~#R4w=>P|WNoM+G%HxJJ=)1PF!{hC&0U^C_WAQYR2C=HY_Ko9F9i)4CSpn!^Q#oRb*Vl z$wl;(M{1|B4Gl-Gf!3CVcn52({y@akgH?H1Ayv7SdI;zJdcHdzM7xw&0)jJmEyUDp5k3_{-Hp4o)Xyu3MYath2D0E1Vk6q zD|$TgLDDTia8uKT*!n(EWEvx0GnC>+20XI@tZHw2S!q@$=>(09vJED(XZKehfRs!P zAgHNv215W1`{^uyH+ zD!Zo_3IaUlCAZ>0<!rE8)Cs`#pzB}q?z1Z| z0^cwW0^U|svnoGre7`5%2t0Pgc+eoI(e4|0sZCnSTt2L=2pHB5olH2Oz*bmD95Ew3Z-Sv{E2HKsUIva(FNck-!Z}=nwTlvX zb?qTyd*dc8Ue?Fc5oUOpRH}Xmq?Tc(XL2aPI+Elsxj~oZ!<2r!pOJY#lC`172_UsG zGb-jHuQ!{=DG$LYmE)!D7YD4w+s17xLrTWG(SBuTpx!cZr;u%7HzSTj$V4PJo445j zvE%>tb#ir@2t`m2D?HdLJ}flSDkKk?J7BUnVT$0&I0O3ZhJknl+r{U?!22iT)2{wv zv4xt%)$1ezJxhkYG7iW!ip2D_-*}`0Jje&%EsDsXp!j%p*p$q6O&6GY`i=Ou9Ui`P zG}UZ|`p#F1*eSL?hW9f4m5Q04c6)LGLuW>zth`E>Ipb)m2g@XR3d$(G7}u##2_(RM z3$juzJY@v;B#WKKz3{1?>QqQUBfRY|XOwh!Yd8MU^a-jEXP4~Pa?i-t+v~OR2#GHDFs=k33 z&#=4tn3ZfJ)Or%Z6?`1NM+IA}2k_gs_d0JEj6N)Okc}$7d1WP0P?t1yWPHq+fdt5<7jZ=0;yL!Ff&4y7Al9 zn`F?+d=sbhyc3@qAI1#XnR^2GC2Rd#9wDHqg<5q(Z2on;W9H24s(oNB6!}+kj8u=& z_T!AO?uScdcAV$$bcP{D>%3L%o{@)`6-r$tNXhRLZ zTHMEiQ}qs~l{P*RS;dPr%?9Sr-+^EaCtQm>#+l5`)|ra~-}Xb^eO{`$R6gaH(lh5v+7&iEe;CvuDG#o? zn(;S!9K3I|2W&8%_0i7R!eqe^iOZv%+1OX}wqI#@duA-D2o-$Qz#^cy{|cHg0H9!aINXC zVqJdfED&^lj}RN@yL%3+&HYMh@r%-z zWExV|nfT(Hi8bR707r;?3n`#ov4@!%!cylHwv33EIlKgV2ZjN)xrf8?MrL`rXaTRH z?+JTD5ltqtx}tlGIic?3FAuZu0Qy&($NTWgh60#r913%u7%CrU*R-xP+`go!GXd^u z6#y62#-W2fk*<)B&ktM%Iv9M-{Q~oy%$uwcLC-;x?RVBksvG8d2|0mN3Tf#l-OD6z zJPIMNNemw+3e7R)#0RlXXM%`}=96x|T5}4l>ZOBH7CC8_rFU~OgQ0nYW|n3fp+57Q z#f}3{Yab^S2iz^#j@Qet!2WPG=H_aI_ta}m#R`jBtH%(^`nBlmvu1cF1~GqH&Z1q-d#ZFc^!`o*zN*wCgF*85}jb<#ZNHf*QfOKvBdSA5?9spEuF8%~g zJU^}9+})Eq`Br9#-~uQ-&Ik|+AIM;~92Soyh_7qh4bKAw5h$#>6^-rcwju&(EW9J5 zZ_^zxm|8A!a?&K?Vv=Rx-VVt28^T1LW2xK)P+(mIG;B!5PI6{uFXZ80UyZfJ%HGu) z>8ey7)^!`SJTbI)@XyJ2G1C`XUwPmjdH;+!dN&qiV!|ys^)eo$(=nKM`dM3*w&H6kBu1pxj*$xDocN0`^G>*)x@g?a)q2qnZIyLy zkP;1%^ot6^H?akJP2F2m3SdzClm#xfR9)K z!2|f`QKI!5(GB6-1;CgbL3c@)HdfJD1%^}{RG(^RF7Nv*Y2P{ZhD)BbsS6vGM{W%m zRwMM6J@^BQG7wLN%t`z05Bhhenk$5T)u?|r4+z&|-oz)D{@mGL-7}LJR@$aob*roL zC34&w8P{+;+&jnVDy9SnC6HSpVv1mbjg>jF@j0F1B~3ZU-&EoPMabY3<0$RFqGr$`~#t}N7>+S8aVfo7rUxNa@Y|1IJ#mo&_N@*mIY8 zSHkSq-j=pJEYS~JT5&-i;*8PIZF5{rRTWZK%-fqrNe>YepO;PDXsQpTgd1o=(hTo> zV1-?-r$d9}sOl>-_tOa09)36($WXDb>7yMx`F8D=Br8S4Bq(%Uv*rPYV=j94HrQBJ zV>+0ak%2)HzDgwp?F!x8n54WUL`K%8t`9eH^{bmTiS3r#3GtaoQn?31TtZ^wu&SJ5 zsz&*>$C$jlJc?ag|MX&e91M*HG#}s}LH?0xj^fR`#1|BwughP|W3^U&F3?m!yP(+{ z1D=YFRXQQQ4~6SH`x?wlf|v=n49wy;;`CNJzRCugprPC+ZNU9Qr_wwhruJ_My)yPZ zxE+#omp6h5_h?^fZ5^J!Idn6XTy9eceQ3e9HNH91#pFSJ&XhV^qge?;-OaD)j+1(d zXiELcmsb{?Map+?&26!ydWW`{nJsY)7a7q=pV3%fn6vdvW>hyA%wI7H>S-RG*i`X( zjrtIIWCWTuyozsIQUF2k{x%7JNAI{UBr)V<=F zEYSjr@j1IoV|TvkPR1Hvor%Ut;O(Nw{N?izjz{0#`sdwGR3~;mC`Mjsc9Xso!#C_7 ziwxTzX4%vA?lDj-E;Ihu`uw_aMEfqo9bkm%eV<;wIolSL{OT&ie`esGwvk?hqbnrr z*E;?^fH>g?J7DuqX1lWm`g0zw>Cetp40jjJ+(O;q!@R?<|9;=DgHnq-Mghud#yQbn z!-V$^cw;kcdb(C8b~*WatqK3%@ z)W08mx8!Z>7XCZl;0s7W^%vp-Wu$X93DpQ=Bk(|^6r><}==k3g1Prt{?UB$#JM1ZI zkE@cr2&6nRQ^B7Zih>mi0pYtS#^&D}Q|WB>shtunaWqNVfp=&1rSaE_2vVlLPTYP_U(xKDxQtvC{$VX%3S?xg}46~Ci3Tx^jEC%fp+}@ zgI$6ui_YFwm*B9Qw5QJ=z|94o^Z3qA9!IR zrc+PADRwlF^n3jz$yyOv3YQ6*>lse*f-rKN&fDbONq9OV+-E2QS?jdC(uq=rmp2;(0;t4E>DjZ#=fk(iUDTQPSVB!$X%` zdCls<(K^)Y-fhl;m969XQg~NaR6~nuPU*4Vclgi6*=j)H{N{@3Kb!X7yD}mQkeL6^ zU;O?+{o2_7Ggto{S%05#|BrUbRaM5B9Xod3u()u};qM{+f44R*xBq;7#XRqVug*WG z`|o4o1.12.300 2.21.0 1.0.0-beta.19 + 3.13.10 2.18.0 2.8.0 6.0.0 @@ -865,6 +866,12 @@ casdoor-spring-boot-starter ${casdoor.version} + + + net.snowflake + snowflake-jdbc + ${snowflake-jdbc.version} + diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/DataSourceConstants.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/DataSourceConstants.java index 3812759e3d..25ea5bea48 100644 --- a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/DataSourceConstants.java +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/DataSourceConstants.java @@ -40,7 +40,7 @@ public class DataSourceConstants { public static final String COM_DAMENG_JDBC_DRIVER = "dm.jdbc.driver.DmDriver"; public static final String ORG_APACHE_KYUUBI_JDBC_DRIVER = "org.apache.kyuubi.jdbc.KyuubiHiveDriver"; public static final String COM_OCEANBASE_JDBC_DRIVER = "com.oceanbase.jdbc.Driver"; - + public static final String NET_SNOWFLAKE_JDBC_DRIVER = "net.snowflake.client.jdbc.SnowflakeDriver"; /** * validation Query */ @@ -57,6 +57,7 @@ public class DataSourceConstants { public static final String ATHENA_VALIDATION_QUERY = "select 1"; public static final String TRINO_VALIDATION_QUERY = "select 1"; public static final String DAMENG_VALIDATION_QUERY = "select 1"; + public static final String SNOWFLAKE_VALIDATION_QUERY = "select 1"; public static final String KYUUBI_VALIDATION_QUERY = "select 1"; @@ -80,6 +81,7 @@ public class DataSourceConstants { public static final String JDBC_TRINO = "jdbc:trino://"; public static final String JDBC_DAMENG = "jdbc:dm://"; public static final String JDBC_OCEANBASE = "jdbc:oceanbase://"; + public static final String JDBC_SNOWFLAKE = "jdbc:snowflake://"; /** * database type diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-all/pom.xml b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-all/pom.xml index 21eacfe9f4..e84fab766f 100644 --- a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-all/pom.xml +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-all/pom.xml @@ -112,6 +112,11 @@ dolphinscheduler-datasource-dameng ${project.version} + + org.apache.dolphinscheduler + dolphinscheduler-datasource-snowflake + ${project.version} + org.apache.dolphinscheduler dolphinscheduler-datasource-ssh diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/pom.xml b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/pom.xml new file mode 100644 index 0000000000..26cb50c884 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/pom.xml @@ -0,0 +1,50 @@ + + + + 4.0.0 + + org.apache.dolphinscheduler + dolphinscheduler-datasource-plugin + dev-SNAPSHOT + + + dolphinscheduler-datasource-snowflake + jar + ${project.artifactId} + + + + + org.apache.dolphinscheduler + dolphinscheduler-spi + provided + + + + org.apache.dolphinscheduler + dolphinscheduler-datasource-api + ${project.version} + + + + net.snowflake + snowflake-jdbc + + + diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannel.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannel.java new file mode 100644 index 0000000000..da21967f4b --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannel.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake; + +import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam; +import org.apache.dolphinscheduler.spi.datasource.DataSourceChannel; +import org.apache.dolphinscheduler.spi.datasource.DataSourceClient; +import org.apache.dolphinscheduler.spi.enums.DbType; + +public class SnowflakeDataSourceChannel implements DataSourceChannel { + + @Override + public DataSourceClient createDataSourceClient(BaseConnectionParam baseConnectionParam, DbType dbType) { + return new SnowflakeDataSourceClient(baseConnectionParam, dbType); + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelFactory.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelFactory.java new file mode 100644 index 0000000000..0d0c97ecd6 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelFactory.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake; + +import org.apache.dolphinscheduler.spi.datasource.DataSourceChannel; +import org.apache.dolphinscheduler.spi.datasource.DataSourceChannelFactory; + +import com.google.auto.service.AutoService; + +@AutoService(DataSourceChannelFactory.class) +public class SnowflakeDataSourceChannelFactory implements DataSourceChannelFactory { + + @Override + public String getName() { + return "snowflake"; + } + + @Override + public DataSourceChannel create() { + return new SnowflakeDataSourceChannel(); + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceClient.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceClient.java new file mode 100644 index 0000000000..2649cc0c4d --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceClient.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake; + +import org.apache.dolphinscheduler.plugin.datasource.api.client.CommonDataSourceClient; +import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam; +import org.apache.dolphinscheduler.spi.enums.DbType; + +public class SnowflakeDataSourceClient extends CommonDataSourceClient { + + public SnowflakeDataSourceClient(BaseConnectionParam baseConnectionParam, DbType dbType) { + super(baseConnectionParam, dbType); + } + +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeConnectionParam.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeConnectionParam.java new file mode 100644 index 0000000000..9a7ac81ac1 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeConnectionParam.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake.param; + +import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam; + +public class SnowflakeConnectionParam extends BaseConnectionParam { + + @Override + public String toString() { + return "SnowFlakeConnectionParam{" + + "user='" + user + '\'' + + ", password='" + password + '\'' + + ", address='" + address + '\'' + + ", database='" + database + '\'' + + ", jdbcUrl='" + jdbcUrl + '\'' + + ", driverLocation='" + driverLocation + '\'' + + ", driverClassName='" + driverClassName + '\'' + + ", validationQuery='" + validationQuery + '\'' + + ", other='" + other + '\'' + + '}'; + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDatasourceParamDTO.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDatasourceParamDTO.java new file mode 100644 index 0000000000..27a72a45cd --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDatasourceParamDTO.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake.param; + +import org.apache.dolphinscheduler.plugin.datasource.api.datasource.BaseDataSourceParamDTO; +import org.apache.dolphinscheduler.spi.enums.DbType; + +public class SnowflakeDatasourceParamDTO extends BaseDataSourceParamDTO { + + @Override + public String toString() { + return "SnowFlakeDatasourceParamDTO{" + + "name='" + name + '\'' + + ", note='" + note + '\'' + + ", host='" + host + '\'' + + ", port=" + port + + ", database='" + database + '\'' + + ", userName='" + userName + '\'' + + ", password='" + password + '\'' + + ", other='" + other + '\'' + + '}'; + } + + @Override + public DbType getType() { + return DbType.SNOWFLAKE; + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDatasourceProcessor.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDatasourceProcessor.java new file mode 100644 index 0000000000..02229ed6b3 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/main/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDatasourceProcessor.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake.param; + +import org.apache.dolphinscheduler.common.constants.Constants; +import org.apache.dolphinscheduler.common.constants.DataSourceConstants; +import org.apache.dolphinscheduler.common.utils.JSONUtils; +import org.apache.dolphinscheduler.plugin.datasource.api.datasource.AbstractDataSourceProcessor; +import org.apache.dolphinscheduler.plugin.datasource.api.datasource.BaseDataSourceParamDTO; +import org.apache.dolphinscheduler.plugin.datasource.api.datasource.DataSourceProcessor; +import org.apache.dolphinscheduler.plugin.datasource.api.utils.PasswordUtils; +import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam; +import org.apache.dolphinscheduler.spi.datasource.ConnectionParam; +import org.apache.dolphinscheduler.spi.enums.DbType; + +import org.apache.commons.collections4.MapUtils; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +import lombok.extern.slf4j.Slf4j; + +import com.google.auto.service.AutoService; +@AutoService(DataSourceProcessor.class) +@Slf4j +public class SnowflakeDatasourceProcessor extends AbstractDataSourceProcessor { + + @Override + public BaseDataSourceParamDTO castDatasourceParamDTO(String paramJson) { + return JSONUtils.parseObject(paramJson, SnowflakeDatasourceParamDTO.class); + } + + @Override + public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { + SnowflakeConnectionParam snowFlakeConnectionParam = + (SnowflakeConnectionParam) createConnectionParams(connectionJson); + String[] tmpArray = snowFlakeConnectionParam.getAddress().split(Constants.DOUBLE_SLASH); + StringBuilder hosts = new StringBuilder(); + String[] hostPortArray = tmpArray[tmpArray.length - 1].split(Constants.COMMA); + for (String hostPort : hostPortArray) { + hosts.append(hostPort.split(Constants.COLON)[0]).append(Constants.COMMA); + } + hosts.deleteCharAt(hosts.length() - 1); + SnowflakeDatasourceParamDTO snowflakeDatasourceParamDTO = new SnowflakeDatasourceParamDTO(); + snowflakeDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(Constants.COLON)[1])); + snowflakeDatasourceParamDTO.setHost(hosts.toString()); + snowflakeDatasourceParamDTO.setDatabase(snowFlakeConnectionParam.getDatabase()); + snowflakeDatasourceParamDTO.setUserName(snowFlakeConnectionParam.getUser()); + snowflakeDatasourceParamDTO.setOther(snowFlakeConnectionParam.getOther()); + + return snowflakeDatasourceParamDTO; + } + + @Override + public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) { + SnowflakeDatasourceParamDTO snowflakeParam = (SnowflakeDatasourceParamDTO) datasourceParam; + StringBuilder address = new StringBuilder(); + address.append(DataSourceConstants.JDBC_SNOWFLAKE); + for (String zkHost : datasourceParam.getHost().split(",")) { + address.append(String.format("%s:%s,", zkHost, datasourceParam.getPort())); + } + address.deleteCharAt(address.length() - 1); + String jdbcUrl = address.toString() + "/" + datasourceParam.getDatabase(); + SnowflakeConnectionParam snowFlakeConnectionParam = new SnowflakeConnectionParam(); + snowFlakeConnectionParam.setUser(snowflakeParam.getUserName()); + snowFlakeConnectionParam.setPassword(PasswordUtils.encodePassword(snowflakeParam.getPassword())); + snowFlakeConnectionParam.setOther(snowflakeParam.getOther()); + snowFlakeConnectionParam.setAddress(address.toString()); + snowFlakeConnectionParam.setJdbcUrl(jdbcUrl); + snowFlakeConnectionParam.setDriverClassName(getDatasourceDriver()); + snowFlakeConnectionParam.setValidationQuery(getValidationQuery()); + return snowFlakeConnectionParam; + } + + @Override + public ConnectionParam createConnectionParams(String connectionJson) { + return JSONUtils.parseObject(connectionJson, SnowflakeConnectionParam.class); + } + + @Override + public String getDatasourceDriver() { + return DataSourceConstants.NET_SNOWFLAKE_JDBC_DRIVER; + } + + @Override + public String getValidationQuery() { + return DataSourceConstants.SNOWFLAKE_VALIDATION_QUERY; + } + + @Override + public String getJdbcUrl(ConnectionParam connectionParam) { + SnowflakeConnectionParam snowFlakeConnectionParam = (SnowflakeConnectionParam) connectionParam; + if (MapUtils.isNotEmpty(snowFlakeConnectionParam.getOther())) { + return String.format("%s?%s", snowFlakeConnectionParam.getJdbcUrl(), snowFlakeConnectionParam.getOther()); + } + return snowFlakeConnectionParam.getJdbcUrl(); + } + + @Override + public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException { + SnowflakeConnectionParam snowFlakeConnectionParam = (SnowflakeConnectionParam) connectionParam; + Class.forName(getDatasourceDriver()); + return DriverManager.getConnection(getJdbcUrl(connectionParam), + snowFlakeConnectionParam.getUser(), + PasswordUtils.decodePassword(snowFlakeConnectionParam.getPassword())); + } + @Override + public DataSourceProcessor create() { + return new SnowflakeDatasourceProcessor(); + } + @Override + public DbType getDbType() { + return DbType.SNOWFLAKE; + } + +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelFactoryTest.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelFactoryTest.java new file mode 100644 index 0000000000..1c0b6ff472 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelFactoryTest.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake; + +import org.apache.dolphinscheduler.spi.datasource.DataSourceChannel; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class SnowflakeDataSourceChannelFactoryTest { + + @Test + public void testCreate() { + SnowflakeDataSourceChannelFactory sourceChannelFactory = new SnowflakeDataSourceChannelFactory(); + DataSourceChannel dataSourceChannel = sourceChannelFactory.create(); + Assertions.assertNotNull(dataSourceChannel); + } + + @Test + public void testGetName() { + SnowflakeDataSourceChannelFactory sourceChannelFactory = new SnowflakeDataSourceChannelFactory(); + Assertions.assertEquals(sourceChannelFactory.getName(), "snowflake"); + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelTest.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelTest.java new file mode 100644 index 0000000000..42e5f056b2 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceChannelTest.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake; + +import org.apache.dolphinscheduler.plugin.datasource.snowflake.param.SnowflakeConnectionParam; +import org.apache.dolphinscheduler.spi.enums.DbType; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class SnowflakeDataSourceChannelTest { + + @Test + public void testCreateDataSourceClient() { + SnowflakeDataSourceChannel sourceChannel = Mockito.mock(SnowflakeDataSourceChannel.class); + SnowflakeDataSourceClient dataSourceClient = Mockito.mock(SnowflakeDataSourceClient.class); + Mockito.when(sourceChannel.createDataSourceClient(Mockito.any(), Mockito.any())).thenReturn(dataSourceClient); + Assertions + .assertNotNull(sourceChannel.createDataSourceClient(new SnowflakeConnectionParam(), DbType.SNOWFLAKE)); + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceClientTest.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceClientTest.java new file mode 100644 index 0000000000..b7da5385f9 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/SnowflakeDataSourceClientTest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake; + +import java.sql.Connection; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class SnowflakeDataSourceClientTest { + + @Mock + private SnowflakeDataSourceClient snowflakeDataSourceClient; + + @Test + public void testCheckClient() { + snowflakeDataSourceClient.checkClient(); + Mockito.verify(snowflakeDataSourceClient).checkClient(); + } + + @Test + public void testGetConnection() { + Connection connection = Mockito.mock(Connection.class); + Mockito.when(snowflakeDataSourceClient.getConnection()).thenReturn(connection); + Assertions.assertNotNull(snowflakeDataSourceClient.getConnection()); + + } + +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDataSourceProcessorTest.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDataSourceProcessorTest.java new file mode 100644 index 0000000000..501c556c59 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/param/SnowflakeDataSourceProcessorTest.java @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake.param; + +import org.apache.dolphinscheduler.common.constants.DataSourceConstants; +import org.apache.dolphinscheduler.common.utils.JSONUtils; +import org.apache.dolphinscheduler.plugin.datasource.api.utils.CommonUtils; +import org.apache.dolphinscheduler.plugin.datasource.api.utils.DataSourceUtils; +import org.apache.dolphinscheduler.plugin.datasource.api.utils.PasswordUtils; +import org.apache.dolphinscheduler.spi.datasource.ConnectionParam; +import org.apache.dolphinscheduler.spi.enums.DbType; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class SnowflakeDataSourceProcessorTest { + + private SnowflakeDatasourceProcessor snowflakeDataSourceProcessor = new SnowflakeDatasourceProcessor(); + + @Test + public void testCheckDatasourceParam() { + SnowflakeDatasourceParamDTO snowflakeDatasourceParamDTO = new SnowflakeDatasourceParamDTO(); + snowflakeDatasourceParamDTO.setHost("localhost"); + snowflakeDatasourceParamDTO.setDatabase("default"); + Map other = new HashMap<>(); + other.put("serverTimezone", "Asia/Shanghai"); + snowflakeDatasourceParamDTO.setOther(other); + DataSourceUtils.checkDatasourceParam(snowflakeDatasourceParamDTO); + Assertions.assertTrue(true); + } + + @Test + public void testBuildConnectionParams() { + SnowflakeDatasourceParamDTO snowflakeDatasourceParamDTO = new SnowflakeDatasourceParamDTO(); + snowflakeDatasourceParamDTO.setHost("localhost"); + snowflakeDatasourceParamDTO.setDatabase("default"); + snowflakeDatasourceParamDTO.setUserName("root"); + snowflakeDatasourceParamDTO.setPort(3306); + snowflakeDatasourceParamDTO.setPassword("123456"); + try ( + MockedStatic mockedStaticPasswordUtils = Mockito.mockStatic(PasswordUtils.class); + MockedStatic mockedStaticCommonUtils = Mockito.mockStatic(CommonUtils.class)) { + mockedStaticPasswordUtils.when(() -> PasswordUtils.encodePassword(Mockito.anyString())) + .thenReturn("123456"); + mockedStaticCommonUtils.when(CommonUtils::getKerberosStartupState).thenReturn(false); + ConnectionParam connectionParam = DataSourceUtils.buildConnectionParams(snowflakeDatasourceParamDTO); + Assertions.assertNotNull(connectionParam); + } + } + + @Test + public void testBuildConnectionParams2() { + SnowflakeDatasourceParamDTO snowflakeDatasourceParamDTO = new SnowflakeDatasourceParamDTO(); + snowflakeDatasourceParamDTO.setHost("localhost"); + snowflakeDatasourceParamDTO.setDatabase("default"); + snowflakeDatasourceParamDTO.setUserName("root"); + snowflakeDatasourceParamDTO.setPort(3306); + snowflakeDatasourceParamDTO.setPassword("123456"); + ConnectionParam connectionParam = + DataSourceUtils.buildConnectionParams(DbType.SNOWFLAKE, + JSONUtils.toJsonString(snowflakeDatasourceParamDTO)); + Assertions.assertNotNull(connectionParam); + } + + @Test + public void testCreateConnectionParams() { + Map props = new HashMap<>(); + props.put("serverTimezone", "utc"); + SnowflakeDatasourceParamDTO snowflakeDataSourceParamDTO = new SnowflakeDatasourceParamDTO(); + snowflakeDataSourceParamDTO.setHost("localhost1,localhost2"); + snowflakeDataSourceParamDTO.setPort(5142); + snowflakeDataSourceParamDTO.setUserName("default"); + snowflakeDataSourceParamDTO.setDatabase("default"); + snowflakeDataSourceParamDTO.setOther(props); + try ( + MockedStatic mockedStaticPasswordUtils = Mockito.mockStatic(PasswordUtils.class); + MockedStatic mockedStaticCommonUtils = Mockito.mockStatic(CommonUtils.class)) { + mockedStaticPasswordUtils.when(() -> PasswordUtils.encodePassword(Mockito.anyString())).thenReturn("test"); + SnowflakeConnectionParam connectionParams = (SnowflakeConnectionParam) snowflakeDataSourceProcessor + .createConnectionParams(snowflakeDataSourceParamDTO); + Assertions.assertNotNull(connectionParams); + Assertions.assertEquals("jdbc:snowflake://localhost1:5142,localhost2:5142", connectionParams.getAddress()); + } + } + + @Test + public void testCreateConnectionParams2() { + String connectionParam = + "{\"user\":\"default\",\"address\":\"jdbc:snowflake://localhost1:5142,localhost2:5142\"" + + ",\"jdbcUrl\":\"jdbc:snowflake://localhost1:5142,localhost2:5142/default\"}"; + SnowflakeConnectionParam connectionParams = (SnowflakeConnectionParam) snowflakeDataSourceProcessor + .createConnectionParams(connectionParam); + Assertions.assertNotNull(connectionParam); + Assertions.assertEquals("default", connectionParams.getUser()); + } + + @Test + public void testGetDatasourceDriver() { + Assertions.assertEquals(DataSourceConstants.NET_SNOWFLAKE_JDBC_DRIVER, + snowflakeDataSourceProcessor.getDatasourceDriver()); + } + + @Test + public void testGetJdbcUrl() { + SnowflakeConnectionParam connectionParam = new SnowflakeConnectionParam(); + connectionParam.setJdbcUrl("jdbc:snowflake://localhost1:5142,localhost2:5142/default"); + Assertions.assertEquals("jdbc:snowflake://localhost1:5142,localhost2:5142/default", + snowflakeDataSourceProcessor.getJdbcUrl(connectionParam)); + } + + @Test + public void testGetDbType() { + Assertions.assertEquals(DbType.SNOWFLAKE, snowflakeDataSourceProcessor.getDbType()); + } + + @Test + public void testGetValidationQuery() { + Assertions.assertEquals(DataSourceConstants.SNOWFLAKE_VALIDATION_QUERY, + snowflakeDataSourceProcessor.getValidationQuery()); + } + + @Test + public void testGetDatasourceUniqueId() { + SnowflakeConnectionParam connectionParam = new SnowflakeConnectionParam(); + connectionParam.setJdbcUrl("jdbc:snowflake://localhost:3306/default"); + connectionParam.setUser("root"); + connectionParam.setPassword("123456"); + try (MockedStatic mockedPasswordUtils = Mockito.mockStatic(PasswordUtils.class)) { + Mockito.when(PasswordUtils.encodePassword(Mockito.anyString())).thenReturn("123456"); + Assertions.assertEquals("snowflake@root@123456@jdbc:snowflake://localhost:3306/default", + snowflakeDataSourceProcessor.getDatasourceUniqueId(connectionParam, DbType.SNOWFLAKE)); + } + } + + @Test + public void testCreateDatasourceParamDTO() { + String connectionParam = + "{\"user\":\"default\",\"address\":\"jdbc:snowflake://localhost1:5142,localhost2:5142\"" + + ",\"jdbcUrl\":\"jdbc:snowflake://localhost1:5142,localhost2:5142/default\"}"; + SnowflakeDatasourceParamDTO snowflakeDatasourceParamDTO = + (SnowflakeDatasourceParamDTO) snowflakeDataSourceProcessor + .createDatasourceParamDTO(connectionParam); + Assertions.assertEquals("default", snowflakeDatasourceParamDTO.getUserName()); + } + + @Test + public void testDbType() { + Assertions.assertEquals(DbType.SNOWFLAKE.getCode(), 20); + Assertions.assertEquals(DbType.SNOWFLAKE.getDescp(), "snowflake"); + Assertions.assertEquals(DbType.of(20), DbType.SNOWFLAKE); + Assertions.assertEquals(DbType.ofName("SNOWFLAKE"), DbType.SNOWFLAKE); + } + + @Test + public void testBuildString() { + SnowflakeDatasourceParamDTO snowflakeDatasourceParamDT = new SnowflakeDatasourceParamDTO(); + snowflakeDatasourceParamDT.setHost("localhost"); + snowflakeDatasourceParamDT.setDatabase("default"); + snowflakeDatasourceParamDT.setUserName("root"); + snowflakeDatasourceParamDT.setPort(3306); + snowflakeDatasourceParamDT.setPassword("123456"); + Assertions.assertNotNull(snowflakeDatasourceParamDT.toString()); + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/provider/SnowflakeJDBCDataSourceProviderTest.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/provider/SnowflakeJDBCDataSourceProviderTest.java new file mode 100644 index 0000000000..69dc1c0f56 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-snowflake/src/test/java/org/apache/dolphinscheduler/plugin/datasource/snowflake/provider/SnowflakeJDBCDataSourceProviderTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.plugin.datasource.snowflake.provider; + +import org.apache.dolphinscheduler.plugin.datasource.api.provider.JDBCDataSourceProvider; +import org.apache.dolphinscheduler.plugin.datasource.snowflake.param.SnowflakeConnectionParam; +import org.apache.dolphinscheduler.spi.enums.DbType; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.zaxxer.hikari.HikariDataSource; + +@ExtendWith(MockitoExtension.class) +public class SnowflakeJDBCDataSourceProviderTest { + + @Test + public void testCreateJdbcDataSource() { + try ( + MockedStatic mockedJDBCDataSourceProvider = + Mockito.mockStatic(JDBCDataSourceProvider.class)) { + HikariDataSource dataSource = Mockito.mock(HikariDataSource.class); + mockedJDBCDataSourceProvider + .when(() -> JDBCDataSourceProvider.createJdbcDataSource(Mockito.any(), Mockito.any())) + .thenReturn(dataSource); + Assertions.assertNotNull( + JDBCDataSourceProvider.createJdbcDataSource(new SnowflakeConnectionParam(), DbType.SNOWFLAKE)); + } + } + + @Test + public void testCreateOneSessionJdbcDataSource() { + try ( + MockedStatic mockedJDBCDataSourceProvider = + Mockito.mockStatic(JDBCDataSourceProvider.class)) { + HikariDataSource dataSource = Mockito.mock(HikariDataSource.class); + mockedJDBCDataSourceProvider + .when(() -> JDBCDataSourceProvider.createOneSessionJdbcDataSource(Mockito.any(), Mockito.any())) + .thenReturn(dataSource); + Assertions.assertNotNull( + JDBCDataSourceProvider.createOneSessionJdbcDataSource(new SnowflakeConnectionParam(), + DbType.SNOWFLAKE)); + } + } + +} diff --git a/dolphinscheduler-datasource-plugin/pom.xml b/dolphinscheduler-datasource-plugin/pom.xml index 4e81fea5c1..332bab306a 100644 --- a/dolphinscheduler-datasource-plugin/pom.xml +++ b/dolphinscheduler-datasource-plugin/pom.xml @@ -49,6 +49,7 @@ dolphinscheduler-datasource-dameng dolphinscheduler-datasource-ssh dolphinscheduler-datasource-databend + dolphinscheduler-datasource-snowflake diff --git a/dolphinscheduler-dist/release-docs/licenses/LICENSE-snowflake-jdbc.txt b/dolphinscheduler-dist/release-docs/licenses/LICENSE-snowflake-jdbc.txt new file mode 100644 index 0000000000..96cd5d8186 --- /dev/null +++ b/dolphinscheduler-dist/release-docs/licenses/LICENSE-snowflake-jdbc.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2013-2018 Snowflake Computing, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbType.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbType.java index 9e8dc067f0..4360b8cfd0 100644 --- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbType.java +++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbType.java @@ -47,7 +47,8 @@ public enum DbType { OCEANBASE(16, "oceanbase"), SSH(17, "ssh"), KYUUBI(18, "kyuubi"), - DATABEND(19, "databend"); + DATABEND(19, "databend"), + SNOWFLAKE(20, "snowflake"); private static final Map DB_TYPE_MAP = Arrays.stream(DbType.values()).collect(toMap(DbType::getCode, Functions.identity())); diff --git a/dolphinscheduler-ui/src/locales/en_US/datasource.ts b/dolphinscheduler-ui/src/locales/en_US/datasource.ts index f001dc145a..d054714410 100644 --- a/dolphinscheduler-ui/src/locales/en_US/datasource.ts +++ b/dolphinscheduler-ui/src/locales/en_US/datasource.ts @@ -23,6 +23,8 @@ export default { search_input_tips: 'Please input the keywords', datasource_name: 'Datasource Name', datasource_name_tips: 'Please enter datasource name', + datawarehouse: 'Datawarehouse', + datawarehouse_tips: 'Please enter datawarehouse', datasource_user_name: 'Owner', datasource_type: 'Datasource Type', datasource_parameter: 'Datasource Parameter', diff --git a/dolphinscheduler-ui/src/locales/zh_CN/datasource.ts b/dolphinscheduler-ui/src/locales/zh_CN/datasource.ts index 702ad9d6dd..e3daf608fa 100644 --- a/dolphinscheduler-ui/src/locales/zh_CN/datasource.ts +++ b/dolphinscheduler-ui/src/locales/zh_CN/datasource.ts @@ -23,6 +23,8 @@ export default { search_input_tips: '请输入关键字', datasource_name: '源名称', datasource_name_tips: '请输入数据源名称', + datawarehouse: '数据仓库', + datawarehouse_tips: '请输入数据仓库', datasource_user_name: '所属用户', datasource_type: '源类型', datasource_parameter: '参数', diff --git a/dolphinscheduler-ui/src/service/modules/data-source/types.ts b/dolphinscheduler-ui/src/service/modules/data-source/types.ts index 3b4246369c..ab3dc1ed07 100644 --- a/dolphinscheduler-ui/src/service/modules/data-source/types.ts +++ b/dolphinscheduler-ui/src/service/modules/data-source/types.ts @@ -34,6 +34,7 @@ type IDataBase = | 'OCEANBASE' | 'SSH' | 'DATABEND' + | 'SNOWFLAKE' type IDataBaseLabel = | 'MYSQL' @@ -80,6 +81,7 @@ interface IDataSource { dbUser?: string compatibleMode?: string publicKey?: string + datawarehouse?: string } interface ListReq { diff --git a/dolphinscheduler-ui/src/views/datasource/list/detail.tsx b/dolphinscheduler-ui/src/views/datasource/list/detail.tsx index 8b5d6d2cf5..6888dbfb5b 100644 --- a/dolphinscheduler-ui/src/views/datasource/list/detail.tsx +++ b/dolphinscheduler-ui/src/views/datasource/list/detail.tsx @@ -556,6 +556,21 @@ const DetailModal = defineComponent({ placeholder={t('datasource.database_name_tips')} /> + {detailForm.type === 'SNOWFLAKE' && ( + + + + )}