§
    ›ÇjeY ã                  óR  — 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mZmZmZmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZmZ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(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 ddl1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:  G d„ de¦  «        Z; G d„ de¦  «        Z< G d„ de<¦  «        Z= G d„ de<¦  «        Z> G d„ de<¦  «        Z?dZ@dGd „ZAd!ZBd"ZCdHd%„ZDdId'„ZEdJd+„ZF G d,„ d-e¦  «        ZG G d.„ d/e¦  «        ZH G d0„ d1e¦  «        ZI G d2„ d3e¦  «        ZJ G d4„ d5e¦  «        ZK G d6„ d7e¦  «        ZLdKd:„ZM G d;„ d<e¦  «        ZN G d=„ d>e¦  «        ZO G d?„ d@e¦  «        ZP G dA„ dBe¦  «        ZQ G dC„ dDe¦  «        ZR G dE„ dFe¦  «        ZSdS )Luá  The Python side of the Playwright protocol, backed by Juggler.

â›” EVERY SHAPE IN THIS FILE WAS MEASURED, NOT DEDUCED. `scripts/capture_protocol.py`
records a real session against the Node driver, and the initializers, the object
parentage, the event names and the ordering below come from that recording. The
difference matters: reading `_impl` tells you which initializer fields are
CONSUMED today, and the fields a future code path will want are exactly the ones
that reading cannot show you.

**WHAT THE RECORDING SAID, and some of it is not what you would guess:**

- `goto`, `click`, `fill`, `title`, `content` and `querySelector` are sent to
  the **Frame**, not the Page. The Page owns almost nothing.
- `mouseMove` IS sent to the Page - and in a humanised session it arrives
  nineteen times for one click, because the cursor travels.
- `BrowserContext` is created with three children already alive - `Debugger`,
  `Tracing`, `APIRequestContext` - and each is announced BEFORE the context that
  names it, then re-parented with `__adopt__`.
- A `Frame` is created before its `Page` and adopted afterwards, so the Page
  initializer can point at a `mainFrame` that already exists.

**THE ORDER IS THE PROTOCOL.** `Connection.dispatch` looks a guid up in a plain
dict and raises `Cannot find object` when it is missing, so a `__create__` that
arrives after the message naming it is not a race that usually works: it is a
hard failure. Everything here creates first and returns the channel second.
é    )ÚannotationsN)ÚAnyÚDictÚListÚOptionalé   )ÚPageActsÚpopup_numberé   )Ú
connection)ÚActions)Ú
DispatcherÚProtocolExceptionÚServer)ÚInjectedScript)ÚMODIFIER_MASK)Ú	Lifecycle)Ú_as_callableÚ_buttonÚ
_called_onÚ_console_textÚ_deserializeÚ_element_functionÚ_guid_ofÚ_headers_arrayÚ
_js_stringÚ	_locationÚ_resource_typeÚ
_serializeÚ_with_argument)ÚSessionLocaleÚparse_proxy)Ú_domain_matchesÚ_host_ofÚ	_only_setÚ_read_versionÚ_remove_profileÚ_write_user_jsc                  ó8   ‡ — e Zd ZdZdZddiZdˆ fd„Zdd„Zˆ xZS )ÚDisposableDispatcheruí  The handle `add_init_script` gives back so a caller can remove it.

    â›” IT IS PART OF THE CONTRACT, NOT AN EXTRA. `_page.py` and
    `_browser_context.py` both wrap the reply in `from_channel(...)`, so a
    server that answers `None` does not merely lose the handle - it raises
    `AttributeError: 'NoneType' object has no attribute '_object'` inside the
    client, on a call that otherwise worked. The first implementation here
    returned None and that is exactly what happened.
    Ú
DisposableÚdisposeÚ
op_disposeÚreturnÚNonec                ó\   •— || _         t          ¦   «                              ||i ¦  «         d S ©N)Ú_undoÚsuperÚ__init__)ÚselfÚserverÚparentÚundoÚ	__class__s       €úUC:\Projects\Historical\venv\Lib\site-packages\invisible_playwright/_juggler/server.pyr4   zDisposableDispatcher.__init__\   s,   ø€ ØˆŒ
Ý‰Œ×Ò˜ ¨Ñ,Ô,Ð,Ð,Ð,ó    Úparamsr   r   c                óz   — 	 |                       ¦   «          n# t          $ r Y nw xY w|                      ¦   «          d S r1   )r2   Ú	Exceptionr,   ©r5   r<   s     r:   r-   zDisposableDispatcher.op_dispose`   sL   € ð	Ø�JŠJ‰LŒLˆLˆLøÝð 	ð 	ð 	ð ˆDð	øøøð 	�Š‰ŒˆØˆts   ‚ —
$£$©r.   r/   ©r<   r   r.   r   )	Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚTYPEÚMETHODSr4   r-   Ú__classcell__©r9   s   @r:   r*   r*   N   sl   ø€ € € € € ðð ð €DØ˜,Ð'€Gð-ð -ð -ð -ð -ð -ðð ð ð ð ð ð ð r;   r*   c                  ó(   ‡ — e Zd ZdZdZd
ˆ fd	„Zˆ xZS )ÚRefusingDispatcherul  An object that exists so the tree is well formed, and refuses the rest.

    â›” IT EXISTS BECAUSE THE PROTOCOL REQUIRES IT, NOT BECAUSE WE SUPPORT IT.
    `BrowserContext`'s initializer names a `tracing`, a `debugger` and a
    `requestContext`, and `_browser_context.py` reads all three with
    `from_channel` at construction time. Leaving them out does not disable
    tracing: it raises a KeyError before any page exists.

    So they are created, and every method on them refuses with a reason. That is
    the whole of section 5.4: out of perimeter must FAIL LOUDLY, never no-op and
    never AttributeError.
    znot implementedÚmethodÚstrr<   r   r.   r   c                óž   •— || j         v r"t          ¦   «                              ||¦  «        S t          | j        ›d|›d| j        ›d�¦  «        ‚)Nú.z2 is outside what invisible_playwright implements: zW. This is a deliberate refusal, not a gap - see 32-stacco-da-playwright.md section 5.4.)rG   r3   Úcallr   rF   ÚREASON)r5   rL   r<   r9   s      €r:   rP   zRefusingDispatcher.call{   sX   ø€ Ø�T”\Ð!Ð!Ý‘7”7—<’< ¨Ñ/Ô/Ð/Ýð Œyˆyˆy˜&˜&˜& $¤+ + +ð/ñ0ô 0ð 	0r;   ©rL   rM   r<   r   r.   r   )rB   rC   rD   rE   rQ   rP   rH   rI   s   @r:   rK   rK   k   sN   ø€ € € € € ðð ð €Fð0ð 0ð 0ð 0ð 0ð 0ð 0ð 0ð 0ð 0r;   rK   c                  ó(   — e Zd ZdZdZdddœZdd	„Zd
S )ÚTracingDispatcherÚTracingzgtracing is outside the automation core; it records a session for the trace viewer and drives none of itÚ	stop_noop)ÚtracingStopÚtracingStopChunkr<   r   r.   r   c                ó
   — dd iS )NÚartifact© r?   s     r:   rV   zTracingDispatcher.stop_noop‹   s   € ð ˜DÐ!Ð!r;   NrA   )rB   rC   rD   rF   rQ   rG   rV   r[   r;   r:   rT   rT   …   sA   € € € € € Ø€Dð;€Fà)¸{ÐKÐK€Gð"ð "ð "ð "ð "ð "r;   rT   c                  ó   — e Zd ZdZdZdS )ÚDebuggerDispatcherÚDebuggerz<the inspector and its paused state are not part of this forkN)rB   rC   rD   rF   rQ   r[   r;   r:   r]   r]   ’   s   € € € € € Ø€DØK€F€F€Fr;   r]   c                  ó&   — e Zd ZdZdZddiZdd	„Zd
S )ÚAPIRequestContextDispatcherÚAPIRequestContextz}APIRequestContext performs HTTP outside the page, which is not browser automation and carries none of the browser fingerprintr,   Údispose_selfr<   r   r.   r   c                ó.   — |                       ¦   «          d S r1   )r,   r?   s     r:   rb   z(APIRequestContextDispatcher.dispose_self�   s   € Ø�Š‰ŒˆØˆtr;   NrA   )rB   rC   rD   rF   rQ   rG   rb   r[   r;   r:   r`   r`   —   s?   € € € € € Ø€DðO€Fà˜.Ð)€Gðð ð ð ð ð r;   r`   z<element handle>r<   r   r.   úOptional[float]c                óR   — |                       d¦  «        }|€dnt          |¦  «        S )uÜ  The caller's `delay` for a key operation, in milliseconds, or None.

    â›” ONE PLACE READS IT, for the same reason `_act_opts` and `_pointer` exist:
    six key operations take it, and the copies that each read it on their own
    were how `page.type(sel, text, delay=100)`, `locator.type`,
    `press_sequentially` and `locator.press(delay=...)` came to accept it and
    drop it, while `keyboard.type` and the element-handle `type` honoured it.

    It means two things and the callers say which: for `type` it is the gap
    between two keys, for `press` the time the key stays down, as Playwright
    documents both. Either way it overrides the session's hand rather than
    replacing a rhythm that is otherwise missing.
    ÚdelayN)ÚgetÚfloat)r<   rf   s     r:   Ú
_key_delayri   ª   s)   € ð �JŠJ�wÑÔ€EØ�=ˆ4ˆ4¥e¨E¡l¤lÐ2r;   zinvisible.server.session_seedz!invisible.server.motion_budget_msÚprefsÚtuplec                óà   — t          | ¦  «        }|                     t          d¦  «        }|                     t          d¦  «        }||€dnt	          |¦  «        |€dnt	          |¦  «        dz  fS )uü  Split the launch prefs into what the BROWSER gets and what the SESSION
    keeps: the seed of its rhythms, and the budget one movement may spend.

    â›” A FUNCTION RATHER THAN THREE LINES INSIDE `op_launch`, because the thing
    worth testing is that the keys come OUT: a version that read them and forgot
    to remove them would behave identically in every observable way except for
    writing a session identifier into the profile, which no test that drives a
    browser would notice.

    â›” A MALFORMED VALUE RAISES rather than falling back to no rhythm. Emitting
    input at pipe speed is precisely the failure these personae exist to
    remove, and a fallback would make it the quiet default whenever the
    launcher sent something unexpected.
    Nç     @�@)ÚdictÚpopÚSESSION_SEED_PREFÚMOTION_BUDGET_PREFÚint)rj   ÚrestÚseedÚ	budget_mss       r:   Útake_session_motionrv   Ø   sn   € õ �‰;Œ;€DØ�8Š8Õ% tÑ,Ô,€DØ—’Õ+¨TÑ2Ô2€IØØ�\ˆTˆT¥s¨4¡y¤yØÐ&ˆTˆT­C°	©N¬N¸VÑ,CðFð Fr;   úDict[str, str]c                óP   — | st          t          j        ¦  «        S d„ | D ¦   «         S )a  The environment a launched browser gets, from what the caller named.

    `named` is the protocol's `env`: a list of ``{"name", "value"}`` pairs,
    or nothing. Naming nothing (no list, or an empty one) means "inherit this
    process's environment"; naming anything means "this, and only this" - so
    a variable the caller left out is a variable the browser does not get.
    The `None` half of a hidden surface's `launch_env()` depends on the
    second sentence, and the network of a bare launch on the first.
    c                ó,   — i | ]}|d          |d         “ŒS ©ÚnameÚvaluer[   )Ú.0Úes     r:   ú
<dictcomp>z'_launch_environment.<locals>.<dictcomp>û   s"   € Ð1Ð1Ð1 aˆAˆfŒI�q˜”zÐ1Ð1Ð1r;   )rn   ÚosÚenviron)Únameds    r:   Ú_launch_environmentrƒ   ï   s0   € ð ð  Ý•B”JÑÔÐØ1Ð1¨5Ð1Ñ1Ô1Ð1r;   r6   ú'JugglerServer'Úlistc                ó  ‡ — |                      d¦  «        }|rt          d|z  ¦  «        ‚|                      d¦  «        p|                      d¦  «        }|rd„ |D ¦   «         S ˆ fd„|                      d¦  «        pg D ¦   «         S )u÷  The local paths a `setInputFiles` request stands for.

    â›” ONE READER, because there are two senders. The same request arrives at
    the Frame (a selector) and at the ElementHandle (a chooser already holding
    the input), and the wire shape is the same for both. Two dispatchers each
    unpacking that by hand is two places that know one fact, and the second
    one is always the one that falls behind.

    â›” THREE SHAPES, AND ONLY ONE WAS READ. The client sends `localPaths` for
    files, `localDirectory` for a folder (`<input webkitdirectory>`), and
    `payloads` - name, MIME type and base64 bytes - when the caller hands
    over content instead of a path. Only `localPaths` was read, so the other
    two became an EMPTY upload: the input was cleared, `change` fired with
    no files, and the call returned as if it had worked. Measured on 0.25.7:
    a payload `note.txt` arrived as `files.length == 0`.

    A payload is written to a file this session owns and goes through the
    same engine command as a path, so the page receives it the way it
    receives a file a user picked - and, as for a user's pick, Firefox derives
    the file's type from its name; the payload's `mimeType` is not carried.
    `streams` are the remote-connection path (`createTempFiles`), outside the
    perimeter by decision; this client never sends them to a local server.

    â›” A FOLDER IS REFUSED, BY NAME. The engine's `Page.setFileInputFiles`
    takes files: handed the folder's path it took the TAB down (the next call
    answered "cannot find session"), measured on firefox-34 and on the engine
    after it. Read as an empty list, as before, the engine answered with an
    exception naming neither the folder nor the reason. Both are worse than
    saying it.
    ÚlocalDirectoryzpset_input_files with a folder (%s) is not supported: the engine takes files, so pass the files inside it insteadÚ
localPathsÚfilesc                óf   — g | ].}t          |t          ¦  «        r|                     d ¦  «        n|‘Œ/S )r{   )Ú
isinstancern   rg   )r}   Úentrys     r:   ú
<listcomp>z!_upload_paths.<locals>.<listcomp>$  sH   € ð "ð "ð "Øõ &0°µtÑ%<Ô%<ÐG�—	’	˜&Ñ!Ô!Ð!À%ð "ð "ð "r;   c                ó:   •— g | ]}‰                      |¦  «        ‘ŒS r[   )Ústage_upload)r}   Úpayloadr6   s     €r:   r�   z!_upload_paths.<locals>.<listcomp>&  s7   ø€ ð 9ð 9ð 9Øð ×Ò Ñ(Ô(ð 9ð 9ð 9r;   Úpayloads)rg   r   )r6   r<   Ú	directoryÚraws   `   r:   Ú_upload_pathsr”   þ   sÌ   ø€ ð> —
’
Ð+Ñ,Ô,€IØð LÝð?ØAJñKñLô Lð 	Lð �*Š*�\Ñ
"Ô
"Ð
9 f§j¢j°Ñ&9Ô&9€CØ
ð "ð"ð "Ø ð"ñ "ô "ð 	"ð9ð 9ð 9ð 9Ø!Ÿ:š: jÑ1Ô1Ð7°Rð9ñ 9ô 9ð 9r;   c            
      ó®  ‡ — e Zd ZdZi dd“dd“dd“dd	“d
d“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“d d!“d"d#“d$d%d&d'd(d)d*d+d,œ¥Z	 dZd.d/œd[ˆ fd8„Zed\d:„¦   «         Zed]d<„¦   «         Zd^d@„Z	d^dA„Z
d^dB„Zd^dC„Zd^dD„Zd^dE„Zd^dF„Zd^dG„Zd^dH„Zd^dI„Zd^dJ„Zd^dK„Zd^dL„Zd^dM„Zd^dN„Zd_dO„Zd^dP„Zd^dQ„Zd^dR„Zd^dS„Zd^dT„Zd^dU„Zd^dV„Zd^dW„Z d^dX„Z!d^dY„Z"ˆ xZ#S )`ÚElementHandleDispatcherÚElementHandler,   r-   ÚboundingBoxÚop_bounding_boxÚcheckHitTargetÚop_check_hit_targetÚevaluateExpressionÚop_evaluateÚtextContentÚop_text_contentÚ	innerTextÚop_inner_textÚ	innerHTMLÚop_inner_htmlÚ
inputValueÚop_input_valueÚgetAttributeÚop_get_attributeÚscrollIntoViewIfNeededÚop_scroll_into_viewÚ
ownerFrameÚop_owner_frameÚcontentFrameÚop_content_frameÚgetPropertyÚop_get_propertyÚgetPropertyListÚop_get_property_listÚ	jsonValueÚop_json_valueÚclickÚop_clickÚhoverÚop_hoverÚop_fillÚop_typeÚop_pressÚop_focusÚop_checkÚ
op_uncheckÚop_select_optionÚop_set_input_files)ÚfillÚtypeÚpressÚfocusÚcheckÚuncheckÚselectOptionÚsetInputFilesÚ Úutility©ÚworldÚframeú'FrameDispatcher'Ú	object_idrM   ÚpreviewrË   r.   r/   c               ó€   •— || _         || _        || _        t          ¦   «                              ||d|pdi¦  «         d S )NrÏ   úJSHandle@node)rÌ   rÎ   rË   r3   r4   )r5   r6   rÌ   rÎ   rÏ   rË   r9   s         €r:   r4   z ElementHandleDispatcher.__init__K  sX   ø€ àˆŒ
Ø"ˆŒð ˆŒ
õ 	‰Œ×Ò˜ Ø# WÐ%?°Ð@ñ	Bô 	Bð 	Bð 	Bð 	Br;   ú'InjectedScript'c                ó   — | j         j        S r1   ©ÚpageÚinjected©r5   s    r:   rÖ   z ElementHandleDispatcher.injectedj  ó   € àŒyÔ!Ð!r;   ú'PageDispatcher'c                ó   — | j         j        S r1   )rÌ   rÕ   r×   s    r:   rÕ   zElementHandleDispatcher.pageo  s   € àŒzŒÐr;   r<   r   r   c                ó¦   — 	 | j                              | j        j        | j        ¦  «         n# t
          $ r Y nw xY w|                      ¦   «          d S r1   )rÖ   r,   rÌ   Úframe_idrÎ   r>   r?   s     r:   r-   z"ElementHandleDispatcher.op_disposes  s_   € ð	ØŒM×!Ò! $¤*Ô"5°t´~ÑFÔFÐFÐFøÝð 	ð 	ð 	ð ˆDð		øøøð
 	�Š‰ŒˆØˆts   ‚*- ­
:¹:c                óZ   — d| j                              | j        j        | j        ¦  «        iS ©Nr|   )rÖ   Úbounding_boxrÌ   rÜ   rÎ   r?   s     r:   r™   z'ElementHandleDispatcher.op_bounding_box~  ó/   € Ø˜œ×3Ò3ØŒJÔ ¤ñ1ô 1ð 2ð 	2r;   c           
     óÎ   — |d         }d| j         j                             | j        j        | j        t          |d         ¦  «        t          |d         ¦  «        f¦  «        dk    iS )u	  Would an event at this MAIN-FRAME point land on this element?

        â›” NOT A PLAYWRIGHT METHOD: the humanised cursor (`_cursor._hits`) is
        its only caller, asking about the off-centre point it is about to aim
        at. The point is in the space `boundingBox` answers in, and the answer
        is the one the action's own check gives (`Actions.hit_target`): the
        same frame shift, the same shadow-aware test. A second hit test here
        would be a second definition of where a click lands.
        Úpointr|   ÚxÚyÚdone)rÕ   ÚactionsÚ
hit_targetrÌ   rÜ   rÎ   rh   )r5   r<   râ   s      r:   r›   z+ElementHandleDispatcher.op_check_hit_target‚  se   € ð �w”ˆØ˜œÔ*×5Ò5ØŒJÔ ¤Ý�5˜”:ÑÔ¥ e¨C¤jÑ 1Ô 1Ð2ñ4ô 4à7=ò>ð ?ð 	?r;   c           	     ó”   — dt          | j                             | j        j        t          |¦  «        d| j        i¦  «        ¦  «        iS )uK  `handle.evaluate(fn, arg)` - and the SECOND argument is the point.

        â›” IT USED TO CALL `r(el)` AND DROP `arg` ON THE FLOOR, and that was
        not a corner: Playwright's contract is `fn(element, arg)`, so every
        caller passing data got `undefined` where their value should be. The
        expression then threw inside the page, the client turned it into an
        evaluation error, and callers that treat a failed probe as "no" - which
        is the sane way to write a probe - simply took the wrong branch in
        silence.

        â›” THE COST, MEASURED. The humanised cursor asks the element whether an
        off-centre point actually lands on it (`_cursor._hits`, which passes
        `{x, y}` as exactly this argument). With `arg` dropped the check threw
        every single time, was caught, and answered False - so the landing
        override was never applied and EVERY click fell on the exact geometric
        centre of its element. That is the tell `_landing_override`'s own
        docstring describes: one exact number, identical in every install,
        readable from a single event. The whole landing feature was inert on
        this transport and nothing failed.

        It was found by diffing the protocol against the Node driver: the
        driver's `click` carried a `position` and ours did not.
        r|   ÚobjectId)r   rÖ   rP   rÌ   rÜ   r   rÎ   r?   s     r:   r�   z#ElementHandleDispatcher.op_evaluate‘  sN   € ð0 � D¤M×$6Ò$6ØŒJÔÕ!2°6Ñ!:Ô!:Ø˜œÐ(ñ%*ô %*ñ +ô +ð ,ð 	,r;   c                óZ   — d| j                              | j        j        | j        ¦  «        iS rÞ   )rÖ   Útext_contentrÌ   rÜ   rÎ   r?   s     r:   rŸ   z'ElementHandleDispatcher.op_text_content­  rà   r;   c                óZ   — d| j                              | j        j        | j        ¦  «        iS rÞ   )rÖ   Ú
inner_textrÌ   rÜ   rÎ   r?   s     r:   r¡   z%ElementHandleDispatcher.op_inner_text±  ó/   € Ø˜œ×1Ò1ØŒJÔ ¤ñ1ô 1ð 2ð 	2r;   c                óZ   — d| j                              | j        j        | j        ¦  «        iS rÞ   )rÖ   Ú
inner_htmlrÌ   rÜ   rÎ   r?   s     r:   r£   z%ElementHandleDispatcher.op_inner_htmlµ  rî   r;   c                óZ   — d| j                              | j        j        | j        ¦  «        iS rÞ   )rÖ   Úinput_valuerÌ   rÜ   rÎ   r?   s     r:   r¥   z&ElementHandleDispatcher.op_input_value¹  s/   € Ø˜œ×2Ò2ØŒJÔ ¤ñ1ô 1ð 2ð 	2r;   c                óh   — d| j                              | j        j        | j        |d         ¦  «        iS )Nr|   r{   )rÖ   Úget_attributerÌ   rÜ   rÎ   r?   s     r:   r§   z(ElementHandleDispatcher.op_get_attribute½  s9   € Ø˜œ×4Ò4ØŒJÔ ¤°¸´ñAô Að Bð 	Br;   c                ó¶   — | j                              | j        j        dd| j        i|d         d¬¦  «        }t          | j        | j        |¦  «        }d|j        iS )Nú(injected, o, n) => o[n]ré   r{   F©Úby_valueÚhandle)rÖ   rP   rÌ   rÜ   rÎ   r–   r6   Úchannel©r5   r<   rÎ   rù   s       r:   r¯   z'ElementHandleDispatcher.op_get_propertyÁ  sa   € Ø”M×&Ò&ØŒJÔØ&Ø˜œÐ(¨&°¬.À5ð 'ñ Jô Jˆ	õ )¨¬°d´jÀ)ÑLÔLˆØ˜&œ.Ð)Ð)r;   c                óF  — | j                              | j        j        dd| j        i¦  «        pg }g }|D ]j}| j                              | j        j        dd| j        i|d¬¦  «        }t          | j        | j        |¦  «        }|                     ||j        dœ¦  «         Œkd|iS )uò   â›” ONE HANDLE PER PROPERTY, and each one holds its value alive. On a
        large object this is the most expensive call in the file, which is why
        `json_value` exists and should be preferred when the values are
        serialisable.z6(injected, o) => o === Object(o) ? Object.keys(o) : []ré   rö   Fr÷   rz   Ú
properties)	rÖ   rP   rÌ   rÜ   rÎ   r–   r6   Úappendrú   )r5   r<   ÚnamesÚoutr{   rÎ   rù   s          r:   r±   z,ElementHandleDispatcher.op_get_property_listÉ  sÍ   € ð
 ”×"Ò"ØŒJÔØDØ˜œÐ(ñ*ô *ð 0ð .0ð 	ð ˆØð 	@ð 	@ˆDØœ×*Ò*Ø”
Ô#Ð%?Ø˜Tœ^Ð,¨d¸Uð +ñ Dô DˆIõ -¨T¬[¸$¼*ÀiÑPÔPˆFØ�JŠJ ¨v¬~Ð>Ð>Ñ?Ô?Ð?Ð?Ø˜cÐ"Ð"r;   c           	     ó  — t          | dd¦  «        dk    r:dt          | j                             | j        j        d| j        ¦  «        ¦  «        iS dt          | j                             | j        j        dd| j        i¦  «        ¦  «        iS )u*  The handle's value, read IN THE WORLD THE HANDLE LIVES IN.

        â›” Almost every handle here is a utility-world one and takes the first
        branch. The exception is what `waitForFunction` hands back: the
        caller's expression ran in the page's own world, so its result exists
        only there. Reading it through the utility world asks Juggler about an
        objectId that context has never seen, and the answer is not an error a
        caller can act on - it is an evaluation failure on a handle they were
        just given.
        rË   rÉ   Úmainr|   z(injected, o) => oré   )Úgetattrr   rÖ   Újson_value_inrÌ   rÜ   rÎ   rP   r?   s     r:   r³   z%ElementHandleDispatcher.op_json_valueÛ  s˜   € õ �4˜ )Ñ,Ô,°Ò6Ð6Ø�Z¨¬×(CÒ(CØ”
Ô# V¨T¬^ñ)=ô )=ñ >ô >ð ?ð ?à� D¤M×$6Ò$6ØŒJÔÐ!5Ø˜œÐ(ñ%*ô %*ñ +ô +ð ,ð 	,r;   c                óZ   — | j                              | j        j        | j        ¦  «         dS )uh  Bring the element into view, through the injected script.

        â›” IT USED TO SEND `Page.scrollIntoViewIfNeeded`, AND THAT COMMAND CAN
        NEVER SUCCEED. [B184]: the engine's handler calls
        `unsafeObject.scrollRectIntoViewIfNeeded`, and that method is not
        declared in ANY binding of `Element` in the tree - not a `.webidl`, not
        a `.idl`, not `Bindings.conf` - so it is `undefined` for every caller
        and the `else` branch always throws. Measured on the shipped binary at
        four positions, including an element ALREADY IN VIEW: timeout every
        time, while `bounding_box()` on the same element answered correctly.

        â›” AND THE REMEDY WAS ALREADY IN THIS FILE'S REACH, which is the part
        worth knowing. `Actions` scrolls before every click through
        `InjectedScript.scroll_into_view` - native `scrollIntoView` reached from
        the utility world, `block: "center"` - and has done since a click below
        the fold was found to miss. So the click path scrolled correctly while
        the public method sent a command that cannot work. One concept, two
        implementations, and the broken one was the one users call.

        Reusing that helper rather than writing a second one is the whole fix:
        no new abstraction, and the two paths cannot drift.

        â›” `rect` IS NOT HONOURED, and saying so is better than pretending.
        Playwright can ask to scroll a sub-rectangle of the element; the helper
        scrolls the element. No caller in this package passes it, and a partial
        answer that looks total is worse than a named limit.
        N)rÖ   Úscroll_into_viewrÌ   rÜ   rÎ   r?   s     r:   r©   z+ElementHandleDispatcher.op_scroll_into_viewí  s(   € ð8 	Œ×&Ò& t¤zÔ':¸D¼NÑKÔKÐKØˆtr;   c                ó   — d| j         j        iS )NrÌ   )rÌ   rú   r?   s     r:   r«   z&ElementHandleDispatcher.op_owner_frame  s   € Ø˜œÔ+Ð,Ð,r;   c                óÜ   — | j                              d| j        j        | j        dœ¦  «        pi }|                     d¦  «        }|sddiS | j                              |¦  «        }d|j        iS )u  The frame this element CONTAINS, for an iframe.

        â›” Answers null rather than raising when the element is not a frame
        owner: that is what the client expects, and raising would turn an
        ordinary "this div is not an iframe" into a failed script.
        úPage.describeNode©ÚframeIdré   ÚcontentFrameIdrÌ   N)rÕ   ÚsendrÌ   rÜ   rÎ   rg   Ú	frame_forrú   )r5   r<   ÚresultÚcontent_frame_idrÌ   s        r:   r­   z(ElementHandleDispatcher.op_content_frame  s‰   € ð ”—’Ð 3Ø,0¬JÔ,?Ø-1¬^ð!=ð !=ñ>ô >ð DàACð 	ð "Ÿ:š:Ð&6Ñ7Ô7ÐØð 	#Ø˜T�?Ð"Ø”	×#Ò#Ð$4Ñ5Ô5ˆØ˜œÐ'Ð'r;   c                ó�   — | j                              |¦  «        | j         j        | j        dœ| j                              |¦  «        ¥S )uƒ  â›” THE PER-ACTION OPTIONS COME THROUGH HERE TOO, and that is why
        every operation on this class uses this helper rather than spelling the
        three arguments out. `strict` is inert on a handle - the node is given,
        not looked up - but `trial` and `force` are not, and an operation that
        built its own argument set would be the one written without them.
        )ÚtimeoutrÜ   Ú
element_id)rÌ   Ú_timeoutrÜ   rÎ   Ú	_act_optsr?   s     r:   Ú	_act_argsz!ElementHandleDispatcher._act_args<  sM   € ð  œ:×.Ò.¨vÑ6Ô6Ø œJÔ/Ø"œnð0ð 0ð ”*×&Ò& vÑ.Ô.ð0ð 	0r;   c                óÎ   —  | j         j        j        t          fd| j                              |¦  «        i| j                              |¦  «        ¤|                      |¦  «        ¤Ž d S ©NÚposition)rÌ   ræ   r´   Ú_HANDLEÚ	_positionÚ_pointerr  r?   s     r:   rµ   z ElementHandleDispatcher.op_clickH  so   € Ø ˆŒ
ÔÔ ¥ð 	;ð 	;°4´:×3GÒ3GÈÑ3OÔ3Oð 	;Ø#'¤:×#6Ò#6°vÑ#>Ô#>ð	;à#'§>¢>°&Ñ#9Ô#9ð	;ð 	;ð 	;ð ˆtr;   c                óš   —  | j         j        j        t          fd| j                              |¦  «        i|                      |¦  «        ¤Ž d S r  )rÌ   ræ   r¶   r  r  r  r?   s     r:   r·   z ElementHandleDispatcher.op_hoverN  óU   € Ø ˆŒ
ÔÔ ¥ð 	;ð 	;°4´:×3GÒ3GÈÑ3OÔ3Oð 	;Ø#'§>¢>°&Ñ#9Ô#9ð	;ð 	;ð 	;àˆtr;   c                óš   —  | j         j        j        t          fd| j                              |¦  «        i|                      |¦  «        ¤Ž d S r  )rÌ   ræ   rÄ   r  r  r  r?   s     r:   r¼   z ElementHandleDispatcher.op_checkS  r  r;   c                óš   —  | j         j        j        t          fd| j                              |¦  «        i|                      |¦  «        ¤Ž d S r  )rÌ   ræ   rÅ   r  r  r  r?   s     r:   r½   z"ElementHandleDispatcher.op_uncheckX  sU   € Ø"ˆŒ
ÔÔ"¥7ð 	=ð 	=°T´Z×5IÒ5IÈ&Ñ5QÔ5Qð 	=Ø%)§^¢^°FÑ%;Ô%;ð	=ð 	=ð 	=àˆtr;   c                ót   —  | j         j        j        t          |d         fi |                      |¦  «        ¤Ž d S rÞ   )rÌ   ræ   rÀ   r  r  r?   s     r:   r¸   zElementHandleDispatcher.op_fill]  s9   € ØˆŒ
ÔÔ¥¨°¬ÐSÐS¸D¿NºNÈ6Ñ<RÔ<RÐSÐSÐSØˆtr;   c                ó–   —  | j         j        j        t          |d         fdt	          |¦  «        pdi|                      |¦  «        ¤Ž dS )zôOne key per character, and it does NOT clear first.

        The same distinction the selector version carries: `fill` replaces,
        `type` appends. Swapping them is how a field meant to hold `bar` ends up
        holding `foobar`.
        Útextrf   ç        N)rÌ   ræ   Ú	type_textr  ri   r  r?   s     r:   r¹   zElementHandleDispatcher.op_typea  s]   € ð 	%ˆŒ
