
    @yjr                       U d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlmZ ddlmZ ddlmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlm Z m!Z!m"Z"m#Z#m$Z$ ddlm%Z& dZ'dZ(dZ)dZ*dZ+dZ,dddZ-de.d<   dZ/dZ0dZ1 G d de2      Z3 G d d      Z4 ed        G d! d"             Z5 ed        G d# d$             Z6dSd%Z7dTd&Z8dUd'Z9dVd(Z:dWdXd)Z;dYd*Z<dZd+Z=dTd,Z>dWd[d-Z?	 	 	 	 	 	 	 	 	 	 d\d.Z@dd/	 	 	 	 	 	 	 	 	 	 	 d]d0ZA G d1 d2      ZBd3ZCd^d4ZDd_d5ZE	 	 	 	 	 	 d`d6ZFdad7ZGdbd8ZHdcd9ZIddd:ZJ	 	 	 	 	 	 	 	 	 	 ded;ZKdfd<ZLdd=	 	 	 	 	 	 	 	 	 dgd>ZMdhd?ZN	 dW	 	 	 	 	 	 	 	 	 did@ZOdd=	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 djdAZPdkdBZQdkdCZRdldDZSdmdEZTdkdFZU G dG dHe      ZVej                  dndI       ZXdodJZYdpdKZZdqdLZ[drdMZ\dkdNZ]dsdOZ^dkdPZ_dtdQZ`eadRk(  r eb e`             y)uau  Isolated, privacy-preserving Telegram Web QA setup for DualCoach Tasks 22-25.

This tool deliberately contains no Telegram bot, role-link, message, or product-state
actions. It only presents an official Telegram Web QR page, reports a boolean login
state, and captures redacted browser evidence. It must be run with the installed
Miniconda Playwright runtime on this host.
    )annotationsN)Counter)Iterator)	dataclass)BaseHTTPRequestHandlerThreadingHTTPServer)Path)Any)urlparse)Image)BrowserContext	FloatRectPageViewportSizeasync_playwright)Errorzhttps://web.telegram.org/a/)customertrainerownerztask22-telegram-web-s   task22-telegram-web-qa-v1
i  i  i   i  )widthheightr   VIEWPORT-   )      (   c                  &     e Zd ZdZdd fdZ xZS )HarnessErrorz7A deliberately non-sensitive error suitable for stdout.c                H    t         |   |       || _        |xs i | _        y N)super__init__codedetails)selfr#   r$   	__class__s      D/home/cube/projects/richard/traning coach/.omo/qa/telegram_web_qa.pyr"   zHarnessError.__init__7   s"    	}"    r    )r#   strr$   zdict[str, object] | NonereturnNone)__name__
__module____qualname____doc__r"   __classcell__)r&   s   @r'   r   r   4   s    A% %r(   r   c                  T    e Zd ZdZd	dZed
d       ZdddZddZdd	 	 	 	 	 ddZ	y)LiveDiagnosticsz5Aggregate only non-sensitive browser lifecycle facts.c                l    d| _         t               | _        t               | _        t               | _        y )Nstartup)stager   _events_hosts	_statusesr%   s    r'   r"   zLiveDiagnostics.__init__@   s$    
%,Y$+I'.yr(   c                    t        |       j                  xs dj                         }|dk(  ry|dk(  ry|dv ry|j                  d      ry	y
)N web.telegram.orgofficial_roottelegram.orgofficial_apex   t.metelegram.metelegram.dogexpected_optional.web.telegram.orgofficial_subdomainblocked)r   hostnamelowerendswith)raw_urlhosts     r'   _host_bucketzLiveDiagnostics._host_bucketF   sV    !**0b779%%">!"::&==,-'r(   Nc                    | j                   |xx   dz  cc<   | j                  | j                  |      xx   dz  cc<   |0d|cxk  rdk  r$n y | j                  t	        |      xx   dz  cc<   y y y )N   d   iW  )r6   r7   rM   r8   r)   )r%   eventrK   statuss       r'   record_eventzLiveDiagnostics.record_eventS   sg    Uq D%%g./14/#"63"6NN3v;'1,' #7r(   c                
   t        t        | j                  j                                     t        t        | j                  j                                     t        t        | j
                  j                                     dS )N)eventshostsstatuses)dictsortedr6   itemsr7   r8   r9   s    r'   summaryzLiveDiagnostics.summaryY   sZ    6$,,"4"4"678&!2!2!456VDNN$8$8$:;<
 	
r(   cleanup_errorc          
        t        |t              r(|j                  j                  d      r|j                  }n&dddddddd	d
d	j	                  | j
                  d      }t        |j                  t        t        f      r|j                  n|}|t        |      j                  | j
                  d| j                         }|t        |      j                  |d<   |S )Nlogin_profile_filesystem_failedchromium_launch_failedbrowser_guard_failednavigation_failedlogin_state_failedqr_capture_failedunexpected_network_requestbrowser_close_failedprofile_cleanup_failed)	profile_setupbrowser_launchguard_install
navigation
state_wait
qr_capturenetwork_validationsession_closecleanupbrowser_runtime_failed)r#   exception_classr5   cleanup_exception_class)
isinstancer   r#   
startswithgetr5   	__cause__PlaywrightErrorOSErrortyper,   r[   )r%   errorr]   r#   causepayloads         r'   failure_payloadzLiveDiagnostics.failure_payload`   s     e\*uzz/D/DX/N::D 963-.-">3/
 c$**67  $.eooQX?Y#Z`e#E{33ZZ&
 lln	&
 $15m1D1M1MG-.r(   r*   r+   )rK   r)   r*   r)   r    )rQ   r)   rK   r)   rR   z
int | Noner*   r+   )r*   dict[str, object])r|   BaseExceptionr]   zBaseException | Noner*   r   )
r,   r-   r.   r/   r"   staticmethodrM   rS   r[   r    r(   r'   r2   r2   =   sN    ?1 
 
-
 /3	 ,	
 
r(   r2   T)frozenc                  @    e Zd ZU ded<   ded<   ded<   ded<   ded	<   y
)Capturer)   roler	   qr_path
proof_pathdict[str, float]qr_boxbool
qr_qualityNr,   r-   r.   __annotations__r   r(   r'   r   r      s    
IMr(   r   c                  6    e Zd ZU ded<   ded<   ded<   ded<   y	)
PageSessionr   contextr   pageNetworkGuardguardr
   
playwrightNr   r   r(   r'   r   r      s    
JOr(   r   c                J    t        t        j                  | dd      d       y)zGPrint only tool-created metadata, never browser data or exception text.T),:)	sort_keys
separators)flushN)printjsondumps)values    r'   emitr      s     
$**Udz
B$Or(   c                $   | j                  ddt               t        j                  |       }t	        j
                  |j                        rt	        j                  |j                        rt        d      t        j                  | t               y )NT)parentsexist_okmodeunsafe_directory)
mkdirDIRECTORY_MODEoslstatstatS_ISDIRst_modeS_ISLNKr   chmod)pathinfos     r'   secure_mkdirr      sZ    JJtdJ@88D>D<<%dll)C-..HHT>"r(   c           	     0   	 t        j                  | j                        }t        j                  |j
                        rt        j                  |j
                        rt        d      t        j                  | t         j                  t         j                  z  t         j                  z  t         j                  z  t        t         dd      z  t               }	 d}|t#        |      k  r+|t        j$                  |||d        z  }|t#        |      k  r+t        j&                  |       t        j(                  |t                t        j*                  |       y # t        $ r t        | j                         Y w xY w# t        j*                  |       w xY w)Nr   
