
    2yi/                       d Z ddl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
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 ddlmZ e	j2                  d	k\  r	dd
lmZmZ ndd
lmZmZ ddlmZ ddl m!Z!m"Z" erddl#m$Z$  ed      Z% ejL                  e'      Z(dZ)ddd6dZ*d7dZ+d8dZ,e	j2                  dk\  re-j\                  Z/nd9dZ/d:dZ0e	j2                  d	k\  rddl1m2Z2 nd dd;dZ2d<dZ3d=dZ4d>dZ5d?dZ6 ejn                  d      Z8d?d Z9 ejt                  d!      d@d"       Z;dAd#Z<dBdCd$Z= ejt                  d!      dDd%       Z>	 dB	 	 	 	 	 	 	 dEd&Z?d' Z@dFd(ZA ejt                  d!      dGd)       ZBdHd*ZCdId+ZDdJd,ZEd- ZFd. ZG G d/ d0      ZH G d1 d2ej                        ZJ G d3 d4      ZKdKd5ZLy)Lz
Standalone file utils.

Nothing in this module should have an knowledge of config or the layout
and structure of the site and pages in the site.
    )annotationsN)defaultdict)datetimetimezone)PurePath)TYPE_CHECKING
CollectionIterableMutableSequenceTypeVar)urlsplit)   
   )
EntryPointentry_points)
exceptions)get_yaml_loader	yaml_load)PageT)z	.markdownz.mdownz.mkdnz.mkdz.md)pagesc                    | rFt        d | D              }t        j                  |      j                  t        j
                        }n
t               }t        |j                               S )z
    Returns the number of seconds since the epoch for the latest updated page.

    In reality this is just today's date because that's how pages' update time is populated.
    c              3  4   K   | ]  }|j                     y wN)update_date).0ps     W/var/www/html/content_weaver/venv/lib/python3.12/site-packages/mkdocs/utils/__init__.py	<genexpr>z&get_build_timestamp.<locals>.<genexpr>7   s     7A!--7s   )tzinfo)	maxr   fromisoformatreplacer   utcget_build_datetimeint	timestamp)r   date_stringdts      r   get_build_timestampr*   /   sR     777##K0888M!r||~    c                     t         j                  j                  d      } | #t        j                  t
        j                        S t        j                  t        |       t
        j                        S )z
    Returns an aware datetime object.

    Support SOURCE_DATE_EPOCH environment variable for reproducible builds.
    See https://reproducible-builds.org/specs/source-date-epoch/
    SOURCE_DATE_EPOCH)	osenvirongetr   nowr   r$   fromtimestampr&   )source_date_epochs    r   r%   r%   >   sN     

':; ||HLL))!!#&7"8(,,GGr+   c                 4    t               j                  d      S )z
    Returns the displayable date string.

    Support SOURCE_DATE_EPOCH environment variable for reproducible builds.
    See https://reproducible-builds.org/specs/source-date-epoch/
    z%Y-%m-%d)r%   strftime r+   r   get_build_dater7   L   s     ((44r+   )r   	   c                J    |r | j                  |      r| d t        |        S | S r   )endswithlen)ssuffixs     r   _removesuffixr>   Z   s(    ajj(^F|$$r+   c                >    t        t        j                  |             S )z4Reduce duplicate items in a list and preserve order.)listdictfromkeys)data_sets    r   reduce_listrD   `   s    h'((r+   )insortc                    | S r   r6   )vs    r   <lambda>rH   i   s    Q r+   )keyc                    ||      }t        |       }|dkD  r-| || |dz
           k  r|dz  }|dkD  r| || |dz
           k  r| j                  ||       y )Nr      )r;   insert)axrI   kxis        r   rE   rE   i   s`    VF!eS1q5]*FA !eS1q5]*	Ar+   c                T   t         j                  j                  |      }t        j                  |d       t         j                  j	                  |      r=t         j                  j                  |t         j                  j                  |             }t        j                  | |       y)z}
    Copy source_path to output_path, making sure any parent directories exist.

    The output_path may be a directory.
    Texist_okN)	r.   pathdirnamemakedirsisdirjoinbasenameshutilcopyfile)source_pathoutput_path
