Ë
    i[åjYq  ã                   óx  — d Z ddlZddlZddlZddlmZ ddlmZ  ee«      j                  «       j                  j                  j                  Z
e
dz  e
dz  fD ]9  Z ee«      ej                  vsŒej                  j                  d ee«      «       Œ; 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mZmZmZ d
ZddddddœZej>                  ZdZ  ejB                  d«      Z"h d£Z# ejB                  d«      Z$ ejB                  dejJ                  «      Z&da'de(fd„Z)defd„Z*defd„Z+defd„Z,defd„Z-defd„Z.defd„Z/defd„Z0defd„Z1defd „Z2de(fd!„Z3d3de(fd"„Z4d3de5fd#„Z6de7fd$„Z8d3de(fd%„Z9de5fd&„Z: G d'„ d(«      Z;de(fd)„Z<d*„ Z=de(fd+„Z>d,„ Z?d-„ Z@d3de(fd.„ZAde(fd/„ZBdefd0„ZCd4defd1„ZDd3defd2„ZEy)5a#  
planner: convierte lo que pide la pantalla en Jobs, SIN tocar la GPU.

La preview y el lanzamiento usan el MISMO objeto: `/api/plan` compone los jobs
y los guarda en memoria; `/api/start` solo ejecuta esos jobs. Asi lo que se ve
es exactamente lo que se genera (D2.7).

Reglas que respeta (las mismas del CLI, no hay una segunda verdad):

- Poses sin repetir mientras queden en el banco; si se agotan, se repite y se
  avisa (`limits`/`blocked`). El limite se cuenta POR NIVEL, que es lo que de
  verdad manda (sugerente/spicy/explicito).
- Una pose por (personaje, stage): se reparten sin reemplazo con un unico
  `Dealer` para todo el lote. Nada de dejar que `compose_stage_jobs` elija solo,
  porque su contador de reuso es por personaje.
- Camara por orden de imagen dentro del personaje (el piloto "Diferent poses":
  from above / from front / from side), no por stage.
- Semilla aleatoria por imagen (`seed=None`); fija solo si se pide a proposito.

    from planner import compose
    plan = compose({"mode": "group", "keys": [...], "stages": [...]})
é    N)Údatetime)ÚPathÚEngineÚArchivos)ÚPromptBuilder)Úload_affinity)ÚSTAGESÚSTAGE_LEVELÚSTAGE_DRESSÚstage_allows_pose)Ú	sugerenteÚspicyÚ	explicitoÚ	SugerentezSpicy 1zSpicy 2u   ExplÃ­cito 1u   ExplÃ­cito 2)r   Úspicy1Úspicy2Ú	explicit1Ú	explicit2)é#   é-   é2   z!\(\s*([^():]*?)\s*:\s*[\d.]+\s*\)>   úmultiple girlsÚboyÚ1boyÚgirlÚmaleÚsoloÚ1girlÚ1otherÚ2girlsÚfemaleÚheteroÚandrogynousz<lora:[^>]*>zy\b(illustrious|illust|illu|ixl|ilxl|il|xl|sdxl|noobai\w*|nvwls|lora|nochekaiser|nyx|goofy|richy|v\d+(\.\d+)?|r\d+|s\d+)\bÚreturnc                  ó¤  — t         €¢i } t        dz  dz  }	 ddl}|j                  dd¬«      5 }|j	                  |«      D ]\  }|j                  d«      xs dj                  «       j                  «       }|sŒ7|j                  d	«      xs dj                  «       | |<   Œ^ 	 ddd«       | a t         S # 1 sw Y   ŒxY w# t        t        f$ r i } Y Œ'w xY w)
zÑ{tag: type} del CSV de Danbooru, cargado una vez por proceso.

    Solo se usa `type`: 4 = personaje, 3 = copyright. Sirve para reconocer el
    nombre real dentro de una linea sin fiarse del triggerword.
    Nr   zDanbooru tags.csvr   z	utf-8-sigÚ )ÚencodingÚnewlineÚtagÚtype)
Ú
_CSV_TYPESÚBASE_DIRÚcsvÚopenÚ
DictReaderÚgetÚstripÚlowerÚOSErrorÚUnicodeDecodeError)ÚtypesÚpathr-   ÚfhÚrowr)   s         úEngine/ui/planner.pyÚ
_tag_typesr:   M   sÈ   € ô ÐØˆÜ˜*Ñ$Ð':Ñ:ˆð	ÛØ—‘ K¸�Ô<ÀØŸ>™>¨"Ö-�CØŸ7™7 5›>Ò/¨R×6Ñ6Ó8×>Ñ>Ó@�CÚØ&)§g¡g¨f£oÒ&;¸×%BÑ%BÓ%D˜˜cš
ñ .÷ =ð ˆ
ÜÐ÷ =Ð<ûô
 Ô+Ð,ò 	ØŠEð	ús/   –B; ­AB/Á6(B/ÂB; Â/B8Â4B; Â;CÃCc                 óT   — t        j                  dd| xs dj                  «       «      S )Nz	[^a-z0-9]r&   )ÚreÚsubr2   ©Útexts    r9   Ú_normr@   d   s"   € Ü�6‰6�,  T¢Z¨R×$6Ñ$6Ó$8Ó9Ð9ó    c                 ó�   — t        j                  dd| xs dj                  dd«      «      j                  «       j	                  «       S )Nú\s+Ú r&   Ú_)r<   r=   Úreplacer1   r2   r>   s    r9   Ú_plainrG   h   s8   € Ü�6‰6�&˜# ¢