O_NOFOLLOWr   )r   r   parentr   r   r   r   r   FileNotFoundErrorr   openO_WRONLYO_CREATO_TRUNC	O_CLOEXECgetattr	FILE_MODElenwritefsyncfchmodclose)r   r~   parent_info
descriptorwrittens        r'   secure_writer      s!   3hht{{+ ||K//0DLLATAT4U122
bjj 2::-<wr<YZ?[[J
G$rxx
GGH,=>>G G$

		*i(
#  "T[[!"" 	s#   E :E> /E> E;:E;>Fc                    	 t        j                  |       }t        j                  |j
                         xr" t        j                  |j
                        |k(  S # t        $ r Y yw xY w)NF)r   r   r   r   r   r   S_IMODE)r   expectedr   s      r'   
exact_moder      sW    xx~ ||DLL))Tdll4<<.HH.TT  s   A 	A'&A'c                4   | t        d      n| }| t        |       t        t        j                  t        |            }t        j                  |t               t        |dz  t               t        |dz         t        D ]  }t        || dz          |S )Nz/tmp)prefixdir.task22-session	artifacts-profile)r	   r   tempfilemkdtempSESSION_PREFIXr   r   r   r   SESSION_MARKERROLES)base_dirbaserootr   s       r'   create_sessionr      s    #+4<DT  DABDHHT>"))>:#$TtfH--. Kr(   c                   | j                         } 	 t        j                  |       }| j
                  j                  t              du st        j                  |j                        rft        j                  |j                        sG|j                  t        j                         k7  s&t        j                  |j                        t        k7  rt	        d      | dz  }	 |j!                         }|t$        k7  st'        |t(              st	        d      | S # t        $ r}t	        d      |d }~ww xY w# t"        $ r}t	        d      |d }~ww xY w)Nsession_missingFunsafe_sessionr   )absoluter   r   r   r   namerv   r   r   r   r   r   st_uidgetuidr   r   
read_bytesrz   r   r   r   )r   r   excmarkermarker_values        r'   validate_sessionr      s   ==?D7xx~ 			^,5||DLL)<<%;;"))+%<<%7+,,%%F6((* ~%Z	-J+,,K#  7,-367  6+,#56s/   D D1 	D.D))D.1	E:EEc                    |t         vrt        d      | | dz  }t        |       t        |t              st        d      |S )Ninvalid_roler   unsafe_profile)r   r   r   r   r   )r   r   profiles      r'   role_profiler      sI    5>**vX&&Gg~.+,,Nr(   c                    	 t        j                  |       }t        j                  |j
                        st        j                  |j
                        st        d      dfd |        y# t        $ r Y yw xY w)aA  Best-effort overwrite then unlink, without traversing symlinks.

    Filesystem snapshots, CoW filesystems, and SSD wear-leveling can prevent physical
    erasure guarantees. This removes the local browser material and overwrites ordinary
    files before unlinking; it never follows a link outside the session root.
    Nunsafe_cleanup_targetc           
     H   t        j                  |       }t        j                  |j                        rt        j
                  |        y t        j                  |j                        rWt        j                  |       5 }|D ]  } t        |j                                	 d d d        t        j                  |        y t        j                  |j                        rt        j                  | t         j                  t         j                  z  t        t         dd      z        }	 t        j                   |      j"                  }t        j$                  |dt         j&                         dt)        dt+        |d            z  }|r4t        j,                  ||d t)        t/        |      |             }||z  }|r4t        j0                  |       t        j2                  |       t        j
                  |        y # 1 sw Y   [xY w# t        j2                  |       w xY w)Nr   r       i   rO   )r   r   r   r   r   unlinkr   scandirr	   r   rmdirS_ISREGr   r   r   r   fstatst_sizelseekSEEK_SETminmaxr   r   r   r   )	item	item_infochildrenchildr   	remainingblockr   purges	           r'   r   z!secure_remove_tree.<locals>.purge   sx   HHTN	<<	))*IIdO<<	))*D!X%E$uzz*+ & " HHTN<<	))*bll*WRq-IIJ	%HHZ088	Q4KY1B CC hhz59U3s5z9;U3VWG(I   $$
		$) "!& $s    #G=*BH
 =H
 =H
H!)r   r	   r*   r+   )r   r   r   r   r   r   r   r   )r   r   r   s     @r'   secure_remove_treer     se    xx~ ||DLL!dll)C2338 
$KC  s   A0 0	A<;A<c                @   t        |       }|Mt        |      }|j                  dk(  r3|j                  |j                  k(  r|j                  |j                  k(  ry|j                  dvry|j                  xs dj	                         }|dk(  xs |j                  d      S )NhttpT>   wsshttpsFr;   r<   rE   )r   schemenetlocrH   rI   rJ   )rK   fixture_originparsedfixturerL   s        r'   allowed_urlr    s    gF!>*==F"v}}'F6==\c\j\jKj}},,OO!r((*D%%K7J)KKr(   c                   t        |       }	 |j                  }| xrE |dk(  xr> |dk(  xr7 |j                  dk(  xr& |j                  xs dj                         dv xr |dv S # t        $ r Y yw xY w)NFGETscriptr  r;   r@      N  )r   port
ValueErrorr  rH   rI   )rK   methodresource_typeis_navigationr	  r  s         r'   expected_denied_requestr  '  s     gF{{  	 eO	 X%	  MMW$	  __"))+/VV		 
 K  s   A# #	A/.A/)r  c                   t        | |      ryt        |       }	 |j                  }| xrF |dk(  xr? |dk(  xr8 |j                  dk(  xr' |j
                  xs dj                         dk(  xr |dv S # t        $ r Y yw xY w)	NTFr  xhrr  r;   r>   r  )r  r   r  r  r  rH   rI   )rK   r  r  r  r  r	  r  s          r'   allowed_requestr  =  s     7N+gF{{  	 eO	 U"	  MMW$	  __"))+~=		 
 K  s   A1 1	A=<A=c                  P    e Zd ZdZ	 	 d		 	 	 	 	 d
dZddZddZddZddZddZ	y)r   zGBlock non-Telegram navigation, downloads, dialogs, and clipboard reads.Nc                X    || _         || _        d| _        d| _        d| _        d| _        y )Nr   )r  diagnosticsblocked_requestsblocked_downloadsblocked_dialogsblocked_popups)r%   r  r  s      r'   r"   zNetworkGuard.__init__Y  s4    
 -& !!" r(   c                .    t        || j                        S r    )r  r  )r%   rK   s     r'   allowszNetworkGuard.allowse  s    7D$7$788r(   c                   K   |j                  d| j                         d {    |j                  d| j                         d {    |j	                  d       d {    y 7 B7  7 	w)Nz**/*aH  
            (() => {
              const denied = () => Promise.reject(new DOMException('blocked', 'NotAllowedError'));
              try {
                Object.defineProperty(navigator, 'clipboard', {
                  configurable: false,
                  value: Object.freeze({read: denied, readText: denied}),
                });
              } catch (_) {}
              document.addEventListener('copy', event => event.preventDefault(), true);
              document.addEventListener('cut', event => event.preventDefault(), true);
              document.addEventListener('click', event => {
                const link = event.target instanceof Element && event.target.closest('a[href]');
                if (!link) return;
                const target = new URL(link.href, document.baseURI);
                const isWebTelegram = target.protocol === 'https:' &&
                  (target.hostname === 'web.telegram.org' || target.hostname.endsWith('.web.telegram.org'));
                if (!isWebTelegram) event.preventDefault();
              }, true);
            })();
            )route_routeroute_web_socket_route_web_socketadd_init_script)r%   r   s     r'   installzNetworkGuard.installh  sf     mmFDKK000&&vt/E/EFFF%%
 	
 	
 	1F	
