ó
    -çÜjø*  ã                   óž  • S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKr	\R                  R                  \R                  R                  \5      5      r\R                  R                  S5      r\R                  R#                  \S5      r\R                  R#                  \SS5      r\R                  R#                  \S5      r\R*                  " 5       r\R.                  " S5      rS	rS
 rS rSqS r/ rS rSS jr \R                  R#                  \SS5      r!\RD                  " S5      r#S r$S r%S r&S r'SS jr(SS jr)SS jr*S r+g)a¯  partbin.py -- its bin grows from the whole LDraw catalog (Ivy, Oct 23 2026: "we need to go thru the library and add pieces.
Starting with the most useful ones. And the frog dammit" -> "I should be able to request pieces from the catalog be added to its
bin!!" -> "It should work on its turn, what shape would be right, and what lego does that. We also need descriptions of each piece
somehow").

    catalog(q, n)    search the whole library by meaning: Ivy's words or its wished-for shape
    check(part)      can the engine actually join it? (studs, sockets or holes found in its geometry)
    add(part, who)   check, draw its card pictures and ghost model, describe it, put it in the bin (bin.json, kept forever)
    describe(part)   a plain sentence for a piece: what it looks like and what it's good for (Haiku, from its name + picture)

The base palette lives in play.py; play.PALETTE also takes everything in bin.json. Written by Iris.
é    Nz~/lego/ldraw/partszbin.jsonÚpartsz	desc.jsonzcatalog.jsonz^\d+[a-z]?\d?$|^\d+c\d+$)Ú~Ú=Ú_Ú|c                  ó¨   • [         R                  " [        [        5      5       V s/ s H  o S   PM	     sn $ s  sn f ! [        [
        4 a    / s $ f = f)NÚpart)ÚjsonÚloadÚopenÚBINÚOSErrorÚ
