
    it                       d dl mZ d dlZd dlmZ d dlmZmZ d dlm	Z	 d dl
mZmZmZmZmZmZmZmZ d dlmZ d dlmZmZmZ d d	lmZmZmZ erd d
lmZmZm Z m!Z! ddZ"	 d dl#m$Z$ dZ%e%r@e$jN                  Z(e$jR                  e$jT                  z  e$jV                  z  Z,dZ-e$jV                  Z. ej^                  e0      Z1g dZ2eee3e3e3f   e3ge3f   Z4ee3gee3e3e3e3f   f   Z5eee6e6e6f   ee6   gee6ddf   f   Z7ee3ee   ee   ee   e3geeeeef   eeddf   f   f   Z8 G d de      Z9ddZ:ddZ;	 	 	 	 	 	 ddZ<ddZ=y# e&$ r dZ%Y w xY w)    )annotationsN)mkdir)abspathexists)Thread)TYPE_CHECKINGAnyCallableDict	GeneratorListOptionalTuple)pathname2url)NO_STOREVALID_STOREStore)
IdentifierNodeURIRef)Graph_ContextType_TriplePatternType_TripleTypec                $    | j                  d      S Nutf-8)encode)us    OC:\Projects\mas-dev\.venv\Lib\site-packages\rdflib/plugins/stores/berkeleydb.pybbr!      s    88G    )dbTFi   )
BerkeleyDB
_ToKeyFunc_FromKeyFunc_GetPrefixFunc_ResultsFromKeyFuncc                      e Zd ZU dZdZdZdZdZdZde	d<   	 	 d	 	 	 d fdZ
d dZ ee      Z	 d!	 	 	 	 	 d"d	Zd#d
Zd!d$dZd%dZd%dZd&d'dZ	 	 d(	 	 	 	 	 	 	 	 	 d)dZ	 	 d(	 	 	 	 	 	 	 	 	 d*dZ	 d+	 	 	 	 	 	 	 d,dZ	 	 d	 	 	 	 	 	 	 d-dZd+d.dZd!d/dZd0dZd1dZd2dZ	 d+	 	 	 d3dZd4dZd5dZd6dZ d+d7dZ!	 d+	 	 	 	 	 	 	 d8dZ" xZ#S )9r$   aQ      A store that allows for on-disk persistent using BerkeleyDB, a fast
    key/value DB.

    This store implementation used to be known, previous to rdflib 6.0.0
    as 'Sleepycat' due to that being the then name of the Python wrapper
    for BerkeleyDB.

    This store allows for quads as well as triples. See examples of use
    in both the `examples.berkeleydb_example` and ``test/test_store/test_store_berkeleydb.py``
    files.

    **NOTE on installation**:

    To use this store, you must have BerkeleyDB installed on your system
    separately to Python (``brew install berkeley-db`` on a Mac) and also have
    the BerkeleyDB Python wrapper installed (``pip install berkeleydb``).
    You may need to install BerkeleyDB Python wrapper like this:
    ``YES_I_HAVE_THE_RIGHT_TO_USE_THIS_BERKELEY_DB_VERSION=1 pip install berkeleydb``
    TFNdb.DBEnvdb_envc                    t         st        d      d| _        || _        t        t
        |   |       | j                  j                  | _	        | j                  j                  | _        |  y )Nz/Unable to import berkeleydb, store is unusable.F)	has_bsddbImportError_BerkeleyDB__open_BerkeleyDB__identifiersuperr$   __init__node_picklerloads_loadsdumps_dumps)selfconfiguration
identifier	__class__s      r    r2   zBerkeleyDB.__init__[   s[    
 OPP&j$(7''--''--r"   c                    | j                   S N)r0   r8   s    r    __get_identifierzBerkeleyDB.__get_identifieri   s       r"   c                8   t        |      s'|du rt        |       | j                  |       nt        S t	        j
                         }|j                  dt               |j                  t        d       |j                  |t        t        j                  z         |S )NTr      )r   r   creater   r#   DBEnvset_cachesize	CACHESIZE	set_flagsENVSETFLAGSopenENVFLAGS	DB_CREATE)r8   homeDirrB   r+   s       r    _init_db_environmentzBerkeleyDB._init_db_environmentn   sq     g~gG$Q	*a(GX45r"   c                    | j                   S r=   )r/   r>   s    r    is_openzBerkeleyDB.is_open   s    {{r"   c                	   t         st        S |}| j                  "t        t	        t        |                  | _        | j                  ||      }|t        k(  rt        S || _        d| _        d }t        j                  }t        }| j                  du r|t        j                  z  }|r|t        j                  z  }d}d}	d gdz  | _        d gdz  | _        t#        dd      D ]  }
 t%        |
      dj'                  d      dj'                  d      dj'                  d      fd	j'                  d            j)                         }t        j*                  |      }|j-                  |	       |j/                  |||||       || j                  |
