
    f                        d dl mZmZ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mZmZmZmZmZ d dlmZ d dlZd dlmZ d dlmZ  ej0                  d      Z G d d	      Z G d
 d      Zej8                  ej:                  z  ej<                  z  ej>                  z  Z dddddddddZ!dgdgdZ"ddgddgddgddgddgd d!gdd!gd"d#gd$d%gg	Z# e$e#      Z%i 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dFdGdHdIdJdKdLdMdNdOd7dPdQ
Z&dRZ'ddSdTdUdVdWdXdYdZd[d\d]d^d_d`Z(da Z)ddbZ*dc Z+dd Z,de Z-df Z.dg Z/dh Z0di Z1dj Z2 G dk dle3      Z4de5fdmZ6ddnZ7do Z8 G dp dq      Z9ddrZ:ds Z;ddtZ<dduZ=dv Z>dw Z?dx Z@dy ZAdz ZBd{ ZCd dlDZD	 	 dd|ZEeej                  fd}       ZG G d~ d      ZH G d de3      ZI G d de3      ZJ G d d      ZKd ZLddZMddZNddZOd ZP G d d      ZQ G d de3      ZR G d d      ZS ej                  dej                  ej                  z  ej                  z        ZXd ZYddZZ G d de3      Z[y)    )divisionprint_functionunicode_literalsN)pisincossqrtlog)contextmanager)reduce)GLibutilsc                       e Zd ZdZdZdZy)KeyCode$   h   6   N)__name__
__module____qualname__ReturnKP_EnterC     //usr/lib/python3/dist-packages/Onboard/utils.pyr   r   ,   s    FHAr   r   c                   <    e Zd Zd  ed      D        \  ZZZZZZ	Z
Zy)	Modifiersc              #   &   K   | ]	  }d |z    yw   Nr   .0bits     r   	<genexpr>zModifiers.<genexpr>5   s     +33+      N)r   r   r   rangeSHIFTCAPSCTRLALTNUMLKMOD3SUPERALTGRr   r   r   r   r   2   s%     ,%(+ 6E4sE4r   r   r!         r'          @      )shiftcapscontrolmod1mod2mod3mod4mod5LFSHLCTL)r)   r+   LWIN)Winr5   RTSH)u   ⇧r!   RALT)zAlt Grr6   LALT)Altr'   RCTL)Ctrlr2   r*   )r*   r1   NMLK)zNm
Lkr3   RWINrB   MENUMenuBKSPu   ⇦RTRNr   TABTabINSInsHOMEHmPGUPzPg
UpDELEDelENDEndPGDNzPg
DnUPu   ↑DOWNu   ↓LEFTu   ←RGHTu   →KP00KP1123456789Ent)
KP2KP3KP4KP5KP6KP7KP8KP9KPDLKPEN))ESCi  )F1i  )F2i  )F3i  )F4i  )F5i  )F6i  )F7i  )F8i  )F9i  )F10i  )F11i  )F12i  )Prntia  )Scrolli  )Pausei  i  ic  iP  iU  iV  iW  i  i  i  iQ  iR  iS  iT  )spacekp_spaceinserthomepage_up	page_downenddeletereturn	backspaceleftuprightdownc                     t         |    S N)keysyms)names    r   get_keysym_from_namer      s    4=r   c                     | dd }| d   }t        |      }|yg }t        j                  |      }|D ]=  }|j                  |      }|s|j	                         |k(  s+|j                  ||f       ? |S )a  
    Parses a key combination into a list of modifier masks and key_ids.
    The key-id part of the combo may contain a regex pattern.

    Doctests:

    # modifiers
    >>> parse_key_combination(["TAB"], ["TAB"])
    [('TAB', 0)]
    >>> parse_key_combination(["LALT", "TAB"], ["TAB"])
    [('TAB', 8)]
    >>> parse_key_combination(["LALT", "LFSH", "TAB"], ["TAB"])
    [('TAB', 9)]
    >>> parse_key_combination(["LWIN", "RTSH", "LFSH", "RALT", "LALT", "RCTL", "LCTL", "CAPS", "NMLK", "TAB"], ["TAB"])
    [('TAB', 223)]

    # modifier groups
    >>> parse_key_combination(["CTRL", "SHIFT", "TAB"], ["TAB"])
    [('TAB', 5)]

    # regex
    >>> parse_key_combination([r"F\d+"], ["TAB", "F1", "F2", "F3", "F9"])
    [('F1', 0), ('F2', 0), ('F3', 0), ('F9', 0)]
    N)parse_modifier_stringsrecompilematchgroupappend)	comboavaliable_key_ids	modifierskey_patternmod_maskresultspatternkey_idr   s	            r   parse_key_combinationr      s    2 cr
I)K &i0H Gjj%G# /f%U[[]f,NNFH-./
 Nr   c           
      :   d}| D ]  }t         j                  |      }|	||d   z  }#t        j                  |      }||D ]  }|t         |   d   z  } Qt        j	                  dj                  |dj                  d t        D                           d} |S  |S )z, Build modifier mask from modifier strings. r   Nr!   z)unrecognized modifier '{}'; try one of {},c              3   &   K   | ]	  }|d      yw)r   Nr   )r#   ms     r   r%   z)parse_modifier_strings.<locals>.<genexpr>   s     :QA1Q4:Qr&   )modDicget	modGroups_loggerwarningformatjoinmodList)r   r   modifierr   r   mods         r   r   r      s    H JJx y!HMM(+E=  /CsA.H/  K!'#((:Q:Q2Q!RTO Or   c                 :    t        |       }|j                          y r   )
__import__run)scriptas     r   
run_scriptr      s    &AEEGr   c                 h   | j                  d      }t        j                  dt        j                        }|j	                  d|      }t        j                  dd |      }t
        j                  j                  |j                         D cg c]  }|j                         s| c}      }|S c c}w )Nz  )indentz>\n\s+([^<>\s].*?)\n\s+</z>\g<1></z"[^"]*"c                 D    | j                  d      j                  dd      S )Nr   
z&#10;)r   replace)r   s    r   <lambda>ztoprettyxml.<locals>.<lambda>   s    QWWQZ''g6 r   )
toprettyxmlr   r   DOTALLsuboslinesepr   
splitlinesstrip)domdocugly_xmlr   
pretty_xmlss        r   r   r      s    !!!.Hjj5ryyAG[(3J 6J  * 5 5 7E11779QEGJ Fs   B/"B/c                 `    t        t        d| z              dd  }t        |      dk(  rd|z   }|S )N   r1   r!   r`   )hexintlen)dec	hexStrings     r   dec_to_hex_colourr      s6    CCL!!"%I
9~)O	r   c                     | j                  |      }|syg }|d   j                  D ]7  }|j                  |j                  k(  s|j	                  |j
                         9 dj                  |      j                         S )z extract text from a dom node Nr    )getElementsByTagName
