From 9390c4651f65574b9e5ae7fdd365c524e61c483e Mon Sep 17 00:00:00 2001 From: "aman.jeph" Date: Wed, 15 Sep 2021 14:16:06 +0530 Subject: [PATCH] Adding screen-mirroring-sink package Change-Id: I8e8acc9dc881e21a8c3d87f3403a818e2de2105f Signed-off-by: aman.jeph --- LICENSE | 204 ++++++++++++++++++ build.conf | 19 ++ .../org.tizen.ScreenMirroringSink-1.0.0.tpk | Bin 0 -> 50520 bytes packaging/org.tizen.ScreenMirroringSink.spec | 37 ++++ screen-mirroring-sink/AppConstants.cs | 20 ++ screen-mirroring-sink/MirroringDisplay.cs | 24 +++ screen-mirroring-sink/MirroringManager.cs | 127 +++++++++++ screen-mirroring-sink/MirroringSink.cs | 192 +++++++++++++++++ .../PermissionEventHandlerArgs.cs | 22 ++ screen-mirroring-sink/PermissionPopup.cs | 117 ++++++++++ screen-mirroring-sink/Resources.cs | 19 ++ screen-mirroring-sink/ScreenMirroringSink.cs | 123 +++++++++++ .../ScreenMirroringSink.csproj | 28 +++ screen-mirroring-sink/ScreenMirroringSink.sln | 25 +++ screen-mirroring-sink/TitleBarView.cs | 189 ++++++++++++++++ screen-mirroring-sink/UIConstants.cs | 20 ++ screen-mirroring-sink/WifiDirectController.cs | 175 +++++++++++++++ .../WifiDirectPeerController.cs | 36 ++++ .../res/images/dark/back.png | Bin 0 -> 723 bytes .../res/images/dark/cancel_button_bg.png | Bin 0 -> 2749 bytes .../res/images/light/back.png | Bin 0 -> 785 bytes .../res/images/light/cancel_button_bg.png | Bin 0 -> 2914 bytes screen-mirroring-sink/res/themes/dark.xaml | 29 +++ screen-mirroring-sink/res/themes/light.xaml | 30 +++ .../shared/res/ScreenMirroringSink.png | Bin 0 -> 10097 bytes screen-mirroring-sink/tizen-manifest.xml | 19 ++ 26 files changed, 1455 insertions(+) create mode 100755 LICENSE create mode 100755 build.conf create mode 100755 packaging/org.tizen.ScreenMirroringSink-1.0.0.tpk create mode 100755 packaging/org.tizen.ScreenMirroringSink.spec create mode 100755 screen-mirroring-sink/AppConstants.cs create mode 100755 screen-mirroring-sink/MirroringDisplay.cs create mode 100755 screen-mirroring-sink/MirroringManager.cs create mode 100755 screen-mirroring-sink/MirroringSink.cs create mode 100755 screen-mirroring-sink/PermissionEventHandlerArgs.cs create mode 100755 screen-mirroring-sink/PermissionPopup.cs create mode 100755 screen-mirroring-sink/Resources.cs create mode 100755 screen-mirroring-sink/ScreenMirroringSink.cs create mode 100755 screen-mirroring-sink/ScreenMirroringSink.csproj create mode 100755 screen-mirroring-sink/ScreenMirroringSink.sln create mode 100755 screen-mirroring-sink/TitleBarView.cs create mode 100755 screen-mirroring-sink/UIConstants.cs create mode 100755 screen-mirroring-sink/WifiDirectController.cs create mode 100755 screen-mirroring-sink/WifiDirectPeerController.cs create mode 100755 screen-mirroring-sink/res/images/dark/back.png create mode 100755 screen-mirroring-sink/res/images/dark/cancel_button_bg.png create mode 100755 screen-mirroring-sink/res/images/light/back.png create mode 100755 screen-mirroring-sink/res/images/light/cancel_button_bg.png create mode 100755 screen-mirroring-sink/res/themes/dark.xaml create mode 100755 screen-mirroring-sink/res/themes/light.xaml create mode 100755 screen-mirroring-sink/shared/res/ScreenMirroringSink.png create mode 100755 screen-mirroring-sink/tizen-manifest.xml diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..54b213e --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + + 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 [yyyy] [name of copyright owner] + + 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. + diff --git a/build.conf b/build.conf new file mode 100755 index 0000000..7831c55 --- /dev/null +++ b/build.conf @@ -0,0 +1,19 @@ +[general] +profile = profile.device + +[profile.device] + +obs = obs.tizen5.0 +user = obs_viewer +passwdx = obs_viewer +repos = repo.base_arm, repo.target_unified +buildroot = ~/GBS-ROOT + +[obs.tizen5.0] +url = https://api.tizen.org + +[repo.base_arm] +url = http://download.tizen.org/snapshots/tizen/base/latest/repos/standard/packages/ + +[repo.target_unified] +url = http://download.tizen.org/snapshots/tizen/unified/latest/repos/standard/packages/ diff --git a/packaging/org.tizen.ScreenMirroringSink-1.0.0.tpk b/packaging/org.tizen.ScreenMirroringSink-1.0.0.tpk new file mode 100755 index 0000000000000000000000000000000000000000..6770634ef4f41b7818d61e1189425e8f466564d5 GIT binary patch literal 50520 zcmYJZV{|4=(6t*)Y$p@joY=N)+qP}ru{E)6CwFYywkA5ydp^~l+N-;Mb*0s;aJQf0@eqGNNrI|Bm((uWBG@;|FaZmyON&h#!;7WPK2Zq8;5o_4k)nyZZ) znwWm4w7TxoXl^>7phc56G-hO}O`e&`oTxw)sk>)V-|NfG7tgY;v1>0PyBS0q${Oz5 zxIY!2`x`+VzEAt~PWTLNuOvPn<_s~FKX)%I@Y8k3f8-V!7f;eVWr)zjjiC7jCxiYf zq%8kBehNM1^V#e|$8D3Q6PBc?y_l%YTe5tilm zjm*Anz2gg&XCMcvoG)_gsDcRtdPDzrKl4!yhgHSA*Ws&PWtK0)%4vV*mF+xzft419^9eXHp~{&1`NMUj9S)%*(=j7}CF zUnx{}6RBs#R~)2A@a;7b^A~m~O~l{F|ZR^Q}}e zWl~w-hY~%Jhstg-D}oM3l9sPPbL%KR8PbAz$65;C+gSG387M~7w**nlC&Ld{e{|lN zZ8eVr_0Pqj4ccy;C-AW`g{**`13}&Xr6nol^eq4s0Pue(HJ!9LW2B4@fLt~DTNMB~ zprb}Qj}$QTMtrHtB??2Q z0gNxO9HaFh$s>%su7#FefJRHRl_20)<@uD@^Z9fBQ?H^({RK~7O>;;4zxwoMQv3=(Zbxl_LoOPZIE zd9jh*KBZihkSeZLb+!G2{-wAn20o~EJ&seqzT;1+?S}L1J$nO)N1-LA{*T756kH*(6hviLK!%Xs+WO+R-5P9`}t1 z^E-7+d-6VjPH1J5E0J1x*e-)sPKM`rI4c|>KZs@?&rl?>vG>Ac9sZNau5mSk2sq1$ ztDTwQ4bSm|b0Dk9gfOJ^1hAL`EX|WGjlGh-ManXUZ%t8gW~!w!W>KV3{g$$qNky^D zk|Miejl`3da}y`X92mWT_!Jprf5OS3!>0ZiOLyl;^M;>&xbo#-6po7#SO`~63bQeu~b8zKxG54P}y3qDRq>l_yxh zI!}BCrwhpK6c3J($Dq}C4PL0`zmw}ckaCoW&q+0&!J=8h@uVo-j1NkxGmSIzPgd7I zzYu6n`je9S#{}!{L+&hLpz73eyGvm1MNLsi>PIH;Re=_;S=p6V zs_Zj0jDiB7r|)~s5#7S_dUA*>9+jNpym~)I^YjM>Qtbr!AmX6JH0D%)Uj_~rVym;Y zQ)S~C#tFDB#VdmG+3=0G<9X5zh3t>dblP+D^tHK=2DO4k)y&cHV}NNR@e+9Ms7diT zmd$Z@;xB!BGHx`|U$oQ@JsVR9R!BepZNuXnVAzJ8s!xD8$g{lM znr@ODTg`Thh2Ff6mXfs*_Azi3Geb4|D_5OC0<*M8RF@XY%k!7I%c% zUutzJ`QCcuXU73GW&AHawk}w?wB$RTNyEMR6-)RWCzthIxAD$1#%$9Dx2q|P+inWK zf3{1x;xUsZKx;f|bmQ+isSn~Aw@<)`(nZ;Ju8xEh&I0+Z^8*PP|wMCh06 z*YQ$k%Hye9?bE_QhY#A}GE1&JT~Kv5;*!RzP*Np0qArnr{kFdh<3>*eshea*P?l-; zQzN70fy*srl9xnVaGItW<#4|}=qdO0(CwJ#yXHQI_fVqQKpJi6I1ugpX7xiq3O=YQ z)m1r?rf51dEzpNn|FrU|x0{1eh!OGf z9*;P=tzEdNb0mwb6FFPaIu^|fuBy8Jwu7>+qX71ctUP$6Lw1;XFS=5zmhYV~&#=1- zv_Wp#o6wj$-79 zSD21jz$*G^8QHYRchU}QbCB(m>93zVth?nhm_HbKuDfU&WKI8OkFAU-`=d?wte}*| zYcF8H+g&uYJN#f!baf$sR;2%v`9{#1|CxaKQ;xj|t(wpna+4qd>^u7eo!$LzSbFU! z%*#G&TYY+I3jkI8-~0#i|MTB}$oGE(;y-0;Wz6`0D*hKCvM9^j{`!v)1+hRt5dW+A zzi7z(zu0grc~cU#=a80LyMa<1E*>%?5nTzyQm|1_6IYjFPbt&`Vxo?)p4#1|TtZul z)Qa(sR;Jeb0y@D(NO}rpaCTejO_S$yoIKdZiLTxDJu^6?9lg zy@*@3cQ0#L>fqqt1P`|Y;<~~vAOBvyUa#oubZ_K0{Zu&_ZI6eU8J}9A7(#fRzS``o zG^1NLln90Z|H|1_sX|m5$!^ufYwr7@T7wFP;@m{9%j?W@SKsyffwkR8+-n8&z+VmO zRt9CFKyU?OzT!St_DS-FKXhU%&^~Hu(V~PNgaUi701b#YxX^&`rE7ifn}EMk=W5&K zC#iYq!m0qhPpg8$Ki>J}1B?+-P@VYU)(!fyAiQGUrg;!HIk{NH7?eVGJT+Bbd4Fdb zaek1eXgj%|l1~YlVFzpdR~)GJQuQ#r3Y$I(PT+@?{R9%&X-%_b0tz59n{@tl%QY;a zstSN-+N90jf?{eE=)TIh^y|cpJh_^C8YWUnXA|AAR_W z8@S`%W^W`bo1PSS-srETKo<-L?}+}0iFFPvn2iNBw1MEvz~8UQ0;4K#4%~#NgY%=7 zTXS|<{Y{Z-G&zV$T-hMH>(|ML$k7@MnPTm77jpzpqC>{ddWauc@AR^se$;@K9IPcq zf^}^XVRTAh#wAW#tzZB3Bu(?|F>3jYc^vmnMfx4*!lBBPg{f#_P#fOnlvjZL^x6t& z8>uStOU(=l6Ma~#6)9rf{MiJmB5r|^k3#n&y*TC%f(EtwRa12|c$^zb;ADYWbdVg7 zcF$e9h6^YqcJpKEYX5nuury6#arAdL<=Cs8_zkTMsj7klA29Z}@ndQSg|c~pWJDK7 zAausMGjOu}LOjhME{Hk&d_FMlSXB+%soLOo556=iSIU*MpoU$4Wmw5lQnG~r#D$)| z`8zFaPxAtB7Fg05brWVVR$8TDd65y&IX4A2;@c?+orSk`IJA57P_%Oo-YKI=kgXEZe$#R} zUUNKc*^142ZaubWKS>Fif>2y6aNrvjM8`c-ohw7TAG=!#Xf`Q_N{4@cU(u#jIZf2e zW@bN_aP}=BK3Ygb_#)^DBW$3}^8vvx3-jpoSzSYfRbdbP{-1Nhf;7)8Oq8WsiTLd<1p`<-OQXLe#Yt4huWZp)Sw=T|ML! zoS8s)-F3&`+u7`(FIoAzTRi%v*TQ6D-Xh2=w&Mo2PCNV?b#-0YX#8rrdL!92f2Ue906`iapFVWD;`5}f=SEH%RqS)!F4rR_k&lE~!-jf>lz{1MaA&MHq z)9B5KUzXfhhoycA9)(hxYe2gpe#m1M*wyX40~q(AstFTdTa~w}TPYr#Nvn=zE6azL z6?JTQx=O%uf1^dpTRPxacGCRcWPx*vcpE5 zMG3>JOd8;*YQf-}3|4&2?N^9^n1g^)IWhD=u=d~8ziDowqlfx^9VLBkIAy1$iaSaE zSc^NPJ*x8n>l0Da&fn!X^Ma1?deR6y;gWA*MlvXn@{SJ>hw6TN|b$wN^b#jAKhR3%np-y)MJ+#kp}`^n-zai;2!J-8#SukFi5 zx-#{*7lvBu&Ic%b40YpJsj8Q^WLDxhl}sYk8OmprwnFwg^#{)F{Hjk7Yx1h6b6m@> z&dUq?XIFFSU1NaXn1Jd9=xM88{qr^pxkOIbU8E`f{B>%l_7p zLAkHBw(m8lHp5-I*sB$TTPt+g7F|vcNL8l<%C(D+S8FL*3#)C=;bD|+q^}|W0?j;& z9ht$|fj&MaiB0M=)VP+akgXZRTkXBF&{J8kOL_Y+&?VavDRE$6#DiWZ6dXF;Nw!+$3AqOqo2BCL=XV6)rFx{ zgr%|3X}G~U)-U>J+Q}e4DXc%i$EozXC`Ua?;;s!VFS9Sh&I=jWZ#x8{Sy75@5r=KR zpV;&=xHCW3JvHbDNr@s+U$24q>82WDLw}4)d~Exg~PQ zTYf4cU>4qqlubExKl@vb#Jd%FB{aA!90TtWN&3|=HmK4(3GYkWPiv6-;K2<0NuH{(SsfnmfLHn;3e3fb`}~b3zK{$_hQ5M zB=t48;B?h&8CY~DhMUYPqU`VIZI79{9TLDh!F3&dr|1Rtnk(R{xbK} zzhuNf6U;YApo72A%kYHMv9l36-bY=USYj{ZyL8J*sUE3XvsSELG}*Bnp?tt-Vop-{ zCudrX#0EvZGK$*uNQwE0#71NnY6Uno5JVF>pAtqgRfIa>cY&Z_spChf%5&Rt0cAkt zjdIyVK)f3_)Xp>l*9$-Eg&!^luvf zd337KhG4z_b>U+CV^p_jb&3Fvld2%zvzK*&+}3yyanYW=BZNp?;%;aoL<_py{IL*- zb>BU;(M|XQe`=MRyRaPTdbr`!J~_7_e|61h_ z0`mL6WNc;6sAA%5W@ayEY-MkuVr6f`U}|f7?FZwjJCfws!@=r+n9G_h{=f&I z_pzO53{zNdq}NKe+ZP#3j+2wUYIvfPXjzn;W^{Hs73S`0t#!FK@dy>BDjK17B$VtPN|K9^$RJw zcC6LPT4shVhkG;bL=*V2b9Dt4-YTP4ZHn0CQ3`tm#fB+xpXr%}zh*RiG5y|PHLxWo zs$x}AdAKzL65`~UxKfj$f6vVB^@)3jQ4Qn|mj5RB6!Ig2Z4yBTulEyMF3!+^))a1$ zE!TTp=#=1suXTiUP?h8$6l;!Th!^L_3sSvvQgaD#hd}jsg1%^z4p&K>(z7riCyMvsi>}t?5)8>ps{XPSPK59Zj=O_E$lbD*DEvKTkf*E7VGv6 zSI_~ls2W{IwDmUW02eWOmSzL$(772DXA$@^RxDHVQE5-@_2NxioIqC@8Hwr3tSQ#k z+i?w=!;ZWbEXS-J<5`WePu~6!+WLb@d^H4MnhqO$5x0Of+Nw+$EXNcQ95SRKx5fOW zGW<{uyrkM3O&i%$j-y)ch+BVyZjy^p#He#Tb``4QuiA5zCgRQxokk%b*=8@0&I@MN zqFvUzVp*0;>Xa(H!Oc%L5u6{8UO(B`V%I9~SxWii29FnL9{Ttd2w;3+`zhr^>C2$C zQk6XD%v`-1CaQ)j4+v&!TTzpNvlnM>TUjpo$*fo;!$>ErAv=mL!Uu0#kyH2q*jR8@ z``ftIVoYqUigjq~4C154S+iQw0y;QXP~a*lzs8a0qPuIUI$09M>@3i$u+WxI<4DvA z=ej2iP#g5yw?94R?Xz_omt^ss6W%4|T=uI7;ObZS8)(#&iRg)T8PQFWpJ0n5qIx4W zH1m9_l*(4)HKq}$+k$c-!H7A3*Usd=pBmeF$3R`Hk(&1=-t+JE08^bZBTSdFS%7fk zo}s2w$?RC&ypT#cqxWq1p>Y?0cFZNLs!YfQ->67)-QSV;&pAO~KiD6yDnHKEwOlpg zq^!Mn2=&5LUy$yVI5IA5nPr6(v`5@8gAz$Sl8uamxOENHARo9B-^KwAN7v$wbwmy^ z6J4F65AsCov(_cI2P7OeK)V%d_F_*Jb&$G?v-r|QPp`2Db3wQXXIxzKjN{pU>zroT z8vIMoJLIXHSsU3WJQmh}J2e$12v3f2^koq~)p-PJCQ9DAvUtRi2h#d|8LI{4wiu}{ zK_WA-#1^HN9XUF+$n<(!sMW0_OE1C_n{GvRF_v9`%~~|OZ7(~Szt=(%n{q{VU6z}p zb{tWy1nU6f19e{jxACARF|ThNDN%2UlHifoH948My#&J|_^sb&py3N6=URHNoh;Lb z0r%Q^pVIzrw6rE}l7F>jL}^(7?LvL(r_7-=u|=kfE^R3QGy;$U`OI_i600&v@;`dy z3hCIgVhWub0A<$$)CtqiUbYO8T`qE&qN`b&T4*<{@jLE*Q9G{9tknFd9Ns9$&}Mzy zoDLXs$K@T2LT+Wn0ygi$Rlt{(26bASu+3l8|BO?ZAfzug)o)myJdi(5wA=jhd8Zkam3}6Odt+bS8<+QaVsyeYeKw3D(q|l#|cUGw_Rka9N!r3xg+g7lL0mHn}yn& z0j|Q37$ewEpZ|m1SVJK>F7~>*)ck7C!o2+N!A(~t*)a6*nbA4+n!SA2a*FDonL|Db zn8EvQl+?dQ(#d~JGzvSdEw<(MQkQAPfyev|8qNVMv)YEI1=w`-x{wYGAiKG^$$Vm~6ImMB!L|)_+6?f8vc5smpyegNlruQa5A4Ao6jy>01?UexJgJ z{&h%dxF&Ywmm3|Ug0$3zyb#j)eCghu-EWCkidnum({He{AGCkHAGd0oU-O)Y3)LDd zLumQCTj?`f(iy1M7ND%xFcqYCr=Jy2O}cI{6$KY%@OD`3j`(ZFC(2jw%q4LpKW&g@ z@;pgPM27$IH#0<5>}6~OqLI<21J5*T#3rZclxHXcomKKU2+m2lDR%DoviyUCEQ|Ti zvov{nD0mU?ASd-JcGSP~12d>uDa`$_YR6+#5-Skx;--9YgQ=C4sP z^(qG-pE+dB`^5xKJfFFU(l-HXN*h#gy6Zhqv1bo;>-Uxg+x8ai#c0=2RP;&$jygEC zs;gu2Hp zfrM^XI_)hYEs;MqNqFq?_jJgs;BspMZXqdC;QPtmTelP0%_R4^Vlf#B?PubvQ9i<^ zV0~P-CpsQd$~yM=t+h#4OhF_0toN70SI9;xaw#G9mX?~MW16=n6y80o{e!`1r_I6^ zkn44GOmwaK{HG+K)}C_O2YHXg8-GfoI$m7~<)N;vr%Y3&4-Z?xV-+N8EU~))MTVI&Yu}CZA#zaMhDz3*L-3K+xlN#Q#ImerH_qbXVa!)%>+u|t%ykA* z(YQId#7!GnROCIk;2-ers9W38!VA8(?xY^$U*`=dI99%|R!2uSXut2z#1UVo%99+r z0gaclbJ1L(qp}uOLGN@EJzhkriG!llHW0U-e50pq*%kp0YdYF=COgys|s;@uTQ_ zaEUD?Fjw>)u1NG2)o0jXA=H4#Sn1bRpkdayPn7wV9NK$zG_w||l+j^Kb4571bV&1o z_b&PC+>RC!zYBaoeC%65U@WQ1c>fk?S)UBf5Z#cTS!?;$4e1m5qcfJ>i)V6s`r0Lu zPu$1fx^B7)II$eD_t+1iBe?_?qpaCC)JWO$G1-iLRsumVJt=PIk|y+sZ&Zo+Bevey zS@PAM$jS0m8{c0?Lc%$uKw>{?y`jh^sG1&DxO48!CAGiD2Y7A6yLmETeGE^x4 zxW~KtSGKwY*#~Y=djrhSBE^Tc&WQIbn)X{OaC6b)LO+?dDL8cLM5mG&oPQ%N;$eMP z$OklsZYhyg3`#AMxpkKKhg7hVxs{d39}BD;qJE4K;YrjTxU|}ZBs@A2Fx$=P8*&#Sl8MnUL7%|^} zcl)2)7p@>lpF#1jh&Hf%`nH^nPJK3r;iLB^upOF%VCtES#zCD)q`27fP?efS^m%t_ z{uKd?KLhY{_V3;{!@%1<+L!GcwgZN50ytiOYT7P;$R;|d>wdaAwhgks9P%o+r{BL0 zt>Im+zXST6zgIV(f9l9i0o~tN0HrRa-u@!6h?La}_zW`~$Dk291!R^)j9^h2Uk_ZFU8lH`wG$d*W7 z4A`w&f9hM31@j+n^me^3Z>^i8b@KoS=NtOt%qFjz_NpW2tzHYeUQmGheWprbmwCq6 zXyz_zFpQwGcTaX!GL(^8&c@RN7E(g0#`>e`;zNI%KKr%gxJ8DWER=j zLelt}Ge&#*l$QkPB^sh#w?Zn1?(KxQFx~T(G&3;*fBvxZ#y>r3aeVRup7nTb-OkXj z@vqY33eVdRchKWQIx@gi6N%9`HlSW2P3&UiiBl(RMq`O)9o6hh(z6wZOGfo)4Yl*9 zk*_R|O!)ijKF3)Xqb*wl%VHwbp6!glrup|GlF3qv==e_*JjV_5ZvpW*KI=Kw)+PJy zNFRM}wb>PXxSGEhS-4B1fc3bpj{C+6+-wd8#yp*UwUC_#imqdbHd_|A6T)3d-dhV! zI;%d6Fh=>hy9$>XSc`h3;NG)@iiZ)PuJ@CJDO0l^ zstBVxgr7G-4_reF$?Qa-LHJq+Nx32SC=_o{=`A%~$Vu2iyZVvlazkyriJMoD=5}yW z%R;Q$A*IUjsWVFcGz-5*#{K!>+Y%>#wwN#b>FDW0&Ra=-g`#gQFkx2h7v6N8B7Ek} zMD(6+E}=nHxpgL!PAx`K2ZccUitIAWF+5D1?(E^I5fqz+CwMD-)?l7s-4j>iF$j`56^3Ke)|UB&nS+^Fsw$*pA-Wh|_sBaCGH{8^TUj2~LIIdp%DMOA8PQ8&0 ze}iLR5zG6>f=*7YD8&1g%$St4vkx-iu_8-hk^mXWg-@y54x)gC$zNo)tT6w*2zN=X zF~IQ1f?=^g=XFV;Ts(e6jH&-&u+iKs1j$ zB)S=`u}t*p^4SN(4YEJBUfm2j2Km5@g_-Y^L44gs2xN>=pU%EZC*}Jy+)J2o>D{T^ zLf*}~zuC&&&bPSSf^h13_l53`3~~+Lb}ghc(947=wDXf~4S10)|7vf`$BIg_svrCj z?11E8&N=1L(}!ey@ChmR(*ehoeIuk>DTv;0;t#H4y)pqZFa(qp6>@@jgm>N1si7g# z;4VerMvKhd^k9*b1py<#RA1f+sE|ZLUjGa(uW3N%A?(DQ#%~`(yh25tCMQFtcI53p z!~cZuf8h>r%CzHcTHlG4)vZWA3Z$a=!cZ^nPb(k1<37?cQsjx`g&(Zn`4Xus!6snf zS7jhzl&aQ3tGqW5r8!U`(p(1mD{8|s#EH+VvVcptmJA!{!p4LM(ft&~?(vO#A)zy$ z5;^-LmAPn{<;^$;uckw$X}80QE6xao!WpWpXTlvayE^@Q=ypeEdV zfJk>R$}p6sO&`)vuFsb6i>+af)z<-8wYH$a9AXVpFY%?DQ`~~)!1_&$zz;Y47?Ajg z$GNMPfay=>>QI2rU!D}+rh)1kC-LW|@E$<3h&>?{)R{s!y!@31`?XpDBoZuFD|!ZdmbPGtSK zJI#4+JBAYQ-wk+%Jti5#IaQoTN7}&08pI(MYgFMkYB02Eo=>(#h zz`Ixj2~Uk>4H>h@~ef~G)ywEN6{8M$0FG}ay!84xXFy=;rB9x8^ zm3%W#oT0jou9iG#u{S8|+OZZ`9WCtE5x*Sf-OjtVKN#{%?E9Oj{;&-&5(;n4MSjsvX#j9!*Vs#_tq$P$ex7rL@w zoLguM%L|OAs%r5}Xy~vy^UDNztDD6jJ=dC^Oz0Gr7ElEBgV{tNX$@@DpSB^uyt-TI zU#?q6yV9Di*7BcQ*|&!356UYe_D^NwzQRLL^N9&QRkGc=mAS2n! z^a8UP3Y`wM_>-Ppiw*OXzS*k=lG3RB@|LQ9LKQ(T{e^FvVe?9ePfI_6U^S?=`sOvD zU!?KocOKu9_!(|cTq^1calA71OgCM_t%)zY z@Vz#3IM#M{Pn=?}ydkw)xd+ZtGxU|eTf!?|yO8m%#_pvaDBI<)msIbyF4$iBh9st& z)w^NHAU@r+r`n)^HN$vI^aiWnVR;+}ky%DT!{%zpt-8jC8!k8ImfMy(ML4ajFDl1z zG=u)@6!k7GRK|5J>p3?2NOtU}+MZ?GC%SO6t(!TQd$${QGj5J$izm8J2A9oTI(zr> z*-gLfca2?I`%hcfdi9WA9U3-kBI;P(acYHyZoNGhDt|xQr~Z^kX%=Dl#>&0fk4V~w z?Wu1v*fGhiENi5as?%QXz+Ml?8a7nZj&#b^>#o=hQCUW~HP+Ti@B8Wpaphe9%qck9 zVdF_N4WlfqTQAFuYFGtiAm z)md!!R(^S9b!R_>nL#kl!46I2q}1Gt^da%bbhA+HSnmc4h``p2b@MJ*b2U)iUCVHWIEU|WD~ z1UIavFi*h=Ti4lUbY0O;z**_vcmP&nG08zJn`S@QMB)@*nV>;|;;w#xBhSXAFqn3s ze2wNPt#{agG1+%-f-{ULR3ks2{*02rIQdm;vB$rr{*B5D8L*%qrgTCVUX!=lfa!vJ zTz+SgL%NvCl8{KKctXQyvkc8sWlml0SqL}xZK&=NP{7NVBrH^e@u6^)D zp0v)emip#5Q#&pN@*fY}Nu*Myv8EA@JzP9wqbCR8a@AFTf++)N(`jBS*e>{hUUcug z$NNQfR0!4YUO?2VVr*If!L*@{efWu%Y>2sn)WT&HsXGnhI$kzpHbCWQX-glxzL)`f0j10 zI0t=3cy3X~-*{}ejILumc~|1n!TtJ_z@*miLVq=ouCJQF ziQM!Z@)=b_9ne-;u8TGKze-pxn%1>f zXS*G%U#9G+BVTSadB3>Jh0d?&Cfu)u4KBQ>>&zcU`2zXS#`2%>gXORL+~K=$PS1CP zN@HL0t!-Spet}4HaYD$f;#E_=&a8S;TZr`+w0g)1R$%VN+^2=Twkh?*{V6C%pWSXF zp$o_2<=2EXnvQt1g&h1s7V<>CKt^QpgT}OpYljNJWzB(o!yCl8qYr)D>w;zme`Gt* z^1>W+Ll#>@q(!ke@n#(C0Qx9C=#~<8e~-0)VyFLbqzjRs8Dkr9CK&My`G=R2m#AYS z%w70sO)KiGqKv=wiycD)9A3rRx1x^;-?ckF|Hf?eP9bk?!3`~2mZy#Glj71J>C%GsZU*NN%S^<@>g=?V2=?8qd39ls+|L3I9ai(a-P zY%+o6N+Wwcnbp!}&7SgD;9@cc#{?G|_f$65nR|x3B?Cibq-gvI2 z-HY$!*_PPG>Zo(wJ@a4sO7>~BC_V*ChHg}V)EB-GHn;t`CD!s6DzqAQxR$0o$#ww!T6qYNPlP$rx>2cFy?^VNBpT? zpg}uduCqt*q@T+IEpxvayX$TSN0!FJT-BkX6}PMRhL71NR%j;j7z8dS2L%w4F$q|a zbl@~C>UtXRq^K(Y2!Ar_@uLFZEwQS0h0|=tnJVAT+G7*huWfX+H8r_Bo={lME7)pA z{Ym8!PNEU44w_DHFbaI zDpRC;8Wv~aUZv-#m~<)0Bb-INUT7jcH{G?A7HH22Pa2SKpN4IUQ`3|>i~!(|_Dc%y zg6M1%GWsXw*=}`o!FfwKJq^X_Z70q*L3zi@^8V&X_Hn8AbEE@c&m-X_Uc1MVHQpQf z5fO+Cd@)5JPyXqZTEy zB~mIuTocd(*S(P%Zj6X~s+YQqEKN9CY#oD&XnY@5CD>tS0%-^e0!KWJA?Re`lAESE z5bJ5=f?z(tbM|0CN+T5^m9;0BefmB2^kk`@LVd38L5fqJv&Gn_YhHTf@C*MY_GcE08P?NBUIm z#@9hAf8^;rR|`-dB`%AVjmN3sWKo-@%!aI|zCt%4(<^Y|$58_oLtAWmZr*G1cJX9J z;jc{C3{`~Qn6lmja+!1NBoOh|&@TmoMKBVGNwP^3G!{(EgQadMogvQ3A^}#j#|t>S(j$ zOj|j4vXGOY=`AiY~`bmy!7%_V&0r3c|0J3@>w!n?YoG^VpT3EXZRby4m zY0KLfv+~pdz>lut+ zBJB1AfAla}T7|=kl%)})x;#DJ65`j~_+CNYPAYqRlfbVI#Z*o{69zlP3YAr8-$~v=aQ-Lq0%8GTgQ+CqHMhIe(Y-T69#`ljs#hI!j9SYYB5r zzuac!8SrYs1blm9*s`$KQAmoL=4i{ro86x(FVX_P1>8AgFEf;NK=STf?M`M%pw zgV^hZl(bg-ylD}>Ux z7OLYwsq;sMGqp)cKqMxNP3B4h9IpICtLLK}8t7~`@B#1f5S*CYItDqWpUv#Tn) zH~dfh9ZK`6&F4IEbaEt93OTBcwDv%pZHkssC?^d$bB}m3RCWv(m>f^=ZEC%0Uiax6 zQ(H0~QIudf*8l-|~IrVVeYXj&ByP#q(c!;&1)$y*!MyB+}du2i;}#|fkyy@ zb#N#|DY9b9b7B%)IL>GK0@+IeJc0iU4~Ipa~UnYtoS6YoXQdm2L7D+7~)JZA0f+<8ra!Is}wPLa$Te~ z8m*ZwsKr#BL!lL9ih~f@Z)eiT7s+2YoS!M4P@}KN(C^G%9W%Q&Q%j{-STeCC@EK8l z;wR9i_9lU}6uXugT%@IGI1(jX(+N$~;4_B|8Z2%PD66&E|K9e{70;M#G!&fN-IyZL zPE&hMa(L|+E_F>)Jo8-&s8&bs_KZlG!RUXh<8db9M_X`WbE8Fh(xA=C0#R|P7g*-J zT*(0A=$c{eZrSa>s2!QX{!lvwa9}x{N8F^^Ch}-L_!^6<9xE)t8!#Owy>(mQ3mjvb z7k0yx<)pEezN;_GTJx02IyQsS6jX$7`6#5-Onm`6c zVko7eKGBhn#Jy}C{94pUx71jxC7g+-%c|FN{V*w3m6D<}3*U}FvcQw|GEFMGJ4Q)J zS{SY2F3zPq&}!tsM@173q(UJq3+A*jiE0(~Ws>qiT~?q#t;+p4V!|SMEj5{d&wa1I z;v{Rxpl_!t?M$Gw`kBZYb{}GRd@)4jbZHXa?Iv_mj2wUukVU8|S{o6Ul#n(W!3^^0 z?Ix17fV*~)EuRwHQO%f)n~Ivcq12dD6X%~sbRy0H%i+M^FvB5M6NQ8-<00<^?^>7Y z+hiwAk#s!iZr7%Siam7H<+W5e#)E$YzsU+siE%A6c%59{PiycoP@#u)E*(J|}erPb0-MR$v zZX>LmF(TM*%-9nQJ%Z&7Pu}eO^{hWu-!ejPE-Ju%5OfVxFY-Fr{&O$~v_A!BxR5X( zB@~kEJ^@kd6A?s~%EyTQD&nz$1i@1@5PdkqO8|g?Ekt94Gx~wDc&~s8=x2hJJ0!Hm zk^mAdu;_9>7=(I^m2BX1vdeNbl#te-n3)M?uEsSZMr3Z#lRjsgbI;M1ir-}lWr*g{ znM~j{Wzmz2ho!_dKn`!LCtIy#Z#-+a*qjrFpu_OW^)VgrIqYh{qK zx6XrJaBKS4-n6O~g1<=x3-x6<-q@FvXu3zcKUl3JgqS{;vBGpoc7z zIbx}ohe)J%a*mOQyKS8s3u>{qKIADU3R^*D6bfmb&))4Y&=Kw`=9{t-i5FTjUd#Fq zz);^J$kVyNlPG*S@Pc0_`eW|8V2_MK(!pV!?U$Frl;iK0B3aWY1j6K}VDG#AG38c7 zBGB-tsjCoNys2&PwfeHt_fe|xlMlNkFOW?pm1E6Bvnz!s(N&Ka#W{PUuQjb zAjdUYq&CuyUK_7j+EaTLO@kWQ3Gy`~cfji(gl&=$Pdzo(LPm)J=%@a0iyIwd{wr2! z2^_STQ6xJ2sUu2dYpE>t=uXLHO>8(wH(}HDkm`jHjfe~+d$-Vz}}bbaS2N^wmv>C&&KzlFVS2=dS&diu&B=`FSJA z3kY%)TO-XN!l0Tpe(*oUNTj(HlRln5vn=FsJ&}88|0Ir5*&ZQLAQk0&mIHN#@rv~< z9QXb-%40Q5<8lQeJs!yt`N1%PhpdGI-4&$Mjq1>OQz3V zVypcg7CJ1k08n1dTKYw{{*)Z@Z&rSv#_C`Va$B|iE)tu^l(?m6bfazco9r)#pp++1hMEDy&kWPY~A{4@@y`#^QUVI?3x zOlo1h^}tb1pS-S=xGtdv@ATc_{7~IA=SARhtnBr*azebNV92+B_#{wNuaLTEP7EaL z*0&(6c!SXs0vk1Fi0U4Xk>Za=3un_IYsIiur}5^$Z}*reG6?%s>}ggCq&64xX9vp{ z8rI?&fmic)J!Jeg@4yOAG+`Vv~ft3^(V{0&c=uFss2vp;%YF@ZN>){2UmKQ`S-LrAa(V&oOM(D^^PrCNNQMJH@?ei13gIpGYa2*?1ZT;qCFHXld8Q zep)78X>ZshRqHK0Kx8ExO4R66_{x_=OKLRM&tE#l4$vvo9x5MMMmZN@6`w4;>-S!_ z%xqIc8dz@VA7PZTPnN|Fgwc!htaiz2B&O{}yEo8-=3WU6Q#t*O`UoCg{dz0sUWH+i zBr5{RYH@!sJ)ol4(6?0OVyRt8S(L~vNh6;wGlL|B_qaEHBwMwAt)izz%& z@tSb{;vIZ2TaZduL|d-?Pce4rhsCzF_cS8!+3eOeb8F8?*e;csr7QMtguoLA!sPS+Ie<*qn( zadcecY)>9JxDOa#v1W5!MQE%XtX}72OY>rRLN z#nbCkLT?Z0%c(4tE6rHV&$jeHe?2s(@(h- z$FS!4Hv`u9ZcXTf6O};2Trd@7`#C(qSS2Afd==qz{03E`{(a-T;O>`lkky$Q|gfHKyupW}lpnfB)l# zEdssxe7oI->ml9wi=}S6-NF9fDEFRgbhhJWMD%RW_2iq;{mcDVD37pGs%yMgs&0T* zA8EePVFM=J88;ZoEX&Rw#a*bSA;$d4mVsTOkxbm019aZ=dj@k#(M?xM8-fSHuWcf) zzb2Db0|+J=PbJ?r@xbUC>Im-fG_z-!?JLZyKpvo2@=sdHmG3|4#Pv67w4zNh!=^j5 zrnHZ%)W`PAl_mbSn`@)jlJE{F7U}a7{Ab}E=1Gw(3hJFqMI`=OKv&z{Tb^^hcsb(M zrNWj}v(G12pf+Lu*ZT^w)taXX4=OKJ+qd3kxed8@<4!(z$@0qe^+vauqFtyV1zrSY zOmT0oyTM#5Be9ic4s%J28^$2}b=?&R<01Xd)Av`73w8`F%v z5mUvMggqTLf1O#g7oHDsKtcp%wT+1K?}N2@f}B%jyU_2ovG;YtqPVseJSWpi13C(` zMe+=W9?N^CCtm5t7)EyQ9~r!lWFED{58%6qGM_&~?i}>fR9A9m_j2NXatOYTFc7-c zK)95e3^w?}#uWE%)^(vJA)(zfz}@d^Plv2%QnVqy1hSb`(CTWUuX^V$(Nt& z1+lsX30g83GO}PWF0oTW&<6QHkp6gMv`nECvgbG*6%2g1C`ieA(5RjegUg;Yi@{O# zANHgzGw?gV*`H4yi{CC5HzzYW8T=mCQ%o1=gqInwQM+ zCxJ`!Y_y=MzMyBpRQVRhI!Rbw%z6xm_v#Y2z2RJ8w1bVSmbNsnInV*nLr`zQ7pNiu zu#nBj${>HXGK{tt(jBncKLEq&oIUPa+n2oNizF&m*+-y?Zion0lpy0U#Vql!Bn={J zpcRM|Zt>lsjnJ}@3Y8>hfo4kE+#$1kK>2qj|$f>E)4PGo)Tzzb1FLD1Tt;3_;(Vlf37Y>g9RLEEg(Bd$IFK``u5Npv0caTY0jtU@3c{O11A=EHrbV;tDDqxH2 zNZg1^Ln%WZv1M#Tz1d=HQRe*i9nGsziZMxYz|Qs^s~7XwQrX0C`Ps!Fn{KuG^+oR= zORp(84Ri6v3@v(eGL7T@;{}p%$p)mwa(_kmI3(lMxmK z;wMDUr%j9@Nove1OkYIwj;rGK{Lj&xf$`Xq&s@Rfn6u_fAgCGk=^?@lwm_{@Q~ zE>4VB^Ve3!Ku&y%fPY@8FPKIT{HY>l8GJlL%0t?ZM7hhg5PI%3lB5GnFROS^6i=pT z52s_^l3QQu!0ao288n%7?I(U2vY9w`8N3LKD{)eM=h zo%ARp@JZFg`JnUX5?N%rqk|942>@z2bJ>H!=Hh(m81T0z#wLA8` zz7(G&DI_7AP%}V2bxq|JFIb)`x941!xpfM6EczLieVpZ7Kk#pb2iVih4jD&4x_}+Y z(cI`MF&6|kYFK?Z?uwF>u_x}vOi=b$&`$Ui2*BLEy1y&tV`^kD-00m{HjaFV!??QP zRmRlr4QkH+>&ptN^>sjW6&zaISh$*GT5oKqwKJIIx1N_je zg}lpa5CwDEjH=KR9B-3w6JjCXzXFa(j5w=d4`0FrAv$hu1;ilvxw>HwiO7k9Hyt2K zi-U*b>cu*^$Ef2XpuG+v1mbPHeCVr;Pr9>2u1A~IRQs{mdQ|O8DuXFsJ*x^kH8dO4 z@&s--A~cci^|jE)w3~>6yEFb&RG2*Y)hub$Gxu(jc-+!!hoEIHp&*aheNN)it($47&8i~6&X5FG-+?nSnR>j@4^g3`m_N{P%M@4HDH;vEp8Rs!FRGwE~` zSxR9|Wa2|$Sb2z&heC%!68%XmjK#$=Rbh|RPBY>tc$6+-M6EH-Qqq#tSs@fV-L7Q5b8RHTF__Qg& z%oBoR6l7dNRgm(MXpSi)!Q?{CUA{Vc^+{XNoWsHW5)$;pi?W>eOfBNZfUa6<}2%Mu)QMf|tgoIpI zavr?H7lzh1q?INFI;#5}0(vyZlP$>qhM82uIf$V&*UTMBNvK?ZCB+GwdIQ;B3{PIk z2PBkNx0?#tzFfO_>PbnT#%R)@)mcoM)4cz?3v`qFl@7}zAuxpVRLAyiKT2Hw zh=FdVJ)t|jCAnqb;xd35QT%=wCOeTxc=y!T9mV8_)mg)vQG3^&+ru{ygOUveSGL zBr7q!N`suDh@V#8cM4SiL`5*s0@MDj5GbYrt3NcuzM6b3E<1=Wx)%~1Ee2iQ2To>9 z!t%Zz*GSa1tq*t4w2s!>GQPMEyXeybgayAvULI1=>+oLA z;W>^jhnW%o{_1BhDyK~|XCzQmlY+p}B;wCtM6KuaXXeuB@NSHgv>EtGx7JfW-rRO= z7y2u;3U}$9)7Y1;NwdEHzV&&Pt2=-2=U((T;|#7Qk?Ov>NEtHceQeYW+(p;yiJ=ol z?pVcBAYiTNdb2~PFzke+vuQxK$;eIfA3!Wl9Dz7kB>j($c#u?lINJc-TPSsk{bK4{ z=M0mE_^fzZDey9BP2JVD`hWr-(n&i1l&4(HMX_go82xp)s3Nd!h+mdFyPM0cG_x6R z4F+>XX@z@5X3%#@kZ{HJ4S0i-Y;=Y_20xWhqjgV(1e6eJDDp>IIVopt}G9T*8#-3aT;x;QvF31IfW>97*tM)9ll6d?1|&| zF85Clk%*4L2Pmuye{peTKX@G%K=3$?6DNx!5|Y3`P!G7(u17$Ix%GcS9lzKIH1A@A z0?;^BlrXeDCjX`pUgg;NiDP8edU&2+vl+* z^JkCAqQQuO7&o!NGWa~_sKfG{XnmZj zxXk&TTRm~=Q38B4>Ka>>c9P7n%|-q-r05z}ss#2`TU#46KbgWCV!bZ(gs}B=_~P<> zHgACmPKh&FqzZ3r?sC7gVaG5AQzy@F+HmV7Q;UE;dW7ui7KZ`Gj_T6XSDXMM7)OyT zYW%trtJp8_6w$eZ3=FS{V3ENN>KHqqinsOC%3~aeY6oB8_k$a}h$ug9F(%k4+53=iqNrssfXWg;sUp;mNhxk=$JATYHrD2a}dL54&zdKmk+>?3Rm(p`R#N z=DAWk_&7a$>IRMo>^)fgQ7~lE?_)k@Mm^ITa;L)NpBi2lo@d27t@o z1M>$7|Bt9JT&=85l6C1}YAE&4er4zN27q8?sN%Jk4`%BMMV&Bt>{RAlz714=QYMEO zC7PM|7b7%SeR|ZwWi~fhqvq%x7Kr>#p%6c`$IJfa8DzTpMo?V+0M1ksff!LI>FK0?G?3}U~~zA z%@%4}_@-x9bh|C7r`B7B@;0f1HbZPlm*Q}%GZC)*p`*XG<)Ts!q)m=`ySy0O7;75!<0!D+Py+u(d?7fTncq)#Y5ioa&i!uRP?OcjQzPeyup0Us}hUmNS4I zC@4yn*=s_|ud1Ng$o{a)sRP?|%IwW(WrZR$@GSZEm>I?cvm2nopS?qy~Y zG$dA?;pDS?dvxn2OMmp>&;!WAt|hf{h{75w*nRoN4HWpq*IGVjb3HEyWbVbn62lyCV%AX51X9Zc&KT|s>(~-O*LG>d@*(;W ziQKNHsK;#wpj`J!F~p7sX)kJ46;?K=G$k>>o@mw)AzsllIkro~(E%Q>{7ph?uSSi1qheed6y?W;58Y4qbCyo85HNv#tbR&HgG~DM0d|FddO)8GA zJ{UL6JJ0m{UP|6CgP4P(&g}URXkGOkXY@mKU7D3Kw_3|iZlW{yURoH&GWv0^<%Dl0Ej>Dak$@CJ-md=IbaC20xj)JG1<;3?hX z*%9ACg>_zP+PCcsc=%`!Jp(CMSJ~qZ5l>V^UA_Anrt2NTm^s(#dH!R2xeO)@D?At> zwu}ifVQqmNC`GCcGpTA@+saURBQcJ35AFIl(O$2#nUk6wCvXQ;xg%ygsYc|x>~1T+ z=mJ``wJVALY3R^c(Rto#BXVZmFhO_rsjqqAYjfj%9GyLwYad)YBk-IUoGj)Q7B!y4 zT1`~tU94LdUOjF~6Yg$ncQ%J697VN&4^7&OK`&h-JSq7bgum-(%j%KkX*+4SoCu3` zmKh?)X1OY}hIc>7`GHhjad?rv+?w4OxF3M~;{V~VUF71Cn|*_~CESPid$?wCT?5GH zItxy%9o*w2gvg%APMJiW2qi;}^|%g+3gjmMp7#h4tDsN+Y^nNai-=3O^uQ0hqm99M94cJ>PIO@MK3)WgA2wG&^@9{`sysIj8WW+`&G(;LFR5|M@96?@H#}P} z7MK?2^0;=Njx#t3f!cNyZ#LW5n`~CJ@%R` zBT&~XaPX6@9Zp^BFEn$oU{)NCj)Su`b9hXAME@ax&K8WLi7#$^tD zsdinTxb9wBDldfaOHVy3ALm?;Yqu%R_2j(c8q9-DzuWQVd>l6vQ<7B1`*IO+n~-x5 z*7V=hJvgeWTj})%h`F4n8O9uJxqQ1EUw6I{eRev2Xui5T>4C)Q*c6s}hmBm##ChnQ zyrZ>iKIFCconzlsgTx}D1(rsNd2NbSf49Q_At|n(a9+Ar1@v^K0YX3UKatVI_SBIL~FQ!a*VW!|7Wu;Y^3f;I2f7GE*$mbO(RLz4- zX9~b`ihN(p?GgacxdBR!KVNU9V9AHrPmiKtD{Wri@B>D@PZ_&Joy?v)T32fHe_z78 z`Y3&{(EbE)N|9f5Y)lNjB#(7HM%zr|Ub{|^t2=Q;3nWs0Wx@=BlDV_BnCNxC^`gSP z*-Xkz{%TFMTSK{3nvRIIIruQM;WF*GDzjS{j3I^NW|9#U_H$(>;9y3$6?a_ z7bVoA%3Wybznu#%zmD?*u8`_sAWrDO&;y&&F)zeQ)mzWw*pw>E-O}?{`3Kp{N#8$_ z{pNxX3_nblA%S`o=;FX(ioxtHRD)TUU(fRI0+^p8_-8=)RNf;&WW<9dQ{u z_RKf#?1r^-FFKQk2>XqL6?hcDz-Lm)$#zKRmhF1K`nvsLQYl@@@KbfGl--dE3A-kn z|HjyJto9EhcF%z3wue~IZ)g6Sh2P!05nw45!tMK2Co>WZm0vgwCEitg0b*aO4$}18zLaVE$ttk8ur-0Aj8njC;ew0}Zr`qNy6T@| zO~jwboBenqMS=!AIlzxk@$!zP($GZ7EC*1UIpaM~O{z>idMTJ0vuUsLw+=y1dw>?d zOUS=-(V-a4B`F2GoqA7Odp^yRs{}zNvAKQ*LlvjB@!hq!qcxkJ8BBLjSQqx8U<^`z za?X{Eae36h1&s=fzgMin1sMFLT9a3cnL!^>P|A5LC+>#(#<)Qx>KmYsttp9It13sybwGgA1S=)Er%%+IBKN)w3Vr=Jp5$tJm zApfDcZHBbpt?m5m8Mx-W?FE0{f*vQs(@fX|1E6_)7Cn!Q1)^?nqz0*fRh?kVNcc=t-9oQ>#g^lmh$^})+D>W2qAdkoTrY`S z*|@JJZBDfKgFF&?ejP3)Z5f>LWG>cs)tTw-F``{l}~Yis!EODEG9POD`jOil>(1H{^rQm2qPQnj|5$iLc4>aUPA zq5yrjv)G4u;e5(`*b5_JiL5Q@ohh~%i9gukPq?Z*u6vcjft@iv$*mL8u3~O(>v}o7 zkl&NeeiqzIRoNfly^FM=JdVrm5m?U|2f*$_(Y{i`EQ?NmA@6|7{Mu(20IvnAC&dqH2k&2N=2 z6e-&{{uylKik=f)(rvU&{j-x7LzM6Lk)!wWW*0s?V~R_U^qHA1Y8pC9)nLM;d~A@F zNL66x03`2vUOFN)W%|5WX^)1StT-t*+mv8i$?I)K`7;^r^UUkg>2o^~hEH|^?97Uv zYQ*$Vasfcvk^^vzTD=8lGO_;^ZnV;R!o()H6KSD#+Tde+6gr>PoMf$oVaM#9LQQox zg^n<;(TxpX_vam48zVbaGc-9ckK!(hBQaOcs99A{lontNOQsCoq~=dtB3rFTzDN;# zdx$FAmCWLCtXdk0l0^&_cReY~ZlXKRKnm#cwfW5??5;unS-r`Tt~!f%HKd*^ITvYm z@)6vrEb+N|xa|NnO;zG&A2K46u%fa1w^UGbO8b3p|9}iRZ1Y;ntI@{w{D8{I$B@XV zR1&9|cr~B?fWM5u2dr9mxG14*n)ngw`p+j%xa<@&G$Dg#y?ak>sx+}&hd9WMhr35w zaq{7JGBP3zQ44DCf7NVg%grSnrzj6v3psGz3BNOrd3u~L=G?0U*e8lyPYv2%_9dYl z-~G1x3`4~S_uxr4`)YaiD8nO9&)C<{p5WQhHwsq5R$80p?Ce=6qiOZuUOceFKO&v) z_>}NMgodId=kM8B(epX05zCtf@J*99&CHTG;o=J5{LRl8hlqx83-&Ru!d@SneqqXb zYYjOA8pm9{r$)=ZM;V*2^0RU#PN#YE(i{F}hj7t16iDYPrFOA6>U4qZU-^d_=(j4n z&~$}6Dpeyr%dxI)Q{!83-gQ&Y=Fj0ZMFYu_Iu(&ae{KyJRrsE~8;VoK*NwiaMXrlA z?AAez`tDx7yUxm*>l_Jyvsz$ji7Efl(=e3O=~atK5@?q~p0b*4IP&JJc*gPeb-lJu zk6Ujnj`$bujvZ?*-SE>UVx+{zpCpYtTKl4@T#y|}%ycu;bsPGx-oqcz)3Z|c!zdk0 zoY!l`nqA0DWOP*R)BVrmZ$%i1tDpY;&xkZ!Xfj&#zB(drVV5{b-5vF%t{TC$Z&Hgp%}aXO^LGNTDHcZOwhVT)APQjIfudm$#ctlh)qD*u4tuQbws$WJ;7-S*{*QiN`zGo7zQcdr|g!`(wEniL=h% zT@f@jW?wdcv5Anz+R^9XS=6XO_H}ayeaj){W4{C@9S(|tH3_e&=qzkZ5>e5TA@7HY z+jg(od@n6D2?3L29)9kg@ZV)e8(txE?2@l{_XJye;r(>MMkO*nMggR4LV7dqgdh|0 z55l}xR(4!XZw01SQDtYh`#TyZ%J$ahQZsv^v6H4Vr={g;3wA9tkB6fg|}x;2p$hM?5#JA z>#=RZR-?Y!6k+h6)$LVOK81*JqKa{!gnZllqNhf`xGz836lv9eXvF+WeH=FVhzDx4 z&nbL_=#ljwL;SpbZ=$i#c;xTDJDciAvS!g`2G>YAljiT|UO9N&W$SE#J#SfHF^K%2qBQWxrm}O-zsWgpn{h~~ zq+R_R?xDX^RNo&DCGce4sSF01Qt=)K09VDV#J{%4wO$x zKWi-9yCv=x8eV$xY<*B!JeV!UQ;ngy;Uw+4OS!*9x?rEzZ_>cF&c9x!xa#WNI^;9` zadc8Te3fXz84m|hgd>=5C>i3y3c*t>k^)k)3Dbz%-G6$cpC$*QXxB=so5E{#p)QO=hBj{fGnS zKJJsAmTqF#!y<@5G{_@r6R{A_aKd(9FihfEnshZU6`!-o;14}2>zwx6+j%{ceVTM~ ztSW)Q9XCCZ^UM6BJxh1`X+z||$#48V<6tGbj%>soCIhN*Ejs#$EQ~ZjB-@6h<;``a zH&*+a7W;97fokAL-e3FI8@kZ?9TCI*DyH}6pRt{u%$_WCiF6Djd{;0}Bv`>E&P(1y zzqYY?sXSrsp9`r!*i1h?_VdxGvT%;Zu?e_i9g!XUyR5G_pfjQy^f%#*{+Naf+ZNv9 z*x83E!AdQ;IXBN(SiTxgbuGxv0l_zaA58ci=JgE9~2O5^7y#vB}1-Jw<*rtlqB@yf4sX3gg zH>e=kFQ8z#W)`f<&xV)_Kc8*`fCbpu(Q-loJ*K|n0d{}Ov)~0wDJCDJ%bNNNnS7#o z+dcU*m(aaek@W-em+CmyYB%78^44G}OPkNz+MY=d1KuY*PPfZb{2u~z+F}~FUG;N? z<1UnYz&O9np8=~e89hvTpRYvYde28b;uWIDnYAF}!n*M+J11F6qN^xvpUfZR!`mB` z`s{A*lJ-;pf%9&!ii8)Ya^>NVZKGCQ->6le(RG=N?@DnB;s~hXdG;e3=(1XYI9=5A zU8DKa%(z7%&5vxGXg`OuF%q=i^}wf#dI9iiPF4NUg zL`LDtr!Is1T36Rn-!aP93<$K;@fpNjy%)ECyvX?)XZ1LMkNq9l`RD4|;@KVw4TYd{ zPGOr>8gk%jb11&|&)loTeWtYy+AY)CQPe9rV;ZZgQ;!gFC^L+e^QrQ}hT&hjJqn6F z<^WQc$qou}BOqz9aBQeDYB}~*`BneiiABEs3?iwV2e_>+C;JQHPL{hR9U*9{`Fd5A zcAlXDa#^9puJP|Z3f0vh8$;G6L5C!NMQ`7$$%JleP?J>sH;_j|DBC$R=77 z<@Kh$Fc;+5Q;I-=2CuYEjGhmUoi|C1oUj1h%=DMyvRgaqV;NHJ=$v$TW__YEm(S~7 z#xI!rO3iJ2;a7g>tKKyBBHPijWF;{Q>T7adTrgB^2A`~mhi6{zRX6$tRQ|~WA8n$} zr(SoZk2R%J9AV+}3@bc#IMSJuWaS23z=co!EQT~ObPE6@m>Er_(od23EbxoiU(tB0 z)xmKnF--m&TkfGsMypfOR*_!xrWWtYO0_o13&pAaC6&20be@q{D*%a_7W5Jz6Z3sh zaGK%aJ}not5$~&|>pU^)u~r)AoL;NU9==H!Y_dN9T*<9_6AX6S6@MqEpU7*kV&aAIEi?Q%gG)Uq9;TnT@~_RFO;Xc@LT+*UOP%+EKP8 zU~;xD>-5Y&qD0!U2mjyCSIng!((o&je53cf)$^?#&-$QLSIvtl?0-s0&hBxbk+l|c(9tl69S$9q3*jR2fLu1O>?4eIiItFHvB}(f>cD=(pn`^)t zY+#yb(Qq>Jif2X_QtQC}SN>eS;NG6}HOizZR(CJM=*1}X9Tg`*XYd!zsh|0lU_|5lBu3|&s}f>HTZcYwqobO=d@m&wvsoI2c>spS<6}5 zFTyqtor4PW2K-HBNAn0(Fs99k`4^Se{$F$ePDZW+W`RdKvlL%}DtA#IIpJZFx0y^2 z`)A6CBVlCkI=%4+Mr%ekCnFNNG~)vv*ybER#b8oz{e7+<`}>(D*`TWEb@^T)3?!1- zmOWII@eZdqv&Yh#>*mw!$m@avM9!5w0wvk6QaV;XmxbrkA8GM#@Hncgj%34=TRDTy z*VFxQ`P;#Z+d;S2z2Bd=oUd+3{EBXz2;n>OXR<8K{dM}UdFR$rQn!U0(*u`(ol5wU z-G@NNf{dit7E2EwNpUjM;X#2NB8Th2zuFV{;=E80;HQ%M9_z0mN+Wp(KHecdQQ#8b zfsH{g@hoQp0Ta^B&9Gru-O+;{5st6JskXs;l(e83Xa(Uyc|rUj`Jnyrvd&PDAuwTg z0WuS0I0_XM_^(G)%pm_sh`1J$#G{7h)}ig*gX()7K@93na6zQ6j}|TMS!4&UV^M^3u+hYVmk_|hDu}29y8$gCD@EP3g>7Ird87zdEk{Sp?UtAK!e=tOSD`Uy*5#_fE8$l_q zsEx#BXIao8$Uh&{c1fhf5PmA>P=oo|fOlEAqe?tsvtV@~4 zjQv7Z)Sm38Q6wB`1Bsw#cVvL!!p>;JlpwVP>90>qUXz&w8)u`Oo7d27Z=Mp<8==Cf zO=OF=+VeW{>?O|qL1Ly^9DX?7dkeYy?DFhq=yoIl&x<Ad`F^s`|14Aoz$pnC1 zovsK4|Dev*nl=-SS!f&zY?p}LIuf!H3R$)^v|xI2F2hJEKk&9gy?h24xI~Bty>Sy; z%4yMKL@>?4rZm#2!Lid7qvjMN~Mm5AU5G++h#OAftt?RJOCR zZfwsRBqH9}Q{G2i@qD;E;a*D`3#4*>Qd2eD=n@q-XkTTb+D9~$aSct=I5Fp>if$>9 z;UOV){MZqNfj#U3_2}>YGippmBPUcvu+N^C&+Vs^=eKlWKFDBUSAR_~U#1qF+LNCQ zvYhc?ic3rJaIK?afiJsbhMwAvfQUCV9+Yb)b>wHZy)ooK6UBgLPzS&=6}3G<@REbr z?vQb*c;62IFEZF-C9he_YL_FePLDNR*G-tOuBli9P%m?ffWfB_bdDz zV)1J|=!Ef>QXsc}!6bL^y)7Vvlfo{UQa-m5D-Lse2wg#>iaPMxF=#%LQ9r-D^kV)4 zl;Lh7y@4*>_;$m-ULviRrZA&Yo|^?kRjRtr;}_bVgkb}#(xGX2+Hk%Q`PgPs@672q zG(_#~hWe|k+kF_WZ5ZpNxT&*X_zuzFLllTO_gLWjbSQzcsgB~dnDuthT7*Ue+n?dd ze+eF1qv;UK=y0jLCEWt2Dfe=q;aELy)^lhznl75fRZWoD+*tK#UHzn7fna99n3R4I z9ItJJnhccXt? zaf->oxd7jw;GoUnlr6;w;dCG3DY`89AWgk27ove$YiMZDCZ1iwD?q`slk+ zF1U#zqcH3vs72Jq9A)f!i@2!KMi#nU&J4#aTIxDEVa`l=Edb-I zUx@2Dq*#df)F5%@l>O->XL2T)X;AOYg!L37Fr1sRoS@2m!3?{tPXRKlVND=31(2io z)TJPR4mE%t9%wy_wmMnDSQYC?4vce6L(p|G_oYlFVrxAFt(h!I6{ytJRvq;2EaYbb z%W4!ki^s0HRT4>Eps_;A3>ZnwSXUI~bEuRqj0yl^5Zo4oB(Ql9M@OF9Ql(tBbJej@ z7C{!=8y!Ks(nz4ZRDwNNK*TtF9E{&CCOziFKy}(;|4m_P6>V7u!8#_86HHKWuDLOI z*oNZV$Jlh-MB7HE8x-SXaGyr!Qp!P-roTQJr<+47jL~MMKB$k*x~D-6%I*w#?K7Xe zDI8c0SVo2u|04p zSu0oAlH~g5U;MIo>i?Y0CFZRQjgE~9u=XEgjj#}=<;4j8>?`_c*no9y$5%$-@s|Us z7u_J)-d-=<5F-|deoCees6Cwb1w&FKAVLHn6RSP;@WRoUfBV-uTdVJ+cR>!}8e10= zqq^E09Oa*y_(e|^rnf@c&&ord#SWZLcXFtgcbUO}v8qlD@!lK_;M7mF{}<-zicygN zpyj(_@*?u{q4GUleVTO&x3VGQhH&M-pP&3xZbe2eHFzXf_6j5^B#tN$XzR)6ddr@F z;E?Zgu6+N<%|Ls->re=I5a_O+pcD7vVH6@)8*v-~We_i>Se~ z+PB1f_$n9($l`wm=RYMEXLA>3D?5P2f5r^pY{P5 z2d){s0jveA;lEq})&O2DQX^6>!mmQF!XJp#4Cc$6p-4r(Y3|_h+#aeJK>$7ZaeT7n zs0A%(q&fRUdk(%cpdjq8bxfs6*yx14#MHO`CJ$yr7rp1uL@ zz$7Ob_W8K*=Rr0>bd8I0GpBzCwmVd=ZJum^&GF$n8OSY-tfV8RH2~0k=>zLg*#P*N zW$8JSYACWGYD%V`N2k@;>>@BPHezgnBDdHp{6yhVg)%M{peiVrpc|Xn(Yemt4y(-g zfg<%CUODY7!6$*~o+4(DD$~;nn>hVU(^p_Bi<|PJj&M_@mlJ!VL=SkNR2fz|74)GZ5%PX01t|@ebjl#45&$A&smR8 z;1W!!fA0(KD|i9h4r>FK9`1i$3L-11BvC779Q?oWR&GMH>NWJ{0eSyPclP|};uQb& z`hRzWDZt*;+}6m%&DGVx-pIt_e|E-|)`xJ?7xDJ*V-+1FS|T+vibtMFfP&TG6ggok zQf{`FbyNDFD+(%aYGVsUGeNkSjd&pim4Y2_sI@}ogR^DtOYY6h4sh4!$B}sZ<*Rdh z<-^5b<>I^8$E$s8ymCBPgoJlV)q)rW<`QxfT6Qq7X@fgNYZt8NGW0$PDh}cd-ijoi z0qW@T)B{qGKapVXNAY0#(>#*eGGx9$B~P*a5;k_}ymAWN4Sy7%{je=ts_&?RP^>p= z5u#d2y`600r_7skaG8lSBPf3rc~R<3*}+p8SbVKEu@6VZU5D;@k8|4+7;-04~V(5Q45f(W+|@ zy-}z#UeKfxo+x0bsTZM+$@=ASmpP}ZYm_L85ThaboEXXw0m&UAs6f>mMq_393n`6= zqEwY88~9AOoZ`FtchS720XK@H(HLZo|@XOT3e4MzxF@{qYRPoMkTk{NN}tRlvG# zqdidC@2{tv1w`*s`dbCF@s&GMXxfgkEIy_}-GsM+FMZ;^fI&mu{=y8wPmCdTTu$A; zKpC5iWLcy&rrf-@<;7rt*8wpv17lpMBdA(f$I#lQl=$?e?V!5<&~y5bsbV70z456Q z&GBn#M4a%wwE&fTE}pNR2ltDpPGIj)KEhh87m;r99tT9Z>lI-;!%v}E4_bkR^S8AGcAq)#U?TE?5# z?EmWQ9e^uoyZzA}PHYeEewu+vH1VgOJ5 zmd{3f(Y-PN>)du8l?bi!t2}6=WM2X^n33(J)CU3mC}5@)9A_-Q3}%AG02w-e zqe+0cPXSg3nz#UuBozBpAg(CG^!Y;;tS%v0L^@<1k0cST9Jxrvvk4gKRF4Twq=c3<>O$$vOyE z?W@TC)f@e`OUT1|^y|J7_aMxT9TAeBnIhTR_nL_NP~3Cp@8AhkcYr!@9VaKK4T!aB zbTWS)o(;*&49p|#*)1w%cu;=+a}}Kc&hWF@4>;?fKzeO2N+ZZ`u8@k?62~27p6!Ys zM2zh9@bl!|w~O4DHeenu-=wO%Hh*GXw^~NBKSx?w2;C^U{KoAjz7k)o`bFY^kSo4J zHkAOcE3R<&;Ex2nb%w_-P!2CZ`C`PJo_AV&zS}@7v_gPwdLuz%mAY(L>i^_fE`4@G zH)~s$`W+?8^q$CPyqb3tXdWTJD@B#)I|d`f6bD%moRiWwsOieMS#7a$jW(cG*$%NB z0Gr&Rz;NVgA@H=V9mvxs-zWA_n2?~4lA4znT|@Gn`>8YlIUx^bW`>~>v@USu>9~Q6 ztbot4c6zG$XXj5rdF^$jQxOY>Kqh8$XNdG)uw{p|6s*)l5P~(f`^@@kPBSp8XE%$> z4~)NH4szaVuEeV{oS~Tfi?gwztk|6y; zzFSEhp0wZHfYp?$N(bBc0eh=l01=p|5LBG7(>mvSkA=F9b%X#oR4e%im5J90kF%d| zt!)bGY)Z^PpqXe=?}tv3KO{@*&e}noC&AM4l(wbOJb3}yGJBU_e-0r@&t>-Pp=z)sw9gF%t{1G zvdMI{FCX6o7f|m~VI(X(0QrjMEFsd9y)<(C}r! z@E}k;p(6JdoxPN)_F{&YF2nv(JWt22N*@4ETHAZ8 zZczzd5vTLGzdo_GFHi>SKRBB$F%{A<%N~05-ua3DHkj=eAPys4d}|PQlxY1`XmqSc zb5jbVja)n3hdjZx&9t~)_ROr*wvPEjEoei|%vpO;Nwje$o<6S0c*Z!QirwCKm@4ExPS z(QMPX9bj<=o=CpMTYGC|)H5=go>A_E2{R~pEs4TZq#f<%A#)OVZShc6w0L2uiJo5c z!ST|I;VZ#IR#;`w?eYTS4~cus+TR%Ru`ifW1g1q6S91 zxE$=Iut|tnh!TpJ2~oU56EjZ`gcf91GJM=jG2I9tU7e95+~~~v`ZstX&P4f3`tT+f zr1@1oLH<_o4&)x>y^_N_(Z1S@B7SXu>4E>I;8~iPm^%Dz?;wI)y#4>NcZUDR-Wij_ z=0^x}PYRdFr;PUda)x@W~p5tPgI~?yf zeB%Ly6>6(^+ObXR=Y_Wk=KNcqIUcVEuqCH|TP)CKN3S|NIH3rF3>imoosrKX&($CZ zy%V)R+71{H+zC)OC(7M9Z&Nr$Lf1mgbI>OCkgR7=din$Sx zI|u(_mR@t8rYT?HCG)E*&|e}W-j2>ZbIivu9W3%ZP)P|q0(z}=h2E$2hp`e-j zlDO(hU{+ThT9Ac75vzt49Zh%4f+|*ZVIw#>t|9(r(clS>(z~4jqa3ih(Mui#r5u0C zF7KIQ;7YnMHFS-J%lsVDzpj)BynCnmd~7j8;Pe#VZ-3UW<{}^=m$_rc$jbOWO~FUU z)vRc)p57SF`jZY!x$u0PR~MjTM`9b2n%y35rPw~_mlFUVE-w%nkNgC3B*H-iI+0FG zLBtBe?pJv={$d2=0Crd~y>A3#rQ3wKJ`TUI1lAt_6rhvfF8y&YSn6LEPZC1+;E!M7 zpq?{lgUS^~pU&S1oMU#1eq0N#$cDLdTmk*T&?T`R?XQLjK>zg$M2^g+wF#Wjg3`nb z@QX>}%!`vB$ovkX!iMYxq`VX4?ohMENV30YJtSW7;|Ct_>v9@}x#r0u)l`D5P6yB+t;AAY!o*lsG z0+3#@l();w&h|Wr563dRfZ965435q7fY>C5fb$K%wefx3CI4V8CEAfItXfek@qbxL z`p^IX$v@pp|7hXaViHI)9HUngNtPg#Ut~O*Tz`FiqW~ zoMyE(wG?j1g(p9R>ovObndmDf=5qfzLy||^ohA?e2GH7zKRK0}*(+wfQgCpblN=cg zI0l(Pvf9XhX4CM9Mxg+0!edk#+ubg~Ah8!7R;Rv7KB+cG{;e@&V2I=-5(POk;>p3M z;uL`KX4loa$k*xKbK0gd5T5Vs&Af5UXKI+mG`AwhN4%WA;Bf1Z9@KR?6^ZSI`4*27 zF;A9IajES(1fSHC=tqCApb)~GnH*mvfc$i522Y!s%21qa0jP3G@7vY?p^XyR12D-I|#k;4zcKRB4(ev&f zkSVAkJ0m%eA7pkF_c}i})H_iQ#=Q5y-bmb>?c-))N%SGCDu|q3M8I zCEt!OO?|;eSlYSntZYf}OC@U7rLJPc)NdYG>@QwPAHEukPoG98k%hv7Qc^35S779x zWvAh1U81f`i8-ulLh!oLR${{G?jEtrG5kWnxx6%m%Y3=>k#E4PQDf(sliSEqB>YO_ zRvT~V2j}|zOpLPXp;(oIy-5ZMdZ`;Zsre%zdi|NNHtnMN5Eq_7`~gw-wr`Ta zN;e<0C!8jeSBC|>o)6N)5+^26E@$hmpOeIL4BX&|A0R-#R3~;~7r-NjZM5$vasH%u ztVAuf8ockJfzR@jaEx)m?-1{hk{64L^lkz1OmyvL=xmwc;kP-P1`-wrPXn2kA`1D| z_QJN$Hq_ON@a%BR4k%T`yGf=mi#(Yu$w4BHx%{X2_!e&2PQa^|Il*+QGEb<#J3tpr z8`Zq<&-WLL_8F>mVKWij2And!Q2tWh@!#WtjRurvWg?16n#jU+G|;){9cXlE>I2*r zq*~PX%g*o@YP1&mOan+5b0UZ>m7JRb-zWeCPpPXba4M&Tn?0co9dhR>D>qGOzmlG< znVepKXmt6+_qcNDOlgn0dw}vM%DPa(;B9s4gy-JEDaAs?zlKOC{)vmdueq3wx_9$xOZBP(>Uvqb3lXgD`DQfbQgqtqlg++y>04b#Zc{z+VY>;>cx9Ec)q zL2sX&l)755Au`#=`^wNEp<4}Bhm9=p8`GWQn4lck;#zO?egT}}3n_drmrSYeRM~v7R&krw(15po!z~8@8ZOSX|VC~x*iIB-5 z;bswPe!e|Wvtm)dfpot5Qjn3|Tf*eRS&-TsuW3G=O5ZP_3Ko6**2(GoFzUR14XwRm z!v{^t6Z9t}X(uqIm0P;<8EGrj9~UNXXCHEPZ%U+_d#025x{FQJ@OMY7In?9N@UB z%P3>#dHI}$8^dce6@Mxkdp<+Lu8jkYZ3-IYoRX-w7%*)x1uLA8LOB+JoHDe(tGUIU zLnB|D<%0XtzyHUg3BFe{nO%Qr6|FLPXbY376p|R1ZuJAFDhx8-Iy3J`Kl7PeO7&MR z>dDetaB&v=HcjXLAd#!|rPaSS;0CT;OCs@fhX{vxfzQ8Ls?^P8bN}FVIML zqk*|i(tNxp`wjaU=ut-V#@AP`CcMQ=gCCq(pz;9wRHuFbB1t5?x|@SYLAd(Sqo4!<}>~-FmzHZD+Sq*-b{M z0jGM_`5sUK4gzkmaT2tUhW**^(mJ=;GzZk{P1%O$a8X4wte4b3Sxbqi-yzA{5K>y& z&a7X78Ila>nz%oDX_yo7`nhk=j694GnAQJKEM`&Bm_ zFM20Mp{G)=1O1SuktIDn{W<;K;u(vll42Uw@(`2%+c7Cc-4ySMRjJtkhMen<#skV3 zM>07r#BMN6g*)+{7|!cE#0Jb&0CMS>>X<7IHg2Z!Z4$o#vpVtPa6m~?cl5)vvKcOa z@z4f)MuK>26J(T;@2^+U8f+0;?q7Z(SsPxzokMlJ^>SUq*s>p1_uPd82;MmbIZcRy zl1dA*eIE~VUKpJ|_`r{a@rc&m!L2%URw5a&vyIIEC4Td=OOJ1)tXW;T|Y5b7y7@12h3?~_i;)|G2$(F#T zUt^4H>m?8bRZsl&RLI6a$oS$qFlM){VKl$zTK2J!`@2l>v3cVh{}(!4*$JPsK$Xp; zY3{2`W2K#}3ViF<-dADsq{%%>=Qwz$6pjY>rn5RPX$bA?(~lwUt)7r_&nj_Ks0uee zlV_K8TUC-^VBO(AZBNpxT#oCXmUStZAy4m)Bu%MK(dK$5nd#rq(^visp+9hS%As$q z!I}?FfsOCAcl?UhMbFBzQenn=l^(^jx}R6o*+vOlP{Wa#SP=ykGE!+S zXKs^nNK-&@D9X|V_Pv4oEdBxdH%LHSPkr$I$d_y0eyU~Z`F_{rtCTP3bJS{qxX3i* zDxa(!i;NKxzaILbR`Yq2wA*hI<7JLt3$sEs^{ns|4aZcYe8&NkWpjPIDcbd%S}#^t zX29tuH5I3@&eY?eYNHK|=6WDij4yGc!pFAf*y?qX^Xzy)=r5XeFjAB3L5}gdC3TuV z6Ba#m2X)cHl^n=Vn+IoB>V0d>Z{rI!C7(Oygm4<)B zY`B&L%p$g1Y&oxHKJpzU`2{-%Hi%!$xU6%)7@nXA+b(but7s7zFbVsv*Qqui`9b>g zxX^iaht{`tgLs;x{WQ_xfJ*E$ORgco*omg-;v9-8afM*~SUw6(a{zSJ6 zGs%ff#yhSlY$_7ZnkI9pw$Pe6_;q5IJ`6+ zUrkbQ(wIr9zj!;Q+bjB_kCGAnuFK(*?QhB1ccV~nL^HVi_9ZzTUy_6RpOW)mu7Lj* zowYB~!RQp-!KJ>eGT-GZ4>JycLJ%{pNCVGwQu%Q}CUi?!m&tOs;8ZKRN;M9Lu!>Tk zbvF4Cz18z^d+PkziGuSEYQ;!muns8@!N=GzYKXPlTUG7$X;3UKni|bCU#n_omWu_ zidU`C11Y~eNlF3n3gB`b-!Z6SsUT<5qUSLXAh!mK>#P?oQFmRFtStusoV4d?0`E4M zTy$qiAe8wsHIdi!Q=$p)VhxmgQ2D#A70t5@AM~k`MRRZ>d-Q(7`Mv5STM^fuZS*40 z!Q_K%9TE<6eWu1}-M(sRw&+?4*4^L8X20Qxl|!@FI+vC@+%@Fy_7KmnQdqUXQJ zqL%-`o8}e?;TidNhJp7FfQjO}6v}5D`~E3?r!JA;ban0uYe+ z1_DE%lu=L-GsKko{T86aGDCK9$eT_0!$Q=9wpC&_ky{FoxVC%1BNpMix5+k(`790I;5CdOp~BV-64Y{u~$| zT3+4_KD?}4*JfHrwG|4`2U&thrqQex>oHR(9w6 zzyH#+cB+z(IvfKPV6c8XB>or*^nQ<`nAu^j)ucuZyH*WtmL-xJa&3{16(Sr-+(A0_ zX1vBvdWVd6h6Pjv$#hFMerp)B?Do0<0uF~$opl26dEL@PU_r+M5KNdET^|8}_^#(@ zJ}Mx)%-S#k zW7u0*yC_3~Z=D>-Jg_5QO9?(!*kF$Ri~}>gmQPZi#SB(G9=A_pUh#~?k)s2^Gc3x$ zXNCdJIATRlGa^`6H&hjibO_C0UzJ5Un#BNDmCXqiyE{wo65=~>xDWCfgmwTzuccp1 zjHs%ls$dDp8F4*QD})N9e*i--8Bu(ROg)Jk(sRFyK1Xegsz?Rt1tA_`7Kt_)9I{Tl z*mt;*xIJkoLXsH9pU^)o#MZ=U3KR->W)aLXBuP(WtVTBXAnJT72$Ex)V&G$B;$BDk z_L@*Q210fuA@jb=7bGBwvl#L2gBE5p3Z&+g$xW1I%|n!haAd3hw90XkrBetlMP_zP zBbi7?6C5j`$zPaGGcz%JG^IOsXocMH#}iJTPM)@YAa=}nv{2zkCvU1)5-7DdG~uUfUOG(6v+t^ z%U3jL8pMnwL>pu@x>glfv{ME-rM5_s($}baK9h6;d&PF5bC*;Qv@bKRFpf3OJoq&M z1UFc_ef47{Lwu5O5_Zy^284!}rgqW1(zw#Al5N#(wR2Vf-0mFh{B-rw(KeGWlRERB z!;0h45wexFRjxI#b;yOvS!kYV3S=I7jz!u3L6~#3g%6tbqg*% zeKW?jg8qVmy-tdW1dBA|)|vV_hw<@Y>h+4{ijlLZ9}5{4S$dr-?Q3t5frY{u1LEPV z;X_HQNgiWhNm5CV6)DO*%C5@y%1aeL7d20*PpuYJEM>7((qYm$(#IN0D$^_bozktg zPdb4aJ{q^+j?+JPtYJA*W9k=|-} ztzToiW6WKbgNNJbW%3w=XOIUt+buh|v#673i@TH9Ytbv!>)Tt_E9cADd-PM+AJ-eS zYiTfDpdO%opblRw-`^k>Ao!rEpoQO9z#_rg!0BLkPz7KhVb$>M;%&OoZ?K;YnAT0c zis_+_LS&+}YxZ>seiFV;Msh&@ z4tXBB*T3A)9lC1|d}x`*l(CnlnB-tkwZER%f_`v3IhN(jrN*KbkRB)_+?f}dCs*6lEY1~okg1&bz`nuhDfnUw(oMc6{*Y;~w#| z{p}j6WuW9te!YB^EF797T?v(o28M=9vsj0i`aIK?@yE$CF|;3=M@LMJY;(=;usVg;Wjkla0PT{S_UooRznxFt69%6)3LgwciA0Pd8He3*Y%qydH>nMLP07&73Rd! zgpo1psyp=-15~|4L#0deN!*g96?n+~~d=J!z(^%J8LAS`+;=NjXU6>B%S ztoaXanciAs%I}rsO`R*GtBYM5&hEEx{ZBY*y3H)0`V@)hXe6 z`S*Lswu(I5cV&-qC;Qg>Cbm+&o9-b_#ayXoIl3GxX!5OcxN|!$k0SCjakX(pJDWbe zE*W+W9EVt?cRKInuzMp)1fj{xC|EM+U zw%UHu?be;@Q-i;RgAC64Ncfx!{xd5&F1kQ0LL3>LiI0yBi`8*sI2r$^xULv^YSc^l z)AiK8{BY}i=T%}#^=c&GWMPvUO{y z13#7gjqgMDcIL%ksCZiDk>}9kjpl`oi`n{C<&_#5{fn?dU=;-9liD_}|(&g`U45WO(K!d=PMJ*cNq3 zfaGA>0>xN;ID>SXYln#cM8y4|n1~+!If}M%|evenkgq(!QLfeF~O*xq~58n(a!!rQ@x%=aRtniXSj<=MMApXx(K6oPy6- zu9auhodbgD)TvCWA0Z)G_&>Cm8@R8OW(}tF{WYo_YA-e;m~f}%pSkHj9Hte)Q?&c zt^`89_)AQ4FB8OjGFjbUJ<_}J++6ZU^zF&$=){&1) zu}T)M8ixw~K9a6>9babbyb9Ckht(d(q50G|AVG8N`A-6s(@crsQ9h?O5!A{#C*)B85Ov8 zy3w52%NT4#zyFv_)pOh6$g>h>0o}r3?50ztY3IOM>OV|*wpr$j8@~*Mg-F@@xsKZm zaA8g3jR+$3z?`v&(_{c(y6uOFwztFWm7l_AP$6qv^#(eVR+cwzKchbs3rBgVv{qFzZ&DdI4KB$_U&6yQ#VjRr|8 z8f!)wwiRQxT^qI)XEzjUkZ4A|&SVY_7$S`QVahks9Rg99B;rkE=J$pHhb>X~LwbFdO)YBHmn#QfEE>=hz_QnF?4* zZLJ}kP`apQ)aVufx`wbxbB6Jf*W)0z>HyKK;jZ~-!$HJ~U z+GEG$%pOd0gC_7T`1jEYv)kBAacXa?J0s@C7+5e%ZRd~($c7*bH>Z+T8IP@~R@!E} zX6i+xG;YZ?w>*LA)m~FB7M%hDL$iT2BwL48z?2PNm1YlFm`aco%>n*gnCn3m%)#ba z=qZ*pW>K`H!E7a-CIu^dUg8h4nGx7pzf~sVeBIjkdA6pTRNlNukW&9lBb{$6N}Bh6 z_17sP#i81yo>)FG=~o;L{m8=`I<$t9WM0NRX%ocU$na3smpg`io|yI4W!>6J0sJ%E zdkwXIFJrAy^=ryw>d*QJ+5C<-qxzgpxnfEzM%%^Y7RG8fsi#W-TY=bm*YLOQIBrCajx(dpGK4+K z7<1elwsA_mfjB_?kP!nxlao8E^~sTLpAFNod#)e=yKE8XOBKc_JDaj8SCEx(aAW%& zpDF*2avon!ZyS@|{Q!}I76NIgQT>dtt-yC&B{17Q$LE3;8Tqa9YSz z1y+plt_e*Z(=WWXem{*_uzh7{$h(=#WWLtO$ZtwK%UGqzeJptm9i(G(9i+1ELXO4y znN_Y(;Wksc56cdCZ>j0w>dRmzPQz!5tUC~4z~D6L3i}<4-A-CTiKM+aBfJu+q~ZAf=6FeDs}C;-S=| ziI@m)ng+6ZUYVu)x>0t#V^MIj3Yfp8aAn6SK^bq+#iJ7*i^7N|4m|IcOGWR{EAgV* z-LP6%lIBBatgl0qm!G+u3lOJadyIeN%Lx^m{PV4(Q1=be1v0(x(^PlMEg4`gmHlG{uDGy*4&N-SX%yH_-yo1vO<3s=$gaftqR zqtJ4#4C-d3Ad-42u}Vo!guI)gkr!Rq3lb}X`{pV_70SHA#j;|qs6rq*c=vdu-howk z%|puIY6m6GQjcWy{?|1c3(qcXX$p^@s%BQvxjyt<6>B(sp4QX%M4VdWB3K`n;lKHQakS-39 zTwl|&6mgCrtxwPNz~bVP8J~T!20iQA2UKeG;&4>y$;4!M+L%&CN$C*{v6P^{zr0jm z3R1st0Dg#1Y%z?7W)lDQat`REL;b4T#5VOqG4@h!~UXN94bT?72^ zU1}}N&Cy8(;#ncW6uDouD{8i7OALl?u~&8qg=OC~1XA|&?c*!+v9g%44cuE(+?~OL zvr2}xlbi2HnvP6IgE<=a zy2DOb2J1ML=4+?W#t9Vbv!fhmg}{pzsN<+3mgYWeVaruqAek2Z>YAP$C%CH9?Htd> zNXT+QNgX_&mzz?bBxSG{2mU43@2h*{4%XyM&4HPE=eT5}R^moi6-Wo(xD{Uw$%(xg z2aVp(4R5jCBSl*y?>QA0aTks>x6+y`b+U-SzYl;TS*}#y>^(rRlhoB21vS+&6~+61 z$jOHO7Acs$9uWAmK724l$l&c5^Sl*2no@FO7%Vg}D~*}P+Q8JFn0dnsi@b220xykom`+fZ@)KC^;lAq@~osS898k&wpCFf15sC1n3!%W)iO03zUz!97FP=J zI@3?i;oFVZS~Ox%H(5Penj~c8ok1Y9hQxxRv+tXP@XkKm-A0r$b#qLHz}5|J3My6u zC+D+H>o0-EB^rro7pGg{kezsUD7JyrcnRRf9_w8Ragr5hSvEk=c(P^o(Wbuc1;cA-o?g9&;_Jz$vqc}xfe+nGjN87YYk~q~C zk?BRLP?=EmgOflrUJUbG|YUoX^F>V420zJl(UXtYeT0$Ta1OEY zSf3d`(3n+Q$pnPhbi2T%&S8#|dK=EqVN9*b*g6g@;LWWMkL4wZ!mq%prN4Ne7m>Ks z>u87;HeqVCJ8?q10YIDjOp-68Vs1r|Rj{bmM|--8oSd)*F4bLkb__OB@)$*Nqs?0z zAt=)N)+(x?x0q5!UjjMHCX;I+n5r2asrXttw}8%Y75qn*&t#V&GLTaV?J}gMT1XTc zQ!}lczO2Jv4i~3>B+M$V-fLj&;l1oCgm_zidxVGfqIvnJQ&|7*7zh{3Z_qSyB@6k| zmdDV*87-ZnEik95afRkifBzym$*POFFtrBS??=O{yZ+u55o0fpBRO8a zlZ^6BvN9`!S)9S|j;s&LYlt3QVeSni{w6L$jCAUxX*( zfN*9oHiic7$`z>0ZzGVC=p6x9Hj*OdRHo~Z0pjANyWA3V_i0miK>Bcu{%kz_HQ8J$exWO}l-2zWhA zpudYGqHX2-)8cFW(!_;X(Q9lx!%C*{u8aYOrV4jSzGTBpM1Z2Aq2Du6HrkeWLHaWY75yC%Ff4$3} zm@P?eI6scm{%2K+G3qTx$WVi;*j!7=xw9%VGySz?yF}fSOP6vb(G|6FBoNjJEn3QC zA0#zE@#x+Gs4MHR{EDsX>)}AYu(|?e4zh!=rNH-|Wd48{f~`6pL#SZ9`1O<~b8|H} z%TeAuW6S>bq;FJn6W}aG>Ml$9<%1xyEQ4D1@g){DmJA+MnA*UmIKxXGXmc*S9ZW;G zAd9|T(e8n~v&@@rFsNjZ)KL;fP9lI?_^s_QmuW*Cuak5A^h$D{du2kd7_LjJGx>814BdGpa4M>9n_aEWM32#RbdhXc5%Z<`Lq7 zM)}^#Intv;XeXcHfhl~vS7J{*^cz>r^wihOyzT~N#@{d#MX9*7khIyU(4iZ9*p#Ea zd0I5s8@GSc94x3MWSAuUKZ{7m@9dmk?$Y`V)17RXoW_V5RBJ^ z@+2m=bG7B&R7??%f#9qlhI;*mg9K(sYY% z=`Qs$Hj+t&_fRzH#xnW?-+jqTt~b3VOiig$`FVs6q@5;5G#qJwg))EjgZ4#LKd|2_ zS(T9$*Cc5?#cA>EkpQU4(Gd!s^OtLBosO~*sP?z2B3fZlW~3G)ve@m6Gc zj{>pz)fxhha?0ga9&GZ`ufp8fBpY2$`y9_rdFu^veLhNXY132$bv?j9tHdP=I=t%7I{uxr#ch!uCeXqp) z=Q48qNF7q(;2j`G-W~duR#>d>g*(o(#`KAg{zQ7Z-+- zYyCJ0_oB=YSj^JpUbviCjLmyWbPCDf{TI|^kAKAYxKq2l&kQ!Mmyz?Ic`|W>7lg)y zv!e&Q7rr~sGc%bFoZ&5)EiU%#Ws_*r)H>*ZT23?mHc!4?>%-dkJT;m~3LzINuTYqz zp5teHde#`&do@sKigp(2x6A8?J>m7)Q1)?yaH0NkbwV@>2MIS7%}r;zc(8jXhbih5 z@uOnh%uGTgOOYF@bdrj}`h%hr?X?z;D(grh1GDzbrLx;xhgQhq0=5XCjktGQ}JV9JNFhkJ48TrCXq zuzNF^)g>wMiu=VA3A0zOIXf|ejE3vwK1?RJO)yz^x`SifzFIol_TS0|aLg+8e66qRN(Eg;hZv*SA2E5|hg4 zovzSZtdy`vy-_Ss>vW?0jb%)8hkb_`PnH+Vx|Z4FN5M>0WoD_r0!=1a{^1jWR-R5) z@1rOSZQ9ZPs}*8xqL0#G_xdb6q{t+BY40g)XxaL*h&!&WRJ$NnbUVm+ZU5N|tnBtg zc_rALkIdnaBO$5QrCv`JMDp7Z6;>wJ0zzHCMbPO8%6|F!o!r3vy(yo`N0Jzq_9aW` z(a&~9nAkiCOZqTJ?N)|NyvRy!;k--EfxGi0Kg;eMm2i5+zBuzf^TMq0`am!3Ct5{X z!?2u#^4f=K7{2*%5?nhOkQvGum;sYWYABF6O>y-;0Wt_B!W zvjLH$NM4%jc$-EZX*K+?#M6$Y2rFJmNqDctlZY5A8b@`l6AhBudAO))J$82`&7DC=Owvl^rK zJ4XnwevEnYG%S4{*RdL~gWy?FMzk$&x^*jdvDB6I%30ueQp>UtV|9`W zV{O|T2vW+aa-M=rQU+mxg|a4iIlGm!vgJ61@kZ#=S@EqklM;zH(B(jtu(JFGCvHHu zQwGX~Prl_oBMrZP`)A9z#yBcWVwx8iKO?PI*KTxtu6o5W~*n&CEbDNg;CF_`VJ}Grq{059?cH2mO z{<(B~CTN_~rB4FnOWLAm`RZPL`v_rIKHut&ZS^A9XU57PIVfhD#{aeLnLLLwjBv%8 zcYDS(dd}*^5n_i0x6E;SOGKpOPE4O+`n}8yWcm6TA;6R?SSvUN~<-<-~Pi0$( zdCO9=?~Z-Y`dJEj;1t(FGNT4#Uh0DQ(~l1E6{p!Z9FgqJiFLvOnt*EZw7e+)H(0If zE|e~6&7p3{u8PU2}S;|WM4+7x75dJ>;tI*BA z?|iZJzUXXb`d>`J{~7VGIT_`pEy2F#wQ!#V5j>l&g=EB?$LikfPE2O z_06pRk*;WH`ESeq*CPIR8|uG-ti=A$KwnL%|NUzGQ?;SLfu`L4BN_KUY7hN8%0E?U z`5R@!^Z$wRPf3XXj`&Y$!G9xme$_PkKPCzPJIp^NME(r}9sUn6|8HmZPyF`3A)^!j z1^K_(?*D#L|HO0t8(}2*KM?+AJ^wqzKM`L4h5$+X|3ZJ2l>qyzLKFb@>l^wd%q=~C G?fqX?vv7z2 literal 0 HcmV?d00001 diff --git a/packaging/org.tizen.ScreenMirroringSink.spec b/packaging/org.tizen.ScreenMirroringSink.spec new file mode 100755 index 0000000..38ff784 --- /dev/null +++ b/packaging/org.tizen.ScreenMirroringSink.spec @@ -0,0 +1,37 @@ +Name: org.tizen.ScreenMirroringSink +Summary: org.tizen.ScreenMirroringSink +Version: 1.0.0 +Release: 1 +Group: N/A +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz + +ExclusiveArch: i586 x86 i486 i686 i386 armv7l arm aarch64 + + +BuildRequires: pkgconfig(libtzplatform-config) +Requires(post): /usr/bin/tpk-backend + +%define internal_name org.tizen.ScreenMirroringSink +%define preload_tpk_path %{TZ_SYS_RO_APP}/.preload-tpk + +%description +profile/iot/apps/native/screen-mirroring +This is a container package which have preload TPK/WGT files + +%prep +%setup -q + +%build + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{preload_tpk_path} +install packaging/%{internal_name}-%{version}.tpk %{buildroot}/%{preload_tpk_path}/ + +%post + +%files +%defattr(-,root,root,-) +%{preload_tpk_path}/* + diff --git a/screen-mirroring-sink/AppConstants.cs b/screen-mirroring-sink/AppConstants.cs new file mode 100755 index 0000000..6ab0a2d --- /dev/null +++ b/screen-mirroring-sink/AppConstants.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ScreenMirrorSink +{ + class AppConstants + { + // LogTag + public const string LogTag = "SCREEN_MIRRORING_SINK"; + + // KeyCodes + public const string BackKeyCode = "XF86Back"; + public const string EscapeKeyCode = "Escape"; + + // string literals + public const string LightPlatformThemeId = "org.tizen.default-light-theme"; + public const string DarkPlatformThemeId = "org.tizen.default-dark-theme"; + } +} diff --git a/screen-mirroring-sink/MirroringDisplay.cs b/screen-mirroring-sink/MirroringDisplay.cs new file mode 100755 index 0000000..d4d6779 --- /dev/null +++ b/screen-mirroring-sink/MirroringDisplay.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tizen.Multimedia; +using Tizen.NUI; + +namespace ScreenMirrorSink +{ + class MirroringDisplay + { + public MirroringDisplay(Window window) + { + Display = new Display(window); + } + + private Display display; + + public Display Display + { + get => display; + private set => display = value; + } + } +} diff --git a/screen-mirroring-sink/MirroringManager.cs b/screen-mirroring-sink/MirroringManager.cs new file mode 100755 index 0000000..9637761 --- /dev/null +++ b/screen-mirroring-sink/MirroringManager.cs @@ -0,0 +1,127 @@ +using System; +using Tizen.Multimedia.Remoting; +using Tizen.NUI; + +namespace ScreenMirrorSink +{ + class MirroringManager + { + private WifiDirectController controller; + private MirroringDisplay mirroringDisplay; + private MirroringSink sink; + + public MirroringManager() + { + controller = new WifiDirectController(); + controller.DeviceConnected += OnDeviceConnected; + } + + private void OnDeviceConnected(object sender, EventArgs e) + { + Tizen.Log.Debug(AppConstants.LogTag, "device conneted"); + mirroringDisplay = new MirroringDisplay(Window.Instance); + sink = new MirroringSink(); + sink.SourceConnected += OnSourceConnected; + StartMirroring(); + } + + private void Start() + { + if (sink.CurrentState == ScreenMirroringState.Connected) + { + sink.Start(); + } + else + { + Tizen.Log.Error(AppConstants.LogTag, "Sink is not in connected state, Current State: " + sink.CurrentState.ToString()); + } + } + + private void StartMirroring() + { + SetUpConnection(); + } + + public void Pause() + { + if(sink?.CurrentState == ScreenMirroringState.Playing) + { + sink.Pause(); + } + else + { + Tizen.Log.Error(AppConstants.LogTag, "Sink is not in playing state, Current State: " + sink?.CurrentState.ToString()); + } + } + + public void Resume() + { + if(sink?.CurrentState == ScreenMirroringState.Paused) + { + sink.Resume(); + } + } + + public void Stop() + { + if(sink.CurrentState == ScreenMirroringState.Connected || sink.CurrentState == ScreenMirroringState.Playing || sink.CurrentState == ScreenMirroringState.Paused) + { + Tizen.Log.Debug(AppConstants.LogTag, "Disconnecting sink"); + sink.Disconnect(); + } + + if(sink.CurrentState == ScreenMirroringState.Disconnected || sink.CurrentState == ScreenMirroringState.Prepared) + { + Tizen.Log.Debug(AppConstants.LogTag, "Unpreparing sink"); + sink.Unprepare(); + } + } + + public void Terminate() + { + Stop(); + controller.StopWifiDirect(); + } + + private void OnSourceConnected(object sender, EventArgs e) + { + Tizen.Log.Info(AppConstants.LogTag, "Screen Mirroring source connected, now start screen mirroring"); + PermissionPopup permissionPopup = new PermissionPopup(controller.ConnectedDeviceName); + permissionPopup.PermissionRequest += OnPermissionRequest; + } + + private void OnPermissionRequest(object sender, PermissionEventHandlerArgs e) + { + ((PermissionPopup)sender).Dispose(); + if (e.Permission == RequestPermission.Allow) + { + Start(); + } + else if(e.Permission == RequestPermission.Deny) + { + Tizen.Applications.Application.Current.Exit(); + } + } + + private void SetUpConnection() + { + if(sink.CurrentState == ScreenMirroringState.Connected) + { + Tizen.Log.Info(AppConstants.LogTag, "Sink is already in connected state"); + return; + } + + if(sink.CurrentState == ScreenMirroringState.Idle) + { + Tizen.Log.Debug(AppConstants.LogTag, "Preparing Sink"); + sink.Prepare(mirroringDisplay.Display); + } + if(sink.CurrentState == ScreenMirroringState.Prepared) + { + Tizen.Log.Debug(AppConstants.LogTag, "Connecting to Source"); + Tizen.Log.Debug(AppConstants.LogTag, "Source Ip: " + controller.ConnectedDeviceIp+":"+controller.ConnectedDevicePort+ ", Name: " + controller.ConnectedDeviceName); + sink.Connect(controller.ConnectedDeviceIp, (uint)controller.ConnectedDevicePort); + } + } + } +} diff --git a/screen-mirroring-sink/MirroringSink.cs b/screen-mirroring-sink/MirroringSink.cs new file mode 100755 index 0000000..c4504a2 --- /dev/null +++ b/screen-mirroring-sink/MirroringSink.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tizen.Multimedia.Remoting; +using Tizen.Multimedia; + +namespace ScreenMirrorSink +{ + class MirroringSink + { + private readonly ScreenMirroring screenMirroring = new ScreenMirroring(); + + public event EventHandler SourceConnected; + + public MirroringSink() + { + currentState = ScreenMirroringState.Idle; + screenMirroring.StateChanged += OnScreenMirroringStateChange; + screenMirroring.ErrorOccurred += OnScreenMirroringErrorOccured; + } + + private void OnScreenMirroringErrorOccured(object sender, ScreenMirroringErrorOccurredEventArgs e) + { + Tizen.Log.Error(AppConstants.LogTag, "Screen Mirroring error occurred: " + e.Error.ToString()); + } + + private void OnScreenMirroringStateChange(object sender, ScreenMirroringStateChangedEventArgs e) + { + Tizen.Log.Debug(AppConstants.LogTag, "Screen Mirror State changed: " + e.State.ToString()); + currentState = e.State; + if (e.State == ScreenMirroringState.Connected) + { + SourceConnected?.Invoke(this, new EventArgs()); + } + } + + private ScreenMirroringState currentState; + + public ScreenMirroringState CurrentState + { + get => currentState; + } + + public void Prepare(Display display) + { + try + { + screenMirroring.Prepare(display, ScreenMirroringResolutions.R640x360P30); + } + catch (ArgumentNullException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Argument null: " + ex.ParamName); + } + catch (ObjectDisposedException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Object disposed : " + ex.Message); + } + catch (InvalidOperationException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Invalid operation null: " + ex.Message); + } + catch (ArgumentException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Argument exception: " + ex.ParamName + ", " + ex.Message); + } + } + + public async void Connect(string sourceIp, uint port) + { + try + { + await screenMirroring.ConnectAsync(sourceIp, port); + } + catch(UnauthorizedAccessException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Unauthorized access: " + ex.Message); + } + catch(ArgumentNullException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Argument null: " + ex.ParamName); + } + catch (ObjectDisposedException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Object disposed : " + ex.Message); + } + catch (InvalidOperationException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Invalid operation null: " + ex.Message); + } + catch(ArgumentException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Argument exception: " + ex.ParamName+", "+ex.Message); + } + } + + public async void Start() + { + try + { + await screenMirroring.StartAsync(); + } + catch (UnauthorizedAccessException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Unauthorized access: " + ex.Message); + } + catch (ObjectDisposedException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Object disposed : " + ex.Message); + } + catch (InvalidOperationException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Invalid operation null: " + ex.Message); + } + } + + public async void Pause() + { + try + { + await screenMirroring.PauseAsync(); + } + catch (UnauthorizedAccessException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Unauthorized access: " + ex.Message); + } + catch (ObjectDisposedException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Object disposed : " + ex.Message); + } + catch (InvalidOperationException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Invalid operation null: " + ex.Message); + } + } + + public async void Resume() + { + try + { + await screenMirroring.ResumeAsync(); + } + catch (UnauthorizedAccessException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Unauthorized access: " + ex.Message); + } + catch (ObjectDisposedException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Object disposed : " + ex.Message); + } + catch (InvalidOperationException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Invalid operation null: " + ex.Message); + } + } + + public void Disconnect() + { + try + { + screenMirroring.Disconnect(); + } + catch (UnauthorizedAccessException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Unauthorized access: " + ex.Message); + } + catch (ObjectDisposedException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Object disposed : " + ex.Message); + } + catch (InvalidOperationException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Invalid operation null: " + ex.Message); + } + } + + public void Unprepare() + { + try + { + screenMirroring.Unprepare(); + } + catch (ObjectDisposedException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Object disposed : " + ex.Message); + } + catch (InvalidOperationException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Invalid operation null: " + ex.Message); + } + } + } +} diff --git a/screen-mirroring-sink/PermissionEventHandlerArgs.cs b/screen-mirroring-sink/PermissionEventHandlerArgs.cs new file mode 100755 index 0000000..1489ee7 --- /dev/null +++ b/screen-mirroring-sink/PermissionEventHandlerArgs.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ScreenMirrorSink +{ + + public enum RequestPermission + { + Allow, + Deny + }; + class PermissionEventHandlerArgs : EventArgs + { + internal PermissionEventHandlerArgs(RequestPermission requestPermission) + { + Permission = requestPermission; + } + + public RequestPermission Permission { get; private set; } + } +} diff --git a/screen-mirroring-sink/PermissionPopup.cs b/screen-mirroring-sink/PermissionPopup.cs new file mode 100755 index 0000000..078ff43 --- /dev/null +++ b/screen-mirroring-sink/PermissionPopup.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using Tizen.NUI; +using Tizen.NUI.Components; +using Tizen.NUI.BaseComponents; + +namespace ScreenMirrorSink +{ + class PermissionPopup : IDisposable + { + private AlertDialog alertDialog; + private TextLabel titleLabel; + private TextLabel contentLabel; + private Button cancelbutton; + private Button allowButton; + private bool disposedValue; + + public event EventHandler PermissionRequest; + public PermissionPopup(string name) + { + titleLabel = new TextLabel("LabelText") + { + ThemeChangeSensitive = true, + PixelSize = 40, + FontFamily = "BreezeSans", + FontStyle = UIConstants.AllNormal, + Text = "Screen Mirroring", + }; + + View contentArea = new View() + { + SizeHeight = 144, + WidthResizePolicy = ResizePolicyType.FillToParent, + BackgroundColor = Color.Transparent, + }; + + contentLabel = new TextLabel("LabelText") + { + ThemeChangeSensitive = true, + PixelSize = 32, + FontFamily = "BreezeSans", + FontStyle = UIConstants.NormalLight, + Text = "Allow [" + name + "] to mirror on this device", + WidthResizePolicy = ResizePolicyType.FillToParent, + HorizontalAlignment = HorizontalAlignment.Begin, + PositionY = 40, + }; + contentArea.Add(contentLabel); + + cancelbutton = new Button("CancelButton") + { + ThemeChangeSensitive = true, + }; + cancelbutton.TextLabel.FontStyle = UIConstants.AllNormal; + cancelbutton.Clicked += OnCanelClicked; + + allowButton = new Button() + { + Text = "Allow", + }; + allowButton.Clicked += OnAllowClicked; + + alertDialog = new AlertDialog() + { + TitleContent = titleLabel, + Content = contentArea, + Actions = new List { cancelbutton, allowButton }, + }; + Window.Instance.Add(alertDialog); + } + + private void OnAllowClicked(object sender, ClickedEventArgs e) + { + PermissionRequest?.Invoke(this, new PermissionEventHandlerArgs(RequestPermission.Allow)); + } + + private void OnCanelClicked(object sender, ClickedEventArgs e) + { + PermissionRequest?.Invoke(this, new PermissionEventHandlerArgs(RequestPermission.Deny)); + } + + private void RemoveAlertDialog() + { + Window.Instance.Remove(alertDialog); + alertDialog.Dispose(); + alertDialog = null; + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + } + + RemoveAlertDialog(); + disposedValue = true; + } + } + + // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + ~PermissionPopup() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: false); + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/screen-mirroring-sink/Resources.cs b/screen-mirroring-sink/Resources.cs new file mode 100755 index 0000000..dc9d17f --- /dev/null +++ b/screen-mirroring-sink/Resources.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ScreenMirrorSink +{ + public class Resources + { + public static string GetImagePath() + { + return Tizen.Applications.Application.Current.DirectoryInfo.Resource + "images/"; + } + + public static string GetThemePath() + { + return Tizen.Applications.Application.Current.DirectoryInfo.Resource + "themes/"; + } + } +} diff --git a/screen-mirroring-sink/ScreenMirroringSink.cs b/screen-mirroring-sink/ScreenMirroringSink.cs new file mode 100755 index 0000000..bbe59be --- /dev/null +++ b/screen-mirroring-sink/ScreenMirroringSink.cs @@ -0,0 +1,123 @@ +using System; +using System.IO; +using Tizen.NUI; +using Tizen.NUI.Xaml; + +namespace ScreenMirrorSink +{ + class Application : NUIApplication + { + private MirroringManager manager; + + public Application() : base(ThemeOptions.PlatformThemeEnabled) + { + + } + + protected override void OnCreate() + { + base.OnCreate(); + Initialize(); + } + + protected override void OnPause() + { + base.OnPause(); + manager?.Pause(); + } + + protected override void OnResume() + { + base.OnResume(); + manager?.Resume(); + } + + protected override void OnTerminate() + { + base.OnTerminate(); + manager?.Terminate(); + } + + void Initialize() + { + Window.Instance.BackgroundColor = Color.Transparent; + Window.Instance.KeyEvent += OnKeyEvent; + + UpdateTheme(ThemeManager.PlatformThemeId); + RegisterThemeChanges(); + + TitleBarView titleBarView = new TitleBarView(); + Window.Instance.GetDefaultLayer().Add(titleBarView); + + manager = new MirroringManager(); + } + + public void OnKeyEvent(object sender, Window.KeyEventArgs e) + { + if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == AppConstants.BackKeyCode || e.Key.KeyPressedName == AppConstants.EscapeKeyCode)) + { + Exit(); + } + } + + private void RegisterThemeChanges() + { + ThemeManager.ThemeChanged += (object sender, ThemeChangedEventArgs e) => + { + if (e.IsPlatformThemeChanged) + { + Tizen.Log.Error(AppConstants.LogTag, "Theme Changed: " + e.ThemeId); + UpdateTheme(e.PlatformThemeId); + } + }; + } + + private void SetTheme(string path) + { + try + { + Theme lightTheme = new Theme(path); + ThemeManager.ApplyTheme(lightTheme); + } + catch (ArgumentNullException e) + { + Tizen.Log.Error(AppConstants.LogTag, "ArgumentNullException: " + e.ParamName); + } + catch (IOException e) + { + Tizen.Log.Error(AppConstants.LogTag, "IOException: " + e.Message); + } + catch (XamlParseException e) + { + Tizen.Log.Error(AppConstants.LogTag, "XamlParseException: " + e.Message); + if (e.XmlInfo != null) + { + Tizen.Log.Error(AppConstants.LogTag, "XamlParseException, LineNo." + e.XmlInfo.LineNumber + " Pos: " + e.XmlInfo.LinePosition + " HasInfo: " + e.XmlInfo.HasLineInfo().ToString()); + } + } + } + + private void UpdateTheme(string platformThemeId) + { + if (platformThemeId == null) + { + Tizen.Log.Error(AppConstants.LogTag, "Platform theme id is null"); + return; + } + if (platformThemeId.Equals(AppConstants.LightPlatformThemeId)) + { + SetTheme(Resources.GetThemePath() + "light.xaml"); + } + else if (platformThemeId.Equals(AppConstants.DarkPlatformThemeId)) + { + SetTheme(Resources.GetThemePath() + "dark.xaml"); + } + } + + static void Main(string[] args) + { + var app = new Application(); + app.Run(args); + } + } +} diff --git a/screen-mirroring-sink/ScreenMirroringSink.csproj b/screen-mirroring-sink/ScreenMirroringSink.csproj new file mode 100755 index 0000000..5ee4675 --- /dev/null +++ b/screen-mirroring-sink/ScreenMirroringSink.csproj @@ -0,0 +1,28 @@ + + + + Exe + netcoreapp3.1 + Tizen + ScreenMirroringSink + + + + portable + + + None + + + + + + + + + + + + + + diff --git a/screen-mirroring-sink/ScreenMirroringSink.sln b/screen-mirroring-sink/ScreenMirroringSink.sln new file mode 100755 index 0000000..0153f0d --- /dev/null +++ b/screen-mirroring-sink/ScreenMirroringSink.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31025.194 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScreenMirroringSink", "ScreenMirroringSink.csproj", "{C3A5CC64-F899-4116-9959-B45B30D63A29}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C3A5CC64-F899-4116-9959-B45B30D63A29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3A5CC64-F899-4116-9959-B45B30D63A29}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3A5CC64-F899-4116-9959-B45B30D63A29}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3A5CC64-F899-4116-9959-B45B30D63A29}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CF208F67-5E2E-4605-AE1B-5C6DDAA0593B} + EndGlobalSection +EndGlobal diff --git a/screen-mirroring-sink/TitleBarView.cs b/screen-mirroring-sink/TitleBarView.cs new file mode 100755 index 0000000..12037d2 --- /dev/null +++ b/screen-mirroring-sink/TitleBarView.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tizen.NUI; +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Components; + +namespace ScreenMirrorSink +{ + class TitleBarView : View + { + private const int Interval = 3000; + private const int AnimationTime = 300; + private const int ShowAnimationPosition = 0; + private const int HideAnimationPosition = -120; + + private View titleBar; + private Button backButton; + private TextLabel titleLabel; + private Timer autoHideTimer; + private Animation showHideAnimation; + private bool isAnimating; + private bool isTitleBarVisible; + public TitleBarView() : base() + { + Name = "TitleBarView"; + //StyleName = "AppBackground"; + BackgroundColor = Color.Transparent; + ThemeChangeSensitive = true; + WidthResizePolicy = ResizePolicyType.FillToParent; + HeightResizePolicy = ResizePolicyType.FillToParent; + titleBar = new View() + { + BackgroundColor = Color.Transparent, + WidthResizePolicy = ResizePolicyType.FillToParent, + SizeHeight = 120, + Layout = new RelativeLayout() + { + Padding = new Extents(64, 64, 0, 0), + }, + PositionX = 0, + PositionY = -120, + }; + Add(titleBar); + + backButton = new Button("BackButton") + { + ThemeChangeSensitive = true, + }; + backButton.Clicked += (object sender, ClickedEventArgs e) => + { + Tizen.Applications.Application.Current.Exit(); + }; + titleBar.Add(backButton); + titleBar.Hide(); + isTitleBarVisible = false; + RelativeLayout.SetLeftRelativeOffset(backButton, 0.0f); + RelativeLayout.SetRightRelativeOffset(backButton, 0.0f); + RelativeLayout.SetHorizontalAlignment(backButton, RelativeLayout.Alignment.Start); + RelativeLayout.SetVerticalAlignment(backButton, RelativeLayout.Alignment.Center); + + titleLabel = new TextLabel("LabelText") + { + Text = "Screen Mirroring", + PixelSize = 40, + FontFamily = "BreezeSans", + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + Ellipsis = true, + FontStyle = UIConstants.NormalLight, + Margin = new Extents(24, 0, 0, 0), + }; + titleBar.Add(titleLabel); + RelativeLayout.SetLeftTarget(titleLabel, backButton); + RelativeLayout.SetLeftRelativeOffset(titleLabel, 1.0f); + RelativeLayout.SetRightTarget(titleLabel, titleBar); + RelativeLayout.SetRightRelativeOffset(titleLabel, 1.0f); + RelativeLayout.SetFillHorizontal(titleLabel, true); + RelativeLayout.SetVerticalAlignment(titleLabel, RelativeLayout.Alignment.Center); + + showHideAnimation = new Animation(AnimationTime); + showHideAnimation.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.Linear); + showHideAnimation.Finished += OnAnimationFinished; + isAnimating = false; + + autoHideTimer = new Timer(Interval); + autoHideTimer.Tick += OnAutoHide; + + TouchEvent += OnTitleBarViewTouch; + } + + private bool OnTitleBarViewTouch(object source, TouchEventArgs e) + { + PointStateType pointState = e.Touch.GetState(0); + if (pointState == PointStateType.Up) + { + if (isAnimating) + { + return false; + } + + if (isTitleBarVisible) + { + HideTitleBar(); + } + else + { + ShowTitleBar(); + } + } + + return false; + } + + private void OnAnimationFinished(object sender, EventArgs e) + { + isAnimating = false; + if(isTitleBarVisible == false) + { + titleBar.Hide(); + } + } + + public void ShowTitleBar() + { + titleBar.Show(); + isTitleBarVisible = true; + AnimateTitleBar(true); + autoHideTimer.Start(); + } + + public void HideTitleBar() + { + autoHideTimer.Stop(); + isTitleBarVisible = false; + AnimateTitleBar(false); + } + + private bool OnAutoHide(object source, Timer.TickEventArgs e) + { + HideTitleBar(); + return false; + } + + private void AnimateTitleBar(bool show) + { + int destionValue = show ? ShowAnimationPosition : HideAnimationPosition; + showHideAnimation.AnimateTo(titleBar, "PositionY", destionValue); + showHideAnimation.Play(); + isAnimating = true; + } + + protected override void Dispose(DisposeTypes type) + { + if(Disposed) + { + return; + } + + if(type == DisposeTypes.Explicit) + { + titleBar.Remove(titleLabel); + titleBar.Remove(backButton); + + titleLabel.Dispose(); + titleLabel = null; + + backButton.Dispose(); + backButton = null; + + base.Remove(titleBar); + titleBar.Dispose(); + titleBar = null; + + autoHideTimer.Dispose(); + autoHideTimer = null; + + showHideAnimation.Finished -= OnAnimationFinished; + showHideAnimation.Dispose(); + showHideAnimation = null; + + TouchEvent -= OnTitleBarViewTouch; + } + + base.Dispose(type); + } + + } +} diff --git a/screen-mirroring-sink/UIConstants.cs b/screen-mirroring-sink/UIConstants.cs new file mode 100755 index 0000000..5e49677 --- /dev/null +++ b/screen-mirroring-sink/UIConstants.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tizen.NUI; + +namespace ScreenMirrorSink +{ + class UIConstants + { + public static readonly Color HEXEEEFF1 = new Color(0.9333f, 0.9373f, 0.9450f, 1.0f); + public static readonly PropertyMap NormalLight = new PropertyMap(). + Add("width", new PropertyValue("normal")). + Add("weight", new PropertyValue("light")); + + public static readonly PropertyMap AllNormal = new PropertyMap(). + Add("width", new PropertyValue("normal")). + Add("weight", new PropertyValue("normal")). + Add("slant", new PropertyValue("normal")); + } +} diff --git a/screen-mirroring-sink/WifiDirectController.cs b/screen-mirroring-sink/WifiDirectController.cs new file mode 100755 index 0000000..162ae35 --- /dev/null +++ b/screen-mirroring-sink/WifiDirectController.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tizen.Network.WiFiDirect; + +namespace ScreenMirrorSink +{ + class WifiDirectController + { + + public event EventHandler DeviceConnected; + + private struct PeerInfo + { + public PeerInfo(WiFiDirectPeer peer ) + { + Name = peer.Name; + IpAddress = peer.IpAddress; + MacAddress = peer.MacAddress; + Port = peer.Port; + } + + public string Name { get; private set; } + public string IpAddress { get; private set; } + public string MacAddress { get; private set; } + public int Port { get; private set; } + } + + private List peerInfoList; + + public WifiDirectController() + { + WiFiDirectManager.DeviceStateChanged += OnDeviceStatusChanged; + WiFiDirectManager.ConnectionStatusChanged += OnConnectionStateChanged; + WiFiDirectManager.DiscoveryStateChanged += OnDiscoveryStateChanged; + WiFiDirectManager.StateChanged += OnStateChanged; + WiFiDirectManager.PeerFound += OnPeerFound; + WiFiDirectManager.Activate(); + peerInfoList = new List(); + } + + public string ConnectedDeviceName + { + get + { + if (peerInfoList.Count > 0) + { + return peerInfoList[0].Name; + } + return string.Empty; + } + } + + public string ConnectedDeviceIp + { + get + { + if(peerInfoList.Count > 0) + { + return peerInfoList[0].IpAddress; + } + return string.Empty; + } + } + + public string ConnectedDeviceMac + { + get + { + if (peerInfoList.Count > 0) + { + return peerInfoList[0].MacAddress; + } + return string.Empty; + } + } + + public int ConnectedDevicePort + { + get + { + if (peerInfoList.Count > 0) + { + return peerInfoList[0].Port; + } + return -1; + } + } + + public void StopWifiDirect() + { + WiFiDirectManager.DeinitDisplay(); + if (WiFiDirectManager.IsDiscoverable) + { + WiFiDirectManager.CancelDiscovery(); + } + WiFiDirectManager.Deactivate(); + } + + private void OnPeerFound(object sender, PeerFoundEventArgs e) + { + Tizen.Log.Error(AppConstants.LogTag, "Peer Found Error: " + e.Error.ToString()); + Tizen.Log.Error(AppConstants.LogTag, "DiscoveryState: " + e.DiscoveryState.ToString()); + if(e.Error == WiFiDirectError.None) + { + Tizen.Log.Info(AppConstants.LogTag, e.Peer.Name+", "+e.Peer.IpAddress+", "+e.Peer.MacAddress+", "+e.Peer.IsConnected.ToString()); + } + } + + private void OnStateChanged(object sender, StateChangedEventArgs e) + { + Tizen.Log.Error(AppConstants.LogTag, "Current State: " + e.State.ToString()); + if(e.State == WiFiDirectState.Connected) + { + IEnumerable wiFiDirectPeers = WiFiDirectManager.GetConnectedPeers(); + peerInfoList.Clear(); + foreach(WiFiDirectPeer peer in wiFiDirectPeers) + { + peerInfoList.Add(new PeerInfo(peer)); + } + Tizen.Log.Info(AppConstants.LogTag, "Connected peer count: " + peerInfoList.Count); + DeviceConnected?.Invoke(this, new EventArgs()); + } + } + + private void OnDiscoveryStateChanged(object sender, DiscoveryStateChangedEventArgs e) + { + Tizen.Log.Debug(AppConstants.LogTag, "Discovery Error: " + e.Error.ToString()); + Tizen.Log.Debug(AppConstants.LogTag, "DiscoveryState: " + e.DiscoveryState.ToString()); + } + + private void OnConnectionStateChanged(object sender, ConnectionStatusChangedEventArgs e) + { + Tizen.Log.Debug(AppConstants.LogTag, "Connection Error: " + e.Error.ToString()); + Tizen.Log.Debug(AppConstants.LogTag, "Connection State: " + e.ConnectionState.ToString()); + } + + private void OnDeviceStatusChanged(object sender, DeviceStateChangedEventArgs e) + { + Tizen.Log.Debug(AppConstants.LogTag, "DeviceState Error: " + e.Error); + Tizen.Log.Debug(AppConstants.LogTag, "DeviceState: " + e.DeviceState.ToString()); + if(e.DeviceState == WiFiDirectDeviceState.Activated) + { + Tizen.Log.Info(AppConstants.LogTag, "Start setting up wifi direct display"); + SetupWifiDirectDisplay(); + } + } + + private void SetupWifiDirectDisplay() + { + try + { + //WiFiDirectManager.DisconnectAll(); + WiFiDirectManager.InitDisplay(); + WiFiDirectManager.SetDisplayAvailability(true); + WiFiDirectManager.SetDisplay(WiFiDirectDisplayType.Prisink, 2022, 0); + WiFiDirectManager.GroupOwnerIntent = 1; + WiFiDirectManager.MaxClients = 1; + WiFiDirectManager.StartDiscovery(false, 100); + } + catch (InvalidOperationException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Invalid operation null: " + ex.Message); + } + catch (UnauthorizedAccessException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Unauthorized access: " + ex.Message); + } + catch(NotSupportedException ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Not supported access: " + ex.Message); + } + } + } +} diff --git a/screen-mirroring-sink/WifiDirectPeerController.cs b/screen-mirroring-sink/WifiDirectPeerController.cs new file mode 100755 index 0000000..d3b93e0 --- /dev/null +++ b/screen-mirroring-sink/WifiDirectPeerController.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tizen.Network.WiFiDirect; + +namespace ScreenMirrorSink +{ + class WifiDirectPeerController + { + private WiFiDirectPeer currentPeer; + + public WifiDirectPeerController(WiFiDirectPeer peer) + { + if(peer == null) + { + throw new ArgumentNullException(nameof(peer), "provided peer is null"); + } + currentPeer = peer; + } + + public string Name + { + get => currentPeer.Name; + } + + public string IpAddress + { + get => currentPeer.IpAddress; + } + + public WiFiDirectDisplayType DisplayType + { + get => currentPeer.Display; + } + } +} diff --git a/screen-mirroring-sink/res/images/dark/back.png b/screen-mirroring-sink/res/images/dark/back.png new file mode 100755 index 0000000000000000000000000000000000000000..b6e3472a20dfb7e6993da0044b95523416759dfc GIT binary patch literal 723 zcmV;^0xbQBP)zq2u>-6?tw5+iJ5Vc7JAe+f z0(>u-O(rAUWp8)(xP(oJ90$w$=I7mTRtG&_RnPSw>;byY;7(*K?Ap8ho-$XohF9C4U3jl~`#GjRT>Rth0u=4;So{?t;!urLN;m(&3#E&KNI?yW| zjAF%egQ7hE@wfQSM^hr-68WE)(h2V^1_1G_cSc{Y1rDZ&d@J!qG9XU#!YEtu5N?5@ zli->Gh^M1aJRL``3B=E%)o%EJ8$gZIj3NFthj_OVg7^_OXU!+uWD{ui3~aH*{QVEIE&?ae@VR5G6 z#VLzTHW9T3fcPOcr+9a#$zDP=PD786`a#kZ;imJ^8IZF1G#k6wqz3>SlT&3_3vZ{% zT0+PG$ABxf>3Qk0(LilVXo?N!`C;(_MawMWIyM{80NemsV56Rz&1QhOZ>rhc=i36% zIvH_YO4P>Jm<^Y)VH12SfUprVVH=vKn4QZ~5J>=1PGkJ#=&TnrKnVA1LNb6r@E6xR z9*2seNONZaP!Q|^+uWRso^m&D*e@G^K(M)aowzW9=YW`aKx73_&CN{Q7{M;h?E+BK z+)JFh&e_~<00J?TlCsUs+bUV^Ot=E5=BC(VQ&L&(4Y>oT=BCYBhe~elA^;7|O)&OF ztMQ{KfMml?vwWEj#gdA?au){>2;RA))!OEc9zQw(P|eNq(GdOlAK8}XUZIQz#;s}( zJIjD-Y>po@JU9??Zi?!I&H-Ygz3IJsfYb=4e!lk^_yeIb-!ZW^S{VQU002ovPDHLk FV1mH{M3Ddh literal 0 HcmV?d00001 diff --git a/screen-mirroring-sink/res/images/dark/cancel_button_bg.png b/screen-mirroring-sink/res/images/dark/cancel_button_bg.png new file mode 100755 index 0000000000000000000000000000000000000000..3c4f884093929620754f23228c7f8116d73d46a2 GIT binary patch literal 2749 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 P00000NkvXXu0mjfL^52z literal 0 HcmV?d00001 diff --git a/screen-mirroring-sink/res/images/light/cancel_button_bg.png b/screen-mirroring-sink/res/images/light/cancel_button_bg.png new file mode 100755 index 0000000000000000000000000000000000000000..c86737078f6e0388873579b0d87d1331572e119a GIT binary patch literal 2914 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 literal 0 HcmV?d00001 diff --git a/screen-mirroring-sink/res/themes/dark.xaml b/screen-mirroring-sink/res/themes/dark.xaml new file mode 100755 index 0000000..04b2935 --- /dev/null +++ b/screen-mirroring-sink/res/themes/dark.xaml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + *Resource*/images/dark/cancel_button_bg.png + + + + + + + + \ No newline at end of file diff --git a/screen-mirroring-sink/res/themes/light.xaml b/screen-mirroring-sink/res/themes/light.xaml new file mode 100755 index 0000000..efb16f2 --- /dev/null +++ b/screen-mirroring-sink/res/themes/light.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + *Resource*/images/light/cancel_button_bg.png + + + + + + + + \ No newline at end of file diff --git a/screen-mirroring-sink/shared/res/ScreenMirroringSink.png b/screen-mirroring-sink/shared/res/ScreenMirroringSink.png new file mode 100755 index 0000000000000000000000000000000000000000..9f3cb98608134e7b9eb4beb7394fec9f03e40f63 GIT binary patch literal 10097 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 TJbOA100000NkvXXu0mjf?x(Kf literal 0 HcmV?d00001 diff --git a/screen-mirroring-sink/tizen-manifest.xml b/screen-mirroring-sink/tizen-manifest.xml new file mode 100755 index 0000000..c1cfb6e --- /dev/null +++ b/screen-mirroring-sink/tizen-manifest.xml @@ -0,0 +1,19 @@ + + + + + + ScreenMirroringSink.png + + + + + + http://tizen.org/privilege/internet + http://tizen.org/privilege/wifidirect + + + + + + -- 2.34.1