<   |t%        |
      t1        |
      f| j                   |
<    i }t#        dd
      D ]  }
g }t#        dd      D ]L  }d}d}t#        ||dz         D ]  }|
d|dz  z  z  r|dz  }|dz  } n d|z
  }|j3                  ||f||f       N |j5                          |d   \  }}}dd}| j                  |    ||||z         t1        |      t7        || j8                        f||
<    || _        t        j*                  |      | _        | j<                  j-                  |	       | j<                  j/                  d||||       t        j*                  |      | _        | j>                  j-                  |	       | j>                  j/                  d||||       t        j*                  |      | _         | j@                  j-                  |	       | j@                  j/                  d||||       t        j*                  |      | _!        | jB                  j-                  |	       | jB                  j/                  d|t        jD                  ||       t        j*                  |      | _#        | jF                  j-                  |	       | jF                  j/                  d|t        jH                  ||       d| _%        tM        | jN                        }|jQ                  d       |jS                          || _*        tV        S )NTi  r      slatin-1poc   rA      c                $     	 	 	 	 	 	 d fd}|S )Nc              3  d   K   |d n| }|k  r| |dz      |dz  }|k  rd y w)N rP   rA    )triplecontextiendstarts      r    
get_prefixz<BerkeleyDB.open.<locals>.get_prefix_func.<locals>.get_prefix   sK       %Ac'$QUm+Q c' Hs   '00)r]   zTuple[str, str, str]r^   Optional[str]returnzGenerator[str, None, None]r\   )ra   r`   rb   s   `` r    get_prefix_funcz(BerkeleyDB.open.<locals>.get_prefix_func   s(    0;H/ "!r"   contexts	namespaceprefixk2ii2kF)target)ra   intr`   rl   rd   r'   ),r-   r   r0   r   r   r   rL   r+   r/   r#   DB_BTREEDBOPENFLAGStransaction_awareDB_AUTO_COMMITrJ   _BerkeleyDB__indicies_BerkeleyDB__indicies_inforangeto_key_funcr   decodeDBrF   rH   from_key_funcappendsortresults_from_key_func_from_string_BerkeleyDB__lookup_dict_BerkeleyDB__contexts_BerkeleyDB__namespace_BerkeleyDB__prefix_BerkeleyDB__k2iDB_HASH_BerkeleyDB__i2kDB_RECNO_BerkeleyDB__needs_syncr   _BerkeleyDB__sync_run	setDaemonra   _BerkeleyDB__sync_threadr   )r8   pathrB   rK   r+   dbnamedbtypedbopenflagsdbmode
dbsetflagsr_   
index_nameindexlookupresultsra   scorelenj	tie_breakre   ts                         r    rH   zBerkeleyDB.open   s   O$ &|GG4D'E FD**7F;XO "!!T)2,,,K2<<'K
 (
(  
  q!A'QI&

9(=szz)?TU

9% fh  EE&MEOOJ'JJz66;G!&DOOA',k!nmA>N&OD  #   	 q!A>@Gq!ueai0AA!a%L) %
q 1 I		 2E3?@ % LLN !(E5#"" &us{3e$%eT->->?	F1II V $%%-!!*-ZfM55="":.k66;Of
+8VV[&IUU6]


Z(

vrzz;GUU6]


Z(

vr{{KH!$//*	D		r"   c                   ddl m}m } 	 d\  }}| j                  r| j                  r |       x}}d| _        | j                  r |d       | j                  r |       }d| _         |       |z
  |kD  s |       |z
  |kD  r-d| _        t        j                  d       | j                          n| j                  rvn |d       | j                  ry y # t        $ r}t        j                  |       Y d }~y d }~ww xY w)Nr   )sleeptime)
   i,  Fg?syncrA   )	r   r   r/   r   loggerdebugr   	Exception	exception)r8   r   r   min_secondsmax_secondst0t1es           r    
__sync_runzBerkeleyDB.__sync_run   s    $	 '.$K++$$"f$B(-D%++c
,,!%B05D-6B;4k8Q05D-"LL0 IIK! ++ !H ++   	 Q	 s   B.C 9C 	C9C44C9c                d   | j                   r| j                  D ]  }|j                           | j                  j                          | j                  j                          | j
                  j                          | j                  j                          | j                  j                          y y r=   )r/   rq   r   r}   r~   r   r   r   )r8   r_   s     r    r   zBerkeleyDB.sync  ss    ;;__ %OO  "!!#MM JJOOJJOO r"   c                   d| _         | j                  j                          | j                  D ]  }|j	                           | j
                  j	                          | j                  j	                          | j                  j	                          | j                  j	                          | j                  j	                          | j                  j	                          y )NF)r/   r   joinrq   closer}   r~   r   r   r   r+   )r8   commit_pending_transactionr_   s      r    r   zBerkeleyDB.close!  s    !AGGI ! 



