
    ]Sjj              
       \   d Z ddlZddlZddlZddlZddlmZ  ee      j                  Z
ej                  j                  d ee
             ddlZddlZddlZe
Zedz  dz  Zedz  dz  dz  Zedz  dz  dz  Zedz  Zd	Z ej4                   eed
z  dz              Zed   D  ci c]  } | d   | d   f|  c} Zed   D  cg c]  } d| d    d| d     c} Zd Zd Z d Z!d Z"d Z#d Z$dhZ%d Z&d Z'd Z(d Z)d Z*e+dk(  r ejX                         Z-e-j]                  ddg d !       e-j]                  d"d#$       e-j_                         Z0e0jb                  je                  d%      D cg c]  }|s|	 c}Z3 d& d' d( d) d* d+ d, d- d e0jh                             yyc c} w c c} w c c}w ).uU  s35 — 프로젝트 전체 선택 샷(58) 풀 런 (2026-07-12, 실험 전용·커밋 금지).

v24s 로직을 전체 샷에 적용:
①LLM 장소 그룹핑(전 샷 → 장소 연속 그룹 + 그룹 장소 서술 EN)
②그룹별 동선 분석(EN, s34 계약 재사용)
③그룹 샷을 ≤6개 시트로 청킹 → i2 콘티(v24 계약) ④그리드 크롭
⑤그룹별 prev 시각 관련성 판정 ⑥샷별 콘티 필요 판정(쉬운 구도 제거)
⑦nb2 스틸 58샷 — 참조=선별 콘티 패널(참조 전용)+prev 스틸+VE 엔티티
  (캐릭터 composite+소품, 배경 제외)+REALIZE+LOCATION lock+시간 잠금
⑧stills_run_full.html — 샷별 참조 이미지 전부+프롬프트 전문 기록.

사용: backend/.venv/bin/python s35_fullrun.py --only
     <groups|movement|conti|crop|prev|conti_need|gen|html> [--groups-filter g1,g2]
    N)Pathoutcontipanels35stills35zstills_run_full.htmls35_full_v1pipeline_doczshot_loc_data.jsonshotssceneshotSshc                 \    | dd  j                  d      \  }}t        |      t        |      fS )N   r   )splitint)tagsishis      O/Users/manta/Documents/Projects/TheRoad-I1/scratchpad/forest_exp/s35_fullrun.py_keyr   '   s-    !"gmmD!GBGSX    c                     t         dz  t         dz  j                         rt        j                  t              ni } dj                  g d      }dddddd	idd	idd	iddd	id
dg ddd
idgd}g }t        d   D ]X  }d|d    d|d    }|j                  | d|d    ddj                  |j                  d      xs g       xs d d|d           Z t        j                  d|ddj                  |      z   |      }|d   }|D 	cg c]  }|d   D ]  }	|	  }
}}	t        D 	cg c]	  }	|	|
vs|	 }}	t        |
      D 	cg c]  }	|
j                  |	      dkD  s|	 }}	|
D 	cg c]  }	|	t        vs|	 }}	|s|s|rt        d| d| d|       || d<   t        j                  t        |        t        d t!        |       d!|D ci c]  }|d"   t!        |d          c}       y c c}	}w c c}	w c c}	w c c}	w c c}w )#Nplansz.json
)u\   당신은 영화 로케이션 스크립터다. 전체 샷 목록(씬 헤딩·샷 텍스트·u[   배정 장소 데이터 포함)을 보고, 샷들을 '같은 물리적 장소' 그룹으로uX   묶어라. 장소 연속성이 있는 샷들(같은 공간을 다른 씬에서 재방문u   포함)은 한 그룹. 규칙:uJ   1) 모든 샷은 정확히 한 그룹에 속한다(누락·중복 금지).uR   2) 그룹 안에서 샷 순서는 입력 순서(스토리 순서)를 유지한다.uY   3) 그룹마다: key(영문 스네이크 슬러그), name_ko(짧은 한국어 표시명),uX   place_en(영어 1~3문장 장소 서술 — 고정 지형지물 포함, 이미지 생성uE   프롬프트의 LOCATION lock 으로 쓸 수 있게 구체적으로).uU   4) 실내/실외가 명확히 다른 공간이면 다른 그룹(예: 같은 건물의u   내부와 외부는 분리).uE   5) 작품 고유명사는 place_en 에 쓰지 말 것(범용 서술).objectgroupsarraytypestringr   items)keyname_koplace_enr
   r   
