Ë
    rPêjñ³  ã            &       óö  — d 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mZ ddlmZ ddlmZmZmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZmZmZm Z m!Z!m"Z"m#Z# ddl$m%Z% ddl&m'Z' erddl(m)Z)  ejT                  e+«      Z,dZ-dZ.e G d„ d«      «       Z/e G d„ d«      «       Z0e G d„ d«      «       Z1e G d„ d«      «       Z2 ed¬«       G d„ d«      «       Z3e G d„ d«      «       Z4e G d „ d!«      «       Z5e G d"„ d#«      «       Z6d$e7d%efd&„Z8d$e7d%e9fd'„Z:e G d(„ d)«      «       Z;e G d*„ d+«      «       Z< G d,„ d-«      Z=d.e7d%e>e?e7e7f      fd/„Z@d$e7d%e?eAeBf   dz  fd0„ZCd1e7d%e	e?e7eAeBf      fd2„ZDd3d4d5e7d6e7d%e	e?e7eAeBef      fd7„ZEd8eBd%e7fd9„ZFdd:œd$e7d;ed<   d=eAd>eBd?eAd@eBdAe7dBe7dCe9dDe9dEe9dFedz  d%e;fdG„ZG	 	 	 	 	 	 	 dadIe7dJe7d3d4dKe9dDe9dCe9dLe9dEe9dMe=dz  dNedz  d%e<fdO„ZHdPe<d%dfdQ„ZIdPe<dRe7d%dfdS„ZJdRe7d%e<fdT„ZKdbdPe<d3d4dUe9dNedz  d%df
dV„ZLdPe<d%dfdW„ZM	 	 dcdHdHdHdHdHddddddHdHdHddXœdIe7dz  dJe7dz  d3d4dKe9dDe9dCe9dLe9dEe9dYe>e7   dz  dZe>e7   dz  d[e7dz  dPe7dz  d\e7dz  d]e9dUe9d^e9d_e9e7z  dz  d%e<f$d`„ZNy)dzzShared logic for bucket operations.

This module contains the core buckets logic used by both the CLI and the Python API.
é    N)ÚIterator)Ú	dataclassÚfield)ÚdatetimeÚtimezone)ÚPath)ÚTYPE_CHECKINGÚAnyÚLiteralé   )Ú	constantsÚlogging)Ú_validate_relative_filename)ÚBucketNotFoundError)ÚHfUriÚ
StatusLineÚXetFileDataÚdisable_progress_barsÚenable_progress_barsÚparse_datetimeÚparse_hf_uri)Ú_looks_like_hf_url)Ú_normalize_separators©ÚHfApizhf://buckets/éè  c                   óJ   — e Zd ZU dZeed<   eed<   eed<   eed<   eed<   d„ Z	y)	Ú
BucketInfoaß  
    Contains information about a bucket on the Hub. This object is returned by [`bucket_info`] and [`list_buckets`].

    Attributes:
        id (`str`):
            ID of the bucket.
        private (`bool`):
            Is the bucket private.
        created_at (`datetime`):
            Date of creation of the bucket on the Hub.
        size (`int`):
            Size of the bucket in bytes.
        total_files (`int`):
            Total number of files in the bucket.
    ÚidÚprivateÚ
created_atÚsizeÚtotal_filesc                 ó*  — |j                  d«      | _        |j                  d«      | _        t        |j                  d«      «      | _        |j                  d«      | _        |j                  d«      | _         | j                  j                  di |¤Ž y )Nr   r    Ú	createdAtr"   Ú
totalFiles© )	Úpopr   r    r   r!   r"   r#   Ú__dict__Úupdate)ÚselfÚkwargss     ú]/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/huggingface_hub/_buckets.pyÚ__init__zBucketInfo.__init__X   so   € Ø—*‘*˜TÓ"ˆŒØ—z‘z )Ó,ˆŒÜ(¨¯©°KÓ)@ÓAˆŒØ—J‘J˜vÓ&ˆŒ	Ø!Ÿ:™: lÓ3ˆÔØˆ�‰×ÑÑ&˜vÓ&ó    N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstrÚ__annotations__Úboolr   Úintr.   r'   r/   r-   r   r   @   s)   … ñð  	ƒGØƒMØÓØ
ƒIØÓó'r/   r   c                   ó¸   — e Zd ZU eez  ez  ed<   eed<    ed¬«      Zedz  ed<    ed¬«      Z	e
dz  ed<    ed¬«      Ze
ed	<    ed¬«      Zedz  ed
<   dd„Zy)Ú_BucketAddFileÚsourceÚdestinationN©ÚdefaultÚxet_hashr"   F©ÚinitÚmtimeÚcontent_typec                 óð  — d | _         t        | j                  t        t        f«      r't        j                  | j                  «      d   | _         | j                   €'t        j                  | j                  «      d   | _         t        t        | j                  t        «      s6t        j                  j                  | j                  «      dz  «      | _        y t        j                  «       dz  «      | _        y ©Nr   r   )rB   Ú
isinstancer:   r4   r   Ú	mimetypesÚ
guess_typer;   r7   ÚbytesÚosÚpathÚgetmtimeÚtimerA   ©r+   s    r-   Ú__post_init__z_BucketAddFile.__post_init__k   s²   € Ø ˆÔÜ�d—k‘k¤C¬ ;Ô/Ü )× 4Ñ 4°T·[±[Ó AÀ!Ñ DˆDÔØ×ÑÐ$Ü )× 4Ñ 4°T×5EÑ5EÓ FÀqÑ IˆDÔäÜ8BÀ4Ç;Á;ÔPUÔ8VŒB�G‰G×Ñ˜TŸ[™[Ó)¨DÑ0ó
ˆ�
Ü\`×\eÑ\eÓ\gÐjnÑ\nó
ˆ�
r/   ©ÚreturnN)r0   r1   r2   r4   r   rH   r5   r   r>   r"   r7   rA   rB   rN   r'   r/   r-   r9   r9   a   sd   … à�$‰J˜ÑÓØÓá ¨Ô.€Hˆc�D‰jÓ.Ù TÔ*€Dˆ#�‰*Ó*Ù˜EÔ"€Eˆ3Ó"Ù$¨%Ô0€L�#˜‘*Ó0ô	
r/   r9   c                   óž   — e Zd ZU eed<   eed<   eed<   eed<    ed¬«      Zedz  ed<    ed¬	«      Zeed
<    ed¬	«      Z	edz  ed<   dd„Z
y)Ú_BucketCopyFiler;   r>   Úsource_repo_typeÚsource_repo_idNr<   r"   Fr?   rA   rB   c                 óœ   — t        j                  | j                  «      d   | _        t	        t        j
                  «       dz  «      | _        y rD   )rF   rG   r;   rB   r7   rL   rA   rM   s    r-   rN   z_BucketCopyFile.__post_init__�   s7   € Ü%×0Ñ0°×1AÑ1AÓBÀ1ÑEˆÔÜœŸ™› tÑ+Ó,ˆ�
r/   rO   )r0   r1   r2   r4   r5   r   r"   r7   rA   rB   rN   r'   r/   r-   rR   rR   w   sS   … àÓØƒMØÓØÓÙ TÔ*€Dˆ#�‰*Ó*Ù˜EÔ"€Eˆ3Ó"Ù$¨%Ô0€L�#˜‘*Ó0ô-r/   rR   c                   ó   — e Zd ZU eed<   y)Ú_BucketDeleteFilerJ   N)r0   r1   r2   r4   r5   r'   r/   r-   rW   rW   †   s   … à
„Ir/   rW   T)Úfrozenc                   ó&   — e Zd ZU dZeed<   eed<   y)ÚBucketFileMetadataa%  Data structure containing information about a file in a bucket.

    Returned by [`get_bucket_file_metadata`].

    Args:
        size (`int`):
            Size of the file in bytes.
        xet_file_data (`XetFileData`):
            Xet information for the file (hash and refresh route).
    r"   Úxet_file_dataN)r0   r1   r2   r3   r7   r5   r   r'   r/   r-   rZ   rZ   ‹   s   … ñ	ð ƒIØÔr/   rZ   c                   ó†   — e Zd ZU dZeed<   dZeed<    ed¬«      Zeed<    ed¬«      Z	eed<    ed¬«      Z
eed	<   dd„Zy
)Ú	BucketUrla½  Describes a bucket URL on the Hub.

    `BucketUrl` is returned by [`create_bucket`]. At initialization, the URL is parsed to populate properties:
    - endpoint (`str`)
    - namespace (`str`)
    - bucket_id (`str`)
    - url (`str`)
    - uri (`HfUri`)

    Args:
        url (`str`):
            String value of the bucket url.
        endpoint (`str`, *optional*):
            Endpoint of the Hub. Defaults to <https://huggingface.co>.
    ÚurlÚ ÚendpointFr?   Ú	namespaceÚ	bucket_idÚuriNc                 óÆ  — | j                   xs t        j                  | _         | j                  j	                  | j                   d«      j                  d«      }|j                  d«      r|t        d«      d  }t        |«      }|j                  rt        d| j                  › �«      ‚|j                  j                  d«      d   | _        |j                  | _        || _        y )Nr_   ú/zbuckets/zUnable to parse bucket URL: r   )r`   r   ÚENDPOINTr^   ÚreplaceÚstripÚ