ÔÔ$¥W¨f°V¬nð 	?ð 	?Ý+5°fÑ+=Ô+=Ð+DÀð	?à'+§~¢~°fÑ'=Ô'=ð	?ð 	?ð 	?ð ˆtr;   c                ó’   —  | j         j        j        t          |d         fdt	          |¦  «        i|                      |¦  «        ¤Ž d S )NÚkeyÚdwell_ms)rÌ   ræ   rÂ   r  ri   r  r?   s     r:   rº   z ElementHandleDispatcher.op_pressm  sV   € Ø ˆŒ
ÔÔ ¥¨&°¬-ð 	;ð 	;Ý*4°VÑ*<Ô*<ð	;à#'§>¢>°&Ñ#9Ô#9ð	;ð 	;ð 	;ð ˆtr;   c                óf   —  | j         j        j        t          fi |                      |¦  «        ¤Ž d S r1   )rÌ   ræ   rÃ   r  r  r?   s     r:   r»   z ElementHandleDispatcher.op_focuss  s3   € Ø ˆŒ
ÔÔ ¥ÐCÐC¨D¯NªN¸6Ñ,BÔ,BÐCÐCÐCØˆtr;   c                ó�   —  | j         j        j        d |                     d¦  «        pg fi |                      |¦  «        ¤Ž}d|pg iS )NÚoptionsÚvalues)rÌ   ræ   Úselect_optionrg   r  )r5   r<   Úchosens      r:   r¾   z(ElementHandleDispatcher.op_select_optionw  s]   € Ø1�”Ô#Ô1Ø�&—*’*˜YÑ'Ô'Ð-¨2ðIð IØ15·²ÀÑ1GÔ1GðIð Iˆà˜&˜, BÐ'Ð'r;   c                óŽ   —  | j         j        j        t          t	          | j        |¦  «        fi |                      |¦  «        ¤Ž dS )uM  â›” THE DOOR `FileChooser.set_files()` COMES THROUGH, and it was shut.

        A chooser already holds the input element, so the client never sends a
        selector: it asks this dispatcher for `setInputFiles`, and until now
        there was no such method here. The refusal was honest - the dispatcher
        said the operation is inside the perimeter and therefore a gap - but a
        gap it was, and the whole listening half of the file-chooser feature
        led to it.

        Same action as the Frame's, same helper reading the request: one
        upload, not two.
        N)rÌ   ræ   Úset_input_filesr  r”   r6   r  r?   s     r:   r¿   z*ElementHandleDispatcher.op_set_input_files|  sQ   € ð 	+ˆŒ
ÔÔ*Ý•] 4¤;°Ñ7Ô7ð	&ð 	&à�nŠn˜VÑ$Ô$ð	&ð 	&ð 	&ð ˆtr;   ©rÈ   )
rÌ   rÍ   rÎ   rM   rÏ   rM   rË   rM   r.   r/   ©r.   rÒ   )r.   rÙ   rA   ©r<   r   r.   r   )$rB   rC   rD   rF   rG   r4   ÚpropertyrÖ   rÕ   r-   r™   r›   r�   rŸ   r¡   r£   r¥   r§   r¯   r±   r³   r©   r«   r­   r  rµ   r·   r¼   r½   r¸   r¹   rº   r»   r¾   r¿   rH   rI   s   @r:   r–   r–   *  s²  ø€ € € € € Ø€DðØ�<ðàÐ(ðð 	Ð/ðð 	˜mð	ð
 	Ð(ðð 	�_ðð 	�_ðð 	Ð&ðð 	Ð*ðð 	!Ð"7ðð 	Ð&ðð 	Ð*ðð 	Ð(ðð 	Ð1ðð 	�_ðð& 	�ð'ð( 	�ð)ð* ØØØØØØ*Ø-ð9ð ð €Gð@ !#ðBØ4=ðBð Bð Bð Bð Bð Bð Bð Bð> ð"ð "ð "ñ „Xð"ð ðð ð ñ „Xðð	ð 	ð 	ð 	ð2ð 2ð 2ð 2ð?ð ?ð ?ð ?ð,ð ,ð ,ð ,ð82ð 2ð 2ð 2ð2ð 2ð 2ð 2ð2ð 2ð 2ð 2ð2ð 2ð 2ð 2ðBð Bð Bð Bð*ð *ð *ð *ð#ð #ð #ð #ð$,ð ,ð ,ð ,ð$ð ð ð ð>-ð -ð -ð -ð(ð (ð (ð (ðZ
0ð 
0ð 
0ð 
0ðð ð ð ðð ð ð ð
ð ð ð ð
ð ð ð ð
ð ð ð ð
ð 
ð 
ð 
ðð ð ð ðð ð ð ð(ð (ð (ð (ð
ð ð ð ð ð ð ð r;   r–   c                  ó–  ‡ — e Zd ZdZi dd“dd“dd“dd	“d
d“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“d d!“d"d#“i d$d%“d&d'“d(d)“d*d+“d,d-“d.d/“d0d1“d2d3“d4d5“d6d7“d8d9“d:d;“d<d=“d>d?“d@dA“dBdC“dDdE“¥i dFdG“dHdI“dJdK“dLdM“dNdO“dPdQ“dRdS“dTdU“dVdW“dXdY“dZd[“d\d]“d^d_“d`da“dbdc“ddde“dfdg“¥Z	 	 	 dÂdÃˆ fdw„ZedÄdy„¦   «         ZedÅd{„¦   «         ZedÆd}„¦   «         Z	dÇd�„Z
dÇd‚„ZdÇdƒ„ZdÇd„„ZdÈd…„ZdÇd†„ZdÇd‡„ZdÇdˆ„ZdÇd‰„ZdÇdŠ„ZdÉdŒ„ZdÇd�„ZdÇdŽ„ZdÇd�„ZdÇd�„ZdÇd‘„ZdÇd’„ZdÇd“„Zd”ZdÊd–„ZdËd˜„ZdÌd™„ZdÌdš„Z dÈd›„Z!dÇdœ„Z"dÇd�„Z#dÇdž„Z$dÇdŸ„Z%dÇd „Z&dÇd¡„Z'dÇd¢„Z(dÇd£„Z)dÇd¤„Z*dÇd¥„Z+dÇd¦„Z,dÇd§„Z-dÇd¨„Z.dÇd©„Z/dÇdª„Z0dÇd«„Z1dÇd¬„Z2dÇd­„Z3dÇd®„Z4dÇd¯„Z5dÇd°„Z6dÇd±„Z7dÇd²„Z8dÇd³„Z9dÇd´„Z:dÇdµ„Z;dÇd¶„Z<dÇd·„Z=dÍd¹„Z>dÇdº„Z?dÇd»„Z@dÇd¼„ZAdÇd½„ZBdÇd¾„ZCdÇd¿„ZDdÇdÀ„ZEdÇdÁ„ZFˆ xZGS )ÎÚFrameDispatcherÚFrameÚgotoÚop_gotoÚquerySelectorÚop_query_selectorr´   rµ   rÀ   r¸   ÚtitleÚop_titleÚcontentÚ
op_contentrž   rŸ   r    r¡   r¢   r£   r¤   r¥   r¦   r§   Ú	isVisibleÚop_is_visibleÚisHiddenÚop_is_hiddenÚ	isEnabledÚop_is_enabledÚ
isDisabledÚop_is_disabledÚ	isCheckedÚop_is_checkedÚ
isEditableÚop_is_editabler¶   r·   ÚdblclickÚop_dblclickrÄ   r¼   rÅ   r½   rÃ   r»   ÚblurÚop_blurÚ
selectTextÚop_select_textrÂ   rº   rÁ   r¹   rœ   r�   ÚevaluateExpressionHandleÚop_evaluate_handleÚquerySelectorAllÚop_query_selector_allÚ
queryCountÚop_query_countÚwaitForSelectorÚop_wait_for_selectorÚwaitForFunctionÚop_wait_for_functionÚwaitForTimeoutÚop_wait_for_timeoutÚ
setContentÚop_set_contentÚevalOnSelectorÚop_eval_on_selectorÚevalOnSelectorAllÚop_eval_on_selector_allrÆ   r¾   rÇ   r¿   ÚtapÚop_tapÚdispatchEventÚop_dispatch_eventÚdragAndDropÚop_drag_and_dropÚframeElementÚop_frame_elementÚexpectÚ	op_expectÚresolveSelectorÚop_resolve_selectorÚariaSnapshotÚop_aria_snapshotÚdropÚop_dropÚregisterSelectorEngineÚop_register_selector_engineÚwaitForElementStateÚop_wait_for_element_stateÚsetTestIdAttributeNameÚop_set_test_idÚaddScriptTagÚop_add_script_tagÚaddStyleTagÚop_add_style_tagúabout:blankrÈ   NrÕ   rÙ   rÜ   rM   Úurlr{   Úload_statesúOptional[List[str]]Úparent_frameúOptional['FrameDispatcher']r.   r/   c           	     óÈ   •— || _         || _        || _        || _        || _        t          ¦   «                              ||r|n|j        |||r|j        nd |pdgdœ¦  «         d S )NÚcommit)r  r{   ÚparentFrameÚ
loadStates)	rÕ   rÜ   r‚  r  r{   r3   r4   Úcontextrú   )	r5   r6   rÕ   rÜ   r  r{   r€  r‚  r9   s	           €r:   r4   zFrameDispatcher.__init__Æ  s“   ø€ ð ˆŒ	Ø ˆŒØ(ˆÔð
 ˆŒð ˆŒ	Ý‰Œ×Ò˜¨Ð!G  ¸4¼<Ø!$¨dØAMÐ)W¨Ô)=Ð)=ÐSWØ(3Ð(A¸°zðCð Cñ	Dô 	Dð 	Dð 	Dð 	Dr;   ú	'Actions'c                ó   — | j         j        S r1   )rÕ   ræ   r×   s    r:   ræ   zFrameDispatcher.actionsã  s   € àŒyÔ Ð r;   rÒ   c                ó   — | j         j        S r1   rÔ   r×   s    r:   rÖ   zFrameDispatcher.injectedç  rØ   r;   ú'Lifecycle'c                ó   — | j         j        S r1   )rÕ   Ú	lifecycler×   s    r:   rŽ  zFrameDispatcher.lifecycleë  s   € àŒyÔ"Ð"r;   r<   r   r   c                óò   — | j                              |d         | j        |                     d¦  «        pd|                     d¦  «        pddz  ¬¦  «        }d| j                             |d	         ¦  «        iS )
Nr  Ú	waitUntilÚloadr  é0u  rm   )rÜ   Úuntilr  ÚresponseÚnavigationId)rŽ  r8  rÜ   rg   rÕ   Únavigation_response©r5   r<   r  s      r:   r9  zFrameDispatcher.op_gotoñ  s�   € Ø”×$Ò$Ø�5ŒM D¤MØ—*’*˜[Ñ)Ô)Ð3¨VØ—Z’Z 	Ñ*Ô*Ð3¨e°vÑ=ð %ñ ?ô ?ˆð ˜DœI×9Ò9Ø�>Ô"ñ$ô $ð %ð 	%r;   c                óD   — d| j                              | j        ¦  «        iS rÞ   )rÖ   r<  rÜ   r?   s     r:   r=  zFrameDispatcher.op_title  s   € Ø˜œ×,Ò,¨T¬]Ñ;Ô;Ð<Ð<r;   c                óD   — d| j                              | j        ¦  «        iS rÞ   )rÖ   r>  rÜ   r?   s     r:   r?  zFrameDispatcher.op_content  s   € Ø˜œ×.Ò.¨t¬}Ñ=Ô=Ð>Ð>r;   c                óî   — |                       |d         ¦  «        \  }}| j                             ||¦  «        }|sdd iS t          | j        | j                             |¦  «        |¦  «        }d|j        iS )NÚselectorÚelement)Úenter_framesrÖ   Úquery_selectorr–   r6   rÕ   r  rú   )r5   r<   rÜ   r›  rÎ   rù   s         r:   r;  z!FrameDispatcher.op_query_selector  s€   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø”M×0Ò0°¸8ÑDÔDˆ	Øð 	%Ø˜tÐ$Ð$Ý(ØŒK˜œ×,Ò,¨XÑ6Ô6¸	ñCô Cˆà˜6œ>Ð*Ð*r;   c                ó0  — |                       |d         ¦  «        \  }}| j                             ||¦  «        }|st          d|z  ¦  «        ‚	 d |||¦  «        i| j                             ||¦  «         S # | j                             ||¦  «         w xY w)Nr›  zno element matches %rr|   )r�  rÖ   rž  r   r,   )r5   r<   ÚreadrÜ   r›  rÎ   s         r:   Ú_with_elementzFrameDispatcher._with_element  s¥   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø”M×0Ò0°¸8ÑDÔDˆ	Øð 	HÝ#Ð$;¸hÑ$FÑGÔGÐGð	7Ø˜T˜T (¨IÑ6Ô6Ð7àŒM×!Ò! (¨IÑ6Ô6Ð6Ð6øˆDŒM×!Ò! (¨IÑ6Ô6Ð6Ð6øøøs   ÁA8 Á8Bc                óB   — |                       || j        j        ¦  «        S r1   )r¡  rÖ   rë   r?   s     r:   rŸ   zFrameDispatcher.op_text_content  s   € Ø×!Ò! &¨$¬-Ô*DÑEÔEÐEr;   c                óB   — |                       || j        j        ¦  «        S r1   )r¡  rÖ   rí   r?   s     r:   r¡   zFrameDispatcher.op_inner_text!  ó   € Ø×!Ò! &¨$¬-Ô*BÑCÔCÐCr;   c                óB   — |                       || j        j        ¦  «        S r1   )r¡  rÖ   rð   r?   s     r:   r£   zFrameDispatcher.op_inner_html$  r¤  r;   c                óB   — |                       || j        j        ¦  «        S r1   )r¡  rÖ   rò   r?   s     r:   r¥   zFrameDispatcher.op_input_value'  s   € Ø×!Ò! &¨$¬-Ô*CÑDÔDÐDr;   c                ó:   ‡ ‡— ‰                       ‰ˆˆ fd„¦  «        S )Nc                óH   •— ‰j                              | |‰d         ¦  «        S )Nr{   )rÖ   rô   ©ÚfÚor<   r5   s     €€r:   ú<lambda>z2FrameDispatcher.op_get_attribute.<locals>.<lambda>+  s(   ø€ °t´}ß#0¢=°°AØ17¸´ñ$Aô $Að r;   ©r¡  r?   s   ``r:   r§   z FrameDispatcher.op_get_attribute*  s?   øø€ Ø×!Ò! &ð +Að +Að +Að +Að +Añ Bô Bð 	Br;   Ústatec                ó:   ‡ ‡— ‰                       |ˆ ˆfd„¦  «        S )Nc                ó<   •— ‰j                              | |‰¦  «        S r1   )rÖ   Úelement_state)rª  r«  r5   r®  s     €€r:   r¬  z(FrameDispatcher._state.<locals>.<lambda>0  s   ø€ °t´}ß#0¢=°°A°uÑ#=Ô#=ð r;   r­  )r5   r<   r®  s   ` `r:   Ú_statezFrameDispatcher._state/  s7   øø€ Ø×!Ò! &ð +>ð +>ð +>ð +>ð +>ñ ?ô ?ð 	?r;   c                ó.   — |                       |d¦  «        S )NÚvisible©r²  r?   s     r:   rA  zFrameDispatcher.op_is_visible3  ó   € Ø�{Š{˜6 9Ñ-Ô-Ð-r;   c                ó.   — |                       |d¦  «        S )NÚhiddenrµ  r?   s     r:   rC  zFrameDispatcher.op_is_hidden6  s   € Ø�{Š{˜6 8Ñ,Ô,Ð,r;   c                ó.   — |                       |d¦  «        S )NÚenabledrµ  r?   s     r:   rE  zFrameDispatcher.op_is_enabled9  r¶  r;   c                ó.   — |                       |d¦  «        S )NÚdisabledrµ  r?   s     r:   rG  zFrameDispatcher.op_is_disabled<  ó   € Ø�{Š{˜6 :Ñ.Ô.Ð.r;   c                ó.   — |                       |d¦  «        S )NÚcheckedrµ  r?   s     r:   rI  zFrameDispatcher.op_is_checked?  r¶  r;   c                ó.   — |                       |d¦  «        S )NÚeditablerµ  r?   s     r:   rK  zFrameDispatcher.op_is_editableB  r½  r;   c           	     óz   — dt          | j                             | j        t	          |¦  «        ¦  «        ¦  «        iS )uI  â›” THE PAGE'S OWN WORLD, not the utility one, and the distinction
        is the semantics of the API rather than a preference.

        `page.evaluate()` is the user asking to run code AS THE PAGE: it must
        see the page's globals, the page's prototypes, and whatever the site
        has monkey-patched. The utility world sees the same DOM through an
        Xray, so those are exactly what it does NOT see.

        The first draft ran it in utility and it was caught by the opposite
        assertion to the one you would expect: a test checking that the PAGE
        cannot see a closed shadow root found that it could - because the code
        asking was not running as the page at all.

        Everything else in this file stays in utility on purpose. This one
        method leaves, because the caller asked for it.
        r|   )r   rÖ   Úevaluate_in_mainrÜ   r    r?   s     r:   r�   zFrameDispatcher.op_evaluateE  s@   € ð" � D¤M×$BÒ$BØŒM�>¨&Ñ1Ô1ñ%3ô %3ñ 4ô 4ð 5ð 	5r;   z$ >> internal:control=enter-frame >> r›  c                óF  — | }	 |                      | j        ¦  «        \  }}}|s	|j        |fS |j        j                             |j        |¦  «        }|st          d|z  ¦  «        ‚	 |j                             d|j        |dœ¦  «        pi }|j        j                             |j        |¦  «         n*# |j        j                             |j        |¦  «         w xY w| 	                    d¦  «        }|st          d|z  ¦  «        ‚|j         
                    |¦  «        }|}�Œ)uˆ  `(frame_id, tail)` for a selector that crosses into an iframe.

        â›” THE HOP IS SERVER-SIDE, and that is not an implementation detail:
        the injected script lives in ONE document and cannot reach inside an
        iframe's - that is the same-origin boundary, not a missing feature. So
        `#outer >> internal:control=enter-frame >> #inner` is resolved here by
        finding `#outer`, asking the engine which frame it CONTAINS, and
        starting again in that frame.

        â›” AND IT RECURSES, because frames nest. Handling one level looks
        right on every page that has a single iframe and is wrong on the ones
        that matter - the geometry test in this suite uses two.

        The judge found this as three failures out of seven: they were the only
        ones left after child frames started being announced, and they are all
        the same missing hop.
        Tz@the frame owner %r matched nothing, so there is nothing to enterr	  r
  r  z9%r is not a frame owner: it has no content frame to enter)Ú	partitionÚENTER_FRAMErÜ   rÕ   rÖ   rž  r   r  r,   rg   r  )	r5   r›  rÌ   ÚheadÚ_ÚtailÚownerÚ	describedÚinners	            r:   r�  zFrameDispatcher.enter_frames]  sZ  € ð$ ˆð	Ø$×.Ò.¨tÔ/?Ñ@Ô@‰MˆD�!�TØð ,Ø”~ tÐ+Ð+Ø”JÔ'×6Ò6°u´~ÀtÑLÔLˆEØð 'Ý'ðØ!%ñ&ñ'ô 'ð 'ðCØ!œJŸOšOØ'Ø %¤¸EÐBÐBñDô Dð JàGIð ð ”
Ô#×+Ò+¨E¬N¸EÑBÔBÐBÐBø�”
Ô#×+Ò+¨E¬N¸EÑBÔBÐBÐBøøøØ—M’MÐ"2Ñ3Ô3ˆEØð $Ý'ðØ"ñ#ñ$ô $ð $ð ”J×(Ò(¨Ñ/Ô/ˆEØˆHñ+	s   Á'%B2 Â2'Crh   c                ó6   — |                      d¦  «        pddz  S )Nr  r’  rm   ©rg   r?   s     r:   r  zFrameDispatcher._timeout‡  s   € Ø—
’
˜9Ñ%Ô%Ð.¨°&Ñ8Ð8r;   c                ó&  — |                      d¦  «        pg }d}|D ]}|t          j         |d¦  «        z  }Œt          |                      d¦  «        ¦  «        |t          |                      d¦  «        pd¦  «        |                      d¦  «        dœS )u}  `button`, `modifiers` and `clickCount`, read in ONE place.

        â›” THEY WERE NEVER READ AT ALL, and the operations looked complete
        because the click happened. `page.click(button="right")` produced a
        LEFT click - no `contextmenu` event, no error - and
        `modifiers=["Shift"]` produced a click whose `event.shiftKey` was
        false. Both are documented options of the API this package promises to
        answer, and both were dropped between the wire and the engine.

        â›” AND THE FIELD-COVERAGE GATE COULD NOT SEE IT, which is worth
        writing down rather than hiding: that gate compares what a CAPTURED
        session sent against what the code reads, and the captured session
        clicks once, with the left button and no modifier. A field nobody
        exercised is a field it cannot report. It was the e2e - the slowest and
        least clever instrument here - that caught this.

        â›” The masks are Firefox's, not Gecko's, and right and middle are
        swapped in the `buttons` encoding: both tables live in `keyboard.py`
        and are read from there rather than re-derived.
        Ú	modifiersr   ÚbuttonÚ
clickCountr   rf   )rÑ  rÐ  ÚclicksÚdelay_ms)rg   r   r   rr   )r5   r<   rÿ   Úmaskr{   s        r:   r  zFrameDispatcher._pointerŠ  sŸ   € ð* —
’
˜;Ñ'Ô'Ð-¨2ˆØˆØð 	/ð 	/ˆDØ•MÔ% d¨AÑ.Ô.Ñ.ˆDˆDå˜fŸjšj¨Ñ2Ô2Ñ3Ô3ð
 Ý˜&Ÿ*š* \Ñ2Ô2Ð7°aÑ8Ô8ð Ÿ
š
 7Ñ+Ô+ð
ð 
ð 	
r;   c                óÎ   — t          |                     d¦  «        ¦  «        t          |                     d¦  «        ¦  «        t          |                     d¦  «        ¦  «        dœS )u#  Every per-action option the wire carries, read in ONE place.

        â›” ONE PLACE KNOWS THE NAMES OF THESE PARAMETERS, and that is the point
        of a helper this small. `trial` reaches seven operations, and seven
        copies of `params.get("trial")` is how the eighth gets written without
        one - which is exactly how it came to be accepted on 31 public
        signatures and read by nobody, so `click(trial=True)` clicked.

        â›” AND THAT SHAPE IS WHY THIS READS THREE OPTIONS RATHER THAN ONE.
        The helper used to answer only `trial`, so `strict` and `force` had to
        be wired option by option, action by action - and they never were: both
        were accepted by the public API and read by nobody. `strict` is the
        expensive one. Every Locator method sends `strict=True` (28 call sites
        in `_locator.py`), so `page.locator("button").click()` on a page with
        two buttons clicked the FIRST one instead of refusing - the automation
        acting on an element nobody chose, with nothing said. Reading them
        together means the ninth action cannot be written with one and without
        the others.

        What they MEAN lives in `Actions._retry`, the only thing that knows
        what actionable is. This just carries them across the wire.
        ÚtrialÚstrictÚforce)r×  rØ  rÙ  )Úboolrg   r?   s     r:   r  zFrameDispatcher._act_opts³  sX   € õ. ˜fŸjšj¨Ñ1Ô1Ñ2Ô2Ý˜vŸzšz¨(Ñ3Ô3Ñ4Ô4Ý˜fŸjšj¨Ñ1Ô1Ñ2Ô2ð4ð 4ð 	4r;   c                ón   — |                      d¦  «        }t          |t          ¦  «        r
d|v rd|v r|S dS )uD  The caller's offset inside the element, or None.

        â›” ONE PLACE READS IT. Six pointer operations take it, and six copies
        of `params.get("position")` is exactly the shape that lets the seventh
        be written without it - which is how this option came to be dropped by
        all of them at once.
        r  rã   rä   N)rg   r‹   rn   )r5   r<   r  s      r:   r  zFrameDispatcher._positionÎ  sA   € ð —:’:˜jÑ)Ô)ˆÝ�h¥Ñ%Ô%ð 	¨#°¨/¨/¸cÀX¸o¸oØˆOØˆtr;   c                ó  — |                       |d         ¦  «        \  }} | j        j        |f|                      |¦  «        |dœ|                      |¦  «        ¤d|                      |¦  «        i¤|                      |¦  «        ¤Ž d S ©Nr›  ©r  rÜ   r  )r�  ræ   r´   r  r  r  r  ©r5   r<   rÜ   r›  s       r:   rµ   zFrameDispatcher.op_clickÛ  s¤   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØˆŒÔ˜8ð 	9¨T¯]ª]¸6Ñ-BÔ-BØ)1ð	9ð 	9Ø59·^²^ÀFÑ5KÔ5Kð	9ð 	9à)-¯ª¸Ñ)?Ô)?ð	9ð 	9ð #'§-¢-°Ñ"7Ô"7ð	9ð 	9ð 	9ð ˆtr;   c                óB  — |                       |d         ¦  «        \  }}|                      |¦  «        }|                     dd ¦  «          | j        j        |f|                      |¦  «        |dœ|                      |¦  «        ¤d|                      |¦  «        i¤|¤Ž d S )Nr›  rÓ  rÞ  r  )r�  r  ro   ræ   rL  r  r  r  )r5   r<   rÜ   r›  Úpointers        r:   rM  zFrameDispatcher.op_dblclickã  sÅ   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø—-’- Ñ'Ô'ˆà�Š�H˜dÑ#Ô#Ð#ØˆŒÔ˜hð 	O°·²¸fÑ0EÔ0EØ,4ð	Oð 	OØ8<¿ºÀvÑ8NÔ8Nð	Oð 	Oà,0¯NªN¸6Ñ,BÔ,Bð	Oð 	OàFMð	Oð 	Oð 	Oð ˆtr;   c                óè   — |                       |d         ¦  «        \  }} | j        j        |f|                      |¦  «        |dœ|                      |¦  «        ¤d|                      |¦  «        i¤Ž d S rÝ  )r�  ræ   r¶   r  r  r  rß  s       r:   r·   zFrameDispatcher.op_hoverí  ó—   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØˆŒÔ˜8ð 	A¨T¯]ª]¸6Ñ-BÔ-BØ)1ð	Að 	AØ59·^²^ÀFÑ5KÔ5Kð	Að 	Aà)-¯ª¸Ñ)?Ô)?ð	Að 	Að 	Að 	Að ˆtr;   c                óÈ   — |                       |d         ¦  «        \  }} | j        j        ||d         f|                      |¦  «        |dœ|                      |¦  «        ¤Ž d S )Nr›  r|   rÞ  )r�  ræ   rÀ   r  r  rß  s       r:   r¸   zFrameDispatcher.op_fillô  sv   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØˆŒÔ˜( F¨7¤Oð 	9Ø'+§}¢}°VÑ'<Ô'<Àxð	9ð 	9à!%§¢°Ñ!7Ô!7ð	9ð 	9ð 	9ð ˆtr;   c                óè   — |                       |d         ¦  «        \  }} | j        j        |f|                      |¦  «        |dœ|                      |¦  «        ¤d|                      |¦  «        i¤Ž d S rÝ  )r�  ræ   rÄ   r  r  r  rß  s       r:   r¼   zFrameDispatcher.op_checkû  rã  r;   c                óè   — |                       |d         ¦  «        \  }} | j        j        |f|                      |¦  «        |dœ|                      |¦  «        ¤d|                      |¦  «        i¤Ž d S rÝ  )r�  ræ   rÅ   r  r  r  rß  s       r:   r½   zFrameDispatcher.op_uncheck  s—   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØˆŒÔ˜Xð 	C¨t¯}ª}¸VÑ/DÔ/DØ+3ð	Cð 	CØ7;·~²~ÀfÑ7MÔ7Mð	Cð 	Cà+/¯>ª>¸&Ñ+AÔ+Að	Cð 	Cð 	Cð 	Cð ˆtr;   c                óº   — |                       |d         ¦  «        \  }} | j        j        |f|                      |¦  «        |dœ|                      |¦  «        ¤Ž d S ©Nr›  rÞ  )r�  ræ   rÃ   r  r  rß  s       r:   r»   zFrameDispatcher.op_focus	  sp   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØˆŒÔ˜8ð 	:Ø(,¯ª°fÑ(=Ô(=Èð	:ð 	:à"&§.¢.°Ñ"8Ô"8ð	:ð 	:ð 	:ð ˆtr;   c                óº   — |                       |d         ¦  «        \  }} | j        j        |f|                      |¦  «        |dœ|                      |¦  «        ¤Ž d S rè  )r�  ræ   rN  r  r  rß  s       r:   rO  zFrameDispatcher.op_blur  sp   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØˆŒÔ˜(ð 	9Ø'+§}¢}°VÑ'<Ô'<Àxð	9ð 	9à!%§¢°Ñ!7Ô!7ð	9ð 	9ð 	9ð ˆtr;   c                óº   — |                       |d         ¦  «        \  }} | j        j        |f|                      |¦  «        |dœ|                      |¦  «        ¤Ž d S rè  )r�  ræ   Úselect_textr  r  rß  s       r:   rQ  zFrameDispatcher.op_select_text  sv   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø ˆŒÔ  ð 	@Ø.2¯mªm¸FÑ.CÔ.CÈhð	@ð 	@à(,¯ª°vÑ(>Ô(>ð	@ð 	@ð 	@ð ˆtr;   c                óä   — |                       |d         ¦  «        \  }} | j        j        ||d         f|                      |¦  «        |t	          |¦  «        dœ|                      |¦  «        ¤Ž d S )Nr›  r'  )r  rÜ   r(  )r�  ræ   rÂ   r  ri   r  rß  s       r:   rº   zFrameDispatcher.op_press  sƒ   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØˆŒÔ˜8 V¨E¤]ð 	:Ø(,¯ª°fÑ(=Ô(=ÈÝ)3°FÑ);Ô);ð	:ð 	:ð #'§.¢.°Ñ"8Ô"8ð	:ð 	:ð 	:ð ˆtr;   c                óè   — |                       |d         ¦  «        \  }} | j        j        ||d         f|                      |¦  «        |t	          |¦  «        pddœ|                      |¦  «        ¤Ž d S )Nr›  r#  r$  )r  rÜ   rf   )r�  ræ   r%  r  ri   r  rß  s       r:   r¹   zFrameDispatcher.op_type&  sˆ   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØˆŒÔ˜x¨°¬ð 	>Ø,0¯MªM¸&Ñ,AÔ,AÈHÝ*4°VÑ*<Ô*<Ð*CÀð	>ð 	>ð '+§n¢n°VÑ&<Ô&<ð	>ð 	>ð 	>ð ˆtr;   c                óî   — |                       |d         ¦  «        \  }} | j        j        ||                     d¦  «        pg f||                      |¦  «        dœ|                      |¦  «        ¤Ž}d|pg iS )Nr›  r+  )rÜ   r  r,  )r�  ræ   r-  rg   r  r  )r5   r<   rÜ   r›  r.  s        r:   r¾   z FrameDispatcher.op_select_option.  s“   € ð
 "×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø+�”Ô+Ø�f—j’j Ñ+Ô+Ð1¨rðEØ<DØ—M’M &Ñ)Ô)ðEð Eà-1¯^ª^¸FÑ-CÔ-CðEð Eˆð ˜&˜, BÐ'Ð'r;   c                óâ   — |                       |d         ¦  «        \  }} | j        j        |t          | j        |¦  «        f|                      |¦  «        |dœ|                      |¦  «        ¤Ž d S rè  )r�  ræ   r0  r”   r6   r  r  rß  s       r:   r¿   z"FrameDispatcher.op_set_input_files9  s‚   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø$ˆŒÔ$ XÝ%2°4´;ÀÑ%GÔ%Gð	?à-1¯]ª]¸6Ñ-BÔ-BØ.6ð	?ð 	?ð (,§~¢~°fÑ'=Ô'=ð		?ð 	?ð 	?ð
 ˆtr;   c                óè   — |                       |d         ¦  «        \  }} | j        j        |f|                      |¦  «        |dœ|                      |¦  «        ¤d|                      |¦  «        i¤Ž d S rÝ  )r�  ræ   rd  r  r  r  rß  s       r:   re  zFrameDispatcher.op_tapB  sŽ   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØˆŒÔ˜ð 	?¨4¯=ª=¸Ñ+@Ô+@Ø'/ð	?ð 	?Ø37·>²>À&Ñ3IÔ3Ið	?ð 	?à'+§~¢~°fÑ'=Ô'=ð	?ð 	?ð 	?ð 	?ð ˆtr;   c           	     ó  — |                       |d         ¦  «        \  }} | j        j        ||d         t          |                     d¦  «        ¦  «        pi f|                      |¦  «        |dœ|                      |¦  «        ¤Ž d S )Nr›  rÁ   Ú	eventInitrÞ  )r�  ræ   Údispatch_eventr   rg   r  r  rß  s       r:   rg  z!FrameDispatcher.op_dispatch_eventI  s™   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ð 	$ˆŒÔ#Ø�f˜V”nÝ˜Ÿš KÑ0Ô0Ñ1Ô1Ð7°Rð	&ð —M’M &Ñ)Ô)°Hð	&ð 	&ð �nŠn˜VÑ$Ô$ð		&ð 	&ð 	&ð
 ˆtr;   c                ó–   —  | j         j        |d         |d         fd|                      |¦  «        i|                      |¦  «        ¤Ž d S )NÚsourceÚtargetr  )ræ   Údrag_and_dropr  r  r?   s     r:   ri  z FrameDispatcher.op_drag_and_dropY  sc   € Ø"ˆŒÔ" 6¨(Ô#3°V¸HÔ5Eð 	Bð 	BØ04·²¸fÑ0EÔ0Eð	Bà*.¯.ª.¸Ñ*@Ô*@ð	Bð 	Bð 	Bð ˆtr;   c                ó
  — | j                              | j        dt          |d         ¦  «        z  d¬¦  «         | j                             | j        |                     d¦  «        pd|                      |¦  «        ¬¦  «         dS )	up  â›” Goes through `document.open/write/close` in the MAIN world.

        The utility world has an EXTENDED principal, and Gecko requires
        `document.open()` to run under a principal EQUAL to the document's, so
        from there it answers `The operation is insecure` every single time -
        the same defect the fork already fixed inside the driver.
        zD(() => { document.open(); document.write(%s); document.close(); })()ÚhtmlTr÷   r�  r‘  ©r  N)rÖ   rÃ  rÜ   r   rŽ  Úwait_for_staterg   r  r?   s     r:   r_  zFrameDispatcher.op_set_content_  s‘   € ð 	Œ×&Ò&ØŒMØRÝ˜ œÑ(Ô(ñ)Ø37ð 	'ñ 	9ô 	9ð 	9ð 	Œ×%Ò%ØŒM˜6Ÿ:š: kÑ2Ô2Ð<°fØ—M’M &Ñ)Ô)ð 	&ñ 	+ô 	+ð 	+ð ˆtr;   c                ó^   — t          j        |                     d¦  «        pddz  ¦  «         d S )NÚwaitTimeoutr   rm   )ÚtimeÚsleeprg   r?   s     r:   r]  z#FrameDispatcher.op_wait_for_timeouts  s/   € õ  	Œ
�F—J’J˜}Ñ-Ô-Ð2°°fÑ<Ñ=Ô=Ð=Øˆtr;   c                óš   — | j                              | j        |                     d¦  «        pd|                      |¦  «        ¬¦  «         d S )Nr®  r‘  rú  )rŽ  rû  rÜ   rg   r  r?   s     r:   Úop_wait_for_load_statez&FrameDispatcher.op_wait_for_load_state†  sO   € ØŒ×%Ò%ØŒM˜6Ÿ:š: gÑ.Ô.Ð8°&Ø—M’M &Ñ)Ô)ð 	&ñ 	+ô 	+ð 	+ð ˆtr;   c           	     ó|  — |                       |d         ¦  «        \  }}|                     d¦  «        pd}| j                             |||                      |¦  «        ||                      |¦  «        d         ¬¦  «        }|€dd iS t          | j        | j         	                    |¦  «        |¦  «        }d|j
        iS )Nr›  r®  r´  rØ  )r®  r  rÜ   rØ  rœ  )r�  rg   ræ   Úwait_for_selectorr  r  r–   r6   rÕ   r  rú   )r5   r<   rÜ   r›  r®  rÎ   rù   s          r:   rY  z$FrameDispatcher.op_wait_for_selectorŒ  sÆ   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø—