propertiesrequiredr
   r   r   r   r   u    | 헤딩: headingu    | 배정 장소: , ve_locs   (없음)u   
  샷: desc
s35_groupsu!   전체 샷 목록(순서대로):
r   u    그룹핑 검증 실패 missing=z dup=z bad=z	[groups] u   그룹 / 58샷:r#   )BASEPLANexistsF	load_planjoinDATAappendgetllmALL_TAGSsetcount
SystemExit	save_planprintlen)planSYSSCHEMAlinessr   resr   gtseenmissingdupbads                 r   stage_groupsrL   .   s[   !%TF%.!@ H H J1;;tPRD
))  C x'"H%)*%0BC	3E
 @A:B /C J F E']!G*R&	{+uK)~5G		!%%	"2"8b9GZH I yk+ 	, 
 %%c#G))E"$#$*,C]F2v!qz!AzAvD2"4(Qatmq(G4$i
5i4::a=1#41iC
5
0dax/1dC
0#;G9E#eTWSXYZZDNKKd	Ic&k]/
2.4
5f1U8S7_$f
57 34
5
0 6s0   G0*	G64G6G;!G;+H 9H H
c                 :    | d   D ci c]  }|d   |
 c}S c c}w )Nr   r#    )r@   rF   s     r   _groupsrO   \   s&    !%h0AAeHaK000s   c           
         t        j                  t              }|j                  di       }|d   D ]  }|d   }| r|| vr|d   D cg c]  }t	        |       }}t        |D ch c]  \  }}|	 c}}      }	dj                  d |	D              }
dj                  d |D              }t        j                  d	| t        j                  d
|
 d| t        j                        }|d   D ci c]  }|d   |d   |d   d c}||<   t        d| dt        ||          d        t        j                  t        |       y c c}w c c}}w c c}w )Nmovementr   r#   r
   

c              3      K   | ]<  }d | dt         d   t        |         d    dt         d   t        |         d   z    > ywu   [씬 z] scenesr)   r   textNr5   str.0r   s     r   	<genexpr>z!stage_movement.<locals>.<genexpr>k   sU       C8A" B4r$x.R1)<=R@8nSW%f-.8A   AAr   c           	   3   P   K   | ]  \  }}d | d| dt         ||f   d       yw)r   r   : r-   N)SHOT)rZ   r   r   s      r   r[   z!stage_movement.<locals>.<genexpr>n   s:      LFJ72sat2cU"T2s)_V456d   $&	s35_move_u   씬 원문 전문:
u$   

샷 목록(각각 동선 판정):
	movementsr   movement_en
figures_en)rQ   figuresz[movement] r^   u   건)r2   r3   r0   
setdefaultr   sortedr4   r8   CMOVEMENT_SYSMOVEMENT_SCHEMAr>   r?   r=   )groups_filterr@   mvrF   gkeyrG   keysr   _	scene_ids	scene_txt	shots_txtrE   ms                 r   stage_movementrt   b   sw   ;;tD	R	(B(^xT6!"7,AQ,D1D52qBD12	KK  C8A C C	 II LFJL L	eeiv&*9+5\ k#$%$5$57
 !-/- fIAm,<+,\? < <-/4 	D6C4M?#67# $ KKd -1/s   E%E	-Ec                     g g }}| D ]5  }|j                  |       t        |      dk(  s#|j                  |       g }7 |r|j                  |       |S )N   )r6   r?   )tagsr   currG   s       r   _chunksry   |   sP    2C

1s8q=JJsOC	 
 

3Jr   c                    t        j                  t              }|j                  di       }|d   D ]  }|d   }| r|| vr|j	                  di       j	                  |i       }t        t        |d               D ]  \  }}|D cg c]  }t        |       }	}t        j                  t        |	            \  }
}}}t        j                  |d   |	|      }d| d| d	}||||
|d
|| d| <   t        j                  d| d| d|d |t        |z         t        d| d| dt        |       d|         	 t        j                  t        |       y c c}w )Nsheetsr   r#   rQ   r
   r%   conti35_ro   z_i2.png)rm   filer
   slotsprompt