s3    A+A%#A+A'A+A) A+'A+)A+c                   K   |j                   }t        |j                  |j                  |j                  |j                               rL| j                  &| j                  j                  d|j                         |j                  d       d {    y t        |j                  |j                  |j                  |j                         | j                        rK| j                  &| j                  j                  d|j                         |j                          d {    y | xj                  dz  c_        | j                  &| j                  j                  d|j                         |j                  d       d {    y 7 7 h7 	w)Nr  r  r  expected_deniedblockedbyclient)r  r  r  r  requestrO   rG   )r.  r  urlr  r  is_navigation_requestr  rS   abortr  r  	continue_r  )r%   r$  r.  s      r'   r%  zNetworkGuard._route  sC    --"KK>>!//!779	
 +  --.?M++/000KK>>!//!779..
 +  --iE//###"')))W[[Akk+,,,! 1 $
 	-s8   BFFBF!F
"A FFF
FFc                  K   | j                  |j                        rK| j                  &| j                  j                  d|j                         |j	                          d {    y | xj
                  dz  c_        | j                  &| j                  j                  d|j                         |j                          d {    y 7 e7 w)N	websocketrO   rG   )r"  r/  r  rS   connectr  r   )r%   r$  s     r'   r'  zNetworkGuard._route_web_socket  s     ;;uyy!+  --k599E--/!!"')))UYY?kkm "
 	s%   A!C#C	$ACCCCc                     j                   -|j                  dfd       dfd}|j                  d|       d fd}d fd}d fd
}|j                  d|       |j                  d|       |j                  d	|       y )Nresponsec                R    j                  d| j                  | j                        S )Nr7  )rS   r/  rR   )r7  r  s    r'   <lambda>z+NetworkGuard.protect_page.<locals>.<lambda>  s    !9!9hoo"r(   c                    t        | j                  | j                  | j                  | j	                               ry j                  d| j                         y )Nr+  request_failed)r  r/  r  r  r0  rS   )r.  r  s    r'   record_failedz0NetworkGuard.protect_page.<locals>.record_failed  sH    *KK">>")"7"7")"?"?"A	 (()97;;Gr(   requestfailedpopupc                v    xj                   dz  c_         t        j                  | j                                y NrO   )r   asynciocreate_taskr   )r>  r%   s    r'   reject_popupz/NetworkGuard.protect_page.<locals>.reject_popup  s(    1$.r(   downloadc                v    xj                   dz  c_         t        j                  | j                                y r@  )r  rA  rB  cancel)rD  r%   s    r'   reject_downloadz2NetworkGuard.protect_page.<locals>.reject_download  s)    ""a'" 12r(   dialogc                v    xj                   dz  c_         t        j                  | j                                y r@  )r  rA  rB  dismiss)rH  r%   s    r'   reject_dialogz0NetworkGuard.protect_page.<locals>.reject_dialog  s)      A%  01r(   )r.  r
   r*   r+   )r>  r   r*   r+   )rD  r
   r*   r+   )rH  r
   r*   r+   )r  on)r%   r   r<  rC  rG  rK  r  s   `     @r'   protect_pagezNetworkGuard.protect_page  sy    &&"GGH GGO]3	/	3	2 	&
O,-(r(   )NN)r  
str | Noner  LiveDiagnostics | Noner*   r+   )rK   r)   r*   r   )r   r   r*   r+   )r$  r
   r*   r+   r   r   r*   r+   )
r,   r-   r.   r/   r"   r"  r)  r%  r'  rM  r   r(   r'   r   r   V  sG    Q &*.2
 "
  ,
  
	
 9
6-8	#)r(   r   a~
  
(() => {
  const visible = (node, minimum = 1) => {
    if (!(node instanceof Element)) return false;
    const style = getComputedStyle(node);
    if (style.display === 'none' || style.visibility === 'hidden' || Number(style.opacity) === 0) return false;
    const rect = node.getBoundingClientRect();
    return rect.width >= minimum && rect.height >= minimum;
  };
  const qrGraphic = () => {
    const rootSelector = [
      '[data-testid*="qr" i]', '[aria-label*="qr" i]', '[class*="qr-code" i]',
      '[class*="qr_code" i]', '[class~="qr" i]'
    ].join(',');
    const graphics = new Set();
    for (const root of document.querySelectorAll(rootSelector)) {
      if (!visible(root, 32)) continue;
      const descendants = Array.from(root.querySelectorAll('canvas,svg,img')).filter(node => {
        if (!visible(node, 96)) return false;
        const rect = node.getBoundingClientRect();
        const ratio = Math.abs(rect.width - rect.height) / Math.max(rect.width, rect.height);
        return rect.width <= 640 && rect.height <= 640 && ratio <= 0.15;
      });
      if (descendants.length === 1) graphics.add(descendants[0]);
    }
    return graphics.size === 1 ? Array.from(graphics)[0] : null;
  };
  const qrCandidate = () => {
    const graphic = qrGraphic();
    if (!graphic) return null;
    const rect = graphic.getBoundingClientRect();
    return {x: rect.x, y: rect.y, width: rect.width, height: rect.height};
  };
  const phoneCandidate = () => {
    if (qrCandidate()) return null;
    const inputs = Array.from(document.querySelectorAll(
      'input[type="tel"],input[autocomplete="tel"],input[inputmode="tel"]'
    )).filter(node => visible(node, 1));
    return inputs.length === 1 ? inputs[0] : null;
  };
  const authenticated = () => Array.from(document.querySelectorAll(
    '[data-testid="chat-list"],[class*="chat-list" i],[class*="chatlist" i],#column-left [class*="chat" i],[id="dialogs"]'
  )).some(node => visible(node, 32));
  const loading = () => Array.from(document.querySelectorAll(
    '[aria-busy="true"],[role="progressbar"],[class*="preloader" i],[class*="loading" i]'
  )).some(node => visible(node, 1));
  const failed = () => Array.from(document.querySelectorAll(
    '[role="alert"],[data-testid*="error" i],[class*="error" i]'
  )).some(node => visible(node, 1));
  window.__task22QrGraphic = qrGraphic;
  window.__task22QrBox = qrCandidate;
  window.__task22DomState = () => {
    if (document.body?.dataset.task22Auth === '1' || authenticated()) return 'auth';
    if (qrCandidate()) return 'qr';
    if (phoneCandidate()) return 'phone';
    if (failed()) return 'error';
    return loading() ? 'loading' : 'blank';
  };
})();
c                J   K   | j                  t               d {    y 7 wr    )evaluateSTATE_HELPER)r   s    r'   install_state_helperrT    s     
--
%%%s   #!#c                8  K   |dz  }	 | j                  d||d       d {   S 7 # t        $ rf}d}t        j                  t              5  | j                  d       d {  7  }|dv r|}d d d        n# 1 sw Y   nxY wt	        d| d      |d }~ww xY ww)	N  a  
            ({expected, timeoutMs}) => new Promise((resolve, reject) => {
              const matches = () => {
                const state = window.__task22DomState?.() || 'unknown';
                return expected === 'qr_or_auth' ? ['qr', 'auth', 'phone', 'error'].includes(state) : state === expected;
              };
              if (matches()) return resolve(window.__task22DomState());
              const observer = new MutationObserver(() => {
                if (!matches()) return;
                observer.disconnect();
                clearTimeout(timer);
                resolve(window.__task22DomState());
              });
              observer.observe(document.documentElement, {attributes: true, childList: true, subtree: true});
              const timer = setTimeout(() => {
                observer.disconnect();
                reject(new Error('state_timeout'));
              }, timeoutMs);
            })
            )r   	timeoutMsblankz,() => window.__task22DomState?.() || 'blank'>   rX  r|   phoneloadingr_   _state)rR  ry   
contextlibsuppressr   )r   r   timeout_seconds
timeout_msr   stater   s          r'   wait_for_statera    s      4'J<]]( "
;+
 
 	
 
.  <  1--(VWWWE>> 211 VE7&12;<sT   B( &( B( 	BBA6!A$"A6-	B6A?	;BBBc           
     X   t        dt        j                  t        | d   | d         dz              }t        d| d   |z
        }t        d| d   |z
        }t        t	        |d         | d   | d   z   |z         }t        t	        |d         | d   | d   z   |z         }||||z
  ||z
  dS )	Nr   r   r   gQ?g        xyrc  rd  r   r   )r   mathceilr   float)boxviewportpadlefttoprightbottoms          r'   padded_cliprp  5  s     b$))CGc(m<tCD
ECsCHsN#D
c3s8c>
"Chw'(#c(S\*AC*GHEx)*CHs8},Ds,JKFC%$,&3,OOr(   c           
       K   	 | j                  dt        dt        |dz                     d {   t        t              st	        d      d}t        fd|D              rt	        d      |D ci c]  }|t        |          }}|d   d	k  s|d
   d	k  rt	        d      |S 7 y# t        $ r}t	        d      |d }~ww xY wc c}w w)Na&  
            timeoutMs => new Promise((resolve, reject) => {
              let graphic = null;
              let previous = null;
              let stableFrames = 0;
              let frame = 0;
              const timer = setTimeout(() => {
                cancelAnimationFrame(frame);
                reject(new Error('qr_stability_timeout'));
              }, timeoutMs);
              const step = () => {
                const candidate = window.__task22QrGraphic?.() || null;
                if (!candidate || !candidate.isConnected) {
                  graphic = null; previous = null; stableFrames = 0;
                } else {
                  const rect = candidate.getBoundingClientRect();
                  const box = {x: rect.x, y: rect.y, width: rect.width, height: rect.height};
                  if (candidate !== graphic || !previous) {
                    graphic = candidate; stableFrames = 0;
                  } else {
                    const delta = Math.max(...Object.keys(box).map(key => Math.abs(box[key] - previous[key])));
                    stableFrames = delta <= 0.5 ? stableFrames + 1 : 0;
                  }
                  previous = box;
                  if (stableFrames >= 3) {
                    clearTimeout(timer);
                    window.__task22StableQrGraphic = graphic;
                    resolve(box);
                    return;
                  }
                }
                frame = requestAnimationFrame(step);
              };
              frame = requestAnimationFrame(step);
            })
            rO   rV  qr_stability_timeoutqr_not_foundre  c              3  ^   K   | ]$  }|vxs t        |   t        t        f        & y wr    )ru   intrh  ).0keyr   s     r'   	<genexpr>z stable_qr_box.<locals>.<genexpr>o  s3     
\S[C3eG:eCj3,#GGGS[s   *-r   `   r   )	rR  r   ru  ry   r   ru   rX   anyrh  )r   r^  r   requiredrw  ri  r   s         @r'   stable_qr_boxr|  A  s     )<mm#H 3-./K&
 &
