
    g~H                        d Z dZ G d de      Z G d de      Z G d de      Z G d d	e      Z G d
 de      Z G d de      Z	 G d de	      Z
 G d de	      Z G d de	      Z G d de	      Z G d de	      Z G d de	      Z G d de	      Z G d de	      Z G d de	      Z G d  d!e	      Z G d" d#e	      Z G d$ d%e	      Z G d& d'e	      Z G d( d)e	      Z G d* d+e	      Z G d, d-e	      Z G d. d/e	      Z G d0 d1e	      Z G d2 d3e	      Z G d4 d5e	      Z G d6 d7e	      Z G d8 d9e	      Z G d: d;e	      Z  G d< d=e	      Z! G d> d?e	      Z" G d@ dAe	      Z# G dB dCe	      Z$ G dD dEe	      Z% G dF dGe	      Z& G dH dIe	      Z' G dJ dKe	      Z( G dL dMe	      Z) G dN dOe	      Z* G dP dQe	      Z+ G dR dSe	      Z, G dT dUe	      Z- G dV dWe	      Z. G dX dYe	      Z/ G dZ d[e	      Z0 G d\ d]e	      Z1 G d^ d_e	      Z2 G d` dae	      Z3 G db dce	      Z4 G dd dee	      Z5 G df dge	      Z6 G dh die	      Z7 G dj dke	      Z8 G dl dme	      Z9 G dn doe	      Z: G dp dqe	      Z; G dr dse	      Z< G dt due      Z= G dv dwe      Z> G dx dye      Z? G dz d{e      Z@ G d| d}e      ZA G d~ de      ZB G d de      ZC G d de      ZD G d de      ZE G d de      ZF G d de      ZF G d de      ZG G d de      ZH G d de	      ZI G d de	      ZJ G d de	      ZK G d de      ZL G d de      ZM G d de      ZN G d de      ZO G d de      ZP G d de      ZQ G d d      ZR e       ZSddZTdZUdZVddZWddZXy)a1  
Extract client information from http user agent
The module does not try to detect all capabilities of browser in current form (it can easily be extended though).
Tries to
    * be fast
    * very easy to extend
    * reliable enough for practical purposes
    * assist python web apps to detect clients.
z1.9.5c                   ,    e Zd Zg dZd Zd Zd Zd Zy)DetectorsHub)osdistflavorbrowserc                     t        j                  | g|i | | j                  D ]  }| j                  |g         | j	                          y N)dict__init___known_types
setdefaultregisterDetectors)selfargskwtyps       -/opt/Tautulli/lib/httpagentparser/__init__.pyr   zDetectorsHub.__init__   sG    d(T(R($$ 	%COOC$	%     c                     |j                   | j                  vrA|g| |j                   <   | j                  j                  |j                  |j                          y | |j                      j	                  |       y r	   )	info_typer   insertorderappend)r   detectors     r   registerzDetectorsHub.register   sa    T%6%66(0zD##$$$X^^X5G5GH##$++H5r   c                 ,    t        | j                        S r	   )iterr   r   s    r   __iter__zDetectorsHub.__iter__   s    D%%&&r   c           	          t        t               j                               D cg c]  }t        t	        |dg       v s |        }}|D ]   }|j
                  s| j                  |       " y c c}w )N__mro__)listglobalsvaluesDetectorBasegetattrcan_registerr   )r   v	detectorsds       r   r   zDetectorsHub.registerDetectors!   sb    "&wy'7'7'9":hQlgVWYbdfNg>gQSh	h 	!A~~a 	! is
   A.	A.N)__name__
__module____qualname__r   r   r   r   r    r   r   r   r      s    6L!6'!r   r   c                   V    e Zd ZdZdZdZdZdZg ZdZ	dgZ
dZdZdZdZd Zd	 Zd
 Zd Zy)r%    zoverride me
   zstring to look forF/ Nc                     | j                   s| j                  j                  | _         | j                  j                  j	                  dd      | _        y )Nr'   T)name	__class__r+   __dict__getr'   r   s    r   r   zDetectorBase.__init__6   s9    yy//DI!^^4488Nr   c                    | j                  |      }|rwt        | j                        || j                  <   | j                  |d<   | j                  ||      }|r||| j                     d<   | j                  r| j                  |d|d<   yy )N)r6   botversionr6   r<   platformT)
