+
    +j                     j    R t ^ RIt^ RIt^ RIt^ RIt^ RIt^RIHtHtH	t	 ^<t
R tR t ! R R4      tR# )u   sshj.identity — our own LAN/tailnet identity (leaf).

B2 step 2: moved verbatim from sshj_cli.py (single-file era) — no
behavior change. Owns IDENT_REFRESH (only its consumer, Identity,
lives here).
N)IDENTITY_FILE	load_json	save_jsonc                 (   ^ RI p R Fu  p V P                  V P                  V P                  4      pVP                  R4       VP	                  V4       VP                  4       ^ ,          pVP                  4        Vu # 	  R#   \         d     K  i ; i)u   Best-effort LAN IP without the `ip` command (e.g. Termux/Android):
open a UDP socket 'to' an address and read the local endpoint — no
packet is actually sent, so it works on any interface.Ng333333? ))z10.255.255.1   )z8.8.8.8P   )socketAF_INET
SOCK_DGRAM
settimeoutconnectgetsocknameclose	Exception)r	   probesips       src/sshj/identity.py_lan_ip_socketr      s     7	fnnf.?.?@ALLIIe#BGGII 8   		s   A0BBBc                    R;r \         P                  ! . RORR^R7      pVP                  P                  4        Fl  pVP	                  4       p\        V4      ^8  g   K%  V^,          V^,          P	                  R4      ^ ,          reVR8X  d   TpKW  VR8w  g   K`  V '       d   Kj  Tp Kn  	  V '       g   \        4       p Rp \         P                  ! . RORR^R7      p\        P                  ! VP                  4      pVP                  R4      ;'       g    / p	V	P                  R4      ;'       g    RP                  R	4      p
V
P                  R
4      '       d   V
P	                  R
4      ^ ,          pR	V9   d   VP	                  R	4      ^ ,          pV	P                  R4      ;'       g    . pV'       d
   V^ ,          pT'       g    \        P                  ! 4       P                  pYT3#   \         d     ELIi ; i  \         d     LJi ; i)u=   (lan_ip, tailscale_ip, tailscale_name) — live, best-effort.r   T)capture_outputtexttimeout/
tailscale0loSelfDNSName.z.ts.netTailscaleIPs)r   z-4z-oaddrshow)	tailscalestatusz--json)
subprocessrunstdout
splitlinessplitlenr   r   jsonloadsgetrstripendswithosunamenodename)lantsrlnpdevr!   namedself_dnsipss               r   our_identityr>   %   s   MCNN=*.T1F((%%'B
A1v{aD!A$**S/!"4T,&BD[C ( DNN<*.T1FJJqxx f##yy#))r11#6<<	""99Y'*D$;::c?1%Dii'--2QB xxz""D=-  $  sV   AG&  6G& G& %G&  AG8 G8 /(G8 AG8 '
G8 2	G8 &G54G58HHc                   H   a  ] tR t^Lt o RtR tR tR tR tR t	R t
RtV tR	# )
IdentityzBLive identity: cached value shown muted until a fresh fetch lands.c                r    R ;V n         ;V n        V n        RV n        \        P
                  ! 4       V n        R# )r   FN)r9   r3   r4   stale	threadingLocklockselfs   &r   __init__Identity.__init__O   s,    )++	+DHtw
NN$	    c                4   \        \        / 4      pV'       dl   V P                  ;_uu_ 4        VP                  R R4      V n        VP                  RR4      V n        VP                  RR4      V n        RV n        RRR4       R# R#   + '       g   i     R# ; i)r9   r   r3   r4   TN)r   r   rE   r-   r9   r3   r4   rB   )rG   r:   s   & r   
load_cacheIdentity.load_cacheT   sj    mR(EE&"-	55+%%b/!
	  s   ABB	c                   \        4       w  rpV P                  ;_uu_ 4        V'       d   W0n        V'       d   W n        V'       d   Wn        R V n        V P                  V P                  V P                  3pRRR4       \        \        RX^ ,          RV^,          RV^,          R\        P                  ! 4       /4       R#   + '       g   i     LR; i)FNr3   r4   r9   ts_at)	r>   rE   r9   r4   r3   rB   r   r   time)rG   r3   r4   r9   snaps   &    r   refreshIdentity.refresh]   s    $YYY 	DJHHdggtyy1D  	-%a$Q"($q'7DIIK"I 	J Ys   CC0CC	c                j    \         P                  ! R V P                  R7      pVP                  4        V# )T)daemontarget)rC   Thread_loopstart)rG   ts   & r   rY   Identity.startk   s&    D<		rJ   c                    V P                  4         \        P                  ! \        4        V P                  4        K.    \         d     K<  i ; i)T)rR   rP   sleepIDENT_REFRESHr   rF   s   &r   rX   Identity._loopp   s:    JJ}% s   ? AAc                   V P                   ;_uu_ 4        V P                  V P                  3 Uu. uF  q"'       g   K  VNK  	  ppRP                  V4      pRP                  R V P                  V3 4       4      pV P
                  pV P                  pRRR4       XXX3 F#  pV'       g   K  \        V4      V8:  g   K  VX3u # 	  RX3# u upi   + '       g   i     LE; i)uE   Pick the longest tier that fits: lan · ts name → ts name → name. u    · c              3   8   "   T F  q'       g   K  Vx  K  	  R # 5i)N ).0r7   s   & r   	<genexpr>#Identity.display.<locals>.<genexpr>~   s     A*;Qqqq*;s   	
Nr   )rE   r4   r9   joinr3   rB   r*   )	rG   max_wr7   partsshortfullrB   r9   r   s	   &&       r   displayIdentity.displayy   s    YYY!%$)) 4: 41QQ 4E:HHUOE;;A488U*;AADJJE99D  t$AqSVu_%x % 5y ; Ys"   C	CCACCC 	)r3   rE   r9   rB   r4   N)__name__
__module____qualname____firstlineno____doc__rH   rL   rR   rY   rX   rl   __static_attributes____classdictcell__)__classdict__s   @r   r@   r@   L   s,     L%
"J
 rJ   r@   )rr   r+   r0   r%   rC   rP   jsonior   r   r   r^   r   r>   r@   rc   rJ   r   <module>rw      s;     	    7 7$$N8 8rJ   