Ë
    Ø]j¶  ã                   ób  — d Z ddlZddlmZmZ ddlmZ ddlmZ ddl	m
Z
 ddl	mZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZmZ d"d„Zd„ Zd„ Zd„ Z d„ Z! edg d¢«      Z" edg d¢«      Z# e#dddd¬«      Z$ G d„ d«      Z% G d„ de%«      Z& G d„ de%«      Z' G d „ d!e%«      Z(y)#zk
Pagination serializers determine the structure of the output that should
be used for paginated responses.
é    N)Ú	b64decodeÚ	b64encode)Ú
namedtuple)Úparse)ÚInvalidPage)Ú	Paginator)Úloader)Ú	force_str)Úgettext_lazy)ÚNotFound)ÚResponse)Úapi_settings)Úremove_query_paramÚreplace_query_paramFc                 ód   — t        | «      }|dk  s|dk(  r|r
t        «       ‚|rt        ||«      S |S )z7
    Cast a string to a strictly positive integer.
    r   )ÚintÚ
ValueErrorÚmin)Úinteger_stringÚstrictÚcutoffÚrets       úP/var/www/zogu/zoguvenv/lib/python3.12/site-packages/rest_framework/pagination.pyÚ_positive_intr      s:   € ô ˆnÓ
€CØ
ˆQ‚w�3˜!’8¡Ü‹lÐÙÜ�3˜ÓÐØ€Jó    c                 ó&   — | |z  r| |z  dz   S | |z  S )zD
    Returns 'a' divided by 'b', with any remainder rounded up.
    é   © )ÚaÚbs     r   Ú_divide_with_ceilr!   #   s"   € ð 	ˆ1‚uØ�Q‘˜!‰|Ðà�‰6€Mr   c                 óô  — | dk\  sJ ‚|| k\  sJ ‚|dk  rt        t        d|dz   «      «      S d| dz
  | | dz   |h}| dk  r"|j                  d«       |j                  d«       | |dz
  k\  r(|j                  |dz
  «       |j                  |dz
  «       t        |«      D �cg c]  }d|cxk  r|k  rn n|‘Œ }}| dkD  r|j	                  dd«       | |dz
  k  r|j	                  t        |«      dz
  d«       |S c c}w )aŒ  
    This utility function determines a list of page numbers to display.
    This gives us a nice contextually relevant set of page numbers.

    For example:
    current=14, final=16 -> [1, None, 13, 14, 15, 16]

    This implementation gives one page to each side of the cursor,
    or two pages to the side when the cursor is at the edge, then
    ensures that any breaks between non-continuous page numbers never
    remove only a single page.

    For an alternative implementation which gives two pages to each side of
    the cursor, eg. as in GitHub issue list pagination, see:

    https://gist.github.com/tomchristie/321140cebb1c4a558b15
    r   é   é   é   é   r   N)ÚlistÚrangeÚaddÚsortedÚinsertÚlen)ÚcurrentÚfinalÚincludedÚidxs       r   Ú_get_displayed_page_numbersr1   -   s  € ð$ �aŠ<Ðˆ<Ø�GÒÐÐà�‚zÜ”E˜!˜U Q™YÓ'Ó(Ð(ð �7˜Q‘; ¨°1©°eÐ<€Hð �!‚|Ø�‰�QŒØ�‰�QŒØ�%˜!‘)ÒØ�‰�U˜Q‘YÔØ�‰�U˜Q‘YÔô ˜hÓ'öØØˆsÔ�eÕò 	ð€Hð ð �‚{Ø�‰˜˜4Ô Ø�˜‘ÒØ�‰œ˜H›¨Ñ)¨4Ô0Ø€Oùòs   ÂC5c                 ó|   — g }| D ]4  }|€t         }nt         ||«      |||k(  d¬«      }|j                  |«       Œ6 |S )zg
    Given a list of page numbers and `None` page breaks,
    return a list of `PageLink` objects.
    F©ÚurlÚnumberÚ	is_activeÚis_break)Ú
