
    Lj]T              
          d Z ddlZddlZddlZddlZddlmZ ej                  j                  d e
 ee      j                               ddlZddlZddlZej&                  dz  Zej*                  dz  Zg dZg dZdZd	d
ddiddidddgdddZd
dd	d
ddiddiddiddidg ddddd	d
i dddidddidddiddej6                  ddddiddddgddddiddedd ddid!ddid"dedd#ddid$dd%id&dd'd(gdd)dd*d+gdd,eg d-dddd	d
ddiddiddid.g d.dddddid/g d/d0Zed1z   Zd2 Zd3 Zd4 Z d5 Z!d6 Z"d;d7Z#d8 Z$d9 Z%e&d:k(  r e%        yy)<u  s22 — 코드 렌더 BD v3: 관계 데이터 + 결정론 솔버/검증 (2026-07-07).

사용자 질문 "코드로 bd 를 만들 때 LLM 이 데이터를 제대로 만들어 줄까?"
→ 2026 연구 조사 결론을 반영한 재설계 (s13 v2 는 LLM 절대좌표 직출 = 연구가
지목하는 실패 모드):
  - SpatialGrammar (arXiv 2604.27555, 2026-04): raw JSON 좌표 충돌 66.7% →
    저차원 DSL 13.6% → 결정론 컴파일러의 구조화 에러 피드백 루프 0%.
  - RLVR 도면 (arXiv 2605.14117, 2026-05): 최상위 LLM 도 few-shot 좌표 JSON
    비일관 → 결정론 검증+수리 루프 필수.
  - Holodeck (CVPR'24): LLM=공간 관계만, 좌표=솔버 (의미↔기하 분리).
  - PSDL (arXiv 2510.16147): 위치=선행 요소 기준 상대 표현식.
설계:
  ① LLM(gpt) = 씬 원문 전체+멤버+샷+CREATOR CORRECTIONS → **관계 데이터만**
     (parent 포함 + 부모 내 9방위 anchor + 부모 대비 크기% + 부착 변 +
     변 위 위치%) — 절대 좌표 0.
  ② 결정론 솔버 = 부모 트리 순회로 좌표 계산 (100×100 캔버스).
  ③ 결정론 검증 = 겹침/포함/부착/개구부 위반 → 구조화 메시지.
  ④ bounded 수리(≤2회) = 위반 메시지를 LLM 에 되먹여 관계 데이터 수정.
  ⑤ 렌더 = s13 결정론 PIL 렌더러 **그대로 재사용** (마커/레이어 색/범례).
사용: backend/.venv/bin/python s22_bd_code.py [--only all|llm|repair|html]
산출: plans/bd_code_rel_v1.json(+rounds), out/blockset/bd_code_r*.png,
      bd_code.html (8897)
    N)Pathblocksetzbd_code.html	NWNNEWCESWSSE)noner   r   r   r	   uV  You are a set-layout analyst for film pre-production. You get one
real-world place's member descriptions, the FULL ORIGINAL TEXT of every scene
that plays there, all shots, and creator corrections (which override any
conflicting text). Build ONE top-down BLOCK LAYOUT of the whole property as
RELATIONAL data for a deterministic solver — you never output coordinates;
you only state what contains what, where inside its container, how big
relative to its container, and what is attached to which side.

Placement model (the solver computes all geometry from this):
- Every element names a parent: "canvas" (the whole 100x100 site, canvas top
  = the property's rear, canvas bottom = the street/approach side unless the
  texts imply otherwise — state your choice in layout_notes_ko) or another
  element's id (true containment: the child sits ON/INSIDE the parent area).
- anchor: one of NW,N,NE,W,C,E,SW,S,SE — where the element sits INSIDE its
  parent.
- w_pct,h_pct: the element's width/height as a PERCENT of its parent's
  width/height (5..100). For shape "circle", w_pct alone sets the diameter
  as a percent of the parent's smaller side.
- attach_side: none, or N/S/E/W — the element is snapped flush against that
  side of its parent (stairs on an outside wall, walls on an edge, and ALL
  openings). along_pct (0..100) positions it along that side (left→right or
  top→bottom); use it whenever attach_side is not "none".
- Openings (door/window/gate) MUST have attach_side = the wall side of their
  host parent that the texts support, and repeat = how many identical
  openings the strip contains.

