From 9e2e095b23691f885e0311c41e5abfd7a3dc472c Mon Sep 17 00:00:00 2001 From: muhammadeko Date: Fri, 29 Apr 2022 05:28:46 +0700 Subject: [PATCH] Convert auth-system to plugin --- .gitignore | 6 + .../dependencies-accessors.lock | Bin 0 -> 17 bytes .../7.1/dependencies-accessors/gc.properties | 0 .../7.1/executionHistory/executionHistory.bin | Bin 0 -> 19533 bytes .../executionHistory/executionHistory.lock | Bin 0 -> 17 bytes .gradle/7.1/fileChanges/last-build.bin | Bin 0 -> 1 bytes .gradle/7.1/fileHashes/fileHashes.bin | Bin 0 -> 18697 bytes .gradle/7.1/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes .gradle/7.1/gc.properties | 0 .../dependencies-accessors.lock | Bin 0 -> 17 bytes .../7.2/dependencies-accessors/gc.properties | 0 .../7.2/executionHistory/executionHistory.bin | Bin 0 -> 27425 bytes .../executionHistory/executionHistory.lock | Bin 0 -> 17 bytes .gradle/7.2/fileChanges/last-build.bin | Bin 0 -> 1 bytes .gradle/7.2/fileHashes/fileHashes.bin | Bin 0 -> 19697 bytes .gradle/7.2/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes .../7.2/fileHashes/resourceHashesCache.bin | Bin 0 -> 18803 bytes .gradle/7.2/gc.properties | 0 .../buildOutputCleanup.lock | Bin 0 -> 17 bytes .gradle/buildOutputCleanup/cache.properties | 2 + .gradle/buildOutputCleanup/outputFiles.bin | Bin 0 -> 18929 bytes .gradle/checksums/checksums.lock | Bin 0 -> 17 bytes .gradle/checksums/md5-checksums.bin | Bin 0 -> 18647 bytes .gradle/checksums/sha1-checksums.bin | Bin 0 -> 18875 bytes .gradle/vcs-1/gc.properties | 0 build.gradle | 21 ++ build/resources/main/plugin.json | 7 + .../compileJava/previous-compilation-data.bin | Bin 0 -> 76259 bytes build/tmp/jar/MANIFEST.MF | 3 + gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 185 ++++++++++++++++++ gradlew.bat | 89 +++++++++ settings.gradle | 2 + src/main/java/me/exzork/gcauth/Config.java | 6 + src/main/java/me/exzork/gcauth/GCAuth.java | 68 +++++++ .../gcauth/handler/AbstractHandler.java | 23 +++ .../gcauth/handler/AuthStatusHandler.java | 18 ++ .../gcauth/handler/ChangePasswordHandler.java | 64 ++++++ .../exzork/gcauth/handler/LoginHandler.java | 61 ++++++ .../gcauth/handler/RegisterHandler.java | 63 ++++++ .../exzork/gcauth/json/AuthResponseJson.java | 7 + .../gcauth/json/ChangePasswordAccount.java | 8 + .../gcauth/json/LoginGenerateToken.java | 6 + .../exzork/gcauth/json/RegisterAccount.java | 7 + .../exzork/gcauth/utils/Authentication.java | 65 ++++++ src/main/resources/plugin.json | 7 + 46 files changed, 723 insertions(+) create mode 100644 .gradle/7.1/dependencies-accessors/dependencies-accessors.lock create mode 100644 .gradle/7.1/dependencies-accessors/gc.properties create mode 100644 .gradle/7.1/executionHistory/executionHistory.bin create mode 100644 .gradle/7.1/executionHistory/executionHistory.lock create mode 100644 .gradle/7.1/fileChanges/last-build.bin create mode 100644 .gradle/7.1/fileHashes/fileHashes.bin create mode 100644 .gradle/7.1/fileHashes/fileHashes.lock create mode 100644 .gradle/7.1/gc.properties create mode 100644 .gradle/7.2/dependencies-accessors/dependencies-accessors.lock create mode 100644 .gradle/7.2/dependencies-accessors/gc.properties create mode 100644 .gradle/7.2/executionHistory/executionHistory.bin create mode 100644 .gradle/7.2/executionHistory/executionHistory.lock create mode 100644 .gradle/7.2/fileChanges/last-build.bin create mode 100644 .gradle/7.2/fileHashes/fileHashes.bin create mode 100644 .gradle/7.2/fileHashes/fileHashes.lock create mode 100644 .gradle/7.2/fileHashes/resourceHashesCache.bin create mode 100644 .gradle/7.2/gc.properties create mode 100644 .gradle/buildOutputCleanup/buildOutputCleanup.lock create mode 100644 .gradle/buildOutputCleanup/cache.properties create mode 100644 .gradle/buildOutputCleanup/outputFiles.bin create mode 100644 .gradle/checksums/checksums.lock create mode 100644 .gradle/checksums/md5-checksums.bin create mode 100644 .gradle/checksums/sha1-checksums.bin create mode 100644 .gradle/vcs-1/gc.properties create mode 100644 build.gradle create mode 100644 build/resources/main/plugin.json create mode 100644 build/tmp/compileJava/previous-compilation-data.bin create mode 100644 build/tmp/jar/MANIFEST.MF create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle create mode 100644 src/main/java/me/exzork/gcauth/Config.java create mode 100644 src/main/java/me/exzork/gcauth/GCAuth.java create mode 100644 src/main/java/me/exzork/gcauth/handler/AbstractHandler.java create mode 100644 src/main/java/me/exzork/gcauth/handler/AuthStatusHandler.java create mode 100644 src/main/java/me/exzork/gcauth/handler/ChangePasswordHandler.java create mode 100644 src/main/java/me/exzork/gcauth/handler/LoginHandler.java create mode 100644 src/main/java/me/exzork/gcauth/handler/RegisterHandler.java create mode 100644 src/main/java/me/exzork/gcauth/json/AuthResponseJson.java create mode 100644 src/main/java/me/exzork/gcauth/json/ChangePasswordAccount.java create mode 100644 src/main/java/me/exzork/gcauth/json/LoginGenerateToken.java create mode 100644 src/main/java/me/exzork/gcauth/json/RegisterAccount.java create mode 100644 src/main/java/me/exzork/gcauth/utils/Authentication.java create mode 100644 src/main/resources/plugin.json diff --git a/.gitignore b/.gitignore index a1c2a23..7a5a0a6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,12 @@ # Log file *.log +# Intellij +.idea + +# Output of the build +out + # BlueJ files *.ctxt diff --git a/.gradle/7.1/dependencies-accessors/dependencies-accessors.lock b/.gradle/7.1/dependencies-accessors/dependencies-accessors.lock new file mode 100644 index 0000000000000000000000000000000000000000..9bece22856d7db1ce5b4c9314acd10265143daf3 GIT binary patch literal 17 TcmZSnG?Rl**5KVc1}FdkE|&w& literal 0 HcmV?d00001 diff --git a/.gradle/7.1/dependencies-accessors/gc.properties b/.gradle/7.1/dependencies-accessors/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/7.1/executionHistory/executionHistory.bin b/.gradle/7.1/executionHistory/executionHistory.bin new file mode 100644 index 0000000000000000000000000000000000000000..c85e32cb201af40dab875a0482d119b273db2913 GIT binary patch literal 19533 zcmeI%Z%7ki90%~{++NHmoQNa^y$A~eciT?goEV{P`6n%NE;Sa{?e@%_&F#FqZRR^s zB2Y|wQ9@9L)SKu(1ilD+Q7A-&FM_0k=tVDjE4_#iyX`hq2$AYV#P{Ite%$jszu!Hd zd+y$xmyj~+T5cojTj_d;2m%m*00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOL~?MIfM0 zWQQ@CvWkLCP?RRbu~QEihq$-9VAq`+Msrhr{{KP#tY1H5wBZN=2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fWW^X zP)Uf{M2P7}X1^YDSH{v|K}w|}T&!PqxzxzOVAa6DP|~(`04%GmZJ2YcRdAvoPjJbd_z)-h5e!; z$r@kIE6F%7#u92$q0aJr#PNb#bkiD_%Mq?}JF6oc$GKddh$rOasDsvsqP4k1n_mgl zojOo*xOaZdH)t6b6fr8LXoH|q%l+-lw7gx=qM7bfjUDygRv#bm`#SihlWo3yu1p8h zL=MOvmQ+oh${ZCbl+>g|{BP9Sl<*e?uWl^pj|yD1%b)Bgn}&5>kg4VAw&v{JaQm5I zqYcd`CO4J{C^6HssHVwkt=+CtB_)Ye&9550M3x~BpxTY)WOK8eEhNR+AxWMvE}f=| zsuP(;^(JB-4+)wWHJ&;%>#Gg6D~UcTYQYvEB?KFf)+e=S&={Cz^}fV9_L(W}{I+zw zuy&-*yR`OXd3tW;qT^Mm`BI;t9Ft;{ncFf=F!$JUS#9}cu8$^G&-lVj;MPcSeA(00 zR;Jy3d@YlFa>-=AEGr59ZO|mDW{W&$eyhrQ7GnL_dav!_i^A#MUsi{EzVCbaC|hii sF^{R)w;)^R=9XpB#Cqhz?OAF6>+ZMb#F3dX=bI~8j|rQZ(LV#0pMCnP2mk;8 literal 0 HcmV?d00001 diff --git a/.gradle/7.1/executionHistory/executionHistory.lock b/.gradle/7.1/executionHistory/executionHistory.lock new file mode 100644 index 0000000000000000000000000000000000000000..fe0e65285b685471cb580cc6b92acef52d3f7016 GIT binary patch literal 17 UcmZP$s%y75-oN@T0|YPw05EC<7XSbN literal 0 HcmV?d00001 diff --git a/.gradle/7.1/fileChanges/last-build.bin b/.gradle/7.1/fileChanges/last-build.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/.gradle/7.1/fileHashes/fileHashes.bin b/.gradle/7.1/fileHashes/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..aa2874881530862b5b1174bfc6ff2b3169d9eb68 GIT binary patch literal 18697 zcmeI%%_{_90LSrXZ^Z z|3E}Z+Jms+;2<|q4h~w+^gPq1J-X@p)HBc1@9Edf^SMq`2s2dFLzG5+Y0C})1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R;YwKwMrVs4io6R(PA5IU%~MpW)p%VgZ#-HD_Tj0q-uUvpnD}Zw(~Tq55Etc*!H4YjRO{9F&BUaeN%vgquc}pz IhGnnu17%xvO8@`> literal 0 HcmV?d00001 diff --git a/.gradle/7.1/fileHashes/fileHashes.lock b/.gradle/7.1/fileHashes/fileHashes.lock new file mode 100644 index 0000000000000000000000000000000000000000..d23b881c88acf703df4792a062b26bea4fea39ac GIT binary patch literal 17 TcmZSPH1|!M_&~Xm0Rq?nBS8ZN literal 0 HcmV?d00001 diff --git a/.gradle/7.1/gc.properties b/.gradle/7.1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/7.2/dependencies-accessors/dependencies-accessors.lock b/.gradle/7.2/dependencies-accessors/dependencies-accessors.lock new file mode 100644 index 0000000000000000000000000000000000000000..aca628094ec33124a40f7dd1f757224f24fdb38c GIT binary patch literal 17 TcmZP$Ib5Z1$oJd@1}FdkH2?%+ literal 0 HcmV?d00001 diff --git a/.gradle/7.2/dependencies-accessors/gc.properties b/.gradle/7.2/dependencies-accessors/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/7.2/executionHistory/executionHistory.bin b/.gradle/7.2/executionHistory/executionHistory.bin new file mode 100644 index 0000000000000000000000000000000000000000..6e425c2c381c87ba13e02dbb51e9338dfed2061e GIT binary patch literal 27425 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 l7#q)!;orzK3JW%grR@rrw+=*40{ss;~Wh4Lq literal 0 HcmV?d00001 diff --git a/.gradle/7.2/fileHashes/fileHashes.lock b/.gradle/7.2/fileHashes/fileHashes.lock new file mode 100644 index 0000000000000000000000000000000000000000..c31eb534e4abc2d90849a6f6554b36008a87e50f GIT binary patch literal 17 UcmZQx^Tz2jgWH{E1_)3G068ZFod5s; literal 0 HcmV?d00001 diff --git a/.gradle/7.2/fileHashes/resourceHashesCache.bin b/.gradle/7.2/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000000000000000000000000000000000000..0f367a9905407f9f666017ada2744cf89e959e3f GIT binary patch literal 18803 zcmeI(?MqWp0LSsGf=_JtFk}WQiTcJQQxVkET>8R+7}5f@hS-AyY8Z)2uu#dsA%ddj zo4rU(2`eOfF|kl$5F^DwAmT*k15^k@9K@iq?$|wuT>k?39ys?Ne&@%5^Lcx@6_S(~ z`%f9t@klscvO)j>1Q0*~0R#|0009ILKmY**5I_I{1Q0*~fwLlTL%v9K@G^;6p@Bt= zMUpOQnG3(t@H#R*v26N&o-= literal 0 HcmV?d00001 diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..2b1a3ea --- /dev/null +++ b/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Thu Apr 28 11:29:29 WIB 2022 +gradle.version=7.2 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000000000000000000000000000000000000..77a82d218c1a98f852ae5a3a538a2c21e84ff09a GIT binary patch literal 18929 zcmeI&Pe_w-7{Kv&Lrf!TV%9p$T`ESa7;Eide^`(-y+~;u(y0-P0;wc)NGPR6=^^Z( zg%iYzU}=H|6O#%&NEkx8Lk2|$FEzS!2qc2}u04<9ErJom_l3QC`R;jt@B4ms+>RTD z-IkKgSlf!$4mm;q0R#|0009ILKmY**5I_I{1Q0*~0R#|00D=ES;I#Q58#51M-)l`D zY>60#XOnqgzj1KLQhRZECi8LG5&iw3bN5_BeCwxc(l=uEwuXxAY3_CGB5!p7UJf10hxcTy*9VU zH{!ceAiYw1^Zw@#+Q+xWrAM{5K0Oo)<%ISAuWHwK!?2#roWmXg1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKp@)!2h0oPo3Her c<}K;n=5@sk|FC55e*SLd?49)|EB~HZ0VR`1(f|Me literal 0 HcmV?d00001 diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock new file mode 100644 index 0000000000000000000000000000000000000000..b03b58dac8b104ec8f8bc45e92ed3fc2303e2f31 GIT binary patch literal 17 UcmZR+x9V=p7w6q)7$ATT07bP0kpKVy literal 0 HcmV?d00001 diff --git a/.gradle/checksums/md5-checksums.bin b/.gradle/checksums/md5-checksums.bin new file mode 100644 index 0000000000000000000000000000000000000000..bb7a282606815971e9333158cad5644afb5b31fd GIT binary patch literal 18647 zcmeI(F-rnr9LMoT6B6n0gbW8AbP+)#Xi1?$2vJ-$I1qGlRve^B3tANyr)a8Zam^Rd zS}!0FS|xOG*Yi1^J4APv_&)I5^XLEYdyeO`9(N-|NH^^vHY2zxsSrQ_0R#|0009IL zKmY**5I_I{1Q0*~0R#|0;J*lzbpuuBY3HkLUa8!dw5$HXgz~&*(xWGINy(SnE#WrFuOY48z7( TGxzTC=5s2Mw*MfA_N~Mk;j>xM literal 0 HcmV?d00001 diff --git a/.gradle/checksums/sha1-checksums.bin b/.gradle/checksums/sha1-checksums.bin new file mode 100644 index 0000000000000000000000000000000000000000..0be8626ee64976758596458050923fa2dc553486 GIT binary patch literal 18875 zcmeI(Pbh<70LSrn6O$(Y%SvmKQzwfh;n`Rt`9D@ZxK$1 zSBKlBe}Ax2Vm2-YA8$ln@6+?=?QuCPf9gf#?j=2!Ck&(Uug*g4{T4mX4b?__uItLR zyjjni+RtNhTK2-)=Zxri+kU-i-WTcC@{peEvyyL!XS^bS00IagfB*srAbc{T)ln>CLc(WVRBG*b_kzLzcSlDw{9=;F6Eh}<$@x6Abvcs(>pf2 zCt4M^qLrl1Us^}y2WIc6f52`H9Oey${XzHDuxM2!iq^}?Z?%55!vsgi(5Zjc)ackQ zy+6!YU-Lww#136|?>mg@@BF^QhMqv1ZN+mo_q0{L>$PmAp|Nnw8j D1>V#> literal 0 HcmV?d00001 diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..7d35e8b --- /dev/null +++ b/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'java' +} + +group 'me.exzork.gcauth' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + implementation group: 'tech.xigam', name: 'grasscutter', version: '1.0.2-dev' + implementation 'io.jsonwebtoken:jjwt-api:0.11.3' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.3', 'io.jsonwebtoken:jjwt-gson:0.11.3' + implementation 'org.springframework.security:spring-security-crypto:5.6.3' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/build/resources/main/plugin.json b/build/resources/main/plugin.json new file mode 100644 index 0000000..05f68d5 --- /dev/null +++ b/build/resources/main/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "GCAuth", + "description": "GCAuth is a plugin that allows you to implement authentication for your server.", + "version": "1.0.0", + "author": ["ExZork"], + "mainClass": "me.exzork.gcauth.GCAuth" +} \ No newline at end of file diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin new file mode 100644 index 0000000000000000000000000000000000000000..0cb435f6b952a15e57ecca05e4832d3e1d264301 GIT binary patch literal 76259 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