R eT">**,H

\S[
\\>**-5
6Xc3eCj!!XC
6
7|bCMB.>**Jc&
N  <12;< 7sD   C+B, B*B, A C5C	C*B, ,	C5CCCc                T   K   t        | j                  d|       d {         S 7 w)Na  
            expected => {
              const graphic = window.__task22StableQrGraphic;
              if (!graphic || !graphic.isConnected || window.__task22QrGraphic?.() !== graphic) return false;
              const rect = graphic.getBoundingClientRect();
              return Math.max(
                Math.abs(rect.x - expected.x), Math.abs(rect.y - expected.y),
                Math.abs(rect.width - expected.width), Math.abs(rect.height - expected.height)
              ) <= 0.5;
            }
            )r   rR  )r   ri  s     r'   stable_qr_unchangedr~  w  s3     mm
 
 	
 	
s   (&	(c           	        g d
fd}t              D ]  } || |z  |dz   z   |d        t              D ],  } |t              D cg c]  }| |z  |z       c}|d       . t               }D ]Z  \  }}|dk  r|dk  r|j                  d       "|dkD  r|dk  r|j                  d       >|dk  sD|dkD  sJ|j                  d	       \ |S c c}w )Nc                z  	
 g }d}t        dt        |       dz         D ]A  }|t        |       k  r| |   dk  | |   dk  k(  r#|j                  | |   dk  ||z
  |f       |}C t        t        |      dz
        D ]  }|||dz    }|D cg c]  }|d   	 c}g dk7  r$|D cg c]  }|d   	 c}	t        	      dz  

dk  rKt	        	
fdd	D              rat        	d
   
dz  z
        
dz  kD  r||d
   d
   |d
   d   d
z  z   }j                  |r
|z  |z  fn	|z  |z  f        y c c}w c c}w )Nr   rO            )TFTFT   c              3  L   K   | ]  }t        |   z
        d z  kD    yw)g      ?N)abs)rv  poslengthsunits     r'   rx  z8_finder_pattern_corners.<locals>.scan.<locals>.<genexpr>  s)     R\c3ws|d*+dTk9\s   !$)r   rO      r     r  g      ?)ranger   appendsumrz  r  )linefixedverticalrunsstartindexsampler   centerr  r  r   hitsr   s            @@r'   scanz%_finder_pattern_corners.<locals>.scan  sp   ,.1c$i!m,Es4y d5kC&7T%[3=N%OKKes*EEM5ABE	 -
 3t9q=)E%%!),F$*+FDQF+/OO+1264tAw62Gw<!#DaxR\RR71:q()D4K7AYq\F1IaL1$44FKKH86TY>[`ci[iJjk *+2s   
D3#D8rO   FTg?top_leftg?	top_rightbottom_left)r  	list[int]r  ru  r  r   r*   r+   )r  setadd)pixelsr   r   r  rd  rc  cornersr  s    ``    @r'   _finder_pattern_cornersr    s    &(Dl. 6]VAIQ%0!U; 5\U6];]fQY]#];QE  G1t8DKK
#X!d(KK$X!d(KK&  N <s   C
c                   t        j                  t        j                  |             5 }|j	                  d      j                  d      }|j                         D cg c]  }t        |       }}d d d        t              t        |      z
  }t        d |D              t        |      z  }t        |dd      }|dk\  xr d|cxk  xr dk  nc xr |h dk(  S c c}w # 1 sw Y   pxY w)	NL)ry  ry  c              3  &   K   | ]	  }|d k    yw)P   Nr   )rv  pixels     r'   rx  z$qr_visual_quality.<locals>.<genexpr>  s     7u
s   ry  x   gQ?g333333?>   r  r  r  )r   r   ioBytesIOconvertresizetobytesru  r   r   r  r   r  )pngimage	grayscaler  r  contrastdark_fractionfinderss           r'   qr_visual_qualityr    s    	BJJsO	$MM#&--h7	*3*;*;*=>*=#e**=> 
% 6{S[(H777#f+EM%fb"5GC 	@M)T)	@??	 ? 
%	$s   3CC.CCC(c                  K   t        j                         j                         |z   }d }d }t        j                         j                         |k  r|t        j                         j                         z
  }t        | |       d {   }t	        |t
              }| j                  |       d {   }	t        | |       d {   r|	}n&t        j                         j                         |k  r||t        d      t        |      st        d      |dz  | dz  }