s35_conti__i2)refssizeout_pathz[conti] r^   u   샷 → )r2   r3   r0   rf   r7   	enumeratery   r   rh   _gridr?   _promptimg_gptOUTCr>   r=   )rk   r@   r{   rF   rm   rl   ichunkrG   rn   r~   layoutr   arr   fns                   r   stage_contir      sc   ;;tD__Xr*F(^xT6XXj"%))$3!'!G*"56HAu%*+UDGUD+&'ggc$i&8#E64YYq}dB7FD61#W-Bb5&%2FdV1QC=! II
4&!C0&dTBY@HTF!A3bUHRDAB 7   KKd ,s   Edense_forest_incident_site_0c                  r   ddl m}  dd l}t        j                  t
              }t        j                  dd       dddd}|d	   j                         D ]V  \  }}| j                  t        |d
   z        j                  d      }|j                  d      j                  d       }|j                         }|rsd}	t        d|d   |	z
        t        d|d   |	z
        t        |j                   d   |d   |	z         t        |j                   d   |d   |	z         f}|j#                  |      }|j                   \  }
}||d      \  }}|j%                  |j                  d            }|dk  }d }|t&        v rIt)        |dz
        D cg c]  }|
|dz   z  |z   }}t)        |dz
        D cg c]  }||dz   z  |z   }}nH|dkD  r ||j+                  d      |dz
  |
      ng }|dkD  r ||j+                  d      |dz
  |      ng }dg|z   |
gz   }dg|z   |gz   }t-        |d         D ]]  \  }}||z  ||z  }}||   dz   ||   dz   ||dz      dz
  ||dz      dz
  f}|j#                  |      j/                  t        | dz         _ t1        d| dt3        |d          d| d|        Y y c c}w c c}w )Nr   )ImageTparentsexist_ok)   r   )r   r   )   r   )r      rv   r{   r}   RGBLc                     | dk  rdS dS )N      r   rN   )vs    r   <lambda>zstage_crop.<locals>.<lambda>   s    S#2Ga2Gr   r   r   r   r   r~   x   c                    t        |       D cg c]  \  }}|dkD  s| }}}g }|D ]9  }|r#||d   d   z
  dk  r|d   j                  |       (|j                  |g       ; |D cg c]B  }|dz  t        |      t        |      z  cxk  r|dz  k  rn nt        |      t        |      z  D }}t        |      |k(  r|S t	        |      D 	cg c]  }	||	dz   z  |dz   z   c}	S c c}}w c c}w c c}	w )Ng?rv   g?gffffff?r   )r   r6   sumr?   range)
profilen_expecttotalr   r   candgsxcentersks
             r   _lineszstage_crop.<locals>._lines   s   "+G"4A"4$!QDA"4DAB!bfRj.A-rFMM!$IIqcN	 
 24 IA$,Q#a&G54<G 1vQ'G I7|x'"8_., QUO15,. . BI.s   C&C&(AC,C1)axisr
   .pngz[crop] r^   u	   패널 v=z h=)PILr   numpyr2   r3   r0   OUTPmkdirr"   openr   convertpointgetbboxmaxminr   cropasarrayEQUAL_FORCEr   meanr   saver>   r?   )r   npr@   GRIDMAPskeyr   sheetmaskbboxpadWHcolsrowsarrdarkr   r   v_linesh_linesxsysr   r   crboxs                              r   