’
˜7Ñ#Ô#Ð0 yˆØ”L×2Ò2Ø˜E¨4¯=ª=¸Ñ+@Ô+@Ø d§n¢n°VÑ&<Ô&<¸XÔ&Fð 3ñ Hô Hˆ	ð ÐØ˜tÐ$Ð$Ý(ØŒK˜œ×,Ò,¨XÑ6Ô6¸	ñCô Cˆà˜6œ>Ð*Ð*r;   c                óø  — t          j        ¦   «         |                      |¦  «        z   }t          |¦  «        }	 | j                             | j        |¦  «        }|rE| j                             | j        |d¬¦  «        }t          | j        | |pdd¬¦  «        }d|j	        iS t          j        ¦   «         |k    r/t          d|                      |¦  «        |d	d
…         fz  ¦  «        ‚t          j        d¦  «         ŒÂ)uÌ  Poll the CALLER'S expression until it is truthy.

        â›” IN THE PAGE'S OWN WORLD, and it used to poll in the utility one.
        `wait_for_function` has exactly the semantics of `evaluate`: it is the
        caller asking to run THEIR code as the page. From behind the Xray a
        page global does not exist, so an expression like
        `() => !!window.Fingerprint` is false forever and the call dies on its
        own timeout naming an expression that was true in the page all along.

        â›” Measured: five e2e tests - every one that waits for a real detector
        library to finish - failed on this transport and passed on the driver.
        Nothing else in the suite waits on a page global, which is why 181 of
        186 were green and the gap looked like a detector problem.

        â›” AND IT IS THE SECOND METHOD THAT LEAVES THE XRAY, on purpose and
        for the same reason as `op_evaluate`: everything else in this server
        stays in utility so a site cannot count our reads, and these two leave
        because the caller asked for the page's own world by name. The cost is
        real - a polled expression is repeated page-visible work - so the
        interval stays coarse.
        TFr÷   rÈ   r  rÊ   rù   z/the expression never became truthy in %.0fs: %sNéx   gš™™™™™©?)rþ  Ú	monotonicr  r    rÖ   rÃ  rÜ   r–   r6   rú   r   rÿ  )r5   r<   ÚdeadlineÚ
expressionr|   rÎ   rù   s          r:   r[  z$FrameDispatcher.op_wait_for_function˜  s  € õ, ”>Ñ#Ô# d§m¢m°FÑ&;Ô&;Ñ;ˆÝ# FÑ+Ô+ˆ
ð	Ø”M×2Ò2°4´=Ø8BñDô DˆEàð 
2ð !œM×:Ò:Ø”M :¸ð ;ñ ?ô ?�	å0Ø”K  y °B¸fðFñ Fô F�à  &¤.Ð1Ð1ÝŒ~ÑÔ (Ò*Ð*Ý'ØEØ—}’} VÑ,Ô,¨j¸¸#¸Ô.>Ð?ñ@ñAô Að Aõ ŒJ�tÑÔÐð%	r;   c                ó@  — |                      d¦  «        pd}|                      d¦  «        }	 |                     d¦  «        rZ| j                             | j        |¦  «        }t          |                      d¦  «        pd¦  «        }||k    t          |¦  «        dœS |                     d¦  «        r9|                     dd	¦  «        d	         }|                      d|id
„ ¦  «        oddiS n"# t          $ r dt          d¦  «        dœcY S w xY wt          d|z  ¦  «        ‚)u×   â›” The polling half of `expect()`. It answers ONE probe; the
        retrying is the client's, in `_assertions.py`, which is why this must
        not loop: looping here would multiply the caller's timeout by ours.r  rÈ   r›  zto.have.countÚexpectedNumberr   )ÚmatchesÚreceivedzto.be.r   c                ó   — d S r1   r[   )rª  r«  s     r:   r¬  z+FrameDispatcher.op_expect.<locals>.<lambda>Ô  s   €  € r;   r  TFNz!expect(%r) is not implemented yet)
rg   Ú
startswithrÖ   ÚcountrÜ   rr   r   Úsplitr¡  r   )r5   r<   r  r›  r  Úexpectedr®  s          r:   rm  zFrameDispatcher.op_expectÄ  s`  € ð —Z’Z Ñ-Ô-Ð3°ˆ
Ø—:’:˜jÑ)Ô)ˆð	DØ×$Ò$ _Ñ5Ô5ð 7Øœ×+Ò+¨D¬M¸8ÑDÔD�Ý §
¢
Ð+;Ñ <Ô <Ð AÀÑCÔC�Ø#(¨HÒ#4Ý$.¨uÑ$5Ô$5ð7ð 7ð 7à×$Ò$ XÑ.Ô.ð =Ø"×(Ò(¨°1Ñ5Ô5°aÔ8�Ø×)Ò)Ø Ð*Ø%Ð%ñ'ô 'ð =à,5°tÐ+<ð=ð=øõ
 !ð 	Dð 	Dð 	DØ$µ*¸TÑ2BÔ2BÐCÐCÐCÐCÐCð	DøøøåØ/°*Ñ<ñ>ô >ð 	>s   ®A.C, ÂAC, Ã,DÄ
Dc           	     óÜ   ‡ ‡— ‰                      d¦  «        }|r‰                      ‰ˆˆ fd„¦  «        S d‰ j                             ‰ j        dd‰                      d¦  «        pdi¦  «        iS )uÂ  The accessibility tree, as the injected script builds it.

        â›” It runs in the UTILITY world like every other read, which matters
        more here than elsewhere: an aria snapshot walks the WHOLE document and
        reads a role, a name and a description off every node. Done in the
        page's world that is thousands of accessor calls a site could count -
        the most expensive read in the API turned into the loudest one.
        r›  c           	     óp   •— ‰j                              | dd|id‰                     d¦  «        pdi¦  «        S )Nz1(injected, el, o) => injected.ariaSnapshot(el, o)ré   Úmoder“   )rÖ   rP   rg   r©  s     €€r:   r¬  z2FrameDispatcher.op_aria_snapshot.<locals>.<lambda>ç  s@   ø€ ˜Tœ]×/Ò/ØØGØ �O f¨f¯jªj¸Ñ.@Ô.@Ð.IÀEÐ%JñLô L€ r;   ÚsnapshotzC(injected, o) => injected.ariaSnapshot(document.documentElement, o)r  r“   )rg   r¡  rÖ   rP   rÜ   )r5   r<   r›  s   `` r:   rq  z FrameDispatcher.op_aria_snapshotÚ  s    øø€ ð —:’:˜jÑ)Ô)ˆØð 	MØ×%Ò%ØðLð Lð Lð Lð LñMô Mð Mð ˜DœM×.Ò.ØŒMØQØ�V—Z’Z Ñ'Ô'Ð0¨5Ð1ñ3ô 3ð 4ð 	4r;   c                ó    — t          d¦  «        ‚)uÛ  â›” REFUSED, and the reason is the protocol rather than the effort.

        `drop` carries an explicit DataTransfer payload - mime types and their
        values - and Juggler declares no command that can inject one:
        `dispatchDragEvent` exists INSIDE the content agent, reachable only
        from `Page.dispatchMouseEvent`, which synthesises the drag from real
        pointer movement and builds its own data.

        `drop()` with a payload therefore cannot be expressed. Faking it by
        dispatching an untrusted `drop` event from the injected script would
        produce `isTrusted: false` on a form that saw trusted events for
        everything else - which is the mixture [B175] exists about.

        â›” AND THIS USED TO SAY "so `drag_and_drop()` works, because that is a
        pointer gesture". It does not, and nothing checked: measured 2026-09-16,
        a drag onto a target that accepts the drop delivers no `dragenter`, no
        `dragover` and no `drop`, so the payload never arrives. The gesture
        moves the pointer correctly and transfers nothing. [B212] holds the
        measurement and where the cause is; the sentence is gone because a
        claim no gate can fail is how it survived.
        z×drop() with an explicit data payload has no engine command: Juggler builds the DataTransfer from a real pointer drag, so there is nothing to inject one into. Use drag_and_drop(), which is a pointer gesture and works©r   r?   s     r:   rs  zFrameDispatcher.op_dropð  s   € õ,  ð-ñ.ô .ð 	.r;   c                ó    — t          d¦  «        ‚)u]  â›” REFUSED for the same reason as `set_test_id_attribute`: the
        engines are handed to the injected script AT CONSTRUCTION, in
        `customEngines`, and the script is built once per frame. Registering
        one afterwards would need every live InjectedScript rebuilt, and a
        rebuild throws away every handle the caller is holding.zÇregister_selector_engine() cannot be honoured after a page exists: custom engines are baked into the injected script when it is built, and rebuilding it would invalidate every handle the caller holdsr  r?   s     r:   ru  z+FrameDispatcher.op_register_selector_engine  s   € õ  ðñô ð 	r;   c                ó    — |                       |                     d¦  «        pd¦  «        \  }}| j                             |¦  «        j        |dœS )z3The frame and selector a locator finally points at.r›  rÈ   )rÌ   r›  )r�  rg   rÕ   r  rú   rß  s       r:   ro  z#FrameDispatcher.op_resolve_selector  sL   € à!×.Ò.¨v¯zªz¸*Ñ/EÔ/EÐ/KÈÑLÔLÑˆ�(Øœ×,Ò,¨XÑ6Ô6Ô>ÈHÐUÐUÐUr;   c                ó°   — |                       |d         ¦  «        \  }}| j                             ||d         |                      |¦  «        |¬¦  «         d S )Nr›  r®  )r®  r  rÜ   )r�  ræ   r  r  rß  s       r:   rw  z)FrameDispatcher.op_wait_for_element_state  s_   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(ØŒ×&Ò&Ø˜F 7œOØ—M’M &Ñ)Ô)°Hð 	'ñ 	>ô 	>ð 	>ð ˆtr;   c                ó    — t          d¦  «        ‚)NzÇset_test_id_attribute() cannot be honoured after the injected script is built: the attribute name is baked into it at construction. Pass it when the page is created instead of changing it mid-sessionr  r?   s     r:   ry  zFrameDispatcher.op_set_test_id$  s   € Ýð&ñ'ô 'ð 	'r;   Útagc           
     óÞ  — |                      d¦  «        }|                      d¦  «        }|                      d¦  «        }|r(t          j        |¦  «                             d¬¦  «        }|€|€t	          d|z  ¦  «        ‚|dk    r*d	t          |                      d
¦  «        pd¦  «        z  }d}nd}d}|�d}|�*d|›d|›dt          |¦  «        ›dt          |¦  «        ›d�	}nd|›dt          |¦  «        ›d�}| j                             | j        |d¬¦  «        }	| j         	                    | j        |	¦  «        }
|
st	          d|z  ¦  «        ‚t          | j        | |
¦  «        }d|j        iS )u�  `add_script_tag` / `add_style_tag`.

        â›” THE MAIN WORLD, and that is the whole correctness of this method. A
        tag appended from the utility world would execute BEHIND THE XRAY: it
        would define nothing the page can see, which is the exact opposite of
        what these two functions promise. The utility world is right for
        everything we read and wrong for the one thing the caller wants the
        page itself to run.

        â›” AND A `url` HAS TO BE AWAITED. Appending a `<script src=...>` and
        returning immediately hands back a handle to a tag whose code has not
        run yet, so the very next `evaluate` does not see what it defines. The
        load is awaited here, and a failure to load RAISES rather than
        answering an element that does nothing.

        â›” IT LIVES ON THE FRAME BECAUSE THAT IS WHERE THE CLIENT SENDS IT.
        `page.add_script_tag` is `page.main_frame.add_script_tag`, so the call
        arrives on the Frame channel. Registered on the Page alone, every
        `add_script_tag` and `add_style_tag` - page or child frame - answered
        `Frame has no method 'addScriptTag'`.
        r  r>  Úpathúutf-8)ÚencodingNz,add_%s_tag needs one of url, path or contentÚscriptz:const el = document.createElement('script'); el.type = %s;rÁ   ztext/javascriptÚsrczAconst el = document.createElement('style'); el.type = 'text/css';ÚhrefzAconst el = document.createElement('link'); el.rel = 'stylesheet';z(async () => { z  el.z = zt;  const done = new Promise((ok, no) => {    el.onload = ok;    el.onerror = () => no(new Error('failed to load ' + zc));  });  (document.head || document.documentElement).appendChild(el);  await done; return el; })()z	(() => { z el.textContent = zP;  (document.head || document.documentElement).appendChild(el);  return el; })()Fr÷   z6add_%s_tag appended the tag but could not hand it backrœ  )rg   ÚpathlibÚPathÚ	read_textr   r   rÖ   rÃ  rÜ   Úadoptr–   r6   rú   )r5   r<   r  r  r>  r  ÚbuildÚ	attributeÚbodyrÎ   Úadoptedrù   s               r:   Ú_add_tagzFrameDispatcher._add_tag,  sÊ  € ð, �jŠj˜ÑÔˆØ—*’*˜YÑ'Ô'ˆØ�zŠz˜&Ñ!Ô!ˆØð 	EÝ”l 4Ñ(Ô(×2Ò2¸GÐ2ÑDÔDˆGØˆ;˜7˜?Ý#Ø>ÀÑDñFô Fð Fð �(Š?ˆ?ð&å! &§*¢*¨VÑ"4Ô"4Ð"IÐ8IÑJÔJñKˆEð ˆIˆIð3ˆEàˆIØˆð8�ð ˆ?ˆ?ð �5�5˜)˜)˜)¥Z°¡_¤_ _ _µjÀ±o´o°o°oðGð ˆDð ð (- u u­j¸Ñ.AÔ.AÐ.AÐ.AðCð ð
 ”M×2Ò2ØŒM˜4¨%ð 3ñ 1ô 1ˆ	ð ”-×%Ò% d¤m°YÑ?Ô?ˆØð 	PÝ#ØHÈ3ÑNñPô Pð På(¨¬°d¸GÑDÔDˆØ˜6œ>Ð*Ð*r;   c                ó.   — |                       |d¦  «        S )Nr!  ©r,  r?   s     r:   r{  z!FrameDispatcher.op_add_script_tagx  s   € Ø�}Š}˜V XÑ.Ô.Ð.r;   c                ó.   — |                       |d¦  «        S )NÚstyler.  r?   s     r:   r}  z FrameDispatcher.op_add_style_tag{  s   € Ø�}Š}˜V WÑ-Ô-Ð-r;   c                óÞ   — | j         }|€t          d¦  «        ‚| j                             | j        |j        ¬¦  «        }|st          d¦  «        ‚t          | j        ||¦  «        }d|j        iS )Nz(Frame has been detached or has no parent)ÚintozFrame has been detachedrœ  )r‚  r   rÖ   r'  rÜ   r–   r6   rú   )r5   r<   r7   rÎ   rù   s        r:   rk  z FrameDispatcher.op_frame_element  ss   € ØÔ"ˆØˆ>Ý#Ð$NÑOÔOÐOØ”M×'Ò'¨¬¸F¼OÐ'ÑLÔLˆ	Øð 	?Ý#Ð$=Ñ>Ô>Ð>Ý(¨¬°f¸iÑHÔHˆØ˜6œ>Ð*Ð*r;   c                óx   — |                       |d         ¦  «        \  }}d| j                             ||¦  «        iS )Nr›  r|   )r�  rÖ   r  rß  s       r:   rW  zFrameDispatcher.op_query_countŠ  s<   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø˜œ×,Ò,¨X°xÑ@Ô@ÐAÐAr;   c                óæ   ‡ ‡— ‰                       |d         ¦  «        \  }}‰ j                             |¦  «        Š‰ j                             ||¦  «        }ˆ ˆfd„|D ¦   «         }dd„ |D ¦   «         iS )Nr›  c                ó<   •— g | ]}t          ‰j        ‰|¦  «        ‘ŒS r[   )r–   r6   )r}   Úoidr5   rö  s     €€r:   r�   z9FrameDispatcher.op_query_selector_all.<locals>.<listcomp>’  s7   ø€ ð #ð #ð #Øõ +¨4¬;¸ÀÑDÔDð #ð #ð #r;   Úelementsc                ó   — g | ]	}|j         ‘Œ
S r[   ©rú   )r}   Úhs     r:   r�   z9FrameDispatcher.op_query_selector_all.<locals>.<listcomp>”  s   € Ð8Ð8Ð8¨1˜QœYÐ8Ð8Ð8r;   )r�  rÕ   r  rÖ   Úquery_selector_all)r5   r<   rÜ   r›  ÚidsÚhandlesrö  s   `     @r:   rU  z%FrameDispatcher.op_query_selector_allŽ  s”   øø€ Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø”×$Ò$ XÑ.Ô.ˆØŒm×.Ò.¨x¸ÑBÔBˆð#ð #ð #ð #ð #Ø!ð#ñ #ô #ˆàÐ8Ð8°Ð8Ñ8Ô8Ð9Ð9r;   c                ó:   ‡ ‡— ‰                       ‰ˆˆ fd„¦  «        S )Nc                ót   •— t          ‰j                             | t          ‰¦  «        d|i¦  «        ¦  «        S )Nré   )r   rÖ   rP   r   r©  s     €€r:   r¬  z5FrameDispatcher.op_eval_on_selector.<locals>.<lambda>™  s;   ø€ � D¤M×$6Ò$6ØÕ$ VÑ,Ô,¨z¸1¨oñ%?ô %?ñ @ô @€ r;   r­  r?   s   ``r:   ra  z#FrameDispatcher.op_eval_on_selector–  s@   øø€ Ø×!Ò!Øð@ð @ð @ð @ð @ñAô Að 	Ar;   c                óº   — |                       |d         ¦  «        \  }}| j                             |dt          |d¦  «        z  |¦  «        }dt	          |¦  «        iS )Nr›  zi(injected, sel) => { const els = injected.querySelectorAll(  injected.parseSelector(sel), document); %s }Úelsr|   )r�  rÖ   rP   r   r   )r5   r<   rÜ   r›  r|   s        r:   rc  z'FrameDispatcher.op_eval_on_selector_allœ  sj   € Ø!×.Ò.¨v°jÔ/AÑBÔBÑˆ�(Ø”×"Ò"Øð=å˜ Ñ'Ô'ñ(ð ñô ˆð � EÑ*Ô*Ð+Ð+r;   c                óž   — | j                              | j        t          |¦  «        d¬¦  «        }t	          | j        | |¦  «        }d|j        iS )NFr÷   rù   )rÖ   rÃ  rÜ   r    r–   r6   rú   rû   s       r:   rS  z"FrameDispatcher.op_evaluate_handle¦  sQ   € Ø”M×2Ò2ØŒM�>¨&Ñ1Ô1¸Eð 3ñ Cô Cˆ	å(¨¬°d¸IÑFÔFˆØ˜&œ.Ð)Ð)r;   )r~  rÈ   NN)rÕ   rÙ   rÜ   rM   r  rM   r{   rM   r€  r�  r‚  rƒ  r.   r/   )r.   r‰  r2  )r.   rŒ  rA   )r<   r   )r<   r   r®  rM   r.   r   )r›  rM   )r<   r   r.   rh   r3  )r<   r   r  rM   r.   r   )HrB   rC   rD   rF   rG   r4   r4  ræ   rÖ   rŽ  r9  r=  r?  r;  r¡  rŸ   r¡   r£   r¥   r§   r²  rA  rC  rE  rG  rI  rK  r�   rÆ  r�  r  r  r  r  rµ   rM  r·   r¸   r¼   r½   r»   rO  rQ  rº   r¹   r¾   r¿   re  rg  ri  r_  r]  r  rY  r[  rm  rq  rs  ru  ro  rw  ry  r,  r{  r}  rk  rW  rU  ra  rc  rS  rH   rI   s   @r:   r6  r6  Ž  sX  ø€ € € € € Ø€Dð4Ø�	ð4àÐ,ð4ð 	�ð4ð 	�	ð	4ð
 	�ð4ð 	�<ð4ð 	Ð(ð4ð 	�_ð4ð 	�_ð4ð 	Ð&ð4ð 	Ð*ð4ð 	�_ð4ð 	�Nð4ð 	�_ð4ð 	Ð&ð4ð  	�_ð!4ð" 	Ð&ð#4ð 4ð$ 	�ð%4ð& 	�Mð'4ð( 	�ð)4ð* 	�<ð+4ð, 	�ð-4ð. 	�	ð/4ð0 	Ð&ð14ð2 	�ð34ð4 	�	ð54ð6 	˜mð74ð8 	#Ð$8ð94ð: 	Ð3ð;4ð< 	Ð&ð=4ð> 	Ð1ð?4ð@ 	Ð1ðA4ðB 	Ð/ðC4ðD 	Ð&ðE4ð 4ð 4ðF 	Ð/ðG4ðH 	Ð6ðI4ðJ 	Ð*ðK4ðL 	Ð-ðM4ðN 	ˆxðO4ðP 	Ð,ðQ4ðR 	Ð)ðS4ðT 	Ð*ðU4ðV 	�+ðW4ðX 	Ð0ðY4ðZ 	Ð*ð[4ð\ 	�	ð]4ð^ 	!Ð"?ð_4ð` 	Ð:ða4ðb 	!Ð"2ðc4ðd 	Ð+ðe4ðf 	Ð)ðg4ð 4€Gðn 8:Ø48Ø=AðDð Dð Dð Dð Dð Dð Dð: ð!ð !ð !ñ „Xð!ð ð"ð "ð "ñ „Xð"ð ð#ð #ð #ñ „Xð#ð
%ð %ð %ð %ð(=ð =ð =ð =ð?ð ?ð ?ð ?ð+ð +ð +ð +ð7ð 7ð 7ð 7ðFð Fð Fð FðDð Dð Dð DðDð Dð Dð DðEð Eð Eð EðBð Bð Bð Bð
?ð ?ð ?ð ?ð.ð .ð .ð .ð-ð -ð -ð -ð.ð .ð .ð .ð/ð /ð /ð /ð.ð .ð .ð .ð/ð /ð /ð /ð5ð 5ð 5ð 5ð, 9€Kð(ð (ð (ð (ðT9ð 9ð 9ð 9ð'
ð '
ð '
ð '
ðR4ð 4ð 4ð 4ð6ð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ð	(ð 	(ð 	(ð 	(ðð ð ð ðð ð ð ðð ð ð ð ð ð ð ðð ð ð ð(ð ð ð ð&ð ð ð ð
+ð 
+ð 
+ð 
+ð*ð *ð *ð *ðX>ð >ð >ð >ð,4ð 4ð 4ð 4ð,.ð .ð .ð .ð8
ð 
ð 
ð 
ðVð Vð Vð Vð
ð ð ð ð'ð 'ð 'ð 'ðJ+ð J+ð J+ð J+ðX/ð /ð /ð /ð.ð .ð .ð .ð+ð +ð +ð +ðBð Bð Bð Bð:ð :ð :ð :ðAð Að Að Að,ð ,ð ,ð ,ð*ð *ð *ð *ð *ð *ð *ð *r;   r6  c                  óH   ‡ — e Zd ZdZddddœZdˆ fd„Zdd„Zdd„Zdd„Zˆ xZ	S )ÚRequestDispatcherÚRequestÚop_responseÚop_raw_request_headersÚ
op_failure)r”  ÚrawRequestHeadersÚfailurerÕ   rÙ   r<   r   r.   r/   c           
     ó’  •— || _         |                     d¦  «        | _        |                     d¦  «        | _        t	          |                     d¦  «        ¦  «        | _        d | _        d | _        |                     d¦  «        p|j        j	        }t          ¦   «                              |||                     d¦  «        pd|                     d¦  «        pd| j        d	œ|                     d
¦  «        �
d
|d
         ini ¥t          | j        ¦  «        t          |¦  «        |                     |¦  «        j        dœ¥¦  «         d S )NÚ	requestIdr•  Úheadersr  r  rÈ   rL   ÚGET)r  rL   rM  ÚpostData)ÚisNavigationRequestÚresourceTyperÌ   )rÕ   rg   Ú
request_idÚnavigation_idr   Úraw_headersr”  rJ  rÌ   rÜ   r3   r4   rÚ  r   r  rú   )r5   r6   rÕ   r<   rÜ   r9   s        €r:   r4   zRequestDispatcher.__init__Á  sF  ø€ ØˆŒ	Ø Ÿ*š* [Ñ1Ô1ˆŒð $ŸZšZ¨Ñ7Ô7ˆÔÝ)¨&¯*ª*°YÑ*?Ô*?Ñ@Ô@ˆÔØ8<ˆŒð '+ˆŒØ—:’:˜iÑ(Ô(Ð?¨D¬JÔ,?ˆÝ‰Œ×Ò˜ Ø—:’:˜eÑ$Ô$Ð*¨Ø—j’j Ñ*Ô*Ð3¨eØÔ'ð(
ð (
ð( —*’*˜ZÑ(Ô(Ð4ð ˜F :Ô.Ð/Ð/Ø:<ð)(
õ* $(¨Ô(:Ñ#;Ô#;Ý*¨6Ñ2Ô2Ø—^’^ HÑ-Ô-Ô5ð/(
ð (
ð (
ñ 	ô 	ð 	ð 	ð 	r;   r   c                ó0   — d| j         r| j         j        nd iS )Nr”  )r”  rú   r?   s     r:   rF  zRequestDispatcher.op_responseì  s   € Ø°T´]ÐL˜DœMÔ1Ð1ÈÐMÐMr;   c                ó   — d| j         iS ©NrM  ©rT  r?   s     r:   rG  z(RequestDispatcher.op_raw_request_headersï  ó   € Ø˜4Ô+Ð,Ð,r;   c                ó*   — d| j         r	d| j         indiS )u  â›” NULL means "it did not fail", and that is a different answer from
        an empty string. `_network.py` reads `errorText` and hands back None
        when there is none, so an empty string here would make every successful
        request look like it failed with a blank reason.ÚerrorÚ	errorTextN)rJ  r?   s     r:   rH  zRequestDispatcher.op_failureò  s"   € ð
 ¸¼ÐN˜+ t¤|Ð4Ð4È$ÐOÐOr;   )rÕ   rÙ   r<   r   r.   r/   rA   )
rB   rC   rD   rF   rG   r4   rF  rG  rH  rH   rI   s   @r:   rD  rD  ¹  s    ø€ € € € € Ø€Dà!Ø5Øðð €Gð)ð )ð )ð )ð )ð )ðVNð Nð Nð Nð-ð -ð -ð -ðPð Pð Pð Pð Pð Pð Pð Pr;   rD  c                  óf   ‡ — e Zd ZdZdddddddœZdˆ fd„Zdd„Zdd„Zdd„Zdd„Z	dd„Z
dd„Zˆ xZS )ÚResponseDispatcherÚResponseÚop_bodyÚop_raw_response_headersÚop_security_detailsÚop_server_addrÚop_sizesÚop_http_version)r*  ÚrawResponseHeadersÚsecurityDetailsÚ
serverAddrÚsizesÚhttpVersionÚrequestrD  r<   r   r.   r/   c                ó*  •— || _         t          |                     d¦  «        ¦  «        | _        |                     d¦  «        pd| _        |                     d¦  «        pd|                     d¦  «        pddœ| _        t          ¦   «                              |||j        d         |                     d	¦  «        pd|                     d
¦  «        pd| j        |j	        t          |                     d¦  «        ¦  «        dddddddddœdœ¦  «         d S )NrM  ÚprotocolVersionrÈ   ÚremoteIPAddressÚ
remotePortr   )Ú	ipAddressÚportr  ÚstatusÚ
statusTextÚfromServiceWorkeréÿÿÿÿ)Ú	startTimeÚdomainLookupStartÚdomainLookupEndÚconnectStartÚsecureConnectionStartÚ
connectEndÚrequestStartÚresponseStart)r  rr  rs  rM  rk  rt  Útiming)rk  r   rg   rT  Úprotocol_versionÚremoter3   r4   Úinitializerrú   rÚ  )r5   r6   rk  r<   r9   s       €r:   r4   zResponseDispatcher.__init__  s%  ø€ àˆŒÝ)¨&¯*ª*°YÑ*?Ô*?Ñ@Ô@ˆÔØ &§
¢
Ð+<Ñ =Ô =Ð CÀˆÔØ$*§J¢JÐ/@Ñ$AÔ$AÐ$GÀRØ%Ÿzšz¨,Ñ7Ô7Ð<¸1ð>ð >ˆŒõ 	‰Œ×Ò˜ ØÔ& uÔ-Ø—j’j Ñ*Ô*Ð/¨aØ Ÿ*š* \Ñ2Ô2Ð8°bØÔ'Ø”Ý!% f§j¢jÐ1DÑ&EÔ&EÑ!FÔ!Fð %&¸BØ*,¸bØ02À"Ø')¸Bð@ð @ð+
ð +
ñ 	ô 	ð 	ð 	ð 	r;   r   c                óÜ  — | j         j        }t          j        ¦   «         dz   }| j         j        }|t          |di ¦  «        v rUt          j        ¦   «         |k     r>t          j        d¦  «         |t          |di ¦  «        v rt          j        ¦   «         |k     °>|                     dd|i¦  «        pi }|                     d¦  «        rt          d¦  «        ‚d|                     d	¦  «        pd
iS )u«  The response body, base64, straight from the engine.

        This raised unconditionally between 2026-08-24 and 2026-08-30, because
        `Network.getResponseBody` had been removed from Juggler while trimming
        it. The command is back, and so is this. Reported from outside by
        someone identifying protection vendors from three signals - URL,
        headers, and the body of the scripts - who was left with two.

        â›” ONE KEY, and it has to be one. `_connection.py` asserts
        `len(result) == 1` and returns that value unwrapped, so the engine's
        second field cannot be forwarded even though it is the more
        interesting of the two.
        g      $@Ú	_requestsg{®Gáz”?zNetwork.getResponseBodyrL  ÚevictedzÍresponse.body() is not available: the engine evicted this body to stay under its response-storage cap (100 MB per tab, 10 MB per response). Read the body sooner, or fetch the URL again if it is still thereÚbinaryÚ
base64bodyrÈ   )
rk  rÕ   rþ  r  rR  r  rÿ  r  rg   r   )r5   r<   rÕ   r  ÚridÚanswers         r:   r`  zResponseDispatcher.op_body"  s  € ð Œ|Ô ˆõ" ”>Ñ#Ô# dÑ*ˆØŒlÔ%ˆØ•W˜T ;°Ñ3Ô3Ð3Ð3½¼Ñ8HÔ8HÈ8Ò8SÐ8SÝŒJ�tÑÔÐð •W˜T ;°Ñ3Ô3Ð3Ð3½¼Ñ8HÔ8HÈ8Ò8SÐ8Sð —’Ø%¨°SÐ'9ñ;ô ;ð AØ>@ð 	à�:Š:�iÑ Ô ð 	.õ $ð-ñ.ô .ð .ð
 ˜&Ÿ*š* \Ñ2Ô2Ð8°bÐ9Ð9r;   c                ó   — d| j         iS rW  rX  r?   s     r:   ra  z*ResponseDispatcher.op_raw_response_headers]  rY  r;   c                ó   — d| j         pdiS )u  â›” Juggler sends it on `requestFinished`, not on `responseReceived`,
        so a response asked before the request finished does not know yet. It
        answers what it has - the alternative is blocking a property read on a
        network event that may never come.r|   Úunknown)r  r?   s     r:   re  z"ResponseDispatcher.op_http_version`  s   € ð
 ˜Ô.Ð;°)Ð<Ð<r;   c                ó
   — dd iS rÞ   r[   r?   s     r:   rb  z&ResponseDispatcher.op_security_detailsg  s   € Ø˜ˆÐr;   c                ó2   — d| j         d         r| j         nd iS )Nr|   rp  )r€  r?   s     r:   rc  z!ResponseDispatcher.op_server_addrj  s   € Ø¨¬°KÔ(@ÐJ˜œ˜ÀdÐKÐKr;   c                ó   — ddddddœiS )Nri  r   )ÚrequestBodySizeÚrequestHeadersSizeÚresponseBodySizeÚresponseHeadersSizer[   r?   s     r:   rd  zResponseDispatcher.op_sizesm  s&   € Ø¨QÀaØ./ÈðKð Kð Lð 	Lr;   )rk  rD  r<   r   r.   r/   rA   )rB   rC   rD   rF   rG   r4   r`  ra  re  rb  rc  rd  rH   rI   s   @r:   r^  r^  ú  så   ø€ € € € € Ø€DàØ7Ø0Ø&ØØ(ðð €Gðð ð ð ð ð ð:9:ð 9:ð 9:ð 9:ðv-ð -ð -ð -ð=ð =ð =ð =ðð ð ð ðLð Lð Lð LðLð Lð Lð Lð Lð Lð Lð Lr;   r^  c                  ó^   ‡ — e Zd ZdZdZdddddœZdˆ fd„Zdd„Zdd„Zdd„Z	dd„Z
dd„Zˆ xZS )ÚRouteDispatcheru2  One intercepted request, waiting for the caller to decide.

    â›” A ROUTE THAT IS NEVER ANSWERED HANGS THE PAGE, and it hangs it silently.
    The request sits held in the network layer; nothing errors, the page simply
    never finishes loading, and the failure surfaces as a timeout on whatever
    the caller does next. Playwright's client answers automatically when no
    handler matches - that safety net only works if this object reaches it,
    which is why the `route` event is emitted the instant the request is
    intercepted and never lazily.
    ÚRouteÚop_abortÚop_continueÚ
op_fulfillÚop_redirect)ÚabortÚcontinueÚfulfillÚredirectNavigationRequestrk  ú'RequestDispatcher'r.   r/   c                ó‚   •— || _         d| _        t          ¦   «                              ||j        d|j        i¦  «         d S )NFrk  )rk  Úansweredr3   r4   rÕ   rú   )r5   r6   rk  r9   s      €r:   r4   zRouteDispatcher.__init__†  s<   ø€ ØˆŒØˆŒÝ‰Œ×Ò˜ ¤°	¸7¼?Ð/KÑLÔLÐLÐLÐLr;   ÚcommandrM   r<   r   r   c                óä   — | j         rt          d¦  «        ‚d| _         t          |¦  «        }| j        j        |d<   | j        j                             ||¦  «        }|                      ¦   «          |S )Nz^this route was already answered: a request can be aborted, continued or fulfilled exactly onceTrL  )r   r   rn   rk  rR  rÕ   r  r,   )r5   r¡  r<   r  s       r:   Ú_sendzRouteDispatcher._send‹  st   € ØŒ=ð 	7Ý#ð6ñ7ô 7ð 7ð ˆŒÝ�f‘”ˆØ"œlÔ5ˆˆ{Ñð ”Ô"×'Ò'¨°Ñ8Ô8ˆØ�Š‰ŒˆØˆr;   c                ó\   — |                       dd|                     d¦  «        pdi¦  «        S )uë   â›” The error code travels: `NS_ERROR_ABORT` and `NS_ERROR_FAILURE`
        are not the same thing to a page that inspects the failure, and
        collapsing every reason into one is the sort of flattening a detector
        can read.zNetwork.abortInterceptedRequestÚ	errorCodeÚaborted)r£  rg   r?   s     r:   r–  zRouteDispatcher.op_abortœ  s9   € ð
 �zŠzÐ;Ø&¨¯
ª
°;Ñ(?Ô(?Ð(LÀ9ÐMñOô Oð 	Or;   c           	     ó6  — t          |                     d¦  «        |                     d¦  «        |                     d¦  «        �"t          |                     d¦  «        ¦  «        nd |                     d¦  «        dœ¦  «        }|                      d|¦  «        S )Nr  rL   rM  rO  )r  rL   rM  rO  ú Network.resumeInterceptedRequest)r%   rg   r   r£  )r5   r<   r�   s      r:   r—  zRouteDispatcher.op_continue¤  s�   € ÝØ—:’:˜eÑ$Ô$Ø—j’j Ñ*Ô*à Ÿ*š* YÑ/Ô/Ð;õ & f§j¢j°Ñ&;Ô&;Ñ<Ô<Ð<ØAEØŸ
š
 :Ñ.Ô.ð
ð 
ñ ô ˆð �zŠzÐ<¸gÑFÔFÐFr;   c                óÖ  — |                      d¦  «        }|�a|                      d¦  «        sLddl}|                     t          |¦  «                             d¦  «        ¦  «                             d¦  «        }|                      dt          |                      d¦  «        pd	|                      d
¦  «        pdt          |                      d¦  «        ¦  «        |dœ¦  «        ¦  «        S )u8  â›” THE BODY IS BASE64 ON THE WIRE, always. The client already
        encodes it and names the field `body` with `isBase64` beside it;
        Juggler wants `base64body`. Handing over the raw string produces a page
        whose bytes are the base64 TEXT, which renders as gibberish rather than
        failing.r*  NÚisBase64r   r  Úasciiz!Network.fulfillInterceptedRequestrr  éÈ   rs  rÈ   rM  )rr  rs  rM  r†  )	rg   Úbase64Ú	b64encoderM   ÚencodeÚdecoder£  r%   r   )r5   r<   r*  Ú_b64s       r:   r˜  zRouteDispatcher.op_fulfill®  sà   € ð �zŠz˜&Ñ!Ô!ˆØÐ F§J¢J¨zÑ$:Ô$:ÐØ!Ð!Ð!Ð!Ø—>’>¥# d¡)¤)×"2Ò"2°7Ñ";Ô";Ñ<Ô<×CÒCÀGÑLÔLˆDØ�zŠzÐ=½yØ—j’j Ñ*Ô*Ð1¨cØ Ÿ*š* \Ñ2Ô2Ð8°bÝ% f§j¢j°Ñ&;Ô&;Ñ<Ô<Øð	J
ð J
ñ @ô @ñ ô ð 	r;   c                ó>   — |                       dd|d         i¦  «        S )Nr¨  r  )r£  r?   s     r:   r™  zRouteDispatcher.op_redirect¿  s'   € Ø�zŠzÐ<Ø  &¨¤-Ð0ñ2ô 2ð 	2r;   ©rk  rž  r.   r/   ©r¡  rM   r<   r   r.   r   rA   )rB   rC   rD   rE   rF   rG   r4   r£  r–  r—  r˜  r™  rH   rI   s   @r:   r”  r”  r  sØ   ø€ € € € € ð	ð 	ð €DàØ!ØØ%2ð	ð €GðMð Mð Mð Mð Mð Mð
ð ð ð ð"Oð Oð Oð OðGð Gð Gð Gðð ð ð ð"2ð 2ð 2ð 2ð 2ð 2ð 2ð 2r;   r”  c            
      ón  ‡ — e Zd ZdZi dd“dd“dd“dd	“d
d“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“d d!“d"d#“i d$d%“d&d'“d(d)“d*d+“d,d-“d.d/“d0d1“d2d3“d4d5“d6d5“d7d8“d9d:“d;d<“d=d>“d?d@“dAdB“dCdD“¥dEdFdGdHdIdJdKdLdMœ¥Z	 d¹dºdZ„Zd»ˆ fd[„Zed¼d]„¦   «         Zed^„ ¦   «         Z	ed½d`„¦   «         Z
d¾da„Zd¾db„Z	 d¹d¿dg„ZdhZdÀdl„Zd¾dm„ZdÀdn„ZdoZedÁds„¦   «         ZdÂdv„ZdÃdx„ZdÄdz„ZdÅd{„ZdÆd}„ZdÇd~„ZdÂd„ZdÈd�„ZdÈd‚„ZdÉd‡„ZdÈdˆ„ZdÇd‰„Z dÇdŠ„Z!dÇd‹„Z"dÇdŒ„Z#dÇd�„Z$dÇdŽ„Z%dÇd�„Z&dÇd�„Z'dÇd‘„Z(dÇd’„Z)dÇd“„Z*dÇd”„Z+dÇd•„Z,dÇd–„Z-dÇd—„Z.dÇd˜„Z/dÇd™„Z0dÇdš„Z1dÇd›„Z2dÇdœ„Z3dÇd�„Z4dÇdž„Z5dÇdŸ„Z6dÊd¡„Z7dÇd¢„Z8dÇd£„Z9dÇd¤„Z:dÇd¥„Z;dÇd¦„Z<dÇd§„Z=dÇd¨„Z>dÇd©„Z?dÇdª„Z@dÇd«„ZAdÇd¬„ZBdÇd­„ZCdÇd®„ZDd¯d°d±œZEd²ZFd³ZGdÇd´„ZHdÇdµ„ZIdÇd¶„ZJdÇd·„ZKd¾d¸„ZLˆ xZMS )ËÚPageDispatcherÚPageÚ	mouseMoveÚop_mouse_moveÚ	mouseDownÚop_mouse_downÚmouseUpÚop_mouse_upÚ
mouseClickÚop_mouse_clickÚ
mouseWheelÚop_mouse_wheelÚkeyboardDownÚop_key_downÚ
keyboardUpÚ	op_key_upÚkeyboardPressÚop_key_pressÚkeyboardTypeÚop_key_typeÚkeyboardInsertTextÚop_key_insertÚcloseÚop_closeÚgoBackÚ
op_go_backÚ	goForwardÚop_go_forwardÚreloadÚ	op_reloadÚupdateSubscriptionÚop_update_subscriptionÚsetViewportSizeÚop_set_viewport_sizeÚemulateMediaÚop_emulate_mediaÚ
screenshotÚop_screenshotÚscreencastStartÚop_screencast_startÚscreencastStopÚop_screencast_stopÚbringToFrontÚop_bring_to_frontÚexposeBindingÚop_expose_bindingÚtouchscreenTapÚop_touchscreen_tapÚrequestsÚop_requestsÚ__waitInfo__Úop_noopÚrejectÚop_binding_replyÚresolveÚ	requestGCÚop_request_gcrz  r{  r|  r}  ÚconsoleMessagesÚop_console_messagesÚ
pageErrorsÚop_page_errorsÚclearConsoleMessagesÚop_clear_console_messagesÚclearPageErrorsÚop_clear_page_errorsÚop_storage_itemsÚop_storage_getÚop_storage_setÚop_storage_removeÚop_storage_clearÚop_run_before_unloadÚop_add_init_scriptÚop_set_interception)ÚwebStorageItemsÚwebStorageGetItemÚwebStorageSetItemÚwebStorageRemoveItemÚwebStorageClearÚrunBeforeUnloadÚaddInitScriptÚsetNetworkInterceptionPatternsNrˆ  ú'BrowserContextDispatcher'ÚsessionrM   Ú	target_idÚnumberrr   ÚopenerúOptional['PageDispatcher']r.   r/   c                ón  — || _         d| _        || _        || _        || _        d| _        t          j        ¦   «         | _        d| _	        d | _
        |j        j        }g | _        t          j        ¦   «         | _        t          ||¦  «        | _        t#          ||¦  «        | _        |                     | j        ¦  «         	 |                      |||||¦  «         d S # t,          $ rN |                     | j        ¦  «         | j                             ¦   «          | j                             ¦   «          ‚ w xY w)NFr   )rˆ  Úinterceptingr  r	  r
  Úpopups_openedÚ	threadingÚLockÚ_close_lockÚ_announced_closedÚ_screencast_idÚbrowserÚconnÚ_heldÚ