childNodesnodeType	TEXT_NODEr   datar   r   )dom_nodetag_namenodelistrcnodes        r   xml_get_textr      so    ,,X6H	B&& !==DNN*IIdii ! 772;r   c                     t        |       }dg|z  }t        |      D ]*  }t        d t        t	        d | |   |                  ||<   , |S )z Matrix-vector multiplication Nc                     | |z   S r   r   xys     r   r   zmatmult.<locals>.<lambda>  s
    AaC r   c                     | |z  S r   r   r   s     r   r   zmatmult.<locals>.<lambda>  s
    ac r   )r   r(   r   listmap)r   vnrowswrows        r   matmultr      sR    FE	AU| Pc/1S61.M)NO#PHr   c                 ,    t        t        | d            S )Nr3   )floatr   )r   s    r   hexstring_to_floatr     s    Y#$$r   c                 4   d}t        |       }|dk(  s|dk(  rn	 t        | dd       dz  t        | dd       dz  t        | dd       dz  g}|dk(  r"|j                  t        | dd       dz         |S |j                  d       	 |S |S # t        $ r d}Y |S w xY w)	am  
    convert '#rrggbb' or '#rrggbbaa' to (r, g, b, a)

    Doctests:
    >>> def test(color):
    ...     rgba = hexcolor_to_rgba(color)
    ...     if rgba is None:
    ...         print(repr(rgba))
    ...     else:
    ...         print(repr([round(c, 2) for c in rgba]))

    >>> test("#1a2b3c")
    [0.1, 0.17, 0.24, 1.0]

    >>> test("#1a2b3c4d")
    [0.1, 0.17, 0.24, 0.3]

    >>> test("")
    None

    >>> test("1a2b3c")
    None

    >>> test("1a2b3c4d")
    None

    >>> test("#1a2b3c4dx")
    None

    >>> test("#1a2b3cx")
    None

    >>> test("#1a2bx")
    None

    >>> test("#1aXb3c4d")
    None
    N   	   r!      r            ?)r   r   r   
ValueError)colorrgbans      r   hexcolor_to_rgbar     s    N DE
AAva		&uQqz236&uQqz236&uQqz2368D Av.uQqz:3>?
 K C  K4K  	DK	s   AB 2B BBc                   6    e Zd ZdZ G d de      ZddZddZy)	dictpropertyz* Property implementation for dictionaries c                   $    e Zd Zd Zd Zd Zd Zy)dictproperty._proxyc                 <    || _         || _        || _        || _        y r   )_obj_fget_fset_fdel)selfobjfgetfsetfdels        r   __init__zdictproperty._proxy.__init__C  s    DIDJDJDJr   c                 h    | j                   t        d      | j                  | j                  |      S )Nzcan't read item)r  	TypeErrorr  r  keys     r   __getitem__zdictproperty._proxy.__getitem__I  s-    zz! 122::dii--r   c                 l    | j                   t        d      | j                  | j                  ||       y )Nzcan't set item)r  r  r  )r  r  values      r   __setitem__zdictproperty._proxy.__setitem__N  s,    zz! 011JJtyy#u-r   c                 j    | j                   t        d      | j                  | j                  |       y )Nzcan't delete item)r  r  r  r  s     r   __delitem__zdictproperty._proxy.__delitem__S  s*    zz! 344JJtyy#&r   N)r   r   r   r  r  r  r  r   r   r   _proxyr  A  s    		.
	.
	'r   r  Nc                 <    || _         || _        || _        || _        y r   )r  r  r  __doc__)r  r
  r  r  docs        r   r  zdictproperty.__init__X  s    


r   c                 n    || S | j                  || j                  | j                  | j                        S r   )r  r  r  r  )r  r	  objtypes      r   __get__zdictproperty.__get__^  s-    ;K{{3

DJJ

CCr   )NNNNr   )r   r   r   r  objectr  r  r  r   r   r   r   r   >  s    4' '.Dr   r   c                    i }|dk(  r%t        j                  dt         j                        }n,|dk(  r%t        j                  dt         j                        }nJ | D ]  }|j                  |      }|sg }|d   D ]7  }|j	                  dd      }|j	                  dd	      }|j                  |       9 |t        k(  r|d   |dd
 i}	n|t        k(  rt        |d         |dd
 i}	nJ |j                  |	        |S )z
    Converts a list of strings into a dict of tuples.
    Sample list: ['LWIN:label:super', ...]
    ":" in a value must be escaped as "\:"
    "\" in a value must be escaped as "\\"
    r!   z([^\s:]+)             # name
                                 : ((?:\\.|[^\\:])*)   # first value
                             r1   z([^\s:]+)             # name
                                 : ((?:\\.|[^\\:])*)   # first value
                                 : ((?:\\.|[^\\:])*)   # second value
                             r   \\\z\::N)	r   r   VERBOSEfindallr   r   strr   update)
_list
num_valueskey_typeresultr   texttuplesr   titems
             r   unpack_name_value_listr0  c  s    F Q** !"$**. 
q** ! #%**.
 	u  &AAY IIfd+IIeS)
 3!!"'SAaD	QqrU,uMM$ " Mr   c                    g }t        | j                               D ]a  }t        |d         }|}|d   D ]6  }|j                  dd      }|j                  |d|z         }||d|z  z   z  }|}8 |j	                  |       c |S )z
    Converts a dict of tuples to a string array. It creates one string
    per dict key, with the key-string separated by <name_sep> and
    individual tuple elements separated by <field_sep>.
    r   r!   r"  r!  z%s)r   itemsr&  r   r   )r-  	field_sepname_sepr+  r.  r,  sepr  s           r   pack_name_value_listr6    s     F&,,.! 1Q4yqT 	EMM$/EMM#tCx0EC$,&&DC		
 	d Mr   c                     t        |       }t        |      }t        |j                               D ]
  \  }}|||<    t        |      S )zI
    Existing entries in text1 will be kept or overwritten by text2.
    )unpack_name_value_tuplesr   r2  pack_name_value_tuples)text1text2tuples1tuples2r  valuess         r   merge_tuple_stringsr?    sJ     'u-G&u-G7==?+ 
F!'**r   c                   :   e Zd ZdZdZd-dZd Zd Zd Zd Z	d Z
d	 Zd
 Zed        Zed        Zed        Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd.dZ d Z!d.d Z"d! Z#d.d"Z$d.d#Z%d$ Z&d% Z'd& Z(d/d'Z)d( Z*d) Z+d/d*Z,d/d+Z-d0d,Z.y)1Rectz
    Simple rectangle class.
    Left and top are included, right and bottom excluded.
    Attributes can be accessed by name or by index, e.g. rect.x or rect[0].
    r   r   r   hc                 <    || _         || _        || _        || _        y r   rB  )r  r   r   r   rC  s        r   r  zRect.__init__  s    r   c                      y)Nr2   r   r  s    r   __len__zRect.__len__  s    r   c                 4    t        | | j                  |         S )z? Collection interface for rvalues, unpacking with '*' operator )getattr
attributes)r  indexs     r   r  zRect.__getitem__  s    tT__U344r   c                 6    t        | | j                  |   |      S )z" Collection interface for lvalues )setattrrJ  )r  rK  r  s      r   r  zRect.__setitem__  s    tT__U3U;;r   c                 X     ddj                   fd j                  D              z   dz   S )NzRect( c              3   V   K   | ]   }d j                  |t        |             " yw)z	{}={:.1f}N)r   rI  )r#   r   r  s     r   r%   zRect.__str__.<locals>.<genexpr>  s-      / !''74+;< /s   &)))r   rJ  rF  s   `r   __str__zRect.__str__  s7    HH /"oo/ //  	r   c                 "    | j                         S r   )rR  rF  s    r   __repr__zRect.__repr__  s    ||~r   c                     | j                   |j                   k(  xrO | j                  |j                  k(  xr4 | j                  |j                  k(  xr | j                  |j                  k(  S r   rB  r  others     r   __eq__zRect.__eq__  X    vv  !vv !vv ! vv 	!r   c                     | j                   |j                   k7  xsO | j                  |j                  k7  xs4 | j                  |j                  k7  xs | j                  |j                  k7  S r   rB  rV  s     r   __ne__zRect.__ne__  rY  r   c                 *    t        | ||| z
  ||z
        S )zy
        New Rect from two points.
        x0 and y0 are considered inside, x1 and y1 are just outside the Rect.
        rA  )x0y0x1y1s       r   from_extentszRect.from_extents  s     BBGR"W--r   c                 6    t        | d   | d   |d   |d         S )z+
        New Rect from two tuples.
        r   r!   r]  )positionsizes     r   from_position_sizezRect.from_position_size  s%    
 HQK!d1gtAw??r   c                 N    t        | d   | d   |d   | d   z
  |d   | d   z
        S )z
        New Rect from two points, left-top and right-botton.
        The former lies inside, while the latter is considered to be
        just outside the rect.
        r   r!   r]  )p0p1s     r   from_pointszRect.from_points  s5     BqE2a5"Q%"Q%-AA??r   c                     | j                   | j                  | j                   | j                  z   | j                  | j                  z   fS r   rB  rF  s    r   
