
    ec7              	       4   d 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 ddl	m
Z
 ddlmZmZmZmZ ddlmZ ddlmZmZ d d	Z G d
 de      Zd dZd Zd dZdZd!dZ G d dee         Zd dZd ZdedefdZ d Z!	 d dZ"d"dZ#d"dede$de%de$fdZ&d"dZ'y)#z2Functions for prompting the user for project info.    N)OrderedDict)Path)UndefinedError)ConfirmInvalidResponsePrompt
PromptBase)UndefinedVariableInTemplate)create_env_with_contextrmtreec                     |r| |j                         v r
||    r||    n| }	 t        j                  | | |      }|	 |S !)zPrompt user for variable and return the entered value or given default.

    :param str var_name: Variable of the context to query the user
    :param default_value: Value that will be returned if no input happens
    default)keysr   ask)var_namedefault_valuepromptsprefixquestionvariables         3lib/python3.12/site-packages/cookiecutter/prompt.pyread_user_variabler      s^     x7<<>1gh6G 	  ::
3]KO     c                   0    e Zd ZdZg dZg dZdedefdZy)YesNoPromptz5A prompt that returns a boolean for yes/no questions.)1truetyesyon)0falsefnonoffvaluereturnc                     |j                         j                         }|| j                  v ry|| j                  v ryt	        | j
                        )zConvert choices to a bool.TF)striploweryes_choices
no_choicesr   validate_error_messageselfr)   s     r   process_responsezYesNoPrompt.process_response+   sG    ##%D$$$doo%!$"="=>>r   N)	__name__
__module____qualname____doc__r.   r/   strboolr3    r   r   r   r   %   s"    ?6K6J?c ?d ?r   r   c                 x    |r| |j                         v r
||    r||    n| }t        j                  | | |      S )a  Prompt the user to reply with 'yes' or 'no' (or equivalent values).

    - These input values will be converted to ``True``:
      "1", "true", "t", "yes", "y", "on"
    - These input values will be converted to ``False``:
      "0", "false", "f", "no", "n", "off"

    Actual parsing done by :func:`prompt`; Check this function codebase change in
    case of unexpected behaviour.

    :param str question: Question to the user
    :param default_value: Value that will be returned if no input happens
    r   )r   r   r   )r   r   r   r   r   s        r   read_user_yes_nor<   6   sK      x7<<>1gh6G 	 
 ??fXhZ0-?HHr   c                 0    t        j                  | d      S )zXPrompt the user to enter a password.

    :param str question: Question to the user
    T)password)r   r   )r   s    r   read_repo_passwordr?   L   s    
 ::h..r   c           	         t        |t              st        |st        t	        d t        |d      D              }|j                         }d|  }|j                         D cg c]  } dj                  |  }}|ry| |j                         v rgt        ||    t              r||    }nNd||    v r||    d   }|j                         D 	
cg c]$  \  }	}
|
||    v rd|	 d||    |
    dnd|	 d|
 d& }}	}
d	j                  | | d	j                  |      d
f      }t        j                  |t        |      t        |      d         }||   S c c}w c c}
}	w )aa  Prompt the user to choose from several options for the given variable.

    The first item will be returned if no input happens.

    :param str var_name: Variable as specified in the context
    :param list options: Sequence of options that are available to select from
    :return: Exactly one item of ``options`` that has been chosen by the user
    c              3   ,   K   | ]  \  }}| |f  y wNr:   ).0ir)   s      r   	<genexpr>z#read_user_choice.<locals>.<genexpr>c   s     SEe_Ss      zSelect z%    [bold magenta]{}[/] - [bold]{}[/]
__prompt__z    [bold magenta]z[/] - [bold]z[/]
z    Choose fromr   )choicesr   )
isinstancelist	TypeError
ValueErrorr   	enumerater   itemsformatr8   joinr   r   )r   optionsr   r   
choice_maprI   r   cchoice_linesrD   ppromptuser_choices                r   read_user_choicerY   T   s    gt$SYwPQ=RSSJooG
#HDNDTDTDV?@6/66:L 
 8w||~-gh'-x(Hwx00"8,\: ',,. Aq GH-- )<8I!8L7MSQ-aSQCsCDL  YYhxj!IIl#	