output_dirs      r   	copy_filer_   q   se     -JKK
T*	ww}}[!ggll;0@0@0MN
OOK-r+   c                    t         j                  j                  |      }t        j                  |d       t	        |d      5 }|j                  |        ddd       y# 1 sw Y   yxY w)zGWrite content to output_path, making sure any parent directories exist.TrR   wbN)r.   rT   rU   rV   openwrite)contentr]   r^   fs       r   
write_filerf   ~   sO    -JKK
T*	k4	  A	  s   AA'c                r   t         j                  j                  |       syt        j                  |       D ]  }|j	                  d      rt         j                  j                  | |      }t         j                  j                  |      rt        j                  |d       kt        j                  |        y)zKRemove the content of a directory recursively but not the directory itself.N.T)
r.   rT   existslistdir
startswithrX   rW   rZ   rmtreeunlink)	directoryentryrT   s      r   clean_directoryrp      s}    77>>)$I& 
 C ww||Iu-77==MM$%IIdO
r+   c                ,    | j                  t              S )z
    Return True if the given file path is a Markdown file.

    https://superuser.com/questions/249436/file-extension-for-markdown-files
    )r:   markdown_extensionsrT   s    r   is_markdown_filert      s     ==,--r+   z^\d{3}\.html?$c                >    t        t        j                  |             S )z=Return True if the given file path is an HTTP error template.)bool_ERROR_TEMPLATE_REmatchrs   s    r   is_error_templatery      s    "((.//r+   )maxsizec                    | j                  d      sd| z   } t        j                  |       dd  } | r| j                  d      S g S )N/rK   )rk   	posixpathnormpathsplitrs   s    r   _norm_partsr      sC    ??3Tzd#AB'D"4::c?**r+   c                2   |j                  d      \  }}}d|v r|}t        |      }t        |       }d}t        ||      D ]  \  }}	||	k7  r n|dz  } dgt        |      |z
  z  ||d z   }
dj	                  |
      xs d}| j                  d      r|dz   S |S )a  
    Return given url relative to other.

    Both are operated as slash-separated paths, similarly to the 'path' part of a URL.
    The last component of `other` is skipped if it contains a dot (considered a file).
    Actual URLs (with schemas etc.) aren't supported. The leading slash is ignored.
    Paths are normalized ('..' works as parent directory), but going higher than the
    root has no effect ('foo/../../bar' ends up just as 'bar').
    r|   rh   r   rK   z..N)
rpartitionr   zipr;   rX   r:   )urlotherrU   _rY   other_parts
dest_partscommonrM   b	rel_partsrelurls               r   get_relative_urlr      s     !++C0GQ
he$KS!JFK, 16!
 #k*V34z&'7JJIXXi 'CF<<,6C<8&8r+   c                    t        |       \  } }|dk(  r| S |%t        | |j                        }|dkD  rd|z  |z   }|S t        j                  ||       S )z:Return a URL relative to the given page or using the base.r   ../)_get_norm_urlr   r   r}   rX   )rT   pagebaserelative_levelresults        r   normalize_urlr      sa    (.D.!$1A^+f4F>>$%%r+   c                v   | sd} n/d| v r+t         j                  d|  d       | j                  dd      } t        |       }|j                  s|j
                  s| j                  d      r| dfS t        j                  |       dz   }d}|j                  d	|d
z        r|dz  }|j                  d	|d
z        r| |fS )Nrh   \zPath 'zh' uses OS-specific separator '\'. That will be unsupported in a future release. Please change it to '/'.r|   )r|   #r   r   r   r   rK   )	logwarningr#   r   schemenetlocrk   r}   r~   )rT   parsednormr   s       r   r   r      s    	TF U V	
 ||D#&d^F}})DRx d#c)DN