Element kinds: building_mass, upper_shell (enclosed upper unit — outline
only, never interior), terrace, yard, road, alley, stair, wall, neighbor_mass
(BLOCK kinds) and door, window, gate, fixture_round, fixture_rect, equipment
(POINT kinds).
- ids: short lowercase slugs, unique.
- Simplify ALL neighbouring buildings to plain neighbor_mass rects (parent =
  canvas, no openings). Include the road/alley approach.
- COUNT-CRITICAL: opening counts/sides must match the texts; if the texts
  give no exact count choose a modest count and set certainty="inferred".
- EXTERIOR ONLY: this is an OUTDOOR site diagram — ground areas, building
  outer shells, roof-level surfaces, OUTDOOR fixtures, and boundary openings
  (doors/windows/gates in OUTER walls) only. NEVER include interior
  furniture, appliances or fixtures of any enclosed unit (no beds, tables,
  stoves, counters, mirrors, lamps, TVs); every enclosed volume stays
  sealed — outline and outer-wall openings only.
- Include permanent OUTDOOR fixtures the scenes rely on. NO story props, no
  vehicles, no people, nothing temporary.
- 10 to 26 elements. name_en: 1-3 generic English words, no proper names.
  desc_ko: one short Korean sentence — what it PHYSICALLY is, its form and
  key spatial relation, present tense, PHYSICAL VISIBLE FACTS ONLY: never
  events, actions, characters or animals, usage stories, moments of motion,
  or authorial phrasing (verbatim shown to the human reviewer).
- evidence: source = scene index / shot key / member id, quote = exact
  phrase copied from the given texts. certainty="text" needs a real quote.

HEIGHT LAYERS (3-6): you define them; each = layer_id, name_en, desc_ko (one
Korean sentence: what physical height), rel_height (0 = ground, increasing
upward). Every element references one layer_id.

Solid blocks that share a parent must not overlap — place siblings at
different anchors with sizes that leave room (the solver will report any
overlap back to you for correction).

connections: pairs of element ids that the texts say PHYSICALLY adjoin or
connect — a stair to the ground area it rises from AND to the level it
serves, a gate between the two areas it joins, an alley to the yard/road it
links. why_ko = one short Korean line quoting-level grounding. The solver
verifies each pair actually touches (gap <= 1 unit) and reports failures —
so place connected elements so they really meet (matching anchors/sides).

Also output layout_notes_ko: 3-6 Korean sentences on the arrangement logic
(verbatim shown to the human reviewer).arrayobjecttypestring)sourcequoter   r   F)r   
propertiesrequiredadditionalProperties)r   itemsnumber)layer_idname_endesc_ko
rel_heightidr   r   kind)r   enumr   shaperectcircleparentanchorw_pcth_pctattach_side	along_pctrepeatinteger
importancemajorminor	certaintytextinferredevidence)r   r   r   r    r   r"   r%   r&   r'   r(   r)   r*   r+   r-   r0   r3   )abwhy_ko)layerselementsconnectionslayout_notes_ko)r   r   r   r   ul  

REPAIR MODE: you previously produced the RELATIONAL data below and the
deterministic solver found the listed violations. Return the FULL corrected
data (same schema): change ONLY what is needed to resolve every violation —
adjust anchors, sizes, attach sides or containment; keep every element,
meaning, desc_ko and evidence unless a violation forces a change.c                    ddi}g t        | d         }}d}|r_|dk  rZ|dz  }g }|D ]D  }|d   |v r*|j                  |       t        |||d            ||d   <   4|j                  |       F |}|r|dk  rZ|D cg c]  }d	|d    d
|d    d }}g }|D ]  }||d      \  }	}
}}dD ci c]  }|||   
 }}d|d<   d|d<   |d   dk(  r"|j                  |	|dz  z   |
|dz  z   ||       n|j                  |	|
||       |d   |d<   |j                  |        dd| j	                  dd      d| d   || j	                  dd      d}t        j                  |       |||fS c c}w c c}w )uQ   parent 트리 순회 배치. 반환: s13 렌더러 포맷 layout + id→rect 맵.canvas)        r=         Y@r>   r8   r   d      r%   r   zSTRUCTURE: 'z' has unknown/cyclic parent '')	r   r   r    r   r"   r+   r-   r0   r3    markerrot_degr"   r$      )xywh_idr:   )widthheightorientation_noter7   )r<   r7   r8   r:   )listappend_placeupdategetS13_fix_markers)relrectsorderpendingguardreste
structuralout_elsrF   rG   rH   rI   ks13elayouts                   s22_bd_code.pysolverb      s   /0Ec*o.7EE
eck
A{e#Q!'58+=!>agA   eck 078/6! !4	 *{m1&/6  8G1T7^
1a"; < ";A1Q4 "; < XYW:!KK!a!e)q1q5yAK;KK!qAK+gUt  #&-0WW5F-KMH7!$):B!?AF V5*$$+8
<s   <E',E,c           
         |\  }}}}| d   dk(  r$t        ||      t        d| d         z  dz  }|x}}n*|t        d| d         z  dz  }|t        d| d         z  dz  }| j                  d      xs d}	t        dt        d	| j                  d
      xs d            dz  }
