ó
    Ýf—jj  ã                   ó@   • S r SSKrSSKJr  SrS rS rS
S jrSS	 jrg)a9  
Glass's valuation lookup.

Given a registration and mileage, BidBrain enters them on the Glass's home page,
runs the valuation, and reads back the Glass's Retail value, the figure the
buying brain uses. It deliberately reads Glass's Retail, not the live retail
price and not the trade price.

The value sits in an element with id avBasicRetailPrice and a data-price
attribute holding the plain integer, for example 9085.

If the value cannot be read with confidence, this returns None so the caller
holds the car back rather than pricing it on a guess. It never bids.
é    Né   )Úbrowserzhttps://uk.glass.co.uk/c                 óà   • S nU" U 5      n U" U5      R                  5       nU" U5      R                  5       nU(       a  U(       d  g[        S U 5       US   5      nUS   U ;   =(       a    X`;   $ )a  True when the text plainly describes the expected car: the make plus a
distinctive model word must both appear. Short model tokens like the 1 in
1 Series or the A in A Class match everything, so the first token with at
least three characters is used instead when one exists.c                 ó€   • [         R                  " SSU =(       d    SR                  5       R                  SS5      5      $ )Nz
[^a-z0-9 ]Ú Ú-Ú )ÚreÚsubÚlowerÚreplace)Úss    Úbidbrain/readers/glass.pyÚ_cleanÚmatch_tokens.<locals>._clean"   s-   € Ü�vŠv�m R¨!¯'¨r¯©Ó):×)BÑ)BÀ3ÈÓ)LÓMÐMó    Fc              3   óH   #   • U  H  n[        U5      S :¼  d  M  Uv •  M     g7f)é   N)Úlen)Ú.0Úts     r   Ú	<genexpr>Úmatch_tokens.<locals>.<genexpr>)   s   é € Ð3¢˜A¤s¨1£v°¡{—a‘a¢ùs   ‚"™	"r   )ÚsplitÚnext)ÚtextÚexpect_makeÚexpect_modelr   ÚmkÚmdÚ	model_toks          r   Úmatch_tokensr"      sk   € òNá�$‹<€DÙ	�Ó	×	"Ñ	"Ó	$€BÙ	�Ó	×	#Ñ	#Ó	%€BÞ–RØÜÑ3¡Ó3°R¸±UÓ;€IØˆa‰5�D‰=×.˜YÑ.Ð.r   c                 ó^   •  U R                  S5      n[        X1U5      $ ! [         a     gf = f)zÄCheck a valuation page is describing the right car. A registration can
move between cars (private plates), so a price is never trusted unless the
page names the same make and model as the listing.ÚbodyF)Ú
inner_textÚ	Exceptionr"   )Úpager   r   r   s       r   Údetails_matchr(   -   s8   € ðØ�‰˜vÓ&ˆô ˜¨<Ó8Ð8øô ó Ùðús   ‚ Ÿ
,«,c                 ó  • U(       a  Uc  g[         R                  " U SUS9n UR                  (       a  UR                  S   OUR                  5       n[	        XaX$S9UR                  5         $ ! UR                  5         f = f)aë  Return the Glass's Retail value as a whole number of pounds, or None if
it could not be read with confidence. expect is an optional (make, model)
pair; when given, the result page must describe that car or None is
returned, used by the private plate fallback.

Opens its own context per call. For a whole list use valuate_on_page on one
shared logged in page instead, so the single Glass's session is not torn down
and rebuilt for every car (which Glass's treats as session churn and kills).NÚglass)Úheadlessr   )Úexpect)r   Úopen_reader_contextÚpagesÚnew_pageÚvaluate_on_pageÚclose)Ú
playwrightÚregÚmileager+   r,   Úctxr'   s          r   Úlookupr6   8   s_   € ö �'‘/ØÜ
×
%Ò
% j°'ÀHÑ
M€CðØ"ŸyŸyˆs�y‰y˜Š|¨c¯l©l«nˆÜ˜t¨'ÑAà�	‰	�øˆ�	‰	�ús   £9A- Á-A?c                 ó‚  • U(       a  Uc  g U R                  [        SSS9   U R                  SSS9  U R                  S[        U5      R                  S	S
5      5        U R                  S[        [        U5      5      5        S H  n U R                  USS9    O   U R                  S5        U R                  nSU;   aÉ  U R                  S5      n[        U5      S:X  a  g[        U5      S:”  a†  [        5       nU Hf  nUR                  S5      n	UR!                  U	(       a  U	R#                  5       R%                  5       OUR#                  5       R'                  5       5        Mh     [        U5      S:”  a  gUS   R                  5          U R)                  SSS9  S H  n U R                  USS9    O    U R                  SSS9  U R+                  SS5      n
U
(       am  [        U
5      R%                  5       R-                  5       (       aA  U(       a  [/        XS   US   5      (       d  g[        [        U
5      R%                  5       5      $ g! [         a    [	        S5      ef = f! [         a     GMî  f = f! [         a     gf = f! [         a     Mø  f = f! [         a     gf = f! [         a    e [         a     gf = f)zÅRun one valuation on an already open, logged in Glass's page and return
the Glass's Retail value (or None). Reused for every car in the on demand
pass so one logged in window serves the whole list.NÚdomcontentloadedi@œ  )Ú
wait_untilÚtimeoutz#plateNumberInputi˜:  )r:   zpGlass's did not show the valuation box. The login may have expired. Run: python3 login.py glass, then try again.r	   r   z#mileageInput)zbutton:has-text("Go")ztext=Goi   i¬  z/identificationz!.ag-center-cols-container .ag-rowr   é   z*[col-id="edition"], [col-id="editionName"]z**/valuations/**i N  )ztext=Show morezbutton:has-text("Show more")i¸  z#avBasicRetailPricei'  z
data-price)ÚgotoÚHOMEÚwait_for_selectorr&   ÚRuntimeErrorÚfillÚstrr   ÚintÚclickÚwait_for_timeoutÚurlÚquery_selector_allr   ÚsetÚquery_selectorÚaddr%   Ústripr   Úwait_for_urlÚget_attributeÚisdigitr(   )r'   r3   r4   r,   ÚselrE   ÚrowsÚeditionsÚrÚcellÚ
data_prices              r   r0   r0   K   s©  € ö �'‘/ØðLØ�	‰	”$Ð#5¸uˆ	ÑEð	Ø×"Ñ"Ð#6ÀÐ"ÑFð 	�	‰	Ð%¤s¨3£x×'7Ñ'7¸¸RÓ'@ÔAØ�	‰	�/¤3¤s¨7£|Ó#4Ô5ó 8ˆCðØ—
‘
˜3¨�
Ñ-Ùñ 8ð 	×Ñ˜dÔ#Ø�h‰hˆà Ó#Ø×*Ñ*Ð+NÓOˆDÜ�4‹y˜A‹~ØÜ�4‹y˜1‹}ô ›5�Û�AØ×+Ñ+Ð,XÓY�DØ—L‘L¾t $§/¡/Ó"3×"9Ñ"9Ô";ÈÏÉË×!^Ñ!^Ó!`Öañ ô �x“= 1Ó$ØØ�‰G�M‰MŒOð	Ø×ÑÐ0¸%ÐÑ@ó
 FˆCðØ—
‘
˜3¨�
Ñ-Ùñ Fð	Ø×"Ñ"Ð#8À%Ð"ÑHØ×+Ñ+Ð,AÀ<ÓPˆJö œ#˜j›/×/Ñ/Ó1×9Ñ9×;Ñ;Þœm¨D¸±)¸VÀA¹Y×GÑGØÜ”s˜:“×,Ñ,Ó.Ó/Ð/Øøô ó 	Üð?óð ð	ûô ó Ûðûô6 ó 	Ùð	ûô ó Úðûô ó 	Ùð	ûô ó ð 	Üó áðúsÍ   �J' £I ³AJ' ÂI$ÂAJ' Ã BJ' Å5J' Æ	I6 ÆJ' ÆJÆ/J' Æ4"J ÇAJ' È(!J' ÉI!É!J' É$
I3É.J' É2I3É3J' É6
JÊ J' ÊJÊJ' Ê
JÊJ' ÊJÊJ' Ê
J$Ê!J' Ê#J$Ê$J' Ê'J>Ê=J>)TN)N)	Ú__doc__r
   r   r   r=   r"   r(   r6   r0   © r   r   Ú<module>rV      s,   ðñó 
å à €ò/ò,9ôõ&Rr   