§
    ›ÇjÄ ã                  óÔ   — d Z ddlm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mZ g d
¢Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Zdd„Z G d„ d¦  «        ZdS )uj  The retry loop, and the actions that run inside it.

â›” THIS IS THE PIECE THAT FAILS SILENTLY, and the reason is the shape of the
loop: if a condition is checked ONCE and then acted on, the page can change
between the check and the action. It doesn't break: it breaks ONE TIME IN
TWENTY, when loading is slower than usual.

THE RIGHT SHAPE, and every line of this file exists to keep it:

    until it expires:
        RESOLVE THE SELECTOR FROM SCRATCH   <- don't reuse the old handle
        ask whether it is actionable
        get the point
        act
        if something says "it's not there anymore": START OVER

â›” **The selector is resolved on EVERY turn.** Reusing the previous turn's
handle is the mistake that makes the loop pointless: if the DOM has changed,
that handle points to a detached node, and the action goes nowhere without
saying anything.

â›” **And a timeout must say WHY.** A bare `TimeoutError` on a retry loop is
the least useful thing you can print: the reason for the last turn - "missing
visible", "the selector finds nothing", "no quad" - is the only information
that tells you what to look at.
é    )ÚannotationsN)ÚOptionalé   )Ú_pacingé   )ÚEvaluationError)ÚBUTTON_MASKÚKeyboardÚ
UnknownKey©ÚvisibleÚstableÚenabledc                  ó   — e Zd ZdZdS )ÚElementNotActionablezEThe loop timed out. The message carries the reason for the LAST turn.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úVC:\Projects\Historical\venv\Lib\site-packages\invisible_playwright/_juggler/actions.pyr   r   *   s   € € € € € ØOÐOÐOÐOr   r   c                  ó   — e Zd ZdZdS )ÚActionMisseduË  The event went out and landed on something other than the element.

    â›” NOT RETRYABLE, AND THAT IS THE WHOLE DIFFERENCE FROM `WrongHitTarget`.
    That one is raised BEFORE anything happened, so starting over is free.
    This one is raised after: a press has been delivered to whatever was under
    the pointer, and a loop that repeated the action would be pressing twice.

    It exists because the alternative was silence. Measured 2026-09-19 with
    a target that moves (`tests/gates/hover_non_mente.py` in the workbench):
    `hover()` returned normally 2 times out of 8 with the page having seen
    no event at all, and `click()` 8 times out of 8 - the hit-target check
    before the press passed, then the element left between `mousedown` and
    `mouseup`, the two landed on different nodes and no `click` was ever
    born. Nothing after the commit looked, for a reason that is right (see
    `_act_on_target`), so the caller was told "done". [B217]
    Nr   r   r   r   r   r   .   s   € € € € € ðð ð ð r   r   c                  ó   — e Zd ZdZdS )ÚWrongHitTargetuÛ  The event would have landed on ANOTHER element. RETRYABLE condition.

    â›” It's the window that the rest of the loop doesn't close, and it was
    MEASURED, not feared. Between the actionability check and the event a
    couple of commands go by; if the layout moves in that gap - a banner
    appearing, a font finishing loading, a `setTimeout` shifting the page -
    the point calculated earlier no longer belongs to the intended element.

    The case from 2026-08-27: a page that at 1200 ms reveals a block higher
    up. `dblclick` succeeded, the page saw NO `dblclick` event at all, and
    on the same page without that timer the same code worked. No error
    anywhere: the click had landed nineteen pixels higher.
    Nr   r   r   r   r   r   A   s   € € € € € ðð ð ð r   r   ÚreturnÚlistc                óŠ   — g }| D ]=}|                      t          |t          ¦  «        rd|int          |¦  «        ¦  «         Œ>|S )u«  A string becomes `{"valueOrLabel": ...}`, and that's NOT a detail.

    â›” THE INJECTED SCRIPT'S FILTER STARTS FROM `matches = true` AND NARROWS
    it down ONLY if the criterion carries one of `valueOrLabel`, `value`,
    `label` or `index`. A bare string has none of those, so every option
    matches and **the first one** gets picked.

    Measured on 2026-08-27 on a `<select>` with A/a and B/b: `["b"]`
    answered `['a']`, leaving the value at `a`. No error, no exception, the
    operation succeeded and the option was wrong - which is worse than a
    refusal, because the failure surfaces on the page later. With
    `[{"value": "b"}]` the same call answers `['b']`.
    ÚvalueOrLabel)ÚappendÚ
isinstanceÚstrÚdict)ÚoptionsÚoutÚos      r   Ú_normalize_optionsr)   Q   sS   € ð €CØð Kð KˆØ�
Š
­*°Q½Ñ*<Ô*<ÐI�N AÐ&Ð&Å$ÀqÁ'Ä'ÑJÔJÐJÐJØ€Jr   c            
      óp  — e Zd ZdZdZdddœdmd„Zd„ Zdnd
„Zdodpd„Zddddddddddœ	dqd„Z	drd„Z
d„ Zdddœdsd"„Zd#dddd$œdtd&„Zddddd'œdud(„Zddddd)dddd*œdvd1„Zddddddd2œdwd3„Zddddd'œdud4„Zddddd'œdud5„Zdddd6œdxd8„Zdddd9œdud:„Zddd;œdyd<„Zddd;œdyd=„Zdddd9œdud>„Zdoddd;œdzd@„ZdddddAœd{dD„ZdddEddFœd|dI„Zdddd9œdudJ„ZddddKœdydL„ZddMœd}dO„Zddd;œd~dR„Zd)dSœddX„Zdd)dYœd€dZ„Z dd)dYœd€d[„Z!dd)dd\œd�d]„Z"d‚d`„Z#dd)dddaœdƒdb„Z$dod„dc„Z%dddd9œd…dd„Z&deZ'd†dg„Z(dddddhœd‡dk„Z)dˆdl„Z*dS )‰ÚActionsr   N)Úsession_seedÚmotion_budget_sÚsessionr$   c               óÆ  — || _         || _        || _        || _        || _        d | _        d | _        d | _        || _        |�tddl	m
}m}	m}
 |                     |¦  «        | _        |	                     |¦  «        | _        	 ddlm} n# t           $ r d }Y nw xY w|� | |
|d¦  «        ¦  «        | _        || _        t%          ||| j        |¬¦  «        | _        d| _        d S )Nr   )ÚPointerPersonaÚTypingPersonaÚ	_sub_seed)ÚCursorMotionzserver:drag)Úacts©ç        r6   )Úcr.   Ú	lifecycleÚinjr,   Úpointer_personaÚtyping_personaÚmotionr-   Ú
_behaviourr0   r1   r2   Ú	from_seedÚ_motionr3   Ú	Exceptionr4   r
   ÚkeyboardÚposition)ÚselfÚ
connectionr.   r8   Úinjectedr4   r,   r-   r0   r1   r2   r3   s               r   Ú__init__zActions.__init__p   s4  € àˆŒØˆŒØ"ˆŒØˆŒð )ˆÔØ#ˆÔØ"ˆÔð ˆŒØ.ˆÔØÐ#ØMÐMÐMÐMÐMÐMÐMÐMÐMÐMØ#1×#;Ò#;¸LÑ#IÔ#IˆDÔ Ø"/×"9Ò"9¸,Ñ"GÔ"GˆDÔð$Ø2Ð2Ð2Ð2Ð2Ð2Ð2øÝð $ð $ð $Ø#���ð$øøøàÐ'Ø*˜l¨9¨9°\À=Ñ+QÔ+QÑRÔR�”ð ˆŒ	õ
 ! ¨W°dÔ6IØ&*ð,ñ ,ô ,ˆŒð #ˆŒˆˆs   ÂB ÂBÂBc                óô   — 	 | j                              | j        j        d¦  «        }n# t          $ r Y dS w xY wt          |t          ¦  «        sdS |                     d¦  «        |                     d¦  «        fS )u*  The main frame's viewport, or ``(None, None)`` when it cannot be read.

        â›” Asked of the PAGE, not of a stored viewport size. The window can be
        resized, and a value cached at launch is a second source for a fact the
        page already knows.

        â›” And ONE reader for two callers, since 2026-09-16. `_in_viewport`
        asked this question already; the drag's path needs the same answer to
        keep its waypoints somewhere an event can land. Asking twice in two
        shapes is how the two would come to disagree.
        z/({w: window.innerWidth, h: window.innerHeight}))NNÚwÚh)r9   Úevaluater8   Ú
main_framer@   r#   r%   Úget)rC   Úsizes     r   Ú	_viewportzActions._viewport§   s‡   € ð	Ø”8×$Ò$Ø”Ô)ØAñCô CˆDˆDøõ ð 	ð 	ð 	Ø�:�:ð	øøøå˜$¥Ñ%Ô%ð 	Ø�:Ø�xŠx˜‰}Œ}˜dŸhšh s™mœmÐ+Ð+s   ‚%( ¨
6µ6r   Úboolc                ó”   — |                       ¦   «         \  }}|�|€dS d|d         cxk    o|k    nc od|d         cxk    o|k    nc S )z>Is this main-frame point somewhere an event can actually land?NTr   r   )rN   )rC   ÚpointrH   rI   s       r   Ú_in_viewportzActions._in_viewport½   sp   € à�~Š~ÑÔ‰ˆˆ1ð ˆ9˜˜	Ø�4Ø�E˜!”HÐ!Ð!Ò!Ð! Ò!Ð!Ð!Ð!Ð8 a¨5°¬8Ð&8Ð&8Ò&8Ð&8°qÒ&8Ð&8Ð&8Ð&8Ð8r   Úframe_idÚelementc                ó:  — | j                              d||dœ| j        d¬¦  «        pi }|                     d¦  «        pg }|sdS |d         }|d         |d	         |d
         |d         g}t	          |t
          ¦  «        rfd|v rbd|v r^t          d„ |D ¦   «         ¦  «        t          |d         ¦  «        z   t          d„ |D ¦   «         ¦  «        t          |d         ¦  «        z   fS t          d„ |D ¦   «         ¦  «        dz  t          d„ |D ¦   «         ¦  «        dz  fS )u=  Where the event lands: the quad's centre, or the caller's offset.

        â›” No quad is NOT an error to propagate: it means "not visible
        right now", i.e. a RETRYABLE condition. Raising here would turn an
        element that's about to appear into a failure.

        â›” `position` IS PART OF THE CONTRACT AND WAS NOT IMPLEMENTED. Every
        pointer action in Playwright takes `position={x, y}` - an offset from
        the element's top-left - and this server ignored it, so a caller who
        pinned a point got the centre and no error. Two consequences, and the
        second is the one that matters here:

          * a documented option did nothing, silently;
          * the humanised cursor aims OFF-CENTRE on purpose and passes the
            point back through exactly this option. With it dropped, the last
            event of every element-targeted action landed on the exact
            geometric centre - one number, identical in every install,
            readable from a single event. The landing feature was inert on
            this transport and nothing failed.

        â›” Measured from the TOP-LEFT of the quad, not from the centre. The
        quad is in main-frame coordinates like everything else on this path,
        so the offset is added to its minimum x and y rather than to the mean.
        zPage.getContentQuads)ÚframeIdÚobjectIdé
   ©r.   ÚtimeoutÚquadsNr   Úp1Úp2Úp3Úp4ÚxÚyc              3  ó&   K  — | ]}|d          V — ŒdS ©r`   Nr   ©Ú.0Úps     r   ú	<genexpr>z(Actions._center_point.<locals>.<genexpr>è   ó&   è è € Ð/Ð/ 1˜˜#œÐ/Ð/Ð/Ð/Ð/Ð/r   c              3  ó&   K  — | ]}|d          V — ŒdS ©ra   Nr   rd   s     r   rg   z(Actions._center_point.<locals>.<genexpr>é   rh   r   c              3  ó&   K  — | ]}|d          V — ŒdS rc   r   rd   s     r   rg   z(Actions._center_point.<locals>.<genexpr>ê   ó&   è è € Ð+Ð+˜q�A�c”FÐ+Ð+Ð+Ð+Ð+Ð+r   g      @c              3  ó&   K  — | ]}|d          V — ŒdS rj   r   rd   s     r   rg   z(Actions._center_point.<locals>.<genexpr>ë   rl   r   )	r7   Úsendr.   rL   r#   r%   ÚminÚfloatÚsum)rC   rS   rT   rB   Úrr[   ÚqÚpointss           r   Ú_center_pointzActions._center_pointÆ   sV  € ð2 ŒF�KŠKÐ.Ø$,¸'ÐBÐBØ $¤°bð ñ :ô :ð @à=?ð 	
ð —’�g‘”Ð$ "ˆØð 	Ø�4Ø�!ŒHˆØ�D”'˜1˜Tœ7 A d¤G¨Q¨t¬WÐ5ˆÝ�h¥Ñ%Ô%ð 	H¨#°¨/¨/¸cÀX¸o¸oÝÐ/Ð/¨Ð/Ñ/Ô/Ñ/Ô/µ%¸À¼Ñ2FÔ2FÑFÝÐ/Ð/¨Ð/Ñ/Ô/Ñ/Ô/µ%¸À¼Ñ2FÔ2FÑFðHð HåÐ+Ð+ FÐ+Ñ+Ô+Ñ+Ô+¨cÑ1ÝÐ+Ð+ FÐ+Ñ+Ô+Ñ+Ô+¨cÑ1ð3ð 	3r   g      >@FT)	ÚstatesrZ   rS   rB   Ú
element_idÚtrialÚstrictÚforceÚneeds_pointÚselectorrZ   rp   úOptional[str]rw   rx   ry   rz   r{   c       	        ó  — |p| j         j        }|€t          d¦  «        ‚|€t          n|}t	          j        ¦   «         |z   }d}d}	 |dz  }d}d}	 |�|}n| j                             |||	¬¦  «        }d}|sd	}nV|rR|
sP| j                             |||¦  «        }| 	                    d
¦  «        sd| 	                    dd¦  «        z  }d}nd}nd}|rZ|rX|sV|r&	 |r|r| j         
                    ||¦  «         dS dS dS  |||d¦  «        |r|r| j         
                    ||¦  «         S S S |�r|�r|                      |||¦  «        }|�k|                      |¦  «        sV| j                             ||¦  «        r$d}	 |r|r| j         
                    ||¦  «         �ŒY|                      |||¦  «        }|€d}n„|rT|
