§
    ›Çj  ã                  ór   — d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	 dd	„Z
dd„Zdd„Zdd„Zdd„Zdd„ZdS )u(  Writing the profile a Firefox launch is given, and reading back what it is.

â›” Leaves, like the ones in `_marshal`: none of them mentions a dispatcher.
What they have in common is a different subject - a directory on disk and the
`user.js` inside it - which is why they are not in the same module. One
`_helpers.py` holding both would be the bucket every project grows and nobody
can name.

Re-exported from `server.py`: `tests/gates/prefs_byte_parity.py` and the
transport tests import `_write_user_js`, `_host_of` and `_domain_matches` from
there.
é    )ÚannotationsN)ÚAnyÚDictÚOptionalÚ	directoryÚstrÚreturnÚNonec                ó2   — t          j        | d¬¦  «         dS )u°  Take away a profile WE created. Never one the caller named.

    â›” IT MUST NOT RAISE. This runs while the session is already going away,
    and on Windows a file can still be held for a moment after the process that
    owned it exits. A profile left behind is a few dozen megabytes; an
    exception here would be a shutdown that fails for a reason nobody cares
    about, on a path the caller has already stopped watching.
    T)Úignore_errorsN)ÚshutilÚrmtree)r   s    úWC:\Projects\Historical\venv\Lib\site-packages\invisible_playwright/_juggler/_profile.pyÚ_remove_profiler      s   € õ „M�)¨4Ð0Ñ0Ô0Ð0Ð0Ð0ó    Úprofile_dirÚprefsr   Úintc                ó  — ddl }g }|D ]Ñ}||         }t          |t          ¦  «        r|rdnd}n}t          |t          ¦  «        rt	          |¦  «        }nXt          |t
          ¦  «        r"t          j        t	          |¦  «        ¦  «        }n!t          j        t	          |¦  «        ¦  «        }|                     dt          j        |¦  «        ›d|›d�¦  «         ŒÒ| 	                    | d¬	¦  «         d
 
                    |¦  «        d
z   }t          |j         
                    | d¦  «        d¦  «        5 }|                     |                     d¦  «        ¦  «         ddd¦  «         n# 1 swxY w Y   t          |¦  «        S )uJ  The prefs, into the profile, BEFORE the browser starts.

    â›” WITHOUT THIS THE PYTHON PATH LAUNCHES A BROWSER THAT IS NOT THE PRODUCT,
    and it does so silently. Two hundred prefs arrive in `firefoxUserPrefs` on
    every `launch`, and the first draft of this server threw them away and
    started Firefox on an empty temporary profile. Everything worked - pages
    loaded, clicks landed, the tests were green - and every stealth declaration
    the package exists to make was simply absent.

    It was caught by a closed shadow root, of all things: the engine patch that
    lets a locator reach inside one is gated on `StealthEngineActive()`, which
    is a pref. The same probe found the root through `_juggler` directly and
    lost it through the public API, and the only difference between those two
    arms was who wrote the profile. A gate for a completely different feature
    is what made the absence visible; nothing was checking for it directly.

    â›” AND THEY ARE WRITTEN, NOT SENT. Our fork already removed prefs from the
    protocol - `Browser.enable` does not accept them any more - because a
    browser configured on the second launch is a browser that was wrong on the
    first. This mirrors what the driver's `defaultArgs` does, in Python.

    â›” Gecko HAS NO FLOAT PREF TYPE: a fraction must be written as a STRING, or
    the parser fails on that line and IGNORES EVERY LINE AFTER IT. That is not
    a hypothetical - `ui.textScaleFactor` written as a number once killed the
    browser on the second context, and the failure looked nothing like a prefs
    problem.
    r   NÚtrueÚfalsez
user_pref(z, z);T)Úexist_okú
zuser.jsÚwbúutf-8)ÚosÚ
isinstanceÚboolr   r   ÚfloatÚjsonÚdumpsÚappendÚmakedirsÚjoinÚopenÚpathÚwriteÚencodeÚlen)	r   r   r   ÚlinesÚnameÚvalueÚrenderedÚbodyÚhandles	            r   Ú_write_user_jsr0   !   s©  € ð8 €I€I€IØ€Eð ð Jð JˆØ�d”ˆÝ�e�TÑ"Ô"ð 	.Ø!&Ð3�v�v¨GˆHˆHÝ˜�sÑ#Ô#ð 	.Ý˜5‘z”zˆHˆHÝ˜�uÑ%Ô%ð 	.å”z¥# e¡*¤*Ñ-Ô-ˆHˆHå”z¥# e¡*¤*Ñ-Ô-ˆHØ�Šˆ­T¬Z¸Ñ-=Ô-=Ð-=Ð-=¸x¸x¸xÐHÑIÔIÐIÐIØ‡K‚K� d€KÑ+Ô+Ð+ð
 �9Š9�UÑÔ˜dÑ"€Dõ 