¨×3Ñ3°C¸Ó=Ó>×DÑDÓF×LÑLÓNÐNrA   c                 ób   — | j                  dd«      j                  dd«      j                  «       S )Nú\(Ú(ú\)Ú))rF   r1   ©r)   s    r9   Ú
_clean_tagrN   l   s)   € Ø�;‰;�u˜cÓ"×*Ñ*¨5°#Ó6×<Ñ<Ó>Ð>rA   c                 óT   — t        | «      j                  dd«      j                  «       S )NrD   rE   )rN   rF   r2   rM   s    r9   Ú	_csv_formrP   p   s"   € Ü�c‹?×"Ñ" 3¨Ó,×2Ñ2Ó4Ð4rA   c           	      óŽ  — t         j                  d| xs d«      }t        j                  dd|«      }t        j                  dd|«      j                  «       }|j	                  «       D �cg c]9  }|j                  «       st        d„ |dd D «       «      r|n|j                  «       ‘Œ; }}dj                  |«      xs | xs dS c c}w )zAUltimo recurso: `Hoseki_..._IllustriousXL_v2` -> `Hoseki ... V2`.rD   r&   z[_\-.]+rC   c              3   ó<   K  — | ]  }|j                  «       –— Œ y ­w©N©Úisupper©Ú.0Úcs     r9   Ú	<genexpr>z_pretty_key.<locals>.<genexpr>y   s   è ø€ Ð%A¹5°a a§i¡i§k¹5ùó   ‚é   N)	Ú_NAME_NOISEr=   r<   r1   ÚsplitrU   ÚanyÚ
capitalizeÚjoin)Úkeyr?   ÚwÚwordss       r9   Ú_pretty_keyrd   t   s®   € ä�?‰?˜3 ¢	 rÓ*€DÜ�6‰6�*˜c 4Ó(€DÜ�6‰6�&˜#˜tÓ$×*Ñ*Ó,€Dà*.¯*©*¬,ó8Ù*6 Qð —9‘9”;¤#Ñ%A¸1¸Q¸R¹5Ó%AÔ"A‰QØ—,‘,“.ñ!Ø*6ð 
ð 8à�8‰8�E‹?Ò)˜sšy bÐ)ùò8s   Á)>Cc                 ó†   — t        d„ | D «       «      st        j                  d| «      s| S t        j                  dd„ | «      S )zÇ`reze (chainsaw man)` -> `Reze (Chainsaw Man)`.

    Solo toca tags que vienen en minusculas (asi los escribe Danbooru): si el
    nombre ya trae mayusculas o caracteres raros, se deja tal cual.
    c              3   ó<   K  — | ]  }|j                  «       –— Œ y ­wrS   rT   rV   s     r9   rY   z"_titlecase_name.<locals>.<genexpr>„   s   è ø€ Ð
$¡˜1ˆ1�9‰9�;¡ùrZ   z[a-z0-9 ().'\-]+z(^|[\s(])([a-z])c                 ód   — | j                  d«      | j                  d«      j                  «       z   S )Nr[   é   )ÚgroupÚupper)Úms    r9   Ú<lambda>z!_titlecase_name.<locals>.<lambda>ˆ   s"   € ˜AŸG™G A›J¨¯©°«×)9Ñ)9Ó);Ò;rA   )r^   r<   Ú	fullmatchr=   rM   s    r9   Ú_titlecase_namern   ~   sC   € ô Ñ
$¡Ó
$Ô$¬B¯L©LÐ9LØ8;ô-=àˆ
Ü�6‰6Ð%Ù;¸SóBð BrA   c                 óB  — t        «       }t        j                  d| xs d«      j                  d«      D �cg c]"  }|j	                  «       r|j	                  «       ‘Œ$ }}|D ]L  }|j                  «       t        v rŒ|j                  t        |«      «      dk(  sŒ8t        t        |«      «      c S  t        |«      }|D ]Q  }|j                  «       t        v rŒt        |«      }t        |«      dk\  sŒ4||v s||v sŒ=t        t        |«      «      c S  t        |«      S c c}w )z1Nombre visible del personaje, sacado de su linea.r&   Ú,Ú4é   )r:   Ú_LORA_REr=   r]   r1   r2   Ú_GENERIC_TAGSr0   rP   rn   rN   r@   Úlenrd   )Úlinera   r5   ÚtÚtagsr)   ÚknÚtns           r9   Údisplay_namer{   ‹   sõ   € ä‹L€EÜ'Ÿ|™|¨B°²
¸Ó;×AÑAÀ#ÔFó ÑF˜!Ø�w‰wŒyð �G‰G�IÐF€Dð ãˆØ�9‰9‹;œ-Ñ'ØØ�9‰9”Y˜s“^Ó$¨Ó+Ü"¤:¨c£?Ó3Ò3ð	 ô
 
ˆs‹€BÛˆØ�9‰9‹;œ-Ñ'ØÜ�3‹ZˆÜˆr‹7�a‹<˜R 2™X¨¨rªÜ"¤:¨c£?Ó3Ò3ð ô �sÓÐùòs   ¶'Dc                 ó    — t        |«      j                  t        | «      d«      }t        j                  dd|«      j	                  «       }|xs |S )a  Lo que sobra de la clave quitando el nombre: `Makima` + `Makima_v2` -> v2.

    Es lo que se pone entre parentesis cuando dos personajes comparten nombre
    visible (dos LoRAs de Yelan, Makima, Raiden...), para que la lista no
    parezca tener duplicados.
    rD   u
   [\s\-_Â·]+)rG   rF   r<   r=   r1   )Únamera   Útails      r9   Ú_name_suffixr   Ÿ   sC   € ô �#‹;×Ñœv d›|¨SÓ1€DÜ�6‰6�-  dÓ+×1Ñ1Ó3€DØŠ;�3ÐrA   c                 ó¦   — | xs dj                  dd«      j                  dd«      }t        j                  dd|«      }|j                  d«      xs d	S )
a]  Nombre de CARPETA para una clave de personaje.

    `reze \(chainsaw man\)` lleva una barra invertida que Windows lee como
    separador de ruta: `run_dir / key` acaba en `...\reze \(chainsaw man` y
    `mkdir` revienta con WinError 3. La clave sigue siendo la identidad (es la
    que comen los scripts); esto es solo el nombre del directorio.
    r&   rI   rJ   rK   rL   z[\\/:*?"<>|]rE   z .Úchar)rF   r<   r=   r1   )ra   r?   s     r9   Úfs_namer‚   «   sM   € ð ŠI�2×Ñ˜u cÓ*×2Ñ2°5¸#Ó>€DÜ�6‰6�/ 3¨Ó-€DØ�:‰:�dÓÒ%˜vÐ%rA   c            
      óD  — t        t        t        «      «      } t        j                  «       }t        j
                  «       }| ||t        D �ci c]  }|t        j                  |«      “Œ c}t        j                  «       t        j                  «       t        «       dœS c c}w )zÉCarga personajes, banco, pools y temas. Sin GPU y sin cache.

    Se rehace en cada preview a proposito: si editas el pool desde la UI, el
    siguiente plan ya cuenta con las poses nuevas (D2.3).
    )ÚBÚbankÚavoidÚpoolsÚcamerasÚthemesÚaffinity)r   Ústrr,   Ú	pose_bankÚ	load_bankÚ
