"""SSOT용: 골든(TCP540) 토치 부착의 truthTool-로컬 순변환(pos·quat·scale) 박제값 추출."""
import asyncio, json
from playwright.async_api import async_playwright
URL='http://localhost:8090/DOZIKWORKS_OS_v5_locked.dc.html'
async def main():
    async with async_playwright() as p:
        br=await p.chromium.launch(channel='msedge',headless=True)
        pg=await br.new_page()
        await pg.goto(URL); await pg.wait_for_function("window.__dzw && window.__dzw._torchMesh",timeout=15000)
        r=await pg.evaluate("""()=>{ const d=window.__dzw,T=d._T;
          const me=d._torchMesh, pivot=d._torchPivot; pivot.updateMatrix(); me.updateMatrix();
          // 순변환 = pivot.matrix · me.matrix (torchNode=truthTool-로컬 프레임)
          const net=new T.Matrix4().multiplyMatrices(pivot.matrix, me.matrix);
          const p=new T.Vector3(), qq=new T.Quaternion(), s=new T.Vector3(); net.decompose(p,qq,s);
          const e=new T.Euler().setFromQuaternion(qq,'XYZ'); const R=180/Math.PI;
          return { pos:[+p.x.toFixed(4),+p.y.toFixed(4),+p.z.toFixed(4)],
                   quat:[+qq.x.toFixed(6),+qq.y.toFixed(6),+qq.z.toFixed(6),+qq.w.toFixed(6)],
                   eulerXYZdeg:[+(e.x*R).toFixed(3),+(e.y*R).toFixed(3),+(e.z*R).toFixed(3)],
                   scale:[+s.x.toFixed(4),+s.y.toFixed(4),+s.z.toFixed(4)],
                   meshName:me.name }; }""")
        print(json.dumps(r,ensure_ascii=False,indent=1)); await br.close()
asyncio.run(main())