| d   dv }|	dv r1|||z
  |
z  z   }|	dk(  r|n||z   }|r||dz  z
  n|	dk(  r|n||z   |z
  }no|	dv r1|||z
  |
z  z   }|	dk(  r|n||z   }|r||dz  z
  n|	dk(  r|n||z   |z
  }n:dddddddddd	| d      }dddddddddd	| d      }|||z
  |z  z   |||z
  |z  z   }}||||fS )Nr"   r$   g       @r'   r>   r(   r)   r   r=   r*   g      I@r    doorwindowgate)r   r   r   rE   )r	   r   r	   r         ?r@   )	r   r	   r   r   r
   r   r   r   r   r&   r   )minmaxrR   )r[   r%   pxpypwphdrH   rI   sidealongopeningrF   edgerG   fxfys                    ra   rP   rP      s   NBBzXBK#c1W:..6	AS!G*%%-S!G*%%-55)6Ds3k 2 :d;<uDEi55Gz"q&E!!S[rb2g#D1q5L"b1		"q&E!!S[rb2g#D1q5L"b1AQRbrAQ(()(5AQRbrAQ(()(5R!VrM!2a2#51q!Q<    c                   " t        |      }| d   D ci c]  }|d   |
 c}""fd}d }| d   D ]  }|d   |vr||d      \  }}}	}
|j                  |d         }|rY ||      sQ|\  }}}}||dz
  k  s$||dz
  k  s||	z   ||z   dz   kD  s||
z   ||z   dz   kD  r|j                  d|d    d|d    d	        ||      s|j                  d
      xs ddk(  s|j                  d|d    d|d    d        | d   D cg c]#  }|d   t        j                  v r|d   |v r|d   % }}t        |      D ]  \  }}||dz   d  D ]  }| ||      v s| ||      v s"|   d   "|   d   k7  r)||   \  }}}}||   \  }}}}t        ||z   ||z         t        ||      z
  }t        ||z   ||z         t        ||      z
  }|dkD  s|dkD  s||z  dkD  s|j                  d| d| d"|   d    d||z  dd	         | j                  d      xs g D ]  }|d   |d   }}||vs||vr|j                  d| d| d       .||   \  }}}}||   \  }}}}t        dt        |||z   z
  |||z   z
              }t        dt        |||z   z
  |||z   z
              } t        ||       }!|!dkD  s|j                  d | d| d!|d"    d#|!dd$	        |S c c}w c c}w )%Nr8   r   c                 x    t               }| }|dk7  r'|v r#|   d   }|j                  |       |dk7  r|v r#|S )Nr<   r%   )setadd)ichaincurelss      ra   anczvalidate.<locals>.anc   sK    Xo#*c(8$CIIcN Xo#* rv   c                     | d   dv S )Nr    rd    )r[   s    ra   <lambda>zvalidate.<locals>.<lambda>   s    &	%??rv   r%   rh   zCONTAINMENT: 'z' sticks out of its parent 'u)   ' — reduce w_pct/h_pct or change anchorr)   r   z