checkWordsr
   r6   r   r;   
getVersionr>   )r   agentresultwordr<   s        r   detectzDetectorBase.detect;   s    u%%)tyy%9F4>>" HHF5MooeT2G4;t~~&y1}}.2mm%Pz" r   c                     | j                   D ]  }||v s y t        | j                  t        t        f      r| j                  D ]
  }||v s|c S  y | j                  |v r| j                  S y )NF)skip_if_found
isinstancelook_fortupler"   )r   rA   wrC   s       r   r?   zDetectorBase.checkWordsH   sq    ## 	AEz	 dmmeT]3  5=K  ]]e#==  $r   c                 b   t        | j                  d   t        t        f      r| j                  n| j                  g}|j	                  |d      d   }|D ]Y  \  }}|j                  |      s||v s|dd }|r|j	                  |      d   }| j                  s|j	                         d   }|c S  y)z)
        => version string /None
               N)rG   version_markersr"   rI   split
startswithallow_space_in_version)r   rA   rC   rO   version_partstartendr<   s           r   r@   zDetectorBase.getVersionT   s    
 t++A.u> ..EIEYEYDZ 	{{4+B/) 	JE3&&u-#2E&qr*%mmC03G22%mmoa0G	r   )r+   r,   r-   r6   r   
result_keyr   rH   rF   r'   rO   rR   _suggested_detectorsr>   r;   r   rD   r?   r@   r.   r   r   r%   r%   (   sW    DIJE#HML!lO"H
CP

!r   r%   c                   $    e Zd ZdZdZddgZdZdZy)OSr   F;r4   TN)r+   r,   r-   r   r'   rO   rR   r>   r.   r   r   rY   rY   e   s     ILCjO!Hr   rY   c                       e Zd ZdZdZdZy)Distr   FNr+   r,   r-   r   r'   r>   r.   r   r   r\   r\   m   s    ILHr   r\   c                       e Zd ZdZdZdZy)Flavorr   FNr]   r.   r   r   r_   r_   s   s    ILHr   r_   c                       e Zd ZdZdZy)Browserr   FN)r+   r,   r-   r   r'   r.   r   r   ra   ra   y   s    ILr   ra   c                       e Zd Zd ZddgZy)	Konquerorr3   rZ   Nr+   r,   r-   rH   rO   r.   r   r   rc   rc   ~   s    HCjOr   rc   c                       e Zd ZdZdZd Zy)OperaMobile
Opera MobizOpera Mobilec                     	 d}|j                  |      d   dd  j                  d      d   S # t        $ r. d}|j                  |      d   dd  j                  d      d   cY S w xY w)NVersionrM   r4   rL   OperarP   
IndexError)r   rA   rC   rH   s       r   r@   zOperaMobile.getVersion   sv    	> H;;x(+AB/55c:1== 	>H;;x(+AB/55c:1==	>s   *- 4A$#A$N)r+   r,   r-   rH   r6   r@   r.   r   r   rf   rf      s    HD>r   rf   c                       e Zd Zd ZdgZd Zy)rj   rg   c                     	 d}|j                  |      d   dd  j                  d      d   S # t        $ rB d}|j                  |      d   dd  j                  d      d   }|j                  d      d   cY S w xY w)Nri   rM   r4   rL   rj   (rk   )r   rA   rC   rH   r<   s        r   r@   zOpera.getVersion   s    	) H;;x(+AB/55c:1== 	)Hkk(+A.qr288=a@G==%a((	)s   *- AA87A8Nr+   r,   r-   rH   rF   r@   r.   r   r   rj   rj      s    H!NM)r   rj   c                   $    e Zd ZdZdZdZdgZdgZy)OperaNewz 
    Opera after version 15
    rj   OPRz	Build/OPRr3   r0   N)r+   r,   r-   __doc__r6   rH   rF   rO   r.   r   r   rr   rr      s!     DH MM kOr   rr   c                       e Zd Zd ZdgZy)Netscapert   Nrd   r.   r   r   rw   rw      s    H kOr   rw   c                   D     e Zd Zd ZddgZdZddgZdddd	d