startswithÚlenÚ_parse_bucket_uriÚpath_in_repoÚ
ValueErrorr   Úsplitra   rb   rc   )r+   Úurl_pathÚparseds      r-   rN   zBucketUrl.__post_init__´   s³   € ØŸ™Ò;¬×);Ñ);ˆŒð —8‘8×#Ñ# D§M¡M°2Ó6×<Ñ<¸SÓAˆà×Ñ˜zÔ*Ø¤ J£Ð 1Ð2ˆHÜ" 8Ó,ˆØ×ÒÜÐ;¸D¿H¹H¸:ÐFÓGÐGØŸ™Ÿ™¨Ó-¨aÑ0ˆŒØŸ™ˆŒØˆ�r/   rO   )r0   r1   r2   r3   r4   r5   r`   r   ra   rb   rc   r   rN   r'   r/   r-   r]   r]   œ   sJ   … ñð  
ƒHØ€HˆcÓÙ Ô&€IˆsÓ&Ù Ô&€IˆsÓ&Ù˜EÔ"€CˆÓ"ôr/   r]   c                   óf   — e Zd ZU dZed   ed<   eed<   eed<   eed<   edz  ed<   edz  ed	<   d
„ Z	y)Ú
BucketFilez«
    Contains information about a file in a bucket on the Hub. This object is returned by [`list_bucket_tree`].

    Similar to [`RepoFile`] but for files in buckets.
    ÚfileÚtyperJ   r"   r>   NrA   Úuploaded_atc                 óX  — |j                  d«      | _        |j                  d«      | _        |j                  d«      | _        |j                  d«      | _        |j                  dd «      }|rt        |«      nd | _        |j                  dd «      }|rt        |«      | _        y d | _        y )Nrt   rJ   r"   ÚxetHashrA   Ú
uploadedAt)r(   rt   rJ   r"   r>   r   rA   ru   )r+   r,   rA   ru   s       r-   r.   zBucketFile.__init__Ó   sˆ   € Ø—J‘J˜vÓ&ˆŒ	Ø—J‘J˜vÓ&ˆŒ	Ø—J‘J˜vÓ&ˆŒ	ØŸ
™
 9Ó-ˆŒØ—
‘
˜7 DÓ)ˆÙ.3”^ EÔ*¸ˆŒ
Ø—j‘j ¨tÓ4ˆÙ:Eœ>¨+Ó6ˆÕÈ4ˆÕr/   )
r0   r1   r2   r3   r   r5   r4   r7   r   r.   r'   r/   r-   rr   rr   Ä   s<   … ñð �&‰/ÓØ
ƒIØ
ƒIØƒMØ�d‰?ÓØ˜D‘Ó óPr/   rr   c                   óB   — e Zd ZU dZed   ed<   eed<   edz  ed<   d„ Zy)ÚBucketFolderz¸
    Contains information about a directory in a bucket on the Hub. This object is returned by [`list_bucket_tree`].

    Similar to [`RepoFolder`] but for directories in buckets.
    Ú	directoryrt   rJ   Nru   c                 ó  — |j                  d«      | _        |j                  d«      | _        |j                  dd «      xs |j                  dd «      }|r)t        |t        «      r|| _        y t        |«      | _        y d | _        y )Nrt   rJ   rx   ru   )r(   rt   rJ   rE   r   r   ru   )r+   r,   ru   s      r-   r.   zBucketFolder.__init__ê   s|   € Ø—J‘J˜vÓ&ˆŒ	Ø—J‘J˜vÓ&ˆŒ	Ø—j‘j ¨tÓ4ÒW¸¿
¹
À=ÐRVÓ8Wˆñ ô ' {´HÔ=ˆ[ð 	ÕÜCQÐR]ÓC^ð 	Õð ð 	Õr/   )	r0   r1   r2   r3   r   r5   r4   r   r.   r'   r/   r-   rz   rz   Þ   s(   … ñð �+Ñ
ÓØ
ƒIØ˜D‘Ó ó
r/   rz   rJ   rP   c                 óv  — | j                  t        j                  «      st        | «      r(t	        | «      }|j
                  st        d| › d�«      ‚|S | j                  dd«      }t        |«      dk  s