PAGE_BREAKÚPageLinkÚappend)Úpage_numbersr-   Úurl_funcÚ
page_linksÚpage_numberÚ	page_links         r   Ú_get_page_linksr@   `   s[   € ð
 €JØ#ò 
%ˆØÐÜ"‰Iä Ù˜[Ó)Ø"Ø&¨'Ñ1Øô	ˆIð 	×Ñ˜)Õ$ð
%ð Ðr   c                 óP   — d„ }t        | D �cg c]
  } ||«      ‘Œ c}«      S c c}w )z�
    Given an order_by tuple such as `('-created', 'uuid')` reverse the
    ordering and return a new tuple, eg. `('created', '-uuid')`.
    c                 ó8   — | j                  d«      r| dd  S d| z   S )Nú-r   )Ú
startswith)Úxs    r   Úinvertz!_reverse_ordering.<locals>.inverty   s"   € ØŸ™ SÔ)ˆq��ˆuÐ6¨s°Q©wÐ6r   )Útuple)Úordering_tuplerF   Úitems      r   Ú_reverse_orderingrJ   t   s&   € ò
7ô ¨>Ö: 4‘&˜•,Ò:Ó;Ð;ùÒ:s   �#ÚCursor©ÚoffsetÚreverseÚpositionr9   r3   Tc                   ó6   — e Zd ZdZd	d„Zd„ Zd„ Zd„ Zd„ Zd„ Z	y)
ÚBasePaginationFNc                 ó   — t        d«      ‚)Nz(paginate_queryset() must be implemented.©ÚNotImplementedError©ÚselfÚquerysetÚrequestÚviews       r   Úpaginate_querysetz BasePagination.paginate_querysetˆ   s   € Ü!Ð"LÓMÐMr   c                 ó   — t        d«      ‚)Nz-get_paginated_response() must be implemented.rS   ©rV   Údatas     r   Úget_paginated_responsez%BasePagination.get_paginated_response‹   s   € Ü!Ð"QÓRÐRr   c                 ó   — |S ©Nr   ©rV   Úschemas     r   Úget_paginated_response_schemaz,BasePagination.get_paginated_response_schemaŽ   s   € Øˆr   c                 ó   — t        d«      ‚)Nz7to_html() must be implemented to display page controls.rS   ©rV   s    r   Úto_htmlzBasePagination.to_html‘   s   € Ü!Ð"[Ó\Ð\r   c                 ó   — |d   S )NÚresultsr   r\   s     r   Úget_resultszBasePagination.get_results”   s   € Ø�I‰Ðr   c                 ó   — g S r`   r   )rV   rY   s     r   Úget_schema_operation_parametersz.BasePagination.get_schema_operation_parameters—   s   € Øˆ	r   r`   )
Ú__name__Ú
__module__Ú__qualname__Údisplay_page_controlsrZ   r^   rc   rf   ri   rk   r   r   r   rQ   rQ   …   s)   „ Ø!ÐóNòSòò]òór   rQ   c                   ó®   — e Zd ZdZej
                  ZeZdZ	 e
d«      ZdZ e
d«      ZdZdZdZ e
d«      Zdd	„Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚPageNumberPaginationzÒ
    A simple page number based style that supports page numbers as
    query parameters. For example:

    http://api.example.org/accounts/?page=4
    http://api.example.org/accounts/?page=4&page_size=100
    Úpagez.A page number within the paginated result set.Nú%Number of results to return per page.)Úlastú&rest_framework/pagination/numbers.htmlzInvalid page.c                 ó   — || _         | j                  |«      }|sy| j                  ||«      }| j                  ||«      }	 |j	                  |«      | _        |j                  dkD  r| j                  �d| _        t        | j                  «      S # t
        $ r6}| j                  j                  |t        |«      ¬«      }t        |«      ‚d}~ww xY w)z“
        Paginate a queryset if required, either returning a
        page object, or `None` if pagination is not configured for this view.
        N)r>   Úmessager   T)rX   Úget_page_sizeÚdjango_paginator_classÚget_page_numberrr   r   Úinvalid_page_messageÚformatÚstrr   Ú	num_pagesÚtemplatero   r'   )	rV   rW   rX   rY   Ú	page_sizeÚ	paginatorr>   ÚexcÚmsgs	            r   rZ   z&PageNumberPagination.paginate_queryset¼   sË   € ð
 ˆŒØ×&Ñ& wÓ/ˆ	ÙØà×/Ñ/°¸)ÓDˆ	Ø×*Ñ*¨7°IÓ>ˆð	 Ø!Ÿ™ {Ó3ˆDŒIð ×Ñ Ò" t§}¡}Ð'@à)-ˆDÔ&ä�D—I‘I‹Ðøô ò 	 Ø×+Ñ+×2Ñ2Ø'´°S³ð 3ó ˆCô ˜3“-Ðûð		 ús   ÁB Â	CÂ1CÃCc                 óŒ   — |j                   j                  | j                  «      xs d}|| j                  v r|j                  }|S ©Nr   )Úquery_paramsÚgetÚpage_query_paramÚlast_page_stringsr~   )rV   rX   r�   r>   s       r   rz   z$PageNumberPagination.get_page_number×   sB   € Ø×*Ñ*×.Ñ.¨t×/DÑ/DÓEÒJÈˆØ˜$×0Ñ0Ñ0Ø#×-Ñ-ˆKØÐr   c                 ó–   — t        | j                  j                  j                  | j	                  «       | j                  «       |dœ«      S ©N©ÚcountÚnextÚpreviousrh   )r   rr   r�   r�   Úget_next_linkÚget_previous_linkr\   s     r   r^   z+PageNumberPagination.get_paginated_responseÝ   sB   € ÜØ—Y‘Y×(Ñ(×.Ñ.Ø×&Ñ&Ó(Ø×.Ñ.Ó0Øñ	
ó ð 	r   c           
      óž   — dddgdddœddd	d
j                  | j                  ¬«      dœddd	dj                  | j                  ¬«      dœ|dœdœS )NÚobjectr�   rh   Úintegeré{   ©ÚtypeÚexampleÚstringTÚuriz5http://api.example.org/accounts/?{page_query_param}=4)rˆ   ©r—   Únullabler|   r˜   z5http://api.example.org/accounts/?{page_query_param}=2rŒ   ©r—   ÚrequiredÚ
properties)r|   rˆ   ra   s     r   rc   z2PageNumberPagination.get_paginated_response_schemaå   sŠ   € àØ  )Ð,ð &Ø"ñð
 %Ø $Ø#ØV×]Ñ]Ø)-×)>Ñ)>ð  ^ó  @ñ	ð %Ø $Ø#ØV×]Ñ]Ø)-×)>Ñ)>ð  ^ó  @ñ	ð "ñ'ñ
ð 	
r   c                 ó  — | j                   rWt        j                  t        t        «      5  t        |j                  | j                      d| j                  ¬«      cd d d «       S | j                  S # 1 sw Y   | j                  S xY w©NT)r   r   ©	Úpage_size_query_paramÚ
contextlibÚsuppressÚKeyErrorr   r   r†   Úmax_page_sizer€   ©rV   rX   s     r   rx   z"PageNumberPagination.get_page_size   óp   € Ø×%Ò%Ü×$Ñ$¤X¬zÓ:ñ Ü$Ø×(Ñ(¨×)CÑ)CÑDØØ×-Ñ-ô÷ñ ð �~‰~Ð÷ð �~‰~Ðúó   «/A0Á0Bc                 óÎ   — | j                   j                  «       sy | j                  j                  «       }| j                   j	                  «       }t        || j                  |«      S r`   )rr   Úhas_nextrX   Úbuild_absolute_uriÚnext_page_numberr   rˆ   ©rV   r4   r>   s      r   r�   z"PageNumberPagination.get_next_link
  sN   € Ø�y‰y×!Ñ!Ô#ØØ�l‰l×-Ñ-Ó/ˆØ—i‘i×0Ñ0Ó2ˆÜ" 3¨×(=Ñ(=¸{ÓKÐKr   c                 ó  — | j                   j                  «       sy | j                  j                  «       }| j                   j	                  «       }|dk(  rt        || j                  «      S t        || j                  |«      S r…   )rr   Úhas_previousrX   r­   Úprevious_page_numberr   rˆ   r   r¯   s      r   r‘   z&PageNumberPagination.get_previous_link  si   € Ø�y‰y×%Ñ%Ô'ØØ�l‰l×-Ñ-Ó/ˆØ—i‘i×4Ñ4Ó6ˆØ˜!ÒÜ% c¨4×+@Ñ+@ÓAÐAÜ" 3¨×(=Ñ(=¸{ÓKÐKr   c                 ó(  ‡ ‡— ‰ j                   j                  «       Šˆˆ fd„}‰ j                  j                  }‰ j                  j                  j
                  }t        ||«      }t        |||«      }‰ j                  «       ‰ j                  «       |dœS )Nc                 óh   •— | dk(  rt        ‰‰j                  «      S t        ‰‰j                  | «      S r…   )r   rˆ   r   )r>   Úbase_urlrV   s    €€r   Úpage_number_to_urlzAPageNumberPagination.get_html_context.<locals>.page_number_to_url  s3   ø€ Ø˜aÒÜ)¨(°D×4IÑ4IÓJÐJä*¨8°T×5JÑ5JÈKÓXÐXr   ©Úprevious_urlÚnext_urlr=   )