t        |
|       |dz  | dz  }| j                  d|       d {    	 | j                  d	       d {   }| j                  d
       d {    t        ||       t        ||
||d      S 7 7 7 7 Z7 A7 *# | j                  d
       d {  7   w xY ww)N)clipqr_changed_during_captureqr_visual_check_failedr   z-qr.pngz-qr-redacted.pnga.  
        box => {
          const previous = document.getElementById('__task22_qr_redaction');
          previous?.remove();
          const mask = document.createElement('div');
          mask.id = '__task22_qr_redaction';
          mask.setAttribute('aria-label', 'QR redacted');
          const margin = 10;
          mask.style.cssText = [
            'position:absolute', 'z-index:2147483647', 'pointer-events:none',
            `left:${Math.max(0, box.x + window.scrollX - margin)}px`,
            `top:${Math.max(0, box.y + window.scrollY - margin)}px`,
            `width:${box.width + margin * 2}px`, `height:${box.height + margin * 2}px`,
            'background:#101828', 'border:2px solid #ffffff', 'box-sizing:border-box'
          ].join(';');
          document.body.append(mask);
        }
        T	full_pagez@() => document.getElementById('__task22_qr_redaction')?.remove())rA  get_running_looptimer|  rp  r   
screenshotr~  r   r  r   rR  r   )r   r   r   r^  deadlineri  cropr   r  	candidater   r   proofs                r'   
capture_qrr    s     '')..0?BH#'CD

"
"
$
)
)
+h
6w779>>@@	!$	223)//t/44	$T3///D 
"
"
$
)
)
+h
6 {dl677T"344[ dV7#33G$#.>&??J
--	$ 	'  *`ooo55mm^___U#4*c488Q 34/, 6_dmm^___s   BGF!)G/F$0GF&,G1AGF(GF. (F*)F. -GF, G$G&G(G*F. ,G.G
GG

Gc                   K   |dz  | dz  }| j                  d       d {    	 | j                  d       d {   }| j                  d       d {    t        ||       |S 7 F7 -7 # | j                  d       d {  7   w xY ww)Nr   z-authenticated-redacted.pnga  
        () => {
          const previous = document.getElementById('__task22_full_redaction');
          previous?.remove();
          const mask = document.createElement('div');
          mask.id = '__task22_full_redaction';
          mask.setAttribute('aria-label', 'Authenticated Telegram UI redacted');
          mask.style.cssText = [
            'position:absolute', 'z-index:2147483647', 'pointer-events:none',
            'left:0', 'top:0', `width:${Math.max(document.documentElement.scrollWidth, innerWidth)}px`,
            `height:${Math.max(document.documentElement.scrollHeight, innerHeight)}px`,
            'background:#101828'
          ].join(';');
          document.body.append(mask);
        }
        Tr  zB() => document.getElementById('__task22_full_redaction')?.remove())rR  r  r   )r   r   r   r   r  s        r'   capture_authenticated_redactionr    s     #.I&JJJ
--	  $booo55mm`aaaU#/& 6admm`aaasT    BA)BA/ A+A/ BA-B+A/ -B/BBBB)r  c               &  K   t               j                          d {   }|d|_        	 |j                  j	                  t        |       |t        dg        d {   }|d|_        t        ||      }|j                  |       d {    |j                  r|j                  d   n|j                          d {   }|j                  |       t        ||||      S 7 7 # t        $ r |j                          d {  7    w xY w7 7 Pw)Nrj   F)headlessrj  accept_downloadspermissionsrk   r   )r   r  r5   chromiumlaunch_persistent_contextr)   r   r   stopr   r)  pagesnew_pagerM  r   )r   r  r  r  r   r   r   r   s           r'   open_page_sessionr    s
     ()//11J,
"++EEL" F 
 
 +5E
--
   &}}7==8H8H8J2JD	tweZ88) 2
  oo !2Jsb   DC"D0C& C$C& ")DD2D>D?$D$C& &D
DD