ˆbŒg�lŠl˜;¨	Ñ2Ô2°DÑ	9Ô	9ð +¸VØ�Š�T—[’[ Ñ)Ô)Ñ*Ô*Ð*ð+ð +ð +ñ +ô +ð +ð +ð +ð +ð +ð +øøøð +ð +ð +ð +åˆu‰:Œ:Ðs   Ä3)E(Å(E,Å/E,Ú
executablec                óD  — t          j        | ¦  «        j        dz  }	 |                     dd¬¦  «                             ¦   «         D ]G}|                     d¦  «        r0|                     dd¦  «        d                              ¦   «         c S ŒHn# t          $ r Y nw xY wdS )	u   The base version, from `application.ini` next to the binary.

    â›” Read, never assumed: this project has three separate incidents where a
    folder name or a guess about the version sent a whole evening of
    measurements against the wrong build.
    zapplication.inir   Úreplace)ÚencodingÚerrorszVersion=ú=é   z0.0)	ÚpathlibÚPathÚparentÚ	read_textÚ
splitlinesÚ
startswithÚsplitÚstripÚOSError)r1   ÚiniÚlines      r   Ú_read_versionrC   ]   sÁ   € õ Œ,�zÑ
"Ô
"Ô
)Ð,=Ñ
=€CðØ—M’M¨7Ø)2ð "ñ 4ô 4ß4>²J±L´Lð	5ð 	5ˆDà�Š˜zÑ*Ô*ð 5Ø—z’z # qÑ)Ô)¨!Ô,×2Ò2Ñ4Ô4Ð4Ð4Ð4ð5ð	5øõ ð ð ð Øˆðøøøàˆ5s   žA/B ÂB Â
BÂBÚparamsc                ó>   — d„ |                       ¦   «         D ¦   «         S )u=  The parameters that were actually given, with the absent ones REMOVED.

    â›” IN A CLOSED-WORLD SCHEMA, `null` AND ABSENT ARE DIFFERENT ANSWERS.
    Juggler validates every field it is handed: an Optional that arrives as
    `null` is not "not provided", it is a value of the wrong type, and the
    command is REJECTED at runtime with `Object "<root>.clip" is undefined,
    but has some scheme`. Measured on 2026-08-28 on `Page.screenshot`, whose
    clip and quality are both optional and were both being sent as null.

    â›” AND THIS IS NOT DONE INSIDE `Connection.send`, tempting as that is:
    some commands mean something BY sending null. `Browser.setGeolocationOverride`
    with `geolocation: null` CLEARS the override, and stripping it there would
    turn "stop pretending to be somewhere" into "do nothing".
    c                ó   — i | ]
\  }}|®||“ŒS )N© )Ú.0ÚkÚvs      r   ú
<dictcomp>z_only_set.<locals>.<dictcomp>~   s   € Ð=Ð=Ð=‘T�Q˜¨q¨}ˆAˆq¨}¨}¨}r   )Úitems)rD   s    r   Ú	_only_setrM   o   s    € ð >Ð=˜VŸ\š\™^œ^Ð=Ñ=Ô=Ð=r   Úurlc                óÊ   — |                       dd¦  «        d         }|                      dd¦  «        d                               dd¦  «        d                              ¦   «         S )zCThe host of a url, without importing a parser for three characters.z://r7   éÿÿÿÿú/r   ú:)r>   Úlower)rN   Úwithout_schemes     r   Ú_host_ofrU   �   sV   € à—Y’Y˜u aÑ(Ô(¨Ô,€NØ×Ò  QÑ'Ô'¨Ô*×0Ò0°°aÑ8Ô8¸Ô;×AÒAÑCÔCÐCr   Úcookie_domainÚhostr   c                óœ   — | pd                      d¦  «                             ¦   «         }|r|sdS ||k    p|                     d|z   ¦  «        S )uÜ   â›” A LEADING DOT MEANS "AND EVERY SUBDOMAIN", and dropping it turns a
    site-wide cookie into one that matches nothing. Comparing the two strings
    directly is the version that looks right and returns an empty list.Ú ú.F)ÚlstriprS   Úendswith)rV   rW   Údomains      r   Ú_domain_matchesr^   ‡   s[   € ð Ð!˜r×)Ò)¨#Ñ.Ô.×4Ò4Ñ6Ô6€FØð ˜ð ØˆuØ�6Š>Ð8˜TŸ]š]¨3°©<Ñ8Ô8Ð8r   )r   r   r	   r
   )r   r   r   r   r	   r   )r1   r   r	   r   )rD   r   r	   r   )rN   r   r	   r   )rV   r   rW   r   r	   r   )Ú__doc__Ú
__future__r   r    r8   r   Útypingr   r   r   r   r0   rC   rM   rU   r^   rG   r   r   ú<module>rb      sã   ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø €€€Ø &Ð &Ð &Ð &Ð &Ð &Ð &Ð &Ð &Ð &ð	1ð 	1ð 	1ð 	1ð9ð 9ð 9ð 9ðxð ð ð ð$>ð >ð >ð >ð$Dð Dð Dð Dð9ð 9ð 9ð 9ð 9ð 9r   