YaskawaNX100ControllerSimulator.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. using System;
  2. using System.Threading;
  3. using MECF.Framework.Simulator.Core.Driver;
  4. namespace MECF.Framework.Simulator.Core.Robots
  5. {
  6. public class YaskawaNX100ControllerSimulator : SocketDeviceSimulator
  7. {
  8. protected Random _rd = new Random();
  9. public bool Failed { get; set; }
  10. public string ResultValue { get; set; }
  11. public YaskawaNX100ControllerSimulator(int port)
  12. :base(port, 4, "\r", ' ')
  13. {
  14. //Action Command
  15. AddCommandHandler("INIT", HandleINIT);
  16. AddCommandHandler("MHOM", HandleMHOM);
  17. AddCommandHandler("MTRG", HandleMTRG);
  18. AddCommandHandler("MTRE", HandleMTRE);
  19. AddCommandHandler("MTGO", HandleMTGO);
  20. AddCommandHandler("MTPO", HandleMTPO);
  21. AddCommandHandler("MTRP", HandleMTRP);
  22. AddCommandHandler("MMAP", HandleMMAP);
  23. AddCommandHandler("MALN", HandleMALN);
  24. AddCommandHandler("MPNT", HandleMPNT);
  25. AddCommandHandler("MTPT", HandleMTPT);
  26. AddCommandHandler("MTRS", HandleMTRS);
  27. AddCommandHandler("MEXG", HandleMEXG);
  28. /*
  29. AddCommandHandler("MREL", HandleMREL);
  30. AddCommandHandler("MALN", HandleMALN);
  31. AddCommandHandler("MACA", HandleMACA);
  32. AddCommandHandler("MCTR", HandleMCTR);
  33. AddCommandHandler("MTCH", HandleMTCH);
  34. AddCommandHandler("MABS", HandleMABS);
  35. AddCommandHandler("MMCA", HandleMMCA);
  36. */
  37. //Control Command
  38. AddCommandHandler("CCLR", HandleCCLR);
  39. AddCommandHandler("CSOL", HandleCSOL);
  40. AddCommandHandler("CHLT", HandleCHLT);
  41. AddCommandHandler("CLFT", HandleCLFT);
  42. //AddCommandHandler("CSTP", HandleCSTP);
  43. AddCommandHandler("CRSM", HandleCRSM);
  44. //AddCommandHandler("CSRV", HandleCSRV);
  45. //Setting Command
  46. AddCommandHandler("SSPD", HandleSSPD);
  47. AddCommandHandler("SSLV", HandleSSLV);
  48. AddCommandHandler("SPRM", HandleSPRM);
  49. AddCommandHandler("SMSK", HandleSMSK);
  50. //Reference Command
  51. AddCommandHandler("RMAP", HandleRMAP);
  52. AddCommandHandler("RSTS", HandleRSTS);
  53. /*
  54. AddCommandHandler("RSPD", HandleRSPD);
  55. AddCommandHandler("RSLV", HandleRSLV);
  56. AddCommandHandler("RPRM", HandleRPRM);
  57. AddCommandHandler("RERR", HandleRERR);
  58. AddCommandHandler("RMSK", HandleRMSK);
  59. AddCommandHandler("RVER", HandleRVER);
  60. AddCommandHandler("RALN", HandleRALN);
  61. AddCommandHandler("RACA", HandleRACA);
  62. AddCommandHandler("RCCD", HandleRCCD);
  63. AddCommandHandler("RLOG", HandleRLOG);
  64. AddCommandHandler("RMAP", HandleRMAP);
  65. */
  66. //ACK
  67. AddCommandHandler("ACKN", HandleACKN);
  68. AddCommandHandler("Unknown", HandleUnknown);
  69. }
  70. public virtual void HandleMTRG(string obj)
  71. {
  72. Response("MTRG", obj);
  73. Thread.Sleep(2000);
  74. EndOfExecution(obj);
  75. }
  76. public virtual void HandleMTRE(string obj)
  77. {
  78. Response("MTRE", obj);
  79. Thread.Sleep(1000);
  80. EndOfExecution(obj);
  81. }
  82. public virtual void HandleMTPO(string obj)
  83. {
  84. Response("MTPO", obj);
  85. Thread.Sleep(1000);
  86. EndOfExecution(obj);
  87. }
  88. public virtual void HandleMTGO(string obj)
  89. {
  90. Response("MTGO", obj);
  91. Thread.Sleep(1000);
  92. EndOfExecution(obj);
  93. }
  94. public virtual void HandleMTRP(string obj)
  95. {
  96. Response("MTRP", obj);
  97. Thread.Sleep(2000);
  98. EndOfExecution(obj);
  99. }
  100. public virtual void HandleRMAP(string obj)
  101. {
  102. Response("RMAP", obj);
  103. EndOfExecution(obj);
  104. }
  105. public virtual void HandleMMCA(string obj)
  106. {
  107. Response("MMCA", obj);
  108. EndOfExecution(obj);
  109. }
  110. public virtual void HandleMMAP(string msg)
  111. {
  112. string unit = msg.Substring(1, 1);
  113. string seq = msg.Substring(2, 2); ;
  114. string cmd = msg.Substring(4, 4); ;
  115. string sts = 0.ToString("X02");
  116. string Ackcd = 0.ToString("X04");
  117. //$ <UNo> (<SeqNo>) <StsN> <Ackcd> <Sum> <CR>
  118. string feedback = string.Format(",{0},{1},{2},{3},{4},", unit, seq, sts, Ackcd, cmd).Replace(",", "");
  119. string sum = CheckSum(feedback);
  120. string result = String.Format("{0}{1}{2}", "$", feedback, sum);
  121. OnWriteMessage(result);
  122. Thread.Sleep(3000);
  123. int executeTime = _rd.Next(10000, 999999);
  124. string exeTime = executeTime.ToString("D6");
  125. string posData = GetPosData();
  126. string error = 0.ToString("X04");
  127. //! <UNo> (<SeqNo>) <StsN> <Errcd> INIT <Sum> <CR>
  128. feedback = string.Format(",{0},{1},{2},{3},{4},", unit, seq, sts, error, cmd).Replace(",", "");
  129. sum = CheckSum(feedback);
  130. result = String.Format("{0}{1}{2}", "!", feedback, sum);
  131. OnWriteMessage(result);
  132. }
  133. public virtual void HandleMABS(string obj)
  134. {
  135. Response("MABS", obj);
  136. EndOfExecution(obj);
  137. }
  138. public virtual void HandleMTCH(string obj)
  139. {
  140. Response("MTCH", obj);
  141. EndOfExecution(obj);
  142. }
  143. public virtual void HandleMCTR(string obj)
  144. {
  145. Response("MCTR", obj);
  146. EndOfExecution(obj);
  147. }
  148. public virtual void HandleMTRS(string obj)
  149. {
  150. Response("MTRS", obj);
  151. EndOfExecution(obj);
  152. }
  153. public virtual void HandleMPNT(string obj)
  154. {
  155. Response("MPNT", obj);
  156. Thread.Sleep(1000);
  157. EndOfExecution(obj);
  158. }
  159. public virtual void HandleMTPT(string obj)
  160. {
  161. Response("MTPT", obj);
  162. Thread.Sleep(1000);
  163. EndOfExecution(obj);
  164. }
  165. public virtual void HandleMEXG(string obj)
  166. {
  167. Response("MEXG", obj);
  168. Thread.Sleep(1000);
  169. EndOfExecution(obj);
  170. }
  171. public virtual void HandleUnknown(string obj)
  172. {
  173. Response("", obj);
  174. }
  175. private void HandleACKN(string obj)
  176. {
  177. //DO NOTHING
  178. }
  179. private void HandleRLOG(string obj)
  180. {
  181. Response("RLOG", obj);
  182. }
  183. private void HandleRCCD(string obj)
  184. {
  185. Response("RCCD", obj);
  186. }
  187. private void HandleRACA(string obj)
  188. {
  189. Response("RACA", obj);
  190. }
  191. private void HandleRALN(string obj)
  192. {
  193. Response("RALN", obj);
  194. }
  195. private void HandleRVER(string obj)
  196. {
  197. Response("RVER", obj);
  198. }
  199. private void HandleRMSK(string obj)
  200. {
  201. Response("RMSK", obj);
  202. }
  203. private void HandleRERR(string obj)
  204. {
  205. Response("RERR", obj);
  206. }
  207. //$,<UNo>(,<SeqNo>),RSTS(,<Sum>)<CR>
  208. //$ <UNo> (<SeqNo>) <StsN> <Ackcd> <Sum> <CR>
  209. //$ <UNo> (<SeqNo>) <StsN> <Ackcd> <Errcd> <Status1> … <Status4> <Sum> <CR>
  210. public virtual void HandleRSTS(string msg)
  211. {
  212. string unit = msg.Substring(1, 1);
  213. string seq = msg.Substring(2, 2); ;
  214. string cmd = msg.Substring(4, 4); ;
  215. string sts = 0.ToString("X02");
  216. string Ackcd = 0.ToString("X04");
  217. string error = 0.ToString("X04");
  218. int status1 = Convert.ToInt32("0011", 2);
  219. string status = string.Format("{0}000", status1.ToString("X1"));
  220. string feedback = string.Format(",{0},{1},{2},{3},{4},{5}", unit, seq, sts, Ackcd, error, status).Replace(",","");
  221. string sum = CheckSum(feedback);
  222. string result = String.Format("{0}{1}{2}", "$", feedback, sum);
  223. OnWriteMessage(result);
  224. }
  225. private void HandleRPRM(string obj)
  226. {
  227. Response("RPRM", obj);
  228. }
  229. private void HandleRSLV(string obj)
  230. {
  231. Response("RSLV", obj);
  232. }
  233. private void HandleRSPD(string obj)
  234. {
  235. Response("RSPD", obj);
  236. }
  237. private void HandleSMSK(string obj)
  238. {
  239. Response("SMSK", obj);
  240. }
  241. private void HandleSPRM(string obj)
  242. {
  243. Response("SPRM", obj);
  244. }
  245. private void HandleSSLV(string obj)
  246. {
  247. Response("SSLV", obj);
  248. }
  249. private void HandleSSPD(string obj)
  250. {
  251. Response("SSPD", obj);
  252. }
  253. private void HandleCSOL(string obj)
  254. {
  255. Response("CSOL", obj);
  256. EndOfExecution(obj);
  257. }
  258. private void HandleCLFT(string obj)
  259. {
  260. Response("CLFT", obj);
  261. EndOfExecution(obj);
  262. }
  263. private void HandleCHLT(string obj)
  264. {
  265. Response("CHLT", obj);
  266. EndOfExecution(obj);
  267. }
  268. //$,<UNo>(,<SeqNo>),CCLR,<CMode>(,<Sum>)<CR>
  269. //$,<UNo>(,<SeqNo>),<Sts>,<Ackcd>,CCLR,<CMode>(,<Sum>)<CR>
  270. //!,<UNo>(,<SeqNo>),<Sts>,<Errcd>,CCLR,<ExeTime>,<PosData1>…,<PosDataN>(,<Sum>)<CR>
  271. public virtual void HandleCCLR(string msg)
  272. {
  273. string unit = msg.Substring(1, 1);
  274. string seq = msg.Substring(2, 2); ;
  275. string cmd = msg.Substring(4, 4); ;
  276. string sts = 0.ToString("X02");
  277. string Ackcd = 0.ToString("X04");
  278. string feedback1 = string.Format(",{0},{1},{2},{3}", unit, seq, sts, Ackcd).Replace(",", "");
  279. string feedback2 = string.Format(",{0},{1},{2},{3},{4},", unit, seq, sts, Ackcd, cmd).Replace(",", "");
  280. string sum = CheckSum(feedback1);
  281. string result = String.Format("{0}{1}{2}", "$", feedback1, sum);
  282. OnWriteMessage(result);
  283. Thread.Sleep(3000);
  284. sum = CheckSum(feedback2);
  285. result = String.Format("{0}{1}{2}", "!", feedback2, sum);
  286. OnWriteMessage(result);
  287. //int executeTime = _rd.Next(10000, 999999);
  288. //string exeTime = executeTime.ToString("D6");
  289. //string posData = GetPosData();
  290. //string error = 0.ToString("X04");
  291. //feedback = string.Format(",{0},{1},{2},{3},{4},{5},{6},", unit, seq, sts, error, cmd, exeTime, posData).Replace(",", "");
  292. //sum = CheckSum(feedback);
  293. //result = String.Format("{0}{1}{2}", "!", feedback, sum);
  294. //OnWriteMessage(result);
  295. }
  296. private void HandleCSRV(string obj)
  297. {
  298. Response("CSRV", obj);
  299. EndOfExecution(obj);
  300. }
  301. private void HandleCRSM(string obj)
  302. {
  303. Response("CRSM", obj);
  304. EndOfExecution(obj);
  305. }
  306. private void HandleCSTP(string obj)
  307. {
  308. Response("CSTP", obj);
  309. EndOfExecution(obj);
  310. }
  311. private void HandleMACA(string obj)
  312. {
  313. Response("MACA", obj);
  314. EndOfExecution(obj);
  315. }
  316. //$,<UNo>(,<SeqNo>),MALN,<Mode>,<Angle>(,<Sum>)<CR>
  317. //$,<UNo>(,<SeqNo>),<Sts>,<Ackcd>,MALN,<Mode>,<Angle>(,<Sum>)<CR>
  318. //! <UNo> (<SeqNo>) <StsN> <Errcd> MALN<Sum> <CR>
  319. //!,<UNo>(,<SeqNo>),<Sts>,<Errcd>,MALN,<ExeTime>,<PosData1>…,<PosDataN>,<Value1>…,<Value10>(,<Sum>)<CR>
  320. public virtual void HandleMALN(string msg)
  321. {
  322. string unit = msg.Substring(1, 1);
  323. string seq = msg.Substring(2, 2); ;
  324. string cmd = msg.Substring(4, 4); ;
  325. string sts = 0.ToString("X02");
  326. string Ackcd = 0.ToString("X04");
  327. string feedback = string.Format(",{0},{1},{2},{3},{4},", unit, seq, sts, Ackcd, cmd).Replace(",", "");
  328. string sum = CheckSum(feedback);
  329. string result = String.Format("{0}{1}{2}", "$", feedback, sum);
  330. OnWriteMessage(result);
  331. Thread.Sleep(3000);
  332. string error = 0.ToString("X04");
  333. int executeTime = _rd.Next(10000, 999999);
  334. string exeTime = executeTime.ToString("D6");
  335. string posData = GetPosData();
  336. string valueData = GetValueData();
  337. feedback = string.Format(",{0},{1},{2},{3},{4},{5},{6},{7},", unit, seq, sts, error, cmd, exeTime, posData, valueData).Replace(",", "");
  338. sum = CheckSum(feedback);
  339. result = String.Format("{0}{1}{2}", "!", feedback, sum);
  340. OnWriteMessage(result);
  341. }
  342. private void HandleMREL(string obj)
  343. {
  344. Response("MREL", obj);
  345. EndOfExecution(obj);
  346. }
  347. //$,<UNo>(,<SeqNo>),INIT,<ErrClr>,<SrvOn>,<Home>(,<Sum>)<CR>
  348. //$,<UNo>(,<SeqNo>),<Sts>,<Ackcd>,INIT,<ErrClr>,<SrvOn>,<Axis>(,<Sum>)<CR>
  349. //!,<UNo>(,<SeqNo>),<Sts>,<Errcd>,INIT,<ExeTime>,<PosData1>…,<PosDataN>(,<Sum>)<CR>
  350. public virtual void HandleINIT(string msg)
  351. {
  352. string unit = msg.Substring(1, 1);
  353. string seq = msg.Substring(2, 2); ;
  354. string cmd = msg.Substring(4, 4); ;
  355. string sts = 0.ToString("X02");
  356. string Ackcd = 0.ToString("X04");
  357. //$ <UNo> (<SeqNo>) <StsN> <Ackcd> <Sum> <CR>
  358. string feedback = string.Format(",{0},{1},{2},{3}", unit, seq, sts, Ackcd).Replace(",", "");
  359. string sum = CheckSum(feedback);
  360. string result = String.Format("{0}{1}{2}", "$", feedback, sum);
  361. OnWriteMessage(result);
  362. Thread.Sleep(3000);
  363. int executeTime = _rd.Next(10000, 999999);
  364. string exeTime = executeTime.ToString("D6");
  365. string posData = GetPosData();
  366. string error = 0.ToString("X04");
  367. //! <UNo> (<SeqNo>) <StsN> <Errcd> INIT <Sum> <CR>
  368. feedback = string.Format(",{0},{1},{2},{3},{4},", unit, seq, sts, error, cmd).Replace(",", "");
  369. sum = CheckSum(feedback);
  370. result = String.Format("{0}{1}{2}", "!", feedback, sum);
  371. OnWriteMessage(result);
  372. }
  373. public virtual void HandleMHOM(string msg)
  374. {
  375. string unit = msg.Substring(1,1);
  376. string seq = msg.Substring(2, 2); ;
  377. string cmd = msg.Substring(4, 4); ;
  378. string sts = 0.ToString("X02");
  379. string Ackcd = 0.ToString("X04");
  380. //$ <UNo> (<SeqNo>) <StsN> <Ackcd> <Sum> <CR>
  381. string feedback = string.Format(",{0},{1},{2},{3},", unit, seq, sts, Ackcd).Replace(",", "");
  382. string sum = CheckSum(feedback);
  383. string result = String.Format("{0}{1}{2}", "$", feedback, sum);
  384. OnWriteMessage(result);
  385. Thread.Sleep(3000);
  386. int executeTime = _rd.Next(10000, 999999);
  387. string exeTime = executeTime.ToString("D6");
  388. string posData = GetPosData();
  389. string error = 0.ToString("X04");
  390. //! <UNo> (<SeqNo>) <StsN> <Errcd> INIT <Sum> <CR>
  391. feedback = string.Format(",{0},{1},{2},{3},{4},", unit, seq, sts, error, cmd).Replace(",", "");
  392. sum = CheckSum(feedback);
  393. result = String.Format("{0}{1}{2}", "!", feedback, sum);
  394. OnWriteMessage(result);
  395. }
  396. //$,0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 <CR>
  397. //$,<UNo>(,<SeqNo>),<Sts>,<Ackcd>,<Command>,<Parameter>, <Value>(,<Sum>)<CR>
  398. //
  399. public void Response(string cmd, string msg,string data="")
  400. {
  401. string unit = msg.Substring(1, 1);
  402. string seq = msg.Substring(2, 2); ;
  403. string sts = 0.ToString("X02");
  404. string Ackcd = 0.ToString("X04");
  405. int status1 = Convert.ToInt32("0011", 2);
  406. string status = string.Format("{0}000", status1.ToString("X1"));
  407. //$ <UNo> (<SeqNo>) <StsN> <Ackcd> <Sum> <CR>
  408. string feedback = string.Format(",{0},{1},{2},{3},{4}", unit, seq, sts, Ackcd,data).Replace(",", "");
  409. string sum = CheckSum(feedback);
  410. string result = String.Format("{0}{1}{2}", "$", feedback, sum);
  411. OnWriteMessage(result);
  412. }
  413. public string CheckSum(string feedback)
  414. {
  415. int sum = 0;
  416. foreach (var item in feedback)
  417. {
  418. sum += (int)item;
  419. }
  420. sum = sum % 256;
  421. return sum.ToString("X02");
  422. }
  423. public void EndOfExecution(string msg)
  424. {
  425. string[] arrayMsg = msg.Split(',');
  426. string unit = msg.Substring(1, 1);
  427. string seq = msg.Substring(2, 2); ;
  428. string cmd = msg.Substring(4, 4); ;
  429. string sts = 0.ToString("X02");
  430. string Ackcd = Failed ? "33D4" : 0.ToString("X04");
  431. int executeTime = _rd.Next(10000, 999999);
  432. string exeTime = executeTime.ToString("D6");
  433. string posData = 0.ToString("D8");
  434. int status1 = Convert.ToInt32("0011", 2);
  435. string status = string.Format("{0}000", status1.ToString("X1"));
  436. //! < UNo > (< SeqNo >) < StsN > < Errcd > MTRG<Sum> < CR >
  437. string feedback = string.Format(",{0},{1},{2},{3},{4},", unit, seq, sts, Ackcd, cmd).Replace(",", "");
  438. string sum = CheckSum(feedback);
  439. string result = String.Format("{0}{1}{2}", "!", feedback, sum);
  440. OnWriteMessage(result);
  441. }
  442. public string GetPosData()
  443. {
  444. return string.Format("{0},{1},{2},{3},{4}", _rd.Next().ToString("D8"), _rd.Next().ToString("D8"), _rd.Next().ToString("D8"), _rd.Next().ToString("D8"), _rd.Next().ToString("D8"));
  445. }
  446. public string GetValueData()
  447. {
  448. return string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}",
  449. _rd.Next(0, 0).ToString("D8"),
  450. _rd.Next(0, 0).ToString("D8"),
  451. _rd.Next(0, 0).ToString("D8"),
  452. _rd.Next(0, 0).ToString("D8"),
  453. _rd.Next(0, 0).ToString("D8"),
  454. _rd.Next(0, 0).ToString("D8"),
  455. _rd.Next(0, 0).ToString("D8"),
  456. _rd.Next(0, 0).ToString("D8"),
  457. _rd.Next(0, 0).ToString("D8"),
  458. _rd.Next(0, 0).ToString("D8"));
  459. }
  460. public string GetMapData(bool random, bool full)
  461. {
  462. string result="";
  463. for (int i = 0; i < 25; i++)
  464. {
  465. if (random)
  466. {
  467. result += string.Format("{0:00}:{1}", i + 1, _rd.Next(100) > 50 ? "OK" : "--");
  468. }else if (full)
  469. {
  470. result += string.Format("{0:00}:{1}", i + 1, "OK" );
  471. }
  472. else
  473. {
  474. result += string.Format("{0:00}:{1}", i + 1, "--");
  475. }
  476. if (i < 24)
  477. {
  478. result += ",";
  479. }
  480. }
  481. return result;
  482. }
  483. public string GetMapData(bool pre, bool post, bool mid)
  484. {
  485. string result = "";
  486. for (int i = 0; i < 25; i++)
  487. {
  488. if (i < 8)
  489. {
  490. result += string.Format("{0:00}:{1}", i + 1, pre ? "OK" : "--");
  491. }
  492. else if (i < 16)
  493. {
  494. result += string.Format("{0:00}:{1}", i + 1, mid ? "OK" : "--");
  495. }
  496. else
  497. {
  498. result += string.Format("{0:00}:{1}", i + 1, post ? "OK" : "--");
  499. }
  500. if (i < 24)
  501. {
  502. result += ",";
  503. }
  504. }
  505. return result;
  506. }
  507. public string GetMapData(int startslot, int endslot)
  508. {
  509. string result = "";
  510. for (int i = 0; i < 25; i++)
  511. {
  512. if (i >= startslot && i<=endslot)
  513. {
  514. result += string.Format("{0:00}:{1}", i + 1, "OK" );
  515. }
  516. else
  517. {
  518. result += string.Format("{0:00}:{1}", i + 1, "--");
  519. }
  520. if (i < 24)
  521. {
  522. result += ",";
  523. }
  524. }
  525. return result;
  526. }
  527. }
  528. }