DDc                   K   t        j                  t              5  | j                  j	                          d {    d d d        | j
                  j                          d {    y 7 /# 1 sw Y   .xY w7 wr    )r\  r]  ry   r   r   r   r  )sessions    r'   close_page_sessionr  2  sY     			_	-oo##%%% 
.



!
!
### 	& 
.	-#s7   A:A,A*A,%A:$A8%A:*A,,A51A:c                  K   t        |      s|j                  d      st        d      |d|_        	 | j	                  |d|dz         d {    t        |        d {    y 7 7 # t        $ r}t        d      |d }~ww xY ww)Nhttp://127.0.0.1:navigation_rejectedrl   domcontentloadedrV  
wait_untiltimeoutrc   )r  rv   r   r5   gotorT  ry   )r   r/  r^  r  r   s        r'   loadr  8  s      sCNN3F$G011(9ii(:OVZDZi[[["4((( 	\( 9./S89sL   1BA+ A'A+ !A)"A+ &B'A+ )A+ +	B4B  BBc               ~  K   t        | |      }t        ||||       d {   }	 t        |j                  |||       d {    |d|_        t        |j                  d|       d {   }	|	dk(  r||	d fS |	dk(  rt        d      |	dk(  rt        d      |	d	k7  rt        d
      |d|_        ||	t        |j                  | ||       d {   fS 7 7 7 n7 # t        t        t        f$ rI t        j                  t        t              5  t        |       d {  7   d d d         # 1 sw Y    xY ww xY ww)N)r  r  r  rm   
qr_or_authauthrY  login_phone_stater|   login_error_stateqrlogin_blank_statern   )r   r  r  r   r5   ra  r   r  ry   rz   r\  r]  r  )
r   r   r/  r  r^  r  r  r   r  r`  s
             r'   prepare_roler  I  sV     4&G%%	 G7<<o{CCC" ,K$W\\<QQF?E4''G233G233D=233" ,KZLL	&
  
 
 	
+ 	D R 
 /73   ':$W--- ; ;s   D=CD=C C'C *C+C 8D=9AC CC D=C C C 2D:D-D!D-$	D:-D6	2D::D=c           	     @  K   t        t        | j                              }| j                  t	        d      t               }t        || j                  t        d | j                  | j                   |       d {   \  }}}	 t        |       |dk(  rrt        d| j                  | j                  rdndd       | j                  r*t        j                         j!                          d {    	 t#        |       d {    y |t	        d      t        d	t%        |j&                        t%        |j(                        | j                  d
d       | j                  s	 t#        |       d {    y t+        |j,                  d| j.                         d {    t        d| j                  dd       t        j                         j!                          d {    t#        |       d {    y 7 {7 7 7 7 e7 $7 # t#        |       d {  7   w xY ww)N#fixture_only_available_to_self_testr/  r  r^  r  r  r  Tpausedclosedauthenticatedr   r`  rs  Fqr_ready)r  r  r  r   r`  )r   r	   session_rootfixture_urlr   r2   r  r   OFFICIAL_URLr^  headedvalidate_live_networkr   interactiverA  Eventwaitr  r)   r   r   ra  r   auth_timeout_seconds)argsr   r  r  r`  captures         r'   command_preparer  u  s    D!2!234D#@AA!#K$0		,,[[% GUG*k*F?4QUQaQaXgopqmmo**,,,$ !)))# ?~..!&W//0'//*		#	
 
 !)))	 W\\643L3LMMMtTYYJKmmo""$$$ )))C -& 	*)	 	N$) )))s   A8H:G5;HA(H ,G8-H 2H G;HAH !H/G=0H5$H G?AH HH !H/H0H8H ;H=H?H H HHHHHc                  K   t        t        | j                              }t        || j                        }t        |d | j                          d {   }	 t        |j                  t        | j                         d {    t        |j                  d| j                         d {   }|dk7  r.t        d| j                  dd       	 t        |       d {    y t        |j                  || j                         d {   }t        dt        |      | j                  dd       t        |       d {    y 7 7 7 7 k7 C7 # t        |       d {  7   w xY ww)	Nr  r  r  r  Fr  r  T)r  r  r   r`  )r   r	   r  r   r   r  r  r  r   r  r^  ra  r   r  r  r)   )r  r   r   r  r`  r  s         r'   command_capturer    s!    D!2!234D4+G%gdQUQ\Q\_]]G	*7<<t/C/CDDD$W\\<AUAUVVF?5$))hOP !))) 6gllD$))TTtc%j$))V^_` ))) ^DV 	* U 	* )))s   AE'EE'(E E(E *E+"E E'EE'"$E E
'E .E'<E=E'E E E'
E E'E$E E$$E'c                   K   	 | j                  d       d{    |j                          d{    y7 7 # t        $ r Y yw xY ww)zPClear only browser-local Telegram state; no account identity is read or emitted.as  
            async () => {
              localStorage.clear();
              sessionStorage.clear();
              await Promise.all((await caches.keys()).map(key => caches.delete(key)));
              if (indexedDB.databases) {
                const databases = await indexedDB.databases();
                await Promise.all(databases.filter(item => item.name).map(item => new Promise(resolve => {
                  const request = indexedDB.deleteDatabase(item.name);
                  request.onsuccess = request.onerror = request.onblocked = () => resolve();
                })));
              }
            }
            NFT)rR  clear_cookiesry   )r   r   s     r'   clear_local_site_datar    s[     mm
 	
 	
  ##%%% '	
  	& s=   A	: 6: 8: A	: : 	AA	AA	c                  K   	 | j                  t         dd|dz         d{    t        |        d{    | j                  t	        j
                  dt        j                              }|j                          d{   dk7  s|j                          d{   sy|j                  |dz  	       d{    y
7 7 7 B7 )7 # t        $ r Y yw xY ww)zRAttempt the visible local logout control only when cleanup explicitly requests it.z	#settingsr  rV  r  Nu   ^(log\s*out|로그아웃)$rO   Fr  T)r  r  rT  get_by_textrecompile
IGNORECASEcount
is_visibleclickry   )r   r^  logouts      r'   attempt_web_logoutr    s     ii<.	2?Q[jmq[qirrr"4(((!!"**-JBMM"Z[1$&2C2C2E,E,Ell?T#9l:::  	s(,E: s   C!C CC CA
C CC CC #C$C <C
=C CC C C C 
C 	CCCCc                  K   t        t        | j                              }d}d}| j                  rt        D ]  }t        ||      }t        |d d       d {   }	 t        |j                  t        | j                         d {    t        |j                  d| j                         d {   }|dk(  rXt        |j                  | j                         d {   xs |}t        |j                  |j                         d {   xs |}t        |       d {     t!        |       t#        |d|dd       y 7 7 7 7 k7 A7 ,# t        |       d {  7   w xY ww)NFTr  r  r  cleaned)local_browser_state_clearedprofile_directories_removedremote_logout_attemptedr`  )r   r	   r  r  r   r   r  r  r   r  r^  ra  r  r  r   r  r  r   )r  r   local_clearr  r   r   r  r`  s           r'   command_cleanupr    s7    D!2!234DK#{{D"4.G-gdUYZZG27<<t7K7KLLL,W\\<I]I]^^F?4Fw||UYUiUi4j.j  /F  oF+(=gllGOO(\"\"k`kK(111  t+6+/'>		
 [L^.j"\1(111s   AE&EE&(EE(E.E/,EE+EE	EE&E#E&EEE	EE&E#E
E##E&c                       e Zd ZdZddZddZy)FixtureHandlerz&fixture-secret-must-never-reach-outputc                $   d| j                    dj                         }| j                  d       | j                  dd       | j                  dt	        t        |                   | j                          | j                  j                  |       y )Nau  <!doctype html>
<html><head><meta charset='utf-8'><style>
body { margin:0; background:#f5f7fb; }
#shell { width:920px; height:680px; margin:40px auto; background:white; border:1px solid #ccd5e1; }
#fixture-qr { width:280px; height:280px; margin:130px auto; display:block; }
#fixture-main { display:none; width:100%; height:100%; }
</style></head><body data-fixture-secret='a!  '>
<main id='shell'><div data-testid='fixture-qr-login'><canvas id='fixture-qr' width='280' height='280'></canvas><canvas id='fixture-overlay' width='54' height='54' style='width:54px;height:54px'></canvas></div>
<section id='fixture-main' class='chat-list'></section><button id='fixture-auth'>Fixture authentication event</button></main>
<script>
const canvas = document.getElementById('fixture-qr'); const context = canvas.getContext('2d');
context.fillStyle = '#fff'; context.fillRect(0, 0, 280, 280); context.fillStyle = '#000';
for (let y = 16; y < 264; y += 8) for (let x = 16; x < 264; x += 8) if (((x / 8) * 7 + (y / 8) * 11) % 5 < 2) context.fillRect(x, y, 8, 8);
const finder = (x, y) => {
  context.fillStyle = '#fff'; context.fillRect(x - 8, y - 8, 72, 72);
  context.fillStyle = '#000'; context.fillRect(x, y, 56, 56);
  context.fillStyle = '#fff'; context.fillRect(x + 8, y + 8, 40, 40);
  context.fillStyle = '#000'; context.fillRect(x + 16, y + 16, 24, 24);
};
finder(16, 16); finder(208, 16); finder(16, 208);
requestAnimationFrame(() => {
  canvas.style.width = '197.5px'; canvas.style.height = '197.5px';
  requestAnimationFrame(() => {
    canvas.style.width = '308px'; canvas.style.height = '308px';
    requestAnimationFrame(() => { canvas.style.width = '280px'; canvas.style.height = '280px'; });
  });
});
document.getElementById('fixture-auth').addEventListener('click', () => {
  document.body.dataset.task22Auth = '1'; canvas.style.display = 'none'; document.getElementById('fixture-main').style.display = 'block';
});
</script></body></html>   zContent-Typeztext/html; charset=utf-8zContent-Length)	secretencodesend_responsesend_headerr)   r   end_headerswfiler   )r%   r~   s     r'   do_GETzFixtureHandler.do_GET  s    + ,0;;- 8< "68= 	> 	3)CD)3s7|+<=

!r(   c                     y r    r   )r%   formatr  s      r'   log_messagezFixtureHandler.log_message  s    r(   Nr   )r  r)   r  objectr*   r+   )r,   r-   r.   r  r  r  r   r(   r'   r  r    s    5F$"Lr(   r  c               #    K   t        dt              } t        j                  | j                  d      }|j                          	 d| j                  d    d | j                          |j                  d       | j                          y # | j                          |j                  d       | j                          w xY ww)	N)z	127.0.0.1r   T)targetdaemonr  rO   /r  r  )
r   r  	threadingThreadserve_foreverr  server_addressshutdownjoinserver_close)serverworkers     r'   fixture_serverr*    s      !1>BFV%9%9$GF
LLN!&"7"7":!;1==A 	As   ACB 3C4CCc           	        t        j                  | j                        5 }t        dt	        | j
                  d   | j
                  d   dz  z               }t        dt	        | j
                  d   | j
                  d   dz  z               }|j                  d      j                  ||f      }d d d        t        k7  rt        d      y # 1 sw Y   xY w)	Nr   rc  r   r  rd  r   RGBfixture_redaction_failed)