r"   c                   |\  }}}| j                   sJ d       || k7  sJ d       t        j                  | |||f||       | j                  } |||      }	 |||      }
 |||      } |||      }| j                  \  }}}|j                  t        |d|	d|
d|d      |      }|| j                  j                  t        |      d|       |j                  t        dd|	d|
d|d      |      xs dj                  d      }t        |j                  dj                  d                  }|j                  t        |             dj                  d      j                  |      }|J |j                  t        |d|	d|
d|d      d|       |j                  t        |d|
d|d|	d      d|       |j                  t        |d|d|	d|
d      d|       |s{|j                  t        dd|	d|
d|d      ||       |j                  t        dd|
d|d|	d      ||       |j                  t        dd|d|	d|
d      ||       d	| _        yy)
z6        Add a triple to the store of triples.
        The Store must be open.z$Can not add triple directly to storetxn^Nr"   r[   rR   T)r/   r   add
_to_stringrq   getr!   r}   putr   setsplitr   r   )r8   r]   r^   quotedr   subject	predicateobjectr   rQ   rS   rT   rU   cspocposcospvaluecontexts_valuerf   s                      r    r   zBerkeleyDB.add-  s:    (.$)V{{555{$F FF		$)V4gvF__
wC(yc*v3'wC(??dDaAq9:D=OO1s4!XXRAq12 &  &9%  >//

90EFGHLLA ZZ	277AN!---HHR!Q156HEHHR!Q156HEHHR!Q156HEb!Q:;^QTUb!Q:;^QTUb!Q:;^QTU $D' r"   c                \   |\  }}}| j                   \  }}	}
|j                  dj                  d      j                  dj                  d      |||dj                  d      g      |      xs dj                  d      }t	        |j                  dj                  d                  }|j                  |       dj                  d      j                  |      }| j                  D ]#  \  }}}|j                   ||||f|      |       % |s|rC| j                  D ]3  \  }}}|j                   ||||fdj                  d            ||       5 y | j                  D ]3  \  }}}	 |j                   ||||fdj                  d            |       5 y y # t        j                  $ r Y Mw xY w)Nr   rR   r[   r   )rq   r   r   r   r   r   discardrr   deleter   r#   DBNotFoundError)r8   sporU   r   r   rQ   rS   rT   r   r   r   r   rf   r_   _to_key	_from_keys                   r    __removezBerkeleyDB.__remove[  s    1a??dDJJy!&&9%q!Q		)0DE 	 " 
 "
 YYy! 	 ~++CJJy,ABCI.33H=%)%9%9!Aw	HHWaAY*H4 &:-1-A-A)Aw	EEAq	299Y+?@&   .B .2-A-A)Aw	!QBIIi4H!IsS .B  -- s   %,FF+*F+c                6   |\  }}}| j                   sJ d       t        j                  | |||f|       | j                  }||| k(  rd }|||| |||      } |||      }	 |||      }
 |||      }| j                  d   j                  t        |d|d|	d|
d      |      }|C| j                  t        |      t        |	      t        |
      ft        |      |       d| _        y y | j                  \  }}}| j                  |||f||      \  }}}}|j                  |      }	 |j                  |      }d}|j                          |r0|\  }}|j                  |      }	 |j                  |        t        |d             }|j                          |j!                  |      r ||      \  }}}	}