rX   r­   rr   r5   r�   r~   r1   r@   r‘   r�   )rV   r¶   r-   r.   r;   r=   rµ   s   `     @r   Úget_html_contextz%PageNumberPagination.get_html_context  sƒ   ù€ Ø—<‘<×2Ñ2Ó4ˆõ	Yð —)‘)×"Ñ"ˆØ—	‘	×#Ñ#×-Ñ-ˆÜ2°7¸EÓBˆÜ$ \°7Ð<NÓOˆ
ð !×2Ñ2Ó4Ø×*Ñ*Ó,Ø$ñ
ð 	
r   c                 ó‚   — t        j                  | j                  «      }| j                  «       }|j	                  |«      S r`   ©r	   Úget_templater   rº   Úrender©rV   r   Úcontexts      r   rf   zPageNumberPagination.to_html.  ó3   € Ü×&Ñ& t§}¡}Ó5ˆØ×'Ñ'Ó)ˆØ�‰˜wÓ'Ð'r   c                 óÚ   — | j                   ddt        | j                  «      ddidœg}| j                  �6|j	                  | j                  ddt        | j
                  «      ddidœ«       |S ©NFÚqueryr—   r”   ©Únamerž   ÚinÚdescriptionrb   )rˆ   r
   Úpage_query_descriptionr£   r:   Úpage_size_query_description©rV   rY   Ú
parameterss      r   rk   z4PageNumberPagination.get_schema_operation_parameters3  s‡   € ð ×-Ñ-Ø!ØÜ(¨×)DÑ)DÓEà˜Iðñð