load_avoidÚLEVELSÚpbÚload_pool_linesÚload_camerasÚload_themesr   )r„   r…   r†   Úlvs       r9   Úload_contextr•   º   s�   € ô 	”cœ(“mÓ$€AÜ×ÑÓ €DÜ× Ñ Ó"€EàØØÝ7=Ó>±v°�"”b×(Ñ(¨Ó,Ñ,°vÑ>Ü—?‘?Ó$Ü—.‘.Ó"Ü!“Oñð ùò ?s   ÁB
c                 ó<   — t        j                  | d   | d   |«      S )zB{nivel: [entradas]} sin blacklisteadas ni vetadas en esta corrida.r…   r†   )ÚbpcÚusable_poses)ÚctxÚskip_idss     r9   r˜   r˜   Î   s   € ä×Ñ˜C ™K¨¨W©°xÓ@Ð@rA   c                 ó  — ddl m}  |«       }|xs
 t        «       }g }| d   j                  «       D ]©  }| d   j	                  |«      xs i }|j                  d«      xs d}t        j                  d|«      }|sd}	n(|r!|j                  d«      j                  «       |v rd	}	nd
}	|j                  |t        ||«      ||j                  d«      |	|	d
k7  ||v dœ«       Œ« i }
|D ]4  }|
j                  |d   j                  «       g «      j                  |«       Œ6 |
j                  «       D ]]  }t        |«      dk  rŒ|D ]G  }t        |d   «      t        |d   «      k7  sŒ!|d   ›dt!        t#        |d   |d   «      «      ›d�|d<   ŒI Œ_ |S )a~  Todos los personajes con las marcas que necesita la pantalla.

    `key` es el ID (lo que comen los scripts), `name` es lo que se pinta y
    `lora_state` dice si el LoRA declarado esta en disco:

        ok      -> el .safetensors existe
        missing -> la linea pide un LoRA que no esta en disco
        none    -> la linea no lleva <lora:> (se resuelve con tags del ckpt)
    r   )Ú
lora_stemsr„   Úbaser&   z<lora:([^:>]+):Únoner[   ÚokÚmissingÚlora)ra   r}   rv   r¡   Ú
lora_stateÚhas_loraÚusedr}   rh   ra   z (rL   )Úcharacter_keysrœ   ÚsetÚget_character_namesÚget_characterr0   r<   Úsearchri   r2   Úappendr{   Ú
setdefaultÚvaluesru   rG   rn   r   )r™   r¤   rœ   Ú	availableÚrowsra   r�   rv   ÚmatchÚstateÚseenr8   ri   s                r9   Ú
charactersr²   Ó   s�  € õ *Ù“€IØŠ=”3“5€DØ€DØ�3‰x×+Ñ+Ö-ˆØ�3‰x×%Ñ% cÓ*Ò0¨bˆØ�x‰x˜ÓÒ% 2ˆÜ—	‘	Ð,¨dÓ3ˆÙØ‰EÙ˜eŸk™k¨!›n×2Ñ2Ó4¸	ÑAØ‰EàˆEØ�‰ØÜ   sÓ+ØØ—H‘H˜VÓ$ØØ Ñ*Ø˜4�Kñ
õ 	ð .ð, €DÛˆØ�‰˜˜F™×)Ñ)Ó+¨RÓ0×7Ñ7¸Õ<ð à—‘–ˆÜˆu‹:˜Š>ØÛˆCÜ�c˜%‘jÓ!¤V¨C°©KÓ%8Ó8Ø+.¨v«;Ü+:¼<Ø/2°6©{¸CÀ¹Jó<Hõ ,IðJ��F’ñ ð ð €KrA   c                  ó*   — t        j                  «       S rS   )r—   Úused_characters© rA   r9   r´   r´     s   € Ü×ÑÓ Ð rA   c                 óJ  — t        | |«      }t        D �ci c]  }|t        ||   «      “Œ }}i }t        D ]F  }t        |   }t        ||   D �cg c]   }t        ||j                  dd«      «      r|‘Œ" c}«      ||<   ŒH ||t        |j                  «       «      dœS c c}w c c}w )zFCuenta de poses usables por nivel y por stage (para el aviso de D2.3).Ú	pose_liner&   )Úby_levelÚby_stageÚtotal)	r˜   r�   ru   r	   r
   r   r0   Úsumr¬   )	r™   rš   Úusabler”   r¸   r¹   ÚstageÚlevelÚes	            r9   Úpose_countsrÀ   	  s¹   € ä˜#˜xÓ(€FÝ.4Ó5©f¨�”C˜˜r™
“OÑ#¨f€HÐ5Ø€HßˆÜ˜EÑ"ˆÜ¨&°ª-ó M©- QÜ"3°EØ45·E±E¸+ÀrÓ4Jô#Lò  !¨-ñ Mó Nˆ�Šð ð
 !¨hÜ˜Ÿ™Ó*Ó+ñ-ð -ùò 6ùòMs   •BÁ%B 
c                 óB  — g }t        | d   xs i j                  «       «      D ]y  \  }}|j                  d«      }t        |j                  d«      xs i j	                  «       «      }|j                  |t        |t        «      xr t        |«      ||t        v dœ«       Œ{ |S )z4Lista de temas con lo justo para pintar el selector.r‰   Úoutfit_storyÚscene)r}   Ú	has_storyÚscenesÚblocked)
ÚsortedÚitemsr0   ÚlistÚkeysrª   Ú
isinstanceÚdictÚboolÚTHEMES_BLOCKED)r™   Úoutr}   ÚthemeÚstoryrÅ   s         r9   Úthemes_metarÒ     s”   € à
€CÜ˜s 8™}Ò2°×9Ñ9Ó;Ö<‰ˆˆeØ—	‘	˜.Ó)ˆÜ�u—y‘y Ó)Ò/¨R×5Ñ5Ó7Ó8ˆØ�
‰
ØÜ# E¬4Ó0Ò@´T¸%³[ØØœ~Ð-ñ	
õ 	ð =ð €JrA   c                   ó   — e Zd ZdZdd„Zd„ Zy)ÚDealerzäReparte poses por stage sin reemplazo; repite solo si se agota.

    Un unico Dealer para TODO el lote: es lo que garantiza que no se repita la
    misma pose entre personajes (el contador de pack_builder es por personaje).
    c                 óª   — || _         || _        t        D �ci c]  }|d“Œ c}| _        t        D �ci c]  }|d“Œ c}| _        g | _        y c c}w c c}w )Nr   )r‡   Úallow_repeatr�   ÚptrÚcycleÚrepeated)Úselfr‡   rÖ   r”   s       r9   Ú__init__zDealer.__init__/  sT   € ØˆŒ
Ø(ˆÔÝ$*Ó+¡F˜b�B˜‘E FÑ+ˆŒÝ&,Ó-¡f �b˜!‘e fÑ-ˆŒ
Øˆ�ùò ,ùÚ-s
   —
A±
Ac           
      óÐ  — t         |   }| j                  j                  |«      xs g }| j                  |   t	        |«      k  rc|| j                  |      }| j                  |xx   dz  cc<   t        ||j                  dd«      «      r|S | j                  |   t	        |«      k  rŒc|D �cg c]   }t        ||j                  dd«      «      r|‘Œ" }}|st        d|›d|›�«      ‚| j                  st        d|z  «      ‚|| j                  |   t	        |«      z     }| j                  |xx   dz  cc<   | j                  j                  ||j                  d«      dœ«       |S c c}w )	Nr[   r·   r&   zno queda ninguna pose de 'z' valida para z*se acabo el banco de '%s' sin repetir poseÚid)r½   Úpose_id)r
   r‡   r0   r×   ru   r   Ú