Z fdZ xZ	S )TridentMSIErj   Microsoft Internet Explorerr3   rZ   z8.0z9.0z10.0z11.0)z4.0z5.0z6.0z7.0c                 ^    | j                   j                  t        t        |   ||            S r	   )trident_to_ie_versionsr9   superry   r@   )r   rA   rC   r7   s      r   r@   zTrident.getVersion   s)    **..uWd/NuVZ/[\\r   )
r+   r,   r-   rH   rF   r6   rO   r}   r@   __classcell__)r7   s   @r   ry   ry      s@    HW%M(DCjO	] ]r   ry   c                   "    e Zd Zd ZdgZdZddgZy)rz   rj   r{   r4   rZ   N)r+   r,   r-   rH   rF   r6   rO   r.   r   r   rz   rz      s    HIM(DCjOr   rz   c                       e Zd ZdZdgZddgZy)MSEdgeEdgerz   r3   r0   N)r+   r,   r-   rH   rF   rO   r.   r   r   r   r      s    HHMBiOr   r   c                       e Zd ZdZd Zy)ChromiumEdgeEdg/c                 P    d|v r"|j                  d      d   j                         S y )Nr   rN   rP   stripr   rA   rC   s      r   r@   zChromiumEdge.getVersion   s+    U?;;v&r*0022 r   Nr+   r,   r-   rH   r@   r.   r   r   r   r      s    H3r   r   c                       e Zd Zd Zy)GaleonNr+   r,   r-   rH   r.   r   r   r   r          Hr   r   c                       e Zd ZdZd Zy)
WOSBrowser
wOSBrowserc                      y r	   r.   r   s      r   r@   zWOSBrowser.getVersion       r   Nr   r.   r   r   r   r      s    Hr   r   c                   $    e Zd Zd Zg dZd Zd Zy)Safari)r   	YaBrowserFxiOSc                 Z    g d}| j                   |v r|D ]  }||v s y | j                   S y )N)ChromeOmniWebr   AndroidCriOSF)rH   )r   rA   unless_listrC   s       r   r?   zSafari.checkWords   s=    M==E!# !5= ! == 	 "r   c                 J   d|v r4|j                  d      d   j                  d      d   j                         S d|v r4|j                  d      d   j                  d      d   j                         S |j                  d      d   j                  d      d   j                         S )NzVersion/rN   r4   rL   zSafari/zSafari r   r   s      r   r@   zSafari.getVersion   s    ;;z*2.44S9!<BBDD;;y)"-33C8;AACC;;y)"-33C8;AACCr   N)r+   r,   r-   rH   rF   r?   r@   r.   r   r   r   r      s    H2M!Dr   r   c                        e Zd Zg dZdZddgZy)	GoogleBot)		GooglebotzGooglebot-NewszGooglebot-ImagezGooglebot-VideozGooglebot-MobilezMediapartners-GoogleMediapartnerszAdsBot-Googleweb/snippetTr3   rZ   r2   Nr+   r,   r-   rH   r;   rO   r.   r   r   r   r      s    AH C!:.Or   r   c                       e Zd ZdZdZd Zy)GoogleFeedFetcherzFeedfetcher-GoogleTc                      y r	   r.   r   rA   s     r   get_versionzGoogleFeedFetcher.get_version   r   r   Nr+   r,   r-   rH   r;   r   r.   r   r   r   r      s    #H
Cr   r   c                       e Zd ZdZdZy)RunscopeRadarzrunscope-radarTNr+   r,   r-   rH   r;   r.   r   r   r   r          H
Cr   r   c                       e Zd ZdZdZd Zy)GoogleAppEnginezAppEngine-GoogleTc                      y r	   r.   r   s     r   r   zGoogleAppEngine.get_version  r   r   Nr   r.   r   r   r   r     s    !H
Cr   r   c                       e Zd ZdZdZd Zy)
GoogleAppszGoogleApps scriptTc                      y r	   r.   r   s     r   r   zGoogleApps.get_version  r   r   Nr   r.   r   r   r   r   	  s    "H
Cr   r   c                       e Zd ZdZdZy)
TwitterBot
TwitterbotTNr   r.   r   r   r   r         H
Cr   r   c                       e Zd Zd ZdZy)TelegramBotTNr   r.   r   r   r   r         H
Cr   r   c                       e Zd ZdZdZy)MJ12BotMJ12botTNr   r.   r   r   r   r     s    H
Cr   r   c                       e Zd ZdZdZd Zy)	YandexBotYandexTc                     ||j                  d      d  j                  d      d   j                  d      d   j                         S )Nr   r3   rN   )rL   )indexrP   r   r   s      r   r@   zYandexBot.getVersion!  sB    U[[*+,2237;AA#FqIOOQQr   N)r+   r,   r-   rH   r;   r@   r.   r   r   r   r     s    H
CRr   r   c                       e Zd ZdZddgZdZy)BingBotbingbotr3   rZ   TN)r+   r,   r-   rH   rO   r;   r.   r   r   r   r   $  s    HCjO
Cr   r   c                       e Zd Zg dZdZdZy)BaiduBot)BaiduspiderzBaiduspider-imagezBaiduspider-videozBaiduspider-newszBaiduspider-favozBaiduspider-cprozBaiduspider-adsTr   Nr   r.   r   r   r   r   *  s    #H C Or   r   c                       e Zd Zd ZdZy)LinkedInBotTNr   r.   r   r   r   r   3  r   r   r   c                       e Zd ZdZdZy)ArchiveDotOrgBotzarchive.org_botTNr   r.   r   r   r   r   7       H
Cr   r   c                       e Zd Zd ZdZy)	YoudaoBotTNr   r.   r   r   r   r   ;  s    H
Cr   r   c                       e Zd ZdZdZy)YoudaoBotImagezYodaoBot-ImageTNr   r.   r   r   r   r   ?  r   r   r   c                       e Zd ZdZdZy)RogerBotrogerbotTNr   r.   r   r   r   r   C      H
Cr   r   c                       e Zd Zd ZdZy)TweetmemeBotTNr   r.   r   r   r   r   G  s    H
Cr   r   c                       e Zd Zd ZdZy)
WebshotBotTNr   r.   r   r   r   r   K  r   r   r   c                       e Zd Zd ZdZy)
SensikaBotTNr   r.   r   r   r   r   O  r   r   r   c                       e Zd Zd ZdZy)YesupBotTNr   r.   r   r   r   r   S  r   r   r   c                       e Zd Zd ZdZy)DotBotTNr   r.   r   r   r   r   W  s    H
Cr   r   c                       e Zd ZdZdZy)	PhantomJSzBrowser/PhantomTNr   r.   r   r   r   r   [  r   r   r   c                       e Zd ZdZdZy)FacebookExternalHitfacebookexternalhitTNr   r.   r   r   r   r   _  s    $H
Cr   r   c                       e Zd ZdZy)NokiaOviS40OviBrowserNr   r.   r   r   r   r   d      Hr   r   c                       e Zd Zd Zy)	UCBrowserNr   r.   r   r   r   r   g      Hr   r   c                       e Zd Zd Zy)	BrowserNGNr   r.   r   r   r   r   j  r   r   r   c                       e Zd Zd Zy)DolfinNr   r.   r   r   r   r   m  r   r   r   c                       e Zd Zd Zy)NetFrontNr   r.   r   r   r   r   p      Hr   r   c                       e Zd Zd Zy)JasmineNr   r.   r   r   r   r   s  s    Hr   r   c                       e Zd Zd Zy)OpenwaveNr   r.   r   r   r   r   v  r   r   r   c                       e Zd ZdZy)	UPBrowserz
UP.BrowserNr   r.   r   r   r   r   y      Hr   r   c                       e Zd Zd Zy)
OneBrowserNr   r.   r   r   r   r   |  r   r   r   c                       e Zd Zd Zy)ObigoInternetBrowserNr   r.   r   r   r  r    s    %Hr   r  c                       e Zd Zd Zy)TelecaBrowserNr   r.   r   r   r  r    r   r   r  c                       e Zd ZdZd Zy)MAUIzBrowser/MAUIc                 4    |j                  d      d   d d }|S )NzRelease/rN   r1   )rP   )r   rA   rC   r<   s       r   r@   zMAUI.getVersion  s!    ++j)"-cr2r   Nr   r.   r   r   r  r    s    Hr   r  c                       e Zd Zd Zy)NintendoBrowserNr   r.   r   r   r  r    s     Hr   r  c                       e Zd ZdZg dZd Zy)AndroidBrowserr   )r   Windows Phonerj   Firefoxc                      y r	   r.   r   s      r   r@   zAndroidBrowser.getVersion  r   r   Nrp   r.   r   r   r
  r
    s    HCMr   r
  c                   "    e Zd Zd dgZdgZddgZy)r  r   rt   	SeaMonkeyr   N)r+   r,   r-   rH   rO   rF   r.   r   r   r  r    s    7#H kO -0Mr   r  c                       e Zd Zd ZdgZy)r  rt   Nrd   r.   r   r   r  r    s    H kOr   r  c                       e Zd Zd Zd Zd Zy)Linuxc                      y r	   r.   r   s      r   r@   zLinux.getVersion  r   r   Nr+   r,   r-   rH   r>   r@   r.   r   r   r  r    s    HHr   r  c                       e Zd ZdZdZd Zy)