to_extentszRect.to_extents  s1    vvtvv$&&@@r   c                 b    | j                   | j                  f| j                  | j                  ffS r   rB  rF  s    r   to_position_sizezRect.to_position_size  s'    $&&$&&!111r   c                 n    t        | j                  | j                  | j                  | j                        S r   rA  r   r   r   rC  rF  s    r   copyz	Rect.copy  s#    DFFDFFDFFDFF33r   c                 B    | j                   dk  xs | j                  dk  S Nr   r   rC  rF  s    r   is_emptyzRect.is_empty  s    vv{)dffk)r   c                 2    | j                   | j                  fS r   r   rF  s    r   get_positionzRect.get_position      r   c                 2    | j                   | j                  fS r   rt  rF  s    r   get_sizezRect.get_size  rx  r   c                 r    | j                   | j                  dz  z   | j                  | j                  dz  z   fS )N       @r   r   r   rC  rF  s    r   
get_centerzRect.get_center  s/    #%tvv'<==r   c                     | j                   S r   )r   rF  s    r   topzRect.top      vvr   c                     | j                   S r   )r   rF  s    r   r   z	Rect.left  r  r   c                 4    | j                   | j                  z   S r   )r   r   rF  s    r   r   z
Rect.right      vvr   c                 4    | j                   | j                  z   S r   )r   rC  rF  s    r   bottomzRect.bottom  r  r   c                 2    | j                   | j                  fS r   r   rF  s    r   left_topzRect.left_top  s    vvtvv~r   c                     | j                   |d   k  rQ| j                   | j                  z   |d   kD  r2| j                  |d   k  r | j                  | j                  z   |d   kD  ryy)z4 True, if the given point lies inside the rectangle r   r!   TFr}  )r  points     r   is_point_withinzRect.is_point_within  sX    66U1X66DFF?U1X%66U1X66DFF?U1X%r   c                     t        t        | j                        t        | j                        t        | j                        t        | j
                              S r   )rA  roundr   r   r   rC  rF  s    r   r  z
Rect.round  s3    E$&&M5=%-tvvOOr   c                     t        t        | j                        t        | j                        t        | j                        t        | j
                              S r   )rA  r   r   r   r   rC  rF  s    r   r   zRect.int   s3    CKTVVc$&&k3tvv;GGr   Nc                     |d k(  r|}t        | j                  |z  | j                  |z  | j                  |z  | j                  |z        S r   rp  )r  kxkys      r   scalez
Rect.scale#  s?    :BDFFRK"dffrk466B;GGr   c                 z    t        | j                  |z   | j                  |z   | j                  | j                        S )z<
        Returns a new Rect displaced by dx and dy.
        rp  r  dxdys      r   offsetzRect.offset(  s-     DFFRK"dffdff==r   c                     ||}t        | j                  |z
  | j                  |z
  | j                  d|z  z   | j                  d|z  z         S )zO
        Returns a new Rect which is larger by dx and dy on all sides.
        r1   rp  r  s      r   inflatezRect.inflate.  G     :BDFF2Itvvby$&&2+tvvad{CCr   c                     t        | j                  |z
  | j                  |z
  | j                  |z   |z   | j                  |z   |z         S )zP
        Returns a new Rect which is larger by l, t, r, b on all sides.
        rp  )r  r   r  r   r  s        r   apply_borderzRect.apply_border6  sD     DFF4KFF4K%tvvcz&'8: 	:r   c                     ||}t        | j                  |z   | j                  |z   | j                  d|z  z
  | j                  d|z  z
        S )zP
        Returns a new Rect which is smaller by dx and dy on all sides.
        r1   rp  r  s      r   deflatezRect.deflate=  r  r   c                     ||}| j                   |z  }| j                  |z  }t        | j                  | j                   |z
  dz  z   | j                  | j                  |z
  dz  z   ||      S )zH
        Returns a new Rect with its size multiplied by kx, ky.
        r|  )r   rC  rA  r   r   )r  r  r  r   rC  s        r   growz	Rect.growE  sk     :BFFRKFFRKDFFdffqjC//FFdffqjC//q 	r   c                 @   | j                   |j                   |j                  z   k\  xsv | j                   | j                  z   |j                   k  xsN | j                  |j                  |j                  z   k\  xs& | j                  | j                  z   |j                  k   S )a  
        Doctests:
        >>> Rect(0, 0, 1, 1).intersects(Rect(0, 0, 1, 1))
        True
        >>> Rect(0, 0, 1, 1).intersects(Rect(1, 0, 1, 1))
        False
        >>> Rect(1, 0, 1, 1).intersects(Rect(0, 0, 1, 1))
        False
        >>> Rect(0, 0, 1, 1).intersects(Rect(0, 1, 1, 1))
        False
        >>> Rect(0, 1, 1, 1).intersects(Rect(0, 0, 1, 1))
        False
        r}  )r  rects     r   
intersectszRect.intersectsQ  s     FFdfftvvo- .FFTVVOtvv-.FFdfftvvo-. FFTVVOtvv-/ 	/r   c                    t        | j                  |j                        }t        | j                  |j                        }t        | j                  | j                  z   |j                  |j                  z         }t        | j                  | j
                  z   |j                  |j
                  z         }||kD  s||kD  r
t               S t        ||||z
  ||z
        S r   )maxr   r   minr   rC  rA  r  r  r^  r_  r`  ra  s         r   intersectionzRect.intersectione  s    rr$&&466/2r$&&466/2r
r'R"W&=r2rBwR00r   c                    t        | j                  |j                        }t        | j                  |j                        }t        | j                  | j                  z   |j                  |j                  z         }t        | j                  | j
                  z   |j                  |j
                  z         }t        ||||z
  ||z
        S r   )r  r   r   r  r   rC  rA  r  s         r   unionz
Rect.uniono  s    rr$&&466/2r$&&466/2r2r27BG,,r   c                    | j                         s|j                         r
t               S | j                  t        | j                        z  }|j                  t        |j                        z  }|j                         }||kD  rE|j                  |z  |_        |xj                  ||j                  |j                  z
  z  z  c_        |S |j                  |z  |_        |xj                  ||j                  |j                  z
  z  z  c_        |S )zl Returns a new Rect with the aspect ratio of self
            that fits inside the given rectangle.
        )ru  rA  r   r   rC  rq  r   r   )r  r  x_aligny_align
src_aspect
dst_aspectr+  s          r   inscribe_with_aspectzRect.inscribe_with_aspectv  s     ==?dmmo6MVVeDFFm+
VVeDFFm+

"vv
*FHHH466FHH#455H  vv
*FHHH466FHH#455Hr   c                 `   | j                         s|j                         r
t               S |j                  t        |j                        z  }| j                  t        | j                        z  }| j                         }||kD  r| j                  |z  |_        |S | j                  |z  |_        |S )zA
        Resize self to the aspect ratio of aspect_rect.
        )ru  rA  r   r   rC  rq  )r  aspect_rectr  r  r+  s        r   resize_to_aspectzRect.resize_to_aspect  s     ==?k2246M ]]U;==%99
