ÿØÿà JFIF    ÿÛ „ !.%+&8&+/1555$;@;4?.451 4,$,44444444444414444444444444444444444444444444444444ÿÀ  á á" ÿÄ     ÿÄ ?    !1AQaq"2‘¡±ÁðBRbrÑá#‚’¢²3S CñÿÄ   ÿÄ !    !1QAa‘2ÿÚ   ? 5˜Z¯V¦cø)›t/? z¨±>Õ5€¶‹Á¤·¼z¼Ü¬+ñ®v¤¨_ˆR­BFn©—˜ý®ç̝P8gýt·ÉSTŦˆìät?þé¼íìN/Þa)ì–í6ô… Ï¿øÃj´¿KÇü]ÿ ªô¹-eKànëÕHTx}ýSÜ›ÿ ”7Ø×&µ<¦  ¥ÑO¶[Ù¯ä¨ÞÃÿ PZ-¬;#õ|•oaÿ ©CìÞz3˜öː/¤­ñTûIØ}š^ mÓ%ªxˆ¥ÉŸu=Z+ISe¿45™¼u;ú&WØ÷€æßQ™®{|íx*TC“#ZŠìZ§²‹ 6pv…³¿¡äª*áZÐ%ÒOáˆo"x«OHk w±æ+¬V(kMúŸ5Vö«$ ÁrÏbàb57/luR ¸ÑÛj Òµì`Мq­û žICÀÊ•©4€Âcà¨Ï€O´<èÐ:›ù(Ë^L8þ‘ÍÌ#¸Ð_Ì©ÙK(Öz 4¬û+¸;ü’V’84‘¬ÃŽ:[â‡ÔÌáõp¢~§ªlæ£ö{®G>J¼"°‡7¯ÆÉèßû ‹É‹§ÁòÃýâßî ^ƾÙõ‹×óH#«LP½ïX=xÑÍ$|W?•~• îëÔ©ª‹ {ÝT…Kÿ ”hûâá)J*ö˜–ÔU;iÇ€/ ÆþjóZ\ýwØ=Ìm ºèËL9 ýèÆð/¨’¥öo=nË.%Îì ŽÕ¯È|{Oj²ƒE6e/ßdÄõ²Ìâ1O®ò×TsəԸhOMýíMˆ¿¼H˜l²,7Â¥#MF/Úf°Ö½± ¸–dr‹NýÊ íjqx{œÉ ä-È ¦ øÄër¨q°ð †nцýÑÄÆ’mä…n<0È™;ÁÝá¯ÁZƒ7FÀmì­ É&9ˆîéi¶ùN§Y• ÃZãAâ?•‡©‰ , ó¾IŸŠc1 4â&y­&pŠ­6;M À 0¹qç»p.á …ŸÅáK@%6·y6ƒ‰3?”úºŽ‰éX5ªPT §µ!=Mž«Ú½‹ÅgÂSâÉaþÓoö–¯ÁÔìR>5éÿ üs¶ÆUcÌ kÇR ]ÿ ù¬¼«VŽ;Â|‡~¢¦”ÏŰæ {L™Õ°Óv¹ò¸írޡעCÃ!íVÕ {¶»sŒNPg/ "uÕbkm²“$ďå¿é¹§°½æz¯6 †s¿!s–wÚÝ“™Œ °.ûj>·+™Òa…©Œ&rÝÎtÛë긪Ît’LAVp%c Úý[ÄzJ¾ÇàXXç@˜ó<êL]·T˜¾¥1Ó©V‡g´æ½¦Ý@¹óø!_@´ÞâSÁ —S3™•& ]@JHÚý©ZŽ €×æÔr»Áf!‡yÞ4Mv*èÓã_{‘åóUuљØ«Oïé*®EvÑ Œ÷‡U \"㪒ÍK+À 4“M¡ï:0¥5í!'<@î´”>Ç»&Z–ïCCV˜Ì5Šo&îhè.žû |ÓK©h$s6KìŒëã)¹hI¦GïOåóI;ììü#É$Š0…Ææ¥TØ.5­¾gn´ “ÂÖ\:hœ89G)J@„}œ:’Ò{/Š"¦_Æ×7Æ3VÇŠÊa]ÚŒÙ€Ä–=®uÁßâACZƒ§§£ Qnâ:«,×{tyø¬iÛcœÜÄ€H½ÄÍCk´÷šß .W'b¤Íåh]÷€=,Žv×cÚEÚHXJX¶îo¨FÒtèöŸ>ªª6[J®Fµ£sGÁeqõfe\íjÒÐïÄÐGˆe1Ø‹.Ø”‘Ëuø Y­ˆÜ ŽG|zùªüMpDnQWÄ”%JŠ™)â*p@Örš«ÕT2Ð%ˆG#ª„ ·¤!°ŸOTÂT¸aÚ%4&h™LµšØüÐ.F¿²ÐÞ_Ç‚¾ÅÃaÜ÷09Æ q€öy˜v‡85õN÷]¬äѼóS{°_MެúÔ#°Ç¸0åÞè2ëôPcvÆw9®ií1Ä8F™˜à‰´+‰Ik1òÝ7“Ñ×ÒsÝ\x‚h`ÞÑ`ó"|µEcý£n˜h`}GÞ !±ù²Ápü²ß6 0ïi󜵩SÈÇ7˜-ÕURO˜¦´f$ªž-Í6(œ}<„ éc øs]ŽŽ„*—¾ ìdŽ„)méª\¿êÎIg¾ØÞ~I#C/¼¼´EÁÈŽi8“©õådô·>euä ƒ'Ê×लR1ÉJE1ÐAát`t;ÇР%Ý<‡¥„ÍÆ`×Oyó)õiI€ñQaŸ4Ûù\áàaÃÔ¹HÃu¹*k€¦<„e S‡&õÏ B!ŽhüÞ`yj}mªf×\¿ Ç~æ­9‡û\՞Ǖg²1Žû5V7 !àöšm° c`ܬøÇìµÒ'P"?…´Ö,"§^•õލsÔ)6˜sæéÍR¼ ò|Sl”‹7 nPW Gòú÷½§O¯‡„l¡kSÞŒr½PÊ@æ¢pŽ-mÿ #Ÿ˜Àº¶Áä¦;ïÔæ$1££`“Õ>„—·ž)ßð³ñ#Ï Ô$¶œ‰ÊE‹À;÷º ¯«P:Ñ”8–IÊtpÞ3ª“>ê“þës4ò2OÏÕ­±zô†Õ§‰.÷ä¸;¿˜“'œ›žª}«Œ{ª±Ì 9ÔóÞÕ‡0 $íWV3Üì¬ —@kÝ4@¿r¼±½¬™›?øØæ´'Áé®CË3-g$˜ö‡×auÚi´Žp/êÛ æF›Ú2v‹ã¿¿,nB1̨ƃqÞa5͝@&Æû“él÷ \C²½UÍc ¯k×¢U ÖéQå™—-r wô ÞÏ<Ò=&=ÿ Ôê Òêˈt,i—;LîÜ á¸*ÚÃ1$êL•LÍ <É)ýÐà’ ;F™{ƒ™˜€&'}‚ãÄK`¡ÞT@I;®žZóè‚s’7®°›+§O­Åq©é»²9<Ô J ¼9O’HL»Ùïì¸rk¼Ž_ý‘TŸu[²ßÚŒ·ü÷B%¯E ŸÔX5êO´ Ç•€’I0 ÉJX` ñ¹õ%;µŸD‘«´€àwÒ™U ûئžÖö\×®×´8 ½‡ºÐÆÓ§?Àkmœ=;d5*@-ì0F Rªýš[Ü6âö̃ڸr*KA9· u*µæ£?U¸Âêí†8@¦X4 e-ò„0s{ HâUpU?¼mñRa°®a%Ð'tÉ×’\¾ÊÉ]t›h>·(Ë@R¼¡Ãt h}’O÷au<+nT…Ö…MӐ??Óe95 q>í/;&JSû °¯ÊéÞ øƒ*Ã2½Ài&:nôUl=¾¿5eˆ3”ñc|Ú2V”>„»&eE;«ÚäC p¢Û úy 9š[ŒÌx¼擼A&DåÒ¯ˆ¤ÀÌ;"˜ ÏQä¸åhÊ}Ûq«Û0WžÒ|»€ø®öCm5•\ÇÀ§Pe3£]0ÃàLDÉ‰1øªxjgwT‚÷¿LΨK‹›ùs—xˆÜ±µ kæ¸f‰‰ÜGk/LÛØ6d9ò¶ùA{ƒA3š/¬D¬khÓk‰`˜"㯒r¿±Óã jx‡°e}<Ñø\3y:'À•/h½Í€Ç4~g ?Û(¼]v‘ªlKÎâ~?O‚W%{Ì:“'©úNq¾›úo(X’¥¯ˆ nFê{Ç€ü?º'ë ø‹ì Þ09ŒÌç9Æ —ËC`j@ÓÄ(+a‹un¸#ÂꟋ{K`‘ÑÍÍ'à´»/Û,KW;Þ4²þð ï Nm|~fGÏ(…³Ã)«1ö­Õ ¥‡¨©ƒÃ™ü-s=à=U66Ï«Ýc蓦W¹íž®›nÔ%êÇìŒ<#Ü×84ån®Ð ÒåOC` ñânÑs‡¢ç 1õ%Îhì½Ã½® e:ݼUZo™`  ÅZŸŒÊ«ê1ÏÄo$q¹Þ€©ˆhÐÉä¯ñ[!…Ú˜àJ:x2$Íß&PåT£6ç— ‡Í*4Ýšçjÿ ‰É nófÐ ó(L5C•åÆ\rMÒ@ò }y-W}™üýVù—ú¢=Ù”c®‘< M ž ´Phr ¦©TD ‘ù.$´÷O‡‘V2Æò.=IUŒ=ž‡â¬i™aþÓåÙ?òUø'ØÖ•.~* šTŒ!•-×áºTâ®ä#õü'´ eýlYÅÓeÕKÂrT"CÚ@u!Óxƒ{š3€}1¿(r}%«nËamjÑ%ÑNEò v ˜à  σöK³,*º.àzù¨™Ó ÚçâU¦*¿ 9{%Ö¹ njûdaXöb) kÛÆ±ûÓ\°M7ˆÂ=û›ç¿Ã‚­V»Cg–8ÙêE- j)k$º`Ã-ùEýeBÆÇ]c¡°ñty&Òd0nõ'¡W+ƒ*|–øµFa\GQªEAÔp5\Ǽ·¼Ç8·õ -â§Ú[ ‡ uZeÖ 3}×d'+¹:ð+K†Û®s!Ï$úe€<Û”x)1»a­¡LC]¸µík…ÚàA»AYº{†ªS[¦5HÒ7ù --,ísòDØ€èk ÞÀîÜ ò@â( ËNˆë›4ô½•/¦o‡€Û7 ê•ÆêòðÜy'Án½µ á˜ݦ ndeo…[ì¶Ê,¥R³Ä=À±—–ß;£™´ñSâ*g§”ïaið‘Jå~™ÓÞ ß³Õ¢»8x埒²52>AÊb&-÷\7´éÄù€T˜,w;3{ï˜k…à¹ÄqÀ«œ{€\ ˆ¾[´¨јr &Úé„Ívˆ±8†¿]|¬ņ4I×pÞS1ÈÖz‰#Ìv‡G!YNògñ:màTz¢Ý1ô©^O=~ë|5Bã™ç•¼µõ•bÆ@úÕS¬ÈŒ#¬zünrŸ û” Z²•èðV"ÁHÚý©wÝ €7¼Ìu1hÑa3Éä û f$o¿É ™Ú›ÝçnpÒ3äÌ3†Í§,Äï]$‰/pê †«À¼¸e9­Æê_C]žƒ·ý·frÁN«, E=›Çq -‰öŒ:aÏ¿±í&£Í:-} 84‘ÿ eƒQÑeëSsuiA ³g㟥ú£?ÿ ʼn*”“÷aühe:ÊWa@ÒÞk±eØ] F Ô—r.åä˜ @ö¥ªZoÐýYL·¥S²G/‡ñ <~*ZÆ´è>JlòàÛÆ½ÿ 窘ìGN¢:I®KšJp/`íIÁÀõ#Ä-€ö­šµŒoF4|ÆQØÆ@Ì|£Ô…¢À{9˜è½Üó›€ôYÒÎYsið;ís¤€à²ˆ‚4qÉVŒI$ ‰"° æµ8cXGjœˏ¡Aâý•ËÜ¢ûï e·çLx']á"oÅÎê3¯Ç—¹”ó0nå‚âg{Œñ> S´˜îè°g238‚ãköÝfÚd´6Ò€;ò÷±¢™¼›º ¢Æ'¥Ðx'e¬ç ]bÈÆV¢ó‹kýBO ðÊâ$Ÿ!×T 3Mýמ žìٍàÌü‘8÷€àæØ8æ©6‰©L´«…oãpð„~Çk‰!ñ;‹”ÛžÍ àž±z Ÿôû øŸÝužÏ;ÿ #|u6™Þ¬ÚˆÐõA4¶â|ôl|Ê2ŽÇ¤ÝÅÇY.<#Aí.k§hóF‚”Y; M½Ö4hŸ4&›­¿tès´%FìL¥£Ãk‰ÇT¤haÁ¤ÚxfÉ`ÑìË›>i 3t‚:,–+^÷´–{Û–Nxi"x‘Ûg î¨>¥Õ܁ùZH,2Û“:8xÊ¢Çí9.É-Ìâã-=çjwµS˜dütžçwýGòú®®ûº_ˆýx$–¡ãøO EÚÛÏ÷R„×w+3£Á£öUMyR²¹âŒ°š›¸Ñãò9§Ó_Dl+Ùßc›úšGÅÌc†Ž!Ko=¶.‘Îÿ c²(2®V mª.ÿ ¹B›¹å ù„öŸSV>™ü¯$y:G¢Z×àøúdî¹û­·ýÇ´:•c LÍõi_‹ö+ÎæGÊè>OŠ•äž´§Þ{X}¨1ÚTc›»Qþ•êô°t¿OP?eæ~É{5]•ÙR£r5†nZ\ã@ &îJõ ¾àC°þV>fé¥/ü5ñÊIº_é5 ;e­h<@ Ä&æÃëE%;X,ÒãÆÞ`Oò¦kŸm#˜!ÀyÄ¢| óLšò¥Ä` ¶R=|ÈCâh5ò3DˆïF†ðÒ#ÅìÛœ?¸yhBãœí ZxßÎÄhºRK„`Þödvײ™ÀÈÑÒgŒuY w³%†ƒÓzõ ÖÏp‚dH®¦A´ù§»ÓÇMæ~)ˆð‡û:ù&Ä •vGD´À n ݇¼Ö8Fö óáà£~Ë¥x`oK|Ä?fxiØü%pìR>éò+Û±éÎ>núlFŤ'tq8LZÏvÃ?„¡ß±È⽆¯³íü@x|PöUäèØã¡ð‚ŒAìÏ"vÍwóŸÍ{ ý0.z È•Ö{,N¡£¡ŸKÕÙž>Ýœþ ÍÀ°<×EA!Å‚D™IúOÍ¡>ôG}Â` ÍßkÜL™Ž Þð™ {IøF²¹òQ3&!ÃÂÞz.d&Ï-sH¸,Ôõ˜ŽP€ 77ˆÝ¼ÊëÜw =cÕ Ú,ØÐ5ÎYÐ)ì´öœgŒ[¤ßv㙑8心>h]§µháYš£²ºÑ.{Ï7Sð•?´~×SÃKýJÛ˜ ™Íäiúu<µX¶1õ^kâçIÑ£sZ4h>j*ÔšD:4­¿_ ÷¸ Õxæÿ ¸?Mù _•­ÊÐ ä ÷ý ÑwL œ­ïnTkÛUÍN©ë:¦fV ¶ÜÔÜMªÅâA½–¿R×TXš-%iTÊT•‡Ù‚JôϐZxWÑè‰f‰òG º ×Õû2aZ7OU3[“×AT–ÞŒ…-‘¤”Ì ì&(ˆ¿­•ƒkï’:ðY¦W‘ Å)“†‘˜³Åtcø˜ñTÂwÚÇ4|üLÇªí–v- qˆèU qPE.†â‘˜µ Æ,ÐÅs]8¾„oúÑ i>ÜxxÈó)ƒ ´æÁâØ$À‰vžŸf$Ž |ãw;ÀÁIJ»b` {¦Ó¤Ú$©YÀ‘n@Óïž«9J¼êG m¤ ܯ¹ÌW4€ÐÒÅÛ‡#褕Ÿn-?í|с¥÷Ú¹¬'´ÞÜ9ÓK `hê£SÄSà?7—Wí_´…óB›»:=Ãïq`<8ñÓŒÑlú2d¬ê³£hÖ[l|$vÝro~'R®‰§°ñmY ͧäP |PUª¹·:3Œ[Û{Xÿ ºâ@‚W–Äé u‚ ¯´*=íή.pûÒdt @G‰¬ s¸ ëÉücr ÞæÑ¨Ê@>¤¢Ö±. Þ'¯°ÌME[YéïĵÂCå½ Ué©Áû'Ê9%eÔðNU”ë‘ÌsD3/®+UI˜9h.WC”빓$#:pz:YÓ ¿xž* ³$Í +$kñAŠ‹†¢ Uê>¸)_š¬÷©ßAÂÔb9ÇU ¯¾á•9¯ÏÏ÷O÷¼¼Fähal1‰3Ì[Ïr•´UCksNÐ] R‘¸¥H+§Šé†c©vÖÞ0iÓ76s†î!§=ß ¼~Ô'°Ãmäoäš³ªøi1úÉ)³yV8 CLÄØÁ‘WYïi€H6ÖÑiámø^ÈY´°Ñ7¥Û*—Ñ©L«Qƒï—Ùrÿ ›£Ð*š¸ˆL©ˆ$ˆ ÷¾D§9È®«qbqC)–ˆïv´çñsÑVT­Ø, <àïºÀO«Jý·õ àfPìð .wFšir´þ’2_Y *Æ€x\« ì€9š@ Ž|F⇥ˆkZ@hÖÄ0t¿-<“‹qµ¾*ZL¤Ú)&BJpÓF5=$„at*Zš$’ÑtdûÝRI1 2މ$€$I$#‰SÞ’Hë¬ï;Á$¡t$’`<(ñÇt)$‡Ð.Êf¢X’Kt=Éé$‚ˆªè¢oÝëòI%Rgcª÷ŠyI%¡‰ÿ !ñ)´õ $¤ Ô’IIGÿÙ )uycQJdZddlZddlZ ddlmZmZmZmZmZm Z m Z m Z m Z m Z eee efZeee efZee gefZee gefZee e e e fgefZn #e$rYnwxYwddlmZdZeeZdZeeZdZeeZ ddZeeZd Z d Z!d Z"ee"Z#Gd d Z$dS)z< Facilities to work with debtags - tags for Debian packages N) CallableDictIOIterableIteratorListOptionalSetTextTuple)function_deprecated_byc#Ktjd}|D]}||}|st|dd}|dr6t|dd}nt}||fVdS)Nz^(.+?)(?::?\s*|:\s+(.+?)\s*)$, )recompilematchsetgroupsplit) input_datalrelinempkgstagss 0/usr/lib/python3/dist-packages/debian/debtags.py parse_tagsr0s *5 6 6C   IIdOO  1771::##D))** 771:: qwwqzz''--..DD55DDj  cli}t|D]!\}}|D]}|||<"|S)z7Read the tag database, returning a pkg->tags dictionaryrcopy)rdbrrps rread_tag_databaser&EsP B ,,  d  AIIKKBqEE Ir ci}t|D]6\}}|D].}||vr||xx|zcc<|||</7|S)z7Read the tag database, returning a tag->pkgs dictionaryr")rr$rrtags rread_tag_database_reversedr)Ssr B ,,&& d & &Cbyy34))++3  & Ir c4i}i}t|D]\}}|t|}ntt||}|D]}|||<|D].}||vr||xx|zcc<|||</||fS)zGRead the tag database, returning a pkg->tags and a tag->pkgs dictionary)rrfilterr#)r tag_filterr$dbrrrpkgr(s rread_tag_database_both_waysr/ds B C ,, ' ' d  t99DDvj$//00D " "CiikkBsGG ' 'CczzCD 99;;C  ' s7Nr ci}|D]:\}}|D]2}||vrt||<|||3;|S)z=Reverse a tag database, from package -> tags to tag->packages)itemsradd)r$resr.rr(s rreverser4sn CXXZZ T  C#~~55C HLL      Jr c|D]+\}}td|zd|,dS)zWrite the tag databasez%s:rN)r1printjoin)r$r.rs routputr8sLXXZZ.. T esmTYYt__----..r cfdS)Nct|dzt|z S)Nr)floatcard)r(fullsubs rz*relevance_index_function..s5uSXXc]]A-..tyy~~1F1FFr )r=r>s``rrelevance_index_functionrAs* G F F F FFr ceZdZdZdZ d&dZdZdZdZdZ d Z e e Z d Z d Ze eZd Zd Ze eZdZe eZdZe eZdZe eZdZe eZdZe eZdZe eZdZe eZ dZ!e e!Z"dZ#e e#Z$dZ%e e%Z&dZ'e e'Z(dZ)e e)Z*dZ+e e+Z,dZ-e e-Z.dZ/dZ0dZ1e e1Z2dZ3e e3Z4d Z5e e5Z6d!Z7e e7Z8d"Z9e e9Z:d#Z;e e;Zd%Z?dS)'DBzK In-memory database mapping packages to tags and tags to packages. c"i|_i|_dSN)r$rdbselfs r__init__z DB.__init__sr Nc@t||\|_|_dS)z Read the database from a file. Example:: # Read the system Debtags database db.read(open("/var/lib/debtags/package-tags", "r")) N)r/r$rF)rHrr,s rreadzDB.reads 8 JOOr cntj|j|tj|j|dS)z(Quickly write the data to a pickled fileN)pickledumpr$rFrHfiles rqwritez DB.qwrites2  DGT""" DHd#####r cjtj||_tj||_dS)z)Quickly read the data from a pickled fileN)rMloadr$rFrOs rqreadzDB.qreads*+d##;t$$r c||j|<|D]C}||jvr!|j||,t ||j|<DdSrE)r#r$rFr2r)rHr.rr(s rinsertz DB.insertsiyy{{  + +Cdh !!#&&&& #S   + +r c.t|jdSrE)r8r$rGs rrNzDB.dumpstwr c.t|jdSrE)r8rFrGs r dump_reversezDB.dump_reversestxr cRt}|j|_|j|_|S)z).0ttofacets r z&DB.facet_collection..s'999qW[[**999r )rCrriter_packages_tagsrV)rHfcollr.rftagsr`s @rfacet_collectionzDB.facet_collectionsq *]++0022 % %IC9999D999E LLe $ $ $ $ r ct}|j|_|j|_|S)z\ Return a copy of this collection, with the tagsets copied as well. )rCr$r#rFr[s rr#zDB.copy s4 dd(--// r ct}|j|_|j|_|S)z` Return the reverse collection, with a copy of the tagsets of this one. )rCrFr#r$r[s r reverse_copyzDB.reverse_copys4 dd',,.. r ct}i}|D]}||jvr|j|||<||_t||_|S)zs Return a collection with only the packages in package_iter, sharing tagsets with this one rCr$r4rFrH package_iterr3r$r.s rchoose_packageszDB.choose_packages!sU dd  ' 'Cdg~~'#,3"++ r ct}i}|D]}|j|||<||_t||_|S)z| Return a collection with only the packages in package_iter, with a copy of the tagsets of this one rjrks rchoose_packages_copyzDB.choose_packages_copy2sK dd  # #CgclBsGG"++ r ct}i}t||jD]}|j|||<||_t ||_|S)z Return a collection with only those packages that match a filter, sharing tagsets with this one. The filter will match on the package. )rCr+r$keysr4rF)rHpackage_filterr3r$r.s rfilter_packageszDB.filter_packagesBs_dd .$',,..99 # #CgclBsGG"++ r ct}i}t||jD]$}|j|||<%||_t ||_|S)z Return a collection with only those packages that match a filter, with a copy of the tagsets of this one. The filter will match on the package. )rCr+r$rqr#r4rF)rH filter_datar3r$r.s rfilter_packages_copyzDB.filter_packages_copySskdd +tw||~~66 * *Cgcl''))BsGG"++ r ct}i}t||jD]\}}|j|||<||_t ||_|S)z Return a collection with only those packages that match a filter, sharing tagsets with this one. The filter will match on (package, tags). )rCr+r$r1r4rFrHpackage_tag_filterr3r$r._s rfilter_packages_tagszDB.filter_packages_tagsdsddd /AA # #FCgclBsGG"++ r ct}i}t||jD]'\}}|j|||<(||_t ||_|S)z Return a collection with only those packages that match a filter, with a copy of the tagsets of this one. The filter will match on (package, tags). )rCr+r$r1r#r4rFrxs rfilter_packages_tags_copyzDB.filter_packages_tags_copyuspdd /AA * *FCgcl''))BsGG"++ r ct}i}t||jD]}|j|||<||_t ||_|S)z Return a collection with only those tags that match a filter, sharing package sets with this one. The filter will match on the tag. )rCr+rFrqr4r$rHr,r3rFr(s r filter_tagszDB.filter_tagss_dd*dhmmoo66 % %Cx}CHH r ct}i}t||jD]$}|j|||<%||_t ||_|S)z Return a collection with only those tags that match a filter, with a copy of the package sets of this one. The filter will match on the tag. )rCr+rFrqr#r4r$rs rfilter_tags_copyzDB.filter_tags_copyskdd*dhmmoo66 , ,Cx}))++CHH r c||jvS)z2Check if the collection contains the given package)r$rHr.s r has_packagezDB.has_packagesdg~r c||jvS)z9Check if the collection contains packages tagged with tag)rFrHr(s rhas_tagz DB.has_tagsdhr cJ||jvr |j|n tS)zReturn the tag set of a package)r$rrs rtags_of_packagezDB.tags_of_packages" #dg~~tws||3558r cJ||jvr |j|n tS)zReturn the package set of a tag)rFrrs rpackages_of_tagzDB.packages_of_tags"!$txtx}}SUU:r c8tjfd|DS)z=Return the set of tags that have all the packages in ``pkgs``c3BK|]}|VdSrE)r)r^r%rHs r z&DB.tags_of_packages..1AAq4//22AAAAAAr runion)rHrs` rtags_of_packageszDB.tags_of_packages'yAAAADAAABBr c8tjfd|DS)z=Return the set of packages that have all the tags in ``tags``c3BK|]}|VdSrE)r)r^r_rHs rrz&DB.packages_of_tags..rr r)rHrs` rpackages_of_tagszDB.packages_of_tagsrr cL||jvrt|j|ndS)z1 Return the cardinality of a tag r)rFlenrs rr<zDB.cards' &)DH__s48C=!!!!;r cz||}|}t|||z S)a Return the discriminance index if the tag. Th discriminance index of the tag is defined as the minimum number of packages that would be eliminated by selecting only those tagged with this tag or only those not tagged with this tag. )r< package_countmin)rHr(ntots r discriminancezDB.discriminances6 IIcNN  ""1cAgr c4|jS)zIterate over the packages)r$rqrGs r iter_packageszDB.iter_packagessw||~~r c4|jS)zIterate over the tags)rFrqrGs r iter_tagsz DB.iter_tagssx}}r c4|jS)z$Iterate over 2-tuples of (pkg, tags))r$r1rGs rrbzDB.iter_packages_tagssw}}r c4|jS)z$Iterate over 2-tuples of (tag, pkgs))rFr1rGs riter_tags_packageszDB.iter_tags_packagessx~~r c*t|jS)zReturn the number of packages)rr$rGs rrzDB.package_counts47||r c*t|jS)zReturn the number of tags)rrFrGs r tag_countz DB.tag_count s48}}r cdd}t}d}tt|D]f}||d|dz}t|}|dkrn.||}||kr|}t|d|dz}g|st|ddS|S)av Return an ideal selection of the top tags in a list of tags. Return the tagset made of the highest number of tags taken in consecutive sequence from the beginning of the given vector, that would intersect with the tagset of a comfortable amount of packages. Comfortable is defined in terms of how far it is from 7. c8t|dz |dz z|z S)N)r;)xs r score_funz"DB.ideal_tagset..score_fun!s!!B$2'') )r g@Nrr)rrangerr) rHrrtagset min_scoreirr<scores r ideal_tagsetzDB.ideal_tagsets  * * * s4yy!! ) )A((dqsd44Dt99DqyyIdOOEy  ! T$1Q3$Z !tBQBx==  r c#K|D]|fd}|fd}|D]}|kr t||t|z }t||t|z }|||z fVdS)z Generate the list of correlation as a tuple (hastag, hasalsotag, score). Every tuple will indicate that the tag 'hastag' tends to also have 'hasalsotag' with a score of 'score'. c|dvSNrr@ptpivots rr?z!DB.correlations..As"Q%r c|dvSrr@rs rr?z!DB.correlations..Bs51;Mr N)rr{r;r<r)rHwith_withoutr(hashasntrs @r correlationszDB.correlations7s ^^%% . .E--.G.G.G.GHHE//0M0M0M0MNNG(( . .%<<EJJsOO,,uU5H5H5J5J/K/KKgll3//0059N9N9P9P3Q3QQS#+-----  . . .r rE)@__name__ __module__ __qualname____doc__rIrKrQrTrVrNrYr dumpReverser4refacetCollectionr#rh reverseCopyrmchoosePackagesrochoosePackagesCopyrsfilterPackagesrvfilterPackagesCopyr{filterPackagesTagsr}filterPackagesTagsCopyr filterTagsrfilterTagsCopyr hasPackagerhasTagr tagsOfPackager packagesOfTagrtagsOfPackagesrpackagesOfTagsr<rr iterPackagesriterTagsrbiterPackagesTagsriterTagsPackagesr packageCountrtagCountr idealTagsetrr@r rrCrCs P P P P$$$ %%% +++)(66K   -,-=>>O      )(66K   ,+O<rsMBB"                          SX &LSX &LdVT\*MdVT\*MtSY!7 8$ >?   D 655555$ # ": . . )():;;   101KLL 0101LMM   ...GGGH0/0HIIM.M.M.M.M.M.M.M.M.M.sA'A44A<;A<