Blackberry
BlackBerryc                      y r	   r.   r   s      r   r@   zBlackberry.getVersion  r   r   Nr  r.   r   r   r  r    s    HHr   r  c                       e Zd ZdZdZd Zy)BlackberryPlaybookPlayBookr  c                      y r	   r.   r   s      r   r@   zBlackberryPlaybook.getVersion  r   r   Nr  r.   r   r   r  r    s    HHr   r  c                   $    e Zd ZdZdZddgZddgZy)WindowsPhoner  WindowszWindows Phone OS)r4   rZ   )r4   r   N)r+   r,   r-   r6   r>   rH   rO   r.   r   r   r  r    s     DH"O4H!:.Or   r  c                       e Zd ZdZdgZy)iOS)iPhoneiPadlike iPhoneN)r+   r,   r-   rH   rF   r.   r   r   r!  r!    s    !H"OMr   r!  c                        e Zd Zd ZdZdgZd Zy)r"  r!  r$  c                     dg}d|vry |j                  d      d   j                         }|D ].  }||v s|j                  |      d   }|j                  dd      c S  y )Nr4   z	iPhone OSrN   rL   _.rP   r   replacer   rA   rC   version_end_charspartcr<   s          r   r@   ziPhone.getVersion  so     Ee#{{;'+113" 	1ADy**Q-*sC00	1 r   Nr+   r,   r-   rH   r>   rF   r@   r.   r   r   r"  r"    s    HH"OM	r   r"  c                       e Zd ZdZdZd Zy)IPadziPad;r!  c                     dg}d|vry |j                  d      d   j                         }|D ].  }||v s|j                  |      d   }|j                  dd      c S  y )Nr4   zCPU OS rN   rL   r'  r(  r)  r+  s          r   r@   zIPad.getVersion  so     EE!{{9%b)//1" 	1ADy**Q-*sC00	1 r   Nr  r.   r   r   r1  r1    s    HH	r   r1  c                       e Zd Zd Zd Zy)	Macintoshc                      y r	   r.   r   s      r   r@   zMacintosh.getVersion  r   r   Nr   r.   r   r   r4  r4    s    Hr   r4  c                   "    e Zd ZdZdZddgZd Zy)MacOSMac OSr"  r#  c                     ddg}|j                  d      d   j                         }|D ].  }||v s|j                  |      d   }|j                  dd      c S  y)	NrZ   r   r8  rN   rL   r'  r(  r0   r)  r+  s          r   r@   zMacOS.getVersion  sf     #J{{8$R(..0" 	1ADy**Q-*sC00	1 r   Nr/  r.   r   r   r7  r7    s    HHv&Mr   r7  c                       e Zd Zd Zd Zy)r  Nr+   r,   r-   rH   r>   r.   r   r   r  r     s    HHr   r  c                   :    e Zd Zd Zd ZdgZdddddddd	d
dd
Zd Zy)r  r  10z8.187VistazServer 2003 / XP x64XPz2000 SP12000Me)
zNT 10.0zNT 6.3zNT 6.2zNT 6.1zNT 6.0zNT 5.2zNT 5.1zNT 5.01zNT 5.0z98; Win 9x 4.90c                     |j                  d      d   j                  d      d   j                         }d|v r|j                  d      d   }| j                  j                  ||      }|S )Nr  rN   rZ   rL   r   )rP   r   win_versionsr9   )r   rA   rC   r(   s       r   r@   zWindows.getVersion  sc    KK	"2&,,S1!4::<!8QA!!!Q'r   N)r+   r,   r-   rH   r>   rF   rE  r@   r.   r   r   r  r    s>    HH$%M##!!%4")$'+Lr   c                       e Zd Zd ZddgZy)Ubuntur3   r4   Nrd   r.   r   r   rG  rG        HCjOr   rG  c                       e Zd Zd ZddgZy)Debianr3   r4   Nrd   r.   r   r   rJ  rJ  #  rH  r   rJ  c                   &    e Zd Zd ZddgZg dZd Zy)r   r3   r4   )z OPRr   r   r   c                     |j                  || j                  d   z         d   }|j                  | j                  d         d   }d|v r|j                  d      d   }|j                         S NrL   rN   rM   +rP   rO   r   r   rA   rC   r-  r<   s        r   r@   zChrome.getVersion,  i    {{4$"6"6q"99:2>**T11!45a8'>mmC(+G}}r   N)r+   r,   r-   rH   rO   rF   r@   r.   r   r   r   r   '  s    HCjO9Mr   r   c                   "    e Zd Zd ZdZddgZd Zy)r   zYandex.Browserr3   r4   c                     |j                  || j                  d   z         d   }|j                  | j                  d         d   }d|v r|j                  d      d   }|j                         S rM  rO  rP  s        r   r@   zYaBrowser.getVersion8  rQ  r   N)r+   r,   r-   rH   r6   rO   r@   r.   r   r   r   r   3  s    HDCjOr   r   c                       e Zd ZdZddgZy)	ChromeiOSr   r3   r4   Nrd   r.   r   r   rU  rU  ?  s    HCjOr   rU  c                   "    e Zd ZdZdZddgZd Zy)ChromeOSCrOSz	 ChromeOSr4   c                     | j                   }|dz   |v rddg}|j                  ||d   z         d   j                  |d         d   j                         d d S )NrN  rL   rN   rM   )rO   rP   r   )r   rA   rC   rO   s       r   r@   zChromeOS.getVersionI  si    ..#:"CjO{{4/!"445b9??PQ@RSTUV\\^_b`bccr   N)r+   r,   r-   rH   r>   rO   r@   r.   r   r   rW  rW  D  s    HHCjOdr   rW  c                        e Zd Zd Zd ZdgZd Zy)r   r  c                     |j                  |      d   j                  dd      j                  d      d   j                         S )NrN   r   rZ   rL   )rP   r*  r   r   s      r   r@   zAndroid.getVersionU  s<    {{4 $,,S#6<<SA!DJJLLr   Nr/  r.   r   r   r   r   P  s    HH$%MMr   r   c                       e Zd ZdZd Zy)WebOShpwOSc                 j    |j                  d      d   j                  d      d   j                         S )NzhpwOS/rN   rZ   rL   r   r   s      r   r@   zWebOS.getVersion\  s/    {{8$R(..s3A6<<>>r   Nr   r.   r   r   r]  r]  Y  s    H?r   r]  c                       e Zd ZdZdZd Zy)NokiaS40Series40z	Nokia S40c                      y r	   r.   r   s      r   r@   zNokiaS40.getVersiond  r   r   Nr  r.   r   r   ra  ra  `  s    HHr   ra  c                       e Zd Zd dgZd Zy)Symbian	SymbianOSNr;  r.   r   r   re  re  h  s    ;'HHr   re  c                        e Zd Zd dgZd ZddgZy)PlayStationPLAYSTATIONr4   r   N)r+   r,   r-   rH   r>   rO   r.   r   r   rh  rh  m  s    }-HHCjOr   rh  c            
          e Zd Z e e eeegeeg             eeg       ee	g       ee