||j                  ||      xs dj#                  d	      }t%        |j'                  dj#                  d	                  }|j)                  dj#                  d	             |D ]4  }| j*                  D ]#  \  }}}|j-                   |||	|
f|      |       % 6 n| j                  ||	|
f||       nn|r0|5|3|1|/	 | j.                  j-                  t         |||            |       || _        y # t        j                  $ r d }d}Y w xY w# t        j                  $ r d }Y kw xY w# t        j                  $ r Y Ww xY w)
Nr   r   r   r   TFnextr[   rR   )r/   r   remover   rq   r   r!   _BerkeleyDB__remover   _BerkeleyDB__lookupcursor	set_ranger#   r   r   getattr
startswithr   r   r   r   rr   r   r}   )r8   r   r^   r   r   r   r   r   rQ   rS   rT   rU   r   r   r   r   r   rh   from_keyresults_from_keyr   current
needs_synckeyr   rf   r_   r   _s                                r    r   zBerkeleyDB.remove  sF    &)"F{{555{TGY7A__
$ %"#7,A9#.A6s+A7,AOOA&**21a.K+LRU*VE r!ubeRU3RUD$(! !  $D$8<)V,g3 9F 95E68%5 \\c\*F# **62!
 LLN$
U#.#$$S)5gff57G >>&) "*#JAq!Q).3C)@)XBIIiDX#&~';';CJJy<Q'R#S RYYy%9:!)A151E1E7A
 !"!QA)>C H 2F "* q!Qi<C F "?y'8V^..z's;<# /  !+De %% #"
# )) #"G#H -- s6   3K 1"K& .L K#"K#&K?>K?LLc              #  h  K   | j                   sJ d       |\  }}}||| k(  rd}| j                  |||f||      \  }}}	}
|j                  |      }	 |j                  |      }|j                          |r|\  }}|j                  |      }	 |j                  |        t        |d             }|j                          |r3|j                  |      r"|j                  ||      } |
|||||       ny|ryy# t        j
                  $ r d}Y w xY w# t        j
                  $ r d}Y }w xY ww)z)A generator over all the triples matchingr   Nr   r   )