s,|                      |||¦  «        }|dk    rt          |¦  «        ‚	 |r|r| j         
                    ||¦  «         dS dS dS  ||||¦  «        |r|r| j         
                    ||¦  «         S S S nB# t           $ r}dt#          |¦  «        vr‚ d}Y d}~nd}~wt          $ r}d|z  }Y d}~nd}~ww xY w|r|r| j         
                    ||¦  «         n&# |r|r| j         
                    ||¦  «         w w w xY wt	          j        ¦   «         |k    rt%          d||||fz  ¦  «        ‚t	          j        d¦  «         �ŒÄ)uw  Resolve, check, act, and if something doesn't match, START OVER.

        â›” `needs_point=False` IS FOR AN ACTION THAT DOES NOT TOUCH THE SCREEN.
        Setting a file input's files goes through the engine, not the pointer,
        and the input it is aimed at is usually HIDDEN - a styled button in
        front of an `<input type=file>` with `display:none`. Asking that input
        for a quad answered "it isn't visible" on every turn until the
        timeout, so an upload to the commonest upload widget there is could
        not happen through either door, `set_input_files` or a file chooser's
        `set_files`. Such an action gets the element and no point: no scroll,
        no hit test, nothing a hidden element cannot satisfy.

        â›” AND IT IS A PROPERTY OF THE ACTION, NOT OF FILE INPUTS: every action
        whose `states` are empty declared that it needs no visibility, and the
        quad put the requirement back. `focus`, `blur` and `dispatch_event` on
        a `display:none` element timed out the same way, 4 s out of 4, where
        Playwright performs all three; they pass `needs_point=False` too.

        â›” `position` travels HERE and not through each action, because the
        point is recomputed on every turn of this loop: an offset applied by
        the caller once would be stale the moment the page moved, which is
        precisely the case this loop exists to absorb.

        â›” `element_id` IS THE ElementHandle CASE, and it changes exactly two
        things. The node is not looked up again - a handle names one node, and
        re-querying the selector would be a different element with the same
        description, which is not what `handle.click()` means - and the node is
        NOT disposed at the end, because it belongs to the caller and disposing
        it would destroy the handle they still hold.

        Everything else is deliberately shared: states, the point, the scroll,
        the hit-target check, the retry on detachment. A second loop for handles
        would be a second definition of "actionable" and a second click path,
        and two click paths are two fingerprints.
        Nz#no main frame: the page isn't readyzhaven't tried yetr   Tr   F©ry   zthe selector finds nothingÚokz
missing %sÚmissingza statezFthe element was outside the viewport; scrolled it in and starting overz*the element has no quad (it isn't visible)ÚdoneÚnotconnectedz&the node detached while I was using itz*the event would have landed elsewhere (%s)z=%r not actionable in %.0fs after %d attempts. Last reason: %sçš™™™™™©?)r8   rK   ÚRuntimeErrorÚACTION_STATESÚtimeÚ	monotonicr9   Úquery_selectorÚelement_statesrL   Údisposeru   rR   Úscroll_into_viewÚ
hit_targetr   r   r$   r   Úsleep)rC   r|   Úrunrv   rZ   rS   rB   rw   rx   ry   rz   r{   ÚfÚdeadlineÚreasonÚturnsrT   ÚoursÚresultÚ
element_okrQ   ÚverdictÚes                          r   Ú_retryzActions._retryî   s–  € ðP Ð1˜œÔ1ˆØˆ9ÝÐDÑEÔEÐEØ"( .•�°fˆÝ”>Ñ#Ô# gÑ-ˆØ$ˆØˆðB	Ø�Q‰JˆEØˆGØˆDðx1ØÐ)à(�G�Gð #œh×5Ò5°a¸È&Ð5ÑQÔQ�GØ�DØð &Ø9�F�FØð 	& Eð 	&Ø!œX×4Ò4°Q¸ÀÑHÔH�FØ!Ÿ:š: dÑ+Ô+ð *Ø!-°·
²
¸9Ø<Eñ1Gô 1Gñ "G˜à%*˜
˜
à%)˜
˜
à!%�Jàð 1˜zð 1°+ð 1Øð $Ø#ðp ð 1˜tð 1Ø”H×$Ò$ Q¨Ñ0Ô0Ð0Ð0Ð0ð1ð 1ð 1ð 1ðo ˜3˜q '¨4Ñ0Ô0ðn ð 1˜tð 1Ø”H×$Ò$ Q¨Ñ0Ô0Ð0Ð0ð1ð 1ðm ñ 46˜zñ 46ð !×.Ò.¨q°'¸8ÑDÔD�EØÐ(°×1BÒ1BÀ5Ñ1IÔ1IÐ(Øœ8×4Ò4°Q¸Ñ@Ô@ð %ð'I˜Fà$ðN ð 1˜tð 1Ø”H×$Ò$ Q¨Ñ0Ô0Ð0ùðO !%× 2Ò 2°1°g¸xÑ HÔ H˜Ø�}Ø!M˜˜Øð !6ð6  %ð >Ø&*§o¢o°a¸À%Ñ&HÔ&H˜GØ&¨&Ò0Ð0Ý&4°WÑ&=Ô&=Ð =Ø#ðH ð 1˜tð 1Ø”H×$Ò$ Q¨Ñ0Ô0Ð0Ð0Ð0ð1ð 1ð 1ð 1ðE  #˜s 1 g¨uÑ5Ô5ðD ð 1˜tð 1Ø”H×$Ò$ Q¨Ñ0Ô0Ð0Ð0ð1ð 1øøõC #ð Bð Bð Bð "­¨Q©¬Ð/Ð/ØØA������øøøøÝ!ð Jð Jð Jð( FÈÑI������øøøøð)Jøøøð4 ð 1˜tð 1Ø”H×$Ò$ Q¨Ñ0Ô0Ð0øøð ð 1˜tð 1Ø”H×$Ò$ Q¨Ñ0Ô0Ð0Ð0ð1ð 1øøøõ Œ~ÑÔ (Ò*Ð*Ý*ð!Ø$,¨g°u¸fÐ#EñFñGô Gð Gõ ŒJ�tÑÔÐñEB	s]   ÁBH? Ã=H? Ä+AH? ÆAH? ÈH? È>J! È?
I>É	I"ÉJ! É"I>É/I9É4J! É9I>É>J! Ê!#Kc                ób   — | j                              |||                      ||¦  «        ¦  «        S )uþ  Does a MAIN-FRAME point land on `element`? `"done"`, or what is there.

        â›” ONE QUESTION, ONE ANSWER, THREE ASKERS: the trial, the check before
        a commit, and the humanised cursor choosing an off-centre landing
        (`ElementHandle.checkHitTarget`). The cursor used to answer it on its
        own with `document.elementFromPoint` at main-frame coordinates, which
        is wrong twice: inside a nested frame the number means another place,
        and inside a shadow root the hit is the host, never the control. Both
        made every landing fail its check and fall back to the exact geometric
        centre - one number for every click. Asking here means the cursor
        accepts exactly the points the action itself would accept.
        )r9   Úcheck_hit_targetÚ