|d   r|d   st        d| › d�«      ‚|d   › d|d   › �}dj                  |dd	 «      }t        d
||¬«      S )a  Parse a bucket path into a HfUri.

    Accepts:
    - `hf://buckets/namespace/name(/path/in/repo)` URIs,
    - Hugging Face web URLs such as `https://huggingface.co/buckets/namespace/name(/tree/path)`,
    - plain `namespace/name(/path/in/repo)` paths.
    zInvalid bucket path: z*. Must be a bucket URI (hf://buckets/...).re   é   r   r   zInvalid bucket path: 'z)'. Expected format: namespace/bucket_nameNÚbucket)rt   r   rl   )ri   r   ÚHF_PROTOCOLr   r   Ú	is_bucketrm   rn   rj   Újoinr   )rJ   rp   Úpartsrb   Úprefixs        r-   rk   rk   ú   sÄ   € ð ‡�”y×,Ñ,Ô-Ô1CÀDÔ1Iä˜dÓ#ˆØ×ÒÜÐ4°T°FÐ:dÐeÓfÐfØˆØ�J‰J�s˜AÓ€EÜ
ˆ5ƒz�A‚~˜U 1šX¨U°1ªXÜÐ1°$°Ð7`ÐaÓbÐbØ˜‘8�*˜A˜e A™h˜ZÐ(€IØ�X‰X�e˜A˜B�iÓ €FÜ�h 9¸6ÔBÐBr/   c                 ól   — | j                  t        j                  «      syt        | «      j                  S )z›Check if a path is a bucket path.

    Do not raise if the path is not a hf:// URI.
    Raise if the path is a hf:// URI but with an incorrect format.
    F)ri   r   r€   r   r�   )rJ   s    r-   Ú_is_bucket_pathr†     s*   € ð �?‰?œ9×0Ñ0Ô1ØÜ˜Ó×'Ñ'Ð'r/   c                   óŠ   — e Zd ZU dZed   ed<   eed<   dZedz  ed<   dZ	eed<   dZ
edz  ed	<   dZedz  ed
<   dZedz  ed<   y)ÚSyncOperationz,Represents a sync operation to be performed.)ÚuploadÚdownloadÚdeleteÚskipÚactionrJ   Nr"   r_   ÚreasonÚlocal_mtimeÚremote_mtimeÚbucket_file)r0   r1   r2   r3   r   r5   r4   r"   r7   rŽ   r�   r�   r‘   rr   r'   r/   r-   rˆ   rˆ      sY   … á6àÐ:Ñ;Ó;Ø
ƒIØ€Dˆ#�‰*ÓØ€FˆCÓØ"€K��t‘Ó"Ø#€L�#˜‘*Ó#Ø%)€K�˜dÑ"Ô)r/   rˆ   c                   ón   — e Zd ZU dZeed<   eed<   eed<    ee¬«      Zee	   ed<   de
eeez  f   fd„Zy	)
ÚSyncPlanz Represents a complete sync plan.r:   ÚdestÚ	timestamp)Údefault_factoryÚ
operationsrP   c                 ó*  — t        d„ | j                  D «       «      }t        d„ | j                  D «       «      }t        d„ | j                  D «       «      }t        d„ | j                  D «       «      }t        d„ | j                  D «       «      }|||||dœS )Nc              3   ó@   K  — | ]  }|j                   d k(  sŒd–— Œ y­w)r‰   r   N©r�   ©Ú.0Úops     r-   ú	<genexpr>z#SyncPlan.summary.<locals>.<genexpr>7  ó   è ø€ ÒK˜B°R·Y±YÀ(Ó5J”aÑKùó   ‚—c              3   ó@   K  — | ]  }|j                   d k(  sŒd–— Œ y­w)rŠ   r   Nrš   r›   s     r-   rž   z#SyncPlan.summary.<locals>.<genexpr>8  s   è ø€ ÒO˜b°r·y±yÀJÓ7NœÑOùr    c              3   ó@   K  — | ]  }|j                   d k(  sŒd–— Œ y­w)r‹   r   Nrš   r›   s     r-   rž   z#SyncPlan.summary.<locals>.<genexpr>9  rŸ   r    c              3   ó@   K  — | ]  }|j                   d k(  sŒd–— Œ y­w)rŒ   r   Nrš   r›   s     r-   rž   z#SyncPlan.summary.<locals>.<genexpr>:  s   è ø€ ÒG˜"°2·9±9ÀÓ3F”AÑGùr    c              3   óZ   K  — | ]#  }|j                   d v sŒ|j                  xs d–— Œ% y­w)©r‰   rŠ   r   N)r�   r"   r›   s     r-   rž   z#SyncPlan.summary.<locals>.<genexpr>;  s&   è ø€ Òg¨"À2Ç9Á9ÐPfÒCf˜Ÿ™š A›Ñgùs   ‚+–+)ÚuploadsÚ	downloadsÚdeletesÚskipsÚ
total_size)Úsumr—   )r+   r¦   r§   r¨   r©   rª   s         r-   ÚsummaryzSyncPlan.summary6  s   € ÜÑK $§/¡/ÔKÓKˆÜÑO D§O¡OÔOÓOˆ	ÜÑK $§/¡/ÔKÓKˆÜÑG §¡ÔGÓGˆÜÑg°·±ÔgÓgˆ
àØ"ØØØ$ñ
ð 	
r/   N)r0   r1   r2   r3   r4   r5   r   Úlistr—   rˆ   Údictr7   r¬   r'   r/   r-   r“   r“   -  sA   … á*àƒKØ
ƒIØƒNÙ&+¸DÔ&A€J��]Ñ#ÓAð
˜˜c 3¨¡9˜nÑ-ô 
r/   r“   c            
       ój   — e Zd ZdZ	 	 	 d
dee   dz  dee   dz  deeeef      dz  fd„Zdedefd	„Z	y)ÚFilterMatcherz÷Matches file paths against include/exclude patterns.

    Matching is case-sensitive on every platform, like bucket paths. Backslashes in patterns are treated as path
    separators, since bucket paths and local relative paths always use `/`.
    NÚinclude_patternsÚexclude_patternsÚfilter_rulesc                 óþ   — |xs g D �cg c]  }t        |«      ‘Œ c}| _        |xs g D �cg c]  }t        |«      ‘Œ c}| _        |xs g D ��cg c]  \  }}|t        |«      f‘Œ c}}| _        yc c}w c c}w c c}}w )a  Initialize the filter matcher.

        Args:
            include_patterns: Patterns to include (from --include)
            exclude_patterns: Patterns to exclude (from --exclude)
            filter_rules: Rules from filter file as list of ("+"/"-", pattern) tuples
        N)r   r±   r²   r³   )r+   r±   r²   r³   ÚpÚsigns         r-   r.   zFilterMatcher.__init__Q  sx   € ð DTÒCYÐWYÖ Z¸aÔ!6°qÕ!9Ò ZˆÔØCSÒCYÐWYÖ Z¸aÔ!6°qÕ!9Ò ZˆÔØMYÒM_Ð]_×`Á'À$È˜dÔ$9¸!Ó$<Ò=Ó`ˆÕùò ![ùÚ ZùÛ`s   ‰A/«A4ÁA9rJ   rP   c                 ó$  — | j                   D ]"  \  }}t        j                  ||«      sŒ|dk(  c S  | j                  D ]  }t        j                  ||«      sŒ y | j                  D ]  }t        j                  ||«      sŒ y | j                  ryy)zþCheck if a path should be included based on the filter rules.

        Filtering rules:
        - Filters are evaluated in order, first matching rule decides
        - If no rules match, include by default (unless include patterns are specified)
        ú+FT)r³   ÚfnmatchÚfnmatchcaser²   r±   )r+   rJ   r¶   Úpatterns       r-   ÚmatcheszFilterMatcher.matchesb  sž   € ð "×.Ñ.ò 	#‰MˆD�'Ü×"Ñ" 4¨Õ1Ø˜s‘{Ò"ð	#ð
 ×,Ñ,ò 	ˆGÜ×"Ñ" 4¨Õ1Ùð	ð ×,Ñ,ò 	ˆGÜ×"Ñ" 4¨Õ1Ùð	ð
 × Ò Øð r/   )NNN)
r0   r1   r2   r3   r­   r4   Útupler.   r6   r¼   r'   r/   r-   r°   r°   J  sn   „ ñð .2Ø-1Ø59ñ	aà˜s™) dÑ*ðað ˜s™) dÑ*ðað ˜5  c ™?Ñ+¨dÑ2ó	að"˜Cð  Dô r/   r°   Úfilter_filec                 ó¢  — g }t        | «      5 }|D ]¥  }|j                  «       }|r|j                  d«      rŒ'|j                  d«      r%|j                  d|dd j                  «       f«       Œ]|j                  d«      r%|j                  d|dd j                  «       f«       Œ“|j                  d|f«       Œ§ 	 ddd«       |S # 1 sw Y   |S xY w)zþParse a filter file and return a list of (sign, pattern) tuples.

    Filter file format:
    - Lines starting with "+" are include patterns
    - Lines starting with "-" are exclude patterns
    - Empty lines and lines starting with "#" are ignored
    ú#r¸   r   Nú-)Úopenrh   ri   Úappend)r¾   ÚrulesÚfÚlines       r-   Ú_parse_filter_filerÇ     sÂ   € ð €EÜ	ˆkÓ	ð *˜aØò 
	*ˆDØ—:‘:“<ˆDÙ˜4Ÿ?™?¨3Ô/ØØ�‰˜sÔ#Ø—‘˜c 4¨¨ 8§>¡>Ó#3Ð4Õ5Ø—‘ Ô%Ø—‘˜c 4¨¨ 8§>¡>Ó#3Ð4Õ5ð —‘˜c 4˜[Õ)ñ
	*÷*ð €L÷*ð €Lús   ŽB+CÃCc                 óÂ   — 	 t        j                  | «      }t        j                  |j                  «      ry|j
                  |j                  dz  fS # t        $ r Y yw xY w)zÇStat a local file and return (size, mtime_ms).

    Returns None if the path is missing or is a directory. Uses a single
    ``os.stat`` call so callers don't pay for multiple syscalls per file.
    Nr   )rI   ÚstatÚOSErrorÚS_ISDIRÚst_modeÚst_sizeÚst_mtime)rJ   Ústs     r-   Ú_stat_localrÐ   œ  sU   € ðÜ�W‰W�T‹]ˆô ‡|�|�B—J‘JÔØØ�:‰:�r—{‘{ TÑ)Ð)Ð)øô	 ò Ùðús   ‚A Á	AÁAÚ