r/   r   r   r   r#   r   r   r   r   r   )r8   r   r^   r   r   r   r   r   rh   r   r   r   r   r   r   r   s                   r    tripleszBerkeleyDB.triples  sV     {{555{%("F$ 59MMi('s 5B 5
1vx!1 #&	&&v.G 	 JC\\c\*F  %1'&&13 LLNs~~f-!&3C!8 'sGYWW#  !! 	G	 %% sU   AD2C< %)D2"D 1AD2:D2<DD2DD2D/,D2.D//D2c                   | j                   sJ d       ||| k(  rd }|dj                  d      }nt        d| j                  |      z        }| j                  d   }|j                         }|j                  |      }d}|r1|\  }}|j                  |      r|dz  } t        |d             }nn|r1|j                          |S )Nr   r   rR   z%s^r   rA   r   )
r/   r   r!   r   rq   r   r   r   r   r   )	r8   r^   rh   r   r   r   countr   r   s	            r    __len__zBerkeleyDB.__len__  s    {{555{$?ZZ	*F 889F"""6* JC~~f%
1'&&13  	r"   c                   |j                  d      }|j                  d      }| j                  j                  |      }| j                  j                  |      }|rY|r| j                  j	                  |       |r| j                  j	                  |       || j                  |<   || j                  |<   y |xs || j                  |xs |<   |xs || j                  |xs |<   y r   )r   r   r   r~   r   )r8   rh   rg   overridebound_prefixbound_namespaces         r    bindzBerkeleyDB.bind%  s     w'$$W-	}}((3**..v6  ''5$$_5'-DMM)$'0DV$:F:P&DMM/6Y77F7S)D\3V4r"   c                    |j                  d      }| j                  j                  |d       }|t        |j	                  d            S y r   )r   r~   r   r   ru   )r8   rh   nss      r    rg   zBerkeleyDB.namespace9  sF     w'!!&$/>"))G,--r"   c                    |j                  d      }| j                  j                  |d       }||j                  d      S y r   )r   r   r   ru   )r8   rg   rh   s      r    rh   zBerkeleyDB.prefixC  sB     $$W-	""9d3==))r"   c              #  N  K   | j                   j                         }g }|j                         }|rJ|\  }}|j                  |j	                  d      |j	                  d      f        t        |d             }|rJ|j                          |D ]  \  }}|t        |      f  y w)Nr   r   )r~   r   firstrx   ru   r   r   r   )r8   r   r   r   rh   rg   s         r    
namespaceszBerkeleyDB.namespacesM  s     !!((*,,. 'FINNFMM'2I4D4DW4MNO-gff-/G	 
 	!(FI&+++ ")s   A8B%;*B%c              #    K   | j                   }| j                  }|r|\  }}} ||      } ||      } ||      }| j                  d   j                  t	        dd|d|d|d            }|r3|j                  dj                  d            D ]  }|s ||        y y | j                  }	|	j                         }
|
j                         }|
j                          |rX|\  }} ||      }| |	j                         }
	 |
j                  |        t        |
d             }|
j                          |rWy y # t        j                  $ r d }Y ,w xY ww)Nr   r[   r   rR   r   )r{   r   rq   r   r!   r   r   r}   r   r   r   r   r   r#   r   )r8   r]   r{   r   rQ   rS   rT   rf   rU   r   r   r   r   r   r^   s                  r    rf   zBerkeleyDB.contextsZ  s@     ((__
 
 GAq!1A1A1Aq)--b2q!Q1O.PQH!

9(=>A*1o- ?  OOE\\^FllnGLLN$
U&s+#$$S)5gff57G   )) #"G#s7   BEA-E"D; &E9E;EEEEc                l    | j                   j                  t        | j                  |            d       y )Nr"   )r}   r   r!   r   r8   graphs     r    	add_graphzBerkeleyDB.add_graph  s$    Btu56<r"   c                (    | j                  d|       y )N)NNN)r   r   s     r    remove_graphzBerkeleyDB.remove_graph  s    &.r"   c                l    | j                   j                  t        |            }| j                  |      S r=   )r   r   rl   r5   )r8   r_   ks      r    r{   zBerkeleyDB._from_string  s&    JJNN3q6"{{1~r"   c                v   | j                  |      }| j                  j                  ||      }|x| j                  r d| j                  j                  ||      z  }nd| j                  j                  |      z  }| j                  j                  ||j                         |       |S |j                         }|S )Nr   z%s)	r7   r   r   ro   r   rx   r   r   ru   )r8   termr   r   r_   s        r    r   zBerkeleyDB._to_string  s    KKJJNN1#N&9 %%4::,,Q444::,,Q//JJNN1ahhjcN2  
Ar"   c           	     $   |\  }}}| j                   }|
 |||      }d}||dz  } |||      }||dz  } |||      }||dz  } |||      }| j                  |   \  }	}
}}t        dj                   |
|||f|                  }|	|||fS )Nr   r   rA   rW      r   )r   r|   r!   r   )r8   r   r^   r   r   r   r   r   r_   r   prefix_funcr   r   rh   s                 r    __lookupzBerkeleyDB.__lookup  s     &)"F__
 c2GFA c2G FA"9#6IFAC0F9=9K9KA9N6{H&6
 CHH['9f)EwOPQfh(888r"   )NN)r9   rc   r:   Optional[Identifier])rd   r   )T)rK   strrB   boolrd   r*   )rd   r   )r   r   rB   r   rd   zOptional[int])rd   None)F)r   r   rd   r   )FN)
r]   r   r^   r   r   r   r   Optional[Any]rd   r   )
r   Tuple[bytes, bytes, bytes]rU   bytesr   r   r   r   rd   r   r=   )r   r   r^   Optional[_ContextType]r   r   rd   r   )r   r   r^   r   r   r   rd   zXGenerator[Tuple[_TripleType, Generator[Optional[_ContextType], None, None]], None, None])r^   r   rd   rl   )rh   r   rg   r   r   r   rd   r   )rh   r   rd   zOptional[URIRef])rg   r   rd   rc   )rd   z)Generator[Tuple[str, URIRef], None, None])r]   zOptional[_TripleType]rd   z#Generator[_ContextType, None, None])r   r   rd   r   )r   r   )r_   r   rd   r   )r   r   r   r   rd   r   )r   r   r^   r   r   r   rd   z6Tuple[db.DB, bytes, _FromKeyFunc, _ResultsFromKeyFunc])$__name__
__module____qualname____doc__context_awareformula_awarero   graph_awarer+   __annotations__r2   _BerkeleyDB__get_identifierpropertyr:   rL   rN   rH   r   r   r   r   r   r   r   r   r   rg   rh   r   rf   r   r   r{   r   r   __classcell__)r;   s   @r    r$   r$   ?   s   * MMKFH (,+/I$I )I! *+J ,0$(	"{z 0
  !,%,% ,% 	,%
 ,% 
,%d !!'! ! 	!
 ! 
!P "	Y+Y+ (Y+ 	Y+
 
Y+| +/!	// (/ 	/

/b4T(, /3*+*	,*X=/( "	99 (9 	9
 
@9r"   r$   c                     d fd}|S )Nc           	         dj                  d      j                  || dz     | dz   dz     | dz   dz     dj                  d      f      S )zTakes a string; returns keyr   rR   rP   rA   rW   r[   )r   r   )r]   r^   r_   s     r    to_keyzto_key_func.<locals>.to_key  s^    zz)$))q1uA{#A{#		)$
 	
r"   )r]   r   r^   r   rd   r   r\   )r_   r
  s   ` r    rt   rt     s    

 Mr"   c                     d fd}|S )Nc                    | j                  dj                  d            }|d   |dz
  dz   dz  dz      |dz
  dz   dz  dz      |dz
  dz   dz  dz      fS )zTakes a key; returns stringr   rR   r   rP   rA   rW   r   r   )r   partsr_   s     r    r   zfrom_key_func.<locals>.from_key  sv    		#**Y/0!H1q519/A%&1q519/A%&1q519/A%&	
 	
r"   )r   r   rd   z!Tuple[bytes, bytes, bytes, bytes]r\   )r_   r   s   ` r    rw   rw     s    
 Or"   c                0     	 	 	 	 	 	 	 	 	 	 	 	 d fd}|S )Nc                H   | j                  dj                  d            }| 	|d
z
  dz   dz  dz            }n|}| 	|d
z
  dz   dz  dz            }n|}| 	|d
z
  dz   dz  dz            }n|}|||f	fd|j                  dj                  d            D        fS )zCTakes a key and subject, predicate, object; returns tuple for yieldr   rR   rP   r   rA   rW   c              3  4   K   | ]  }|s |        y wr=   r\   ).0rU   from_strings     r    	<genexpr>z:results_from_key_func.<locals>.from_key.<locals>.<genexpr>  s     V%PTU[^%Ps   r  )r   r   r   r   r   r  rQ   rS   rT   r  r_   s            r    r   z'results_from_key_func.<locals>.from_key  s     		#**Y/0? E1q519/A"567AAE1q519/A"567AA>E1q519/A"567AA1IV^%9%9#**Y:O%PV
 	
r"   )r   r   r   Optional[Node]r   r  r   r  r   r   rd   z;Tuple[Tuple[Node, Node, Node], Generator[Node, None, None]]r\   )r_   r  r   s   `` r    rz   rz     sH    


 "
 	

 
 
E
8 Or"   c                L    d\  }}}| dz  rd}| dz  rd}| dz  rd}|d|d|S )	Nz???rA   rQ   rW   rS   r   rT   ,r\   )r_   rQ   rS   rT   s       r    readable_indexr    s>    GAq!1u1u1uAq!!r"   )r   r   rd   r   )r_   rl   rd   r%   )r_   rl   rd   r&   )r_   rl   r  zCallable[[bytes], Node]rd   r(   )r_   rl   rd   r   )>
__future__r   loggingosr   os.pathr   r   	threadingr   typingr   r	   r
   r   r   r   r   r   urllib.requestr   rdflib.storer   r   r   rdflib.termr   r   r   rdflib.graphr   r   r   r   r!   
berkeleydbr#   r-   r.   DB_CDB_ALLDBrG   DB_INIT_MPOOLDB_INIT_CDB	DB_THREADrI   rE   rn   	getLoggerr   r   __all__r   r%   r&   r   r'   r(   r$   rt   rw   rz   r  r\   r"   r    <module>r*     s   "   #  W W W ' 5 5 0 0QQI
  //K"..02<<?H I ,,K			8	$ uUE501595@A
ueUE'A!BBC
3S=8C=)9S$_+EE 
HTNHTNHTNEB	%dD 
!9T4-=#>
>?A @
9 @
9F 
0F	"U  Is    D> >EE