VVeDFFm+

"vv
*FH  vv
*FHr   c                 |   | j                         s|j                         r
t               S |}|j                  rt|j                  t	        |j                        z  }||d   z  }| j                  t	        | j                        z  }t        ||      }t        dd|d      }t        dd|d      }| j                  |      S )zt
        Resize self to get the aspect ratio of aspect_rect, but limited
        to the given aspect range.
        r!   r   r   )ru  rA  rC  r   r   r  r  )r  r  aspect_change_rangera0a0_maxa1r   s           r   resize_to_aspect_rangezRect.resize_to_aspect_range  s    
 ==?k2246M33uQSSz!B-a00F%-'BBAQ1c"AQ1c"A$$Q''r   c                     | j                   | j                  |j                  z
  |z  z   }| j                  | j                  |j                  z
  |z  z   }t	        |||j                  |j                        S )z]
        Aligns the given rect inside of self.
        x/y_align = 0.5 centers rect.
        )r   r   r   rC  rA  )r  r  r  r  r   r   s         r   
align_rectzRect.align_rect  s[    
 FFdfftvvo00FFdfftvvo00Aq$&&$&&))r   c                     || j                   |z  z
  }|| j                  |z  z
  }t        ||| j                   | j                        S )zY
        Aligns the given rect to a point.
        x/y_align = 0.5 centers rect.
        )r   rC  rA  )r  r   r   r  r  s        r   align_at_pointzRect.align_at_point  sC    
     Aq$&&$&&))r   c           
      v   ||}|d}| \  }}}}| j                   |dz
  |z  z
  t        |      z  }	| j                  |dz
  |z  z
  t        |      z  }
g }| j                  }t	        |      D ]K  }| j
                  }t	        |      D ]'  }|j                  t        |||	|
             ||	|z   z  }) ||
|z   z  }M |S )z0 Divide self into columns x rows sub-rectangles r   r!   )r   r   rC  r   r(   r   r   rA  )r  columnsrows	x_spacing	y_spacingr   r   r   rC  wshsrectsr   columns                 r   	subdividezRect.subdivide  s    !II
1aff!y00E'NBffqy00E$K?FF; 	 CA. $T!QB/0R)^#$ iA	  r   )r   r   r   r   r   )      ?r  )NN)/r   r   r   r  rJ  r  rG  r  r  rR  rT  rX  r[  staticmethodrb  rf  rj  rl  rn  rq  ru  rw  rz  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   rA  rA    s    &J5<!! . . @ @ @ @A24*  >PHH
>D:D
/(1-&"(&**r   rA  c                     t        j                  |||      \  }}}|| z  }|dkD  rd}|dk  rd}t        t        j                  |||            |gz   S )z8 Make the given color brighter by amount a [-1.0...1.0] r           )colorsys
rgb_to_hlsr   
hls_to_rgb)amountr  gbr   rC  lr   s           r   brightenr    s^    !!!Q*GAq!KA3w3w##Aq!,-33r   c           	          d } || |d   t         d          || |d   t         d          || |d   t         d          || |d   t         d         gS )z  interpolate between two colors c                     |||z
  | z  z   S r   r   )kr   r  s      r   r   zlinint_rgba.<locals>.<lambda>  s    Q!a%1_ r   r   r!   r1   r   )rgba12)r  rgba1rgba2linints       r   linint_rgbar    sa    ,F1eAhq	*1eAhq	*1eAhq	*1eAhq	*, ,r   c                    |j                   |j                  }}||j                  z   ||j                  z   }}| j	                  ||z   |       | j                  ||z
  |       | j                  ||z
  ||z   |t         dz  d       | j                  |||z
         | j                  ||z
  ||z
  |dt        dz         | j                  ||z   |       | j                  ||z   ||z
  |t        dz  t               | j                  |||z          | j                  ||z   ||z   |t        t        dz         | j                          y )Nr1   r   g      ?)	r   r   r   rC  move_toline_toarcr   
close_path)contextr  r  r^  r_  r`  ra  s          r   roundrect_arcr    s   FFDFFrBKdffrB OOBqD" OOBqDKK1bdAs1ua( OOB1KK1bdAq"Q$' OOBqD"KK1bdAr!tR( OOB1KK1bdAr2c6*r   c           	      P   |j                   }|j                  }|j                  }|j                  }||z   }||z   }t	        ||      t	        |dz  d      z  }	|	dz
  |z  dz  }
| j
                  }| j                  }| j                  ||	z   |        |||	z
  |        |||
z
  ||||
z   |||	z           ||||	z
          ||||
z
  ||
z
  |||	z
  |        |||	z   |        |||
z   ||||
z
  |||	z
          ||||	z           ||||
z   ||
z   |||	z   |       | j                          y)zy
    Uses B-splines for less even looks than with arcs, but
    still allows for approximate circles at r_pct = 100.
          Y@r  r!         i@N)	r   r   r   rC  r  r  curve_tor  r  )r  r  r_pctr^  r_  r   rC  r`  ra  r  r  r  r  s                r   roundrect_curver    sS   
 
B	B	A	A	aB	aBAq	CeS))A	
1eAooGH OOBqD" BqDRT2r2a4RT* B1RAr!tRAr* BqD"RT2r2a4RT* B1RAr!tRAr*r   c                 6    t        |||      }t        | |       y r   )polygon_to_rounded_path"rounded_polygon_path_to_cairo_path)crcoordsr  chamfer_sizepaths        r   rounded_polygonr  (  s    "65,?D&r40r   c           	      ,   g }|dz  t        |dz  d      z  }t        |       }t        d|d      D ]`  }|}|dz   }||k\  r||z  }|dz   }	|	|k\  r|	|z  }	| |   }
| |dz      }| |   }| |dz      }| |	   }| |	dz      }||
z
  }||z
  }t        ||z  ||z  z         }||z  }||z  }||z
  }||z
  }t        ||z  ||z  z         }||z  }||z  }t        ||dz        }t        ||dz        }|dz
  |z  dz  }|dz
  |z  dz  }|dk(  r#|
||z  z   }|||z  z   }|j	                  ||f       |||z  z
  }|||z  z
  }|j	                  ||f       |||z  z   }|||z  z   }|||z  z
  } |||z  z
  }!|||z  z   }"|||z  z   }#|j	                  ||| |!|"|#f       c |S )	a  
    Doctests:
    # simple rectangle, chamfer radius 0.
    >>> coords = [0, 0, 10, 0, 10, 10, 0, 10]
    >>> polygon_to_rounded_path(coords, 0, 0) # doctest: +NORMALIZE_WHITESPACE
    [(0.0, 0.0), (10.0, 0.0), (10.0, 0.0, 10.0, 0.0, 10.0, 0.0),
     (10.0, 10.0), (10.0, 10.0, 10.0, 10.0, 10.0, 10.0),
     (0.0, 10.0), (0.0, 10.0, 0.0, 10.0, 0.0, 10.0),
     (0.0, 0.0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)]
    r|  r  r  r   r1   r2   r!   r  )r  r   r(   r	   r   )$r  r  r  r  r  r   ii0i1i2r^  r_  r`  ra  x2y2vaxvaylauaxuayvbxvbylbubxubyrarbkakbr   r   c0xc0yc1xc1ys$                                       r   r  r  ,  sA    DsSuc22AFA1a^ /0U7!GBU7!GBBZBqD\BZBqD\BZBqD\2g2g#c'CG#$BhBh2g2g#c'CG#$BhBhBHBHde^E!de^E!6RVARVAKKACKCKQFCKCK2c6k2c6k2c6k2c6kQ3S#./_/0b Kr   c           
         |r | j                   |d     t        dt        |      d      D ]O  }||   }| j                  |d   |d          ||dz      }| j	                  |d   |d   |d   |d   |d   |d          Q | j                          y y )Nr   r!   r1   r   r2   r   )r  r(   r   r  r  r  )r  r  r  ps       r   r  r  n  s    