local_pathc              #   óä  K  — t         j                  j                  | «      } t         j                  j                  | «      st	        d| › �«      ‚t        j
                  | «      D ]ˆ  \  }}}|D ]}  }t         j                  j                  ||«      }t        |«      }|€Œ1t         j                  j                  || «      }|j                  t         j                  d«      }||d   |d   f–— Œ ŒŠ y­w)zsList all files in a local directory.

    Yields:
        tuple: (relative_path, size, mtime_ms) for each file
    z Local path must be a directory: Nre   r   r   )rI   rJ   ÚabspathÚisdirrm   Úwalkr‚   rÐ   Úrelpathrg   Úsep)rÑ   ÚrootÚ_ÚfilesÚfilenameÚ	full_pathÚ	stat_infoÚrel_paths           r-   Ú_list_local_filesrß   «  sÐ   è ø€ ô —‘—‘ Ó,€JÜ�7‰7�=‰=˜Ô$ÜÐ;¸J¸<ÐHÓIÐIäŸ'™' *Ó-ò 	7‰ˆˆa�Øò 	7ˆHÜŸ™Ÿ™ T¨8Ó4ˆIÜ# IÓ.ˆIØÐ ØÜ—w‘w—‘ y°*Ó=ˆHà×'Ñ'¬¯©°Ó4ˆHØ˜I a™L¨)°A©,Ð6Ó6ñ	7ñ	7ùs   ‚C.C0Úapir   rb   r„   c              #   ó¨  K  — | j                  ||xs dd¬«      D ]³  }t        |t        «      rŒ|j                  }|rH|j	                  |dz   «      r|t        |«      dz   d }n$||k(  rd|v r|j                  dd«      d   n|}nŒj|}t        |«       |j                  r|j                  j                  «       dz  nd}||j                  ||f–— Œµ y­w)	zÔList all files in a bucket with a given prefix.

    Yields:
        tuple: (relative_path, size, mtime_ms, bucket_file) for each file.
            bucket_file is the BucketFile object from list_bucket_tree.
    NT)r„   Ú	recursivere   r   éÿÿÿÿr   r   )Úlist_bucket_treerE   rz   rJ   ri   rj   Úrsplitr   rA   r•   r"   )rà   rb   r„   ÚitemrJ   rÞ   Úmtime_mss          r-   Ú_list_remote_filesrè   Á  sÖ   è ø€ ð ×$Ñ$ Y°v²~ÀÐQUÐ$ÓVò 2ˆÜ�dœLÔ)ØØ�y‰yˆñ Ø�‰˜v¨™|Ô,Ø¤ F£¨a¡Ð 1Ð2‘Ø˜’à69¸T±k˜4Ÿ;™; s¨AÓ.¨rÒ2Àt‘ð àˆHä# HÔ-Ø48·J²J�4—:‘:×'Ñ'Ó)¨DÒ0ÀAˆØ˜Ÿ	™	 8¨TÐ1Ó1ñ+2ùs   ‚CCrç   c                 ón   — t        j                  | dz  t        j                  ¬«      j	                  «       S )z3Convert mtime in milliseconds to ISO format string.r   )Útz)r   Úfromtimestampr   ÚutcÚ	isoformat)rç   s    r-   Ú_mtime_to_isorî   å  s&   € ä×!Ñ! (¨T¡/´h·l±lÔC×MÑMÓOÐOr/   )r‘   r�   r¥   Úsource_sizeÚsource_mtimeÚ	dest_sizeÚ
dest_mtimeÚsource_newer_labelÚdest_newer_labelÚignore_sizesÚignore_timesÚignore_existingr‘   c                 ó�  — t        |dk(  r|n|«      }t        |dk(  r|n|«      }| |||dœ}|
rt        ddddœ|¤ŽS ||k7  }||z
  t        kD  }|r1|rt        d|||dœ|¤ŽS ||z
  t        kD  }|r|nd}t        dd|dœ|¤ŽS |	r|rt        d|d|dœ|¤ŽS t        ddd	dœ|¤ŽS |s|r|rdn|}t        d|||dœ|¤ŽS t        ddd
dœ|¤ŽS )a—  Compare source and dest files and return the appropriate sync operation.

    This is a unified helper for both upload and download directions.

    Args:
        path: Relative file path
        action: "upload" or "download"
        source_size: Size of the source file (bytes)
        source_mtime: Mtime of the source file (milliseconds)
        dest_size: Size of the destination file (bytes)
        dest_mtime: Mtime of the destination file (milliseconds)
        source_newer_label: Label when source is newer (e.g., "local newer" or "remote newer")
        dest_newer_label: Label when dest is newer (e.g., "remote newer" or "local newer")
        ignore_sizes: Only compare mtime
        ignore_times: Only compare size
        ignore_existing: Skip files that exist on receiver
        bucket_file: BucketFile object (for downloads only)

    Returns:
        SyncOperation describing the action to take
    r‰   )rJ   r"   r�   r�   rŒ   z&exists on receiver (--ignore-existing))r�   rŽ   )r�   rŽ   r‘   z
same mtimezsize differsz	same sizeÚ	identicalr'   )rî   rˆ   Ú_SYNC_TIME_WINDOW_MS)rJ   r�   rï   rð   rñ   rò   ró   rô   rõ   rö   r÷   r‘   Úlocal_mtime_isoÚremote_mtime_isoÚbase_kwargsÚsize_differsÚsource_newerÚ
dest_newerÚskip_reasonrŽ   s                       r-   Ú_compare_files_for_syncr  ê  s6  € ôH $°F¸hÒ4F¡LÈJÓW€OÜ$°6¸XÒ3E¡ZÈ<ÓXÐð ØØ&Ø(ñ	#€Kñ ÜÐk FÐ3[ÑkÐ_jÑkÐkà )Ñ+€LØ  :Ñ-Ô1EÑE€LáÙÜ Ðr¨Ð7IÐWbÑrÐfqÑrÐrà$ |Ñ3Ô7KÑKˆJÙ.8Ñ*¸lˆKÜ ÐR¨°{ÑRÀkÑRÐRÙ	ÙÜ Ðn¨°~ÐS^ÑnÐbmÑnÐnä ÐR¨°{ÑRÀkÑRÐRá™<Ù'3‘^Ð9KˆFÜ Ðf¨°vÈ;ÑfÐZeÑfÐfä ÐR¨°{ÑRÀkÑRÐRr/   Fr:   r”   r‹   ÚexistingÚfilter_matcherÚstatusc
                 ó�  — |xs
 t        «       }t        | «       xr t        |«      }
t        | «      xr t        |«       }|
s|st        d«      ‚t        | |t	        j
                  t        j                  «      j                  «       ¬«      }d}|
