JLChen
2021-01-05 f500e14c0a994487070380c50c85e0929cbc8e63
Crabtree/SmartHome/UI/SimpleControl/MainPage.cs
@@ -1,18 +1,16 @@
using System;
using Shared.IO;
using Shared.Net;
using System.Text;
using System.Collections.Generic;
using System.Net;
using System.IO;
using Shared.SimpleControl.Phone;
// <summary>
// 程序主入口
// </summary>
//using SystemConfiguration;
using System.Net;
using System.IO;
using Shared.SimpleControl.Phone;
namespace Shared.SimpleControl
{
{
    /// <summary>
    /// 主页面
    /// </summary>
@@ -38,19 +36,61 @@
        }
        //public static Button LogoButton = new Button ();
        public static string CodeIDString = "20191223";
        public static string RequestVersion = "2.512151";
        public static UserInfo LoginUser;
        /// <summary>
        /// 是否是管理员权限(变更了,成员的时候,这个也为ture。为什么会声明这样变量,因为有些接口必须使用原来的Token)
        /// </summary>
        public static bool IsAdministrator {
            get {
                if (UserConfig.Instance == null || UserConfig.Instance.CurrentRegion == null) {
                    return false;
                } else {
                    return UserConfig.Instance.CurrentRegion.IsOthreShare;
                }
            }
        }
        ///// <summary>
        ///// 是否账号在其它设备登录了
        ///// </summary>
        //public static bool IsOtherDevicesLogin = false;
//#if __IOS__
//        public static readonly string PhoneType = "iOS";
//#else
//         public static readonly string PhoneType = "Android";
//#endif
        public static string SoftPadTitle = "Crabtree";
        public static string SoftTitle = "Crabtree";
        public static int SoftSmsType = 0;
        public static string RequestSource = "1"; //0:Zigbee、1:HdlOn、2:GraphicsMonitor、3:BusproSoft、4:AgentWeb
        public static string LogoString = "";//"Logo/Logo.png";
        public static string WiFiStatus = "CrabtreeAdd/WiFi.png";//"CrabtreeAdd/WiFi.png";
        public static string RegisterLogoString = "Logo/Register_logo.png";
        public static string SeviceIP = "52.172.25.151";
        public static string RequestHttpsHost = "https://homeautomation.havells.com";
        public static string RequestHttpsHost = "https://smarth-api.havells.com/HangZhouHdlCloudApi";
        //public static string RequestHttpsHost = "https://global.hdlcontrol.com/HangZhouHdlCloudApi";
        public static string RequestHttpsHostMqtt = "https://smarth-api.havells.com";
        //public static string RequestHttpsHost = "https://developer.hdlcontrol.com";
        #region GetDesignHeight
        /// <summary>
        /// 获取view的计算高度,ON软件为了适配全面特殊使用的比例方法,由于一些背景图片是直接全部填充的,改动成三层的(view-button-button)的工作量很大,不禁需要增加一个view,还需要修改图片
        /// </summary>
        /// <returns>The view height.</returns>
        public static int GetDesignHeight (int height)
        {
            int ss = Convert.ToInt32 (height / PixelScale);
            return Application.GetRealHeight (ss);
        }
        #endregion
        public static double PixelScale {
            get {
@@ -109,11 +149,17 @@
                } else {
                    Phone.UserHomePage.Init ();
#if __IOS__
                    //Loading.LodingBackgroundColor = 0x10777777;
               //Loading.LodingBackgroundColor = 0x10777777;
#else
                    Loading.LodingBackgroundColor = SkinStyle.Current.MainColor;
              //Loading.LodingBackgroundColor = SkinStyle.Current.MainColor;
#endif
                    Loading.TextColor = 0xFFA9A9A9;
                    Loading.LodingBackgroundColor = SkinStyle.Current.MainColor;
                }
                CommonUtlis.Current.CheckIfJailBreak ();
            } catch (Exception ex) {
                //new Alert ("Eorr", ex.Message, "Close").Show();
            }
@@ -121,7 +167,7 @@
        /// <summary>
        /// 增加rjfi
        /// 弹出错误提示
        /// </summary>
        /// <param name="tip">Tip.</param>
        /// <param name="time">Time.</param>
@@ -135,11 +181,13 @@
                    Gravity = Gravity.Center,
                    Width = Application.GetRealWidth (560),
                    Height = Application.GetRealHeight (126),
                    BackgroundColor = SkinStyle.Current.AddTipButtonColor,
                    //BackgroundColor = SkinStyle.Current.AddTipButtonColor,
                    BackgroundColor = SkinStyle.Current.MainColor,
                    Radius = 10,
                    IsMoreLines = true,
                    Text = tip,
                    TextSize = 16,
                    TextColor = 0xFF000000
                };
                MainFrameLayout.AddChidren (button);
                button.MouseUpEventHandler += (sender, e) => {
@@ -156,6 +204,53 @@
        static DateTime requesTime = DateTime.MinValue;
        static bool isShowLoading = true;
        ///// <summary>
        ///// 请求服务器方法
        ///// </summary>
        ///// <returns>The https.</returns>
        ///// <param name="methodType">请求方法.</param>
        ///// <param name="dataStringJson">请求的参数.</param>
        ///// <param name="needHeaders">是否需要包头.</param>
        //public static ResponsePack RequestHttpsOld (string methodType, string dataStringJson, string urlHead = "")
        //{
        //    ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => {
        //        return true;
        //    };
        //    #region
        //    var webClient = new WebClient ();
        //    if (urlHead == "") {
        //        urlHead = RequestHttpsHost;
        //    }
        //    //else {
        //    //    webClient.Headers.Add ("CONTENT-TYPE", "application/json");
        //    //}
        //    webClient.Headers.Add ("CONTENT-TYPE", "application/json");
        //    string url = urlHead + methodType;
        //    if (LoginUser != null) {/* 如果不需要验证Token可以不用传入 */
        //        webClient.Headers.Add ("Authorization", LoginUser.LoginTokenString);
        //    }
        //    byte [] bytes = null;
        //    try {
        //        bytes = webClient.UploadData (url, Encoding.UTF8.GetBytes (dataStringJson));
        //    } catch (System.Net.WebException webEx) {
        //        //Application.RunOnMainThread (() => {
        //        //    MainPage.Loading.Hide ();
        //        //});
        //        return new ResponsePack () { StateCode = ErrorCode.NetworkError };
        //    }
        //    string responseString = Encoding.UTF8.GetString (bytes);
        //    try {
        //        return Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePack> (responseString);
        //    } catch (Exception ex) {
        //        Utlis.WriteLine (ex.ToString ());
        //        return new ResponsePack () { StateCode = "Data exception" };
        //    }
        //    #endregion
        //}
        /// <summary>
        /// 请求服务器方法
        /// </summary>
@@ -163,40 +258,24 @@
        /// <param name="methodType">请求方法.</param>
        /// <param name="dataStringJson">请求的参数.</param>
        /// <param name="needHeaders">是否需要包头.</param>
        public static ResponsePack RequestHttps (string methodType, string dataStringJson, bool needHeaders = true, bool needTip = true,string urlHead = "")
        public static byte [] RequestHttpsReturnByte (string methodType, string dataStringJson, bool needHeaders = false, string urlHead = "")
        {
            ResponsePack revertObj = null;
            try {
                if (!SystemRemote.checeInternet ()) {
                    Application.RunOnMainThread (() => {
                        MainPage.WiFiStatus = "CrabtreeAdd/WiFiUnlink.png";
                        MainPage.Loading.Hide ();
                    });
                }
                //new System.Threading.Thread (() => {
                //    requesTime = DateTime.Now;
                //    isShowLoading = true;
                //    while (isShowLoading) {
                //        System.Threading.Thread.Sleep (1000);
                //        if (requesTime == DateTime.MinValue) {
                //            break;
                //        }
                //        if (requesTime.AddSeconds (30) < DateTime.Now) {
                //            Application.RunOnMainThread (Loading.Hide);
                //            isShowLoading = false;
                //        }
                //    }
                //}) { IsBackground = true }.Start ();
                ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => {
                    return true;
                };
                #region
                var webClient = new WebClient ();
                if (urlHead == "") {
                    urlHead = $"{"https://homeautomation.havells.com"}/WebApi/";
                    urlHead = "https://developer.hdlcontrol.com/api/";
                } else {
                    webClient.Headers.Add ("CONTENT-TYPE", "application/json");
                    urlHead = RequestHttpsHost;
                }
                //else {
                //    webClient.Headers.Add ("CONTENT-TYPE", "application/json");
                //}
                webClient.Headers.Add ("CONTENT-TYPE", "application/json");
                string url = urlHead + methodType;
                if (needHeaders && LoginUser != null) {/* 如果不需要验证Token可以不用传入 */
                    webClient.Headers.Add ("Authorization", LoginUser.LoginTokenString);
@@ -205,76 +284,363 @@
                try {
                    bytes = webClient.UploadData (url, Encoding.UTF8.GetBytes (dataStringJson));
                } catch (System.Net.WebException webEx) {
                    Application.RunOnMainThread (() => {
                        MainPage.Loading.Hide ();
                        revertObj = new ResponsePack () { StateCode = "Network_Error" };
                        //new Alert ( "","Network abnormal, unable to connect to the Internet", Language.StringByID (R.MyInternationalizationString.Close)).Show ();
                        return;
                    });
                    return bytes;
                }
                string responseString = null;
                if (bytes != null) {
                    responseString = Encoding.UTF8.GetString (bytes);
                }
                //var request = (HttpWebRequest)WebRequest.Create (url);
                //var data = Encoding.UTF8.GetBytes (dataStringJson);
                //request.Method = "POST";
                //request.ContentLength = data.Length;
                //if (needHeaders) {/* 如果不需要验证Token可以不用传入 */
                //    request.Headers.Set (HttpRequestHeader.Authorization, LoginUser.LoginTokenString);
                //}
                //using (var stream = request.GetRequestStream ()) {
                //    stream.Write (data, 0, data.Length);
                //}
                //var response = (HttpWebResponse)request.GetResponse ();
                //var responseString = new StreamReader (response.GetResponseStream ()).ReadToEnd ();
                if (responseString != null) {
                    try {
                        revertObj = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePack> (responseString);
                        if (revertObj.StateCode != "SUCCESS") {
                            if (methodType == "IsExistingAccount") {
                            } else if (needTip) {
                                Application.RunOnMainThread (() => {
                                    new Alert ("", revertObj.ErrorInfo, Language.StringByID (R.MyInternationalizationString.Close)).Show ();
                                });
                            }
                        }
                    } catch (Exception ex) {
                        Console.WriteLine (ex.ToString ());
                    }
                } else {
                    if (methodType == "Login" && needTip) {
                        Application.RunOnMainThread (() => {
                            new Alert ("", Language.StringByID (R.MyInternationalizationString.FailureToDataBase),
                                       Language.StringByID (R.MyInternationalizationString.Close)).Show ();
                        });
                    } else {
                        if (needTip)
                            FailureToServer ();
                    }
                }
                return revertObj;
                return bytes;
                #endregion
            } catch (Exception ex) {
                Console.WriteLine (ex.Message);
                return revertObj;
                Utlis.WriteLine (ex.Message);
                return null;
            } finally {
                //requesTime = requesTime.AddDays(1);
            }
        }
        /// <summary>
        /// 请求服务器方法
        /// </summary>
        /// <returns>The https.</returns>
        /// <param name="methodType">请求方法.</param>
        public static ResponsePack RequestHttpsNewBig (string methodType, byte [] byteData, UploadHomeAppGatewaySubFilesBigObj mUploadHomeAppGatewaySubFilesBigObj, string urlHead = "", int mTimeout = 10, string requestMethod = "POST")
        {
            ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => {
                return true;
            };
            #region HttpWebRequest
            try {
                if (urlHead == "") {
                    urlHead = RequestHttpsHost;
                }
                string requestFullUrl = urlHead + methodType;
                //初始化新的webRequst
                //1. 创建httpWebRequest对象
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create (new Uri (requestFullUrl));
                //2. 初始化HttpWebRequest对象
                webRequest.Method = requestMethod;
                //webRequest.Timeout = mTimeout * 1000;
                webRequest.Headers.Add (HttpRequestHeader.Authorization, LoginUser.LoginTokenString);
                webRequest.Headers.Add ("RequestVersion", mUploadHomeAppGatewaySubFilesBigObj.RequestVersion);
                webRequest.Headers.Add ("LoginAccessToken", LoginUser.LoginTokenString);
                webRequest.Headers.Add ("HomeId", mUploadHomeAppGatewaySubFilesBigObj.HomeId);
                webRequest.Headers.Add ("BackupClassId", mUploadHomeAppGatewaySubFilesBigObj.BackupClassId);
                webRequest.Headers.Add ("FileName", mUploadHomeAppGatewaySubFilesBigObj.FileName);
                webRequest.Headers.Add ("IsOtherAccountCtrl", mUploadHomeAppGatewaySubFilesBigObj.IsOtherAccountCtrl.ToString ());
                //var byteData = new byte [] { };//Encoding.UTF8.GetBytes (dataStringJson);
                //if (LoginUser != null) {/* 如果不需要验证Token可以不用传入 */
                //    //对应微信网址
                //}
                if (requestMethod == "GET") {
                    //webRequest.ContentType = "text/html";
                    webRequest.ContentType = "application/json";
                } else {
                    webRequest.ContentType = "application/octet-stream";
                    //webRequest.ContentType = "application/json";
                    webRequest.ContentLength = byteData.Length;
                    //3. 附加要POST给服务器的数据到HttpWebRequest对象(附加POST数据的过程比较特殊,它并没有提供一个属性给用户存取,需要写入HttpWebRequest对象提供的一个stream里面。)
                    var newStream = webRequest.GetRequestStream ();//创建一个Stream,赋值是写入HttpWebRequest对象提供的一个stream里面
                    newStream.Write (byteData, 0, byteData.Length);
                    newStream.Flush ();
                    newStream.Close ();
                }
                //4. 读取服务器的返回信息
                var response = (HttpWebResponse)webRequest.GetResponse ();
                using (var stream = response.GetResponseStream ()) {
                    if (stream == null) {
                        return new ResponsePack () { StateCode = ErrorCode.NetworkError };
                    }
                    var ms = new MemoryStream ();
                    var bytes = new byte [1024];
                    var len = int.MaxValue;
                    while (stream.CanRead && 0 < len) {
                        len = stream.Read (bytes, 0, bytes.Length);
                        ms.Write (bytes, 0, len);
                    }
                    //var backBytes = ms.ToArray ();
                    string responseString = Encoding.UTF8.GetString (ms.ToArray ());
                    try {
                        ResponsePack revertObj = new ResponsePack () { };
                        revertObj = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePack> (responseString);
                        if (revertObj.StateCode == null) {
                            revertObj.StateCode = "Data Exception";
                        }
                        return revertObj;
                    } catch (Exception ex) {
                        Shared.Utlis.WriteLine (ex.ToString ());
                        return new ResponsePack () { StateCode = "Data Exception" };
                    }
                    //return ms.ToArray ();
                }
            } catch (Exception ex) {
#if DEBUG
                System.Console.WriteLine (ex.Message);
#endif
                //The operation has timed out
                return new ResponsePack () { StateCode = ErrorCode.NetworkError };
            }
            #endregion
        }
        /// <summary>
        /// 请求服务器方法
        /// 2020-06-22 带自定义请求超时 时间方法
        /// </summary>
        /// <returns>The https.</returns>
        /// <param name="methodType">请求方法.</param>
        /// <param name="dataStringJson">请求的参数.</param>
        /// <param name="needHeaders">是否需要包头.</param>
        public static ResponsePack RequestHttps (string methodType, string dataStringJson, string urlHead = "", int mTimeout = 10, string requestMethod = "POST")
        {
            ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => {
                return true;
            };
            #region HttpWebRequest
            try {
                if (urlHead == "") {
                    urlHead = RequestHttpsHost;
                }
                string requestFullUrl = urlHead + methodType;
                //初始化新的webRequst
                //1. 创建httpWebRequest对象
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create (new Uri (requestFullUrl));
                //2. 初始化HttpWebRequest对象
                webRequest.Method = requestMethod;
                webRequest.Timeout = mTimeout * 1000;
                var byteData = Encoding.UTF8.GetBytes (dataStringJson);
                if (LoginUser != null) {/* 如果不需要验证Token可以不用传入 */
                    //对应微信网址
                    webRequest.Headers.Add (HttpRequestHeader.Authorization, LoginUser.LoginTokenString);
                }
                if (requestMethod == "GET") {
                    //webRequest.ContentType = "text/html";
                    webRequest.ContentType = "application/json";
                } else {
                    webRequest.ContentType = "application/json";
                    webRequest.ContentLength = byteData.Length;
                    //3. 附加要POST给服务器的数据到HttpWebRequest对象(附加POST数据的过程比较特殊,它并没有提供一个属性给用户存取,需要写入HttpWebRequest对象提供的一个stream里面。)
                    var newStream = webRequest.GetRequestStream ();//创建一个Stream,赋值是写入HttpWebRequest对象提供的一个stream里面
                    newStream.Write (byteData, 0, byteData.Length);
                    newStream.Flush ();
                    newStream.Close ();
                }
                //4. 读取服务器的返回信息
                var response = (HttpWebResponse)webRequest.GetResponse ();
                using (var stream = response.GetResponseStream ()) {
                    if (stream == null) {
                        return new ResponsePack () { StateCode = ErrorCode.NetworkError };
                    }
                    var ms = new MemoryStream ();
                    var bytes = new byte [1024];
                    var len = int.MaxValue;
                    while (stream.CanRead && 0 < len) {
                        len = stream.Read (bytes, 0, bytes.Length);
                        ms.Write (bytes, 0, len);
                    }
                    //var backBytes = ms.ToArray ();
                    string responseString = Encoding.UTF8.GetString (ms.ToArray ());
                    try {
                        ResponsePack revertObj = new ResponsePack () { };
                        revertObj = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePack> (responseString);
                        if (revertObj.StateCode == null) {
                            revertObj.StateCode = "Data Exception";
                        }
                        return revertObj;
                    } catch (Exception ex) {
                        Shared.Utlis.WriteLine (ex.ToString ());
                        return new ResponsePack () { StateCode = "Data Exception" };
                    }
                    //return ms.ToArray ();
                }
            } catch (Exception ex) {
#if DEBUG
                System.Console.WriteLine (ex.Message);
#endif
                //The operation has timed out
                return new ResponsePack () { StateCode = ErrorCode.NetworkError };
            }
            #endregion
        }
        public const int TIME_OUT_20 = 30;
        /// <summary>
        /// 下载文件方法
        /// </summary>
        /// <param name="methodType"></param>
        /// <param name="dataStringJson"></param>
        /// <param name="urlHead"></param>
        /// <param name="mTimeout"></param>
        /// <param name="requestMethod"></param>
        /// <returns></returns>
        public static byte [] RequestHttpsReturnByteNew (string methodType, string dataStringJson, string urlHead = "", int mTimeout = 20, string requestMethod = "POST")
        {
            try {
                #region
                if (urlHead == "") {
                    urlHead = RequestHttpsHost;
                }
                string requestFullUrl = urlHead + methodType;
                //初始化新的webRequst
                //1. 创建httpWebRequest对象
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create (new Uri (requestFullUrl));
                //2. 初始化HttpWebRequest对象
                webRequest.Method = requestMethod;
                //webRequest.Timeout = timeout * 1000;
                //取消使用代理访问
                webRequest.Proxy = null;
                webRequest.UseDefaultCredentials = false;
                if (requestMethod == "GET") {
                    webRequest.ContentType = "application/json";
                } else {
                    var byteData = Encoding.UTF8.GetBytes (dataStringJson);
                    webRequest.ContentType = "application/json";
                    webRequest.ContentLength = byteData.Length;
                    //3. 附加要POST给服务器的数据到HttpWebRequest对象(附加POST数据的过程比较特殊,它并没有提供一个属性给用户存取,需要写入HttpWebRequest对象提供的一个stream里面。)
                    var newStream = webRequest.GetRequestStream ();//创建一个Stream,赋值是写入HttpWebRequest对象提供的一个stream里面
                    newStream.Write (byteData, 0, byteData.Length);
                    newStream.Flush ();
                    newStream.Close ();
                }
                //4. 读取服务器的返回信息
                var response = (HttpWebResponse)webRequest.GetResponse ();
                using (var stream = response.GetResponseStream ()) {
                    if (stream == null) {
                        return null;
                    }
                    var ms = new MemoryStream ();
                    var bytes = new byte [1024];
                    var len = int.MaxValue;
                    while (stream.CanRead && 0 < len) {
                        len = stream.Read (bytes, 0, bytes.Length);
                        ms.Write (bytes, 0, len);
                    }
                    return ms.ToArray ();
                }
                #endregion
            } catch (WebException e) {
                //if (e.Status == WebExceptionStatus.ConnectFailure//由有网络切换到无网络时触发
                //    || e.Status == WebExceptionStatus.Timeout//超时
                //    || e.Status == WebExceptionStatus.NameResolutionFailure)//本身就是无网络时启动时触发
                //{
                //    //Phone.UserCenter.HdlWifiLogic.Current.CanAccessHttp = false;
                //}
                return null;
            } catch (Exception e) {
                return null;
            }
        }
        #region LoadingTipMsg 远程连接Tip
        static Button btnLoadingTipMsg;
        public static void LoadingTipShow (string tip)
        {
            if (MainFrameLayout == null) {
                return;
            }
            Application.RunOnMainThread (() => {
                try {
                    if (btnLoadingTipMsg == null) {
                        btnLoadingTipMsg = new Button () {
                            Height = Application.GetRealHeight (90),
                            BackgroundColor = SkinStyle.Current.MainColor,
                            //BackgroundColor = 0xFF000000,
                            Y = Application.GetRealHeight (36),
                            TextAlignment = TextAlignment.Center,
                            TextColor = 0xFF000000,
                        };
                    }
                    if (btnLoadingTipMsg.Parent == null) {
                        MainFrameLayout.AddChidren (btnLoadingTipMsg);
                        if (btnLoadingTipMsg.MouseUpEventHandler == null) {
                            btnLoadingTipMsg.MouseUpEventHandler += (sender, e) => {
                                if (btnLoadingTipMsg.Parent != null)
                                    btnLoadingTipMsg.RemoveFromParent ();
                            };
                        }
                    }
                    btnLoadingTipMsg.Text = tip;
                } catch { }
            });
        }
        public static void LoadingTipHide ()
        {
            if (MainFrameLayout == null) {
                return;
            }
            Application.RunOnMainThread (() => {
                try {
                    if (btnLoadingTipMsg != null) {
                        if (btnLoadingTipMsg.Parent != null)
                            btnLoadingTipMsg.RemoveFromParent ();
                    }
                } catch { }
            });
        }
        #endregion
        /// <summary>
        /// 连接服务器失败
        /// </summary>
        public static void FailureToServer ()
        {
            //Application.RunOnMainThread (() => {
            //    new Alert ("", Language.StringByID (R.MyInternationalizationString.FailureToServer),
            //               Language.StringByID (R.MyInternationalizationString.Close)).Show ();
            //});
            ShowAlertOnMainThread (Language.StringByID (R.MyInternationalizationString.FailureToServer));
        }
        /// <summary>
        /// 2020-01-11 弹窗提示
        /// </summary>
        /// <param name="mes"></param>
        public static void ShowAlertOnMainThread (string mes)
        {
            Application.RunOnMainThread (() => {
                new Alert ("", Language.StringByID (R.MyInternationalizationString.FailureToServer),
                           Language.StringByID (R.MyInternationalizationString.Close)).Show ();
                new Alert ("", mes, Language.StringByID (R.MyInternationalizationString.Close)).Show ();
            });
        }
        /// <summary>
        /// 设备不在线,无响应
@@ -294,11 +660,21 @@
            });
        }
        public static void LoadingSetText (string showString = "")
        {
            Application.RunOnMainThread (() => {
                MainPage.Loading.Text = showString;
            });
        }
        public static void LoadingHide ()
        {
            Application.RunOnMainThread (() => {
                MainPage.Loading.Hide ();
            });
        }
    }
}
}