ValueErrorrÖ   rØ   rÙ   rª   )rÚ   r½   r¾   ÚpoolÚentryr¿   Úalloweds          r9   ÚtakezDealer.take6  sM  € Ü˜EÑ"ˆØ�z‰z�~‰~˜eÓ$Ò*¨ˆØ�h‰h�u‰o¤ D£	Ò)Ø˜Ÿ™ %™Ñ)ˆEØ�H‰H�U‹O˜qÑ ‹OÜ  ¨¯	©	°+¸rÓ(BÔCØ�ð	 �h‰h�u‰o¤ D£	Ó)ñ
 #ó H™d˜Ü'¨¨q¯u©u°[À"Ó/EÔFò ˜dˆð HáÝÚ %¡uð.ó /ð /à× Ò ÜÐIÈEÑQÓRÐRØ˜Ÿ
™
 5Ñ)¬C°«LÑ8Ñ9ˆØ�
‰
�5Ó˜QÑÓØ�‰×Ñ u¸¿¹À4»ÑIÔJØˆùòHs   Â+%E#N)T)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rÛ   rã   rµ   rA   r9   rÔ   rÔ   (  s   „ ñóórA   rÔ   c                 ó  — t         D �ci c]  }|d“Œ }}t         D �cg c]  }|t        | «      v sŒ|‘Œ } }| s|S t        t        |«      t	        | «      «      \  }}t        | «      D ]  \  }}|||k  rdndz   ||<   Œ |S c c}w c c}w )zDReparte `total` entre los stages marcados; el resto, a los primeros.r   r[   )r	   r¦   ÚdivmodÚintru   Ú	enumerate)Ústagesrº   r½   ÚquotasÚsr�   ÚrestÚis           r9   Ú_even_quotasrñ   K  s�   € å$*Ó+¡F˜5ˆe�Q‰h F€FÐ+ÝÓ4™�A 1¬¨F«Ò#3Ša˜€FÐ4ÙØˆÜœ˜E›
¤C¨£KÓ0�J€Dˆ$Ü˜fÖ%‰ˆˆ5Ø Q¨¢X¡°1Ñ5ˆˆuŠð &à€Mùò ,ùÚ4s   ‰
A?�B°Bc                 ó†  — g }|D ]–  \  }}|sŒ	|t        |«      i}	t        j                  |gt        |«      t        D �
ci c]  }
|
d“Œ c}
di dd| d   | d   | d   | d   |d	|D �cg c]  }|j	                  d
«      ‘Œ c}|	d|| d   ¬«      }|j                  |«       Œ˜ t        j                  || d   «       |S c c}
w c c}w )z×Jobs de un personaje: una llamada a compose por stage.

    Se hace por stage y no de golpe porque `bank_ids` fija la pose por NIVEL:
    con spicy1 y spicy2 en la misma llamada, los dos cogerian la misma pose.
    r   z	per-imageÚautog        r…   r†   r‡   rˆ   r[   rÝ   TrŠ   )Úmax_variantsÚbank_idsÚstage_quotasÚallow_legacy_outfitÚstrict_scenerŠ   )ru   r�   Úcompose_theme_jobsr�   r0   ÚextendÚassign_cameras)r™   Ú	char_linerÐ   Ústage_posesÚrngrø   Újobsr½   Úposesrí   r”   ÚpÚgots                r9   Ú_compose_charr  Y  sÝ   € ð €DÛ#‰ˆˆuÙØØœ˜U›Ð$ˆÜ×#Ñ#ØˆG”S˜“Zµ&Ó!9±&¨B " a¡%°&Ñ!9¸;ÈØ�C˜˜V™ c¨'¡l°C¸±LØ�	‰N˜C¨aÙ+0Ó1©5 a�a—e‘e˜D•k¨5Ñ1Ø°TØ%°°J±ôAˆð 	�‰�CÕð $ô ×Ñ�d˜C 	™NÔ+Ø€Kùò ":ùò 2s   ¾
B9Á$B>$c                 ó~  — | xs i } | j                  d«      xs d}|dvrt        d|z  «      ‚| j                  d«      xs g D �cg c]  }|t        v sŒ|‘Œ }}|st        d«      ‚t        D �cg c]  }|t        |«      v sŒ|‘Œ }}| j                  d«      }	 |dvrt	        |«      nd	}|dk(  r|dk  rt        d«      ‚| j                  d«      }|dv rd }n	 t	        |«      }| j                  d«      }	 |dvrt	        |«      nd }|| j                  d«      xs g D �cg c]'  }t        |«      j                  «       sŒt        |«      ‘Œ) c}t	        | j                  d«      xs d«      t        | j                  d«      «      ||| j                  d«      xs dj                  «       xs d ||t        | j                  d«      «      t        | j                  d«      «      | j                  d«      xs g D �cg c]4  }t        |«      j                  «       rt        |«      j                  «       ‘Œ6 c}dœS c c}w c c}w # t
        t        f$ r t        d
| j                  d«      z  «      ‚w xY w# t
        t        f$ r t        d| j                  d«      z  «      ‚w xY w# t
        t        f$ r d }Y �Œ«w xY wc c}w c c}w )NÚmodeÚpack)r  ri   zmode desconocido: %rrì   zmarca al menos un stagerº   )Nr&   r   ztotal de imagenes no entero: %rr[   z"el total de imagenes debe ser >= 1Úseed)r&   Nzsemilla no entera: %rÚ	pick_seedrÊ   Úcountr   Úexclude_usedrÐ   r&   rÖ   rø   Úexclude_poses)r  rÊ   r	  r
  rì   rº   rÐ   r  r  rÖ   rø   r  )	r0   rß   r	   r¦   rê   Ú	TypeErrorr‹   r1   rÍ   )	Úrawr  rî   rì   rº   r  r  ÚkÚxs	            r9   Ú_specr  q  s´  € Ø
Š)�€CØ�7‰7�6‹?Ò$˜f€DØÐ$Ñ$ÜÐ/°$Ñ6Ó7Ð7ØŸ'™' (Ó+Ò1¨rÐ1ÓBÑ1�A°a¼6²kŠaÐ1€FÐBÙÜÐ2Ó3Ð3ÝÓ4™�A 1¬¨F«Ò#3Ša˜€FÐ4Ø�G‰G�GÓ€EðOØ#¨:Ñ5”�E”
¸2ˆð ˆv‚~˜% !š)ÜÐ=Ó>Ð>Ø�7‰7�6‹?€DØˆzÑØ‰ð	HÜ�t“9ˆDð —‘˜Ó$€IðØ&/°zÑ&A”C˜	”NÀtˆ	ð Ø"%§'¡'¨&£/Ò"7°RÐ"7ÓKÑ"7˜A¼CÀ»F¿L¹L½N”�Q•Ð"7ÑKÜ�S—W‘W˜WÓ%Ò*¨Ó+Ü˜SŸW™W ^Ó4Ó5ØØØ—'‘'˜'Ó"Ò( b×/Ñ/Ó1Ò9°TØØÜ˜SŸW™W ^Ó4Ó5Ü˜SŸW™W ^Ó4Ó5àŸ7™7 ?Ó3Ò9°rÐ9óNÙ9ð ./Ü>AÀ!»f¿l¹l¼nô ˜a›&Ÿ,™,�.Ø9ñNñð ùò1 Cùò 5øô ”zÐ"ò OÜÐ:¸S¿W¹WÀWÓ=MÑMÓNÐNðOûô œ:Ð&ò 	HÜÐ4°s·w±w¸v³ÑFÓGÐGð	Hûô
 ”zÐ"ò Ø‹	ðüò LùòNsT   ÁH3ÁH3Á.H8ÂH8ÂH= ÃI- Ã5J ÄJ5Ä=J5Ç59J:È=-I*É--JÊJ2Ê1J2c           	      óª  — g }t        | |«      D �ci c]  }|d   |“Œ
 }}|d   dk(  rz|d   xs dgd   }|st        d«      ‚||vrt        d|z  «      ‚|g}||   d	   }	|	d