stage_cropr      s   ;;tDJJtdJ+V/GN((*b

4"V*,-55e<}}S!''(GH||~C47S=)3q$q'C-+@

1tAw}5

1tAw}57D JJt$Ezz1R[)
djjs+,Sy	. ;49$(ODOqqAE{d*OGD49$(ODOqqAE{d*OGD@DqfTYYAY.q!<bG@DqfTYYAY.q!<bGS7]aS S7]aS 7,FAst8Q$YqAa519beaiAEQ1q5	AFCJJsO  3%t!45 - 	vRBwK 017)3wiPQU +> EDs   J/)J4c                 2   t        j                  t              }|j                  di       }dj	                  g d      }ddddddiddd	giddid
g d
ddidgd}|d   D ]  }|d   }| r|| vrt        |d         dk(  r|d   d   d ddi||<   2t        |d   D ch c]  }t        |      d    c}      }dj	                  d |D              }	dj	                  d |d   D              }
t        j                  d| |d|	 d|
 |      }|d   D ci c]  }|d   |d   |d   d c}||<   t        d| d||   j                         D ci c]  \  }}||d    c}}        t        j                  t        |       y c c}w c c}w c c}}w )Nprevr   )u\   당신은 콘티 연속성 판정가다. 같은 장소 그룹의 샷 목록(순서대로)과uW   씬 원문을 보고, 각 샷마다 '시각적으로 관련된 앞쪽 샷'이 있는지uY   판정하라. 시각적 관련 = 같은 공간·연속된 액션·같은 인물 구도가uZ   이어져 앞 샷의 생성 이미지를 참조로 붙이면 일관성에 도움이 되는uP   경우. 다른 시간대·다른 서브 공간·연결 단서가 없으면 null.uT   앞쪽 샷은 반드시 목록에서 자기보다 앞에 있는 샷이어야 한다.uJ   각 샷마다 prev(태그 또는 null)와 reason_ko(한 구절)를 반환.r   r"   r   r   r    null)r   r   	reason_kor&   r!   r   r#   r
   r   r   u
   단독 샷)r   reasonrR   c              3      K   | ]<  }d | dt         d   t        |         d    dt         d   t        |         d   z    > ywrT   rW   rY   s     r   r[   zstage_prev.<locals>.<genexpr>   sU      !C8A" B4r$x.R1)<=R@8nSW%f-.8Ar\   c              3   P   K   | ]  }| d t         t        |         d       yw)r^   r-   N)r_   r   )rZ   rG   s     r   r[   zstage_prev.<locals>.<genexpr>   s.      A5?qcDaM&)*+Zr`   	s35_prev_u   씬 원문:
u   

샷 목록(순서):
r   r   z[prev] :)r2   r3   r0   rf   r4   r?   rg   r   r8   r>   r"   r=   )rk   r@   prev_maprA   rB   rF   rm   rG   rp   
scenes_txtrr   rE   itr   r   s                  r   
stage_prevr      s   ;;tDvr*H
))  C w"X&h/0 (+3- 6	798 /9 IF (^xT6qz?ajmd8D.F GHTN'
;
1DGAJ
;<	[[ !C8A!C C
 II A56wZA A	eeiv&#J</HT
 %(L2$0b V*r&z13K'B B$02 	vQ(0(<(<(>?(>1q!F)|(>?	A) , KKd <2 @s    F	
FFc                 <   t        j                  t              }|j                  di       }dj	                  g d      }ddddddidd	iddid
g d
ddidgd}|d   D ]  }|d   }| r|| vr|j                  di       j                  |i       }g }|d   D ]Q  }	|j                  |	i       }
|j                  |	 dt        t        |	         d    d|
j                  dd      z          S t        j                  d| |ddj	                  |      z   |      }|d   D ci c]  }|d   |d   |d   d c}||<   t        d| d||   j                         D ci c]  \  }}||d    c}}        t        j                  t        |       y c c}w c c}}w )N
conti_needr   )uU   당신은 촬영 현장의 콘티 운용 판정가다. 각 샷의 텍스트와 동선uO   분석을 보고, 이미지 생성 시 스토리보드(콘티) 패널을 구도u5   참조로 첨부할 필요가 있는지 판정하라.uO   콘티 필요(true) = 구도를 글만으로 오해하기 쉬운 경우: 여러uT   인물의 동선·위치 관계가 얽힘, 특수한 카메라 각도/깊이 관계,uT   연속 액션의 방향 유지가 중요, 프레임 내 배치가 스토리텔링에u
   결정적.uP   콘티 불필요(false) = 글만으로 충분히 명확한 쉬운 구도: 단일uV   인물 클로즈업/상반신, 단순 인서트(손·사물), 정적인 단순 배치,u   표준적인 대화 구도 등.uH   각 샷마다 need_conti(bool)와 reason_ko(한 구절)를 반환하라.r   r"   r   r   r    boolean)r   