�rût        j                  j                  | «      }t        |«      }|j                  |j                  }}t        j                  j                  |«      st        d|› �«      ‚i }t!        |«      D ]?  \  }}}|j#                  |«      r||f||<   |	sŒ"|	j%                  dt'        |«      › d�«       ŒA |	r|	j)                  dt'        |«      › d�«       i }|	r	 |j+                  |«      j,                  }	 t1        |||«      D ]K  \  }}}}|j#                  |«      r||f||<   |	sŒ#|�d|› �nd}|	j%                  d	t'        |«      › |› d�«       ŒM 	 |	r|	j)                  d	t'        |«      › d�«       t9        |j;                  «       «      t9        |j;                  «       «      z  }|	r|	j)                  dt'        |«      › d�«       t=        |«      D �]  }|j?                  |«      }|j?                  |«      }|rv|st|r9|j@                  jC                  tE        d||d   dtG        |d   «      ¬«      «       Œe|j@                  jC                  tE        d||d   dtG        |d   «      ¬«      «       Œž|r<|r:|\  }}|\  }} |j@                  jC                  tI        |d|||| dd|||¬«      «       ŒÜ|rŒß|sŒâ|sŒå|j@                  jC                  tE        d||d   dtG        |d   «      ¬«      «       �Œ |S t        | «      }|j                  |j                  }}t        j                  j                  |«      }i }i }!|	r	 |j+                  |«      j,                  }t1        |||«      D ]P  \  }}}}"|j#                  |«      r||f||<   |"|!|<   |	sŒ(|�d|› �nd}|	j%                  d	t'        |«      › |› d�«       ŒR |	r|	j)                  d	t'        |«      › d�«       i }t        j                  j                  |«      r«|rNt!        |«      D ]?  \  }}}|j#                  |«      r||f||<   |	sŒ"|	j%                  dt'        |«      › d�«       ŒA n[|D ]V  }t        j                  jK                  ||«      }#tM        |#«      }$|$€Œ1|$||<   |	sŒ9|	j%                  dt'        |«      › d�«       ŒX |	r|	j)                  dt'        |«      › d�«       t9        |j;                  «       «      t9        |j;                  «       «      z  }|	r|	j)                  dt'        |«      › d�«       t=        |«      D �]>  }|j?                  |«      }|j?                  |«      }|r†|s„|r9|j@                  jC                  tE        d||d   dtG        |d   «      ¬«      «       Œe|j@                  jC                  tE        d||d   dtG        |d   «      |!j?                  |«      ¬«      «       Œ®|rL|rJ|\  }} |\  }}|j@                  jC                  tI        |d|| ||dd||||!j?                  |«      ¬«      «       Œü|rŒÿ|s�Œ|s�Œ|j@                  jC                  tE        d||d   dtG        |d   «      ¬«      «       �ŒA |S # t.        $ r Y �Œ{w xY w# t2        $ r t4        j7                  d
|› d�«       Y �ŒGw xY w# t.        $ r Y �ŒSw xY w)z‚Compute the sync plan by comparing source and destination.

    Returns:
        SyncPlan with all operations to be performed
    z[One of source or dest must be a bucket path (hf://buckets/...) and the other must be local.©r:   r”   r•   NzSource must be a directory: zScanning local directory (z files)re   r_   zScanning remote bucket (zBucket 'z' not found, treating as empty.zComparing files (z paths)rŒ   r   znew file (--existing)r   )r�   rJ   r"   rŽ   r�   r‰   znew filezlocal newerzremote newer)rJ   r�   rï   rð   rñ   rò   ró   rô   rõ   rö   r÷   r‹   znot in source (--delete))r�   rJ   r"   rŽ   r�   rŠ   )r�   rJ   r"   rŽ   r�   r‘   )rJ   r�   rï   rð   rñ   rò   ró   rô   rõ   rö   r÷   r‘   )'r°   r†   rm   r“   r   Únowr   rì   rí   rI   rJ   rÓ   rk   r   rl   rÔ   rß   r¼   r*   rj   ÚdoneÚbucket_infor#   Ú	Exceptionrè   r   ÚloggerÚdebugÚsetÚkeysÚsortedÚgetr—   rÃ   rˆ   rî   r  r‚   rÐ   )%r:   r”   rà   r‹   rö   rõ   r  r÷   r  r  Ú	is_uploadÚis_downloadÚplanÚremote_totalrÑ   rp   rb   r„   Úlocal_filesrÞ   r"   rç   Úremote_filesrÙ   Ú	total_strÚ	all_pathsrJ   Ú
local_infoÚremote_infoÚ
local_sizer�   Úremote_sizer�   Úbucket_file_mapr‘   Ú
local_filerÝ   s%                                        r-   Ú_compute_sync_planr   2  s”  € ð" $Ò6¤}£€NÜ# FÓ+Ð+ÒE´ÀÓ0E€IÜ! &Ó)ÒG´/À$Ó2GÐ.G€Ká™[ÜÐvÓwÐwäØØÜ—,‘,œxŸ|™|Ó,×6Ñ6Ó8ô€Dð  $€LÚä—W‘W—_‘_ VÓ,ˆ
Ü" 4Ó(ˆØ"ŸI™I v×':Ñ':�6ˆ	ä�w‰w�}‰}˜ZÔ(ÜÐ;¸J¸<ÐHÓIÐIð ˆÜ(9¸*Ó(Eò 	VÑ$ˆH�d˜HØ×%Ñ% hÔ/Ø)-¨xÐ(8�˜HÑ%ÚØ—‘Ð :¼3¸{Ó;KÐ:LÈGÐTÕUð		Vñ
 Ø�K‰KÐ4´S¸Ó5EÐ4FÀgÐNÔOàˆÙðØ"Ÿ™¨yÓ9×EÑE�ð		PÜ/AÀ#ÀyÐRXÓ/Yò dÑ+�˜$ ¨!Ø!×)Ñ)¨(Ô3Ø.2°HÐ-=�L Ñ*ÚØ6BÐ6N ! L >Ñ 2ÐTV�IØ—M‘MÐ$<¼SÀÓ=NÐ<OÐPYÈ{ÐZaÐ"bÕcñdñ Ø�K‰KÐ2´3°|Ó3DÐ2EÀWÐMÔNô ˜×(Ñ(Ó*Ó+¬c°,×2CÑ2CÓ2EÓ.FÑFˆ	ÙØ�K‰KÐ+¬C°	«NÐ+;¸7ÐCÔDÜ˜9Ó%ó 8	ˆDØ$Ÿ™¨Ó.ˆJØ&×*Ñ*¨4Ó0ˆKá¡+áà—O‘O×*Ñ*Ü%Ø#)Ø!%Ø!+¨A¡Ø#:Ü(5°jÀ±mÓ(Dôõð —O‘O×*Ñ*Ü%Ø#+Ø!%Ø!+¨A¡Ø#-Ü(5°jÀ±mÓ(Dôõñ ¡à*4Ñ'�
˜KØ,7Ñ)�˜\Ø—‘×&Ñ&Ü+Ø!Ø'Ø$.Ø%0Ø"-Ø#/Ø+8Ø)7Ø%1Ø%1Ø(7ôõò  ¢K²Fà—‘×&Ñ&Ü!Ø'Ø!Ø(¨™^Ø9Ü%2°;¸q±>Ó%Bôöða8	ðV €Kô_ # 6Ó*ˆØ"ŸI™I v×':Ñ':�6ˆ	Ü—W‘W—_‘_ TÓ*ˆ
ð ˆØ*,ˆÙðØ"Ÿ™¨yÓ9×EÑE�ô 6HÈÈYÐX^Ó5_ò 	`Ñ1ˆH�d˜H kØ×%Ñ% hÔ/Ø*.°Ð)9�˜XÑ&Ø,7� Ñ)ÚØ2>Ð2J˜a ˜~Ñ.ÐPR�	Ø—‘Ð 8¼¸\Ó9JÐ8KÈIÈ;ÐV]Ð^Õ_ð	`ñ Ø�K‰KÐ2´3°|Ó3DÐ2EÀWÐMÔNàˆÜ�7‰7�=‰=˜Ô$Ùä0AÀ*Ó0Mò ^Ñ,�H˜d HØ%×-Ñ-¨hÔ7Ø15°xÐ0@˜ HÑ-ÚØŸ™Ð(BÄ3À{ÓCSÐBTÐT[Ð&\Õ]ñ	^ð !-ò ^�HÜ!#§¡§¡¨j¸(Ó!C�JÜ +¨JÓ 7�IØ Ð(Ø Ø,5�K Ñ)ÚØŸ™Ð(BÄ3À{ÓCSÐBTÐT[Ð&\Õ]ð^ñ Ø�K‰KÐ4´S¸Ó5EÐ4FÀgÐNÔOô ˜×)Ñ)Ó+Ó,¬s°;×3CÑ3CÓ3EÓ/FÑFˆ	ÙØ�K‰KÐ+¬C°	«NÐ+;¸7ÐCÔDÜ˜9Ó%ó :	ˆDØ&×*Ñ*¨4Ó0ˆKØ$Ÿ™¨Ó.ˆJá¡:áà—O‘O×*Ñ*Ü%Ø#)Ø!%Ø!,¨Q¡Ø#:Ü)6°{À1±~Ó)Fôõð —O‘O×*Ñ*Ü%Ø#-Ø!%Ø!,¨Q¡Ø#-Ü)6°{À1±~Ó)FØ(7×(;Ñ(;¸DÓ(Aôõ	ñ ¡à,7Ñ)�˜\Ø*4Ñ'�
˜KØ—‘×&Ñ&Ü+Ø!Ø)Ø$/Ø%1Ø",Ø#.Ø+9Ø)6Ø%1Ø%1Ø(7Ø$3×$7Ñ$7¸Ó$=ôõò  !£Z³Fà—‘×&Ñ&Ü!Ø'Ø!Ø'¨™]Ø9Ü$1°*¸Q±-Ó$@ôöðe:	ðx €Køô} ò Úðûô #ò 	Pä�L‰L˜8 I ;Ð.MÐN×Oð	Pûô` ò Úðús<   Å5[? Æ/\ Ç+\ Ï\8 Û?	\Ü\Ü"\5Ü4\5Ü8	]Ý]r  c                 ó  — d| j                   | j                  | j                  | j                  «       dœ}|j	                  t        j                  |«      dz   «       | j                  D ]Ÿ  }d|j                  |j                  |j                  dœ}|j                  �|j                  |d<   |j                  �|j                  |d<   |j                  �|j                  |d	<   |j	                  t        j                  |«      dz   «       Œ¡ y)
z1Write a sync plan as JSONL to a file-like object.Úheader)rt   r:   r”   r•   r¬   ú
Ú	operation)rt   r�   rJ   rŽ   Nr"   r�   r�   )r:   r”   r•   r¬   ÚwriteÚjsonÚdumpsr—   r�   rJ   rŽ   r"   r�   r�   )r  rÅ   r"  r�   Úop_dicts        r-   Ú_write_planr)  .  sß   € ð Ø—+‘+Ø—	‘	Ø—^‘^Ø—<‘<“>ñ€Fð ‡G�GŒD�J‰J�vÓ Ñ%Ô&ð �o‰oò ,ˆàØ—i‘iØ—G‘GØ—i‘iñ	#
ˆð �7‰7ÐØ Ÿg™gˆG�F‰OØ�>‰>Ð%Ø%'§^¡^ˆG�MÑ"Ø�?‰?Ð&Ø&(§o¡oˆG�NÑ#Ø	�‰”—
‘
˜7Ó# dÑ*Õ+ñ,r/   Ú	plan_filec                 ó^   — t        |d«      5 }t        | |«       ddd«       y# 1 sw Y   yxY w)z!Save a sync plan to a JSONL file.ÚwN)rÂ   r)  )r  r*  rÅ   s      r-   Ú
_save_planr-  K  s-   € ä	ˆi˜Ó	ð  Ü�D˜!Ô÷÷ ñ ús   �#£,c                 óf  — t        | «      5 }|j                  «       }ddd«       st        d| › �«      ‚t        j                  |d   «      }|j                  d«      dk7  rt        d«      ‚t        |d   |d   |d	   ¬
«      }|dd D ]™  }t        j                  |«      }|j                  d«      dk7  rŒ-|j                  j                  t        |d   |d   |j                  d«      |j                  dd«      |j                  d«      |j                  d«      ¬«      «       Œ› |S # 1 sw Y   �ŒxY w)z#Load a sync plan from a JSONL file.NzEmpty plan file: r   rt   r"  z0Invalid plan file: expected header as first liner:   r”   r•   r  r   r$  r�   rJ   r"   rŽ   r_   r�   r�   )r�   rJ   r"   rŽ   r�   r�   )
rÂ   Ú	readlinesrm   r&  Úloadsr  r“   r—   rÃ   rˆ   )r*  rÅ   Úlinesr"  r  rÆ   r(  s          r-   Ú
_load_planr2  Q  s1  € ä	ˆi‹ð ˜AØ—‘“ˆ÷ñ ÜÐ,¨Y¨KÐ8Ó9Ð9ô �Z‰Z˜˜a™Ó!€FØ‡z�z�&Ó˜XÒ%ÜÐKÓLÐLäØ�hÑØ�F‰^Ø˜Ñ%ô€Dð �a�b�	ò 
ˆÜ—*‘*˜TÓ"ˆØ�;‰;�vÓ +Ò-ØØ�‰×ÑÜØ˜xÑ(Ø˜V‘_Ø—[‘[ Ó(Ø—{‘{ 8¨RÓ0Ø#ŸK™K¨Ó6Ø$Ÿ[™[¨Ó8ôõ		
ð	
ð €K÷Cñ ús   ŒD&Ä&D0Úverbosec                 óÀ  — t        | j                  «       xr t        | j                  «      }t        | j                  «      xr t        | j                  «       }| j                  D ]  }t	        |j
                  «       Œ |�r%t        j
                  j                  | j                  «      }t        | j                  «      }|j                  |j                  }
}	g }g }| j                  D �]'  }|j                  xdk(  r† t        j
                  j                  ||j
                  «      }|