n*joL!im|`%!rGZm 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%0A*w3PhhhGB(BifY)@2cb!T4l<#V_r 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%0Dbg+fPdEkx^`Wk{ovbUFlUJ%QRQG!nIP^wR@%bc zMso0skJ#9&5Qn|{4jgO?5v7KT%DnX80tGRr9v(Jb-XY(RdFhndFhSTROcZqO0-}t% zGC$?@KJ!9FXSzvd6;(Q16xc*CNo}$YmItMpqD>u9n!}r&>k*>VNKvIN!4LrpA&Bd* z`Q_fw3$C4syG_TdT>l?$?;Q};(e;ndHg=b7cNezbvdM$dC&g6Ln_!IvBPOONMvade zV~M7kgd&0>h*U*IKoJ2!5owBuf`EvKSWu~gbQBN}MaAzqyAqQ;EqUMf_xtOdnLBs( z?$lF0XGXDu9urGXYm@DSHdwZJ(cjDJ$_{x@H@AARk#;nkoEarBr*VY-pJ zF!H&a=-VzvTYilGd6@3AD>EGCeq_}(=LOyGbzk;#4q;Bn8&|yUAk*Ua9M5=J#A^DmYTND zY3APfpT5v@Y|$uVQhi)9?Y4)8yRbIdM;WQ_ca2+m>+Y;f|N2$WeNr=F=U&=5g?36t z>*jo3A+!6)vAYii8DvLRJH5G&c1xuv$4U1{!4&U*?xCJ&uc(~Eg{Pttl2)$RPdi^W z{YWL|el_p4?6gCo9j3is4R`ok8tt4;yKa!-I=OsrS2p#jeC3qHpt2*?->t}?C*PsK zYP*CR*Zrl()_a$`N3>p7&%T~XyJXRm+^IYs0LR~T-g%39-u(QM(Qkyx{JuS1E}`mg zeQ@Zhy%(Nc@U!N`N7MNs2k03GX}4_ptrmk652_P=wdqpz^4?23V}dq!eKu#wA$nX6 zJ^j4Y8d2R|8LYbZS=!9XALm`TWIq4iVR~FH?R12G_b5Fwj|O8`KCA%WeDSsP7)`u@ zz}f7cZlAa&kGj$J@XuScTXr{97tqdyv}?O{?SHIi);#wE-lmtuEfE(B){QKp-Hy}K zi)oiIb&@z)yhlt;-yP+$EV)#V)=Z z$_w+8&(qEov}=vk2sP@BS=6kX+aCJIoP5_s5y`p>w9`d;$|c&Zl7`!(tKgpi!1Bv# z8V|t-OxJdFh3ws!@Zswx;uR6^-;6lm<$Jr-kvjfy^`_myk+l@Wb)$^;H>2WQz>vS6yzUC$`aU?KB(=53vhiIyxTP#oS1ExO>9qXQxb;oVe6MPbhSV zx1*kOo;Y&mr`5s33nI^!4woFbO2gf=u$-TYc<#kP$*PIwrypw4f8Ni(Mmu-XBfDsb zQthV6IyhGsBJI!=|FzUaCGQF!+RWDWp3kHxyui4=>ukZ11d3ybnqiH0N%Q^twqq-=baJ zt)j-`4^R7Id2jHnL+1rG9vl8f56~lT(|~Qh1MAbb)?+~7a~nQ!tH1kgZAYhWC6(do z-g1{7H%L!Tvc>KH^qzdy_13iLyiHI2{fz}7S@-BEeY`6w>iLy#{lZQ-UwiKTiL=f$ zHL2S*)HUzuJ)0Z8-#Kd4r=JwvUGvcfB{g=B*ApLhd^EGo{)4C9rbq5`XQp{DV?CJ} zUX0r|`xwD02BMy3&7ONv;o(5#KhbqRF+JqIj&b#8rUo#s>lwE| zQ260GQ7McM>cGkpAD50DPRpy`y!yorZ$Y=3+MBFOyc!$1X6qWK$JamU{Nx5^ToB{t zV`o)KmQMam$rpUh3aheJ<--R59?ZAq-re4vqiD z1KNxp-?&BZ1Yh&3*M%0EfQ`Vb7>$pgrj#58!w(-n} z7wo#Xv3+68v~Xrx93X>Xg!Ahsj~B0)+><-LGEY$EJvsqGJl5A#ot_@uKyT{#@b9~R z4%)~#HRxatiYER1*#a`s#VI-CbFUun37eR)5e!@cu$h6-n0a_!rI(xv;LmzRaa54C z;qB+|zFc1S>=p*xJpgL|=5@>F59TWOcVAZTyZTL1@>XWTS|04j_1_+x<9En4Zp5yC zocfwtQya;Q*~UzXkzBI7p{Hh#W21(}Z%#{S`tq&7T}~_ucf~#(GVt{G{qN0e z58KJW!K83dz=|11T9Y?wwr{Qdz z{<|Wc8I!3>-GRQvxR2PggJSUsgD(P!{2{agAR1QVKJ2 zK8%O?9-)ucPkHOr*yD{)oSf7@V+F+|xfMJy{hat8lQe?q&rce*k8w_AoXQcy%qX_` zE?8uLJ|jA^arnboWIr>p08Z_pUVZYX538o0@2Os77_;cBrU3w5k!!m%DAQ(49MfKhJ zzPM!eC|OT+N#o~VXmhinj0QY%{11lZlt&zx9<*d%;Et$6FCT(GD1rvQTy|%M*Yd?L z=7=gv_q@$~k;9BV%#81)HfrFe1m2^gCcIR6Y4X*Lo8OO{x67EzOgX|#KFW-}1^}yj zVi@bb3&{8NLQ&zlqJ{~xcXjX2V`k(tZpWA@1&mW6<5I-99%p70!{wm!Ys)5kFiO)tEK9iF4anKmO7O zl=2iaIzxPyNBtPqVkkCsZR?JVTK~Ssqz}s&IPL+4{(@H?A2E5?jf&ydUuzUzJxES7 zjMx5#DQh2{l5TL*%vha&FKE*l#^o$C;~Y#mIfx{nV}6$X<(D(B-He)f zD8YR3X4ZuB%-9NMO0b=W4o*sQ`)22nx=QgoZyYcczU}qF&I^q5MfjuEKJNO5dd8RX z%9a=U4ZAj6o_>jOu4G)Jtue#&>Z%PJ@}>O#yOpb^u4Fztrlq0-Lm#=bzxF6!^Q>T} zb4OMc<5tZ~sbRo22nXPR2{-?_r9GutoBBIsV;}wLEr;v1%#^)og?n@6BTGGZk6W3Q zkbU!|>TtQc5v~S0(cqU*npLrHf!j|BRhf0nxXa9#OEy?l-W@@YUyk9LQbcpyH0tpbM2^uU%4BoNyDCa zM>_cYHv_jA-6)rCZ38pq3Nxk7z7a+!9tmL!dVtTG_uH|&^kvxynk z%uElrA%5pO-S{q-H|oSO!e% z&YN&&McCM>zEje!F(W$}Fdd><*30~w(^>C%Lh`vKX3;B0T)G(NZpJm)8uYVf{j%({ zWaECZ$%6+6K*q8_sa@Zv#E>c<;xm9 z-o9M2^3Iqf*|M@b%*eY8h$@4)4q5M}ffn3vh%mPgtpDosm&NmPUf;gx9^>rJLbMP3 zlUFsCEZM23kg1w*YUd_RGuJUhLRatcy20 zrWk-Wkzxoouz#nM>Kp$0^0w3?um6x6{OoFWMxlcb3%`s9xGbYK>P1@|nqKu7`4h)mMTY4=v z_#~lW;?Ir@V8L6lp1m&!!kNP;2zpV0EMA)R4IV-ake^3ieCn~Mm-;bZjo&AI zIBD;M4eaD|vVA-%W*g6ArpxB&hkktQqc5K}El-A>BxOBw;b_tiN9t?dd?)izZ4f&n zn4NM+7c77kaEisJtZC|to$>42mt}ucHz|aj5z3AWW1YfTmyN9JCU!;y3kP>>hX1;F z8QeWK=l%k^nT414Keo7j#f#}>vsI5A36I~rcMI#hm38t%+nU3jSC)P{qUVF{%X~s& zQp=u+WXEq~T}~PX_)#nzyZ99~Y|<;~x!lc?b&0E-9@pIbC7K-nCJU!$@39B-Tu`&iVP$Gh*hSe((Mx_AE4i(r*fE!O zKe=zx<>!38OOJSe{>CO9)%eKZ`%6P!aPmFsOD~$$yCREqKES$mSaCw1On1+J?%4?+ z<@+o+^z!UTS*etI#qLe-p9?BqSb6%f*$rdzJPxumve_Aj*pWHx$Zrp`5SDDa>KJyQ zC#YYz^$)Lj+@&k<`L90Ud6k~&;Zcu%o!0vBOuP4%?Q~BlA{%$+vQwJ1Alz?kpP8By zdpS}Vc6h|7r@vZogmpd2j>)#Oo*z5Feo`=F>{G(=HyRAV>d_D7v18nIpHt`l{&8Q` zD7UsGyXKj0gG-X~+3AY)@`(>UE~iJo+)6R3t6WqjJR(u zuMHkQ>rK~}-0T+kO?!q{#5x~mor+nP6Rc|q>wJ=TPiOT`-P2L)C-_`{<;RCV*%dru zgsjJM;Uw!^%DP^*q6Ri>dfYuRW^m8z+Q(*mxbmrQPq8j#EX3Al@K3|1EQY~>*M37+ zw{4j1n58+l_3EydzYEVer>Hkjt)FH`ytHA=PiO8d^Y*y5_*gkR?hHHny5KAft*^ea zT8rnLgTV~|&f1L?vmWW6)EOUqX2BZ+%Z{CAr&X{sF0eB%vNO)YwA%)F*K{4_yQit_ zQ$=w^jOa_LQ(ru}#JX0p6RWT(J?w5`ly%-K!f#HEc(ZU%=lJg)f5QKvYIZ^mJ8@hs z3rDTsfedP@n(JKghRgQCn&%hZR(jd(u4A1qvrZ`p4S&X@d@(X>LHnt1s_for-Mze? zb!}kZ`N@jnda?3+B>%Z5WQR}2XSTkwW%3mk4p)Q~G`FH-{%Y)h}-| zQ~TbYld(fvHTKMrrlwKj-qJR*&P}Xqg0(#ljD57JZ}aSqYsa(S%-rMpS~EMLg`M8Y zI<>Lm+gX=zDb9E4VLK0+x|~$E->bVg@mbSd$><*opYC8?ud*)J*fE{#*lfElXhhq= z^mFH|5?Y-dQBJQvW+;uC^!TmG+?!tAmIgWXS!v}Bd!5Oz=-!X-IUcM0pqq8M&Q9rJ zNA|KK``D2;*pct{Lq!OxgUebMT#sW{(@8^52wNlndv`n`4G(%N08 zR;9jD)DXCJ6*tnG12JSZ2RARkdEd}Yg2$d~BvWsOPpDk6CU3;-k9;^+Uk+}{Tf>pH zc){y@xZmjewH(~jG;1~hq`&*>)#_2AWY@FD^wamB*fGM7n^8o=0?rKvoQ#MclwaYF z49}7Ix~}8kvM;E9_~n8z+m)7YB?0=(*N^QQ?a#r5(;!a>hG)*{kt}+7*u(4A#7(ao z9l*V_o||@E5D34t0EOyxf@p8y4MxV zIfrmgC(utnxo2+t=DzZ_Q3s+;pSAWcW)2XmvloJJ!L3hNJbZFP$AN3#@kEa1*e%?Y<3jLY8~)B;E`9sS*)JB!*82bO zu+vt~Ig)eALbG^3PxrU6bJ+%;4S(CabN#vCZJbLKH!+$Ub61a-41zk*7xZ2JxSyHl zo0hp%MW@~kjNzQObFQ`4v)giOqCb6g+wEt6&`#hM?wjeegBusiO%AsibVlVhWQ3pi z$mNlixv9#4=cklWl>8_EO|c0Db9`T?!#}&QMNnX%Mq4K4ocbnJ_;+>GOsBX|;ZDvi zj+?xnUtk0X?#xgo{!;1G$rnxr&JkTt%Gkxti09nGrA2Bu4p4chKjc!)lD2 z^s#7M^Q}IovT+$ZB=+rgdpMW9+{7~`YY_kPbFNBi`7@;_=X?LCDL6MGg&Vhzn_h1- z2xpIcc8RCQ^u#SrDdx~($Np4qY6Y{O12rE`CV>O|=2Dsi6|tN274A>>uBwjy#p~1= z71gr7x5hMPM7r|AWO2?1IHx-F9h+X2AAXeLo@rj#dhpa6yYv0DRKTgG z(+l2bosZ0elY>{QuN>q?W^;gY$iZ_Q=FQu8>z-B_n$`9ClB6GeKR(1w%;Cm(3l4J- zC=QG5SF@Lc_0r?}M^|S(^tSsqMbmuJofhWiaubhmV}HuDJIX;QAE1-*7HinkR(@$5 zR(J1}{gLl3txBnK4avjbfnVXj$9sOoBN3Y;FG>H>Dad5=^re5 z@Ab?R_EC$b9^s`>#h-C90|8C6tYa2o?B!4lw=M*=- zhe{Vvb9bt~TKV0VZ@H;I4Xt|n>*_Mj`5f~jl|FWI&GAPk*DPe7{AN{Bspd52T+X?c zSiu};y}nMp{K3QDb)@gruZzpynDlY)y=5A= zV7oS!`aW&uSN~9tSo%qr=h}wG)PhEuI`g>itkzX?>uTRUw(#p!bwTI3i51-R3mhDh zgJFTtN2VnO&ux0rr-msfb2`@dK6R0EzQj2du`no{pZIXL$A*4!4*3hTf~M`)SitmE4Rf&IOzwu;PE~#Gc-}d~%f_C09J%;^kA#jjiEaYPm7% zz~yAsbtIomJ2Fagp=3s3@!&^2lQnhR*vlM5U)RHsUoji+9k9kl(OeS2&kO&Z%Dp2Wr5puoD!k5c7)cv6>3p~e6ng&e z!4F-SncAZraqOEfGE+|GwsVs^xM|(|3|$|edh`RQh3oH5t@ZF2dHr2V`S$_`D*Wj) z=U(04l9m^3Oj$Z9@yTR6O1|mST~&&Tvr88z7w-FHiE0(#^xD_#rKeSYTh4vt{kntW zV^_Ip*SIn60LWOUq4s>IdiwEw>fIT?C@y>YeDq2uH@1tL(#^pU_t!b=9rr`wu5*I% z9RKStPyA3Y?AlC04ZC-8Z1Th&&bgO!T7{UCTkSsgUS-B@t)JmvHX;6*(mu}l2IsoQ z8fj7Mw6~-5Wz&evO^>PkYWDB!=bUeHuH9Cgd9N&!~t%~ zHoWVTNBz8byKD3EZea!U^*ru~>*d?r=sVmvxc63g!H!b?jrZi@?Zpc;r*?3sx9xcI zF6TVRLFgBJ%*d{@o<>1keE7xNOHJul8t-xMx?9GA!O22=z61Np{I5JMaPS|X9ii#J zr-t)Ys>H=jOGlg#e3(6uQ0Zlv0=^bCrEl>4z~!`8@$krX;`V9pTDHij*zY4}j@@{1 z$*bc(SkzU2sBD#GvbSZ-HLweTGf)5dwfL#YKd-oT{EV(6`sPQgEiM&|j|Gk_fPn?N zEnIi|lVg?OsA}c8hu%Lmp3DC34PVRXH5S)CVWH>(9NP2D-Ejxs_(#RC&knQ>o4&km zt!2_ra5jBndG>qGbCah%ebKJum-Qw0{47&m1M|@0Dc)b){leqXucv)C{N9~;bJkg$ z{Vh)UC`nvtxstTNu=(}37yo#@-<)3D1s3E}KL_uQdzJEi`k{TVpAgakmbceiCW3ea z4FOjNevQFq(L!qSY+laV*FIi&>-n&44Wp*a+F)@BvP|E_SZ`IEGG4r~=HrpHNBcu_ zZjC;b8*Fh2vB04b`}lCoOxm-hDN|P-2{_;}dS%7MA5xc4uXr3RJG*$8`=s($$M1S| z@{Ul8bC|_-tJQobeX{$BIlH&VRi2IS_HX>~g?6ycRb}ljD}Cxr>1PcSHb%}n8*Xvi zXmQ(Qaq=<3h4J8a4SVN<<>SMrT$<#tX_o7rb8Zoq(VH!BG|(0cSqB&1LJ%G_@+>_4 zXW92pzgTqf%*b8w!D>@W2Y;&t&ME;(_8&DzZhjKu@s-%FYRrWeQ&yzKd7H&G)jAM| z4=-GEbme1y$vOJ?GcOc6MOmDK0Bj%e_UZ92c)xey*v~KNuB=XfDB3bE#xiy84mkYc z=wWBScb*yjx9GqxL_bdYe%uZr6|&$;-mt--)jPWCS3L3l*3#{k@jEOo=ZvT-P>l;C zv*x2aXT$D<1FLnZkO(|Km^8exX@xT_0XrYv$8}x7DjA;tj6Sc zabvt?VlVH!miqkNY14LX{>3}(deo(#r+xWZg2nBUHqio3Q@AXL8rihI>H0C(%M%#m z5oz2bqjy`zCBeT|Cqn_evmB&Rr^b(}@^3d>l5I)cwdnN_pFI}05c6K>{}rEOyw&G( zsn=(D28Q&|KCd+Y{E5ZMHz>t2W1nSYss-+<-)})XA$sqYOVcd2(AF>DhHtPCjUHH% z&^oLzC8K_6-um`y3)3w#Gc3-Vl`;HGm~U``E%Xh93#G39@}<{azPapWpRA|1PRX*2 zJYa!^@gUZPr+a`|-g@G2q<8pxscz1~?>`DoVkTJHvn}HeSzN)(kHDB4{Hb4!F28(x z1-GDf?xH8IisKmpkf0RqUGkR}47#kG zdFhc?Hw;unYN`B&_nzMRspG-h*-tMVP>&DEw@g1~8B+=OSA&fsaiDGK!by*Oz^e>6 zeq?QtFhfjLI`-F$zr4Kl**(o?3yIy;0?Xt=3ml4pGk=^YEacreKc~O{>66c8_+G3k zvN#{NxE{0arg76Jrhc}t^|O;+Z(e$QOM*O^rE=bAe|OHA$xlw`edMjd_RDm!#rcHA zwaz*Y%O8^rFq<ePDClPiSU{!uJRac}@Ul2^4!It#f=8Nw6J4ikjV-*( z#*-|$j!*o}5o$6BoFLbbsCDNPKR%RNW#6Fe;XLjA`6Lw5T&}}fy24cAQ0j0+zt(=O zJWH3SIHK~_?%E$bL={e$YX4x3)l@FE8ek^N_ZmQ>3flcNhol@5*wtce!XwtcBFzuhj9O9Xo;J z1sKT<%(-IcPm?>qaj8aI%dE98(Udu4=|cI~GKZmU5@~D~Y?U<5_79qLjmm6GswP>D ztx_#5wGb}>w0y6w#~}|)qrmgl3rHx^Fag<$wBA5=02Ky{D)dp7O*#?}DSo`Bn>yVp>h!cAe0ccj-iaqpDPRl8Mr`imm-)ZOJ}!nKYIBQ%^Rpb`Z z0Riz8@`yTsZl$l$5wbYS%kDgrYQIa8ui4>vo4sPH`=faBc} zl3=9O60!-Xpw}T+cUeZZW8MxSi9@=_OcH_ey-Y14k_4Q{myXxf(EjQ@LUIU89N>|B zq=&@h7}7!^DFynlt%(MuB@P+pQU`3PYG^2Irgl@O$wPw!4x8#E(<%-y_o-}y&DKo! z6!(W*75>9c6}bR4T0&J7rZR^#MKc|0@2@|s!diB4cj;YpqY9@4Huz~Kz+4Bz)=M3y z=`-7=MYiRb=`41A9n>Pu-Lky&)ubkj9yby9nB$M(imncB~Sgr%52Bc~KS;fpoKoL<6q)Swx z%smC!fp2tBEz+~{4f;?CiG?&jPLyIIdw~rP6%SOqv63%uzd11eD(*-60|s@GF9R&3S%;nUr9zb)28ZayR&- z3TeEMTt>Q{B3FRQ`(hjoKCYXKhVt5X7&kHEO(a~E>)&M7LH(=RrI}(JcE~D++$u>xd&S@GQqs8lF0WuN` zX-Td=+nA#-)z^pvjMkAC54pSqG1&{0->W+$Bfe0EE3HC73k6>1ip5y}+ZdR?cRGCs8$#F>WgSiu8QURPOMR!b^h~NFZyYN;sFQ0dgH^_?@6bc#yS)$XTT2Y_Ko$n=HBMuVBiu1));tug` zvAZNpkSfWM6iPZJ6}%K_wzNbVV_(N_vtKLQAoGz`$(m&y(slB!@@?`Y`B{04ov)%> z(W&THxGVETsmg3+f%2lVLD{TatqN4ds5Yyj<)>7qRj^pVZX8anRYWP$sZz>c?W<0f z6!2Qqo$8&MculFMMtn}w!t2wtsr?)x9Cq@P9X3(r4(X}}hekoMV}`oXu~*@vT@MpD zLmMOskR2D4X!Eoc+A3|6_Num9o1hpJ$Lo@HmC6>~dWSk?yUw3qAit?wqYu@m=yBLo z=?C<8^lJv4jv8_e&4zYEroFc@)VRx-Bki#ZbSyTWFoqavjop$i zV~?@l7%lcR<;v2O5vCMVk?DlE$`l~KZt@m~EB2WWnva@y*q=6M$}gL8bIi~HfzYGICR^2Z;r}khW;D_BKER`0pMQk10 zAiu@>OM|%_-BzxQ+O9jJ^3!H076C)dNRv%vNg0G(@hL*}n6F?_>Flh7ZdMR(ge`>%I(oh18TcJ+gf z{&$_c#cb>3lHYZ6i10sk^bMV@tM94*OlM_T4GL;?+_j~!KxjO z^SVq!qJaw9*idOJM|J^E<*_SMl=W<{F5TSEw5!_{A)+3K1n!WqLZ54j)REm#NQ5#m zE*r3Dq(WNQtPIun!Q<6!e4$Q4t{`2nBb`XQB_sd^eh*yrZ(|O~P}+dZx;Rb&wn88TV?&Tw#rc}xuQqGuF`;_T@r(mG-@S@e4Aj0GJSygf)KPFt2CV{K;bUi z0z%zI{L~ynERS3QPOyAMu7Ffyy(oyF7=l_twE@LW)DngS&qUC6?(hT5Lz+VEubKi1 zA}B0E9aNwJbq&YA4K{I~ zxk-mxrB&NoXaAS=u|WI)PoWpc9moYz(IOHI9R8V5{GjSv~88O!+))R zGjjgQYXTAtoM@{#$UfO*{k<4`vcn!GVjZe@n^AdAfIMCXOH%Mzs(r4Sqys0}XU>ET z80Dn<@=+0%J8dGxKm}WvLd8ilIf;4kJaQIkg*~YRDory6&|!2YJ;-)yw^~{hcNOFY z$noX>2OC4vZ)AZ#$^n07Tlk|4@ZTkXf4%?zPd9}Bz8(B=$M+WFM)2Fc{y%R5|7y4Y zS9|@x+Uc!}e+_nJo{C&S3Ib{~P+0y7bfgWr6n%$1xq;7aaby5#h=>d#h4sKw28&#m zs94m*ZBY_$NQt@?Te%FQk1PvL7J)Pmg!FYlK^zAWdjpoYDO|7=Zo>Qs*=-q#22OyA z6R1rI!1Fw{BpE48o_$F3S&|7I>6A!H5;;JYxE=s(;&VZa%CvO zljD#EG4+JZS3*t$udmZrXkwICBx%eZc_p{eu1M}_&SMVH*Ok}g*R@+r{f1MD5VlGX zEekTHIg+#Rj>IPWWGilIPug!_Vc`2fuF&=$;U8AW{_?6&1r_kxC{hDd)W#0TL#2@{ z?5>v~J!cM1q$Y%er2jm)=9)O7BtaQw8a9udUX{Q4RW5{Z;*T zrk?UM3{Y^nsv%SzXUJ6_Qx_RdQ3SnIhe3 zWu&3QxZNSv+${C7cqxMIOU+G+Sl%^7HrzNRhbh>GJFO0Ij3z=Z-wPxyKW1cDfc!)e;Kj0vO%frSCDP+D}p?2iYZ!7b|ZhD zvF^@E$S2Eh=#HAn9^i$YiX^T>3_5W-q?mf`E@QMVP?cajXb!cssGAKBz71Qwh#zEV z#NU&Z=<(MM$nf_P%~e`*2y4D!j5C1#p9?&AmA6}L^Bttme8`cY1c=tAbuv_{pe>5< zod%^JAI#LJffv;qf~l*_QM+0Lsla9T7qS^e-aF<^unj{2l!+>VI&6_$(WV(!!?e6) zXjjD1mG)b;sa%8%nw{RLiq!6ss)oYfwyJGpCRn_$o|+0eltJ3G0$~7gF~1Y%VM+Jr0q&T=Pm?w!p&TrGVlfC3z#w zfY5iK{04`$3bMhPBO)P~6Ry|^n+WE#nn@&3S)2%*6p{iqPunT!=Tb~jiXuy_i0p!A zqRpx*(ah?LLohS^WoE@b_J15FsC}|&}QP$43B&*A$ zXsid}H5-2yHiV-{!9triROgWC9Hn@h3=gwMYpZq0rI5y9y=Xc|3BC+!v;l8k)4K$U2{ThFvoF>I!nUftCb%}h8$7K;pUsZ$}x7{V_7E**oHiJ?DRA4i+ zl2gDN|J|M!uE1TdQ)S!tLfC59^-kONy)t-DR4DmXCo9J~&nQlts*L13@Vqh|xdapz z30xphr$FPAzdn?YO9UE>la**HMn8c~qj<1Dpr-(B^w5A+P=_#Fan#UbDAkY#O!?ER z9d2>395zCV?<-wNnt;KPPz{EL+W&<-c|$m4UHYR$dFpqzr33#X%hLbG)G%aO`fJ99 z`1_WnT*IkfElW4`4{S@nH8}jUgc+{rRQ+E`nYrxmZA$-I&h)i_nV|*y__pH~T{V~M zNZPQE+Z8EFa_xR6cVbS5c&&_dBe#|Fk&zzcnzX$N(vMs>Y`NqXa5&{}0~OaB&S?4^ z8WcC|w+cW)y$gBDyK*!M-(OF991aQV*;;uOV>M9R!)nlTK-`t^IR`0sNx1{q@qHmB zxT*2cf#+=<@Vrbh@ka`CJP@Dt@zTYsbR-{UA$SRH>f#MnFF_EN309IYq#-&IffR({ zXr$oDhyg0FiM%8kc$hXr4noxOac4!f8K(_;YjAH(;cO1VS{=F_hn$Z0t@nGO4n-0j zrim~N=nfk5%++8{8C#;dVan9_Xh;hFY`cP_0tIVmnvxvAoMIix#vFf5Cr1jbIYv^9 zIo2)k6mZrB5$yyxt8E@PoYCkHMc*ab32;t>c6{GH@Y|0AuiI&?6{hN0q+l|s04ffZ zwwdbiapJA9i}p$;zV^-|-~j2=i_NUa{oW~f6v$g?T3*NjCb@Bv?kJi9zCx`d8tt=odT z3Vt&ljXA54s}&`}Eo{JH_XPkI{;Ea?Ldt%Z5e2UxL#F(o8HJN75I0B=Jh97UHfyhP zXc&S45DGc){YM=tOjq<}4rp&lV$gSLGs~kx&gQqY*;?=)JTTCsc^=ww07O9kEh#vg z!l5=kNbVGghTT$(-@i@%>p$2GPldVqDw9>?iNUg`MKG9mAeSWqr`As3c%dBGjr5p? z>_G~C*?mYG6=Xk9QMxLMxo;dh3~8%t0X*Z-`l0qmRQJCdT!3gFxgdPd@;0*se)EtI z*xLF>unrUR07S%sb=c*MVI0RLSva@GM{0vvj+PGL@!3HJEY$emF^V^kqmDP2J>10y+;&SO+h%TNYt1ASeC{1dijiu-pq9 z9DEh)9sC_g6r}9`C?s0ff>?OlI%XfJJ?KjRD~b<^gF1LyWF!&kMiogyx{oF4NOL44 z6DYq<9%Ck1z*!X_Z*hRkOH2-88ZG9y8NvTMgeCjXF`5G$uUbzIV@{qKS~w4LpkIz- zj`g3Pz#K0HDaD*J3ii(nm;V59rs)H))gT-FEwF^k~Nm&;^D- zp%!rN-7{`hdD{0eJ58t&b}HgEp+@l9`osJD8X9!_VBiEpeg)uVcceLnE^Qf`Z`{eH z@?&|ij$RzVd6K~=Aq=JNJ4GU(B+ti4qVeq%eXM$qjwA#B7q`8kMf2BfZ?F0&+2dR*7cD6<^fKf) zM_9CqT>=}Lm!MXT#xiR;3?K>zKx<);uk)5yQ_WO0yIIst#b^V~I}8m>DgAMtIZw4-SEBOK z)Yxb1eT)D(0T&j$AP?eJ8?Ko)Ywt+bYHm6-nsGn6X{^+f&G>Wo7_tTFVTwc|1$)6x zpnMM&T0Raq%I1g&wg1heg4Nl!HsgdM@%Uc6fNaElB!FHC;z%N9`ASI&R^_h-3{NU> z|FrGf7XJUX@&CH*r$HT>4D}#yK=0091K_=6yPf5rbp7NE}vt>HlC^*0y>j6U`%+#*lB1NO>A>kRtc}25* zn=qEQn#u)9J(mLq%rU4yh5E}4ew%r#pwHokeK0ks-_M+u-{Kk+DVEy`QUql#{!a1j z5&k=9#eep(+Z5jcnGIO+|Bo}}{~I{PzXDVIXNC8#DZ4{{_1}BdljVQOtx^mfCps?h zlj5i?6p#`~Tb+<=?NKN~tPakNPE#W6VJKvxa6Kdx+uV;s`ytv?tvg~V)WIuIk}{zD z5_%=61U*3j?$}FG@(VnI1*-;tIQKm)Rbp}m3JTl}b&d@Rat>cYuoJ1kYMLq1gcPhs ztw2TXnsUi4whVmlqy^V$#MD}S^1bj>fbhLAn)G4GK*?z^JohU=6K{h>7a&yI#L?nn z9cV*0HGg>n8pMzAR}xPLpgnMF3{rnk$&iBE#}6p%wczmaN3OwPy#v{Z&+e&71W@6S z&ysA%+#(&>i8Ne6;*f4Nlbs;I!rpryrkjAdc^VQAe^PWqW`njs!zE(=N|Fo&OxLjB zAHobU*XII-joD`Fdf=G1VPb7qVH819IFx3=sQ0TrW79~j?)js(IzmfpPhe18@=UZa?t2P)`P zcdIWrkPE;|I@OVuW+fV?`%Ttu{}R4)fdU=A3g1cPNIL9M!e8~-I(%-GBO35I44y`$ zJ805|PYQ*{grpt0Q_OW9>A`298TDe$0JGYG^kEL*m2V&gK=4hVV%%$ShYeEgw)h&! zEyx4i>kI%wPou(l8`6UP<^=me6B)$!wlL%#Qcp+X;|OIl%)K;%RslNVi|JATv1aST zG$0cCL)x|p1>lpL^i{39GSCrf-G)#40Z~Vyfs^bsH44zAjRNU@xTU*X3#*b2grZSusBE^NiS=VHBC`ZdBjjvRIT z%WFq5yw3L&!9rI8oG8^$>UdukufQiICJ<;Z{Pk+<;AI}DJPku^#a`J?@ zLmB|MNpEqC-46RqIU)r^gzm}&W4|6Sxs9=>%{BwCpEyWvH}NwJ2MbE5PV59-1Z1fUd=P;%&s4f*9Kea|MONq1jR*eK22|tTSdnHZ*4tcZ0L0Td@J; zn+G#zFTe+I_5`Z_{QPNApHtfeMw~-KxZ~f?q6fYboJWn0KKF6QLvyLhia93r&>SFj zq0H5%0jcW>HdvRIG$94gNDET1_FM(Zx9%04zzH(xt(HNSbOA56nkDqHykmlBONoVa z<8yR87s$zV~otOM@UIH~mhh`k!c2 zAO!yboOVi4E%+@^{eR|6Ow;^dxf6^30#NA|g{D|FNrANL_a?DKn;0h$=nyYjQQ*6%Dt+N}TyG;Y8JIq0OsGYkxP}d?Z zGhdLO6P74jxN7-E^EUHAIMwu`KFiW)yvCGk_h>?lZMr1GHC-N8!c626By2|PO5nhYh%1>jgr^$QLkeMp1F3~H zXeH>2L(L0O%Axisogzwk$RA;gCd6>53qq7qF;E7rUiTfYm!S@ncbhOUCSQ|ahVjq< zd4d(oVR3A-{lZYUS)(Pv-;t+y;PGoz*|aYkwix|qLtc*!Hf(VV)B$(@?5F#f0eypV zoxD@g!^LZS)nq+r4XEuQ=D!4<@t)vs4@w;?j z_3K8?>K-cq-{G%Nqf-h58-e871J6-o>IEwC05cZic0xokG$Q&*ALI&?<-x)bVU3pD z#JciDCE%OHw?IF3*ALb1fn2XH7p?*W4m;WhsKBOjlQqCg0u14b2T&*YZ9gm#$1Ab( zb49A`b$!P}rGK}f;B83NQcMnaKGm4Jyj9Jrxj7J=p3L?jaF zW-WLC zJ_ zDuD9i%rG!6VNRcxR05TSDT7o&T(jz?11hzfG$A@PAd@OA-64f$s|HSz$F|bvIX{D! z;1CyQxFILC_v@$w>WDC+2jJR%!vlD22pcUsKnEESZUms(2CUWUJ-Py%wbN~ogZ~6L zco35C2gpGa))pd!_{kRF5E9ag6b4{BQgBROMGBL*3u%;;^a8cv9s4oImnFeCv6{qZ zq@F^U*aP^ykAcPi4s!0watAVqoImXj*BTq(9T@tnk*?JcAD|+P@ko(cqdeL$8WHWu zEp`BwS_4n{7$8pkusjUP0H9W}3*gFuz;i>(1`d214h@$MTWE$2Zei1FaA^YDpf%by z+hWsez)KN?zfd9#F_19)h4UPVKzhSOB9X%XjzXFxA~8VufvR@c5Rr?~-Z7I{;2A*hqhsMF|f^s z*}ZHY!t4GwwC)Yv@A0}QDFaiv@(!7(5++%M#SL`fFxKA3VELf@t_cSp9ZC5tJrn%q^Z+2S!|J}SaXtX z)%ZKOa~B+9xFqhDLxAHp$7sh?#}YXD=`^=SyGh%}^>h8&NXwwO2qm}E_}|VN$VH$I zMI6RF+q4Iad)_TChMRbcmHv*&vfJzdO}EY(1$_zIAR zMVj$R03ftUE4~xwK-w{94FcP)A{WmKG?Gr_&hzhbqzk!T9pL7BfU_@9_5vs}mo3$V zD=;jyz;IbbGQr;n2=^h;20hiJ58vz4*6K+=a6$})Sfd9->`lX8*0j!m-XsbUp(E^^ z4uaF}L4`bbxcb-#3f*Dqs=AThL3`4GKJbPdSaRx=#0NQFbdCA~hfe=>nB%919X$Xz zQJ@)ImJuR|ix0FG;E|iSl6I=vRU`;<1hy|Gp}>pdbTJ^w*NRrF^2Kl#!)D0ihiNd< zA2^ZCX>2|EV>_gArQcyK0d^U(6H9bRe?`pi!Y2tvkSi0BvkL#afkUfH4(PJNUqeXt zL9XP0GF$<=oGIQ=EjXnBpj;~C!pb}pSN%Wo)TBWjf-nf!x70&cUZcmYfVN2?V1WoH~H!U@!)+1h21$sX-rR zvdL^!MqepzJbvtU9?6AQ?TS@6UHl!b^50R&;qNg)v*iQF+sTnapz17$r|AG7cQ=6Q z%O(EmTs>O%(v-1q2}F{1gAAOy$Dy1cQ@mn1DF&|ozSe9D??&?^hIFH$1p~Qe#MX%|t=ybL@S?O92Er`%5vn`69QJTogpXeZgD66Ke;Y6!3ZdcyzX=krljK^1!$XZ|+WoC3GsSe+8Vc?$-eL^_w?zkI z2>4K3a1DK(hC2%(@Y|+M+kBR`pl=NI#`qPRnF#~DlkKb_U%ue`;>GdE3FuP(O&zGo zC$XD@;Z$0%*_;Mm6l1@`{ythI1Qr8OvVs8bS}g$O;|x6KT~U)AFe0USYz&>EtOdX= zMgsLXROm?s)|x9=PA(yXvBIPZIDsDAcRqw818BV#G(jf z^E}~+GYH2=K?q^7X<9@~;;A_{U)uu^y-h5tmLdiZHw4u9(AkQ@6`sX|&>4fPMs2R0t0Tq^41DZ zhBS)~ELCbIu&4di6MU}0tG_#u!<`QSab1wh4-)q=?YQ-RuiNm(V)_T*3jr!4DlzRlnvlp zV2QnlCE_&z`0y~nAHyXE)NW7YJE%GdEDJ5T8ljt`*)fhGUho9R(<-DOb@~969#B>Z zss*^V#zSCTu@3A2Yasvk+le2(0nWGppo073Ef*RUK&{yZtLrHcogdlG@C)KrK`2%yRw=d8@v73n&RnY4!~%yipf z&_0*DE32n4RxU?-R1pnFF2S(hgYUuuoB~u3ril~5Zj=tZD8X*GG|r)y_JOl$u*@xn z9KbU7qwWu385@9ctpXs7eef^j3D$FI&<%+vkEDz583qJat?e+B=9ie^{F_|l_UR!I z=jd;0%fsAs3c!fRfWwn?3XsAnNkv$yS&5)&@-0dFqw#Md#rd8nj^*<5JAL}} zneOKF>EHSNzVB;~mZG_adh=!%UYyravg|}A6plkbTdxX;ChuD#stvQ1oGHj(H<;^fR^}^vkRjKyl%r?`HVPI-cTsZgvX=X%-G!bR|MIlu zN|kkU&T7lgIdws#i^i~D2YHajZ!lx%Lgahod?RNwDWi1BDuEv4+4Fp~1kpJ9xc-LG z>F2iBOR2nj%umZZkx@yG?D9GhmH4-%;Tgo_Q<4`?NgR_-ET0lf-^9dIwD;=-{)MK2 zka$E32YC`UEk;MUov9HLrnncgr_z&``MePr#Tkq zPf=fc$4TlDH`CM&khPgVQ9a>&IaNJv6I*z-RY9>8HiZ;){T^?_whSPyMy}LSWu10| zNWK9JrT-*~j9f#sjq*P)vze=qqCDW2x-hZ$2t8SY)%*aw=0q_PgW1fiij0zUTi!lS zBC{%qA|)rhWH-xL$%ONM9J|?wm)y#E!ELVOUC~xl4GaiV^Fi$39mF`^MSI0Bs%Y1^ zMK!FYG`iE(1C643N}LsTnAlH}oT4U{b&z68m}Dl)}J^@LQgCzP83ffF@lW z;yI9)co+q1V^CkK9cA_X97KMOqhtb0tbw*3>`>UhCmJt_N6YKD@5UIB%=cIn%@`fV z*hn^lCgW#s9z7#rQRBHc;@WISmA?>^OqLGN$fuM4x3=<5K^XEVqZupI@{l--8cVlw zF7yLb{Sf!CZZlRQZETB?)=t|K7N@Xc&Y(`*Ddnc0%iE#gK6Ny#tHpJqm3e;-1sr`J zOB3G7us8ze+G>OY!~p8krO2SfaMP23XQ7B&>;n$t2rcrKqsiafhdA^V?g*1BuX0Fc zxg*8M?OR`@L?_Xsb;|MtY{(xS;xSLH!zZ56{$3P>V1P1T3~MH2My!LQ{MWg!kP@o_ zV$Rc0PLMW$K3rm)lY!eXP#Y5C6pwJCDqLc8)BMP$*?5c&cbAJY4|7pX%T?f-s_~yo z*{#%P*7>f2CoGopIw>A03Q@w1W|onD=36NY?ZRTh1i8wUyo(bcpTb5?dnO&d*>{iz zI;D)cyOd{vM+g891uK>{*+>hx#%5SEb8w=JC4k*SqMZ96*szuMY`UnRC5@FW$kP|wS+gc6cEJJ~1>waA zpi#TAHBYAX}vem_dgfPD*VS*dbmCk~RxALz_%PeFhs1ZZ zn7Pkkk)J{#vVv?)imaZ;);p-YA&#Sr*NlV&8%};a{ayN6vkCCz@y5~Lzvu4&VA>3u zB2&4;UL4fQ20oz;ty6i6R(so{T3oT6{eY=;j<#D7U9?alJrAn`iDlpopcQrsjLJ z<gtGDf06ZVVrhpNisdK`gV;gw`2_Sfx%qz8Z=cV$_uIXsq6YRw7M++>!{tS8>rEZrI`p9{(+oz5G!Xy7zv7>pOq)#_vt&Pi^;}v> z6knx9>9l7rW>1tXRO}gmFc->979Hc>nJm!Dj^ z0Q+~qS{QvpaED$+_4v=OJ{ChpwO`rd6(}4 z6#X^8>*IkMz?zoYnvg##3*JCJW+dZOkeQFG$n_A?&a9Gzv`b)abLe%@Tt;*f!P}?8 zV_7nK(Bg@Q==Mf7YU02K*!>bRI|khSNK^uKJEHNCga^@wz%e)GOhyUVEroP$HFSqW z9#%Ba`C??JDAekI8U;zVk2fDNmRqpyh6NK2Ewwf+wvA8qFu!s@Hct z&=Bql6Fo3!H}C{sN86oU!P<;Yhq!}Q+Mr05q7+9^x{SA!`BJFaFGjfH+UFZe*I3D; zJYOtA?!kfqLNND>VN;qScP+=9Ri@($L@k!><_SRc#agxi_H`Ys zwaQZE>5j}Oq6}MR@;yX3_gAW-0v1mTeL6Yc&t{a!x27@IcZMlcGKW!8i9YNxEw}nW zmolgzcDtRwaSQKjSj)!;Ol!flVpT2lR%nq4t;32K{7m_Q2XPp+=1WYjfm)Vqwr~?X zpqMXp1YM=@xgC*DZX1vesRYI{XRBrRj-rK57Ja}3FkXQT{C!Pb=_E@N-r+3K$WkQ` zj!i5)Q8oePi;|U^YE)DcE!e_>`-yj7;Bpk|YG=94XZ(hui9EMs+XPPgP0W93J;5G7 z7o^bekM^emKXWdU^o3qvhmifhLW_IYO^dL4FD%pq_SwZvmQFc87ek0d*!ax=Muqe^ z&;WK~*ZF5r;Q|@B!p}VX*%U@vI1TNVM+Ln+gf(47WC)l4VRz;J(eQR;Jbrcc- zkCkU>q6p&xYS^p2dYrq2KLV-kA22WhZ$51;u!<^{r`>y1ez*nu@tu=Kr11-^J6(4} z>rzUyL00%GDqm8Dpvw@vmRKy7k&C~}-Pd{-y_GwAyP27VFVHulhpT5|_ zQmY++n6FW?JPv8VmTf2_3{Nd4?IRl7v8_dP=jzGKrzT?vXNe9nXXWJrp4E(DX=#e` z+{8}wZaQEVyJ4m7L^Vn_Y7$bBP?saD#MS7Wf-3({irC9GC7BJ%8COwumz_8pF^GX@ z8Nz=EyuljmPZ@Jk$&CMNQODk!?MMReLkU+SCmz183$^bKF((@T<)IjvP3qzpSEA)Z z51mf-*N(gLF0M?2{dw`iBU#2~Cf>BSfbn-FXQunE5|wM*#r zxU0oCs1SHvk=CrjsT=0;e-OFytMqtwN(Wa7?EbrSw-M5^z^F$|4GO? za~LtClm}pswuiOTYQ`=PAI|bHxe@(Y^1)=h!qC*MjEuXkgGqsw=F?b@iCVsT|0~X* z!qH;BnN#7dcW~Yxi0lb2b(E^DKGBMOd=%PX-|A{)Jet=dM4m|qVee3LJJmm*Q$OfZ zKRT~2{8?RiL0x!JU6_(;^V#3~&2KNMV(H&L{r9J6Yx?zNHTR0T=&JgsYwG*w)nEKF zg1xAZcB{G9)%SaNtbL)Z%k5QjZ>WE~seaO@E;_IJm4K}G^sBi8>Y`if`?u8(dQ`jJ zFYAAGN6j5nKO9m&8devMuqT)Oy)3!!ccb`Pq59#Nx@cH+>vfKMYVLh?(YU(s0UM{; a(`8#Rq2@kR7d=uxIj@HG^TXQ?fByr_A3 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MSYS* | MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..97ba25b --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'GCAuth' + diff --git a/src/main/java/me/exzork/gcauth/Config.java b/src/main/java/me/exzork/gcauth/Config.java new file mode 100644 index 0000000..f4cca43 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/Config.java @@ -0,0 +1,6 @@ +package me.exzork.gcauth; + +public final class Config { + public String Hash = "BCRYPT"; + public boolean Enable = true; +} diff --git a/src/main/java/me/exzork/gcauth/GCAuth.java b/src/main/java/me/exzork/gcauth/GCAuth.java new file mode 100644 index 0000000..b30dfa7 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/GCAuth.java @@ -0,0 +1,68 @@ +package me.exzork.gcauth; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.sun.net.httpserver.HttpServer; +import emu.grasscutter.Grasscutter; +import emu.grasscutter.plugin.Plugin; +import me.exzork.gcauth.handler.AuthStatusHandler; +import me.exzork.gcauth.handler.ChangePasswordHandler; +import me.exzork.gcauth.handler.LoginHandler; +import me.exzork.gcauth.handler.RegisterHandler; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; + +public class GCAuth extends Plugin { + private static Config config; + private static final File configFile = new File(Grasscutter.getConfig().PLUGINS_FOLDER+"GCAuth/config.json"); + private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + @Override + public void onLoad() { + if (!configFile.exists()) { + try { + Files.createDirectories(configFile.toPath().getParent()); + } catch (IOException e) { + Grasscutter.getLogger().error("Failed to create config.json for GCAuth"); + } + } + loadConfig(); + } + + @Override + public void onEnable() { + HttpServer server = Grasscutter.getDispatchServer().getServer(); + server.createContext("/grasscutter/auth_status",new AuthStatusHandler()); + server.createContext("/grasscutter/login", new LoginHandler()); + server.createContext("/grasscutter/register", new RegisterHandler()); + server.createContext("/grasscutter/change_password", new ChangePasswordHandler()); + } + + @Override + public void onDisable() { + super.onDisable(); + } + + public static void loadConfig() { + try (FileReader file = new FileReader(configFile)) { + config = gson.fromJson(file,Config.class); + saveConfig(); + } catch (Exception e) { + config = new Config(); + saveConfig(); + } + } + + public static void saveConfig() { + try (FileWriter file = new FileWriter(configFile)) { + file.write(gson.toJson(config)); + } catch (Exception e) { + Grasscutter.getLogger().error("Unable to save config file."); + } + } + + public static Config getConfig() {return config;} +} diff --git a/src/main/java/me/exzork/gcauth/handler/AbstractHandler.java b/src/main/java/me/exzork/gcauth/handler/AbstractHandler.java new file mode 100644 index 0000000..19841fa --- /dev/null +++ b/src/main/java/me/exzork/gcauth/handler/AbstractHandler.java @@ -0,0 +1,23 @@ +package me.exzork.gcauth.handler; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import emu.grasscutter.Grasscutter; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collections; + +public abstract class AbstractHandler implements HttpHandler { + void responseJSON(HttpExchange t, Object data) throws IOException { + // Create a response + String response = Grasscutter.getGsonFactory().toJson(data); + // Set the response header status and length + t.getResponseHeaders().put("Content-Type", Collections.singletonList("application/json")); + t.sendResponseHeaders(200, response.getBytes().length); + // Write the response string + OutputStream os = t.getResponseBody(); + os.write(response.getBytes()); + os.close(); + } +} diff --git a/src/main/java/me/exzork/gcauth/handler/AuthStatusHandler.java b/src/main/java/me/exzork/gcauth/handler/AuthStatusHandler.java new file mode 100644 index 0000000..4349c36 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/handler/AuthStatusHandler.java @@ -0,0 +1,18 @@ +package me.exzork.gcauth.handler; + +import com.sun.net.httpserver.HttpExchange; +import me.exzork.gcauth.GCAuth; +import me.exzork.gcauth.json.AuthResponseJson; + +import java.io.IOException; + +public class AuthStatusHandler extends AbstractHandler{ + @Override + public void handle(HttpExchange t) throws IOException { + AuthResponseJson authResponse = new AuthResponseJson(); + authResponse.success = true; + authResponse.message = GCAuth.getConfig().Enable ? "AUTH_ENABLED" : "AUTH_DISABLED"; + authResponse.jwt = ""; + responseJSON(t, authResponse); + } +} diff --git a/src/main/java/me/exzork/gcauth/handler/ChangePasswordHandler.java b/src/main/java/me/exzork/gcauth/handler/ChangePasswordHandler.java new file mode 100644 index 0000000..42a36be --- /dev/null +++ b/src/main/java/me/exzork/gcauth/handler/ChangePasswordHandler.java @@ -0,0 +1,64 @@ +package me.exzork.gcauth.handler; + +import com.google.gson.Gson; +import com.sun.net.httpserver.HttpExchange; +import emu.grasscutter.Grasscutter; +import emu.grasscutter.game.Account; +import emu.grasscutter.utils.Utils; +import me.exzork.gcauth.GCAuth; +import me.exzork.gcauth.json.AuthResponseJson; +import me.exzork.gcauth.json.ChangePasswordAccount; +import me.exzork.gcauth.utils.Authentication; + +import java.io.IOException; + +public class ChangePasswordHandler extends AbstractHandler{ + @Override + public void handle(HttpExchange t) throws IOException { + AuthResponseJson authResponse = new AuthResponseJson(); + + if (GCAuth.getConfig().Enable) { + try { + String requestBody = Utils.toString(t.getRequestBody()); + if (requestBody.isEmpty()) { + authResponse.success = false; + authResponse.message = "EMPTY_BODY"; // ENG = "No data was sent with the request" + authResponse.jwt = ""; + } else { + ChangePasswordAccount changePasswordAccount = new Gson().fromJson(requestBody, ChangePasswordAccount.class); + if (changePasswordAccount.new_password.equals(changePasswordAccount.new_password_confirmation)) { + Account account = Authentication.getAccountByUsernameAndPassword(changePasswordAccount.username, changePasswordAccount.old_password); + if (account == null) { + authResponse.success = false; + authResponse.message = "INVALID_ACCOUNT"; // ENG = "Invalid username or password" + authResponse.jwt = ""; + } + String newPassword = Authentication.generateHash(changePasswordAccount.new_password); + account.setPassword(newPassword); + account.save(); + authResponse.success = true; + authResponse.message = ""; + authResponse.jwt = ""; + } else { + authResponse.success = false; + authResponse.message = "PASSWORD_MISMATCH"; // ENG = "Passwords do not match." + authResponse.jwt = ""; + } + } + } catch (Exception e) { + authResponse.success = false; + authResponse.message = "UNKNOWN"; // ENG = "An unknown error has occurred..." + authResponse.jwt = ""; + Grasscutter.getLogger().error("[Dispatch] Error while changing user password."); + e.printStackTrace(); + responseJSON(t, authResponse); + } + } else { + authResponse.success = false; + authResponse.message = "AUTH_DISABLED"; // ENG = "Authentication is not required for this server..." + authResponse.jwt = ""; + } + + responseJSON(t, authResponse); + } +} diff --git a/src/main/java/me/exzork/gcauth/handler/LoginHandler.java b/src/main/java/me/exzork/gcauth/handler/LoginHandler.java new file mode 100644 index 0000000..53906b3 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/handler/LoginHandler.java @@ -0,0 +1,61 @@ +package me.exzork.gcauth.handler; + +import com.google.gson.Gson; +import com.sun.net.httpserver.HttpExchange; +import emu.grasscutter.Grasscutter; +import emu.grasscutter.game.Account; +import emu.grasscutter.utils.Utils; +import me.exzork.gcauth.GCAuth; +import me.exzork.gcauth.json.AuthResponseJson; +import me.exzork.gcauth.json.LoginGenerateToken; +import me.exzork.gcauth.utils.Authentication; + +import java.io.IOException; + +public class LoginHandler extends AbstractHandler{ + @Override + public void handle(HttpExchange t) throws IOException { + AuthResponseJson authResponse = new AuthResponseJson(); + + if (GCAuth.getConfig().Enable) { + try { + String requestBody = Utils.toString(t.getRequestBody()); + if (requestBody.isEmpty()) { + authResponse.success = false; + authResponse.message = "EMPTY_BODY"; // ENG = "No data was sent with the request" + authResponse.jwt = ""; + } else { + LoginGenerateToken loginGenerateToken = new Gson().fromJson(requestBody, LoginGenerateToken.class); + Account account = Authentication.getAccountByUsernameAndPassword(loginGenerateToken.username, loginGenerateToken.password); + if (account == null) { + authResponse.success = false; + authResponse.message = "INVALID_ACCOUNT"; // ENG = "Invalid username or password" + authResponse.jwt = ""; + } else { + if (account.getPassword() != null && !account.getPassword().isEmpty()) { + authResponse.success = true; + authResponse.message = ""; + authResponse.jwt = Authentication.generateJwt(account); + } else { + authResponse.success = false; + authResponse.message = "NO_PASSWORD"; // ENG = "There is no account password set. Please create a password by resetting it." + authResponse.jwt = ""; + } + } + } + } catch (Exception e) { + authResponse.success = false; + authResponse.message = "UNKNOWN"; // ENG = "An unknown error has occurred..." + authResponse.jwt = ""; + Grasscutter.getLogger().error("[Dispatch] An error occurred while a user was logging in."); + e.printStackTrace(); + } + } else { + authResponse.success = false; + authResponse.message = "AUTH_DISABLED"; // ENG = "Authentication is not required for this server..." + authResponse.jwt = ""; + } + + responseJSON(t, authResponse); + } +} diff --git a/src/main/java/me/exzork/gcauth/handler/RegisterHandler.java b/src/main/java/me/exzork/gcauth/handler/RegisterHandler.java new file mode 100644 index 0000000..96da451 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/handler/RegisterHandler.java @@ -0,0 +1,63 @@ +package me.exzork.gcauth.handler; + +import com.google.gson.Gson; +import com.sun.net.httpserver.HttpExchange; +import emu.grasscutter.Grasscutter; +import emu.grasscutter.database.DatabaseHelper; +import emu.grasscutter.game.Account; +import emu.grasscutter.utils.Utils; +import me.exzork.gcauth.GCAuth; +import me.exzork.gcauth.json.AuthResponseJson; +import me.exzork.gcauth.json.RegisterAccount; +import me.exzork.gcauth.utils.Authentication; + +import java.io.IOException; + +public class RegisterHandler extends AbstractHandler{ + @Override + public void handle(HttpExchange t) throws IOException { + AuthResponseJson authResponse = new AuthResponseJson(); + + if (GCAuth.getConfig().Enable) { + try { + String requestBody = Utils.toString(t.getRequestBody()); + if (requestBody.isEmpty()) { + authResponse.success = false; + authResponse.message = "EMPTY_BODY"; // ENG = "No data was sent with the request" + authResponse.jwt = ""; + } else { + RegisterAccount registerAccount = new Gson().fromJson(requestBody, RegisterAccount.class); + if (registerAccount.password.equals(registerAccount.password_confirmation)) { + String password = Authentication.generateHash(registerAccount.password); + Account account = DatabaseHelper.createAccountWithPassword(registerAccount.username, password); + if (account == null) { + authResponse.success = false; + authResponse.message = "USERNAME_TAKEN"; // ENG = "Username has already been taken by another user." + authResponse.jwt = ""; + } else { + authResponse.success = true; + authResponse.message = ""; + authResponse.jwt = ""; + } + } else { + authResponse.success = false; + authResponse.message = "PASSWORD_MISMATCH"; // ENG = "Passwords do not match." + authResponse.jwt = ""; + } + } + } catch (Exception e) { + authResponse.success = false; + authResponse.message = "UNKNOWN"; // ENG = "An unknown error has occurred..." + authResponse.jwt = ""; + Grasscutter.getLogger().error("[Dispatch] An error occurred while creating an account."); + e.printStackTrace(); + } + } else { + authResponse.success = false; + authResponse.message = "AUTH_DISABLED"; // ENG = "Authentication is not required for this server..." + authResponse.jwt = ""; + } + + responseJSON(t, authResponse); + } +} diff --git a/src/main/java/me/exzork/gcauth/json/AuthResponseJson.java b/src/main/java/me/exzork/gcauth/json/AuthResponseJson.java new file mode 100644 index 0000000..847fe89 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/json/AuthResponseJson.java @@ -0,0 +1,7 @@ +package me.exzork.gcauth.json; + +public class AuthResponseJson { + public boolean success; + public String message; + public String jwt; +} diff --git a/src/main/java/me/exzork/gcauth/json/ChangePasswordAccount.java b/src/main/java/me/exzork/gcauth/json/ChangePasswordAccount.java new file mode 100644 index 0000000..e823045 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/json/ChangePasswordAccount.java @@ -0,0 +1,8 @@ +package me.exzork.gcauth.json; + +public class ChangePasswordAccount { + public String username; + public String new_password; + public String new_password_confirmation; + public String old_password; +} diff --git a/src/main/java/me/exzork/gcauth/json/LoginGenerateToken.java b/src/main/java/me/exzork/gcauth/json/LoginGenerateToken.java new file mode 100644 index 0000000..9a9b854 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/json/LoginGenerateToken.java @@ -0,0 +1,6 @@ +package me.exzork.gcauth.json; + +public class LoginGenerateToken { + public String username; + public String password; +} diff --git a/src/main/java/me/exzork/gcauth/json/RegisterAccount.java b/src/main/java/me/exzork/gcauth/json/RegisterAccount.java new file mode 100644 index 0000000..880639f --- /dev/null +++ b/src/main/java/me/exzork/gcauth/json/RegisterAccount.java @@ -0,0 +1,7 @@ +package me.exzork.gcauth.json; + +public class RegisterAccount { + public String username; + public String password; + public String password_confirmation; +} diff --git a/src/main/java/me/exzork/gcauth/utils/Authentication.java b/src/main/java/me/exzork/gcauth/utils/Authentication.java new file mode 100644 index 0000000..fd4a090 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/utils/Authentication.java @@ -0,0 +1,65 @@ +package me.exzork.gcauth.utils; + +import emu.grasscutter.database.DatabaseHelper; +import emu.grasscutter.game.Account; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import me.exzork.gcauth.GCAuth; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; +import io.jsonwebtoken.Jwts; + +import javax.crypto.SecretKey; +import java.util.HashMap; + +public final class Authentication { + public static final HashMap tokens = new HashMap(); + private static SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256); + public static SecretKey getKey() { + return key; + } + + public static Account getAccountByUsernameAndPassword(String username, String password) { + Account account = DatabaseHelper.getAccountByName(username); + if(account.getPassword() != null && !account.getPassword().isEmpty()) { + if(!verifyPassword(password, account.getPassword())) account = null; + } + return account; + } + + public static String generateOneTimeToken(Account account) { + String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < 32; i++) { + sb.append(chars.charAt((int) (Math.random() * chars.length()))); + } + Authentication.tokens.put(sb.toString(), account.getUsername()); + return sb.toString(); + } + + public static String generateJwt(Account account) { + String jws = Jwts.builder() + .signWith(Authentication.getKey()) + .claim("token",generateOneTimeToken(account)) + .claim("username",account.getUsername()) + .claim("uid",account.getPlayerUid()) + .compact(); + return jws; + } + + public static String generateHash(String password) { + return switch (GCAuth.getConfig().Hash.toLowerCase()) { + case "bcrypt" -> new BCryptPasswordEncoder().encode(password); + case "scrypt" -> new SCryptPasswordEncoder().encode(password); + default -> password; + }; + } + + private static boolean verifyPassword(String password, String hash) { + return switch (GCAuth.getConfig().Hash.toLowerCase()) { + case "bcrypt" -> new BCryptPasswordEncoder().matches(password, hash); + case "scrypt" -> new SCryptPasswordEncoder().matches(password, hash); + default -> password.equals(hash); + }; + } +} diff --git a/src/main/resources/plugin.json b/src/main/resources/plugin.json new file mode 100644 index 0000000..05f68d5 --- /dev/null +++ b/src/main/resources/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "GCAuth", + "description": "GCAuth is a plugin that allows you to implement authentication for your server.", + "version": "1.0.0", + "author": ["ExZork"], + "mainClass": "me.exzork.gcauth.GCAuth" +} \ No newline at end of file