//%!!3
4! //%!!3
4r+   c                B    | D cg c]  }t        |||       c}S c c}w )Soft-deprecated, do not use.)r   )	path_listr   r   rT   s       r   create_media_urlsr      s"     9BBM$d+BBBs   c                Z    t        j                  dt               | j                  dd      S )Nz=path_to_url is never used in MkDocs and will be removed soon.r   r|   )warningswarnDeprecationWarningr#   rs   s    r   path_to_urlr      s'    MMGI[ <<c""r+   c                    t               |    }t        j                  j                  t        j                  j	                  |j                         j                              S )z3Return the directory of an installed theme by name.)
get_themesr.   rT   rU   abspathload__file__)namethemes     r   get_theme_dirr      s:    LE77??277??5::<+@+@ABBr+   c                    i } t         j                  t        d            }|D ch c]5  }|j                  |j                  j                  dk(  s*|j                  7 }}|D ]
  }|j                  J |j                  |v rS|j                  j                  dk7  r:t        j                  d|j                   d|j                  j                   d      |j                  | v r{| |j                     j                  }|J t        j                  d|j                   d|j                  j                   d	|j                   d
|j                  j                   d	       || |j                  <    | S c c}w )z<Return a dict of all installed themes as {name: EntryPoint}.zmkdocs.themes)groupmkdocszThe theme 'z&' is a builtin theme but the package 'z1' attempts to provide a theme with the same name.zA theme named 'z&' is provided by the Python packages 'z' and 'z'. The one in 'z' will be used.)	rA   rB   r   distr   r   ConfigurationErrorr   r   )themesepsepbuiltinsr   
other_dists         r   r   r     sd    %'F"&--?0S"TC"%ZB)<QYAYZHZ #zz%%%::!ejjoo&A//ejj\)OPUPZPZP_P_O` aB B  ZZ6!

+00J)))KK!%**-STYT^T^TcTcSd e"(

7HY
 #uzz!#$ M) [s   E4E4E4c                 2    t               j                         S )z.Return a list of all installed themes by name.)r   keysr6   r+   r   get_theme_namesr   "  s    <r+   c                    | }|j                  dd      j                  dd      }|j                         |k(  r|j                         }|S )z2Return a page tile obtained from a directory name.- r   )r#   lower
capitalize)rU   titles     r   dirname_to_titler   '  sE    EMM#s#++C5E{{}  "Lr+   c                   | j                  dd      j                  dd      j                  d      }|rS|j                  d      j                         }|j                         s2|j	                  d      sy|j                  d      S y)r   z

r   z# N)r#   r   popstriprk   lstrip)markdown_srclineslines      r   get_markdown_titler   2  sr      .66tTBHHNE
yy|!!#zz|t${{4  r+   c                z    | D ]  }t        |t              s||v s||   c S  g }||i}| j                  |       |S )z
    Given a list, look for dictionary with a key matching key and return it's
    value. If it doesn't exist, create it with the value of an empty list and
    return that.
    )
isinstancerA   append)branchrI   node
new_branchs       r   find_or_create_noder   ?  sT      $%$;9 JD
MM$r+   c                    g }| D ]R  }t        |      j                  j                  }|}|D ]  }t        |      }t	        ||      } |j                  |       T |S )zk
    Given a list of paths, convert them into a nested structure that will match
    the pages config.
    )r   parentpartsr   r   r   )pathsnestedrT   r   r   parts         r   
nest_pathsr   R  sl    
 F %%++ 	7D#D)D(6F	7 	d Mr+   c                       e Zd ZdZddZddZy)DuplicateFilterz!Avoid logging duplicate messages.c                "    t               | _        y r   )setmsgs)selfs    r   __init__zDuplicateFilter.__init__i  s    !e	r+   c                    |j                   | j                  v}| j                  j                  |j                          |S r   )msgr   addr   recordrvs      r   __call__zDuplicateFilter.__call__l  s-    ZZtyy(		fjj!	r+   NreturnNone)r   zlogging.LogRecordr   rv   )__name__