DGq#d)Q' 	<AQAJJqtQqT"QqS	AKK!adAaD!A$!ad;		<
 	 r   c                 J    |j                         D ]  }t        | |||        y r   )iter_polygonsr  )r  r  r  r  polygons        r   rounded_pathr  x  s(    %%' :GUL9:r   c           	      \   | j                  d|dd|d       | j                  dd       | j                          | j                          | j                  |||d||z
  d       | j                  |d       | j                          | j                          | j                  ||d|d||z
         | j                  d|       | j                          | j                          | j                  |||z
  ||||z
  |       | j                  ||       | j                          | j                          y)zT
    Paint 4 round corners.
    Currently x, y are ignored and assumed to be 0.
    r   N)r  r  r  fill)r  r  r   r   r   rC  s         r   round_cornersr  |  s     KKAq!Q"JJ1MMOGGIKKAq!QUA&JJ1MMOGGIKKAq!QA&JJ1MMOGGIKKAE1aQ*JJ1MMOGGIr   c                    | j                   | j                  | j                  | j                  f\  }}}}|dz  }|dz  }| | f|| f||f| |fg}|D 	cg c]%  }	|	d   t	        |      z  |	d   t        |      z  z
  ' }
}	t        |
      t        |
      z
  }|dz  }|t	        |      z  |z   |z   |t        |      z  |z   |z   | t	        |      z  |z   |z   | t        |      z  |z   |z   fS c c}	w )Nr|  r   r!   )r   r   r   rC  r   r   r  r  )r  alphar^  r_  r   rC  r   r  r  cvxr  r  s                r   gradient_liner    s    664664664661LBAq	CA	CArA2hQB!Q1"a1F39	:a!A$s5z/!A$s5z/
)	:B	:	R3r7	B
SAE
NR!#E
NR!#2E
?R!#2E
?R!#% % 
;s   *C,c           	      <   |j                         }| j                  ddd|       t        |      D ]  }|r|ndt        |      z  }	t	        t        t        d|	z
                    dz  |z  }
|j                  |
z   |j                  z  }|j                  |
z   |j                  z  }| j                           | j                  |  | j                  ||       | j                  |d    |d   z   |d    |d   z          | j                  |       | j                           y)zv
    Mostly works, but has issues with clipping artefacts for
    damage rects smaller than the full window rect.
    r  r  r!   gffffff?r   N)r~  set_source_rgbar(   r   r	   absr
   r   rC  save	translater  maskrestore)r  r   boundsblur_radiusr  r  stepsoriginr  r   r  x_scaley_scales                r   drop_shadowr&    s      FsCe,5\ Qe,S1X#%3 88a<688+88a<688+
	f
'"
fQiZ&)+fQiZ&)-CD



r   c              #   Z  K   dd l }dd l}|r|j                          |j                          |j                           |j                          }| r| nd}|j                  d|z         |j	                          d  |j                  d |j                          |z
  dz  z         y d  y w)Nr   timeitz%-15s z	%10.3fms
i  )timegccollectwriteflush)r   outr)  r*  r.  r,  s         r   r(  r(    s     









DIIKq8		(T/"		
		,9499;?D"89:
s   B)B+c                   0    e Zd ZdZed        Zed        Zy)Fadez Helper for opacity fading c                     t        j                          | z
  }|rt        d||z        }nd}t        j                  |||      |dk\  fS )Nr   )r)  r  r0  sin_int)
start_timedurationstart_valuetarget_valueelapsedlin_progresss         r   sin_fadezFade.sin_fade  sM    ))+
*sGh$67LL||L+|Ds"$ 	$r   c                 \    t        | t        z  t        dz  z
        dz   dz  }|||z
  z  |z   S )Nr|  r   )r   r   )r8  r5  r6  sin_progresss       r   r2  zFade.sin_int  s9    L2-S89C?3F|k9:[HHr   N)r   r   r   r  r  r9  r2  r   r   r   r0  r0    s-    %$ $ I Ir   r0  c                   R    e Zd ZdZdZdZdZd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zy)TreeItemzg
    Abstract base class of tree nodes.
    Base class of nodes in  layout- and color scheme tree.
    Nr   c                 .    || _         |D ]	  }| |_         y r   r2  parentr  r2  r/  s      r   	set_itemszTreeItem.set_items  s    
 	DDK	r   c                     | j                   r#| j                   j                  |       | |_        y |g| _         | |_        y r   )r2  r   r@  r  r/  s     r   append_itemzTreeItem.append_item  s6    ::JJd#  DJr   c                 r    | j                   r| xj                   |z  c_         n|| _         |D ]	  }| |_         y r   r?  rA  s      r   append_itemszTreeItem.append_items  s4    ::JJ%JDJ 	DDK	r   c                     | j                   S r   r@  rF  s    r   
get_parentzTreeItem.get_parent  s    {{r   c              #   \   K   | j                         D ]  }|j                  |v s|  ywz! find all items with matching id N)
iter_itemsid)r  idsr/  s      r   find_idszTreeItem.find_ids
  s,     OO% 	Dww#~
	s   ",,c              #   X   K   | j                         D ]  }t        ||      s|  ywrL  )rM  
isinstance)r  item_classesr/  s      r   find_classeszTreeItem.find_classes  s+     OO% 	D$-
	s    **c              #   h   K   |  | j                   D ]  }|j                         D ]  }|   yw)z9
        Iterates through all items of the tree.
        N)r2  rM  r  r/  childs      r   rM  zTreeItem.iter_items  s;      
JJ 	D* 	   02c              #   h   K   | j                   D ]  }|j                         D ]  }|   |  yw)z8
        Iterates depth first through the tree.
        N)r2  iter_depth_firstrV  s      r   rZ  zTreeItem.iter_depth_first   s?      JJ 	D..0 	 
rX  c              #   <   K   | }|r| |j                   }|ry y wr   rI  rD  s     r   iter_to_rootzTreeItem.iter_to_root*  s!     J;;D s   )r   r   r   r  rN  r@  r2  rB  rE  rG  rJ  rP  rT  rM  rZ  r\  r   r   r   r=  r=    sI     
B F E
r   r=  c                   f    e Zd ZdZdZdZddZd Zed        Z	d Z
d Zd Zd	 Zd
 Zd Zd Zd Zy)Versionz. Simple class to encapsulate a version number r   c                      || _         || _        y r   majorminor)r  ra  rb  s      r   r  zVersion.__init__6  s    

r   c                 "    | j                         S r   )	to_stringrF  s    r   rR  zVersion.__str__:  s    ~~r   c                     | j                  d      }d}d}	 t        |      dk\  rt        |d         }t        |      dk\  rt        |d         }t	        ||      S # t        $ r Y w xY w)N.r   r!   r1   )splitr   r   r   r^  )version
componentsra  rb  s       r   from_stringzVersion.from_string=  sv    ]]3'
	:!#JqM*:!#JqM* ue$$  		s   8A 	A'&A'c                 P    dj                  | j                  | j                        S )Nz{major}.{minor}r`  )r   ra  rb  rF  s    r   rd  zVersion.to_stringM  s      ''djj