_held_lockr   rŽ  r   rÖ   Úadd_listenerÚ_route_juggler_eventÚ_buildÚBaseExceptionÚremove_listenerÚdetach)r5   r6   rˆ  r  r	  r
  r  r  s           r:   r4   zPageDispatcher.__init__ö  s9  € ð ˆŒð "ˆÔØˆŒØ"ˆŒð ˆŒð ˆÔõ %œ>Ñ+Ô+ˆÔØ!&ˆÔð .2ˆÔØŒÔ#ˆð, &(ˆŒ
Ý#œ.Ñ*Ô*ˆŒÝ" 4¨Ñ1Ô1ˆŒÝ& t¨WÑ5Ô5ˆŒØ×Ò˜$Ô3Ñ4Ô4Ð4ð	Ø�KŠK˜ ¨°$¸Ñ?Ô?Ð?Ð?Ð?øÝð 	ð 	ð 	ð × Ò  Ô!:Ñ;Ô;Ð;ØŒN×!Ò!Ñ#Ô#Ð#ØŒM× Ò Ñ"Ô"Ð"Øð	øøøs   ÃC ÃAD4c                ó   •— | j                              ¦   «          |j                             || j        | j         | j        ¦  «        | _        |j                             ||j        ¦  «        }|| _	        i | _
        i | _        i | _        g | _        g | _        g | _        | j                             d¬¦  «        | _        t%          || | j        ¦  «        | _        |j                             d¦  «        pdddœ}| j        j        |d| j        dœ}|�
|j        |d
<   t/          ¦   «                              |||¦  «         |                      dd| j        j        i¦  «         | | j        _        |                      ¦   «          d	S )z9The rest of the construction, under `__init__`'s cleanup.ç      4@rú  Úviewporté   éÐ  ©ÚwidthÚheightF)Ú	mainFrameÚviewportSizeÚisClosedÚ
pageNumberNr  Ú	__adopt__Úguid)rÖ   Úinstallr  Úactions_for_pagerŽ  r
  ræ   Úreplayró  Úreplayed_eventsÚ_framesrƒ  Ú_navigation_requestsÚ_console_logÚ
_error_logÚ_request_logÚwait_for_main_frameÚmain_frame_idr6  rÌ   r+  rg   rú   r3   r4   Úemitr,  r7   Ú_install_events)
r5   r6   rˆ  r  r  r  Úreplayedr!  r�  r9   s
            €r:   r  zPageDispatcher._build:  sŒ  ø€ ð 	Œ×ÒÑÔÐØ”×7Ò7Ø�T”^ T¤]°D´KñAô AˆŒð ”?×)Ò)¨'°4Ô3FÑGÔGˆØ'ˆÔØ')ˆŒØ)+ˆŒð 57ˆÔ!ð )+ˆÔØ&(ˆŒð (*ˆÔØ!œ^×?Ò?ÈÐ?ÑMÔMˆÔõ % V¨T°4Ô3EÑFÔFˆŒ
Ø”?×&Ò& zÑ2Ô2ð FÀØADð7Fð 7Fˆð
 %)¤JÔ$6Ø'/¸UØ%)¤[ð2ð 2ˆð Ðð %+¤NˆK˜Ñ!Ý‰Œ×Ò˜ ¨+Ñ6Ô6Ð6Ø�	Š	�+ ¨¬
¬Ð8Ñ9Ô9Ð9Ø ˆŒ
Ôð 	×ÒÑÔÐÐÐr;   ú'BrowserDispatcher'c                ó   — | j         j        S r1   )rˆ  r  r×   s    r:   r  zPageDispatcher.browser}  s   € àŒ|Ô#Ð#r;   c                ó   — | j         j        S r1   )ræ   Úkeyboardr×   s    r:   r>  zPageDispatcher.keyboard„  s   € àŒ|Ô$Ð$r;   ú'juggler.Connection'c                ó$   — | j         j        j        S r1   )rˆ  r  r  r×   s    r:   r  zPageDispatcher.connŽ  s   € àŒ|Ô#Ô(Ð(r;   c                óž  — | j         5  | j        pg dc}| _        d„ t          |¦  «        D ¦   «         }t          |¦  «        D ]^\  }\  }}|t          |¦  «                 |k    r=|                     d¦  «        r(	 |                      ||¦  «         ŒN# t          $ r Y ŒZw xY wŒ_	 ddd¦  «         n# 1 swxY w Y   |                      ¦   «          dS )u  Turn Juggler events into protocol events.

        â›” THE SUBSCRIPTION IS NOT OPTIONAL AND IT IS NOT FREE. Playwright asks
        the server to enable categories with `updateSubscription`, and this
        server ignores that and always sends: the events are cheap here because
        they are already crossing the pipe for the lifecycle, and a category
        that is off is a `page.on("console")` that silently never fires.

        â›” AND `console` AND `pageError` GO TO THE CONTEXT, not to the Page.
        `_browser_context.py` listens for them and re-emits on the page it
        finds in `params["page"]`. Emitting them on the Page instead produces
        no error at all: the handler simply never runs, and the user concludes
        their page prints nothing.
        Nc                ó:   — i | ]\  }\  }}t          |¦  «        |“ŒS r[   )Úid)r}   ÚirÈ  r<   s       r:   r   z2PageDispatcher._install_events.<locals>.<dictcomp>³  s(   € ÐHÐHÐH¡n a©¨!¨V•B�v‘J”J ÐHÐHÐHr;   zNetwork.)r  r  Ú	enumeraterC  r  Ú_on_juggler_eventr>   Ú_hear_lifecycle)r5   ÚheldÚlastrD  rL   r<   s         r:   r9  zPageDispatcher._install_events”  s5  € ð: Œ_ð 	ð 	Ø#œzÐ/¨R°ÐˆD�$”*ØHÐH½	À$¹¼ÐHÑHÔHˆDÝ'0°¡¤ð ð Ñ#�Ñ#�F˜FØ�˜6™
œ
Ô# qÒ(Ð(¨V×->Ò->¸zÑ-JÔ-JÐ(ðØ×.Ò.¨v°vÑ>Ô>Ð>Ð>øÝ$ð ð ð Ø˜ðøøøøð	ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	×ÒÑÔÐÐÐs6   ˆA0B.Á9BÂB.Â
BÂB.ÂBÂB.Â.B2Â5B2c                ó(   — | j         | j        _        dS )uy  Take what only the lifecycle can decide and send it up.

        â›” networkidle IS NOT AN ENGINE EVENT: it is born in
        `Lifecycle._settle` on a silence deadline, and until 2026-10-04 it went
        no further than the lifecycle's own waits. The client never got
        `loadstate {"add": "networkidle"}`, so `page.wait_for_load_state(
        "networkidle")`, `wait_for_url(..., wait_until="networkidle")` and
        `expect_navigation(wait_until="networkidle")` - which wait for exactly
        that event - timed out on a loaded, silent page. One definition, two
        consumers: `goto`'s wait and this event.
        N)Ú_on_lifecyclerŽ  Úannouncer×   s    r:   rG  zPageDispatcher._hear_lifecycle¼  s   € ð #'Ô"4ˆŒÔÐÐr;   ÚwhatrÜ   r  úOptional[str]c                óØ   — |                       |¦  «        }|dk    r|                     dddi¦  «         d S |dk    r.|pd|_        |                     d|j        |j        dœ¦  «         d S d S )NÚnetworkidleÚ	loadstateÚaddÚsameDocumentrÈ   Ú	navigated)r  r{   )r  r8  r  r{   )r5   rM  rÜ   r  Úchilds        r:   rK  zPageDispatcher._on_lifecycleÊ  sƒ   € à—’˜xÑ(Ô(ˆØ�=Ò Ð Ø�JŠJ�{ U¨MÐ$:Ñ;Ô;Ð;Ð;Ð;Ø�^Ò#Ð#ð. ˜	˜rˆEŒIØ�JŠJ�{¨E¬I¸u¼zÐ$JÐ$JÑKÔKÐKÐKÐKð1 $Ð#r;   i   rL   r<   r   c                ó6  — || j         k    rd S | j        �n| j        5  | j        �Gt          | j        ¦  «        | j        k     r| j                             ||f¦  «         	 d d d ¦  «         d S 	 d d d ¦  «         n# 1 swxY w Y   |                      ||¦  «         d S r1   )r  r  r  ÚlenÚHELD_CAPrþ   rF  )r5   rL   r<   r  s       r:   r  z#PageDispatcher._route_juggler_eventî  sý   € à�d”lÒ"Ð"ØˆFØŒ:Ð!Ø”ð ð Ø”:Ð)Ý˜4œ:‘”¨¬Ò6Ð6Øœ
×)Ò)¨6°6Ð*:Ñ;Ô;Ð;Øð	ð ð ñ ô ð ð ð Ø)ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð
 	×Ò˜v vÑ.Ô.Ð.Ð.Ð.s   œAA8Á8A<Á?A<c                ó  — | j         }|                     | j        ¦  «         | j                             ¦   «          | j                             ¦   «          | j        r&|                     di | j        ¬¦  «         d| _        dS dS )uú  Unsubscribe this page and everything it owns.

        â›” ALL THREE, AND THIS IS THE HALF OF THE FIX THAT IS EASY TO FORGET.
        A page registers three subscribers - its Lifecycle, its InjectedScript
        and itself - and before the registry none of them was ever removed:
        that is how a browser reached 979 subscribers at page 325 and then
        stopped delivering events altogether. Adding a listener without a
        matching removal is the same defect written in a new shape.
        úPage.stopScreencast©r  N)	r  r  r  rŽ  r  rÖ   r  Úpostr  )r5   r  s     r:   Ú_detach_listenersz PageDispatcher._detach_listenersú  sŠ   € ð ŒyˆØ×Ò˜TÔ6Ñ7Ô7Ð7ØŒ×ÒÑÔÐØŒ×ÒÑÔÐð
 Ôð 	'Ø�IŠIÐ+¨R¸¼ˆIÑFÔFÐFØ"&ˆDÔÐÐð	'ð 	'r;   c           
     ób  — |dk    r£| j         sd S |                      d|                     d¦  «        pd|                     d¦  «        pd|                     d¦  «        pd|                     d¦  «        pdd	œ¦  «         | j                             d
d| j         i| j        ¬¦  «         d S |dk    rœ| j        |                     d¦  «        pdt          |                     d¦  «        pg ¦  «        g t          |                     d¦  «        ¦  «        dœ}|  	                    | j
        |¦  «         | j                             d|¦  «         d S |dk    r“| j        dd|                     d¦  «        pd|                     d¦  «        pddœit          |                     d¦  «        ¦  «        dœ}|  	                    | j        |¦  «         | j                             d|¦  «         d S |dk    r_|                      |d         |                     d¦  «        pd|                     d¦  «        pd|                     d¦  «        pd¦  «         d S |d k    r1t          j        | j        |fd!¬"¦  «                             ¦   «          d S |d#k    r|                      d$¦  «         d S |d%k    r:|                      |d&         ¦  «        }|                      d'd(|j        i¦  «         d S |d)k    re| j                             |                     d&¦  «        d ¦  «        }|�3|                      d*d(|j        i¦  «         |                     ¦   «          d S d S |d+k    rdd,d-d.œ                     |                     d/¦  «        pd¦  «        }|r3|                      |d&         ¦  «                             d0d1|i¦  «         d S d S |d2k    rÀt-          | j        | |¦  «        }|| j        |                     d3¦  «        <   |  	                    | j        |¦  «         |j        r|                      |¦  «         | j                             d4|j        | j        d5œ¦  «         |                     d6¦  «        r|                      |¦  «         d S d S |d7k    rx| j                             |                     d3¦  «        ¦  «        }|�Gt;          | j        ||¦  «        }||_        | j                             d8|j        | j        d9œ¦  «         d S d S |d:k    r®| j                             |                     d3¦  «        d ¦  «        }|�||j        �!|                     d;¦  «        pd|j        _        | j                             d<|j        |j        r|j        j        nd |                     d=¦  «        pd| j        d>œ¦  «         d S d S |d?k    r¤| j                             |                     d3¦  «        d ¦  «        }|�r|                     d@¦  «        pdA|_         | j                             dB|j        |                     d=¦  «        pd|                     d@¦  «        pdA| j        dCœ¦  «         d S d S |dDk    rÔ|                      |d&         ¦  «        }dED ]}|                     d0dF|i¦  «         Œ|                     dG¦  «        pd|_!        |                     d/¦  «        pd|_"        |                     dH|j!        |j"        |  #                    |                     dI¦  «        ¦  «        dJœ¦  «         |                     d0d1dKi¦  «         d S d S )LNzPage.screencastFrameÚscreencastFrameÚdatarÈ   Ú	timestampr   ÚdeviceWidthÚdeviceHeight)r`  ra  ÚviewportWidthÚviewportHeightzPage.screencastFrameAckÚscreencastIdr[  zRuntime.consolerÁ   ÚlogÚargsÚlocation)rÕ   rÁ   r#  rh  ri  ÚconsolezPage.uncaughtErrorr[  ÚErrorÚmessageÚstack)r{   rl  rm  )rÕ   r[  ri  Ú	pageErrorzPage.dialogOpenedÚdialogIdÚalertÚdefaultValuezPage.fileChooserOpenedT)rö  rh  ÚdaemonzPage.crashedÚcrashzPage.frameAttachedr  ÚframeAttachedrÌ   zPage.frameDetachedÚframeDetachedzPage.eventFiredr‘  Údomcontentloaded)r‘  ÚDOMContentLoadedr{   rQ  rR  zNetwork.requestWillBeSentrL  rk  )rk  rÕ   ÚisInterceptedzNetwork.responseReceivedr”  )r”  rÕ   zNetwork.requestFinishedrm  ÚrequestFinishedÚresponseEndTime)rk  r”  ÚresponseEndTimingrÕ   zNetwork.requestFailedr¥  ÚfailedÚrequestFailed)rk  r{  ÚfailureTextrÕ   zPage.navigationCommitted)r…  rv  r‘  rP  Úremover  rT  r•  )r  r{   ÚnewDocumentr…  )$r  r8  rg   r  r\  r  rú   r   r   Ú	_rememberr3  rˆ  r4  Ú_emit_fused_dialogr  ÚThreadÚ_announce_file_chooserÚstartr  r1  ro   r,   rD  r6   rƒ  r5  rS  Ú_remember_navigationÚ_offer_router^  r”  r  rJ  r  r{   Únavigation_document)	r5   rL   r<   rŒ   rJ  rU  r®  rk  r”  s	            r:   rF  z PageDispatcher._on_juggler_event  s,  € ØÐ+Ò+Ð+ð Ô&ð Ø�Ø�IŠIÐ'ØŸ
š
 6Ñ*Ô*Ð0¨bØ#ŸZšZ¨Ñ4Ô4Ð9¸Ø!'§¢¨MÑ!:Ô!:Ð!?¸aØ"(§*¢*¨^Ñ"<Ô"<Ð"AÀð	*ð *ñ ô ð ð ŒI�NŠNÐ4Ø*¨DÔ,?Ð@Ø#'¤<ð ñ 1ô 1ð 1ð 1ð 1ð Ð(Ò(Ð(ð œØŸ