need_contir   r&   r!   r   r#   rQ   r
   r^   r-   u   
  동선: r,   s35_contineed_u   샷 목록:
r   r   r   needr   z[conti_need] r   r   )r2   r3   r0   rf   r4   r7   r6   r_   r   r8   r>   r"   r=   )rk   r@   need_maprA   rB   rF   rm   rl   rC   rG   rs   rE   r   r   r   s                  r   stage_conti_needr     s   ;;tD|R0H
))  C w"X&!9- (+3- <	=9> /? IF (^xT6XXj"%))$37Aq"ALLA3bd1gv!6 7|D55Z89 :  eenTF+S#dii&66@ %(L2$0b V*r,/?13K'B B$02 	dV1%(0(<(<(>?(>1q!F)|(>?	A " KKd2 @s   !FFc                 
   t        j                  t              }|d   }|d   }|j                  di       }|j	                  di       }t        j                         }t        j                         }t        j                         }i }	|j                         D ]1  \  \  }
}}|	j	                  |
t                     j                  |       3 t        j                  dd       |d   D ]  }|d   }| r|| vr|d	   D ]n  }t        | d
z  }|j                         rt        d| d       0t         t#        |         }|j                  |i       j                  |i       }|j                  |i       j                  |i       }|j                  d      }|j                  |i       j                  |ddd      }g }|d   r7t$        | dz  j                         r|j'                  dt$        | dz  f       d }|r9t        | d
z  j                         r|}|j'                  dt        | d
z  f       |j                  t#        |      g       }|s/t)        |	j                  t#        |      d   t                           }g g }}|D ]  }||v rB||   \  }}|j                         s |j'                  |       |j'                  d| d|f       I||v sN||   \  }}|j                         sg|j'                  |       |j'                  d| d|f        dt        j*                  |      z   dz   dt        j,                  |d          d|d    dg}|r9|d   d   j/                  d      r"|j'                  d j1                  g d!             |j'                  t
        j2                         |j                  d      r*|j'                  d"t        j,                  |d         z          |j                  d#      r*|j'                  d$t        j,                  |d#         z          |r'|j'                  d%d&j1                  |      z   d'z          n|j'                  d(       |j'                  d)       d*j1                  |      }t        j4                  d+| d,||d-|.       |t7        |xr |d   d   j/                  d/            |d0   |||D  cg c]X  \  } }| t9        |      j/                  t9        t:                    rt9        |j=                  t:                    n
t9        |      d1Z c}} d2||<   t        j>                  t        |       t        d| d3|d    d4| d5| d6| d7       q  y c c}} w )8Nr   r   rQ   gen_metaTr   r   r#   r
   _nb2.pngz[gen] z skip(exists)u   판정 없음r   r   r   uy  STORYBOARD PANEL — a REFERENCE ONLY, never the target: use it loosely for camera framing, figure placement and depth order. Do NOT photorealize this drawing as-is — the SHOT TEXT and the other references are authoritative; re-stage the moment naturally as a real photograph. Never copy the sketch's line style, paper texture, borders, simplified geometry or drawing errors.u   PREVIOUS SHOT STILL — a visually related earlier shot of this same place: the location's look, materials, fixed features, lighting mood and each person's clothing are LOCKED to this photo; never copy its camera framing.r   u   CHARACTER REFERENCE — zN: the exact person appearing in this shot; match face, hair and build exactly.u   PROP REFERENCE — zU: the exact object appearing in this shot; match its look, material and wear exactly.u   Create ONE FINAL photorealistic live-action film still of the moment below — contemporary South Korea, 2026; all people are Korean unless stated. TIME OF DAY (lock): .z#SHOT TEXT (authoritative, Korean): r-   zLOCATION (lock): r%   u]    The shot takes place here — pick the sub-area of this location that the shot text implies.