'KKr   c                 *    | j                  |      dk(  S rs  _cmprV  s     r   rX  zVersion.__eq__P      DIIe$4$99r   c                 *    | j                  |      dk7  S rs  rm  rV  s     r   r[  zVersion.__ne__Q  ro  r   c                 *    | j                  |      dk  S rs  rm  rV  s     r   __lt__zVersion.__lt__R      DIIe$4q$88r   c                 *    | j                  |      dk  S rs  rm  rV  s     r   __le__zVersion.__le__S  ro  r   c                 *    | j                  |      dkD  S rs  rm  rV  s     r   __gt__zVersion.__gt__T  rs  r   c                 *    | j                  |      dk\  S rs  rm  rV  s     r   __ge__zVersion.__ge__U  ro  r   c                     | j                   |j                   k  ry| j                   |j                   kD  ry| j                  |j                  k  ry| j                  |j                  kD  ryy)Nr   r!   r   r`  rV  s     r   rn  zVersion._cmpW  sQ    ::#::#::#::#r   N)r   )r   r   r   r  ra  rb  r  rR  r  rj  rd  rX  r[  rr  ru  rw  ry  rn  r   r   r   r^  r^  1  sL    8EE  % %L :98989	r   r^  c                   P    e Zd ZdZed        Zed        Zed        Zed        Zy)Processz Process utilities c                     d}t        d| z        5 }|j                         }ddd       |j                  d      S # 1 sw Y   xY w)z- Returns the command line for process id pid r   z/proc/%s/cmdlineN )openreadrg  )pidcmdlinefs      r   get_cmdlinezProcess.get_cmdlinef  sH     $s*+ 	qffhG	}}T""	 	s	   ;Ac                 v    t         j                  |       }|r"t        j                  j	                  |d         S y)Nr   r   )r|  r  r   r  basename)r  r  s     r   get_process_namezProcess.get_process_namen  s1    %%c*77##GAJ//r   c                  `    t        j                         } | rt        j                  |       }|S g S )7 Checks if this process was launched by <process_name> )r   getppidr|  r  )ppidr  s     r   get_launch_process_cmdlinez"Process.get_launch_process_cmdlineu  s,     zz|))$/GN	r   c                 P    dj                  t        j                               }| |v S )r  rO  )r   r|  r  )process_namer  s     r   was_launched_byzProcess.was_launched_by~  s&     ((7==?@w&&r   N)	r   r   r   r  r  r  r  r  r  r   r   r   r|  r|  c  sS    # #     ' 'r   r|  c                     t         j                  d   j                  t         j                        D ]C  }t         j                  j                  ||       }t         j                  j                  |      sC y y)zN
    Does a file with this basename exist anywhere in PATH's directories?
    PATHTF)r   environrg  pathsepr  r   isfile)r  r  filenames      r   exists_in_pathr    sW     

6"((4 77<<h/77>>(# r   c                 ^   t        j                  | |       t        j                  |       D ]  \  }}}|D ]6  }t        j                  t         j                  j	                  ||      |       8 |rE|D ]6  }t        j                  t         j                  j	                  ||      |       8  y)zZ
    Change permissions of all files of the given directory tree.
    Raises OSError.
    N)r   chmodwalkr  r   )r  mode	only_dirsrootdirsfilesdr  s           r   	chmodtreer    s    
 HHT4WWT] 6dE 	2AHHRWW\\$*D1	2 6dA.56	6r   c                     t         j                  j                  dk\  rt        |       S t	        |       t
        k(  r| S t        | d      rt        |       S t        |       j                  d      S )zv
    Safe str() function that always returns an unicode string.
    Do nothing if the string was already unicode.
    r   __unicode__utf-8)sysversion_infora  r&  typeunicodehasattrdecode)r	  encodings     r   unicode_strr    sY    
 "3xCyG
sM"s|s8??7##r   c                 p    t         j                  j                  dk(  rt        | |      S t        | |d      S )zh
    Python 2 compatible replacement for builtin open().
    Python 3 added the encoding parameter.
    r1   zUTF-8)r  r  )r  r  ra  r  )r  r  s     r   	open_utf8r    s4    
 "Hd##H4'::r   c                     d t        d      D        D cg c]	  }| |z  r| }}t        |      }g }t        d|z        D ]6  }d}t        |      D ]  }|d|z  z  s|||   z  } |j                  |       8 |S c c}w )z
    Return all permutations of the bits in mask.

    Doctests:
    >>> permute_mask(1)
    [0, 1]
    >>> permute_mask(5)
    [0, 1, 4, 5]
    >>> permute_mask(14)
    [0, 2, 4, 6, 8, 10, 12, 14]
    c              3   &   K   | ]	  }d |z    ywr    r   r"   s     r   r%   zpermute_mask.<locals>.<genexpr>  s     *Fc1c6*Fr&   r'   r1   r   r!   )r(   r   r   )r  bit_mask	bit_masksr   permsr  r   r$   s           r   permute_maskr    s     +GU1X*F %h8O  %I %IAE1a4[ 8 	$C1c6zYs^#	$ 	Q L%s   A;c                   ,    e Zd ZdZed        Zd Zd Zy)Translationa  
    Translations occasionally contain errors in format fields that
    prevent onboard from starting up. This class aims to catch these
    errors gracefully, report and ignore bad translations and then
    just go on.

    Common errors have been:
        - bad field names, e.g. "{filename}" was translated "{path}"
        - bad anonymous fields, e.g. "{}" was translated "{ }"
    c                    	 ddl }t	               }t        j                  | d      |_        |j                  |j                  d<   |j                  |j                  d<   y# t        $ r t        j                  d   }Y ww xY w)z5 setup gettext, install _() function for all modules r   N__builtin__T)fallback__format)
builtinsImportErrorr  modulesr  gettexttranslationugettext__dict__r   )domainr  r.  s      r   installzTranslation.install  sn    	2 M++FTB!"#'(xx)$  	2{{=1H	2s   A A>=A>c                     |st        d      S t        j                  j                  dk  r| j                  j                  |      S | j                  j                  |      S )Nr   r   )r  r  r  ra  r  r  r  )r  msgids     r   r  zTranslation.ugettext  sQ    r?"!!A%##,,U33''..r   c                 >   | j                  |      }	  |j                  |i |}|S # t        t        t        f$ ra} |j                  |i |}t
        j                  dj                  |||j                  j                  t        |                   Y d}~|S d}~ww xY w)z# Safe replacement for str.format() z?_format: Skipping bad translation msgid='{}' msgstr='{}' {}: {}N)
r  r   KeyError
IndexErrorUnicodeDecodeErrorr   r   	__class__r   r  )r  r  argskwargsmsgstrr+  es          r   r   zTranslation.format  s    u%		5"V]]D3F3F  *&89 	5!U\\4262FOO <#VE6$%KK$8$8$/N45 5
 	5s   ' BABBN)r   r   r   r  r  r  r  r   r   r   r   r  r    s%    	 0 0/r   r  c                   L    e Zd ZdZdZd Zd Zd Zd ZddZ	d Z
d	 Zd
 Zd Zy)EventSourcez1 Simple event handling based on python callbacks Nc                 2    t        d |D              | _        y )Nc              3   $   K   | ]  }|g f 
 y wr   r   )r#   r  s     r   r%   z'EventSource.__init__.<locals>.<genexpr>  s     ;!"v;s   )dict
_callbacksr  event_namess     r   r  zEventSource.__init__  s    ;{;;r   c                 $    | j                          y r   )flush_eventsrF  s    r   cleanupzEventSource.cleanup  s    r   c                 N    | j                   |   }||vr|j                  |       y y r   )r  r   r  
event_namecallback	callbackss       r   connectzEventSource.connect
  s+    OOJ/	9$X& %r   c                 N    | j                   |   }||v r|j                  |       y y r   )r  remover  s       r   