_hit_point)rC   r�   rT   rQ   s       r   r�   zActions.hit_target¢  s,   € ð Œx×(Ò(¨¨G°T·_²_ÀQÈÑ5NÔ5NÑOÔOÐOr   c                ó
  — || j         j        k    r|S | j                             | j         j        ¦  «        }| j                             |¦  «        }|d         |d         z   |d         z
  |d         |d         z   |d         z
  fS )u€  The caller's point, expressed in `f`'s own coordinate space.

        â›” A POINT IS ALWAYS IN THE MAIN FRAME'S SPACE when it gets here:
        `Page.getContentQuads` answers there and `dispatchMouseEvent` wants it
        there. Handing that number to a hit test running INSIDE a nested frame
        asks the child about a coordinate that means something else, and it
        answers `<html>` - which is how a covered element used to be reported
        for something sitting right under the pointer.

        The shift is the difference between the two content origins, read from
        the engine rather than recomputed here.
        r   r`   r   ra   )r8   rK   r9   Úcontent_origin)rC   r�   rQ   ÚmainÚheres        r   rœ   zActions._hit_point±  s„   € ð �”Ô)Ò)Ð)ØˆLØŒx×&Ò& t¤~Ô'@ÑAÔAˆØŒx×&Ò& qÑ)Ô)ˆØ�a”˜4 œ9Ñ$ t¨C¤yÑ0Ø�a”˜4 œ9Ñ$ t¨C¤yÑ0ð2ð 	2r   )Ú	mousedownÚmouseup)rz   Úlandsr£   Útuplec               óŒ  —  |¦   «          |s,|                       |||¦  «        }|dk    rt          |¦  «        ‚ |¦   «         }	|s|r}| j                             d||t	          |¦  «        | j        dœ| j        d¬¦  «        }
d„ |
d         D ¦   «         }|r/t          dd	                     d
„ |D ¦   «         ¦  «        z   ¦  «        ‚|	S )u5  Approach, check that the point still belongs to the element, and
        only then do the thing that cannot be taken back.

        â›” `force` SKIPS THE CHECK, AND THAT IS NOT AN EXEMPTION - IT IS WHAT
        THE OPTION MEANS. "Receives events" is one of the actionability checks
        `force` is documented to bypass, and an overlay intercepting the
        pointer is the ordinary reason somebody passes it. Honouring `force`
        on the state checks alone would leave it half wired, which is the
        defect this was: an option accepted on every public signature that
        changed nothing a caller could observe.

        â›” IT USED TO BE AN INTERCEPTOR, and that history is why the shape here
        matters. An interceptor watched each event WHILE it arrived and BLOCKED
        the ones whose point had stopped belonging to the element. It needed
        capture listeners for the duration of every action, and the block
        itself was a tell: a real `mousedown` that vanishes under
        `preventDefault` is not something any input stack produces.

        It was replaced by two pure DOM reads, one before the action and one
        after, and the one AFTER is what this corrects.

        â›” A CHECK AFTER THE EVENT CANNOT ANSWER THE QUESTION IT IS ASKED, AND
        IT DROVE A RETRY. Once the event has gone out, these two are the SAME
        observation:

            the point stopped belonging to the element BEFORE the event, so the
            click landed on something else;

            the point stopped belonging to the element BECAUSE of the event, so
            the click landed exactly where it was aimed and the control did
            what it exists to do.

        The second is not an edge case, it is most controls. Measured on the
        published 0.22.0, one `browser_click` per call: a button that hides
        itself on click received THIRTY-NINE clicks and the call then reported
        failure; a panel toggle was opened and closed by a single call, which
        reported success; a button that only moves, and one that does nothing,
        were correct thirty times out of thirty. The discriminant is not
        movement - it is the target ceasing to be hittable BY ITS OWN EFFECT.

        A check whose negative result carries no information cannot gate
        anything, so it is gone rather than narrowed. What it leaves behind is
        the invariant `_retry` depends on: starting over is sound only while
        nothing has happened, and every raise here is now before `commit`.

        â›” AND THE READ MOVED AFTER `approach`, WHICH IS WHERE THE RACE IS. It
        used to run before the pointer moved, so a page that rearranges itself
        on hover - a menu opening under the cursor is the ordinary case - was
        judged in the layout that existed before the thing that changed it.
        What is left is one round trip between this read and the press. Closing
        that one belongs to the engine, the only place that can verify and
        dispatch without a gap; it is not closed by reading the DOM again
        afterwards, which is what this function just stopped doing.

        Measured by `tests/gates/injected_page_surface.js`: the bundle touches
        the page's window zero times, in every phase.

        â›” AND WHAT CLOSES THE GAP IS NOT A THIRD READ OF THE GEOMETRY. It is
        the engine telling us where each event LANDED, recorded at dispatch by
        a privileged listener the page cannot see (`Page.pointerLanded`). That
        answer distinguishes what a read after the fact cannot: an event that
        hit the element and then saw it move away by its own effect landed ON
        the element, and says so. `lands` names the events the commit emits -
        the press and the release for a click, the one move for a hover - and
        every one of them must have landed on the element or inside it, which
        is also the condition under which the DOM composes a `click`. A miss
        raises `ActionMissed`, which `_retry` does not catch: something has
        happened, and the invariant this loop rests on is that it starts over
        only while nothing has.

        `force` skips this as it skips the check before: the caller has said
        the event is to go wherever the pointer is, and an overlay receiving it
        is then not a miss but the request. [B217]
        r‚   zPage.pointerLanded)rV   rW   ÚtypesÚafterEventIdrX   rY   c                ó"   — g | ]}|d          °
|‘ŒS )Úlandedr   ©re   Úls     r   ú
<listcomp>z*Actions._act_on_target.<locals>.<listcomp>#  s!   € ÐGÐGÐG˜A¸1¸X¼;ÐG�aÐGÐGÐGr   Úlandingsz3the action went out but did not reach the element: z; c              3  ó<   K  — | ]}|d          ›d|d         ›�V — ŒdS )Útypez landed on ÚonNr   rª   s     r   rg   z)Actions._act_on_target.<locals>.<genexpr>'  sI   è è € ð  1ð  1Ø$%ð 67°v´Y°Y°YÀÀ$ÄÀÐ Hð  1ð  1ð  1ð  1ð  1ð  1r   )	r�   r   r7   rn   r   Ú_last_event_idr.   r   Újoin)rC   r�   rT   rQ   ÚapproachÚcommitrz   r£   r—   r•   ÚanswerÚmisseds               r   Ú_act_on_targetzActions._act_on_targetÅ  s  € ðZ 	ˆ‰
Œ
ˆ
Øð 	.Ø—o’o a¨°%Ñ8Ô8ˆGØ˜&Ò Ð Ý$ WÑ-Ô-Ð-Ø�‘”ˆØð 	2˜ð 	2ð ”V—[’[Ð!5Ø-.¸GÝ+/°©;¬;Ø26Ô2Eð"Gð "Gð *.¬¸rð	 !ñ Cô CˆFð
 HÐG ¨
Ô!3ÐGÑGÔGˆFØð 2Ý"ØIØ—i’ið  1ð  1Ø)/ð 1ñ  1ô  1ñ 1ô 1ñ1ñ2ô 2ð 2ð ˆr   r   )ÚstaterZ   rS   ry   r¸   c               óf  — |p| j         j        }|€t          d¦  «        ‚t          j        ¦   «         |z   }d}	 | j                             |||¬¦  «        }	|dk    r"|	sdS | j                             ||	¦  «         d}ns|	ro|dk    r|	S 	 | j                             ||	|¦  «        r|	S d	|z  }n&# t          $ r}
t          |
¦  «        }Y d}
~
nd}
~
ww xY w| j                             ||	¦  «         nd
}t          j        ¦   «         |k    rt          d||||fz  ¦  «        ‚t          j        d¦  «         Œú)u  Waits for a selector to reach a state, and returns its handle.

        â›” THE HANDLE IS NOT DISPOSED HERE, and that is deliberate: the caller
        is about to use it. `_retry` disposes what it resolves on every turn
        precisely because it re-resolves, so this cannot go through it - it
        would hand back an objectId it has just released, and a released handle
        does not raise, it answers wrong.

        â›” AND `state="attached"` AND `"detached"` ARE NOT ELEMENT STATES. The
        injected script knows visible / hidden / enabled / disabled / editable
        / checked; presence in the DOM is answered by the selector resolving at
        all, so those two are handled here rather than asked of a function that
        would reject them.
        Nz$no main frame: the page is not readyznot tried yetTr   Údetachedzthe element is still attachedÚattachedzthe element is not %szthe selector matches nothingz.%r did not become %s in %.0fs. Last reason: %sr„   )r8   rK   r…   r‡   rˆ   r9   r‰   r‹   Úelement_stater   r$   r   rŽ   )rC   r|   r¸   rZ   rS   ry   Úframer‘   r’   rT   Úfailures              r   Úwait_for_selectorzActions.wait_for_selector,  s„  € ð" Ð5˜DœNÔ5ˆØˆ=ÝÐEÑFÔFÐFÝ”>Ñ#Ô# gÑ-ˆØ ˆð	Ø”h×-Ò-¨e°XÀfÐ-ÑMÔMˆGØ˜
Ò"Ð"Øð  Ø˜4Ø”× Ò  ¨Ñ0Ô0Ð0Ø8��Øð 8Ø˜JÒ&Ð&Ø"�Nð*Ø”x×-Ò-¨e°W¸eÑDÔDð 'Ø&˜Ø4°uÑ<�F�FøÝ&ð *ð *ð *Ý  ™\œ\�F�F�F�F�F�Føøøøð*øøøà”× Ò  ¨Ñ0Ô0Ð0Ð0à7�ÝŒ~ÑÔ (Ò*Ð*Ý*ØDØ ¨°Ð8ñ9ñ:ô :ð :õ ŒJ�tÑÔÐð/	s   Â	B- Â'B- Â-
CÂ7CÃC©rZ   rS   rB   rw   c               ó:   ‡ ‡— ˆˆ fd„} ‰ j         ||f||||dœ‰¤ŽS )Nc                óˆ   •‡— ‰                      | |‰d„ ˆˆfd„t          ‰                     d¦  «        ¦  «        d¬¦  «        S )Nc                 ó   — d S ©Nr   r   r   r   ú<lambda>z,Actions.hover.<locals>.run.<locals>.<lambda>c  s   €  € r   c                 ó4   •— ‰                      d‰ ¦  «        p‰ S ©NÚ	mousemove©Ú_mouse_event©rQ   rC   s   €€r   rÅ   z,Actions.hover.<locals>.run.<locals>.<lambda>d  s   ø€ ˜t×0Ò0°¸eÑDÔDÐMÈ€ r   rz   )rÈ   )r³   r´   rz   r£   ©r·   rO   rL   )r�   rT   rQ   ÚoptsrC   s     `€€r   r�   zActions.hover.<locals>.run^  sZ   øø€ ð ×&Ò&Ø�7˜EØ%˜ØMÐMÐMÐMÐMÝ˜4Ÿ8š8 GÑ,Ô,Ñ-Ô-ð %ð 'ñ &ô &ð &r   ©rZ   rw   rS   rB   ©r™   )rC   r|   rZ   rS   rB   rw   rÍ   r�   s   `     ` r   ÚhoverzActions.hover\  s_   øø€ ð
	&ð 
	&ð 
	&ð 
	&ð 
	&ð 
	&ð ˆtŒ{˜8 Sð I°'ÀjØ$,°xðIð IØCGðIð Ið 	Ir   r   )rZ   rS   ÚbuttonÚdelay_msÚclicksrB   Ú	modifiersrw   rÑ   ÚintrÒ   úOptional[float]rÓ   rÔ   c               óJ   ‡ ‡‡‡‡‡
— ˆˆˆˆˆ
ˆ fd„} ‰ j         ||f||||	dœ‰
¤ŽS )Nc                óš   •‡— ˆˆˆˆˆˆ	fd„}‰	                      | |‰ˆˆˆ	fd„|t          ‰                     d¦  «        ¦  «        ¬¦  «        S )Nc                 ó<   •— ‰                      ‰‰ ‰‰‰¬¦  «         ‰S )N©rÑ   rÓ   rÔ   rÒ   ©Ú_click_at_point)rÑ   rÓ   rÒ   rÔ   rQ   rC   s   €€€€€€r   Úactz'Actions.click.<locals>.run.<locals>.actq  s3   ø€ Ø×$Ò$ U°6À&Ø/8À8ð %ñ Mô Mð Mà�r   c                 ó4   •— ‰                      d‰‰ ¬¦  «        S )NrÈ   )rÔ   rÉ   )rÔ   rQ   rC   s   €€€r   rÅ   z,Actions.click.<locals>.run.<locals>.<lambda>  s%   ø€  ×!2Ò!2°;ÀØ=Fð "3ñ "Hô "H€ r   rz   ©r³   r´   rz   rÌ   )
r�   rT   rQ   rÝ   rÑ   rÓ   rÒ   rÔ   rÍ   rC   s
     ` €€€€€€r   r�   zActions.click.<locals>.runp  sš   øø€ ðð ð ð ð ð ð ð ð ð ð ×&Ò&Ø�7˜EðHð Hð Hð Hð Hð HàÝ˜4Ÿ8š8 GÑ,Ô,Ñ-Ô-ð 'ñ /ô /ð /r   rÀ   rÏ   )rC   r|   rZ   rS   rÑ   rÒ   rÓ   rB   rÔ   rw   rÍ   r�   s   `   ``` ` ` r   ÚclickzActions.clickl  sw   øøøøøø€ ð	/ð 	/ð 	/ð 	/ð 	/ð 	/ð 	/ð 	/ð 	/ð 	/ð& ˆtŒ{˜8 Sð M°'ÀHØ$,¸ðMð MØGKðMð Mð 	Mr   )rZ   rS   rÒ   rÑ   rB   rÔ   c               ó.   —  | j         |f||d||||dœ|¤ŽS )uÙ  â›” These are NOT two `click`s in a row: the second one must carry
        `clickCount: 2`, and it's that field - not the interval between the
        two - that gives birth to the `dblclick` event. Two clicks with
        `clickCount: 1` produce two `click` events and no `dblclick`, which
        is a silent failure: the action succeeds and the site's handler
        never fires.

        â›” AND IT FORWARDS `frame_id`, which it used to accept and drop. A
        double click on an element inside an iframe resolved the selector in
        the MAIN frame instead, so it either found nothing or found a
        same-named element in the wrong document. The signature said the
        argument was honoured; nothing else did.r   )rZ   rÑ   rÓ   rS   rB   rÔ   rÒ   )rà   )	rC   r|   rZ   rS   rÒ   rÑ   rB   rÔ   rÍ   s	            r   ÚdblclickzActions.dblclick†  sD   € ð ˆtŒz˜(ð J¨G¸FØ!"¨XÀØ$-¸ðJð JàDHðJð Jð 	Jr   c               ó*   —  | j         |df||||dœ|¤ŽS )NTrÎ   ©Ú_set_checked©rC   r|   rZ   rS   rB   rw   rÍ   s          r   ÚcheckzActions.check™  s>   € à ˆtÔ  ¨4ð O¸ÈZØ*2¸XðOð OØIMðOð Oð 	Or   c               ó*   —  | j         |df||||dœ|¤ŽS )NFrÎ   rä   ræ   s          r   ÚuncheckzActions.uncheckž  s>   € à ˆtÔ  ¨5ð O¸'ÈjØ*2¸XðOð OØIMðOð Oð 	Or   )rS   rB   rw   Úwantedc               ó>   ‡ ‡‡— ˆˆ ˆfd„} ‰ j         ||f||||dœ‰¤ŽS )uÄ  `check` / `uncheck`.

        â›” It CHECKS FIRST, and rechecks after. Clicking without looking
        flips a box that was already right - that's the obvious defect -
        but the second check is the one that matters: a `<label>` that
        intercepts the click, or a handler that puts the value back, make
        the action succeed while leaving the wrong state. Without the
        recheck the failure surfaces much later, elsewhere.
        c                ó<  •‡— ‰rdnd}‰j                              | ||¦  «        rdS ‰                     | |‰ˆˆfd„ˆˆfd„t          ‰                     d¦  «        ¦  «        ¬¦  «         ‰j                              | ||¦  «        st          d‰rdndz  ¦  «        ‚|S )	NÚcheckedÚ	uncheckedzalready therec                 ó0   •— ‰                      d‰ ¦  «        S rÇ   rÉ   rË   s   €€r   rÅ   z3Actions._set_checked.<locals>.run.<locals>.<lambda>»  s   ø€  ×!2Ò!2°;ÀÑ!FÔ!F€ r   c                 ó.   •— ‰                      ‰ ¦  «        S rÄ   rÛ   rË   s   €€r   rÅ   z3Actions._set_checked.<locals>.run.<locals>.<lambda>¼  s   ø€ ˜t×3Ò3°EÑ:Ô:€ r   rz   rß   zRclicked but the box stayed %s: someone intercepted the click or put the value back)r9   r¼   r·   rO   rL   r   )r�   rT   rQ   r¸   rÍ   rC   rê   s     ` €€€r   r�   z!Actions._set_checked.<locals>.run¯  sÛ   øø€ Ø!'Ð8�I�I¨[ˆEØŒx×%Ò% a¨°%Ñ8Ô8ð 'Ø&�ð ×ÒØ�7˜EØFÐFÐFÐFÐFØ:Ð:Ð:Ð:Ð:Ý˜4Ÿ8š8 GÑ,Ô,Ñ-Ô-ð	  ñ /ô /ð /ð
 ”8×)Ò)¨!¨W°eÑ<Ô<ð >Ý%ð6à&,Ð;�{�{°)ñ=ñ>ô >ð >ð ˆLr   rÎ   rÏ   )	rC   r|   rê   rZ   rS   rB   rw   rÍ   r�   s	   ` `    ` r   rå   zActions._set_checked£  se   øøø€ ð	ð 	ð 	ð 	ð 	ð 	ð 	ð* ˆtŒ{˜8 Sð I°'ÀjØ$,°xðIð IØCGðIð Ið 	Ir   )rZ   rS   rw   c          	     ó8   ‡ — ˆ fd„} ‰ j         ||fg |||ddœ|¤ŽS )uÇ   â›” Does NOT require `visible`: `focus()` works on an off-screen
        element, and imposing the pointer states would time out an action
        that would have succeeded. Playwright does the same.c                ó@   •— ‰j                              | dd|i¦  «        S )Nú.(injected, el) => injected.focusNode(el, true)rW   ©r9   Úcall©r�   rT   rQ   rC   s      €r   r�   zActions.focus.<locals>.runÍ  s)   ø€ Ø”8—=’=ØÐCØ˜WÐ%ñ'ô 'ð 'r   F©rv   rZ   rS   rw   r{   rÏ   )rC   r|   rZ   rS   rw   rÍ   r�   s   `      r   ÚfocuszActions.focusÇ  s[   ø€ ð	'ð 	'ð 	'ð 	'ð 	'ð ˆtŒ{˜8 Sð M°¸WÈxØ&0¸eðMð MØGKðMð Mð 	Mr   ©rZ   rS   c               ó6   ‡ — ˆ fd„} ‰ j         ||fg ||ddœ|¤ŽS )Nc                ó@   •— ‰j                              | dd|i¦  «        S )Nza(injected, el) => { if (!el.isConnected) return 'error:notconnected'; el.blur(); return 'done'; }rW   rô   rö   s      €r   r�   zActions.blur.<locals>.runÖ  s,   ø€ Ø”8—=’=ØðDà˜WÐ%ñ	'ô 'ð 'r   F©rv   rZ   rS   r{   rÏ   ©rC   r|   rZ   rS   rÍ   r�   s   `     r   ÚblurzActions.blurÔ  sS   ø€ ð	'ð 	'ð 	'ð 	'ð 	'ð ˆtŒ{˜8 Sð 6°¸WÈxØ',ð6ð 6Ø04ð6ð 6ð 	6r   c               ó6   ‡ — ˆ fd„} ‰ j         ||fdg||dœ|¤ŽS )Nc                ó¼   •— ‰j                              | dd|i¦  «        }t          |t          ¦  «        r'|                     d¦  «        rt          d|z  ¦  «        ‚|S )Nz)(injected, el) => injected.selectText(el)rW   úerror:zselectText: %s)r9   rõ   r#   r$   Ú
startswithr   )r�   rT   rQ   rr   rC   s       €r   r�   z Actions.select_text.<locals>.runá  sc   ø€ Ø”—’˜aÐ!LØ)¨7Ð3ñ5ô 5ˆAå˜!�SÑ!Ô!ð < a§l¢l°8Ñ&<Ô&<ð <Ý%Ð&6¸Ñ&:Ñ;Ô;Ð;ØˆHr   r   )rv   rZ   rS   rÏ   rý   s   `     r   Úselect_textzActions.select_textß  sY   ø€ ð	ð 	ð 	ð 	ð 	ð ˆtŒ{˜8 Sð G°)°Ø#*°XðGð GØAEðGð Gð 	Gr   c               ó\   ‡ ‡— t          |¦  «        Šˆ ˆfd„} ‰ j        ||fg d¢|||dœ|¤ŽS )u«  `select_option`. Options are given by value, label or index.

        â›” The injected script only RESOLVES which options are meant; the
        engine selects them through the dropdown's own path
        (`Page.selectOptions`), so Firefox fires `input`/`change` itself, and
        fires nothing when the selection did not change. Selected from the
        page they came out with `isTrusted: false`, which is [B175].
        c                ó$  •— ‰j                              | dd|i‰¦  «        }t          |t          ¦  «        r'|                     d¦  «        rt          d|z  ¦  «        ‚‰j                             d| ||d         dœ‰j        d¬	¦  «         |d
         S )Nz2(injected, el, o) => injected.selectOptions(el, o)rW   r  zselectOptions: %szPage.selectOptionsÚindices)rV   rW   r  rX   rY   Úvalues)	r9   rõ   r#   r$   r  r   r7   rn   r.   )r�   rT   rQ   rr   rC   rê   s       €€r   r�   z"Actions.select_option.<locals>.run÷  s¬   ø€ Ø”—’ØÐGØ˜WÐ% vñ/ô /ˆAõ ˜!�SÑ!Ô!ð ? a§l¢l°8Ñ&<Ô&<ð ?Ý%Ð&9¸AÑ&=Ñ>Ô>Ð>ØŒF�KŠKÐ,Ø$%°7Ø$% i¤Lð2ð 2à $¤°bð ñ :ô :ð :ð �X”;Ðr   r   ©rv   rZ   rS   rw   )r)   r™   )	rC   r|   r&   rZ   rS   rw   rÍ   r�   rê   s	   `       @r   Úselect_optionzActions.select_optionê  sr   øø€ õ $ GÑ,Ô,ˆð
	ð 
	ð 
	ð 
	ð 
	ð 
	ð ˆtŒ{˜8 Sð :Ø"BÐ"BÐ"BØ#*°XØ&0ð:ð :ð 59ð:ð :ð 	:r   Ú
event_typec               ó>   ‡ ‡‡— ˆˆˆ fd„} ‰ j         ||fg ||ddœ|¤ŽS )uí  `dispatch_event`.

        â›” This is the ONLY spot in the file where an event comes out NOT
        trusted, and it should be stated rather than discovered: the
        injected script builds it, so `isTrusted` is false. This is
        exactly what Playwright's API promises - it exists precisely to
        fabricate an arbitrary event - but it isn't a way to simulate a
        user: for that there is `click` and `type_text`, which go through
        the browser's own commands.
        c                óH   •— ‰j                              | dd|i‰‰pi ¦  «        S )Nz8(injected, el, t, d) => injected.dispatchEvent(el, t, d)rW   rô   )r�   rT   rQ   Údetailr
  rC   s      €€€r   r�   z#Actions.dispatch_event.<locals>.run  s4   ø€ Ø”8—=’=ØÐMØ˜WÐ% z°6°<¸RñAô Að Ar   Frü   rÏ   )rC   r|   r
  r  rZ   rS   rÍ   r�   s   ` ``    r   Údispatch_eventzActions.dispatch_event  sf   øøø€ ð	Að 	Að 	Að 	Að 	Að 	Að 	Að ˆtŒ{˜8 Sð 6°¸WÈxØ',ð6ð 6Ø04ð6ð 6ð 	6r   )rZ   rS   rw   Údwell_msÚkeyr  c               óB   ‡ ‡‡— ˆˆˆ fd„} ‰ j         ||fg d¢|||dœ|¤ŽS )aú  `press`: focuses and presses, with the modifiers from the name.

        No typist's pause before the key, unlike `fill` and `type`: a press is
        one key, most often sent to a field that already holds the focus
        (Enter after typing), where there is no focus for a page to answer
        and the wait between the two calls is the caller's.

        `dwell_ms` is the caller's `delay`, how long the key stays down; None
        leaves it to the session's hand, as `keyboard.press` does.
        c                ó|   •— ‰j                              | dd|i¦  «         ‰j                             ‰‰¬¦  «         ‰S )Nró   rW   )r  )r9   rõ   rA   Úpress)r�   rT   rQ   r  r  rC   s      €€€r   r�   zActions.press.<locals>.run)  sH   ø€ ØŒH�MŠM˜!ÐMØ% wÐ/ñ1ô 1ð 1àŒM×Ò ¨hÐÑ7Ô7Ð7ØˆJr   r   r  rÏ   )	rC   r|   r  rZ   rS   rw   r  rÍ   r�   s	   ` `   `  r   r  zActions.press  si   øøø€ ð	ð 	ð 	ð 	ð 	ð 	ð 	ð
 ˆtŒ{˜8 Sð :Ø"BÐ"BÐ"BØ#*°XØ&0ð:ð :ð 59ð:ð :ð 	:r   r6   )rZ   rS   Údelayrw   Útextr  c               ór   ‡ ‡‡‡	— t          j        ¦   «         |z   Š	ˆ	ˆˆ ˆfd„} ‰ j        ||fg d¢|||dœ|¤ŽS )u{  `type`: one key per character, WITHOUT clearing first.

        â›” It isn't `fill`: that one replaces the content, this one
        appends to it. Swapping them is the easiest way to end up with
        `foobar` in a field that was meant to hold `bar`.

        The typist's pause between the focus and the first key is the same
        as `fill`'s, see `_reach_field`.
        c                ón   •— ‰                      | |‰¦  «         ‰j                             ‰‰¬¦  «         ‰S )N)rÒ   )Ú_reach_fieldrA   r¯   )r�   rT   rQ   r‘   r  rC   r  s      €€€€r   r�   zActions.type_text.<locals>.runA  s;   ø€ Ø×Ò˜a ¨(Ñ3Ô3Ð3ØŒM×Ò˜t¨eÐÑ4Ô4Ð4ØˆKr   r   r  ©r‡   rˆ   r™   )