š
 6Ñ*Ô*Ð3¨eÝ% f§j¢j°Ñ&8Ô&8Ð&>¸BÑ?Ô?ØÝ% f§j¢j°Ñ&<Ô&<Ñ=Ô=ðð ˆEð �NŠN˜4Ô,¨eÑ4Ô4Ð4ØŒL×Ò˜i¨Ñ/Ô/Ð/Ð/Ð/ØÐ+Ò+Ð+ð œØ!Ø#Ø%Ÿzšz¨)Ñ4Ô4Ð:¸Ø#ŸZšZ¨Ñ0Ô0Ð6°Bð$ð $ð õ
 & f§j¢j°Ñ&<Ô&<Ñ=Ô=ðð ˆGð �NŠN˜4œ?¨GÑ4Ô4Ð4ØŒL×Ò˜k¨7Ñ3Ô3Ð3Ð3Ð3ØÐ*Ò*Ð*Ø×#Ò# F¨:Ô$6Ø$*§J¢J¨vÑ$6Ô$6Ð$A¸'Ø$*§J¢J¨yÑ$9Ô$9Ð$?¸RØ$*§J¢J¨~Ñ$>Ô$>Ð$DÀ"ñFô Fð Fð Fð Fð Ð/Ò/Ð/õ ÔØÔ2¸&¸Øðñ ô ç"šU™WœW˜W˜W˜WØ�~Ò%Ð%Ø�IŠI�gÑÔÐÐÐØÐ+Ò+Ð+ð —N’N 6¨)Ô#4Ñ5Ô5ˆEØ�IŠI�o¨°´Ð'?Ñ@Ô@Ð@Ð@Ð@ØÐ+Ò+Ð+Ø”L×$Ò$ V§Z¢Z°	Ñ%:Ô%:¸DÑAÔAˆEØÐ Ø—	’	˜/¨G°U´]Ð+CÑDÔDÐDØ—’‘”���ð !Ð ð Ð(Ò(Ð(Ø#Ø);ð=ð =ß=@ºSØŸš FÑ+Ô+Ð1¨rñ>3ô >3ð ð ð 1ð —’˜v iÔ0Ñ1Ô1×6Ò6Ø %¨ ñ1ô 1ð 1ð 1ð 1ð1ð 1ð
 Ð2Ò2Ð2Ý'¨¬°T¸6ÑBÔBˆGØ6=ˆDŒN˜6Ÿ:š: kÑ2Ô2Ñ3Ø�NŠN˜4Ô,¨gÑ6Ô6Ð6ØÔ$ð 3Ø×)Ò)¨'Ñ2Ô2Ð2ØŒL×Ò˜i°W´_Ø26´,ð*@ð *@ñ Aô Að Aà�zŠz˜/Ñ*Ô*ð +Ø×!Ò! 'Ñ*Ô*Ð*Ð*Ð*ð+ð +àÐ1Ò1Ð1Ø”n×(Ò(¨¯ª°KÑ)@Ô)@ÑAÔAˆGØÐ"Ý-¨d¬k¸7ÀFÑKÔK�Ø#+�Ô Ø”×!Ò! *¸8Ô;KØ7;´|ð/Eð /Eñ Fô Fð Fð Fð Fð #Ð"ð
 Ð0Ò0Ð0Ø”n×(Ò(¨¯ª°KÑ)@Ô)@À$ÑGÔGˆGØÐ"ØÔ#Ð/àŸ
š
Ð#4Ñ5Ô5Ð;¸ð Ô$Ô5à”×!Ò!Ð"3Ø&œà")Ô"2ð!= Ô 0Ô 8Ð 8Ø8<Ø)/¯ªÐ4EÑ)FÔ)FÐ)KÈ!Ø œLð6ð 6ñ ô ð ð ð ð	 #Ð"ð Ð.Ò.Ð.Ø”n×(Ò(¨¯ª°KÑ)@Ô)@À$ÑGÔGˆGØÐ"Ø"(§*¢*¨[Ñ"9Ô"9Ð"E¸X�”Ø”×!Ò! /Ø&œð *0¯ªÐ4EÑ)FÔ)FÐ)KÈ!Ø#)§:¢:¨kÑ#:Ô#:Ð#F¸hØ œLð!4ð 4ñ ô ð ð ð ð #Ð"ð( Ð1Ò1Ð1Ø—N’N 6¨)Ô#4Ñ5Ô5ˆEØNð ;ð ;�Ø—
’
˜;¨°5Ð(9Ñ:Ô:Ð:Ð:ØŸ
š
 5Ñ)Ô)Ð/¨RˆEŒIØŸš FÑ+Ô+Ð1¨rˆEŒJØ�JŠJ�{Ø”yØœ
Ø#×7Ò7¸¿
º
À>Ñ8RÔ8RÑSÔSð%ð %ñ ô ð ð
 �JŠJ�{ U¨HÐ$5Ñ6Ô6Ð6Ð6Ð6ð 2Ð1r;   iô  rg  r…   rŒ   c                ót   — |                       |¦  «         t          | ¦  «        t          j        k    r| d= d S d S )Nr   )rþ   rW  r¶  Ú	LOG_LIMIT)rg  rŒ   s     r:   r�  zPageDispatcher._rememberº  s;   € à�
Š
�5ÑÔÐÝˆs‰8Œ8•nÔ.Ò.Ð.Ø�A���ð /Ð.r;   rk  rž  c                ó  — | j         }|                     |j        d¦  «         |||j        <   t          |¦  «        t          j        k    r<|t          t          |¦  «        ¦  «        = t          |¦  «        t          j        k    °:dS dS )u½  Index a document request by the navigation it belongs to.

        â›” THE KEY IS RE-INSERTED, not merely overwritten, so that a redirect
        chain keeps ONE entry and keeps it at the young end of the dict. A
        plain assignment would leave the entry at the position of the first
        hop, and the eviction below - which drops the oldest key - would then
        be able to throw away a navigation that is still in progress.
        N)r2  ro   rS  rW  r¶  rŠ  ÚnextÚiter)r5   rk  Úindexs      r:   r†  z#PageDispatcher._remember_navigationÀ  s|   € ð Ô)ˆØ�	Š	�'Ô'¨Ñ.Ô.Ð.Ø'.ˆˆgÔ#Ñ$Ý�%‰jŒj�>Ô3Ò3Ð3Ø•d�4 ™;œ;Ñ'Ô'Ð(õ �%‰jŒj�>Ô3Ò3Ð3Ð3Ð3Ð3Ð3r;   rS  c                óP   — | j                              |¦  «        }|�	d|j        ini S )zEThe request field is optional, not nullable in Playwright's protocol.Nrk  )r2  rg   rú   ©r5   rS  rk  s      r:   rˆ  z"PageDispatcher.navigation_documentÏ  s/   € àÔ+×/Ò/°Ñ>Ô>ˆØ/6Ð/B�	˜7œ?Ð+Ð+ÈÐJr;   r   c                ód   — | j                              |¦  «        }|�|j        €dS |j        j        S )uþ  The Response CHANNEL for a finished navigation, or None.

        â›” None IS A REAL ANSWER, and Playwright gives it in exactly the cases
        that reach here with nothing to return: a same-document navigation or
        an anchor (no navigationId at all, so `goto` never even started a
        document load), and a navigation whose document request failed or was
        served without a response. Answering with an empty object instead
        would turn "there is no response" into "here is a response with no
        status", which is the shape of lie rule 12 is about.

        The three cases collapse into ONE lookup on purpose: a `None` id, an
        id nothing was indexed under, and an indexed request that has no
        response yet all mean the same thing here. An explicit guard on the
        id was written first and removed - it could not change the answer,
        since `get(None)` misses like any other miss, so it was a second
        place deciding a question this line already decides.
        N)r2  rg   r”  rú   r�  s      r:   r–  z"PageDispatcher.navigation_responseÔ  s8   € ð$ Ô+×/Ò/°Ñ>Ô>ˆØˆ?˜gÔ.Ð6Ø�4ØÔÔ'Ð'r;   c                ó®  — 	 |                      d¦  «        pi }|                      d¦  «        }|                      d¦  «        }|r|sdS | j                             |¦  «        }|sdS | j                             ||¦  «        }|sdS |                      |¦  «        }t          | j        ||d¦  «        }t          | j                             |dd|i¦  «        ¦  «        }	|  	                    d|j
        |	dœ¦  «         dS # t          $ rM}
| j        }t          |j        ¦  «        d	k     r#|j                             d
|
z  ¦  «         Y d}
~
dS Y d}
~
dS d}
~
ww xY w)uÜ  Build the handle the client expects and emit `fileChooser`.

        â›” `isMultiple` IS NOT IN THE ENGINE EVENT. Juggler sends the element
        and the context it lives in, nothing else, while the client's
        `FileChooser` is constructed with it - so it has to be ASKED of the
        element. Defaulting it to false would be a value invented here to fill
        a field, which is the shape of thing that is right until the first
        `<input multiple>`.
        rœ  ré   ÚexecutionContextIdNrÑ   z(injected, el) => !!el.multipleÚfileChooser)rœ  Ú
isMultipleé    zfileChooser: %s)rg   rÖ   Úframe_of_contextr'  r  r–   r6   rÚ  rP   r8  rú   r>   r  rW  Úhandler_errorsrþ   )r5   r<   rœ  rÎ   Ú
context_idrÜ   r+  rÌ   rù   ÚmultiplerJ  r  s               r:   r„  z%PageDispatcher._announce_file_chooserë  s±  € ð	HØ—j’j Ñ+Ô+Ð1¨rˆGØŸš JÑ/Ô/ˆIØŸšÐ$8Ñ9Ô9ˆJØð  Jð Ø�Ø”}×5Ò5°jÑAÔAˆHØð ð
 �Ø”m×)Ò)¨(°IÑ>Ô>ˆGØð Ø�Ø—N’N 8Ñ,Ô,ˆEÝ,¨T¬[¸%ÀØ-<ñ>ô >ˆFå˜DœM×.Ò.ØÐ;Ø˜WÐ%ñ'ô 'ñ (ô (ˆHð �IŠI�m°´Ø4<ð&>ð &>ñ ?ô ?ð ?ð ?ð ?øåð 	Hð 	Hð 	HØ”9ˆDÝ�4Ô&Ñ'Ô'¨"Ò,Ð,ØÔ#×*Ò*Ð+<¸wÑ+FÑGÔGÐGÐGÐGÐGÐGÐGÐGð -Ð,Ð,Ð,Ð,Ð,øøøøð	Høøøs+   ‚AC= Á	C= Á'C= ÂA5C= Ã=
EÄ<EÅErÍ   c                ó   — || j         j        k    r| j         S | j                             |¦  «        }|�|S | j                              |¦  «        }t          |dd¦  «        }t          | j        | |t          |dd¦  «        pd|r|                      |¦  «        ndt          t          |dg ¦  «        pg ¦  «        pdg¬¦  «        }|| j        |<   |S )u£  The dispatcher for a frame of this page, made on first sight.

        â›” ONE DISPATCHER PER FRAME ID, AND THE REGISTRY IS WHY. Building a
        new one each time would announce a second `__create__` for the same
        frame, and the client would hold two ChannelOwners that disagree about
        the load states - the second one starting empty while the first is the
        one events are delivered to.
        Nr7   r  rÈ   Ústatesr…  )r  r‚  r€  )
rÌ   rÜ   r1  rg   rŽ  r  r6  r6   r  Úsorted)r5   rÜ   ÚexistingrÌ   Ú	parent_idÚmades         r:   r  zPageDispatcher.frame_for	  så   € ð �t”zÔ*Ò*Ð*Ø”:ÐØ”<×#Ò# HÑ-Ô-ˆØÐØˆOØ”×$Ò$ XÑ.Ô.ˆÝ˜E 8¨TÑ2Ô2ˆ	ÝØŒK˜˜xÝ˜˜u bÑ)Ô)Ð/¨RØ6?ÐI˜Ÿš¨	Ñ2Ô2Ð2ÀTÝ�w u¨h¸Ñ;Ô;ÐA¸rÑBÔBÐPÀxÀjð	Rñ Rô Rˆð
 "&ˆŒ�XÑØˆr;   c                óÀ   — t          |                     d¦  «        ¦  «        }|r| j                             d¦  «         |                      dd|i¦  «         || _        dS )a>  `page.route()`: hold this page's requests until a handler answers.

        It was missing, and the dispatcher refused it as a gap. Juggler's
        `Network.setRequestInterception` is per page and, like the context's,
        a boolean: the client filters by url and continues what it does not
        want.
        Úpatternszpage.route()zNetwork.setRequestInterceptionrº  N)rÚ  rg   r  Úrequire_interceptionr  r  ©r5   r<   Úwanteds      r:   rþ  z"PageDispatcher.op_set_interception*	  sb   € õ �f—j’j Ñ,Ô,Ñ-Ô-ˆØð 	>ØŒL×-Ò-¨nÑ=Ô=Ð=Ø�	Š	Ð2°YÀÐ4GÑHÔHÐHØ"ˆÔØˆtr;   c                ó6  — | j         r| }nV| j        j         r| j        }nB	 |                      dd|j        i¦  «         n!# t          j        t          j        f$ r Y nw xY wdS t          | j        |¦  «        }| 	                    d|j
        | j
        dœ¦  «         dS )uE  Hand a held request to whoever asked to hold it.

        â›” THE PAGE'S CHANNEL WHEN THE PAGE ASKED, the context's otherwise. The
        client's `Page._on_route` runs the page's handlers and then falls
        through to the context's, so a request emitted on the page reaches
        both; one emitted on the context never reaches a `page.route()`.

        â›” AND A HELD REQUEST NOBODY CLAIMS IS RELEASED HERE. Interception can
        be switched off while a request is already held; emitting nothing
        would leave it held for ever and hang the page silently.
        r¨  rL  NÚroute)r§  rÕ   )r  rˆ  r  rR  ÚjugglerÚProtocolErrorÚTargetClosedErrorr”  r6   r8  rú   )r5   rk  rÊ  r§  s       r:   r‡  zPageDispatcher._offer_route9	  sÁ   € ð Ôð 	ØˆEˆEØŒ\Ô&ð 	Ø”LˆEˆEðØ—	’	Ð<Ø&¨Ô(:Ð;ñ=ô =ð =ð =øåÔ)­7Ô+DÐEð ð ð Ø�ðøøøàˆFÝ ¤¨WÑ5Ô5ˆØ�
Š
�7 e¤m¸T¼\ÐJÐJÑKÔKÐKÐKÐKs    > ¾AÁAr¡  c                óH   — | j                              ||| j        d¬¦  «        S )u  A Juggler command on THIS page's session.

        â›” The session is not optional and it is not a detail: without it the
        command lands on whichever page the browser feels like, and with two
        pages open the events of one are indistinguishable from the other.
        é   ©r  r  )r  r  r  ©r5   r¡  r<   s      r:   r  zPageDispatcher.sendW	  s/   € ð Œy�~Š~˜g vØ6:´lÈBð ñ Pô Pð 	Pr;   c              ƒ  óT   K  — | j                              | j        ||¦  «        ƒ d{V —†S )uû  `send`, off the loop and awaitable.

        â›” THE PRIMITIVE A FUSED TYPE NEEDS. A fused object's own methods are
        `async def` - the public API promises that - but the Juggler call
        underneath still BLOCKS. This hands it to the transport's worker pool
        via `Server.run_blocking` and awaits the result, instead of a fused
        type reaching for the pool on its own and reinventing the translation
        `run_blocking` already does. Dialog is the first caller, 2026-08-29.
        N)r6   Úrun_blockingr  r®  s      r:   Ú
send_asynczPageDispatcher.send_asynca	  s6   è è € ð ”[×-Ò-¨d¬i¸À&ÑIÔIÐIÐIÐIÐIÐIÐIÐIr;   Ú	dialog_idÚkindrl  Údefault_valuec                óÊ   ‡ ‡‡— ddl m} ‰ j                             ‰ j        ¦  «        }|€dS  |‰ |||||¦  «        Š|j        Š‰ j                             ˆˆˆ fd„¦  «         dS )uJ  A dialog just opened: build the fused object and hand it to the
        impl-side `BrowserContext` directly, no `__create__`, no guid, no
        channel.

        â›” THIS RUNS ON THE CONNECTION'S READ LOOP, not the asyncio loop -
        `_on_juggler_event` always does, see the comment on `_history` /
        `Page.fileChooserOpened` above for the same fact stated once already.
        `_on_dialog` and the auto-answer path it may take
        (`asyncio.create_task(...)`) both require the ASYNCIO loop, so the
        hand-off is `Server.call_soon`, the exact mechanism every other event
        already crosses this same boundary with - just carrying a real object
        instead of a wire message this time.

        â›” AND CREATING THE OBJECT IS NOT NOTIFYING ANYONE, same as when this
        was two objects: forgetting the hand-off is a HANG, not a leak - the
        content process sits inside `window.alert` and the next command times
        out naming something unrelated. Measured on 2026-08-28, before the
        fusion, as `Runtime.callFunction: no response in 30s`.
        r   )ÚDialogNc                 óD   •— ‰j                              ‰ j        ‰¦  «        S r1   )r6   ÚdeliverÚ
_on_dialog)Úbrowser_contextÚdialogr5   s   €€€r:   r¬  z3PageDispatcher._emit_fused_dialog.<locals>.<lambda>˜	  s   ø€ �D”K×'Ò'¨Ô(BÀFÑKÔK€ r;   )Ú&invisible_playwright._pw._impl._dialogr¶  r6   Útwinr,  Ú_browser_contextÚ	call_soon)	r5   r²  r³  rl  r´  Ú
ImplDialogÚ	impl_pagerº  r»  s	   `      @@r:   r‚  z!PageDispatcher._emit_fused_dialogm	  s¡   øøø€ ð* 	PÐOÐOÐOÐOÐOà”K×$Ò$ T¤YÑ/Ô/ˆ	ØÐð ˆFØ�˜D )¨Y¸¸gØ(ñ*ô *ˆà#Ô4ˆð 	Œ×ÒØKÐKÐKÐKÐKÐKñ	Mô 	Mð 	Mð 	Mð 	Mr;   c                óª  — | j         j        }| j                              |¦  «        }|�|j        nd}|                      ||dk    rd|ini ¦  «        pi }|dk    r|                     d¦  «        sddiS | j                             |||                     d¦  «        pd|                     d¦  «        pd	d
z  ¬¦  «        }d|                      |¦  «        iS )u`  â›” goBack / goForward / reload are sent to the PAGE, not the Frame.

        The first draft put them on the Frame because everything else that
        navigates lives there, and it was wrong: `_page.py` sends them on the
        page channel. Guessing which object owns an operation is exactly what
        the recorded trace exists to stop.
        NúPage.reloadr  Úsuccessr”  r�  r‘  r  r’  rm   rú  )rÌ   rÜ   rŽ  Ú
navigationr  rg   Úwait_for_new_navigationr–  )r5   r¡  r<   rÜ   rÌ   Úpreviousr  rÅ  s           r:   Ú_historyzPageDispatcher._history›	  s  € ð ”:Ô&ˆð
 ”×$Ò$ XÑ.Ô.ˆØ',Ð'8�5Ô#Ð#¸dˆØ—’˜7Ø%¨Ò6Ð6ð &/°Ð$9Ð$9Ø<>ñ@ô @ð FØCEð 	à�mÒ#Ð#¨F¯JªJ°yÑ,AÔ,AÐ#ð  Ð%Ð%ð ”^×;Ò;Ø�h §
¢
¨;Ñ 7Ô 7Ð A¸6Ø—Z’Z 	Ñ*Ô*Ð3¨e°vÑ=ð <ñ ?ô ?ˆ
ð ˜D×4Ò4°ZÑ@Ô@ÐAÐAr;   c                ó.   — |                       d|¦  «        S )NzPage.goBack©rÈ  r?   s     r:   rÏ  zPageDispatcher.op_go_back¼	  ó   € Ø�}Š}˜]¨FÑ3Ô3Ð3r;   c                ó.   — |                       d|¦  «        S )NzPage.goForwardrÊ  r?   s     r:   rÑ  zPageDispatcher.op_go_forward¿	  s   € Ø�}Š}Ð-¨vÑ6Ô6Ð6r;   c                ó.   — |                       d|¦  «        S )NrÃ  rÊ  r?   s     r:   rÓ  zPageDispatcher.op_reloadÂ	  rË  r;   c                ó‚   — | j                              |d         |d         |                     d¦  «        pd¬¦  «         d S )Nrã   rä   Ústepsr   )rÏ  )ræ   Úmoverg   r?   s     r:   r¹  zPageDispatcher.op_mouse_moveÆ	  sF   € ØŒ×Ò˜& œ+ v¨c¤{Ø &§
¢
¨7Ñ 3Ô 3Ð 8°qð 	ñ 	:ô 	:ð 	:àˆtr;   c                ó¨   — | j                              t          |                     d¦  «        ¦  «        |                     d¦  «        pd¬¦  «         d S ©NrÑ  rÒ  r   ©rÑ  rÓ  )ræ   Ú
mouse_downr   rg   r?   s     r:   r»  zPageDispatcher.op_mouse_downË	  sS   € ØŒ×Ò¥w¨v¯zªz¸(Ñ/CÔ/CÑ'DÔ'DØ'-§z¢z°,Ñ'?Ô'?Ð'DÀ1ð 	 ñ 	Fô 	Fð 	Fàˆtr;   c                ó¨   — | j                              t          |                     d¦  «        ¦  «        |                     d¦  «        pd¬¦  «         d S rÒ  )ræ   Úmouse_upr   rg   r?   s     r:   r½  zPageDispatcher.op_mouse_upÐ	  sS   € ØŒ×Ò¥W¨V¯ZªZ¸Ñ-AÔ-AÑ%BÔ%BØ%+§Z¢Z°Ñ%=Ô%=Ð%BÀð 	ñ 	Dô 	Dð 	Dàˆtr;   c           	     óÄ   — | j                              |d         |d         t          |                     d¦  «        ¦  «        |                     d¦  «        pd¬¦  «         d S )Nrã   rä   rÑ  rÒ  r   rÓ  )ræ   Úclick_atr   rg   r?   s     r:   r¿  zPageDispatcher.op_mouse_clickÕ	  sb   € ØŒ×Ò˜f Sœk¨6°#¬;Ý%,¨V¯ZªZ¸Ñ-AÔ-AÑ%BÔ%BØ%+§Z¢Z°Ñ%=Ô%=Ð%BÀð 	ñ 	Dô 	Dð 	Dð ˆtr;   c                óT   — | j                              |d         |d         ¦  «         d S )NÚdeltaXÚdeltaY)ræ   Úwheelr?   s     r:   rÁ  zPageDispatcher.op_mouse_wheelÛ	  s)   € ØŒ×Ò˜6 (Ô+¨V°HÔ-=Ñ>Ô>Ð>Øˆtr;   c                óF   — | j                              |d         ¦  «         d S ©Nr'  )r>  Údownr?   s     r:   rÃ  zPageDispatcher.op_key_downß	  s!   € ØŒ×Ò˜6 %œ=Ñ)Ô)Ð)Øˆtr;   c                óF   — | j                              |d         ¦  «         d S rÞ  )r>  Úupr?   s     r:   rÅ  zPageDispatcher.op_key_upã	  s!   € ØŒ×Ò˜ œÑ'Ô'Ð'Øˆtr;   c                ód   — | j                              |d         t          |¦  «        ¬¦  «         d S )Nr'  )r(  )r>  rÂ   ri   r?   s     r:   rÇ  zPageDispatcher.op_key_pressç	  s0   € ð 	Œ×Ò˜F 5œMµJ¸vÑ4FÔ4FÐÑGÔGÐGØˆtr;   c                óh   — | j                              |d         t          |¦  «        pd¬¦  «         d S )Nr#  r$  )rÔ  )r>  rÁ   ri   r?   s     r:   rÉ  zPageDispatcher.op_key_typeî	  s>   € ð 	Œ×Ò˜6 &œ>Ý$.¨vÑ$6Ô$6Ð$=¸#ð 	ñ 	?ô 	?ð 	?àˆtr;   c                óF   — | j                              |d         ¦  «         d S )Nr#  )r>  Úinsert_textr?   s     r:   rË  zPageDispatcher.op_key_insertö	  s!   € ØŒ×!Ò! &¨¤.Ñ1Ô1Ð1Øˆtr;   c           	     óv   — |                       dt          d|                     d¦  «        i¦  «        ¦  «         d S )NzPage.setViewportSizer(  )r  r%   rg   r?   s     r:   r×  z#PageDispatcher.op_set_viewport_sizeû	  s@   € Ø�	Š	Ð(­)Ø˜VŸZšZ¨Ñ7Ô7Ð8ñ+:ô +:ñ 	;ô 	;ð 	;àˆtr;   c                ó†   — i }dD ]!\  }}|                      |¦  «        }|�|||<   Œ"|sdS |                      d|¦  «         dS )u˜  â›” ONLY WHAT WAS ASKED FOR TRAVELS. Our fork turned four hardwired
        values into "no-override" precisely because a BrowsingContext override
        SHORT-CIRCUITS the pref: Gecko reads the override first and only
        consults LookAndFeel when it is None, so an override nobody requested
        turns every declaration invisible_core makes into dead code without
        raising anything.
        ))ÚcolorSchemerè  )ÚreducedMotionré  )ÚforcedColorsrê  )Úcontrastrë  )ÚmediarÁ   NzPage.setEmulatedMedia)rg   r  )r5   r<   r   ÚoursÚtheirsr|   s         r:   rÙ  zPageDispatcher.op_emulate_media 
  sh   € ð !ˆð0ð 	$ð 	$‰LˆD�&ð
 —J’J˜tÑ$Ô$ˆEØÐ Ø#��F‘øØð 	Ø�4Ø�	Š	Ð)¨3Ñ/Ô/Ð/Øˆtr;   c           
     óþ  — |                      d¦  «        }|sx| j                             | j        j        d¦  «        }|pdddddddœ}|                      d¦  «        rdd|d         |d	         d
œ}n|d         |d         |d         |d         d
œ}|                      dt          |                      d¦  «        dk    rdnd||                      d¦  «        ddœ¦  «        ¦  «        pi }d|                      d¦  «        iS )uŽ   â›” The engine answers base64 and the client wants base64: it does
        NOT want bytes. Decoding here would send a str() of a bytes object.Úclipa^  ({x: window.scrollX, y: window.scrollY, width: window.innerWidth, height: window.innerHeight, fullWidth: Math.max(document.documentElement.scrollWidth,                     document.body ? document.body.scrollWidth : 0), fullHeight: Math.max(document.documentElement.scrollHeight,                      document.body ? document.body.scrollHeight : 0)})r   r"  r#  )rã   rä   r%  r&  Ú	fullWidthÚ
fullHeightÚfullPagerñ  rò  )rã   rä   r%  r&  rã   rä   r%  r&  zPage.screenshotrÁ   Újpegz
image/jpegz	image/pngÚqualityF)ÚmimeTyperð  rõ  ÚomitDeviceScaleFactorr…  r`  )rg   rÖ   ÚevaluaterÌ   rÜ   r  r%   )r5   r<   rð  Úboxr  s        r:   rÛ  zPageDispatcher.op_screenshot
  sS  € ð< �zŠz˜&Ñ!Ô!ˆØð 	HØ”-×(Ò(Ø”
Ô#ðZñ[ô [ˆCð ð @˜q q°4À3Ø'+¸3ð@ð @ˆCà�zŠz˜*Ñ%Ô%ð HØ QØ!$ [Ô!1¸SÀÔ=NðPð P��ð ! œX¨C°¬HØ!$ W¤¸¸X¼ðHð H�à—’Ð,­iØ(.¯
ª
°6Ñ(:Ô(:¸fÒ(DÐ(D˜˜Ø(ØØ—z’z )Ñ,Ô,Ø%*ð9
ð 9
ñ /ô /ñ ô ð ð ð 	ð ˜&Ÿ*š* VÑ,Ô,Ð-Ð-r;   c                ó@   — | j                              di d¬¦  «         dS )u  â›” `Heap.collectGarbage` really does collect, and it is SLOW - it was
        once used as a "bare command" to measure transport latency and reported
        26,8 ms of browser work as if it were ours. It is the right command
        here, and the wrong one to benchmark with.zHeap.collectGarbager¬  rú  N)r  r  r?   s     r:   rî  zPageDispatcher.op_request_gcU
  s$   € ð
 	Œ	�ŠÐ,¨b¸"ˆÑ=Ô=Ð=Øˆtr;   c                ó6   — | j                              |¦  «        S r1   )rÌ   r{  r?   s     r:   r{  z PageDispatcher.op_add_script_tag]
  s   € ØŒz×+Ò+¨FÑ3Ô3Ð3r;   c                ó6   — | j                              |¦  «        S r1   )rÌ   r}  r?   s     r:   r}  zPageDispatcher.op_add_style_tag`
  s   € ØŒz×*Ò*¨6Ñ2Ô2Ð2r;   c                ó.   — dt          | j        ¦  «        iS )NÚmessages)r…   r3  r?   s     r:   rð  z"PageDispatcher.op_console_messagesc
  s   € Ø�D Ô!2Ñ3Ô3Ð4Ð4r;   c                ó.   — dt          | j        ¦  «        iS )NÚerrors)r…   r4  r?   s     r:   rò  zPageDispatcher.op_page_errorsf
  s   € Ø�$˜tœÑ/Ô/Ð0Ð0r;   c                ó8   — | j                              ¦   «          d S r1   )r3  Úclearr?   s     r:   rô  z(PageDispatcher.op_clear_console_messagesi
  s   € ØÔ×ÒÑ!Ô!Ð!Øˆtr;   c                ó8   — | j                              ¦   «          d S r1   )r4  r  r?   s     r:   rö  z#PageDispatcher.op_clear_page_errorsm
  s   € ØŒ×ÒÑÔÐØˆtr;   Úcodec                ó°   — |                      d¦  «        }|dvrt          d|z  ¦  «        ‚| j                             | j        j        ||f|z   z  ¦  «        S )uI  localStorage or sessionStorage, in the PAGE's own world.

        â›” THE MAIN WORLD, and this one is not a style choice: web storage is
        keyed by ORIGIN and the utility world sandbox has an ExpandedPrincipal.
        Reading it from there does not raise - it answers a DIFFERENT store,
        empty, and the caller concludes the site saved nothing.

        â›” AND THE KIND IS VALIDATED. `kind` arrives as a string from the
        client; interpolating it into the expression would let anything through
        and produce a JavaScript error the caller cannot read.
        r³  )ÚlocalStorageÚsessionStoragezDunknown storage kind %r: the two are localStorage and sessionStorage)rg   r   rÖ   rÃ  rÌ   rÜ   )r5   r<   r  rh  r³  s        r:   Ú_storagezPageDispatcher._storager
  sq   € ð �zŠz˜&Ñ!Ô!ˆØÐ9Ð9Ð9Ý#ð!Ø#'ñ(ñ)ô )ð )ð Œ}×-Ò-ØŒJÔ ¨$¨°4©Ñ!8ñ:ô :ð 	:r;   c                ó:   — |                       |d¦  «        }d|pg iS )Nz¡(() => { const s = window.%s; const o = []; for (let i = 0; i < s.length; i++) {   const k = s.key(i);   o.push({name: k, value: s.getItem(k)}); } return o; })()Úitems©r  )r5   r<   r
  s      r:   r÷  zPageDispatcher.op_storage_items†
  s-   € Ø—’˜fð0ñ1ô 1ˆð ˜˜ "Ð%Ð%r;   c                ó^   — |                       |dt          |d         ¦  «        ¦  «        }d|iS )Nzwindow.%s.getItem(%s)r{   r|   ©r  r   )r5   r<   r|   s      r:   rø  zPageDispatcher.op_storage_get�
  s4   € Ø—’˜fÐ&=Ý(¨°¬Ñ8Ô8ñ:ô :ˆà˜ÐÐr;   c           	     ó‚   — |                       |dt          |d         ¦  «        t          |d         ¦  «        ¦  «         d S )Nzwindow.%s.setItem(%s, %s)r{   r|   r  r?   s     r:   rù  zPageDispatcher.op_storage_set”
  sB   € Ø�Š�fÐ9Ý  ¨¤Ñ0Ô0µ*¸VÀG¼_Ñ2MÔ2Mñ	Oô 	Oð 	Oàˆtr;   c                óZ   — |                       |dt          |d         ¦  «        ¦  «         d S )Nzwindow.%s.removeItem(%s)r{   r  r?   s     r:   rú  z PageDispatcher.op_storage_remove™
  s1   € Ø�Š�fÐ8Ý  ¨¤Ñ0Ô0ñ	2ô 	2ð 	2àˆtr;   c                ó2   — |                       |d¦  «         d S )Nzwindow.%s.clear()r  r?   s     r:   rû  zPageDispatcher.op_storage_clearž
  s   € Ø�Š�fÐ1Ñ2Ô2Ð2Øˆtr;   c                ó®   ‡ ‡— |                      d¦  «        pdŠ‰ j                             ‰¦  «         t          ‰ j        ‰ ˆ ˆfd„¦  «        }d|j        iS )uŸ  A script the caller wants run before anything on every document.

        â›” IT WAS MISSING, AND THE REFUSAL LAYER SAID SO CORRECTLY: the name
        is INSIDE the perimeter, so its absence was a gap and not a decision.
        Nothing in the transport judgement reached it - none of those five
        files calls it - and it turned up the first time a REALNESS gate ran on
        this path, which is the argument for running those on both transports
        rather than on the one they were written against.

        The list itself is owned by `InjectedScript`, because the engine's
        command REPLACES the whole set and the utility world lives in it.
        rõ  rÈ   c                 ó8   •— ‰ j                              ‰¦  «        S r1   )rÖ   Úremove_init_script©r5   rõ  s   €€r:   r¬  z3PageDispatcher.op_add_init_script.<locals>.<lambda>³
  s   ø€ �D”M×4Ò4°VÑ<Ô<€ r;   Ú
