devicely 2.1.3 ā 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/devicely.js +105 -1
- package/lib/androidDeviceDetection.js +276 -1
- package/lib/appMappings.js +337 -1
- package/lib/deviceDetection.js +394 -1
- package/lib/devices.js +54 -1
- package/lib/doctor.js +94 -1
- package/lib/executor.js +104 -1
- package/lib/logger.js +35 -1
- package/lib/scriptLoader.js +75 -0
- package/lib/server.js +3483 -1
- package/package.json +3 -12
- package/scripts/compile-shell-scripts.js +208 -0
- package/scripts/encrypt-shell-simple.js +75 -0
- package/scripts/obfuscate-shell.js +160 -0
- package/scripts/shell/android_device_control +0 -0
- package/scripts/shell/android_device_control.sh +848 -0
- package/scripts/shell/apps_presets.conf +271 -0
- package/scripts/shell/connect_android_usb +0 -0
- package/scripts/shell/connect_android_usb_multi_final +0 -0
- package/scripts/shell/connect_android_usb_multi_final.sh +289 -0
- package/scripts/shell/connect_android_wireless +0 -0
- package/scripts/shell/connect_android_wireless.sh +58 -0
- package/scripts/shell/connect_android_wireless_multi_final +0 -0
- package/scripts/shell/connect_android_wireless_multi_final.sh +476 -0
- package/scripts/shell/connect_ios_usb +0 -0
- package/scripts/shell/connect_ios_usb_multi_final +0 -0
- package/scripts/shell/connect_ios_usb_multi_final.sh +4225 -0
- package/scripts/shell/connect_ios_wireless_multi_final +0 -0
- package/scripts/shell/connect_ios_wireless_multi_final.sh +4167 -0
- package/scripts/shell/create_production_scripts +0 -0
- package/scripts/shell/create_production_scripts.sh +38 -0
- package/scripts/shell/devices.conf +24 -0
- package/scripts/shell/diagnose_wireless_ios +0 -0
- package/scripts/shell/find_element_coordinates +0 -0
- package/scripts/shell/find_wda +0 -0
- package/scripts/shell/install_uiautomator2 +0 -0
- package/scripts/shell/install_uiautomator2.sh +93 -0
- package/scripts/shell/ios_device_control +0 -0
- package/scripts/shell/ios_device_control.sh +220 -0
- package/scripts/shell/organize_project +0 -0
- package/scripts/shell/organize_project.sh +59 -0
- package/scripts/shell/pre-publish-check +0 -0
- package/scripts/shell/pre-publish-check.sh +238 -0
- package/scripts/shell/publish +0 -0
- package/scripts/shell/publish-to-npm +0 -0
- package/scripts/shell/publish-to-npm.sh +366 -0
- package/scripts/shell/publish.sh +100 -0
- package/scripts/shell/setup +0 -0
- package/scripts/shell/setup.sh +121 -0
- package/scripts/shell/setup_android +0 -0
- package/scripts/shell/start +0 -0
- package/scripts/shell/start.sh +59 -0
- package/scripts/shell/sync-to-npm-package-final +0 -0
- package/scripts/shell/sync-to-npm-package-final.sh +60 -0
- package/scripts/shell/test-local-package.sh +95 -0
- package/scripts/shell/test_android_locators +0 -0
- package/scripts/shell/test_connect +0 -0
- package/scripts/shell/test_device_detection +0 -0
- package/scripts/shell/test_fixes +0 -0
- package/scripts/shell/test_getlocators_fix +0 -0
- package/scripts/shell/test_recording_feature +0 -0
- package/scripts/shell/verify-shell-protection +0 -0
- package/scripts/shell/verify-shell-protection.sh +73 -0
- package/scripts/shell/verify_distribution +0 -0
- package/lib/package-lock.json +0 -1678
- package/lib/package.json +0 -30
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_225900.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_225942.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_231101.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_232911.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260208_095103.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260208_095720.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115040.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115047.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115118.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115125.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115143.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120107.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120118.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120137.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120201.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_134529.png +0 -0
- package/scripts/shell/android_device_control.enc +0 -1
- package/scripts/shell/connect_android_usb_multi_final.enc +0 -1
- package/scripts/shell/connect_android_wireless.enc +0 -1
- package/scripts/shell/connect_android_wireless_multi_final.enc +0 -1
- package/scripts/shell/connect_ios_usb_multi_final.enc +0 -1
- package/scripts/shell/connect_ios_wireless_multi_final.enc +0 -1
- package/scripts/shell/ios_device_control.enc +0 -1
package/lib/server.js
CHANGED
|
@@ -1 +1,3483 @@
|
|
|
1
|
-
const _0x47c41d=_0x4c0b;(function(_0x1f5ccc,_0x5a72e5){const _0x54f4d6=_0x4c0b,_0x5f0b76=_0x1f5ccc();while(!![]){try{const _0xb7eaf2=-parseInt(_0x54f4d6(0x63a))/0x1+-parseInt(_0x54f4d6(0x3d0))/0x2*(-parseInt(_0x54f4d6(0x2a8))/0x3)+-parseInt(_0x54f4d6(0x39a))/0x4*(parseInt(_0x54f4d6(0x353))/0x5)+-parseInt(_0x54f4d6(0x277))/0x6*(-parseInt(_0x54f4d6(0x37f))/0x7)+parseInt(_0x54f4d6(0x56f))/0x8*(parseInt(_0x54f4d6(0x52a))/0x9)+-parseInt(_0x54f4d6(0x40d))/0xa*(parseInt(_0x54f4d6(0x37d))/0xb)+-parseInt(_0x54f4d6(0x66f))/0xc*(parseInt(_0x54f4d6(0x495))/0xd);if(_0xb7eaf2===_0x5a72e5)break;else _0x5f0b76['push'](_0x5f0b76['shift']());}catch(_0xbc271b){_0x5f0b76['push'](_0x5f0b76['shift']());}}}(_0x3d34,0x92c6e));const path=require(_0x47c41d(0x793));require(_0x47c41d(0x46c))[_0x47c41d(0x8b5)]({'path':path['join'](__dirname,_0x47c41d(0x2b3))});const express=require(_0x47c41d(0x573)),cors=require(_0x47c41d(0x603)),{spawn}=require('child_process'),WebSocket=require('ws'),fs=require('fs')[_0x47c41d(0x690)],AIProviderManager=require(_0x47c41d(0x5c7));let discoverAllDevices;try{({discoverAllDevices}=require(_0x47c41d(0x4b9)));}catch(_0x36b9c0){({discoverAllDevices}=require('../../deviceDetection'));}const {execSync}=require(_0x47c41d(0x41c)),app=express(),PORT=process.env.PORT||0xbb9;app['use'](cors()),app['use'](express[_0x47c41d(0x843)]());const frontendPath=require('fs')[_0x47c41d(0x730)](path[_0x47c41d(0x5c8)](__dirname,_0x47c41d(0x50c)))?path[_0x47c41d(0x5c8)](__dirname,'../frontend/build'):path[_0x47c41d(0x5c8)](__dirname,'./frontend');app[_0x47c41d(0x5c6)](express[_0x47c41d(0x2f1)](frontendPath));const _0x1094d3={};_0x1094d3[_0x47c41d(0x656)]=!![];function _0x3d34(){const _0x5f1800=['4PQG77IpicbPChjVEhKGChjVy2vZCYa','l2fWAs9SB2nHDg9YCY9JBgLJAW','CKfRqM4','BuH4CNu','qML0yxK','tM8Gzgv2AwnLCYb0BYbKAxnJB25Uzwn0','uKjpwLq','sw52ywXPzcbKzxzPy2uGB2jQzwn0','EhzYsha','vvDsqNq','C0DZC04','rwX4q3y','Aezorfq','iIaO','iIaYpIyX','ANj4y1u','l2fWAs9KzxzPy2vZl2rPC2nVBM5Ly3q','BwfPBG','y29UBMvJDgLUzW','u0Lhvevstq','vMfeDNy','y1jAwgu','D29tq1u','ANnVBG','vK12DKq','r0vu','wwDetfG','r1Dut2C','vKfcsuO','uu9kBxq','yxbWC19WCMvZzxrZlMnVBMy','D2rjAfK','suPuDhm','swTQsvO','iI9HChbPDw0TDwLHDxrVBwf0B3iYlxnLCNzLCI1Kzwj1zY1HBMrYB2LKvgvZDc5HCgSGmJ4Vzgv2l251BgWGFhWGzwnOBYaIiG','tMnQqMG','CMvQzwn0zwq','vufXuxK','zxHLy3v0zunVBw1HBMqGzMfPBgvKoIa','wgvwzvm','CMvHzezPBgvtEw5J','EhvoDMe','tuXWs08','8j+tSsbeAxnJB25Uzwn0Aw5Nia','4PYfifvjqxv0B21HDg9YmIbPBNn0ywXSzwqGC3vJy2vZC2z1BgX5ig9Uia','C3vJy2vZCW','ENHRyK4','svbit05ft1nFrevqte9ztuvovf9uqvjhrvq9mtqUma','cUkwTU+4JYaGrxHLy3v0Aw5NignVBw1HBMqG','sgHjru8','v2vIu29JA2v0ignVBM5Ly3rPB24Gy2XVC2vK','vLHfqNK','wKLSs2S','q2zXqMW','D01WELO','v0fusNy','sxnzA1O','reLmt1q','rfHhtxq','C2HLBgW','rgLZy29UBMvJDgvKigzYB20G','rxbKCg8','r1bZtxC','teTquMS','CNLTzxq','s3brshq','BM9Kzv9TB2r1BgvZ','rNjVBNrLBMqGyxzHAwXHyMXLigf0oIa','qwLYzgy','quLFufjpvKLervi','BK1eDwy','DuXQyLO','4P2miefeqIbLCNjVCJOG','uvbVzeu','A2XYDuu','ww5Wsxi','zwXXyxO','AhnMwhO','BK9TAu0','8j+tVcbszwnVCMrPBMC6ia','DufszeS','CfPhAfm','vhnYtK0','4P2mievYCM9YigrPC2nVBM5Ly3rPBMCGywXSigrLDMLJzxm6','tefOueO','zMT3uNK','DfjjCg8','ic0G','y2XVC2u','rhnkCw4','qvblCYbUB3qGzM91BMqUifrYAwvKihrVihjLAw5ZDgfSBcbKCML2zxiUifbSzwfZzsbYDw46igfWCgL1BsbKCML2zxiGAw5ZDgfSBcb1Awf1Dg9TyxrVCJi','wNnUyLO','wgTQz0G','zhvfshO','4P2miezHAwXLzcb0BYbZyxzLihnLC3nPB24GzM9Yia','B3v0Chv0','iIdIHPiGiG','wMjgvwS','wKzrsKS','4PYfie5LDYbZzxnZAw9UignYzwf0zwqGyw5KihnHDMvKoIa','v3Liuha','uvrhv3K','EMLlCxK','DhDvA2y','sezft0y','zuTrqKq','yKHgwKG','vNrKtLK','C0zLBwG','Exn0EvG','z2v0q3vYCMvUDfbYB3zPzgvY','A1LiDuS','qKn2wfO','v2vIrhjPDMvYqwDLBNq','z2fUq0G','BwzMBxi','Eg94CNu','l2fWAs9HAs9WCM92AwrLCG','cUkAOo+4JYaGrxjYB3i6ierLDMLJzxmGBM90ignVBM5Ly3rLzdOG','CgjVtwi','y2jUtvK','A3PAD1e','zfD2wLe','tgPvq0y','qMz2ugm','r1jpuv9bueLFs0vzpq','zNffDui','vKvpvu4','4PQG77IpicbgywLSzwqGDg8GDxbKyxrLihnLC3nPB24GzMLSztOG','DgLTzw91Da','lIbqBgvHC2uGy2XPy2SGiKnVBM5Ly3qIigj1DhrVBIbVBIbLywnOigrLDMLJzsbMAxjZDc4','ENbztwi','z0L0tMe','uM9kBgy','tfresuu','qvzftLa','Bhbqv2G','y29UzMLN','Bej2D1y','l3DKl2H1yI9ZzxnZAw9U','wNnLvhi','ihzPysbxAuzPic0Gv0rbifn0yxj0zwqH','vNP0y00','uvbUwMG','t0fRDuC','DvfiELC','4P2mifvjqxv0B21HDg9YmIbPBNn0ywXSyxrPB24GzxjYB3i6','vxnPBMCGqw5KCM9PzcbJB250CM9SihnJCMLWDcbMB3iGD2LYzwXLC3mGzgv2AwnLCZOG','y2XPy2SGiG','cVcFLRhVUi8GqvbjoIbdBgLJA2LUzYbSB2nHDg9Yici','rxjYB3iGCMvHzgLUzYbYzwnVCMrPBMCG','l2fWAs9HChbZl2LUzM8','qLjNwNC','t2ffsK8','r3PtCwe','iYbuExbLoIb1C2iGFcb3AxjLBgvZCWO','CMvZB3vYy2vjza','revNueS','C0T4rKm','lI4U','4P2miezHAwXLzcb0BYbPBNn0ywXSifvjqxv0B21HDg9YmJOG','zgf0yq','8j+tNsbgywXSyMfJAYb0BYb0zxH0ihbHCNnPBMCUlI4','BvfmvuC','y2XHDwrLx2fWAv9RzxK','B2TyquW','rMfPBgvKihrVihbHCNnLifDeqsbZzxnZAw9UihjLC3bVBNnLoG','q01xA3u','B3DPv1m','EeHcBwC','s1DhCeK','ugHuwfq','CNfMveK','t3PjDMy','4O+ZifDHAxrPBMCG','BMHQBNC','AhncAwy','EgzYyK8','DurZtxm','4PQG77IpicbdB3vSzcbUB3qGC3rVCcbvsuf1Dg9TyxrVCJiGC2vYDMvYoIa','BuHwrNm','4PYtvMLZ','AwrLDMLJzwLUC3rHBgXLCIaTDsa','Au9t','vuHqDNi','wvvkt0S','ignVBM5Ly3rLzcaTifDeqsbszwfKEsek','rKfIr0S','4PQG77IpicbfEgLZDgLUzYbZzxnZAw9UigLUDMfSAwqSignYzwf0Aw5Nig5LDYbVBMuGzM9Yia','4PYfifbVCNqGzM9YD2fYzgLUzYbYzw1VDMvKigzVCIa','z3DdsLK','CgfYC2u','B1j6s00','A3HxD2q','v1HoDgy','u0PZBwG','rgv2AwnLCYbYzwnLAxzLzdOGwW','tuX0Cve','A09OD20','DwrPza','AMngB0K','icH3AxjLBgvZCYKUifbYB2nLC3mGsuq6ia','8j+AGcbtDgfYDgLUzYbUzxCGvuLbDxrVBwf0B3iYihnLC3nPB24GB24G','r3noufO','tvb2Dxu','C1vJwLi','B3jPz2LUywW','sgrerhC','4PYfifnLC3nPB24GzMLSzsb1CgrHDgvKoIa','v1PJyu8','vunREgy','lI4VC2nYAxb0CY9ZAgvSBc8','BfnUBwe','l2fWAs9Zy3jLzw5ZAg90CW','lcbWBgf0zM9YBtOG','C3jJsLa','CePTt20','s3vmEgC','v0XtsK8','Dw5Yzwy','vergALe','q0zIquS','EwLwrxe','DMLZAwjSzq','ExDfz1m','yxHPB3m','qvvjqK8','t1bftKfjx0fqsv9lrvK','y29UDMvYDenVBw1HBMq','t3jPz2LUywWGzgv2AwnLCZOG','qxv0BY1JB25Uzwn0Aw9UigzHAwXLzdOG','ENbkBKC','rMfPBgvKihrVigv4zwn1DguGDgfW','C2XPy2u','BK9Sz3a','EgTRu04','uvDvBgG','yxndwhG','sw1iv2K','tM14Bu8','ywrI','ls1TyxGTDgLTzq','zKrkwMi','DMfZAfe','v0fhvvC','vgfYz2v0igrLDMLJzxmGCMvXDwLYzwq','wKTlwuG','wfrdDK8','ExPUyKW','4P2miefqssbLCNjVCJO','DgXkzeW','AezHs0y','wMvKrwK','q09irvjfx0fqsv9lrvK9','rMfPBgvKihrVigDLDcbvssbLBgvTzw50CY4GugXLyxnLigvUC3vYzsbvsuf1Dg9TyxrVCJiGAxmGAw5ZDgfSBgvKigzVCIbbBMrYB2LKigrLDMLJzxmU','vLL3tvK','CMvZDwX0CW','weDVAM0','seDRELO','rwPjquq','tu5PEg8','ugTIBLi','zxfpsgG','sNrPqKu','8j+tSsbezxzPy2uGvurjrdOG','A0zws0q','Dgv4Da','A1rtzK4','u2nYAxb0ihjLC3vSDdO','r1P2rvu','vxnLiefjoIa','4PQG77IpifDeqsbfCNjVCIaO','yMfZzw5HBwu','CeHPs1q','zwjJs0e','D0rhAhO','sLLXEva','CMvHzhLtDgf0zq','4P2miezHAwXLzcb0BYbZDgfYDcbvsuf1Dg9TyxrVCJiGzM9Yia','uKjnqNC','uMvWBgf5ihn0yxj0zwq','vhrxD1y','rxjYB3iGCgfYC2LUzYbSB2nHDg9YigXPBMu6','y29TBwfUzf9VDxrWDxq','wxHJuuG','y01qC2q','r0nKCvu','rxjYB3iGyxv0BY1ZyxzPBMCGzgv2AwnLCZO','D2DIDwm','A09dq2y','zxHPC3rPBMC','ExD4sw0','4PYfifnLC3nPB24GDMvYAwzPzwqGyw5KihDVCMTPBMCGB24G','rgv2AwnLCZOGwW','8j+tSsbxreeGka','s05jtwC','zwnQBeG','EfzutwS','ywXSu2v0DgXLza','tfnRsuS','DvfTEfy','ChHZquO','C3rYAw5N','zKj1txm','B0vREuS','v0vcu09ds0vuoIbszwnLAxzLzcbLEgvJDxrLx2nVBw1HBMq','B1DIv2q','CfPAD0C','y29VCMrPBMf0zxm','zgv2AwnLtMfTzq','4PYfifDeqsbHBhjLywr5ihj1BM5PBMCGzM9Yia','DgvZDa','v01ovxe','u2vYDMvY','4PQG77IpicboBYbHy3rPDMuGC2vZC2LVBIbMB3vUzcbMB3iG','zwrvCMe','CLLmCKO','ExbQqMq','mZeYALPhAhzV','BfLkuum','CMvWBgf5x2nVBxbSzxrL','icaGu2vZC2LVBIbjrdOG','qwj0q2S','lMfWCgL1Bq','Ag9tEhy','zgvSzxrL','we9preO','EgnVzgvIDwLSza','CKrUwM4','CLDUzNm','B0T0y3K','y2XPzw50CW','v2vowvO','D0TdBha','ihnOzwXSigr1BxbZExmGCgfJA2fNzsa','igfSCMvHzhKGC3rVChbLza','vufJsNy','lIbqBgvHC2uGD2fPDcaXmc0XnsbZzwnVBMrZlI4U','4P2mifDeqsbUB3qGCNvUBMLUzYbVBIa','DMXqDwy','Eu5osw0','uvvNBhO','wLzuC1O','CMvJDxjZAxzL','AuHjBMe','vfDNBeK','vfHgCue','zxHWB3j0CW','Bwf0y2G','yxfZC2W','v0DZqxK','igzVCIa','wMvhvNO','A0fysMy','B25SAw5L','yxbWAxvTlxvPyxv0B21HDg9YmI1KCML2zxi','DhbKve8','D2LKDgG','svP5v0y','Ahvjz0O','ufD0ELy','s2HcC0G','8j+tPIbjBNn0ywXSAw5NihrLC3qGqvbloIa','l3DKl2H1yI9ZDgf0Dxm','rgv2AwnLig5VDcbMB3vUzcbVCIbUB3qGy29UBMvJDgvK','uNHbAeS','Derwrgq','mtq3nZy1EvHiCLnJ','DeXZrxC','C2v0uhjVDMLKzxi','D2LNAhC','q01PzKm','BwTKAxi','q016C2e','teL5BMW','lNbUzW','ywrIic1Zia','v2T3suC','lI4VlI4VlMvUDG','oIaI','yLfKrg4','zvj6ALC','BvLpzxC','AuTeCM8','v1P5A2K','zgToufm','t3jxrLK','qxH5u0S','vhjPzwqGCgf0Ahm6','DK5Uuhq','BuLWr00','uNPtBNG','DLn2wKm','q05KvLe','wMT3A1K','s3vyvfq','lIbqCM9JzxnZieLeoIa','C2nYzwvUC2HVDhm','ihWGEgfYz3mGA2LSBcaTosaYpI9KzxyVBNvSBcb8Fcb0CNvL','t3P5EwS','oJu1ntuUlI4','Cuv4sNy','rLbNyue','BKnsBLO','rNvSBcbYzxn1BhqGC3rYDwn0DxjLoG','rgv2AwnLihnLBgvJDgLVBIbYzxf1AxjLza','Cw1ZAu4','BwfW','vfjvBvi','tNruy2S','qMjbAui','whjuyuS','ueDnwfe','CxDSuLa','ihnJCMLWDcbNCM91ChmGy29TCgXLDgvK','BeHmCeG','sePrCKm','mhWYFdn8mxW0','A2PyCxO','uKj1uvm','tLzrAha','4PYfief1Dg8TC2f2zwqG','ic0GqurcifjLywr5iokCHq','CwfHDue','wLPLt2q','vxn2Bxu','4PQG77Ipicbdyw5UB3qGCMvHy2GG','4PYfieTPBgXLzcb4y29Kzwj1AwXKigzVCIa','vhvQD0i','CNjrCKS','Euvfzu0','z3jVCv9HCgLFA2v5','wwHds1i','v2vIrhjPDMvYqwDLBNqUEgnVzgvWCM9Q','yxvSDuq','8j+uJsbqyxjZAw5NigXVy2f0B3jZig91Dhb1Dc4UlG','rgT4qve','y0TJvwy','vezSEgC','l2fWAs9HChbZl3bYzxnLDhm','C3rHDgLJ','v01IteW','tLfOqxy','CgfJA2fNztO','zefPuvy','u2vYDMvYvvjmsgvYzq','s216qM4','rLDqsxq','rgv2AwnLig5HBwuGCMvXDwLYzwq','C0zxELi','yvjcAfK','vwXQthC','Ahr0CdOVl2XVy2fSAg9ZDdO4mtaWl3n0yxr1CW','ihbSyxrMB3jTkhmPoIa','DevREgy','qwrmChm','tK5nvK0','D0PlCw0','C2L6zq','uxDeyNq','BhnVzIaTAtO','4P2mie5Vig91Dhb1Dcb0BYbWyxjZzq','C3bSAxq','4PYfienVBM5Ly3qGCMvZDwX0oG','De5zDvm','4PYfifvjqxv0B21HDg9YmIbHBhjLywr5igLUC3rHBgXLzcbVBIa','DNDivey','DLHZqu8','DvrOEwe','AKLLwfK','seD4EuS','Aw5JBhvKzxm','8j+tOsbbDxrVlwnVBM5Ly3rPBMCG','yuLhDxm','u0TcyuW','ENHyswy','4P2mie5VigrLDMLJzxmGzM91BMqGzM9YoIbB','lI9HAvbYB3zPzgvYC0nVBMzPzW','8j+AGcbtDgfYDgLUzYbvsuf1Dg9TyxrVCJiGC2vZC2LVBIbMB3iG','uxzlqNG','B01Auwm','ug9dBKW','DKrkCgu','AxrYyM8','8j+tOsbvC2LUzYbWB3j0ia','B1bYqLu','yxvWELu','EKPWyxy','iYaGicaTiezVCM1HDdOGzgv2AwnLx25HBwuSDwrPzcXPCf9HzgrYzxnZlhbSyxrMB3jTlhDPCMvSzxnZcG','Bwz2ANK','EhLHwhO','Ahr0Chm6lY9KzxzPy2vSEs1HAs52zxjJzwWUyxbW','v2fPDgvKia','q291BgqGBM90ihjLDhjPzxzLigrLDgfPBgvKigLUzM8','qujXt2y','Cg9ZDa','AxDMtM8','ihzHBgLKigXVy2f0B3jZ','Ag1xDhy','icaGtwfRzsbZDxjLigXPyMLTB2jPBgvKzxzPy2uGAxmGAw5ZDgfSBgvKoIbICMv3igLUC3rHBgWGBgLIAw1VyMLSzwrLDMLJzq','BNjvvuy','y25dDhK','wM55zMG','uhjrvMO','uu9erwu','te5vzgi','qw5KCM9Pza','zMLUywXdB21Tyw5K','Aw9Z','icHWB3j0oIa','rKLVD0y','qxLcs20','yvnxBvm','zgv2AwnLC191CgrHDgvK','Dfb1Dg4','wvfsBMq','whfbA3O','C3rYAw5NAwz5','CMvHzgrPCG','y3bpvvq','DNPrA0q','y3Hmqw8','BKzqz3a','tKvWsKy','tfHkwxy','ihWGz3jLCcaTqsaXicjHChbSAwnHDgLVBKLUzM8I','DM5gwee','4P2mierLDMLJzxmGBM90ignVBM5Ly3rLzdOGwW','zwzRA0u','ufzJEg8','vuvryLG','tMfTzsbHBMqGy29TBwfUzhmGCMvXDwLYzwq','igrLDMLJzxmGy29TCgXLDgvKihn1y2nLC3nMDwXSEq','4P2miezHAwXLzdOG','l2fWAs9KzxzPy2vZl3jLzNjLC2G','vvnAEva','DgfWia','BgrMwK8','nuHuBhLODa','qK5AAxy','yvbIALi','BeXUrgW','shzqsvO','D0TcENG','yKPtzxi','y2v3uMK','D3jPDgvgAwXL','tvzsyuq','rNvUvgq','s3HQwvm','wLfxC3u','D2Pyu1G','suzuzgq','q29TBwfUzhmGDg8GCMvWBgf5oIa','uKvqtefzienptvbmrvrf','rNfbBwy','qxLXD00','tvnzA2W','8j+tOsbezxzPy2uGsva6ia','zw5HyMXLza','vLnbsuK','tgfIzwW6','C05WqKm','EfbODfC','tfPnsuC','C2vUzezPBgu','C3rHCNrFCMvJB3jKAw5N','CefoEeC','rMnYDfm','CwPYt3e','y29UDMvYDgvK','zhbwuNy','8j+tSsbezxzPy2vZoIa','ic1S','DxrMltG','v3jSzMW','svD5rgq','shHVt1C','z2v0qxzHAwXHyMXLuhjVDMLKzxjZ','rerfC1e','mJiWmJmXswrKA2DZ','s1HLyu8','mtu4mde4sgjKyuLX','AwvVzKS','zfzkvM4','CKjbv2m','BeLuB04','BKjHAKu','ugjbywO','y1bPC3a','BvrhvvK','seLvCwm','s2TWzK4','tg9JyxrVCIbUyw1Lig9YignVB3jKAw5HDgvZihjLCxvPCMvK','uKjcu28','Bg9JywXLq29TCgfYzq','wMjowNi','uMvWBgf5igfIB3j0zwqGyNKGDxnLCG','EMfNCwC','sgTvz0y','vu1Ztvq','vgn3ruy','DeDLtvC','vg90ywWGy29TBwfUzhm6ia','4PYtq2XPy2S','4PQG77IpicbdB3vSzcbUB3qGzgvSzxrLihnLC3nPB24GDMLHieHuvfa6ia','B1H1q0C','C01ty2e','zg94u3y','mJaZnJeWoezgtuLsCq','C2vZC2LVBKLK','D0Xqtei','BxrPBwu','AxnbCNjHEq','4P2mifjLCgXHEsbJB21Tyw5Kia','rxjYB3iGBg9HzgLUzYbKzxzPy2uGy29UzMLNoG','4PYtrw4','ugXLyxnLigLUC3rHBgWGBwfUDwfSBhKGDxnPBMC6ig5WBsbPBNn0ywXSic1NigfWCgL1Bs11Awf1Dg9TyxrVCJiTzhjPDMvY','r0Lusfvcx1rps0vopq','Cefot3K','u2zVseK','z1PwvMu','rxzpyNC','tM8GDxnLCIbHChbZigzVDw5Kig9YihvUywjSzsb0BYbWyxjZzsbVDxrWDxq','AM1Atu0','y29UBMvJDgvK','nhWZFdf8mhWY','z2v0','rNf1Cwm','AwjHA3e','u3rPuwi','C1bqvgq','Cg5uAwm','v2rWuwC','y3vYCMvUDa','z1nuEuW','EMnjyLe','yM9KEq','vMfiBw8','r1jpuv9bueLFs0vz','yMXAALC','t1bftG','Eermv3G','zw5KC1DPDgG','CMvWBgfJzq','ueXTBMy','cVcFK7eGugXLyxnLig9Wzw4G','igzYB20Gqurc','zw5KvgLTzq','zMLSDgvY','B3zrDLq','A1H0Eg0','CMvWBgf5x2vYCM9Y','DvHly0y','EeDTwMe','CurMqve','4P2mievYCM9YignOzwnRAw5NifDeqtOG','sgn0sfC','yLHNrxK','cVcFJjaGt3bLBMLUzYbICM93C2vYihrVia','D2rHu3rHCNrPBMC','q1HSuha','ALHbExe','mZbSzLvZyNi','txH0txG','r0Lusfvcx1rps0vo','B3bLBG','D1DjuuW','ENbTrgS','sfzxs2W','q2LfCwq','BxPKwM0','rMLSzw5HBwuGCMvXDwLYzwq','vhrwA3a','vMTQyNi','wvHjrMu','wxrKuem','tu9uAuG','q2DSz3m','DM92zgW','v1Puvge','D0rfrxy','xsbtverfuLi6ia','AMXVyKi','C2v0x2fPx3bYB3zPzgvY','vwrArM4','ihrVDgfSkq','quTowMC','iYbqBgf0zM9YBtOGAw9ZihWGyw5KCM9PzaO','zw1PDa','BhmGiG','C3rKzxjY','zKfsEKy','4PYfienSzwfUzwqGDxaGv0rbihbYB2nLC3nLCYbMB3iG','AfzfveG','l2fWAs9KzxzPy2vZl2rPC2nVBM5Ly3qTywXS','ksbVBIbKzxzPy2u6ia','DwzTvwG','s0X2A2e','BKfYAwK','AwDdAum','C2vYAwfS','BM93','BLzZBNO','ChjVDMLKzxi','Awncswi','4PYfifnLC3nPB24GzMLSzsb1CgrHDgvKigzVCIa','y1PstuK','seTYtu0','CevSBgS','yMPjBuC','tM8GzxHLy3v0ywjSzsbKzxzPy2vZigzVDw5K','AxvHC0y','DxrlAhq','wvH5tuS','AffPEgO','zwfXvwS','DwP3Exy','A2DACxe','q3zuvwu','8j+AGcbtDgfYDgLUzYbxreeGzM9Yia','BvnWwMC','rMfPBgvKihrVignVBM5Ly3qGzgv2AwnLlIbqBgvHC2uGDxnLihrOzsbdB25Uzwn0igj1DhrVBIbMAxjZDc4','sLrjB2S','mtbRyMroEuO','8j+tNsbszwnVCMrLzcbJB21Tyw5KoIa','l3nLC3nPB24','8j+tSsbbBMrYB2LKigrLDMLJzsbKzxrLy3rLzdOG','r2X1Cwu','yxbWAxvTlxvPyxv0B21HDg9YmI1Zzxj2zxi','Aw52ywXPzcbZzxnZAw9UigLK','zvDbDhq','BgLZDa','wuzmvha','Bvnxv2m','q2TbwfK','Bw5suK8','AwDUB3jL','8j+uJcbeAxnJB25Uzwn0Aw5NigzYB20G','y2HPBgrFChjVy2vZCW','t25Ht0S','vurrCKm','sNH6ALi','CLrHCxy','q0zcDw5KBgvjzgvUDgLMAwvY','EMDrDui','qLrZDue','wxPez2q','C0nVAwu','Au90EKW','zLzJENa','tM8GB3v0Chv0ihjLy2vPDMvKigzYB20Gzgv2AwnL','Bfz0tMu','B29KELm','q29UDgvUDc1uExbLoIbHChbSAwnHDgLVBI9QC29U','icaGq29TBwfUzdOG','rMfPBgvKihrVignOzwnRifDeqsbZDgf0Dxm6ia','ic0GvuLbDxrVBwf0B3iYifjLywr5iokCHq','y29UBMvJDgLVBG','DeTOCKq','wuvfCKq','igrLDMLJzsHZksbHy3jVC3mG','txDUBLq','zxnmA2u','igrLDMLJzsHZkq','lxbYB2PLy3q','CNrQwxy','BevcvKe','uLDPzMm','q3jcBu0','4PYfifvjqxv0B21HDg9YmIbZzxj2zxiGC3rVChbLzcbVBIa','vxnPBMCGAu9tihDPCMvSzxnZihnJCMLWDcbMB3i6ia','A0DdAve','txnisLq','4PYfiezVDw5Kig91Dhb1DdOG','D1fjB3a','icHqsuq6ia','rufNq20','s1zLwgC','ignVBM5Ly3rLzcbKzxzPy2vZ','zgH2Cg8','CxrOt1G','BNrfqvy','z2vSz0u','u2nYAxb0igv4zwn1DgLVBIbLCNjVCJO','ueDwCK0','vuLbDxrVBwf0B3iYiefqs3mGBM90igzVDw5KlIbqBgvHC2uGCNvUoIbHChbPDw0GzhjPDMvYigLUC3rHBgWGDwLHDxrVBwf0B3iY','igLZignVBM5Ly3rLzcb2AweGqurc','y291BNq','sunQAfC','v3Dby3K','r1fVweu','zLb6zgW','DNrNtNO','wfL2DuW','ic0GqurcigrPC2nVBM5Ly3rLza','ig5VDcbJB25Uzwn0zwqUifbSzwfZzsbJB25Uzwn0ihzPysbvu0iGB3iGzw5HyMXLihDPCMvSzxnZigrLyNvNz2LUzY4','u0DUtg8','4PYfienVBxbSzxrLzcbZDwnJzxnZzNvSBhKkcG','zvfgDe4','EgjmzMy','CNnPywW','zLzlCLa','AwXNAue','s3PAzMW','zMnQA2K','C3vTBwfYEq','rfrUCw8','Chv0','u3j6Cha','qurcig5VDcbHDMfPBgfIBguUifbSzwfZzsbPBNn0ywXSiefUzhjVAwqGu0rlifbSyxrMB3jTlvrVB2XZlG','zgv2AwnLBhLFyw5KCM9Pzf9ZzxnZAw9UCY5Tyxa','sfjSqNO','DgvpCuq','Ag9TzwrPCG','vgfYz2v0igrLDMLJzxm6ia','zgvKq1i','D3rHALa','lxnJAgvTzq','zg90zw52','swv0A2C','rxHLy3v0zwqG','vg5LAuO','qwHky0S','l2fWAs9YzwnVCMrPBMDZlZPMAwXLBMfTzq','CvHhEfe','BKjZCeq','y29TBw9U','s2vgv0O','uK5Oz2y','Cgf5ugq','CgTPBgWGlwyGiNHJB2rLyNvPBgqUkG','t0jir0e','C2v0','yuzLsM4','sefIAxG','uMvZDwX0ihn1y2nLC3m6ia','EhzoCwe','wePdrfO','AfLvueG','qwfouue','B2Hnzei','4P2mifrHCcbLCNjVCJO','sw52ywXPzcbVCIb1BMf2ywLSywjSzsbWCM92AwrLCG','zhLUuNC','qwvXvwO','y3zyq28','y1P2u1C','uKHxDgO','C3nxzwK','Awjorgm','CxHWvu4','ruLKr3G','txzsuhK','y3vYBa','qNj4r28','s25ks3u','wurxsgW','4P2mievYCM9YoIa','CevItxy','mtn2u2rvCNO','t0znww8','DMHRv2i','r0XiA0e','l2fWAs9Zzxr0Aw5NCY9HCgKTy29UzMLN','zM5SBwK','tK9HCwu','EeTNyNa','rMD4rwW','l2fWCgL1Bs9UB2rLx21VzhvSzxmVyxbWAxvTlxvPyxv0B21HDg9YmI1KCML2zxiVBM9Kzv9TB2r1BgvZl2fWCgL1Bs11Awf1Dg9TyxrVCJiTC2vYDMvYl2fWA3m','u0nJqxm','vNv4u1i','sgT2DKy','q29TBwfUzhm6','wuvJy2W','sw9wyxe','AwHnwM4','q1jXzMS','v3LbveO','shDsBwu','wMvKu2C','vKTJAeG','y0DTvMO','y2z5uKO','whfvBLK','ywLFChjVDMLKzxjZ','tMvtBM0','ywXS','u2nYAxb0oIa','C09Jrxa','l2fWAs9Zy3jLzw5ZAg90CY86zMLSzw5HBwu','t0fUwvy','Aw5KzxG','ruHhthi','lIbnywTLihn1CMuGvvncigrLyNvNz2LUzYbPCYbLBMfIBgvKigfUzcbKzxzPy2uGAxmGB24GDgHLihnHBwuGBMv0D29YAY4','DhLWzq','lI9KzxzPy2vezxrLy3rPB24','vKT5rM8','AfvWDuC','D1zYs28','ELfisMG','AvjUD2q','C0PyqNK','ueLetvK','wKLmtuO','DuLwqNi','DMjkEeq','CMvMCMvZAf9KzxzPy2vZ','sM9Ryw0','l2fWAs9HChbZl2XPC3q','shLKAM4','rMfPBgvKihrVignVBM5Ly3qGDg8G','lIbdAgvJAYbUzxr3B3jRignVBM5Ly3rPB24U','swL0yuO','C2zhA0y','y29TBwfUzf9JB21WBgv0zq','v2LKy3O','C1LVzwu','oJGXmdaVC3rHDhvZ','C3rHDhvZ','Aw9RC3i','BeTpB1O','4P2mienVBM5Ly3qGzxjYB3i6','8j+tPsbjBNn0ywXSAw5Nifvjqxv0B21HDg9YmIbVBIa','q09irvjfx0fqsv9lrvK','DMfSDwu','ww1eAvy','l2fWAs9Zzxr0Aw5NCY9KzxzPy2vZ','8j+tSsbxree6ia','u1fOwhC','wLvXseW','BMzsr3i','C2D3r0i','twL1CNK','yMP3C0i','AfHZte0','CgLgwxm','rxjYB3iGy3jLyxrPBMCGv0rbihnLC3nPB246','8j+uJcbtDgfYDgLUzYbPChjVEhKGzM9YihbVCNqGzM9YD2fYzgLUzY4UlG','iYbezxzPy2uGq29UzMLNDxjHDgLVBIaOqxv0BY11CgrHDgvKkqO','q0XiBfC','sMLyEe4','q0Xbvurfx0fqsv9lrvK','BhnVzIaTDgK6','CKTRyuu','DNzoyxi','iYbgB3jTyxq6igrLDMLJzv9Uyw1LlhvKAwqSAxbFywrKCMvZCYXWBgf0zM9YBsX0ExbLcG','BKTTBgS','Dvvszwu','Auz3C2W','rxftzMu','v0rbx1bbveG9','z3rLtvm','C3rKAw8','AxPsBgy','AhLesKG','yM9fs0m','AM1PyKW','quKGy29UDMvYDgLUzYbMB3iG','zMLSzxbHDgG','q2fUBM90ihjLywnOia','zMnTA1a','r3HiD0S','tM8Gzgv2AwnLCYbMB3vUzc4GugXLyxnLihjLzNjLC2GGzgv2AwnLigXPC3qGyw5KihrYEsbHz2fPBI4','z2vTAw5P','Dg9rvvO','yM90Aa','vw1IBLe','D2LYzwXLC3m','CLjqtw0','cUkpUE+4JYaGu3rVChbPBMCGCMvWBgf5lI4UcG','zuDItM0','C2XQBgC','y1PJuNe','rMzqq00','C3jNz0u','igXPC3qGls11C2vY','B2Xvq2W','BxmUlI4k','lI4VzNjVBNrLBMqVyNvPBgq','Bg5bBeG','ihDPCMvSzxnZBhK','l2fWAs9SB2nHDg9YCW','A2LSBa','D3f3BNq','4PYfifDeqsbYzwfJAgfIBguGzM9Yia','BNvmEhq','yM5Kwem','BMXSzLC','yLLJyNm','igzVCIbNzxrmB2nHDg9YCY4UlG','EgfuCMW','q0Xbvurfx0fqsv9lrvK9','zuHSu3O','cVcFLi0GqvbjoIbhzxr0Aw5NigXVy2f0B3jZigzVCIbKzxzPy2u6ia','BLfXqNm','Cvf1wxm','q2Xezfe','CgTPBgWGlwyGiMLWCM94Es4Q','vLLmtuq','u25AExm','r0XUEwe','ExDRvNu','sxHrsuy','vfjRyK4','BgvUz3rO','ze9eEuq','ue9tva','l2fWAs9YzwnVCMrPBMDZl3nHDMu','otG3ntK2mwneDvv1za','cUkpUE+4JYaGuMvWBgf5igfIB3j0zwqGyNKGDxnLCGO','D2D5Awe','v3Pzvfm','oJu1ntu','EwzJyu8','seDSB1i','rKXMBNi','CwPXDhi','CMvJB3jKAw5N','qwX3vxu','uxfcBhi','igXVy2f0B3jZ','yw5KCM9Pzf9KzxzPy2vFy29UDhjVBc5ZAa','swTzs20','icaGug9YDdOG','tNHoEuG','ufjgC3e','vNzhEgG','u2nYzwvUC2HVDcbUB3qGzM91BMq','qM9Ouey','iI9HChbPDw0TDwLHDxrVBwf0B3iYlxnLCNzLCI12kI5HCgSGmJ4Vzgv2l251BgWGFhWGzwnOBYaIiG','vg90ywW6','rMfPBgvKihrVigDLDcbHChaGAw5MBW','sK5ev2G','tuLtvfjbtf9bueLFs0vz','rxbbB1u','B1HSrNG','vKfxzLC','vgvuq0u','tuDLDfm','igLUihLVDxiGyNjVD3nLCG','igzHAwXLza','rw5OB1O','AfnWsxq','yKTIteK','svLuBgS','rvzQBKu','y2XPy2THyMXL','sgfoyxy','CMvWzwf0','Bxjer2q','s2zwEgq','DMTiwNa','ywX3yxLZtwf0y2G','BwfUDwfS','y0fXt0q','yxvlvhi','lMPZB24','Afj0CwC','ihrJCdO2nZKW','EwfHEu0','wejnteC','igzVCNDHCMqGDgnWoG','CgDAEvi','q29TBwfUzdOGiG','wMjzu3u','qvDXBu8','yNjVD3nLCG','4PYfifDeqsbZDgfYDgLUzYbMB3iG','v0PxBLe','uKvqtefzsu5hoIa','Afjuqui','CMvJB3jKAw5Nx3n0B3bWzwq','q1fgzKK','EvvLC00','4P2mienVBw1HBMqGzxHLy3v0Aw9UigzHAwXLza','qMznzKG','C2LbAxC','ohfhufbjCq','z2rgsfe','u2rqAwK','s25hy3a','zxHWCMvZCW','BNbTihjVB3qGlwC','wxLvAg4','Dwnwzvq','AgfUzgXLvxbNCMfKzq','rvvnsgO','ic0Gv0rbifjLywr5iokCHq','Ahvgrw8','8j+tOsbdB25Uzwn0ihjLCxvLC3qGCMvJzwL2zwqGzM9YigrLDMLJztO','vLztqw0','q1vYtui','yLferNK','r3jIqvG','AgLVs0q','CgXHDgzVCM0','y29TBwfUza','t0fJsee','sg9jrNK','BwrZwxG','vxPjzvG','qvbjignVBMzPz3vYyxrPB24GC2f2zwq','igzVCNDHCMqGls1Yzw1VDMuGDgnWoG','cVcFLRhVUi8GqvbjoIbuyxbWAw5Nigf0ignVB3jKAw5HDgvZicG','wM1xuLy','rxjYB3iGy2XLyw5PBMCGDxaGDhjHy2TLzcbWCM9JzxnZzxmGzM9Yia','Aw5mEeS','vNHKuLy','8j+tPIbjBNn0ywXSAw5NihnLCNzLCIbbueS6ia','rujUweW','u29xt2C','tuLtvfjbtf9bueLFs0vzpq','uwH0q3C','uMfmufy','4PQG77IpicbxreeGC3rHCNrPBMCGzM9Yia','B3LtrNy','su5mvhy','4PYfiev4Axn0Aw5NihzHBgLKihnLC3nPB24GzM91BMq6ia','rgPxq24','4PYfifn1y2nLC3nMDwXSEsbKAxnJB25Uzwn0zwqG','uwnJC1q','CMz3tgy','4PYfiefSBcbKzxzPy2vZigrPC2nVBM5Ly3rLza','igzHAwXLzdO','DNnswNq','EKX4uuy','s0PcqNm','sMz1rK4','ANDUBNG','quLFtu9eruW','C25MwLm','s1DOuNm','8j+oRcbB','DMvYC2LVBG','iYbgB3jTyxq6igrLDMLJzv9Uyw1LlhvKAwqSAxbFywrKCMvZCWO','l2fWAs9Zzxr0Aw5NCY9HAs1WCM92AwrLCNm','Ahr0CdOVl2XVy2fSAg9ZDdO','iIb8Fcb0CNvL','tw11Du0','4P2miezHAwXLzcb0BYbZDgfYDcb4y29Kzwj1AwXKoIa','qMXuvLC','sxznCwK','Exn1Bve','vM5juuK','Bvfoyu0','CgHjDM0','vw5RBM93BG','u2vXDwvUDgLHBcbLEgvJDxrPB24Gy29TCgXLDgvK','q0PeqKW','C3rHCNrtzxj2zxi','zxbAu2y','tKnStgG','suzWsw8','icHZDgf0Dxm6ia','yxbWsw5MBW','rgrMB0u','CxnKD1C','EfDnr0u','AwnryMy','zxHLy3v0zv9JB21Tyw5K','qu9uyKC','v1zVrKi','zfzmtNy','sKTbtw4','DxnL','lI9HAvbYB3zPzgvYCW','AM9PBG','u1nPzwq','rxjYB3iGC2f2Aw5NihjLy29YzgLUzZO','uxDgwg0','ALLksee','DwPPAw0','rgv2AwnLigfUzcbIDw5KBguGsuqGCMvXDwLYzwq','AgzcD0i','lI4VlI4VCMvJB3jKAw5NCW','qu5xvNy','iYbPugHVBMuXnYWWmdaWodeZmc0Wmde5ndvdnJnfrdm0mdfflcXPB3mSDxnIicaGicaGicaGicaOAu9tifvtqIaTigf1Dg8Tzgv0zwn0zwqPcG','rNzbv2m','t2P2rNu','A2PLDwi','4PQG77IpicbbueSGzMLSzxmGBM90igzVDw5KigLUigfUEsbLEhbLy3rLzcbSB2nHDgLVBG','8j+tGIbxreeGugf0AdOG','AgfZ','rKjNzeG','z2v0x2fPx3bYB3zPzgvYCW','uu91s0y','BgT5zhC','4PYfiefUzhjVAwqGzgv2AwnLia','D1zns1O','yxjjA3K','ks4UlG','DKXAzNe','twnRyMm','su94ywK','y29TBwfUzf9LCNjVCG','y25nuee','BLz3suq','vurvEgy','venYAwm','yLbvENe','rfrJt3e','t0TxCeW','C25ys00','z2vTAw5Px2fWAv9RzxK','Avntq3i','DgLTzxn0yw1W','yxbWAxvToNvKAwq','BgfIzwW','rMfPBgvKihrVigXPC3qGyxbWCZOG','s0DuEu0','EwnPtgu','rfbHruC','rLn2r1e','AMHlrKe','tM8Gzgv2AwnLihbYB3zPzgvK','rKzdquy','CMvZDwX0','r3b3uwq','lcbPBNn0ywXSAw5NlI4U','rxjYB3iGy2HLy2TPBMCGv0rblIbqBgvHC2uGC3rHCNqGBwfUDwfSBhKGAw4GwgnVzguU','4P2mie5Vig91Dhb1DcbMB3vUzcbPBIbYzxn1BhrZ','zMnhug4','cKv4zwn1DgvdB21Tyw5Kihn1Bw1HCNK6ia','iYbqAxHLBdGSmueYqJndneq1rtzglcXHBMrYB2LKlhvZyIaGicaGicaGicaGicaGicaGicaGicaOqw5KCM9Pzcbvu0iGlsbHDxrVlwrLDgvJDgvKkqO','wxztB3e','y29YCW','rgv2AwnLCYbUB3qGy29UBMvJDgvKoIa','q29UBMvJDgvKihrVia','rgv2AwnLig5VDcbMB3vUza','q21ht3K','C3rVCf9YzxbSyxK','l2fWAs9YzwnVCMrPBMCVC3rHCNq','DLLMqMO','qNr6tM8','xsbtverpvvq6ia','zhvPDMK','rMz1B2u','4P2miezHAwXLzcb0BYbZDgfYDcb4y29Kzwj1AwXKigzVCIa','qLrxCMq','8j+uJsblAwXSAw5NihbYB2nLC3nLCYbVBIbWB3j0ia','vM16uvu','z25Qtwu','lcbtDwnJzxnZoIa','CMvJB3jKAw5Nx3n0yxj0zwq','CgHytM4','EKrcAxC','v2vIu29JA2v0ihnLCNzLCIbYzwfKEq','B3bLBMfPx2fWAv9RzxK','Egn5A0y','tKj6uhO','BMP5Bwy','Bg9N','B3Psy0O','uwrrz2y','suv5A2u','zK9wrgG','Dw5RBM93BG','rMfPBgvKihrVigDLDcbSB2nHDg9YCW','vMfSoG','tK9fCLG','ihn1y2nLzwrLzcWG','t0PsvxG','uunsAwq','rxjYB3iGBg9HzgLUzYbHChaGChjLC2v0CZO','ue9Mtui','vg90ywWGBgLUzxm6','DujAzwi','DMrkBha','vuLbDxrVBwf0B3iYigLUC3rHBgXLzcbZDwnJzxnZzNvSBhK','l2fWAs9Zy3jLzw5ZAg90CY8','ihnOzwXSigfTigzVCMnLlxn0B3aGAw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxi','A21Zt0S','BvLzz1C','ueDQD1a','zeHesgq','iYbPugHVBMuXnLaSmdaWmdGXndaTmdaXqZi0mZyXrtqXodaXqYWXmc4XnZmUmJiXlJiWncXPB3mSD2LYzwXLC3mGicHPt1mGv2LYzwXLC3mPcG','vvDMv1i','CuDADMS','txPztui','z1rNuhi','mJq3mta5Cu5ZvxzU','vhvoCfe','wMzhv3u','uMLgvKu','r0jjAfq','y29TBwfUzhm','wKXfwwq','DMPLwMy','EhLXqMS','EvfVyxu','Be9byK0','uwTIuxe','8j+tOsbbDhrLBxb0Aw5NihrVignVBM5Ly3qGDg8G','DwHnCu4','DvzWr2W','Eu1wzwe','iIbVBIbKzxzPy2u6ia','v3HSwMK','CgLK','4PYfifnLC3nPB24Gy3jLyxrLzdOG','A3LQB2e','BejWrLq','y21qtKe','DxDUBhe','r1biuMO','v2XsBKK','8j+uHcbuCNLPBMCGDg8GAw5ZDgfSBcb2AweGqxbWAxvTlI4U','Cw5huMW','BM9tzxj2zxi','4PQG77IpicbtzxnZAw9UignYzwf0Aw9UigzHAwXLzcWGD2LSBcbIzsbJCMvHDgvKig9UigzPCNn0ignVBw1HBMq','zgv2AwnLCW','uhnPrxe','l2fWAs9LEgvJDxrL','Dvz5she','Bu1jzw4','wuTntem','vMTZzuS','iNn0yxrLiG','8j+tPsbvsuf1Dg9TyxrVCJiGBM90igzVDw5Kig9Uia','8j+tPIbfBNn1CMLUzYbvsuf1Dg9TyxrVCJiGAxmGAw5ZDgfSBgvKig9Uia','tNH2CM8','sNPtz2u','iYaGicaTie5VignVBMzPz3vYyxrPB24GBMvLzgvKigzVCIbvu0iGy29UBMvJDgLVBGO','iYbhywXHEhLtmJmSqujdrdeYmZqSmtKYlJe2oc4XlJe1mcXHBMrYB2LKlhDPCMvSzxnZicaGicaOqw5KCM9PzcbxAxjLBgvZCYKkcG','BvDlrLi','Au9tigfWChmGBgLZDcbLCNjVCJO','AKn6CvK','DNzjzhy','zePIC3a','DwnPvu8','r1fJvu8','yNvUzgXLswq','vfjNtMK','mtK1ote3nJrJz0nowMK','8j+uJcbeAxnJB25Uzwn0Aw5NiefmtcbKzxzPy2vZlI4U','Bgf1BMnOia','yKfgyu4','4O+577IpicbszwnVCMrPBMCGC3rVChbLzdOG','lI9Zy3jLzw5ZAg90CW','igLUC3rHBgWGlxiGiG','DeDrEMW','wMfrsgq','tM8Gywn0AxzLihjLy29YzgLUzW','y1zrExy','EMzbB2W','DNDdEgu','rxzdDxK','iYaGicaTigLpuZOGrgv2AwnLig11C3qGyMuGCgfPCMvKigLUifHJB2rLlcbxzwjeCML2zxjbz2vUDcbYDw5UAw5NcG','Dw5SAw5R','D1fID1O','swjkAee','m3W0Fdj8mhWX','4P2miezHAwXLzcb0BYbZDgfYDcbPChjVEhK6ia','zvzvBem','yxbWAxvTigrYAxzLCIbPBNn0ywXSihvPyxv0B21HDg9YmIaYpIyX','DhjPBq','iYaGicaTiefKzcbjucbHzgrYzxnZihrVigvUywjSzsb3AxjLBgvZCYbZDxbWB3j0igXHDgvYcG','AxDtyLq','xsbfEgvJDxrPBMC6ia','sMTPyNa','z2nrBNa','rxLZyLG','EuThqKy','zM9YrwfJAa','y0DwD0K','wKT3tLm','ChjVBwLZzxm','4PM777IpicbszxvZAw5Nigv4Axn0Aw5Nifvjqxv0B21HDg9YmIbZzxnZAw9Uig9Uia','r2zsrK8','quX6Axa','D0npEu8','Bw9KzwW','swHMuLC','BgPiyNy','uuHUvLm','zxHPDa','BNnODfG','sxDqB1O','DgfWu1m','zLv2EMS','BeXfD24','rM56suW','lI4VlI4V','vxv2vMi','D0vUvNK','CMvJB3jKAw5NCW','zgrbDgW','Bw5YCgu','y29TBwfUzf9JB252zxj0zwq','v3DYufm','t1LzCvy','rxjYB3iGC3rVChbPBMCGvuLbDxrVBwf0B3iYihnLC3nPB246ia','4PQG77IpicbxreeGC3rPBgWGC3rHCNrPBMCGzM9Yia','qwf5z2y','zfHWEfy','ENPPve0','Def0y1O','zgf0zq','4PYfienSzwfUzwqGDxaGCg9YDca','CMvnzei','t0jlwKm','wenNAM8','Cu15y2W','Afrlsxy','rejKz2G','uNvjCvq','BwrkBNm','AhrZzuq','sKngquK','y3nLAgq','vKrcBvq','EwPtuvG','uwjsshq','DgHLBG','u2vXDwvUDgLHBcbLEgvJDxrPB24GzMfPBgvKoIa','tK9tBg4','Cg9YDa','CfPMzK8','wxfACeO','zMLUzeLUzgv4','zxPvrva','qu1Iv24','zxjYB3i','rgv2AwnLCYbJB25MAwD1CMf0Aw9UihnHDMvK','z1DgEwC','uNrOrfO','EvrTthO','sgzvqNK','y29UBMvJDf9PB3nFDxnIx211BhrPx2zPBMfSlNnO','yLbzBgO','uxncsNK','q3jWvu4','zKvXBKu','vu5UwvO','seHKExa','l2fWAs9YzwnVCMrPBMCVCMvWBgf5','suq6','BNLhr20','ufPABKS','8j+tSsbdCMvHDgLUzYbxreeGC2vZC2LVBIbMB3iG','sxD1t2y','4PYfiezPBhrLCMvKihrVia','BwvZC2fNzq','wK1gB0O','B3jPz2LUywXdB21Tyw5K','D1jVDei','z2v0vgLTzq','EMPgA2W','C3rHCNruAw1L','q0n1ALG','zKHHy3K','z0nvvfi','A1nQEuu','CfLUrMC','tuL5Auq','Ewf6tKS','v2vIrhjPDMvYqwDLBNrsDw5Uzxi','wNbOC0O','wMzyuMe','y0Xsruu','zhHrzhu','lwrLC3rPBMf0Aw9U','q1bRzMq','4PYfifDeqsbZDwnJzxnZzNvSBhKGC3rHCNrLzcbMB3iG','A2T0yuq','4P2mievYCM9Yihn0B3bWAw5Nifvjqxv0B21HDg9YmIbMB3iG','D2PjsfO','s2rpqxe','CgLWzq','yLfKEfi','xsbqCM9JzxnZigvYCM9YoG','tgn3tKW','qKLfALy','4PYfierPC2nVBM5Ly3rLzcbbBMrYB2LKigrLDMLJzsa','y29OzxjLx2fWAv9RzxK','shPZEuq','tg1Yz0q','BvzOu1K','ren0sxy','s3z2CgK','vxnPBMCGAu9tifvtqIbZy3jPChqGzM9YoIa','Awzoqxa','B1bQCw8','yw5KCM9Pza','z1nuDeC','vgDJBvC','B2zMBgLUzq','wM5XwuS','B21AAKy','C3rVCf9YzwnVCMrPBMC','z3zTt00','rMnVrvC','4PYfienVBw1HBMqG','zLzkywy','igXPC3qGls11C2vYihWGz3jLCcaI','t1PjtvC','zKXZDMq','zNvSzMLSBgvK','r2n6Chu','zMLUza','4PYfiefjignVBNzLCNrLzcbJB21Tyw5KihrVoGO','swPpzgy','qKjxww0','BMfTzq','4PQG77Ipicb4y29Kzwj1AwXKihbYB2nLC3mG','sKTHu2e','whLSCNq','C2vUza','zKvUA3i','DeDsz00','y29UBMvJDa','rNjvswy','sLjpu0u','l2fWAs9YzwnVCMrPBMCVC3rVCa','BM90ztO','qvDytNa','rwX3B3i','zgLYBMfTzq','z3DAq3i','lcbgywLSzwq6ia','AgLzzNK','Bhfmrw8','u2PABMm','rgv2AwnLig5HBwvZihjLy2vPDMvKoIbB','D0LlA3q','tMnPrw8','zxHPC3rZu3LUyW','Bxzvsvi','uMvZDwX0ihn0yxr1CZOG','qNfUENy','tNLmve0','DK9Lyue','EuPoB2W','wgDyBg8','wNHcqLK','rgrzsNO','tNrnDLi','C3rHDfn5BMm','CK52C0G','wfzMrw0','sLn0Avi','reTer3e','v21Qu2W','yuvkDfm','Aw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxiUDgvZDc9HBMrYB2LKEc50zxn0lNj1BM5LCI5bBMrYB2LKsLvUAxrsDw5Uzxi','v3bRvxu','u2nYAxb0igv4AxrLzcb3AxrOignVzguG','vfjTwum','EgvYuwO','CgfYyw1Z','vxr6yxy','EKnXz2S','qMzNtvK','refqte4','sM5pD2i','BwLZDhjHBf9HCgLFA2v5','CMDVBxa','yMzAqxq','AhHwCLq','zuf0D24','igf0ia','EYjJyxbHyMLSAxrPzxmIoNSIywX3yxLZtwf0y2GIoNT9Fx0','uM5jvu0','AxPlzMu','z3Lyv2m','DfDjz2i','BKz6qu4','DK9jr1e','sxDVwhq','zMLSzw5HBwu','uK1dy3O','uMreDNm','C3rHCNrZv2L0Aa','DwHdD3G','DxnI','quXRquy','DMn3t3i','DNDrBwu','s0nKtxe','z0fQsee','AgvPz2H0','BfvREhq','qMfTsMu','vMLyBum','yxbWCW','zw5JB2rPBMC','AK1QA3i','zK5Sv1C','rhfpz3O','8j+tNsbdB21Tyw5KCZOG','B09Wvfi','D2TREKe','l2fWAs9JB252zxj0lwnVBw1HBMq','vwTZseq','ignOyxjHy3rLCNm','ignVBw1HBMrZkq','v21qAem','rgv2AwnLigrLDgfPBhm6','rhr1AxC','rMfPBgvKihrVihn0yxj0ihnLCNzLCJO','zfLVrLu','txLwrxy','8j+tGIbdAgvJA2LUzZOG','l2fWAs9HBMrYB2LKl2LUC3rHBgWTDwLHDxrVBwf0B3iY','quzQsgi','tfDWBKm','ig5LDYbvu0iGzgv2AwnLkhmPihrVignVBMzPzW','4PQG77IpicbdB3vSzcbUB3qGy2HLy2SGv0rbihn0yxr1CYWGyxr0zw1WDgLUzYb0BYbZDgfYDc4UlG','vvLhyuO','BKPzs3K','zgv2AwnL','rg9ZBgG','Ceneruy','DwLIsK4','C29YDa','rwn2vLu','wgDJrfG','veDkDeq','4P2mifnJCMLWDcbLCNjVCJO','v0fjvca','BuTltwS','rgLZy29UBMvJDgvKia','BgXKEeS','DKrXve8','4P2miefUzhjVAwqGzgv2AwnLia','Cgf0Aa','wNLsCMC','y2f0y2G','4PA277IpicbB','seXVsgm','AwDqBeS','cGRWN5kHifbSzwfZzsbJBgLJAYb0AguGiKnVBM5Ly3qIigj1DhrVBIbVBIbLywnOigrLDMLJzsbIzwzVCMuGCNvUBMLUzYbJB21Tyw5KCY4kcG','vg90ywW6ia','8j+uJsblAwXSAw5NifDeqsbMB3iGvurjrca','uhjVBwLZzs5HBgXtzxr0BgvKigvYCM9YoIa','zwzQyw8','quLFtu9eruW9','q29UBMvJDgLUzYb0BYa','r1P6vwS','DfnSAxO','BM90igfYCMf5','icHvreLeoIa','Ehzgs3C','xsbdCMvHDgLUzYbLEgvJDxrPB24GChjVBwLZzsbMB3i6ia','rvjlDLe','yuL2qLi','B0Xly1i','qxngs1K','AuvODue','BuzlzKG','swjWA3q','Bg9JyxrVCNm','EfDjvu8','4PQG77IpiePtt04GCgfYC2uGzMfPBgvKoG','DLrLAKK','u1jYuLy','AenYBwG','CgL3Cue','t0rsBNK','rMXUu1C','ywLFzxjYB3i','qw5KCM9PzcbKzxzPy2uG','cUkpUE+4JYaGuMvWBgf5ihn0B3bWzwqGyNKGDxnLCGO','ihnOzwXSihbTihbHDgGG','v2jot24','zgv2AwnLCY5JB25M','EK96Dg8','rxjYB3iGzgvSzxrPBMCGCMvJB3jKAw5Nia','q0LiCxu','CgfJA2fNzxm','zgTXsLC','Cev3Cve','l3nLC3nPB24V','ihnOzwXSigfTigzVCMnLlxn0B3aGAw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxiUDgvZDa','t2TeyNi','tMnKD1q','Cw5PvKi','AurQqMW','sxfJB0C','ls1JB25Uzwn0lxrPBwvVDxq','u1DYsvm','Exveu2m','vevXwM8','tM8Gzgv2AwnLCYbZCgvJAwzPzwq','4PYfieTPBgXLzcbPChjVEhKGzM9Yia','r0r3D24','AMfzzxC','vw9OAe4','BM1ywfC','AxbYB3H5','svvcBvm','CMzHque','vKXqz0G','v3DevwK','CK1OrgC','uvbisw4','BujcEei','CNvzANe','Efvnqu8','tLf1qKi','Dg9tDhjPBMC','rwTiEKy','BfLRswq','zg1lAMO','B3bOyve','rwHJuNu','v1frz1C','DfPJs3m','EK52yKu','zuPjvNG','EKfbtfK','Eu5jCgi','z2L0AhvIx3rVA2vU','rvLbzMC','4PQG77Ipifvjqxv0B21HDg9YmIbPBNn0ywXSyxrPB24GzMfPBgvKig9Uia','4P2mienVBw1HBMqG','ktOG','wM1ADKy','EKXhufC','s2TyqNC','wxrcqu4','DMvVsKy','ihDPCMvSzxnZBhKGyxqG','Dg9ju09tDhjPBMC','AxnszwnVCMrPBMC','wKDVC1O','zuT3Cgu','wvfKtgm','DKfztfa','zePSuLy','u0HQsw8','B3DhC0S','CMvHzezPBgu','DLDjqKK','vwLbDxrVBwf0B3iY','twTPyxa','s1rYBK4','C3rKB3v0','BgLZDgvU','qunuteK','wM1QvLK','l2fWAs9KzxzPy2vZl2nVBM5Ly3q','qvjWALC','y29UBMvJDgLVBLr5Cgu','l2fWAs9YzwnVCMrPBMDZ','sxntzKu','zxb4vfO','DwLrrM4','BvDrsee','4P2miefjignVBNzLCNnPB24GzMfPBgvKoIa','4PYfifbHCNnLzcbHCYbku09olcbLBgvTzw50CZO','B3v5sKW','s3HPBvy','B0Tiq0S','tML4thi','CffzBxG','B2fHsMm','twL4Dvu','v3zNv2O','iYbfEgfTCgXLigvUDhjPzxm6cG','CMvJB3jKAw5NxW','Ahr0CdOVlW','ignVBw1HBMrZ','thzPBKu','zgHcsuC','uhj5ALK','EMffCeW','tLvyqLm','rLzwuLu','ChvZAa','BxvfvM4','EgPOswS','CvnqCMe','sNP4qwy','mxW0Fdn8mNWW','tuPxzNy','u0P6z2q','4PYfifvjqxv0B21HDg9YmIbZzxnZAw9UigrLBgv0zwqGzM9Yia'];_0x3d34=function(){return _0x5f1800;};return _0x3d34();}const wss=new WebSocket[(_0x47c41d(0x272))](_0x1094d3),aiManager=new AIProviderManager();let connectedDevices=[],activeConnections=new Map(),wdaProcesses=new Map(),androidSessions=new Map();function findConfigFile(_0x487521){const _0x255eb9=_0x47c41d,_0x57efb3={'hmWtv':_0x255eb9(0x6a0),'NciEo':function(_0x1e0785,_0x2e7f56){return _0x1e0785(_0x2e7f56);},'pHiKT':'../config/','gbvCj':function(_0xc5a320,_0x564ab3){return _0xc5a320(_0x564ab3);}};let _0xd0341d=path['join'](__dirname,_0x57efb3[_0x255eb9(0x32b)],_0x487521);if(_0x57efb3[_0x255eb9(0x72f)](require,'fs')[_0x255eb9(0x730)](_0xd0341d))return _0xd0341d;_0xd0341d=path[_0x255eb9(0x5c8)](__dirname,_0x57efb3[_0x255eb9(0x24a)],_0x487521);if(_0x57efb3['gbvCj'](require,'fs')['existsSync'](_0xd0341d))return _0xd0341d;return path[_0x255eb9(0x5c8)](__dirname,_0x57efb3[_0x255eb9(0x32b)],_0x487521);}function findScriptFile(_0x3218e6){const _0x5a61e2=_0x47c41d,_0x23fe09={'QOJmt':_0x5a61e2(0x6a0),'oKHCK':function(_0x5dd94c,_0x2b4130){return _0x5dd94c(_0x2b4130);},'UMsMT':_0x5a61e2(0x20c),'WLSJO':function(_0x49bede,_0x5184bd){return _0x49bede(_0x5184bd);},'NOErX':_0x5a61e2(0x6b4)};let _0x186e00=path[_0x5a61e2(0x5c8)](__dirname,_0x23fe09['QOJmt'],_0x3218e6);if(_0x23fe09[_0x5a61e2(0x813)](require,'fs')[_0x5a61e2(0x730)](_0x186e00))return _0x186e00;_0x186e00=path[_0x5a61e2(0x5c8)](__dirname,_0x23fe09[_0x5a61e2(0x391)],_0x3218e6);if(_0x23fe09[_0x5a61e2(0x213)](require,'fs')['existsSync'](_0x186e00)){if(_0x23fe09[_0x5a61e2(0x625)]!==_0x23fe09['NOErX'])_0x2c8cc3[_0x5a61e2(0x61d)]('ā
\x20UIAutomator2\x20already\x20installed\x20on\x20'+_0x423a95);else return _0x186e00;}const _0x32aefa=_0x3218e6[_0x5a61e2(0x3bd)](/\.sh$/,'');_0x186e00=path[_0x5a61e2(0x5c8)](__dirname,_0x5a61e2(0x20c),_0x32aefa);if(_0x23fe09['oKHCK'](require,'fs')['existsSync'](_0x186e00))return _0x186e00;return path[_0x5a61e2(0x5c8)](__dirname,_0x23fe09[_0x5a61e2(0x849)],_0x3218e6);}const DEVICE_CONFIG=findConfigFile(_0x47c41d(0x7bb)),SESSION_MAP_FILE=path['join'](require('os')['tmpdir'](),_0x47c41d(0x464)),APPS_CONFIG=findConfigFile(_0x47c41d(0x84a)),WIRELESS_SCRIPT_PATH=findScriptFile('connect_ios_wireless_multi_final.sh'),USB_SCRIPT_PATH=findScriptFile(_0x47c41d(0x6ce)),ANDROID_WIRELESS_SCRIPT_PATH=findScriptFile(_0x47c41d(0x537)),ANDROID_USB_SCRIPT_PATH=findScriptFile(_0x47c41d(0x537)),RECORDINGS_DIR=path['join'](__dirname,_0x47c41d(0x5d0)),SCREENSHOTS_DIR=path['join'](__dirname,_0x47c41d(0x674));let currentRecording=null,isRecording=![],isReplaying=![],replayAborted=![];async function startUIAutomator2Session(_0x27c358,_0x2bbb6a){const _0x425d04=_0x47c41d,_0x498eac={'HkvvF':'command_output','NtTck':_0x425d04(0x503),'piDQM':_0x425d04(0x5b4),'VAWfW':function(_0x57ddd4,_0x4fd825){return _0x57ddd4===_0x4fd825;},'ibNDc':_0x425d04(0x559),'mrDGd':_0x425d04(0x571),'zJpav':_0x425d04(0x837),'rymet':function(_0x51584c,_0xcc74cd,_0x4629e1){return _0x51584c(_0xcc74cd,_0x4629e1);},'zziTM':function(_0x5583af,_0x583494){return _0x5583af!==_0x583494;},'ouyJL':function(_0x17e1f7,_0x48cf86,_0x41cea7,_0x301886){return _0x17e1f7(_0x48cf86,_0x41cea7,_0x301886);},'TzZyL':_0x425d04(0x867),'xVWxO':'instrument','WXNtf':_0x425d04(0x742),'KkXBw':'ignore','qwlRP':function(_0x7d635b,_0x327789){return _0x7d635b(_0x327789);},'LAhPJ':_0x425d04(0x21a),'vzQkD':_0x425d04(0x377),'sCoie':function(_0x3d4750,_0x121ded){return _0x3d4750+_0x121ded;},'SJsmh':_0x425d04(0x62c)};console[_0x425d04(0x61d)](_0x425d04(0x317)+_0x2bbb6a+'\x20('+_0x27c358+_0x425d04(0x5e0));try{if(_0x498eac[_0x425d04(0x546)](_0x498eac[_0x425d04(0x48b)],_0x425d04(0x494)))_0x1187a5+=_0x1178e8[_0x425d04(0x7de)]();else{let _0x331f1f=0x2008;while(!![]){if(_0x498eac[_0x425d04(0x553)]!==_0x498eac[_0x425d04(0x320)])try{const _0x1f4e7e={};_0x1f4e7e[_0x425d04(0x4f2)]=_0x425d04(0x41a),_0x498eac[_0x425d04(0x86c)](execSync,_0x425d04(0x305)+_0x331f1f,_0x1f4e7e),_0x331f1f++;}catch{if(_0x498eac[_0x425d04(0x6ad)](_0x425d04(0x452),_0x425d04(0x36d)))break;else{_0x4dfc23=!![];const _0x1c319f={};_0x1c319f[_0x425d04(0x4b8)]=_0x498eac[_0x425d04(0x4a1)],_0x1c319f['data']=_0x498eac[_0x425d04(0x2d2)],_0x16c9d1[_0x425d04(0x71d)](_0xde01f1[_0x425d04(0x33e)](_0x1c319f));}}else _0x12e655+=_0x233fe1[_0x425d04(0x7de)]();}console[_0x425d04(0x61d)](_0x425d04(0x31d)+_0x331f1f+_0x425d04(0x298)+_0x2bbb6a);const _0x268a7c=_0x498eac[_0x425d04(0x811)](spawn,_0x425d04(0x229),['-s',_0x27c358,_0x498eac['TzZyL'],'am',_0x498eac['xVWxO'],'-w',_0x498eac[_0x425d04(0x1fb)]],{'detached':!![],'stdio':_0x498eac[_0x425d04(0x7f1)]});_0x268a7c['unref'](),await new Promise(_0x589c5a=>setTimeout(_0x589c5a,0x7d0)),_0x498eac[_0x425d04(0x2d6)](execSync,'adb\x20-s\x20'+_0x27c358+_0x425d04(0x55f)+_0x331f1f+_0x425d04(0x55c)),await new Promise(_0x8b24cf=>setTimeout(_0x8b24cf,0x7d0));const _0x517631=require(_0x498eac[_0x425d04(0x880)]),_0x41929d={};_0x41929d['platformName']=_0x425d04(0x333),_0x41929d['appium:automationName']=_0x425d04(0x800),_0x41929d[_0x425d04(0x5f0)]=_0x27c358;const _0x1d5936={};_0x1d5936[_0x425d04(0x556)]=_0x41929d;const _0x217d8d={};_0x217d8d['capabilities']=_0x1d5936;const _0x373fc2=await _0x517631[_0x425d04(0x328)]('http://localhost:'+_0x331f1f+_0x425d04(0x8b7),_0x217d8d),_0x404521=_0x373fc2['data'][_0x425d04(0x4d6)][_0x425d04(0x39b)]||_0x373fc2[_0x425d04(0x1da)][_0x425d04(0x39b)],_0x317fd0={};_0x317fd0[_0x425d04(0x39b)]=_0x404521,_0x317fd0[_0x425d04(0x6c2)]=_0x331f1f,_0x317fd0['serverPid']=_0x268a7c[_0x425d04(0x64c)],_0x317fd0[_0x425d04(0x26e)]=_0x2bbb6a,androidSessions[_0x425d04(0x47a)](_0x27c358,_0x317fd0);try{let _0x5b234c='';try{_0x5b234c=await fs[_0x425d04(0x7fe)](SESSION_MAP_FILE,_0x498eac[_0x425d04(0x341)]);}catch(_0x2773a1){}const _0x196bff=_0x5b234c[_0x425d04(0x307)]('\x0a')[_0x425d04(0x3c2)](_0x3e0489=>_0x3e0489&&!_0x3e0489[_0x425d04(0x75e)](_0x27c358+':'));_0x196bff['push'](_0x27c358+':'+_0x404521+':'+_0x331f1f),await fs['writeFile'](SESSION_MAP_FILE,_0x498eac[_0x425d04(0x425)](_0x196bff[_0x425d04(0x5c8)]('\x0a'),'\x0a')),console['log'](_0x425d04(0x209)+_0x27c358+':'+_0x404521+':'+_0x331f1f);}catch(_0x564c95){console[_0x425d04(0x6c8)](_0x425d04(0x8ac)+_0x564c95[_0x425d04(0x6dc)]);}console[_0x425d04(0x61d)]('ā
\x20UIAutomator2\x20session\x20created\x20for\x20'+_0x2bbb6a),console[_0x425d04(0x61d)](_0x425d04(0x27a)+_0x404521),console[_0x425d04(0x61d)](_0x425d04(0x539)+_0x331f1f);const _0x35c0e4={};return _0x35c0e4[_0x425d04(0x859)]=!![],_0x35c0e4['sessionId']=_0x404521,_0x35c0e4[_0x425d04(0x6c2)]=_0x331f1f,_0x35c0e4;}}catch(_0x4bed0e){if(_0x498eac[_0x425d04(0x546)](_0x498eac[_0x425d04(0x1fc)],_0x498eac['SJsmh'])){console[_0x425d04(0x6c8)](_0x425d04(0x24f)+_0x2bbb6a+':',_0x4bed0e['message']);const _0x1af4f7={};return _0x1af4f7[_0x425d04(0x859)]=![],_0x1af4f7['error']=_0x4bed0e[_0x425d04(0x6dc)],_0x1af4f7;}else _0xef9720[_0x425d04(0x66d)]=_0x5bda18,_0x729e15[_0x425d04(0x719)]=_0x81d6cb,_0x59d9a5[_0x425d04(0x5a7)]=_0x498eac['piDQM'];}}async function stopUIAutomator2Session(_0x470ea8,_0x6a25f7){const _0x12da20=_0x47c41d,_0x189630={'ixYhd':_0x12da20(0x89d),'yazNK':function(_0x49dbf6,_0x550895){return _0x49dbf6(_0x550895);},'vhkWb':function(_0x26ff8d,_0x56d259){return _0x26ff8d!==_0x56d259;},'JxzjR':_0x12da20(0x7e1),'DqOgz':_0x12da20(0x4f1),'bBeAX':'No\x20active\x20session','Uunmp':function(_0x1a7926,_0xb6aff4){return _0x1a7926!==_0xb6aff4;},'ZsnbZ':_0x12da20(0x4bb),'nhjnw':'axios','LNUdb':function(_0x5ae98c,_0x4940dc){return _0x5ae98c===_0x4940dc;},'BmJsd':_0x12da20(0x268),'UmbnQ':_0x12da20(0x2d8),'iFwsl':function(_0x42a205,_0x4d9be8){return _0x42a205(_0x4d9be8);},'PYAVa':function(_0x4ed603,_0xbbe967){return _0x4ed603(_0xbbe967);},'Srzpp':_0x12da20(0x377)};console[_0x12da20(0x61d)]('š\x20Stopping\x20UIAutomator2\x20session\x20for\x20'+_0x6a25f7+'\x20('+_0x470ea8+')...');try{if(_0x189630[_0x12da20(0x497)](_0x189630[_0x12da20(0x41f)],_0x189630[_0x12da20(0x76e)])){const _0x245692=androidSessions['get'](_0x470ea8);if(!_0x245692){console[_0x12da20(0x61d)](_0x12da20(0x273)+_0x6a25f7);const _0x3b2d3f={};return _0x3b2d3f['success']=!![],_0x3b2d3f[_0x12da20(0x6dc)]=_0x189630['bBeAX'],_0x3b2d3f;}try{if(_0x189630['Uunmp'](_0x189630[_0x12da20(0x887)],_0x189630[_0x12da20(0x887)])){const _0x3bb3e7=_0x571a7c[_0x12da20(0x7de)]();(_0x3bb3e7['includes'](_0x12da20(0x2f6))||_0x3bb3e7[_0x12da20(0x310)](_0x189630['ixYhd']))&&_0x40175b['log'](_0x12da20(0x25f)+_0x2b29e7+_0x12da20(0x7ee)+_0x3bb3e7[_0x12da20(0x685)]());}else{const _0x47645c=_0x189630[_0x12da20(0x6e9)](require,_0x189630[_0x12da20(0x1e8)]);await _0x47645c['delete'](_0x12da20(0x5aa)+_0x245692[_0x12da20(0x6c2)]+'/wd/hub/session/'+_0x245692[_0x12da20(0x39b)]),console['log'](_0x12da20(0x82b)+_0x6a25f7);}}catch(_0x37599b){_0x189630[_0x12da20(0x332)]('HgYNl',_0x189630['BmJsd'])?(_0x2b7fae=_0x12da20(0x8c0)+_0x43444f+'\x22',_0x4448c6['log'](_0x12da20(0x8c1)+_0x35bc07+_0x12da20(0x64a)+_0x2efef4)):console[_0x12da20(0x61d)](_0x12da20(0x396)+_0x37599b[_0x12da20(0x6dc)]);}try{_0x189630[_0x12da20(0x6e9)](execSync,'adb\x20-s\x20'+_0x470ea8+'\x20forward\x20--remove\x20tcp:'+_0x245692[_0x12da20(0x6c2)]),console[_0x12da20(0x61d)](_0x12da20(0x1f6)+_0x6a25f7);}catch(_0x537584){console['log']('ā ļø\x20\x20Could\x20not\x20remove\x20port\x20forwarding:\x20'+_0x537584['message']);}try{if(_0x189630['vhkWb'](_0x189630[_0x12da20(0x500)],_0x189630[_0x12da20(0x500)])){const _0x76e50={};return _0x76e50[_0x12da20(0x859)]=![],_0x76e50[_0x12da20(0x6c8)]=_0x12da20(0x22e),_0xce0b77['status'](0x190)[_0x12da20(0x843)](_0x76e50);}else _0x189630[_0x12da20(0x4ee)](execSync,'adb\x20-s\x20'+_0x470ea8+_0x12da20(0x630)),_0x189630['PYAVa'](execSync,'adb\x20-s\x20'+_0x470ea8+_0x12da20(0x7c3)),console[_0x12da20(0x61d)](_0x12da20(0x43b)+_0x6a25f7);}catch(_0x52f322){console[_0x12da20(0x61d)](_0x12da20(0x1ec)+_0x52f322[_0x12da20(0x6dc)]);}androidSessions['delete'](_0x470ea8);try{const _0x1f5313=await fs[_0x12da20(0x7fe)](SESSION_MAP_FILE,_0x189630[_0x12da20(0x462)]),_0x40b67f=_0x1f5313[_0x12da20(0x307)]('\x0a')[_0x12da20(0x3c2)](_0x477e35=>!_0x477e35[_0x12da20(0x75e)](_0x470ea8+':'));await fs[_0x12da20(0x35b)](SESSION_MAP_FILE,_0x40b67f['join']('\x0a')),console[_0x12da20(0x61d)](_0x12da20(0x3fb)+_0x6a25f7);}catch(_0x4beb6b){console[_0x12da20(0x61d)]('ā ļø\x20\x20Could\x20not\x20update\x20session\x20file:\x20'+_0x4beb6b[_0x12da20(0x6dc)]);}console[_0x12da20(0x61d)]('ā
\x20UIAutomator2\x20session\x20stopped\x20for\x20'+_0x6a25f7);const _0x3121dd={};return _0x3121dd[_0x12da20(0x859)]=!![],_0x3121dd;}else _0x189630[_0x12da20(0x6e9)](_0x3ac6fc,'adb\x20-s\x20'+_0x516c49+_0x12da20(0x588)+_0x514aae[_0x12da20(0x6c2)]),_0x5689e2[_0x12da20(0x61d)](_0x12da20(0x1f6)+_0x2e621c);}catch(_0x574f78){console['error'](_0x12da20(0x6f3)+_0x6a25f7+':',_0x574f78[_0x12da20(0x6dc)]);const _0x35ce09={};return _0x35ce09['success']=![],_0x35ce09[_0x12da20(0x6c8)]=_0x574f78['message'],_0x35ce09;}}async function loadDeviceConfig(){const _0x2ae5c9=_0x47c41d,_0x49697b={'Ugjzx':function(_0x51b57c,_0x48e382,_0x4bbb7b){return _0x51b57c(_0x48e382,_0x4bbb7b);},'JnOwb':_0x2ae5c9(0x377),'xvrHp':function(_0x49a8f6,_0x2b2d54,_0x5b4489){return _0x49a8f6(_0x2b2d54,_0x5b4489);},'HKrMM':_0x2ae5c9(0x62e),'HGloR':function(_0x2d7485,_0x55b15a){return _0x2d7485===_0x55b15a;},'pBKkG':function(_0x5c85e6,_0x377e59){return _0x5c85e6(_0x377e59);},'ywkVu':function(_0x17009c,_0xb0e37e){return _0x17009c||_0xb0e37e;},'LumKd':function(_0xdf068,_0x26c73f){return _0xdf068!==_0x26c73f;},'BTsuA':'offline','uIVBr':_0x2ae5c9(0x33a),'WZyki':function(_0x211c1c,_0x5e85dd){return _0x211c1c||_0x5e85dd;},'QwDbt':_0x2ae5c9(0x335),'VxdRV':_0x2ae5c9(0x7d2),'ufmUh':'XProS','cvXCo':_0x2ae5c9(0x3d8),'OjvFu':_0x2ae5c9(0x2db),'GZJju':_0x2ae5c9(0x705),'nVsnz':function(_0x2fa63c,_0x17a61f){return _0x2fa63c>_0x17a61f;},'DPaEG':_0x2ae5c9(0x3be),'FSvGQ':function(_0x224456,_0x2929ef){return _0x224456||_0x2929ef;},'dhvpo':_0x2ae5c9(0x501),'ZMFoJ':_0x2ae5c9(0x622),'TRUmR':function(_0x4c65c4,_0x451cb6,_0x2c44f8,_0x1f4b3a,_0xe07ec){return _0x4c65c4(_0x451cb6,_0x2c44f8,_0x1f4b3a,_0xe07ec);},'sljlg':_0x2ae5c9(0x352),'QccsT':_0x2ae5c9(0x3a0)};try{if(_0x49697b[_0x2ae5c9(0x505)]===_0x49697b[_0x2ae5c9(0x505)]){const _0x2b1f08=await fs[_0x2ae5c9(0x7fe)](DEVICE_CONFIG,_0x49697b[_0x2ae5c9(0x74c)]),_0x5523a9=_0x2b1f08[_0x2ae5c9(0x307)]('\x0a')[_0x2ae5c9(0x3c2)](_0x18a247=>_0x18a247[_0x2ae5c9(0x685)]()&&!_0x18a247[_0x2ae5c9(0x75e)]('#'))[_0x2ae5c9(0x2d0)](_0x5df2e5=>{const _0x3335a4=_0x2ae5c9,_0x2b45e6={};_0x2b45e6[_0x3335a4(0x486)]=function(_0x2b597d,_0x3b48ce){return _0x2b597d===_0x3b48ce;},_0x2b45e6[_0x3335a4(0x6f4)]=_0x49697b[_0x3335a4(0x4c2)];const _0x2b2508=_0x2b45e6,_0x51b905=_0x5df2e5[_0x3335a4(0x307)](',')[_0x3335a4(0x2d0)](_0x519265=>_0x519265[_0x3335a4(0x685)]()),[_0x4cbc5f,_0x347f82,_0x3f5b90,_0x4fc67b,_0x5b9833]=_0x51b905;let _0x7e027e=_0x49697b[_0x3335a4(0x2b9)](_0x4fc67b,_0x49697b['QwDbt']);if(!_0x4fc67b&&_0x347f82){if(_0x3335a4(0x7d2)!==_0x49697b[_0x3335a4(0x58d)])_0x4c332c+=_0x5ac1db[_0x3335a4(0x7de)]();else{if(_0x347f82[_0x3335a4(0x310)](':')&&_0x347f82[_0x3335a4(0x295)](/^\d+\.\d+\.\d+\.\d+:\d+$/)){if(_0x49697b[_0x3335a4(0x3f2)]===_0x49697b[_0x3335a4(0x3f2)])_0x7e027e=_0x3335a4(0x705);else{_0x5843e3['log']('š¦\x20Installing\x20server\x20APK:\x20'+_0x1f118b);const _0x263f00=_0x49697b['Ugjzx'](_0x3adc9f,_0x3335a4(0x2b1)+_0x47821a+_0x3335a4(0x675)+_0x56f5e6+_0x3335a4(0x83a),{'encoding':_0x49697b[_0x3335a4(0x74c)]});_0x3f614b[_0x3335a4(0x61d)](_0x263f00),_0x5b580f['log']('š¦\x20Installing\x20test\x20APK:\x20'+_0x482c44);const _0x408eca=_0x49697b[_0x3335a4(0x834)](_0x1fce3f,_0x3335a4(0x2b1)+_0x302640+_0x3335a4(0x675)+_0x409629+'\x22\x202>&1',{'encoding':_0x49697b[_0x3335a4(0x74c)]});_0x1a91af[_0x3335a4(0x61d)](_0x408eca),_0x53b408['log'](_0x3335a4(0x858)+_0x216363);const _0x3e2be1={};_0x3e2be1[_0x3335a4(0x859)]=!![],_0x3e2be1[_0x3335a4(0x6dc)]=_0x49697b[_0x3335a4(0x3fd)],_0x2c2b68(_0x3e2be1);}}else{if(_0x347f82[_0x3335a4(0x526)]<0x14&&!_0x347f82['includes']('-')){if(_0x49697b['HGloR'](_0x49697b[_0x3335a4(0x487)],_0x49697b[_0x3335a4(0x5d4)])){if(_0x49697b[_0x3335a4(0x530)](_0x3ac8f6,0x0)){const _0x4bd29d={};_0x4bd29d[_0x3335a4(0x859)]=!![],_0x4bd29d[_0x3335a4(0x88b)]=_0xa208f0,_0x4bd29d[_0x3335a4(0x784)]=_0x23b1e8[_0x3335a4(0x719)],_0x49697b['pBKkG'](_0x5525c6,_0x4bd29d);}else _0xce21de({'success':![],'error':_0x49697b[_0x3335a4(0x523)](_0x1f695e,_0x3e6fe3),'device':_0x52b241[_0x3335a4(0x719)]});}else _0x7e027e=_0x49697b['GZJju'];}else{if(_0x347f82['includes']('-')&&_0x49697b[_0x3335a4(0x3f8)](_0x347f82['length'],0x1e)){if(_0x3335a4(0x1f4)!==_0x49697b[_0x3335a4(0x5f5)])_0x7e027e=_0x49697b[_0x3335a4(0x304)];else{const _0x469b2d=_0x20321d[_0x3335a4(0x6c5)](_0x53077b=>_0x53077b[_0x3335a4(0x719)]===_0x49a62d);_0x49697b['LumKd'](_0x469b2d,-0x1)&&(_0xb2f35f[_0x469b2d][_0x3335a4(0x4d0)]=_0x49697b[_0x3335a4(0x423)]);_0xf9bc83[_0x3335a4(0x284)][_0x3335a4(0x68d)](_0x2b4c2c=>{const _0x2c5188=_0x3335a4;if(_0x2b2508['AeqUj'](_0x2b4c2c[_0x2c5188(0x24e)],_0x2f8843[_0x2c5188(0x3ba)])){const _0x4cdf27={};_0x4cdf27[_0x2c5188(0x4b8)]=_0x2b2508[_0x2c5188(0x6f4)],_0x4cdf27[_0x2c5188(0x658)]=_0x42e846,_0x2b4c2c[_0x2c5188(0x71d)](_0x216ca7[_0x2c5188(0x33e)](_0x4cdf27));}});const _0x204cd6={};_0x204cd6['success']=!![],_0x204cd6[_0x3335a4(0x6dc)]=_0x3335a4(0x868)+_0xea4d4,_0x3d1fac(_0x204cd6);}}}}}}return{'name':_0x4cbc5f,'udid':_0x347f82,'ip':_0x49697b[_0x3335a4(0x5f6)](_0x3f5b90,''),'platform':_0x7e027e,'type':_0x5b9833||(_0x3f5b90?_0x49697b[_0x3335a4(0x445)]:_0x3335a4(0x760)),'status':_0x49697b[_0x3335a4(0x6dd)]};});return _0x5523a9;}else _0x49697b[_0x2ae5c9(0x2d1)](_0x3c4e98,_0x41aba1,_0x2c79a5,_0x5440dc,_0x41557e);}catch(_0x1e1bba){return console[_0x2ae5c9(0x6c8)](_0x49697b[_0x2ae5c9(0x59a)],_0x1e1bba),[];}}async function discoverDevices(){const _0x106517=_0x47c41d,_0x347296={'oLAtH':function(_0x206c18,_0x4238fd){return _0x206c18(_0x4238fd);},'izRlf':function(_0x124eaf,_0x313077){return _0x124eaf!==_0x313077;},'aEJtS':'PXUxe','asCXx':_0x106517(0x3ca),'xAJzv':'4|0|2|1|3','OzIvf':function(_0x295fac,_0x52f2dc){return _0x295fac===_0x52f2dc;},'cZRMI':_0x106517(0x8ab),'sFWzR':function(_0x230f9f){return _0x230f9f();}},_0x128d9e=new Map();return connectedDevices[_0x106517(0x68d)](_0x2d5539=>{const _0x2c5baf=_0x106517;_0x347296[_0x2c5baf(0x4f3)](_0x347296[_0x2c5baf(0x741)],_0x347296[_0x2c5baf(0x226)])?_0x128d9e[_0x2c5baf(0x47a)](_0x2d5539[_0x2c5baf(0x200)],{'status':_0x2d5539['status'],'sessionId':_0x2d5539[_0x2c5baf(0x39b)]}):(_0x26554d[_0x2c5baf(0x6c8)]('Promise.allSettled\x20error:\x20'+_0x33135d['message']),_0x347296['oLAtH'](_0x7004c1,_0x5e5010));}),connectedDevices=await _0x347296[_0x106517(0x2fa)](discoverAllDevices),connectedDevices['forEach'](_0x375a15=>{const _0x1d5073=_0x106517,_0x3c1fc9={'PGMXQ':_0x347296['xAJzv'],'SWrIS':function(_0x2822d7,_0x2e3d4f){return _0x2822d7(_0x2e3d4f);},'vYfBj':function(_0xe4403f,_0x59b84f){return _0xe4403f(_0x59b84f);}},_0x2e224a=_0x128d9e['get'](_0x375a15['udid']);if(_0x2e224a&&_0x347296[_0x1d5073(0x1e6)](_0x2e224a[_0x1d5073(0x4d0)],_0x1d5073(0x29b))){if(_0x347296[_0x1d5073(0x3fc)]!==_0x347296[_0x1d5073(0x3fc)]){const _0x2de658=_0x3c1fc9[_0x1d5073(0x2d5)][_0x1d5073(0x307)]('|');let _0x593d1a=0x0;while(!![]){switch(_0x2de658[_0x593d1a++]){case'0':_0x106293['y']=_0x3c1fc9['SWrIS'](_0x4c63ad,_0x5cf056[0x2]);continue;case'1':_0x120e96[_0x1d5073(0x766)]=_0x439b08(_0x37f55d[0x4]);continue;case'2':_0x3b4f05[_0x1d5073(0x29e)]=_0x3c1fc9[_0x1d5073(0x60a)](_0x551415,_0x25a17c[0x3]);continue;case'3':_0x3a2eaf[_0x1d5073(0x26d)]='('+_0x252922['x']+','+_0x28f06e['y']+')\x20'+_0x553e41['width']+'x'+_0x378bd3[_0x1d5073(0x766)];continue;case'4':_0x128a9b['x']=_0x3c1fc9[_0x1d5073(0x7ca)](_0x17c3ba,_0x332a2d[0x1]);continue;}break;}}else _0x375a15[_0x1d5073(0x4d0)]='online',_0x2e224a[_0x1d5073(0x39b)]&&(_0x375a15[_0x1d5073(0x39b)]=_0x2e224a[_0x1d5073(0x39b)]);}}),await autoSaveUSBDevicesToConfig(connectedDevices),connectedDevices;}async function autoSaveUSBDevicesToConfig(_0x418552){const _0x17fc6d=_0x47c41d,_0x22ac2c={'RWEIO':function(_0x3e683d,_0x5b5157){return _0x3e683d===_0x5b5157;},'vcwOr':function(_0x33a7df){return _0x33a7df();},'UksHD':function(_0x268169,_0x2cd3bb){return _0x268169===_0x2cd3bb;},'icBIb':'#\x20Device\x20Configuration\x20(Auto-updated)\x0a','XqUnY':_0x17fc6d(0x5a8),'FPgaA':'#\x20USB\x20devices\x20auto-detected.\x20Add\x20IP\x20for\x20wireless\x20connection.\x0a\x0a'};try{const _0x390972=_0x418552[_0x17fc6d(0x3c2)](_0x3af9e8=>_0x3af9e8[_0x17fc6d(0x809)]===_0x17fc6d(0x760));if(_0x22ac2c['RWEIO'](_0x390972[_0x17fc6d(0x526)],0x0))return;const _0x4dec45=await _0x22ac2c[_0x17fc6d(0x762)](loadDeviceConfig),_0x172681=new Set(_0x4dec45[_0x17fc6d(0x2d0)](_0x2898b7=>_0x2898b7[_0x17fc6d(0x200)])),_0x1c06ab=_0x390972[_0x17fc6d(0x3c2)](_0xa7d582=>!_0x172681[_0x17fc6d(0x5d8)](_0xa7d582[_0x17fc6d(0x200)]));if(_0x22ac2c[_0x17fc6d(0x773)](_0x1c06ab[_0x17fc6d(0x526)],0x0))return;const _0xc0a3ef=[..._0x4dec45,..._0x1c06ab[_0x17fc6d(0x2d0)](_0x43c096=>({'name':_0x43c096[_0x17fc6d(0x719)],'udid':_0x43c096[_0x17fc6d(0x200)],'ip':''}))];let _0x1192ee=_0x22ac2c[_0x17fc6d(0x3fa)];_0x1192ee+=_0x22ac2c[_0x17fc6d(0x4ad)],_0x1192ee+=_0x22ac2c[_0x17fc6d(0x2cb)],_0xc0a3ef['forEach'](_0x5e946e=>{const _0xf1c3b6=_0x17fc6d,_0x2e2321=_0x5e946e['ip']||'';_0x1192ee+=_0x5e946e[_0xf1c3b6(0x719)]+','+_0x5e946e[_0xf1c3b6(0x200)]+','+_0x2e2321+'\x0a';}),await fs[_0x17fc6d(0x35b)](DEVICE_CONFIG,_0x1192ee),console[_0x17fc6d(0x61d)](_0x17fc6d(0x2de)+_0x1c06ab[_0x17fc6d(0x526)]+_0x17fc6d(0x780));}catch(_0x1d5e51){console[_0x17fc6d(0x6c8)](_0x17fc6d(0x258),_0x1d5e51);}}function checkDeviceConnectivity(_0x25c3fd){const _0x3f479a=_0x47c41d,_0x118e38={'QwFXm':function(_0x272a67,_0x1495e1){return _0x272a67(_0x1495e1);},'kGCiQ':_0x3f479a(0x33a),'Wrlfl':_0x3f479a(0x48f),'yuDSc':_0x3f479a(0x7c9),'MDGoz':_0x3f479a(0x22a),'dXpxV':_0x3f479a(0x1da),'XaZgZ':_0x3f479a(0x884),'sycTW':function(_0xc8444a,_0xff8668,_0x248bd1){return _0xc8444a(_0xff8668,_0x248bd1);}};return new Promise(_0x2c4496=>{const _0x5be0ce=_0x3f479a,_0x1843de={'nzDTd':function(_0x1ed5b7,_0x5f46e3){return _0x1ed5b7===_0x5f46e3;},'SJzgd':_0x118e38[_0x5be0ce(0x43d)],'rrQrK':function(_0x47a37f,_0x55d926){return _0x47a37f!==_0x55d926;},'wkkzA':'PbAaj','llegf':function(_0x246869,_0x5a328d){const _0x3adcf0=_0x5be0ce;return _0x118e38[_0x3adcf0(0x5cb)](_0x246869,_0x5a328d);},'cGVwI':_0x5be0ce(0x65f)},_0x514110=spawn(_0x118e38[_0x5be0ce(0x378)],['-s',_0x118e38[_0x5be0ce(0x7cb)],'2',_0x118e38['MDGoz'],'3',_0x5be0ce(0x81b)+_0x25c3fd['ip']+_0x5be0ce(0x4cf)]);let _0x1476b8='';_0x514110[_0x5be0ce(0x803)]['on'](_0x118e38[_0x5be0ce(0x6ac)],_0x4f4110=>{const _0xd7985f=_0x5be0ce;if(_0x1843de[_0xd7985f(0x2e6)](_0x1843de[_0xd7985f(0x771)],_0xd7985f(0x385))){if(_0x1843de['nzDTd'](_0x3c3fe0[_0xd7985f(0x24e)],_0x59421e['OPEN'])){const _0x352719={};_0x352719[_0xd7985f(0x4b8)]=_0x1843de[_0xd7985f(0x82a)],_0x352719[_0xd7985f(0x658)]=_0x32992d,_0x546828[_0xd7985f(0x71d)](_0x42350f[_0xd7985f(0x33e)](_0x352719));}}else _0x1476b8+=_0x4f4110[_0xd7985f(0x7de)]();}),_0x514110['on'](_0x118e38['XaZgZ'],_0x4f86dc=>{const _0x314597=_0x5be0ce;_0x1843de['llegf'](_0x2c4496,_0x1476b8[_0x314597(0x310)](_0x1843de[_0x314597(0x68e)]));}),_0x118e38['sycTW'](setTimeout,()=>{const _0x5d23f0=_0x5be0ce;_0x514110[_0x5d23f0(0x510)](),_0x118e38[_0x5d23f0(0x5cb)](_0x2c4496,![]);},0xbb8);});}function loadAppPresets(){const _0x5862e7=_0x47c41d,_0xb9e5fa={'AbtCk':'Error\x20loading\x20device\x20config:','vvIdv':function(_0x37f571,_0x5d1b2c){return _0x37f571!==_0x5d1b2c;},'IJTts':_0x5862e7(0x5d9),'SGnLo':'VwqgH','YxcQH':function(_0x292820,_0x589a63){return _0x292820===_0x589a63;},'KpQHt':function(_0x4ca0fd,_0x3fa35f){return _0x4ca0fd(_0x3fa35f);},'JStiR':function(_0x16741e,_0x261747){return _0x16741e(_0x261747);},'TFlxg':_0x5862e7(0x377),'BYCnf':_0x5862e7(0x629)};try{if(!_0xb9e5fa[_0x5862e7(0x86d)](require,'fs')[_0x5862e7(0x730)](APPS_CONFIG))return{};const _0x2f2087=_0xb9e5fa[_0x5862e7(0x73e)](require,'fs')[_0x5862e7(0x854)](APPS_CONFIG,_0xb9e5fa[_0x5862e7(0x2ef)]),_0x46d22b={};return _0x2f2087[_0x5862e7(0x307)]('\x0a')[_0x5862e7(0x3c2)](_0x14930e=>_0x14930e[_0x5862e7(0x685)]()&&!_0x14930e[_0x5862e7(0x75e)]('#'))[_0x5862e7(0x68d)](_0x14ddb5=>{const _0x22af0c=_0x5862e7,_0x4436ec={};_0x4436ec[_0x22af0c(0x7fb)]=_0x22af0c(0x33a);const _0x12adf8=_0x4436ec;if(_0xb9e5fa[_0x22af0c(0x669)](_0xb9e5fa[_0x22af0c(0x84c)],_0x22af0c(0x5d9)))return _0x3384c2[_0x22af0c(0x6c8)](PxBtDJ[_0x22af0c(0x27b)],_0x5f36e3),[];else{const [_0x37e92e,_0x3424ad]=_0x14ddb5[_0x22af0c(0x307)](',')[_0x22af0c(0x2d0)](_0x4ef8f0=>_0x4ef8f0[_0x22af0c(0x685)]());if(_0x37e92e&&_0x3424ad){if(_0xb9e5fa['SGnLo']!==_0xb9e5fa[_0x22af0c(0x456)]){const _0x5559c3={};_0x5559c3[_0x22af0c(0x4b8)]=_0x12adf8[_0x22af0c(0x7fb)],_0x5559c3[_0x22af0c(0x658)]=_0x3e2d8f,_0x520f69[_0x22af0c(0x71d)](_0x4c1d6b[_0x22af0c(0x33e)](_0x5559c3));}else{const _0x3d77e9=_0x37e92e[_0x22af0c(0x307)]('.');if(_0xb9e5fa[_0x22af0c(0x255)](_0x3d77e9[_0x22af0c(0x526)],0x2)){const [_0x435295,_0x610e55]=_0x3d77e9;if(!_0x46d22b[_0x435295])_0x46d22b[_0x435295]={};_0x46d22b[_0x435295][_0x610e55]=_0x3424ad;}else{if(!_0x46d22b[_0x37e92e])_0x46d22b[_0x37e92e]={};_0x46d22b[_0x37e92e][_0x22af0c(0x474)]=_0x3424ad;}}}}}),_0x46d22b;}catch(_0x570252){return console[_0x5862e7(0x6c8)](_0xb9e5fa['BYCnf'],_0x570252),{};}}function resolveAppPreset(_0x8f8ccc,_0x1d7018){const _0x16cd90=_0x47c41d,_0xf3c4e7={'BlTVW':function(_0x3895b2){return _0x3895b2();}},_0x81dc50=_0xf3c4e7[_0x16cd90(0x5ae)](loadAppPresets),_0x197e70=_0x8f8ccc[_0x16cd90(0x295)](/^launch\s+(\S+)(.*)$/);if(!_0x197e70)return _0x8f8ccc;const _0xe3e132=_0x197e70[0x1],_0x20f8c7=_0x197e70[0x2];if(_0xe3e132[_0x16cd90(0x310)]('.'))return _0x8f8ccc;if(_0x81dc50[_0xe3e132]){const _0x154147=_0x81dc50[_0xe3e132];let _0x4b8ae7;if(_0x154147[_0x1d7018])_0x4b8ae7=_0x154147[_0x1d7018];else _0x154147[_0x16cd90(0x474)]&&(_0x4b8ae7=_0x154147[_0x16cd90(0x474)]);if(_0x4b8ae7)return console[_0x16cd90(0x61d)]('\x20\x20š±\x20Resolved\x20app\x20preset:\x20\x22'+_0xe3e132+_0x16cd90(0x88c)+_0x4b8ae7+'\x22\x20('+_0x1d7018+')'),_0x16cd90(0x671)+_0x4b8ae7+_0x20f8c7;}return _0x8f8ccc;}function executeCommand(_0x3042c2,_0x52ea43,_0x5517e7){const _0x2850b8=_0x47c41d,_0x429690={'xWIUO':function(_0x2bf5eb,_0x2449b5){return _0x2bf5eb!==_0x2449b5;},'tPqau':_0x2850b8(0x6e6),'HGxyK':function(_0x3574af,_0x1d834b){return _0x3574af===_0x1d834b;},'UWfWR':_0x2850b8(0x6bd),'rYLrJ':_0x2850b8(0x4fc),'qthOX':function(_0x49da92,_0xf16a50){return _0x49da92>_0xf16a50;},'itrbo':_0x2850b8(0x777),'ddAtl':function(_0xb13edc,_0x3d2cbe){return _0xb13edc>_0x3d2cbe;},'xaTrl':function(_0x2aa752,_0x4a6bc8,_0x47271e){return _0x2aa752(_0x4a6bc8,_0x47271e);},'RBOZT':_0x2850b8(0x335),'pIgJG':function(_0x3c31d0,_0xa08e36){return _0x3c31d0>_0xa08e36;},'duEHz':function(_0x11484f,_0x5e7d58,_0x16ce21,_0x346846,_0x225d22){return _0x11484f(_0x5e7d58,_0x16ce21,_0x346846,_0x225d22);},'KLkll':'android','oRzKM':function(_0x29f16f,_0x47e90e,_0x15c06f){return _0x29f16f(_0x47e90e,_0x15c06f);},'OAnYV':function(_0x14eb94,_0x38b877){return _0x14eb94(_0x38b877);},'cZvSW':_0x2850b8(0x400),'EpAoU':'Script\x20execution\x20error:'};return new Promise(async(_0x45b2fc,_0x3cc176)=>{const _0x21e510=_0x2850b8;if(_0x429690[_0x21e510(0x7ae)](_0x429690['tPqau'],_0x429690['tPqau']))_0xfb2cd6[_0x21e510(0x61d)](_0x21e510(0x1f5)+_0x530fc8),_0x1186b2[_0x21e510(0x27e)](_0x3c6831);else{console[_0x21e510(0x61d)]('\x0a'+'#'[_0x21e510(0x552)](0x3c)),console['log'](_0x21e510(0x72d)+_0x3042c2['join'](',\x20')+']'),console['log']('Command:\x20\x22'+_0x52ea43+'\x22'),console[_0x21e510(0x61d)]('#'[_0x21e510(0x552)](0x3c)+'\x0a');const _0x3c7ce3=connectedDevices[_0x21e510(0x3c2)](_0x160232=>_0x3042c2[_0x21e510(0x310)](_0x160232['name'])||_0x3042c2[_0x21e510(0x310)](_0x160232['udid'])||_0x3042c2[_0x21e510(0x310)](_0x160232['serial']));console[_0x21e510(0x61d)]('Cache\x20contents:',connectedDevices[_0x21e510(0x2d0)](_0x20d8bd=>_0x20d8bd[_0x21e510(0x719)]+'('+_0x20d8bd[_0x21e510(0x4d0)]+')')['join'](',\x20'));if(_0x429690[_0x21e510(0x30f)](_0x3c7ce3['length'],0x0)){if(_0x429690[_0x21e510(0x30f)](_0x429690[_0x21e510(0x636)],_0x429690[_0x21e510(0x636)])){console[_0x21e510(0x6c8)](_0x21e510(0x315)+_0x3042c2[_0x21e510(0x5c8)](',\x20')+']');const _0x34a726={};return _0x34a726[_0x21e510(0x859)]=![],_0x34a726[_0x21e510(0x6c8)]=_0x429690[_0x21e510(0x275)],_0x3cc176(_0x34a726);}else _0x22fadb+=_0x22e8c4['toString']();}const _0x1b4434=_0x3c7ce3[_0x21e510(0x3c2)](_0x3d05d8=>![_0x21e510(0x29b),_0x21e510(0x3aa)][_0x21e510(0x310)](_0x3d05d8[_0x21e510(0x4d0)]));if(_0x429690[_0x21e510(0x446)](_0x1b4434[_0x21e510(0x526)],0x0)){const _0x52736e=_0x1b4434['map'](_0x218f00=>_0x218f00[_0x21e510(0x719)]+'\x20(status:\x20'+_0x218f00[_0x21e510(0x4d0)]+')')[_0x21e510(0x5c8)](',\x20');console[_0x21e510(0x6c8)](_0x21e510(0x348)+_0x52736e+']');if(_0x5517e7){const _0x196949={};_0x196949[_0x21e510(0x4b8)]='command_output',_0x196949[_0x21e510(0x1da)]=_0x21e510(0x8a2)+_0x52736e+_0x21e510(0x799),_0x196949[_0x21e510(0x658)]=_0x3042c2,_0x5517e7['send'](JSON[_0x21e510(0x33e)](_0x196949));}const _0x289b8b={};return _0x289b8b[_0x21e510(0x859)]=![],_0x289b8b[_0x21e510(0x6c8)]='Devices\x20not\x20connected:\x20'+_0x52736e+_0x21e510(0x8ae),_0x3cc176(_0x289b8b);}console[_0x21e510(0x61d)]('ā
\x20Found\x20'+_0x3c7ce3['length']+_0x21e510(0x444)),console[_0x21e510(0x61d)](_0x429690[_0x21e510(0x31c)],_0x3c7ce3[_0x21e510(0x2d0)](_0x26727d=>_0x26727d[_0x21e510(0x719)]+'('+_0x26727d[_0x21e510(0x581)]+'-'+_0x26727d['connectionType']+')')[_0x21e510(0x5c8)](',\x20'));const _0x4b7b4e=_0x3c7ce3[_0x21e510(0x3c2)](_0x369ff5=>_0x369ff5[_0x21e510(0x581)]===_0x21e510(0x335)&&_0x369ff5[_0x21e510(0x809)]==='usb'),_0x161b17=_0x3c7ce3[_0x21e510(0x3c2)](_0xc03046=>_0xc03046['platform']==='ios'&&_0xc03046[_0x21e510(0x809)]===_0x21e510(0x501)),_0x50584d=_0x3c7ce3[_0x21e510(0x3c2)](_0x4908df=>_0x4908df['platform']===_0x21e510(0x705)&&_0x4908df[_0x21e510(0x809)]===_0x21e510(0x760)),_0x24bb46=_0x3c7ce3[_0x21e510(0x3c2)](_0x232a3b=>_0x232a3b[_0x21e510(0x581)]===_0x21e510(0x705)&&_0x232a3b[_0x21e510(0x809)]===_0x21e510(0x501)),_0x5dc6ab=[];if(_0x429690['ddAtl'](_0x4b7b4e[_0x21e510(0x526)],0x0)){const _0x213416=_0x4b7b4e[_0x21e510(0x2d0)](_0x3b0ac4=>_0x3b0ac4['name']),_0x1ba1fe=_0x429690[_0x21e510(0x518)](resolveAppPreset,_0x52ea43,_0x429690['RBOZT']);console[_0x21e510(0x61d)](_0x21e510(0x702)+_0x213416[_0x21e510(0x5c8)](',\x20')),_0x5dc6ab['push'](executeWithScript(USB_SCRIPT_PATH,_0x213416,_0x1ba1fe,_0x5517e7));}if(_0x429690['pIgJG'](_0x161b17[_0x21e510(0x526)],0x0)){const _0x192ace=_0x161b17['map'](_0x4bde18=>_0x4bde18['name']),_0x51dbd2=resolveAppPreset(_0x52ea43,_0x429690[_0x21e510(0x832)]);console[_0x21e510(0x61d)](_0x21e510(0x43c)+_0x192ace['join'](',\x20')),_0x5dc6ab[_0x21e510(0x823)](_0x429690['duEHz'](executeWithScript,WIRELESS_SCRIPT_PATH,_0x192ace,_0x51dbd2,_0x5517e7));}if(_0x429690[_0x21e510(0x6a4)](_0x50584d[_0x21e510(0x526)],0x0)){const _0xf92518=_0x429690['xaTrl'](resolveAppPreset,_0x52ea43,_0x429690['KLkll']);console[_0x21e510(0x61d)]('Using\x20Android\x20control\x20script\x20for\x20USB\x20devices:\x20'+_0x50584d[_0x21e510(0x2d0)](_0x5539d6=>_0x5539d6['name'])[_0x21e510(0x5c8)](',\x20')),_0x5dc6ab[_0x21e510(0x823)](_0x429690[_0x21e510(0x889)](executeAndroidDevices,ANDROID_USB_SCRIPT_PATH,_0x50584d,_0xf92518,_0x5517e7));}if(_0x429690['pIgJG'](_0x24bb46[_0x21e510(0x526)],0x0)){const _0x109dfe=_0x429690[_0x21e510(0x1f9)](resolveAppPreset,_0x52ea43,_0x429690['KLkll']);console['log'](_0x21e510(0x8bf)+_0x24bb46[_0x21e510(0x2d0)](_0x4c93ff=>_0x4c93ff[_0x21e510(0x719)])[_0x21e510(0x5c8)](',\x20')),_0x5dc6ab[_0x21e510(0x823)](executeAndroidDevices(ANDROID_WIRELESS_SCRIPT_PATH,_0x24bb46,_0x109dfe,_0x5517e7));}if(_0x5dc6ab[_0x21e510(0x526)]===0x0)return _0x429690[_0x21e510(0x4b4)](_0x3cc176,{'success':![],'error':_0x429690[_0x21e510(0x488)]});try{const _0x3005b1=await Promise[_0x21e510(0x263)](_0x5dc6ab),_0x446d59=_0x3005b1['filter'](_0x229d54=>_0x229d54[_0x21e510(0x4d0)]===_0x21e510(0x713))[_0x21e510(0x526)],_0x3bf361=_0x3005b1[_0x21e510(0x3c2)](_0x9e73a2=>_0x9e73a2[_0x21e510(0x4d0)]===_0x21e510(0x850))[_0x21e510(0x526)];console[_0x21e510(0x61d)](_0x21e510(0x600)+_0x446d59+_0x21e510(0x626)+_0x3bf361+_0x21e510(0x54a));const _0x240b4a={};_0x240b4a[_0x21e510(0x859)]=!![],_0x240b4a['results']=_0x3005b1,_0x240b4a[_0x21e510(0x45f)]=_0x446d59+'/'+_0x5dc6ab[_0x21e510(0x526)]+_0x21e510(0x2d7),_0x429690['OAnYV'](_0x45b2fc,_0x240b4a);}catch(_0xf13005){console[_0x21e510(0x6c8)](_0x429690[_0x21e510(0x544)],_0xf13005),_0x429690[_0x21e510(0x4b4)](_0x3cc176,_0xf13005);}}});}function executeWithScript(_0x703874,_0xc9aab0,_0x450889,_0x204a33){const _0x543b67=_0x47c41d,_0x6dcb55={'UdZFn':function(_0x1ebf84,_0x39a107){return _0x1ebf84(_0x39a107);},'zOzto':function(_0x130ae5,_0x453a39){return _0x130ae5===_0x453a39;},'UljLw':'aIKem','LmrgD':function(_0x529ef2,_0x29f1dd){return _0x529ef2!==_0x29f1dd;},'trHgF':'rVTwp','ntEAV':_0x543b67(0x254),'Doslh':function(_0x149c43,_0x182cba,_0x5a2cea,_0x6a96da){return _0x149c43(_0x182cba,_0x5a2cea,_0x6a96da);},'FFCAF':_0x543b67(0x6c8),'NxuEK':function(_0xe4c352,_0x527afb){return _0xe4c352&&_0x527afb;},'uwnlq':function(_0x11898e,_0x451da9){return _0x11898e===_0x451da9;},'KnGcp':_0x543b67(0x29a),'CRqfk':'qSMhV'};return new Promise((_0x3e0e87,_0x23b534)=>{const _0x544497=_0x543b67,_0x5f2a14={'ysumQ':function(_0x32baca,_0x56cfc0){const _0x303bf1=_0x4c0b;return _0x6dcb55[_0x303bf1(0x7bc)](_0x32baca,_0x56cfc0);},'pnTic':_0x6dcb55[_0x544497(0x2fc)],'sVvMG':_0x544497(0x2c0),'ICjhW':function(_0x4a8a63,_0x32bee2){const _0x3c6c63=_0x544497;return _0x6dcb55[_0x3c6c63(0x6fe)](_0x4a8a63,_0x32bee2);},'RWifc':_0x6dcb55['trHgF'],'nfRGr':_0x6dcb55[_0x544497(0x447)],'jYJHA':function(_0xa69ca1,_0x353549,_0x410bac,_0x10ab01){const _0x1bdba5=_0x544497;return _0x6dcb55[_0x1bdba5(0x785)](_0xa69ca1,_0x353549,_0x410bac,_0x10ab01);},'ecjlH':'data','WeNYZ':_0x6dcb55[_0x544497(0x5f9)],'cXTHJ':function(_0x5e99f5,_0x2d7417){return _0x6dcb55['NxuEK'](_0x5e99f5,_0x2d7417);},'mIpGM':function(_0x177467,_0x5781d7){const _0x632341=_0x544497;return _0x6dcb55[_0x632341(0x7bc)](_0x177467,_0x5781d7);},'FvAWc':function(_0x3627b5,_0x3df7ab){const _0x290cdc=_0x544497;return _0x6dcb55[_0x290cdc(0x651)](_0x3627b5,_0x3df7ab);},'qSPra':_0x6dcb55[_0x544497(0x572)]};if(_0x544497(0x6b8)!==_0x6dcb55[_0x544497(0x4a6)]){console[_0x544497(0x61d)]('\x0a'+'='['repeat'](0x3c)),console['log']('Script:\x20'+path[_0x544497(0x249)](_0x703874)),console[_0x544497(0x61d)]('Devices:\x20['+_0xc9aab0[_0x544497(0x5c8)](',\x20')+']'),console[_0x544497(0x61d)](_0x544497(0x561)+_0x450889+'\x22'),console[_0x544497(0x61d)]('='[_0x544497(0x552)](0x3c)+'\x0a');const _0x44a872=_0xc9aab0[_0x544497(0x2d0)]((_0x5018de,_0x63aab1)=>{const _0x454202={'TujwB':function(_0x12b0ba,_0x57aa8c){const _0x3b5145=_0x4c0b;return _0x6dcb55[_0x3b5145(0x3e6)](_0x12b0ba,_0x57aa8c);}};return new Promise((_0x94f706,_0x383216)=>{const _0x1f3815=_0x4c0b,_0x3ee740={'rtjYv':function(_0x51c4f4,_0x3ee3a5){return _0x5f2a14['ysumQ'](_0x51c4f4,_0x3ee3a5);},'kXtxm':_0x5f2a14[_0x1f3815(0x3b1)],'hiYfy':_0x5f2a14['sVvMG'],'aIvBR':function(_0x3c425c,_0x5382af){const _0x564016=_0x1f3815;return _0x5f2a14[_0x564016(0x44e)](_0x3c425c,_0x5382af);},'AyBKm':_0x5f2a14[_0x1f3815(0x439)],'zKkPg':_0x5f2a14[_0x1f3815(0x4dc)],'HRlBz':function(_0x42bc6f,_0x47a235){const _0x3b0f2b=_0x1f3815;return _0x5f2a14[_0x3b0f2b(0x5b0)](_0x42bc6f,_0x47a235);},'ifNAp':function(_0x3f8d13,_0x52187f){return _0x3f8d13(_0x52187f);}},_0x8019c2=['-d',_0x5018de,_0x450889],_0x17ce99=_0x5f2a14[_0x1f3815(0x5cc)](spawn,_0x703874,_0x8019c2,{'cwd':path[_0x1f3815(0x727)](_0x703874)});let _0x48564e='',_0x3fdc12='';_0x17ce99[_0x1f3815(0x803)]['on'](_0x5f2a14['ecjlH'],_0x14fb57=>{const _0x286fc0=_0x1f3815;if(_0x3ee740[_0x286fc0(0x437)](_0x3ee740[_0x286fc0(0x3c4)],_0x3ee740[_0x286fc0(0x72a)])){_0x8ea6dd[_0x286fc0(0x6c8)](_0x286fc0(0x7bd)+_0x9aaa72+':',_0x3b3007);throw _0x2a78a7;}else{const _0x6e37be=_0x14fb57['toString']();_0x48564e+=_0x6e37be,console[_0x286fc0(0x61d)]('['+_0x5018de+_0x286fc0(0x60c)+_0x6e37be['trim']());if(_0x204a33){if(_0x3ee740[_0x286fc0(0x7a7)](_0x3ee740[_0x286fc0(0x338)],_0x286fc0(0x892))){const _0x3f410e={};_0x3f410e['type']=_0x3ee740['zKkPg'],_0x3f410e[_0x286fc0(0x1da)]='['+_0x5018de+']\x20'+_0x6e37be,_0x3f410e[_0x286fc0(0x658)]=[_0x5018de],_0x204a33[_0x286fc0(0x71d)](JSON[_0x286fc0(0x33e)](_0x3f410e));}else _0x5e1fb9[_0x286fc0(0x577)](_0x3e6cec,_0x1b5e1b,_0x2d68ae,_0x2bf1b5=>{const _0x3a2792=_0x286fc0;_0x3614ee[_0x3a2792(0x3ea)](_0x3a2792(0x42f),_0x2bf1b5,_0x2fdbe6);});}}}),_0x17ce99[_0x1f3815(0x3ec)]['on'](_0x5f2a14[_0x1f3815(0x261)],_0x4b9bdf=>{const _0x509431=_0x1f3815,_0x1e9f28=_0x4b9bdf['toString']();_0x3fdc12+=_0x1e9f28,console[_0x509431(0x6c8)]('['+_0x5018de+_0x509431(0x3e3)+_0x1e9f28[_0x509431(0x685)]());}),_0x17ce99['on'](_0x1f3815(0x884),_0x5ab9d0=>{const _0x371db9=_0x1f3815;if(_0x3ee740[_0x371db9(0x465)](_0x5ab9d0,0x0)){const _0x33b75c={};_0x33b75c[_0x371db9(0x859)]=!![],_0x33b75c[_0x371db9(0x88b)]=_0x48564e,_0x33b75c['device']=_0x5018de,_0x94f706(_0x33b75c);}else{const _0x48c8c8={};_0x48c8c8[_0x371db9(0x859)]=![],_0x48c8c8['error']=_0x3fdc12||'Script\x20exited\x20with\x20code\x20'+_0x5ab9d0,_0x48c8c8[_0x371db9(0x784)]=_0x5018de,_0x3ee740[_0x371db9(0x703)](_0x383216,_0x48c8c8);}}),_0x17ce99['on'](_0x5f2a14[_0x1f3815(0x285)],_0x2a4813=>{const _0x3ec800=_0x1f3815;console['error']('['+_0x5018de+']\x20Process\x20error:\x20'+_0x2a4813[_0x3ec800(0x6dc)]);const _0x226ff6={};_0x226ff6[_0x3ec800(0x859)]=![],_0x226ff6['error']=_0x2a4813[_0x3ec800(0x6dc)],_0x226ff6['device']=_0x5018de,_0x454202[_0x3ec800(0x2e5)](_0x383216,_0x226ff6);});});});Promise[_0x544497(0x263)](_0x44a872)[_0x544497(0x6bf)](_0x458763=>{const _0x39e5cd=_0x544497,_0x298544=_0x458763[_0x39e5cd(0x3c2)](_0x108500=>_0x108500[_0x39e5cd(0x4d0)]===_0x39e5cd(0x713))[_0x39e5cd(0x526)],_0x43b0d0=_0x458763[_0x39e5cd(0x3c2)](_0x540ad5=>_0x540ad5[_0x39e5cd(0x4d0)]===_0x39e5cd(0x850))[_0x39e5cd(0x526)];console[_0x39e5cd(0x61d)]('\x0a'+'='['repeat'](0x3c)),console[_0x39e5cd(0x61d)]('='[_0x39e5cd(0x552)](0x3c)+'\x0a');const _0x5ee5d4={};_0x5ee5d4[_0x39e5cd(0x859)]=!![],_0x5ee5d4[_0x39e5cd(0x239)]=_0x458763,_0x5ee5d4[_0x39e5cd(0x45f)]=_0x298544+'/'+_0xc9aab0[_0x39e5cd(0x526)]+'\x20devices\x20completed\x20successfully',_0x6dcb55[_0x39e5cd(0x3e6)](_0x3e0e87,_0x5ee5d4);})['catch'](_0x68765a=>{const _0x105fae=_0x544497;if(_0x5f2a14[_0x105fae(0x5d3)](_0x105fae(0x453),_0x5f2a14[_0x105fae(0x826)])){const [_0x34df0e,_0x58bf57]=_0x11c9df[_0x105fae(0x307)](',')[_0x105fae(0x2d0)](_0x44b929=>_0x44b929['trim']());if(BKxeJI['cXTHJ'](_0x34df0e,_0x58bf57)){const _0x390ce5=_0x34df0e[_0x105fae(0x307)]('.');if(BKxeJI[_0x105fae(0x2bf)](_0x390ce5[_0x105fae(0x526)],0x2)){const [_0x4b059a,_0x5a6dc6]=_0x390ce5;if(!_0x171fec[_0x4b059a])_0x4d6060[_0x4b059a]={};_0x463ce7[_0x4b059a][_0x5a6dc6]=_0x58bf57;}else{if(!_0x52e2a5[_0x34df0e])_0x2bac20[_0x34df0e]={};_0x40ea93[_0x34df0e][_0x105fae(0x474)]=_0x58bf57;}}}else console[_0x105fae(0x6c8)](_0x105fae(0x79c)+_0x68765a[_0x105fae(0x6dc)]),_0x23b534(_0x68765a);});}else return![];});}function executeAndroidDevices(_0x5f0b99,_0x4dbea3,_0x8b44af,_0x5a1f73){const _0x169837=_0x47c41d,_0x12172b={};_0x12172b[_0x169837(0x3d7)]=function(_0x3b9424,_0x561f65){return _0x3b9424!==_0x561f65;},_0x12172b[_0x169837(0x66e)]=_0x169837(0x7f7),_0x12172b[_0x169837(0x4db)]=_0x169837(0x2ee),_0x12172b['iOtzL']=function(_0x433d15,_0x42b706){return _0x433d15-_0x42b706;},_0x12172b[_0x169837(0x23a)]=function(_0x22ecfb,_0x1986a5){return _0x22ecfb===_0x1986a5;},_0x12172b[_0x169837(0x408)]='YWqPA',_0x12172b[_0x169837(0x653)]=_0x169837(0x5e5),_0x12172b['ZeGVz']=_0x169837(0x88b),_0x12172b[_0x169837(0x560)]=function(_0x500d4c,_0x28fc08){return _0x500d4c+_0x28fc08;},_0x12172b[_0x169837(0x3ef)]=_0x169837(0x34c),_0x12172b[_0x169837(0x5a2)]='Execution\x20error:';const _0x5bf8ea=_0x12172b;return new Promise((_0x340953,_0x142685)=>{const _0x3be5ba=_0x169837,_0x2066ba={'KximV':function(_0x4f1f2b,_0x471167){const _0x437019=_0x4c0b;return _0x5bf8ea[_0x437019(0x23a)](_0x4f1f2b,_0x471167);},'fOVDh':_0x5bf8ea[_0x3be5ba(0x408)],'YQdLc':_0x5bf8ea['WlRnI'],'kUHIY':function(_0x5ceaa9,_0x295872){return _0x5bf8ea['CiEqd'](_0x5ceaa9,_0x295872);},'kOCCf':_0x5bf8ea[_0x3be5ba(0x299)],'bndXC':function(_0x1c129f,_0x1dd06c){return _0x1c129f(_0x1dd06c);},'vSvZC':function(_0x43103a,_0x2f1c5c){return _0x43103a(_0x2f1c5c);},'JYqyP':_0x3be5ba(0x884),'ZQWsu':function(_0x1efc8e,_0x3b740c){const _0x2a5796=_0x3be5ba;return _0x5bf8ea[_0x2a5796(0x560)](_0x1efc8e,_0x3b740c);},'kzZwQ':_0x5bf8ea[_0x3be5ba(0x3ef)],'KTrnN':_0x5bf8ea[_0x3be5ba(0x5a2)]};console[_0x3be5ba(0x61d)]('\x0a'+'='['repeat'](0x3c)),console['log'](_0x3be5ba(0x4b1)+path[_0x3be5ba(0x249)](_0x5f0b99)),console[_0x3be5ba(0x61d)](_0x3be5ba(0x25e)+_0x4dbea3[_0x3be5ba(0x2d0)](_0x3e5b4e=>_0x3e5b4e[_0x3be5ba(0x719)])[_0x3be5ba(0x5c8)](',\x20')+']'),console[_0x3be5ba(0x61d)](_0x3be5ba(0x561)+_0x8b44af+'\x22'),console[_0x3be5ba(0x61d)]('='[_0x3be5ba(0x552)](0x3c)+'\x0a');const _0x2a57aa=_0x4dbea3['map']((_0x309bd4,_0x34c03c)=>{const _0x4da40=_0x3be5ba,_0x13fb78={'pboMb':function(_0x5a5236,_0x2df832){const _0x301c87=_0x4c0b;return _0x2066ba[_0x301c87(0x812)](_0x5a5236,_0x2df832);},'AjEAp':_0x2066ba[_0x4da40(0x621)],'Epdpo':_0x2066ba[_0x4da40(0x7f9)],'IkmZV':function(_0x4d6f60,_0x618aab){return _0x2066ba['kUHIY'](_0x4d6f60,_0x618aab);},'sXkqV':_0x2066ba[_0x4da40(0x25a)],'tGzxu':function(_0x169560,_0x5ac844){const _0x138d65=_0x4da40;return _0x2066ba[_0x138d65(0x812)](_0x169560,_0x5ac844);},'VztcM':function(_0x51a26c,_0x1aca68){const _0x47e58e=_0x4da40;return _0x2066ba[_0x47e58e(0x514)](_0x51a26c,_0x1aca68);},'MKtBW':function(_0x261b25,_0x8802c4,_0x4769c9){return _0x261b25(_0x8802c4,_0x4769c9);},'Miury':_0x4da40(0x705),'VKyFo':function(_0x1811bc,_0x5eed97){const _0xf9bd5e=_0x4da40;return _0x2066ba[_0xf9bd5e(0x2c1)](_0x1811bc,_0x5eed97);},'OKWpL':_0x2066ba[_0x4da40(0x24d)]};return console[_0x4da40(0x61d)]('['+_0x2066ba[_0x4da40(0x35f)](_0x34c03c,0x1)+'/'+_0x4dbea3[_0x4da40(0x526)]+_0x4da40(0x7a5)+_0x309bd4['name']+'\x20('+_0x309bd4[_0x4da40(0x200)]+')'),new Promise((_0x393019,_0x1428f9)=>{const _0x500ffe=_0x4da40,_0x7fe6c8={'PZZnK':function(_0x1f492f,_0x12a0fd,_0x233a5f){return _0x13fb78['MKtBW'](_0x1f492f,_0x12a0fd,_0x233a5f);},'bXgEy':_0x13fb78[_0x500ffe(0x4de)],'PGjwP':function(_0x4c5fe5,_0x4eee10,_0x1307b0,_0xbe24b9,_0x426b08){return _0x4c5fe5(_0x4eee10,_0x1307b0,_0xbe24b9,_0x426b08);},'izpVw':function(_0x3699a1,_0x10cfec){const _0x333a3b=_0x500ffe;return _0x13fb78[_0x333a3b(0x4ba)](_0x3699a1,_0x10cfec);}},_0x553c4f=[_0x309bd4[_0x500ffe(0x200)],..._0x8b44af[_0x500ffe(0x307)]('\x20')],_0x5cac82=spawn(_0x5f0b99,_0x553c4f,{'cwd':path[_0x500ffe(0x727)](_0x5f0b99)});let _0x53a3d0='',_0x348cfe='';_0x5cac82[_0x500ffe(0x803)]['on'](_0x500ffe(0x1da),_0x5b4870=>{const _0x3b7a46=_0x500ffe;if(_0x13fb78[_0x3b7a46(0x8a3)](_0x13fb78['AjEAp'],_0x13fb78[_0x3b7a46(0x869)])){const _0x848347=XOWGva[_0x3b7a46(0x6d8)](_0x177b78,_0x2423cf,XOWGva[_0x3b7a46(0x3cb)]);_0x1e12d3[_0x3b7a46(0x61d)](_0x3b7a46(0x8bf)+_0x1eaba8['map'](_0x3107c7=>_0x3107c7['name'])[_0x3b7a46(0x5c8)](',\x20')),_0x280fb6[_0x3b7a46(0x823)](XOWGva[_0x3b7a46(0x633)](_0x59a1cf,_0x5232cf,_0x5efa78,_0x848347,_0x16953d));}else{const _0xafdd4e=_0x5b4870[_0x3b7a46(0x7de)]();_0x53a3d0+=_0xafdd4e,console[_0x3b7a46(0x61d)]('['+_0x309bd4['name']+_0x3b7a46(0x60c)+_0xafdd4e[_0x3b7a46(0x685)]());if(_0x5a1f73){if(_0x13fb78['IkmZV'](_0x3b7a46(0x480),_0x3b7a46(0x89b))){const _0xe0a6bf={};_0xe0a6bf['type']=_0x13fb78['sXkqV'],_0xe0a6bf[_0x3b7a46(0x784)]=_0x309bd4[_0x3b7a46(0x719)],_0xe0a6bf[_0x3b7a46(0x1da)]=_0xafdd4e,_0x5a1f73[_0x3b7a46(0x71d)](JSON[_0x3b7a46(0x33e)](_0xe0a6bf));}else{if(!_0x52083b||!_0x299824)return![];return _0x53a28e['commands'][_0x3b7a46(0x823)]({'timestamp':new _0x28c73c()[_0x3b7a46(0x7f5)](),'devices':_0x5c1bf1,'originalCommand':_0xd8eba4,'useAI':_0xb846a7,'finalCommand':_0x342cca||_0xcb3231}),_0x35fd3b['log'](_0x3b7a46(0x40e)+_0x3a3583+'\x20('+_0x3645ce['commands'][_0x3b7a46(0x526)]+_0x3b7a46(0x3e7)),!![];}}}}),_0x5cac82[_0x500ffe(0x3ec)]['on'](_0x500ffe(0x1da),_0x2b1a60=>{const _0x4f7aa5=_0x500ffe,_0x4aa3c2=_0x2b1a60[_0x4f7aa5(0x7de)]();_0x348cfe+=_0x4aa3c2,console['log']('['+_0x309bd4[_0x4f7aa5(0x719)]+_0x4f7aa5(0x3e3)+_0x4aa3c2[_0x4f7aa5(0x685)]());}),_0x5cac82['on'](_0x13fb78[_0x500ffe(0x5eb)],_0x191b72=>{const _0x15382a=_0x500ffe;if(_0x13fb78['tGzxu'](_0x191b72,0x0)){const _0x48ebf4={};_0x48ebf4['success']=!![],_0x48ebf4[_0x15382a(0x88b)]=_0x53a3d0,_0x48ebf4['device']=_0x309bd4[_0x15382a(0x719)],_0x13fb78['VztcM'](_0x393019,_0x48ebf4);}else{const _0xdf8748={};_0xdf8748['success']=![],_0xdf8748['error']=_0x348cfe||_0x53a3d0,_0xdf8748[_0x15382a(0x784)]=_0x309bd4[_0x15382a(0x719)],_0x13fb78[_0x15382a(0x8ba)](_0x393019,_0xdf8748);}}),_0x5cac82['on'](_0x500ffe(0x6c8),_0x18e9f9=>{const _0x5dcd8b=_0x500ffe;console[_0x5dcd8b(0x6c8)]('['+_0x309bd4[_0x5dcd8b(0x719)]+_0x5dcd8b(0x6f8),_0x18e9f9);const _0x449a04={};_0x449a04[_0x5dcd8b(0x859)]=![],_0x449a04['error']=_0x18e9f9['message'],_0x449a04[_0x5dcd8b(0x784)]=_0x309bd4['name'],_0x7fe6c8['izpVw'](_0x393019,_0x449a04);});});});Promise[_0x3be5ba(0x263)](_0x2a57aa)[_0x3be5ba(0x6bf)](_0x596f7c=>{const _0x851b65=_0x3be5ba;if(_0x5bf8ea[_0x851b65(0x3d7)](_0x5bf8ea[_0x851b65(0x66e)],_0x5bf8ea[_0x851b65(0x4db)])){console[_0x851b65(0x61d)]('\x0a'+'='[_0x851b65(0x552)](0x3c));const _0x13e1ad=_0x596f7c[_0x851b65(0x3c2)](_0xaaabdd=>_0xaaabdd[_0x851b65(0x4d0)]==='fulfilled'&&_0xaaabdd[_0x851b65(0x4d6)]['success'])[_0x851b65(0x526)],_0x9d3c40=_0x5bf8ea[_0x851b65(0x426)](_0x596f7c[_0x851b65(0x526)],_0x13e1ad);console[_0x851b65(0x61d)]('='['repeat'](0x3c)+'\x0a');const _0x25b82c={};_0x25b82c[_0x851b65(0x859)]=!![],_0x25b82c[_0x851b65(0x239)]=_0x596f7c,_0x340953(_0x25b82c);}else{const _0x3c8535={};return _0x3c8535[_0x851b65(0x859)]=![],_0x3c8535[_0x851b65(0x6c8)]=_0x2066ba[_0x851b65(0x8a5)],_0x4c54c6[_0x851b65(0x4d0)](0x190)[_0x851b65(0x843)](_0x3c8535);}})['catch'](_0x518325=>{const _0x419988=_0x3be5ba;console[_0x419988(0x6c8)](_0x2066ba[_0x419988(0x802)],_0x518325),_0x142685(_0x518325);});});}async function convertNaturalLanguageToCommand(_0x51e691,_0x12e97a,_0xc939e9=null){const _0x5b0fc0=_0x47c41d,_0xaae856={};_0xaae856[_0x5b0fc0(0x3b5)]=function(_0x516545,_0x59a829){return _0x516545===_0x59a829;},_0xaae856[_0x5b0fc0(0x5b8)]=function(_0x38e6d9,_0x40f052){return _0x38e6d9===_0x40f052;},_0xaae856[_0x5b0fc0(0x697)]=_0x5b0fc0(0x58c),_0xaae856[_0x5b0fc0(0x75f)]=_0x5b0fc0(0x210),_0xaae856[_0x5b0fc0(0x5cf)]=function(_0xc5d0cf,_0x55dd7b){return _0xc5d0cf===_0x55dd7b;},_0xaae856[_0x5b0fc0(0x51e)]=_0x5b0fc0(0x4ff);const _0x2daadc=_0xaae856,_0x57433f=connectedDevices['filter'](_0x295744=>_0x12e97a[_0x5b0fc0(0x310)](_0x295744[_0x5b0fc0(0x719)]));if(_0x2daadc['zcIbQ'](_0x57433f[_0x5b0fc0(0x526)],0x0)){if(_0x2daadc['epZSf'](_0x2daadc['ljHbv'],_0x2daadc[_0x5b0fc0(0x75f)]))_0x2ccda9[_0x5b0fc0(0x61d)](_0x5b0fc0(0x64d)+_0x1d83a4[_0x5b0fc0(0x39b)]);else return await aiManager[_0x5b0fc0(0x21d)](_0x51e691,null,_0xc939e9);}const _0x1811ce=[...new Set(_0x57433f[_0x5b0fc0(0x2d0)](_0x4faf86=>_0x4faf86[_0x5b0fc0(0x581)]))];console['log'](_0x5b0fc0(0x4f7)+_0x57433f['length']+_0x5b0fc0(0x432)+_0x1811ce[_0x5b0fc0(0x526)]+_0x5b0fc0(0x2fe)+_0x1811ce['join'](',\x20'));const _0x24003d=_0x2daadc[_0x5b0fc0(0x5cf)](_0x1811ce[_0x5b0fc0(0x526)],0x1)?_0x1811ce[0x0]:_0x2daadc[_0x5b0fc0(0x51e)];return console['log']('AI\x20using\x20platform\x20mode:\x20'+_0x24003d),await aiManager[_0x5b0fc0(0x21d)](_0x51e691,_0x24003d,_0xc939e9);}async function executeCommandsSequentially(_0x50b664,_0x55bb71,_0x2504f6){const _0x26070b=_0x47c41d,_0x2b6504={'pZZwG':function(_0x2cee8f,_0x3c416b){return _0x2cee8f<_0x3c416b;},'YgDLX':_0x26070b(0x78d),'rkXFk':function(_0x2735c9,_0x36a6c1){return _0x2735c9!==_0x36a6c1;},'YyUhn':_0x26070b(0x234),'lVtNe':function(_0x12ecd1,_0x4d91fc){return _0x12ecd1(_0x4d91fc);},'jMjkr':function(_0x4487e5,_0xcb86b5){return _0x4487e5+_0xcb86b5;},'QdQgf':_0x26070b(0x254)},_0x1b6bb0=_0x55bb71[_0x26070b(0x307)]('\x0a')[_0x26070b(0x2d0)](_0x227287=>_0x227287[_0x26070b(0x685)]())[_0x26070b(0x3c2)](_0xba48a1=>_0xba48a1);console[_0x26070b(0x61d)]('\x0a'+'~'[_0x26070b(0x552)](0x3c)),console[_0x26070b(0x61d)](_0x26070b(0x394)+_0x1b6bb0['length']),console[_0x26070b(0x61d)](_0x26070b(0x4a2),_0x1b6bb0),console[_0x26070b(0x61d)]('~'['repeat'](0x3c)+'\x0a');const _0x3715f2=[];for(let _0x2758dd=0x0;_0x2b6504[_0x26070b(0x26c)](_0x2758dd,_0x1b6bb0[_0x26070b(0x526)]);_0x2758dd++){const _0x32bea5=_0x1b6bb0[_0x2758dd];if(_0x32bea5[_0x26070b(0x75e)]('#'))continue;if(_0x32bea5[_0x26070b(0x75e)](_0x2b6504[_0x26070b(0x846)])){if(_0x2b6504['rkXFk'](_0x2b6504['YyUhn'],_0x2b6504[_0x26070b(0x575)])){const _0x71f86e={};_0x71f86e[_0x26070b(0x859)]=![],_0x71f86e[_0x26070b(0x6c8)]=_0x58d14a[_0x26070b(0x6dc)],_0x1ccbd8[_0x26070b(0x4d0)](0x1f4)[_0x26070b(0x843)](_0x71f86e);}else{const _0x3a9ae3=_0x2b6504[_0x26070b(0x429)](parseInt,_0x32bea5['replace'](_0x26070b(0x78d),''));console[_0x26070b(0x61d)](_0x26070b(0x1e7)+_0x3a9ae3+'ms\x20before\x20next\x20command...');if(_0x2504f6){const _0x1db6e5={};_0x1db6e5[_0x26070b(0x4b8)]=_0x26070b(0x254),_0x1db6e5[_0x26070b(0x1da)]=_0x26070b(0x1e7)+_0x3a9ae3+_0x26070b(0x50b),_0x1db6e5['devices']=_0x50b664,_0x2504f6['send'](JSON[_0x26070b(0x33e)](_0x1db6e5));}await new Promise(_0x3657ba=>setTimeout(_0x3657ba,_0x3a9ae3));const _0x3c842a={};_0x3c842a['command']=_0x32bea5,_0x3c842a[_0x26070b(0x859)]=!![],_0x3c842a[_0x26070b(0x88b)]=_0x26070b(0x325)+_0x3a9ae3+'ms',_0x3715f2[_0x26070b(0x823)](_0x3c842a);continue;}}console[_0x26070b(0x61d)](_0x26070b(0x85c)+_0x2b6504[_0x26070b(0x76c)](_0x2758dd,0x1)+'/'+_0x1b6bb0['length']+_0x26070b(0x2b4)+_0x32bea5+'\x22');_0x2504f6&&_0x2504f6[_0x26070b(0x71d)](JSON['stringify']({'type':_0x2b6504['QdQgf'],'data':_0x26070b(0x796)+_0x2b6504['jMjkr'](_0x2758dd,0x1)+'/'+_0x1b6bb0[_0x26070b(0x526)]+']\x20'+_0x32bea5+'\x0a','devices':_0x50b664}));try{const _0x2776f2=await executeCommand(_0x50b664,_0x32bea5,_0x2504f6),_0xb0d9fb={};_0xb0d9fb[_0x26070b(0x582)]=_0x32bea5,_0xb0d9fb[_0x26070b(0x859)]=!![],_0xb0d9fb[_0x26070b(0x5fa)]=_0x2776f2,_0x3715f2[_0x26070b(0x823)](_0xb0d9fb),console[_0x26070b(0x61d)](_0x26070b(0x70e)+_0x2b6504[_0x26070b(0x76c)](_0x2758dd,0x1)+'\x20completed\x20successfully');}catch(_0x54fdc8){console[_0x26070b(0x6c8)]('ā\x20Command\x20'+(_0x2758dd+0x1)+_0x26070b(0x59d),_0x54fdc8[_0x26070b(0x6dc)]);const _0x2cf380={};_0x2cf380[_0x26070b(0x582)]=_0x32bea5,_0x2cf380[_0x26070b(0x859)]=![],_0x2cf380[_0x26070b(0x6c8)]=_0x54fdc8['message'],_0x3715f2['push'](_0x2cf380);if(_0x2504f6){const _0x3c0018={};_0x3c0018[_0x26070b(0x4b8)]=_0x2b6504[_0x26070b(0x61f)],_0x3c0018[_0x26070b(0x1da)]=_0x26070b(0x493)+_0x54fdc8['message']+'\x0a',_0x3c0018[_0x26070b(0x658)]=_0x50b664,_0x2504f6['send'](JSON['stringify'](_0x3c0018));}}}console[_0x26070b(0x61d)]('\x0a'+'~'['repeat'](0x3c)),console[_0x26070b(0x61d)](_0x26070b(0x79a)+_0x3715f2[_0x26070b(0x526)]+_0x26070b(0x614)+_0x3715f2[_0x26070b(0x3c2)](_0x3e1f2c=>_0x3e1f2c[_0x26070b(0x859)])['length']+_0x26070b(0x729)+_0x3715f2[_0x26070b(0x3c2)](_0x70828=>!_0x70828[_0x26070b(0x859)])[_0x26070b(0x526)]),console[_0x26070b(0x61d)]('~'['repeat'](0x3c)+'\x0a');const _0x358799={};return _0x358799[_0x26070b(0x859)]=!![],_0x358799[_0x26070b(0x239)]=_0x3715f2,_0x358799['summary']=_0x26070b(0x46e)+_0x3715f2[_0x26070b(0x526)]+_0x26070b(0x81c),_0x358799;}async function createWDASession(_0x3bf2d5,_0x413217){const _0x5af39c=_0x47c41d,_0x134154={'uURee':function(_0x4ed231,_0x456157){return _0x4ed231===_0x456157;},'lIToN':function(_0xc92a7,_0xafe07e){return _0xc92a7(_0xafe07e);},'wCOyO':_0x5af39c(0x413),'fTjaX':function(_0x4b1c08,_0x1155a2){return _0x4b1c08(_0x1155a2);},'RxAhK':function(_0x31235e,_0x584645,_0x5227e7,_0x343bd7,_0x3f1e50){return _0x31235e(_0x584645,_0x5227e7,_0x343bd7,_0x3f1e50);},'KXeaO':'/tmp/ios_multi_sessions','zYQjg':_0x5af39c(0x507),'ezUEP':'utf-8','vwQme':function(_0x9244a6,_0x213349){return _0x9244a6===_0x213349;},'ErZoK':_0x5af39c(0x49a),'QsBJy':function(_0x2d910b,_0xda096b){return _0x2d910b===_0xda096b;},'ZLEYd':function(_0x5c5a81,_0x319e69){return _0x5c5a81===_0x319e69;},'McGmm':'localhost','yEEeM':function(_0x56cd04,_0x40f8aa,_0x393add){return _0x56cd04(_0x40f8aa,_0x393add);},'KeFWJ':_0x5af39c(0x48f),'uQmxV':_0x5af39c(0x845),'IEyke':_0x5af39c(0x884)};return new Promise(async _0x10fadd=>{const _0x512f95=_0x5af39c,_0x7531ec=_0x134154[_0x512f95(0x37e)];try{if(_0x134154['zYQjg']!==_0x512f95(0x507)){const _0x17de3b=_0x4e221f[_0x11d576];let _0x22d6fd;if(_0x17de3b[_0x524c9b])_0x22d6fd=_0x17de3b[_0x26b5f4];else _0x17de3b[_0x512f95(0x474)]&&(_0x22d6fd=_0x17de3b[_0x512f95(0x474)]);if(_0x22d6fd)return _0x2789f8[_0x512f95(0x61d)]('\x20\x20š±\x20Resolved\x20app\x20preset:\x20\x22'+_0x414696+_0x512f95(0x88c)+_0x22d6fd+_0x512f95(0x839)+_0x5f1508+')'),_0x512f95(0x671)+_0x22d6fd+_0x2847ca;}else{const _0x9fc5c6=await fs['readFile'](_0x7531ec,_0x134154[_0x512f95(0x6c6)])[_0x512f95(0x795)](()=>''),_0x3f61bc=_0x9fc5c6[_0x512f95(0x307)]('\x0a')[_0x512f95(0x3c2)](_0x5de433=>_0x5de433[_0x512f95(0x685)]());for(const _0x30857a of _0x3f61bc){if(_0x134154[_0x512f95(0x763)](_0x512f95(0x746),_0x134154['ErZoK'])){if(xNtdhL[_0x512f95(0x4ed)](_0x58faf0,0x0)){const _0x3e4a1e={};_0x3e4a1e[_0x512f95(0x859)]=!![],_0x3e4a1e[_0x512f95(0x88b)]=_0x1317b4,_0x3e4a1e[_0x512f95(0x784)]=_0x2d16bf,_0xf63c8f(_0x3e4a1e);}else{const _0xf2d634={};_0xf2d634['success']=![],_0xf2d634['error']=_0x35f772||_0x512f95(0x744)+_0x3710e1,_0xf2d634['device']=_0x25e40e,xNtdhL[_0x512f95(0x383)](_0x24fb7f,_0xf2d634);}}else{const [_0x1843bf,_0xdfc645]=_0x30857a[_0x512f95(0x307)](':');if(_0x134154[_0x512f95(0x6d0)](_0x1843bf,_0x413217)&&_0xdfc645){const _0x2f091a=_0x134154[_0x512f95(0x640)](_0x3bf2d5,_0x134154['McGmm'])?0x1fa4:0x1fa4,_0x2e8e41=_0x512f95(0x81b)+_0x3bf2d5+':'+_0x2f091a+_0x512f95(0x7c2)+_0xdfc645,_0x595f63=_0x134154[_0x512f95(0x2e7)](spawn,_0x134154[_0x512f95(0x475)],['-s','-X',_0x134154[_0x512f95(0x265)],_0x2e8e41]);let _0x22ae50='';_0x595f63['stdout']['on'](_0x512f95(0x1da),_0x145b69=>{_0x22ae50+=_0x145b69['toString']();}),_0x595f63['on'](_0x134154[_0x512f95(0x620)],_0xfe0863=>{const _0x4ffe7d=_0x512f95;if(_0xfe0863===0x0&&_0x22ae50&&!_0x22ae50['includes'](_0x134154[_0x4ffe7d(0x694)])){console[_0x4ffe7d(0x61d)](_0x4ffe7d(0x597)+_0xdfc645);const _0x282fe0={};return _0x282fe0[_0x4ffe7d(0x859)]=!![],_0x282fe0['sessionId']=_0xdfc645,_0x282fe0[_0x4ffe7d(0x25b)]=!![],_0x134154['fTjaX'](_0x10fadd,_0x282fe0);}else _0x134154[_0x4ffe7d(0x2a6)](createNewSession,_0x3bf2d5,_0x413217,_0x7531ec,_0x10fadd);});return;}}}}}catch(_0x3dc3c0){}createNewSession(_0x3bf2d5,_0x413217,_0x7531ec,_0x10fadd);});}function createNewSession(_0x32b274,_0x5e5b98,_0x1a4103,_0x5f2ce7){const _0x46448f=_0x47c41d,_0x58a703={'tPutn':_0x46448f(0x4ec),'pJmOm':function(_0x57a88a,_0x1fd450){return _0x57a88a===_0x1fd450;},'pbHzL':_0x46448f(0x242),'xUMAO':function(_0x180147,_0x23efbf){return _0x180147+_0x23efbf;},'lnAlH':_0x46448f(0x86b),'TneiJ':function(_0x36c727,_0x53871c){return _0x36c727(_0x53871c);},'vAYLP':function(_0x4a2bfc,_0x28ff59){return _0x4a2bfc(_0x28ff59);},'qQuYs':_0x46448f(0x5fe),'eAtwn':function(_0x53d122,_0x111fd7){return _0x53d122!==_0x111fd7;},'pEllk':'uVOae','uTGhH':_0x46448f(0x371),'xyqBk':_0x46448f(0x515),'ALkAF':'rJWrl','hgnYE':function(_0xd0ca63,_0x5bfc0c){return _0xd0ca63!==_0x5bfc0c;},'HzsyD':'ENDpf','NOSln':function(_0x37786d,_0x1ad42b){return _0x37786d!==_0x1ad42b;},'CMifC':_0x46448f(0x4a7),'ophaQ':'Failed\x20to\x20parse\x20WDA\x20session\x20response:','vDqTO':function(_0x475d55,_0x376b7b){return _0x475d55(_0x376b7b);},'VuxSR':_0x46448f(0x797),'xHBmg':function(_0x16055f,_0x361e89){return _0x16055f(_0x361e89);},'AMbWn':function(_0x485f5c,_0x27c18d,_0x1f29ca){return _0x485f5c(_0x27c18d,_0x1f29ca);},'RiFVE':_0x46448f(0x48f),'GzZfp':_0x46448f(0x528),'HxoOW':_0x46448f(0x753),'zQHJh':'error'},_0x71f586=_0x32b274==='localhost'?0x1fa4:0x1fa4,_0x312bd1=_0x46448f(0x81b)+_0x32b274+':'+_0x71f586+_0x46448f(0x40f),_0x1759ab=_0x58a703[_0x46448f(0x6c7)](spawn,_0x58a703[_0x46448f(0x63d)],['-s','-X',_0x58a703['GzZfp'],_0x312bd1,'-H',_0x46448f(0x42b),'-d',_0x58a703[_0x46448f(0x37a)]]);let _0x227662='';_0x1759ab[_0x46448f(0x803)]['on'](_0x46448f(0x1da),_0x47d133=>{_0x227662+=_0x47d133['toString']();}),_0x1759ab['on'](_0x46448f(0x884),_0x30e402=>{const _0x4c370f=_0x46448f,_0x13854d={'oWbWd':function(_0x4067d0,_0x4015c0){const _0x42e1b6=_0x4c0b;return _0x58a703[_0x42e1b6(0x7fa)](_0x4067d0,_0x4015c0);},'afrWQ':'\x22state\x22','aFeJn':function(_0x54df80,_0x6925dc,_0x24bc7f){return _0x54df80(_0x6925dc,_0x24bc7f);},'jrxcU':_0x4c370f(0x884),'WGsAy':_0x4c370f(0x342),'KfVxd':function(_0x585062,_0x5dccd6){return _0x585062(_0x5dccd6);},'GKBCP':_0x58a703[_0x4c370f(0x51d)],'cGmVj':_0x4c370f(0x2cd),'FLfnr':_0x4c370f(0x428)};if(_0x58a703[_0x4c370f(0x751)](_0x58a703[_0x4c370f(0x3fe)],_0x58a703['uTGhH'])){if(_0x58a703[_0x4c370f(0x211)](_0x30e402,0x0)&&_0x227662)try{if(_0x58a703[_0x4c370f(0x642)]===_0x58a703[_0x4c370f(0x761)])_0x41d7ae=_0x26df23[_0x22101d];else{const _0x12f4f5=JSON[_0x4c370f(0x1f8)](_0x227662),_0xc2675=_0x12f4f5['sessionId']||_0x12f4f5[_0x4c370f(0x4d6)]?.[_0x4c370f(0x39b)];if(_0xc2675)_0x58a703['hgnYE'](_0x58a703[_0x4c370f(0x6fd)],_0x58a703['HzsyD'])?khiELQ[_0x4c370f(0x26b)](_0x5cfb0b,_0x439c23['includes'](khiELQ['afrWQ'])):fs[_0x4c370f(0x7fe)](_0x1a4103,_0x4c370f(0x377))[_0x4c370f(0x795)](()=>'')['then'](_0x29fb75=>{const _0x3d4ece=_0x4c370f,_0x29fce0={};_0x29fce0['ZedEi']=_0x58a703[_0x3d4ece(0x33b)],_0x29fce0[_0x3d4ece(0x7fd)]=_0x3d4ece(0x835),_0x29fce0[_0x3d4ece(0x6e5)]=function(_0x4d5021,_0x4db341){return _0x4d5021!==_0x4db341;};const _0x34ecf7=_0x29fce0;if(_0x58a703[_0x3d4ece(0x211)](_0x58a703['pbHzL'],_0x58a703['pbHzL'])){const _0x4837e9=_0x29fb75[_0x3d4ece(0x307)]('\x0a')[_0x3d4ece(0x3c2)](_0x5d891f=>{const _0x448f51=_0x3d4ece;if(_0x34ecf7[_0x448f51(0x235)]===_0x34ecf7[_0x448f51(0x7fd)])_0x558495[_0x448f51(0x61d)]('ā ļø\x20\x20Session\x20creation\x20failed,\x20will\x20be\x20created\x20on\x20first\x20command');else{const [_0x4b4536]=_0x5d891f['split'](':');return _0x5d891f['trim']()&&_0x34ecf7[_0x448f51(0x6e5)](_0x4b4536,_0x5e5b98);}});return _0x4837e9[_0x3d4ece(0x823)](_0x5e5b98+':'+_0xc2675),fs['writeFile'](_0x1a4103,_0x58a703[_0x3d4ece(0x7dc)](_0x4837e9[_0x3d4ece(0x5c8)]('\x0a'),'\x0a'));}else{const _0xecacf6={};_0xecacf6[_0x3d4ece(0x859)]=![],_0xecacf6[_0x3d4ece(0x6c8)]=_0x4d72e6['message'],_0x1b4368[_0x3d4ece(0x4d0)](0x1f4)['json'](_0xecacf6);}})['then'](()=>{const _0x56ca5b=_0x4c370f,_0xa92b72={'cnCty':function(_0x5e6704,_0x58fe6d,_0x5428be){const _0x211278=_0x4c0b;return _0x13854d[_0x211278(0x47b)](_0x5e6704,_0x58fe6d,_0x5428be);},'NcjBh':_0x13854d[_0x56ca5b(0x83b)]};if('zFBzg'===_0x13854d[_0x56ca5b(0x297)]){_0x3f0d2b['log'](_0x56ca5b(0x611)+_0x1c335b+_0x56ca5b(0x298)+_0x590175+_0x56ca5b(0x8cb));const _0x17cfa9=_0xa92b72[_0x56ca5b(0x32e)](_0x4d6aef,'sh',['-c',_0x56ca5b(0x4e8)+_0x4356d2+_0x56ca5b(0x2c7)]);_0x17cfa9['on'](_0xa92b72[_0x56ca5b(0x84f)],()=>{const _0x3ad64b=_0x56ca5b;_0x3ee385['log'](_0x3ad64b(0x6b0)+_0x23b755+'\x20for\x20'+_0x192dcb);});}else{console[_0x56ca5b(0x61d)](_0x56ca5b(0x88f)+_0xc2675);const _0x2a095f={};_0x2a095f['success']=!![],_0x2a095f['sessionId']=_0xc2675,_0x13854d[_0x56ca5b(0x554)](_0x5f2ce7,_0x2a095f);}})[_0x4c370f(0x795)](_0x5dc4eb=>{const _0x1bfc2e=_0x4c370f;if(_0x58a703[_0x1bfc2e(0x211)](_0x58a703[_0x1bfc2e(0x50d)],_0x58a703[_0x1bfc2e(0x50d)])){console['error'](_0x1bfc2e(0x88a)+_0x5e5b98+':',_0x5dc4eb);const _0x204bf5={};_0x204bf5[_0x1bfc2e(0x859)]=![],_0x58a703[_0x1bfc2e(0x46f)](_0x5f2ce7,_0x204bf5);}else return _0x5ceec0;});else{if(_0x58a703[_0x4c370f(0x6c1)](_0x58a703['CMifC'],_0x58a703[_0x4c370f(0x2ac)]))_0x2626ea+='OPENAI_API_KEY='+_0x8acf6c+'\x0a';else{const _0x34ed74={};_0x34ed74[_0x4c370f(0x859)]=![],_0x58a703[_0x4c370f(0x46f)](_0x5f2ce7,_0x34ed74);}}}}catch(_0x4fe180){console['error'](_0x58a703[_0x4c370f(0x7e2)],_0x4fe180);const _0x5ef656={};_0x5ef656[_0x4c370f(0x859)]=![],_0x58a703[_0x4c370f(0x791)](_0x5f2ce7,_0x5ef656);}else{if(_0x58a703[_0x4c370f(0x211)](_0x58a703[_0x4c370f(0x4a0)],_0x4c370f(0x764)))_0x219e53[_0x4c370f(0x61d)](_0x4c370f(0x6b0)+_0x355e5b+_0x4c370f(0x298)+_0x498627);else{const _0x4a3881={};_0x4a3881['success']=![],_0x58a703[_0x4c370f(0x1e2)](_0x5f2ce7,_0x4a3881);}}}else{_0x50a64c['log'](_0x13854d['GKBCP']),_0x199458['log'](_0x13854d[_0x4c370f(0x4ab)],_0x3ad080[_0x4c370f(0x33e)](_0x20af72,null,0x2));const _0x2fc6f8={};return _0x2fc6f8[_0x4c370f(0x859)]=![],_0x2fc6f8['error']=_0x13854d[_0x4c370f(0x531)],_0x1b46f2[_0x4c370f(0x4d0)](0x1f4)[_0x4c370f(0x843)](_0x2fc6f8);}}),_0x1759ab['on'](_0x58a703[_0x46448f(0x4bd)],_0x5df225=>{const _0x396736=_0x46448f;console[_0x396736(0x6c8)](_0x396736(0x4e2),_0x5df225);const _0x409208={};_0x409208[_0x396736(0x859)]=![],_0x5f2ce7(_0x409208);});}async function installUIAutomator2(_0x1053e7,_0x3c228e){const _0x36c40c=_0x47c41d,_0x4f636a={'KNIMg':_0x36c40c(0x83f),'wDEEv':function(_0x62679e,_0x35839d){return _0x62679e(_0x35839d);},'KxjYS':_0x36c40c(0x41c),'yTmLz':function(_0x522a48,_0x9a8bd6){return _0x522a48(_0x9a8bd6);},'lYkId':_0x36c40c(0x793),'vTejI':_0x36c40c(0x29c),'FARym':_0x36c40c(0x412),'lzHYN':function(_0x19e176,_0x195dd8){return _0x19e176+_0x195dd8;},'TRkbN':function(_0x14bf75,_0x248ab0,_0x2e2d35){return _0x14bf75(_0x248ab0,_0x2e2d35);},'Gczpu':_0x36c40c(0x574),'Zrphr':'/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks','GdkUa':function(_0x3a57e6,_0x1808ab){return _0x3a57e6+_0x1808ab;},'snfZS':_0x36c40c(0x377),'wEnVy':_0x36c40c(0x49e),'okXAL':function(_0x1d6b47,_0x2ebd0c){return _0x1d6b47!==_0x2ebd0c;},'GQoXE':'gauSb','efkkE':function(_0x1e3eba,_0x59ce26){return _0x1e3eba&&_0x59ce26;},'HdQmy':'zYwFw','MPvuu':function(_0x46f0c5,_0x416595){return _0x46f0c5!==_0x416595;},'EmPxc':_0x36c40c(0x76d),'iwfNo':function(_0x7ff317,_0x5652eb){return _0x7ff317(_0x5652eb);},'VtdNY':_0x36c40c(0x7dd)};return new Promise(_0x146585=>{const _0x44eb30=_0x36c40c,_0x2ce1ce={};_0x2ce1ce['Vkjbr']=_0x4f636a[_0x44eb30(0x260)];const _0x5cd6ff=_0x2ce1ce;console[_0x44eb30(0x61d)](_0x44eb30(0x4d4)+_0x3c228e+_0x44eb30(0x8cb));const {execSync:_0xd79e38}=_0x4f636a[_0x44eb30(0x3e2)](require,_0x4f636a[_0x44eb30(0x35e)]),_0x4161a3=_0x4f636a[_0x44eb30(0x3e2)](require,'os'),_0x233eaf=_0x4f636a[_0x44eb30(0x6cc)](require,_0x4f636a[_0x44eb30(0x7e0)]);try{const _0x7f9dbc={};_0x7f9dbc[_0x44eb30(0x76b)]='utf-8';const _0x39b66f=[_0x233eaf['join'](_0x4161a3[_0x44eb30(0x467)](),_0x44eb30(0x27c),_0x44eb30(0x86e),_0x4f636a[_0x44eb30(0x7b0)],_0x44eb30(0x86e),_0x4f636a['FARym'],'apks'),_0x4f636a['lzHYN'](_0x4f636a['TRkbN'](_0xd79e38,_0x4f636a[_0x44eb30(0x714)],_0x7f9dbc)['trim'](),_0x4f636a['Zrphr']),_0x4f636a['GdkUa'](_0xd79e38(_0x4f636a['Gczpu'],{'encoding':_0x4f636a['snfZS']})[_0x44eb30(0x685)](),_0x4f636a[_0x44eb30(0x6a2)])];let _0x228e8b=null,_0x38f279=null,_0x478e04=null;for(const _0x217669 of _0x39b66f){if(_0x4f636a['okXAL'](_0x4f636a[_0x44eb30(0x450)],_0x44eb30(0x2be))){console[_0x44eb30(0x61d)](_0x44eb30(0x77c)+_0x217669);try{const _0x2a1863=_0x4f636a[_0x44eb30(0x525)](_0xd79e38,_0x44eb30(0x3eb)+_0x217669+_0x44eb30(0x53f),{'encoding':_0x4f636a['snfZS']})['trim'](),_0x409597={};_0x409597['encoding']=_0x4f636a[_0x44eb30(0x5a4)];const _0x3a0df0=_0xd79e38(_0x44eb30(0x3eb)+_0x217669+_0x44eb30(0x84e),_0x409597)[_0x44eb30(0x685)]();if(_0x4f636a[_0x44eb30(0x349)](_0x2a1863,_0x3a0df0)){if(_0x4f636a[_0x44eb30(0x1de)](_0x44eb30(0x3ed),_0x4f636a['HdQmy'])){_0x228e8b=_0x2a1863,_0x38f279=_0x3a0df0,_0x478e04=_0x217669,console[_0x44eb30(0x61d)]('ā
\x20Found\x20APKs\x20in:\x20'+_0x478e04);break;}else _0x5f00a3[_0x44eb30(0x61d)](_0x44eb30(0x1f5)+_0xe5cca7),_0x4571f1[_0x44eb30(0x27e)](_0x1d68a0+':5555');}}catch(_0x2a2466){if(_0x4f636a[_0x44eb30(0x205)](_0x44eb30(0x76d),_0x4f636a['EmPxc']))_0xc07e67[_0x44eb30(0x510)](_0x363e36[_0x44eb30(0x7d3)],_0x5cd6ff[_0x44eb30(0x3db)]),_0x52871f[_0x44eb30(0x61d)](_0x44eb30(0x7ce)+_0x4e07ac+_0x44eb30(0x441)+_0x225bdd[_0x44eb30(0x7d3)]+')');else continue;}}else{if(_0x22ca2c[_0x44eb30(0x24e)]===_0x279e9e[_0x44eb30(0x3ba)]){const _0x172f0e={};_0x172f0e[_0x44eb30(0x4b8)]='devices_updated',_0x172f0e[_0x44eb30(0x658)]=_0xf13a18,_0x510e2d[_0x44eb30(0x71d)](_0x4d9914[_0x44eb30(0x33e)](_0x172f0e));}}}if(_0x4f636a[_0x44eb30(0x349)](_0x228e8b,_0x38f279)){console[_0x44eb30(0x61d)](_0x44eb30(0x58e)+_0x228e8b);const _0x55a2da=_0x4f636a['TRkbN'](_0xd79e38,_0x44eb30(0x2b1)+_0x1053e7+_0x44eb30(0x675)+_0x228e8b+_0x44eb30(0x83a),{'encoding':_0x4f636a[_0x44eb30(0x5a4)]});console['log'](_0x55a2da),console[_0x44eb30(0x61d)](_0x44eb30(0x2a3)+_0x38f279);const _0x2e0b3f={};_0x2e0b3f['encoding']=_0x44eb30(0x377);const _0x435740=_0xd79e38(_0x44eb30(0x2b1)+_0x1053e7+_0x44eb30(0x675)+_0x38f279+_0x44eb30(0x83a),_0x2e0b3f);console[_0x44eb30(0x61d)](_0x435740),console['log'](_0x44eb30(0x858)+_0x3c228e);const _0x3d3880={};_0x3d3880[_0x44eb30(0x859)]=!![],_0x3d3880['message']='UIAutomator2\x20installed\x20successfully',_0x4f636a['iwfNo'](_0x146585,_0x3d3880);}else{console['log'](_0x44eb30(0x5d6)),console[_0x44eb30(0x61d)](_0x44eb30(0x2bd),_0x39b66f);try{if(_0x4f636a[_0x44eb30(0x897)]!==_0x4f636a[_0x44eb30(0x897)]){const _0x18dc7a={};_0x18dc7a[_0x44eb30(0x859)]=![],_0x18dc7a['error']=_0x31a8e2[_0x44eb30(0x6dc)],_0x59daae['status'](0x1f4)[_0x44eb30(0x843)](_0x18dc7a);}else{console[_0x44eb30(0x61d)](_0x44eb30(0x654));const _0x4c3f1c=_0x4f636a[_0x44eb30(0x525)](_0xd79e38,'appium\x20driver\x20install\x20uiautomator2\x202>&1',{'encoding':_0x4f636a[_0x44eb30(0x5a4)]});console[_0x44eb30(0x61d)](_0x4c3f1c);const _0x5f28bc={};_0x5f28bc[_0x44eb30(0x859)]=![],_0x5f28bc[_0x44eb30(0x6dc)]=_0x44eb30(0x886),_0x4f636a[_0x44eb30(0x6cc)](_0x146585,_0x5f28bc);}}catch(_0x41c0ea){const _0x5a131c={};_0x5a131c['success']=![],_0x5a131c[_0x44eb30(0x6dc)]='UIAutomator2\x20APKs\x20not\x20found.\x20Please\x20run:\x20appium\x20driver\x20install\x20uiautomator2',_0x4f636a[_0x44eb30(0x329)](_0x146585,_0x5a131c);}}}catch(_0x2649ed){console[_0x44eb30(0x6c8)](_0x44eb30(0x1d9)+_0x2649ed[_0x44eb30(0x6dc)]);const _0x3aa496={};_0x3aa496['success']=![],_0x3aa496[_0x44eb30(0x6dc)]='Failed\x20to\x20install\x20UIAutomator2:\x20'+_0x2649ed[_0x44eb30(0x6dc)],_0x4f636a[_0x44eb30(0x6cc)](_0x146585,_0x3aa496);}});}async function connectToDevice(_0x911b5c){const _0x1942f3=_0x47c41d,_0x51bca1={'KWGpI':'devices_updated','IkYKm':function(_0x3e971b,_0x536af0,_0xf397f){return _0x3e971b(_0x536af0,_0xf397f);},'JDSLf':_0x1942f3(0x83f),'ywxIm':function(_0x5e04d2,_0x220172,_0x194e7d,_0x574cd5,_0x23d07b){return _0x5e04d2(_0x220172,_0x194e7d,_0x574cd5,_0x23d07b);},'oXuCG':_0x1942f3(0x4cc),'YFLTp':_0x1942f3(0x5e4),'aupzU':_0x1942f3(0x458),'XkjgH':_0x1942f3(0x2f6),'rfaAA':function(_0x1dbd18,_0x527923){return _0x1dbd18(_0x527923);},'qmsiN':_0x1942f3(0x65f),'rfwLf':_0x1942f3(0x282),'iDDjJ':'localhost','rBAWc':function(_0xa534d4,_0x4de315){return _0xa534d4!==_0x4de315;},'YtdPC':_0x1942f3(0x6b6),'CmGOy':_0x1942f3(0x29b),'qxpUN':function(_0x2818c6,_0x432fc1){return _0x2818c6===_0x432fc1;},'PsiEq':_0x1942f3(0x47c),'YzDgd':_0x1942f3(0x5a5),'ZIlKk':function(_0x172a86,_0x552843,_0x1234f3){return _0x172a86(_0x552843,_0x1234f3);},'dhBIG':_0x1942f3(0x7d9),'fcGPn':function(_0x3e1976,_0x5eb95e){return _0x3e1976!==_0x5eb95e;},'jIeXY':_0x1942f3(0x768),'ovUgF':function(_0xfedf38,_0x1915a0){return _0xfedf38===_0x1915a0;},'WVoFB':'vkZKn','SnZys':_0x1942f3(0x60d),'QxrIb':_0x1942f3(0x31b),'YKMLC':'Downloads/WebDriverAgent-10.2.1','ilgiA':'xcodebuild','mTGUY':_0x1942f3(0x270),'OKTrz':_0x1942f3(0x436),'sCkdR':_0x1942f3(0x2ea),'ZmYuw':_0x1942f3(0x46b),'XOODJ':_0x1942f3(0x6ea),'mnrpe':_0x1942f3(0x6ef),'UAcJv':_0x1942f3(0x85b),'MixuU':_0x1942f3(0x41a),'MIyiD':_0x1942f3(0x6f6),'sGssN':_0x1942f3(0x1da),'GLHkA':_0x1942f3(0x6c8),'ypjBd':function(_0x52b149,_0xb5416b,_0x21d325,_0x808b1a){return _0x52b149(_0xb5416b,_0x21d325,_0x808b1a);},'WZRNX':'iproxy','EVjnE':'8100','mcAyJ':function(_0xe07243,_0x4d6abb){return _0xe07243(_0x4d6abb);},'uDsMs':function(_0x2da1a4,_0x143960){return _0x2da1a4===_0x143960;},'vbJxD':'jXzrl','JXcZi':_0x1942f3(0x24b),'hRtqg':function(_0x932a5,_0x46c4f5){return _0x932a5(_0x46c4f5);},'ZkwkY':_0x1942f3(0x21a),'nFMGC':_0x1942f3(0x330),'hQixj':_0x1942f3(0x229),'GQyjE':_0x1942f3(0x415),'TtWwV':'close','zxXIf':_0x1942f3(0x306),'WJJWl':_0x1942f3(0x40a),'aIGus':function(_0x2e34fb,_0x499aba,_0x12ebcb){return _0x2e34fb(_0x499aba,_0x12ebcb);},'sfGkF':_0x1942f3(0x6fa),'pYnFg':_0x1942f3(0x8a6),'Xylrt':function(_0x242c67,_0x96a5bc){return _0x242c67!==_0x96a5bc;},'ZKwNS':_0x1942f3(0x822),'eJIVx':_0x1942f3(0x52e),'NeSnm':'NBvfy','RWJMW':_0x1942f3(0x867),'icQbf':_0x1942f3(0x7bf),'LjUCF':_0x1942f3(0x718),'gyXWc':_0x1942f3(0x720),'hRTAB':_0x1942f3(0x6ee),'edUra':_0x1942f3(0x8ca),'Hydjn':_0x1942f3(0x5e3),'dsShF':_0x1942f3(0x5f7),'DdfoE':_0x1942f3(0x724),'XLdQu':'warning:','qExJv':_0x1942f3(0x48a),'weQgs':function(_0x2dfdb3,_0x54662e){return _0x2dfdb3===_0x54662e;},'BDdJV':_0x1942f3(0x46d),'bYcbs':_0x1942f3(0x7da),'TCric':_0x1942f3(0x593),'pEwqQ':function(_0x2ce06d){return _0x2ce06d();},'SCcAs':'qtHwJ','zxkbN':_0x1942f3(0x4df),'Mckbc':'hXjSV','jCzqY':_0x1942f3(0x5e1),'YtBAN':_0x1942f3(0x7c4),'phIvm':'WebDriverAgent','AlwUu':_0x1942f3(0x7a4),'tGRgM':_0x1942f3(0x7c9),'mYOew':function(_0x134b30,_0x349135){return _0x134b30(_0x349135);},'wVrKo':function(_0x374003,_0x514e17,_0x2b0fc9,_0x16bb74){return _0x374003(_0x514e17,_0x2b0fc9,_0x16bb74);},'PWtzV':function(_0x2faffc,_0x217072){return _0x2faffc(_0x217072);},'YXIFe':function(_0x1581d4,_0x180fc9){return _0x1581d4===_0x180fc9;},'vwCxe':'bkNMZ','vkHZp':function(_0x2e990b,_0x567dfa,_0x51876a){return _0x2e990b(_0x567dfa,_0x51876a);},'xDVNp':function(_0x355941,_0x2c95dc){return _0x355941===_0x2c95dc;},'iXLoI':'YBvLA','DAUai':'curl'};return new Promise(async(_0x3161fe,_0x2281c2)=>{const _0x1f759a=_0x1942f3,_0x10ce4a={'teOqD':function(_0xdc4efa,_0x52eb10){const _0x49b9f5=_0x4c0b;return _0x51bca1[_0x49b9f5(0x1eb)](_0xdc4efa,_0x52eb10);},'YDWHl':_0x1f759a(0x42f),'WkwIG':function(_0x21a940,_0x1fdf39){return _0x51bca1['rfaAA'](_0x21a940,_0x1fdf39);},'KmzBn':_0x1f759a(0x4f6),'IEHmh':_0x51bca1[_0x1f759a(0x4c3)],'JROSE':_0x51bca1['JXcZi'],'uThya':'io.appium.uiautomator2','pZffO':function(_0x500496,_0x3cd938){const _0x4f38da=_0x1f759a;return _0x51bca1[_0x4f38da(0x55b)](_0x500496,_0x3cd938);},'tpdTO':_0x51bca1[_0x1f759a(0x2c3)],'oodzS':function(_0x1a50fe,_0x4f3114){const _0x3d976e=_0x1f759a;return _0x51bca1[_0x3d976e(0x382)](_0x1a50fe,_0x4f3114);},'XVfEm':'GsNPZ','LSkIK':_0x51bca1[_0x1f759a(0x607)],'fPzdl':_0x1f759a(0x6df),'QbRHt':_0x51bca1['nFMGC'],'mQNaM':function(_0x5b0320,_0x1cf03c,_0x488171){const _0x4d7a1e=_0x1f759a;return _0x51bca1[_0x4d7a1e(0x860)](_0x5b0320,_0x1cf03c,_0x488171);},'gcQnp':_0x51bca1[_0x1f759a(0x404)],'Dtuiw':_0x51bca1['GQyjE'],'TWglI':_0x51bca1[_0x1f759a(0x836)],'yfcaO':_0x51bca1['TtWwV'],'ODRny':_0x51bca1[_0x1f759a(0x314)],'oaaJc':_0x51bca1['WJJWl'],'XqAkz':_0x1f759a(0x33a),'QqBlr':function(_0x5452bb,_0x3e4dfc,_0x7e496a){const _0x3601d8=_0x1f759a;return _0x51bca1[_0x3601d8(0x312)](_0x5452bb,_0x3e4dfc,_0x7e496a);},'WmPhC':_0x51bca1[_0x1f759a(0x4cb)],'nBajE':function(_0x2c45ac,_0x57698c){return _0x51bca1['fcGPn'](_0x2c45ac,_0x57698c);},'WATJv':_0x1f759a(0x216),'JiXxN':_0x51bca1[_0x1f759a(0x6e7)],'iKDro':'VXRPH','HFEOF':function(_0x121efc,_0x37de44){const _0x13cb24=_0x1f759a;return _0x51bca1[_0x13cb24(0x382)](_0x121efc,_0x37de44);},'IYTlk':function(_0x37d17a,_0x26745b){return _0x51bca1['hRtqg'](_0x37d17a,_0x26745b);},'Airdf':function(_0x3b1bcf,_0x15b377){const _0x3a7bbe=_0x1f759a;return _0x51bca1[_0x3a7bbe(0x71c)](_0x3b1bcf,_0x15b377);},'NOaqe':_0x51bca1[_0x1f759a(0x68f)],'mWQHA':_0x51bca1[_0x1f759a(0x7e7)],'jcWLL':function(_0x18a129,_0xb984a8){return _0x18a129!==_0xb984a8;},'RHWtj':function(_0x3abaef,_0x54c802){const _0x3675b9=_0x1f759a;return _0x51bca1[_0x3675b9(0x5ff)](_0x3abaef,_0x54c802);},'XRJcS':_0x51bca1[_0x1f759a(0x4af)],'vOeaA':_0x1f759a(0x83e),'WbNOn':_0x51bca1['RWJMW'],'yMVea':_0x51bca1[_0x1f759a(0x5c0)],'oLKcR':function(_0x931ed7,_0x2202da){return _0x931ed7!==_0x2202da;},'VnIQI':_0x51bca1[_0x1f759a(0x8a7)],'uXKcF':_0x51bca1[_0x1f759a(0x756)],'OnaOK':_0x51bca1[_0x1f759a(0x568)],'MwnnT':'NPtBK','AUIBO':function(_0x355203,_0x3e7230){const _0x12e92d=_0x1f759a;return _0x51bca1[_0x12e92d(0x5ff)](_0x355203,_0x3e7230);},'FBYLn':_0x51bca1[_0x1f759a(0x274)],'nBspD':_0x51bca1[_0x1f759a(0x4c7)],'fHacy':function(_0x529fb8,_0x12d4ea,_0x1a1eda){return _0x529fb8(_0x12d4ea,_0x1a1eda);},'ujwyv':function(_0x300572,_0x9fdbf8){return _0x300572===_0x9fdbf8;},'cpOUT':_0x51bca1['dsShF'],'xLPhl':_0x1f759a(0x440),'oOpTR':_0x1f759a(0x2a5),'zLGPW':_0x51bca1[_0x1f759a(0x5bd)],'iHIna':_0x51bca1['XLdQu'],'DXGMt':_0x51bca1[_0x1f759a(0x2ca)],'tGQzl':function(_0x4d9070,_0x311cc7){return _0x51bca1['weQgs'](_0x4d9070,_0x311cc7);},'xWMGE':_0x51bca1['BDdJV'],'FUoAy':_0x51bca1[_0x1f759a(0x516)],'yKGBF':_0x51bca1[_0x1f759a(0x5e8)],'bJBej':function(_0x18062a){const _0x30fcf2=_0x1f759a;return _0x51bca1[_0x30fcf2(0x7c1)](_0x18062a);},'GxHwK':_0x51bca1[_0x1f759a(0x49f)],'ItftN':_0x51bca1[_0x1f759a(0x85a)],'iSSCr':_0x51bca1[_0x1f759a(0x5e2)],'XeVeS':_0x51bca1[_0x1f759a(0x668)],'nQqBs':_0x51bca1[_0x1f759a(0x7f2)],'YUJOK':_0x51bca1[_0x1f759a(0x5b3)],'uhMqN':_0x51bca1[_0x1f759a(0x2cf)],'rMhDg':function(_0x5aa0d6,_0x4d578a,_0x62d61e){const _0x2580e1=_0x1f759a;return _0x51bca1[_0x2580e1(0x312)](_0x5aa0d6,_0x4d578a,_0x62d61e);},'qCPLE':_0x51bca1[_0x1f759a(0x534)],'wtajP':_0x51bca1[_0x1f759a(0x71f)],'kOhwm':function(_0x1b3cbf,_0x1aa13b){const _0x586e50=_0x1f759a;return _0x51bca1[_0x586e50(0x2b7)](_0x1b3cbf,_0x1aa13b);},'JzxAf':_0x51bca1[_0x1f759a(0x65d)],'VDBmT':function(_0x395256,_0x58e24d,_0x126962,_0x439f18){const _0x25fefa=_0x1f759a;return _0x51bca1[_0x25fefa(0x4bc)](_0x395256,_0x58e24d,_0x126962,_0x439f18);},'ozRcJ':_0x51bca1[_0x1f759a(0x45c)],'nyGGm':_0x51bca1[_0x1f759a(0x387)],'dkqJW':_0x1f759a(0x2ea),'ZmjVY':_0x51bca1[_0x1f759a(0x27f)],'PIDMY':_0x51bca1[_0x1f759a(0x6a5)],'KJBBs':_0x51bca1[_0x1f759a(0x289)],'FgpwJ':_0x51bca1['MixuU'],'qniVB':_0x1f759a(0x6f6),'AWqmO':function(_0x393a2b,_0x34ca37){const _0x15e419=_0x1f759a;return _0x51bca1[_0x15e419(0x2a1)](_0x393a2b,_0x34ca37);}},{name:_0x5c7b29,udid:_0x240b88,type:_0x51caa6,ip:_0x105410,platform:_0x3c0c4d}=_0x911b5c;console[_0x1f759a(0x61d)]('Connecting\x20to\x20'+_0x5c7b29+'\x20('+_0x51caa6+',\x20platform:\x20'+_0x3c0c4d+')...');if(_0x51bca1[_0x1f759a(0x1eb)](_0x3c0c4d,_0x1f759a(0x705))){if(_0x51bca1[_0x1f759a(0x3dc)](_0x51bca1['vwCxe'],_0x51bca1[_0x1f759a(0x67b)])){console[_0x1f759a(0x61d)](_0x1f759a(0x410)+_0x5c7b29);const _0x41908b=_0x51bca1[_0x1f759a(0x555)](spawn,_0x51bca1['hQixj'],[_0x1f759a(0x658)]);let _0xf52d76='';_0x41908b['stdout']['on'](_0x1f759a(0x1da),_0x1ee99f=>{_0xf52d76+=_0x1ee99f['toString']();}),_0x41908b['on'](_0x51bca1[_0x1f759a(0x252)],async _0x42eda1=>{const _0x4e904e=_0x1f759a,_0x1c73c0={'Gksua':'Invalid\x20or\x20unavailable\x20provider','CkAXY':function(_0x2f1b56,_0x5a7374){const _0xf23efd=_0x4c0b;return _0x10ce4a[_0xf23efd(0x466)](_0x2f1b56,_0x5a7374);},'wQbwZ':function(_0x1c4e89,_0x7826e5){return _0x1c4e89!==_0x7826e5;},'SHjIo':_0x10ce4a[_0x4e904e(0x816)],'glRSk':_0x10ce4a[_0x4e904e(0x33d)],'CCujX':'Failed\x20to\x20get\x20locators','GPHRj':'ltjuy','ZxBBY':function(_0x56d584,_0xf0a0b8){return _0x10ce4a['teOqD'](_0x56d584,_0xf0a0b8);},'INLTv':function(_0x3479e6,_0x1b84b4){return _0x3479e6(_0x1b84b4);},'SGvOJ':_0x10ce4a[_0x4e904e(0x30d)],'dHDHd':function(_0x3af3ae,_0x48a5c8,_0x50958b){const _0x32d44d=_0x4e904e;return _0x10ce4a[_0x32d44d(0x535)](_0x3af3ae,_0x48a5c8,_0x50958b);},'sdPRj':_0x10ce4a[_0x4e904e(0x776)],'cRZXe':function(_0x10d1cf,_0x401b2d){const _0x2b4be2=_0x4e904e;return _0x10ce4a[_0x2b4be2(0x384)](_0x10d1cf,_0x401b2d);},'avRTj':_0x10ce4a[_0x4e904e(0x863)],'ybZJX':_0x10ce4a[_0x4e904e(0x4e6)],'EnhoZ':_0x10ce4a[_0x4e904e(0x29d)],'izKfe':'online','NjMsm':function(_0x5887cc,_0x4e14ea){return _0x5887cc(_0x4e14ea);},'VkseK':function(_0x147e6f,_0x337dcb){const _0x29d0f3=_0x4e904e;return _0x10ce4a[_0x29d0f3(0x384)](_0x147e6f,_0x337dcb);},'kuhlI':_0x10ce4a[_0x4e904e(0x2b8)],'DEgPK':function(_0x49f077,_0x473875){const _0x17f231=_0x4e904e;return _0x10ce4a[_0x17f231(0x894)](_0x49f077,_0x473875);},'ZZeOd':function(_0x56c93f,_0x13a386){const _0x2f2b4a=_0x4e904e;return _0x10ce4a[_0x2f2b4a(0x54e)](_0x56c93f,_0x13a386);},'UuvVb':function(_0x57eb6a,_0xb59636){const _0x45c051=_0x4e904e;return _0x10ce4a[_0x45c051(0x6c3)](_0x57eb6a,_0xb59636);}};if(_0x10ce4a[_0x4e904e(0x870)](_0x10ce4a[_0x4e904e(0x49b)],_0x10ce4a['NOaqe'])){const _0x2b9bc8={};_0x2b9bc8[_0x4e904e(0x859)]=![],_0x2b9bc8[_0x4e904e(0x6c8)]=_0x1c73c0['Gksua'],_0x39a296[_0x4e904e(0x4d0)](0x190)['json'](_0x2b9bc8);}else{const _0x48824b=_0xf52d76[_0x4e904e(0x310)](_0x240b88['replace'](_0x10ce4a[_0x4e904e(0x80e)],''))||_0xf52d76[_0x4e904e(0x310)](_0x240b88);if(_0x48824b){console[_0x4e904e(0x61d)](_0x4e904e(0x5dd)+_0x5c7b29+_0x4e904e(0x44c));const _0x54cd51=connectedDevices[_0x4e904e(0x6c5)](_0x57569f=>_0x57569f['name']===_0x5c7b29);_0x10ce4a['jcWLL'](_0x54cd51,-0x1)&&(_0x10ce4a[_0x4e904e(0x489)](_0x4e904e(0x520),_0x10ce4a['XRJcS'])?connectedDevices[_0x54cd51][_0x4e904e(0x4d0)]=_0x10ce4a[_0x4e904e(0x735)]:(_0x2c5c7d=_0x4e904e(0x351)+_0x3ccede+','+_0x56c80d,_0x1b5b43[_0x4e904e(0x61d)]('\x0aš±ļø\x20API:\x20Tapping\x20at\x20coordinates\x20('+_0x4c4d76+','+_0x155dd8+_0x4e904e(0x3f1)+_0x3728d8)));wss['clients'][_0x4e904e(0x68d)](_0x4dfbe8=>{const _0x43ac18=_0x4e904e;if(_0x10ce4a[_0x43ac18(0x466)](_0x4dfbe8[_0x43ac18(0x24e)],WebSocket['OPEN'])){const _0x6ec544={};_0x6ec544[_0x43ac18(0x4b8)]=_0x43ac18(0x33a),_0x6ec544[_0x43ac18(0x658)]=connectedDevices,_0x4dfbe8[_0x43ac18(0x71d)](JSON['stringify'](_0x6ec544));}}),console['log'](_0x4e904e(0x661)+_0x5c7b29+_0x4e904e(0x8cb));const _0x189651=_0x10ce4a['QqBlr'](spawn,'adb',['-s',_0x240b88,_0x10ce4a[_0x4e904e(0x7ba)],'pm',_0x10ce4a['Dtuiw'],_0x10ce4a[_0x4e904e(0x649)],_0x10ce4a[_0x4e904e(0x30d)]]);let _0x19df24='';_0x189651[_0x4e904e(0x803)]['on'](_0x10ce4a[_0x4e904e(0x292)],_0x3b6bbb=>{const _0x391c69=_0x4e904e;_0x19df24+=_0x3b6bbb[_0x391c69(0x7de)]();}),_0x189651['on'](_0x10ce4a[_0x4e904e(0x52f)],async()=>{const _0x5a66e1=_0x4e904e,_0x3827a9={'ZKKYH':_0x1c73c0[_0x5a66e1(0x6e3)],'CMzsa':_0x1c73c0[_0x5a66e1(0x652)],'sMSca':function(_0x1e67c5,_0x34dec5){const _0x17b029=_0x5a66e1;return _0x1c73c0[_0x17b029(0x738)](_0x1e67c5,_0x34dec5);},'GVecy':function(_0x246923,_0x5a6b18){const _0x1e1184=_0x5a66e1;return _0x1c73c0[_0x1e1184(0x596)](_0x246923,_0x5a6b18);}},_0x374613=_0x19df24['includes'](_0x1c73c0['SGvOJ']);if(!_0x374613){console[_0x5a66e1(0x61d)](_0x5a66e1(0x660)+_0x5c7b29+_0x5a66e1(0x5fc));const _0x5f0282=await _0x1c73c0['dHDHd'](installUIAutomator2,_0x240b88,_0x5c7b29);if(!_0x5f0282[_0x5a66e1(0x859)]){if(_0x1c73c0[_0x5a66e1(0x67f)](_0x1c73c0['sdPRj'],_0x5a66e1(0x3d5))){console[_0x5a66e1(0x61d)](_0x5a66e1(0x7ec)+_0x5c7b29);const _0x160e42={};_0x160e42[_0x5a66e1(0x859)]=!![],_0x160e42['message']=_0x5a66e1(0x605)+_0x5c7b29+_0x5a66e1(0x2df),_0x1c73c0['INLTv'](_0x3161fe,_0x160e42);return;}else{const _0x119cd5=_0x16d864[_0x5a66e1(0x295)](/^(.+?)\s+-\s+(.+?)$/);return _0x119cd5?{'id':_0x119cd5[0x1]['trim'](),'name':_0x119cd5[0x2]['trim']()}:null;}}}else{if(_0x1c73c0[_0x5a66e1(0x841)](_0x1c73c0['avRTj'],_0x1c73c0['ybZJX']))console[_0x5a66e1(0x61d)]('ā
\x20UIAutomator2\x20already\x20installed\x20on\x20'+_0x5c7b29);else{const _0x14204e={};_0x14204e[_0x5a66e1(0x859)]=![],_0x14204e[_0x5a66e1(0x6c8)]=_0x2fa56f[_0x5a66e1(0x6dc)],_0x5974a7[_0x5a66e1(0x4d0)](0x1f4)['json'](_0x14204e);}}const _0x5bc268=androidSessions[_0x5a66e1(0x3ac)](_0x240b88);if(_0x5bc268){console[_0x5a66e1(0x61d)]('ā»ļø\x20\x20Reusing\x20existing\x20UIAutomator2\x20session\x20on\x20'+_0x5c7b29+'\x20(port:\x20'+_0x5bc268[_0x5a66e1(0x6c2)]+')');try{const _0x275556=_0x1c73c0['INLTv'](require,_0x1c73c0[_0x5a66e1(0x54b)]);await _0x275556[_0x5a66e1(0x3ac)](_0x5a66e1(0x5aa)+_0x5bc268[_0x5a66e1(0x6c2)]+_0x5a66e1(0x2a4)),console['log'](_0x5a66e1(0x25d)+_0x5c7b29);const _0x541b2b=connectedDevices[_0x5a66e1(0x6c5)](_0x18a853=>_0x18a853[_0x5a66e1(0x719)]===_0x5c7b29);_0x1c73c0[_0x5a66e1(0x67f)](_0x541b2b,-0x1)&&(connectedDevices[_0x541b2b][_0x5a66e1(0x4d0)]=_0x1c73c0[_0x5a66e1(0x755)],wss[_0x5a66e1(0x284)][_0x5a66e1(0x68d)](_0x18e5d6=>{const _0x825a10=_0x5a66e1;if(_0x3827a9['CMzsa']===_0x3827a9[_0x825a10(0x2ae)]){if(_0x3827a9[_0x825a10(0x398)](_0x18e5d6[_0x825a10(0x24e)],WebSocket[_0x825a10(0x3ba)])){const _0x2923be={};_0x2923be['type']=_0x825a10(0x33a),_0x2923be['devices']=connectedDevices,_0x18e5d6[_0x825a10(0x71d)](JSON[_0x825a10(0x33e)](_0x2923be));}}else{_0x3bf963[_0x825a10(0x61d)]('ā\x20Command\x20execution\x20failed');const _0x6fab1a={};_0x6fab1a[_0x825a10(0x859)]=![],_0x6fab1a[_0x825a10(0x6c8)]=_0x3827a9[_0x825a10(0x22f)],_0x35c499[_0x825a10(0x4d0)](0x1f4)[_0x825a10(0x843)](_0x6fab1a);}}));const _0x2ec207={};_0x2ec207['success']=!![],_0x2ec207[_0x5a66e1(0x6dc)]='Connected\x20to\x20'+_0x5c7b29+'\x20-\x20UIAutomator2\x20Ready\x20ā
',_0x1c73c0['NjMsm'](_0x3161fe,_0x2ec207);return;}catch(_0x401b60){console[_0x5a66e1(0x61d)](_0x5a66e1(0x1f5)+_0x5c7b29),androidSessions[_0x5a66e1(0x27e)](_0x240b88);}}console[_0x5a66e1(0x61d)](_0x5a66e1(0x203)+_0x5c7b29+'...');const _0xe78dac=await startUIAutomator2Session(_0x240b88,_0x5c7b29);if(_0xe78dac[_0x5a66e1(0x859)]){if(_0x1c73c0[_0x5a66e1(0x65e)](_0x1c73c0['kuhlI'],_0x5a66e1(0x53b))){const _0x3e9378=connectedDevices[_0x5a66e1(0x6c5)](_0x492fe4=>_0x492fe4[_0x5a66e1(0x719)]===_0x5c7b29);_0x1c73c0[_0x5a66e1(0x8c9)](_0x3e9378,-0x1)&&(connectedDevices[_0x3e9378][_0x5a66e1(0x4d0)]=_0x1c73c0[_0x5a66e1(0x755)],wss[_0x5a66e1(0x284)]['forEach'](_0x1dc00b=>{const _0xb05270=_0x5a66e1;if(_0x1c73c0[_0xb05270(0x418)](_0x1dc00b[_0xb05270(0x24e)],WebSocket[_0xb05270(0x3ba)])){if(_0x1c73c0[_0xb05270(0x67f)](_0x1c73c0[_0xb05270(0x7fc)],_0x1c73c0[_0xb05270(0x7fc)]))_0x4186fe[_0xb05270(0x5a7)]=_0x314e37[0x1];else{const _0x491e34={};_0x491e34[_0xb05270(0x4b8)]=_0x1c73c0['glRSk'],_0x491e34[_0xb05270(0x658)]=connectedDevices,_0x1dc00b[_0xb05270(0x71d)](JSON['stringify'](_0x491e34));}}}));const _0x9cf923={};_0x9cf923[_0x5a66e1(0x859)]=!![],_0x9cf923[_0x5a66e1(0x6dc)]=_0x5a66e1(0x605)+_0x5c7b29+'\x20-\x20UIAutomator2\x20Ready\x20ā
',_0x1c73c0[_0x5a66e1(0x2e1)](_0x3161fe,_0x9cf923);}else{_0x42b12a[_0x5a66e1(0x61d)](_0x5a66e1(0x781));const _0x5d1ed9={};_0x5d1ed9[_0x5a66e1(0x859)]=![],_0x5d1ed9['message']=_0x5a66e1(0x5fd),_0x3827a9['GVecy'](_0x2e6bb5,_0x5d1ed9);}}else{const _0x2b26f3={};_0x2b26f3[_0x5a66e1(0x859)]=!![],_0x2b26f3[_0x5a66e1(0x6dc)]=_0x5a66e1(0x605)+_0x5c7b29+_0x5a66e1(0x2df),_0x1c73c0[_0x5a66e1(0x6a1)](_0x3161fe,_0x2b26f3);}});}else{console['log'](_0x4e904e(0x792)+_0x5c7b29+'\x20not\x20found\x20in\x20ADB');if(_0x10ce4a['teOqD'](_0x51caa6,'wireless')&&_0x105410){if(_0x10ce4a['oLKcR'](_0x10ce4a[_0x4e904e(0x5b1)],_0x10ce4a[_0x4e904e(0x5b1)])){const _0x34b9e7={};_0x34b9e7[_0x4e904e(0x4f2)]=_0x4e904e(0x41a),XFSSbZ[_0x4e904e(0x634)](_0xda2f1d,'lsof\x20-i:'+_0x4ba8c2,_0x34b9e7),_0x505d9a++;}else{console[_0x4e904e(0x61d)](_0x4e904e(0x646)+_0x5c7b29+_0x4e904e(0x7f4)+_0x105410+_0x4e904e(0x2c9));const _0x6ac007=_0x10ce4a[_0x4e904e(0x5b2)](spawn,_0x10ce4a[_0x4e904e(0x68a)],[_0x10ce4a[_0x4e904e(0x3c6)],_0x105410+_0x4e904e(0x52e)]);_0x6ac007['on'](_0x10ce4a['yfcaO'],async _0x165fa8=>{const _0x4c0613=_0x4e904e,_0x9b2eeb={'Gluqe':_0x10ce4a[_0x4c0613(0x492)],'AVENP':function(_0x23d0f3,_0x1a3cdd){return _0x10ce4a['WkwIG'](_0x23d0f3,_0x1a3cdd);},'IFTdd':_0x10ce4a[_0x4c0613(0x2f7)],'FgxEl':_0x10ce4a['IEHmh'],'RnIUM':'devices_updated','KkpfN':function(_0x344496,_0x1cb1e6){const _0x17b99c=_0x4c0613;return _0x10ce4a[_0x17b99c(0x466)](_0x344496,_0x1cb1e6);},'eGbNm':_0x4c0613(0x5df),'VVSAm':_0x10ce4a[_0x4c0613(0x722)],'MxtMx':_0x10ce4a[_0x4c0613(0x30d)],'POfMB':function(_0x4a7661,_0x1407d5,_0x47b63f){return _0x4a7661(_0x1407d5,_0x47b63f);},'nVwID':function(_0x32f927,_0x26d671){const _0x5734f0=_0x4c0613;return _0x10ce4a[_0x5734f0(0x6c3)](_0x32f927,_0x26d671);},'HkUgF':_0x10ce4a[_0x4c0613(0x29d)],'PhTXT':function(_0xba2463,_0x3c4f74){return _0x10ce4a['oodzS'](_0xba2463,_0x3c4f74);},'ANWVv':_0x10ce4a[_0x4c0613(0x73d)],'nFzAN':_0x10ce4a[_0x4c0613(0x264)],'VvGxh':function(_0x48af72,_0x3a58bc,_0x5de609){return _0x48af72(_0x3a58bc,_0x5de609);},'tSliz':function(_0xc922aa,_0xc45c1a){const _0x1f9cd4=_0x4c0613;return _0x10ce4a[_0x1f9cd4(0x42a)](_0xc922aa,_0xc45c1a);},'gnjMe':_0x10ce4a[_0x4c0613(0x451)],'VLPgH':function(_0x3e8c55,_0x5de838){return _0x3e8c55(_0x5de838);}};if(_0x10ce4a['QbRHt']!==_0x10ce4a[_0x4c0613(0x6be)])_0x5601aa+=_0xde7a82['toString']();else{if(_0x10ce4a['teOqD'](_0x165fa8,0x0)){console[_0x4c0613(0x61d)]('ā
\x20Connected\x20to\x20'+_0x5c7b29+_0x4c0613(0x50e));const _0x1f982a=connectedDevices['findIndex'](_0x1e2557=>_0x1e2557[_0x4c0613(0x719)]===_0x5c7b29);_0x10ce4a[_0x4c0613(0x42a)](_0x1f982a,-0x1)&&(connectedDevices[_0x1f982a][_0x4c0613(0x4d0)]=_0x4c0613(0x83e));console['log']('š¦\x20Ensuring\x20UIAutomator2\x20is\x20installed\x20on\x20'+_0x5c7b29+'...');const _0x4d4b7f=_0x10ce4a['mQNaM'](spawn,_0x10ce4a[_0x4c0613(0x68a)],['-s',_0x105410+_0x4c0613(0x52e),_0x4c0613(0x867),'pm',_0x10ce4a[_0x4c0613(0x778)],_0x4c0613(0x7bf),_0x10ce4a[_0x4c0613(0x30d)]]);let _0x427366='';_0x4d4b7f[_0x4c0613(0x803)]['on'](_0x10ce4a['TWglI'],_0x1770e1=>{const _0x1297c3=_0x4c0613;_0x427366+=_0x1770e1[_0x1297c3(0x7de)]();}),_0x4d4b7f['on'](_0x10ce4a[_0x4c0613(0x52f)],async()=>{const _0xea1b5b=_0x4c0613,_0x52064f={'fLsvd':function(_0x36b4ca,_0x89f19a){const _0x43dedb=_0x4c0b;return _0x9b2eeb[_0x43dedb(0x8b3)](_0x36b4ca,_0x89f19a);},'tDVDd':_0x9b2eeb[_0xea1b5b(0x361)],'JTIok':function(_0x166fc8,_0x4daf80){return _0x166fc8===_0x4daf80;},'WBDVj':_0x9b2eeb[_0xea1b5b(0x49d)],'DdYJz':_0x9b2eeb[_0xea1b5b(0x754)]};if(_0x9b2eeb[_0xea1b5b(0x389)](_0x9b2eeb[_0xea1b5b(0x504)],_0x9b2eeb[_0xea1b5b(0x57c)]))_0x6a148c+=_0x33f169[_0xea1b5b(0x7de)]();else{const _0x51a3f9=_0x427366[_0xea1b5b(0x310)](_0x9b2eeb[_0xea1b5b(0x3d1)]);if(!_0x51a3f9){console[_0xea1b5b(0x61d)](_0xea1b5b(0x660)+_0x5c7b29+',\x20installing...');const _0x102784=await _0x9b2eeb[_0xea1b5b(0x62a)](installUIAutomator2,_0x105410+_0xea1b5b(0x52e),_0x5c7b29);!_0x102784[_0xea1b5b(0x859)]&&console[_0xea1b5b(0x61d)]('ā ļø\x20UIAutomator2\x20installation\x20failed\x20on\x20'+_0x5c7b29);}else console[_0xea1b5b(0x61d)](_0xea1b5b(0x30a)+_0x5c7b29);const _0x340141=androidSessions['get'](_0x105410+_0xea1b5b(0x52e));if(_0x340141){console['log'](_0xea1b5b(0x691)+_0x5c7b29+_0xea1b5b(0x336)+_0x340141[_0xea1b5b(0x6c2)]+')');try{const _0x58ab5a=_0x9b2eeb[_0xea1b5b(0x5e6)](require,_0x9b2eeb[_0xea1b5b(0x390)]);await _0x58ab5a[_0xea1b5b(0x3ac)](_0xea1b5b(0x5aa)+_0x340141[_0xea1b5b(0x6c2)]+_0xea1b5b(0x2a4)),console[_0xea1b5b(0x61d)](_0xea1b5b(0x25d)+_0x5c7b29);_0x1f982a!==-0x1&&(_0x9b2eeb[_0xea1b5b(0x1e4)](_0x9b2eeb[_0xea1b5b(0x5d1)],_0xea1b5b(0x204))?_0x5c6e43[_0xea1b5b(0x3ea)](_0x9b2eeb[_0xea1b5b(0x411)],_0x448ee6,_0x1e2395):(connectedDevices[_0x1f982a][_0xea1b5b(0x4d0)]=_0x9b2eeb[_0xea1b5b(0x758)],wss[_0xea1b5b(0x284)]['forEach'](_0x3fc01b=>{const _0x3bca25=_0xea1b5b;if(_0x52064f[_0x3bca25(0x2a7)]!==_0x52064f[_0x3bca25(0x2a7)]){const _0x1fdfc1={};_0x1fdfc1[_0x3bca25(0x66d)]=_0x2eaa52,_0x1fdfc1[_0x3bca25(0x581)]=_0x2e9371[_0x3bca25(0x581)],_0x1fdfc1[_0x3bca25(0x6c8)]='Failed\x20to\x20get\x20app\x20info';const _0x523299={};_0x523299['success']=![],_0x523299['error']=_0x54d557[_0x3bca25(0x6dc)],_0x523299[_0x3bca25(0x5bc)]=_0x1fdfc1,_0x26242f[_0x3bca25(0x843)](_0x523299);}else{if(_0x52064f[_0x3bca25(0x40c)](_0x3fc01b[_0x3bca25(0x24e)],WebSocket['OPEN'])){if(_0x52064f[_0x3bca25(0x40c)](_0x52064f['WBDVj'],_0x52064f['WBDVj'])){const _0x48624e={};_0x48624e['type']=_0x52064f[_0x3bca25(0x739)],_0x48624e[_0x3bca25(0x658)]=connectedDevices,_0x3fc01b[_0x3bca25(0x71d)](JSON[_0x3bca25(0x33e)](_0x48624e));}else{const _0x4931be={};_0x4931be[_0x3bca25(0x859)]=![],KLLbwg[_0x3bca25(0x712)](_0x21bd27,_0x4931be);}}}})));const _0x83990b={};_0x83990b[_0xea1b5b(0x859)]=!![],_0x83990b[_0xea1b5b(0x6dc)]=_0xea1b5b(0x605)+_0x5c7b29+'\x20-\x20UIAutomator2\x20Ready\x20ā
',_0x9b2eeb[_0xea1b5b(0x8b3)](_0x3161fe,_0x83990b);return;}catch(_0x3826b7){console[_0xea1b5b(0x61d)](_0xea1b5b(0x1f5)+_0x5c7b29),androidSessions[_0xea1b5b(0x27e)](_0x105410+_0xea1b5b(0x52e));}}console[_0xea1b5b(0x61d)](_0xea1b5b(0x203)+_0x5c7b29+_0xea1b5b(0x8cb));const _0x61f449=await _0x9b2eeb[_0xea1b5b(0x53c)](startUIAutomator2Session,_0x105410+_0xea1b5b(0x52e),_0x5c7b29);let _0x2f6b71='';if(_0x61f449[_0xea1b5b(0x859)]){if(_0x9b2eeb[_0xea1b5b(0x1e4)](_0x1f982a,-0x1)){if(_0x9b2eeb[_0xea1b5b(0x7a1)](_0x9b2eeb['gnjMe'],_0x9b2eeb[_0xea1b5b(0x613)])){_0x258917['error'](_0xea1b5b(0x232),_0x51f957);const _0xad170c={};_0xad170c[_0xea1b5b(0x859)]=![],_0xad170c['error']=_0x39390b[_0xea1b5b(0x6dc)],_0x2340aa['status'](0x1f4)[_0xea1b5b(0x843)](_0xad170c);}else connectedDevices[_0x1f982a]['status']=_0x9b2eeb[_0xea1b5b(0x758)],wss[_0xea1b5b(0x284)][_0xea1b5b(0x68d)](_0x2dda12=>{const _0x462736=_0xea1b5b;if(_0x52064f['JTIok'](_0x2dda12[_0x462736(0x24e)],WebSocket[_0x462736(0x3ba)])){const _0xa044e1={};_0xa044e1[_0x462736(0x4b8)]=_0x52064f[_0x462736(0x739)],_0xa044e1[_0x462736(0x658)]=connectedDevices,_0x2dda12[_0x462736(0x71d)](JSON['stringify'](_0xa044e1));}});}_0x2f6b71=_0xea1b5b(0x605)+_0x5c7b29+_0xea1b5b(0x42e);}else _0x2f6b71=_0xea1b5b(0x605)+_0x5c7b29+_0xea1b5b(0x2df);const _0x1c6d36={};_0x1c6d36[_0xea1b5b(0x859)]=!![],_0x1c6d36[_0xea1b5b(0x6dc)]=_0x2f6b71,_0x9b2eeb[_0xea1b5b(0x7d6)](_0x3161fe,_0x1c6d36);}});}else{const _0x41eb1d={};_0x41eb1d['success']=![],_0x41eb1d[_0x4c0613(0x6dc)]=_0x4c0613(0x4c8)+_0x5c7b29+_0x4c0613(0x4b7),_0x10ce4a[_0x4c0613(0x6c3)](_0x2281c2,_0x41eb1d);}}});}}else{if(_0x10ce4a[_0x4e904e(0x466)](_0x10ce4a[_0x4e904e(0x41d)],_0x10ce4a[_0x4e904e(0x433)]))return _0x25b329[_0x4e904e(0x61d)](_0x10ce4a[_0x4e904e(0x7b4)]),[];else{const _0x20ffc1={};_0x20ffc1['success']=![],_0x20ffc1[_0x4e904e(0x6dc)]=_0x4e904e(0x7b7)+_0x5c7b29+_0x4e904e(0x455),_0x10ce4a[_0x4e904e(0x2b2)](_0x2281c2,_0x20ffc1);}}}}}),_0x41908b['on'](_0x1f759a(0x6c8),_0x21cdba=>{const _0x1ffba7=_0x1f759a;console[_0x1ffba7(0x6c8)]('ā\x20ADB\x20error:\x20'+_0x21cdba['message']);const _0x5191b8={};_0x5191b8['success']=![],_0x5191b8['message']=_0x1ffba7(0x463),_0x10ce4a[_0x1ffba7(0x6c3)](_0x2281c2,_0x5191b8);});return;}else{const _0x1dd208={};return _0x1dd208[_0x1f759a(0x859)]=![],_0x1dd208[_0x1f759a(0x6c8)]=_0x1f759a(0x21f)+_0x5bd2d3[_0x1f759a(0x6dc)],_0x5ded6a[_0x1f759a(0x4d0)](0x1f4)[_0x1f759a(0x843)](_0x1dd208);}}if(_0x51bca1['xDVNp'](_0x51caa6,_0x1f759a(0x760))){if(_0x51bca1[_0x1f759a(0x3dc)](_0x51bca1['iXLoI'],_0x51bca1['iXLoI'])){const _0x5253b7=_0x51bca1[_0x1f759a(0x312)](spawn,_0x51bca1['DAUai'],['-s',_0x1f759a(0x7c9),'2','http://localhost:8100/status']);let _0x2edd7d='';_0x5253b7[_0x1f759a(0x803)]['on'](_0x51bca1[_0x1f759a(0x836)],_0x476b03=>{const _0x1042c1=_0x1f759a;if(_0x10ce4a[_0x1042c1(0x21b)](_0x10ce4a['FBYLn'],_0x10ce4a[_0x1042c1(0x473)]))_0x2edd7d+=_0x476b03[_0x1042c1(0x7de)]();else{_0x1cabe4[_0x1042c1(0x6c8)](_0x1042c1(0x24f)+_0xc78179+':',_0x7b8a1c['message']);const _0x522a94={};return _0x522a94[_0x1042c1(0x859)]=![],_0x522a94[_0x1042c1(0x6c8)]=_0x108667['message'],_0x522a94;}}),_0x5253b7['on'](_0x51bca1[_0x1f759a(0x498)],_0x4f0782=>{const _0x5ae321=_0x1f759a;console[_0x5ae321(0x6c8)](_0x5ae321(0x3c9)+_0x4f0782[_0x5ae321(0x6dc)]);const _0x5e656d={};_0x5e656d['success']=![],_0x5e656d[_0x5ae321(0x6dc)]=_0x5ae321(0x42d)+_0x4f0782[_0x5ae321(0x6dc)],_0x2281c2(_0x5e656d);}),_0x5253b7['on'](_0x1f759a(0x884),async _0x452967=>{const _0xda6d34=_0x1f759a,_0x430810={'BrxGo':_0x51bca1[_0xda6d34(0x1e3)],'CJDBL':function(_0x39f6ab,_0x107c40,_0x2a937c){const _0x233f7c=_0xda6d34;return _0x51bca1[_0x233f7c(0x538)](_0x39f6ab,_0x107c40,_0x2a937c);},'VaHmo':_0xda6d34(0x377),'tKhrD':_0x51bca1['JDSLf'],'vwHTF':function(_0xb32bc8,_0x93478e,_0x3bcc51,_0x55f985,_0x221de7){const _0x593fb1=_0xda6d34;return _0x51bca1[_0x593fb1(0x25c)](_0xb32bc8,_0x93478e,_0x3bcc51,_0x55f985,_0x221de7);},'kqgXJ':_0x51bca1[_0xda6d34(0x397)],'muEVn':_0x51bca1[_0xda6d34(0x416)],'mMIen':function(_0x876eb4,_0x3343c6,_0x7f25db,_0x176f8a){return _0x876eb4(_0x3343c6,_0x7f25db,_0x176f8a);},'woSCU':function(_0x37c271,_0x563158){return _0x37c271!==_0x563158;},'NQhAv':_0x51bca1[_0xda6d34(0x31f)],'eGDAf':_0x51bca1[_0xda6d34(0x888)],'eHlSz':_0xda6d34(0x89d),'lqLEo':_0xda6d34(0x681),'zpJnG':function(_0x275584,_0xf74b26){const _0x32ce02=_0xda6d34;return _0x51bca1[_0x32ce02(0x7d5)](_0x275584,_0xf74b26);},'YhCKR':'āVis','TgcmW':_0x51bca1['qmsiN'],'fEqnE':_0x51bca1[_0xda6d34(0x59b)],'NtMvR':_0x51bca1['iDDjJ'],'NNMVM':function(_0x238e25,_0x59d74f){return _0x51bca1['rBAWc'](_0x238e25,_0x59d74f);},'OYYqV':_0x51bca1[_0xda6d34(0x3dd)],'SjZnc':_0x51bca1['CmGOy'],'gvmOM':function(_0x188aa2,_0x2b8ad5){return _0x188aa2===_0x2b8ad5;}};if(_0x51bca1[_0xda6d34(0x48c)](_0x51bca1[_0xda6d34(0x659)],_0xda6d34(0x31a))){const _0x4dc61e={};_0x4dc61e[_0xda6d34(0x4b8)]=ywoSXV[_0xda6d34(0x490)],_0x4dc61e[_0xda6d34(0x658)]=_0xee52a,_0x23f112[_0xda6d34(0x71d)](_0x398d5a['stringify'](_0x4dc61e));}else{if(_0x2edd7d[_0xda6d34(0x310)](_0x51bca1[_0xda6d34(0x2cf)])){if(_0x51bca1[_0xda6d34(0x48c)]('KWhRs',_0x51bca1[_0xda6d34(0x424)])){console[_0xda6d34(0x61d)](_0xda6d34(0x26f)+_0x5c7b29),console['log'](_0xda6d34(0x6d9)+_0x5c7b29+_0xda6d34(0x8cb));const _0x499d71=await _0x51bca1[_0xda6d34(0x860)](createWDASession,_0x51bca1['iDDjJ'],_0x5c7b29);if(_0x499d71[_0xda6d34(0x859)]){if(_0x51bca1[_0xda6d34(0x81e)]===_0x51bca1[_0xda6d34(0x81e)])console[_0xda6d34(0x61d)](_0xda6d34(0x64d)+_0x499d71[_0xda6d34(0x39b)]);else{const _0x3ba0dd={};_0x3ba0dd[_0xda6d34(0x859)]=![],_0x3ba0dd[_0xda6d34(0x6c8)]=_0x4d4ab7[_0xda6d34(0x6dc)],_0x583899[_0xda6d34(0x4d0)](0x1f4)[_0xda6d34(0x843)](_0x3ba0dd);}}else _0x51bca1[_0xda6d34(0x5ff)](_0x51bca1[_0xda6d34(0x30e)],_0xda6d34(0x768))?_0x18c9a0=_0x430810[_0xda6d34(0x5b6)](_0xd56704,_0xda6d34(0x1ef)+_0x17c6c5+_0xda6d34(0x509),{'encoding':_0x430810[_0xda6d34(0x3b7)],'timeout':0x7530}):console['log'](_0xda6d34(0x657));const _0x504c30=connectedDevices['findIndex'](_0x4ddc00=>_0x4ddc00[_0xda6d34(0x719)]===_0x5c7b29);if(_0x504c30!==-0x1){if(_0x51bca1['ovUgF'](_0x51bca1[_0xda6d34(0x5c3)],_0x51bca1[_0xda6d34(0x521)])){const _0x38a7f9=_0x10ce4a[_0xda6d34(0x6e4)](_0x1ba688,'sh',['-c',_0xda6d34(0x51f)+_0x4c4ad8+'\x22\x20||\x20true']);_0x38a7f9['on']('close',()=>{const _0x2a1e59=_0xda6d34;_0xe9c94f[_0x2a1e59(0x61d)]('ā
\x20Cleaned\x20up\x20iproxy\x20for\x20'+_0x2b1af1);});}else connectedDevices[_0x504c30][_0xda6d34(0x4d0)]=_0x51bca1[_0xda6d34(0x607)];}wss[_0xda6d34(0x284)][_0xda6d34(0x68d)](_0x11f7c2=>{const _0x2b3655=_0xda6d34;if(_0x10ce4a['ujwyv'](_0x10ce4a[_0x2b3655(0x340)],_0x10ce4a[_0x2b3655(0x340)])){if(_0x10ce4a[_0x2b3655(0x406)](_0x11f7c2[_0x2b3655(0x24e)],WebSocket[_0x2b3655(0x3ba)])){if(_0x10ce4a['jcWLL'](_0x2b3655(0x440),_0x10ce4a['xLPhl']))try{_0x3f493d['kill'](_0x58356e['iproxy'],_0x430810[_0x2b3655(0x430)]),_0x4ced6f[_0x2b3655(0x61d)](_0x2b3655(0x7ce)+_0x49d9c1+_0x2b3655(0x441)+_0x478669[_0x2b3655(0x7d3)]+')');}catch(_0x44b20b){_0x273dc1[_0x2b3655(0x61d)](_0x2b3655(0x82c)+_0x368162[_0x2b3655(0x7d3)]+_0x2b3655(0x288));}else{const _0x1dbec3={};_0x1dbec3[_0x2b3655(0x4b8)]=_0x10ce4a[_0x2b3655(0x33d)],_0x1dbec3[_0x2b3655(0x658)]=connectedDevices,_0x11f7c2[_0x2b3655(0x71d)](JSON[_0x2b3655(0x33e)](_0x1dbec3));}}}else{const _0x9e1b5f={'bPUzq':function(_0x25411c,_0x26227d,_0x5ab4d8,_0x52d658,_0x13ce05){const _0x137b75=_0x2b3655;return _0x430810[_0x137b75(0x30b)](_0x25411c,_0x26227d,_0x5ab4d8,_0x52d658,_0x13ce05);},'IqcoG':_0x430810['kqgXJ'],'jXAyq':_0x430810[_0x2b3655(0x824)]};_0x430810[_0x2b3655(0x65c)](_0x128e0a,_0x21e81d,_0x4d4607,_0x425475)[_0x2b3655(0x6bf)](_0x16424c=>{const _0x16a83b=_0x2b3655;_0x5eb6c0&&_0x9e1b5f[_0x16a83b(0x5e9)](_0x3c782f,_0x2530c7,_0x45514a,_0x454464,_0x492415);const _0x25ebc8={};_0x25ebc8['type']=_0x9e1b5f[_0x16a83b(0x7c8)],_0x25ebc8['result']=_0x16424c,_0x4435f8[_0x16a83b(0x71d)](_0x418a59[_0x16a83b(0x33e)](_0x25ebc8));})[_0x2b3655(0x795)](_0x31d46d=>{const _0x5463fa=_0x2b3655;_0x175374[_0x5463fa(0x6c8)](_0x5463fa(0x852)+_0x31d46d['message']);const _0x3b28c4={};_0x3b28c4[_0x5463fa(0x4b8)]=_0x9e1b5f[_0x5463fa(0x3cf)],_0x3b28c4[_0x5463fa(0x6c8)]=_0x31d46d['message'],_0x174f1b[_0x5463fa(0x71d)](_0x468de1[_0x5463fa(0x33e)](_0x3b28c4));});}});const _0x1101ce={};_0x1101ce[_0xda6d34(0x859)]=!![],_0x1101ce['message']=_0xda6d34(0x605)+_0x5c7b29+_0xda6d34(0x579),_0x51bca1[_0xda6d34(0x7d5)](_0x3161fe,_0x1101ce);}else{const _0x2b6495={};return _0x2b6495[_0xda6d34(0x859)]=![],_0x2b6495['error']=_0x10ce4a[_0xda6d34(0x770)],_0x214828[_0xda6d34(0x843)](_0x2b6495);}}else{if(_0x51bca1[_0xda6d34(0x382)](_0x51bca1['QxrIb'],'WsSaA')){console['log'](_0xda6d34(0x409)+_0x5c7b29+_0xda6d34(0x7a3)+_0x240b88+_0xda6d34(0x5e0));const _0x6c80f9=process.env.WDA_PATH||path[_0xda6d34(0x5c8)](process.env.HOME,_0x51bca1[_0xda6d34(0x65d)]);console['log'](_0xda6d34(0x5d7)+_0x6c80f9),console['log'](_0xda6d34(0x241)+_0x240b88);const _0x46736a=spawn(_0x51bca1[_0xda6d34(0x45c)],[_0x51bca1[_0xda6d34(0x387)],_0x51bca1['OKTrz'],path['join'](_0x6c80f9,_0x51bca1['sCkdR']),_0x51bca1['ZmYuw'],_0x51bca1[_0xda6d34(0x27f)],_0x51bca1['mnrpe'],'id='+_0x240b88,_0x51bca1[_0xda6d34(0x289)]],{'cwd':_0x6c80f9,'detached':!![],'stdio':[_0x51bca1[_0xda6d34(0x817)],_0x51bca1[_0xda6d34(0x6e8)],_0xda6d34(0x6f6)]});_0x46736a['stdout']['on'](_0x51bca1[_0xda6d34(0x836)],_0x5570d8=>{const _0xa50741=_0xda6d34;if(_0x430810[_0xa50741(0x842)](_0x430810[_0xa50741(0x2f3)],_0xa50741(0x721))){const _0x4e60eb=_0x5570d8[_0xa50741(0x7de)]();(_0x4e60eb['includes'](_0x430810['eGDAf'])||_0x4e60eb[_0xa50741(0x310)](_0x430810[_0xa50741(0x51a)]))&&console['log'](_0xa50741(0x4d9)+_0x4e60eb[_0xa50741(0x685)]());}else{const _0x46ff7b={};_0x46ff7b['success']=![],_0x46ff7b[_0xa50741(0x6c8)]=_0x120d66[_0xa50741(0x6dc)],_0x1d43dd[_0xa50741(0x4d0)](0x1f4)[_0xa50741(0x843)](_0x46ff7b);}}),_0x46736a[_0xda6d34(0x3ec)]['on']('data',_0x308d35=>{const _0x55f240=_0xda6d34,_0x56c928={'cxdsU':function(_0x41b6e8,_0x46dcff){return _0x10ce4a['pZffO'](_0x41b6e8,_0x46dcff);}},_0x5e2c6f=_0x308d35[_0x55f240(0x7de)]();if(!_0x5e2c6f[_0x55f240(0x310)](_0x10ce4a[_0x55f240(0x7f0)])&&!_0x5e2c6f[_0x55f240(0x310)](_0x10ce4a[_0x55f240(0x291)])){if(_0x10ce4a[_0x55f240(0x7a8)](_0x10ce4a[_0x55f240(0x866)],_0x10ce4a['DXGMt'])){const _0xb72853=_0x400fdd[_0x55f240(0x3c2)](_0xb898ea=>_0xb898ea[_0x55f240(0x4d0)]===_0x55f240(0x713))[_0x55f240(0x526)],_0x4e56c0=_0x33399d[_0x55f240(0x3c2)](_0x10400f=>_0x10400f[_0x55f240(0x4d0)]===_0x55f240(0x850))[_0x55f240(0x526)];_0x2bafea['log']('\x0a'+'='[_0x55f240(0x552)](0x3c)),_0x189814[_0x55f240(0x61d)]('='[_0x55f240(0x552)](0x3c)+'\x0a');const _0x5187da={};_0x5187da['success']=!![],_0x5187da[_0x55f240(0x239)]=_0x3e4ced,_0x5187da['summary']=_0xb72853+'/'+_0x498409[_0x55f240(0x526)]+_0x55f240(0x34d),SEgHKP['cxdsU'](_0x4c18d7,_0x5187da);}else console[_0x55f240(0x6c8)]('ā ļø\x20WDA\x20Error:\x20'+_0x5e2c6f[_0x55f240(0x685)]());}}),_0x46736a['on'](_0x51bca1[_0xda6d34(0x498)],_0x382309=>{const _0x345461=_0xda6d34;console[_0x345461(0x6c8)](_0x345461(0x5ad)+_0x382309['message']);}),_0x46736a[_0xda6d34(0x214)](),console[_0xda6d34(0x61d)](_0xda6d34(0x4e3));const _0xee8f0d=_0x51bca1[_0xda6d34(0x276)](spawn,_0x51bca1['WZRNX'],[_0x51bca1[_0xda6d34(0x54f)],_0x51bca1[_0xda6d34(0x54f)]],{'detached':!![],'stdio':[_0x51bca1[_0xda6d34(0x817)],'pipe',_0xda6d34(0x6f6)]});_0xee8f0d[_0xda6d34(0x803)]['on'](_0x51bca1[_0xda6d34(0x836)],_0x1f4d87=>{const _0x3a4103=_0xda6d34;console[_0x3a4103(0x61d)]('š\x20iproxy:\x20'+_0x1f4d87[_0x3a4103(0x7de)]()['trim']());}),_0xee8f0d['on'](_0x51bca1[_0xda6d34(0x498)],_0x781d93=>{const _0xedd7b1=_0xda6d34;console[_0xedd7b1(0x6c8)](_0xedd7b1(0x682)+_0x781d93[_0xedd7b1(0x6dc)]),console[_0xedd7b1(0x6c8)](_0xedd7b1(0x32c));}),_0xee8f0d[_0xda6d34(0x214)]();const _0x208be5={};_0x208be5['xcodebuild']=_0x46736a[_0xda6d34(0x64c)],_0x208be5[_0xda6d34(0x7d3)]=_0xee8f0d['pid'],wdaProcesses[_0xda6d34(0x47a)](_0x5c7b29,_0x208be5),console[_0xda6d34(0x61d)](_0xda6d34(0x565)+_0x5c7b29+_0xda6d34(0x2c5)+_0x46736a[_0xda6d34(0x64c)]),setTimeout(()=>{const _0x58b91e=_0xda6d34,_0x14eb22={'zfAol':function(_0x5d5768,_0x4a5781){const _0x4fa0e8=_0x4c0b;return _0x10ce4a[_0x4fa0e8(0x676)](_0x5d5768,_0x4a5781);},'ERKvQ':_0x10ce4a[_0x58b91e(0x5bf)],'SoWOg':_0x10ce4a['FUoAy']},_0x414444=_0x10ce4a[_0x58b91e(0x5b2)](spawn,_0x58b91e(0x48f),['-s',_0x58b91e(0x7c9),'5',_0x58b91e(0x2fd)]);let _0x26c3fc='';_0x414444[_0x58b91e(0x803)]['on'](_0x10ce4a[_0x58b91e(0x292)],_0x33dd87=>{const _0x3a4eb3=_0x58b91e;_0x26c3fc+=_0x33dd87[_0x3a4eb3(0x7de)]();}),_0x414444['on'](_0x10ce4a[_0x58b91e(0x52f)],async()=>{const _0x30f98f=_0x58b91e,_0x2bacf6={'HGkzZ':_0x430810[_0x30f98f(0x72b)],'abZgs':function(_0x565a1f,_0x19f96a){const _0x418d61=_0x30f98f;return _0x430810[_0x418d61(0x220)](_0x565a1f,_0x19f96a);},'EqSfe':function(_0x325ee3,_0x16bf69){const _0x2f8d44=_0x30f98f;return _0x430810[_0x2f8d44(0x220)](_0x325ee3,_0x16bf69);},'DAPLN':function(_0x2c9875,_0x46b8d7){return _0x2c9875(_0x46b8d7);},'gwZCr':_0x430810[_0x30f98f(0x2e9)],'bQdDn':_0x30f98f(0x3a1)};if(_0x26c3fc[_0x30f98f(0x310)](_0x430810[_0x30f98f(0x707)])){if(_0x430810[_0x30f98f(0x6d2)]!==_0x430810[_0x30f98f(0x6d2)]){const _0x2dfc32=_0x58a6d8[_0x30f98f(0x295)](/š\s+([^\[]+?)(?:\s*\[|\s*Label)/);_0x2dfc32&&(_0x473158[_0x30f98f(0x719)]=_0x2dfc32[0x1][_0x30f98f(0x685)](),_0x57fb40[_0x30f98f(0x243)]=_0x2dfc32[0x1][_0x30f98f(0x685)]());const _0x3a6e6d=_0x46634e['match'](/\[([^\]]+)\]/);if(_0x3a6e6d)_0x56aa8b[_0x30f98f(0x4b8)]=_0x3a6e6d[0x1][_0x30f98f(0x685)]();const _0x4a6a0e=_0x4268f7[_0x30f98f(0x295)](/Label:([^\s]+?)(?:\s*Val:|\s*@|\s*ā)/);if(_0x4a6a0e)_0x56f88c[_0x30f98f(0x5f1)]=_0x4a6a0e[0x1]['trim']();const _0x120d8b=_0x3df8da[_0x30f98f(0x295)](/Val:([^\s]+?)(?:\s*@|\s*ā)/);if(_0x120d8b)_0x1578c5[_0x30f98f(0x4d6)]=_0x120d8b[0x1][_0x30f98f(0x685)]();const _0x419630=_0x53290f['match'](/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);if(_0x419630){const _0x1f234a=_0x2bacf6[_0x30f98f(0x23b)]['split']('|');let _0x12045c=0x0;while(!![]){switch(_0x1f234a[_0x12045c++]){case'0':_0x27cd85['height']=_0x2bacf6['abZgs'](_0x4600d3,_0x419630[0x4]);continue;case'1':_0x3dd686[_0x30f98f(0x26d)]='('+_0xab9ab8['x']+','+_0x24d4fa['y']+')\x20'+_0x55431d[_0x30f98f(0x29e)]+'x'+_0x16bf1d['height'];continue;case'2':_0x532f0c['width']=_0x557518(_0x419630[0x3]);continue;case'3':_0x17e8fd['x']=_0x2bacf6[_0x30f98f(0x4ef)](_0x56bd74,_0x419630[0x1]);continue;case'4':_0x39d4a1['y']=_0x2bacf6[_0x30f98f(0x74b)](_0xb0da24,_0x419630[0x2]);continue;}break;}}const _0x27c2b4=_0x287ba8['match'](/ID:([^\s]+)/);if(_0x27c2b4)_0x1b6f88[_0x30f98f(0x8c8)]=_0x27c2b4[0x1]['trim']();_0x485a54[_0x30f98f(0x218)]=_0x1f275c[_0x30f98f(0x310)](_0x2bacf6[_0x30f98f(0x728)]),_0x42589f[_0x30f98f(0x368)]=_0x56a017[_0x30f98f(0x310)](_0x2bacf6[_0x30f98f(0x2b5)]);}else{console[_0x30f98f(0x61d)](_0x30f98f(0x6f1)+_0x5c7b29),console[_0x30f98f(0x61d)](_0x30f98f(0x6d9)+_0x5c7b29+_0x30f98f(0x8cb));const _0x5e1124=await _0x430810[_0x30f98f(0x5b6)](createWDASession,_0x430810[_0x30f98f(0x73a)],_0x5c7b29);_0x5e1124['success']?console[_0x30f98f(0x61d)](_0x30f98f(0x64d)+_0x5e1124[_0x30f98f(0x39b)]):console[_0x30f98f(0x61d)]('ā ļø\x20\x20Session\x20creation\x20failed,\x20will\x20be\x20created\x20on\x20first\x20command');const _0x63b427=connectedDevices[_0x30f98f(0x6c5)](_0x5e2da8=>_0x5e2da8[_0x30f98f(0x719)]===_0x5c7b29);_0x430810[_0x30f98f(0x301)](_0x63b427,-0x1)&&(_0x430810[_0x30f98f(0x6a8)]===_0x430810[_0x30f98f(0x6a8)]?connectedDevices[_0x63b427][_0x30f98f(0x4d0)]=_0x430810[_0x30f98f(0x72c)]:_0x88f563[_0x30f98f(0x884)](_0x60cfbf)),wss[_0x30f98f(0x284)][_0x30f98f(0x68d)](_0x39fdf5=>{const _0x1cc2b7=_0x30f98f;if(_0x14eb22[_0x1cc2b7(0x67a)](_0x39fdf5[_0x1cc2b7(0x24e)],WebSocket[_0x1cc2b7(0x3ba)])){if(_0x14eb22[_0x1cc2b7(0x7a6)]!==_0x14eb22[_0x1cc2b7(0x590)]){const _0x42bc80={};_0x42bc80['type']=_0x1cc2b7(0x33a),_0x42bc80['devices']=connectedDevices,_0x39fdf5[_0x1cc2b7(0x71d)](JSON[_0x1cc2b7(0x33e)](_0x42bc80)),_0x39fdf5[_0x1cc2b7(0x71d)](JSON[_0x1cc2b7(0x33e)]({'type':_0x1cc2b7(0x254),'output':'ā
\x20'+_0x5c7b29+'\x20connected\x20-\x20WDA\x20Ready!\x0a'+'ā'['repeat'](0x32)+'\x0a','device':_0x5c7b29}));}else return{};}});}}else console[_0x30f98f(0x61d)](_0x30f98f(0x6aa)+_0x5c7b29+_0x30f98f(0x8cb));});},0x1f40);const _0x2f9819={};_0x2f9819[_0xda6d34(0x859)]=!![],_0x2f9819[_0xda6d34(0x6dc)]=_0xda6d34(0x79f)+_0x5c7b29+'\x20-\x20Starting\x20WDA...',_0x2f9819[_0xda6d34(0x3cd)]=!![],_0x51bca1['mcAyJ'](_0x3161fe,_0x2f9819);}else{if(_0x430810[_0xda6d34(0x70c)](_0x35de51[_0xda6d34(0x24e)],_0x4c40d0[_0xda6d34(0x3ba)])){const _0x3c8250={};_0x3c8250[_0xda6d34(0x4b8)]='devices_updated',_0x3c8250[_0xda6d34(0x658)]=_0x47e3cd,_0xa27bd8[_0xda6d34(0x71d)](_0x2d3e76[_0xda6d34(0x33e)](_0x3c8250));}}}}}),_0x5253b7['on'](_0x51bca1['GLHkA'],()=>{const _0x432eed=_0x1f759a;console['log'](_0x432eed(0x781));const _0x492684={};_0x492684[_0x432eed(0x859)]=![],_0x492684['message']=_0x432eed(0x5fd),_0x3161fe(_0x492684);});}else{const _0x26ff86={};_0x26ff86[_0x1f759a(0x859)]=!![],_0x26ff86[_0x1f759a(0x3f9)]=_0x5c9831,_0x45d246[_0x1f759a(0x843)](_0x26ff86);}}else{const _0x106547=_0x51bca1[_0x1f759a(0x555)](spawn,'curl',['-s',_0x51bca1['tGRgM'],'3','http://'+_0x105410+':8100/status']);let _0x4267e1='';_0x106547['stdout']['on'](_0x1f759a(0x1da),_0xfba276=>{const _0x4b66a7=_0x1f759a;if(_0x10ce4a[_0x4b66a7(0x68c)]!==_0x10ce4a[_0x4b66a7(0x68c)]){const _0x31a744=_0x5a6bee[_0x4b66a7(0x307)]('.');if(_0x31a744['length']===0x2){const [_0x12156e,_0x19e78a]=_0x31a744;if(!_0x298a50[_0x12156e])_0x6a2dca[_0x12156e]={};_0x556a29[_0x12156e][_0x19e78a]=_0x28a58d;}else{if(!_0x5ef9af[_0x265abf])_0x5ad7de[_0x4ab16e]={};_0x37301f[_0x26865][_0x4b66a7(0x474)]=_0x514620;}}else _0x4267e1+=_0xfba276[_0x4b66a7(0x7de)]();}),_0x106547['on'](_0x51bca1[_0x1f759a(0x252)],async()=>{const _0x11e0e4=_0x1f759a,_0x1adc2b={'BfMfH':function(_0x596ade,_0x1c2fa4){const _0x1865fb=_0x4c0b;return _0x10ce4a[_0x1865fb(0x466)](_0x596ade,_0x1c2fa4);},'XTCvO':function(_0x545ad4,_0x36a584){const _0x1a54d4=_0x4c0b;return _0x10ce4a[_0x1a54d4(0x384)](_0x545ad4,_0x36a584);},'NyLTM':_0x11e0e4(0x708),'MJWfv':function(_0x1041cb,_0x7f1917){return _0x1041cb(_0x7f1917);},'nshtX':_0x10ce4a[_0x11e0e4(0x51c)],'mmXkS':_0x11e0e4(0x2f6),'xGmZa':_0x10ce4a[_0x11e0e4(0x1f2)],'XCgjo':_0x11e0e4(0x6b5),'elqaz':_0x10ce4a['uhMqN'],'ZnqYK':function(_0x107be9,_0x2c50b0,_0x46fe3b){const _0x220bc5=_0x11e0e4;return _0x10ce4a[_0x220bc5(0x7d8)](_0x107be9,_0x2c50b0,_0x46fe3b);},'LEvsV':_0x10ce4a['qCPLE'],'WvgWj':'online','ovQvT':_0x10ce4a[_0x11e0e4(0x46a)],'XYnAV':_0x10ce4a[_0x11e0e4(0x292)]};if(_0x4267e1[_0x11e0e4(0x310)](_0x10ce4a[_0x11e0e4(0x647)])){console[_0x11e0e4(0x61d)](_0x11e0e4(0x512)+_0x5c7b29),console[_0x11e0e4(0x61d)](_0x11e0e4(0x6d9)+_0x5c7b29+'...');const _0x31dfec=await _0x10ce4a[_0x11e0e4(0x535)](createWDASession,_0x105410,_0x5c7b29);_0x31dfec[_0x11e0e4(0x859)]?console[_0x11e0e4(0x61d)]('ā
\x20Session\x20created:\x20'+_0x31dfec[_0x11e0e4(0x39b)]):console[_0x11e0e4(0x61d)](_0x11e0e4(0x657));const _0x37a2da=connectedDevices[_0x11e0e4(0x6c5)](_0x553e65=>_0x553e65[_0x11e0e4(0x719)]===_0x5c7b29);_0x37a2da!==-0x1&&(connectedDevices[_0x37a2da][_0x11e0e4(0x4d0)]=_0x10ce4a[_0x11e0e4(0x264)]);wss['clients'][_0x11e0e4(0x68d)](_0x41cceb=>{const _0x41a84d=_0x11e0e4;if(_0x41cceb[_0x41a84d(0x24e)]===WebSocket['OPEN']){const _0x4cb2a6={};_0x4cb2a6['type']=_0x10ce4a[_0x41a84d(0x33d)],_0x4cb2a6[_0x41a84d(0x658)]=connectedDevices,_0x41cceb[_0x41a84d(0x71d)](JSON['stringify'](_0x4cb2a6));}});const _0x2cfcf0={};_0x2cfcf0[_0x11e0e4(0x859)]=!![],_0x2cfcf0['message']=_0x11e0e4(0x605)+_0x5c7b29+_0x11e0e4(0x579),_0x10ce4a[_0x11e0e4(0x1ff)](_0x3161fe,_0x2cfcf0);}else{console['log'](_0x11e0e4(0x28b)+_0x5c7b29+',\x20attempting\x20to\x20start...');const _0x135fca=process.env.WDA_PATH||path[_0x11e0e4(0x5c8)](process.env.HOME,_0x10ce4a[_0x11e0e4(0x827)]);console[_0x11e0e4(0x61d)](_0x11e0e4(0x5d7)+_0x135fca),console['log']('š±\x20Device\x20UDID:\x20'+_0x240b88),console[_0x11e0e4(0x61d)](_0x11e0e4(0x367)+_0x105410);const _0x228659=_0x10ce4a[_0x11e0e4(0x6bc)](spawn,_0x10ce4a[_0x11e0e4(0x61e)],[_0x10ce4a[_0x11e0e4(0x6d7)],_0x11e0e4(0x436),path[_0x11e0e4(0x5c8)](_0x135fca,_0x10ce4a[_0x11e0e4(0x7c0)]),_0x11e0e4(0x46b),_0x10ce4a[_0x11e0e4(0x806)],_0x10ce4a[_0x11e0e4(0x4c0)],'id='+_0x240b88,_0x10ce4a[_0x11e0e4(0x5a0)]],{'cwd':_0x135fca,'detached':!![],'stdio':[_0x10ce4a['FgpwJ'],_0x10ce4a[_0x11e0e4(0x7c6)],_0x11e0e4(0x6f6)]});_0x228659[_0x11e0e4(0x803)]['on'](_0x11e0e4(0x1da),_0x3fc54b=>{const _0x13d2b4=_0x11e0e4,_0x3c0016={'OrWFY':function(_0x2bef6a,_0x485910){const _0x55e960=_0x4c0b;return _0x1adc2b[_0x55e960(0x56d)](_0x2bef6a,_0x485910);},'GDwwn':_0x13d2b4(0x33a),'HHdyp':function(_0x16c65c,_0x500257){const _0x47baa5=_0x13d2b4;return _0x1adc2b[_0x47baa5(0x230)](_0x16c65c,_0x500257);},'lAvcb':_0x1adc2b[_0x13d2b4(0x734)],'DjWCn':function(_0x16e388,_0x2349fe){const _0x217a5d=_0x13d2b4;return _0x1adc2b[_0x217a5d(0x829)](_0x16e388,_0x2349fe);}};if(_0x1adc2b[_0x13d2b4(0x230)](_0x1adc2b[_0x13d2b4(0x69a)],_0x1adc2b[_0x13d2b4(0x69a)])){const _0x4d54bf={'nFPgp':function(_0x5ca8d8,_0x153fa4){const _0x2f224d=_0x13d2b4;return _0x3c0016[_0x2f224d(0x2bb)](_0x5ca8d8,_0x153fa4);},'QTGWy':_0x3c0016[_0x13d2b4(0x7cf)]},_0x8f6b0e=_0x480be4[_0x13d2b4(0x6c5)](_0x29bfa3=>_0x29bfa3[_0x13d2b4(0x719)]===_0x520468);_0x3c0016[_0x13d2b4(0x6d4)](_0x8f6b0e,-0x1)&&(_0x56151e[_0x8f6b0e][_0x13d2b4(0x4d0)]=_0x3c0016['lAvcb']);_0x486f8d[_0x13d2b4(0x284)]['forEach'](_0x24b95c=>{const _0x17da0a=_0x13d2b4;if(_0x4d54bf[_0x17da0a(0x343)](_0x24b95c['readyState'],_0x202672['OPEN'])){const _0x6f3850={};_0x6f3850[_0x17da0a(0x4b8)]=_0x4d54bf[_0x17da0a(0x891)],_0x6f3850['devices']=_0x7cb54e,_0x24b95c[_0x17da0a(0x71d)](_0xc188ac[_0x17da0a(0x33e)](_0x6f3850));}}),_0x179c5b[_0x13d2b4(0x61d)](_0x13d2b4(0x599)+_0x1dcd8f);const _0x397b9b={};_0x397b9b[_0x13d2b4(0x859)]=!![],_0x397b9b[_0x13d2b4(0x6dc)]='Disconnected\x20from\x20'+_0x2e682f+'\x20-\x20WDA\x20stopped',_0x3c0016[_0x13d2b4(0x598)](_0x2a9e78,_0x397b9b);}else{const _0x389076=_0x3fc54b[_0x13d2b4(0x7de)]();(_0x389076[_0x13d2b4(0x310)](_0x1adc2b['mmXkS'])||_0x389076[_0x13d2b4(0x310)](_0x1adc2b[_0x13d2b4(0x3c7)]))&&console[_0x13d2b4(0x61d)](_0x13d2b4(0x25f)+_0x5c7b29+'):\x20'+_0x389076['trim']());}}),_0x228659[_0x11e0e4(0x3ec)]['on'](_0x10ce4a[_0x11e0e4(0x292)],_0x304c0f=>{const _0x23e570=_0x11e0e4,_0x43dc6d={'bQdxR':function(_0x5591fd){return _0x10ce4a['bJBej'](_0x5591fd);}};if(_0x10ce4a[_0x23e570(0x406)](_0x10ce4a[_0x23e570(0x4fb)],_0x10ce4a['ItftN']))_0x43dc6d[_0x23e570(0x6f7)](_0x10dcc0)[_0x23e570(0x795)](_0x31db1c=>{const _0x306df8=_0x23e570;_0x234a12[_0x306df8(0x6c8)](_0x306df8(0x779),_0x31db1c),_0x5698fa[_0x306df8(0x699)](0x1);});else{const _0x2b6030=_0x304c0f['toString']();!_0x2b6030[_0x23e570(0x310)]('note:')&&!_0x2b6030[_0x23e570(0x310)](_0x10ce4a[_0x23e570(0x291)])&&console[_0x23e570(0x6c8)](_0x23e570(0x248)+_0x5c7b29+_0x23e570(0x7ee)+_0x2b6030['trim']());}}),_0x228659['on'](_0x11e0e4(0x6c8),_0xd98127=>{const _0x5e210a=_0x11e0e4,_0x278529={};_0x278529[_0x5e210a(0x347)]=_0x5e210a(0x254);const _0x52db6e=_0x278529;if(_0x10ce4a['tGQzl'](_0x10ce4a[_0x5e210a(0x5ee)],_0x10ce4a[_0x5e210a(0x853)])){const _0xea0389={};_0xea0389[_0x5e210a(0x4b8)]=_0x52db6e['vnFXA'],_0xea0389[_0x5e210a(0x1da)]='ā
\x20Completed\x20successfully\x0a\x0a',_0xea0389[_0x5e210a(0x658)]=_0x130005,_0x16ad75[_0x5e210a(0x71d)](_0x214799[_0x5e210a(0x33e)](_0xea0389));}else console[_0x5e210a(0x6c8)](_0x5e210a(0x60f)+_0x5c7b29+':\x20'+_0xd98127['message']);}),_0x228659[_0x11e0e4(0x214)]();const _0x5015d0={};_0x5015d0[_0x11e0e4(0x280)]=_0x228659['pid'],wdaProcesses[_0x11e0e4(0x47a)](_0x5c7b29,_0x5015d0),console['log'](_0x11e0e4(0x565)+_0x5c7b29+_0x11e0e4(0x202)+_0x228659['pid']),setTimeout(()=>{const _0x13b220=_0x11e0e4,_0x5bf183={'fcjki':function(_0x2bd102,_0x1adfc9){const _0x381dec=_0x4c0b;return _0x1adc2b[_0x381dec(0x56d)](_0x2bd102,_0x1adfc9);},'cittz':_0x13b220(0x693),'tEkxf':_0x1adc2b[_0x13b220(0x6b3)],'xjhIk':_0x1adc2b[_0x13b220(0x878)],'JfClF':function(_0x307f27,_0x71d592,_0x64ca96){const _0x44bf18=_0x13b220;return _0x1adc2b[_0x44bf18(0x709)](_0x307f27,_0x71d592,_0x64ca96);},'epxTZ':function(_0x2bf70a,_0x186c91){return _0x2bf70a!==_0x186c91;},'lSnma':_0x1adc2b['LEvsV'],'AWXNp':_0x1adc2b[_0x13b220(0x818)]},_0x937f0a=_0x1adc2b['ZnqYK'](spawn,_0x13b220(0x48f),['-s',_0x1adc2b[_0x13b220(0x3c3)],'5',_0x13b220(0x81b)+_0x105410+':8100/status']);let _0x6d7747='';_0x937f0a[_0x13b220(0x803)]['on'](_0x1adc2b['XYnAV'],_0x1b0a98=>{const _0x502c0d=_0x13b220;_0x6d7747+=_0x1b0a98[_0x502c0d(0x7de)]();}),_0x937f0a['on']('close',async()=>{const _0x1cb8ec=_0x13b220;if(_0x6d7747[_0x1cb8ec(0x310)](_0x5bf183[_0x1cb8ec(0x825)])){console['log'](_0x1cb8ec(0x6f1)+_0x5c7b29),console[_0x1cb8ec(0x61d)](_0x1cb8ec(0x6d9)+_0x5c7b29+'...');const _0x244831=await _0x5bf183['JfClF'](createWDASession,_0x105410,_0x5c7b29);_0x244831[_0x1cb8ec(0x859)]?console['log']('ā
\x20Session\x20created:\x20'+_0x244831[_0x1cb8ec(0x39b)]):console[_0x1cb8ec(0x61d)](_0x1cb8ec(0x657));const _0x2b2931=connectedDevices['findIndex'](_0x37edfe=>_0x37edfe['name']===_0x5c7b29);if(_0x5bf183[_0x1cb8ec(0x80c)](_0x2b2931,-0x1)){if(_0x5bf183[_0x1cb8ec(0x20d)]===_0x1cb8ec(0x7a4))connectedDevices[_0x2b2931][_0x1cb8ec(0x4d0)]=_0x5bf183[_0x1cb8ec(0x725)];else{_0xa5945[_0x1cb8ec(0x6c8)](_0x1cb8ec(0x667),_0x3fcbf0[_0x1cb8ec(0x6dc)]);const _0xe986a4={};_0xe986a4[_0x1cb8ec(0x6c8)]=_0x1cb8ec(0x5f2)+_0x40bd0d[_0x1cb8ec(0x6dc)],_0x3282b6=[_0xe986a4];}}wss[_0x1cb8ec(0x284)][_0x1cb8ec(0x68d)](_0x2aecc8=>{const _0x16737d=_0x1cb8ec;if(_0x5bf183['fcjki'](_0x5bf183['cittz'],_0x5bf183[_0x16737d(0x2ff)]))_0xe171e9[_0x16737d(0x61d)](_0x16737d(0x64d)+_0x1290b0[_0x16737d(0x39b)]);else{if(_0x5bf183[_0x16737d(0x45e)](_0x2aecc8[_0x16737d(0x24e)],WebSocket[_0x16737d(0x3ba)])){const _0x4d3505={};_0x4d3505[_0x16737d(0x4b8)]='devices_updated',_0x4d3505[_0x16737d(0x658)]=connectedDevices,_0x2aecc8['send'](JSON[_0x16737d(0x33e)](_0x4d3505));}}});const _0x3e63b5={};_0x3e63b5['success']=!![],_0x3e63b5[_0x1cb8ec(0x6dc)]=_0x1cb8ec(0x605)+_0x5c7b29+_0x1cb8ec(0x8b9),_0x3e63b5['wdaStarted']=!![],_0x3161fe(_0x3e63b5);}else{console[_0x1cb8ec(0x61d)](_0x1cb8ec(0x594)+_0x5c7b29+',\x20may\x20take\x20a\x20moment...');const _0x37245b={};_0x37245b[_0x1cb8ec(0x859)]=!![],_0x37245b[_0x1cb8ec(0x6dc)]='WDA\x20is\x20starting\x20for\x20'+_0x5c7b29+_0x1cb8ec(0x28a),_0x37245b[_0x1cb8ec(0x3cd)]=!![],_0x3161fe(_0x37245b);}});},0x2710);}}),_0x106547['on'](_0x51bca1['GLHkA'],()=>{const _0x218b65=_0x1f759a;console[_0x218b65(0x61d)](_0x218b65(0x2e3)+_0x5c7b29+'\x20at\x20'+_0x105410+_0x218b65(0x4c9));const _0x116b93={};_0x116b93[_0x218b65(0x859)]=![],_0x116b93[_0x218b65(0x6dc)]=_0x218b65(0x4f9)+_0x5c7b29+_0x218b65(0x752)+_0x105410+'.\x20Check\x20network\x20connection.',_0x10ce4a[_0x218b65(0x563)](_0x2281c2,_0x116b93);});}});}async function disconnectFromDevice(_0x2a92b6){const _0x503d70=_0x47c41d,_0x16333e={'rsial':function(_0x399479,_0x5777ac){return _0x399479!==_0x5777ac;},'IoVaq':_0x503d70(0x708),'ZfGWu':function(_0x36c9f2,_0x39c7e1){return _0x36c9f2(_0x39c7e1);},'UZVyg':_0x503d70(0x5db),'IjOdf':function(_0x4348c5,_0x1adc74){return _0x4348c5===_0x1adc74;},'tGZwC':function(_0x47ea5b,_0x56b6a5){return _0x47ea5b!==_0x56b6a5;},'lkydw':function(_0x4621af,_0x487025){return _0x4621af===_0x487025;},'WMbLL':_0x503d70(0x33a),'VhOHU':function(_0x33ec84,_0x1f9a6f){return _0x33ec84===_0x1f9a6f;},'TRQQV':_0x503d70(0x580),'AsFKY':_0x503d70(0x366),'qGZvk':_0x503d70(0x62d),'VKchH':function(_0x3ee6d2,_0x3192a8){return _0x3ee6d2(_0x3192a8);},'hoNgn':function(_0x157a1f,_0x1f86a0){return _0x157a1f!==_0x1f86a0;},'RReGA':'ZBSjP','gIHXN':_0x503d70(0x61b),'WmjSl':_0x503d70(0x705),'uARdK':function(_0x1b34b2,_0x4579e7,_0xeb82df){return _0x1b34b2(_0x4579e7,_0xeb82df);},'QPnZh':function(_0x2baaf1,_0x25087b){return _0x2baaf1===_0x25087b;},'yNIpb':_0x503d70(0x501),'ganCH':_0x503d70(0x229),'KVeXg':function(_0x6cbc01,_0xa95b39){return _0x6cbc01===_0xa95b39;},'iuasF':_0x503d70(0x319),'XgXlo':'SIGTERM','RuIqT':function(_0x45c825,_0x150261,_0x494740){return _0x45c825(_0x150261,_0x494740);},'xvNqa':_0x503d70(0x884),'gwCJY':function(_0x1116f3,_0x700018){return _0x1116f3===_0x700018;},'DDEsQ':_0x503d70(0x760),'VmzQU':'HZFxa','BNZiv':function(_0x2cb325,_0x4cba28){return _0x2cb325!==_0x4cba28;},'pZGhS':_0x503d70(0x61c)};return new Promise((_0x1db5d9,_0x370306)=>{const _0x3925b6=_0x503d70,_0x22c701={'VaDvv':function(_0x24ab54,_0x337662){const _0xc53b13=_0x4c0b;return _0x16333e[_0xc53b13(0x717)](_0x24ab54,_0x337662);},'cfyRJ':function(_0x4c394e,_0xd639eb){return _0x16333e['tGZwC'](_0x4c394e,_0xd639eb);},'QFNlq':'owbXb','RoJlf':function(_0x34642a,_0x2af74a){const _0x27fe8e=_0x4c0b;return _0x16333e[_0x27fe8e(0x5dc)](_0x34642a,_0x2af74a);},'QUglz':_0x16333e[_0x3925b6(0x2f2)],'UqVxD':function(_0x345706,_0x27f1a3){const _0x3d63fb=_0x3925b6;return _0x16333e[_0x3d63fb(0x5dc)](_0x345706,_0x27f1a3);},'olUCl':function(_0x345c93,_0x34e8db){return _0x16333e['VhOHU'](_0x345c93,_0x34e8db);},'PVcxo':_0x16333e['TRQQV'],'iwSbT':_0x16333e[_0x3925b6(0x7a9)],'nuLxt':function(_0x39a02d,_0x1ef7dc){const _0x1ecd49=_0x3925b6;return _0x16333e[_0x1ecd49(0x717)](_0x39a02d,_0x1ef7dc);},'StiQb':function(_0x36cbab,_0x2bca0e){return _0x36cbab===_0x2bca0e;},'gdFHQ':_0x16333e[_0x3925b6(0x637)],'aRBhY':_0x16333e['IoVaq'],'OBHGA':function(_0x57870d,_0x5495e3){const _0x42b2e0=_0x3925b6;return _0x16333e[_0x42b2e0(0x4aa)](_0x57870d,_0x5495e3);}};if(_0x16333e['hoNgn'](_0x16333e['RReGA'],_0x16333e['gIHXN'])){const {name:_0x1bb0cc,connectionType:_0x40c924,udid:_0x32fd2c,platform:_0x4745a8}=_0x2a92b6;console[_0x3925b6(0x61d)](_0x3925b6(0x41b)+_0x1bb0cc+'\x20('+_0x40c924+_0x3925b6(0x20f)+_0x4745a8+')...');if(_0x16333e[_0x3925b6(0x5dc)](_0x4745a8,_0x16333e[_0x3925b6(0x740)])){console['log']('š±\x20Android\x20device\x20disconnect:\x20'+_0x1bb0cc),_0x16333e[_0x3925b6(0x87c)](stopUIAutomator2Session,_0x32fd2c,_0x1bb0cc)[_0x3925b6(0x795)](_0x1da56c=>{const _0x195837=_0x3925b6;console['error'](_0x195837(0x6a9)+_0x1da56c[_0x195837(0x6dc)]);});if(_0x16333e[_0x3925b6(0x8bb)](_0x40c924,_0x16333e[_0x3925b6(0x7e9)])){const _0x27eff5=_0x16333e[_0x3925b6(0x87c)](spawn,_0x16333e[_0x3925b6(0x89e)],['disconnect',_0x32fd2c]);_0x27eff5['on'](_0x3925b6(0x884),_0x5cb771=>{const _0x5563e3=_0x3925b6;console[_0x5563e3(0x61d)](_0x5563e3(0x6fb)+_0x1bb0cc+_0x5563e3(0x3c0));const _0x145ccb=connectedDevices[_0x5563e3(0x6c5)](_0x4c92c5=>_0x4c92c5['name']===_0x1bb0cc);_0x16333e[_0x5563e3(0x45a)](_0x145ccb,-0x1)&&(connectedDevices[_0x145ccb][_0x5563e3(0x4d0)]=_0x16333e[_0x5563e3(0x4a4)]);wss[_0x5563e3(0x284)][_0x5563e3(0x68d)](_0x502625=>{const _0x4c46d5=_0x5563e3,_0x1a723b={};_0x1a723b['TeTCE']=_0x4c46d5(0x5ca);const _0x3d1610=_0x1a723b;if(_0x22c701[_0x4c46d5(0x840)](_0x502625['readyState'],WebSocket[_0x4c46d5(0x3ba)])){if(_0x22c701[_0x4c46d5(0x4ac)](_0x22c701['QFNlq'],_0x4c46d5(0x644))){const _0x3752f3={};_0x3752f3['type']='devices_updated',_0x3752f3[_0x4c46d5(0x658)]=connectedDevices,_0x502625[_0x4c46d5(0x71d)](JSON['stringify'](_0x3752f3));}else{_0x65f37b[_0x4c46d5(0x6c8)](_0x3d1610[_0x4c46d5(0x547)],_0x274765);const _0x355f1a={};_0x355f1a[_0x4c46d5(0x859)]=![],_0x355f1a[_0x4c46d5(0x6c8)]=_0x47556a[_0x4c46d5(0x6dc)],_0x21403b['status'](0x1f4)['json'](_0x355f1a);}}});const _0x5d8ad4={};_0x5d8ad4[_0x5563e3(0x859)]=!![],_0x5d8ad4[_0x5563e3(0x6dc)]=_0x5563e3(0x868)+_0x1bb0cc+_0x5563e3(0x454),_0x16333e[_0x5563e3(0x63c)](_0x1db5d9,_0x5d8ad4);});}else{const _0x75ee83=connectedDevices[_0x3925b6(0x6c5)](_0x503088=>_0x503088[_0x3925b6(0x719)]===_0x1bb0cc);_0x75ee83!==-0x1&&(connectedDevices[_0x75ee83][_0x3925b6(0x4d0)]=_0x3925b6(0x708));wss[_0x3925b6(0x284)][_0x3925b6(0x68d)](_0x1bc843=>{const _0x159bcc=_0x3925b6;if(_0x1bc843['readyState']===WebSocket[_0x159bcc(0x3ba)]){if(_0x22c701[_0x159bcc(0x8b1)](_0x159bcc(0x3f4),'Gmocq'))_0x57e4bf['error'](_0x159bcc(0x779),_0x34f6ec),_0x29a411[_0x159bcc(0x699)](0x1);else{const _0xaa8456={};_0xaa8456['type']=_0x22c701[_0x159bcc(0x28e)],_0xaa8456[_0x159bcc(0x658)]=connectedDevices,_0x1bc843[_0x159bcc(0x71d)](JSON[_0x159bcc(0x33e)](_0xaa8456));}}});const _0x1a0736={};_0x1a0736['success']=!![],_0x1a0736['message']=_0x3925b6(0x868)+_0x1bb0cc,_0x16333e[_0x3925b6(0x63c)](_0x1db5d9,_0x1a0736);}return;}const _0x1d54fd=connectedDevices[_0x3925b6(0x715)](_0x571e93=>_0x571e93[_0x3925b6(0x719)]===_0x1bb0cc),_0x2786ad=_0x1d54fd?.[_0x3925b6(0x6c2)];if(wdaProcesses[_0x3925b6(0x5d8)](_0x1bb0cc)){const _0x9d77b6=wdaProcesses[_0x3925b6(0x3ac)](_0x1bb0cc);try{if(_0x9d77b6[_0x3925b6(0x280)]){if(_0x16333e[_0x3925b6(0x443)](_0x16333e['iuasF'],_0x16333e[_0x3925b6(0x401)]))try{process['kill'](_0x9d77b6[_0x3925b6(0x280)],_0x3925b6(0x83f)),console[_0x3925b6(0x61d)](_0x3925b6(0x2e4)+_0x1bb0cc+_0x3925b6(0x441)+_0x9d77b6[_0x3925b6(0x280)]+')');}catch(_0x34747e){console['log'](_0x3925b6(0x71a)+_0x9d77b6[_0x3925b6(0x280)]+_0x3925b6(0x288));}else _0x2621e2['sessionId']=_0x3c461d['sessionId'];}if(_0x9d77b6['iproxy'])try{process[_0x3925b6(0x510)](_0x9d77b6['iproxy'],_0x16333e[_0x3925b6(0x737)]),console['log']('ā
\x20Killed\x20iproxy\x20for\x20'+_0x1bb0cc+_0x3925b6(0x441)+_0x9d77b6['iproxy']+')');}catch(_0x5f1ae5){console[_0x3925b6(0x61d)](_0x3925b6(0x82c)+_0x9d77b6[_0x3925b6(0x7d3)]+_0x3925b6(0x288));}wdaProcesses['delete'](_0x1bb0cc);}catch(_0x55dafc){console[_0x3925b6(0x6c8)](_0x3925b6(0x58b)+_0x1bb0cc+':',_0x55dafc);}}if(_0x2786ad){console[_0x3925b6(0x61d)]('š\x20Killing\x20processes\x20on\x20port\x20'+_0x2786ad+_0x3925b6(0x298)+_0x1bb0cc+_0x3925b6(0x8cb));const _0x183afe=_0x16333e[_0x3925b6(0x6b7)](spawn,'sh',['-c',_0x3925b6(0x4e8)+_0x2786ad+'\x20|\x20xargs\x20kill\x20-9\x202>/dev/null\x20||\x20true']);_0x183afe['on'](_0x16333e[_0x3925b6(0x47e)],()=>{const _0x547eec=_0x3925b6;if(_0x16333e['UZVyg']!==_0x547eec(0x5db)){const _0x3582e5={};_0x3582e5[_0x547eec(0x859)]=![],_0x3582e5[_0x547eec(0x6c8)]=_0x339546[_0x547eec(0x6dc)],_0x185688[_0x547eec(0x4d0)](0x1f4)['json'](_0x3582e5);}else console[_0x547eec(0x61d)](_0x547eec(0x6b0)+_0x2786ad+_0x547eec(0x298)+_0x1bb0cc);});}if(_0x32fd2c&&_0x16333e[_0x3925b6(0x1f7)](_0x40c924,_0x16333e[_0x3925b6(0x37c)])){if(_0x16333e[_0x3925b6(0x612)]===_0x16333e[_0x3925b6(0x612)]){console[_0x3925b6(0x61d)](_0x3925b6(0x79b)+_0x32fd2c+_0x3925b6(0x8cb));const _0x1c6d98=spawn('sh',['-c',_0x3925b6(0x478)+_0x32fd2c+_0x3925b6(0x5ab)]);_0x1c6d98['on'](_0x3925b6(0x884),()=>{const _0x662a63=_0x3925b6;console[_0x662a63(0x61d)]('ā
\x20Cleaned\x20up\x20WDA\x20processes\x20for\x20'+_0x1bb0cc);});}else{_0x887276[_0x3925b6(0x61d)]('ā
\x20New\x20session\x20created\x20and\x20saved:\x20'+_0x172a32);const _0x924d19={};_0x924d19['success']=!![],_0x924d19[_0x3925b6(0x39b)]=_0x46e97c,_0x54dc76(_0x924d19);}}if(_0x40c924===_0x16333e[_0x3925b6(0x37c)]&&_0x2786ad){if(_0x16333e[_0x3925b6(0x354)](_0x16333e[_0x3925b6(0x87d)],_0x16333e[_0x3925b6(0x87d)]))_0x5049da[_0x3925b6(0x719)]=_0x52c8e2[0x1]['trim'](),_0x2a32cb[_0x3925b6(0x243)]=_0x2800a8[0x1][_0x3925b6(0x685)]();else{const _0x3d57a1=_0x16333e[_0x3925b6(0x87c)](spawn,'sh',['-c',_0x3925b6(0x51f)+_0x2786ad+'\x22\x20||\x20true']);_0x3d57a1['on'](_0x16333e['xvNqa'],()=>{const _0x5ec1d2=_0x3925b6;if(_0x22c701[_0x5ec1d2(0x50a)](_0x22c701[_0x5ec1d2(0x34a)],_0x22c701[_0x5ec1d2(0x687)])){if(ZavzQq['UqVxD'](_0x2fd70e[_0x5ec1d2(0x24e)],_0x56bee4[_0x5ec1d2(0x3ba)])){const _0x52d610={};_0x52d610[_0x5ec1d2(0x4b8)]=ZavzQq['QUglz'],_0x52d610[_0x5ec1d2(0x658)]=_0x192790,_0x5efe4c[_0x5ec1d2(0x71d)](_0x272f2b[_0x5ec1d2(0x33e)](_0x52d610));}}else console['log']('ā
\x20Cleaned\x20up\x20iproxy\x20for\x20'+_0x1bb0cc);});}}setTimeout(()=>{const _0x15387b=_0x3925b6,_0x25f6cf=connectedDevices[_0x15387b(0x6c5)](_0xa11bd2=>_0xa11bd2[_0x15387b(0x719)]===_0x1bb0cc);_0x22c701[_0x15387b(0x4ac)](_0x25f6cf,-0x1)&&(connectedDevices[_0x25f6cf][_0x15387b(0x4d0)]=_0x22c701[_0x15387b(0x2fb)]);wss[_0x15387b(0x284)][_0x15387b(0x68d)](_0x215c57=>{const _0x5f33ed=_0x15387b;if(_0x22c701[_0x5f33ed(0x513)](_0x215c57[_0x5f33ed(0x24e)],WebSocket['OPEN'])){if(_0x22c701[_0x5f33ed(0x3af)](_0x22c701[_0x5f33ed(0x570)],_0x22c701[_0x5f33ed(0x570)])){const _0x58353a={};_0x58353a[_0x5f33ed(0x4b8)]=_0x5f33ed(0x33a),_0x58353a[_0x5f33ed(0x658)]=connectedDevices,_0x215c57['send'](JSON[_0x5f33ed(0x33e)](_0x58353a));}else{_0x4e1ea4['error'](_0x5f33ed(0x6c0)+_0x1ab74b[_0x5f33ed(0x6dc)]);const _0x55a766={};_0x55a766[_0x5f33ed(0x4b8)]=_0x5f33ed(0x5e4),_0x55a766[_0x5f33ed(0x6c8)]=_0x23a9d0[_0x5f33ed(0x6dc)],_0x300f50[_0x5f33ed(0x71d)](_0x1a0500['stringify'](_0x55a766));}}}),console['log'](_0x15387b(0x599)+_0x1bb0cc);const _0x1db61c={};_0x1db61c[_0x15387b(0x859)]=!![],_0x1db61c['message']=_0x15387b(0x868)+_0x1bb0cc+'\x20-\x20WDA\x20stopped',_0x22c701[_0x15387b(0x479)](_0x1db5d9,_0x1db61c);},0x1f4);}else{_0x3afee1['error']('Error\x20loading\x20recording\x20'+_0x53aacf+':',_0x33a2da);throw _0xb80964;}});}async function ensureRecordingsDir(){const _0x3d271f=_0x47c41d,_0x48fae1={};_0x48fae1['payPd']=function(_0x1cd634,_0x5a48ba){return _0x1cd634+_0x5a48ba;},_0x48fae1[_0x3d271f(0x485)]=_0x3d271f(0x254),_0x48fae1[_0x3d271f(0x80b)]=function(_0x125ba8,_0x2aee05){return _0x125ba8===_0x2aee05;},_0x48fae1[_0x3d271f(0x393)]='bSdQg';const _0x31bea8=_0x48fae1;try{await fs['access'](RECORDINGS_DIR);}catch{if(_0x31bea8[_0x3d271f(0x80b)](_0x31bea8['tGeMW'],_0x31bea8[_0x3d271f(0x393)])){const _0x29a442={};_0x29a442[_0x3d271f(0x290)]=!![],await fs[_0x3d271f(0x2ad)](RECORDINGS_DIR,_0x29a442);}else{_0x103fd2[_0x3d271f(0x6c8)](_0x3d271f(0x39f)+_0x31bea8[_0x3d271f(0x477)](_0x140057,0x1)+'\x20failed:',_0x16e27f['message']);const _0x1cd7e9={};_0x1cd7e9[_0x3d271f(0x582)]=_0xf60828,_0x1cd7e9['success']=![],_0x1cd7e9[_0x3d271f(0x6c8)]=_0x16a509['message'],_0x11492c[_0x3d271f(0x823)](_0x1cd7e9);if(_0x11b1d7){const _0x3652c1={};_0x3652c1[_0x3d271f(0x4b8)]=_0x31bea8['dynRw'],_0x3652c1[_0x3d271f(0x1da)]=_0x3d271f(0x34e)+_0x3a6f45['message']+'\x0a\x0a',_0x3652c1[_0x3d271f(0x658)]=_0x35d9f3,_0x4680d3['send'](_0x6e7b7a[_0x3d271f(0x33e)](_0x3652c1));}}}}async function startRecording(_0x9e4850,_0x99237f){const _0x3c5d44=_0x47c41d,_0x10a627={'VIqhB':_0x3c5d44(0x3ab),'yfIzC':function(_0x2292ba){return _0x2292ba();}},_0x5b6a16=_0x10a627['VIqhB'][_0x3c5d44(0x307)]('|');let _0x11cd6c=0x0;while(!![]){switch(_0x5b6a16[_0x11cd6c++]){case'0':console[_0x3c5d44(0x61d)]('š“\x20Recording\x20started:\x20'+currentRecording[_0x3c5d44(0x719)]);continue;case'1':isRecording=!![];continue;case'2':const _0x17bc62={};_0x17bc62[_0x3c5d44(0x859)]=!![],_0x17bc62[_0x3c5d44(0x533)]=currentRecording;return _0x17bc62;case'3':currentRecording={'name':_0x9e4850||_0x3c5d44(0x81a)+Date[_0x3c5d44(0x3f7)](),'devices':_0x99237f||[],'commands':[],'startTime':new Date()[_0x3c5d44(0x7f5)]()};continue;case'4':await _0x10a627['yfIzC'](ensureRecordingsDir);continue;}break;}}function _0x4c0b(_0x104683,_0x26ed02){_0x104683=_0x104683-0x1d9;const _0x3d34c0=_0x3d34();let _0x4c0bc4=_0x3d34c0[_0x104683];if(_0x4c0b['qTiWPS']===undefined){var _0x5e358c=function(_0x5e7a93){const _0x22abd2='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x3719e0='',_0x21862d='';for(let _0x2d6363=0x0,_0x2cdd6c,_0x4a9d94,_0x59d8aa=0x0;_0x4a9d94=_0x5e7a93['charAt'](_0x59d8aa++);~_0x4a9d94&&(_0x2cdd6c=_0x2d6363%0x4?_0x2cdd6c*0x40+_0x4a9d94:_0x4a9d94,_0x2d6363++%0x4)?_0x3719e0+=String['fromCharCode'](0xff&_0x2cdd6c>>(-0x2*_0x2d6363&0x6)):0x0){_0x4a9d94=_0x22abd2['indexOf'](_0x4a9d94);}for(let _0x4d8926=0x0,_0x275e3a=_0x3719e0['length'];_0x4d8926<_0x275e3a;_0x4d8926++){_0x21862d+='%'+('00'+_0x3719e0['charCodeAt'](_0x4d8926)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x21862d);};_0x4c0b['Mhtnbu']=_0x5e358c,_0x4c0b['irmZCe']={},_0x4c0b['qTiWPS']=!![];}const _0x54e794=_0x3d34c0[0x0],_0x3a200f=_0x104683+_0x54e794,_0x183e64=_0x4c0b['irmZCe'][_0x3a200f];return!_0x183e64?(_0x4c0bc4=_0x4c0b['Mhtnbu'](_0x4c0bc4),_0x4c0b['irmZCe'][_0x3a200f]=_0x4c0bc4):_0x4c0bc4=_0x183e64,_0x4c0bc4;}function recordCommand(_0x2997c5,_0x3935c5,_0x5c5073,_0x1843e9){const _0x4ba626=_0x47c41d,_0x1bf824={};_0x1bf824[_0x4ba626(0x511)]=function(_0x4fe1e9,_0x5087f2){return _0x4fe1e9||_0x5087f2;};const _0x446a63=_0x1bf824;if(_0x446a63[_0x4ba626(0x511)](!isRecording,!currentRecording))return![];return currentRecording[_0x4ba626(0x63f)][_0x4ba626(0x823)]({'timestamp':new Date()['toISOString'](),'devices':_0x2997c5,'originalCommand':_0x3935c5,'useAI':_0x5c5073,'finalCommand':_0x446a63[_0x4ba626(0x511)](_0x1843e9,_0x3935c5)}),console[_0x4ba626(0x61d)](_0x4ba626(0x40e)+_0x3935c5+'\x20('+currentRecording[_0x4ba626(0x63f)][_0x4ba626(0x526)]+_0x4ba626(0x3e7)),!![];}async function stopRecording(){const _0x5d0714=_0x47c41d,_0x3d173a={};_0x3d173a[_0x5d0714(0x5cd)]=function(_0x455016,_0x3717ad){return _0x455016||_0x3717ad;},_0x3d173a[_0x5d0714(0x56a)]=_0x5d0714(0x678);const _0x9e06a1=_0x3d173a;if(_0x9e06a1[_0x5d0714(0x5cd)](!isRecording,!currentRecording)){const _0x2d968e={};return _0x2d968e[_0x5d0714(0x859)]=![],_0x2d968e[_0x5d0714(0x6c8)]=_0x9e06a1[_0x5d0714(0x56a)],_0x2d968e;}currentRecording[_0x5d0714(0x3c1)]=new Date()['toISOString']();const _0x29146c=currentRecording['name']+_0x5d0714(0x55a),_0x466557=path[_0x5d0714(0x5c8)](RECORDINGS_DIR,_0x29146c);await fs[_0x5d0714(0x35b)](_0x466557,JSON['stringify'](currentRecording,null,0x2));const _0x2d2329={};_0x2d2329[_0x5d0714(0x859)]=!![],_0x2d2329[_0x5d0714(0x533)]=currentRecording,_0x2d2329[_0x5d0714(0x4f8)]=_0x29146c;const _0x350c47=_0x2d2329;return console[_0x5d0714(0x61d)](_0x5d0714(0x673)+currentRecording['name']+'\x20('+currentRecording[_0x5d0714(0x63f)][_0x5d0714(0x526)]+_0x5d0714(0x775)),isRecording=![],currentRecording=null,_0x350c47;}async function listRecordings(){const _0x592a5d=_0x47c41d,_0x5dc40d={};_0x5dc40d[_0x592a5d(0x24c)]=_0x592a5d(0x221),_0x5dc40d[_0x592a5d(0x616)]='devices_updated',_0x5dc40d[_0x592a5d(0x896)]=function(_0x5c73ee,_0x598a83){return _0x5c73ee===_0x598a83;},_0x5dc40d[_0x592a5d(0x281)]=_0x592a5d(0x4be),_0x5dc40d['IwPoZ']=function(_0x299f74,_0x5b78ad){return _0x299f74!==_0x5b78ad;},_0x5dc40d[_0x592a5d(0x41e)]=_0x592a5d(0x583),_0x5dc40d[_0x592a5d(0x256)]='TMLgx',_0x5dc40d['mYYgW']=_0x592a5d(0x377),_0x5dc40d[_0x592a5d(0x23f)]=_0x592a5d(0x267),_0x5dc40d[_0x592a5d(0x794)]=_0x592a5d(0x419),_0x5dc40d[_0x592a5d(0x54c)]='.json',_0x5dc40d[_0x592a5d(0x64e)]=function(_0x516c2f,_0x109a11){return _0x516c2f!==_0x109a11;},_0x5dc40d[_0x592a5d(0x259)]=_0x592a5d(0x683),_0x5dc40d[_0x592a5d(0x77b)]=_0x592a5d(0x765),_0x5dc40d['zDBiw']='Error\x20listing\x20recordings:';const _0x5b947c=_0x5dc40d;await ensureRecordingsDir();try{const _0x4b1b86=await fs[_0x592a5d(0x33f)](RECORDINGS_DIR),_0x1159b4=[];for(const _0x298245 of _0x4b1b86){if(_0x5b947c[_0x592a5d(0x896)](_0x5b947c['rDnZn'],_0x5b947c[_0x592a5d(0x281)])){if(_0x298245[_0x592a5d(0x3bc)](_0x592a5d(0x55a))){if(_0x5b947c[_0x592a5d(0x69b)](_0x5b947c[_0x592a5d(0x41e)],_0x5b947c['cMPsd']))try{const _0x205b63=path['join'](RECORDINGS_DIR,_0x298245),_0xdb1e9=await fs[_0x592a5d(0x7fe)](_0x205b63,_0x5b947c[_0x592a5d(0x632)]),_0xe94cd8=JSON[_0x592a5d(0x1f8)](_0xdb1e9);let _0x1d465b=0x0;if(Array[_0x592a5d(0x39e)](_0xe94cd8[_0x592a5d(0x63f)]))_0x1d465b=_0xe94cd8['commands'][_0x592a5d(0x526)];else{if(_0x5b947c[_0x592a5d(0x896)](typeof _0xe94cd8[_0x592a5d(0x63f)],_0x5b947c[_0x592a5d(0x23f)])){if(_0x5b947c[_0x592a5d(0x794)]!==_0x5b947c[_0x592a5d(0x794)]){const _0x40d76d={};_0x40d76d['success']=![],_0x40d76d[_0x592a5d(0x6c8)]=_0x5b947c[_0x592a5d(0x24c)],_0x586f76[_0x592a5d(0x4d0)](0x1f4)[_0x592a5d(0x843)](_0x40d76d);}else _0x1d465b=_0xe94cd8[_0x592a5d(0x63f)][_0x592a5d(0x307)]('\x0a')['filter'](_0x2acbc2=>_0x2acbc2[_0x592a5d(0x685)]())[_0x592a5d(0x526)];}}_0x1159b4[_0x592a5d(0x823)]({'filename':_0x298245,'name':_0xe94cd8[_0x592a5d(0x719)]||_0x298245[_0x592a5d(0x3bd)](_0x5b947c['hSpIt'],''),'devices':_0xe94cd8['devices']||[],'commandCount':_0x1d465b,'startTime':_0xe94cd8[_0x592a5d(0x6e2)]||_0xe94cd8['date'],'endTime':_0xe94cd8[_0x592a5d(0x3c1)]||_0xe94cd8[_0x592a5d(0x6af)],'type':_0xe94cd8['type']||_0x592a5d(0x557)});}catch(_0x1d33d8){if(_0x5b947c[_0x592a5d(0x64e)](_0x5b947c[_0x592a5d(0x259)],_0x592a5d(0x683))){const _0x470a7b={};_0x470a7b[_0x592a5d(0x6c8)]=_0x592a5d(0x3a8),_0x54dba7=[_0x470a7b];}else console[_0x592a5d(0x6c8)](_0x592a5d(0x8c2)+_0x298245+':',_0x1d33d8);}else{if(_0x177c0f[_0x592a5d(0x24e)]===_0x7fd568[_0x592a5d(0x3ba)]){const _0x24c1b5={};_0x24c1b5[_0x592a5d(0x4b8)]=pPKtcu['phXNn'],_0x24c1b5[_0x592a5d(0x658)]=_0x5accde,_0x1a5cf4['send'](_0x1e8f89[_0x592a5d(0x33e)](_0x24c1b5));}}}}else{const _0x31bf10=_0x10331a[_0x592a5d(0x7de)]();_0x1af768+=_0x31bf10,_0x54599e[_0x592a5d(0x6c8)]('['+_0x5a5624+_0x592a5d(0x3e3)+_0x31bf10[_0x592a5d(0x685)]());}}return _0x1159b4;}catch(_0x554aa7){if(_0x5b947c[_0x592a5d(0x77b)]!==_0x5b947c[_0x592a5d(0x77b)])_0x1d449c[_0x592a5d(0x61d)](_0x592a5d(0x25f)+_0x3aa1c0+_0x592a5d(0x7ee)+_0x50c3d1['trim']());else return console[_0x592a5d(0x6c8)](_0x5b947c[_0x592a5d(0x617)],_0x554aa7),[];}}async function loadRecording(_0x2cdb6a){const _0x269119=_0x47c41d,_0x46967e={};_0x46967e['sNpBC']=function(_0x302d64,_0x35b80f){return _0x302d64===_0x35b80f;},_0x46967e['hFNDT']=_0x269119(0x5ac),_0x46967e[_0x269119(0x5f4)]=_0x269119(0x377),_0x46967e[_0x269119(0x61a)]=function(_0x5ab40a,_0x5425e9){return _0x5ab40a!==_0x5425e9;},_0x46967e[_0x269119(0x59f)]=_0x269119(0x337);const _0x4ac3a7=_0x46967e,_0x335ff9=path[_0x269119(0x5c8)](RECORDINGS_DIR,_0x2cdb6a);try{if(_0x4ac3a7[_0x269119(0x36b)](_0x269119(0x5ac),_0x4ac3a7[_0x269119(0x838)])){const _0x2d0e74=await fs[_0x269119(0x7fe)](_0x335ff9,_0x4ac3a7[_0x269119(0x5f4)]);return JSON[_0x269119(0x1f8)](_0x2d0e74);}else _0x11b92b[_0x269119(0x6c8)](_0x269119(0x5ad)+_0xfd1e8[_0x269119(0x6dc)]);}catch(_0x463a7a){if(_0x4ac3a7[_0x269119(0x61a)](_0x269119(0x875),_0x4ac3a7['zLxQF'])){console['error']('Error\x20loading\x20recording\x20'+_0x2cdb6a+':',_0x463a7a);throw _0x463a7a;}else _0x39b100['log']('ā ļø\x20UIAutomator2\x20installation\x20failed\x20on\x20'+_0x18a519);}}async function deleteRecording(_0x2571cb){const _0x37f680=_0x47c41d,_0x32b1da={};_0x32b1da[_0x37f680(0x821)]=_0x37f680(0x254),_0x32b1da['GQcUO']=function(_0x3ea39f,_0x2c8b64){return _0x3ea39f+_0x2c8b64;},_0x32b1da['WQQgW']=function(_0x2564a9,_0x3081d6){return _0x2564a9!==_0x3081d6;},_0x32b1da['mWKFR']=_0x37f680(0x736);const _0x51ac0a=_0x32b1da,_0x45a2e6=path[_0x37f680(0x5c8)](RECORDINGS_DIR,_0x2571cb);try{await fs[_0x37f680(0x67e)](_0x45a2e6);const _0x246bea={};return _0x246bea[_0x37f680(0x859)]=!![],_0x246bea;}catch(_0x50f7a0){if(_0x51ac0a[_0x37f680(0x7e4)](_0x51ac0a['mWKFR'],_0x51ac0a[_0x37f680(0x666)]))_0x448fc3[_0x37f680(0x71d)](_0x2dc05f[_0x37f680(0x33e)]({'type':NaKPyg[_0x37f680(0x821)],'data':_0x37f680(0x796)+NaKPyg[_0x37f680(0x66c)](_0x6d5cb4,0x1)+'/'+_0x51b238[_0x37f680(0x526)]+']\x20'+_0xae5906+'\x0a','devices':_0x4f61f1}));else{console[_0x37f680(0x6c8)](_0x37f680(0x7bd)+_0x2571cb+':',_0x50f7a0);throw _0x50f7a0;}}}async function replayRecording(_0xd70daa,_0x47aee5,_0x145228){const _0x1be1c8=_0x47c41d,_0x15d2b3={'qaauA':'Execution\x20error:','svNBL':function(_0x56a3bb,_0x5c0451){return _0x56a3bb(_0x5c0451);},'cAqOD':function(_0x5e3dd9,_0x274a1e){return _0x5e3dd9===_0x274a1e;},'bPYlj':_0x1be1c8(0x267),'tWIgb':function(_0x4e90f3,_0x5b127b){return _0x4e90f3>_0x5b127b;},'ioksr':'command_output','BCvXZ':function(_0xc0e614,_0x41f601){return _0xc0e614+_0x41f601;},'qjFDq':function(_0x194be7,_0x2ae607){return _0x194be7+_0x2ae607;},'gWFyg':function(_0xab6f24,_0x20f3e9){return _0xab6f24<_0x20f3e9;},'ystyX':_0x1be1c8(0x52b),'mSWWc':'\x0aā¹ļø\x20\x20Replay\x20stopped\x20by\x20user\x0a','eKQBD':_0x1be1c8(0x38e),'WMNUq':function(_0x56ca97,_0x7dfac0){return _0x56ca97+_0x7dfac0;},'MBoZp':'FrpfZ','zaEpL':_0x1be1c8(0x8a8),'XrTaK':function(_0x271e53,_0x5f2f44,_0x48412c,_0x25eeb3){return _0x271e53(_0x5f2f44,_0x48412c,_0x25eeb3);},'igUnW':'yFKfK','EkHzF':function(_0x2340a8,_0x591280){return _0x2340a8<_0x591280;},'JHPhc':function(_0x2d27f3,_0x4c9ff4){return _0x2d27f3-_0x4c9ff4;},'EcvVU':function(_0x59f64e,_0x31793d){return _0x59f64e===_0x31793d;},'wLPLB':_0x1be1c8(0x48e)},_0x2480e2=await loadRecording(_0xd70daa);let _0x2ef7ab=[];if(Array['isArray'](_0x2480e2['commands']))_0x2ef7ab=_0x2480e2[_0x1be1c8(0x63f)][_0x1be1c8(0x2d0)](_0x1d000e=>_0x1d000e[_0x1be1c8(0x334)]||_0x1d000e[_0x1be1c8(0x6de)]);else _0x15d2b3[_0x1be1c8(0x558)](typeof _0x2480e2[_0x1be1c8(0x63f)],_0x15d2b3[_0x1be1c8(0x6cf)])&&(_0x2ef7ab=_0x2480e2[_0x1be1c8(0x63f)]['split']('\x0a')['filter'](_0x409510=>_0x409510['trim']()));const _0x1d0404=_0x2480e2[_0x1be1c8(0x658)]&&_0x15d2b3[_0x1be1c8(0x757)](_0x2480e2[_0x1be1c8(0x658)][_0x1be1c8(0x526)],0x0)?_0x2480e2['devices']:_0x47aee5;console[_0x1be1c8(0x61d)]('\x0a'+'ā¶'[_0x1be1c8(0x552)](0x3c)),console['log'](_0x1be1c8(0x567)+_0x2480e2[_0x1be1c8(0x719)]),console[_0x1be1c8(0x61d)](_0x1be1c8(0x21e)+_0x1d0404['join'](',\x20')),console[_0x1be1c8(0x61d)](_0x1be1c8(0x468)+_0x47aee5['join'](',\x20')),console['log'](_0x1be1c8(0x362)+_0x2ef7ab['length']),console['log']('ā¶'[_0x1be1c8(0x552)](0x3c)+'\x0a'),replayAborted=![],isReplaying=!![];_0x145228&&_0x145228[_0x1be1c8(0x71d)](JSON['stringify']({'type':_0x15d2b3[_0x1be1c8(0x4d1)],'data':_0x15d2b3[_0x1be1c8(0x89c)](_0x15d2b3['qjFDq'](_0x15d2b3[_0x1be1c8(0x89c)](_0x1be1c8(0x87b)+_0x2480e2[_0x1be1c8(0x719)]+'\x0a',_0x1be1c8(0x375)+_0x47aee5['join'](',\x20')+'\x0a'),_0x1be1c8(0x76f)+_0x2ef7ab[_0x1be1c8(0x526)]+'\x0a'),'ā'['repeat'](0x32)+'\x0a\x0a'),'devices':_0x47aee5}));const _0x5f108c=[];for(let _0x4f5ba7=0x0;_0x15d2b3[_0x1be1c8(0x6ca)](_0x4f5ba7,_0x2ef7ab[_0x1be1c8(0x526)]);_0x4f5ba7++){if(replayAborted){console['log'](_0x15d2b3[_0x1be1c8(0x899)]);if(_0x145228){const _0x1bc226={};_0x1bc226[_0x1be1c8(0x4b8)]=_0x1be1c8(0x254),_0x1bc226[_0x1be1c8(0x1da)]=_0x15d2b3[_0x1be1c8(0x417)],_0x1bc226['devices']=_0x47aee5,_0x145228[_0x1be1c8(0x71d)](JSON[_0x1be1c8(0x33e)](_0x1bc226));}isReplaying=![];throw new Error(_0x15d2b3[_0x1be1c8(0x895)]);}const _0x3e533f=_0x2ef7ab[_0x4f5ba7];console[_0x1be1c8(0x61d)]('\x0aš¬\x20Replaying\x20command\x20'+_0x15d2b3['BCvXZ'](_0x4f5ba7,0x1)+'/'+_0x2ef7ab['length']),console[_0x1be1c8(0x61d)](_0x1be1c8(0x42c)+_0x3e533f);_0x145228&&_0x145228['send'](JSON[_0x1be1c8(0x33e)]({'type':_0x15d2b3[_0x1be1c8(0x4d1)],'data':_0x1be1c8(0x5a6)+_0x15d2b3[_0x1be1c8(0x271)](_0x4f5ba7,0x1)+'/'+_0x2ef7ab[_0x1be1c8(0x526)]+_0x1be1c8(0x688)+_0x3e533f+'\x0a','devices':_0x47aee5}));try{if(_0x15d2b3[_0x1be1c8(0x558)](_0x15d2b3['MBoZp'],_0x15d2b3[_0x1be1c8(0x820)]))_0x26f16d[_0x1be1c8(0x6c8)](vIJgib[_0x1be1c8(0x2e0)],_0x37ffcd),vIJgib['svNBL'](_0x2ea479,_0x4b3991);else{const _0x4231ba=await _0x15d2b3[_0x1be1c8(0x2d4)](executeCommand,_0x47aee5,_0x3e533f,null),_0x34a579={};_0x34a579[_0x1be1c8(0x582)]=_0x3e533f,_0x34a579[_0x1be1c8(0x859)]=!![],_0x34a579[_0x1be1c8(0x5fa)]=_0x4231ba,_0x5f108c['push'](_0x34a579);if(_0x145228){if(_0x15d2b3[_0x1be1c8(0x558)](_0x15d2b3['igUnW'],_0x1be1c8(0x4ca))){const [_0x2e2382,_0x12303c]=_0xc091ce;if(!_0x355162[_0x2e2382])_0x5b9702[_0x2e2382]={};_0x42e5ab[_0x2e2382][_0x12303c]=_0x1f15c6;}else{const _0x32a5a1={};_0x32a5a1['type']=_0x15d2b3[_0x1be1c8(0x4d1)],_0x32a5a1[_0x1be1c8(0x1da)]=_0x1be1c8(0x457),_0x32a5a1[_0x1be1c8(0x658)]=_0x47aee5,_0x145228[_0x1be1c8(0x71d)](JSON[_0x1be1c8(0x33e)](_0x32a5a1));}}if(_0x15d2b3[_0x1be1c8(0x7df)](_0x4f5ba7,_0x15d2b3['JHPhc'](_0x2ef7ab['length'],0x1))){if(_0x15d2b3[_0x1be1c8(0x789)](_0x15d2b3[_0x1be1c8(0x39c)],_0x1be1c8(0x639))){const _0x28a490={};_0x28a490[_0x1be1c8(0x859)]=![],_0x28a490[_0x1be1c8(0x6c8)]=_0x55cd2c['message'],_0x3835e0[_0x1be1c8(0x4d0)](0x1f4)['json'](_0x28a490);}else await new Promise(_0x49631d=>setTimeout(_0x49631d,0x3e8));}}}catch(_0x33c157){console['error'](_0x1be1c8(0x39f)+(_0x4f5ba7+0x1)+_0x1be1c8(0x59d),_0x33c157[_0x1be1c8(0x6dc)]);const _0x54004a={};_0x54004a[_0x1be1c8(0x582)]=_0x3e533f,_0x54004a['success']=![],_0x54004a[_0x1be1c8(0x6c8)]=_0x33c157['message'],_0x5f108c[_0x1be1c8(0x823)](_0x54004a);if(_0x145228){const _0xc5f30e={};_0xc5f30e[_0x1be1c8(0x4b8)]=_0x1be1c8(0x254),_0xc5f30e['data']=_0x1be1c8(0x34e)+_0x33c157[_0x1be1c8(0x6dc)]+'\x0a\x0a',_0xc5f30e[_0x1be1c8(0x658)]=_0x47aee5,_0x145228[_0x1be1c8(0x71d)](JSON['stringify'](_0xc5f30e));}}}isReplaying=![],console[_0x1be1c8(0x61d)]('\x0a'+'ā¶'[_0x1be1c8(0x552)](0x3c)),console[_0x1be1c8(0x61d)](_0x1be1c8(0x363)),console[_0x1be1c8(0x61d)](_0x1be1c8(0x79a)+_0x5f108c['length']+',\x20Success:\x20'+_0x5f108c[_0x1be1c8(0x3c2)](_0x5975dc=>_0x5975dc[_0x1be1c8(0x859)])['length']+_0x1be1c8(0x729)+_0x5f108c[_0x1be1c8(0x3c2)](_0x4d57c2=>!_0x4d57c2['success'])[_0x1be1c8(0x526)]),console[_0x1be1c8(0x61d)]('ā¶'['repeat'](0x3c)+'\x0a');const _0x1fa3ee={};return _0x1fa3ee[_0x1be1c8(0x859)]=!![],_0x1fa3ee['recording']=_0x2480e2[_0x1be1c8(0x719)],_0x1fa3ee[_0x1be1c8(0x239)]=_0x5f108c,_0x1fa3ee;}app[_0x47c41d(0x3ac)]('/api/devices',async(_0x290708,_0x2655e4)=>{const _0x353054=_0x47c41d,_0xf7ad7={'CIHqu':function(_0x38a047){return _0x38a047();}};try{const _0x135605=await _0xf7ad7[_0x353054(0x7be)](discoverDevices),_0xb73c03={};_0xb73c03[_0x353054(0x859)]=!![],_0xb73c03[_0x353054(0x658)]=_0x135605,_0x2655e4[_0x353054(0x843)](_0xb73c03);}catch(_0x51a2c1){const _0x5b115a={};_0x5b115a['success']=![],_0x5b115a[_0x353054(0x6c8)]=_0x51a2c1[_0x353054(0x6dc)],_0x2655e4[_0x353054(0x4d0)](0x1f4)[_0x353054(0x843)](_0x5b115a);}}),app['post'](_0x47c41d(0x34f),async(_0x589ae2,_0x43688d)=>{const _0x3f2add=_0x47c41d,_0x9d4d5f={'crKKI':function(_0x3d3a8a,_0x208bb4){return _0x3d3a8a!==_0x208bb4;},'uLjbZ':_0x3f2add(0x677),'BkAtQ':_0x3f2add(0x33a),'dODyD':_0x3f2add(0x893),'xoxru':function(_0x150059){return _0x150059();}};try{if(_0x9d4d5f['crKKI'](_0x3f2add(0x893),_0x9d4d5f[_0x3f2add(0x527)])){const _0x330a68=_0x3e3f02('fs')[_0x3f2add(0x73b)](_0x10d677[_0x3f2add(0x5c8)](_0x1a59f9,_0xeac132));return{'filename':_0x17bd86,'path':_0x3f2add(0x62f)+_0x49d6ef,'size':_0x330a68['size'],'timestamp':_0x330a68[_0x3f2add(0x39d)][_0x3f2add(0x6e0)](),'created':_0x330a68[_0x3f2add(0x39d)]};}else{const _0x39ef18=await _0x9d4d5f[_0x3f2add(0x8a0)](discoverDevices);wss[_0x3f2add(0x284)][_0x3f2add(0x68d)](_0x2330a8=>{const _0x3fc38a=_0x3f2add,_0x249a89={};_0x249a89[_0x3fc38a(0x2d3)]='android';const _0x3867ff=_0x249a89;if(_0x9d4d5f['crKKI'](_0x9d4d5f[_0x3fc38a(0x873)],_0x9d4d5f['uLjbZ']))_0xba0a7c=YgooFE[_0x3fc38a(0x2d3)];else{if(_0x2330a8['readyState']===WebSocket[_0x3fc38a(0x3ba)]){const _0xee06e9={};_0xee06e9['type']=_0x9d4d5f['BkAtQ'],_0xee06e9['devices']=_0x39ef18,_0x2330a8[_0x3fc38a(0x71d)](JSON[_0x3fc38a(0x33e)](_0xee06e9));}}});const _0x2c5111={};_0x2c5111[_0x3f2add(0x859)]=!![],_0x2c5111[_0x3f2add(0x658)]=_0x39ef18,_0x43688d[_0x3f2add(0x843)](_0x2c5111);}}catch(_0x488469){const _0x2e4625={};_0x2e4625[_0x3f2add(0x859)]=![],_0x2e4625['error']=_0x488469[_0x3f2add(0x6dc)],_0x43688d[_0x3f2add(0x4d0)](0x1f4)[_0x3f2add(0x843)](_0x2e4625);}}),app[_0x47c41d(0x328)](_0x47c41d(0x65a),async(_0x24fd52,_0xce8e0c)=>{const _0x3c6515=_0x47c41d,_0x4325f2={'DZliJ':function(_0x459abd,_0xf103c6){return _0x459abd===_0xf103c6;},'BfgMY':function(_0x1d45bd,_0x5a2acf){return _0x1d45bd===_0x5a2acf;},'HhIEO':function(_0xb7fb2c,_0x359819,_0xa37643,_0x494533){return _0xb7fb2c(_0x359819,_0xa37643,_0x494533);},'ZtEDz':function(_0x4e391c,_0xd30718,_0x182089,_0x1e95d2){return _0x4e391c(_0xd30718,_0x182089,_0x1e95d2);},'sJXBy':function(_0x1eb999,_0x76650e,_0x289463,_0x2ede67){return _0x1eb999(_0x76650e,_0x289463,_0x2ede67);}};try{const {devices:_0x56db1a,command:_0x149bea,useAI:_0xecc7da,aiProvider:_0x21ebba}=_0x24fd52[_0x3c6515(0x3b6)];if(!_0x56db1a||_0x4325f2['DZliJ'](_0x56db1a[_0x3c6515(0x526)],0x0)){const _0x24bfc7={};return _0x24bfc7[_0x3c6515(0x859)]=![],_0x24bfc7[_0x3c6515(0x6c8)]=_0x3c6515(0x7cd),_0xce8e0c['status'](0x190)[_0x3c6515(0x843)](_0x24bfc7);}let _0x1e6085=_0x149bea;if(_0xecc7da){if(_0x4325f2[_0x3c6515(0x74a)](_0x3c6515(0x7e8),'zAALY'))_0x1e6085=await _0x4325f2[_0x3c6515(0x85d)](convertNaturalLanguageToCommand,_0x149bea,_0x56db1a,_0x21ebba);else{const _0x1f4ab4=_0x13fa84['join'](_0x2b3f0e,_0x3db07b['params'][_0x3c6515(0x75b)]);_0x33e0cb[_0x3c6515(0x36e)](_0x1f4ab4,_0x35c525=>{const _0x1e8812=_0x3c6515;if(_0x35c525){const _0xe2ce1f={};_0xe2ce1f['success']=![],_0xe2ce1f['error']=_0x1e8812(0x53d),_0x2fcbaa[_0x1e8812(0x4d0)](0x194)[_0x1e8812(0x843)](_0xe2ce1f);}});}}const _0x2bd914=_0x1e6085[_0x3c6515(0x310)]('\x0a');let _0x565664;_0x2bd914?_0x565664=await _0x4325f2['ZtEDz'](executeCommandsSequentially,_0x56db1a,_0x1e6085,null):_0x565664=await _0x4325f2[_0x3c6515(0x4bf)](executeCommand,_0x56db1a,_0x1e6085,null),_0xce8e0c[_0x3c6515(0x843)](_0x565664);}catch(_0x45f602){const _0x286380={};_0x286380[_0x3c6515(0x859)]=![],_0x286380[_0x3c6515(0x6c8)]=_0x45f602[_0x3c6515(0x6dc)],_0xce8e0c[_0x3c6515(0x4d0)](0x1f4)['json'](_0x286380);}}),app[_0x47c41d(0x328)](_0x47c41d(0x772),async(_0x6d7f16,_0x2b4c57)=>{const _0x28d868=_0x47c41d,_0x464940={'YqZpJ':function(_0x540fa4,_0x216bc9){return _0x540fa4(_0x216bc9);},'SfJHB':function(_0x1b6e4a,_0x26d4a1){return _0x1b6e4a!==_0x26d4a1;},'QkbQq':_0x28d868(0x20a)};try{if(_0x464940['SfJHB'](_0x464940[_0x28d868(0x645)],_0x464940[_0x28d868(0x645)])){_0x30108d[_0x28d868(0x61d)](_0x28d868(0x2e3)+_0x4390d4+'\x20at\x20'+_0x390725+_0x28d868(0x4c9));const _0x4db3fc={};_0x4db3fc[_0x28d868(0x859)]=![],_0x4db3fc[_0x28d868(0x6dc)]='Cannot\x20reach\x20'+_0x127a3b+'\x20at\x20'+_0x17573c+'.\x20Check\x20network\x20connection.',cwnEfE[_0x28d868(0x6c4)](_0x4f2633,_0x4db3fc);}else{const {text:_0x46c81d,devices:_0xa4567b,provider:_0x9bfaae}=_0x6d7f16[_0x28d868(0x3b6)],_0x4ef1da=await convertNaturalLanguageToCommand(_0x46c81d,_0xa4567b||[],_0x9bfaae),_0x66313f={};_0x66313f[_0x28d868(0x859)]=!![],_0x66313f[_0x28d868(0x582)]=_0x4ef1da,_0x2b4c57[_0x28d868(0x843)](_0x66313f);}}catch(_0x3e362a){const _0x2c64c2={};_0x2c64c2[_0x28d868(0x859)]=![],_0x2c64c2[_0x28d868(0x6c8)]=_0x3e362a[_0x28d868(0x6dc)],_0x2b4c57[_0x28d868(0x4d0)](0x1f4)[_0x28d868(0x843)](_0x2c64c2);}}),app[_0x47c41d(0x328)](_0x47c41d(0x807),async(_0x4a4668,_0x1bff71)=>{const _0x2f0fac=_0x47c41d,_0x531651={'Utzav':'ā\x20No\x20device\x20provided\x20in\x20request','DkxAQ':_0x2f0fac(0x5f8),'Aaygf':_0x2f0fac(0x833),'AaNQA':function(_0x1f4f67,_0x3fdd60){return _0x1f4f67(_0x3fdd60);},'fkwRy':function(_0x536bbf,_0x39653e){return _0x536bbf===_0x39653e;},'Rbmbt':_0x2f0fac(0x7e5)};try{const {device:_0x53406b}=_0x4a4668[_0x2f0fac(0x3b6)];console[_0x2f0fac(0x61d)](_0x2f0fac(0x57b),_0x53406b);if(!_0x53406b){if(_0x2f0fac(0x890)===_0x2f0fac(0x890)){console[_0x2f0fac(0x6c8)](_0x531651[_0x2f0fac(0x748)]);const _0x385acc={};return _0x385acc[_0x2f0fac(0x859)]=![],_0x385acc['error']=_0x531651[_0x2f0fac(0x2ed)],_0x1bff71['status'](0x190)[_0x2f0fac(0x843)](_0x385acc);}else{const _0x3f52f5={};_0x3f52f5[_0x2f0fac(0x859)]=![],_0x3f52f5[_0x2f0fac(0x6c8)]=_0x380967[_0x2f0fac(0x6dc)],_0x3585ed[_0x2f0fac(0x4d0)](0x1f4)[_0x2f0fac(0x843)](_0x3f52f5);}}if(!_0x53406b[_0x2f0fac(0x719)]||!_0x53406b[_0x2f0fac(0x200)]){console[_0x2f0fac(0x6c8)]('ā\x20Invalid\x20device\x20object:',_0x53406b);const _0x3f7980={};return _0x3f7980[_0x2f0fac(0x859)]=![],_0x3f7980[_0x2f0fac(0x6c8)]=_0x531651[_0x2f0fac(0x6ab)],_0x1bff71['status'](0x190)[_0x2f0fac(0x843)](_0x3f7980);}const _0x298822=await _0x531651[_0x2f0fac(0x481)](connectToDevice,_0x53406b);console['log'](_0x2f0fac(0x308),_0x298822),_0x1bff71[_0x2f0fac(0x843)](_0x298822);}catch(_0x33b0df){if(_0x531651[_0x2f0fac(0x881)](_0x2f0fac(0x7e5),_0x531651['Rbmbt'])){console[_0x2f0fac(0x6c8)](_0x2f0fac(0x4d3),_0x33b0df);const _0x53fab1={};_0x53fab1['success']=![],_0x53fab1[_0x2f0fac(0x6c8)]=_0x33b0df['message'],_0x1bff71['status'](0x1f4)['json'](_0x53fab1);}else _0xcfb01c+='CLAUDE_API_KEY='+_0x43f2c1+'\x0a';}}),app[_0x47c41d(0x328)](_0x47c41d(0x83c),async(_0x2e27e4,_0x196eb6)=>{const _0x443f36=_0x47c41d,_0x26f4e4={'dpVRv':function(_0x13605a,_0x51b71a){return _0x13605a(_0x51b71a);}};try{const {device:_0x3c724b}=_0x2e27e4[_0x443f36(0x3b6)],_0x4401a6=await _0x26f4e4[_0x443f36(0x374)](disconnectFromDevice,_0x3c724b);_0x196eb6[_0x443f36(0x843)](_0x4401a6);}catch(_0x58e73e){const _0x4766b7={};_0x4766b7[_0x443f36(0x859)]=![],_0x4766b7[_0x443f36(0x6c8)]=_0x58e73e[_0x443f36(0x6dc)],_0x196eb6[_0x443f36(0x4d0)](0x1f4)[_0x443f36(0x843)](_0x4766b7);}}),app[_0x47c41d(0x328)](_0x47c41d(0x3f0),async(_0x3cc6eb,_0x1bf46e)=>{const _0x284865=_0x47c41d,_0x40e49d={};_0x40e49d[_0x284865(0x847)]=function(_0x4541a0,_0x4dc9e6){return _0x4541a0===_0x4dc9e6;},_0x40e49d[_0x284865(0x482)]='oXlFx',_0x40e49d['Bqnzv']=function(_0x2ec70d,_0x230a90){return _0x2ec70d===_0x230a90;},_0x40e49d[_0x284865(0x2af)]=_0x284865(0x831),_0x40e49d[_0x284865(0x595)]=_0x284865(0x69f),_0x40e49d[_0x284865(0x434)]=_0x284865(0x313);const _0x131ab7=_0x40e49d;try{if(_0x131ab7[_0x284865(0x847)](_0x284865(0x545),_0x131ab7['ohMdB'])){console[_0x284865(0x61d)](_0x284865(0x670));const _0x1560dd=connectedDevices[_0x284865(0x3c2)](_0x5772d4=>_0x5772d4[_0x284865(0x4d0)]===_0x284865(0x29b));if(_0x131ab7[_0x284865(0x733)](_0x1560dd['length'],0x0)){const _0x2c91eb={};return _0x2c91eb[_0x284865(0x859)]=!![],_0x2c91eb[_0x284865(0x6dc)]=_0x131ab7[_0x284865(0x2af)],_0x1bf46e[_0x284865(0x843)](_0x2c91eb);}console[_0x284865(0x61d)](_0x284865(0x857)+_0x1560dd[_0x284865(0x526)]+'\x20device(s)...');const _0x182bc1=_0x1560dd[_0x284865(0x2d0)](_0x3638f2=>disconnectFromDevice(_0x3638f2));await Promise[_0x284865(0x4b0)](_0x182bc1),console[_0x284865(0x61d)](_0x284865(0x59c));const _0x5306fa={};_0x5306fa['success']=!![],_0x5306fa[_0x284865(0x6dc)]=_0x284865(0x78f)+_0x1560dd[_0x284865(0x526)]+_0x284865(0x435),_0x5306fa[_0x284865(0x44d)]=_0x1560dd[_0x284865(0x526)],_0x1bf46e['json'](_0x5306fa);}else _0x3aa822['log'](_0x284865(0x3bf)+_0x24a4a9+'\x20in\x20your\x20browser');}catch(_0x2e00e6){if(_0x131ab7[_0x284865(0x595)]===_0x131ab7[_0x284865(0x434)]){const _0x419b05=_0x4f62eb['ip']||'';_0x94fcfa+=_0x57394c['name']+','+_0x3a1ea0[_0x284865(0x200)]+','+_0x419b05+'\x0a';}else{console[_0x284865(0x6c8)](_0x284865(0x87f),_0x2e00e6);const _0xc1a0ca={};_0xc1a0ca['success']=![],_0xc1a0ca[_0x284865(0x6c8)]=_0x2e00e6[_0x284865(0x6dc)],_0x1bf46e[_0x284865(0x4d0)](0x1f4)[_0x284865(0x843)](_0xc1a0ca);}}}),app[_0x47c41d(0x3ac)]('/api/ai/providers',(_0x34992b,_0x4607a6)=>{const _0x5beed3=_0x47c41d;try{const _0x14b9a6=aiManager[_0x5beed3(0x37b)](),_0x548658=aiManager[_0x5beed3(0x89a)](),_0x321bb3={};_0x321bb3[_0x5beed3(0x859)]=!![],_0x321bb3['providers']=_0x14b9a6,_0x321bb3[_0x5beed3(0x3b3)]=_0x548658['id'],_0x4607a6[_0x5beed3(0x843)](_0x321bb3);}catch(_0x56569c){const _0x484f8b={};_0x484f8b['success']=![],_0x484f8b[_0x5beed3(0x6c8)]=_0x56569c['message'],_0x4607a6[_0x5beed3(0x4d0)](0x1f4)['json'](_0x484f8b);}}),app['post'](_0x47c41d(0x8a1),(_0x4771a1,_0x1e1418)=>{const _0x45087d=_0x47c41d,_0x1cadf9={'tAtcZ':'../../','snXKM':function(_0x39cb68,_0x47fce8){return _0x39cb68(_0x47fce8);},'GZzUk':_0x45087d(0x20c),'AyqwM':'ā
\x20Parsed\x20as\x20JSON,\x20elements:','HdDDw':_0x45087d(0x7af),'wVMKZ':'offline','dedCR':_0x45087d(0x8b8),'wgyia':function(_0x1bd38f,_0x4e06f7){return _0x1bd38f!==_0x4e06f7;},'bMCAu':_0x45087d(0x300),'Mdizw':_0x45087d(0x80d),'usVBs':_0x45087d(0x484),'IbJhA':function(_0x519502,_0x56f6bf){return _0x519502!==_0x56f6bf;},'lIeKM':'WRytu'};try{if(_0x1cadf9[_0x45087d(0x469)]===_0x45087d(0x8b8)){const {provider:_0x27ac15}=_0x4771a1[_0x45087d(0x3b6)],_0x468934=aiManager[_0x45087d(0x2aa)](_0x27ac15);if(_0x468934){if(_0x1cadf9[_0x45087d(0x52c)](_0x1cadf9['bMCAu'],_0x1cadf9['Mdizw'])){const _0x1518a6={};_0x1518a6[_0x45087d(0x859)]=!![],_0x1518a6[_0x45087d(0x3f9)]=_0x27ac15,_0x1e1418[_0x45087d(0x843)](_0x1518a6);}else{let _0x2f3caf=_0x37f2a8[_0x45087d(0x5c8)](_0x427c09,GJNTrY[_0x45087d(0x6ae)],_0x117684);if(GJNTrY['snXKM'](_0xd6bc36,'fs')['existsSync'](_0x2f3caf))return _0x2f3caf;_0x2f3caf=_0x531fb9[_0x45087d(0x5c8)](_0x2b5239,_0x45087d(0x20c),_0x57a054);if(_0x2c4c30('fs')[_0x45087d(0x730)](_0x2f3caf))return _0x2f3caf;const _0x5e9095=_0x50f0e0['replace'](/\.sh$/,'');_0x2f3caf=_0x38bdaf[_0x45087d(0x5c8)](_0x454255,GJNTrY[_0x45087d(0x7a0)],_0x5e9095);if(GJNTrY[_0x45087d(0x5ec)](_0x3e2dc5,'fs')[_0x45087d(0x730)](_0x2f3caf))return _0x2f3caf;return _0x2960d9[_0x45087d(0x5c8)](_0x210075,'../../',_0x47279b);}}else{const _0x5e28d7={};_0x5e28d7['success']=![],_0x5e28d7['error']=_0x1cadf9['usVBs'],_0x1e1418['status'](0x190)['json'](_0x5e28d7);}}else{const _0x43bd6f=_0x14183b[_0x45087d(0x685)]();if(_0x43bd6f[_0x45087d(0x75e)]('[')||_0x43bd6f[_0x45087d(0x75e)]('{'))try{const _0x1c19d8=_0x1b3e04['parse'](_0x43bd6f);return _0x2549f4[_0x45087d(0x61d)](_0x1cadf9[_0x45087d(0x365)],_0x15fe1f['isArray'](_0x1c19d8)?_0x1c19d8['length']:_0x45087d(0x7a2)),_0x3a5cdf[_0x45087d(0x39e)](_0x1c19d8)?_0x1c19d8:[];}catch(_0x535952){_0x14a16c[_0x45087d(0x61d)](_0x1cadf9[_0x45087d(0x208)],_0x535952[_0x45087d(0x6dc)]);}}}catch(_0x15860e){if(_0x1cadf9[_0x45087d(0x680)](_0x1cadf9['lIeKM'],'WRytu'))_0x1b4195[_0x1781e4][_0x45087d(0x4d0)]=GJNTrY[_0x45087d(0x5de)];else{const _0x1635c6={};_0x1635c6[_0x45087d(0x859)]=![],_0x1635c6[_0x45087d(0x6c8)]=_0x15860e[_0x45087d(0x6dc)],_0x1e1418[_0x45087d(0x4d0)](0x1f4)[_0x45087d(0x843)](_0x1635c6);}}}),app[_0x47c41d(0x3ac)](_0x47c41d(0x499),async(_0x34181b,_0x245842)=>{const _0x4d5ac7=_0x47c41d,_0x24dc18={'UHPvr':_0x4d5ac7(0x1e0),'nvzJT':function(_0x374aea,_0x42690a){return _0x374aea&&_0x42690a;},'xPhtW':_0x4d5ac7(0x871),'ndPIa':function(_0x19481d,_0x2ffb3c){return _0x19481d===_0x2ffb3c;},'vXsAO':_0x4d5ac7(0x5a3),'rqfTI':function(_0xc0845e,_0x188de7){return _0xc0845e===_0x188de7;},'NsQwQ':_0x4d5ac7(0x21c),'gZVVe':'GEMINI_API_KEY','IvMqi':function(_0x49a235,_0xe6c670){return _0x49a235===_0xe6c670;},'aqssl':function(_0x41c67b,_0x4c5762){return _0x41c67b===_0x4c5762;},'cdeIl':_0x4d5ac7(0x3b8),'mKKMk':_0x4d5ac7(0x4d5),'jmZMM':function(_0x1e6612,_0x2f15a3){return _0x1e6612===_0x2f15a3;},'QCRid':_0x4d5ac7(0x543),'lEBVA':function(_0x5bc377,_0x562f89){return _0x5bc377!==_0x562f89;},'HoIFy':'RnSqq','PryjY':'JCCWN','oupJq':function(_0x5610a4,_0x2c5d04){return _0x5610a4<_0x2c5d04;},'oEkyK':function(_0x34890a,_0x3b2fdc){return _0x34890a+_0x3b2fdc;},'KuXTT':function(_0x2a7203,_0x287b5b){return _0x2a7203-_0x287b5b;},'auluD':'../../.env','vvNar':_0x4d5ac7(0x4fd),'nJYKy':function(_0x1fd87f,_0x15daff){return _0x1fd87f(_0x15daff);},'McGHB':function(_0x8e7cbb,_0x18b11d){return _0x8e7cbb(_0x18b11d);},'bKbLI':function(_0x284091,_0x1361d2){return _0x284091(_0x1361d2);},'Jkibp':function(_0x3fdf95,_0x2cbb6c){return _0x3fdf95(_0x2cbb6c);},'sUcZR':_0x4d5ac7(0x2dc)};try{const _0x1f2117=path['join'](__dirname,_0x24dc18[_0x4d5ac7(0x2eb)]),_0x569886={};_0x569886[_0x4d5ac7(0x3f9)]=process.env.AI_PROVIDER||_0x24dc18[_0x4d5ac7(0x4ea)],_0x569886[_0x4d5ac7(0x695)]=process.env.AI_MODEL||'',_0x569886[_0x4d5ac7(0x619)]=process.env.OPENAI_API_KEY||'',_0x569886[_0x4d5ac7(0x5ed)]=process.env.GEMINI_API_KEY||'',_0x569886['claude_api_key']=process.env.CLAUDE_API_KEY||'',_0x569886['github_token']=process.env.GITHUB_TOKEN||'',_0x569886['groq_api_key']=process.env.GROQ_API_KEY||'',_0x569886[_0x4d5ac7(0x6fc)]=process.env.COHERE_API_KEY||'',_0x569886['mistral_api_key']=process.env.MISTRAL_API_KEY||'';let _0x405c0b=_0x569886;try{const _0x1f42b7=await fs[_0x4d5ac7(0x7fe)](_0x1f2117,_0x4d5ac7(0x377)),_0xbdd5a0=_0x1f42b7[_0x4d5ac7(0x307)]('\x0a');_0xbdd5a0[_0x4d5ac7(0x68d)](_0x5c3d1c=>{const _0x5e1ed8=_0x4d5ac7;if(_0x24dc18[_0x5e1ed8(0x1f1)]===_0x24dc18['UHPvr']){const [_0x12437e,_0x3f51ee]=_0x5c3d1c['split']('=');if(_0x24dc18['nvzJT'](_0x12437e,_0x3f51ee)){const _0x4575d=_0x12437e[_0x5e1ed8(0x685)](),_0x22f07b=_0x3f51ee['trim']();if(_0x4575d===_0x24dc18[_0x5e1ed8(0x36c)])_0x405c0b[_0x5e1ed8(0x3f9)]=_0x22f07b;if(_0x24dc18['ndPIa'](_0x4575d,_0x24dc18[_0x5e1ed8(0x30c)]))_0x405c0b[_0x5e1ed8(0x695)]=_0x22f07b;if(_0x24dc18[_0x5e1ed8(0x1e5)](_0x4575d,_0x24dc18['NsQwQ']))_0x405c0b[_0x5e1ed8(0x619)]=_0x22f07b;if(_0x4575d===_0x24dc18[_0x5e1ed8(0x3a6)])_0x405c0b['gemini_api_key']=_0x22f07b;if(_0x24dc18[_0x5e1ed8(0x5af)](_0x4575d,_0x5e1ed8(0x4e7)))_0x405c0b[_0x5e1ed8(0x1dd)]=_0x22f07b;if(_0x24dc18[_0x5e1ed8(0x296)](_0x4575d,_0x5e1ed8(0x3d2)))_0x405c0b[_0x5e1ed8(0x7ea)]=_0x22f07b;if(_0x24dc18[_0x5e1ed8(0x296)](_0x4575d,_0x24dc18['cdeIl']))_0x405c0b['groq_api_key']=_0x22f07b;if(_0x4575d===_0x24dc18[_0x5e1ed8(0x78e)])_0x405c0b[_0x5e1ed8(0x6fc)]=_0x22f07b;if(_0x24dc18[_0x5e1ed8(0x3a9)](_0x4575d,_0x24dc18[_0x5e1ed8(0x628)]))_0x405c0b[_0x5e1ed8(0x74d)]=_0x22f07b;}}else{_0x1f363e[_0x5e1ed8(0x6c8)]('ā\x20No\x20device\x20provided\x20in\x20request');const _0x45d213={};return _0x45d213[_0x5e1ed8(0x859)]=![],_0x45d213[_0x5e1ed8(0x6c8)]=_0x5e1ed8(0x5f8),_0x56c7b4['status'](0x190)[_0x5e1ed8(0x843)](_0x45d213);}});}catch(_0x3794e2){}const _0x3e6127=_0x458fe1=>{const _0x1922ae=_0x4d5ac7;if(_0x24dc18[_0x1922ae(0x438)](_0x24dc18[_0x1922ae(0x584)],_0x24dc18[_0x1922ae(0x81f)])){if(!_0x458fe1||_0x24dc18['oupJq'](_0x458fe1[_0x1922ae(0x526)],0x8))return'';return _0x24dc18[_0x1922ae(0x269)]('ā¢'[_0x1922ae(0x552)](_0x24dc18[_0x1922ae(0x2c4)](_0x458fe1[_0x1922ae(0x526)],0x4)),_0x458fe1[_0x1922ae(0x222)](-0x4));}else{_0x169e4d[_0x1922ae(0x6c8)]('ā\x20Error\x20stopping\x20UIAutomator2\x20for\x20'+_0x1b141b+':',_0x47a89c['message']);const _0x22b21e={};return _0x22b21e[_0x1922ae(0x859)]=![],_0x22b21e[_0x1922ae(0x6c8)]=_0x4247c9[_0x1922ae(0x6dc)],_0x22b21e;}};_0x245842['json']({'provider':_0x405c0b[_0x4d5ac7(0x3f9)],'model':_0x405c0b[_0x4d5ac7(0x695)],'openai_api_key':_0x24dc18[_0x4d5ac7(0x783)](_0x3e6127,_0x405c0b[_0x4d5ac7(0x619)]),'gemini_api_key':_0x24dc18[_0x4d5ac7(0x783)](_0x3e6127,_0x405c0b['gemini_api_key']),'claude_api_key':_0x24dc18['McGHB'](_0x3e6127,_0x405c0b['claude_api_key']),'github_token':_0x24dc18[_0x4d5ac7(0x783)](_0x3e6127,_0x405c0b['github_token']),'groq_api_key':_0x24dc18[_0x4d5ac7(0x783)](_0x3e6127,_0x405c0b[_0x4d5ac7(0x2e8)]),'cohere_api_key':_0x24dc18[_0x4d5ac7(0x54d)](_0x3e6127,_0x405c0b['cohere_api_key']),'mistral_api_key':_0x24dc18[_0x4d5ac7(0x689)](_0x3e6127,_0x405c0b['mistral_api_key']),'has_openai_key':!!_0x405c0b[_0x4d5ac7(0x619)],'has_gemini_key':!!_0x405c0b['gemini_api_key'],'has_claude_key':!!_0x405c0b['claude_api_key'],'has_github_token':!!_0x405c0b['github_token'],'has_groq_key':!!_0x405c0b['groq_api_key'],'has_cohere_key':!!_0x405c0b[_0x4d5ac7(0x6fc)],'has_mistral_key':!!_0x405c0b[_0x4d5ac7(0x74d)]});}catch(_0x55cc13){if(_0x24dc18[_0x4d5ac7(0x438)](_0x24dc18[_0x4d5ac7(0x206)],_0x24dc18['sUcZR'])){const _0x53111b={};_0x53111b[_0x4d5ac7(0x859)]=![],_0x53111b['error']=_0x100155[_0x4d5ac7(0x6dc)],_0xbbf15e[_0x5f1d9b[_0x4d5ac7(0x719)]]=_0x53111b;}else{const _0xb2b866={};_0xb2b866['success']=![],_0xb2b866[_0x4d5ac7(0x6c8)]=_0x55cc13['message'],_0x245842[_0x4d5ac7(0x4d0)](0x1f4)[_0x4d5ac7(0x843)](_0xb2b866);}}}),app['post'](_0x47c41d(0x499),async(_0x51fac6,_0x194e5d)=>{const _0x48ddf8=_0x47c41d,_0x4113c3={'MLpKO':_0x48ddf8(0x828),'eaqUk':function(_0x9a2e6,_0x29a024){return _0x9a2e6(_0x29a024);},'zNvbE':function(_0x175d7e,_0x26a1cd){return _0x175d7e!==_0x26a1cd;},'wIKkt':_0x48ddf8(0x602),'pANOy':function(_0x261c0a,_0x16927d){return _0x261c0a===_0x16927d;},'lLnDl':_0x48ddf8(0x4e1),'OJRUx':function(_0x2fe219,_0x24b4d2){return _0x2fe219!==_0x24b4d2;},'YRoMy':_0x48ddf8(0x7ac),'IwoXt':_0x48ddf8(0x532),'cewRi':'POjfn','ACTLI':_0x48ddf8(0x587),'GzSqa':_0x48ddf8(0x7f3)};try{const {provider:_0x31a5a4,model:_0x1449ad,openai_api_key:_0x4c8994,gemini_api_key:_0x5892bf,claude_api_key:_0x564416,github_token:_0x52aea8,groq_api_key:_0x1e2242,cohere_api_key:_0x23f340,mistral_api_key:_0xc6b491}=_0x51fac6['body'],_0x1329af=path[_0x48ddf8(0x5c8)](__dirname,'../../.env');let _0x46da3e='#\x20AI\x20Provider\x20Configuration\x0aAI_PROVIDER='+_0x31a5a4+'\x0a';_0x1449ad&&(_0x46da3e+=_0x48ddf8(0x79e)+_0x1449ad+'\x0a');if(_0x4c8994){if('YvSoq'!==_0x4113c3[_0x48ddf8(0x72e)]){const _0x11a4cb=_0x4113c3[_0x48ddf8(0x856)]['split']('|');let _0x4ce3d3=0x0;while(!![]){switch(_0x11a4cb[_0x4ce3d3++]){case'0':_0x521992[_0x48ddf8(0x26d)]='('+_0x22c041['x']+','+_0x33126e['y']+')\x20'+_0x23bee3[_0x48ddf8(0x29e)]+'x'+_0x3506ae[_0x48ddf8(0x766)];continue;case'1':_0x3ee0f4['x']=_0x4113c3[_0x48ddf8(0x405)](_0x2902de,_0x5b8504[0x1]);continue;case'2':_0x31f32e['height']=_0x3f7f95(_0x2a832f[0x4]);continue;case'3':_0x1fb553[_0x48ddf8(0x29e)]=_0x4113c3[_0x48ddf8(0x405)](_0x149453,_0x56c822[0x3]);continue;case'4':_0x56e504['y']=_0x4113c3['eaqUk'](_0x3d75ab,_0x2112fe[0x2]);continue;}break;}}else _0x46da3e+='OPENAI_API_KEY='+_0x4c8994+'\x0a';}if(_0x5892bf){if(_0x4113c3[_0x48ddf8(0x3a4)](_0x4113c3[_0x48ddf8(0x356)],_0x4113c3['lLnDl']))_0x46da3e+='GEMINI_API_KEY='+_0x5892bf+'\x0a';else{const [_0x4e99d0]=_0x12b168[_0x48ddf8(0x307)](':');return _0x4c8874[_0x48ddf8(0x685)]()&&VTeuxY[_0x48ddf8(0x7e6)](_0x4e99d0,_0x3ba493);}}_0x564416&&(_0x46da3e+=_0x48ddf8(0x519)+_0x564416+'\x0a');_0x52aea8&&(_0x46da3e+=_0x48ddf8(0x3a3)+_0x52aea8+'\x0a');_0x1e2242&&(_0x4113c3[_0x48ddf8(0x627)](_0x48ddf8(0x7ac),_0x4113c3['YRoMy'])?_0x1de5d2[_0x48ddf8(0x61d)](_0x48ddf8(0x657)):_0x46da3e+=_0x48ddf8(0x8a9)+_0x1e2242+'\x0a');if(_0x23f340){if(_0x4113c3[_0x48ddf8(0x3a4)](_0x4113c3[_0x48ddf8(0x75a)],_0x4113c3[_0x48ddf8(0x35a)])){const _0xaaf9b0={};_0xaaf9b0[_0x48ddf8(0x859)]=![],_0xaaf9b0[_0x48ddf8(0x6c8)]=_0x506097[_0x48ddf8(0x6dc)],_0x5163f8[_0x48ddf8(0x4d0)](0x1f4)['json'](_0xaaf9b0);}else _0x46da3e+=_0x48ddf8(0x236)+_0x23f340+'\x0a';}_0xc6b491&&(_0x46da3e+=_0x48ddf8(0x591)+_0xc6b491+'\x0a');process.env.WDA_PATH&&(_0x46da3e+=_0x48ddf8(0x4f0)+process.env.WDA_PATH+'\x0a');await fs[_0x48ddf8(0x35b)](_0x1329af,_0x46da3e),process.env.AI_PROVIDER=_0x31a5a4;if(_0x1449ad)process.env.AI_MODEL=_0x1449ad;if(_0x4c8994)process.env.OPENAI_API_KEY=_0x4c8994;if(_0x5892bf)process.env.GEMINI_API_KEY=_0x5892bf;if(_0x564416)process.env.CLAUDE_API_KEY=_0x564416;if(_0x52aea8)process.env.GITHUB_TOKEN=_0x52aea8;if(_0x1e2242)process.env.GROQ_API_KEY=_0x1e2242;if(_0x23f340)process.env.COHERE_API_KEY=_0x23f340;if(_0xc6b491)process.env.MISTRAL_API_KEY=_0xc6b491;aiManager[_0x48ddf8(0x3f9)]=_0x31a5a4;if(_0x1449ad)aiManager['model']=_0x1449ad;aiManager['initializeProviders']();const _0x3f66e2={};_0x3f66e2[_0x48ddf8(0x859)]=!![],_0x3f66e2['message']=_0x4113c3[_0x48ddf8(0x805)],_0x194e5d['json'](_0x3f66e2);}catch(_0x5b350e){if(_0x4113c3[_0x48ddf8(0x8c6)]!==_0x4113c3[_0x48ddf8(0x8c6)])_0x56f265[_0x48ddf8(0x61d)](_0x48ddf8(0x657));else{const _0xe2d1fd={};_0xe2d1fd[_0x48ddf8(0x859)]=![],_0xe2d1fd[_0x48ddf8(0x6c8)]=_0x5b350e['message'],_0x194e5d[_0x48ddf8(0x4d0)](0x1f4)['json'](_0xe2d1fd);}}}),app[_0x47c41d(0x3ac)](_0x47c41d(0x5a9),(_0x46843e,_0x59f8ab)=>{const _0x7a62d8=_0x47c41d,_0x21f57e={'ibakq':_0x7a62d8(0x6c8),'uHPkN':function(_0x45b4f3,_0x38ed21){return _0x45b4f3===_0x38ed21;},'nrUUF':'LXliL','EIdGx':function(_0x4ea49e,_0x1f85b8){return _0x4ea49e(_0x1f85b8);},'UDUxf':_0x7a62d8(0x586)};try{if(_0x21f57e['uHPkN'](_0x21f57e[_0x7a62d8(0x32d)],'CVRKd')){_0x1b5848[_0x7a62d8(0x6c8)](_0x7a62d8(0x315)+_0x3620b5[_0x7a62d8(0x5c8)](',\x20')+']');const _0x49ee77={};return _0x49ee77['success']=![],_0x49ee77['error']='No\x20devices\x20found.\x20Please\x20refresh\x20device\x20list\x20and\x20try\x20again.',_0x192c7b(_0x49ee77);}else{const {AI_PROVIDERS_CONFIG:_0x2c9ac6}=_0x21f57e[_0x7a62d8(0x48d)](require,_0x7a62d8(0x316)),_0x1fa622={};_0x1fa622[_0x7a62d8(0x859)]=!![],_0x1fa622['providers']=_0x2c9ac6,_0x59f8ab[_0x7a62d8(0x843)](_0x1fa622);}}catch(_0x4aa2e1){if(_0x21f57e[_0x7a62d8(0x5e7)]!==_0x7a62d8(0x586)){const _0x2a0d27={};_0x2a0d27[_0x7a62d8(0x4b8)]=_0x21f57e[_0x7a62d8(0x3ae)],_0x2a0d27[_0x7a62d8(0x6dc)]=_0x339c6b['message'],_0x2a8535[_0x7a62d8(0x71d)](_0x208d0e[_0x7a62d8(0x33e)](_0x2a0d27));}else{const _0x53baff={};_0x53baff['success']=![],_0x53baff['error']=_0x4aa2e1[_0x7a62d8(0x6dc)],_0x59f8ab['status'](0x1f4)[_0x7a62d8(0x843)](_0x53baff);}}}),app[_0x47c41d(0x3ac)](_0x47c41d(0x4d8),async(_0x19678a,_0x407e6f)=>{const _0x11205c=_0x47c41d,_0x186ebc={'eRzjW':function(_0x1d634d,_0x366768){return _0x1d634d===_0x366768;},'fDJZb':_0x11205c(0x231),'GrbAX':function(_0x548f8c){return _0x548f8c();},'nQnau':function(_0x15d5b5,_0x3817de){return _0x15d5b5!==_0x3817de;},'ADfwj':_0x11205c(0x2c8),'oQSss':_0x11205c(0x2ab)};try{if(_0x186ebc[_0x11205c(0x2b6)](_0x186ebc[_0x11205c(0x22b)],_0x186ebc[_0x11205c(0x22b)])){const _0x4f35ad=await _0x186ebc[_0x11205c(0x57f)](loadDeviceConfig),_0xc4180={};_0xc4180[_0x11205c(0x859)]=!![],_0xc4180['devices']=_0x4f35ad,_0x407e6f[_0x11205c(0x843)](_0xc4180);}else{const [_0x41bf44,_0x2ac909]=_0x75706c[_0x11205c(0x307)](',');return{'name':_0x41bf44[_0x11205c(0x685)](),'packageId':_0x2ac909['trim']()};}}catch(_0xc23ed8){if(_0x186ebc['nQnau'](_0x186ebc['ADfwj'],_0x186ebc['oQSss'])){const _0x18b33b={};_0x18b33b[_0x11205c(0x859)]=![],_0x18b33b[_0x11205c(0x6c8)]=_0xc23ed8[_0x11205c(0x6dc)],_0x407e6f[_0x11205c(0x4d0)](0x1f4)[_0x11205c(0x843)](_0x18b33b);}else _0x1d1e0e[_0x11205c(0x6c8)](_0x11205c(0x6a9)+_0x1e8ffd[_0x11205c(0x6dc)]);}}),app[_0x47c41d(0x328)](_0x47c41d(0x4d8),async(_0x5cd03d,_0xe461de)=>{const _0x49b2fe=_0x47c41d,_0x39903b={'AhJcK':function(_0x516c82,_0x3415c4){return _0x516c82(_0x3415c4);},'oninH':function(_0x2ce432,_0x28b1d2,_0x120c11){return _0x2ce432(_0x28b1d2,_0x120c11);},'TsrNM':_0x49b2fe(0x377),'ZedSg':_0x49b2fe(0x886),'nMDuf':_0x49b2fe(0x44b),'FcoEW':function(_0x14389e,_0x297569){return _0x14389e!==_0x297569;},'EBnXL':_0x49b2fe(0x386),'QODEe':'ios','OaEJO':'ā
\x20Parsed\x20locator:','vsRZt':function(_0x4243c2,_0x24b591){return _0x4243c2===_0x24b591;},'nJaIH':_0x49b2fe(0x8a4),'WwDUi':_0x49b2fe(0x4e4),'dVJVn':_0x49b2fe(0x4eb),'utKht':_0x49b2fe(0x3e9),'EvObw':_0x49b2fe(0x8c7),'VMFyh':_0x49b2fe(0x664),'EysbX':_0x49b2fe(0x686),'KuLxg':'#\x20š”\x20WIRELESS\x20DEVICES:\x20Manually\x20add\x20with\x20IP\x20address\x0a','VYwMY':_0x49b2fe(0x321),'dBmQX':_0x49b2fe(0x67d),'kktaD':'#\x20\x20\x20\x20-\x20Android:\x20Enable\x20wireless\x20ADB\x20first\x0a','CPkfd':_0x49b2fe(0x635),'CNdVQ':_0x49b2fe(0x601),'RdDvs':_0x49b2fe(0x665),'ruYjq':_0x49b2fe(0x6c9),'AKNZg':function(_0xc32d81,_0x573b0e){return _0xc32d81!==_0x573b0e;},'mfvjy':_0x49b2fe(0x4fa)};try{if(_0x39903b[_0x49b2fe(0x59e)](_0x39903b['nJaIH'],_0x49b2fe(0x244)))_0x3656cb[_0x49b2fe(0x510)](),hnelrU[_0x49b2fe(0x470)](_0x1f14be,![]);else{const {devices:_0xe390a6}=_0x5cd03d[_0x49b2fe(0x3b6)];let _0x5bc095=_0x39903b[_0x49b2fe(0x7d7)];_0x5bc095+=_0x39903b[_0x49b2fe(0x381)],_0x5bc095+=_0x39903b[_0x49b2fe(0x402)],_0x5bc095+=_0x39903b[_0x49b2fe(0x3a7)],_0x5bc095+='#\x20\x0a',_0x5bc095+='#\x20š\x20USB\x20DEVICES:\x20Automatically\x20detected\x20and\x20saved\x20here\x0a',_0x5bc095+=_0x39903b['VMFyh'],_0x5bc095+=_0x39903b[_0x49b2fe(0x68b)],_0x5bc095+='#\x0a',_0x5bc095+=_0x39903b[_0x49b2fe(0x212)],_0x5bc095+=_0x39903b[_0x49b2fe(0x238)],_0x5bc095+=_0x39903b['dBmQX'],_0x5bc095+=_0x39903b[_0x49b2fe(0x6f2)],_0x5bc095+='#\x0a',_0x5bc095+=_0x49b2fe(0x819),_0x5bc095+=_0x49b2fe(0x5d2),_0x5bc095+=_0x39903b[_0x49b2fe(0x6f0)],_0x5bc095+=_0x39903b[_0x49b2fe(0x2c2)],_0x5bc095+=_0x39903b[_0x49b2fe(0x75d)],_0xe390a6['forEach'](_0x535051=>{const _0x26e057=_0x49b2fe;if(_0x39903b[_0x26e057(0x70d)](_0x26e057(0x22d),_0x39903b[_0x26e057(0x58f)])){const _0x275861=_0x535051['ip']||'',_0xc2334f=_0x535051[_0x26e057(0x581)]||_0x39903b[_0x26e057(0x331)],_0x3e20af=_0x535051[_0x26e057(0x4b8)]||_0x535051[_0x26e057(0x809)]||(_0x275861?_0x26e057(0x501):_0x26e057(0x760));_0x5bc095+=_0x535051[_0x26e057(0x719)]+','+_0x535051[_0x26e057(0x200)]+','+_0x275861+','+_0xc2334f+','+_0x3e20af+'\x0a';}else{_0x36d05f[_0x26e057(0x61d)](_0x26e057(0x5d6)),_0x24024e[_0x26e057(0x61d)]('Tried\x20paths:',_0x319be4);try{_0x2d4106['log'](_0x26e057(0x654));const _0xfcc56b=hnelrU['oninH'](_0x558edb,_0x26e057(0x684),{'encoding':hnelrU[_0x26e057(0x87e)]});_0x4650fa[_0x26e057(0x61d)](_0xfcc56b);const _0x3fdd8d={};_0x3fdd8d[_0x26e057(0x859)]=![],_0x3fdd8d['message']=hnelrU[_0x26e057(0x4a9)],_0x179603(_0x3fdd8d);}catch(_0x58362f){hnelrU[_0x26e057(0x470)](_0x3ff76a,{'success':![],'message':hnelrU[_0x26e057(0x872)]});}}}),await fs[_0x49b2fe(0x35b)](DEVICE_CONFIG,_0x5bc095);const _0x5ee05e={};_0x5ee05e['success']=!![],_0x5ee05e[_0x49b2fe(0x6dc)]=_0x39903b[_0x49b2fe(0x7db)],_0xe461de[_0x49b2fe(0x843)](_0x5ee05e);}}catch(_0x35ff69){if(_0x39903b[_0x49b2fe(0x3e8)](_0x49b2fe(0x4fa),_0x39903b[_0x49b2fe(0x322)]))_0x402f9[_0x49b2fe(0x61d)](_0x39903b[_0x49b2fe(0x8c5)],_0x1cf0ce),_0x4045ec[_0x49b2fe(0x823)](_0x42dbc4);else{const _0xa26c2d={};_0xa26c2d['success']=![],_0xa26c2d[_0x49b2fe(0x6c8)]=_0x35ff69[_0x49b2fe(0x6dc)],_0xe461de[_0x49b2fe(0x4d0)](0x1f4)[_0x49b2fe(0x843)](_0xa26c2d);}}}),app[_0x47c41d(0x3ac)](_0x47c41d(0x2f0),async(_0x51bc46,_0x4f6f58)=>{const _0x33b99d=_0x47c41d,_0x89b3e7={};_0x89b3e7[_0x33b99d(0x7c7)]=_0x33b99d(0x377);const _0x289d49=_0x89b3e7;try{const _0x30a181=await fs[_0x33b99d(0x7fe)](APPS_CONFIG,_0x289d49['iDjBl']),_0x2f266a=_0x30a181[_0x33b99d(0x307)]('\x0a')[_0x33b99d(0x3c2)](_0x3c652f=>_0x3c652f[_0x33b99d(0x685)]()&&!_0x3c652f[_0x33b99d(0x75e)]('#'))['map'](_0x3432a0=>{const _0x4ea0c0=_0x33b99d,[_0x337270,_0x5c8484]=_0x3432a0['split'](',');return{'name':_0x337270[_0x4ea0c0(0x685)](),'packageId':_0x5c8484[_0x4ea0c0(0x685)]()};}),_0x3bf2f8={};_0x3bf2f8[_0x33b99d(0x859)]=!![],_0x3bf2f8[_0x33b99d(0x76a)]=_0x2f266a,_0x4f6f58[_0x33b99d(0x843)](_0x3bf2f8);}catch(_0x3f8653){const _0x2a774d={};_0x2a774d[_0x33b99d(0x859)]=![],_0x2a774d[_0x33b99d(0x6c8)]=_0x3f8653['message'],_0x4f6f58['status'](0x1f4)['json'](_0x2a774d);}}),app[_0x47c41d(0x328)](_0x47c41d(0x50f),async(_0x5f137c,_0x5edee2)=>{const _0x122ded=_0x47c41d,_0x4c7a3d={'oDOlT':_0x122ded(0x708),'uciUO':function(_0x10e3a8,_0x5874fe){return _0x10e3a8===_0x5874fe;},'mHVFs':'devices_updated','rgomp':function(_0x244637,_0xcb257b){return _0x244637!==_0xcb257b;},'VXEBy':_0x122ded(0x29b),'XJCDZ':_0x122ded(0x7b8),'nOlgp':_0x122ded(0x449),'sYoee':function(_0x19cf0f,_0x3ae0f2){return _0x19cf0f(_0x3ae0f2);},'JzSge':_0x122ded(0x524),'PkbnR':_0x122ded(0x2f9),'anUoz':_0x122ded(0x3ad),'Cglgs':_0x122ded(0x6d3),'DJzhL':function(_0x31233f,_0x44d5df){return _0x31233f(_0x44d5df);},'fVczp':_0x122ded(0x6cd),'xkkSN':_0x122ded(0x40b),'gItNa':function(_0xea238,_0x2a4b58,_0x38c44f,_0x50cd32){return _0xea238(_0x2a4b58,_0x38c44f,_0x50cd32);},'CrBmM':function(_0x52c9b2,_0x313c61){return _0x52c9b2===_0x313c61;},'ywEgS':_0x122ded(0x70a),'fqEuB':function(_0x1b837c,_0x1086a4){return _0x1b837c===_0x1086a4;},'GfRFO':_0x122ded(0x713),'NxNyH':'ltmVm','hoSxv':function(_0x21659c,_0x26af4a){return _0x21659c===_0x26af4a;},'vgeyZ':function(_0x9a3e79,_0x1f5e9f){return _0x9a3e79!==_0x1f5e9f;},'TtVkp':_0x122ded(0x29f),'LWpnC':_0x122ded(0x237),'NEpJF':'ā\x20No\x20output\x20found\x20in\x20results','JCFAI':_0x122ded(0x2cd),'uduUg':_0x122ded(0x428),'ZmWRV':_0x122ded(0x56c)};try{const {deviceName:_0x5495b6}=_0x5f137c['body'];if(!_0x5495b6){if(_0x4c7a3d[_0x122ded(0x663)]===_0x4c7a3d[_0x122ded(0x663)]){const _0xa8f330={};return _0xa8f330[_0x122ded(0x859)]=![],_0xa8f330[_0x122ded(0x6c8)]=_0x4c7a3d[_0x122ded(0x23e)],_0x5edee2['status'](0x190)[_0x122ded(0x843)](_0xa8f330);}else _0x18d53f[_0x5d8177][_0x122ded(0x4d0)]=PYSPwx['oDOlT'];}console[_0x122ded(0x61d)](_0x122ded(0x51b)+_0x5495b6);const _0x3e9e1a=connectedDevices[_0x122ded(0x715)](_0x385e77=>_0x385e77[_0x122ded(0x719)]===_0x5495b6);if(!_0x3e9e1a){const _0x131f0a={};return _0x131f0a['success']=![],_0x131f0a['error']=_0x122ded(0x606),_0x5edee2['status'](0x194)[_0x122ded(0x843)](_0x131f0a);}if(_0x4c7a3d['uciUO'](_0x3e9e1a[_0x122ded(0x581)],_0x122ded(0x705))){if(_0x4c7a3d['anUoz']!==_0x4c7a3d[_0x122ded(0x3df)]){const _0x165118=androidSessions[_0x122ded(0x3ac)](_0x3e9e1a[_0x122ded(0x200)]);if(!_0x165118){console[_0x122ded(0x61d)](_0x122ded(0x311)+_0x5495b6+_0x122ded(0x517));try{const _0x454047=await _0x4c7a3d['DJzhL'](connectToDevice,_0x3e9e1a);if(!_0x454047[_0x122ded(0x859)]){if(_0x4c7a3d['uciUO'](_0x4c7a3d[_0x122ded(0x427)],_0x122ded(0x6cd))){const _0x339141={};return _0x339141[_0x122ded(0x859)]=![],_0x339141['error']=_0x4c7a3d[_0x122ded(0x224)],_0x5edee2['status'](0x1f4)['json'](_0x339141);}else{const _0x1ca4de=_0x24938d[_0x122ded(0x6c5)](_0x59b66c=>_0x59b66c[_0x122ded(0x719)]===_0x417281);PYSPwx[_0x122ded(0x74e)](_0x1ca4de,-0x1)&&(_0x4e0833[_0x1ca4de][_0x122ded(0x4d0)]=PYSPwx[_0x122ded(0x85f)],_0xd5ba5['clients'][_0x122ded(0x68d)](_0x5d13e0=>{const _0x27fc19=_0x122ded;if(PYSPwx[_0x27fc19(0x66b)](_0x5d13e0[_0x27fc19(0x24e)],_0x575ca7[_0x27fc19(0x3ba)])){const _0x3b184e={};_0x3b184e['type']=PYSPwx[_0x27fc19(0x1ed)],_0x3b184e[_0x27fc19(0x658)]=_0xb40d24,_0x5d13e0[_0x27fc19(0x71d)](_0x12ff33[_0x27fc19(0x33e)](_0x3b184e));}}));const _0x3a551e={};_0x3a551e[_0x122ded(0x859)]=!![],_0x3a551e[_0x122ded(0x6dc)]=_0x122ded(0x605)+_0x1e31e3+_0x122ded(0x42e),_0x5821c6(_0x3a551e);}}await new Promise(_0x5740dc=>setTimeout(_0x5740dc,0x7d0));}catch(_0x5b4ec3){const _0x420e68={};return _0x420e68[_0x122ded(0x859)]=![],_0x420e68[_0x122ded(0x6c8)]='Auto-connection\x20failed:\x20'+_0x5b4ec3[_0x122ded(0x6dc)],_0x5edee2[_0x122ded(0x4d0)](0x1f4)['json'](_0x420e68);}}}else _0x48bc0=_0x16c3f8[_0x122ded(0x63f)][_0x122ded(0x2d0)](_0x4dc74d=>_0x4dc74d[_0x122ded(0x334)]||_0x4dc74d[_0x122ded(0x6de)]);}const _0x43b141=await _0x4c7a3d[_0x122ded(0x8b0)](executeCommand,[_0x5495b6],'getLocators',null);console['log'](_0x122ded(0x47d)+_0x43b141[_0x122ded(0x859)]),console[_0x122ded(0x61d)]('Results\x20array\x20length:\x20'+(_0x43b141[_0x122ded(0x239)]?.[_0x122ded(0x526)]||0x0));if(_0x43b141[_0x122ded(0x859)]&&_0x43b141[_0x122ded(0x239)]){if(_0x4c7a3d[_0x122ded(0x43a)](_0x4c7a3d[_0x122ded(0x219)],_0x4c7a3d[_0x122ded(0x219)])){let _0x374ac2='';for(const _0x578a5d of _0x43b141[_0x122ded(0x239)]){console['log'](_0x122ded(0x245),_0x578a5d);if(_0x4c7a3d[_0x122ded(0x8aa)](_0x578a5d['status'],_0x4c7a3d[_0x122ded(0x692)])&&_0x578a5d['value']&&_0x578a5d[_0x122ded(0x4d6)][_0x122ded(0x239)])for(const _0xadb9a3 of _0x578a5d[_0x122ded(0x4d6)]['results']){if(_0x4c7a3d[_0x122ded(0x53a)]===_0x4c7a3d[_0x122ded(0x53a)]){console[_0x122ded(0x61d)](_0x122ded(0x732)+_0xadb9a3[_0x122ded(0x4d0)]);if(_0x4c7a3d[_0x122ded(0x27d)](_0xadb9a3[_0x122ded(0x4d0)],_0x4c7a3d['GfRFO'])&&_0xadb9a3[_0x122ded(0x4d6)]){if(_0xadb9a3[_0x122ded(0x4d6)][_0x122ded(0x859)]&&_0xadb9a3[_0x122ded(0x4d6)][_0x122ded(0x88b)]){if(_0x4c7a3d['vgeyZ'](_0x4c7a3d[_0x122ded(0x3da)],_0x4c7a3d[_0x122ded(0x3da)])){const _0x31c88f={};_0x31c88f[_0x122ded(0x4b8)]='command_output',_0x31c88f[_0x122ded(0x1da)]=PYSPwx[_0x122ded(0x47f)],_0x31c88f['devices']=_0x4fa415,_0x1e11e4['send'](_0x3ce55f[_0x122ded(0x33e)](_0x31c88f));}else{_0x374ac2=_0xadb9a3[_0x122ded(0x4d6)][_0x122ded(0x88b)],console[_0x122ded(0x61d)](_0x122ded(0x43f)+_0x374ac2[_0x122ded(0x526)]+_0x122ded(0x774));break;}}else{if(_0xadb9a3['value'][_0x122ded(0x6c8)]){console[_0x122ded(0x61d)](_0x122ded(0x78c),_0xadb9a3[_0x122ded(0x4d6)][_0x122ded(0x6c8)]);const _0x2a990f={};return _0x2a990f[_0x122ded(0x859)]=![],_0x2a990f[_0x122ded(0x6c8)]=_0x4c7a3d[_0x122ded(0x77f)],_0x5edee2[_0x122ded(0x4d0)](0x1f4)[_0x122ded(0x843)](_0x2a990f);}}}}else _0x43c1f5[_0x122ded(0x6c8)](_0x122ded(0x8ac)+_0x33bdb3['message']);}if(_0x374ac2)break;}if(!_0x374ac2){console[_0x122ded(0x61d)](_0x4c7a3d[_0x122ded(0x344)]),console['log'](_0x4c7a3d[_0x122ded(0x6ba)],JSON[_0x122ded(0x33e)](_0x43b141,null,0x2));const _0x142837={};return _0x142837[_0x122ded(0x859)]=![],_0x142837[_0x122ded(0x6c8)]=_0x4c7a3d['uduUg'],_0x5edee2[_0x122ded(0x4d0)](0x1f4)['json'](_0x142837);}const _0x5308f7=_0x4c7a3d[_0x122ded(0x4ce)](parseLocatorsOutput,_0x374ac2);console[_0x122ded(0x61d)]('ā
\x20Parsed\x20'+_0x5308f7[_0x122ded(0x526)]+_0x122ded(0x536));const _0x460f29=_0x5308f7[_0x122ded(0x3c2)](_0x10400d=>_0x10400d[_0x122ded(0x719)]||_0x10400d[_0x122ded(0x5f1)]||_0x10400d[_0x122ded(0x243)]);console[_0x122ded(0x61d)](_0x122ded(0x6db)+_0x460f29['length']+_0x122ded(0x32a));const _0x5ed993={};_0x5ed993[_0x122ded(0x859)]=!![],_0x5ed993[_0x122ded(0x7ad)]=_0x460f29,_0x5edee2['json'](_0x5ed993);}else _0x20f45c[_0x122ded(0x6c8)](PYSPwx[_0x122ded(0x223)],_0x4a37a9),PYSPwx[_0x122ded(0x4ce)](_0x175ace,_0x5a1610);}else{console[_0x122ded(0x61d)](_0x4c7a3d[_0x122ded(0x58a)]);const _0x484305={};_0x484305['success']=![],_0x484305[_0x122ded(0x6c8)]=_0x122ded(0x623),_0x5edee2['status'](0x1f4)[_0x122ded(0x843)](_0x484305);}}catch(_0x1692b5){console[_0x122ded(0x6c8)](_0x122ded(0x232),_0x1692b5);const _0x560f31={};_0x560f31[_0x122ded(0x859)]=![],_0x560f31[_0x122ded(0x6c8)]=_0x1692b5[_0x122ded(0x6dc)],_0x5edee2[_0x122ded(0x4d0)](0x1f4)[_0x122ded(0x843)](_0x560f31);}}),app[_0x47c41d(0x328)](_0x47c41d(0x82d),async(_0x250c14,_0x42e60c)=>{const _0x5e918e=_0x47c41d,_0x2a01bf={'VSAII':function(_0x5bbcee,_0x30ed48){return _0x5bbcee===_0x30ed48;},'yNNIm':_0x5e918e(0x2f9),'SRrRV':function(_0x1d6f3a,_0x418550){return _0x1d6f3a!==_0x418550;},'DILOT':function(_0x349b01,_0x4cb150){return _0x349b01!==_0x4cb150;},'GLnya':_0x5e918e(0x38d),'UEQbX':_0x5e918e(0x38a),'YEccl':function(_0x283e90,_0x5d09f2,_0x160788,_0x53f2a6){return _0x283e90(_0x5d09f2,_0x160788,_0x53f2a6);},'TRmYC':function(_0x3b8308,_0x12e1d9){return _0x3b8308!==_0x12e1d9;},'QvKBx':_0x5e918e(0x2d9),'DTcOq':_0x5e918e(0x221),'rKkaE':_0x5e918e(0x483)};try{if(_0x2a01bf[_0x5e918e(0x369)](_0x5e918e(0x8b4),_0x5e918e(0x4da))){const _0x3bc871=_0x280d1e[_0x5e918e(0x3ac)](_0x41b6f8[_0x5e918e(0x200)]);_0x3bc871&&qAHqSq['VSAII'](_0x3bc871[_0x5e918e(0x4d0)],_0x5e918e(0x29b))&&(_0xb30318[_0x5e918e(0x4d0)]=_0x5e918e(0x29b),_0x3bc871['sessionId']&&(_0x33719a[_0x5e918e(0x39b)]=_0x3bc871['sessionId']));}else{const {deviceName:_0x50e5fa,locatorName:_0x2f73ab,x:_0x1fb9a6,y:_0x2683fb}=_0x250c14['body'];if(!_0x50e5fa){const _0x2c85b7={};return _0x2c85b7[_0x5e918e(0x859)]=![],_0x2c85b7[_0x5e918e(0x6c8)]=_0x2a01bf[_0x5e918e(0x28d)],_0x42e60c[_0x5e918e(0x4d0)](0x190)['json'](_0x2c85b7);}let _0x153259;if(_0x2a01bf[_0x5e918e(0x7b1)](_0x1fb9a6,undefined)&&_0x2a01bf[_0x5e918e(0x865)](_0x2683fb,undefined))_0x153259=_0x5e918e(0x351)+_0x1fb9a6+','+_0x2683fb,console[_0x5e918e(0x61d)](_0x5e918e(0x589)+_0x1fb9a6+','+_0x2683fb+')\x20on\x20device:\x20'+_0x50e5fa);else{if(_0x2f73ab){if(_0x2a01bf['GLnya']===_0x2a01bf[_0x5e918e(0x522)])_0x153259='click\x20\x22'+_0x2f73ab+'\x22',console[_0x5e918e(0x61d)](_0x5e918e(0x8c1)+_0x2f73ab+_0x5e918e(0x64a)+_0x50e5fa);else{_0x1967f9[_0x5e918e(0x6c8)](_0x5e918e(0x4d3),_0x3e4f60);const _0x3bf916={};_0x3bf916[_0x5e918e(0x859)]=![],_0x3bf916[_0x5e918e(0x6c8)]=_0x1ecfe0[_0x5e918e(0x6dc)],_0x482bbd[_0x5e918e(0x4d0)](0x1f4)[_0x5e918e(0x843)](_0x3bf916);}}else{const _0x5ebb3e={};return _0x5ebb3e[_0x5e918e(0x859)]=![],_0x5ebb3e[_0x5e918e(0x6c8)]=_0x2a01bf[_0x5e918e(0x34b)],_0x42e60c[_0x5e918e(0x4d0)](0x190)[_0x5e918e(0x843)](_0x5ebb3e);}}const _0x1462cf=await _0x2a01bf[_0x5e918e(0x4a3)](executeCommand,[_0x50e5fa],_0x153259,null);if(_0x1462cf['success']){const _0x28996f={};_0x28996f['success']=!![],_0x28996f['message']='Tap\x20executed\x20successfully',_0x42e60c[_0x5e918e(0x843)](_0x28996f);}else{if(_0x2a01bf[_0x5e918e(0x745)](_0x2a01bf[_0x5e918e(0x318)],_0x5e918e(0x472))){const _0x217134={};_0x217134[_0x5e918e(0x859)]=![],_0x217134[_0x5e918e(0x6c8)]=_0x2a01bf[_0x5e918e(0x5ea)],_0x42e60c[_0x5e918e(0x4d0)](0x1f4)['json'](_0x217134);}else _0x322240[_0x5e918e(0x61d)](_0x5e918e(0x64d)+_0x51f021[_0x5e918e(0x39b)]);}}}catch(_0x4c7bc3){console[_0x5e918e(0x6c8)](_0x2a01bf[_0x5e918e(0x4e9)],_0x4c7bc3);const _0x3a0ae9={};_0x3a0ae9[_0x5e918e(0x859)]=![],_0x3a0ae9[_0x5e918e(0x6c8)]=_0x4c7bc3[_0x5e918e(0x6dc)],_0x42e60c[_0x5e918e(0x4d0)](0x1f4)[_0x5e918e(0x843)](_0x3a0ae9);}});function parseLocatorsOutput(_0x2ebc17){const _0x229e2a=_0x47c41d,_0x4c82e4={'huFEo':_0x229e2a(0x29b),'DKDGq':function(_0x3399c6,_0x287fdf){return _0x3399c6!==_0x287fdf;},'uVyHq':'devices_updated','huIgJ':_0x229e2a(0x254),'tNYuS':function(_0x32a999,_0x4707cc,_0x4ba97a,_0x505c8d,_0x58573e){return _0x32a999(_0x4707cc,_0x4ba97a,_0x505c8d,_0x58573e);},'YvfhJ':_0x229e2a(0x4cc),'cVQyv':_0x229e2a(0x2ec),'IFpIo':'Output\x20length:','fVJaf':function(_0x5ba26c,_0x4e30d6){return _0x5ba26c===_0x4e30d6;},'DsJqn':_0x229e2a(0x643),'bAFaN':_0x229e2a(0x306),'yiVEq':_0x229e2a(0x4b2),'uQHzW':_0x229e2a(0x7b3),'twwfC':'NrbrK','xIipt':function(_0x4fe03a,_0x1805d9){return _0x4fe03a===_0x1805d9;},'ZphsJ':_0x229e2a(0x75c),'ozNhC':_0x229e2a(0x810),'pANxG':'not\x20array','TuNpQ':_0x229e2a(0x7af),'UYGaJ':_0x229e2a(0x1db),'ZfXRa':_0x229e2a(0x62b),'uVpGl':'AOTbG','Mkiap':function(_0x55490e,_0x250c79){return _0x55490e===_0x250c79;},'RBMBw':_0x229e2a(0x6bb),'LTDIE':'FraQZ','QHnVS':function(_0x551892,_0x47d576){return _0x551892<_0x47d576;},'ZEwwB':_0x229e2a(0x36a),'MGetS':_0x229e2a(0x6d6),'zagqg':_0x229e2a(0x2da),'xKgbp':function(_0x5105e8,_0x522c37){return _0x5105e8(_0x522c37);},'ptcgy':_0x229e2a(0x1ee),'dkNPS':_0x229e2a(0x3a1),'HVWKl':_0x229e2a(0x395),'lKOoZ':function(_0x1170d6,_0x157224){return _0x1170d6===_0x157224;},'HvPIZ':'KfAMG','ieofK':function(_0x35353a,_0x4432c6){return _0x35353a(_0x4432c6);},'sukDV':_0x229e2a(0x491),'siAiw':'ā
\x20Parsed\x20locator:','kAFCm':function(_0x1c6bac,_0x570ea1){return _0x1c6bac!==_0x570ea1;},'GPsMw':_0x229e2a(0x508),'CUrMB':_0x229e2a(0x286)};console[_0x229e2a(0x61d)](_0x4c82e4[_0x229e2a(0x679)]),console['log'](_0x4c82e4[_0x229e2a(0x5ba)],_0x2ebc17?.[_0x229e2a(0x526)]||0x0);if(!_0x2ebc17){if(_0x4c82e4[_0x229e2a(0x70f)](_0x4c82e4[_0x229e2a(0x885)],_0x4c82e4['DsJqn']))return console[_0x229e2a(0x61d)](_0x4c82e4[_0x229e2a(0x672)]),[];else _0x5a873b[_0x334199][_0x229e2a(0x4d0)]=wwUbtT[_0x229e2a(0x57a)];}const _0x5bbba6=_0x2ebc17[_0x229e2a(0x307)]('\x0a');for(const _0x6c3e04 of _0x5bbba6){if(_0x4c82e4[_0x229e2a(0x70f)]('sOcEp',_0x4c82e4[_0x229e2a(0x217)])){const _0x3996dd=_0x6c3e04['trim']();if(_0x3996dd[_0x229e2a(0x75e)]('[')||_0x3996dd['startsWith']('{')){if(_0x4c82e4[_0x229e2a(0x73f)](_0x4c82e4[_0x229e2a(0x8bd)],_0x4c82e4['twwfC']))try{if(_0x4c82e4['xIipt'](_0x229e2a(0x75c),_0x4c82e4[_0x229e2a(0x6eb)])){const _0x4df6e8=JSON[_0x229e2a(0x1f8)](_0x3996dd);return console['log'](_0x4c82e4['ozNhC'],Array[_0x229e2a(0x39e)](_0x4df6e8)?_0x4df6e8['length']:_0x4c82e4[_0x229e2a(0x370)]),Array[_0x229e2a(0x39e)](_0x4df6e8)?_0x4df6e8:[];}else{const _0x5343fb={};_0x5343fb[_0x229e2a(0x859)]=![],_0x5343fb[_0x229e2a(0x6c8)]=_0x384f7d[_0x229e2a(0x6dc)],_0x14d4fb[_0x229e2a(0x4d0)](0x1f4)[_0x229e2a(0x843)](_0x5343fb);}}catch(_0x4daf6a){console[_0x229e2a(0x61d)](_0x4c82e4[_0x229e2a(0x63b)],_0x4daf6a['message']);}else{const _0x3b72aa={};_0x3b72aa[_0x229e2a(0x859)]=![],_0x3b72aa[_0x229e2a(0x6c8)]=_0x5ab864[_0x229e2a(0x6dc)],_0x2943b3['status'](0x1f4)[_0x229e2a(0x843)](_0x3b72aa);}}}else{const _0x464a18={};_0x464a18['FunTd']='devices_updated';const _0xe71f3c=_0x464a18;wwUbtT[_0x229e2a(0x73f)](_0x6d7d62,-0x1)&&(_0x1bf18c[_0x3b9689][_0x229e2a(0x4d0)]=wwUbtT[_0x229e2a(0x57a)],_0x22a2ad[_0x229e2a(0x284)][_0x229e2a(0x68d)](_0x5053b3=>{const _0x2af3af=_0x229e2a;if(_0x5053b3[_0x2af3af(0x24e)]===_0x3ecc3a['OPEN']){const _0x34071a={};_0x34071a[_0x2af3af(0x4b8)]=_0xe71f3c[_0x2af3af(0x35d)],_0x34071a[_0x2af3af(0x658)]=_0x376dbe,_0x5053b3[_0x2af3af(0x71d)](_0x1c5efe[_0x2af3af(0x33e)](_0x34071a));}})),_0x121d23='Connected\x20to\x20'+_0x5014fe+_0x229e2a(0x42e);}}console['log'](_0x4c82e4[_0x229e2a(0x782)]);const _0x990e15=[];console[_0x229e2a(0x61d)](_0x4c82e4[_0x229e2a(0x6ec)],_0x5bbba6['length']);for(const _0x948680 of _0x5bbba6){if(_0x4c82e4[_0x229e2a(0x648)]!==_0x229e2a(0x5c2)){const _0x51f68d={};_0x51f68d[_0x229e2a(0x859)]=![],_0x51f68d['error']=_0x580c2b[_0x229e2a(0x6dc)],_0x2de698[_0x229e2a(0x4d0)](0x1f4)['json'](_0x51f68d);}else{if(_0x948680['includes']('š')&&/^\s*\d+\./[_0x229e2a(0x270)](_0x948680))try{const _0x2b5d9b={},_0x2dcb72=_0x948680['match'](/^\s*(\d+)\./);if(_0x2dcb72)_0x2b5d9b[_0x229e2a(0x4b5)]=parseInt(_0x2dcb72[0x1]);if(_0x948680[_0x229e2a(0x310)]('ā')){if(_0x4c82e4[_0x229e2a(0x801)](_0x4c82e4[_0x229e2a(0x250)],_0x4c82e4[_0x229e2a(0x8b2)])){const _0x181797={};_0x181797[_0x229e2a(0x859)]=![],_0x181797[_0x229e2a(0x6c8)]=_0x59b51d['message'],_0x3ce1e7['status'](0x1f4)[_0x229e2a(0x843)](_0x181797);}else{const _0x5f3bbd=_0x948680[_0x229e2a(0x307)]('ā')[_0x229e2a(0x2d0)](_0x3b5b5c=>_0x3b5b5c['trim']()),_0x15983f=_0x5f3bbd[0x0][_0x229e2a(0x295)](/š\s+(.+)/);_0x15983f&&(_0x2b5d9b[_0x229e2a(0x719)]=_0x15983f[0x1][_0x229e2a(0x685)](),_0x2b5d9b[_0x229e2a(0x243)]=_0x15983f[0x1]['trim']());const _0x2b7c9f=_0x5f3bbd[0x1]?_0x5f3bbd[0x1]['match'](/\[([^\]]+)\]/):null;if(_0x2b7c9f)_0x2b5d9b[_0x229e2a(0x4b8)]=_0x2b7c9f[0x1]['trim']();for(let _0x45de81=0x2;_0x4c82e4[_0x229e2a(0x698)](_0x45de81,_0x5f3bbd[_0x229e2a(0x526)]);_0x45de81++){const _0x3a7ef5=_0x5f3bbd[_0x45de81];if(_0x3a7ef5[_0x229e2a(0x310)](_0x4c82e4['ZEwwB'])){const _0x1c8249=_0x3a7ef5['match'](/Label:([^\s]+)/);if(_0x1c8249)_0x2b5d9b[_0x229e2a(0x5f1)]=_0x1c8249[0x1];}if(_0x3a7ef5[_0x229e2a(0x310)](_0x229e2a(0x624))){const _0x2a1943=_0x3a7ef5[_0x229e2a(0x295)](/Val:([^\s]+)/);if(_0x2a1943)_0x2b5d9b['value']=_0x2a1943[0x1];}if(_0x3a7ef5['includes'](_0x4c82e4[_0x229e2a(0x548)])){const _0x4659e0=_0x3a7ef5[_0x229e2a(0x295)](/ID:([^\s]+)/);if(_0x4659e0)_0x2b5d9b[_0x229e2a(0x8c8)]=_0x4659e0[0x1];}if(_0x3a7ef5[_0x229e2a(0x310)]('@')){const _0x4b86cd=_0x3a7ef5['match'](/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);if(_0x4b86cd){const _0x5986b8=_0x4c82e4[_0x229e2a(0x38f)][_0x229e2a(0x307)]('|');let _0x2a0475=0x0;while(!![]){switch(_0x5986b8[_0x2a0475++]){case'0':_0x2b5d9b['x']=parseInt(_0x4b86cd[0x1]);continue;case'1':_0x2b5d9b[_0x229e2a(0x766)]=_0x4c82e4[_0x229e2a(0x49c)](parseInt,_0x4b86cd[0x4]);continue;case'2':_0x2b5d9b['y']=_0x4c82e4[_0x229e2a(0x49c)](parseInt,_0x4b86cd[0x2]);continue;case'3':_0x2b5d9b[_0x229e2a(0x29e)]=_0x4c82e4[_0x229e2a(0x49c)](parseInt,_0x4b86cd[0x3]);continue;case'4':_0x2b5d9b[_0x229e2a(0x26d)]='('+_0x2b5d9b['x']+','+_0x2b5d9b['y']+')\x20'+_0x2b5d9b[_0x229e2a(0x29e)]+'x'+_0x2b5d9b['height'];continue;}break;}}}if(_0x3a7ef5[_0x229e2a(0x310)](_0x4c82e4['ptcgy']))_0x2b5d9b[_0x229e2a(0x218)]=!![];if(_0x3a7ef5[_0x229e2a(0x310)](_0x4c82e4['dkNPS']))_0x2b5d9b[_0x229e2a(0x368)]=!![];if(_0x3a7ef5[_0x229e2a(0x310)](_0x4c82e4[_0x229e2a(0x3d6)]))_0x2b5d9b[_0x229e2a(0x550)]=!![];}}}else{const _0x52c9c9=_0x948680[_0x229e2a(0x295)](/š\s+([^\[]+?)(?:\s*\[|\s*Label)/);_0x52c9c9&&(_0x2b5d9b[_0x229e2a(0x719)]=_0x52c9c9[0x1]['trim'](),_0x2b5d9b[_0x229e2a(0x243)]=_0x52c9c9[0x1][_0x229e2a(0x685)]());const _0x4c3042=_0x948680[_0x229e2a(0x295)](/\[([^\]]+)\]/);if(_0x4c3042)_0x2b5d9b[_0x229e2a(0x4b8)]=_0x4c3042[0x1][_0x229e2a(0x685)]();const _0x4784d5=_0x948680['match'](/Label:([^\s]+?)(?:\s*Val:|\s*@|\s*ā)/);if(_0x4784d5)_0x2b5d9b[_0x229e2a(0x5f1)]=_0x4784d5[0x1][_0x229e2a(0x685)]();const _0x308f1e=_0x948680[_0x229e2a(0x295)](/Val:([^\s]+?)(?:\s*@|\s*ā)/);if(_0x308f1e)_0x2b5d9b['value']=_0x308f1e[0x1]['trim']();const _0x5b9bde=_0x948680[_0x229e2a(0x295)](/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);if(_0x5b9bde){if(_0x4c82e4[_0x229e2a(0x4d2)](_0x4c82e4[_0x229e2a(0x357)],_0x229e2a(0x6b1))){const _0x18a6ff={};return _0x18a6ff[_0x229e2a(0x859)]=![],_0x18a6ff[_0x229e2a(0x6c8)]=_0x229e2a(0x2f9),_0x2e7fd0[_0x229e2a(0x4d0)](0x190)['json'](_0x18a6ff);}else _0x2b5d9b['x']=_0x4c82e4[_0x229e2a(0x380)](parseInt,_0x5b9bde[0x1]),_0x2b5d9b['y']=_0x4c82e4[_0x229e2a(0x380)](parseInt,_0x5b9bde[0x2]),_0x2b5d9b[_0x229e2a(0x29e)]=_0x4c82e4['xKgbp'](parseInt,_0x5b9bde[0x3]),_0x2b5d9b[_0x229e2a(0x766)]=parseInt(_0x5b9bde[0x4]),_0x2b5d9b[_0x229e2a(0x26d)]='('+_0x2b5d9b['x']+','+_0x2b5d9b['y']+')\x20'+_0x2b5d9b['width']+'x'+_0x2b5d9b[_0x229e2a(0x766)];}const _0x107818=_0x948680[_0x229e2a(0x295)](/ID:([^\s]+)/);if(_0x107818)_0x2b5d9b[_0x229e2a(0x8c8)]=_0x107818[0x1]['trim']();_0x2b5d9b[_0x229e2a(0x218)]=_0x948680['includes'](_0x4c82e4['ptcgy']),_0x2b5d9b['enabled']=_0x948680[_0x229e2a(0x310)](_0x4c82e4[_0x229e2a(0x2ba)]);}if(_0x2b5d9b['name']||_0x2b5d9b[_0x229e2a(0x5f1)]||_0x2b5d9b[_0x229e2a(0x243)]){if(_0x4c82e4['sukDV']!==_0x229e2a(0x7e3))console[_0x229e2a(0x61d)](_0x4c82e4[_0x229e2a(0x56e)],_0x2b5d9b),_0x990e15[_0x229e2a(0x823)](_0x2b5d9b);else{const _0x4e5865={};_0x4e5865[_0x229e2a(0x4b8)]=wwUbtT[_0x229e2a(0x65b)],_0x4e5865['devices']=_0x450738,_0x14fd6c[_0x229e2a(0x71d)](_0x410572[_0x229e2a(0x33e)](_0x4e5865)),_0x108457[_0x229e2a(0x71d)](_0x36af28['stringify']({'type':wwUbtT[_0x229e2a(0x2a0)],'output':'ā
\x20'+_0x4da659+_0x229e2a(0x1f3)+'ā'[_0x229e2a(0x552)](0x32)+'\x0a','device':_0x5e373d}));}}}catch(_0x20de3e){if(_0x4c82e4['kAFCm'](_0x4c82e4[_0x229e2a(0x86a)],_0x4c82e4[_0x229e2a(0x57d)]))console['error'](_0x229e2a(0x253),_0x948680,_0x20de3e);else{_0x1be5e6&&_0x4c82e4[_0x229e2a(0x309)](_0x2d0972,_0x220302,_0x6ec759,_0x8be38b,_0x5d947d);const _0x92d717={};_0x92d717[_0x229e2a(0x4b8)]=_0x4c82e4['YvfhJ'],_0x92d717['result']=_0x41bf45,_0x33588d[_0x229e2a(0x71d)](_0x1f8864[_0x229e2a(0x33e)](_0x92d717));}}}}return console['log']('ā
\x20Total\x20parsed\x20locators:\x20'+_0x990e15[_0x229e2a(0x526)]),_0x990e15;}wss['on'](_0x47c41d(0x42f),_0x36c266=>{const _0x41146b=_0x47c41d,_0x37ef36={'NClLh':function(_0xe198ba){return _0xe198ba();},'hXsLM':_0x41146b(0x5b4),'USZyP':_0x41146b(0x326),'AFjHb':_0x41146b(0x3b0),'mnmGg':_0x41146b(0x3d9),'cmPNA':_0x41146b(0x7c5),'UAqQy':_0x41146b(0x4cc),'qnGRl':_0x41146b(0x279),'rNvsH':_0x41146b(0x3c5),'OZIMW':function(_0x24cd77,_0x4aa103,_0x16ce3e){return _0x24cd77(_0x4aa103,_0x16ce3e);},'YEErD':function(_0x49f415,_0x417670){return _0x49f415===_0x417670;},'oPjqo':_0x41146b(0x879),'WrYkF':_0x41146b(0x392),'QqDXt':_0x41146b(0x5e4),'JKaSa':_0x41146b(0x33a),'qsdwW':function(_0x43aa02,_0x534779){return _0x43aa02!==_0x534779;},'eIPDK':'vovdl','hxVrT':function(_0x4b8a89,_0x307cdb){return _0x4b8a89!==_0x307cdb;},'blZjW':'OjrRq','DQavF':_0x41146b(0x69d),'WdpQg':_0x41146b(0x7b6),'xyaXz':function(_0xcd714b,_0x34ce20,_0x23bcb2,_0x3f7a62){return _0xcd714b(_0x34ce20,_0x23bcb2,_0x3f7a62);},'xVTMk':function(_0x210f4f,_0x1a0cdc,_0x237be4,_0x239180){return _0x210f4f(_0x1a0cdc,_0x237be4,_0x239180);},'lldxK':_0x41146b(0x615),'Znyfh':_0x41146b(0x70b),'VMvvD':_0x41146b(0x569),'HIUqc':'command_output','HwRme':function(_0x1cddc9,_0x20753d,_0x327e94,_0x5d80b){return _0x1cddc9(_0x20753d,_0x327e94,_0x5d80b);},'WwAcy':_0x41146b(0x608),'tapSS':_0x41146b(0x7cc),'eKwpe':_0x41146b(0x43e),'dAiQV':_0x41146b(0x5da),'SSied':_0x41146b(0x4ae),'SfoHI':_0x41146b(0x3e5),'YXyMK':_0x41146b(0x576),'ViXmC':'ARBEF','WkeKx':_0x41146b(0x6c8),'rBjzG':'New\x20WebSocket\x20connection','hyDJH':_0x41146b(0x6dc),'CXlPp':function(_0x1c63db){return _0x1c63db();}};console[_0x41146b(0x61d)](_0x37ef36['rBjzG']),_0x36c266['on'](_0x37ef36[_0x41146b(0x4f4)],async _0x27a800=>{const _0x393cfe=_0x41146b,_0xfd35dc={'EvCuy':function(_0x18e5c3,_0x59ec94,_0x5b437a){const _0x1c8abb=_0x4c0b;return _0x37ef36[_0x1c8abb(0x711)](_0x18e5c3,_0x59ec94,_0x5b437a);},'KhBsH':function(_0x289164,_0x557864){const _0x4eb9a8=_0x4c0b;return _0x37ef36[_0x4eb9a8(0x431)](_0x289164,_0x557864);},'Kvvpi':_0x37ef36[_0x393cfe(0x704)],'GBIhT':_0x37ef36[_0x393cfe(0x851)],'zgQuB':_0x37ef36['WrYkF'],'MLtqQ':_0x37ef36['QqDXt'],'xbLff':function(_0x57058f,_0x4ec60d){const _0x38a22e=_0x393cfe;return _0x37ef36[_0x38a22e(0x431)](_0x57058f,_0x4ec60d);},'ZILMJ':_0x37ef36[_0x393cfe(0x71b)]};if(_0x37ef36[_0x393cfe(0x5be)](_0x37ef36['eIPDK'],_0x393cfe(0x3e0))){const _0x1ed0b3={};_0x1ed0b3[_0x393cfe(0x76b)]='utf-8',_0x1ed0b3['timeout']=0x7530,_0x248722=_0xfd35dc[_0x393cfe(0x67c)](_0x16b361,_0x393cfe(0x1ef)+_0x208424+_0x393cfe(0x376),_0x1ed0b3);}else try{const _0x2035ef=JSON[_0x393cfe(0x1f8)](_0x27a800);switch(_0x2035ef[_0x393cfe(0x4b8)]){case _0x393cfe(0x5c1):const {devices:_0x491e56,command:_0x399032,useAI:_0x4a04bd,aiProvider:_0x250b9e}=_0x2035ef;console['log']('\x0a'+'*'[_0x393cfe(0x552)](0x3c)),console['log'](_0x393cfe(0x26a)),console[_0x393cfe(0x61d)](_0x393cfe(0x1fd)+_0x491e56['join'](',\x20')+']'),console[_0x393cfe(0x61d)](_0x393cfe(0x561)+_0x399032+'\x22'),console[_0x393cfe(0x61d)](_0x393cfe(0x247)+_0x4a04bd);if(_0x250b9e)console[_0x393cfe(0x61d)]('AI\x20Provider:\x20'+_0x250b9e);console[_0x393cfe(0x61d)]('*'['repeat'](0x3c)+'\x0a');let _0xf0c942=_0x399032;if(_0x4a04bd){if(_0x37ef36[_0x393cfe(0x5be)](_0x393cfe(0x55d),_0x393cfe(0x55d))){const _0x45b168={'UCkxf':function(_0x373112){const _0x454d0d=_0x393cfe;return _0x37ef36[_0x454d0d(0x5b9)](_0x373112);}};return new _0x14850e(_0x4f28f7=>{const _0x30b9db=_0x393cfe;_0x224bc5?_0x2ad7c1[_0x30b9db(0x884)](_0x4f28f7):_0x45b168[_0x30b9db(0x20b)](_0x4f28f7);});}else try{if(_0x37ef36[_0x393cfe(0x750)](_0x37ef36[_0x393cfe(0x3b9)],_0x37ef36['DQavF'])){_0xf0c942=await convertNaturalLanguageToCommand(_0x399032,_0x491e56,_0x250b9e),console[_0x393cfe(0x61d)](_0x393cfe(0x716)+_0xf0c942);const _0x340cfa={};_0x340cfa[_0x393cfe(0x4b8)]=_0x393cfe(0x6a6),_0x340cfa[_0x393cfe(0x207)]=_0x399032,_0x340cfa[_0x393cfe(0x373)]=_0xf0c942,_0x340cfa[_0x393cfe(0x3f9)]=_0x250b9e||aiManager['provider'],_0x36c266[_0x393cfe(0x71d)](JSON[_0x393cfe(0x33e)](_0x340cfa));}else _0x27bcbe[_0x393cfe(0x66d)]=_0xee5d9c,_0x32ed65[_0x393cfe(0x719)]=_0x52ed95,_0x148b65[_0x393cfe(0x5a7)]=_0x37ef36[_0x393cfe(0x4e0)],_0x58c658[_0x393cfe(0x6c8)]=_0x37ef36[_0x393cfe(0x350)];}catch(_0x42fdaf){console['error'](_0x393cfe(0x80f)+_0x42fdaf['message']);const _0x2998e8={};_0x2998e8[_0x393cfe(0x4b8)]=_0x37ef36[_0x393cfe(0x3b2)],_0x2998e8[_0x393cfe(0x6c8)]=_0x42fdaf[_0x393cfe(0x6dc)],_0x2998e8['original']=_0x399032,_0x36c266[_0x393cfe(0x71d)](JSON[_0x393cfe(0x33e)](_0x2998e8));return;}}else{}const _0x204c6b=_0xf0c942[_0x393cfe(0x310)]('\x0a');_0x204c6b?_0x37ef36[_0x393cfe(0x323)](executeCommandsSequentially,_0x491e56,_0xf0c942,_0x36c266)['then'](_0x256eed=>{const _0x57d395=_0x393cfe;if(_0xfd35dc['KhBsH'](_0xfd35dc[_0x57d395(0x701)],_0x57d395(0x3d4))){const _0x5b9972={};_0x5b9972['success']=![],_0x5b9972[_0x57d395(0x6c8)]=_0x157058[_0x57d395(0x6dc)],_0x46981f[_0x57d395(0x4d0)](0x1f4)['json'](_0x5b9972);}else{console['log'](_0x57d395(0x5b5));const _0x309150={};_0x309150['type']=_0xfd35dc[_0x57d395(0x63e)],_0x309150[_0x57d395(0x5fa)]=_0x256eed,_0x36c266['send'](JSON['stringify'](_0x309150));}})[_0x393cfe(0x795)](_0x389454=>{const _0x30d2f9=_0x393cfe;if(_0x30d2f9(0x60e)!==_0x37ef36[_0x30d2f9(0x77e)]){console[_0x30d2f9(0x6c8)](_0x30d2f9(0x6c0)+_0x389454['message']);const _0x4c747e={};_0x4c747e[_0x30d2f9(0x4b8)]='command_error',_0x4c747e[_0x30d2f9(0x6c8)]=_0x389454['message'],_0x36c266[_0x30d2f9(0x71d)](JSON[_0x30d2f9(0x33e)](_0x4c747e));}else{const _0x26d45b={};return _0x26d45b[_0x30d2f9(0x859)]=![],_0x26d45b[_0x30d2f9(0x6c8)]=_0x30d2f9(0x5ce),_0x3d2e40[_0x30d2f9(0x4d0)](0x190)['json'](_0x26d45b);}}):_0x37ef36[_0x393cfe(0x262)](executeCommand,_0x491e56,_0xf0c942,_0x36c266)[_0x393cfe(0x6bf)](_0x257720=>{const _0xcc303e=_0x393cfe,_0x107c1e={};_0x107c1e[_0xcc303e(0x5a1)]=_0x37ef36['mnmGg'],_0x107c1e[_0xcc303e(0x5d5)]='Target\x20devices\x20required';const _0x320a83=_0x107c1e;if(_0x37ef36[_0xcc303e(0x650)]===_0xcc303e(0x7c5)){isRecording&&recordCommand(_0x491e56,_0x399032,_0x4a04bd,_0xf0c942);const _0x334381={};_0x334381[_0xcc303e(0x4b8)]=_0x37ef36['UAqQy'],_0x334381[_0xcc303e(0x5fa)]=_0x257720,_0x36c266['send'](JSON['stringify'](_0x334381));}else{const {filename:_0x55aa50,devices:_0x53da02}=_0x4d52ea[_0xcc303e(0x3b6)];if(!_0x55aa50){const _0x1f91fe={};return _0x1f91fe['success']=![],_0x1f91fe[_0xcc303e(0x6c8)]=_0x320a83[_0xcc303e(0x5a1)],_0x2689ef[_0xcc303e(0x4d0)](0x190)[_0xcc303e(0x843)](_0x1f91fe);}if(!_0x53da02||_0x53da02[_0xcc303e(0x526)]===0x0){const _0x17deac={};return _0x17deac[_0xcc303e(0x859)]=![],_0x17deac[_0xcc303e(0x6c8)]=_0x320a83[_0xcc303e(0x5d5)],_0x81487c[_0xcc303e(0x4d0)](0x190)[_0xcc303e(0x843)](_0x17deac);}const _0x205567={};_0x205567[_0xcc303e(0x859)]=!![],_0x205567['message']='Replay\x20started',_0x39df19[_0xcc303e(0x843)](_0x205567);}})[_0x393cfe(0x795)](_0x168795=>{const _0x2f5b50=_0x393cfe;if(_0xfd35dc[_0x2f5b50(0x2a2)](_0xfd35dc[_0x2f5b50(0x422)],_0xfd35dc['zgQuB'])){console[_0x2f5b50(0x6c8)](_0x2f5b50(0x852)+_0x168795[_0x2f5b50(0x6dc)]);const _0x3b2069={};_0x3b2069[_0x2f5b50(0x4b8)]=_0xfd35dc[_0x2f5b50(0x1fe)],_0x3b2069[_0x2f5b50(0x6c8)]=_0x168795[_0x2f5b50(0x6dc)],_0x36c266[_0x2f5b50(0x71d)](JSON[_0x2f5b50(0x33e)](_0x3b2069));}else _0xdc217=_0x13ec7d['commands'][_0x2f5b50(0x307)]('\x0a')[_0x2f5b50(0x3c2)](_0x1edaab=>_0x1edaab[_0x2f5b50(0x685)]())[_0x2f5b50(0x526)];});break;case _0x393cfe(0x36f):const _0x39eba6=await _0x37ef36[_0x393cfe(0x711)](startRecording,_0x2035ef[_0x393cfe(0x719)],_0x2035ef['devices']),_0x4e7fe1={'type':_0x37ef36[_0x393cfe(0x790)],..._0x39eba6};_0x36c266[_0x393cfe(0x71d)](JSON[_0x393cfe(0x33e)](_0x4e7fe1));break;case _0x37ef36[_0x393cfe(0x32f)]:const _0x18b170=await _0x37ef36[_0x393cfe(0x5b9)](stopRecording),_0x1b8084={'type':_0x37ef36[_0x393cfe(0x844)],..._0x18b170};_0x36c266[_0x393cfe(0x71d)](JSON['stringify'](_0x1b8084));break;case'replay_recording':const {filename:_0x1b4592,targetDevices:_0x353011}=_0x2035ef,_0x3c0428={};_0x3c0428[_0x393cfe(0x4b8)]=_0x37ef36[_0x393cfe(0x388)],_0x3c0428[_0x393cfe(0x1da)]='\x0aš¬\x20Starting\x20replay:\x20'+_0x1b4592+'\x0a\x0a',_0x3c0428[_0x393cfe(0x658)]=_0x353011,_0x36c266[_0x393cfe(0x71d)](JSON['stringify'](_0x3c0428)),_0x37ef36[_0x393cfe(0x4a8)](replayRecording,_0x1b4592,_0x353011,_0x36c266)[_0x393cfe(0x6bf)](_0x26c486=>{const _0x39929b=_0x393cfe,_0x5882d3={'type':_0x37ef36[_0x39929b(0x655)],..._0x26c486};_0x36c266[_0x39929b(0x71d)](JSON['stringify'](_0x5882d3));})['catch'](_0x3f0016=>{const _0x10d7cc=_0x393cfe,_0x127a89={};_0x127a89[_0x10d7cc(0x4b8)]=_0x37ef36[_0x10d7cc(0x73c)],_0x127a89[_0x10d7cc(0x6c8)]=_0x3f0016['message'],_0x36c266[_0x10d7cc(0x71d)](JSON[_0x10d7cc(0x33e)](_0x127a89));});break;case _0x37ef36[_0x393cfe(0x44f)]:if(isReplaying){if(_0x37ef36[_0x393cfe(0x750)](_0x37ef36[_0x393cfe(0x69c)],_0x37ef36[_0x393cfe(0x7f8)])){replayAborted=!![];const _0x161506={};_0x161506[_0x393cfe(0x4b8)]=_0x37ef36[_0x393cfe(0x388)],_0x161506['data']='\x0aā¹ļø\x20\x20Stopping\x20replay...\x0a',_0x36c266[_0x393cfe(0x71d)](JSON[_0x393cfe(0x33e)](_0x161506));}else _0x3bcae1[_0x393cfe(0x61d)](_0x393cfe(0x4d9)+_0x29a490[_0x393cfe(0x685)]());}break;case _0x393cfe(0x4c4):const _0x700f10=await discoverDevices(),_0x275558={};_0x275558['type']='devices_updated',_0x275558[_0x393cfe(0x658)]=_0x700f10,_0x36c266[_0x393cfe(0x71d)](JSON[_0x393cfe(0x33e)](_0x275558));break;case _0x37ef36[_0x393cfe(0x2f5)]:_0x36c266[_0x393cfe(0x71d)](JSON['stringify']({'type':_0x37ef36[_0x393cfe(0x5c9)],'providers':aiManager[_0x393cfe(0x37b)](),'current':aiManager['provider']}));break;case _0x37ef36[_0x393cfe(0x3a5)]:const _0x374b54=aiManager[_0x393cfe(0x2aa)](_0x2035ef[_0x393cfe(0x3f9)]),_0x563b8e={};_0x563b8e[_0x393cfe(0x4b8)]='ai_provider_set',_0x563b8e[_0x393cfe(0x859)]=_0x374b54,_0x563b8e[_0x393cfe(0x3f9)]=_0x2035ef[_0x393cfe(0x3f9)],_0x36c266[_0x393cfe(0x71d)](JSON[_0x393cfe(0x33e)](_0x563b8e));break;}}catch(_0x44bbc5){if(_0x37ef36[_0x393cfe(0x403)]===_0x37ef36[_0x393cfe(0x769)]){if(hGefJg[_0x393cfe(0x459)](_0x44432d[_0x393cfe(0x24e)],_0x152f12[_0x393cfe(0x3ba)])){const _0x8fa93b={};_0x8fa93b[_0x393cfe(0x4b8)]=hGefJg[_0x393cfe(0x4c1)],_0x8fa93b['devices']=_0x91babe,_0x4624b7['send'](_0x56af54[_0x393cfe(0x33e)](_0x8fa93b));}}else{const _0x456201={};_0x456201[_0x393cfe(0x4b8)]=_0x37ef36['WkeKx'],_0x456201['message']=_0x44bbc5[_0x393cfe(0x6dc)],_0x36c266[_0x393cfe(0x71d)](JSON[_0x393cfe(0x33e)](_0x456201));}}}),_0x36c266['on']('close',()=>{const _0x2a018f=_0x41146b;console[_0x2a018f(0x61d)](_0x2a018f(0x85e));}),_0x37ef36[_0x41146b(0x3ce)](discoverDevices)['then'](_0x252ac3=>{const _0xd244e8=_0x41146b,_0x5b3a21={};_0x5b3a21[_0xd244e8(0x4b8)]=_0x37ef36['JKaSa'],_0x5b3a21[_0xd244e8(0x658)]=_0x252ac3,_0x36c266[_0xd244e8(0x71d)](JSON[_0xd244e8(0x33e)](_0x5b3a21));});}),app[_0x47c41d(0x328)](_0x47c41d(0x77d),async(_0xec76b3,_0x4bac8b)=>{const _0x557353=_0x47c41d,_0x46bf6a={'aopPI':'Device\x20name\x20required','vlPuf':function(_0x2e29f8,_0x34658d){return _0x2e29f8!==_0x34658d;},'QAdYM':_0x557353(0x631),'oTDIH':_0x557353(0x2f8),'lLEwn':_0x557353(0x2a5),'bfZAt':function(_0x2fa28f,_0x1023fd,_0x3761cf){return _0x2fa28f(_0x1023fd,_0x3761cf);},'MqrGm':_0x557353(0x8be)},{device:_0x3d2135}=_0xec76b3[_0x557353(0x3b6)];if(!_0x3d2135){const _0x4bdb24={};return _0x4bdb24['success']=![],_0x4bdb24['error']=_0x46bf6a['aopPI'],_0x4bac8b[_0x557353(0x4d0)](0x190)[_0x557353(0x843)](_0x4bdb24);}try{console[_0x557353(0x61d)](_0x557353(0x4d4)+_0x3d2135+_0x557353(0x8cb));const _0x20241c=connectedDevices[_0x557353(0x715)](_0x5b87f7=>_0x5b87f7['name']===_0x3d2135);if(!_0x20241c){if(_0x46bf6a[_0x557353(0x28c)](_0x46bf6a['QAdYM'],_0x46bf6a['oTDIH'])){const _0x16dad4={};return _0x16dad4[_0x557353(0x859)]=![],_0x16dad4[_0x557353(0x6c8)]=_0x46bf6a[_0x557353(0x69e)],_0x4bac8b[_0x557353(0x843)](_0x16dad4);}else _0x2b50ea=_0x4746a9[_0x557353(0x474)];}const _0x22a770=await _0x46bf6a[_0x557353(0x74f)](installUIAutomator2,_0x20241c[_0x557353(0x200)],_0x3d2135);_0x4bac8b[_0x557353(0x843)](_0x22a770);}catch(_0x4fe9ef){console[_0x557353(0x6c8)](_0x46bf6a['MqrGm'],_0x4fe9ef[_0x557353(0x6dc)]);const _0x15b770={};_0x15b770[_0x557353(0x859)]=![],_0x15b770[_0x557353(0x6c8)]=_0x4fe9ef['message'],_0x15b770['suggestion']=_0x557353(0x3a2),_0x4bac8b[_0x557353(0x843)](_0x15b770);}}),app[_0x47c41d(0x328)](_0x47c41d(0x609),async(_0x3e97a3,_0x2c12ce)=>{const _0x1d672c=_0x47c41d,_0x1075bb={'gSTyL':function(_0x5c4115,_0x50b594){return _0x5c4115(_0x50b594);},'WKJgz':function(_0x11d7ec,_0x3c988a,_0x22bff1){return _0x11d7ec(_0x3c988a,_0x22bff1);},'GUHrX':_0x1d672c(0x506)};try{const {name:_0x2fbe7e,devices:_0xecb339}=_0x3e97a3[_0x1d672c(0x3b6)],_0x2f0aac=await _0x1075bb['WKJgz'](startRecording,_0x2fbe7e,_0xecb339);_0x2c12ce['json'](_0x2f0aac);}catch(_0x20af94){if(_0x1d672c(0x4fe)===_0x1075bb['GUHrX']){const _0x3ff697={};_0x3ff697[_0x1d672c(0x859)]=![],_0x3ff697[_0x1d672c(0x6dc)]=_0x1d672c(0x4c8)+_0x2747e7+_0x1d672c(0x4b7),KLGxWE[_0x1d672c(0x3b4)](_0x40db9e,_0x3ff697);}else{const _0x40b00d={};_0x40b00d['success']=![],_0x40b00d['error']=_0x20af94[_0x1d672c(0x6dc)],_0x2c12ce[_0x1d672c(0x4d0)](0x1f4)[_0x1d672c(0x843)](_0x40b00d);}}}),app[_0x47c41d(0x328)](_0x47c41d(0x723),async(_0xb80b17,_0x5ad90b)=>{const _0x145e05=_0x47c41d,_0x4dcecd={'zjFkl':function(_0x22f40d,_0x50a3d8){return _0x22f40d!==_0x50a3d8;},'xfrbO':'BDZEa','jeWyw':_0x145e05(0x6b9),'csrkz':function(_0x24d83b){return _0x24d83b();}};try{if(_0x4dcecd[_0x145e05(0x6e1)](_0x4dcecd[_0x145e05(0x1ea)],_0x4dcecd['jeWyw'])){const _0x5c3e79=await _0x4dcecd['csrkz'](stopRecording);_0x5ad90b[_0x145e05(0x843)](_0x5c3e79);}else return _0x329f92;}catch(_0x4df37a){const _0x765ccb={};_0x765ccb['success']=![],_0x765ccb['error']=_0x4df37a['message'],_0x5ad90b[_0x145e05(0x4d0)](0x1f4)[_0x145e05(0x843)](_0x765ccb);}}),app[_0x47c41d(0x3ac)]('/api/recording/status',(_0x3e5f6f,_0x17e006)=>{const _0x26f1a4=_0x47c41d,_0x138880={};_0x138880[_0x26f1a4(0x7f6)]=isRecording,_0x138880[_0x26f1a4(0x533)]=currentRecording,_0x17e006[_0x26f1a4(0x843)](_0x138880);}),app[_0x47c41d(0x3ac)](_0x47c41d(0x80a),async(_0x16deee,_0x5a4ede)=>{const _0x859949=_0x47c41d;try{const _0x321bdf=await listRecordings(),_0x5c39ce={};_0x5c39ce[_0x859949(0x859)]=!![],_0x5c39ce[_0x859949(0x6a3)]=_0x321bdf,_0x5a4ede[_0x859949(0x843)](_0x5c39ce);}catch(_0x2b7ab1){const _0x294aec={};_0x294aec[_0x859949(0x859)]=![],_0x294aec[_0x859949(0x6c8)]=_0x2b7ab1['message'],_0x5a4ede['status'](0x1f4)[_0x859949(0x843)](_0x294aec);}}),app[_0x47c41d(0x3ac)]('/api/recordings/:filename',async(_0x558192,_0x2fe12b)=>{const _0x22e92e=_0x47c41d,_0x545160={};_0x545160[_0x22e92e(0x7d0)]=_0x22e92e(0x254),_0x545160[_0x22e92e(0x84d)]=function(_0x3fae7a,_0x21fcee){return _0x3fae7a+_0x21fcee;},_0x545160['vYWFj']=_0x22e92e(0x830);const _0xf671fe=_0x545160;try{const _0x26ce9d=await loadRecording(_0x558192[_0x22e92e(0x747)]['filename']),_0x3b9815={};_0x3b9815[_0x22e92e(0x859)]=!![],_0x3b9815[_0x22e92e(0x533)]=_0x26ce9d,_0x2fe12b[_0x22e92e(0x843)](_0x3b9815);}catch(_0x4d0dd2){if(_0xf671fe['vYWFj']!==_0x22e92e(0x830))_0x2b7c96['send'](_0x2a1533[_0x22e92e(0x33e)]({'type':mWQltJ['jaYew'],'data':_0x22e92e(0x5a6)+mWQltJ[_0x22e92e(0x84d)](_0x11733a,0x1)+'/'+_0x4a69c4['length']+_0x22e92e(0x688)+_0x2cf504+'\x0a','devices':_0x1a4ece}));else{const _0x4aa152={};_0x4aa152[_0x22e92e(0x859)]=![],_0x4aa152['error']='Recording\x20not\x20found',_0x2fe12b['status'](0x194)['json'](_0x4aa152);}}}),app[_0x47c41d(0x27e)](_0x47c41d(0x471),async(_0x2f19e5,_0x299fe5)=>{const _0x1a69d2=_0x47c41d,_0x106d48={'oPrBU':function(_0x2acf5c,_0x5515bc){return _0x2acf5c(_0x5515bc);},'AxySK':_0x1a69d2(0x89f)};try{await _0x106d48[_0x1a69d2(0x31e)](deleteRecording,_0x2f19e5[_0x1a69d2(0x747)]['filename']);const _0x480013={};_0x480013['success']=!![],_0x299fe5[_0x1a69d2(0x843)](_0x480013);}catch(_0x2ccb2e){if(_0x106d48[_0x1a69d2(0x2bc)]===_0x1a69d2(0x293))_0x32b992[_0x1a69d2(0x61d)](_0x1a69d2(0x657));else{const _0x13ffc0={};_0x13ffc0[_0x1a69d2(0x859)]=![],_0x13ffc0[_0x1a69d2(0x6c8)]=_0x2ccb2e[_0x1a69d2(0x6dc)],_0x299fe5[_0x1a69d2(0x4d0)](0x1f4)['json'](_0x13ffc0);}}}),app[_0x47c41d(0x461)](_0x47c41d(0x471),async(_0x49df57,_0x16e323)=>{const _0x56136e=_0x47c41d;try{const {filename:_0x187647}=_0x49df57[_0x56136e(0x747)],_0x51aa55=_0x49df57[_0x56136e(0x3b6)],_0x12a654=path[_0x56136e(0x5c8)](RECORDINGS_DIR,_0x187647);await fs['writeFile'](_0x12a654,JSON[_0x56136e(0x33e)](_0x51aa55,null,0x2));const _0x27bef8={};_0x27bef8[_0x56136e(0x859)]=!![],_0x27bef8[_0x56136e(0x533)]=_0x51aa55,_0x16e323[_0x56136e(0x843)](_0x27bef8);}catch(_0x5e3149){const _0x24bde6={};_0x24bde6[_0x56136e(0x859)]=![],_0x24bde6[_0x56136e(0x6c8)]=_0x5e3149[_0x56136e(0x6dc)],_0x16e323[_0x56136e(0x4d0)](0x1f4)[_0x56136e(0x843)](_0x24bde6);}}),app[_0x47c41d(0x328)](_0x47c41d(0x529),async(_0x23bddb,_0x111ce0)=>{const _0x29dd87=_0x47c41d,_0x527564={};_0x527564[_0x29dd87(0x882)]=function(_0x114586,_0x59bbb9){return _0x114586===_0x59bbb9;},_0x527564[_0x29dd87(0x743)]=_0x29dd87(0x33a),_0x527564['WxlZi']=function(_0x52d963,_0x3a0b61){return _0x52d963||_0x3a0b61;},_0x527564[_0x29dd87(0x3e4)]=function(_0x2e8b43,_0x107274){return _0x2e8b43!==_0x107274;},_0x527564[_0x29dd87(0x278)]=_0x29dd87(0x578),_0x527564[_0x29dd87(0x53e)]=_0x29dd87(0x7ab),_0x527564[_0x29dd87(0x44a)]=_0x29dd87(0x34c),_0x527564['bJSer']=function(_0x4ddb2c,_0x2c4cdc){return _0x4ddb2c||_0x2c4cdc;},_0x527564[_0x29dd87(0x610)]='manual',_0x527564[_0x29dd87(0x5f3)]='Error\x20saving\x20recording:';const _0xc59715=_0x527564;try{const {name:_0x29cd0d,commands:_0x5b2bd2,date:_0x5eb0e9,type:_0x1d3f79}=_0x23bddb['body'];if(_0xc59715[_0x29dd87(0x64b)](!_0x29cd0d,!_0x5b2bd2)){if(_0xc59715[_0x29dd87(0x3e4)](_0xc59715['lYJQC'],_0xc59715[_0x29dd87(0x53e)])){const _0x260dd4={};return _0x260dd4[_0x29dd87(0x859)]=![],_0x260dd4[_0x29dd87(0x6c8)]=_0xc59715[_0x29dd87(0x44a)],_0x111ce0[_0x29dd87(0x4d0)](0x190)['json'](_0x260dd4);}else{if(rSKpPW[_0x29dd87(0x882)](_0x1d9ded['readyState'],_0xa4b672[_0x29dd87(0x3ba)])){const _0x503f6e={};_0x503f6e['type']=rSKpPW[_0x29dd87(0x743)],_0x503f6e[_0x29dd87(0x658)]=_0x896327,_0x63ecbb[_0x29dd87(0x71d)](_0x153016[_0x29dd87(0x33e)](_0x503f6e)),_0x12f8d7['send'](_0x54aa24[_0x29dd87(0x33e)]({'type':_0x29dd87(0x254),'output':'ā
\x20'+_0x259e90+_0x29dd87(0x1f3)+'ā'[_0x29dd87(0x552)](0x32)+'\x0a','device':_0x18d355}));}}}const _0x433a95=_0x29cd0d['replace'](/[^a-z0-9_-]/gi,'_'),_0x9cda63=_0x433a95+'_'+Date['now']()+_0x29dd87(0x55a),_0x304c8c=path[_0x29dd87(0x5c8)](RECORDINGS_DIR,_0x9cda63),_0x3161d5={'name':_0x29cd0d,'commands':_0x5b2bd2,'date':_0x5eb0e9||new Date()[_0x29dd87(0x7f5)](),'type':_0xc59715[_0x29dd87(0x359)](_0x1d3f79,_0xc59715['BTWrd'])};await fs['writeFile'](_0x304c8c,JSON[_0x29dd87(0x33e)](_0x3161d5,null,0x2));const _0x1f8187={};_0x1f8187[_0x29dd87(0x859)]=!![],_0x1f8187['filename']=_0x9cda63,_0x1f8187[_0x29dd87(0x533)]=_0x3161d5,_0x111ce0['json'](_0x1f8187);}catch(_0x2f9337){console[_0x29dd87(0x6c8)](_0xc59715[_0x29dd87(0x5f3)],_0x2f9337);const _0x34cd98={};_0x34cd98[_0x29dd87(0x859)]=![],_0x34cd98[_0x29dd87(0x6c8)]=_0x2f9337['message'],_0x111ce0[_0x29dd87(0x4d0)](0x1f4)[_0x29dd87(0x843)](_0x34cd98);}}),app[_0x47c41d(0x328)](_0x47c41d(0x6d5),async(_0x59001b,_0x5f2e69)=>{const _0x2626b9=_0x47c41d,_0x35801a={};_0x35801a[_0x2626b9(0x6ed)]=_0x2626b9(0x3d9),_0x35801a['YmDiV']=function(_0x194846,_0x125e17){return _0x194846===_0x125e17;},_0x35801a['wMpzZ']=_0x2626b9(0x22e),_0x35801a['XIFgK']=_0x2626b9(0x251);const _0x51a5b4=_0x35801a;try{const {filename:_0x38095c,devices:_0x55829e}=_0x59001b[_0x2626b9(0x3b6)];if(!_0x38095c){const _0x581eb5={};return _0x581eb5['success']=![],_0x581eb5[_0x2626b9(0x6c8)]=_0x51a5b4[_0x2626b9(0x6ed)],_0x5f2e69[_0x2626b9(0x4d0)](0x190)[_0x2626b9(0x843)](_0x581eb5);}if(!_0x55829e||_0x51a5b4[_0x2626b9(0x4d7)](_0x55829e[_0x2626b9(0x526)],0x0)){const _0x3b4921={};return _0x3b4921[_0x2626b9(0x859)]=![],_0x3b4921[_0x2626b9(0x6c8)]=_0x51a5b4[_0x2626b9(0x862)],_0x5f2e69[_0x2626b9(0x4d0)](0x190)['json'](_0x3b4921);}const _0x3282d3={};_0x3282d3[_0x2626b9(0x859)]=!![],_0x3282d3[_0x2626b9(0x6dc)]=_0x51a5b4['XIFgK'],_0x5f2e69[_0x2626b9(0x843)](_0x3282d3);}catch(_0x4cd4f8){const _0xb9cfa1={};_0xb9cfa1[_0x2626b9(0x859)]=![],_0xb9cfa1[_0x2626b9(0x6c8)]=_0x4cd4f8['message'],_0x5f2e69[_0x2626b9(0x4d0)](0x1f4)[_0x2626b9(0x843)](_0xb9cfa1);}}),app[_0x47c41d(0x3ac)](_0x47c41d(0x20e),async(_0x137dba,_0x33601a)=>{const _0x307306=_0x47c41d,_0x1812da={'AnXvX':function(_0x5ee433,_0xf847b7){return _0x5ee433(_0xf847b7);}};try{const _0x184a0c={};_0x184a0c[_0x307306(0x290)]=!![],await fs[_0x307306(0x2ad)](SCREENSHOTS_DIR,_0x184a0c);const _0x3c8228=await fs[_0x307306(0x33f)](SCREENSHOTS_DIR),_0x42d054=_0x3c8228[_0x307306(0x3c2)](_0x4f5f65=>_0x4f5f65[_0x307306(0x3bc)](_0x307306(0x2b0)))[_0x307306(0x2d0)](_0x4d0645=>{const _0x39efff=_0x307306,_0x59d3f9=_0x1812da['AnXvX'](require,'fs')[_0x39efff(0x73b)](path['join'](SCREENSHOTS_DIR,_0x4d0645));return{'filename':_0x4d0645,'path':_0x39efff(0x62f)+_0x4d0645,'size':_0x59d3f9[_0x39efff(0x303)],'timestamp':_0x59d3f9['mtime'][_0x39efff(0x6e0)](),'created':_0x59d3f9[_0x39efff(0x39d)]};})[_0x307306(0x788)]((_0x54db1d,_0x4c5448)=>_0x4c5448[_0x307306(0x5ef)]-_0x54db1d[_0x307306(0x5ef)]),_0x106ca1={};_0x106ca1[_0x307306(0x859)]=!![],_0x106ca1[_0x307306(0x2c6)]=_0x42d054,_0x33601a[_0x307306(0x843)](_0x106ca1);}catch(_0x426e93){const _0x47fdcd={};_0x47fdcd[_0x307306(0x859)]=![],_0x47fdcd[_0x307306(0x6c8)]=_0x426e93[_0x307306(0x6dc)],_0x33601a[_0x307306(0x4d0)](0x1f4)[_0x307306(0x843)](_0x47fdcd);}}),app['get'](_0x47c41d(0x4b3),(_0x4bcc16,_0x20fe1b)=>{const _0x54a568=_0x47c41d,_0xe03e1e={};_0xe03e1e[_0x54a568(0x855)]=_0x54a568(0x254),_0xe03e1e['IsYkZ']=function(_0x4e5035,_0x5c7b40){return _0x4e5035!==_0x5c7b40;},_0xe03e1e[_0x54a568(0x233)]='gSTtG',_0xe03e1e[_0x54a568(0x57e)]='Screenshot\x20not\x20found';const _0xb65a7b=_0xe03e1e,_0x2711a1=path[_0x54a568(0x5c8)](SCREENSHOTS_DIR,_0x4bcc16[_0x54a568(0x747)]['filename']);_0x20fe1b[_0x54a568(0x36e)](_0x2711a1,_0x2ea0fa=>{const _0x58a5a0=_0x54a568;if(_0x2ea0fa){if(_0xb65a7b[_0x58a5a0(0x864)](_0x58a5a0(0x706),_0xb65a7b['tlJdL'])){const _0x4589e4={};_0x4589e4[_0x58a5a0(0x4b8)]=dyxQLV[_0x58a5a0(0x855)],_0x4589e4[_0x58a5a0(0x1da)]='ā\x20Error:\x20'+_0xf0dd21[_0x58a5a0(0x6dc)]+'\x0a',_0x4589e4['devices']=_0x35ad1f,_0x31257e[_0x58a5a0(0x71d)](_0x5db5e4[_0x58a5a0(0x33e)](_0x4589e4));}else{const _0x3cf191={};_0x3cf191[_0x58a5a0(0x859)]=![],_0x3cf191[_0x58a5a0(0x6c8)]=_0xb65a7b[_0x58a5a0(0x57e)],_0x20fe1b[_0x58a5a0(0x4d0)](0x194)[_0x58a5a0(0x843)](_0x3cf191);}}});}),app['delete'](_0x47c41d(0x4b3),async(_0x3c7959,_0x4d8980)=>{const _0x25627a=_0x47c41d,_0x1b3c9b={};_0x1b3c9b['KLvka']=function(_0x5d24db,_0x578856){return _0x5d24db===_0x578856;},_0x1b3c9b[_0x25627a(0x88e)]='xNNWK';const _0x30e0fc=_0x1b3c9b;try{if(_0x30e0fc[_0x25627a(0x3f3)](_0x30e0fc[_0x25627a(0x88e)],_0x30e0fc[_0x25627a(0x88e)])){const _0x1a28d1=path['join'](SCREENSHOTS_DIR,_0x3c7959[_0x25627a(0x747)]['filename']);await fs[_0x25627a(0x67e)](_0x1a28d1);const _0xd76c2c={};_0xd76c2c['success']=!![],_0x4d8980['json'](_0xd76c2c);}else _0x23d24c[_0x25627a(0x61d)](_0x25627a(0x396)+_0x5e06f6['message']);}catch(_0x2f6d0e){const _0x539a2a={};_0x539a2a[_0x25627a(0x859)]=![],_0x539a2a['error']=_0x2f6d0e[_0x25627a(0x6dc)],_0x4d8980['status'](0x1f4)[_0x25627a(0x843)](_0x539a2a);}}),app[_0x47c41d(0x328)](_0x47c41d(0x4c6),async(_0x30a7cc,_0x4921ee)=>{const _0x49d729=_0x47c41d,_0x5e8d48={'rRPMm':function(_0x3a8d54,_0x195b5c){return _0x3a8d54===_0x195b5c;},'qukgc':'devices_updated','vZiAJ':_0x49d729(0x254),'ARpjW':function(_0x575e32,_0x50a308){return _0x575e32(_0x50a308);},'klruE':_0x49d729(0x540),'wjXSX':_0x49d729(0x421),'VHZzo':_0x49d729(0x883),'LcwNL':function(_0x2651a8,_0x1ef80c){return _0x2651a8!==_0x1ef80c;},'mHxru':_0x49d729(0x84b),'FVzPN':'XUdQB','iPEGa':_0x49d729(0x7eb),'dYoFU':function(_0x314bb1,_0x21cd0e){return _0x314bb1===_0x21cd0e;},'Elwor':function(_0x4e0244,_0x14d1b8){return _0x4e0244===_0x14d1b8;},'mVhSY':_0x49d729(0x45d),'xDLWx':'No\x20connected\x20devices\x20found','aqKFS':'fvpRn','OFMYo':_0x49d729(0x3e1),'YQRnd':function(_0x1d48f7,_0x5e3f2c){return _0x1d48f7===_0x5e3f2c;},'EjIAD':_0x49d729(0x7ff),'ZmZvF':_0x49d729(0x23d),'yUesM':function(_0x1a381c,_0x5114d9){return _0x1a381c(_0x5114d9);},'CLHlW':_0x49d729(0x41c),'RBBSo':function(_0x564ca2,_0x807919,_0x38470d){return _0x564ca2(_0x807919,_0x38470d);},'MzYMB':_0x49d729(0x377),'RthDZ':function(_0xf24868,_0x45df83){return _0xf24868===_0x45df83;},'rTaqv':_0x49d729(0x898),'LvinE':function(_0x210f7e,_0xfae42d){return _0x210f7e!==_0xfae42d;},'eWAtt':_0x49d729(0x4a5),'IhfRW':_0x49d729(0x1e9),'DTnqo':function(_0x56e1eb,_0x3b46ab,_0x25c73f){return _0x56e1eb(_0x3b46ab,_0x25c73f);},'BJLiM':function(_0x120539,_0x49929c){return _0x120539===_0x49929c;},'pCDEF':_0x49d729(0x3a8),'ImHWi':_0x49d729(0x667),'MOTiH':function(_0x12b0c9,_0x2b7fca){return _0x12b0c9===_0x2b7fca;},'hCrmh':_0x49d729(0x364)};try{if(_0x5e8d48[_0x49d729(0x502)](_0x5e8d48['FVzPN'],_0x5e8d48['iPEGa'])){const _0x59ee50={};_0x59ee50[_0x49d729(0x859)]=![],_0x59ee50['error']=_0x2e9985[_0x49d729(0x6dc)],_0x20ed08['status'](0x1f4)[_0x49d729(0x843)](_0x59ee50);}else{const {devices:_0xbc7605}=_0x30a7cc['body'];if(!_0xbc7605||_0x5e8d48[_0x49d729(0x77a)](_0xbc7605['length'],0x0)){const _0x2ee481={};return _0x2ee481['success']=![],_0x2ee481[_0x49d729(0x6c8)]=_0x49d729(0x2ce),_0x4921ee['status'](0x190)[_0x49d729(0x843)](_0x2ee481);}const _0x40d894=connectedDevices[_0x49d729(0x3c2)](_0x2f6d58=>_0xbc7605['includes'](_0x2f6d58[_0x49d729(0x719)])||_0xbc7605[_0x49d729(0x310)](_0x2f6d58[_0x49d729(0x200)])||_0xbc7605[_0x49d729(0x310)](_0x2f6d58['serial']));if(_0x5e8d48[_0x49d729(0x726)](_0x40d894[_0x49d729(0x526)],0x0)){if(_0x5e8d48[_0x49d729(0x6f9)](_0x5e8d48['mVhSY'],_0x5e8d48[_0x49d729(0x6ff)])){_0x5af2ae[_0x49d729(0x6c8)](_0x49d729(0x7ed)+(_0x22d3af+0x1)+_0x49d729(0x59d),_0x1208a3[_0x49d729(0x6dc)]);const _0xc027e3={};_0xc027e3[_0x49d729(0x582)]=_0x83c7f5,_0xc027e3[_0x49d729(0x859)]=![],_0xc027e3[_0x49d729(0x6c8)]=_0x22780b[_0x49d729(0x6dc)],_0x1041f7[_0x49d729(0x823)](_0xc027e3);if(_0x9fc747){const _0x44ea42={};_0x44ea42[_0x49d729(0x4b8)]='command_output',_0x44ea42['data']=_0x49d729(0x493)+_0x340e38[_0x49d729(0x6dc)]+'\x0a',_0x44ea42['devices']=_0xc88c28,_0x1424b5[_0x49d729(0x71d)](_0x410c74[_0x49d729(0x33e)](_0x44ea42));}}else{const _0x4517cb={};return _0x4517cb[_0x49d729(0x859)]=![],_0x4517cb[_0x49d729(0x6c8)]=_0x5e8d48[_0x49d729(0x3bb)],_0x4921ee[_0x49d729(0x4d0)](0x190)[_0x49d729(0x843)](_0x4517cb);}}const _0xa5f4a1={};for(const _0x232c22 of _0x40d894){try{if(_0x5e8d48['aqKFS']===_0x5e8d48[_0x49d729(0x496)]){if(uXXcCw[_0x49d729(0x502)](_0xe61b49[_0x49d729(0x24e)],_0xc50d18[_0x49d729(0x3ba)])){const _0x1a1254={};_0x1a1254['type']=uXXcCw['qukgc'],_0x1a1254['devices']=_0x5e89bd,_0x4928c7[_0x49d729(0x71d)](_0x510d04[_0x49d729(0x33e)](_0x1a1254));}}else{let _0xec56d6=[];if(_0x5e8d48[_0x49d729(0x33c)](_0x232c22[_0x49d729(0x581)],_0x49d729(0x705))){if(_0x5e8d48[_0x49d729(0x23c)]!==_0x5e8d48[_0x49d729(0x7ef)]){const {execSync:_0x3f912f}=_0x5e8d48[_0x49d729(0x56b)](require,_0x5e8d48[_0x49d729(0x4e5)]),_0x254f1f=_0x232c22['udid']||_0x232c22[_0x49d729(0x3f6)],_0x549e5b=_0x5e8d48[_0x49d729(0x38b)](_0x3f912f,_0x49d729(0x2b1)+_0x254f1f+'\x20shell\x20pm\x20list\x20packages\x20-3',{'encoding':_0x5e8d48[_0x49d729(0x638)]});_0xec56d6=_0x549e5b[_0x49d729(0x307)]('\x0a')[_0x49d729(0x3c2)](_0x53792c=>_0x53792c[_0x49d729(0x75e)](_0x49d729(0x2f4)))[_0x49d729(0x2d0)](_0x14071f=>_0x14071f[_0x49d729(0x3bd)](_0x49d729(0x2f4),'')[_0x49d729(0x685)]())['filter'](_0x56000a=>_0x56000a)[_0x49d729(0x788)]();}else{const _0x1721af={};_0x1721af[_0x49d729(0x4b8)]=uXXcCw['vZiAJ'],_0x1721af['data']=_0x49d729(0x1e7)+_0x33a920+_0x49d729(0x50b),_0x1721af[_0x49d729(0x658)]=_0x1df71f,_0x7ce251['send'](_0x51142f[_0x49d729(0x33e)](_0x1721af));}}else{if(_0x232c22['platform']===_0x49d729(0x335)){const {execSync:_0x224194}=_0x5e8d48[_0x49d729(0x56b)](require,_0x49d729(0x41c)),_0x131f4c=_0x232c22['udid'];try{if(_0x5e8d48[_0x49d729(0x6cb)](_0x5e8d48[_0x49d729(0x420)],_0x49d729(0x66a))){const _0x1eecc6=_0x28eed3['map'](_0x590d39=>_0x590d39['name']+_0x49d729(0x5bb)+_0x590d39['status']+')')[_0x49d729(0x5c8)](',\x20');_0x34b769[_0x49d729(0x6c8)](_0x49d729(0x348)+_0x1eecc6+']');if(_0x103185){const _0x33a857={};_0x33a857[_0x49d729(0x4b8)]=uXXcCw['vZiAJ'],_0x33a857[_0x49d729(0x1da)]=_0x49d729(0x8a2)+_0x1eecc6+_0x49d729(0x799),_0x33a857['devices']=_0xa08f12,_0x40126c['send'](_0x4b8294[_0x49d729(0x33e)](_0x33a857));}const _0x3c09ee={};return _0x3c09ee['success']=![],_0x3c09ee['error']=_0x49d729(0x604)+_0x1eecc6+_0x49d729(0x8ae),uXXcCw[_0x49d729(0x808)](_0x9c1b20,_0x3c09ee);}else{let _0x317db6;try{_0x317db6=_0x5e8d48[_0x49d729(0x38b)](_0x224194,'ideviceinstaller\x20-u\x20'+_0x131f4c+_0x49d729(0x509),{'encoding':_0x5e8d48[_0x49d729(0x638)],'timeout':0x7530});}catch(_0x40d048){if(_0x5e8d48[_0x49d729(0x81d)](_0x5e8d48[_0x49d729(0x414)],_0x5e8d48[_0x49d729(0x696)]))_0x317db6=_0x5e8d48[_0x49d729(0x460)](_0x224194,_0x49d729(0x1ef)+_0x131f4c+_0x49d729(0x376),{'encoding':_0x5e8d48[_0x49d729(0x638)],'timeout':0x7530});else{const _0x5809e1=_0x260264[_0x49d729(0x685)]();return _0x5809e1&&!_0x5809e1[_0x49d729(0x75e)](_0x5e8d48['klruE'])&&!_0x5809e1['startsWith'](_0x5e8d48[_0x49d729(0x360)]);}}_0xec56d6=_0x317db6[_0x49d729(0x307)]('\x0a')['filter'](_0x598429=>{const _0x2eef13=_0x49d729,_0x11f33f=_0x598429[_0x2eef13(0x685)]();return _0x11f33f&&!_0x11f33f[_0x2eef13(0x75e)](_0x5e8d48[_0x2eef13(0x876)])&&!_0x11f33f['startsWith'](_0x2eef13(0x421));})['map'](_0xfb384c=>{const _0x250352=_0x49d729;if(_0xfb384c[_0x250352(0x310)](_0x5e8d48['VHZzo'])){const _0x1d0b18=_0xfb384c[_0x250352(0x295)](/^(.+?)\s+-\s+(.+?)$/);return _0x1d0b18?{'id':_0x1d0b18[0x1][_0x250352(0x685)](),'name':_0x1d0b18[0x2][_0x250352(0x685)]()}:null;}else{if(_0xfb384c[_0x250352(0x310)](',')){const _0x3ccc41=_0xfb384c[_0x250352(0x307)](',')[_0x250352(0x2d0)](_0x567824=>_0x567824[_0x250352(0x685)]()[_0x250352(0x3bd)](/"/g,''));return _0x3ccc41[_0x250352(0x526)]>=0x3?{'id':_0x3ccc41[0x0],'name':_0x3ccc41[0x2]}:null;}else{if(_0xfb384c['match'](/^[a-zA-Z0-9.-]+$/)){if(_0x5e8d48[_0x250352(0x6f9)](_0x250352(0x3c8),_0x5e8d48[_0x250352(0x82f)]))return{'id':_0xfb384c[_0x250352(0x685)](),'name':_0xfb384c[_0x250352(0x685)]()};else{const _0x2e942b={};_0x2e942b[_0x250352(0x859)]=![],_0x2e942b[_0x250352(0x6c8)]=_0x343a2d[_0x250352(0x6dc)],_0x5cc37a['status'](0x1f4)['json'](_0x2e942b);}}}}return null;})['filter'](_0x5a1cb9=>_0x5a1cb9)[_0x49d729(0x788)]((_0x42d8e0,_0x5df2c2)=>_0x42d8e0[_0x49d729(0x719)][_0x49d729(0x38c)](_0x5df2c2[_0x49d729(0x719)]));if(_0x5e8d48['BJLiM'](_0xec56d6['length'],0x0)){const _0x21358b={};_0x21358b['error']=_0x5e8d48[_0x49d729(0x786)],_0xec56d6=[_0x21358b];}}}catch(_0x3ada88){console['error'](_0x5e8d48[_0x49d729(0x227)],_0x3ada88[_0x49d729(0x6dc)]);const _0x18a028={};_0x18a028[_0x49d729(0x6c8)]=_0x49d729(0x5f2)+_0x3ada88[_0x49d729(0x6dc)],_0xec56d6=[_0x18a028];}}}_0xa5f4a1[_0x232c22[_0x49d729(0x719)]]={'success':!![],'platform':_0x232c22['platform'],'apps':_0xec56d6,'count':Array['isArray'](_0xec56d6)?_0xec56d6[_0x49d729(0x526)]:0x0};}}catch(_0x132030){if(_0x5e8d48[_0x49d729(0x3de)](_0x5e8d48[_0x49d729(0x7b2)],_0x5e8d48[_0x49d729(0x7b2)])){const _0x383ed0={};_0x383ed0[_0x49d729(0x859)]=![],_0x383ed0['error']=_0x132030[_0x49d729(0x6dc)],_0xa5f4a1[_0x232c22[_0x49d729(0x719)]]=_0x383ed0;}else _0x19b580[_0x49d729(0x61d)]('ā
\x20Cleaned\x20up\x20iproxy\x20for\x20'+_0x5f0003);}}const _0x1946af={};_0x1946af[_0x49d729(0x859)]=!![],_0x1946af[_0x49d729(0x239)]=_0xa5f4a1,_0x4921ee[_0x49d729(0x843)](_0x1946af);}}catch(_0x487e4b){const _0x241937={};_0x241937[_0x49d729(0x859)]=![],_0x241937[_0x49d729(0x6c8)]=_0x487e4b['message'],_0x4921ee['status'](0x1f4)['json'](_0x241937);}}),app[_0x47c41d(0x328)](_0x47c41d(0x8c3),async(_0xc901b7,_0x51c1fb)=>{const _0x8a9a4d=_0x47c41d,_0x2a1b39={'GCdqU':_0x8a9a4d(0x237),'oKtcy':'Recording\x20not\x20found','RjHQz':function(_0x4b79fa,_0x4d5782){return _0x4b79fa(_0x4d5782);},'vjeZf':function(_0x45b5dc,_0x521d43){return _0x45b5dc(_0x521d43);},'doxSv':_0x8a9a4d(0x83e),'efjao':function(_0x3e69b5,_0x3e8913){return _0x3e69b5(_0x3e8913);},'MVRaD':_0x8a9a4d(0x3d3),'QWUlh':function(_0x38a8eb,_0x39f699){return _0x38a8eb(_0x39f699);},'BtzNo':_0x8a9a4d(0x884),'GpwQd':function(_0x57b2cd,_0x942369){return _0x57b2cd===_0x942369;},'CrpUN':_0x8a9a4d(0x6a7),'WJWnQ':function(_0x303958,_0x56787e){return _0x303958||_0x56787e;},'uibJN':function(_0x94a40e,_0x50f419){return _0x94a40e!==_0x50f419;},'ACWtJ':_0x8a9a4d(0x1dc),'EHGLr':_0x8a9a4d(0x5ce),'OAkuG':_0x8a9a4d(0x8b6),'zCqgk':_0x8a9a4d(0x55e),'tLsEw':'Device\x20not\x20found','vashQ':_0x8a9a4d(0x41c),'RAEnb':_0x8a9a4d(0x705),'ZbFUk':function(_0x568308,_0x50ba7f){return _0x568308===_0x50ba7f;},'bjImG':'ICBsD','EAgCm':'utf-8','TGJtD':function(_0x3ba514,_0x188a07){return _0x3ba514===_0x188a07;},'xqjpK':_0x8a9a4d(0x8af),'igCiC':_0x8a9a4d(0x355),'XsrcX':_0x8a9a4d(0x407),'CfqBl':_0x8a9a4d(0x5b4),'EFUxi':function(_0x3d3c20,_0x4bafc0){return _0x3d3c20!==_0x4bafc0;},'ZbYSu':_0x8a9a4d(0x798),'VABIJ':'lHVJg','owiWS':function(_0x2997e6,_0x4f8120){return _0x2997e6!==_0x4f8120;},'OBKZC':_0x8a9a4d(0x662),'GZvEU':_0x8a9a4d(0x542),'lBpFT':'MDxWz','NVQhp':function(_0x43ada5,_0x81a0dc,_0x2b80b3){return _0x43ada5(_0x81a0dc,_0x2b80b3);},'aSWmS':'Android','bzpeL':_0x8a9a4d(0x335),'WzYTS':function(_0xf17425,_0x4b0496){return _0xf17425===_0x4b0496;},'pxsAJ':'MVtjC','GtAaw':_0x8a9a4d(0x379),'MwGHL':function(_0x1dbc67,_0x5ecccd){return _0x1dbc67>=_0x5ecccd;},'Usvmu':function(_0x4cc83b,_0x5ec59f){return _0x4cc83b!==_0x5ec59f;},'dVLNv':_0x8a9a4d(0x4c5),'KdOAq':_0x8a9a4d(0x2cc),'RNhgf':_0x8a9a4d(0x4cd),'ZVTsZ':_0x8a9a4d(0x1f0),'QhtCw':'DqIcd'};try{if(_0x2a1b39['GpwQd'](_0x8a9a4d(0x6a7),_0x2a1b39[_0x8a9a4d(0x6d1)])){const {device:_0x3e5de2,bundleId:_0x234d63}=_0xc901b7['body'];if(_0x2a1b39[_0x8a9a4d(0x566)](!_0x3e5de2,!_0x234d63)){if(_0x2a1b39[_0x8a9a4d(0x787)](_0x2a1b39['ACWtJ'],_0x8a9a4d(0x1dc))){_0x8225a2[_0x8a9a4d(0x61d)](_0x8a9a4d(0x78c),_0xec3437[_0x8a9a4d(0x4d6)][_0x8a9a4d(0x6c8)]);const _0x125cb7={};return _0x125cb7[_0x8a9a4d(0x859)]=![],_0x125cb7['error']=tJhrUI[_0x8a9a4d(0x257)],_0x30a96f[_0x8a9a4d(0x4d0)](0x1f4)[_0x8a9a4d(0x843)](_0x125cb7);}else{const _0x40e8b8={};return _0x40e8b8[_0x8a9a4d(0x859)]=![],_0x40e8b8[_0x8a9a4d(0x6c8)]=_0x2a1b39[_0x8a9a4d(0x4b6)],_0x51c1fb[_0x8a9a4d(0x4d0)](0x190)['json'](_0x40e8b8);}}const _0x216736=discoveredDevices[_0x8a9a4d(0x715)](_0x4b4066=>_0x4b4066[_0x8a9a4d(0x719)]===_0x3e5de2);if(!_0x216736){if(_0x2a1b39[_0x8a9a4d(0x8bc)]===_0x2a1b39[_0x8a9a4d(0x749)])_0x4db719[_0x8a9a4d(0x6c8)](_0x8a9a4d(0x682)+_0x39ef0b['message']),_0x5b0846[_0x8a9a4d(0x6c8)](_0x8a9a4d(0x32c));else{const _0x4e4d1a={};return _0x4e4d1a['success']=![],_0x4e4d1a[_0x8a9a4d(0x6c8)]=_0x2a1b39[_0x8a9a4d(0x2a9)],_0x51c1fb[_0x8a9a4d(0x4d0)](0x194)[_0x8a9a4d(0x843)](_0x4e4d1a);}}const {execSync:_0x2c26c0}=_0x2a1b39[_0x8a9a4d(0x79d)](require,_0x2a1b39[_0x8a9a4d(0x22c)]);let _0x137e14={};try{if(_0x2a1b39[_0x8a9a4d(0x5fb)](_0x216736['platform'],_0x2a1b39['RAEnb'])){const _0x3446ee=_0x216736['udid']||_0x216736[_0x8a9a4d(0x3f6)];try{if(_0x2a1b39[_0x8a9a4d(0x88d)](_0x2a1b39[_0x8a9a4d(0x3ff)],'DVrjG')){const _0x466664={};_0x466664[_0x8a9a4d(0x859)]=![],_0x466664[_0x8a9a4d(0x6c8)]=tJhrUI[_0x8a9a4d(0x283)],_0x4a9bd7[_0x8a9a4d(0x4d0)](0x194)['json'](_0x466664);}else{const _0x52bd9c={};_0x52bd9c[_0x8a9a4d(0x76b)]=_0x2a1b39[_0x8a9a4d(0x442)],_0x52bd9c[_0x8a9a4d(0x8ad)]=0x2710;const _0xd7ce40=_0x2c26c0('adb\x20-s\x20'+_0x3446ee+_0x8a9a4d(0x287)+_0x234d63+'\x20|\x20grep\x20versionName',_0x52bd9c),_0x472b15=_0xd7ce40[_0x8a9a4d(0x295)](/versionName=([^\s]+)/);if(_0x472b15){if(_0x2a1b39[_0x8a9a4d(0x78b)](_0x2a1b39['xqjpK'],_0x2a1b39[_0x8a9a4d(0x3f5)])){_0x334180[_0x8a9a4d(0x6c8)](_0x8a9a4d(0x874)+_0x232241[_0x8a9a4d(0x6dc)]);const _0x1e5467={};_0x1e5467[_0x8a9a4d(0x859)]=![],_0x1e5467['message']=_0x8a9a4d(0x463),tJhrUI['RjHQz'](_0x46aca7,_0x1e5467);}else _0x137e14['version']=_0x472b15[0x1];}}}catch(_0x136524){_0x2a1b39[_0x8a9a4d(0x787)](_0x2a1b39['XsrcX'],_0x2a1b39['XsrcX'])?_0x4b30c5+=_0x8a9a4d(0x591)+_0x491fad+'\x0a':_0x137e14[_0x8a9a4d(0x5a7)]=_0x2a1b39[_0x8a9a4d(0x861)];}try{if(_0x2a1b39['EFUxi'](_0x2a1b39[_0x8a9a4d(0x562)],_0x2a1b39[_0x8a9a4d(0x848)])){const _0xd8d420={};_0xd8d420[_0x8a9a4d(0x76b)]=_0x2a1b39[_0x8a9a4d(0x442)],_0xd8d420['timeout']=0x2710;const _0x2262cf=_0x2c26c0('adb\x20-s\x20'+_0x3446ee+_0x8a9a4d(0x287)+_0x234d63+_0x8a9a4d(0x346),_0xd8d420);_0x137e14['name']=_0x234d63;}else{const _0x53955c={};_0x53955c[_0x8a9a4d(0x859)]=!![],_0x53955c[_0x8a9a4d(0x88b)]=_0x449ef6,_0x53955c['device']=_0x20408a,tJhrUI[_0x8a9a4d(0x641)](_0x54ffc4,_0x53955c);}}catch(_0x55e011){_0x2a1b39[_0x8a9a4d(0x1e1)](_0x2a1b39['OBKZC'],_0x2a1b39[_0x8a9a4d(0x6b2)])?_0x3658ee+='GEMINI_API_KEY='+_0x44cfcd+'\x0a':_0x137e14[_0x8a9a4d(0x719)]=_0x234d63;}try{if(_0x2a1b39[_0x8a9a4d(0x246)]!==_0x2a1b39[_0x8a9a4d(0x64f)]){const _0x380917={};_0x380917[_0x8a9a4d(0x76b)]=_0x8a9a4d(0x377),_0x380917[_0x8a9a4d(0x8ad)]=0x2710;const _0x1c226b=_0x2a1b39[_0x8a9a4d(0x2dd)](_0x2c26c0,'adb\x20-s\x20'+_0x3446ee+_0x8a9a4d(0x7b9)+_0x234d63,_0x380917);_0x137e14[_0x8a9a4d(0x793)]=_0x1c226b['replace']('package:','')[_0x8a9a4d(0x685)]();}else _0x29a3a1[_0x8a9a4d(0x4d0)]=_0x8a9a4d(0x29b),_0x381f31[_0x8a9a4d(0x39b)]&&(_0x220b7f[_0x8a9a4d(0x39b)]=_0x34378d['sessionId']);}catch(_0x456439){_0x137e14[_0x8a9a4d(0x793)]=_0x2a1b39[_0x8a9a4d(0x861)];}_0x137e14[_0x8a9a4d(0x66d)]=_0x234d63,_0x137e14['platform']=_0x2a1b39[_0x8a9a4d(0x339)];}else{if(_0x216736[_0x8a9a4d(0x581)]===_0x2a1b39['bzpeL']){const _0x315b95=_0x216736['udid'];try{if(_0x2a1b39[_0x8a9a4d(0x52d)](_0x2a1b39[_0x8a9a4d(0x266)],_0x2a1b39['GtAaw']))_0x5953a6[_0x4a0b0d]['status']=tJhrUI[_0x8a9a4d(0x399)];else{const _0x3bbcda={};_0x3bbcda[_0x8a9a4d(0x76b)]=_0x2a1b39[_0x8a9a4d(0x442)],_0x3bbcda[_0x8a9a4d(0x8ad)]=0x2710;const _0x4fcb47=_0x2c26c0(_0x8a9a4d(0x1ef)+_0x315b95+_0x8a9a4d(0x710)+_0x234d63+'\x22',_0x3bbcda),_0x16010e=_0x4fcb47['split'](',')[_0x8a9a4d(0x2d0)](_0x372dff=>_0x372dff[_0x8a9a4d(0x685)]()[_0x8a9a4d(0x3bd)](/"/g,''));if(_0x2a1b39['MwGHL'](_0x16010e[_0x8a9a4d(0x526)],0x3))_0x137e14[_0x8a9a4d(0x66d)]=_0x16010e[0x0],_0x137e14[_0x8a9a4d(0x5a7)]=_0x16010e[0x1],_0x137e14[_0x8a9a4d(0x719)]=_0x16010e[0x2];else{if(_0x2a1b39[_0x8a9a4d(0x2e2)](_0x2a1b39['dVLNv'],_0x2a1b39[_0x8a9a4d(0x5c4)])){_0x5b711c[_0x8a9a4d(0x61d)](_0x8a9a4d(0x3cc)+_0x54c4c6+_0x8a9a4d(0x8cb));const _0x4daeaf=_0x2a1b39['efjao'](_0x462c1d,_0x2a1b39[_0x8a9a4d(0x35c)]);_0x2a1b39[_0x8a9a4d(0x225)](_0x4daeaf,_0x580e7f)[_0x8a9a4d(0x795)](_0x288327=>{const _0x4c5deb=_0x8a9a4d;_0x4a4cdf[_0x4c5deb(0x61d)](_0x4c5deb(0x3bf)+_0x57aeb2+'\x20in\x20your\x20browser');});}else _0x137e14[_0x8a9a4d(0x66d)]=_0x234d63,_0x137e14[_0x8a9a4d(0x719)]=_0x234d63,_0x137e14[_0x8a9a4d(0x5a7)]=_0x8a9a4d(0x5b4);}}}catch(_0x16ffdf){if(_0x2a1b39['GpwQd'](_0x2a1b39[_0x8a9a4d(0x6f5)],_0x2a1b39[_0x8a9a4d(0x476)]))return _0x334441;else _0x137e14[_0x8a9a4d(0x66d)]=_0x234d63,_0x137e14['name']=_0x234d63,_0x137e14[_0x8a9a4d(0x5a7)]=_0x2a1b39[_0x8a9a4d(0x861)],_0x137e14[_0x8a9a4d(0x6c8)]=_0x8a9a4d(0x326);}_0x137e14['platform']=_0x2a1b39[_0x8a9a4d(0x28f)];}}const _0x646f8d={};_0x646f8d['success']=!![],_0x646f8d[_0x8a9a4d(0x5bc)]=_0x137e14,_0x51c1fb[_0x8a9a4d(0x843)](_0x646f8d);}catch(_0x262d59){const _0x248650={};_0x248650[_0x8a9a4d(0x66d)]=_0x234d63,_0x248650[_0x8a9a4d(0x581)]=_0x216736[_0x8a9a4d(0x581)],_0x248650[_0x8a9a4d(0x6c8)]=_0x8a9a4d(0x541);const _0x2a7acd={};_0x2a7acd[_0x8a9a4d(0x859)]=![],_0x2a7acd[_0x8a9a4d(0x6c8)]=_0x262d59[_0x8a9a4d(0x6dc)],_0x2a7acd['appInfo']=_0x248650,_0x51c1fb['json'](_0x2a7acd);}}else _0x44ee8c['error']('Error\x20parsing\x20locator\x20line:',_0x2827ab,_0x3d104f);}catch(_0x53bd8f){if(_0x2a1b39[_0x8a9a4d(0x1e1)](_0x2a1b39[_0x8a9a4d(0x592)],_0x2a1b39[_0x8a9a4d(0x592)])){_0x13fd4a[_0x8a9a4d(0x61d)](_0x8a9a4d(0x79b)+_0x5e879c+_0x8a9a4d(0x8cb));const _0x4de354=_0x209eea('sh',['-c',_0x8a9a4d(0x478)+_0x11b2b3+_0x8a9a4d(0x5ab)]);_0x4de354['on'](tJhrUI[_0x8a9a4d(0x60b)],()=>{const _0x5e6ebf=_0x8a9a4d;_0x17fdc8[_0x5e6ebf(0x61d)](_0x5e6ebf(0x3ee)+_0x1d6b86);});}else{const _0x55b207={};_0x55b207[_0x8a9a4d(0x859)]=![],_0x55b207[_0x8a9a4d(0x6c8)]=_0x53bd8f['message'],_0x51c1fb[_0x8a9a4d(0x4d0)](0x1f4)[_0x8a9a4d(0x843)](_0x55b207);}}});let server;function startServer(_0x4d1e3c={}){const _0x3f7cf6=_0x47c41d,_0x1e7616={'wKBzx':function(_0x5aa5b3){return _0x5aa5b3();},'YnpIr':'IBmcx','iEhuA':function(_0x576eb0,_0x532773){return _0x576eb0(_0x532773);},'IOjgR':function(_0x206a00,_0x56c879){return _0x206a00===_0x56c879;},'wJKqm':_0x3f7cf6(0x759),'kxWwd':_0x3f7cf6(0x700),'kPVeG':function(_0x3b940c,_0x591f84){return _0x3b940c(_0x591f84);},'NixLr':'connection','UohhN':function(_0x1c46c7,_0x30220b,_0x1f8f03){return _0x1c46c7(_0x30220b,_0x1f8f03);},'ABqOf':'utf-8','BRgZw':_0x3f7cf6(0x2f4),'NmxmO':'upgrade','IwuOf':'error','XgcDX':function(_0x5ac4c5,_0x45f82e){return _0x5ac4c5!==_0x45f82e;},'rAkBn':_0x3f7cf6(0x324)},_0x57308d=_0x4d1e3c[_0x3f7cf6(0x6c2)]||PORT,_0x4b0410=_0x1e7616[_0x3f7cf6(0x78a)](_0x4d1e3c[_0x3f7cf6(0x564)],![]),_0x582a4d=_0x1e7616[_0x3f7cf6(0x82e)];return console['log'](_0x3f7cf6(0x86f)+_0x582a4d+'\x0a'),new Promise((_0x353338,_0x3e5356)=>{const _0x55907b=_0x3f7cf6,_0x444dff={'nOmiM':_0x55907b(0x1df),'QfaMI':function(_0x21a636,_0xc67b43){const _0x8b53dc=_0x55907b;return _0x1e7616[_0x8b53dc(0x7aa)](_0x21a636,_0xc67b43);},'FXYxr':function(_0x34d8d9,_0x594160){return _0x1e7616['IOjgR'](_0x34d8d9,_0x594160);},'LXJYv':_0x1e7616[_0x55907b(0x302)],'mdsYx':_0x1e7616[_0x55907b(0x1fa)],'qjrOq':'open','fEnkr':function(_0x525f8d,_0x5c7fc1){return _0x525f8d(_0x5c7fc1);},'boEKC':function(_0x136011,_0x3b39dd){return _0x1e7616['kPVeG'](_0x136011,_0x3b39dd);},'jcFoI':_0x1e7616[_0x55907b(0x814)],'lUkxt':function(_0x5155fb,_0x11581f,_0x28aa82){const _0x2d2b0d=_0x55907b;return _0x1e7616[_0x2d2b0d(0x7d1)](_0x5155fb,_0x11581f,_0x28aa82);},'JtiBE':_0x1e7616[_0x55907b(0x327)],'FESby':_0x1e7616[_0x55907b(0x8c4)]};server=app[_0x55907b(0x804)](_0x57308d,()=>{const _0x3be123=_0x55907b;console['log']('Server\x20running\x20on\x20port\x20'+_0x57308d),console['log'](_0x3be123(0x618)),_0x1e7616[_0x3be123(0x358)](discoverDevices)[_0x3be123(0x6bf)](_0x4ef329=>{const _0x5d7a7c=_0x3be123,_0x324594={'IUBmS':_0x444dff[_0x5d7a7c(0x87a)],'TDFjQ':function(_0x45bf23,_0x5db77f){return _0x444dff['QfaMI'](_0x45bf23,_0x5db77f);},'JKAMn':function(_0x45605e,_0x160738){return _0x444dff['FXYxr'](_0x45605e,_0x160738);},'mvUIR':_0x444dff[_0x5d7a7c(0x345)],'BCXnk':_0x444dff[_0x5d7a7c(0x585)]};console[_0x5d7a7c(0x61d)]('Discovered\x20'+_0x4ef329[_0x5d7a7c(0x526)]+'\x20devices');if(_0x4b0410){console['log'](_0x5d7a7c(0x3cc)+_0x582a4d+_0x5d7a7c(0x8cb));const _0x1a162c=_0x444dff['QfaMI'](require,_0x444dff[_0x5d7a7c(0x372)]);_0x444dff[_0x5d7a7c(0x71e)](_0x1a162c,_0x582a4d)[_0x5d7a7c(0x795)](_0x1293f9=>{const _0x303299=_0x5d7a7c,_0x18d016={'HaNav':_0x324594[_0x303299(0x7d4)],'XGPtn':function(_0x5a3273,_0x323dad){const _0x37e827=_0x303299;return _0x324594[_0x37e827(0x215)](_0x5a3273,_0x323dad);}};if(_0x324594[_0x303299(0x5c5)](_0x324594[_0x303299(0x731)],_0x324594['BCXnk'])){_0x49d8e8[_0x303299(0x6c8)](EhxJib[_0x303299(0x551)],_0x37ea0e);const _0x4cd933={};_0x4cd933[_0x303299(0x859)]=![],EhxJib['XGPtn'](_0x246603,_0x4cd933);}else console[_0x303299(0x61d)](_0x303299(0x3bf)+_0x582a4d+_0x303299(0x549));});}const _0x1068a8={};_0x1068a8[_0x5d7a7c(0x6c2)]=_0x57308d,_0x1068a8['devices']=_0x4ef329,_0x444dff[_0x5d7a7c(0x4f5)](_0x353338,_0x1068a8);})[_0x3be123(0x795)](_0x3e5356);}),server['on'](_0x1e7616[_0x55907b(0x228)],(_0x3a1618,_0x592d7e,_0x1aea9a)=>{const _0x3cc90c=_0x55907b;if('IBmcx'===_0x1e7616[_0x3cc90c(0x877)])wss[_0x3cc90c(0x577)](_0x3a1618,_0x592d7e,_0x1aea9a,_0x2e69b7=>{const _0x3679e0=_0x3cc90c;wss['emit'](_0x444dff[_0x3679e0(0x201)],_0x2e69b7,_0x3a1618);});else{const _0x46fadd=bGEhJT[_0x3cc90c(0x767)](_0x389b30,_0x3cc90c(0x2b1)+_0x34cdac+_0x3cc90c(0x7b9)+_0xe968ab,{'encoding':bGEhJT[_0x3cc90c(0x240)],'timeout':0x2710});_0x328ac9['path']=_0x46fadd[_0x3cc90c(0x3bd)](bGEhJT['FESby'],'')[_0x3cc90c(0x685)]();}}),server['on'](_0x1e7616[_0x55907b(0x6da)],_0x3e5356);});}function stopServer(){const _0x56c301=_0x47c41d,_0x3e8fc5={'tIUUa':'online','sgwGB':function(_0x351b17,_0x3d6bc8){return _0x351b17!==_0x3d6bc8;},'FlnSW':_0x56c301(0x45b),'cZFut':function(_0x5bc6f7){return _0x5bc6f7();}};return new Promise(_0x5174ad=>{const _0x431c28=_0x56c301,_0x4b24a5={};_0x4b24a5[_0x431c28(0x815)]=_0x3e8fc5['tIUUa'];const _0x467177=_0x4b24a5;server?server['close'](_0x5174ad):_0x3e8fc5[_0x431c28(0x4dd)](_0x3e8fc5[_0x431c28(0x7b5)],_0x3e8fc5[_0x431c28(0x7b5)])?_0x1a039a[_0x598c19][_0x431c28(0x4d0)]=VwhDJA[_0x431c28(0x815)]:_0x3e8fc5['cZFut'](_0x5174ad);});}const _0x2aef20={};_0x2aef20[_0x47c41d(0x5b7)]=startServer,_0x2aef20['stopServer']=stopServer,module[_0x47c41d(0x294)]=_0x2aef20;require[_0x47c41d(0x83d)]===module&&startServer()[_0x47c41d(0x795)](_0x51b861=>{const _0x11c6d1=_0x47c41d,_0x2843f2={};_0x2843f2['gelgE']=_0x11c6d1(0x779);const _0x80b40a=_0x2843f2;console[_0x11c6d1(0x6c8)](_0x80b40a[_0x11c6d1(0x448)],_0x51b861),process['exit'](0x1);});
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
// Load environment variables from .env file in project root
|
|
4
|
+
require('dotenv').config({ path: path.join(__dirname, '../../.env') });
|
|
5
|
+
|
|
6
|
+
const express = require('express');
|
|
7
|
+
const cors = require('cors');
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
const WebSocket = require('ws');
|
|
10
|
+
const fs = require('fs').promises;
|
|
11
|
+
const AIProviderManager = require('./aiProviders');
|
|
12
|
+
|
|
13
|
+
// Import deviceDetection from appropriate location (dev vs npm package)
|
|
14
|
+
let discoverAllDevices;
|
|
15
|
+
try {
|
|
16
|
+
// Try npm package location first (lib/)
|
|
17
|
+
({ discoverAllDevices } = require('./deviceDetection'));
|
|
18
|
+
} catch (err) {
|
|
19
|
+
// Fall back to development location
|
|
20
|
+
({ discoverAllDevices } = require('../../deviceDetection'));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const { execSync } = require('child_process');
|
|
24
|
+
|
|
25
|
+
const app = express();
|
|
26
|
+
const PORT = process.env.PORT || 3001;
|
|
27
|
+
|
|
28
|
+
// Middleware
|
|
29
|
+
app.use(cors());
|
|
30
|
+
app.use(express.json());
|
|
31
|
+
|
|
32
|
+
// Serve static frontend files - check both dev and npm package locations
|
|
33
|
+
const frontendPath = require('fs').existsSync(path.join(__dirname, '../frontend/build'))
|
|
34
|
+
? path.join(__dirname, '../frontend/build')
|
|
35
|
+
: path.join(__dirname, './frontend');
|
|
36
|
+
|
|
37
|
+
app.use(express.static(frontendPath));
|
|
38
|
+
// Frontend path: ${frontendPath}
|
|
39
|
+
|
|
40
|
+
// WebSocket server
|
|
41
|
+
const wss = new WebSocket.Server({ noServer: true });
|
|
42
|
+
|
|
43
|
+
// AI Provider Manager - supports multiple AI providers
|
|
44
|
+
const aiManager = new AIProviderManager();
|
|
45
|
+
|
|
46
|
+
// Store connected devices
|
|
47
|
+
let connectedDevices = [];
|
|
48
|
+
let activeConnections = new Map();
|
|
49
|
+
let wdaProcesses = new Map(); // Track WDA processes: Map<deviceName, {xcodebuild: pid, iproxy: pid}>
|
|
50
|
+
|
|
51
|
+
// Track UIAutomator2 sessions for Android devices
|
|
52
|
+
let androidSessions = new Map(); // Map<udid, {sessionId, port, serverPid}>
|
|
53
|
+
|
|
54
|
+
// Helper to find config files in both dev and npm package locations
|
|
55
|
+
function findConfigFile(filename) {
|
|
56
|
+
// Try development location first
|
|
57
|
+
let configPath = path.join(__dirname, '../../', filename);
|
|
58
|
+
if (require('fs').existsSync(configPath)) {
|
|
59
|
+
return configPath;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Try npm package location (lib/ -> config/)
|
|
63
|
+
configPath = path.join(__dirname, '../config/', filename);
|
|
64
|
+
if (require('fs').existsSync(configPath)) {
|
|
65
|
+
return configPath;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Fall back to dev location for creation
|
|
69
|
+
return path.join(__dirname, '../../', filename);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function findScriptFile(filename) {
|
|
73
|
+
const fs = require('fs');
|
|
74
|
+
|
|
75
|
+
// List of paths to try in order
|
|
76
|
+
const pathsToTry = [
|
|
77
|
+
// Development location (project root)
|
|
78
|
+
path.join(__dirname, '../../', filename),
|
|
79
|
+
// NPM global install location - from lib/ to scripts/shell/
|
|
80
|
+
path.join(__dirname, '../scripts/shell/', filename),
|
|
81
|
+
// Try without .sh extension (compiled binaries)
|
|
82
|
+
path.join(__dirname, '../scripts/shell/', filename.replace(/\.sh$/, '')),
|
|
83
|
+
// Try in lib directory itself (backup)
|
|
84
|
+
path.join(__dirname, filename),
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
for (const scriptPath of pathsToTry) {
|
|
88
|
+
if (fs.existsSync(scriptPath)) {
|
|
89
|
+
console.log(`ā
Found script: ${filename} at ${scriptPath}`);
|
|
90
|
+
return scriptPath;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.error(`ā Script not found: ${filename}`);
|
|
95
|
+
console.error(` Searched in:`);
|
|
96
|
+
pathsToTry.forEach(p => console.error(` - ${p}`));
|
|
97
|
+
|
|
98
|
+
// Return first path as fallback (will fail but with clear error)
|
|
99
|
+
return pathsToTry[0];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Device configuration paths
|
|
103
|
+
const DEVICE_CONFIG = findConfigFile('devices.conf');
|
|
104
|
+
// Use OS temp directory for session file - works for both local and npm package
|
|
105
|
+
const SESSION_MAP_FILE = path.join(require('os').tmpdir(), 'devicely_android_sessions.map');
|
|
106
|
+
const APPS_CONFIG = findConfigFile('apps_presets.conf');
|
|
107
|
+
|
|
108
|
+
// iOS scripts
|
|
109
|
+
const WIRELESS_SCRIPT_PATH = findScriptFile('connect_ios_wireless_multi_final.sh');
|
|
110
|
+
const USB_SCRIPT_PATH = findScriptFile('connect_ios_usb_multi_final.sh');
|
|
111
|
+
|
|
112
|
+
// Android scripts
|
|
113
|
+
const ANDROID_WIRELESS_SCRIPT_PATH = findScriptFile('android_device_control.sh');
|
|
114
|
+
const ANDROID_USB_SCRIPT_PATH = findScriptFile('android_device_control.sh');
|
|
115
|
+
|
|
116
|
+
// Recording storage path
|
|
117
|
+
const RECORDINGS_DIR = path.join(__dirname, '../../recordings');
|
|
118
|
+
|
|
119
|
+
// Screenshots storage path
|
|
120
|
+
const SCREENSHOTS_DIR = path.join(__dirname, './screenshots');
|
|
121
|
+
|
|
122
|
+
// Recording state
|
|
123
|
+
let currentRecording = null; // { name, devices, commands: [], startTime }
|
|
124
|
+
let isRecording = false;
|
|
125
|
+
|
|
126
|
+
// Replay state
|
|
127
|
+
let isReplaying = false;
|
|
128
|
+
let replayAborted = false;
|
|
129
|
+
|
|
130
|
+
// ============================================
|
|
131
|
+
// UIAutomator2 Session Management Functions
|
|
132
|
+
// ============================================
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Start UIAutomator2 session for Android device
|
|
136
|
+
*/
|
|
137
|
+
async function startUIAutomator2Session(udid, deviceName) {
|
|
138
|
+
console.log(`š Starting UIAutomator2 session for ${deviceName} (${udid})...`);
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
// Find available port
|
|
142
|
+
let port = 8200;
|
|
143
|
+
while (true) {
|
|
144
|
+
try {
|
|
145
|
+
execSync(`lsof -i:${port}`, { stdio: 'ignore' });
|
|
146
|
+
port++; // Port is in use, try next
|
|
147
|
+
} catch {
|
|
148
|
+
break; // Port is available
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.log(`š” Using port ${port} for ${deviceName}`);
|
|
153
|
+
|
|
154
|
+
// Start UIAutomator2 server on device
|
|
155
|
+
const serverProcess = spawn('adb', ['-s', udid, 'shell', 'am', 'instrument', '-w',
|
|
156
|
+
'io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner'
|
|
157
|
+
], { detached: true, stdio: 'ignore' });
|
|
158
|
+
|
|
159
|
+
serverProcess.unref(); // Don't wait for process to exit
|
|
160
|
+
|
|
161
|
+
// Wait for server to start
|
|
162
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
163
|
+
|
|
164
|
+
// Forward port
|
|
165
|
+
execSync(`adb -s ${udid} forward tcp:${port} tcp:6790`);
|
|
166
|
+
|
|
167
|
+
// Wait a bit more
|
|
168
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
169
|
+
|
|
170
|
+
// Create session via HTTP
|
|
171
|
+
const axios = require('axios');
|
|
172
|
+
const sessionResponse = await axios.post(`http://localhost:${port}/wd/hub/session`, {
|
|
173
|
+
capabilities: {
|
|
174
|
+
alwaysMatch: {
|
|
175
|
+
platformName: 'Android',
|
|
176
|
+
'appium:automationName': 'UiAutomator2',
|
|
177
|
+
'appium:udid': udid
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const sessionId = sessionResponse.data.value.sessionId || sessionResponse.data.sessionId;
|
|
183
|
+
|
|
184
|
+
// Store session info
|
|
185
|
+
androidSessions.set(udid, {
|
|
186
|
+
sessionId,
|
|
187
|
+
port,
|
|
188
|
+
serverPid: serverProcess.pid,
|
|
189
|
+
deviceName
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Save to session file for scripts to use - remove old entries first
|
|
193
|
+
try {
|
|
194
|
+
let content = '';
|
|
195
|
+
try {
|
|
196
|
+
content = await fs.readFile(SESSION_MAP_FILE, 'utf-8');
|
|
197
|
+
} catch (err) {
|
|
198
|
+
// File doesn't exist yet, that's ok
|
|
199
|
+
}
|
|
200
|
+
const lines = content.split('\n').filter(line => line && !line.startsWith(`${udid}:`));
|
|
201
|
+
lines.push(`${udid}:${sessionId}:${port}`);
|
|
202
|
+
await fs.writeFile(SESSION_MAP_FILE, lines.join('\n') + '\n');
|
|
203
|
+
console.log(`ā
Session file updated: ${udid}:${sessionId}:${port}`);
|
|
204
|
+
} catch (err) {
|
|
205
|
+
console.error(`ā ļø Failed to update session file: ${err.message}`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
console.log(`ā
UIAutomator2 session created for ${deviceName}`);
|
|
209
|
+
console.log(` Session ID: ${sessionId}`);
|
|
210
|
+
console.log(` Port: ${port}`);
|
|
211
|
+
|
|
212
|
+
return { success: true, sessionId, port };
|
|
213
|
+
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error(`ā Failed to start UIAutomator2 for ${deviceName}:`, error.message);
|
|
216
|
+
return { success: false, error: error.message };
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Stop UIAutomator2 session for Android device
|
|
222
|
+
*/
|
|
223
|
+
async function stopUIAutomator2Session(udid, deviceName) {
|
|
224
|
+
console.log(`š Stopping UIAutomator2 session for ${deviceName} (${udid})...`);
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
const session = androidSessions.get(udid);
|
|
228
|
+
|
|
229
|
+
if (!session) {
|
|
230
|
+
console.log(`ā ļø No active session found for ${deviceName}`);
|
|
231
|
+
return { success: true, message: 'No active session' };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Delete session via HTTP
|
|
235
|
+
try {
|
|
236
|
+
const axios = require('axios');
|
|
237
|
+
await axios.delete(`http://localhost:${session.port}/wd/hub/session/${session.sessionId}`);
|
|
238
|
+
console.log(`ā
UIAutomator2 session deleted for ${deviceName}`);
|
|
239
|
+
} catch (err) {
|
|
240
|
+
console.log(`ā ļø Could not delete session via HTTP: ${err.message}`);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Remove port forwarding
|
|
244
|
+
try {
|
|
245
|
+
execSync(`adb -s ${udid} forward --remove tcp:${session.port}`);
|
|
246
|
+
console.log(`ā
Port forwarding removed for ${deviceName}`);
|
|
247
|
+
} catch (err) {
|
|
248
|
+
console.log(`ā ļø Could not remove port forwarding: ${err.message}`);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Kill UIAutomator2 server on device
|
|
252
|
+
try {
|
|
253
|
+
execSync(`adb -s ${udid} shell am force-stop io.appium.uiautomator2.server`);
|
|
254
|
+
execSync(`adb -s ${udid} shell am force-stop io.appium.uiautomator2.server.test`);
|
|
255
|
+
console.log(`ā
UIAutomator2 server stopped on ${deviceName}`);
|
|
256
|
+
} catch (err) {
|
|
257
|
+
console.log(`ā ļø Could not stop UIAutomator2 server: ${err.message}`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Remove from memory
|
|
261
|
+
androidSessions.delete(udid);
|
|
262
|
+
|
|
263
|
+
// Update session file
|
|
264
|
+
try {
|
|
265
|
+
const content = await fs.readFile(SESSION_MAP_FILE, 'utf-8');
|
|
266
|
+
const lines = content.split('\n').filter(line => !line.startsWith(`${udid}:`));
|
|
267
|
+
await fs.writeFile(SESSION_MAP_FILE, lines.join('\n'));
|
|
268
|
+
console.log(`ā
Session file updated for ${deviceName}`);
|
|
269
|
+
} catch (err) {
|
|
270
|
+
console.log(`ā ļø Could not update session file: ${err.message}`);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
console.log(`ā
UIAutomator2 session stopped for ${deviceName}`);
|
|
274
|
+
return { success: true };
|
|
275
|
+
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.error(`ā Error stopping UIAutomator2 for ${deviceName}:`, error.message);
|
|
278
|
+
return { success: false, error: error.message };
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// ============================================
|
|
283
|
+
|
|
284
|
+
// Load device configuration
|
|
285
|
+
async function loadDeviceConfig() {
|
|
286
|
+
try {
|
|
287
|
+
const content = await fs.readFile(DEVICE_CONFIG, 'utf-8');
|
|
288
|
+
const devices = content
|
|
289
|
+
.split('\n')
|
|
290
|
+
.filter(line => line.trim() && !line.startsWith('#'))
|
|
291
|
+
.map(line => {
|
|
292
|
+
const parts = line.split(',').map(s => s.trim());
|
|
293
|
+
const [name, udid, ip, platform, type] = parts;
|
|
294
|
+
|
|
295
|
+
// Smart platform detection if not specified
|
|
296
|
+
let detectedPlatform = platform || 'ios';
|
|
297
|
+
if (!platform && udid) {
|
|
298
|
+
// Android wireless: IP:PORT format
|
|
299
|
+
if (udid.includes(':') && udid.match(/^\d+\.\d+\.\d+\.\d+:\d+$/)) {
|
|
300
|
+
detectedPlatform = 'android';
|
|
301
|
+
}
|
|
302
|
+
// Android USB: Short serial without dashes
|
|
303
|
+
else if (udid.length < 20 && !udid.includes('-')) {
|
|
304
|
+
detectedPlatform = 'android';
|
|
305
|
+
}
|
|
306
|
+
// iOS: Long UUID with dashes
|
|
307
|
+
else if (udid.includes('-') && udid.length > 30) {
|
|
308
|
+
detectedPlatform = 'ios';
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
name,
|
|
314
|
+
udid,
|
|
315
|
+
ip: ip || '',
|
|
316
|
+
platform: detectedPlatform,
|
|
317
|
+
type: type || (ip ? 'wireless' : 'usb'),
|
|
318
|
+
status: 'unknown'
|
|
319
|
+
};
|
|
320
|
+
});
|
|
321
|
+
return devices;
|
|
322
|
+
} catch (error) {
|
|
323
|
+
console.error('Error loading device config:', error);
|
|
324
|
+
return [];
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Discover and check device connectivity (USB + Wireless)
|
|
329
|
+
async function discoverDevices() {
|
|
330
|
+
// Save current connection states
|
|
331
|
+
const previousStates = new Map();
|
|
332
|
+
connectedDevices.forEach(device => {
|
|
333
|
+
previousStates.set(device.udid, {
|
|
334
|
+
status: device.status,
|
|
335
|
+
sessionId: device.sessionId
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
connectedDevices = await discoverAllDevices();
|
|
340
|
+
|
|
341
|
+
// Restore connection states for devices that were previously connected
|
|
342
|
+
connectedDevices.forEach(device => {
|
|
343
|
+
const prevState = previousStates.get(device.udid);
|
|
344
|
+
if (prevState && prevState.status === 'online') {
|
|
345
|
+
// Preserve the online status for previously connected devices
|
|
346
|
+
device.status = 'online';
|
|
347
|
+
if (prevState.sessionId) {
|
|
348
|
+
device.sessionId = prevState.sessionId;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
// Auto-save USB devices to config for wireless use later
|
|
354
|
+
await autoSaveUSBDevicesToConfig(connectedDevices);
|
|
355
|
+
|
|
356
|
+
return connectedDevices;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Auto-save USB devices to config
|
|
360
|
+
async function autoSaveUSBDevicesToConfig(devices) {
|
|
361
|
+
try {
|
|
362
|
+
const usbDevices = devices.filter(d => d.connectionType === 'usb');
|
|
363
|
+
if (usbDevices.length === 0) return;
|
|
364
|
+
|
|
365
|
+
// Load existing config
|
|
366
|
+
const existingDevices = await loadDeviceConfig();
|
|
367
|
+
const existingUdids = new Set(existingDevices.map(d => d.udid));
|
|
368
|
+
|
|
369
|
+
// Add new USB devices
|
|
370
|
+
const newDevices = usbDevices.filter(d => !existingUdids.has(d.udid));
|
|
371
|
+
if (newDevices.length === 0) return;
|
|
372
|
+
|
|
373
|
+
// Append to config with placeholder IP (will be filled when wireless is configured)
|
|
374
|
+
const allDevices = [...existingDevices, ...newDevices.map(d => ({
|
|
375
|
+
name: d.name,
|
|
376
|
+
udid: d.udid,
|
|
377
|
+
ip: '' // Empty IP for USB devices, to be filled for wireless
|
|
378
|
+
}))];
|
|
379
|
+
|
|
380
|
+
// Save to config
|
|
381
|
+
let content = '# Device Configuration (Auto-updated)\n';
|
|
382
|
+
content += '# Format: device_name,udid,ip_address\n';
|
|
383
|
+
content += '# USB devices auto-detected. Add IP for wireless connection.\n\n';
|
|
384
|
+
|
|
385
|
+
allDevices.forEach(device => {
|
|
386
|
+
const ip = device.ip || '';
|
|
387
|
+
content += `${device.name},${device.udid},${ip}\n`;
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
await fs.writeFile(DEVICE_CONFIG, content);
|
|
391
|
+
console.log(`ā
Auto-saved ${newDevices.length} new USB device(s) to config`);
|
|
392
|
+
} catch (error) {
|
|
393
|
+
console.error('Error auto-saving devices:', error);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Check device connectivity
|
|
398
|
+
function checkDeviceConnectivity(device) {
|
|
399
|
+
return new Promise((resolve) => {
|
|
400
|
+
const curl = spawn('curl', [
|
|
401
|
+
'-s',
|
|
402
|
+
'--connect-timeout', '2',
|
|
403
|
+
'--max-time', '3',
|
|
404
|
+
`http://${device.ip}:8100/status`
|
|
405
|
+
]);
|
|
406
|
+
|
|
407
|
+
let output = '';
|
|
408
|
+
curl.stdout.on('data', (data) => {
|
|
409
|
+
output += data.toString();
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
curl.on('close', (code) => {
|
|
413
|
+
resolve(output.includes('"state"'));
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
setTimeout(() => {
|
|
417
|
+
curl.kill();
|
|
418
|
+
resolve(false);
|
|
419
|
+
}, 3000);
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Load app presets from config file
|
|
424
|
+
function loadAppPresets() {
|
|
425
|
+
try {
|
|
426
|
+
if (!require('fs').existsSync(APPS_CONFIG)) {
|
|
427
|
+
return {};
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const content = require('fs').readFileSync(APPS_CONFIG, 'utf-8');
|
|
431
|
+
const presets = {};
|
|
432
|
+
|
|
433
|
+
content.split('\n')
|
|
434
|
+
.filter(line => line.trim() && !line.startsWith('#'))
|
|
435
|
+
.forEach(line => {
|
|
436
|
+
const [name, packageId] = line.split(',').map(s => s.trim());
|
|
437
|
+
if (name && packageId) {
|
|
438
|
+
// Support platform-specific notation: name.ios or name.android
|
|
439
|
+
const parts = name.split('.');
|
|
440
|
+
if (parts.length === 2) {
|
|
441
|
+
const [appName, platform] = parts;
|
|
442
|
+
if (!presets[appName]) presets[appName] = {};
|
|
443
|
+
presets[appName][platform] = packageId;
|
|
444
|
+
} else {
|
|
445
|
+
// Generic app (works on both platforms)
|
|
446
|
+
if (!presets[name]) presets[name] = {};
|
|
447
|
+
presets[name].common = packageId;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
return presets;
|
|
453
|
+
} catch (error) {
|
|
454
|
+
console.error('Error loading app presets:', error);
|
|
455
|
+
return {};
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Resolve app preset based on device platform
|
|
460
|
+
function resolveAppPreset(command, platform) {
|
|
461
|
+
const appPresets = loadAppPresets();
|
|
462
|
+
|
|
463
|
+
// Check if command is "launch <appname>"
|
|
464
|
+
const launchMatch = command.match(/^launch\s+(\S+)(.*)$/);
|
|
465
|
+
if (!launchMatch) return command; // Not a launch command
|
|
466
|
+
|
|
467
|
+
const appName = launchMatch[1];
|
|
468
|
+
const restOfCommand = launchMatch[2];
|
|
469
|
+
|
|
470
|
+
// If it already looks like a bundle ID, don't resolve
|
|
471
|
+
if (appName.includes('.')) return command;
|
|
472
|
+
|
|
473
|
+
// Look up preset
|
|
474
|
+
if (appPresets[appName]) {
|
|
475
|
+
const preset = appPresets[appName];
|
|
476
|
+
let bundleId;
|
|
477
|
+
|
|
478
|
+
// Try platform-specific first, then common
|
|
479
|
+
if (preset[platform]) {
|
|
480
|
+
bundleId = preset[platform];
|
|
481
|
+
} else if (preset.common) {
|
|
482
|
+
bundleId = preset.common;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (bundleId) {
|
|
486
|
+
console.log(` š± Resolved app preset: "${appName}" ā "${bundleId}" (${platform})`);
|
|
487
|
+
return `launch ${bundleId}${restOfCommand}`;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// No preset found, return original
|
|
492
|
+
return command;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// Execute command on device(s)
|
|
496
|
+
function executeCommand(deviceNames, command, wsClient) {
|
|
497
|
+
return new Promise(async (resolve, reject) => {
|
|
498
|
+
console.log(`\n${'#'.repeat(60)}`);
|
|
499
|
+
console.log(`Device names received: [${deviceNames.join(', ')}]`);
|
|
500
|
+
console.log(`Command: "${command}"`);
|
|
501
|
+
console.log(`${'#'.repeat(60)}\n`);
|
|
502
|
+
|
|
503
|
+
// Get full device objects from connectedDevices cache
|
|
504
|
+
// Match by name, udid, or serial
|
|
505
|
+
const devices = connectedDevices.filter(d =>
|
|
506
|
+
deviceNames.includes(d.name) ||
|
|
507
|
+
deviceNames.includes(d.udid) ||
|
|
508
|
+
deviceNames.includes(d.serial)
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
console.log(`Cache contents:`, connectedDevices.map(d => `${d.name}(${d.status})`).join(', '));
|
|
512
|
+
|
|
513
|
+
if (devices.length === 0) {
|
|
514
|
+
console.error(`ā No devices found for: [${deviceNames.join(', ')}]`);
|
|
515
|
+
return reject({ success: false, error: 'No devices found. Please refresh device list and try again.' });
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Check if devices are online/connected
|
|
519
|
+
// Accept both 'online' and 'connected' as valid statuses
|
|
520
|
+
const offlineDevices = devices.filter(d => !['online', 'connected'].includes(d.status));
|
|
521
|
+
if (offlineDevices.length > 0) {
|
|
522
|
+
const offlineNames = offlineDevices.map(d => `${d.name} (status: ${d.status})`).join(', ');
|
|
523
|
+
console.error(`ā Devices not connected: [${offlineNames}]`);
|
|
524
|
+
|
|
525
|
+
// Send user-friendly message via WebSocket
|
|
526
|
+
if (wsClient) {
|
|
527
|
+
wsClient.send(JSON.stringify({
|
|
528
|
+
type: 'command_output',
|
|
529
|
+
data: `\nā ļø Error: Devices not connected: ${offlineNames}\n\nš” Please click the "Connect" button on each device before running commands.\n\n`,
|
|
530
|
+
devices: deviceNames
|
|
531
|
+
}));
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
return reject({
|
|
535
|
+
success: false,
|
|
536
|
+
error: `Devices not connected: ${offlineNames}. Please click "Connect" button on each device first.`
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
console.log(`ā
Found ${devices.length} connected devices`);
|
|
541
|
+
console.log('Device details:', devices.map(d => `${d.name}(${d.platform}-${d.connectionType})`).join(', '));
|
|
542
|
+
|
|
543
|
+
// Group devices by platform and connection type
|
|
544
|
+
const iosUSBDevices = devices.filter(d => d.platform === 'ios' && d.connectionType === 'usb');
|
|
545
|
+
const iosWirelessDevices = devices.filter(d => d.platform === 'ios' && d.connectionType === 'wireless');
|
|
546
|
+
const androidUSBDevices = devices.filter(d => d.platform === 'android' && d.connectionType === 'usb');
|
|
547
|
+
const androidWirelessDevices = devices.filter(d => d.platform === 'android' && d.connectionType === 'wireless');
|
|
548
|
+
|
|
549
|
+
const promises = [];
|
|
550
|
+
|
|
551
|
+
// Execute for iOS USB devices
|
|
552
|
+
if (iosUSBDevices.length > 0) {
|
|
553
|
+
const names = iosUSBDevices.map(d => d.name);
|
|
554
|
+
const iosCommand = resolveAppPreset(command, 'ios');
|
|
555
|
+
console.log(`Using iOS USB script for: ${names.join(', ')}`);
|
|
556
|
+
promises.push(executeWithScript(USB_SCRIPT_PATH, names, iosCommand, wsClient));
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Execute for iOS wireless devices
|
|
560
|
+
if (iosWirelessDevices.length > 0) {
|
|
561
|
+
const names = iosWirelessDevices.map(d => d.name);
|
|
562
|
+
const iosCommand = resolveAppPreset(command, 'ios');
|
|
563
|
+
console.log(`Using iOS wireless script for: ${names.join(', ')}`);
|
|
564
|
+
promises.push(executeWithScript(WIRELESS_SCRIPT_PATH, names, iosCommand, wsClient));
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Execute for Android USB devices
|
|
568
|
+
if (androidUSBDevices.length > 0) {
|
|
569
|
+
const androidCommand = resolveAppPreset(command, 'android');
|
|
570
|
+
console.log(`Using Android control script for USB devices: ${androidUSBDevices.map(d => d.name).join(', ')}`);
|
|
571
|
+
promises.push(executeAndroidDevices(ANDROID_USB_SCRIPT_PATH, androidUSBDevices, androidCommand, wsClient));
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Execute for Android wireless devices
|
|
575
|
+
if (androidWirelessDevices.length > 0) {
|
|
576
|
+
const androidCommand = resolveAppPreset(command, 'android');
|
|
577
|
+
console.log(`Using Android control script for wireless devices: ${androidWirelessDevices.map(d => d.name).join(', ')}`);
|
|
578
|
+
promises.push(executeAndroidDevices(ANDROID_WIRELESS_SCRIPT_PATH, androidWirelessDevices, androidCommand, wsClient));
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
if (promises.length === 0) {
|
|
582
|
+
|
|
583
|
+
return reject({ success: false, error: 'No executable devices found' });
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
try {
|
|
587
|
+
const results = await Promise.allSettled(promises);
|
|
588
|
+
const successCount = results.filter(r => r.status === 'fulfilled').length;
|
|
589
|
+
const failCount = results.filter(r => r.status === 'rejected').length;
|
|
590
|
+
|
|
591
|
+
console.log(`\nExecuteCommand summary: ${successCount} succeeded, ${failCount} failed`);
|
|
592
|
+
|
|
593
|
+
resolve({
|
|
594
|
+
success: true,
|
|
595
|
+
results,
|
|
596
|
+
summary: `${successCount}/${promises.length} script groups completed`
|
|
597
|
+
});
|
|
598
|
+
} catch (error) {
|
|
599
|
+
console.error('Script execution error:', error);
|
|
600
|
+
reject(error);
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
function executeWithScript(scriptPath, deviceNames, command, wsClient) {
|
|
606
|
+
return new Promise((resolve, reject) => {
|
|
607
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
608
|
+
console.log(`Script: ${path.basename(scriptPath)}`);
|
|
609
|
+
console.log(`Devices: [${deviceNames.join(', ')}]`);
|
|
610
|
+
console.log(`Command: "${command}"`);
|
|
611
|
+
|
|
612
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
613
|
+
|
|
614
|
+
// Execute command on each device in parallel
|
|
615
|
+
const devicePromises = deviceNames.map((deviceName, index) => {
|
|
616
|
+
|
|
617
|
+
return new Promise((resolveDevice, rejectDevice) => {
|
|
618
|
+
// Use -d flag for each device
|
|
619
|
+
const args = ['-d', deviceName, command];
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
const child = spawn(scriptPath, args, {
|
|
623
|
+
cwd: path.dirname(scriptPath)
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
let output = '';
|
|
628
|
+
let error = '';
|
|
629
|
+
|
|
630
|
+
child.stdout.on('data', (data) => {
|
|
631
|
+
const text = data.toString();
|
|
632
|
+
output += text;
|
|
633
|
+
console.log(`[${deviceName}] STDOUT: ${text.trim()}`);
|
|
634
|
+
if (wsClient) {
|
|
635
|
+
wsClient.send(JSON.stringify({
|
|
636
|
+
type: 'command_output',
|
|
637
|
+
data: `[${deviceName}] ${text}`,
|
|
638
|
+
devices: [deviceName]
|
|
639
|
+
}));
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
child.stderr.on('data', (data) => {
|
|
644
|
+
const text = data.toString();
|
|
645
|
+
error += text;
|
|
646
|
+
console.error(`[${deviceName}] STDERR: ${text.trim()}`);
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
child.on('close', (code) => {
|
|
650
|
+
|
|
651
|
+
if (code === 0) {
|
|
652
|
+
resolveDevice({ success: true, output, device: deviceName });
|
|
653
|
+
} else {
|
|
654
|
+
rejectDevice({ success: false, error: error || `Script exited with code ${code}`, device: deviceName });
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
child.on('error', (err) => {
|
|
659
|
+
console.error(`[${deviceName}] Process error: ${err.message}`);
|
|
660
|
+
rejectDevice({ success: false, error: err.message, device: deviceName });
|
|
661
|
+
});
|
|
662
|
+
});
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
// Wait for all devices to complete
|
|
667
|
+
Promise.allSettled(devicePromises)
|
|
668
|
+
.then(results => {
|
|
669
|
+
const successful = results.filter(r => r.status === 'fulfilled').length;
|
|
670
|
+
const failed = results.filter(r => r.status === 'rejected').length;
|
|
671
|
+
|
|
672
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
673
|
+
|
|
674
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
675
|
+
|
|
676
|
+
resolve({
|
|
677
|
+
success: true,
|
|
678
|
+
results,
|
|
679
|
+
summary: `${successful}/${deviceNames.length} devices completed successfully`
|
|
680
|
+
});
|
|
681
|
+
})
|
|
682
|
+
.catch(error => {
|
|
683
|
+
console.error(`Promise.allSettled error: ${error.message}`);
|
|
684
|
+
reject(error);
|
|
685
|
+
});
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// Execute Android commands (uses device UDID instead of name)
|
|
690
|
+
function executeAndroidDevices(scriptPath, devices, command, wsClient) {
|
|
691
|
+
return new Promise((resolve, reject) => {
|
|
692
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
693
|
+
|
|
694
|
+
console.log(`Script: ${path.basename(scriptPath)}`);
|
|
695
|
+
console.log(`Devices: [${devices.map(d => d.name).join(', ')}]`);
|
|
696
|
+
console.log(`Command: "${command}"`);
|
|
697
|
+
|
|
698
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
699
|
+
|
|
700
|
+
// Execute command on each device in parallel
|
|
701
|
+
const devicePromises = devices.map((device, index) => {
|
|
702
|
+
console.log(`[${index + 1}/${devices.length}] Creating execution promise for: ${device.name} (${device.udid})`);
|
|
703
|
+
|
|
704
|
+
return new Promise((resolveDevice, rejectDevice) => {
|
|
705
|
+
// Android script expects: <device_serial> <command> [args...]
|
|
706
|
+
// Use UDID (which is the serial for Android)
|
|
707
|
+
const args = [device.udid, ...command.split(' ')];
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
const child = spawn(scriptPath, args, {
|
|
711
|
+
cwd: path.dirname(scriptPath)
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
let output = '';
|
|
716
|
+
let error = '';
|
|
717
|
+
|
|
718
|
+
child.stdout.on('data', (data) => {
|
|
719
|
+
const text = data.toString();
|
|
720
|
+
output += text;
|
|
721
|
+
console.log(`[${device.name}] STDOUT: ${text.trim()}`);
|
|
722
|
+
if (wsClient) {
|
|
723
|
+
wsClient.send(JSON.stringify({
|
|
724
|
+
type: 'output',
|
|
725
|
+
device: device.name,
|
|
726
|
+
data: text
|
|
727
|
+
}));
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
child.stderr.on('data', (data) => {
|
|
732
|
+
const text = data.toString();
|
|
733
|
+
error += text;
|
|
734
|
+
console.log(`[${device.name}] STDERR: ${text.trim()}`);
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
child.on('close', (code) => {
|
|
738
|
+
|
|
739
|
+
if (code === 0) {
|
|
740
|
+
resolveDevice({ success: true, output, device: device.name });
|
|
741
|
+
} else {
|
|
742
|
+
resolveDevice({ success: false, error: error || output, device: device.name });
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
child.on('error', (err) => {
|
|
747
|
+
console.error(`[${device.name}] Process error:`, err);
|
|
748
|
+
resolveDevice({ success: false, error: err.message, device: device.name });
|
|
749
|
+
});
|
|
750
|
+
});
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
Promise.allSettled(devicePromises)
|
|
754
|
+
.then(results => {
|
|
755
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
756
|
+
|
|
757
|
+
const successCount = results.filter(r => r.status === 'fulfilled' && r.value.success).length;
|
|
758
|
+
const failCount = results.length - successCount;
|
|
759
|
+
|
|
760
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
761
|
+
|
|
762
|
+
resolve({ success: true, results });
|
|
763
|
+
})
|
|
764
|
+
.catch(error => {
|
|
765
|
+
console.error('Execution error:', error);
|
|
766
|
+
reject(error);
|
|
767
|
+
});
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// AI-powered command conversion (supports multiple providers)
|
|
772
|
+
async function convertNaturalLanguageToCommand(text, devices, provider = null) {
|
|
773
|
+
// Determine platforms from devices
|
|
774
|
+
const deviceObjs = connectedDevices.filter(d => devices.includes(d.name));
|
|
775
|
+
|
|
776
|
+
if (deviceObjs.length === 0) {
|
|
777
|
+
// No devices found, try with null platform
|
|
778
|
+
return await aiManager.convertCommand(text, null, provider);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// Group devices by platform
|
|
782
|
+
const platforms = [...new Set(deviceObjs.map(d => d.platform))];
|
|
783
|
+
|
|
784
|
+
console.log(`AI converting for ${deviceObjs.length} device(s) across ${platforms.length} platform(s): ${platforms.join(', ')}`);
|
|
785
|
+
|
|
786
|
+
// For multi-platform, use 'both' to get generic app names
|
|
787
|
+
// The executeCommand function will resolve platform-specific package IDs
|
|
788
|
+
const platform = platforms.length === 1 ? platforms[0] : 'both';
|
|
789
|
+
|
|
790
|
+
console.log(`AI using platform mode: ${platform}`);
|
|
791
|
+
return await aiManager.convertCommand(text, platform, provider);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// Execute commands sequentially with WAIT support
|
|
795
|
+
async function executeCommandsSequentially(devices, commandsText, wsClient) {
|
|
796
|
+
const lines = commandsText.split('\n').map(line => line.trim()).filter(line => line);
|
|
797
|
+
|
|
798
|
+
console.log(`\n${'~'.repeat(60)}`);
|
|
799
|
+
|
|
800
|
+
console.log(`Total commands: ${lines.length}`);
|
|
801
|
+
console.log(`Commands:`, lines);
|
|
802
|
+
console.log(`${'~'.repeat(60)}\n`);
|
|
803
|
+
|
|
804
|
+
const results = [];
|
|
805
|
+
|
|
806
|
+
for (let i = 0; i < lines.length; i++) {
|
|
807
|
+
const line = lines[i];
|
|
808
|
+
|
|
809
|
+
// Skip comments
|
|
810
|
+
if (line.startsWith('#')) {
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// Check if it's a WAIT command
|
|
815
|
+
if (line.startsWith('WAIT ')) {
|
|
816
|
+
const waitTime = parseInt(line.replace('WAIT ', ''));
|
|
817
|
+
console.log(`ā³ Waiting ${waitTime}ms before next command...`);
|
|
818
|
+
|
|
819
|
+
if (wsClient) {
|
|
820
|
+
wsClient.send(JSON.stringify({
|
|
821
|
+
type: 'command_output',
|
|
822
|
+
data: `ā³ Waiting ${waitTime}ms...\n`,
|
|
823
|
+
devices: devices
|
|
824
|
+
}));
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
828
|
+
results.push({ command: line, success: true, output: `Waited ${waitTime}ms` });
|
|
829
|
+
continue;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// Execute the command on ALL devices simultaneously
|
|
833
|
+
console.log(`\nā¶ļø Executing command ${i + 1}/${lines.length}: "${line}"`);
|
|
834
|
+
|
|
835
|
+
if (wsClient) {
|
|
836
|
+
wsClient.send(JSON.stringify({
|
|
837
|
+
type: 'command_output',
|
|
838
|
+
data: `ā¶ļø [${i + 1}/${lines.length}] ${line}\n`,
|
|
839
|
+
devices: devices
|
|
840
|
+
}));
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
try {
|
|
844
|
+
const result = await executeCommand(devices, line, wsClient);
|
|
845
|
+
results.push({ command: line, success: true, result });
|
|
846
|
+
console.log(`ā
Command ${i + 1} completed successfully`);
|
|
847
|
+
} catch (error) {
|
|
848
|
+
console.error(`ā Command ${i + 1} failed:`, error.message);
|
|
849
|
+
results.push({ command: line, success: false, error: error.message });
|
|
850
|
+
|
|
851
|
+
if (wsClient) {
|
|
852
|
+
wsClient.send(JSON.stringify({
|
|
853
|
+
type: 'command_output',
|
|
854
|
+
data: `ā Error: ${error.message}\n`,
|
|
855
|
+
devices: devices
|
|
856
|
+
}));
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
console.log(`\n${'~'.repeat(60)}`);
|
|
862
|
+
|
|
863
|
+
console.log(`Total: ${results.length}, Success: ${results.filter(r => r.success).length}, Failed: ${results.filter(r => !r.success).length}`);
|
|
864
|
+
console.log(`${'~'.repeat(60)}\n`);
|
|
865
|
+
|
|
866
|
+
return {
|
|
867
|
+
success: true,
|
|
868
|
+
results,
|
|
869
|
+
summary: `Executed ${results.length} commands`
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// Create WDA session for a device
|
|
874
|
+
async function createWDASession(host, deviceName) {
|
|
875
|
+
return new Promise(async (resolve) => {
|
|
876
|
+
const sessionFile = '/tmp/ios_multi_sessions';
|
|
877
|
+
|
|
878
|
+
// First, check if session already exists for this device
|
|
879
|
+
try {
|
|
880
|
+
const existingContent = await fs.readFile(sessionFile, 'utf-8').catch(() => '');
|
|
881
|
+
const lines = existingContent.split('\n').filter(line => line.trim());
|
|
882
|
+
|
|
883
|
+
for (const line of lines) {
|
|
884
|
+
const [name, sessionId] = line.split(':');
|
|
885
|
+
if (name === deviceName && sessionId) {
|
|
886
|
+
// Session already exists, verify it's still valid
|
|
887
|
+
const port = host === 'localhost' ? 8100 : 8100;
|
|
888
|
+
const verifyUrl = `http://${host}:${port}/session/${sessionId}`;
|
|
889
|
+
|
|
890
|
+
const verifyProcess = spawn('curl', ['-s', '-X', 'GET', verifyUrl]);
|
|
891
|
+
let verifyOutput = '';
|
|
892
|
+
|
|
893
|
+
verifyProcess.stdout.on('data', (data) => {
|
|
894
|
+
verifyOutput += data.toString();
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
verifyProcess.on('close', (code) => {
|
|
898
|
+
if (code === 0 && verifyOutput && !verifyOutput.includes('invalid session id')) {
|
|
899
|
+
console.log(`ā
Existing valid session found: ${sessionId}`);
|
|
900
|
+
return resolve({ success: true, sessionId, existing: true });
|
|
901
|
+
} else {
|
|
902
|
+
// Session is invalid, create a new one
|
|
903
|
+
createNewSession(host, deviceName, sessionFile, resolve);
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
} catch (e) {
|
|
911
|
+
// File doesn't exist or error reading, create new session
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// No existing session, create a new one
|
|
915
|
+
createNewSession(host, deviceName, sessionFile, resolve);
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function createNewSession(host, deviceName, sessionFile, resolve) {
|
|
920
|
+
const port = host === 'localhost' ? 8100 : 8100;
|
|
921
|
+
const sessionUrl = `http://${host}:${port}/session`;
|
|
922
|
+
|
|
923
|
+
const curlProcess = spawn('curl', [
|
|
924
|
+
'-s',
|
|
925
|
+
'-X', 'POST',
|
|
926
|
+
sessionUrl,
|
|
927
|
+
'-H', 'Content-Type: application/json',
|
|
928
|
+
'-d', '{"capabilities":{"alwaysMatch":{}}}'
|
|
929
|
+
]);
|
|
930
|
+
|
|
931
|
+
let output = '';
|
|
932
|
+
curlProcess.stdout.on('data', (data) => {
|
|
933
|
+
output += data.toString();
|
|
934
|
+
});
|
|
935
|
+
|
|
936
|
+
curlProcess.on('close', (code) => {
|
|
937
|
+
if (code === 0 && output) {
|
|
938
|
+
try {
|
|
939
|
+
const response = JSON.parse(output);
|
|
940
|
+
const sessionId = response.sessionId || response.value?.sessionId;
|
|
941
|
+
|
|
942
|
+
if (sessionId) {
|
|
943
|
+
// Read existing sessions and update
|
|
944
|
+
fs.readFile(sessionFile, 'utf-8')
|
|
945
|
+
.catch(() => '')
|
|
946
|
+
.then(existingContent => {
|
|
947
|
+
// Remove old session for this device if exists
|
|
948
|
+
const lines = existingContent.split('\n').filter(line => {
|
|
949
|
+
const [name] = line.split(':');
|
|
950
|
+
return line.trim() && name !== deviceName;
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
// Add new session
|
|
954
|
+
lines.push(`${deviceName}:${sessionId}`);
|
|
955
|
+
|
|
956
|
+
// Write back to file
|
|
957
|
+
return fs.writeFile(sessionFile, lines.join('\n') + '\n');
|
|
958
|
+
})
|
|
959
|
+
.then(() => {
|
|
960
|
+
console.log(`ā
New session created and saved: ${sessionId}`);
|
|
961
|
+
resolve({ success: true, sessionId });
|
|
962
|
+
})
|
|
963
|
+
.catch((err) => {
|
|
964
|
+
console.error(`ā Failed to save session for ${deviceName}:`, err);
|
|
965
|
+
resolve({ success: false });
|
|
966
|
+
});
|
|
967
|
+
} else {
|
|
968
|
+
resolve({ success: false });
|
|
969
|
+
}
|
|
970
|
+
} catch (e) {
|
|
971
|
+
console.error('Failed to parse WDA session response:', e);
|
|
972
|
+
resolve({ success: false });
|
|
973
|
+
}
|
|
974
|
+
} else {
|
|
975
|
+
resolve({ success: false });
|
|
976
|
+
}
|
|
977
|
+
});
|
|
978
|
+
|
|
979
|
+
curlProcess.on('error', (err) => {
|
|
980
|
+
console.error('Error creating WDA session:', err);
|
|
981
|
+
resolve({ success: false });
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// Install UIAutomator2 on Android device
|
|
986
|
+
async function installUIAutomator2(deviceUdid, deviceName) {
|
|
987
|
+
return new Promise((resolve) => {
|
|
988
|
+
console.log(`š„ Installing UIAutomator2 on ${deviceName}...`);
|
|
989
|
+
|
|
990
|
+
const { execSync } = require('child_process');
|
|
991
|
+
const os = require('os');
|
|
992
|
+
const path = require('path');
|
|
993
|
+
|
|
994
|
+
try {
|
|
995
|
+
// Try multiple locations for APKs
|
|
996
|
+
const possiblePaths = [
|
|
997
|
+
// Appium installed location
|
|
998
|
+
path.join(os.homedir(), '.appium', 'node_modules', 'appium-uiautomator2-driver', 'node_modules', 'appium-uiautomator2-server', 'apks'),
|
|
999
|
+
// Global npm location
|
|
1000
|
+
execSync('npm root -g', { encoding: 'utf-8' }).trim() + '/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks',
|
|
1001
|
+
// Alternative npm location
|
|
1002
|
+
execSync('npm root -g', { encoding: 'utf-8' }).trim() + '/appium/node_modules/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks',
|
|
1003
|
+
];
|
|
1004
|
+
|
|
1005
|
+
let serverApk = null;
|
|
1006
|
+
let testApk = null;
|
|
1007
|
+
let foundPath = null;
|
|
1008
|
+
|
|
1009
|
+
// Try each path
|
|
1010
|
+
for (const apkPath of possiblePaths) {
|
|
1011
|
+
console.log(`š Checking: ${apkPath}`);
|
|
1012
|
+
|
|
1013
|
+
try {
|
|
1014
|
+
const serverCheck = execSync(`ls "${apkPath}"/appium-uiautomator2-server-v*.apk 2>/dev/null || echo ""`, { encoding: 'utf-8' }).trim();
|
|
1015
|
+
const testCheck = execSync(`ls "${apkPath}"/appium-uiautomator2-server-debug-androidTest.apk 2>/dev/null || echo ""`, { encoding: 'utf-8' }).trim();
|
|
1016
|
+
|
|
1017
|
+
if (serverCheck && testCheck) {
|
|
1018
|
+
serverApk = serverCheck;
|
|
1019
|
+
testApk = testCheck;
|
|
1020
|
+
foundPath = apkPath;
|
|
1021
|
+
console.log(`ā
Found APKs in: ${foundPath}`);
|
|
1022
|
+
break;
|
|
1023
|
+
}
|
|
1024
|
+
} catch (e) {
|
|
1025
|
+
continue;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
if (serverApk && testApk) {
|
|
1030
|
+
console.log(`š¦ Installing server APK: ${serverApk}`);
|
|
1031
|
+
const serverOutput = execSync(`adb -s ${deviceUdid} install -r "${serverApk}" 2>&1`, { encoding: 'utf-8' });
|
|
1032
|
+
console.log(serverOutput);
|
|
1033
|
+
|
|
1034
|
+
console.log(`š¦ Installing test APK: ${testApk}`);
|
|
1035
|
+
const testOutput = execSync(`adb -s ${deviceUdid} install -r "${testApk}" 2>&1`, { encoding: 'utf-8' });
|
|
1036
|
+
console.log(testOutput);
|
|
1037
|
+
|
|
1038
|
+
console.log(`ā
UIAutomator2 installed successfully on ${deviceName}`);
|
|
1039
|
+
resolve({
|
|
1040
|
+
success: true,
|
|
1041
|
+
message: 'UIAutomator2 installed successfully'
|
|
1042
|
+
});
|
|
1043
|
+
} else {
|
|
1044
|
+
console.log(`ā ļø APK files not found in any expected location`);
|
|
1045
|
+
console.log(`Tried paths:`, possiblePaths);
|
|
1046
|
+
|
|
1047
|
+
// Try using appium to install
|
|
1048
|
+
try {
|
|
1049
|
+
console.log(`š Trying to install via Appium...`);
|
|
1050
|
+
const appiumOutput = execSync(`appium driver install uiautomator2 2>&1`, { encoding: 'utf-8' });
|
|
1051
|
+
console.log(appiumOutput);
|
|
1052
|
+
|
|
1053
|
+
resolve({
|
|
1054
|
+
success: false,
|
|
1055
|
+
message: 'APKs not found. Tried to reinstall driver. Please run: appium driver install uiautomator2'
|
|
1056
|
+
});
|
|
1057
|
+
} catch (appiumError) {
|
|
1058
|
+
resolve({
|
|
1059
|
+
success: false,
|
|
1060
|
+
message: 'UIAutomator2 APKs not found. Please run: appium driver install uiautomator2'
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
} catch (error) {
|
|
1065
|
+
console.error(`ā Failed to install UIAutomator2: ${error.message}`);
|
|
1066
|
+
resolve({
|
|
1067
|
+
success: false,
|
|
1068
|
+
message: `Failed to install UIAutomator2: ${error.message}`
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// Connect to device - starts WDA if needed
|
|
1075
|
+
async function connectToDevice(device) {
|
|
1076
|
+
return new Promise(async (resolve, reject) => {
|
|
1077
|
+
const { name, udid, type, ip, platform } = device;
|
|
1078
|
+
|
|
1079
|
+
console.log(`Connecting to ${name} (${type}, platform: ${platform})...`);
|
|
1080
|
+
|
|
1081
|
+
// Handle Android devices differently
|
|
1082
|
+
if (platform === 'android') {
|
|
1083
|
+
console.log(`š± Android device detected: ${name}`);
|
|
1084
|
+
|
|
1085
|
+
// Check if device is connected via adb
|
|
1086
|
+
const checkAdb = spawn('adb', ['devices']);
|
|
1087
|
+
let output = '';
|
|
1088
|
+
|
|
1089
|
+
checkAdb.stdout.on('data', (data) => {
|
|
1090
|
+
output += data.toString();
|
|
1091
|
+
});
|
|
1092
|
+
|
|
1093
|
+
checkAdb.on('close', async (code) => {
|
|
1094
|
+
const deviceConnected = output.includes(udid.replace(':5555', '')) || output.includes(udid);
|
|
1095
|
+
|
|
1096
|
+
if (deviceConnected) {
|
|
1097
|
+
console.log(`ā
Android device ${name} is connected via ADB`);
|
|
1098
|
+
|
|
1099
|
+
// Don't set status to 'online' yet - wait for UIAutomator2 confirmation
|
|
1100
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1101
|
+
if (deviceIndex !== -1) {
|
|
1102
|
+
connectedDevices[deviceIndex].status = 'connecting';
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
// Broadcast connecting status
|
|
1106
|
+
wss.clients.forEach(client => {
|
|
1107
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1108
|
+
client.send(JSON.stringify({
|
|
1109
|
+
type: 'devices_updated',
|
|
1110
|
+
devices: connectedDevices
|
|
1111
|
+
}));
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
// Always ensure UIAutomator2 is installed and ready
|
|
1116
|
+
console.log(`š¦ Ensuring UIAutomator2 is installed on ${name}...`);
|
|
1117
|
+
|
|
1118
|
+
// Check if already installed
|
|
1119
|
+
const checkUiAutomator = spawn('adb', ['-s', udid, 'shell', 'pm', 'list', 'packages', 'io.appium.uiautomator2']);
|
|
1120
|
+
let uiautomatorOutput = '';
|
|
1121
|
+
|
|
1122
|
+
checkUiAutomator.stdout.on('data', (data) => {
|
|
1123
|
+
uiautomatorOutput += data.toString();
|
|
1124
|
+
});
|
|
1125
|
+
|
|
1126
|
+
checkUiAutomator.on('close', async () => {
|
|
1127
|
+
const isInstalled = uiautomatorOutput.includes('io.appium.uiautomator2');
|
|
1128
|
+
|
|
1129
|
+
if (!isInstalled) {
|
|
1130
|
+
console.log(`š„ UIAutomator2 not found on ${name}, installing...`);
|
|
1131
|
+
// Install UIAutomator2
|
|
1132
|
+
const installResult = await installUIAutomator2(udid, name);
|
|
1133
|
+
|
|
1134
|
+
if (!installResult.success) {
|
|
1135
|
+
console.log(`ā ļø UIAutomator2 installation failed on ${name}`);
|
|
1136
|
+
resolve({
|
|
1137
|
+
success: true,
|
|
1138
|
+
message: `Connected to ${name} - ADB Ready ā
`
|
|
1139
|
+
});
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
} else {
|
|
1143
|
+
console.log(`ā
UIAutomator2 already installed on ${name}`);
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// Check if session already exists for this device
|
|
1147
|
+
const existingSession = androidSessions.get(udid);
|
|
1148
|
+
if (existingSession) {
|
|
1149
|
+
console.log(`ā»ļø Reusing existing UIAutomator2 session on ${name} (port: ${existingSession.port})`);
|
|
1150
|
+
|
|
1151
|
+
// Verify session is still valid
|
|
1152
|
+
try {
|
|
1153
|
+
const axios = require('axios');
|
|
1154
|
+
await axios.get(`http://localhost:${existingSession.port}/wd/hub/status`);
|
|
1155
|
+
console.log(`ā
Session verified and working on ${name}`);
|
|
1156
|
+
|
|
1157
|
+
// Set status to 'online'
|
|
1158
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1159
|
+
if (deviceIndex !== -1) {
|
|
1160
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1161
|
+
|
|
1162
|
+
// Broadcast updated status
|
|
1163
|
+
wss.clients.forEach(client => {
|
|
1164
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1165
|
+
client.send(JSON.stringify({
|
|
1166
|
+
type: 'devices_updated',
|
|
1167
|
+
devices: connectedDevices
|
|
1168
|
+
}));
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
resolve({
|
|
1174
|
+
success: true,
|
|
1175
|
+
message: `Connected to ${name} - UIAutomator2 Ready ā
`
|
|
1176
|
+
});
|
|
1177
|
+
return;
|
|
1178
|
+
} catch (err) {
|
|
1179
|
+
console.log(`ā ļø Existing session invalid, creating new one for ${name}`);
|
|
1180
|
+
androidSessions.delete(udid);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
// Start new UIAutomator2 session
|
|
1185
|
+
console.log(`š Starting new UIAutomator2 session on ${name}...`);
|
|
1186
|
+
const sessionResult = await startUIAutomator2Session(udid, name);
|
|
1187
|
+
|
|
1188
|
+
if (sessionResult.success) {
|
|
1189
|
+
// Set status to 'online' only after UIAutomator2 is ready
|
|
1190
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1191
|
+
if (deviceIndex !== -1) {
|
|
1192
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1193
|
+
|
|
1194
|
+
// Broadcast updated status
|
|
1195
|
+
wss.clients.forEach(client => {
|
|
1196
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1197
|
+
client.send(JSON.stringify({
|
|
1198
|
+
type: 'devices_updated',
|
|
1199
|
+
devices: connectedDevices
|
|
1200
|
+
}));
|
|
1201
|
+
}
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
resolve({
|
|
1206
|
+
success: true,
|
|
1207
|
+
message: `Connected to ${name} - UIAutomator2 Ready ā
`
|
|
1208
|
+
});
|
|
1209
|
+
} else {
|
|
1210
|
+
resolve({
|
|
1211
|
+
success: true,
|
|
1212
|
+
message: `Connected to ${name} - ADB Ready ā
`
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
});
|
|
1216
|
+
} else {
|
|
1217
|
+
console.log(`ā Android device ${name} not found in ADB`);
|
|
1218
|
+
|
|
1219
|
+
// If wireless, try to connect via adb
|
|
1220
|
+
if (type === 'wireless' && ip) {
|
|
1221
|
+
console.log(`š” Attempting to connect to ${name} wirelessly at ${ip}:5555...`);
|
|
1222
|
+
const adbConnect = spawn('adb', ['connect', `${ip}:5555`]);
|
|
1223
|
+
|
|
1224
|
+
adbConnect.on('close', async (code) => {
|
|
1225
|
+
if (code === 0) {
|
|
1226
|
+
console.log(`ā
Connected to ${name} wirelessly`);
|
|
1227
|
+
|
|
1228
|
+
// Don't set status yet - wait for UIAutomator2
|
|
1229
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1230
|
+
if (deviceIndex !== -1) {
|
|
1231
|
+
connectedDevices[deviceIndex].status = 'connecting';
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// Always ensure UIAutomator2 is installed
|
|
1235
|
+
console.log(`š¦ Ensuring UIAutomator2 is installed on ${name}...`);
|
|
1236
|
+
|
|
1237
|
+
// Check if already installed
|
|
1238
|
+
const checkUiAutomator = spawn('adb', ['-s', `${ip}:5555`, 'shell', 'pm', 'list', 'packages', 'io.appium.uiautomator2']);
|
|
1239
|
+
let uiautomatorOutput = '';
|
|
1240
|
+
|
|
1241
|
+
checkUiAutomator.stdout.on('data', (data) => {
|
|
1242
|
+
uiautomatorOutput += data.toString();
|
|
1243
|
+
});
|
|
1244
|
+
|
|
1245
|
+
checkUiAutomator.on('close', async () => {
|
|
1246
|
+
const isInstalled = uiautomatorOutput.includes('io.appium.uiautomator2');
|
|
1247
|
+
|
|
1248
|
+
if (!isInstalled) {
|
|
1249
|
+
console.log(`š„ UIAutomator2 not found on ${name}, installing...`);
|
|
1250
|
+
const installResult = await installUIAutomator2(`${ip}:5555`, name);
|
|
1251
|
+
if (!installResult.success) {
|
|
1252
|
+
console.log(`ā ļø UIAutomator2 installation failed on ${name}`);
|
|
1253
|
+
}
|
|
1254
|
+
} else {
|
|
1255
|
+
console.log(`ā
UIAutomator2 already installed on ${name}`);
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
// Check if session already exists for this device
|
|
1259
|
+
const existingSession = androidSessions.get(`${ip}:5555`);
|
|
1260
|
+
if (existingSession) {
|
|
1261
|
+
console.log(`ā»ļø Reusing existing UIAutomator2 session on ${name} (port: ${existingSession.port})`);
|
|
1262
|
+
|
|
1263
|
+
// Verify session is still valid
|
|
1264
|
+
try {
|
|
1265
|
+
const axios = require('axios');
|
|
1266
|
+
await axios.get(`http://localhost:${existingSession.port}/wd/hub/status`);
|
|
1267
|
+
console.log(`ā
Session verified and working on ${name}`);
|
|
1268
|
+
|
|
1269
|
+
// Set status to 'online'
|
|
1270
|
+
if (deviceIndex !== -1) {
|
|
1271
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1272
|
+
|
|
1273
|
+
// Broadcast updated status
|
|
1274
|
+
wss.clients.forEach(client => {
|
|
1275
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1276
|
+
client.send(JSON.stringify({
|
|
1277
|
+
type: 'devices_updated',
|
|
1278
|
+
devices: connectedDevices
|
|
1279
|
+
}));
|
|
1280
|
+
}
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
resolve({
|
|
1285
|
+
success: true,
|
|
1286
|
+
message: `Connected to ${name} - UIAutomator2 Ready ā
`
|
|
1287
|
+
});
|
|
1288
|
+
return;
|
|
1289
|
+
} catch (err) {
|
|
1290
|
+
console.log(`ā ļø Existing session invalid, creating new one for ${name}`);
|
|
1291
|
+
androidSessions.delete(`${ip}:5555`);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
// Start new UIAutomator2 session
|
|
1296
|
+
console.log(`š Starting new UIAutomator2 session on ${name}...`);
|
|
1297
|
+
const sessionResult = await startUIAutomator2Session(`${ip}:5555`, name);
|
|
1298
|
+
|
|
1299
|
+
let message = '';
|
|
1300
|
+
if (sessionResult.success) {
|
|
1301
|
+
// Now set status to 'online' after UIAutomator2 is ready
|
|
1302
|
+
if (deviceIndex !== -1) {
|
|
1303
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1304
|
+
|
|
1305
|
+
// Broadcast updated status
|
|
1306
|
+
wss.clients.forEach(client => {
|
|
1307
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1308
|
+
client.send(JSON.stringify({
|
|
1309
|
+
type: 'devices_updated',
|
|
1310
|
+
devices: connectedDevices
|
|
1311
|
+
}));
|
|
1312
|
+
}
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
message = `Connected to ${name} - UIAutomator2 Ready ā
`;
|
|
1317
|
+
} else {
|
|
1318
|
+
message = `Connected to ${name} - ADB Ready ā
`;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
resolve({
|
|
1322
|
+
success: true,
|
|
1323
|
+
message: message
|
|
1324
|
+
});
|
|
1325
|
+
});
|
|
1326
|
+
} else {
|
|
1327
|
+
reject({
|
|
1328
|
+
success: false,
|
|
1329
|
+
message: `Failed to connect to ${name}. Make sure USB debugging is enabled and device is on the same network.`
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
});
|
|
1333
|
+
} else {
|
|
1334
|
+
reject({
|
|
1335
|
+
success: false,
|
|
1336
|
+
message: `Android device ${name} not connected. Please connect via USB or enable wireless debugging.`
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
});
|
|
1341
|
+
|
|
1342
|
+
checkAdb.on('error', (err) => {
|
|
1343
|
+
console.error(`ā ADB error: ${err.message}`);
|
|
1344
|
+
reject({
|
|
1345
|
+
success: false,
|
|
1346
|
+
message: `ADB not available. Please install Android SDK Platform-Tools.`
|
|
1347
|
+
});
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1350
|
+
return; // Exit early for Android devices
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
// iOS device handling continues below
|
|
1354
|
+
if (type === 'usb') {
|
|
1355
|
+
// For USB devices, check if WDA is already running
|
|
1356
|
+
const checkWDA = spawn('curl', [
|
|
1357
|
+
'-s',
|
|
1358
|
+
'--connect-timeout', '2',
|
|
1359
|
+
'http://localhost:8100/status'
|
|
1360
|
+
]);
|
|
1361
|
+
|
|
1362
|
+
let output = '';
|
|
1363
|
+
checkWDA.stdout.on('data', (data) => {
|
|
1364
|
+
output += data.toString();
|
|
1365
|
+
});
|
|
1366
|
+
|
|
1367
|
+
checkWDA.on('error', (err) => {
|
|
1368
|
+
console.error(`ā Error checking WDA: ${err.message}`);
|
|
1369
|
+
reject({ success: false, message: `Failed to check WDA status: ${err.message}` });
|
|
1370
|
+
});
|
|
1371
|
+
|
|
1372
|
+
checkWDA.on('close', async (code) => {
|
|
1373
|
+
if (output.includes('"state"')) {
|
|
1374
|
+
console.log(`ā
WDA already running for ${name}`);
|
|
1375
|
+
|
|
1376
|
+
// Create WDA session if not exists
|
|
1377
|
+
console.log(`š± Creating WDA session for ${name}...`);
|
|
1378
|
+
const sessionResult = await createWDASession('localhost', name);
|
|
1379
|
+
|
|
1380
|
+
if (sessionResult.success) {
|
|
1381
|
+
console.log(`ā
Session created: ${sessionResult.sessionId}`);
|
|
1382
|
+
} else {
|
|
1383
|
+
console.log(`ā ļø Session creation failed, will be created on first command`);
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
// Update status to online
|
|
1387
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1388
|
+
if (deviceIndex !== -1) {
|
|
1389
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
// Broadcast updated device list
|
|
1393
|
+
wss.clients.forEach(client => {
|
|
1394
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1395
|
+
client.send(JSON.stringify({
|
|
1396
|
+
type: 'devices_updated',
|
|
1397
|
+
devices: connectedDevices
|
|
1398
|
+
}));
|
|
1399
|
+
}
|
|
1400
|
+
});
|
|
1401
|
+
|
|
1402
|
+
resolve({ success: true, message: `Connected to ${name} - WDA Ready ā
` });
|
|
1403
|
+
} else {
|
|
1404
|
+
console.log(`š Starting WDA for ${name} (UDID: ${udid})...`);
|
|
1405
|
+
|
|
1406
|
+
// Start WDA using xcodebuild
|
|
1407
|
+
// First, check if we have WebDriverAgent path
|
|
1408
|
+
const wdaPath = process.env.WDA_PATH || path.join(process.env.HOME, 'Downloads/WebDriverAgent-10.2.1');
|
|
1409
|
+
|
|
1410
|
+
console.log(`š WDA Path: ${wdaPath}`);
|
|
1411
|
+
console.log(`š± Device UDID: ${udid}`);
|
|
1412
|
+
|
|
1413
|
+
// Start xcodebuild in background with piped output for debugging
|
|
1414
|
+
const wdaProcess = spawn('xcodebuild', [
|
|
1415
|
+
'test',
|
|
1416
|
+
'-project', path.join(wdaPath, 'WebDriverAgent.xcodeproj'),
|
|
1417
|
+
'-scheme', 'WebDriverAgentRunner',
|
|
1418
|
+
'-destination', `id=${udid}`,
|
|
1419
|
+
'IPHONEOS_DEPLOYMENT_TARGET=14.0'
|
|
1420
|
+
], {
|
|
1421
|
+
cwd: wdaPath,
|
|
1422
|
+
detached: true,
|
|
1423
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
1424
|
+
});
|
|
1425
|
+
|
|
1426
|
+
// Log output for debugging
|
|
1427
|
+
wdaProcess.stdout.on('data', (data) => {
|
|
1428
|
+
const output = data.toString();
|
|
1429
|
+
if (output.includes('ServerURLHere') || output.includes('WebDriverAgent')) {
|
|
1430
|
+
console.log(`š± WDA: ${output.trim()}`);
|
|
1431
|
+
}
|
|
1432
|
+
});
|
|
1433
|
+
|
|
1434
|
+
wdaProcess.stderr.on('data', (data) => {
|
|
1435
|
+
const error = data.toString();
|
|
1436
|
+
if (!error.includes('note:') && !error.includes('warning:')) {
|
|
1437
|
+
console.error(`ā ļø WDA Error: ${error.trim()}`);
|
|
1438
|
+
}
|
|
1439
|
+
});
|
|
1440
|
+
|
|
1441
|
+
wdaProcess.on('error', (err) => {
|
|
1442
|
+
console.error(`ā Failed to start xcodebuild: ${err.message}`);
|
|
1443
|
+
});
|
|
1444
|
+
|
|
1445
|
+
wdaProcess.unref();
|
|
1446
|
+
|
|
1447
|
+
// Also start iproxy to forward port
|
|
1448
|
+
console.log(`š Starting iproxy for port forwarding...`);
|
|
1449
|
+
const iproxyProcess = spawn('iproxy', ['8100', '8100'], {
|
|
1450
|
+
detached: true,
|
|
1451
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
1452
|
+
});
|
|
1453
|
+
|
|
1454
|
+
iproxyProcess.stdout.on('data', (data) => {
|
|
1455
|
+
console.log(`š iproxy: ${data.toString().trim()}`);
|
|
1456
|
+
});
|
|
1457
|
+
|
|
1458
|
+
iproxyProcess.on('error', (err) => {
|
|
1459
|
+
console.error(`ā Failed to start iproxy: ${err.message}`);
|
|
1460
|
+
console.error(` Make sure libimobiledevice is installed: brew install libimobiledevice`);
|
|
1461
|
+
});
|
|
1462
|
+
|
|
1463
|
+
iproxyProcess.unref();
|
|
1464
|
+
|
|
1465
|
+
// Track WDA processes for cleanup on disconnect
|
|
1466
|
+
wdaProcesses.set(name, {
|
|
1467
|
+
xcodebuild: wdaProcess.pid,
|
|
1468
|
+
iproxy: iproxyProcess.pid
|
|
1469
|
+
});
|
|
1470
|
+
|
|
1471
|
+
console.log(`ā
WDA starting for ${name}. Process ID: ${wdaProcess.pid}`);
|
|
1472
|
+
|
|
1473
|
+
// Wait a bit for WDA to start, then verify
|
|
1474
|
+
setTimeout(() => {
|
|
1475
|
+
const verifyWDA = spawn('curl', [
|
|
1476
|
+
'-s',
|
|
1477
|
+
'--connect-timeout', '5',
|
|
1478
|
+
'http://localhost:8100/status'
|
|
1479
|
+
]);
|
|
1480
|
+
|
|
1481
|
+
let verifyOutput = '';
|
|
1482
|
+
verifyWDA.stdout.on('data', (data) => {
|
|
1483
|
+
verifyOutput += data.toString();
|
|
1484
|
+
});
|
|
1485
|
+
|
|
1486
|
+
verifyWDA.on('close', async () => {
|
|
1487
|
+
if (verifyOutput.includes('"state"')) {
|
|
1488
|
+
console.log(`ā
WDA successfully started for ${name}`);
|
|
1489
|
+
|
|
1490
|
+
// Create WDA session for USB device
|
|
1491
|
+
console.log(`š± Creating WDA session for ${name}...`);
|
|
1492
|
+
const sessionResult = await createWDASession('localhost', name);
|
|
1493
|
+
|
|
1494
|
+
if (sessionResult.success) {
|
|
1495
|
+
console.log(`ā
Session created: ${sessionResult.sessionId}`);
|
|
1496
|
+
} else {
|
|
1497
|
+
console.log(`ā ļø Session creation failed, will be created on first command`);
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
// Update device status to online in connectedDevices
|
|
1501
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1502
|
+
if (deviceIndex !== -1) {
|
|
1503
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
// Broadcast updated device list and connection status to all WebSocket clients
|
|
1507
|
+
wss.clients.forEach(client => {
|
|
1508
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1509
|
+
client.send(JSON.stringify({
|
|
1510
|
+
type: 'devices_updated',
|
|
1511
|
+
devices: connectedDevices
|
|
1512
|
+
}));
|
|
1513
|
+
// Send connection complete message
|
|
1514
|
+
client.send(JSON.stringify({
|
|
1515
|
+
type: 'command_output',
|
|
1516
|
+
output: `ā
${name} connected - WDA Ready!\n${'ā'.repeat(50)}\n`,
|
|
1517
|
+
device: name
|
|
1518
|
+
}));
|
|
1519
|
+
}
|
|
1520
|
+
});
|
|
1521
|
+
} else {
|
|
1522
|
+
console.log(`ā ļø WDA still starting for ${name}...`);
|
|
1523
|
+
}
|
|
1524
|
+
});
|
|
1525
|
+
}, 8000); // Wait 8 seconds for WDA to start
|
|
1526
|
+
|
|
1527
|
+
// Return immediately with starting status
|
|
1528
|
+
resolve({
|
|
1529
|
+
success: true,
|
|
1530
|
+
message: `Connecting to ${name} - Starting WDA...`,
|
|
1531
|
+
wdaStarting: true
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
});
|
|
1535
|
+
|
|
1536
|
+
checkWDA.on('error', () => {
|
|
1537
|
+
console.log(`ā ļø Could not check WDA status, attempting to start...`);
|
|
1538
|
+
resolve({ success: false, message: `Error checking WDA. Please start manually in Xcode.` });
|
|
1539
|
+
});
|
|
1540
|
+
} else {
|
|
1541
|
+
// For wireless devices, check if WDA is reachable
|
|
1542
|
+
const checkWDA = spawn('curl', [
|
|
1543
|
+
'-s',
|
|
1544
|
+
'--connect-timeout', '3',
|
|
1545
|
+
`http://${ip}:8100/status`
|
|
1546
|
+
]);
|
|
1547
|
+
|
|
1548
|
+
let output = '';
|
|
1549
|
+
checkWDA.stdout.on('data', (data) => {
|
|
1550
|
+
output += data.toString();
|
|
1551
|
+
});
|
|
1552
|
+
|
|
1553
|
+
checkWDA.on('close', async () => {
|
|
1554
|
+
if (output.includes('"state"')) {
|
|
1555
|
+
console.log(`ā
WDA reachable for ${name}`);
|
|
1556
|
+
|
|
1557
|
+
// Create WDA session for wireless device
|
|
1558
|
+
console.log(`š± Creating WDA session for ${name}...`);
|
|
1559
|
+
const sessionResult = await createWDASession(ip, name);
|
|
1560
|
+
|
|
1561
|
+
if (sessionResult.success) {
|
|
1562
|
+
console.log(`ā
Session created: ${sessionResult.sessionId}`);
|
|
1563
|
+
} else {
|
|
1564
|
+
console.log(`ā ļø Session creation failed, will be created on first command`);
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
// Update status to online
|
|
1568
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1569
|
+
if (deviceIndex !== -1) {
|
|
1570
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
// Broadcast updated device list
|
|
1574
|
+
wss.clients.forEach(client => {
|
|
1575
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1576
|
+
client.send(JSON.stringify({
|
|
1577
|
+
type: 'devices_updated',
|
|
1578
|
+
devices: connectedDevices
|
|
1579
|
+
}));
|
|
1580
|
+
}
|
|
1581
|
+
});
|
|
1582
|
+
|
|
1583
|
+
resolve({ success: true, message: `Connected to ${name} - WDA Ready ā
` });
|
|
1584
|
+
} else {
|
|
1585
|
+
console.log(`ā WDA not running on ${name}, attempting to start...`);
|
|
1586
|
+
|
|
1587
|
+
// Start WDA wirelessly using xcodebuild
|
|
1588
|
+
const wdaPath = process.env.WDA_PATH || path.join(process.env.HOME, 'Downloads/WebDriverAgent-10.2.1');
|
|
1589
|
+
|
|
1590
|
+
console.log(`š WDA Path: ${wdaPath}`);
|
|
1591
|
+
console.log(`š± Device UDID: ${udid}`);
|
|
1592
|
+
console.log(`š” Device IP: ${ip}`);
|
|
1593
|
+
|
|
1594
|
+
// Start xcodebuild in background for wireless device
|
|
1595
|
+
const wdaProcess = spawn('xcodebuild', [
|
|
1596
|
+
'test',
|
|
1597
|
+
'-project', path.join(wdaPath, 'WebDriverAgent.xcodeproj'),
|
|
1598
|
+
'-scheme', 'WebDriverAgentRunner',
|
|
1599
|
+
'-destination', `id=${udid}`,
|
|
1600
|
+
'IPHONEOS_DEPLOYMENT_TARGET=14.0'
|
|
1601
|
+
], {
|
|
1602
|
+
cwd: wdaPath,
|
|
1603
|
+
detached: true,
|
|
1604
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
1605
|
+
});
|
|
1606
|
+
|
|
1607
|
+
// Log output for debugging
|
|
1608
|
+
wdaProcess.stdout.on('data', (data) => {
|
|
1609
|
+
const output = data.toString();
|
|
1610
|
+
if (output.includes('ServerURLHere') || output.includes('WebDriverAgent')) {
|
|
1611
|
+
console.log(`š± WDA (${name}): ${output.trim()}`);
|
|
1612
|
+
}
|
|
1613
|
+
});
|
|
1614
|
+
|
|
1615
|
+
wdaProcess.stderr.on('data', (data) => {
|
|
1616
|
+
const error = data.toString();
|
|
1617
|
+
if (!error.includes('note:') && !error.includes('warning:')) {
|
|
1618
|
+
console.error(`ā ļø WDA Error (${name}): ${error.trim()}`);
|
|
1619
|
+
}
|
|
1620
|
+
});
|
|
1621
|
+
|
|
1622
|
+
wdaProcess.on('error', (err) => {
|
|
1623
|
+
console.error(`ā Failed to start xcodebuild for ${name}: ${err.message}`);
|
|
1624
|
+
});
|
|
1625
|
+
|
|
1626
|
+
wdaProcess.unref();
|
|
1627
|
+
|
|
1628
|
+
// Track WDA process for cleanup on disconnect
|
|
1629
|
+
wdaProcesses.set(name, {
|
|
1630
|
+
xcodebuild: wdaProcess.pid
|
|
1631
|
+
});
|
|
1632
|
+
|
|
1633
|
+
console.log(`ā
WDA starting for ${name} (wireless). Process ID: ${wdaProcess.pid}`);
|
|
1634
|
+
|
|
1635
|
+
// Wait for WDA to start, then verify
|
|
1636
|
+
setTimeout(() => {
|
|
1637
|
+
const verifyWDA = spawn('curl', [
|
|
1638
|
+
'-s',
|
|
1639
|
+
'--connect-timeout', '5',
|
|
1640
|
+
`http://${ip}:8100/status`
|
|
1641
|
+
]);
|
|
1642
|
+
|
|
1643
|
+
let verifyOutput = '';
|
|
1644
|
+
verifyWDA.stdout.on('data', (data) => {
|
|
1645
|
+
verifyOutput += data.toString();
|
|
1646
|
+
});
|
|
1647
|
+
|
|
1648
|
+
verifyWDA.on('close', async () => {
|
|
1649
|
+
if (verifyOutput.includes('"state"')) {
|
|
1650
|
+
console.log(`ā
WDA successfully started for ${name}`);
|
|
1651
|
+
|
|
1652
|
+
// Create WDA session for wireless device
|
|
1653
|
+
console.log(`š± Creating WDA session for ${name}...`);
|
|
1654
|
+
const sessionResult = await createWDASession(ip, name);
|
|
1655
|
+
|
|
1656
|
+
if (sessionResult.success) {
|
|
1657
|
+
console.log(`ā
Session created: ${sessionResult.sessionId}`);
|
|
1658
|
+
} else {
|
|
1659
|
+
console.log(`ā ļø Session creation failed, will be created on first command`);
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
// Update device status to online
|
|
1663
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1664
|
+
if (deviceIndex !== -1) {
|
|
1665
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
// Broadcast updated device list
|
|
1669
|
+
wss.clients.forEach(client => {
|
|
1670
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1671
|
+
client.send(JSON.stringify({
|
|
1672
|
+
type: 'devices_updated',
|
|
1673
|
+
devices: connectedDevices
|
|
1674
|
+
}));
|
|
1675
|
+
}
|
|
1676
|
+
});
|
|
1677
|
+
|
|
1678
|
+
resolve({
|
|
1679
|
+
success: true,
|
|
1680
|
+
message: `Connected to ${name} via WiFi - WDA Started!`,
|
|
1681
|
+
wdaStarted: true
|
|
1682
|
+
});
|
|
1683
|
+
} else {
|
|
1684
|
+
console.log(`ā ļø WDA starting for ${name}, may take a moment...`);
|
|
1685
|
+
resolve({
|
|
1686
|
+
success: true,
|
|
1687
|
+
message: `WDA is starting for ${name}. Please wait 10-15 seconds...`,
|
|
1688
|
+
wdaStarting: true
|
|
1689
|
+
});
|
|
1690
|
+
}
|
|
1691
|
+
});
|
|
1692
|
+
}, 10000); // Wait 10 seconds for wireless WDA to start
|
|
1693
|
+
}
|
|
1694
|
+
});
|
|
1695
|
+
|
|
1696
|
+
checkWDA.on('error', () => {
|
|
1697
|
+
console.log(`ā ļø Cannot reach ${name} at ${ip}. Check network connection.`);
|
|
1698
|
+
reject({ success: false, message: `Cannot reach ${name} at ${ip}. Check network connection.` });
|
|
1699
|
+
});
|
|
1700
|
+
}
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
// Disconnect from device
|
|
1705
|
+
async function disconnectFromDevice(device) {
|
|
1706
|
+
return new Promise((resolve, reject) => {
|
|
1707
|
+
const { name, connectionType, udid, platform } = device;
|
|
1708
|
+
console.log(`š Disconnecting from ${name} (${connectionType}, platform: ${platform})...`);
|
|
1709
|
+
|
|
1710
|
+
// Handle Android devices
|
|
1711
|
+
if (platform === 'android') {
|
|
1712
|
+
console.log(`š± Android device disconnect: ${name}`);
|
|
1713
|
+
|
|
1714
|
+
// Stop UIAutomator2 session first
|
|
1715
|
+
stopUIAutomator2Session(udid, name).catch(err => {
|
|
1716
|
+
console.error(`Error stopping UIAutomator2 session: ${err.message}`);
|
|
1717
|
+
});
|
|
1718
|
+
|
|
1719
|
+
// For wireless Android devices, disconnect adb
|
|
1720
|
+
if (connectionType === 'wireless') {
|
|
1721
|
+
const adbDisconnect = spawn('adb', ['disconnect', udid]);
|
|
1722
|
+
|
|
1723
|
+
adbDisconnect.on('close', (code) => {
|
|
1724
|
+
console.log(`ā
Disconnected Android device ${name} from ADB`);
|
|
1725
|
+
|
|
1726
|
+
// Update device status
|
|
1727
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1728
|
+
if (deviceIndex !== -1) {
|
|
1729
|
+
connectedDevices[deviceIndex].status = 'offline';
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
// Broadcast update
|
|
1733
|
+
wss.clients.forEach(client => {
|
|
1734
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1735
|
+
client.send(JSON.stringify({
|
|
1736
|
+
type: 'devices_updated',
|
|
1737
|
+
devices: connectedDevices
|
|
1738
|
+
}));
|
|
1739
|
+
}
|
|
1740
|
+
});
|
|
1741
|
+
|
|
1742
|
+
resolve({
|
|
1743
|
+
success: true,
|
|
1744
|
+
message: `Disconnected from ${name} - ADB disconnected`
|
|
1745
|
+
});
|
|
1746
|
+
});
|
|
1747
|
+
} else {
|
|
1748
|
+
// For USB Android devices, just update status
|
|
1749
|
+
|
|
1750
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1751
|
+
if (deviceIndex !== -1) {
|
|
1752
|
+
connectedDevices[deviceIndex].status = 'offline';
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
// Broadcast update
|
|
1756
|
+
wss.clients.forEach(client => {
|
|
1757
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1758
|
+
client.send(JSON.stringify({
|
|
1759
|
+
type: 'devices_updated',
|
|
1760
|
+
devices: connectedDevices
|
|
1761
|
+
}));
|
|
1762
|
+
}
|
|
1763
|
+
});
|
|
1764
|
+
|
|
1765
|
+
resolve({
|
|
1766
|
+
success: true,
|
|
1767
|
+
message: `Disconnected from ${name}`
|
|
1768
|
+
});
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
return; // Exit early for Android
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
// iOS device handling - Find the device in connectedDevices to get its port
|
|
1775
|
+
const deviceInfo = connectedDevices.find(d => d.name === name);
|
|
1776
|
+
const port = deviceInfo?.port;
|
|
1777
|
+
|
|
1778
|
+
// Strategy 1: Kill WDA processes tracked in wdaProcesses Map
|
|
1779
|
+
if (wdaProcesses.has(name)) {
|
|
1780
|
+
const processes = wdaProcesses.get(name);
|
|
1781
|
+
|
|
1782
|
+
try {
|
|
1783
|
+
if (processes.xcodebuild) {
|
|
1784
|
+
try {
|
|
1785
|
+
process.kill(processes.xcodebuild, 'SIGTERM');
|
|
1786
|
+
console.log(`ā
Killed xcodebuild for ${name} (PID: ${processes.xcodebuild})`);
|
|
1787
|
+
} catch (e) {
|
|
1788
|
+
console.log(`ā ļø xcodebuild process ${processes.xcodebuild} already stopped`);
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
if (processes.iproxy) {
|
|
1793
|
+
try {
|
|
1794
|
+
process.kill(processes.iproxy, 'SIGTERM');
|
|
1795
|
+
console.log(`ā
Killed iproxy for ${name} (PID: ${processes.iproxy})`);
|
|
1796
|
+
} catch (e) {
|
|
1797
|
+
console.log(`ā ļø iproxy process ${processes.iproxy} already stopped`);
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
wdaProcesses.delete(name);
|
|
1802
|
+
} catch (error) {
|
|
1803
|
+
console.error(`Error cleaning up tracked processes for ${name}:`, error);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
// Strategy 2: Kill processes by port (works for script-started WDA too)
|
|
1808
|
+
if (port) {
|
|
1809
|
+
console.log(`š Killing processes on port ${port} for ${name}...`);
|
|
1810
|
+
const killPort = spawn('sh', ['-c', `lsof -ti:${port} | xargs kill -9 2>/dev/null || true`]);
|
|
1811
|
+
|
|
1812
|
+
killPort.on('close', () => {
|
|
1813
|
+
console.log(`ā
Cleaned up port ${port} for ${name}`);
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
// Strategy 3: Kill xcodebuild processes for this specific UDID
|
|
1818
|
+
if (udid && connectionType === 'usb') {
|
|
1819
|
+
console.log(`š Killing WDA for UDID ${udid}...`);
|
|
1820
|
+
const killWDA = spawn('sh', ['-c', `pkill -f "xcodebuild.*${udid}" || true`]);
|
|
1821
|
+
|
|
1822
|
+
killWDA.on('close', () => {
|
|
1823
|
+
console.log(`ā
Cleaned up WDA processes for ${name}`);
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
// Strategy 4: For wireless, kill iproxy processes associated with this device's port
|
|
1828
|
+
if (connectionType === 'usb' && port) {
|
|
1829
|
+
const killIproxy = spawn('sh', ['-c', `pkill -f "iproxy.*${port}" || true`]);
|
|
1830
|
+
killIproxy.on('close', () => {
|
|
1831
|
+
console.log(`ā
Cleaned up iproxy for ${name}`);
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
// Wait a moment for all cleanup to complete
|
|
1836
|
+
setTimeout(() => {
|
|
1837
|
+
// Update device status to offline in connectedDevices
|
|
1838
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1839
|
+
if (deviceIndex !== -1) {
|
|
1840
|
+
connectedDevices[deviceIndex].status = 'offline';
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
// Broadcast updated device list to all WebSocket clients
|
|
1844
|
+
wss.clients.forEach(client => {
|
|
1845
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1846
|
+
client.send(JSON.stringify({
|
|
1847
|
+
type: 'devices_updated',
|
|
1848
|
+
devices: connectedDevices
|
|
1849
|
+
}));
|
|
1850
|
+
}
|
|
1851
|
+
});
|
|
1852
|
+
|
|
1853
|
+
console.log(`ā
Successfully disconnected ${name}`);
|
|
1854
|
+
resolve({
|
|
1855
|
+
success: true,
|
|
1856
|
+
message: `Disconnected from ${name} - WDA stopped`
|
|
1857
|
+
});
|
|
1858
|
+
}, 500);
|
|
1859
|
+
});
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
// ============================================
|
|
1863
|
+
// Recording & Replay Functions
|
|
1864
|
+
// ============================================
|
|
1865
|
+
|
|
1866
|
+
// Ensure recordings directory exists
|
|
1867
|
+
async function ensureRecordingsDir() {
|
|
1868
|
+
try {
|
|
1869
|
+
await fs.access(RECORDINGS_DIR);
|
|
1870
|
+
} catch {
|
|
1871
|
+
await fs.mkdir(RECORDINGS_DIR, { recursive: true });
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
// Start recording
|
|
1876
|
+
async function startRecording(name, devices) {
|
|
1877
|
+
await ensureRecordingsDir();
|
|
1878
|
+
|
|
1879
|
+
currentRecording = {
|
|
1880
|
+
name: name || `recording_${Date.now()}`,
|
|
1881
|
+
devices: devices || [],
|
|
1882
|
+
commands: [],
|
|
1883
|
+
startTime: new Date().toISOString()
|
|
1884
|
+
};
|
|
1885
|
+
isRecording = true;
|
|
1886
|
+
|
|
1887
|
+
console.log(`š“ Recording started: ${currentRecording.name}`);
|
|
1888
|
+
return { success: true, recording: currentRecording };
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
// Add command to current recording
|
|
1892
|
+
function recordCommand(devices, command, useAI, convertedCommand) {
|
|
1893
|
+
if (!isRecording || !currentRecording) {
|
|
1894
|
+
return false;
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
currentRecording.commands.push({
|
|
1898
|
+
timestamp: new Date().toISOString(),
|
|
1899
|
+
devices,
|
|
1900
|
+
originalCommand: command,
|
|
1901
|
+
useAI,
|
|
1902
|
+
finalCommand: convertedCommand || command
|
|
1903
|
+
});
|
|
1904
|
+
|
|
1905
|
+
console.log(`š Recorded command: ${command} (${currentRecording.commands.length} total)`);
|
|
1906
|
+
return true;
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1909
|
+
// Stop recording and save
|
|
1910
|
+
async function stopRecording() {
|
|
1911
|
+
if (!isRecording || !currentRecording) {
|
|
1912
|
+
return { success: false, error: 'No active recording' };
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
currentRecording.endTime = new Date().toISOString();
|
|
1916
|
+
|
|
1917
|
+
const filename = `${currentRecording.name}.json`;
|
|
1918
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
1919
|
+
|
|
1920
|
+
await fs.writeFile(filepath, JSON.stringify(currentRecording, null, 2));
|
|
1921
|
+
|
|
1922
|
+
const result = {
|
|
1923
|
+
success: true,
|
|
1924
|
+
recording: currentRecording,
|
|
1925
|
+
filepath: filename
|
|
1926
|
+
};
|
|
1927
|
+
|
|
1928
|
+
console.log(`ā¹ļø Recording stopped: ${currentRecording.name} (${currentRecording.commands.length} commands)`);
|
|
1929
|
+
|
|
1930
|
+
isRecording = false;
|
|
1931
|
+
currentRecording = null;
|
|
1932
|
+
|
|
1933
|
+
return result;
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
// List all recordings
|
|
1937
|
+
async function listRecordings() {
|
|
1938
|
+
await ensureRecordingsDir();
|
|
1939
|
+
|
|
1940
|
+
try {
|
|
1941
|
+
const files = await fs.readdir(RECORDINGS_DIR);
|
|
1942
|
+
const recordings = [];
|
|
1943
|
+
|
|
1944
|
+
for (const file of files) {
|
|
1945
|
+
if (file.endsWith('.json')) {
|
|
1946
|
+
try {
|
|
1947
|
+
const filepath = path.join(RECORDINGS_DIR, file);
|
|
1948
|
+
const content = await fs.readFile(filepath, 'utf-8');
|
|
1949
|
+
const recording = JSON.parse(content);
|
|
1950
|
+
|
|
1951
|
+
// Handle both old format (array of commands) and new format (string)
|
|
1952
|
+
let commandCount = 0;
|
|
1953
|
+
if (Array.isArray(recording.commands)) {
|
|
1954
|
+
commandCount = recording.commands.length;
|
|
1955
|
+
} else if (typeof recording.commands === 'string') {
|
|
1956
|
+
commandCount = recording.commands.split('\n').filter(cmd => cmd.trim()).length;
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
recordings.push({
|
|
1960
|
+
filename: file,
|
|
1961
|
+
name: recording.name || file.replace('.json', ''),
|
|
1962
|
+
devices: recording.devices || [],
|
|
1963
|
+
commandCount: commandCount,
|
|
1964
|
+
startTime: recording.startTime || recording.date,
|
|
1965
|
+
endTime: recording.endTime || recording.date,
|
|
1966
|
+
type: recording.type || 'manual'
|
|
1967
|
+
});
|
|
1968
|
+
} catch (e) {
|
|
1969
|
+
console.error(`Error reading recording ${file}:`, e);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
return recordings;
|
|
1975
|
+
} catch (error) {
|
|
1976
|
+
console.error('Error listing recordings:', error);
|
|
1977
|
+
return [];
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
// Load a recording
|
|
1982
|
+
async function loadRecording(filename) {
|
|
1983
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
1984
|
+
|
|
1985
|
+
try {
|
|
1986
|
+
const content = await fs.readFile(filepath, 'utf-8');
|
|
1987
|
+
return JSON.parse(content);
|
|
1988
|
+
} catch (error) {
|
|
1989
|
+
console.error(`Error loading recording ${filename}:`, error);
|
|
1990
|
+
throw error;
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
// Delete a recording
|
|
1995
|
+
async function deleteRecording(filename) {
|
|
1996
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
1997
|
+
|
|
1998
|
+
try {
|
|
1999
|
+
await fs.unlink(filepath);
|
|
2000
|
+
return { success: true };
|
|
2001
|
+
} catch (error) {
|
|
2002
|
+
console.error(`Error deleting recording ${filename}:`, error);
|
|
2003
|
+
throw error;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
// Replay a recording
|
|
2008
|
+
async function replayRecording(filename, targetDevices, wsClient) {
|
|
2009
|
+
const recording = await loadRecording(filename);
|
|
2010
|
+
|
|
2011
|
+
// Normalize commands to array format
|
|
2012
|
+
let commands = [];
|
|
2013
|
+
if (Array.isArray(recording.commands)) {
|
|
2014
|
+
// Old format: array of command objects
|
|
2015
|
+
commands = recording.commands.map(cmd => cmd.finalCommand || cmd.originalCommand);
|
|
2016
|
+
} else if (typeof recording.commands === 'string') {
|
|
2017
|
+
// New format: string with newlines
|
|
2018
|
+
commands = recording.commands.split('\n').filter(cmd => cmd.trim());
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
const devices = recording.devices && recording.devices.length > 0
|
|
2022
|
+
? recording.devices
|
|
2023
|
+
: targetDevices;
|
|
2024
|
+
|
|
2025
|
+
console.log(`\n${'ā¶'.repeat(60)}`);
|
|
2026
|
+
console.log(`REPLAYING: ${recording.name}`);
|
|
2027
|
+
console.log(`Original devices: ${devices.join(', ')}`);
|
|
2028
|
+
console.log(`Target devices: ${targetDevices.join(', ')}`);
|
|
2029
|
+
console.log(`Commands to replay: ${commands.length}`);
|
|
2030
|
+
console.log(`${'ā¶'.repeat(60)}\n`);
|
|
2031
|
+
|
|
2032
|
+
// Reset abort flag at start
|
|
2033
|
+
replayAborted = false;
|
|
2034
|
+
isReplaying = true;
|
|
2035
|
+
|
|
2036
|
+
// Send initial summary to terminal
|
|
2037
|
+
if (wsClient) {
|
|
2038
|
+
wsClient.send(JSON.stringify({
|
|
2039
|
+
type: 'command_output',
|
|
2040
|
+
data: `š¼ Recording: ${recording.name}\n` +
|
|
2041
|
+
`š± Devices: ${targetDevices.join(', ')}\n` +
|
|
2042
|
+
`š Commands: ${commands.length}\n` +
|
|
2043
|
+
`${'ā'.repeat(50)}\n\n`,
|
|
2044
|
+
devices: targetDevices
|
|
2045
|
+
}));
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
const results = [];
|
|
2049
|
+
|
|
2050
|
+
for (let i = 0; i < commands.length; i++) {
|
|
2051
|
+
// Check if replay was aborted
|
|
2052
|
+
if (replayAborted) {
|
|
2053
|
+
console.log('\nā¹ļø Replay aborted by user\n');
|
|
2054
|
+
if (wsClient) {
|
|
2055
|
+
wsClient.send(JSON.stringify({
|
|
2056
|
+
type: 'command_output',
|
|
2057
|
+
data: '\nā¹ļø Replay stopped by user\n',
|
|
2058
|
+
devices: targetDevices
|
|
2059
|
+
}));
|
|
2060
|
+
}
|
|
2061
|
+
isReplaying = false;
|
|
2062
|
+
throw new Error('Replay aborted by user');
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
const cmd = commands[i];
|
|
2066
|
+
|
|
2067
|
+
console.log(`\nš¬ Replaying command ${i + 1}/${commands.length}`);
|
|
2068
|
+
console.log(` Command: ${cmd}`);
|
|
2069
|
+
|
|
2070
|
+
if (wsClient) {
|
|
2071
|
+
wsClient.send(JSON.stringify({
|
|
2072
|
+
type: 'command_output',
|
|
2073
|
+
data: `š¬ [${i + 1}/${commands.length}] Executing: ${cmd}\n`,
|
|
2074
|
+
devices: targetDevices
|
|
2075
|
+
}));
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
try {
|
|
2079
|
+
// Execute the command
|
|
2080
|
+
const result = await executeCommand(targetDevices, cmd, null); // null to suppress websocket output from executeCommand
|
|
2081
|
+
results.push({ command: cmd, success: true, result });
|
|
2082
|
+
|
|
2083
|
+
if (wsClient) {
|
|
2084
|
+
wsClient.send(JSON.stringify({
|
|
2085
|
+
type: 'command_output',
|
|
2086
|
+
data: `ā
Completed successfully\n\n`,
|
|
2087
|
+
devices: targetDevices
|
|
2088
|
+
}));
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
// Add a small delay between commands
|
|
2092
|
+
if (i < commands.length - 1) {
|
|
2093
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
2094
|
+
}
|
|
2095
|
+
} catch (error) {
|
|
2096
|
+
console.error(`ā Replay command ${i + 1} failed:`, error.message);
|
|
2097
|
+
results.push({ command: cmd, success: false, error: error.message });
|
|
2098
|
+
|
|
2099
|
+
if (wsClient) {
|
|
2100
|
+
wsClient.send(JSON.stringify({
|
|
2101
|
+
type: 'command_output',
|
|
2102
|
+
data: `ā Failed: ${error.message}\n\n`,
|
|
2103
|
+
devices: targetDevices
|
|
2104
|
+
}));
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
isReplaying = false;
|
|
2110
|
+
|
|
2111
|
+
console.log(`\n${'ā¶'.repeat(60)}`);
|
|
2112
|
+
console.log(`REPLAY COMPLETE`);
|
|
2113
|
+
console.log(`Total: ${results.length}, Success: ${results.filter(r => r.success).length}, Failed: ${results.filter(r => !r.success).length}`);
|
|
2114
|
+
console.log(`${'ā¶'.repeat(60)}\n`);
|
|
2115
|
+
|
|
2116
|
+
return {
|
|
2117
|
+
success: true,
|
|
2118
|
+
recording: recording.name,
|
|
2119
|
+
results
|
|
2120
|
+
};
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
// API Routes
|
|
2124
|
+
app.get('/api/devices', async (req, res) => {
|
|
2125
|
+
try {
|
|
2126
|
+
const devices = await discoverDevices();
|
|
2127
|
+
res.json({ success: true, devices });
|
|
2128
|
+
} catch (error) {
|
|
2129
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2130
|
+
}
|
|
2131
|
+
});
|
|
2132
|
+
|
|
2133
|
+
app.post('/api/devices/refresh', async (req, res) => {
|
|
2134
|
+
try {
|
|
2135
|
+
const devices = await discoverDevices();
|
|
2136
|
+
|
|
2137
|
+
// Broadcast to all WebSocket clients
|
|
2138
|
+
wss.clients.forEach(client => {
|
|
2139
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
2140
|
+
client.send(JSON.stringify({
|
|
2141
|
+
type: 'devices_updated',
|
|
2142
|
+
devices
|
|
2143
|
+
}));
|
|
2144
|
+
}
|
|
2145
|
+
});
|
|
2146
|
+
|
|
2147
|
+
res.json({ success: true, devices });
|
|
2148
|
+
} catch (error) {
|
|
2149
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2150
|
+
}
|
|
2151
|
+
});
|
|
2152
|
+
|
|
2153
|
+
app.post('/api/execute', async (req, res) => {
|
|
2154
|
+
try {
|
|
2155
|
+
const { devices, command, useAI, aiProvider } = req.body;
|
|
2156
|
+
|
|
2157
|
+
if (!devices || devices.length === 0) {
|
|
2158
|
+
return res.status(400).json({ success: false, error: 'No devices specified' });
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
let finalCommand = command;
|
|
2162
|
+
if (useAI) {
|
|
2163
|
+
finalCommand = await convertNaturalLanguageToCommand(command, devices, aiProvider);
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
// Check if command has multiple lines (sequential execution)
|
|
2167
|
+
const hasMultipleCommands = finalCommand.includes('\n');
|
|
2168
|
+
|
|
2169
|
+
let result;
|
|
2170
|
+
if (hasMultipleCommands) {
|
|
2171
|
+
|
|
2172
|
+
result = await executeCommandsSequentially(devices, finalCommand, null);
|
|
2173
|
+
} else {
|
|
2174
|
+
result = await executeCommand(devices, finalCommand, null);
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
res.json(result);
|
|
2178
|
+
} catch (error) {
|
|
2179
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2180
|
+
}
|
|
2181
|
+
});
|
|
2182
|
+
|
|
2183
|
+
app.post('/api/convert-command', async (req, res) => {
|
|
2184
|
+
try {
|
|
2185
|
+
const { text, devices, provider } = req.body;
|
|
2186
|
+
const command = await convertNaturalLanguageToCommand(text, devices || [], provider);
|
|
2187
|
+
res.json({ success: true, command });
|
|
2188
|
+
} catch (error) {
|
|
2189
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2190
|
+
}
|
|
2191
|
+
});
|
|
2192
|
+
|
|
2193
|
+
// Connect to device endpoint
|
|
2194
|
+
app.post('/api/devices/connect', async (req, res) => {
|
|
2195
|
+
try {
|
|
2196
|
+
const { device } = req.body;
|
|
2197
|
+
console.log(`š” Connect request received for device:`, device);
|
|
2198
|
+
|
|
2199
|
+
if (!device) {
|
|
2200
|
+
console.error('ā No device provided in request');
|
|
2201
|
+
return res.status(400).json({ success: false, error: 'No device provided' });
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
if (!device.name || !device.udid) {
|
|
2205
|
+
console.error('ā Invalid device object:', device);
|
|
2206
|
+
return res.status(400).json({ success: false, error: 'Invalid device object' });
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
const result = await connectToDevice(device);
|
|
2210
|
+
console.log(`ā
Connect result:`, result);
|
|
2211
|
+
res.json(result);
|
|
2212
|
+
} catch (error) {
|
|
2213
|
+
console.error(`ā Connect error:`, error);
|
|
2214
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2215
|
+
}
|
|
2216
|
+
});
|
|
2217
|
+
|
|
2218
|
+
// Disconnect from device endpoint
|
|
2219
|
+
app.post('/api/devices/disconnect', async (req, res) => {
|
|
2220
|
+
try {
|
|
2221
|
+
const { device } = req.body;
|
|
2222
|
+
const result = await disconnectFromDevice(device);
|
|
2223
|
+
res.json(result);
|
|
2224
|
+
} catch (error) {
|
|
2225
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2226
|
+
}
|
|
2227
|
+
});
|
|
2228
|
+
|
|
2229
|
+
// Disconnect all devices endpoint
|
|
2230
|
+
app.post('/api/devices/disconnect-all', async (req, res) => {
|
|
2231
|
+
try {
|
|
2232
|
+
console.log(`š Disconnecting ALL devices...`);
|
|
2233
|
+
|
|
2234
|
+
// Get all connected devices
|
|
2235
|
+
const devicesToDisconnect = connectedDevices.filter(d => d.status === 'online');
|
|
2236
|
+
|
|
2237
|
+
if (devicesToDisconnect.length === 0) {
|
|
2238
|
+
return res.json({
|
|
2239
|
+
success: true,
|
|
2240
|
+
message: 'No devices to disconnect'
|
|
2241
|
+
});
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
console.log(`š± Disconnecting ${devicesToDisconnect.length} device(s)...`);
|
|
2245
|
+
|
|
2246
|
+
// Disconnect all devices in parallel
|
|
2247
|
+
const disconnectPromises = devicesToDisconnect.map(device => disconnectFromDevice(device));
|
|
2248
|
+
await Promise.all(disconnectPromises);
|
|
2249
|
+
|
|
2250
|
+
console.log(`ā
All devices disconnected`);
|
|
2251
|
+
|
|
2252
|
+
res.json({
|
|
2253
|
+
success: true,
|
|
2254
|
+
message: `Disconnected ${devicesToDisconnect.length} device(s)`,
|
|
2255
|
+
count: devicesToDisconnect.length
|
|
2256
|
+
});
|
|
2257
|
+
} catch (error) {
|
|
2258
|
+
console.error(`ā Error disconnecting all devices:`, error);
|
|
2259
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2260
|
+
}
|
|
2261
|
+
});
|
|
2262
|
+
|
|
2263
|
+
// New endpoints for AI provider management
|
|
2264
|
+
app.get('/api/ai/providers', (req, res) => {
|
|
2265
|
+
try {
|
|
2266
|
+
const providers = aiManager.getAvailableProviders();
|
|
2267
|
+
const current = aiManager.getCurrentProvider();
|
|
2268
|
+
res.json({ success: true, providers, current: current.id });
|
|
2269
|
+
} catch (error) {
|
|
2270
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2271
|
+
}
|
|
2272
|
+
});
|
|
2273
|
+
|
|
2274
|
+
app.post('/api/ai/provider', (req, res) => {
|
|
2275
|
+
try {
|
|
2276
|
+
const { provider } = req.body;
|
|
2277
|
+
const success = aiManager.setProvider(provider);
|
|
2278
|
+
if (success) {
|
|
2279
|
+
res.json({ success: true, provider });
|
|
2280
|
+
} else {
|
|
2281
|
+
res.status(400).json({ success: false, error: 'Invalid or unavailable provider' });
|
|
2282
|
+
}
|
|
2283
|
+
} catch (error) {
|
|
2284
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2285
|
+
}
|
|
2286
|
+
});
|
|
2287
|
+
|
|
2288
|
+
// Settings API - Get API configuration
|
|
2289
|
+
app.get('/api/settings/api-config', async (req, res) => {
|
|
2290
|
+
try {
|
|
2291
|
+
const configPath = path.join(__dirname, '../../.env');
|
|
2292
|
+
let config = {
|
|
2293
|
+
provider: process.env.AI_PROVIDER || 'gemini',
|
|
2294
|
+
model: process.env.AI_MODEL || '',
|
|
2295
|
+
openai_api_key: process.env.OPENAI_API_KEY || '',
|
|
2296
|
+
gemini_api_key: process.env.GEMINI_API_KEY || '',
|
|
2297
|
+
claude_api_key: process.env.CLAUDE_API_KEY || '',
|
|
2298
|
+
github_token: process.env.GITHUB_TOKEN || '',
|
|
2299
|
+
groq_api_key: process.env.GROQ_API_KEY || '',
|
|
2300
|
+
cohere_api_key: process.env.COHERE_API_KEY || '',
|
|
2301
|
+
mistral_api_key: process.env.MISTRAL_API_KEY || '',
|
|
2302
|
+
};
|
|
2303
|
+
|
|
2304
|
+
// Try to read from .env file if exists
|
|
2305
|
+
try {
|
|
2306
|
+
const envContent = await fs.readFile(configPath, 'utf-8');
|
|
2307
|
+
const lines = envContent.split('\n');
|
|
2308
|
+
lines.forEach(line => {
|
|
2309
|
+
const [key, value] = line.split('=');
|
|
2310
|
+
if (key && value) {
|
|
2311
|
+
const trimmedKey = key.trim();
|
|
2312
|
+
const trimmedValue = value.trim();
|
|
2313
|
+
if (trimmedKey === 'AI_PROVIDER') config.provider = trimmedValue;
|
|
2314
|
+
if (trimmedKey === 'AI_MODEL') config.model = trimmedValue;
|
|
2315
|
+
if (trimmedKey === 'OPENAI_API_KEY') config.openai_api_key = trimmedValue;
|
|
2316
|
+
if (trimmedKey === 'GEMINI_API_KEY') config.gemini_api_key = trimmedValue;
|
|
2317
|
+
if (trimmedKey === 'CLAUDE_API_KEY') config.claude_api_key = trimmedValue;
|
|
2318
|
+
if (trimmedKey === 'GITHUB_TOKEN') config.github_token = trimmedValue;
|
|
2319
|
+
if (trimmedKey === 'GROQ_API_KEY') config.groq_api_key = trimmedValue;
|
|
2320
|
+
if (trimmedKey === 'COHERE_API_KEY') config.cohere_api_key = trimmedValue;
|
|
2321
|
+
if (trimmedKey === 'MISTRAL_API_KEY') config.mistral_api_key = trimmedValue;
|
|
2322
|
+
}
|
|
2323
|
+
});
|
|
2324
|
+
} catch (err) {
|
|
2325
|
+
// .env doesn't exist, return defaults
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
// Mask API keys for security - only show last 4 characters
|
|
2329
|
+
const maskKey = (key) => {
|
|
2330
|
+
if (!key || key.length < 8) return '';
|
|
2331
|
+
return 'ā¢'.repeat(key.length - 4) + key.slice(-4);
|
|
2332
|
+
};
|
|
2333
|
+
|
|
2334
|
+
res.json({
|
|
2335
|
+
provider: config.provider,
|
|
2336
|
+
model: config.model,
|
|
2337
|
+
openai_api_key: maskKey(config.openai_api_key),
|
|
2338
|
+
gemini_api_key: maskKey(config.gemini_api_key),
|
|
2339
|
+
claude_api_key: maskKey(config.claude_api_key),
|
|
2340
|
+
github_token: maskKey(config.github_token),
|
|
2341
|
+
groq_api_key: maskKey(config.groq_api_key),
|
|
2342
|
+
cohere_api_key: maskKey(config.cohere_api_key),
|
|
2343
|
+
mistral_api_key: maskKey(config.mistral_api_key),
|
|
2344
|
+
has_openai_key: !!config.openai_api_key,
|
|
2345
|
+
has_gemini_key: !!config.gemini_api_key,
|
|
2346
|
+
has_claude_key: !!config.claude_api_key,
|
|
2347
|
+
has_github_token: !!config.github_token,
|
|
2348
|
+
has_groq_key: !!config.groq_api_key,
|
|
2349
|
+
has_cohere_key: !!config.cohere_api_key,
|
|
2350
|
+
has_mistral_key: !!config.mistral_api_key,
|
|
2351
|
+
});
|
|
2352
|
+
} catch (error) {
|
|
2353
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2354
|
+
}
|
|
2355
|
+
});
|
|
2356
|
+
|
|
2357
|
+
// Settings API - Save API configuration
|
|
2358
|
+
app.post('/api/settings/api-config', async (req, res) => {
|
|
2359
|
+
try {
|
|
2360
|
+
const {
|
|
2361
|
+
provider,
|
|
2362
|
+
model,
|
|
2363
|
+
openai_api_key,
|
|
2364
|
+
gemini_api_key,
|
|
2365
|
+
claude_api_key,
|
|
2366
|
+
github_token,
|
|
2367
|
+
groq_api_key,
|
|
2368
|
+
cohere_api_key,
|
|
2369
|
+
mistral_api_key
|
|
2370
|
+
} = req.body;
|
|
2371
|
+
|
|
2372
|
+
const configPath = path.join(__dirname, '../../.env');
|
|
2373
|
+
|
|
2374
|
+
let envContent = `# AI Provider Configuration\nAI_PROVIDER=${provider}\n`;
|
|
2375
|
+
if (model) {
|
|
2376
|
+
envContent += `AI_MODEL=${model}\n`;
|
|
2377
|
+
}
|
|
2378
|
+
if (openai_api_key) {
|
|
2379
|
+
envContent += `OPENAI_API_KEY=${openai_api_key}\n`;
|
|
2380
|
+
}
|
|
2381
|
+
if (gemini_api_key) {
|
|
2382
|
+
envContent += `GEMINI_API_KEY=${gemini_api_key}\n`;
|
|
2383
|
+
}
|
|
2384
|
+
if (claude_api_key) {
|
|
2385
|
+
envContent += `CLAUDE_API_KEY=${claude_api_key}\n`;
|
|
2386
|
+
}
|
|
2387
|
+
if (github_token) {
|
|
2388
|
+
envContent += `GITHUB_TOKEN=${github_token}\n`;
|
|
2389
|
+
}
|
|
2390
|
+
if (groq_api_key) {
|
|
2391
|
+
envContent += `GROQ_API_KEY=${groq_api_key}\n`;
|
|
2392
|
+
}
|
|
2393
|
+
if (cohere_api_key) {
|
|
2394
|
+
envContent += `COHERE_API_KEY=${cohere_api_key}\n`;
|
|
2395
|
+
}
|
|
2396
|
+
if (mistral_api_key) {
|
|
2397
|
+
envContent += `MISTRAL_API_KEY=${mistral_api_key}\n`;
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
// Add WDA path if exists
|
|
2401
|
+
if (process.env.WDA_PATH) {
|
|
2402
|
+
envContent += `WDA_PATH=${process.env.WDA_PATH}\n`;
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2405
|
+
await fs.writeFile(configPath, envContent);
|
|
2406
|
+
|
|
2407
|
+
// Update environment variables
|
|
2408
|
+
process.env.AI_PROVIDER = provider;
|
|
2409
|
+
if (model) process.env.AI_MODEL = model;
|
|
2410
|
+
if (openai_api_key) process.env.OPENAI_API_KEY = openai_api_key;
|
|
2411
|
+
if (gemini_api_key) process.env.GEMINI_API_KEY = gemini_api_key;
|
|
2412
|
+
if (claude_api_key) process.env.CLAUDE_API_KEY = claude_api_key;
|
|
2413
|
+
if (github_token) process.env.GITHUB_TOKEN = github_token;
|
|
2414
|
+
if (groq_api_key) process.env.GROQ_API_KEY = groq_api_key;
|
|
2415
|
+
if (cohere_api_key) process.env.COHERE_API_KEY = cohere_api_key;
|
|
2416
|
+
if (mistral_api_key) process.env.MISTRAL_API_KEY = mistral_api_key;
|
|
2417
|
+
|
|
2418
|
+
// Reinitialize AI manager with new config
|
|
2419
|
+
aiManager.provider = provider;
|
|
2420
|
+
if (model) aiManager.model = model;
|
|
2421
|
+
aiManager.initializeProviders();
|
|
2422
|
+
|
|
2423
|
+
res.json({ success: true, message: 'API configuration saved' });
|
|
2424
|
+
} catch (error) {
|
|
2425
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2426
|
+
}
|
|
2427
|
+
});
|
|
2428
|
+
|
|
2429
|
+
// Settings API - Get available AI providers and their models
|
|
2430
|
+
app.get('/api/settings/ai-providers', (req, res) => {
|
|
2431
|
+
try {
|
|
2432
|
+
const { AI_PROVIDERS_CONFIG } = require('./aiProvidersConfig');
|
|
2433
|
+
res.json({ success: true, providers: AI_PROVIDERS_CONFIG });
|
|
2434
|
+
} catch (error) {
|
|
2435
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2436
|
+
}
|
|
2437
|
+
});
|
|
2438
|
+
|
|
2439
|
+
// Settings API - Get devices configuration
|
|
2440
|
+
app.get('/api/settings/devices', async (req, res) => {
|
|
2441
|
+
try {
|
|
2442
|
+
const devices = await loadDeviceConfig();
|
|
2443
|
+
res.json({ success: true, devices });
|
|
2444
|
+
} catch (error) {
|
|
2445
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2446
|
+
}
|
|
2447
|
+
});
|
|
2448
|
+
|
|
2449
|
+
// Settings API - Save devices configuration
|
|
2450
|
+
app.post('/api/settings/devices', async (req, res) => {
|
|
2451
|
+
try {
|
|
2452
|
+
const { devices } = req.body;
|
|
2453
|
+
|
|
2454
|
+
// Format: device_name,udid,ip_address,platform,type
|
|
2455
|
+
let content = '# Device Configuration (Auto-updated)\n';
|
|
2456
|
+
content += '# Format: device_name,udid,ip_address,platform,type\n';
|
|
2457
|
+
content += '# Platform: ios | android\n';
|
|
2458
|
+
content += '# Type: usb | wireless\n';
|
|
2459
|
+
content += '# \n';
|
|
2460
|
+
content += '# š USB DEVICES: Automatically detected and saved here\n';
|
|
2461
|
+
content += '# - No configuration needed for USB connection\n';
|
|
2462
|
+
content += '# - Add IP address to enable wireless support later\n';
|
|
2463
|
+
content += '#\n';
|
|
2464
|
+
content += '# š” WIRELESS DEVICES: Manually add with IP address\n';
|
|
2465
|
+
content += '# - Format: device_name,udid,ip_address,platform,wireless\n';
|
|
2466
|
+
content += '# - iOS: Device must be paired in Xcode, WebDriverAgent running\n';
|
|
2467
|
+
content += '# - Android: Enable wireless ADB first\n';
|
|
2468
|
+
content += '#\n';
|
|
2469
|
+
content += '# Example entries:\n';
|
|
2470
|
+
content += '# iPhone17,00008130-001945C63ED3401E,,ios,usb (iOS USB - auto-detected)\n';
|
|
2471
|
+
content += '# iPhone16P,00008140-001C24361E41801C,10.173.221.204,ios,wireless (iOS Wireless)\n';
|
|
2472
|
+
content += '# Pixel8,1A2B3C4D5E6F,,android,usb (Android USB - auto-detected)\n';
|
|
2473
|
+
content += '# GalaxyS23,ABCD1234,192.168.1.150,android,wireless (Android Wireless)\n\n';
|
|
2474
|
+
|
|
2475
|
+
devices.forEach(device => {
|
|
2476
|
+
const ip = device.ip || '';
|
|
2477
|
+
const platform = device.platform || 'ios';
|
|
2478
|
+
const type = device.type || device.connectionType || (ip ? 'wireless' : 'usb');
|
|
2479
|
+
content += `${device.name},${device.udid},${ip},${platform},${type}\n`;
|
|
2480
|
+
});
|
|
2481
|
+
|
|
2482
|
+
await fs.writeFile(DEVICE_CONFIG, content);
|
|
2483
|
+
|
|
2484
|
+
res.json({ success: true, message: 'Devices configuration saved' });
|
|
2485
|
+
} catch (error) {
|
|
2486
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2487
|
+
}
|
|
2488
|
+
});
|
|
2489
|
+
|
|
2490
|
+
// Get app presets
|
|
2491
|
+
app.get('/api/apps/presets', async (req, res) => {
|
|
2492
|
+
try {
|
|
2493
|
+
const content = await fs.readFile(APPS_CONFIG, 'utf-8');
|
|
2494
|
+
const apps = content
|
|
2495
|
+
.split('\n')
|
|
2496
|
+
.filter(line => line.trim() && !line.startsWith('#'))
|
|
2497
|
+
.map(line => {
|
|
2498
|
+
const [name, packageId] = line.split(',');
|
|
2499
|
+
return { name: name.trim(), packageId: packageId.trim() };
|
|
2500
|
+
});
|
|
2501
|
+
|
|
2502
|
+
res.json({ success: true, apps });
|
|
2503
|
+
} catch (error) {
|
|
2504
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2505
|
+
}
|
|
2506
|
+
});
|
|
2507
|
+
|
|
2508
|
+
// Get locators from device's current screen
|
|
2509
|
+
app.post('/api/locators', async (req, res) => {
|
|
2510
|
+
try {
|
|
2511
|
+
const { deviceName } = req.body;
|
|
2512
|
+
|
|
2513
|
+
if (!deviceName) {
|
|
2514
|
+
return res.status(400).json({ success: false, error: 'Device name required' });
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
console.log(`\nš API: Getting locators for device: ${deviceName}`);
|
|
2518
|
+
|
|
2519
|
+
// Find the device info
|
|
2520
|
+
const device = connectedDevices.find(d => d.name === deviceName);
|
|
2521
|
+
if (!device) {
|
|
2522
|
+
return res.status(404).json({ success: false, error: 'Device not found' });
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
// For Android devices, ensure UIAutomator2 session exists
|
|
2526
|
+
if (device.platform === 'android') {
|
|
2527
|
+
const session = androidSessions.get(device.udid);
|
|
2528
|
+
if (!session) {
|
|
2529
|
+
// Auto-connect the device
|
|
2530
|
+
console.log(`š” Auto-connecting ${deviceName} for getLocators...`);
|
|
2531
|
+
try {
|
|
2532
|
+
const connectResult = await connectToDevice(device);
|
|
2533
|
+
if (!connectResult.success) {
|
|
2534
|
+
return res.status(500).json({
|
|
2535
|
+
success: false,
|
|
2536
|
+
error: 'Failed to connect device. Please use the Connect button first.'
|
|
2537
|
+
});
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
// Wait a moment for session to stabilize
|
|
2541
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2542
|
+
} catch (err) {
|
|
2543
|
+
return res.status(500).json({
|
|
2544
|
+
success: false,
|
|
2545
|
+
error: `Auto-connection failed: ${err.message}`
|
|
2546
|
+
});
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
// Execute getLocators command - this uses the fast shell script implementation
|
|
2552
|
+
const result = await executeCommand([deviceName], 'getLocators', null);
|
|
2553
|
+
|
|
2554
|
+
console.log(`Result success: ${result.success}`);
|
|
2555
|
+
console.log(`Results array length: ${result.results?.length || 0}`);
|
|
2556
|
+
|
|
2557
|
+
if (result.success && result.results) {
|
|
2558
|
+
let output = '';
|
|
2559
|
+
|
|
2560
|
+
// executeCommand returns: { success, results: [scriptResults] }
|
|
2561
|
+
// scriptResults is from executeAndroidDevices/executeWithScript
|
|
2562
|
+
// Structure: { status: 'fulfilled', value: { success, results: [allSettledResults] } }
|
|
2563
|
+
// allSettledResults contains: { status: 'fulfilled', value: { success, output, device } }
|
|
2564
|
+
|
|
2565
|
+
for (const scriptResult of result.results) {
|
|
2566
|
+
console.log(`Script result:`, scriptResult);
|
|
2567
|
+
|
|
2568
|
+
// Check if scriptResult has value.results (fulfilled promise)
|
|
2569
|
+
if (scriptResult.status === 'fulfilled' && scriptResult.value && scriptResult.value.results) {
|
|
2570
|
+
// This is the result from executeAndroidDevices/executeWithScript
|
|
2571
|
+
for (const r of scriptResult.value.results) {
|
|
2572
|
+
console.log(`Result status: ${r.status}`);
|
|
2573
|
+
if (r.status === 'fulfilled' && r.value) {
|
|
2574
|
+
// Check if it's a successful execution
|
|
2575
|
+
if (r.value.success && r.value.output) {
|
|
2576
|
+
output = r.value.output;
|
|
2577
|
+
console.log(`ā
Found output: ${output.length} characters`);
|
|
2578
|
+
break;
|
|
2579
|
+
} else if (r.value.error) {
|
|
2580
|
+
// Script executed but returned an error
|
|
2581
|
+
console.log(`ā Script error:`, r.value.error);
|
|
2582
|
+
return res.status(500).json({
|
|
2583
|
+
success: false,
|
|
2584
|
+
error: 'Failed to get UI elements. Please ensure UIAutomator2 is installed for Android devices.'
|
|
2585
|
+
});
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
if (output) break;
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
if (!output) {
|
|
2594
|
+
console.log('ā No output found in results');
|
|
2595
|
+
console.log('Full result structure:', JSON.stringify(result, null, 2));
|
|
2596
|
+
return res.status(500).json({ success: false, error: 'No output received from device' });
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
// Parse the output into locator objects
|
|
2600
|
+
const locators = parseLocatorsOutput(output);
|
|
2601
|
+
console.log(`ā
Parsed ${locators.length} locators`);
|
|
2602
|
+
|
|
2603
|
+
// Filter out empty/invalid locators
|
|
2604
|
+
const validLocators = locators.filter(loc => loc.name || loc.label || loc.text);
|
|
2605
|
+
console.log(`ā
Filtered to ${validLocators.length} valid locators`);
|
|
2606
|
+
|
|
2607
|
+
res.json({ success: true, locators: validLocators });
|
|
2608
|
+
} else {
|
|
2609
|
+
console.log('ā Command execution failed');
|
|
2610
|
+
res.status(500).json({ success: false, error: 'Failed to get locators' });
|
|
2611
|
+
}
|
|
2612
|
+
} catch (error) {
|
|
2613
|
+
console.error(`ā API error:`, error);
|
|
2614
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2615
|
+
}
|
|
2616
|
+
});
|
|
2617
|
+
|
|
2618
|
+
// Click on a locator
|
|
2619
|
+
app.post('/api/locators/click', async (req, res) => {
|
|
2620
|
+
try {
|
|
2621
|
+
const { deviceName, locatorName, x, y } = req.body;
|
|
2622
|
+
|
|
2623
|
+
if (!deviceName) {
|
|
2624
|
+
return res.status(400).json({ success: false, error: 'Device name required' });
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
let command;
|
|
2628
|
+
// If coordinates are provided, use them directly
|
|
2629
|
+
if (x !== undefined && y !== undefined) {
|
|
2630
|
+
command = `tap ${x},${y}`;
|
|
2631
|
+
console.log(`\nš±ļø API: Tapping at coordinates (${x},${y}) on device: ${deviceName}`);
|
|
2632
|
+
} else if (locatorName) {
|
|
2633
|
+
command = `click "${locatorName}"`;
|
|
2634
|
+
console.log(`\nš±ļø API: Clicking locator "${locatorName}" on device: ${deviceName}`);
|
|
2635
|
+
} else {
|
|
2636
|
+
return res.status(400).json({ success: false, error: 'Locator name or coordinates required' });
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
// Execute click command
|
|
2640
|
+
const result = await executeCommand([deviceName], command, null);
|
|
2641
|
+
|
|
2642
|
+
if (result.success) {
|
|
2643
|
+
res.json({ success: true, message: 'Tap executed successfully' });
|
|
2644
|
+
} else {
|
|
2645
|
+
res.status(500).json({ success: false, error: 'Failed to execute tap' });
|
|
2646
|
+
}
|
|
2647
|
+
} catch (error) {
|
|
2648
|
+
console.error('ā Tap error:', error);
|
|
2649
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2650
|
+
}
|
|
2651
|
+
});
|
|
2652
|
+
|
|
2653
|
+
// Helper function to parse locators output
|
|
2654
|
+
function parseLocatorsOutput(output) {
|
|
2655
|
+
console.log('š Parsing locators output...');
|
|
2656
|
+
console.log('Output length:', output?.length || 0);
|
|
2657
|
+
|
|
2658
|
+
if (!output) {
|
|
2659
|
+
console.log('ā No output to parse');
|
|
2660
|
+
return [];
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2663
|
+
// First try to parse as JSON (new format)
|
|
2664
|
+
const lines = output.split('\n');
|
|
2665
|
+
for (const line of lines) {
|
|
2666
|
+
const trimmed = line.trim();
|
|
2667
|
+
if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
|
|
2668
|
+
try {
|
|
2669
|
+
const jsonData = JSON.parse(trimmed);
|
|
2670
|
+
console.log('ā
Parsed as JSON, elements:', Array.isArray(jsonData) ? jsonData.length : 'not array');
|
|
2671
|
+
return Array.isArray(jsonData) ? jsonData : [];
|
|
2672
|
+
} catch (err) {
|
|
2673
|
+
console.log('ā ļø JSON parse failed:', err.message);
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
|
|
2678
|
+
console.log('š Fallback to text parsing...');
|
|
2679
|
+
|
|
2680
|
+
// Fallback to old text parsing
|
|
2681
|
+
const locators = [];
|
|
2682
|
+
console.log('Total lines:', lines.length);
|
|
2683
|
+
|
|
2684
|
+
for (const line of lines) {
|
|
2685
|
+
// New format: " 1. š ButtonName ā [Button] ā Label:LabelText ā Val:ValueText ā @ (x,y) WxH ā āVis āEn"
|
|
2686
|
+
// Look for lines with numbered locators starting with š
|
|
2687
|
+
if (line.includes('š') && /^\s*\d+\./.test(line)) {
|
|
2688
|
+
try {
|
|
2689
|
+
const locator = {};
|
|
2690
|
+
|
|
2691
|
+
// Extract index number
|
|
2692
|
+
const indexMatch = line.match(/^\s*(\d+)\./);
|
|
2693
|
+
if (indexMatch) locator.index = parseInt(indexMatch[1]);
|
|
2694
|
+
|
|
2695
|
+
// Split by pipe separator if present (new format), otherwise use old logic
|
|
2696
|
+
if (line.includes('ā')) {
|
|
2697
|
+
const parts = line.split('ā').map(p => p.trim());
|
|
2698
|
+
|
|
2699
|
+
// Part 0: "1. š ButtonName"
|
|
2700
|
+
const nameMatch = parts[0].match(/š\s+(.+)/);
|
|
2701
|
+
if (nameMatch) {
|
|
2702
|
+
locator.name = nameMatch[1].trim();
|
|
2703
|
+
locator.text = nameMatch[1].trim();
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
// Part 1: "[Button]" or "[TextView]"
|
|
2707
|
+
const typeMatch = parts[1] ? parts[1].match(/\[([^\]]+)\]/) : null;
|
|
2708
|
+
if (typeMatch) locator.type = typeMatch[1].trim();
|
|
2709
|
+
|
|
2710
|
+
// Process remaining parts for Label, Val, ID, coordinates, flags
|
|
2711
|
+
for (let i = 2; i < parts.length; i++) {
|
|
2712
|
+
const part = parts[i];
|
|
2713
|
+
|
|
2714
|
+
// Label:...
|
|
2715
|
+
if (part.includes('Label:')) {
|
|
2716
|
+
const labelMatch = part.match(/Label:([^\s]+)/);
|
|
2717
|
+
if (labelMatch) locator.label = labelMatch[1];
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2720
|
+
// Val:...
|
|
2721
|
+
if (part.includes('Val:')) {
|
|
2722
|
+
const valueMatch = part.match(/Val:([^\s]+)/);
|
|
2723
|
+
if (valueMatch) locator.value = valueMatch[1];
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2726
|
+
// ID:...
|
|
2727
|
+
if (part.includes('ID:')) {
|
|
2728
|
+
const idMatch = part.match(/ID:([^\s]+)/);
|
|
2729
|
+
if (idMatch) locator.resourceId = idMatch[1];
|
|
2730
|
+
}
|
|
2731
|
+
|
|
2732
|
+
// @ (x,y) WxH
|
|
2733
|
+
if (part.includes('@')) {
|
|
2734
|
+
const coordMatch = part.match(/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);
|
|
2735
|
+
if (coordMatch) {
|
|
2736
|
+
locator.x = parseInt(coordMatch[1]);
|
|
2737
|
+
locator.y = parseInt(coordMatch[2]);
|
|
2738
|
+
locator.width = parseInt(coordMatch[3]);
|
|
2739
|
+
locator.height = parseInt(coordMatch[4]);
|
|
2740
|
+
locator.coordinates = `(${locator.x},${locator.y}) ${locator.width}x${locator.height}`;
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
// Flags
|
|
2745
|
+
if (part.includes('āVis')) locator.visible = true;
|
|
2746
|
+
if (part.includes('āEn')) locator.enabled = true;
|
|
2747
|
+
if (part.includes('āClick')) locator.clickable = true;
|
|
2748
|
+
}
|
|
2749
|
+
} else {
|
|
2750
|
+
// Old format fallback
|
|
2751
|
+
const nameMatch = line.match(/š\s+([^\[]+?)(?:\s*\[|\s*Label)/);
|
|
2752
|
+
if (nameMatch) {
|
|
2753
|
+
locator.name = nameMatch[1].trim();
|
|
2754
|
+
locator.text = nameMatch[1].trim();
|
|
2755
|
+
}
|
|
2756
|
+
|
|
2757
|
+
const typeMatch = line.match(/\[([^\]]+)\]/);
|
|
2758
|
+
if (typeMatch) locator.type = typeMatch[1].trim();
|
|
2759
|
+
|
|
2760
|
+
const labelMatch = line.match(/Label:([^\s]+?)(?:\s*Val:|\s*@|\s*ā)/);
|
|
2761
|
+
if (labelMatch) locator.label = labelMatch[1].trim();
|
|
2762
|
+
|
|
2763
|
+
const valueMatch = line.match(/Val:([^\s]+?)(?:\s*@|\s*ā)/);
|
|
2764
|
+
if (valueMatch) locator.value = valueMatch[1].trim();
|
|
2765
|
+
|
|
2766
|
+
const coordMatch = line.match(/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);
|
|
2767
|
+
if (coordMatch) {
|
|
2768
|
+
locator.x = parseInt(coordMatch[1]);
|
|
2769
|
+
locator.y = parseInt(coordMatch[2]);
|
|
2770
|
+
locator.width = parseInt(coordMatch[3]);
|
|
2771
|
+
locator.height = parseInt(coordMatch[4]);
|
|
2772
|
+
locator.coordinates = `(${locator.x},${locator.y}) ${locator.width}x${locator.height}`;
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
const idMatch = line.match(/ID:([^\s]+)/);
|
|
2776
|
+
if (idMatch) locator.resourceId = idMatch[1].trim();
|
|
2777
|
+
|
|
2778
|
+
locator.visible = line.includes('āVis');
|
|
2779
|
+
locator.enabled = line.includes('āEn');
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2782
|
+
// Only add if we have meaningful data
|
|
2783
|
+
if (locator.name || locator.label || locator.text) {
|
|
2784
|
+
console.log('ā
Parsed locator:', locator);
|
|
2785
|
+
locators.push(locator);
|
|
2786
|
+
}
|
|
2787
|
+
} catch (e) {
|
|
2788
|
+
// Skip malformed lines
|
|
2789
|
+
console.error('Error parsing locator line:', line, e);
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
|
|
2794
|
+
console.log(`ā
Total parsed locators: ${locators.length}`);
|
|
2795
|
+
return locators;
|
|
2796
|
+
}
|
|
2797
|
+
|
|
2798
|
+
// WebSocket handling
|
|
2799
|
+
wss.on('connection', (ws) => {
|
|
2800
|
+
console.log('New WebSocket connection');
|
|
2801
|
+
|
|
2802
|
+
ws.on('message', async (message) => {
|
|
2803
|
+
try {
|
|
2804
|
+
const data = JSON.parse(message);
|
|
2805
|
+
|
|
2806
|
+
switch (data.type) {
|
|
2807
|
+
case 'execute_command':
|
|
2808
|
+
const { devices, command, useAI, aiProvider } = data;
|
|
2809
|
+
|
|
2810
|
+
console.log(`\n${'*'.repeat(60)}`);
|
|
2811
|
+
console.log(`WEBSOCKET: Received execute_command`);
|
|
2812
|
+
console.log(`Devices received: [${devices.join(', ')}]`);
|
|
2813
|
+
console.log(`Command: "${command}"`);
|
|
2814
|
+
console.log(`Use AI: ${useAI}`);
|
|
2815
|
+
if (aiProvider) console.log(`AI Provider: ${aiProvider}`);
|
|
2816
|
+
console.log(`${'*'.repeat(60)}\n`);
|
|
2817
|
+
|
|
2818
|
+
let finalCommand = command;
|
|
2819
|
+
|
|
2820
|
+
if (useAI) {
|
|
2821
|
+
try {
|
|
2822
|
+
finalCommand = await convertNaturalLanguageToCommand(command, devices, aiProvider);
|
|
2823
|
+
console.log(`ā
AI converted command to:\n${finalCommand}`);
|
|
2824
|
+
ws.send(JSON.stringify({
|
|
2825
|
+
type: 'command_converted',
|
|
2826
|
+
original: command,
|
|
2827
|
+
converted: finalCommand,
|
|
2828
|
+
provider: aiProvider || aiManager.provider
|
|
2829
|
+
}));
|
|
2830
|
+
} catch (error) {
|
|
2831
|
+
console.error(`ā AI conversion failed: ${error.message}`);
|
|
2832
|
+
|
|
2833
|
+
// Send error to frontend - DO NOT execute command
|
|
2834
|
+
ws.send(JSON.stringify({
|
|
2835
|
+
type: 'ai_error',
|
|
2836
|
+
error: error.message,
|
|
2837
|
+
original: command
|
|
2838
|
+
}));
|
|
2839
|
+
|
|
2840
|
+
// Stop execution - don't run unconverted commands
|
|
2841
|
+
return;
|
|
2842
|
+
}
|
|
2843
|
+
} else {
|
|
2844
|
+
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
// Check if command has multiple lines (sequential execution)
|
|
2848
|
+
const hasMultipleCommands = finalCommand.includes('\n');
|
|
2849
|
+
|
|
2850
|
+
if (hasMultipleCommands) {
|
|
2851
|
+
|
|
2852
|
+
executeCommandsSequentially(devices, finalCommand, ws)
|
|
2853
|
+
.then(result => {
|
|
2854
|
+
console.log(`Sequential execution completed`);
|
|
2855
|
+
ws.send(JSON.stringify({
|
|
2856
|
+
type: 'command_complete',
|
|
2857
|
+
result
|
|
2858
|
+
}));
|
|
2859
|
+
})
|
|
2860
|
+
.catch(error => {
|
|
2861
|
+
console.error(`Sequential execution failed: ${error.message}`);
|
|
2862
|
+
ws.send(JSON.stringify({
|
|
2863
|
+
type: 'command_error',
|
|
2864
|
+
error: error.message
|
|
2865
|
+
}));
|
|
2866
|
+
});
|
|
2867
|
+
} else {
|
|
2868
|
+
executeCommand(devices, finalCommand, ws)
|
|
2869
|
+
.then(result => {
|
|
2870
|
+
|
|
2871
|
+
// Record command if recording is active
|
|
2872
|
+
if (isRecording) {
|
|
2873
|
+
recordCommand(devices, command, useAI, finalCommand);
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2876
|
+
ws.send(JSON.stringify({
|
|
2877
|
+
type: 'command_complete',
|
|
2878
|
+
result
|
|
2879
|
+
}));
|
|
2880
|
+
})
|
|
2881
|
+
.catch(error => {
|
|
2882
|
+
console.error(`executeCommand failed: ${error.message}`);
|
|
2883
|
+
ws.send(JSON.stringify({
|
|
2884
|
+
type: 'command_error',
|
|
2885
|
+
error: error.message
|
|
2886
|
+
}));
|
|
2887
|
+
});
|
|
2888
|
+
}
|
|
2889
|
+
break;
|
|
2890
|
+
|
|
2891
|
+
case 'start_recording':
|
|
2892
|
+
const startResult = await startRecording(data.name, data.devices);
|
|
2893
|
+
ws.send(JSON.stringify({
|
|
2894
|
+
type: 'recording_started',
|
|
2895
|
+
...startResult
|
|
2896
|
+
}));
|
|
2897
|
+
break;
|
|
2898
|
+
|
|
2899
|
+
case 'stop_recording':
|
|
2900
|
+
const stopResult = await stopRecording();
|
|
2901
|
+
ws.send(JSON.stringify({
|
|
2902
|
+
type: 'recording_stopped',
|
|
2903
|
+
...stopResult
|
|
2904
|
+
}));
|
|
2905
|
+
break;
|
|
2906
|
+
|
|
2907
|
+
case 'replay_recording':
|
|
2908
|
+
const { filename, targetDevices } = data;
|
|
2909
|
+
|
|
2910
|
+
ws.send(JSON.stringify({
|
|
2911
|
+
type: 'command_output',
|
|
2912
|
+
data: `\nš¬ Starting replay: ${filename}\n\n`,
|
|
2913
|
+
devices: targetDevices
|
|
2914
|
+
}));
|
|
2915
|
+
|
|
2916
|
+
replayRecording(filename, targetDevices, ws)
|
|
2917
|
+
.then(result => {
|
|
2918
|
+
ws.send(JSON.stringify({
|
|
2919
|
+
type: 'replay_complete',
|
|
2920
|
+
...result
|
|
2921
|
+
}));
|
|
2922
|
+
})
|
|
2923
|
+
.catch(error => {
|
|
2924
|
+
ws.send(JSON.stringify({
|
|
2925
|
+
type: 'replay_error',
|
|
2926
|
+
error: error.message
|
|
2927
|
+
}));
|
|
2928
|
+
});
|
|
2929
|
+
break;
|
|
2930
|
+
|
|
2931
|
+
case 'stop_replay':
|
|
2932
|
+
if (isReplaying) {
|
|
2933
|
+
replayAborted = true;
|
|
2934
|
+
ws.send(JSON.stringify({
|
|
2935
|
+
type: 'command_output',
|
|
2936
|
+
data: '\nā¹ļø Stopping replay...\n'
|
|
2937
|
+
}));
|
|
2938
|
+
}
|
|
2939
|
+
break;
|
|
2940
|
+
|
|
2941
|
+
case 'refresh_devices':
|
|
2942
|
+
const updatedDevices = await discoverDevices();
|
|
2943
|
+
ws.send(JSON.stringify({
|
|
2944
|
+
type: 'devices_updated',
|
|
2945
|
+
devices: updatedDevices
|
|
2946
|
+
}));
|
|
2947
|
+
break;
|
|
2948
|
+
|
|
2949
|
+
case 'get_ai_providers':
|
|
2950
|
+
ws.send(JSON.stringify({
|
|
2951
|
+
type: 'ai_providers',
|
|
2952
|
+
providers: aiManager.getAvailableProviders(),
|
|
2953
|
+
current: aiManager.provider
|
|
2954
|
+
}));
|
|
2955
|
+
break;
|
|
2956
|
+
|
|
2957
|
+
case 'set_ai_provider':
|
|
2958
|
+
const success = aiManager.setProvider(data.provider);
|
|
2959
|
+
ws.send(JSON.stringify({
|
|
2960
|
+
type: 'ai_provider_set',
|
|
2961
|
+
success,
|
|
2962
|
+
provider: data.provider
|
|
2963
|
+
}));
|
|
2964
|
+
break;
|
|
2965
|
+
}
|
|
2966
|
+
} catch (error) {
|
|
2967
|
+
ws.send(JSON.stringify({
|
|
2968
|
+
type: 'error',
|
|
2969
|
+
message: error.message
|
|
2970
|
+
}));
|
|
2971
|
+
}
|
|
2972
|
+
});
|
|
2973
|
+
|
|
2974
|
+
ws.on('close', () => {
|
|
2975
|
+
console.log('WebSocket connection closed');
|
|
2976
|
+
});
|
|
2977
|
+
|
|
2978
|
+
// Send initial device list
|
|
2979
|
+
discoverDevices().then(devices => {
|
|
2980
|
+
ws.send(JSON.stringify({
|
|
2981
|
+
type: 'devices_updated',
|
|
2982
|
+
devices
|
|
2983
|
+
}));
|
|
2984
|
+
});
|
|
2985
|
+
});
|
|
2986
|
+
|
|
2987
|
+
// Android UIAutomator2 Installation
|
|
2988
|
+
app.post('/api/android/install-uiautomator2', async (req, res) => {
|
|
2989
|
+
const { device } = req.body;
|
|
2990
|
+
|
|
2991
|
+
if (!device) {
|
|
2992
|
+
return res.status(400).json({ success: false, error: 'Device name required' });
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
try {
|
|
2996
|
+
console.log(`š„ Installing UIAutomator2 on ${device}...`);
|
|
2997
|
+
|
|
2998
|
+
// Find device UDID
|
|
2999
|
+
const deviceObj = connectedDevices.find(d => d.name === device);
|
|
3000
|
+
if (!deviceObj) {
|
|
3001
|
+
return res.json({
|
|
3002
|
+
success: false,
|
|
3003
|
+
error: 'Device not found or not connected'
|
|
3004
|
+
});
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
// Use the helper function
|
|
3008
|
+
const result = await installUIAutomator2(deviceObj.udid, device);
|
|
3009
|
+
|
|
3010
|
+
res.json(result);
|
|
3011
|
+
|
|
3012
|
+
} catch (error) {
|
|
3013
|
+
console.error('ā UIAutomator2 installation error:', error.message);
|
|
3014
|
+
res.json({
|
|
3015
|
+
success: false,
|
|
3016
|
+
error: error.message,
|
|
3017
|
+
suggestion: 'Please install manually using: npm install -g appium-uiautomator2-driver'
|
|
3018
|
+
});
|
|
3019
|
+
}
|
|
3020
|
+
});
|
|
3021
|
+
|
|
3022
|
+
// ============================================
|
|
3023
|
+
// Recording & Replay API Endpoints
|
|
3024
|
+
// ============================================
|
|
3025
|
+
|
|
3026
|
+
// Start recording
|
|
3027
|
+
app.post('/api/recording/start', async (req, res) => {
|
|
3028
|
+
try {
|
|
3029
|
+
const { name, devices } = req.body;
|
|
3030
|
+
const result = await startRecording(name, devices);
|
|
3031
|
+
res.json(result);
|
|
3032
|
+
} catch (error) {
|
|
3033
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3034
|
+
}
|
|
3035
|
+
});
|
|
3036
|
+
|
|
3037
|
+
// Stop recording
|
|
3038
|
+
app.post('/api/recording/stop', async (req, res) => {
|
|
3039
|
+
try {
|
|
3040
|
+
const result = await stopRecording();
|
|
3041
|
+
res.json(result);
|
|
3042
|
+
} catch (error) {
|
|
3043
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3044
|
+
}
|
|
3045
|
+
});
|
|
3046
|
+
|
|
3047
|
+
// Get recording status
|
|
3048
|
+
app.get('/api/recording/status', (req, res) => {
|
|
3049
|
+
res.json({
|
|
3050
|
+
isRecording,
|
|
3051
|
+
recording: currentRecording
|
|
3052
|
+
});
|
|
3053
|
+
});
|
|
3054
|
+
|
|
3055
|
+
// List all recordings
|
|
3056
|
+
app.get('/api/recordings', async (req, res) => {
|
|
3057
|
+
try {
|
|
3058
|
+
const recordings = await listRecordings();
|
|
3059
|
+
res.json({ success: true, recordings });
|
|
3060
|
+
} catch (error) {
|
|
3061
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3062
|
+
}
|
|
3063
|
+
});
|
|
3064
|
+
|
|
3065
|
+
// Get specific recording
|
|
3066
|
+
app.get('/api/recordings/:filename', async (req, res) => {
|
|
3067
|
+
try {
|
|
3068
|
+
const recording = await loadRecording(req.params.filename);
|
|
3069
|
+
res.json({ success: true, recording });
|
|
3070
|
+
} catch (error) {
|
|
3071
|
+
res.status(404).json({ success: false, error: 'Recording not found' });
|
|
3072
|
+
}
|
|
3073
|
+
});
|
|
3074
|
+
|
|
3075
|
+
// Delete recording
|
|
3076
|
+
app.delete('/api/recordings/:filename', async (req, res) => {
|
|
3077
|
+
try {
|
|
3078
|
+
await deleteRecording(req.params.filename);
|
|
3079
|
+
res.json({ success: true });
|
|
3080
|
+
} catch (error) {
|
|
3081
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3082
|
+
}
|
|
3083
|
+
});
|
|
3084
|
+
|
|
3085
|
+
// Update recording
|
|
3086
|
+
app.put('/api/recordings/:filename', async (req, res) => {
|
|
3087
|
+
try {
|
|
3088
|
+
const { filename } = req.params;
|
|
3089
|
+
const updatedRecording = req.body;
|
|
3090
|
+
|
|
3091
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
3092
|
+
await fs.writeFile(filepath, JSON.stringify(updatedRecording, null, 2));
|
|
3093
|
+
|
|
3094
|
+
res.json({ success: true, recording: updatedRecording });
|
|
3095
|
+
} catch (error) {
|
|
3096
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3097
|
+
}
|
|
3098
|
+
});
|
|
3099
|
+
|
|
3100
|
+
// Save new recording
|
|
3101
|
+
app.post('/api/recordings/save', async (req, res) => {
|
|
3102
|
+
try {
|
|
3103
|
+
const { name, commands, date, type } = req.body;
|
|
3104
|
+
|
|
3105
|
+
if (!name || !commands) {
|
|
3106
|
+
return res.status(400).json({ success: false, error: 'Name and commands required' });
|
|
3107
|
+
}
|
|
3108
|
+
|
|
3109
|
+
// Create filename from name (sanitize)
|
|
3110
|
+
const sanitizedName = name.replace(/[^a-z0-9_-]/gi, '_');
|
|
3111
|
+
const filename = `${sanitizedName}_${Date.now()}.json`;
|
|
3112
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
3113
|
+
|
|
3114
|
+
const recording = {
|
|
3115
|
+
name,
|
|
3116
|
+
commands,
|
|
3117
|
+
date: date || new Date().toISOString(),
|
|
3118
|
+
type: type || 'manual'
|
|
3119
|
+
};
|
|
3120
|
+
|
|
3121
|
+
await fs.writeFile(filepath, JSON.stringify(recording, null, 2));
|
|
3122
|
+
|
|
3123
|
+
res.json({ success: true, filename, recording });
|
|
3124
|
+
} catch (error) {
|
|
3125
|
+
console.error('Error saving recording:', error);
|
|
3126
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3127
|
+
}
|
|
3128
|
+
});
|
|
3129
|
+
|
|
3130
|
+
// Replay recording
|
|
3131
|
+
app.post('/api/recording/replay', async (req, res) => {
|
|
3132
|
+
try {
|
|
3133
|
+
const { filename, devices } = req.body;
|
|
3134
|
+
|
|
3135
|
+
if (!filename) {
|
|
3136
|
+
return res.status(400).json({ success: false, error: 'Filename required' });
|
|
3137
|
+
}
|
|
3138
|
+
|
|
3139
|
+
if (!devices || devices.length === 0) {
|
|
3140
|
+
return res.status(400).json({ success: false, error: 'Target devices required' });
|
|
3141
|
+
}
|
|
3142
|
+
|
|
3143
|
+
// Start replay in background, send immediate response
|
|
3144
|
+
res.json({ success: true, message: 'Replay started' });
|
|
3145
|
+
|
|
3146
|
+
// Replay will send updates via WebSocket
|
|
3147
|
+
// This is handled by WebSocket message 'replay_recording'
|
|
3148
|
+
} catch (error) {
|
|
3149
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3150
|
+
}
|
|
3151
|
+
});
|
|
3152
|
+
|
|
3153
|
+
// Screenshots API
|
|
3154
|
+
app.get('/api/screenshots', async (req, res) => {
|
|
3155
|
+
try {
|
|
3156
|
+
// Ensure screenshots directory exists
|
|
3157
|
+
await fs.mkdir(SCREENSHOTS_DIR, { recursive: true });
|
|
3158
|
+
|
|
3159
|
+
const files = await fs.readdir(SCREENSHOTS_DIR);
|
|
3160
|
+
const screenshots = files
|
|
3161
|
+
.filter(f => f.endsWith('.png'))
|
|
3162
|
+
.map(f => {
|
|
3163
|
+
const stat = require('fs').statSync(path.join(SCREENSHOTS_DIR, f));
|
|
3164
|
+
return {
|
|
3165
|
+
filename: f,
|
|
3166
|
+
path: `/api/screenshots/${f}`,
|
|
3167
|
+
size: stat.size,
|
|
3168
|
+
timestamp: stat.mtime.getTime(),
|
|
3169
|
+
created: stat.mtime
|
|
3170
|
+
};
|
|
3171
|
+
})
|
|
3172
|
+
.sort((a, b) => b.timestamp - a.timestamp);
|
|
3173
|
+
|
|
3174
|
+
res.json({ success: true, screenshots });
|
|
3175
|
+
} catch (error) {
|
|
3176
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3177
|
+
}
|
|
3178
|
+
});
|
|
3179
|
+
|
|
3180
|
+
// Serve screenshot files
|
|
3181
|
+
app.get('/api/screenshots/:filename', (req, res) => {
|
|
3182
|
+
const filepath = path.join(SCREENSHOTS_DIR, req.params.filename);
|
|
3183
|
+
res.sendFile(filepath, (err) => {
|
|
3184
|
+
if (err) {
|
|
3185
|
+
res.status(404).json({ success: false, error: 'Screenshot not found' });
|
|
3186
|
+
}
|
|
3187
|
+
});
|
|
3188
|
+
});
|
|
3189
|
+
|
|
3190
|
+
// Delete screenshot
|
|
3191
|
+
app.delete('/api/screenshots/:filename', async (req, res) => {
|
|
3192
|
+
try {
|
|
3193
|
+
const filepath = path.join(SCREENSHOTS_DIR, req.params.filename);
|
|
3194
|
+
await fs.unlink(filepath);
|
|
3195
|
+
res.json({ success: true });
|
|
3196
|
+
} catch (error) {
|
|
3197
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3198
|
+
}
|
|
3199
|
+
});
|
|
3200
|
+
|
|
3201
|
+
// List installed apps on device
|
|
3202
|
+
app.post('/api/apps/list', async (req, res) => {
|
|
3203
|
+
try {
|
|
3204
|
+
const { devices } = req.body;
|
|
3205
|
+
|
|
3206
|
+
if (!devices || devices.length === 0) {
|
|
3207
|
+
return res.status(400).json({ success: false, error: 'Device selection required' });
|
|
3208
|
+
}
|
|
3209
|
+
|
|
3210
|
+
const deviceObjects = connectedDevices.filter(d =>
|
|
3211
|
+
devices.includes(d.name) || devices.includes(d.udid) || devices.includes(d.serial)
|
|
3212
|
+
);
|
|
3213
|
+
|
|
3214
|
+
if (deviceObjects.length === 0) {
|
|
3215
|
+
return res.status(400).json({ success: false, error: 'No connected devices found' });
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
const results = {};
|
|
3219
|
+
|
|
3220
|
+
for (const device of deviceObjects) {
|
|
3221
|
+
try {
|
|
3222
|
+
let apps = [];
|
|
3223
|
+
|
|
3224
|
+
if (device.platform === 'android') {
|
|
3225
|
+
// List Android apps
|
|
3226
|
+
const { execSync } = require('child_process');
|
|
3227
|
+
const serial = device.udid || device.serial;
|
|
3228
|
+
const output = execSync(`adb -s ${serial} shell pm list packages -3`, { encoding: 'utf-8' });
|
|
3229
|
+
apps = output
|
|
3230
|
+
.split('\n')
|
|
3231
|
+
.filter(line => line.startsWith('package:'))
|
|
3232
|
+
.map(line => line.replace('package:', '').trim())
|
|
3233
|
+
.filter(pkg => pkg)
|
|
3234
|
+
.sort();
|
|
3235
|
+
} else if (device.platform === 'ios') {
|
|
3236
|
+
// List iOS apps - requires ideviceinstaller
|
|
3237
|
+
const { execSync } = require('child_process');
|
|
3238
|
+
const udid = device.udid;
|
|
3239
|
+
try {
|
|
3240
|
+
// Try new syntax first (ideviceinstaller list)
|
|
3241
|
+
let output;
|
|
3242
|
+
try {
|
|
3243
|
+
output = execSync(`ideviceinstaller -u ${udid} list --user`, { encoding: 'utf-8', timeout: 30000 });
|
|
3244
|
+
} catch (e) {
|
|
3245
|
+
// Fallback to old syntax
|
|
3246
|
+
output = execSync(`ideviceinstaller -u ${udid} -l`, { encoding: 'utf-8', timeout: 30000 });
|
|
3247
|
+
}
|
|
3248
|
+
|
|
3249
|
+
// Parse output - format is "BundleID - AppName" or CFBundleIdentifier format
|
|
3250
|
+
apps = output
|
|
3251
|
+
.split('\n')
|
|
3252
|
+
.filter(line => {
|
|
3253
|
+
const trimmed = line.trim();
|
|
3254
|
+
// Skip empty lines, Total: line, and CSV header
|
|
3255
|
+
return trimmed &&
|
|
3256
|
+
!trimmed.startsWith('Total:') &&
|
|
3257
|
+
!trimmed.startsWith('CFBundleIdentifier');
|
|
3258
|
+
})
|
|
3259
|
+
.map(line => {
|
|
3260
|
+
// Try different formats
|
|
3261
|
+
if (line.includes(' - ')) {
|
|
3262
|
+
const match = line.match(/^(.+?)\s+-\s+(.+?)$/);
|
|
3263
|
+
return match ? { id: match[1].trim(), name: match[2].trim() } : null;
|
|
3264
|
+
} else if (line.includes(',')) {
|
|
3265
|
+
// Format: "BundleID", "Version", "Name"
|
|
3266
|
+
const parts = line.split(',').map(p => p.trim().replace(/"/g, ''));
|
|
3267
|
+
return parts.length >= 3 ? { id: parts[0], name: parts[2] } : null;
|
|
3268
|
+
} else if (line.match(/^[a-zA-Z0-9.-]+$/)) {
|
|
3269
|
+
// Just bundle ID
|
|
3270
|
+
return { id: line.trim(), name: line.trim() };
|
|
3271
|
+
}
|
|
3272
|
+
return null;
|
|
3273
|
+
})
|
|
3274
|
+
.filter(app => app)
|
|
3275
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
3276
|
+
|
|
3277
|
+
if (apps.length === 0) {
|
|
3278
|
+
apps = [{ error: 'No user apps found or unable to parse output' }];
|
|
3279
|
+
}
|
|
3280
|
+
} catch (error) {
|
|
3281
|
+
console.error('iOS apps list error:', error.message);
|
|
3282
|
+
apps = [{ error: `Failed to list apps: ${error.message}` }];
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
|
|
3286
|
+
results[device.name] = {
|
|
3287
|
+
success: true,
|
|
3288
|
+
platform: device.platform,
|
|
3289
|
+
apps: apps,
|
|
3290
|
+
count: Array.isArray(apps) ? apps.length : 0
|
|
3291
|
+
};
|
|
3292
|
+
} catch (error) {
|
|
3293
|
+
results[device.name] = {
|
|
3294
|
+
success: false,
|
|
3295
|
+
error: error.message
|
|
3296
|
+
};
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
3299
|
+
|
|
3300
|
+
res.json({ success: true, results });
|
|
3301
|
+
} catch (error) {
|
|
3302
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3303
|
+
}
|
|
3304
|
+
});
|
|
3305
|
+
|
|
3306
|
+
// Get app info
|
|
3307
|
+
app.post('/api/apps/info', async (req, res) => {
|
|
3308
|
+
try {
|
|
3309
|
+
const { device, bundleId } = req.body;
|
|
3310
|
+
|
|
3311
|
+
if (!device || !bundleId) {
|
|
3312
|
+
return res.status(400).json({ success: false, error: 'Device and bundle ID required' });
|
|
3313
|
+
}
|
|
3314
|
+
|
|
3315
|
+
const deviceObj = discoveredDevices.find(d => d.name === device);
|
|
3316
|
+
if (!deviceObj) {
|
|
3317
|
+
return res.status(404).json({ success: false, error: 'Device not found' });
|
|
3318
|
+
}
|
|
3319
|
+
|
|
3320
|
+
const { execSync } = require('child_process');
|
|
3321
|
+
let appInfo = {};
|
|
3322
|
+
|
|
3323
|
+
try {
|
|
3324
|
+
if (deviceObj.platform === 'android') {
|
|
3325
|
+
// Get Android app info
|
|
3326
|
+
const serial = deviceObj.udid || deviceObj.serial;
|
|
3327
|
+
|
|
3328
|
+
// Get app version
|
|
3329
|
+
try {
|
|
3330
|
+
const versionOutput = execSync(
|
|
3331
|
+
`adb -s ${serial} shell dumpsys package ${bundleId} | grep versionName`,
|
|
3332
|
+
{ encoding: 'utf-8', timeout: 10000 }
|
|
3333
|
+
);
|
|
3334
|
+
const versionMatch = versionOutput.match(/versionName=([^\s]+)/);
|
|
3335
|
+
if (versionMatch) {
|
|
3336
|
+
appInfo.version = versionMatch[1];
|
|
3337
|
+
}
|
|
3338
|
+
} catch (e) {
|
|
3339
|
+
appInfo.version = 'Unknown';
|
|
3340
|
+
}
|
|
3341
|
+
|
|
3342
|
+
// Get app label/name
|
|
3343
|
+
try {
|
|
3344
|
+
const labelOutput = execSync(
|
|
3345
|
+
`adb -s ${serial} shell dumpsys package ${bundleId} | grep -A 1 "applicationInfo"`,
|
|
3346
|
+
{ encoding: 'utf-8', timeout: 10000 }
|
|
3347
|
+
);
|
|
3348
|
+
appInfo.name = bundleId;
|
|
3349
|
+
} catch (e) {
|
|
3350
|
+
appInfo.name = bundleId;
|
|
3351
|
+
}
|
|
3352
|
+
|
|
3353
|
+
// Get install location
|
|
3354
|
+
try {
|
|
3355
|
+
const pathOutput = execSync(
|
|
3356
|
+
`adb -s ${serial} shell pm path ${bundleId}`,
|
|
3357
|
+
{ encoding: 'utf-8', timeout: 10000 }
|
|
3358
|
+
);
|
|
3359
|
+
appInfo.path = pathOutput.replace('package:', '').trim();
|
|
3360
|
+
} catch (e) {
|
|
3361
|
+
appInfo.path = 'Unknown';
|
|
3362
|
+
}
|
|
3363
|
+
|
|
3364
|
+
appInfo.bundleId = bundleId;
|
|
3365
|
+
appInfo.platform = 'Android';
|
|
3366
|
+
|
|
3367
|
+
} else if (deviceObj.platform === 'ios') {
|
|
3368
|
+
// Get iOS app info
|
|
3369
|
+
const udid = deviceObj.udid;
|
|
3370
|
+
|
|
3371
|
+
try {
|
|
3372
|
+
// Try to get app info using ideviceinstaller
|
|
3373
|
+
const output = execSync(
|
|
3374
|
+
`ideviceinstaller -u ${udid} list --user | grep "${bundleId}"`,
|
|
3375
|
+
{ encoding: 'utf-8', timeout: 10000 }
|
|
3376
|
+
);
|
|
3377
|
+
|
|
3378
|
+
// Parse CSV format: BundleID, Version, Name
|
|
3379
|
+
const parts = output.split(',').map(p => p.trim().replace(/"/g, ''));
|
|
3380
|
+
if (parts.length >= 3) {
|
|
3381
|
+
appInfo.bundleId = parts[0];
|
|
3382
|
+
appInfo.version = parts[1];
|
|
3383
|
+
appInfo.name = parts[2];
|
|
3384
|
+
} else {
|
|
3385
|
+
appInfo.bundleId = bundleId;
|
|
3386
|
+
appInfo.name = bundleId;
|
|
3387
|
+
appInfo.version = 'Unknown';
|
|
3388
|
+
}
|
|
3389
|
+
} catch (e) {
|
|
3390
|
+
// Fallback
|
|
3391
|
+
appInfo.bundleId = bundleId;
|
|
3392
|
+
appInfo.name = bundleId;
|
|
3393
|
+
appInfo.version = 'Unknown';
|
|
3394
|
+
appInfo.error = 'Could not retrieve detailed info';
|
|
3395
|
+
}
|
|
3396
|
+
|
|
3397
|
+
appInfo.platform = 'iOS';
|
|
3398
|
+
}
|
|
3399
|
+
|
|
3400
|
+
res.json({ success: true, appInfo });
|
|
3401
|
+
|
|
3402
|
+
} catch (error) {
|
|
3403
|
+
res.json({
|
|
3404
|
+
success: false,
|
|
3405
|
+
error: error.message,
|
|
3406
|
+
appInfo: {
|
|
3407
|
+
bundleId: bundleId,
|
|
3408
|
+
platform: deviceObj.platform,
|
|
3409
|
+
error: 'Failed to get app info'
|
|
3410
|
+
}
|
|
3411
|
+
});
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3414
|
+
} catch (error) {
|
|
3415
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3416
|
+
}
|
|
3417
|
+
});
|
|
3418
|
+
|
|
3419
|
+
// Upgrade HTTP server to WebSocket
|
|
3420
|
+
let server;
|
|
3421
|
+
|
|
3422
|
+
function startServer(options = {}) {
|
|
3423
|
+
const port = options.port || PORT;
|
|
3424
|
+
const shouldOpenBrowser = options.browser !== false;
|
|
3425
|
+
const frontendUrl = 'https://devicely-ai.vercel.app';
|
|
3426
|
+
|
|
3427
|
+
console.log(`Frontend available at: ${frontendUrl}\n`);
|
|
3428
|
+
|
|
3429
|
+
return new Promise((resolve, reject) => {
|
|
3430
|
+
server = app.listen(port, () => {
|
|
3431
|
+
console.log(`Server running on port ${port}`);
|
|
3432
|
+
console.log(`WebSocket server ready`);
|
|
3433
|
+
|
|
3434
|
+
// Initial device discovery
|
|
3435
|
+
discoverDevices().then(devices => {
|
|
3436
|
+
console.log(`Discovered ${devices.length} devices`);
|
|
3437
|
+
|
|
3438
|
+
// Open browser if not disabled
|
|
3439
|
+
if (shouldOpenBrowser) {
|
|
3440
|
+
console.log(`\nš Opening browser to ${frontendUrl}...`);
|
|
3441
|
+
const open = require('open');
|
|
3442
|
+
open(frontendUrl).catch(err => {
|
|
3443
|
+
console.log(`\nš± Please open ${frontendUrl} in your browser`);
|
|
3444
|
+
});
|
|
3445
|
+
}
|
|
3446
|
+
|
|
3447
|
+
resolve({ port, devices });
|
|
3448
|
+
}).catch(reject);
|
|
3449
|
+
});
|
|
3450
|
+
|
|
3451
|
+
server.on('upgrade', (request, socket, head) => {
|
|
3452
|
+
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
3453
|
+
wss.emit('connection', ws, request);
|
|
3454
|
+
});
|
|
3455
|
+
});
|
|
3456
|
+
|
|
3457
|
+
server.on('error', reject);
|
|
3458
|
+
});
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
function stopServer() {
|
|
3462
|
+
return new Promise((resolve) => {
|
|
3463
|
+
if (server) {
|
|
3464
|
+
server.close(resolve);
|
|
3465
|
+
} else {
|
|
3466
|
+
resolve();
|
|
3467
|
+
}
|
|
3468
|
+
});
|
|
3469
|
+
}
|
|
3470
|
+
|
|
3471
|
+
// Export for CLI usage
|
|
3472
|
+
module.exports = {
|
|
3473
|
+
startServer,
|
|
3474
|
+
stopServer
|
|
3475
|
+
};
|
|
3476
|
+
|
|
3477
|
+
// Start server if run directly (not imported as module)
|
|
3478
|
+
if (require.main === module) {
|
|
3479
|
+
startServer().catch(err => {
|
|
3480
|
+
console.error('Failed to start server:', err);
|
|
3481
|
+
process.exit(1);
|
|
3482
|
+
});
|
|
3483
|
+
}
|