__module____qualname____doc__r   r   r6   r+   r   r   r   f  s    +$r+   r   c                  2     e Zd ZdZd fdZd ZddZ xZS )CountHandlerz$Counts all logged messages >= level.c                L    t        t              | _        t        |   di | y )Nr6   )r   r&   countssuperr   )r   kwargs	__class__s     r   r   zCountHandler.__init__u  s    &1#&6"6"r+   c                n    | j                  |      }|r!| j                  |j                  xx   dz  cc<   |S )NrK   )filterr   levelnor   s      r   handlezCountHandler.handley  s0    [[ KK'1,'	r+   c                    t        | j                  j                         d      D cg c]  \  }}t        j                  |      |f c}}S c c}}w )NT)reverse)sortedr   itemslogginggetLevelName)r   krG   s      r   
get_countszCountHandler.get_counts  s?    9?@Q@Q@S]a9bcA%%a(!,cccs   !Ar   )r   zlist[tuple[str, int]])r   r   r   r   r   r   r  __classcell__)r   s   @r   r   r   r  s    .#dr+   r   c                      e Zd ZdZd ZddZy)weak_propertyzHSame as a read-only property, but allows overwriting the field for good.c                4    || _         |j                  | _        y r   )funcr   )r   r	  s     r   r   zweak_property.__init__  s    	||r+   Nc                ,    || S | j                  |      S r   )r	  )r   instanceowners      r   __get__zweak_property.__get__  s    Kyy""r+   r   )r   r   r   r   r   r  r6   r+   r   r  r    s    R$#r+   r  c                    | dk(  r.t        j                  dt               t        j                         S t        dt        d|       )Nwarning_filterzwarning_filter doesn't do anything since MkDocs 1.2 and will be removed soon. All messages on the `mkdocs` logger get counted automatically.zmodule z has no attribute )r   r   r   r  FilterAttributeErrorr   )r   s    r   __getattr__r    sH    M	

 ~~
78,.@I
JJr+   )r   zCollection[Page] | Noner   r&   )r   r   )r   str)r<   r  r=   r  r   r  )rC   zIterable[T]r   zlist[T])rM   zMutableSequence[T]rN   r   r   r   )r\   r  r]   r  r   r   )rd   bytesr]   r  r   r   )rn   r  r   r   )rT   r  r   rv   )rT   r  r   	list[str])r   r  r   r  r   r  )N )rT   r  r   Page | Noner   r  r   r  )rT   r  r   ztuple[str, int])r   zIterable[str]r   r  r   r  r   r  )r   r  r   r  )r   zdict[str, EntryPoint])r   zCollection[str])rU   r  r   r  )r   r  r   z
str | None)r   r  )Mr   
__future__r   	functoolsr  r.   r}   rerZ   sysr   collectionsr   r   r   pathlibr   typingr   r	   r
   r   r   urllib.parser   version_infoimportlib.metadatar   r   importlib_metadatar   r   mkdocs.utils.yamlr   r   mkdocs.structure.pagesr   r   	getLoggerr   r   rr   r*   r%   r7   r  removesuffixr>   rD   bisectrE   r_   rf   rp   rt   compilerw   ry   	lru_cacher   r   r   r   r   r   r   r   r   r   r   r   r   r   NullHandlerr   r  r  r6   r+   r   <module>r+     s   #   	  	  
  # '  P P !w;;;  8+CLg!  =A H5 v$$M)
 w 4? 
.$.  RZZ 12 0
 T"+ #+98& T"  # . EGCC$/C>ACC#C T" #6

&(	 	d7&& d$
# 
#	Kr+   