eg       eeg       eeg            Z e eeg       eeg       eeg       eeg            Z e eeeee
g            Zy)	prefs)r   r   )r   )r   )r   )r  r  r4  r  rW  rJ  )rG  r   IPhoner1  )r7  N)r+   r,   r-   r
   r  r   rG  r   r  r7  rz   r   r   r   rj   r   r.   r   r   rk  rk  s  s    	4& 18IJK012ug&dG_-vh'WI&
B WI&fX&VH%6(#	D E67D9:Fr   rk  c                 @   t        t        dd            }g }t        D ])  }|xs	 t        |   }|D ]  }	 |j                  | |        + |r:dD ]5  }|j	                  |t                     }	dD ]  }
|	j	                  |
d        7 |S # t        $ r
}Y d}~fd}~ww xY w)zp
    fill_none: if name/version is not detected respective key is still added to the result with value None
    Nr=   )r>   )r   r   )r
   detectorshubrD   	Exceptionr   )rA   	fill_nonerB   rW   r   r)   r   _err	outer_keyouter_value	inner_keys              r   rD   rD     s     4T489F! 	(CL,C	! 	Hv.	 * 	8I ++Itv>K0 8	&&y$78	8
 M  s   B

	BBz
Unknown OSzUnknown BrowserNc                    |xs t        |       }g }d|v r|j                  |d   d          d|v r|j                  |d   d          d|v r|j                  |d   d          |xr dj                  |      xs t        }|xr' |j	                  d      xr |d   j	                  d      xsT |j	                  d      xr |d   j	                  d      xs+ |j	                  d      xr |d   j	                  d      xs d}d|v xr |d   j	                  d      xs t
        }d|v xr |d   j	                  d      xs d}||||fS )	z
    @params:
        agent::str
        parsed_agent::dict
            The result of detect, used to save calculations

    @return:
        (os_name, os_version, browser_name, browser_version)::Tuple(str)
    r   r6   r   r   r4   r<   r0   r   )rD   r   joinUNKNOWN_OS_NAMEr9   UNKNOWN_BROWSER_NAME)rA   parsed_agentrB   os_listr   