k(  r|j                  d||   d   z  «       �nK|	dk(  �rE|j                  d||   d   z  «       �n)|d   r�|d   D �
cg c]	  }
|
|vsŒ|
‘Œ }}
|rt        ddj                  |«      z  «      ‚|d   }|D �
cg c]  }
||
   d	   d
k(  r||
   d   ‘Œ }}
|rÇ|j                  ddj                  |«      z  «       n£t	        |d   xs d«      }|dk  rt        d«      ‚|j                  «       D �
�cg c]  \  }
}|d   r|d   r|d   s|
‘Œ }}
}|j                  |«       |t        |«      kD  r|j                  d|t        |«      fz  «       |d| }|st        d«      ‚|d   dk(  rJ|d   xs* |j                  | d   D �cg c]  }|t        vr|‘Œ c}«      }|| d   vrt        d|z  «      ‚|g}nÎ|d   r.|d   | d   vrt        d|d   z  «      ‚|d   gt        |«      z  }n›| d   D �cg c]  }|t        vsŒ|‘Œ }}|j                  |«       t        |«      t        |«      kD  r(|j                  dt        |«      t        |«      fz  «       t        t        |«      «      D �cg c]  }||t        |«      z     ‘Œ }}g }t        ||«      D ]1  \  }}|j                  |||   d   t        |«      ||   d   |dœ«       Œ3 ||fS c c}w c c}
w c c}
w c c}}
w c c}w c c}w c c}w ) u<   -> ([{char, char_line, theme}], avisos) segun modo/pestaÃ±a.ra   r  r  rÊ   Nr   zelige un personajez'%s' no esta en personajes.txtr¢   r    zV%s pide un LoRA que no esta en disco: saldra con el aspecto por defecto del checkpointr}   rž   zD%s no lleva <lora:>: el personaje depende de los tags del checkpointzno estan en personajes.txt: %sú, zLoRA ausente en disco: %sr	  r[   z!indica cuantos personajes sortearr£   r
  r¤   z.pedias %d personajes y solo hay %d disponiblesz9no hay personajes disponibles (quita el filtro de usados)rÐ   r‰   zel tema '%s' no existez3pedias %d temas distintos y solo hay %d: se repitenrv   )r�   Ú	char_nameÚdirrü   rÐ   )r²   rß   rª   r`   rê   rÈ   Úshuffleru   ÚchoicerÎ   ÚrangeÚzipr‚   )r™   Úspecrþ   r¤   ÚwarningsrX   Úinfora   rÈ   r°   r  r    Úmissing_lorar	  rà   rw   rÐ   r‰   rð   rÏ   s                       r9   Ú_pick_itemsr  Ÿ  s  € à€HÜ!+¨C°Ô!6Ó7Ñ!6˜AˆAˆe‰H�a‰KÐ!6€DÐ7àˆF�|�vÒØ�F‰|Ò% ˜v qÑ)ˆÙÜÐ1Ó2Ð2Ø�d‰?ÜÐ=ÀÑCÓDÐDØ�ˆØ�S‘	˜,Ñ'ˆØ�IÒØ�O‰Oð Dà" 3™i¨Ñ/ñ0ö 1ð �f‹_Ø�O‰Oð 2Ø48¸±I¸fÑ4EñFö Gð �Š<Ø"& v¢,Ó@¡,˜Q°!¸4²-’q ,ˆGÐ@ÙÜ Ð!AØ#'§9¡9¨WÓ#5ñ"6ó 7ð 7à˜‘LˆEÙ5:ó C±U°Ø# A™w |Ñ4¸	ÒAð ! ™G F›O°UˆLð CáØ—‘Ð ;Ø"&§)¡)¨LÓ"9ñ!:õ ;ô ˜˜W™Ò*¨Ó+ˆEØ�qŠyÜ Ð!DÓEÐEØ"&§*¡*¤,ô @¡,™$˜!˜QØ˜’}¨t°NÒ/CØ34°V²9ò  ,ˆDñ @ð �K‰K˜ÔØ”s˜4“yÒ Ø—‘Ð PØ#(¬#¨d«)Ð"4ñ!5ô 6à˜˜%�LˆEÙÜ ð "?ó @ð @ð ˆF�|�vÒØ�W‘ò J §¡¸¸Hºó -I¹°1Ø01¼Ñ0Gò ./¸ñ -Ió "Jˆà˜˜H™Ñ%ÜÐ5¸Ñ=Ó>Ð>Ø�‰à�Š=Ø�G‰} C¨¡MÑ1Ü Ð!9¸DÀ¹MÑ!IÓJÐJØ˜7‘m�_¤s¨5£zÑ1‰Fà" 8š}ÓH™}˜!°¼Ò0G’A˜}ˆDÐHØ�K‰K˜ÔÜ�5‹zœC ›IÒ%Ø—‘ð !-Ü03°E³
¼CÀ»IÐ/Fñ!Gô Hä38¼¸U»Ô3DÓEÑ3D¨a�d˜1œs 4›y™=Ó)Ð3DˆFÐEà
€CÜ˜% Ö(‰
ˆˆUØ�
‰
˜C¨d°3©i¸Ñ.?Ü" 3›<Ø!% c¡¨6Ñ!2¸UñDõ 	Eð )ð �ˆ=ÐùòK 8ùò& Aùò
Cùó@ùò-Iùò Iùò
 Fs5   ‘L1Â.	L6Â8L6Ã&L;ÅM Ç,MÉMÉ%MËMc           	      óè  — g }| j                  «       }dD ]e  \  }}t        t        j                  ||«      «      }|dk(  r|j	                  |dk(  rdndd|z  dœ«       ŒI|dkD  sŒO|j	                  dd|z  dœ«       Œg d	|vrd
|vr|j	                  dddœ«       | j                  d«      D �cg c]  }|j                  «       ‘Œ }	}|j	                  t        |	«      dk\  rdnddt        |	«      z  dœ«       d|vr|j	                  dddœ«       |j                  j                  «       s|j	                  dddœ«       t        j                  |j                  xs d«      r|j	                  dddœ«       t        j                  d|«      r|j	                  dddœ«       |	D �
�cg c]F  }
|
j                  d«      D ]0  }|j                  «       r|j                  «       j                  «       ‘Œ2 ŒH }}
}h d£}t        |D �ch c]  }|j                  |«      dkD  r||vr|’Œ c}«      }|r)|j	                  dddj                  |dd «      z  dœ«       t        |«      dkD  r |j	                  ddt        |«      z  dœ«       |j                  dv r7|j                  s|j	                  dd dœ«       n|s|j	                  dd!dœ«       |j                  s|j	                  dd"dœ«       |S c c}w c c}}
w c c}w )#z8Validaciones de la preview (D2.7). -> [{'level','text'}]))z	\b1girl\br   )z\b1boy\br   r   r[   rŸ   Úerrz	1girl x%d)r¾   r?   z1boy x%d (sale otro hombre)r   r   Úwarnz1girl sin `solo`ÚBREAKrr   z%d tramos BREAKz<lora:z sin <lora:> (personaje generico)z
pose vaciar&   z*pesos en la pose: el ensamblador los borraz(^|, )\s*no\s+[a-z]z!`no X` en el positivo: refuerza Xrp   >   r   Únuder   r   ÚnakedÚcompletely_nudeztags duplicados: %sr  Né   éA   z%d tags (diluye))ÚdressedÚ	strippingÚlingerieÚclothedzvestida pero sin outfitz#tema sin outfit_story (ropa legacy)z
sin camara)r2   ru   r<   Úfindallrª   r]   r1   r·   Ú
_WEIGHT_REr©   rÇ   r	  r`   ÚdressÚoutfit_lineÚcamera)ÚpromptÚjobÚtheme_has_storyrÏ   ÚlowÚtokenÚlabelÚnrî   ÚsegmentsÚsegrw   rx   ÚharmlessÚdupess                  r9   Ú_checksr;  ê  sÊ  € à
€CØ
�,‰,‹.€CÛH‰ˆˆuÜ”—
‘
˜5 #Ó&Ó'ˆØ�GÒØ�J‰J¨¨aª¡°UØ +¨a¡ñ1õ 2à�‹UØ�J‰J Ð0MÐPQÑ0QÑRÕSð Ið �SÑ˜V¨3Ñ.Ø�
‰
˜VÐ-?Ñ@ÔAØ#)§<¡<°Ô#8Ó9Ñ#8˜a�—‘•	Ð#8€HÐ9Ø‡J�J¤ X£°!Ò!3™¸Ø)¬C°«MÑ9ñ;ô <à�sÑØ�
‰
˜UÐ,NÑOÔPØ�=‰=×ÑÔ Ø�
‰
˜U¨LÑ9Ô:Ü×Ñ˜Ÿ™Ò,¨"Ô-Ø�
‰
˜VØHñJô 	Kä	‡y�yÐ'¨Ô-Ø�
‰
˜UØ?ñAô 	Bá)1ô © #¸3¿9¹9ÀS¾>°aØ�w‰wŒyð �G‰G‹I�O‰OÕ¸>Ð¨€Dñ âL€HÜ™tó @™t˜!Ø—z‘z !“} qÒ(¨Q°hÑ->ò ˜tñ @ó A€EáØ�
‰
˜VØ1°D·I±I¸eÀBÀQ¸iÓ4HÑHñJô 	Kä
ˆ4ƒy�2‚~Ø�
‰
˜VÐ-?Ä#ÀdÃ)Ñ-KÑLÔMØ
‡y�yÐCÑCØ�ŠØ�J‰J Ð1JÑKÕLÙ Ø�J‰J Ø EñGô Hà�:Š:Ø�
‰
˜V¨\Ñ:Ô;Ø€Jùò? :ùóùò@s   Â,K$Æ!AK)Ç<!K/c                 óÐ  ‡— t        | «      }t        «       }|€|d   s|d   dk(  r
t        «       }|d   }|€t        j                  dd«      }t        j
                  |«      }t        ||||xs
 t        «       «      \  }}t        ||d   «      Št        D ]  }|j                  ‰|   «       Œ t        ˆfd„t        D «       «      st        d	«      ‚|d   d