ValueError)Úbs    Ú-/home/ivy/projects/brick_reef/reef/partbin.pyÚextrasr      s?   € Ü$(§I¢I¬d´3«iÔ$8Ó9Ò$8˜q�6”Ñ$8Ñ9Ð	9ùÒ9øÜ”ZÐ Ó+¨¢)Ð+ús   �%< ¦7´< ·< ¼AÁAc            	      ój  • [         R                  R                  [        5      (       a#  [        R
                  " [        [        5      5      $ / n [        [        R                  " [         R                  R                  [        S5      5      5       GHb  n[         R                  R                  U5      SS n[        R                  U5      (       d  MB  [        [        S5      [        USS95       VVs/ s H  u  p4UR!                  5       PM     nnnU(       a/  US   R%                  S5      (       a  US   S	S R!                  5       OS
nU(       a2  UR%                  [&        5      (       d  SU;   d  SU;   d  SU;   d  SU;   a  Mô  SR                  S U 5       5      nSR                  S U 5       5      nU R)                  U[*        R,                  " SSU5      US-   U-   R!                  5       /5        GMe     [        R.                  " U [        [        S5      5        U $ s  snnf ! ["         a     GM¢  f = f)zMevery usable part in the library: id, name, keywords (cached in catalog.json)z*.datNéüÿÿÿé   Úignore)Úerrorsr   ú0 é   Ú ÚStickerzMoved toÚObsoleteÚMinifigÚ c              3   óx   #   • U  H0  nS U;   d  M  UR                  S S5      S   R                  5       v •  M2     g7f)z	!KEYWORDSé   N©ÚsplitÚstrip©Ú.0Úls     r   Ú	<genexpr>Úindex.<locals>.<genexpr>'   s7   é € Ð[Â$¸QÈ+ÐYZÑJZÓ8�a—g‘g˜k¨1Ó-¨aÑ0×6Ñ6×8Ð8Â$ùó   ‚
:�*:c              3   óx   #   • U  H0  nS U;   d  M  UR                  S S5      S   R                  5       v •  M2     g7f)z	!CATEGORYr    Nr!   r$   s     r   r'   r(   (   s7   é € Ð\Â4¸aÈ;ÐZ[ÑK[Ó9�q—w‘w˜{¨AÓ.¨qÑ1×7Ñ7×9Ð9Â4ùr)   z\s+Úw)ÚosÚpathÚexistsÚINDEXr
   r   r   ÚsortedÚglobÚjoinÚLIBÚbasenameÚID_OKÚmatchÚzipÚranger#   r   Ú
startswithÚSKIPÚappendÚreÚsubÚdump)	ÚoutÚfÚpidr   r&   ÚheadÚnameÚkwÚcats	            r   ÚindexrF      s§  € ä	‡w�w‡~�~”e×Ñ¤T§Y¢Y¬t´E«{Ó%;Ð;Ø
€CÜ”D—I’IœbŸg™gŸl™l¬3°Ó8Ó9×:ˆÜ�g‰g×Ñ˜qÓ! # 2Ð&ˆÜ�{‰{˜3×Ñ¡Ü+.¬u°R«y¼$¸qÈÑ:RÔ+SÔTÒ+S¡4 1�Q—W‘W–YÑ+SˆTÑTæ&*¨t°A©w×/AÑ/AÀ$×/GÑ/Gˆt�A‰w�q�rˆ{× Ñ Ô"ÈRˆÞ�t—‘¤t×,Ñ,°	¸TÓ0AÀZÐSWÓEWÐ[eÐimÓ[mÐqzð  Có  rCñ  EMØ�X‰XÑ[Á$Ó[Ó[ˆØ�h‰hÑ\Á4Ó\Ó\ˆØ�
‰
�CœŸš ¨¨TÓ2°S¸3±YÀ±^×4JÑ4JÓ4LÐM×Nñ ;ô 	‡I‚Iˆc”4œ˜sÓ#Ô$¨S jùó UøÜÓ ›Ð ús$   Ã H#Ã1HÄH#ÈH#È#
H2È1H2c                  ó:  • [         b  [         $ SSKo R                  R                  S[        R                  R                  [        S5      5        SSKn[        5       n[        R                  R                  [        S5      n[        R                  R                  U5      (       aC  [        [        R                  " U5      5      [        U5      :X  a  [        R                  " U5      q Oi[        R                  " UR                  U VVVs/ s H  u  pEoe SU 3PM     snnn5      [        R                  S9q [        R                   " U[         5        [         [        R"                  " [        R$                  R'                  [         SSS	9S
5      -  q [         $ s  snnnf )z@MiniLM vectors for the whole catalog (cached as catalog_emb.npy)Nr   Úteacherúcatalog_emb.npyz. ©Údtyper    T)ÚaxisÚkeepdimsç•Ö&è.>)Ú_EÚsysr-   Úinsertr,   r2   ÚHEREÚteachrF   r.   ÚlenÚnpr   ÚasarrayÚembÚfloat32ÚsaveÚmaximumÚlinalgÚnorm)rP   rS   Úixr-   r   ÚnÚks          r   Ú_embr`   -   sÿ   € ô 
�~œb�yÛ—‘—‘ ¤2§7¡7§<¡<´°iÓ#@ÔAÃ<Ü	‹€BœŸ™Ÿ™¤dÐ,=Ó>�$Ü	‡w�w‡~�~�d×Ñ¤¤B§G¢G¨D£MÓ 2´c¸"³gÓ =ÄBÇGÂGÈDÃM¹rä�ZŠZ˜Ÿ	™	¹bÕ"Aºb±7°1¸ S¨¨1¨#£;¹bÓ"AÓBÌ"Ï*É*ÑUˆÔWY×W^ÒW^Ð_cÔegÔWhÜ	Œb�jŠjœŸ™Ÿ™¬°¸T˜ÐBÀDÓIÑ	I€BÜ€Iùô #Bs   Ä	Fc                  óú   • [         (       a  [         S   R                  5       c  g[        R                  " / SQ[        0 [
        R                  ESSS.E[        R                  [        R                  S9/[         SS& g)zpbuild the catalog's meaning vectors in a background process on spare CPU (it took minutes in-process under load)r   N)	Úflockz-nz$/var/tmp/brick_loop/catalog_emb.lockÚchrtz--idleÚ0Úpython3z-czimport partbin; partbin._emb()r   )ÚHIP_VISIBLE_DEVICESÚCUDA_VISIBLE_DEVICES)ÚcwdÚenvÚstdoutÚstderr)Ú_WARMINGÚpollÚ
subprocessÚPopenrR   r,   ÚenvironÚDEVNULL© ó    r   Ú_warmrt   :   sx   € ç‚x”H˜Q‘K×$Ñ$Ó&Ñ.°Ü×#Ò#ò %GÜLPð  W\ÔY[×YcÑYcð  W\Ð|~ð  Y[ò  W\Ü+5×+=Ñ+=Äj×FXÑFXñZð [„H‰Q�Krs   c                 óZ  ^^^^^^^• Uo1U-   n[        5       mU =(       d    SR                  5       n U (       d  / $ [        R                  " SU R	                  5       5       Vs/ s H  oDPM     snm[        T5       VV^V^V^s/ s H3  u  nu  mmmT(       d  M  [        UUU4S jT 5       5      (       d  M1  UPM5     n	nnnn[        R                  " [        [        R                  R                  [        S5      5      5      mUU4S jmU	R!                  UUU4S jS9  U	SU n
[#        U
5      U:  aR  [        R                  R%                  [        R                  R                  [        S	5      5      (       d  ['        5         GO[#        U
5      U:  Ga  S
SKo»R                  R+                  S
[        R                  R                  [        S5      5        S
SKn[.        R0                  " UR3                  U /5      S
   [.        R4                  S9oÝ[7        [.        R8                  R;                  U5      S5      -  n[.        R<                  " [?        5       U-  * 5       H?  n[#        U
5      U:¼  a    O/[A        U5      U
;  d  M%  U
RC                  [A        U5      5        MA     [E        [G        5       5      nS
SK$nX¢X#-     Vs/ s H:  nTU   S
   TU   S   TU   S
   U;   =(       d    TU   S
   URJ                  ;   S.PM<     sn$ s  snf s  snnnnf ! [        [        4 a    0 m GN"f = fs  snf )zfthe parts that best match q: every word of q found in the name first, then by meaning (page by offset)r   z	[a-z0-9]+c              3   ó`   >#   • U  H#  oTS -   T-   S -   T-   R                  5       ;   v •  M%     g7f)r   N©Úlower)r%   r+   rD   ÚnmrA   s     €€€r   r'   Úcatalog.<locals>.<genexpr>F   s6   øé € ÐE~Òx}ÐstÈCÐRUÉIÐXZÉNÐ]`ÑL`ÐceÑLe×KlÑKlÓKnÖFnÒx}ùs   ƒ+.zcommon_rank.jsonc                 ó2   >^ • [        U U4S jT 5       5      $ )Nc              3   ól   >#   • U  H)  oTT   S    S-   TT   S   -   R                  5       ;   v •  M+     g7f)r   r   r    Nrw   )r%   r+   Úir]   s     €€r   r'   Ú,catalog.<locals>.<lambda>.<locals>.<genexpr>I   s6   øé € ÐTÊeÈ " Q¡%¨¡(¨S¡.°2°a±5¸±8Ñ";×!BÑ!BÓ!DÖDÊeùs   ƒ14)Úall)r}   r]   Úwordss   `€€r   Ú<lambda>Úcatalog.<locals>.<lambda>I   s   ù€ œÕTÉeÓTÔTrs   c                 ón   >• T" U 5      (       + TR                  TU    S   S5      [        TU    S   5      4$ )Nr   i@B r    )ÚgetrT   )r}   Úin_namer]   Úranks    €€€r   r�   r‚   J   s3   ø€ ¡'¨!£*œn¨d¯h©h°r¸!±u¸Q±xÀÓ.GÌÈRÐPQÉUÐSTÉXËÑWrs   )ÚkeyNrI   r   rH   rJ   rN   r    )r	   rC   Úin_bin)&rF   r#   r<   Úfindallrx   Ú	enumerater   r
   r   r   r,   r-   r2   rR   r   r   ÚsortrT   r.   rt   rP   rQ   rS   rU   rV   rW   rX   Úmaxr[   r\   Úargsortr`   Úintr;   Úsetr   ÚplayÚPALETTE)Úqr^   ÚoffsetÚwantr+   r}   rA   ry   rD   Úexactr?   rP   rS   ÚvÚhaver�   r…   r]   r†   r€   s         ```       @@@@r   Úcatalogr˜   @   s]  þ€ à€D�f‘*ˆaÜ	‹€B�q—w˜B—o‘oÓ'�!Þ�RˆiÜŸ
š
 <°·±³Ô;Ó<Ò;�1ŠQÑ;Ñ<€EÜ'0°¤}×Ñ¢}Ñ#�1‘m�s˜B ¼‹QÄ#ÖE~Ñx}ÓE~×B~�Q¡}€EÓÜ—	’	œ$œrŸw™wŸ|™|¬DÐ2DÓEÓFÓGˆåT€GØ	‡J�JÖW€JÑXØ
��ˆ)€CÜ
ˆ3ƒx�!ƒ|œBŸG™GŸN™N¬2¯7©7¯<©<¼Ð>OÓ+P×QÑQÜŽÜ	ˆS‹�AŒÛ—H‘H—O‘O A¤r§w¡w§|¡|´D¸)Ó'DÔEÃ|Ü�JŠJ�u—y‘y ! “~ aÑ(´·
±
Ñ;ˆÄ#ÄbÇiÁiÇnÁnÐUVÓFWÐY]ÓB^Ñ=^¸QÜ—’œd›f q™j˜MÖ*ˆAÜ�3‹x˜1‹}™eÜ�1‹v˜SÕ  #§*¡*¬S°«VÖ"4ñ +ô Œv‹x‹=€DÛØruð  ~Dñ  ~Kñ  sLó  Mò  sLÐmn�R˜‘U˜1‘X r¨!¡u¨Q¡x¸2¸a¹5À¹8ÀtÑ;K×;gÈrÐRSÉuÐUVÉxÐ[_×[gÑ[gÑOgÔhñ  sLñ  Mð  Mùò# =ùÝøä”ZÐ Ó+¨£$Ð+üò Ms2   Á!LÂL
ÂL
Â6L
ÃAL Ê>AL(ÌL%Ì$L%Úprevr   c                 ó@  • [         R                  " SS[        U 5      R                  5       5      n [        R
                  R                  [        SU  S35      [        R
                  R                  [        U  S35      4 H+  n[        R
                  R                  U5      (       d  M)  Us  $    [        R
                  R                  [        R
                  R                  [        U S-   5      5      (       d  g[        R                  " [        SS9  [        R
                  R                  [        U  S	35      n[           [        R
                  R                  USS
 S-   5      (       dj  [        US5      R                  SU  SU  S35        [        R                   " SSSSS[        R
                  R#                  S5      SUSS
 S-   SSSSSSU/SSS9  SSS5        [        R
                  R                  USS
 S-   5      (       a  USS
 S-   $ S$ ! , (       d  f       NB= f)zqa picture of any catalog part (its card picture if it's in the bin; otherwise drawn once and kept). Path or None.z	[^0-9a-z]r   r   ú.pngú.datNT©Úexist_okú.ldrr   r+   r   z
1 14 0 0 0 1 0 0 0 1 0 0 0 1 ú.dat
ÚflatpakÚrunú--filesystem=homeúorg.leocad.LeoCADú-lú~/lego/ldrawú-iú-wÚ160ú-hú--viewpointÚhomeéx   ©Úcapture_outputÚtimeout)r<   r=   Ústrrx   r,   r-   r2   rR   ÚPREVr.   r3   ÚmakedirsÚ
_PREV_LOCKr   Úwritern   r¢   Ú
expanduser)r	   ÚpÚldrs      r   Úpreviewr¹   Z   s³  € ä�6Š6�, ¤C¨£I§O¡OÓ$5Ó6€DÜ�g‰g�l‰lœ4 ¨T¨F°$¨-Ó8¼"¿'¹'¿,¹,ÄtÐPTÈvÐUYÈ]Ó:[Ó\ˆÜ�7‰7�>‰>˜!×Ó Qšhñ ]ä�7‰7�>‰>œ"Ÿ'™'Ÿ,™,¤s¨D°6©MÓ:×;Ñ;ÀDÜ‡K‚K”˜tÒ$¬B¯G©G¯L©L¼À$ÀÀt¸}Ó,M cÞ	Ü�w‰w�~‰~˜c # 2˜h¨Ñ/×0Ñ0Ü��c‹N× Ñ  2 d VÐ+JÈ4È&ÐPVÐ!WÔXÜ�NŠN˜I uÐ.AÐCVÐX\Ô^`×^eÑ^e×^pÑ^pÐqó  _Að  CGØ  ˜H vÑ-¨t°U¸DÀ%ÈÐX^Ð`cðeØuyð  DGòH÷ 
ô
 !#§¡§¡¨s°3°B¨x¸&Ñ/@× AÑ Aˆ3ˆs�ˆ8�fÑÐKÀtÐK÷ 
�ús   Ä>BHÈ
Hc                 ó:  • SSK n[        R                  R                  [        R                  R	                  [
        U S-   5      5      (       d  gUR                  R                  U 5      n[        UR                  5      (       dK  [        UR                  5      (       d1  [        UR                  5      (       d  UR                  U 5      (       d  g[        UR                   R"                  5      S	:”  a  g
g! [         a  nS[        U5      SS  S3s SnA$ SnAff = f)z,None if the engine can join it, else why notr   Nrœ   znot in the libraryzcould not load it (é<   Ú)zVno studs, sockets, holes, bars, clips, axles or hinges on it, so nothing could join ité    ztoo big for the bin)r�   r,   r-   r.   r2   r3   ÚGÚfreshÚ	Exceptionr±   rT   ÚstudsÚsocketsÚholesÚ	new_snapsrŒ   ÚmeshÚextents)r	   r�   r·   Úes       r   ÚcheckrÈ   h   s¸   € ãÜ�7‰7�>‰>œ"Ÿ'™'Ÿ,™,¤s¨D°6©MÓ:×;Ñ;ÐDXØ�V‰V�\‰\˜$Óˆä�—‘�L‰LœC §	¡	ŸN™N¬c°!·'±'¯l©l¸d¿n¹nÈT×>RÑ>RØgÜ
ˆ1�6‰6�>‰>Ó˜SÓ Ð)>Øøô	 ÓFÐ$7¼¸A»¸sÀ¸°}ÀAÐ"FÕFûÐFús   ÁC4 Ã4
DÃ>DÄDÄDc                 ó,  • [         R                  " [         R                  R                  [        S5      SS9  S Hœ  u  p[         R                  R                  [        SU  U S35      n[        US5      R                  SU  SU S	U  S
35        [        R                  " SSSSS[         R                  R                  S5      SUS S S-   SSSSSSU/SSS9  Mž     SS K
oDR                  U [         R                  R                  [        SU  S35      5        g )Nr   Tr�   ))r   é   )Ú_wé   rŸ   r+   r   z
1 z 0 0 0 1 0 0 0 1 0 0 0 1 r    r¡   r¢   r£   r¤   r¥   r¦   r§   r   r›   r¨   r©   rª   r«   r¬   r­   r®   r   z.glb)r,   r³   r-   r2   rR   r   rµ   rn   r¢   r¶   Úto_glbÚpart_glb)r	   ÚtagÚcolr¸   rÍ   s        r   Ú_renderrÑ   s   s  € Ü‡K‚K”—‘—‘œT 7Ó+°dÒ;Û*‰ˆÜ�g‰g�l‰lœ4 ¨T¨F°3°%°tÐ*<Ó=ˆÜˆS�#‹×Ñ˜r $  t¨C¨5Ð0IÈ$ÈÈvÐVÔWÜ�Š˜	 5Ð*=Ð?RÐTXÔZ\×ZaÑZa×ZlÑZlÐm{ÓZ|ð  CØ˜C˜R˜ 6Ñ)¨4°¸¸eÀ]ÐTZÐ\_ðaØquð  @Cô	Dñ +ó
 —?‘? 4¬¯©¯©´d¸GÈÀvÈTÀ]Ó)SÕTrs   c                  óx   • [         R                  " [        [        5      5      $ ! [        [
        4 a    0 s $ f = f©N)r
   r   r   ÚDESCr   r   rr   rs   r   Ú	_desc_allrÕ   |   s)   € Ü—	’	œ$œt›*Ó%Ð	%øÜ”ZÐ Ó+¨¢)Ð+ús   �"$ ¤9¸9c           
      ó  ^ • [        5       nT U;   a  U(       d  UT    $ SSKnU=(       d    [        U 4S j[        5        5       T 5      n[        R
                  R                  [        ST  S35      nSnS H\  n[        R                  " U5         UR                  SU S	T  S
3[        R
                  R                  U5      (       a  U/O/ SSS9u  ph  O   U=(       d    SR                  5       R                  S5      nU(       aC  [            [        5       o6UT '   ["        R$                  " U['        [(        S5      SS9  SSS5        U$ U$ ! [         a$  n	[        ST S[        U	5      SS SS9   Sn	A	Mý  Sn	A	ff = f! , (       d  f       U$ = f)zxwhat it looks like and what it's good for, in plain words a kid could follow (Haiku, from the name and the white render)r   Nc              3   ó<   >#   • U  H  u  po1T:X  d  M  Uv •  M     g 7frÓ   rr   ©r%   rA   ry   r   r	   s       €r   r'   Údescribe.<locals>.<genexpr>…   s   øé € ÐEªg¡
 ¨À¹Ÿ™ªgùó   ƒ“	r   ú_w.pngr   )r   é   r»   zThis is the Lego part "z	" (LDraw zæ), pictured. In ONE plain sentence of at most 22 words, say what it looks like (shape, size in studs, anything special like a slope, hole, curve or face) and what builders use it for. No part number. Answer with the sentence only.r­   Úgemini)ÚpreferÚdescribezfailed:r»   T©ÚflushÚ"r+   ©Úindent)rÕ   ÚimagineÚnextrF   r,   r-   r2   rR   ÚtimeÚsleepÚ	small_askr.   rÀ   Úprintr±   r#   Ú_LOCKr
   r>   r   rÔ   )
r	   rC   ÚforceÚdÚIÚimgÚtÚwaitr   rÇ   s
   `         r   rß   rß   €   s]  ø€ ä‹€AØˆqƒyž q¨¡w ÛØ×L”4ÔE¬e¬gÓEÀtÓL€DÜ
�'‰'�,‰,”t˜W¨¨¨f oÓ
6€CØ
€AÛˆÜ�
Š
�4Ôð	[Ø—;‘;Ð!8¸¸¸iÈÀvð NJð  KäUW×U\ÑU\×UcÑUcÐdg×UhÑUhÈSÉEÐnpÐruð  Gð ð H‰DˆAñ ñ ð 
�ˆb�‰Ó×Ñ Ó$€AÞÞÜ“ˆA˜Q˜t™W¬$¯)ª)°A´t¼DÀ#³ÈqÒ*Q÷ à€Hˆ1€Høô ÓZœu Z°°yÄ#ÀaÃ&ÈÈ"À+ÐUY×ZÐZûÐZú÷ ŒUà€Hús%   ÂAE	Ä
3E:Å	
E7ÅE2Å2E7Å:
F	c                 óÒ  ^ • SSK n[        T 5      R                  5       R                  5       m T UR                  ;   a  g[        T 5      nU(       a  SU4$ [           [        T 5        [        U 4S j[        5        5       T 5      n[        R                  " [        [        R                  R                  [         SS5      5      5      nXVT '   [        R&                  " U[        [        R                  R                  [         SS5      S5      5        [        R                  R)                  [*        5      (       a#  [        R                  " [        [*        5      5      O/ nT U Vs/ s H  oˆS	   PM	     sn;  a)  UR-                  T U[.        R0                  " S
5      S.5        [        R&                  " U[        [*        S5      SS9  UR                  R-                  T 5        XSR2                  R4                  T '   SSS5        U=(       a    [7        T W5        SW S34$ ! ["        [$        4 a    0 n GNgf = fs  snf ! , (       d  f       NH= f! [8         a  n	[;        SU	SS9   Sn	A	NPSn	A	ff = f)z=put a catalog part in its bin for good. Returns (ok, message)r   N)Fzalready in its binFc              3   ó<   >#   • U  H  u  po1T:X  d  M  Uv •  M     g 7frÓ   rr   rØ   s       €r   r'   Úadd.<locals>.<genexpr>Ÿ   s   øé € ÐAª'™J˜C Q¸D±[—R‘Rª'ùrÚ   r   z
names.jsonr+   r	   z%Y-%m-%d %H:%M)r	   ÚwhoÚwhenr    rã   zdescribe failed:Trà   z is in its bin now)r�   r±   r#   rx   r‘   rÈ   rë   rÑ   ræ   rF   r
   r   r   r,   r-   r2   rR   r   r   r>   r.   r   r;   rç   ÚstrftimeÚCXÚNAMESrß   rÀ   rê   )
r	   rõ   Údescribe_itr�   ÚwhyrC   Únamesr   ÚxrÇ   s
   `         r   Úaddrþ   –   s¬  ø€ ãÜˆt‹9�?‰?Ó×"Ñ"Ó$€DØˆt�|‰|ÓÐ$?Ü
�‹+€CÞ
�5˜#�:ÐÞ	Ü�ŒÜÔA¬%¬'ÓAÀ4ÓHˆÜ—Y’Yœt¤B§G¡G§L¡L´°wÀÓ$MÓNÓOˆUàˆd‰œDŸIšI e¬T´"·'±'·,±,¼tÀWÈlÓ2[Ð]`Ó-aÔbÜ$&§G¡G§N¡N´3×$7Ñ$7ŒD�IŠI”dœ3“iÔ ¸RˆØ©1Ó-ª1 a˜&œ	©1Ñ-Ó-¨q¯x©xÀÈcÔ[_×[hÒ[hÐiyÓ[zÑ8{Ô/|Ü�	Š	�!”Tœ#˜s“^¨AÒ.Ø�‰×Ñ˜DÔ!¸§7¡7§=¡=°Ñ#6÷ 
ð 
×	-œ $¨Ó-øà�D�6Ð+Ð,Ð,Ð,øô œÐ$Ó0¨b£eÐ0üò .÷ 
�ûô ÓCœ5Ð!3°Q¸d×CûÐCúsW   Á*H6ÂAHÃBH6Å H1Å.BH6Ç<I ÈH.È*H6È-H.È.H6È6
IÉ
I&ÉI!É!I&c           	      óŽ  • SSK n[        5       nSnUR                   H¤  nXB;   a  M
  [        R                  R                  [        R                  R                  [        SU S35      5      (       d  MV  [        XAR                  R                  R                  U5      5      (       a  US-  n[        R                  " U 5        M¦     U$ )zma description for every piece in its bin that doesn't have one yet (slowly: one call every couple of seconds)r   Nr   rÛ   r    )r�   rÕ   r‘   r,   r-   r.   r2   rR   rß   rø   rù   r„   rç   rè   )Úpauser�   rí   Údoner	   s        r   Údescribe_missingr  «   sŠ   € ãÜ‹€A˜A�TØ—”ˆØ‹9‘hÜ�w‰w�~‰~œbŸg™gŸl™l¬4°¸T¸FÀ&¸/ÓJ×KÑKÉXÜ�DŸ'™'Ÿ-™-×+Ñ+¨DÓ1×2Ñ2°D¸A±I°DÜ�
Š
�5Öñ	 ð
 €Krs   c                 óÈ   • X S-   U S-   U S-   4 HP  n[         R                  R                  [         R                  R                  [        US-   5      5      (       d  MN  Us  $    g)zEBrick Architect / BrickLink numbers -> the LDraw file (3069 -> 3069b)r   ÚaÚcrœ   N)r,   r-   r.   r2   r3   )rA   r  s     r   Úldraw_idr  ¶   sL   € à˜‘9˜c C™i¨¨s©Ó3ˆÜ�7‰7�>‰>œ"Ÿ'™'Ÿ,™,¤s¨A°©JÓ7×8Ó8Àº(ñ 4àrs   )é   r   )NF)ÚIvyT)g       @),Ú__doc__r
   r,   r<   r1   rn   Ú	threadingrç   ÚnumpyrU   r-   ÚdirnameÚabspathÚ__file__rR   r¶   r3   r2   r   rÔ   r/   ÚRLockrë   Úcompiler5   r:   r   rF   rO   r`   rl   rt   r˜   r²   Ú	Semaphorer´   r¹   rÈ   rÑ   rÕ   rß   rþ   r  r  rr   rs   r   Ú<module>r     s(  ðñ÷ 7× 6× 6Ó 6Û Ø	‡w�w‡��r—w‘w—‘ xÓ0Ó1€Ø‡g�g×ÑÐ-Ó.€Ø‡g�g‡l�l�4˜Ó$€Ø	‡w�w‡|�|�D˜' ;Ó/€Ø
�‰�‰�T˜>Ó*€Ø�ŠÓ€Ø
�
Š
Ð.Ó/€Ø€ò,ò1ð  
€ò
ð €ò[ôMð0 
‡w�w‡|�|�D˜' 6Ó*€Ø× Ò  Ó#€
òLò	òUò,ôô,-ô*	órs   