r   r   r   r   ru  r   r  getpixelREDACTION_RGBr   )r  r  rc  rd  r  s        r'   assert_redactionr0  ,  s    	G&&	'53w~~c*W^^G-Dq-HHIJ3w~~c*W^^H-E-IIJKe$--q!f5 
( 566 	 
(	's   BC

Cc            
       K   t        j                  d      5 } t               5 }t        t	        |             |j                  d      }t        d||dd       d {   \  }}}t        |       d {    t        d||dd       d {   \  }}}t        |       d {    |d	k7  s	|d	k7  s||t        d
      t        d |j                  |j                  |j                  |j                  fD              st        d      t        fdt        D              st        d      t        |       t        j                  |j                        5 }	|	j                   dk\  s|	j"                  dk\  rt        d      	 d d d        t%        d      }
t'        |
|d       d {   }	 t)        |j*                  |d       d {    |j*                  j-                  d       d {    t        |       d {    t%        d      }t'        ||d       d {   }	 t)        |j*                  |d       d {    |j*                  j-                  d       d {   t        d      |j*                  j-                  d       d {    |j*                  j-                  d       d {   dk7  rt        d      |j*                  j-                  d       d {    |j*                  j-                  d       d {   d	k7  rt        d      |j*                  j-                  d       d {    |j*                  j-                  d       d {   dk7  rt        d      |j*                  j-                  d       d {    t/        j0                  t3        |j*                  d d            }|j*                  j5                  d!      j7                          d {    | d {   d k7  rt        d"      	 |j*                  j9                  d#d$%       d {    |j<                  j>                  d&k  rt        d'      	 t        |       d {    tA        jB                         }tE        jF                  |      5  tI        d(dd)d*       tK        tM        jN                  d(d+             d {    d d d        tP        jR                  |jU                         v rt        d,      jW                         rt        d-      	 d d d        d d d        y 7 7 7 7 # 1 sw Y   xY w7 7 y7 Y7 I# t        |       d {  7   w xY w7 C7 &7 7 7 7 7 m7 ?7 7 7 7 7 a# t:        $ r Y kw xY w7 <# t        |       d {  7   w xY w7 # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   y xY ww).Nztask22-harness-test-)r   r   r   
   T)r/  r  r^  r  r   r  fixture_qr_state_failedc              3  <   K   | ]  }t        |t                y wr    )r   r   )rv  r   s     r'   rx  zself_test.<locals>.<genexpr>M  s#       i  <h4:dI.  <hs   fixture_permissions_failedc              3  J   K   | ]  }t        | d z  t                yw)r   N)r   r   )rv  r   r   s     r'   rx  zself_test.<locals>.<genexpr>O  s'     ZTYD:dvX%66GTYs    #"fixture_profile_permissions_failedi  i  fixture_qr_crop_failedr  z;() => localStorage.setItem('fixture-isolation', 'customer')z/() => localStorage.getItem('fixture-isolation')fixture_role_isolation_faileda  
                () => {
                  const root = document.querySelector('[data-testid="fixture-qr-login"]');
                  root.removeAttribute('data-testid');
                  root.className = 'generic-login';
                }
                z() => window.__task22DomState()rX  $fixture_bare_graphic_rejected_failedz
                () => {
                  const root = document.querySelector('.generic-login');
                  root.className = '';
                  root.dataset.testid = 'fixture-qr-login';
                }
                fixture_semantic_qr_failedad  
                () => {
                  document.querySelector('[data-testid="fixture-qr-login"]').style.display = 'none';
                  const phone = document.createElement('input');
                  phone.type = 'tel';
                  phone.id = 'fixture-phone';
                  document.body.append(phone);
                }
                rY  fixture_phone_state_failedz
                () => {
                  document.getElementById('fixture-phone').remove();
                  document.querySelector('[data-testid="fixture-qr-login"]').style.display = '';
                }
                r  z#fixture-authfixture_auth_event_failedzhttps://example.invalid/blockedi  r  rO   fixture_navigation_guard_failedFr  r  )r  r  r^  fixture_secret_output_failedfixture_cleanup_failed),r   TemporaryDirectoryr*  r   r	   removesuffixr  r  r   allr   r   r   r0  r   r   r   r   r   r  r  r   rR  rA  rB  ra  locatorr  r  ry   r   r  r  StringIOr\  redirect_stdoutr   r  argparse	Namespacer  r  getvalueexists)	temporaryr  r  customer_sessioncustomer_statecustomer_capturetrainer_sessiontrainer_statetrainer_capturer  customer_profiler   trainer_profiler   authenticated_waitrenderedr   s                   @r'   	self_testrV  5  s    		$	$,B	CyR`Rbfqd9o.$11#6CO)D
 >
:.*: !!1222@L)A
 ;
7 !111T!]d%:>N>VZiZq899  i<L<T<TVfVqVq  tC  tK  tK  M\  Mg  Mg  <h  i  i;<<ZTYZZCDD)*ZZ(001U{{c!U\\S%8"#;<< &9 2 (j9*+;Neijj	/x}}k2666--(()fggg$X...&tY7)/.cghh:	.w||["555\\**+\]]i"#BCC,,''   \\**+LMMQXX"#IJJ,,''   \\**+LMMQUU"#?@@,,''
 
 
 \\**+LMMQXX"#?@@,,''   ")!4!4^GLLRXZ\5]!^,,&&7==???''61"#>??ll''(ISX'YYY }}--1"#DEE 2 %W---;;=''15*zRS!""UTVW   2
   H$5$5$77=>>;;=788 [ Sc	C	C>
 	3;
 	2 21
 k6g.$X...h5] N N
 N @' Z" 
 .$W---
 21M ScRb	C	Csd  WW:WT' W6T*7WT-W&T0'B3W*T3%W*U +W0U
U"U-U.U2W U	!W"U%#W(VU("V%U+&-VU."V6U170V'U4("V
U70V;U:<"VU=0VV AV*V+	V4V5V V(V	)V-$VW V!-W4V:V8
V:AWW	W'W*W-W0W3T=8	WUU	WU"UU""W(V+V.V1V4V7V:V=V VVV	V	VVVVWV5.V1/V55W8V::W?WW	WWWc                V   K   t                d {    t        dddddd       y 7 w)Npass)rq   r
  r  role_isolationr`  )rV  r   )_argss    r'   command_self_testr[    s2     
+!$	
 s   )')c                    | j                         }|d   }t        |t              sJ |j                  d      dk7  s*|j                  dd      dk7  s|j                  dd      dk7  rt	        d|      y )NrU   r,  r  rG   r   r;  rf   )r[   ru   rX   rw   r   )r  r[   rU   s      r'   r  r    sv    !!#GXFfd###

$%*::i#q(::&*a/7AA 0r(   c           
       K   t        | j                        j                         }t        | j                        j                         }t	               }d }d }d }d }	 d|_        t               }t        |dt        d | j                  d|       d {   \  }}	}d|_        t        |       d {    |	dk7  s||j                  st        d      d|_        t        |       t        |       t        ||j                  j!                                t        ||j                  j!                                d	|_        |	 t1        |       ||||fD ]4  }t3        j4                  t6              5  |j9                          d d d        6 ||n|d	f\  }
}|
J ||_        |j;                  |
|
      }t=        |j?                  d            }t        ||      |
|t        d      tA        i |jC                         dt=        |      t=        |      dd       y 7 7 q# t        t"        t$        t&        t(        t*        t,        t.        f$ r}
|
|j
                  f}Y d }
~
-d }
~
ww xY w# t        t$        f$ r}
|
}Y d }
~
7d }
~
ww xY w# d	|_        |+	 t1        |       w # t        t$        f$ r}
|
}Y d }
~
w d }
~
ww xY ww xY w# 1 sw Y   zxY ww)Nri   r   Tr  rp   r  live_qr_ui_not_detectedro   rq   r\   r#   r  )profile_removedr  r  r`  )"r	   r   r   r   r2   r5   r   r  r  r^  r  r   r   r  r0  r   r   ry   rz   AttributeErrorKeyErrorRuntimeError	TypeErrorr  r  r\  r]  r   r   r   r)   popr   r[   )r  r   r   r  r   primaryr]   r  r  r`  r|   r   r5   r~   r#   s                  r'   command_live_smokerf    s    doo&//1J4<< ))+G!#KD04G*.M"G&&+(4 00#)
 #
 , )))D=GO73E3E8990k*!Z!3!3!>!>!@AWgoo88:; &&"4( m7)D$$%67 87 * #*"5wM9;Uu   !--e=-Q7;;v&'4)u4455	