disconnectzEventSource.disconnect  s+    OOJ/	y X& !r   c                      |rt         fd|D              S t        d  j                  j                         D              S )zX
        Are there callbacks registered for the given event_names or any event?
        c              3   N   K   | ]  }t        j                  |           y wr   )boolr  )r#   r   r  s     r   r%   z,EventSource.has_listeners.<locals>.<genexpr>  s     KttDOOD12Ks   "%c              3   2   K   | ]  }t        |        y wr   )r  )r#   r  s     r   r%   z,EventSource.has_listeners.<locals>.<genexpr>  s     E54;Es   )anyr  r>  r  s   ` r   has_listenerszEventSource.has_listeners  s7     K{KKKEDOO,B,B,DEEEr   c                 <    | j                   |   D ]
  } ||i |  y)z<
        Send event, call all listener's callbacks.
        N)r  )r  r  r  r  r  s        r   emitzEventSource.emit  s)    
 
3 	&Hd%f%	&r   c                     |||f}| j                   (|g| _         t        j                  | j                         y| j                   j	                  |       y)z.
        Queue up asynchronous event.
        N)_event_queuer   idle_addr  r   )r  r  r  r  events        r   
emit_asynczEventSource.emit_async$  sL    
 T6*$!&DMM$++,$$U+r   c                     | j                   <| j                   D ]  \  }}} | j                  |g|i |  | j                          yy)z3
        Send pending asynchronous events.
        N)r  r  clear_events)r  r  r  r  s       r   r  zEventSource.flush_events0  sU       (,0,=,= 7(
D&		*6t6v67 )r   c                     d| _         y)z5
        Cancel pending asynchronous events.
        N)r  rF  s    r   r  zEventSource.clear_events9  s     !r   r   )r   r   r   r  r  r  r  r  r  r  r  r  r  r  r   r   r   r  r     s8    ;L<'
'
F&
, !r   r  c                       e Zd ZdZedd       Zed        Zedd       Zed        Zed        Z	edd       Z
ed	        Zedd
       Zed        Zed        Zd Zy)XDGDirsa  
    Build paths compliant with XDG Base Directory Specification.
    http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html

    Doctests:

    >>> old_env = os.environ.copy()
    >>> os.environ["HOME"] = "/home/test_user"

    # XDG_CONFIG_HOME unavailable
    >>> os.environ["XDG_CONFIG_HOME"] = ""
    >>> XDGDirs.get_config_home("onboard/test.dat")
    '/home/test_user/.config/onboard/test.dat'

    # XDG_CONFIG_HOME available
    >>> os.environ["XDG_CONFIG_HOME"] = "/home/test_user/.config_home"
    >>> XDGDirs.get_config_home("onboard/test.dat")
    '/home/test_user/.config_home/onboard/test.dat'

    # XDG_DATA_HOME unavailable
    >>> os.environ["XDG_DATA_HOME"] = ""
    >>> XDGDirs.get_data_home("onboard/test.dat")
    '/home/test_user/.local/share/onboard/test.dat'

    # XDG_DATA_HOME available
    >>> os.environ["XDG_DATA_HOME"] = "/home/test_user/.data_home"
    >>> XDGDirs.get_data_home("onboard/test.dat")
    '/home/test_user/.data_home/onboard/test.dat'

    # XDG_CONFIG_DIRS unvailable
    >>> os.environ["XDG_CONFIG_HOME"] = ""
    >>> os.environ["XDG_CONFIG_DIRS"] = ""
    >>> XDGDirs.get_all_config_dirs("onboard/test.dat")
    ['/home/test_user/.config/onboard/test.dat', '/etc/xdg/onboard/test.dat']

    # XDG_CONFIG_DIRS available
    >>> os.environ["XDG_CONFIG_HOME"] = ""
    >>> os.environ["XDG_CONFIG_DIRS"] = "/etc/xdg/xdg-ubuntu:/etc/xdg"
    >>> XDGDirs.get_all_config_dirs("onboard/test.dat")
    ['/home/test_user/.config/onboard/test.dat', '/etc/xdg/xdg-ubuntu/onboard/test.dat', '/etc/xdg/onboard/test.dat']

    # XDG_DATA_DIRS unvailable
    >>> os.environ["XDG_DATA_HOME"] = ""
    >>> os.environ["XDG_DATA_DIRS"] = ""
    >>> XDGDirs.get_all_data_dirs("onboard/test.dat")
    ['/home/test_user/.local/share/onboard/test.dat', '/usr/local/share/onboard/test.dat', '/usr/share/onboard/test.dat']

    # XDG_DATA_DIRS available
    >>> os.environ["XDG_DATA_HOME"] = ""
    >>> os.environ["XDG_DATA_DIRS"] = "/usr/share/gnome:/usr/local/share/:/usr/share/"
    >>> XDGDirs.get_all_data_dirs("onboard/test.dat")
    ['/home/test_user/.local/share/onboard/test.dat', '/usr/share/gnome/onboard/test.dat', '/usr/local/share/onboard/test.dat', '/usr/share/onboard/test.dat']

    >>> os.environ = old_env
    Nc                 v   t         j                  j                  d      }|r6t         j                  j	                  |      st
        j                  d       d}|s=t         j                  j                  t         j                  j                  d      d      }| r t         j                  j                  ||       }|S )z1
        User specific config directory.
        XDG_CONFIG_HOMEz:XDG_CONFIG_HOME doesn't contain an absolute path,ignoring.N~z.config	r   r  r   r  isabsr   r   r   
expanduserfiler  s     r   get_config_homezXDGDirs.get_config_home  s    
 zz~~/0d+OO ( )D77<< 2 23 7CD77<<d+Dr   c                      g } t         j                  j                  d      }|sd}|j                  d      } | D cg c]$  }t         j                  j                  |      s#|& } }| S c c}w )z;
        Config directories ordered by preference.
        XDG_CONFIG_DIRSz/etc/xdgr#  r   r  r   rg  r  r  pathsr  r  s      r   get_config_dirszXDGDirs.get_config_dirs  s^    
 

01EC !6qRWW]]1%566 7   $A( A(c                     t         j                         gt         j                         z   }| r-|D cg c]"  }t        j                  j                  ||       $ }}|S c c}w r   )r  r  r  r   r  r   r  r  r  s      r   get_all_config_dirszXDGDirs.get_all_config_dirs  sP    ((*+g.E.E.GG49:qRWW\\!T*:E: ;   'Ac                     t         j                  |       }|D cg c]P  }t        j                  j	                  t              s't        j
                  t        t        j                        r|R c}S c c}w )z> Find file in all config directories, highest priority first. )r  r  r   r  r  accessr  R_OKr  s      r   find_config_fileszXDGDirs.find_config_files  sX     ++D1  BaBGGNN4$8$&IIh$@  B 	B B   (A2,A2c                 <    t         j                  |       }|r|d   S yz Find file of highest priority r   N)r  r  r  r  s     r   find_config_filezXDGDirs.find_config_file  s#     ))$/8Or   c                 x   t         j                  j                  d      }|r6t         j                  j	                  |      st
        j                  d       d}|s>t         j                  j                  t         j                  j                  d      dd      }| r t         j                  j                  ||       }|S )z/
        User specific data directory.
        XDG_DATA_HOMEz8XDG_DATA_HOME doesn't contain an absolute path,ignoring.Nr  z.localsharer  r  s     r   get_data_homezXDGDirs.get_data_home  s    
 zz~~o.d+OO ( )D77<< 2 23 77KD77<<d+Dr   c                      g } t         j                  j                  d      }|sd}|j                  d      } | D cg c]$  }t         j                  j                  |      s#|& } }| S c c}w )z9
        Data directories ordered by preference.
        XDG_DATA_DIRSz/usr/local/share/:/usr/share/r#  r   r  s      r   get_data_dirszXDGDirs.get_data_dirs  s]    
 