r|
› d|j
                  › �n|j
                  }|r&t        d|j
                  › d|j                  › d�«       |j                  ||f«       Œšxdk(  rZ |
r|
› d|j
                  › �n|j
                  }|r&t        d|j
                  › d|j                  › d�«       |j                  |«       Œùdk(  sŒþ|s�Œt        d	|j
                  › d|j                  › d�«       �Œ* |s|r�|rpg }|r|j                  d
t!        |«      › d�«       |r|j                  dt!        |«      › d�«       |j#                  dj                  |«      j%                  «       «       |j'                  |	|xs d|xs d¬«       yy|�r$t        | j                  «      }|j                  |j                  }
}	t        j
                  j                  | j                  «      }t        j(                  |d¬«       g }g }| j                  D �]¤  }|j                  dk(  rãt        j
                  j                  ||j
                  «      }t        j(                  t        j
                  j+                  |«      d¬«       |r&t        d|j
                  › d|j                  › d�«       |j,                  �|j                  |j,                  |f«       ŒÃ|
r|
› d|j
                  › �n|j
                  }|j                  ||f«       Œö|j                  dk(  ret        j
                  j                  ||j
                  «      }|r&t        d|j
                  › d|j                  › d�«       |j                  |«       �Œj|j                  dk(  s�Œ{|s�Œt        d	|j
                  › d|j                  › d�«       �Œ§ t!        |«      dkD  r2|r|j#                  dt!        |«      › d�«       |j/                  |	|«       |r |r|j#                  dt!        |«      › d�«       |D ]—  }t        j
                  j1                  |«      sŒ#t        j2                  |«       t        j
                  j+                  |«      }||k7  sŒ]	 t        j4                  |«       t        j
                  j+                  |«      }||k7  rŒ;Œ™ yy# t6        $ r Y Œ§w xY w)zExecute a sync plan.r‰   re   z  Uploading: z (ú)r‹   z  Deleting: rŒ   z  Skipping: z