rC   r|   r  rZ   rS   r  rw   rÍ   r�   r‘   s
   ` `  `   @r   Ú	type_textzActions.type_text3  sƒ   øøøø€ õ ”>Ñ#Ô# gÑ-ˆð	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð ˆtŒ{˜8 Sð :Ø"BÐ"BÐ"BØ#*°XØ&0ð:ð :ð 59ð:ð :ð 	:r   c          	     ót   ‡ ‡‡‡	— t          j        ¦   «         |z   Šg Š	ˆˆˆ	ˆ fd„} ‰ j        ||fg |||ddœ|¤ŽS )u²  `set_input_files`. The paths are ABSOLUTE and the browser
        resolves them.

        â›” Goes through `Page.setFileInputFiles` and not the injected
        script: a page can't construct a `FileList`, and trying would
        leave the input empty with no error.

        â›” `element_id` WAS MISSING, AND THAT IS WHY A FILE CHOOSER COULD NOT
        UPLOAD ANYTHING. `FileChooser.set_files()` does not go through a
        selector - it holds the input element already - so it asks the
        ElementHandle for `setInputFiles`, and without this parameter there was
        nothing for that dispatcher to call. Every other action here takes the
        handle; this one was the exception nobody had needed yet.

        â›” A PERSON TAKES A MOMENT TO PICK A FILE. Between the chooser opening
        and the files arriving, a hand finds the file and confirms it; files
        that land a few milliseconds after the click are a timing no person
        produces. So the files go in after two hesitations of the session's
        typing persona (act ``"file"``, one nonce per upload of the session),
        bounded by the action's deadline. It lives here, inside the standard
        `set_input_files` and so inside `FileChooser.set_files`, because the
        product adds nothing to Playwright's contract (decision D82): a caller
        that used to draw this pause through a public helper no longer needs
        one. No persona, no pause.
        c                ó²  •— ‰j         ��‰sŽddlm}  |‰j         d‰j                             d¦  «        d¬¦  «        dz  }t          j        t          dt          |‰t          j	        ¦   «         z
  ¦  «        ¦  «        ¦  «         ‰ 
                    |¦  «         ‰j                             d| |d„ ‰D ¦   «         d	œ‰j        d
¬¦  «         t          ‰¦  «        S )Nr   ©Úplan_hesitationÚfile)Útimesç     @�@r6   zPage.setFileInputFilesc                ó,   — g | ]}t          |¦  «        ‘ŒS r   )r$   rd   s     r   r¬   z8Actions.set_input_files.<locals>.run.<locals>.<listcomp>t  s   € Ð"9Ð"9Ð"9¨a¥3 q¡6¤6Ð"9Ð"9Ð"9r   )rV   rW   Úfilesé   rY   )r;   r=   r  r4   Únextr‡   rŽ   Úmaxro   rˆ   r"   r7   rn   r.   r   )	r�   rT   rQ   r  Úpauser‘   r#  ÚpausedrC   s	        €€€€r   r�   z$Actions.set_input_files.<locals>.runi  sù   ø€ ð Ô"Ð.°vÐ.Ø8Ð8Ð8Ð8Ð8Ð8Ø'˜¨Ô(;¸VØ(,¬	¯ª°vÑ(>Ô(>ÀaðIñ Iô IØKQñR�å”
�3˜s¥C¨¨x½$¼.Ñ:JÔ:JÑ/JÑ$KÔ$KÑLÔLÑMÔMÐMØ—’˜eÑ$Ô$Ð$ØŒF�KŠKÐ0Ø$%°7Ø"9Ð"9°5Ð"9Ñ"9Ô"9ð;ð ;à $¤°bð ñ :ô :ð :õ ˜‘;”;Ðr   Fr÷   r  )
rC   r|   r#  rZ   rS   rw   rÍ   r�   r‘   r(  s
   ` `     @@r   Úset_input_fileszActions.set_input_filesJ  s�   øøøø€ õ8 ”>Ñ#Ô# gÑ-ˆØˆð	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð ˆtŒ{˜8 Sð 6°¸WØ$,¸Ø',ð6ð 6à04ð6ð 6ð 	6r   ©rZ   rS   rB   c               ó4   ‡ — ˆ fd„} ‰ j         ||f|||dœ|¤ŽS )u,  `tap`. â›” Requires the context to have touch TURNED ON: without
        it, the event fires and the page has no `ontouchstart`, so it
        doesn't listen for it - it succeeds and does nothing. Touch is
        turned on with `Browser.setTouchOverride`, which is a
        context-level operation.c                óœ   •— ‰j                              d|d         |d         ‰j                             ¦   «         dœ‰j        d¬¦  «         |S )NzPage.dispatchTapEventr   r   )r`   ra   rÔ   rX   rY   )r7   rn   rA   Úmodifier_maskr.   rö   s      €r   r�   zActions.tap.<locals>.run‚  s[   ø€ ØŒF�KŠKÐ/Ø# Aœh¨U°1¬XØ&*¤m×&AÒ&AÑ&CÔ&CðEð Eà $¤°bð ñ :ô :ð :ð ˆLr   r*  rÏ   )rC   r|   rZ   rS   rB   rÍ   r�   s   `      r   ÚtapzActions.tap{  sW   ø€ ð	ð 	ð 	ð 	ð 	ð ˆtŒ{˜8 Sð I°'Ø$,°xðIð IØCGðIð Ið 	Ir   ©Úbuttonsr0  c          	     ó†  ‡ ‡‡‡— ‰ j         €‰                      d|‰¬¦  «         dS ‰ j        \  }}‰ j                              |||d         |d         ‰ j                             d¦  «        ¬¦  «        dd…         }‰                      ¦   «         \  ŠŠˆˆfd„|dd	…         D ¦   «         }|                     t          j	        |d	         j
        |d         |d         ¦  «        ¦  «         ‰ j        rt          j        |‰ j        ¦  «        }|s‰                      d|‰¬¦  «         dS t          j        |ˆˆ fd