ˆ
ð ×%Ñ%Ð1Ø×Ñà ×6Ñ6Ø %Ø!Ü#,¨T×-MÑ-MÓ#Nà 	ðñô
ð Ðr   r`   )rl   rm   rn   Ú__doc__r   Ú	PAGE_SIZEr€   ÚDjangoPaginatorry   rˆ   Ú_rÉ   r£   rÊ   r§   r‰   r   r{   rZ   rz   r^   rc   rx   r�   r‘   rº   rf   rk   r   r   r   rq   rq   ›   s“   „ ñð ×&Ñ&€Ià,Ðð ÐÙÐOÓPÐð !ÐÙ"#Ð$KÓ"LÐð €Mà!Ðà7€Há˜_Ó-Ðóò6òò
ò6òLòLò
ò((ó
r   rq   c                   óœ   — e Zd ZdZej
                  ZdZ ed«      Z	dZ
 ed«      ZdZdZdd„Zd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚLimitOffsetPaginationzœ
    A limit/offset based style. For example:

    http://api.example.org/accounts/?limit=100
    http://api.example.org/accounts/?offset=400&limit=100
    Úlimitrs   rM   z3The initial index from which to return the results.Nru   c                 ó¸  — || _         | j                  |«      | _        | j                  €y | j                  |«      | _        | j                  |«      | _        | j                  | j                  kD  r| j                  �d| _        | j                  dk(  s| j                  | j                  kD  rg S t        || j                  | j                  | j                  z    «      S )NTr   )
rX   Ú	get_limitrÓ   Ú	get_countr�   Ú
get_offsetrM   r   ro   r'   rU   s       r   rZ   z'LimitOffsetPagination.paginate_queryset]  s©   € ØˆŒØ—^‘^ GÓ,ˆŒ
Ø�:‰:ÐØà—^‘^ HÓ-ˆŒ
Ø—o‘o gÓ.ˆŒØ�:‰:˜Ÿ
™
Ò" t§}¡}Ð'@Ø)-ˆDÔ&à�:‰:˜Š?˜dŸk™k¨D¯J©JÒ6ØˆIÜ�H˜TŸ[™[¨¯©°t·z±zÑ)AÐBÓCÐCr   c                 ón   — t        | j                  | j                  «       | j                  «       |dœ«      S r‹   )r   r�   r�   r‘   r\   s     r   r^   z,LimitOffsetPagination.get_paginated_responsel  s6   € ÜØ—Z‘ZØ×&Ñ&Ó(Ø×.Ñ.Ó0Øñ	
ó ð 	r   c                 óÊ   — dddgdddœddd	d
j                  | j                  | j                  ¬«      dœddd	dj                  | j                  | j                  ¬«      dœ|dœdœS )Nr“   r�   rh   r”   r•   r–   r™   Trš   zEhttp://api.example.org/accounts/?{offset_param}=400&{limit_param}=100)Úoffset_paramÚlimit_paramr›   zEhttp://api.example.org/accounts/?{offset_param}=200&{limit_param}=100rŒ   r�   )r|   Úoffset_query_paramÚlimit_query_paramra   s     r   rc   z3LimitOffsetPagination.get_paginated_response_schemat  sš   € àØ  )Ð,ð &Ø"ñð
 %Ø $Ø#Øf×mÑmØ%)×%<Ñ%<È$×J`ÑJ`ð  nó  bñ	ð %Ø $Ø#Øf×mÑmØ%)×%<Ñ%<È$×J`ÑJ`ð  nó  bñ	ð "ñ'ñ
ð 	
r   c                 ó  — | j                   rWt        j                  t        t        «      5  t        |j                  | j                      d| j                  ¬«      cd d d «       S | j                  S # 1 sw Y   | j                  S xY wr¡   )	rÝ   r¤   r¥   r¦   r   r   r†   Ú	max_limitÚdefault_limitr¨   s     r   rÕ   zLimitOffsetPagination.get_limit�  sr   € Ø×!Ò!Ü×$Ñ$¤X¬zÓ:ñ Ü$Ø×(Ñ(¨×)?Ñ)?Ñ@ØØŸ>™>ô÷ñ ð ×!Ñ!Ð!÷ð ×!Ñ!Ð!úrª   c                 ór   — 	 t        |j                  | j                     «      S # t        t        f$ r Y yw xY w©Nr   )r   r†   rÜ   r¦   r   r¨   s     r   r×   z LimitOffsetPagination.get_offset™  sA   € ð	Ü Ø×$Ñ$ T×%<Ñ%<Ñ=óð øô œ*Ð%ò 	Ùð	ús   ‚!$ ¤6µ6c                 ó&  — | j                   | j                  z   | j                  k\  ry | j                  j	                  «       }t        || j                  | j                  «      }| j                   | j                  z   }t        || j                  |«      S r`   )rM   rÓ   r�   rX   r­   r   rÝ   rÜ   ©rV   r4   rM   s      r   r�   z#LimitOffsetPagination.get_next_link¡  so   € Ø�;‰;˜Ÿ™Ñ# t§z¡zÒ1Øà�l‰l×-Ñ-Ó/ˆÜ! # t×'=Ñ'=¸t¿z¹zÓJˆà—‘˜tŸz™zÑ)ˆÜ" 3¨×(?Ñ(?ÀÓHÐHr   c                 ó\  — | j                   dk  ry | j                  j                  «       }t        || j                  | j
                  «      }| j                   | j
                  z
  dk  rt        || j                  «      S | j                   | j
                  z
  }t        || j                  |«      S râ   )rM   rX   r­   r   rÝ   rÓ   r   rÜ   rä   s      r   r‘   z'LimitOffsetPagination.get_previous_link«  sŠ   € Ø�;‰;˜!ÒØà�l‰l×-Ñ-Ó/ˆÜ! # t×'=Ñ'=¸t¿z¹zÓJˆà�;‰;˜Ÿ™Ñ# qÒ(Ü% c¨4×+BÑ+BÓCÐCà—‘˜tŸz™zÑ)ˆÜ" 3¨×(?Ñ(?ÀÓHÐHr   c                 óê  ‡ ‡‡— ‰ j                   j                  «       Š‰ j                  r~t        ‰ j                  ‰ j                  «      dz   Št        ‰ j
                  ‰ j                  z
  ‰ j                  «      t        ‰ j                  ‰ j                  «      z   }t        |d«      }ndŠd}‰|kD  r|Šˆˆˆ fd„}t        ‰|«      }t        |‰|«      }‰ j                  «       ‰ j                  «       |dœS )Nr   c                 ó¦   •— | dk(  rt        ‰‰j                  «      S ‰j                  | ‰z
  ‰j                  z  z   }t	        ‰‰j                  |«      S r…   )r   rÜ   rM   rÓ   r   )r>   rM   rµ   r-   rV   s     €€€r   r¶   zBLimitOffsetPagination.get_html_context.<locals>.page_number_to_urlÐ  sO   ø€ Ø˜aÒÜ)¨(°D×4KÑ4KÓLÐLàŸ™¨°wÑ)>À$Ç*Á*Ñ(LÑM�Ü*¨8°T×5LÑ5LÈfÓUÐUr   r·   )rX   r­   rÓ   r!   rM   r�   Úmaxr1   r@   r‘   r�   )rV   r.   r¶   r;   r=   rµ   r-   s   `    @@r   rº   z&LimitOffsetPagination.get_html_context¸  sÛ   ú€ Ø—<‘<×2Ñ2Ó4ˆà�:Š:Ü'¨¯©°T·Z±ZÓ@À1ÑDˆGô " $§*¡*¨t¯{©{Ñ":¸D¿J¹JÓGÜ! $§+¡+¨t¯z©zÓ:ñ;ð ô
 ˜˜q“M‰EàˆGØˆEà�UŠ?ØˆGö	Vô 3°7¸EÓBˆÜ$ \°7Ð<NÓOˆ
ð !×2Ñ2Ó4Ø×*Ñ*Ó,Ø$ñ
ð 	
r   c                 ó‚   — t        j                  | j                  «      }| j                  «       }|j	                  |«      S r`   r¼   r¿   s      r   rf   zLimitOffsetPagination.to_htmlà  rÁ   r   c                 ód   — 	 |j                  «       S # t        t        f$ r t        |«      cY S w xY w)zZ
        Determine an object count, supporting either querysets or regular lists.
        )r�   ÚAttributeErrorÚ	TypeErrorr,   )rV   rW   s     r   rÖ   zLimitOffsetPagination.get_countå  s2   € ð	!Ø—>‘>Ó#Ð#øÜ¤	Ð*ò 	!Ü�x“=Ò ð	!ús   ‚ ’/®/c                 ó¢   — | j                   ddt        | j                  «      ddidœ| j                  ddt        | j                  «      ddidœg}|S rÃ   )rÝ   r
   Úlimit_query_descriptionrÜ   Úoffset_query_descriptionrË   s      r   rk   z5LimitOffsetPagination.get_schema_operation_parametersî  sm   € ð ×.Ñ.Ø!ØÜ(¨×)EÑ)EÓFà˜Iðñð ×/Ñ/Ø!ØÜ(¨×)FÑ)FÓGà˜Iðñð