OPENING: 'z' (r    z,) must have attach_side = its host wall sider@      zOVERLAP: solid blocks 'z' and 'z' (same parent 'z') overlap by z.0fu0    sq-units — move anchors apart or shrink sizesr9   r4   r5   zCONNECTION: pair ('z', 'z#') references an unknown element idr=   g      ?zCONNECTION: 'z' must physically adjoin (r6   z
) but are u^    units apart — move/resize one of them (anchor, size or attach_side/along_pct) so they touch)rN   rR   rO   rS   BLOCK_KINDS	enumerateri   rj   )#rU   rV   r\   vr[   r   rr   rF   rG   rH   rI   pxrrk   rl   rm   rn   idsr{   r4   r5   axayawahbxbybwbhowohcgxgygapr~   s#                                     @ra   validater      s   ZA":
/!1T7A:
/C @G_T7%1T7^
1aii($wqz NBBBGq27{a!eb2gl.B1urBw|+>!D' 3k] +#$ % 1:155/96fDHHz!D'#ai[ 99 : ;   
O AOqi3??*qw%/? T7OC A#1QUVACF{a3q6kSVH-=QAQ-Q"1XNBB"1XNBBR"Wb2g&R4BR"Wb2g&R4BAv"q&R"Wq[21#WQC @!!fX./ 0"WSM *)* +   WW]#)r)vqv1E>Qe^HH*1#T! 5# $ %qBBqBBc"R."R.9:c"R."R.9:"bk9HH}QCwqc 2H+jS	 :=> ? *  Hs 04As   K(Kc           	         t        j                         }dj                  |j                  d      xs g       }t	        j
                  | d         }t        j                  |       \  }}dj                  d t        | d   j                               D              }d|z   dz   |z   d	z   |z   }|r|d
|z   z  }|dz  }t	        j                  dt        |t        d      }t        dt        |d          dt        |d          d|        |S )N
facts_extramembersz

c              3   N   K   | ]  \  }}t        j                  ||        y w)N)F
shot_block).0r^   ss      ra   	<genexpr>zgen_rel.<locals>.<genexpr>/  s%      G'Etq!Q'Es   #%shotszPLACE MEMBERS:
z:

FULL ORIGINAL SCENE TEXTS (every scene at this place):

z+

ALL SHOTS AT THIS PLACE (full content):

z7

CREATOR CORRECTIONS (override any conflicting text):
z(

Build the relational block layout now.s22_bd_rel_v1gptmodelzrel: layers r7   z | elements r8   z
 | scenes )S14load_overridesjoinrR   r   members_blockrS   scene_textssortedr   llm
REL_SYSTEM
REL_SCHEMAprintlen)	reconovcorrectionsr   idxsscenesshot_blocksuserrU   s	            ra   gen_relr   *  s,   				B))BFF=17R8KooeI./G??5)LD&++ G'-eGn.B.B.D'EG GK(NO @@ CNND M 	 88D
%%T:U
KC	LS]+, -#j/"#:dV5 6Jrv   c                     dt        j                  | d      z   dz   dj                  d |D              z   dz   }t        j                  dt
        |t        d	
      S )NzPREVIOUS RELATIONAL DATA:
F)ensure_asciiz-

SOLVER VIOLATIONS (each must be resolved):
r   c              3   &   K   | ]	  }d |   yw)z- Nr   )r   rF   s     ra   r   zrepair_rel.<locals>.<genexpr>C  s     5*Q"QC*s   z!

Return the full corrected data.s22_bd_rel_repairr   r   )jsondumpsr   r   r   REPAIR_SYSTEMr   )rU   
violationsr   s      ra   
repair_relr   ?  se    )jj512@A ii5*556 4	4D
 55$mT: rv   c           	      N   dg i}t        |       }t        |dz         D ]  }t        |      \  }}}t        |||      }t        d| dz  }	|	j                         r|	j                  t        d| dz         t        j                  ||	       |d   j                  ||	j                  |||d       t        j                  d|       t        |       t        d| d	t        |       d
|	j                          |D ]  }
t        d|
        |r||k(  r |S t!        ||      } |S )Nroundsr@   	bd_code_rz.pngz	_prev.png)roundimgr   rU   r`   bd_code_rel_v1zround z: violations=z -> z   -)r   rangerb   r   OUTBexistsrenamerS   renderrO   namer   	save_plan
build_pager   r   r   )r   max_repairsplanrU   rndr`   rV   r\   r   r   rF   s              ra   runr   I  s(   b>D
%.C[1_%$)#J!zc5*5
yT**::<JJt	#i889

63XCHH-7)/1 	2 	
$d+4se=Z(9chhZHIA&! SK/K j)# &$ Krv   c                    d g }| d   D ]7  }|d   }dj                  fdt        |d   d       D              }|d	   d
   D ci c]  }|j                  d      |d    c}d dj                  fd|d
   D              }|j                  d      xs g }d}|r dj                  fd|D              }	d|	 d}dj                  fd|d   D              }