/3EC !6qRWW]]1%566 7r  c                     t         j                         gt         j                         z   }| r-|D cg c]"  }t        j                  j                  ||       $ }}|S c c}w r   )r  r  r  r   r  r   r  s      r   get_all_data_dirszXDGDirs.get_all_data_dirs  sP    &&()G,A,A,CC49:qRWW\\!T*:E: ;r  c                     t         j                  |       }|D cg c]P  }t        j                  j	                  t              s't        j
                  t        t        j                        r|R c}S c c}w )z< Find file in all data directories, highest priority first. )r  r  r   r  r  r
  r  r  r  s      r   find_data_fileszXDGDirs.find_data_files  sX     ))$/  BaBGGNN4$8$&IIh$@  B 	B Br  c                 <    t         j                  |       }|r|d   S yr  )r  r  r  s     r   find_data_filezXDGDirs.find_data_file  s#     ''-8Or   c           
          t         j                  j                  |       }|s	 t        j                  | d       d}|S |S # t        $ r0}t
        j                  t        d| t        |                   |d}~ww xY w)zQ
        If necessary create user XDG directory.
        Raises OSError.
        i  )r  Tz#failed to create directory '{}': {}N)	r   r  existsmakedirsOSErrorr   errorr  r  )r  r   exs      r   assure_user_dir_existszXDGDirs.assure_user_dir_exists  sr    
 %D/
 v	  g&K'+[_> ?s   A   	A9	+A44A9r   )r   r   r   r  r  r  r  r  r  r  r  r  r  r  r  r%  r   r   r   r  r  @  s    =~  "     B B    "     B B  r   r  z(?:
            <[\w\-_]+                         # tag
            (?:\s+[\w\-_]+=["'][^"']*["'])*  # attributes
            /?>
        ) |
        (?:
            </?[\w\-_]+>
        )
    c              #      K   d}t         j                  |       }|D ]A  }| ||j                          }|r|df |j                         df |j	                         }C | |d }|r|df yyw)a  
    Iterate over tag and non-tag sections of a markup string.

    Doctests:
    # Never yield for empty string
    >>> list(_iter_markup(""))
    []

    # must return tag- as well as non-tag sections
    >>> list(_iter_markup("<tt>test</tt>test2"))
    [('<tt>', True), ('test', False), ('</tt>', True), ('test2', False)]

    # should recognize tags with attributes
    >>> list(_iter_markup('<tag attr="value">'))
    [('<tag attr="value">', True)]
    >>> list(_iter_markup('<tag attr="v alue" attr2="234">'))
    [('<tag attr="v alue" attr2="234">', True)]

    # should recognize tags with end shortcut
    >>> list(_iter_markup('<tag/> <tag2 attr="value"/>'))
    [('<tag/>', True), (' ', False), ('<tag2 attr="value"/>', True)]

    # must not modify input, i.e. concatenated result must equal input text
    >>> markup = "asd <tt>t est\n ds</tt> te st2 "
    >>> "".join([text for text, tag in _iter_markup(markup)]) == markup
    True
    r   FTN)_tag_patternfinditerstartr   r   )markupposmatchesr   r,  s        r   _iter_markupr-    s     8 C##F+G c!'')$+ggioeeg #$<DEk s   A-A/c           
          d}t        |       D ](  \  }}|r|r||z  }	 |t        j                  |      z  }* |S # t        $ r8}t        j                  dj                  |t        |                   Y d}~id}~ww xY w)a  
    Escape strings of uncertain content for use in Gtk markup.
    If requested, markup tags are skipped and won't be escaped.

    Doctests:
    >>> escape_markup("&<>")
    '&amp;&lt;&gt;'

    # tags must be escaped when preserve_tags is False
    >>> escape_markup("<big>&<></big>")
    '&lt;big&gt;&amp;&lt;&gt;&lt;/big&gt;'

    # tags must not be escaped when preserve_tags is True
    >>> escape_markup('<big>&</big>><tag attr="value"><</tag>1<3', True)
    '<big>&amp;</big>&gt;<tag attr="value">&lt;</tag>1&lt;3'

    # whitespace must be preserved
    >>> escape_markup("test <big> test2& </big> test3", True)
    'test <big> test2&amp; </big> test3'
    r   z&markup_escape_text failed for '{}': {}N)r-  r   markup_escape_text	Exceptionr   r#  r   r  )r*  preserve_tagsr+  r,  is_tagr$  s         r   escape_markupr3  :  s    * F$V, 	<fmdNF<$11$77	< M	  < +#VD+b/:< <<s   ;	A<.A77A<c            
       b    e Zd ZdZ ed      \
  ZZZZZ	Z
ZZZZi Zd Zd Zd Zd Zed        Zy)	
TermColorsz5 Singleton class providing ANSI terminal color codes 
   c                     t        | d      s8t        j                  | g|i || _        | j                  j	                          | j                  S )z Singleton magic.  r  )r  r  __new__r  	construct)clsr  r  s      r   r8  zTermColors.__new__g  s?    sF#~~c;D;F;CHHH xxr   c                      y)z% Called multiple times, do not use.  Nr   rF  s    r   r  zTermColors.__init__n  s    r   c                      y)z) Singleton constructor, runs only once.  Nr   rF  s    r   r9  zTermColors.constructr  s    r   c                 `   | j                   j                  |      }|d}|}|| j                  k\  r-|| j                  k  r| j	                  dt        |      z         }nA|| j                  k(  r| j	                  d      }n || j                  k(  r| j	                  d      }|| j                   |<   |S )ze
        Return ANSI character sequence for the given sequence id,
        e.g. color index.
        r   zsetaf boldsgr0)	sequencesr   BLACKWHITE_tputr&  BOLDRESET)r  seq_idseqs      r   r   zTermColors.getu  s    
 nn  (;C>TZZ'Fdjj,@**XF%;<Ctyy(**V,Ctzz)**V,C%(DNN6"
r   c                     	 t        j                  d| z   j                               }|j                  d      S # t         j                  $ r Y yw xY w)Nztput ASCIIr   )
subprocesscheck_outputrg  r  CalledProcessError)paramsr   s     r   rC  zTermColors._tput  sL    	''6)9(@(@(BCA88G$$,, 		s   69 AAN)r   r   r   r  r(   rA  REDGREENYELLOWBLUEMAGENTACYANrB  rD  rE  r@  r8  r  r9  r   r  rC  r   r   r   r5  r5  ]  sW    ? )E3vtWdE% I8$  r   r5  r   )r#  r#  )r  )   )d   )g      @)r   r   gQ?r2   )i  F)r  )r  )F)\
__future__r   r   r   r  r   r)  r   r  r  rJ  mathr   r   r   r	   r
   
contextlibr   logging	functoolsr   gi.repositoryr   	getLoggerr   r   r   r)   r*   r-   r0   LABEL_MODIFIERSr   r   r   r  r   otherDicfuncKeysr   r   r   r   r   r   r   r   r   r   r   r  r   r&  r0  r6  r?  rA  r  r  r  r  r  r  r  r  r  r  cairor&  stdoutr(  r0  r=  r^  r|  r  r  r  r  r  r  r  r  r   UNICODEr   r$  r'  r-  r3  r5  r   r   r   <module>rc     s  . B A 
 	  	    ( ( %   
'

G
$ , , //..!//" //"
 	 xx	 JJJO$JK K K M"$ 
gFU VU X E	
 % 4 H 5 % 8 5 5 U U C  C!" 58" )V($	%4l#D6 #DJ ./3 'R$+j jZ	4,2%N1@D:4% AG450 **  "I I$Lv L^/f /d' 'D6$ ;2. .b=!& =!@B BJ rzz 
BII	bjj	(	*'T F0 0r   