k(  rt        |d   |d   «      }	nt        D �
ci c]  }
|
|
|d   v rdnd“Œ }	}
t        ‰d¬«      }g }d}|D ]Ô  }g }|d   D ]S  }
|	j!                  |
d«      }|dk  rŒ|j#                  |
t%        |«      D �cg c]  }|j'                  |
«      ‘Œ c}f«       ŒU t)        d„ |D «       «      }t+        ||d   |d   |||d   «      }t-        |«      |k7  r||t-        |«      z
  z  }|j#                  i |¥|D ��cg c]  \  }}|‘Œ	 c}}|dœ¥«       ŒÖ ||||	dœ}t/        ||«      }|d   j1                  |«       |r|d   j#                  d|z  «       |j2                  r|d   sd|d<   d|d   z  |d<   ||dœS c c}
w c c}w c c}}w )zµ-> plan completo (items con Jobs reales) + preview serializable.

    No genera nada. Lanza `ValueError` con un mensaje legible si la peticion
    no se puede cumplir tal cual.
    r
  r  ri   r  r[   iÿÿÿr  c              3   ó(   •K  — | ]	  }‰|   –— Œ y ­wrS   rµ   )rW   r”   r¼   s     €r9   rY   zcompose.<locals>.<genexpr>-  s   øè ø€ Ð+¡F˜bˆv�b�z¡Fùs   ƒzel banco no tiene poses usablesr  rì   rº   r   T)rÖ   c              3   ó8   K  — | ]  \  }}t        |«      –— Œ y ­wrS   )ru   )rW   rE   r  s      r9   rY   zcompose.<locals>.<genexpr>@  s   è ø€ Ð6©+¡$ ! Q”s˜1—v©+ùs   ‚rü   rÐ   rø   )rì   rÿ   )r  rÈ   r  rí   r  uH   %d imagen(es) descartadas por poseâ†”escena conflictiva (--strict-scene)rÖ   rÆ   z`el banco no da para %d imagenes sin repetir pose; marca 'permitir repetir poses' o baja el totalÚblocked_reason)ÚplanÚpreview)r  r•   r´   ÚrandomÚrandintÚRandomr  r¦   r˜   r�   r  r^   rß   rñ   r	   rÔ   r0   rª   r  rã   r»   r  ru   Ú
preview_ofrú   rÙ   )Úraw_specr¤   r  r™   r  rþ   r�   r  r”   rí   r½   ÚdealerrÈ   Úmissing_jobsrá   rý   r6  rE   Úexpectedrÿ   rî   r@  rA  r¼   s                          @r9   ÚcomposerJ    sÐ  ø€ ô �‹?€DÜ
‹.€CØ€|˜˜nÒ-°°f±ÀÒ1HÜÓ ˆØ�[Ñ!€IØÐÜ—N‘N 1 iÓ0ˆ	Ü
�-‰-˜	Ó
"€Cä   d¨C°²¼»Ó?�N€Dˆ(Ü˜#˜t OÑ4Ó5€FßˆØ�‰�F˜2‘JÕð ô Ó+¥FÓ+Ô+ÜÐ:Ó;Ð;àˆF�|�vÒÜ˜d 8™n¨d°7©mÓ<‰õ  &ó'Ù%�eð ˜u¨¨X©Ñ6™!¸AÑ=Ø%ð 	ð 'ô �F¨Ô.€FØ€EØ€LÛˆØˆØ˜(”^ˆEØ—
‘
˜5 !Ó$ˆAØ�AŠvØØ×Ñ ÄEÈ!ÄHÓ'MÁH¸q¨¯©°EÕ(:ÀHÑ'MÐNÕOð	 $ô
 Ñ6©+Ó6Ó6ˆÜ˜S %¨Ñ"4°e¸G±nØ(¨#¨t°NÑ/CóEˆäˆt‹9˜Ò Ø˜H¤s¨4£yÑ0Ñ0ˆLØ�‰ð $˜ð $¹Ô)D¹±°°1ª!¸Ò)DØ"ò$õ 	%ð ð  ØØØñ	€Dô ˜˜dÓ#€GØˆJÑ×Ñ˜xÔ(ÙØ�
Ñ×"Ñ"ðØ!-ñ.ô	/ð ‡‚˜t NÒ3Ø!ˆ�	Ñð7à�gÑñð 	Ð Ñ!ð  WÑ-Ð-ùòO'ùò (Nùó *Es   Ã3IÅIÇI"c                 óX  — |d   }t         D �ci c]  }|d“Œ }}d}g }|d   D �]Ú  }| d   j                  |d   «      xs i }t        |j                  d«      t        «      xr t	        |j                  d«      «      }	g }
|d   D �]?  }t        j                  | d   j                  |d	   |«      }|j                  |j                  d«      d
z   ||j                  <   |d
z  }|
j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  j                  d«      |j                   |j                  j                  d«      |j                  j                  d«      |j"                  |t%        |||	«      t'        |j(                  «      |j*                  dœ«       �ŒB |j                  |d   |j                  d«      xs |d   |d   |	|d   |
dœ«       �ŒÝ t-        | |d   «      }|d   }g }d}d}t         D ]‹  }|j                  |d«      }||j                  |d«      k  }|j                  |||j                  |d«      |dœ«       |dkD  r|s|€|}|dkD  sŒa|sŒd|j                  |d«      |z  |z  }|€|nt/        ||«      }Œ� d}|d   dk(  rot         D �ci c]  }|d“Œ }}|d   D ]  }|t0        |   xx   d
z  cc<   Œ d}t         D ]0  }||   sŒ	|j                  |d«      ||   z  }|€|nt/        ||«      }Œ2 d}g }|�'|j                  d||j                  |d«      |fz  «       d}|dk(  rd}|d   |d   |d   |t3        |«      ||||d   |�t5        |«      nd|dœ|du||d   |d    |d!   |d"   d#œS c c}w c c}w )$z7Vista serializable del plan (lo que pinta la pantalla).r  r   rÈ   r‰   rÐ   rÂ   rÿ   r„   rü   r[   ÚoutfitrÃ   Úlighting)r½   ÚnivelrÞ   r·   r/  r-  rL  r.  rÃ   rM  Úoriginr0  Úchecksr  r  r�   r  rì   )r�   r}   rÐ   rÄ   rì   Úimagesr  r¸   N)r¾   ÚneedÚavailrŸ   rQ  r  ri   ÚcharszQ%d imagenes: el banco solo tiene %d poses de %s usables, asi que habra repeticionzel plan sale vacior¹   )Úlevelsr¹   Úno_repeat_maxÚno_repeat_unitr  r  rí   rÖ   )r  rì   rÐ   rº   rT  rÈ   r  ÚlimitsrÆ   r?  r  r  rí   rÖ   )r�   r0   rË   rÌ   rÍ   r�   Úbuild_run_promptÚmaster_promptrN  rª   r½   rÞ   r·   r/  r-  Úvariant_keysr.  rO  r;  rÉ   Úpose_scene_warningsr  rÀ   Úminr
   ru   rê   )r™   r@  r  r”   r¸   rº   Ú	items_outÚitemrÐ   rÄ   rQ  r1  r0  ÚcountsrS  rX  Ú
bottleneckÚ	max_totalrR  rŸ   ÚroomÚunitÚper_charr½   r  r?  s                             r9   rE  rE  ]  s  € à�‰<€DÝ &Ó'¡˜"��A‘ €HÐ'Ø€EØ€IØ�W•ˆØ�H‘×!Ñ! $ w¡-Ó0Ò6°BˆÜ˜uŸy™y¨Ó8¼$Ó?ò 'ÄDØ�I‰I�nÓ%óE'ˆ	àˆØ˜•<ˆCÜ×(Ñ(¨¨S©×)?Ñ)?Ø)-¨kÑ):¸CóAˆFà"*§,¡,¨s¯y©y¸!Ó"<¸qÑ"@ˆH�S—Y‘YÑØ�Q‰JˆEØ�M‰MØŸ™ØŸ™ØŸ;™;Ø Ÿ]™]ØŸ*™*ØŸ™Ø×*Ñ*×.Ñ.¨xÓ8Ø"Ÿ™Ø×)Ñ)×-Ñ-¨gÓ6Ø×,Ñ,×0Ñ0°Ó<ØŸ*™*Ø Ü! &¨#¨yÓ9Ü  ×!8Ñ!8Ó9ØŸ™ñö ð  ð, 	×ÑØ˜‘LØ—H‘H˜[Ó)Ò9¨T°&©\Ø˜'‘]Ø"Ø˜8‘nØñ
ö 	ð7 ôH ˜˜d ?Ñ3Ó4€FØ�:Ñ€EØ€FØ€JØ€IßˆØ�|‰|˜B Ó"ˆØ�U—Y‘Y˜r 1Ó%Ñ%ˆØ�‰ ¨D¸5¿9¹9ÀRÈÓ;KØñ!ô 	"à�!Š8™B :Ð#5ØˆJØ�!‹8šØ—9‘9˜R Ó# eÑ+¨dÑ2ˆDØ )Ð 1™´s¸9ÀdÓ7K‰Ið ð €DØˆF�|�wÒå$*Ó+¡F˜b�B˜‘E FˆÐ+Ø˜(”^ˆEØ”[ Ñ'Ó(¨AÑ-Ô(ð $àˆ	ßˆBØ˜B’<ØØ—9‘9˜R Ó# x°¡|Ñ3ˆDØ )Ð 1™´s¸9ÀdÓ7K‰Ið	 ð
 ˆà€HØÐØ�‰ðØ"'¨¯©°:¸qÓ)AÀ:Ð!NñOô	Pð €NØ�‚zØ-ˆà�V‘Ø�x‘.Ø�g‘ØÜ�Y“ØØàØ˜zÑ*Ø/8Ð/DœS œ^È$Ø"ñ	
ð "¨Ð-Ø(Ø˜+Ñ&Ø�V‘Ø�x‘.Ø˜^Ñ,ñ'ð ùò[ (ùòt ,s   Ž
N"Ë
N'c                 ó\   — | xs dd t        dt        |«      «       j                  d«      } | S )Nr&   r   z ._-+)Úmaxrê   Úrstrip)r?   Úsizes     r9   Ú_cliprj  Ä  s.   € ØŠJ�BÐ*œ˜Q¤ D£	Ó*Ð+×2Ñ2°7Ó;€DØ€KrA   c                 óž  — | j                  d«      xs g }g g }}|D ]X  }|j                  d«      r|d   |vr|j                  |d   «       |j                  d«      }|sŒC||vsŒH|j                  |«       ŒZ t        |«      dk(  r|d   }n4t        |«      dk(  r|d   ›d|d   ›�}ndt        dt        |«      «      z  }dj	                  |d	d «      }	t        |«      dkD  r|	d
t        |«      dz
  z  z  }	|xs t        j                  «       j                  d«      }
|t        |
«      z
  dz
  }t        |	t        dt        d|dz
  «      «      «      }	t        |t        d||	rt        |	«      dz   ndz
  «      «      }||	|
fD �cg c]  }|sŒ|‘Œ	 }}t        dj	                  |«      j                  dd«      «      d	| j                  d«      S c c}w )ap  Nombre legible de carpeta: `<personaje>_<ambiente>_<fecha>`.

    - 1 personaje  -> `Reze_(Chainsaw_Man)_locker_room_20261030_215533`
    - 2 personajes -> `A-B_<ambiente>_<fecha>`
    - mas          -> `grupoN_<2 ambientes>+N_<fecha>` (N personajes no caben)

    Sustituye al viejo `<stamp>_<plan_id>` (D2.15). El `plan_id` sigue siendo
    el ID interno del plan; esto es solo el nombre del directorio. Se sanea con
    `fs_name` (`Reze` lleva `\(`) y los espacios pasan a `_` para poder
    escribirlo en la consola sin comillas. La **fecha nunca se recorta**: si no
    cabe, se acortan el personaje y el ambiente.
    rÈ   r}   rÐ   r[   r   rh   Ú-zgrupo%dNz+%dz%Y%m%d_%H%M%Sé   é   rE   rD   z ._)r0   rª   ru   rg  r`   r   ÚnowÚstrftimerj  r]  r‚   rF   rh  )rA  ÚwhenÚlimitrÈ   Únamesr‰   r_  rÐ   ÚwhoÚambÚstampÚbudgetr  Úpartss                 r9   Ú	run_labelry  É  s¹  € ð �K‰K˜Ó Ò& B€EØ˜ˆ6€EÛˆØ�8‰8�FÔ  V¡°EÑ 9Ø�L‰L˜˜f™Ô&Ø—‘˜Ó!ˆÚ�U &Ò(Ø�M‰M˜%Õ ð ô ˆ5ƒz�Q‚Ø�A‰h‰Ü	ˆU‹�qŠØ˜q› 5¨¢8Ð,‰àœ#˜a¤ U£Ó,Ñ,ˆà
�(‰(�6˜"˜1�:Ó
€CÜ
ˆ6ƒ{�Q‚Øˆuœ˜F› a™Ñ(Ñ(ˆàÒ#”X—\‘\“^×-Ñ-¨oÓ>€EØ”S˜“ZÑ !Ñ#€FÜ
�”S˜œS  F¨Q¡JÓ/Ó0Ó
1€CÜ
�”S˜˜F±c¤c¨#£h°¢l¸qÑAÓBÓ
C€Cà˜c 5Ñ)Ó/Ñ)�1ªQŠQÐ)€EÐ/Ü�3—8‘8˜E“?×*Ñ*¨3°Ó4Ó5°f°uÐ=×DÑDÀUÓKÐKùò 0s   Æ G
ÆG
c                 ó°   — t        ||«      }t        | «      |z  }d}|j                  «       r)t        | «      d||fz  z  }|dz  }|j                  «       rŒ)|S )zH`run_label()` garantizando que la carpeta no existe (sufijo `_2`, `_3`).rh   z%s_%dr[   )ry  r   Úexists)ÚrootrA  rq  r5  r6   r6  s         r9   Úunique_run_dirr}  ò  s\   € ä�g˜tÓ$€EÜ�‹:˜Ñ€DØ	€AØ
�+‰+Œ-Ü�D‹z˜W¨¨q zÑ1Ñ2ˆØ	ˆQ‰ˆð �+‰+�-ð €KrA   rS   )NéN   )Frç   rB  r<   Úsysr   Úpathlibr   Ú__file__ÚresolveÚparentr,   Ú_extrar‹   r6   ÚinsertrŒ   Úpack_builderr�   Úbatch_poses_charsr—   Úprompt_builderr   Ú
pose_scener   rì   r	   r
   r   r   r�   ÚSTAGE_TITLErÎ   ÚPACK_PRESETSÚcompiler,  rt   rs   ÚIr\   r+   rÌ   r:   r@   rG   rN   rP   rd   rn   r{   r   r‚   r•   r˜   rÉ   r²   r¦   r´   rÀ   rÒ   rÔ   rñ   r  r  r  r;  rJ  rE  rj  ry  r}  rµ   rA   r9   Ú<module>rŽ     s[  ðñó, Û 	Û 
Ý Ý á�‹>×!Ñ!Ó#×*Ñ*×1Ñ1×8Ñ8€Ø˜(Ñ" H¨zÑ$9Ó:€FÙ
ˆ6ƒ{˜#Ÿ(™(Ò"Ø�‰�‰˜™3˜v›;Õ'ð ;ó Û Û Ý (Ý $÷'ó 'ð 
-€ð ØØØØñ€ð ×#Ñ#€ð €àˆR�Z‰ZÐ<Ó=€
òN€àˆ2�:‰:�oÓ&€Øˆb�j‰jð=Ø>@¿d¹dóD€ð €
ð�Dó ð.:�3ó :ðO�Có Oð?�só ?ð5�có 5ð*˜ó *ð
B˜Có 
Bð˜só ð(	˜só 	ð
&�Có 
&ð�dó ñ(A¨ó Añ
/ $ó /ðd!˜ó !ñ- tó -ð˜ó ÷" ñ  ðF	 4ó 	òð0+�$ó +ò\HòV,ñ^A. Dó A.ðHd˜Tó dðN˜ó ñ
&L¨só &LñR°ô rA   