uploading z filesz	deleting z, N)Úaddr‹   T)Úexist_okrŠ   z  Downloading: r   zDownloading z	Deleting z local files)r†   r:   r”   r—   r   rJ   rI   rÓ   rk   r   rl   r�   r‚   ÚprintrŽ   rÃ   rj   r	  Ú
capitalizeÚbatch_bucket_filesÚmakedirsÚdirnamer‘   Údownload_bucket_filesÚexistsÚremoveÚrmdirrÊ   )r  rà   r3  r  r  r  r�   rÑ   rp   rb   r„   Ú	add_filesÚdelete_pathsr  Úremote_pathrƒ   Údownload_filesÚdelete_filesÚ	file_pathÚparents                       r-   Ú_execute_planrH  |  sÂ  € ä# D§K¡KÓ0Ð0ÒO´_ÀTÇYÁYÓ5O€IÜ! $§+¡+Ó.ÒQ´ÀtÇyÁyÓ7QÐ3Q€Kð �o‰oò -ˆÜ# B§G¡GÕ,ð-ò Ü—W‘W—_‘_ T§[¡[Ó1ˆ
Ü" 4§9¡9Ó-ˆØ"ŸI™I v×':Ñ':�6ˆ	ð ;=ˆ	Ø"$ˆà—/‘/ó 	BˆBØ—)‘)ÝÜ!#§¡§¡¨j¸"¿'¹'Ó!B�JÙ;A V H¨A¨b¯g©g¨YÑ"7ÀrÇwÁw�KÙÜ ¨b¯g©g¨Y°b¸¿¹¸À1ÐEÔFØ×$Ñ$ j°+Ð%>Õ?ÝÙ;A V H¨A¨b¯g©g¨YÑ"7ÀrÇwÁw�KÙÜ ¨R¯W©W¨I°R¸¿	¹	°{À!ÐDÔEØ ×'Ñ'¨Õ4Ü›wÜ˜L¨¯©¨	°°B·I±I°;¸aÐ@ÖAð	Bñ" ™ÙØ�ÙØ—L‘L :¬c°)«nÐ-=¸VÐ!DÔEÙØ—L‘L 9¬S°Ó->Ð,?¸vÐ!FÔGØ—‘˜DŸI™I eÓ,×7Ñ7Ó9Ô:Ø×"Ñ"ØØÒ% Ø#Ò+ tð #õ ð %ò 
Ü" 4§;¡;Ó/ˆØ"ŸI™I v×':Ñ':�6ˆ	Ü—W‘W—_‘_ T§Y¡YÓ/ˆ
ô 	�‰�J¨Õ.ð EGˆØ"$ˆà—/‘/ó 	>ˆBØ�y‰y˜JÒ&ÜŸW™WŸ\™\¨*°b·g±gÓ>�
ä—‘œBŸG™GŸO™O¨JÓ7À$ÕGÙÜ˜O¨B¯G©G¨9°B°r·y±y°kÀÐCÔDà—>‘>Ð-Ø"×)Ñ)¨2¯>©>¸:Ð*FÕGá;A V H¨A¨b¯g©g¨YÑ"7ÀrÇwÁw�KØ"×)Ñ)¨;¸
Ð*CÕDØ—‘˜hÒ&ÜŸW™WŸ\™\¨*°b·g±gÓ>�
ÙÜ˜L¨¯©¨	°°B·I±I°;¸aÐ@ÔAØ×#Ñ# JÖ/Ø—‘˜fÔ$«Ü˜ R§W¡W I¨R°·	±	¨{¸!Ð<Ö=ð'	>ô, ˆ~Ó Ò"ÙØ—‘˜l¬3¨~Ó+>Ð*?¸vÐFÔGØ×%Ñ% i°Ô@ñ ‘lØ�K‰K˜)¤C¨Ó$5Ð#6°lÐCÔDØ%ò 
	ˆIÜ�w‰w�~‰~˜iÕ(Ü—	‘	˜)Ô$äŸ™Ÿ™¨Ó3�Ø 
Ó*ðÜŸ™ Ô(Ü!#§¡§¡°Ó!8˜ð  
Ô*ñ
	ðU 
øôf #ò Ùðús   Ö4W×	W×Wc                 óö   — | j                  «       }t        d| j                  › d| j                  › �«       t        d|d   › �«       t        d|d   › �«       t        d|d   › �«       t        d	|d
   › �«       y)z!Print a summary of the sync plan.zSync plan: z -> z  Uploads: r¦   z  Downloads: r§   z  Deletes: r¨   z	  Skips: r©   N)r¬   r8  r:   r”   )r  r¬   s     r-   Ú_print_plan_summaryrJ  ä  s~   € à�l‰l‹n€GÜ	ˆK˜Ÿ™�} D¨¯©¨Ð
4Ô5Ü	ˆK˜ 	Ñ*Ð+Ð
,Ô-Ü	ˆM˜' +Ñ.Ð/Ð
0Ô1Ü	ˆK˜ 	Ñ*Ð+Ð
,Ô-Ü	ˆI�g˜gÑ&Ð'Ð
(Õ)r/   )r‹   rö   rõ   r  r÷   ÚincludeÚexcludeÚfilter_fromr  ÚapplyÚdry_runr3  ÚquietÚtokenrK  rL  rM  rN  rO  rP  rQ  c                óÒ  — |�Fddl m}  ||j                  ||j                  |j                  |j
                  |j                  ¬«      }|rù| s|rt        d«      ‚|�t        d«      ‚|rt        d«      ‚|rt        d«      ‚|rt        d	«      ‚|rt        d
