From f2a1a8c95aabb87b8fd237eb2e09ba1da3823a0b Mon Sep 17 00:00:00 2001 From: 623756217 <623756217@qq.com> Date: Mon, 27 Feb 2023 20:25:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=81=E8=A3=85=E5=B9=B3=E5=8F=B0webhhok?= =?UTF-8?q?=E5=92=8Cbot=E6=9D=83=E9=99=90=E6=8E=A5=E5=8F=A3=EF=BC=8C?= =?UTF-8?q?=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 24 +++- .../com/gitlink/softbot/utils/GitLinkApi.java | 119 ++++++++++++++++++ .../softbot/utils/RestTemplateUtil.java | 3 + src/main/resources/application.yml | 5 + .../service/market/GitLinkApiTest.java | 77 ++++++++++++ target/classes/application.yml | 5 + .../gitlink/softbot/utils/GitLinkApi.class | Bin 0 -> 4744 bytes .../softbot/utils/RestTemplateUtil.class | Bin 5276 -> 5419 bytes .../service/market/GitLinkApiTest.class | Bin 0 -> 3544 bytes 9 files changed, 227 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/gitlink/softbot/utils/GitLinkApi.java create mode 100644 src/test/java/com/gitlink/softbot/service/market/GitLinkApiTest.java create mode 100644 target/classes/com/gitlink/softbot/utils/GitLinkApi.class create mode 100644 target/test-classes/com/gitlink/softbot/service/market/GitLinkApiTest.class diff --git a/pom.xml b/pom.xml index 3eb6bd8..032771c 100644 --- a/pom.xml +++ b/pom.xml @@ -127,12 +127,12 @@ spring-boot-starter-data-redis 2.4.0 - - junit - junit - 4.13.2 - test - + + + + + + io.springfox @@ -144,6 +144,18 @@ springfox-swagger2 2.9.2 + + org.jetbrains + annotations + RELEASE + compile + + + org.jetbrains + annotations + RELEASE + compile + diff --git a/src/main/java/com/gitlink/softbot/utils/GitLinkApi.java b/src/main/java/com/gitlink/softbot/utils/GitLinkApi.java new file mode 100644 index 0000000..1e7d619 --- /dev/null +++ b/src/main/java/com/gitlink/softbot/utils/GitLinkApi.java @@ -0,0 +1,119 @@ +package com.gitlink.softbot.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.gitlink.softbot.global.vo.Response; +import com.gitlink.softbot.vo.Webhook; +import org.mapstruct.BeforeMapping; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +@Component +public class GitLinkApi { + + @Value("${gitlink.url}") + private String URL; + + @Value("${gitlink.token}") + private String TOKEN; + + @Autowired + private RestTemplate restTemplate; + + private Map headParams; + + public Map getHeader(){ + Map headParams = new HashMap<>(); + headParams.put("Authorization", "Bearer "+TOKEN); + return headParams; + } + + + public Response getUserByUid(Integer uid){ + Map inputParams = new HashMap<>(); + inputParams.put("uid", uid.toString()); + Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.GET, URL+"/api", null, "/users/get_user_info.json", inputParams, null ,getHeader()); + return response; + } + + public Response getWebhookById(Integer uid, Object[] params,Integer webhookId) throws JsonProcessingException { + Map inputParams = new HashMap<>(); + inputParams.put("uid", uid.toString()); + ObjectMapper mapper = new ObjectMapper(); + Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.GET, URL+"/api/v1", params, "/webhooks/"+webhookId+".json", inputParams, null,getHeader()); + return response; + } + + public Response addWebhook(Integer uid, Object[] params, Webhook webhook) throws JsonProcessingException { + Map inputParams = new HashMap<>(); + inputParams.put("uid", uid.toString()); + ObjectMapper mapper = new ObjectMapper(); + Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.POST, URL+"/api/v1", params, "/webhooks.json", inputParams, mapper.writeValueAsString(webhook) ,getHeader()); + return response; + } + + public Response updateWebhook(Integer uid, Object[] params, Integer webhookId, Webhook webhook) throws JsonProcessingException { + Map inputParams = new HashMap<>(); + inputParams.put("uid", uid.toString()); + ObjectMapper mapper = new ObjectMapper(); + Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.PATCH, URL+"/api/v1", params, "/webhooks/"+webhookId+".json", inputParams, mapper.writeValueAsString(webhook) ,getHeader()); + return response; + } + + public Response deleteWebhook(Integer uid, Object[] params, Integer webhookId) { + Map inputParams = new HashMap<>(); + inputParams.put("uid", uid.toString()); + ObjectMapper mapper = new ObjectMapper(); + Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.DELETE, URL+"/api/v1", params, "/webhooks/"+webhookId+".json", inputParams,null, getHeader()); + return response; + } + + /** + * 调用平台中与bot 身份认证相关的接口,auth_active, update_secret, update_private_key + * + * @param uid bot拥有者用户的uid + * @param botId bot主键id + * @param suffix 方法类别 auth_active, update_secret, update_private_key + * @return Response 统一响应对象 + */ + public Response activeBotAuth(Integer uid, Integer botId, String suffix){ + Map inputParams = new HashMap<>(); + inputParams.put("uid", uid.toString()); + Object[] params = new Object[]{botId.toString()}; + Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.POST, URL+"/app", params, "/"+suffix, inputParams, null ,getHeader()); + return response; + } + +// public Response activeBotAuth(Integer uid, Integer botId){ +// Map inputParams = new HashMap<>(); +// inputParams.put("uid", uid.toString()); +// Object[] params = new Object[]{botId.toString()}; +// Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.POST, URL+"/app", params, "/auth_active", inputParams, null ,getHeader()); +// return response; +// } +// +// public Response updateSecet(Integer uid, Integer botId){ +// Map inputParams = new HashMap<>(); +// inputParams.put("uid", uid.toString()); +// Object[] params = new Object[]{botId.toString()}; +// Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.POST, URL+"/app", params, "/update_secret", inputParams, null ,getHeader()); +// return response; +// } +// +// public Response updatePrivateKey(Integer uid, Integer botId){ +// Map inputParams = new HashMap<>(); +// inputParams.put("uid", uid.toString()); +// Object[] params = new Object[]{botId.toString()}; +// Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.POST, URL+"/app", params, "/update_private_key", inputParams, null ,getHeader()); +// return response; +// } + + +} diff --git a/src/main/java/com/gitlink/softbot/utils/RestTemplateUtil.java b/src/main/java/com/gitlink/softbot/utils/RestTemplateUtil.java index 930e889..3b3c776 100644 --- a/src/main/java/com/gitlink/softbot/utils/RestTemplateUtil.java +++ b/src/main/java/com/gitlink/softbot/utils/RestTemplateUtil.java @@ -2,6 +2,8 @@ package com.gitlink.softbot.utils; import com.gitlink.softbot.global.vo.Response; +import org.apache.logging.log4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.util.LinkedMultiValueMap; @@ -17,6 +19,7 @@ import java.util.Objects; public class RestTemplateUtil { + //private static Logger logger = (Logger) LoggerFactory.getLogger(RestTemplateUtil.class); /** * @Description 私有构造函数 */ diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5e8ef5a..7866537 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -58,3 +58,8 @@ logging: mapper : debug elasticsearch: url: localhost:9200 + +gitlink: + url: https://testforgeplus.trustie.net + token: eyJraWQiOiJUaEVSLVl3Ukg4TWYwOHM0UnJLUDYzXzZLWmVET2NZckZXcmdzN2VUVWdrIiwiYWxnIjoiSFM1MTIifQ.eyJpc3MiOiJHaXRMaW5rIiwiaWF0IjoxNjc1NzYyMDkwLCJqdGkiOiI0MzA1ZDUwZC01ZGRkLTQ0MzUtODMyNS1iZDczYmVhMWMxYjciLCJ1c2VyIjp7ImlkIjpudWxsLCJsb2dpbiI6bnVsbCwibWFpbCI6bnVsbH19.hpHCJeU4Jyz-DM2NBUdB-tQW_E0-tu9H3LoGhsJ7kPHkSsdXJCII0jxhyPb9gwDsgd8SnlRZF8tZDDjnZSoztQ + diff --git a/src/test/java/com/gitlink/softbot/service/market/GitLinkApiTest.java b/src/test/java/com/gitlink/softbot/service/market/GitLinkApiTest.java new file mode 100644 index 0000000..10d87d9 --- /dev/null +++ b/src/test/java/com/gitlink/softbot/service/market/GitLinkApiTest.java @@ -0,0 +1,77 @@ +package com.gitlink.softbot.service.market; + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.gitlink.softbot.global.vo.Response; +import com.gitlink.softbot.utils.GitLinkApi; +import com.gitlink.softbot.vo.Webhook; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +@SpringBootTest +public class GitLinkApiTest { + + @Autowired + private GitLinkApi api; + + private Integer uid = 85175; + + private Webhook webhooks; + + @Test + public void getUserTest(){ + Response response = api.getUserByUid(uid); + System.out.println(response.getData()); + } + + @Test + public void activeBotAuthTest(){ + Response response = api.activeBotAuth(84993,800,"auth_active"); + System.out.println(response.getData()); + } + + @Test + public void updateSecretTest(){ + Response response = api.activeBotAuth(84993,800,"update_secret"); + System.out.println(response.getData()); + } + + @Test + public void updatePrivateKeyTest(){ + Response response = api.activeBotAuth(84993,800,"update_private_key"); + System.out.println(response.getData()); + } + + @Test + public void addWebhook() throws JsonProcessingException { + webhooks = new Webhook(true, "json", "GET", "123456", "http://localhost:10000", "*", new Object[]{"push"}); + Object[] params = new Object[]{"xxq250", "ruoyi-vue-pro"}; + Response response = api.addWebhook(85175,params,webhooks); + System.out.println(response.getData()); + } + + @Test + public void updateWebhook() throws JsonProcessingException { + webhooks = new Webhook(false, "json", "GET", "123456", "http://localhost:10000", "*", new Object[]{"push"}); + Object[] params = new Object[]{"xxq250", "ruoyi-vue-pro"}; + Response response = api.updateWebhook(85175,params,1082,webhooks); + System.out.println(response.getData()); + } + + @Test + public void deleteWebhook() throws JsonProcessingException { + Object[] params = new Object[]{"xxq250", "ruoyi-vue-pro"}; + Response response = api.deleteWebhook(85175,params,1082); + System.out.println(response.getData()); + } + + @Test + public void getWebhook() throws JsonProcessingException { + Object[] params = new Object[]{"xxq250", "ruoyi-vue-pro"}; + Response response = api.getWebhookById(85175,params,983); + System.out.println(response.getData()); + } +} diff --git a/target/classes/application.yml b/target/classes/application.yml index 5e8ef5a..7866537 100644 --- a/target/classes/application.yml +++ b/target/classes/application.yml @@ -58,3 +58,8 @@ logging: mapper : debug elasticsearch: url: localhost:9200 + +gitlink: + url: https://testforgeplus.trustie.net + token: eyJraWQiOiJUaEVSLVl3Ukg4TWYwOHM0UnJLUDYzXzZLWmVET2NZckZXcmdzN2VUVWdrIiwiYWxnIjoiSFM1MTIifQ.eyJpc3MiOiJHaXRMaW5rIiwiaWF0IjoxNjc1NzYyMDkwLCJqdGkiOiI0MzA1ZDUwZC01ZGRkLTQ0MzUtODMyNS1iZDczYmVhMWMxYjciLCJ1c2VyIjp7ImlkIjpudWxsLCJsb2dpbiI6bnVsbCwibWFpbCI6bnVsbH19.hpHCJeU4Jyz-DM2NBUdB-tQW_E0-tu9H3LoGhsJ7kPHkSsdXJCII0jxhyPb9gwDsgd8SnlRZF8tZDDjnZSoztQ + diff --git a/target/classes/com/gitlink/softbot/utils/GitLinkApi.class b/target/classes/com/gitlink/softbot/utils/GitLinkApi.class new file mode 100644 index 0000000000000000000000000000000000000000..c49f79af38c025d2abe372ba0a84cbb9dcd3177b GIT binary patch literal 4744 zcmb_fYj+#f72Vf*jI79cD3DZrVMs##%oH~?i5)`hVB*A1;@Gm25NJA*uBEZ088I`m zV<@GC7Fzm#{0F|$t}au^YJWg~L%;PiKLHl|&Ws+GC&6a*gJ$mB$GQ9Lv(LF#|M}w6 ze*-v!zos#W*EIYnjXu1V!hH=tP9ve3hI$wJaRNovDjk5tS_+raD5IphEB!FBu3FU; zYAMvyY+7m9XlQsnjVF~ACk0n6_flx8`5P&0s-Xw!V@o~W(C}soKS|*&4L=o#tt>4F zWEa+r4MVRPR#{*69MdXK3FMZVmS@)Gs_B}Anw+*Q+cP}Vwp@WT3$|0%-G-XF<`{Lk zX**TDAPvja*NmcPJ6pQZUZAfUwWg%W#D;1J96b4E+4O3rRXyEwYHx8Me{+8JhQQ&@ zfM-{w#i5KNT`w=|jhf+c>3HPMo3fx6Yo@e3eW`0Yw>%d)|B*54Q; ziw51J$AGQEq8!_e@mK>V^@ zqP0T{rX_DQ>jmlL4N|WHWEYLvs^OUGJM4^m6_d!GT`1ahJ>*k&?KQ7pd%6PZ>Q_vU zwyM(&QvohZZ;mcWN8rfN@J`4aKels|tww93v%Qn|>|cgkuDH^f*;+A60xt}8(QwuB zWLY{>!;$#QHM?Nc^bK1Dv_a7+{luEe%FzfT0tZa1(ezs3N>MfbDuJQB+dq6=dKEi} zx%8w%b`R2n+pSEqhMMkJwQhFayr>e&ps&1hM&4-Uo;T^WPVS+gw{SA26`XcGD@!mrYel4s~k6X~l)W zNMwmrDw4LxDxhDs>&zt<*QpGCfHSNfK8b!UoHN`C6~%xk4{gVM!#^Vgj(3O-T$pK^ zHNW;~GtzLRGnm28@be5ta4Lg$@UDhmWbjM8r{Vn!#xSnoR~h^oA7pS6r&t?xqhaz? z(wnR&uFkZ)uUhv_Yt25rPMv2ki75@g$>6v6oxrFP<{pzlKvUNBjps;~9?HmqKjKdr{8_>LiyA-NaXU!2067T~y1>b(Z0Rl40u#~Li?$>6Yjkzd zv5V4mdHA+dm~}wqwZ(!k-Yv4Wd^)&xgoAY;<=H`(z!R-Xzw;_E(22Jn>liC7kJj#e zc2~WyCp>3-gJD-oKz?7Cg#ss{t`rr|Yv^-)1eKXbz?Ip&z^O>d_DrU0Bai00`<}4E z!;&Y6TE8S;Z}J8q@V}wRJt&UIn?~g1UO>CkI-=|=jyPnIycJrnj(D|Tol zB4WK-i7(z zg73u0#}I$>r~HslwHP>xvwUWP2{?!I{1U3L(5PCx>4OA@AENK>$A~SAX5$Z$U^AK3 zwvih72m1NiM*0&Rh~f6=M_d$x+TbAHpsy)BL%&Y=8y%xr8Vff{aWp`FfxQYu&@;hS z;L8haUBrtam=8G~=gjF4%=NKsW^@|^!PbOw@b5SjqT|0MBEFWcT@?F5@LS*#WP{CO9@rkO{#h zip-aBg_9JSpK-ayw+!)5#&hv*4<6!45_@bi5$($Hz?HEU|KH&E_%?FcZw3Roc+11d zWG>n9@fiOgDH-$=_i++CNQ?yvL`8ls0MzzVhJF$x$FBO}lDJ0SV_g5L?|YmUW-*Ti z^$(8yiiKpGg<#eM`MXa0aT0LD=VKt|^D)QHYy1h^#A3+He?wmKd*kI>Jt1!KlKplr zo=cFC?}UMlqTwvvI7b@J(}_vkqR=}uHJ(61hZ_Jd%MtzWWFo9x0DRE}4sWv7_a*UXi>=b}o^fX|gke z3PY>dSqfma*{QbKskYgvh9V(+pQku26?~o&v^DSZl%&N#E?Spd)T{|gX{TI{#COOg z;A(}b6x5}CrqWaU>9nC@6wQLv-JN=B~?&%CD1Bv?~#r8zc6?= zHpWu9+$t`;N%VABLlQ0dJQGwGRoWk4SZ-h$l# literal 0 HcmV?d00001 diff --git a/target/classes/com/gitlink/softbot/utils/RestTemplateUtil.class b/target/classes/com/gitlink/softbot/utils/RestTemplateUtil.class index 1a0c55ba1e039e66a42a39746ce4b51a4439577d..77ef41d36cfadb66efd20cb7a4d891a4fe8cf191 100644 GIT binary patch delta 1384 zcmZvc+gDXp6vls>1FUm43*|mMV1+~q2bC<%QY;lOS)?YZCEd`7Aa3c=GAj)2o~3O| zDZ6M{l$W?9k(qSASRnw+`cnHHZ`+MH=Oboe~LdS^C7NxF5T&n6!9DdQo-<|q$G*%IRs z9`zZ^V}?$jJhmDh_bG5$3+Rfn&8^#=d19{NNuTjFW$=^(e41yRdDfZde4b~AGcUw= zk)1xfc*!SVx5Inc@QPti-?5)PuX$j5%GuPsy@qa)G}Ibi6}IP9mIYoUKRBG)6|_Ys z1xurQ(i2p8lm>mVi-Jocrq1#j`z){XhT%=iTkN+S;BAkr=K4+bl`Zvcjg_^@^-XP! zhIcFndDrqDJs$S=-fh3_?m2U!>&(!Q<$XRd9I_ndh-DgAc$5eu9&C#hXB@SBNUtS9 zUvM;57D><_{1O|VH^4_8UZrJ#W0pZa_Lv;(GI_ypdRkE8=g%E7d}2Ayr}E_bC#S!&pVGJ;WgD(LpB8 z%8X|YF{xLvsbYpuvSk;D%|dcntZ!tAWZfv8HLT<&+O#IQSzqT0cFNPuDvkPTdbm|H zcAExj4X3FKbsbO*v&85I)iKJ-PU1>bqZWvmQZ3c$o|dsZls%%f)hdPat)Mn+%m}y0 z=gKxBu<2nVM+8|dfzIdJW<>JHd5{_U_*RQbOvI{0XN`*8BVl#iPG^P~7I6o6s-LHo zz*RXjta9QXh*{?$T&MLX2$S5UB%|?*6z_U4leFA(OyAAb*wT5+}z2}0h sGBn8PX+Y0bF}Wyg+=QsqBi%?b(u!0feMlMMB#lndy{b#2JSp7wH*#(C0ssI2 delta 1251 zcmYL|`&U#|6vsbzc$_=eGdKNsG-5O*p=FtqT4^sc zuNjn;VHRZ%kWwTQ`^mLhYx*x-^(Xj)tNNY`)~vPnId`9Z_V>H@_sog(k(%7^e~+I7 zZsL5v4P*?P0%ByG>vnE)z%%qX_pBis@Ep%Ox5cN|tuF-hu{B^G+YB%IyyUYz&datdCz+`{Ad|wBuoYk3r-qFEkE(I<6WlQ(84YHipO;1_`(udj9W!g4N~BEBvTC$kCYgr#sYPb68cQ>b^Ob9 zA*G6U&>D48MH_c2{y(ydELFrI7vRl|K#M#@uK+G1&RyK?`WAi@#gynQUs*gxVt|tH zeClK_U1{f6##8<&=CmX#6JyLBR!(6w(>C>s@O{-R6;`#XHL_go+{68>Agi^H``E#1 z4zP{^+8LySA)Su1o(nt}^)jeBNwHY2+4(xF)V&p&y13+6$-UZW%PN&}%H~zBHIg&W z8rDW)Hi>_ry!iV`ddXs9#xUa{H4lwb6-qR>1E0!`9FF~3BzNC#|=*y zIwSw&72jfbNsE9+Hcm29sAw26#j-p6XF08F4lWmEdmN7S1lJ?K(uJQ)F2kMrIX|k29iviISJ6#_D5f% zzxoF4s_1H0`v84`zD-xZlNpjA5v0|%Jd<1f7@;K#RYO zU*;{SP0`$7@vo+ z7{=oeo`mra;;=mOy%>oG^J(dT@6>`wv#d3f@9?~%Z`~7 z>$bCIB!!uGjb$?>ZD-RkD+i3JqO{j7N2D1xP_)t-+TyEb$uzQNK4Z+~rN{_}@51XM zxnkREM2OX;S+b2s-WKjYJYnT6d5s~vdlobVXY4dpwork%Tg)YeGjEc&hG^VQnb`%? zvDDmO49XRYFhg}=T;Y_glrVCpvnFJXE%U;aL_U%c@*y{=DOo$hEzlN1b=M7-$=XRX zYmoc{e*Y71)MM{Z@%x|9q;3V5LR`pAsa$YM;>+v1s%`egy8CsC^9)F4O{Z;(^0~DMbeU6c8(R{ zNn9eLvTbQiY-%`DuP>?v7s7_3!i~XI*Uq!*ZqClr+=0QN;gL}dohwon#tb8?ifzSq z<=DVw{?nlKYB*Z0cF%W4DHPomCGu+>7tqZ}8yn9CM|hygDcYM>U#Tei3XZMg3ck@X zfp2w8;<=9R@La<{J+gb2t%gB$X4!OEX&bq$v1+E)D1`ny!nnm>_Z>SWT$e3fsR#|N zRpx%5Y6z9gY*E}}t#o$J_0-fjdk0`<|+?Ik8Ed zIcCW&vPC<*xR!0OQ}Qw)9bx8J`(5>D?rv8~CeiDrWI4BY*D9`bQCr!kod7(hYFcJl zEgiMe{8Q@IYTD7~8j`j9w*9Q*O3f10FlXZj@Tn%L?6)khZI#N$wZi;$dh|mrqwVG0 z@b7A+&K;$ED%7&r_NC6=y2VoM;)A%fL-<~hyIN%Y9kNKht?=C}4p0%z)k}SPb1u!B zHpXujAbq5gh&JOc=p3eq#9haZHx%h14I&W)^7de~YdyUWL-j}@mq7APQc!A*0 z<^7j9M))55XbGYnef*_+yU`DWGYyv+si7Px!Kd1LtoK(O;{V_l4#$5%=;9W_TWG9? zY$j3Q1Vf!9?NjBjo!(JDtd1iXz#zkK3mGbd4OhUPl8^$6DX?gStXl&yj?p7q(Dy)% zp@SBkrAbPRhZ^%yJKlggvOj9m-l$zfy+G9N1E7xXkJ`L9>LsG~5w-sSs8@&@D5vvB zG?nvoxA%9nECyfUXtXsNjkZPGqaDFN(770h9!tE$doOVOkT*S%SPVu_CgSCks6x8P zU&ps_>JF>m((6^wi9^i5ATu$>LNYz?=5pIZy7#B=!EzTB=Igj?Wm`nQF% ddvKd0w_D_Po4n%xi(3Oerq%|0QmKh4;9oy>Oius+ literal 0 HcmV?d00001