STORYBOARDr   )
z1THE STORYBOARD PANEL IS ONLY A REFERENCE: it is az-rough pre-production sketch, not the image toz-reproduce. Take from it only the shot's roughu4   composition — framing, where figures sit, near/farz5order. Everything else (real-world detail, materials,z4light, anatomy, environment richness) must come fromz.the shot text and the photographic references,z5re-staged as if actually filmed on a real set. If thez,sketch conflicts with the shot text or looksz2simplified/wrong, FOLLOW THE TEXT, not the sketch.zMOVEMENT (follow exactly): re   u+   FIGURES — size & depth (follow exactly): zPEOPLE: the SHOT TEXT alone decides whether any person is visible in this shot. IF a person appears, they must be one of the referenced people (r*   uu   ) matched exactly to their reference photo — never anyone else, and never add a person the shot text does not show.z5No people appear unless the shot text itself says so.z6No text, captions, watermarks or annotations anywhere.rR   s35run__nb2z16:9)aspect_ratior   STORYr   )labelpath)rm   
conti_usedconti_reason	prev_usedr   r   u    완료 (conti=z, prev=z, chars=z, props=)) r2   r3   r0   r7   rf   r   
_char_refs
_prop_refs_ve_idsr"   r:   updateOUTSr   r1   r>   r_   r   r   r6   rg   _time_of_soften
startswithr4   REALIZE_STILLimg_nb2boolrX   r/   relative_tor=   )!rk   r@   r   r   mv_allmetacharspropsvescene_unionr   r   idsrF   rm   r   r   rD   rs   pjprev_tagndr   r   ve_ids
char_names
prop_namescidnameppartsprompt_fulllabs!                                    r   	stage_genr  2  su   ;;tDF|HL!HXXj"%F??:r*DLLNELLNE	
BK((*	S3r35)005 %JJtdJ+(^xT6W:CC5))Czz|se=12T#YA

4$((b1AdB'++C4Bvvf~HdB'++C$<K2M NBD&ztTl2::<> cU$<'	) 	* ITxj$99AAC$	' )-(8/D(DF G VVDIr*FS	!ce DE%'
J%<#CjGD!xxz"))$/6tf =7 789%; < E\#CjGD!xxz"))$/1$ 8: :;<%> ? $I **S/" %(( 6aii&	6J5KL#AjM? 3! !	E Q
--l;TYY (   LL)uuZ : yy:78 9uuYJ yy967 8> ii
+,&	&'  ) *LL & ' ++e,KIIuD);#)C9 "4#JDGAJ,A,A',JK "89%
 (,	- (,VS!	 $'&)!f&7&7D	&B $'q}}T':#;(+A1 (,	-
DI KKd#F3%r&zl') M&<x
|1> ?a 	 Z-s   AU1c                  ^   dd l t        j                  t              } | j	                  di       }| j	                  di       }| j	                  di       }t
        dz  dz  dz  j                  dd	       d
 d fd}t        d |j                         D              }g }| d   D ]  }|d   }d}	|d   D ]  }
