GdopHelper.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. 
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Runtime.InteropServices;
  6. namespace XdCxRhDW.Api
  7. {
  8. public static class GdopHelper
  9. {
  10. static readonly DateTime dtZero = new DateTime(1970, 1, 1, 8, 0, 0, 0);
  11. /// <summary>
  12. /// 两星一地GDOP 无参时参考位置不赋值
  13. /// </summary>
  14. /// <param name="mainLines">主星星历</param>
  15. /// <param name="adajLines">邻星星历</param>
  16. /// <param name="captime">信号时间</param>
  17. /// <param name="cdbPos">超短波位置 3</param>
  18. /// <param name="refPos">参考站位置 3</param>
  19. /// <param name="dtousErr">时差误差</param>
  20. /// <param name="ephLocErr">星历误差</param>
  21. /// <returns></returns>
  22. public static (List<MapSatInfo>, List<ErrDistanceMapPoints>) Gdop2Sat1D(string mainLines, string adajLines, DateTime captime, double[] cdbPos, double dtousErr, double ephLocErr, double[] refPos = null)
  23. {
  24. int satCount = 2;
  25. //该值和points 一一对应
  26. double[] level = GdopParam.误差配置.误差距离m;
  27. double[] satllh = new double[satCount * 3];
  28. var timeSpan = (long)(captime - dtZero).TotalSeconds;
  29. IntPtr res = IntPtr.Zero;
  30. int[] resCount = new int[level.Length];
  31. if (refPos == null || refPos.Length == 0)
  32. {
  33. GDOPApi.Gdop2Sat1DNoRef(mainLines, adajLines, timeSpan, cdbPos, dtousErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  34. }
  35. else
  36. {
  37. GDOPApi.Gdop2Sat1DRef(mainLines, adajLines, timeSpan, cdbPos, refPos, dtousErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  38. }
  39. IntPtr tmp = res;
  40. //用于绘制的数据
  41. List<double[]> points = new List<double[]>();
  42. for (int idx = 0; idx < level.Length; ++idx)
  43. {
  44. double[] levelval = new double[resCount[idx]];
  45. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  46. tmp += (resCount[idx] * sizeof(double));
  47. points.Add(levelval);
  48. }
  49. GDOPApi.FreeGDOPBuf(res);
  50. List<MapSatInfo> satInfos = ParseResult(satCount, satllh, mainLines, adajLines);
  51. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  52. for (int i = 0; i < points.Count; i++)
  53. {
  54. if (!points[i].Any()) continue;
  55. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  56. errDistanceMap.ErrDistance = level[i];
  57. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  58. errs.Add(errDistanceMap);
  59. }
  60. return (satInfos, errs);
  61. }
  62. /// <summary>
  63. /// 两星一地GDOP 无参时参考位置不赋值
  64. /// </summary>
  65. /// <param name="mainEph">主星星历 x y z vx vy vz</param>
  66. /// <param name="adajEph">邻星星历x y z vx vy vz</param>
  67. /// <param name="cdbPos">超短波位置 3</param>
  68. /// <param name="refPos">参考站位置 3</param>
  69. /// <param name="dtousErr">时差误差</param>
  70. /// <param name="ephLocErr">星历误差</param>
  71. /// <param name="refPos"></param>
  72. /// <returns></returns>
  73. public static List<ErrDistanceMapPoints> Gdop2Sat1DByXyz(double[] mainEph, double[] adajEph, double[] cdbPos, double dtousErr, double ephLocErr, double[] refPos = null)
  74. {
  75. int satCount = 2;
  76. //该值和points 一一对应
  77. double[] level = GdopParam.误差配置.误差距离m;
  78. double[] satllh = new double[satCount * 3];
  79. IntPtr res = IntPtr.Zero;
  80. int[] resCount = new int[level.Length];
  81. if (refPos == null || refPos.Length == 0)
  82. {
  83. GDOPApi.Gdop2Sat1DNoRefByXyz(mainEph, adajEph, cdbPos, dtousErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  84. }
  85. else
  86. {
  87. GDOPApi.Gdop2Sat1DRefByXyz(mainEph, adajEph, cdbPos, refPos, dtousErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  88. }
  89. IntPtr tmp = res;
  90. //用于绘制的数据
  91. List<double[]> points = new List<double[]>();
  92. for (int idx = 0; idx < level.Length; ++idx)
  93. {
  94. double[] levelval = new double[resCount[idx]];
  95. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  96. tmp += (resCount[idx] * sizeof(double));
  97. points.Add(levelval);
  98. }
  99. GDOPApi.FreeGDOPBuf(res);
  100. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  101. for (int i = 0; i < points.Count; i++)
  102. {
  103. if (!points[i].Any()) continue;
  104. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  105. errDistanceMap.ErrDistance = level[i];
  106. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  107. errs.Add(errDistanceMap);
  108. }
  109. return errs;
  110. }
  111. /// <summary>
  112. /// 一星一地GDOP
  113. /// </summary>
  114. /// <param name="mainLines">主星星历</param>
  115. /// <param name="captime">信号时间</param>
  116. /// <param name="cdbPos">超短波位置 3</param>
  117. /// <param name="cxPos">测向站位置 3</param>
  118. /// <param name="dtousErr">时差误差</param>
  119. /// <param name="doaErr">测向误差</param>
  120. /// <param name="ephLocErr">星历误差</param>
  121. /// <param name="refPos">参考站位置 3</param>
  122. /// <returns></returns>
  123. public static (List<MapSatInfo>, List<ErrDistanceMapPoints>) Gdop1Sat1D(string mainLines, DateTime captime, double[] cdbPos, double[] cxPos, double dtousErr, double doaErr, double ephLocErr, double[] refPos = null)
  124. {
  125. int satCount = 1;
  126. //该值和points 一一对应
  127. double[] level = GdopParam.误差配置.误差距离m;
  128. double[] satllh = new double[satCount * 3];
  129. var timeSpan = (long)(captime - dtZero).TotalSeconds;
  130. IntPtr res = IntPtr.Zero;
  131. int[] resCount = new int[level.Length];
  132. if (refPos == null || refPos.Length == 0)
  133. {
  134. GDOPApi.GdopXDCXNoRef(mainLines, timeSpan, cdbPos, cxPos, dtousErr, doaErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  135. }
  136. else
  137. {
  138. GDOPApi.GdopXDCXRef(mainLines, timeSpan, cdbPos, cxPos, refPos, dtousErr, doaErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  139. }
  140. IntPtr tmp = res;
  141. //用于绘制的数据
  142. List<double[]> points = new List<double[]>();
  143. for (int idx = 0; idx < level.Length; ++idx)
  144. {
  145. double[] levelval = new double[resCount[idx]];
  146. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  147. tmp += (resCount[idx] * sizeof(double));
  148. points.Add(levelval);
  149. }
  150. GDOPApi.FreeGDOPBuf(res);
  151. List<MapSatInfo> satInfos = ParseResult(satCount, satllh, mainLines);
  152. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  153. for (int i = 0; i < points.Count; i++)
  154. {
  155. if (!points[i].Any()) continue;
  156. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  157. errDistanceMap.ErrDistance = level[i];
  158. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  159. errs.Add(errDistanceMap);
  160. }
  161. return (satInfos, errs);
  162. }
  163. public static List<ErrDistanceMapPoints> Gdop1Sat1DByXyz(double[] mainEph, double[] cdbPos, double[] cxPos, double dtousErr, double doaErr, double ephLocErr, double[] refPos = null)
  164. {
  165. int satCount = 1;
  166. //该值和points 一一对应
  167. double[] level = GdopParam.误差配置.误差距离m;
  168. double[] satllh = new double[satCount * 3];
  169. IntPtr res = IntPtr.Zero;
  170. int[] resCount = new int[level.Length];
  171. if (refPos == null || refPos.Length == 0)
  172. {
  173. GDOPApi.GdopXDCXNoRefByXyz(mainEph, cdbPos, cxPos, dtousErr, doaErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  174. }
  175. else
  176. {
  177. GDOPApi.GdopXDCXRefByXyz(mainEph, cdbPos, cxPos, refPos, dtousErr, doaErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  178. }
  179. IntPtr tmp = res;
  180. //用于绘制的数据
  181. List<double[]> points = new List<double[]>();
  182. for (int idx = 0; idx < level.Length; ++idx)
  183. {
  184. double[] levelval = new double[resCount[idx]];
  185. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  186. tmp += (resCount[idx] * sizeof(double));
  187. points.Add(levelval);
  188. }
  189. GDOPApi.FreeGDOPBuf(res);
  190. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  191. for (int i = 0; i < points.Count; i++)
  192. {
  193. if (!points[i].Any()) continue;
  194. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  195. errDistanceMap.ErrDistance = level[i];
  196. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  197. errs.Add(errDistanceMap);
  198. }
  199. return errs;
  200. }
  201. public static (List<MapSatInfo>, List<ErrDistanceMapPoints>) Gdop3Sat(string mainLines, string adajLines, string adajLines2,
  202. DateTime captime, double dtousErr, double ephLocErr, double[] refPos = null)
  203. {
  204. int satCount = 3;
  205. //该值和points 一一对应
  206. double[] level = GdopParam.误差配置.误差距离m;
  207. double[] satllh = new double[satCount * 3];
  208. var timeSpan = (long)(captime - dtZero).TotalSeconds;
  209. IntPtr res = IntPtr.Zero;
  210. int[] resCount = new int[level.Length];
  211. if (refPos == null || refPos.Length == 0)
  212. {
  213. GDOPApi.Gdop3SatNoRef(mainLines, adajLines, adajLines2, timeSpan, dtousErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  214. }
  215. else
  216. {
  217. GDOPApi.Gdop3SatRef(mainLines, adajLines, adajLines2, timeSpan, refPos, dtousErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  218. }
  219. IntPtr tmp = res;
  220. //用于绘制的数据
  221. List<double[]> points = new List<double[]>();
  222. for (int idx = 0; idx < level.Length; ++idx)
  223. {
  224. double[] levelval = new double[resCount[idx]];
  225. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  226. tmp += (resCount[idx] * sizeof(double));
  227. points.Add(levelval);
  228. }
  229. GDOPApi.FreeGDOPBuf(res);
  230. List<MapSatInfo> satInfos = ParseResult(satCount, satllh, mainLines, adajLines, adajLines2);
  231. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  232. for (int i = 0; i < points.Count; i++)
  233. {
  234. if (!points[i].Any()) continue;
  235. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  236. errDistanceMap.ErrDistance = level[i];
  237. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  238. errs.Add(errDistanceMap);
  239. }
  240. return (satInfos, errs);
  241. }
  242. public static List<ErrDistanceMapPoints> Gdop3SatByXyz(double[] mainEph, double[] adaj1Eph, double[] adaj2Eph,
  243. double dtousErr, double ephLocErr, double[] refPos = null)
  244. {
  245. int satCount = 3;
  246. //该值和points 一一对应
  247. double[] level = GdopParam.误差配置.误差距离m;
  248. double[] satllh = new double[satCount * 3];
  249. IntPtr res = IntPtr.Zero;
  250. int[] resCount = new int[level.Length];
  251. if (refPos == null || refPos.Length == 0)
  252. {
  253. GDOPApi.Gdop3SatNoRefByXyz(mainEph, adaj1Eph, adaj2Eph, dtousErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  254. }
  255. else
  256. {
  257. GDOPApi.Gdop3SatRefByXyz(mainEph, adaj1Eph, adaj2Eph, refPos, dtousErr, ephLocErr, level, level.Length, resCount, out res, satllh);
  258. }
  259. IntPtr tmp = res;
  260. //用于绘制的数据
  261. List<double[]> points = new List<double[]>();
  262. for (int idx = 0; idx < level.Length; ++idx)
  263. {
  264. double[] levelval = new double[resCount[idx]];
  265. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  266. tmp += (resCount[idx] * sizeof(double));
  267. points.Add(levelval);
  268. }
  269. GDOPApi.FreeGDOPBuf(res);
  270. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  271. for (int i = 0; i < points.Count; i++)
  272. {
  273. if (!points[i].Any()) continue;
  274. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  275. errDistanceMap.ErrDistance = level[i];
  276. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  277. errs.Add(errDistanceMap);
  278. }
  279. return errs;
  280. }
  281. public static (List<MapSatInfo>, List<ErrDistanceMapPoints>) Gdop3SatDF(string mainLines, string adajLines, string adajLines2,
  282. DateTime captime, double fuHz1, double fuHz2, double dfoErr, double ephLocErr, double ephVErr, double[] refPos)
  283. {
  284. int satCount = 3;
  285. //该值和points 一一对应
  286. double[] level = GdopParam.误差配置.误差距离m;
  287. double[] satllh = new double[satCount * 3];
  288. var timeSpan = (long)(captime - dtZero).TotalSeconds;
  289. IntPtr res = IntPtr.Zero;
  290. int[] resCount = new int[level.Length];
  291. GDOPApi.Gdop3SatDF(mainLines, adajLines, adajLines2, timeSpan, refPos, fuHz1, fuHz2, dfoErr, ephLocErr, ephVErr, level, level.Length, resCount, out res, satllh);
  292. IntPtr tmp = res;
  293. //用于绘制的数据
  294. List<double[]> points = new List<double[]>();
  295. for (int idx = 0; idx < level.Length; ++idx)
  296. {
  297. double[] levelval = new double[resCount[idx]];
  298. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  299. tmp += (resCount[idx] * sizeof(double));
  300. points.Add(levelval);
  301. }
  302. GDOPApi.FreeGDOPBuf(res);
  303. List<MapSatInfo> satInfos = ParseResult(satCount, satllh, mainLines, adajLines, adajLines2);
  304. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  305. for (int i = 0; i < points.Count; i++)
  306. {
  307. if (!points[i].Any()) continue;
  308. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  309. errDistanceMap.ErrDistance = level[i];
  310. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  311. errs.Add(errDistanceMap);
  312. }
  313. return (satInfos, errs);
  314. }
  315. public static List<ErrDistanceMapPoints> Gdop3SatDFByXyz(double[] mainEph, double[] adaj1Eph, double[] adaj2Eph,
  316. double fuHz1, double fuHz2, double dfoErr, double ephLocErr, double ephVErr, double[] refPos)
  317. {
  318. int satCount = 3;
  319. //该值和points 一一对应
  320. double[] level = GdopParam.误差配置.误差距离m;
  321. double[] satllh = new double[satCount * 3];
  322. IntPtr res = IntPtr.Zero;
  323. int[] resCount = new int[level.Length];
  324. GDOPApi.Gdop3SatDFByXyz(mainEph, adaj1Eph, adaj2Eph, refPos, fuHz1, fuHz2, dfoErr, ephLocErr, ephVErr, level, level.Length, resCount, out res, satllh);
  325. IntPtr tmp = res;
  326. //用于绘制的数据
  327. List<double[]> points = new List<double[]>();
  328. for (int idx = 0; idx < level.Length; ++idx)
  329. {
  330. double[] levelval = new double[resCount[idx]];
  331. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  332. tmp += (resCount[idx] * sizeof(double));
  333. points.Add(levelval);
  334. }
  335. GDOPApi.FreeGDOPBuf(res);
  336. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  337. for (int i = 0; i < points.Count; i++)
  338. {
  339. if (!points[i].Any()) continue;
  340. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  341. errDistanceMap.ErrDistance = level[i];
  342. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  343. errs.Add(errDistanceMap);
  344. }
  345. return errs;
  346. }
  347. public static (List<MapSatInfo>, List<ErrDistanceMapPoints>) Gdop2SatDRef(string mainLines, string adajLines,
  348. DateTime captime, double fuHz1, double fuHz2, double dtousErr, double dfoErr, double ephLocErr, double ephVErr, double[] refPos)
  349. {
  350. int satCount = 2;
  351. //该值和points 一一对应
  352. double[] level = GdopParam.误差配置.误差距离m;
  353. double[] satllh = new double[satCount * 3];
  354. var timeSpan = (long)(captime - dtZero).TotalSeconds;
  355. IntPtr res = IntPtr.Zero;
  356. int[] resCount = new int[level.Length];
  357. GDOPApi.Gdop2SatDRef(mainLines, adajLines, timeSpan, refPos, fuHz1, fuHz2, dtousErr, dfoErr, ephLocErr, ephVErr, level, level.Length, resCount, out res, satllh);
  358. IntPtr tmp = res;
  359. //用于绘制的数据
  360. List<double[]> points = new List<double[]>();
  361. for (int idx = 0; idx < level.Length; ++idx)
  362. {
  363. double[] levelval = new double[resCount[idx]];
  364. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  365. tmp += (resCount[idx] * sizeof(double));
  366. points.Add(levelval);
  367. }
  368. GDOPApi.FreeGDOPBuf(res);
  369. List<MapSatInfo> satInfos = ParseResult(satCount, satllh, mainLines, adajLines);
  370. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  371. for (int i = 0; i < points.Count; i++)
  372. {
  373. if (!points[i].Any()) continue;
  374. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  375. errDistanceMap.ErrDistance = level[i];
  376. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  377. errs.Add(errDistanceMap);
  378. }
  379. return (satInfos, errs);
  380. }
  381. public static List<ErrDistanceMapPoints> Gdop2SatDRefByXyz(double[] mainEph, double[] adajEph, double fuHz1, double fuHz2, double dtousErr, double dfoErr, double ephLocErr, double ephVErr, double[] refPos)
  382. {
  383. int satCount = 2;
  384. //该值和points 一一对应
  385. double[] level = GdopParam.误差配置.误差距离m;
  386. double[] satllh = new double[satCount * 3];
  387. IntPtr res = IntPtr.Zero;
  388. int[] resCount = new int[level.Length];
  389. GDOPApi.Gdop2SatDRefByXyz(mainEph, adajEph, refPos, fuHz1, fuHz2, dtousErr, dfoErr, ephLocErr, ephVErr, level, level.Length, resCount, out res, satllh);
  390. IntPtr tmp = res;
  391. //用于绘制的数据
  392. List<double[]> points = new List<double[]>();
  393. for (int idx = 0; idx < level.Length; ++idx)
  394. {
  395. double[] levelval = new double[resCount[idx]];
  396. Marshal.Copy(tmp, levelval, 0, resCount[idx]);
  397. tmp += (resCount[idx] * sizeof(double));
  398. points.Add(levelval);
  399. }
  400. GDOPApi.FreeGDOPBuf(res);
  401. List<ErrDistanceMapPoints> errs = new List<ErrDistanceMapPoints>();
  402. for (int i = 0; i < points.Count; i++)
  403. {
  404. if (!points[i].Any()) continue;
  405. ErrDistanceMapPoints errDistanceMap = new ErrDistanceMapPoints();
  406. errDistanceMap.ErrDistance = level[i];
  407. errDistanceMap.MapDots.AddRange(ParseResult(points[i]));
  408. errs.Add(errDistanceMap);
  409. }
  410. return errs;
  411. }
  412. private static List<MapDot> ParseResult(double[] ponits)
  413. {
  414. List<MapDot> mapDots = new List<MapDot>();
  415. int count = 2;
  416. for (int i = 0; i < ponits.Length / count; i++)
  417. {
  418. MapDot mapDot = new MapDot();
  419. mapDot.Lon = ponits[count * i];
  420. mapDot.Lat = ponits[count * i + 1];//0 1 2 3 4 5 6 7
  421. mapDots.Add(mapDot);
  422. }
  423. return mapDots;
  424. }
  425. private static List<MapSatInfo> ParseResult(int satCount, double[] satllh, params string[] ephLine)
  426. {
  427. List<MapSatInfo> list = new List<MapSatInfo>();
  428. int len = 3;
  429. for (int i = 0; i < satCount; i++)
  430. {
  431. MapSatInfo satInfo = new MapSatInfo();
  432. var ephstrs = ephLine[i].Split(new string[] { " ", "U" }, StringSplitOptions.RemoveEmptyEntries);
  433. if (ephstrs.Length == 16)
  434. {
  435. satInfo.SatCode = Convert.ToInt32(ephstrs[1]);
  436. }
  437. satInfo.SatLon = Convert.ToDouble(satllh[len * i]);
  438. satInfo.SatLat = Convert.ToDouble(satllh[len * i + 1]);
  439. list.Add(satInfo);
  440. }
  441. return list;
  442. }
  443. }
  444. }