os_versionr   browser_versions           r   simple_detect_tupler}    sc    *VE]FG6vh'/0vf~f-.v~vd|F+,		&SXXg&	9/BWfjj2Vvh7G7K7KI7V {	F		=v 2 29 ={CI::dCSCsX^_cXdXhXhirXs{xz 6!CfY&7&;&;F&C[G[G6)NfY.?.C.CI.NTRTOz7O33r   c                     t        | |      \  }}}}|rdj                  ||f      }|rdj                  ||f      }||fS )z
    @params:
        agent::str
        parsed_agent::dict
            The result of detect, used to save calculations

    @return:
        (os_name_version, browser_name_version)::Tuple(str)
    )ry  r4   )r}  rv  )rA   ry  r   r{  r   r|  s         r   simple_detectr    sQ     0C5Wc/d,B
G_((G_56XXr:&'w;r   )Fr	   )Yru   __version__r
   r   objectr%   rY   r\   r_   ra   rc   rf   rj   rr   rw   ry   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   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r
  r  r  r  r  r  r  r!  r"  r1  r4  r7  r  rG  rJ  r   r   rU  rW  r   r]  ra  re  rh  rk  rn  rD   rw  rx  r}  r  r.   r   r   <module>r     s   !4 !4:6 :z < \ l 
! !

>' 
>)G )"w ""w "
]g ] !7 ! W  
37 3W  DW D(/ / G g   ' g R Rg !w !' w  W w 7   w W  ' 
w   W w g w   &7 &G 7 !g !W 1g 1" "
B   /2 /$" $
T "4   F d 
b 2!T !
!T !
W 

 
! !
	dr 	dMd M?D ?r b 
!" ! ( ~0 ( 48r   