disposable)rg   rÖ   Úadd_init_scriptr*   r6   rú   )r5   r<   rù   rõ  s   `  @r:   rý  z!PageDispatcher.op_add_init_script¢
  sf   øø€ ð —’˜HÑ%Ô%Ð+¨ˆØŒ×%Ò% fÑ-Ô-Ð-Ý%ØŒK˜Ø<Ð<Ð<Ð<Ð<ñ>ô >ˆð ˜fœnÐ-Ð-r;   c           	     óÂ   — |                      d¦  «        dk    rE| j                             ddt          |                      d¦  «        ¦  «        i| j        d¬¦  «         dS )uØ  Turn a client-side event subscription into an engine-side one.

        â›” IT WAS A NO-OP, AND FOR MOST EVENTS THAT IS CORRECT: console,
        requests, dialogs and the rest are emitted unconditionally, so the
        client asking to hear them changes nothing here. `fileChooser` is the
        exception, and it is the exception that makes the no-op WRONG rather
        than merely incomplete: Juggler does not report a file picker unless it
        has been told to intercept it, so the subscription is the only thing
        that arms the engine. Without this, `page.expect_file_chooser()` waits
        for an event nobody will ever send and dies on its own timeout, with
        nothing in the log saying why.
        Úeventr”  z"Page.setInterceptFileChooserDialogrº  é
   r­  N)rg   r  r  rÚ  r  r?   s     r:   rÕ  z%PageDispatcher.op_update_subscription¶
  se   € ð �:Š:�gÑÔ -Ò/Ð/ØŒI�NŠNØ4Ø�D §¢¨IÑ!6Ô!6Ñ7Ô7Ð8Øœ¨bð ñ 2ô 2ð 2ð ˆtr;   c                óP   — | j                              | j        j        d¦  «         dS )u  â›” `close(run_before_unload=True)` means: let the page show its
        `beforeunload` dialog. Answering it is the CALLER's job through the
        dialog event, so this must not close the page itself - doing that
        would dismiss the very dialog the option exists to raise.zwindow.close()N)rÖ   rÃ  rÌ   rÜ   r?   s     r:   rü  z#PageDispatcher.op_run_before_unloadÊ
  s'   € ð
 	Œ×&Ò& t¤zÔ':Ð<LÑMÔMÐMØˆtr;   c                ó€   — |                       d|d         |d         | j                             ¦   «         dœ¦  «         dS )u#  â›” It fires whether or not touch is enabled on the context, and that
        is worth knowing: with touch off the event goes out and the page has no
        `ontouchstart` to listen with, so the call SUCCEEDS and does nothing.
        Touch is turned on at context creation with `hasTouch`.zPage.dispatchTapEventrã   rä   )rã   rä   rÐ  N)r  r>  Úmodifier_maskr?   s     r:   rå  z!PageDispatcher.op_touchscreen_tapÒ
  sO   € ð
 	�	Š	Ð)Ø˜sœ¨&°¬+Ø $¤× ;Ò ;Ñ =Ô =ð?ð ?ñ	@ô 	@ð 	@ð ˆtr;   c                ó(   — dd„ | j         D ¦   «         iS )Nræ  c                ó   — g | ]	}|j         ‘Œ
S r[   r9  )r}   Úrs     r:   r�   z.PageDispatcher.op_requests.<locals>.<listcomp>Ý
  s   € ÐBÐBÐB¨1˜QœYÐBÐBÐBr;   )r5  r?   s     r:   rç  zPageDispatcher.op_requestsÜ
  s   € ØÐBÐB°Ô0AÐBÑBÔBÐCÐCr;   c                ó    — t          d¦  «        ‚)us  â›” `resolve` and `reject` are the REPLY half of `expose_binding`,
        and they are unreachable while that is refused: they arrive on a
        BindingCall object, and no BindingCall is ever created. This exists so
        the refusal names the feature instead of answering "Page has no method
        resolve", which would send the reader looking in the wrong place.z…this is the reply path of expose_binding(), which is not implemented: no binding is ever installed, so nothing can call back into oner  r?   s     r:   rë  zPageDispatcher.op_binding_replyß
  s   € õ  ðñô ð 	r;   c                ó    — t          d¦  «        ‚)u³  `expose_binding` / `expose_function`.

        â›” THE PAGE-FACING HALF IS NOT THE HARD PART. Installing a function on
        the page is one init script; what makes this a real feature is the
        REPLY path - the page calls it, the server raises `bindingCalled`, the
        client runs Python, and the answer has to travel back into the promise
        the page is holding. That is what `reject` and `resolve` are for, and
        they are only reachable through the BindingCall object this creates.

        â›” AND THE FUNCTION MUST LIVE IN THE PAGE'S WORLD. Installed behind the
        Xray it would be invisible to the site, which is the whole point of the
        call. Juggler's `Page.addBinding` does that, so the world is not ours
        to choose here - which is also why it cannot be hidden from the page:
        a binding is a name the site can enumerate, and a caller asking for one
        is asking for that trade.
        zûexpose_binding() is not implemented yet: the page-facing half is one init script, but the reply path - bindingCalled, then resolve or reject into the promise the page holds - is not wired, and a binding that never answers hangs the page that called itr  r?   s     r:   rã  z PageDispatcher.op_expose_bindingê
  s   € õ"  ðGñHô Hð 	Hr;   c                ó2   — |                       di ¦  «         d S )NzPage.bringToFront)r  r?   s     r:   rá  z PageDispatcher.op_bring_to_front  s   € Ø�	Š	Ð% rÑ*Ô*Ð*Øˆtr;   r"  i   r$  éP   r  c           
     óD  — | j         rt          d¦  «        ‚|                     d¦  «        rt          d¦  «        ‚|                     d¦  «        st          d¦  «        ‚|                     d¦  «        p| j        }|                     d¦  «        }|€| j        }|                     d	¦  «        }|€| j        }|                      d
t          |d         ¦  «        t          |d         ¦  «        t          |¦  «        dt          |¦  «        dœ¦  «        }|d         | _         i S )u®  `page.screencast.start(on_frame=...)`: live JPEG frames of the
        browser WINDOW.

        â›” THE WINDOW, NOT THE PAGE, AND THAT IS THE POINT. `page.screenshot()`
        already gives the content viewport. What it can never give is the
        pointer, which is drawn in the chrome document precisely so that no
        page can see it - and a person watching an agent work wants the
        pointer, the tab strip and the address bar. So every screencast this
        server starts asks the engine for `fullWindow`, our own flag on
        `Page.startScreencast`, and the `viewportWidth`/`viewportHeight` the
        client reads on each frame are the captured window's size in device
        pixels.

        Nothing is injected into the page and no script runs in it: the engine
        captures the window through the operating system, in the parent
        process, and the content process is never told.

        â›” `record` (a video file) is REFUSED, not ignored. The engine has no
        encoder - the VP8/WebM half of Playwright's screencast was never
        rebuilt - and the refusal at context creation for `record_video_dir`
        is the same decision one level up.
        z;a screencast is already running on this page; stop it firstÚrecordz›screencast to a video FILE is not available: the engine streams JPEG frames and has no video encoder. Pass on_frame= to receive the frames instead of path=Ú
sendFrameszgscreencast.start() was called with neither on_frame= nor path=, so there is nobody to deliver frames toÚsizerõ  NÚfpszPage.startScreencastr%  r&  T)r%  r&  rõ  Ú
fullWindowr(  rf  )r  r   rg   ÚSCREENCAST_DEFAULT_SIZEÚSCREENCAST_DEFAULT_QUALITYÚSCREENCAST_FPSr  rr   )r5   r<   r'  rõ  r(  r  s         r:   rÝ  z"PageDispatcher.op_screencast_start  sL  € ð. Ôð 	OÝ#ØMñOô Oð Oà�:Š:�hÑÔð 	DÝ#ðCñDô Dð Dð �zŠz˜,Ñ'Ô'ð 	BÝ#ðAñBô Bð Bð �zŠz˜&Ñ!Ô!ÐA TÔ%AˆØ—*’*˜YÑ'Ô'ˆØˆ?ØÔ5ˆGð �jŠj˜ÑÔˆØˆ;ØÔ%ˆCØ—’Ð1Ý˜˜gœÑ'Ô'Ý˜$˜xœ.Ñ)Ô)Ý˜7‘|”|ØÝ�s‘8”8ð4
ð 4
ñ ô ˆð % ^Ô4ˆÔð ˆ	r;   c                óR   — | j         sd S d | _         |                      di ¦  «         d S )NrZ  )r  r  r?   s     r:   rß  z!PageDispatcher.op_screencast_stopW  s4   € ØÔ"ð 	Ø�4Ø"ˆÔØ�	Š	Ð'¨Ñ,Ô,Ð,Øˆtr;   c                ó   — d S r1   r[   r?   s     r:   ré  zPageDispatcher.op_noop^  ó   € Øˆtr;   c                óœ   — 	 | j                              dddi| j        d¬¦  «         n# t          $ r Y nw xY w|                      ¦   «          dS )u3  Close THIS page, and only this page.

        â›” `Page.close`, NOT `Browser.removeBrowserContext`. Removing the
        context is right for a page created by `browser.new_page()`, where the
        client made an implicit context that exists only for it - and wrong for
        every other page: a caller who opens three pages in one context and
        closes one would lose all three, plus its cookies and its storage. The
        earlier version did the second thing always, and it looked correct
        because the tests open one page per context.
        z
Page.closer  Fr  r­  N)r  r  r  r>   Úannounce_closedr?   s     r:   rÍ  zPageDispatcher.op_closea  sv   € ð	ØŒI�NŠNØÐ0°%Ð8Øœ¨bð ñ 2ô 2ð 2ð 2øõ ð 	ð 	ð 	ØˆDð	øøøð 	×ÒÑÔÐØˆts   ‚%( ¨
5´5c                óP  — | j         5  | j        r	 ddd¦  «         dS d| _        	 | j                             | ¦  «         n# t          $ r Y nw xY w|                      ¦   «          |                      d¦  «         |                      ¦   «          ddd¦  «         dS # 1 swxY w Y   dS )u@  Tell the client this page is closed, ONCE.

        â›” Once, because there are four ways in: the caller closes the page,
        the caller closes the CONTEXT, which tells its pages, the engine
        detaches the target (the site called `window.close()`), and a detach
        that arrived while the page was still being adopted. They can overlap
        - `page.close()` is followed by the engine's detach for the same
        target, and by `context.close()` - and they run on different threads,
        hence the lock rather than a bare flag. A second `close`
        is not obviously harmful on today's client, which resolves a future
        that is already resolved; it is a protocol event that never happens
        against the driver, and the whole point of this exercise is that the
        two answer the same.
        NTrÌ  )r  r  r  Ú
_page_overr>   r]  r8  r,   r×   s    r:   r1  zPageDispatcher.announce_closedy  s"  € ð Ôð 	ð 	ØÔ%ð Øð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð &*ˆDÔ"ðØ”×'Ò'¨Ñ-Ô-Ð-Ð-øÝð ð ð Ø�ðøøøà×"Ò"Ñ$Ô$Ð$Ø�IŠI�gÑÔÐð �LŠL‰NŒNˆNð'	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s:   ˆ	BžB¦AÁ BÁ
AÁBÁAÁA BÂBÂ"Br1   )rˆ  r  r  rM   r	  rM   r
  rr   r  r  r.   r/   )rˆ  r  r  rM   r  r  r.   r/   )r.   r;  ©r.   r?  r@   )rM  rM   rÜ   rM   r  rN  r.   r/   ©rL   rM   r<   r   r.   r/   )rg  r…   rŒ   r   r.   r/   r³  )rS  rN  r.   r   )rS  rN  r.   r   )r<   r   r.   r/   )rÜ   rM   r.   rÍ   rA   r´  )
r²  rM   r³  rM   rl  rM   r´  rM   r.   r/   )r<   r   r  rM   r.   r   )NrB   rC   rD   rF   rG   r4   r  r4  r  r>  r  r9  rG  rK  rX  r  r]  rF  rŠ  Ústaticmethodr�  r†  rˆ  r–  r„  r  rþ  r‡  r  r±  r‚  rÈ  rÏ  rÑ  rÓ  r¹  r»  r½  r¿  rÁ  rÃ  rÅ  rÇ  rÉ  rË  r×  rÙ  rÛ  rî  r{  r}  rð  rò  rô  rö  r  r÷  rø  rù  rú  rû  rý  rÕ  rü  rå  rç  rë  rã  rá  r*  r+  r,  rÝ  rß  ré  rÍ  r1  rH   rI   s   @r:   r¶  r¶  Ç  sÕ  ø€ € € € € Ø€Dð+Ø�_ð+à�_ð+ð 	�=ð+ð 	Ð&ð	+ð
 	Ð&ð+ð 	˜ð+ð 	�kð+ð 	˜ð+ð 	˜ð+ð 	˜oð+ð 	�ð+ð 	�,ð+ð 	�_ð+ð 	�+ð+ð 	Ð6ð+ð  	Ð1ð!+ð" 	Ð*ð#+ð +ð$ 	�oð%+ð& 	Ð0ð'+ð( 	Ð.ð)+ð* 	Ð+ð++ð, 	Ð,ð-+ð. 	Ð.ð/+ð0 	�Mð1+ð2 	˜	ð3+ð4 	Ð$ð5+ð6 	Ð%ð7+ð8 	�_ð9+ð: 	Ð+ð;+ð< 	Ð)ð=+ð> 	Ð0ð?+ð@ 	Ð&ðA+ðB 	Ð ;ðC+ðD 	Ð1ðE+ð +ðF .Ø-Ø-Ø 3Ø-Ø1Ø-Ø*?ðU+ð +ð +€Gð^ 7;ðBð Bð Bð Bð BðHAð Að Að Að Að AðF ð$ð $ð $ñ „Xð$ð ð%ð %ñ „Xð%ð ð)ð )ð )ñ „Xð)ð
&ð &ð &ð &ðP5ð 5ð 5ð 5ð ,0ðLð Lð Lð Lð LðD €Hð
/ð 
/ð 
/ð 
/ð'ð 'ð 'ð 'ð,_7ð _7ð _7ð _7ðP €Iàðð ð ñ „\ðð
)ð )ð )ð )ðKð Kð Kð Kð
(ð (ð (ð (ð.%Hð %Hð %Hð %HðNð ð ð ð0ð ð ð ðLð Lð Lð Lð<Pð Pð Pð Pð
Jð 
Jð 
Jð 
Jð+Mð +Mð +Mð +Mð\Bð Bð Bð BðB4ð 4ð 4ð 4ð7ð 7ð 7ð 7ð4ð 4ð 4ð 4ðð ð ð ð
ð ð ð ð
ð ð ð ð
ð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ðð ð ð ð
ð ð ð ð
ð ð ð ð,<.ð <.ð <.ð <.ð~ð ð ð ð4ð 4ð 4ð 4ð3ð 3ð 3ð 3ð5ð 5ð 5ð 5ð1ð 1ð 1ð 1ðð ð ð ðð ð ð ð
:ð :ð :ð :ð(&ð &ð &ð &ð ð  ð  ð  ð
ð ð ð ð
ð ð ð ð
ð ð ð ð.ð .ð .ð .ð(ð ð ð ð(ð ð ð ðð ð ð ðDð Dð Dð Dð	ð 	ð 	ð 	ðHð Hð Hð Hð.ð ð ð ð )-¸Ð<Ð<ÐØ!#Ðð €Nð;ð ;ð ;ð ;ðzð ð ð ðð ð ð ðð ð ð ð0"ð "ð "ð "ð "ð "ð "ð "r;   r¶  r™  rN  c                ó`   — t          |¦  «        }| €|                     dd¦  «         n| |d<   |S )u×  The context a `Browser.*` command is about, in the form Juggler reads.

    â›” `None` IS THE DEFAULT CONTEXT, AND IT IS ADDRESSED BY ABSENCE. Juggler
    keeps every context in a Map keyed by its id and registers the default one
    under `undefined`, so an omitted field resolves to it and a `null` does not:
    `Map.get(null)` finds nothing, and the command fails naming no cause. Every
    command that names a context goes through here, so the rule lives once.
    NÚbrowserContextId)rn   ro   )r™  r<   r   s      r:   Ú_addressr9  ¯  s=   € õ ˆv‰,Œ,€CØÐØ�ŠÐ" DÑ)Ô)Ð)Ð)à",ˆÐÑØ€Jr;   c                  ó0  ‡ — e Zd ZdZi dd“dd“dd“dd	“d
d“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“d d!“ZdDˆ fd*„ZedEd,„¦   «         ZdFd/„ZdGd2„Z	dFd3„Z
dFd4„ZdFd5„ZdFd6„ZdFd7„ZdHd9„ZdFd:„ZdFd;„ZdFd<„ZdFd=„ZdFd>„ZdFd?„ZdFd@„ZdFdA„ZdFdB„ZdFdC„Zˆ xZS )IÚBrowserContextDispatcherÚBrowserContextÚnewPageÚop_new_pagerÌ  rÍ  rÔ  ré  r  Úop_context_init_scriptÚ
addCookiesÚop_add_cookiesÚcookiesÚ
op_cookiesÚclearCookiesÚop_clear_cookiesÚgrantPermissionsÚop_grant_permissionsÚclearPermissionsÚop_clear_permissionsÚsetGeolocationÚop_set_geolocationÚ
setOfflineÚop_set_offlineÚsetExtraHTTPHeadersÚop_set_extra_headersÚstorageStateÚop_storage_stateÚsetStorageStateÚop_set_storage_stater  rþ  Ú setWebSocketInterceptionPatternsÚop_set_ws_interceptionr  r;  r+  r   r™  rN  r.   r/   c           	     óê  •— || _         || _        || _        t          ||¦  «        }|                     di ¦  «         t          ||¦  «        }t          ||d|j        i¦  «        }|                     dd|j        i¦  «         t          ¦   «          
                    |||j        |j        |j        |dœ¦  «         |||fD ]}|                      dd|j        i¦  «         Œ g | _        d| _        g | _        d S )NÚpausedStateChangedÚtracingr+  r,  )ÚdebuggerÚrequestContextrX  r+  F)r  r+  r™  r]   r8  rT   r`   rú   r,  r3   r4   Úpagesr  Ú_init_scripts)
r5   r6   r  r+  r™  rY  rX  Úrequest_contextrU  r9   s
            €r:   r4   z!BrowserContextDispatcher.__init__Õ  s  ø€ àˆŒØˆŒð %ˆŒõ & f¨gÑ6Ô6ˆØ�ŠÐ*¨BÑ/Ô/Ð/Ý# F¨GÑ4Ô4ˆÝ5Ø�G˜i¨¬Ð9ñ;ô ;ˆà×Ò˜[¨6°7´<Ð*@ÑAÔAÐAÝ‰Œ×Ò˜ Ø Ô(Ø-Ô5Ø”Øð	
+
ð 
+
ñ 
	ô 
	ð 
	ð  °Ð9ð 	9ð 	9ˆEØ�IŠI�k F¨E¬JÐ#7Ñ8Ô8Ð8Ð8Ø+-ˆŒ
Ø!ˆÔð )+ˆÔÐÐr;   r?  c                ó   — | j         j        S r1   )r  r  r×   s    r:   r  zBrowserContextDispatcher.connù  s   € àŒ|Ô Ð r;   r<   r   c                ó€  ‡ ‡— |                      d¦  «        pdŠ‰ j                             ‰¦  «         ‰                      ddd„ ‰ j        D ¦   «         i¦  «         t	          ‰ j        ¦  «        D ]-}	 |j                             ‰¦  «         Œ# t          $ r Y Œ*w xY wt          ‰ j
        ‰ ˆ ˆfd„¦  «        }d|j        iS )uP  The same, for every page of this context - present and future.

        â›” IT WAS `op_noop`, which is the worst of the three possible
        answers. Refusing would have told the caller; doing it would have been
        right; accepting and discarding meant `context.add_init_script(...)`
        returned successfully and the page never saw the script - and a caller
        who adds a stub and then tests for it concludes the SITE removed it.

        â›” BOTH SIDES, and that is not belt and braces. `Browser.setInitScripts`
        covers pages this context opens LATER; the pages already open have
        their own list in the engine and do not re-read the context's, so they
        are told directly. A version that did only the first works in every
        test that adds the script before opening a page, which is most of them.
        rõ  rÈ   úBrowser.setInitScriptsÚscriptsc                ó   — g | ]}d |i‘ŒS ©r!  r[   ©r}   Úss     r:   r�   zCBrowserContextDispatcher.op_context_init_script.<locals>.<listcomp>  ó2   € ð (Eð (Eð (EØ,-ð *2°1¨ð (Eð (Eð (Er;   c                 ó.   •— ‰                       ‰¦  «        S r1   )Ú_remove_init_scriptr  s   €€r:   r¬  zABrowserContextDispatcher.op_context_init_script.<locals>.<lambda>  s   ø€ ¨d×.FÒ.FÀvÑ.NÔ.N€ r;   r  )rg   r\  rþ   Ú_browser_sendr…   r[  rÖ   r  r>   r*   r6   rú   )r5   r<   rÕ   rù   rõ  s   `   @r:   r?  z/BrowserContextDispatcher.op_context_init_scriptþ  s
  øø€ ð —’˜HÑ%Ô%Ð+¨ˆØÔ×!Ò! &Ñ)Ô)Ð)Ø×ÒÐ3Ø%ð (Eð (EØ15Ô1Cð(Eñ (Eô (Eð Fñ	Gô 	Gð 	Gõ ˜œÑ$Ô$ð 	ð 	ˆDðØ”×-Ò-¨fÑ5Ô5Ð5Ð5øÝð ð ð Ø�ðøøøå% d¤k°4Ø&NÐ&NÐ&NÐ&NÐ&NñPô Pˆà˜fœnÐ-Ð-s   Á2BÂ
BÂBrõ  rM   c                ó  — || j         v r| j                              |¦  «         |                      ddd„ | j         D ¦   «         i¦  «         t          | j        ¦  «        D ]-}	 |j                             |¦  «         Œ# t          $ r Y Œ*w xY wdS )zBUndo one context-level init script, on both sides it was added to.r`  ra  c                ó   — g | ]}d |i‘ŒS rc  r[   rd  s     r:   r�   z@BrowserContextDispatcher._remove_init_script.<locals>.<listcomp>   rf  r;   N)r\  r  ri  r…   r[  rÖ   r  r>   )r5   rõ  rÕ   s      r:   rh  z,BrowserContextDispatcher._remove_init_script  sÕ   € à�TÔ'Ð'Ð'ØÔ×%Ò% fÑ-Ô-Ð-Ø×ÒÐ3Ø%ð (Eð (EØ15Ô1Cð(Eñ (Eô (Eð Fñ	Gô 	Gð 	Gõ ˜œÑ$Ô$ð 	ð 	ˆDðØ”×0Ò0°Ñ8Ô8Ð8Ð8øÝð ð ð Ø�ðøøøð	ð 	s   Á"A=Á=
B
Â	B
c                óÞ   — |                      d¦  «        pi }|                      d¦  «        rt          d¦  «        ‚|                      d¦  «        pg }|r|                      dd|i¦  «         dS )ui  â›” COOKIES ONLY, and it refuses the rest rather than dropping it.
        A storage state carries cookies AND per-origin localStorage; writing
        the cookies and silently ignoring the origins would restore half a
        session and look like it worked, which is worse than saying no - the
        caller would debug the site instead of the tool.
        rP  ÚoriginszÐset_storage_state() with per-origin localStorage is not implemented: restoring only the cookies would look like it worked and leave half the session missing. Use page.evaluate on each origin, or open an issuerB  úBrowser.setCookiesN)rg   r   ri  )r5   r<   r®  rB  s       r:   rS  z-BrowserContextDispatcher.op_set_storage_state(  sŒ   € ð —
’
˜>Ñ*Ô*Ð0¨bˆØ�9Š9�YÑÔð 	BÝ#ðAñBô Bð Bð
 —)’)˜IÑ&Ô&Ð,¨"ˆØð 	KØ×ÒÐ3°iÀÐ5IÑJÔJÐJØˆtr;   c                óÀ   — t          |                     d¦  «        ¦  «        }|r| j                             d¦  «         |                      dd|i¦  «         || _        dS )u˜  Turn request interception on or off for this context.

        â›” THE PATTERNS ARE NOT SENT, and that is a real narrowing that has to
        be said out loud rather than discovered. Juggler's
        `Browser.setRequestInterception` is a BOOLEAN: it intercepts
        everything or nothing. Playwright's client filters by url on its side
        and calls `continue` on what it does not want, so behaviour is correct
        - but every request now makes a round trip through this process, which
        a narrow pattern would have avoided. It is a cost, not a defect, and it
        is the reason `route()` on a busy page is slower here than upstream.
        r¢  zcontext.route()zBrowser.setRequestInterceptionrº  N)rÚ  rg   r  r£  ri  r  r¤  s      r:   rþ  z,BrowserContextDispatcher.op_set_interception;  sm   € õ �f—j’j Ñ,Ô,Ñ-Ô-ˆØð 	AØŒL×-Ò-Ð.?Ñ@Ô@Ð@Ø×ÒÐ;Ø% vÐ.ñ	0ô 	0ð 	0à"ˆÔØˆtr;   c                ó    — t          d¦  «        ‚)Nz¹WebSocket routing is not implemented: Juggler reports websocket frames but has no command to hold or rewrite one, so a route that appeared to work would silently pass everything throughr  r?   s     r:   rU  z/BrowserContextDispatcher.op_set_ws_interceptionO  s   € ÝðFñGô Gð 	Gr;   c                ó   — d S r1   r[   r?   s     r:   ré  z BrowserContextDispatcher.op_noopU  r/  r;   c                óÊ  — |                      d¦  «        }t          |¦  «        t          us|dk     rt          d|›�¦  «        ‚| j        }|                     | j        ¦  «        5 }| j                             dt          | j        i ¦  «        d¬¦  «        } ||d         |¦  «         ddd¦  «         n# 1 swxY w Y   | 
                    |d         d	¬¦  «        }d
|j        iS )uE  Ask the engine for a page, then wait for its adoption.

        â›” THIS DOES NOT BUILD THE PAGE ITSELF, and that is the whole fix for
        popups. The engine emits `Browser.attachedToTarget` for EVERY page
        target - requested or spontaneous - and a single adoption path builds
        the `PageDispatcher` for all of them, so a target can never be built
        twice (once by this call, once by the event) and a `window.open`
        target is a page like any other, with its opener recorded.

        â›” AND IT DOES NOT NUMBER THE PAGE EITHER: the number arrives with the
        request (`pageNumber`, reserved by the client at the call) and is
        handed to the adoption through `BrowserDispatcher._asking`. Required,
        not defaulted: a server-side default is the second counter [B237]
        removed.
        r*  r   zenewPage needs the page's number in the session (pageNumber), reserved by the client at the call; got zBrowser.newPager¬  rú  ÚtargetIdNç      N@rÕ   )rg   rÁ   rr   r   r  Ú_askingr™  r  r  r9  Ú_wait_for_pagerú   )r5   r<   r
  r  r   r  rÕ   s          r:   r>  z$BrowserContextDispatcher.op_new_pageX  s1  € ð  —’˜LÑ)Ô)ˆÝ�‰<Œ<�sÐ"Ð" f¨q¢j jÝ#Ð#ð �6ðñô ð ð ”,ˆØ�_Š_˜Tœ_Ñ-Ô-ð 	1°Ø”Y—^’^Ð$5Ý$,¨T¬_¸bÑ$AÔ$AÈ2ð $ñ Oô OˆFàˆH�V˜JÔ'¨Ñ0Ô0Ð0ð	1ð 	1ð 	1ñ 	1ô 	1ð 	1ð 	1ð 	1ð 	1ð 	1ð 	1øøøð 	1ð 	1ð 	1ð 	1ð ×%Ò% f¨ZÔ&8À$Ð%ÑGÔGˆØ˜œÐ%Ð%s   Á%AB4Â4B8Â;B8r¡  c                ób   — | j                              |t          | j        |¦  «        d¬¦  «        S )Nr¬  rú  )r  r  r9  r™  r®  s      r:   ri  z&BrowserContextDispatcher._browser_sendw  s2   € ØŒy�~Š~˜g¥x°´ÀÑ'HÔ'HØ&(ð ñ *ô *ð 	*r;   c                ó`   — |                       dd|                     d¦  «        pg i¦  «         dS )u  â›” `expires` IS SECONDS AND -1 MEANS SESSION, not zero and not
        milliseconds. Playwright's client already speaks that convention, so
        the cookies pass through unchanged - but a translation added here
        "helpfully" would silently expire every session cookie in 1970.rn  rB  N©ri  rg   r?   s     r:   rA  z'BrowserContextDispatcher.op_add_cookies{  s@   € ð
 	×ÒÐ/Ø% v§z¢z°)Ñ'<Ô'<Ð'BÀÐCñ	Eô 	Eð 	Eàˆtr;   c                óÐ   ‡— |                       di ¦  «        pi }|                     d¦  «        pg }|                     d¦  «        pg }|rd„ |D ¦   «         Šˆfd„|D ¦   «         }d|iS )NúBrowser.getCookiesrB  Úurlsc                ó,   — g | ]}t          |¦  «        ‘ŒS r[   )r$   )r}   Úus     r:   r�   z7BrowserContextDispatcher.op_cookies.<locals>.<listcomp>‰  s   € Ð0Ð0Ð0 a•h˜q‘k”kÐ0Ð0Ð0r;   c                óL   •‡— g | ]Št          ˆfd „‰D ¦   «         ¦  «        ¯‰‘Œ S )c              3  ób   •K  — | ])}t          ‰                     d ¦  «        pd|¦  «        V — Œ*dS )ÚdomainrÈ   N)r#   rg   )r}   r:  Úcs     €r:   ú	<genexpr>zABrowserContextDispatcher.op_cookies.<locals>.<listcomp>.<genexpr>‹  sP   øè è € ð /ð /Ø"#õ .¨a¯eªe°H©o¬oÐ.CÀÀQÑGÔGð /ð /ð /ð /ð /ð /r;   )Úany)r}   r‚  r¥  s    @€r:   r�   z7BrowserContextDispatcher.op_cookies.<locals>.<listcomp>Š  s^   øø€ ð 0ð 0ð 0˜QÝð /ð /ð /ð /Ø'-ð/ñ /ô /ñ /ô /ð0�qð 0ð 0ð 0r;   ry  )r5   r<   r  rB  r|  r¥  s        @r:   rC  z#BrowserContextDispatcher.op_cookies„  s™   ø€ Ø×#Ò#Ð$8¸"Ñ=Ô=ÐCÀˆØ—*’*˜YÑ'Ô'Ð-¨2ˆØ�zŠz˜&Ñ!Ô!Ð' RˆØð 	0Ø0Ð0¨4Ð0Ñ0Ô0ˆFð0ð 0ð 0ð 0 'ð 0ñ 0ô 0ˆGð ˜7Ð#Ð#r;   c                óˆ   ‡— t          ˆfd„dD ¦   «         ¦  «        rt          d¦  «        ‚|                      di ¦  «         d S )Nc              3  óB   •K  — | ]}‰                      |¦  «        V — Œd S r1   rÎ  )r}   Úkr<   s     €r:   rƒ  z<BrowserContextDispatcher.op_clear_cookies.<locals>.<genexpr>”  s-   øè è € ÐAÐA ˆv�zŠz˜!‰}Œ}ÐAÐAÐAÐAÐAÐAr;   )r{   r�  r  z˜clear_cookies() with a filter is not supported: the engine command clears the whole context, and quietly clearing more than asked is worse than refusingzBrowser.clearCookies)r„  r   ri  r?   s    `r:   rE  z)BrowserContextDispatcher.op_clear_cookies�  s`   ø€ õ
 ÐAÐAÐAÐAÐ&@ÐAÑAÔAÑAÔAð 	5Ý#ð4ñ5ô 5ð 5ð 	×ÒÐ1°2Ñ6Ô6Ð6Øˆtr;   c                óŒ   — |                       d|                     d¦  «        pd|                     d¦  «        pg dœ¦  «         d S )NúBrowser.grantPermissionsÚoriginrÈ   Úpermissions)rŠ  r‹  ry  r?   s     r:   rG  z-BrowserContextDispatcher.op_grant_permissionsœ  s[   € Ø×ÒÐ5Ø&,§j¢j°Ñ&:Ô&:Ð&@¸bØ+1¯:ª:°mÑ+DÔ+DÐ+JÈðLð Lñ	Mô 	Mð 	Mð ˆtr;   c                ó2   — |                       di ¦  «         d S )NzBrowser.resetPermissions)ri  r?   s     r:   rI  z-BrowserContextDispatcher.op_clear_permissions¢  s   € Ø×ÒÐ5°rÑ:Ô:Ð:Øˆtr;   c                ó\   — |                       dd|                     d¦  «        i¦  «         dS )uË   â›” NULL clears the override, and that is not the same as sending
        zeroes: latitude 0 longitude 0 is a real place in the Atlantic, and a
        page that reads it gets a fix instead of a refusal.úBrowser.setGeolocationOverrideÚgeolocationNry  r?   s     r:   rK  z+BrowserContextDispatcher.op_set_geolocation¦  s;   € ð 	×ÒÐ;Ø)¨6¯:ª:°mÑ+DÔ+DÐEñ	Gô 	Gð 	Gàˆtr;   c                ó    — t          d¦  «        ‚)Nz˜set_offline() has no engine command in this Juggler: the protocol declares no offline override, so honouring it would mean lying about the network stater  r?   s     r:   rM  z'BrowserContextDispatcher.op_set_offline®  s   € Ýð1ñ2ô 2ð 	2r;   c                ó    — t          d¦  «        ‚)Nzdset_extra_http_headers() is not wired yet: it needs request interception, which is the network groupr  r?   s     r:   rO  z-BrowserContextDispatcher.op_set_extra_headers´  s   € Ýð7ñ8ô 8ð 	8r;   c                óf   — |                       di ¦  «        pi }|                     d¦  «        pg g dœS )u  â›” COOKIES ONLY, and it says so. Upstream also collects localStorage
        per origin by evaluating in every page; returning just the cookies with
        an empty origins list would look complete and silently lose half the
        state a caller is trying to save.r{  rB  )rB  rm  ry  r—  s      r:   rQ  z)BrowserContextDispatcher.op_storage_state¹  s>   € ð
 ×#Ò#Ð$8¸"Ñ=Ô=ÐCÀˆØ!Ÿ:š: iÑ0Ô0Ð6°BÀ2ÐFÐFÐFr;   c                óL  — | j         €�t          | j        ¦  «        D ]'}	 |                     ¦   «          Œ# t          $ r Y Œ$w xY w|                      d¦  «         |                      ¦   «          | j                             i ¦  «         d S 	 | j	         
                    dd| j         id¬¦  «         n# t          $ r Y nw xY wt          | j        ¦  «        D ]'}	 |                     ¦   «          Œ# t          $ r Y Œ$w xY w|                      d¦  «         |                      ¦   «          d S )NrÌ  zBrowser.removeBrowserContextr8  r  rú  )r™  r…   r[  r1  r>   r8  r,   r  rÍ  r  r  )r5   r<   rÕ   s      r:   rÍ  z!BrowserContextDispatcher.op_closeÁ  sk  € ØŒ?Ð"õ ˜TœZÑ(Ô(ð ð �ðØ×(Ò(Ñ*Ô*Ð*Ð*øÝ ð ð ð Ø�Dðøøøà�IŠI�gÑÔÐØ�LŠL‰NŒNˆNØŒL×!Ò! "Ñ%Ô%Ð%Ø�4ð	ØŒI�NŠNÐ9Ø$6¸¼Ð#HØ+-ð ñ /ô /ð /ð /øõ ð 	ð 	ð 	ØˆDð	øøøõ ˜œÑ$Ô$ð 	ð 	ˆDðØ×$Ò$Ñ&Ô&Ð&Ð&øÝð ð ð Ø�ðøøøà�	Š	�'ÑÔÐØ�Š‰ŒˆØˆts3   Ÿ4´