„||f¬¦  «        S )u¦  Move the pointer to *to_point* along a path a hand could have drawn.

        â›” WHY THIS EXISTS ON THIS SIDE AT ALL. Every other pointer action is
        approached by the client's cursor wrapper, which walks the cursor onto
        the element BEFORE calling the action. A drag cannot be served that way:
        the travel happens with the button already down, and its far end is only
        known after the press. So the movement is generated here - from the same
        generator (`_motion.CursorMotion`) and delivered under the same
        discipline (`_pacing`) as every movement the client makes. Neither is
        reimplemented here; a second copy of either is the defect this replaced.

        Returns the number of events actually delivered. Falls back to a single
        event when there is no generator (`humanize=False`, or a broken
        install), which is what "no humanising" has always meant here.
        NrÈ   r/  r   r   Údrag)Úindexc                ó|   •— g | ]8}t          j        |j        gt          j        |j        |j        ‰‰¦  «        ¢R Ž ‘Œ9S r   )r   ÚEvÚt_msÚclamp_to_viewportr`   ra   )re   ÚwprI   rH   s     €€r   r¬   z"Actions._glide.<locals>.<listcomp>¯  sR   ø€ ð $ð $ð $Øõ Œz˜"œ'ÐP¥GÔ$=¸b¼dÀBÄDÈ!ÈQÑ$OÔ$OÐPÐPÐPð $ð $ð $r   éÿÿÿÿc                ó8   •— ‰                      d| |f‰¬¦  «        S )NrÈ   r/  rÉ   )r`   ra   r0  rC   s     €€r   rÅ   z Actions._glide.<locals>.<lambda>¸  s)   ø€ ˜d×/Ò/°¸aÀ¸VØ8?ð 0ñ Aô A€ r   )Úorigin)r<   rÊ   rB   Úpathr4   r%  rN   r"   r   r5  r6  r-   Úfit_timelineÚdrive)	rC   Úto_pointr0  Úx0Úy0r<  ÚevsrI   rH   s	   ` `    @@r   Ú_glidezActions._glide‹  s‰  øøøø€ ð  Œ;ÐØ×Ò˜k¨8¸WÐÑEÔEÐEØ�1Ø”‰ˆˆBð Œ{×Ò  B¨°¬°X¸a´[Ø&*¤i§n¢n°VÑ&<Ô&<ð  ñ >ô >Ø>?¸b¸bôBˆð �~Š~ÑÔ‰ˆˆ1ð$ð $ð $ð $ð $Ø˜c˜r˜cœð$ñ $ô $ˆà�
Š
•7”:˜d 2œhœm¨X°a¬[¸(À1¼+ÑFÔFÑGÔGÐGØÔð 	BÝÔ& s¨DÔ,@ÑAÔAˆCØð 	Ø×Ò˜k¨8¸WÐÑEÔEÐEØ�1ÝŒ}Øð Að Að Að Að Aà˜�8ðñ ô ð 	r   ÚsourceÚtargetc               ó–  ‡ — |                      d¦  «        r( ‰ j        |d„ f||dœ|¤Ž  ‰ j        |d„ f||dœ|¤Ž dS  ‰ j        |d„ f||dœ|¤Ž}‰                      |¦  «         ‰                      d|t          d         d	¬
¦  «         ˆ fd„}	  ‰ j        ||f||dœ|¤ŽS # t
          $ r ‰                      d|dd	¬
¦  «         ‚ w xY w)u?  `drag_and_drop`, in four beats.

        â›” THE FIRST `mousemove` AFTER THE `mousedown` IS NOT SKIPPED.
        Gecko gives birth to a drag from a movement with the button held
        down: press and release on the target, and you've made two
        clicks. And the two ends are resolved SEPARATELY, each with its
        own retry loop, because taking the second point before pressing
        the first would measure it on a page that is about to change.

        â›” AND THE TRAVEL IS A PATH, NOT A JUMP - which is a correctness fix as
        well as a stealth one. Measured 2026-09-16 on a page whose source was
        `draggable`: this used to emit five events in all, of which the two
        carrying the whole 480-pixel journey were IDENTICAL and 7 ms apart - a
        pair no device can produce, since a move event is born from moving. The
        second was there because one jump alone did not reliably start the drag.
        With a real path it is not needed: the drag is born at the first point
        that clears Gecko's threshold, the way it is for a hand.
        rx   c                ó   — |S rÄ   r   ©r�   Úelrf   s      r   rÅ   z'Actions.drag_and_drop.<locals>.<lambda>Ù  ó   € °€ r   rù   c                ó   — |S rÄ   r   rH  s      r   rÅ   z'Actions.drag_and_drop.<locals>.<lambda>Û  rJ  r   Nc                ó   — |S rÄ   r   rH  s      r   rÅ   z'Actions.drag_and_drop.<locals>.<lambda>Þ  s   € °Q€ r   r¡   r   r   ©r0  Úclick_countc                ó~   •— ‰                      |t          d         ¬¦  «         ‰                     d|dd¬¦  «         |S )Nr   r/  r¢   r   rM  )rC  r	   rÊ   rö   s      €r   r�   z"Actions.drag_and_drop.<locals>.runç  s?   ø€ Ø�KŠK˜¥{°1¤~ˆKÑ6Ô6Ð6Ø×Ò˜i¨¸ÀqÐÑIÔIÐIØˆLr   r¢   )rL   r™   rC  rÊ   r	   ÚBaseException)rC   rD  rE  rZ   rS   rÍ   Ústartr�   s   `       r   Údrag_and_dropzActions.drag_and_drop¼  s…  ø€ ð, �8Š8�GÑÔð 	ð ˆDŒK˜Ð 2Ð 2ð 3¸GØ!)ð3ð 3Ø-1ð3ð 3ð 3àˆDŒK˜Ð 2Ð 2ð 3¸GØ!)ð3ð 3Ø-1ð3ð 3ð 3à�4Ø�”˜FÐ$6Ð$6ð 7ÀØ%-ð7ð 7Ø15ð7ð 7ˆð
 	�Š�EÑÔÐØ×Ò˜+ uµkÀ!´nØ&'ð 	ñ 	)ô 	)ð 	)ð	ð 	ð 	ð 	ð 	ð	Ø�4”;˜v sð '°GÀhð 'ð 'Ø!%ð'ð 'ð 'øåð 	ð 	ð 	ð ×Ò˜i¨¸ÀqÐÑIÔIÐIØð		øøøs   ÂB# Â#%C)Ústepsr`   ra   rS  ÚNonec               óÂ   — | j         \  }}t          dt          d|¦  «        dz   ¦  «        D ]2}|                      d|||z
  |z  |z  z   |||z
  |z  |z  z   f¦  «         Œ3dS )zM`mouse.move`. With `steps > 1` it interpolates, like Playwright
        does.r   rÈ   N)rB   Úranger&  rÊ   )rC   r`   ra   rS  r@  rA  Úis          r   ÚmovezActions.moveõ  s�   € ð ”‰ˆˆBÝ�q�#˜a ™-œ-¨!Ñ+Ñ,Ô,ð 	;ð 	;ˆAØ×Ò˜kØ! Q¨¡V¨q¡L°5Ñ$8Ñ8Ø! Q¨¡V¨q¡L°5Ñ$8Ñ8ð:ñ;ô ;ð ;ð ;ð	;ð 	;r   )rÑ   rÓ   c               óZ   — |                       d| j        |t          |         |¬¦  «         d S )Nr¡   ©rÑ   r0  rN  )rÊ   rB   r	   ©rC   rÑ   rÓ   s      r   Ú
mouse_downzActions.mouse_downþ  s@   € Ø×Ò˜+ t¤}¸VÝ"-¨fÔ"5À6ð 	ñ 	Kô 	Kð 	Kð 	Kð 	Kr   c               óD   — |                       d| j        |d|¬¦  «         d S )Nr¢   r   rZ  )rÊ   rB   r[  s      r   Úmouse_upzActions.mouse_up  s6   € Ø×Ò˜) T¤]¸6Ø"#°ð 	ñ 	9ô 	9ð 	9ð 	9ð 	9r   ©rÑ   rÓ   rÒ   c               óh   — |                       ||¦  «         |                      ||f|||¬¦  «         d S )Nr_  )rX  rÜ   )rC   r`   ra   rÑ   rÓ   rÒ   s         r   Úclick_atzActions.click_at  sG   € à�	Š	�!�Q‰ŒˆØ×Ò˜a ˜V¨F¸6Ø&.ð 	ñ 	0ô 	0ð 	0ð 	0ð 	0r   ÚdxÚdyc           
     ó´   — | j                              d| j        d         | j        d         ||d| j                             ¦   «         dœ| j        d¬¦  «         dS )z8`mouse.wheel`, from where the pointer IS - not from 0,0.zPage.dispatchWheelEventr   r   )r`   ra   ÚdeltaXÚdeltaYÚdeltaZrÔ   rX   rY   N)r7   rn   rB   rA   r-  r.   )rC   rb  rc  s      r   ÚwheelzActions.wheel  sl   € àŒ�ŠÐ-Øœ-¨Ô*°´¸qÔ1AØ!¨R¸1Ø"&¤-×"=Ò"=Ñ"?Ô"?ðAð Að !œL°"ð	 	ñ 	6ô 	6ð 	6ð 	6ð 	6r   rÚ   c          	     óp  — |                       ||¦  «        }t          d|dz   ¦  «        D ]‹}||dz
           \  }}	|                      d||t          |         ||¬¦  «         |dk    rt	          j        |dz  ¦  «         |                      d||d||¬¦  «         |	dk    rt	          j        |	dz  ¦  «         ŒŒdS )	u”  â›” `clickCount` GROWS between hits: 1, then 2. It's that field
        that gives birth to `dblclick`, not the interval. And the
        release's `buttons` is zero, because it describes what stays
        pressed AFTERWARD.

        â›” `modifiers` is what the CALLER asked for, and it is ORed with what
        the keyboard is really holding rather than replacing it - a click made
        inside `keyboard.down("Shift")` and one made with
        `modifiers=["Shift"]` have to reach the page identically. It used to be
        dropped entirely: `event.shiftKey` came back false on a click the
        caller had explicitly modified, with no error anywhere.r   r¡   ©rÑ   r0  rN  rÔ   r6   r!  r¢   r   N)Ú_click_planrV  rÊ   r	   r‡   rŽ   )
rC   rQ   rÑ   rÓ   rÔ   rÒ   ÚplanÚnr  Úgap_mss
             r   rÜ   zActions._click_at_point  sí   € ð ×Ò ¨Ñ1Ô1ˆÝ�q˜& 1™*Ñ%Ô%ð 
	,ð 
	,ˆAØ# A¨¡Eœ{ÑˆH�fØ×Ò˜k¨5¸Ý&1°&Ô&9ÀqØ(1ð ñ 3ô 3ð 3ð ˜#Š~ˆ~Ý”
˜8 fÑ,Ñ-Ô-Ð-Ø×Ò˜i¨°vÀqØ*+°yð ñ Bô Bð Bà˜Š|ˆ|Ý”
˜6 F™?Ñ+Ô+Ð+øð
	,ð 
	,r   c                ó¬   — |rt          |¦  «        dfg|z  S | j        €dg|z  S ddlm}  || j        || j                             d¦  «        ¬¦  «        S )u÷  How long each press lasts and how long until the next one.

        â›” A PRESS WITH NO DURATION IS A PRESS NO HAND MADE. `mousedown` and
        `mouseup` used to leave together, so what a page measured as the hold
        was one protocol round trip, and the two presses of a double click had
        nothing between them either - delivered as a `dblclick` regardless,
        because that event is born from `clickCount` and not from the interval,
        so a page saw a double click no operating system would have accepted.

        â›” `delay_ms` IS THE CALLER'S OVERRIDE and Playwright documents it in
        milliseconds - the wait between `mousedown` and `mouseup`. It used to
        be dropped here, so the only rhythm available was none.
        r6   Nr5   r   )Ú
plan_clickrà   )Únonce)rp   r:   r=   rp  r4   r%  )rC   rÓ   rÒ   rp  s       r   rk  zActions._click_plan/  s~   € ð ð 	5Ý˜8‘_”_ cÐ*Ð+¨fÑ4Ð4ØÔÐ'Ø�< &Ñ(Ð(Ø+Ð+Ð+Ð+Ð+Ð+Øˆz˜$Ô.°Ø $¤	§¢¨wÑ 7Ô 7ð9ñ 9ô 9ð 	9r   c               ón   ‡ ‡‡— t          j        ¦   «         |z   Šˆˆ ˆfd„} ‰ j        ||f|g d¢||dœ|¤ŽS )u  Writes into a field.

        â›” It doesn't just write `element.value = ...`: a site listening
        for `input`/`change` would see nothing. The injected script says
        what's needed - `needsinput` if the text has to be typed, or
        `{"setUserInput": value}` for a control a user sets by picking
        (date, color, range...). That value is committed by the ENGINE
        through Firefox's own user path (`Page.setUserInput`), so Firefox
        fires the events with the shape a user's pick gets; built here or in
        the page they came out untrusted ([B175]) or with the wrong shape.

        â›” AND THE FIRST KEY DOES NOT FOLLOW THE FOCUS IN THE SAME BREATH:
        `_reach_field` stands between them, before the injected script
        selects what the field holds, so what gets selected and replaced is
        what the page left there once it had answered the focus. A picked
        value waits the same: the person who focuses a date field does not
        commit a date in the same millisecond either.
        c                óê  •— ‰                      | |‰¦  «         ‰j                             | dd|i‰¦  «        }t          |t          ¦  «        r'|                     d¦  «        rt          d|z  ¦  «        ‚t          |t          ¦  «        r2d|v r.‰j         	                    d| ||d         dœ‰j
        d¬	¦  «         n8|d
k    r2‰r‰                     ‰¦  «         n‰j                             d¦  «         |S )Nz)(injected, el, v) => injected.fill(el, v)rW   r  zfill: %sÚsetUserInputzPage.setUserInput)rV   rW   ÚvaluerX   rY   Ú
needsinputÚDelete)r  r9   rõ   r#   r$   r  r   r%   r7   rn   r.   Ú_typerA   r  )r�   rT   rQ   r•   r‘   rC   r  s       €€€r   r�   zActions.fill.<locals>.run\  s"  ø€ Ø×Ò˜a ¨(Ñ3Ô3Ð3Ø”X—]’]ØÐ>Ø˜WÐ% tñ-ô -ˆFõ ˜&¥#Ñ&Ô&ð ;¨6×+<Ò+<¸XÑ+FÔ+Fð ;Ý% j°6Ñ&9Ñ:Ô:Ð:Ý˜&¥$Ñ'Ô'ð 2¨N¸fÐ,DÐ,DØ”—’Ð/Ø()°wØ&,¨^Ô&<ð>ð >à$(¤L¸"ð ñ >ô >ð >ð >ð ˜<Ò'Ð'Øð 2Ø—J’J˜tÑ$Ô$Ð$Ð$ð ”M×'Ò'¨Ñ1Ô1Ð1ØˆMr   )r   r   r   Úeditable)rw   rv   rZ   rS   r  )	rC   r|   r  rZ   rS   rw   rÍ   r�   r‘   s	   ` `     @r   ÚfillzActions.fillE  sŠ   øøø€ õ* ”>Ñ#Ô# gÑ-ˆð	ð 	ð 	ð 	ð 	ð 	ð 	ð4 ˆtŒ{˜8 Sð G°Zð#/ð #/ð #/à#*°XðGð Gð BFðGð Gð 	Gr   zì(injected, el) => {  if (!el.isConnected) return 'error:notconnected';  const e = injected.retarget(el, 'follow-label') || el;  const n = e.nodeName.toLowerCase();  return (n === 'input' || n === 'textarea') ? e.value : e.textContent; }r‘   c                óþ  ‡ ‡‡— ˆˆˆ fd„}‰ j                              ‰dd‰i¦  «         ‰ j        €dS ddlm}  |‰ j        d‰ j                             d¦  «        ¦  «        dz  } |¦   «         }t          j        ¦   «         }	 t          j        ¦   «         }	t          ||z   |¦  «        |	z
  }
|
d
k    rdS t          j
        t          |
|dz  ¦  «        ¦  «          |¦   «         }||k    r|t          j        ¦   «         }}Œ|)ui  Focus a field, then wait the time a person takes before the first
        key, and longer while the field visibly changes.

        â›” A PERSON DOES NOT TYPE THE INSTANT A FIELD HAS THE FOCUS, AND PAGES
        COUNT ON IT. `fill` and `type` focused and pressed the first key in
        the same breath, a few milliseconds apart, which no hand does - and a
        page that answers the focus a moment later (a store writing its stored
        answer back, a formatter, a field loading its suggestions) then wrote
        over what was already arriving. Measured by the MCP server on a real
        form: "30" gone a second after it was typed, an email keeping only its
        last letters. The server inserted a pause of its own in front of
        `fill`, importing private names of this package to draw it; the pause
        belongs to the action that types, and to every caller of it.

        The pause is one hesitation of the session's typing persona
        (`_behaviour.plan_hesitation`, act ``"field"``, one nonce per field
        of the session, from `self.acts`),
        and it starts again from every change the field shows, so a page still
        answering the focus finishes before the first key. Bounded by the
        action's own deadline: a field that never stops changing is typed into
        when the time the caller gave the action is up, not waited on forever.

        â›” NOTHING THE PAGE CAN SEE IS ADDED, ONLY TIME. The field is read in
        the utility world, through the engine's own accessors, so a page that
        wrapped `value` in its own world is not called, and a read fires no
        event. What the page does not SHOW - a timer about to fire - cannot be
        waited for by anybody.

        No persona, no pause: humanising off keeps meaning no rhythm. And a
        caller who passed `delay=` chose the interval between keys, not this.
        c                 óx   •— ‰j                              ‰‰j        d‰i¦  «        } | dk    rt          d¦  «        ‚| S )NrW   zerror:notconnectedzfield: error:notconnected)r9   rõ   Ú_FIELD_TEXT_JSr   )ÚgotrT   r�   rC   s    €€€r   r  z"Actions._reach_field.<locals>.text¦  sD   ø€ Ø”(—-’-  4Ô#6¸ÀWÐ8MÑNÔNˆCØÐ*Ò*Ð*õ &Ð&AÑBÔBÐBØˆJr   ró   rW   Nr   r  Úfieldr!  Tr   é   )r9   rõ   r;   r=   r  r4   r%  r‡   rˆ   ro   rŽ   )rC   r�   rT   r‘   r  r  r'  ÚheldÚstill_sinceÚnowÚleftÚseens   ```         r   r  zActions._reach_field†  s=  øøø€ ð@	ð 	ð 	ð 	ð 	ð 	ð 	ð 	Œ�Š�aÐIØ! 7Ð+ñ	-ô 	-ð 	-àÔÐ&ØˆFØ0Ð0Ð0Ð0Ð0Ð0Ø� Ô 3°WØ $¤	§¢¨wÑ 7Ô 7ñ9ô 9Ø;AñBˆàˆt‰vŒvˆÝ”nÑ&Ô&ˆð
	;Ý”.Ñ"Ô"ˆCÝ�{ UÑ*¨HÑ5Ô5¸Ñ;ˆDØ�qŠyˆyØ�õ ŒJ•s˜4 ¨¡Ñ+Ô+Ñ,Ô,Ð,Ø�4‘6”6ˆDØ�tŠ|ˆ|Ø$(­$¬.Ñ*:Ô*:�k�ð
	;r   rj  rN  úOptional[int]c               ó  — ||d         |d         |||p| j                              ¦   «         dœ}|�||d<   | j                             d|| j        d¬¦  «        }|pi                      dd¦  «        | _        |d         |d         f| _        d S )	Nr   r   )r¯   r`   ra   rÑ   r0  rÔ   Ú
clickCountzPage.dispatchMouseEventrX   rY   ÚeventId)rA   r-  r7   rn   r.   rL   r±   rB   )	rC   r
  rQ   rÑ   r0  rN  rÔ   rf   rµ   s	            r   rÊ   zActions._mouse_eventÄ  s«   € ð   e¨A¤h°U¸1´XØ¨'ð
 $ÐD t¤}×'BÒ'BÑ'DÔ'DðFð Fˆð Ð"Ø)ˆAˆl‰OØ”—’Ð6¸Ø%)¤\¸2ð ñ ?ô ?ˆð  &˜|¨×0Ò0°¸AÑ>Ô>ˆÔØ˜qœ 5¨¤8Ð,ˆŒˆˆr   c                ó’   — 	 | j                              |¦  «         dS # t          $ r | j                              |¦  «         Y dS w xY w)u+  Character-by-character typing.

        â›” It's a handoff to the keyboard, and the reason it isn't written
        here anymore is a measured defect: this function used to send
        `code: ""` and `keyCode: 0` for EVERY character. The event still
        fires, the text shows up in the field, the action succeeds and
        the tests pass - while the page reads an empty `event.code` on a
        key that every real Firefox names. The real layout lives in
        `keylayout.py`, generated from the bundle.

        â›” And characters the US layout doesn't have (an ideogram, an
        emoji) are not TYPED: `keyboard.type` rejects them and they go to
        `Page.insertText`. Faking a keypress for a key that doesn't exist
        is exactly the defect above, in a form that's harder to see.
        N)rA   r¯   r   Úinsert_text)rC   r  s     r   rx  zActions._typeÙ  s_   € ð 	,ØŒM×Ò˜tÑ$Ô$Ð$Ð$Ð$øÝð 	,ð 	,ð 	,ð ŒM×%Ò% dÑ+Ô+Ð+Ð+Ð+Ð+ð		,øøøs   ‚ ž$AÁA)r.   r$   )r   rO   rÄ   )rS   r$   rT   r$   )r|   r$   rZ   rp   rS   r}   rw   r}   rx   rO   ry   rO   rz   rO   r{   rO   )r   r$   )rz   rO   r£   r¤   )
r|   r$   r¸   r$   rZ   rp   rS   r}   ry   rO   )r|   r$   rZ   rp   rS   r}   rw   r}   )r|   r$   rZ   rp   rS   r}   rÑ   rÕ   rÒ   rÖ   rÓ   rÕ   rÔ   rÕ   rw   r}   )r|   r$   rZ   rp   rS   r}   rÒ   rÖ   rÑ   rÕ   rÔ   rÕ   )
r|   r$   rê   rO   rZ   rp   rS   r}   rw   r}   )r|   r$   rZ   rp   rS   r}   )r|   r$   r
  r$   rZ   rp   rS   r}   )r|   r$   r  r$   rZ   rp   rS   r}   rw   r}   r  rÖ   )r|   r$   r  r$   rZ   rp   rS   r}   r  rp   rw   r}   )r0  rÕ   r   rÕ   )rD  r$   rE  r$   rZ   rp   rS   r}   )r`   rp   ra   rp   rS  rÕ   r   rT  )rÑ   rÕ   rÓ   rÕ   r   rT  )