ˆ
ð( Ðr   r`   )rl   rm   rn   rÍ   r   rÎ   rà   rÝ   rÐ   rî   rÜ   rï   rß   r   rZ   r^   rc   rÕ   r×   r�   r‘   rº   rf   rÖ   rk   r   r   r   rÒ   rÒ   N  s}   „ ñð !×*Ñ*€MØÐÙÐ GÓHÐØ!ÐÙ Ð!VÓWÐØ€IØ7€HóDòò
ò6"òòIòIò&
òP(ò
!ór   rÒ   c                   óÀ   — e Zd ZdZdZ ed«      Zej                  Z	 ed«      Z
dZdZdZ ed«      ZdZd	Zdd
„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚCursorPaginationzÐ
    The cursor pagination implementation is necessarily complex.
    For an overview of the position/offset style we use, see this post:
    https://cra.mr/2011/03/08/building-cursors-for-the-disqus-api
    ÚcursorzThe pagination cursor value.zInvalid cursorz-createdz0rest_framework/pagination/previous_and_next.htmlNrs   iè  c                 ó*  — || _         | j                  |«      | _        | j                  sy |j                  «       | _        | j                  |||«      | _        | j                  |«      | _        | j                  €d\  }}}n| j                  \  }}}|r# |j                  t        | j                  «      Ž }n |j                  | j                  Ž }|�k| j                  d   }|j                  d«      }|j                  d«      }	| j                  j                  |k7  r|	dz   |i}
n|	dz   |i}
 |j                  d
i |
¤Ž}t        |||| j                  z   dz    «      }t        |d | j                   «      | _        t#        |«      t#        | j                   «      kD  r"d}| j%                  |d   | j                  «      }nd	}d }|rat        t'        | j                   «      «      | _        |d uxs |dkD  | _        || _        | j(                  r|| _        | j*                  rE|| _        n=|| _        |d uxs |dkD  | _        | j(                  r|| _        | j*                  r|| _        | j*                  s| j(                  r| j0                  �d| _        | j                   S )N)r   FNr   rC   Ú__ltÚ__gtr   TéÿÿÿÿFr   )rX   rx   r€   r­   rµ   Úget_orderingÚorderingÚdecode_cursorrò   Úorder_byrJ   rD   ÚlstriprN   Úfilterr'   rr   r,   Ú_get_position_from_instanceÚreversedr¬   r±   Únext_positionÚprevious_positionr   ro   )rV   rW   rX   rY   rM   rN   Úcurrent_positionÚorderÚis_reversedÚ
order_attrÚkwargsrh   Úhas_following_positionÚfollowing_positions                 r   rZ   z"CursorPagination.paginate_queryset"  sv  € ØˆŒØ×+Ñ+¨GÓ4ˆŒØ�~Š~Øà×2Ñ2Ó4ˆŒØ×)Ñ)¨'°8¸TÓBˆŒà×(Ñ(¨Ó1ˆŒØ�;‰;ÐØ2BÑ/ˆV�WÑ.à26·+±+Ñ/ˆV�WÐ.ñ Ø(�x×(Ñ(Ô*;¸D¿M¹MÓ*JÐK‰Hà(�x×(Ñ(¨$¯-©-Ð8ˆHð Ð'Ø—M‘M !Ñ$ˆEØ×*Ñ*¨3Ó/ˆKØŸ™ cÓ*ˆJð �{‰{×"Ñ" kÒ1Ø$ vÑ-Ð/?Ð@‘à$ vÑ-Ð/?Ð@�à&�x—‘Ñ0¨Ñ0ˆHô
 �x  v°·±Ñ'>ÀÑ'BÐCÓDˆÜ˜  $§.¡.Ð1Ó2ˆŒ	ô ˆw‹<œ#˜dŸi™i›.Ò(Ø%)Ð"Ø!%×!AÑ!AÀ'È"Á+ÈtÏ}É}Ó!]Ñà%*Ð"Ø!%Ðáô œX d§i¡iÓ0Ó1ˆDŒIð .°TÐ9ÒJ¸vÈ¹zˆDŒMØ 6ˆDÔØ�}Š}Ø%5�Ô"Ø× Ò Ø);�Õ&ð 3ˆDŒMØ!1¸Ð!=Ò NÀ6ÈAÁ:ˆDÔØ�}Š}Ø%7�Ô"Ø× Ò Ø)9�Ô&ð ×Ò §¢°D·M±MÐ4MØ)-ˆDÔ&à�y‰yÐr   c                 ó  — | j                   rWt        j                  t        t        «      5  t        |j                  | j                      d| j                  ¬«      cd d d «       S | j                  S # 1 sw Y   | j                  S xY wr¡   r¢   r¨   s     r   rx   zCursorPagination.get_page_sizeo  r©   rª   c                 ó  — | j                   sy | j                  re| j                  rY| j                  j                  rC| j                  j                  dk7  r*| j                  | j                  d   | j                  «      }n| j                  }d}d}t        | j                  «      D ].  }| j                  || j                  «      }||k7  rd} n	|}|dz  }Œ0 | j                  rq|so| j                  s| j                  }d }nT| j                  j                  rd}| j                  }n/| j                  j                  | j                  z   }| j                  }| j                  s| j                  }t        |d¬«      }| j                  |«      S )Nr   rö   FTr   rL   )r¬   rr   rò   rN   rM   rý   rø   rÿ   rþ   r±   r€   r   rK   Úencode_cursor©rV   ÚcomparerM   Úhas_item_with_unique_positionrI   rO   rò   s          r   r�   zCursorPagination.get_next_linky  sX  € Ø�}Š}Øà�9Š9˜Ÿš¨¯©×)<Ò)<ÀÇÁ×ASÑASÐWXÒAXð ×6Ñ6°t·y±yÀ±}ÀdÇmÁmÓT‰Gà×(Ñ(ˆGØˆà(-Ð%Ü˜TŸY™YÓ'ò 	ˆDØ×7Ñ7¸¸d¿m¹mÓLˆHØ˜7Ò"ð 15Ð-Ùð
 ˆGØ�a‰K‰Fð	ð �9Š9Ñ:à×$Ò$ð Ÿ™�Ø‘Ø—‘×$Ò$ð �Ø×1Ñ1‘ð Ÿ™×+Ñ+¨d¯n©nÑ<�Ø×1Ñ1�à�yŠyØ×)Ñ)ˆHä˜v¨u¸xÔHˆØ×!Ñ! &Ó)Ð)r   c                 ó   — | j                   sy | j                  re| j                  rY| j                  j                  sC| j                  j                  dk7  r*| j                  | j                  d   | j                  «      }n| j                  }d}d}| j                  D ].  }| j                  || j                  «      }||k7  rd} n	|}|dz  }Œ0 | j                  rq|so| j                  s| j                  }d }nT| j                  j                  r0| j                  j                  | j                  z   }| j                  }nd}| j                  }| j                  s| j                  }t        |d¬«      }| j                  |«      S )Nr   FTr   rL   )r±   rr   rò   rN   rM   rý   rø   r   r¬   r€   rÿ   rK   r
  r  s          r   r‘   z"CursorPagination.get_previous_link®  sS  € Ø× Ò Øà�9Š9˜Ÿš¨T¯[©[×-@Ò-@ÀTÇ[Á[×EWÑEWÐ[\ÒE\ð ×6Ñ6°t·y±yÀ±|ÀTÇ]Á]ÓS‰Gà×,Ñ,ˆGØˆà(-Ð%Ø—I‘Iò 	ˆDØ×7Ñ7¸¸d¿m¹mÓLˆHØ˜7Ò"ð 15Ð-Ùð
 ˆGØ�a‰K‰Fð	ð �9Š9Ñ:à—=’=ð Ÿ™�Ø‘Ø—‘×$Ò$ð Ÿ™×+Ñ+¨d¯n©nÑ<�Ø×-Ñ-‘ð �Ø×-Ñ-�à�yŠyØ×-Ñ-ˆHä˜v¨t¸hÔGˆØ×!Ñ! &Ó)Ð)r   c                 ó¨  — | j                   }t        |dg «      D �cg c]  }t        |d«      r|‘Œ }}|r#|d   } |«       }|j                  |||«      }|r|}|€J d«       ‚d|vsJ d«       ‚t	        |t
        t        t        f«      s*J dj                  t        |«      j                  ¬«      «       ‚t	        |t
        «      r|fS t        |«      S c c}w )	zV
        Return a tuple of strings, that may be used in an `order_by` method.
        Úfilter_backendsr÷   r   zXUsing cursor pagination, but no ordering attribute was declared on the pagination class.Ú__z¶Cursor pagination does not support double underscore lookups for orderings. Orderings should be an unchanging, unique or nearly-unique field on the model, such as "-created" or "pk".z:Invalid ordering. Expected string or tuple, but got {type})r—   )rø   ÚgetattrÚhasattrr÷   Ú
isinstancer}   r'   rG   r|   r—   rl   )	rV   rX   rW   rY   rø   Ú
filter_clsÚordering_filtersÚfilter_instanceÚordering_from_filters	            r   r÷   zCursorPagination.get_orderingã  s  € ð —=‘=ˆô *1°Ð7HÈ"Ó)Mö
Ø%Ü�z >Ô2ò ð
Ðð 
ñ
 ð *¨!Ñ,ˆJÙ(›lˆOØ#2×#?Ñ#?ÀÈÐSWÓ#XÐ Ù#Ø/�àÐ#ð 	
ð'ó	
Ð#ð ˜8Ñ#ð 	
ðLó	
Ð#ô ˜(¤S¬$´Ð$6Ô7ð 	
ØH×OÑOÜ˜(“^×,Ñ,ð Pó ó	
Ð7ô �h¤Ô$Ø�;ÐÜ�X‹ÐùòA
s   œCc                 ó  — |j                   j                  | j                  «      }|€y	 t        |j	                  d«      «      j                  d«      }t        j                  |d¬«      }|j                  ddg«      d   }t        || j                  ¬«      }|j                  d	dg«      d   }t        t        |«      «      }|j                  d
dg«      d   }t!        |||¬«      S # t        t        f$ r t        | j                  «      ‚w xY w)zL
        Given a request with a cursor, return a `Cursor` instance.
        NÚasciiT)Úkeep_blank_valuesÚoÚ0r   )r   ÚrÚprL   )r†   r‡   Úcursor_query_paramr   ÚencodeÚdecoder   Úparse_qsr   Úoffset_cutoffÚboolr   rì   r   r   Úinvalid_cursor_messagerK   )rV   rX   ÚencodedÚquerystringÚtokensrM   rN   rO   s           r   rù   zCursorPagination.decode_cursor  sø   € ð
 ×&Ñ&×*Ñ*¨4×+BÑ+BÓCˆØˆ?Øð	8Ü# G§N¡N°7Ó$;Ó<×CÑCÀGÓLˆKÜ—^‘^ KÀ4ÔHˆFà—Z‘Z  c UÓ+¨AÑ.ˆFÜ" 6°$×2DÑ2DÔEˆFà—j‘j  s eÓ,¨QÑ/ˆGÜœ3˜w›<Ó(ˆGà—z‘z #¨ vÓ.¨qÑ1ˆHô ˜V¨W¸xÔHÐHøô œ:Ð&ò 	8Ü˜4×6Ñ6Ó7Ð7ð	8ús   ªB-C% Ã%%D
c                 ón  — i }|j                   dk7  rt        |j                   «      |d<   |j                  rd|d<   |j                  �|j                  |d<   t	        j
                  |d¬«      }t        |j                  d«      «      j                  d«      }t        | j                  | j                  |«      S )	zM
        Given a Cursor instance, return an url with encoded cursor.
        r   r  Ú1r  r  T)Údoseqr  )rM   r}   rN   rO   r   Ú	urlencoder   r!  r"  r   rµ   r   )rV   rò   r)  r(  r'  s        r   r
  zCursorPagination.encode_cursor&  s—   € ð ˆØ�=‰=˜AÒÜ˜fŸm™mÓ,ˆF�3‰KØ�>Š>ØˆF�3‰KØ�?‰?Ð&Ø Ÿ/™/ˆF�3‰Kä—o‘o f°DÔ9ˆÜ˜K×.Ñ.¨wÓ7Ó8×?Ñ?ÀÓHˆÜ" 4§=¡=°$×2IÑ2IÈ7ÓSÐSr   c                 ó˜   — |d   j                  d«      }t        |t        «      r||   }t	        |«      S t        ||«      }t	        |«      S )Nr   rC   )rû   r  Údictr  r}   )rV   Úinstancerø   Ú
field_nameÚattrs        r   rý   z,CursorPagination._get_position_from_instance6  sN   € Ø˜a‘[×'Ñ'¨Ó,ˆ
Ü�h¤Ô%Ø˜JÑ'ˆDô �4‹yÐô ˜8 ZÓ0ˆDÜ�4‹yÐr   c                 óX   — t        | j                  «       | j                  «       |dœ«      S )N©rŽ   r�   rh   )r   r�   r‘   r\   s     r   r^   z'CursorPagination.get_paginated_response>  s/   € ÜØ×&Ñ&Ó(Ø×.Ñ.Ó0Øñ
ó ð 	r   c           	      ó”   — ddgddddj                  | j                  ¬«      dœdddd	j                  | j                  ¬«      dœ|d
œdœS )Nr“   rh   r™   Trš   zAhttp://api.example.org/accounts/?{cursor_query_param}=cD00ODY%3D")r   r›   zBhttp://api.example.org/accounts/?{cursor_query_param}=cj0xJnA9NDg3r4  r�   )r|   r   ra   s     r   rc   z.CursorPagination.get_paginated_response_schemaE  sz   € àØ"˜ð %Ø $Ø#Øb×iÑiØ+/×+BÑ+Bð  jó  Dñ	ð %Ø $Ø#Øc×jÑjØ+/×+BÑ+Bð  kó  Dñ	ð "ññ
ð 	
r   c                 óD   — | j                  «       | j                  «       dœS )N)r¸   r¹   )r‘   r�   re   s    r   rº   z!CursorPagination.get_html_context\  s$   € à ×2Ñ2Ó4Ø×*Ñ*Ó,ñ
ð 	
r   c                 ó‚   — t        j                  | j                  «      }| j                  «       }|j	                  |«      S r`   r¼   r¿   s      r   rf   zCursorPagination.to_htmlb  rÁ   r   c                 óÚ   — | j                   ddt        | j                  «      ddidœg}| j                  �6|j	                  | j                  ddt        | j
                  «      ddidœ«       |S )NFrÄ   r—   r™   rÅ   r”   )r   r
   Úcursor_query_descriptionr£   r:   rÊ   rË   s      r   rk   z0CursorPagination.get_schema_operation_parametersg  s‡   € ð ×/Ñ/Ø!ØÜ(¨×)FÑ)FÓGà˜Hðñð