AÁ AÂ
$B/ Â/
B<Â;B<ÃC+Ã+
C8Ã7C8)r  r;  r+  r   r™  rN  r.   r/   r4  rA   )rõ  rM   r.   r/   r´  )rB   rC   rD   rF   rG   r4   r4  r  r?  rh  rS  rþ  rU  ré  r>  ri  rA  rC  rE  rG  rI  rK  rM  rO  rQ  rÍ  rH   rI   s   @r:   r;  r;  À  s¢  ø€ € € € € Ø€DðØ�=ðà�ðð 	˜iðð 	Ð1ð	ð
 	Ð&ðð 	�<ðð 	Ð*ðð 	Ð2ðð 	Ð2ðð 	Ð.ðð 	Ð&ðð 	Ð5ðð 	Ð*ðð 	Ð1ðð 	)Ð*?ðð  	+Ð,Dð!€Gð&"+ð "+ð "+ð "+ð "+ð "+ðH ð!ð !ð !ñ „Xð!ð.ð .ð .ð .ð:ð ð ð ðð ð ð ð&ð ð ð ð(Gð Gð Gð Gðð ð ð ð&ð &ð &ð &ð>*ð *ð *ð *ðð ð ð ð	$ð 	$ð 	$ð 	$ðð ð ð ðð ð ð ðð ð ð ðð ð ð ð2ð 2ð 2ð 2ð8ð 8ð 8ð 8ð
Gð Gð Gð Gð$ð $ð $ð $ð $ð $ð $ð $r;   r;  c                  óø   ‡ — e Zd ZdZddddœZ	 	 	 dBdCˆ fd„ZdDd„ZdEd„Zej	        dFd„¦   «         Z
dGd#„ZdHd'„ZdId(„ZdJd)„ZdKd*„ZdLd-„ZdMd1„ZdNd3„ZdOd5„ZdPd6„ZdQd8„Zd9ZdRd:„ZdSd;„ZdTdUd>„ZdRd?„ZdRd@„ZdRdA„Zˆ xZS )VÚBrowserDispatcherÚBrowserÚop_new_contextrÍ  r>  )Ú
newContextrÌ  r=  NTÚbrowser_typeú'BrowserTypeDispatcher'r  r   ÚversionrM   Úsession_seedÚmotion_budget_sÚservice_workers_enabledrÚ  r.   r/   c                óÜ  •— || _         || _        || _        || _        || _        i | _        t          j        ¦   «         | _        i | _	        t          j
        ¦   «         | _        t          ¦   «         | _        d| _        t          j
        ¦   «         | _        i | _        t          ¦   «         | _        i | _        t          ¦   «         | _        i | _        i | _        d| _        t          j        | j        ¦  «        | _        d| _        |                     | j        ¦  «         |                     dddid¬¦  «         t9          ¦   «                              |||d	d	d
œ¦  «         g | _        d| _        d S )Né   r   FzBrowser.enableÚattachToDefaultContextTr¬  rú  Úfirefox)r›  r{   ÚbrowserName)r  rž  r™  rœ  r�  Ú	_sessionsr  Ú	ConditionÚ_sessions_readyÚ	_bufferedr  Ú_buffer_lockÚsetÚ_liveÚ
BUFFER_CAPÚ_targets_lockÚ_page_targetsÚ	_adoptingÚ_adopt_errorsÚ_detached_earlyÚ_unansweredÚ_answered_numbersÚ_straysÚ_pages_readyÚ_adopt_enabledr  Ú_route_browser_eventr  r3   r4   Úcontexts)	r5   r6   r™  r  r›  rœ  r�  rž  r9   s	           €r:   r4   zBrowserDispatcher.__init__í  s|  ø€ ð ˆŒ	ð (?ˆÔ$Ø(ˆÔð )ˆÔØ.ˆÔØ)+ˆŒÝ(Ô2Ñ4Ô4ˆÔð0 +-ˆŒÝ%œNÑ,Ô,ˆÔõ ™%œ%ˆŒ
ð ˆŒõ 'œ^Ñ-Ô-ˆÔØ8:ˆÔõ "™eœeˆŒð 46ˆÔõ %(¡E¤EˆÔð 68ˆÔØ13ˆÔð ˆŒÝ%Ô/°Ô0BÑCÔCˆÔØ#ˆÔð 	×Ò˜$Ô3Ñ4Ô4Ð4Ø�	Š	Ð"Ð%=¸tÐ$DØð 	ñ 	ô 	ð 	å‰Œ×Ò˜ Ø%,°iØ)2ð4ð 4ñ	5ô 	5ð 	5ð 9;ˆŒð #ˆÔÐÐr;   rM  c                ó8   — | j         st          d|z  ¦  «        ‚dS )u¥  Refuse a route this browser cannot honour, instead of ignoring it.

        â›” FAIL CLOSED. A route is often a guard - "abort every POST" - and a
        guard that is accepted and never runs is worse than none: the caller
        believes it is protected. The check is Firefox's own:
        `HttpBaseChannel::ShouldIntercept` returns false before asking any
        intercept controller while the pref is off.
        a  %s cannot intercept anything in this browser: it was launched with dom.serviceWorkers.enabled=false, and Firefox only offers a request to the interception hook while that pref is true, so every request would go out unseen. Drop the pref: routes work with service workers enabledN)rž  r   )r5   rM  s     r:   r£  z&BrowserDispatcher.require_interceptiong  s:   € ð Ô+ð 	<Ý#ð4ð 7;ñ	;ñ<ô <ð <ð	<ð 	<r;   r  r
  rr   r   c           	     óf   — t          | j        |||t          |¦  «        | j        | j        ¬¦  «        S )a  The hands of a new page: the session's seed and motion budget, and
        the page's number in the session, which goes into the nonce of every
        act it performs. The number is the page's own (`PageDispatcher.
        number`); nothing here counts pages.)Úactsrœ  r�  )r   r  r	   rœ  r�  )r5   r  rŽ  rÖ   r
  s        r:   r.  z"BrowserDispatcher.actions_for_pagex  s<   € õ �t”y '¨9°hÝ$ VÑ,Ô,Ø$(Ô$5Ø'+Ô';ð=ñ =ô =ð 	=r;   r™  rN  c              #  óö  ‡K  — | j         5  | j                             |d¦  «        dz   | j        |<   ddd¦  «         n# 1 swxY w Y   g Š	 ˆfd„V — | j         5  | j                             |d¦  «        dz
  }|r|| j        |<   n| j                             |d¦  «         ‰D ]\  }}|| j        |<   Œ| j                             ¦   «          ddd¦  «         dS # 1 swxY w Y   dS # | j         5  | j                             |d¦  «        dz
  }|r|| j        |<   n| j                             |d¦  «         ‰D ]\  }}|| j        |<   Œ| j                             ¦   «          ddd¦  «         w # 1 swxY w Y   w xY w)a`  One `Browser.newPage` request in flight for `context_id`, for the
        span of the block. The block calls the yielded function with the
        target the engine answered and the number the client gave; leaving
        the block without it (the request failed) still ends the request, so
        an adoption waiting on it learns it was not this one.r   r   Nc                ó2   •— ‰                      | |f¦  «        S r1   )rþ   )r	  r
  rˆ  s     €r:   r¬  z+BrowserDispatcher._asking.<locals>.<lambda>Ž  s   ø€ ¨F¯MªM¸9ÀfÐ:MÑ,NÔ,N€ r;   )r¬  r±  rg   ro   r²  r´  Ú
notify_all)r5   r™  Úleftr	  r
  rˆ  s        @r:   ru  zBrowserDispatcher._askingƒ  sž  øè è € ð Ôð 	Sð 	SØ+/Ô+;×+?Ò+?À
ÈAÑ+NÔ+NÐQRÑ+RˆDÔ˜ZÑ(ð	Sð 	Sð 	Sñ 	Sô 	Sð 	Sð 	Sð 	Sð 	Sð 	Sð 	Søøøð 	Sð 	Sð 	Sð 	Sàˆð	/ØNÐNÐNÐNÐNÐNÐNàÔ#ð /ð /ØÔ'×+Ò+¨J¸Ñ:Ô:¸QÑ>�Øð ;Ø37�DÔ$ ZÑ0Ð0àÔ$×(Ò(¨°TÑ:Ô:Ð:Ø)/ð ?ð ?Ñ%�I˜vØ8>�DÔ*¨9Ñ5Ð5ØÔ!×,Ò,Ñ.Ô.Ð.ð/ð /ð /ñ /ô /ð /ð /ð /ð /ð /ð /ð /øøøð /ð /ð /ð /ð /ð /ø�Ô#ð /ð /ØÔ'×+Ò+¨J¸Ñ:Ô:¸QÑ>�Øð ;Ø37�DÔ$ ZÑ0Ð0àÔ$×(Ò(¨°TÑ:Ô:Ð:Ø)/ð ?ð ?Ñ%�I˜vØ8>�DÔ*¨9Ñ5Ð5ØÔ!×,Ò,Ñ.Ô.Ð.ð/ð /ð /ñ /ô /ð /ð /ð /ð /ð /ð /øøøð /ð /ð /ð /ð /øøøsS   ‹'>¾AÁAÁC& ÁA2CÃCÃ CÃ&E8Ã.A2E,Å E8Å,E0Å0E8Å3E0Å4E8r	  Úbrowser_context_idr  rh   c                óÜ  — t          j        ¦   «         |z   }| j        5  	 | j                             |d¦  «        }|�|cddd¦  «         S | j                             |¦  «        s1| xj        dz  c_        t          d| j        ¦  «        cddd¦  «         S |t          j        ¦   «         z
  }|dk    rt          d||fz  ¦  «        ‚| j         
                    |¦  «         ŒÁ# 1 swxY w Y   dS )a  The number of a target that attached while a `newPage` of its
        context was unanswered: the number that request named for it, or -
        once every request of the context is answered and none named it - a
        page the site opened, numbered as a stray.TNr   r   zQtarget %s attached while a newPage was in flight, and no answer named it in %.0fs)rþ  r  r´  r²  ro   r±  rg   r³  r
   r   Úwait)r5   r	  r¿  r  r  r
  r¾  s          r:   Ú_number_of_requestedz&BrowserDispatcher._number_of_requestedš  so  € õ ”>Ñ#Ô# gÑ-ˆØÔð 	-ð 	-ð-ØÔ/×3Ò3°I¸tÑDÔD�ØÐ%Ø!ð		-ð 	-ð 	-ð 	-ñ 	-ô 	-ð 	-ð 	-ð
 Ô'×+Ò+Ð,>Ñ?Ô?ð <Ø�L”L AÑ%�L”LÝ'¨¨d¬lÑ;Ô;ð	-ð 	-ð 	-ð 	-ñ 	-ô 	-ð 	-ð 	-ð  ¥$¤.Ñ"2Ô"2Ñ2�Ø˜1’9�9Ý+ð:Ø=FÈÐ<PñQñRô Rð Rð Ô!×&Ò& tÑ,Ô,Ð,ð-ð	-ð 	-ð 	-ð 	-øøøð 	-ð 	-ð 	-ð 	-ð 	-ð 	-s   ž C!Á>C!ÂAC!Ã!C%Ã(C%rL   r<   r   c                óª  — |dk    �r|                      d¦  «        pi }| j        5  |                      d¦  «        | j        |                      d¦  «        <   | j                             ¦   «          d d d ¦  «         n# 1 swxY w Y   |                      d¦  «        dk    ry|                      d¦  «        rd|                      |                      d¦  «        |                      d¦  «        |                      d¦  «        |                      d¦  «        ¦  «         nB|d	k    r<|                      |                      d¦  «        |                      d¦  «        ¦  «         |ru| j        5  || j        vrJ| j         	                    |g ¦  «        }t          |¦  «        | j        k     r|                     ||f¦  «         d d d ¦  «         d S # 1 swxY w Y   d S d S )
NzBrowser.attachedToTargetÚ
targetInfoÚ	sessionIdrs  rÁ   rÕ   r8  ÚopenerIdzBrowser.detachedFromTarget)rg   r¦  r¤  r½  Ú_spawn_adoptionÚ_handle_detachr¨  rª  r§  Ú
setdefaultrW  r«  rþ   )r5   rL   r<   r  ÚinforH  s         r:   r¶  z&BrowserDispatcher._route_browser_event±  sJ  € ØÐ/Ò/Ñ/Ø—:’:˜lÑ+Ô+Ð1¨rˆDØÔ%ð 2ð 2Ø7=·z²zÀ+Ñ7NÔ7N�”˜tŸxšx¨
Ñ3Ô3Ñ4ØÔ$×/Ò/Ñ1Ô1Ð1ð2ð 2ð 2ñ 2ô 2ð 2ð 2ð 2ð 2ð 2ð 2øøøð 2ð 2ð 2ð 2ð �xŠx˜ÑÔ 6Ò)Ð)¨d¯hªh°zÑ.BÔ.BÐ)Ø×$Ò$ T§X¢X¨jÑ%9Ô%9Ø%+§Z¢Z°Ñ%<Ô%<Ø%)§X¢XÐ.@Ñ%AÔ%AØ%)§X¢X¨jÑ%9Ô%9ñ;ô ;ð ;øð Ð3Ò3Ð3Ø×Ò §
¢
¨:Ñ 6Ô 6Ø &§
¢
¨;Ñ 7Ô 7ñ9ô 9ð 9àð 	6ØÔ"ð 6ð 6Ø $¤*Ð,Ð,Øœ>×4Ò4°W¸bÑAÔA�DÝ˜4‘y”y 4¤?Ò2Ð2ØŸš V¨VÐ$4Ñ5Ô5Ð5ð	6ð 6ð 6ñ 6ô 6ð 6ð 6ð 6ð 6ð 6ð 6ð 6øøøð 6ð 6ð 6ð 6ð 6ð 6ð	6ð 	6s%   ¦A
A<Á<B ÂB Å%AGÇG
ÇG
c                óö   — | j         5  | j                             |¦  «         | j                             |d¦  «        pg }ddd¦  «         n# 1 swxY w Y   |D ]\  }} ||||¦  «         Œt          |¦  «        S )u¡  Hand a new consumer the events of its session that it missed.

        â›” DELIVERED IN ORDER AND EXACTLY ONCE. The buffer is dropped as it is
        replayed, under the same lock that fills it, so an event arriving
        during the replay is either in the list or goes to the live path -
        never both, which would announce a frame twice, and never neither,
        which is the bug this exists for.
        N)r¨  rª  rR  r§  ro   rW  )r5   r  r¸  rH  rL   r<   s         r:   r/  zBrowserDispatcher.replayÍ  sÊ   € ð Ôð 	;ð 	;ØŒJ�NŠN˜7Ñ#Ô#Ð#Ø”>×%Ò% g¨tÑ4Ô4Ð:¸ˆDð	;ð 	;ð 	;ñ 	;ô 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð 	;øøøð 	;ð 	;ð 	;ð 	;ð #ð 	-ð 	-‰NˆF�FØˆG�F˜F GÑ,Ô,Ð,Ð,Ý�4‰yŒyÐs   ˆ8AÁAÁAc                ó°   — | j         5  | j                             |d¦  «         | j                             |¦  «         ddd¦  «         dS # 1 swxY w Y   dS )z:Stop holding events for a session nobody is going to read.N)r¨  r§  ro   rª  Údiscard)r5   r  s     r:   ÚforgetzBrowserDispatcher.forgetÝ  s�   € àÔð 	(ð 	(ØŒN×Ò˜w¨Ñ-Ô-Ð-ØŒJ×Ò˜wÑ'Ô'Ð'ð	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(s   ˆ6AÁAÁAc                ó:  — ddl } |j        ¦   «         |z   }| j        5  || j        vrO| |j        ¦   «         z
  }|dk    rt	          d||fz  ¦  «        ‚| j                             |¦  «         || j        v°O| j        |         cddd¦  «         S # 1 swxY w Y   dS )uÈ   â›” The session arrives as an EVENT, not in the reply to `newPage`.
        Polling the dict without waiting on the condition is a race that passes
        on a fast machine and fails on a loaded one.r   Nz.no session was attached for target %s in %.0fs)rþ  r  r¦  r¤  r   rÁ  )r5   r	  r  rþ  r  r¾  s         r:   Úsession_forzBrowserDispatcher.session_forã  s  € ð 	ˆˆˆØ!�4”>Ñ#Ô# gÑ-ˆØÔ!ð 	-ð 	-Ø 4¤>Ð1Ð1Ø . $¤.Ñ"2Ô"2Ñ2�Ø˜1’9�9Ý+ØHØ$ gÐ.ñ/ñ0ô 0ð 0ð Ô$×)Ò)¨$Ñ/Ô/Ð/ð  4¤>Ð1Ð1ð ”> )Ô,ð	-ð 	-ð 	-ð 	-ñ 	-ô 	-ð 	-ð 	-ð 	-ð 	-ð 	-ð 	-øøøð 	-ð 	-ð 	-ð 	-ð 	-ð 	-s   žA%BÂBÂBÚ