|j                  d|d    dt	        |d          d|d   rdnd d |d          d|d    d|
rd|
z   d z   nd! d"| d#| d$| d% |d&          d'       : t
        j                  d(dj                  |       d)d*+       t        d,t
                y c c}w )-Nc                 F    t        j                  t        | xs d            S )NrB   )_htmlescapestr)ts    ra   _esczbuild_page.<locals>._escd  s    ||CRL))rv   r   rU   rB   c              3   z   K   | ]2  }d  |d          d|d   dd |d          d |d          d	 4 yw)	<tr><td>r   	</td><td>r   gr   r   
</td></tr>Nr   )r   lr   s     ra   r   zbuild_page.<locals>.<genexpr>j  se      K J tAjM*+9Q|_Q4G H)%&iQy\0B/C:OIs   8;r7   c                     | d   S )Nr   r   )r   s    ra   r   zbuild_page.<locals>.<lambda>m  s    <rv   )keyr`   r8   rJ   rC   c           	          d| d    d| d    d| d   dd| d   dd		}| d
   dk7  r|d| d
    d| d   dd	z  }|d| d    d| d    z   S )Nzparent=r%   u    · r&   r'   r   u   %×r(   %r)   r   u    · attach z @r*   u    · rep=r+   r0   r   )r[   r   s     ra   _rel_txtzbuild_page.<locals>._rel_txtp  s    1X;-tAhK='
1~S7Aa9A6){1]#3"4Bq~a6HJJ!H+d1[>2BCCCrv   c              3      K   | ]t  }d  j                  |d   d             d |d          d |d          d |d          d  |             dd	j                  fd
|d   D               d v yw)z<tr><td><b>r   ?z</b></td><td>r   z<br><span class='mini'>z</span></td><td>r   z</td><td class='mini'>z<br>c              3   R   K   | ]  } |d          dz    |d         z      yw)r   z: r   Nr   )r   r   r   s     ra   r   z'build_page.<locals>.<genexpr>.<genexpr>}  s1     +oan\]D8,=,DtAgJGW,Wans   $'r3   r   N)rR   r   )r   r[   r   r   mks     ra   r   zbuild_page.<locals>.<genexpr>w  s      & % $rvvags345 6)%&&=d1T7m_)%& '  $Xa[ 12 3  &+oabcman+o oppz| %s   A:A=r9   c           
   3   l   K   | ]+  }d  |d          d |d          d |d          d - yw)r   r4   u    ↔ r5   r   r6   r   Nr   )r   r   r   s     ra   r   zbuild_page.<locals>.<genexpr>  sO       E>C 4#<.d1S6l^ <AhK()5>Cs   14uU   <table><tr><th>연결 (물리 접촉 검증 대상)</th><th>근거 (why_ko)</th></tr>z</table>c              3   6   K   | ]  }d  |       d  yw)z<li>z</li>Nr   )r   rF   r   s     ra   r   zbuild_page.<locals>.<genexpr>  s     E_T!WIU+_s   r   z
<h2>round r   u    — 검증 위반 u   건
u   (수리 후 재솔브)u   (최초 생성)z</h2>
<img src='out/blockset/r   z?v=z'>
z<ul class=vio>z</ul>u6   <p class='ok'>위반 0 — 결정론 검증 통과</p>u   
<details><summary>레이어 / 요소 관계 데이터 / 근거 인용</summary>
<table><tr><th>layer</th><th>h</th><th>name</th><th>desc_ko</th></tr>
u|   </table>
<table><tr><th>마커</th><th>요소</th><th>desc_ko</th><th>관계 (LLM 산출
그대로)</th><th>근거</th></tr>z	</table>
z"
<p class='mini'>layout_notes_ko: r:   z</p>
</details>
u<  <!doctype html><meta charset='utf-8'>
<title>s22 — 코드 렌더 BD v3 (관계 데이터+결정론 솔버)</title>
<style>
body{font-family:system-ui,'Apple SD Gothic Neo',sans-serif;margin:24px;
background:#fafafa;color:#222;max-width:1500px}
h1{font-size:20px} h2{font-size:16px;margin-top:30px;border-bottom:2px
solid #ddd;padding-bottom:4px}
img{width:100%;display:block;background:#fff;border:1px solid #ddd;
padding:6px;box-sizing:border-box}
table{border-collapse:collapse;font-size:12.5px;background:#fff;width:100%;
margin:8px 0}
td,th{border:1px solid #e0e0e0;padding:4px 8px;vertical-align:top}
.mini{font-size:11px;color:#667}
.vio{background:#fdecea;border:1px solid #e5b4ae;padding:8px 26px;
font-size:12.5px;color:#7a2e26}
.ok{background:#e8f4e8;border:1px solid #b6d7b6;padding:8px 12px;
font-size:13px;color:#2e6b2e;font-weight:600}
.note{background:#fff8e6;border:1px solid #eeddaa;padding:10px 14px;
font-size:13px}
details{margin:8px 0} summary{font-size:12.5px;color:#557;cursor:pointer}
</style>
<h1>s22 — 코드 렌더 BD v3: LLM=관계 데이터만 → 결정론 솔버(좌표)+검증 →
위반 되먹임 수리(≤2회) → s13 PIL 렌더</h1>
<div class='note'>재설계 근거(2026 조사): raw 좌표 직출=충돌 66.7% →
저차원 관계 DSL 13.6% → 결정론 검증 피드백 루프 0%
(<a href='https://arxiv.org/abs/2604.27555'>SpatialGrammar 2026-04</a> ·
<a href='https://arxiv.org/abs/2605.14117'>RLVR floor plan 2026-05</a> ·
<a href='https://arxiv.org/abs/2312.09067'>Holodeck</a> ·
<a href='https://arxiv.org/abs/2510.16147'>PSDL</a>).
LLM 산출=포함(parent)/9방위(anchor)/부모 대비 크기%/부착 변+변 위 위치%,
절대 좌표 0. 좌표·마커·색·범례=결정론 코드(s13 렌더러 재사용).
씬 원문 전체+멤버+샷+CREATOR CORRECTIONS 입력, 근거 인용 필수.</div>
r   zutf-8)encodingzpage -> )r   r   rR   rO   r   PAGE
write_textr   )r   secsrrU   lay_rowsr[   el_rowsconns
conn_table	conn_rowsvior   r   r   s              @@@ra   r   r   c  s&   * D(^h77 K CM/HIK K 238Z1HI1HAaeeElAhK'1HI	D '' & _& & &,"
  E>C E EI::CHNJggEQ|_EE W:,)#ao*>)? @wZ-> ? @QuX's1W:, 7%(C'!9;; 

 $$+9 - ""&s+<'=">!? @ 	A ^ 	OO  @  A!B C  !D 
HTF
W Js   
Fc                  X   t        j                         } | j                  ddddg       | j                         }|j                  dk(  rt        t        j                  d             y t        j                         }t        |       t        j                  dd|j                  d       y )	Nz--onlyallhtml)defaultchoicesr   stages22_bd_code)r    r   done)argparseArgumentParseradd_argument
parse_argsonlyr   r   	load_plan
load_reconr   runlog)apargsr   s      ra   mainr
    s{    		 	 	"BOOHeeV_OE==?DyyF1;;/01LLNEJHHgtyyIJrv   __main__)rE   )'__doc__r   r   r   r   syspathlibr   pathinsertr   __file__r%   
forest_libr   s13_blockset_v2rS   s14_blockgenr   OUTr   EXPr   ANCHORSSIDESr   	_EVIDENCEKINDSr   r   rb   rP   r   r   r   r   r   r
  __name__r   rv   ra   <module>r     s  .    
  3tH~,,- .   uuzuu~
;$C+
J x FH+=I?7#U(D E	
 !"h*7I)&(9KOM I$)	.+ ,
 % Q#68$Q#)Q# )Q# Xsyy9	Q#
 *Q# h0BCQ# vx(Q# x9Q# fh'Q# *1682DQ# He<Q# &(+Q# vy)Q# 8gw5GHQ# (VZ4HIQ# 	Q# 2 %*)0+ ,* !(!' 2&(9K&,h%79,$)3+ , #H-C"F IM'
R  E E$%N<;@*4Vr	K zF rv   