«      ‚|	rt        d«      ‚|
rt        d«      ‚|rt        d«      ‚|rt        d«      ‚|rt        d«      ‚t        |«      }t        | ¬«      }|st        |«       t        d«       |r
t        «        	 t        ||||¬«       |rt        «        	 |st        d«       |S | r|st        d«      ‚t        | «      }t        |«      }|r|rt        d«      ‚|s|st        d«      ‚|r|rt        d«      ‚|r|rt        d«      ‚|r|rt        d«      ‚|rLt         j"                  j%                  |«      rZt         j"                  j'                  |«      s;t        d|› �«      ‚t         j"                  j'                  | «      st        d| › �«      ‚d}|
rt)        |
«      }t+        ||	|¬«      }t        | xr | ¬«      }t-        | |||||||||¬«
      }|rt/        |t0        j2                  «       |S |r)t5        ||«       |st        |«       t        d|› �«       |S |st        |«       |j7                  «       }|d   d k(  r|d!   d k(  r|d"   d k(  r|st        d#«       |S |st        d$«       |r
t        «        	 t        ||||¬«       |rt        «        	 |st        d«       |S # |rt        «        w w xY w# |rt        «        w w xY w)%a  Sync files between a local directory and a bucket.

    This is equivalent to the ``hf buckets sync`` CLI command. One of ``source`` or ``dest`` must be a bucket path
    (``hf://buckets/...``) and the other must be a local directory path.

    Args:
        source (`str`, *optional*):
            Source path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``.
            Required unless using ``apply``.
        dest (`str`, *optional*):
            Destination path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``.
            Required unless using ``apply``.
        api ([`HfApi`]):
            The HfApi instance to use for API calls.
        delete (`bool`, *optional*, defaults to `False`):
            Delete destination files not present in source.
        ignore_times (`bool`, *optional*, defaults to `False`):
            Skip files only based on size, ignoring modification times.
        ignore_sizes (`bool`, *optional*, defaults to `False`):
            Skip files only based on modification times, ignoring sizes.
        existing (`bool`, *optional*, defaults to `False`):
            Skip creating new files on receiver (only update existing files).
        ignore_existing (`bool`, *optional*, defaults to `False`):
            Skip updating files that exist on receiver (only create new files).
        include (`list[str]`, *optional*):
            Include files matching patterns (fnmatch-style).
        exclude (`list[str]`, *optional*):
            Exclude files matching patterns (fnmatch-style).
        filter_from (`str`, *optional*):
            Path to a filter file with include/exclude rules.
        plan (`str`, *optional*):
            Save sync plan to this JSONL file instead of executing.
        apply (`str`, *optional*):
            Apply a previously saved plan file. When set, ``source`` and ``dest`` are not needed.
        dry_run (`bool`, *optional*, defaults to `False`):
            Print sync plan to stdout as JSONL without executing.
        verbose (`bool`, *optional*, defaults to `False`):
            Show detailed per-file operations.
        quiet (`bool`, *optional*, defaults to `False`):
            Suppress all output and progress bars.
        token (Union[bool, str, None], optional):
            A valid user access token. If not provided, the locally saved token will be used.

    Returns:
        [`SyncPlan`]: The computed (or loaded) sync plan.

    Raises:
        `ValueError`: If arguments are invalid (e.g., both paths are remote, conflicting options).

    Example:
        ```python
        >>> from huggingface_hub import HfApi
        >>> api = HfApi()

        # Upload local directory to bucket
        >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket")

        # Download bucket to local directory
        >>> api.sync_bucket("hf://buckets/username/my-bucket", "./data")

        # Sync with delete and filtering
        >>> api.sync_bucket(
        ...     "./data",
        ...     "hf://buckets/username/my-bucket",
        ...     delete=True,
        ...     include=["*.safetensors"],
        ... )

        # Dry run: preview what would be synced
        >>> plan = api.sync_bucket("./data", "hf://buckets/username/my-bucket", dry_run=True)
        >>> plan.summary()
        {'uploads': 3, 'downloads': 0, 'deletes': 0, 'skips': 1, 'total_size': 4096}

        # Save plan for review, then apply
        >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket", plan="sync-plan.jsonl")
        >>> api.sync_bucket(apply="sync-plan.jsonl")
        ```
    Nr   r   )r`   rQ  Úlibrary_nameÚlibrary_versionÚ
user_agentÚheadersz,Cannot specify source/dest when using apply.z#Cannot specify both plan and apply.z'Cannot specify delete when using apply.z-Cannot specify ignore_times when using apply.z-Cannot specify ignore_sizes when using apply.z(Cannot specify include when using apply.z(Cannot specify exclude when using apply.z,Cannot specify filter_from when using apply.z)Cannot specify existing when using apply.z0Cannot specify ignore_existing when using apply.z(Cannot specify dry_run when using apply.)ÚenabledzExecuting plan...)r3  r  zSync completed.z7Both source and dest are required (unless using apply).z?Remote to remote sync is not supported. One path must be local.z?One of source or dest must be a bucket path (hf://buckets/...).z2Cannot specify both ignore_times and ignore_sizes.z1Cannot specify both existing and ignore_existing.z%Cannot specify both dry_run and plan.z!Destination must be a directory: z&Source must be an existing directory: )r±   r²   r³   )
r:   r”   rà   r‹   rö   rõ   r  r÷   r  r  zPlan saved to: r¦   r   r§   r¨   zNothing to sync.z
Syncing...)Úhf_apir   r`   rS  rT  rU  rV  rm   r2  r   rJ  r8  r   rH  r   r†   rI   rJ   r>  rÔ   rÇ   r°   r   r)  ÚsysÚstdoutr-  r¬   )r:   r”   rà   r‹   rö   rõ   r  r÷   rK  rL  rM  r  rN  rO  r3  rP  rQ  r   Ú	sync_planr  Úsource_is_bucketÚdest_is_bucketr³   r  r¬   s                            r-   Úsync_bucket_internalr^  ó  s�  € ðF ÐÝ!áØ—\‘\ØØ×)Ñ)Ø×/Ñ/Ø—~‘~Ø—K‘Kô
ˆñ Ù‘TÜÐKÓLÐLØÐÜÐBÓCÐCÙÜÐFÓGÐGÙÜÐLÓMÐMÙÜÐLÓMÐMÙÜÐGÓHÐHÙÜÐGÓHÐHÙÜÐKÓLÐLÙÜÐHÓIÐIÙÜÐOÓPÐPÙÜÐGÓHÐHä˜uÓ%ˆ	Ü¨ IÔ.ˆÙÜ 	Ô*ÜÐ%Ô&áÜ!Ô#ð	'Ü˜) S°'À&ÕIáÜ$Õ&áÜÐ#Ô$àÐñ ™ÜÐRÓSÐSä& vÓ.ÐÜ$ TÓ*€Ná™NÜÐZÓ[Ð[á¡NÜÐZÓ[Ð[á™ÜÐMÓNÐNá‘OÜÐLÓMÐMá‘4ÜÐ@ÓAÐAñ Ü�7‰7�>‰>˜$Ô¬¯©¯©°dÔ(;ÜÐ@ÀÀÐGÓHÐHä�w‰w�}‰}˜VÔ$ÜÐEÀfÀXÐNÓOÐOð €LÙÜ)¨+Ó6ˆä"Ø Ø Ø!ô€Nô  E 	Ò 9°'¨kÔ:€FÜ"ØØØØØ!Ø!ØØ'Ø%Øô€Iñ Ü�IœsŸz™zÔ*ØÐáÜ�9˜dÔ#ÙÜ 	Ô*Ü�O D 6Ð*Ô+ØÐñ Ü˜IÔ&à×ÑÓ!€GØˆyÑ˜QÒ 7¨;Ñ#7¸1Ò#<ÀÈÑASÐWXÒAXÙÜÐ$Ô%ØÐáÜˆlÔáÜÔð#Ü�i ¨g¸fÕEáÜ Õ"áÜÐÔ àÐøñG Ü$Õ&ð ûñz Ü Õ"ð ús   ÄM ÌM ÍMÍM&)FFFFFNN)FN)NN)Or3   r¹   r&  rF   rI   rÉ   rY  rL   Úcollections.abcr   Údataclassesr   r   r   r   Úpathlibr   Útypingr	   r
   r   r_   r   r   Ú_local_folderr   Úerrorsr   Úutilsr   r   r   r   r   r   r   Úutils._hf_urisr   Úutils._pathsr   rX  r   Ú
get_loggerr0   r  ÚBUCKET_PREFIXrú   r   r9   rR   rW   rZ   r]   rr   rz   r4   rk   r6   r†   rˆ   r“   r°   r­   r½   rÇ   r7   ÚfloatrÐ   rß   rè   rî   r  r   r)  r-  r2  rH  rJ  r^  r'   r/   r-   ú<module>rk     sn  ðñó
 Û Û Û 	Û Û 
Û Ý $ß (ß 'Ý ß .Ñ .ç  Ý 6Ý '÷÷ ñ õ /Ý /ñ Ýð 
ˆ×	Ñ	˜HÓ	%€ð  €ØÐ ð ÷'ð 'ó ð'ð@ ÷
ð 
ó ð
ð* ÷-ð -ó ð-ð ÷ð ó ðñ �$Ô÷ð ó ðð  ÷$ð $ó ð$ðN ÷Pð Pó ðPð2 ÷
ð 
ó ð
ð6C˜Cð C Eó Cð,(˜#ð ( $ó (ð  ÷	*ð 	*ó ð	*ð ÷
ð 
ó ð
÷82ñ 2ðj Cð ¨D°°s¸C°x±Ñ,Aó ð:*�cð *˜e C¨ JÑ/°$Ñ6ó *ð7 #ð 7¨(°5¸¸cÀ5¸Ñ3IÑ*Jó 7ð,2˜Gð 2°ð 2¸Sð 2ÀXÈeÐTWÐY\Ð^cÐehÐThÑNiÑEjó 2ðHP˜Eð P có Pð$ #òESà
ðESð Ð(Ñ)ðESð ð	ESð
 ðESð ðESð ðESð ðESð ðESð ðESð ðESð ðESð �t‘ðESð óESðX ØØØØ!Ø+/ØñtØðtà
ðtð 
ðtð ð	tð
 ðtð ðtð ðtð ðtð " DÑ(ðtð �$‰Jðtð ótðx,�hð , dó ,ð:�Xð ¨#ð °$ó ð#˜#ð # (ó #ñVe˜ð e wð e¸ð eÈsÐUYÉzð eÐeió eðP*˜hð *¨4ó *ð  Øðuð
 ØØØØ!Ø $Ø $Ø"ØØØØØØ#ò%uØ�$‰Jðuà
�‰*ðuð 
ð	uð
 ðuð ðuð ðuð ðuð ðuð �#‰Y˜Ñðuð �#‰Y˜Ñðuð �t‘ðuð �‰*ðuð �‰:ðuð ðuð  ð!uð" ð#uð$ �#‰:˜Ñð%uð& ô'ur/   