r`   rp   ra   rp   rÑ   rÕ   rÓ   rÕ   rÒ   rÖ   )rb  rp   rc  rp   r   rT  )
rÑ   rÕ   rÓ   rÕ   rÔ   rÕ   rÒ   rÖ   r   rT  )rÓ   rÕ   rÒ   rÖ   )
r|   r$   r  r$   rZ   rp   rS   r}   rw   r}   )r‘   rp   r   rT  )
r
  r$   rÑ   rÕ   r0  rÕ   rN  r†  rÔ   rÕ   )r  r$   )+r   r   r   r±   r;   rF   rN   rR   ru   r™   r�   rœ   r·   r¿   rÐ   rà   râ   rç   ré   rå   rø   rþ   r  r	  r  r  r  r)  r.  rC  rR  rX  r\  r^  ra  rh  rÜ   rk  rz  r}  r  rÊ   rx  r   r   r   r+   r+   e   sÕ  € € € € € ð
 €Nð €Nð %)¸$ð4#ð 4#ð 4#ð 4#ð 4#ð 4#ðn,ð ,ð ,ð,9ð 9ð 9ð 9ð%3ð %3ð %3ð %3ð %3ðP 48Ø $ÀØ¸$Ø"°5Ø"¸ð	qð qð qð qð qð qðhPð Pð Pð Pð2ð 2ð 2ð* &+Ø&>ðdð dð dð dð dð dðN @IØ+/È4Ø).ð-ð -ð -ð -ð -ð -ð` 8<ÐW[Ø¸ðIð Ið Ið Ið Ið Ið  8<ÐW[ÐklØ*.Ø¨¸qØ*.ðMð Mð Mð Mð Mð Mð4 ;?ÐZ^Ø-1Ø ¨4À!ðJð Jð Jð Jð Jð Jð& 8<ÐW[Ø¸ðOð Oð Oð Oð Oð Oð
 :>ÐY]Ø¸4ðOð Oð Oð Oð Oð Oð 04¸dØ15ð"Ið "Ið "Ið "Ið "Ið "IðH 8<Ø(,Ø*.ðMð Mð Mð Mð Mð Mð 7;Ø'+ð	6ð 	6ð 	6ð 	6ð 	6ð 	6ð >BØ.2ð	Gð 	Gð 	Gð 	Gð 	Gð 	Gð IMØ04Ø26ð:ð :ð :ð :ð :ð :ð:6Ø(,Èð6ð 6ð 6ð 6ð 6ð 6ð( BFØ(,Ø*.Ø*.ð:ð :ð :ð :ð :ð :ð0 GKÐfjØ!$À$ð:ð :ð :ð :ð :ð :ð. IMØ26Ø48ð/6ð /6ð /6ð /6ð /6ð /6ðb 6:ÐUYØðIð Ið Ið Ið Ið Ið  23ð /ð /ð /ð /ð /ð /ðd (,Ø04ð6ð 6ð 6ð 6ð 6ð 6ðr 89ð ;ð ;ð ;ð ;ð ;ð ;ð +,¸1ð Kð Kð Kð Kð Kð Kð )*¸ð 9ð 9ð 9ð 9ð 9ð 9ð =>Ø¸Tð0ð 0ð 0ð 0ð 0ð 0ð6ð 6ð 6ð 6ð 78Ø&'¸!Ø48ð,ð ,ð ,ð ,ð ,ð ,ð69ð 9ð 9ð 9ð 9ð, BFØ'+Ø)-ð4Gð 4Gð 4Gð 4Gð 4Gð 4Gðv	Tð ð;;ð ;;ð ;;ð ;;ð| EFØ$%ÀDØ&'ð-ð -ð -ð -ð -ð -ð*,ð ,ð ,ð ,ð ,ð ,r   r+   )r   r   )r   Ú
__future__r   r‡   Útypingr   Ú r   rE   r   rA   r	   r
   r   r†   ÚTimeoutErrorr   r…   r   r   r)   r+   r   r   r   ú<module>r�     sc  ððð ð4 #Ð "Ð "Ð "Ð "Ð "à €€€Ø Ð Ð Ð Ð Ð à Ð Ð Ð Ð Ð Ø %Ð %Ð %Ð %Ð %Ð %Ø 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7ð
 1Ð0Ð0€ðPð Pð Pð Pð P˜<ñ Pô Pð Pðð ð ð ð �<ñ ô ð ð&ð ð ð ð �\ñ ô ð ð ð ð ð ð(J,ð J,ð J,ð J,ð J,ñ J,ô J,ð J,ð J,ð J,r   