session_idÚ	opener_idc           	     ó�  — | j         5  | j        s	 ddd¦  «         dS || j        v s	|| j        v r	 ddd¦  «         dS | j                             |¦  «         |r| j                             |¦  «        nd}|�+|xj        dz  c_        t          |j        |j        ¦  «        }nK|| j	        v s| j
                             |¦  «        rd}n%| xj        dz  c_        t          d| j        ¦  «        }ddd¦  «         n# 1 swxY w Y   t          j        | j        |||||fdd|dd…         z  ¬¦  «        }|                     ¦   «          dS )u%  Claim a fresh engine target and build its page off the reader thread.

        â›” AND DECIDE HOW IT IS NUMBERED HERE, ON THE READER THREAD, because
        this is the only place that sees the targets in the engine's order;
        each adoption then builds on a thread of its own, in no order at all.
        A target with a known opener is that opener's next popup; one that
        some `newPage` answer named, or may still name, takes the number that
        request carried (`_number_of_requested`); anything else is a page the
        site opened with no opener we know, the session's next stray. The
        popups' numbers live in a space of their own (`_behaviour.
        popup_number`), so a popup landing between two `new_page()` calls
        does not shift the second one's number.
        Nr   Tzinvpw-adopt-%sé   )rö  rh  rr  r{   )r¬  rµ  r­  r®  rR  rg   r  r
   r
  r²  r±  r³  r  rƒ  Ú_adopt_targetr…  )r5   r	  rÑ  r¿  rÒ  r  r
  Úthreads           r:   rÇ  z!BrowserDispatcher._spawn_adoptionô  sõ  € ð  Ôð 	:ð 	:ØÔ&ð Øð	:ð 	:ð 	:ñ 	:ô 	:ð 	:ð 	:ð 	:ð ˜DÔ.Ð.Ð.°)¸t¼~Ð2MÐ2MØð		:ð 	:ð 	:ñ 	:ô 	:ð 	:ð 	:ð 	:ð
 ŒN×Ò˜yÑ)Ô)Ð)Ø:CÐM�TÔ'×+Ò+¨IÑ6Ô6Ð6ÈˆFØÐ!ØÐ$Ô$¨Ñ)Ð$Ô$Ý(4°V´]Ø5;Ô5Iñ)Kô )K��à˜tÔ5Ð5Ð5ØÔ%×)Ò)Ð*<Ñ=Ô=ð 6à��à�” Ñ!�”Ý% d¨D¬LÑ9Ô9�ð!	:ð 	:ð 	:ñ 	:ô 	:ð 	:ð 	:ð 	:ð 	:ð 	:ð 	:øøøð 	:ð 	:ð 	:ð 	:õ" Ô!ØÔ%Ø˜ZÐ);¸VÀVÐLØÐ.°¸2¸A¸2´Ñ>ð@ñ @ô @ˆð 	�Š‰Œˆˆˆs   ˆ	C:žC:¾B0C:Ã:C>ÄC>r  úOptional[PageDispatcher]úOptional[int]c           	     óÊ  — 	 |€|                       ||d¬¦  «        }|p|                      |d¬¦  «        }|                      |¦  «        }t          | j        |||||¬¦  «        }|                     dd|j        i¦  «         | j        5  | j         	                    |¦  «         || j
        |<   |j                             |¦  «         || j        v }	|	r| j         	                    |¦  «         | j                             ¦   «          ddd¦  «         n# 1 swxY w Y   |	r|                     ¦   «          dS dS # t"          $ �r¡}
| j        5  | j         	                    |¦  «         | j         	                    |¦  «         |
| j        |<   t'          | j        ¦  «        dk    rQ| j                             t+          t-          | j        ¦  «        ¦  «        ¦  «         t'          | j        ¦  «        dk    °Q	 t/          j        d|›d	|
›�t2          d
¬¦  «         n# t"          $ r Y nw xY w| j                             ¦   «          ddd¦  «         n# 1 swxY w Y   	 |r|                      |¦  «         n# t"          $ r Y nw xY w	 t'          | j        j        ¦  «        dk     r%| j        j                             d|›d	|
›�¦  «         n# t"          $ r Y n
w xY wY d}
~
dS Y d}
~
dS d}
~
ww xY w)a  Build the `PageDispatcher` for one engine target, then announce it.

        A popup goes through EXACTLY the same construction as a `newPage`
        page - lifecycle, injected script, buffered-event replay, cursor acts -
        so it behaves like any other page and carries no observable marker of
        how it was opened. Stealth is preserved by doing nothing special.
        Nrt  rú  r   )r  rÕ   é@   z)invisible_playwright: adoption of target z	 failed: r   )Ú
stacklevelr–  z-Browser.attachedToTarget: adoption of target )rÂ  rÐ  Ú_context_for_popupr¶  r6   r8  rú   r¬  r®  rÍ  r­  r[  rþ   r°  r´  r½  r1  r>   r¯  rW  ro   rŒ  r�  ÚwarningsÚwarnÚRuntimeWarningrÎ  r  r˜  )r5   r	  rÑ  r¿  r  r
  r  rˆ  rÕ   ÚearlyrJ  s              r:   rÕ  zBrowserDispatcher._adopt_target  só  € ð4	Øˆ~Ø×2Ò2ØÐ1¸4ð 3ñ Aô A�à ÐM D×$4Ò$4°YÈÐ$4Ñ$MÔ$MˆGØ×-Ò-Ð.@ÑAÔAˆGÝ! $¤+¨w¸ÀØ"(°ð9ñ 9ô 9ˆDð �LŠL˜ &¨$¬,Ð!7Ñ8Ô8Ð8ØÔ#ð /ð /Ø”×&Ò& yÑ1Ô1Ð1Ø04�Ô" 9Ñ-Ø”×$Ò$ TÑ*Ô*Ð*Ø! TÔ%9Ð9�Øð <ØÔ(×0Ò0°Ñ;Ô;Ð;ØÔ!×,Ò,Ñ.Ô.Ð.ð/ð /ð /ñ /ô /ð /ð /ð /ð /ð /ð /øøøð /ð /ð /ð /ð ð 'Ø×$Ò$Ñ&Ô&Ð&Ð&Ð&ð'ð 'øåð 	ñ 	ð 	ØÔ#ð /ð /Ø”×&Ò& yÑ1Ô1Ð1ØÔ$×,Ò,¨YÑ7Ô7Ð7Ø07�Ô" 9Ñ-Ý˜$Ô,Ñ-Ô-°Ò2Ð2ØÔ&×*Ò*­4µ°TÔ5GÑ0HÔ0HÑ+IÔ+IÑJÔJÐJõ ˜$Ô,Ñ-Ô-°Ò2Ð2ðÝ”M�Mà$˜9˜9 g gð/Ý0>È1ðNñ Nô Nð Nð Nøõ !ð ð ð Ø�DðøøøàÔ!×,Ò,Ñ.Ô.Ð.ð!/ð /ð /ñ /ô /ð /ð /ð /ð /ð /ð /øøøð /ð /ð /ð /ð"Øð ,Ø—K’K 
Ñ+Ô+Ð+øøÝð ð ð Ø�ðøøøðÝ�t”yÔ/Ñ0Ô0°2Ò5Ð5Ø”IÔ,×3Ò3Ð3à(1¨	¨	°7°7ð<ñ=ô =ð =øøõ ð ð ð Ø�ðøøøè è è è è è Ø�����øøøøð;	øøøsÏ   ‚BD6 ÂA=DÄD6 ÄDÄD6 ÄDÄD6 Ä6K"ÅKÅB(I	Ç1"HÈI	È
H!ÈI	È H!È!I	È=KÉ	I	ÉKÉI	ÉKÉI-É,KÉ-
I:É7KÉ9I:É:KÉ>AKË KË
KËKËKËKËK"r  c                ó‚   — t          | j        ¦  «        D ]}|j        |k    r|j        s|c S Œt	          d|›d�¦  «        ‚)zÐThe context an engine target belongs to. The DEFAULT context (a
        persistent launch) is addressed by ABSENCE - `context_id None` - which
        is also what the event omits, so the two Nones meet here.z+popup arrived for unknown browserContextId z.: its context was closed or never existed here)r…   r·  r™  Údisposedr   )r5   r¿  rˆ  s      r:   rÜ  z$BrowserDispatcher._context_for_popup\  sg   € õ
 ˜DœMÑ*Ô*ð 	ð 	ˆGð Ô!Ð%7Ò7Ð7ÀÔ@PÐ7Ø���øÝÐà.@Ð.@Ð.@ðCñDô Dð 	Dr;   r¶  c                ó‚  — t          j        ¦   «         |z   }| j        5  	 | j                             |¦  «        }|�|cddd¦  «         S | j                             |d¦  «        }|�|‚|t          j        ¦   «         z
  }|dk    rt          d||fz  ¦  «        ‚| j                             |¦  «         Œ”# 1 swxY w Y   dS )zŽThe `newPage` half of the single creation path: the adoption thread
        owns the build, this only waits for it (or re-raises its failure).TNr   z‚no page was attached for target %s in %.0fs: the engine answered Browser.newPage but never emitted Browser.attachedToTarget for it)	rþ  r  r´  r­  rg   r¯  ro   r   rÁ  )r5   r	  r  r  rÕ   rJ  r¾  s          r:   rv  z BrowserDispatcher._wait_for_pagej  s-  € õ ”>Ñ#Ô# gÑ-ˆØÔð 	-ð 	-ð-ØÔ)×-Ò-¨iÑ8Ô8�ØÐ#Øð		-ð 	-ð 	-ð 	-ñ 	-ô 	-ð 	-ð 	-ð
 Ô,×0Ò0°¸DÑAÔA�ØÐ&Ø!�MØ¥$¤.Ñ"2Ô"2Ñ2�Ø˜1’9�9Ý+ð:à=FÈÐ<PñQñRô Rð Rð Ô!×&Ò& tÑ,Ô,Ð,ð-ð	-ð 	-ð 	-ð 	-øøøð 	-ð 	-ð 	-ð 	-ð 	-ð 	-s   žB4Á
A*B4Â4B8Â;B8c                óÜ  — |sdS | j         5  | j                             |¦  «        }|€1|| j        v r(| j                             |¦  «         	 ddd¦  «         dS ddd¦  «         n# 1 swxY w Y   |€S| j        5  | j                             |d¦  «         ddd¦  «         n# 1 swxY w Y   |r|  	                    |¦  «         dS 	 | 
                    ¦   «          dS # t          $ r Y dS w xY w)zŒThe engine reports a target gone: an engine-side close (or a popup
        that died before it finished attaching). Never blocks the reader.N)r¬  r­  rg   r®  r°  rR  r¦  r¤  ro   rÎ  r1  r>   )r5   r	  rÑ  rÕ   s       r:   rÈ  z BrowserDispatcher._handle_detach~  sµ  € ð ð 	ØˆFØÔð 	ð 	ØÔ%×)Ò)¨)Ñ4Ô4ˆDØˆ| 	¨T¬^Ð ;Ð ;ØÔ$×(Ò(¨Ñ3Ô3Ð3Øð		ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð
 ˆ<ð Ô%ð 4ð 4Ø”×"Ò" 9¨dÑ3Ô3Ð3ð4ð 4ð 4ñ 4ô 4ð 4ð 4ð 4ð 4ð 4ð 4øøøð 4ð 4ð 4ð 4àð (Ø—’˜JÑ'Ô'Ð'ØˆFð	Ø× Ò Ñ"Ô"Ð"Ð"Ð"øÝð 	ð 	ð 	ØˆDˆDð	øøøs6   ŒAA&Á&A*Á-A*Á:B"Â"B&Â)B&ÃC Ã
C+Ã*C+rÕ   c                óÞ  — | j         5  | j                             |j        ¦  «        |u r| j        |j        = 	 |j        j                             |¦  «         n# t          $ r Y nw xY wddd¦  «         n# 1 swxY w Y   | j        5  | j	                             |j        ¦  «        |j
        k    r| j	        |j        = ddd¦  «         n# 1 swxY w Y   |                      |j
        ¦  «         dS )u1  Forget a page everywhere this browser keeps it.

        â›” CALLED FROM ONE PLACE, `PageDispatcher.announce_closed`, and that
        is the point. A page ends four ways - `page.close()`, `context.close()`,
        the engine's detach, and a detach that beat its own adoption - and each
        of them used to repeat this bookkeeping next to its call to
        `announce_closed`, so a fifth way would have had to remember both. The
        once-guard there already knows when a page is over; the registries
        hang off it like the listeners do.
        N)r¬  r­  rg   r	  rˆ  r[  r  Ú
ValueErrorr¦  r¤  r  rÎ  )r5   rÕ   s     r:   r3  zBrowserDispatcher._page_over–  su  € ð Ôð 	ð 	ØÔ!×%Ò% d¤nÑ5Ô5¸Ð=Ð=ØÔ& t¤~Ð6ðØ”Ô"×)Ò)¨$Ñ/Ô/Ð/Ð/øÝð ð ð Ø�ðøøøð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð Ô!ð 	3ð 	3ØŒ~×!Ò! $¤.Ñ1Ô1°T´\ÒAÐAØ”N 4¤>Ð2ð	3ð 	3ð 	3ñ 	3ô 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3øøøð 	3ð 	3ð 	3ð 	3ð 	�Š�D”LÑ!Ô!Ð!Ð!Ð!sF   ˆ/A4¸AÁA4Á
A%Á"A4Á$A%Á%A4Á4A8Á;A8Â6CÃCÃC))ÚlocalezBrowser.setLocaleOverriderç  )Ú
timezoneIdzBrowser.setTimezoneOverriderè  )rè  zBrowser.setColorSchemerè  )ré  zBrowser.setReducedMotionré  )rê  zBrowser.setForcedColorsrê  )Ú	userAgentzBrowser.setUserAgentOverrideré  c                ó*  — | j                              dddid¬¦  «        }|d         }|                      ||¦  «         t          | j        | ||¦  «        }| j                             |¦  «         |                      dd|j        i¦  «         d|j        iS )NzBrowser.createBrowserContextÚremoveOnDetachTr¬  rú  r8  rˆ  )	r  r  Ú_apply_context_optionsr;  r6   r·  rþ   r8  rú   )r5   r<   r  r™  rˆ  s        r:   r—  z BrowserDispatcher.op_new_contextÜ  s¤   € Ø”—’Ð >Ø!1°4Ð 8À"ð  ñ Fô FˆàÐ.Ô/ˆ
Ø×#Ò# J°Ñ7Ô7Ð7Ý*¨4¬;¸¸fØ+5ñ7ô 7ˆàŒ×Ò˜WÑ%Ô%Ð%Ø�	Š	�)˜i¨¬Ð9Ñ:Ô:Ð:Ø˜7œ?Ð+Ð+r;   c                óü  — |                      d¦  «        dk    rt          d¦  «        ‚| j        D ][\  }}}|                      |¦  «        }|dv rŒ |dk    rt          j        |¦  «        j        }|                      |d|||id¬¦  «         Œ\|                      d	¦  «        rt	 t          |d	         ¦  «                             ¦   «         }n$# t          $ r}t          d
|z  ¦  «        ‚d}~ww xY w|                      dt          ||¬¦  «        d¬¦  «         |                      d¦  «        }	|	r|                      d||	dœd¬¦  «         |                      d¦  «        r|                      d|ddœd¬¦  «         |                      d¦  «        }
|
r|                      d||
dœd¬¦  «         |                      d¦  «        }|r|                      d||dœd¬¦  «         |                      d¦  «        r|                      d|ddœd¬¦  «         |                      d¦  «        r|                      d|dd œd¬¦  «         |                      d!¦  «        d"u r|                      d#|dd$œd¬¦  «         |                      d%¦  «        r|                      d&|dd'œd¬¦  «         |                      d(¦  «        }|r|                      d)|d*|d+œd¬¦  «         |                      d,¦  «        }|r•d-|d.         |d/         d0œi}|                      d1¦  «        }|r|d.         |d/         d0œ|d2<   |                      d3¦  «        r|d3         |d3<   |                      d4¦  «        rd|d4<   |                      d5||d6œd¬¦  «         dS dS )7u  Push the options the caller asked for into the engine.

        â›” BEFORE THE FIRST PAGE EXISTS, and that ordering is the whole point:
        these are defaults a new page INHERITS, so applying them after
        `newPage` would leave the first page - the only one most sessions ever
        open - without them.

        â›” AND `no-preference` IS SENT, NOT SKIPPED. It looks like an "unset"
        value and it is not: the client omits the field entirely when the
        caller said nothing, so the string only ever arrives because somebody
        asked for it by name. Treating it as absent would mean a context that
        explicitly asks to express no preference silently keeps whatever the
        profile declared - the one case where the caller was most explicit.
        ÚserviceWorkersÚblocka  service_workers="block" is not supported: Playwright blocks them with a page script that any page can read back, and this engine has no switch for one context. Leave it out: route() holds requests with service workers allowed, except the ones a page's own service worker answers)NrÈ   rç  r8  r  rú  Úproxyz,new_context(proxy=...) cannot be applied: %sNzBrowser.setContextProxy)r8  ÚextraHTTPHeaderszBrowser.setExtraHTTPHeaders)r8  rM  ÚofflinezBrowser.setOnlineOverride)r8  Úoverrider�  rŽ  )r8  r�  ÚhttpCredentialszBrowser.setHTTPCredentials)r8  ÚcredentialsÚignoreHTTPSErrorszBrowser.setIgnoreHTTPSErrorsT)r8  rö  Ú	bypassCSPzBrowser.setBypassCSP)r8  r÷  ÚjavaScriptEnabledFzBrowser.setJavaScriptDisabled)r8  ÚjavaScriptDisabledÚhasTouchzBrowser.setTouchOverride)r8  rú  r‹  r‰  Ú*)r8  rŠ  r‹  r!  r(  r%  r&  r$  ÚscreenÚ
screenSizeÚdeviceScaleFactorÚisMobilezBrowser.setDefaultViewport)r8  r!  )rg   r   ÚENGINE_OPTIONSr!   ÚofÚaccept_languagesÚ_context_sendr"   Úas_engine_commandræ  rn   )r5   r™  r<   r{   r¡  Úfieldr|   rð  ÚexcrM  r�  rõ  r‹  r!  r¥  rü  s                   r:   rì  z(BrowserDispatcher._apply_context_optionsç  sE  € ð4 �:Š:Ð&Ñ'Ô'¨7Ò2Ð2Ý#ð?ñ@ô @ð @ð %)Ô$7ð 	'ð 	'Ñ ˆD�'˜5Ø—J’J˜tÑ$Ô$ˆEØ˜
Ð"Ð"ØØ�xÒÐõ$ &Ô(¨Ñ/Ô/Ô@�Ø×Ò˜wØ.°
¸EÀ5ÐIØ#%ð ñ 'ô 'ð 'ð 'ð �:Š:�gÑÔð 	'ðJÝ# F¨7¤OÑ4Ô4×FÒFÑHÔH��øÝð Jð Jð JÝ'ØBÀSÑHñJô Jð JøøøøðJøøøð ×ÒÐ8Ý ¸
ÐCÑCÔCØ#%ð ñ 'ô 'ð 'ð —*’*Ð/Ñ0Ô0ˆØð 	=Ø×ÒÐ<Ø0:Ø'.ð0ð 0Ø9;ð ñ =ô =ð =ð �:Š:�iÑ Ô ð 	@Ø×ÒÐ:Ø0:Ø(1ð3ð 3Ø<>ð ñ @ô @ð @ð —j’j Ñ/Ô/ˆØð 	EØ×ÒÐ?Ø0:Ø+6ð8ð 8ØACð ñ Eô Eð Eð —j’jÐ!2Ñ3Ô3ˆØð 	EØ×ÒÐ;Ø0:Ø+6ð8ð 8ØACð ñ Eô Eð Eð �:Š:Ð)Ñ*Ô*ð 	DØ×ÒÐ=Ø0:Ø15ð7ð 7Ø@Bð ñ Dô Dð Dð �:Š:�kÑ"Ô"ð 	<Ø×ÒÐ5Ø0:Ø)-ð/ð /Ø8:ð ñ <ô <ð <ð �:Š:Ð)Ñ*Ô*¨eÐ3Ð3Ø×ÒÐ>Ø0:Ø26ð8ð 8ØACð ñ Eô Eð Eð �:Š:�jÑ!Ô!ð 	;Ø×ÒÐ9Ø0:Ø(,ð.ð .Ø79ð ñ ;ô ;ð ;ð —j’j Ñ/Ô/ˆØð 	Eð ×ÒÐ9Ø0:ÀcØ+6ð8ð 8ØACð ñ Eô Eð Eð —:’:˜jÑ)Ô)ˆØð 	=ð
 '5Ø! 'Ô*°h¸xÔ6Hð7Jð 7Jð &KˆFà—Z’Z Ñ)Ô)ˆFØð DØ17¸´Ø28¸Ô2Bð(Dð (D��|Ñ$à�zŠzÐ-Ñ.Ô.ð JØ.4Ð5HÔ.I�Ð*Ñ+Ø�zŠz˜*Ñ%Ô%ð *Ø%)��zÑ"Ø×ÒÐ;Ø0:Ø(.ð0ð 0Ø9;ð ñ =ô =ð =ð =ð =ð	=ð 	=s   Â"'C
 Ã

C+ÃC&Ã&C+r  r¡  c                ó~   — | j                              |t          |                     d¦  «        |¦  «        |¬¦  «        S )zÒA `Browser.*` command about one context. The literal dicts above
        carry `browserContextId` with the id, or with None for the default
        context; `_address` turns None into the absence Juggler reads.r8  rú  )r  r  r9  rg   )r5   r¡  r<   r  s       r:   r  zBrowserDispatcher._context_sendy  s@   € ð Œy�~Š~˜gÝ& v§z¢zÐ2DÑ'EÔ'EÀvÑNÔNØ&-ð ñ /ô /ð 	/r;   c                óÜ   — |                       d|¦  «         t          | j        | |d¦  «        }| j                             |¦  «         |                      dd|j        i¦  «         d|j        iS )u;  The context whose state IS the profile's: userContextId 0, the one
        `launchPersistentContext` promises.

        â›” UNTIL 0.12.0 THE PERSISTENT PATH HANDED BACK `op_new_context`, AND A
        `profile_dir=` KEPT NOTHING. `Browser.createBrowserContext` makes a
        container, a fresh userContextId, and Juggler's `destroy()` calls
        `ContextualIdentityService.remove` on it, which deletes the container's
        cookies and storage together with the identity. Every cookie and every
        localStorage entry a session wrote lived in a container that died with
        the session: `cookies.sqlite` in the profile stayed at zero rows, and
        the second session of the same profile started logged out. Measured
        2026-09-05 against the published 0.12.0, cookies and localStorage both,
        while the docs promised "logging in once instead of every run".

        Upstream's persistent context is the DEFAULT one, addressed by omitting
        `browserContextId`. That is what this returns, with the same options
        applied the same way.
        Nrˆ  )rì  r;  r6   r·  rþ   r8  rú   )r5   r<   rˆ  s      r:   Úop_default_contextz$BrowserDispatcher.op_default_context�  sm   € ð& 	×#Ò# D¨&Ñ1Ô1Ð1Ý*¨4¬;¸¸fÀdÑKÔKˆØŒ×Ò˜WÑ%Ô%Ð%Ø�	Š	�)˜i¨¬Ð9Ñ:Ô:Ð:Ø˜7œ?Ð+Ð+r;   c                óð   — t          |¦  «        }|                     dd ¦  «        }|                      |¦  «        }|d         d         }| j                             |¦  «                             d|i¦  «        S )Nr*  rˆ  r,  )rn   ro   r—  r6   Úobjectr>  )r5   r<   r
  rˆ  r,  s        r:   r>  zBrowserDispatcher.op_new_pageš  sk   € Ý�f‘”ˆØ—’˜L¨$Ñ/Ô/ˆØ×%Ò% fÑ-Ô-ˆØ�yÔ! &Ô)ˆØŒ{×!Ò! $Ñ'Ô'×3Ò3°\À6Ð4JÑKÔKÐKr;   c                ó®   — 	 | j                              ¦   «          n# t          $ r Y nw xY w|                      d¦  «         |                      ¦   «          d S )NrÌ  )r  rÌ  r>   r8  r,   r?   s     r:   rÍ  zBrowserDispatcher.op_close¡  s`   € ð	ØŒI�OŠOÑÔÐÐøÝð 	ð 	ð 	ØˆDð	øøøà�	Š	�'ÑÔÐØ�Š‰ŒˆØˆts   ‚ œ
)¨))NNT)r™  rš  r  r   r›  rM   rœ  r   r�  r   rž  rÚ  r.   r/   )rM  rM   r.   r/   )r  rM   r
  rr   r.   r   )r™  rN  )r	  rM   r¿  rN  r  rh   r.   rr   r5  )r  rM   r.   rr   )r  rM   r.   r/   )r	  rM   r  rh   r.   rM   )
r	  rM   rÑ  rN  r¿  rN  rÒ  rN  r.   r/   )r	  rM   rÑ  rN  r¿  rN  r  r×  r
  rØ  r.   r/   )r¿  rN  r.   r  )r	  rM   r  rh   r.   r¶  )r	  rN  rÑ  rN  r.   r/   )rÕ   r¶  r.   r/   rA   )r™  rN  r<   r   r.   r/   )r  )r¡  rM   r<   r   r  rh   r.   r   )rB   rC   rD   rF   rG   r4   r£  r.  Ú
contextlibÚcontextmanagerru  rÂ  r¶  r/  rÎ  rÐ  rÇ  rÕ  rÜ  rv  rÈ  r3  r   r—  rì  r  r	  r>  rÍ  rH   rI   s   @r:   r•  r•  è  s+  ø€ € € € € Ø€DØ-¸
Ø'ð)ð )€Gð ?CØ(,Ø15ðx#ð x#ð x#ð x#ð x#ð x#ð x#ðt<ð <ð <ð <ð"	=ð 	=ð 	=ð 	=ð Ôð/ð /ð /ñ Ôð/ð,-ð -ð -ð -ð.6ð 6ð 6ð 6ð8ð ð ð ð (ð (ð (ð (ð-ð -ð -ð -ð"%ð %ð %ð %ðN?ð ?ð ?ð ?ðBDð Dð Dð Dð-ð -ð -ð -ð(ð ð ð ð0"ð "ð "ð "ðV€Nð6	,ð 	,ð 	,ð 	,ðP=ð P=ð P=ð P=ðd/ð /ð /ð /ð /ð,ð ,ð ,ð ,ð2Lð Lð Lð Lðð ð ð ð ð ð ð r;   r•  c                  ó@   ‡ — e Zd ZdZdddœZddˆ fd
„Zdd„Zdd„Zˆ xZS )ÚBrowserTypeDispatcherÚBrowserTypeÚ	op_launchÚop_launch_persistent)ÚlaunchÚlaunchPersistentContextrÈ   Úexecutable_pathrM   r.   r/   c                óT   •— t          ¦   «                              |d |ddœ¦  «         d S )Nr¢  )ÚexecutablePathr{   ©r3   r4   )r5   r6   r  r9   s      €r:   r4   zBrowserTypeDispatcher.__init__±  s=   ø€ Ý‰Œ×Ò˜ Ø,;Ø"+ð-ð -ñ	.ô 	.ð 	.ð 	.ð 	.r;   r<   r   r   c                ó*  — |                      d¦  «        }|st          d¦  «        ‚|                      t          ||¬¦  «        ¦  «        }| j                             |d         d         ¦  «        }|d         |                     |¦  «        d         dœS )uL  A browser whose profile SURVIVES the session, plus its context.

        â›” THE PROFILE IS THE CALLER'S AND IS NOT WIPED. `launch()` makes a
        throwaway directory; here the caller names one they intend to reuse, so
        writing `user.js` into it on every launch is correct - the prefs must be
        re-applied - but deleting anything in it is not.

        â›” BOTH COME BACK, AND THE LINE THAT USED TO BE HERE SAID OTHERWISE.
        It read "the CONTEXT comes back, NOT the browser ... `_browser_type.py`
        reads `context` from the answer". The client reads BOTH: `result
        ["browser"]` first, to attach it to the browser type, and then
        `result["context"]`. Returning only the context raised `KeyError:
        'browser'` on every `profile_dir=` session - measured 2026-08-30
        against the published 0.8.0, so it shipped.

        It is this project's most repeated defect, in its purest form: the
        assertion was written against the COMMENT rather than against the code
        it describes, and no test opened a persistent context to find out.
        ÚuserDataDirz—launch_persistent_context() needs a userDataDir: without one it is just launch(), and the profile it is supposed to keep would be a temporary directory)r  r  r,  rˆ  )r  rˆ  )rg   r   r  rn   r6   r  r	  )r5   r<   r’   Úbrowser_channelr  s        r:   r  z*BrowserTypeDispatcher.op_launch_persistent¶  s£   € ð( —J’J˜}Ñ-Ô-ˆ	Øð 	2Ý#ð1ñ2ô 2ð 2ð Ÿ.š.­¨fÀ)Ð)LÑ)LÔ)LÑMÔMˆØ”+×$Ò$ _°YÔ%?ÀÔ%GÑHÔHˆØ*¨9Ô5Ø"×5Ò5°fÑ=Ô=¸iÔHðJð Jð 	Jr;   c                ó8  ‡— |                      d¦  «        }|st          d¦  «        ‚t          |                      d¦  «        ¦  «        }|                      d¦  «        d u }|                      d¦  «        pt          j        d¬¦  «        Št          |                      d¦  «        pi ¦  «        \  }}}t          ‰|¦  «         |                      d¦  «        }d	}	t          |t          t          f¦  «        r|d
k    rt          |¦  «        dz  }	d }
|                      d¦  «        rM	 t          |d         ¦  «                             ¦   «         }
n$# t          $ r}t          d|z  ¦  «        ‚d }~ww xY wt          j        |‰t          |                      dd¦  «        ¦  «        ||                      d¦  «        pg |	¬¦  «        }| j                             |j        ¦  «         |
�R	 |                     d|
d¬¦  «         n8# t(          $ r+}|                     ¦   «          t          d|z  ¦  «        ‚d }~ww xY w|r| j                             ˆfd„¦  «         t+          |¦  «        }t-          | j        | |||||                      d¦  «        du¬¦  «        }d|j        iS )Nr  zolaunch needs an executablePath: invisible_playwright pins its own engine and never downloads one at launch timeÚenvr  Úinvisible_profile_©ÚprefixÚfirefoxUserPrefsr  rt  r   rm   rð  z'launch(proxy=...) cannot be applied: %sÚheadlessTrh  )r#  r  Ú
argv_extraÚready_timeoutzBrowser.setBrowserProxyr  rú  z`the engine refused the proxy, so the browser was closed rather than left running without one: %sc                 ó"   •— t          ‰ ¦  «        S r1   )r'   )Úprofiles   €r:   r¬  z1BrowserTypeDispatcher.op_launch.<locals>.<lambda>?  s   ø€ ­O¸GÑ,DÔ,D€ r;   zdom.serviceWorkers.enabledF)rœ  r�  rž  r  )rg   r   rƒ   ÚtempfileÚmkdtemprv   r(   r‹   rr   rh   r"   r  ræ  r¨  r  rÚ  r6   Úon_shutdownrÌ  r  r  r&   r•  rú   )r5   r<   Ú
executabler  rí  rj   rœ  r�  r¥  Úreadyrð  r  r  r›  r  r'  s                  @r:   r  zBrowserTypeDispatcher.op_launchÕ  s  ø€ Ø—Z’ZÐ 0Ñ1Ô1ˆ
Øð 	EÝ#ðDñEô Eð Eõ6 " &§*¢*¨UÑ"3Ô"3Ñ4Ô4ˆð �zŠz˜-Ñ(Ô(¨DÐ0ˆØ—*’*˜]Ñ+Ô+ð )­xÔ/?Ø'ð0)ñ 0)ô 0)ˆõ 0CØ�JŠJÐ)Ñ*Ô*Ð0¨bñ02ô 02Ñ,ˆˆ|˜_å�w Ñ&Ô&Ð&ð —’˜IÑ&Ô&ˆØˆÝ�f�s¥E˜lÑ+Ô+ð 	+°¸²
°
Ý˜&‘M”M FÑ*ˆEð ˆØ�:Š:�gÑÔð 	4ð4Ý# F¨7¤OÑ4Ô4×FÒFÑHÔH��øÝð 4ð 4ð 4Ý'ð )-Ø/2ñ)3ñ 4ô 4ð 4øøøøð4øøøõ Œ~˜j¨'Ý'+¨F¯JªJ°zÀ4Ñ,HÔ,HÑ'IÔ'IØ"%°&·*²*¸VÑ2DÔ2DÐ2JÈØ,1ð3ñ 3ô 3ˆð 	Œ×Ò ¤
Ñ+Ô+Ð+ð ÐðFØ—	’	Ð3°UÀB�	ÑGÔGÐGÐGøÝ ð Fð Fð FØ—
’
‘”�Ý'ð?ØADñEñFô Fð FøøøøðFøøøð
 ð 	Fð ŒK×#Ò#Ð$DÐ$DÐ$DÐ$DÑEÔEÐEÝ 
Ñ+Ô+ˆÝ#ØŒK˜˜t W¸<Ø+Ø$)§I¢IØ,ñ%.ô %.Ø5:ð%;ð<ñ <ô <ˆð
 ˜7œ?Ð+Ð+s0   Ä&'E Å
E/ÅE*Å*E/Ç$G= Ç=
H2È&H-È-H2r1  )r  rM   r.   r/   rA   )	rB   rC   rD   rF   rG   r4   r  r  rH   rI   s   @r:   r  r  «  s�   ø€ € € € € Ø€DØ$Ø#9ðð €Gð.ð .ð .ð .ð .ð .ð .ð
Jð Jð Jð Jð>q,ð q,ð q,ð q,ð q,ð q,ð q,ð q,r;   r  c                  ó   — e Zd ZdZi ZdS )ÚPlaywrightDispatcherÚ
PlaywrightN)rB   rC   rD   rF   rG   r[   r;   r:   r.  r.  P  s   € € € € € Ø€DØ€G€G€Gr;   r.  c                  ó6   ‡ — e Zd ZdZdddœZdˆ fd„Zdd
„Zˆ xZS )ÚLocalUtilsDispatcherÚ
LocalUtilsré  )ÚaddStackToTracingNoReplyÚtraceDiscardedr.   r/   c                óV   •— t          ¦   «                              |d dg id¬¦  «         d S )NÚdeviceDescriptorsÚ
localUtils©r,  r  )r5   r6   r9   s     €r:   r4   zLocalUtilsDispatcher.__init__Z  s=   ø€ Ý‰Œ×Ò˜ Ð(;¸RÐ'@Ø*ð 	ñ 	,ô 	,ð 	,ð 	,ð 	,r;   r<   r   r   c                ó   — d S r1   r[   r?   s     r:   ré  zLocalUtilsDispatcher.op_noop^  r/  r;   r@   rA   )rB   rC   rD   rF   rG   r4   ré  rH   rI   s   @r:   r1  r1  U  sh   ø€ € € € € Ø€DØ+4Ø!*ð,ð ,€Gð,ð ,ð ,ð ,ð ,ð ,ðð ð ð ð ð ð ð r;   r1  c                  ó:   — e Zd ZdZdd„ZddiZdd„Zdd„Zdd„ZdS )ÚJugglerServerz8The whole Playwright protocol, answered in this process.r,  rM   r.   r   c                ób   — | j                              |¦  «        }|€t          d|z  ¦  «        ‚|S )Nzno object %r)Ú_objectsrg   r   )r5   r,  Úobjs      r:   r  zJugglerServer.objecte  s4   € ØŒm×Ò Ñ%Ô%ˆØˆ;Ý# N°TÑ$9Ñ:Ô:Ð:Øˆ
r;   Ú
initializeÚop_initializer�   r   c                óv  ‡— t           j                             |                     d¦  «        pd                     dd¦  «        ¦  «        }|st          d¦  «        ‚t          | dd¦  «        Š‰€4t          j        d¬	¦  «        Š‰| _	        |  
                    ˆfd
„¦  «         t           j                             t          j        ‰¬¦  «        |¦  «        }t          |d¦  «        5 }|                     t          j        |                     d¦  «        pd¦  «        ¦  «         ddd¦  «         n# 1 swxY w Y   |S )uö  A `setInputFiles` payload written to a file, and that file's path.

        Each payload gets a folder of its own, so the file keeps exactly the
        name the caller gave it - that is the `File.name` the page reads -
        and two payloads with the same name do not overwrite each other. The
        name is reduced to its last component: a payload is content, and its
        name must not choose where on this machine the content is written.

        â›” THE FILES LIVE AS LONG AS THE SESSION, not as long as the call. A
        page reads an uploaded file when it SUBMITS it, which can be minutes
        after `set_input_files` returned; removing it at the end of the call
        would leave the input holding a file that no longer exists.
        r{   rÈ   ú\ú/z;a file payload needs a name: the page reads it as File.nameÚ_upload_rootNÚinvisible_upload_r   c                 ó0   •— t          j        ‰ d¬¦  «        S )NT)Úignore_errors)ÚshutilÚrmtree)Úroots   €r:   r¬  z,JugglerServer.stage_upload.<locals>.<lambda>‰  s   ø€ ¥V¤]°4ÀtÐ%LÑ%LÔ%L€ r;   )ÚdirÚwbÚbuffer)r€   r  Úbasenamerg   Úreplacer   r  r(  r)  rD  r*  ÚjoinÚopenÚwriter­  Ú	b64decode)r5   r�   r{   r  r   rJ  s        @r:   r�   zJugglerServer.stage_uploads  st  ø€ õ Œw×Ò §¢¨VÑ!4Ô!4Ð!:¸× CÒ CÀDÈ#Ñ NÔ NÑOÔOˆØð 	OÝ#ØMñOô Oð Oå�t˜^¨TÑ2Ô2ˆØˆ<ÝÔ#Ð+>Ð?Ñ?Ô?ˆDØ $ˆDÔØ×ÒÐLÐLÐLÐLÑMÔMÐMÝŒw�|Š|�HÔ,°Ð6Ñ6Ô6¸Ñ=Ô=ˆÝ�$˜ÑÔð 	E Ø�IŠI•fÔ& w§{¢{°8Ñ'<Ô'<Ð'BÀÑCÔCÑDÔDÐDð	Eð 	Eð 	Eñ 	Eô 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eøøøð 	Eð 	Eð 	Eð 	Eàˆs   Ã%=D.Ä.D2Ä5D2rL   r<   r   c                óà   — | j                              |¦  «        }|€:t          dd                     t	          | j         ¦  «        ¦  «        ›d|›�¦  «        ‚ t          | |¦  «        |¦  «        S )Nzthe root only answers z, z, not )rG   rg   r   rP  r�  r  )r5   rL   r<   r{   s       r:   Úhandle_rootzJugglerServer.handle_root�  su   € ØŒ|×Ò Ñ'Ô'ˆØˆ<Ý#Ð#à—9’9�V D¤LÑ1Ô1Ñ2Ô2Ð2Ð2°F°Fð<ñ=ô =ð =ð #�w�t˜TÑ"Ô" 6Ñ*Ô*Ð*r;   c                ó�   — t          | ¦  «        }t          | ¦  «        }t          | d |j        |j        dœd¬¦  «        }d|j        iS )N)r¢  Úutilsr/  r8  Ú
playwright)r  r1  r.  rú   )r5   r<   r™  rW  rX  s        r:   r@  zJugglerServer.op_initialize—  s^   € õ -¨TÑ2Ô2ˆÝ$ TÑ*Ô*ˆÝ)Ø�$ LÔ$8Ø"'¤-ð1ð 1àðñ ô ˆ
ð ˜jÔ0Ð1Ð1r;   N)r,  rM   r.   r   )r�   r   r.   rM   rR   rA   )	rB   rC   rD   rE   r  rG   r�   rU  r@  r[   r;   r:   r;  r;  b  sv   € € € € € ØBÐBðð ð ð ð ˜_Ð-€Gðð ð ð ð8+ð +ð +ð +ð
2ð 
2ð 
2ð 
2ð 
2ð 
2r;   r;  )r<   r   r.   rd   )rj   r   r.   rk   )r.   rw   )r6   r„   r<   r   r.   r…   )r™  rN  r<   r   r.   r   )TrE   Ú
__future__r   r­  r  r€   r$  rH  r(  r  rþ  rÝ  Útypingr   r   r   r   Ú
_behaviourr	   r
   rÈ   r   r¨  ræ   r   Ú
dispatcherr   r   r   rÖ   r   r>  r   rŽ  r   Ú_marshalr   r   r   r   r   r   r   r   r   r   r   r   r    Úinvisible_corer!   r"   Ú_profiler#   r$   r%   r&   r'   r(   r*   rK   rT   r]   r`   r  ri   rp   rq   rv   rƒ   r”   r–   r6  rD  r^  r”  r¶  r9  r;  r•  r  r.  r1  r;  r[   r;   r:   ú<module>r`     s  ððð ð4 #Ð "Ð "Ð "Ð "Ð "à €€€Ø Ð Ð Ð Ø 	€	€	€	Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ø €€€Ø €€€Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,à /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ø #Ð #Ð #Ð #Ð #Ð #Ø Ð Ð Ð Ð Ð Ø =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ø $Ð $Ð $Ð $Ð $Ð $Ø #Ð #Ð #Ð #Ð #Ð #Ø  Ð  Ð  Ð  Ð  Ð  ðCð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð Cð 6Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5ðGð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gðð ð ð ð ˜:ñ ô ð ð:0ð 0ð 0ð 0ð 0˜ñ 0ô 0ð 0ð4
"ð 
"ð 
"ð 
"ð 
"Ð*ñ 
"ô 
"ð 
"ðLð Lð Lð Lð LÐ+ñ Lô Lð Lð
ð ð ð ð Ð"4ñ ô ð ð  €ð3ð 3ð 3ð 3ðB 4Ð ð 9Ð ðFð Fð Fð Fð.2ð 2ð 2ð 2ð)9ð )9ð )9ð )9ðXbð bð bð bð b˜jñ bô bð bðH\*ð \*ð \*ð \*ð \*�jñ \*ô \*ð \*ðV>Pð >Pð >Pð >Pð >P˜
ñ >Pô >Pð >PðBuLð uLð uLð uLð uL˜ñ uLô uLð uLðpO2ð O2ð O2ð O2ð O2�jñ O2ô O2ð O2ðjTð Tð Tð Tð T�Zñ Tô Tð TðP'ð ð ð ð"eð eð eð eð e˜zñ eô eð eðP	@ð @ð @ð @ð @˜
ñ @ô @ð @ðF[,ð [,ð [,ð [,ð [,˜Jñ [,ô [,ð [,ðJð ð ð ð ˜:ñ ô ð ð

ð 
ð 
ð 
ð 
˜:ñ 
ô 
ð 
ð?2ð ?2ð ?2ð ?2ð ?2�Fñ ?2ô ?2ð ?2ð ?2ð ?2r;   