@kaeawc/auto-mobile 0.0.92 → 0.0.93
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/dist/build-info.json +12 -12
- package/dist/schemas/test-plan.schema.json +370 -52
- package/dist/src/{chunk-jhnbfj19.js → chunk-00167wan.js} +5 -5
- package/dist/src/chunk-0jrrsnc9.js +6 -0
- package/dist/src/chunk-0n6swkwg.js +5 -0
- package/dist/src/chunk-0qsy1qsx.js +57 -0
- package/dist/src/chunk-11m8wj8j.js +237 -0
- package/dist/src/{chunk-4pfftt07.js → chunk-1p7xf5kb.js} +3 -3
- package/dist/src/chunk-23p5f095.js +4 -0
- package/dist/src/{chunk-a4k9rt7z.js → chunk-26k317v5.js} +3 -3
- package/dist/src/chunk-284ptqa4.js +7 -0
- package/dist/src/chunk-28re4xrg.js +4 -0
- package/dist/src/chunk-2f9rkmhx.js +5 -0
- package/dist/src/chunk-2fxdh48t.js +4 -0
- package/dist/src/chunk-2tbdrbt6.js +4 -0
- package/dist/src/chunk-2tqzq5qh.js +971 -0
- package/dist/src/chunk-32gvv9b4.js +21 -0
- package/dist/src/chunk-3f3t1x97.js +8 -0
- package/dist/src/chunk-3fspkbc7.js +4 -0
- package/dist/src/chunk-3qwrzxh0.js +11 -0
- package/dist/src/chunk-3sy6ahhz.js +26 -0
- package/dist/src/chunk-3vg455e6.js +4 -0
- package/dist/src/chunk-3xkpk44w.js +5 -0
- package/dist/src/chunk-3y6eykz9.js +4 -0
- package/dist/src/chunk-49bsqdx3.js +4 -0
- package/dist/src/chunk-4hw3665t.js +42 -0
- package/dist/src/chunk-58wzr3mt.js +5 -0
- package/dist/src/chunk-5d2hft6c.js +5 -0
- package/dist/src/chunk-5snsn9cf.js +4 -0
- package/dist/src/chunk-5tm9mn47.js +54 -0
- package/dist/src/chunk-5zc77a5t.js +4 -0
- package/dist/src/chunk-64j0majr.js +19 -0
- package/dist/src/chunk-65y8v4td.js +17 -0
- package/dist/src/chunk-6awz7vhq.js +5 -0
- package/dist/src/{chunk-stfzjr9y.js → chunk-6bznss4t.js} +5 -5
- package/dist/src/chunk-6ep7f5ge.js +4 -0
- package/dist/src/{chunk-0dfnyfkh.js → chunk-6wt9rgjf.js} +3 -3
- package/dist/src/chunk-6xmss8er.js +8 -0
- package/dist/src/chunk-710rxz9y.js +5 -0
- package/dist/src/chunk-7cs2da62.js +5 -0
- package/dist/src/chunk-7g103b54.js +4 -0
- package/dist/src/chunk-7j5vj4pa.js +4 -0
- package/dist/src/chunk-7rz9898k.js +5 -0
- package/dist/src/chunk-7tw8x05v.js +4 -0
- package/dist/src/chunk-7zy586cb.js +4 -0
- package/dist/src/{chunk-r0f1q783.js → chunk-8037tzzj.js} +3 -3
- package/dist/src/chunk-84nanf8s.js +5 -0
- package/dist/src/{chunk-950qcq1e.js → chunk-8g1922rp.js} +4 -4
- package/dist/src/chunk-8gvwcv2p.js +4 -0
- package/dist/src/{chunk-sz1a7p43.js → chunk-8ph29g99.js} +1 -1
- package/dist/src/chunk-8thrmfat.js +4 -0
- package/dist/src/chunk-8zgzzs7k.js +78 -0
- package/dist/src/chunk-97b1zmaq.js +4 -0
- package/dist/src/chunk-9fth9ayh.js +4 -0
- package/dist/src/chunk-9j6anhjr.js +4 -0
- package/dist/src/{chunk-w7zsh13a.js → chunk-aabchzxk.js} +4 -4
- package/dist/src/{chunk-wry6skrm.js → chunk-ayp07wbb.js} +1 -1
- package/dist/src/chunk-bfjwqk8q.js +4 -0
- package/dist/src/{chunk-jdqvcq0a.js → chunk-bfw6125s.js} +3 -3
- package/dist/src/chunk-bnhscm2n.js +4 -0
- package/dist/src/chunk-bxmsax22.js +5 -0
- package/dist/src/chunk-c1vs4g1n.js +4 -0
- package/dist/src/chunk-ct3e7yng.js +4 -0
- package/dist/src/{chunk-8en08r7q.js → chunk-cyy71ggq.js} +3 -3
- package/dist/src/chunk-ddzkz92z.js +4 -0
- package/dist/src/chunk-dgrbdpb7.js +9 -0
- package/dist/src/chunk-drdz8hee.js +5 -0
- package/dist/src/chunk-e98dqnc9.js +145 -0
- package/dist/src/chunk-eersndy7.js +5 -0
- package/dist/src/chunk-eggq53ks.js +4 -0
- package/dist/src/chunk-f2dya7cs.js +4 -0
- package/dist/src/chunk-fbakd6cw.js +4 -0
- package/dist/src/chunk-fgb98zjj.js +5 -0
- package/dist/src/chunk-fmpad823.js +5 -0
- package/dist/src/{chunk-v90es00d.js → chunk-g04bwyj3.js} +2 -2
- package/dist/src/chunk-g0xr8zw0.js +4 -0
- package/dist/src/chunk-g3rjs80x.js +4 -0
- package/dist/src/chunk-g78rtrfv.js +4 -0
- package/dist/src/{chunk-r20pe1nv.js → chunk-g7tmjbkt.js} +3 -3
- package/dist/src/chunk-gabgv3y5.js +4 -0
- package/dist/src/chunk-gmr45m8f.js +4 -0
- package/dist/src/chunk-gsyfebqj.js +4 -0
- package/dist/src/chunk-h5rpn9wr.js +247 -0
- package/dist/src/chunk-hb1x7v55.js +4 -0
- package/dist/src/chunk-hrfytkxh.js +168 -0
- package/dist/src/chunk-j4yjzbak.js +4 -0
- package/dist/src/chunk-jd6a5v6p.js +5 -0
- package/dist/src/chunk-jh6vhqzx.js +5 -0
- package/dist/src/chunk-kn5spq15.js +4 -0
- package/dist/src/{chunk-w2mwa0jk.js → chunk-m94qs0f0.js} +2 -2
- package/dist/src/chunk-mjrps0ac.js +7 -0
- package/dist/src/chunk-n03dmn5q.js +5 -0
- package/dist/src/chunk-n72qhwd9.js +4 -0
- package/dist/src/{chunk-km0dy5vc.js → chunk-ndt1ccxm.js} +9 -9
- package/dist/src/chunk-nr6y0n4y.js +5 -0
- package/dist/src/chunk-pcsen2vs.js +4 -0
- package/dist/src/chunk-ppfr0b8h.js +4 -0
- package/dist/src/chunk-q10bdnat.js +4 -0
- package/dist/src/chunk-q9xmq595.js +4 -0
- package/dist/src/{chunk-2v7tw1nj.js → chunk-qcxzr2my.js} +3 -3
- package/dist/src/chunk-qf6nynk6.js +7 -0
- package/dist/src/chunk-qyqypn28.js +5 -0
- package/dist/src/chunk-r2epb56s.js +4 -0
- package/dist/src/chunk-r5bxavdx.js +311 -0
- package/dist/src/{chunk-r14wwk37.js → chunk-r6z1eztj.js} +12 -12
- package/dist/src/{chunk-d57432wq.js → chunk-r7bpkgff.js} +2 -2
- package/dist/src/chunk-r8jf3d92.js +4 -0
- package/dist/src/{chunk-9rkfyt6q.js → chunk-rbpdk7m0.js} +3 -3
- package/dist/src/chunk-rc0dbypm.js +4 -0
- package/dist/src/chunk-rhcty4ms.js +4 -0
- package/dist/src/chunk-rpvckv3p.js +4 -0
- package/dist/src/{chunk-s1zq65ny.js → chunk-rqc9ap3x.js} +2 -2
- package/dist/src/chunk-rvvy1bte.js +7 -0
- package/dist/src/chunk-ry0mz41y.js +4 -0
- package/dist/src/{chunk-34zxqcmq.js → chunk-s3jc6cwp.js} +3 -3
- package/dist/src/chunk-sfv61xjb.js +6 -0
- package/dist/src/chunk-t6bfvfkg.js +4 -0
- package/dist/src/chunk-t6c8akcm.js +5 -0
- package/dist/src/chunk-t7w8rctc.js +4 -0
- package/dist/src/chunk-thbh3jew.js +5 -0
- package/dist/src/chunk-v2wd4n3e.js +5 -0
- package/dist/src/{chunk-zg67wjkh.js → chunk-v6pya0dm.js} +3 -3
- package/dist/src/chunk-vy3bwm1d.js +17 -0
- package/dist/src/chunk-w3vs79ex.js +27 -0
- package/dist/src/chunk-w4zga19f.js +4 -0
- package/dist/src/chunk-w5b2jwk3.js +14 -0
- package/dist/src/chunk-w7hkv422.js +5 -0
- package/dist/src/{chunk-qv2918jt.js → chunk-waqwcjyn.js} +2 -2
- package/dist/src/{chunk-b4cxdzwy.js → chunk-wbh8spm5.js} +7 -7
- package/dist/src/{chunk-ajsrz473.js → chunk-wyrkw6hw.js} +3 -3
- package/dist/src/chunk-xa73x2cx.js +5 -0
- package/dist/src/{chunk-eka89q3k.js → chunk-xgan0qqp.js} +1 -1
- package/dist/src/chunk-y2vs6jwg.js +4 -0
- package/dist/src/chunk-yattm52s.js +4 -0
- package/dist/src/{chunk-9y5bcy28.js → chunk-yb97j25b.js} +4 -4
- package/dist/src/{chunk-c9nk1r78.js → chunk-ybbtagbt.js} +3 -3
- package/dist/src/chunk-ycaj2sgf.js +9 -0
- package/dist/src/chunk-yf7ympyz.js +325 -0
- package/dist/src/chunk-yjawdzk8.js +4 -0
- package/dist/src/chunk-z637nqg8.js +11 -0
- package/dist/src/{chunk-0w1spptt.js → chunk-zgja5f3p.js} +4 -4
- package/dist/src/chunk-zs1sghs9.js +4 -0
- package/dist/src/daemon/processEntry.js +2 -2
- package/dist/src/index.js +4 -4
- package/dist/src/runtime/bunRuntimeGuard.js +2 -2
- package/dist/src/utils/workers/iosBundleExtractWorker.js +2 -2
- package/ios/CameraPosterInjection/Injection/CameraPosterInjection.m +466 -0
- package/package.json +3 -2
- package/schemas/test-plan.schema.json +370 -52
- package/dist/src/chunk-09442h7v.js +0 -4
- package/dist/src/chunk-0e4gm1kj.js +0 -5
- package/dist/src/chunk-0eb8576f.js +0 -4
- package/dist/src/chunk-0rjm4nx7.js +0 -5
- package/dist/src/chunk-1zmh2eak.js +0 -4
- package/dist/src/chunk-28k63ha3.js +0 -5
- package/dist/src/chunk-2d4wmp8b.js +0 -4
- package/dist/src/chunk-2e6s75qv.js +0 -78
- package/dist/src/chunk-32jpxz2y.js +0 -323
- package/dist/src/chunk-3jmvqygr.js +0 -238
- package/dist/src/chunk-3swvfhqt.js +0 -5
- package/dist/src/chunk-44bt78m9.js +0 -5
- package/dist/src/chunk-488vt2bp.js +0 -4
- package/dist/src/chunk-4fgdhcwx.js +0 -5
- package/dist/src/chunk-4jp2se4w.js +0 -4
- package/dist/src/chunk-4vhr9e4t.js +0 -4
- package/dist/src/chunk-4xd6zs3y.js +0 -15
- package/dist/src/chunk-51567pg8.js +0 -4
- package/dist/src/chunk-5agqsfev.js +0 -4
- package/dist/src/chunk-5d706gmr.js +0 -4
- package/dist/src/chunk-5kd4rqk7.js +0 -5
- package/dist/src/chunk-61t538bm.js +0 -4
- package/dist/src/chunk-6d3mmqxt.js +0 -54
- package/dist/src/chunk-6hyt398x.js +0 -5
- package/dist/src/chunk-6mnr8kpm.js +0 -4
- package/dist/src/chunk-79q5xsdc.js +0 -42
- package/dist/src/chunk-7bdgand3.js +0 -4
- package/dist/src/chunk-84cp9dw5.js +0 -4
- package/dist/src/chunk-86f2h5ww.js +0 -5
- package/dist/src/chunk-8cghfzb2.js +0 -19
- package/dist/src/chunk-9tf2p9y9.js +0 -5
- package/dist/src/chunk-a2sc4jm0.js +0 -5
- package/dist/src/chunk-aa5ng3d1.js +0 -4
- package/dist/src/chunk-b3h0a6ca.js +0 -4
- package/dist/src/chunk-b6a737qt.js +0 -4
- package/dist/src/chunk-bn64x5z5.js +0 -5
- package/dist/src/chunk-bvh649za.js +0 -12
- package/dist/src/chunk-c9tyfg4j.js +0 -26
- package/dist/src/chunk-cfsdfqnm.js +0 -4
- package/dist/src/chunk-cxyf04jc.js +0 -7
- package/dist/src/chunk-da08tx5v.js +0 -4
- package/dist/src/chunk-f2tc08m2.js +0 -4
- package/dist/src/chunk-f8tnk179.js +0 -5
- package/dist/src/chunk-f9s1kkhx.js +0 -5
- package/dist/src/chunk-fbp8a4rx.js +0 -4
- package/dist/src/chunk-fd2z0sze.js +0 -4
- package/dist/src/chunk-fk927f4q.js +0 -54
- package/dist/src/chunk-fxmr3a0f.js +0 -4
- package/dist/src/chunk-gaqwhd44.js +0 -4
- package/dist/src/chunk-ggtd5x5a.js +0 -5
- package/dist/src/chunk-gndcfrm7.js +0 -4
- package/dist/src/chunk-h3n4adc6.js +0 -310
- package/dist/src/chunk-h5pjbb83.js +0 -4
- package/dist/src/chunk-hgnnh302.js +0 -4
- package/dist/src/chunk-hmke8nhx.js +0 -5
- package/dist/src/chunk-j2bx12hn.js +0 -4
- package/dist/src/chunk-j70y1a2g.js +0 -4
- package/dist/src/chunk-js1jpyxp.js +0 -6
- package/dist/src/chunk-kbjq0qvb.js +0 -4
- package/dist/src/chunk-kfwx57xd.js +0 -4
- package/dist/src/chunk-kzwctna2.js +0 -4
- package/dist/src/chunk-m9ehyehy.js +0 -4
- package/dist/src/chunk-mct91p1f.js +0 -4
- package/dist/src/chunk-mf9spd4g.js +0 -5
- package/dist/src/chunk-mgrcansb.js +0 -4
- package/dist/src/chunk-mqc1d0eb.js +0 -6
- package/dist/src/chunk-n1zmpk0z.js +0 -4
- package/dist/src/chunk-ncyjf63g.js +0 -4
- package/dist/src/chunk-nr64d21q.js +0 -973
- package/dist/src/chunk-nwm2pq5v.js +0 -168
- package/dist/src/chunk-pm06b05d.js +0 -9
- package/dist/src/chunk-q50s00ry.js +0 -4
- package/dist/src/chunk-qwye1958.js +0 -14
- package/dist/src/chunk-r8z9pfve.js +0 -5
- package/dist/src/chunk-rdpgkjf6.js +0 -4
- package/dist/src/chunk-rkr0dks9.js +0 -5
- package/dist/src/chunk-rn84t3sf.js +0 -11
- package/dist/src/chunk-s123kn7n.js +0 -4
- package/dist/src/chunk-s73qn3fx.js +0 -4
- package/dist/src/chunk-sjn0nj4p.js +0 -5
- package/dist/src/chunk-sns0c35v.js +0 -7
- package/dist/src/chunk-t4dr5c8v.js +0 -8
- package/dist/src/chunk-tc8k9c1j.js +0 -4
- package/dist/src/chunk-teznhase.js +0 -4
- package/dist/src/chunk-ty9xgmz4.js +0 -4
- package/dist/src/chunk-tyazf3sk.js +0 -145
- package/dist/src/chunk-v6npjrjm.js +0 -5
- package/dist/src/chunk-vbvtzkwz.js +0 -5
- package/dist/src/chunk-vefd8qee.js +0 -8
- package/dist/src/chunk-vs9r72ta.js +0 -17
- package/dist/src/chunk-w88k0bgr.js +0 -4
- package/dist/src/chunk-wzdt0enk.js +0 -4
- package/dist/src/chunk-xhhv854c.js +0 -4
- package/dist/src/chunk-y58270hd.js +0 -4
- package/dist/src/chunk-yk0hmbex.js +0 -4
- package/dist/src/chunk-ympy4fdz.js +0 -28
- package/dist/src/chunk-yw436axy.js +0 -4
- package/dist/src/chunk-z04jrpjy.js +0 -5
- package/dist/src/chunk-z2xznczw.js +0 -4
- package/dist/src/chunk-z4xnrgps.js +0 -4
- package/dist/src/chunk-z7csyszv.js +0 -4
- package/dist/src/chunk-z8t0v07j.js +0 -11
- package/dist/src/chunk-z916af47.js +0 -228
- package/dist/src/chunk-zcr8he8q.js +0 -5
- package/dist/src/chunk-zd9vmkzn.js +0 -9
- package/dist/src/chunk-zj939v0h.js +0 -5
- package/dist/src/chunk-zkdjwtc1.js +0 -4
- package/dist/src/chunk-zkv5kzt6.js +0 -4
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{Zm,i,Ae,Xe,dn,ai,te,Sl,Hk,gt,gd,dr,Q,Se,Rl,Ft,l,e}from"./chunk-z8t0v07j.js";import{GF,Xt,Ji,w,ns,Cr,$h,Ge,U,Je,pe,Zr,B,fL,vT,See,uc,pc,jt,hn,iW,at,oe,hw,je,v,Un,F,To,Pe,Pw,gW,nl,S,pt,ti,ko,Tm,ce,nu,xT,iu,me,Xh,Eo,o,R,W,Im,op,Cv,cl,$w,ur,st,Io,$5,BW,Dv,qw,M,Zt,Gt,Qt,to,Da,G,VW,Dn,we,Kw,ng,KW,jC,Z5,be,ig,Yw,zo,XL,qn,Bv,ge,ZW,ek,na,Oa,Vn,pB,sn,pu,sk,_e,Lm,mu,ro,Yte,nD,gB,mR,sz,Yv,fr,xB,mre,fre,vz,hD,bc,gs,D,Sr,pl,Pre,Az,wD,Tz,hg,RD,C3,On,Are,id,Tre,kz,gg,Qv,O3,yg,xz,UB,_D,bg,jm,xre,io,Cre,PR,Tk,An,Dre,Mn,eb,_o,_,xe,k,OD,Ure,Vi}from"./chunk-h3n4adc6.js";import{g,E,ft,$e,wu}from"./chunk-mf9spd4g.js";import{L,m,ke,BD,$r}from"./chunk-32jpxz2y.js";import{so,y,hr,z,kt,n,a,b,s,p}from"./chunk-79q5xsdc.js";import{r,t,u}from"./chunk-9rkfyt6q.js";import{Lt}from"./chunk-2v7tw1nj.js";var Ce=250,Ct=3,_i=8000,Ni=3,Hi=5000,Ne=2000,Tt=1000,Bi=5000,Wi=2,It="17.0";class go extends t{get code(){return this.deadlineExhausted?"timeout":void 0}get retryable(){return this.deadlineExhausted?!0:void 0}attempts;diagnosticCause;failureKind;retryableAndroidFrameworkFailure;deadlineExhausted;phase;constructor(c,{retryableAndroidFrameworkFailure:d=!1,deadlineExhausted:h=!1,phase:f,...P}={}){super(c);this.retryableAndroidFrameworkFailure=d,this.deadlineExhausted=h,this.phase=f,this.attempts=P.attempts,this.diagnosticCause=P.diagnosticCause,this.failureKind=P.failureKind}}var Ui=4000;function $i(c){switch(c){case"package-compatibility":return"packageCompatibilityElapsedMs";case"runner-setup":return"runnerSetupElapsedMs";case"runner-connect":return"connectElapsedMs";case"runner-health":return"healthElapsedMs";default:return`${c}ElapsedMs`}}function ie(c){let d=r(c),h=Oa(d);if(h.length<=Ui)return h;let f=Math.floor((Ui-32)/2);return`${h.slice(0,f)}
|
|
3
|
-
...[diagnostic truncated]...
|
|
4
|
-
${h.slice(-f)}`}async function Gi(c,d,h,f){let P=Number.isNaN(f)?1:Math.floor(f??Ct),C=Math.max(1,Math.min(Ct,P)),A=[];for(let T=1;T<=C;T+=1){h.throwIfCallerCancelled(c),d.resetSetupState();let I=await h.runPhase(c,"runner-setup",T,{operation:(x)=>d.setup(!1,c.perf,x,h.remainingForPhase(c,"runner-setup"))}).catch((x)=>{if(x instanceof go&&A.length>0)h.fail(c,"runner-setup",T,{detail:x.diagnosticCause,deadlineExhausted:x.deadlineExhausted,failureKind:x.failureKind,previousAttemptDetails:A});throw x});if(c.onRunnerSetup?.(),h.throwIfCallerCancelled(c),I.success)break;let O=I.retryableStartupFailure===!0&&h.remainingForPhase(c,"runner-setup")<=0;if(!I.retryableStartupFailure||O||T===C)h.fail(c,"runner-setup",T,{detail:I.error??I.message,deadlineExhausted:O,previousAttemptDetails:A});A.push(`attempt ${T}/${C}: ${ie(I.error??I.message).slice(0,500)}`)}}var Dt=2000,qi=1000;class Te{timer;constructor(c){this.timer=c}throwIfCallerCancelled(c,d){if(c.signal?.aborted){if(c.deadlineFailure)throw c.deadlineFailure;throw c.signal.reason??d??Error("System UI ANR recovery cancelled")}}async runPhase(c,d,h,{operation:f,operationDeadlineMs:P}){let C=Math.min(this.remainingForPhase(c,d),P===void 0?Number.POSITIVE_INFINITY:Math.max(0,P-this.timer.now()));if(C<=0)this.fail(c,d,h,{detail:"readiness budget exhausted before phase started",deadlineExhausted:!0});let A=!1,T,I=!1,O=()=>{I=this.timer.now()>=this.totalDeadlineMs(c)};if(c.signal?.addEventListener("abort",O,{once:!0}),c.signal?.aborted)O();let x=()=>{let K=d==="runner-connect"?"CtrlProxy WebSocket connect":d==="runner-health"?"CtrlProxy readiness wait":c.device.platform==="ios"?"iOS CtrlProxy setup":"CtrlProxy package/setup";return new t(`${K} timed out: readiness phase exceeded the remaining deadline. Retry device acquisition.`)},N=(K)=>I?T===void 0?x():u(T,`Runner readiness ${d} failed`):K,H=this.timer.now(),V=!1,q=()=>{if(V)return;V=!0;let K=Math.max(0,this.timer.now()-H);c.phaseElapsedMs[d]=(c.phaseElapsedMs[d]??0)+K};try{return await Tm({timer:this.timer,timeoutMs:C,deadline:Te.movableDeadline(c,d,P),signal:c.signal,graceMs:qi,label:`Runner readiness ${d}`,preferOperationFailureOnTimeout:!0,explicitAbortError:N,defaultAbortError:()=>N(c.signal?.reason),timeoutError:()=>(A=!0,x()),onRaceSettled:q},async(K)=>{try{return await jt(`readiness:${d}`,()=>U(K,()=>f(K)))}catch(j){throw T=j,j}})}catch(K){if(q(),!I)this.throwIfCallerCancelled(c,K);return this.fail(c,d,h,{detail:K,deadlineExhausted:A||I})}finally{c.signal?.removeEventListener("abort",O),q()}}async awaitAbortSettlement(c){let d=Error("Abort settlement grace expired");try{await l(c.then(()=>{return},()=>{return}),{timer:this.timer,timeoutMs:qi,label:"Abort settlement grace",timeoutError:()=>d})}catch(h){if(h!==d)throw h}}probeTimeout(c){return Math.max(1,Math.min(Dt,this.remainingForPhase(c,"runner-health")))}static isSetupPhase(c){return c==="runner-setup"||c==="package-compatibility"}static movableDeadline(c,d,h){return h===void 0&&Te.isSetupPhase(d)?c.deadline:void 0}totalDeadlineMs(c){return c.deadline?.deadlineMs??c.totalDeadlineMs}phaseDeadlineMs(c,d){if(Te.isSetupPhase(d))return this.totalDeadlineMs(c);return c.healthDeadlineMs??this.totalDeadlineMs(c)}remainingForPhase(c,d){return Math.max(0,this.phaseDeadlineMs(c,d)-this.timer.now())}startHealthWindow(c){if(c.healthDeadlineMs!==null)return;c.healthDeadlineMs=Math.min(this.totalDeadlineMs(c),this.timer.now()+c.readinessTimeoutMs)}fail(c,d,h,{detail:f,...P}){let{device:C}=c,A=`platform=${C.platform} requested=[${c.requestedIdentity}] resolved=[${C.name} (${C.deviceId})]`,T=this.remainingForPhase(c,d),I=Object.entries(c.phaseElapsedMs).map(([H,V])=>`${$i(H)}=${V}`).join(" "),O=`${c.operationName??"startDevice"} automation runner readiness failed: ${A} phase=${d} attempts=${h} remainingBudgetMs=${T}${I?` ${I}`:""}`,x=[ie(f),...P.previousAttemptDetails??[]].join("; "),N=new go(P.failureKind?`${x}; ${O}`:`${O}: ${x}`,{retryableAndroidFrameworkFailure:C.platform==="android"&&Te.isSetupPhase(d)&&(nl(f)||gW(f)||iW(f)),deadlineExhausted:P.deadlineExhausted??!1,phase:d,attempts:h,diagnosticCause:f,failureKind:P.failureKind});if(P.deadlineExhausted)c.deadlineFailure=N;throw N}}class et{dependencies;phases;constructor(c,d){this.dependencies=c;this.phases=d}async isResponsive(c,d,h){let f=c.deadlineFailure;try{return await this.probeUntilEvidence(c,d,h)}catch(P){if(!this.isHealthWindowExhaustion(c,P))throw P;return c.deadlineFailure=f,e.info(`[RunnerReadiness] iOS post-setup health window exhausted; restarting runner: ${P.message}`),!1}}isHealthWindowExhaustion(c,d){return d instanceof go&&d.deadlineExhausted&&(d.phase==="runner-health"||d.phase==="runner-connect")&&!c.signal?.aborted&&this.phases.remainingForPhase(c,"runner-setup")>0}async probeUntilEvidence(c,d,h){let f=Math.max(1,this.dependencies.iosPostSetupRestartMinFailedProbes??Ni);for(let P=1;P<=f;P++){let C=d.runnerSnapshot?.().xcTestProcess;if(await this.isResponsiveOnce(c,h,P))return!0;if(C&&et.exitedRunnerIsCurrent(d,C))return!1;let A=await this.phases.runPhase(c,"runner-health",P,{operation:()=>d.checkRunningWithReason?.()??Promise.resolve(void 0)});if(A?.ok===!1&&A.reason==="refused")return!1;if(P<f)await this.dependencies.timer.sleep(Math.min(Ce,this.phases.remainingForPhase(c,"runner-health"))),this.phases.throwIfCallerCancelled(c)}return!1}static exitedRunnerIsCurrent(c,d){if(d.exitCode===null&&d.signalCode===null)return!1;let h=c.runnerSnapshot?.().xcTestProcess??null;return h===null||h===d}async isResponsiveOnce(c,d,h){if(!(d.isConnected()||await this.phases.runPhase(c,"runner-connect",h,{operation:(C)=>d.connectWithoutSetup(C)})))return!1;let P=h===1?Math.min(_i,this.phases.remainingForPhase(c,"runner-health")):this.phases.probeTimeout(c);return await this.phases.runPhase(c,"runner-health",h,{operation:()=>d.verifyServiceReady(1,0,P)})}}var Ot="com.android.systemui",Ta="System UI isn't responding",Ia="Wait",xt="android:id/alertTitle",Et="android:id/button2",Mt="android:id/button1",ka=3;function _t(c,d=new Da){let h=d.extractWindowRootGroups(c,"topmost-first")[0]??d.extractRootNodes(c);if(h.length===0)return;let f={systemUi:_a(c)||Fa(c),systemWindow:Na(c),titleFound:!1,alertTitleFound:!1,closeAppResourceFound:!1};for(let A of h)d.traverseNode(A,(T)=>Ma(T,d,f));let P=xa(f)?f.waitBounds:void 0;if(P)return{waitBounds:P};let C=Ea(f)?f.waitBoundsByResourceId:void 0;if(C)return{waitBounds:C};return}function xa(c){return c.titleFound&&c.waitBounds!==void 0&&c.systemUi}function Ea(c){return c.systemUi&&c.systemWindow&&c.alertTitleFound&&c.closeAppResourceFound&&c.waitBoundsByResourceId!==void 0}function Ma(c,d,h){let f=d.extractNodeProperties(c),P=tt(f.text,f["content-desc"]),C=tt(f.packageName,tt(f.package,f["package-name"])),A=tt(f["resource-id"],f.resourceId);if(h.systemUi||=C===Ot,h.titleFound||=P===Ta,h.alertTitleFound||=A===xt,h.closeAppResourceFound||=A===Mt,P===Ia)h.waitBounds??=Ki(d,c);if(A===Et)h.waitBoundsByResourceId??=Ki(d,c)}function tt(c,d){return String(c??d??"")}function Ki(c,d){return c.parseBounds(Ft(d))??void 0}function Fa(c){return zi(c)?.packageName===Ot}function _a(c){return c.packageName===Ot}function Na(c){return zi(c)?.type===ka}function zi(c){let d=c.windows;if(!d||d.length===0)return;return d.reduce((h,f)=>(f.windowLayer??0)>(h.windowLayer??0)?f:h)}function ji(c){return{x:Math.floor((c.left+c.right)/2),y:Math.floor((c.top+c.bottom)/2)}}class WA extends go{}var Nt=1000,Ha=2,Ba=5000;class Ht{timer;phases;constructor(c,d){this.timer=c;this.phases=d}async recoverIfPresent(c,d){let h=this.systemUiAnrClient(c,d);if(!h)return;let f=Math.min(c.healthDeadlineMs??c.totalDeadlineMs,this.timer.now()+Ba),P=await this.readSystemUiAnrHierarchy(c,h,f),C=_t(P??{hierarchy:{}});if(!C)return;await this.selectSystemUiAnrWait(c,h,C.waitBounds,f),await this.waitForSystemUiAnrRecovery(c,h,f,P?.updatedAt)}systemUiAnrClient(c,d){if(c.device.platform!=="android"||!d.getAccessibilityHierarchy||!d.requestTapCoordinates)return;return{getAccessibilityHierarchy:(...h)=>d.getAccessibilityHierarchy(...h),requestTapCoordinates:(...h)=>d.requestTapCoordinates(...h)}}async readSystemUiAnrHierarchy(c,d,h,{minTimestamp:f=0,required:P=!1}={}){let C=Math.min(this.phases.probeTimeout(c),this.remainingSystemUiAnrRecoveryBudget(h));if(C<=0){if(this.phases.throwIfCallerCancelled(c),!P)return null;throw this.systemUiAnrRecoveryRequired(c,"recovery budget expired before the dialog state could be confirmed")}try{let A=await this.phases.runPhase(c,"runner-health",1,{operation:async(I)=>await d.getAccessibilityHierarchy(void 0,{skipWaitForFresh:!0,minTimestamp:f,disableAllFiltering:!0,signal:I,timeoutMs:C})}),T=this.isSystemUiAnrHierarchyUnavailable(A,f);if(T&&P)throw this.systemUiAnrRecoveryRequired(c,"could not confirm dialog recovery: hierarchy unavailable");return T?null:A}catch(A){if(A instanceof WA)throw A;if(this.phases.throwIfCallerCancelled(c,A),!P)return null;throw this.systemUiAnrRecoveryRequired(c,`could not confirm dialog recovery: ${ie(A)}`)}}isSystemUiAnrHierarchyUnavailable(c,d){if(c===null||c.fresh===!1)return!0;return c.updatedAt!==void 0&&c.updatedAt<d}async selectSystemUiAnrWait(c,d,h,f){let{x:P,y:C}=ji(h);try{let A=await this.phases.runPhase(c,"runner-health",1,{operation:async()=>await d.requestTapCoordinates({x:P,y:C,duration:10,timeoutMs:Math.min(this.phases.probeTimeout(c),this.remainingSystemUiAnrRecoveryBudget(f))})});if(!A.success)throw Error(A.error??"unknown tap failure")}catch(A){throw this.phases.throwIfCallerCancelled(c,A),this.systemUiAnrRecoveryRequired(c,`could not select Wait: ${ie(A)}`)}}async waitForSystemUiAnrRecovery(c,d,h,f){let P=0,C=(f??0)+1;while(this.remainingSystemUiAnrRecoveryBudget(h)>0){await this.timer.sleep(Math.min(Nt,this.remainingSystemUiAnrRecoveryBudget(h)));let A=await this.readSystemUiAnrHierarchy(c,d,h,{minTimestamp:C,required:!0});if(C=Math.max(C,(A?.updatedAt??0)+1),_t(A??{hierarchy:{}})){P=0;continue}if(P++,P>=Ha)return}throw this.systemUiAnrRecoveryRequired(c,"dialog persisted after selecting Wait")}remainingSystemUiAnrRecoveryBudget(c){return Math.max(0,c-this.timer.now())}systemUiAnrRecoveryRequired(c,d){return new WA(this.systemUiAnrDiagnostic(c,d))}systemUiAnrDiagnostic(c,d){return`System UI ANR recovery required: platform=android requested=[${c.requestedIdentity}] resolved=[${c.device.name} (${c.device.deviceId})]: ${d}`}}function Xi(c){return(c.isLastConnectionFailureForwardingLeaseConflict?.()??!1)&&!(c.isLastConnectionFailureTransientLeaseConflict?.()??!1)}class RF{dependencies;phases;anrRecovery;iosPostSetupProbe;constructor(c){this.dependencies=c;this.phases=new Te(c.timer),this.iosPostSetupProbe=new et(c,this.phases),this.anrRecovery=new Ht(c.timer,this.phases)}async ensureReady(c){let d={...c,healthDeadlineMs:null,phaseElapsedMs:{},lastCtrlProxyRebindMs:Number.NEGATIVE_INFINITY,ctrlProxyAccessibilityRebindAttempted:!1,lastConnectedRecoveryMs:Number.NEGATIVE_INFINITY,ctrlProxyProcessRestartAttempted:!1,lastSuccessfulRebindMs:Number.NEGATIVE_INFINITY,failedHealthProbesSinceRecovery:0},h=ro(c.device.platform,c.device.deviceId),f=await this.acquireReadinessTurn(d,h);try{c.signal?.throwIfAborted(),c.assertCanSetup?.(),await this.ensureReadyUncoordinated(d)}finally{f()}}async ensureReadyUncoordinated(c){let d=c.perf,h=async()=>{if(c.device.platform==="android"){await this.ensureAndroidReady(c);return}await this.ensureIosReady(c)};if(!d)return h();return uc(pc(d),h)}async acquireReadinessTurn(c,d){if(this.phases.remainingForPhase(c,"runner-setup")<=0)this.phases.fail(c,"runner-setup",1,{detail:"readiness budget exhausted before setup lock",deadlineExhausted:!0});try{return await nD(d,{timer:this.dependencies.timer,signal:c.signal,timeoutMs:this.phases.remainingForPhase(c,"runner-setup"),timeoutError:()=>Error("readiness setup lock exceeded this request's deadline")})}catch(h){this.phases.throwIfCallerCancelled(c,h),this.phases.fail(c,"runner-setup",1,{detail:ie(h),deadlineExhausted:!0})}}async ensureAndroidReady(c){this.phases.throwIfCallerCancelled(c);let d=this.inspectAndroidFrameworkBestEffort(c);try{let h="Android framework readiness budget exhausted";await new hn(this.dependencies.timer).executeOrThrow(async(f)=>{if(this.phases.throwIfCallerCancelled(c),this.phases.remainingForPhase(c,"runner-setup")<=0)this.phases.fail(c,"runner-setup",f,{detail:h,deadlineExhausted:!0});if(f>1)this.dependencies.getAndroidManager(c.device).resetSetupState();await this.ensureAndroidReadyAttempt(c),this.phases.throwIfCallerCancelled(c)},{maxAttempts:Math.ceil(this.phases.remainingForPhase(c,"runner-setup")/Ce)+1,signal:c.signal,delays:()=>Math.min(Ce,this.phases.remainingForPhase(c,"runner-setup")),shouldRetry:(f)=>f instanceof go&&f.retryableAndroidFrameworkFailure&&this.phases.remainingForPhase(c,"runner-setup")>0,onRetry:(f)=>{h=ie(f),e.debug(`Retrying Android framework setup: ${h}`)}})}catch(h){throw this.phases.throwIfCallerCancelled(c,h),h}finally{await d?.(),this.phases.throwIfCallerCancelled(c)}}async ensureAndroidReadyAttempt(c){let d=this.dependencies.getAndroidManager(c.device),h=this.dependencies.getAndroidClient(c.device);if(c.skipCtrlProxyDownload){await this.ensureAndroidReadyWithoutDownloads(c,d,h);return}let f=await this.phases.runPhase(c,"package-compatibility",1,{operation:(A)=>d.ensureCompatibleVersion({allowDownloadWhenInstalled:!0,bypassVersionCheckCache:!1},A)});this.assertAndroidCompatibility(c,f);let[P,C]=await this.phases.runPhase(c,"runner-setup",1,{operation:async(A)=>[await d.isInstalled(A),await d.isEnabled(A)]});if(await this.isResponsiveFastPath(c,h,P&&C)){await this.anrRecovery.recoverIfPresent(c,h);return}d.reopenSetupGate(),await this.setupAndroidRunner(c,d),await this.waitForResponsiveClient(c,h,d),await this.anrRecovery.recoverIfPresent(c,h)}inspectAndroidFrameworkBestEffort(c){let d=this.dependencies.getAndroidFrameworkReadiness;if(!d)return;let h=Math.max(0,c.totalDeadlineMs-this.dependencies.timer.now());if(h<=0)return;let f=new AbortController,P=c.signal?AbortSignal.any([c.signal,f.signal]):f.signal,C=Math.min(Dt,h),A=this.dependencies.timer.setTimeout(()=>f.abort(Error("Android framework inspection timed out")),C),T=Promise.resolve().then(()=>(P.throwIfAborted(),d(c.device,P,C))).then((I)=>{if(!I.ready)e.debug(`Android framework inspection is not ready yet: ${I.unavailableResources?.join(", ")??"unknown resources"}${I.diagnostic?`; ${ie(I.diagnostic)}`:""}`)},(I)=>{e.debug(`Android framework inspection failed: ${ie(I)}`)}).finally(()=>this.dependencies.timer.clearTimeout(A));return async()=>{f.abort(Error("Android readiness inspection finished")),this.dependencies.timer.clearTimeout(A),await this.phases.awaitAbortSettlement(T)}}async ensureAndroidReadyWithoutDownloads(c,d,h){let[f,P]=await this.phases.runPhase(c,"runner-setup",1,{operation:async(A)=>[await d.isInstalled(A),await d.isEnabled(A)]});if(!f)this.phases.fail(c,"runner-setup",1,{detail:"CtrlProxy is not installed and runner downloads are disabled"});if(!await this.phases.runPhase(c,"package-compatibility",1,{operation:()=>d.isVersionCompatible()}))this.phases.fail(c,"package-compatibility",1,{detail:"CtrlProxy version mismatch; run without skipCtrlProxyDownload to install a compatible version"});if(await this.isResponsiveFastPath(c,h,P)){await this.anrRecovery.recoverIfPresent(c,h);return}if(!P)await this.phases.runPhase(c,"runner-setup",1,{operation:()=>d.enable()});await this.waitForResponsiveClient(c,h,d),await this.anrRecovery.recoverIfPresent(c,h)}assertAndroidCompatibility(c,d){if(!(d.status==="failed"||d.status==="skipped"||d.acceptedPreinstalled===!0))return;let f=[d.error,d.upgradeError,d.reinstallError,d.acceptedPreinstalled?"installed package compatibility was not verified":void 0,d.status==="skipped"?"package compatibility check was skipped":void 0].filter((P)=>Boolean(P));this.phases.fail(c,"package-compatibility",1,{detail:d.cause??f.join("; ")})}async isResponsiveFastPath(c,d,h){if(!h||!d.isConnected())return!1;return this.phases.runPhase(c,"runner-health",1,{operation:()=>d.verifyServiceReady(1,0,this.phases.probeTimeout(c))})}async setupAndroidRunner(c,d){let h=await this.phases.runPhase(c,"runner-setup",1,{operation:(T)=>d.setup(!1,c.perf,T)});if(!h.success)this.phases.fail(c,"runner-setup",1,{detail:h.cause??h.error??h.message});let f=Math.min(c.totalDeadlineMs,this.dependencies.timer.now()+Hi),P=0,C=!1,A=!1;for(;;){if(P++,[C,A]=await this.phases.runPhase(c,"runner-setup",P,{operation:async(T)=>[await d.isInstalled(T),await d.isEnabled(T,{bypassCache:P>1})],operationDeadlineMs:f}),C&&A)return;if(!C||this.dependencies.timer.now()>=f)break;if(this.phases.throwIfCallerCancelled(c),await this.dependencies.timer.sleep(Math.min(Ce,f-this.dependencies.timer.now())),this.phases.throwIfCallerCancelled(c),this.dependencies.timer.now()>=f)break;await this.phases.runPhase(c,"runner-setup",P,{operation:()=>d.enable(),operationDeadlineMs:f})}if(!C||!A)this.phases.fail(c,"runner-setup",P,{detail:`CtrlProxy state after setup: installed=${C}, enabled=${A}`})}async ensureIosReady(c){this.assertIosRuntimeCompatible(c);let d=await this.phases.runPhase(c,"runner-setup",1,{operation:()=>this.dependencies.checkIosOverride()});if(d.present&&!d.usable)this.phases.fail(c,"runner-setup",1,{detail:`AUTOMOBILE_CTRL_PROXY_IOS_BUNDLE_PATH / _IPA_PATH is set but unusable: ${d.reason??"unknown reason"}`});await this.phases.runPhase(c,"runner-setup",1,{operation:()=>this.dependencies.awaitIosStartupMaintenance()});let h=this.dependencies.getIosManager(c.device),f=this.dependencies.getIosClient(c.device,h.getServicePort());if(f.isConnected()){if(this.phases.startHealthWindow(c),await this.phases.runPhase(c,"runner-health",1,{operation:()=>f.verifyServiceReady(1,0,this.phases.probeTimeout(c))}))return;h.resetSetupState(),await this.phases.runPhase(c,"runner-setup",1,{operation:(C)=>h.forceRestart({signal:C,minimumHealthPollDurationMs:this.phases.remainingForPhase(c,"runner-health")})}),c.healthDeadlineMs=null,f=this.dependencies.getIosClient(c.device,h.getServicePort()),await this.waitForResponsiveClient(c,f);return}if(c.skipCtrlProxyDownload){await this.ensureIosReadyWithoutDownloads(c,h);return}await Gi(c,h,this.phases,this.dependencies.iosSetupMaxAttempts),f=this.dependencies.getIosClient(c.device,h.getServicePort()),await this.ensureIosClientReadyAfterStart(c,h,f)}assertIosRuntimeCompatible(c){let d=c.device.iosVersion??c.device.osVersion,h=GF(d,It);if(h!==null&&h<0)this.phases.fail(c,"runner-setup",1,{detail:`iOS runtime ${d} is below the CtrlProxy minimum ${It}; select a compatible simulator or device.`})}async ensureIosReadyWithoutDownloads(c,d){if(!await this.phases.runPhase(c,"runner-setup",1,{operation:()=>d.isInstalled()}))this.phases.fail(c,"runner-setup",1,{detail:"CtrlProxy iOS runner is not installed and runner downloads are disabled"});await this.phases.runPhase(c,"runner-setup",1,{operation:(P)=>d.start({signal:P,minimumHealthPollDurationMs:this.phases.remainingForPhase(c,"runner-setup")})});let f=this.dependencies.getIosClient(c.device,d.getServicePort());await this.ensureIosClientReadyAfterStart(c,d,f)}async ensureIosClientReadyAfterStart(c,d,h){if(this.phases.startHealthWindow(c),await this.iosPostSetupProbe.isResponsive(c,d,h))return;d.resetSetupState(),await this.phases.runPhase(c,"runner-setup",1,{operation:(P)=>d.forceRestart({signal:P,minimumHealthPollDurationMs:this.phases.remainingForPhase(c,"runner-setup")})}),c.healthDeadlineMs=null;let f=this.dependencies.getIosClient(c.device,d.getServicePort());await this.waitForResponsiveClient(c,f)}async waitForResponsiveClient(c,d,h){let f={release:c.device.platform==="android"?d.beginReadinessHold?.():void 0};try{await this.pollResponsiveClient(c,d,f,h)}finally{f.release?.()}}async pollResponsiveClient(c,d,h,f){this.phases.startHealthWindow(c);let P=0,C=d.isConnected(),A=C?"runner-health":"runner-connect",T=Number.NEGATIVE_INFINITY;while(this.phases.remainingForPhase(c,"runner-health")>0){if(this.phases.throwIfCallerCancelled(c),c.device.platform==="android")d=await this.replaceClosedAndroidClient(c,d,h,P);if(P++,C=d.isConnected(),!C){if(A="runner-connect",await this.rebindUnhealthyAndroidAccessibilityService(c,f,P,d),C=await this.phases.runPhase(c,A,P,{operation:()=>d.waitForConnection(1,0)}),!C&&Xi(d))await this.failUnresponsiveClient(c,d,A,{attempts:P})}if(C){if(A="runner-health",await this.phases.runPhase(c,A,P,{operation:()=>d.verifyServiceReady(1,0,this.phases.probeTimeout(c))}))return;await this.recoverConnectedButUnresponsiveAndroid(c,f,d,P)}if(c.device.platform==="android"&&this.dependencies.timer.now()-T>=Nt)T=this.dependencies.timer.now(),await this.anrRecovery.recoverIfPresent(c,d);let I=this.phases.remainingForPhase(c,"runner-health");if(I>0)await this.dependencies.timer.sleep(Math.min(Ce,I))}await this.failUnresponsiveClient(c,d,A,{attempts:P})}async replaceClosedAndroidClient(c,d,h,f){if(!d.isClosed?.())return d;h.release?.(),h.release=void 0;let P=this.dependencies.getAndroidClient(c.device);if(e.info(`[RunnerReadiness] Re-resolved closed CtrlProxy client for ${c.device.deviceId}`),h.release=P.beginReadinessHold?.(),P.isClosed?.())await this.failUnresponsiveClient(c,P,"runner-connect",{attempts:f,deadlineExhausted:!1});return P}async rebindUnhealthyAndroidAccessibilityService(c,d,h,f){if(c.device.platform!=="android"||!d?.rebindIfUnhealthy||c.ctrlProxyAccessibilityRebindAttempted||this.dependencies.timer.now()-c.lastCtrlProxyRebindMs<Tt)return;let P=await this.phases.runPhase(c,"runner-connect",h,{operation:async()=>{try{return await d.rebindIfUnhealthy()}catch(C){if(!(C instanceof Pw))throw C;return e.warn(`[CTRL_PROXY] Accessibility rebind inspection unavailable: ${C}`,C),!1}}});if(c.lastCtrlProxyRebindMs=this.dependencies.timer.now(),c.ctrlProxyAccessibilityRebindAttempted||=P,P)f.resetConnectionBudget?.()}async recoverConnectedButUnresponsiveAndroid(c,d,h,f){if(c.device.platform!=="android"||!d)return;if(c.failedHealthProbesSinceRecovery++,this.dependencies.timer.now()-c.lastConnectedRecoveryMs<Tt)return;let P=c.failedHealthProbesSinceRecovery;if(c.lastConnectedRecoveryMs=this.dependencies.timer.now(),d.rebindIfUnhealthy&&!c.ctrlProxyAccessibilityRebindAttempted){let A=await this.phases.runPhase(c,"runner-health",f,{operation:()=>d.rebindIfUnhealthy()});if(c.ctrlProxyAccessibilityRebindAttempted||=A,A){c.failedHealthProbesSinceRecovery=0,c.lastSuccessfulRebindMs=this.dependencies.timer.now(),h.resetConnectionBudget?.();return}}if(!this.canEscalateToProcessRestart(c,d,P))return;if(c.ctrlProxyProcessRestartAttempted=!0,await this.phases.runPhase(c,"runner-health",f,{operation:()=>d.forceRestartProcess()}))h.resetConnectionBudget?.()}canEscalateToProcessRestart(c,d,h){if(c.ctrlProxyProcessRestartAttempted||!d.forceRestartProcess)return!1;if(h<Wi)return!1;return this.dependencies.timer.now()-c.lastSuccessfulRebindMs>=Bi}async failUnresponsiveClient(c,d,h,{attempts:f,deadlineExhausted:P=!0}){if(h==="runner-connect"&&(d.isLastConnectionFailureForwardingLeaseConflict?.()??!1)){let T=d.getLastConnectionFailureMessage?.();if(T)this.phases.fail(c,h,f,{detail:T})}if(h==="runner-connect")this.failForwardUnavailableClient(c,d,f,P);let A=h==="runner-connect"?await this.runnerConnectFailureDiagnostic(c):await this.runnerHealthFailureDiagnostic(c,h);this.phases.fail(c,h,f,{detail:`${this.unresponsiveClientRecoveryNote(c,h)}${A}`,deadlineExhausted:!0})}failForwardUnavailableClient(c,d,h,f){let P=d.getForwardFailureCause?.()??(d.isClosed?.()?`CtrlProxy client for ${c.device.deviceId} is closed; adb forward unavailable`:void 0);if(P)this.phases.fail(c,"runner-connect",h,{detail:P,deadlineExhausted:f,failureKind:"ctrlproxy_forward_unavailable"})}unresponsiveClientRecoveryNote(c,d){if(d==="runner-connect"&&c.ctrlProxyAccessibilityRebindAttempted)return"CtrlProxy accessibility service was crashed or unbound; rebind attempted, but the runner did not become responsive before the readiness deadline";if(c.ctrlProxyProcessRestartAttempted)return"CtrlProxy accessibility service was bound but unresponsive; process restart attempted, but the runner did not become responsive before the readiness deadline";return"runner did not become responsive before the readiness deadline"}async runnerConnectFailureDiagnostic(c){let d=this.dependencies.getAndroidRunnerConnectDiagnostic;if(c.device.platform!=="android"||!d)return"";let h=await this.collectBoundedAndroidDiagnostic(c,d,"runner-connect");if(!h)return"";let f=[h.primaryUserStartState?`primaryUserStartState=${h.primaryUserStartState}`:void 0,h.deviceLock?`deviceLock=${h.deviceLock.locked?"locked":"unlocked"}`:void 0].filter((P)=>Boolean(P));return f.length>0?`; ${f.join(" ")}`:""}async runnerHealthFailureDiagnostic(c,d){let h=this.dependencies.getAndroidRunnerHealthDiagnostic;if(c.device.platform!=="android"||d!=="runner-health"||!h)return"";let f=await this.collectBoundedAndroidDiagnostic(c,h,"runner-health");if(!f)return"";return`; sys.boot_completed=${f.sysBootCompleted} adbDevices=${f.adbDevices} emulatorQemuHealth=${f.emulatorQemuHealth}`}async collectBoundedAndroidDiagnostic(c,d,h){try{let f=new AbortController,P=c.signal?AbortSignal.any([c.signal,f.signal]):f.signal,C=d(c.device,P);C.catch((I)=>{e.debug(`Android readiness diagnostic rejection observed: ${r(I)}`)});let A=Error(`${h} diagnostic timed out`),T;try{T=await l(C,{timer:this.dependencies.timer,timeoutMs:Ne,label:`${h} diagnostic`,timeoutError:()=>A,onTimeout:()=>f.abort(A)})}catch(I){if(I!==A)throw I}if(!T)return;return T}catch(f){e.debug(`Failed to collect Android ${h} diagnostic: ${r(f)}`);return}}}class Bt{d;constructor(c){this.d=c}async execute(c){let d=c?.deviceReadScreenshot;pB(Q(this.d.device().platform,"Observing all displays"));let h=this.d.timer().now()+(c?.timeoutMs??15000),f=await this.readAggregatePanel("active",{options:c,deadline:h,deviceReadScreenshot:d}),P=this.d.device().displays?.panels.filter(gd);if(!P?.length)return f;let C=this.activePanelKey(P,f.display.key),A=[];for(let I of P){let O=I.key===C?f:await this.readAggregatePanel(I.key,{options:{...c,skipScreenshot:!0,skipPerformanceAudit:!0,skipAccessibilityAudit:!0,skipRecompositionTracking:!0},deadline:h}),{display:x,screenSize:N,viewHierarchy:H,elements:V,screenshotPath:q,screenshotExpiresAt:K,systemInsets:j,insets:Y,activeWindow:X}=O;A.push({display:{...x,key:I.key,role:I.role},screenSize:N,viewHierarchy:H,elements:V,screenshotPath:q,screenshotExpiresAt:K,systemInsets:j,insets:Y,activeWindow:X,freshness:O.freshness??qw({now:this.d.timer().now(),unavailable:!0})})}let T={...f,displays:A};return await eb(T,this.d.pathProtection()),T}activePanelKey(c,d){let h=this.d.device();if(h.displays?.panels.some((f)=>f.key===d&&!gd(f)))return;if(c.some((f)=>f.key===d))return d;return sn(h.displays,"active",{focusedPanelKey:xe.observedPanel(h.deviceId)?.key}).key}async readAggregatePanel(c,d){let{options:h,deadline:f,deviceReadScreenshot:P}=d,C=Math.max(0,f-this.d.timer().now()),A=new AbortController,T=h?.signal,I=T?AbortSignal.any([T,A.signal]):A.signal,O=C===0;try{if(T?.throwIfAborted(),O)throw new Vn("Observe deadline reached; retry this panel separately.");return await l(async()=>{let x=await this.d.executeSingleDisplay({...h,display:c,signal:I,timeoutMs:C,skipCache:!0,preserveDisplayState:!0});if(P!==void 0)await this.d.captureDeviceReadScreenshot(x,I,P,{display:c});return x},{timer:this.d.timer(),timeoutMs:C,signal:T,label:`Observe display ${c}`,onTimeout:()=>{O=!0,A.abort()}})}catch(x){if(T?.throwIfAborted(),e.warn(`[ObserveScreen] Display ${c} unavailable: ${r(x)}`,x),c==="active"&&!O)return this.d.createCriticalFallback(x);let N=this.d.createBaseResult(),H=sn(this.d.device().displays,c,{focusedPanelKey:xe.observedPanel(this.d.device().deviceId)?.key});return N.display={...N.display,key:H.key,role:H.role,generation:xe.identityRevision(this.d.device().deviceId)},N.screenSize={...H.sizePx,units:"physical-pixels"},N.freshness=qw({now:this.d.timer().now(),unavailable:!0,unavailableReason:O?"request_timed_out":"unknown",unavailableDetail:r(x)}),N}}}var Qi="com.apple.springboard.lockstate",Va=2000;function tV(c){return c.kind==="known"?c.lock:void 0}function rt(c,d){if(delete c.deviceLock,delete c.deviceLockUnknown,d.kind==="known")c.deviceLock=d.lock;else c.deviceLockUnknown={reason:d.reason,...d.message===void 0?{}:{message:d.message}}}class zA{executor;options;constructor(c=new F,d={}){this.executor=c;this.options=d}async read(c,d){try{let h=await this.executor.executeCommand(sz(c,Qi),this.options.timeoutMs??Va,d);if(h.stderr?.trim())return e.warn(`[iOS] Lock-state probe failed: ${h.stderr.trim()}`),{kind:"unknown",reason:"error",message:h.stderr.trim()};let f=h.stdout.split(`
|
|
5
|
-
`).find((C)=>C.trim().startsWith(`${Qi} `)),P=mR(f??"");if(P===null)return e.warn("[iOS] Lock-state probe returned unparseable output"),{kind:"unknown",reason:"unparseable"};return{kind:"known",lock:{locked:P,keyguardShowing:P}}}catch(h){return e.warn(`[iOS] Lock-state probe failed: ${r(h)}`,h),{kind:"unknown",reason:h instanceof ns?"timeout":"error",message:r(h)}}}}var Zi=new Set(["debug","tool-results-no-structured-content"]),WS=[{key:"debug",label:"Debug mode",description:"Enable debug tools and include extra debug data in responses.",defaultValue:!1},{key:"debug-perf",label:"Debug perf (--debug-perf)",description:"Collect performance timing data in tool responses.",defaultValue:!1},{key:"ui-perf-mode",label:"UI performance audit",description:"Run UI performance audits during observe.",defaultValue:!1},{key:"mem-perf-audit",label:"Memory audit",description:"Run memory audits during tool execution.",defaultValue:!1},{key:"accessibility-audit",label:"Accessibility audit",description:"Run accessibility audits during observe.",defaultValue:!1,defaultConfig:{level:"AA",failureMode:"report",minSeverity:"warning",useBaseline:!1,contrast:{useMultiPointSampling:!0,detectGradients:!0,compositeOverlays:!1,detectTextShadows:!1,samplingPoints:9}}},{key:"predictive-ui",label:"Predictive UI",description:"Enable predictive UI state generation during observe.",defaultValue:!1},{key:"raw-element-search",label:"Raw element search",description:"Use raw view hierarchies for element search while returning filtered observations.",defaultValue:!1},{key:"force-accessibility-mode",label:"Force accessibility mode",description:"Force-enable accessibility mode for testing (overrides auto-detection).",defaultValue:!1},{key:"accessibility-auto-detect",label:"Accessibility auto-detect",description:"Automatically detect and adapt to TalkBack/VoiceOver when enabled.",defaultValue:!0},{key:"screen-reader-navigation",label:"Screen-reader navigation (fidelity mode)",description:"Opt-in: when a screen reader is active, move the accessibility cursor onto the target with an accessibility-focus action and confirm it landed before activating (instead of activating the node directly). A failure after the focus request fails the call without a coordinate tap. For accessibility validation \u2014 reachability and what the cursor lands on.",defaultValue:!1},{key:"ai-recovery",label:"AI recovery",description:"AI-assisted recovery for failed test steps.",defaultValue:!0,defaultConfig:{maxToolCalls:5}},{key:"tool-call-recording",label:"Tool call recording",description:"Allow recordToolCalls begin/end to capture MCP tool calls as replayable YAML test plans. On by default; the tool itself is still opt-in via setToolEnabled.",defaultValue:!0},{key:"navigation-screenshots",label:"Navigation screenshots",description:"Capture screenshots on navigation events to enrich the navigation graph. Disable to reduce device resource usage.",defaultValue:!0},{key:"observe-settled-screenshot",label:"Settled observation screenshots",description:"Wait for a validated, settled screenshot instead of capturing one in the background.",defaultValue:!1},{key:"observe-result-include-elements",label:"Observe result: include elements",description:"Include the flattened elements array in observe results. It is dropped by default to reduce output size; enable this to restore it.",defaultValue:!1},{key:"tool-results-no-structured-content",label:"Tool results: no structured content",description:"Omit the structuredContent field from tool results to reduce output size.",defaultValue:!1},{key:"actions-diff-observe",label:"Actions: diff observe",description:"Return action-aware observation diffs after non-observe tools, falling back to full observations for navigation-prone or uncertain screen changes.",defaultValue:!1},{key:"actions-no-observe",label:"Actions: no observe",description:"Skip returning the post-action observation entirely to reduce output size.",defaultValue:!1},{key:"actions-compact-metadata",label:"Actions: compact metadata",description:"Omit unchanged device metadata after its first inline action response in a session and omit identical duplicate matched elements.",defaultValue:!0},{key:"device-condition",label:"Device condition fixtures",description:"Opt-in: expose the session-scoped deviceCondition surface on setDeviceState for root/integrity/fault test fixtures (epic #14047). Off by default while the individual injectors land; conditions always restore to a clean state on release.",defaultValue:!1},{key:"ios-sdk-observation-bridge",label:"iOS SDK observation bridge",description:"On iOS, merge the app's registered AutoMobile SDK observation bridge into observe and route tapOn on its nodes through it, falling back to XCTest only when the bridge is unavailable or the action is unsupported. Disable to use XCTest alone.",defaultValue:!0}];var Wa=kt(y(),hr());function Ua(c,d,h=e){if(!d)return null;try{return Wa.parse(JSON.parse(d))}catch(f){return h.warn(`[FeatureFlagRepository] Ignoring invalid config_json for flag "${c}": ${r(f)}`),null}}class Vt{injectedDb;logger;timer;constructor({db:c,timer:d=i,log:h}={}){this.timer=d,this.injectedDb=c??null,this.logger=h??e}async ensureReady(){if(!this.injectedDb)await BD()}getDb(){return this.injectedDb??ke()}async ensureFlags(c){if(await this.ensureReady(),c.length===0)return;let d=this.getDb(),h=$r(this.timer);await d.insertInto("feature_flags").values(c.map((f)=>({key:f.key,enabled:f.defaultValue?1:0,config_json:f.defaultConfig?JSON.stringify(f.defaultConfig):null,updated_at:h}))).onConflict((f)=>f.column("key").doNothing()).execute()}async listFlags(){return await this.ensureReady(),(await this.getDb().selectFrom("feature_flags").select(["key","enabled","config_json","updated_at"]).execute()).map((h)=>({key:h.key,enabled:h.enabled===1,config:Ua(h.key,h.config_json,this.logger),updatedAt:h.updated_at}))}async upsertFlag(c,d,h){await this.ensureReady();let f=this.getDb(),P=$r(this.timer),C=h?JSON.stringify(h):null;await f.insertInto("feature_flags").values({key:c,enabled:d?1:0,config_json:C,updated_at:P}).onConflict((A)=>A.column("key").doUpdateSet((T)=>({enabled:d?1:0,config_json:h===void 0?T.ref("feature_flags.config_json"):C,updated_at:P}))).execute()}}var en=!1;function tn(c){en=c}function Jl(){return en}var fe={level:"AA",failureMode:"report",useBaseline:!1,minSeverity:"warning",contrast:{useMultiPointSampling:!0,detectGradients:!0,compositeOverlays:!1,detectTextShadows:!1,samplingPoints:9}};class Wt{apply(c,d,h){switch(c){case"debug":tn(d);break;case"debug-perf":fL(d);break;case"ui-perf-mode":M.setUiPerfMode(d);break;case"mem-perf-audit":M.setMemPerfAuditMode(d);break;case"accessibility-audit":M.setAccessibilityAuditConfig(d?$a(h):null);break;case"predictive-ui":M.setPredictiveUiEnabled(d);break;case"raw-element-search":M.setRawElementSearchEnabled(d);break;case"tool-call-recording":M.setToolCallRecordingEnabled(d);break;case"navigation-screenshots":M.setNavigationScreenshotsEnabled(d);break;case"ios-sdk-observation-bridge":M.setIosSdkObservationBridgeEnabled(d);break;default:this.applyOutputReduction(c,d);break}}applyOutputReduction(c,d){switch(c){case"observe-result-include-elements":M.setObserveResultIncludeElementsEnabled(d);break;case"tool-results-no-structured-content":M.setToolResultsNoStructuredContentEnabled(d);break;case"actions-diff-observe":M.setActionsDiffObserveEnabled(d);break;case"actions-compact-metadata":M.setActionsCompactMetadataEnabled(d);break;case"actions-no-observe":M.setActionsNoObserveEnabled(d);break}}}var $a=(c)=>{if(!c)return fe;let d=c.level==="A"||c.level==="AA"||c.level==="AAA"?c.level:fe.level,h=c.failureMode==="report"||c.failureMode==="threshold"||c.failureMode==="strict"?c.failureMode:fe.failureMode,f=c.minSeverity==="error"||c.minSeverity==="warning"||c.minSeverity==="info"?c.minSeverity:fe.minSeverity,P=typeof c.useBaseline==="boolean"?c.useBaseline:fe.useBaseline,C=Ga(c.contrast);return{level:d,failureMode:h,minSeverity:f,useBaseline:P,contrast:C}},Ga=(c)=>{if(!c||typeof c!=="object")return fe.contrast;let d=c,h=qa(d);return{useMultiPointSampling:typeof d.useMultiPointSampling==="boolean"?d.useMultiPointSampling:fe.contrast?.useMultiPointSampling,detectGradients:typeof d.detectGradients==="boolean"?d.detectGradients:fe.contrast?.detectGradients,compositeOverlays:typeof d.compositeOverlays==="boolean"?d.compositeOverlays:fe.contrast?.compositeOverlays,detectTextShadows:typeof d.detectTextShadows==="boolean"?d.detectTextShadows:fe.contrast?.detectTextShadows,samplingPoints:h}},qa=(c)=>c.samplingPoints===5||c.samplingPoints===9||c.samplingPoints===13?c.samplingPoints:fe.contrast?.samplingPoints;class Ut{notifyToolListChanged(){}}var eC="notifications/resources/updated";class rn{listeners=new Set;subscribe(c){return this.listeners.add(c),()=>{this.listeners.delete(c)}}emit(c){for(let d of this.listeners)try{d(c)}catch(h){e.warn("[ResourceUpdatedBroadcaster] resource update listener failed",h)}}clearForTesting(){this.listeners.clear()}}var zS=new rn;var L4={tools:"notifications/tools/list_changed",resources:"notifications/resources/list_changed"};function pQ(c){for(let[d,h]of Object.entries(L4))if(h===c)return d;return}class nn{listeners=new Set;generations={tools:0,resources:0};generation(c){return this.generations[c]}subscribe(c){return this.listeners.add(c),()=>{this.listeners.delete(c)}}invalidate(c){this.generations[c]++}emit(c){this.invalidate(c);for(let d of this.listeners)try{d(c)}catch(h){e.warn(`[ListChangedBroadcaster] listener failed for ${c} list_changed: ${h}`)}}clearForTesting(){this.listeners.clear()}}var kr=new nn;class sr{repository;applier;definitions;notifier;static instance=null;definitionByKey;initialized=!1;flagsByKey=new Map;configsByKey=new Map;static getInstance(){if(!sr.instance)sr.instance=new sr(new Vt,new Wt);return sr.instance}static peekInstanceForTesting(){return sr.instance}static setInstanceForTesting(c){sr.instance=c}constructor(c,d,h=WS,f=new Ut){this.repository=c;this.applier=d;this.definitions=h;this.notifier=f;this.definitionByKey=new Map(h.map((P)=>[P.key,P]))}setToolListChangedNotifier(c){this.notifier=c}toolListChangedNotifierForTesting(){return this.notifier}async initialize(){if(this.initialized)return;await this.repository.ensureFlags(this.definitions);let c=await this.repository.listFlags(),d=new Map(c.map((h)=>[h.key,h]));for(let h of this.definitions){let f=d.get(h.key),P=f?f.enabled:h.defaultValue,C=f?.config??h.defaultConfig??null;this.flagsByKey.set(h.key,P),this.configsByKey.set(h.key,C),this.applier.apply(h.key,P,C)}this.initialized=!0,kr.invalidate("tools")}async listFlags(){return await this.initialize(),this.definitions.map((c)=>({key:c.key,label:c.label,description:c.description,enabled:this.flagsByKey.get(c.key)??c.defaultValue,config:this.configsByKey.get(c.key)??c.defaultConfig??null}))}async setFlag(c,d,h){await this.initialize();let f=this.definitionByKey.get(c);if(!f)throw Error(`Unknown feature flag: ${c}`);let P=h!==void 0?h:this.configsByKey.get(c)??f.defaultConfig??null,C=this.flagsByKey.get(c)??f.defaultValue;if(await this.repository.upsertFlag(c,d,h),this.flagsByKey.set(c,d),h!==void 0)this.configsByKey.set(c,P);if(this.applier.apply(c,d,P),d!==C&&Zi.has(c))this.notifier.notifyToolListChanged();return{key:f.key,label:f.label,description:f.description,enabled:d,config:P}}async setFlagConfig(c,d){await this.initialize();let h=this.definitionByKey.get(c);if(!h)throw Error(`Unknown feature flag: ${c}`);let f=this.flagsByKey.get(c)??h.defaultValue;return await this.repository.upsertFlag(c,f,d),this.configsByKey.set(c,d),this.applier.apply(c,f,d),{key:h.key,label:h.label,description:h.description,enabled:f,config:d}}isEnabled(c){let d=this.definitionByKey.get(c);if(!d)return!1;return this.flagsByKey.get(c)??d.defaultValue}}var Tf=g.ACTION_OBSERVATION_SKIP_SCREENSHOT.name,If=g.OBSERVE_WAIT_FOR_SKIP_SCREENSHOT.name;function on(c){return c?.trim().toLowerCase()!=="false"&&c?.trim()!=="0"}function PF(c=process.env){return on(E(g.ACTION_OBSERVATION_SKIP_SCREENSHOT,c))}function mQ(c=process.env){return on(E(g.OBSERVE_WAIT_FOR_SKIP_SCREENSHOT,c))}var Of=g.OBSERVE_SETTLED_SCREENSHOT.name;function nm(c,d=process.env,h=sr.getInstance()){if(c!==void 0)return c;let f=E(g.OBSERVE_SETTLED_SCREENSHOT,d);if(f!==void 0)return["true","1"].includes(f.trim().toLowerCase())?"settled":"async";return h.isEnabled("observe-settled-screenshot")?"settled":"async"}function Ka(c){return c?.freshness?c.freshness==="cached-ok":c?.skipWaitForFresh??!0}function an(c,d){return(c.result.backStack?.displayCount??0)<2&&(d.displayCount??0)>1&&(c.requestedDisplayId??c.observedAndroid?.logicalId)===0}function cn(c){return{preserveDisplayState:c?.preserveDisplayState===!0,observerMode:c?.observerMode===!0,queryOptions:c?.queryOptions,skipWaitForFresh:Ka(c),minTimestamp:c?.minTimestamp??0,signal:c?.signal,skipBackStack:c?.skipBackStack??!1,screenshotMode:c?.skipScreenshot?"none":nm(c?.screenshot)}}function ln(c){let{options:d}=c;return!c.observerMode&&!c.preserveDisplayState&&!d?.skipCache&&!d?.skipRecompositionTracking}function za(c,d){let h=c.viewHierarchy?.hierarchy;return d&&h?.unavailableReason!==void 0||h===void 0||h.error!==void 0||c.viewHierarchy?.ctrlProxyIncomplete===!0&&!h.node}function un(c,d){let{result:h,requestedDisplayId:f}=c,P=c.routedAggregateSecondary&&d.sampledForeground===null,C=h.viewHierarchy?.hierarchy;return{unavailable:P||!d.hierarchyPlatformValid||za(h,c.preserveDisplayState),unavailableReason:C?.unavailableReason??(P?"unknown":void 0),unavailableDetail:C?.unavailableDetail??(P?`The foreground app of display ${f} could not be determined.`:void 0)}}function fn(c,d){let h=See(d.getTimings());if(!h)return;if(c.perfTiming=h.data,h.truncated)c.perfTimingTruncated=!0}var yn=s({className:n(),bounds:s({left:a().finite(),top:a().finite(),right:a().finite(),bottom:a().finite()}),text:n().optional(),"resource-id":n().optional(),enabled:p(["true","false"]).optional(),focused:p(["true","false"]).optional(),selected:p(["true","false"]).optional(),get node(){return b(yn).optional()}}),Ya=s({hierarchy:yn,updatedAt:a().finite(),packageName:n(),screenWidth:a().positive().finite(),screenHeight:a().positive().finite()});function $t(c){return Ya.safeParse(c).success}function jA(c){if(!$t(c))throw new t("Invalid visionOS hierarchy; reconnect the runner.");return Yw(c)}import{AsyncLocalStorage as Xa}from"async_hooks";var De=new Xa;function Ja(c,d){return c.labelSessionUuids??d?.labelSessionUuids}function Qa(c,d){return c.routingBaseSessionUuid??d?.routingBaseSessionUuid}function Za(c,d){return c.callerMcpSessionId??d?.callerMcpSessionId}function ec(c,d){return c.deviceConnectionKey??d?.deviceConnectionKey}function tc(c,d){return Object.hasOwn(c,"requestDeadline")?c.requestDeadline:d?.requestDeadline}var jd=async(c,d)=>{let h=De.getStore();return De.run({...h,...c,planRequest:c.planRequest??h?.planRequest,routingSessionUuid:c.routingSessionUuid??h?.routingSessionUuid,callerMcpSessionId:Za(c,h),deviceConnectionKey:ec(c,h),execution:c.execution??h?.execution,requestDeadline:tc(c,h),toolSelectionProfileUuid:c.toolSelectionProfileUuid??h?.toolSelectionProfileUuid,labelSessionUuids:Ja(c,h),routingBaseSessionUuid:Qa(c,h),sessionToolSelectionService:c.sessionToolSelectionService??h?.sessionToolSelectionService},()=>$h((c.execution??h?.execution)?.deviceBinding,d))},Be=()=>De.getStore(),yr=()=>De.getStore()?.autolockMcpSessionId,cc=()=>De.getStore()?.oneShotCli===!0,fQ=()=>De.getStore()?.acceptanceDiscoveryOrder,bh=()=>{let c=De.getStore();return c?.autolockMcpSessionId??c?.callerMcpSessionId};function Sh(){return Be()?.execution}function Is(){return Be()?.requestDeadline}function rV(){return Be()?.planLockNamespace}function wh(){return Be()?.explicitObserveDeviceRead===!0}import{access as gn}from"fs/promises";import{join as rc}from"path";var qt="AutoMobileVisionTest";class zt{dependencies;builds=new at;constructor(c){this.dependencies=c}async resolve(c){c?.throwIfAborted();let d=(this.dependencies.override??(()=>ft(g.VISIONOS_RUNNER_XCTESTRUN)))();if(d){let C=Ae(d);return await(this.dependencies.access??gn)(C),C}let h=this.dependencies.builder,f=await h.getXctestrunPath("visionSimulator",{scheme:qt});if(f)return f;let P=h.getConfig();return await this.builds.run(P.derivedDataPath,async(C)=>await U(C,async()=>{let A=async()=>{C?.throwIfAborted();let T=rc(Ae(P.projectRoot),"ios","control-proxy","CtrlProxy.xcodeproj");try{await(this.dependencies.access??gn)(T)}catch(O){throw new t(`Visionos runner project is unavailable; set ${g.VISIONOS_RUNNER_XCTESTRUN.name} to a prebuilt visionos runner xctestrun. The published package does not include the visionos project.`,{cause:O})}await(this.dependencies.xcodebuild??new qn).executeCommand(["build-for-testing","-project",T,"-scheme",qt,"-destination","generic/platform=visionOS Simulator","-derivedDataPath",P.derivedDataPath,"CODE_SIGNING_ALLOWED=NO"],{signal:C,timeoutMs:120000});let I=await h.getXctestrunPath("visionSimulator",{scheme:qt});if(!I)throw new t(`No xrsimulator xctestrun found in ${P.derivedDataPath}/Build/Products after building AutoMobileVisionTest; set ${g.VISIONOS_RUNNER_XCTESTRUN.name} to a prebuilt visionos runner.`);return I};return h.runExclusiveOnDerivedData?await h.runExclusiveOnDerivedData(A):await A()}),c,{cancelWhenAllWaitersAbort:!0})}}class ve extends t{errorCode;constructor(c,d,h){super(c,h);this.errorCode=d}}import ic from"ws";var vn=5000,nc=20000,oc=(c)=>{let d=new ic(c);return{send:(h)=>d.send(h),close:()=>d.close(),onMessage:(h)=>{d.on("message",(f)=>h(f.toString()))},onFailure:(h)=>{d.on("error",h),d.on("close",()=>h(Error("Visionos runner disconnected; reconnect it.")))}}};function sc(c){return c==="request_hierarchy"?"hierarchy_update":`${c.slice(8)}_result`}function ac(c){if(c==="request_hierarchy")return"The visionOS runner could not read this app's accessibility window even after relaunching the app. Other apps on the simulator may still work. Use a screenshot (simctl/screenshot) to see the app instead.";return`The visionOS runner could not read this app's accessibility window, so ${c} failed; the app was not relaunched. Observe the app first (observing relaunches it once to recover), then retry this step. Other apps on the simulator may still work. Use a screenshot (simctl/screenshot) to see the app instead.`}function lc(c){return c.type==="request_hierarchy"?nc:vn}class Yt{options;socket;pending=new Map;sequence=0;supported=new Set;ready;resolveReady;rejectReady;failure;constructor(c,d={}){this.options=d;this.ready=new Promise((h,f)=>{this.resolveReady=h,this.rejectReady=f}),this.ready.then(void 0,()=>{}),this.socket=(d.factory??oc)(c),this.socket.onMessage((h)=>this.receive(h)),this.socket.onFailure((h)=>this.fail(u(h,"Visionos runner connection failed")))}isUsable(){return this.failure===void 0}async waitUntilConnected(c,d){await l(async()=>{if(await this.ready,this.failure)throw this.failure},{timer:this.options.timer??i,timeoutMs:d?.timeoutMs??this.options.timeoutMs??vn,signal:c,label:"Visionos runner connected handshake"})}fail(c){this.failure=c,this.rejectReady(c);for(let d of this.pending.values())d.reject(c);this.pending.clear()}receive(c){try{let d=JSON.parse(c);if(!d||typeof d!=="object"||!("type"in d))throw new t("Invalid visionos runner response; reconnect it.");let h=d;if(h.type==="connected")this.connected(h);else this.reply(h)}catch(d){this.fail(u(d,"Invalid visionos runner response")),this.socket.close()}}connected(c){if(c.platform!=="visionos"){this.fail(new ve("Refusing runner: connected platform must be visionos.","invalid_runner_platform")),this.socket.close();return}this.supported=new Set(Array.isArray(c.supportedCommands)?c.supportedCommands.filter((d)=>typeof d==="string"):[]),this.resolveReady();return}reply(c){let d=typeof c.requestId==="string"?this.pending.get(c.requestId):void 0;if(!d)return;if(c.type==="error"||c.success===!1){let h=String(c.error??"Visionos command failed");if(h.includes("kAXErrorAPIDisabled")){d.reject(new ve(ac(d.type),"accessibility_api_disabled",{cause:h}));return}d.reject(new ve(h,String(c.errorCode??"command_failed")))}else if(c.type===sc(d.type)&&(c.success===!0||d.type==="request_hierarchy"&&c.success===void 0))d.resolve(c.data)}async request(c,d,h){let f=this.options.timer??i,P=h?.timeoutMs??this.options.timeoutMs??lc(c),C=String(++this.sequence),A=new AbortController,T=c.type!=="request_hierarchy",I=!1,O=!1,x=d?AbortSignal.any([d,A.signal]):A.signal;try{return await l(async()=>{if(await this.ready,x.throwIfAborted(),this.failure)throw this.failure;if(!this.supported.has(c.type))throw new ve(`The visionos runner does not support ${c.type}.`,"unsupported_on_visionos");return new Promise((N,H)=>{this.pending.set(C,{type:c.type,resolve:(V)=>{O=!0,N(V)},reject:(V)=>{O=!0,H(V)}}),this.socket.send(JSON.stringify({...c,requestId:C})),I=!0})},{timer:f,timeoutMs:P,signal:x,label:`Visionos runner ${c.type}`})}catch(N){if(I&&!O&&T&&!d?.aborted)throw new ve(`Visionos runner ${c.type} got no reply within ${P}ms and may still be applied; observe before retrying.`,"input_outcome_unknown",{cause:N});throw N}finally{A.abort(),this.pending.delete(C)}}async hierarchy(c,d){let h=await this.request({type:"request_hierarchy"},c,d);if(!$t(h))throw new t("Invalid visionos hierarchy; reconnect the runner.");return h}close(){this.fail(new t("Visionos runner closed; reconnect it.")),this.socket.close()}}class bn{clients=new Map;get(c){return this.clients.get(c)}require(c){let d=this.get(c);if(!d)throw new t(`Start and connect the visionos XCUITest runner for ${c} before acting.`);return d}register(c,d){if(this.clients.has(c))throw new t(`A visionos runner is already registered for ${c}.`);return this.clients.set(c,d),()=>{if(this.clients.get(c)===d)this.clients.delete(c)}}}var Xy=new bn;import{rm as dc}from"fs/promises";function mc(c){for(let[d,h]of[["stdout",c.stdout],["stderr",c.stderr]])h?.on("data",(f)=>{e.debug(`Visionos runner ${d}: ${String(f).trimEnd()}`)})}class Jt{dependencies;constructor(c){this.dependencies=c}async launch(c){if(!Number.isInteger(c.port)||c.port<1||c.port>65535)throw new t("Visionos runner port must be an integer from 1 to 65535.");if(Xy.get(c.deviceId))throw new t("Visionos runner is already connected.");c.signal?.throwIfAborted();let d=c.bundleId?.trim()||void 0,h=await this.dependencies.writeRunnerEnvironment(c.xctestrun,{AM_PORT:String(c.port),...d?{AM_BUNDLE_ID:d}:{}},`visionos-${c.deviceId}`),f=!1,P=()=>{if(!f&&h!==c.xctestrun)f=!0,dc(h,{force:!0}).catch((C)=>{e.warn("Failed to remove visionos runner xctestrun copy",C)})};try{return await this.launchPrepared({...c,bundleId:d,xctestrun:h},P)}catch(C){throw P(),u(C,"Failed to launch visionos runner")}}async launchPrepared(c,d){let h=this.dependencies.timer??i;c.signal?.throwIfAborted();let f=await(this.dependencies.xcodebuild??new qn).startStreaming(["test-without-building","-xctestrun",c.xctestrun,"-destination",`platform=visionOS Simulator,id=${c.deviceId}`,"-only-testing:CtrlProxyVisionUITests/CtrlProxyVisionUITests/testRunService"],{env:{...globalThis.process.env,TEST_RUNNER_AM_PORT:String(c.port),...c.bundleId?{TEST_RUNNER_AM_BUNDLE_ID:c.bundleId}:{}},stdio:["ignore","pipe","pipe"],startupSignal:c.signal}),P={exited:!1,unregister:()=>{}},C=()=>{P.exited=!0,P.unregister(),P.client?.close(),d()},A=()=>{let T=!P.exited;if(C(),T)f.kill("SIGTERM")};mc(f),f.once("exit",C),f.once("error",C);try{return await l(()=>this.waitForRunner(c,P),{timer:h,timeoutMs:60000,label:"Visionos runner startup",onTimeout:A,signal:c.signal}),{stop:A}}catch(T){throw A(),u(T,"Failed to launch visionos runner")}}async waitForRunner(c,d){let h=this.dependencies.timer??i;while(!d.exited){let f=(this.dependencies.connect??((P)=>new Yt(P,{timer:h})))(`ws://127.0.0.1:${c.port}/ws`);d.client=f;try{await f.waitUntilConnected(c.signal)}catch(P){if(f.close(),d.exited||c.signal?.aborted||P instanceof ve)throw u(P,"Visionos runner exited during startup");e.debug("Visionos runner not ready during startup",P),await h.sleep(100);continue}if(d.exited)break;c.signal?.throwIfAborted(),d.unregister=Xy.register(c.deviceId,f);return}throw new t("Visionos runner exited before becoming ready; check the prebuilt test bundle.")}}class nV{apps=new Map;uninstallListeners=[];get(c){return this.apps.get(c)}launched(c,d){this.apps.set(c,d)}terminated(c,d){if(this.apps.get(c)===d)this.apps.delete(c)}uninstalled(c,d){this.terminated(c,d);for(let h of this.uninstallListeners)h(c,d)}onUninstalled(c){this.uninstallListeners.push(c)}}var AF=new nV;var tr="dev.jasonpearson.automobile.ctrlproxy.vision";class wn{dependencies;starts=new at;runners=new Map;observedSessions=new WeakSet;constructor(c){this.dependencies=c;c.appUninstalls?.onUninstalled((d,h)=>this.appUninstalled(d,h))}appUninstalled(c,d){let h=this.runners.get(c);if(h&&(h.bundleId??tr)===d)h.appRemoved=!0}async ensure(c){let d=await this.start(c);return this.attach(c)??d.runnerUnavailable}async start(c){return this.starts.run(c.deviceId,(d)=>this.startOwned({...c,signal:d}),c.signal,{cancelWhenAllWaitersAbort:!0})}async startOwned(c){let{deviceId:d,sessions:h}=c;if(h)this.observeSessions(h);if(Xy.get(d)?.isUsable()&&!this.needsRestart(d))return{};this.stop(d);let f=this.dependencies.targetBundleId?.(d),P={controller:new AbortController,bundleId:f},C=Ge(c.signal,P.controller.signal);this.runners.set(d,P);try{let A=await this.dependencies.artifacts.resolve(C);C.throwIfAborted(),P.port=this.dependencies.ports.allocate(d);let T=await this.dependencies.launcher.launch({deviceId:d,xctestrun:A,port:P.port,bundleId:f,signal:C});if(P.stop=T.stop,C.aborted||this.runners.get(d)!==P){if(this.runners.get(d)!==P)T.stop();throw new t("the visionos session ended during runner startup")}return{stop:()=>{if(this.runners.get(d)===P)this.stop(d)}}}catch(A){if(this.runners.get(d)===P)this.stop(d);let T=r(A);return e.warn(`[VisionosRunner] Runner unavailable for ${d}: ${T}`,A),{runnerUnavailable:T}}}needsRestart(c){let d=this.runners.get(c);return d!==void 0&&(d.appRemoved===!0||d.bundleId!==this.dependencies.targetBundleId?.(c))}attach({deviceId:c,ownerSession:d,sessions:h}){this.observeSessions(h);let f=this.runners.get(c);if(!h.hasSession(d)){if(!f?.ownerSession)this.stop(c);return"the visionos session ended before runner startup"}if(f)f.ownerSession=d;return}stop(c){let d=this.runners.get(c);if(!d)return;this.runners.delete(c),d.controller.abort(new t("Visionos runner lifecycle ended"));try{d.stop?.()}catch(h){e.warn(`[VisionosRunner] Failed to stop runner for ${c}`,h)}finally{if(d.port!==void 0)this.dependencies.ports.release(c,d.port)}}stopSession(c){for(let[d,h]of this.runners)if(h.ownerSession===c)this.stop(d)}stopAll(){for(let c of this.runners.keys())this.stop(c)}observeSessions(c){if(this.observedSessions.has(c))return;this.observedSessions.add(c),c.onSessionRelease((d)=>this.stopSession(d)),c.onSessionDeviceUnbound((d,h)=>{if(this.runners.get(h)?.ownerSession===d)this.stop(h)})}}var er;function hQ(c){er=c}function Sn(){if(!er)throw new t("Visionos runner builder has not been registered by the server.");return er()}function hc(c){return{getXctestrunPath:(d,h)=>c().getXctestrunPath(d,h),getConfig:()=>c().getConfig(),runExclusiveOnDerivedData:(d)=>{let h=c();return h.runExclusiveOnDerivedData?h.runExclusiveOnDerivedData(d):d()}}}var Re;function fc(){if(!Re)Re=new wn({artifacts:new zt({builder:hc(Sn)}),launcher:new Jt({writeRunnerEnvironment:(c,d,h)=>Sn().writeRunnerEnvironment(c,d,`${h}-${L.next()}`)}),targetBundleId:(c)=>AF.get(c)??globalThis.process.env.CTRL_PROXY_IOS_BUNDLE_ID,appUninstalls:AF,ports:{allocate:(c)=>Pe.allocate(`visionos:${c}`,{reservedPorts:To}),release:(c,d)=>Pe.releaseIfAllocated(`visionos:${c}`,d)}}),process.once("exit",()=>Re?.stopAll());return Re}function gQ(){Re?.stopAll()}async function jS(c,d,h){if(d?.throwIfAborted(),!Xy.get(c)?.isUsable()||(h??Re)?.needsRestart?.(c)){h??=fc();let f=await h.start({deviceId:c,signal:d});if(d?.throwIfAborted(),f.runnerUnavailable)throw new t(`visionOS window-app runner unavailable: ${f.runnerUnavailable}`)}return gc(c,h),Xy.require(c)}function yc(c){let d=r(c);return d.includes(tr)&&/is not running|not installed/i.test(d)}async function KA(c,d,h,f){try{return await h()}catch(P){let C=f??Re;if(d?.aborted||!yc(P)||!C?.appUninstalled)throw P;if(C.appUninstalled(c,tr),!C.needsRestart?.(c))throw P;return e.warn(`[VisionosRunner] Host app of the runner for ${c} is gone; restarting the runner: ${r(P)}`,P),h()}}function gc(c,d){let h=Be()?.routingSessionUuid,f=w.sessionManager();if(h&&f){let P=(d??Re)?.attach({deviceId:c,ownerSession:h,sessions:f});if(P)throw new t(P)}}function GA(c){Re?.stop(c)}var Rn=s({className:n(),bounds:s({left:a().finite(),top:a().finite(),right:a().finite(),bottom:a().finite()}),text:n().optional(),"resource-id":n().optional(),enabled:p(["true","false"]).optional(),focused:p(["true","false"]).optional(),selected:p(["true","false"]).optional(),get node(){return b(Rn).optional()}}),vc=s({hierarchy:Rn,updatedAt:a().finite(),packageName:n(),screenWidth:a().positive().finite(),screenHeight:a().positive().finite()});function TF(c){return vc.safeParse(c).success}function im(c){if(!TF(c))throw new t("Invalid tvOS hierarchy; reconnect the runner.");return Yw(c)}class Pn{clients=new Map;get(c){return this.clients.get(c)}require(c){let d=this.get(c);if(!d)throw new t(`Start and connect the tvos XCUITest runner for ${c} before acting.`);return d}register(c,d){if(this.clients.has(c))throw new t(`A tvos runner is already registered for ${c}.`);return this.clients.set(c,d),()=>{if(this.clients.get(c)===d)this.clients.delete(c)}}}var Ln=new Pn;function B4(c){if(!c||typeof c!=="object")return!1;let d=c;return typeof d.timestamp==="number"&&Number.isFinite(d.timestamp)&&[d.screenWidth,d.screenHeight,d.screenScale].every((h)=>typeof h==="number"&&Number.isFinite(h)&&h>0)&&(d.bundleId===void 0||d.bundleId===null||typeof d.bundleId==="string")&&Cn(d.root)}function Cn(c){if(!c||typeof c!=="object")return!1;let d=c;return typeof d.className==="string"&&Sc(d.bounds)&&wc(d)&&(d.children===void 0||d.children===null||Array.isArray(d.children)&&d.children.every(Cn))}function Sc(c){if(!c||typeof c!=="object")return!1;let d=c;return["left","top","right","bottom"].every((h)=>typeof d[h]==="number"&&Number.isFinite(d[h]))}function wc(c){let d=c.accessibilityTraits??[];return[c.accessibilityIdentifier,c.accessibilityLabel,c.role].every((h)=>h===void 0||h===null||typeof h==="string")&&[c.isHidden,c.isOccluded,c.isAccessibilityElement,c.isAccessibilityFocused,c.hasTapTarget,c.isUserInteractionEnabled].every((h)=>h===void 0||h===null||typeof h==="boolean")&&Number.isFinite(c.alpha??1)&&Array.isArray(d)&&d.every((h)=>typeof h==="string")}function Tn(c){return!c.isHidden&&!c.isOccluded&&(c.alpha??1)>0}var Rc=new Set([9,10,12,14,15,16,17,20,27,30,40,41,42,45,49,50,52,54,56,59,60,75,80]),Pc=new Set([45,49,50,52]),Cc=new Set([26,32,46]);function Ac(c){let d=/^XCUIElementType\((\d+)\)$/.exec(c);return d?Number(d[1]):void 0}function rr(c,d){let h=Ac(c.className);return h!==void 0&&d.has(h)}function Tc(c,d){let h=d&&rr(c,Rc),f=d&&rr(c,Pc);return{clickable:String((c.hasTapTarget??!1)||h),scrollable:rr(c,Cc)?"true":void 0,actions:f?["set_text"]:void 0}}function In(c){let d=c.isUserInteractionEnabled??!0;return{text:c.accessibilityLabel??void 0,resourceId:c.accessibilityIdentifier??void 0,role:c.role??void 0,className:c.className,bounds:c.bounds,enabled:String(d),...Tc(c,d),focusable:String(c.isAccessibilityElement??!1),accessibilityFocused:String(c.isAccessibilityFocused??!1),extras:c.accessibilityTraits?.length?{"sdk.accessibilityTraits":c.accessibilityTraits.join(",")}:void 0,node:(c.children??[]).filter(Tn).map(In)}}function YA(c){if(!B4(c))throw new t("The watch runner returned an invalid hierarchy; reconnect the runner.");return Yw({updatedAt:c.timestamp,hierarchy:Tn(c.root)?In(c.root):{},packageName:c.bundleId??"",screenWidth:c.screenWidth,screenHeight:c.screenHeight,screenScale:c.screenScale})}class kn{clients=new Map;get(c){return this.clients.get(c)}require(c){let d=this.get(c);if(!d)throw new t(`Start and connect the watch XCUITest runner for ${c} before acting.`);return d}register(c,d){if(this.clients.has(c))throw new t(`A watch runner is already registered for ${c}.`);return this.clients.set(c,d),()=>{if(this.clients.get(c)===d)this.clients.delete(c)}}}var yo=new kn;var ir=Lt(Im());var xn=new Map;function iV(c){let d=xn.get(c);if(!d)d=new Un,xn.set(c,d);return d}var Ic=1500;async function En(c,{deadline:d,signal:h},f){if(c.deviceId===void 0)return f();o(h);let P=d-c.timer.now();if(P<=0)throw Error("Hierarchy fallback deadline exhausted before the dump lock was free");let C=iV(c.deviceId).acquire(),A;try{A=await l(C,{timer:c.timer,timeoutMs:P,signal:h,label:"Hierarchy fallback dump lock wait"})}catch(T){throw C.then((I)=>I()),T}try{return await f()}finally{A()}}function Fn(c,d){let h=Gt(d??c.bounds);return JSON.stringify([c.package,c.class,cl(c,"resource-id")??"",cl(c,"text")??"",cl(c,"content-desc")??"",h?[h.left,h.top,h.right,h.bottom]:null])}function nr(c,d,h){return c.flatMap((f)=>{let P=nr(f.node??[],d,h),C=f.$,A=Gt(C?.bounds);if(!C||h!==void 0&&C.package!==h||!A||A.right<=A.left||A.bottom<=A.top)return P;let T={...C,"hierarchy-source":"uiautomator"},I={$:T,bounds:A,...P.length?{node:P}:{}};if(delete T["view-id"],delete T["unique-id"],delete T.actions,d.has(Fn(T,I.bounds)))return P;return[I]})}function kc(c,d,h){let f=new G,P=new Set(f.flattenViewHierarchy(c,{includeWindows:!0}).map((T)=>Fn(T.element,T.element.bounds))),C=nr(d,P,h);if(!C.length)return c;let A={...c,packageName:h,hierarchy:{node:{$:{},node:[...f.extractRootNodes(c),...C]}},sources:[...new Set([...c.sources??["control-proxy"],"uiautomator"])],fresh:!1};return delete A.frameContext,delete A.receivedAt,delete A.updatedAt,A}async function oV(c,d,h,f){if(o(f),d.timer.now()>=h)return c;let P=Nn(d.idGenerator),C=Hn(d,{deadline:h,signal:f});try{let A=await d.adb.getForegroundApp(f,h-d.timer.now());if(!A)return c;if(c.packageName!==void 0&&c.packageName!==A.packageName)return c;e.warn(`[HierarchyFallback] Supplementing incomplete CtrlProxy hierarchy (ctrlProxyIncompleteReason=${c.ctrlProxyIncompleteReason??"unknown"})`);let T=await En(d,{deadline:h,signal:f},async()=>(await C(["shell","uiautomator","dump",P]),C(["shell","cat",P])));return o(f),await Dc(c,T.stdout,A,{deps:d,bound:{deadline:h,signal:f}})}catch(A){return o(f),e.debug("[HierarchyFallback] Could not supplement incomplete CtrlProxy hierarchy",A),c}finally{await _n(d,P,h,f)}}async function _n(c,d,h,f){let P=c.adb.execute(["shell","rm","-f",d],{timeoutMs:Ic,signal:new AbortController().signal,noRetry:!0}).catch((A)=>{e.debug("[HierarchyFallback] Could not remove temporary dump",A)}),C=h-c.timer.now();if(f?.aborted||C<=0){o(f);return}try{await l(P,{timer:c.timer,timeoutMs:C,signal:f,label:"Hierarchy fallback cleanup wait"})}catch(A){e.debug("[HierarchyFallback] Stopped waiting for temporary dump cleanup",A)}o(f)}function Nn(c=L){return`/data/local/tmp/automobile-hierarchy-${c.next()}.xml`}async function Dc(c,d,h,{deps:f,bound:P}){let{deadline:C,signal:A}=P,I=(await ir.parseStringPromise(d,{explicitArray:!0})).hierarchy?.node;if(!Array.isArray(I)||f.timer.now()>=C)return c;let O=await f.adb.getForegroundApp(A,C-f.timer.now());if(o(A),O?.packageName!==h.packageName||O?.userId!==h.userId||f.timer.now()>=C)return c;return kc(c,I,h.packageName)}function Hn(c,{deadline:d,signal:h}){return async(f)=>{o(h);let P=d-c.timer.now();if(P<=0)throw Error("Hierarchy fallback deadline exhausted");return c.adb.execute(f,{timeoutMs:P,signal:h,noRetry:!0,maxBuffer:4194304})}}function Oc(c){let d=new Set,h=(f)=>{let P=f.$?.package;if(typeof P==="string"&&P)d.add(P);(f.node??[]).forEach(h)};return c.forEach(h),d.size===1?[...d][0]:void 0}function Wn(c,d){return c.every((h)=>{let f=h.bounds;return(!f||f.left>=0&&f.top>=0&&f.right<=d.width&&f.bottom<=d.height)&&Wn(h.node??[],d)})}async function xc(c,d){let f=ig((await d(["shell","dumpsys","display"])).stdout).find((P)=>P.logicalId===String(c))?.sizePx;if(!f||f.width<=0||f.height<=0)throw new t(`Display ${c} has no readable size in dumpsys display`);return f}async function $n(c,d,h,f){let P=Nn(d.idGenerator),C=Hn(d,{deadline:h,signal:f});try{let A=await xc(c,C),T=await En(d,{deadline:h,signal:f},async()=>(await C(["shell","uiautomator","dump","--display",String(c),P]),C(["shell","cat",P]))),I=await ir.parseStringPromise(T.stdout,{explicitArray:!0});o(f);let O=nr(I.hierarchy?.node??[],new Set);if(!O.length||d.timer.now()>=h)throw new t(`UIAutomator returned no hierarchy for display ${c}`);if(!Wn(O,A))throw new t(`UIAutomator dump does not fit display ${c} (${A.width}x${A.height}); this Android release likely ignores --display`);let x=Oc(O);return{hierarchy:{node:O.length===1?O[0]:{$:{},node:O}},displayId:c,screenWidth:A.width,screenHeight:A.height,...x?{packageName:x}:{},sources:["uiautomator"],fresh:!1}}catch(A){throw o(f),u(A,`Failed to read display ${c} with UIAutomator`)}finally{await _n(d,P,h,f)}}class or{hierarchy;sync;visible;settle;constructor(c,d,h,f){this.hierarchy=c;this.sync=d;this.visible=h;this.settle=f}readCached(c){return this.hierarchy.getViewHierarchy({},{skipWaitForFresh:!0,minTimestamp:c.minTimestamp??0,signal:c.signal,timeoutMs:c.timeoutMs})}readFresh(c){return this.sync(c)}async readSettled(c){if(!this.settle)throw new t("Settled hierarchy capture requires a settlement adapter");let d=await this.settle.execute({timeoutMs:c.timeoutMs,initialMinTimestampMs:c.minTimestamp,signal:c.signal,skipPerformanceAudit:!0,skipRecompositionTracking:!0});if(!d.settled||!d.observation.viewHierarchy)throw new t(`Hierarchy did not settle: ${d.terminalReason}`);return d.observation.viewHierarchy}projectVisible(c){return this.visible(c)}}class He extends t{}class ar{clock;current;listeners=new Set;constructor(c,d){this.clock=c;this.current=d}get deadlineMs(){return this.current}remainingMs(){return Math.max(0,this.current-this.clock.now())}set(c){if(c===this.current)return;this.current=c;for(let d of[...this.listeners])d()}onChange(c){return this.listeners.add(c),()=>{this.listeners.delete(c)}}whenExpired(c,d,h){let f,P=!1,C=()=>{if(f!==void 0)c.clearTimeout(f),f=void 0},A=()=>{if(P)return;C(),f=c.setTimeout(()=>{if(f=void 0,this.remainingMs()>0){A();return}P=!0,T(),d()},this.remainingMs()),h?.(f)},T=this.onChange(A);return A(),()=>{P=!0,T(),C()}}}async function Ec(c,d,h){let f=v.create(c),[P,C]=await Promise.allSettled([f.execute(["shell","cmd","package","path","android"],{timeoutMs:h,noRetry:!0,signal:d}),f.execute(["shell","settings","get","secure","accessibility_enabled"],{timeoutMs:h,noRetry:!0,signal:d})]);d.throwIfAborted();let A=[],T=[];if(P.status==="rejected"||!P.value.stdout.includes("package:"))A.push("package"),T.push(P.status==="rejected"?`package: ${ie(P.reason)}`:`package: ${ie(P.value.stdout||P.value.stderr)}`);if(C.status==="rejected"||nl(`${C.value.stdout}
|
|
6
|
-
${C.value.stderr}`))A.push("settings"),T.push(C.status==="rejected"?`settings: ${ie(C.reason)}`:`settings: ${ie(C.value.stdout||C.value.stderr)}`);return{ready:A.length===0,...A.length>0?{unavailableResources:A}:{},...T.length>0?{diagnostic:T.join("; ")}:{}}}function Gn(c){return ie(c).replace(/\s+/g," ").trim()||"empty"}async function Mc(c,d){let h=v.create(c),f=v.create(),P={timeoutMs:Ne,noRetry:!0,signal:d},[C,A,T]=await Promise.allSettled([h.execute(["shell","getprop","sys.boot_completed"],P),f.execute(["devices","-l"],P),f.execute(["-s",c.deviceId,"get-state"],P)]),I=(O)=>O.status==="fulfilled"?Gn(O.value.stdout||O.value.stderr):`unavailable (${Gn(r(O.reason))})`;return{sysBootCompleted:I(C),adbDevices:I(A),emulatorQemuHealth:I(T)}}function sV(c=i){return new RF({timer:c,getAndroidFrameworkReadiness:Ec,getAndroidManager:(d)=>ce.getInstance(d),getAndroidClient:(d)=>k.getInstance(d),getIosManager:(d)=>ge.getInstance(d),getIosClient:(d,h)=>_.getInstance(d,h),checkIosOverride:Bv,awaitIosStartupMaintenance:()=>ge.awaitStartupOrphanRunnerReap(),getAndroidRunnerConnectDiagnostic:async(d,h)=>{let f=v.create(d),[P,C]=await Promise.all([f.getDeviceLock(h),f.listUsers(h)]),A=C.find((T)=>T.profileType==="primary"||T.userId===0);return{deviceLock:P,primaryUserStartState:A?.startState}},getAndroidRunnerHealthDiagnostic:Mc})}function cr(c){return c.platform==="ios"?_.getExistingInstance(c.deviceId):k.getExistingInstance(c.deviceId)}var Fc={async awaitTransition(c,d){return w.devicePool()?.waitForAssignmentTransition(c.deviceId,d)??!1},canStart(c){let d=w.devicePool();if(!d)return!1;let h=d.getDevice(c.deviceId);return!gB(ro(c.platform,c.deviceId))&&h?.platform===c.platform&&h.name===c.name&&Sr(h)&&!D(h)&&d.isSafeForObservationServiceStart(c.deviceId)}},_c={available:()=>w.devicePoolWrites()!==void 0,isPooled:(c)=>Boolean(w.devicePool()?.getDevice(c.deviceId)),ensurePooled:async(c)=>{await w.devicePoolWrites()?.pickUpRunningDevice(c)}},Nc=1e4,Kn=8,Hc=60000,Vc=300000;class jn{options;queueSnapshots=new Map;flights=new at;pickupFlights=new at;unpooledPickupAt=new Map;poolPickup;timer;guard;constructor(c={}){this.options=c;this.timer=c.timer??i,this.guard=c.ownershipGuard??Fc,this.poolPickup=c.poolPickup??_c}async start(c){if(c.signal?.throwIfAborted(),!this.guard.canStart(c.device)){if(this.poolPickup.available()&&!this.poolPickup.isPooled(c.device))await this.pickupIfUnpooled(c);await this.admit(c)}let d=ro(c.device.platform,c.device.deviceId),h=this.queueSnapshotFor(d),f=!1;try{return await l(()=>this.flights.run(d,(P)=>this.setup({request:c,flightSignal:P,snapshot:h}),c.signal,{cancelWhenAllWaitersAbort:!0}),{timer:this.timer,timeoutMs:Math.max(0,c.deadlineMs-this.timer.now()),signal:c.signal,label:"Observer hierarchy service start",onTimeout:()=>{f=!0}})}catch(P){c.signal?.throwIfAborted(),e.warn(`[observe] Hierarchy service start failed: ${r(P)}`,P);let C=f&&c.device.platform==="ios"&&this.flights.has(d);return this.rethrowStartupFailure(P,c,h,C)}finally{if(!this.flights.has(d))this.clearQueueSnapshot(d,h)}}async admit(c){let d=0;while(!this.guard.canStart(c.device)){let h=c.deadlineMs-this.timer.now();if(!this.guard.awaitTransition||h<=0||d>=Kn)break;if(d++,!await this.awaitTransition(c.device,c.deadlineMs,c.signal))break}if(!this.guard.canStart(c.device))throw new t("service start declined: ownership or pool transition cannot be excluded")}async awaitTransition(c,d,h){return l(()=>this.guard.awaitTransition(c,h),{timer:this.timer,timeoutMs:Math.max(0,d-this.timer.now()),signal:h,label:"Observer pool assignment transition"})}queueSnapshotFor(c){let d=this.flights.has(c)?this.queueSnapshots.get(c)??{}:{};return this.queueSnapshots.set(c,d),d}clearQueueSnapshot(c,d){if(this.queueSnapshots.get(c)===d)this.queueSnapshots.delete(c)}rethrowStartupFailure(c,d,h,f){if(!(c instanceof go&&c.deadlineExhausted||c instanceof Error&&c.message.startsWith("Observer hierarchy service start timed out"))||d.device.platform!=="ios")throw c;let C=h.status??this.launchQueueStatus(d.device);throw new OD(d.device.deviceId,C,{cause:c,startWindowExpired:!C&&!f})}launchQueueStatus(c){return c.platform==="ios"?(this.options.launchQueue??XL()).queueStatus(c.deviceId):void 0}async pickupIfUnpooled(c){let{device:d}=c;if(this.poolPickup.isPooled(d))return;let h=c.deadlineMs-this.timer.now();if(h<=0)throw new t("Observer device pool pickup timed out before pickup");let f=ro(d.platform,d.deviceId),P=await l(()=>this.pickupFlights.run(f,async()=>{let C=this.unpooledPickupAt.get(f);if(this.poolPickup.isPooled(d)||C!==void 0&&this.timer.now()-C<Nc)return;let A;try{await this.poolPickup.ensurePooled(d)}catch(T){A=r(T),e.warn(`[observe] Device pool pickup failed: ${A}`,T)}if(!this.poolPickup.isPooled(d))this.unpooledPickupAt.set(f,this.timer.now());else this.unpooledPickupAt.delete(f);return A},c.signal),{timer:this.timer,timeoutMs:h,signal:c.signal,label:"Observer device pool pickup"});if(!this.poolPickup.isPooled(d)){if(P!==void 0)throw new t(`Device ${d.deviceId} is running but could not be added to this daemon's device pool: ${P}; call startDevice for it.`);throw new t(`Device ${d.deviceId} is running but not known to this daemon's device pool; call startDevice for it (or retry once the daemon has discovered it).`)}}async setup(c){let{request:d,flightSignal:h,snapshot:f}=c;if(f.status=void 0,(this.options.isServiceConnected??((O)=>cr(O)?.isConnected()===!0))(d.device))return!1;let P=ro(d.device.platform,d.device.deviceId);if(Yte(P))throw new t("service start declined: device readiness is in progress");let C=d.deadlineMs-this.timer.now();if(C<=0)throw new t("Observer hierarchy service start timed out before setup");let A=d.device.platform==="ios"?Math.max(C,this.options.iosFlightCeilingMs??Hc):C,T=this.startFlightDeadline(d,f,A),I=h?AbortSignal.any([h,T.signal]):T.signal;try{let O=this.options.readiness??sV(this.timer);return await this.ensureReadyWithTransitions(O,{device:d.device,requestedIdentity:d.device.deviceId,operationName:"observe deviceId",totalDeadlineMs:T.totalDeadlineMs,deadline:T.deadline,readinessTimeoutMs:A,signal:I,skipCtrlProxyDownload:(this.options.skipCtrlProxyDownload??(()=>M.isSkipCtrlProxyDownloadEnabled()))(),assertCanSetup:()=>{if(I.throwIfAborted(),!this.guard.canStart(d.device))throw new He("service start declined: ownership or pool transition changed while waiting for readiness")}}),!0}finally{T.stop(),this.clearQueueSnapshot(P,f)}}startFlightDeadline(c,d,h){let f=new AbortController,P=()=>{d.status=this.launchQueueStatus(c.device),f.abort(new t("Observer hierarchy service start timed out"))};if(c.device.platform!=="ios"){let I=this.timer.setTimeout(P,h);return{signal:f.signal,totalDeadlineMs:c.deadlineMs,deadline:void 0,stop:()=>this.timer.clearTimeout(I)}}let C=new ar(this.timer,this.timer.now()+h),A=this.followLaunchQueue(c.device,C,h),T=C.whenExpired(this.timer,P);return{signal:f.signal,totalDeadlineMs:C.deadlineMs,deadline:C,stop:()=>{T(),A()}}}followLaunchQueue(c,d,h){let f=Math.max(h,this.options.iosQueueCeilingMs??Vc),C=this.timer.now()+f+h,A=(x)=>d.set(Math.min(x,C)),T=()=>A(Math.max(d.deadlineMs,this.timer.now()+f)),I=this.options.launchQueue??XL(),O=I.watchQueue(c.deviceId,{queued:T,admitted:()=>A(this.timer.now()+h),left:()=>A(this.timer.now()+h)});if(I.queueStatus(c.deviceId))T();return O}async ensureReadyWithTransitions(c,d){let h=0;while(!0){let f=Math.max(0,it(d)-this.timer.now());try{await l(()=>c.ensureReady({...d,readinessTimeoutMs:Math.min(f,d.readinessTimeoutMs)}),{timer:this.timer,signal:d.signal,...d.deadline?{deadline:d.deadline}:{timeoutMs:f},label:"Observer hierarchy service start"});return}catch(P){await this.awaitSetupTransition(P,d,h),h++}}}async awaitSetupTransition(c,d,h){if(!(c instanceof He)||!this.guard.awaitTransition||h>=Kn||d.signal?.aborted||this.timer.now()>=it(d))throw c;let f;try{f=await this.awaitTransition(d.device,it(d),d.signal)}catch(P){throw e.debug("[observe] Assignment transition wait ended before setup retry",P),c}if(!f||d.signal?.aborted||this.timer.now()>=it(d))throw c}}function it(c){return c.deadline?.deadlineMs??c.totalDeadlineMs}var zn=new WeakMap;function Yn(c){let d=zn.get(c);if(!d)d=new jn({timer:c}),zn.set(c,d);return d}var Fi=15000,Lc=ai(100);function Wc(c,d,h){let f=d[zo];return{...Tz(c.convertToViewHierarchyResult(d.hierarchy)),...f==="device"||f==="client-cache"?{[zo]:f}:{},receivedAt:h.now(),fresh:!0,...d.frameContext!==void 0?{frameContext:d.frameContext}:{}}}async function no(c,d,h){let f={},P=[new B,d.searchRaw===!0,d.signal],{timeoutMs:C}=h,A;if(d.observerMode){if(!c.requestHierarchySyncForObserver)throw new t("Observer hierarchy read is unavailable for this client");A=await c.requestHierarchySyncForObserver(...P,{timeoutMs:C,...d.displayId!==void 0&&d.displayId!==0?{diagnostics:f}:{},display:d.preserveDisplayState?{displayId:d.displayId,preserveDisplayState:!0}:d.displayId})}else A=await c.requestHierarchySync(...P,{timeoutMs:C,diagnostics:f,displayId:d.displayId});if(!A)Gc(d,h,f);return A}function Gc(c,d,h){if(c.displayId!==void 0&&c.displayId!==0&&h.runnerError?.includes("exposes no accessibility windows"))throw new Yv(h.runnerError);let f=h.failureReason??(h.runnerError?`runner error: ${h.runnerError}`:void 0),P=!c.observerMode||d.owned?`Device ${d.deviceId} hierarchy service did not answer`:`Device ${d.deviceId} has no reachable hierarchy service`;throw new t(f?`${P}: ${f}`:P)}function Jn(c,d,h=!1,f){let{adbFactory:P}=d,C=d.androidClients??k;if(c.platform==="ios")return h?_.createForObservationRead(c):_.getInstance(c);return h?C.createForObservationRead(c,P,f instanceof k?f:void 0):C.getInstance(c,P)}function qc(c,d,h){if(d.syncClientFactory)return{syncClient:d.syncClientFactory(c),transient:!1,owned:!1};let f=cr(c);if(!h)return{syncClient:f??Jn(c,d),transient:!1,owned:!1};let P=w.devicePool(),C=P?!!D(P.getDevice(c.deviceId)):!1;if(C&&!f?.isConnected())throw new t(`Device ${c.deviceId} is session-owned and has no connected hierarchy service: the owning session's hierarchy client is disconnected. Run a session observe as the owner to reconnect it; a deviceId read only connects to an already-running service.`);if(f?.isConnected())return{syncClient:f,transient:!1,owned:C};return{syncClient:Jn(c,d,!0,f),transient:!0,owned:!1}}function oo(c){let{device:d,dependencies:h,observerMode:f}=c;if(f&&h.observationClientResolver)return h.observationClientResolver(d);return qc(d,h,f)}async function Qn(c){let{connection:d,request:h,timer:f,deadline:P,device:C}=c;return await l(()=>d.syncClient.connectForObservationRead?.()??Promise.resolve(!1),{timer:f,timeoutMs:Math.max(0,P-f.now()),signal:h.signal,label:`Observer hierarchy connection for ${C.deviceId}`})}async function Kc(c){let{connection:d,request:h,timer:f,deadline:P,device:C,dependencies:A}=c;if(!d.transient||await Qn(c))return!1;await d.syncClient.close?.(),d.transient=!1;let T;try{T=await(A.observationServiceStart??Yn(f)).start({device:C,deadlineMs:P,signal:h.signal})}catch(I){throw h.signal?.throwIfAborted(),new t(`Device ${C.deviceId} has no reachable hierarchy service; read tried to start the service: ${r(I)}`,{cause:I})}if(Object.assign(d,oo({device:C,dependencies:A,observerMode:!0})),d.transient&&!await Qn(c))throw new t(`Device ${C.deviceId} has no reachable hierarchy service; read started the service but could not connect`);return T}function eo(c,d,h){let f=c.convertToViewHierarchyResult(d.hierarchy),P=d.hierarchy?.updatedAt;if(typeof P==="number"&&Number.isFinite(P))f.updatedAt=P;if(f.receivedAt=h.now(),f.fresh=!0,d.frameContext!==void 0)f.frameContext=d.frameContext;return f}async function zc(c){let{device:d,dependencies:h,syncClient:f,deadline:P,request:C,timer:A,owned:T}=c,I=c.synced;if(d.platform==="ios")return Wc(f,I,A);let O=eo(f,I,A);if(C.observerMode||!O.ctrlProxyIncomplete||A.now()>=P)return O;let x=Lc.delayForAttempt(1);if(P-A.now()>x)try{I=await l(async()=>{await A.sleep(x),C.signal?.throwIfAborted();let H=P-A.now();if(H<=0)throw new t(`Device ${d.deviceId} hierarchy retry deadline exhausted`);return no(f,C,{timeoutMs:H,deviceId:d.deviceId,owned:T})},{timer:A,timeoutMs:P-A.now(),signal:C.signal,label:`Device ${d.deviceId} incomplete hierarchy retry`}),O=eo(f,I,A)}catch(H){C.signal?.throwIfAborted(),e.warn("[HierarchyCapture] Incomplete CtrlProxy hierarchy retry failed",H)}if(!O.ctrlProxyIncomplete||A.now()>=P)return O;let N=await oV(O,{adb:(h.adbFactory??v).create(d),timer:A,idGenerator:h.ids,deviceId:d.deviceId},P,C.signal);return Are(N,O.updatedAt),N}function jc(c,{device:d,request:h,owned:f}){let P=h.displayId;return!(h.observerMode&&f)&&d.platform==="android"&&P!==void 0&&P!==0&&c instanceof Yv&&c.message.includes(`Display ${P} exposes no accessibility windows`)?P:void 0}async function Yc(c,d){try{return await zc({...d,synced:await c()})}catch(h){let{device:f,dependencies:P,request:C,timer:A,deadline:T}=d;C.signal?.throwIfAborted();let I=jc(h,d);if(I===void 0)throw h;try{return await $n(I,{adb:(P.adbFactory??v).create(f),timer:A,idGenerator:P.ids,deviceId:f.deviceId},T,C.signal)}catch(O){throw C.signal?.throwIfAborted(),e.warn("[HierarchyCapture] Untracked-display UIAutomator fallback failed",O),h}}}function pn(c,d={}){if(c.platform==="watchos"||c.platform==="tvos"||c.platform==="visionos"){let P=async(C)=>c.platform==="visionos"?jA(await KA(c.deviceId,C.signal,async()=>(await jS(c.deviceId,C.signal)).hierarchy(C.signal,C.timeoutMs===void 0?void 0:{timeoutMs:C.timeoutMs}))):c.platform==="tvos"?im(await Ln.require(c.deviceId).hierarchy(C.signal)):YA(await yo.require(c.deviceId).hierarchy(C.signal));return new gg("ios",{readCached:P,readFresh:P,projectVisible:(C)=>C},d.timer,d.ids)}let h=Q(c.platform,"Observing the view hierarchy"),f=new or({getViewHierarchy:(P,C)=>(d.viewHierarchy??new Vi(c,d.adbFactory,null,{timer:d.timer})).getViewHierarchy(P,C),filterOffscreenNodes:RD},async(P)=>{let C=d.timer??i,A=P.timeoutMs??Fi,T=C.now()+A;P.signal?.throwIfAborted();let I=oo({device:c,dependencies:d,observerMode:P.observerMode===!0});try{let O=await Kc({device:c,dependencies:d,connection:I,request:P,timer:C,deadline:T}),{syncClient:x,owned:N}=I,H=T-C.now();if(H<=0)throw new t(`Device ${c.deviceId} hierarchy read timed out`);let V=()=>no(x,P,{timeoutMs:H,deviceId:c.deviceId,owned:N}),q=await Yc(()=>P.observerMode?l(V,{timer:C,timeoutMs:H,signal:P.signal,label:`Device ${c.deviceId} hierarchy read`}):V(),{device:c,dependencies:d,syncClient:x,deadline:T,timer:C,request:P,owned:N});if(!P.observerMode)return q;let K={...q};if(delete K.hierarchyServiceStarted,O)K.hierarchyServiceStarted=!0;return K}finally{if(I.transient)await I.syncClient.close?.()}},(P)=>hg(h,P,h==="ios"&&(c.displays?.panels.length??0)>1),d.settle);return new gg(h,f,d.timer,d.ids)}var Xc=[{kind:"runner-error",transient:!1,pattern:/runner error:/},{kind:"screen-off",transient:!1,pattern:/Screen is off while waiting for hierarchy response/},{kind:"capture-error",transient:!1,pattern:/Unable to capture hierarchy/},{kind:"timestamp-floor",transient:!1,pattern:/Hierarchy capture did not satisfy the device timestamp floor/},{kind:"connect-failed",transient:!0,pattern:/Failed to establish CtrlProxy WebSocket connection/},{kind:"socket-unavailable",transient:!0,pattern:/Unable to request hierarchy for Android display \d+: CtrlProxy WebSocket is unavailable/},{kind:"send-failed",transient:!0,pattern:/Unable to request hierarchy for Android display \d+: /},{kind:"socket-closed-before-wait",transient:!0,pattern:/CtrlProxy WebSocket closed or changed before hierarchy wait/},{kind:"socket-changed",transient:!0,pattern:/CtrlProxy WebSocket changed while waiting for hierarchy response/},{kind:"socket-disconnected",transient:!0,pattern:/CtrlProxy WebSocket disconnected while waiting for hierarchy response/},{kind:"timeout",transient:!0,pattern:/Timed out waiting for hierarchy response after \d+ms/},{kind:"timeout",transient:!0,pattern:/Device .+ hierarchy read timed out$/},{kind:"no-answer",transient:!0,pattern:/Hierarchy service did not answer the sync request$/},{kind:"no-answer",transient:!0,pattern:/[Hh]ierarchy service did not answer$/}];function ao(c,d){if(d.signal?.aborted)return{kind:"aborted",transient:!1};let h=r(c),f=Xc.find(({pattern:P})=>P.test(h));return f?{kind:f.kind,transient:f.transient}:{kind:"unknown",transient:!1}}class lr extends Vn{kind;attempts;transient=!0;constructor(c,d){super(`${c} (after ${d.attempts} attempts)`,{cause:d.cause});this.name="SelectedDisplayReadError",this.kind=d.kind,this.attempts=d.attempts}}var Jc=te({initialDelayMs:200,multiplier:2,maxDelayMs:1000});function Qc(c,d){return c.transient&&!d?.aborted}async function co(c){let{timer:d,signal:h}=c,f=c.backoff??Jc,P=c.maxAttempts??4,C=d.now()+c.budgetMs,A=0;while(!0){h?.throwIfAborted(),A++;try{return await c.read({number:A,timeoutMs:A===1?c.timeoutMs:C-d.now()})}catch(T){let I=c.classify(T),O={...I,attempts:A,exhausted:!1};if(!Qc(I,h))throw c.wrap(T,O);let x=f.delayForAttempt(A),N=()=>c.wrap(T,{...O,exhausted:!0});if(A>=P||C-d.now()<=x)throw N();if(e.warn(`[SelectedDisplayRead] Retrying ${I.kind}; attempt ${A+1}`,T),await l(()=>d.sleep(x),{timer:d,signal:h,label:"Selected display read backoff"}),h?.throwIfAborted(),c.assertFenceCurrent(),C-d.now()<=0)throw N()}}}class Ve extends t{constructor(c,d){super(u(c,`Failed to capture screenshot for device ${d}`).message,{cause:c})}}async function lo(c,d){let{request:h,panelKey:f,captureStart:P}=d;return(await co({...c.selectedDisplayRead,timer:c.timer,budgetMs:h.timeoutMs??Fi,timeoutMs:h.timeoutMs,signal:h.signal,read:(A)=>c.hierarchyCapture.capture(A.number===1?h:{...h,timeoutMs:A.timeoutMs}),classify:(A)=>ao(A,{signal:h.signal}),assertFenceCurrent:()=>{let A=c.deviceId;if(xe.revision(A)!==P.revision)throw Lm(P.identityRevision,xe.identityRevision(A),xe.currentObservedPanel(A)?.key)},wrap:(A,T)=>{let I=`Unable to read selected display "${f}": ${String(A)}`;return T.exhausted?new lr(I,{cause:A,kind:T.kind,attempts:T.attempts}):new Vn(I,{cause:A})}})).hierarchy}function uo(c,d,h){if(d instanceof Ve||d instanceof Vn)return!0;if(!(c==="android"&&h.display!==void 0&&h.display!=="active"))return!1;return d instanceof Yv||d instanceof _e||h.signal?.aborted===!0&&d===h.signal.reason}async function po(c,d){try{return(await c.capture(d)).hierarchy}catch(h){if(d.signal?.aborted||h instanceof Yv)throw h;let f=Ure(h),P=f?.message??r(h);return e.warn(`[ObserveScreen] Observer hierarchy unavailable: ${P}`,h),{hierarchy:{error:"Hierarchy service unavailable",unavailableReason:f?"runner_launch_queued":h instanceof Xh?"request_timed_out":"connection_lost",unavailableDetail:P},fresh:!1}}}class pr{d;constructor(c){this.d=c}captureSingleDisplayData(c){let{result:d,options:h,queryOptions:f,perf:P,skipWaitForFresh:C,minTimestamp:A,signal:T,skipBackStack:I,observerMode:O,preserveDisplayState:x,capturedHierarchy:N,requestedDisplayId:H,observedAndroid:V}=c;return this.d.collectAllData(d,{queryOptions:f,perf:P,skipWaitForFresh:C,minTimestamp:A,signal:T,skipBackStack:I,readOnly:O||x||h?.skipRecompositionTracking===!0,capturedHierarchy:N,readOptions:this.d.device().platform==="android"&&h?.requireFreshExtraction?{timeoutMs:h.timeoutMs,requireFreshExtraction:h.requireFreshExtraction}:h?.timeoutMs,displayId:H??V?.logicalId??0})}resolveSingleDisplayIntent(c){let d=cn(c);return{...d,options:c,androidDisplayCache:this.selectAndroidDisplayCache(d.observerMode||d.preserveDisplayState),displayRequest:c?.display??this.defaultDisplayRequest(),perf:c?.perf??new B,iosLockState:this.startIosLockStateProbe(d.signal)}}selectAndroidDisplayCache(c){return c?new fr(this.d.timer(),!0):this.d.observedAndroidDisplayCache()}defaultDisplayRequest(){return this.d.requestedDisplay()==="all"?void 0:this.d.requestedDisplay()}startIosLockStateProbe(c){return this.d.device().platform==="ios"&&W({deviceId:this.d.device().deviceId})==="simulator"?this.d.iosLockStateProbe().read(this.d.device().deviceId,c):void 0}async beginSingleDisplay(c){let{perf:d,skipWaitForFresh:h,minTimestamp:f,signal:P,preserveDisplayState:C}=c;e.debug(`Executing observe command (skipWaitForFresh=${h}, minTimestamp=${f})`);let A=this.d.timer().now();o(P);let T=this.d.createBaseResult(),I={revision:xe.revision(this.d.device().deviceId),identityRevision:xe.identityRevision(this.d.device().deviceId)},O=this.d.displayBinding().resolveTarget({result:T,displayRequest:c.displayRequest,androidDisplayCache:c.androidDisplayCache,signal:P}),x=O instanceof Promise?await O:O,{explicitlyRouted:N,requestedDisplayId:H}=x,V=C&&N&&H!==void 0&&H!==0,q=io().currentGeneration(this.d.device().deviceId);return d.serial("observe"),{...c,...x,result:T,startTime:A,captureStart:I,routedAggregateSecondary:V,cacheGeneration:q}}async failSingleDisplay(c,d){let{preserveDisplayState:h,observerMode:f,displayRequest:P,signal:C,iosLockState:A}=d;if(h){if(C?.throwIfAborted(),!f&&(P===void 0||P==="active"))return e.error("Critical error in aggregate active observation:",c),this.d.createCriticalFallback(c)}if(f||h)throw u(c,`Unable to observe device ${this.d.device().deviceId}`);if(uo(this.d.device().platform,c,{display:P,signal:C}))throw sk(c);let T=c instanceof Error?c.stack||c.message:String(c);e.error(`Critical error in observe command: ${T}`),be.cancelJob(this.d.device().deviceId),An().update(this.d.device().deviceId,void 0,`Observation failed: ${T}`);let I=this.d.createBaseResult();if(A)rt(I,await A);return this.d.createCriticalFallback(c,{fallback:I})}async captureSingleDisplay(c){let{options:d,result:h,perf:f,queryOptions:P,skipWaitForFresh:C,minTimestamp:A,signal:T}=c,I=this.startForegroundProbe(c),O=I.then((N)=>N?.packageName),x=await this.captureRequestedHierarchy(c);if(d?.hierarchyOnly)return await this.d.hierarchyCollector().collect(h,{queryOptions:P,perf:f,skipWaitForFresh:C,minTimestamp:A,signal:T,readOnly:!0,capturedHierarchy:x,readOptions:d.timeoutMs}),o(T),f.end(),{earlyResult:h,foregroundSnapshot:I,foregroundIdentity:O};return await this.captureSingleDisplayData({result:h,options:d,queryOptions:P,perf:f,skipWaitForFresh:C,minTimestamp:A,signal:T,skipBackStack:c.skipBackStack,observerMode:c.observerMode,preserveDisplayState:c.preserveDisplayState,capturedHierarchy:x,requestedDisplayId:c.requestedDisplayId,observedAndroid:c.observedAndroid}),{earlyResult:void 0,foregroundSnapshot:I,foregroundIdentity:O}}startForegroundProbe(c){let{options:d,signal:h,observerMode:f,routedAggregateSecondary:P,requestedDisplayId:C}=c;return!d?.hierarchyOnly&&this.d.device().platform==="android"&&(!f||P)?this.d.deviceStateCollector().collectForegroundSnapshot(h,{displayId:C}):Promise.resolve(null)}buildHierarchyCaptureRequest(c){let{options:d,observerMode:h,preserveDisplayState:f,minTimestamp:P,signal:C}=c;return{freshness:c.requestedDisplayId!==void 0&&d?.freshness==="cached-ok"?"fresh":d?.freshness??"fresh",observerMode:h,...f?{preserveDisplayState:!0}:{},minTimestamp:P>0?P:void 0,signal:C,timeoutMs:d?.timeoutMs,displayId:c.requestedDisplayId}}async captureRequestedHierarchy(c){let{options:d,observerMode:h,requestedDisplayId:f,requestedPanel:P,captureStart:C}=c,A=this.buildHierarchyCaptureRequest(c);if(h)return await po(this.d.hierarchyCapture(),A);if(f!==void 0)return await lo({selectedDisplayRead:this.d.selectedDisplayRead(),timer:this.d.timer(),hierarchyCapture:this.d.hierarchyCapture(),deviceId:this.d.device().deviceId},{request:A,panelKey:P?.key,captureStart:C});if((d?.freshness||d?.hierarchyOnly)&&!(this.d.device().platform==="android"&&d.requireFreshExtraction))try{return(await this.d.hierarchyCapture().capture(A)).hierarchy}catch(T){e.warn(`[ObserveScreen] Freshness capture failed; collecting hierarchy: ${T}`)}return}}function Zc(c){if(c.screenScale!==void 0)return!0;let d=c.hierarchy;if(d.type==="XCUIElementTypeApplication")return!0;if(d.elementType==="application")return!0;if(typeof d.bundleId==="string"&&!c.hierarchy.node)return!0;return!1}function el(c){if(c.density!==void 0)return!0;if(c.sdkInt!==void 0)return!0;if(c.foregroundActivity!==void 0)return!0;let d=c.hierarchy.node,h=d&&Se(d).class;if(typeof h==="string"&&h.startsWith("android."))return!0;return!1}class mr{validate(c,d){let h=Zc(d),f=el(d);if(c==="android"&&h&&!f)return{valid:!1,error:"Platform mismatch detected: received iOS hierarchy for Android device. This may indicate a stale connection. Try calling observe again."};if(c==="ios"&&f&&!h)return{valid:!1,error:"Platform mismatch detected: received Android hierarchy for iOS device. This may indicate a stale connection. Try calling observe again."};return{valid:!0}}}function tl(c){c.updatedAt=0,c.viewHierarchy=void 0,c.elements=void 0,c.selectedElements=void 0,c.focusedElement=void 0,c.accessibilityFocusedElement=void 0,c.intentChooserDetected=void 0,c.notificationPermissionDetected=void 0,c.predictions=void 0,c.activeWindow=void 0,c.screenIdentity=void 0,c.screenSize={width:0,height:0},c.systemInsets={top:0,right:0,bottom:0,left:0},c.insets={available:!1,source:"unavailable",units:"unknown"},c.layoutWarnings=void 0,c.rotation=void 0,c.wakefulness=void 0}function mo(c,d,h,f){if(!c.viewHierarchy?.hierarchy)return!0;let P=f.validate(d,c.viewHierarchy);if(P.valid)return!0;return e.error(`[observe] Platform mismatch: device ${h} is ${d} but received hierarchy from other platform. Discarding stale data to prevent cross-platform contamination.`),tl(c),c.error=P.error,!1}var rl="androidx.car.app.activity.CarAppActivity",ho="com.google.android.apps.automotive.templates.host",kF=`${ho}:id/`;function il(c){return c["resource-id"]??c.$?.["resource-id"]}function ol(c){let d=[...yg(c)];for(let h=d.pop();h;h=d.pop()){let f=il(h);if(typeof f==="string"&&f.startsWith(kF))return!0;d.push(...Rl(h))}return!1}function EF(c){if(ol(c.viewHierarchy?.hierarchy?.node))return{kind:"carAppLibrary",hostPackage:ho};return c.activeWindow?.activityName===rl?{kind:"carAppLibrary"}:void 0}function fo(c){let d=c.automotive;if(!d)return;let h=EF(c);if(h)d.hostRenderedUi=h;else delete d.hostRenderedUi}class gr{d;constructor(c){this.d=c}async reconcileSingleDisplay(c,d){let{result:h,signal:f}=c,P=bo(h),C=await d.foregroundSnapshot,A,T=()=>(A??=this.d.isConfirmedFrameworkErrorDialog(h.viewHierarchy,f),A);if(await this.recoverInitialWindowMismatch(c,d,T))A=void 0;this.adoptSampledPrimaryActivity(c,C),this.attributeRoutedAggregateSecondary(c,C);let O=mo(h,Q(this.d.device().platform,"Observing the view hierarchy"),this.d.device().deviceId,this.d.platformValidator()),x=await this.resolvePostCaptureForeground(c);if(await this.verifyCachedHierarchyIfRequested(c,x),h.automotive&&bo(h)!==P)await this.d.deviceStateCollector().refreshAutomotiveForegroundActivity(h,f);else fo(h);let N=await this.bindFinalSingleDisplay(c);return this.attachOtherDisplays(h),{sampledForeground:C,postCaptureForeground:x,hierarchyPlatformValid:O,getConfirmedFrameworkErrorDialog:T,recordProvenance:N}}async recoverInitialWindowMismatch(c,d,h){let{options:f,result:P,startTime:C,minTimestamp:A,signal:T,skipBackStack:I}=c;if(!this.shouldRecoverWrongWindow(c))return!1;let O=await this.d.windowIdentity().resolveWindowIdentityMismatch(P,d.foregroundIdentity,{postCaptureForeground:{sampled:!1,identity:void 0,activityAttributionMismatch:!1},getConfirmedFrameworkErrorDialog:h,minTimestamp:A,signal:T}),x=Math.min(500,(f?.timeoutMs??Fi)-(this.d.timer().now()-C));if(!O||x<=0)return!1;return await this.d.staleRecovery().refreshKnownStaleHierarchy(P,O.foreground,f,{remainingMs:x,sideSamples:{skipBackStack:I,displayId:c.requestedDisplayId??c.observedAndroid?.logicalId??0}}),!0}shouldRecoverWrongWindow(c){let{options:d,observerMode:h,preserveDisplayState:f,explicitlyRouted:P}=c;return this.d.device().platform==="android"&&!h&&!f&&!P&&!d?.skipRecompositionTracking&&!d?.requireFreshExtraction&&!d?.skipStaleWindowRecovery}adoptSampledPrimaryActivity(c,d){let{result:h}=c;if(d===null||!an(c,d))return;if(d.packageName===h.viewHierarchy?.packageName&&d.activityName&&h.activeWindow)h.activeWindow={...h.activeWindow,appId:d.packageName,activityName:d.activityName}}attributeRoutedAggregateSecondary(c,d){if(!c.routedAggregateSecondary)return;let{result:h}=c,f=d?.packageName??h.viewHierarchy?.packageName;h.activeWindow=f?{appId:f,activityName:d?.activityName??"",layoutSeqSum:0}:void 0}async resolvePostCaptureForeground(c){let{result:d,signal:h,observerMode:f,preserveDisplayState:P,explicitlyRouted:C}=c;if(C)return{sampled:!1,identity:void 0,activityAttributionMismatch:!1,displayId:c.requestedDisplayId};if(f)return{sampled:!1,identity:void 0,activityAttributionMismatch:!1};return await this.d.reconcileActiveWindowAttribution(d,{signal:h,readOnly:P})}async verifyCachedHierarchyIfRequested(c,d){let{options:h,result:f,signal:P,startTime:C,skipBackStack:A}=c;if(!h?.verifyCachedHierarchy||d.activityAttributionMismatch)return;await this.d.staleRecovery().verifyCachedAndroidHierarchy(f,{signal:P,remainingMs:Math.min(500,(h.timeoutMs??Fi)-(this.d.timer().now()-C)),eligible:!c.observerMode&&!c.preserveDisplayState&&!c.explicitlyRouted,sideSamples:{skipBackStack:A,displayId:c.requestedDisplayId??c.observedAndroid?.logicalId??0}})}async bindFinalSingleDisplay(c){let d=this.d.displayBinding().bindFinalDisplay({result:c.result,displayRequest:c.displayRequest,androidDisplayCache:c.androidDisplayCache,observedAndroid:c.observedAndroid,requestedPanel:c.requestedPanel,requestedDisplayId:c.requestedDisplayId,explicitlyRouted:c.explicitlyRouted,preserveDisplayState:c.preserveDisplayState,observerMode:c.observerMode,recordProvenance:c.captureStart,signal:c.signal});return(d instanceof Promise?await d:d).recordProvenance}attachOtherDisplays(c){let d=this.d.device().displays?.panels;if(d&&d.length>1)c.otherDisplays=d.filter((h)=>h.key!==c.display.key).map((h)=>sl(h))}}function sl(c){if(c.scale&&c.scale>0)return{key:c.key,role:c.role,size:{width:Math.round(c.sizePx.width/c.scale),height:Math.round(c.sizePx.height/c.scale)},units:"points"};return{key:c.key,role:c.role,size:c.sizePx,units:"physical-pixels"}}function bo(c){return`${c.activeWindow?.appId??""}/${c.activeWindow?.activityName??""}`}import{AsyncLocalStorage as al}from"async_hooks";var vr=new al;function om(c){return vr.run(new WeakSet,c)}function So(c){if(c.viewHierarchy)vr.getStore()?.add(c.viewHierarchy);return c}function sm(c){return vr.getStore()?.has(c)??!1}function wo(c){return c?.[zo]==="device"}var ll=5000,dl=1000,ul=30000;function Ro(){return $e(g.OBSERVE_PERF_SNAPSHOT)}function Po(){let c=wu(g.OBSERVE_PERF_WINDOW_MS);if(c===void 0)return ll;return Math.min(ul,Math.max(dl,Math.round(c)))}async function Co(c,d,h){if(!Ro())return;let f=c.activeWindow?.appId;if(!f){e.debug("[PerfSnapshot] Skipping snapshot, no active app");return}let P=d.platform;if(!dr(P)){e.debug(`[PerfSnapshot] Skipping snapshot, no perf sampling on ${P}`);return}try{let{getPerformanceMonitor:C,getLastStartupTimingMs:A}=await import("./chunk-n1zmpk0z.js");C().requestPerfWindow(d.deviceId,f,P);let I=VW().snapshot(d.deviceId,h.now(),Po());I.startup=A(d.deviceId,f),c.perfSnapshot=I}catch(C){e.warn(`[PerfSnapshot] Failed to attach performance snapshot: ${C}`)}}class br{d;constructor(c){this.d=c}enrichSingleDisplayElements(c){let{result:d}=c;if(this.d.stampScreenSizeUnits(d),d.layoutWarnings={scope:"full",warnings:this.d.safeAreaAuditor().inspect(d)},d.viewHierarchy)d.elements=this.d.elementsBuilder().build(d.viewHierarchy,Q(this.d.device().platform,"Observing the view hierarchy"))}async enrichSingleDisplay(c){this.enrichSingleDisplayElements({result:c.result}),await this.attachScreenRound(c),await this.startSingleDisplayScreenshot(c),await this.runSingleDisplayAudits(c)}async attachScreenRound(c){if(this.d.device().formFactor!=="watch")return;let d=await this.d.screenRound().isScreenRound(c.signal);if(d!==void 0)c.result.isScreenRound=d}async startSingleDisplayScreenshot(c){let{options:d,result:h,perf:f,signal:P,screenshotMode:C,requestedDisplayId:A}=c;if(C==="none"){h.screenshotCaptureAttempted=!1;return}let T=A,I=wr(d?.screenshotOptions);if(h.screenshotCaptureAttempted=!0,Rr(h,I),C==="settled")h.screenshotOrientation=this.d.platformTraits().settledScreenshotOrientation(),await this.d.captureSettledScreenshot(h,f,P,{strict:d?.screenshot==="settled",displayId:T,screenshotOptions:d?.screenshotOptions});else if(M.getAccessibilityAuditConfig())await this.d.screenshotRecorder().capture(h.observationId,{perf:f,signal:P,displayId:T,capture:I});else this.d.screenshotRecorder().start(h.observationId,{perf:f,signal:P,displayId:T,capture:I})}async runSingleDisplayAudits(c){let{options:d,result:h,perf:f,signal:P,observerMode:C}=c;if(!d?.skipRecompositionTracking&&!C)await this.d.processRecomposition(h,f);if(!d?.skipPerformanceAudit&&!C)await this.d.performanceAuditor().run(h,f);if(!d?.skipAccessibilityAudit&&!C)await this.d.accessibilityAuditor().run(h,f);if(!C)await this.d.accessibilityStateDetector().run(h,f,P);if(!C)await this.attachPredictionsIfEnabled(h)}async attachPredictionsIfEnabled(c){if(!M.isPredictiveUiEnabled())return;try{let d=await this.d.predictiveUIState().generate(c,this.d.device());this.attachPredictions(c,d)}catch(d){e.warn(`[PredictiveUIState] Failed to generate predictions: ${d}`)}}async publishSingleDisplay(c){let{result:d,perf:h,startTime:f,skipBackStack:P,observerMode:C}=c;if(h.end(),!C)await Co(d,this.d.device(),this.d.timer());if(fn(d,h),d.screenshotPath)d.screenshotExpiresAt=await this.d.pathProtection().protect(d.screenshotPath);if(this.d.device().platform==="android"&&!C&&P)this.d.deferredBackStackDisplays().set(d,c.requestedDisplayId??c.observedAndroid?.logicalId??0);return e.debug("Observe command completed"),e.debug(`Total observe command execution took ${this.d.timer().now()-f}ms`),this.d.platformTraits().grantsObservationRead(d)?So(d):d}attachPredictions(c,d){if(d)c.predictions=d}}function wr(c){return c?.hidePrototypes===!0?{hidePrototypes:!0}:void 0}function Rr(c,d){if(d)c.screenshotIncludesPrototype=!1;else delete c.screenshotIncludesPrototype}function se(c,d){if(!c.errors){if(c.errors=[],c.error)c.errors.push({phase:"critical",message:c.error})}c.errors.push(d),c.error=c.errors.map((h)=>h.message).join("; ")}function Kd(c,d){let h=Number.isInteger(c)&&c>=0&&c<=3;if(!d)return h?c:void 0;let f=[d.width,d.height].every((A)=>Number.isFinite(A)&&A>0),P=d.width<d.height;if(h&&!(f&&P&&(c===1||c===3)))return c;return f?P?0:1:void 0}var de=new Set(["com.android.systemui"]),Oo="com.android.systemui",ml=3;function Ao(c){return c.packageName===Oo||c.type===ml}function hl(c,d){let h=c.bounds;if(!h)return!1;let f=h.bottom-h.top;if(d&&d>0)return f>d/2;return f>400}function Do(c){let d=c?.windows;if(!d||d.length===0)return"none";let h=d.find((P)=>P.isFocused===!0);if(h)return Ao(h)?"focused":"none";let f=d.reduce((P,C)=>(C.windowLayer??0)>(P.windowLayer??0)?C:P);return Ao(f)&&hl(f,c?.screenHeight)?"topmost-suspect":"none"}function Pr(c){let d=c.split("/")[1]??"";return d.startsWith("android.widget.")||d.startsWith("android.view.")||d.endsWith("DecorView")}function Le(c){let d=c?.foregroundActivity;return typeof d==="string"&&!Pr(d)}function xo(c,d){if(d===void 0)return!0;if(!Le(c))return!1;let[h,f=""]=(c.foregroundActivity??"").split("/"),P=f.startsWith(".")?h+f:f;return d.appId===h&&d.activityName===P}function fl(c,d){return c===d||c.startsWith(`${d}.`)}function Me(c){let d=c.viewHierarchy?.packageName,h=c.backStack;if(!d||h?.source!=="adb")return;let f=h.currentActivity?.name;if(!f)return;if(fl(f,d))return{packageName:d,activityName:f};let P=h.currentActivity?.taskId;return h.tasks.some((A)=>A.id===P&&A.packageName===d)===!0?{packageName:d,activityName:f}:void 0}function Ar(c,d,h){return!Le(c.viewHierarchy)||d.activityName!==h.activityName}function Gd(c){return c?.hierarchy!==void 0&&typeof c.hierarchy==="object"&&c.hierarchy!==null&&!("error"in c.hierarchy)}class Tr{dependencies;constructor(c){this.dependencies=c}get viewHierarchy(){return this.dependencies.viewHierarchy()}get deviceStateCollector(){return this.dependencies.deviceStateCollector()}get device(){return this.dependencies.device()}get platformValidator(){return this.dependencies.platformValidator()}get hierarchyPlatform(){return Q(this.device.platform,"Observing the view hierarchy")}get resolveObservationTimestampMs(){return this.dependencies.resolveObservationTimestampMs}get extractScreenSizeFromHierarchy(){return this.dependencies.extractScreenSizeFromHierarchy}async reconcileActiveWindowAttribution(c,d={}){let{signal:h,readOnly:f=!1}=d;if(await this.applyFocusedSystemUiOverlay(c,h))return{sampled:!1,identity:void 0,activityAttributionMismatch:!1};let P=c.activeWindow,C=c.viewHierarchy?.packageName;if(C===void 0||P===void 0||de.has(C))return{sampled:!1,identity:void 0,activityAttributionMismatch:!1};let A=Me(c);if(A){let I=await this.reconcileAgainstBackStack(c,P,A,{signal:h,readOnly:f});if(I)return I}if(P.appId===C)return{sampled:!1,identity:void 0,activityAttributionMismatch:!1};let T=await this.deviceStateCollector.collectForegroundIdentity(h);if(T===C)c.activeWindow={...P,appId:C,activityName:""};return{sampled:!0,identity:T,activityAttributionMismatch:!1}}async reconcileAgainstBackStack(c,d,h,f={}){let{signal:P,readOnly:C=!1}=f,A=!Le(c.viewHierarchy);if(!Ar(c,d,h))return;if(!await this.recaptureHierarchyForBackStackAttribution(c,h,P)){if(A&&d.activityName!=="")c.activeWindow={...d,activityName:""};return{sampled:!1,identity:void 0,activityAttributionMismatch:!0}}let I=await this.refreshRecaptureSideSamples(c,d,h,{bootstrapAttribution:A,signal:P,readOnly:C});if(c.activeWindow=I,await this.applyFocusedSystemUiOverlay(c,P,!0))return{sampled:!1,identity:void 0,activityAttributionMismatch:!1};let O={...I,appId:h.packageName,activityName:h.activityName};if(c.notificationPermissionDetected)O.type="notification_permission_dialog";else delete O.type;return c.activeWindow=O,{sampled:!1,identity:void 0,activityAttributionMismatch:!1}}async applyFocusedSystemUiOverlay(c,d,h=!1){if(this.device.platform!=="android")return!1;let f=c.activeWindow;if(f===void 0)return!1;let P=Do(c.viewHierarchy);if(P==="none")return!1;if(P==="focused")return this.mirrorFocusedSystemUiOverlay(c,f),!0;return this.applyFallbackSystemUiOverlay(c,f,h,d)}async applyFallbackSystemUiOverlay(c,d,h,f){if(h)return this.confirmFallbackOverlayFocus(c,d,f);return this.resolveFallbackOverlayWithRecapture(c,d,f)}async confirmFallbackOverlayFocus(c,d,h){if(!await this.deviceStateCollector.collectFocusedSystemUiSurface(h))return!1;return this.mirrorFocusedSystemUiOverlay(c,d),!0}async resolveFallbackOverlayWithRecapture(c,d,h,f=1){if(!await this.recaptureHierarchyForSystemUiOverlay(c,h))return this.confirmFallbackOverlayFocus(c,d,h);let P=c.activeWindow??d,C=Do(c.viewHierarchy);if(C==="none")return!1;if(C==="focused")return this.mirrorFocusedSystemUiOverlay(c,P),!0;if(await this.deviceStateCollector.collectFocusedSystemUiSurface(h))return this.mirrorFocusedSystemUiOverlay(c,P),!0;if(f>0)return this.resolveFallbackOverlayWithRecapture(c,P,h,f-1);return!1}mirrorFocusedSystemUiOverlay(c,d){let h={...d,appId:Oo,activityName:"",systemOverlay:!0};delete h.type,c.activeWindow=h}async recaptureHierarchyForSystemUiOverlay(c,d){let h=this.resolveObservationTimestampMs(c);if(h===void 0)return e.debug("[OBSERVE] Skipping SystemUI-overlay recapture without a device capture timestamp"),!1;let f=h+1,P;try{P=await this.viewHierarchy.getViewHierarchy(void 0,{skipWaitForFresh:!0,minTimestamp:f,signal:d})}catch(C){return e.debug(`[OBSERVE] SystemUI-overlay recapture failed; preserving original hierarchy: ${C}`),!1}if(!P||!Gd(P)||P.fresh!==!0||!this.platformValidator.validate(this.hierarchyPlatform,P).valid)return!1;return this.applyRecapturedHierarchy(c,P),delete c.deviceLock,delete c.deviceLockUnknown,await this.deviceStateCollector.collectDeviceLock(c,d),delete c.backStack,this.recorrelateActiveWindowToRecapture(c,P),!0}recorrelateActiveWindowToRecapture(c,d){if(c.activeWindow===void 0)return;let h=this.deriveActiveWindowFromHierarchy(d);if(h===void 0)return;if(c.notificationPermissionDetected)h.type="notification_permission_dialog";c.activeWindow=h}deriveActiveWindowFromHierarchy(c){let d=c.packageName??c.foregroundActivity?.split("/")[0];if(!d)return;return{appId:d,activityName:"",layoutSeqSum:0}}async recaptureHierarchyForBackStackAttribution(c,d,h){let f=this.resolveObservationTimestampMs(c);if(f===void 0)return e.debug("[OBSERVE] Skipping back-stack recapture without a device capture timestamp"),!1;let P=f+1,C;try{C=await this.viewHierarchy.getViewHierarchy(void 0,{skipWaitForFresh:!0,minTimestamp:P,signal:h})}catch(I){return e.debug(`[OBSERVE] Attribution recapture failed; preserving original hierarchy: ${I}`),!1}if(!this.isUsableAttributionRecapture(C,d))return!1;let A={...c,backStack:void 0,errors:void 0};await this.deviceStateCollector.collectBackStack(A,new B,h);let T=Me(A);if(!this.matchesExpectedBackStackAttribution(T,d)){for(let I of A.errors??[])se(c,I);return!1}return this.applyRecapturedHierarchy(c,C),c.backStack=A.backStack,!0}async refreshRecaptureSideSamples(c,d,h,{bootstrapAttribution:f,...P}){let{signal:C,readOnly:A=!1}=P;delete c.deviceLock,delete c.deviceLockUnknown;let[T]=await Promise.all([f?this.refreshBootstrapLayoutSeqSum(c,d,h,{readOnly:A}):Promise.resolve(d),this.deviceStateCollector.collectDeviceLock(c,C)]);return T}async refreshBootstrapLayoutSeqSum(c,d,h,f={}){let{readOnly:P=!1}=f,C={...c,activeWindow:void 0,errors:void 0};await this.deviceStateCollector.collectActiveWindow(C,P);for(let O of C.errors??[])se(c,O);let A=C.activeWindow;if(!A?.layoutSeqSum)return d;let T=A.activityName.startsWith(".")?A.appId+A.activityName:A.activityName;return A.appId===h.packageName&&T===h.activityName?{...d,layoutSeqSum:A.layoutSeqSum}:d}isUsableAttributionRecapture(c,d){if(!c)return!1;return Gd(c)&&c.fresh===!0&&c.packageName===d.packageName&&this.platformValidator.validate(this.hierarchyPlatform,c).valid}matchesExpectedBackStackAttribution(c,d){return c?.packageName===d.packageName&&c.activityName===d.activityName}applyRecapturedHierarchy(c,d){if(c.viewHierarchy=d,c.updatedAt=d.updatedAt??c.updatedAt,d.screenWidth&&d.screenHeight)c.screenSize={width:d.screenWidth,height:d.screenHeight};if(this.device.platform==="ios")c.screenSize=this.extractScreenSizeFromHierarchy(d)??c.screenSize,c.rotation=Kd(d.rotation,c.screenSize);else c.rotation=d.rotation;if(c.systemInsets=d.systemInsets??{top:0,right:0,bottom:0,left:0},c.insets=d.insets??{available:!1,source:"unavailable",units:"unknown"},c.wakefulness=d.wakefulness??c.wakefulness,d.wakefulness)c.wakefulnessSource="hierarchy";c.intentChooserDetected=d.intentChooserDetected,c.notificationPermissionDetected=d.notificationPermissionDetected,c.focusedElement=this.viewHierarchy.findFocusedElement(d)??void 0,c.accessibilityFocusedElement=this.viewHierarchy.findAccessibilityFocusedElement(d)??void 0}}function yl(c,d){let h=c?.packageName;return d!==void 0&&!de.has(d)&&(h===void 0?c?.ctrlProxyIncomplete===!0:de.has(h))}function gl(c,d,h,f){return de.has(d)||de.has(h)||f&&jC(c)}function nt(c){let d=c.systemInsets.top,h=c.viewHierarchy?.hierarchy.node;if(d<=0||!h)return!1;let f=!1,P=Array.isArray(h)?[...h]:[h];while(P.length>0){let C=P.pop();if(!C)continue;if(C.bounds){if(f=!0,C.bounds.bottom>d)return!1}let A=C.node;if(A)P.push(...Array.isArray(A)?A:[A])}return f}function vl(c,d){return{foreground:d,ctrlProxyIncomplete:c?.ctrlProxyIncomplete===!0,sdkInt:c?.sdkInt,accessibilityTool:c?.accessibilityTool}}class Ir{dependencies;constructor(c){this.dependencies=c}get deviceStateCollector(){return this.dependencies.deviceStateCollector()}get timer(){return this.dependencies.timer()}get resolveObservationTimestampMs(){return this.dependencies.resolveObservationTimestampMs}async resolveWindowIdentityMismatch(c,d,{postCaptureForeground:h,getConfirmedFrameworkErrorDialog:f,minTimestamp:P,signal:C}){let A=await d,T=c.viewHierarchy?.packageName??c.activeWindow?.appId;if(!A||!T)return;if(gl(c.viewHierarchy,T,A,this.isOwnWindowEvidenceCurrent(c,P)))return;let I=await this.resolvePostCaptureForegroundIdentity(A,T,h,C);if(!I||I!==A||I===T)return;if(await f())return;return{observed:T,foreground:A}}isOwnWindowEvidenceCurrent(c,d){let h=this.resolveObservationTimestampMs(c);if(h===void 0||d>0&&h<d)return!1;let f=this.resolveHostReceivedAtMs(c)??h;return this.timer.now()-f<=Dv()}async attributeFocusedOwnWindowToForeground(c,d,h){let f=c.activeWindow;if(f?.appId!==pt||!jC(c.viewHierarchy)||!this.isOwnWindowEvidenceCurrent(c,h))return;let P=await d;if(!P||P===pt||de.has(P))return;c.activeWindow={...f,appId:P,type:f.type??KW}}async resolveStatusBarOnlyHierarchy(c,d,h,f){let P=await d,C=c.viewHierarchy,A=nt(c);if(!yl(C,P)&&!A)return;if(P===void 0||de.has(P))return;let T=A?await this.confirmForegroundIdentity(h,f):await this.resolvePostCaptureForegroundIdentity(P,C?.packageName??"",h,f);if(!T||de.has(T)||!nt(c))return;return vl(C,T)}async confirmForegroundIdentity(c,d){if(c.sampled)return c.identity;return this.deviceStateCollector.collectForegroundIdentity(d,{displayId:c.displayId})}async resolvePostCaptureForegroundIdentity(c,d,h,f){if(h.sampled)return h.identity;if(c===d)return;return this.deviceStateCollector.collectForegroundIdentity(f,{displayId:h.displayId})}resolveHostReceivedAtMs(c){let d=c.viewHierarchy?.receivedAt;if(typeof d==="number"&&!Number.isNaN(d))return d;return}}function Dr(c,d={}){let h,f=new Map;for(let C of c.split(`
|
|
7
|
-
`)){let A=C.match(/^\s*Display:\s*mDisplayId=(\d+)/);if(A){h=parseInt(A[1],10);continue}let T=C.trim(),O=T.match(/^mRotation=(\d+)/)??(T.startsWith("mDisplayFrozen=")?T.match(/\bmRotation=(\d+)\b/):null);if(!O)continue;let x=parseInt(O[1],10);if(!f.has(h))f.set(h,x)}let P=h===void 0?void 0:d.displayId??0;return f.get(P)??null}function Mo(c,d={}){let h,f=new Map,P=new Set;for(let C of c.split(`
|
|
8
|
-
`)){let A=C.match(/^\s*Display:\s*mDisplayId=(\d+)/);if(A){h=Number(A[1]);continue}if(h===void 0||P.has(h))continue;let T=C.match(/\bmDisplayRotation=(?:ROTATION_(0|90|180|270)\b|\S+)/);if(T){if(T[1]!==void 0)f.set(h,Number(T[1])/90);P.add(h)}}return f.get(d.displayId??0)??null}var bl="shell dumpsys window displays",wl='shell dumpsys window | grep -i "mRotation="',Pl=5000,Fo=oe;function Cl(c,d){return Mo(c,d)??Dr(c,d)}async function Yd(c,d={}){let h=d.timeoutMs??Pl,f=(d.displayId??0)===0,P="display 0 rotation is missing",C;try{let{stdout:T}=await c.executeCommand(bl,{timeoutMs:h,maxBuffer:Fo,signal:d.signal}),I=Cl(T,d);if(I!==null||!f)return I}catch(T){if(d.signal?.aborted||T instanceof Error&&T.name==="AbortError"||!f)throw T;P="the displays subcommand failed",C=T}o(d.signal),e.debug(`[readWindowManagerRotation] Falling back to legacy WindowManager rotation: ${P}`,C);let{stdout:A}=await c.executeCommand(wl,{timeoutMs:h,maxBuffer:Fo,signal:d.signal});return Dr(A)}var tC="sdk-capture-identity",rC="web-snapshot-id";function Al(c,d){if(c===tC||c===rC)return;if(c!==""&&typeof d==="object"&&d!==null&&"resource-id"in d){let h=d["resource-id"];if(typeof h==="string"&&Az.has(h))return}return d}function Tl(c){let d=new WeakMap;return(h)=>{if(!h?.hierarchy)return null;let f=d.get(h);if(f!==void 0)return f;let P=null;try{P=c(JSON.stringify(h.hierarchy,Al))}catch(C){e.warn(`[hierarchyFingerprint] Failed to fingerprint view hierarchy: ${r(C)}`)}return d.set(h,P),P}}var mn=Tl((c)=>bc.generateCacheKey(c)),IF=(c,d)=>{let h=mn(c),f=mn(d);if(h===null||f===null)return null;return h!==f};function ct(c){let d=0;for(let h of c?.windows??[]){let f=h.prototypeMotion?.active;if(typeof f==="number"&&Number.isFinite(f)&&f>0)d+=f}return d}var JA=["com.google.android.apps.nexuslauncher","com.android.launcher3","com.sec.android.app.launcher","com.huawei.android.launcher","com.miui.home","com.android.launcher","com.samsung.android.app.launcher","com.oneplus.launcher"];var Il="shell cmd package resolve-activity --brief -c android.intent.category.HOME -a android.intent.action.MAIN",No=5000,kl=new Set(JA),Dl=30000,Ol=2000,lt=new Map;function xl(c){let d=c.split(`
|
|
9
|
-
`).map((P)=>P.trim()).filter((P)=>P.length>0),h=d[d.length-1];if(!h)return null;let f=h.match(/^([^\s/]+)\//);return f?f[1]:null}function El(c,d,h){if(c===void 0||c.incarnationToken!==h)return;let f=h===void 0?Ol:Dl;return d-c.resolvedAtMs<f?c.packageName:void 0}async function $4(c,d,h=i,{incarnationToken:f,signal:P,timeoutMs:C}={}){let A=pe(P);o(A);let T=h.now(),I=lt.get(d),O=El(I,T,f);if(O!==void 0)return O;let x=C===void 0?No:Math.max(1,Math.min(No,C));try{let N=await c.executeCommand(Il,{timeoutMs:x,noRetry:!0,signal:A}),H=xl(N.stdout);if(H)lt.set(d,{packageName:H,resolvedAtMs:h.now(),incarnationToken:f});return H}catch(N){if(A?.aborted)throw N;return e.warn(`[androidLauncherPackages] Failed to resolve configured HOME launcher package: ${r(N)}`,N),null}}function yQ(c){if(c===void 0)lt.clear();else lt.delete(c)}function Ml(c){if(!c)return!1;return kl.has(c)}async function Zy(c,d,h,{timer:f=i,...P}={}){if(!c)return!1;let{incarnationToken:C,signal:A,timeoutMs:T}=P,I=await $4(d,h,f,{incarnationToken:C,signal:A,timeoutMs:T});if(P.formFactor==="automotive"&&c==="com.android.car.mapsplaceholder")return!0;if(I)return c===I;return Ml(c)}class Or{device;adbFactory;timer;reader;lastUpdatedAt;constructor(c,d,h,f){this.device=c;this.adbFactory=d;this.timer=h;this.reader=f}async wait(c,d){let h=this.timer.now()+Math.max(0,c),f=null;while(this.timer.now()<h&&!d?.aborted){let P=h-this.timer.now();try{let C=await this.readFingerprint(P,d);if(C!==null&&C===f)return;f=C}catch(C){if(f=null,d?.aborted||this.timer.now()>=h){e.debug(`Quiet-tree stability read ended: ${r(C)}`);return}e.warn(`Quiet-tree stability read failed: ${r(C)}`)}if(d?.aborted)return;await this.timer.sleep(Math.min(17,Math.max(0,h-this.timer.now())))}}async readFingerprint(c,d){let h=new AbortController,f=d?AbortSignal.any([d,h.signal]):h.signal,P=this.reader??=new Vi(this.device,this.adbFactory,null,{timer:this.timer}),C=await l(()=>P.getViewHierarchy(void 0,{timeoutMs:c,requireFreshExtraction:!0,skipWaitForFresh:!0,...this.lastUpdatedAt===void 0?{}:{minTimestamp:this.lastUpdatedAt+1},signal:f}),{timer:this.timer,timeoutMs:c,signal:d,label:"Quiet-tree stability read",onTimeout:()=>h.abort()});if(!C.hierarchy.error)this.lastUpdatedAt=On(C)??this.lastUpdatedAt;if(ct(C)>0)return null;return C.fresh===!0&&!C.hierarchy.error?mn(C):null}async metrics(c,d,h,f){return await this.wait(d+h-this.timer.now(),f),{packageName:c,percentile50thMs:null,percentile90thMs:null,percentile95thMs:null,percentile99thMs:null,missedVsyncCount:null,slowUiThreadCount:null,frameDeadlineMissedCount:null,pollCount:0,stabilityWaitMs:this.timer.now()-d,isStable:!0}}}var _F=1000,vQ=5000;class XA{adb;timer;quietTree;testHooks={isSystemLauncher:(c)=>this.isSystemLauncher(c)};constructor(c,d=v,h=i,f){this.adb=d.create(c),this.timer=h,this.quietTree=new Or(c,d,h,f)}isSystemLauncher(c){if(!c)return!1;let d=["com.android.systemui",...JA];return c==="android"||d.some((h)=>c===h||c.startsWith(`${h}.`))}async waitForQuietTreeStability(c,d,h,f){if(!this.isSystemLauncher(c))return null;return this.quietTree.metrics(c,d,h,f)}getTouchStatus(c,d,h,f){let P=this.timer.now()-c,C=this.timer.now()-d,A=C>=h,T=!A&&P<f;return{isIdle:A,shouldContinue:T,currentElapsed:P,idleTime:C}}async getRotationStatus(c,d,h,{perf:f=new B,signal:P}={}){try{let C=await f.track("adbDumpsysWindowRotation",()=>{P?.throwIfAborted();let A=d+h-this.timer.now();return Yd(this.adb,{signal:P,timeoutMs:Math.max(A,_F)})});if(C!==null){if(e.debug(`Current rotation: ${C}, target: ${c}`),C===c)return e.debug(`Rotation to ${c} complete, took ${this.timer.now()-d}ms`),{rotationComplete:!0,currentRotation:C,shouldContinue:!1};return{rotationComplete:!1,currentRotation:C,shouldContinue:this.timer.now()-d<h}}return{rotationComplete:!1,currentRotation:null,shouldContinue:this.timer.now()-d<h}}catch(C){return P?.throwIfAborted(),e.debug(`Rotation idle check failed, treating as not-yet-idle: ${C}`),{rotationComplete:!1,currentRotation:null,shouldContinue:this.timer.now()-d<h}}}async getUiStabilitySnapshot(c,d=200,h=new B){e.info(`[AwaitIdle] Measuring UI idle for ${c} with ${d}ms delay`);try{return await h.track("adbGfxinfoReset",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)} reset`,{maxBuffer:oe})),await this.timer.sleep(d),await this.getUiStability(c,{missedVsync:null,slowUiThread:null,frameDeadlineMissed:null,totalFrames:null},!1,{perf:h})}catch(f){return e.info(`[Idle] Error measuring UI idle: ${f}`),{isStable:!1,shouldUpdateLastNonIdleTime:!0,updatedPrevMissedVsync:null,updatedPrevSlowUiThread:null,updatedPrevFrameDeadlineMissed:null,updatedPrevTotalFrames:null,updatedFirstGfxInfoLog:!1}}}async getFrameStats(c,d,h=new B,f={}){try{let{stdout:P}=await h.track("adbGfxinfo",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)}`,{timeoutMs:f.timeoutMs,maxBuffer:oe,signal:f.signal}));if(d)e.info(`[AwaitIdle] Initial gfxinfo stdout for ${c}:
|
|
10
|
-
${P}`);return P}catch(P){return f.signal?.throwIfAborted(),e.info(`[AwaitIdle] Failed to get gfxinfo for ${c}: ${P}`),null}}parseMetrics(c){let d=this.extractMetric(c,/50th percentile:\s+(\d+(?:\.\d+)?)ms/),h=this.extractMetric(c,/90th percentile:\s+(\d+(?:\.\d+)?)ms/),f=this.extractMetric(c,/95th percentile:\s+(\d+(?:\.\d+)?)ms/),P=this.extractMetric(c,/99th percentile:\s+(\d+(?:\.\d+)?)ms/),C=this.extractMetric(c,/Total frames rendered:\s+(\d+)/),A=this.extractMetric(c,/Number Missed Vsync:\s+(\d+)/),T=this.extractMetric(c,/Number Slow UI thread:\s+(\d+)/),I=this.extractMetric(c,/Number Frame deadline missed:\s+(\d+)/);return e.debug(`Metrics: 50th=${d}ms 90th=${h}ms 95th=${f}ms 99th=${P}ms TotalFrames=${C} MissedVsync=${A} SlowUI=${T} DeadlineMissed=${I}`),{percentile50th:d,percentile90th:h,percentile95th:f,percentile99th:P,totalFrames:C,missedVsync:A,slowUiThread:T,frameDeadlineMissed:I}}validateFrameData(c){return c.percentile50th!==null&&c.missedVsync!==null&&c.slowUiThread!==null}updateStabilityState(c,d){let{missedVsync:h,slowUiThread:f,frameDeadlineMissed:P,totalFrames:C}=c,A=this.calculateDeltas(c,d);return{updatedPrevMissedVsync:h,updatedPrevSlowUiThread:f,updatedPrevFrameDeadlineMissed:P,updatedPrevTotalFrames:C,deltas:A}}processFrameStatsForStability(c,d,h,{prevFrameDeadlineMissed:f,prevTotalFrames:P}){let C=this.parseMetrics(c);if(!this.validateFrameData(C))return e.info(`[AwaitIdle] No valid frame data yet: percentile50th ${C.percentile50th} && missedVsync ${C.missedVsync} && slowUiThread ${C.slowUiThread}`),{isStable:!1,noFrameData:!0,shouldUpdateLastNonIdleTime:!0,updatedPrevMissedVsync:d,updatedPrevSlowUiThread:h,updatedPrevFrameDeadlineMissed:f,updatedPrevTotalFrames:P};let A=this.updateStabilityState({missedVsync:C.missedVsync,slowUiThread:C.slowUiThread,frameDeadlineMissed:C.frameDeadlineMissed,totalFrames:C.totalFrames},{missedVsync:d,slowUiThread:h,frameDeadlineMissed:f,totalFrames:P}),T=this.checkStabilityCriteria(A.deltas,{percentile50th:C.percentile50th,percentile90th:C.percentile90th,percentile95th:C.percentile95th},C.totalFrames);return{isStable:T,shouldUpdateLastNonIdleTime:!T,updatedPrevMissedVsync:A.updatedPrevMissedVsync,updatedPrevSlowUiThread:A.updatedPrevSlowUiThread,updatedPrevFrameDeadlineMissed:A.updatedPrevFrameDeadlineMissed,updatedPrevTotalFrames:A.updatedPrevTotalFrames}}calculateDeltas(c,d){let h=d.missedVsync!==null&&c.missedVsync!==null?c.missedVsync-d.missedVsync:0,f=d.slowUiThread!==null&&c.slowUiThread!==null?c.slowUiThread-d.slowUiThread:0,P=d.frameDeadlineMissed!==null&&c.frameDeadlineMissed!==null?c.frameDeadlineMissed-d.frameDeadlineMissed:0,C=d.totalFrames!==null&&c.totalFrames!==null?c.totalFrames>=d.totalFrames?c.totalFrames-d.totalFrames:null:null;return e.debug(`Deltas: MissedVsync=${h} SlowUI=${f} DeadlineMissed=${P} TotalFrames=${C}`),{missedVsyncDelta:h,slowUiThreadDelta:f,frameDeadlineMissedDelta:P,totalFramesDelta:C}}checkStabilityCriteria(c,d,h){let{p50Int:f,p90Int:P,p95Int:C,shouldCheckPercentiles:A,percentilesOk:T}=this.assessPercentiles(c.totalFramesDelta,d,h),I=c.missedVsyncDelta===0&&c.slowUiThreadDelta===0&&c.frameDeadlineMissedDelta===0&&T;if(I)e.info("[AwaitIdle] UI appears stable (criteria met)");else{let O=A?`percentiles (50th=${f}, 90th=${P}, 95th=${C})`:`percentiles skipped (frames=${h??"n/a"}, delta=${c.totalFramesDelta??"n/a"})`;e.info(`[AwaitIdle] UI not stable: deltas (Vsync=${c.missedVsyncDelta}, UI=${c.slowUiThreadDelta}, Deadline=${c.frameDeadlineMissedDelta}, Frames=${c.totalFramesDelta??"n/a"}), ${O}`)}return I}assessPercentiles(c,d,h){let f=d.percentile50th!==null?Math.floor(d.percentile50th):0,P=d.percentile90th!==null?Math.floor(d.percentile90th):0,C=d.percentile95th!==null?Math.floor(d.percentile95th):0,A=5,T=c!==null&&c>0,I=h!==null&&h>=5,O=c===null||T&&I,x=!O||f<100&&P<100&&C<200;return{p50Int:f,p90Int:P,p95Int:C,shouldCheckPercentiles:O,percentilesOk:x}}async getUiStability(c,d,h,{perf:f=new B,...P}={}){let{missedVsync:C,slowUiThread:A,frameDeadlineMissed:T,totalFrames:I}=d;try{if(this.isSystemLauncher(c))return await this.quietTree.wait(P.timeoutMs??1000,P.signal),{isStable:!0,shouldUpdateLastNonIdleTime:!1,updatedPrevMissedVsync:null,updatedPrevSlowUiThread:null,updatedPrevFrameDeadlineMissed:null,updatedPrevTotalFrames:null,updatedFirstGfxInfoLog:!1};let O=await this.getFrameStats(c,h,f,P);if(O===null)return{isStable:!1,frameStatsUnavailable:!0,shouldUpdateLastNonIdleTime:!0,updatedPrevMissedVsync:C,updatedPrevSlowUiThread:A,updatedPrevFrameDeadlineMissed:T,updatedPrevTotalFrames:I,updatedFirstGfxInfoLog:!1};if(O.trim()==="")return e.info(`[AwaitIdle] No gfxinfo data for ${c}, treating as stable`),{isStable:!0,shouldUpdateLastNonIdleTime:!1,updatedPrevMissedVsync:null,updatedPrevSlowUiThread:null,updatedPrevFrameDeadlineMissed:null,updatedPrevTotalFrames:null,updatedFirstGfxInfoLog:!1};let x=this.processFrameStatsForStability(O,C,A,{prevFrameDeadlineMissed:T,prevTotalFrames:I});return{isStable:x.isStable,...x.noFrameData?{noFrameData:!0}:{},shouldUpdateLastNonIdleTime:x.shouldUpdateLastNonIdleTime,updatedPrevMissedVsync:x.updatedPrevMissedVsync,updatedPrevSlowUiThread:x.updatedPrevSlowUiThread,updatedPrevFrameDeadlineMissed:x.updatedPrevFrameDeadlineMissed,updatedPrevTotalFrames:x.updatedPrevTotalFrames,updatedFirstGfxInfoLog:!1}}catch(O){return P.signal?.throwIfAborted(),e.info(`[AwaitIdle] Error checking frame stats: ${O}`),{isStable:!1,frameStatsUnavailable:!0,shouldUpdateLastNonIdleTime:!0,updatedPrevMissedVsync:C,updatedPrevSlowUiThread:A,updatedPrevFrameDeadlineMissed:T,updatedPrevTotalFrames:I,updatedFirstGfxInfoLog:!1}}}extractMetric(c,d){let h=c.match(d);if(h&&h[1]){let f=parseFloat(h[1]);return isNaN(f)?null:f}return null}}var Fl=750,_l=2000,dt=new Map;class Oe{timer;adb;deviceId;constructor(c,d=v,h=i){this.timer=h;this.adb=d.create(c),this.deviceId=c.deviceId}async detectRefreshRate(){let c=Ji(this.deviceId)??"unknown",d=`${this.deviceId}\x00${c}`,h=dt.get(d);if(h!==void 0)return h;let f=this.timer.now();try{let{stdout:P}=await this.probe("shell dumpsys display | grep mRefreshRate",f),C=P.match(/mRefreshRate[=:]\s*(\d+\.?\d*)/i);if(C&&C[1]){let N=Math.round(parseFloat(C[1]));return e.info(`Detected refresh rate: ${N}Hz`),dt.set(d,N),N}let{stdout:A}=await this.probe("shell dumpsys SurfaceFlinger | grep 'refresh-rate'",f),T=A.match(/refresh-rate[=:]\s*(\d+\.?\d*)/i);if(T&&T[1]){let N=Math.round(parseFloat(T[1]));return e.info(`Detected refresh rate from SurfaceFlinger: ${N}Hz`),dt.set(d,N),N}let{stdout:I}=await this.probe("shell dumpsys display | grep -A 5 'mBaseDisplayInfo'",f),O=I.match(/fps\s*[=:]\s*(\d+\.?\d*)|(\d+\.?\d*)\s*fps/i),x=O?.[1]??O?.[2];if(x){let N=Math.round(parseFloat(x));return e.info(`Detected refresh rate from display modes: ${N}Hz`),dt.set(d,N),N}return e.warn("Could not detect refresh rate, defaulting to 60Hz"),60}catch(P){return e.warn(`Error detecting refresh rate: ${P}; defaulting to 60Hz`,P),60}}async probe(c,d){let h=this.timer.now()-d,f=_l-h;if(f<=0)return{stdout:""};return this.adb.executeCommand(c,{timeoutMs:Math.min(Fl,f),maxBuffer:oe,noRetry:!0})}async getCapabilities(){let c=await this.detectRefreshRate(),d=1000/c;return{refreshRate:c,frameTimeMs:d}}static calculateDefaultThresholds(c){let{frameTimeMs:d,refreshRate:h}=c;return{frameTimeThresholdMs:d,p50ThresholdMs:d*0.9,p90ThresholdMs:d*1,p95ThresholdMs:d*1.2,p99ThresholdMs:d*1.5,jankCountThreshold:Math.ceil(h/12),cpuUsageThresholdPercent:80,touchLatencyThresholdMs:d*2}}}var xr={min:0.1,max:2,successMultiplier:1.1,failureMultiplier:0.9};function Ho(c,d,h){if(c.length===0)return null;let f=c.reduce((C,A)=>C+h(A),0);if(f===0)return null;return c.reduce((C,A)=>C+d(A)*h(A),0)/f}function Bo(c){if(c.length===0)return;let d=new Map,h=0,f=c[0];for(let P of c){let C=(d.get(P)??0)+1;if(d.set(P,C),C>h)h=C,f=P}return f}function Vo(c){if(c.length===0)return;let d=[...c].sort((f,P)=>f-P),h=Math.floor(d.length/2);return d.length%2===0?(d[h-1]+d[h])/2:d[h]}function nC(c,d){if(d===0)return c>0?1/0:1;return c/d}function aV(c,d=Date.now()){let h=new Date(d);return h.setDate(h.getDate()-c),h.toISOString()}var iC={thresholdHours:24,baselineDays:30},bQ=0.3;var Nl=10,Hl=100,Lo=125;function ut(c,d){return c!==null&&d!==null&&d>c}function Wo(c,d){return ut(c.totalFrames,d.totalFrames)||ut(c.missedVsync,d.missedVsync)||ut(c.slowUiThread,d.slowUiThread)||ut(c.frameDeadlineMissed,d.frameDeadlineMissed)}class Er{adb;device;idle;timer;inertTouchPointResolver;constructor(c,d=v,h=i,f){this.device=c,this.adb=d.create(c),this.idle=new XA(c,d),this.timer=h,this.inertTouchPointResolver=f}selectSafeTouchLocation(c,d,h){if(d)return e.debug(`[TouchLatency] Using caller-provided touch location: (${d.x}, ${d.y})`),d;if(h&&h.right>h.left&&h.bottom>h.top){let C=Math.floor((h.left+h.right)/2),A=Math.floor((h.top+h.bottom)/2);return e.debug(`[TouchLatency] Selected touch location from app window bounds ${JSON.stringify(h)}: (${C}, ${A})`),{x:C,y:A}}let f=Math.floor(c.width*0.5),P=Math.floor(c.height*0.12);return e.debug(`[TouchLatency] Selected safe touch location (no window bounds): (${f}, ${P})`),{x:f,y:P}}async injectTouch(c,d,h){await h.track("adbInputTap",()=>this.adb.executeCommand(`shell input tap ${c} ${d}`))}async measureFrameResponse(c,d,h,f){let P=this.timer.now();while(this.timer.now()-P<h){await this.timer.sleep(Nl);try{let{stdout:C}=await f.track("adbGfxinfoCheck",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)}`,{maxBuffer:oe})),A=this.idle.parseMetrics(C);if(Wo(d,A)){let T=this.timer.now()-P;return e.debug(`[TouchLatency] Frame activity detected after ${T}ms`),T}}catch(C){e.warn(`[TouchLatency] Error checking frame stats: ${C}`)}}return e.warn(`[TouchLatency] No frame activity detected within ${h}ms`),null}async takeSample(c,d,h,{perf:f,sampleIndex:P}){await f.track("adbGfxinfoReset",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)} reset`,{maxBuffer:oe})),await this.timer.sleep(Lo);let{stdout:C}=await f.track("adbGfxinfoBaselineFirst",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)}`,{maxBuffer:oe})),A=this.idle.parseMetrics(C);await this.timer.sleep(Lo);let{stdout:T}=await f.track("adbGfxinfoBaselineSecond",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)}`,{maxBuffer:oe})),I=this.idle.parseMetrics(T);if(Wo(A,I))return e.warn(`[TouchLatency] Sample ${P+1}: frame activity detected across two consecutive no-input snapshots - app is animating, skipping this sample`),{latencyMs:null,animating:!0,obstructed:!1,tapPoint:d};let O=d,x=I;if(this.inertTouchPointResolver){let H=await f.track("touchLatencyRevalidatePoint",()=>this.inertTouchPointResolver.resolveInertTouchPoint());if(!H)return e.warn(`[TouchLatency] Sample ${P+1}: no verified-inert touch point on a freshly captured hierarchy - aborting this sample instead of tapping a possibly-live control (issue #6228)`),{latencyMs:null,animating:!1,obstructed:!0,tapPoint:d};O=H;let{stdout:V}=await f.track("adbGfxinfoBaselinePostRevalidate",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)}`,{maxBuffer:oe}));x=this.idle.parseMetrics(V)}return await this.injectTouch(O.x,O.y,f),{latencyMs:await this.measureFrameResponse(c,x,h,f),animating:!1,obstructed:!1,tapPoint:O}}buildResult(c,d,h,{otherFailureCount:f,obstructedCount:P}){let C=h>0;if(d.length===0){let T=C&&f===0&&P===0,I=P>0&&f===0&&!C,O;if(T)O="App renders continuously (animating); touch latency cannot be isolated";else if(I)O="Touch point was no longer inert on a freshly captured hierarchy; aborted touch-latency measurement rather than tapping a possibly-live control";else O="No successful measurements - UI may be frozen or gfxinfo unavailable";return{latencyMs:0,touchCoordinates:c,success:!1,error:O,sampleCount:0,animating:T}}let A=Vo(d)??0;return e.info(`[TouchLatency] Measured latency: ${A}ms (from ${d.length} samples)`),{latencyMs:A,touchCoordinates:c,success:!0,sampleCount:d.length,...C?{animating:!0}:{}}}async measureLatency(c,d,h={},f=new B){let P=h.sampleCount||3,C=h.maxWaitMs||200;e.info(`[TouchLatency] Measuring touch latency for ${c} (${P} samples)`);let A=this.selectSafeTouchLocation(d,h.touchPoint,h.windowBounds),T=[],I=0,O=0,x=0,N=A;try{for(let H=0;H<P;H++){e.debug(`[TouchLatency] Taking sample ${H+1}/${P}`);let V=await this.takeSample(c,A,C,{perf:f,sampleIndex:H});if(V.animating)I++;else if(V.obstructed)x++;else if(V.latencyMs!==null)N=V.tapPoint,T.push(V.latencyMs),e.debug(`[TouchLatency] Sample ${H+1}: ${V.latencyMs}ms`);else O++,e.warn(`[TouchLatency] Sample ${H+1} timeout - no response within ${C}ms`);if(H<P-1)await this.timer.sleep(Hl)}return this.buildResult(N,T,I,{otherFailureCount:O,obstructedCount:x})}catch(H){return e.warn(`[TouchLatency] Failed to measure touch latency: ${r(H)}`,H),{latencyMs:0,touchCoordinates:A,success:!1,error:r(H),sampleCount:T.length}}}}function Uo(){return M.isUiPerfModeEnabled()&&vT()&&!$e(g.DISABLE_PERF_AUDIT)}function $o(){return $e(g.TOUCH_LATENCY_SAMPLING)}var Bl=1e4,Vl=24,Go=300000,Ll=xT(),Fe=null,Wl=500;class am{timer;db;constructor({db:c,timer:d=i}={}){this.timer=d,this.db=c??null}getDb(){if(this.db)return this.db;return ke()}async recordAudit(c){try{let d=this.getDb(),h={device_id:c.deviceId,session_id:c.sessionId,package_name:c.packageName,timestamp:c.timestamp,passed:c.passed?1:0,p50_ms:c.metrics.p50Ms,p90_ms:c.metrics.p90Ms,p95_ms:c.metrics.p95Ms,p99_ms:c.metrics.p99Ms,jank_count:c.metrics.jankCount,missed_vsync_count:c.metrics.missedVsyncCount,slow_ui_thread_count:c.metrics.slowUiThreadCount,frame_deadline_missed_count:c.metrics.frameDeadlineMissedCount,cpu_usage_percent:c.metrics.cpuUsagePercent,touch_latency_ms:c.metrics.touchLatencyMs,diagnostics_json:c.diagnostics,time_to_first_frame_ms:c.metrics.timeToFirstFrameMs??null,time_to_interactive_ms:c.metrics.timeToInteractiveMs??null,frame_rate_fps:c.metrics.frameRateFps??null,node_id:c.nodeId??null};await d.insertInto("performance_audit_results").values(h).execute(),await this.cleanupRetention()}catch(d){e.error(`[PerformanceAuditRepository] Failed to store audit result: ${d}`)}}async listResults(c){let d=this.getDb(),h=Math.max(1,c.limit??50),f=Math.max(0,c.offset??0),P=d.selectFrom("performance_audit_results").select(["id","device_id","session_id","package_name","timestamp","passed","p50_ms","p90_ms","p95_ms","p99_ms","jank_count","missed_vsync_count","slow_ui_thread_count","frame_deadline_missed_count","cpu_usage_percent","touch_latency_ms","diagnostics_json","time_to_first_frame_ms","time_to_interactive_ms","frame_rate_fps","node_id"]);if(c.deviceId)P=P.where("device_id","=",c.deviceId);if(c.startTime)P=P.where("timestamp",">=",c.startTime);if(c.endTime)P=P.where("timestamp","<=",c.endTime);let C=await P.orderBy("timestamp","desc").orderBy("id","desc").limit(h+1).offset(f).execute(),A=C.length>h;return{results:(A?C.slice(0,h):C).map((O)=>({id:O.id,deviceId:O.device_id,sessionId:O.session_id,packageName:O.package_name,timestamp:O.timestamp,passed:O.passed===1,metrics:{p50Ms:O.p50_ms,p90Ms:O.p90_ms,p95Ms:O.p95_ms,p99Ms:O.p99_ms,jankCount:O.jank_count,missedVsyncCount:O.missed_vsync_count,slowUiThreadCount:O.slow_ui_thread_count,frameDeadlineMissedCount:O.frame_deadline_missed_count,cpuUsagePercent:O.cpu_usage_percent,touchLatencyMs:O.touch_latency_ms,timeToFirstFrameMs:O.time_to_first_frame_ms,timeToInteractiveMs:O.time_to_interactive_ms,frameRateFps:O.frame_rate_fps},diagnostics:O.diagnostics_json,nodeId:O.node_id})),hasMore:A,nextOffset:A?f+h:null}}async listResultsSince(c){let d=this.getDb(),h=Math.min(Math.max(1,c.limit??50),Wl),f=d.selectFrom("performance_audit_results").select(["id","device_id","session_id","package_name","timestamp","passed","p50_ms","p90_ms","p95_ms","p99_ms","jank_count","missed_vsync_count","slow_ui_thread_count","frame_deadline_missed_count","cpu_usage_percent","touch_latency_ms","diagnostics_json","time_to_first_frame_ms","time_to_interactive_ms","frame_rate_fps","node_id"]);if(c.deviceId)f=f.where("device_id","=",c.deviceId);if(c.sessionId)f=f.where("session_id","=",c.sessionId);if(c.packageName)f=f.where("package_name","=",c.packageName);if(c.startTime)f=f.where("timestamp",">=",c.startTime);if(c.endTime)f=f.where("timestamp","<=",c.endTime);if(c.sinceTimestamp){let C=c.sinceTimestamp,A=c.sinceId??0;f=f.where((T)=>T.or([T("timestamp",">",C),T.and([T("timestamp","=",C),T("id",">",A)])]))}return(await f.orderBy("timestamp","asc").orderBy("id","asc").limit(h).execute()).map((C)=>({id:C.id,deviceId:C.device_id,sessionId:C.session_id,packageName:C.package_name,timestamp:C.timestamp,passed:C.passed===1,metrics:{p50Ms:C.p50_ms,p90Ms:C.p90_ms,p95Ms:C.p95_ms,p99Ms:C.p99_ms,jankCount:C.jank_count,missedVsyncCount:C.missed_vsync_count,slowUiThreadCount:C.slow_ui_thread_count,frameDeadlineMissedCount:C.frame_deadline_missed_count,cpuUsagePercent:C.cpu_usage_percent,touchLatencyMs:C.touch_latency_ms,timeToFirstFrameMs:C.time_to_first_frame_ms,timeToInteractiveMs:C.time_to_interactive_ms,frameRateFps:C.frame_rate_fps},diagnostics:C.diagnostics_json,nodeId:C.node_id}))}async cleanupRetention(){await iu(Ll,()=>this.pruneToRowCap())}async pruneToRowCap(c=Bl){try{await nu(this.getDb(),"performance_audit_results",c)}catch(d){e.warn(`[PerformanceAuditRepository] Retention cleanup failed: ${d}`)}}async pruneOldRecords(){try{let c=this.getDb(),h=new Date(this.timer.now()-Vl*60*60*1000).toISOString(),f=await c.deleteFrom("performance_audit_results").where("timestamp","<",h).executeTakeFirst(),P=Number(f.numDeletedRows??0);if(P>0)e.info(`[PerformanceAuditRepository] Pruned ${P} old records`);return P}catch(c){return e.warn(`[PerformanceAuditRepository] Pruning failed: ${c}`),0}}startPeriodicPruning(){if(Fe)return;Fe=i.setInterval(()=>{this.pruneOldRecords().catch((c)=>{e.warn(`[PerformanceAuditRepository] Periodic pruning error: ${c}`)})},Go),Fe.unref(),e.info(`[PerformanceAuditRepository] Started periodic pruning (every ${Go/1000}s)`)}stopPeriodicPruning(){if(Fe)i.clearInterval(Fe),Fe=null,e.info("[PerformanceAuditRepository] Stopped periodic pruning")}}function cV(c){if(c.length===0)return[];let d=[...c].sort((f,P)=>P.contributionWeight-f.contributionWeight),h=Math.min(0.5,d[0].contributionWeight);return d.filter((f)=>f.contributionWeight>=h)}var Ul=5000,$l=1048576;async function Mr(c){let d=c;if(typeof d.getAndroidApiLevel==="function"){let h=await d.getAndroidApiLevel();if(h!==null&&h>=29)return"ActivityTaskManager"}return"ActivityManager"}function Fr(c){let d=c.replace("+","").trim(),h=d.match(/^(\d+)s(\d+)ms$/);if(h)return Number.parseInt(h[1],10)*1000+Number.parseInt(h[2],10);let f=d.match(/^(\d+)ms$/);if(f)return Number.parseInt(f[1],10);let P=d.match(/^(\d+)s$/);if(P)return Number.parseInt(P[1],10)*1000;return null}function U4(c){let d=c.match(/^\s*(\d+\.\d+)\s+\d+\s+\d+\s+[VDIWEF]\s+(\w+):\s+(.*)$/);if(!d)return null;let h=Number.parseFloat(d[1]);if(Number.isNaN(h))return null;let f=d[2];if(f!=="ActivityManager"&&f!=="ActivityTaskManager")return null;return{timestampMs:Math.round(h*1000),logcatTag:f,message:d[3]}}function H4(c,d){let h=d==="Displayed"?/Displayed\s+(\S+?)(?:\s+for user \d+)?:/:/Fully drawn\s+(\S+?)(?:\s+for user \d+)?:/,f=c.match(h);return f?f[1]:null}function dV(c){let[d,h]=c.split("/"),f=h??"";if(f.startsWith("."))f=`${d}${f}`;return{packageName:d,activityName:f,componentName:c}}function q4(c){let d=c.match(/\+\s*\d+(?:s\d+ms|ms|s)/);if(!d)return null;return Fr(d[0])}class V4{adb;device;logcatTagCache;constructor(c,d=v){if(this.device=c,d&&typeof d.create==="function")this.adb=d.create(c);else if(d)this.adb=d;else this.adb=v.create(c)}async captureDisplayedMetrics(c,d=new B){if(this.device.platform!=="android")return e.info("[DisplayedTimeMetrics] Skipping - not Android platform"),[];let h=await this.getPreferredLogcatTag();e.info(`[DisplayedTimeMetrics] Using logcat tag: ${h}`);let f=this.buildLogcatCommand(h);e.info(`[DisplayedTimeMetrics] Logcat command: ${f}`);try{let{stdout:P}=await d.track("adbLogcatDisplayed",()=>this.adb.executeCommand(f,{timeoutMs:Ul,maxBuffer:$l}));e.info(`[DisplayedTimeMetrics] Logcat output length: ${P.length} chars`);let C=this.parseDisplayedMetrics(P,c);return e.info(`[DisplayedTimeMetrics] Parsed ${C.length} metrics for package ${c.packageName} (window: ${c.startTimestampMs} - ${c.endTimestampMs})`),C}catch(P){return e.warn(`[DisplayedTimeMetrics] Failed to read logcat: ${P}`),[]}}async getPreferredLogcatTag(){if(this.logcatTagCache)return this.logcatTagCache;return this.logcatTagCache=await Mr(this.adb),this.logcatTagCache}buildLogcatCommand(c){return`shell logcat -d -v epoch -s ${c}:I`}parseDisplayedMetrics(c,d){let h=[],f=c.split(`
|
|
11
|
-
`),P=f.filter((C)=>C.includes("Displayed"));if(e.info(`[DisplayedTimeMetrics] Found ${P.length} 'Displayed' lines in logcat`),P.length>0)e.info(`[DisplayedTimeMetrics] Last few Displayed lines: ${P.slice(-3).join(" | ")}`);for(let C of f){let A=U4(C);if(!A)continue;let{timestampMs:T,logcatTag:I,message:O}=A;if(T<d.startTimestampMs||T>d.endTimestampMs){if(O.includes("Displayed")&&O.includes(d.packageName))e.info(`[DisplayedTimeMetrics] Filtered by timestamp: logcatTs=${T}, window=[${d.startTimestampMs}, ${d.endTimestampMs}]`);continue}let x=H4(O,"Displayed");if(!x)continue;let N=dV(x);if(N.packageName!==d.packageName)continue;let H=q4(O);if(H===null)continue;e.info(`[DisplayedTimeMetrics] Found metric: ${N.componentName} = ${H}ms`),h.push({packageName:N.packageName,activityName:N.activityName,componentName:N.componentName,displayedTimeMs:H,timestampMs:T,logcatTag:I})}return h}}var _r=500;function qo(c,d){if(c.startTimeTicks!==d.startTimeTicks)return null;let h=d.processTicks-c.processTicks,f=d.uptimeSeconds-c.uptimeSeconds;if(!Number.isFinite(h)||!Number.isFinite(f))return null;if(h<0||f<=0)return null;return h/(f*100)*100}function mt(c,d){if(c===null||d===null)return null;return d>=c?d-c:d}function Gl(c,d,h){let f=mt(c.jankyFrames,d.jankyFrames);if(f!==null)return f;return h.length>0?Math.max(...h):null}function Ko(c,d,h){if(!(h>0))return null;let f=mt(c.missedVsync,d.missedVsync),P=mt(c.slowUiThread,d.slowUiThread),C=mt(c.frameDeadlineMissed,d.frameDeadlineMissed),A=[f,P,C].filter((O)=>O!==null),T=Gl(c,d,A);if(T===null)return null;let I=T*1000/h;return{jankPerSecond:Math.round(I*100)/100,missedVsync:f,slowUiThread:P,frameDeadlineMissed:C}}function jo(c){let d=c.match(/^[ \t]*Janky frames:[ \t]*(\d+)/m);return d?parseInt(d[1],10):null}function Yo(c){let d=c.lastIndexOf(")");if(d<0)return null;let h=c.slice(d+1).trim().split(/\s+/),f=parseInt(h[11]??"",10),P=parseInt(h[12]??"",10),C=parseInt(h[19]??"",10);if(![f,P,C].every(Number.isFinite))return null;return{processTicks:f+P,startTimeTicks:C}}var ql="No frames were rendered in the audit window, so there are no frame times to check.",Kl="gfxinfo reported no rendered-frame count, so its frame times cannot be checked.";function zl(c){if(!c.totalFrames)return{p50Ms:null,p90Ms:null,p95Ms:null,p99Ms:null,frameTimeUnmeasured:c.totalFrames===0?ql:Kl};return{p50Ms:c.percentile50th,p90Ms:c.percentile90th,p95Ms:c.percentile95th,p99Ms:c.percentile99th}}var jl=200,Yl=100,Ql=500,ed=5000;class Nr{adb;device;idle;capabilitiesDetector;touchLatencyTracker;repository=new am;timer;constructor(c,d=v,h,f=i){this.timer=f,this.device=c,this.adb=d.create(c),this.idle=new XA(c,d),this.capabilitiesDetector=new Oe(c,d),this.touchLatencyTracker=new Er(c,d,f,h)}async collectMetrics(c,d,h=new B,f){let P=f??{};e.info(`[PerformanceAudit] Collecting metrics for ${c}`);let[C,A,T,I]=await Promise.all([this.collectGfxMetrics(c,h),this.collectCpuMetrics(c,h),this.checkForAnr(c,h),this.calculateFrameRate(c,h)]),O=await this.measureTouchLatency(c,d,h,{windowBounds:P.windowBounds,touchPoint:P.touchPoint,skipTouchLatency:P.skipTouchLatency}),x=null,N=null;if(P.measureTtff)x=await this.measureTimeToFirstFrame(c,h);if(P.measureTti&&x!==null)N=await this.measureTimeToInteractive(c,x,h);return{...this.normalizeGfxMetrics(C),cpuUsagePercent:A.cpuUsagePercent??null,threadCount:A.threadCount??null,touchLatencyMs:O,anrDetected:T.anrDetected??!1,anrDetails:T.anrDetails??null,timeToFirstFrameMs:x,timeToInteractiveMs:N,frameRateFps:I,gfxinfoRaw:C.gfxinfoRaw??null,cpuStatsRaw:A.cpuStatsRaw??null}}normalizeGfxMetrics(c){return{p50Ms:c.p50Ms??null,p90Ms:c.p90Ms??null,p95Ms:c.p95Ms??null,p99Ms:c.p99Ms??null,...c.frameTimeUnmeasured!==void 0?{frameTimeUnmeasured:c.frameTimeUnmeasured}:{},jankCount:c.jankCount??null,missedVsyncCount:c.missedVsyncCount??null,slowUiThreadCount:c.slowUiThreadCount??null,frameDeadlineMissedCount:c.frameDeadlineMissedCount??null}}async readGfxSample(c,d){let{stdout:h}=await d.track("adbGfxinfo",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)}`,{maxBuffer:oe})),f=this.idle.parseMetrics(h);return{stdout:h,counters:{totalFrames:f.totalFrames,jankyFrames:jo(h),missedVsync:f.missedVsync,slowUiThread:f.slowUiThread,frameDeadlineMissed:f.frameDeadlineMissed}}}async collectGfxMetrics(c,d){try{let h=await this.readGfxSample(c,d),f=this.timer.now();await this.timer.sleep(_r);let P=await this.readGfxSample(c,d),C=this.timer.now()-f,A=this.idle.parseMetrics(P.stdout),T=Ko(h.counters,P.counters,C);return{...zl(A),jankCount:T?.jankPerSecond??null,missedVsyncCount:T?.missedVsync??null,slowUiThreadCount:T?.slowUiThread??null,frameDeadlineMissedCount:T?.frameDeadlineMissed??null,gfxinfoRaw:P.stdout}}catch(h){return e.warn(`[PerformanceAudit] Failed to collect gfx metrics: ${h}`),{p50Ms:null,p90Ms:null,p95Ms:null,p99Ms:null,jankCount:null,missedVsyncCount:null,slowUiThreadCount:null,frameDeadlineMissedCount:null,gfxinfoRaw:null}}}async readCpuSample(c,d){let{stdout:h}=await d.track("adbCpuStat",()=>this.adb.executeCommand(`shell cat /proc/${S(c)}/stat`)),{stdout:f}=await d.track("adbUptime",()=>this.adb.executeCommand("shell cat /proc/uptime")),P=Yo(h),C=parseFloat(f.trim().split(/\s+/)[0]||"");if(!P||!Number.isFinite(C)||C<=0)return null;return{sample:{...P,uptimeSeconds:C},statRaw:h}}async collectCpuMetrics(c,d){try{let{stdout:h}=await d.track("adbGetPid",()=>this.adb.executeCommand(`shell pidof ${S(c)}`)),f=h.trim().split(/\s+/)[0];if(!f)return e.warn(`[PerformanceAudit] No PID found for ${c}`),{cpuUsagePercent:null,threadCount:null,cpuStatsRaw:null};let{stdout:P}=await d.track("adbThreadCount",()=>this.adb.executeCommand(`shell ps -T -p ${S(f)} | wc -l`)),C=parseInt(P.trim(),10)-1,A=await this.readCpuSample(f,d);await this.timer.sleep(_r);let T=await this.readCpuSample(f,d);return{cpuUsagePercent:A&&T?qo(A.sample,T.sample):null,threadCount:C,cpuStatsRaw:(T??A)?.statRaw??null}}catch(h){return e.warn(`[PerformanceAudit] Failed to collect CPU metrics: ${h}`),{cpuUsagePercent:null,threadCount:null,cpuStatsRaw:null}}}async checkForAnr(c,d){try{let{stdout:h}=await d.track("adbCheckAnr",()=>this.adb.executeCommand(`shell dumpsys activity processes | grep -A 20 ${S(c)}`,{maxBuffer:oe})),f=h.toLowerCase().includes("anr")||h.toLowerCase().includes("not responding");return{anrDetected:f,anrDetails:f?h:null}}catch(h){return e.warn(`[PerformanceAudit] Failed to check for ANR: ${h}`),{anrDetected:!1,anrDetails:null}}}async measureTouchLatency(c,d,h,f={}){let{windowBounds:P,touchPoint:C,skipTouchLatency:A}=f;if(A)return e.info("[PerformanceAudit] Touch latency measurement skipped (no verified-inert touch point available)"),null;if(!M.isUiPerfModeEnabled()||!$o())return e.debug("[PerformanceAudit] Touch latency measurement skipped (sampling not enabled)"),null;if(!d)return e.warn("[PerformanceAudit] Touch latency measurement skipped (screen size not provided)"),null;try{e.info("[PerformanceAudit] Measuring touch latency with synthetic touches");let T=await h.track("touchLatencyMeasurement",()=>this.touchLatencyTracker.measureLatency(c,d,{sampleCount:3,maxWaitMs:jl,windowBounds:P,touchPoint:C},h));return this.resolveTouchLatency(T)}catch(T){return e.warn(`[PerformanceAudit] Failed to measure touch latency: ${T}`),null}}resolveTouchLatency(c){if(c.success){if(c.animating)e.warn(`[PerformanceAudit] Touch latency measured: ${c.latencyMs}ms (some samples were discounted as animating)`);else e.info(`[PerformanceAudit] Touch latency measured: ${c.latencyMs}ms`);return c.latencyMs}if(c.animating)e.warn("[PerformanceAudit] Touch latency measurement discarded: app is rendering frames on its own (animating) - latency cannot be attributed to the synthetic touch");else e.warn(`[PerformanceAudit] Touch latency measurement failed: ${c.error}`);return null}async calculateFrameRate(c,d){try{let{stdout:h}=await d.track("adbGfxinfoFrameRate",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)}`,{maxBuffer:oe})),f=h.match(/Total frames rendered:\s*(\d+)/);if(!f)return null;let P=parseInt(f[1],10);if(P===0)return null;let A=(await this.capabilitiesDetector.getCapabilities()).refreshRate||60,T=h.match(/Janky frames:\s*(\d+)/),I=T?parseInt(T[1],10):0,O=this.idle.parseMetrics(h);if(O.percentile50th&&O.percentile50th>0){let N=1000/O.percentile50th;return Math.min(N,A)}if(I>0&&P>0){let x=P-I,N=1000/A,H=x*N+I*N*2,V=P*1000/H;return Math.min(V,A)}return A}catch(h){return e.warn(`[PerformanceAudit] Failed to calculate frame rate: ${h}`),null}}async measureTimeToFirstFrame(c,d){try{let h=await Mr(this.adb),{stdout:f}=await d.track("adbLogcatTtff",()=>this.adb.executeCommand(`shell "logcat -d -s ${h}:I | grep -E 'Displayed.*'${S(c)} | tail -1"`));if(!f.trim())return e.debug("[PerformanceAudit] No TTFF data found in logcat"),null;let P=f.match(/\+\s*\d+(?:s\d+ms|ms|s)/);return P?Fr(P[0]):null}catch(h){return e.warn(`[PerformanceAudit] Failed to measure TTFF: ${h}`),null}}async measureTimeToInteractive(c,d,h){try{let f=Yl,P=Ql,C=ed,A=null,T=0;while(T<C){await h.track("adbGfxinfoTtiReset",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)} reset`,{maxBuffer:oe})),await i.sleep(f),T+=f;let{stdout:I}=await h.track("adbGfxinfoTtiAfter",()=>this.adb.executeCommand(`shell dumpsys gfxinfo ${S(c)}`,{maxBuffer:oe})),O=this.idle.parseMetrics(I);if((O.missedVsync||0)>0||(O.slowUiThread||0)>0||(O.frameDeadlineMissed||0)>0){A=null;continue}if(A===null){A=T;continue}if(T-A>=P)return e.info(`[PerformanceAudit] TTI reached: ${d+A}ms`),d+A}return e.warn(`[PerformanceAudit] TTI measurement timed out after ${C}ms`),null}catch(f){return e.warn(`[PerformanceAudit] Failed to measure TTI: ${f}`),null}}validateMetrics(c,d){let h=[];if(this.appendPercentileViolations(h,c,d),c.jankCount!==null&&c.jankCount>d.jankCountThreshold)h.push({metric:"jankCount",threshold:d.jankCountThreshold,actual:c.jankCount,severity:"critical",contributionWeight:0.9});if(c.cpuUsagePercent!==null&&c.cpuUsagePercent>d.cpuUsageThresholdPercent)h.push({metric:"cpuUsage",threshold:d.cpuUsageThresholdPercent,actual:c.cpuUsagePercent,severity:"warning",contributionWeight:0.5});if(c.touchLatencyMs!==null&&c.touchLatencyMs>d.touchLatencyThresholdMs)h.push({metric:"touchLatency",threshold:d.touchLatencyThresholdMs,actual:c.touchLatencyMs,severity:"critical",contributionWeight:0.85});if(c.anrDetected)h.push({metric:"anr",threshold:0,actual:1,severity:"critical",contributionWeight:1});return h}appendPercentileViolations(c,d,h){if(d.p50Ms!==null&&d.p50Ms>h.p50ThresholdMs)c.push({metric:"p50",threshold:h.p50ThresholdMs,actual:d.p50Ms,severity:"warning",contributionWeight:0.6});if(d.p90Ms!==null&&d.p90Ms>h.p90ThresholdMs)c.push({metric:"p90",threshold:h.p90ThresholdMs,actual:d.p90Ms,severity:"warning",contributionWeight:0.7});if(d.p95Ms!==null&&d.p95Ms>h.p95ThresholdMs)c.push({metric:"p95",threshold:h.p95ThresholdMs,actual:d.p95Ms,severity:"critical",contributionWeight:0.8});if(d.p99Ms!==null&&d.p99Ms>h.p99ThresholdMs)c.push({metric:"p99",threshold:h.p99ThresholdMs,actual:d.p99Ms,severity:"warning",contributionWeight:0.4})}generateDiagnostics(c,d){if(d.length===0)return"No performance issues detected";let h=`Performance issues detected:
|
|
12
|
-
|
|
13
|
-
`,f=cV(d);h+=`Top contributors:
|
|
14
|
-
`;for(let A of f)h+=`- ${A.metric}: ${A.actual.toFixed(2)} (threshold: ${A.threshold.toFixed(2)}) [${A.severity}]
|
|
15
|
-
`;if(h+=`
|
|
16
|
-
Diagnostic details:
|
|
17
|
-
`,f.some((A)=>["p50","p90","p95","p99","jankCount"].includes(A.metric))&&c.gfxinfoRaw)h+=`
|
|
18
|
-
--- GFXINFO DUMP ---
|
|
19
|
-
`,h+=c.gfxinfoRaw,h+=`
|
|
20
|
-
--- END GFXINFO ---
|
|
21
|
-
`;if(f.some((A)=>A.metric==="cpuUsage")&&c.cpuStatsRaw)h+=`
|
|
22
|
-
--- CPU STATS ---
|
|
23
|
-
`,h+=`Thread count: ${c.threadCount}
|
|
24
|
-
`,h+=`CPU usage: ${c.cpuUsagePercent?.toFixed(2)}%
|
|
25
|
-
`,h+=c.cpuStatsRaw,h+=`
|
|
26
|
-
--- END CPU STATS ---
|
|
27
|
-
`;if(c.anrDetected&&c.anrDetails)h+=`
|
|
28
|
-
--- ANR DETECTED ---
|
|
29
|
-
`,h+=c.anrDetails,h+=`
|
|
30
|
-
--- END ANR ---
|
|
31
|
-
`;return h}async runAudit(c,d,h={}){let{screenSize:f,perf:P=new B,windowBounds:C,touchPoint:A,skipTouchLatency:T}=h;e.info(`[PerformanceAudit] Running audit for ${c}`);let I=await this.capabilitiesDetector.getCapabilities(),O=await this.collectMetrics(c,f,P,{windowBounds:C,touchPoint:A,skipTouchLatency:T}),x=this.validateMetrics(O,d),N=x.length>0?this.generateDiagnostics(O,x):null,H=x.length===0,V=new Date().toISOString().split("T")[0];return await this.repository.recordAudit({deviceId:this.device.deviceId,sessionId:V,packageName:c,timestamp:new Date().toISOString(),passed:H,metrics:{p50Ms:O.p50Ms,p90Ms:O.p90Ms,p95Ms:O.p95Ms,p99Ms:O.p99Ms,jankCount:O.jankCount,missedVsyncCount:O.missedVsyncCount,slowUiThreadCount:O.slowUiThreadCount,frameDeadlineMissedCount:O.frameDeadlineMissedCount,cpuUsagePercent:O.cpuUsagePercent,touchLatencyMs:O.touchLatencyMs},diagnostics:N}),{passed:H,metrics:O,violations:x,diagnostics:N,deviceCapabilities:I}}}var Hr=m`datetime(created_at, '+' || ttl_hours || ' hours')`,Br=m`datetime('now')`;class Vr{table;constructor(c){this.table=m.table(c)}async deleteExpired(c,d){let h=await m`
|
|
32
|
-
delete from ${this.table}
|
|
33
|
-
where ${Hr} < ${Br}${this.andWhere(d)}
|
|
34
|
-
`.execute(c);return Number(h.numAffectedRows??0)}async selectValid(c,d){return(await m`
|
|
35
|
-
select * from ${this.table}
|
|
36
|
-
where ${Hr} >= ${Br}${this.andWhere(d)}
|
|
37
|
-
order by created_at desc
|
|
38
|
-
`.execute(c)).rows}async insert(c,d){let h=Object.entries(d),f=m.join(h.map(([C])=>m.ref(C))),P=m.join(h.map(([,C])=>m.val(C)));await m`insert into ${this.table} (${f}) values (${P})`.execute(c)}async adjustLatestWeight(c,d,h,f){let P=h?m`min(weight * ${f.successMultiplier}, ${f.max})`:m`max(weight * ${f.failureMultiplier}, ${f.min})`,C=await m`
|
|
39
|
-
update ${this.table}
|
|
40
|
-
set weight = ${P}
|
|
41
|
-
where id = (
|
|
42
|
-
select id from ${this.table}
|
|
43
|
-
where ${Hr} >= ${Br}${this.andWhere(d)}
|
|
44
|
-
order by created_at desc
|
|
45
|
-
limit 1
|
|
46
|
-
)
|
|
47
|
-
`.execute(c);return Number(C.numAffectedRows??0)}andWhere(c){return m.join(c.map((d)=>m` and ${m.ref(d.column)} = ${m.val(d.value)}`),m``)}}class xF{injectedDb;descriptor;repository;constructor(c,d){this.descriptor=c,this.repository=new Vr(c.tableName),this.injectedDb=d??null}get db(){return this.injectedDb??ke()}async cleanupExpiredThresholds(c,d,h=this.db){try{let f=await this.repository.deleteExpired(h,c);if(f>0)e.info(`[${this.descriptor.logPrefix}] Cleaned up ${f} expired thresholds for ${d}`)}catch(f){e.warn(`[${this.descriptor.logPrefix}] Failed to cleanup expired thresholds: ${f}`)}}async getValidThresholds(c,d,h,f=this.db){return await this.cleanupExpiredThresholds(d,h,f),await this.repository.selectValid(f,c)}calculateWeightedAverageThresholds(c){if(c.length===0)return null;let d={weight:xr.max/2,ttl_hours:iC.thresholdHours};for(let h of this.descriptor.modeColumns??[])d[h]=Bo(c.map((f)=>Number(f[h])))??60;for(let{column:h,round:f}of this.descriptor.weightedColumns){let P=Ho(c,(C)=>Number(C[h]),(C)=>C.weight);if(P===null)return null;d[h]=f?Math.round(P):P}return d}async storeThresholds(c,d,h=this.db){try{await this.repository.insert(h,c),e.info(`[${this.descriptor.logPrefix}] Stored new thresholds for ${d}`)}catch(f){throw e.error(`[${this.descriptor.logPrefix}] Failed to store thresholds: ${f}`),f}}async updateThresholdWeight(c,d,h){try{if(await this.cleanupExpiredThresholds(h.cleanupWhere??c,this.describeWhere(h.cleanupWhere??c)),await this.repository.adjustLatestWeight(this.db,c,d,xr)===0){e.warn(`[${this.descriptor.logPrefix}] ${h.missingMessage}`);return}e.debug(`[${this.descriptor.logPrefix}] ${h.updatedMessage}`)}catch(f){e.warn(`[${this.descriptor.logPrefix}] Failed to update threshold weight: ${f}`)}}describeWhere(c){return c.map((d)=>`${d.column} ${d.value}`).join(", ")}}var td={tableName:"performance_thresholds",logPrefix:"ThresholdManager",modeColumns:["refresh_rate"],weightedColumns:[{column:"frame_time_threshold_ms"},{column:"p50_threshold_ms"},{column:"p90_threshold_ms"},{column:"p95_threshold_ms"},{column:"p99_threshold_ms"},{column:"jank_count_threshold",round:!0},{column:"cpu_usage_threshold_percent"},{column:"touch_latency_threshold_ms"}]};class Lr{thresholds;constructor(c){this.thresholds=new xF(td,c)}get db(){return this.thresholds.db}getCurrentSessionId(){return new Date().toISOString().split("T")[0]}async cleanupExpiredThresholds(c){await this.cleanupExpiredThresholdsWith(this.db,c)}async cleanupExpiredThresholdsWith(c,d){await this.thresholds.cleanupExpiredThresholds(this.deviceWhere(d),`device ${d}`,c)}async getValidThresholds(c){return await this.getValidThresholdsWith(this.db,c)}async getValidThresholdsWith(c,d){return await this.thresholds.getValidThresholds(this.deviceWhere(d),this.deviceWhere(d),`device ${d}`,c)}calculateWeightedAverageThresholds(c){return this.thresholds.calculateWeightedAverageThresholds(c)}async getOrCreateThresholds(c,d){let h=this.db,f=async(A)=>{let T=await this.getValidThresholdsWith(A,c);if(T.length===0)return null;let I=this.calculateWeightedAverageThresholds(T);if(!I)return null;return e.info(`[ThresholdManager] Using weighted average of ${T.length} threshold entries for device ${c}`),{frameTimeThresholdMs:I.frame_time_threshold_ms,p50ThresholdMs:I.p50_threshold_ms,p90ThresholdMs:I.p90_threshold_ms,p95ThresholdMs:I.p95_threshold_ms,p99ThresholdMs:I.p99_threshold_ms,jankCountThreshold:I.jank_count_threshold,cpuUsageThresholdPercent:I.cpu_usage_threshold_percent,touchLatencyThresholdMs:I.touch_latency_threshold_ms}},P=async(A)=>{let T=await f(A);if(T)return T;e.info(`[ThresholdManager] Creating new thresholds for device ${c}`);let I=Oe.calculateDefaultThresholds(d);return await this.storeThresholdsWith(A,c,d,{thresholds:I}),I};if(h.isTransaction)return P(h);return await f(h)??h.transaction().execute(P)}async storeThresholds(c,d,h,{weight:f=1,ttlHours:P=24}={}){await this.storeThresholdsWith(this.db,c,d,{thresholds:h,weight:f,ttlHours:P})}async storeThresholdsWith(c,d,h,{thresholds:f,weight:P=1,ttlHours:C=24}){let A=this.getCurrentSessionId(),T={device_id:d,session_id:A,refresh_rate:h.refreshRate,frame_time_threshold_ms:f.frameTimeThresholdMs,p50_threshold_ms:f.p50ThresholdMs,p90_threshold_ms:f.p90ThresholdMs,p95_threshold_ms:f.p95ThresholdMs,p99_threshold_ms:f.p99ThresholdMs,jank_count_threshold:f.jankCountThreshold,cpu_usage_threshold_percent:f.cpuUsageThresholdPercent,touch_latency_threshold_ms:f.touchLatencyThresholdMs,weight:P,ttl_hours:C};await this.thresholds.storeThresholds(T,`device ${d} session ${A}`,c)}async updateThresholdWeight(c,d,h){await this.thresholds.updateThresholdWeight([...this.deviceWhere(c),{column:"session_id",value:d}],h,{missingMessage:`No threshold found for device ${c} session ${d}`,updatedMessage:`Updated threshold weight (${h?"passed":"failed"})`})}deviceWhere(c){return[{column:"device_id",value:c}]}}var KS="com.android.systemui",rd="proud-lock",Rh=300,nd=["NotificationCenter","NCNotification","NotificationList","NotificationShortLookView","NotificationLongLookView","PLPlatterView"],W4=["notification_panel","notification_stack","notification_stack_scroller","status_bar_expanded","quick_settings","quick_settings_panel","quick_settings_container","qs_panel","qs_frame","qs_header","shade_header","expanded_status_bar"],od=["NotificationPanel","NotificationShade","NotificationStack","QSPanel","QuickSettings","StatusBarExpanded"],ot=(c)=>{if(!c||typeof c!=="object")return null;return Se(c)},cm=(c,d)=>{if(!c)return!1;if(d(c))return!0;let h=c.node;if(Array.isArray(h)){for(let f of h)if(cm(f,d))return!0}else if(h&&typeof h==="object"){if(cm(h,d))return!0}return!1},sd=new we,Li=(c)=>{let d=new Set;return[...sd.project(c)].filter((h)=>h.parentIndex===void 0).sort((h,f)=>h.windowRank-f.windowRank||h.index-f.index).filter((h)=>{if(d.has(h.source))return!1;return d.add(h.source),!0}).map((h)=>h.source)},ad={notification_children_container:["com.android.systemui:id/notification_children_container"],notification_header:["android:id/notification_header","com.android.systemui:id/notification_header"],expand_button:["android:id/expand_button","android:id/expand_button_touch_container","com.android.systemui:id/expand_button"],status_bar_latest_event_content:["android:id/status_bar_latest_event_content"],notification_stack_scroller:["com.android.systemui:id/notification_stack_scroller"]},Bc=(c,d)=>ad[d].some((h)=>c===h),z4=(c)=>{let d=String(c.packageName??c.package??"");if(d)return d===KS;return ur(c).startsWith(`${KS}:id/`)},SQ=(c)=>{let d=ot(c);if(!d)return!1;let h=ur(d),f=String(d.className??d.class??"");if(!z4(d))return!1;let C=W4.some((T)=>h===`${KS}:id/${T}`||h===T),A=od.some((T)=>f.includes(T));return C||A},lV=(c)=>Li(c).some((d)=>cm(d,(h)=>ur(ot(h))===rd)),Xo=(c)=>{let d=ot(c);if(!d)return!1;return String(d.className??d.class??"")==="UIWindow"&&ur(d,["identifier"])==="SBCoverSheetWindow"&&cm(c,(h)=>{let f=ur(ot(h));return f==="combined-list-view"||f==="lockscreen-date-view"})},uV=(c)=>!lV(c)&&Li(c).some((d)=>cm(d,Xo)),wQ=(c)=>{let d=ot(c);if(!d)return!1;let h=String(d.className??d.class??""),f=$w(d,["content-desc","ios-accessibility-label"]),P=ur(d,["identifier"]);return Xo(c)||nd.some((C)=>h.includes(C)||f.includes(C)||P.includes(C))},j4=(c)=>ur(ot(c)),RQ=1500,PQ=150,pV=["title","title_big","conversation_text","notification_title"];class Wr{observeScreen;appId;enclosingUpdatedAt;constructor(c,d,h){this.observeScreen=c;this.appId=d;this.enclosingUpdatedAt=h}async resolveInertTouchPoint(){try{let c=C3(this.enclosingUpdatedAt)+1,d=await this.observeScreen.execute({perf:new B,skipWaitForFresh:!1,minTimestamp:c,skipScreenshot:!0,skipBackStack:!0,skipAccessibilityAudit:!0,skipPerformanceAudit:!0});if(C3(d.updatedAt)<c)return e.warn("[PerformanceAudit] Re-observation did not yield a hierarchy newer than the enclosing observation; aborting inert-point re-derivation rather than reusing a stale capture"),null;if(d.activeWindow?.appId!==this.appId)return e.warn(`[PerformanceAudit] Foreground changed from ${this.appId} to ${d.activeWindow?.appId??"none"} during audit; aborting inert-point re-derivation`),null;let h=We(d,this.appId),{touchPoint:f,skipTouchLatency:P}=Gr(h,d);if(P||!f)return null;return f}catch(c){return e.warn(`[PerformanceAudit] Failed to re-derive inert touch point: ${c}`),null}}}var cd=1,ld="notification_permission_dialog";function dd(c,d){if(!c.bounds||c.type!==cd)return!1;return c.packageName===void 0||c.packageName===d}function We(c,d){let h=c.viewHierarchy?.windows;if(!h||h.length===0)return;let f=h.filter((C)=>dd(C,d));return(f.find((C)=>C.isFocused)??f[0])?.bounds}var ud=[{x:0.5,y:0.5},{x:0.25,y:0.25},{x:0.75,y:0.25},{x:0.25,y:0.75},{x:0.75,y:0.75},{x:0.5,y:0.08},{x:0.5,y:0.92},{x:0.08,y:0.5},{x:0.92,y:0.5}],pd={x:0.5,y:0.95};function md(c){return st(c.clickable)||st(c.focusable)||st(c["long-clickable"])||Io(c.actions,"click")||Io(c.actions,"long_click")}function Jo(c,d,h){return c>=h.left&&c<h.right&&d>=h.top&&d<h.bottom}function hd(c){return Number.isFinite(c.left)&&Number.isFinite(c.top)&&Number.isFinite(c.right)&&Number.isFinite(c.bottom)&&c.right-c.left>0&&c.bottom-c.top>0}function fd(c,d,h=[]){let f=d.filter((T)=>T.bounds&&md(T)),P=c.right-c.left,C=c.bottom-c.top,A=(T)=>({x:Math.floor(c.left+P*T.x),y:Math.floor(c.top+C*T.y)});for(let T of ud){let I=A(T),O=f.some((N)=>Jo(I.x,I.y,N.bounds)),x=h.some((N)=>Jo(I.x,I.y,N));if(!O&&!x)return{point:I,inert:!0}}return e.warn("[PerformanceAudit] Could not find a fully inert touch point inside the app window (every scanned candidate overlapped an interactive element or content-hidden region) - falling back to a default point that may still activate a control"),{point:A(pd),inert:!1}}function yd(c,d=new G){if(!c.viewHierarchy)return c.elements?.clickable??[];return d.flattenViewHierarchy(c.viewHierarchy,{includeWindows:!0}).map((h)=>h.element)}function vd(c){return(c.viewHierarchy?.contentHiddenRegions??[]).map((d)=>d.bounds)}var bd=[(c)=>c?null:"no app window bounds were found",(c)=>c&&!hd(c)?"window bounds are malformed (zero-area, inverted, or non-finite): "+JSON.stringify(c):null,(c,d)=>d.viewHierarchy?.fresh===!1?"the view hierarchy is a stale cached snapshot (fresh: false), not verified against the device on this call":null,(c,d)=>d.viewHierarchy?.ctrlProxyIncomplete?"CtrlProxy reported an incomplete capture (ctrlProxyIncomplete) - the focused app's own root may have been withheld":null,(c,d)=>{let h=Cv(d.viewHierarchy?.truncationReasons);return h.length>0?`view hierarchy is truncated (${h.join(", ")}) - the obstacle map may be incomplete`:null},(c,d)=>d.activeWindow?.appId===KS?`a SystemUI overlay owns focus (activeWindow.appId === "${KS}") - the app window beneath it cannot be safely probed`:null,(c,d)=>d.notificationPermissionDetected||d.activeWindow?.type===ld?"a notification-permission dialog owns the window - the underlying app's bounds/gfxinfo don't correspond to the same surface":null];function Sd(c,d){for(let h of bd){let f=h(c,d);if(f!==null)return f}return null}function Gr(c,d,h=new G){let f=Sd(c,d);if(f!==null||!c){if(f!==null)e.warn(`[PerformanceAudit] Skipping touch-latency measurement: ${f}`);return{skipTouchLatency:!0}}let P=yd(d,h),C=vd(d),{point:A,inert:T}=fd(c,P,C);if(!T)return{skipTouchLatency:!0};return{touchPoint:A,skipTouchLatency:!1}}class CF{device;adbFactory;isEnabled;observeScreenProvider;constructor(c){this.device=c.device,this.adbFactory=c.adbFactory??v,this.isEnabled=c.isEnabled??Uo,this.observeScreenProvider=c.observeScreenProvider}async run(c,d){if(!this.isEnabled())return;let h=this.device.platform;if(h!=="android"){e.debug("[PerformanceAudit] Skipping audit, only Android is supported");return}if(!c.activeWindow?.appId){e.debug("[PerformanceAudit] Skipping audit, no active app");return}try{await d.track("performanceAudit",async()=>{e.info(`[PerformanceAudit] Running UI performance audit for ${c.activeWindow?.appId}`);let f=new Oe(this.device,this.adbFactory),P=new Lr,C=this.observeScreenProvider?.(),A=C?new Wr(C,c.activeWindow.appId,c.updatedAt):void 0,T=new Nr(this.device,this.adbFactory,A),I=await f.getCapabilities(),O=await P.getOrCreateThresholds(this.device.deviceId,I),x=We(c,c.activeWindow.appId),{touchPoint:N,skipTouchLatency:H}=Gr(x,c),V=await T.runAudit(c.activeWindow.appId,O,{screenSize:c.screenSize,perf:d,windowBounds:x,touchPoint:N,skipTouchLatency:H});c.performanceAudit=V;let q=new Date().toISOString().split("T")[0];if(await P.updateThresholdWeight(this.device.deviceId,q,V.passed),!V.passed)e.warn(`[PerformanceAudit] Performance audit FAILED with ${V.violations.length} violations`);else e.info("[PerformanceAudit] Performance audit PASSED");let{getPerformanceMonitor:K}=await import("./chunk-n1zmpk0z.js");K().startMonitoring(this.device.deviceId,c.activeWindow.appId,h)})}catch(f){e.error(`[PerformanceAudit] Failed to run performance audit: ${f}`)}}}var qr="android",Qo="android:id/aerr_";function Zo(c){if(!c.activeWindow?.appId||!c.elements)return!1;if(de.has(c.activeWindow.appId))return!1;let h=We(c,c.activeWindow.appId)??{top:0,bottom:1/0,left:-1/0,right:1/0},f=c.systemInsets,P=Math.max(h.top,f.top),C=Math.min(h.bottom,(c.viewHierarchy?.screenHeight??1/0)-f.bottom),A=Math.max(h.left,f.left),T=Math.min(h.right,(c.viewHierarchy?.screenWidth??1/0)-f.right);return Object.values(c.elements).every((I)=>I.every(({bounds:O})=>O.bottom<=P||O.top>=C||O.right<=A||O.left>=T))}function wd(c){return Boolean(c.activeWindow?.appId||c.viewHierarchy?.packageName||Le(c.viewHierarchy))}function Ph(c){if(!c.viewHierarchy?.hierarchy?.node)return;if(nt(c))return{reason:"status_bar_only"};if(wd(c))return;return{reason:"empty_active_window"}}function es(c,d,h){if(c?.ctrlProxyIncomplete!==!0)return;if(h&&c.packageName===qr)return;let f=c.packageName;if(d!==void 0&&f!==void 0&&f===d)return;return{sdkInt:c.sdkInt,reason:c.ctrlProxyIncompleteReason,accessibilityTool:c.accessibilityTool}}function DF(c){let{freshness:d}=c;if(d?.isFresh===!1||d?.verified===!1||c.viewHierarchy?.fallbackToSpringboard===!0||Ph(c))return;return Rd(c)}function Rd(c){return c.activeWindow?.appId||c.viewHierarchy?.packageName||c.viewHierarchy?.foregroundActivity?.split("/")[0]||void 0}class Kr{d;constructor(c){this.d=c}recordSingleDisplayTransition(c){let{result:d,observerMode:h,preserveDisplayState:f,explicitlyRouted:P,recordProvenance:C}=c;return!h&&!f&&!P&&xe.record(this.d.device().deviceId,d,this.d.platformTraits().isIosMultiPanel()?"ios":"android",C)}reconcileSingleDisplayFreshness(c){let{result:d,recordProvenance:h}=c,f=xe.revision(this.d.device().deviceId)!==h.revision,P=this.recordSingleDisplayTransition(c);return d.display.generation=f?h.identityRevision:xe.identityRevision(this.d.device().deviceId),d.displayRevision=f?h.revision:xe.revision(this.d.device().deviceId),{staleDisplay:f,geometryTransition:P}}async settleSingleDisplay(c,d,h){let{options:f,result:P,perf:C,signal:A,observerMode:T,preserveDisplayState:I}=c;await this.computeSingleDisplayFreshness(c,d,h);let{staleDisplay:O,geometryTransition:x}=this.reconcileSingleDisplayFreshness({result:P,observerMode:T,preserveDisplayState:I,explicitlyRouted:c.explicitlyRouted,recordProvenance:h.recordProvenance}),N=x?io().currentGeneration(this.d.device().deviceId):c.cacheGeneration;if(this.d.device().platform==="android"&&(x||xe.revision(this.d.device().deviceId)!==c.captureStart.revision))await this.resampleDeviceLock(P,A);if(this.d.identifyCapture(P,f?.freshness??"cached-ok"),c.iosLockState)rt(P,await c.iosLockState);if(!O&&ln(c))await C.track("cacheResult",()=>io().put(this.d.device().deviceId,P,N))}async resampleDeviceLock(c,d){delete c.deviceLock,delete c.deviceLockUnknown,await this.d.deviceStateCollector().collectDeviceLock(c,d)}async computeSingleDisplayFreshness(c,d,h){let{result:f,minTimestamp:P,signal:C,observerMode:A}=c,{foregroundIdentity:T}=d,{postCaptureForeground:I,getConfirmedFrameworkErrorDialog:O}=h,x=await this.d.windowIdentity().resolveStatusBarOnlyHierarchy(f,T,I,C);await this.d.windowIdentity().attributeFocusedOwnWindowToForeground(f,T,P);let N=await this.d.windowIdentity().resolveWindowIdentityMismatch(f,T,{postCaptureForeground:I,getConfirmedFrameworkErrorDialog:O,minTimestamp:P,signal:C});if(f.freshness=qw({requestedAfter:P>0?P:void 0,actualTimestamp:this.d.resolveObservationTimestampMs(f),hostAgeBasisMs:this.d.windowIdentity().resolveHostReceivedAtMs(f),now:this.d.timer().now(),verified:typeof f.viewHierarchy==="object"&&f.viewHierarchy!==null?f.viewHierarchy.fresh:void 0,...un(c,h),missingForegroundWindow:Ph(f),statusBarOnlyHierarchy:x,windowIdentityMismatch:N,activityAttributionMismatch:I.activityAttributionMismatch,emptyFocusedWindow:this.d.device().platform==="android"&&Zo(f),incompleteCapture:await this.describeIncompleteSingleDisplay(c,h)}),N)$5(f);if(A&&f.freshness?.unavailableDetail)f.freshness.warning+=` ${f.freshness.unavailableDetail}`}async describeIncompleteSingleDisplay(c,d){let{viewHierarchy:h}=c.result,f=h?.ctrlProxyIncomplete===!0;return es(h,f?await this.d.windowIdentity().confirmForegroundIdentity(d.postCaptureForeground,c.signal):void 0,f?await d.getConfirmedFrameworkErrorDialog():!1)}}var OF=0.02;function Pd(c,d,h){let{x:f,y:P}=c;switch(h){case 1:return{x:d.height-P,y:f};case 2:return{x:d.width-f,y:d.height-P};case 3:return{x:P,y:d.width-f};default:return c}}function mV(c,d,h){let{x:f,y:P}=c;switch(h){case 1:return{x:P,y:d.height-f};case 2:return{x:d.width-f,y:d.height-P};case 3:return{x:d.width-P,y:f};default:return c}}function fV(c,d){return d===1||d===3?{width:c.height,height:c.width}:c}function ts(c,d){let h=[{x:c.left,y:c.top},{x:c.right,y:c.top},{x:c.left,y:c.bottom},{x:c.right,y:c.bottom}].map(d);return{left:Math.min(...h.map((f)=>f.x)),top:Math.min(...h.map((f)=>f.y)),right:Math.max(...h.map((f)=>f.x)),bottom:Math.max(...h.map((f)=>f.y))}}function MF(c,d,h){return ts(c,(f)=>Pd(f,d,h))}function K4(c,d,h){return ts(c,(f)=>mV(f,d,h))}function NF(c,d,h){return{left:Math.max(0,Math.floor(c.left*d.x)),top:Math.max(0,Math.floor(c.top*d.y)),right:Math.min(h.width,Math.ceil(c.right*d.x)),bottom:Math.min(h.height,Math.ceil(c.bottom*d.y))}}function hV(c,d,h="snapshotOf"){let{width:f,height:P}=d.screenSize;if(![f,P].every((K)=>Number.isFinite(K)&&K>0))throw new t(`${h} requires finite, nonempty bounds and screen dimensions`);if([c.width,c.height].some((K)=>K<=0))throw new t(`${h} received an empty screenshot raster`);let A=d.platform==="ios"&&d.rasterOrientation!=="display"?d.rotation:0,T=[1,3].some((K)=>K===A)&&f>P&&c.width<c.height,I=A===2,[O,x]=T?[P,f]:[f,P],N=c.width/O,H=c.height/x;if(Math.abs(N-H)>OF)throw new t(`${h} screenshot and screen geometry have incompatible aspect ratios`);let V=[N,H].every((K)=>Math.abs((d.nativeScale??NaN)-K)<=OF)?"native-scale-confirmed":"raster-dimensions",q=[T,I].includes(!0)?"native":"display";return{pixelsPerNativeUnit:{x:N,y:H},scaleProvenance:V,quarterTurn:T,halfTurn:I,screenshotOrientation:q}}import*as Cd from"fs/promises";import Ad from"path";function Td(c){let d=Ad.extname(c).toLowerCase(),f={".png":"png",".jpg":"jpeg",".jpeg":"jpeg",".webp":"webp"}[d];if(!f)throw new t("Screenshot file has an unrecognized format.");return f}async function Ue(c,d,h,f={}){let{files:P=Cd,timer:C=i,protection:A=Mn}=f;await A.protect(c);let T=await P.stat(c);if(!T.isFile()||T.size===0)throw new t("Screenshot file is missing or empty.");let I=Number.isFinite(T.mtimeMs)?T.mtimeMs:C.now(),O=Td(c),x=await A.protect(c);return{screenshotPath:c,screenshotExpiresAt:x,screenshotSource:d,screenshotCaptureSource:d==="fresh"?"device":"observation-cache",screenshotCapturedAt:new Date(I).toISOString(),screenshotAgeMs:Math.max(0,C.now()-I),screenshotFormat:O,screenshotMimeType:`image/${O}`,...h?{screenshotFreshFailure:{code:"SCREENSHOT_CAPTURE_FAILED",message:h,retryable:!0}}:{}}}class zr{deps;constructor(c){this.deps=c}get device(){return this.deps.device()}get timer(){return this.deps.timer()}get screenshotRecorder(){return this.deps.screenshotRecorder()}get screenshotEvidenceFiles(){return this.deps.screenshotEvidenceFiles()}get pathProtection(){return this.deps.pathProtection()}async captureSettledScreenshot(c,d,h,{strict:f,displayId:P,screenshotOptions:C}){try{if(!this.screenshotRecorder.captureSettled)throw new t("Settled screenshot capture is unavailable");let A=await this.screenshotRecorder.captureSettled(c.observationId,{perf:d,signal:h,displayId:P,options:C}),T=await Ue(A,"fresh",void 0,{files:this.screenshotEvidenceFiles,timer:this.timer,protection:this.pathProtection});Object.assign(c,T);let I=An().getImageSizeForObservation(this.device.deviceId,c.observationId,A);await this.attachScreenshotRaster(c,I),this.refineIosPanelOrientation(c),c.screenshotSettled=!0}catch(A){if(h?.throwIfAborted(),f)throw new Ve(A,this.device.deviceId);c.screenshotSettled=!1,c.screenshotSettledError=r(A),e.warn(`[OBSERVE] Settled screenshot unavailable: ${c.screenshotSettledError}`,A)}}refineIosPanelOrientation(c){if(this.device.platform==="ios"&&(this.device.displays?.panels.length??0)>1){let d=c.screenshotImageSize;c.screenshotOrientation=d&&d.width>d.height===c.screenSize.width>c.screenSize.height?"display":"native"}}async attachScreenshotRaster(c,d){delete c.screenshotImageSize,delete c.screenshotPixelsPerNativeUnit,delete c.screenshotScaleProvenance;try{if(!d||![d.width,d.height].every((C)=>Number.isInteger(C)&&C>0)){e.warn("[OBSERVE] Could not read screenshot raster dimensions");return}c.screenshotImageSize={width:d.width,height:d.height};let h=c.viewHierarchy??{},f=Q(this.device.platform,"Deriving the screenshot raster scale"),P=hV(d,{platform:f,screenSize:c.screenSize,rotation:h.rotation??c.rotation,nativeScale:h.nativeScale,rasterOrientation:f==="ios"&&!((this.device.displays?.panels.length??0)>1&&d.width>d.height===c.screenSize.width>c.screenSize.height)?"native":"display"},"observe");c.screenshotPixelsPerNativeUnit=P.pixelsPerNativeUnit,c.screenshotScaleProvenance=P.scaleProvenance}catch(h){e.warn(`[OBSERVE] Could not derive screenshot raster scale: ${r(h)}`,h);return}}}function Id(c,d){return c?.key===d.key&&c.generation===d.generation}class jr{deps;constructor(c){this.deps=c}get device(){return this.deps.device()}get adb(){return this.deps.adb()}get timer(){return this.deps.timer()}get requestedDisplay(){return this.deps.requestedDisplay()}get observedAndroidDisplayCache(){return this.deps.observedAndroidDisplayCache()}get screenshotService(){return this.deps.screenshotService()}get screenshotEvidenceFiles(){return this.deps.screenshotEvidenceFiles()}get pathProtection(){return this.deps.pathProtection()}settledScreenshots(){return this.deps.settledScreenshots()}async captureDeviceReadScreenshot(c,d,h,f={}){let{requireFreshScreenshot:P=!1,display:C=this.requestedDisplay}=f;c.screenshotCaptureAttempted=!0,c.screenshotOrientation=this.device.platform==="ios"?"native":"display";let A=await this.resolveReadDisplayId(c,{signal:d,display:C}),T={format:h?.format??"png",...h,displayId:A},I=this.screenshotService instanceof _o?await this.screenshotService.executeObservationRead(T,d):await this.screenshotService.execute(T,d);if(d?.throwIfAborted(),I.success&&I.path){Object.assign(c,await Ue(I.path,"fresh",void 0,{files:this.screenshotEvidenceFiles,timer:this.timer,protection:this.pathProtection})),await this.settledScreenshots().attachScreenshotRaster(c,I.screenshotImageSize),c.screenshotSettled=!0;return}await this.handleDeviceReadScreenshotFailure(c,I.error??"Screenshot capture failed",A,P)}async handleDeviceReadScreenshotFailure(c,d,h,f){if(f)throw new t(`observe crop screenshot capture failed for device ${this.device.deviceId}: ${d}. Retry with a fresh settled capture.`);let P=this.eligibleCachedScreenshot(h,c.display);if(P)try{Object.assign(c,await Ue(P.path,"cached",d,{files:this.screenshotEvidenceFiles,timer:this.timer,protection:this.pathProtection})),await this.settledScreenshots().attachScreenshotRaster(c,P.imageSize)}catch(C){e.warn(`[OBSERVE] Cached screenshot unavailable: ${r(C)}`,C)}c.screenshotSettled=!1,c.screenshotSettledError=d}async resolveReadDisplayId(c,d={}){let{signal:h,display:f=this.requestedDisplay}=d;if(this.device.platform!=="android"||!f||f==="active")return;let P=sn(this.device.displays,f,{}),C=await this.observedAndroidDisplayCache.logicalIdForPanel(this.device,this.adb,P.key,h);return c.display={...c.display,key:P.key,role:P.role},C}eligibleCachedScreenshot(c,d){let h=io().getRecentInMemoryForDevice(this.device.deviceId);if(!this.cachedScreenshotDisplayMatches(h,c,d))return;if(h?.screenshotPath)return{path:h.screenshotPath,imageSize:h.screenshotImageSize};let f=this.deviceWideScreenshotPath(c);return f?{path:f}:void 0}deviceWideScreenshotPath(c){return!Boolean(this.requestedDisplay&&this.requestedDisplay!=="active")&&c===void 0&&!this.hasMultiplePanels()?An().getPath(this.device.deviceId):void 0}hasMultiplePanels(){return(this.device.displays?.panels.length??0)>1}cachedScreenshotDisplayMatches(c,d,h){let f=[void 0,"active",c?.display.key,c?.display.role].includes(this.requestedDisplay),P=[void 0,c?.viewHierarchy?.displayId].includes(d),C=!this.hasMultiplePanels()||Id(c?.display,h);return f&&P&&C}}async function rs(c,d,h){if(d?.packageName!==qr)return!1;let f=new G,P=!1,C=!1,A=!1,T=!1,I=!1,O=!1;for(let N of f.extractRootNodes(d))f.traverseNode(N,(H)=>{let V=f.extractNodeProperties(H),q=V["resource-id"]??V.resourceId;P||=typeof q==="string"&&q.startsWith(Qo),C||=q===xt,A||=q===Mt,T||=q===Et;let K=V.text??V["content-desc"];I||=typeof K==="string"&&/\b(?:isn't|is not) responding\b/i.test(K),O||=K==="Wait"});if(!(P||I&&O||C&&A&&T))return!1;try{let{stdout:N}=await c.executeCommand('shell "dumpsys window"',{signal:h});return/mCurrentFocus=Window\{[^}\r\n]*Application (?:Error:|Not Responding)/.test(N)}catch(N){return e.debug("Failed to read focused framework window from dumpsys:",N),!1}}class Yr{deps;constructor(c){this.deps=c}get timer(){return this.deps.timer()}get device(){return this.deps.device()}get viewHierarchy(){return this.deps.viewHierarchy()}get deviceStateCollector(){return this.deps.deviceStateCollector()}get hierarchyPlatform(){return Q(this.device.platform,"Observing the view hierarchy")}get platformValidator(){return this.deps.platformValidator()}get reconciler(){return this.deps.reconciler()}async refreshKnownStaleHierarchy(c,d,h,{remainingMs:f,sideSamples:P}){let C=this.timer.now(),A=await this.readIndependentHierarchy(c.viewHierarchy?.updatedAt,h?.signal,f,"Known-stale hierarchy refresh");if(A?.fresh===!0&&Gd(A)&&A.packageName===d&&this.platformValidator.validate(this.hierarchyPlatform,A).valid)this.reconciler.applyRecapturedHierarchy(c,A),this.reconciler.recorrelateActiveWindowToRecapture(c,A),delete c.backStack,delete c.deviceLock,delete c.deviceLockUnknown,await this.resampleAfterStaleWindowRecovery(c,{...P,signal:h?.signal,budgetMs:f-(this.timer.now()-C)})}async resampleAfterStaleWindowRecovery(c,d){let{skipBackStack:h,displayId:f,signal:P,budgetMs:C}=d;if(C<=0)return;let A={...c,deviceLock:void 0,deviceLockUnknown:void 0,backStack:void 0,errors:void 0},T=new AbortController,I=P?AbortSignal.any([P,T.signal]):T.signal;try{await l(Promise.all([this.deviceStateCollector.collectDeviceLock(A,I),h?Promise.resolve():this.deviceStateCollector.collectBackStack(A,new B,I,f)]),{timer:this.timer,timeoutMs:C,signal:P,label:"Stale-window side-sample refresh",onTimeout:()=>T.abort()})}catch(O){o(P),e.warn(`[StaleHierarchyRecovery] Stale-window side-sample refresh failed: ${r(O)}`,O);return}if(A.deviceLockUnknown)c.deviceLockUnknown=A.deviceLockUnknown;if(A.deviceLock)c.deviceLock=A.deviceLock;if(A.backStack)c.backStack=A.backStack;for(let O of A.errors??[])se(c,O)}async verifyCachedAndroidHierarchy(c,d){let h=c.viewHierarchy;if(!h||!this.needsCachedVerification(h,d))return;let f=this.timer.now(),P=await this.readIndependentHierarchy(h.updatedAt,d.signal,d.remainingMs,"Cached hierarchy verification");if(!P||!this.isVerifyingReplacement(P,h))return;let C=xo(P,c.activeWindow);if(this.reconciler.applyRecapturedHierarchy(c,P),!C)this.reconciler.recorrelateActiveWindowToRecapture(c,P),delete c.backStack,delete c.deviceLock,delete c.deviceLockUnknown,await this.resampleAfterStaleWindowRecovery(c,{...d.sideSamples,signal:d.signal,budgetMs:d.remainingMs-(this.timer.now()-f)})}needsCachedVerification(c,d){return d.eligible&&this.device.platform==="android"&&c.fresh!==!0&&Gd(c)&&d.remainingMs>0}isVerifyingReplacement(c,d){return c.fresh===!0&&Gd(c)&&c.packageName===d.packageName&&this.platformValidator.validate(this.hierarchyPlatform,c).valid}async readIndependentHierarchy(c,d,h,f){let P=new AbortController,C=d?AbortSignal.any([d,P.signal]):P.signal;try{return await l(()=>this.viewHierarchy.getViewHierarchy({},{perf:new B,skipWaitForFresh:!0,minTimestamp:Math.max(1,c??1),signal:C,timeoutMs:h,requireFreshExtraction:!0}),{timer:this.timer,timeoutMs:h,signal:d,label:f,onTimeout:()=>P.abort()})}catch(A){o(d),e.warn(`[StaleHierarchyRecovery] ${f} failed: ${r(A)}`,A);return}}}async function is(c,d,h=na){if(!c.success)throw new t(`Screenshot capture failed for device ${d}: ${c.error??"no error details"}`);if(!c.path)throw new t(`Screenshot capture succeeded for device ${d} but returned no file path.`);if(!await h(c.path))throw new t(`Screenshot capture succeeded for device ${d} but the file is missing: ${c.path}`);return c.path}var kd=2;class Jr{pathProtection;device;screenshotUtil;store;completionByJob=new Map;observationResultCountByJob=new Map;constructor(c,d,h=An(),f=Mn){this.pathProtection=f;this.device=c,this.screenshotUtil=d,this.store=h}start(c,{perf:d=new B,signal:h,displayId:f,capture:P}={}){this.store.beginObservation(this.device.deviceId,c),d.startOperation("screenshot");let C=this.screenshotUtil.startTrackedCapture(Xr(f,P),{parentSignal:h,coalesceWithPending:!0,queueAfterPendingIfRunning:!0,onComplete:async(A)=>{if(this.completionByJob.set(A.jobId,{aborted:A.aborted,isLatest:A.isLatest}),!A.isLatest){this.store.endObservation(this.device.deviceId,c,Tk);return}if(A.aborted){e.debug("[OBSERVE] Screenshot capture cancelled"),this.store.endObservation(this.device.deviceId,c,PR);return}try{await this.handleScreenshotResult(A.result,{ignoreCancel:!0})}catch(T){e.warn(`[OBSERVE] Failed to finalize screenshot capture: ${T}`)}}});this.recordObservationResult(C,c),C.promise.finally(()=>{d.endOperation("screenshot")}).catch((A)=>{e.debug(`[OBSERVE] Screenshot completion rejected: ${r(A)}`)})}async capture(c,{perf:d=new B,signal:h,displayId:f,capture:P}={}){this.store.beginObservation(this.device.deviceId,c),await this.captureWithOptions(c,d,h,{trackerOptions:{coalesceWithPending:!0,queueAfterPendingIfRunning:!0},request:Xr(f,P)})}async captureFresh(c,{perf:d=new B,signal:h,displayId:f,capture:P}={}){this.store.beginObservation(this.device.deviceId,c),await this.captureWithOptions(c,d,h,{trackerOptions:{queueAfterPending:!0},request:Xr(f,P)})}async captureSettled(c,{perf:d=new B,signal:h,displayId:f,options:P}={}){this.store.beginObservation(this.device.deviceId,c);try{return await d.track("screenshot",async()=>{for(let C=0;C<kd;C++){let{result:A,cancelled:T}=await this.captureSettledAttempt(h,f,P);if(T&&C===0&&!h?.aborted){e.debug("[OBSERVE] Retrying screenshot cancelled by another capture");continue}if(A.path)await this.pathProtection.protect(A.path);let I=await is(T?{success:!1,error:A.error??je}:A,this.device.deviceId);return this.store.update(this.device.deviceId,I),this.store.updateForObservation(this.device.deviceId,c,{path:I,imageSize:A.screenshotImageSize}),I}throw new t("Screenshot capture retry exhausted")})}catch(C){let A=r(C);throw this.store.updateForObservation(this.device.deviceId,c,{error:A}),e.warn(`[OBSERVE] Settled screenshot capture failed: ${A}`),u(C,`Failed to capture screenshot for device ${this.device.deviceId}`)}}async captureSettledAttempt(c,d,h){let f=this.screenshotUtil.startTrackedCapture({...h,format:h?.format??"png",displayId:d},{parentSignal:c,queueAfterPending:!0});be.registerCompletionReader(f.jobId);try{let P=await f.promise,C=be.getCompletion(f.jobId);return{result:P,cancelled:f.signal.aborted||C?.aborted===!0||C?.isLatest===!1||P.error?.includes(je)===!0}}finally{be.releaseCompletionReader(f.jobId)}}async captureWithOptions(c,d,h,{trackerOptions:f,request:P}){try{await d.track("screenshot",async()=>{let C=this.screenshotUtil.startTrackedCapture(P,{parentSignal:h,...f,onComplete:async(T)=>{if(this.completionByJob.set(T.jobId,{aborted:T.aborted,isLatest:T.isLatest}),!T.isLatest){this.store.endObservation(this.device.deviceId,c,Tk);return}if(T.aborted){e.debug("[OBSERVE] Screenshot capture cancelled"),this.store.endObservation(this.device.deviceId,c,PR);return}try{await this.handleScreenshotResult(T.result,{ignoreCancel:!0})}catch(I){e.warn(`[OBSERVE] Failed to finalize screenshot capture: ${I}`)}}}),A=this.recordObservationResult(C,c);await C.promise,await A})}catch(C){let A=r(C);if(A.includes(je)){e.debug("[OBSERVE] Screenshot capture cancelled");return}this.store.update(this.device.deviceId,void 0,A),this.store.updateForObservation(this.device.deviceId,c,{error:A}),e.warn(`[OBSERVE] Screenshot capture failed: ${A}`)}}async handleScreenshotResult(c,d={}){let h=(P,C)=>{if(d.updateDeviceWide!==!1)this.store.update(this.device.deviceId,P,C);if(d.observationId)this.store.updateForObservation(this.device.deviceId,d.observationId,{path:P,error:C,imageSize:c.screenshotImageSize})};if(!c.success){let P=c.error||"Failed to capture screenshot";if(d.ignoreCancel&&P.includes(je)){if(e.debug("[OBSERVE] Screenshot capture cancelled"),d.observationId)this.store.endObservation(this.device.deviceId,d.observationId,PR);return}h(void 0,P),e.warn(`[OBSERVE] Screenshot capture failed: ${P}`);return}if(!c.path){h(void 0,"Screenshot capture returned no file path"),e.warn("[OBSERVE] Screenshot capture succeeded but no file path was returned");return}if(await this.pathProtection.protect(c.path),!await na(c.path)){h(void 0,"Screenshot file missing after capture"),e.warn(`[OBSERVE] Screenshot capture reported success but file missing: ${c.path}`);return}h(c.path)}recordObservationResult(c,d){be.registerCompletionReader(c.jobId),this.observationResultCountByJob.set(c.jobId,(this.observationResultCountByJob.get(c.jobId)??0)+1);let h=!1,f=()=>{if(h)return;h=!0,be.releaseCompletionReader(c.jobId);let P=(this.observationResultCountByJob.get(c.jobId)??1)-1;if(P<=0){this.observationResultCountByJob.delete(c.jobId),this.completionByJob.delete(c.jobId);return}this.observationResultCountByJob.set(c.jobId,P)};return c.promise.then(async(P)=>{let C=be.getCompletion(c.jobId)??this.completionByJob.get(c.jobId);if(f(),!C||C.aborted||!C.isLatest){e.debug("[OBSERVE] Screenshot capture cancelled"),this.store.endObservation(this.device.deviceId,d,C?.isLatest===!1?Tk:PR);return}await this.handleScreenshotResult(P,{ignoreCancel:!0,observationId:d,updateDeviceWide:!1})}).catch((P)=>{f();let C=r(P);this.store.updateForObservation(this.device.deviceId,d,{error:C}),e.warn(`[OBSERVE] Failed to record screenshot for observation ${d}: ${C}`)})}}function Xr(c,d){return d?.hidePrototypes===!0?{displayId:c,hidePrototypes:!0}:{displayId:c}}function Dd(c){return typeof c==="number"?{timeoutMs:c}:c}class Qr{opts;constructor(c){this.opts=c}reportTransportFailureIfAny(c,d){if(c!=="android"||d.hierarchy?.transportFailure!==!0)return;try{this.opts.onAvailabilityLost?.(`CtrlProxy hierarchy connection lost: ${d.hierarchy.error??"transport failure"}`)}catch(h){e.warn("[HierarchyCollector] Failed to report lost availability:",h)}}async collect(c,d={}){let{queryOptions:h,perf:f=new B,skipWaitForFresh:P=!1,minTimestamp:C=0,signal:A,readOnly:T=!1,capturedHierarchy:I,readOptions:O}=d,{device:x,viewHierarchy:N,adb:H,timer:V}=this.opts;try{if(x.platform==="android"&&!T)await N.configureRecompositionTracking(!0,f,A);let q=V.now(),K=I??await N.getViewHierarchy(h,{perf:f,skipWaitForFresh:P,minTimestamp:C,signal:A,...Dd(O)});if(e.debug("Accessibility service availability cached as: true"),K)this.attachHierarchy(c,K,N,x);e.debug(`View hierarchy retrieval took ${V.now()-q}ms`)}catch(q){e.warn("Failed to get view hierarchy:",q);try{ce.getInstance(x,{create:()=>H}).clearAvailabilityCache()}catch(K){e.debug(`[HierarchyCollector] Failed to clear availability cache: ${K}`)}this.reportHierarchyError(c,x,q)}}reportHierarchyError(c,d,h){let f=String(h);if(d.platform==="android"&&(f.includes(Eo)||f.includes("Failed to connect to accessibility service")))try{this.opts.onAvailabilityLost?.(`CtrlProxy hierarchy connection lost: ${f}`)}catch(P){e.warn("[HierarchyCollector] Failed to report lost availability:",P)}if(f.includes("null root node returned by UiTestAutomationBridge")||f.includes("cat:")&&f.includes("No such file or directory")||f.includes("screen appears to be off"))se(c,{phase:"viewHierarchy",message:"Screen appears to be off or device is locked",cause:f});else se(c,{phase:"viewHierarchy",message:"Failed to retrieve view hierarchy",cause:f})}attachHierarchy(c,d,h,f){if(c.viewHierarchy=d,this.reportTransportFailureIfAny(f.platform,d),d.updatedAt)c.updatedAt=d.updatedAt,e.debug(`Using updatedAt from view hierarchy: ${d.updatedAt}`);this.attachFocusedElements(c,d,h);try{let P=d.intentChooserDetected;if(c.intentChooserDetected=P,P)e.debug("[ObserveScreen] Intent chooser dialog detected in view hierarchy")}catch(P){e.warn(`[ObserveScreen] Failed to detect intent chooser: ${P}`)}if(d.notificationPermissionDetected!==void 0){if(c.notificationPermissionDetected=d.notificationPermissionDetected,d.notificationPermissionDetected)e.debug("[ObserveScreen] Notification permission dialog detected in view hierarchy")}}attachFocusedElements(c,d,h){let f=h.findFocusedElement(d);if(f)c.focusedElement=f,e.debug(`Found focused element: ${f.text||f["resource-id"]||"no text/id"}`);let P=h.findAccessibilityFocusedElement(d);if(P)c.accessibilityFocusedElement=P,e.debug(`Found accessibility-focused element: ${P.text||P["resource-id"]||P["content-desc"]||"no text/id/desc"}`)}async collectRaw(c,d,h){let{device:f,adbFactory:P,timer:C}=this.opts;try{if(f.platform==="android"){let A=(this.opts.androidRawClient??((I,O)=>k.getInstance(I,O)))(f,P),T=await A.requestHierarchySync(new B,!0,d,{displayId:h});if(h===void 0||h===0)A.invalidateCache();if(T?.hierarchy)c.rawViewHierarchy={json:JSON.stringify(T.hierarchy,null,2),source:"accessibility-service",timestamp:C.now(),device:{deviceId:f.deviceId,platform:f.platform}}}else{let A=_.getInstance(f),T=await A.requestHierarchySync(new B,!0,d);if(A.invalidateCache(),T?.hierarchy)c.rawViewHierarchy={xcuitest:JSON.stringify(T.hierarchy,null,2),source:"xcuitest",timestamp:C.now(),device:{deviceId:f.deviceId,platform:f.platform}}}}catch(A){e.warn("[ObserveScreen] Failed to collect raw view hierarchy:",A)}}extractScreenSize(c,d=!1){return c?wD(c,d):null}reconcileScreenDimensions(c,d){if(!c||typeof c==="string")return c;if(!d||d.width<=0||d.height<=0)return c;return c.screenWidth=d.width,c.screenHeight=d.height,c}}function os(c){let d=/^\s*Current Driving State:\s*(\d+)\s*$/m.exec(c)?.[1];return d==="0"?"parked":d==="1"?"idling":d==="2"?"moving":void 0}function ss(c,d){for(let h of c.matchAll(/^\s*Display id:\s*(\d+)\s+UXR:\s*DO:\s*(true|false)\s+UxR:\s*(\d+)\s+time:/gm))if(Number(h[1])===d&&Number.isSafeInteger(Number(h[3])))return{requiresDistractionOptimization:h[2]==="true",activeRestrictions:Number(h[3])};return}function as(c,d){let h=c.trim().split(/\r?\n/).map((P)=>P.trim());if(h[0]===`No DO Activities for ${d}`)return new Set;if(h[0]!==`DO Activities for ${d}`)return;let f=h.slice(1).filter((P)=>P.length>0);if(f.some((P)=>!/^[\w$]+(?:\.[\w$]+)+$/.test(P)))return;return new Set(f)}async function Js(c,d,h,{timeoutMs:f,signal:P}={}){let C=await c.executeCommand(`shell pm list packages --user ${h}`,{timeoutMs:f,noRetry:!0,signal:P});return ko(C.stdout,d)}class dm extends Error{details;constructor(c,d={kind:"unavailable",users:[]}){super(c);this.details=d}}class At{adb;constructor(c){this.adb=c}async resolve(c={}){if(c.explicitUserId!==void 0)return{userId:c.explicitUserId,source:"explicit"};if(c.currentUser){let C=await this.adb.executeCommand("shell am get-current-user",{noRetry:!0,signal:c.signal}),A=Number.parseInt(C.stdout.trim(),10);if(Number.isSafeInteger(A)&&A>=0)return{userId:A,source:"currentUser"}}let d=c.packageName?await this.readForeground(c):void 0;if(d?.match)return d.match;let h=await this.adb.listUsers(c.signal),f=await this.installedCandidates(c,h);return{...f!==h&&f.length===1?{userId:f[0].userId,source:"installedUser"}:this.selectDefaultUser(f,h),...d?.extra}}async readForeground(c){let d=await this.adb.getForegroundApp(c.signal),h=c.includeForegroundApp?{foregroundApp:d}:void 0;if(d&&d.packageName===c.packageName)return{match:{userId:d.userId,source:"foregroundPackage",...h}};return{extra:h}}selectDefaultUser(c,d){let h=c.filter((P)=>P.running&&(P.profileType??Sl(P.flags))==="managed");if(h.length===1)return{userId:h[0].userId,source:"managedProfile"};if(h.length>1)throw new dm(`Android target user is ambiguous: ${h.length} managed profiles are running`,{kind:"ambiguous",users:d});let f=c.find((P)=>P.running&&(P.profileType??Sl(P.flags))==="primary");if(f)return{userId:f.userId,source:"primary"};throw new dm("Android target user is unavailable: no running primary or uniquely selectable managed profile",{kind:"unavailable",users:d})}async installedCandidates(c,d){if(!c.installedOnly||!c.packageName||c.currentUser)return d;let h=d.filter((P)=>P.running);if(h.length<=1)return d;let f=[];for(let P of h)if(await Js(this.adb,c.packageName,P.userId,{signal:c.signal}))f.push(P);if(f.length>0)return f;return e.info(`Android app ${c.packageName} is not installed for any running user; checked users: ${h.map((P)=>P.userId).join(", ")}`),d}}async function re(c,d,h){let f=await c.execute(["shell",...d],{signal:h});if(f.error)throw new t(`adb shell ${d.join(" ")} failed: ${f.error}`);return f.stdout.replace(/\r\n?/g,`
|
|
48
|
-
`).trim()}function ze(c){throw new t(`unsupported on this image: ${c}`)}function Kt(c,d,h){throw new t(`Invalid ${c} value '${d}'. Expected one of: ${h.join(", ")}.`)}async function Sa(c,d,h){let f=await c.execute([...d],{signal:h});if(f.error)throw new t(`adb ${d.join(" ")} failed: ${f.error}`);return`${f.stdout}
|
|
49
|
-
${f.stderr}`.replace(/\r\n?/g,`
|
|
50
|
-
`).trim()}function Xn(){let c=Promise.resolve();return(d)=>{let h=c.then(d,d);return c=h.catch(()=>{return}),h}}var Ah=(c)=>(d,h)=>new At(c).resolve({packageName:d,installedOnly:!0,signal:h}).then((f)=>f.userId);class ei{opts;constructor(c){this.opts=c}async collectAutomotive(c,d,h=0){if(this.opts.device.formFactor!=="automotive")return;let[f,P]=await Promise.all([this.readAutomotive(["dumpsys","car_service","--services","CarDrivingStateService"],d),this.readAutomotive(["dumpsys","car_service","--services","CarUxRestrictionsManagerService"],d)]),C=os(f),A=ss(P,h);c.automotive={...C!==void 0?{drivingState:C}:{},...A?{uxRestrictions:A}:{},blocked:!1},await this.refreshAutomotiveForegroundActivity(c,d)}async refreshAutomotiveForegroundActivity(c,d){let h=c.automotive;if(!h)return;let{appId:f,activityName:P}=c.activeWindow??{},C;if(f&&P){let O=as(await this.readAutomotive(["cmd","car_service","get-do-activities",f],d),f),x=P.replace(/^\./,`${f}.`);C=O?.has(x)}let{drivingState:A,uxRestrictions:T}=h,I=EF(c);c.automotive={...A!==void 0?{drivingState:A}:{},...T?{uxRestrictions:T}:{},...C!==void 0?{foregroundActivity:{distractionOptimized:C}}:{},blocked:T?.requiresDistractionOptimization===!0&&C===!1,...I?{hostRenderedUi:I}:{}}}async readAutomotive(c,d){try{return await re(this.opts.adb,c,d)}catch(h){return e.warn("Failed to read automotive observation state:",h),""}}async collectWakefulness(c,d){let{adb:h}=this.opts;try{let f=await h.getWakefulness(d);if(f)c.wakefulness=f,c.wakefulnessSource="adb"}catch(f){e.warn("Failed to get wakefulness state:",f)}}async collectDeviceLock(c,d){let{adb:h}=this.opts;try{let f=await h.getDeviceLock(d);if(f)c.deviceLock=f}catch(f){e.warn("Failed to get device lock state:",f)}}async collectBackStack(c,d=new B,h,f=0){let{backStack:P,timer:C}=this.opts;try{let A=C.now(),T=await P.execute(d,h,f);c.backStack=T,e.debug(`Back stack retrieval took ${C.now()-A}ms`)}catch(A){e.warn("Failed to get back stack:",A),se(c,{phase:"backStack",message:"Failed to retrieve back stack information",cause:String(A)})}}async collectForegroundIdentity(c,d={}){return(await this.collectForegroundSnapshot(c,d))?.packageName??void 0}async collectForegroundSnapshot(c,d={}){let{adb:h}=this.opts;try{return await h.getForegroundApp(c,{displayId:d.displayId??0})}catch(f){if(c?.aborted)e.debug("Failed to get ground-truth foreground app:",f);else e.warn("Failed to get ground-truth foreground app:",f);return null}}async collectFocusedSystemUiSurface(c){let{adb:d}=this.opts;try{let{stdout:h}=await d.executeCommand('shell "dumpsys window"',{signal:c});return Pre(h)}catch(h){return e.debug("Failed to read focused window surface from dumpsys:",h),!1}}async collectActiveWindow(c,d=!1){let{window:h,timer:f}=this.opts;try{let P=f.now(),C=d?await h.getActive(!0,void 0,{cacheResult:!1}):await h.getActive(!0);if(e.debug(`Bootstrap active window retrieval took ${f.now()-P}ms`),C)c.activeWindow=C}catch(P){e.warn("Failed to get bootstrap active window:",P),se(c,{phase:"activeWindow",message:"Failed to retrieve active window information",cause:String(P)})}}}import ou from"crypto";function ht(c){let d=c.textSize;return typeof d==="number"&&Number.isFinite(d)&&d>0?d:null}var cs=new WeakMap;function ls(c){let d=cs.get(c);if(!d){let h=c.width+1;d=new Int32Array(h*(c.height+1));for(let f=0;f<c.height;f++){let P=0;for(let C=0;C<c.width;C++)P+=c.data[(c.width*f+C)*4+3]===255?1:0,d[(f+1)*h+C+1]=d[f*h+C+1]+P}cs.set(c,d)}return d}function ds(c,d,{x:h,y:f,radius:P}){let C=Math.round(to(h-P,0,c.width-1)),A=Math.round(to(h+P,0,c.width-1)),T=Math.round(to(f-P,0,c.height-1)),I=Math.round(to(f+P,0,c.height-1)),O=c.width+1;return d[(I+1)*O+A+1]-d[T*O+A+1]-d[(I+1)*O+C]+d[T*O+C]>0}function ri(c,d){return d.left>=0&&d.top>=0&&d.right<=c.width&&d.bottom<=c.height}var Od=6,xd=20,Ed=2,Md=10,yt=8,Fd=256,_d=0.5,Nd=30,vt=12;function us(c,d){return ye(c,d)<=20}function ye(c,d){let h=c.r-d.r,f=c.g-d.g,P=c.b-d.b;return Math.sqrt(h*h+f*f+P*P)}class ii{resolve;constructor(c){this.resolve=c}isGlyphPixel(c,d,h,{color:f,point:P}){let{x:C,y:A}=P,T=ye(f,h.textColor)<=Nd;if(!T&&us(this.resolve(c,C,A),h.textColor)&&this.isFringeNear(c,d,P,{color:f,...h}))return!0;if(!T||ye(f,h.textColor)>=ye(f,h.backgroundColor))return!1;return[[vt,0],[-vt,0],[0,vt],[0,-vt]].filter(([O,x])=>us(this.resolve(c,to(C+O,d.left,d.right-1),to(A+x,d.top,d.bottom-1)),h.backgroundColor)).length>=3}isFringeNear(c,d,h,{color:f,textColor:P,backgroundColor:C}){return this.isFringe(c,{left:Math.max(d.left,h.x-yt),top:Math.max(d.top,h.y-yt),right:Math.min(d.right,h.x+yt),bottom:Math.min(d.bottom,h.y+yt)},f,{text:P,background:C})}*levelPixels(c,d,h){let f=Math.ceil(d.left),P=Math.ceil(d.top),C=Math.ceil(d.right)-1,A=Math.ceil(d.bottom)-1;for(let T=P;T<=A;T++)for(let I=f;I<=C;I++)if(ye(this.resolve(c,I,T),h)<=Ed)yield{x:I,y:T}}isFringe(c,d,h,{text:f,background:P}){if(!this.isAntiAliasingBlend(h,P,f))return!1;let C=ye(h,f),A=ye(h,P),T=(V,q)=>V>=0&&q>=0&&V<c.width&&q<c.height?this.resolve(c,V,q):null,I=(V)=>V!==null&&ye(V,f)<C-xd,O=(V)=>V!==null&&ye(V,P)<A-Md,x=(V,q,K,j)=>[1,2,3].some((Y)=>I(T(V+K*Y,q+j*Y)))&&[1,2,3].some((Y)=>O(T(V-K*Y,q-j*Y))),N=0,H=0;for(let V of this.levelPixels(c,d,h)){if(N++,x(V.x,V.y,1,0)||x(V.x,V.y,-1,0)||x(V.x,V.y,0,1)||x(V.x,V.y,0,-1))H++;if(N>=Fd)break}return N>0&&H>=N*_d}isAntiAliasingBlend(c,d,h){let f=h.r-d.r,P=h.g-d.g,C=h.b-d.b,A=f*f+P*P+C*C;if(A===0)return!1;let T=((c.r-d.r)*f+(c.g-d.g)*P+(c.b-d.b)*C)/A;if(T<=0||T>=1)return!1;let I={r:d.r+T*f,g:d.g+T*P,b:d.b+T*C};return ye(c,I)<=Od}}var ps=160,Hd=24,Bd=32,Vd=40,ni=40,bt=10,Ld=40,Wd=16384,Ud=65536,$d=0.6,ms=3,qd=65536;class oi{config;getCachedContrast;constructor(c,d){this.config=c;this.getCachedContrast=d}fringe=new ii((c,d,h)=>this.resolvePixelColor(c,d,h));pixelRGBA(c,d,h){let f=Math.round(d),P=Math.round(h);if(f<0)f=0;else if(f>=c.width)f=c.width-1;if(P<0)P=0;else if(P>=c.height)P=c.height-1;let C=(c.width*P+f)*4;return{r:c.data[C],g:c.data[C+1],b:c.data[C+2],a:c.data[C+3]}}colorClusters(c,d=!0){let h=new Map,f=new Map;for(let P of c){let C=P.r<<16|P.g<<8|P.b,A=d?P.r>>3<<10|P.g>>3<<5|P.b>>3:C,T=(f.get(C)??0)+1;f.set(C,T);let I=h.get(A);if(I)I.r+=P.r,I.g+=P.g,I.b+=P.b,I.count++,I.coreCount=Math.max(I.coreCount,T);else h.set(A,{...P,count:1,coreCount:1})}return Array.from(h.values(),(P)=>({color:{r:Math.round(P.r/P.count),g:Math.round(P.g/P.count),b:Math.round(P.b/P.count)},count:P.count,coreCount:P.coreCount})).sort((P,C)=>C.count-P.count)}elementPixels(c,d){let h=Math.ceil(d.right)-Math.ceil(d.left),f=Math.ceil(d.bottom)-Math.ceil(d.top),P=h*f,C=Math.min(P,4096);return Array.from({length:C},(A,T)=>{let I=Math.floor(T*P/C);return this.resolvePixelColor(c,Math.ceil(d.left)+I%h,Math.ceil(d.top)+Math.floor(I/h))})}perimeterPixels(c,d){let h=[];for(let f=0;f<128;f++){let P=d.left+Math.floor((d.right-d.left-1)*f/127),C=d.top+Math.floor((d.bottom-d.top-1)*f/127);h.push(this.resolvePixelColor(c,P,d.top)),h.push(this.resolvePixelColor(c,P,d.bottom-1)),h.push(this.resolvePixelColor(c,d.left,C)),h.push(this.resolvePixelColor(c,d.right-1,C))}return h}interiorBounds(c){let d=Math.min(4,Math.floor((c.right-c.left-2)/2),Math.floor((c.bottom-c.top-2)/2));return{left:c.left+d,top:c.top+d,right:c.right-d,bottom:c.bottom-d}}inkBounds(c,d,h){let f=Math.ceil(d.left),P=Math.ceil(d.top),C=Math.ceil(d.right)-f,A=Math.ceil(d.bottom)-P,T=Math.max(1,Math.ceil(Math.sqrt(C*A/Wd))),I=1/0,O=1/0,x=-1/0,N=-1/0,H=0,V=0;for(let Y=0;Y<A;Y+=T)for(let X=0;X<C;X+=T)if(H++,this.colorDistance(this.resolvePixelColor(c,f+X,P+Y),h)>ni)V++,I=Math.min(I,X),O=Math.min(O,Y),x=Math.max(x,X),N=Math.max(N,Y);if(V===0||V>H*0.5)return null;let q=T+2,K={left:f+Math.max(0,I-q),top:P+Math.max(0,O-q),right:f+Math.min(C,x+q+1),bottom:P+Math.min(A,N+q+1)};return(K.right-K.left)*(K.bottom-K.top)<=C*A*0.5&&K.right-K.left>=2&&K.bottom-K.top>=2?K:null}hasSolidStroke(c,d,h,f=bt){return!this.solidStrokeSeeds(c,d,h,f).next().done}*solidStrokeSeeds(c,d,h,f=bt){let P=Math.ceil(d.left),C=Math.ceil(d.top),A=Math.ceil(d.right)-1,T=Math.ceil(d.bottom)-1,I=(A-P+1)*(T-C+1),O=Math.max(1,Math.ceil(Math.sqrt(I/Ud))),x=(H,V)=>this.colorDistance(this.resolvePixelColor(c,H,V),h)<=f,N=(H,V)=>x(H,V)&&(H>P&&x(H-1,V)||H<A&&x(H+1,V))&&(V>C&&x(H,V-1)||V<T&&x(H,V+1));for(let H=C;H<=T;H+=O)for(let V=P;V<=A;V+=O)if(N(V,H))yield{x:V,y:H}}hasGlyphStrokes(c,d,h){let f={left:Math.max(0,d.left),top:Math.max(0,d.top),right:Math.min(c.width,d.right),bottom:Math.min(c.height,d.bottom)},P=new Set,C={pixels:qd},A=0;for(let T of this.solidStrokeSeeds(c,f,h)){if(C.pixels<=0||A>=ms)break;if(P.has(T.y*c.width+T.x))continue;let I=this.strokeRegion(c,f,h,{seed:T,visited:P,budget:C}),O=I.right-I.left+1,x=I.bottom-I.top+1;if(I.count<=O*x*$d)return!0;A+=Math.min(O,x)*3<=Math.max(O,x)?1:0}return A>=ms}strokeRegion(c,d,h,{seed:f,visited:P,budget:C}){let A=Math.ceil(d.left),T=Math.ceil(d.top),I=Math.ceil(d.right)-1,O=Math.ceil(d.bottom)-1,x={count:0,left:f.x,top:f.y,right:f.x,bottom:f.y},N=[f.y*c.width+f.x];P.add(N[0]);while(N.length>0&&C.pixels>0){let H=N.pop(),V=H%c.width,q=Math.floor(H/c.width);C.pixels--,x.count++,x.left=Math.min(x.left,V),x.top=Math.min(x.top,q),x.right=Math.max(x.right,V),x.bottom=Math.max(x.bottom,q);let K=[V>A?H-1:-1,V<I?H+1:-1,q>T?H-c.width:-1,q<O?H+c.width:-1];for(let j of K)if(j>=0&&!P.has(j)&&this.isStrokePixel(c,j,h))P.add(j),N.push(j)}return x}isStrokePixel(c,d,h){let f=this.resolvePixelColor(c,d%c.width,Math.floor(d/c.width));return this.colorDistance(f,h)<=bt}sampleElementColors(c,d){let h=this.interiorBounds(d),f=this.elementPixels(c,h),P=this.colorClusters(f),C=P[0].color,A=this.perimeterPixels(c,d),T=this.colorClusters(A),I=T.filter((J)=>this.isSimilarColor(J.color,C)).reduce((J,ee)=>J+ee.count,0),O=P.filter((J)=>!this.isSimilarColor(J.color,C)&&T.some((ee)=>this.isSimilarColor(J.color,ee.color))).reduce((J,ee)=>J+ee.count,0),x=T.filter((J)=>J.count>=51.2),N=this.perimeterPixels(c,this.interiorBounds(d)).filter((J)=>x.some((ee)=>this.colorDistance(J,ee.color)<=40)).length;if(I<51.2&&O>=f.length*0.1&&N>=256)C=this.averageColor(A);let H=this.inkBounds(c,h,C),V=H?this.elementPixels(c,H):f,K=(H?this.colorClusters(V):P).filter((J)=>J.count>=Math.max(2,V.length*0.0025)&&!this.isSimilarColor(J.color,C)&&(!H||this.colorDistance(J.color,C)>ni)),j=(J)=>this.hasSolidStroke(c,H??h,J,this.colorDistance(J,C)<=Ld?0:bt),Y=(J,ee)=>this.fringe.isFringe(c,H??h,J,{text:ee,background:C}),X=this.selectTextColor(K,C,T,{isSolidStroke:j,isFringe:Y});return{textColor:(H?P.filter((J)=>J.count>=Math.max(2,f.length*0.0025)&&!this.isSimilarColor(J.color,C)&&this.colorDistance(J.color,C)<=ni&&!T.some((ee)=>this.isSimilarColor(J.color,ee.color))&&this.hasGlyphStrokes(c,h,J.color)):[]).reduce((J,ee)=>this.getCachedContrast(ee.color,C)<this.getCachedContrast(J,C)?ee.color:J,X),backgroundColor:C}}selectTextColor(c,d,h,{isSolidStroke:f,isFringe:P}){let C=c[0]?.count??0,A=c.filter((T)=>T.count>=C*0.25||T.coreCount>=T.count*0.8&&!h.some((I)=>this.isSimilarColor(T.color,I.color))&&!P(T.color,c[0].color)&&f(T.color));return A.reduce((T,I)=>{let O=this.getCachedContrast(I.color,d),x=this.getCachedContrast(T,d);return O<x?I.color:T},A[0]?.color??d)}async sampleBackgroundColors(c,d,h,f){let P=[];for(let C of f){let A=await this.sampleBackgroundAtPoint(c,d,h,{x:C.x,y:C.y});P.push({x:C.x,y:C.y,ratio:0,backgroundColor:A})}return P}backgroundColorsAtRadius(c,d,h,{x:f,y:P,radius:C}){let A=[];for(let T=-C;T<=C;T++)for(let I=-C;I<=C;I++){let O=to(f+T,d.left,d.right-1),x=to(P+I,d.top,d.bottom-1),N=this.resolvePixelColor(c,O,x);if(!this.isSimilarColor(N,h))A.push(N)}return A}async sampleBackgroundAtPoint(c,d,h,{x:f,y:P}){let C=[2,4,6,8];for(let A of C){let T=this.backgroundColorsAtRadius(c,d,h.textColor,{x:f,y:P,radius:A}),I=this.colorClusters(T)[0];if(I&&T.length>=(2*A+1)**2*0.2&&I.count>=T.length*0.2){let O=this.colorClusters(T.filter((x)=>this.isSimilarColor(x,I.color)),!1)[0].color;return this.fringe.isGlyphPixel(c,d,h,{color:O,point:{x:f,y:P}})?h.backgroundColor:O}}return h.backgroundColor}resolvePixelColor(c,d,h){let f=this.pixelRGBA(c,d,h);if(!this.config.compositeOverlays||f.a===255)return{r:f.r,g:f.g,b:f.b};let P=this.findUnderlyingColor(c,d,h);if(!P)return{r:f.r,g:f.g,b:f.b};return this.compositeColors(P,f)}underlyingColorAtRadius(c,d,h,f){for(let P=-f;P<=f;P++)for(let C=-f;C<=f;C++){if(f>1&&Math.abs(P)<f&&Math.abs(C)<f)continue;let A=Math.round(to(d+P,0,c.width-1)),T=Math.round(to(h+C,0,c.height-1)),I=(c.width*T+A)*4;if(c.data[I+3]===255)return{r:c.data[I],g:c.data[I+1],b:c.data[I+2]}}return null}findUnderlyingColor(c,d,h){let f=ls(c);for(let P=1;P<=12;P++)if(ds(c,f,{x:d,y:h,radius:P}))return this.underlyingColorAtRadius(c,d,h,P);return null}compositeColors(c,d){let h=d.a/255;return{r:Math.round(d.r*h+c.r*(1-h)),g:Math.round(d.g*h+c.g*(1-h)),b:Math.round(d.b*h+c.b*(1-h))}}detectGradient(c){if(c.length<5)return null;let d=c.map((A)=>A.backgroundColor),h=this.calculateColorVariance(d);if(h<250)return null;let P=this.calculateGradientAxes(c),C=P.direction;if(this.colorDistance(P.startColor,P.endColor)<20)return null;return{isGradient:!0,direction:C,variance:h,startColor:P.startColor,endColor:P.endColor}}calculateColorVariance(c){let d=this.averageColor(c);return c.reduce((f,P)=>{let C=P.r-d.r,A=P.g-d.g,T=P.b-d.b;return f+C*C+A*A+T*T},0)/c.length/3}calculateGradientAxes(c){let d=[...c].sort((Z,ne)=>Z.x-ne.x),h=[...c].sort((Z,ne)=>Z.y-ne.y),f=this.averageColor(d.slice(0,3).map((Z)=>Z.backgroundColor)),P=this.averageColor(d.slice(-3).map((Z)=>Z.backgroundColor)),C=this.averageColor(h.slice(0,3).map((Z)=>Z.backgroundColor)),A=this.averageColor(h.slice(-3).map((Z)=>Z.backgroundColor)),T=this.colorDistance(f,P),I=this.colorDistance(C,A),O=d[0].x,x=d[d.length-1].x,N=h[0].y,H=h[h.length-1].y,V=this.closestSample(c,O,N).backgroundColor,q=this.closestSample(c,x,N).backgroundColor,K=this.closestSample(c,O,H).backgroundColor,j=this.closestSample(c,x,H).backgroundColor,Y=this.colorDistance(V,j),X=this.colorDistance(q,K);if(T>=I&&T>=Y&&T>=X)return{direction:"horizontal",startColor:f,endColor:P};if(I>=T&&I>=Y&&I>=X)return{direction:"vertical",startColor:C,endColor:A};if(Y>=X)return{direction:"diagonal-down",startColor:V,endColor:j};return{direction:"diagonal-up",startColor:K,endColor:q}}closestSample(c,d,h){let f=c[0],P=Number.POSITIVE_INFINITY;for(let C of c){let A=C.x-d,T=C.y-h,I=A*A+T*T;if(I<P)P=I,f=C}return f}getGradientSamplingPoints(c,d){let{left:h,top:f,right:P,bottom:C}=c,A=P-h,T=C-f,I=Math.max(1,Math.floor(Math.min(A,T)*0.1)),O=h+I,x=P-I-1,N=f+I,H=C-I-1,V=5,q=[];for(let K=0;K<5;K++){let j=K/4;if(d==="horizontal")q.push({x:Math.round(O+j*(x-O)),y:Math.round((N+H)/2)});else if(d==="vertical")q.push({x:Math.round((O+x)/2),y:Math.round(N+j*(H-N))});else if(d==="diagonal-up")q.push({x:Math.round(O+j*(x-O)),y:Math.round(H-j*(H-N))});else q.push({x:Math.round(O+j*(x-O)),y:Math.round(N+j*(H-N))})}return q}mergeSamples(c,d){let h=new Set,f=[];for(let P of[...c,...d]){let C=`${P.x},${P.y}`;if(h.has(C))continue;h.add(C),f.push(P)}return f}getSamplingPoints(c,d){let{left:h,top:f,right:P,bottom:C}=c,A=P-h,T=C-f,I=Math.max(1,Math.floor(Math.min(A,T)*0.1)),O=h+I,x=P-I-1,N=f+I,H=C-I-1,V=d===5?[0.5,0.1,0.9]:[0.1,0.5,0.9],q=[];if(d===5)return q.push({x:Math.round(O+V[0]*(x-O)),y:Math.round(N+V[0]*(H-N))}),q.push({x:Math.round(O),y:Math.round(N+V[0]*(H-N))}),q.push({x:Math.round(x),y:Math.round(N+V[0]*(H-N))}),q.push({x:Math.round(O+V[0]*(x-O)),y:Math.round(N)}),q.push({x:Math.round(O+V[0]*(x-O)),y:Math.round(H)}),q;for(let K of V)for(let j of V)q.push({x:Math.round(O+K*(x-O)),y:Math.round(N+j*(H-N))});if(d===13)q.push({x:Math.round(O),y:Math.round(N)}),q.push({x:Math.round(x),y:Math.round(N)}),q.push({x:Math.round(O),y:Math.round(H)}),q.push({x:Math.round(x),y:Math.round(H)});return q}detectTextShadow(c,d,h,f){let{left:P,top:C,right:A,bottom:T}=d,I=1,O=[{x:P+1,y:C+1},{x:A-1-1,y:C+1},{x:P+1,y:T-1-1},{x:A-1-1,y:T-1-1},{x:Math.round((P+A)/2),y:C+1},{x:Math.round((P+A)/2),y:T-1-1},{x:P+1,y:Math.round((C+T)/2)},{x:A-1-1,y:Math.round((C+T)/2)}],x=this.relativeLuminance(h),N=this.relativeLuminance(f),H=x>N;return O.reduce((q,K)=>{let j=this.resolvePixelColor(c,K.x,K.y);if(this.isSimilarColor(j,h))return q;let Y=this.relativeLuminance(j);if(H&&Y<N-0.05)return q+1;if(!H&&Y>N+0.05)return q+1;return q},0)>=3}applyShadowAdjustment(c,d,h,f){if(!h||!this.isLargeText(d,f))return c;return Math.max(3,c-0.5)}requiredRatioFor(c,d,h,f){return this.applyShadowAdjustment(this.getRequiredContrastRatio(c,d,f),c,h,f)}isLargeText(c,d){if(!d||d<=0)return!1;let h=ht(c);if(h!==null)return h*ps/d>=Hd;let P=(c.bounds.bottom-c.bounds.top)*ps/d;return P>=Bd&&P<Vd}isSimilarColor(c,d){return this.colorDistance(c,d)<=20}colorDistance(c,d){let h=c.r-d.r,f=c.g-d.g,P=c.b-d.b;return Math.sqrt(h*h+f*f+P*P)}averageColor(c){if(c.length===0)return{r:128,g:128,b:128};let d=c.reduce((h,f)=>({r:h.r+f.r,g:h.g+f.g,b:h.b+f.b}),{r:0,g:0,b:0});return{r:Math.round(d.r/c.length),g:Math.round(d.g/c.length),b:Math.round(d.b/c.length)}}relativeLuminance(c){let d=c.r/255,h=c.g/255,f=c.b/255,P=d<=0.03928?d/12.92:Math.pow((d+0.055)/1.055,2.4),C=h<=0.03928?h/12.92:Math.pow((h+0.055)/1.055,2.4),A=f<=0.03928?f/12.92:Math.pow((f+0.055)/1.055,2.4);return 0.2126*P+0.7152*C+0.0722*A}calculateContrastRatio(c,d){let h=this.relativeLuminance(c),f=this.relativeLuminance(d),P=Math.max(h,f),C=Math.min(h,f);return(P+0.05)/(C+0.05)}getRequiredContrastRatio(c,d,h){let f=this.isLargeText(c,h);if(d==="AAA")return f?4.5:7;else if(d==="AA")return f?3:4.5;else return f?3:4.5}}import hs from"fs/promises";function zd(c){return{screenshots:c.maxCacheSize?.screenshots??10,colorPairs:c.maxCacheSize?.colorPairs??1000,elements:c.maxCacheSize?.elements??500,backgrounds:c.maxCacheSize?.backgrounds??200}}function Xd(c){return{useMultiPointSampling:c.useMultiPointSampling??!0,detectGradients:c.detectGradients??!0,compositeOverlays:c.compositeOverlays??!1,detectTextShadows:c.detectTextShadows??!1,samplingPoints:c.samplingPoints??9,enableScreenshotCache:c.enableScreenshotCache??!0,enableColorPairCache:c.enableColorPairCache??!0,enableElementCache:c.enableElementCache??!0,enableBackgroundCache:c.enableBackgroundCache??!0,screenshotCacheTTL:c.screenshotCacheTTL??60000,maxCacheSize:zd(c)}}class St{deps;imageAnalysis;config;timer;backend;screenshotCache=new Map;screenshotHits=0;screenshotMisses=0;contrastCache=new Map;colorPairHits=0;colorPairMisses=0;elementCache=new Map;elementHits=0;elementMisses=0;bgColorCache=new Map;bgColorHits=0;bgColorMisses=0;constructor(c={},d=i,h=gs(),f={readFile:hs.readFile}){this.deps=f;this.timer=d,this.backend=h,this.config=Xd(c),this.imageAnalysis=new oi(this.config,(P,C)=>this.getCachedContrast(P,C))}async checkContrast(c,d,h,f){try{if(this.config.enableElementCache){let H=this.elementCacheKey(d,h,f),V=await this.getScreenshotFingerprint(c),q=this.elementCache.get(H);if(q&&q.screenshotFingerprint===V)return this.elementHits++,q.result;this.elementMisses++}let{left:P,top:C,right:A,bottom:T}=d.bounds,I=A-P,O=T-C;if(I<2||O<2)return null;let x=await this.getOrLoadScreenshot(c),N=await this.checkContrastWithImage(x,d,h,f);if(N&&this.config.enableElementCache){let H=this.elementCacheKey(d,h,f),V=await this.getScreenshotFingerprint(c);this.elementCache.set(H,{result:N,timestamp:this.timer.now(),screenshotFingerprint:V}),this.cleanupCache(this.elementCache,this.config.maxCacheSize.elements)}return N}catch(P){return e.warn(`Contrast checking error: ${r(P)}`,P),null}}getBatchCachedContrast(c,d,h,f){if(!this.config.enableElementCache)return;let P=this.elementCacheKey(c,d,f),C=this.elementCache.get(P);if(C&&C.screenshotFingerprint===h)return this.elementHits++,C;this.elementMisses++;return}cacheBatchContrast(c,d,h,{result:f,density:P}){if(f&&this.config.enableElementCache){let C=this.elementCacheKey(c,d,P);this.elementCache.set(C,{result:f,timestamp:this.timer.now(),screenshotFingerprint:h})}}async checkContrastBatch(c,d,h,f){return(await this.checkContrastBatchWithCoverage(c,d,h,f)).results}async checkContrastBatchWithCoverage(c,d,h,f){let P=new Map,C=[];try{let A=await this.getOrLoadScreenshot(c),T=await this.getScreenshotFingerprint(c);for(let I of d){if(!ri(A,I.bounds)){C.push(I);continue}P.set(I,await this.checkBatchElement(A,I,h,{screenshotFingerprint:T,density:f}))}if(this.config.enableElementCache)this.cleanupCache(this.elementCache,this.config.maxCacheSize.elements)}catch(A){e.warn(`Batch contrast checking error: ${r(A)}`,A),C.length=0;for(let T of d)P.set(T,null)}return{results:P,outsideImage:C}}async checkBatchElement(c,d,h,{screenshotFingerprint:f,density:P}){try{let C=this.getBatchCachedContrast(d,h,f,P);if(C)return C.result;let A=await this.checkContrastWithImage(c,d,h,P);return this.cacheBatchContrast(d,h,f,{result:A,density:P}),A}catch(C){return e.warn(`Error checking contrast for element: ${r(C)}`,C),null}}async checkContrastWithImage(c,d,h,f){let{left:P,top:C,right:A,bottom:T}=d.bounds,I=A-P,O=T-C;if(I<2||O<2)return null;if(!ri(c,d.bounds))return null;let{textColor:x,backgroundColor:N}=this.imageAnalysis.sampleElementColors(c,d.bounds);if(!this.config.useMultiPointSampling){let le=N,ue=this.getCachedContrast(x,le),Ze=this.config.detectTextShadows?this.imageAnalysis.detectTextShadow(c,d.bounds,x,le):!1,Mi=this.imageAnalysis.getRequiredContrastRatio(d,h,f),Pa=this.imageAnalysis.applyShadowAdjustment(Mi,d,Ze,f),Ca=ue>=this.imageAnalysis.requiredRatioFor(d,"AA",Ze,f),Aa=ue>=this.imageAnalysis.requiredRatioFor(d,"AAA",Ze,f);return{ratio:ue,minRatio:ue,maxRatio:ue,avgRatio:ue,samples:[{x:Math.floor((P+A)/2),y:Math.floor((C+T)/2),ratio:ue,backgroundColor:le}],textColor:x,backgroundColor:le,shadowDetected:Ze,baseRequiredRatio:Mi,meetsAA:Ca,meetsAAA:Aa,requiredRatio:Pa}}let H=this.imageAnalysis.getSamplingPoints(d.bounds,this.config.samplingPoints),V=await this.imageAnalysis.sampleBackgroundColors(c,d.bounds,{textColor:x,backgroundColor:N},H),q=this.config.detectGradients?this.imageAnalysis.detectGradient(V):null,K=V,j;if(q?.isGradient){j=q;let le=this.imageAnalysis.getGradientSamplingPoints(d.bounds,j.direction),ue=await this.imageAnalysis.sampleBackgroundColors(c,d.bounds,{textColor:x,backgroundColor:N},le);K=this.imageAnalysis.mergeSamples(V,ue)}let Y=K.map((le)=>{let ue=this.getCachedContrast(x,le.backgroundColor);return{...le,ratio:ue}}),X=Y.map((le)=>le.ratio),Z=Math.min(...X),ne=Math.max(...X),J=X.reduce((le,ue)=>le+ue,0)/X.length,ee=this.imageAnalysis.averageColor(Y.map((le)=>le.backgroundColor));this.setBackgroundCache(d.bounds,ee);let Qe=this.config.detectTextShadows?this.imageAnalysis.detectTextShadow(c,d.bounds,x,ee):!1,Ei=this.imageAnalysis.getRequiredContrastRatio(d,h,f),va=this.imageAnalysis.applyShadowAdjustment(Ei,d,Qe,f),ba=Z>=this.imageAnalysis.requiredRatioFor(d,"AA",Qe,f),Ra=Z>=this.imageAnalysis.requiredRatioFor(d,"AAA",Qe,f);return{ratio:Z,minRatio:Z,maxRatio:ne,avgRatio:J,samples:Y,textColor:x,backgroundColor:ee,gradient:j,shadowDetected:Qe,baseRequiredRatio:Ei,meetsAA:ba,meetsAAA:Ra,requiredRatio:va}}async getOrLoadScreenshot(c){if(!this.config.enableScreenshotCache)return await this.decodeScreenshot(c);let d=this.screenshotCache.get(c),h=this.timer.now();if(d&&h-d.timestamp<this.config.screenshotCacheTTL){let C=await this.getScreenshotFingerprint(c);if(d.fingerprint===C)return this.screenshotHits++,d.image}this.screenshotMisses++;let f=await this.decodeScreenshot(c),P=await this.getScreenshotFingerprint(c);return this.screenshotCache.set(c,{image:f,timestamp:h,fingerprint:P}),this.cleanupCache(this.screenshotCache,this.config.maxCacheSize.screenshots),f}async decodeScreenshot(c){let d=await this.deps.readFile(c);return this.backend.rawPixels(d)}async getScreenshotFingerprint(c){try{let d=await hs.stat(c);return`${c}:${d.mtime.getTime()}:${d.size}`}catch(d){return e.warn(`Failed to stat contrast screenshot ${c}; using timestamp: ${r(d)}`,d),`${c}:${this.timer.now()}`}}elementCacheKey(c,d,h){return JSON.stringify({text:c.text,bounds:c.bounds,class:c.class,textSize:ht(c),wcagLevel:d,density:h&&h>0?h:null})}getCachedContrast(c,d){if(!this.config.enableColorPairCache)return this.imageAnalysis.calculateContrastRatio(c,d);let h=this.colorPairKey(c,d),f=this.contrastCache.get(h);if(f!==void 0)return this.colorPairHits++,f;return this.colorPairMisses++,f=this.imageAnalysis.calculateContrastRatio(c,d),this.contrastCache.set(h,f),this.cleanupCache(this.contrastCache,this.config.maxCacheSize.colorPairs),f}colorPairKey(c,d){let h=c.r+c.g+c.b,f=d.r+d.g+d.b,[P,C]=h>f?[c,d]:[d,c];return`${P.r},${P.g},${P.b}:${C.r},${C.g},${C.b}`}clearCaches(){this.screenshotCache.clear(),this.contrastCache.clear(),this.elementCache.clear(),this.bgColorCache.clear(),this.screenshotHits=0,this.screenshotMisses=0,this.colorPairHits=0,this.colorPairMisses=0,this.elementHits=0,this.elementMisses=0,this.bgColorHits=0,this.bgColorMisses=0}getCacheStats(){return{screenshots:{size:this.screenshotCache.size,hits:this.screenshotHits,misses:this.screenshotMisses},colorPairs:{size:this.contrastCache.size,hits:this.colorPairHits,misses:this.colorPairMisses},elements:{size:this.elementCache.size,hits:this.elementHits,misses:this.elementMisses},backgrounds:{size:this.bgColorCache.size,hits:this.bgColorHits,misses:this.bgColorMisses}}}cleanupCache(c,d){if(c.size<=d)return;let h=Array.from(c.entries()).sort((P,C)=>{if(typeof P[1]==="number"||typeof C[1]==="number")return 0;return P[1].timestamp-C[1].timestamp}),f=c.size-d;for(let P=0;P<f;P++)c.delete(h[P][0])}setBackgroundCache(c,d){if(!this.config.enableBackgroundCache)return;let h=`${c.left},${c.top},${c.right},${c.bottom}`;if(this.bgColorCache.set(h,d),this.bgColorCache.size>this.config.maxCacheSize.backgrounds){let f=this.bgColorCache.keys().next().value;if(f)this.bgColorCache.delete(f)}}}var Jd=1,wt=2,Qd=3;function Zd(c){let d=c.occlusionState;return d==="partial"||d==="hidden"}function eu(c,d){if(c.type===wt)return!(d?.type===wt||d?.windowLayer!==void 0&&c.windowLayer!==void 0&&d.windowLayer>c.windowLayer);if(c.type!==Jd&&c.type!==Qd)return!1;return d?.windowLayer!==void 0&&c.windowLayer!==void 0&&c.windowLayer>d.windowLayer}function tu(c,d,h){let f=d===void 0?void 0:h.find((P)=>P.id===d);return h.some((P)=>{let C=Gt(P.bounds);return C!==null&&P!==f&&eu(P,f)&&Qt(c.bounds,C)!==null})}function fs(c,d,h=[]){return!Zd(c)&&!tu(c,d,h)}function ys(c,d,h=[]){let f=d===void 0?void 0:h.find((C)=>C.id===d);if(f)return f.type===wt;let P=c.package??c["resource-id"]?.split(":id/")[0];return P!==void 0&&h.some((C)=>C.type===wt&&C.packageName===P)}class si{injectedDb;constructor({db:c}={}){this.injectedDb=c??null}get db(){return this.injectedDb??ke()}async get(c){return await this.db.selectFrom("accessibility_baselines").selectAll().where("screen_id","=",c).executeTakeFirst()??null}async list(){return this.db.selectFrom("accessibility_baselines").selectAll().execute()}async upsert(c,d,h){await this.db.insertInto("accessibility_baselines").values({screen_id:c,violations_json:d,updated_at:h}).onConflict((f)=>f.column("screen_id").doUpdateSet({violations_json:d,updated_at:h})).execute()}async delete(c){await this.db.deleteFrom("accessibility_baselines").where("screen_id","=",c).execute()}async deleteAll(){await this.db.deleteFrom("accessibility_baselines").execute()}async deleteOlderThan(c){let d=await this.db.deleteFrom("accessibility_baselines").where(m`datetime(updated_at)`,"<",m`datetime(${c})`).executeTakeFirst();return Number(d.numDeletedRows)||0}}var ru=z(so((c)=>typeof c==="object"&&c!==null&&("fingerprint"in c)&&typeof c.fingerprint==="string"));class FF{repository;constructor(c){this.repository=new si({db:c})}async getBaseline(c){let d=await this.repository.get(c);if(!d)return null;let h=this.parseViolations(d.violations_json,d.screen_id);if(h===null)return null;return{screenId:d.screen_id,violations:h,updatedAt:d.updated_at}}parseViolations(c,d){try{return ru.parse(JSON.parse(c))}catch(h){return e.warn(`[BaselineManager] Corrupt violations_json for screen "${d}"; ignoring baseline row`,h),null}}async saveBaseline(c,d){let h=new Date().toISOString(),f=JSON.stringify(d);await this.repository.upsert(c,f,h)}async clearBaseline(c){await this.repository.delete(c)}async listBaselines(){let c=await this.repository.list(),d=[];for(let h of c){let f=this.parseViolations(h.violations_json,h.screen_id);if(f===null)continue;d.push({screenId:h.screen_id,violations:f,updatedAt:h.updated_at})}return d}async clearAllBaselines(){await this.repository.deleteAll()}async cleanupOldBaselines(c=iC.baselineDays){let d=aV(c);return this.repository.deleteOlderThan(d)}}var su="no screenshot for this observation",au="text elements are covered by the keyboard or another window, or partly hidden, so the screenshot does not show them",cu="text elements extend beyond the screenshot";function lu(c){return[{count:c.covered,reason:au},{count:c.outsideImage,reason:cu}].filter(({count:d})=>d>0).map(({count:d,reason:h})=>({check:"insufficient-contrast",reason:`${d} ${h}`}))}var Th=50,vs={error:0,warning:1,info:2};function bs(c){let d=c.violations.length;if(d<=Th)return c;let h=[...c.violations].sort((C,A)=>vs[C.severity]-vs[A.severity]),f=h.slice(0,Th),P={};for(let C of h.slice(Th))P[C.type]=(P[C.type]??0)+1;return{...c,violations:f,violationsTruncated:{total:d,omitted:d-f.length,omittedByType:P}}}function du(c){if(Se(c).class||!c.node)return c;let d=Array.isArray(c.node)?c.node:[c.node];return d.find((h)=>Se(h)["resource-id"])??d.find((h)=>Se(h).class)??c}function uu(c,d,h){let f=op(c,h)?.filter((C)=>C.type===1&&(C.packageName===void 0||C.packageName===d)&&C.hierarchy),P=f?.find((C)=>C.isFocused)??f?.find((C)=>C.isActive)??f?.reduce((C,A)=>!C||(A.windowLayer??-1/0)>(C.windowLayer??-1/0)?A:C,void 0);if(!P?.hierarchy)return;return du(P.hierarchy)}class lm{contrastChecker;baselineStore;timer;constructor(c=i,d=new FF,h=new St({},c)){this.contrastChecker=h,this.baselineStore=d,this.timer=c}async audit(c,d,{screenshotPath:h,packageName:f,config:P},C){let{density:A,windows:T,descendantLabelled:I,elementWindowIds:O}=typeof C==="number"?{density:C}:C??{};c=c.filter((Y)=>!ys(Y,O?.get(Y),T));let x=[];x.push(...this.checkMissingContentDescriptions(c,I));let N;if(h)N=await this.checkContrastRatios(c,h,P,{density:A,coverage:{windows:T??[],elementWindowIds:O}}),x.push(...N.violations);x.push(...this.checkTouchTargetSizes(c,P.level,A)),x.push(...this.checkFormInputLabels(c,d,A));let H=this.generateScreenId(f,d,T),V=x,q=0;if(P.useBaseline){let Y=await this.baselineStore.getBaseline(H);if(Y){let X=new Set(Y.violations.map((Z)=>Z.fingerprint));V=x.filter((Z)=>!X.has(Z.fingerprint)),q=x.length-V.length}}let K=this.generateSummary(x,V,q,P),j=N?lu(N):[{check:"insufficient-contrast",reason:su}];if(j.length>0)K.notEvaluated=j;return{config:P,summary:K,violations:V,timestamp:this.timer.now(),screenId:H}}async saveBaseline(c){await this.baselineStore.saveBaseline(c.screenId,c.violations)}async clearBaseline(c){await this.baselineStore.clearBaseline(c)}checkMissingContentDescriptions(c,d){let h=[];for(let f of c){if(f.text||f["content-desc"])continue;if(d?.has(f))continue;if(f.clickable||f.focusable||f.checkable)h.push({type:"missing-content-description",severity:"error",criterion:"1.1.1",message:`Interactive element (${f.class||"unknown"}) lacks accessible label`,element:f,details:{explanation:"Clickable, focusable, or checkable elements must have a text label or content-desc for screen readers"},fingerprint:this.generateFingerprint(f,"missing-content-description")})}return h}async checkContrastRatios(c,d,{level:h,contrast:f},{density:P,coverage:C}){let A=[],T=c.filter((V)=>V.text&&V.text.trim().length>0),I=T.filter((V)=>fs(V,C.elementWindowIds?.get(V),C.windows)),O=T.length-I.length,x=f?new St(f,this.timer):this.contrastChecker,{results:N,outsideImage:H}=await x.checkContrastBatchWithCoverage(d,I,h,P);for(let[V,q]of N.entries())if(q&&q.minRatio<q.requiredRatio){let K=q.minRatio.toFixed(2),j=q.maxRatio.toFixed(2),Y=q.avgRatio.toFixed(2),X=q.shadowDetected?" (shadow-enhanced)":"";A.push({type:"insufficient-contrast",severity:h==="AAA"?"warning":"error",criterion:"1.4.3",message:`Text has insufficient contrast ratio: ${K}:1 (required: ${q.requiredRatio}:1)`,element:V,details:{contrastRatio:parseFloat(K),contrastMinRatio:parseFloat(K),contrastMaxRatio:parseFloat(j),contrastAvgRatio:parseFloat(Y),requiredRatio:q.requiredRatio,explanation:`Text color RGB(${q.textColor.r},${q.textColor.g},${q.textColor.b}) on background RGB(${q.backgroundColor.r},${q.backgroundColor.g},${q.backgroundColor.b}). Samples min/avg/max=${K}/${Y}/${j}${X}.`},fingerprint:this.generateFingerprint(V,"insufficient-contrast")})}return{violations:A,covered:O,outsideImage:H.length}}checkTouchTargetSizes(c,d,h){let f=[];if(!h||h<=0)return f;let P=44,C=h,A=P*(C/lm.BASELINE_DENSITY_DPI);for(let T of c){if(!T.clickable)continue;let I=T.bounds.right-T.bounds.left,O=T.bounds.bottom-T.bounds.top;if(I<A||O<A){let x=Math.floor(I*lm.BASELINE_DENSITY_DPI/C),N=Math.floor(O*lm.BASELINE_DENSITY_DPI/C);f.push({type:"touch-target-too-small",severity:d==="AAA"?"error":"warning",criterion:"2.5.5",message:`Touch target is too small: ${x}x${N}dp (minimum: ${P}x${P}dp)`,element:T,details:{actualSize:{width:x,height:N},requiredSize:{width:P,height:P},explanation:"Touch targets should be at least 44x44 dp to be easily tappable"},fingerprint:this.generateFingerprint(T,"touch-target-too-small")})}}return f}checkFormInputLabels(c,d,h){let f=[],P=c.filter((T)=>T.class?.includes("EditText")||T.class?.includes("Spinner")||T.class?.includes("CheckBox")||T.class?.includes("RadioButton")),C=c.filter((T)=>(!T.class||T.class.includes("TextView"))&&T.text),A=this.labelGapThresholdPx(h);for(let T of P)if(!(T.text||T["content-desc"]||this.hasNearbyLabel(T,C,A)))f.push({type:"unlabeled-form-input",severity:"error",criterion:"3.3.2",message:`Form input (${T.class||"unknown"}) lacks accessible label`,element:T,details:{explanation:"Form inputs must have associated labels for screen reader users to understand their purpose"},fingerprint:this.generateFingerprint(T,"unlabeled-form-input")});return f}static LABEL_GAP_DP=50;static BASELINE_DENSITY_DPI=160;static FALLBACK_DENSITY_DPI=320;labelGapThresholdPx(c){let d=c&&c>0?c:lm.FALLBACK_DENSITY_DPI;return lm.LABEL_GAP_DP*(d/lm.BASELINE_DENSITY_DPI)}hasNearbyLabel(c,d,h){let f=1/0;for(let P of d){let C=this.boundingBoxGap(c.bounds,P.bounds);if(C<f)f=C}return f<=h}boundingBoxGap(c,d){let h=Math.max(0,c.left-d.right,d.left-c.right),f=Math.max(0,c.top-d.bottom,d.top-c.bottom);return Math.sqrt(h*h+f*f)}generateFingerprint(c,d){let h=JSON.stringify({type:d,resourceId:c["resource-id"],class:c.class,bounds:c.bounds,text:c.text});return ou.createHash("md5").update(h).digest("hex")}generateScreenId(c,d,h){let f=this.resolveRootNode(d,c,h),P=Se(f),C=P.class||"unknown",A=P["resource-id"]||"";return`${c}:${C}:${A}`}resolveRootNode(c,d,h){if(h&&h.length>1){let P=uu(c,d,h);if(P)return P}let f=c.node;if(Array.isArray(f)&&f.length>0)return f[f.length-1];if(f&&typeof f==="object")return f;return c}generateSummary(c,d,h,f){let P={error:d.filter((I)=>I.severity==="error").length,warning:d.filter((I)=>I.severity==="warning").length,info:d.filter((I)=>I.severity==="info").length},C={"missing-content-description":0,"insufficient-contrast":0,"touch-target-too-small":0,"unlabeled-form-input":0};for(let I of d)C[I.type]++;let A=!0,T;if(f.failureMode==="strict"&&d.length>0)A=!1,T=`Found ${d.length} accessibility violation(s) in strict mode`;else if(f.failureMode==="threshold"){let I=f.minSeverity||"warning",O=d.filter((x)=>{if(I==="error")return x.severity==="error";if(I==="warning")return x.severity==="error"||x.severity==="warning";return!0});if(O.length>0)A=!1,T=`Found ${O.length} violation(s) at or above ${I} severity`}return{totalViolations:c.length,bySeverity:P,byType:C,baselinedViolations:h,passed:A,failureReason:T}}}function Ss(c,d){let h=Se(c.source).windowId;if(typeof h==="number"&&Number.isInteger(h))return h;return c.parentIndex===void 0?void 0:Ss(d[c.parentIndex],d)}var hu=/Image|Icon/i;function fu(c,d,h){if(/\p{L}/u.test(c??""))return!0;return/\p{N}/u.test(c??"")&&yu(d,h)}function yu(c,d){let h=0;for(let f=d.index+1;f<c.length;f++){let P=c[f];if(P.rootGroup!==d.rootGroup||P.depth<=d.depth)break;if(hu.test(P.className??""))return!1;if((P.element?.text??"").trim()||(P.element?.["content-desc"]??"").trim())h+=1}return h===1}function LF(c,d=new we){let h=d.project(Zt(c)??c),f=[],P=new Set,C=new Map;for(let A of h){if(A.rootGroup!==0||!A.element)continue;f.push(A.element);let T=Ss(A,h);if(T!==void 0)C.set(A.element,T);if(!Boolean(A.element.text||A.element["content-desc"])&&A.affordances.includes("tap")&&fu(A.displayedLabel,h,A))P.add(A.element)}return{elements:f,descendantLabelled:P,windowIds:C}}async function gV(c){if(!c)return;try{return await na(c)?c:void 0}catch(d){e.warn(`[AccessibilityAudit] Failed to check observation screenshot: ${d}`);return}}class ci{device;screenshotPathResolver;getConfig;contrastChecker;constructor(c){this.device=c.device,this.contrastChecker=c.contrastChecker,this.screenshotPathResolver=c.screenshotPathResolver??(()=>Promise.resolve(void 0)),this.getConfig=c.getConfig??(()=>M.getAccessibilityAuditConfig())}async run(c,d){let h=this.getConfig();if(!h)return;if(this.device.platform!=="android"){e.debug("[AccessibilityAudit] Skipping audit, only Android is supported");return}if(!c.viewHierarchy?.hierarchy){e.debug("[AccessibilityAudit] Skipping audit, no view hierarchy available");return}if(!c.activeWindow?.appId){e.debug("[AccessibilityAudit] Skipping audit, no active app");return}try{await d.track("accessibilityAudit",async()=>{e.info(`[AccessibilityAudit] Running WCAG ${h.level} audit for ${c.activeWindow?.appId}`);let f=new lm(void 0,void 0,this.contrastChecker),{elements:P,descendantLabelled:C,windowIds:A}=LF(c.viewHierarchy),T=await this.screenshotPathResolver(c.observationId),I=await f.audit(P,c.viewHierarchy.hierarchy,{screenshotPath:T,packageName:c.activeWindow.appId,config:h},{density:c.viewHierarchy.density,windows:c.viewHierarchy.windows,descendantLabelled:C,elementWindowIds:A});if(c.accessibilityAudit=bs(I),!I.summary.passed)e.warn(`[AccessibilityAudit] Accessibility audit FAILED with ${I.violations.length} violations (${I.summary.bySeverity.error} errors, ${I.summary.bySeverity.warning} warnings)`);else e.info("[AccessibilityAudit] Accessibility audit PASSED")})}catch(f){e.error(`[AccessibilityAudit] Failed to run accessibility audit: ${f}`)}}}class ws{DEFAULT_TTL_MS=60000;cache;timer;constructor(c=new Zm){this.timer=c,this.cache=new Zr(c,{ttlMs:this.DEFAULT_TTL_MS})}async isVoiceOverEnabled(c,d,{featureFlags:h,timeoutMs:f,signal:P}={}){return await this.resolveVoiceOverState(c,d,{featureFlags:h,timeoutMs:f,signal:P})===!0}async isVoiceOverActiveOrUnknown(c,d,{featureFlags:h,timeoutMs:f,signal:P}={}){let C=await this.resolveVoiceOverState(c,d,{featureFlags:h,timeoutMs:f,signal:P});if(C===null)return e.warn(`[IosVoiceOverDetector] VoiceOver state for device ${c} could not be determined; treating as enabled (fail-safe) so the tap path takes the activation gesture instead of a plain touch`),!0;return C}async resolveState(c,d,{featureFlags:h,timeoutMs:f,signal:P}={}){return this.resolveVoiceOverState(c,d,{featureFlags:h,timeoutMs:f,signal:P})}async resolveVoiceOverState(c,d,{featureFlags:h,timeoutMs:f,signal:P}={}){if(h?.isEnabled("force-accessibility-mode"))return e.debug(`[IosVoiceOverDetector] Force-enabled via feature flag for device ${c}`),!0;if(h&&!h.isEnabled("accessibility-auto-detect"))return e.debug(`[IosVoiceOverDetector] Auto-detection disabled via feature flag for device ${c}`),!1;let C=this.cache.get(c);if(C!==void 0)return e.debug(`[IosVoiceOverDetector] Using cached result for device ${c}: enabled=${C}`),C;e.debug(`[IosVoiceOverDetector] Detecting VoiceOver state for device ${c}`);let A=this.timer.now(),T=await this.detectVoiceOverState(c,d,f,P),I=this.timer.now()-A;if(I>50)e.warn(`[IosVoiceOverDetector] Detection took ${I}ms (target: <50ms) for device ${c}`);else e.debug(`[IosVoiceOverDetector] Detection completed in ${I}ms for device ${c}`);if(T!==null)this.cache.set(c,T);return T}invalidateCache(c){e.debug(`[IosVoiceOverDetector] Invalidating cache for device ${c}`),this.cache.delete(c)}clearAllCache(){e.debug("[IosVoiceOverDetector] Clearing all cached entries"),this.cache.clear()}async detectVoiceOverState(c,d,h,f){try{let P=await d.requestVoiceOverState(h,void 0,f);if(!P.success)return e.warn(`[IosVoiceOverDetector] VoiceOver detection failed for ${c}: ${P.error}`),null;return e.debug(`[IosVoiceOverDetector] VoiceOver state for device ${c}: enabled=${P.enabled}`),P.enabled}catch(P){return e.error(`[IosVoiceOverDetector] Failed to detect VoiceOver state for device ${c}:`,P),null}}}var vo=new ws;class li{device;adb;featureFlags;detector;iosDetector;iosClient;constructor(c){this.device=c.device,this.adb=c.adb,this.featureFlags=c.featureFlags,this.detector=c.accessibilityDetector??ti,this.iosDetector=c.iosVoiceOverDetector??vo,this.iosClient=c.iosClient}async run(c,d,h){try{await d.track("accessibilityDetection",async()=>{o(h);let f=this.featureFlags??sr.getInstance();if(this.device.platform==="android"){let P=await this.detector.resolveState(this.device.deviceId,this.adb,f);if(P===null){delete c.accessibilityState;return}let{enabled:C,service:A}=P,T=!f.isEnabled("force-accessibility-mode")&&!f.isEnabled("accessibility-auto-detect");c.accessibilityState={enabled:C,service:A,detectionSkipped:T},e.debug(`[AccessibilityDetector] Android accessibility state: enabled=${C}, service=${A}`)}else if(this.device.platform==="ios"){let P=this.iosClient??_.getInstance(this.device),C=await this.iosDetector.resolveState(this.device.deviceId,P,{featureFlags:f});if(C===null){delete c.accessibilityState;return}c.accessibilityState={enabled:C,service:C?"voiceover":"unknown"},e.debug(`[IosVoiceOverDetector] iOS VoiceOver state: enabled=${C}`)}})}catch(f){e.error(`[detectAccessibilityState] Failed to detect accessibility state: ${f}`)}}}var gu=100,qe=Symbol("observe-poll-budget-expired"),di=Symbol("observe-poll-reconciliation-unconfirmed");async function Ps(c,{timer:d,remainingMs:h,signal:f,label:P}){if(h<0)return qe;let C=new AbortController,A=Error(`${P} exceeded the remaining ${h}ms budget`);try{return await l(()=>c(Ge(f,C.signal)),{timer:d,timeoutMs:h+1,signal:f,label:P,timeoutError:()=>A})}catch(T){if(T!==A)throw T;return C.abort(new DOMException(A.message,"TimeoutError")),e.debug(`[ObservePoll] ${A.message}; aborted the read`),qe}}function vu(c,d,h){return h!==void 0&&(d<=0||c.hardBudget===!0&&d<gu)}function ui(c){return c.wakefulness==="Asleep"}function bu(c){return ui(c)&&c.wakefulnessSource==="adb"}function Cs(c){let d=c.viewHierarchy;if(!d||typeof d.hierarchy!=="object"||d.hierarchy===null||"error"in d.hierarchy)return;return On(d)}function As(c,d,h){if(c)return d!==void 0&&d>0?d:0;return h!==void 0&&h>0?h+1:0}async function Su(c,d,h,f){let P=Error("Observe poll finalization deadline reached"),C;try{await l(c,{timer:d,timeoutMs:Math.max(0,h),signal:f,label:"Observe poll finalization",timeoutError:()=>P}),C="settled"}catch(A){if(f?.aborted)C="aborted";else if(A===P)C="deadline";else throw A}if(C==="settled")return;c.then(()=>{e.debug("[ObservePoll] Background terminal finalization settled after poll completion")}).catch((A)=>{e.debug(`[ObservePoll] Background terminal finalization failed: ${A}`)})}function Ru(c){return Cs(c)!==void 0&&c.freshness?.isFresh!==!1&&c.freshness?.verified!==!1}function Pu(c){return c.freshness?.isFresh===!1||c.freshness?.verified===!1}function Cu(c,d){return{capture:d??c,canProcessRecomposition:d!==void 0}}function Au(c,d,h){return c!==void 0&&(d===void 0||c>=d)&&!h}function Ts(c,d){let h=Cs(c),f=Pu(c);if(d.enteringReference===void 0&&h!==void 0)d.enteringReference=h;let P=Au(h,d.deviceFloor,f);if(P&&h!==void 0)d.deviceFloor=d.deviceFloor===void 0?h:Math.max(d.deviceFloor,h);let C=h!==void 0&&d.enteringReference!==void 0&&h>d.enteringReference&&P;if(C)d.hasPostInvocationEvidence=!0;return{isAdmissibleEvidence:P,isPostInvocation:C}}function Tu(c,d,h){let f=ui(c)&&c.wakefulnessSource==="hierarchy";return bu(c)||ui(c)&&d&&(!f||h)}function Iu(c,d,h){if(c.isAdmissibleEvidence)return{previous:c.capture.observation,newestTrustworthyCapture:c.capture};return{previous:d,newestTrustworthyCapture:h}}function ku(c,d,h,{original:f,capture:P}){if(!h.stopped)return;let{options:C,timer:A,start:T,onObservation:I}=c,O=C.resumeOnTerminalMismatch?Ts(P.observation,d):{isAdmissibleEvidence:!0,isPostInvocation:!0};if(O.isAdmissibleEvidence&&O.isPostInvocation&&I(P.observation,f,h.polls))return;if(h.stopped=!1,h.terminalReason="timeout",C.resumeOnTerminalMismatch&&A.now()-T<C.timeoutMs)return{kind:"resume",outcome:h,capture:P,isAdmissibleEvidence:O.isAdmissibleEvidence};return}function Du(c,d){let{observeScreen:h,timer:f,options:P,start:C}=c;return async(A,T=!0,I,O)=>{let x=await Ou(h,f,P,{start:C,observation:A.observation,minTimestamp:As(d.hasPostInvocationEvidence,d.deviceFloor,d.enteringReference)});if(A.waitMs=f.now()-C,x===di){if(A.stopped)A.stopped=!1,A.terminalReason="timeout"}else if(x){let N=A.observation;A.observation=x.observation,A.polls++,I=x.generation,O=x.cachedAt,T=Ru(x.observation);let H=ku(c,d,A,{original:N,capture:x});if(H)return H}if(o(P.signal),P.skipRecompositionTracking&&T&&h.processRecomposition){let N=(async()=>{await h.processRecomposition(A.observation),await h.cacheObserveResult?.(A.observation,I,O)})();await Su(N,f,P.timeoutMs-(f.now()-C),P.signal)}else await h.cacheObserveResult?.(A.observation,I,O);return{kind:"terminal",outcome:A}}}async function pi(c,d,h,{minTimestamp:f,timeoutMs:P,readBackStackEachPoll:C=h.readBackStackEachPoll,signal:A=h.signal}){let T=c.captureCacheGeneration?.(),I=d.now();return{observation:await c.execute({display:h.display,freshness:h.display===void 0?void 0:"fresh",minTimestamp:f,timeoutMs:P,skipWaitForFresh:h.skipWaitForFresh??!1,requireFreshExtraction:h.requireFreshExtraction,signal:A,skipScreenshot:!0,skipStaleWindowRecovery:!0,skipCache:!0,skipBackStack:C===!0?void 0:!0,skipAccessibilityAudit:!0,skipPerformanceAudit:h.skipPerformanceAudit,skipRecompositionTracking:h.skipRecompositionTracking}),generation:T,cachedAt:I}}function Rs(c,d,h,{start:f,label:P}){if(h.hardBudget)return Ps(c,{timer:d,remainingMs:h.timeoutMs-(d.now()-f),signal:h.signal,label:P});return l(()=>c(h.signal),{timer:d,signal:h.signal,label:P})}async function Ou(c,d,h,{start:f,observation:P,minTimestamp:C}){if(h.readBackStackEachPoll||!c.collectDeferredBackStack)return;let A=await Rs((T)=>c.collectDeferredBackStack(P,{signal:T}),d,h,{start:f,label:"Observe poll terminal back stack"});if(o(h.signal),A===qe)return di;if(!A)return;try{let T=await Rs((I)=>pi(c,d,h,{minTimestamp:C,readBackStackEachPoll:!0,signal:I}),d,h,{start:f,label:"Observe poll attribution reconciliation"});return o(h.signal),T===qe?di:T}catch(T){o(h.signal),e.warn("[ObservePoll] Terminal attribution poll failed; returning original observation",T);return}}async function xu(c,d,h,{start:f,minTimestamp:P,lastCapture:C}){let A=h.timeoutMs-(d.now()-f),T=Math.max(1,A);if(!h.hardBudget)return{capture:await pi(c,d,h,{minTimestamp:P,timeoutMs:T})};let I=await Ps((O)=>pi(c,d,h,{minTimestamp:P,timeoutMs:T,signal:O}),{timer:d,remainingMs:A,signal:h.signal,label:"Observe poll read"});if(o(h.signal),I!==qe)return{capture:I};if(!C)throw new t(`Observe poll read did not finish within its ${h.timeoutMs}ms budget`);return{expired:C}}async function ZA(c,d,h,f){let P=d.now(),C,A,T=0,I={enteringReference:h.initialMinTimestampMs,deviceFloor:h.initialMinTimestampMs,hasPostInvocationEvidence:!1},O,x=Du({observeScreen:c,timer:d,options:h,start:P,onObservation:f},I),N=async(V)=>{let{capture:q,canProcessRecomposition:K}=Cu(V,O);return(await x({observation:q.observation,polls:T,waitMs:d.now()-P,stopped:!1,terminalReason:"timeout"},K,q.generation,q.cachedAt)).outcome},H=()=>h.timeoutMs-(d.now()-P);while(!0){if(o(h.signal),vu(h,H(),A))return N(A);let V=As(I.hasPostInvocationEvidence,I.deviceFloor,I.enteringReference),q=await xu(c,d,h,{start:P,minTimestamp:V,lastCapture:A});if(o(h.signal),"expired"in q)return N(q.expired);let{capture:K}=q,{observation:j,generation:Y,cachedAt:X}=K;T++,A=K;let{isAdmissibleEvidence:Z,isPostInvocation:ne}=Ts(j,I);if(Z)O=K;if(Tu(j,Z,ne))return(await x({observation:j,polls:T,waitMs:d.now()-P,stopped:!1,terminalReason:"screen_off"},Z,Y,X)).outcome;if(Z&&f(j,C,T)&&ne){let ee=await x({observation:j,polls:T,waitMs:d.now()-P,stopped:!0,terminalReason:"matched"},!0,Y,X);if(ee.kind==="terminal")return ee.outcome;T=ee.outcome.polls,A=ee.capture,{previous:C,newestTrustworthyCapture:O}=Iu(ee,j,O),await R(d.sleep(Math.min(Math.max(1,h.pollMs),Math.max(0,h.timeoutMs-(d.now()-P)))),h.signal);continue}if(Z)C=j;if(H()<=0)return N(K);await R(d.sleep(Math.min(h.pollMs,Math.max(0,h.timeoutMs-(d.now()-P)))),h.signal)}}var Eu=new Set(["text","view-id"]);function Ke(c){let d=c.split("\x00");if(d.length!==4)return;return[d[0],d[1],d[3]].join("\x00")}function Mu(c,d){return Os(Object.keys(_D(c.attributes,d.attributes)))}function Os(c){return c.includes("text")&&c.every((d)=>Eu.has(d))}function ks(c){let d=new Map;for(let h of UB(c)){let f=Ke(h.key);if(f===void 0)continue;let P=h.pathKey.split(xz).map((C)=>Ke(C)??C).join(xz);d.set(f,d.has(f)?null:P)}return d}function xs(c,d){let h=ks(c),f=ks(d),P=new Set;for(let C of new Set([...h.keys(),...f.keys()])){let A=h.get(C);if(A===void 0||A===null||A!==f.get(C))P.add(C)}return P}function Ds(c){let d=new Map;for(let h of c){let f=Ke(h.key);if(f!==void 0)d.set(f,[...d.get(f)??[],h])}return d}function Es(c){return Os(Object.keys(c.changes))}function Fu(c,d){let h=new Set,f=Ds(c.added);for(let[P,C]of Ds(c.removed)){let A=f.get(P);if(C.length===1&&A?.length===1&&Mu(C[0],A[0]))h.add(P)}for(let P of c.changed){let C=Ke(P.key);if(C!==void 0&&Es(P))h.add(C)}for(let P of d)h.delete(P);return h}class mi{volatile=new Set;previousChanges=new Set;get volatileCount(){return this.volatile.size}reset(){this.volatile.clear(),this.previousChanges=new Set}mask(c,d=new Set){let h=Fu(c,d),f=new Set([...h].filter((C)=>this.volatile.has(C)));for(let C of h)if(this.previousChanges.has(C))this.volatile.add(C);this.previousChanges=h;let P=(C)=>{let A=Ke(C);return A!==void 0&&f.has(A)};return{...c,added:c.added.filter((C)=>!P(C.key)),removed:c.removed.filter((C)=>!P(C.key)),changed:c.changed.filter((C)=>!Es(C)||!P(C.key))}}}var _u=2500,Nu=150,Hu=2;function yV(c){return c.added.length===0&&c.removed.length===0&&c.changed.length===0&&c.fields===void 0}class um{observeScreen;timer;constructor(c,d=i){this.observeScreen=c;this.timer=d}async captureScreenshot(c,d){await this.observeScreen.captureScreenshot?.(void 0,{signal:d,observation:c})}async execute(c={}){let d=c.timeoutMs??_u,h=c.pollMs??Nu,f=c.stableReads??Hu,P=0,C=!1,A=new mi,T=await ZA(this.observeScreen,this.timer,{display:c.display,timeoutMs:d,pollMs:h,signal:c.signal,initialMinTimestampMs:c.initialMinTimestampMs,skipWaitForFresh:c.skipWaitForFresh,get requireFreshExtraction(){return C||c.requireFreshExtraction},resumeOnTerminalMismatch:c.resumeOnTerminalMismatch,hardBudget:c.hardBudget,skipPerformanceAudit:c.skipPerformanceAudit,skipRecompositionTracking:c.skipRecompositionTracking},(I,O)=>{if(C=ct(I.viewHierarchy)>0,C)return P=0,A.reset(),!1;if(O===void 0)return P=1,P>=f;if(!bg(O,I))return A.reset(),P=1,P>=f;return P=yV(A.mask(jm(O,I),xs(O,I)))?P+1:1,P>=f});return{observation:T.observation,settled:T.stopped,polls:T.polls,waitMs:T.waitMs,terminalReason:T.terminalReason==="matched"?"settled":T.terminalReason}}}function Ms(c){if(c?.cacheStore)Cre(c.cacheStore);if(c?.screenshotStateStore)Dre(c.screenshotStateStore)}function Fs(c){let{device:d,identity:h}=c;return{createHierarchyCapture(f,P){return pn(d,{viewHierarchy:h.viewHierarchy(),settle:new um(c.observeScreenProvider(),f),timer:f,ids:P})},createScreenshotRecorder(f,P){return new Jr(d,f,An(),P)},createHierarchyCollector(f){return new Qr({device:d,viewHierarchy:h.viewHierarchy(),adb:c.adb(),adbFactory:c.adbFactory(),timer:h.timer(),onAvailabilityLost:f?.onAvailabilityLost??(d.platform==="android"?(P)=>{let C=f?.daemonState;(C?C.isInitialized()?C.getSessionManager():void 0:w.sessionManager())?.invalidateAutomationReadinessForDevice(d.deviceId,P)}:void 0)})},createDeviceStateCollector(f,P){return new ei({device:d,window:f,backStack:P,adb:c.adb(),timer:h.timer()})},createPerformanceAuditor(){return new CF({device:d,adbFactory:c.adbFactory(),observeScreenProvider:c.observeScreenProvider})},createAccessibilityAuditor(){return new ci({device:d,screenshotPathResolver:(f)=>gV(An().getPathForObservation(h.device().deviceId,f))})},createAccessibilityStateDetector(){return new li({device:d,adb:c.adb()})},createWindowIdentity(){return new Ir({deviceStateCollector:h.deviceStateCollector,timer:h.timer,resolveObservationTimestampMs:h.resolveObservationTimestampMs})},createReconciler(){return new Tr({viewHierarchy:h.viewHierarchy,deviceStateCollector:h.deviceStateCollector,device:h.device,platformValidator:h.platformValidator,resolveObservationTimestampMs:h.resolveObservationTimestampMs,extractScreenSizeFromHierarchy:h.extractScreenSizeFromHierarchy})}}}var Rt=/^\s*(?:Task\s+id\s+#(\d+)\b|\*?\s*TaskRecord\{\S+\s+#(\d+)\b(.*))$/,Pt=/^\s*\*\s*Task\{\S+\s+#(\d+)\b(.*)$/;var Bu=/^\s*(?:Stack|RootTask)\s+#\d+:(.*)$/,_s=/(?:^|\s)mode=([^\s}]+)/,Vu=/^\s*mBounds=Rect\((-?\d+), (-?\d+) - (-?\d+), (-?\d+)\)/,Lu=/^\s*bounds=\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/,Wu=/^\s*CurrentConfiguration=.*?winConfig=\{\s*mBounds=Rect\((-?\d+), (-?\d+) - (-?\d+), (-?\d+)\)/,Uu=/^\s*CurrentConfiguration=.*?\smWindowingMode=([^\s}]+)/,$u=/^\s*\*\s/;function hi(c){if(!c)return;let[d,h,f,P]=c.slice(1,5).map((C)=>Number.parseInt(C,10));return f>d&&P>h?{left:d,top:h,right:f,bottom:P}:void 0}function Gu(c){let d=c.match(Pt);if(d)return{id:Number.parseInt(d[1],10),tail:d[2]};let h=c.match(Rt);if(h)return{id:Number.parseInt(h[1]??h[2],10),tail:h[3]??""};return}class Ns{evidence=new Map;rootTask;current;ownFields=!1;line(c){if(/^\S/.test(c)){this.rootTask=void 0,this.current=void 0;return}let d=c.match(Bu);if(d){this.rootTask={mode:d[1].match(_s)?.[1]},this.current=void 0;return}let h=Gu(c);if(h){this.startTask(h.id,h.tail);return}if($u.test(c))this.ownFields=!1;this.fields(c)}startTask(c,d){let h=this.evidence.get(c)??{};this.evidence.set(c,h),h.headerMode??=d.match(_s)?.[1],h.rootTaskMode??=this.rootTask?.mode,h.rootTaskBounds??=this.rootTask?.bounds,this.current=h,this.ownFields=!0}fields(c){let d=c.match(Vu);if(d){this.overrideBounds(hi(d));return}if(this.current)this.taskFields(this.current,c)}overrideBounds(c){if(this.current&&this.ownFields)this.current.override??=c;else if(this.rootTask&&!this.current)this.rootTask.bounds=c}taskFields(c,d){let h=d.match(Lu);if(h&&this.ownFields){c.resolved??=hi(h);return}let f=d.match(Wu);if(f)c.activityBounds??=hi(f),c.activityMode??=d.match(Uu)?.[1]}}function Hs(c){let d=new Ns;for(let f of c.split(/\r?\n/))d.line(f);let h=new Map;for(let[f,P]of d.evidence){let C=P.headerMode??P.rootTaskMode??P.activityMode,A=P.resolved??P.override??P.rootTaskBounds??P.activityBounds;h.set(f,{...C===void 0?{}:{windowingMode:C},...A===void 0?{}:{bounds:A}})}return h}function Bs(c,d){for(let h of c){let f=d.get(h.id);if(f?.windowingMode!==void 0)h.windowingMode=f.windowingMode;if(f?.bounds!==void 0)h.bounds=f.bounds}}var qu=/(?:^|\s)A=([^\s}]+)/,Ku=/(?:^|\s)a?I=([^\s}]+)/,zu=/(?:^|\s)U=(\d+)(?=\s|})/,ju=/Hist\s+#(\d+):\s+ActivityRecord\{\S+\s+u(\d+)\s+([^\s}]+)([^\n]*\})/;function Ws(c){let d=c.match(ju);if(!d)return;let h=d[4].match(/(?:^|[\s}])t(\d+)(?=[\s}]|$)/);return{histIndex:parseInt(d[1],10),userId:parseInt(d[2],10),component:d[3],taskId:h?parseInt(h[1],10):void 0}}var Us=/\bHist\s+#\d+:/,$s=/^\s*rootOfTask=(true|false)\b/;function Vs(c){let d=c.match(Pt);if(d)return Ls(parseInt(d[1],10),d[2]);let h=c.match(Rt);if(h)return h[1]!==void 0?{id:parseInt(h[1],10)}:Ls(parseInt(h[2],10),h[3]);return}function Ls(c,d){let h=d.match(qu),f=d.match(Ku),P=d.match(zu);return{id:c,userId:P?parseInt(P[1],10):void 0,affinity:h?h[1]:void 0,component:f?f[1]:void 0}}function fi(c,d){let h=c.get(d);if(h===void 0)h={},c.set(d,h);return h}function Yu(c,d){if(d.userId!==void 0)c.userId=d.userId;if(d.affinity)c.affinity=d.affinity;if(d.component)c.rootActivity=d.component,c.packageName=d.component.split("/")[0]}function Xu(c,d,h,{histRoots:f,openHist:P}){let C=Ws(c);if(C){let A=C.taskId??d;if(h.set(A,(h.get(A)??0)+1),C.histIndex===0)fi(f,A).firstHist0??=C.component;P={owner:A,component:C.component,histIndex:C.histIndex}}else if(Us.test(c))h.set(d,(h.get(d)??0)+1),P=void 0;return P}function Ju(c,d,h){let f=c.match(/launchedFromPackage=([^\s]+)/);if(f&&h){if(h.launchedFromPackage=f[1]==="null"?void 0:f[1],h.histIndex===0&&h.launchedFromPackage!==void 0)fi(d,h.owner).firstHist0LaunchedFromPackage??=h.launchedFromPackage}let P=c.match($s);if(P&&h){if(P[1]==="true"){let C=fi(d,h.owner);if(C.authoritative===void 0)C.authoritative=h.component,C.authoritativeLaunchedFromPackage=h.launchedFromPackage}h=void 0}return h}function Qu(c,d){let h=d.match(/affinity=([^\s]+)/);if(h)c.affinity=h[1];let f=d.match(/realActivity=([^\s]+)/);if(f){let C=f[1];if(c.packageName=C.split("/")[0],!c.rootActivity)c.rootActivity=C}let P=d.match(/numActivities=(\d+)/);if(P)c.numActivities=parseInt(P[1],10)}function Zu(c,d,h){if(c.numActivities===void 0)c.numActivities=d.get(c.id)??0;let f=h.get(c.id),P=f?.authoritative!==void 0?f.authoritativeLaunchedFromPackage:f?.firstHist0LaunchedFromPackage;if(P!==void 0)c.launchedFromPackage=P;if(f===void 0||f.firstHist0===void 0)return;let C=f.authoritative??f.firstHist0;if(c.rootActivity===void 0)c.rootActivity=C;if(c.packageName===void 0)c.packageName=C.split("/")[0]}class BF{adb;timer;constructor(c,d=v,h=i){this.adb=d.create(c),this.timer=h}parseActivities(c){let d=[],h=c.split(/\r?\n/),f=-1,P,C;for(let A=0;A<h.length;A++){let T=h[A],I=Vs(T);if(I)f=I.id,P=I.affinity,C=void 0,e.debug(`[BACK_STACK] Found task ID: ${f}`);let O=T.match(/affinity=([^\s]+)/);if(O)P=O[1],e.debug(`[BACK_STACK] Found task affinity: ${P}`);let x=Ws(T);if(x){let{histIndex:H,component:V}=x,q=x.taskId??f,K=V.split("/"),j=K[0],Y=K[1]||"";if(Y.startsWith("."))Y=j+Y;let X={name:Y,taskId:q,userId:x.userId,taskAffinity:P,isTaskRoot:H===0};d.push(X),C=X,e.debug(`[BACK_STACK] Found activity: ${Y} (task: ${q})`);continue}if(Us.test(T)){C=void 0;continue}let N=T.match($s);if(N&&C)C.isTaskRoot=N[1]==="true",C=void 0}return d}parseTasks(c){let d=new Map,h=c.split(/\r?\n/),f=-1,P={id:-1},C=new Map,A=new Map,T,I=()=>{if(f===-1||P.id===void 0)return;d.set(f,P)};for(let O=0;O<h.length;O++){let x=h[O],N=Vs(x);if(N)I(),f=N.id,P=d.get(f)??{id:f},Yu(P,N),T=void 0,e.debug(`[BACK_STACK] Parsing task: ${f}`);if(f===-1)continue;T=Xu(x,f,C,{histRoots:A,openHist:T}),T=Ju(x,A,T),Qu(P,x)}I();for(let O of d.values())Zu(O,C,A);return Array.from(d.values())}getCurrentActivity(c,d){let h=hw(c,d);if(h.displayCount>0)return h.activity?{name:h.activity.activityName,taskId:h.activity.taskId,userId:h.activity.userId}:void 0;let f=c.split(/\r?\n/);for(let P of f){let C=P.match(/(mResumedActivity|mFocusedActivity|topResumedActivity)\s*[:=].*?u(\d+)\s+([^\s]+)(?:\s+t(\d+))?/);if(C){let A=parseInt(C[2],10),T=C[3],I=C[4]?parseInt(C[4],10):-1,O=T.split("/"),x=O[0],N=O[1]||"";if(N.startsWith("."))N=x+N;return e.debug(`[BACK_STACK] Current activity: ${N} (task: ${I})`),{name:N,taskId:I,userId:A}}}return}async execute(c=new B,d,h=0){let f=this.timer.now();try{e.info("[BACK_STACK] Fetching back stack information via dumpsys");let P=await c.track("dumpsysActivities",()=>this.adb.executeCommand("shell dumpsys activity activities",{maxBuffer:oe,signal:d})),[C,A,T]=await c.track("parseBackStack",()=>Promise.all([Promise.resolve(this.parseActivities(P.stdout)),Promise.resolve(this.parseTasks(P.stdout)),Promise.resolve(this.getCurrentActivity(P.stdout,h))]));Bs(A,Hs(P.stdout));let I=T?.taskId||-1,O=C.filter((V)=>V.taskId===I),x=Math.max(0,O.length-1),N={depth:x,activities:C,tasks:A,currentActivity:T,displayCount:hw(P.stdout).displayCount,currentTaskId:I,capturedAt:this.timer.now(),source:"adb"},H=this.timer.now()-f;return e.info(`[BACK_STACK] Back stack retrieved in ${H}ms: depth=${x}, activities=${C.length}, tasks=${A.length}, currentActivity=${T?.name||"unknown"}`),N}catch(P){let C=this.timer.now()-f;return e.warn(`[BACK_STACK] Failed to get back stack after ${C}ms: ${P}`),{depth:0,activities:[],tasks:[],capturedAt:this.timer.now(),partial:!0,source:"adb"}}}}var ep=(c)=>{if(c.platform==="android")return k.getExistingInstance(c.deviceId)?.getBoundSessionId()??null;if(c.platform==="ios")return _.getExistingInstance(c.deviceId)?.getBoundSessionId()??null;return null};function tp(c=ep){return(d)=>{let h=d?c(d):null;return h?me.getInstanceForSession(h):me.getInstance()}}var vV=tp();function QA(c){if(!c||Object.keys(c).length===0)return"";return Cr(rp(c))}function Yi(c){let d=c?.trim();return d?d.toLowerCase():void 0}function rp(c){let d={...c};return delete d.deviceId,delete d.sessionUuid,d}class $F{db;timer;constructor({db:c,timer:d=i}={}){this.timer=d,this.db=c??null}getDb(){if(this.db)return this.db;return ke()}async recordOutcome(c){let d=this.getDb(),h=$r(this.timer),f=QA(c.toolArgs??void 0),P={app_id:c.appId,prediction_id:c.predictionId,timestamp:c.timestamp,from_screen:c.fromScreen,predicted_screen:c.predictedScreen,actual_screen:c.actualScreen,tool_name:c.toolName,tool_args:f,predicted_elements:c.predictedElements.length>0?JSON.stringify(c.predictedElements):null,found_elements:c.foundElements.length>0?JSON.stringify(c.foundElements):null,confidence:c.confidence,match_score:c.matchScore,correct:c.correct?1:0,partial_match:c.partialMatch?1:0,error_type:c.errorType??null,created_at:h};await d.insertInto("prediction_outcomes").values(P).execute(),await this.upsertTransitionStats({appId:c.appId,fromScreen:c.fromScreen,toScreen:c.predictedScreen,toolName:c.toolName,toolArgs:c.toolArgs},c.confidence,c.correct)}async upsertTransitionStats(c,d,h){let f=this.getDb(),P=$r(this.timer),C=QA(c.toolArgs??void 0),A=Math.pow(d-(h?1:0),2),T=h?1:0,I={app_id:c.appId,from_screen:c.fromScreen,to_screen:c.toScreen,tool_name:c.toolName,tool_args:C,attempts:1,successes:T,total_confidence:d,brier_score_sum:A,updated_at:P,created_at:P};return await f.insertInto("prediction_transition_stats").values(I).onConflict((x)=>x.columns(["app_id","from_screen","to_screen","tool_name","tool_args"]).doUpdateSet((N)=>({attempts:N("prediction_transition_stats.attempts","+",1),successes:N("prediction_transition_stats.successes","+",T),total_confidence:N("prediction_transition_stats.total_confidence","+",d),brier_score_sum:N("prediction_transition_stats.brier_score_sum","+",A),updated_at:P}))).returningAll().executeTakeFirstOrThrow()}async getTransitionStatsForScreen(c,d){return this.getDb().selectFrom("prediction_transition_stats").selectAll().where("app_id","=",c).where("from_screen","=",d).execute()}}class yi{tapByText=new Map;tapById=new Map;swipeByText=new Map;swipeById=new Map;swipeByDesc=new Map;constructor(c){c.forEach((d,h)=>{let f=d.interaction?.toolName;if(f==="tapOn")this.indexTapEdge(d,h);else if(f==="swipeOn")this.indexSwipeEdge(d,h)})}indexTapEdge(c,d){let h=c.interaction?.args;this.addKey(this.tapByText,Yi(h?.text),c,d),this.addKey(this.tapById,Yi(h?.elementId??h?.id),c,d)}indexSwipeEdge(c,d){let f=c.interaction?.args?.container||c.interaction?.uiState?.scrollPosition?.container;if(!f)return;this.addKey(this.swipeByText,Yi(f.text),c,d),this.addKey(this.swipeById,Yi(f.elementId||f.resourceId),c,d),this.addKey(this.swipeByDesc,Yi(f.contentDesc),c,d)}addKey(c,d,h,f){if(!d||c.has(d))return;c.set(d,{edge:h,index:f})}findMatch(c){let d=Yi(c.text),h=Yi(c.contentDesc),f=Yi(c.resourceId),P,C=(A)=>{if(A&&(!P||A.index<P.index))P=A};if(c.clickable){if(d)C(this.tapByText.get(d));if(h)C(this.tapByText.get(h));if(f)C(this.tapById.get(f))}if(c.scrollable){if(d)C(this.swipeByText.get(d));if(h)C(this.swipeByText.get(h)),C(this.swipeByDesc.get(h));if(f)C(this.swipeById.get(f))}return P?.edge}}class gi{resolveNavigationGraph;elementParser;historyRepository;DEFAULT_CONFIDENCE=0.5;constructor(c=vV,d={}){this.resolveNavigationGraph=c;this.elementParser=d.elementParser??new G,this.historyRepository=d.historyRepository??new $F}async generate(c,d){if(!c.viewHierarchy)return;let h=this.resolveNavigationGraph(d),f=h.getCurrentScreen();if(!f)return;let P=h.getCurrentAppId();if(P&&c.activeWindow?.appId&&P!==c.activeWindow.appId)return;let A=(await h.getEdgesFrom(f)).filter((I)=>I.interaction?.toolName==="tapOn"||I.interaction?.toolName==="swipeOn");if(A.length===0)return;let T=this.extractInteractables(c.viewHierarchy);if(T.length===0)return;return this.buildPredictions(T,A,h,{currentScreen:f,appId:P})}async buildPredictions(c,d,h,{currentScreen:f,appId:P}){let C=[],A=[],T=new Set,I=new Map,O=P?await this.historyRepository.getTransitionStatsForScreen(P,f):[],x=new Map;for(let H of O){let V=this.buildTransitionKey(H.from_screen,H.to_screen,H.tool_name,H.tool_args);x.set(V,H)}let N=new yi(d);for(let H of c){let V=N.findMatch(H);if(!V||!V.interaction)continue;let q=ip(V,H);if(!q)continue;let K=this.buildEdgeKey(V);if(!T.has(K)){let j=await this.getPredictedElements(h,V.to,I),Y=this.getAdjustedConfidence(x.get(this.buildTransitionKey(f,V.to,V.interaction.toolName,QA(V.interaction.args))));C.push({action:V.interaction.toolName,target:q,predictedScreen:V.to,predictedElements:j.length>0?j:void 0,confidence:Y}),T.add(K)}A.push({elementId:H.resourceId,elementText:H.text,elementContentDesc:H.contentDesc,predictedOutcome:{screenName:V.to,basedOn:"navigation_graph"}})}if(C.length===0&&A.length===0)return;return{likelyActions:C,interactableElements:A}}extractInteractables(c){if(!c)return[];let d=this.elementParser.flattenViewHierarchy(c),h=[];for(let{element:f}of d){let P=f.clickable===!0||f.clickable==="true",C=f.scrollable===!0||f.scrollable==="true";if(!P&&!C)continue;h.push({element:f,text:f.text,contentDesc:f["content-desc"],resourceId:f["resource-id"],clickable:P,scrollable:C})}return h}buildEdgeKey(c){let d=c.interaction?.args??{};return`${c.from}:${c.to}:${c.interaction?.toolName}:${JSON.stringify(d)}`}buildTransitionKey(c,d,h,f){return`${c}:${d}:${h}:${f}`}getAdjustedConfidence(c){if(!c)return this.DEFAULT_CONFIDENCE;let d=c.attempts,h=d>0?c.successes/d:this.DEFAULT_CONFIDENCE;return this.adjustConfidence(this.DEFAULT_CONFIDENCE,h,d)}adjustConfidence(c,d,h){let f=Math.min(h/100,0.8),P=1-f,C=c*P+d*f;return Math.max(0,Math.min(1,C))}async getPredictedElements(c,d,h){if(h.has(d))return h.get(d)??[];let f=await c.getEdgesFrom(d),P=new Set;for(let A of f){let T=A.interaction?.uiState?.selectedElements;if(!T)continue;for(let I of T){let O=I.text||I.resourceId||I.contentDesc;if(O)P.add(O)}}let C=Array.from(P);return h.set(d,C),C}}function ip(c,d){let h=c.interaction?.args,f=c.interaction?.uiState,P=c.interaction?.toolName;if(P==="tapOn")return np(h,d);if(P==="swipeOn")return sp(h,f);return null}function np(c,d){let h=c?.text??d.text,f=c?.elementId??c?.id??d.resourceId,P=d.contentDesc;if(!h&&!f&&!P)return null;return{text:h,elementId:f,contentDesc:P}}function sp(c,d){let{container:h,lookFor:f}=ap(c,d),P={};if(h)P.container=Gs(h);if(f)P.lookFor=Gs(f);if(!P.container&&!P.lookFor)return null;return P}function ap(c,d){let h=c?.container||d?.scrollPosition?.container,f=c?.lookFor||d?.scrollPosition?.targetElement;return{container:h,lookFor:f}}function Gs(c){return{text:c.text,elementId:c.elementId||c.resourceId,contentDesc:c.contentDesc}}class vi{inner;timer;observeBudgetMs;constructor(c,d,h=750){this.inner=c;this.timer=d;this.observeBudgetMs=h}async read(c,d){let h=Error("iOS lock-state reading pending");try{return await l(()=>this.inner.read(c),{timer:this.timer,signal:d,timeoutMs:this.observeBudgetMs,label:"iOS lock-state observation",timeoutError:()=>h})}catch(f){if(d?.aborted)return e.debug("[iOS] Lock-state caller aborted"),{kind:"unknown",reason:"pending",message:"caller aborted"};if(f===h)return e.debug("[iOS] Lock-state probe still pending after observe budget"),{kind:"unknown",reason:"pending"};return e.warn(`[iOS] Budgeted lock-state probe failed: ${r(f)}`,f),{kind:"unknown",reason:"error",message:r(f)}}}}class bi{inner;timer;options;entries=new Map;settling=new Set;epochs=new Map;constructor(c,d,h={}){this.inner=c;this.timer=d;this.options=h}invalidate(c){this.entries.delete(c),this.settling.add(c),this.epochs.set(c,(this.epochs.get(c)??0)+1)}async read(c,d){try{return await l(()=>this.sharedRead(c),{timer:this.timer,signal:d,label:"iOS lock-state cache"})}catch(h){if(d?.aborted)return e.debug("[iOS] Lock-state cache caller aborted"),{kind:"unknown",reason:"pending",message:"caller aborted"};return e.warn(`[iOS] Lock-state cache failed: ${r(h)}`,h),{kind:"unknown",reason:"error",message:r(h)}}}sharedRead(c){let d=this.entries.get(c);if(d?.reading){if(this.timer.now()<d.expiresAt){let f=d.reading.kind==="known"?void 0:this.staleReading(d);return Promise.resolve(f??d.reading)}}if(!d?.flight)d={expiresAt:0,epoch:this.epochs.get(c)??0,lastKnown:d?.lastKnown},this.entries.set(c,d),d.flight=this.fill(c,d);let h=this.staleReading(d);return h?Promise.resolve(h):d.flight}staleReading(c){let d=c.lastKnown;if(!d)return;let h=d.lock.locked?this.options.staleLockedMs??1e4:this.options.staleUnlockedMs??120000;return this.timer.now()-d.staleSince<h?{kind:"known",lock:d.lock}:void 0}async fill(c,d){let h;try{h=await Je(async()=>this.inner.read(c))}catch(f){e.warn(`[iOS] Shared lock-state probe failed: ${r(f)}`,f),h={kind:"unknown",reason:"error",message:r(f)}}if((this.epochs.get(c)??0)===d.epoch){let f=this.options.failureTtlMs??5000;if(h.kind==="known"){if(f=h.lock.locked?this.options.lockedTtlMs??2000:this.options.knownTtlMs??30000,this.settling.delete(c))f=Math.min(f,this.options.settleTtlMs??2000)}if(d.reading=h,d.expiresAt=this.timer.now()+f,h.kind==="known")d.lastKnown={lock:h.lock,staleSince:d.expiresAt};d.flight=void 0}return h}}var cp;function Xl(){return cp??=new bi(new zA(new F,{timeoutMs:4000}),i)}var lp={getViewHierarchy:async()=>({hierarchy:{error:"Hierarchy connection unavailable",unavailableReason:"connection_lost"}}),configureRecompositionTracking:async()=>{},findFocusedElement:()=>null,findAccessibilityFocusedElement:()=>null,filterOffscreenNodes:(c)=>c};function ae(c,d){return c??d()}function qs(c,d,h){return c?d():h()}function Ks(c){let{device:d,adbFactory:h,dependencies:f}=c;return ae(f?.viewHierarchy,()=>qs(f?.deviceReadOnly,()=>lp,()=>new Vi(d,h)))}function dp(c){let{device:d,adbFactory:h,timer:f,idGenerator:P,wiring:C,dependencies:A}=c,T=A?.deviceReadOnly;return{hierarchyCapture:ae(A?.hierarchyCapture,()=>C.createHierarchyCapture(f,P)),screenshotService:ae(A?.screenshot,()=>qs(T,()=>_o.forObservationRead(d),()=>new _o(d,{adbFactory:h}))),window:ae(A?.window,()=>new pl(d,h)),backStack:ae(A?.backStack,()=>new BF(d,h)),predictiveUIState:ae(A?.predictiveUIState,()=>new gi)}}function up(c,d){let{wiring:h,dependencies:f}=c,P=f?.screenshotPathProtection??Mn;return{pathProtection:P,screenshotRecorder:ae(f?.screenshotRecorder,()=>h.createScreenshotRecorder(d.screenshotService,P)),screenshotEvidenceFiles:f?.screenshotEvidenceFiles}}function pp(c,d){let{wiring:h,dependencies:f}=c;return{hierarchyCollector:ae(f?.hierarchyCollector,()=>h.createHierarchyCollector(f)),deviceStateCollector:ae(f?.deviceStateCollector,()=>h.createDeviceStateCollector(d.window,d.backStack)),iosLockStateProbe:ae(f?.iosLockStateProbe,()=>new vi(Xl(),c.timer)),performanceAuditor:ae(f?.performanceAuditor,()=>h.createPerformanceAuditor()),accessibilityAuditor:ae(f?.accessibilityAuditor,()=>h.createAccessibilityAuditor()),accessibilityStateDetector:ae(f?.accessibilityStateDetector,()=>h.createAccessibilityStateDetector()),platformValidator:ae(f?.platformValidator,()=>new mr),windowIdentity:ae(f?.windowIdentityFreshnessResolver,()=>h.createWindowIdentity()),reconciler:ae(f?.activeWindowAttributionReconciler,()=>h.createReconciler())}}function mp(c,d){return Ms(c.dependencies),{...up(c,d),...pp(c,d)}}function zs(c){let d=dp(c);return{sources:d,services:mp(c,d)}}var js={screenSizeUnits:()=>"physical-pixels",settledScreenshotOrientation:()=>"display",isIosMultiPanel:()=>!1,grantsObservationRead:(c)=>c.viewHierarchy?.fresh===!0},hp={...js,grantsObservationRead:()=>!0};function fp(c){return{screenSizeUnits:()=>"points",settledScreenshotOrientation:()=>"native",isIosMultiPanel:()=>(c().displays?.panels.length??0)>1,grantsObservationRead:(d)=>wo(d.viewHierarchy)}}function Ys(c,d){if(c==="ios")return fp(d);return c==="android"?js:hp}function Si(c,d,h){let{result:f,displayRequest:P}=d,C=P!==void 0&&P!=="active",A=C?sn(c.displays,P,{activePanelKey:h?.display.key,posture:f.display.posture}):void 0;return{explicitlyRouted:C,requestedPanel:A}}function Qs(c,d,h,f){if(h)return;if(xe.checkIdentity(c,d.display,"ios"),f)xe.checkIosGeometry(c,d.screenSize,d.observationId,d.display)}function yp(c){return Boolean(c.viewHierarchy?.hierarchy?.error||c.viewHierarchy?.hierarchy?.unavailableReason||c.viewHierarchy?.ctrlProxyIncomplete&&!c.viewHierarchy.hierarchy?.node)}function gp(c,d){let h=c.viewHierarchy?.hierarchy;if(d!==0&&(h?.error||h?.unavailableReason))return new Vn(h.unavailableDetail??h.error??"Selected display hierarchy is unavailable");return new Vn("CtrlProxy APK too old for display routing; update it and retry the observation.")}function vp({result:c,requestedPanel:d,requestedDisplayId:h,preserveDisplayState:f},P,C){if(h!==void 0&&typeof P!=="number"&&!C&&!(f&&yp(c)))throw gp(c,h);if(h!==void 0&&typeof P==="number"&&P!==h)throw new Vn(`Selected display "${d?.key}" returned hierarchy for display ${P}; retry the observation.`)}function bp(c,d){if(c&&d&&c.key!==d.key)throw new Vn(`Selected display "${c.key}" returned content from "${d.key}"; retry the observation.`)}class wi{deps;constructor(c){this.deps=c}resolveTarget(c){return this.resolveTargetAsync(c)}async resolveTargetAsync(c){let{result:d,androidDisplayCache:h,signal:f}=c,P=this.deps.device(),C=this.deps.adb(),A=await h.resolve(P,C,f);if(A)d.display=A.display;let{explicitlyRouted:T,requestedPanel:I}=Si(P,c,A),O=I?await h.logicalIdForPanel(P,C,I.key,f):void 0;if(I)d.display={...d.display,key:I.key,role:I.role};return{observedAndroid:A,explicitlyRouted:T,requestedPanel:I,requestedDisplayId:O}}bindFinalDisplay(c){if(!this.deps.device().displays?.panels.length)return{recordProvenance:c.recordProvenance};return this.bindFinalDisplayAsync(c)}async bindFinalDisplayAsync(c){let{result:d,androidDisplayCache:h,observedAndroid:f,requestedPanel:P,explicitlyRouted:C,signal:A}=c,T=c.recordProvenance,I=this.deps.device(),O=this.deps.adb(),x=d.viewHierarchy?.displayId,N=d.viewHierarchy?.panelUniqueId;vp(c,x,N);let H=typeof x==="number"||N?await h.panelForLogicalId(I,O,x,{signal:A,identity:{panelUniqueId:N,panelFingerprint:d.viewHierarchy?.panelFingerprint},allowProbe:C}):void 0;bp(P,H);let V=xe.geometryChanged(I.deviceId,d.screenSize),q=V&&!C?await h.resolve(I,O,A,!0):f;return d.display.posture=await h.posture(I,O,A,V&&!C),this.applyBoundPanel(c,I,H?.key,q?.display.key),T=this.recordFinalIdentity(c,I,T),{recordProvenance:T}}applyBoundPanel({result:c,displayRequest:d,requestedPanel:h},f,P,C){let A=h??sn(f.displays,d,{focusedPanelKey:P,activePanelKey:C,posture:c.display.posture});c.display={...c.display,key:A.key,role:A.role}}recordFinalIdentity({result:c,explicitlyRouted:d,preserveDisplayState:h,observerMode:f},P,C){if(!d&&!h&&!f&&xe.revision(P.deviceId)===C.revision)xe.checkIdentity(P.deviceId,c.display),C={revision:xe.revision(P.deviceId),identityRevision:xe.identityRevision(P.deviceId)};return C}}class Ri{deps;constructor(c){this.deps=c}resolveTarget(c){let{explicitlyRouted:d,requestedPanel:h}=Si(this.deps.device(),c,void 0);return{observedAndroid:void 0,explicitlyRouted:d,requestedPanel:h,requestedDisplayId:void 0}}bindFinalDisplay(c){let{result:d,displayRequest:h,explicitlyRouted:f,preserveDisplayState:P,observerMode:C}=c,A=c.recordProvenance,T=this.deps.device();if(d.display=hD(T,d.viewHierarchy,vz(d)),!C&&!P&&xe.revision(T.deviceId)===A.revision)Qs(T.deviceId,d,f,(T.displays?.panels.length??0)>1),A={revision:xe.revision(T.deviceId),identityRevision:xe.identityRevision(T.deviceId)};let I=sn(T.displays,h,{focusedPanelKey:d.display.key,activePanelKey:d.display.key,posture:d.display.posture});if(f&&I.key!==d.display.key)throw new Vn(`Display "${I.key}" is not the active panel on iOS. Active panel: ${d.display.key}`);return{recordProvenance:A}}}var Zs=new Set(["com.android.permissioncontroller","com.google.android.permissioncontroller"]),ea="android.permission.POST_NOTIFICATIONS";function Pi(c){return c!==void 0&&Zs.has(c)}function G4(c){return Pi(c)||c!==void 0&&/permissioncontroller/i.test(c)}function Sp(c,d){return c===d||c.startsWith(`${d}.`)}function bV(c){if(!c||!Pi(c.appId)||c.activityName==="")return c;return[...Zs].some((h)=>Sp(c.activityName,h))?c:{...c,activityName:""}}function wp(c){let d=c.text??c["content-desc"];return typeof d==="string"&&d.trim()!==""?d.trim():void 0}function Rp(c,d){if(c.enabled!==void 0&&!gt(c.enabled))return!1;if(c.package!==void 0&&c.package!==d)return!1;let h=c["resource-id"]??"",f=typeof c.class==="string"?c.class:"";return/button/i.test(h)||/Button$/.test(f)}function Pp(c,d){let h=(c.elements?.clickable??[]).filter((f)=>Rp(f,d)).map(wp).filter((f)=>f!==void 0);return[...new Set(h)]}function AQ(c,d){let h=Cp(d);if(!d||!h||h===c)return;let f=Ap(d);if(!(f?G4(h):Pi(h)))return;return{kind:"permission_dialog",packageName:h,...f?{permission:ea}:{},actions:Pp(d,h)}}function Cp(c){return c?.activeWindow?.appId||c?.viewHierarchy?.packageName}function Ap(c){return c.notificationPermissionDetected===!0||c.activeWindow?.type==="notification_permission_dialog"}function TQ(c){let d=c.permission===ea?"a notification permission dialog":"a permission dialog",h=c.actions.length>0?`tap ${c.actions.map((f)=>`"${f}"`).join(" or ")}`:"answer it with tapOn";return`blocked by ${d} (${c.packageName}); ${h}, or pre-grant with setAppPermissions`}var Tp=1;function ta(c){if(typeof c!=="string")return;let d=c.trim();return d.length>0?d:void 0}function Ip(c,d){let h=new Set(Z5(c).map((C)=>C.id)),f=(op(c.hierarchy,c.windows)??[]).filter((C)=>C.type===Tp&&C.hierarchy!==void 0&&(C.packageName===void 0||C.packageName===d)&&!h.has(C.id)),P=f.toSorted((C,A)=>(A.windowLayer??0)-(C.windowLayer??0))[0];return(f.find((C)=>C.isFocused)??f.find((C)=>C.isActive)??P)?.hierarchy}function kp(c){let d=[c];while(d.length>0){let h=d.shift(),f=ta(Se(h)["pane-title"]);if(f)return f;let P=h.node;if(P)d.unshift(...Array.isArray(P)?P:[P])}return}function SV(c,d){let h=ta(c?.packageName);if(!c||!h)return;if(d?.platform==="android"&&d.source==="sdk"&&d.components.bundleId===h)return d;let f=Ip(c,h),P=f?kp(f):void 0;if(!P)return;return{platform:"android",source:"heuristic",confidence:"medium",key:JSON.stringify([["package",h],["paneTitle",P]]),components:{bundleId:h,navigationTitle:P}}}function Ci(c){if((c.backStack?.displayCount??0)>1&&c.activeWindow){let d=Me(c);if(d)c.activeWindow={...c.activeWindow,appId:d.packageName,activityName:d.activityName}}}function Dp(c){let d=c.viewHierarchy,h=d?.packageName,f=c.activeWindow?.appId,P=d?.sources?.length===1&&d.sources[0]==="uiautomator";if(!h||!f||!P||!c.activeWindow)return!1;return c.activeWindow={...c.activeWindow,appId:h,activityName:""},!0}class Ti{deps;constructor(c){this.deps=c}async collect(c){let{result:d,queryOptions:h,perf:f,skipWaitForFresh:P,minTimestamp:C,signal:A,readOnly:T,capturedHierarchy:I,readOptions:O}=c;f.serial("phase1_hierarchy"),await this.deps.hierarchyCollector().collect(d,{queryOptions:h,perf:f,skipWaitForFresh:P,minTimestamp:C,signal:A,readOnly:T,capturedHierarchy:I,readOptions:O}),f.end();let x=d.viewHierarchy;if(x?.screenWidth&&x?.screenHeight){d.screenSize={width:x.screenWidth,height:x.screenHeight},this.applyHierarchyDeviceMetadata(d,x);let N=this.startDeviceStateTasks(c,!x.wakefulness);if(N.length>0)await Promise.all(N);e.debug("[OBSERVE] Using device metadata from accessibility service")}else this.applyKnownPanelScreenSize(d),await Promise.all(this.startDeviceStateTasks(c,!0));if(!d.activeWindow)await this.deps.deviceStateCollector().collectActiveWindow(d,T);if(this.backfillActiveWindowPackage(d),Ci(d),await this.applyAndroidScreenIdentity(d),d.activeWindow=bV(d.activeWindow),this.deps.device().formFactor==="automotive")await this.deps.deviceStateCollector().collectAutomotive(d,A,c.displayId);if(d.notificationPermissionDetected&&d.activeWindow)d.activeWindow.type="notification_permission_dialog"}applyHierarchyDeviceMetadata(c,d){if(d.rotation!==void 0)c.rotation=d.rotation;if(d.systemInsets)c.systemInsets=d.systemInsets;if(d.insets)c.insets=d.insets;if(d.foregroundActivity&&!Pr(d.foregroundActivity))this.applyAndroidForegroundActivity(c,d.foregroundActivity)}startDeviceStateTasks({result:c,perf:d,signal:h,skipBackStack:f,displayId:P},C){let A=[];if(C)A.push(d.track("wakefulness",()=>this.deps.deviceStateCollector().collectWakefulness(c,h)));else c.wakefulness=c.viewHierarchy?.wakefulness,c.wakefulnessSource="hierarchy";if(A.push(d.track("deviceLock",()=>this.deps.deviceStateCollector().collectDeviceLock(c,h))),!f)A.push(d.track("backStack",()=>this.deps.deviceStateCollector().collectBackStack(c,d.fork(),h,P)));return A}backfillActiveWindowPackage(c){if(Dp(c))return;if(c.viewHierarchy?.packageName&&!c.activeWindow?.appId)c.activeWindow=c.activeWindow?{...c.activeWindow,appId:c.viewHierarchy.packageName}:{appId:c.viewHierarchy.packageName,activityName:"",layoutSeqSum:0}}async applyAndroidScreenIdentity(c){let d=c.viewHierarchy?.packageName;if(!d)return;let h;try{h=await this.deps.viewHierarchy().getScreenIdentity?.(d)}catch(P){e.debug(`[Android] SDK screen identity read failed; using hierarchy identity: ${r(P)}`)}let f=SV(c.viewHierarchy,h);if(f)c.screenIdentity=f}applyAndroidForegroundActivity(c,d){let h=d.split("/"),f=h[0],P=h[1]?.startsWith(".")?f+h[1]:h[1]||"";c.activeWindow={appId:f,activityName:P,layoutSeqSum:0}}applyKnownPanelScreenSize(c){if(e.warn("[OBSERVE] No screen dimensions from accessibility service"),c.screenSize.width>0&&c.screenSize.height>0)return;let d=this.deps.device(),h=c.display?.key,f=h?d.displays?.panels.find((P)=>P.key===h):sn(d.displays,"active",{focusedPanelKey:xe.observedPanel(d.deviceId)?.key});if(!f){e.warn(`[OBSERVE] Display ${h} is not in the display inventory; leaving screen size unknown`);return}if(f.sizePx.width>0&&f.sizePx.height>0)c.screenSize={...f.sizePx}}}var Op="sdkBridge",ra="sdk-element-id";function Qy(c){let d=c[ra],h=Number(c[tC]);if(typeof d!=="string"||d.length===0||!Number.isSafeInteger(h))return null;return{elementId:d,observationIdentity:h}}function oC(c,d){let h=c?.hierarchy?.node,f=Array.isArray(h)?[...h]:h&&typeof h==="object"?[h]:[];for(let P=f.pop();P;P=f.pop()){let C=Qy(Se(P));if(C&&(d===void 0||C.elementId===d))return C;f.push(...Rl(P))}return null}function ia(c,d){if(!c.visible)return null;let h=c.enabled,f=c.role.toLowerCase()==="textfield",P={"resource-id":c.id,"test-tag":c.id,class:c.role,role:f?"textfield":c.role,...f?{focusable:"true","input-type":"text",actions:["set_text"]}:{},bounds:{...c.bounds},enabled:String(c.enabled),[ra]:c.id,[tC]:String(d),...c.label!==void 0?{"content-desc":c.label}:{},...c.value!==void 0?{text:c.value}:{},...h?{clickable:"true"}:{},...c.focused?{focused:"true"}:{}},C=c.children.map((A)=>ia(A,d)).filter((A)=>A!==null);return{$:P,extras:{"sdk.source":Op},...C.length>0?{node:C}:{}}}function Ye(c){if(c===null||typeof c!=="object")return null;let{left:d,top:h,right:f,bottom:P}=c;if([d,h,f,P].some((C)=>typeof C!=="number"))return null;return`${d},${h},${f},${P}`}function oa(c,d){if(!c.visible)return;let h=Ye(c.bounds);if(h){for(let f of[c.id,c.label,c.value])if(f)d.add(`${h}|${f}`)}for(let f of c.children)oa(f,d)}function xp(c,d){if(Rl(c).length>0)return!1;let h=Ye(Ft(c));if(!h)return!1;let f=Se(c);return["resource-id","content-desc","text"].some((P)=>{let C=f[P];return typeof C==="string"&&C.length>0&&d.has(`${h}|${C}`)})}function sa(c,d){let h=Rl(c);if(h.length===0)return 0;let f=h.filter((C)=>!xp(C,d)),P=h.length-f.length;c.node=f;for(let C of f)P+=sa(C,d);return P}function aa(c){return 1+Rl(c).reduce((d,h)=>d+aa(h),0)}function ca(c,d){let h=c.hierarchy?.node;if(!h||!d.root||d.coordinateSpace!=="screen")return null;let f=ia(d.root,d.captureIdentity);if(!f)return null;let P=new Set;oa(d.root,P);let C=sa(h,P);return h.node=[...Rl(h),f],{attached:aa(f),deduplicated:C}}var Ii=2000;function Ep(c){let d=c.enabled??(()=>M.isIosSdkObservationBridgeEnabled()),h=c.timer??i,f=(P)=>P.failure??P.error??"no observation";return{async observe(P,C,A=1/0){let T=h.now()+Math.max(0,A),I=()=>Math.max(0,Math.min(Ii,T-h.now())),O=d()?c.client():null;if(!O||I()<=0)return{kind:"none"};let x;try{x=await O.getObservationBridgeStateForIos(P,I())}catch(V){return e.debug(`[iOS] SDK bridge discovery failed; observing with XCTest: ${r(V)}`),{kind:"none"}}if(x.status!=="available")return e.debug(`[iOS] SDK bridge unavailable for ${P}: ${x.reason}`),{kind:"none"};if(I()<=0)return{kind:"unavailable",detail:"search budget exhausted"};let N;try{N=await O.requestSdkObservationForIos({timeoutMs:I(),signal:C})}catch(V){return e.warn(`[iOS] SDK bridge snapshot failed for ${P}: ${r(V)}`,V),{kind:"unavailable",detail:r(V)}}if(ek(N),N.success&&N.observation)return{kind:"observation",observation:N.observation};let H=f(N);return e.warn(`[iOS] SDK bridge snapshot unavailable for ${P}: ${H}`),{kind:"unavailable",detail:H}}}}function wV(c,d){return Ep({client:()=>_.getExistingInstance(c.deviceId),timer:d})}async function RV(c,d,h,f){let P=c.packageName;if(!P)return{};let C=await d.observe(P,h,f);if(C.kind==="none")return{};if(C.kind==="observation"&&C.observation.bundleId!==void 0&&C.observation.bundleId!==P)return e.debug(`[iOS] SDK snapshot app ${C.observation.bundleId} differs from hierarchy app ${P}; skipping merge`),{backend:"xctest",fallbackReason:"unavailable"};let A=C.kind==="observation"?ca(c,C.observation):null;if(A)return kz(c),e.debug(`[iOS] Merged ${A.attached} SDK bridge nodes (${A.deduplicated} XCTest duplicates removed)`),{backend:"sdk"};return{backend:"xctest",fallbackReason:"unavailable"}}var Mp="sdkWebBridge",la="web-view-id";var da="web-element-id",Fp="web-origin",ua="web-document-id",pa="web-role",_p=new Set(["input","textarea"]);function kQ(c){let d=c[pa],h=typeof d==="string"&&_p.has(d)?PV(c):null;return h?.documentId?h:null}var Np=new Set(["input","textarea","textbox","searchbox","combobox"]),Hp=new Set(["text","search","email","url","tel","password","number"]);function Bp(c,d){if(d!=="input")return Np.has(d);return Hp.has((c.inputType??"text").toLowerCase())}var Vp="[REDACTED]",Lp="WKWebView";function PV(c){let d=c[la],h=c[rC],f=c[da];if(typeof d!=="string"||typeof h!=="string"||typeof f!=="string"||!d||!h||!f)return null;let P=c[ua];return typeof P==="string"&&P?{webViewId:d,snapshotId:h,elementId:f,documentId:P}:{webViewId:d,snapshotId:h,elementId:f}}function EQ(c,d,h){let f=c?.hierarchy?.node,P=Array.isArray(f)?[...f]:f&&typeof f==="object"?[f]:[];for(let C=P.pop();C;C=P.pop()){let A=PV(Se(C));if(A&&A.webViewId===d&&A.elementId===h)return A;P.push(...Rl(C))}return null}function Wp(c){if(c===null||typeof c!=="object")return null;let{left:d,top:h,right:f,bottom:P}=c;if(typeof d!=="number"||typeof h!=="number"||typeof f!=="number"||typeof P!=="number")return null;return{left:d,top:h,right:f,bottom:P}}function Up(c){let d=Se(c);return(d.class??d.className)===Lp}function UF(c){let d=[],h=(C)=>{if(Up(C)){d.push(C);return}Rl(C).forEach(h)},f=c?.hierarchy?.node;return(Array.isArray(f)?f:f&&typeof f==="object"?[f]:[]).forEach(h),d}function $p(c){if(!c||!URL.canParse(c))return;let d=new URL(c).origin;return d==="null"?void 0:d}function Gp(c,d){if(!(c!==void 0&&[c.offsetLeft,c.offsetTop,c.width].every(Number.isFinite)&&c.width>0))return{offsetLeft:0,offsetTop:0,pointsPerPixel:1};return{offsetLeft:c.offsetLeft,offsetTop:c.offsetTop,pointsPerPixel:(d.right-d.left)/c.width}}function qp(c,d,h){let[f,P,C,A]=c.bounds;if([f,P,C,A].some((V)=>V===void 0||!Number.isFinite(V)))return null;let T=d.left+(f-h.offsetLeft)*h.pointsPerPixel,I=d.top+(P-h.offsetTop)*h.pointsPerPixel,O=Math.trunc(Math.max(d.left,T)),x=Math.trunc(Math.max(d.top,I)),N=Math.trunc(Math.min(d.right,T+C*h.pointsPerPixel)),H=Math.trunc(Math.min(d.bottom,I+A*h.pointsPerPixel));return N>O&&H>x?{left:O,top:x,right:N,bottom:H}:null}function Kp(c){let d=new Set,h=new Set;for(let{id:f}of c)(d.has(f)?h:d).add(f);return h}function zp(c,d){if(c.value!==Vp)return c.value?{text:c.value}:{};return typeof d?.value==="string"?{}:{[Hk]:"true"}}function jp(c,d,h,{origin:f,native:P}={}){let C=c.role??"element",A=Bp(c,C);return{$:{class:C,role:A?"textfield":C,...A?{focusable:"true","input-type":"text"}:{},enabled:String(c.enabled),...c.label?{"content-desc":c.label}:{},...zp(c,P),...c.enabled?{clickable:"true"}:{},...c.focused&&!P?{focused:"true"}:{},...P,bounds:d,[la]:h.webViewId,[rC]:h.snapshotId,...h.documentId?{[ua]:h.documentId}:{},[da]:c.id,[pa]:C,...f?{[Fp]:f}:{}},extras:{"sdk.source":Mp}}}function Yp(c,d){let h=Ye(d);return h?[c.label,c.value].flatMap((f)=>f?[`${h}|${f}`]:[]):[]}function ma(c,d,h,f){let P=Rl(c);if(P.length===0)return 0;let C=0,A=P.flatMap((T)=>{let I=Rl(T).length===0?Xp(T,d):void 0;if(I===void 0)return C+=ma(T,d,h,f),[T];if(C+=1,f.has(I))return[];f.add(I);let O=Object.fromEntries(Object.entries(Se(T)).filter(([x])=>x!=="bounds"));return[h(I,O)]});return c.node=A,C}function Xp(c,d){let h=Ye(Ft(c));if(!h)return;let f=Se(c),P=new Set(["resource-id","content-desc","text"].flatMap((C)=>{let A=f[C],T=typeof A==="string"&&A?d.get(`${h}|${A}`):void 0;return T===void 0?[]:[T]}));return P.size===1?[...P][0]:void 0}function ha(c,d){let h=UF(c);if(d.length!==1||h.length!==1)return null;let f={webViews:0,attached:0,deduplicated:0};return h.forEach((P,C)=>{let{webViewId:A,snapshot:T}=d[C],I=Wp(Ft(P));if(!T||!I)return;let O=$p(T.url),x=Kp(T.elements),N=Gp(T.viewport,I),H=T.elements.flatMap((X)=>{let Z=X.id!==""&&!x.has(X.id),ne=X.visible&&Z?qp(X,I,N):null;return ne?[{element:X,bounds:ne}]:[]});if(H.length===0)return;let V=new Map,q=new Set;H.forEach(({element:X,bounds:Z},ne)=>{for(let J of new Set(Yp(X,Z)))if(V.has(J))q.add(J);else V.set(J,ne)}),q.forEach((X)=>V.delete(X));let K=(X,Z)=>{let{element:ne,bounds:J}=H[X],ee={webViewId:A,snapshotId:T.snapshotId,documentId:T.documentId};return jp(ne,J,ee,{origin:O,native:Z})},j=new Set;f.deduplicated+=ma(P,V,K,j);let Y=H.flatMap((X,Z)=>j.has(Z)?[]:[K(Z)]);P.node=[...Rl(P),...Y],f.webViews+=1,f.attached+=H.length}),f.webViews>0?f:null}async function Jp(c,d){try{return await c.requestSdkWebSnapshotForIos(d)}catch(h){return e.warn(`[iOS] SDK web-view snapshot failed: ${r(h)}`,h),null}}function Qp(c){let d=c.enabled??(()=>M.isIosSdkObservationBridgeEnabled()),h=c.timer??i;return{async snapshots(f,P=1/0){let C=h.now()+Math.max(0,P),A=()=>Math.max(0,Math.min(Ii,C-h.now())),T=d()?c.client():null;if(!T)return[];let I=A();if(I===0)return e.debug("[iOS] SDK web-view snapshot skipped: time budget exhausted"),[];let O=await Jp(T,{signal:f,timeoutMs:I});if(O&&!O.success&&O.failure==="bad_reply")e.warn(`[iOS] SDK web-view snapshot failed: ${O.error??O.failure}`);let x=O?.webViews??[];if(x.length>1)return x.map(({webViewId:N})=>({webViewId:N}));return x.map(({webViewId:N})=>({webViewId:N,...O?.success&&O.snapshot&&O.webViewId===N?{snapshot:O.snapshot}:{}}))}}}function eT(c,d){return Qp({client:()=>_.getExistingInstance(c.deviceId),timer:d})}async function AV(c,d,h,f){if(UF(c).length!==1)return null;let P=await d.snapshots(h,f),C=ha(c,P);if(C)kz(c),e.debug(`[iOS] Merged ${C.attached} DOM elements from ${C.webViews} web view(s) (${C.deduplicated} XCTest duplicates removed)`);else if(P.length>0)e.debug(`[iOS] ${P.length} registered web view(s) not merged: no snapshot, or no one-to-one WKWebView match`);return C}var Zp="com.apple.springboard";class ki{deps;constructor(c){this.deps=c}async collect({result:c,queryOptions:d,perf:h,skipWaitForFresh:f,minTimestamp:P,signal:C,readOnly:A,capturedHierarchy:T,readOptions:I}){h.serial("ios_collect"),await this.deps.hierarchyCollector().collect(c,{queryOptions:d,perf:h,skipWaitForFresh:f,minTimestamp:P,signal:C,readOnly:A,capturedHierarchy:T,readOptions:I});let O=await this.readLiveIosPanel(C);fre(c,O),this.dropHomeScreenOfOtherPanel(c,O),this.applyIosScreenMetadata(c),this.applyLiveIosPanelSize(c),this.applyIosInsetsAndRotation(c),this.projectIosObservationHierarchy(c),await this.mergeSdkBridgeObservation(c,C),await this.mergeSdkWebSnapshots(c,C);let x;try{x=await this.deps.viewHierarchy().getScreenIdentity?.(c.viewHierarchy?.packageName,c.viewHierarchy?.updatedAt)}catch(H){e.debug(`[iOS] SDK screen identity refresh failed; using hierarchy identity: ${H}`)}let N=Kw(c.viewHierarchy,c.screenSize);c.screenIdentity=N?.components.modalClass?N:x??N,h.end()}async mergeSdkBridgeObservation(c,d){if(!c.viewHierarchy)return;let h=this.deps.sdkBridge?.()??wV(this.deps.device()),f=await RV(c.viewHierarchy,h,d);if(f.backend)c.backend=f.backend;if(f.fallbackReason)c.fallbackReason=f.fallbackReason}async mergeSdkWebSnapshots(c,d){if(!c.viewHierarchy)return;let h=this.deps.sdkWeb?.()??eT(this.deps.device());if(await AV(c.viewHierarchy,h,d)&&!c.backend)c.backend="sdk"}dropHomeScreenOfOtherPanel(c,d){let h=c.viewHierarchy;if(!d||h?.packageName!==Zp)return;let f=mre(this.deps.device().displays?.panels??[],h);if(f&&f.key!==d.key)c.viewHierarchy=void 0,se(c,{phase:"viewHierarchy",message:`The home screen is not observable on the ${d.role} panel: the runner only sees the ${f.role} panel's SpringBoard. Launch an app, or setPosture closed to return to the ${f.role} panel.`})}async readLiveIosPanel(c){let d=this.deps.device(),h=d.displays?.panels??[];if(h.length<2)return;if(!this.deps.iosDisplayInfoSource){e.debug("[iOS] Live panel source unavailable; using runner size");return}try{let f=await this.deps.iosDisplayInfoSource.readDisplays({deviceId:d.deviceId,signal:c});c?.throwIfAborted();let P=xB(f,h);if(!P)e.debug("[iOS] No unique active CoreDevice panel; using runner size");return P}catch(f){if(c?.aborted)throw f;e.warn(`[iOS] Live panel read failed; using runner size: ${r(f)}`,f);return}}applyLiveIosPanelSize(c){let d=vz(c);if(!d?.scale||d.scale<=0)return;let h=d.sizePx.width/d.scale,f=d.sizePx.height/d.scale,P=c.screenSize;if(P.width===h&&P.height===f||P.width===f&&P.height===h)return;let C=c.viewHierarchy?.rotation===1||c.viewHierarchy?.rotation===3;c.screenSize=C?{width:f,height:h}:{width:h,height:f}}applyIosScreenMetadata(c){let d=this.deps.hierarchyCollector().extractScreenSize(c.viewHierarchy,(this.deps.device().displays?.panels.length??0)>1);if(d)c.screenSize=d,e.debug(`[iOS] Extracted screen size from hierarchy: ${d.width}x${d.height}`);else if(c.viewHierarchy?.screenWidth&&c.viewHierarchy?.screenHeight)c.screenSize={width:c.viewHierarchy.screenWidth,height:c.viewHierarchy.screenHeight},e.debug(`[iOS] Using screen size from CtrlProxy iOS: ${c.screenSize.width}x${c.screenSize.height}`);else e.warn("[iOS] Failed to extract screen size from hierarchy")}applyIosInsetsAndRotation(c){if(c.viewHierarchy?.insets)c.insets=c.viewHierarchy.insets;if(c.viewHierarchy?.systemInsets)c.systemInsets=c.viewHierarchy.systemInsets;c.rotation=Kd(c.viewHierarchy?.rotation,c.screenSize)}projectIosObservationHierarchy(c){if(c.viewHierarchy&&c.screenSize?.width>0&&c.screenSize?.height>0){this.deps.hierarchyCollector().reconcileScreenDimensions(c.viewHierarchy,c.screenSize);let d=c.viewHierarchy,h=(this.deps.device().displays?.panels.length??0)>1;c.viewHierarchy=hg("ios",d,h),Tre(d,c.viewHierarchy,h)}if(c.viewHierarchy?.packageName&&!c.activeWindow)c.activeWindow={appId:c.viewHierarchy.packageName,activityName:"",layoutSeqSum:0}}}var em=/\bFLAG_ROUND\b/,tm=/DisplayInfo\{[^\n]*\bdisplayId 0\b/,rm=/DisplayDeviceInfo\{[^\n]*\btype INTERNAL\b/;function mm(c){let d=c.split(/\r?\n/),h=d.find((f)=>tm.test(f))??d.find((f)=>rm.test(f));return h===void 0?void 0:em.test(h)}class HF{adb;cached;constructor(c){this.adb=c}async isScreenRound(c){if(this.cached)return this.cached.value;try{let d=await this.adb.executeCommand("shell dumpsys display",{timeoutMs:2000,maxBuffer:oe,noRetry:!0,signal:c});return this.cached={value:mm(d.stdout)},this.cached.value}catch(d){c?.throwIfAborted(),e.debug(`isScreenRound unavailable: ${r(d)}`);return}}}function fa(c){if(!c?.layoutWarnings)return c;let d=Qv(c.layoutWarnings);return d===c.layoutWarnings?c:{...c,layoutWarnings:d}}class Ie{device;adb;adbFactory;timer;observedAndroidDisplayCache;requestedDisplay;deferredBackStackDisplays=new WeakMap;idGenerator;viewHierarchy;hierarchyCapture;selectedDisplayRead;predictiveUIState;screenshotRecorder;screenshotService;screenshotEvidenceFiles;pathProtection;hierarchyCollector;deviceStateCollector;iosLockStateProbe;performanceAuditor;accessibilityAuditor;accessibilityStateDetector;elementsBuilder;reconciler;staleRecovery;settledScreenshots;deviceReadScreenshot;androidCollector;displayBinding;platformTraits;iosCollector;windowIdentity;platformValidator;safeAreaAuditor;allDisplays;captureStage;reconcileStage;enrichStage;screenRound;settleStage;static getRecentCachedObservation(){let c=io().getRecentInMemoryEntry();if(!c)return;let d=fa(c.result);return d?{deviceId:c.deviceId,result:d}:void 0}static getRecentCachedResult(){return Ie.getRecentCachedObservation()?.result}static getRecentCachedResultForDevice(c){return fa(io().getRecentInMemoryForDevice(c))}static getRecentCachedScreenshotPathForDevice(c){return An().getPath(c)}static getRecentCachedScreenshotErrorForDevice(c){return An().getError(c)}static getRecentCachedScreenshotPathForObservation(c,d){return An().getPathForObservation(c,d)}static getRecentCachedScreenshotErrorForObservation(c,d){return An().getErrorForObservation(c,d)}static clearCache(c){if(io().clear(c),An().clear(c),c)be.cancelJob(c);else be.clear()}static defaultObserveScreenCache={clearForDevice(c){Ie.clearCache(c)}};constructor(c,d=v,h,{timer:f=i,idGenerator:P=L}={}){this.device=c,this.adbFactory=d,this.adb=d.create(c),this.timer=f,this.observedAndroidDisplayCache=new fr(f),this.requestedDisplay=h?.display,this.selectedDisplayRead=h?.selectedDisplayRead??{},this.idGenerator=P,this.screenRound=new HF(this.adb);let C=Fs({device:c,adb:()=>this.adb,adbFactory:()=>this.adbFactory,observeScreenProvider:()=>this,identity:{device:()=>this.device,viewHierarchy:()=>this.viewHierarchy,deviceStateCollector:()=>this.deviceStateCollector,timer:()=>this.timer,platformValidator:()=>this.platformValidator,resolveObservationTimestampMs:(x)=>this.resolveObservationTimestampMs(x),extractScreenSizeFromHierarchy:(x)=>this.extractScreenSizeFromHierarchy(x)}}),A={device:c,adbFactory:this.adbFactory,timer:f,idGenerator:P,wiring:C,dependencies:h};this.viewHierarchy=Ks(A);let{sources:T,services:I}=zs(A);this.hierarchyCapture=T.hierarchyCapture,this.screenshotService=T.screenshotService,this.predictiveUIState=T.predictiveUIState,this.pathProtection=I.pathProtection,this.screenshotRecorder=I.screenshotRecorder,this.screenshotEvidenceFiles=I.screenshotEvidenceFiles,this.hierarchyCollector=I.hierarchyCollector,this.deviceStateCollector=I.deviceStateCollector,this.iosLockStateProbe=I.iosLockStateProbe,this.performanceAuditor=I.performanceAuditor,this.accessibilityAuditor=I.accessibilityAuditor,this.accessibilityStateDetector=I.accessibilityStateDetector,this.elementsBuilder=new ng,this.platformValidator=I.platformValidator,this.safeAreaAuditor=new O3,this.windowIdentity=I.windowIdentity,this.reconciler=I.reconciler,this.settledScreenshots=new zr({device:()=>this.device,timer:()=>this.timer,screenshotRecorder:()=>this.screenshotRecorder,screenshotEvidenceFiles:()=>this.screenshotEvidenceFiles,pathProtection:()=>this.pathProtection}),this.deviceReadScreenshot=new jr({device:()=>this.device,adb:()=>this.adb,timer:()=>this.timer,requestedDisplay:()=>this.requestedDisplay,observedAndroidDisplayCache:()=>this.observedAndroidDisplayCache,screenshotService:()=>this.screenshotService,screenshotEvidenceFiles:()=>this.screenshotEvidenceFiles,pathProtection:()=>this.pathProtection,settledScreenshots:()=>this.settledScreenshots}),this.staleRecovery=new Yr({timer:()=>this.timer,device:()=>this.device,viewHierarchy:()=>this.viewHierarchy,deviceStateCollector:()=>this.deviceStateCollector,platformValidator:()=>this.platformValidator,reconciler:()=>this.reconciler}),this.androidCollector=new Ti({hierarchyCollector:()=>this.hierarchyCollector,deviceStateCollector:()=>this.deviceStateCollector,viewHierarchy:()=>this.viewHierarchy,device:()=>this.device}),this.platformTraits=Ys(c.platform,()=>this.device);let O={device:()=>this.device,adb:()=>this.adb};this.displayBinding=c.platform==="ios"?new Ri(O):new wi(O),this.iosCollector=new ki({iosDisplayInfoSource:h?.iosDisplayInfoSource,hierarchyCollector:()=>this.hierarchyCollector,sdkBridge:h?.sdkBridge,viewHierarchy:()=>this.viewHierarchy,device:()=>this.device}),this.createStages()}createStages(){this.allDisplays=new Bt({device:()=>this.device,timer:()=>this.timer,pathProtection:()=>this.pathProtection,executeSingleDisplay:(c)=>this.executeSingleDisplay(c),captureDeviceReadScreenshot:(...c)=>this.captureDeviceReadScreenshot(...c),createCriticalFallback:(c)=>this.createCriticalFallback(c),createBaseResult:()=>this.createBaseResult()}),this.captureStage=new pr({device:()=>this.device,timer:()=>this.timer,displayBinding:()=>this.displayBinding,hierarchyCapture:()=>this.hierarchyCapture,hierarchyCollector:()=>this.hierarchyCollector,deviceStateCollector:()=>this.deviceStateCollector,iosLockStateProbe:()=>this.iosLockStateProbe,observedAndroidDisplayCache:()=>this.observedAndroidDisplayCache,requestedDisplay:()=>this.requestedDisplay,selectedDisplayRead:()=>this.selectedDisplayRead,createBaseResult:()=>this.createBaseResult(),createCriticalFallback:(c,d)=>this.createCriticalFallback(c,d),collectAllData:(c,d)=>this.collectAllData(c,d)}),this.reconcileStage=new gr({device:()=>this.device,timer:()=>this.timer,windowIdentity:()=>this.windowIdentity,staleRecovery:()=>this.staleRecovery,displayBinding:()=>this.displayBinding,platformValidator:()=>this.platformValidator,deviceStateCollector:()=>this.deviceStateCollector,reconcileActiveWindowAttribution:(c,d)=>this.reconcileActiveWindowAttribution(c,d),isConfirmedFrameworkErrorDialog:(c,d)=>this.isConfirmedFrameworkErrorDialog(c,d)}),this.enrichStage=new br({device:()=>this.device,timer:()=>this.timer,platformTraits:()=>this.platformTraits,screenshotRecorder:()=>this.screenshotRecorder,pathProtection:()=>this.pathProtection,performanceAuditor:()=>this.performanceAuditor,accessibilityAuditor:()=>this.accessibilityAuditor,accessibilityStateDetector:()=>this.accessibilityStateDetector,predictiveUIState:()=>this.predictiveUIState,safeAreaAuditor:()=>this.safeAreaAuditor,elementsBuilder:()=>this.elementsBuilder,screenRound:()=>this.screenRound,deferredBackStackDisplays:()=>this.deferredBackStackDisplays,stampScreenSizeUnits:(c)=>this.stampScreenSizeUnits(c),processRecomposition:(c,d)=>this.processRecomposition(c,d),captureSettledScreenshot:(...c)=>this.captureSettledScreenshot(...c)}),this.settleStage=new Kr({device:()=>this.device,timer:()=>this.timer,windowIdentity:()=>this.windowIdentity,deviceStateCollector:()=>this.deviceStateCollector,platformTraits:()=>this.platformTraits,identifyCapture:(c,d)=>this.identifyCapture(c,d),resolveObservationTimestampMs:(c)=>this.resolveObservationTimestampMs(c)})}async executeDeviceRead(c,d="settled",h,f={}){let{requireFreshScreenshot:P=!1,timeoutMs:C}=f;if(this.requestedDisplay==="all")return this.allDisplays.execute({observerMode:!0,skipCache:!0,skipRecompositionTracking:!0,skipPerformanceAudit:!0,skipAccessibilityAudit:!0,screenshot:"none",signal:c,timeoutMs:C,deviceReadScreenshot:d==="none"?void 0:h??{}});let A=await this.execute({observerMode:!0,skipCache:!0,skipRecompositionTracking:!0,skipPerformanceAudit:!0,skipAccessibilityAudit:!0,screenshot:"none",signal:c});if(A.viewHierarchy?.hierarchyServiceStarted)A.hierarchyServiceStarted=!0,delete A.viewHierarchy.hierarchyServiceStarted;if(d==="none")return A.screenshotCaptureAttempted=!1,A;if(await this.captureDeviceReadScreenshot(A,c,h,{requireFreshScreenshot:P}),A.screenshotPath)A.screenshotExpiresAt=await this.pathProtection.protect(A.screenshotPath);return A}captureDeviceReadScreenshot(...c){return this.deviceReadScreenshot.captureDeviceReadScreenshot(...c)}async appendRawViewHierarchy(c,d){if(!c.viewHierarchy)return;let h=await this.deviceReadScreenshot.resolveReadDisplayId(c,{signal:d});await this.hierarchyCollector.collectRaw(c,d,h)}async readCachedObservationForTarget(){let c=await io().getMostRecent(this.device.deviceId);if(!c||(this.device.displays?.panels.length??0)<=1)return c;let d=xe.currentObservedPanel(this.device.deviceId),h=![void 0,"active"].includes(this.requestedDisplay),f=d||h?void 0:this.device.platform==="android"?(await this.observedAndroidDisplayCache.resolve(this.device,this.adb)).display:hD(this.device,c.viewHierarchy),{key:P,posture:C}=f??{},A=sn(this.device.displays,this.requestedDisplay,{focusedPanelKey:d?.key,activePanelKey:P,posture:C,displayPin:pu()});return c.display?.key===A.key?c:void 0}async getMostRecentCachedObserveResult(){let c=this.timer.now();try{e.debug("[OBSERVE_CACHE] Getting most recent cached observe result");let d=await this.readCachedObservationForTarget(),h=d&&this.device.platform==="ios"?{...d,rotation:Kd(d.viewHierarchy?.rotation,d.screenSize)}:d,f=this.timer.now()-c;if(h){await eb(h,this.pathProtection),e.debug(`[OBSERVE_CACHE] Found recent result in cache (${f}ms)`),this.identifyCapture(h,"cached-ok");let P=qw({actualTimestamp:this.resolveObservationTimestampMs(h),hostAgeBasisMs:this.windowIdentity.resolveHostReceivedAtMs(h),now:this.timer.now()});P.requestedAfter=h.freshness?.requestedAfter;let C=h.displayRevision!==void 0&&h.displayRevision!==xe.revision(this.device.deviceId)||xe.geometryChanged(this.device.deviceId,h.screenSize);if(h.freshness?.isFresh===!1)return BW(h,{...h,freshness:{...h.freshness,ageMs:P.ageMs}});return{...h,freshness:C?{...P,isFresh:!1,category:"cache_age",warning:"Display changed since this observation was captured; observe again."}:P}}return e.debug(`[OBSERVE_CACHE] No cached observe result available (${f}ms)`),{...this.createBaseResult(),error:"No cached observe result available"}}catch(d){let h=this.timer.now()-c;return e.warn(`[OBSERVE_CACHE] Error getting cached observe result after ${h}ms: ${d}`),{...this.createBaseResult(),error:"Failed to retrieve cached observe result"}}}async execute(c){if((c?.display??this.requestedDisplay)==="all")return this.allDisplays.execute(c);return this.executeSingleDisplay(c)}async executeSingleDisplay(c){let d=this.captureStage.resolveSingleDisplayIntent(c);try{let h=await this.captureStage.beginSingleDisplay(d),f=await this.captureStage.captureSingleDisplay(h);if(f.earlyResult)return f.earlyResult;let P=await this.reconcileStage.reconcileSingleDisplay(h,f);return await this.enrichStage.enrichSingleDisplay(h),await this.settleStage.settleSingleDisplay(h,f,P),await this.enrichStage.publishSingleDisplay(h)}catch(h){if(h instanceof ZW)throw h;return await this.captureStage.failSingleDisplay(h,d)}}createCriticalFallback(c,d={}){let{fallback:h=this.createBaseResult()}=d,f=c instanceof Error?c.stack||c.message:String(c);return this.stampScreenSizeUnits(h),se(h,{phase:"critical",message:"Observation failed due to device access error",cause:f}),h.freshness=qw({now:this.timer.now(),unavailable:!0,unavailableReason:"unknown",unavailableDetail:f}),h}identifyCapture(c,d){if(c.viewHierarchy&&typeof c.viewHierarchy==="object"&&!c.viewHierarchy.hierarchy?.error)id(Q(this.device.platform,"Observing the view hierarchy"),c.viewHierarchy,d,{timer:this.timer,ids:this.idGenerator,captureId:c.observationId,iosMultiPanel:this.platformTraits.isIosMultiPanel()})}async processRecomposition(c,d){await Dn.getInstance().processObservation(c,this.device)}async screenshotDisplayId(c,d){if(this.device.platform!=="android"||this.requestedDisplay==="active")return;let h=this.requestedDisplay||d?.display?.key;if(!h)return;try{let f=sn(this.device.displays,h,{}),P=await this.observedAndroidDisplayCache.logicalIdForPanel(this.device,this.adb,f.key,c);return!this.requestedDisplay&&P===0?void 0:P}catch(f){if(this.requestedDisplay)throw f;e.debug(`Screenshot panel "${h}" could not be mapped; using default display: ${r(f).replace(/\s+/g," ")}`);return}}async captureScreenshot(c=new B,{signal:d,observation:h,screenshot:f,screenshotOptions:P}={}){let C=h??this.createBaseResult(),A=await this.screenshotDisplayId(d,h),T=nm(f),I=wr(P);if(h){if(h.screenshotCaptureAttempted=!0,Rr(h,I),T==="settled")h.screenshotOrientation=this.platformTraits.settledScreenshotOrientation()}if(T==="settled")await this.captureSettledScreenshot(C,c,d,{strict:f==="settled",displayId:A,screenshotOptions:P});else await this.screenshotRecorder.captureFresh(C.observationId,{perf:c,signal:d,displayId:A,capture:I});if(h)await this.runAccessibilityAudit(h,c)}captureSettledScreenshot(...c){return this.settledScreenshots.captureSettledScreenshot(...c)}async runAccessibilityAudit(c,d=new B){await this.accessibilityAuditor.run(c,d)}appendError(c,d){se(c,{phase:"critical",message:d})}extractScreenSizeFromHierarchy(c){return this.hierarchyCollector.extractScreenSize(c,this.platformTraits.isIosMultiPanel())}createBaseResult(){return{observationId:this.idGenerator.next(),deviceId:this.device.deviceId,display:{key:"0",role:"unknown",posture:"unknown",generation:0},updatedAt:new Date(this.timer.now()).toISOString(),screenSize:{width:0,height:0},systemInsets:{top:0,right:0,bottom:0,left:0},insets:{available:!1,source:"unavailable",units:"unknown"}}}stampScreenSizeUnits(c){c.screenSize={...c.screenSize,units:this.platformTraits.screenSizeUnits()}}captureCacheGeneration(){return io().currentGeneration(this.device.deviceId)}async cacheObserveResult(c,d,h){if(c.displayRevision!==void 0&&c.displayRevision!==xe.revision(this.device.deviceId))return;let f=io(),P=h??this.timer.now(),C=f.getRecentInMemoryForDevice(this.device.deviceId),A=f.getRecentCachedAtForDevice(this.device.deviceId);if(C!==void 0&&C.observationId!==c.observationId&&A!==void 0&&A>P){e.debug(`[OBSERVE_CACHE] Skipping deferred observe result for device ${this.device.deviceId}: a more recently cached observation already exists`);return}await f.put(this.device.deviceId,c,d,P)}async collectDeferredBackStack(c,d={}){let h=this.deferredBackStackDisplays.get(c);if(h===void 0||this.device.platform!=="android"||c.backStack)return!1;await this.deviceStateCollector.collectBackStack(c,new B,d.signal,h);let f=Me(c),P=c.activeWindow,C=Boolean(f&&P&&!de.has(c.viewHierarchy?.packageName??"")&&!de.has(P.appId)&&Ar(c,P,f));return Ci(c),C}collectAllData(c,d={}){let h={result:c,queryOptions:d.queryOptions,perf:d.perf??new B,skipWaitForFresh:d.skipWaitForFresh??!1,minTimestamp:d.minTimestamp??0,signal:d.signal,readOnly:d.readOnly??!1,capturedHierarchy:d.capturedHierarchy,readOptions:d.readOptions};switch(this.device.platform){case"android":return this.androidCollector.collect({...h,skipBackStack:d.skipBackStack??!1,displayId:d.displayId??0});case"ios":return this.iosCollector.collect(h);default:return Promise.resolve()}}reconcileActiveWindowAttribution(c,d={}){return this.reconciler.reconcileActiveWindowAttribution(c,d)}applyRecapturedHierarchy(c,d){return this.reconciler.applyRecapturedHierarchy(c,d)}recorrelateActiveWindowToRecapture(c,d){return this.reconciler.recorrelateActiveWindowToRecapture(c,d)}recaptureHierarchyForSystemUiOverlay(c,d){return this.reconciler.recaptureHierarchyForSystemUiOverlay(c,d)}recaptureHierarchyForBackStackAttribution(c,d,h){return this.reconciler.recaptureHierarchyForBackStackAttribution(c,d,h)}isConfirmedFrameworkErrorDialog(c,d){return rs(this.adb,c,d)}resolveObservationTimestampMs(c){return c.viewHierarchy?.updatedAt}}function qF(c,d){return new Ie(c,d,c.platform==="ios"?{iosDisplayInfoSource:mu()}:void 0)}class Zn{invalidate(c,d){if(c.platform==="android")k.getExistingInstance(c.deviceId)?.invalidateCache();else{let h=_.getExistingInstance(c.deviceId);if(d)h?.invalidateCache();else h?.clearCache()}if(Ie.clearCache(c.deviceId),c.platform==="android")xre(c.deviceId)}retireAppProcess(c,d){if(c.platform==="android")k.getExistingInstance(c.deviceId)?.clearSdkScreenIdentity(d)}}function hm(c){let d=[],h=[];for(let f of c.split(`
|
|
51
|
-
`)){let P=f.trim();if(!P)continue;let C=f.length-f.trimStart().length;while(h.length&&h[h.length-1].indent>=C)h.pop();let A={text:P,indent:C,children:[]};h[h.length-1]?.children.push(A),d.push(A),h.push(A)}return d}function ya(c){let d=new Map;for(let{text:h}of c?.children??[]){let f=h.match(/^([A-Za-z0-9_.]+):\s+granted=(true|false)\b(.*)$/);if(!f)continue;let[,P,C,A]=f;d.set(P,{permission:P,state:C==="true"?"granted":"denied",source:"androidRuntime",raw:{granted:C==="true",flags:A.trim()||null}})}return d}function fm(c,d){let f=c.children.find((P)=>P.text.startsWith("sharedUser=SharedUserSetting{"))?.text.split(" ")[1]?.split("/")[0];return f?d.find((P)=>P.text==="Shared users:")?.children.find((P)=>P.text.startsWith(`SharedUser [${f}]`)):void 0}function Bn(c,d,h=0){let f=hm(c),P=f.find((N)=>N.text.startsWith(`Package [${d}]`)),C=P?.children.find((N)=>N.text==="requested permissions:");if(!P)return;let A=fm(P,f),T=P.children.find((N)=>N.text==="install permissions:")??A?.children.find((N)=>N.text==="install permissions:"),I=P.children.find((N)=>N.text.startsWith(`User ${h}:`)),O=A?.children.find((N)=>N.text.startsWith(`User ${h}:`)),x=I?.children.find((N)=>N.text==="runtime permissions:")??O?.children.find((N)=>N.text==="runtime permissions:");return{requestedPermissions:new Set(C?.children.map((N)=>N.text)??[]),installPermissions:ya(T),runtimePermissions:ya(x)}}var Ai=180,Y4=170000,tT={gracefulExit:1e4,pkill:8000,tempFileRemove:8000,probe:5000,pkillOpts:{timeoutMs:8000}},ym=100;async function IQ(c,d){if(!c||c.readableEnded||c.destroyed)return;let h=new Promise((P)=>{c.once("end",P),c.once("close",P)}),f=Error("screenrecord stderr drain timed out");try{await l(h,{timer:d,timeoutMs:ym,label:"screenrecord stderr drain",timeoutError:()=>f})}catch(P){if(P!==f)throw P;e.debug("[VideoCapture] screenrecord stderr did not end before the drain deadline")}}class $c extends t{}async function Ur(c,d,h={}){await w.devicePoolWrites()?.reconcileDiscoveryObservation(c,d,h)}class Di extends t{cause;constructor(c,d){super(`The tvOS runner was already disconnected, so ${c} was not sent. Call startDevice to restart the runner, then retry.`);this.cause=d}}class rT extends t{errorCode;constructor(c,d){super(c);this.errorCode=d}}class Oi extends t{constructor(c,d){super(`The tvOS runner did not answer ${c} within ${d}ms and was disconnected; it can stick while XCTest waits for an app that is not in front. Call startDevice to restart the runner, then retry.`)}}import gm from"ws";var _Q=["up","down","left","right","select","menu","home","playPause"],vm=5000,bm=(c)=>{let d=new gm(c);return{send:(h)=>d.send(h),close:()=>d.close(),onMessage:(h)=>{d.on("message",(f)=>h(f.toString()))},onFailure:(h)=>{d.on("error",h),d.on("close",()=>h(Error("Tvos runner disconnected; reconnect it.")))}}};function Sm(c){return c==="request_hierarchy"?"hierarchy_update":c==="request_screenshot"?"screenshot":`${c.slice(8)}_result`}class J4{options;socket;pending=new Map;sequence=0;supported=new Set;ready;resolveReady;rejectReady;failure;constructor(c,d={}){this.options=d;this.ready=new Promise((h,f)=>{this.resolveReady=h,this.rejectReady=f}),this.ready.then(void 0,()=>{}),this.socket=(d.factory??bm)(c),this.socket.onMessage((h)=>this.receive(h)),this.socket.onFailure((h)=>this.fail(u(h,"Tvos runner connection failed")))}isUsable(){return this.failure===void 0}fail(c){this.failure??=c,this.rejectReady(this.failure);for(let d of this.pending.values())d.reject(this.failure);this.pending.clear()}receive(c){try{let d=JSON.parse(c);if(!d||typeof d!=="object"||!("type"in d))throw new t("Invalid tvos runner response; reconnect it.");let h=d;if(h.type==="connected")this.connected(h);else this.reply(h)}catch(d){this.fail(u(d,"Invalid tvos runner response")),this.socket.close()}}connected(c){if(c.platform!=="tvos"){this.fail(new rT("Refusing runner: connected platform must be tvos.","invalid_runner_platform")),this.socket.close();return}this.supported=new Set(Array.isArray(c.supportedCommands)?c.supportedCommands.filter((d)=>typeof d==="string"):[]),this.resolveReady();return}reply(c){let d=typeof c.requestId==="string"?this.pending.get(c.requestId):void 0;if(!d)return;if(c.type==="error"||c.success===!1)d.reject(new rT(String(c.error??"Tvos command failed"),String(c.errorCode??"command_failed")));else if(c.type===Sm(d.type)&&(c.success===!0||["request_hierarchy","request_screenshot"].includes(d.type)&&c.success===void 0))d.resolve(c.data)}async request(c,d,h){let f=this.options.timer??i,P=h?.timeoutMs??this.options.timeoutMs??vm,C=String(++this.sequence),A=new AbortController,T=d?AbortSignal.any([d,A.signal]):A.signal,I=JSON.stringify({...this.withForegroundHint(c),requestId:C}),O=!1,x,N=()=>x??=new Oi(c.type,P);try{return await l(async()=>{if(await this.ready,T.throwIfAborted(),this.failure)throw new Di(c.type,this.failure);if(!this.supported.has(c.type))throw new rT(`The tvos runner does not support ${c.type}.`,"unsupported_on_tvos");return new Promise((H,V)=>{this.pending.set(C,{type:c.type,resolve:H,reject:V}),O=!0,this.socket.send(I)})},{timer:f,timeoutMs:P,signal:T,label:`Tvos runner ${c.type}`,timeoutError:()=>O?N():void 0,onTimeout:()=>{if(O)this.fail(N()),this.socket.close()}})}finally{A.abort(),this.pending.delete(C)}}withForegroundHint(c){if(c.type!=="request_hierarchy"&&c.type!=="request_append_text"&&c.type!=="request_press_button"||c.bundleId?.trim())return c;let d=this.options.foregroundApp?.();return d?{...c,bundleId:d}:c}async hierarchy(c){let d=await this.request({type:"request_hierarchy"},c);if(!TF(d))throw new t("Invalid tvos hierarchy; reconnect the runner.");return d}close(){this.fail(new t("Tvos runner closed; reconnect it.")),this.socket.close()}}class wa extends t{errorCode;constructor(c,d){super(c);this.errorCode=d}}function Uc(c,d,h={}){let f=h.clock??i,P=h.log??e,C,A,T=async()=>{let I=f.now();try{let O=await d();return C=O,P.info(`[lazy-feature] ${c} module loaded in ${f.now()-I} ms`),O}catch(O){throw A=void 0,P.warn(`[lazy-feature] ${c} module failed to load`,O),u(O,`Failed to load the ${c} module`)}};return{load:()=>{if(C!==void 0)return Promise.resolve(C);return A??=T(),A},loaded:()=>C}}function Zl(c){return _.getInstance(c)}class ga{restored=new Set;removed=new Set;identityChanged=new Set;onDeviceRestored(c){return this.restored.add(c),()=>{this.restored.delete(c)}}onDeviceRemoved(c){return this.removed.add(c),()=>{this.removed.delete(c)}}onDeviceIdentityChanged(c){return this.identityChanged.add(c),()=>{this.identityChanged.delete(c)}}removedListenersForTesting(){return[...this.removed]}clearRemovedListenersForTesting(){this.removed.clear()}deviceRestored(c){this.emit(this.restored,c)}deviceRemoved(c){this.emit(this.removed,c)}deviceIdentityChanged(c){this.emit(this.identityChanged,c)}emit(c,d){for(let h of[...c])try{h(d)}catch(f){e.warn(`[StreamDeviceLifecycle] listener failed for ${d}: ${r(f)}`,f)}}}var xi=null;function Xs(){if(!xi){let c=new ga;xi=c,Xt({name:"stream-device-lifecycle",prepareForIncarnationChange:(d)=>c.deviceRestored(d),onDeviceIncarnationChanged:(d)=>c.deviceRestored(d)})}return xi}class pm extends t{deviceId;recordingIds;code="orphan_recorder_active";retryable=!0;constructor(c,d,h){super(`A recorder from before the daemon restart is still running on device '${c}' and could not be stopped. Retry or stop it by id (${d.join(", ")}).`,{cause:h});this.deviceId=c;this.recordingIds=d;this.name="OrphanRecorderActiveError"}toPayload(){return{code:this.code,message:this.message,retryable:this.retryable,deviceId:this.deviceId,recordingIds:this.recordingIds}}}import*as he from"fs";import*as Ee from"path";class sC{filePath;constructor(c=wm()){this.filePath=c}read(){try{return he.existsSync(this.filePath)?he.readFileSync(this.filePath,"utf8"):null}catch(c){return e.debug(`Failed to read startup failure tracker file: ${c}`),null}}write(c){let d=Ee.dirname(this.filePath);he.mkdirSync(d,{recursive:!0});let h=Ee.join(d,`.${Ee.basename(this.filePath)}.${process.pid}.tmp`);he.writeFileSync(h,c,{mode:384}),he.renameSync(h,this.filePath)}clear(){try{if(he.existsSync(this.filePath))he.rmSync(this.filePath,{force:!0})}catch(c){e.debug(`Failed to clear startup failure tracker file: ${c}`)}}}function wm(){return Ee.join(Xe(dn.STATE),"daemon-startup-failures.json")}
|
|
52
|
-
export{go,WA,RF,tV,zA,WS,Jl,eC,zS,L4,pQ,kr,sr,PF,mQ,nm,jA,jd,Be,yr,cc,fQ,bh,Sh,Is,rV,wh,Xy,nV,AF,hQ,gQ,jS,KA,GA,TF,im,Ln,B4,YA,yo,iV,oV,sV,Fi,pn,kF,EF,om,sm,Kd,Gd,Yd,tC,rC,mn,IF,JA,$4,yQ,Zy,_F,vQ,XA,nC,aV,iC,bQ,am,cV,U4,H4,dV,q4,V4,xF,KS,Rh,W4,ot,cm,Li,Bc,z4,SQ,lV,uV,wQ,j4,RQ,PQ,pV,CF,Ph,DF,OF,mV,fV,MF,K4,NF,hV,Js,dm,At,re,ze,Kt,Sa,Xn,Ah,FF,Th,lm,LF,gV,vo,ZA,yV,um,BF,vV,QA,Yi,$F,Xl,G4,bV,AQ,TQ,SV,Qy,oC,wV,RV,kQ,PV,EQ,UF,eT,AV,HF,Ie,qF,Zn,Bn,Ai,Y4,tT,IQ,$c,Ur,rT,_Q,J4,wa,Uc,Zl,Xs,pm,sC};
|
|
53
|
-
|
|
54
|
-
//# debugId=0C7AE9BC338B3ACE64756E2164756E21
|