|j	                  |i       j	                  |
i       }|j	                  |i       j	                  |
i       }|j	                  |
i       }d|
 d}|j	                  d      rdnd}d}|j	                  dg       D ]+  } ||d         }|d| d| d  |d                dz  }- |sd}dj                  fd|j	                  dg       D              }|	d |
 d!| d" |j	                  d#d             d$ t        |j	                  d      xs d%             |j	                  d      rd& |j	                  d#d             d'ndz   d( t        t        |
         d)          d*| d| d+t        |j	                  dg              d,| d-| d. |j	                  d/d0             d1z   z  }	 |j                  d2 |d3          d4| d5t        |d          d6 |d7          d8|	 d9        t        j!                  d:t        t"               d;| d<t        |      |z
   d=dj                  |       d>	       t%        d?t         d@| dAt        |       d'       y )BNr   r   r   r   r   r   refs35Tr   c                 4    t        j                  | xs d      S )N )_htmlescape)rG   s    r   esczstage_html.<locals>.esc  s    ||AG$$r   c                 |   | j                  d      ry| j                  d      ry| j                  d      r9d| j                  dd      d   j                  d	d      d
   j                         z   S | j                  d      r9d| j                  dd      d   j                  d	d      d
   j                         z   S | d d S )Nr   u$   콘티 패널 (구도 참조 전용)PREVIOUSu'   PREV 스틸 (장소 룩·의상 잠금)	CHARACTERu
   캐릭터 u   —r   r   r   PROPu   소품    )r   r   strip)r   s    r   	_ref_kindzstage_html.<locals>._ref_kind  s    L)9J'<K(%++eQ"7":"@"@a"H"K"Q"Q"SSSF#u{{5!4Q7==c1EaHNNPPPSbzr   c                     | j                  d      s| S t        |       }|j                  z  }|j                         sj	                  ||       d|j                   S )N/zout/conti/refs35/)r   r   r  r1   copy)path_ssrcdstREFDshutils      r   _ref_relzstage_html.<locals>._ref_rel  sT      %M6lSXXozz|KKS!"388*--r   c              3   D   K   | ]  }|j                  d       sd  yw)r   r   N)r7   )rZ   rs   s     r   r[   zstage_html.<locals>.<genexpr>  s     B]aeeL.A!]s     r   r#   r  r
   zout/conti/stills35/r   r   u#   <span class=on>콘티 사용</span>u$   <span class=off>콘티 제거</span>r   r   z<figure class=ref><a href='z' target=_blank><img src='z' loading=lazy></a><figcaption>r   z</figcaption></figure>u/   <span class=note>참조 이미지 없음</span>c           
   3   x   K   | ]1  }d   |d                d |d          d |d          d 3 yw)z<li><b>r   u   </b> — <span class=note>z</span> <code>r   z</code></li>NrN   )rZ   r   r&  r  s     r   r[   zstage_html.<locals>.<genexpr>  s]      "- ,A #i'
