devicely 2.1.4 ā 2.1.6
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 -1
- package/lib/server.js +3485 -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/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_wireless +0 -0
- package/scripts/shell/connect_android_wireless_multi_final +0 -0
- package/scripts/shell/connect_ios_usb +0 -0
- package/scripts/shell/connect_ios_usb_multi_final +0 -0
- package/scripts/shell/connect_ios_wireless_multi_final +0 -0
- package/scripts/shell/create_production_scripts +0 -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/ios_device_control +0 -0
- package/scripts/shell/organize_project +0 -0
- package/scripts/shell/pre-publish-check +0 -0
- package/scripts/shell/publish +0 -0
- package/scripts/shell/publish-to-npm +0 -0
- package/scripts/shell/setup +0 -0
- package/scripts/shell/setup_android +0 -0
- package/scripts/shell/start +0 -0
- package/scripts/shell/sync-to-npm-package-final +0 -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_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,3485 @@
|
|
|
1
|
-
const _0x50607=_0x46ca;(function(_0x4f8fc1,_0x580a99){const _0x1b9b0f=_0x46ca,_0x5a0371=_0x4f8fc1();while(!![]){try{const _0x3146c1=-parseInt(_0x1b9b0f(0x1a4))/0x1+-parseInt(_0x1b9b0f(0xf4))/0x2*(-parseInt(_0x1b9b0f(0x6bd))/0x3)+-parseInt(_0x1b9b0f(0x455))/0x4+parseInt(_0x1b9b0f(0x57c))/0x5*(parseInt(_0x1b9b0f(0x48f))/0x6)+parseInt(_0x1b9b0f(0x4e1))/0x7+-parseInt(_0x1b9b0f(0x39e))/0x8+parseInt(_0x1b9b0f(0x565))/0x9;if(_0x3146c1===_0x580a99)break;else _0x5a0371['push'](_0x5a0371['shift']());}catch(_0x2fe29f){_0x5a0371['push'](_0x5a0371['shift']());}}}(_0x3c82,0xb3b32));const path=require('path');require('dotenv')[_0x50607(0x441)]({'path':path[_0x50607(0x4a3)](__dirname,'../../.env')});const express=require(_0x50607(0x130)),cors=require('cors'),{spawn}=require(_0x50607(0x2a3)),WebSocket=require('ws'),fs=require('fs')[_0x50607(0x521)],AIProviderManager=require(_0x50607(0x1f9));let discoverAllDevices;try{({discoverAllDevices}=require(_0x50607(0x30c)));}catch(_0x208469){({discoverAllDevices}=require(_0x50607(0x3b0)));}const {execSync}=require(_0x50607(0x2a3)),app=express(),PORT=process.env.PORT||0xbb9;app[_0x50607(0x39a)](cors()),app[_0x50607(0x39a)](express[_0x50607(0x573)]());const frontendPath=require('fs')[_0x50607(0x4d6)](path[_0x50607(0x4a3)](__dirname,_0x50607(0x25b)))?path[_0x50607(0x4a3)](__dirname,_0x50607(0x25b)):path[_0x50607(0x4a3)](__dirname,_0x50607(0x10b));app[_0x50607(0x39a)](express[_0x50607(0x2a9)](frontendPath));const _0x3268f2={};_0x3268f2[_0x50607(0x705)]=!![];const wss=new WebSocket['Server'](_0x3268f2),aiManager=new AIProviderManager();let connectedDevices=[],activeConnections=new Map(),wdaProcesses=new Map(),androidSessions=new Map();function findConfigFile(_0x3d8ca1){const _0x4d5ca7=_0x50607,_0x4a3edb={'XYboZ':_0x4d5ca7(0x353),'PhKEf':function(_0x275614,_0x2af3ea){return _0x275614(_0x2af3ea);},'JKjZR':'../config/'};let _0x5198ef=path[_0x4d5ca7(0x4a3)](__dirname,_0x4a3edb[_0x4d5ca7(0x2d8)],_0x3d8ca1);if(_0x4a3edb[_0x4d5ca7(0x53e)](require,'fs')[_0x4d5ca7(0x4d6)](_0x5198ef))return _0x5198ef;_0x5198ef=path[_0x4d5ca7(0x4a3)](__dirname,_0x4a3edb[_0x4d5ca7(0x182)],_0x3d8ca1);if(_0x4a3edb[_0x4d5ca7(0x53e)](require,'fs')['existsSync'](_0x5198ef))return _0x5198ef;return path[_0x4d5ca7(0x4a3)](__dirname,_0x4a3edb[_0x4d5ca7(0x2d8)],_0x3d8ca1);}function findScriptFile(_0x3f18c7){const _0x4f99d8=_0x50607,_0x142cd2={'qEzoh':_0x4f99d8(0x353),'IsNQT':_0x4f99d8(0x661),'JNauJ':function(_0x1bc667,_0x2e2489){return _0x1bc667(_0x2e2489);},'JvQpi':function(_0x569b53,_0x407905){return _0x569b53(_0x407905);}};let _0x59e254=path[_0x4f99d8(0x4a3)](__dirname,_0x142cd2['qEzoh'],_0x3f18c7);if(require('fs')[_0x4f99d8(0x4d6)](_0x59e254))return _0x59e254;_0x59e254=path[_0x4f99d8(0x4a3)](__dirname,_0x142cd2[_0x4f99d8(0x176)],_0x3f18c7);if(_0x142cd2[_0x4f99d8(0x3d3)](require,'fs')[_0x4f99d8(0x4d6)](_0x59e254))return _0x59e254;const _0x210323=_0x3f18c7[_0x4f99d8(0x203)](/\.sh$/,'');_0x59e254=path[_0x4f99d8(0x4a3)](__dirname,_0x142cd2[_0x4f99d8(0x176)],_0x210323);if(_0x142cd2[_0x4f99d8(0x5df)](require,'fs')[_0x4f99d8(0x4d6)](_0x59e254))return _0x59e254;return path[_0x4f99d8(0x4a3)](__dirname,_0x4f99d8(0x353),_0x3f18c7);}const DEVICE_CONFIG=findConfigFile(_0x50607(0x217)),SESSION_MAP_FILE=path[_0x50607(0x4a3)](require('os')[_0x50607(0x535)](),_0x50607(0x2fe)),APPS_CONFIG=findConfigFile('apps_presets.conf'),WIRELESS_SCRIPT_PATH=findScriptFile(_0x50607(0x6f6)),USB_SCRIPT_PATH=findScriptFile(_0x50607(0x215)),ANDROID_WIRELESS_SCRIPT_PATH=findScriptFile(_0x50607(0x641)),ANDROID_USB_SCRIPT_PATH=findScriptFile('android_device_control.sh'),RECORDINGS_DIR=path['join'](__dirname,'../../recordings'),SCREENSHOTS_DIR=path[_0x50607(0x4a3)](__dirname,'./screenshots');let currentRecording=null,isRecording=![],isReplaying=![],replayAborted=![];async function startUIAutomator2Session(_0x547ecc,_0x3136f3){const _0x2f6308=_0x50607,_0x1bccc4={'iEWiX':_0x2f6308(0x39d),'hfIFn':_0x2f6308(0x45d),'JlxAb':function(_0x340c8a,_0x456bcf,_0x2c45ab){return _0x340c8a(_0x456bcf,_0x2c45ab);},'NWONN':_0x2f6308(0x342),'cIgQs':function(_0x29b959,_0x2e9500,_0x382e4c,_0x4a4876){return _0x29b959(_0x2e9500,_0x382e4c,_0x4a4876);},'DYbLp':_0x2f6308(0x70e),'tOwdz':_0x2f6308(0x5cd),'qZMuI':function(_0x3687f7,_0xd3eecf){return _0x3687f7(_0xd3eecf);},'KcwjK':_0x2f6308(0x479),'BIlRZ':function(_0x20ad74,_0x50ee71){return _0x20ad74!==_0x50ee71;},'tSqeA':_0x2f6308(0x626),'nOOVY':_0x2f6308(0x47c),'KrCOD':_0x2f6308(0xb4),'NGJuN':function(_0x5a4016,_0x4b6099){return _0x5a4016+_0x4b6099;},'XrYYE':_0x2f6308(0x2a7),'PVcAp':_0x2f6308(0x177)};console[_0x2f6308(0x37a)](_0x2f6308(0x434)+_0x3136f3+'\x20('+_0x547ecc+_0x2f6308(0x448));try{if(_0x1bccc4[_0x2f6308(0x1e9)]!==_0x1bccc4[_0x2f6308(0x1e9)]){const _0x588c67=_0x518adc['match'](/Val:([^\s]+)/);if(_0x588c67)_0x14eb06[_0x2f6308(0x55d)]=_0x588c67[0x1];}else{let _0x449c27=0x2008;while(!![]){try{_0x1bccc4[_0x2f6308(0x115)](execSync,_0x2f6308(0x25a)+_0x449c27,{'stdio':_0x1bccc4[_0x2f6308(0x4bb)]}),_0x449c27++;}catch{break;}}console['log']('š”\x20Using\x20port\x20'+_0x449c27+_0x2f6308(0x60f)+_0x3136f3);const _0x392d11=_0x1bccc4[_0x2f6308(0x3a4)](spawn,_0x1bccc4[_0x2f6308(0x196)],['-s',_0x547ecc,_0x2f6308(0x2c5),'am',_0x1bccc4[_0x2f6308(0x40a)],'-w',_0x2f6308(0x3cc)],{'detached':!![],'stdio':_0x1bccc4[_0x2f6308(0x4bb)]});_0x392d11['unref'](),await new Promise(_0x9c7ee7=>setTimeout(_0x9c7ee7,0x7d0)),_0x1bccc4[_0x2f6308(0x240)](execSync,'adb\x20-s\x20'+_0x547ecc+_0x2f6308(0x287)+_0x449c27+_0x2f6308(0x3ec)),await new Promise(_0x36b910=>setTimeout(_0x36b910,0x7d0));const _0x288449=require(_0x2f6308(0x6c6)),_0x36a027={};_0x36a027[_0x2f6308(0xba)]=_0x1bccc4[_0x2f6308(0x402)],_0x36a027[_0x2f6308(0x571)]='UiAutomator2',_0x36a027[_0x2f6308(0x6bb)]=_0x547ecc;const _0x92c45f={};_0x92c45f['alwaysMatch']=_0x36a027;const _0x4b7ef1={};_0x4b7ef1[_0x2f6308(0x394)]=_0x92c45f;const _0x539150=await _0x288449[_0x2f6308(0x633)](_0x2f6308(0x1f5)+_0x449c27+_0x2f6308(0x308),_0x4b7ef1),_0x49d24e=_0x539150['data'][_0x2f6308(0x55d)][_0x2f6308(0x75c)]||_0x539150[_0x2f6308(0x49b)][_0x2f6308(0x75c)],_0x529fe6={};_0x529fe6[_0x2f6308(0x75c)]=_0x49d24e,_0x529fe6[_0x2f6308(0x3d1)]=_0x449c27,_0x529fe6[_0x2f6308(0x110)]=_0x392d11[_0x2f6308(0x3b9)],_0x529fe6[_0x2f6308(0x72a)]=_0x3136f3,androidSessions['set'](_0x547ecc,_0x529fe6);try{if(_0x1bccc4[_0x2f6308(0x31b)](_0x1bccc4[_0x2f6308(0x400)],_0x1bccc4[_0x2f6308(0x382)])){let _0x5bbccd='';try{_0x5bbccd=await fs[_0x2f6308(0x642)](SESSION_MAP_FILE,_0x1bccc4[_0x2f6308(0x19a)]);}catch(_0x44989e){}const _0x404408=_0x5bbccd['split']('\x0a')['filter'](_0x164381=>_0x164381&&!_0x164381['startsWith'](_0x547ecc+':'));_0x404408['push'](_0x547ecc+':'+_0x49d24e+':'+_0x449c27),await fs[_0x2f6308(0x4b5)](SESSION_MAP_FILE,_0x1bccc4[_0x2f6308(0x2fd)](_0x404408[_0x2f6308(0x4a3)]('\x0a'),'\x0a')),console[_0x2f6308(0x37a)](_0x2f6308(0x73f)+_0x547ecc+':'+_0x49d24e+':'+_0x449c27);}else{const _0x208aa6={};_0x208aa6[_0x2f6308(0x492)]=![],_0x208aa6['error']=_0x3e6035[_0x2f6308(0xef)],_0xf35161[_0x2f6308(0x160)](0x1f4)[_0x2f6308(0x573)](_0x208aa6);}}catch(_0x577233){if(_0x1bccc4[_0x2f6308(0x2ef)]!==_0x2f6308(0x2a7)){const _0xb42d04=_0x5e9691[_0x2f6308(0x430)](),_0x53e5a9=_0xcd734b['getCurrentProvider'](),_0x4bd5d7={};_0x4bd5d7[_0x2f6308(0x492)]=!![],_0x4bd5d7['providers']=_0xb42d04,_0x4bd5d7[_0x2f6308(0x335)]=_0x53e5a9['id'],_0x39bf4b[_0x2f6308(0x573)](_0x4bd5d7);}else console[_0x2f6308(0x618)](_0x2f6308(0x4f9)+_0x577233[_0x2f6308(0xef)]);}console[_0x2f6308(0x37a)](_0x2f6308(0x1a2)+_0x3136f3),console[_0x2f6308(0x37a)](_0x2f6308(0x6d2)+_0x49d24e),console[_0x2f6308(0x37a)](_0x2f6308(0x677)+_0x449c27);const _0x293ec2={};return _0x293ec2[_0x2f6308(0x492)]=!![],_0x293ec2['sessionId']=_0x49d24e,_0x293ec2[_0x2f6308(0x3d1)]=_0x449c27,_0x293ec2;}}catch(_0xac28c2){if(_0x1bccc4[_0x2f6308(0x31b)](_0x1bccc4[_0x2f6308(0x172)],'mOiXR')){_0x2daec0['log'](_0x1bccc4[_0x2f6308(0x506)]),_0x5e87f6['log'](_0x2f6308(0x5c6),_0x28aebe[_0x2f6308(0x62d)](_0x2e7f3b,null,0x2));const _0x55f1ce={};return _0x55f1ce[_0x2f6308(0x492)]=![],_0x55f1ce[_0x2f6308(0x618)]=_0x2f6308(0x58f),_0x2b8f13['status'](0x1f4)[_0x2f6308(0x573)](_0x55f1ce);}else{console['error']('ā\x20Failed\x20to\x20start\x20UIAutomator2\x20for\x20'+_0x3136f3+':',_0xac28c2['message']);const _0x29d076={};return _0x29d076['success']=![],_0x29d076['error']=_0xac28c2[_0x2f6308(0xef)],_0x29d076;}}}async function stopUIAutomator2Session(_0x8bc6a1,_0x446a19){const _0x4172b2=_0x50607,_0xbb4b38={'jZiYw':_0x4172b2(0x68d),'mvQSB':_0x4172b2(0x5bc),'HVCVY':function(_0xff7cf9,_0x1e5125){return _0xff7cf9===_0x1e5125;},'xgADA':_0x4172b2(0x3a6),'HAbXI':function(_0x17fed6,_0x1faba5){return _0x17fed6&&_0x1faba5;},'okqBp':function(_0x5baff2,_0x5e516e){return _0x5baff2===_0x5e516e;},'svwGc':'devices_updated','iOyGx':_0x4172b2(0x6d7),'aHiGF':function(_0x2d960d,_0xa278ca){return _0x2d960d!==_0xa278ca;},'AyKuE':_0x4172b2(0x753),'HFygz':function(_0x15a371,_0x361fe0){return _0x15a371(_0x361fe0);},'GVQLe':_0x4172b2(0x6c6),'bLfje':_0x4172b2(0x516),'tOGWc':function(_0x276d39,_0x5263bf){return _0x276d39(_0x5263bf);},'GzhLC':function(_0x4e5829,_0x106d16){return _0x4e5829===_0x106d16;},'SzUQh':function(_0x26e8e2,_0x5e59d9){return _0x26e8e2===_0x5e59d9;},'TVwGW':_0x4172b2(0x1c1),'vYHGw':function(_0xc7eea4,_0x257171){return _0xc7eea4(_0x257171);},'BJAEf':function(_0x25f48e,_0x551ed6){return _0x25f48e(_0x551ed6);},'eXItU':function(_0x3cce16,_0x36253e){return _0x3cce16!==_0x36253e;},'PKsFM':_0x4172b2(0xb4),'VXLuD':_0x4172b2(0x379),'lQjOI':'qPGvc'};console[_0x4172b2(0x37a)]('š\x20Stopping\x20UIAutomator2\x20session\x20for\x20'+_0x446a19+'\x20('+_0x8bc6a1+_0x4172b2(0x448));try{const _0xa9c564=androidSessions[_0x4172b2(0x529)](_0x8bc6a1);if(!_0xa9c564){console[_0x4172b2(0x37a)]('ā ļø\x20\x20No\x20active\x20session\x20found\x20for\x20'+_0x446a19);const _0x364026={};return _0x364026[_0x4172b2(0x492)]=!![],_0x364026[_0x4172b2(0xef)]=_0x4172b2(0x122),_0x364026;}try{if(_0xbb4b38['aHiGF'](_0xbb4b38[_0x4172b2(0x361)],_0xbb4b38['AyKuE'])){_0x37fe6a[_0x4172b2(0x618)](_0xbb4b38['jZiYw']);const _0x37c89c={};return _0x37c89c[_0x4172b2(0x492)]=![],_0x37c89c['error']=_0xbb4b38[_0x4172b2(0x55e)],_0x8610cb['status'](0x190)[_0x4172b2(0x573)](_0x37c89c);}else{const _0xaa6fc6=_0xbb4b38['HFygz'](require,_0xbb4b38['GVQLe']);await _0xaa6fc6[_0x4172b2(0x6ee)](_0x4172b2(0x1f5)+_0xa9c564[_0x4172b2(0x3d1)]+_0x4172b2(0x12e)+_0xa9c564[_0x4172b2(0x75c)]),console[_0x4172b2(0x37a)](_0x4172b2(0x707)+_0x446a19);}}catch(_0x31141e){_0xbb4b38['HVCVY'](_0xbb4b38[_0x4172b2(0xee)],_0x4172b2(0x516))?console[_0x4172b2(0x37a)](_0x4172b2(0x592)+_0x31141e[_0x4172b2(0xef)]):(_0x1dcc4a[_0x3a20bc][_0x4172b2(0x160)]=_0xbb4b38[_0x4172b2(0x4de)],_0x3f76f6[_0x4172b2(0x41b)][_0x4172b2(0x224)](_0x368b0b=>{const _0x29408f=_0x4172b2;if(_0xbb4b38[_0x29408f(0x174)](_0x368b0b[_0x29408f(0x625)],_0x43f88f['OPEN'])){const _0x65217d={};_0x65217d['type']=_0x29408f(0x246),_0x65217d[_0x29408f(0x3d4)]=_0x25a15c,_0x368b0b['send'](_0x12dd79[_0x29408f(0x62d)](_0x65217d));}}));}try{_0xbb4b38[_0x4172b2(0x2f0)](execSync,_0x4172b2(0x358)+_0x8bc6a1+'\x20forward\x20--remove\x20tcp:'+_0xa9c564[_0x4172b2(0x3d1)]),console[_0x4172b2(0x37a)]('ā
\x20Port\x20forwarding\x20removed\x20for\x20'+_0x446a19);}catch(_0x620c4){if(_0xbb4b38[_0x4172b2(0x226)]('TUMvA',_0x4172b2(0x1b5)))console[_0x4172b2(0x37a)](_0x4172b2(0x550)+_0x620c4[_0x4172b2(0xef)]);else{const [_0x9e6c52,_0x3c5894]=_0x461848[_0x4172b2(0x19b)](',')[_0x4172b2(0x12b)](_0x2bf53b=>_0x2bf53b[_0x4172b2(0x3ea)]());if(_0xbb4b38['HAbXI'](_0x9e6c52,_0x3c5894)){const _0x27d984=_0x9e6c52[_0x4172b2(0x19b)]('.');if(_0xbb4b38[_0x4172b2(0x200)](_0x27d984[_0x4172b2(0x484)],0x2)){const [_0x5750f6,_0x18ebb3]=_0x27d984;if(!_0x4f9296[_0x5750f6])_0x1c0e96[_0x5750f6]={};_0x2895e1[_0x5750f6][_0x18ebb3]=_0x3c5894;}else{if(!_0x5bd6ad[_0x9e6c52])_0x41306a[_0x9e6c52]={};_0xb6636[_0x9e6c52]['common']=_0x3c5894;}}}}try{if(_0xbb4b38[_0x4172b2(0x57b)](_0xbb4b38['TVwGW'],'sdzqD')){if(_0x4fefa4[_0x4172b2(0x625)]===_0x4f75d8[_0x4172b2(0x467)]){const _0x5c0fcf={};_0x5c0fcf[_0x4172b2(0x2ba)]=_0xbb4b38[_0x4172b2(0x239)],_0x5c0fcf['devices']=_0x1f4456,_0x55db3a[_0x4172b2(0x65f)](_0x5b873d['stringify'](_0x5c0fcf));}}else _0xbb4b38[_0x4172b2(0xfb)](execSync,_0x4172b2(0x358)+_0x8bc6a1+'\x20shell\x20am\x20force-stop\x20io.appium.uiautomator2.server'),_0xbb4b38[_0x4172b2(0x120)](execSync,_0x4172b2(0x358)+_0x8bc6a1+_0x4172b2(0x262)),console[_0x4172b2(0x37a)]('ā
\x20UIAutomator2\x20server\x20stopped\x20on\x20'+_0x446a19);}catch(_0x274553){_0xbb4b38[_0x4172b2(0x5a8)]('UXRwu',_0x4172b2(0x149))?_0x4666e4[_0x4172b2(0x6b7)](_0xbb4b38['iOyGx'],_0x3e2f4c,_0x167fbd):console['log'](_0x4172b2(0x1a7)+_0x274553[_0x4172b2(0xef)]);}androidSessions['delete'](_0x8bc6a1);try{const _0x32a5b0=await fs[_0x4172b2(0x642)](SESSION_MAP_FILE,_0xbb4b38['PKsFM']),_0x4f9cca=_0x32a5b0['split']('\x0a')[_0x4172b2(0x5a2)](_0x24ca1c=>!_0x24ca1c[_0x4172b2(0x4ae)](_0x8bc6a1+':'));await fs[_0x4172b2(0x4b5)](SESSION_MAP_FILE,_0x4f9cca[_0x4172b2(0x4a3)]('\x0a')),console[_0x4172b2(0x37a)]('ā
\x20Session\x20file\x20updated\x20for\x20'+_0x446a19);}catch(_0x3475f0){if(_0xbb4b38[_0x4172b2(0x2ed)]!==_0xbb4b38['lQjOI'])console[_0x4172b2(0x37a)]('ā ļø\x20\x20Could\x20not\x20update\x20session\x20file:\x20'+_0x3475f0['message']);else return![];}console[_0x4172b2(0x37a)](_0x4172b2(0x726)+_0x446a19);const _0x44082b={};return _0x44082b[_0x4172b2(0x492)]=!![],_0x44082b;}catch(_0x2f9bd7){console[_0x4172b2(0x618)]('ā\x20Error\x20stopping\x20UIAutomator2\x20for\x20'+_0x446a19+':',_0x2f9bd7[_0x4172b2(0xef)]);const _0x10a271={};return _0x10a271[_0x4172b2(0x492)]=![],_0x10a271[_0x4172b2(0x618)]=_0x2f9bd7[_0x4172b2(0xef)],_0x10a271;}}async function loadDeviceConfig(){const _0x206efd=_0x50607,_0x4eddcc={};_0x4eddcc[_0x206efd(0x25c)]=_0x206efd(0x102),_0x4eddcc[_0x206efd(0x4e9)]=function(_0x67f9ec,_0x592575){return _0x67f9ec&&_0x592575;},_0x4eddcc[_0x206efd(0x106)]=function(_0x3a74ef,_0x3231ca){return _0x3a74ef===_0x3231ca;},_0x4eddcc['qkEwh']=_0x206efd(0x383),_0x4eddcc[_0x206efd(0x49d)]=_0x206efd(0x412),_0x4eddcc[_0x206efd(0x3e9)]=function(_0x570466,_0x12502f){return _0x570466>_0x12502f;},_0x4eddcc[_0x206efd(0x5d0)]=_0x206efd(0x443),_0x4eddcc[_0x206efd(0x419)]=_0x206efd(0x339),_0x4eddcc['NxCqG']=_0x206efd(0xb4),_0x4eddcc[_0x206efd(0xb3)]=_0x206efd(0x4b7);const _0x2c23ac=_0x4eddcc;try{const _0x11048d=await fs[_0x206efd(0x642)](DEVICE_CONFIG,_0x2c23ac['NxCqG']),_0x5993f0=_0x11048d[_0x206efd(0x19b)]('\x0a')['filter'](_0x5bcc21=>_0x5bcc21[_0x206efd(0x3ea)]()&&!_0x5bcc21[_0x206efd(0x4ae)]('#'))[_0x206efd(0x12b)](_0x41419d=>{const _0x28d6d8=_0x206efd,_0x537350=_0x41419d[_0x28d6d8(0x19b)](',')[_0x28d6d8(0x12b)](_0xf41807=>_0xf41807[_0x28d6d8(0x3ea)]()),[_0x2b9437,_0x5d3bfa,_0x11c8f2,_0x1d1e96,_0x4d4455]=_0x537350;let _0x38524c=_0x1d1e96||_0x2c23ac[_0x28d6d8(0x25c)];if(_0x2c23ac[_0x28d6d8(0x4e9)](!_0x1d1e96,_0x5d3bfa)){if(_0x2c23ac[_0x28d6d8(0x106)](_0x28d6d8(0x67a),_0x2c23ac[_0x28d6d8(0x73b)]))_0x5a673d[_0x28d6d8(0x733)]=_0x51f7a8[0x1];else{if(_0x5d3bfa[_0x28d6d8(0x185)](':')&&_0x5d3bfa[_0x28d6d8(0x600)](/^\d+\.\d+\.\d+\.\d+:\d+$/))_0x38524c=_0x2c23ac['KDzHm'];else{if(_0x5d3bfa['length']<0x14&&!_0x5d3bfa[_0x28d6d8(0x185)]('-'))_0x38524c=_0x2c23ac[_0x28d6d8(0x49d)];else _0x5d3bfa[_0x28d6d8(0x185)]('-')&&_0x2c23ac[_0x28d6d8(0x3e9)](_0x5d3bfa[_0x28d6d8(0x484)],0x1e)&&(_0x38524c=_0x2c23ac[_0x28d6d8(0x25c)]);}}}const _0x46d335={};return _0x46d335[_0x28d6d8(0x192)]=_0x2b9437,_0x46d335[_0x28d6d8(0x343)]=_0x5d3bfa,_0x46d335['ip']=_0x11c8f2||'',_0x46d335['platform']=_0x38524c,_0x46d335[_0x28d6d8(0x2ba)]=_0x4d4455||(_0x11c8f2?'wireless':_0x2c23ac[_0x28d6d8(0x5d0)]),_0x46d335[_0x28d6d8(0x160)]=_0x2c23ac['kLDwY'],_0x46d335;});return _0x5993f0;}catch(_0x5ec3c5){if(_0x206efd(0x4b7)===_0x2c23ac[_0x206efd(0xb3)])return console[_0x206efd(0x618)](_0x206efd(0x69f),_0x5ec3c5),[];else _0x1cf1fe=_0x3207e4[_0x206efd(0x1ec)][_0x206efd(0x19b)]('\x0a')[_0x206efd(0x5a2)](_0x21346c=>_0x21346c[_0x206efd(0x3ea)]());}}async function discoverDevices(){const _0x3b1d81=_0x50607,_0x36e1e2={'szNDU':'error','qmvnQ':_0x3b1d81(0x23b),'IefBQ':_0x3b1d81(0x18b),'IhBzq':_0x3b1d81(0x18f),'mBseI':_0x3b1d81(0x210),'uKMgY':_0x3b1d81(0x3a6),'DNaSU':function(_0x4c8467,_0x424737){return _0x4c8467!==_0x424737;},'CKgKk':_0x3b1d81(0x5e0),'lCvkn':_0x3b1d81(0x1b4),'mTcgs':function(_0x142185){return _0x142185();},'kpRWB':function(_0x382b78,_0x4b27ac){return _0x382b78(_0x4b27ac);}},_0x5d3de0=new Map();return connectedDevices[_0x3b1d81(0x224)](_0x234e28=>{const _0x561cca=_0x3b1d81;if(_0x36e1e2[_0x561cca(0x452)]!==_0x36e1e2[_0x561cca(0x6f9)])_0x5d3de0[_0x561cca(0x3df)](_0x234e28['udid'],{'status':_0x234e28[_0x561cca(0x160)],'sessionId':_0x234e28[_0x561cca(0x75c)]});else{const _0x57c272={};_0x57c272[_0x561cca(0x2ba)]=_0x36e1e2[_0x561cca(0x3d9)],_0x57c272[_0x561cca(0xef)]=_0x9554cc[_0x561cca(0xef)],_0x504889[_0x561cca(0x65f)](_0x381890['stringify'](_0x57c272));}}),connectedDevices=await _0x36e1e2['mTcgs'](discoverAllDevices),connectedDevices[_0x3b1d81(0x224)](_0x519939=>{const _0x5436d7=_0x3b1d81;if(_0x36e1e2[_0x5436d7(0x44a)]!==_0x5436d7(0x41a)){const _0x59e839=_0x5d3de0['get'](_0x519939[_0x5436d7(0x343)]);_0x59e839&&_0x59e839['status']===_0x5436d7(0x3a6)&&(_0x36e1e2[_0x5436d7(0x6e0)]===_0x36e1e2[_0x5436d7(0x6e0)]?(_0x519939[_0x5436d7(0x160)]=_0x36e1e2[_0x5436d7(0x50b)],_0x59e839[_0x5436d7(0x75c)]&&(_0x36e1e2[_0x5436d7(0x179)](_0x36e1e2[_0x5436d7(0x3db)],_0x36e1e2[_0x5436d7(0x413)])?_0x519939[_0x5436d7(0x75c)]=_0x59e839['sessionId']:_0x26c987[_0x5436d7(0x3a0)](_0xd87287))):_0xd28c11[_0x5436d7(0x37a)]('ā ļø\x20\x20iproxy\x20process\x20'+_0x58b5a3[_0x5436d7(0x4b4)]+_0x5436d7(0x6ec)));}else return _0x92efbf['log'](_0x5436d7(0x6ca)+_0x3ec366+'\x22\x20ā\x20\x22'+_0xe7cc4d+_0x5436d7(0x1e2)+_0x2e28e5+')'),_0x5436d7(0x184)+_0x2fb573+_0x3ba949;}),await _0x36e1e2[_0x3b1d81(0x2b8)](autoSaveUSBDevicesToConfig,connectedDevices),connectedDevices;}function _0x3c82(){const _0x4005d2=['ihnOzwXSigfTigzVCMnLlxn0B3aGAw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxi','zxjYB3i','y0HuvvO','wxLtu1e','cUkAOo+4JYaGrxjYB3i6ierLDMLJzxmGBM90ignVBM5Ly3rLzdOG','tfjMs2W','sLDRruq','4P2mifjLCgXHEsbJB21Tyw5Kia','u0Lhvevstq','EMfmsfy','ruHVs0O','zgXxz3i','tLzWChC','wu13B0G','CMvHzhLtDgf0zq','ANbUA1e','tNrOwfi','u29qsK4','D3besLe','CMDoBKW','B0PpsNe','rKjwq3C','C3rYAw5NAwz5','tgTeqMW','ic0GqurcifjLywr5iokCHq','qurcig5VDcbHDMfPBgfIBguUifbSzwfZzsbPBNn0ywXSiefUzhjVAwqGu0rlifbSyxrMB3jTlvrVB2XZlG','AMDNtNG','y29TBw9U','Cg9ZDa','BKLxBvm','yxbWCW','qK9Vq3i','AxnzCfG','uMTds2G','AM1HAfC','B0vOu04','wvvkAuG','lcbtDwnJzxnZoIa','uNrqsu0','v2fPDgvKia','l2fWAs9YzwnVCMrPBMDZl3nHDMu','thnswvq','yw5KCM9Pzf9KzxzPy2vFy29UDhjVBc5ZAa','CMvHzezPBgu','zxHPC3rPBMC','r1jpuv9bueLFs0vzpq','qMHxy0K','svbJqK8','8j+uJcbeAxnJB25Uzwn0Aw5NigzYB20G','BenTruq','AuLbr2K','A0D2sNy','8j+tPsbjBNn0ywXSAw5Nifvjqxv0B21HDg9YmIbVBIa','Dwrgruu','4PYfieTPBgXLzcb4y29Kzwj1AwXKigzVCIa','yLHMBue','r3fPBLm','r1nAD1q','ihnOzwXSihbTigXPC3qGCgfJA2fNzxmGltm','r0vu','y29TBwfUzf9VDxrWDxq','4P2mienVBw1HBMqG','iYbezxzPy2uGq29UzMLNDxjHDgLVBIaOqxv0BY11CgrHDgvKkqO','yNvUzgXLswq','DgvZDa','A3bcq0q','q09PC0m','CgDVzuK','vhjAsKy','tvPqrNa','sNbgrMW','ueLuB3O','C2vUza','tMfTzsbHBMqGy29TBwfUzhmGCMvXDwLYzwq','lI4VC2nYAxb0CY9ZAgvSBc8','s0H6DK8','4PYfieTPBgXLzcbPChjVEhKGzM9Yia','z3r2wuq','vKHKv3y','Dgv4Da','tuLtvfjbtf9bueLFs0vz','q29TBwfUzdOGiG','u0PjDKK','zfDtrNO','uLDfyNq','vvvWAvy','BfP4uKS','4P2mie5Vig91Dhb1Dcb0BYbWyxjZzq','cUkpUE+4JYaGu3rVChbPBMCGCMvWBgf5lI4UcG','rM9LD0u','q29UBMvJDgLUzYb0BYa','sNrTC2C','l3nLC3nPB24','DK9sr1G','Dg1YBxK','DMLZAwjSzq','icaGug9YDdOG','qK1Mtu4','zgLYBMfTzq','tKnnCvm','wNrzzgu','su5Wwuy','z2v0tg9JyxrVCNm','rMfPBgvKihrVigDLDcbvssbLBgvTzw50CY4GugXLyxnLigvUC3vYzsbvsuf1Dg9TyxrVCJiGAxmGAw5ZDgfSBgvKigzVCIbbBMrYB2LKigrLDMLJzxmU','q29Atwy','wNPyv1u','AxPTCvC','vxDtvwG','yxnnyNu','s0DNDfm','igzVCIbNzxrmB2nHDg9YCY4UlG','yxbRCW','s1HSy1u','u2nMC0S','AgfZ','4PQG77IpicbbueSGzMLSzxmGBM90igzVDw5KigLUigfUEsbLEhbLy3rLzcbSB2nHDgLVBG','4PYfief1Dg8TC2f2zwqG','cVcFJjaGt3bLBMLUzYbICM93C2vYihrVia','4P2mie5VigrLDMLJzsbWCM92AwrLzcbPBIbYzxf1zxn0','yLPzqNG','DwTmrKK','sfPQveq','sefqtge','ihzPysbxAuzPic0Gv0rbifn0yxj0zwqH','DurqBLO','C3rHCNrtzxj2zxi','l2fWCgL1Bs11Awf1Dg9TyxrVCJiTzhjPDMvYl25VzgvFBw9KDwXLCY9HChbPDw0TDwLHDxrVBwf0B3iYlxnLCNzLCI9HCgTZ','wwDoDNq','yLbWv3y','qw5bCwC','rKzpwe0','uxLNDxa','ru5qzha','u0nXvw4','serpDxu','DMDTqxK','rxjYB3iGBg9HzgLUzYbKzxzPy2uGy29UzMLNoG','yM9KEq','4PA277IpicbB','y0ziq2e','vLjrzKm','suq6','4P2miefeqIbLCNjVCJOG','BNPtAxq','4PQG77IpifDeqsbfCNjVCJOG','A2jirKS','DuXisM8','veznBem','lcbWBgf0zM9YBtOG','yKDtAK8','uvHWAee','tuzprvi','Ce9YB3q','vM9duei','qNjztui','t2Dfsxe','rfL2s3e','AvnQyNy','vMfSoG','rw5tBwC','zw1PDa','qMXOufO','AhvXEMC','BxrPBwu','yxbWAxvToNvKAwq','qLnNCei','m0fSCuHZEG','wMjesve','BgfIzwW','whbVs0q','t0T1Axm','q0nrsKC','t1LzzfC','vuLbDxrVBwf0B3iYiefqs3mGBM90igzVDw5KlIbqBgvHC2uGCNvUoIbHChbPDw0GzhjPDMvYigLUC3rHBgWGDwLHDxrVBwf0B3iY','z2L0AhvIx3rVA2vU','yxHPB3m','r0vnsu5jx0fqsv9lrvK9','tLfmD3q','CgPAu0K','icdWN5oXifjLC29SDMvKigfWCcbWCMvZzxq6ici','igrLDMLJzsHZks4UlG','DeXwvK4','tefZsvm','wwLNr20','EhPTu0O','ALzmBxy','zefbqvC','icaGu2vZC2LVBIbjrdOG','8j+uJcbeAxnJB25Uzwn0Aw5NiefmtcbKzxzPy2vZlI4U','AMDlugy','v3nWCLi','y29TBwfUzf9JB252zxj0zwq','y29UBMvJDgLVBG','ChHithy','rvntvfq','v2XNsKq','zeH2rhy','yuHvu1e','r2rMBMy','CLv0AfC','tez0uK8','BujZzuK','qLbKvNG','vMTvzNm','DeT1B0m','vMjUte0','rLfxBvi','tuzJvfG','DgLTzw91Da','z3fou3u','ignVBw1HBMrZkq','AwHKuu8','rMfPBgvKihrVigv4zwn1DguGDgfW','igfSCMvHzhKGC3rVChbLza','rgv2AwnLig5VDcbMB3vUza','zgvSzxrL','iYaGicaTiefUzhjVAwq6ievUywjSzsb3AxjLBgvZCYbbreiGzMLYC3qk','C3bnt3G','q3j1Ewq','zxvYt1u','uu1Ns0O','uM5ruwe','zNbOEue','y29UBMvJDf9PB3nFD2LYzwXLC3nFBxvSDgLFzMLUywWUC2G','zMLUza','8j+tPsbvsuf1Dg9TyxrVCJiGBM90igzVDw5Kig9Uia','swvMqLe','igrLDMLJzxmGy29TCgXLDgvKihn1y2nLC3nMDwXSEq','A0jxqMi','r0Lusfvcx1rps0vo','s3PKt2K','4P2mifvjqxv0B21HDg9YmIbPBNn0ywXSyxrPB24GzxjYB3i6','8j+uJsblAwXSAw5NifDeqsbMB3iGvurjrca','yxbWAxvTlxvPyxv0B21HDg9YmI1KCML2zxi','seDlquK','DffuDKG','Axnwuw8','4PYfifbHCNnLzca','BM9tzxj2zxi','yNjcBgG','4PYfifvjqxv0B21HDg9YmIbZzxnZAw9UigrLBgv0zwqGzM9Yia','zMX1B3K','z3PAsLi','yKXoveW','y3DfD2S','vfHPA00','y29OzxjLx2fWAv9RzxK','ywrI','EeroBNG','vLzHu0K','quTsB3q','BM90ztO','4PYfiefSBcbKzxzPy2vZigrPC2nVBM5Ly3rLza','EwDft1O','yMv0Cge','DxH3svO','igrLDMLJzsHZkq','D0PsC0q','twnMy3K','zhLtCKm','r1jpuv9bueLFs0vz','Ce5SvKS','CwXJr3a','vKr3wLK','z0jxt3C','Dw5SAw5R','lMPZB24','swXfru0','zeHcsKm','D2vcvvG','q1jzz1e','4PYfifvjqxv0B21HDg9YmIbZzxnZAw9Uihn0B3bWzwqGzM9Yia','wwXnsLy','qLbzDge','r3vIrw0','zgv2AwnLtMfTzq','Aw1Suve','EeLpDvq','DgnsD2K','zxPhuxy','A1DVB2i','tM8GDxnLCIbHChbZigzVDw5Kig9YihvUywjSzsb0BYbWyxjZzsbVDxrWDxq','cUkwTU+4JYaGrxHLy3v0Aw5NignVBw1HBMqG','tM5LzLG','DMvYC2LVBG','oJu1ntu','s2TiDeu','Bw9KzwW','y3vYBa','vujdtxi','v1H5Ahi','BwLKzfe','CwTfD2G','AK9Wuvm','vxnPBMCGAu9tifvtqIbZy3jPChqGzM9YoIa','4P2mienVBM5Ly3qGzxjYB3i6','4PYfifnLC3nPB24GzMLSzsb1CgrHDgvKoIa','r1HZBfC','4P2mierLDMLJzxmGBM90ignVBM5Ly3rLzdOGwW','qxHhCLC','zwTkuhu','CuDnD2W','AvfUD3q','ywnJzxnZ','4PQG77Ipicbdyw5UB3qGCMvHy2GG','rMfPBgvKihrVigDLDcbSB2nHDg9YCW','ls1TyxGTDgLTzq','tvrcAeO','icHvreLeoIa','tK9ezfy','C1HQzg0','qLvvshO','rxjYB3iGy3jLyxrPBMCGv0rbihnLC3nPB246','C3vNz2vZDgLVBG','B2zVDNG','CvDgtNu','AKz4wfq','l2fWAs9HAs9WCM92AwrLCG','vMDtBM8','BfrrsuG','zNvSzMLSBgvK','cUkpUE+4JYaGuMvWBgf5ihn0B3bWzwqGyNKGDxnLCGO','D0jpCNO','4PYfiezVDw5Kiefqs3mGAw46ia','qKLrz1G','C2vZC2LVBKLK','yM90Aa','DLvsyuq','wuvMAKW','y2TeqLi','B3bLBG','A0Pmtfe','svzWtfC','vhPys28','z3jVCv9HCgLFA2v5','lwrLC3rPBMf0Aw9U','wLjQCLK','zMLUywXdB21Tyw5K','vu14CuK','EezlrMS','8j+uJcbPChjVEhK6ia','lIbdAgvJAYbUzxr3B3jRignVBM5Ly3rPB24U','t3jPz2LUywWGzgv2AwnLCZOG','rK5kBKe','uMvWBgf5ihn0yxj0zwq','Aw5PDgLHBgL6zvbYB3zPzgvYCW','tKvpu04','qM10Awu','rxjYB3iGCMvHzgLUzYbYzwnVCMrPBMCG','AwrLDMLJzwLUC3rHBgXLCIaTDsa','z21lv24','BfvKy2C','AKXdDuC','CNfSz0C','thfSBvK','y29UBMvJDgLVBLr5Cgu','AhzWr3a','BLPkBMS','DLH3r3m','DxrMltG','BwLZDhjHBf9HCgLFA2v5','C0PuDKG','BgLIzvi','u2vYDMvYvvjmsgvYzq','t1rSyKG','CgXHDgzVCM1oyw1L','rMfPBgvKihrVigXPC3qGyxbWCZOG','u2zVsKC','r2v2re4','BM93','C2v0x2fPx3bYB3zPzgvY','cVcFLRhVUi8GqvbjoIbdBgLJA2LUzYbSB2nHDg9Yici','twHvsMC','A3zjsfe','Bw5isvK','CfPdqwW','CgfJA2fNztO','AvfjCvi','r3PowvC','wLzvy3q','4P2mifnJCMLWDcbLCNjVCJO','vw5RBM93BG','CMvHzgrPCG','AMnfDhq','wNfKBha','4PQG77IpicbPChjVEhKGChjVy2vZCYa','yKj5y0u','qwjlsMW','DgzVALq','zNHsy1e','wwXpExC','txv6y1i','DKfUANe','BMH1y2K','A1nKDg0','ywXS','tuLtvfjbtf9bueLFs0vzpq','8j+tOsbdB25Uzwn0ihjLCxvLC3qGCMvJzwL2zwqGzM9YigrLDMLJztO','rgv2AwnLig5VDcbMB3vUzcbVCIbUB3qGy29UBMvJDgvK','ALnbvNe','t3v0Chv0igXLBMD0AdO','wMPure0','D2zxswC','uuvhvKG','Cxbizhe','ruXwtgi','CMvJB3jKAw5Nx3n0yxj0zwq','B1rqAeK','CMvMCMvZAf9KzxzPy2vZ','EK5OwKW','q3bPyLi','y29UBMvJDa','yxfUAgC','zeLnBLu','CxLur0e','qKHcvvO','tM8Gy29UBMvJDgvKigrLDMLJzxmGzM91BMq','yKXMAMu','BwvZC2fNzq','uM5dCLi','uM9gyLC','zfLnt0i','wfLKt2C','mJm0mdyXnenytMTmEq','zLnmue8','rwjTrfO','CMvQzwn0zwq','rhnbvhe','qMz3qve','4PYtq2XPy2S','DLLir3C','l2fWAs9SB2nHDg9YCW','BuHXreq','B3jPz2LUywXdB21Tyw5K','CK9WtKS','iIdIHPiGiG','ug5rCNC','Aw9Z','qKjTz08','verOruC','ExDgzwO','uKjRDLi','u3rqAhy','zwvHsMe','vMXwB3u','s3bAtwS','lI9MCM9UDgvUza','rxjYB3iGyxv0BY1ZyxzPBMCGzgv2AwnLCZO','yKzvvum','ihnOzwXSigr1BxbZExmGCgfJA2fNzsa','tvP5wgO','C2vYDMvYugLK','4PQG77IpicbtzxnZAw9UignYzwf0Aw9UigzHAwXLzcWGD2LSBcbIzsbJCMvHDgvKig9UigzPCNn0ignVBw1HBMq','4P2miezHAwXLzcb0BYbZyxzLihnLC3nPB24GzM9Yia','uwHotxa','q3zQvMu','sMX4qwi','wwrPtva','C2L6zq','ugXLyxnLigLUC3rHBgWGBwfUDwfSBhKGDxnPBMC6ig5WBsbPBNn0ywXSic1NigfWCgL1Bs11Awf1Dg9TyxrVCJiTzhjPDMvY','wfrvv3K','yuPYB2y','zun1ueC','qLvmzhC','wfjsBMq','tg9JyxrVCIbUyw1Lig9YignVB3jKAw5HDgvZihjLCxvPCMvK','vxnLiefjoIa','qKPbrwy','wuj4EvG','tM8Gywn0AxzLihnLC3nPB24','ywTmB1u','r1bRExa','v3rPteG','C0HZEMq','icHZDgf0Dxm6ia','uujVvxC','icHWB3j0oIa','yuzkC2e','BwfW','u2vXDwvUDgLHBcbLEgvJDxrPB24Gy29TCgXLDgvK','ihbSyxrMB3jTkhmPoIa','l3DKl2H1yI9ZzxnZAw9UlW','CxrLuKW','zxHWCMvZCW','4PYfifn1y2nLC3nMDwXSEsbKAxnJB25Uzwn0zwqG','qMrlAhq','zhD6q3K','uMnJC0G','EKXHAha','q2PJB0e','C0PiBuq','sevVz2K','vxjgtMe','DgP3u3i','v2jrt3O','rxjYB3iGBg9HzgLUzYbYzwnVCMrPBMCG','EvvWrxe','rxjYB3iGCgfYC2LUzYbSB2nHDg9YigXPBMu6','se9prfO','CwHoy04','rgPRywC','ig5VDcbJB25Uzwn0zwqUifbSzwfZzsbJB25Uzwn0ihzPysbvu0iGB3iGzw5HyMXLihDPCMvSzxnZigrLyNvNz2LUzY4','BwTYBgW','ChjVDMLKzxjZ','wfj4zgO','we5owLi','l3DKl2H1yI9ZDgf0Dxm','D211ExO','vvHsD3u','BeTAsNO','zfLKzKe','4PQG77IpicbfEgLZDgLUzYbZzxnZAw9UigLUDMfSAwqSignYzwf0Aw5Nig5LDYbVBMuGzM9Yia','CwXkwvy','lIbqBgvHC2uGD2fPDcaXmc0XnsbZzwnVBMrZlI4U','te1wquq','BNbvDw8','BMf6tLu','iYbqBgf0zM9YBtOGAw9ZihWGyw5KCM9PzaO','qu1AzhG','CKjOC1y','sMrgCKi','u3j0Cuu','l2fWAs9Zzxr0Aw5NCY9KzxzPy2vZ','qwr5Ceu','lcbPBNn0ywXSAw5NlI4U','CxLZwwC','uwvXDfe','u2nYAxb0igv4zwn1DgLVBIbLCNjVCJO','wM50DgK','4P2mieLUDMfSAwqGzgv2AwnLig9IAMvJDdO','EMvwv0m','C3rHDhvZ','v2T5q3m','rgLOu0y','vLr3wKe','rMfPBgvKihrVignVBM5Ly3qGzgv2AwnLlIbqBgvHC2uGDxnLihrOzsbdB25Uzwn0igj1DhrVBIbMAxjZDc4','sMTIBK0','rwz0uLu','qvHnCvG','ExHwEe0','s29yCu4','yMfZzw5HBwu','ig5VDcbMB3vUzcbPBIbbrei','rufcA08','s3LMsuG','C2v0uhjVDMLKzxi','8j+uJsblAwXSAw5NihbYB2nLC3nLCYbVBIbWB3j0ia','AM9ougO','D0jfvLO','ufzJqxa','BLnowve','sfzdvLK','rNniDMu','sxnouvq','Bu9Pwfi','wuPHCxG','re5Hu1u','B1fMzhK','B3LXzeW','iIb8Fcb0CNvL','wfLtqLG','4PQG77IpifDeqsbfCNjVCIaO','l2fWAs9Zy3jLzw5ZAg90CY86zMLSzw5HBwu','t3b1s2G','lMfWCgL1Bq','sKTQwLi','swXoCeK','Bgf1BMnOia','Aw5JBhvKzxm','zMLSzxbHDgG','ihDPCMvSzxnZBhKGyxqG','Dg5YDhq','y0ThuM8','t0TNBMy','EhDWELy','zw5KvgLTzq','B0DkvMG','4P2miezHAwXLzcb0BYbZDgfYDcb4y29Kzwj1AwXKoIa','EeLcwwu','DxHurKK','tLLvDKm','BMfTzq','vhncExq','tM8Gywn0AxzLihjLy29YzgLUzW','qMPuuNO','rfLItha','zgTAv2m','sgXpB2K','z3bWCve','s3jdt0q','C3bSAxq','zeDzq0q','oJGXmdaVC3rHDhvZ','sw5gB2q','y2XHDwrLx2fWAv9RzxK','CMvHzezPBgvtEw5J','DLzrCKe','4PYfifvjqxv0B21HDg9YmIbZzxnZAw9UignYzwf0zwqGzM9Yia','A2DVrLK','ndi3nZyZyvrUr0Hi','A1bTDfy','rKzHr2K','4PQG77IpicbdB3vSzcbUB3qGC3rVCcbvsuf1Dg9TyxrVCJiGC2vYDMvYoIa','sLDbDxO','C3vQs1y','ignVBM5Ly3rLzcbKzxzPy2vZ','vxDJuKm','A2TSu1i','4PYfifnLC3nPB24Gy3jLyxrLzdOG','qxnYyMy','lI9HAvbYB3zPzgvYC0nVBMzPzW','yK1At04','rwXYAwy','ywzgC0q','s2XMwhi','q0PXs2u','vfvnDKe','tM8Gzgv2AwnLCYbMB3vUzc4GugXLyxnLihjLzNjLC2GGzgv2AwnLigXPC3qGyw5KihrYEsbHz2fPBI4','v3z4u0m','DNPeue0','quKGy29UDMvYDgLUzYbMB3iG','BwfUDwfS','D2rHu3rHCNrPBMC','D29suKO','tM8Gzgv2AwnLCYb0BYbKAxnJB25Uzwn0','CMvJB3jKAw5N','r0vnsu5jx0fqsv9lrvK','qMLlAuu','DNjLqK4','ignOyxjHy3rLCNm','ENnUsgy','wff0D0G','4PQG77IpicbxreeGC3rPBgWGC3rHCNrPBMCGzM9Yia','qKXLrwe','z1PnreO','u0rJALm','igrLDMLJzsHZksbHy3jVC3mG','yxndB2m','igzYB20Gqurc','A2LSBa','icaGtwfRzsbZDxjLigXPyMLTB2jPBgvKzxzPy2uGAxmGAw5ZDgfSBgvKoIbICMv3igLUC3rHBgWGBgLIAw1VyMLSzwrLDMLJzq','veL5Ew8','lI4VlI4VlMvUDG','AxrxreS','wuHJu2W','zw5Mwei','t0PQBMK','BwTKAxi','yuv2zgG','vu13CuK','8j+AGcbtDgfYDgLUzYbUzxCGvuLbDxrVBwf0B3iYihnLC3nPB24GB24G','zvnmsey','AfD0vhK','sgLzEeS','q0Xbvurfx0fqsv9lrvK','rLr3vNK','ExflyLy','thrvqNO','AwX0q3u','yMLus1m','ChLhDKy','iIaO','l2fWAs9KzxzPy2vZl2rPC2nVBM5Ly3q','s0LKrNC','DNjlz2y','zMXcqwW','vfngwha','ywLFChjVDMLKzxjFC2v0','AgzjrM4','vgfWigv4zwn1DgvKihn1y2nLC3nMDwXSEq','BMLws2K','y29TBwfUzhm','Bu1NrKO','A0z5sLq','Dxfwuu8','CfrACeu','BwvLv0O','ANzqCeO','seTIsMq','CNjgCwi','Ahr0CdOVl2XVy2fSAg9ZDdO','EfDHCvO','tuXZtgq','BgLmue8','lI9HAvbYB3zPzgvYCW','q2fUBM90ihjLywnOia','Awq9','uMvJB3jKAw5Nig5VDcbMB3vUza','vLPAELK','txjjEhO','zwLAtLq','B2TXqNa','zLrWA0G','wMLZzhG','CMvWBgfJzq','EfrqEwu','AMHcsfi','EwT5CuO','uurAB3O','EeLNsMG','BLH5s0u','B1nrq1e','CMvWzwf0','yLL5BxC','odeWma','AgfMweu','tgzjBwO','tNzHsfu','C1nLDKm','qNjLzKW','CMvJB3jKAw5NCW','y29UDMvYDenVBw1HBMq','y29UBMvJDf9PB3nFDxnIx211BhrPx2zPBMfSlNnO','wMLeB2O','zgv2AwnLCY5JB25M','A1fzAgu','zg92B3m','s2fQwuG','vMHvEha','Avnmr3e','icH3AxjLBgvZCYKUifbYB2nLC3mGsuq6ia','4PQG77IpicbdB3vSzcbUB3qGy2HLy2SGv0rbihn0yxr1CYWGyxr0zw1WDgLUzYb0BYbZDgfYDc4UlG','EKvrBxm','rgv2AwnLCZOGwW','vvDlALO','8j+tPIbfBNn1CMLUzYbvsuf1Dg9TyxrVCJiGAxmGAw5ZDgfSBgvKig9Uia','CKL2uMe','zM9YrwfJAa','suzSz3y','r3POtem','D2nYENm','vxnPBMCGAu9tihDPCMvSzxnZihnJCMLWDcbMB3i6ia','zgvJzMu','CvjJrK4','EefbCuC','rMfPBgvKihrVigDLDcbHChaGAw5MBW','B3rpsxy','4P2miefjignVBNzLCNnPB24GzMfPBgvKoIa','BhrwsNO','AKzJwLe','yNz0t3u','uwj0vgK','Cfbnu3e','y05Or3O','q1vVvhi','vgfYz2v0igrLDMLJzxmGCMvXDwLYzwq','rg93BMXVywrZl1DLyKrYAxzLCKfNzw50lteWlJiUmq','y09Hu0O','C3z3r2m','vxrZzxy','wKvhqxm','4P2miefqssbLCNjVCJO','AerLuMS','y2TAEwu','ufbOwwi','CvPnDuK','cVcFJQWGuMvWBgf5Aw5NignVBw1HBMqG','y3fkrKe','zgLZy29UBMvJDa','wffutey','qvbIDKq','zgv2AwnLC191CgrHDgvK','uMH6DgS','rvnhu20','4P2miezHAwXLzcb0BYbZDgfYDcbPChjVEhK6ia','venSChK','EMjfqMS','l2fWAs9HAs9WCM92AwrLCNm','mxWZFdr8mNWW','sLj4tfe','zxLVAg4','Eef4sNm','u2nYzwvUC2HVDcbUB3qGzM91BMq','svHwB0S','B0vHzhe','vhHnzgG','A1PUCLG','qujswLu','uvPfB2O','yurusu4','zwTAsum','BhnVzIaTAtO','lI4VzNjVBNrLBMqVyNvPBgq','r3j6Chq','iIbVBIbKzxzPy2u6ia','v2vIrhjPDMvYqwDLBNqUEgnVzgvWCM9Q','vMHttwe','rLvewMq','DNbVDwy','ihnOzwXSigfTigzVCMnLlxn0B3aGAw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxiUDgvZDa','rxjYB3iGBgLZDgLUzYbYzwnVCMrPBMDZoG','vfjmDNe','reLrA2O','qxHeuM0','l2fWAs9Zzxr0Aw5NCY9HAs1WCM92AwrLCNm','Au9t','qMD2s2C','qMHhzey','zNblBg0','xsbfEgvJDxrPBMC6ia','yvfPtgC','v0fjvca','CMDls3G','sK1rENu','yvLtA2e','u0PmyKi','zgv2AwnL','EYjJyxbHyMLSAxrPzxmIoNSIywX3yxLZtwf0y2GIoNT9Fx0','zufWDge','Ew9SzuK','tufYwfm','BMLIyMG','uxPLsu8','8j+tSsbxreeGka','u2nYAxb0igv4AxrLzcb3AxrOignVzguG','l2fWAs9YzwnVCMrPBMDZlZPMAwXLBMfTzq','u3jAr0m','lIbqCM9JzxnZieLeoIa','BM9Kzv9TB2r1BgvZ','yNjlv2O','4PYtrw4','q291BgqGBM90ihjLDhjPzxzLigrLDgfPBgvKigLUzM8','4PYfienVBw1HBMqG','Aw1Uv1m','C3vbA0y','B09hDeG','igzVCNDHCMqGDgnWoG','CgfYC2u','ELfIq1O','4P2mievYCM9YigrPC2nVBM5Ly3rPBMCGywXSigrLDMLJzxm6','svbit05ft1nFrevqte9ztuvovf9uqvjhrvq9mtqUma','C3PQEuS','rK5Krw8','r2TPAwK','igLUihLVDxiGyNjVD3nLCG','ihWGz3jLCcb2zxjZAw9UtMfTzq','EK16tKO','ChfzyK4','u2f2DuW','uKzOu2S','uxzhDLi','z3jztwG','tK1vy3q','iYak','yNzxvM0','C2nYzwvUC2HVDhm','vg90ywWGBgLUzxm6','txHswLC','lI4U','4P2mievYCM9YignOzwnRAw5NifDeqtOG','vKvnqwC','s2fJDxC','sND5u2G','y0f1u3a','y2HPBgrFChjVy2vZCW','DgLTzxn0yw1W','vvniEge','z2v0vgLTzq','zNDpCKq','whbmy0S','C3rHDgLJ','s3bHrLa','qM1kDuG','sNrlEMy','wNvitwW','sKPUD1e','rMHLCMi','tfb2Axm','icaGq29TBwfUzdOG','vLvcA2W','tK9rtMW','q0Xbvurfx0fqsv9lrvK9','rLvpCee','rK9Hz3e','s2zgDuy','A3bsv0i','ktOG','DhLWzq','8j+oRcbB','zxryAMW','y3HZsKW','CKXVqwy','ic0GqurcigrPC2nVBM5Ly3rLza','sNnLu1y','y2XPy2SGiG','igrLDMLJzxm','Dg9ju09tDhjPBMC','r01yyvC','C2HLBgW','rgv2AwnLigfUzcbIDw5KBguGsuqGCMvXDwLYzwq','t2vAtvy','AKjdwK8','C3rHCNrFCMvJB3jKAw5N','Dg9tDhjPBMC','Dg1oDKe','AfLAD2u','BNbTihjVB3qGlwC','z2vTAw5Px2fWAv9RzxK','8j+tSsbbBMrYB2LKigrLDMLJzsbKAxnJB25Uzwn0oIa','ugjWDue','Ahr0Chm6lY9KzxzPy2vSEs1HAs52zxjJzwWUyxbW','zMnfChG','tLjjvNK','qw5KCM9PzcbKzxzPy2uG','Cwf2y1i','vvP5zvm','B3bLBMfPx2fWAv9RzxK','wfLIB1O','igzHAwXLzdO','qNDSqui','r0LTENq','8j+tOsbezxzPy2uGsva6ia','ue1YAfa','l2fWAs9HBMrYB2LKl2LUC3rHBgWTDwLHDxrVBwf0B3iY','Aff4zwm','AunOA0y','A1LVwK0','vLz1vMq','D2rHu3rHCNrLza','DwHIEhC','Ew5Mvu0','vgfYz2v0igrLDMLJzxm6ia','AeDkDMG','tfDdCei','4P2miezHAwXLzdOG','BgPsuee','s1vUr1a','yxbWAxvTigrYAxzLCIbPBNn0ywXSihvPyxv0B21HDg9YmIaYpIyX','vLHmDuq','vgPTveO','whjzwuu','De9hv2m','rhDRBgO','CLfHuwi','qLDmAwe','DgfWia','4PYfifvjqxv0B21HDg9YmIbPBNn0ywXSzwqGC3vJy2vZC2z1BgX5ig9Uia','u2Hwy0K','rgTsAMq','veDLzKO','rMTfr0O','r0v4Ahm','ALbysvu','4O+ZifDHAxrPBMCG','tKDkDu4','zgv2AwnLBhLFyw5KCM9Pzf9ZzxnZAw9UCY5Tyxa','wurHvuq','tLzIuKW','4O+577IpicbszwnVCMrPBMCGC3rVChbLzdOG','8j+tGIbxreeGugf0AdOG','ugTWExe','wgHUrwu','iYbfEgfTCgXLigvUDhjPzxm6cG','BeTLzLG','4PYfiefjignVBNzLCNrLzcbJB21Tyw5KihrVoGO','l3DKl2H1yI9ZzxnZAw9U','txzPDuu','AefeDwW','ruLvsg4','lI9KzxzPy2vezxrLy3rPB24','rev1A3C','y0TuBM0','rhb2rhm','whzIsNC','v0vcu09ds0vuoIbszwnLAxzLzcbLEgvJDxrLx2nVBw1HBMq','4PYfifbHCNnLzcbHCYbku09olcbLBgvTzw50CZO','cVcFK7eGugXLyxnLig9Wzw4G','tM8Gzgv2AwnLCYbZCgvJAwzPzwq','C2LTtMG','l2fWAs9HChbZl3bYzxnLDhm','lxbYB2PLy3q','vuLywuW','4P2mie5VigrLDMLJzxmGzM91BMqGzM9YoIbB','y29TBwfUzf9LCNjVCG','qKLSuLO','CMvZDwX0','u2HfrfK','suXJBfq','AefRB3m','cVcFLRhVUi8GqvbjoIbuyxbWAw5Nigf0ignVB3jKAw5HDgvZicG','wgHus2S','rNbqEhC','zMDZz04','4P2miefUzhjVAwqGzgv2AwnLia','8j+uJcbtDgfYDgLUzYbPChjVEhKGzM9YihbVCNqGzM9YD2fYzgLUzY4UlG','B3jPz2LUywW','BNv3vvy','uNr3CgC','vNnYqLy','C3rVCf9YzxbSyxK','vevzseC','y2LRC2q','v2L0ww0','8j+AGcbtDgfYDgLUzYbxreeGzM9Yia','B0rXywe','t3LbsM8','BKLesuK','ruj5zfi','AgfWCMe','EMDbEw0','y3vYCMvUDa','v3zSwfC','DuvYqMe','q1nvrfO','Dw5RBM93BG','Cw1yqxK','zunyr1O','rMfPBgvKihrVignOzwnRifDeqsbZDgf0Dxm6ia','tvLKq0S','wKnWr3u','AgjhCu4','u3HAD2W','B1PyAgu','AwDUB3jL','DwrPza','u3LIDxC','cGRWN5kHifbSzwfZzsbJBgLJAYb0AguGiKnVBM5Ly3qIigj1DhrVBIbVBIbLywnOigrLDMLJzsbIzwzVCMuGCNvUBMLUzYbJB21Tyw5KCY4kcG','4PYfienVBM5Ly3rLzcb0BYa','uLvKv1e','ignVBM5Ly3rLzcaTifDeqsbszwfKEsek','l2fWAs9Zy3jLzw5ZAg90CY8','4PYfienSzwfUzwqGDxaGv0rbihbYB2nLC3nLCYbMB3iG','zfrWAfK','sun4vKi','zMLUzeLUzgv4','4PQG77Ipicb4y29Kzwj1AwXKihbYB2nLC3mG','zhn2rxy','uM9SDxK','EhntAgC','vuvethi','lI4VlI4V','xsbtverfuLi6ia','shvdzwm','4PQG77IpiePtt04GCgfYC2uGzMfPBgvKoG','AgvPz2H0','ywrIic1Zia','zLH4DgG','ru5YDxi','ic0Gu3rHCNrPBMCGv0rblI4U','rwDNENm','sxP4B24','zgDlue8','wK9Qy2K','AhvJu2C','qxLlDuu','DKXzrKi','we9JAui','rNjVBNrLBMqGyxzHAwXHyMXLigf0oIa','u0LbtM4','txfUv3a','tervr3m','CwDhz0m','C3nUwNy','svHbtMC','rwH6sMK','Ew5rBu8','q09irvjfx0fqsv9lrvK','AKHwvhO','v2vIrhjPDMvYqwDLBNrsDw5Uzxi','sKTrAKG','rMfPBgvKihrVigLUC3rHBgWGvuLbDxrVBwf0B3iYoIa','v0rbigLZihn0yxj0Aw5NigzVCIa','B0Lqsfq','rvDYyw8','tg5YDhC','l2fWAs9Zzxr0Aw5NCY9HCgKTy29UzMLN','oIaI','r2rdrKm','zMzyDM0','Bg9N','igXPC3qGls11C2vY','zgjdu1q','CKvAAwe','EMLsrLe','CMvJDxjZAxzL','uKvqtefzsu5hoIa','lI4Vy29UzMLNlW','BK9pvLK','BMv2v04','EefbAwG','qM5js3u','4PQG77Ipifvjqxv0B21HDg9YmIbPBNn0ywXSyxrPB24GzMfPBgvKig9Uia','y0vtzMq','BhmGiG','AeTevgq','xsbtverpvvq6ia','C3rKAw8','AwPzBfe','AxnszwnVCMrPBMC','zfLOCKe','thb3DNu','BwHSCM8','sNbwD08','vLPuv2O','ALLmDKq','y2fWywjPBgL0AwvZ','rgLZy29UBMvJDgvKigzYB20G','sLnpCLC','4PYtvMLZ','zMXRDgm','CvznEw4','DxnL','l2fWAs9YzwnVCMrPBMDZ','B0nNyLq','4P2mie5Vig91Dhb1DcbMB3vUzcbPBIbYzxn1BhrZ','mta2mdi1ntjvBKTHvgu','lNbUzW','y2XVC2u','CMfntKW','uLbswfq','DK5xww0','y0LNuxm','q1rSEw0','B25SAw5L','uenHzwK','qxv0BY1JB25Uzwn0Aw9UigzHAwXLzdOG','zLfMEei','iNn0yxrLiG','whfJDK8','y29VCMrPBMf0zxm','z2v0x2fPx3bYB3zPzgvYCW','4PYfifDeqsbZDgfYDgLUzYbMB3iG','ic0Gv0rbifjLywr5iokCHq','lI4VlI4Vzgv2AwnLrgv0zwn0Aw9U','B1LOwLm','EMvxANG','iYbvu0iGzgv2AwnLCYbHDxrVlwrLDgvJDgvKlIbbzgqGsvaGzM9YihDPCMvSzxnZignVBM5Ly3rPB24UcGO','y3jJwK8','sNfyD3i','qNjAqwG','zuXkv1K','s1HtAeC','CgLK','4PYfienSzwfUzwqGDxaGCg9YDca','txb0B2K','Du9yBNO','zxHLy3v0zunVBw1HBMqGzMfPBgvKoIa','CMvWBgf5x3jLy29YzgLUzW','ihWGz3jLCcaTqsaXicjHChbSAwnHDgLVBKLUzM8I','C3jxC00','yxbWsw5MBW','EfrouwS','uuPlzKe','ihWGEgfYz3mGA2LSBcaTosaYpI9KzxyVBNvSBcb8Fcb0CNvL','DuHIDMC','A2T5t1a','sgvXs0K','AhbLDw0','Evfqruu','Ahr0CdOVl2XVy2fSAg9ZDdO4mtaWl3n0yxr1CW','vvjlzu8','Aw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxiUDgvZDc9HBMrYB2LKEc50zxn0lNj1BM5LCI5bBMrYB2LKsLvUAxrsDw5Uzxi','vhjIywC','rKL6Awe','vMn5yuq','u2nYAxb0oIa','Cg9YDa','Buv3z28','sK5HDuO','zgv2AwnLCW','uwjKqu4','quKGuhjVDMLKzxi6ia','EeDwtgi','tNbStwu','C3Porfu','B2TTDw4','q0TNs2S','AKXqCeW','y2jWq0y','B1vowuS','C2v0','tvfHz0e','iIaYpIyX','t05Pz2G','vwrTtvi','zgT4Dem','rKD4Efu','swvnq3C','DLfzq24','zxHPDa','zLHlzhy','DhjPBq','C3vTBwfYEq','ihrJCdO2nZKW','igf0ia','8j+tPIbjBNn0ywXSAw5NihnLCNzLCIbbueS6ia','yLrevKO','iYaGicaTiefKzcbjucbHzgrYzxnZihrVigvUywjSzsb3AxjLBgvZCYbZDxbWB3j0igXHDgvYcG','DLDQyNa','CxrRA2K','tgnAquG','l2fWAs9Zy3jLzw5ZAg90CW','rxHLy3v0Aw9UigvYCM9YoG','wM9qqKC','ic0G','vfntzee','rgLZy292zxjLzca','BwPmDgO','oJu1ntuUlI4','EuLqz2q','t1H3sw0','tMv3ifDLyLnVy2TLDcbJB25Uzwn0Aw9U','uKHbExa','DfnXzue','BerYB2i','s2n3AKS','u2nYAxb0ihjLC3vSDdO','B1PgqKe','y29TBwfUza','wKjLteK','vKLeuNu','ALrrD2u','Ew14wKy','De93zhO','rw9mugy','B2rmA0C','uMvZDwX0CYbHCNjHEsbSzw5NDgG6ia','C3rKzxjY','uMvZDwX0ihn1y2nLC3m6ia','uvjbyNm','AgPoDxe','yw5KCM9Pza','Ben2A24','te1owLC','4P2mifDeqsbUB3qGCNvUBMLUzYbVBIa','rKTYwxu','yunyy3y','s1vKyxa','A0XeD1K','ywLfv28','y2XPzw50CW','t2fmAgi','zNLiCwq','Eu9MEvy','z1Dzuxy','igzVCNDHCMqGls1Yzw1VDMuGDgnWoG','8j+tSsbdCMvHDgLUzYbxreeGC2vZC2LVBIbMB3iG','vfHLugq','Evf2DKi','uMvZDwX0ihn0yxr1CZOG','q0Xdt3a','B0zXu0y','wuLxu0G','whLzDg4','vNvArgG','4P2miezHAwXLzcb0BYbZDgfYDcbvsuf1Dg9TyxrVCJiGzM9Yia','AMvVvwK','AfDXqxe','wKXOzKG','qw96C0y','CKfWz3O','z2v0qxzHAwXHyMXLuhjVDMLKzxjZ','4PYfie5LDYbZzxnZAw9UignYzwf0zwqGyw5KihnHDMvKoIa','icHqsuq6ia','EevRv2C','8j+AGcbtDgfYDgLUzYbvsuf1Dg9TyxrVCJiGC2vZC2LVBIbMB3iG','y1Pry2i','tunzz2S','4PYfiefUzhjVAwqGzgv2AwnLia','Ahr0CdOVlW','tKPtrK4','l2fWAs9YzwnVCMrPBMCVC3rHCNq','AuLwAvm','Bhvdsvq','v3rqsfi','ChvZAa','yLzLr20','t3nQtMG','y29UzMLN','AgrTAui','DxnI','zxHWB3j0CW','zgf0zq','thzRwvK','EwzyCu0','ks4UlG','AMPeDKu','swHcENe','AM1QsNm','v0XzreO','tM8GzxHLy3v0ywjSzsbKzxzPy2vZigzVDw5K','AgLwAhG','ChjVDMLKzxi','qKfODfq','AuLyt24','Cw12BLe','v2vIu29JA2v0ignVBM5Ly3rPB24Gy2XVC2vK','u0XYA2m','ntyWntKYAKXwENzO','t21lvg8','r3DwBxa','r1zMB3i','rxHLy3v0zwqG','DLryrxC','vuzczM4','D2HXwxu','wfPrEvK','DuTXCxy','CNDNwNi','nhWWFdn8mxWY','tezVtvy','uKvqtefzienptvbmrvrf','tujwvNu','s2LVDe8','rKncDvu','CMvZB3vYy2vjza','t1bftG','r1nTvKG','l2fWAs9JB252zxj0lwnVBw1HBMq','iYdWN5smifvtqIbervzjq0vtoIbbDxrVBwf0AwnHBgX5igrLDgvJDgvKigfUzcbZyxzLzcbOzxjLcG','vhjPzwqGCgf0Ahm6','wePrvvu','y3vrugO','zw5HyMXLza','DuTuuKC','4P2mievYCM9YoIa','weD2r1O','v1jmzha','rgv2AwnLig5HBwvZihjLy2vPDMvKoIbB','vg90ywW6ia','BeTPrgK','4PYfifDeqsbZDwnJzxnZzNvSBhKGC3rHCNrLzcbMB3iG','wuDYtgq','Awzssge','qw5KCM9Pza','Dw5Yzwy','uw1ctfG','ChP1uvq','y29TBwfUzf9JB21WBgv0zq','ANjYENy','rgv2AwnLCYbUB3qGy29UBMvJDgvKoIa','igLUC3rHBgWGlxiGiG','AhDAshy','r3PXDve','lIbnywTLihn1CMuGvvncigrLyNvNz2LUzYbPCYbLBMfIBgvKigfUzcbKzxzPy2uGAxmGB24GDgHLihnHBwuGBMv0D29YAY4','BgvUz3rO','DM50AeK','y0PMBw4','z25ir1O','C29YDa','whzewgi','DeHHve8','seTsBfm','uuDUs3y','s3LytwS','EgDguwe','mJe5ntK0wwnktwLf','z2vTAw5P','ihn1y2nLzwrLzcWG','C3vJy2vZCW','CgLWzq','rxjYB3iGy2HLy2TPBMCGv0rblIbqBgvHC2uGC3rHCNqGBwfUDwfSBhKGAw4GwgnVzguU','AeH1EwW','rxjYB3iGzgvSzxrPBMCGCMvJB3jKAw5Nia','z2fbCeC','4PYfifrVDgfSihbHCNnLzcbSB2nHDg9YCZOG','s2HoEui','wxvzwg8','zgf0yq','A2rQwLG','s0r6sg0','Cuf3B1i','EKLJz2G','qxzprui','iYbqAxHLBdGSmueYqJndneq1rtzglcXHBMrYB2LKlhvZyIaGicaGicaGicaGicaGicaGicaGicaOqw5KCM9Pzcbvu0iGlsbHDxrVlwrLDgvJDgvKkqO','qwDeAfO','AM9PBG','4PYfierPC2nVBM5Ly3rLzcbbBMrYB2LKigrLDMLJzsa','C3rYAw5N','A1v4tw0','ihzHBgLKigXVy2f0B3jZ','AuDrEKm','DgHLBG','uxDKsLm','8j+tVcbszwnVCMrPBMC6ia','y29UBMvJDgLUzW','qvblCYbUB3qGzM91BMqUifrYAwvKihrVihjLAw5ZDgfSBcbKCML2zxiUifbSzwfZzsbYDw46igfWCgL1BsbKCML2zxiGAw5ZDgfSBcb1Awf1Dg9TyxrVCJi','C3rHCNrZv2L0Aa','vfzHq2G','wLvcveW','rvDZveK','vKzmC1O','t2XnrvG','AxbYB3H5','D3jPDgvgAwXL','rwzotfG','B1zUEMK','rgv2AwnLig5HBwuGCMvXDwLYzwq','C3rVCf9YzwnVCMrPBMC','BLjfBhC','tLDptK4','rg95txO','l2fWAs9KzxzPy2vZl2nVBM5Ly3q','C01cAvi','EMvYDeq','zw5JB2rPBMC','t2TOsxK','ANfuzK4','Aw5KzxG','ENj6twS','ugXVtwy','ywXSu2v0DgXLza','rujyruG','y2f0y2G','weLytxi','vwTbzMu','zxHoy2q','Cg5NzwS','rhzgDxO','zLL1rgi','tgrbu00','D1b0sMm','y0T5sKO','zvv4Ew8','B3v0Chv0','vLnfC2G','q29TBwfUzhm6','zxHPC3rZu3LUyW','D2LKDgG','zg15r20','wunRrMC','CMfNAuK','r1fqz0W','EgnVzgvIDwLSza','ig5LDYbvu0iGzgv2AwnLkhmPihrVignVBMzPzW','EgDbree','y0vXr04','l2fWAs9HChbZl2XPC3q','mZi1mJCZoxDVshHcqG','zxHLy3v0zv9JB21Tyw5K','iYdWN5oHifDjuKvmrvntierfvKLdrvm6ie1HBNvHBgX5igfKzcb3AxrOieLqigfKzhjLC3mk','Aezgyw0','zMLSzw5HBwu','Au9tigfWChmGBgLZDcbLCNjVCJO','uKjTDfK','uvLgv1C','zg9Ssha','uMXuC2W','BMv2vg8','A09hvKu','wgjpu3m','vKHvBKm','mhWYFdf8m3W0','ufnmB3m','t0Dbr3K','z2noyNK','AePXB0C','twzXue4','z3LjEeS','DNjNwwC','A0fOz2e','uNjSuKO','4PQG77IpicbgywLSzwqGDg8GDxbKyxrLihnLC3nPB24GzMLSztOG','C0r3yuO','CMvWBgf5x2nVBxbSzxrL','wLLXD3y','qwHeCem','BfrxDwC','CgTPBgWGlwyGiMLWCM94Es4Q','zNfWzwW','q2fJAguGy29UDgvUDhm6','ihnJCMLWDcbNCM91ChmGy29TCgXLDgvK','quLFtu9eruW','vhvYsMm','4PYfienVBxbSzxrLzcbZDwnJzxnZzNvSBhKkcG','AuvxAvG','qM9wtMC','q1HeCM0','CMzZALK','sLPqsfK','DuTnz1K','B294wLi','DgTbDw8','uMzzq1e','ignVBw1HBMrZ','qwXKvvO','rxjYB3iGy2XLyw5PBMCGDxaGDhjHy2TLzcbWCM9JzxnZzxmGzM9Yia','reTPwui','C3rRqw0','4PYfienVBM5Ly3qGCMvZDwX0oG','qwrxA0y','EffLB1i','uMvWBgf5igfIB3j0zwqGyNKGDxnLCG','Egj1zfq','z1Pet2u','AvnPA2O','Ag9TzwrPCG','yK9TzKO','uhn0AfK','qxvPtuq','wePbvxC','8j+tNsbszwnVCMrLzcbJB21Tyw5KoIa','ChjVBwLZzxm','Bu9qrNO','iYbbssbqCM92AwrLCIbdB25MAwD1CMf0Aw9UcKfjx1bst1zjrevspq','t1bftKfjx0fqsv9lrvK','EwDLrhu','l2fWCgL1Bs9UB2rLx21VzhvSzxmVyxbWAxvTlxvPyxv0B21HDg9YmI1KCML2zxiVBM9Kzv9TB2r1BgvZl2fWCgL1Bs11Awf1Dg9TyxrVCJiTC2vYDMvYl2fWA3m','y2flALe','CgfYyw1Z','z2v0','EfHrAMW','Bg9JywXOB3n0','igXPC3qGls11C2vYihWGz3jLCcaI','y29UBMvJDgvK','Cw9rDfu','uMn3CNG','iYaGicaTigLpuZOGrgv2AwnLig11C3qGyMuGCgfPCMvKigLUifHJB2rLlcbxzwjeCML2zxjbz2vUDcbYDw5UAw5NcG','igLZignVBM5Ly3rLzcb2AweGqurc','tLb0Bxu','zMvvzKS','CgTPBgWGlwyGiNHJB2rLyNvPBgqUkG','Dg1WzgLY','rffmuxu','qvHrCgC','zML5z1y','8j+tSsbezxzPy2uGvurjrdOG','DwP6tLa','wuzmEwC','te1OBfK','DMzeuLO','ugHlrwy','4PYfienSzwfUzwqGDxaGAxbYB3H5igzVCIa','D1fMtgC','s0TAz1i','8j+tNsbgywXSyMfJAYb0BYb0zxH0ihbHCNnPBMCUlI4','yuL6rM0','Bg9JyxrVCNm','iYaGicaTiezVCM1HDdOGzgv2AwnLx25HBwuSDwrPzcXPCf9HzgrYzxnZlhbSyxrMB3jTlhDPCMvSzxnZcG','BeDttem','ruHAqwC','xsbqCM9JzxnZigvYCM9YoG','teflugu','vw9oBgm','D056t1y','BefAve8','D1zLyMu','qxzxEwO','8j+tGIbdAgvJA2LUzZOG','4PQG77IpicbdB3vSzcbUB3qGCMvTB3zLihbVCNqGzM9YD2fYzgLUzZOG','C3rKB3v0','Cgf0Aa','uLvkzLu','rxjYB3iGC2f2Aw5NihjLy29YzgLUzZO','BxmUlI4k','q054t2m','ufrQEKi','rM1Yt2C','Cgz2CNm','tgr3s2W','v3fSzfu','tLHwrgm','DMfSDwu','Bxzru0i','AhH5qMO','vLbct2C','4PYfiezVDw5Kia','rgv2AwnLCYbJB25MAwD1CMf0Aw9UihnHDMvK','EeHvqKy','4PYfifDeqsbHBhjLywr5ihj1BM5PBMCGzM9Yia','nZmWmtCWouzoBKrkqq','C2vUzezPBgu','DMDQDK4','yxP1wuG','CgXHDgzVCM0','sMnQue0','lIbqBgvHC2uGy2XPy2SGiKnVBM5Ly3qIigj1DhrVBIbVBIbLywnOigrLDMLJzsbMAxjZDc4','svzzyLK','4PYfiezPBhrLCMvKihrVia','iI9HChbPDw0TDwLHDxrVBwf0B3iYlxnLCNzLCI1Kzwj1zY1HBMrYB2LKvgvZDc5HCgSGmJ4Vzgv2l251BgWGFhWGzwnOBYaIiG','uwXYthK','l2fWAs9YzwnVCMrPBMCVCMvWBgf5','yxbWAxvToMf1Dg9TyxrPB25oyw1L','ls1JB25Uzwn0lxrPBwvVDxq','ANnVBG','sNL0quG','u05iCxy','rMfPBgvKihrVignVBM5Ly3qGDg8G','igzHAwXLza','rKTPAvO','sxDoCM8','BLruyLK','u3PvuwG','mJvmu0DYrMi','zKnowMu','uxD3v20','q29UBMvJDgvKihrVia','twT2yLy','BNPSANu','CxnSyum','EKjIwLu','uMHgv1a','u2vXDwvUDgLHBcbLEgvJDxrPB24GzMfPBgvKoIa','lxnJAgvTzq','y0vLsKK','zerJuKS','ic1S','DwvjBLK','CwHxvLu','sxHvEM8','zeHtr3a','swX3v2u','tM8GB3v0Chv0ihjLy2vPDMvKigzYB20Gzgv2AwnL','ze5KqM8','AgDAsfO','4PQG77IpicbdB3vSzcbUB3qGzgvSzxrLihnLC3nPB24GDMLHieHuvfa6ia','ALfUBMK','l2fWAs9YzwnVCMrPBMCVC3rVCa','8j+tPIbjBNn0ywXSAw5NihrLC3qGqvbloIa','qKrhA24','swX2uKK','Aw8UyxbWAxvTlNvPyxv0B21HDg9YmG','uhjVBwLZzs5HBgXtzxr0BgvKigvYCM9YoIa','wgL4sg8','twjIvM0','8j+tSsbxree6ia','q0f5A2q','C3rVCfnLCNzLCG','rMfPBgvKihrVihn0yxj0ihnLCNzLCJO','vML5zKO','C2zIs20','zMLSDgvY','t0XYqwi','v0Hwwei','BM90igfYCMf5','wMv1C3y','ignVBxbSzxrLzcbZDwnJzxnZzNvSBhK','zvHjDfu','EvPIAgK','zhjTDum','uvLwEve','DgTgEwe','yNrVBhe','l2fWAs9LEgvJDxrL','t1j3yva','uhLTywC','C2XPy2u','ywLFzxjYB3i','u29cwNe','BwfPBG','v2rutLy','sw52ywXPzcbKzxzPy2uGB2jQzwn0','yLLxuwW','EfzdEgW','CMvZDwX0CW','xsbqCM9JzxnZigvYCM9YoIa','yMzyyuG','tM8Gzgv2AwnLihbYB3zPzgvK','D2LYzwXLC3m','DK11vNa','uxzIu1C','DLzPu0i','A0rVu0i','vwT4u2i','vxn3vMO','Exvewhi','EgTKrwq','rNvSBcbYzxn1BhqGC3rYDwn0DxjLoG','se15Dgm','CMvWBgf5x2vYCM9Y','vu9prxu','y2XPy2THyMXL','C2vYAwfS','DgvQsLy','Aw5ZDhj1BwvUDa','l2fWAs9HChbZl2LUzM8','l2fWAs9KzxzPy2vZl2rPC2nVBM5Ly3qTywXS','DMPQwuK','swTgsLu','B0zpuu8','yNLKsKi','wfHey1O','s1bPAuq','wKPPtMS','zu9XteW','vhzOrvy','ic0Gv0rbihn0B3bWzwq','4PQG77IpicbdB3vSzcbUB3qGDxbKyxrLihnLC3nPB24GzMLSztOG','quLFufjpvKLervi','r2rWyNG','u0TsseC','Aff2suy','sNzrCgK','qu1REKq','qM5zs2W','Bg9JywXLq29TCgfYzq','uhndC0O','8j+uTcbszwnVCMrPBMCGC3rHCNrLzdOG','yuvuAKy','rxjYB3iGC3rVChbPBMCGvuLbDxrVBwf0B3iYihnLC3nPB246ia','ihnOzwXSihbTihbHDgGG','CvfIweS','vgXJruq','s0TezKW','yxvpvxG','ksbVBIbKzxzPy2u6ia','qunIyve','Bvbtsw4','z1Djvvy','q29TBwfUzhmGDg8GCMvWBgf5oIa','vg90ywWGy29TBwfUzhm6ia','rxjYB3iGBg9HzgLUzYbHChaGChjLC2v0CZO','Dfbhsu0','q0nMD2u','tujNuhu','rMLSzw5HBwuGCMvXDwLYzwq','rfrlt3y','BhnVzIaTDgK6','4PM777IpicbszxvZAw5Nigv4Axn0Aw5Nifvjqxv0B21HDg9YmIbZzxnZAw9Uig9Uia','B2zMBgLUzq','ic0GvuLbDxrVBwf0B3iYifjLywr5iokCHq','rKnAAMe','iYaGicaTie5VignVBMzPz3vYyxrPB24GBMvLzgvKigzVCIbvu0iGy29UBMvJDgLVBGO','sgPjtMW','vg90ywW6','Bwf0y2G','l3nLC3nPB24V','swH0Auu','lcbgywLSzwq6ia','whP6BKe','DM90Bue','s2fMzuq','DfzwEg0','vgXlz2e','reD0D0K','ANjfEwi','AgjhqKi','wwjRCeO','tgnJvKC','v0r1q0C','igzVCIa','qwXAB1u','D2fYBMLUzZO','vhbTuK8','Bu5Yy2e','AxLjtNm','CfPSB1m','AxnbCNjHEq'];_0x3c82=function(){return _0x4005d2;};return _0x3c82();}async function autoSaveUSBDevicesToConfig(_0x4f7d31){const _0x45dd28=_0x50607,_0x16dd93={'SxZwl':function(_0x3f5812,_0x318c37){return _0x3f5812===_0x318c37;},'xTPye':function(_0x3cb8bc){return _0x3cb8bc();},'cEeJI':'#\x20Device\x20Configuration\x20(Auto-updated)\x0a','rIvRa':'#\x20Format:\x20device_name,udid,ip_address\x0a','oYhZS':_0x45dd28(0x3b3),'nazNU':_0x45dd28(0x10c)};try{const _0x660e03=_0x4f7d31[_0x45dd28(0x5a2)](_0x2085ca=>_0x2085ca[_0x45dd28(0xb0)]===_0x45dd28(0x443));if(_0x16dd93[_0x45dd28(0x340)](_0x660e03[_0x45dd28(0x484)],0x0))return;const _0x594df6=await _0x16dd93[_0x45dd28(0x204)](loadDeviceConfig),_0xcf2d3b=new Set(_0x594df6[_0x45dd28(0x12b)](_0x248e56=>_0x248e56[_0x45dd28(0x343)])),_0x2c9a08=_0x660e03[_0x45dd28(0x5a2)](_0x5e867a=>!_0xcf2d3b['has'](_0x5e867a[_0x45dd28(0x343)]));if(_0x2c9a08[_0x45dd28(0x484)]===0x0)return;const _0x2cc5b2=[..._0x594df6,..._0x2c9a08['map'](_0x24136d=>({'name':_0x24136d[_0x45dd28(0x192)],'udid':_0x24136d[_0x45dd28(0x343)],'ip':''}))];let _0x13fe4b=_0x16dd93[_0x45dd28(0x587)];_0x13fe4b+=_0x16dd93[_0x45dd28(0x223)],_0x13fe4b+=_0x16dd93[_0x45dd28(0x3b1)],_0x2cc5b2[_0x45dd28(0x224)](_0x2e881d=>{const _0x228984=_0x45dd28,_0x3affe3=_0x2e881d['ip']||'';_0x13fe4b+=_0x2e881d[_0x228984(0x192)]+','+_0x2e881d['udid']+','+_0x3affe3+'\x0a';}),await fs[_0x45dd28(0x4b5)](DEVICE_CONFIG,_0x13fe4b),console['log'](_0x45dd28(0x68b)+_0x2c9a08[_0x45dd28(0x484)]+_0x45dd28(0x4dd));}catch(_0xf1762c){console[_0x45dd28(0x618)](_0x16dd93[_0x45dd28(0x151)],_0xf1762c);}}function checkDeviceConnectivity(_0x3ac412){const _0x40d65a=_0x50607,_0xdb651a={'FTwVy':function(_0x401549,_0x32f3a5){return _0x401549(_0x32f3a5);},'hbGBB':_0x40d65a(0x3aa),'cbNZN':function(_0x27d321,_0x75fb9e,_0x1b16fb){return _0x27d321(_0x75fb9e,_0x1b16fb);},'QwwWm':_0x40d65a(0x737),'RccsH':_0x40d65a(0x49b),'FOagq':_0x40d65a(0x3a0)};return new Promise(_0x303bf7=>{const _0x449a66=_0x40d65a,_0x393745={'gppqQ':function(_0x52496d,_0x5dcec3){const _0x4c9b27=_0x46ca;return _0xdb651a[_0x4c9b27(0x1dc)](_0x52496d,_0x5dcec3);}},_0x3e296a=_0xdb651a['cbNZN'](spawn,_0xdb651a[_0x449a66(0x57e)],['-s',_0x449a66(0x572),'2',_0x449a66(0x749),'3','http://'+_0x3ac412['ip']+_0x449a66(0x19d)]);let _0xd9b569='';_0x3e296a['stdout']['on'](_0xdb651a[_0x449a66(0x134)],_0xf53c7a=>{const _0x7893df=_0x449a66;_0xd9b569+=_0xf53c7a[_0x7893df(0x2ca)]();}),_0x3e296a['on'](_0xdb651a[_0x449a66(0x2b6)],_0xfcb927=>{const _0x3bb1c0=_0x449a66;_0xdb651a[_0x3bb1c0(0x1dc)](_0x303bf7,_0xd9b569[_0x3bb1c0(0x185)](_0xdb651a[_0x3bb1c0(0x60b)]));}),setTimeout(()=>{const _0x24a20d=_0x449a66;_0x3e296a['kill'](),_0x393745[_0x24a20d(0x199)](_0x303bf7,![]);},0xbb8);});}function loadAppPresets(){const _0x519547=_0x50607,_0x49aea9={'BpbDZ':_0x519547(0x4fb),'Gdfnf':_0x519547(0x13e),'bFUUC':_0x519547(0x2e8),'bYWQl':function(_0x4ec391,_0x1deb22){return _0x4ec391&&_0x1deb22;},'MFOER':function(_0xecc17b,_0x4c0bcd){return _0xecc17b===_0x4c0bcd;},'xzmSJ':function(_0xfde6ac,_0x874b6d){return _0xfde6ac!==_0x874b6d;},'vmykn':'LJEfT','iSlww':_0x519547(0x10a),'azuYH':function(_0x27c51a,_0xa7e70d){return _0x27c51a!==_0xa7e70d;},'wmuyz':_0x519547(0x3c6),'zeWjx':function(_0x4027b8,_0x10d9cb){return _0x4027b8(_0x10d9cb);},'hHuyl':_0x519547(0xb4)};try{if(_0x49aea9[_0x519547(0x568)](_0x49aea9[_0x519547(0x148)],_0x49aea9[_0x519547(0x148)])){const _0x257bcc={'type':_0x49aea9['BpbDZ'],..._0x103da5};_0x420aa6['send'](_0x29a80c['stringify'](_0x257bcc));}else{if(!_0x49aea9[_0x519547(0x3b2)](require,'fs')[_0x519547(0x4d6)](APPS_CONFIG))return{};const _0x1dfc50=require('fs')[_0x519547(0x1a0)](APPS_CONFIG,_0x49aea9[_0x519547(0x495)]),_0x4cc055={};return _0x1dfc50['split']('\x0a')[_0x519547(0x5a2)](_0x580def=>_0x580def[_0x519547(0x3ea)]()&&!_0x580def[_0x519547(0x4ae)]('#'))['forEach'](_0x3d1d38=>{const _0x394a7d=_0x519547,_0x246d69={};_0x246d69[_0x394a7d(0x101)]=_0x49aea9[_0x394a7d(0x6dd)];const _0x4fb6a8=_0x246d69;if(_0x49aea9[_0x394a7d(0x10d)]===_0x394a7d(0x584))_0xbb7c9a[_0x394a7d(0x618)](_0x4fb6a8[_0x394a7d(0x101)],_0x3d80f1,_0x4d331a);else{const [_0xf2bb32,_0x43c274]=_0x3d1d38[_0x394a7d(0x19b)](',')[_0x394a7d(0x12b)](_0x22a6ff=>_0x22a6ff[_0x394a7d(0x3ea)]());if(_0x49aea9[_0x394a7d(0x5b7)](_0xf2bb32,_0x43c274)){const _0x4e1c4b=_0xf2bb32[_0x394a7d(0x19b)]('.');if(_0x49aea9[_0x394a7d(0x6ae)](_0x4e1c4b[_0x394a7d(0x484)],0x2)){const [_0x2dbe36,_0x3d9701]=_0x4e1c4b;if(!_0x4cc055[_0x2dbe36])_0x4cc055[_0x2dbe36]={};_0x4cc055[_0x2dbe36][_0x3d9701]=_0x43c274;}else{if(_0x49aea9[_0x394a7d(0x6cf)](_0x49aea9['vmykn'],_0x49aea9['iSlww'])){if(!_0x4cc055[_0xf2bb32])_0x4cc055[_0xf2bb32]={};_0x4cc055[_0xf2bb32]['common']=_0x43c274;}else{const _0x344c13={};_0x344c13[_0x394a7d(0x492)]=![],_0x344c13[_0x394a7d(0x618)]=_0x2563f5[_0x394a7d(0xef)],_0x1d490f['status'](0x1f4)[_0x394a7d(0x573)](_0x344c13);}}}}}),_0x4cc055;}}catch(_0x2c8601){return console[_0x519547(0x618)](_0x519547(0x5f2),_0x2c8601),{};}}function resolveAppPreset(_0x6d762e,_0x24b31b){const _0x31f6f6=_0x50607,_0x4ee59d={'CNxOc':function(_0x18632a,_0x50a9ee){return _0x18632a||_0x50a9ee;},'ioQbe':function(_0x2df4c8,_0x4c0f14){return _0x2df4c8||_0x4c0f14;},'SKRHG':function(_0x3ecf83){return _0x3ecf83();},'mNrca':'tnjBc','sfhWU':_0x31f6f6(0x4f4)},_0x2b632c=_0x4ee59d[_0x31f6f6(0x5dd)](loadAppPresets),_0x58182f=_0x6d762e[_0x31f6f6(0x600)](/^launch\s+(\S+)(.*)$/);if(!_0x58182f)return _0x6d762e;const _0x32f2c6=_0x58182f[0x1],_0x393b59=_0x58182f[0x2];if(_0x32f2c6['includes']('.'))return _0x6d762e;if(_0x2b632c[_0x32f2c6]){if(_0x4ee59d[_0x31f6f6(0x613)]==='XIJIG'){if(_0x4ee59d[_0x31f6f6(0x556)](!_0x2f3100,!_0x51f3d9))return![];return _0x2ac7e7['commands']['push']({'timestamp':new _0x3176b7()['toISOString'](),'devices':_0x10108f,'originalCommand':_0x5d0015,'useAI':_0x26f643,'finalCommand':_0x4ee59d['ioQbe'](_0x327466,_0x34008c)}),_0x574f8e[_0x31f6f6(0x37a)](_0x31f6f6(0x520)+_0x328cb8+'\x20('+_0x187aaf[_0x31f6f6(0x1ec)][_0x31f6f6(0x484)]+'\x20total)'),!![];}else{const _0x4b02b0=_0x2b632c[_0x32f2c6];let _0x292cda;if(_0x4b02b0[_0x24b31b])_0x292cda=_0x4b02b0[_0x24b31b];else _0x4b02b0[_0x31f6f6(0x632)]&&(_0x292cda=_0x4b02b0['common']);if(_0x292cda){if(_0x31f6f6(0x247)!==_0x4ee59d['sfhWU'])return console[_0x31f6f6(0x37a)]('\x20\x20š±\x20Resolved\x20app\x20preset:\x20\x22'+_0x32f2c6+_0x31f6f6(0x100)+_0x292cda+_0x31f6f6(0x1e2)+_0x24b31b+')'),_0x31f6f6(0x184)+_0x292cda+_0x393b59;else _0x55d0c1=_0x31f6f6(0x57f)+_0x2640e1+_0x31f6f6(0x62f);}}}return _0x6d762e;}function executeCommand(_0x3eb98b,_0x408c54,_0x8e4152){const _0x13c55b=_0x50607,_0x1908e8={'ILclT':function(_0x10d818,_0x251b10){return _0x10d818(_0x251b10);},'GQPgL':function(_0x14470b,_0x141351){return _0x14470b===_0x141351;},'BwDRc':function(_0x33d862,_0x117177){return _0x33d862===_0x117177;},'lKiDi':_0x13c55b(0x463),'dZRhg':_0x13c55b(0x2ff),'nzlju':_0x13c55b(0x1b6),'FCZja':function(_0x4afa70,_0x5d7fda){return _0x4afa70>_0x5d7fda;},'qteRL':_0x13c55b(0x102),'USHxa':function(_0x22048d,_0x42c4dd,_0x2d1b4b,_0x193237,_0x160d64){return _0x22048d(_0x42c4dd,_0x2d1b4b,_0x193237,_0x160d64);},'TDhEG':function(_0x11b141,_0x325113){return _0x11b141!==_0x325113;},'PPhYb':'syajQ','tQTvH':function(_0x480f7e,_0x277ce5,_0x2081db,_0x47b871,_0x527a32){return _0x480f7e(_0x277ce5,_0x2081db,_0x47b871,_0x527a32);},'zQbCZ':function(_0x42ca9b,_0x130f91){return _0x42ca9b>_0x130f91;},'KajYH':function(_0xaebc93,_0xa46715,_0x5aa90e){return _0xaebc93(_0xa46715,_0x5aa90e);},'BSgpB':_0x13c55b(0x260),'BOoCr':_0x13c55b(0x412),'LdwKl':function(_0xc52fa2,_0x121bf2){return _0xc52fa2(_0x121bf2);},'EWsTI':_0x13c55b(0x44d),'eOqLL':_0x13c55b(0x15c)};return new Promise(async(_0x13f858,_0x5a2592)=>{const _0x58b191=_0x13c55b;console[_0x58b191(0x37a)]('\x0a'+'#'['repeat'](0x3c)),console[_0x58b191(0x37a)](_0x58b191(0x473)+_0x3eb98b[_0x58b191(0x4a3)](',\x20')+']'),console['log'](_0x58b191(0x668)+_0x408c54+'\x22'),console['log']('#'[_0x58b191(0x20b)](0x3c)+'\x0a');const _0xd56595=connectedDevices[_0x58b191(0x5a2)](_0xc96647=>_0x3eb98b[_0x58b191(0x185)](_0xc96647[_0x58b191(0x192)])||_0x3eb98b[_0x58b191(0x185)](_0xc96647['udid'])||_0x3eb98b['includes'](_0xc96647[_0x58b191(0x5cb)]));console['log'](_0x58b191(0x501),connectedDevices['map'](_0x2d7ba7=>_0x2d7ba7['name']+'('+_0x2d7ba7[_0x58b191(0x160)]+')')['join'](',\x20'));if(_0x1908e8[_0x58b191(0x4db)](_0xd56595[_0x58b191(0x484)],0x0)){if(_0x1908e8['BwDRc'](_0x1908e8[_0x58b191(0x475)],_0x1908e8['dZRhg']))_0x47a47d[_0x58b191(0x618)](_0x58b191(0x17e)+_0x3b9ef1+_0x58b191(0x2b9)+_0x2c9eac[_0x58b191(0x3ea)]());else return console['error'](_0x58b191(0x319)+_0x3eb98b[_0x58b191(0x4a3)](',\x20')+']'),_0x1908e8[_0x58b191(0x31e)](_0x5a2592,{'success':![],'error':_0x1908e8[_0x58b191(0x581)]});}const _0x1c51a4=_0xd56595[_0x58b191(0x5a2)](_0x52429e=>![_0x58b191(0x3a6),_0x58b191(0x52d)][_0x58b191(0x185)](_0x52429e[_0x58b191(0x160)]));if(_0x1908e8[_0x58b191(0x5fc)](_0x1c51a4[_0x58b191(0x484)],0x0)){const _0x4e007a=_0x1c51a4[_0x58b191(0x12b)](_0x27fde8=>_0x27fde8['name']+_0x58b191(0x127)+_0x27fde8['status']+')')[_0x58b191(0x4a3)](',\x20');console[_0x58b191(0x618)](_0x58b191(0x741)+_0x4e007a+']');if(_0x8e4152){const _0x3f883b={};_0x3f883b[_0x58b191(0x2ba)]=_0x58b191(0x653),_0x3f883b['data']=_0x58b191(0x61b)+_0x4e007a+_0x58b191(0x345),_0x3f883b[_0x58b191(0x3d4)]=_0x3eb98b,_0x8e4152['send'](JSON[_0x58b191(0x62d)](_0x3f883b));}const _0x10d03e={};return _0x10d03e[_0x58b191(0x492)]=![],_0x10d03e[_0x58b191(0x618)]='Devices\x20not\x20connected:\x20'+_0x4e007a+_0x58b191(0x56b),_0x1908e8[_0x58b191(0x31e)](_0x5a2592,_0x10d03e);}console[_0x58b191(0x37a)](_0x58b191(0x561)+_0xd56595[_0x58b191(0x484)]+_0x58b191(0x1aa)),console[_0x58b191(0x37a)]('Device\x20details:',_0xd56595[_0x58b191(0x12b)](_0x2ad131=>_0x2ad131[_0x58b191(0x192)]+'('+_0x2ad131[_0x58b191(0x569)]+'-'+_0x2ad131[_0x58b191(0xb0)]+')')[_0x58b191(0x4a3)](',\x20'));const _0x2459a9=_0xd56595[_0x58b191(0x5a2)](_0x1a32a9=>_0x1a32a9[_0x58b191(0x569)]===_0x58b191(0x102)&&_0x1a32a9[_0x58b191(0xb0)]===_0x58b191(0x443)),_0x2564a8=_0xd56595['filter'](_0x2e456d=>_0x2e456d[_0x58b191(0x569)]===_0x58b191(0x102)&&_0x2e456d[_0x58b191(0xb0)]===_0x58b191(0x5bd)),_0x55176e=_0xd56595['filter'](_0x45110b=>_0x45110b['platform']==='android'&&_0x45110b[_0x58b191(0xb0)]===_0x58b191(0x443)),_0x2cb36d=_0xd56595[_0x58b191(0x5a2)](_0x47222c=>_0x47222c[_0x58b191(0x569)]===_0x58b191(0x412)&&_0x47222c['connectionType']==='wireless'),_0x103a42=[];if(_0x1908e8[_0x58b191(0x5fc)](_0x2459a9['length'],0x0)){const _0x23a78b=_0x2459a9[_0x58b191(0x12b)](_0x5d70eb=>_0x5d70eb[_0x58b191(0x192)]),_0x3913a0=resolveAppPreset(_0x408c54,_0x1908e8[_0x58b191(0x12f)]);console[_0x58b191(0x37a)](_0x58b191(0x73d)+_0x23a78b[_0x58b191(0x4a3)](',\x20')),_0x103a42[_0x58b191(0x43e)](_0x1908e8[_0x58b191(0x2a5)](executeWithScript,USB_SCRIPT_PATH,_0x23a78b,_0x3913a0,_0x8e4152));}if(_0x1908e8[_0x58b191(0x5fc)](_0x2564a8[_0x58b191(0x484)],0x0)){if(_0x1908e8[_0x58b191(0x104)](_0x1908e8[_0x58b191(0x23f)],_0x1908e8['PPhYb'])){_0x1cdb4f[_0x58b191(0x37a)](_0x58b191(0x431)+_0x186b1f);const _0x59e4d6={};_0x59e4d6[_0x58b191(0x492)]=!![],_0x59e4d6['sessionId']=_0x114f00,_0x1908e8['ILclT'](_0x110742,_0x59e4d6);}else{const _0x286b8f=_0x2564a8['map'](_0x51af71=>_0x51af71[_0x58b191(0x192)]),_0x3c65da=resolveAppPreset(_0x408c54,_0x1908e8[_0x58b191(0x12f)]);console[_0x58b191(0x37a)](_0x58b191(0x228)+_0x286b8f[_0x58b191(0x4a3)](',\x20')),_0x103a42[_0x58b191(0x43e)](_0x1908e8[_0x58b191(0x702)](executeWithScript,WIRELESS_SCRIPT_PATH,_0x286b8f,_0x3c65da,_0x8e4152));}}if(_0x1908e8[_0x58b191(0x289)](_0x55176e[_0x58b191(0x484)],0x0)){const _0xa1938=_0x1908e8[_0x58b191(0x21a)](resolveAppPreset,_0x408c54,_0x58b191(0x412));console[_0x58b191(0x37a)]('Using\x20Android\x20control\x20script\x20for\x20USB\x20devices:\x20'+_0x55176e[_0x58b191(0x12b)](_0x151233=>_0x151233[_0x58b191(0x192)])['join'](',\x20')),_0x103a42['push'](executeAndroidDevices(ANDROID_USB_SCRIPT_PATH,_0x55176e,_0xa1938,_0x8e4152));}if(_0x2cb36d['length']>0x0){if(_0x1908e8[_0x58b191(0x6bc)]!==_0x1908e8[_0x58b191(0x6bc)]){_0x45a5de[_0x58b191(0x37a)](_0x58b191(0x747)+_0x5d4b94+_0x58b191(0x3ed)+_0xab456e+_0x58b191(0x76c));const _0x3c11f9={};_0x3c11f9[_0x58b191(0x492)]=![],_0x3c11f9[_0x58b191(0xef)]=_0x58b191(0x1fa)+_0x54ad3e+'\x20at\x20'+_0x2956ba+'.\x20Check\x20network\x20connection.',_0x49f213(_0x3c11f9);}else{const _0x45c503=resolveAppPreset(_0x408c54,_0x1908e8[_0x58b191(0x636)]);console[_0x58b191(0x37a)]('Using\x20Android\x20control\x20script\x20for\x20wireless\x20devices:\x20'+_0x2cb36d[_0x58b191(0x12b)](_0x749fb7=>_0x749fb7[_0x58b191(0x192)])[_0x58b191(0x4a3)](',\x20')),_0x103a42[_0x58b191(0x43e)](_0x1908e8[_0x58b191(0x702)](executeAndroidDevices,ANDROID_WIRELESS_SCRIPT_PATH,_0x2cb36d,_0x45c503,_0x8e4152));}}if(_0x103a42[_0x58b191(0x484)]===0x0)return _0x1908e8[_0x58b191(0x55a)](_0x5a2592,{'success':![],'error':_0x1908e8[_0x58b191(0x4b1)]});try{const _0xb09d2d=await Promise[_0x58b191(0x4c6)](_0x103a42),_0x2f5ff3=_0xb09d2d[_0x58b191(0x5a2)](_0xbd1d98=>_0xbd1d98[_0x58b191(0x160)]===_0x58b191(0x757))['length'],_0x28f05a=_0xb09d2d[_0x58b191(0x5a2)](_0x658135=>_0x658135['status']===_0x58b191(0xf7))['length'];console[_0x58b191(0x37a)]('\x0aExecuteCommand\x20summary:\x20'+_0x2f5ff3+_0x58b191(0x491)+_0x28f05a+_0x58b191(0x577));const _0x26c577={};_0x26c577[_0x58b191(0x492)]=!![],_0x26c577[_0x58b191(0x5b9)]=_0xb09d2d,_0x26c577[_0x58b191(0x3eb)]=_0x2f5ff3+'/'+_0x103a42[_0x58b191(0x484)]+_0x58b191(0x502),_0x1908e8['ILclT'](_0x13f858,_0x26c577);}catch(_0x227c96){console[_0x58b191(0x618)](_0x1908e8[_0x58b191(0x5d7)],_0x227c96),_0x5a2592(_0x227c96);}});}function executeWithScript(_0x56bc14,_0x3661be,_0x4bfa78,_0x4ab74e){const _0x12cbf5=_0x50607,_0x26d5e8={'VoCPB':_0x12cbf5(0x653),'gaApG':_0x12cbf5(0x5a5),'IFlgv':_0x12cbf5(0x5b6),'DkRjd':function(_0x3b51d1,_0x2258fc){return _0x3b51d1!==_0x2258fc;},'XbOSs':_0x12cbf5(0x439),'qpHdq':_0x12cbf5(0x4c4),'rLoAf':_0x12cbf5(0x362),'qVMyn':function(_0x387385,_0xe8c51a){return _0x387385(_0xe8c51a);},'ScfsK':_0x12cbf5(0x63d),'QqUYb':function(_0x24c23c,_0x259619,_0x4c6a0d,_0x3c5503){return _0x24c23c(_0x259619,_0x4c6a0d,_0x3c5503);},'ORwaP':_0x12cbf5(0x618),'EABkO':function(_0xa9e623,_0x415c70){return _0xa9e623!==_0x415c70;},'QYVyQ':_0x12cbf5(0x1dd),'LvkYY':_0x12cbf5(0x1de)};return new Promise((_0x21d351,_0x295aa4)=>{const _0x5545db=_0x12cbf5,_0x5039e2={'UswVj':function(_0x1ba253,_0x470228){return _0x1ba253(_0x470228);},'SJLbB':function(_0x568741,_0x14b347){const _0x1f7da2=_0x46ca;return _0x26d5e8[_0x1f7da2(0x399)](_0x568741,_0x14b347);}};console[_0x5545db(0x37a)]('\x0a'+'='[_0x5545db(0x20b)](0x3c)),console[_0x5545db(0x37a)](_0x5545db(0x3d0)+path['basename'](_0x56bc14)),console[_0x5545db(0x37a)](_0x5545db(0x220)+_0x3661be[_0x5545db(0x4a3)](',\x20')+']'),console[_0x5545db(0x37a)](_0x5545db(0x668)+_0x4bfa78+'\x22'),console[_0x5545db(0x37a)]('='['repeat'](0x3c)+'\x0a');const _0x58c369=_0x3661be[_0x5545db(0x12b)]((_0x39ab58,_0x14615b)=>{const _0x3b5a39=_0x5545db,_0xfdda38={'IVpLW':_0x26d5e8[_0x3b5a39(0x6b0)],'betpa':_0x26d5e8[_0x3b5a39(0x497)],'PhGxK':_0x26d5e8[_0x3b5a39(0x225)],'TlcED':function(_0x1ec8a4,_0x28f553){const _0x4a24dc=_0x3b5a39;return _0x26d5e8[_0x4a24dc(0x2f7)](_0x1ec8a4,_0x28f553);},'gMCpw':_0x26d5e8[_0x3b5a39(0x4ed)],'wBEVZ':_0x26d5e8[_0x3b5a39(0xe1)],'CXDrm':function(_0x5cc3fa,_0x57cdb4){return _0x5cc3fa===_0x57cdb4;},'cNhGz':_0x26d5e8[_0x3b5a39(0x2be)],'zaLHV':function(_0x730337,_0x22a3a4){const _0x41707a=_0x3b5a39;return _0x26d5e8[_0x41707a(0x399)](_0x730337,_0x22a3a4);},'kdjZX':_0x26d5e8[_0x3b5a39(0x688)],'dUsWG':function(_0x12f844,_0x46b3c9){return _0x12f844(_0x46b3c9);},'QZEoj':function(_0x296c42,_0x628b45,_0x2115a8,_0x2573a4){return _0x26d5e8['QqUYb'](_0x296c42,_0x628b45,_0x2115a8,_0x2573a4);},'dsvEv':_0x3b5a39(0x49b),'ZrWcA':_0x26d5e8[_0x3b5a39(0x5af)]};if(_0x26d5e8[_0x3b5a39(0x16c)](_0x26d5e8[_0x3b5a39(0x5ab)],_0x26d5e8[_0x3b5a39(0x446)]))return new Promise((_0x38ef38,_0x1fc4b0)=>{const _0x2238d9=_0x3b5a39,_0x2e4a9b={'KyfIH':_0x2238d9(0x312),'KfFuF':_0xfdda38[_0x2238d9(0x715)],'UdmMR':_0xfdda38['PhGxK'],'TvhEV':function(_0xdd704a,_0x461977){const _0x3728af=_0x2238d9;return _0xfdda38[_0x3728af(0x5e9)](_0xdd704a,_0x461977);},'hWtTy':_0xfdda38['gMCpw'],'gcNby':_0xfdda38[_0x2238d9(0x171)],'beHkG':function(_0x4021bb,_0x4e240b){const _0x259518=_0x2238d9;return _0xfdda38[_0x259518(0x508)](_0x4021bb,_0x4e240b);},'jLCuG':_0xfdda38[_0x2238d9(0x234)],'VFLsZ':function(_0x23c0b7,_0x13b29b){const _0x153d2d=_0x2238d9;return _0xfdda38[_0x153d2d(0x620)](_0x23c0b7,_0x13b29b);},'RMLYA':_0xfdda38[_0x2238d9(0x49c)],'GucYD':function(_0x3ba517,_0x244bcb){return _0xfdda38['dUsWG'](_0x3ba517,_0x244bcb);}},_0x12b9d2=['-d',_0x39ab58,_0x4bfa78],_0x42f6b3=_0xfdda38[_0x2238d9(0x257)](spawn,_0x56bc14,_0x12b9d2,{'cwd':path[_0x2238d9(0x679)](_0x56bc14)});let _0x50bcd6='',_0x45726c='';_0x42f6b3[_0x2238d9(0x551)]['on'](_0xfdda38['dsvEv'],_0xd7f474=>{const _0x5a8ce=_0x2238d9,_0x43d1e1=_0xd7f474[_0x5a8ce(0x2ca)]();_0x50bcd6+=_0x43d1e1,console[_0x5a8ce(0x37a)]('['+_0x39ab58+_0x5a8ce(0x38a)+_0x43d1e1['trim']());if(_0x4ab74e){const _0x52b11d={};_0x52b11d[_0x5a8ce(0x2ba)]=_0xfdda38[_0x5a8ce(0x763)],_0x52b11d['data']='['+_0x39ab58+']\x20'+_0x43d1e1,_0x52b11d[_0x5a8ce(0x3d4)]=[_0x39ab58],_0x4ab74e[_0x5a8ce(0x65f)](JSON[_0x5a8ce(0x62d)](_0x52b11d));}}),_0x42f6b3['stderr']['on'](_0xfdda38[_0x2238d9(0x34f)],_0xad330c=>{const _0x317de1=_0x2238d9,_0x190cb9=_0xad330c[_0x317de1(0x2ca)]();_0x45726c+=_0x190cb9,console[_0x317de1(0x618)]('['+_0x39ab58+_0x317de1(0x354)+_0x190cb9['trim']());}),_0x42f6b3['on'](_0x2238d9(0x3a0),_0xad3a05=>{const _0x1dd340=_0x2238d9,_0x35339f={};_0x35339f[_0x1dd340(0x5dc)]=_0x1dd340(0x15e),_0x35339f[_0x1dd340(0x4ce)]=_0x2e4a9b[_0x1dd340(0x3e3)];const _0x2a954d=_0x35339f;if(_0x2e4a9b['TvhEV'](_0x2e4a9b[_0x1dd340(0x1d9)],_0x2e4a9b[_0x1dd340(0x4f2)])){if(_0x2e4a9b['beHkG'](_0xad3a05,0x0)){if(_0x1dd340(0x541)===_0x2e4a9b[_0x1dd340(0xad)]){const _0x315097=_0x52c2dd[_0x1dd340(0x288)](_0x2ae39f);return _0x5d38ad[_0x1dd340(0x37a)](_0x2e4a9b[_0x1dd340(0x16d)],_0x1e0ec9[_0x1dd340(0x616)](_0x315097)?_0x315097[_0x1dd340(0x484)]:_0x2e4a9b[_0x1dd340(0x2b7)]),_0x2cd7dc[_0x1dd340(0x616)](_0x315097)?_0x315097:[];}else{const _0x56c37c={};_0x56c37c[_0x1dd340(0x492)]=!![],_0x56c37c[_0x1dd340(0x4d3)]=_0x50bcd6,_0x56c37c[_0x1dd340(0x273)]=_0x39ab58,_0x2e4a9b['VFLsZ'](_0x38ef38,_0x56c37c);}}else{if(_0x2e4a9b['beHkG'](_0x2e4a9b['RMLYA'],_0x1dd340(0x63d))){const _0x320cc0={};_0x320cc0[_0x1dd340(0x492)]=![],_0x320cc0[_0x1dd340(0x618)]=_0x45726c||_0x1dd340(0x27b)+_0xad3a05,_0x320cc0[_0x1dd340(0x273)]=_0x39ab58,_0x2e4a9b['GucYD'](_0x1fc4b0,_0x320cc0);}else{const _0x15cae8={};_0x15cae8['type']=_0x1dd340(0x246),_0x15cae8['devices']=_0x15d7d3,_0x4c9659[_0x1dd340(0x65f)](_0x15f167[_0x1dd340(0x62d)](_0x15cae8));}}}else{_0x568b90['error'](_0x2a954d['Gdpbx'],_0x311e1e);const _0x4f2dc7={};return _0x4f2dc7[_0x1dd340(0x492)]=![],_0x4f2dc7['error']=_0x2a954d[_0x1dd340(0x4ce)],_0x52c3b0['status'](0x190)[_0x1dd340(0x573)](_0x4f2dc7);}}),_0x42f6b3['on'](_0xfdda38['ZrWcA'],_0x2245b4=>{const _0x181531=_0x2238d9;if(_0x2e4a9b[_0x181531(0x5d8)](_0x181531(0x416),'pjDKJ')){console[_0x181531(0x618)]('['+_0x39ab58+_0x181531(0x5ba)+_0x2245b4[_0x181531(0xef)]);const _0x1d89e0={};_0x1d89e0[_0x181531(0x492)]=![],_0x1d89e0[_0x181531(0x618)]=_0x2245b4[_0x181531(0xef)],_0x1d89e0['device']=_0x39ab58,_0x2e4a9b[_0x181531(0x4b2)](_0x1fc4b0,_0x1d89e0);}else _0xfddd0c[_0x181531(0x192)]=_0x12eb55[0x1][_0x181531(0x3ea)](),_0x2369c6[_0x181531(0x666)]=_0x38d400[0x1]['trim']();});});else{const _0x562e26={};_0x562e26[_0x3b5a39(0x160)]=_0x48052e[_0x3b5a39(0x160)],_0x562e26[_0x3b5a39(0x75c)]=_0x506351['sessionId'],_0x6d95dd['set'](_0x2b9674[_0x3b5a39(0x343)],_0x562e26);}});Promise[_0x5545db(0x4c6)](_0x58c369)[_0x5545db(0x4a9)](_0x6f4061=>{const _0x47c82f=_0x5545db,_0x5ccbd7=_0x6f4061[_0x47c82f(0x5a2)](_0x548199=>_0x548199[_0x47c82f(0x160)]==='fulfilled')[_0x47c82f(0x484)],_0xe7f5b5=_0x6f4061[_0x47c82f(0x5a2)](_0x18b014=>_0x18b014[_0x47c82f(0x160)]===_0x47c82f(0xf7))[_0x47c82f(0x484)];console[_0x47c82f(0x37a)]('\x0a'+'='[_0x47c82f(0x20b)](0x3c)),console[_0x47c82f(0x37a)]('='[_0x47c82f(0x20b)](0x3c)+'\x0a');const _0x5c33c1={};_0x5c33c1[_0x47c82f(0x492)]=!![],_0x5c33c1['results']=_0x6f4061,_0x5c33c1[_0x47c82f(0x3eb)]=_0x5ccbd7+'/'+_0x3661be['length']+_0x47c82f(0x6fa),_0x5039e2[_0x47c82f(0x5c3)](_0x21d351,_0x5c33c1);})['catch'](_0x3308cb=>{const _0x36786a=_0x5545db;console['error'](_0x36786a(0x599)+_0x3308cb[_0x36786a(0xef)]),_0x5039e2[_0x36786a(0x272)](_0x295aa4,_0x3308cb);});});}function executeAndroidDevices(_0x31eb56,_0x3a22b8,_0x131aed,_0x48d63b){const _0x439ee8=_0x50607,_0x50c790={'DoSVm':function(_0x56ea7b,_0x243ea7){return _0x56ea7b!==_0x243ea7;},'KIdFw':_0x439ee8(0x624),'EJDUP':_0x439ee8(0x3f5),'xDNnx':function(_0x1e1906,_0x2876a1){return _0x1e1906(_0x2876a1);},'SoBZq':_0x439ee8(0x5a3),'iIViS':_0x439ee8(0x246),'BwlAB':function(_0x19d3a1,_0x146310){return _0x19d3a1===_0x146310;},'YBxyX':_0x439ee8(0x4d0),'BIQgX':function(_0xca0b8b,_0xe0d048){return _0xca0b8b!==_0xe0d048;},'CCfwe':function(_0x34c7d2,_0xfcb25){return _0x34c7d2+_0xfcb25;},'ZtYde':'3|4|0|1|2'};return new Promise((_0x690b61,_0x13dca5)=>{const _0x4fb3f4=_0x439ee8,_0x5392df={'cKTnm':_0x4fb3f4(0x4d3),'DKiYB':_0x50c790[_0x4fb3f4(0x5b3)],'XqcvO':function(_0x183c69,_0x456dbf){return _0x50c790['xDNnx'](_0x183c69,_0x456dbf);},'QzeIO':_0x50c790[_0x4fb3f4(0x43b)],'eeaJa':function(_0x5b8000,_0x14a215){return _0x5b8000===_0x14a215;},'JkbnM':function(_0x2f26e1,_0x4ef673){const _0x1d1715=_0x4fb3f4;return _0x50c790[_0x1d1715(0x2da)](_0x2f26e1,_0x4ef673);},'zEQms':_0x50c790[_0x4fb3f4(0x121)],'CkPMo':'error','bPpWv':function(_0x2576e4,_0x2f01a2){const _0x1b4647=_0x4fb3f4;return _0x50c790[_0x1b4647(0x75b)](_0x2576e4,_0x2f01a2);},'jqTfN':'AITgM','BKQvF':function(_0x2f86fa,_0x3a7c4d){const _0x514a37=_0x4fb3f4;return _0x50c790[_0x514a37(0x5f4)](_0x2f86fa,_0x3a7c4d);},'YuYXo':function(_0x3e9512,_0x276223){const _0x3bd529=_0x4fb3f4;return _0x50c790[_0x3bd529(0x2da)](_0x3e9512,_0x276223);},'dwzCy':'DOFDW','FIzia':function(_0x5dfbf8,_0x3af4e2){return _0x5dfbf8-_0x3af4e2;},'qlcGp':function(_0x1449a9,_0x71d6ee){return _0x50c790['xDNnx'](_0x1449a9,_0x71d6ee);},'ziRFQ':_0x50c790[_0x4fb3f4(0x67b)]};console[_0x4fb3f4(0x37a)]('\x0a'+'='[_0x4fb3f4(0x20b)](0x3c)),console[_0x4fb3f4(0x37a)]('Script:\x20'+path[_0x4fb3f4(0x16a)](_0x31eb56)),console[_0x4fb3f4(0x37a)]('Devices:\x20['+_0x3a22b8['map'](_0xf5a8f1=>_0xf5a8f1[_0x4fb3f4(0x192)])['join'](',\x20')+']'),console[_0x4fb3f4(0x37a)]('Command:\x20\x22'+_0x131aed+'\x22'),console[_0x4fb3f4(0x37a)]('='['repeat'](0x3c)+'\x0a');const _0x3eaf43=_0x3a22b8[_0x4fb3f4(0x12b)]((_0x1137ae,_0x5e6218)=>{const _0x3eb095=_0x4fb3f4,_0x36cbae={'ABxJB':_0x5392df[_0x3eb095(0x30e)],'yNrwu':_0x5392df[_0x3eb095(0x512)],'IlEEM':function(_0x1e6a3d,_0x1eab97){const _0x39496f=_0x3eb095;return _0x5392df[_0x39496f(0x3ab)](_0x1e6a3d,_0x1eab97);},'fCNZe':_0x5392df[_0x3eb095(0x279)],'qhWVU':function(_0x5573c8,_0x2b5071){return _0x5392df['eeaJa'](_0x5573c8,_0x2b5071);},'bqOHw':function(_0x2e7d6d,_0x52d9e8){const _0x1b1946=_0x3eb095;return _0x5392df[_0x1b1946(0x165)](_0x2e7d6d,_0x52d9e8);},'XePrw':_0x5392df[_0x3eb095(0x21f)],'hapra':function(_0x50063b,_0x237d8b){return _0x50063b(_0x237d8b);},'iQnwt':function(_0x5b2d89,_0x9aca8c){return _0x5b2d89(_0x9aca8c);},'KkHtE':function(_0x5d5e05,_0xd37205,_0x5f5285,_0x42d290){return _0x5d5e05(_0xd37205,_0x5f5285,_0x42d290);},'dNqCw':'data','aHUSQ':_0x3eb095(0x3a0),'libeR':_0x5392df['CkPMo']};if(_0x5392df[_0x3eb095(0x697)]('AITgM',_0x5392df[_0x3eb095(0x4c2)])){if(!_0x7b6d33[_0x34efc4])_0x562381[_0x26a6d1]={};_0x1afe63[_0x3ee977][_0x3eb095(0x632)]=_0x147b23;}else return console['log']('['+_0x5392df['BKQvF'](_0x5e6218,0x1)+'/'+_0x3a22b8[_0x3eb095(0x484)]+']\x20Creating\x20execution\x20promise\x20for:\x20'+_0x1137ae[_0x3eb095(0x192)]+'\x20('+_0x1137ae[_0x3eb095(0x343)]+')'),new Promise((_0x389bae,_0x1f7ab9)=>{const _0x284a91=_0x3eb095,_0x5e77e6={'bMZON':_0x36cbae[_0x284a91(0x57d)],'yUpEq':function(_0x554b6b,_0x257faa){const _0x2a1fc8=_0x284a91;return _0x36cbae[_0x2a1fc8(0x58b)](_0x554b6b,_0x257faa);},'rOpNK':_0x284a91(0xf2),'qslaC':function(_0x1b3192,_0x243117){return _0x36cbae['bqOHw'](_0x1b3192,_0x243117);},'hWqAq':_0x36cbae['XePrw'],'JxOOi':function(_0x46b50a,_0x5af81d){const _0x48697b=_0x284a91;return _0x36cbae[_0x48697b(0x333)](_0x46b50a,_0x5af81d);},'iIAGi':function(_0x4435d2,_0x496377){const _0x54beb8=_0x284a91;return _0x36cbae[_0x54beb8(0x745)](_0x4435d2,_0x496377);},'PSLos':function(_0x36962e,_0x178c07){const _0xf2e3f4=_0x284a91;return _0x36cbae[_0xf2e3f4(0x745)](_0x36962e,_0x178c07);},'ApItH':function(_0x1f1f5b,_0x18e771){const _0x3d2842=_0x284a91;return _0x36cbae[_0x3d2842(0x745)](_0x1f1f5b,_0x18e771);}},_0x395bdc=[_0x1137ae[_0x284a91(0x343)],..._0x131aed['split']('\x20')],_0x3cdc5e=_0x36cbae[_0x284a91(0x735)](spawn,_0x31eb56,_0x395bdc,{'cwd':path[_0x284a91(0x679)](_0x31eb56)});let _0x2f58e4='',_0x4f8de7='';_0x3cdc5e['stdout']['on'](_0x36cbae['dNqCw'],_0x491600=>{const _0x5c31fb=_0x284a91,_0x1947fd=_0x491600['toString']();_0x2f58e4+=_0x1947fd,console[_0x5c31fb(0x37a)]('['+_0x1137ae[_0x5c31fb(0x192)]+_0x5c31fb(0x38a)+_0x1947fd[_0x5c31fb(0x3ea)]());if(_0x48d63b){const _0x3987ae={};_0x3987ae[_0x5c31fb(0x2ba)]=_0x36cbae['ABxJB'],_0x3987ae[_0x5c31fb(0x273)]=_0x1137ae[_0x5c31fb(0x192)],_0x3987ae['data']=_0x1947fd,_0x48d63b['send'](JSON[_0x5c31fb(0x62d)](_0x3987ae));}}),_0x3cdc5e[_0x284a91(0x40e)]['on'](_0x36cbae['dNqCw'],_0x554a58=>{const _0x44b120=_0x284a91,_0xeea653=_0x554a58[_0x44b120(0x2ca)]();_0x4f8de7+=_0xeea653,console[_0x44b120(0x37a)]('['+_0x1137ae[_0x44b120(0x192)]+_0x44b120(0x354)+_0xeea653[_0x44b120(0x3ea)]());}),_0x3cdc5e['on'](_0x36cbae[_0x284a91(0x6dc)],_0xc69803=>{const _0x42b124=_0x284a91;if(_0x5e77e6[_0x42b124(0x13d)](_0x5e77e6[_0x42b124(0xff)],_0x42b124(0x525))){if(_0x281b43[_0x42b124(0x625)]===_0x55c1fc[_0x42b124(0x467)]){const _0x33a1d6={};_0x33a1d6[_0x42b124(0x2ba)]=_0x5e77e6[_0x42b124(0x1b0)],_0x33a1d6[_0x42b124(0x3d4)]=_0x54ce81,_0x40ce74[_0x42b124(0x65f)](_0x1479bd[_0x42b124(0x62d)](_0x33a1d6));}}else{if(_0x5e77e6[_0x42b124(0x582)](_0xc69803,0x0)){if(_0x5e77e6[_0x42b124(0x582)](_0x5e77e6['hWqAq'],_0x5e77e6[_0x42b124(0x42c)])){const _0x3021c6={};_0x3021c6['success']=!![],_0x3021c6['output']=_0x2f58e4,_0x3021c6[_0x42b124(0x273)]=_0x1137ae[_0x42b124(0x192)],_0x389bae(_0x3021c6);}else _0x36e523[_0x42b124(0x37a)](_0x42b124(0x550)+_0x27f892[_0x42b124(0xef)]);}else{const _0x27b661={};_0x27b661[_0x42b124(0x492)]=![],_0x27b661[_0x42b124(0x618)]=_0x4f8de7||_0x2f58e4,_0x27b661[_0x42b124(0x273)]=_0x1137ae['name'],_0x5e77e6['JxOOi'](_0x389bae,_0x27b661);}}}),_0x3cdc5e['on'](_0x36cbae[_0x284a91(0xb7)],_0x3aae89=>{const _0x3a0aef=_0x284a91;if(_0x3a0aef(0x5a3)===_0x36cbae['yNrwu']){console[_0x3a0aef(0x618)]('['+_0x1137ae[_0x3a0aef(0x192)]+_0x3a0aef(0x548),_0x3aae89);const _0x184e68={};_0x184e68['success']=![],_0x184e68['error']=_0x3aae89['message'],_0x184e68[_0x3a0aef(0x273)]=_0x1137ae[_0x3a0aef(0x192)],_0x36cbae[_0x3a0aef(0x722)](_0x389bae,_0x184e68);}else _0x2a5a5c['x']=_0x5e77e6['JxOOi'](_0x5977c6,_0x47ddb2[0x1]),_0xddb18f['y']=_0x5e77e6[_0x3a0aef(0x649)](_0x144f30,_0x445980[0x2]),_0x5b13e4[_0x3a0aef(0x4d7)]=_0x5e77e6[_0x3a0aef(0x4f0)](_0x36b132,_0x11c8d8[0x3]),_0x3613c3[_0x3a0aef(0x357)]=_0x5e77e6['ApItH'](_0x371e78,_0x1a149d[0x4]),_0x5671f3[_0x3a0aef(0x3ac)]='('+_0x3f19a1['x']+','+_0x303894['y']+')\x20'+_0x2e037f[_0x3a0aef(0x4d7)]+'x'+_0x328334[_0x3a0aef(0x357)];});});});Promise[_0x4fb3f4(0x4c6)](_0x3eaf43)['then'](_0x5a0a06=>{const _0x3883b1=_0x4fb3f4;if(_0x5392df[_0x3883b1(0x49a)](_0x3883b1(0x374),_0x5392df[_0x3883b1(0x133)])){if(_0x5392df[_0x3883b1(0x108)](_0x3922c[_0x3883b1(0x625)],_0x11ab04[_0x3883b1(0x467)])){const _0x2c3ea3={};_0x2c3ea3[_0x3883b1(0x2ba)]=_0x5392df[_0x3883b1(0x279)],_0x2c3ea3[_0x3883b1(0x3d4)]=_0xe2eafa,_0x52ddda[_0x3883b1(0x65f)](_0x11a41c[_0x3883b1(0x62d)](_0x2c3ea3));}}else{console['log']('\x0a'+'='[_0x3883b1(0x20b)](0x3c));const _0x33016d=_0x5a0a06[_0x3883b1(0x5a2)](_0x1da7a7=>_0x1da7a7['status']===_0x3883b1(0x757)&&_0x1da7a7[_0x3883b1(0x55d)][_0x3883b1(0x492)])['length'],_0xd73655=_0x5392df[_0x3883b1(0x3ce)](_0x5a0a06[_0x3883b1(0x484)],_0x33016d);console[_0x3883b1(0x37a)]('='[_0x3883b1(0x20b)](0x3c)+'\x0a');const _0x2da84d={};_0x2da84d['success']=!![],_0x2da84d[_0x3883b1(0x5b9)]=_0x5a0a06,_0x5392df[_0x3883b1(0x71d)](_0x690b61,_0x2da84d);}})['catch'](_0x502d04=>{const _0x19c57f=_0x4fb3f4;if(_0x50c790['DoSVm'](_0x19c57f(0x624),_0x50c790[_0x19c57f(0x1e4)])){const _0x3bddb2=_0x1c3ff3[_0x19c57f(0x600)](/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);if(_0x3bddb2){const _0x363a06=_0x5392df[_0x19c57f(0x37e)][_0x19c57f(0x19b)]('|');let _0x54afee=0x0;while(!![]){switch(_0x363a06[_0x54afee++]){case'0':_0x51f552[_0x19c57f(0x4d7)]=_0x5019b7(_0x3bddb2[0x3]);continue;case'1':_0x4ecfa4[_0x19c57f(0x357)]=_0x5392df[_0x19c57f(0x3ab)](_0xa39131,_0x3bddb2[0x4]);continue;case'2':_0x39f2fc[_0x19c57f(0x3ac)]='('+_0x373654['x']+','+_0x15dba5['y']+')\x20'+_0x165e3c['width']+'x'+_0x1d2f67[_0x19c57f(0x357)];continue;case'3':_0x5f0829['x']=_0x5392df[_0x19c57f(0x3ab)](_0x461eb7,_0x3bddb2[0x1]);continue;case'4':_0x2172ec['y']=_0x5392df[_0x19c57f(0x71d)](_0x28be44,_0x3bddb2[0x2]);continue;}break;}}}else console[_0x19c57f(0x618)](_0x50c790['EJDUP'],_0x502d04),_0x50c790[_0x19c57f(0x70f)](_0x13dca5,_0x502d04);});});}async function convertNaturalLanguageToCommand(_0x3936f1,_0x575021,_0x2a7749=null){const _0x15c897=_0x50607,_0x380b68={};_0x380b68[_0x15c897(0xa8)]=function(_0x43fd59,_0x253f5e){return _0x43fd59===_0x253f5e;},_0x380b68[_0x15c897(0x392)]=_0x15c897(0x75d);const _0x1ccbb5=_0x380b68,_0x2054ae=connectedDevices['filter'](_0x3c705f=>_0x575021[_0x15c897(0x185)](_0x3c705f[_0x15c897(0x192)]));if(_0x1ccbb5['Bmtie'](_0x2054ae[_0x15c897(0x484)],0x0))return await aiManager['convertCommand'](_0x3936f1,null,_0x2a7749);const _0x123553=[...new Set(_0x2054ae[_0x15c897(0x12b)](_0x2480ae=>_0x2480ae['platform']))];console[_0x15c897(0x37a)](_0x15c897(0x1b9)+_0x2054ae[_0x15c897(0x484)]+_0x15c897(0x1c9)+_0x123553[_0x15c897(0x484)]+_0x15c897(0x12d)+_0x123553[_0x15c897(0x4a3)](',\x20'));const _0x170ed3=_0x123553['length']===0x1?_0x123553[0x0]:_0x1ccbb5[_0x15c897(0x392)];return console[_0x15c897(0x37a)]('AI\x20using\x20platform\x20mode:\x20'+_0x170ed3),await aiManager[_0x15c897(0x214)](_0x3936f1,_0x170ed3,_0x2a7749);}async function executeCommandsSequentially(_0x5b92aa,_0x172a6c,_0x55e71b){const _0x3bb041=_0x50607,_0x36e58b={'fphyA':_0x3bb041(0x246),'NOQNl':_0x3bb041(0xb8),'dovos':function(_0x547808,_0x5d42e8){return _0x547808===_0x5d42e8;},'ckZye':function(_0x14e77e,_0x4853d4){return _0x14e77e<_0x4853d4;},'BmJuH':function(_0xbb54b9,_0x27a008){return _0xbb54b9!==_0x27a008;},'dHSGp':_0x3bb041(0x231),'xsShg':'WAIT\x20','gnhXq':_0x3bb041(0x607),'aQiLg':function(_0x4dc6f1,_0x366d3d){return _0x4dc6f1(_0x366d3d);},'ELVLb':_0x3bb041(0x4cc),'LYYCh':'command_output','qQbXK':function(_0x6ecb98,_0x177f55){return _0x6ecb98+_0x177f55;},'hvpGp':function(_0x570d80,_0x1ab5b3,_0x13baf7,_0x570100){return _0x570d80(_0x1ab5b3,_0x13baf7,_0x570100);}},_0x37571a=_0x172a6c[_0x3bb041(0x19b)]('\x0a')['map'](_0xf48a36=>_0xf48a36[_0x3bb041(0x3ea)]())[_0x3bb041(0x5a2)](_0x57d0fa=>_0x57d0fa);console[_0x3bb041(0x37a)]('\x0a'+'~'[_0x3bb041(0x20b)](0x3c)),console['log'](_0x3bb041(0x5f1)+_0x37571a[_0x3bb041(0x484)]),console[_0x3bb041(0x37a)](_0x3bb041(0x4d5),_0x37571a),console['log']('~'[_0x3bb041(0x20b)](0x3c)+'\x0a');const _0x2abee3=[];for(let _0x9e662b=0x0;_0x36e58b[_0x3bb041(0x23e)](_0x9e662b,_0x37571a[_0x3bb041(0x484)]);_0x9e662b++){if(_0x36e58b[_0x3bb041(0x2ab)](_0x36e58b[_0x3bb041(0x58d)],_0x36e58b[_0x3bb041(0x58d)])){const _0x4dd4e5={};_0x4dd4e5[_0x3bb041(0x2ba)]=_0x36e58b[_0x3bb041(0x6f5)],_0x4dd4e5[_0x3bb041(0x3d4)]=_0x34e43d,_0x4889e1['send'](_0x55c7bd[_0x3bb041(0x62d)](_0x4dd4e5));}else{const _0x3d80c6=_0x37571a[_0x9e662b];if(_0x3d80c6[_0x3bb041(0x4ae)]('#'))continue;if(_0x3d80c6[_0x3bb041(0x4ae)](_0x36e58b[_0x3bb041(0x351)])){if(_0x36e58b[_0x3bb041(0x219)](_0x36e58b['gnhXq'],_0x3bb041(0x607))){const _0x31ff17=_0x36e58b[_0x3bb041(0x26d)](parseInt,_0x3d80c6[_0x3bb041(0x203)](_0x3bb041(0x26e),''));console[_0x3bb041(0x37a)](_0x3bb041(0x2fc)+_0x31ff17+'ms\x20before\x20next\x20command...');if(_0x55e71b){if(_0x36e58b[_0x3bb041(0x2ab)](_0x36e58b[_0x3bb041(0xe2)],_0x3bb041(0x4cc))){const _0x3b1f39=_0x21cd4d[_0x3bb041(0x2ca)]();(_0x3b1f39[_0x3bb041(0x185)](_0x36e58b[_0x3bb041(0x2b3)])||_0x3b1f39[_0x3bb041(0x185)]('WebDriverAgent'))&&_0x37a27d[_0x3bb041(0x37a)](_0x3bb041(0x27a)+_0x3f214c+'):\x20'+_0x3b1f39[_0x3bb041(0x3ea)]());}else{const _0x19cd6f={};_0x19cd6f[_0x3bb041(0x2ba)]=_0x36e58b['LYYCh'],_0x19cd6f[_0x3bb041(0x49b)]=_0x3bb041(0x2fc)+_0x31ff17+_0x3bb041(0x555),_0x19cd6f['devices']=_0x5b92aa,_0x55e71b[_0x3bb041(0x65f)](JSON['stringify'](_0x19cd6f));}}await new Promise(_0x27a23b=>setTimeout(_0x27a23b,_0x31ff17));const _0x1d527e={};_0x1d527e[_0x3bb041(0x405)]=_0x3d80c6,_0x1d527e[_0x3bb041(0x492)]=!![],_0x1d527e[_0x3bb041(0x4d3)]=_0x3bb041(0x63e)+_0x31ff17+'ms',_0x2abee3[_0x3bb041(0x43e)](_0x1d527e);continue;}else{if(_0x36e58b[_0x3bb041(0x219)](_0x5b927e[_0x3bb041(0x625)],_0x973c[_0x3bb041(0x467)])){const _0x161b13={};_0x161b13['type']=_0x3bb041(0x246),_0x161b13['devices']=_0x461ff4,_0x116886['send'](_0xe576fd[_0x3bb041(0x62d)](_0x161b13));}}}console[_0x3bb041(0x37a)](_0x3bb041(0x731)+_0x36e58b[_0x3bb041(0x5e8)](_0x9e662b,0x1)+'/'+_0x37571a[_0x3bb041(0x484)]+_0x3bb041(0x377)+_0x3d80c6+'\x22');_0x55e71b&&_0x55e71b[_0x3bb041(0x65f)](JSON[_0x3bb041(0x62d)]({'type':_0x3bb041(0x653),'data':'ā¶ļø\x20\x20['+_0x36e58b[_0x3bb041(0x5e8)](_0x9e662b,0x1)+'/'+_0x37571a[_0x3bb041(0x484)]+']\x20'+_0x3d80c6+'\x0a','devices':_0x5b92aa}));try{const _0x3338e3=await _0x36e58b[_0x3bb041(0xb1)](executeCommand,_0x5b92aa,_0x3d80c6,_0x55e71b),_0xe2873b={};_0xe2873b[_0x3bb041(0x405)]=_0x3d80c6,_0xe2873b[_0x3bb041(0x492)]=!![],_0xe2873b['result']=_0x3338e3,_0x2abee3[_0x3bb041(0x43e)](_0xe2873b),console[_0x3bb041(0x37a)](_0x3bb041(0x283)+_0x36e58b['qQbXK'](_0x9e662b,0x1)+_0x3bb041(0x5a7));}catch(_0x2807eb){console[_0x3bb041(0x618)](_0x3bb041(0x654)+_0x36e58b[_0x3bb041(0x5e8)](_0x9e662b,0x1)+_0x3bb041(0x2d9),_0x2807eb[_0x3bb041(0xef)]);const _0x124162={};_0x124162[_0x3bb041(0x405)]=_0x3d80c6,_0x124162[_0x3bb041(0x492)]=![],_0x124162['error']=_0x2807eb['message'],_0x2abee3['push'](_0x124162);if(_0x55e71b){const _0x2b7a54={};_0x2b7a54[_0x3bb041(0x2ba)]=_0x3bb041(0x653),_0x2b7a54[_0x3bb041(0x49b)]=_0x3bb041(0x470)+_0x2807eb[_0x3bb041(0xef)]+'\x0a',_0x2b7a54['devices']=_0x5b92aa,_0x55e71b[_0x3bb041(0x65f)](JSON['stringify'](_0x2b7a54));}}}}console['log']('\x0a'+'~'[_0x3bb041(0x20b)](0x3c)),console[_0x3bb041(0x37a)](_0x3bb041(0x474)+_0x2abee3[_0x3bb041(0x484)]+_0x3bb041(0x63c)+_0x2abee3[_0x3bb041(0x5a2)](_0x1b3ad4=>_0x1b3ad4[_0x3bb041(0x492)])[_0x3bb041(0x484)]+_0x3bb041(0x603)+_0x2abee3[_0x3bb041(0x5a2)](_0x57d4a9=>!_0x57d4a9[_0x3bb041(0x492)])[_0x3bb041(0x484)]),console['log']('~'[_0x3bb041(0x20b)](0x3c)+'\x0a');const _0x548ff4={};return _0x548ff4[_0x3bb041(0x492)]=!![],_0x548ff4[_0x3bb041(0x5b9)]=_0x2abee3,_0x548ff4['summary']=_0x3bb041(0x459)+_0x2abee3[_0x3bb041(0x484)]+_0x3bb041(0x50f),_0x548ff4;}async function createWDASession(_0x3b7a5c,_0x2e8b53){const _0x32f1a8=_0x50607,_0xfd56d2={'cxsJL':function(_0x3a53fc,_0xe41101,_0x329efa){return _0x3a53fc(_0xe41101,_0x329efa);},'BrZAh':'utf-8','GSmVH':function(_0x11a1de,_0x27eb31){return _0x11a1de===_0x27eb31;},'jlhfb':_0x32f1a8(0x1b1),'iGQzC':_0x32f1a8(0x246),'KpaFP':_0x32f1a8(0x353),'yuDXr':function(_0x5d0934,_0x5ba503){return _0x5d0934(_0x5ba503);},'ZLhfH':_0x32f1a8(0x661),'Rtwpg':_0x32f1a8(0x28d),'tHaTO':'invalid\x20session\x20id','DYvKq':function(_0x3378e9,_0x5a670a){return _0x3378e9===_0x5a670a;},'mRynG':_0x32f1a8(0x350),'pfvrs':function(_0x1e386a,_0x46aec3,_0x54bd61,_0x44cc99,_0x14b0a1){return _0x1e386a(_0x46aec3,_0x54bd61,_0x44cc99,_0x14b0a1);},'APbvD':'/tmp/ios_multi_sessions','qavcR':function(_0x526455,_0x473ca8){return _0x526455!==_0x473ca8;},'fXxth':'FzfiT','TjmTJ':function(_0x4f8de9,_0x3add3a){return _0x4f8de9===_0x3add3a;},'ENrur':_0x32f1a8(0x52b),'QJKfA':'curl','cwEwk':_0x32f1a8(0x652)};return new Promise(async _0x1e0407=>{const _0x59785f=_0x32f1a8,_0x1c72c5={'DTKOv':function(_0xb9b230,_0x35c367,_0x5795ba){const _0x13d377=_0x46ca;return _0xfd56d2[_0x13d377(0x2bd)](_0xb9b230,_0x35c367,_0x5795ba);},'uDPnZ':_0xfd56d2[_0x59785f(0x3b6)],'dDcRK':function(_0xfa7f93,_0x3c7bb4){const _0xfd5163=_0x59785f;return _0xfd56d2[_0xfd5163(0x468)](_0xfa7f93,_0x3c7bb4);},'tcFIa':_0xfd56d2['jlhfb'],'COisC':function(_0x344853,_0x36fbe8){return _0x344853===_0x36fbe8;},'sujKV':_0xfd56d2[_0x59785f(0x4a8)],'FKiiZ':_0xfd56d2[_0x59785f(0x2aa)],'Xodum':function(_0x5e618b,_0x46c989){const _0x527ac9=_0x59785f;return _0xfd56d2[_0x527ac9(0x5c4)](_0x5e618b,_0x46c989);},'yoleI':_0xfd56d2[_0x59785f(0x42d)],'jeoUi':function(_0x38b480,_0x585741){const _0x3cc5a9=_0x59785f;return _0xfd56d2[_0x3cc5a9(0x5c4)](_0x38b480,_0x585741);},'CLCOp':function(_0x2bbf07,_0x42e776){return _0x2bbf07!==_0x42e776;},'AbKJl':_0xfd56d2[_0x59785f(0x328)],'dNdBo':_0x59785f(0x648),'wRHZn':_0xfd56d2[_0x59785f(0x48a)],'tnXmz':_0x59785f(0x674),'Trbag':_0x59785f(0x189),'ZyxKf':function(_0xc7fd8b,_0x2f9a30){const _0x32442b=_0x59785f;return _0xfd56d2[_0x32442b(0x6b3)](_0xc7fd8b,_0x2f9a30);},'dkZWc':_0xfd56d2['mRynG'],'Zisdx':function(_0xe0e4fd,_0x293374,_0x3d3295,_0x5a04c1,_0x3589c6){const _0x34546e=_0x59785f;return _0xfd56d2[_0x34546e(0x559)](_0xe0e4fd,_0x293374,_0x3d3295,_0x5a04c1,_0x3589c6);}},_0x258cbe=_0xfd56d2[_0x59785f(0x245)];try{const _0x50620a=await fs['readFile'](_0x258cbe,_0xfd56d2[_0x59785f(0x3b6)])[_0x59785f(0x4c8)](()=>''),_0x263d5e=_0x50620a[_0x59785f(0x19b)]('\x0a')['filter'](_0x2b72e0=>_0x2b72e0[_0x59785f(0x3ea)]());for(const _0x441c9c of _0x263d5e){if(_0xfd56d2[_0x59785f(0x2d5)](_0xfd56d2['fXxth'],_0xfd56d2[_0x59785f(0x359)])){const _0x3937fd={};_0x3937fd[_0x59785f(0x492)]=![],_0x3937fd[_0x59785f(0x618)]=_0x2b94be[_0x59785f(0xef)],_0x574213[_0x1a65de['name']]=_0x3937fd;}else{const [_0x13860a,_0xe7a3bb]=_0x441c9c[_0x59785f(0x19b)](':');if(_0xfd56d2[_0x59785f(0x6b3)](_0x13860a,_0x2e8b53)&&_0xe7a3bb){const _0x239900=_0xfd56d2[_0x59785f(0x2ee)](_0x3b7a5c,_0xfd56d2[_0x59785f(0x35a)])?0x1fa4:0x1fa4,_0x321228='http://'+_0x3b7a5c+':'+_0x239900+_0x59785f(0x601)+_0xe7a3bb,_0x5d092a=_0xfd56d2[_0x59785f(0x2bd)](spawn,_0xfd56d2[_0x59785f(0x3c3)],['-s','-X',_0xfd56d2[_0x59785f(0x70b)],_0x321228]);let _0x2d1834='';_0x5d092a[_0x59785f(0x551)]['on'](_0x59785f(0x49b),_0x37001e=>{const _0x40bc24=_0x59785f;_0x1c72c5[_0x40bc24(0x588)](_0x40bc24(0x3b4),_0x1c72c5['tcFIa'])?_0x2e90ab=_0x1c72c5[_0x40bc24(0x5f7)](_0x214a60,_0x40bc24(0xaa)+_0x11e6dd+_0x40bc24(0x37b),{'encoding':_0x1c72c5[_0x40bc24(0x693)],'timeout':0x7530}):_0x2d1834+=_0x37001e['toString']();}),_0x5d092a['on'](_0x59785f(0x3a0),_0x226d02=>{const _0xf1829e=_0x59785f;if(_0x1c72c5[_0xf1829e(0x425)](_0x1c72c5[_0xf1829e(0xd0)],_0x1c72c5[_0xf1829e(0x590)])){if(_0x226d02===0x0&&_0x2d1834&&!_0x2d1834[_0xf1829e(0x185)](_0x1c72c5['wRHZn'])){if(_0x1c72c5[_0xf1829e(0x659)](_0x1c72c5['tnXmz'],_0x1c72c5[_0xf1829e(0x3cd)])){if(_0x1c72c5[_0xf1829e(0x659)](_0x26f5ec[_0xf1829e(0x625)],_0x582d09[_0xf1829e(0x467)])){const _0x289c0c={};_0x289c0c[_0xf1829e(0x2ba)]=_0x1c72c5[_0xf1829e(0x1a9)],_0x289c0c['devices']=_0xbcd013,_0x1c3282[_0xf1829e(0x65f)](_0x2e9d9e[_0xf1829e(0x62d)](_0x289c0c));}}else{console[_0xf1829e(0x37a)]('ā
\x20Existing\x20valid\x20session\x20found:\x20'+_0xe7a3bb);const _0xaee297={};return _0xaee297[_0xf1829e(0x492)]=!![],_0xaee297[_0xf1829e(0x75c)]=_0xe7a3bb,_0xaee297[_0xf1829e(0x643)]=!![],_0x1e0407(_0xaee297);}}else _0x1c72c5['ZyxKf'](_0x1c72c5[_0xf1829e(0x197)],_0x1c72c5['dkZWc'])?_0x1c72c5[_0xf1829e(0x202)](createNewSession,_0x3b7a5c,_0x2e8b53,_0x258cbe,_0x1e0407):_0x2a683f['log'](_0xf1829e(0x76b)+_0x156c17[_0xf1829e(0x2ca)]()[_0xf1829e(0x3ea)]());}else{let _0x1d6b9b=_0x21b3be[_0xf1829e(0x4a3)](_0xcfff3,GUSKPX[_0xf1829e(0x578)],_0x14a385);if(GUSKPX['Xodum'](_0x2ab5c4,'fs')[_0xf1829e(0x4d6)](_0x1d6b9b))return _0x1d6b9b;_0x1d6b9b=_0xfb321[_0xf1829e(0x4a3)](_0x59b51b,GUSKPX[_0xf1829e(0x276)],_0x3882ef);if(_0xa74f1e('fs')[_0xf1829e(0x4d6)](_0x1d6b9b))return _0x1d6b9b;const _0x2a8eb4=_0x300945['replace'](/\.sh$/,'');_0x1d6b9b=_0x306b93[_0xf1829e(0x4a3)](_0x3a8ac5,_0xf1829e(0x661),_0x2a8eb4);if(GUSKPX[_0xf1829e(0x42b)](_0x18cb0e,'fs')[_0xf1829e(0x4d6)](_0x1d6b9b))return _0x1d6b9b;return _0x267a0f[_0xf1829e(0x4a3)](_0x262c1c,GUSKPX[_0xf1829e(0x578)],_0x2eb030);}});return;}}}}catch(_0x35775d){}_0xfd56d2[_0x59785f(0x559)](createNewSession,_0x3b7a5c,_0x2e8b53,_0x258cbe,_0x1e0407);});}function createNewSession(_0x2d6338,_0x8af00b,_0x3c6264,_0x2c7e83){const _0x325472=_0x50607,_0x37f9ec={'ijYlQ':function(_0x526627,_0x45713b){return _0x526627!==_0x45713b;},'oQfdy':function(_0x4e669a,_0x26d9e0){return _0x4e669a+_0x26d9e0;},'TXePd':function(_0x4b8236,_0x28187e){return _0x4b8236(_0x28187e);},'FkEGJ':function(_0x302ba9,_0x3c02cc){return _0x302ba9===_0x3c02cc;},'VHdWv':_0x325472(0x2b2),'jLPpL':_0x325472(0x191),'FFaGi':_0x325472(0x74f),'bTDVJ':function(_0x3851b3,_0x376cac){return _0x3851b3===_0x376cac;},'AdypE':_0x325472(0x4b6),'sDwaJ':_0x325472(0x4d2),'iSLGq':'xCweG','MYdCK':_0x325472(0xb4),'PsthY':function(_0x49a4af,_0x227593){return _0x49a4af!==_0x227593;},'udFEE':_0x325472(0x70c),'ynfUM':'Failed\x20to\x20parse\x20WDA\x20session\x20response:','fSLPO':'ospJe','raMNL':function(_0x595957,_0xb8531c){return _0x595957(_0xb8531c);},'ZbDIQ':function(_0x5101ac,_0x2d3d4a,_0x28899a){return _0x5101ac(_0x2d3d4a,_0x28899a);},'NplMe':_0x325472(0x737),'hiVhx':'POST','FsHve':'Content-Type:\x20application/json','gmKWn':_0x325472(0x274),'ezGQv':_0x325472(0x49b),'pZloS':_0x325472(0x618)},_0x288fe5=_0x2d6338===_0x325472(0x52b)?0x1fa4:0x1fa4,_0x4ccf36='http://'+_0x2d6338+':'+_0x288fe5+_0x325472(0x673),_0x55a6c8=_0x37f9ec[_0x325472(0x6be)](spawn,_0x37f9ec[_0x325472(0x3d8)],['-s','-X',_0x37f9ec[_0x325472(0x44e)],_0x4ccf36,'-H',_0x37f9ec[_0x325472(0x175)],'-d',_0x37f9ec[_0x325472(0xab)]]);let _0x3de35b='';_0x55a6c8[_0x325472(0x551)]['on'](_0x37f9ec[_0x325472(0x72e)],_0x3e09e0=>{_0x3de35b+=_0x3e09e0['toString']();}),_0x55a6c8['on'](_0x325472(0x3a0),_0x49bd40=>{const _0x2cee12=_0x325472,_0x5a9e72={'ckDBR':function(_0x407402,_0x96f2b){const _0x321bff=_0x46ca;return _0x37f9ec[_0x321bff(0x422)](_0x407402,_0x96f2b);},'HGKAI':function(_0x23d132,_0x5cf60b){const _0x3bcfc3=_0x46ca;return _0x37f9ec[_0x3bcfc3(0x2f9)](_0x23d132,_0x5cf60b);},'nzSit':_0x37f9ec[_0x2cee12(0x665)],'HvOGS':_0x37f9ec[_0x2cee12(0x3dc)],'oFOQO':_0x37f9ec[_0x2cee12(0x1a6)],'RPRXT':function(_0x3dec7e){return _0x3dec7e();}};if(_0x37f9ec[_0x2cee12(0x3ef)](_0x37f9ec[_0x2cee12(0x158)],_0x37f9ec[_0x2cee12(0x4fa)]))_0x2c9739[_0x2cee12(0x75c)]=_0x26045a[_0x2cee12(0x75c)];else{if(_0x49bd40===0x0&&_0x3de35b){if(_0x37f9ec[_0x2cee12(0x21c)]!==_0x2cee12(0x3b5))try{const _0x576961=JSON[_0x2cee12(0x288)](_0x3de35b),_0x9ea2c5=_0x576961[_0x2cee12(0x75c)]||_0x576961[_0x2cee12(0x55d)]?.['sessionId'];if(_0x9ea2c5)fs[_0x2cee12(0x642)](_0x3c6264,_0x37f9ec[_0x2cee12(0x33d)])[_0x2cee12(0x4c8)](()=>'')['then'](_0x4b72bd=>{const _0x356e49=_0x2cee12,_0xe84d67={'tmNvA':'abgrh','FGxxU':function(_0x3184c3,_0x35896a){const _0x4ab6c9=_0x46ca;return _0x37f9ec[_0x4ab6c9(0x38c)](_0x3184c3,_0x35896a);}},_0x28c1ed=_0x4b72bd['split']('\x0a')[_0x356e49(0x5a2)](_0x319e47=>{const _0x344920=_0x356e49;if(_0xe84d67[_0x344920(0x2cb)]!==_0xe84d67[_0x344920(0x2cb)]){const _0x207abf={};_0x207abf[_0x344920(0x492)]=![],_0x207abf['error']=_0x1e0c2c[_0x344920(0xef)],_0x259f27[_0x344920(0x160)](0x1f4)['json'](_0x207abf);}else{const [_0x16248c]=_0x319e47[_0x344920(0x19b)](':');return _0x319e47[_0x344920(0x3ea)]()&&_0xe84d67[_0x344920(0x3e5)](_0x16248c,_0x8af00b);}});return _0x28c1ed['push'](_0x8af00b+':'+_0x9ea2c5),fs[_0x356e49(0x4b5)](_0x3c6264,_0x37f9ec[_0x356e49(0x17a)](_0x28c1ed[_0x356e49(0x4a3)]('\x0a'),'\x0a'));})[_0x2cee12(0x4a9)](()=>{const _0x1aec5e=_0x2cee12;console[_0x1aec5e(0x37a)](_0x1aec5e(0x431)+_0x9ea2c5);const _0x16c6a4={};_0x16c6a4[_0x1aec5e(0x492)]=!![],_0x16c6a4[_0x1aec5e(0x75c)]=_0x9ea2c5,_0x5a9e72[_0x1aec5e(0x760)](_0x2c7e83,_0x16c6a4);})['catch'](_0x415055=>{const _0x5b04c3=_0x2cee12;if(_0x5a9e72[_0x5b04c3(0x701)](_0x5a9e72[_0x5b04c3(0x6a6)],_0x5a9e72['HvOGS']))_0xe14e80=_0x63b5cc[_0x5b04c3(0x632)];else{console[_0x5b04c3(0x618)](_0x5b04c3(0x112)+_0x8af00b+':',_0x415055);const _0x2c24e1={};_0x2c24e1[_0x5b04c3(0x492)]=![],_0x2c7e83(_0x2c24e1);}});else{const _0x1300ef={};_0x1300ef[_0x2cee12(0x492)]=![],_0x2c7e83(_0x1300ef);}}catch(_0xab6d1d){if(_0x37f9ec[_0x2cee12(0x51d)](_0x37f9ec[_0x2cee12(0x64c)],_0x37f9ec[_0x2cee12(0x64c)])){_0x3d74d4['error'](_0x5a9e72[_0x2cee12(0x5d2)],_0x298cec);const _0x33d8eb={};_0x33d8eb[_0x2cee12(0x492)]=![],_0x5a9e72['ckDBR'](_0x564650,_0x33d8eb);}else{console[_0x2cee12(0x618)](_0x37f9ec[_0x2cee12(0x2e5)],_0xab6d1d);const _0xd93a29={};_0xd93a29[_0x2cee12(0x492)]=![],_0x2c7e83(_0xd93a29);}}else _0x105873?_0x800c12['close'](_0x3a509b):_0x5a9e72[_0x2cee12(0x3a2)](_0x5a3c72);}else{const _0x13dd72={};_0x13dd72[_0x2cee12(0x492)]=![],_0x37f9ec[_0x2cee12(0x422)](_0x2c7e83,_0x13dd72);}}}),_0x55a6c8['on'](_0x37f9ec[_0x325472(0x615)],_0x13ea6b=>{const _0x29861c=_0x325472;if(_0x37f9ec[_0x29861c(0x3ef)](_0x37f9ec[_0x29861c(0xf5)],_0x29861c(0x461))){const _0x552656={};_0x552656[_0x29861c(0x492)]=![],_0x552656[_0x29861c(0x618)]=_0x59d1b2[_0x29861c(0xef)],_0x4108fe[_0x29861c(0x160)](0x1f4)['json'](_0x552656);}else{console['error'](_0x37f9ec[_0x29861c(0x1a6)],_0x13ea6b);const _0x220009={};_0x220009[_0x29861c(0x492)]=![],_0x37f9ec[_0x29861c(0x3a1)](_0x2c7e83,_0x220009);}});}function _0x46ca(_0x52f3ed,_0x5006ef){_0x52f3ed=_0x52f3ed-0xa8;const _0x3c826f=_0x3c82();let _0x46ca97=_0x3c826f[_0x52f3ed];if(_0x46ca['SbauIt']===undefined){var _0x3336c3=function(_0x36b395){const _0x1d84dc='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x378752='',_0x4c2faa='';for(let _0x4ddac5=0x0,_0x1f2eb4,_0x54f218,_0x1eea58=0x0;_0x54f218=_0x36b395['charAt'](_0x1eea58++);~_0x54f218&&(_0x1f2eb4=_0x4ddac5%0x4?_0x1f2eb4*0x40+_0x54f218:_0x54f218,_0x4ddac5++%0x4)?_0x378752+=String['fromCharCode'](0xff&_0x1f2eb4>>(-0x2*_0x4ddac5&0x6)):0x0){_0x54f218=_0x1d84dc['indexOf'](_0x54f218);}for(let _0x57c9df=0x0,_0x55eee8=_0x378752['length'];_0x57c9df<_0x55eee8;_0x57c9df++){_0x4c2faa+='%'+('00'+_0x378752['charCodeAt'](_0x57c9df)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x4c2faa);};_0x46ca['rWkyef']=_0x3336c3,_0x46ca['YcnYHw']={},_0x46ca['SbauIt']=!![];}const _0x2830a0=_0x3c826f[0x0],_0x592dc7=_0x52f3ed+_0x2830a0,_0x21ec39=_0x46ca['YcnYHw'][_0x592dc7];return!_0x21ec39?(_0x46ca97=_0x46ca['rWkyef'](_0x46ca97),_0x46ca['YcnYHw'][_0x592dc7]=_0x46ca97):_0x46ca97=_0x21ec39,_0x46ca97;}async function installUIAutomator2(_0x58c025,_0x2299d4){const _0x34f0fc=_0x50607,_0x2e9eb0={'srWsM':function(_0x294604,_0x34157f){return _0x294604===_0x34157f;},'mHqDD':_0x34f0fc(0x246),'luCIT':function(_0x4f1b8a,_0x3194d2){return _0x4f1b8a(_0x3194d2);},'vrKgf':_0x34f0fc(0x2a3),'TlKga':function(_0x3268b8,_0x369fe9){return _0x3268b8(_0x369fe9);},'Gkiii':_0x34f0fc(0x552),'SIANn':_0x34f0fc(0x181),'zBbZU':_0x34f0fc(0x27f),'JMQzu':_0x34f0fc(0x700),'OKgnf':'utf-8','yQPEE':_0x34f0fc(0x695),'KiotO':function(_0x3b246f,_0x1084af){return _0x3b246f+_0x1084af;},'RFhSk':_0x34f0fc(0x2cd),'pTZpE':'govqF','OyAJo':_0x34f0fc(0x14d),'NODdV':_0x34f0fc(0x708),'XpoKD':function(_0x36e256,_0x59e3fe,_0x572de0){return _0x36e256(_0x59e3fe,_0x572de0);},'spMOx':function(_0x5a5e9d,_0x5a23c8,_0x5e5953){return _0x5a5e9d(_0x5a23c8,_0x5e5953);},'uqVQO':function(_0x44d4e1,_0x3b34cf){return _0x44d4e1&&_0x3b34cf;},'OTMDz':function(_0x197537,_0x27ce2d,_0x49e48d){return _0x197537(_0x27ce2d,_0x49e48d);},'eLJWY':'APKs\x20not\x20found.\x20Tried\x20to\x20reinstall\x20driver.\x20Please\x20run:\x20appium\x20driver\x20install\x20uiautomator2','aCXcv':function(_0x314458,_0xa9f033){return _0x314458(_0xa9f033);},'hhwkF':_0x34f0fc(0x6c4),'qgGgC':function(_0x3415c8,_0x476175){return _0x3415c8===_0x476175;},'RUJfU':_0x34f0fc(0x341)};return new Promise(_0x4f5e59=>{const _0x22cced=_0x34f0fc,_0x27593d={};_0x27593d[_0x22cced(0x206)]=_0x22cced(0x194);const _0xd1d87e=_0x27593d;console['log'](_0x22cced(0x64b)+_0x2299d4+_0x22cced(0x29d));const {execSync:_0x10bc16}=_0x2e9eb0[_0x22cced(0x43c)](require,_0x2e9eb0[_0x22cced(0x1e5)]),_0x435bc2=_0x2e9eb0[_0x22cced(0x608)](require,'os'),_0x26b6ec=_0x2e9eb0[_0x22cced(0x43c)](require,_0x2e9eb0[_0x22cced(0x28e)]);try{const _0x3ecbf0=[_0x26b6ec[_0x22cced(0x4a3)](_0x435bc2[_0x22cced(0x51b)](),_0x2e9eb0[_0x22cced(0x365)],_0x2e9eb0[_0x22cced(0x583)],_0x2e9eb0[_0x22cced(0x270)],_0x22cced(0x27f),'appium-uiautomator2-server',_0x22cced(0x686)),_0x10bc16('npm\x20root\x20-g',{'encoding':_0x2e9eb0['OKgnf']})[_0x22cced(0x3ea)]()+_0x2e9eb0[_0x22cced(0x3c9)],_0x2e9eb0[_0x22cced(0x464)](_0x10bc16(_0x2e9eb0[_0x22cced(0x294)],{'encoding':_0x2e9eb0[_0x22cced(0x18a)]})[_0x22cced(0x3ea)](),_0x22cced(0x526))];let _0x10d4d7=null,_0x56a158=null,_0x22d9b7=null;for(const _0x102bc2 of _0x3ecbf0){if(_0x2e9eb0[_0x22cced(0x1f0)]===_0x2e9eb0[_0x22cced(0x330)]){const _0x54e8c0={};return _0x54e8c0['success']=![],_0x54e8c0[_0x22cced(0x618)]=_0xd1d87e['ykyqJ'],_0x54e8c0;}else{console[_0x22cced(0x37a)](_0x22cced(0x54f)+_0x102bc2);try{if(_0x2e9eb0[_0x22cced(0x74c)]===_0x2e9eb0[_0x22cced(0x74c)]){const _0x48a9f8=_0x2e9eb0[_0x22cced(0x6c0)](_0x10bc16,_0x22cced(0x388)+_0x102bc2+'\x22/appium-uiautomator2-server-v*.apk\x202>/dev/null\x20||\x20echo\x20\x22\x22',{'encoding':_0x2e9eb0[_0x22cced(0x18a)]})[_0x22cced(0x3ea)](),_0x7fee23=_0x2e9eb0['spMOx'](_0x10bc16,'ls\x20\x22'+_0x102bc2+_0x22cced(0x56e),{'encoding':_0x2e9eb0[_0x22cced(0x18a)]})['trim']();if(_0x2e9eb0[_0x22cced(0x1ef)](_0x48a9f8,_0x7fee23)){_0x10d4d7=_0x48a9f8,_0x56a158=_0x7fee23,_0x22d9b7=_0x102bc2,console[_0x22cced(0x37a)](_0x22cced(0x75a)+_0x22d9b7);break;}}else{if(_0x2e9eb0[_0x22cced(0x3c0)](_0x450b58[_0x22cced(0x625)],_0x10f530[_0x22cced(0x467)])){const _0x35c173={};_0x35c173[_0x22cced(0x2ba)]=_0x2e9eb0[_0x22cced(0xfd)],_0x35c173[_0x22cced(0x3d4)]=_0x186772,_0x28de8b[_0x22cced(0x65f)](_0x1a151a['stringify'](_0x35c173));}}}catch(_0x4e9fa2){continue;}}}if(_0x2e9eb0[_0x22cced(0x1ef)](_0x10d4d7,_0x56a158)){console[_0x22cced(0x37a)](_0x22cced(0x3ee)+_0x10d4d7);const _0xbdc5a4=_0x2e9eb0['OTMDz'](_0x10bc16,_0x22cced(0x358)+_0x58c025+'\x20install\x20-r\x20\x22'+_0x10d4d7+_0x22cced(0x3e1),{'encoding':_0x2e9eb0['OKgnf']});console[_0x22cced(0x37a)](_0xbdc5a4),console[_0x22cced(0x37a)](_0x22cced(0x595)+_0x56a158);const _0x3da7b1={};_0x3da7b1[_0x22cced(0x4c0)]=_0x22cced(0xb4);const _0x4fda78=_0x10bc16(_0x22cced(0x358)+_0x58c025+_0x22cced(0x480)+_0x56a158+_0x22cced(0x3e1),_0x3da7b1);console[_0x22cced(0x37a)](_0x4fda78),console[_0x22cced(0x37a)](_0x22cced(0x2f5)+_0x2299d4);const _0xbbdc84={};_0xbbdc84[_0x22cced(0x492)]=!![],_0xbbdc84[_0x22cced(0xef)]='UIAutomator2\x20installed\x20successfully',_0x2e9eb0[_0x22cced(0x43c)](_0x4f5e59,_0xbbdc84);}else{console[_0x22cced(0x37a)](_0x22cced(0x68a)),console[_0x22cced(0x37a)](_0x22cced(0x46b),_0x3ecbf0);try{console[_0x22cced(0x37a)]('š\x20Trying\x20to\x20install\x20via\x20Appium...');const _0x30f39a={};_0x30f39a[_0x22cced(0x4c0)]='utf-8';const _0x244e4f=_0x2e9eb0[_0x22cced(0x6f0)](_0x10bc16,_0x22cced(0x2ec),_0x30f39a);console[_0x22cced(0x37a)](_0x244e4f),_0x2e9eb0['luCIT'](_0x4f5e59,{'success':![],'message':_0x2e9eb0[_0x22cced(0x3b7)]});}catch(_0x516b0a){_0x2e9eb0[_0x22cced(0x417)](_0x4f5e59,{'success':![],'message':_0x2e9eb0['hhwkF']});}}}catch(_0x2edafe){if(_0x2e9eb0[_0x22cced(0x368)](_0x2e9eb0[_0x22cced(0x553)],_0x22cced(0x4ec)))_0x381f5e+=_0x36e29f[_0x22cced(0x2ca)]();else{console['error']('ā\x20Failed\x20to\x20install\x20UIAutomator2:\x20'+_0x2edafe['message']);const _0x71f5d0={};_0x71f5d0['success']=![],_0x71f5d0[_0x22cced(0xef)]=_0x22cced(0x371)+_0x2edafe[_0x22cced(0xef)],_0x2e9eb0['TlKga'](_0x4f5e59,_0x71f5d0);}}});}async function connectToDevice(_0x4a0a8d){const _0x265f0f=_0x50607,_0x1a92f9={'wQfLg':function(_0x149cd6,_0x43aab0,_0x206b5c){return _0x149cd6(_0x43aab0,_0x206b5c);},'XixHo':function(_0x2a8634,_0x2511f4){return _0x2a8634===_0x2511f4;},'HiYxK':_0x265f0f(0x128),'IDpka':_0x265f0f(0x4ba),'sJHmD':function(_0x215deb,_0x4d1872){return _0x215deb(_0x4d1872);},'qoQtU':_0x265f0f(0x47d),'aEvdh':_0x265f0f(0x712),'kpBCD':_0x265f0f(0x653),'QeqtQ':_0x265f0f(0x3aa),'hbGqN':function(_0x998b67,_0x437eb4){return _0x998b67!==_0x437eb4;},'StPhv':'online','FwvPS':_0x265f0f(0x2ad),'BPYta':_0x265f0f(0x52b),'Utsev':function(_0x4b0a8f,_0x1721f9){return _0x4b0a8f!==_0x1721f9;},'biTKS':function(_0x40be2a,_0x3b9fde){return _0x40be2a===_0x3b9fde;},'AnAqg':_0x265f0f(0x30d),'vQYCn':function(_0x29c42e,_0xa9b8cc){return _0x29c42e(_0xa9b8cc);},'QwdJS':function(_0x2e4239,_0x281ab0){return _0x2e4239!==_0x281ab0;},'ywFej':'Downloads/WebDriverAgent-10.2.1','ZCpGu':function(_0x298657,_0xf351c5,_0x6fa48d,_0x4cb6d4){return _0x298657(_0xf351c5,_0x6fa48d,_0x4cb6d4);},'OpuKh':'test','UkAfe':_0x265f0f(0x317),'jTwjh':_0x265f0f(0x25e),'hQxec':_0x265f0f(0x36f),'AuiMD':_0x265f0f(0x766),'fTpkH':_0x265f0f(0x493),'flBAl':_0x265f0f(0x49b),'FQWmR':_0x265f0f(0x618),'dmTks':function(_0x6b3109,_0x4b27e3,_0x52ac69,_0x1d9c5b){return _0x6b3109(_0x4b27e3,_0x52ac69,_0x1d9c5b);},'ymxZF':_0x265f0f(0x4b4),'AozsF':_0x265f0f(0x20d),'jTQwe':_0x265f0f(0x342),'exNcd':function(_0x53ba22,_0x5dd53c,_0x48528e){return _0x53ba22(_0x5dd53c,_0x48528e);},'vpouf':function(_0x86549f,_0x51a4e0){return _0x86549f(_0x51a4e0);},'eeAgb':function(_0xb1c5e8){return _0xb1c5e8();},'SJIvI':'JcuAs','OeZMV':_0x265f0f(0x66b),'fYRcE':_0x265f0f(0x3a7),'stcAx':_0x265f0f(0x59d),'zsnHf':function(_0x14c630,_0x56823d){return _0x14c630(_0x56823d);},'kDoSB':function(_0x422d13,_0x1ee11a){return _0x422d13===_0x1ee11a;},'LPvis':_0x265f0f(0xf0),'lUdcg':_0x265f0f(0x718),'xaFzk':_0x265f0f(0x451),'CvjVe':_0x265f0f(0x143),'lxbum':_0x265f0f(0x193),'kPmtV':function(_0x5cdaec,_0x44f7a6){return _0x5cdaec(_0x44f7a6);},'woRRJ':function(_0x541895,_0x390263,_0x5d08b6,_0xaf7a2f){return _0x541895(_0x390263,_0x5d08b6,_0xaf7a2f);},'lGSLC':_0x265f0f(0x4dc),'Zntti':'Failed\x20to\x20start\x20server:','cbpCF':_0x265f0f(0x67e),'EmnEJ':'mLMOs','Lpwvu':'io.appium.uiautomator2','UZyeS':function(_0x3fb755,_0x151136){return _0x3fb755(_0x151136);},'oIPHT':function(_0xc85f5f,_0x548bbb,_0xdc2806){return _0xc85f5f(_0x548bbb,_0xdc2806);},'QGnKv':_0x265f0f(0x5be),'tPGIM':_0x265f0f(0x32f),'XvbJw':_0x265f0f(0x6aa),'XQTLF':'ezJpq','FhgBG':_0x265f0f(0x32d),'HMytc':_0x265f0f(0x61f),'kWeXg':_0x265f0f(0x646),'YFLyg':_0x265f0f(0x161),'XRxdj':_0x265f0f(0x207),'xyWPY':_0x265f0f(0x2a3),'YUJiH':_0x265f0f(0xb6),'RfPar':_0x265f0f(0x1c8),'MZPFp':'GoUBb','mMgFJ':_0x265f0f(0x547),'VEMAg':function(_0x3d90bb,_0x359001,_0x2ce340){return _0x3d90bb(_0x359001,_0x2ce340);},'wfWIg':function(_0x5e2f44,_0x2078ce){return _0x5e2f44!==_0x2078ce;},'TRLvq':'HVEAi','EcFHJ':_0x265f0f(0xc8),'FKwJJ':'GXslW','WsprR':_0x265f0f(0x4ac),'bLNTL':_0x265f0f(0x70e),'eofsY':'shell','YpMBt':'list','wcrzs':'packages','NMdRB':_0x265f0f(0x22d),'cqJFA':_0x265f0f(0x6b9),'AayiE':_0x265f0f(0xca),'ZOjci':_0x265f0f(0x513),'uvrnT':_0x265f0f(0x734),'TIyyo':'close','HuCec':_0x265f0f(0x5bd),'EnSmg':_0x265f0f(0x634),'ODXqZ':_0x265f0f(0x606),'fiygV':_0x265f0f(0x55b),'tkAuo':_0x265f0f(0x5ee),'fxRcQ':function(_0x49ddc4,_0x2b0e8c){return _0x49ddc4===_0x2b0e8c;},'jVLmv':_0x265f0f(0x1e7),'GzquQ':'WebDriverAgent','NXVDc':_0x265f0f(0xdc),'NkqKL':_0x265f0f(0x353),'dlWgr':_0x265f0f(0x478),'dIMnU':_0x265f0f(0x572),'IVYbY':_0x265f0f(0x3ca),'vgjvN':function(_0x166b49,_0x5c6f57){return _0x166b49===_0x5c6f57;},'KlYGZ':function(_0x47d8c9,_0xef6566){return _0x47d8c9!==_0xef6566;},'EnnvY':'warning:','kBWBb':_0x265f0f(0xc2),'cOaSJ':'TlqvG','dySrC':_0x265f0f(0xd6),'iGoXC':_0x265f0f(0x737),'GPkyp':_0x265f0f(0x719),'RBwMW':_0x265f0f(0x412),'ZzXWU':_0x265f0f(0x714),'rndat':function(_0x2dce1,_0x55041b,_0x22a4b8){return _0x2dce1(_0x55041b,_0x22a4b8);}};return new Promise(async(_0xa0c362,_0x5a23e6)=>{const _0x36e88e=_0x265f0f,_0x4f2eba={'cKyJJ':'devices_updated','VytZA':_0x1a92f9[_0x36e88e(0x15d)],'hKDTd':_0x1a92f9[_0x36e88e(0x3dd)],'imlQQ':_0x1a92f9['EmnEJ'],'Rcwrx':_0x1a92f9[_0x36e88e(0x38f)],'vgdgx':function(_0x4853fb,_0x1a9c1f,_0x5b16c1){const _0xf7a2a4=_0x36e88e;return _0x1a92f9[_0xf7a2a4(0x4cb)](_0x4853fb,_0x1a9c1f,_0x5b16c1);},'ihdQO':function(_0x3dda80,_0x3a3d58){const _0x4710e2=_0x36e88e;return _0x1a92f9[_0x4710e2(0x2d6)](_0x3dda80,_0x3a3d58);},'OxjjC':function(_0x4468df,_0x48d10d){return _0x1a92f9['vQYCn'](_0x4468df,_0x48d10d);},'QbdAN':_0x1a92f9[_0x36e88e(0x107)],'pZCAl':function(_0x326b82,_0x1084cb){return _0x326b82(_0x1084cb);},'gWIUV':function(_0x49bee1,_0x97ad91,_0x4e7901){const _0x524d67=_0x36e88e;return _0x1a92f9[_0x524d67(0x373)](_0x49bee1,_0x97ad91,_0x4e7901);},'SavuL':function(_0x2f7b78,_0x59059e){const _0x1ae762=_0x36e88e;return _0x1a92f9[_0x1ae762(0x1e0)](_0x2f7b78,_0x59059e);},'RlTsl':_0x1a92f9[_0x36e88e(0x48c)],'dmyGm':_0x1a92f9[_0x36e88e(0x5f3)],'soFKp':_0x1a92f9[_0x36e88e(0x310)],'EfEkD':function(_0x3dee5c,_0x406580){const _0x2b4048=_0x36e88e;return _0x1a92f9[_0x2b4048(0x3e7)](_0x3dee5c,_0x406580);},'gZDOe':_0x1a92f9[_0x36e88e(0x244)],'Zeusv':_0x1a92f9['FhgBG'],'MArXS':function(_0x5072f9,_0x4434b5){return _0x5072f9===_0x4434b5;},'OApzA':_0x1a92f9[_0x36e88e(0x5c7)],'pgoeI':_0x1a92f9['kWeXg'],'pdgmg':_0x1a92f9[_0x36e88e(0x53b)],'TSSdA':_0x1a92f9[_0x36e88e(0x145)],'bargc':_0x1a92f9['xyWPY'],'IwNro':_0x1a92f9[_0x36e88e(0x63b)],'Zqdlp':_0x1a92f9['RfPar'],'gWYQv':_0x1a92f9[_0x36e88e(0x65c)],'oCukm':function(_0x5bbda8,_0x1e4c58){const _0x5a651c=_0x36e88e;return _0x1a92f9[_0x5a651c(0x33f)](_0x5bbda8,_0x1e4c58);},'ViyfJ':_0x1a92f9[_0x36e88e(0x1ed)],'bvWVm':function(_0x112340,_0x5d2668,_0x3f0c1e){const _0x49860d=_0x36e88e;return _0x1a92f9[_0x49860d(0x29f)](_0x112340,_0x5d2668,_0x3f0c1e);},'jvPpJ':function(_0x40e60f,_0x49f4b1){const _0x1a1e07=_0x36e88e;return _0x1a92f9[_0x1a1e07(0xdf)](_0x40e60f,_0x49f4b1);},'ltVJz':_0x1a92f9[_0x36e88e(0x264)],'IlvRI':_0x1a92f9['EcFHJ'],'cuQPj':function(_0x541525,_0x4ad9fb){return _0x541525===_0x4ad9fb;},'oGJVh':_0x1a92f9['FKwJJ'],'MFcTX':_0x1a92f9[_0x36e88e(0x6d5)],'LsRYT':function(_0x255ea9,_0x58de6b,_0x5eee36){return _0x1a92f9['oIPHT'](_0x255ea9,_0x58de6b,_0x5eee36);},'bYymw':_0x1a92f9[_0x36e88e(0x70a)],'PsCsJ':_0x1a92f9['eofsY'],'EZBbe':_0x1a92f9['YpMBt'],'vVQrA':_0x1a92f9[_0x36e88e(0x227)],'kgoFY':function(_0x2a3e3f,_0x6e89fa){return _0x2a3e3f(_0x6e89fa);},'btolq':_0x1a92f9['NMdRB'],'grYMh':_0x1a92f9[_0x36e88e(0x242)],'Cnhmp':function(_0x1801e9,_0xf27afd){return _0x1801e9>=_0xf27afd;},'RnRzZ':_0x1a92f9['AayiE'],'VHUnC':_0x1a92f9[_0x36e88e(0x35f)],'tLVVN':_0x1a92f9['uvrnT'],'aqnhg':function(_0x310e08,_0x398f48,_0x3c137a){return _0x1a92f9['oIPHT'](_0x310e08,_0x398f48,_0x3c137a);},'BHBUZ':_0x36e88e(0x49b),'sSevC':_0x1a92f9[_0x36e88e(0x1ce)],'UFBfn':function(_0x1fc373,_0x108373){return _0x1fc373===_0x108373;},'VIDRu':_0x1a92f9[_0x36e88e(0x355)],'szjyK':function(_0x709798,_0x34b7e9){return _0x709798(_0x34b7e9);},'Dwklj':_0x1a92f9[_0x36e88e(0x6b6)],'oEhSN':_0x1a92f9['ODXqZ'],'MkvbV':function(_0x31875e,_0x502ed0){const _0x5ab09d=_0x36e88e;return _0x1a92f9[_0x5ab09d(0x23a)](_0x31875e,_0x502ed0);},'XJQUU':_0x1a92f9[_0x36e88e(0x538)],'CLUph':_0x1a92f9[_0x36e88e(0x50d)],'jmahW':function(_0x5ddd7a,_0x5d5dd8){const _0x36f45e=_0x36e88e;return _0x1a92f9[_0x36f45e(0xd2)](_0x5ddd7a,_0x5d5dd8);},'ESSTT':_0x1a92f9[_0x36e88e(0x6d0)],'VlVou':_0x36e88e(0xb8),'wBOrz':_0x1a92f9[_0x36e88e(0x482)],'WinpJ':function(_0x2abaf0,_0x3c77c9){return _0x2abaf0!==_0x3c77c9;},'JpVwO':_0x1a92f9[_0x36e88e(0x55c)],'AdWkF':_0x1a92f9['NkqKL'],'zeGSn':function(_0x59a614,_0xe1e14){return _0x59a614!==_0xe1e14;},'aFJsa':_0x1a92f9[_0x36e88e(0x622)],'isYpX':_0x1a92f9[_0x36e88e(0xea)],'HOODZ':_0x1a92f9[_0x36e88e(0x56c)],'WvaDT':function(_0x927ab9,_0x4c3341){return _0x1a92f9['vgjvN'](_0x927ab9,_0x4c3341);},'cFHCa':function(_0x698e20,_0x4f89e3){return _0x1a92f9['KlYGZ'](_0x698e20,_0x4f89e3);},'EftRU':'aleVa','uOXnz':_0x1a92f9['EnnvY'],'moFGR':_0x36e88e(0x4a2),'qRcFN':_0x1a92f9[_0x36e88e(0x6fb)],'ZiDoj':function(_0x2353c7,_0x276c5c){return _0x2353c7===_0x276c5c;},'VuCif':_0x1a92f9[_0x36e88e(0x238)],'hZXAF':_0x1a92f9[_0x36e88e(0x71a)],'WADlF':_0x1a92f9['iGoXC']};if(_0x1a92f9[_0x36e88e(0xdf)](_0x1a92f9[_0x36e88e(0x124)],_0x1a92f9[_0x36e88e(0x124)])){const _0x1bcd6e={};return _0x1bcd6e[_0x36e88e(0x492)]=![],_0x1bcd6e[_0x36e88e(0x618)]=_0x36e88e(0x164),_0x2811dc['status'](0x1f4)['json'](_0x1bcd6e);}else{const {name:_0x5cdd66,udid:_0x3e0bec,type:_0xa07786,ip:_0x4c5a83,platform:_0x2620c8}=_0x4a0a8d;console[_0x36e88e(0x37a)](_0x36e88e(0x671)+_0x5cdd66+'\x20('+_0xa07786+_0x36e88e(0x6ab)+_0x2620c8+')...');if(_0x1a92f9[_0x36e88e(0x5c1)](_0x2620c8,_0x1a92f9['RBwMW'])){if(_0x36e88e(0xf9)===_0x1a92f9[_0x36e88e(0x680)]){const _0x44ec7c=_0x4dbbbb['toString']();_0x5c0df9+=_0x44ec7c,_0x59223f['error']('['+_0x5cb096+_0x36e88e(0x354)+_0x44ec7c[_0x36e88e(0x3ea)]());}else{console[_0x36e88e(0x37a)]('š±\x20Android\x20device\x20detected:\x20'+_0x5cdd66);const _0x2aae66=_0x1a92f9[_0x36e88e(0x373)](spawn,_0x1a92f9[_0x36e88e(0x70a)],[_0x36e88e(0x3d4)]);let _0x32a224='';_0x2aae66[_0x36e88e(0x551)]['on'](_0x1a92f9[_0x36e88e(0x1e6)],_0x4d06e7=>{const _0x2adebd=_0x36e88e;_0x32a224+=_0x4d06e7[_0x2adebd(0x2ca)]();}),_0x2aae66['on'](_0x1a92f9[_0x36e88e(0x1ce)],async _0x3b9fe1=>{const _0x422c8c=_0x36e88e,_0x375d94={'kCZQX':function(_0x2b11cb,_0x2cdf54){return _0x2b11cb===_0x2cdf54;},'BPdVx':function(_0x120187,_0x391f86){const _0x118f0f=_0x46ca;return _0x4f2eba[_0x118f0f(0x277)](_0x120187,_0x391f86);},'hNOBu':_0x4f2eba[_0x422c8c(0x5ad)],'QGOsU':_0x4f2eba[_0x422c8c(0x296)],'vTXEw':function(_0x4e09d7,_0x3fcc24){return _0x4f2eba['Cnhmp'](_0x4e09d7,_0x3fcc24);},'Fxljj':_0x4f2eba['RnRzZ']};if(_0x4f2eba['VHUnC']===_0x4f2eba[_0x422c8c(0x4ee)]){const _0x1ef6b6=_0x32a224[_0x422c8c(0x185)](_0x3e0bec['replace'](_0x4f2eba[_0x422c8c(0x6cc)],''))||_0x32a224[_0x422c8c(0x185)](_0x3e0bec);if(_0x1ef6b6){console[_0x422c8c(0x37a)](_0x422c8c(0x437)+_0x5cdd66+_0x422c8c(0x531));const _0x1dcb26=connectedDevices[_0x422c8c(0x34d)](_0x27acea=>_0x27acea['name']===_0x5cdd66);_0x4f2eba['oCukm'](_0x1dcb26,-0x1)&&(connectedDevices[_0x1dcb26][_0x422c8c(0x160)]=_0x4f2eba['MFcTX']);wss[_0x422c8c(0x41b)][_0x422c8c(0x224)](_0x12cb74=>{const _0x271ba1=_0x422c8c;if(_0x375d94['kCZQX'](_0x12cb74['readyState'],WebSocket[_0x271ba1(0x467)])){if(_0x375d94[_0x271ba1(0x6e1)](_0x375d94['hNOBu'],_0x375d94['QGOsU'])){const _0x484299={};return _0x484299[_0x271ba1(0x492)]=![],_0x484299[_0x271ba1(0x618)]=_0x271ba1(0x44d),_0x527bb4(_0x484299);}else{const _0x319f93={};_0x319f93['type']=_0x271ba1(0x246),_0x319f93[_0x271ba1(0x3d4)]=connectedDevices,_0x12cb74[_0x271ba1(0x65f)](JSON[_0x271ba1(0x62d)](_0x319f93));}}}),console[_0x422c8c(0x37a)]('š¦\x20Ensuring\x20UIAutomator2\x20is\x20installed\x20on\x20'+_0x5cdd66+_0x422c8c(0x29d));const _0x463db0=_0x4f2eba['aqnhg'](spawn,_0x4f2eba[_0x422c8c(0x20c)],['-s',_0x3e0bec,_0x4f2eba[_0x422c8c(0x5e3)],'pm','list',_0x4f2eba[_0x422c8c(0x1a1)],_0x422c8c(0x598)]);let _0x44e35c='';_0x463db0['stdout']['on'](_0x4f2eba['BHBUZ'],_0x1f5dee=>{_0x44e35c+=_0x1f5dee['toString']();}),_0x463db0['on'](_0x4f2eba[_0x422c8c(0x211)],async()=>{const _0x239085=_0x422c8c,_0x501856={};_0x501856['eSLHF']=_0x4f2eba[_0x239085(0x4d1)],_0x501856[_0x239085(0x138)]=_0x4f2eba['VytZA'],_0x501856[_0x239085(0x113)]=_0x4f2eba[_0x239085(0x389)],_0x501856[_0x239085(0x258)]=_0x4f2eba[_0x239085(0x72b)];const _0x55a956=_0x501856,_0x4fe39c=_0x44e35c['includes'](_0x4f2eba[_0x239085(0x52f)]);if(!_0x4fe39c){console[_0x239085(0x37a)](_0x239085(0x6f8)+_0x5cdd66+_0x239085(0x159));const _0x592dd1=await _0x4f2eba['vgdgx'](installUIAutomator2,_0x3e0bec,_0x5cdd66);if(!_0x592dd1['success']){console[_0x239085(0x37a)](_0x239085(0x386)+_0x5cdd66);const _0x38a472={};_0x38a472[_0x239085(0x492)]=!![],_0x38a472['message']=_0x239085(0x57f)+_0x5cdd66+_0x239085(0x62f),_0x4f2eba[_0x239085(0x6ea)](_0xa0c362,_0x38a472);return;}}else console[_0x239085(0x37a)]('ā
\x20UIAutomator2\x20already\x20installed\x20on\x20'+_0x5cdd66);const _0x1b7f46=androidSessions[_0x239085(0x529)](_0x3e0bec);if(_0x1b7f46){console['log'](_0x239085(0x5f9)+_0x5cdd66+_0x239085(0x129)+_0x1b7f46['port']+')');try{const _0x47b80f=_0x4f2eba['OxjjC'](require,_0x239085(0x6c6));await _0x47b80f[_0x239085(0x529)]('http://localhost:'+_0x1b7f46['port']+_0x239085(0x147)),console['log']('ā
\x20Session\x20verified\x20and\x20working\x20on\x20'+_0x5cdd66);const _0x7661e=connectedDevices[_0x239085(0x34d)](_0x540969=>_0x540969[_0x239085(0x192)]===_0x5cdd66);_0x7661e!==-0x1&&(connectedDevices[_0x7661e][_0x239085(0x160)]=_0x4f2eba[_0x239085(0x3d5)],wss['clients']['forEach'](_0x49564a=>{const _0x519ab8=_0x239085;if(_0x49564a[_0x519ab8(0x625)]===WebSocket['OPEN']){const _0x1ec256={};_0x1ec256[_0x519ab8(0x2ba)]=_0x55a956[_0x519ab8(0x1d8)],_0x1ec256[_0x519ab8(0x3d4)]=connectedDevices,_0x49564a['send'](JSON[_0x519ab8(0x62d)](_0x1ec256));}}));const _0xaf1e4a={};_0xaf1e4a[_0x239085(0x492)]=!![],_0xaf1e4a['message']='Connected\x20to\x20'+_0x5cdd66+_0x239085(0x5fb),_0x4f2eba[_0x239085(0xc4)](_0xa0c362,_0xaf1e4a);return;}catch(_0x1b77c3){console[_0x239085(0x37a)](_0x239085(0x14c)+_0x5cdd66),androidSessions['delete'](_0x3e0bec);}}console['log'](_0x239085(0x1d7)+_0x5cdd66+_0x239085(0x29d));const _0x4ca78b=await _0x4f2eba[_0x239085(0x5ef)](startUIAutomator2Session,_0x3e0bec,_0x5cdd66);if(_0x4ca78b[_0x239085(0x492)]){const _0x221004=connectedDevices[_0x239085(0x34d)](_0x3583a9=>_0x3583a9[_0x239085(0x192)]===_0x5cdd66);_0x221004!==-0x1&&(_0x4f2eba[_0x239085(0x293)](_0x4f2eba[_0x239085(0x4ea)],_0x4f2eba[_0x239085(0x4d8)])?(_0x386c54[_0x239085(0x618)](_0x55a956[_0x239085(0x138)],_0x247f1a),_0x44cea2[_0x239085(0x3e8)](0x1)):(connectedDevices[_0x221004]['status']=_0x4f2eba['QbdAN'],wss[_0x239085(0x41b)]['forEach'](_0x3fbf1d=>{const _0x1c94e0=_0x239085,_0xbbd1f={};_0xbbd1f['BrefL']=_0x55a956[_0x1c94e0(0x113)];const _0x1138bb=_0xbbd1f;if(_0x3fbf1d[_0x1c94e0(0x625)]===WebSocket[_0x1c94e0(0x467)]){if(_0x55a956[_0x1c94e0(0x258)]!==_0x55a956['aDTIN']){_0x38ad2e['log'](_0x1c94e0(0xc9),_0x22a4a3[_0x1c94e0(0x55d)][_0x1c94e0(0x618)]);const _0x26ed51={};return _0x26ed51[_0x1c94e0(0x492)]=![],_0x26ed51['error']=_0x1138bb[_0x1c94e0(0x212)],_0x40687a[_0x1c94e0(0x160)](0x1f4)[_0x1c94e0(0x573)](_0x26ed51);}else{const _0x26d354={};_0x26d354[_0x1c94e0(0x2ba)]=_0x55a956[_0x1c94e0(0x1d8)],_0x26d354['devices']=connectedDevices,_0x3fbf1d['send'](JSON['stringify'](_0x26d354));}}})));const _0x5774ea={};_0x5774ea[_0x239085(0x492)]=!![],_0x5774ea['message']='Connected\x20to\x20'+_0x5cdd66+_0x239085(0x5fb),_0x4f2eba[_0x239085(0xc4)](_0xa0c362,_0x5774ea);}else{if(_0x4f2eba['SavuL'](_0x4f2eba['soFKp'],'TFMlC')){const _0x33dafd={};_0x33dafd[_0x239085(0x492)]=!![],_0x33dafd['message']='Connected\x20to\x20'+_0x5cdd66+_0x239085(0x62f),_0x4f2eba[_0x239085(0xc4)](_0xa0c362,_0x33dafd);}else{const _0x466ef4=_0x12123e[_0x239085(0x19b)](',')[_0x239085(0x12b)](_0x37ee66=>_0x37ee66['trim']()[_0x239085(0x203)](/"/g,''));return _0x375d94[_0x239085(0x45a)](_0x466ef4[_0x239085(0x484)],0x3)?{'id':_0x466ef4[0x0],'name':_0x466ef4[0x2]}:null;}}});}else{console[_0x422c8c(0x37a)](_0x422c8c(0x324)+_0x5cdd66+_0x422c8c(0x16b));if(_0x4f2eba[_0x422c8c(0x45b)](_0xa07786,_0x4f2eba[_0x422c8c(0x407)])&&_0x4c5a83){console[_0x422c8c(0x37a)]('š”\x20Attempting\x20to\x20connect\x20to\x20'+_0x5cdd66+_0x422c8c(0x187)+_0x4c5a83+_0x422c8c(0x3fb));const _0x186b87=spawn(_0x4f2eba[_0x422c8c(0x20c)],[_0x422c8c(0xe8),_0x4c5a83+_0x422c8c(0x734)]);_0x186b87['on'](_0x422c8c(0x3a0),async _0x17b830=>{const _0x4a37e=_0x422c8c,_0x5beb6b={'tjwSr':function(_0x589eae,_0x4e7033){return _0x4f2eba['EfEkD'](_0x589eae,_0x4e7033);},'WvlXW':function(_0x1a501f,_0x2ac09c){return _0x1a501f===_0x2ac09c;},'cEqGN':_0x4f2eba[_0x4a37e(0x519)],'Axaku':_0x4f2eba[_0x4a37e(0x5a6)],'YbkpJ':function(_0x224859,_0x83ae3f){const _0x269d9f=_0x4a37e;return _0x4f2eba[_0x269d9f(0x277)](_0x224859,_0x83ae3f);},'kAhga':_0x4f2eba[_0x4a37e(0x4d1)],'zIcgh':_0x4f2eba[_0x4a37e(0x3d5)],'Pymag':_0x4f2eba['OApzA'],'afFsD':_0x4f2eba[_0x4a37e(0x65a)],'UZmFl':_0x4f2eba['pdgmg'],'yokqo':_0x4f2eba[_0x4a37e(0x3f8)],'EjsvC':_0x4f2eba['bargc'],'NQLwt':function(_0x354941,_0x449a00,_0x7e06bd){return _0x354941(_0x449a00,_0x7e06bd);},'ShEDY':_0x4a37e(0xb4),'EhzJi':function(_0x573996,_0x28833b){return _0x573996===_0x28833b;},'PMrhP':_0x4f2eba[_0x4a37e(0x579)],'xIOuT':function(_0x306fde,_0x5af940){return _0x306fde===_0x5af940;},'kYoZM':_0x4f2eba[_0x4a37e(0x52f)],'isVQo':_0x4a37e(0x1d3),'sfbKm':function(_0x1e4ec2,_0x1d571e){return _0x4f2eba['SavuL'](_0x1e4ec2,_0x1d571e);},'sdnrv':'GMXqP','PxPBf':function(_0x256b76,_0x49dda4){const _0x5512b1=_0x4a37e;return _0x4f2eba[_0x5512b1(0x277)](_0x256b76,_0x49dda4);},'LfImj':_0x4f2eba[_0x4a37e(0xcd)],'TzXKo':_0x4f2eba[_0x4a37e(0x41f)],'mjLtj':_0x4a37e(0x6c6),'KzdOi':function(_0x1ae76f,_0x2445e0){return _0x4f2eba['oCukm'](_0x1ae76f,_0x2445e0);},'LkDBl':_0x4f2eba[_0x4a37e(0x5a0)],'flktc':function(_0x5218ce,_0xec8b93){return _0x5218ce(_0xec8b93);},'SfoJG':function(_0x38511b,_0x282939,_0x3736c9){const _0xf3326d=_0x4a37e;return _0x4f2eba[_0xf3326d(0x299)](_0x38511b,_0x282939,_0x3736c9);},'kSdtm':function(_0x51ef77,_0x28be9d){return _0x51ef77!==_0x28be9d;}};if(_0x4f2eba[_0x4a37e(0x1f2)](_0x4f2eba[_0x4a37e(0x22f)],_0x4f2eba[_0x4a37e(0x597)])){if(_0x4f2eba[_0x4a37e(0x46d)](_0x17b830,0x0)){console[_0x4a37e(0x37a)](_0x4a37e(0x346)+_0x5cdd66+'\x20wirelessly');const _0x4d2394=connectedDevices[_0x4a37e(0x34d)](_0x371fdd=>_0x371fdd[_0x4a37e(0x192)]===_0x5cdd66);_0x4d2394!==-0x1&&(_0x4a37e(0x740)!==_0x4f2eba[_0x4a37e(0x18d)]?_0x1e0ccb[_0x4a37e(0x37a)](_0x4a37e(0x313)+_0xa494bf+_0x4a37e(0x28f)):connectedDevices[_0x4d2394][_0x4a37e(0x160)]=_0x4f2eba[_0x4a37e(0x6e6)]);console[_0x4a37e(0x37a)](_0x4a37e(0x222)+_0x5cdd66+_0x4a37e(0x29d));const _0x56d2b0=_0x4f2eba[_0x4a37e(0x640)](spawn,_0x4f2eba[_0x4a37e(0x20c)],['-s',_0x4c5a83+_0x4a37e(0x734),_0x4f2eba['PsCsJ'],'pm',_0x4f2eba['EZBbe'],_0x4f2eba[_0x4a37e(0x1a1)],_0x4a37e(0x598)]);let _0x135a80='';_0x56d2b0[_0x4a37e(0x551)]['on']('data',_0x15b90e=>{const _0x623bd0=_0x4a37e,_0x1a6d0d={'pLsLI':function(_0x5beb03,_0x56aa16){const _0x2c620c=_0x46ca;return _0x5beb6b[_0x2c620c(0x13a)](_0x5beb03,_0x56aa16);}};if(_0x5beb6b[_0x623bd0(0x336)](_0x5beb6b[_0x623bd0(0x4df)],_0x5beb6b['Axaku'])){const _0x135ace={};_0x135ace[_0x623bd0(0x492)]=!![],_0x135ace['output']=_0x20d70c,_0x135ace[_0x623bd0(0x273)]=_0x1f4726[_0x623bd0(0x192)],jNeMet['pLsLI'](_0x1801be,_0x135ace);}else _0x135a80+=_0x15b90e[_0x623bd0(0x2ca)]();}),_0x56d2b0['on']('close',async()=>{const _0x2c90ee=_0x4a37e,_0x3cdb06=_0x135a80[_0x2c90ee(0x185)](_0x5beb6b[_0x2c90ee(0x2e1)]);if(!_0x3cdb06){console[_0x2c90ee(0x37a)](_0x2c90ee(0x6f8)+_0x5cdd66+_0x2c90ee(0x159));const _0x1ef0e5=await _0x5beb6b[_0x2c90ee(0x6c8)](installUIAutomator2,_0x4c5a83+_0x2c90ee(0x734),_0x5cdd66);if(!_0x1ef0e5[_0x2c90ee(0x492)]){if(_0x5beb6b[_0x2c90ee(0x60c)](_0x2c90ee(0x1d3),_0x5beb6b[_0x2c90ee(0x703)]))console[_0x2c90ee(0x37a)]('ā ļø\x20UIAutomator2\x20installation\x20failed\x20on\x20'+_0x5cdd66);else{const _0x28fb26={};_0x28fb26[_0x2c90ee(0x492)]=![],_0x28fb26[_0x2c90ee(0x618)]=_0x43ba8e||'Script\x20exited\x20with\x20code\x20'+_0x49045b,_0x28fb26[_0x2c90ee(0x273)]=_0x352f28,_0x20ffec(_0x28fb26);}}}else console['log']('ā
\x20UIAutomator2\x20already\x20installed\x20on\x20'+_0x5cdd66);const _0x38589a=androidSessions[_0x2c90ee(0x529)](_0x4c5a83+_0x2c90ee(0x734));if(_0x38589a){if(_0x5beb6b[_0x2c90ee(0x5a1)](_0x2c90ee(0x605),_0x5beb6b['sdnrv']))_0x216037[_0x2c90ee(0x37a)](_0x2c90ee(0x1ad)+_0x3c2291['sessionId']);else{console[_0x2c90ee(0x37a)](_0x2c90ee(0x5f9)+_0x5cdd66+'\x20(port:\x20'+_0x38589a[_0x2c90ee(0x3d1)]+')');try{if(_0x5beb6b['PxPBf'](_0x5beb6b[_0x2c90ee(0x20f)],_0x5beb6b[_0x2c90ee(0x764)]))_0x226527[_0x2c90ee(0x618)]('ā\x20Failed\x20to\x20start\x20iproxy:\x20'+_0x59e36e[_0x2c90ee(0xef)]),_0x1bbb35['error'](_0x2c90ee(0x1cd));else{const _0x25d8da=_0x5beb6b[_0x2c90ee(0x13a)](require,_0x5beb6b[_0x2c90ee(0x3fa)]);await _0x25d8da['get'](_0x2c90ee(0x1f5)+_0x38589a[_0x2c90ee(0x3d1)]+_0x2c90ee(0x147)),console[_0x2c90ee(0x37a)]('ā
\x20Session\x20verified\x20and\x20working\x20on\x20'+_0x5cdd66);if(_0x5beb6b[_0x2c90ee(0x6fd)](_0x4d2394,-0x1)){if(_0x5beb6b['LkDBl']!==_0x5beb6b[_0x2c90ee(0x62e)]){const _0x2b239e={'tfojT':function(_0x414274,_0x2cd42f){const _0x182de5=_0x2c90ee;return _0x5beb6b[_0x182de5(0x60c)](_0x414274,_0x2cd42f);},'jjDvE':_0x5beb6b['kAhga']};_0x1df9fa[_0x33d7bb]['status']=_0x5beb6b[_0x2c90ee(0x49f)],_0x572475['clients']['forEach'](_0x1390b8=>{const _0x3766b2=_0x2c90ee;if(_0x2b239e[_0x3766b2(0xd1)](_0x1390b8[_0x3766b2(0x625)],_0x2cf2a7['OPEN'])){const _0x3274d0={};_0x3274d0[_0x3766b2(0x2ba)]=_0x2b239e[_0x3766b2(0x449)],_0x3274d0[_0x3766b2(0x3d4)]=_0x49e125,_0x1390b8['send'](_0x2ce549[_0x3766b2(0x62d)](_0x3274d0));}});}else connectedDevices[_0x4d2394][_0x2c90ee(0x160)]=_0x5beb6b[_0x2c90ee(0x49f)],wss['clients'][_0x2c90ee(0x224)](_0x5d7a9a=>{const _0x4ef55b=_0x2c90ee,_0x12d153={};_0x12d153['UBCMr']=_0x5beb6b[_0x4ef55b(0x5b0)];const _0x3d17f9=_0x12d153;if(_0x5beb6b[_0x4ef55b(0x336)](_0x5beb6b[_0x4ef55b(0x1b2)],_0x5beb6b['UZmFl']))_0xf3f13f[_0x4ef55b(0x618)](_0x4ef55b(0x18e)+_0x214c20[_0x4ef55b(0xef)]);else{if(_0x5beb6b[_0x4ef55b(0x60c)](_0x5d7a9a[_0x4ef55b(0x625)],WebSocket[_0x4ef55b(0x467)])){if(_0x4ef55b(0x367)===_0x5beb6b['yokqo'])try{_0x49d91a[_0x4ef55b(0x1cc)](_0x4cfb27[_0x4ef55b(0x4b4)],_0x3d17f9[_0x4ef55b(0x738)]),_0x248e43['log'](_0x4ef55b(0x663)+_0x2da96d+_0x4ef55b(0x432)+_0x20dbd2[_0x4ef55b(0x4b4)]+')');}catch(_0x31ccc7){_0xc64eeb[_0x4ef55b(0x37a)](_0x4ef55b(0xce)+_0x25ce50[_0x4ef55b(0x4b4)]+_0x4ef55b(0x6ec));}else{const _0xe4e5e9={};_0xe4e5e9['type']=_0x5beb6b[_0x4ef55b(0x4f7)],_0xe4e5e9[_0x4ef55b(0x3d4)]=connectedDevices,_0x5d7a9a[_0x4ef55b(0x65f)](JSON[_0x4ef55b(0x62d)](_0xe4e5e9));}}}});}const _0x46359b={};_0x46359b[_0x2c90ee(0x492)]=!![],_0x46359b['message']=_0x2c90ee(0x57f)+_0x5cdd66+'\x20-\x20UIAutomator2\x20Ready\x20ā
',_0x5beb6b[_0x2c90ee(0x398)](_0xa0c362,_0x46359b);return;}}catch(_0x57be6d){console[_0x2c90ee(0x37a)]('ā ļø\x20\x20Existing\x20session\x20invalid,\x20creating\x20new\x20one\x20for\x20'+_0x5cdd66),androidSessions[_0x2c90ee(0x6ee)](_0x4c5a83+':5555');}}}console[_0x2c90ee(0x37a)]('š\x20Starting\x20new\x20UIAutomator2\x20session\x20on\x20'+_0x5cdd66+_0x2c90ee(0x29d));const _0x312c1e=await _0x5beb6b[_0x2c90ee(0xbc)](startUIAutomator2Session,_0x4c5a83+_0x2c90ee(0x734),_0x5cdd66);let _0x4eaeaa='';_0x312c1e['success']?(_0x5beb6b[_0x2c90ee(0xd7)](_0x4d2394,-0x1)&&(connectedDevices[_0x4d2394][_0x2c90ee(0x160)]=_0x5beb6b[_0x2c90ee(0x49f)],wss[_0x2c90ee(0x41b)][_0x2c90ee(0x224)](_0x216397=>{const _0x4b8e0c=_0x2c90ee,_0x384ab0={'xAAqG':_0x5beb6b['EjsvC'],'cJfmn':function(_0x356a47,_0x46996b,_0x18392a){const _0x3159bc=_0x46ca;return _0x5beb6b[_0x3159bc(0x6c8)](_0x356a47,_0x46996b,_0x18392a);},'CpibR':_0x5beb6b[_0x4b8e0c(0x31d)]};if(_0x5beb6b[_0x4b8e0c(0x36b)](_0x5beb6b[_0x4b8e0c(0x2dd)],_0x5beb6b[_0x4b8e0c(0x2dd)])){if(_0x5beb6b[_0x4b8e0c(0x72c)](_0x216397['readyState'],WebSocket[_0x4b8e0c(0x467)])){const _0x37cb86={};_0x37cb86['type']=_0x5beb6b[_0x4b8e0c(0x4f7)],_0x37cb86[_0x4b8e0c(0x3d4)]=connectedDevices,_0x216397[_0x4b8e0c(0x65f)](JSON[_0x4b8e0c(0x62d)](_0x37cb86));}}else{const {execSync:_0x31759f}=_0x50aee4(_0x384ab0[_0x4b8e0c(0x22b)]),_0x57cda9=_0x3e1df8['udid']||_0x59e0f0[_0x4b8e0c(0x5cb)],_0x53d555=_0x384ab0[_0x4b8e0c(0x486)](_0x31759f,'adb\x20-s\x20'+_0x57cda9+_0x4b8e0c(0x651),{'encoding':_0x384ab0[_0x4b8e0c(0xe7)]});_0x165f83=_0x53d555['split']('\x0a')[_0x4b8e0c(0x5a2)](_0x54b40a=>_0x54b40a[_0x4b8e0c(0x4ae)](_0x4b8e0c(0xc5)))['map'](_0x3c8e89=>_0x3c8e89[_0x4b8e0c(0x203)](_0x4b8e0c(0xc5),'')['trim']())[_0x4b8e0c(0x5a2)](_0x2aba59=>_0x2aba59)[_0x4b8e0c(0x488)]();}})),_0x4eaeaa=_0x2c90ee(0x57f)+_0x5cdd66+_0x2c90ee(0x5fb)):_0x4eaeaa='Connected\x20to\x20'+_0x5cdd66+_0x2c90ee(0x62f);const _0x377ee7={};_0x377ee7['success']=!![],_0x377ee7[_0x2c90ee(0xef)]=_0x4eaeaa,_0x5beb6b['flktc'](_0xa0c362,_0x377ee7);});}else{const _0x2a637e={};_0x2a637e['success']=![],_0x2a637e[_0x4a37e(0xef)]=_0x4a37e(0x576)+_0x5cdd66+_0x4a37e(0x483),_0x4f2eba[_0x4a37e(0x1a3)](_0x5a23e6,_0x2a637e);}}else{const _0x52320e=_0x19f42e[_0x4a37e(0x600)](/Label:([^\s]+)/);if(_0x52320e)_0x3285c1[_0x4a37e(0x6bf)]=_0x52320e[0x1];}});}else{const _0x1ba316={};_0x1ba316[_0x422c8c(0x492)]=![],_0x1ba316['message']=_0x422c8c(0x2d4)+_0x5cdd66+_0x422c8c(0x142),_0x4f2eba[_0x422c8c(0x28c)](_0x5a23e6,_0x1ba316);}}}else _0x51df24[_0x422c8c(0x733)]=_0x375d94['Fxljj'];}),_0x2aae66['on'](_0x36e88e(0x618),_0x1d860d=>{const _0x1bc1d2=_0x36e88e,_0x48bb42={'oyqdL':function(_0x75ab9f,_0x4ba3d6,_0x2e88d9){const _0x2496de=_0x46ca;return _0x1a92f9[_0x2496de(0x540)](_0x75ab9f,_0x4ba3d6,_0x2e88d9);}};if(_0x1a92f9[_0x1bc1d2(0x59a)](_0x1a92f9[_0x1bc1d2(0x1da)],_0x1a92f9['IDpka'])){_0xda535b[_0x1bc1d2(0x37a)]('š\x20Trying\x20to\x20install\x20via\x20Appium...');const _0x422a18={};_0x422a18[_0x1bc1d2(0x4c0)]='utf-8';const _0x7c578e=UzANls[_0x1bc1d2(0x17b)](_0x4863f5,_0x1bc1d2(0x2ec),_0x422a18);_0x2cb93a[_0x1bc1d2(0x37a)](_0x7c578e);const _0x3e6980={};_0x3e6980['success']=![],_0x3e6980[_0x1bc1d2(0xef)]=_0x1bc1d2(0x4ad),_0x3e2592(_0x3e6980);}else{console['error'](_0x1bc1d2(0x6a5)+_0x1d860d[_0x1bc1d2(0xef)]);const _0xebfb65={};_0xebfb65[_0x1bc1d2(0x492)]=![],_0xebfb65[_0x1bc1d2(0xef)]=_0x1bc1d2(0x630),_0x1a92f9['sJHmD'](_0x5a23e6,_0xebfb65);}});return;}}if(_0x1a92f9[_0x36e88e(0x567)](_0xa07786,'usb')){const _0x41ed82=_0x1a92f9['wQfLg'](spawn,_0x36e88e(0x737),['-s','--connect-timeout','2',_0x36e88e(0x3ca)]);let _0x255920='';_0x41ed82[_0x36e88e(0x551)]['on'](_0x1a92f9[_0x36e88e(0x1e6)],_0x36f88a=>{const _0x16b874=_0x36e88e,_0x2fb503={};_0x2fb503['XYSBX']=_0x4f2eba['OApzA'];const _0x59a2ce=_0x2fb503;if(_0x4f2eba[_0x16b874(0x2f1)]!==_0x4f2eba[_0x16b874(0x63a)])_0x255920+=_0x36f88a[_0x16b874(0x2ca)]();else try{_0x4a7696[_0x16b874(0x1cc)](_0x4207c4[_0x16b874(0x4dc)],_0x59a2ce[_0x16b874(0x17d)]),_0x565c25[_0x16b874(0x37a)](_0x16b874(0x64d)+_0x3319cb+_0x16b874(0x432)+_0x251de9[_0x16b874(0x4dc)]+')');}catch(_0x3d82e1){_0x2d68d8[_0x16b874(0x37a)](_0x16b874(0x34e)+_0x1c5a52[_0x16b874(0x4dc)]+_0x16b874(0x6ec));}}),_0x41ed82['on'](_0x36e88e(0x618),_0x4d6ba3=>{const _0x3a0d3f=_0x36e88e;console['error'](_0x3a0d3f(0x29e)+_0x4d6ba3[_0x3a0d3f(0xef)]);const _0x35c674={};_0x35c674[_0x3a0d3f(0x492)]=![],_0x35c674[_0x3a0d3f(0xef)]='Failed\x20to\x20check\x20WDA\x20status:\x20'+_0x4d6ba3[_0x3a0d3f(0xef)],_0x4f2eba['szjyK'](_0x5a23e6,_0x35c674);}),_0x41ed82['on'](_0x1a92f9[_0x36e88e(0x1ce)],async _0x445686=>{const _0x31f5b5=_0x36e88e,_0x2d9375={'decfe':_0x1a92f9[_0x31f5b5(0x52e)],'kUxMm':function(_0x528c06,_0x10675c){return _0x528c06===_0x10675c;},'enfXB':_0x1a92f9[_0x31f5b5(0x1d5)],'xAAih':function(_0x31c784,_0x5c66bd){return _0x31c784===_0x5c66bd;},'jXtcT':_0x1a92f9[_0x31f5b5(0x658)],'pyGvF':'VjuwA','XhnEe':_0x1a92f9[_0x31f5b5(0x15b)],'oZFBA':function(_0x26e57b,_0x4b9c74){const _0xaf974e=_0x31f5b5;return _0x1a92f9[_0xaf974e(0x33f)](_0x26e57b,_0x4b9c74);},'yZbhi':'TClpy','WtiLH':function(_0x14b114,_0x1d2a28,_0x26469d){const _0x138ab9=_0x31f5b5;return _0x1a92f9[_0x138ab9(0x540)](_0x14b114,_0x1d2a28,_0x26469d);},'IkFJU':_0x31f5b5(0x52b),'GqinS':function(_0x2485fe,_0x372cf8){return _0x2485fe!==_0x372cf8;},'aJrof':_0x1a92f9[_0x31f5b5(0x107)]};if(_0x31f5b5(0x2ad)!==_0x1a92f9['FwvPS']){const _0x37dda2={};_0x37dda2[_0x31f5b5(0x492)]=![],_0x37dda2[_0x31f5b5(0x618)]=_0x2dcc2c[_0x31f5b5(0xef)],_0x5994bb[_0x31f5b5(0x160)](0x1f4)[_0x31f5b5(0x573)](_0x37dda2);}else{if(_0x255920['includes'](_0x31f5b5(0x3aa))){console['log'](_0x31f5b5(0x564)+_0x5cdd66),console[_0x31f5b5(0x37a)]('š±\x20Creating\x20WDA\x20session\x20for\x20'+_0x5cdd66+'...');const _0x427b75=await _0x1a92f9[_0x31f5b5(0x540)](createWDASession,_0x1a92f9[_0x31f5b5(0x728)],_0x5cdd66);if(_0x427b75[_0x31f5b5(0x492)]){if(_0x1a92f9[_0x31f5b5(0x23a)](_0x31f5b5(0x762),_0x31f5b5(0x762))){_0x152d20['error'](_0x31f5b5(0x554),_0xa45dc9);const _0xb38e5f={};_0xb38e5f[_0x31f5b5(0x492)]=![],_0xb38e5f[_0x31f5b5(0x618)]=_0x2f1992[_0x31f5b5(0xef)],_0x305ce4[_0x31f5b5(0x160)](0x1f4)[_0x31f5b5(0x573)](_0xb38e5f);}else console[_0x31f5b5(0x37a)]('ā
\x20Session\x20created:\x20'+_0x427b75[_0x31f5b5(0x75c)]);}else console[_0x31f5b5(0x37a)](_0x31f5b5(0x111));const _0x27a75c=connectedDevices['findIndex'](_0x1f9cfa=>_0x1f9cfa[_0x31f5b5(0x192)]===_0x5cdd66);if(_0x1a92f9[_0x31f5b5(0x23a)](_0x27a75c,-0x1)){if(_0x1a92f9[_0x31f5b5(0x1e0)](_0x1a92f9[_0x31f5b5(0x698)],_0x31f5b5(0x725))){_0x5902cb['log'](_0x31f5b5(0x12c));const _0x1393fc={};_0x1393fc[_0x31f5b5(0x2ba)]=_0x2d9375[_0x31f5b5(0x229)],_0x1393fc[_0x31f5b5(0x31c)]=_0x281ecf,_0x2123c3[_0x31f5b5(0x65f)](_0x5eec85['stringify'](_0x1393fc));}else connectedDevices[_0x27a75c][_0x31f5b5(0x160)]=_0x1a92f9[_0x31f5b5(0x107)];}wss['clients'][_0x31f5b5(0x224)](_0x2e8fe0=>{const _0x3246c9=_0x31f5b5,_0x271828={'dkxtC':function(_0x2b8959,_0x15b6fc){const _0x474f51=_0x46ca;return _0x4f2eba[_0x474f51(0x277)](_0x2b8959,_0x15b6fc);},'LqlmY':_0x4f2eba[_0x3246c9(0x4d1)]};if(_0x4f2eba[_0x3246c9(0x46d)](_0x2e8fe0[_0x3246c9(0x625)],WebSocket['OPEN'])){if(_0x4f2eba[_0x3246c9(0x580)](_0x4f2eba[_0x3246c9(0x46c)],_0x4f2eba['CLUph'])){const _0x43d07f={};_0x43d07f[_0x3246c9(0x2ba)]=_0x4f2eba[_0x3246c9(0x4d1)],_0x43d07f[_0x3246c9(0x3d4)]=connectedDevices,_0x2e8fe0[_0x3246c9(0x65f)](JSON[_0x3246c9(0x62d)](_0x43d07f));}else{if(LzZnND[_0x3246c9(0x3e4)](_0x41fcbe['readyState'],_0x40d044[_0x3246c9(0x467)])){const _0x5914df={};_0x5914df['type']=LzZnND[_0x3246c9(0xaf)],_0x5914df[_0x3246c9(0x3d4)]=_0x15dcd8,_0x3c0094[_0x3246c9(0x65f)](_0x2f86e2['stringify'](_0x5914df));}}}});const _0x32b1a5={};_0x32b1a5[_0x31f5b5(0x492)]=!![],_0x32b1a5[_0x31f5b5(0xef)]=_0x31f5b5(0x57f)+_0x5cdd66+_0x31f5b5(0x3af),_0x1a92f9[_0x31f5b5(0x3e7)](_0xa0c362,_0x32b1a5);}else{if(_0x1a92f9['QwdJS']('hafXE',_0x31f5b5(0x20e))){const _0x235361={};return _0x235361[_0x31f5b5(0x492)]=![],_0x235361[_0x31f5b5(0x618)]=_0x31f5b5(0x6ed),_0x31024c[_0x31f5b5(0x160)](0x194)[_0x31f5b5(0x573)](_0x235361);}else{console[_0x31f5b5(0x37a)](_0x31f5b5(0x32e)+_0x5cdd66+_0x31f5b5(0x74b)+_0x3e0bec+_0x31f5b5(0x448));const _0x9b4ddc=process.env.WDA_PATH||path['join'](process.env.HOME,_0x1a92f9[_0x31f5b5(0x105)]);console[_0x31f5b5(0x37a)]('š\x20WDA\x20Path:\x20'+_0x9b4ddc),console['log'](_0x31f5b5(0x539)+_0x3e0bec);const _0x1b4153=_0x1a92f9[_0x31f5b5(0x33e)](spawn,'xcodebuild',[_0x1a92f9[_0x31f5b5(0x180)],_0x1a92f9[_0x31f5b5(0x4ca)],path['join'](_0x9b4ddc,_0x1a92f9['jTwjh']),'-scheme',_0x1a92f9[_0x31f5b5(0x2df)],_0x1a92f9['AuiMD'],_0x31f5b5(0x1fb)+_0x3e0bec,'IPHONEOS_DEPLOYMENT_TARGET=14.0'],{'cwd':_0x9b4ddc,'detached':!![],'stdio':[_0x31f5b5(0x342),_0x1a92f9[_0x31f5b5(0x201)],_0x1a92f9['fTpkH']]});_0x1b4153[_0x31f5b5(0x551)]['on'](_0x1a92f9[_0x31f5b5(0x1e6)],_0x299032=>{const _0x571bac=_0x31f5b5,_0x144f62={'BDGkn':function(_0x256599,_0x525e9b){const _0x1ce82c=_0x46ca;return _0x4f2eba[_0x1ce82c(0x639)](_0x256599,_0x525e9b);},'hJqoG':_0x4f2eba['cKyJJ'],'dKvLs':function(_0x19eced,_0x1c7145){return _0x4f2eba['jvPpJ'](_0x19eced,_0x1c7145);},'pKrvc':function(_0x5dac87,_0x385284){const _0x105f1d=_0x46ca;return _0x4f2eba[_0x105f1d(0x6ea)](_0x5dac87,_0x385284);}};if(_0x4f2eba[_0x571bac(0x45b)](_0x4f2eba[_0x571bac(0x6d9)],_0x4f2eba[_0x571bac(0x6d9)])){const _0x305d29=_0x299032['toString']();if(_0x305d29[_0x571bac(0x185)](_0x4f2eba[_0x571bac(0x109)])||_0x305d29[_0x571bac(0x185)](_0x4f2eba[_0x571bac(0x759)])){if(_0x4f2eba['WinpJ'](_0x4f2eba[_0x571bac(0x391)],_0x4f2eba[_0x571bac(0x391)])){const _0x2ad3d0={'XNNZR':function(_0xe961d6,_0x255e76){const _0x44cc5e=_0x571bac;return _0x144f62[_0x44cc5e(0x596)](_0xe961d6,_0x255e76);},'fQfxB':_0x144f62[_0x571bac(0x4f3)]};_0x21fab0['log'](_0x571bac(0x4a4)+_0x6083e1+_0x571bac(0x1cb));const _0x13136e=_0x4bcf0f[_0x571bac(0x34d)](_0x5a4930=>_0x5a4930[_0x571bac(0x192)]===_0x41fdfa);_0x144f62['dKvLs'](_0x13136e,-0x1)&&(_0x2b82ac[_0x13136e][_0x571bac(0x160)]='offline');_0x297c34[_0x571bac(0x41b)][_0x571bac(0x224)](_0x444413=>{const _0x185eba=_0x571bac;if(_0x2ad3d0[_0x185eba(0x146)](_0x444413[_0x185eba(0x625)],_0x21fd5e['OPEN'])){const _0x369ef2={};_0x369ef2[_0x185eba(0x2ba)]=_0x2ad3d0[_0x185eba(0x3a9)],_0x369ef2[_0x185eba(0x3d4)]=_0x1ea003,_0x444413[_0x185eba(0x65f)](_0x43d497[_0x185eba(0x62d)](_0x369ef2));}});const _0x264795={};_0x264795[_0x571bac(0x492)]=!![],_0x264795[_0x571bac(0xef)]='Disconnected\x20from\x20'+_0x1c63d8+'\x20-\x20ADB\x20disconnected',_0x2f54d5(_0x264795);}else console[_0x571bac(0x37a)](_0x571bac(0x59c)+_0x305d29[_0x571bac(0x3ea)]());}}else FSsIRU['pKrvc'](_0x43bda2,_0x571bac(0x358)+_0x3ceede+_0x571bac(0x420)+_0x639593[_0x571bac(0x3d1)]),_0x5bea04[_0x571bac(0x37a)]('ā
\x20Port\x20forwarding\x20removed\x20for\x20'+_0x2045e8);}),_0x1b4153[_0x31f5b5(0x40e)]['on'](_0x1a92f9[_0x31f5b5(0x1e6)],_0x20ec1c=>{const _0x2cd2f4=_0x31f5b5;if(_0x2d9375['kUxMm']('fYbzY',_0x2cd2f4(0x675)))_0x373aa8[_0x2cd2f4(0x37a)](_0x2cd2f4(0x53f)+_0x2b57f4);else{const _0x3c5576=_0x20ec1c['toString']();!_0x3c5576[_0x2cd2f4(0x185)](_0x2d9375[_0x2cd2f4(0x1d2)])&&!_0x3c5576['includes'](_0x2cd2f4(0x611))&&console[_0x2cd2f4(0x618)](_0x2cd2f4(0x6a7)+_0x3c5576['trim']());}}),_0x1b4153['on'](_0x1a92f9[_0x31f5b5(0x6e5)],_0x341012=>{const _0x2f1ce8=_0x31f5b5;console[_0x2f1ce8(0x618)](_0x2f1ce8(0x18e)+_0x341012[_0x2f1ce8(0xef)]);}),_0x1b4153[_0x31f5b5(0x47a)](),console[_0x31f5b5(0x37a)](_0x31f5b5(0x325));const _0x2c9c78=_0x1a92f9['dmTks'](spawn,_0x1a92f9[_0x31f5b5(0x409)],[_0x31f5b5(0x20d),_0x1a92f9[_0x31f5b5(0x42e)]],{'detached':!![],'stdio':[_0x1a92f9['jTQwe'],_0x1a92f9[_0x31f5b5(0x201)],_0x1a92f9[_0x31f5b5(0x201)]]});_0x2c9c78['stdout']['on'](_0x31f5b5(0x49b),_0x12916d=>{const _0x42b831=_0x31f5b5,_0x16bea7={'nkvZQ':function(_0x2030cf,_0x48675b){const _0x1db020=_0x46ca;return _0x4f2eba[_0x1db020(0x28c)](_0x2030cf,_0x48675b);},'Asrbf':function(_0x4272ab,_0x48f14f){const _0x19f2ab=_0x46ca;return _0x4f2eba[_0x19f2ab(0x28c)](_0x4272ab,_0x48f14f);},'IlNpI':_0x4f2eba[_0x42b831(0x515)]};if(_0x4f2eba['zeGSn'](_0x4f2eba[_0x42b831(0x12a)],_0x42b831(0x478))){let _0x5ba13c=_0x48fe81[_0x42b831(0x4a3)](_0x46bb59,_0x42b831(0x353),_0x2b18b3);if(JpSIhW['nkvZQ'](_0x9cc59c,'fs')[_0x42b831(0x4d6)](_0x5ba13c))return _0x5ba13c;_0x5ba13c=_0x2d06fb[_0x42b831(0x4a3)](_0x4ca43e,_0x42b831(0x381),_0x3e4500);if(JpSIhW[_0x42b831(0x1ae)](_0x44bc82,'fs')[_0x42b831(0x4d6)](_0x5ba13c))return _0x5ba13c;return _0x2d9606[_0x42b831(0x4a3)](_0x33d6da,JpSIhW[_0x42b831(0x183)],_0x479ed6);}else console[_0x42b831(0x37a)]('š\x20iproxy:\x20'+_0x12916d[_0x42b831(0x2ca)]()[_0x42b831(0x3ea)]());}),_0x2c9c78['on'](_0x1a92f9['FQWmR'],_0x696496=>{const _0xa95f03=_0x31f5b5;console[_0xa95f03(0x618)](_0xa95f03(0x249)+_0x696496[_0xa95f03(0xef)]),console['error']('\x20\x20\x20Make\x20sure\x20libimobiledevice\x20is\x20installed:\x20brew\x20install\x20libimobiledevice');}),_0x2c9c78[_0x31f5b5(0x47a)]();const _0x4f9390={};_0x4f9390[_0x31f5b5(0x4dc)]=_0x1b4153[_0x31f5b5(0x3b9)],_0x4f9390[_0x31f5b5(0x4b4)]=_0x2c9c78['pid'],wdaProcesses[_0x31f5b5(0x3df)](_0x5cdd66,_0x4f9390),console[_0x31f5b5(0x37a)](_0x31f5b5(0x3ae)+_0x5cdd66+_0x31f5b5(0x27e)+_0x1b4153['pid']),_0x1a92f9[_0x31f5b5(0x4cb)](setTimeout,()=>{const _0x268551=_0x31f5b5,_0x94a33f=_0x4f2eba[_0x268551(0xe9)](spawn,_0x268551(0x737),['-s',_0x4f2eba[_0x268551(0x637)],'5',_0x4f2eba[_0x268551(0x13f)]]);let _0x53c39b='';_0x94a33f[_0x268551(0x551)]['on'](_0x4f2eba[_0x268551(0xec)],_0x4521cc=>{const _0x31f913=_0x268551;_0x53c39b+=_0x4521cc[_0x31f913(0x2ca)]();}),_0x94a33f['on']('close',async()=>{const _0x35c65f=_0x268551,_0x470ce7={'uhbxw':function(_0x49f14d,_0x5ad85e){const _0x7dd1b1=_0x46ca;return _0x2d9375[_0x7dd1b1(0x384)](_0x49f14d,_0x5ad85e);},'FmrOg':_0x2d9375['jXtcT']};if(_0x2d9375[_0x35c65f(0x4a6)](_0x2d9375[_0x35c65f(0x1e1)],_0x2d9375['pyGvF'])){if(_0x53c39b[_0x35c65f(0x185)](_0x2d9375[_0x35c65f(0x304)])){if(_0x2d9375[_0x35c65f(0x404)](_0x35c65f(0x24a),_0x2d9375[_0x35c65f(0x5a9)]))_0x3481ba=_0x35c65f(0x2f4)+_0x2d9053+','+_0xaa0ccf,_0x3ab4b6['log']('\x0aš±ļø\x20API:\x20Tapping\x20at\x20coordinates\x20('+_0x1480ee+','+_0x1aeb25+_0x35c65f(0x5ec)+_0x55aa3c);else{console[_0x35c65f(0x37a)](_0x35c65f(0x476)+_0x5cdd66),console[_0x35c65f(0x37a)]('š±\x20Creating\x20WDA\x20session\x20for\x20'+_0x5cdd66+'...');const _0x3f85b3=await _0x2d9375[_0x35c65f(0x125)](createWDASession,_0x2d9375[_0x35c65f(0x5d1)],_0x5cdd66);_0x3f85b3['success']?console[_0x35c65f(0x37a)](_0x35c65f(0x1ad)+_0x3f85b3[_0x35c65f(0x75c)]):console[_0x35c65f(0x37a)](_0x35c65f(0x111));const _0x4c8328=connectedDevices[_0x35c65f(0x34d)](_0x1e4019=>_0x1e4019[_0x35c65f(0x192)]===_0x5cdd66);_0x2d9375[_0x35c65f(0x64f)](_0x4c8328,-0x1)&&(connectedDevices[_0x4c8328][_0x35c65f(0x160)]=_0x2d9375[_0x35c65f(0x11a)]),wss['clients']['forEach'](_0x49fbc0=>{const _0x4a4690=_0x35c65f;if(_0x470ce7[_0x4a4690(0x2e4)](_0x49fbc0[_0x4a4690(0x625)],WebSocket[_0x4a4690(0x467)])){const _0x48402a={};_0x48402a['type']=_0x4a4690(0x246),_0x48402a[_0x4a4690(0x3d4)]=connectedDevices,_0x49fbc0[_0x4a4690(0x65f)](JSON[_0x4a4690(0x62d)](_0x48402a)),_0x49fbc0['send'](JSON['stringify']({'type':_0x470ce7[_0x4a4690(0x558)],'output':'ā
\x20'+_0x5cdd66+'\x20connected\x20-\x20WDA\x20Ready!\x0a'+'ā'[_0x4a4690(0x20b)](0x32)+'\x0a','device':_0x5cdd66}));}});}}else console[_0x35c65f(0x37a)](_0x35c65f(0x1c5)+_0x5cdd66+_0x35c65f(0x29d));}else{const _0x440a14=_0xf7c88a['toString']();_0x198ba4+=_0x440a14,_0x567236[_0x35c65f(0x37a)]('['+_0x105930+']\x20STDOUT:\x20'+_0x440a14[_0x35c65f(0x3ea)]());if(_0x254334){const _0x3dd438={};_0x3dd438[_0x35c65f(0x2ba)]=Bbjxlc[_0x35c65f(0x558)],_0x3dd438[_0x35c65f(0x49b)]='['+_0x499b43+']\x20'+_0x440a14,_0x3dd438[_0x35c65f(0x3d4)]=[_0x146d17],_0xee9896[_0x35c65f(0x65f)](_0x604447[_0x35c65f(0x62d)](_0x3dd438));}}});},0x1f40);const _0x22a7fb={};_0x22a7fb['success']=!![],_0x22a7fb[_0x31f5b5(0xef)]=_0x31f5b5(0x671)+_0x5cdd66+_0x31f5b5(0x35b),_0x22a7fb[_0x31f5b5(0x1bb)]=!![],_0x1a92f9[_0x31f5b5(0x137)](_0xa0c362,_0x22a7fb);}}}}),_0x41ed82['on'](_0x1a92f9[_0x36e88e(0x6e5)],()=>{const _0x420a38=_0x36e88e;console[_0x420a38(0x37a)](_0x420a38(0x21e));const _0x4ca01c={};_0x4ca01c['success']=![],_0x4ca01c['message']=_0x420a38(0x494),_0x1a92f9[_0x420a38(0x261)](_0xa0c362,_0x4ca01c);});}else{const _0x3154e9=_0x1a92f9['rndat'](spawn,_0x1a92f9['iGoXC'],['-s',_0x1a92f9['dIMnU'],'3',_0x36e88e(0x438)+_0x4c5a83+_0x36e88e(0x19d)]);let _0x29b270='';_0x3154e9[_0x36e88e(0x551)]['on'](_0x1a92f9[_0x36e88e(0x1e6)],_0x2fc408=>{_0x29b270+=_0x2fc408['toString']();}),_0x3154e9['on'](_0x1a92f9[_0x36e88e(0x1ce)],async()=>{const _0x4dcfb5=_0x36e88e,_0x59672a={'Gvmmg':function(_0x315805){return _0x1a92f9['eeAgb'](_0x315805);},'nTTbY':function(_0x22f98c,_0x9f0fbd){return _0x22f98c!==_0x9f0fbd;},'jFcZQ':_0x1a92f9[_0x4dcfb5(0x669)],'yHBin':_0x1a92f9[_0x4dcfb5(0x2c7)],'eKCjo':function(_0xb12c0b,_0x2c2663,_0x33cec0){return _0xb12c0b(_0x2c2663,_0x33cec0);},'HDOuu':_0x4dcfb5(0x2bc),'nIDII':_0x1a92f9['fYRcE'],'RBmtY':_0x1a92f9['stcAx'],'npUuo':_0x1a92f9[_0x4dcfb5(0x107)],'DoyMz':function(_0x37f9f1,_0x53a027){const _0x2efc61=_0x4dcfb5;return _0x1a92f9[_0x2efc61(0x1c3)](_0x37f9f1,_0x53a027);},'YlMJV':function(_0x433e46,_0x40922c){return _0x1a92f9['XixHo'](_0x433e46,_0x40922c);},'lPQpi':function(_0x47d40e,_0x16d6bb){return _0x47d40e(_0x16d6bb);}};if(_0x29b270['includes'](_0x1a92f9[_0x4dcfb5(0x15b)])){if(_0x1a92f9['kDoSB'](_0x1a92f9[_0x4dcfb5(0x2b0)],_0x1a92f9[_0x4dcfb5(0x2b0)])){console[_0x4dcfb5(0x37a)]('ā
\x20WDA\x20reachable\x20for\x20'+_0x5cdd66),console['log'](_0x4dcfb5(0x421)+_0x5cdd66+'...');const _0x3ebf2f=await _0x1a92f9[_0x4dcfb5(0x4cb)](createWDASession,_0x4c5a83,_0x5cdd66);_0x3ebf2f[_0x4dcfb5(0x492)]?_0x1a92f9[_0x4dcfb5(0x5c1)](_0x1a92f9[_0x4dcfb5(0xac)],_0x1a92f9['xaFzk'])?_0xd6d17a=_0x1802b4[_0x4dcfb5(0x1ec)][_0x4dcfb5(0x19b)]('\x0a')[_0x4dcfb5(0x5a2)](_0x4286ae=>_0x4286ae['trim']())[_0x4dcfb5(0x484)]:console[_0x4dcfb5(0x37a)](_0x4dcfb5(0x1ad)+_0x3ebf2f['sessionId']):console[_0x4dcfb5(0x37a)](_0x4dcfb5(0x111));const _0x225b9a=connectedDevices['findIndex'](_0x1119b8=>_0x1119b8[_0x4dcfb5(0x192)]===_0x5cdd66);if(_0x225b9a!==-0x1){if(_0x1a92f9[_0x4dcfb5(0x4aa)](_0x1a92f9[_0x4dcfb5(0x114)],_0x1a92f9['lxbum']))connectedDevices[_0x225b9a][_0x4dcfb5(0x160)]=_0x1a92f9[_0x4dcfb5(0x107)];else{_0x1efdd7[_0x4dcfb5(0x618)]('ā\x20API\x20error:',_0x244c50);const _0x283ee7={};_0x283ee7[_0x4dcfb5(0x492)]=![],_0x283ee7[_0x4dcfb5(0x618)]=_0x3ef00e[_0x4dcfb5(0xef)],_0x41e8a8['status'](0x1f4)['json'](_0x283ee7);}}wss[_0x4dcfb5(0x41b)]['forEach'](_0x50f7a9=>{const _0x29bb2e=_0x4dcfb5,_0x10b7fa={'flQzO':function(_0x26fff4,_0x3d5508){return _0x4f2eba['WvaDT'](_0x26fff4,_0x3d5508);},'FNJnA':_0x29bb2e(0x246),'LccVG':_0x29bb2e(0x3a6)};if(_0x4f2eba[_0x29bb2e(0x6a2)](_0x29bb2e(0x141),_0x4f2eba[_0x29bb2e(0x166)])){if(_0x50f7a9[_0x29bb2e(0x625)]===WebSocket['OPEN']){const _0x161229={};_0x161229['type']=_0x4f2eba[_0x29bb2e(0x4d1)],_0x161229['devices']=connectedDevices,_0x50f7a9[_0x29bb2e(0x65f)](JSON[_0x29bb2e(0x62d)](_0x161229));}}else{const _0x1caa6e={'gyAeF':function(_0x21b103,_0x392821){return LcmsKd['flQzO'](_0x21b103,_0x392821);},'Wmopw':LcmsKd[_0x29bb2e(0x76e)]};_0x692c73!==-0x1&&(_0x46a765[_0x153041][_0x29bb2e(0x160)]=LcmsKd[_0x29bb2e(0x60d)],_0x1a610f[_0x29bb2e(0x41b)]['forEach'](_0xe82256=>{const _0x25fe4f=_0x29bb2e;if(_0x1caa6e['gyAeF'](_0xe82256['readyState'],_0x5ec7c2[_0x25fe4f(0x467)])){const _0x3768be={};_0x3768be[_0x25fe4f(0x2ba)]=_0x1caa6e['Wmopw'],_0x3768be[_0x25fe4f(0x3d4)]=_0x28f921,_0xe82256[_0x25fe4f(0x65f)](_0x40e599[_0x25fe4f(0x62d)](_0x3768be));}})),_0x24da00=_0x29bb2e(0x57f)+_0xc501bd+'\x20-\x20UIAutomator2\x20Ready\x20ā
';}});const _0x5143ba={};_0x5143ba[_0x4dcfb5(0x492)]=!![],_0x5143ba[_0x4dcfb5(0xef)]=_0x4dcfb5(0x57f)+_0x5cdd66+_0x4dcfb5(0x3af),_0x1a92f9[_0x4dcfb5(0x1a5)](_0xa0c362,_0x5143ba);}else{const _0x125312={};_0x125312['type']=_0x4dcfb5(0x246),_0x125312['devices']=_0x1ac456,_0xf1129a[_0x4dcfb5(0x65f)](_0x4f2e43[_0x4dcfb5(0x62d)](_0x125312));}}else{console[_0x4dcfb5(0x37a)](_0x4dcfb5(0x415)+_0x5cdd66+',\x20attempting\x20to\x20start...');const _0x5dc29a=process.env.WDA_PATH||path[_0x4dcfb5(0x4a3)](process.env.HOME,_0x4dcfb5(0x237));console[_0x4dcfb5(0x37a)](_0x4dcfb5(0x302)+_0x5dc29a),console['log']('š±\x20Device\x20UDID:\x20'+_0x3e0bec),console[_0x4dcfb5(0x37a)](_0x4dcfb5(0x2dc)+_0x4c5a83);const _0x31793d=_0x1a92f9[_0x4dcfb5(0x1bc)](spawn,_0x1a92f9[_0x4dcfb5(0x546)],[_0x1a92f9['OpuKh'],_0x1a92f9['UkAfe'],path['join'](_0x5dc29a,'WebDriverAgent.xcodeproj'),_0x4dcfb5(0x586),_0x1a92f9[_0x4dcfb5(0x2df)],_0x1a92f9[_0x4dcfb5(0x51e)],'id='+_0x3e0bec,_0x4dcfb5(0x28b)],{'cwd':_0x5dc29a,'detached':!![],'stdio':[_0x1a92f9[_0x4dcfb5(0x408)],_0x4dcfb5(0x493),_0x1a92f9[_0x4dcfb5(0x201)]]});_0x31793d[_0x4dcfb5(0x551)]['on'](_0x1a92f9['flBAl'],_0x16b0d1=>{const _0x205c99=_0x4dcfb5,_0x4ded32=_0x16b0d1['toString']();(_0x4ded32[_0x205c99(0x185)](_0x4f2eba['VlVou'])||_0x4ded32[_0x205c99(0x185)](_0x4f2eba[_0x205c99(0x759)]))&&console[_0x205c99(0x37a)]('š±\x20WDA\x20('+_0x5cdd66+_0x205c99(0x2b9)+_0x4ded32[_0x205c99(0x3ea)]());}),_0x31793d[_0x4dcfb5(0x40e)]['on'](_0x1a92f9[_0x4dcfb5(0x1e6)],_0x3ceb22=>{const _0x4f798d=_0x4dcfb5,_0x41ebf1=_0x3ceb22['toString']();if(!_0x41ebf1[_0x4f798d(0x185)](_0x4f798d(0x712))&&!_0x41ebf1['includes'](_0x4f2eba[_0x4f798d(0x3bc)])){if(_0x4f2eba['MkvbV'](_0x4f2eba['moFGR'],_0x4f2eba[_0x4f798d(0x22a)]))console[_0x4f798d(0x618)](_0x4f798d(0x17e)+_0x5cdd66+'):\x20'+_0x41ebf1[_0x4f798d(0x3ea)]());else{const _0x461433={};_0x461433['success']=!![],_0x461433[_0x4f798d(0xef)]=_0x4f798d(0x1ea),_0x49da75[_0x4f798d(0x573)](_0x461433);}}}),_0x31793d['on'](_0x4dcfb5(0x618),_0x491822=>{const _0x320944=_0x4dcfb5;_0x59672a[_0x320944(0x57a)](_0x59672a[_0x320944(0x230)],_0x59672a['yHBin'])?console[_0x320944(0x618)]('ā\x20Failed\x20to\x20start\x20xcodebuild\x20for\x20'+_0x5cdd66+':\x20'+_0x491822[_0x320944(0xef)]):_0x59672a['Gvmmg'](_0x11dd89);}),_0x31793d[_0x4dcfb5(0x47a)]();const _0x3c7ccb={};_0x3c7ccb[_0x4dcfb5(0x4dc)]=_0x31793d['pid'],wdaProcesses[_0x4dcfb5(0x3df)](_0x5cdd66,_0x3c7ccb),console[_0x4dcfb5(0x37a)](_0x4dcfb5(0x3ae)+_0x5cdd66+_0x4dcfb5(0x21d)+_0x31793d[_0x4dcfb5(0x3b9)]),_0x1a92f9[_0x4dcfb5(0x4cb)](setTimeout,()=>{const _0x3f6ca1=_0x4dcfb5,_0x581514={'WWMss':function(_0x12ca62,_0x3a6a7b){const _0x24b438=_0x46ca;return _0x4f2eba[_0x24b438(0x216)](_0x12ca62,_0x3a6a7b);},'VPBOg':_0x4f2eba['VuCif'],'MTBhJ':_0x4f2eba['hZXAF']},_0x4618e3=_0x4f2eba[_0x3f6ca1(0x5ef)](spawn,_0x4f2eba['WADlF'],['-s',_0x3f6ca1(0x572),'5',_0x3f6ca1(0x438)+_0x4c5a83+_0x3f6ca1(0x19d)]);let _0x3eb4e8='';_0x4618e3['stdout']['on'](_0x4f2eba[_0x3f6ca1(0xec)],_0x3a754b=>{const _0x2a4e4f=_0x3f6ca1;if(_0x581514['WWMss'](_0x581514[_0x2a4e4f(0x560)],_0x581514[_0x2a4e4f(0x74a)])){_0x2c3723[_0x2a4e4f(0x618)]('ā\x20Failed\x20to\x20save\x20session\x20for\x20'+_0x2cfba6+':',_0x390faf);const _0x54562a={};_0x54562a[_0x2a4e4f(0x492)]=![],_0x23e82a(_0x54562a);}else _0x3eb4e8+=_0x3a754b[_0x2a4e4f(0x2ca)]();}),_0x4618e3['on'](_0x4f2eba[_0x3f6ca1(0x211)],async()=>{const _0x23f893=_0x3f6ca1;if(_0x3eb4e8[_0x23f893(0x185)]('\x22state\x22')){console[_0x23f893(0x37a)](_0x23f893(0x476)+_0x5cdd66),console[_0x23f893(0x37a)](_0x23f893(0x421)+_0x5cdd66+'...');const _0x38ad52=await _0x59672a['eKCjo'](createWDASession,_0x4c5a83,_0x5cdd66);_0x38ad52[_0x23f893(0x492)]?_0x59672a[_0x23f893(0x69d)]===_0x59672a[_0x23f893(0x331)]?_0x5a39d7+=_0x529684[_0x23f893(0x2ca)]():console[_0x23f893(0x37a)](_0x23f893(0x1ad)+_0x38ad52['sessionId']):console[_0x23f893(0x37a)]('ā ļø\x20\x20Session\x20creation\x20failed,\x20will\x20be\x20created\x20on\x20first\x20command');const _0xa1e5f2=connectedDevices[_0x23f893(0x34d)](_0x28c1de=>_0x28c1de[_0x23f893(0x192)]===_0x5cdd66);if(_0xa1e5f2!==-0x1){if(_0x59672a[_0x23f893(0x4e7)]!==_0x59672a[_0x23f893(0x4e7)]){const _0x368418={};return _0x368418[_0x23f893(0x492)]=![],_0x368418[_0x23f893(0x618)]=_0x23f893(0xdb),_0x298d7f[_0x23f893(0x573)](_0x368418);}else connectedDevices[_0xa1e5f2]['status']=_0x59672a[_0x23f893(0x150)];}wss[_0x23f893(0x41b)][_0x23f893(0x224)](_0x52af8a=>{const _0x5c399a=_0x23f893;if(_0x52af8a[_0x5c399a(0x625)]===WebSocket[_0x5c399a(0x467)]){const _0x48f70c={};_0x48f70c[_0x5c399a(0x2ba)]=_0x5c399a(0x246),_0x48f70c[_0x5c399a(0x3d4)]=connectedDevices,_0x52af8a['send'](JSON[_0x5c399a(0x62d)](_0x48f70c));}});const _0x5a97d4={};_0x5a97d4[_0x23f893(0x492)]=!![],_0x5a97d4[_0x23f893(0xef)]='Connected\x20to\x20'+_0x5cdd66+_0x23f893(0x692),_0x5a97d4[_0x23f893(0x2e3)]=!![],_0x59672a[_0x23f893(0x4bc)](_0xa0c362,_0x5a97d4);}else{if(_0x59672a[_0x23f893(0x727)](_0x23f893(0x188),_0x23f893(0x188))){console[_0x23f893(0x37a)]('ā ļø\x20\x20WDA\x20starting\x20for\x20'+_0x5cdd66+',\x20may\x20take\x20a\x20moment...');const _0x89e6cf={};_0x89e6cf[_0x23f893(0x492)]=!![],_0x89e6cf[_0x23f893(0xef)]=_0x23f893(0x372)+_0x5cdd66+_0x23f893(0x14e),_0x89e6cf[_0x23f893(0x1bb)]=!![],_0x59672a['lPQpi'](_0xa0c362,_0x89e6cf);}else _0xd5d292+=_0xc8d53d[_0x23f893(0x2ca)]();}});},0x2710);}}),_0x3154e9['on'](_0x1a92f9['FQWmR'],()=>{const _0x26fd27=_0x36e88e;console[_0x26fd27(0x37a)](_0x26fd27(0x747)+_0x5cdd66+_0x26fd27(0x3ed)+_0x4c5a83+_0x26fd27(0x76c));const _0x1a9222={};_0x1a9222[_0x26fd27(0x492)]=![],_0x1a9222[_0x26fd27(0xef)]=_0x26fd27(0x1fa)+_0x5cdd66+_0x26fd27(0x3ed)+_0x4c5a83+_0x26fd27(0x76c),_0x5a23e6(_0x1a9222);});}}});}async function disconnectFromDevice(_0x36104a){const _0x53e05c=_0x50607,_0x114f9d={'CUoTr':function(_0x31c4ab,_0x131938,_0x53f6d6){return _0x31c4ab(_0x131938,_0x53f6d6);},'oSQCQ':_0x53e05c(0xc5),'AChjy':function(_0x522107,_0x301f3a){return _0x522107(_0x301f3a);},'VVuVd':_0x53e05c(0x653),'KXShG':function(_0x316cb7,_0xe856f4){return _0x316cb7+_0xe856f4;},'asCoc':function(_0xf99fb5,_0x2d2125){return _0xf99fb5!==_0x2d2125;},'NVbRL':_0x53e05c(0x303),'bGSjO':function(_0x515197,_0x1aadbf){return _0x515197!==_0x1aadbf;},'YgNvt':_0x53e05c(0x5fa),'hGJvh':function(_0x3038d9,_0x5ed88d){return _0x3038d9(_0x5ed88d);},'uxTFI':_0x53e05c(0x246),'DIQkj':'NZsGi','jrEyb':function(_0x2d362b,_0x18784c){return _0x2d362b===_0x18784c;},'XyYtn':_0x53e05c(0x30a),'HZgte':_0x53e05c(0x412),'XzznA':_0x53e05c(0xc3),'YEfjL':_0x53e05c(0x5bd),'OHmCu':function(_0x4acc84,_0x672876){return _0x4acc84===_0x672876;},'AKRot':_0x53e05c(0x591),'HZjTD':_0x53e05c(0x70e),'KhNyB':_0x53e05c(0x243),'ZcnsO':function(_0x51018c,_0x184556){return _0x51018c!==_0x184556;},'zbEBk':_0x53e05c(0x1a8),'BgvKg':_0x53e05c(0x322),'RnQQa':'SIGTERM','DvFuz':_0x53e05c(0x537),'wsfHk':_0x53e05c(0x67f),'ONigh':'KITGb','URKeO':function(_0x3aa5d5,_0x24c8c4,_0x3b4508){return _0x3aa5d5(_0x24c8c4,_0x3b4508);},'EoLPf':'close','ZjTDM':_0x53e05c(0x443),'VNwdn':_0x53e05c(0x575),'CSJeM':_0x53e05c(0x752),'CkOxX':function(_0x73fa89,_0x47dc7e,_0x4009f3){return _0x73fa89(_0x47dc7e,_0x4009f3);},'HeqKI':function(_0x30e55a,_0x39a4ed,_0xcde956){return _0x30e55a(_0x39a4ed,_0xcde956);},'HCgye':function(_0x12a8fa,_0x20e239,_0x191f4c){return _0x12a8fa(_0x20e239,_0x191f4c);}};return new Promise((_0x276e4c,_0x58fd56)=>{const _0x1f4fe6=_0x53e05c,_0x5c1691={'iQIqR':function(_0x401afd,_0xe3babe){return _0x401afd===_0xe3babe;},'Sybuw':function(_0x3641c5,_0x36c895){const _0x3d4a86=_0x46ca;return _0x114f9d[_0x3d4a86(0x6ac)](_0x3641c5,_0x36c895);},'WDuCG':function(_0x2b3c49,_0x32f325){return _0x2b3c49!==_0x32f325;},'QbtTi':_0x1f4fe6(0x54b),'tcRwi':'offline','OYYdW':function(_0x1d1e62,_0x3add62){return _0x1d1e62(_0x3add62);},'BWLia':_0x114f9d[_0x1f4fe6(0x190)],'MZyXj':'wireless','AhDpC':_0x1f4fe6(0x443),'jPXIU':_0x114f9d[_0x1f4fe6(0x2e2)],'HAPLa':'Device\x20selection\x20required','zHrWk':_0x114f9d[_0x1f4fe6(0x265)]};if(_0x114f9d[_0x1f4fe6(0x60a)](_0x114f9d['XyYtn'],_0x114f9d[_0x1f4fe6(0x428)])){const {name:_0x19b5c2,connectionType:_0x25ad0e,udid:_0x1ddcc0,platform:_0x4bb12b}=_0x36104a;console[_0x1f4fe6(0x37a)](_0x1f4fe6(0x647)+_0x19b5c2+'\x20('+_0x25ad0e+',\x20platform:\x20'+_0x4bb12b+')...');if(_0x114f9d['jrEyb'](_0x4bb12b,_0x114f9d['HZgte'])){if(_0x114f9d[_0x1f4fe6(0x60a)](_0x114f9d[_0x1f4fe6(0x604)],_0x114f9d[_0x1f4fe6(0x604)])){console[_0x1f4fe6(0x37a)](_0x1f4fe6(0x2cf)+_0x19b5c2),stopUIAutomator2Session(_0x1ddcc0,_0x19b5c2)[_0x1f4fe6(0x4c8)](_0x2dc635=>{const _0x231efa=_0x1f4fe6;console[_0x231efa(0x618)](_0x231efa(0x5e6)+_0x2dc635[_0x231efa(0xef)]);});if(_0x25ad0e===_0x114f9d[_0x1f4fe6(0x75f)]){if(_0x114f9d['OHmCu'](_0x114f9d[_0x1f4fe6(0x711)],_0x114f9d['AKRot'])){const _0x4530ce=_0x114f9d[_0x1f4fe6(0x235)](spawn,_0x114f9d[_0x1f4fe6(0x690)],[_0x114f9d[_0x1f4fe6(0x499)],_0x1ddcc0]);_0x4530ce['on'](_0x1f4fe6(0x3a0),_0x30a026=>{const _0x31ecff=_0x1f4fe6,_0x5a6327={'ELJSh':function(_0x118b70,_0x33a5e3){const _0x159ea2=_0x46ca;return _0x5c1691[_0x159ea2(0xc6)](_0x118b70,_0x33a5e3);},'ukLFI':function(_0x108471,_0x598726){return _0x108471(_0x598726);},'eyohn':_0x31ecff(0x1c0)};console[_0x31ecff(0x37a)](_0x31ecff(0x4a4)+_0x19b5c2+_0x31ecff(0x1cb));const _0x847959=connectedDevices[_0x31ecff(0x34d)](_0x28e988=>_0x28e988[_0x31ecff(0x192)]===_0x19b5c2);if(_0x5c1691[_0x31ecff(0x344)](_0x847959,-0x1)){if(_0x5c1691[_0x31ecff(0x60e)](_0x5c1691[_0x31ecff(0x232)],'GtQZA'))connectedDevices[_0x847959][_0x31ecff(0x160)]=_0x5c1691[_0x31ecff(0x72d)];else{if(FMAdMV['ELJSh'](_0xe06924,0x0)){const _0x4063ad={};_0x4063ad[_0x31ecff(0x492)]=!![],_0x4063ad[_0x31ecff(0x4d3)]=_0x995b55,_0x4063ad[_0x31ecff(0x273)]=_0x1fc669,FMAdMV[_0x31ecff(0x68f)](_0x26b214,_0x4063ad);}else{const _0x149027={};_0x149027[_0x31ecff(0x492)]=![],_0x149027[_0x31ecff(0x618)]=_0x2bf9c6||_0x31ecff(0x27b)+_0x33e0c8,_0x149027[_0x31ecff(0x273)]=_0x3a35dc,_0x218233(_0x149027);}}}wss['clients'][_0x31ecff(0x224)](_0x2c388a=>{const _0x22ca71=_0x31ecff;if(_0x2c388a[_0x22ca71(0x625)]===WebSocket['OPEN']){if(_0x5a6327[_0x22ca71(0x24f)]!=='BiKiE')return{};else{const _0x3b52e6={};_0x3b52e6[_0x22ca71(0x2ba)]=_0x22ca71(0x246),_0x3b52e6['devices']=connectedDevices,_0x2c388a['send'](JSON[_0x22ca71(0x62d)](_0x3b52e6));}}});const _0x3e32a5={};_0x3e32a5['success']=!![],_0x3e32a5[_0x31ecff(0xef)]=_0x31ecff(0x395)+_0x19b5c2+_0x31ecff(0x2bf),_0x5c1691['OYYdW'](_0x276e4c,_0x3e32a5);});}else{const _0x231cb3={};_0x231cb3[_0x1f4fe6(0x4c0)]=_0x1f4fe6(0xb4),_0x231cb3['timeout']=0x2710;const _0x4e6864=_0x114f9d[_0x1f4fe6(0x235)](_0x34a507,_0x1f4fe6(0x358)+_0x2fecc8+'\x20shell\x20pm\x20path\x20'+_0x58ae47,_0x231cb3);_0x4f539e['path']=_0x4e6864[_0x1f4fe6(0x203)](_0x114f9d[_0x1f4fe6(0x20a)],'')[_0x1f4fe6(0x3ea)]();}}else{const _0x5df7ff=connectedDevices[_0x1f4fe6(0x34d)](_0x41c27c=>_0x41c27c[_0x1f4fe6(0x192)]===_0x19b5c2);_0x114f9d['ZcnsO'](_0x5df7ff,-0x1)&&(connectedDevices[_0x5df7ff][_0x1f4fe6(0x160)]=_0x114f9d[_0x1f4fe6(0x696)]);wss['clients']['forEach'](_0x22a9e6=>{const _0x5d3238=_0x1f4fe6;if(_0x22a9e6[_0x5d3238(0x625)]===WebSocket['OPEN']){const _0x9959bc={};_0x9959bc[_0x5d3238(0x2ba)]=_0x5c1691[_0x5d3238(0x2f3)],_0x9959bc[_0x5d3238(0x3d4)]=connectedDevices,_0x22a9e6['send'](JSON[_0x5d3238(0x62d)](_0x9959bc));}});const _0x6683e5={};_0x6683e5['success']=!![],_0x6683e5[_0x1f4fe6(0xef)]='Disconnected\x20from\x20'+_0x19b5c2,_0x276e4c(_0x6683e5);}return;}else{_0x41f734[_0x1f4fe6(0x37a)](_0x1f4fe6(0x386)+_0x52a176);const _0x1ac510={};_0x1ac510[_0x1f4fe6(0x492)]=!![],_0x1ac510[_0x1f4fe6(0xef)]=_0x1f4fe6(0x57f)+_0x2be076+'\x20-\x20ADB\x20Ready\x20ā
',iLpeRA[_0x1f4fe6(0x6c3)](_0x57654d,_0x1ac510);return;}}const _0x5d7382=connectedDevices['find'](_0x4b11db=>_0x4b11db[_0x1f4fe6(0x192)]===_0x19b5c2),_0x286c5c=_0x5d7382?.[_0x1f4fe6(0x3d1)];if(wdaProcesses[_0x1f4fe6(0x689)](_0x19b5c2)){const _0x52f8ed=wdaProcesses[_0x1f4fe6(0x529)](_0x19b5c2);try{if(_0x52f8ed[_0x1f4fe6(0x4dc)]){if(_0x114f9d['bGSjO'](_0x114f9d[_0x1f4fe6(0x24b)],'JWAuz')){const _0x351745=_0xd49bad['ip']||'',_0x5b74cf=_0x160cac[_0x1f4fe6(0x569)]||_0x1f4fe6(0x102),_0x53e665=_0xf8960b[_0x1f4fe6(0x2ba)]||_0x272e0f[_0x1f4fe6(0xb0)]||(_0x351745?_0x5c1691[_0x1f4fe6(0x10f)]:_0x5c1691[_0x1f4fe6(0x4fd)]);_0x2884e6+=_0x54925a[_0x1f4fe6(0x192)]+','+_0xe3605[_0x1f4fe6(0x343)]+','+_0x351745+','+_0x5b74cf+','+_0x53e665+'\x0a';}else try{if(_0x114f9d[_0x1f4fe6(0x1ca)](_0x1f4fe6(0x322),_0x114f9d[_0x1f4fe6(0x269)])){const _0x3b77ec={};_0x3b77ec['success']=!![],_0x3b77ec[_0x1f4fe6(0x4d3)]=_0x5729ed,_0x3b77ec['device']=_0x51ea32,zMwoEL['AChjy'](_0x1008a7,_0x3b77ec);}else process[_0x1f4fe6(0x1cc)](_0x52f8ed[_0x1f4fe6(0x4dc)],_0x114f9d['RnQQa']),console[_0x1f4fe6(0x37a)](_0x1f4fe6(0x64d)+_0x19b5c2+_0x1f4fe6(0x432)+_0x52f8ed['xcodebuild']+')');}catch(_0x367966){_0x114f9d['DvFuz']!==_0x114f9d[_0x1f4fe6(0x4cd)]?_0x763378[_0x1f4fe6(0x65f)](_0x45a74e['stringify']({'type':zMwoEL[_0x1f4fe6(0x2e2)],'data':_0x1f4fe6(0x6a1)+zMwoEL[_0x1f4fe6(0x3b8)](_0xfd812f,0x1)+'/'+_0x3f92dd[_0x1f4fe6(0x484)]+']\x20'+_0x293574+'\x0a','devices':_0x552e67})):console[_0x1f4fe6(0x37a)]('ā ļø\x20\x20xcodebuild\x20process\x20'+_0x52f8ed[_0x1f4fe6(0x4dc)]+_0x1f4fe6(0x6ec));}}if(_0x52f8ed[_0x1f4fe6(0x4b4)])try{process[_0x1f4fe6(0x1cc)](_0x52f8ed[_0x1f4fe6(0x4b4)],_0x114f9d[_0x1f4fe6(0x6f4)]),console['log'](_0x1f4fe6(0x663)+_0x19b5c2+_0x1f4fe6(0x432)+_0x52f8ed[_0x1f4fe6(0x4b4)]+')');}catch(_0x39833d){if(_0x114f9d[_0x1f4fe6(0x6ac)](_0x114f9d['wsfHk'],_0x114f9d[_0x1f4fe6(0x3e2)]))console['log'](_0x1f4fe6(0xce)+_0x52f8ed[_0x1f4fe6(0x4b4)]+_0x1f4fe6(0x6ec));else{const _0x18fd0f={};_0x18fd0f[_0x1f4fe6(0x2ba)]=_0x5c1691[_0x1f4fe6(0x2fb)],_0x18fd0f[_0x1f4fe6(0x49b)]=_0x1f4fe6(0x505),_0x18fd0f['devices']=_0x407ead,_0xbab2cb['send'](_0x4e739e['stringify'](_0x18fd0f));}}wdaProcesses[_0x1f4fe6(0x6ee)](_0x19b5c2);}catch(_0x121e1b){console['error'](_0x1f4fe6(0x511)+_0x19b5c2+':',_0x121e1b);}}if(_0x286c5c){console['log'](_0x1f4fe6(0x16f)+_0x286c5c+_0x1f4fe6(0x60f)+_0x19b5c2+'...');const _0xebd807=_0x114f9d[_0x1f4fe6(0x3cb)](spawn,'sh',['-c',_0x1f4fe6(0x5f8)+_0x286c5c+_0x1f4fe6(0x3c4)]);_0xebd807['on'](_0x114f9d[_0x1f4fe6(0x40b)],()=>{const _0x336a7d=_0x1f4fe6;if(_0x114f9d[_0x336a7d(0x1ca)](_0x114f9d[_0x336a7d(0x300)],_0x336a7d(0x73a)))console[_0x336a7d(0x37a)](_0x336a7d(0x3ba)+_0x286c5c+_0x336a7d(0x60f)+_0x19b5c2);else{const _0x41f03f={};_0x41f03f[_0x336a7d(0x4c0)]='utf-8',_0x41f03f['timeout']=0x2710;const _0x38fbab=_0x566900(_0x336a7d(0x358)+_0x1a43d9+_0x336a7d(0x10e)+_0x173d5c+'\x20|\x20grep\x20versionName',_0x41f03f),_0x579ce7=_0x38fbab[_0x336a7d(0x600)](/versionName=([^\s]+)/);_0x579ce7&&(_0x121307[_0x336a7d(0x733)]=_0x579ce7[0x1]);}});}if(_0x1ddcc0&&_0x25ad0e===_0x114f9d[_0x1f4fe6(0xde)]){if(_0x114f9d[_0x1f4fe6(0x1ca)](_0x114f9d['VNwdn'],_0x114f9d['CSJeM'])){console[_0x1f4fe6(0x37a)](_0x1f4fe6(0x6ff)+_0x1ddcc0+_0x1f4fe6(0x29d));const _0x336978=_0x114f9d['CkOxX'](spawn,'sh',['-c',_0x1f4fe6(0x534)+_0x1ddcc0+_0x1f4fe6(0x17c)]);_0x336978['on'](_0x114f9d['EoLPf'],()=>{const _0x190402=_0x1f4fe6;if(_0x5c1691['Sybuw'](_0x5c1691['zHrWk'],_0x190402(0x487)))console['log'](_0x190402(0x34a)+_0x19b5c2);else{const _0x17c6b3={};return _0x17c6b3[_0x190402(0x492)]=![],_0x17c6b3[_0x190402(0x618)]=_0x5c1691[_0x190402(0x691)],_0x6da97[_0x190402(0x160)](0x190)['json'](_0x17c6b3);}});}else{const _0x332782={};_0x332782['type']=_0x114f9d[_0x1f4fe6(0x2e2)],_0x332782[_0x1f4fe6(0x49b)]='ā\x20Failed:\x20'+_0x1bd9f6[_0x1f4fe6(0xef)]+'\x0a\x0a',_0x332782[_0x1f4fe6(0x3d4)]=_0x1593c5,_0x31f6d7[_0x1f4fe6(0x65f)](_0x3dce0a['stringify'](_0x332782));}}if(_0x25ad0e===_0x1f4fe6(0x443)&&_0x286c5c){const _0x45eee5=_0x114f9d[_0x1f4fe6(0x3c7)](spawn,'sh',['-c',_0x1f4fe6(0x4ff)+_0x286c5c+'\x22\x20||\x20true']);_0x45eee5['on'](_0x114f9d['EoLPf'],()=>{const _0x24b5b2=_0x1f4fe6;console['log'](_0x24b5b2(0x53f)+_0x19b5c2);});}_0x114f9d['HCgye'](setTimeout,()=>{const _0x2fb391=_0x1f4fe6;if(_0x114f9d[_0x2fb391(0x6ac)]('RHAyp',_0x2fb391(0x3ff))){const _0x44bab5=_0x9b7ba3['map'](_0x478c98=>_0x478c98[_0x2fb391(0x192)]+_0x2fb391(0x127)+_0x478c98[_0x2fb391(0x160)]+')')[_0x2fb391(0x4a3)](',\x20');_0x680cd9[_0x2fb391(0x618)]('ā\x20Devices\x20not\x20connected:\x20['+_0x44bab5+']');if(_0x1f579d){const _0x43611f={};_0x43611f[_0x2fb391(0x2ba)]=iLpeRA[_0x2fb391(0x2fb)],_0x43611f['data']='\x0aā ļø\x20\x20Error:\x20Devices\x20not\x20connected:\x20'+_0x44bab5+_0x2fb391(0x345),_0x43611f['devices']=_0x131a71,_0x386830['send'](_0x5ba1dd['stringify'](_0x43611f));}const _0x52f153={};return _0x52f153[_0x2fb391(0x492)]=![],_0x52f153[_0x2fb391(0x618)]=_0x2fb391(0x47f)+_0x44bab5+_0x2fb391(0x56b),iLpeRA[_0x2fb391(0x6c3)](_0x31e2d8,_0x52f153);}else{const _0x3cca4f=connectedDevices[_0x2fb391(0x34d)](_0xb39153=>_0xb39153[_0x2fb391(0x192)]===_0x19b5c2);_0x3cca4f!==-0x1&&(connectedDevices[_0x3cca4f][_0x2fb391(0x160)]=_0x114f9d[_0x2fb391(0x696)]);wss['clients']['forEach'](_0x97eb36=>{const _0x43c39d=_0x2fb391;if(_0x5c1691[_0x43c39d(0xc6)](_0x97eb36['readyState'],WebSocket['OPEN'])){const _0x44c300={};_0x44c300[_0x43c39d(0x2ba)]='devices_updated',_0x44c300[_0x43c39d(0x3d4)]=connectedDevices,_0x97eb36[_0x43c39d(0x65f)](JSON[_0x43c39d(0x62d)](_0x44c300));}}),console['log'](_0x2fb391(0x131)+_0x19b5c2);const _0x2646d8={};_0x2646d8['success']=!![],_0x2646d8[_0x2fb391(0xef)]=_0x2fb391(0x395)+_0x19b5c2+_0x2fb391(0x5d9),_0x114f9d[_0x2fb391(0x2e7)](_0x276e4c,_0x2646d8);}},0x1f4);}else{_0xdfb1b6[_0x1f4fe6(0x618)]('ā\x20Replay\x20command\x20'+(_0x124d5c+0x1)+'\x20failed:',_0x2c4c75[_0x1f4fe6(0xef)]);const _0x1303e1={};_0x1303e1[_0x1f4fe6(0x405)]=_0x41bae6,_0x1303e1[_0x1f4fe6(0x492)]=![],_0x1303e1[_0x1f4fe6(0x618)]=_0x12bcbc[_0x1f4fe6(0xef)],_0x4ba947['push'](_0x1303e1);if(_0x5ec983){const _0x415f28={};_0x415f28[_0x1f4fe6(0x2ba)]=_0x5c1691['jPXIU'],_0x415f28['data']='ā\x20Failed:\x20'+_0x2c76df[_0x1f4fe6(0xef)]+'\x0a\x0a',_0x415f28[_0x1f4fe6(0x3d4)]=_0x1c452a,_0x4e6031[_0x1f4fe6(0x65f)](_0x48e69f['stringify'](_0x415f28));}}});}async function ensureRecordingsDir(){const _0x5cac11=_0x50607,_0x3b6e92={};_0x3b6e92['oUNYK']=_0x5cac11(0x3a6),_0x3b6e92['wweLM']=function(_0x497568,_0x32e80a){return _0x497568===_0x32e80a;},_0x3b6e92[_0x5cac11(0x4b0)]=_0x5cac11(0x327);const _0x4577dd=_0x3b6e92;try{await fs[_0x5cac11(0x746)](RECORDINGS_DIR);}catch{if(_0x4577dd['wweLM'](_0x5cac11(0x327),_0x4577dd[_0x5cac11(0x4b0)])){const _0x55d085={};_0x55d085[_0x5cac11(0x37f)]=!![],await fs[_0x5cac11(0x1d4)](RECORDINGS_DIR,_0x55d085);}else _0x5f59c7[_0x78dcc5]['status']=CjoRCg[_0x5cac11(0x3de)];}}async function startRecording(_0x59a415,_0xfe350d){const _0x42f35b=_0x50607,_0x10de14={'pNlVK':_0x42f35b(0x24d),'TVaCh':function(_0x2f8c4b){return _0x2f8c4b();}},_0x3f93e5=_0x10de14[_0x42f35b(0x71c)][_0x42f35b(0x19b)]('|');let _0x57c7db=0x0;while(!![]){switch(_0x3f93e5[_0x57c7db++]){case'0':const _0xebb396={};_0xebb396['success']=!![],_0xebb396[_0x42f35b(0x1be)]=currentRecording;return _0xebb396;case'1':await _0x10de14[_0x42f35b(0x4af)](ensureRecordingsDir);continue;case'2':console['log'](_0x42f35b(0x5e4)+currentRecording[_0x42f35b(0x192)]);continue;case'3':currentRecording={'name':_0x59a415||'recording_'+Date['now'](),'devices':_0xfe350d||[],'commands':[],'startTime':new Date()[_0x42f35b(0x2c3)]()};continue;case'4':isRecording=!![];continue;}break;}}function recordCommand(_0x3811dd,_0x359ec7,_0x5dd492,_0xbded6e){const _0x3e67dd=_0x50607,_0x2f12f6={};_0x2f12f6['JZPHY']=function(_0x543c7d,_0x337a2e){return _0x543c7d||_0x337a2e;};const _0xfce451=_0x2f12f6;if(!isRecording||!currentRecording)return![];return currentRecording['commands'][_0x3e67dd(0x43e)]({'timestamp':new Date()[_0x3e67dd(0x2c3)](),'devices':_0x3811dd,'originalCommand':_0x359ec7,'useAI':_0x5dd492,'finalCommand':_0xfce451[_0x3e67dd(0x50a)](_0xbded6e,_0x359ec7)}),console[_0x3e67dd(0x37a)]('š\x20Recorded\x20command:\x20'+_0x359ec7+'\x20('+currentRecording[_0x3e67dd(0x1ec)][_0x3e67dd(0x484)]+'\x20total)'),!![];}async function stopRecording(){const _0xf56df5=_0x50607,_0x395205={};_0x395205[_0xf56df5(0x2a2)]=function(_0x4f879f,_0x1a9f72){return _0x4f879f||_0x1a9f72;},_0x395205['Edqjz']=_0xf56df5(0x194);const _0x218251=_0x395205;if(_0x218251['cAuSp'](!isRecording,!currentRecording)){const _0x37aa31={};return _0x37aa31['success']=![],_0x37aa31[_0xf56df5(0x618)]=_0x218251['Edqjz'],_0x37aa31;}currentRecording[_0xf56df5(0x18c)]=new Date()[_0xf56df5(0x2c3)]();const _0x2e5403=currentRecording['name']+_0xf56df5(0x721),_0x33ad61=path[_0xf56df5(0x4a3)](RECORDINGS_DIR,_0x2e5403);await fs[_0xf56df5(0x4b5)](_0x33ad61,JSON[_0xf56df5(0x62d)](currentRecording,null,0x2));const _0x5528b7={};_0x5528b7[_0xf56df5(0x492)]=!![],_0x5528b7[_0xf56df5(0x1be)]=currentRecording,_0x5528b7[_0xf56df5(0x186)]=_0x2e5403;const _0x174251=_0x5528b7;return console[_0xf56df5(0x37a)](_0xf56df5(0x301)+currentRecording[_0xf56df5(0x192)]+'\x20('+currentRecording[_0xf56df5(0x1ec)]['length']+_0xf56df5(0x6e9)),isRecording=![],currentRecording=null,_0x174251;}async function listRecordings(){const _0x36715a=_0x50607,_0x12fe42={'HjINl':'Unknown','WHVXB':function(_0x3335b2){return _0x3335b2();},'TEYHG':_0x36715a(0x33b),'hYZwe':_0x36715a(0x721),'aETjF':_0x36715a(0xb4),'rUthW':function(_0x4b09c8,_0x5c0cdc){return _0x4b09c8!==_0x5c0cdc;},'gyIxK':'DReCj','GSZwT':function(_0xd9af72,_0x226781){return _0xd9af72===_0x226781;},'jYLvD':_0x36715a(0x3a5),'whqYu':'sCJRT','Lnrtw':_0x36715a(0x1ba),'QHUrT':_0x36715a(0x263)};await _0x12fe42[_0x36715a(0x5a4)](ensureRecordingsDir);try{const _0x32f559=await fs['readdir'](RECORDINGS_DIR),_0xb98d6b=[];for(const _0x4e11fb of _0x32f559){if(_0x12fe42[_0x36715a(0x32b)]===_0x12fe42[_0x36715a(0x32b)]){if(_0x4e11fb['endsWith'](_0x12fe42[_0x36715a(0x2cc)]))try{const _0x3e9d13=path['join'](RECORDINGS_DIR,_0x4e11fb),_0x4af5fe=await fs[_0x36715a(0x642)](_0x3e9d13,_0x12fe42[_0x36715a(0x5e5)]),_0x54d3f6=JSON[_0x36715a(0x288)](_0x4af5fe);let _0x5c92de=0x0;if(Array[_0x36715a(0x616)](_0x54d3f6[_0x36715a(0x1ec)]))_0x12fe42[_0x36715a(0x6de)](_0x12fe42[_0x36715a(0x4f5)],_0x12fe42['gyIxK'])?_0x5e8b44[_0x36715a(0x37a)](_0x36715a(0x59c)+_0x38f325[_0x36715a(0x3ea)]()):_0x5c92de=_0x54d3f6[_0x36715a(0x1ec)][_0x36715a(0x484)];else _0x12fe42[_0x36715a(0x650)](typeof _0x54d3f6['commands'],_0x36715a(0x4a5))&&(_0x12fe42[_0x36715a(0x6de)](_0x12fe42[_0x36715a(0x393)],_0x12fe42[_0x36715a(0x45c)])?_0x5c92de=_0x54d3f6[_0x36715a(0x1ec)][_0x36715a(0x19b)]('\x0a')[_0x36715a(0x5a2)](_0x44ab36=>_0x44ab36[_0x36715a(0x3ea)]())[_0x36715a(0x484)]:_0x4fb462[_0x36715a(0x552)]=_0x12fe42[_0x36715a(0x5fe)]);_0xb98d6b[_0x36715a(0x43e)]({'filename':_0x4e11fb,'name':_0x54d3f6['name']||_0x4e11fb['replace'](_0x12fe42[_0x36715a(0x2cc)],''),'devices':_0x54d3f6['devices']||[],'commandCount':_0x5c92de,'startTime':_0x54d3f6['startTime']||_0x54d3f6[_0x36715a(0x445)],'endTime':_0x54d3f6[_0x36715a(0x18c)]||_0x54d3f6[_0x36715a(0x445)],'type':_0x54d3f6[_0x36715a(0x2ba)]||_0x12fe42[_0x36715a(0x375)]});}catch(_0x1146d9){console['error'](_0x36715a(0xa9)+_0x4e11fb+':',_0x1146d9);}}else _0x33f402[_0x36715a(0x618)](_0x36715a(0xa9)+_0x452c1e+':',_0x430382);}return _0xb98d6b;}catch(_0x5c4b4d){return console[_0x36715a(0x618)](_0x12fe42['QHUrT'],_0x5c4b4d),[];}}async function loadRecording(_0x4f2c1b){const _0x57b17f=_0x50607,_0x13cb7d={};_0x13cb7d[_0x57b17f(0x518)]='Unknown',_0x13cb7d['RUdWQ']='utf-8',_0x13cb7d[_0x57b17f(0x1df)]='iWcti';const _0x4aabf5=_0x13cb7d,_0x53a619=path[_0x57b17f(0x4a3)](RECORDINGS_DIR,_0x4f2c1b);try{const _0x214d56=await fs[_0x57b17f(0x642)](_0x53a619,_0x4aabf5[_0x57b17f(0x347)]);return JSON[_0x57b17f(0x288)](_0x214d56);}catch(_0x4428be){if(_0x4aabf5[_0x57b17f(0x1df)]!==_0x4aabf5[_0x57b17f(0x1df)])_0xdbefb4['bundleId']=_0x487e4f,_0x1add00[_0x57b17f(0x192)]=_0x91d926,_0x2c1c14[_0x57b17f(0x733)]=_0x4aabf5[_0x57b17f(0x518)];else{console[_0x57b17f(0x618)](_0x57b17f(0x13c)+_0x4f2c1b+':',_0x4428be);throw _0x4428be;}}}async function deleteRecording(_0x5202a3){const _0x31113c=_0x50607,_0x25a545={};_0x25a545['ueInY']=function(_0x38466c,_0x562cad){return _0x38466c===_0x562cad;},_0x25a545[_0x31113c(0x259)]='gjvrt';const _0xc48887=_0x25a545,_0xf8aec6=path['join'](RECORDINGS_DIR,_0x5202a3);try{await fs[_0x31113c(0x720)](_0xf8aec6);const _0x18699b={};return _0x18699b[_0x31113c(0x492)]=!![],_0x18699b;}catch(_0x3daa86){if(_0xc48887[_0x31113c(0x58a)](_0xc48887[_0x31113c(0x259)],_0xc48887[_0x31113c(0x259)])){console['error'](_0x31113c(0x496)+_0x5202a3+':',_0x3daa86);throw _0x3daa86;}else{const _0x259a58={};return _0x259a58[_0x31113c(0x492)]=![],_0x259a58[_0x31113c(0x618)]=_0x31113c(0x5f6),_0x26aa5e[_0x31113c(0x160)](0x190)['json'](_0x259a58);}}}async function replayRecording(_0x438e4f,_0x21a5a5,_0x215847){const _0x277544=_0x50607,_0x236098={'fqpel':_0x277544(0x15c),'WtPHR':_0x277544(0x5fa),'UEDLr':_0x277544(0x246),'itWDK':_0x277544(0x653),'GMXaW':function(_0x3d04d2,_0x5c0809){return _0x3d04d2===_0x5c0809;},'UwSUh':_0x277544(0x14f),'ciksd':function(_0x2165b3,_0x44adff){return _0x2165b3===_0x44adff;},'ESGSm':_0x277544(0x4a5),'TrZJF':_0x277544(0x485),'NPtmu':_0x277544(0x5d4),'fgsgN':function(_0x7c1e9e,_0x145e95){return _0x7c1e9e===_0x145e95;},'IhtiE':'Oxmnn','rlWGP':function(_0x3ac71e,_0xb8c707){return _0x3ac71e+_0xb8c707;},'VsrBV':function(_0x82f87b,_0x34bc7e){return _0x82f87b+_0x34bc7e;},'rApgz':function(_0x4aa3a9,_0x54d801){return _0x4aa3a9<_0x54d801;},'kEUaG':function(_0xcb0ec0,_0x5bdc68){return _0xcb0ec0!==_0x5bdc68;},'BMfMN':'dsmxB','XTUWy':_0x277544(0x614),'jrrzv':'\x0aā¹ļø\x20\x20Replay\x20aborted\x20by\x20user\x0a','Yjngz':_0x277544(0x758),'qtkki':_0x277544(0x517),'oJOJq':function(_0x233a2b,_0x283bec){return _0x233a2b+_0x283bec;},'PbpuA':'MlYpJ','QYFWW':function(_0x43cdb2,_0x213182,_0x49d9de,_0x57d5c3){return _0x43cdb2(_0x213182,_0x49d9de,_0x57d5c3);},'LFtRO':function(_0x7fcf8d,_0x345046){return _0x7fcf8d-_0x345046;},'XpLcK':function(_0xe69757,_0xdd05f6){return _0xe69757===_0xdd05f6;},'OaLhb':_0x277544(0x631),'TYBup':_0x277544(0x536)},_0x282469=await loadRecording(_0x438e4f);let _0x3429eb=[];if(Array[_0x277544(0x616)](_0x282469[_0x277544(0x1ec)])){if(_0x236098['GMXaW'](_0x236098[_0x277544(0x682)],_0x277544(0x14f)))_0x3429eb=_0x282469[_0x277544(0x1ec)][_0x277544(0x12b)](_0x5f0f5c=>_0x5f0f5c[_0x277544(0x768)]||_0x5f0f5c[_0x277544(0xfe)]);else{const _0x195bdb={};_0x195bdb['success']=!![],_0x195bdb[_0x277544(0x44f)]=_0x564efc,_0x399861['json'](_0x195bdb);}}else _0x236098[_0x277544(0x32c)](typeof _0x282469['commands'],_0x236098[_0x277544(0x248)])&&(_0x236098[_0x277544(0x2c4)](_0x236098[_0x277544(0x65b)],_0x236098[_0x277544(0x532)])?(_0x4d4e5e[_0x277544(0x618)](iAYJZQ[_0x277544(0x500)],_0x5e87a5),_0x81bae9(_0x211010)):_0x3429eb=_0x282469[_0x277544(0x1ec)][_0x277544(0x19b)]('\x0a')[_0x277544(0x5a2)](_0x42ff16=>_0x42ff16[_0x277544(0x3ea)]()));const _0x542985=_0x282469['devices']&&_0x282469[_0x277544(0x3d4)]['length']>0x0?_0x282469[_0x277544(0x3d4)]:_0x21a5a5;console['log']('\x0a'+'ā¶'[_0x277544(0x20b)](0x3c)),console[_0x277544(0x37a)](_0x277544(0x380)+_0x282469[_0x277544(0x192)]),console[_0x277544(0x37a)](_0x277544(0x76d)+_0x542985[_0x277544(0x4a3)](',\x20')),console[_0x277544(0x37a)](_0x277544(0x2e6)+_0x21a5a5[_0x277544(0x4a3)](',\x20')),console[_0x277544(0x37a)](_0x277544(0x5f0)+_0x3429eb[_0x277544(0x484)]),console[_0x277544(0x37a)]('ā¶'[_0x277544(0x20b)](0x3c)+'\x0a'),replayAborted=![],isReplaying=!![];_0x215847&&(_0x236098[_0x277544(0x323)](_0x236098[_0x277544(0x602)],'QGjxM')?_0x3aacb4+=_0x572b98[_0x277544(0x2ca)]():_0x215847[_0x277544(0x65f)](JSON[_0x277544(0x62d)]({'type':_0x236098[_0x277544(0x1d0)],'data':_0x236098['rlWGP'](_0x236098[_0x277544(0x329)](_0x277544(0x4ab)+_0x282469[_0x277544(0x192)]+'\x0a'+('š±\x20Devices:\x20'+_0x21a5a5[_0x277544(0x4a3)](',\x20')+'\x0a'),'š\x20Commands:\x20'+_0x3429eb[_0x277544(0x484)]+'\x0a'),'ā'[_0x277544(0x20b)](0x32)+'\x0a\x0a'),'devices':_0x21a5a5})));const _0xf7fd04=[];for(let _0x3b59d1=0x0;_0x236098[_0x277544(0x42f)](_0x3b59d1,_0x3429eb[_0x277544(0x484)]);_0x3b59d1++){if(_0x236098['kEUaG'](_0x236098[_0x277544(0x678)],_0x236098[_0x277544(0x119)])){if(replayAborted){console[_0x277544(0x37a)](_0x236098[_0x277544(0x47e)]);if(_0x215847){const _0x21c24d={};_0x21c24d[_0x277544(0x2ba)]=_0x277544(0x653),_0x21c24d[_0x277544(0x49b)]=_0x236098['Yjngz'],_0x21c24d['devices']=_0x21a5a5,_0x215847[_0x277544(0x65f)](JSON[_0x277544(0x62d)](_0x21c24d));}isReplaying=![];throw new Error(_0x236098[_0x277544(0x3f2)]);}const _0x2ba6f8=_0x3429eb[_0x3b59d1];console[_0x277544(0x37a)](_0x277544(0x241)+(_0x3b59d1+0x1)+'/'+_0x3429eb[_0x277544(0x484)]),console[_0x277544(0x37a)](_0x277544(0x2b1)+_0x2ba6f8);_0x215847&&_0x215847[_0x277544(0x65f)](JSON[_0x277544(0x62d)]({'type':_0x277544(0x653),'data':_0x277544(0x2bb)+_0x236098[_0x277544(0x62b)](_0x3b59d1,0x1)+'/'+_0x3429eb[_0x277544(0x484)]+_0x277544(0x26c)+_0x2ba6f8+'\x0a','devices':_0x21a5a5}));try{if(_0x236098[_0x277544(0x2d0)]===_0x236098[_0x277544(0x2d0)]){const _0x578c38=await _0x236098[_0x277544(0x4e8)](executeCommand,_0x21a5a5,_0x2ba6f8,null),_0xc69622={};_0xc69622[_0x277544(0x405)]=_0x2ba6f8,_0xc69622[_0x277544(0x492)]=!![],_0xc69622[_0x277544(0x31c)]=_0x578c38,_0xf7fd04[_0x277544(0x43e)](_0xc69622);if(_0x215847){const _0x4a6537={};_0x4a6537[_0x277544(0x2ba)]=_0x236098[_0x277544(0x1d0)],_0x4a6537[_0x277544(0x49b)]=_0x277544(0x505),_0x4a6537[_0x277544(0x3d4)]=_0x21a5a5,_0x215847[_0x277544(0x65f)](JSON[_0x277544(0x62d)](_0x4a6537));}_0x236098['rApgz'](_0x3b59d1,_0x236098[_0x277544(0x6df)](_0x3429eb['length'],0x1))&&(_0x236098[_0x277544(0x2a8)](_0x236098[_0x277544(0x41c)],_0x236098['TYBup'])?_0x42482a['log'](_0x277544(0x592)+_0xc2c17c[_0x277544(0xef)]):await new Promise(_0x266d87=>setTimeout(_0x266d87,0x3e8)));}else _0xdfd8ca[_0x5332ce][_0x277544(0x160)]=iAYJZQ[_0x277544(0x43d)];}catch(_0x5bf3ef){console[_0x277544(0x618)](_0x277544(0x61e)+_0x236098['rlWGP'](_0x3b59d1,0x1)+_0x277544(0x2d9),_0x5bf3ef[_0x277544(0xef)]);const _0x4e0bc3={};_0x4e0bc3[_0x277544(0x405)]=_0x2ba6f8,_0x4e0bc3[_0x277544(0x492)]=![],_0x4e0bc3[_0x277544(0x618)]=_0x5bf3ef[_0x277544(0xef)],_0xf7fd04[_0x277544(0x43e)](_0x4e0bc3);if(_0x215847){const _0x36bd38={};_0x36bd38[_0x277544(0x2ba)]=_0x277544(0x653),_0x36bd38[_0x277544(0x49b)]=_0x277544(0x2e9)+_0x5bf3ef['message']+'\x0a\x0a',_0x36bd38['devices']=_0x21a5a5,_0x215847[_0x277544(0x65f)](JSON[_0x277544(0x62d)](_0x36bd38));}}}else{if(_0x11dbae[_0x277544(0x625)]===_0x4d28ea[_0x277544(0x467)]){const _0x220eff={};_0x220eff[_0x277544(0x2ba)]=iAYJZQ[_0x277544(0x352)],_0x220eff['devices']=_0x427a4d,_0x63ee8[_0x277544(0x65f)](_0x90d09c[_0x277544(0x62d)](_0x220eff)),_0x327439[_0x277544(0x65f)](_0x16073e[_0x277544(0x62d)]({'type':iAYJZQ[_0x277544(0x1d0)],'output':'ā
\x20'+_0x9c4c3c+_0x277544(0x348)+'ā'[_0x277544(0x20b)](0x32)+'\x0a','device':_0x5b0950}));}}}isReplaying=![],console[_0x277544(0x37a)]('\x0a'+'ā¶'[_0x277544(0x20b)](0x3c)),console['log'](_0x277544(0x462)),console[_0x277544(0x37a)](_0x277544(0x474)+_0xf7fd04[_0x277544(0x484)]+',\x20Success:\x20'+_0xf7fd04[_0x277544(0x5a2)](_0x1828f3=>_0x1828f3[_0x277544(0x492)])[_0x277544(0x484)]+_0x277544(0x603)+_0xf7fd04[_0x277544(0x5a2)](_0x1e2e0b=>!_0x1e2e0b[_0x277544(0x492)])['length']),console[_0x277544(0x37a)]('ā¶'['repeat'](0x3c)+'\x0a');const _0x225ce0={};return _0x225ce0[_0x277544(0x492)]=!![],_0x225ce0['recording']=_0x282469[_0x277544(0x192)],_0x225ce0['results']=_0xf7fd04,_0x225ce0;}app['get']('/api/devices',async(_0x2a2498,_0x2fc244)=>{const _0x24f2b4=_0x50607,_0x5a4c9a={'chNUz':function(_0x27a1b4){return _0x27a1b4();}};try{const _0x4a264d=await _0x5a4c9a['chNUz'](discoverDevices),_0xdbc50d={};_0xdbc50d[_0x24f2b4(0x492)]=!![],_0xdbc50d[_0x24f2b4(0x3d4)]=_0x4a264d,_0x2fc244[_0x24f2b4(0x573)](_0xdbc50d);}catch(_0x31da26){const _0x254ffd={};_0x254ffd[_0x24f2b4(0x492)]=![],_0x254ffd[_0x24f2b4(0x618)]=_0x31da26[_0x24f2b4(0xef)],_0x2fc244['status'](0x1f4)[_0x24f2b4(0x573)](_0x254ffd);}}),app[_0x50607(0x633)]('/api/devices/refresh',async(_0x3fb446,_0xdd77fa)=>{const _0x49a1e2=_0x50607,_0x57057e={'ofovx':function(_0x1f08da,_0x5e0e69){return _0x1f08da===_0x5e0e69;},'lTWug':_0x49a1e2(0x6b2),'BjTRz':_0x49a1e2(0xb8),'jgKPf':'WebDriverAgent','xTNQk':function(_0x5dc0fa){return _0x5dc0fa();},'suAkF':function(_0x21fe7d,_0x211361){return _0x21fe7d===_0x211361;},'OGAGy':_0x49a1e2(0x53d)};try{const _0x4366bf=await _0x57057e[_0x49a1e2(0x3c2)](discoverDevices);wss[_0x49a1e2(0x41b)][_0x49a1e2(0x224)](_0x5c5434=>{const _0x51fed9=_0x49a1e2;if(_0x57057e['ofovx'](_0x5c5434[_0x51fed9(0x625)],WebSocket['OPEN'])){if(_0x57057e[_0x51fed9(0x751)](_0x57057e[_0x51fed9(0x4fe)],_0x57057e['lTWug'])){const _0x599db6={};_0x599db6['type']=_0x51fed9(0x246),_0x599db6[_0x51fed9(0x3d4)]=_0x4366bf,_0x5c5434['send'](JSON[_0x51fed9(0x62d)](_0x599db6));}else{const _0x435880=_0x2465ee[_0x51fed9(0x2ca)]();_0x374680+=_0x435880,_0x286957[_0x51fed9(0x37a)]('['+_0xfd03fe[_0x51fed9(0x192)]+_0x51fed9(0x354)+_0x435880['trim']());}}});const _0x27a6ce={};_0x27a6ce[_0x49a1e2(0x492)]=!![],_0x27a6ce[_0x49a1e2(0x3d4)]=_0x4366bf,_0xdd77fa[_0x49a1e2(0x573)](_0x27a6ce);}catch(_0x49cc44){if(_0x57057e[_0x49a1e2(0x285)](_0x57057e[_0x49a1e2(0x4f1)],_0x57057e[_0x49a1e2(0x4f1)])){const _0x50dd1f={};_0x50dd1f[_0x49a1e2(0x492)]=![],_0x50dd1f[_0x49a1e2(0x618)]=_0x49cc44['message'],_0xdd77fa[_0x49a1e2(0x160)](0x1f4)[_0x49a1e2(0x573)](_0x50dd1f);}else{const _0x530e18=_0x519031[_0x49a1e2(0x2ca)]();(_0x530e18['includes'](wUebjd[_0x49a1e2(0x195)])||_0x530e18[_0x49a1e2(0x185)](wUebjd[_0x49a1e2(0x6d4)]))&&_0x58348b[_0x49a1e2(0x37a)](_0x49a1e2(0x59c)+_0x530e18[_0x49a1e2(0x3ea)]());}}}),app[_0x50607(0x633)](_0x50607(0x5ae),async(_0x2201d7,_0x1a217c)=>{const _0x16dae2=_0x50607,_0x566d94={'ljRPA':_0x16dae2(0x4b8),'ZoPBG':function(_0x45b9d3,_0x503f0a){return _0x45b9d3===_0x503f0a;},'yfXqM':function(_0x590aad,_0x56b79f){return _0x590aad===_0x56b79f;},'AvWyj':_0x16dae2(0x2c0),'bgokr':'No\x20devices\x20specified','BULdw':function(_0x23dc30,_0x3d4bcd){return _0x23dc30!==_0x3d4bcd;},'EBydR':_0x16dae2(0x4cf),'SoPJN':_0x16dae2(0x75e),'YlOyw':function(_0xdcecf9,_0x32ffcd,_0x46038e,_0x51a1c6){return _0xdcecf9(_0x32ffcd,_0x46038e,_0x51a1c6);},'MviuE':function(_0x1e3014,_0x1af170,_0x539ee9,_0x3a2ac1){return _0x1e3014(_0x1af170,_0x539ee9,_0x3a2ac1);}};try{const {devices:_0x415d76,command:_0x240133,useAI:_0xff16ed,aiProvider:_0x20daa8}=_0x2201d7[_0x16dae2(0x6a0)];if(!_0x415d76||_0x566d94[_0x16dae2(0x3f6)](_0x415d76['length'],0x0)){if(_0x566d94[_0x16dae2(0x447)](_0x566d94[_0x16dae2(0x54e)],'JseSV')){const _0x55deed={};return _0x55deed[_0x16dae2(0x492)]=![],_0x55deed[_0x16dae2(0x618)]=_0x566d94['bgokr'],_0x1a217c[_0x16dae2(0x160)](0x190)[_0x16dae2(0x573)](_0x55deed);}else{_0xb43ec4['error'](_0x16dae2(0x42a)+_0x3bd8d9+':',_0x9cdb23[_0x16dae2(0xef)]);const _0x2b2284={};return _0x2b2284[_0x16dae2(0x492)]=![],_0x2b2284[_0x16dae2(0x618)]=_0x104e54[_0x16dae2(0xef)],_0x2b2284;}}let _0x1bdf0b=_0x240133;if(_0xff16ed){if(_0x566d94[_0x16dae2(0x11c)](_0x566d94[_0x16dae2(0x332)],_0x566d94[_0x16dae2(0x628)]))_0x1bdf0b=await _0x566d94[_0x16dae2(0xd3)](convertNaturalLanguageToCommand,_0x240133,_0x415d76,_0x20daa8);else return _0x4f89f1;}const _0x1e22f7=_0x1bdf0b[_0x16dae2(0x185)]('\x0a');let _0x17b236;_0x1e22f7?_0x17b236=await _0x566d94[_0x16dae2(0x309)](executeCommandsSequentially,_0x415d76,_0x1bdf0b,null):_0x17b236=await _0x566d94['YlOyw'](executeCommand,_0x415d76,_0x1bdf0b,null),_0x1a217c[_0x16dae2(0x573)](_0x17b236);}catch(_0x33a35d){if(_0x566d94[_0x16dae2(0x447)](_0x16dae2(0x522),_0x16dae2(0x522))){const _0x1ac99b={};_0x1ac99b[_0x16dae2(0x492)]=![],_0x1ac99b[_0x16dae2(0x618)]=_0x33a35d[_0x16dae2(0xef)],_0x1a217c[_0x16dae2(0x160)](0x1f4)['json'](_0x1ac99b);}else{const _0x41ecd5={};return _0x41ecd5[_0x16dae2(0x492)]=![],_0x41ecd5['error']=_0x566d94[_0x16dae2(0x2ea)],_0x23b121[_0x16dae2(0x160)](0x190)[_0x16dae2(0x573)](_0x41ecd5);}}}),app[_0x50607(0x633)](_0x50607(0x469),async(_0x46cf16,_0x37e5c8)=>{const _0x47f2fb=_0x50607,_0x167255={'LAKPe':function(_0xcdade6,_0xa1e6bc,_0xb3d09d,_0x53f210){return _0xcdade6(_0xa1e6bc,_0xb3d09d,_0x53f210);}};try{const {text:_0x28f746,devices:_0x5c12d3,provider:_0x116398}=_0x46cf16[_0x47f2fb(0x6a0)],_0x4686ab=await _0x167255[_0x47f2fb(0x549)](convertNaturalLanguageToCommand,_0x28f746,_0x5c12d3||[],_0x116398),_0x382aa8={};_0x382aa8[_0x47f2fb(0x492)]=!![],_0x382aa8[_0x47f2fb(0x405)]=_0x4686ab,_0x37e5c8['json'](_0x382aa8);}catch(_0x5e5aa2){const _0x5627fa={};_0x5627fa[_0x47f2fb(0x492)]=![],_0x5627fa[_0x47f2fb(0x618)]=_0x5e5aa2['message'],_0x37e5c8[_0x47f2fb(0x160)](0x1f4)[_0x47f2fb(0x573)](_0x5627fa);}}),app['post'](_0x50607(0x4bd),async(_0x2ecd9d,_0x3c337a)=>{const _0xc9a43d=_0x50607,_0x582c8d={};_0x582c8d[_0xc9a43d(0x58e)]=_0xc9a43d(0x263),_0x582c8d[_0xc9a43d(0x68e)]=function(_0x477b03,_0x1f85f2){return _0x477b03===_0x1f85f2;},_0x582c8d[_0xc9a43d(0x5c0)]=_0xc9a43d(0x68d),_0x582c8d[_0xc9a43d(0x3c5)]=_0xc9a43d(0x5bc),_0x582c8d[_0xc9a43d(0x11d)]=function(_0x136dfe,_0x543a39){return _0x136dfe!==_0x543a39;},_0x582c8d[_0xc9a43d(0x742)]=_0xc9a43d(0x67c),_0x582c8d[_0xc9a43d(0xae)]='IOYiG',_0x582c8d['YCkFg']='ā\x20Invalid\x20device\x20object:',_0x582c8d[_0xc9a43d(0x6da)]=_0xc9a43d(0x5b6);const _0x5d2acd=_0x582c8d;try{const {device:_0x295e0a}=_0x2ecd9d['body'];console[_0xc9a43d(0x37a)](_0xc9a43d(0xda),_0x295e0a);if(!_0x295e0a){if(_0x5d2acd[_0xc9a43d(0x68e)](_0xc9a43d(0x271),_0xc9a43d(0x271))){console[_0xc9a43d(0x618)](_0x5d2acd[_0xc9a43d(0x5c0)]);const _0x25cc6a={};return _0x25cc6a['success']=![],_0x25cc6a[_0xc9a43d(0x618)]=_0x5d2acd['uHbvg'],_0x3c337a[_0xc9a43d(0x160)](0x190)[_0xc9a43d(0x573)](_0x25cc6a);}else _0x4d278d[_0xc9a43d(0x37a)]('ā ļø\x20\x20Could\x20not\x20stop\x20UIAutomator2\x20server:\x20'+_0x39e310[_0xc9a43d(0xef)]);}if(!_0x295e0a[_0xc9a43d(0x192)]||!_0x295e0a[_0xc9a43d(0x343)]){if(_0x5d2acd[_0xc9a43d(0x11d)](_0x5d2acd[_0xc9a43d(0x742)],_0x5d2acd[_0xc9a43d(0xae)])){console[_0xc9a43d(0x618)](_0x5d2acd[_0xc9a43d(0x4d9)],_0x295e0a);const _0x259a02={};return _0x259a02[_0xc9a43d(0x492)]=![],_0x259a02[_0xc9a43d(0x618)]=_0x5d2acd[_0xc9a43d(0x6da)],_0x3c337a[_0xc9a43d(0x160)](0x190)['json'](_0x259a02);}else return _0x45f16f[_0xc9a43d(0x618)](EqEBgV['IlwWe'],_0x20e02c),[];}const _0x4393a3=await connectToDevice(_0x295e0a);console[_0xc9a43d(0x37a)](_0xc9a43d(0x514),_0x4393a3),_0x3c337a['json'](_0x4393a3);}catch(_0x11d51c){console['error'](_0xc9a43d(0x73e),_0x11d51c);const _0x29ce2a={};_0x29ce2a[_0xc9a43d(0x492)]=![],_0x29ce2a[_0xc9a43d(0x618)]=_0x11d51c[_0xc9a43d(0xef)],_0x3c337a[_0xc9a43d(0x160)](0x1f4)[_0xc9a43d(0x573)](_0x29ce2a);}}),app['post'](_0x50607(0x1e3),async(_0x1a18d5,_0x294e4b)=>{const _0x40f88e=_0x50607,_0x65a4bf={'XhTKk':function(_0x57a0a2,_0x4077c3){return _0x57a0a2(_0x4077c3);},'iBffN':function(_0x5f7883,_0x166fc0){return _0x5f7883!==_0x166fc0;},'lKefX':_0x40f88e(0x132)};try{const {device:_0x40b0a6}=_0x1a18d5[_0x40f88e(0x6a0)],_0x5ca758=await _0x65a4bf['XhTKk'](disconnectFromDevice,_0x40b0a6);_0x294e4b['json'](_0x5ca758);}catch(_0x3202c5){if(_0x65a4bf['iBffN'](_0x65a4bf[_0x40f88e(0x306)],'QbgfR')){const _0x33fcd1={};_0x33fcd1[_0x40f88e(0x492)]=![],_0x33fcd1[_0x40f88e(0x618)]=_0x3202c5['message'],_0x294e4b[_0x40f88e(0x160)](0x1f4)[_0x40f88e(0x573)](_0x33fcd1);}else{_0x12777e[_0x40f88e(0x618)](_0x40f88e(0x29e)+_0x33db24[_0x40f88e(0xef)]);const _0x36f6d3={};_0x36f6d3[_0x40f88e(0x492)]=![],_0x36f6d3[_0x40f88e(0xef)]=_0x40f88e(0x33c)+_0x40f9a7[_0x40f88e(0xef)],hwSJlG[_0x40f88e(0x321)](_0x26903b,_0x36f6d3);}}}),app[_0x50607(0x633)](_0x50607(0x5cf),async(_0x466fb3,_0x417d1d)=>{const _0x444c84=_0x50607,_0x9b82ec={};_0x9b82ec[_0x444c84(0x5aa)]=function(_0x3e0799,_0x2d9969){return _0x3e0799!==_0x2d9969;},_0x9b82ec['bydJB']='mWFCh',_0x9b82ec[_0x444c84(0x612)]=_0x444c84(0x51a),_0x9b82ec[_0x444c84(0x297)]='lUowL',_0x9b82ec['bXfmA']=_0x444c84(0x1bd);const _0x30ad57=_0x9b82ec;try{if(_0x30ad57[_0x444c84(0x5aa)]('HahqF',_0x30ad57[_0x444c84(0x5d3)])){console['log'](_0x444c84(0x6d3));const _0x306565=connectedDevices[_0x444c84(0x5a2)](_0x5b52cb=>_0x5b52cb['status']===_0x444c84(0x3a6));if(_0x306565[_0x444c84(0x484)]===0x0){if(_0x30ad57[_0x444c84(0x612)]===_0x30ad57[_0x444c84(0x297)]){_0xc229c0[_0x444c84(0x618)](_0x444c84(0x3bd)+_0x20e5b7[_0x444c84(0xef)]);const _0x48fdba={};_0x48fdba[_0x444c84(0x2ba)]=_0x444c84(0x31a),_0x48fdba[_0x444c84(0x618)]=_0x2e9c04[_0x444c84(0xef)],_0x38467b[_0x444c84(0x65f)](_0x16086d[_0x444c84(0x62d)](_0x48fdba));}else{const _0x25d040={};return _0x25d040[_0x444c84(0x492)]=!![],_0x25d040[_0x444c84(0xef)]=_0x30ad57[_0x444c84(0x64e)],_0x417d1d['json'](_0x25d040);}}console[_0x444c84(0x37a)]('š±\x20Disconnecting\x20'+_0x306565[_0x444c84(0x484)]+_0x444c84(0x6cb));const _0xe7abc3=_0x306565[_0x444c84(0x12b)](_0x195118=>disconnectFromDevice(_0x195118));await Promise[_0x444c84(0xd8)](_0xe7abc3),console[_0x444c84(0x37a)](_0x444c84(0x713));const _0x5d8bf5={};_0x5d8bf5[_0x444c84(0x492)]=!![],_0x5d8bf5['message']='Disconnected\x20'+_0x306565[_0x444c84(0x484)]+_0x444c84(0x717),_0x5d8bf5['count']=_0x306565[_0x444c84(0x484)],_0x417d1d[_0x444c84(0x573)](_0x5d8bf5);}else _0x4911d1['log'](_0x444c84(0x1c5)+_0x559bbe+_0x444c84(0x29d));}catch(_0x551d16){console[_0x444c84(0x618)](_0x444c84(0x28a),_0x551d16);const _0x316ce3={};_0x316ce3[_0x444c84(0x492)]=![],_0x316ce3[_0x444c84(0x618)]=_0x551d16[_0x444c84(0xef)],_0x417d1d[_0x444c84(0x160)](0x1f4)[_0x444c84(0x573)](_0x316ce3);}}),app[_0x50607(0x529)](_0x50607(0x24c),(_0x2b6d33,_0x32ec95)=>{const _0x435646=_0x50607,_0x40b323={};_0x40b323['asMbu']=function(_0x44c9ef,_0x460e68){return _0x44c9ef===_0x460e68;},_0x40b323[_0x435646(0x6ad)]='tvvAT';const _0x70cf5c=_0x40b323;try{if(_0x70cf5c[_0x435646(0x683)](_0x70cf5c['QXphA'],'tvvAT')){const _0x145fe0=aiManager[_0x435646(0x430)](),_0x4ccc6b=aiManager['getCurrentProvider'](),_0x4a1e72={};_0x4a1e72[_0x435646(0x492)]=!![],_0x4a1e72[_0x435646(0x144)]=_0x145fe0,_0x4a1e72[_0x435646(0x335)]=_0x4ccc6b['id'],_0x32ec95[_0x435646(0x573)](_0x4a1e72);}else _0xa1de3d[_0x435646(0x37a)](_0x435646(0x3ba)+_0x24a7a7+_0x435646(0x60f)+_0x55848c);}catch(_0x56c4b6){const _0x2bc4c9={};_0x2bc4c9[_0x435646(0x492)]=![],_0x2bc4c9['error']=_0x56c4b6[_0x435646(0xef)],_0x32ec95['status'](0x1f4)[_0x435646(0x573)](_0x2bc4c9);}}),app['post'](_0x50607(0x754),(_0x4c6435,_0x526f0d)=>{const _0x55fd80=_0x50607,_0x29aa32={};_0x29aa32[_0x55fd80(0x504)]=_0x55fd80(0x10c),_0x29aa32[_0x55fd80(0x6c2)]=function(_0x172773,_0x151db7){return _0x172773===_0x151db7;},_0x29aa32[_0x55fd80(0x26f)]='ZlFWB',_0x29aa32[_0x55fd80(0x30b)]=function(_0x3eedc6,_0x137ef1){return _0x3eedc6===_0x137ef1;},_0x29aa32['NwWGg']='Invalid\x20or\x20unavailable\x20provider';const _0x14a014=_0x29aa32;try{const {provider:_0x2885df}=_0x4c6435['body'],_0x5669db=aiManager[_0x55fd80(0x16e)](_0x2885df);if(_0x5669db){if(_0x14a014[_0x55fd80(0x6c2)](_0x55fd80(0x256),_0x14a014[_0x55fd80(0x26f)]))_0x3d2532['error'](GrktFv['TurJc'],_0xe7c00f);else{const _0x15383e={};_0x15383e[_0x55fd80(0x492)]=!![],_0x15383e['provider']=_0x2885df,_0x526f0d[_0x55fd80(0x573)](_0x15383e);}}else{if(_0x14a014[_0x55fd80(0x30b)](_0x55fd80(0xe0),'VokqR')){const _0x56a461={};_0x56a461[_0x55fd80(0x2ba)]=_0x55fd80(0x653),_0x56a461['data']='['+_0xbb795e+']\x20'+_0x36805d,_0x56a461[_0x55fd80(0x3d4)]=[_0x57b0c5],_0x2522d7[_0x55fd80(0x65f)](_0x79a8b4[_0x55fd80(0x62d)](_0x56a461));}else{const _0x337aaa={};_0x337aaa[_0x55fd80(0x492)]=![],_0x337aaa['error']=_0x14a014['NwWGg'],_0x526f0d[_0x55fd80(0x160)](0x190)[_0x55fd80(0x573)](_0x337aaa);}}}catch(_0x1558f1){const _0x429563={};_0x429563[_0x55fd80(0x492)]=![],_0x429563[_0x55fd80(0x618)]=_0x1558f1[_0x55fd80(0xef)],_0x526f0d[_0x55fd80(0x160)](0x1f4)['json'](_0x429563);}}),app['get'](_0x50607(0x376),async(_0x2b9c8c,_0x5cebe4)=>{const _0x5d5687=_0x50607,_0x8c260c={'eurOU':function(_0x108cde,_0x36b9ff){return _0x108cde===_0x36b9ff;},'weBUX':function(_0x38a27f,_0x29a6bd){return _0x38a27f&&_0x29a6bd;},'dHvDv':_0x5d5687(0x503),'nXyKE':_0x5d5687(0x524),'hFJkd':function(_0x212696,_0x323b95){return _0x212696===_0x323b95;},'pxHLv':function(_0x48a806,_0x666f1c){return _0x48a806===_0x666f1c;},'qmXAy':_0x5d5687(0x1db),'Kacuw':function(_0x2494dc,_0x3d40d2){return _0x2494dc===_0x3d40d2;},'YJaqx':_0x5d5687(0x6fc),'YHcSl':function(_0xfb9b12,_0xfb7d68){return _0xfb9b12===_0xfb7d68;},'JWkED':function(_0x46b937,_0x52bd54){return _0x46b937<_0x52bd54;},'bugnA':function(_0x215fcd,_0x1bee3c){return _0x215fcd-_0x1bee3c;},'dYhrA':_0x5d5687(0x1cf),'GVfor':_0x5d5687(0x490),'AlZoU':function(_0xf62996,_0x3c629e){return _0xf62996!==_0x3c629e;},'QMgKJ':_0x5d5687(0x14a),'AxDRm':function(_0x585cb9,_0x36a02f){return _0x585cb9(_0x36a02f);},'dYdfA':function(_0x437bfd,_0x538911){return _0x437bfd(_0x538911);},'BAhtT':function(_0x1dc7dd,_0x43cd72){return _0x1dc7dd(_0x43cd72);},'kbHFK':function(_0x97e6a8,_0x5e349d){return _0x97e6a8(_0x5e349d);}};try{const _0x46cfab=path[_0x5d5687(0x4a3)](__dirname,_0x8c260c[_0x5d5687(0x38e)]),_0xe11b08={};_0xe11b08[_0x5d5687(0x44f)]=process.env.AI_PROVIDER||_0x8c260c[_0x5d5687(0x458)],_0xe11b08[_0x5d5687(0x736)]=process.env.AI_MODEL||'',_0xe11b08[_0x5d5687(0x2d7)]=process.env.OPENAI_API_KEY||'',_0xe11b08['gemini_api_key']=process.env.GEMINI_API_KEY||'',_0xe11b08[_0x5d5687(0x19f)]=process.env.CLAUDE_API_KEY||'',_0xe11b08[_0x5d5687(0x6c5)]=process.env.GITHUB_TOKEN||'',_0xe11b08[_0x5d5687(0x765)]=process.env.GROQ_API_KEY||'',_0xe11b08[_0x5d5687(0x70d)]=process.env.COHERE_API_KEY||'',_0xe11b08[_0x5d5687(0xb5)]=process.env.MISTRAL_API_KEY||'';let _0x47eff2=_0xe11b08;try{if(_0x8c260c[_0x5d5687(0x610)](_0x8c260c[_0x5d5687(0x6f3)],_0x5d5687(0x609))){const _0x475093=await fs[_0x5d5687(0x642)](_0x46cfab,_0x5d5687(0xb4)),_0x29450c=_0x475093['split']('\x0a');_0x29450c[_0x5d5687(0x224)](_0x39fdd4=>{const _0x1e42c4=_0x5d5687;if(_0x8c260c[_0x1e42c4(0x6f2)](_0x1e42c4(0x4da),'ragiI')){const [_0x12ad67,_0x5737d2]=_0x39fdd4[_0x1e42c4(0x19b)]('=');if(_0x8c260c[_0x1e42c4(0x724)](_0x12ad67,_0x5737d2)){const _0x4ee63d=_0x12ad67['trim'](),_0x439430=_0x5737d2['trim']();if(_0x4ee63d===_0x1e42c4(0x5db))_0x47eff2[_0x1e42c4(0x44f)]=_0x439430;if(_0x8c260c[_0x1e42c4(0x6f2)](_0x4ee63d,_0x8c260c[_0x1e42c4(0x6db)]))_0x47eff2['model']=_0x439430;if(_0x8c260c[_0x1e42c4(0x6f2)](_0x4ee63d,_0x8c260c[_0x1e42c4(0x209)]))_0x47eff2[_0x1e42c4(0x2d7)]=_0x439430;if(_0x8c260c['hFJkd'](_0x4ee63d,_0x1e42c4(0x1bf)))_0x47eff2['gemini_api_key']=_0x439430;if(_0x8c260c[_0x1e42c4(0x6d8)](_0x4ee63d,_0x8c260c[_0x1e42c4(0x33a)]))_0x47eff2[_0x1e42c4(0x19f)]=_0x439430;if(_0x8c260c[_0x1e42c4(0x2a0)](_0x4ee63d,_0x8c260c[_0x1e42c4(0x178)]))_0x47eff2[_0x1e42c4(0x6c5)]=_0x439430;if(_0x8c260c['pxHLv'](_0x4ee63d,_0x1e42c4(0x71b)))_0x47eff2[_0x1e42c4(0x765)]=_0x439430;if(_0x4ee63d===_0x1e42c4(0x36d))_0x47eff2[_0x1e42c4(0x70d)]=_0x439430;if(_0x8c260c[_0x1e42c4(0x1d1)](_0x4ee63d,_0x1e42c4(0x667)))_0x47eff2[_0x1e42c4(0xb5)]=_0x439430;}}else _0x327cdd[_0x1e42c4(0x618)]('Error\x20stopping\x20UIAutomator2\x20session:\x20'+_0x11fd2f[_0x1e42c4(0xef)]);});}else{const _0x348656={};_0x348656[_0x5d5687(0x2ba)]=_0x5d5687(0x246),_0x348656['devices']=_0x1a01d5,_0x567f71[_0x5d5687(0x65f)](_0x525069['stringify'](_0x348656));}}catch(_0x32d763){}const _0x42a982=_0x4f799d=>{const _0x11e550=_0x5d5687;if(!_0x4f799d||_0x8c260c[_0x11e550(0x61d)](_0x4f799d[_0x11e550(0x484)],0x8))return'';return'ā¢'[_0x11e550(0x20b)](_0x8c260c['bugnA'](_0x4f799d[_0x11e550(0x484)],0x4))+_0x4f799d[_0x11e550(0x5b1)](-0x4);};_0x5cebe4[_0x5d5687(0x573)]({'provider':_0x47eff2[_0x5d5687(0x44f)],'model':_0x47eff2['model'],'openai_api_key':_0x42a982(_0x47eff2[_0x5d5687(0x2d7)]),'gemini_api_key':_0x8c260c[_0x5d5687(0x266)](_0x42a982,_0x47eff2[_0x5d5687(0x2ce)]),'claude_api_key':_0x42a982(_0x47eff2[_0x5d5687(0x19f)]),'github_token':_0x8c260c[_0x5d5687(0x266)](_0x42a982,_0x47eff2['github_token']),'groq_api_key':_0x8c260c[_0x5d5687(0x14b)](_0x42a982,_0x47eff2[_0x5d5687(0x765)]),'cohere_api_key':_0x8c260c[_0x5d5687(0x450)](_0x42a982,_0x47eff2[_0x5d5687(0x70d)]),'mistral_api_key':_0x8c260c[_0x5d5687(0x6a8)](_0x42a982,_0x47eff2[_0x5d5687(0xb5)]),'has_openai_key':!!_0x47eff2[_0x5d5687(0x2d7)],'has_gemini_key':!!_0x47eff2[_0x5d5687(0x2ce)],'has_claude_key':!!_0x47eff2[_0x5d5687(0x19f)],'has_github_token':!!_0x47eff2[_0x5d5687(0x6c5)],'has_groq_key':!!_0x47eff2[_0x5d5687(0x765)],'has_cohere_key':!!_0x47eff2[_0x5d5687(0x70d)],'has_mistral_key':!!_0x47eff2[_0x5d5687(0xb5)]});}catch(_0x5d6936){const _0x3c4904={};_0x3c4904[_0x5d5687(0x492)]=![],_0x3c4904[_0x5d5687(0x618)]=_0x5d6936['message'],_0x5cebe4['status'](0x1f4)[_0x5d5687(0x573)](_0x3c4904);}}),app[_0x50607(0x633)](_0x50607(0x376),async(_0x2dc9c0,_0x264dc2)=>{const _0x1d95ea=_0x50607,_0x3fa08b={};_0x3fa08b[_0x1d95ea(0x15a)]=_0x1d95ea(0x660),_0x3fa08b['MhUJg']=_0x1d95ea(0x11e),_0x3fa08b[_0x1d95ea(0x5ed)]=function(_0x24159a,_0x3d72ea){return _0x24159a===_0x3d72ea;},_0x3fa08b['oLRqL']=_0x1d95ea(0x1cf),_0x3fa08b[_0x1d95ea(0x48b)]=function(_0x1dbec6,_0x54939a){return _0x1dbec6===_0x54939a;},_0x3fa08b[_0x1d95ea(0x2b5)]=_0x1d95ea(0x4c1),_0x3fa08b[_0x1d95ea(0x3d7)]=_0x1d95ea(0x557),_0x3fa08b[_0x1d95ea(0x286)]=_0x1d95ea(0x29c),_0x3fa08b[_0x1d95ea(0x205)]=function(_0x3ab9d0,_0x2f316c){return _0x3ab9d0!==_0x2f316c;},_0x3fa08b['nevTo']=_0x1d95ea(0x385);const _0x6b6803=_0x3fa08b;try{if(_0x6b6803['ACbaQ'](_0x1d95ea(0x291),_0x1d95ea(0x291))){const {provider:_0x71b139,model:_0xa476e4,openai_api_key:_0x51c8b2,gemini_api_key:_0x553337,claude_api_key:_0x1db6fd,github_token:_0x5eb2f8,groq_api_key:_0x732cb0,cohere_api_key:_0x31d9f9,mistral_api_key:_0x1b79f2}=_0x2dc9c0[_0x1d95ea(0x6a0)],_0xad9aaf=path[_0x1d95ea(0x4a3)](__dirname,_0x6b6803['oLRqL']);let _0x210d59=_0x1d95ea(0x523)+_0x71b139+'\x0a';if(_0xa476e4){if(_0x6b6803[_0x1d95ea(0x48b)](_0x6b6803[_0x1d95ea(0x2b5)],_0x6b6803[_0x1d95ea(0x2b5)]))_0x210d59+='AI_MODEL='+_0xa476e4+'\x0a';else{const _0x245d76={};return _0x245d76[_0x1d95ea(0x492)]=![],_0x245d76[_0x1d95ea(0x618)]=_0x6b6803[_0x1d95ea(0x15a)],_0x10e8fd[_0x1d95ea(0x160)](0x190)[_0x1d95ea(0x573)](_0x245d76);}}_0x51c8b2&&(_0x1d95ea(0x557)!==_0x6b6803[_0x1d95ea(0x3d7)]?_0x414985[_0x1d95ea(0x37a)](_0x1d95ea(0x5da)+_0x4ed2a4[_0x1d95ea(0xef)]):_0x210d59+='OPENAI_API_KEY='+_0x51c8b2+'\x0a');_0x553337&&(_0x210d59+=_0x1d95ea(0x6c7)+_0x553337+'\x0a');_0x1db6fd&&(_0x210d59+=_0x1d95ea(0x2b4)+_0x1db6fd+'\x0a');if(_0x5eb2f8){if(_0x6b6803['ACbaQ'](_0x6b6803['oOGtH'],_0x1d95ea(0x29c)))_0x210d59+='GITHUB_TOKEN='+_0x5eb2f8+'\x0a';else{const _0x27e1f4={};return _0x27e1f4[_0x1d95ea(0x492)]=![],_0x27e1f4[_0x1d95ea(0x618)]=_0x1d95ea(0x3a8)+_0x3ac7d5[_0x1d95ea(0xef)],_0xbf3eea[_0x1d95ea(0x160)](0x1f4)['json'](_0x27e1f4);}}_0x732cb0&&(_0x210d59+=_0x1d95ea(0x644)+_0x732cb0+'\x0a');_0x31d9f9&&(_0x6b6803['jhBHR'](_0x6b6803['nevTo'],_0x6b6803[_0x1d95ea(0x4eb)])?_0x4a3e5c[_0x1d95ea(0x37a)](_0x1d95ea(0x34a)+_0xfccf96):_0x210d59+='COHERE_API_KEY='+_0x31d9f9+'\x0a');_0x1b79f2&&(_0x210d59+=_0x1d95ea(0xd9)+_0x1b79f2+'\x0a');process.env.WDA_PATH&&(_0x210d59+='WDA_PATH='+process.env.WDA_PATH+'\x0a');await fs[_0x1d95ea(0x4b5)](_0xad9aaf,_0x210d59),process.env.AI_PROVIDER=_0x71b139;if(_0xa476e4)process.env.AI_MODEL=_0xa476e4;if(_0x51c8b2)process.env.OPENAI_API_KEY=_0x51c8b2;if(_0x553337)process.env.GEMINI_API_KEY=_0x553337;if(_0x1db6fd)process.env.CLAUDE_API_KEY=_0x1db6fd;if(_0x5eb2f8)process.env.GITHUB_TOKEN=_0x5eb2f8;if(_0x732cb0)process.env.GROQ_API_KEY=_0x732cb0;if(_0x31d9f9)process.env.COHERE_API_KEY=_0x31d9f9;if(_0x1b79f2)process.env.MISTRAL_API_KEY=_0x1b79f2;aiManager['provider']=_0x71b139;if(_0xa476e4)aiManager[_0x1d95ea(0x736)]=_0xa476e4;aiManager[_0x1d95ea(0x770)]();const _0x444840={};_0x444840[_0x1d95ea(0x492)]=!![],_0x444840[_0x1d95ea(0xef)]='API\x20configuration\x20saved',_0x264dc2[_0x1d95ea(0x573)](_0x444840);}else{const _0x11d567={};return _0x11d567[_0x1d95ea(0x492)]=![],_0x11d567['error']=_0x6b6803[_0x1d95ea(0xc1)],_0x49d083[_0x1d95ea(0x160)](0x190)['json'](_0x11d567);}}catch(_0x8805e9){const _0x5569ba={};_0x5569ba[_0x1d95ea(0x492)]=![],_0x5569ba['error']=_0x8805e9[_0x1d95ea(0xef)],_0x264dc2[_0x1d95ea(0x160)](0x1f4)['json'](_0x5569ba);}}),app['get'](_0x50607(0x267),(_0x543213,_0x7a2dcc)=>{const _0x1f0cad=_0x50607,_0x510e44={'vAnjq':function(_0x2b366f,_0x3c2664){return _0x2b366f(_0x3c2664);},'WLYDJ':_0x1f0cad(0x1af)};try{const {AI_PROVIDERS_CONFIG:_0x2ca733}=_0x510e44[_0x1f0cad(0xd5)](require,_0x510e44[_0x1f0cad(0x44c)]),_0x243707={};_0x243707[_0x1f0cad(0x492)]=!![],_0x243707[_0x1f0cad(0x144)]=_0x2ca733,_0x7a2dcc[_0x1f0cad(0x573)](_0x243707);}catch(_0x460b8c){const _0x3cfbb5={};_0x3cfbb5[_0x1f0cad(0x492)]=![],_0x3cfbb5[_0x1f0cad(0x618)]=_0x460b8c[_0x1f0cad(0xef)],_0x7a2dcc[_0x1f0cad(0x160)](0x1f4)[_0x1f0cad(0x573)](_0x3cfbb5);}}),app[_0x50607(0x529)](_0x50607(0x157),async(_0x5ce256,_0x3c17a1)=>{const _0x553baf=_0x50607,_0x33c781={'RVWAt':function(_0x1b7684){return _0x1b7684();}};try{const _0x3eced5=await _0x33c781['RVWAt'](loadDeviceConfig),_0x15e4e1={};_0x15e4e1[_0x553baf(0x492)]=!![],_0x15e4e1[_0x553baf(0x3d4)]=_0x3eced5,_0x3c17a1['json'](_0x15e4e1);}catch(_0x36580b){const _0x41006d={};_0x41006d[_0x553baf(0x492)]=![],_0x41006d[_0x553baf(0x618)]=_0x36580b[_0x553baf(0xef)],_0x3c17a1[_0x553baf(0x160)](0x1f4)[_0x553baf(0x573)](_0x41006d);}}),app[_0x50607(0x633)]('/api/settings/devices',async(_0xabbd7,_0x21de7a)=>{const _0x5943d6=_0x50607,_0x30e390={};_0x30e390[_0x5943d6(0x71f)]=_0x5943d6(0x1bd),_0x30e390[_0x5943d6(0x4c5)]=function(_0x4815a5,_0x24f6ee){return _0x4815a5===_0x24f6ee;},_0x30e390['NaEsv']=_0x5943d6(0x51f),_0x30e390['xHUBF']='ios',_0x30e390['wVebe']=_0x5943d6(0x443),_0x30e390[_0x5943d6(0x198)]=_0x5943d6(0x655),_0x30e390[_0x5943d6(0x638)]='#\x20Format:\x20device_name,udid,ip_address,platform,type\x0a',_0x30e390[_0x5943d6(0x4a0)]=_0x5943d6(0x152),_0x30e390[_0x5943d6(0x1fd)]=_0x5943d6(0x298),_0x30e390['VgSno']=_0x5943d6(0x46a),_0x30e390['mEwgo']=_0x5943d6(0x5fd),_0x30e390[_0x5943d6(0x55f)]=_0x5943d6(0x3f0),_0x30e390[_0x5943d6(0x2eb)]=_0x5943d6(0x545),_0x30e390[_0x5943d6(0x65d)]=_0x5943d6(0x530),_0x30e390[_0x5943d6(0x756)]=_0x5943d6(0x305),_0x30e390[_0x5943d6(0x153)]='#\x20iPhone17,00008130-001945C63ED3401E,,ios,usb\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(iOS\x20USB\x20-\x20auto-detected)\x0a',_0x30e390[_0x5943d6(0x139)]='#\x20iPhone16P,00008140-001C24361E41801C,10.173.221.204,ios,wireless\x20\x20(iOS\x20Wireless)\x0a',_0x30e390[_0x5943d6(0x23d)]=_0x5943d6(0x4a1),_0x30e390[_0x5943d6(0x456)]=_0x5943d6(0x562),_0x30e390['rEZia']=function(_0x3b9b87,_0x858e66){return _0x3b9b87!==_0x858e66;},_0x30e390[_0x5943d6(0x5bb)]=_0x5943d6(0x3c8);const _0x290dff=_0x30e390;try{const {devices:_0x25f679}=_0xabbd7['body'];let _0x51b8f6=_0x290dff[_0x5943d6(0x198)];_0x51b8f6+=_0x290dff['RkCKh'],_0x51b8f6+=_0x290dff[_0x5943d6(0x4a0)],_0x51b8f6+='#\x20Type:\x20usb\x20|\x20wireless\x0a',_0x51b8f6+=_0x290dff[_0x5943d6(0x1fd)],_0x51b8f6+=_0x290dff[_0x5943d6(0x755)],_0x51b8f6+=_0x290dff[_0x5943d6(0x3d2)],_0x51b8f6+=_0x290dff[_0x5943d6(0x55f)],_0x51b8f6+='#\x0a',_0x51b8f6+=_0x5943d6(0x4e3),_0x51b8f6+=_0x290dff[_0x5943d6(0x2eb)],_0x51b8f6+=_0x290dff[_0x5943d6(0x65d)],_0x51b8f6+=_0x5943d6(0x6ef),_0x51b8f6+='#\x0a',_0x51b8f6+=_0x290dff[_0x5943d6(0x756)],_0x51b8f6+=_0x290dff['AMZdx'],_0x51b8f6+=_0x290dff['UrFNa'],_0x51b8f6+=_0x290dff[_0x5943d6(0x23d)],_0x51b8f6+='#\x20GalaxyS23,ABCD1234,192.168.1.150,android,wireless\x20\x20\x20\x20\x20(Android\x20Wireless)\x0a\x0a',_0x25f679[_0x5943d6(0x224)](_0x22a8de=>{const _0xe12acb=_0x5943d6,_0x116157={};_0x116157[_0xe12acb(0x41d)]=_0x290dff[_0xe12acb(0x71f)];const _0x4f267b=_0x116157;if(_0x290dff[_0xe12acb(0x4c5)](_0x290dff['NaEsv'],'XJAUw')){const _0x3a9dfd=_0x22a8de['ip']||'',_0x3f6bb9=_0x22a8de[_0xe12acb(0x569)]||_0x290dff[_0xe12acb(0x563)],_0x2d8293=_0x22a8de[_0xe12acb(0x2ba)]||_0x22a8de[_0xe12acb(0xb0)]||(_0x3a9dfd?_0xe12acb(0x5bd):_0x290dff[_0xe12acb(0x54d)]);_0x51b8f6+=_0x22a8de['name']+','+_0x22a8de[_0xe12acb(0x343)]+','+_0x3a9dfd+','+_0x3f6bb9+','+_0x2d8293+'\x0a';}else{const _0x3012dc={};return _0x3012dc[_0xe12acb(0x492)]=!![],_0x3012dc[_0xe12acb(0xef)]=XmbuRB[_0xe12acb(0x41d)],_0x19ddb9[_0xe12acb(0x573)](_0x3012dc);}}),await fs['writeFile'](DEVICE_CONFIG,_0x51b8f6);const _0x332099={};_0x332099[_0x5943d6(0x492)]=!![],_0x332099[_0x5943d6(0xef)]=_0x290dff[_0x5943d6(0x456)],_0x21de7a[_0x5943d6(0x573)](_0x332099);}catch(_0x24252b){if(_0x290dff[_0x5943d6(0x37d)](_0x290dff[_0x5943d6(0x5bb)],_0x290dff[_0x5943d6(0x5bb)]))_0x158662+=_0x5e9510[_0x5943d6(0x2ca)]();else{const _0x38bba5={};_0x38bba5[_0x5943d6(0x492)]=![],_0x38bba5[_0x5943d6(0x618)]=_0x24252b[_0x5943d6(0xef)],_0x21de7a[_0x5943d6(0x160)](0x1f4)[_0x5943d6(0x573)](_0x38bba5);}}}),app[_0x50607(0x529)](_0x50607(0x316),async(_0x2d8408,_0x1c4e76)=>{const _0x221e73=_0x50607,_0xcfc7a3={};_0xcfc7a3[_0x221e73(0x1ee)]=function(_0x53a561,_0x2b0c4f){return _0x53a561!==_0x2b0c4f;},_0xcfc7a3['QRAbs']='JGAfC';const _0x41cb4a=_0xcfc7a3;try{const _0x19e052=await fs[_0x221e73(0x642)](APPS_CONFIG,_0x221e73(0xb4)),_0x2fe437=_0x19e052[_0x221e73(0x19b)]('\x0a')['filter'](_0x2a6981=>_0x2a6981['trim']()&&!_0x2a6981['startsWith']('#'))['map'](_0xd4812a=>{const _0x21e4f0=_0x221e73,[_0x505076,_0x395148]=_0xd4812a['split'](',');return{'name':_0x505076['trim'](),'packageId':_0x395148[_0x21e4f0(0x3ea)]()};}),_0x3bddd4={};_0x3bddd4[_0x221e73(0x492)]=!![],_0x3bddd4[_0x221e73(0x635)]=_0x2fe437,_0x1c4e76['json'](_0x3bddd4);}catch(_0x419a0f){if(_0x41cb4a[_0x221e73(0x1ee)](_0x41cb4a[_0x221e73(0x410)],_0x221e73(0x716))){const _0x200b81={};_0x200b81[_0x221e73(0x492)]=![],_0x200b81[_0x221e73(0x618)]=_0x419a0f[_0x221e73(0xef)],_0x1c4e76[_0x221e73(0x160)](0x1f4)['json'](_0x200b81);}else{const _0x46b467={};_0x46b467[_0x221e73(0x492)]=![],_0x46b467[_0x221e73(0x618)]='Recording\x20not\x20found',_0x2b82df['status'](0x194)[_0x221e73(0x573)](_0x46b467);}}}),app[_0x50607(0x633)](_0x50607(0xfc),async(_0x3516cf,_0x38ff4a)=>{const _0x25be83=_0x50607,_0x4501aa={'quYYI':function(_0x9c8326,_0x275f04){return _0x9c8326===_0x275f04;},'FIfCW':function(_0x4b26dc,_0x2d2e4f){return _0x4b26dc!==_0x2d2e4f;},'QvbSW':_0x25be83(0x3a6),'MLsLd':'No\x20active\x20session','wJZKq':_0x25be83(0x246),'rfsjY':function(_0x262682,_0x5ead4d){return _0x262682(_0x5ead4d);},'qyTGA':_0x25be83(0x4b8),'JSOrW':'Device\x20not\x20found','xXQjl':function(_0x8fedf2,_0x50a5bc){return _0x8fedf2===_0x50a5bc;},'sMBiR':'android','JdFrB':_0x25be83(0x6e4),'kWoob':_0x25be83(0x21b),'ojZRO':'QqyhS','eiZNT':function(_0x157350,_0x50447a){return _0x157350(_0x50447a);},'jFFGM':function(_0x4586f8,_0x2de73b,_0xf17409,_0x1fce1b){return _0x4586f8(_0x2de73b,_0xf17409,_0x1fce1b);},'JKQjH':_0x25be83(0x67d),'KPiiD':'lISao','HKbJd':function(_0x52a53c,_0x342a5a){return _0x52a53c!==_0x342a5a;},'TGefJ':'mhrDY','hFFam':function(_0x399d54,_0x4ed226){return _0x399d54===_0x4ed226;},'feUfK':_0x25be83(0x757),'SLrkc':_0x25be83(0x6a9),'wtFOr':_0x25be83(0x67e),'iSjbv':_0x25be83(0x5c6),'dGYCD':_0x25be83(0x58f),'KKDfL':'ā\x20Command\x20execution\x20failed','vzDPM':_0x25be83(0x748),'VcyaD':_0x25be83(0x56a)};try{const {deviceName:_0x277272}=_0x3516cf[_0x25be83(0x6a0)];if(!_0x277272){const _0xc98013={};return _0xc98013[_0x25be83(0x492)]=![],_0xc98013[_0x25be83(0x618)]=_0x4501aa[_0x25be83(0xeb)],_0x38ff4a['status'](0x190)[_0x25be83(0x573)](_0xc98013);}console[_0x25be83(0x37a)]('\x0aš\x20API:\x20Getting\x20locators\x20for\x20device:\x20'+_0x277272);const _0xca6ae1=connectedDevices['find'](_0x9a1053=>_0x9a1053[_0x25be83(0x192)]===_0x277272);if(!_0xca6ae1){const _0x4bffda={};return _0x4bffda[_0x25be83(0x492)]=![],_0x4bffda[_0x25be83(0x618)]=_0x4501aa[_0x25be83(0x396)],_0x38ff4a[_0x25be83(0x160)](0x194)[_0x25be83(0x573)](_0x4bffda);}if(_0x4501aa[_0x25be83(0x52a)](_0xca6ae1[_0x25be83(0x569)],_0x4501aa[_0x25be83(0x4be)])){if(_0x4501aa[_0x25be83(0x155)]!==_0x4501aa['JdFrB']){const _0x20c368={};_0x20c368[_0x25be83(0x492)]=![],_0x20c368[_0x25be83(0x618)]=_0x3bc723['message'],_0x466d63['status'](0x1f4)[_0x25be83(0x573)](_0x20c368);}else{const _0x455ab2=androidSessions['get'](_0xca6ae1[_0x25be83(0x343)]);if(!_0x455ab2){console[_0x25be83(0x37a)]('š”\x20Auto-connecting\x20'+_0x277272+_0x25be83(0x685));try{if(_0x4501aa['quYYI'](_0x4501aa[_0x25be83(0x72f)],_0x4501aa['ojZRO']))return _0x53e1bd;else{const _0x191a26=await _0x4501aa[_0x25be83(0x1ff)](connectToDevice,_0xca6ae1);if(!_0x191a26['success']){const _0x2c9745={};return _0x2c9745['success']=![],_0x2c9745['error']=_0x25be83(0x164),_0x38ff4a[_0x25be83(0x160)](0x1f4)[_0x25be83(0x573)](_0x2c9745);}await new Promise(_0x460af0=>setTimeout(_0x460af0,0x7d0));}}catch(_0x5ea0f8){const _0x167d90={};return _0x167d90[_0x25be83(0x492)]=![],_0x167d90['error']=_0x25be83(0x3a8)+_0x5ea0f8[_0x25be83(0xef)],_0x38ff4a['status'](0x1f4)[_0x25be83(0x573)](_0x167d90);}}}}const _0x181669=await _0x4501aa['jFFGM'](executeCommand,[_0x277272],_0x4501aa[_0x25be83(0x370)],null);console['log'](_0x25be83(0x40f)+_0x181669[_0x25be83(0x492)]),console['log'](_0x25be83(0x40d)+(_0x181669['results']?.[_0x25be83(0x484)]||0x0));if(_0x181669[_0x25be83(0x492)]&&_0x181669['results']){let _0x45b999='';for(const _0x1e4cf5 of _0x181669[_0x25be83(0x5b9)]){console['log'](_0x25be83(0x403),_0x1e4cf5);if(_0x1e4cf5['status']===_0x25be83(0x757)&&_0x1e4cf5['value']&&_0x1e4cf5[_0x25be83(0x55d)][_0x25be83(0x5b9)]){if(_0x4501aa['KPiiD']===_0x4501aa[_0x25be83(0x5d5)])for(const _0x454405 of _0x1e4cf5[_0x25be83(0x55d)][_0x25be83(0x5b9)]){if(_0x4501aa[_0x25be83(0x1f3)](_0x4501aa[_0x25be83(0x2f8)],'Xfuxb')){console[_0x25be83(0x37a)](_0x25be83(0x424)+_0x454405[_0x25be83(0x160)]);if(_0x4501aa[_0x25be83(0x4e4)](_0x454405[_0x25be83(0x160)],_0x4501aa[_0x25be83(0x533)])&&_0x454405[_0x25be83(0x55d)]){if(_0x454405[_0x25be83(0x55d)][_0x25be83(0x492)]&&_0x454405[_0x25be83(0x55d)][_0x25be83(0x4d3)]){_0x45b999=_0x454405[_0x25be83(0x55d)]['output'],console['log']('ā
\x20Found\x20output:\x20'+_0x45b999['length']+_0x25be83(0x1c2));break;}else{if(_0x454405['value']['error']){if(_0x4501aa[_0x25be83(0x454)]===_0x4501aa['SLrkc']){console[_0x25be83(0x37a)](_0x25be83(0xc9),_0x454405[_0x25be83(0x55d)][_0x25be83(0x618)]);const _0x41fadd={};return _0x41fadd[_0x25be83(0x492)]=![],_0x41fadd[_0x25be83(0x618)]=_0x4501aa['wtFOr'],_0x38ff4a[_0x25be83(0x160)](0x1f4)[_0x25be83(0x573)](_0x41fadd);}else{const _0x55621b={'brKWj':function(_0x3a8632,_0x5764e1){return eFXrWh['quYYI'](_0x3a8632,_0x5764e1);},'ObEep':_0x25be83(0x246)},_0xd45c09=_0x13040e[_0x25be83(0x34d)](_0x4cb3cb=>_0x4cb3cb[_0x25be83(0x192)]===_0x501c67);eFXrWh['FIfCW'](_0xd45c09,-0x1)&&(_0x2a4f40[_0xd45c09][_0x25be83(0x160)]=eFXrWh[_0x25be83(0x5bf)],_0x2c6ab0['clients']['forEach'](_0x436622=>{const _0xe1f4bb=_0x25be83;if(_0x55621b[_0xe1f4bb(0x280)](_0x436622['readyState'],_0x5efde8[_0xe1f4bb(0x467)])){const _0xb1db40={};_0xb1db40['type']=_0x55621b['ObEep'],_0xb1db40[_0xe1f4bb(0x3d4)]=_0x2b11c8,_0x436622['send'](_0x5317aa[_0xe1f4bb(0x62d)](_0xb1db40));}}));const _0x31f201={};_0x31f201[_0x25be83(0x492)]=!![],_0x31f201['message']=_0x25be83(0x57f)+_0x3fdef6+_0x25be83(0x5fb),_0x4b0f4e(_0x31f201);}}}}}else{_0x3f6f51[_0x25be83(0x37a)]('ā ļø\x20\x20No\x20active\x20session\x20found\x20for\x20'+_0x1a8d58);const _0x6b4604={};return _0x6b4604[_0x25be83(0x492)]=!![],_0x6b4604[_0x25be83(0xef)]=eFXrWh[_0x25be83(0x1f7)],_0x6b4604;}}else{if(_0x2a13b7[_0x25be83(0x625)]===_0x491404[_0x25be83(0x467)]){const _0x31c38b={};_0x31c38b[_0x25be83(0x2ba)]=eFXrWh['wJZKq'],_0x31c38b[_0x25be83(0x3d4)]=_0x2e6a6e,_0x47b4f1[_0x25be83(0x65f)](_0x10cfb0['stringify'](_0x31c38b));}}}if(_0x45b999)break;}if(!_0x45b999){console[_0x25be83(0x37a)]('ā\x20No\x20output\x20found\x20in\x20results'),console['log'](_0x4501aa[_0x25be83(0x6b4)],JSON[_0x25be83(0x62d)](_0x181669,null,0x2));const _0x29dd6e={};return _0x29dd6e[_0x25be83(0x492)]=![],_0x29dd6e[_0x25be83(0x618)]=_0x4501aa[_0x25be83(0x19c)],_0x38ff4a[_0x25be83(0x160)](0x1f4)[_0x25be83(0x573)](_0x29dd6e);}const _0x410709=_0x4501aa[_0x25be83(0x509)](parseLocatorsOutput,_0x45b999);console[_0x25be83(0x37a)](_0x25be83(0x704)+_0x410709[_0x25be83(0x484)]+'\x20locators');const _0x120769=_0x410709[_0x25be83(0x5a2)](_0x2165f6=>_0x2165f6['name']||_0x2165f6['label']||_0x2165f6['text']);console[_0x25be83(0x37a)](_0x25be83(0x56d)+_0x120769[_0x25be83(0x484)]+_0x25be83(0x4a7));const _0x16c849={};_0x16c849[_0x25be83(0x492)]=!![],_0x16c849[_0x25be83(0x544)]=_0x120769,_0x38ff4a[_0x25be83(0x573)](_0x16c849);}else{console[_0x25be83(0x37a)](_0x4501aa[_0x25be83(0x5ea)]);const _0x595903={};_0x595903[_0x25be83(0x492)]=![],_0x595903[_0x25be83(0x618)]=_0x4501aa[_0x25be83(0x1b8)],_0x38ff4a[_0x25be83(0x160)](0x1f4)[_0x25be83(0x573)](_0x595903);}}catch(_0x12187a){if(_0x4501aa[_0x25be83(0x3cf)]!==_0x4501aa[_0x25be83(0x3cf)]){const _0x521eee={};_0x521eee[_0x25be83(0x492)]=![],eFXrWh['rfsjY'](_0x5ef0f1,_0x521eee);}else{console[_0x25be83(0x618)](_0x25be83(0x23c),_0x12187a);const _0x3703e6={};_0x3703e6['success']=![],_0x3703e6[_0x25be83(0x618)]=_0x12187a['message'],_0x38ff4a[_0x25be83(0x160)](0x1f4)['json'](_0x3703e6);}}}),app[_0x50607(0x633)]('/api/locators/click',async(_0x1e2c34,_0x15edbd)=>{const _0x32edea=_0x50607,_0x56e170={};_0x56e170[_0x32edea(0x48e)]=function(_0x23e549,_0x139203){return _0x23e549!==_0x139203;},_0x56e170[_0x32edea(0x15f)]=_0x32edea(0x664),_0x56e170[_0x32edea(0x69e)]=_0x32edea(0x24e),_0x56e170[_0x32edea(0x66d)]=_0x32edea(0x4b8),_0x56e170[_0x32edea(0x2e0)]=function(_0x46b250,_0x18aa60){return _0x46b250!==_0x18aa60;},_0x56e170[_0x32edea(0x687)]=_0x32edea(0x11e),_0x56e170['THuMk']=_0x32edea(0x1ea),_0x56e170[_0x32edea(0x1f4)]=_0x32edea(0x6eb),_0x56e170['eBnNc']='ā\x20Tap\x20error:';const _0x241e6f=_0x56e170;try{const {deviceName:_0x24c53c,locatorName:_0x1258e3,x:_0x32d92a,y:_0x28efb4}=_0x1e2c34[_0x32edea(0x6a0)];if(!_0x24c53c){if(_0x241e6f[_0x32edea(0x48e)](_0x241e6f['zeVWC'],_0x241e6f[_0x32edea(0x69e)])){const _0x2c1cea={};return _0x2c1cea[_0x32edea(0x492)]=![],_0x2c1cea[_0x32edea(0x618)]=_0x241e6f['lZxRK'],_0x15edbd[_0x32edea(0x160)](0x190)['json'](_0x2c1cea);}else{const _0x4a6c7d={};_0x4a6c7d['success']=![],_0x4a6c7d[_0x32edea(0x618)]=_0x768554['message'],_0x390ef6['status'](0x1f4)[_0x32edea(0x573)](_0x4a6c7d);}}let _0x14379d;if(_0x32d92a!==undefined&&_0x241e6f['iChkF'](_0x28efb4,undefined))_0x14379d=_0x32edea(0x2f4)+_0x32d92a+','+_0x28efb4,console['log'](_0x32edea(0x320)+_0x32d92a+','+_0x28efb4+_0x32edea(0x5ec)+_0x24c53c);else{if(_0x1258e3)_0x14379d=_0x32edea(0x2c1)+_0x1258e3+'\x22',console['log'](_0x32edea(0xc0)+_0x1258e3+_0x32edea(0x25d)+_0x24c53c);else{const _0xeecd50={};return _0xeecd50[_0x32edea(0x492)]=![],_0xeecd50[_0x32edea(0x618)]=_0x241e6f[_0x32edea(0x687)],_0x15edbd[_0x32edea(0x160)](0x190)[_0x32edea(0x573)](_0xeecd50);}}const _0x45a5d2=await executeCommand([_0x24c53c],_0x14379d,null);if(_0x45a5d2['success']){const _0x511f0b={};_0x511f0b[_0x32edea(0x492)]=!![],_0x511f0b[_0x32edea(0xef)]=_0x241e6f['THuMk'],_0x15edbd['json'](_0x511f0b);}else{const _0x438a4f={};_0x438a4f[_0x32edea(0x492)]=![],_0x438a4f[_0x32edea(0x618)]=_0x241e6f[_0x32edea(0x1f4)],_0x15edbd[_0x32edea(0x160)](0x1f4)[_0x32edea(0x573)](_0x438a4f);}}catch(_0x5eb1f4){console[_0x32edea(0x618)](_0x241e6f['eBnNc'],_0x5eb1f4);const _0x57f85c={};_0x57f85c['success']=![],_0x57f85c[_0x32edea(0x618)]=_0x5eb1f4['message'],_0x15edbd['status'](0x1f4)[_0x32edea(0x573)](_0x57f85c);}});function parseLocatorsOutput(_0x250292){const _0x1d77da=_0x50607,_0x1caa52={'gzhyQ':function(_0x45c128,_0x20f40d,_0x290a78){return _0x45c128(_0x20f40d,_0x290a78);},'hvhxq':_0x1d77da(0xb4),'jOpQS':function(_0x476053,_0x10bfef){return _0x476053(_0x10bfef);},'XIXMr':_0x1d77da(0x761),'qGMwl':function(_0x43f569,_0x4ae038){return _0x43f569(_0x4ae038);},'uErBa':function(_0x498795,_0x38a669){return _0x498795(_0x38a669);},'KGgtS':function(_0x255bd4,_0x44aca8){return _0x255bd4===_0x44aca8;},'kklSR':_0x1d77da(0x246),'YigGm':_0x1d77da(0x3a6),'VuZDh':function(_0x22892f,_0x1546f5){return _0x22892f>=_0x1546f5;},'OTlbH':_0x1d77da(0xca),'PExWc':_0x1d77da(0xdd),'VhSMa':_0x1d77da(0x312),'ocbmW':_0x1d77da(0x5a5),'wtaoM':function(_0x4317af,_0x186cee){return _0x4317af!==_0x186cee;},'pjZSI':_0x1d77da(0x6b8),'LAsIS':_0x1d77da(0x356),'LwBdf':_0x1d77da(0x542),'InFod':_0x1d77da(0x29b),'VTwZA':function(_0x59f23c,_0x344c92){return _0x59f23c===_0x344c92;},'simNh':'UEQTg','OKuis':function(_0x38080a,_0x27328e){return _0x38080a<_0x27328e;},'kUQav':'Label:','UwcRC':'txTHv','JytAH':_0x1d77da(0x6b5),'bBycE':function(_0x510924,_0x31ed99){return _0x510924!==_0x31ed99;},'kLzLf':'VkUfs','xEkWg':_0x1d77da(0x6a4),'ekJPu':function(_0xdc363,_0x244de1){return _0xdc363!==_0x244de1;},'qmXbP':_0x1d77da(0x401),'xFKFk':'2|4|1|3|0','VDwZY':function(_0x40dd1f,_0x3c58ec){return _0x40dd1f(_0x3c58ec);},'GExhs':_0x1d77da(0x281),'BnYKl':_0x1d77da(0xfa),'xkdEd':function(_0x1c593a,_0x38dd4e){return _0x1c593a===_0x38dd4e;},'BoVNg':_0x1d77da(0x66a),'GpLqC':_0x1d77da(0x2f6),'cZQcb':function(_0xdc0360,_0xc41137){return _0xdc0360!==_0xc41137;},'VRQfC':_0x1d77da(0x34b),'UMxqI':_0x1d77da(0x4ef),'PReps':_0x1d77da(0x397),'MQagA':'ā
\x20Parsed\x20locator:','GubEm':_0x1d77da(0x13e)};console[_0x1d77da(0x37a)]('š\x20Parsing\x20locators\x20output...'),console[_0x1d77da(0x37a)](_0x1caa52['PExWc'],_0x250292?.['length']||0x0);if(!_0x250292)return console[_0x1d77da(0x37a)](_0x1d77da(0x66e)),[];const _0x5ec288=_0x250292[_0x1d77da(0x19b)]('\x0a');for(const _0x57d188 of _0x5ec288){const _0x170307=_0x57d188[_0x1d77da(0x3ea)]();if(_0x170307[_0x1d77da(0x4ae)]('[')||_0x170307[_0x1d77da(0x4ae)]('{'))try{const _0x4db5af=JSON[_0x1d77da(0x288)](_0x170307);return console['log'](_0x1caa52[_0x1d77da(0x25f)],Array[_0x1d77da(0x616)](_0x4db5af)?_0x4db5af[_0x1d77da(0x484)]:_0x1caa52['ocbmW']),Array[_0x1d77da(0x616)](_0x4db5af)?_0x4db5af:[];}catch(_0x276311){_0x1caa52['wtaoM'](_0x1caa52[_0x1d77da(0x6c9)],_0x1d77da(0x706))?console['log'](_0x1caa52[_0x1d77da(0x6cd)],_0x276311[_0x1d77da(0xef)]):_0x312bb4=_0x1caa52['gzhyQ'](_0x552361,_0x1d77da(0xaa)+_0x151a7c+'\x20-l',{'encoding':_0x1caa52['hvhxq'],'timeout':0x7530});}}console[_0x1d77da(0x37a)](_0x1caa52['LwBdf']);const _0x2a7634=[];console[_0x1d77da(0x37a)](_0x1caa52[_0x1d77da(0x19e)],_0x5ec288[_0x1d77da(0x484)]);for(const _0x5b9248 of _0x5ec288){if(_0x1caa52[_0x1d77da(0x163)]('rBhsV',_0x1d77da(0x154))){if(_0x5b9248[_0x1d77da(0x185)]('š')&&/^\s*\d+\./[_0x1d77da(0x657)](_0x5b9248))try{const _0x52b51b={},_0x1bac50=_0x5b9248[_0x1d77da(0x600)](/^\s*(\d+)\./);if(_0x1bac50)_0x52b51b[_0x1d77da(0x4c3)]=_0x1caa52['uErBa'](parseInt,_0x1bac50[0x1]);if(_0x5b9248[_0x1d77da(0x185)]('ā')){if(_0x1caa52[_0x1d77da(0x315)]===_0x1caa52[_0x1d77da(0x315)]){const _0x4d2b46=_0x5b9248[_0x1d77da(0x19b)]('ā')['map'](_0x5a5d83=>_0x5a5d83['trim']()),_0x4f07e0=_0x4d2b46[0x0][_0x1d77da(0x600)](/š\s+(.+)/);_0x4f07e0&&(_0x52b51b['name']=_0x4f07e0[0x1][_0x1d77da(0x3ea)](),_0x52b51b[_0x1d77da(0x666)]=_0x4f07e0[0x1][_0x1d77da(0x3ea)]());const _0x3fd070=_0x4d2b46[0x1]?_0x4d2b46[0x1][_0x1d77da(0x600)](/\[([^\]]+)\]/):null;if(_0x3fd070)_0x52b51b[_0x1d77da(0x2ba)]=_0x3fd070[0x1][_0x1d77da(0x3ea)]();for(let _0x5473b5=0x2;_0x1caa52[_0x1d77da(0x6c1)](_0x5473b5,_0x4d2b46['length']);_0x5473b5++){const _0x56e03b=_0x4d2b46[_0x5473b5];if(_0x56e03b['includes'](_0x1caa52['kUQav'])){if(_0x1caa52[_0x1d77da(0x1ab)]===_0x1d77da(0x69c)){const _0x5842b7=_0x591672[_0x1a015c];let _0x126996;if(_0x5842b7[_0x4b3bc4])_0x126996=_0x5842b7[_0x65ecae];else _0x5842b7[_0x1d77da(0x632)]&&(_0x126996=_0x5842b7[_0x1d77da(0x632)]);if(_0x126996)return _0x90bc8[_0x1d77da(0x37a)](_0x1d77da(0x6ca)+_0x2f1be8+_0x1d77da(0x100)+_0x126996+'\x22\x20('+_0x21869c+')'),'launch\x20'+_0x126996+_0x4d4a17;}else{const _0x59db3d=_0x56e03b[_0x1d77da(0x600)](/Label:([^\s]+)/);if(_0x59db3d)_0x52b51b[_0x1d77da(0x6bf)]=_0x59db3d[0x1];}}if(_0x56e03b[_0x1d77da(0x185)](_0x1caa52[_0x1d77da(0x574)])){if(_0x1caa52[_0x1d77da(0xcf)](_0x1d77da(0x6e2),_0x1caa52['kLzLf'])){_0x3dab0d[_0x1d77da(0x37a)](_0x1d77da(0x3f9)+_0x3121b2[_0x1d77da(0x484)]+_0x1d77da(0x2c2));if(_0x7c0283){_0x12b280[_0x1d77da(0x37a)](_0x1d77da(0x68c)+_0x38c82d+_0x1d77da(0x29d));const _0x1e430f=_0x1caa52[_0x1d77da(0x73c)](_0xe41a,_0x1caa52[_0x1d77da(0x4c9)]);_0x1caa52['qGMwl'](_0x1e430f,_0x5202f6)[_0x1d77da(0x4c8)](_0x3dc76b=>{const _0x170b59=_0x1d77da;_0x3e918b[_0x170b59(0x37a)]('\x0aš±\x20Please\x20open\x20'+_0x3acd6b+'\x20in\x20your\x20browser');});}const _0x5b5916={};_0x5b5916[_0x1d77da(0x3d1)]=_0x4f3b18,_0x5b5916[_0x1d77da(0x3d4)]=_0x53f76a,_0x1caa52[_0x1d77da(0x337)](_0x437c94,_0x5b5916);}else{const _0x1de1a9=_0x56e03b[_0x1d77da(0x600)](/Val:([^\s]+)/);if(_0x1de1a9)_0x52b51b[_0x1d77da(0x55d)]=_0x1de1a9[0x1];}}if(_0x56e03b[_0x1d77da(0x185)](_0x1caa52[_0x1d77da(0x433)])){const _0x706bb6=_0x56e03b[_0x1d77da(0x600)](/ID:([^\s]+)/);if(_0x706bb6)_0x52b51b[_0x1d77da(0x466)]=_0x706bb6[0x1];}if(_0x56e03b[_0x1d77da(0x185)]('@')){const _0x25ab64=_0x56e03b[_0x1d77da(0x600)](/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);if(_0x25ab64){if(_0x1caa52[_0x1d77da(0x743)](_0x1caa52['qmXbP'],_0x1caa52['qmXbP'])){_0x38aa13[_0x1d77da(0x618)](_0x1d77da(0x73e),_0x272b35);const _0x40e38e={};_0x40e38e[_0x1d77da(0x492)]=![],_0x40e38e[_0x1d77da(0x618)]=_0x199929[_0x1d77da(0xef)],_0x32a522['status'](0x1f4)[_0x1d77da(0x573)](_0x40e38e);}else{const _0x12ac82=_0x1caa52[_0x1d77da(0x76a)][_0x1d77da(0x19b)]('|');let _0x2b435d=0x0;while(!![]){switch(_0x12ac82[_0x2b435d++]){case'0':_0x52b51b[_0x1d77da(0x3ac)]='('+_0x52b51b['x']+','+_0x52b51b['y']+')\x20'+_0x52b51b[_0x1d77da(0x4d7)]+'x'+_0x52b51b[_0x1d77da(0x357)];continue;case'1':_0x52b51b[_0x1d77da(0x4d7)]=_0x1caa52['qGMwl'](parseInt,_0x25ab64[0x3]);continue;case'2':_0x52b51b['x']=_0x1caa52[_0x1d77da(0x71e)](parseInt,_0x25ab64[0x1]);continue;case'3':_0x52b51b['height']=parseInt(_0x25ab64[0x4]);continue;case'4':_0x52b51b['y']=_0x1caa52[_0x1d77da(0x73c)](parseInt,_0x25ab64[0x2]);continue;}break;}}}}if(_0x56e03b['includes'](_0x1d77da(0x397)))_0x52b51b[_0x1d77da(0x676)]=!![];if(_0x56e03b[_0x1d77da(0x185)](_0x1caa52[_0x1d77da(0x2fa)]))_0x52b51b[_0x1d77da(0x46e)]=!![];if(_0x56e03b[_0x1d77da(0x185)](_0x1caa52[_0x1d77da(0x5e1)]))_0x52b51b[_0x1d77da(0x5ca)]=!![];}}else{const _0xa4dbf5={'UOOEu':function(_0x574f71,_0x539858){const _0x1b620e=_0x1d77da;return zJjPzU[_0x1b620e(0x684)](_0x574f71,_0x539858);},'OsjNh':zJjPzU[_0x1d77da(0x1ac)]};_0x3384df[_0x37d62f][_0x1d77da(0x160)]=zJjPzU[_0x1d77da(0x6ce)],_0x5d6549[_0x1d77da(0x41b)]['forEach'](_0x40704b=>{const _0xf89082=_0x1d77da;if(_0xa4dbf5[_0xf89082(0x5c9)](_0x40704b['readyState'],_0x53da7c[_0xf89082(0x467)])){const _0x24feb5={};_0x24feb5[_0xf89082(0x2ba)]=_0xa4dbf5[_0xf89082(0x440)],_0x24feb5[_0xf89082(0x3d4)]=_0x1dc6aa,_0x40704b[_0xf89082(0x65f)](_0x35ee0c[_0xf89082(0x62d)](_0x24feb5));}});}}else{if(_0x1caa52[_0x1d77da(0x5c5)](_0x1caa52[_0x1d77da(0x507)],_0x1caa52['GpLqC'])){const _0x214b7d={};_0x214b7d[_0x1d77da(0x492)]=![],_0x214b7d[_0x1d77da(0x618)]=_0x367dda[_0x1d77da(0xef)],_0x53f248[_0x1d77da(0x160)](0x1f4)[_0x1d77da(0x573)](_0x214b7d);}else{const _0x1e9117=_0x5b9248[_0x1d77da(0x600)](/š\s+([^\[]+?)(?:\s*\[|\s*Label)/);_0x1e9117&&(_0x52b51b['name']=_0x1e9117[0x1][_0x1d77da(0x3ea)](),_0x52b51b[_0x1d77da(0x666)]=_0x1e9117[0x1][_0x1d77da(0x3ea)]());const _0x12cdc6=_0x5b9248[_0x1d77da(0x600)](/\[([^\]]+)\]/);if(_0x12cdc6)_0x52b51b[_0x1d77da(0x2ba)]=_0x12cdc6[0x1][_0x1d77da(0x3ea)]();const _0xf291cc=_0x5b9248['match'](/Label:([^\s]+?)(?:\s*Val:|\s*@|\s*ā)/);if(_0xf291cc)_0x52b51b[_0x1d77da(0x6bf)]=_0xf291cc[0x1][_0x1d77da(0x3ea)]();const _0x221e9d=_0x5b9248[_0x1d77da(0x600)](/Val:([^\s]+?)(?:\s*@|\s*ā)/);if(_0x221e9d)_0x52b51b[_0x1d77da(0x55d)]=_0x221e9d[0x1]['trim']();const _0x5a0c26=_0x5b9248[_0x1d77da(0x600)](/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);if(_0x5a0c26){if(_0x1caa52[_0x1d77da(0x435)]('dTphY',_0x1caa52[_0x1d77da(0x6a3)])){const _0x1b4cfd={};_0x1b4cfd['RoFbW']=function(_0x257ca7,_0x31ba42){return _0x257ca7!==_0x31ba42;};const _0xc61540=_0x1b4cfd,_0x52bb53=_0x38cff7[_0x1d77da(0x19b)]('\x0a')[_0x1d77da(0x5a2)](_0x4c7dba=>{const _0x5f08d1=_0x1d77da,[_0x6be037]=_0x4c7dba[_0x5f08d1(0x19b)](':');return _0x4c7dba[_0x5f08d1(0x3ea)]()&&_0xc61540[_0x5f08d1(0xf1)](_0x6be037,_0x40d60c);});return _0x52bb53[_0x1d77da(0x43e)](_0x202236+':'+_0x208852),_0x2696e3[_0x1d77da(0x4b5)](_0x418b24,_0x52bb53[_0x1d77da(0x4a3)]('\x0a')+'\x0a');}else{const _0x1fbcb0=_0x1caa52[_0x1d77da(0x769)][_0x1d77da(0x19b)]('|');let _0x5a6dba=0x0;while(!![]){switch(_0x1fbcb0[_0x5a6dba++]){case'0':_0x52b51b['x']=_0x1caa52[_0x1d77da(0x337)](parseInt,_0x5a0c26[0x1]);continue;case'1':_0x52b51b[_0x1d77da(0x4d7)]=parseInt(_0x5a0c26[0x3]);continue;case'2':_0x52b51b['y']=parseInt(_0x5a0c26[0x2]);continue;case'3':_0x52b51b['height']=_0x1caa52[_0x1d77da(0x744)](parseInt,_0x5a0c26[0x4]);continue;case'4':_0x52b51b[_0x1d77da(0x3ac)]='('+_0x52b51b['x']+','+_0x52b51b['y']+')\x20'+_0x52b51b[_0x1d77da(0x4d7)]+'x'+_0x52b51b[_0x1d77da(0x357)];continue;}break;}}}const _0xcc3186=_0x5b9248[_0x1d77da(0x600)](/ID:([^\s]+)/);if(_0xcc3186)_0x52b51b['resourceId']=_0xcc3186[0x1]['trim']();_0x52b51b['visible']=_0x5b9248['includes'](_0x1caa52['PReps']),_0x52b51b['enabled']=_0x5b9248[_0x1d77da(0x185)](_0x1caa52[_0x1d77da(0x2fa)]);}}(_0x52b51b[_0x1d77da(0x192)]||_0x52b51b['label']||_0x52b51b[_0x1d77da(0x666)])&&(console[_0x1d77da(0x37a)](_0x1caa52[_0x1d77da(0x3e0)],_0x52b51b),_0x2a7634['push'](_0x52b51b));}catch(_0x59e874){console[_0x1d77da(0x618)](_0x1caa52[_0x1d77da(0x729)],_0x5b9248,_0x59e874);}}else{const _0x38889c={};_0x38889c[_0x1d77da(0x4c0)]=_0x1d77da(0xb4),_0x38889c['timeout']=0x2710;const _0x4b1506=_0x5556ea(_0x1d77da(0xaa)+_0x36a40a+_0x1d77da(0x52c)+_0x4e2fff+'\x22',_0x38889c),_0x364891=_0x4b1506[_0x1d77da(0x19b)](',')[_0x1d77da(0x12b)](_0x3c8ae3=>_0x3c8ae3['trim']()[_0x1d77da(0x203)](/"/g,''));_0x1caa52[_0x1d77da(0x429)](_0x364891[_0x1d77da(0x484)],0x3)?(_0xf47ebd[_0x1d77da(0x656)]=_0x364891[0x0],_0x15ef93[_0x1d77da(0x733)]=_0x364891[0x1],_0x520cc0[_0x1d77da(0x192)]=_0x364891[0x2]):(_0x23f9ae[_0x1d77da(0x656)]=_0x190453,_0x41075a[_0x1d77da(0x192)]=_0x44322f,_0xd302a1[_0x1d77da(0x733)]=_0x1caa52[_0x1d77da(0xb9)]);}}return console[_0x1d77da(0x37a)](_0x1d77da(0x498)+_0x2a7634[_0x1d77da(0x484)]),_0x2a7634;}wss['on']('connection',_0x15e7b1=>{const _0x412500=_0x50607,_0x5da357={'qhNcN':'command_complete','GImzt':function(_0x24db27,_0x501a70){return _0x24db27===_0x501a70;},'LcZAH':_0x412500(0xf6),'DpvDs':function(_0x1d7fd9,_0x3cc718,_0x5db7f9,_0x27573e,_0x6e72a5){return _0x1d7fd9(_0x3cc718,_0x5db7f9,_0x27573e,_0x6e72a5);},'liLPO':_0x412500(0x5c8),'rgNnL':_0x412500(0x5ff),'FBVCw':'CFBundleIdentifier','wVmjH':function(_0x1b9be2,_0x4486a8){return _0x1b9be2!==_0x4486a8;},'RfYCQ':_0x412500(0x253),'AvQEH':_0x412500(0x314),'xWaqZ':function(_0x36c917,_0x333c35){return _0x36c917!==_0x333c35;},'ynQmO':_0x412500(0x423),'caKjQ':_0x412500(0x732),'EHoKJ':_0x412500(0x4e2),'gEfLi':function(_0x248b42,_0x3d6cc7,_0x2608a5,_0x5ab226){return _0x248b42(_0x3d6cc7,_0x2608a5,_0x5ab226);},'CwTWl':_0x412500(0x6d6),'auOUx':'vNbAu','sCDmd':function(_0x3b8ddf,_0x1a8038,_0x3cff12,_0x411612){return _0x3b8ddf(_0x1a8038,_0x3cff12,_0x411612);},'Jtmsg':_0x412500(0xe3),'qdimL':_0x412500(0x4b9),'xRwyF':'recording_stopped','vNWYm':_0x412500(0x3be),'NthXR':_0x412500(0x653),'gzZJR':_0x412500(0x32a),'GwVmp':_0x412500(0x66f),'OYdPh':_0x412500(0x246),'joNPj':_0x412500(0x3ad),'DwxQG':'ai_providers','tuHgA':_0x412500(0xbf),'GevDN':_0x412500(0x1e8),'NsATR':function(_0x38c21f,_0x22b8cb){return _0x38c21f!==_0x22b8cb;},'kGvJv':_0x412500(0x61a),'tkFya':_0x412500(0x295),'oTPhI':_0x412500(0x618),'FCBuU':_0x412500(0x251),'ujzNP':_0x412500(0x338),'odLkG':_0x412500(0x453),'lpPDx':_0x412500(0x3fe),'yIPgd':'close'};console[_0x412500(0x37a)](_0x5da357['lpPDx']),_0x15e7b1['on'](_0x412500(0xef),async _0x4cbb81=>{const _0x216816=_0x412500,_0x3b878d={'jgeTL':_0x5da357[_0x216816(0x62a)],'uqXTa':_0x5da357[_0x216816(0x62c)],'meeWJ':_0x216816(0x5fa),'hAkos':function(_0x419a58,_0x217370){return _0x5da357['wVmjH'](_0x419a58,_0x217370);},'OlMEX':_0x216816(0x1c6),'EBXEH':_0x5da357[_0x216816(0x50e)],'KlfXr':_0x5da357['AvQEH'],'ENPdp':'TprIC','dAAAW':_0x216816(0x4fb),'yxVxM':_0x216816(0x412)};if(_0x5da357[_0x216816(0x1f6)]('yQvvB',_0x5da357[_0x216816(0x36c)])){_0x50c2a5[_0x216816(0x618)](_0x216816(0x496)+_0x3bcadf+':',_0x546bdc);throw _0xfc1019;}else try{if(_0x5da357['wVmjH'](_0x5da357[_0x216816(0x527)],_0x5da357[_0x216816(0x527)])){const _0x2d5310=_0x5aede7[_0x216816(0x3ea)]();return _0x2d5310&&!_0x2d5310['startsWith'](_0x3b878d['jgeTL'])&&!_0x2d5310['startsWith'](_0x3b878d['uqXTa']);}else{const _0x4d307c=JSON[_0x216816(0x288)](_0x4cbb81);switch(_0x4d307c[_0x216816(0x2ba)]){case _0x5da357[_0x216816(0x621)]:const {devices:_0x23ba9b,command:_0x1138ac,useAI:_0x34ebb5,aiProvider:_0x39e9a7}=_0x4d307c;console[_0x216816(0x37a)]('\x0a'+'*'['repeat'](0x3c)),console['log'](_0x216816(0x311)),console[_0x216816(0x37a)]('Devices\x20received:\x20['+_0x23ba9b[_0x216816(0x4a3)](',\x20')+']'),console[_0x216816(0x37a)](_0x216816(0x668)+_0x1138ac+'\x22'),console['log'](_0x216816(0x11f)+_0x34ebb5);if(_0x39e9a7)console['log'](_0x216816(0x3d6)+_0x39e9a7);console[_0x216816(0x37a)]('*'['repeat'](0x3c)+'\x0a');let _0x56b1c5=_0x1138ac;if(_0x34ebb5)try{_0x56b1c5=await _0x5da357['gEfLi'](convertNaturalLanguageToCommand,_0x1138ac,_0x23ba9b,_0x39e9a7),console[_0x216816(0x37a)](_0x216816(0x307)+_0x56b1c5);const _0x2dd3fe={};_0x2dd3fe[_0x216816(0x2ba)]=_0x5da357['CwTWl'],_0x2dd3fe['original']=_0x1138ac,_0x2dd3fe['converted']=_0x56b1c5,_0x2dd3fe['provider']=_0x39e9a7||aiManager[_0x216816(0x44f)],_0x15e7b1[_0x216816(0x65f)](JSON[_0x216816(0x62d)](_0x2dd3fe));}catch(_0x246f87){console['error']('ā\x20AI\x20conversion\x20failed:\x20'+_0x246f87[_0x216816(0xef)]);const _0x3cd080={};_0x3cd080[_0x216816(0x2ba)]=_0x216816(0x5b2),_0x3cd080[_0x216816(0x618)]=_0x246f87[_0x216816(0xef)],_0x3cd080[_0x216816(0x326)]=_0x1138ac,_0x15e7b1[_0x216816(0x65f)](JSON[_0x216816(0x62d)](_0x3cd080));return;}else{}const _0xd49494=_0x56b1c5['includes']('\x0a');_0xd49494?_0x5da357[_0x216816(0x5eb)]===_0x5da357[_0x216816(0x5eb)]?executeCommandsSequentially(_0x23ba9b,_0x56b1c5,_0x15e7b1)[_0x216816(0x4a9)](_0x477de7=>{const _0x241482=_0x216816;console[_0x241482(0x37a)](_0x241482(0x12c));const _0x452939={};_0x452939[_0x241482(0x2ba)]=_0x5da357['qhNcN'],_0x452939[_0x241482(0x31c)]=_0x477de7,_0x15e7b1[_0x241482(0x65f)](JSON[_0x241482(0x62d)](_0x452939));})[_0x216816(0x4c8)](_0xea0f9b=>{const _0x3a011c=_0x216816;if(_0x3b878d[_0x3a011c(0x31f)](_0x3b878d[_0x3a011c(0x4b3)],_0x3b878d[_0x3a011c(0x4c7)])){console[_0x3a011c(0x618)](_0x3a011c(0x585)+_0xea0f9b[_0x3a011c(0xef)]);const _0x21105b={};_0x21105b[_0x3a011c(0x2ba)]=_0x3a011c(0x31a),_0x21105b[_0x3a011c(0x618)]=_0xea0f9b[_0x3a011c(0xef)],_0x15e7b1[_0x3a011c(0x65f)](JSON[_0x3a011c(0x62d)](_0x21105b));}else _0x13cf28[_0x1965f5][_0x3a011c(0x160)]=PKvZML[_0x3a011c(0x1f1)];}):_0x10f7cf[_0x216816(0x37a)](_0x216816(0x1ad)+_0x1acfa9[_0x216816(0x75c)]):_0x5da357['sCDmd'](executeCommand,_0x23ba9b,_0x56b1c5,_0x15e7b1)[_0x216816(0x4a9)](_0x15eecd=>{const _0x5ba514=_0x216816,_0x5dc5b4={'XMWcf':function(_0x4ce757,_0x277aad){return _0x4ce757(_0x277aad);},'XYdOg':function(_0x197c0c,_0x3ac8d5){return _0x197c0c(_0x3ac8d5);}};isRecording&&(_0x5da357[_0x5ba514(0x2db)]('RGgUc',_0x5da357[_0x5ba514(0x3f3)])?(Brcfwi['XMWcf'](_0x5f36e6,'adb\x20-s\x20'+_0x51154e+_0x5ba514(0x617)),Brcfwi[_0x5ba514(0xf3)](_0x1db9f1,_0x5ba514(0x358)+_0x40d4a7+_0x5ba514(0x262)),_0x580838[_0x5ba514(0x37a)]('ā
\x20UIAutomator2\x20server\x20stopped\x20on\x20'+_0x3ce019)):_0x5da357[_0x5ba514(0x30f)](recordCommand,_0x23ba9b,_0x1138ac,_0x34ebb5,_0x56b1c5));const _0x50a00d={};_0x50a00d[_0x5ba514(0x2ba)]=_0x5da357[_0x5ba514(0x140)],_0x50a00d[_0x5ba514(0x31c)]=_0x15eecd,_0x15e7b1[_0x5ba514(0x65f)](JSON[_0x5ba514(0x62d)](_0x50a00d));})[_0x216816(0x4c8)](_0x75793d=>{const _0x22946b=_0x216816;console[_0x22946b(0x618)]('executeCommand\x20failed:\x20'+_0x75793d[_0x22946b(0xef)]);const _0x3f55e8={};_0x3f55e8['type']='command_error',_0x3f55e8[_0x22946b(0x618)]=_0x75793d['message'],_0x15e7b1[_0x22946b(0x65f)](JSON[_0x22946b(0x62d)](_0x3f55e8));});break;case _0x216816(0x2c9):const _0x46a208=await startRecording(_0x4d307c['name'],_0x4d307c[_0x216816(0x3d4)]),_0x102cd6={'type':_0x5da357[_0x216816(0x672)],..._0x46a208};_0x15e7b1[_0x216816(0x65f)](JSON[_0x216816(0x62d)](_0x102cd6));break;case _0x5da357['qdimL']:const _0xd9912a=await stopRecording(),_0x247ec6={'type':_0x5da357['xRwyF'],..._0xd9912a};_0x15e7b1[_0x216816(0x65f)](JSON['stringify'](_0x247ec6));break;case _0x5da357[_0x216816(0x3a3)]:const {filename:_0x4c68d0,targetDevices:_0x3989d3}=_0x4d307c,_0x3d4548={};_0x3d4548[_0x216816(0x2ba)]=_0x5da357[_0x216816(0x627)],_0x3d4548[_0x216816(0x49b)]='\x0aš¬\x20Starting\x20replay:\x20'+_0x4c68d0+'\x0a\x0a',_0x3d4548[_0x216816(0x3d4)]=_0x3989d3,_0x15e7b1[_0x216816(0x65f)](JSON['stringify'](_0x3d4548)),replayRecording(_0x4c68d0,_0x3989d3,_0x15e7b1)[_0x216816(0x4a9)](_0x2d3fea=>{const _0x3cfb3b=_0x216816;if(_0x3b878d['ENPdp']!==_0x3b878d[_0x3cfb3b(0x69b)]){const _0x1ec0f8={};return _0x1ec0f8[_0x3cfb3b(0x492)]=![],_0x1ec0f8[_0x3cfb3b(0x618)]=PKvZML[_0x3cfb3b(0x1b3)],_0x177995[_0x3cfb3b(0x160)](0x190)[_0x3cfb3b(0x573)](_0x1ec0f8);}else{const _0x4e1e9a={'type':_0x3b878d[_0x3cfb3b(0x6d1)],..._0x2d3fea};_0x15e7b1[_0x3cfb3b(0x65f)](JSON[_0x3cfb3b(0x62d)](_0x4e1e9a));}})[_0x216816(0x4c8)](_0x257277=>{const _0x5a77eb=_0x216816,_0x45d4df={};_0x45d4df[_0x5a77eb(0x2ba)]=_0x5da357[_0x5a77eb(0x1f8)],_0x45d4df[_0x5a77eb(0x618)]=_0x257277[_0x5a77eb(0xef)],_0x15e7b1[_0x5a77eb(0x65f)](JSON['stringify'](_0x45d4df));});break;case _0x5da357[_0x216816(0x709)]:if(isReplaying){replayAborted=!![];const _0x1ec9ef={};_0x1ec9ef[_0x216816(0x2ba)]=_0x216816(0x653),_0x1ec9ef[_0x216816(0x49b)]=_0x5da357[_0x216816(0x457)],_0x15e7b1[_0x216816(0x65f)](JSON[_0x216816(0x62d)](_0x1ec9ef));}break;case _0x216816(0xe5):const _0x216bd0=await discoverDevices(),_0x2ce07f={};_0x2ce07f[_0x216816(0x2ba)]=_0x5da357['OYdPh'],_0x2ce07f[_0x216816(0x3d4)]=_0x216bd0,_0x15e7b1[_0x216816(0x65f)](JSON[_0x216816(0x62d)](_0x2ce07f));break;case _0x5da357[_0x216816(0x170)]:_0x15e7b1[_0x216816(0x65f)](JSON['stringify']({'type':_0x5da357['DwxQG'],'providers':aiManager['getAvailableProviders'](),'current':aiManager[_0x216816(0x44f)]}));break;case _0x5da357['tuHgA']:const _0x12f7ca=aiManager[_0x216816(0x16e)](_0x4d307c[_0x216816(0x44f)]),_0x3cab11={};_0x3cab11[_0x216816(0x2ba)]=_0x5da357[_0x216816(0xbd)],_0x3cab11[_0x216816(0x492)]=_0x12f7ca,_0x3cab11[_0x216816(0x44f)]=_0x4d307c[_0x216816(0x44f)],_0x15e7b1[_0x216816(0x65f)](JSON[_0x216816(0x62d)](_0x3cab11));break;}}}catch(_0x388644){if(_0x5da357['NsATR'](_0x5da357[_0x216816(0x64a)],_0x5da357[_0x216816(0x5ac)])){const _0x49c72f={};_0x49c72f[_0x216816(0x2ba)]=_0x5da357[_0x216816(0xe4)],_0x49c72f[_0x216816(0xef)]=_0x388644['message'],_0x15e7b1['send'](JSON[_0x216816(0x62d)](_0x49c72f));}else _0x202d5f=PKvZML[_0x216816(0x168)];}}),_0x15e7b1['on'](_0x5da357[_0x412500(0x3fc)],()=>{const _0x48d3cc=_0x412500;if(_0x5da357[_0x48d3cc(0x2db)](_0x48d3cc(0x477),_0x5da357[_0x48d3cc(0x53a)])){const _0x21af37={};_0x21af37['success']=![],_0x21af37[_0x48d3cc(0x618)]=_0x5da357[_0x48d3cc(0x465)],_0x457bc['status'](0x194)['json'](_0x21af37);}else console['log'](_0x5da357[_0x48d3cc(0x40c)]);}),discoverDevices()[_0x412500(0x4a9)](_0x3b8413=>{const _0x12d028=_0x412500,_0x911ee3={};_0x911ee3['type']=_0x5da357['OYdPh'],_0x911ee3[_0x12d028(0x3d4)]=_0x3b8413,_0x15e7b1[_0x12d028(0x65f)](JSON['stringify'](_0x911ee3));});}),app[_0x50607(0x633)](_0x50607(0x2de),async(_0x9503cb,_0x9d2f0a)=>{const _0xfce30f=_0x50607,_0x1a2fec={'SrZGC':_0xfce30f(0x460),'VSEsh':function(_0x51edfa,_0x578587){return _0x51edfa(_0x578587);},'uKTRG':function(_0x10ce04,_0x1d16f3){return _0x10ce04(_0x1d16f3);},'FoewE':function(_0xe7e940,_0xd82979){return _0xe7e940!==_0xd82979;},'MqnWp':_0xfce30f(0xcc),'pOrot':function(_0x2355b9,_0x11d034){return _0x2355b9===_0x11d034;},'ZRjrY':_0xfce30f(0x48d),'PGrfl':'kxTFe','UUpiV':'Device\x20not\x20found\x20or\x20not\x20connected','ZBeLI':_0xfce30f(0x6fe)},{device:_0x10ff01}=_0x9503cb['body'];if(!_0x10ff01){if(_0x1a2fec[_0xfce30f(0x670)](_0xfce30f(0xcc),_0x1a2fec[_0xfce30f(0x366)])){const _0x56e304=_0x1a2fec[_0xfce30f(0x27d)][_0xfce30f(0x19b)]('|');let _0x13c104=0x0;while(!![]){switch(_0x56e304[_0x13c104++]){case'0':_0x320332['y']=NnFQgf[_0xfce30f(0x4d4)](_0x12661d,_0x42ed0f[0x2]);continue;case'1':_0x5a2a0b[_0xfce30f(0x357)]=NnFQgf['uKTRG'](_0x2070e7,_0xb99527[0x4]);continue;case'2':_0x425f9b[_0xfce30f(0x3ac)]='('+_0xe22d1['x']+','+_0x16ead1['y']+')\x20'+_0x17397e[_0xfce30f(0x4d7)]+'x'+_0x342f1e[_0xfce30f(0x357)];continue;case'3':_0x16222e['width']=NnFQgf[_0xfce30f(0x46f)](_0x456ec6,_0xeb4eb4[0x3]);continue;case'4':_0x3de8d3['x']=NnFQgf[_0xfce30f(0x4d4)](_0x196cd7,_0x2576ac[0x1]);continue;}break;}}else{const _0x3add28={};return _0x3add28[_0xfce30f(0x492)]=![],_0x3add28[_0xfce30f(0x618)]=_0xfce30f(0x4b8),_0x9d2f0a[_0xfce30f(0x160)](0x190)[_0xfce30f(0x573)](_0x3add28);}}try{if(_0x1a2fec[_0xfce30f(0x6af)](_0x1a2fec[_0xfce30f(0x767)],_0x1a2fec['PGrfl']))_0x214b69[_0xfce30f(0x618)](_0xfce30f(0x511)+_0x3cbeb2+':',_0x5b3760);else{console[_0xfce30f(0x37a)](_0xfce30f(0x64b)+_0x10ff01+_0xfce30f(0x29d));const _0x2f280b=connectedDevices[_0xfce30f(0x6f7)](_0x17421e=>_0x17421e['name']===_0x10ff01);if(!_0x2f280b){const _0x4965f7={};return _0x4965f7['success']=![],_0x4965f7['error']=_0x1a2fec[_0xfce30f(0x66c)],_0x9d2f0a['json'](_0x4965f7);}const _0x59c565=await installUIAutomator2(_0x2f280b['udid'],_0x10ff01);_0x9d2f0a[_0xfce30f(0x573)](_0x59c565);}}catch(_0x5ada2d){console[_0xfce30f(0x618)](_0x1a2fec[_0xfce30f(0x406)],_0x5ada2d[_0xfce30f(0xef)]);const _0x3b7c90={};_0x3b7c90['success']=![],_0x3b7c90['error']=_0x5ada2d[_0xfce30f(0xef)],_0x3b7c90[_0xfce30f(0x750)]=_0xfce30f(0x118),_0x9d2f0a[_0xfce30f(0x573)](_0x3b7c90);}}),app[_0x50607(0x633)](_0x50607(0x43a),async(_0x36bd8f,_0x5f53a9)=>{const _0x1f8d1b=_0x50607,_0x5201cc={'GVXzH':function(_0x491b36,_0x5adb43,_0xbf2c8f){return _0x491b36(_0x5adb43,_0xbf2c8f);}};try{const {name:_0x57f708,devices:_0x4f156b}=_0x36bd8f[_0x1f8d1b(0x6a0)],_0x3e8a1c=await _0x5201cc['GVXzH'](startRecording,_0x57f708,_0x4f156b);_0x5f53a9[_0x1f8d1b(0x573)](_0x3e8a1c);}catch(_0x1a2a14){const _0x84f3d8={};_0x84f3d8[_0x1f8d1b(0x492)]=![],_0x84f3d8['error']=_0x1a2a14['message'],_0x5f53a9[_0x1f8d1b(0x160)](0x1f4)['json'](_0x84f3d8);}}),app[_0x50607(0x633)](_0x50607(0x594),async(_0xe20441,_0x918ceb)=>{const _0x2c8d5a=_0x50607;try{const _0x290aeb=await stopRecording();_0x918ceb[_0x2c8d5a(0x573)](_0x290aeb);}catch(_0x5ae168){const _0x423418={};_0x423418[_0x2c8d5a(0x492)]=![],_0x423418[_0x2c8d5a(0x618)]=_0x5ae168[_0x2c8d5a(0xef)],_0x918ceb['status'](0x1f4)[_0x2c8d5a(0x573)](_0x423418);}}),app[_0x50607(0x529)]('/api/recording/status',(_0x53bdfe,_0x3cd025)=>{const _0x2a4843=_0x50607,_0x3f58f9={};_0x3f58f9[_0x2a4843(0x38d)]=isRecording,_0x3f58f9[_0x2a4843(0x1be)]=currentRecording,_0x3cd025[_0x2a4843(0x573)](_0x3f58f9);}),app['get'](_0x50607(0x39b),async(_0x23e63e,_0x4c08c7)=>{const _0xe23000=_0x50607,_0x15b914={};_0x15b914[_0xe23000(0x35c)]=function(_0x2f5573,_0x12c9cc){return _0x2f5573!==_0x12c9cc;},_0x15b914[_0xe23000(0x1eb)]=_0xe23000(0x278);const _0x36ddae=_0x15b914;try{const _0x1db911=await listRecordings(),_0x27b54c={};_0x27b54c[_0xe23000(0x492)]=!![],_0x27b54c[_0xe23000(0x213)]=_0x1db911,_0x4c08c7[_0xe23000(0x573)](_0x27b54c);}catch(_0x3022a0){if(_0x36ddae['Eggzs'](_0x36ddae['niVKi'],_0x36ddae[_0xe23000(0x1eb)]))_0x5441c1+=_0xe01c42[_0xe23000(0x2ca)]();else{const _0x1dc4b3={};_0x1dc4b3[_0xe23000(0x492)]=![],_0x1dc4b3[_0xe23000(0x618)]=_0x3022a0[_0xe23000(0xef)],_0x4c08c7[_0xe23000(0x160)](0x1f4)[_0xe23000(0x573)](_0x1dc4b3);}}}),app[_0x50607(0x529)](_0x50607(0x27c),async(_0x11f26a,_0xea4580)=>{const _0x5789c7=_0x50607,_0x3e49d9={'FFOXM':function(_0x3f08aa,_0x48c390){return _0x3f08aa(_0x48c390);}};try{const _0x46869c=await _0x3e49d9[_0x5789c7(0x699)](loadRecording,_0x11f26a[_0x5789c7(0x528)][_0x5789c7(0x4e5)]),_0x28de67={};_0x28de67[_0x5789c7(0x492)]=!![],_0x28de67[_0x5789c7(0x1be)]=_0x46869c,_0xea4580['json'](_0x28de67);}catch(_0x575c3b){const _0x5b1237={};_0x5b1237['success']=![],_0x5b1237[_0x5789c7(0x618)]=_0x5789c7(0x1fc),_0xea4580['status'](0x194)[_0x5789c7(0x573)](_0x5b1237);}}),app[_0x50607(0x6ee)]('/api/recordings/:filename',async(_0x562d3c,_0x2fe247)=>{const _0x28b30f=_0x50607,_0x62386b={'yOfyV':function(_0x19c454,_0x2a5278){return _0x19c454(_0x2a5278);}};try{await _0x62386b[_0x28b30f(0x41e)](deleteRecording,_0x562d3c['params']['filename']);const _0x1bacb1={};_0x1bacb1[_0x28b30f(0x492)]=!![],_0x2fe247['json'](_0x1bacb1);}catch(_0x5a5075){const _0x52ecc3={};_0x52ecc3[_0x28b30f(0x492)]=![],_0x52ecc3[_0x28b30f(0x618)]=_0x5a5075['message'],_0x2fe247['status'](0x1f4)[_0x28b30f(0x573)](_0x52ecc3);}}),app['put'](_0x50607(0x27c),async(_0x27f40a,_0x5c453d)=>{const _0x5f3f62=_0x50607,_0x150d7e={};_0x150d7e[_0x5f3f62(0x36e)]=function(_0x30c880,_0x3ea74d){return _0x30c880===_0x3ea74d;},_0x150d7e['SnNXR']=function(_0x397a67,_0x32fec7){return _0x397a67!==_0x32fec7;},_0x150d7e[_0x5f3f62(0x275)]=_0x5f3f62(0x5c2),_0x150d7e[_0x5f3f62(0x54a)]='bZVaC';const _0x564db9=_0x150d7e;try{if(_0x564db9['SnNXR'](_0x564db9[_0x5f3f62(0x275)],_0x564db9[_0x5f3f62(0x54a)])){const {filename:_0x4c9de2}=_0x27f40a[_0x5f3f62(0x528)],_0x2b90b1=_0x27f40a[_0x5f3f62(0x6a0)],_0x4c198f=path[_0x5f3f62(0x4a3)](RECORDINGS_DIR,_0x4c9de2);await fs[_0x5f3f62(0x4b5)](_0x4c198f,JSON[_0x5f3f62(0x62d)](_0x2b90b1,null,0x2));const _0x35fe40={};_0x35fe40[_0x5f3f62(0x492)]=!![],_0x35fe40['recording']=_0x2b90b1,_0x5c453d['json'](_0x35fe40);}else{const _0x241034=_0xdbb906[_0x5f3f62(0x19b)]('.');if(XaYpav[_0x5f3f62(0x36e)](_0x241034['length'],0x2)){const [_0xa1e317,_0x5d580a]=_0x241034;if(!_0x2bedb3[_0xa1e317])_0x3236e8[_0xa1e317]={};_0x159e33[_0xa1e317][_0x5d580a]=_0x2ed1c8;}else{if(!_0x5a05a2[_0x4faf31])_0x1cf831[_0x4d30e9]={};_0x1c217b[_0x24e271][_0x5f3f62(0x632)]=_0x1449ba;}}}catch(_0x28b0ad){const _0x253dec={};_0x253dec[_0x5f3f62(0x492)]=![],_0x253dec[_0x5f3f62(0x618)]=_0x28b0ad[_0x5f3f62(0xef)],_0x5c453d['status'](0x1f4)['json'](_0x253dec);}}),app[_0x50607(0x633)](_0x50607(0x63f),async(_0x1bd1c6,_0x1aa469)=>{const _0x43377a=_0x50607,_0x7fd9eb={'ssnZv':function(_0xda20b6,_0x311c18){return _0xda20b6(_0x311c18);},'ZtVDd':function(_0x271bbb,_0x29eaab){return _0x271bbb!==_0x29eaab;},'zgAym':'lNiAc','MrIxz':function(_0x852c9e,_0x37a6ea){return _0x852c9e||_0x37a6ea;},'oSrIG':_0x43377a(0x660),'BNFMw':function(_0x2182fe,_0x2f5c2b){return _0x2182fe||_0x2f5c2b;},'tejJV':_0x43377a(0x1ba)};try{if(_0x7fd9eb['ZtVDd'](_0x43377a(0x481),_0x7fd9eb[_0x43377a(0x334)])){const {name:_0x494112,commands:_0x3be03a,date:_0x2c0d0b,type:_0x4bcd2e}=_0x1bd1c6[_0x43377a(0x6a0)];if(_0x7fd9eb[_0x43377a(0x1fe)](!_0x494112,!_0x3be03a)){const _0x14d417={};return _0x14d417[_0x43377a(0x492)]=![],_0x14d417[_0x43377a(0x618)]=_0x7fd9eb['oSrIG'],_0x1aa469[_0x43377a(0x160)](0x190)[_0x43377a(0x573)](_0x14d417);}const _0x12c297=_0x494112[_0x43377a(0x203)](/[^a-z0-9_-]/gi,'_'),_0x533208=_0x12c297+'_'+Date[_0x43377a(0xbe)]()+_0x43377a(0x721),_0x12077d=path[_0x43377a(0x4a3)](RECORDINGS_DIR,_0x533208),_0x5b8e95={'name':_0x494112,'commands':_0x3be03a,'date':_0x2c0d0b||new Date()['toISOString'](),'type':_0x7fd9eb['BNFMw'](_0x4bcd2e,_0x7fd9eb[_0x43377a(0x5cc)])};await fs[_0x43377a(0x4b5)](_0x12077d,JSON[_0x43377a(0x62d)](_0x5b8e95,null,0x2));const _0x1dd84b={};_0x1dd84b[_0x43377a(0x492)]=!![],_0x1dd84b[_0x43377a(0x4e5)]=_0x533208,_0x1dd84b[_0x43377a(0x1be)]=_0x5b8e95,_0x1aa469['json'](_0x1dd84b);}else{const _0x4c6422={};_0x4c6422[_0x43377a(0x492)]=![],_0x4c6422['error']=_0x4399e3||_0x46c573,_0x4c6422[_0x43377a(0x273)]=_0x2348dd['name'],LeWRMT[_0x43377a(0x369)](_0x1cec42,_0x4c6422);}}catch(_0x291654){console[_0x43377a(0x618)]('Error\x20saving\x20recording:',_0x291654);const _0x917828={};_0x917828[_0x43377a(0x492)]=![],_0x917828[_0x43377a(0x618)]=_0x291654[_0x43377a(0xef)],_0x1aa469[_0x43377a(0x160)](0x1f4)['json'](_0x917828);}}),app[_0x50607(0x633)](_0x50607(0x570),async(_0xbdd7d0,_0x2ad2f4)=>{const _0x26ed11=_0x50607,_0x4111b2={'ZJiNk':function(_0x3649fb,_0x3b9f32){return _0x3649fb(_0x3b9f32);},'xVCxl':_0x26ed11(0x3b0),'wpDJQ':function(_0x16b929,_0x22df6c){return _0x16b929!==_0x22df6c;},'NRIVy':_0x26ed11(0x6b1),'vrgYg':'Filename\x20required','xAxJs':function(_0x4f2d09,_0x32942f){return _0x4f2d09===_0x32942f;},'bATpI':function(_0x559d9e,_0x4c7358){return _0x559d9e!==_0x4c7358;},'Qygup':'azFWX','DihSF':_0x26ed11(0x34c),'LMhlY':_0x26ed11(0x489)};try{const {filename:_0xb7bb7a,devices:_0x8fce6}=_0xbdd7d0['body'];if(!_0xb7bb7a){if(_0x4111b2[_0x26ed11(0x629)](_0x4111b2[_0x26ed11(0x2d3)],_0x26ed11(0xe6))){const _0x25d0dd={};return _0x25d0dd[_0x26ed11(0x492)]=![],_0x25d0dd['error']=_0x4111b2[_0x26ed11(0x4f6)],_0x2ad2f4[_0x26ed11(0x160)](0x190)[_0x26ed11(0x573)](_0x25d0dd);}else{_0x2326b4['error']('ā\x20ADB\x20error:\x20'+_0x5599e9['message']);const _0x4b0dca={};_0x4b0dca['success']=![],_0x4b0dca['message']=_0x26ed11(0x630),NgLngD['ZJiNk'](_0x5c7bf7,_0x4b0dca);}}if(!_0x8fce6||_0x4111b2[_0x26ed11(0x250)](_0x8fce6['length'],0x0)){if(_0x4111b2['bATpI'](_0x4111b2[_0x26ed11(0x69a)],_0x26ed11(0x292))){const _0x51960e={};return _0x51960e[_0x26ed11(0x492)]=![],_0x51960e[_0x26ed11(0x618)]=_0x26ed11(0x236),_0x2ad2f4[_0x26ed11(0x160)](0x190)[_0x26ed11(0x573)](_0x51960e);}else{_0x47b8b3[_0x26ed11(0x618)]('['+_0x4a216f+_0x26ed11(0x5ba)+_0x595c27[_0x26ed11(0xef)]);const _0x35ad0e={};_0x35ad0e[_0x26ed11(0x492)]=![],_0x35ad0e[_0x26ed11(0x618)]=_0x2d8492[_0x26ed11(0xef)],_0x35ad0e[_0x26ed11(0x273)]=_0x5186ef,_0x26ee78(_0x35ad0e);}}const _0x8bb808={};_0x8bb808[_0x26ed11(0x492)]=!![],_0x8bb808[_0x26ed11(0xef)]=_0x26ed11(0x76f),_0x2ad2f4[_0x26ed11(0x573)](_0x8bb808);}catch(_0x41b511){if(_0x4111b2[_0x26ed11(0x250)](_0x4111b2[_0x26ed11(0x162)],_0x4111b2[_0x26ed11(0x53c)]))({discoverAllDevices:_0x57c9df}=NgLngD[_0x26ed11(0x5d6)](_0x55eee8,NgLngD[_0x26ed11(0x5b8)]));else{const _0x24e6ab={};_0x24e6ab[_0x26ed11(0x492)]=![],_0x24e6ab[_0x26ed11(0x618)]=_0x41b511[_0x26ed11(0xef)],_0x2ad2f4['status'](0x1f4)['json'](_0x24e6ab);}}}),app[_0x50607(0x529)](_0x50607(0x3f4),async(_0xc5993c,_0x3c2917)=>{const _0x544118=_0x50607,_0x2a86f1={'vWjbp':function(_0x334df4,_0x411fac){return _0x334df4(_0x411fac);}};try{const _0x19938a={};_0x19938a[_0x544118(0x37f)]=!![],await fs[_0x544118(0x1d4)](SCREENSHOTS_DIR,_0x19938a);const _0x2c763e=await fs[_0x544118(0xcb)](SCREENSHOTS_DIR),_0x5914d1=_0x2c763e[_0x544118(0x5a2)](_0x473231=>_0x473231['endsWith'](_0x544118(0x39f)))['map'](_0x565dbb=>{const _0xb31bc1=_0x544118,_0x24f5a3=_0x2a86f1[_0xb31bc1(0x3f1)](require,'fs')['statSync'](path[_0xb31bc1(0x4a3)](SCREENSHOTS_DIR,_0x565dbb));return{'filename':_0x565dbb,'path':_0xb31bc1(0x349)+_0x565dbb,'size':_0x24f5a3[_0xb31bc1(0x117)],'timestamp':_0x24f5a3[_0xb31bc1(0x6ba)][_0xb31bc1(0x2a6)](),'created':_0x24f5a3['mtime']};})[_0x544118(0x488)]((_0xe0d78a,_0x25147b)=>_0x25147b[_0x544118(0x2a4)]-_0xe0d78a[_0x544118(0x2a4)]),_0x23c66a={};_0x23c66a[_0x544118(0x492)]=!![],_0x23c66a[_0x544118(0x29a)]=_0x5914d1,_0x3c2917[_0x544118(0x573)](_0x23c66a);}catch(_0x2e92bb){const _0x44abfa={};_0x44abfa[_0x544118(0x492)]=![],_0x44abfa[_0x544118(0x618)]=_0x2e92bb['message'],_0x3c2917[_0x544118(0x160)](0x1f4)[_0x544118(0x573)](_0x44abfa);}}),app[_0x50607(0x529)](_0x50607(0x17f),(_0x394418,_0x2c3b03)=>{const _0x86a26=_0x50607,_0x255b9d={};_0x255b9d['nSNYQ']=function(_0x1b3f5f,_0x5918a8){return _0x1b3f5f===_0x5918a8;},_0x255b9d[_0x86a26(0x4f8)]=_0x86a26(0x2c8),_0x255b9d[_0x86a26(0x36a)]=_0x86a26(0x251);const _0x49c04d=_0x255b9d,_0x2b3b62=path[_0x86a26(0x4a3)](SCREENSHOTS_DIR,_0x394418[_0x86a26(0x528)]['filename']);_0x2c3b03[_0x86a26(0x566)](_0x2b3b62,_0x1dca30=>{const _0x4ee48e=_0x86a26,_0x2c87f4={};_0x2c87f4[_0x4ee48e(0x135)]=_0x4ee48e(0x4d3);const _0x799877=_0x2c87f4;if(_0x1dca30){if(_0x49c04d[_0x4ee48e(0x173)](_0x49c04d[_0x4ee48e(0x4f8)],_0x4ee48e(0xd4))){const _0x1cae97={};_0x1cae97[_0x4ee48e(0x2ba)]=DHWszq[_0x4ee48e(0x135)],_0x1cae97[_0x4ee48e(0x273)]=_0x23ef27[_0x4ee48e(0x192)],_0x1cae97['data']=_0x47228a,_0x114b31[_0x4ee48e(0x65f)](_0x1998f7['stringify'](_0x1cae97));}else{const _0x51f620={};_0x51f620[_0x4ee48e(0x492)]=![],_0x51f620['error']=_0x49c04d[_0x4ee48e(0x36a)],_0x2c3b03['status'](0x194)[_0x4ee48e(0x573)](_0x51f620);}}});}),app[_0x50607(0x6ee)](_0x50607(0x17f),async(_0x3b3e58,_0x12cd8b)=>{const _0x2eb3a1=_0x50607,_0x34f97e={};_0x34f97e[_0x2eb3a1(0x645)]=_0x2eb3a1(0x69f),_0x34f97e[_0x2eb3a1(0x208)]=function(_0x5d6eee,_0x47b6ea){return _0x5d6eee!==_0x47b6ea;},_0x34f97e[_0x2eb3a1(0x387)]=_0x2eb3a1(0x2f2);const _0x1fa2cd=_0x34f97e;try{if(_0x1fa2cd[_0x2eb3a1(0x208)](_0x2eb3a1(0x2f2),_0x1fa2cd[_0x2eb3a1(0x387)]))return _0xad2ea[_0x2eb3a1(0x618)](giWxDd['BhWcI'],_0x5907d1),[];else{const _0x2eb0b2=path['join'](SCREENSHOTS_DIR,_0x3b3e58[_0x2eb3a1(0x528)]['filename']);await fs['unlink'](_0x2eb0b2);const _0x3b18fb={};_0x3b18fb[_0x2eb3a1(0x492)]=!![],_0x12cd8b[_0x2eb3a1(0x573)](_0x3b18fb);}}catch(_0x295a86){const _0x2e6194={};_0x2e6194[_0x2eb3a1(0x492)]=![],_0x2e6194[_0x2eb3a1(0x618)]=_0x295a86[_0x2eb3a1(0xef)],_0x12cd8b['status'](0x1f4)[_0x2eb3a1(0x573)](_0x2e6194);}}),app[_0x50607(0x633)](_0x50607(0x4e0),async(_0x3c5bdf,_0x4e8707)=>{const _0x436369=_0x50607,_0x2d3335={'WbQOz':'Device\x20name\x20required','xiACB':'CFBundleIdentifier','DsATq':function(_0x2ae66e,_0x3b62fa,_0xad8073){return _0x2ae66e(_0x3b62fa,_0xad8073);},'Cruyd':'ios','hucSg':_0x436369(0x3f7),'fOAgV':function(_0x52a0b6,_0x1d179c){return _0x52a0b6>=_0x1d179c;},'UMwqI':function(_0x3c928e,_0x54b892){return _0x3c928e===_0x54b892;},'WdTNV':'sQBCb','sXjdm':function(_0x1df76a,_0xe434ec,_0x2ba7ee,_0x6fff63,_0x5955c1){return _0x1df76a(_0xe434ec,_0x2ba7ee,_0x6fff63,_0x5955c1);},'UIXYL':_0x436369(0x47d),'LsGVE':_0x436369(0x342),'dbCST':function(_0x51c66b,_0x5af6f5){return _0x51c66b!==_0x5af6f5;},'YlPMX':_0x436369(0x418),'fcEpx':_0x436369(0x126),'Mptoi':function(_0x4a150d,_0x573861){return _0x4a150d===_0x573861;},'YdiMP':_0x436369(0xed),'DGSma':_0x436369(0x412),'UWKjZ':_0x436369(0x2a3),'NVppw':function(_0x1e0ebf,_0x3f9b79,_0x5181dc){return _0x1e0ebf(_0x3f9b79,_0x5181dc);},'eCuPG':'utf-8','SrtqE':_0x436369(0x6e8),'bOmfJ':function(_0x1bd1fb,_0x184e8b){return _0x1bd1fb(_0x184e8b);},'dggQm':function(_0x34af1b,_0x5b7bcb,_0x27f49b){return _0x34af1b(_0x5b7bcb,_0x27f49b);},'zertD':function(_0x4baf69,_0x1115c3){return _0x4baf69===_0x1115c3;},'JJnwQ':_0x436369(0x436),'YIWSH':_0x436369(0x730),'WRLdp':function(_0x1f4847,_0x473ed9){return _0x1f4847===_0x473ed9;},'MbbVm':_0x436369(0x378),'oCgbT':_0x436369(0x4e6)};try{if(_0x2d3335[_0x436369(0x37c)](_0x2d3335['YlPMX'],_0x2d3335[_0x436369(0x2d2)])){const {devices:_0x4b45b2}=_0x3c5bdf[_0x436369(0x6a0)];if(!_0x4b45b2||_0x2d3335['UMwqI'](_0x4b45b2[_0x436369(0x484)],0x0)){const _0x44f3ae={};return _0x44f3ae[_0x436369(0x492)]=![],_0x44f3ae[_0x436369(0x618)]='Device\x20selection\x20required',_0x4e8707[_0x436369(0x160)](0x190)['json'](_0x44f3ae);}const _0x1da79a=connectedDevices['filter'](_0x2f6245=>_0x4b45b2[_0x436369(0x185)](_0x2f6245['name'])||_0x4b45b2[_0x436369(0x185)](_0x2f6245[_0x436369(0x343)])||_0x4b45b2[_0x436369(0x185)](_0x2f6245[_0x436369(0x5cb)]));if(_0x2d3335[_0x436369(0x3bb)](_0x1da79a[_0x436369(0x484)],0x0)){const _0xa51e1d={};return _0xa51e1d[_0x436369(0x492)]=![],_0xa51e1d['error']=_0x2d3335[_0x436369(0x116)],_0x4e8707['status'](0x190)['json'](_0xa51e1d);}const _0x182c14={};for(const _0x11335d of _0x1da79a){try{let _0x1052ab=[];if(_0x2d3335['Mptoi'](_0x11335d[_0x436369(0x569)],_0x2d3335['DGSma'])){const {execSync:_0x1c883e}=require(_0x2d3335[_0x436369(0x221)]),_0x56ca18=_0x11335d['udid']||_0x11335d[_0x436369(0x5cb)],_0x21c68f=_0x2d3335[_0x436369(0x623)](_0x1c883e,_0x436369(0x358)+_0x56ca18+_0x436369(0x651),{'encoding':_0x2d3335[_0x436369(0x11b)]});_0x1052ab=_0x21c68f[_0x436369(0x19b)]('\x0a')[_0x436369(0x5a2)](_0x25b0f8=>_0x25b0f8['startsWith'](_0x436369(0xc5)))[_0x436369(0x12b)](_0x5f6c54=>_0x5f6c54[_0x436369(0x203)](_0x436369(0xc5),'')[_0x436369(0x3ea)]())[_0x436369(0x5a2)](_0x1201b7=>_0x1201b7)[_0x436369(0x488)]();}else{if(_0x11335d[_0x436369(0x569)]===_0x436369(0x102)){if(_0x2d3335[_0x436369(0x156)]!==_0x436369(0x390)){const {execSync:_0x3c6e9c}=_0x2d3335[_0x436369(0x51c)](require,_0x2d3335[_0x436369(0x221)]),_0x47622b=_0x11335d[_0x436369(0x343)];try{let _0xfdd8cc;try{if(_0x2d3335[_0x436369(0x1d6)](_0x436369(0x681),_0x436369(0x681))){const _0x1e3a07={};_0x1e3a07['encoding']=_0x2d3335[_0x436369(0x11b)],_0x1e3a07['timeout']=0x7530,_0xfdd8cc=_0x3c6e9c(_0x436369(0xaa)+_0x47622b+'\x20list\x20--user',_0x1e3a07);}else{const _0x5929c3={};return _0x5929c3[_0x436369(0x492)]=![],_0x5929c3['error']=CXEIka[_0x436369(0x13b)],_0x173421[_0x436369(0x160)](0x190)[_0x436369(0x573)](_0x5929c3);}}catch(_0x27d42b){_0xfdd8cc=_0x2d3335['dggQm'](_0x3c6e9c,_0x436369(0xaa)+_0x47622b+_0x436369(0x589),{'encoding':_0x2d3335[_0x436369(0x11b)],'timeout':0x7530});}_0x1052ab=_0xfdd8cc[_0x436369(0x19b)]('\x0a')[_0x436369(0x5a2)](_0x302102=>{const _0x30866d=_0x436369,_0x105ac8=_0x302102['trim']();return _0x105ac8&&!_0x105ac8[_0x30866d(0x4ae)](_0x30866d(0x5ff))&&!_0x105ac8[_0x30866d(0x4ae)](_0x2d3335['xiACB']);})[_0x436369(0x12b)](_0x7dfaba=>{const _0x566416=_0x436369;if(_0x7dfaba['includes'](_0x2d3335[_0x566416(0x360)])){const _0x4c320c=_0x7dfaba[_0x566416(0x600)](/^(.+?)\s+-\s+(.+?)$/);return _0x4c320c?{'id':_0x4c320c[0x1][_0x566416(0x3ea)](),'name':_0x4c320c[0x2][_0x566416(0x3ea)]()}:null;}else{if(_0x7dfaba['includes'](',')){const _0x9f0c6a=_0x7dfaba[_0x566416(0x19b)](',')[_0x566416(0x12b)](_0x45f701=>_0x45f701['trim']()[_0x566416(0x203)](/"/g,''));return _0x2d3335['fOAgV'](_0x9f0c6a['length'],0x3)?{'id':_0x9f0c6a[0x0],'name':_0x9f0c6a[0x2]}:null;}else{if(_0x7dfaba[_0x566416(0x600)](/^[a-zA-Z0-9.-]+$/)){if(_0x2d3335['UMwqI'](_0x2d3335[_0x566416(0x5b5)],'iLYjN')){const _0x32b225=_0x3b3c6f[_0x566416(0x12b)](_0x437989=>_0x437989[_0x566416(0x192)]),_0x2eb8af=CXEIka[_0x566416(0xf8)](_0x3fcc4c,_0xd0ee48,CXEIka[_0x566416(0x6f1)]);_0x511568['log']('Using\x20iOS\x20wireless\x20script\x20for:\x20'+_0x32b225[_0x566416(0x4a3)](',\x20')),_0xa3b016['push'](_0x524966(_0x90d7f0,_0x32b225,_0x2eb8af,_0x296c0b));}else return{'id':_0x7dfaba[_0x566416(0x3ea)](),'name':_0x7dfaba['trim']()};}}}return null;})['filter'](_0xfbe523=>_0xfbe523)[_0x436369(0x488)]((_0x25401f,_0xe76e56)=>_0x25401f[_0x436369(0x192)][_0x436369(0x5e2)](_0xe76e56[_0x436369(0x192)]));if(_0x1052ab[_0x436369(0x484)]===0x0){if(_0x2d3335[_0x436369(0x4bf)](_0x2d3335[_0x436369(0x2ae)],_0x436369(0x5f5))){_0x138ac8&&CXEIka[_0x436369(0x74d)](_0x4c84a2,_0x48ac84,_0x2ec05a,_0x2b5ff3,_0xbbfff4);const _0xb84249={};_0xb84249[_0x436369(0x2ba)]=CXEIka[_0x436369(0x318)],_0xb84249[_0x436369(0x31c)]=_0x598b3a,_0x1f29fc['send'](_0x3ad01d['stringify'](_0xb84249));}else{const _0x5bec68={};_0x5bec68[_0x436369(0x618)]=_0x2d3335[_0x436369(0x427)],_0x1052ab=[_0x5bec68];}}}catch(_0x3aa910){if(_0x2d3335[_0x436369(0x472)](_0x436369(0x378),_0x2d3335[_0x436369(0x59b)])){console['error'](_0x2d3335[_0x436369(0x39c)],_0x3aa910[_0x436369(0xef)]);const _0x21f094={};_0x21f094[_0x436369(0x618)]=_0x436369(0xbb)+_0x3aa910[_0x436369(0xef)],_0x1052ab=[_0x21f094];}else{const _0x5de54a={};_0x5de54a[_0x436369(0x38b)]=CXEIka['LsGVE'],_0x520a84(_0x436369(0x25a)+_0x12b8d8,_0x5de54a),_0x2a58a9++;}}}else _0x2f925b[_0xb744aa][_0x436369(0x160)]=_0x436369(0x3a6);}}_0x182c14[_0x11335d[_0x436369(0x192)]]={'success':!![],'platform':_0x11335d[_0x436369(0x569)],'apps':_0x1052ab,'count':Array['isArray'](_0x1052ab)?_0x1052ab['length']:0x0};}catch(_0x2faf6d){const _0x2d4b98={};_0x2d4b98[_0x436369(0x492)]=![],_0x2d4b98[_0x436369(0x618)]=_0x2faf6d['message'],_0x182c14[_0x11335d[_0x436369(0x192)]]=_0x2d4b98;}}const _0x50706e={};_0x50706e[_0x436369(0x492)]=!![],_0x50706e[_0x436369(0x5b9)]=_0x182c14,_0x4e8707[_0x436369(0x573)](_0x50706e);}else{const _0x2b275e=_0x4326e8['match'](/ID:([^\s]+)/);if(_0x2b275e)_0x23723b[_0x436369(0x466)]=_0x2b275e[0x1];}}catch(_0x33adc9){const _0x14ee1d={};_0x14ee1d[_0x436369(0x492)]=![],_0x14ee1d[_0x436369(0x618)]=_0x33adc9[_0x436369(0xef)],_0x4e8707['status'](0x1f4)['json'](_0x14ee1d);}}),app[_0x50607(0x633)](_0x50607(0x5ce),async(_0x541438,_0xa79653)=>{const _0x3306e9=_0x50607,_0x184f03={'LMNZW':_0x3306e9(0x6eb),'jQnni':function(_0x5d2354,_0x531ef7){return _0x5d2354||_0x531ef7;},'OXwIm':_0x3306e9(0x2c6),'qKdSw':_0x3306e9(0x6ed),'XOciB':function(_0x5a6014,_0x4822b8){return _0x5a6014(_0x4822b8);},'aIzFm':_0x3306e9(0x2a3),'lAZTO':function(_0x3c4edf,_0x22120e){return _0x3c4edf===_0x22120e;},'bTQee':function(_0x11348d,_0x48cb0f,_0x2a5774){return _0x11348d(_0x48cb0f,_0x2a5774);},'dHBJC':_0x3306e9(0xb4),'NEOSN':'Unknown','dgKPO':function(_0xc8b95f,_0x130168,_0x1338d5){return _0xc8b95f(_0x130168,_0x1338d5);},'pPMSq':function(_0x5d35b9,_0x5223ae){return _0x5d35b9!==_0x5223ae;},'zkfPj':function(_0x521ccc,_0x25162f,_0x45d3a6){return _0x521ccc(_0x25162f,_0x45d3a6);},'Rrxct':_0x3306e9(0xc5),'AldUZ':_0x3306e9(0x284),'ZYqwv':'PHhAC','hjNuq':_0x3306e9(0x102),'kQYhe':_0x3306e9(0x442),'LRfKl':_0x3306e9(0x2ac),'okmun':function(_0x241ce1,_0x56a2df){return _0x241ce1>=_0x56a2df;},'gZMDJ':_0x3306e9(0x2a1),'XGvGZ':_0x3306e9(0x45f),'hQvIF':_0x3306e9(0x282),'Fherb':_0x3306e9(0x26b),'KoXqN':_0x3306e9(0x22c),'xPOtQ':function(_0x78734a,_0x30e776){return _0x78734a===_0x30e776;}};try{const {device:_0x12ee47,bundleId:_0x2c8a39}=_0x541438[_0x3306e9(0x6a0)];if(_0x184f03[_0x3306e9(0x593)](!_0x12ee47,!_0x2c8a39)){const _0x132d46={};return _0x132d46[_0x3306e9(0x492)]=![],_0x132d46[_0x3306e9(0x618)]=_0x184f03[_0x3306e9(0x3fd)],_0xa79653[_0x3306e9(0x160)](0x190)[_0x3306e9(0x573)](_0x132d46);}const _0x314260=discoveredDevices['find'](_0x13f653=>_0x13f653[_0x3306e9(0x192)]===_0x12ee47);if(!_0x314260){const _0x4cf52e={};return _0x4cf52e[_0x3306e9(0x492)]=![],_0x4cf52e['error']=_0x184f03['qKdSw'],_0xa79653[_0x3306e9(0x160)](0x194)['json'](_0x4cf52e);}const {execSync:_0xa6bc02}=_0x184f03[_0x3306e9(0x363)](require,_0x184f03[_0x3306e9(0x543)]);let _0x1ce2ef={};try{if(_0x184f03[_0x3306e9(0x54c)](_0x314260['platform'],_0x3306e9(0x412))){const _0xa7b37b=_0x314260[_0x3306e9(0x343)]||_0x314260['serial'];try{const _0x20195a=_0x184f03['bTQee'](_0xa6bc02,_0x3306e9(0x358)+_0xa7b37b+_0x3306e9(0x10e)+_0x2c8a39+_0x3306e9(0x290),{'encoding':_0x184f03[_0x3306e9(0x723)],'timeout':0x2710}),_0x5c1fad=_0x20195a[_0x3306e9(0x600)](/versionName=([^\s]+)/);_0x5c1fad&&(_0x1ce2ef[_0x3306e9(0x733)]=_0x5c1fad[0x1]);}catch(_0x3bb071){_0x1ce2ef[_0x3306e9(0x733)]=_0x184f03['NEOSN'];}try{const _0x2237af=_0x184f03[_0x3306e9(0x35e)](_0xa6bc02,_0x3306e9(0x358)+_0xa7b37b+'\x20shell\x20dumpsys\x20package\x20'+_0x2c8a39+_0x3306e9(0x3bf),{'encoding':_0x184f03[_0x3306e9(0x723)],'timeout':0x2710});_0x1ce2ef['name']=_0x2c8a39;}catch(_0x48ab67){if(_0x184f03[_0x3306e9(0x233)](_0x3306e9(0x74e),'BUUHz')){_0x27b40f[_0x3306e9(0x618)](_0x3306e9(0x22e)+_0x360949[_0x3306e9(0xef)]);const _0x3b5a57={};_0x3b5a57[_0x3306e9(0x2ba)]=_0x3306e9(0x5b2),_0x3b5a57[_0x3306e9(0x618)]=_0x2e5936[_0x3306e9(0xef)],_0x3b5a57[_0x3306e9(0x326)]=_0x1e11b5,_0x5e2576[_0x3306e9(0x65f)](_0x10f0a5[_0x3306e9(0x62d)](_0x3b5a57));return;}else _0x1ce2ef[_0x3306e9(0x192)]=_0x2c8a39;}try{const _0x54bde1=_0x184f03['zkfPj'](_0xa6bc02,'adb\x20-s\x20'+_0xa7b37b+_0x3306e9(0x5e7)+_0x2c8a39,{'encoding':_0x184f03[_0x3306e9(0x723)],'timeout':0x2710});_0x1ce2ef['path']=_0x54bde1[_0x3306e9(0x203)](_0x184f03['Rrxct'],'')[_0x3306e9(0x3ea)]();}catch(_0x535bff){if(_0x184f03['pPMSq'](_0x184f03[_0x3306e9(0x510)],_0x184f03[_0x3306e9(0x4fc)]))_0x1ce2ef[_0x3306e9(0x552)]=_0x184f03[_0x3306e9(0x771)];else{const _0xcd6790={};_0xcd6790[_0x3306e9(0x492)]=![],_0xcd6790[_0x3306e9(0x618)]=_0x5b83fd[_0x3306e9(0xef)],_0x1f0262['status'](0x1f4)[_0x3306e9(0x573)](_0xcd6790);}}_0x1ce2ef[_0x3306e9(0x656)]=_0x2c8a39,_0x1ce2ef['platform']='Android';}else{if(_0x184f03['lAZTO'](_0x314260[_0x3306e9(0x569)],_0x184f03[_0x3306e9(0x411)])){if(_0x184f03[_0x3306e9(0x233)](_0x184f03[_0x3306e9(0x218)],_0x184f03['kQYhe']))_0x5fdf3c[_0x3306e9(0x37a)](_0x3306e9(0x1ad)+_0x107c38[_0x3306e9(0x75c)]);else{const _0x53fcda=_0x314260[_0x3306e9(0x343)];try{if(_0x184f03[_0x3306e9(0x61c)]===_0x3306e9(0x167)){if(_0x152b03[_0x3306e9(0x625)]===_0xb61111[_0x3306e9(0x467)]){const _0x2e27dd={};_0x2e27dd['type']=_0x3306e9(0x246),_0x2e27dd[_0x3306e9(0x3d4)]=_0x156c77,_0x68ae6c['send'](_0x2c2e62[_0x3306e9(0x62d)](_0x2e27dd));}}else{const _0x2ef4df={};_0x2ef4df[_0x3306e9(0x4c0)]=_0x3306e9(0xb4),_0x2ef4df[_0x3306e9(0x6e7)]=0x2710;const _0x51fb4c=_0xa6bc02('ideviceinstaller\x20-u\x20'+_0x53fcda+_0x3306e9(0x52c)+_0x2c8a39+'\x22',_0x2ef4df),_0x33f3f6=_0x51fb4c[_0x3306e9(0x19b)](',')['map'](_0x8e640e=>_0x8e640e[_0x3306e9(0x3ea)]()[_0x3306e9(0x203)](/"/g,''));if(_0x184f03[_0x3306e9(0x3da)](_0x33f3f6[_0x3306e9(0x484)],0x3)){if(_0x184f03[_0x3306e9(0x233)](_0x184f03[_0x3306e9(0x1c7)],_0x184f03[_0x3306e9(0x471)]))_0x1ce2ef[_0x3306e9(0x656)]=_0x33f3f6[0x0],_0x1ce2ef[_0x3306e9(0x733)]=_0x33f3f6[0x1],_0x1ce2ef[_0x3306e9(0x192)]=_0x33f3f6[0x2];else{const _0x27fe94={};_0x27fe94[_0x3306e9(0x492)]=![],_0x27fe94[_0x3306e9(0x618)]=ZeOEqE[_0x3306e9(0x414)],_0x57bf03[_0x3306e9(0x160)](0x1f4)[_0x3306e9(0x573)](_0x27fe94);}}else _0x1ce2ef[_0x3306e9(0x656)]=_0x2c8a39,_0x1ce2ef[_0x3306e9(0x192)]=_0x2c8a39,_0x1ce2ef[_0x3306e9(0x733)]=_0x184f03[_0x3306e9(0x771)];}}catch(_0x4ca802){_0x1ce2ef[_0x3306e9(0x656)]=_0x2c8a39,_0x1ce2ef['name']=_0x2c8a39,_0x1ce2ef[_0x3306e9(0x733)]=_0x3306e9(0xca),_0x1ce2ef[_0x3306e9(0x618)]=_0x184f03[_0x3306e9(0x5de)];}_0x1ce2ef[_0x3306e9(0x569)]=_0x3306e9(0x268);}}}const _0x5db13f={};_0x5db13f[_0x3306e9(0x492)]=!![],_0x5db13f[_0x3306e9(0x3c1)]=_0x1ce2ef,_0xa79653[_0x3306e9(0x573)](_0x5db13f);}catch(_0x18c067){if(_0x184f03[_0x3306e9(0x233)](_0x3306e9(0x26b),_0x184f03[_0x3306e9(0x2af)]))_0x2f89af=_0xaa4a9d['commands']['map'](_0x49aa68=>_0x49aa68['finalCommand']||_0x49aa68[_0x3306e9(0xfe)]);else{const _0x4ee4cc={};_0x4ee4cc['bundleId']=_0x2c8a39,_0x4ee4cc['platform']=_0x314260[_0x3306e9(0x569)],_0x4ee4cc['error']=_0x184f03[_0x3306e9(0x169)];const _0x4a807f={};_0x4a807f[_0x3306e9(0x492)]=![],_0x4a807f[_0x3306e9(0x618)]=_0x18c067[_0x3306e9(0xef)],_0x4a807f[_0x3306e9(0x3c1)]=_0x4ee4cc,_0xa79653[_0x3306e9(0x573)](_0x4a807f);}}}catch(_0x22a7c5){if(_0x184f03['xPOtQ'](_0x3306e9(0x252),_0x3306e9(0x252))){const _0x50ff00={};_0x50ff00[_0x3306e9(0x492)]=![],_0x50ff00['error']=_0x22a7c5[_0x3306e9(0xef)],_0xa79653[_0x3306e9(0x160)](0x1f4)['json'](_0x50ff00);}else{const _0x19fe65=_0x288132[_0x3306e9(0x600)](/^(.+?)\s+-\s+(.+?)$/);return _0x19fe65?{'id':_0x19fe65[0x1][_0x3306e9(0x3ea)](),'name':_0x19fe65[0x2][_0x3306e9(0x3ea)]()}:null;}}});let server;function startServer(_0xffe247={}){const _0x28edb4=_0x50607,_0x32d6a8={'uKqqv':_0x28edb4(0x312),'VVaSI':_0x28edb4(0x5a5),'IeMCw':function(_0x876071,_0x329824){return _0x876071!==_0x329824;},'BhGdF':function(_0x47f12c,_0xea75e8){return _0x47f12c(_0xea75e8);},'TxMdh':_0x28edb4(0x761),'MYyRJ':function(_0x258cc7){return _0x258cc7();},'WXyhr':'yDMKC','bqIsf':'upgrade','tKuoC':_0x28edb4(0x618),'WbGGY':function(_0x2a24de,_0x1ca16c){return _0x2a24de!==_0x1ca16c;}},_0x32042b=_0xffe247[_0x28edb4(0x3d1)]||PORT,_0x54abd4=_0x32d6a8['WbGGY'](_0xffe247['browser'],![]),_0x14d600=_0x28edb4(0x2d1);return console[_0x28edb4(0x37a)](_0x28edb4(0x364)+_0x14d600+'\x0a'),new Promise((_0x73f07c,_0x2fb30e)=>{const _0x18dd33=_0x28edb4,_0x1095e5={};_0x1095e5[_0x18dd33(0x58c)]=_0x18dd33(0xed),_0x1095e5['GzNYW']=_0x32d6a8[_0x18dd33(0x739)];const _0x5069c3=_0x1095e5;if(_0x18dd33(0x255)!==_0x18dd33(0x255)){const _0x1cafa1={};return _0x1cafa1[_0x18dd33(0x492)]=![],_0x1cafa1['error']=NPWwvf['IxUzo'],_0x301660['status'](0x190)['json'](_0x1cafa1);}else server=app['listen'](_0x32042b,()=>{const _0x1a0ca1=_0x18dd33,_0x3a7bbf={'lRvGs':_0x32d6a8[_0x1a0ca1(0x45e)],'QlrLy':_0x32d6a8[_0x1a0ca1(0x710)],'Jjpgi':_0x1a0ca1(0x356),'KpWgr':_0x1a0ca1(0x246),'Izxon':function(_0x5d89c9,_0x368fa1){const _0x4c5f1e=_0x1a0ca1;return _0x32d6a8[_0x4c5f1e(0x3e6)](_0x5d89c9,_0x368fa1);},'jmjJs':_0x1a0ca1(0x619),'WvxSC':function(_0x197f18,_0xdd3899){const _0x4678c3=_0x1a0ca1;return _0x32d6a8[_0x4678c3(0x26a)](_0x197f18,_0xdd3899);},'PIToz':_0x32d6a8[_0x1a0ca1(0x254)]};console['log']('Server\x20running\x20on\x20port\x20'+_0x32042b),console['log']('WebSocket\x20server\x20ready'),_0x32d6a8['MYyRJ'](discoverDevices)[_0x1a0ca1(0x4a9)](_0x59d21b=>{const _0x1ee2a8=_0x1a0ca1,_0x372606={};_0x372606[_0x1ee2a8(0xb2)]=_0x3a7bbf['KpWgr'];const _0x47acde=_0x372606;if(_0x3a7bbf[_0x1ee2a8(0x35d)](_0x3a7bbf[_0x1ee2a8(0x44b)],'cHTUZ'))try{const _0x15059c=_0x1e61eb['parse'](_0x5d2d0f);return _0x3e3bdc[_0x1ee2a8(0x37a)](zfwsoR['lRvGs'],_0x3aef02[_0x1ee2a8(0x616)](_0x15059c)?_0x15059c[_0x1ee2a8(0x484)]:zfwsoR[_0x1ee2a8(0x56f)]),_0x31b310[_0x1ee2a8(0x616)](_0x15059c)?_0x15059c:[];}catch(_0x4c95){_0x26d237[_0x1ee2a8(0x37a)](zfwsoR['Jjpgi'],_0x4c95[_0x1ee2a8(0xef)]);}else{console[_0x1ee2a8(0x37a)](_0x1ee2a8(0x3f9)+_0x59d21b['length']+_0x1ee2a8(0x2c2));if(_0x54abd4){console[_0x1ee2a8(0x37a)]('\x0aš\x20Opening\x20browser\x20to\x20'+_0x14d600+_0x1ee2a8(0x29d));const _0x1df7a7=_0x3a7bbf[_0x1ee2a8(0x1b7)](require,_0x3a7bbf[_0x1ee2a8(0x65e)]);_0x3a7bbf[_0x1ee2a8(0x1b7)](_0x1df7a7,_0x14d600)[_0x1ee2a8(0x4c8)](_0x89a949=>{const _0x1c523d=_0x1ee2a8,_0x42859d={};_0x42859d[_0x1c523d(0x662)]=_0x47acde[_0x1c523d(0xb2)];const _0x124f09=_0x42859d;if(_0x1c523d(0x47b)!==_0x1c523d(0x47b)){const _0x4cd834={};_0x4cd834[_0x1c523d(0x2ba)]=QRvdFl[_0x1c523d(0x662)],_0x4cd834[_0x1c523d(0x3d4)]=_0x45b107,_0x59612b[_0x1c523d(0x65f)](_0x587642[_0x1c523d(0x62d)](_0x4cd834));}else console[_0x1c523d(0x37a)](_0x1c523d(0x313)+_0x14d600+_0x1c523d(0x28f));});}const _0x1b93d1={};_0x1b93d1['port']=_0x32042b,_0x1b93d1[_0x1ee2a8(0x3d4)]=_0x59d21b,_0x3a7bbf[_0x1ee2a8(0x1b7)](_0x73f07c,_0x1b93d1);}})['catch'](_0x2fb30e);}),server['on'](_0x32d6a8['bqIsf'],(_0x165499,_0x55ba48,_0x40f491)=>{const _0x527740=_0x18dd33,_0x5951cf={};_0x5951cf[_0x527740(0x426)]=function(_0x2f0530,_0x5dbadd){return _0x2f0530===_0x5dbadd;},_0x5951cf[_0x527740(0x123)]='PLXWh',_0x5951cf[_0x527740(0x103)]=_0x5069c3[_0x527740(0xc7)];const _0x27d4fc=_0x5951cf;wss['handleUpgrade'](_0x165499,_0x55ba48,_0x40f491,_0x55e38a=>{const _0x265f6e=_0x527740;if(_0x27d4fc['oFqSF'](_0x27d4fc[_0x265f6e(0x123)],_0x27d4fc[_0x265f6e(0x103)])){const _0x432427={};_0x432427[_0x265f6e(0x492)]=![],_0x432427[_0x265f6e(0x618)]=_0x5940e1[_0x265f6e(0xef)],_0x39318d['status'](0x1f4)[_0x265f6e(0x573)](_0x432427);}else wss[_0x265f6e(0x6b7)](_0x265f6e(0x6d7),_0x55e38a,_0x165499);});}),server['on'](_0x32d6a8[_0x18dd33(0x6e3)],_0x2fb30e);});}function stopServer(){const _0x543dcc=_0x50607,_0x3d8b3a={'bVeGm':function(_0x1b0533,_0x64ec12){return _0x1b0533!==_0x64ec12;},'CjcoA':_0x543dcc(0x1c4),'ooxZR':function(_0x1082ab){return _0x1082ab();}};return new Promise(_0x410be9=>{const _0x2ca48c=_0x543dcc;server?_0x3d8b3a[_0x2ca48c(0x43f)]('UJUFq',_0x3d8b3a[_0x2ca48c(0x136)])?server[_0x2ca48c(0x3a0)](_0x410be9):_0x1f6994+=_0x6f2106['toString']():_0x3d8b3a[_0x2ca48c(0x50c)](_0x410be9);});}const _0xbd65db={};_0xbd65db[_0x50607(0x694)]=startServer,_0xbd65db[_0x50607(0x59e)]=stopServer,module[_0x50607(0x444)]=_0xbd65db;require[_0x50607(0x5b4)]===module&&startServer()[_0x50607(0x4c8)](_0x185fee=>{const _0x47dee2=_0x50607,_0x12f46d={};_0x12f46d[_0x47dee2(0x49e)]=_0x47dee2(0x59f);const _0x471764=_0x12f46d;console[_0x47dee2(0x618)](_0x471764['qAwoR'],_0x185fee),process[_0x47dee2(0x3e8)](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
|
+
const filenameWithoutExt = filename.replace(/\.sh$/, '');
|
|
76
|
+
|
|
77
|
+
// List of paths to try in order (prioritize compiled binaries)
|
|
78
|
+
const pathsToTry = [
|
|
79
|
+
// NPM package: compiled binary (no .sh extension) - PRODUCTION
|
|
80
|
+
path.join(__dirname, '../scripts/shell/', filenameWithoutExt),
|
|
81
|
+
// NPM package: .sh file (if not compiled)
|
|
82
|
+
path.join(__dirname, '../scripts/shell/', filename),
|
|
83
|
+
// Development location (project root)
|
|
84
|
+
path.join(__dirname, '../../', filename),
|
|
85
|
+
// Try in lib directory itself (backup)
|
|
86
|
+
path.join(__dirname, filename),
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
for (const scriptPath of pathsToTry) {
|
|
90
|
+
if (fs.existsSync(scriptPath)) {
|
|
91
|
+
console.log(`ā
Found script: ${filename} at ${scriptPath}`);
|
|
92
|
+
return scriptPath;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.error(`ā Script not found: ${filename}`);
|
|
97
|
+
console.error(` Searched in:`);
|
|
98
|
+
pathsToTry.forEach(p => console.error(` - ${p}`));
|
|
99
|
+
|
|
100
|
+
// Return first path as fallback (will fail but with clear error)
|
|
101
|
+
return pathsToTry[0];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Device configuration paths
|
|
105
|
+
const DEVICE_CONFIG = findConfigFile('devices.conf');
|
|
106
|
+
// Use OS temp directory for session file - works for both local and npm package
|
|
107
|
+
const SESSION_MAP_FILE = path.join(require('os').tmpdir(), 'devicely_android_sessions.map');
|
|
108
|
+
const APPS_CONFIG = findConfigFile('apps_presets.conf');
|
|
109
|
+
|
|
110
|
+
// iOS scripts
|
|
111
|
+
const WIRELESS_SCRIPT_PATH = findScriptFile('connect_ios_wireless_multi_final.sh');
|
|
112
|
+
const USB_SCRIPT_PATH = findScriptFile('connect_ios_usb_multi_final.sh');
|
|
113
|
+
|
|
114
|
+
// Android scripts
|
|
115
|
+
const ANDROID_WIRELESS_SCRIPT_PATH = findScriptFile('android_device_control.sh');
|
|
116
|
+
const ANDROID_USB_SCRIPT_PATH = findScriptFile('android_device_control.sh');
|
|
117
|
+
|
|
118
|
+
// Recording storage path
|
|
119
|
+
const RECORDINGS_DIR = path.join(__dirname, '../../recordings');
|
|
120
|
+
|
|
121
|
+
// Screenshots storage path
|
|
122
|
+
const SCREENSHOTS_DIR = path.join(__dirname, './screenshots');
|
|
123
|
+
|
|
124
|
+
// Recording state
|
|
125
|
+
let currentRecording = null; // { name, devices, commands: [], startTime }
|
|
126
|
+
let isRecording = false;
|
|
127
|
+
|
|
128
|
+
// Replay state
|
|
129
|
+
let isReplaying = false;
|
|
130
|
+
let replayAborted = false;
|
|
131
|
+
|
|
132
|
+
// ============================================
|
|
133
|
+
// UIAutomator2 Session Management Functions
|
|
134
|
+
// ============================================
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Start UIAutomator2 session for Android device
|
|
138
|
+
*/
|
|
139
|
+
async function startUIAutomator2Session(udid, deviceName) {
|
|
140
|
+
console.log(`š Starting UIAutomator2 session for ${deviceName} (${udid})...`);
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
// Find available port
|
|
144
|
+
let port = 8200;
|
|
145
|
+
while (true) {
|
|
146
|
+
try {
|
|
147
|
+
execSync(`lsof -i:${port}`, { stdio: 'ignore' });
|
|
148
|
+
port++; // Port is in use, try next
|
|
149
|
+
} catch {
|
|
150
|
+
break; // Port is available
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log(`š” Using port ${port} for ${deviceName}`);
|
|
155
|
+
|
|
156
|
+
// Start UIAutomator2 server on device
|
|
157
|
+
const serverProcess = spawn('adb', ['-s', udid, 'shell', 'am', 'instrument', '-w',
|
|
158
|
+
'io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner'
|
|
159
|
+
], { detached: true, stdio: 'ignore' });
|
|
160
|
+
|
|
161
|
+
serverProcess.unref(); // Don't wait for process to exit
|
|
162
|
+
|
|
163
|
+
// Wait for server to start
|
|
164
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
165
|
+
|
|
166
|
+
// Forward port
|
|
167
|
+
execSync(`adb -s ${udid} forward tcp:${port} tcp:6790`);
|
|
168
|
+
|
|
169
|
+
// Wait a bit more
|
|
170
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
171
|
+
|
|
172
|
+
// Create session via HTTP
|
|
173
|
+
const axios = require('axios');
|
|
174
|
+
const sessionResponse = await axios.post(`http://localhost:${port}/wd/hub/session`, {
|
|
175
|
+
capabilities: {
|
|
176
|
+
alwaysMatch: {
|
|
177
|
+
platformName: 'Android',
|
|
178
|
+
'appium:automationName': 'UiAutomator2',
|
|
179
|
+
'appium:udid': udid
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const sessionId = sessionResponse.data.value.sessionId || sessionResponse.data.sessionId;
|
|
185
|
+
|
|
186
|
+
// Store session info
|
|
187
|
+
androidSessions.set(udid, {
|
|
188
|
+
sessionId,
|
|
189
|
+
port,
|
|
190
|
+
serverPid: serverProcess.pid,
|
|
191
|
+
deviceName
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Save to session file for scripts to use - remove old entries first
|
|
195
|
+
try {
|
|
196
|
+
let content = '';
|
|
197
|
+
try {
|
|
198
|
+
content = await fs.readFile(SESSION_MAP_FILE, 'utf-8');
|
|
199
|
+
} catch (err) {
|
|
200
|
+
// File doesn't exist yet, that's ok
|
|
201
|
+
}
|
|
202
|
+
const lines = content.split('\n').filter(line => line && !line.startsWith(`${udid}:`));
|
|
203
|
+
lines.push(`${udid}:${sessionId}:${port}`);
|
|
204
|
+
await fs.writeFile(SESSION_MAP_FILE, lines.join('\n') + '\n');
|
|
205
|
+
console.log(`ā
Session file updated: ${udid}:${sessionId}:${port}`);
|
|
206
|
+
} catch (err) {
|
|
207
|
+
console.error(`ā ļø Failed to update session file: ${err.message}`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
console.log(`ā
UIAutomator2 session created for ${deviceName}`);
|
|
211
|
+
console.log(` Session ID: ${sessionId}`);
|
|
212
|
+
console.log(` Port: ${port}`);
|
|
213
|
+
|
|
214
|
+
return { success: true, sessionId, port };
|
|
215
|
+
|
|
216
|
+
} catch (error) {
|
|
217
|
+
console.error(`ā Failed to start UIAutomator2 for ${deviceName}:`, error.message);
|
|
218
|
+
return { success: false, error: error.message };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Stop UIAutomator2 session for Android device
|
|
224
|
+
*/
|
|
225
|
+
async function stopUIAutomator2Session(udid, deviceName) {
|
|
226
|
+
console.log(`š Stopping UIAutomator2 session for ${deviceName} (${udid})...`);
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
const session = androidSessions.get(udid);
|
|
230
|
+
|
|
231
|
+
if (!session) {
|
|
232
|
+
console.log(`ā ļø No active session found for ${deviceName}`);
|
|
233
|
+
return { success: true, message: 'No active session' };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Delete session via HTTP
|
|
237
|
+
try {
|
|
238
|
+
const axios = require('axios');
|
|
239
|
+
await axios.delete(`http://localhost:${session.port}/wd/hub/session/${session.sessionId}`);
|
|
240
|
+
console.log(`ā
UIAutomator2 session deleted for ${deviceName}`);
|
|
241
|
+
} catch (err) {
|
|
242
|
+
console.log(`ā ļø Could not delete session via HTTP: ${err.message}`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Remove port forwarding
|
|
246
|
+
try {
|
|
247
|
+
execSync(`adb -s ${udid} forward --remove tcp:${session.port}`);
|
|
248
|
+
console.log(`ā
Port forwarding removed for ${deviceName}`);
|
|
249
|
+
} catch (err) {
|
|
250
|
+
console.log(`ā ļø Could not remove port forwarding: ${err.message}`);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Kill UIAutomator2 server on device
|
|
254
|
+
try {
|
|
255
|
+
execSync(`adb -s ${udid} shell am force-stop io.appium.uiautomator2.server`);
|
|
256
|
+
execSync(`adb -s ${udid} shell am force-stop io.appium.uiautomator2.server.test`);
|
|
257
|
+
console.log(`ā
UIAutomator2 server stopped on ${deviceName}`);
|
|
258
|
+
} catch (err) {
|
|
259
|
+
console.log(`ā ļø Could not stop UIAutomator2 server: ${err.message}`);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Remove from memory
|
|
263
|
+
androidSessions.delete(udid);
|
|
264
|
+
|
|
265
|
+
// Update session file
|
|
266
|
+
try {
|
|
267
|
+
const content = await fs.readFile(SESSION_MAP_FILE, 'utf-8');
|
|
268
|
+
const lines = content.split('\n').filter(line => !line.startsWith(`${udid}:`));
|
|
269
|
+
await fs.writeFile(SESSION_MAP_FILE, lines.join('\n'));
|
|
270
|
+
console.log(`ā
Session file updated for ${deviceName}`);
|
|
271
|
+
} catch (err) {
|
|
272
|
+
console.log(`ā ļø Could not update session file: ${err.message}`);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
console.log(`ā
UIAutomator2 session stopped for ${deviceName}`);
|
|
276
|
+
return { success: true };
|
|
277
|
+
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error(`ā Error stopping UIAutomator2 for ${deviceName}:`, error.message);
|
|
280
|
+
return { success: false, error: error.message };
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// ============================================
|
|
285
|
+
|
|
286
|
+
// Load device configuration
|
|
287
|
+
async function loadDeviceConfig() {
|
|
288
|
+
try {
|
|
289
|
+
const content = await fs.readFile(DEVICE_CONFIG, 'utf-8');
|
|
290
|
+
const devices = content
|
|
291
|
+
.split('\n')
|
|
292
|
+
.filter(line => line.trim() && !line.startsWith('#'))
|
|
293
|
+
.map(line => {
|
|
294
|
+
const parts = line.split(',').map(s => s.trim());
|
|
295
|
+
const [name, udid, ip, platform, type] = parts;
|
|
296
|
+
|
|
297
|
+
// Smart platform detection if not specified
|
|
298
|
+
let detectedPlatform = platform || 'ios';
|
|
299
|
+
if (!platform && udid) {
|
|
300
|
+
// Android wireless: IP:PORT format
|
|
301
|
+
if (udid.includes(':') && udid.match(/^\d+\.\d+\.\d+\.\d+:\d+$/)) {
|
|
302
|
+
detectedPlatform = 'android';
|
|
303
|
+
}
|
|
304
|
+
// Android USB: Short serial without dashes
|
|
305
|
+
else if (udid.length < 20 && !udid.includes('-')) {
|
|
306
|
+
detectedPlatform = 'android';
|
|
307
|
+
}
|
|
308
|
+
// iOS: Long UUID with dashes
|
|
309
|
+
else if (udid.includes('-') && udid.length > 30) {
|
|
310
|
+
detectedPlatform = 'ios';
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return {
|
|
315
|
+
name,
|
|
316
|
+
udid,
|
|
317
|
+
ip: ip || '',
|
|
318
|
+
platform: detectedPlatform,
|
|
319
|
+
type: type || (ip ? 'wireless' : 'usb'),
|
|
320
|
+
status: 'unknown'
|
|
321
|
+
};
|
|
322
|
+
});
|
|
323
|
+
return devices;
|
|
324
|
+
} catch (error) {
|
|
325
|
+
console.error('Error loading device config:', error);
|
|
326
|
+
return [];
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Discover and check device connectivity (USB + Wireless)
|
|
331
|
+
async function discoverDevices() {
|
|
332
|
+
// Save current connection states
|
|
333
|
+
const previousStates = new Map();
|
|
334
|
+
connectedDevices.forEach(device => {
|
|
335
|
+
previousStates.set(device.udid, {
|
|
336
|
+
status: device.status,
|
|
337
|
+
sessionId: device.sessionId
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
connectedDevices = await discoverAllDevices();
|
|
342
|
+
|
|
343
|
+
// Restore connection states for devices that were previously connected
|
|
344
|
+
connectedDevices.forEach(device => {
|
|
345
|
+
const prevState = previousStates.get(device.udid);
|
|
346
|
+
if (prevState && prevState.status === 'online') {
|
|
347
|
+
// Preserve the online status for previously connected devices
|
|
348
|
+
device.status = 'online';
|
|
349
|
+
if (prevState.sessionId) {
|
|
350
|
+
device.sessionId = prevState.sessionId;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Auto-save USB devices to config for wireless use later
|
|
356
|
+
await autoSaveUSBDevicesToConfig(connectedDevices);
|
|
357
|
+
|
|
358
|
+
return connectedDevices;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Auto-save USB devices to config
|
|
362
|
+
async function autoSaveUSBDevicesToConfig(devices) {
|
|
363
|
+
try {
|
|
364
|
+
const usbDevices = devices.filter(d => d.connectionType === 'usb');
|
|
365
|
+
if (usbDevices.length === 0) return;
|
|
366
|
+
|
|
367
|
+
// Load existing config
|
|
368
|
+
const existingDevices = await loadDeviceConfig();
|
|
369
|
+
const existingUdids = new Set(existingDevices.map(d => d.udid));
|
|
370
|
+
|
|
371
|
+
// Add new USB devices
|
|
372
|
+
const newDevices = usbDevices.filter(d => !existingUdids.has(d.udid));
|
|
373
|
+
if (newDevices.length === 0) return;
|
|
374
|
+
|
|
375
|
+
// Append to config with placeholder IP (will be filled when wireless is configured)
|
|
376
|
+
const allDevices = [...existingDevices, ...newDevices.map(d => ({
|
|
377
|
+
name: d.name,
|
|
378
|
+
udid: d.udid,
|
|
379
|
+
ip: '' // Empty IP for USB devices, to be filled for wireless
|
|
380
|
+
}))];
|
|
381
|
+
|
|
382
|
+
// Save to config
|
|
383
|
+
let content = '# Device Configuration (Auto-updated)\n';
|
|
384
|
+
content += '# Format: device_name,udid,ip_address\n';
|
|
385
|
+
content += '# USB devices auto-detected. Add IP for wireless connection.\n\n';
|
|
386
|
+
|
|
387
|
+
allDevices.forEach(device => {
|
|
388
|
+
const ip = device.ip || '';
|
|
389
|
+
content += `${device.name},${device.udid},${ip}\n`;
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
await fs.writeFile(DEVICE_CONFIG, content);
|
|
393
|
+
console.log(`ā
Auto-saved ${newDevices.length} new USB device(s) to config`);
|
|
394
|
+
} catch (error) {
|
|
395
|
+
console.error('Error auto-saving devices:', error);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Check device connectivity
|
|
400
|
+
function checkDeviceConnectivity(device) {
|
|
401
|
+
return new Promise((resolve) => {
|
|
402
|
+
const curl = spawn('curl', [
|
|
403
|
+
'-s',
|
|
404
|
+
'--connect-timeout', '2',
|
|
405
|
+
'--max-time', '3',
|
|
406
|
+
`http://${device.ip}:8100/status`
|
|
407
|
+
]);
|
|
408
|
+
|
|
409
|
+
let output = '';
|
|
410
|
+
curl.stdout.on('data', (data) => {
|
|
411
|
+
output += data.toString();
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
curl.on('close', (code) => {
|
|
415
|
+
resolve(output.includes('"state"'));
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
setTimeout(() => {
|
|
419
|
+
curl.kill();
|
|
420
|
+
resolve(false);
|
|
421
|
+
}, 3000);
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Load app presets from config file
|
|
426
|
+
function loadAppPresets() {
|
|
427
|
+
try {
|
|
428
|
+
if (!require('fs').existsSync(APPS_CONFIG)) {
|
|
429
|
+
return {};
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
const content = require('fs').readFileSync(APPS_CONFIG, 'utf-8');
|
|
433
|
+
const presets = {};
|
|
434
|
+
|
|
435
|
+
content.split('\n')
|
|
436
|
+
.filter(line => line.trim() && !line.startsWith('#'))
|
|
437
|
+
.forEach(line => {
|
|
438
|
+
const [name, packageId] = line.split(',').map(s => s.trim());
|
|
439
|
+
if (name && packageId) {
|
|
440
|
+
// Support platform-specific notation: name.ios or name.android
|
|
441
|
+
const parts = name.split('.');
|
|
442
|
+
if (parts.length === 2) {
|
|
443
|
+
const [appName, platform] = parts;
|
|
444
|
+
if (!presets[appName]) presets[appName] = {};
|
|
445
|
+
presets[appName][platform] = packageId;
|
|
446
|
+
} else {
|
|
447
|
+
// Generic app (works on both platforms)
|
|
448
|
+
if (!presets[name]) presets[name] = {};
|
|
449
|
+
presets[name].common = packageId;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
return presets;
|
|
455
|
+
} catch (error) {
|
|
456
|
+
console.error('Error loading app presets:', error);
|
|
457
|
+
return {};
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Resolve app preset based on device platform
|
|
462
|
+
function resolveAppPreset(command, platform) {
|
|
463
|
+
const appPresets = loadAppPresets();
|
|
464
|
+
|
|
465
|
+
// Check if command is "launch <appname>"
|
|
466
|
+
const launchMatch = command.match(/^launch\s+(\S+)(.*)$/);
|
|
467
|
+
if (!launchMatch) return command; // Not a launch command
|
|
468
|
+
|
|
469
|
+
const appName = launchMatch[1];
|
|
470
|
+
const restOfCommand = launchMatch[2];
|
|
471
|
+
|
|
472
|
+
// If it already looks like a bundle ID, don't resolve
|
|
473
|
+
if (appName.includes('.')) return command;
|
|
474
|
+
|
|
475
|
+
// Look up preset
|
|
476
|
+
if (appPresets[appName]) {
|
|
477
|
+
const preset = appPresets[appName];
|
|
478
|
+
let bundleId;
|
|
479
|
+
|
|
480
|
+
// Try platform-specific first, then common
|
|
481
|
+
if (preset[platform]) {
|
|
482
|
+
bundleId = preset[platform];
|
|
483
|
+
} else if (preset.common) {
|
|
484
|
+
bundleId = preset.common;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (bundleId) {
|
|
488
|
+
console.log(` š± Resolved app preset: "${appName}" ā "${bundleId}" (${platform})`);
|
|
489
|
+
return `launch ${bundleId}${restOfCommand}`;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// No preset found, return original
|
|
494
|
+
return command;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// Execute command on device(s)
|
|
498
|
+
function executeCommand(deviceNames, command, wsClient) {
|
|
499
|
+
return new Promise(async (resolve, reject) => {
|
|
500
|
+
console.log(`\n${'#'.repeat(60)}`);
|
|
501
|
+
console.log(`Device names received: [${deviceNames.join(', ')}]`);
|
|
502
|
+
console.log(`Command: "${command}"`);
|
|
503
|
+
console.log(`${'#'.repeat(60)}\n`);
|
|
504
|
+
|
|
505
|
+
// Get full device objects from connectedDevices cache
|
|
506
|
+
// Match by name, udid, or serial
|
|
507
|
+
const devices = connectedDevices.filter(d =>
|
|
508
|
+
deviceNames.includes(d.name) ||
|
|
509
|
+
deviceNames.includes(d.udid) ||
|
|
510
|
+
deviceNames.includes(d.serial)
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
console.log(`Cache contents:`, connectedDevices.map(d => `${d.name}(${d.status})`).join(', '));
|
|
514
|
+
|
|
515
|
+
if (devices.length === 0) {
|
|
516
|
+
console.error(`ā No devices found for: [${deviceNames.join(', ')}]`);
|
|
517
|
+
return reject({ success: false, error: 'No devices found. Please refresh device list and try again.' });
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// Check if devices are online/connected
|
|
521
|
+
// Accept both 'online' and 'connected' as valid statuses
|
|
522
|
+
const offlineDevices = devices.filter(d => !['online', 'connected'].includes(d.status));
|
|
523
|
+
if (offlineDevices.length > 0) {
|
|
524
|
+
const offlineNames = offlineDevices.map(d => `${d.name} (status: ${d.status})`).join(', ');
|
|
525
|
+
console.error(`ā Devices not connected: [${offlineNames}]`);
|
|
526
|
+
|
|
527
|
+
// Send user-friendly message via WebSocket
|
|
528
|
+
if (wsClient) {
|
|
529
|
+
wsClient.send(JSON.stringify({
|
|
530
|
+
type: 'command_output',
|
|
531
|
+
data: `\nā ļø Error: Devices not connected: ${offlineNames}\n\nš” Please click the "Connect" button on each device before running commands.\n\n`,
|
|
532
|
+
devices: deviceNames
|
|
533
|
+
}));
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return reject({
|
|
537
|
+
success: false,
|
|
538
|
+
error: `Devices not connected: ${offlineNames}. Please click "Connect" button on each device first.`
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
console.log(`ā
Found ${devices.length} connected devices`);
|
|
543
|
+
console.log('Device details:', devices.map(d => `${d.name}(${d.platform}-${d.connectionType})`).join(', '));
|
|
544
|
+
|
|
545
|
+
// Group devices by platform and connection type
|
|
546
|
+
const iosUSBDevices = devices.filter(d => d.platform === 'ios' && d.connectionType === 'usb');
|
|
547
|
+
const iosWirelessDevices = devices.filter(d => d.platform === 'ios' && d.connectionType === 'wireless');
|
|
548
|
+
const androidUSBDevices = devices.filter(d => d.platform === 'android' && d.connectionType === 'usb');
|
|
549
|
+
const androidWirelessDevices = devices.filter(d => d.platform === 'android' && d.connectionType === 'wireless');
|
|
550
|
+
|
|
551
|
+
const promises = [];
|
|
552
|
+
|
|
553
|
+
// Execute for iOS USB devices
|
|
554
|
+
if (iosUSBDevices.length > 0) {
|
|
555
|
+
const names = iosUSBDevices.map(d => d.name);
|
|
556
|
+
const iosCommand = resolveAppPreset(command, 'ios');
|
|
557
|
+
console.log(`Using iOS USB script for: ${names.join(', ')}`);
|
|
558
|
+
promises.push(executeWithScript(USB_SCRIPT_PATH, names, iosCommand, wsClient));
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Execute for iOS wireless devices
|
|
562
|
+
if (iosWirelessDevices.length > 0) {
|
|
563
|
+
const names = iosWirelessDevices.map(d => d.name);
|
|
564
|
+
const iosCommand = resolveAppPreset(command, 'ios');
|
|
565
|
+
console.log(`Using iOS wireless script for: ${names.join(', ')}`);
|
|
566
|
+
promises.push(executeWithScript(WIRELESS_SCRIPT_PATH, names, iosCommand, wsClient));
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Execute for Android USB devices
|
|
570
|
+
if (androidUSBDevices.length > 0) {
|
|
571
|
+
const androidCommand = resolveAppPreset(command, 'android');
|
|
572
|
+
console.log(`Using Android control script for USB devices: ${androidUSBDevices.map(d => d.name).join(', ')}`);
|
|
573
|
+
promises.push(executeAndroidDevices(ANDROID_USB_SCRIPT_PATH, androidUSBDevices, androidCommand, wsClient));
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// Execute for Android wireless devices
|
|
577
|
+
if (androidWirelessDevices.length > 0) {
|
|
578
|
+
const androidCommand = resolveAppPreset(command, 'android');
|
|
579
|
+
console.log(`Using Android control script for wireless devices: ${androidWirelessDevices.map(d => d.name).join(', ')}`);
|
|
580
|
+
promises.push(executeAndroidDevices(ANDROID_WIRELESS_SCRIPT_PATH, androidWirelessDevices, androidCommand, wsClient));
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
if (promises.length === 0) {
|
|
584
|
+
|
|
585
|
+
return reject({ success: false, error: 'No executable devices found' });
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
try {
|
|
589
|
+
const results = await Promise.allSettled(promises);
|
|
590
|
+
const successCount = results.filter(r => r.status === 'fulfilled').length;
|
|
591
|
+
const failCount = results.filter(r => r.status === 'rejected').length;
|
|
592
|
+
|
|
593
|
+
console.log(`\nExecuteCommand summary: ${successCount} succeeded, ${failCount} failed`);
|
|
594
|
+
|
|
595
|
+
resolve({
|
|
596
|
+
success: true,
|
|
597
|
+
results,
|
|
598
|
+
summary: `${successCount}/${promises.length} script groups completed`
|
|
599
|
+
});
|
|
600
|
+
} catch (error) {
|
|
601
|
+
console.error('Script execution error:', error);
|
|
602
|
+
reject(error);
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
function executeWithScript(scriptPath, deviceNames, command, wsClient) {
|
|
608
|
+
return new Promise((resolve, reject) => {
|
|
609
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
610
|
+
console.log(`Script: ${path.basename(scriptPath)}`);
|
|
611
|
+
console.log(`Devices: [${deviceNames.join(', ')}]`);
|
|
612
|
+
console.log(`Command: "${command}"`);
|
|
613
|
+
|
|
614
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
615
|
+
|
|
616
|
+
// Execute command on each device in parallel
|
|
617
|
+
const devicePromises = deviceNames.map((deviceName, index) => {
|
|
618
|
+
|
|
619
|
+
return new Promise((resolveDevice, rejectDevice) => {
|
|
620
|
+
// Use -d flag for each device
|
|
621
|
+
const args = ['-d', deviceName, command];
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
const child = spawn(scriptPath, args, {
|
|
625
|
+
cwd: path.dirname(scriptPath)
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
let output = '';
|
|
630
|
+
let error = '';
|
|
631
|
+
|
|
632
|
+
child.stdout.on('data', (data) => {
|
|
633
|
+
const text = data.toString();
|
|
634
|
+
output += text;
|
|
635
|
+
console.log(`[${deviceName}] STDOUT: ${text.trim()}`);
|
|
636
|
+
if (wsClient) {
|
|
637
|
+
wsClient.send(JSON.stringify({
|
|
638
|
+
type: 'command_output',
|
|
639
|
+
data: `[${deviceName}] ${text}`,
|
|
640
|
+
devices: [deviceName]
|
|
641
|
+
}));
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
child.stderr.on('data', (data) => {
|
|
646
|
+
const text = data.toString();
|
|
647
|
+
error += text;
|
|
648
|
+
console.error(`[${deviceName}] STDERR: ${text.trim()}`);
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
child.on('close', (code) => {
|
|
652
|
+
|
|
653
|
+
if (code === 0) {
|
|
654
|
+
resolveDevice({ success: true, output, device: deviceName });
|
|
655
|
+
} else {
|
|
656
|
+
rejectDevice({ success: false, error: error || `Script exited with code ${code}`, device: deviceName });
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
child.on('error', (err) => {
|
|
661
|
+
console.error(`[${deviceName}] Process error: ${err.message}`);
|
|
662
|
+
rejectDevice({ success: false, error: err.message, device: deviceName });
|
|
663
|
+
});
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
// Wait for all devices to complete
|
|
669
|
+
Promise.allSettled(devicePromises)
|
|
670
|
+
.then(results => {
|
|
671
|
+
const successful = results.filter(r => r.status === 'fulfilled').length;
|
|
672
|
+
const failed = results.filter(r => r.status === 'rejected').length;
|
|
673
|
+
|
|
674
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
675
|
+
|
|
676
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
677
|
+
|
|
678
|
+
resolve({
|
|
679
|
+
success: true,
|
|
680
|
+
results,
|
|
681
|
+
summary: `${successful}/${deviceNames.length} devices completed successfully`
|
|
682
|
+
});
|
|
683
|
+
})
|
|
684
|
+
.catch(error => {
|
|
685
|
+
console.error(`Promise.allSettled error: ${error.message}`);
|
|
686
|
+
reject(error);
|
|
687
|
+
});
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Execute Android commands (uses device UDID instead of name)
|
|
692
|
+
function executeAndroidDevices(scriptPath, devices, command, wsClient) {
|
|
693
|
+
return new Promise((resolve, reject) => {
|
|
694
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
695
|
+
|
|
696
|
+
console.log(`Script: ${path.basename(scriptPath)}`);
|
|
697
|
+
console.log(`Devices: [${devices.map(d => d.name).join(', ')}]`);
|
|
698
|
+
console.log(`Command: "${command}"`);
|
|
699
|
+
|
|
700
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
701
|
+
|
|
702
|
+
// Execute command on each device in parallel
|
|
703
|
+
const devicePromises = devices.map((device, index) => {
|
|
704
|
+
console.log(`[${index + 1}/${devices.length}] Creating execution promise for: ${device.name} (${device.udid})`);
|
|
705
|
+
|
|
706
|
+
return new Promise((resolveDevice, rejectDevice) => {
|
|
707
|
+
// Android script expects: <device_serial> <command> [args...]
|
|
708
|
+
// Use UDID (which is the serial for Android)
|
|
709
|
+
const args = [device.udid, ...command.split(' ')];
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
const child = spawn(scriptPath, args, {
|
|
713
|
+
cwd: path.dirname(scriptPath)
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
let output = '';
|
|
718
|
+
let error = '';
|
|
719
|
+
|
|
720
|
+
child.stdout.on('data', (data) => {
|
|
721
|
+
const text = data.toString();
|
|
722
|
+
output += text;
|
|
723
|
+
console.log(`[${device.name}] STDOUT: ${text.trim()}`);
|
|
724
|
+
if (wsClient) {
|
|
725
|
+
wsClient.send(JSON.stringify({
|
|
726
|
+
type: 'output',
|
|
727
|
+
device: device.name,
|
|
728
|
+
data: text
|
|
729
|
+
}));
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
child.stderr.on('data', (data) => {
|
|
734
|
+
const text = data.toString();
|
|
735
|
+
error += text;
|
|
736
|
+
console.log(`[${device.name}] STDERR: ${text.trim()}`);
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
child.on('close', (code) => {
|
|
740
|
+
|
|
741
|
+
if (code === 0) {
|
|
742
|
+
resolveDevice({ success: true, output, device: device.name });
|
|
743
|
+
} else {
|
|
744
|
+
resolveDevice({ success: false, error: error || output, device: device.name });
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
child.on('error', (err) => {
|
|
749
|
+
console.error(`[${device.name}] Process error:`, err);
|
|
750
|
+
resolveDevice({ success: false, error: err.message, device: device.name });
|
|
751
|
+
});
|
|
752
|
+
});
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
Promise.allSettled(devicePromises)
|
|
756
|
+
.then(results => {
|
|
757
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
758
|
+
|
|
759
|
+
const successCount = results.filter(r => r.status === 'fulfilled' && r.value.success).length;
|
|
760
|
+
const failCount = results.length - successCount;
|
|
761
|
+
|
|
762
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
763
|
+
|
|
764
|
+
resolve({ success: true, results });
|
|
765
|
+
})
|
|
766
|
+
.catch(error => {
|
|
767
|
+
console.error('Execution error:', error);
|
|
768
|
+
reject(error);
|
|
769
|
+
});
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
// AI-powered command conversion (supports multiple providers)
|
|
774
|
+
async function convertNaturalLanguageToCommand(text, devices, provider = null) {
|
|
775
|
+
// Determine platforms from devices
|
|
776
|
+
const deviceObjs = connectedDevices.filter(d => devices.includes(d.name));
|
|
777
|
+
|
|
778
|
+
if (deviceObjs.length === 0) {
|
|
779
|
+
// No devices found, try with null platform
|
|
780
|
+
return await aiManager.convertCommand(text, null, provider);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// Group devices by platform
|
|
784
|
+
const platforms = [...new Set(deviceObjs.map(d => d.platform))];
|
|
785
|
+
|
|
786
|
+
console.log(`AI converting for ${deviceObjs.length} device(s) across ${platforms.length} platform(s): ${platforms.join(', ')}`);
|
|
787
|
+
|
|
788
|
+
// For multi-platform, use 'both' to get generic app names
|
|
789
|
+
// The executeCommand function will resolve platform-specific package IDs
|
|
790
|
+
const platform = platforms.length === 1 ? platforms[0] : 'both';
|
|
791
|
+
|
|
792
|
+
console.log(`AI using platform mode: ${platform}`);
|
|
793
|
+
return await aiManager.convertCommand(text, platform, provider);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// Execute commands sequentially with WAIT support
|
|
797
|
+
async function executeCommandsSequentially(devices, commandsText, wsClient) {
|
|
798
|
+
const lines = commandsText.split('\n').map(line => line.trim()).filter(line => line);
|
|
799
|
+
|
|
800
|
+
console.log(`\n${'~'.repeat(60)}`);
|
|
801
|
+
|
|
802
|
+
console.log(`Total commands: ${lines.length}`);
|
|
803
|
+
console.log(`Commands:`, lines);
|
|
804
|
+
console.log(`${'~'.repeat(60)}\n`);
|
|
805
|
+
|
|
806
|
+
const results = [];
|
|
807
|
+
|
|
808
|
+
for (let i = 0; i < lines.length; i++) {
|
|
809
|
+
const line = lines[i];
|
|
810
|
+
|
|
811
|
+
// Skip comments
|
|
812
|
+
if (line.startsWith('#')) {
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// Check if it's a WAIT command
|
|
817
|
+
if (line.startsWith('WAIT ')) {
|
|
818
|
+
const waitTime = parseInt(line.replace('WAIT ', ''));
|
|
819
|
+
console.log(`ā³ Waiting ${waitTime}ms before next command...`);
|
|
820
|
+
|
|
821
|
+
if (wsClient) {
|
|
822
|
+
wsClient.send(JSON.stringify({
|
|
823
|
+
type: 'command_output',
|
|
824
|
+
data: `ā³ Waiting ${waitTime}ms...\n`,
|
|
825
|
+
devices: devices
|
|
826
|
+
}));
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
830
|
+
results.push({ command: line, success: true, output: `Waited ${waitTime}ms` });
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// Execute the command on ALL devices simultaneously
|
|
835
|
+
console.log(`\nā¶ļø Executing command ${i + 1}/${lines.length}: "${line}"`);
|
|
836
|
+
|
|
837
|
+
if (wsClient) {
|
|
838
|
+
wsClient.send(JSON.stringify({
|
|
839
|
+
type: 'command_output',
|
|
840
|
+
data: `ā¶ļø [${i + 1}/${lines.length}] ${line}\n`,
|
|
841
|
+
devices: devices
|
|
842
|
+
}));
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
try {
|
|
846
|
+
const result = await executeCommand(devices, line, wsClient);
|
|
847
|
+
results.push({ command: line, success: true, result });
|
|
848
|
+
console.log(`ā
Command ${i + 1} completed successfully`);
|
|
849
|
+
} catch (error) {
|
|
850
|
+
console.error(`ā Command ${i + 1} failed:`, error.message);
|
|
851
|
+
results.push({ command: line, success: false, error: error.message });
|
|
852
|
+
|
|
853
|
+
if (wsClient) {
|
|
854
|
+
wsClient.send(JSON.stringify({
|
|
855
|
+
type: 'command_output',
|
|
856
|
+
data: `ā Error: ${error.message}\n`,
|
|
857
|
+
devices: devices
|
|
858
|
+
}));
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
console.log(`\n${'~'.repeat(60)}`);
|
|
864
|
+
|
|
865
|
+
console.log(`Total: ${results.length}, Success: ${results.filter(r => r.success).length}, Failed: ${results.filter(r => !r.success).length}`);
|
|
866
|
+
console.log(`${'~'.repeat(60)}\n`);
|
|
867
|
+
|
|
868
|
+
return {
|
|
869
|
+
success: true,
|
|
870
|
+
results,
|
|
871
|
+
summary: `Executed ${results.length} commands`
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// Create WDA session for a device
|
|
876
|
+
async function createWDASession(host, deviceName) {
|
|
877
|
+
return new Promise(async (resolve) => {
|
|
878
|
+
const sessionFile = '/tmp/ios_multi_sessions';
|
|
879
|
+
|
|
880
|
+
// First, check if session already exists for this device
|
|
881
|
+
try {
|
|
882
|
+
const existingContent = await fs.readFile(sessionFile, 'utf-8').catch(() => '');
|
|
883
|
+
const lines = existingContent.split('\n').filter(line => line.trim());
|
|
884
|
+
|
|
885
|
+
for (const line of lines) {
|
|
886
|
+
const [name, sessionId] = line.split(':');
|
|
887
|
+
if (name === deviceName && sessionId) {
|
|
888
|
+
// Session already exists, verify it's still valid
|
|
889
|
+
const port = host === 'localhost' ? 8100 : 8100;
|
|
890
|
+
const verifyUrl = `http://${host}:${port}/session/${sessionId}`;
|
|
891
|
+
|
|
892
|
+
const verifyProcess = spawn('curl', ['-s', '-X', 'GET', verifyUrl]);
|
|
893
|
+
let verifyOutput = '';
|
|
894
|
+
|
|
895
|
+
verifyProcess.stdout.on('data', (data) => {
|
|
896
|
+
verifyOutput += data.toString();
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
verifyProcess.on('close', (code) => {
|
|
900
|
+
if (code === 0 && verifyOutput && !verifyOutput.includes('invalid session id')) {
|
|
901
|
+
console.log(`ā
Existing valid session found: ${sessionId}`);
|
|
902
|
+
return resolve({ success: true, sessionId, existing: true });
|
|
903
|
+
} else {
|
|
904
|
+
// Session is invalid, create a new one
|
|
905
|
+
createNewSession(host, deviceName, sessionFile, resolve);
|
|
906
|
+
}
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
} catch (e) {
|
|
913
|
+
// File doesn't exist or error reading, create new session
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// No existing session, create a new one
|
|
917
|
+
createNewSession(host, deviceName, sessionFile, resolve);
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
function createNewSession(host, deviceName, sessionFile, resolve) {
|
|
922
|
+
const port = host === 'localhost' ? 8100 : 8100;
|
|
923
|
+
const sessionUrl = `http://${host}:${port}/session`;
|
|
924
|
+
|
|
925
|
+
const curlProcess = spawn('curl', [
|
|
926
|
+
'-s',
|
|
927
|
+
'-X', 'POST',
|
|
928
|
+
sessionUrl,
|
|
929
|
+
'-H', 'Content-Type: application/json',
|
|
930
|
+
'-d', '{"capabilities":{"alwaysMatch":{}}}'
|
|
931
|
+
]);
|
|
932
|
+
|
|
933
|
+
let output = '';
|
|
934
|
+
curlProcess.stdout.on('data', (data) => {
|
|
935
|
+
output += data.toString();
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
curlProcess.on('close', (code) => {
|
|
939
|
+
if (code === 0 && output) {
|
|
940
|
+
try {
|
|
941
|
+
const response = JSON.parse(output);
|
|
942
|
+
const sessionId = response.sessionId || response.value?.sessionId;
|
|
943
|
+
|
|
944
|
+
if (sessionId) {
|
|
945
|
+
// Read existing sessions and update
|
|
946
|
+
fs.readFile(sessionFile, 'utf-8')
|
|
947
|
+
.catch(() => '')
|
|
948
|
+
.then(existingContent => {
|
|
949
|
+
// Remove old session for this device if exists
|
|
950
|
+
const lines = existingContent.split('\n').filter(line => {
|
|
951
|
+
const [name] = line.split(':');
|
|
952
|
+
return line.trim() && name !== deviceName;
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
// Add new session
|
|
956
|
+
lines.push(`${deviceName}:${sessionId}`);
|
|
957
|
+
|
|
958
|
+
// Write back to file
|
|
959
|
+
return fs.writeFile(sessionFile, lines.join('\n') + '\n');
|
|
960
|
+
})
|
|
961
|
+
.then(() => {
|
|
962
|
+
console.log(`ā
New session created and saved: ${sessionId}`);
|
|
963
|
+
resolve({ success: true, sessionId });
|
|
964
|
+
})
|
|
965
|
+
.catch((err) => {
|
|
966
|
+
console.error(`ā Failed to save session for ${deviceName}:`, err);
|
|
967
|
+
resolve({ success: false });
|
|
968
|
+
});
|
|
969
|
+
} else {
|
|
970
|
+
resolve({ success: false });
|
|
971
|
+
}
|
|
972
|
+
} catch (e) {
|
|
973
|
+
console.error('Failed to parse WDA session response:', e);
|
|
974
|
+
resolve({ success: false });
|
|
975
|
+
}
|
|
976
|
+
} else {
|
|
977
|
+
resolve({ success: false });
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
curlProcess.on('error', (err) => {
|
|
982
|
+
console.error('Error creating WDA session:', err);
|
|
983
|
+
resolve({ success: false });
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// Install UIAutomator2 on Android device
|
|
988
|
+
async function installUIAutomator2(deviceUdid, deviceName) {
|
|
989
|
+
return new Promise((resolve) => {
|
|
990
|
+
console.log(`š„ Installing UIAutomator2 on ${deviceName}...`);
|
|
991
|
+
|
|
992
|
+
const { execSync } = require('child_process');
|
|
993
|
+
const os = require('os');
|
|
994
|
+
const path = require('path');
|
|
995
|
+
|
|
996
|
+
try {
|
|
997
|
+
// Try multiple locations for APKs
|
|
998
|
+
const possiblePaths = [
|
|
999
|
+
// Appium installed location
|
|
1000
|
+
path.join(os.homedir(), '.appium', 'node_modules', 'appium-uiautomator2-driver', 'node_modules', 'appium-uiautomator2-server', 'apks'),
|
|
1001
|
+
// Global npm location
|
|
1002
|
+
execSync('npm root -g', { encoding: 'utf-8' }).trim() + '/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks',
|
|
1003
|
+
// Alternative npm location
|
|
1004
|
+
execSync('npm root -g', { encoding: 'utf-8' }).trim() + '/appium/node_modules/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks',
|
|
1005
|
+
];
|
|
1006
|
+
|
|
1007
|
+
let serverApk = null;
|
|
1008
|
+
let testApk = null;
|
|
1009
|
+
let foundPath = null;
|
|
1010
|
+
|
|
1011
|
+
// Try each path
|
|
1012
|
+
for (const apkPath of possiblePaths) {
|
|
1013
|
+
console.log(`š Checking: ${apkPath}`);
|
|
1014
|
+
|
|
1015
|
+
try {
|
|
1016
|
+
const serverCheck = execSync(`ls "${apkPath}"/appium-uiautomator2-server-v*.apk 2>/dev/null || echo ""`, { encoding: 'utf-8' }).trim();
|
|
1017
|
+
const testCheck = execSync(`ls "${apkPath}"/appium-uiautomator2-server-debug-androidTest.apk 2>/dev/null || echo ""`, { encoding: 'utf-8' }).trim();
|
|
1018
|
+
|
|
1019
|
+
if (serverCheck && testCheck) {
|
|
1020
|
+
serverApk = serverCheck;
|
|
1021
|
+
testApk = testCheck;
|
|
1022
|
+
foundPath = apkPath;
|
|
1023
|
+
console.log(`ā
Found APKs in: ${foundPath}`);
|
|
1024
|
+
break;
|
|
1025
|
+
}
|
|
1026
|
+
} catch (e) {
|
|
1027
|
+
continue;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
if (serverApk && testApk) {
|
|
1032
|
+
console.log(`š¦ Installing server APK: ${serverApk}`);
|
|
1033
|
+
const serverOutput = execSync(`adb -s ${deviceUdid} install -r "${serverApk}" 2>&1`, { encoding: 'utf-8' });
|
|
1034
|
+
console.log(serverOutput);
|
|
1035
|
+
|
|
1036
|
+
console.log(`š¦ Installing test APK: ${testApk}`);
|
|
1037
|
+
const testOutput = execSync(`adb -s ${deviceUdid} install -r "${testApk}" 2>&1`, { encoding: 'utf-8' });
|
|
1038
|
+
console.log(testOutput);
|
|
1039
|
+
|
|
1040
|
+
console.log(`ā
UIAutomator2 installed successfully on ${deviceName}`);
|
|
1041
|
+
resolve({
|
|
1042
|
+
success: true,
|
|
1043
|
+
message: 'UIAutomator2 installed successfully'
|
|
1044
|
+
});
|
|
1045
|
+
} else {
|
|
1046
|
+
console.log(`ā ļø APK files not found in any expected location`);
|
|
1047
|
+
console.log(`Tried paths:`, possiblePaths);
|
|
1048
|
+
|
|
1049
|
+
// Try using appium to install
|
|
1050
|
+
try {
|
|
1051
|
+
console.log(`š Trying to install via Appium...`);
|
|
1052
|
+
const appiumOutput = execSync(`appium driver install uiautomator2 2>&1`, { encoding: 'utf-8' });
|
|
1053
|
+
console.log(appiumOutput);
|
|
1054
|
+
|
|
1055
|
+
resolve({
|
|
1056
|
+
success: false,
|
|
1057
|
+
message: 'APKs not found. Tried to reinstall driver. Please run: appium driver install uiautomator2'
|
|
1058
|
+
});
|
|
1059
|
+
} catch (appiumError) {
|
|
1060
|
+
resolve({
|
|
1061
|
+
success: false,
|
|
1062
|
+
message: 'UIAutomator2 APKs not found. Please run: appium driver install uiautomator2'
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
} catch (error) {
|
|
1067
|
+
console.error(`ā Failed to install UIAutomator2: ${error.message}`);
|
|
1068
|
+
resolve({
|
|
1069
|
+
success: false,
|
|
1070
|
+
message: `Failed to install UIAutomator2: ${error.message}`
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// Connect to device - starts WDA if needed
|
|
1077
|
+
async function connectToDevice(device) {
|
|
1078
|
+
return new Promise(async (resolve, reject) => {
|
|
1079
|
+
const { name, udid, type, ip, platform } = device;
|
|
1080
|
+
|
|
1081
|
+
console.log(`Connecting to ${name} (${type}, platform: ${platform})...`);
|
|
1082
|
+
|
|
1083
|
+
// Handle Android devices differently
|
|
1084
|
+
if (platform === 'android') {
|
|
1085
|
+
console.log(`š± Android device detected: ${name}`);
|
|
1086
|
+
|
|
1087
|
+
// Check if device is connected via adb
|
|
1088
|
+
const checkAdb = spawn('adb', ['devices']);
|
|
1089
|
+
let output = '';
|
|
1090
|
+
|
|
1091
|
+
checkAdb.stdout.on('data', (data) => {
|
|
1092
|
+
output += data.toString();
|
|
1093
|
+
});
|
|
1094
|
+
|
|
1095
|
+
checkAdb.on('close', async (code) => {
|
|
1096
|
+
const deviceConnected = output.includes(udid.replace(':5555', '')) || output.includes(udid);
|
|
1097
|
+
|
|
1098
|
+
if (deviceConnected) {
|
|
1099
|
+
console.log(`ā
Android device ${name} is connected via ADB`);
|
|
1100
|
+
|
|
1101
|
+
// Don't set status to 'online' yet - wait for UIAutomator2 confirmation
|
|
1102
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1103
|
+
if (deviceIndex !== -1) {
|
|
1104
|
+
connectedDevices[deviceIndex].status = 'connecting';
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
// Broadcast connecting status
|
|
1108
|
+
wss.clients.forEach(client => {
|
|
1109
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1110
|
+
client.send(JSON.stringify({
|
|
1111
|
+
type: 'devices_updated',
|
|
1112
|
+
devices: connectedDevices
|
|
1113
|
+
}));
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
|
|
1117
|
+
// Always ensure UIAutomator2 is installed and ready
|
|
1118
|
+
console.log(`š¦ Ensuring UIAutomator2 is installed on ${name}...`);
|
|
1119
|
+
|
|
1120
|
+
// Check if already installed
|
|
1121
|
+
const checkUiAutomator = spawn('adb', ['-s', udid, 'shell', 'pm', 'list', 'packages', 'io.appium.uiautomator2']);
|
|
1122
|
+
let uiautomatorOutput = '';
|
|
1123
|
+
|
|
1124
|
+
checkUiAutomator.stdout.on('data', (data) => {
|
|
1125
|
+
uiautomatorOutput += data.toString();
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
checkUiAutomator.on('close', async () => {
|
|
1129
|
+
const isInstalled = uiautomatorOutput.includes('io.appium.uiautomator2');
|
|
1130
|
+
|
|
1131
|
+
if (!isInstalled) {
|
|
1132
|
+
console.log(`š„ UIAutomator2 not found on ${name}, installing...`);
|
|
1133
|
+
// Install UIAutomator2
|
|
1134
|
+
const installResult = await installUIAutomator2(udid, name);
|
|
1135
|
+
|
|
1136
|
+
if (!installResult.success) {
|
|
1137
|
+
console.log(`ā ļø UIAutomator2 installation failed on ${name}`);
|
|
1138
|
+
resolve({
|
|
1139
|
+
success: true,
|
|
1140
|
+
message: `Connected to ${name} - ADB Ready ā
`
|
|
1141
|
+
});
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
} else {
|
|
1145
|
+
console.log(`ā
UIAutomator2 already installed on ${name}`);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
// Check if session already exists for this device
|
|
1149
|
+
const existingSession = androidSessions.get(udid);
|
|
1150
|
+
if (existingSession) {
|
|
1151
|
+
console.log(`ā»ļø Reusing existing UIAutomator2 session on ${name} (port: ${existingSession.port})`);
|
|
1152
|
+
|
|
1153
|
+
// Verify session is still valid
|
|
1154
|
+
try {
|
|
1155
|
+
const axios = require('axios');
|
|
1156
|
+
await axios.get(`http://localhost:${existingSession.port}/wd/hub/status`);
|
|
1157
|
+
console.log(`ā
Session verified and working on ${name}`);
|
|
1158
|
+
|
|
1159
|
+
// Set status to 'online'
|
|
1160
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1161
|
+
if (deviceIndex !== -1) {
|
|
1162
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1163
|
+
|
|
1164
|
+
// Broadcast updated status
|
|
1165
|
+
wss.clients.forEach(client => {
|
|
1166
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1167
|
+
client.send(JSON.stringify({
|
|
1168
|
+
type: 'devices_updated',
|
|
1169
|
+
devices: connectedDevices
|
|
1170
|
+
}));
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
resolve({
|
|
1176
|
+
success: true,
|
|
1177
|
+
message: `Connected to ${name} - UIAutomator2 Ready ā
`
|
|
1178
|
+
});
|
|
1179
|
+
return;
|
|
1180
|
+
} catch (err) {
|
|
1181
|
+
console.log(`ā ļø Existing session invalid, creating new one for ${name}`);
|
|
1182
|
+
androidSessions.delete(udid);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
// Start new UIAutomator2 session
|
|
1187
|
+
console.log(`š Starting new UIAutomator2 session on ${name}...`);
|
|
1188
|
+
const sessionResult = await startUIAutomator2Session(udid, name);
|
|
1189
|
+
|
|
1190
|
+
if (sessionResult.success) {
|
|
1191
|
+
// Set status to 'online' only after UIAutomator2 is ready
|
|
1192
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1193
|
+
if (deviceIndex !== -1) {
|
|
1194
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1195
|
+
|
|
1196
|
+
// Broadcast updated status
|
|
1197
|
+
wss.clients.forEach(client => {
|
|
1198
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1199
|
+
client.send(JSON.stringify({
|
|
1200
|
+
type: 'devices_updated',
|
|
1201
|
+
devices: connectedDevices
|
|
1202
|
+
}));
|
|
1203
|
+
}
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
resolve({
|
|
1208
|
+
success: true,
|
|
1209
|
+
message: `Connected to ${name} - UIAutomator2 Ready ā
`
|
|
1210
|
+
});
|
|
1211
|
+
} else {
|
|
1212
|
+
resolve({
|
|
1213
|
+
success: true,
|
|
1214
|
+
message: `Connected to ${name} - ADB Ready ā
`
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
});
|
|
1218
|
+
} else {
|
|
1219
|
+
console.log(`ā Android device ${name} not found in ADB`);
|
|
1220
|
+
|
|
1221
|
+
// If wireless, try to connect via adb
|
|
1222
|
+
if (type === 'wireless' && ip) {
|
|
1223
|
+
console.log(`š” Attempting to connect to ${name} wirelessly at ${ip}:5555...`);
|
|
1224
|
+
const adbConnect = spawn('adb', ['connect', `${ip}:5555`]);
|
|
1225
|
+
|
|
1226
|
+
adbConnect.on('close', async (code) => {
|
|
1227
|
+
if (code === 0) {
|
|
1228
|
+
console.log(`ā
Connected to ${name} wirelessly`);
|
|
1229
|
+
|
|
1230
|
+
// Don't set status yet - wait for UIAutomator2
|
|
1231
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1232
|
+
if (deviceIndex !== -1) {
|
|
1233
|
+
connectedDevices[deviceIndex].status = 'connecting';
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// Always ensure UIAutomator2 is installed
|
|
1237
|
+
console.log(`š¦ Ensuring UIAutomator2 is installed on ${name}...`);
|
|
1238
|
+
|
|
1239
|
+
// Check if already installed
|
|
1240
|
+
const checkUiAutomator = spawn('adb', ['-s', `${ip}:5555`, 'shell', 'pm', 'list', 'packages', 'io.appium.uiautomator2']);
|
|
1241
|
+
let uiautomatorOutput = '';
|
|
1242
|
+
|
|
1243
|
+
checkUiAutomator.stdout.on('data', (data) => {
|
|
1244
|
+
uiautomatorOutput += data.toString();
|
|
1245
|
+
});
|
|
1246
|
+
|
|
1247
|
+
checkUiAutomator.on('close', async () => {
|
|
1248
|
+
const isInstalled = uiautomatorOutput.includes('io.appium.uiautomator2');
|
|
1249
|
+
|
|
1250
|
+
if (!isInstalled) {
|
|
1251
|
+
console.log(`š„ UIAutomator2 not found on ${name}, installing...`);
|
|
1252
|
+
const installResult = await installUIAutomator2(`${ip}:5555`, name);
|
|
1253
|
+
if (!installResult.success) {
|
|
1254
|
+
console.log(`ā ļø UIAutomator2 installation failed on ${name}`);
|
|
1255
|
+
}
|
|
1256
|
+
} else {
|
|
1257
|
+
console.log(`ā
UIAutomator2 already installed on ${name}`);
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
// Check if session already exists for this device
|
|
1261
|
+
const existingSession = androidSessions.get(`${ip}:5555`);
|
|
1262
|
+
if (existingSession) {
|
|
1263
|
+
console.log(`ā»ļø Reusing existing UIAutomator2 session on ${name} (port: ${existingSession.port})`);
|
|
1264
|
+
|
|
1265
|
+
// Verify session is still valid
|
|
1266
|
+
try {
|
|
1267
|
+
const axios = require('axios');
|
|
1268
|
+
await axios.get(`http://localhost:${existingSession.port}/wd/hub/status`);
|
|
1269
|
+
console.log(`ā
Session verified and working on ${name}`);
|
|
1270
|
+
|
|
1271
|
+
// Set status to 'online'
|
|
1272
|
+
if (deviceIndex !== -1) {
|
|
1273
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1274
|
+
|
|
1275
|
+
// Broadcast updated status
|
|
1276
|
+
wss.clients.forEach(client => {
|
|
1277
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1278
|
+
client.send(JSON.stringify({
|
|
1279
|
+
type: 'devices_updated',
|
|
1280
|
+
devices: connectedDevices
|
|
1281
|
+
}));
|
|
1282
|
+
}
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
resolve({
|
|
1287
|
+
success: true,
|
|
1288
|
+
message: `Connected to ${name} - UIAutomator2 Ready ā
`
|
|
1289
|
+
});
|
|
1290
|
+
return;
|
|
1291
|
+
} catch (err) {
|
|
1292
|
+
console.log(`ā ļø Existing session invalid, creating new one for ${name}`);
|
|
1293
|
+
androidSessions.delete(`${ip}:5555`);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
// Start new UIAutomator2 session
|
|
1298
|
+
console.log(`š Starting new UIAutomator2 session on ${name}...`);
|
|
1299
|
+
const sessionResult = await startUIAutomator2Session(`${ip}:5555`, name);
|
|
1300
|
+
|
|
1301
|
+
let message = '';
|
|
1302
|
+
if (sessionResult.success) {
|
|
1303
|
+
// Now set status to 'online' after UIAutomator2 is ready
|
|
1304
|
+
if (deviceIndex !== -1) {
|
|
1305
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1306
|
+
|
|
1307
|
+
// Broadcast updated status
|
|
1308
|
+
wss.clients.forEach(client => {
|
|
1309
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1310
|
+
client.send(JSON.stringify({
|
|
1311
|
+
type: 'devices_updated',
|
|
1312
|
+
devices: connectedDevices
|
|
1313
|
+
}));
|
|
1314
|
+
}
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
message = `Connected to ${name} - UIAutomator2 Ready ā
`;
|
|
1319
|
+
} else {
|
|
1320
|
+
message = `Connected to ${name} - ADB Ready ā
`;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
resolve({
|
|
1324
|
+
success: true,
|
|
1325
|
+
message: message
|
|
1326
|
+
});
|
|
1327
|
+
});
|
|
1328
|
+
} else {
|
|
1329
|
+
reject({
|
|
1330
|
+
success: false,
|
|
1331
|
+
message: `Failed to connect to ${name}. Make sure USB debugging is enabled and device is on the same network.`
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
});
|
|
1335
|
+
} else {
|
|
1336
|
+
reject({
|
|
1337
|
+
success: false,
|
|
1338
|
+
message: `Android device ${name} not connected. Please connect via USB or enable wireless debugging.`
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
});
|
|
1343
|
+
|
|
1344
|
+
checkAdb.on('error', (err) => {
|
|
1345
|
+
console.error(`ā ADB error: ${err.message}`);
|
|
1346
|
+
reject({
|
|
1347
|
+
success: false,
|
|
1348
|
+
message: `ADB not available. Please install Android SDK Platform-Tools.`
|
|
1349
|
+
});
|
|
1350
|
+
});
|
|
1351
|
+
|
|
1352
|
+
return; // Exit early for Android devices
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
// iOS device handling continues below
|
|
1356
|
+
if (type === 'usb') {
|
|
1357
|
+
// For USB devices, check if WDA is already running
|
|
1358
|
+
const checkWDA = spawn('curl', [
|
|
1359
|
+
'-s',
|
|
1360
|
+
'--connect-timeout', '2',
|
|
1361
|
+
'http://localhost:8100/status'
|
|
1362
|
+
]);
|
|
1363
|
+
|
|
1364
|
+
let output = '';
|
|
1365
|
+
checkWDA.stdout.on('data', (data) => {
|
|
1366
|
+
output += data.toString();
|
|
1367
|
+
});
|
|
1368
|
+
|
|
1369
|
+
checkWDA.on('error', (err) => {
|
|
1370
|
+
console.error(`ā Error checking WDA: ${err.message}`);
|
|
1371
|
+
reject({ success: false, message: `Failed to check WDA status: ${err.message}` });
|
|
1372
|
+
});
|
|
1373
|
+
|
|
1374
|
+
checkWDA.on('close', async (code) => {
|
|
1375
|
+
if (output.includes('"state"')) {
|
|
1376
|
+
console.log(`ā
WDA already running for ${name}`);
|
|
1377
|
+
|
|
1378
|
+
// Create WDA session if not exists
|
|
1379
|
+
console.log(`š± Creating WDA session for ${name}...`);
|
|
1380
|
+
const sessionResult = await createWDASession('localhost', name);
|
|
1381
|
+
|
|
1382
|
+
if (sessionResult.success) {
|
|
1383
|
+
console.log(`ā
Session created: ${sessionResult.sessionId}`);
|
|
1384
|
+
} else {
|
|
1385
|
+
console.log(`ā ļø Session creation failed, will be created on first command`);
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
// Update status to online
|
|
1389
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1390
|
+
if (deviceIndex !== -1) {
|
|
1391
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
// Broadcast updated device list
|
|
1395
|
+
wss.clients.forEach(client => {
|
|
1396
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1397
|
+
client.send(JSON.stringify({
|
|
1398
|
+
type: 'devices_updated',
|
|
1399
|
+
devices: connectedDevices
|
|
1400
|
+
}));
|
|
1401
|
+
}
|
|
1402
|
+
});
|
|
1403
|
+
|
|
1404
|
+
resolve({ success: true, message: `Connected to ${name} - WDA Ready ā
` });
|
|
1405
|
+
} else {
|
|
1406
|
+
console.log(`š Starting WDA for ${name} (UDID: ${udid})...`);
|
|
1407
|
+
|
|
1408
|
+
// Start WDA using xcodebuild
|
|
1409
|
+
// First, check if we have WebDriverAgent path
|
|
1410
|
+
const wdaPath = process.env.WDA_PATH || path.join(process.env.HOME, 'Downloads/WebDriverAgent-10.2.1');
|
|
1411
|
+
|
|
1412
|
+
console.log(`š WDA Path: ${wdaPath}`);
|
|
1413
|
+
console.log(`š± Device UDID: ${udid}`);
|
|
1414
|
+
|
|
1415
|
+
// Start xcodebuild in background with piped output for debugging
|
|
1416
|
+
const wdaProcess = spawn('xcodebuild', [
|
|
1417
|
+
'test',
|
|
1418
|
+
'-project', path.join(wdaPath, 'WebDriverAgent.xcodeproj'),
|
|
1419
|
+
'-scheme', 'WebDriverAgentRunner',
|
|
1420
|
+
'-destination', `id=${udid}`,
|
|
1421
|
+
'IPHONEOS_DEPLOYMENT_TARGET=14.0'
|
|
1422
|
+
], {
|
|
1423
|
+
cwd: wdaPath,
|
|
1424
|
+
detached: true,
|
|
1425
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
1426
|
+
});
|
|
1427
|
+
|
|
1428
|
+
// Log output for debugging
|
|
1429
|
+
wdaProcess.stdout.on('data', (data) => {
|
|
1430
|
+
const output = data.toString();
|
|
1431
|
+
if (output.includes('ServerURLHere') || output.includes('WebDriverAgent')) {
|
|
1432
|
+
console.log(`š± WDA: ${output.trim()}`);
|
|
1433
|
+
}
|
|
1434
|
+
});
|
|
1435
|
+
|
|
1436
|
+
wdaProcess.stderr.on('data', (data) => {
|
|
1437
|
+
const error = data.toString();
|
|
1438
|
+
if (!error.includes('note:') && !error.includes('warning:')) {
|
|
1439
|
+
console.error(`ā ļø WDA Error: ${error.trim()}`);
|
|
1440
|
+
}
|
|
1441
|
+
});
|
|
1442
|
+
|
|
1443
|
+
wdaProcess.on('error', (err) => {
|
|
1444
|
+
console.error(`ā Failed to start xcodebuild: ${err.message}`);
|
|
1445
|
+
});
|
|
1446
|
+
|
|
1447
|
+
wdaProcess.unref();
|
|
1448
|
+
|
|
1449
|
+
// Also start iproxy to forward port
|
|
1450
|
+
console.log(`š Starting iproxy for port forwarding...`);
|
|
1451
|
+
const iproxyProcess = spawn('iproxy', ['8100', '8100'], {
|
|
1452
|
+
detached: true,
|
|
1453
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
1454
|
+
});
|
|
1455
|
+
|
|
1456
|
+
iproxyProcess.stdout.on('data', (data) => {
|
|
1457
|
+
console.log(`š iproxy: ${data.toString().trim()}`);
|
|
1458
|
+
});
|
|
1459
|
+
|
|
1460
|
+
iproxyProcess.on('error', (err) => {
|
|
1461
|
+
console.error(`ā Failed to start iproxy: ${err.message}`);
|
|
1462
|
+
console.error(` Make sure libimobiledevice is installed: brew install libimobiledevice`);
|
|
1463
|
+
});
|
|
1464
|
+
|
|
1465
|
+
iproxyProcess.unref();
|
|
1466
|
+
|
|
1467
|
+
// Track WDA processes for cleanup on disconnect
|
|
1468
|
+
wdaProcesses.set(name, {
|
|
1469
|
+
xcodebuild: wdaProcess.pid,
|
|
1470
|
+
iproxy: iproxyProcess.pid
|
|
1471
|
+
});
|
|
1472
|
+
|
|
1473
|
+
console.log(`ā
WDA starting for ${name}. Process ID: ${wdaProcess.pid}`);
|
|
1474
|
+
|
|
1475
|
+
// Wait a bit for WDA to start, then verify
|
|
1476
|
+
setTimeout(() => {
|
|
1477
|
+
const verifyWDA = spawn('curl', [
|
|
1478
|
+
'-s',
|
|
1479
|
+
'--connect-timeout', '5',
|
|
1480
|
+
'http://localhost:8100/status'
|
|
1481
|
+
]);
|
|
1482
|
+
|
|
1483
|
+
let verifyOutput = '';
|
|
1484
|
+
verifyWDA.stdout.on('data', (data) => {
|
|
1485
|
+
verifyOutput += data.toString();
|
|
1486
|
+
});
|
|
1487
|
+
|
|
1488
|
+
verifyWDA.on('close', async () => {
|
|
1489
|
+
if (verifyOutput.includes('"state"')) {
|
|
1490
|
+
console.log(`ā
WDA successfully started for ${name}`);
|
|
1491
|
+
|
|
1492
|
+
// Create WDA session for USB device
|
|
1493
|
+
console.log(`š± Creating WDA session for ${name}...`);
|
|
1494
|
+
const sessionResult = await createWDASession('localhost', name);
|
|
1495
|
+
|
|
1496
|
+
if (sessionResult.success) {
|
|
1497
|
+
console.log(`ā
Session created: ${sessionResult.sessionId}`);
|
|
1498
|
+
} else {
|
|
1499
|
+
console.log(`ā ļø Session creation failed, will be created on first command`);
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
// Update device status to online in connectedDevices
|
|
1503
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1504
|
+
if (deviceIndex !== -1) {
|
|
1505
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
// Broadcast updated device list and connection status to all WebSocket clients
|
|
1509
|
+
wss.clients.forEach(client => {
|
|
1510
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1511
|
+
client.send(JSON.stringify({
|
|
1512
|
+
type: 'devices_updated',
|
|
1513
|
+
devices: connectedDevices
|
|
1514
|
+
}));
|
|
1515
|
+
// Send connection complete message
|
|
1516
|
+
client.send(JSON.stringify({
|
|
1517
|
+
type: 'command_output',
|
|
1518
|
+
output: `ā
${name} connected - WDA Ready!\n${'ā'.repeat(50)}\n`,
|
|
1519
|
+
device: name
|
|
1520
|
+
}));
|
|
1521
|
+
}
|
|
1522
|
+
});
|
|
1523
|
+
} else {
|
|
1524
|
+
console.log(`ā ļø WDA still starting for ${name}...`);
|
|
1525
|
+
}
|
|
1526
|
+
});
|
|
1527
|
+
}, 8000); // Wait 8 seconds for WDA to start
|
|
1528
|
+
|
|
1529
|
+
// Return immediately with starting status
|
|
1530
|
+
resolve({
|
|
1531
|
+
success: true,
|
|
1532
|
+
message: `Connecting to ${name} - Starting WDA...`,
|
|
1533
|
+
wdaStarting: true
|
|
1534
|
+
});
|
|
1535
|
+
}
|
|
1536
|
+
});
|
|
1537
|
+
|
|
1538
|
+
checkWDA.on('error', () => {
|
|
1539
|
+
console.log(`ā ļø Could not check WDA status, attempting to start...`);
|
|
1540
|
+
resolve({ success: false, message: `Error checking WDA. Please start manually in Xcode.` });
|
|
1541
|
+
});
|
|
1542
|
+
} else {
|
|
1543
|
+
// For wireless devices, check if WDA is reachable
|
|
1544
|
+
const checkWDA = spawn('curl', [
|
|
1545
|
+
'-s',
|
|
1546
|
+
'--connect-timeout', '3',
|
|
1547
|
+
`http://${ip}:8100/status`
|
|
1548
|
+
]);
|
|
1549
|
+
|
|
1550
|
+
let output = '';
|
|
1551
|
+
checkWDA.stdout.on('data', (data) => {
|
|
1552
|
+
output += data.toString();
|
|
1553
|
+
});
|
|
1554
|
+
|
|
1555
|
+
checkWDA.on('close', async () => {
|
|
1556
|
+
if (output.includes('"state"')) {
|
|
1557
|
+
console.log(`ā
WDA reachable for ${name}`);
|
|
1558
|
+
|
|
1559
|
+
// Create WDA session for wireless device
|
|
1560
|
+
console.log(`š± Creating WDA session for ${name}...`);
|
|
1561
|
+
const sessionResult = await createWDASession(ip, name);
|
|
1562
|
+
|
|
1563
|
+
if (sessionResult.success) {
|
|
1564
|
+
console.log(`ā
Session created: ${sessionResult.sessionId}`);
|
|
1565
|
+
} else {
|
|
1566
|
+
console.log(`ā ļø Session creation failed, will be created on first command`);
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
// Update status to online
|
|
1570
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1571
|
+
if (deviceIndex !== -1) {
|
|
1572
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
// Broadcast updated device list
|
|
1576
|
+
wss.clients.forEach(client => {
|
|
1577
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1578
|
+
client.send(JSON.stringify({
|
|
1579
|
+
type: 'devices_updated',
|
|
1580
|
+
devices: connectedDevices
|
|
1581
|
+
}));
|
|
1582
|
+
}
|
|
1583
|
+
});
|
|
1584
|
+
|
|
1585
|
+
resolve({ success: true, message: `Connected to ${name} - WDA Ready ā
` });
|
|
1586
|
+
} else {
|
|
1587
|
+
console.log(`ā WDA not running on ${name}, attempting to start...`);
|
|
1588
|
+
|
|
1589
|
+
// Start WDA wirelessly using xcodebuild
|
|
1590
|
+
const wdaPath = process.env.WDA_PATH || path.join(process.env.HOME, 'Downloads/WebDriverAgent-10.2.1');
|
|
1591
|
+
|
|
1592
|
+
console.log(`š WDA Path: ${wdaPath}`);
|
|
1593
|
+
console.log(`š± Device UDID: ${udid}`);
|
|
1594
|
+
console.log(`š” Device IP: ${ip}`);
|
|
1595
|
+
|
|
1596
|
+
// Start xcodebuild in background for wireless device
|
|
1597
|
+
const wdaProcess = spawn('xcodebuild', [
|
|
1598
|
+
'test',
|
|
1599
|
+
'-project', path.join(wdaPath, 'WebDriverAgent.xcodeproj'),
|
|
1600
|
+
'-scheme', 'WebDriverAgentRunner',
|
|
1601
|
+
'-destination', `id=${udid}`,
|
|
1602
|
+
'IPHONEOS_DEPLOYMENT_TARGET=14.0'
|
|
1603
|
+
], {
|
|
1604
|
+
cwd: wdaPath,
|
|
1605
|
+
detached: true,
|
|
1606
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
1607
|
+
});
|
|
1608
|
+
|
|
1609
|
+
// Log output for debugging
|
|
1610
|
+
wdaProcess.stdout.on('data', (data) => {
|
|
1611
|
+
const output = data.toString();
|
|
1612
|
+
if (output.includes('ServerURLHere') || output.includes('WebDriverAgent')) {
|
|
1613
|
+
console.log(`š± WDA (${name}): ${output.trim()}`);
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
1616
|
+
|
|
1617
|
+
wdaProcess.stderr.on('data', (data) => {
|
|
1618
|
+
const error = data.toString();
|
|
1619
|
+
if (!error.includes('note:') && !error.includes('warning:')) {
|
|
1620
|
+
console.error(`ā ļø WDA Error (${name}): ${error.trim()}`);
|
|
1621
|
+
}
|
|
1622
|
+
});
|
|
1623
|
+
|
|
1624
|
+
wdaProcess.on('error', (err) => {
|
|
1625
|
+
console.error(`ā Failed to start xcodebuild for ${name}: ${err.message}`);
|
|
1626
|
+
});
|
|
1627
|
+
|
|
1628
|
+
wdaProcess.unref();
|
|
1629
|
+
|
|
1630
|
+
// Track WDA process for cleanup on disconnect
|
|
1631
|
+
wdaProcesses.set(name, {
|
|
1632
|
+
xcodebuild: wdaProcess.pid
|
|
1633
|
+
});
|
|
1634
|
+
|
|
1635
|
+
console.log(`ā
WDA starting for ${name} (wireless). Process ID: ${wdaProcess.pid}`);
|
|
1636
|
+
|
|
1637
|
+
// Wait for WDA to start, then verify
|
|
1638
|
+
setTimeout(() => {
|
|
1639
|
+
const verifyWDA = spawn('curl', [
|
|
1640
|
+
'-s',
|
|
1641
|
+
'--connect-timeout', '5',
|
|
1642
|
+
`http://${ip}:8100/status`
|
|
1643
|
+
]);
|
|
1644
|
+
|
|
1645
|
+
let verifyOutput = '';
|
|
1646
|
+
verifyWDA.stdout.on('data', (data) => {
|
|
1647
|
+
verifyOutput += data.toString();
|
|
1648
|
+
});
|
|
1649
|
+
|
|
1650
|
+
verifyWDA.on('close', async () => {
|
|
1651
|
+
if (verifyOutput.includes('"state"')) {
|
|
1652
|
+
console.log(`ā
WDA successfully started for ${name}`);
|
|
1653
|
+
|
|
1654
|
+
// Create WDA session for wireless device
|
|
1655
|
+
console.log(`š± Creating WDA session for ${name}...`);
|
|
1656
|
+
const sessionResult = await createWDASession(ip, name);
|
|
1657
|
+
|
|
1658
|
+
if (sessionResult.success) {
|
|
1659
|
+
console.log(`ā
Session created: ${sessionResult.sessionId}`);
|
|
1660
|
+
} else {
|
|
1661
|
+
console.log(`ā ļø Session creation failed, will be created on first command`);
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
// Update device status to online
|
|
1665
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1666
|
+
if (deviceIndex !== -1) {
|
|
1667
|
+
connectedDevices[deviceIndex].status = 'online';
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
// Broadcast updated device list
|
|
1671
|
+
wss.clients.forEach(client => {
|
|
1672
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1673
|
+
client.send(JSON.stringify({
|
|
1674
|
+
type: 'devices_updated',
|
|
1675
|
+
devices: connectedDevices
|
|
1676
|
+
}));
|
|
1677
|
+
}
|
|
1678
|
+
});
|
|
1679
|
+
|
|
1680
|
+
resolve({
|
|
1681
|
+
success: true,
|
|
1682
|
+
message: `Connected to ${name} via WiFi - WDA Started!`,
|
|
1683
|
+
wdaStarted: true
|
|
1684
|
+
});
|
|
1685
|
+
} else {
|
|
1686
|
+
console.log(`ā ļø WDA starting for ${name}, may take a moment...`);
|
|
1687
|
+
resolve({
|
|
1688
|
+
success: true,
|
|
1689
|
+
message: `WDA is starting for ${name}. Please wait 10-15 seconds...`,
|
|
1690
|
+
wdaStarting: true
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
});
|
|
1694
|
+
}, 10000); // Wait 10 seconds for wireless WDA to start
|
|
1695
|
+
}
|
|
1696
|
+
});
|
|
1697
|
+
|
|
1698
|
+
checkWDA.on('error', () => {
|
|
1699
|
+
console.log(`ā ļø Cannot reach ${name} at ${ip}. Check network connection.`);
|
|
1700
|
+
reject({ success: false, message: `Cannot reach ${name} at ${ip}. Check network connection.` });
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
});
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
// Disconnect from device
|
|
1707
|
+
async function disconnectFromDevice(device) {
|
|
1708
|
+
return new Promise((resolve, reject) => {
|
|
1709
|
+
const { name, connectionType, udid, platform } = device;
|
|
1710
|
+
console.log(`š Disconnecting from ${name} (${connectionType}, platform: ${platform})...`);
|
|
1711
|
+
|
|
1712
|
+
// Handle Android devices
|
|
1713
|
+
if (platform === 'android') {
|
|
1714
|
+
console.log(`š± Android device disconnect: ${name}`);
|
|
1715
|
+
|
|
1716
|
+
// Stop UIAutomator2 session first
|
|
1717
|
+
stopUIAutomator2Session(udid, name).catch(err => {
|
|
1718
|
+
console.error(`Error stopping UIAutomator2 session: ${err.message}`);
|
|
1719
|
+
});
|
|
1720
|
+
|
|
1721
|
+
// For wireless Android devices, disconnect adb
|
|
1722
|
+
if (connectionType === 'wireless') {
|
|
1723
|
+
const adbDisconnect = spawn('adb', ['disconnect', udid]);
|
|
1724
|
+
|
|
1725
|
+
adbDisconnect.on('close', (code) => {
|
|
1726
|
+
console.log(`ā
Disconnected Android device ${name} from ADB`);
|
|
1727
|
+
|
|
1728
|
+
// Update device status
|
|
1729
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1730
|
+
if (deviceIndex !== -1) {
|
|
1731
|
+
connectedDevices[deviceIndex].status = 'offline';
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
// Broadcast update
|
|
1735
|
+
wss.clients.forEach(client => {
|
|
1736
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1737
|
+
client.send(JSON.stringify({
|
|
1738
|
+
type: 'devices_updated',
|
|
1739
|
+
devices: connectedDevices
|
|
1740
|
+
}));
|
|
1741
|
+
}
|
|
1742
|
+
});
|
|
1743
|
+
|
|
1744
|
+
resolve({
|
|
1745
|
+
success: true,
|
|
1746
|
+
message: `Disconnected from ${name} - ADB disconnected`
|
|
1747
|
+
});
|
|
1748
|
+
});
|
|
1749
|
+
} else {
|
|
1750
|
+
// For USB Android devices, just update status
|
|
1751
|
+
|
|
1752
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1753
|
+
if (deviceIndex !== -1) {
|
|
1754
|
+
connectedDevices[deviceIndex].status = 'offline';
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
// Broadcast update
|
|
1758
|
+
wss.clients.forEach(client => {
|
|
1759
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1760
|
+
client.send(JSON.stringify({
|
|
1761
|
+
type: 'devices_updated',
|
|
1762
|
+
devices: connectedDevices
|
|
1763
|
+
}));
|
|
1764
|
+
}
|
|
1765
|
+
});
|
|
1766
|
+
|
|
1767
|
+
resolve({
|
|
1768
|
+
success: true,
|
|
1769
|
+
message: `Disconnected from ${name}`
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
return; // Exit early for Android
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
// iOS device handling - Find the device in connectedDevices to get its port
|
|
1777
|
+
const deviceInfo = connectedDevices.find(d => d.name === name);
|
|
1778
|
+
const port = deviceInfo?.port;
|
|
1779
|
+
|
|
1780
|
+
// Strategy 1: Kill WDA processes tracked in wdaProcesses Map
|
|
1781
|
+
if (wdaProcesses.has(name)) {
|
|
1782
|
+
const processes = wdaProcesses.get(name);
|
|
1783
|
+
|
|
1784
|
+
try {
|
|
1785
|
+
if (processes.xcodebuild) {
|
|
1786
|
+
try {
|
|
1787
|
+
process.kill(processes.xcodebuild, 'SIGTERM');
|
|
1788
|
+
console.log(`ā
Killed xcodebuild for ${name} (PID: ${processes.xcodebuild})`);
|
|
1789
|
+
} catch (e) {
|
|
1790
|
+
console.log(`ā ļø xcodebuild process ${processes.xcodebuild} already stopped`);
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
if (processes.iproxy) {
|
|
1795
|
+
try {
|
|
1796
|
+
process.kill(processes.iproxy, 'SIGTERM');
|
|
1797
|
+
console.log(`ā
Killed iproxy for ${name} (PID: ${processes.iproxy})`);
|
|
1798
|
+
} catch (e) {
|
|
1799
|
+
console.log(`ā ļø iproxy process ${processes.iproxy} already stopped`);
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
wdaProcesses.delete(name);
|
|
1804
|
+
} catch (error) {
|
|
1805
|
+
console.error(`Error cleaning up tracked processes for ${name}:`, error);
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
// Strategy 2: Kill processes by port (works for script-started WDA too)
|
|
1810
|
+
if (port) {
|
|
1811
|
+
console.log(`š Killing processes on port ${port} for ${name}...`);
|
|
1812
|
+
const killPort = spawn('sh', ['-c', `lsof -ti:${port} | xargs kill -9 2>/dev/null || true`]);
|
|
1813
|
+
|
|
1814
|
+
killPort.on('close', () => {
|
|
1815
|
+
console.log(`ā
Cleaned up port ${port} for ${name}`);
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
// Strategy 3: Kill xcodebuild processes for this specific UDID
|
|
1820
|
+
if (udid && connectionType === 'usb') {
|
|
1821
|
+
console.log(`š Killing WDA for UDID ${udid}...`);
|
|
1822
|
+
const killWDA = spawn('sh', ['-c', `pkill -f "xcodebuild.*${udid}" || true`]);
|
|
1823
|
+
|
|
1824
|
+
killWDA.on('close', () => {
|
|
1825
|
+
console.log(`ā
Cleaned up WDA processes for ${name}`);
|
|
1826
|
+
});
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
// Strategy 4: For wireless, kill iproxy processes associated with this device's port
|
|
1830
|
+
if (connectionType === 'usb' && port) {
|
|
1831
|
+
const killIproxy = spawn('sh', ['-c', `pkill -f "iproxy.*${port}" || true`]);
|
|
1832
|
+
killIproxy.on('close', () => {
|
|
1833
|
+
console.log(`ā
Cleaned up iproxy for ${name}`);
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
// Wait a moment for all cleanup to complete
|
|
1838
|
+
setTimeout(() => {
|
|
1839
|
+
// Update device status to offline in connectedDevices
|
|
1840
|
+
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1841
|
+
if (deviceIndex !== -1) {
|
|
1842
|
+
connectedDevices[deviceIndex].status = 'offline';
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
// Broadcast updated device list to all WebSocket clients
|
|
1846
|
+
wss.clients.forEach(client => {
|
|
1847
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
1848
|
+
client.send(JSON.stringify({
|
|
1849
|
+
type: 'devices_updated',
|
|
1850
|
+
devices: connectedDevices
|
|
1851
|
+
}));
|
|
1852
|
+
}
|
|
1853
|
+
});
|
|
1854
|
+
|
|
1855
|
+
console.log(`ā
Successfully disconnected ${name}`);
|
|
1856
|
+
resolve({
|
|
1857
|
+
success: true,
|
|
1858
|
+
message: `Disconnected from ${name} - WDA stopped`
|
|
1859
|
+
});
|
|
1860
|
+
}, 500);
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
// ============================================
|
|
1865
|
+
// Recording & Replay Functions
|
|
1866
|
+
// ============================================
|
|
1867
|
+
|
|
1868
|
+
// Ensure recordings directory exists
|
|
1869
|
+
async function ensureRecordingsDir() {
|
|
1870
|
+
try {
|
|
1871
|
+
await fs.access(RECORDINGS_DIR);
|
|
1872
|
+
} catch {
|
|
1873
|
+
await fs.mkdir(RECORDINGS_DIR, { recursive: true });
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
// Start recording
|
|
1878
|
+
async function startRecording(name, devices) {
|
|
1879
|
+
await ensureRecordingsDir();
|
|
1880
|
+
|
|
1881
|
+
currentRecording = {
|
|
1882
|
+
name: name || `recording_${Date.now()}`,
|
|
1883
|
+
devices: devices || [],
|
|
1884
|
+
commands: [],
|
|
1885
|
+
startTime: new Date().toISOString()
|
|
1886
|
+
};
|
|
1887
|
+
isRecording = true;
|
|
1888
|
+
|
|
1889
|
+
console.log(`š“ Recording started: ${currentRecording.name}`);
|
|
1890
|
+
return { success: true, recording: currentRecording };
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
// Add command to current recording
|
|
1894
|
+
function recordCommand(devices, command, useAI, convertedCommand) {
|
|
1895
|
+
if (!isRecording || !currentRecording) {
|
|
1896
|
+
return false;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
currentRecording.commands.push({
|
|
1900
|
+
timestamp: new Date().toISOString(),
|
|
1901
|
+
devices,
|
|
1902
|
+
originalCommand: command,
|
|
1903
|
+
useAI,
|
|
1904
|
+
finalCommand: convertedCommand || command
|
|
1905
|
+
});
|
|
1906
|
+
|
|
1907
|
+
console.log(`š Recorded command: ${command} (${currentRecording.commands.length} total)`);
|
|
1908
|
+
return true;
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
// Stop recording and save
|
|
1912
|
+
async function stopRecording() {
|
|
1913
|
+
if (!isRecording || !currentRecording) {
|
|
1914
|
+
return { success: false, error: 'No active recording' };
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
currentRecording.endTime = new Date().toISOString();
|
|
1918
|
+
|
|
1919
|
+
const filename = `${currentRecording.name}.json`;
|
|
1920
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
1921
|
+
|
|
1922
|
+
await fs.writeFile(filepath, JSON.stringify(currentRecording, null, 2));
|
|
1923
|
+
|
|
1924
|
+
const result = {
|
|
1925
|
+
success: true,
|
|
1926
|
+
recording: currentRecording,
|
|
1927
|
+
filepath: filename
|
|
1928
|
+
};
|
|
1929
|
+
|
|
1930
|
+
console.log(`ā¹ļø Recording stopped: ${currentRecording.name} (${currentRecording.commands.length} commands)`);
|
|
1931
|
+
|
|
1932
|
+
isRecording = false;
|
|
1933
|
+
currentRecording = null;
|
|
1934
|
+
|
|
1935
|
+
return result;
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
// List all recordings
|
|
1939
|
+
async function listRecordings() {
|
|
1940
|
+
await ensureRecordingsDir();
|
|
1941
|
+
|
|
1942
|
+
try {
|
|
1943
|
+
const files = await fs.readdir(RECORDINGS_DIR);
|
|
1944
|
+
const recordings = [];
|
|
1945
|
+
|
|
1946
|
+
for (const file of files) {
|
|
1947
|
+
if (file.endsWith('.json')) {
|
|
1948
|
+
try {
|
|
1949
|
+
const filepath = path.join(RECORDINGS_DIR, file);
|
|
1950
|
+
const content = await fs.readFile(filepath, 'utf-8');
|
|
1951
|
+
const recording = JSON.parse(content);
|
|
1952
|
+
|
|
1953
|
+
// Handle both old format (array of commands) and new format (string)
|
|
1954
|
+
let commandCount = 0;
|
|
1955
|
+
if (Array.isArray(recording.commands)) {
|
|
1956
|
+
commandCount = recording.commands.length;
|
|
1957
|
+
} else if (typeof recording.commands === 'string') {
|
|
1958
|
+
commandCount = recording.commands.split('\n').filter(cmd => cmd.trim()).length;
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
recordings.push({
|
|
1962
|
+
filename: file,
|
|
1963
|
+
name: recording.name || file.replace('.json', ''),
|
|
1964
|
+
devices: recording.devices || [],
|
|
1965
|
+
commandCount: commandCount,
|
|
1966
|
+
startTime: recording.startTime || recording.date,
|
|
1967
|
+
endTime: recording.endTime || recording.date,
|
|
1968
|
+
type: recording.type || 'manual'
|
|
1969
|
+
});
|
|
1970
|
+
} catch (e) {
|
|
1971
|
+
console.error(`Error reading recording ${file}:`, e);
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
return recordings;
|
|
1977
|
+
} catch (error) {
|
|
1978
|
+
console.error('Error listing recordings:', error);
|
|
1979
|
+
return [];
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
// Load a recording
|
|
1984
|
+
async function loadRecording(filename) {
|
|
1985
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
1986
|
+
|
|
1987
|
+
try {
|
|
1988
|
+
const content = await fs.readFile(filepath, 'utf-8');
|
|
1989
|
+
return JSON.parse(content);
|
|
1990
|
+
} catch (error) {
|
|
1991
|
+
console.error(`Error loading recording ${filename}:`, error);
|
|
1992
|
+
throw error;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
// Delete a recording
|
|
1997
|
+
async function deleteRecording(filename) {
|
|
1998
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
1999
|
+
|
|
2000
|
+
try {
|
|
2001
|
+
await fs.unlink(filepath);
|
|
2002
|
+
return { success: true };
|
|
2003
|
+
} catch (error) {
|
|
2004
|
+
console.error(`Error deleting recording ${filename}:`, error);
|
|
2005
|
+
throw error;
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
// Replay a recording
|
|
2010
|
+
async function replayRecording(filename, targetDevices, wsClient) {
|
|
2011
|
+
const recording = await loadRecording(filename);
|
|
2012
|
+
|
|
2013
|
+
// Normalize commands to array format
|
|
2014
|
+
let commands = [];
|
|
2015
|
+
if (Array.isArray(recording.commands)) {
|
|
2016
|
+
// Old format: array of command objects
|
|
2017
|
+
commands = recording.commands.map(cmd => cmd.finalCommand || cmd.originalCommand);
|
|
2018
|
+
} else if (typeof recording.commands === 'string') {
|
|
2019
|
+
// New format: string with newlines
|
|
2020
|
+
commands = recording.commands.split('\n').filter(cmd => cmd.trim());
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
const devices = recording.devices && recording.devices.length > 0
|
|
2024
|
+
? recording.devices
|
|
2025
|
+
: targetDevices;
|
|
2026
|
+
|
|
2027
|
+
console.log(`\n${'ā¶'.repeat(60)}`);
|
|
2028
|
+
console.log(`REPLAYING: ${recording.name}`);
|
|
2029
|
+
console.log(`Original devices: ${devices.join(', ')}`);
|
|
2030
|
+
console.log(`Target devices: ${targetDevices.join(', ')}`);
|
|
2031
|
+
console.log(`Commands to replay: ${commands.length}`);
|
|
2032
|
+
console.log(`${'ā¶'.repeat(60)}\n`);
|
|
2033
|
+
|
|
2034
|
+
// Reset abort flag at start
|
|
2035
|
+
replayAborted = false;
|
|
2036
|
+
isReplaying = true;
|
|
2037
|
+
|
|
2038
|
+
// Send initial summary to terminal
|
|
2039
|
+
if (wsClient) {
|
|
2040
|
+
wsClient.send(JSON.stringify({
|
|
2041
|
+
type: 'command_output',
|
|
2042
|
+
data: `š¼ Recording: ${recording.name}\n` +
|
|
2043
|
+
`š± Devices: ${targetDevices.join(', ')}\n` +
|
|
2044
|
+
`š Commands: ${commands.length}\n` +
|
|
2045
|
+
`${'ā'.repeat(50)}\n\n`,
|
|
2046
|
+
devices: targetDevices
|
|
2047
|
+
}));
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
const results = [];
|
|
2051
|
+
|
|
2052
|
+
for (let i = 0; i < commands.length; i++) {
|
|
2053
|
+
// Check if replay was aborted
|
|
2054
|
+
if (replayAborted) {
|
|
2055
|
+
console.log('\nā¹ļø Replay aborted by user\n');
|
|
2056
|
+
if (wsClient) {
|
|
2057
|
+
wsClient.send(JSON.stringify({
|
|
2058
|
+
type: 'command_output',
|
|
2059
|
+
data: '\nā¹ļø Replay stopped by user\n',
|
|
2060
|
+
devices: targetDevices
|
|
2061
|
+
}));
|
|
2062
|
+
}
|
|
2063
|
+
isReplaying = false;
|
|
2064
|
+
throw new Error('Replay aborted by user');
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
const cmd = commands[i];
|
|
2068
|
+
|
|
2069
|
+
console.log(`\nš¬ Replaying command ${i + 1}/${commands.length}`);
|
|
2070
|
+
console.log(` Command: ${cmd}`);
|
|
2071
|
+
|
|
2072
|
+
if (wsClient) {
|
|
2073
|
+
wsClient.send(JSON.stringify({
|
|
2074
|
+
type: 'command_output',
|
|
2075
|
+
data: `š¬ [${i + 1}/${commands.length}] Executing: ${cmd}\n`,
|
|
2076
|
+
devices: targetDevices
|
|
2077
|
+
}));
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
try {
|
|
2081
|
+
// Execute the command
|
|
2082
|
+
const result = await executeCommand(targetDevices, cmd, null); // null to suppress websocket output from executeCommand
|
|
2083
|
+
results.push({ command: cmd, success: true, result });
|
|
2084
|
+
|
|
2085
|
+
if (wsClient) {
|
|
2086
|
+
wsClient.send(JSON.stringify({
|
|
2087
|
+
type: 'command_output',
|
|
2088
|
+
data: `ā
Completed successfully\n\n`,
|
|
2089
|
+
devices: targetDevices
|
|
2090
|
+
}));
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
// Add a small delay between commands
|
|
2094
|
+
if (i < commands.length - 1) {
|
|
2095
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
2096
|
+
}
|
|
2097
|
+
} catch (error) {
|
|
2098
|
+
console.error(`ā Replay command ${i + 1} failed:`, error.message);
|
|
2099
|
+
results.push({ command: cmd, success: false, error: error.message });
|
|
2100
|
+
|
|
2101
|
+
if (wsClient) {
|
|
2102
|
+
wsClient.send(JSON.stringify({
|
|
2103
|
+
type: 'command_output',
|
|
2104
|
+
data: `ā Failed: ${error.message}\n\n`,
|
|
2105
|
+
devices: targetDevices
|
|
2106
|
+
}));
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
isReplaying = false;
|
|
2112
|
+
|
|
2113
|
+
console.log(`\n${'ā¶'.repeat(60)}`);
|
|
2114
|
+
console.log(`REPLAY COMPLETE`);
|
|
2115
|
+
console.log(`Total: ${results.length}, Success: ${results.filter(r => r.success).length}, Failed: ${results.filter(r => !r.success).length}`);
|
|
2116
|
+
console.log(`${'ā¶'.repeat(60)}\n`);
|
|
2117
|
+
|
|
2118
|
+
return {
|
|
2119
|
+
success: true,
|
|
2120
|
+
recording: recording.name,
|
|
2121
|
+
results
|
|
2122
|
+
};
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
// API Routes
|
|
2126
|
+
app.get('/api/devices', async (req, res) => {
|
|
2127
|
+
try {
|
|
2128
|
+
const devices = await discoverDevices();
|
|
2129
|
+
res.json({ success: true, devices });
|
|
2130
|
+
} catch (error) {
|
|
2131
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2132
|
+
}
|
|
2133
|
+
});
|
|
2134
|
+
|
|
2135
|
+
app.post('/api/devices/refresh', async (req, res) => {
|
|
2136
|
+
try {
|
|
2137
|
+
const devices = await discoverDevices();
|
|
2138
|
+
|
|
2139
|
+
// Broadcast to all WebSocket clients
|
|
2140
|
+
wss.clients.forEach(client => {
|
|
2141
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
2142
|
+
client.send(JSON.stringify({
|
|
2143
|
+
type: 'devices_updated',
|
|
2144
|
+
devices
|
|
2145
|
+
}));
|
|
2146
|
+
}
|
|
2147
|
+
});
|
|
2148
|
+
|
|
2149
|
+
res.json({ success: true, devices });
|
|
2150
|
+
} catch (error) {
|
|
2151
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2152
|
+
}
|
|
2153
|
+
});
|
|
2154
|
+
|
|
2155
|
+
app.post('/api/execute', async (req, res) => {
|
|
2156
|
+
try {
|
|
2157
|
+
const { devices, command, useAI, aiProvider } = req.body;
|
|
2158
|
+
|
|
2159
|
+
if (!devices || devices.length === 0) {
|
|
2160
|
+
return res.status(400).json({ success: false, error: 'No devices specified' });
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
let finalCommand = command;
|
|
2164
|
+
if (useAI) {
|
|
2165
|
+
finalCommand = await convertNaturalLanguageToCommand(command, devices, aiProvider);
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
// Check if command has multiple lines (sequential execution)
|
|
2169
|
+
const hasMultipleCommands = finalCommand.includes('\n');
|
|
2170
|
+
|
|
2171
|
+
let result;
|
|
2172
|
+
if (hasMultipleCommands) {
|
|
2173
|
+
|
|
2174
|
+
result = await executeCommandsSequentially(devices, finalCommand, null);
|
|
2175
|
+
} else {
|
|
2176
|
+
result = await executeCommand(devices, finalCommand, null);
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
res.json(result);
|
|
2180
|
+
} catch (error) {
|
|
2181
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2182
|
+
}
|
|
2183
|
+
});
|
|
2184
|
+
|
|
2185
|
+
app.post('/api/convert-command', async (req, res) => {
|
|
2186
|
+
try {
|
|
2187
|
+
const { text, devices, provider } = req.body;
|
|
2188
|
+
const command = await convertNaturalLanguageToCommand(text, devices || [], provider);
|
|
2189
|
+
res.json({ success: true, command });
|
|
2190
|
+
} catch (error) {
|
|
2191
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2192
|
+
}
|
|
2193
|
+
});
|
|
2194
|
+
|
|
2195
|
+
// Connect to device endpoint
|
|
2196
|
+
app.post('/api/devices/connect', async (req, res) => {
|
|
2197
|
+
try {
|
|
2198
|
+
const { device } = req.body;
|
|
2199
|
+
console.log(`š” Connect request received for device:`, device);
|
|
2200
|
+
|
|
2201
|
+
if (!device) {
|
|
2202
|
+
console.error('ā No device provided in request');
|
|
2203
|
+
return res.status(400).json({ success: false, error: 'No device provided' });
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
if (!device.name || !device.udid) {
|
|
2207
|
+
console.error('ā Invalid device object:', device);
|
|
2208
|
+
return res.status(400).json({ success: false, error: 'Invalid device object' });
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
const result = await connectToDevice(device);
|
|
2212
|
+
console.log(`ā
Connect result:`, result);
|
|
2213
|
+
res.json(result);
|
|
2214
|
+
} catch (error) {
|
|
2215
|
+
console.error(`ā Connect error:`, error);
|
|
2216
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2217
|
+
}
|
|
2218
|
+
});
|
|
2219
|
+
|
|
2220
|
+
// Disconnect from device endpoint
|
|
2221
|
+
app.post('/api/devices/disconnect', async (req, res) => {
|
|
2222
|
+
try {
|
|
2223
|
+
const { device } = req.body;
|
|
2224
|
+
const result = await disconnectFromDevice(device);
|
|
2225
|
+
res.json(result);
|
|
2226
|
+
} catch (error) {
|
|
2227
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2228
|
+
}
|
|
2229
|
+
});
|
|
2230
|
+
|
|
2231
|
+
// Disconnect all devices endpoint
|
|
2232
|
+
app.post('/api/devices/disconnect-all', async (req, res) => {
|
|
2233
|
+
try {
|
|
2234
|
+
console.log(`š Disconnecting ALL devices...`);
|
|
2235
|
+
|
|
2236
|
+
// Get all connected devices
|
|
2237
|
+
const devicesToDisconnect = connectedDevices.filter(d => d.status === 'online');
|
|
2238
|
+
|
|
2239
|
+
if (devicesToDisconnect.length === 0) {
|
|
2240
|
+
return res.json({
|
|
2241
|
+
success: true,
|
|
2242
|
+
message: 'No devices to disconnect'
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
console.log(`š± Disconnecting ${devicesToDisconnect.length} device(s)...`);
|
|
2247
|
+
|
|
2248
|
+
// Disconnect all devices in parallel
|
|
2249
|
+
const disconnectPromises = devicesToDisconnect.map(device => disconnectFromDevice(device));
|
|
2250
|
+
await Promise.all(disconnectPromises);
|
|
2251
|
+
|
|
2252
|
+
console.log(`ā
All devices disconnected`);
|
|
2253
|
+
|
|
2254
|
+
res.json({
|
|
2255
|
+
success: true,
|
|
2256
|
+
message: `Disconnected ${devicesToDisconnect.length} device(s)`,
|
|
2257
|
+
count: devicesToDisconnect.length
|
|
2258
|
+
});
|
|
2259
|
+
} catch (error) {
|
|
2260
|
+
console.error(`ā Error disconnecting all devices:`, error);
|
|
2261
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2262
|
+
}
|
|
2263
|
+
});
|
|
2264
|
+
|
|
2265
|
+
// New endpoints for AI provider management
|
|
2266
|
+
app.get('/api/ai/providers', (req, res) => {
|
|
2267
|
+
try {
|
|
2268
|
+
const providers = aiManager.getAvailableProviders();
|
|
2269
|
+
const current = aiManager.getCurrentProvider();
|
|
2270
|
+
res.json({ success: true, providers, current: current.id });
|
|
2271
|
+
} catch (error) {
|
|
2272
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2273
|
+
}
|
|
2274
|
+
});
|
|
2275
|
+
|
|
2276
|
+
app.post('/api/ai/provider', (req, res) => {
|
|
2277
|
+
try {
|
|
2278
|
+
const { provider } = req.body;
|
|
2279
|
+
const success = aiManager.setProvider(provider);
|
|
2280
|
+
if (success) {
|
|
2281
|
+
res.json({ success: true, provider });
|
|
2282
|
+
} else {
|
|
2283
|
+
res.status(400).json({ success: false, error: 'Invalid or unavailable provider' });
|
|
2284
|
+
}
|
|
2285
|
+
} catch (error) {
|
|
2286
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2287
|
+
}
|
|
2288
|
+
});
|
|
2289
|
+
|
|
2290
|
+
// Settings API - Get API configuration
|
|
2291
|
+
app.get('/api/settings/api-config', async (req, res) => {
|
|
2292
|
+
try {
|
|
2293
|
+
const configPath = path.join(__dirname, '../../.env');
|
|
2294
|
+
let config = {
|
|
2295
|
+
provider: process.env.AI_PROVIDER || 'gemini',
|
|
2296
|
+
model: process.env.AI_MODEL || '',
|
|
2297
|
+
openai_api_key: process.env.OPENAI_API_KEY || '',
|
|
2298
|
+
gemini_api_key: process.env.GEMINI_API_KEY || '',
|
|
2299
|
+
claude_api_key: process.env.CLAUDE_API_KEY || '',
|
|
2300
|
+
github_token: process.env.GITHUB_TOKEN || '',
|
|
2301
|
+
groq_api_key: process.env.GROQ_API_KEY || '',
|
|
2302
|
+
cohere_api_key: process.env.COHERE_API_KEY || '',
|
|
2303
|
+
mistral_api_key: process.env.MISTRAL_API_KEY || '',
|
|
2304
|
+
};
|
|
2305
|
+
|
|
2306
|
+
// Try to read from .env file if exists
|
|
2307
|
+
try {
|
|
2308
|
+
const envContent = await fs.readFile(configPath, 'utf-8');
|
|
2309
|
+
const lines = envContent.split('\n');
|
|
2310
|
+
lines.forEach(line => {
|
|
2311
|
+
const [key, value] = line.split('=');
|
|
2312
|
+
if (key && value) {
|
|
2313
|
+
const trimmedKey = key.trim();
|
|
2314
|
+
const trimmedValue = value.trim();
|
|
2315
|
+
if (trimmedKey === 'AI_PROVIDER') config.provider = trimmedValue;
|
|
2316
|
+
if (trimmedKey === 'AI_MODEL') config.model = trimmedValue;
|
|
2317
|
+
if (trimmedKey === 'OPENAI_API_KEY') config.openai_api_key = trimmedValue;
|
|
2318
|
+
if (trimmedKey === 'GEMINI_API_KEY') config.gemini_api_key = trimmedValue;
|
|
2319
|
+
if (trimmedKey === 'CLAUDE_API_KEY') config.claude_api_key = trimmedValue;
|
|
2320
|
+
if (trimmedKey === 'GITHUB_TOKEN') config.github_token = trimmedValue;
|
|
2321
|
+
if (trimmedKey === 'GROQ_API_KEY') config.groq_api_key = trimmedValue;
|
|
2322
|
+
if (trimmedKey === 'COHERE_API_KEY') config.cohere_api_key = trimmedValue;
|
|
2323
|
+
if (trimmedKey === 'MISTRAL_API_KEY') config.mistral_api_key = trimmedValue;
|
|
2324
|
+
}
|
|
2325
|
+
});
|
|
2326
|
+
} catch (err) {
|
|
2327
|
+
// .env doesn't exist, return defaults
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
// Mask API keys for security - only show last 4 characters
|
|
2331
|
+
const maskKey = (key) => {
|
|
2332
|
+
if (!key || key.length < 8) return '';
|
|
2333
|
+
return 'ā¢'.repeat(key.length - 4) + key.slice(-4);
|
|
2334
|
+
};
|
|
2335
|
+
|
|
2336
|
+
res.json({
|
|
2337
|
+
provider: config.provider,
|
|
2338
|
+
model: config.model,
|
|
2339
|
+
openai_api_key: maskKey(config.openai_api_key),
|
|
2340
|
+
gemini_api_key: maskKey(config.gemini_api_key),
|
|
2341
|
+
claude_api_key: maskKey(config.claude_api_key),
|
|
2342
|
+
github_token: maskKey(config.github_token),
|
|
2343
|
+
groq_api_key: maskKey(config.groq_api_key),
|
|
2344
|
+
cohere_api_key: maskKey(config.cohere_api_key),
|
|
2345
|
+
mistral_api_key: maskKey(config.mistral_api_key),
|
|
2346
|
+
has_openai_key: !!config.openai_api_key,
|
|
2347
|
+
has_gemini_key: !!config.gemini_api_key,
|
|
2348
|
+
has_claude_key: !!config.claude_api_key,
|
|
2349
|
+
has_github_token: !!config.github_token,
|
|
2350
|
+
has_groq_key: !!config.groq_api_key,
|
|
2351
|
+
has_cohere_key: !!config.cohere_api_key,
|
|
2352
|
+
has_mistral_key: !!config.mistral_api_key,
|
|
2353
|
+
});
|
|
2354
|
+
} catch (error) {
|
|
2355
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2356
|
+
}
|
|
2357
|
+
});
|
|
2358
|
+
|
|
2359
|
+
// Settings API - Save API configuration
|
|
2360
|
+
app.post('/api/settings/api-config', async (req, res) => {
|
|
2361
|
+
try {
|
|
2362
|
+
const {
|
|
2363
|
+
provider,
|
|
2364
|
+
model,
|
|
2365
|
+
openai_api_key,
|
|
2366
|
+
gemini_api_key,
|
|
2367
|
+
claude_api_key,
|
|
2368
|
+
github_token,
|
|
2369
|
+
groq_api_key,
|
|
2370
|
+
cohere_api_key,
|
|
2371
|
+
mistral_api_key
|
|
2372
|
+
} = req.body;
|
|
2373
|
+
|
|
2374
|
+
const configPath = path.join(__dirname, '../../.env');
|
|
2375
|
+
|
|
2376
|
+
let envContent = `# AI Provider Configuration\nAI_PROVIDER=${provider}\n`;
|
|
2377
|
+
if (model) {
|
|
2378
|
+
envContent += `AI_MODEL=${model}\n`;
|
|
2379
|
+
}
|
|
2380
|
+
if (openai_api_key) {
|
|
2381
|
+
envContent += `OPENAI_API_KEY=${openai_api_key}\n`;
|
|
2382
|
+
}
|
|
2383
|
+
if (gemini_api_key) {
|
|
2384
|
+
envContent += `GEMINI_API_KEY=${gemini_api_key}\n`;
|
|
2385
|
+
}
|
|
2386
|
+
if (claude_api_key) {
|
|
2387
|
+
envContent += `CLAUDE_API_KEY=${claude_api_key}\n`;
|
|
2388
|
+
}
|
|
2389
|
+
if (github_token) {
|
|
2390
|
+
envContent += `GITHUB_TOKEN=${github_token}\n`;
|
|
2391
|
+
}
|
|
2392
|
+
if (groq_api_key) {
|
|
2393
|
+
envContent += `GROQ_API_KEY=${groq_api_key}\n`;
|
|
2394
|
+
}
|
|
2395
|
+
if (cohere_api_key) {
|
|
2396
|
+
envContent += `COHERE_API_KEY=${cohere_api_key}\n`;
|
|
2397
|
+
}
|
|
2398
|
+
if (mistral_api_key) {
|
|
2399
|
+
envContent += `MISTRAL_API_KEY=${mistral_api_key}\n`;
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
// Add WDA path if exists
|
|
2403
|
+
if (process.env.WDA_PATH) {
|
|
2404
|
+
envContent += `WDA_PATH=${process.env.WDA_PATH}\n`;
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
await fs.writeFile(configPath, envContent);
|
|
2408
|
+
|
|
2409
|
+
// Update environment variables
|
|
2410
|
+
process.env.AI_PROVIDER = provider;
|
|
2411
|
+
if (model) process.env.AI_MODEL = model;
|
|
2412
|
+
if (openai_api_key) process.env.OPENAI_API_KEY = openai_api_key;
|
|
2413
|
+
if (gemini_api_key) process.env.GEMINI_API_KEY = gemini_api_key;
|
|
2414
|
+
if (claude_api_key) process.env.CLAUDE_API_KEY = claude_api_key;
|
|
2415
|
+
if (github_token) process.env.GITHUB_TOKEN = github_token;
|
|
2416
|
+
if (groq_api_key) process.env.GROQ_API_KEY = groq_api_key;
|
|
2417
|
+
if (cohere_api_key) process.env.COHERE_API_KEY = cohere_api_key;
|
|
2418
|
+
if (mistral_api_key) process.env.MISTRAL_API_KEY = mistral_api_key;
|
|
2419
|
+
|
|
2420
|
+
// Reinitialize AI manager with new config
|
|
2421
|
+
aiManager.provider = provider;
|
|
2422
|
+
if (model) aiManager.model = model;
|
|
2423
|
+
aiManager.initializeProviders();
|
|
2424
|
+
|
|
2425
|
+
res.json({ success: true, message: 'API configuration saved' });
|
|
2426
|
+
} catch (error) {
|
|
2427
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2428
|
+
}
|
|
2429
|
+
});
|
|
2430
|
+
|
|
2431
|
+
// Settings API - Get available AI providers and their models
|
|
2432
|
+
app.get('/api/settings/ai-providers', (req, res) => {
|
|
2433
|
+
try {
|
|
2434
|
+
const { AI_PROVIDERS_CONFIG } = require('./aiProvidersConfig');
|
|
2435
|
+
res.json({ success: true, providers: AI_PROVIDERS_CONFIG });
|
|
2436
|
+
} catch (error) {
|
|
2437
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2438
|
+
}
|
|
2439
|
+
});
|
|
2440
|
+
|
|
2441
|
+
// Settings API - Get devices configuration
|
|
2442
|
+
app.get('/api/settings/devices', async (req, res) => {
|
|
2443
|
+
try {
|
|
2444
|
+
const devices = await loadDeviceConfig();
|
|
2445
|
+
res.json({ success: true, devices });
|
|
2446
|
+
} catch (error) {
|
|
2447
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2448
|
+
}
|
|
2449
|
+
});
|
|
2450
|
+
|
|
2451
|
+
// Settings API - Save devices configuration
|
|
2452
|
+
app.post('/api/settings/devices', async (req, res) => {
|
|
2453
|
+
try {
|
|
2454
|
+
const { devices } = req.body;
|
|
2455
|
+
|
|
2456
|
+
// Format: device_name,udid,ip_address,platform,type
|
|
2457
|
+
let content = '# Device Configuration (Auto-updated)\n';
|
|
2458
|
+
content += '# Format: device_name,udid,ip_address,platform,type\n';
|
|
2459
|
+
content += '# Platform: ios | android\n';
|
|
2460
|
+
content += '# Type: usb | wireless\n';
|
|
2461
|
+
content += '# \n';
|
|
2462
|
+
content += '# š USB DEVICES: Automatically detected and saved here\n';
|
|
2463
|
+
content += '# - No configuration needed for USB connection\n';
|
|
2464
|
+
content += '# - Add IP address to enable wireless support later\n';
|
|
2465
|
+
content += '#\n';
|
|
2466
|
+
content += '# š” WIRELESS DEVICES: Manually add with IP address\n';
|
|
2467
|
+
content += '# - Format: device_name,udid,ip_address,platform,wireless\n';
|
|
2468
|
+
content += '# - iOS: Device must be paired in Xcode, WebDriverAgent running\n';
|
|
2469
|
+
content += '# - Android: Enable wireless ADB first\n';
|
|
2470
|
+
content += '#\n';
|
|
2471
|
+
content += '# Example entries:\n';
|
|
2472
|
+
content += '# iPhone17,00008130-001945C63ED3401E,,ios,usb (iOS USB - auto-detected)\n';
|
|
2473
|
+
content += '# iPhone16P,00008140-001C24361E41801C,10.173.221.204,ios,wireless (iOS Wireless)\n';
|
|
2474
|
+
content += '# Pixel8,1A2B3C4D5E6F,,android,usb (Android USB - auto-detected)\n';
|
|
2475
|
+
content += '# GalaxyS23,ABCD1234,192.168.1.150,android,wireless (Android Wireless)\n\n';
|
|
2476
|
+
|
|
2477
|
+
devices.forEach(device => {
|
|
2478
|
+
const ip = device.ip || '';
|
|
2479
|
+
const platform = device.platform || 'ios';
|
|
2480
|
+
const type = device.type || device.connectionType || (ip ? 'wireless' : 'usb');
|
|
2481
|
+
content += `${device.name},${device.udid},${ip},${platform},${type}\n`;
|
|
2482
|
+
});
|
|
2483
|
+
|
|
2484
|
+
await fs.writeFile(DEVICE_CONFIG, content);
|
|
2485
|
+
|
|
2486
|
+
res.json({ success: true, message: 'Devices configuration saved' });
|
|
2487
|
+
} catch (error) {
|
|
2488
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2489
|
+
}
|
|
2490
|
+
});
|
|
2491
|
+
|
|
2492
|
+
// Get app presets
|
|
2493
|
+
app.get('/api/apps/presets', async (req, res) => {
|
|
2494
|
+
try {
|
|
2495
|
+
const content = await fs.readFile(APPS_CONFIG, 'utf-8');
|
|
2496
|
+
const apps = content
|
|
2497
|
+
.split('\n')
|
|
2498
|
+
.filter(line => line.trim() && !line.startsWith('#'))
|
|
2499
|
+
.map(line => {
|
|
2500
|
+
const [name, packageId] = line.split(',');
|
|
2501
|
+
return { name: name.trim(), packageId: packageId.trim() };
|
|
2502
|
+
});
|
|
2503
|
+
|
|
2504
|
+
res.json({ success: true, apps });
|
|
2505
|
+
} catch (error) {
|
|
2506
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2507
|
+
}
|
|
2508
|
+
});
|
|
2509
|
+
|
|
2510
|
+
// Get locators from device's current screen
|
|
2511
|
+
app.post('/api/locators', async (req, res) => {
|
|
2512
|
+
try {
|
|
2513
|
+
const { deviceName } = req.body;
|
|
2514
|
+
|
|
2515
|
+
if (!deviceName) {
|
|
2516
|
+
return res.status(400).json({ success: false, error: 'Device name required' });
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
console.log(`\nš API: Getting locators for device: ${deviceName}`);
|
|
2520
|
+
|
|
2521
|
+
// Find the device info
|
|
2522
|
+
const device = connectedDevices.find(d => d.name === deviceName);
|
|
2523
|
+
if (!device) {
|
|
2524
|
+
return res.status(404).json({ success: false, error: 'Device not found' });
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
// For Android devices, ensure UIAutomator2 session exists
|
|
2528
|
+
if (device.platform === 'android') {
|
|
2529
|
+
const session = androidSessions.get(device.udid);
|
|
2530
|
+
if (!session) {
|
|
2531
|
+
// Auto-connect the device
|
|
2532
|
+
console.log(`š” Auto-connecting ${deviceName} for getLocators...`);
|
|
2533
|
+
try {
|
|
2534
|
+
const connectResult = await connectToDevice(device);
|
|
2535
|
+
if (!connectResult.success) {
|
|
2536
|
+
return res.status(500).json({
|
|
2537
|
+
success: false,
|
|
2538
|
+
error: 'Failed to connect device. Please use the Connect button first.'
|
|
2539
|
+
});
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
// Wait a moment for session to stabilize
|
|
2543
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2544
|
+
} catch (err) {
|
|
2545
|
+
return res.status(500).json({
|
|
2546
|
+
success: false,
|
|
2547
|
+
error: `Auto-connection failed: ${err.message}`
|
|
2548
|
+
});
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
// Execute getLocators command - this uses the fast shell script implementation
|
|
2554
|
+
const result = await executeCommand([deviceName], 'getLocators', null);
|
|
2555
|
+
|
|
2556
|
+
console.log(`Result success: ${result.success}`);
|
|
2557
|
+
console.log(`Results array length: ${result.results?.length || 0}`);
|
|
2558
|
+
|
|
2559
|
+
if (result.success && result.results) {
|
|
2560
|
+
let output = '';
|
|
2561
|
+
|
|
2562
|
+
// executeCommand returns: { success, results: [scriptResults] }
|
|
2563
|
+
// scriptResults is from executeAndroidDevices/executeWithScript
|
|
2564
|
+
// Structure: { status: 'fulfilled', value: { success, results: [allSettledResults] } }
|
|
2565
|
+
// allSettledResults contains: { status: 'fulfilled', value: { success, output, device } }
|
|
2566
|
+
|
|
2567
|
+
for (const scriptResult of result.results) {
|
|
2568
|
+
console.log(`Script result:`, scriptResult);
|
|
2569
|
+
|
|
2570
|
+
// Check if scriptResult has value.results (fulfilled promise)
|
|
2571
|
+
if (scriptResult.status === 'fulfilled' && scriptResult.value && scriptResult.value.results) {
|
|
2572
|
+
// This is the result from executeAndroidDevices/executeWithScript
|
|
2573
|
+
for (const r of scriptResult.value.results) {
|
|
2574
|
+
console.log(`Result status: ${r.status}`);
|
|
2575
|
+
if (r.status === 'fulfilled' && r.value) {
|
|
2576
|
+
// Check if it's a successful execution
|
|
2577
|
+
if (r.value.success && r.value.output) {
|
|
2578
|
+
output = r.value.output;
|
|
2579
|
+
console.log(`ā
Found output: ${output.length} characters`);
|
|
2580
|
+
break;
|
|
2581
|
+
} else if (r.value.error) {
|
|
2582
|
+
// Script executed but returned an error
|
|
2583
|
+
console.log(`ā Script error:`, r.value.error);
|
|
2584
|
+
return res.status(500).json({
|
|
2585
|
+
success: false,
|
|
2586
|
+
error: 'Failed to get UI elements. Please ensure UIAutomator2 is installed for Android devices.'
|
|
2587
|
+
});
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
if (output) break;
|
|
2593
|
+
}
|
|
2594
|
+
|
|
2595
|
+
if (!output) {
|
|
2596
|
+
console.log('ā No output found in results');
|
|
2597
|
+
console.log('Full result structure:', JSON.stringify(result, null, 2));
|
|
2598
|
+
return res.status(500).json({ success: false, error: 'No output received from device' });
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
// Parse the output into locator objects
|
|
2602
|
+
const locators = parseLocatorsOutput(output);
|
|
2603
|
+
console.log(`ā
Parsed ${locators.length} locators`);
|
|
2604
|
+
|
|
2605
|
+
// Filter out empty/invalid locators
|
|
2606
|
+
const validLocators = locators.filter(loc => loc.name || loc.label || loc.text);
|
|
2607
|
+
console.log(`ā
Filtered to ${validLocators.length} valid locators`);
|
|
2608
|
+
|
|
2609
|
+
res.json({ success: true, locators: validLocators });
|
|
2610
|
+
} else {
|
|
2611
|
+
console.log('ā Command execution failed');
|
|
2612
|
+
res.status(500).json({ success: false, error: 'Failed to get locators' });
|
|
2613
|
+
}
|
|
2614
|
+
} catch (error) {
|
|
2615
|
+
console.error(`ā API error:`, error);
|
|
2616
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2617
|
+
}
|
|
2618
|
+
});
|
|
2619
|
+
|
|
2620
|
+
// Click on a locator
|
|
2621
|
+
app.post('/api/locators/click', async (req, res) => {
|
|
2622
|
+
try {
|
|
2623
|
+
const { deviceName, locatorName, x, y } = req.body;
|
|
2624
|
+
|
|
2625
|
+
if (!deviceName) {
|
|
2626
|
+
return res.status(400).json({ success: false, error: 'Device name required' });
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
let command;
|
|
2630
|
+
// If coordinates are provided, use them directly
|
|
2631
|
+
if (x !== undefined && y !== undefined) {
|
|
2632
|
+
command = `tap ${x},${y}`;
|
|
2633
|
+
console.log(`\nš±ļø API: Tapping at coordinates (${x},${y}) on device: ${deviceName}`);
|
|
2634
|
+
} else if (locatorName) {
|
|
2635
|
+
command = `click "${locatorName}"`;
|
|
2636
|
+
console.log(`\nš±ļø API: Clicking locator "${locatorName}" on device: ${deviceName}`);
|
|
2637
|
+
} else {
|
|
2638
|
+
return res.status(400).json({ success: false, error: 'Locator name or coordinates required' });
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2641
|
+
// Execute click command
|
|
2642
|
+
const result = await executeCommand([deviceName], command, null);
|
|
2643
|
+
|
|
2644
|
+
if (result.success) {
|
|
2645
|
+
res.json({ success: true, message: 'Tap executed successfully' });
|
|
2646
|
+
} else {
|
|
2647
|
+
res.status(500).json({ success: false, error: 'Failed to execute tap' });
|
|
2648
|
+
}
|
|
2649
|
+
} catch (error) {
|
|
2650
|
+
console.error('ā Tap error:', error);
|
|
2651
|
+
res.status(500).json({ success: false, error: error.message });
|
|
2652
|
+
}
|
|
2653
|
+
});
|
|
2654
|
+
|
|
2655
|
+
// Helper function to parse locators output
|
|
2656
|
+
function parseLocatorsOutput(output) {
|
|
2657
|
+
console.log('š Parsing locators output...');
|
|
2658
|
+
console.log('Output length:', output?.length || 0);
|
|
2659
|
+
|
|
2660
|
+
if (!output) {
|
|
2661
|
+
console.log('ā No output to parse');
|
|
2662
|
+
return [];
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
// First try to parse as JSON (new format)
|
|
2666
|
+
const lines = output.split('\n');
|
|
2667
|
+
for (const line of lines) {
|
|
2668
|
+
const trimmed = line.trim();
|
|
2669
|
+
if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
|
|
2670
|
+
try {
|
|
2671
|
+
const jsonData = JSON.parse(trimmed);
|
|
2672
|
+
console.log('ā
Parsed as JSON, elements:', Array.isArray(jsonData) ? jsonData.length : 'not array');
|
|
2673
|
+
return Array.isArray(jsonData) ? jsonData : [];
|
|
2674
|
+
} catch (err) {
|
|
2675
|
+
console.log('ā ļø JSON parse failed:', err.message);
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2680
|
+
console.log('š Fallback to text parsing...');
|
|
2681
|
+
|
|
2682
|
+
// Fallback to old text parsing
|
|
2683
|
+
const locators = [];
|
|
2684
|
+
console.log('Total lines:', lines.length);
|
|
2685
|
+
|
|
2686
|
+
for (const line of lines) {
|
|
2687
|
+
// New format: " 1. š ButtonName ā [Button] ā Label:LabelText ā Val:ValueText ā @ (x,y) WxH ā āVis āEn"
|
|
2688
|
+
// Look for lines with numbered locators starting with š
|
|
2689
|
+
if (line.includes('š') && /^\s*\d+\./.test(line)) {
|
|
2690
|
+
try {
|
|
2691
|
+
const locator = {};
|
|
2692
|
+
|
|
2693
|
+
// Extract index number
|
|
2694
|
+
const indexMatch = line.match(/^\s*(\d+)\./);
|
|
2695
|
+
if (indexMatch) locator.index = parseInt(indexMatch[1]);
|
|
2696
|
+
|
|
2697
|
+
// Split by pipe separator if present (new format), otherwise use old logic
|
|
2698
|
+
if (line.includes('ā')) {
|
|
2699
|
+
const parts = line.split('ā').map(p => p.trim());
|
|
2700
|
+
|
|
2701
|
+
// Part 0: "1. š ButtonName"
|
|
2702
|
+
const nameMatch = parts[0].match(/š\s+(.+)/);
|
|
2703
|
+
if (nameMatch) {
|
|
2704
|
+
locator.name = nameMatch[1].trim();
|
|
2705
|
+
locator.text = nameMatch[1].trim();
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2708
|
+
// Part 1: "[Button]" or "[TextView]"
|
|
2709
|
+
const typeMatch = parts[1] ? parts[1].match(/\[([^\]]+)\]/) : null;
|
|
2710
|
+
if (typeMatch) locator.type = typeMatch[1].trim();
|
|
2711
|
+
|
|
2712
|
+
// Process remaining parts for Label, Val, ID, coordinates, flags
|
|
2713
|
+
for (let i = 2; i < parts.length; i++) {
|
|
2714
|
+
const part = parts[i];
|
|
2715
|
+
|
|
2716
|
+
// Label:...
|
|
2717
|
+
if (part.includes('Label:')) {
|
|
2718
|
+
const labelMatch = part.match(/Label:([^\s]+)/);
|
|
2719
|
+
if (labelMatch) locator.label = labelMatch[1];
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
// Val:...
|
|
2723
|
+
if (part.includes('Val:')) {
|
|
2724
|
+
const valueMatch = part.match(/Val:([^\s]+)/);
|
|
2725
|
+
if (valueMatch) locator.value = valueMatch[1];
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
// ID:...
|
|
2729
|
+
if (part.includes('ID:')) {
|
|
2730
|
+
const idMatch = part.match(/ID:([^\s]+)/);
|
|
2731
|
+
if (idMatch) locator.resourceId = idMatch[1];
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2734
|
+
// @ (x,y) WxH
|
|
2735
|
+
if (part.includes('@')) {
|
|
2736
|
+
const coordMatch = part.match(/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);
|
|
2737
|
+
if (coordMatch) {
|
|
2738
|
+
locator.x = parseInt(coordMatch[1]);
|
|
2739
|
+
locator.y = parseInt(coordMatch[2]);
|
|
2740
|
+
locator.width = parseInt(coordMatch[3]);
|
|
2741
|
+
locator.height = parseInt(coordMatch[4]);
|
|
2742
|
+
locator.coordinates = `(${locator.x},${locator.y}) ${locator.width}x${locator.height}`;
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
// Flags
|
|
2747
|
+
if (part.includes('āVis')) locator.visible = true;
|
|
2748
|
+
if (part.includes('āEn')) locator.enabled = true;
|
|
2749
|
+
if (part.includes('āClick')) locator.clickable = true;
|
|
2750
|
+
}
|
|
2751
|
+
} else {
|
|
2752
|
+
// Old format fallback
|
|
2753
|
+
const nameMatch = line.match(/š\s+([^\[]+?)(?:\s*\[|\s*Label)/);
|
|
2754
|
+
if (nameMatch) {
|
|
2755
|
+
locator.name = nameMatch[1].trim();
|
|
2756
|
+
locator.text = nameMatch[1].trim();
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2759
|
+
const typeMatch = line.match(/\[([^\]]+)\]/);
|
|
2760
|
+
if (typeMatch) locator.type = typeMatch[1].trim();
|
|
2761
|
+
|
|
2762
|
+
const labelMatch = line.match(/Label:([^\s]+?)(?:\s*Val:|\s*@|\s*ā)/);
|
|
2763
|
+
if (labelMatch) locator.label = labelMatch[1].trim();
|
|
2764
|
+
|
|
2765
|
+
const valueMatch = line.match(/Val:([^\s]+?)(?:\s*@|\s*ā)/);
|
|
2766
|
+
if (valueMatch) locator.value = valueMatch[1].trim();
|
|
2767
|
+
|
|
2768
|
+
const coordMatch = line.match(/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);
|
|
2769
|
+
if (coordMatch) {
|
|
2770
|
+
locator.x = parseInt(coordMatch[1]);
|
|
2771
|
+
locator.y = parseInt(coordMatch[2]);
|
|
2772
|
+
locator.width = parseInt(coordMatch[3]);
|
|
2773
|
+
locator.height = parseInt(coordMatch[4]);
|
|
2774
|
+
locator.coordinates = `(${locator.x},${locator.y}) ${locator.width}x${locator.height}`;
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
const idMatch = line.match(/ID:([^\s]+)/);
|
|
2778
|
+
if (idMatch) locator.resourceId = idMatch[1].trim();
|
|
2779
|
+
|
|
2780
|
+
locator.visible = line.includes('āVis');
|
|
2781
|
+
locator.enabled = line.includes('āEn');
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
// Only add if we have meaningful data
|
|
2785
|
+
if (locator.name || locator.label || locator.text) {
|
|
2786
|
+
console.log('ā
Parsed locator:', locator);
|
|
2787
|
+
locators.push(locator);
|
|
2788
|
+
}
|
|
2789
|
+
} catch (e) {
|
|
2790
|
+
// Skip malformed lines
|
|
2791
|
+
console.error('Error parsing locator line:', line, e);
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2796
|
+
console.log(`ā
Total parsed locators: ${locators.length}`);
|
|
2797
|
+
return locators;
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
// WebSocket handling
|
|
2801
|
+
wss.on('connection', (ws) => {
|
|
2802
|
+
console.log('New WebSocket connection');
|
|
2803
|
+
|
|
2804
|
+
ws.on('message', async (message) => {
|
|
2805
|
+
try {
|
|
2806
|
+
const data = JSON.parse(message);
|
|
2807
|
+
|
|
2808
|
+
switch (data.type) {
|
|
2809
|
+
case 'execute_command':
|
|
2810
|
+
const { devices, command, useAI, aiProvider } = data;
|
|
2811
|
+
|
|
2812
|
+
console.log(`\n${'*'.repeat(60)}`);
|
|
2813
|
+
console.log(`WEBSOCKET: Received execute_command`);
|
|
2814
|
+
console.log(`Devices received: [${devices.join(', ')}]`);
|
|
2815
|
+
console.log(`Command: "${command}"`);
|
|
2816
|
+
console.log(`Use AI: ${useAI}`);
|
|
2817
|
+
if (aiProvider) console.log(`AI Provider: ${aiProvider}`);
|
|
2818
|
+
console.log(`${'*'.repeat(60)}\n`);
|
|
2819
|
+
|
|
2820
|
+
let finalCommand = command;
|
|
2821
|
+
|
|
2822
|
+
if (useAI) {
|
|
2823
|
+
try {
|
|
2824
|
+
finalCommand = await convertNaturalLanguageToCommand(command, devices, aiProvider);
|
|
2825
|
+
console.log(`ā
AI converted command to:\n${finalCommand}`);
|
|
2826
|
+
ws.send(JSON.stringify({
|
|
2827
|
+
type: 'command_converted',
|
|
2828
|
+
original: command,
|
|
2829
|
+
converted: finalCommand,
|
|
2830
|
+
provider: aiProvider || aiManager.provider
|
|
2831
|
+
}));
|
|
2832
|
+
} catch (error) {
|
|
2833
|
+
console.error(`ā AI conversion failed: ${error.message}`);
|
|
2834
|
+
|
|
2835
|
+
// Send error to frontend - DO NOT execute command
|
|
2836
|
+
ws.send(JSON.stringify({
|
|
2837
|
+
type: 'ai_error',
|
|
2838
|
+
error: error.message,
|
|
2839
|
+
original: command
|
|
2840
|
+
}));
|
|
2841
|
+
|
|
2842
|
+
// Stop execution - don't run unconverted commands
|
|
2843
|
+
return;
|
|
2844
|
+
}
|
|
2845
|
+
} else {
|
|
2846
|
+
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
// Check if command has multiple lines (sequential execution)
|
|
2850
|
+
const hasMultipleCommands = finalCommand.includes('\n');
|
|
2851
|
+
|
|
2852
|
+
if (hasMultipleCommands) {
|
|
2853
|
+
|
|
2854
|
+
executeCommandsSequentially(devices, finalCommand, ws)
|
|
2855
|
+
.then(result => {
|
|
2856
|
+
console.log(`Sequential execution completed`);
|
|
2857
|
+
ws.send(JSON.stringify({
|
|
2858
|
+
type: 'command_complete',
|
|
2859
|
+
result
|
|
2860
|
+
}));
|
|
2861
|
+
})
|
|
2862
|
+
.catch(error => {
|
|
2863
|
+
console.error(`Sequential execution failed: ${error.message}`);
|
|
2864
|
+
ws.send(JSON.stringify({
|
|
2865
|
+
type: 'command_error',
|
|
2866
|
+
error: error.message
|
|
2867
|
+
}));
|
|
2868
|
+
});
|
|
2869
|
+
} else {
|
|
2870
|
+
executeCommand(devices, finalCommand, ws)
|
|
2871
|
+
.then(result => {
|
|
2872
|
+
|
|
2873
|
+
// Record command if recording is active
|
|
2874
|
+
if (isRecording) {
|
|
2875
|
+
recordCommand(devices, command, useAI, finalCommand);
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
ws.send(JSON.stringify({
|
|
2879
|
+
type: 'command_complete',
|
|
2880
|
+
result
|
|
2881
|
+
}));
|
|
2882
|
+
})
|
|
2883
|
+
.catch(error => {
|
|
2884
|
+
console.error(`executeCommand failed: ${error.message}`);
|
|
2885
|
+
ws.send(JSON.stringify({
|
|
2886
|
+
type: 'command_error',
|
|
2887
|
+
error: error.message
|
|
2888
|
+
}));
|
|
2889
|
+
});
|
|
2890
|
+
}
|
|
2891
|
+
break;
|
|
2892
|
+
|
|
2893
|
+
case 'start_recording':
|
|
2894
|
+
const startResult = await startRecording(data.name, data.devices);
|
|
2895
|
+
ws.send(JSON.stringify({
|
|
2896
|
+
type: 'recording_started',
|
|
2897
|
+
...startResult
|
|
2898
|
+
}));
|
|
2899
|
+
break;
|
|
2900
|
+
|
|
2901
|
+
case 'stop_recording':
|
|
2902
|
+
const stopResult = await stopRecording();
|
|
2903
|
+
ws.send(JSON.stringify({
|
|
2904
|
+
type: 'recording_stopped',
|
|
2905
|
+
...stopResult
|
|
2906
|
+
}));
|
|
2907
|
+
break;
|
|
2908
|
+
|
|
2909
|
+
case 'replay_recording':
|
|
2910
|
+
const { filename, targetDevices } = data;
|
|
2911
|
+
|
|
2912
|
+
ws.send(JSON.stringify({
|
|
2913
|
+
type: 'command_output',
|
|
2914
|
+
data: `\nš¬ Starting replay: ${filename}\n\n`,
|
|
2915
|
+
devices: targetDevices
|
|
2916
|
+
}));
|
|
2917
|
+
|
|
2918
|
+
replayRecording(filename, targetDevices, ws)
|
|
2919
|
+
.then(result => {
|
|
2920
|
+
ws.send(JSON.stringify({
|
|
2921
|
+
type: 'replay_complete',
|
|
2922
|
+
...result
|
|
2923
|
+
}));
|
|
2924
|
+
})
|
|
2925
|
+
.catch(error => {
|
|
2926
|
+
ws.send(JSON.stringify({
|
|
2927
|
+
type: 'replay_error',
|
|
2928
|
+
error: error.message
|
|
2929
|
+
}));
|
|
2930
|
+
});
|
|
2931
|
+
break;
|
|
2932
|
+
|
|
2933
|
+
case 'stop_replay':
|
|
2934
|
+
if (isReplaying) {
|
|
2935
|
+
replayAborted = true;
|
|
2936
|
+
ws.send(JSON.stringify({
|
|
2937
|
+
type: 'command_output',
|
|
2938
|
+
data: '\nā¹ļø Stopping replay...\n'
|
|
2939
|
+
}));
|
|
2940
|
+
}
|
|
2941
|
+
break;
|
|
2942
|
+
|
|
2943
|
+
case 'refresh_devices':
|
|
2944
|
+
const updatedDevices = await discoverDevices();
|
|
2945
|
+
ws.send(JSON.stringify({
|
|
2946
|
+
type: 'devices_updated',
|
|
2947
|
+
devices: updatedDevices
|
|
2948
|
+
}));
|
|
2949
|
+
break;
|
|
2950
|
+
|
|
2951
|
+
case 'get_ai_providers':
|
|
2952
|
+
ws.send(JSON.stringify({
|
|
2953
|
+
type: 'ai_providers',
|
|
2954
|
+
providers: aiManager.getAvailableProviders(),
|
|
2955
|
+
current: aiManager.provider
|
|
2956
|
+
}));
|
|
2957
|
+
break;
|
|
2958
|
+
|
|
2959
|
+
case 'set_ai_provider':
|
|
2960
|
+
const success = aiManager.setProvider(data.provider);
|
|
2961
|
+
ws.send(JSON.stringify({
|
|
2962
|
+
type: 'ai_provider_set',
|
|
2963
|
+
success,
|
|
2964
|
+
provider: data.provider
|
|
2965
|
+
}));
|
|
2966
|
+
break;
|
|
2967
|
+
}
|
|
2968
|
+
} catch (error) {
|
|
2969
|
+
ws.send(JSON.stringify({
|
|
2970
|
+
type: 'error',
|
|
2971
|
+
message: error.message
|
|
2972
|
+
}));
|
|
2973
|
+
}
|
|
2974
|
+
});
|
|
2975
|
+
|
|
2976
|
+
ws.on('close', () => {
|
|
2977
|
+
console.log('WebSocket connection closed');
|
|
2978
|
+
});
|
|
2979
|
+
|
|
2980
|
+
// Send initial device list
|
|
2981
|
+
discoverDevices().then(devices => {
|
|
2982
|
+
ws.send(JSON.stringify({
|
|
2983
|
+
type: 'devices_updated',
|
|
2984
|
+
devices
|
|
2985
|
+
}));
|
|
2986
|
+
});
|
|
2987
|
+
});
|
|
2988
|
+
|
|
2989
|
+
// Android UIAutomator2 Installation
|
|
2990
|
+
app.post('/api/android/install-uiautomator2', async (req, res) => {
|
|
2991
|
+
const { device } = req.body;
|
|
2992
|
+
|
|
2993
|
+
if (!device) {
|
|
2994
|
+
return res.status(400).json({ success: false, error: 'Device name required' });
|
|
2995
|
+
}
|
|
2996
|
+
|
|
2997
|
+
try {
|
|
2998
|
+
console.log(`š„ Installing UIAutomator2 on ${device}...`);
|
|
2999
|
+
|
|
3000
|
+
// Find device UDID
|
|
3001
|
+
const deviceObj = connectedDevices.find(d => d.name === device);
|
|
3002
|
+
if (!deviceObj) {
|
|
3003
|
+
return res.json({
|
|
3004
|
+
success: false,
|
|
3005
|
+
error: 'Device not found or not connected'
|
|
3006
|
+
});
|
|
3007
|
+
}
|
|
3008
|
+
|
|
3009
|
+
// Use the helper function
|
|
3010
|
+
const result = await installUIAutomator2(deviceObj.udid, device);
|
|
3011
|
+
|
|
3012
|
+
res.json(result);
|
|
3013
|
+
|
|
3014
|
+
} catch (error) {
|
|
3015
|
+
console.error('ā UIAutomator2 installation error:', error.message);
|
|
3016
|
+
res.json({
|
|
3017
|
+
success: false,
|
|
3018
|
+
error: error.message,
|
|
3019
|
+
suggestion: 'Please install manually using: npm install -g appium-uiautomator2-driver'
|
|
3020
|
+
});
|
|
3021
|
+
}
|
|
3022
|
+
});
|
|
3023
|
+
|
|
3024
|
+
// ============================================
|
|
3025
|
+
// Recording & Replay API Endpoints
|
|
3026
|
+
// ============================================
|
|
3027
|
+
|
|
3028
|
+
// Start recording
|
|
3029
|
+
app.post('/api/recording/start', async (req, res) => {
|
|
3030
|
+
try {
|
|
3031
|
+
const { name, devices } = req.body;
|
|
3032
|
+
const result = await startRecording(name, devices);
|
|
3033
|
+
res.json(result);
|
|
3034
|
+
} catch (error) {
|
|
3035
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3036
|
+
}
|
|
3037
|
+
});
|
|
3038
|
+
|
|
3039
|
+
// Stop recording
|
|
3040
|
+
app.post('/api/recording/stop', async (req, res) => {
|
|
3041
|
+
try {
|
|
3042
|
+
const result = await stopRecording();
|
|
3043
|
+
res.json(result);
|
|
3044
|
+
} catch (error) {
|
|
3045
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3046
|
+
}
|
|
3047
|
+
});
|
|
3048
|
+
|
|
3049
|
+
// Get recording status
|
|
3050
|
+
app.get('/api/recording/status', (req, res) => {
|
|
3051
|
+
res.json({
|
|
3052
|
+
isRecording,
|
|
3053
|
+
recording: currentRecording
|
|
3054
|
+
});
|
|
3055
|
+
});
|
|
3056
|
+
|
|
3057
|
+
// List all recordings
|
|
3058
|
+
app.get('/api/recordings', async (req, res) => {
|
|
3059
|
+
try {
|
|
3060
|
+
const recordings = await listRecordings();
|
|
3061
|
+
res.json({ success: true, recordings });
|
|
3062
|
+
} catch (error) {
|
|
3063
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3064
|
+
}
|
|
3065
|
+
});
|
|
3066
|
+
|
|
3067
|
+
// Get specific recording
|
|
3068
|
+
app.get('/api/recordings/:filename', async (req, res) => {
|
|
3069
|
+
try {
|
|
3070
|
+
const recording = await loadRecording(req.params.filename);
|
|
3071
|
+
res.json({ success: true, recording });
|
|
3072
|
+
} catch (error) {
|
|
3073
|
+
res.status(404).json({ success: false, error: 'Recording not found' });
|
|
3074
|
+
}
|
|
3075
|
+
});
|
|
3076
|
+
|
|
3077
|
+
// Delete recording
|
|
3078
|
+
app.delete('/api/recordings/:filename', async (req, res) => {
|
|
3079
|
+
try {
|
|
3080
|
+
await deleteRecording(req.params.filename);
|
|
3081
|
+
res.json({ success: true });
|
|
3082
|
+
} catch (error) {
|
|
3083
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3084
|
+
}
|
|
3085
|
+
});
|
|
3086
|
+
|
|
3087
|
+
// Update recording
|
|
3088
|
+
app.put('/api/recordings/:filename', async (req, res) => {
|
|
3089
|
+
try {
|
|
3090
|
+
const { filename } = req.params;
|
|
3091
|
+
const updatedRecording = req.body;
|
|
3092
|
+
|
|
3093
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
3094
|
+
await fs.writeFile(filepath, JSON.stringify(updatedRecording, null, 2));
|
|
3095
|
+
|
|
3096
|
+
res.json({ success: true, recording: updatedRecording });
|
|
3097
|
+
} catch (error) {
|
|
3098
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3099
|
+
}
|
|
3100
|
+
});
|
|
3101
|
+
|
|
3102
|
+
// Save new recording
|
|
3103
|
+
app.post('/api/recordings/save', async (req, res) => {
|
|
3104
|
+
try {
|
|
3105
|
+
const { name, commands, date, type } = req.body;
|
|
3106
|
+
|
|
3107
|
+
if (!name || !commands) {
|
|
3108
|
+
return res.status(400).json({ success: false, error: 'Name and commands required' });
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
// Create filename from name (sanitize)
|
|
3112
|
+
const sanitizedName = name.replace(/[^a-z0-9_-]/gi, '_');
|
|
3113
|
+
const filename = `${sanitizedName}_${Date.now()}.json`;
|
|
3114
|
+
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
3115
|
+
|
|
3116
|
+
const recording = {
|
|
3117
|
+
name,
|
|
3118
|
+
commands,
|
|
3119
|
+
date: date || new Date().toISOString(),
|
|
3120
|
+
type: type || 'manual'
|
|
3121
|
+
};
|
|
3122
|
+
|
|
3123
|
+
await fs.writeFile(filepath, JSON.stringify(recording, null, 2));
|
|
3124
|
+
|
|
3125
|
+
res.json({ success: true, filename, recording });
|
|
3126
|
+
} catch (error) {
|
|
3127
|
+
console.error('Error saving recording:', error);
|
|
3128
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3129
|
+
}
|
|
3130
|
+
});
|
|
3131
|
+
|
|
3132
|
+
// Replay recording
|
|
3133
|
+
app.post('/api/recording/replay', async (req, res) => {
|
|
3134
|
+
try {
|
|
3135
|
+
const { filename, devices } = req.body;
|
|
3136
|
+
|
|
3137
|
+
if (!filename) {
|
|
3138
|
+
return res.status(400).json({ success: false, error: 'Filename required' });
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
if (!devices || devices.length === 0) {
|
|
3142
|
+
return res.status(400).json({ success: false, error: 'Target devices required' });
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3145
|
+
// Start replay in background, send immediate response
|
|
3146
|
+
res.json({ success: true, message: 'Replay started' });
|
|
3147
|
+
|
|
3148
|
+
// Replay will send updates via WebSocket
|
|
3149
|
+
// This is handled by WebSocket message 'replay_recording'
|
|
3150
|
+
} catch (error) {
|
|
3151
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3152
|
+
}
|
|
3153
|
+
});
|
|
3154
|
+
|
|
3155
|
+
// Screenshots API
|
|
3156
|
+
app.get('/api/screenshots', async (req, res) => {
|
|
3157
|
+
try {
|
|
3158
|
+
// Ensure screenshots directory exists
|
|
3159
|
+
await fs.mkdir(SCREENSHOTS_DIR, { recursive: true });
|
|
3160
|
+
|
|
3161
|
+
const files = await fs.readdir(SCREENSHOTS_DIR);
|
|
3162
|
+
const screenshots = files
|
|
3163
|
+
.filter(f => f.endsWith('.png'))
|
|
3164
|
+
.map(f => {
|
|
3165
|
+
const stat = require('fs').statSync(path.join(SCREENSHOTS_DIR, f));
|
|
3166
|
+
return {
|
|
3167
|
+
filename: f,
|
|
3168
|
+
path: `/api/screenshots/${f}`,
|
|
3169
|
+
size: stat.size,
|
|
3170
|
+
timestamp: stat.mtime.getTime(),
|
|
3171
|
+
created: stat.mtime
|
|
3172
|
+
};
|
|
3173
|
+
})
|
|
3174
|
+
.sort((a, b) => b.timestamp - a.timestamp);
|
|
3175
|
+
|
|
3176
|
+
res.json({ success: true, screenshots });
|
|
3177
|
+
} catch (error) {
|
|
3178
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3179
|
+
}
|
|
3180
|
+
});
|
|
3181
|
+
|
|
3182
|
+
// Serve screenshot files
|
|
3183
|
+
app.get('/api/screenshots/:filename', (req, res) => {
|
|
3184
|
+
const filepath = path.join(SCREENSHOTS_DIR, req.params.filename);
|
|
3185
|
+
res.sendFile(filepath, (err) => {
|
|
3186
|
+
if (err) {
|
|
3187
|
+
res.status(404).json({ success: false, error: 'Screenshot not found' });
|
|
3188
|
+
}
|
|
3189
|
+
});
|
|
3190
|
+
});
|
|
3191
|
+
|
|
3192
|
+
// Delete screenshot
|
|
3193
|
+
app.delete('/api/screenshots/:filename', async (req, res) => {
|
|
3194
|
+
try {
|
|
3195
|
+
const filepath = path.join(SCREENSHOTS_DIR, req.params.filename);
|
|
3196
|
+
await fs.unlink(filepath);
|
|
3197
|
+
res.json({ success: true });
|
|
3198
|
+
} catch (error) {
|
|
3199
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3200
|
+
}
|
|
3201
|
+
});
|
|
3202
|
+
|
|
3203
|
+
// List installed apps on device
|
|
3204
|
+
app.post('/api/apps/list', async (req, res) => {
|
|
3205
|
+
try {
|
|
3206
|
+
const { devices } = req.body;
|
|
3207
|
+
|
|
3208
|
+
if (!devices || devices.length === 0) {
|
|
3209
|
+
return res.status(400).json({ success: false, error: 'Device selection required' });
|
|
3210
|
+
}
|
|
3211
|
+
|
|
3212
|
+
const deviceObjects = connectedDevices.filter(d =>
|
|
3213
|
+
devices.includes(d.name) || devices.includes(d.udid) || devices.includes(d.serial)
|
|
3214
|
+
);
|
|
3215
|
+
|
|
3216
|
+
if (deviceObjects.length === 0) {
|
|
3217
|
+
return res.status(400).json({ success: false, error: 'No connected devices found' });
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
const results = {};
|
|
3221
|
+
|
|
3222
|
+
for (const device of deviceObjects) {
|
|
3223
|
+
try {
|
|
3224
|
+
let apps = [];
|
|
3225
|
+
|
|
3226
|
+
if (device.platform === 'android') {
|
|
3227
|
+
// List Android apps
|
|
3228
|
+
const { execSync } = require('child_process');
|
|
3229
|
+
const serial = device.udid || device.serial;
|
|
3230
|
+
const output = execSync(`adb -s ${serial} shell pm list packages -3`, { encoding: 'utf-8' });
|
|
3231
|
+
apps = output
|
|
3232
|
+
.split('\n')
|
|
3233
|
+
.filter(line => line.startsWith('package:'))
|
|
3234
|
+
.map(line => line.replace('package:', '').trim())
|
|
3235
|
+
.filter(pkg => pkg)
|
|
3236
|
+
.sort();
|
|
3237
|
+
} else if (device.platform === 'ios') {
|
|
3238
|
+
// List iOS apps - requires ideviceinstaller
|
|
3239
|
+
const { execSync } = require('child_process');
|
|
3240
|
+
const udid = device.udid;
|
|
3241
|
+
try {
|
|
3242
|
+
// Try new syntax first (ideviceinstaller list)
|
|
3243
|
+
let output;
|
|
3244
|
+
try {
|
|
3245
|
+
output = execSync(`ideviceinstaller -u ${udid} list --user`, { encoding: 'utf-8', timeout: 30000 });
|
|
3246
|
+
} catch (e) {
|
|
3247
|
+
// Fallback to old syntax
|
|
3248
|
+
output = execSync(`ideviceinstaller -u ${udid} -l`, { encoding: 'utf-8', timeout: 30000 });
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
// Parse output - format is "BundleID - AppName" or CFBundleIdentifier format
|
|
3252
|
+
apps = output
|
|
3253
|
+
.split('\n')
|
|
3254
|
+
.filter(line => {
|
|
3255
|
+
const trimmed = line.trim();
|
|
3256
|
+
// Skip empty lines, Total: line, and CSV header
|
|
3257
|
+
return trimmed &&
|
|
3258
|
+
!trimmed.startsWith('Total:') &&
|
|
3259
|
+
!trimmed.startsWith('CFBundleIdentifier');
|
|
3260
|
+
})
|
|
3261
|
+
.map(line => {
|
|
3262
|
+
// Try different formats
|
|
3263
|
+
if (line.includes(' - ')) {
|
|
3264
|
+
const match = line.match(/^(.+?)\s+-\s+(.+?)$/);
|
|
3265
|
+
return match ? { id: match[1].trim(), name: match[2].trim() } : null;
|
|
3266
|
+
} else if (line.includes(',')) {
|
|
3267
|
+
// Format: "BundleID", "Version", "Name"
|
|
3268
|
+
const parts = line.split(',').map(p => p.trim().replace(/"/g, ''));
|
|
3269
|
+
return parts.length >= 3 ? { id: parts[0], name: parts[2] } : null;
|
|
3270
|
+
} else if (line.match(/^[a-zA-Z0-9.-]+$/)) {
|
|
3271
|
+
// Just bundle ID
|
|
3272
|
+
return { id: line.trim(), name: line.trim() };
|
|
3273
|
+
}
|
|
3274
|
+
return null;
|
|
3275
|
+
})
|
|
3276
|
+
.filter(app => app)
|
|
3277
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
3278
|
+
|
|
3279
|
+
if (apps.length === 0) {
|
|
3280
|
+
apps = [{ error: 'No user apps found or unable to parse output' }];
|
|
3281
|
+
}
|
|
3282
|
+
} catch (error) {
|
|
3283
|
+
console.error('iOS apps list error:', error.message);
|
|
3284
|
+
apps = [{ error: `Failed to list apps: ${error.message}` }];
|
|
3285
|
+
}
|
|
3286
|
+
}
|
|
3287
|
+
|
|
3288
|
+
results[device.name] = {
|
|
3289
|
+
success: true,
|
|
3290
|
+
platform: device.platform,
|
|
3291
|
+
apps: apps,
|
|
3292
|
+
count: Array.isArray(apps) ? apps.length : 0
|
|
3293
|
+
};
|
|
3294
|
+
} catch (error) {
|
|
3295
|
+
results[device.name] = {
|
|
3296
|
+
success: false,
|
|
3297
|
+
error: error.message
|
|
3298
|
+
};
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
|
|
3302
|
+
res.json({ success: true, results });
|
|
3303
|
+
} catch (error) {
|
|
3304
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3305
|
+
}
|
|
3306
|
+
});
|
|
3307
|
+
|
|
3308
|
+
// Get app info
|
|
3309
|
+
app.post('/api/apps/info', async (req, res) => {
|
|
3310
|
+
try {
|
|
3311
|
+
const { device, bundleId } = req.body;
|
|
3312
|
+
|
|
3313
|
+
if (!device || !bundleId) {
|
|
3314
|
+
return res.status(400).json({ success: false, error: 'Device and bundle ID required' });
|
|
3315
|
+
}
|
|
3316
|
+
|
|
3317
|
+
const deviceObj = discoveredDevices.find(d => d.name === device);
|
|
3318
|
+
if (!deviceObj) {
|
|
3319
|
+
return res.status(404).json({ success: false, error: 'Device not found' });
|
|
3320
|
+
}
|
|
3321
|
+
|
|
3322
|
+
const { execSync } = require('child_process');
|
|
3323
|
+
let appInfo = {};
|
|
3324
|
+
|
|
3325
|
+
try {
|
|
3326
|
+
if (deviceObj.platform === 'android') {
|
|
3327
|
+
// Get Android app info
|
|
3328
|
+
const serial = deviceObj.udid || deviceObj.serial;
|
|
3329
|
+
|
|
3330
|
+
// Get app version
|
|
3331
|
+
try {
|
|
3332
|
+
const versionOutput = execSync(
|
|
3333
|
+
`adb -s ${serial} shell dumpsys package ${bundleId} | grep versionName`,
|
|
3334
|
+
{ encoding: 'utf-8', timeout: 10000 }
|
|
3335
|
+
);
|
|
3336
|
+
const versionMatch = versionOutput.match(/versionName=([^\s]+)/);
|
|
3337
|
+
if (versionMatch) {
|
|
3338
|
+
appInfo.version = versionMatch[1];
|
|
3339
|
+
}
|
|
3340
|
+
} catch (e) {
|
|
3341
|
+
appInfo.version = 'Unknown';
|
|
3342
|
+
}
|
|
3343
|
+
|
|
3344
|
+
// Get app label/name
|
|
3345
|
+
try {
|
|
3346
|
+
const labelOutput = execSync(
|
|
3347
|
+
`adb -s ${serial} shell dumpsys package ${bundleId} | grep -A 1 "applicationInfo"`,
|
|
3348
|
+
{ encoding: 'utf-8', timeout: 10000 }
|
|
3349
|
+
);
|
|
3350
|
+
appInfo.name = bundleId;
|
|
3351
|
+
} catch (e) {
|
|
3352
|
+
appInfo.name = bundleId;
|
|
3353
|
+
}
|
|
3354
|
+
|
|
3355
|
+
// Get install location
|
|
3356
|
+
try {
|
|
3357
|
+
const pathOutput = execSync(
|
|
3358
|
+
`adb -s ${serial} shell pm path ${bundleId}`,
|
|
3359
|
+
{ encoding: 'utf-8', timeout: 10000 }
|
|
3360
|
+
);
|
|
3361
|
+
appInfo.path = pathOutput.replace('package:', '').trim();
|
|
3362
|
+
} catch (e) {
|
|
3363
|
+
appInfo.path = 'Unknown';
|
|
3364
|
+
}
|
|
3365
|
+
|
|
3366
|
+
appInfo.bundleId = bundleId;
|
|
3367
|
+
appInfo.platform = 'Android';
|
|
3368
|
+
|
|
3369
|
+
} else if (deviceObj.platform === 'ios') {
|
|
3370
|
+
// Get iOS app info
|
|
3371
|
+
const udid = deviceObj.udid;
|
|
3372
|
+
|
|
3373
|
+
try {
|
|
3374
|
+
// Try to get app info using ideviceinstaller
|
|
3375
|
+
const output = execSync(
|
|
3376
|
+
`ideviceinstaller -u ${udid} list --user | grep "${bundleId}"`,
|
|
3377
|
+
{ encoding: 'utf-8', timeout: 10000 }
|
|
3378
|
+
);
|
|
3379
|
+
|
|
3380
|
+
// Parse CSV format: BundleID, Version, Name
|
|
3381
|
+
const parts = output.split(',').map(p => p.trim().replace(/"/g, ''));
|
|
3382
|
+
if (parts.length >= 3) {
|
|
3383
|
+
appInfo.bundleId = parts[0];
|
|
3384
|
+
appInfo.version = parts[1];
|
|
3385
|
+
appInfo.name = parts[2];
|
|
3386
|
+
} else {
|
|
3387
|
+
appInfo.bundleId = bundleId;
|
|
3388
|
+
appInfo.name = bundleId;
|
|
3389
|
+
appInfo.version = 'Unknown';
|
|
3390
|
+
}
|
|
3391
|
+
} catch (e) {
|
|
3392
|
+
// Fallback
|
|
3393
|
+
appInfo.bundleId = bundleId;
|
|
3394
|
+
appInfo.name = bundleId;
|
|
3395
|
+
appInfo.version = 'Unknown';
|
|
3396
|
+
appInfo.error = 'Could not retrieve detailed info';
|
|
3397
|
+
}
|
|
3398
|
+
|
|
3399
|
+
appInfo.platform = 'iOS';
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3402
|
+
res.json({ success: true, appInfo });
|
|
3403
|
+
|
|
3404
|
+
} catch (error) {
|
|
3405
|
+
res.json({
|
|
3406
|
+
success: false,
|
|
3407
|
+
error: error.message,
|
|
3408
|
+
appInfo: {
|
|
3409
|
+
bundleId: bundleId,
|
|
3410
|
+
platform: deviceObj.platform,
|
|
3411
|
+
error: 'Failed to get app info'
|
|
3412
|
+
}
|
|
3413
|
+
});
|
|
3414
|
+
}
|
|
3415
|
+
|
|
3416
|
+
} catch (error) {
|
|
3417
|
+
res.status(500).json({ success: false, error: error.message });
|
|
3418
|
+
}
|
|
3419
|
+
});
|
|
3420
|
+
|
|
3421
|
+
// Upgrade HTTP server to WebSocket
|
|
3422
|
+
let server;
|
|
3423
|
+
|
|
3424
|
+
function startServer(options = {}) {
|
|
3425
|
+
const port = options.port || PORT;
|
|
3426
|
+
const shouldOpenBrowser = options.browser !== false;
|
|
3427
|
+
const frontendUrl = 'https://devicely-ai.vercel.app';
|
|
3428
|
+
|
|
3429
|
+
console.log(`Frontend available at: ${frontendUrl}\n`);
|
|
3430
|
+
|
|
3431
|
+
return new Promise((resolve, reject) => {
|
|
3432
|
+
server = app.listen(port, () => {
|
|
3433
|
+
console.log(`Server running on port ${port}`);
|
|
3434
|
+
console.log(`WebSocket server ready`);
|
|
3435
|
+
|
|
3436
|
+
// Initial device discovery
|
|
3437
|
+
discoverDevices().then(devices => {
|
|
3438
|
+
console.log(`Discovered ${devices.length} devices`);
|
|
3439
|
+
|
|
3440
|
+
// Open browser if not disabled
|
|
3441
|
+
if (shouldOpenBrowser) {
|
|
3442
|
+
console.log(`\nš Opening browser to ${frontendUrl}...`);
|
|
3443
|
+
const open = require('open');
|
|
3444
|
+
open(frontendUrl).catch(err => {
|
|
3445
|
+
console.log(`\nš± Please open ${frontendUrl} in your browser`);
|
|
3446
|
+
});
|
|
3447
|
+
}
|
|
3448
|
+
|
|
3449
|
+
resolve({ port, devices });
|
|
3450
|
+
}).catch(reject);
|
|
3451
|
+
});
|
|
3452
|
+
|
|
3453
|
+
server.on('upgrade', (request, socket, head) => {
|
|
3454
|
+
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
3455
|
+
wss.emit('connection', ws, request);
|
|
3456
|
+
});
|
|
3457
|
+
});
|
|
3458
|
+
|
|
3459
|
+
server.on('error', reject);
|
|
3460
|
+
});
|
|
3461
|
+
}
|
|
3462
|
+
|
|
3463
|
+
function stopServer() {
|
|
3464
|
+
return new Promise((resolve) => {
|
|
3465
|
+
if (server) {
|
|
3466
|
+
server.close(resolve);
|
|
3467
|
+
} else {
|
|
3468
|
+
resolve();
|
|
3469
|
+
}
|
|
3470
|
+
});
|
|
3471
|
+
}
|
|
3472
|
+
|
|
3473
|
+
// Export for CLI usage
|
|
3474
|
+
module.exports = {
|
|
3475
|
+
startServer,
|
|
3476
|
+
stopServer
|
|
3477
|
+
};
|
|
3478
|
+
|
|
3479
|
+
// Start server if run directly (not imported as module)
|
|
3480
|
+
if (require.main === module) {
|
|
3481
|
+
startServer().catch(err => {
|
|
3482
|
+
console.error('Failed to start server:', err);
|
|
3483
|
+
process.exit(1);
|
|
3484
|
+
});
|
|
3485
|
+
}
|