!!#	
#_g,	
e#
 	* 		 
- +++,
-  !'* & %&	 &&"4( '* & %&  87s   AK4H" HH" .H/BH" 6	K I+ $K/K BKH" H" "-I(I#J
 #I((J
 +J:J<KJK

K J! K !J<0J72K 7J<<K  KK	Kc                    t        j                  t              } | j                  dd      }|j	                  dd      }|j                  dt        	       |j	                  d
d      }|j                  dt               |j                  ddt               |j                  dd       |j                  ddd       |j                  dt        t               |j                  dt        t               |j                  dt         j                         |j	                  dd      }|j                  dt               |j                  ddt               |j                  dt        t               |j                  dd       |j	                  dd      }|j                  ddt               |j                  ddd       |j                  dt        t               |j	                  d d!       |j	                  d"d#      }|j                  d$d%       |j                  d&d%       |j                  dt        t               | S )'N)descriptioncommandT)destr{  initz-create one owner-only Task 22 browser session)helpz
--base-dir)r{   preparez&present one isolated official QR loginr   )choicesz--session-root)r{  r{   z--interactive
store_true)actionz--headedz*requires --interactive and a local display)rp  rl  z--timeout-seconds)r{   defaultz--auth-timeout-secondsz--fixture-urlr  z4verify boolean auth and save fully redacted UI proofrq   z4remove all Task 22 browser profiles and QR artifactsz--logoutz;after Task 25 only: attempt local Web logout before removal	self-testz-run only against a synthetic loopback fixture
live-smokez.one ephemeral unauthenticated official QR loadz--proof-path)r{  z	--qr-path)rG  ArgumentParserr/   add_subparsers
add_parseradd_argumentr	   r   ru  DEFAULT_TIMEOUT_SECONDSDEFAULT_AUTH_TIMEOUT_SECONDSSUPPRESS)resultcommandsrk  rm  r  rq   lives          r'   parserr~    s-   $$9F$$)d$CHv,[\Dl.!!)2Z![G/)DtD>L?kl,3@WX1Eabx/@/@A!!)2h!iG/)DtD,3@WXL9!!)2h!iG)DtDL?|},3@WX*YZ|2bcDnt4kD1)=TUMr(   c                  K   | j                   dk(  r-t        | j                        }t        t	        |      dd       y t        | dd      dk  st        | dd      dk  rt        d      | j                   d	k(  r7| j                  r| j                  st        d
      t        |        d {    y | j                   dk(  rt        |        d {    y | j                   dk(  rt        |        d {    y | j                   dk(  rt        |        d {    y | j                   dk(  rt        |        d {    y t        d      7 7 {7 Z7 97 w)Nrk  ready)r  r`  r^  rO   r   r  invalid_timeoutrm  headed_requires_interactiver  rq   rr  rs  invalid_command)ri  r   r   r   r)   r   r   r  r  r  r  r  r[  rf  )r  r   s     r'   dispatchr  +  s:    ||vdmm,c$i':;t&*a/74AWYZ3[_`3`,--||y ;;t//<==d###||y d###||y d###||{"%%%|||# &&&
(
)) 	$ 	$ 	$ 	& 	'sZ   B(E*E+"EE	"E0E1"EE"E6E7E	EEEEc                    t               j                         } 	 t        j                  t	        |              y	# t
        $ r1}t        d|j                  i|j                  ddi       Y d }~yd }~wt        $ r Y yt        t        f$ r t        ddd       Y yt        t        t        t        t         f$ r t        ddd       Y yw xY w)
Nr#   r`  r|   r     browser_or_filesystem_failure)r#   r`  internal_failurer   )r~  
parse_argsrA  runr  r   r   r#   r$   KeyboardInterruptry   rz   r`  ra  rb  rc  r  )r  r   s     r'   mainr  F  s    8 DHTN#   fchh@#++@w@A W% 5HIHlIzJ (7;<s'   9 	C'A..C<C+CC__main__)r   r   r*   r+   )r   r	   r*   r+   )r   r	   r~   bytesr*   r+   )r   r	   r   ru  r*   r   r    )r   zPath | Noner*   r	   )r   r	   r*   r	   )r   r	   r   r)   r*   r	   )rK   r)   r  rN  r*   r   )
rK   r)   r  r)   r  r)   r  r   r*   r   )rK   r)   r  r)   r  r)   r  r   r  rN  r*   r   rP  )r   r   r   r)   r^  ru  r*   r)   )ri  r   rj  r   r*   r   )r   r   r^  rh  r*   r   )r   r   ri  r   r*   r   )r  r  r   ru  r   ru  r*   zset[str])r  r  r*   r   )
r   r   r   r	   r   r)   r^  ru  r*   r   )r   r   r   r	   r   r)   r*   r	   )
r   r	   r  rN  r  r   r  rO  r*   r   )r  r   r*   r+   )
r   r   r/  r)   r^  ru  r  rO  r*   r+   )r   r	   r   r)   r/  r)   r  rN  r^  ru  r  r   r  rO  r*   z'tuple[PageSession, str, Capture | None])r  argparse.Namespacer*   r+   )r   r   r   r   r*   r   )r   r   r^  ru  r*   r   )r*   zIterator[str])r  r   r*   r+   r   )rZ  r  r*   r+   )r  r2   r*   r+   )r*   zargparse.ArgumentParser)r*   ru  )cr/   
__future__r   rG  rA  r\  r  r   rf  r   r  r   r   r!  collectionsr   collections.abcr   dataclassesr   http.serverr   r   pathlibr	   typingr
   urllib.parser   PILr   playwright.async_apir   r   r   r   r   r   ry   r  r   r   r   r   r   r   r   rx  ry  r/  rb  r   r2   r   r   r   r   r   r   r   r   r   r  r  r  r  r   rS  rT  ra  rp  r|  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r  contextmanagerr*  r0  rV  r[  r  rf  r~  r  r  r,   
SystemExitr   r(   r'   <module>r     s   #    	   	 	     $ ! C   !   :,('/	#'37, 7 " %< %@ @F $   $  P#.U
0+\	L  	
  
8 "&  	
   
2w) w)t;|& <F	P		P	P 	P3l&'T39
39
39 39 	39
 39lB +/99 9 	9
 (9 9<$ +/	9
9	9 9 (	9
 
92 +/)
)
) 
	)
 ) ) ) () -)X&*R* 46*+ *Z 	 	7o9d
	BEP F*6$ z
TV
 r(   