ˆ
ð ×%Ñ%Ð1Ø×Ñà ×6Ñ6Ø %Ø!Ü#,¨T×-MÑ-MÓ#Nà 	ðñô
ð Ðr   r`   )rl   rm   rn   rÍ   r   rÐ   r9  r   rÎ   r€   r&  rø   r   r£   rÊ   r§   r$  rZ   rx   r�   r‘   r÷   rù   r
  rý   r^   rc   rº   rf   rk   r   r   r   rñ   rñ     s¦   „ ñð
 "ÐÙ Ð!?Ó@ÐØ×&Ñ&€IÙÐ/Ó0ÐØ€HØA€Hð !ÐÙ"#Ð$KÓ"LÐð €Mð €MóKòZò3*òj3*òj(òTIò2Tò òò
ò.
ò(ó
r   rñ   )FN))rÍ   r¤   Úbase64r   r   Úcollectionsr   Úurllibr   Údjango.core.paginatorr   r   rÏ   Údjango.templater	   Údjango.utils.encodingr
   Údjango.utils.translationr   rÐ   Úrest_framework.exceptionsr   Úrest_framework.responser   Úrest_framework.settingsr   Úrest_framework.utils.urlsr   r   r   r!   r1   r@   rJ   rK   r9   r8   rQ   rq   rÒ   rñ   r   r   r   ú<module>rE     s¯   ðñó
 ß 'Ý "Ý å -Ý >Ý "Ý +Ý 6å .Ý ,Ý 0ß Mó	òò0òfò(<ñ 
�HÒ?Ó	@€Ù�jÒ"LÓM€á˜$ t°uÀtÔL€
÷ñ ô,p˜>ô pôfu˜Nô uôpy�~õ yr   