345 6$$''
O#4 5QvY(6 ,s   7:z<div class=shot><h3> u%   <span class=note> — 콘티 판정: r   u
    · prev: u   없음z (r   z5</span></h3><div class=note style='margin:2px 0 8px'>r-   z&</div><div class=row><figure><a href='uq   ' loading=lazy></a><figcaption>nb2 스틸</figcaption></figure><div class=refs><div class=note>참조 이미지 (u   장):</div><div class=refrow>uU   </div></div></div><details><summary>참조 상세 + 프롬프트 전문</summary><ul>z
</ul><pre>r   u   (기록 없음)z</pre></details></div>z<section><h2>r$   z <span class=k>(u    · 샷 u;   )</span></h2><div class=note>장소 서술(LOCATION lock): r%   z</div>z
</section>u  <!DOCTYPE html>
<html lang=ko><head><meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>s35 풀 런 — 전체 58샷 (LLM 장소 그룹핑+콘티 선별)</title>
<style>
body { margin:0; padding:24px; background:#0f1216; color:#e6e6e6;
       font:14px/1.6 -apple-system,'Apple SD Gothic Neo',sans-serif; }
h1 { font-size:20px; } h2 { font-size:17px; margin:34px 0 8px;
     border-bottom:1px solid #333; padding-bottom:5px; }
h3 { font-size:15px; margin:6px 0; }
.k { color:#8a939e; font-size:13px; font-weight:400; }
.row { display:flex; gap:14px; align-items:flex-start; margin:10px 0;
        flex-wrap:wrap; }
figure { margin:0; } figcaption { color:#c9d2dc; font-size:12.5px;
          max-width:640px; }
img { max-width:640px; width:100%; border-radius:8px;
      border:1px solid #2a2f36; }
.note { color:#8a939e; }
.box { background:#161b22; border:1px solid #2a2f36; border-radius:8px;
       padding:12px 16px; margin:12px 0; }
.shot { border-top:1px dashed #2a2f36; padding:12px 0; }
.on { background:#1e3a2a; color:#7ee2a8; border-radius:5px;
      padding:1px 8px; font-size:12px; margin-left:6px; }
.off { background:#3a2a1e; color:#e2b57e; border-radius:5px;
       padding:1px 8px; font-size:12px; margin-left:6px; }
.refs { max-width:640px; }
.refrow { display:flex; gap:8px; flex-wrap:wrap; }
figure.ref img { max-width:150px; }
figure.ref figcaption { font-size:11px; max-width:150px; }
code { background:#161b22; padding:0 4px; border-radius:4px;
       font-size:11px; }
details { margin:6px 0; } summary { color:#9ecbff; cursor:pointer; }
pre { background:#161b22; border:1px solid #2a2f36; padding:10px;
      white-space:pre-wrap; font-size:12px; }
</style></head><body>
<h1>s35 풀 런 — 프로젝트 전체 선택 샷 u   개
(콘티 사용 u
    / 제거 u  )</h1>
<div class=box>v24s 로직의 전체 샷 확장: ①LLM 장소 그룹핑(전 샷 →
장소 연속 그룹+장소 서술) → ②그룹별 동선 분석 → ③i2 콘티(v24
실사영화 계약, ≤6샷 시트 청킹) → ④크롭 → ⑤prev 시각 관련성 판정
⑥샷별 콘티 필요 LLM 판정(쉬운 구도는 콘티 제거) → ⑦nb2 스틸.
참조=선별 콘티 패널(참조 전용, 그대로 실사화 금지)+prev 스틸+VE 전
엔티티(캐릭터 composite+소품 reference_face, 배경 L 제외)+REALIZE 원칙
+<b>LOCATION lock</b>(그룹 장소 서술)+씬 헤딩 시간 잠금. 각 샷 카드에
사용된 참조 이미지 전부와 프롬프트 전문 기록. 비교:
<a href='stills_run24s.html'>v24s(6그룹 28샷)</a></div>
z
</body></html>z[html] u	    (콘티 r(  )r.  r2   r3   r0   r7   r/   r   r   valuesr4   rX   r_   r   r?   r6   PAGE
write_textr9   r>   )r@   r   r   r  r/  n_contisecsrF   rm   figsr   r  r  mt	still_relbadge	ref_itemsr   relref_detailsr-  r&  r  r.  s                       @@@@r   
stage_htmlr?    s   ;;tDxx#Hxxb)H88J#D%<'!H,DJJtdJ+%	. BT[[]BBGD(^xW:CdB'++C4BdB'++C4B#r"B-cU(;I>@ff\>R:@ IVVFB'qy)1# 7!!$%D9QwZ0122HJK	 ( M	'' "- +	"- -K
 &se1UG7BFF8R<P8Q7RSRVVF^%?x!@ABD 9;vRBFF8R012!4BP<tDIv./0 133<+ >,,5; 7 +,- .%%.K 0"m $BFF8->?@A B#$	$%D+ N 	C)-..>tf Eqz?# $=1Z=!"&j:	;U ^ 	OO #4F 58M? Cy
3t9w#6"7 
8  ]/ /` 
GD67)1SYKq
9:r   __main__z--onlyT)r   rQ   r   r   r   r   genhtml)r(   choicesz--groups-filterr  )default,c                      t               S N)rL   rN   r   r   r   r   E  s    |~r   c                       t        t              S rG  )rt   gfrN   r   r   r   r   F  s	    +r   c                       t        t              S rG  )r   rI  rN   r   r   r   r   G  s    k"or   c                      t               S rG  )r   rN   r   r   r   r   H      Z\r   c                       t        t              S rG  )r   rI  rN   r   r   r   r   I  s    Z^r   c                       t        t              S rG  )r   rI  rN   r   r   r   r   J  s
    +B/r   c                       t        t              S rG  )r  rI  rN   r   r   r   r   K  s    IbMr   c                      t               S rG  )r?  rN   r   r   r   r   L  rL  r   )5__doc__argparserB  r  jsonsyspathlibr   __file__parentHEREr   insertrX   
forest_libr2   s34_conti_sheetrh   s34_stillrunr   r/   r   r   r   r4  r0   loadr   r5   r_   r9   r   rL   rO   rt   ry   r   r   r   r   r   r  r?  __name__ArgumentParserapadd_argument
parse_argsark   r   rI  only)rD   rF   s   00r   <module>re     s      
 H~ 3t9    e|ge|g
*e|g
*$$tyyd^+.BBCD,0M:Mq7QvY"M:37=A=aa'
|2ai[)=A+7\14	2 ..0Rj)X(ZB?NA;H z	 	 	 	"BOOHt:  ; OO%rO2
A__**3/	5/1!/	5B+%+%!#/!!# $%66+ - u ;A@ 
6s   %FF$)F)1F)