F **VT']DMRSDTUKk"";s   "E	)Er   c                     	 t        j                  | t              }t        |t              st	        d      |S # t        $ r}t	        d      |d}~ww xY w)ztLoad user-supplied value as a JSON dict.

    :param str user_value: User-supplied value to load as a JSON dict
    )object_pairs_hookzUnable to decode to JSON.NzRequires JSON dict.)jsonloadsr   	Exceptionr   rJ   dict)
user_valuer   	user_dicterrors       r   process_jsonrc      sX    
FJJz[I	
 i&344  F9:EFs   : 	AAAc                   ,    e Zd ZdZdZeZdZdedefdZ	y)
JsonPromptz.A prompt that returns a dict from JSON string.Nz2[prompt.invalid]  Please enter a valid JSON stringr)   r*   c                 .    t        || j                        S )zConvert choices to a dict.)rc   r   r1   s     r   r3   zJsonPrompt.process_response   s    E4<<00r   )
r4   r5   r6   r7   r   r_   response_typer0   r8   r3   r:   r   r   re   re      s(    8GMQ1c 1d 1r   re   c                     t        |t              st        |r| |j                         v r
||    r||    n| }t        j                  | | dt         d|d      }|S )zPrompt the user to provide a dictionary of data.

    :param str var_name: Variable as specified in the context
    :param default_value: Value that will be returned if no input is provided
    :return: A Python dictionary to use in the context.
    z [cyan bold](z)[/]F)r   show_default)rJ   r_   rL   r   re   r   DEFAULT_DISPLAY)r   r   r   r   r   r`   s         r   read_user_dictrk      sv     mT* x7<<>1gh6G 	 
 (8*M/):$?   J
 r   c           
         |t        |t              r|S t        |t              r:|j                         D ci c]  \  }}t	        | ||      t	        | ||        c}}S t        |t
              r|D cg c]  }t	        | ||       c}S t        |t              st        |      }| j                  |      }|j                  |      S c c}}w c c}w )a  Render the next variable to be displayed in the user prompt.

    Inside the prompting taken from the cookiecutter.json file, this renders
    the next variable. For example, if a project_name is "Peanut Butter
    Cookie", the repo_name could be be rendered with:

        `{{ cookiecutter.project_name.replace(" ", "_") }}`.

    This is then presented to the user as the default.

    :param Environment env: A Jinja2 Environment object.
    :param raw: The next value to be prompted for by the user.
    :param dict cookiecutter_dict: The current context as it's gradually
        being populated with variables.
    :return: The rendered value for the default variable.
    )cookiecutter)	rJ   r9   r_   rO   render_variablerK   r8   from_stringrender)envrawcookiecutter_dictkvtemplates         r   rn   rn      s    " {jd+
	C	
 			
 1 C$56Q)9 
 	
 
C	DGHqQ(9:HHS!#hs#H??(9?::
 Is   #C3CrR   r*   c                     ddi}| j                         D ]F  \  }}t        |j                  d|            }|j                  d|      }||k(  r|n| d| d}|||<   H |S )z@Process template options and return friendly prompt information.rG   zSelect a templatetitledescriptionz ())rO   r8   get)rR   r   
option_keyoption_valuerx   ry   labels          r   _prompts_from_optionsr      s|    01G$+MMO $ 
LL$$Wj9:"&&}jA+-eWB{m13M#
	$
 Nr   c                 x    t        |j                               }dt        |      i}|r|d   S t        | ||d      S )Prompt user with a set of options to choose from.

    :param no_input: Do not prompt for user input and return the first available option.
    	templatesr    )rK   r   r   rY   )keyrR   no_inputoptsr   s        r   prompt_choice_for_templater      sA    
 D1':;G47L$4S$$LLr   c                 j    |D cg c]  }t        |||        }}|r|d   S t        ||||      S c c}w )r   r   )rn   rY   )	rs   rq   r   rR   r   r   r   rr   rendered_optionss	            r   prompt_choice_for_configr      sJ     QXXS2CDXX""C!17FCC Ys   0c           
         t        g       }t        |       }| d   j                  di       }d}| d   j                         }|D cg c]  \  }}|j	                  d      r| }	}}t        |	      }
|D ]  \  }}|j	                  d      r|j	                  d      s|||<   .|j	                  d      rt        |||      ||<   Pt        |t              s|dz  }d| d|
 d	}	 t        |t              rt        ||||||      }|||<   ngt        |t              r%|rt        |||      ||<   nDt        |||      ||<   n2t        |t              s"t        |||      }|st        |||      }|||<    | d   j                         D ]z  \  }}|j	                  d      r|j	                  d      s)	 t        |t              rA|dz  }d| d|
 d	}t        |||      }|s|j	                  d      st!        ||||      }|||<   | |S c c}}w # t        $ r}d
| d}t        |||       |d}~ww xY w# t        $ r}d
| d}t        |||       |d}~ww xY w)zPrompt user to enter a new config.

    :param dict context: Source for field names and sample values.
    :param no_input: Do not prompt for user input and use only values from context.
    rm   __prompts__r   ___rF   z  [dim][/z][/] zUnable to render variable ''N)r   r   poprO   
startswithlenrn   rJ   r_   rK   r   r9   r<   r   r   r
   rk   )contextr   rs   rq   r   countall_promptsrt   r   visible_promptssizer   rr   r   valerrmsgs                    r   prompt_for_configr     s    $B
!'
*Cn%))-<G
 E.)//1K%0JTQS8IqJOJD %JS>>#s~~d';%(c"^^D!%4S#?P%Qc"#t$QJEwavU3F	J#t$.%sCh *-!#&C&-<S"3.%c* .>c3QW-X%c*T*%c30AB,S#wGC),!#&E%JP N+113 JS>>#s~~d';	J#t$
#E7!D67%c30ABt(<(c7FCC),!#&J( } KJ  	J/uA6C-c3@cI	J*  	J/uA6C-c3@cI	Js>   H H#BH0AH0	H-H((H-0	I9IIr   repo_dirr   c           	      
   t        g       }t        |       }d}| d   j                  di       }d}| d   j                  |i       }|rt	        |||      }	||	   d   }
nMd}| d   j                  |g       }t        |||||||      }	t        j                  d|	      j                  d      }
|
rt        |
      nd	}
|
r|
j                         rt        d
      t        |      j                         }||
z  j                         }| S )a!  Prompt user to select the nested template to use.

    :param context: Source for field names and sample values.
    :param repo_dir: Repository directory.
    :param no_input: Do not prompt for user input and use only values from context.
    :returns: Path to the selected template.
    r   rm   r   r   pathrv   z\((.+)\)rF   NzIllegal template path)r   r   r   r{   r   r   researchgroupr   is_absoluterM   resolve)r   r   r   rs   rq   r   r   r   configr   rv   template_paths               r   choose_nested_templater   U  s    $B
!'
*CFn%))-<G
C^$((b1F(fh?#;v& (,,S"5&sC7F
 99[#.44Q7!)tH~tHX113011H~%%'H(113M_r   c                     |rd}nd|  d}t        |d      }|rAt        j                  j                  |       rt	        |        yt        j
                  |        yt        dd      }|ryt        j                          y)a  
    Ask user if it's okay to delete the previously-downloaded file/directory.

    If yes, delete it. If no, checks to see if the old version should be
    reused. If yes, it's reused; otherwise, Cookiecutter exits.

    :param path: Previously downloaded zipfile.
    :param no_input: Suppress prompt to delete repo and just delete it.
    :return: True if the content was deleted
    TzYou've downloaded z1 before. Is it okay to delete and re-download it?r    z+Do you want to re-use the existing version?FN)r<   osr   isdirr   removesysexit)r   r   ok_to_deleter   ok_to_reuses        r   prompt_and_deleter   z  s}      !&WX 	 (%877==4L  IIdO&95
 
r   )Nr   rB   )F)(r7   r\   r   r   r   collectionsr   pathlibr   jinja2.exceptionsr   rich.promptr   r   r   r	   cookiecutter.exceptionsr
   cookiecutter.utilsr   r   r   r   r<   r?   rY   rj   rc   r_   re   rk   rn   r   r   r   r   r8   r9   r   r   r:   r   r   <module>r      s    8  	 	 
 #  , D D ? >(?' ?"I,/0#f $	1D! 	1.!;H4 D M JL
DM`"D "C "4 "TW "J#r   