@forgeax/view 0.5.0-dev.13604.c415409c3b9d → 0.5.0-dev.13713.d28c4863d779
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -9
- package/dist/build-revision.json +1 -1
- package/dist/modules/backend.mjs +34 -34
- package/dist/modules/browser.mjs +55 -49
- package/dist/modules/chunks/{chunk-EWSCJF77.mjs → chunk-2CMCY54A.mjs} +2 -2
- package/dist/modules/chunks/{chunk-M6S5YA6X.mjs → chunk-2RUKPDIE.mjs} +4 -4
- package/dist/modules/chunks/{chunk-M6S5YA6X.mjs.map → chunk-2RUKPDIE.mjs.map} +1 -1
- package/dist/modules/chunks/{chunk-DWT3TA6M.mjs → chunk-3FBX3P3H.mjs} +9 -8
- package/dist/modules/chunks/chunk-3FBX3P3H.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-6KM24NH6.mjs → chunk-3Y5WN22T.mjs} +3 -3
- package/dist/modules/chunks/chunk-3Y5WN22T.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-YFQGSDK3.mjs → chunk-45WL24XN.mjs} +2 -2
- package/dist/modules/chunks/{chunk-FMCHH5R4.mjs → chunk-4FYKRL46.mjs} +3 -3
- package/dist/modules/chunks/{chunk-VW2ZF3P4.mjs → chunk-4MJHVZMB.mjs} +6 -6
- package/dist/modules/chunks/{chunk-XQYF2P6M.mjs → chunk-5HVXQEO3.mjs} +7 -7
- package/dist/modules/chunks/{chunk-XMP4THLF.mjs → chunk-66LM6NO6.mjs} +4 -4
- package/dist/modules/chunks/{chunk-P4UPH74B.mjs → chunk-6C4OCCYB.mjs} +12 -12
- package/dist/modules/chunks/{chunk-P4UPH74B.mjs.map → chunk-6C4OCCYB.mjs.map} +1 -1
- package/dist/modules/chunks/{chunk-ZGOGO7SS.mjs → chunk-6J27SWMY.mjs} +1 -1
- package/dist/modules/chunks/{chunk-JK7K7RG3.mjs → chunk-6VK7HB4X.mjs} +4 -4
- package/dist/modules/chunks/{chunk-HRKW766Y.mjs → chunk-6WZZ7TIC.mjs} +2 -2
- package/dist/modules/chunks/{chunk-FICPCJKR.mjs → chunk-7DFCIN3T.mjs} +3 -3
- package/dist/modules/chunks/{chunk-FICPCJKR.mjs.map → chunk-7DFCIN3T.mjs.map} +1 -1
- package/dist/modules/chunks/{chunk-U64FRQKP.mjs → chunk-7MWZK7HS.mjs} +3 -3
- package/dist/modules/chunks/{chunk-F5RLQAPN.mjs → chunk-A7OGXJAV.mjs} +3 -3
- package/dist/modules/chunks/{chunk-QUFVUMSY.mjs → chunk-AUINYWZP.mjs} +2 -2
- package/dist/modules/chunks/{chunk-PZIAKZJC.mjs → chunk-B24VYGHV.mjs} +3 -3
- package/dist/modules/chunks/{chunk-SRYQLFBV.mjs → chunk-BIUWJROZ.mjs} +3 -3
- package/dist/modules/chunks/{chunk-SRYQLFBV.mjs.map → chunk-BIUWJROZ.mjs.map} +2 -2
- package/dist/modules/chunks/{chunk-X4NNZ5X6.mjs → chunk-C2AMOM7H.mjs} +3 -3
- package/dist/modules/chunks/{chunk-IZAHIOFU.mjs → chunk-C3WVSJZF.mjs} +6 -6
- package/dist/modules/chunks/{chunk-2Z5KEV6L.mjs → chunk-CAXCOZ7Y.mjs} +3 -3
- package/dist/modules/chunks/{chunk-HWZCLROY.mjs → chunk-CN6YN4HP.mjs} +251 -45
- package/dist/modules/chunks/chunk-CN6YN4HP.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-B6QUJ33G.mjs → chunk-CXFQME65.mjs} +3 -3
- package/dist/modules/chunks/{chunk-IJPWKKIU.mjs → chunk-CYOLEAAY.mjs} +14 -13
- package/dist/modules/chunks/chunk-CYOLEAAY.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-U6UMATPV.mjs → chunk-CYU3WWN6.mjs} +3 -3
- package/dist/modules/chunks/{chunk-AGVLPYVE.mjs → chunk-D2LZIQE2.mjs} +2 -2
- package/dist/modules/chunks/{chunk-5YTMN435.mjs → chunk-DC5JP46Y.mjs} +13 -3
- package/dist/modules/chunks/chunk-DC5JP46Y.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-YNHEYXDG.mjs → chunk-DOU4MNMQ.mjs} +3 -3
- package/dist/modules/chunks/{chunk-ZIDEETK4.mjs → chunk-E4G4HDOC.mjs} +3 -3
- package/dist/modules/chunks/{chunk-ZHO2G4JR.mjs → chunk-EZAJ66NW.mjs} +3 -3
- package/dist/modules/chunks/{chunk-APD2EWSZ.mjs → chunk-FIWL6TQS.mjs} +2 -2
- package/dist/modules/chunks/{chunk-U5J7OTEB.mjs → chunk-FSSARTVM.mjs} +3 -3
- package/dist/modules/chunks/{chunk-47RJSHLM.mjs → chunk-FXXPWAXM.mjs} +3 -3
- package/dist/modules/chunks/{chunk-D2RCKG7Q.mjs → chunk-G2QCXN56.mjs} +6 -6
- package/dist/modules/chunks/{chunk-4T3D67CS.mjs → chunk-GRDCA6LD.mjs} +8 -8
- package/dist/modules/chunks/{chunk-4T3D67CS.mjs.map → chunk-GRDCA6LD.mjs.map} +1 -1
- package/dist/modules/chunks/{chunk-WVU3CQ62.mjs → chunk-GUVUL6D2.mjs} +3 -3
- package/dist/modules/chunks/{chunk-YLCJNKIW.mjs → chunk-I32EONBF.mjs} +70 -30
- package/dist/modules/chunks/chunk-I32EONBF.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-E3PJGTLI.mjs → chunk-IGIELQZ2.mjs} +5 -5
- package/dist/modules/chunks/{chunk-5PHAXNFO.mjs → chunk-IMDR26Y3.mjs} +3 -3
- package/dist/modules/chunks/{chunk-55F55BQY.mjs → chunk-JVOHFCI4.mjs} +3 -3
- package/dist/modules/chunks/{chunk-6I7RY73G.mjs → chunk-KCM7ZCQ3.mjs} +5 -5
- package/dist/modules/chunks/chunk-KCM7ZCQ3.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-K2QZRFLE.mjs → chunk-KJTMDFFX.mjs} +4 -4
- package/dist/modules/chunks/{chunk-KX2WU5Z6.mjs → chunk-KPLESRQY.mjs} +3 -3
- package/dist/modules/chunks/{chunk-PW5CE2Y6.mjs → chunk-KUOWDTI6.mjs} +2 -2
- package/dist/modules/chunks/chunk-L6IHUN7X.mjs +13 -0
- package/dist/modules/chunks/chunk-L6IHUN7X.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-INTTYJVW.mjs → chunk-LBQ6DFMP.mjs} +2 -2
- package/dist/modules/chunks/{chunk-OKQ5RBKO.mjs → chunk-LVWHM3UN.mjs} +2 -2
- package/dist/modules/chunks/{chunk-D57DDEV2.mjs → chunk-MDQMARAN.mjs} +6 -6
- package/dist/modules/chunks/{chunk-D57DDEV2.mjs.map → chunk-MDQMARAN.mjs.map} +2 -2
- package/dist/modules/chunks/{chunk-STQPRNEO.mjs → chunk-MLXRIWJA.mjs} +2 -2
- package/dist/modules/chunks/{chunk-D25SR5FS.mjs → chunk-N2SH3JGI.mjs} +3 -3
- package/dist/modules/chunks/{chunk-KI4WGTWL.mjs → chunk-N7NXZ6R3.mjs} +4 -4
- package/dist/modules/chunks/{chunk-KI4WGTWL.mjs.map → chunk-N7NXZ6R3.mjs.map} +2 -2
- package/dist/modules/chunks/{chunk-7IGFAI5H.mjs → chunk-O5QX6H3U.mjs} +5 -5
- package/dist/modules/chunks/{chunk-5W7SC5D4.mjs → chunk-P2Y73QJJ.mjs} +11 -1
- package/dist/modules/chunks/{chunk-5W7SC5D4.mjs.map → chunk-P2Y73QJJ.mjs.map} +2 -2
- package/dist/modules/chunks/{chunk-FNRGLCZW.mjs → chunk-PCQNUFDL.mjs} +39 -13
- package/dist/modules/chunks/chunk-PCQNUFDL.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-46UEGAXY.mjs → chunk-Q7M7VUOZ.mjs} +6 -6
- package/dist/modules/chunks/{chunk-XE6ITXHT.mjs → chunk-QB33CMEU.mjs} +2 -2
- package/dist/modules/chunks/{chunk-E3Z7GLFU.mjs → chunk-QJHQN6OD.mjs} +15 -4
- package/dist/modules/chunks/chunk-QJHQN6OD.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-KAGFU64Y.mjs → chunk-QW2VT3XB.mjs} +2 -2
- package/dist/modules/chunks/{chunk-U5R6MVM4.mjs → chunk-RFTLGEB5.mjs} +2 -2
- package/dist/modules/chunks/{chunk-VKNIYV2W.mjs → chunk-RYYKMDNI.mjs} +202 -35
- package/dist/modules/chunks/chunk-RYYKMDNI.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-P5XMFZY4.mjs → chunk-SFB5BDTB.mjs} +2 -2
- package/dist/modules/chunks/{chunk-4D3Q7K44.mjs → chunk-SNICHQJP.mjs} +2 -2
- package/dist/modules/chunks/{chunk-CX5WREJC.mjs → chunk-SPGFO2TA.mjs} +2 -2
- package/dist/modules/chunks/{chunk-H256DQT6.mjs → chunk-TMPTVIAP.mjs} +2 -2
- package/dist/modules/chunks/{chunk-OQXDADAS.mjs → chunk-UWJYROKS.mjs} +6 -6
- package/dist/modules/chunks/chunk-UWJYROKS.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-TTRUYO7Q.mjs → chunk-UZH2664E.mjs} +3 -3
- package/dist/modules/chunks/{chunk-TTRUYO7Q.mjs.map → chunk-UZH2664E.mjs.map} +2 -2
- package/dist/modules/chunks/{chunk-CKYXAT7H.mjs → chunk-VC4OEPDH.mjs} +2 -2
- package/dist/modules/chunks/{chunk-RJVOH7G2.mjs → chunk-VKWEA6NG.mjs} +27 -27
- package/dist/modules/chunks/{chunk-LZ57Y73Z.mjs → chunk-VSJOW7J4.mjs} +9 -7
- package/dist/modules/chunks/chunk-VSJOW7J4.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-PVP5YBNR.mjs → chunk-WFM434WJ.mjs} +2 -2
- package/dist/modules/chunks/{chunk-TXLD7JI5.mjs → chunk-WJNASQF2.mjs} +2 -2
- package/dist/modules/chunks/{chunk-357UOBAS.mjs → chunk-XUNDH3E7.mjs} +2 -2
- package/dist/modules/chunks/{chunk-PJFFCRRD.mjs → chunk-YDARD4EP.mjs} +2 -2
- package/dist/modules/chunks/{chunk-27XASYEH.mjs → chunk-YU3HRQX7.mjs} +17 -11
- package/dist/modules/chunks/chunk-YU3HRQX7.mjs.map +7 -0
- package/dist/modules/chunks/{chunk-EZSGDSCC.mjs → chunk-ZRE7BDDB.mjs} +30 -5
- package/dist/modules/chunks/chunk-ZRE7BDDB.mjs.map +7 -0
- package/dist/modules/cli-contributions.mjs +14 -14
- package/dist/modules/cli.mjs +5 -5
- package/dist/modules/command-executor.mjs +3 -3
- package/dist/modules/embedded.mjs +82 -42
- package/dist/modules/embedded.mjs.map +2 -2
- package/dist/modules/extension-bridge.mjs +4 -4
- package/dist/modules/frontend-root.mjs +46 -46
- package/dist/modules/index.mjs +71 -65
- package/dist/modules/index.mjs.map +1 -1
- package/dist/modules/pages/scene.mjs +5 -5
- package/dist/modules/plugin.mjs +35 -35
- package/dist/modules/plugins/asset/frontend.mjs +10 -10
- package/dist/modules/plugins/asset/identity.mjs +9 -9
- package/dist/modules/plugins/asset/ui.mjs +3 -3
- package/dist/modules/plugins/content-browser/frontend.mjs +3 -3
- package/dist/modules/plugins/content-browser/identity.mjs +2 -2
- package/dist/modules/plugins/content-browser/ui.mjs +3 -3
- package/dist/modules/plugins/display/api.mjs +1 -1
- package/dist/modules/plugins/display/backend.mjs +4 -4
- package/dist/modules/plugins/display/frontend.mjs +5 -5
- package/dist/modules/plugins/display/identity.mjs +2 -2
- package/dist/modules/plugins/display/ui.mjs +3 -3
- package/dist/modules/plugins/inspector/frontend.mjs +3 -3
- package/dist/modules/plugins/inspector/identity.mjs +2 -2
- package/dist/modules/plugins/inspector/ui.mjs +3 -3
- package/dist/modules/plugins/material/frontend.mjs +10 -10
- package/dist/modules/plugins/material/identity.mjs +9 -9
- package/dist/modules/plugins/material/ui.mjs +10 -10
- package/dist/modules/plugins/mesh/frontend.mjs +10 -10
- package/dist/modules/plugins/mesh/identity.mjs +9 -9
- package/dist/modules/plugins/mesh/ui.mjs +10 -10
- package/dist/modules/plugins/plugins/api.mjs +4 -4
- package/dist/modules/plugins/plugins/backend.mjs +7 -7
- package/dist/modules/plugins/plugins/cli.mjs +5 -5
- package/dist/modules/plugins/plugins/frontend.mjs +3 -3
- package/dist/modules/plugins/plugins/identity.mjs +2 -2
- package/dist/modules/plugins/plugins/runtime.mjs +6 -6
- package/dist/modules/plugins/plugins/ui/panel.mjs +3 -3
- package/dist/modules/plugins/plugins/ui.mjs +4 -4
- package/dist/modules/plugins/scene/frontend.mjs +5 -5
- package/dist/modules/plugins/scene/identity.mjs +2 -2
- package/dist/modules/plugins/scene-tree/frontend.mjs +3 -3
- package/dist/modules/plugins/scene-tree/identity.mjs +2 -2
- package/dist/modules/plugins/scene-tree/ui.mjs +3 -3
- package/dist/modules/plugins/texture/frontend.mjs +10 -10
- package/dist/modules/plugins/texture/identity.mjs +9 -9
- package/dist/modules/plugins/texture/ui.mjs +10 -10
- package/dist/modules/plugins/viewport/frontend.mjs +12 -12
- package/dist/modules/plugins/viewport/identity.mjs +2 -2
- package/dist/modules/plugins/viewport/presentation.mjs +4 -4
- package/dist/modules/plugins/viewport/schema.mjs +2 -2
- package/dist/modules/plugins/viewport/workspace-shell.mjs +9 -9
- package/dist/modules/product.mjs +35 -35
- package/dist/modules/shell/frontend.mjs +1 -1
- package/dist/modules/viewer/catalog/backend.mjs +31 -31
- package/dist/modules/viewer/catalog/frontend.mjs +42 -42
- package/dist/modules/viewer/catalog/shared.mjs +20 -20
- package/dist/modules/viewer/catalog.mjs +51 -51
- package/dist/modules/viewer/cli.mjs +10 -10
- package/dist/modules/viewer-host/frontend.mjs +48 -48
- package/dist/modules/viewer-host/page-registry.mjs +6 -6
- package/dist/modules/viewer-host.mjs +7 -7
- package/dist/modules/viewer.mjs +51 -51
- package/dist/modules/workspace/api.mjs +1 -1
- package/dist/modules/workspace/backend.mjs +10 -10
- package/dist/modules/workspace/broker.mjs +9 -9
- package/dist/modules/workspace/cli.mjs +2 -2
- package/dist/modules/workspace/client.mjs +3 -3
- package/dist/modules/workspace/command-error.mjs +2 -2
- package/dist/modules/workspace/contract.mjs +7 -1
- package/dist/modules/workspace/engine-adapter.mjs +3 -3
- package/dist/modules/workspace/extension-bridge.mjs +4 -4
- package/dist/modules/workspace/frontend-plugin.mjs +8 -8
- package/dist/modules/workspace/frontend.mjs +9 -9
- package/dist/modules/workspace/page-title.mjs +3 -3
- package/dist/modules/workspace/presentation.mjs +4 -4
- package/dist/modules/workspace/preview-surface.mjs +7 -7
- package/dist/modules/workspace/project-session.mjs +2 -2
- package/dist/modules/workspace/render-resize-sync.mjs +2 -2
- package/dist/modules/workspace/resident.mjs +4 -4
- package/dist/modules/workspace/resource-open.mjs +5 -5
- package/dist/modules/workspace/resource-page.mjs +8 -8
- package/dist/modules/workspace/tool-runtime.mjs +7 -5
- package/dist/modules/workspace/view-trace.mjs +3 -3
- package/dist/modules/workspace/workspace-recovery.mjs +4 -4
- package/dist/modules/workspace/workspace-state.mjs +2 -2
- package/dist/modules/workspace-frontend.mjs +8 -8
- package/dist/viewer/assets/{embedded-DXSSFAyM.js → embedded-BKEAtUD6.js} +2 -2
- package/dist/viewer/assets/{embedded-DXSSFAyM.js.map → embedded-BKEAtUD6.js.map} +1 -1
- package/dist/viewer/assets/main-BQrn6wsa.js +22 -0
- package/dist/viewer/assets/main-BQrn6wsa.js.map +1 -0
- package/dist/viewer/assets/{panels-lazy-DqCwhGd9.js → panels-lazy-C_Cs-76A.js} +2 -2
- package/dist/viewer/assets/{panels-lazy-DqCwhGd9.js.map → panels-lazy-C_Cs-76A.js.map} +1 -1
- package/dist/viewer/assets/panels-ui-DEDHJLuE.js +12 -0
- package/dist/viewer/assets/panels-ui-DEDHJLuE.js.map +1 -0
- package/dist/viewer/assets/style-CcYzhsIZ.css +2 -0
- package/dist/viewer/assets/{wgpu_wasm--oeqTwVY.js → wgpu_wasm-cNR5izZM.js} +126 -0
- package/dist/viewer/assets/{wgpu_wasm_bg-WoZ1YI1I.wasm → wgpu_wasm_bg-Dps0jNcQ.wasm} +0 -0
- package/dist/viewer/index.html +4 -4
- package/dist/viewer/panels.js +1 -1
- package/package.json +2 -2
- package/scripts/verify-runtime-content-engine.mjs +7 -4
- package/skills/forgeax-view-cli/SKILL.md +11 -0
- package/dist/modules/chunks/chunk-27XASYEH.mjs.map +0 -7
- package/dist/modules/chunks/chunk-5YTMN435.mjs.map +0 -7
- package/dist/modules/chunks/chunk-6I7RY73G.mjs.map +0 -7
- package/dist/modules/chunks/chunk-6KM24NH6.mjs.map +0 -7
- package/dist/modules/chunks/chunk-DWT3TA6M.mjs.map +0 -7
- package/dist/modules/chunks/chunk-E3Z7GLFU.mjs.map +0 -7
- package/dist/modules/chunks/chunk-EZSGDSCC.mjs.map +0 -7
- package/dist/modules/chunks/chunk-FNRGLCZW.mjs.map +0 -7
- package/dist/modules/chunks/chunk-HWZCLROY.mjs.map +0 -7
- package/dist/modules/chunks/chunk-IJPWKKIU.mjs.map +0 -7
- package/dist/modules/chunks/chunk-LZ57Y73Z.mjs.map +0 -7
- package/dist/modules/chunks/chunk-OQXDADAS.mjs.map +0 -7
- package/dist/modules/chunks/chunk-QELNKFSI.mjs +0 -10
- package/dist/modules/chunks/chunk-QELNKFSI.mjs.map +0 -7
- package/dist/modules/chunks/chunk-VKNIYV2W.mjs.map +0 -7
- package/dist/modules/chunks/chunk-YLCJNKIW.mjs.map +0 -7
- package/dist/viewer/assets/main-CI6ZQziX.js +0 -22
- package/dist/viewer/assets/main-CI6ZQziX.js.map +0 -1
- package/dist/viewer/assets/panels-ui-CfUtl68h.js +0 -12
- package/dist/viewer/assets/panels-ui-CfUtl68h.js.map +0 -1
- package/dist/viewer/assets/style-gOtSMZif.css +0 -2
- /package/dist/modules/chunks/{chunk-EWSCJF77.mjs.map → chunk-2CMCY54A.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-YFQGSDK3.mjs.map → chunk-45WL24XN.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-FMCHH5R4.mjs.map → chunk-4FYKRL46.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-VW2ZF3P4.mjs.map → chunk-4MJHVZMB.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-XQYF2P6M.mjs.map → chunk-5HVXQEO3.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-XMP4THLF.mjs.map → chunk-66LM6NO6.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-ZGOGO7SS.mjs.map → chunk-6J27SWMY.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-JK7K7RG3.mjs.map → chunk-6VK7HB4X.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-HRKW766Y.mjs.map → chunk-6WZZ7TIC.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-U64FRQKP.mjs.map → chunk-7MWZK7HS.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-F5RLQAPN.mjs.map → chunk-A7OGXJAV.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-QUFVUMSY.mjs.map → chunk-AUINYWZP.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-PZIAKZJC.mjs.map → chunk-B24VYGHV.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-X4NNZ5X6.mjs.map → chunk-C2AMOM7H.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-IZAHIOFU.mjs.map → chunk-C3WVSJZF.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-2Z5KEV6L.mjs.map → chunk-CAXCOZ7Y.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-B6QUJ33G.mjs.map → chunk-CXFQME65.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-U6UMATPV.mjs.map → chunk-CYU3WWN6.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-AGVLPYVE.mjs.map → chunk-D2LZIQE2.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-YNHEYXDG.mjs.map → chunk-DOU4MNMQ.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-ZIDEETK4.mjs.map → chunk-E4G4HDOC.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-ZHO2G4JR.mjs.map → chunk-EZAJ66NW.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-APD2EWSZ.mjs.map → chunk-FIWL6TQS.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-U5J7OTEB.mjs.map → chunk-FSSARTVM.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-47RJSHLM.mjs.map → chunk-FXXPWAXM.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-D2RCKG7Q.mjs.map → chunk-G2QCXN56.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-WVU3CQ62.mjs.map → chunk-GUVUL6D2.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-E3PJGTLI.mjs.map → chunk-IGIELQZ2.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-5PHAXNFO.mjs.map → chunk-IMDR26Y3.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-55F55BQY.mjs.map → chunk-JVOHFCI4.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-K2QZRFLE.mjs.map → chunk-KJTMDFFX.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-KX2WU5Z6.mjs.map → chunk-KPLESRQY.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-PW5CE2Y6.mjs.map → chunk-KUOWDTI6.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-INTTYJVW.mjs.map → chunk-LBQ6DFMP.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-OKQ5RBKO.mjs.map → chunk-LVWHM3UN.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-STQPRNEO.mjs.map → chunk-MLXRIWJA.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-D25SR5FS.mjs.map → chunk-N2SH3JGI.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-7IGFAI5H.mjs.map → chunk-O5QX6H3U.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-46UEGAXY.mjs.map → chunk-Q7M7VUOZ.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-XE6ITXHT.mjs.map → chunk-QB33CMEU.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-KAGFU64Y.mjs.map → chunk-QW2VT3XB.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-U5R6MVM4.mjs.map → chunk-RFTLGEB5.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-P5XMFZY4.mjs.map → chunk-SFB5BDTB.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-4D3Q7K44.mjs.map → chunk-SNICHQJP.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-CX5WREJC.mjs.map → chunk-SPGFO2TA.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-H256DQT6.mjs.map → chunk-TMPTVIAP.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-CKYXAT7H.mjs.map → chunk-VC4OEPDH.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-RJVOH7G2.mjs.map → chunk-VKWEA6NG.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-PVP5YBNR.mjs.map → chunk-WFM434WJ.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-TXLD7JI5.mjs.map → chunk-WJNASQF2.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-357UOBAS.mjs.map → chunk-XUNDH3E7.mjs.map} +0 -0
- /package/dist/modules/chunks/{chunk-PJFFCRRD.mjs.map → chunk-YDARD4EP.mjs.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/view-plugin-scene-tree/src/ui/mount.tsx", "../../../packages/view-plugin-scene-tree/src/ui/SceneTreePanel.tsx", "../../../packages/view-plugin-scene-tree/src/i18n/useTranslation.ts", "../../../packages/view-plugin-scene-tree/src/hierarchy-filters.ts", "../../../packages/view-plugin-scene-tree/src/hierarchy.ts", "../../../packages/view-plugin-scene-tree/src/ui/scene-tree.css"],
|
|
4
|
-
"sourcesContent": ["import type { ComponentProps } from 'react';\nimport '@forgeax/view-components/styles.css';\nimport { OverlayRootProvider } from '@forgeax/view-components';\nimport '../i18n/index.ts';\nimport { createRoot } from 'react-dom/client';\nimport { SceneTreePanel } from './SceneTreePanel';\nimport './scene-tree.css';\n\nexport async function mountSceneTreePanel(props: ComponentProps<typeof SceneTreePanel> & { mountElement: HTMLElement; overlayRoot?: HTMLElement }) {\n if (!props.mountElement) throw new TypeError('mountSceneTreePanel requires mountElement');\n const root = createRoot(props.mountElement);\n root.render(\n <OverlayRootProvider root={props.overlayRoot ?? props.mountElement}>\n <SceneTreePanel client={props.client} />\n </OverlayRootProvider>,\n );\n return async () => root.unmount();\n}\n", "import type { WorkspaceState } from '@forgeax/view-workspace-core/contract';\nimport {\n Box,\n Braces,\n Camera,\n ChevronDown,\n ChevronRight,\n CircleUserRound,\n Crosshair,\n Filter,\n Folder,\n Layers,\n Lightbulb,\n Maximize2,\n Minimize2,\n Settings,\n X,\n} from 'lucide-react';\nimport {\n Checkbox,\n EmptyState,\n useOverlayRoot,\n FloatingMenu,\n IconButton,\n PanelHeader,\n SearchField,\n Toolbar,\n useWorkspaceClientConnected,\n type AnchorRect,\n} from '@forgeax/view-components';\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n type MouseEvent,\n type ReactNode,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { useTranslation } from '../i18n/useTranslation';\nimport { SCENE_TREE_ACTIONS } from '../schema.ts';\nimport type { ViewWorkspaceClient } from '@forgeax/view-workspace-core/client';\nimport { VIEW_WORKSPACE_TAB_ID, jsonUnchanged } from '@forgeax/view-workspace-core/contract';\nimport { createWorkspaceObservation, createWorkspaceStateReader } from '@forgeax/view-workspace-core/workspace-state';\nimport {\n entityMatchesSceneTreeFilters,\n hierarchyTypeCategory,\n} from '../hierarchy-filters.ts';\nimport {\n HIERARCHY_SCENE_FOLDER_ID,\n isSceneRootRow,\n sceneTreeComponentFilters,\n normalizeSceneTreeRows,\n type HierarchyRow,\n} from '../hierarchy.ts';\n\ntype SceneTreeFilterOption = {\n id: string;\n label?: string;\n count?: number;\n};\n\ntype SceneSelectionClient = Pick<\n ViewWorkspaceClient,\n 'subscribe' | 'getState' | 'selectSceneEntity' | 'clearSceneSelection' | 'getSceneTree' | 'call' | 'onDisconnect' | 'transport'\n>;\n\ntype WorkspacePreviewSnapshot = WorkspaceState;\n\ntype MenuItem =\n | { kind: 'title'; label: string; icon?: ReactNode }\n | { kind: 'separator' }\n | {\n kind: 'item';\n id: string;\n label: string;\n icon?: ReactNode;\n shortcut?: string;\n disabled?: boolean;\n danger?: boolean;\n forge?: boolean;\n children?: MenuItem[];\n action?: () => void;\n };\ntype MenuState = { x: number; y: number; items: MenuItem[] } | null;\n\nfunction rowComponentNames(row: HierarchyRow) {\n if (Array.isArray(row.componentNames) && row.componentNames.length > 0) {\n return row.componentNames;\n }\n return row.typeKey ? [String(row.typeKey)] : [];\n}\n\nfunction rowType(row: HierarchyRow) {\n if (isSceneRootRow(row)) return 'scene';\n if (row.kind === 'folder') return 'group';\n const primary = rowComponentNames(row).find((name) => name !== 'Transform') ?? row.typeKey;\n if (!primary) return 'mesh';\n return hierarchyTypeCategory(String(primary));\n}\n\nfunction filterOptionIcon(id: string) {\n switch (hierarchyTypeCategory(id)) {\n case 'camera': return <Camera size={14} />;\n case 'light': return <Lightbulb size={14} />;\n case 'character': return <CircleUserRound size={14} />;\n case 'group': return <Layers size={14} />;\n default: return <Box size={14} />;\n }\n}\n\nfunction RowIcon({ row }: { row: HierarchyRow }) {\n if (isSceneRootRow(row)) return <Folder size={15} />;\n if (row.kind === 'folder') return <Layers size={15} />;\n if (row.typeKey === 'directionalLight') return <Lightbulb size={15} />;\n if (row.typeKey === 'camera') return <Camera size={15} />;\n if (row.name === 'Player') return <CircleUserRound size={15} />;\n return <Box size={15} />;\n}\n\nfunction HierarchyContextMenu({ state, close }: { state: Exclude<MenuState, null>; close: () => void }) {\n const overlayRoot = useOverlayRoot();\n const [submenu, setSubmenu] = useState<string | null>(null);\n useEffect(() => {\n const dismiss = () => close();\n const escape = (event: KeyboardEvent) => event.key === 'Escape' && close();\n window.addEventListener('pointerdown', dismiss);\n window.addEventListener('keydown', escape);\n return () => {\n window.removeEventListener('pointerdown', dismiss);\n window.removeEventListener('keydown', escape);\n };\n }, [close]);\n const renderItems = (items: MenuItem[], nested = false) => (\n <div className={nested ? 'hier-context-submenu' : 'hier-context-menu'}>\n {items.map((item, index) => {\n if (item.kind === 'separator') return <i className=\"hier-context-separator\" key={`sep-${index}`} />;\n if (item.kind === 'title') return <div className=\"hier-context-title\" key={`title-${index}`}>{item.icon}{item.label}</div>;\n return (\n <div className=\"hier-context-item-wrap\" key={item.id} onPointerEnter={() => item.children && setSubmenu(item.id)}>\n <button\n type=\"button\"\n role=\"menuitem\"\n data-operation={item.id}\n data-danger={item.danger || undefined}\n data-forge={item.forge || undefined}\n disabled={item.disabled}\n onClick={() => {\n if (item.children) {\n setSubmenu(submenu === item.id ? null : item.id);\n return;\n }\n item.action?.();\n close();\n }}\n >\n <span className=\"hier-context-icon\">{item.icon}</span>\n <span>{item.label}</span>\n {item.shortcut ? <kbd>{item.shortcut}</kbd> : null}\n {item.children ? <ChevronRight size={12} /> : null}\n </button>\n {item.children && submenu === item.id ? renderItems(item.children, true) : null}\n </div>\n );\n })}\n </div>\n );\n return createPortal(\n <div\n className=\"hier-context-position\"\n data-action={SCENE_TREE_ACTIONS.showContextMenu}\n role=\"menu\"\n style={{\n left: Math.max(8, Math.min(state.x, window.innerWidth - 260)),\n top: Math.max(8, Math.min(state.y, window.innerHeight - 420)),\n }}\n onPointerDown={(event) => event.stopPropagation()}\n onContextMenu={(event) => event.preventDefault()}\n >\n {renderItems(state.items)}\n </div>,\n overlayRoot ?? document.body,\n );\n}\n\nfunction highlighted(value: string, query: string) {\n const index = value.toLowerCase().indexOf(query.toLowerCase());\n if (!query || index < 0) return value;\n return <>{value.slice(0, index)}<mark className=\"hl\">{value.slice(index, index + query.length)}</mark>{value.slice(index + query.length)}</>;\n}\n\nexport function SceneTreePanel(props: { client?: SceneSelectionClient }) {\n if (!props.client) {\n return (\n <EmptyState\n title=\"Scene hierarchy unavailable\"\n description=\"Connect to the View workspace API to load the Engine scene tree.\"\n />\n );\n }\n return <SceneTreeLivePanel client={props.client} />;\n}\n\nfunction useEngineSceneRows(\n client: SceneSelectionClient,\n workspace: WorkspacePreviewSnapshot | null,\n connected: boolean,\n reader: ReturnType<typeof createWorkspaceStateReader>,\n) {\n const [projection, setProjection] = useState<{ key: string; rows: HierarchyRow[]; failed: boolean; hasMore: boolean } | null>(null);\n const [pageCount, setPageCount] = useState(1);\n const target = workspace?.preview?.target;\n const projectId = workspace?.project?.id;\n const key = `${target?.targetId}:${target?.generation}`;\n const current = projection?.key === key ? projection : null;\n const rows = current?.rows ?? [];\n\n useEffect(() => { setPageCount(1); }, [target?.targetId, target?.generation]);\n\n useEffect(() => {\n if (!connected || !target?.targetId || !projectId) {\n if (!connected) return;\n setProjection(null);\n return;\n }\n const observation = createWorkspaceObservation(reader, (current: WorkspacePreviewSnapshot | null) =>\n current?.project?.id === projectId &&\n current?.preview?.target?.targetId === target.targetId &&\n current?.preview?.target?.generation === target.generation);\n const { signal } = observation;\n let timer: ReturnType<typeof setTimeout>;\n const refresh = async () => {\n if (signal.aborted) return;\n let retryDelay = 500;\n try {\n const binding = {\n tabId: VIEW_WORKSPACE_TAB_ID, projectId, targetId: target.targetId,\n targetGeneration: target.generation, signal,\n };\n const result = await client.getSceneTree({ ...binding, limit: 1000 });\n if (signal.aborted) return;\n const nodes = [...(result.nodes ?? [])];\n let nextOffset = result.nextOffset;\n for (let page = 1; page < pageCount && nextOffset !== null && nextOffset !== undefined; page++) {\n const next = await client.getSceneTree({ ...binding, offset: nextOffset, revision: String(result.revision), limit: 1000 });\n if (signal.aborted) return;\n nodes.push(...next.nodes);\n nextOffset = next.nextOffset;\n }\n if (signal.aborted) return;\n setProjection((current) => {\n const next = { key, rows: normalizeSceneTreeRows({ ...result, nodes }), hasMore: nextOffset !== null && nextOffset !== undefined, failed: false };\n if (\n current?.key === next.key &&\n current.failed === next.failed &&\n current.hasMore === next.hasMore &&\n jsonUnchanged(current.rows, next.rows)\n ) return current;\n return next;\n });\n } catch {\n if (signal.aborted) return;\n setProjection((current) => {\n if (current?.key === key && current.failed && !current.hasMore && current.rows.length === 0) return current;\n return { key, rows: [], hasMore: false, failed: true };\n });\n retryDelay = 1500;\n }\n if (!signal.aborted) {\n timer = setTimeout(refresh, retryDelay);\n }\n };\n void refresh();\n return () => { observation.dispose(); clearTimeout(timer); };\n // Include the published snapshot: React may batch A -> B -> A into one\n // render after the observation for A has already been revoked.\n }, [client, connected, projectId, target?.targetId, target?.generation, pageCount, key, reader, workspace]);\n\n return { rows, filterOptions: sceneTreeComponentFilters(rows), failed: current?.failed ?? false, hasMore: current?.hasMore ?? false, loadMore: () => setPageCount(value => value + 1) };\n}\n\nfunction SceneTreeLivePanel({ client }: { client: SceneSelectionClient }) {\n const { t } = useTranslation();\n const reader = useMemo(() => createWorkspaceStateReader(client), [client]);\n const workspace = useSyncExternalStore(\n reader.subscribe,\n () => reader.getSnapshot() as WorkspacePreviewSnapshot | null,\n () => reader.getSnapshot() as WorkspacePreviewSnapshot | null,\n );\n const connected = useWorkspaceClientConnected(client);\n const { rows, filterOptions, failed, hasMore, loadMore } = useEngineSceneRows(client, workspace, connected, reader);\n\n if (!workspace?.preview?.target?.targetId) {\n return (\n <EmptyState\n title={t('sceneTree.unavailable')}\n description=\"Open a scene preview from the Content Browser to load the Engine hierarchy.\"\n />\n );\n }\n if (failed) {\n return (\n <EmptyState\n title={t('sceneTree.unavailable')}\n description={t('sceneTree.loadErrorDescription')}\n />\n );\n }\n if (rows.length === 0) return <EmptyState title=\"Loading hierarchy\" description=\"Reading the selected Engine target.\" />;\n return <>\n {hasMore && <button type=\"button\" onClick={loadMore}>Showing {Math.max(0, rows.length - 1)} entities. Load more</button>}\n <SceneTreeRowsPanel key={`${workspace.preview?.target?.targetId}:${workspace.preview?.target?.generation}`}\n client={client} rows={rows} filterOptions={filterOptions} />\n </>;\n}\n\nfunction SceneTreeRowsPanel({\n client,\n rows,\n filterOptions,\n}: {\n client: SceneSelectionClient;\n rows: HierarchyRow[];\n filterOptions: SceneTreeFilterOption[];\n}) {\n const { t } = useTranslation();\n const reader = useMemo(() => createWorkspaceStateReader(client), [client]);\n const workspace = useSyncExternalStore(\n reader.subscribe,\n () => reader.getSnapshot() as (WorkspacePreviewSnapshot & { sceneSelection?: { primary?: { entityId: string } | null } | null }) | null,\n () => reader.getSnapshot() as (WorkspacePreviewSnapshot & { sceneSelection?: { primary?: { entityId: string } | null } | null }) | null,\n );\n const externalEntityId = workspace?.sceneSelection?.primary?.entityId ?? null;\n const sceneIdentity = workspace?.preview?.asset?.guid ?? workspace?.preview?.target?.targetId ?? null;\n const rowLabel = useCallback(\n (row: HierarchyRow) => (isSceneRootRow(row) ? t('sceneTree.sceneRoot') : row.name),\n [t],\n );\n const typeLabelFor = useCallback(\n (row: HierarchyRow) => {\n if (row.kind === 'folder') return t('sceneTree.types.folder');\n if (row.typeKey) {\n const key = `sceneTree.types.${row.typeKey}`;\n const label = t(key);\n return label === key ? t('sceneTree.types.entity') : label;\n }\n return '';\n },\n [t],\n );\n const componentTypeLabel = useCallback((id: string) => {\n const key = `sceneTree.types.${id}`;\n const label = t(key);\n return label === key ? id : label;\n }, [t]);\n const resolvedFilterOptions = useMemo(\n () => filterOptions.map((option) => ({\n ...option,\n label: option.label ?? componentTypeLabel(option.id),\n })),\n [componentTypeLabel, filterOptions],\n );\n const [query, setQuery] = useState('');\n const [filters, setFilters] = useState(new Set<string>());\n const [expanded, setExpanded] = useState(() => new Set(\n rows.filter((row) => row.expanded || isSceneRootRow(row)).map((row) => row.id),\n ));\n const [columns, setColumns] = useState({ type: true, id: false });\n const [headerMenu, setHeaderMenu] = useState<'filter' | 'settings' | null>(null);\n const [headerMenuAnchor, setHeaderMenuAnchor] = useState<AnchorRect | null>(null);\n const filterButtonRef = useRef<HTMLButtonElement>(null);\n const settingsButtonRef = useRef<HTMLButtonElement>(null);\n const [contextMenu, setContextMenu] = useState<MenuState>(null);\n const [selected, setSelected] = useState(new Set<string>());\n const [anchor, setAnchor] = useState<string | null>(null);\n\n useEffect(() => {\n setExpanded((current) => {\n if (current.has(HIERARCHY_SCENE_FOLDER_ID)) return current;\n const next = new Set(current);\n next.add(HIERARCHY_SCENE_FOLDER_ID);\n return next;\n });\n }, [sceneIdentity]);\n\n useEffect(() => {\n if (externalEntityId && rows.some((row) => row.id === externalEntityId)) {\n setSelected(new Set([externalEntityId]));\n setAnchor(externalEntityId);\n } else if (!externalEntityId) {\n setSelected(new Set());\n setAnchor(null);\n }\n }, [externalEntityId, rows]);\n\n useEffect(() => {\n const allowed = new Set(resolvedFilterOptions.map((option) => option.id));\n setFilters((current) => {\n if (current.size === 0) return current;\n const next = new Set([...current].filter((id) => allowed.has(id)));\n return next.size === current.size ? current : next;\n });\n }, [resolvedFilterOptions]);\n\n const publishSceneSelection = (row: HierarchyRow) => {\n if (row.kind !== 'entity') return;\n const target = workspace?.preview?.target;\n if (!target?.targetId) return;\n void client.selectSceneEntity(row.id, {\n label: row.name,\n tabId: VIEW_WORKSPACE_TAB_ID,\n targetId: target.targetId,\n targetGeneration: target.generation,\n }).catch(() => {});\n };\n\n const clearSceneSelection = () => {\n setSelected(new Set());\n setAnchor(null);\n const target = workspace?.preview?.target;\n if (!target?.targetId) return;\n void client.clearSceneSelection({\n tabId: VIEW_WORKSPACE_TAB_ID,\n targetId: target.targetId,\n targetGeneration: target.generation,\n }).catch(() => {});\n };\n\n const visibleRows = useMemo(() => {\n const text = query.trim().toLowerCase();\n const filtering = text.length > 0 || filters.size > 0;\n if (filtering) {\n return rows.filter((row) => {\n const names = rowComponentNames(row);\n const typeText = typeLabelFor(row).toLowerCase();\n const componentText = names.join(' ').toLowerCase();\n const textMatch = !text\n || rowLabel(row).toLowerCase().includes(text)\n || typeText.includes(text)\n || componentText.includes(text);\n const typeMatch = entityMatchesSceneTreeFilters(names, filters);\n return !isSceneRootRow(row) && textMatch && typeMatch;\n }).map((row) => ({ ...row, depth: 0 }));\n }\n const collapsedDepths: number[] = [];\n return rows.filter((row) => {\n while (collapsedDepths.length && collapsedDepths.at(-1)! >= row.depth) collapsedDepths.pop();\n const hiddenByParent = collapsedDepths.length > 0;\n if (row.hasChildren && !expanded.has(row.id)) collapsedDepths.push(row.depth);\n return !hiddenByParent;\n });\n }, [expanded, filters, query, rowLabel, rows, typeLabelFor]);\n\n const selectRow = (row: HierarchyRow, event: MouseEvent) => {\n if (row.kind === 'folder') {\n setExpanded((current) => {\n const next = new Set(current);\n if (next.has(row.id)) next.delete(row.id); else next.add(row.id);\n return next;\n });\n return;\n }\n const ordered = visibleRows.filter((entry) => entry.kind === 'entity').map((entry) => entry.id);\n let next: Set<string>;\n if (event.shiftKey && anchor) {\n const from = ordered.indexOf(anchor);\n const to = ordered.indexOf(row.id);\n next = from < 0 || to < 0\n ? new Set([row.id])\n : new Set(ordered.slice(Math.min(from, to), Math.max(from, to) + 1));\n } else if (event.ctrlKey || event.metaKey) {\n next = new Set(selected);\n if (next.has(row.id)) next.delete(row.id); else next.add(row.id);\n } else {\n next = new Set([row.id]);\n }\n if (next.size === 0) {\n clearSceneSelection();\n return;\n }\n const primary = next.has(row.id)\n ? row\n : rows.find((entry) => entry.kind === 'entity' && next.has(entry.id));\n if (!primary) {\n clearSceneSelection();\n return;\n }\n setSelected(next);\n setAnchor(primary.id);\n publishSceneSelection(primary);\n };\n const showContext = (event: MouseEvent, items: MenuItem[]) => {\n event.preventDefault();\n event.stopPropagation();\n setHeaderMenu(null);\n setContextMenu({ x: event.clientX, y: event.clientY, items });\n };\n const blankMenu = useCallback((): MenuItem[] => [\n { kind: 'title', label: t('sceneTree.readOnlyTitle') },\n { kind: 'item', id: 'clear-filter', label: t('sceneTree.menu.clearSearchAndFilters'), icon: <X size={14} />, disabled: !query && filters.size === 0, action: () => { setQuery(''); setFilters(new Set()); } },\n { kind: 'item', id: 'focus', label: t('sceneTree.menu.focusSelection'), icon: <Crosshair size={14} />, shortcut: 'F', disabled: selected.size === 0, action: () => {} },\n ], [filters.size, query, selected.size, t]);\n const rowMenu = useCallback((row: HierarchyRow): MenuItem[] => [\n { kind: 'title', label: rowLabel(row), icon: <RowIcon row={row} /> },\n { kind: 'item', id: 'copy-json', label: t('sceneTree.menu.copyJson'), icon: <Braces size={14} />, action: () => void navigator.clipboard?.writeText(JSON.stringify(row, null, 2)) },\n { kind: 'item', id: 'focus', label: t('sceneTree.menu.focusInViewport'), icon: <Crosshair size={14} />, shortcut: 'F', disabled: !workspace?.preview || isSceneRootRow(row), action: () => { const target = workspace?.preview?.target; if (target) void client?.call('entity.focus', { entityId: row.id, targetId: target.targetId, targetGeneration: target.generation }); } },\n ], [rowLabel, t, client, workspace?.preview]);\n useEffect(() => {\n if (!headerMenu) setHeaderMenuAnchor(null);\n }, [headerMenu]);\n\n const openHeaderMenu = (kind: 'filter' | 'settings') => {\n if (headerMenu === kind) {\n setHeaderMenu(null);\n return;\n }\n const ref = kind === 'filter' ? filterButtonRef : settingsButtonRef;\n const rect = ref.current?.getBoundingClientRect();\n if (rect) setHeaderMenuAnchor(rect);\n setHeaderMenu(kind);\n };\n\n const toggleTypeFilter = (filterId: string) => {\n setFilters((current) => {\n const next = new Set(current);\n if (next.has(filterId)) next.delete(filterId);\n else next.add(filterId);\n return next;\n });\n };\n\n return (\n <div\n className=\"panel outliner-panel\"\n data-testid=\"panel-hierarchy\"\n data-view-readonly=\"true\"\n role=\"tree\"\n tabIndex={0}\n onKeyDown={(event) => {\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'a') {\n event.preventDefault();\n setSelected(new Set(rows.filter((row) => row.kind === 'entity').map((row) => row.id)));\n }\n }}\n >\n <PanelHeader\n className=\"fx-hier-toolbar\"\n data-testid=\"hier-toolbar\"\n start={(\n <Toolbar>\n <IconButton\n ref={filterButtonRef}\n className={filters.size ? 'active' : undefined}\n label={t('sceneTree.filterByType')}\n icon={<Filter size={14} />}\n size=\"compact\"\n onClick={() => openHeaderMenu('filter')}\n />\n </Toolbar>\n )}\n center={(\n <SearchField\n className=\"fx-hier-search\"\n data-testid=\"hier-search\"\n data-action={SCENE_TREE_ACTIONS.search}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onClear={() => setQuery('')}\n placeholder={t('sceneTree.searchPlaceholder')}\n label={t('sceneTree.searchLabel')}\n />\n )}\n end={(\n <Toolbar>\n <IconButton\n ref={settingsButtonRef}\n label={t('sceneTree.displaySettings')}\n icon={<Settings size={14} />}\n size=\"compact\"\n onClick={() => openHeaderMenu('settings')}\n />\n </Toolbar>\n )}\n />\n <div className=\"ol-colhead\" data-testid=\"hier-colhead\">\n <span className=\"ch-caret\" aria-hidden />\n <span className=\"ch-name sortable\">{t('sceneTree.columnName')}</span>\n {columns.type ? <span className=\"ch-type sortable col-type\">{t('sceneTree.columnType')}</span> : null}\n {columns.id ? <span className=\"ch-id sortable col-id\">{t('sceneTree.columnId')}</span> : null}\n </div>\n <div\n className=\"ol-body\"\n data-testid=\"hier-root-dropzone\"\n onClick={(event) => {\n if (event.target === event.currentTarget) clearSceneSelection();\n }}\n onContextMenu={(event) => {\n if (!(event.target as HTMLElement).closest('.tn')) showContext(event, blankMenu());\n }}\n >\n {visibleRows.length === 0 ? (\n <EmptyState\n className=\"hier-no-match\"\n title={t('sceneTree.noMatchTitle')}\n description={t('sceneTree.noMatchDescription')}\n />\n ) : visibleRows.map((row) => {\n const isSelected = selected.has(row.id);\n const isHidden = row.hidden === true;\n const isExpanded = expanded.has(row.id);\n return (\n <div\n key={row.id}\n className={`tn k-${rowType(row)}${isSelected ? ' sel' : ''}${isHidden ? ' dim' : ''}`}\n data-testid={isSceneRootRow(row) ? 'hier-row-scene-folder' : `hier-row-${row.id}`}\n data-action={SCENE_TREE_ACTIONS.select}\n style={{ paddingLeft: `calc(var(--fx-ref-space-8) + ${row.depth} * var(--hier-indent-step, calc(var(--fx-ref-space-12) + var(--fx-ref-space-2))))` }}\n role=\"treeitem\"\n aria-selected={isSelected}\n tabIndex={isSelected ? 0 : -1}\n onClick={(event) => selectRow(row, event)}\n onContextMenu={(event) => {\n if (!selected.has(row.id)) {\n setSelected(new Set([row.id]));\n if (row.kind === 'entity') publishSceneSelection(row);\n }\n showContext(event, isSceneRootRow(row) ? blankMenu() : rowMenu(row));\n }}\n >\n <button\n type=\"button\"\n className=\"caret\"\n data-action={SCENE_TREE_ACTIONS.toggleExpanded}\n disabled={!row.hasChildren}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n if (!row.hasChildren) return;\n setExpanded((current) => {\n const next = new Set(current);\n if (next.has(row.id)) next.delete(row.id);\n else next.add(row.id);\n return next;\n });\n }}\n >\n {row.hasChildren ? (isExpanded ? <ChevronDown size={12} /> : <ChevronRight size={12} />) : null}\n </button>\n <span className=\"ico\"><RowIcon row={row} /></span>\n <span className=\"name-cell\">\n <span className=\"nm\">{highlighted(rowLabel(row), query)}</span>\n </span>\n {columns.type ? <span className=\"cell type col-type\"><span className=\"kind\">{typeLabelFor(row)}</span></span> : null}\n {columns.id ? <span className=\"cell id col-id\">{isSceneRootRow(row) ? '' : `#${row.id}`}</span> : null}\n </div>\n );\n })}\n </div>\n <FloatingMenu\n open={Boolean(headerMenuAnchor && headerMenu === 'filter')}\n anchorRect={headerMenuAnchor}\n onClose={() => setHeaderMenu(null)}\n ignorePointerWithin={[filterButtonRef]}\n className=\"hier-filter-menu\"\n containerProps={{ onPointerDown: (event) => event.stopPropagation() }}\n >\n <div className=\"hier-filter-menu-body\">\n <div className=\"hier-filter-section\">{t('sceneTree.filterByType')}</div>\n {resolvedFilterOptions.map((filter) => {\n const active = filters.has(filter.id);\n return (\n <button\n type=\"button\"\n className=\"hier-filter-option\"\n data-active={active ? 'true' : 'false'}\n key={filter.id}\n onClick={() => toggleTypeFilter(filter.id)}\n >\n <Checkbox\n checked={active}\n onChange={() => toggleTypeFilter(filter.id)}\n tabIndex={-1}\n hideLabel\n label={filter.label}\n className=\"hier-filter-check\"\n />\n <span className=\"hier-filter-option-icon\" aria-hidden>{filterOptionIcon(filter.id)}</span>\n {filter.label}\n </button>\n );\n })}\n <div className=\"hier-filter-separator\" />\n <button\n type=\"button\"\n className=\"hier-filter-option hier-filter-clear\"\n disabled={filters.size === 0}\n onClick={() => setFilters(new Set())}\n >\n {t('sceneTree.clearFilters')}\n </button>\n </div>\n </FloatingMenu>\n <FloatingMenu\n open={Boolean(headerMenuAnchor && headerMenu === 'settings')}\n anchorRect={headerMenuAnchor}\n onClose={() => setHeaderMenu(null)}\n ignorePointerWithin={[settingsButtonRef]}\n className=\"hier-filter-menu\"\n containerProps={{ onPointerDown: (event) => event.stopPropagation() }}\n >\n <div className=\"hier-filter-menu-body hierarchy-header-menu-settings\">\n <div className=\"hier-filter-section\">{t('sceneTree.columns')}</div>\n {(['type', 'id'] as const).map((column) => {\n const label = column === 'type'\n ? t('sceneTree.columnType')\n : t('sceneTree.columnId');\n const checked = columns[column];\n const toggle = () => setColumns((current) => ({ ...current, [column]: !current[column] }));\n return (\n <button\n type=\"button\"\n className=\"hier-filter-option\"\n data-action={SCENE_TREE_ACTIONS.toggleColumn}\n data-active={checked ? 'true' : 'false'}\n key={column}\n onClick={toggle}\n >\n <Checkbox\n checked={checked}\n onChange={toggle}\n tabIndex={-1}\n hideLabel\n label={label}\n className=\"hier-filter-check\"\n />\n {label}\n </button>\n );\n })}\n <div className=\"hier-filter-separator\" />\n <button\n type=\"button\"\n className=\"hier-filter-option hier-filter-action\"\n data-action={SCENE_TREE_ACTIONS.expandAll}\n onClick={() => setExpanded(new Set(rows.filter((row) => row.hasChildren).map((row) => row.id)))}\n >\n <Maximize2 size={14} className=\"hier-filter-option-icon\" />\n {t('sceneTree.expandAll')}\n </button>\n <button\n type=\"button\"\n className=\"hier-filter-option hier-filter-action\"\n data-action={SCENE_TREE_ACTIONS.collapseAll}\n onClick={() => setExpanded(new Set(rows.filter(isSceneRootRow).map((row) => row.id)))}\n >\n <Minimize2 size={14} className=\"hier-filter-option-icon\" />\n {t('sceneTree.collapseAll')}\n </button>\n </div>\n </FloatingMenu>\n {contextMenu ? <HierarchyContextMenu state={contextMenu} close={() => setContextMenu(null)} /> : null}\n </div>\n );\n}\n", "import { useCallback, useSyncExternalStore } from 'react';\n\nimport { getLocale, subscribeLocale, t as translate } from './index.ts';\n\nexport function useTranslation() {\n const locale = useSyncExternalStore(subscribeLocale, getLocale, getLocale);\n const t = useCallback(\n (key: string, vars?: Record<string, string | number>) => translate(key, vars),\n [locale],\n );\n return { t, locale };\n}\n", "/**\n * Scene-tree type filters mirror forgeax-editor hierarchy filter options:\n * option ids are component schema names from the Engine host, not UI enums.\n */\n\nconst CATEGORY_RULES = [\n { test: /Camera/, category: 'camera' },\n { test: /Light/, category: 'light' },\n { test: /Character|Controller/, category: 'character' },\n { test: /PlayerStart/, category: 'start' },\n { test: /Spawner/, category: 'spawner' },\n { test: /Mesh/, category: 'mesh' },\n];\n\nfunction categoryRank(category: string) {\n const index = CATEGORY_RULES.findIndex((rule) => rule.category === category);\n return index === -1 ? CATEGORY_RULES.length : index;\n}\n\n/** @param {string} id */\nexport function hierarchyTypeCategory(id: string) {\n if (id === 'group') return 'group';\n if (id === 'entity') return 'entity';\n for (const rule of CATEGORY_RULES) {\n if (rule.test.test(id)) return rule.category;\n }\n return 'generic';\n}\n\n/** @param {string} a @param {string} b */\nexport function compareComponentFilterIds(a: string, b: string) {\n const ra = categoryRank(hierarchyTypeCategory(a));\n const rb = categoryRank(hierarchyTypeCategory(b));\n return ra - rb || a.localeCompare(b);\n}\n\n/**\n * @param {readonly string[]} componentNames\n * @param {ReadonlySet<string>} activeFilters\n */\nexport function entityMatchesSceneTreeFilters(componentNames: readonly string[], activeFilters: ReadonlySet<string>) {\n if (activeFilters.size === 0) return true;\n return componentNames.some((name) => activeFilters.has(name));\n}\n\n/**\n * Build filter options from a component schema name list and optional counts.\n * View derives these options from the loaded entity component identities.\n *\n * @param {readonly string[]} schemaNames\n * @param {ReadonlyMap<string, number>} [counts]\n */\nexport function buildSceneTreeFilterOptions(schemaNames: readonly string[], counts: ReadonlyMap<string, number> = new Map()) {\n const seen = new Set();\n const options = [];\n for (const name of schemaNames) {\n const id = String(name);\n if (!id || seen.has(id)) continue;\n seen.add(id);\n const count = counts.get(id);\n options.push({\n id,\n ...(count === undefined ? {} : { count }),\n });\n }\n options.sort((left, right) => compareComponentFilterIds(left.id, right.id));\n return options;\n}\n", "export type SceneEntityTypeKey = 'mesh' | 'directionalLight' | 'sky' | 'folder' | 'entity' | 'playerStart' | 'camera';\nexport type HierarchyRow = { id: string; name: string; typeKey?: SceneEntityTypeKey; componentNames?: string[]; depth: number; kind: 'folder' | 'entity'; virtual?: boolean; hidden?: boolean; hasChildren?: boolean; expanded?: boolean };\ntype EntityNode = { entityId?: string; entity?: number; name?: string; parentId?: string; componentNames?: string[] };\nimport { buildSceneTreeFilterOptions } from './hierarchy-filters.ts';\n\n/**\n * Normalize Engine `scene-tree.get` payloads into panel rows.\n * View does not author hierarchy; it only projects the latest Engine response.\n */\n\n/**\n * @param {unknown} result\n * @returns {Array<Record<string, unknown>>}\n */\nfunction projectEntityRows(result: unknown): HierarchyRow[] {\n if (!result || typeof result !== 'object') return [];\n const nodes = 'nodes' in result ? result.nodes : undefined;\n if (!Array.isArray(nodes)) return [];\n const rows: HierarchyRow[] = [];\n const seen = new Set();\n const flat = nodes.filter((node): node is EntityNode => node != null && typeof node === 'object');\n const byId = new Map(flat.map(node => [String(node.entityId), node]));\n const children = new Map<string, EntityNode[]>();\n for (const node of flat) {\n if (node.parentId && byId.has(node.parentId)) {\n const siblings = children.get(node.parentId) ?? [];\n siblings.push(node);\n children.set(node.parentId, siblings);\n }\n }\n const visit = (root: EntityNode) => {\n const stack = [{ node: root, depth: 0 }];\n while (stack.length) {\n const { node, depth } = stack.pop()!;\n const id = String(node.entityId ?? '');\n if (!id || seen.has(id)) continue;\n seen.add(id);\n const descendants = children.get(id) ?? [];\n const componentNames = Array.isArray(node.componentNames) ? node.componentNames.filter(name => typeof name === 'string') : [];\n const typeKey = componentNames.includes('Camera') ? 'camera'\n : componentNames.includes('DirectionalLight') ? 'directionalLight'\n : componentNames.includes('MeshFilter') ? 'mesh' : 'entity';\n rows.push({ id, componentNames, name: String(node.name ?? (node.entity === undefined ? id : `Entity ${node.entity}`)), typeKey,\n depth,\n kind: 'entity',\n ...(descendants.length ? { hasChildren: true, expanded: depth < 1 } : {}) });\n for (let i = descendants.length - 1; i >= 0; i--) stack.push({ node: descendants[i], depth: depth + 1 });\n }\n };\n for (const node of flat) if (!node.parentId || !byId.has(node.parentId)) visit(node);\n // Preserve discoverability for cyclic or partial parent projections.\n for (const node of flat) visit(node);\n return rows;\n}\n\n/** Counts describe the loaded rows; Engine owns only component identities. */\nexport function sceneTreeComponentFilters(rows: readonly HierarchyRow[]) {\n const counts = new Map();\n for (const row of rows) for (const name of row.componentNames ?? []) counts.set(name, (counts.get(name) ?? 0) + 1);\n return buildSceneTreeFilterOptions([...counts.keys()], counts);\n}\n\n/** This grouping row belongs only to View and is never sent as an entity reference. */\nexport const HIERARCHY_SCENE_FOLDER_ID = 'hierarchy:scene-root';\nexport function isSceneRootRow(row: HierarchyRow) { return row?.id === HIERARCHY_SCENE_FOLDER_ID; }\nexport function wrapWithVirtualSceneRoot(rows: HierarchyRow[]): HierarchyRow[] {\n if (rows.some(isSceneRootRow)) return rows.map(row => isSceneRootRow(row) ? { ...row, virtual: true } : row);\n return [{ id: HIERARCHY_SCENE_FOLDER_ID, name: 'Scene', typeKey: 'folder', depth: 0,\n kind: 'folder', virtual: true, hasChildren: rows.length > 0, expanded: true },\n ...rows.map(row => ({ ...row, depth: row.depth + 1 }))];\n}\nexport function normalizeSceneTreeRows(result: unknown) { return wrapWithVirtualSceneRoot(projectEntityRows(result)); }\nexport function normalizeSceneTreeResponse(result: unknown) {\n const rows = normalizeSceneTreeRows(result);\n return { rows, filterOptions: sceneTreeComponentFilters(rows) };\n}\n", "\n const css = \"/* packages/view-plugin-scene-tree/src/ui/scene-tree.css */\\n.outliner-panel {\\n --hier-w-caret: calc(var(--fx-ref-space-12) + var(--fx-ref-space-2));\\n --hier-w-type: calc(var(--fx-ref-space-48) + var(--fx-ref-space-16) + var(--fx-ref-space-4));\\n --hier-w-id: calc(var(--fx-ref-space-48) + var(--fx-ref-space-24));\\n --hier-indent-step: calc(var(--fx-ref-space-12) + var(--fx-ref-space-2));\\n display: flex;\\n flex-direction: column;\\n container-type: inline-size;\\n width: 100%;\\n height: 100%;\\n min-height: 0;\\n overflow: hidden;\\n position: relative;\\n background: var(--fx-color-surface-sidebar);\\n color: var(--fx-color-text-primary);\\n font: var(--fx-type-compact-font-weight) var(--fx-type-compact-font-size) / var(--fx-type-compact-line-height) var(--fx-type-compact-font-family);\\n}\\n.outliner-panel * {\\n box-sizing: border-box;\\n}\\n.outliner-panel button,\\n.outliner-panel input {\\n font: inherit;\\n}\\n.fx-hier-toolbar {\\n flex: 0 0 auto;\\n gap: var(--fx-ref-space-6);\\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8);\\n background: var(--fx-color-surface-sidebar);\\n}\\n.fx-hier-toolbar > .fx-panel-header__slot:nth-child(2) {\\n flex: 1;\\n}\\n.fx-hier-search {\\n flex: 1;\\n width: 100%;\\n min-width: 0;\\n}\\n.fx-hier-search .fx-input {\\n height: var(--fx-component-control-height-compact);\\n}\\n.outliner-panel .fx-button--icon.active {\\n border-color: var(--fx-color-brand-accent);\\n background: var(--fx-color-brand-soft);\\n color: var(--fx-color-brand-text);\\n}\\n.hier-filter-menu-body {\\n min-width: 220px;\\n padding: var(--fx-ref-space-4);\\n border: var(--fx-border-width) solid var(--fx-color-border-default);\\n border-radius: var(--fx-radius-popover);\\n background: var(--fx-color-surface-raised);\\n box-shadow: var(--fx-shadow-floating);\\n}\\n.hier-filter-section {\\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8) var(--fx-ref-space-4);\\n color: var(--fx-color-text-muted);\\n font-size: var(--fx-type-caption-font-size);\\n font-weight: var(--fx-ref-font-weight-600);\\n letter-spacing: var(--fx-type-caption-letter-spacing);\\n text-transform: uppercase;\\n}\\n.hier-filter-separator {\\n height: var(--fx-border-width);\\n margin: var(--fx-ref-space-4) 0;\\n background: var(--fx-color-border-subtle);\\n}\\n.hier-filter-option {\\n display: flex;\\n align-items: center;\\n gap: var(--fx-ref-space-8);\\n width: 100%;\\n min-height: var(--fx-component-editor-row-height);\\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\\n border: 0;\\n border-radius: var(--fx-radius-control);\\n background: transparent;\\n color: var(--fx-color-text-secondary);\\n font: inherit;\\n text-align: left;\\n cursor: pointer;\\n}\\n.hier-filter-option:hover:not(:disabled) {\\n background: var(--fx-color-surface-hover);\\n color: var(--fx-color-text-primary);\\n}\\n.hier-filter-option:disabled {\\n color: var(--fx-color-text-disabled);\\n cursor: default;\\n}\\n.hier-filter-option-icon {\\n display: grid;\\n flex: 0 0 14px;\\n place-items: center;\\n width: 14px;\\n color: var(--fx-color-text-muted);\\n}\\n.hier-filter-check {\\n flex: 0 0 var(--fx-component-choice-size);\\n pointer-events: none;\\n}\\n.hier-filter-check.fx-choice {\\n align-items: center;\\n gap: 0;\\n min-height: 0;\\n margin: 0;\\n}\\n.hier-filter-check .fx-choice__text {\\n display: none;\\n}\\n.hier-filter-clear {\\n justify-content: flex-start;\\n color: var(--fx-color-text-muted);\\n}\\n.ol-colhead {\\n display: flex;\\n align-items: center;\\n min-height: var(--fx-component-editor-row-height);\\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\\n border-bottom: var(--fx-border-width) solid var(--fx-color-border-subtle);\\n color: var(--fx-color-text-muted);\\n font: var(--fx-type-caption-font-weight) var(--fx-type-caption-font-size) / var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\\n letter-spacing: var(--fx-type-caption-letter-spacing);\\n text-transform: uppercase;\\n}\\n.ch-caret {\\n width: var(--hier-w-caret);\\n flex: 0 0 auto;\\n}\\n.ch-name {\\n flex: 1;\\n min-width: var(--fx-ref-space-16);\\n}\\n.ch-type {\\n width: var(--hier-w-type);\\n flex: 0 0 auto;\\n}\\n.ch-id {\\n width: var(--hier-w-id);\\n flex: 0 0 auto;\\n}\\n.ol-body {\\n flex: 1;\\n min-height: 0;\\n overflow: auto;\\n padding: var(--fx-ref-space-4) 0 var(--fx-ref-space-8);\\n}\\n.tn {\\n display: flex;\\n align-items: center;\\n min-height: var(--fx-component-editor-row-height);\\n padding-right: var(--fx-ref-space-8);\\n border: 0;\\n border-left: var(--fx-border-focus-width) solid transparent;\\n color: var(--fx-color-text-secondary);\\n white-space: nowrap;\\n cursor: default;\\n user-select: none;\\n}\\n.tn:hover {\\n background: var(--fx-color-surface-hover);\\n color: var(--fx-color-text-primary);\\n}\\n.tn.sel {\\n border-left-color: var(--fx-color-selection-indicator);\\n background: var(--fx-color-selection-bg);\\n color: var(--fx-color-selection-fg);\\n}\\n.tn.dim {\\n opacity: 0.45;\\n}\\n.tn .caret {\\n display: grid;\\n place-items: center;\\n width: var(--hier-w-caret);\\n height: var(--fx-ref-space-16);\\n flex: 0 0 auto;\\n padding: 0;\\n border: 0;\\n background: transparent;\\n color: var(--fx-color-text-muted);\\n}\\n.tn .caret:disabled {\\n opacity: 0;\\n pointer-events: none;\\n}\\n.tn .ico {\\n display: grid;\\n place-items: center;\\n width: calc(var(--fx-ref-space-16) + var(--fx-ref-space-2));\\n flex: 0 0 auto;\\n color: var(--fx-color-text-muted);\\n}\\n.tn .name-cell {\\n display: flex;\\n align-items: center;\\n flex: 1;\\n min-width: 0;\\n gap: var(--fx-ref-space-4);\\n overflow: hidden;\\n}\\n.tn .nm {\\n overflow: hidden;\\n text-overflow: ellipsis;\\n white-space: nowrap;\\n}\\n.tn.k-folder .nm,\\n.tn.k-grp .nm {\\n color: var(--fx-color-text-muted);\\n}\\n.tn .cell {\\n overflow: hidden;\\n color: var(--fx-color-text-muted);\\n font: var(--fx-type-caption-font-weight) var(--fx-type-caption-font-size) / var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\\n text-overflow: ellipsis;\\n}\\n.tn .cell.type {\\n width: var(--hier-w-type);\\n}\\n.tn .cell.id {\\n width: var(--hier-w-id);\\n}\\n.tn .kind {\\n color: var(--fx-color-text-secondary);\\n}\\n.tn.k-light .ico {\\n color: var(--fx-color-status-warning-fg);\\n}\\n.tn.k-camera .ico {\\n color: var(--fx-color-status-info-fg);\\n}\\n.tn.k-character .ico {\\n color: var(--fx-color-brand-text);\\n}\\n.tn.k-scene .ico,\\n.tn.k-group .ico,\\n.tn.k-folder .ico {\\n color: var(--fx-color-text-muted);\\n}\\n.tn.pdim {\\n opacity: 0.68;\\n}\\n.tn.drop-inside {\\n background: var(--fx-color-brand-soft);\\n outline: var(--fx-border-width) solid var(--fx-color-brand-accent);\\n outline-offset: calc(-1 * var(--fx-border-width));\\n}\\n.tn.drop-before::before,\\n.tn.drop-after::after {\\n content: \\\"\\\";\\n position: absolute;\\n z-index: var(--fx-layer-sticky);\\n right: var(--fx-ref-space-4);\\n left: var(--fx-ref-space-4);\\n height: var(--fx-ref-space-2);\\n background: var(--fx-color-brand-accent);\\n box-shadow: var(--fx-shadow-subtle);\\n}\\n.tn {\\n position: relative;\\n}\\n.tn.drop-before::before {\\n top: calc(-1 * var(--fx-border-width));\\n}\\n.tn.drop-after::after {\\n bottom: calc(-1 * var(--fx-border-width));\\n}\\n.hier-inline-rename {\\n width: 100%;\\n min-width: 0;\\n height: var(--fx-component-control-height-compact);\\n padding: var(--fx-ref-space-2) var(--fx-ref-space-4);\\n border: var(--fx-border-width) solid var(--fx-color-border-focus);\\n border-radius: var(--fx-ref-radius-4);\\n outline: 0;\\n background: var(--fx-color-surface-inset);\\n color: var(--fx-color-text-primary);\\n}\\n.hier-no-match {\\n padding: var(--fx-ref-space-8) var(--fx-ref-space-12);\\n}\\n.outliner-panel .hl {\\n border-radius: var(--fx-ref-radius-4);\\n background: var(--fx-color-brand-soft);\\n color: var(--fx-color-text-primary);\\n}\\n.outliner-panel .muted {\\n color: var(--fx-color-text-muted);\\n}\\n@container (max-width: 195px) {\\n .outliner-panel .col-type {\\n display: none;\\n }\\n}\\n@container (max-width: 280px) {\\n .outliner-panel .col-id {\\n display: none;\\n }\\n}\\n.hier-context-position {\\n position: fixed;\\n z-index: var(--fx-layer-tooltip);\\n color: var(--fx-color-text-secondary);\\n font: var(--fx-type-ui-font-weight) var(--fx-type-ui-font-size) / var(--fx-type-ui-line-height) var(--fx-type-ui-font-family);\\n}\\n.hier-context-menu,\\n.hier-context-submenu {\\n box-sizing: border-box;\\n display: flex;\\n flex-direction: column;\\n min-width: var(--fx-component-menu-min-width);\\n max-height: calc(100vh - var(--fx-ref-space-16));\\n padding: var(--fx-ref-space-6);\\n overflow: visible;\\n border: var(--fx-border-width) solid var(--fx-color-border-default);\\n border-radius: var(--fx-radius-popover);\\n background: var(--fx-color-surface-raised);\\n box-shadow: var(--fx-shadow-floating);\\n}\\n.hier-context-submenu {\\n position: absolute;\\n top: calc(-1 * var(--fx-ref-space-6));\\n left: calc(100% - var(--fx-ref-space-2));\\n min-width: var(--fx-component-panel-config-min-width);\\n}\\n.hier-context-title {\\n display: flex;\\n align-items: center;\\n gap: var(--fx-ref-space-6);\\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8);\\n color: var(--fx-color-text-muted);\\n font: var(--fx-type-caption-font-weight) var(--fx-type-caption-font-size) / var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\\n}\\n.hier-context-item-wrap {\\n position: relative;\\n}\\n.hier-context-item-wrap > button {\\n box-sizing: border-box;\\n display: flex;\\n align-items: center;\\n gap: var(--fx-ref-space-8);\\n width: 100%;\\n min-height: var(--fx-component-menu-row-height);\\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8);\\n border: 0;\\n border-radius: var(--fx-radius-control);\\n background: transparent;\\n color: inherit;\\n font: inherit;\\n text-align: left;\\n cursor: pointer;\\n}\\n.hier-context-item-wrap > button:hover:not(:disabled) {\\n background: var(--fx-color-surface-hover);\\n color: var(--fx-color-text-primary);\\n}\\n.hier-context-item-wrap > button:disabled {\\n opacity: 0.38;\\n cursor: default;\\n}\\n.hier-context-item-wrap > button[data-danger=true] {\\n color: var(--fx-color-status-error-fg);\\n}\\n.hier-context-item-wrap > button[data-forge=true] .hier-context-icon {\\n color: var(--fx-color-brand-text);\\n}\\n.hier-context-icon {\\n display: grid;\\n place-items: center;\\n width: var(--fx-component-control-icon-size);\\n flex: 0 0 var(--fx-component-control-icon-size);\\n color: var(--fx-color-text-muted);\\n}\\n.hier-context-item-wrap > button > span:nth-child(2) {\\n flex: 1;\\n}\\n.hier-context-item-wrap kbd {\\n color: var(--fx-color-text-muted);\\n font: var(--fx-type-caption-font-weight) var(--fx-type-caption-font-size) / var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\\n}\\n.hier-context-separator {\\n display: block;\\n height: var(--fx-border-width);\\n margin: var(--fx-ref-space-6);\\n background: var(--fx-color-border-subtle);\\n}\\n\";\n if (typeof document !== 'undefined' && !document.querySelector('style[data-forgeax-css=\"a9fd1866464288a4a4b490686e0c4225551e378d64dcb6499d18061c7e908e0d\"]')) {\n const style = document.createElement('style');\n style.dataset.forgeaxCss = \"a9fd1866464288a4a4b490686e0c4225551e378d64dcb6499d18061c7e908e0d\";\n style.textContent = css;\n document.head.append(style);\n }\n export default css;\n "],
|
|
4
|
+
"sourcesContent": ["import type { ComponentProps } from 'react';\nimport '@forgeax/view-components/styles.css';\nimport { OverlayRootProvider } from '@forgeax/view-components';\nimport '../i18n/index.ts';\nimport { createRoot } from 'react-dom/client';\nimport { SceneTreePanel } from './SceneTreePanel';\nimport './scene-tree.css';\n\nexport async function mountSceneTreePanel(props: ComponentProps<typeof SceneTreePanel> & { mountElement: HTMLElement; overlayRoot?: HTMLElement }) {\n if (!props.mountElement) throw new TypeError('mountSceneTreePanel requires mountElement');\n const root = createRoot(props.mountElement);\n root.render(\n <OverlayRootProvider root={props.overlayRoot ?? props.mountElement}>\n <SceneTreePanel client={props.client} />\n </OverlayRootProvider>,\n );\n return async () => root.unmount();\n}\n", "import type { WorkspaceState } from '@forgeax/view-workspace-core/contract';\nimport {\n Box,\n Braces,\n Camera,\n ChevronDown,\n ChevronRight,\n CircleUserRound,\n Crosshair,\n Filter,\n Folder,\n Layers,\n Lightbulb,\n Maximize2,\n Minimize2,\n Settings,\n X,\n} from 'lucide-react';\nimport {\n Checkbox,\n EmptyState,\n useOverlayRoot,\n FloatingMenu,\n IconButton,\n PanelHeader,\n SearchField,\n Toolbar,\n useWorkspaceClientConnected,\n type AnchorRect,\n} from '@forgeax/view-components';\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n type MouseEvent,\n type ReactNode,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { useTranslation } from '../i18n/useTranslation';\nimport { SCENE_TREE_ACTIONS } from '../schema.ts';\nimport type { ViewWorkspaceClient } from '@forgeax/view-workspace-core/client';\nimport { VIEW_WORKSPACE_TAB_ID, jsonUnchanged } from '@forgeax/view-workspace-core/contract';\nimport { createWorkspaceObservation, createWorkspaceStateReader } from '@forgeax/view-workspace-core/workspace-state';\nimport {\n entityMatchesSceneTreeFilters,\n hierarchyTypeCategory,\n} from '../hierarchy-filters.ts';\nimport {\n HIERARCHY_SCENE_FOLDER_ID,\n isSceneRootRow,\n sceneTreeComponentFilters,\n normalizeSceneTreeRows,\n type HierarchyRow,\n} from '../hierarchy.ts';\n\ntype SceneTreeFilterOption = {\n id: string;\n label?: string;\n count?: number;\n};\n\ntype SceneSelectionClient = Pick<\n ViewWorkspaceClient,\n 'subscribe' | 'getState' | 'selectSceneEntity' | 'clearSceneSelection' | 'getSceneTree' | 'call' | 'onDisconnect' | 'transport'\n>;\n\ntype WorkspacePreviewSnapshot = WorkspaceState;\n\ntype MenuItem =\n | { kind: 'title'; label: string; icon?: ReactNode }\n | { kind: 'separator' }\n | {\n kind: 'item';\n id: string;\n label: string;\n icon?: ReactNode;\n shortcut?: string;\n disabled?: boolean;\n danger?: boolean;\n forge?: boolean;\n children?: MenuItem[];\n action?: () => void;\n };\ntype MenuState = { x: number; y: number; items: MenuItem[] } | null;\n\nfunction rowComponentNames(row: HierarchyRow) {\n if (Array.isArray(row.componentNames) && row.componentNames.length > 0) {\n return row.componentNames;\n }\n return row.typeKey ? [String(row.typeKey)] : [];\n}\n\nfunction rowType(row: HierarchyRow) {\n if (isSceneRootRow(row)) return 'scene';\n if (row.kind === 'folder') return 'group';\n const primary = rowComponentNames(row).find((name) => name !== 'Transform') ?? row.typeKey;\n if (!primary) return 'mesh';\n return hierarchyTypeCategory(String(primary));\n}\n\nfunction filterOptionIcon(id: string) {\n switch (hierarchyTypeCategory(id)) {\n case 'camera': return <Camera size={14} />;\n case 'light': return <Lightbulb size={14} />;\n case 'character': return <CircleUserRound size={14} />;\n case 'group': return <Layers size={14} />;\n default: return <Box size={14} />;\n }\n}\n\nfunction RowIcon({ row }: { row: HierarchyRow }) {\n if (isSceneRootRow(row)) return <Folder size={15} />;\n if (row.kind === 'folder') return <Layers size={15} />;\n if (row.typeKey === 'directionalLight') return <Lightbulb size={15} />;\n if (row.typeKey === 'camera') return <Camera size={15} />;\n if (row.name === 'Player') return <CircleUserRound size={15} />;\n return <Box size={15} />;\n}\n\nfunction HierarchyContextMenu({ state, close }: { state: Exclude<MenuState, null>; close: () => void }) {\n const overlayRoot = useOverlayRoot();\n const [submenu, setSubmenu] = useState<string | null>(null);\n useEffect(() => {\n const dismiss = () => close();\n const escape = (event: KeyboardEvent) => event.key === 'Escape' && close();\n window.addEventListener('pointerdown', dismiss);\n window.addEventListener('keydown', escape);\n return () => {\n window.removeEventListener('pointerdown', dismiss);\n window.removeEventListener('keydown', escape);\n };\n }, [close]);\n const renderItems = (items: MenuItem[], nested = false) => (\n <div className={nested ? 'hier-context-submenu' : 'hier-context-menu'}>\n {items.map((item, index) => {\n if (item.kind === 'separator') return <i className=\"hier-context-separator\" key={`sep-${index}`} />;\n if (item.kind === 'title') return <div className=\"hier-context-title\" key={`title-${index}`}>{item.icon}{item.label}</div>;\n return (\n <div className=\"hier-context-item-wrap\" key={item.id} onPointerEnter={() => item.children && setSubmenu(item.id)}>\n <button\n type=\"button\"\n role=\"menuitem\"\n data-operation={item.id}\n data-danger={item.danger || undefined}\n data-forge={item.forge || undefined}\n disabled={item.disabled}\n onClick={() => {\n if (item.children) {\n setSubmenu(submenu === item.id ? null : item.id);\n return;\n }\n item.action?.();\n close();\n }}\n >\n <span className=\"hier-context-icon\">{item.icon}</span>\n <span>{item.label}</span>\n {item.shortcut ? <kbd>{item.shortcut}</kbd> : null}\n {item.children ? <ChevronRight size={12} /> : null}\n </button>\n {item.children && submenu === item.id ? renderItems(item.children, true) : null}\n </div>\n );\n })}\n </div>\n );\n return createPortal(\n <div\n className=\"hier-context-position\"\n data-action={SCENE_TREE_ACTIONS.showContextMenu}\n role=\"menu\"\n style={{\n left: Math.max(8, Math.min(state.x, window.innerWidth - 260)),\n top: Math.max(8, Math.min(state.y, window.innerHeight - 420)),\n }}\n onPointerDown={(event) => event.stopPropagation()}\n onContextMenu={(event) => event.preventDefault()}\n >\n {renderItems(state.items)}\n </div>,\n overlayRoot ?? document.body,\n );\n}\n\nfunction highlighted(value: string, query: string) {\n const index = value.toLowerCase().indexOf(query.toLowerCase());\n if (!query || index < 0) return value;\n return <>{value.slice(0, index)}<mark className=\"hl\">{value.slice(index, index + query.length)}</mark>{value.slice(index + query.length)}</>;\n}\n\nexport function SceneTreePanel(props: { client?: SceneSelectionClient }) {\n if (!props.client) {\n return (\n <EmptyState\n title=\"Scene hierarchy unavailable\"\n description=\"Connect to the View workspace API to load the Engine scene tree.\"\n />\n );\n }\n return <SceneTreeLivePanel client={props.client} />;\n}\n\nfunction useEngineSceneRows(\n client: SceneSelectionClient,\n workspace: WorkspacePreviewSnapshot | null,\n connected: boolean,\n reader: ReturnType<typeof createWorkspaceStateReader>,\n) {\n const [projection, setProjection] = useState<{ key: string; rows: HierarchyRow[]; failed: boolean; hasMore: boolean } | null>(null);\n const [pageCount, setPageCount] = useState(1);\n const target = workspace?.preview?.target;\n const projectId = workspace?.project?.id;\n const key = `${target?.targetId}:${target?.generation}`;\n const current = projection?.key === key ? projection : null;\n const rows = current?.rows ?? [];\n\n useEffect(() => { setPageCount(1); }, [target?.targetId, target?.generation]);\n\n useEffect(() => {\n if (!connected || !target?.targetId || !projectId) {\n if (!connected) return;\n setProjection(null);\n return;\n }\n const observation = createWorkspaceObservation(reader, (current: WorkspacePreviewSnapshot | null) =>\n current?.project?.id === projectId &&\n current?.preview?.target?.targetId === target.targetId &&\n current?.preview?.target?.generation === target.generation);\n const { signal } = observation;\n let timer: ReturnType<typeof setTimeout>;\n const refresh = async () => {\n if (signal.aborted) return;\n let retryDelay = 500;\n try {\n const binding = {\n tabId: VIEW_WORKSPACE_TAB_ID, projectId, targetId: target.targetId,\n targetGeneration: target.generation, signal,\n };\n const result = await client.getSceneTree({ ...binding, limit: 1000 });\n if (signal.aborted) return;\n const nodes = [...(result.nodes ?? [])];\n let nextOffset = result.nextOffset;\n for (let page = 1; page < pageCount && nextOffset !== null && nextOffset !== undefined; page++) {\n const next = await client.getSceneTree({ ...binding, offset: nextOffset, revision: String(result.revision), limit: 1000 });\n if (signal.aborted) return;\n nodes.push(...next.nodes);\n nextOffset = next.nextOffset;\n }\n if (signal.aborted) return;\n setProjection((current) => {\n const next = { key, rows: normalizeSceneTreeRows({ ...result, nodes }), hasMore: nextOffset !== null && nextOffset !== undefined, failed: false };\n if (\n current?.key === next.key &&\n current.failed === next.failed &&\n current.hasMore === next.hasMore &&\n jsonUnchanged(current.rows, next.rows)\n ) return current;\n return next;\n });\n } catch {\n if (signal.aborted) return;\n setProjection((current) => {\n if (current?.key === key && current.failed && !current.hasMore && current.rows.length === 0) return current;\n return { key, rows: [], hasMore: false, failed: true };\n });\n retryDelay = 1500;\n }\n if (!signal.aborted) {\n timer = setTimeout(refresh, retryDelay);\n }\n };\n void refresh();\n return () => { observation.dispose(); clearTimeout(timer); };\n // Include the published snapshot: React may batch A -> B -> A into one\n // render after the observation for A has already been revoked.\n }, [client, connected, projectId, target?.targetId, target?.generation, pageCount, key, reader, workspace]);\n\n return { rows, filterOptions: sceneTreeComponentFilters(rows), failed: current?.failed ?? false, hasMore: current?.hasMore ?? false, loadMore: () => setPageCount(value => value + 1) };\n}\n\nfunction SceneTreeLivePanel({ client }: { client: SceneSelectionClient }) {\n const { t } = useTranslation();\n const reader = useMemo(() => createWorkspaceStateReader(client), [client]);\n const workspace = useSyncExternalStore(\n reader.subscribe,\n () => reader.getSnapshot() as WorkspacePreviewSnapshot | null,\n () => reader.getSnapshot() as WorkspacePreviewSnapshot | null,\n );\n const connected = useWorkspaceClientConnected(client);\n const { rows, filterOptions, failed, hasMore, loadMore } = useEngineSceneRows(client, workspace, connected, reader);\n\n if (!workspace?.preview?.target?.targetId) {\n return (\n <EmptyState\n title={t('sceneTree.unavailable')}\n description=\"Open a scene preview from the Content Browser to load the Engine hierarchy.\"\n />\n );\n }\n if (failed) {\n return (\n <EmptyState\n title={t('sceneTree.unavailable')}\n description={t('sceneTree.loadErrorDescription')}\n />\n );\n }\n if (rows.length === 0) return <EmptyState title=\"Loading hierarchy\" description=\"Reading the selected Engine target.\" />;\n return <>\n {hasMore && <button type=\"button\" onClick={loadMore}>Showing {Math.max(0, rows.length - 1)} entities. Load more</button>}\n <SceneTreeRowsPanel key={`${workspace.preview?.target?.targetId}:${workspace.preview?.target?.generation}`}\n client={client} rows={rows} filterOptions={filterOptions} />\n </>;\n}\n\nfunction SceneTreeRowsPanel({\n client,\n rows,\n filterOptions,\n}: {\n client: SceneSelectionClient;\n rows: HierarchyRow[];\n filterOptions: SceneTreeFilterOption[];\n}) {\n const { t } = useTranslation();\n const reader = useMemo(() => createWorkspaceStateReader(client), [client]);\n const workspace = useSyncExternalStore(\n reader.subscribe,\n () => reader.getSnapshot() as (WorkspacePreviewSnapshot & { sceneSelection?: { primary?: { entityId: string } | null } | null }) | null,\n () => reader.getSnapshot() as (WorkspacePreviewSnapshot & { sceneSelection?: { primary?: { entityId: string } | null } | null }) | null,\n );\n const externalEntityId = workspace?.sceneSelection?.primary?.entityId ?? null;\n const sceneIdentity = workspace?.preview?.asset?.guid ?? workspace?.preview?.target?.targetId ?? null;\n const rowLabel = useCallback(\n (row: HierarchyRow) => (isSceneRootRow(row) ? t('sceneTree.sceneRoot') : row.name),\n [t],\n );\n const typeLabelFor = useCallback(\n (row: HierarchyRow) => {\n if (row.kind === 'folder') return t('sceneTree.types.folder');\n if (row.typeKey) {\n const key = `sceneTree.types.${row.typeKey}`;\n const label = t(key);\n return label === key ? t('sceneTree.types.entity') : label;\n }\n return '';\n },\n [t],\n );\n const componentTypeLabel = useCallback((id: string) => {\n const key = `sceneTree.types.${id}`;\n const label = t(key);\n return label === key ? id : label;\n }, [t]);\n const resolvedFilterOptions = useMemo(\n () => filterOptions.map((option) => ({\n ...option,\n label: option.label ?? componentTypeLabel(option.id),\n })),\n [componentTypeLabel, filterOptions],\n );\n const [query, setQuery] = useState('');\n const [filters, setFilters] = useState(new Set<string>());\n const [expanded, setExpanded] = useState(() => new Set(\n rows.filter((row) => row.expanded || isSceneRootRow(row)).map((row) => row.id),\n ));\n const [columns, setColumns] = useState({ type: true, id: false });\n const [headerMenu, setHeaderMenu] = useState<'filter' | 'settings' | null>(null);\n const [headerMenuAnchor, setHeaderMenuAnchor] = useState<AnchorRect | null>(null);\n const filterButtonRef = useRef<HTMLButtonElement>(null);\n const settingsButtonRef = useRef<HTMLButtonElement>(null);\n const [contextMenu, setContextMenu] = useState<MenuState>(null);\n const [selected, setSelected] = useState(new Set<string>());\n const [anchor, setAnchor] = useState<string | null>(null);\n\n useEffect(() => {\n setExpanded((current) => {\n if (current.has(HIERARCHY_SCENE_FOLDER_ID)) return current;\n const next = new Set(current);\n next.add(HIERARCHY_SCENE_FOLDER_ID);\n return next;\n });\n }, [sceneIdentity]);\n\n useEffect(() => {\n if (externalEntityId && rows.some((row) => row.id === externalEntityId)) {\n setSelected(new Set([externalEntityId]));\n setAnchor(externalEntityId);\n } else if (!externalEntityId) {\n setSelected(new Set());\n setAnchor(null);\n }\n }, [externalEntityId, rows]);\n\n useEffect(() => {\n const allowed = new Set(resolvedFilterOptions.map((option) => option.id));\n setFilters((current) => {\n if (current.size === 0) return current;\n const next = new Set([...current].filter((id) => allowed.has(id)));\n return next.size === current.size ? current : next;\n });\n }, [resolvedFilterOptions]);\n\n const publishSceneSelection = (row: HierarchyRow) => {\n if (row.kind !== 'entity') return;\n const target = workspace?.preview?.target;\n if (!target?.targetId) return;\n void client.selectSceneEntity(row.id, {\n label: row.name,\n tabId: VIEW_WORKSPACE_TAB_ID,\n targetId: target.targetId,\n targetGeneration: target.generation,\n }).catch(() => {});\n };\n\n const clearSceneSelection = () => {\n setSelected(new Set());\n setAnchor(null);\n const target = workspace?.preview?.target;\n if (!target?.targetId) return;\n void client.clearSceneSelection({\n tabId: VIEW_WORKSPACE_TAB_ID,\n targetId: target.targetId,\n targetGeneration: target.generation,\n }).catch(() => {});\n };\n\n const visibleRows = useMemo(() => {\n const text = query.trim().toLowerCase();\n const filtering = text.length > 0 || filters.size > 0;\n if (filtering) {\n return rows.filter((row) => {\n const names = rowComponentNames(row);\n const typeText = typeLabelFor(row).toLowerCase();\n const componentText = names.join(' ').toLowerCase();\n const textMatch = !text\n || rowLabel(row).toLowerCase().includes(text)\n || typeText.includes(text)\n || componentText.includes(text);\n const typeMatch = entityMatchesSceneTreeFilters(names, filters);\n return !isSceneRootRow(row) && textMatch && typeMatch;\n }).map((row) => ({ ...row, depth: 0 }));\n }\n const collapsedDepths: number[] = [];\n return rows.filter((row) => {\n while (collapsedDepths.length && collapsedDepths.at(-1)! >= row.depth) collapsedDepths.pop();\n const hiddenByParent = collapsedDepths.length > 0;\n if (row.hasChildren && !expanded.has(row.id)) collapsedDepths.push(row.depth);\n return !hiddenByParent;\n });\n }, [expanded, filters, query, rowLabel, rows, typeLabelFor]);\n\n const selectRow = (row: HierarchyRow, event: MouseEvent) => {\n if (row.kind === 'folder') {\n setExpanded((current) => {\n const next = new Set(current);\n if (next.has(row.id)) next.delete(row.id); else next.add(row.id);\n return next;\n });\n return;\n }\n const ordered = visibleRows.filter((entry) => entry.kind === 'entity').map((entry) => entry.id);\n let next: Set<string>;\n if (event.shiftKey && anchor) {\n const from = ordered.indexOf(anchor);\n const to = ordered.indexOf(row.id);\n next = from < 0 || to < 0\n ? new Set([row.id])\n : new Set(ordered.slice(Math.min(from, to), Math.max(from, to) + 1));\n } else if (event.ctrlKey || event.metaKey) {\n next = new Set(selected);\n if (next.has(row.id)) next.delete(row.id); else next.add(row.id);\n } else {\n next = new Set([row.id]);\n }\n if (next.size === 0) {\n clearSceneSelection();\n return;\n }\n const primary = next.has(row.id)\n ? row\n : rows.find((entry) => entry.kind === 'entity' && next.has(entry.id));\n if (!primary) {\n clearSceneSelection();\n return;\n }\n setSelected(next);\n setAnchor(primary.id);\n publishSceneSelection(primary);\n };\n const showContext = (event: MouseEvent, items: MenuItem[]) => {\n event.preventDefault();\n event.stopPropagation();\n setHeaderMenu(null);\n setContextMenu({ x: event.clientX, y: event.clientY, items });\n };\n const blankMenu = useCallback((): MenuItem[] => [\n { kind: 'title', label: t('sceneTree.readOnlyTitle') },\n { kind: 'item', id: 'clear-filter', label: t('sceneTree.menu.clearSearchAndFilters'), icon: <X size={14} />, disabled: !query && filters.size === 0, action: () => { setQuery(''); setFilters(new Set()); } },\n { kind: 'item', id: 'focus', label: t('sceneTree.menu.focusSelection'), icon: <Crosshair size={14} />, shortcut: 'F', disabled: selected.size === 0, action: () => {} },\n ], [filters.size, query, selected.size, t]);\n const rowMenu = useCallback((row: HierarchyRow): MenuItem[] => [\n { kind: 'title', label: rowLabel(row), icon: <RowIcon row={row} /> },\n { kind: 'item', id: 'copy-json', label: t('sceneTree.menu.copyJson'), icon: <Braces size={14} />, action: () => void navigator.clipboard?.writeText(JSON.stringify(row, null, 2)) },\n { kind: 'item', id: 'focus', label: t('sceneTree.menu.focusInViewport'), icon: <Crosshair size={14} />, shortcut: 'F', disabled: !workspace?.preview || isSceneRootRow(row), action: () => { const target = workspace?.preview?.target; if (target) void client?.call('entity.focus', { entityId: row.id, targetId: target.targetId, targetGeneration: target.generation }); } },\n ], [rowLabel, t, client, workspace?.preview]);\n useEffect(() => {\n if (!headerMenu) setHeaderMenuAnchor(null);\n }, [headerMenu]);\n\n const openHeaderMenu = (kind: 'filter' | 'settings') => {\n if (headerMenu === kind) {\n setHeaderMenu(null);\n return;\n }\n const ref = kind === 'filter' ? filterButtonRef : settingsButtonRef;\n const rect = ref.current?.getBoundingClientRect();\n if (rect) setHeaderMenuAnchor(rect);\n setHeaderMenu(kind);\n };\n\n const toggleTypeFilter = (filterId: string) => {\n setFilters((current) => {\n const next = new Set(current);\n if (next.has(filterId)) next.delete(filterId);\n else next.add(filterId);\n return next;\n });\n };\n\n return (\n <div\n className=\"panel outliner-panel\"\n data-testid=\"panel-hierarchy\"\n data-view-readonly=\"true\"\n role=\"tree\"\n tabIndex={0}\n onKeyDown={(event) => {\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'a') {\n event.preventDefault();\n setSelected(new Set(rows.filter((row) => row.kind === 'entity').map((row) => row.id)));\n }\n }}\n >\n <PanelHeader\n className=\"fx-hier-toolbar\"\n data-testid=\"hier-toolbar\"\n start={(\n <Toolbar>\n <IconButton\n ref={filterButtonRef}\n className={filters.size ? 'active' : undefined}\n label={t('sceneTree.filterByType')}\n icon={<Filter size={14} />}\n size=\"compact\"\n onClick={() => openHeaderMenu('filter')}\n />\n </Toolbar>\n )}\n center={(\n <SearchField\n className=\"fx-hier-search\"\n data-testid=\"hier-search\"\n data-action={SCENE_TREE_ACTIONS.search}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onClear={() => setQuery('')}\n placeholder={t('sceneTree.searchPlaceholder')}\n label={t('sceneTree.searchLabel')}\n />\n )}\n end={(\n <Toolbar>\n <IconButton\n ref={settingsButtonRef}\n label={t('sceneTree.displaySettings')}\n icon={<Settings size={14} />}\n size=\"compact\"\n onClick={() => openHeaderMenu('settings')}\n />\n </Toolbar>\n )}\n />\n <div className=\"ol-colhead\" data-testid=\"hier-colhead\">\n <span className=\"ch-caret\" aria-hidden />\n <span className=\"ch-name sortable\">{t('sceneTree.columnName')}</span>\n {columns.type ? <span className=\"ch-type sortable col-type\">{t('sceneTree.columnType')}</span> : null}\n {columns.id ? <span className=\"ch-id sortable col-id\">{t('sceneTree.columnId')}</span> : null}\n </div>\n <div\n className=\"ol-body\"\n data-testid=\"hier-root-dropzone\"\n onClick={(event) => {\n if (event.target === event.currentTarget) clearSceneSelection();\n }}\n onContextMenu={(event) => {\n if (!(event.target as HTMLElement).closest('.tn')) showContext(event, blankMenu());\n }}\n >\n {visibleRows.length === 0 ? (\n <EmptyState\n className=\"hier-no-match\"\n title={t('sceneTree.noMatchTitle')}\n description={t('sceneTree.noMatchDescription')}\n />\n ) : visibleRows.map((row) => {\n const isSelected = selected.has(row.id);\n const isHidden = row.hidden === true;\n const isExpanded = expanded.has(row.id);\n return (\n <div\n key={row.id}\n className={`tn k-${rowType(row)}${isSelected ? ' sel' : ''}${isHidden ? ' dim' : ''}`}\n data-testid={isSceneRootRow(row) ? 'hier-row-scene-folder' : `hier-row-${row.id}`}\n data-action={SCENE_TREE_ACTIONS.select}\n style={{ paddingLeft: `calc(var(--fx-ref-space-8) + ${row.depth} * var(--hier-indent-step, calc(var(--fx-ref-space-12) + var(--fx-ref-space-2))))` }}\n role=\"treeitem\"\n aria-selected={isSelected}\n tabIndex={isSelected ? 0 : -1}\n onClick={(event) => selectRow(row, event)}\n onContextMenu={(event) => {\n if (!selected.has(row.id)) {\n setSelected(new Set([row.id]));\n if (row.kind === 'entity') publishSceneSelection(row);\n }\n showContext(event, isSceneRootRow(row) ? blankMenu() : rowMenu(row));\n }}\n >\n <button\n type=\"button\"\n className=\"caret\"\n data-action={SCENE_TREE_ACTIONS.toggleExpanded}\n disabled={!row.hasChildren}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n if (!row.hasChildren) return;\n setExpanded((current) => {\n const next = new Set(current);\n if (next.has(row.id)) next.delete(row.id);\n else next.add(row.id);\n return next;\n });\n }}\n >\n {row.hasChildren ? (isExpanded ? <ChevronDown size={12} /> : <ChevronRight size={12} />) : null}\n </button>\n <span className=\"ico\"><RowIcon row={row} /></span>\n <span className=\"name-cell\">\n <span className=\"nm\">{highlighted(rowLabel(row), query)}</span>\n </span>\n {columns.type ? <span className=\"cell type col-type\"><span className=\"kind\">{typeLabelFor(row)}</span></span> : null}\n {columns.id ? <span className=\"cell id col-id\">{isSceneRootRow(row) ? '' : `#${row.id}`}</span> : null}\n </div>\n );\n })}\n </div>\n <FloatingMenu\n open={Boolean(headerMenuAnchor && headerMenu === 'filter')}\n anchorRect={headerMenuAnchor}\n onClose={() => setHeaderMenu(null)}\n ignorePointerWithin={[filterButtonRef]}\n className=\"hier-filter-menu\"\n containerProps={{ onPointerDown: (event) => event.stopPropagation() }}\n >\n <div className=\"hier-filter-menu-body\">\n <div className=\"hier-filter-section\">{t('sceneTree.filterByType')}</div>\n {resolvedFilterOptions.map((filter) => {\n const active = filters.has(filter.id);\n return (\n <button\n type=\"button\"\n className=\"hier-filter-option\"\n data-active={active ? 'true' : 'false'}\n key={filter.id}\n onClick={() => toggleTypeFilter(filter.id)}\n >\n <Checkbox\n checked={active}\n onChange={() => toggleTypeFilter(filter.id)}\n tabIndex={-1}\n hideLabel\n label={filter.label}\n className=\"hier-filter-check\"\n />\n <span className=\"hier-filter-option-icon\" aria-hidden>{filterOptionIcon(filter.id)}</span>\n {filter.label}\n </button>\n );\n })}\n <div className=\"hier-filter-separator\" />\n <button\n type=\"button\"\n className=\"hier-filter-option hier-filter-clear\"\n disabled={filters.size === 0}\n onClick={() => setFilters(new Set())}\n >\n {t('sceneTree.clearFilters')}\n </button>\n </div>\n </FloatingMenu>\n <FloatingMenu\n open={Boolean(headerMenuAnchor && headerMenu === 'settings')}\n anchorRect={headerMenuAnchor}\n onClose={() => setHeaderMenu(null)}\n ignorePointerWithin={[settingsButtonRef]}\n className=\"hier-filter-menu\"\n containerProps={{ onPointerDown: (event) => event.stopPropagation() }}\n >\n <div className=\"hier-filter-menu-body hierarchy-header-menu-settings\">\n <div className=\"hier-filter-section\">{t('sceneTree.columns')}</div>\n {(['type', 'id'] as const).map((column) => {\n const label = column === 'type'\n ? t('sceneTree.columnType')\n : t('sceneTree.columnId');\n const checked = columns[column];\n const toggle = () => setColumns((current) => ({ ...current, [column]: !current[column] }));\n return (\n <button\n type=\"button\"\n className=\"hier-filter-option\"\n data-action={SCENE_TREE_ACTIONS.toggleColumn}\n data-active={checked ? 'true' : 'false'}\n key={column}\n onClick={toggle}\n >\n <Checkbox\n checked={checked}\n onChange={toggle}\n tabIndex={-1}\n hideLabel\n label={label}\n className=\"hier-filter-check\"\n />\n {label}\n </button>\n );\n })}\n <div className=\"hier-filter-separator\" />\n <button\n type=\"button\"\n className=\"hier-filter-option hier-filter-action\"\n data-action={SCENE_TREE_ACTIONS.expandAll}\n onClick={() => setExpanded(new Set(rows.filter((row) => row.hasChildren).map((row) => row.id)))}\n >\n <Maximize2 size={14} className=\"hier-filter-option-icon\" />\n {t('sceneTree.expandAll')}\n </button>\n <button\n type=\"button\"\n className=\"hier-filter-option hier-filter-action\"\n data-action={SCENE_TREE_ACTIONS.collapseAll}\n onClick={() => setExpanded(new Set(rows.filter(isSceneRootRow).map((row) => row.id)))}\n >\n <Minimize2 size={14} className=\"hier-filter-option-icon\" />\n {t('sceneTree.collapseAll')}\n </button>\n </div>\n </FloatingMenu>\n {contextMenu ? <HierarchyContextMenu state={contextMenu} close={() => setContextMenu(null)} /> : null}\n </div>\n );\n}\n", "import { useCallback, useSyncExternalStore } from 'react';\n\nimport { getLocale, subscribeLocale, t as translate } from './index.ts';\n\nexport function useTranslation() {\n const locale = useSyncExternalStore(subscribeLocale, getLocale, getLocale);\n const t = useCallback(\n (key: string, vars?: Record<string, string | number>) => translate(key, vars),\n [locale],\n );\n return { t, locale };\n}\n", "/**\n * Scene-tree type filters mirror forgeax-editor hierarchy filter options:\n * option ids are component schema names from the Engine host, not UI enums.\n */\n\nconst CATEGORY_RULES = [\n { test: /Camera/, category: 'camera' },\n { test: /Light/, category: 'light' },\n { test: /Character|Controller/, category: 'character' },\n { test: /PlayerStart/, category: 'start' },\n { test: /Spawner/, category: 'spawner' },\n { test: /Mesh/, category: 'mesh' },\n];\n\nfunction categoryRank(category: string) {\n const index = CATEGORY_RULES.findIndex((rule) => rule.category === category);\n return index === -1 ? CATEGORY_RULES.length : index;\n}\n\n/** @param {string} id */\nexport function hierarchyTypeCategory(id: string) {\n if (id === 'group') return 'group';\n if (id === 'entity') return 'entity';\n for (const rule of CATEGORY_RULES) {\n if (rule.test.test(id)) return rule.category;\n }\n return 'generic';\n}\n\n/** @param {string} a @param {string} b */\nexport function compareComponentFilterIds(a: string, b: string) {\n const ra = categoryRank(hierarchyTypeCategory(a));\n const rb = categoryRank(hierarchyTypeCategory(b));\n return ra - rb || a.localeCompare(b);\n}\n\n/**\n * @param {readonly string[]} componentNames\n * @param {ReadonlySet<string>} activeFilters\n */\nexport function entityMatchesSceneTreeFilters(componentNames: readonly string[], activeFilters: ReadonlySet<string>) {\n if (activeFilters.size === 0) return true;\n return componentNames.some((name) => activeFilters.has(name));\n}\n\n/**\n * Build filter options from a component schema name list and optional counts.\n * View derives these options from the loaded entity component identities.\n *\n * @param {readonly string[]} schemaNames\n * @param {ReadonlyMap<string, number>} [counts]\n */\nexport function buildSceneTreeFilterOptions(schemaNames: readonly string[], counts: ReadonlyMap<string, number> = new Map()) {\n const seen = new Set();\n const options = [];\n for (const name of schemaNames) {\n const id = String(name);\n if (!id || seen.has(id)) continue;\n seen.add(id);\n const count = counts.get(id);\n options.push({\n id,\n ...(count === undefined ? {} : { count }),\n });\n }\n options.sort((left, right) => compareComponentFilterIds(left.id, right.id));\n return options;\n}\n", "export type SceneEntityTypeKey = 'mesh' | 'directionalLight' | 'sky' | 'folder' | 'entity' | 'playerStart' | 'camera';\nexport type HierarchyRow = { id: string; name: string; typeKey?: SceneEntityTypeKey; componentNames?: string[]; depth: number; kind: 'folder' | 'entity'; virtual?: boolean; hidden?: boolean; hasChildren?: boolean; expanded?: boolean };\ntype EntityNode = { entityId?: string; entity?: number; name?: string; parentId?: string; componentNames?: string[] };\nimport { buildSceneTreeFilterOptions } from './hierarchy-filters.ts';\n\n/**\n * Normalize Engine `scene.tree.get` payloads into panel rows.\n * View does not author hierarchy; it only projects the latest Engine response.\n */\n\n/**\n * @param {unknown} result\n * @returns {Array<Record<string, unknown>>}\n */\nfunction projectEntityRows(result: unknown): HierarchyRow[] {\n if (!result || typeof result !== 'object') return [];\n const nodes = 'nodes' in result ? result.nodes : undefined;\n if (!Array.isArray(nodes)) return [];\n const rows: HierarchyRow[] = [];\n const seen = new Set();\n const flat = nodes.filter((node): node is EntityNode => node != null && typeof node === 'object');\n const byId = new Map(flat.map(node => [String(node.entityId), node]));\n const children = new Map<string, EntityNode[]>();\n for (const node of flat) {\n if (node.parentId && byId.has(node.parentId)) {\n const siblings = children.get(node.parentId) ?? [];\n siblings.push(node);\n children.set(node.parentId, siblings);\n }\n }\n const visit = (root: EntityNode) => {\n const stack = [{ node: root, depth: 0 }];\n while (stack.length) {\n const { node, depth } = stack.pop()!;\n const id = String(node.entityId ?? '');\n if (!id || seen.has(id)) continue;\n seen.add(id);\n const descendants = children.get(id) ?? [];\n const componentNames = Array.isArray(node.componentNames) ? node.componentNames.filter(name => typeof name === 'string') : [];\n const typeKey = componentNames.includes('Camera') ? 'camera'\n : componentNames.includes('DirectionalLight') ? 'directionalLight'\n : componentNames.includes('MeshFilter') ? 'mesh' : 'entity';\n rows.push({ id, componentNames, name: String(node.name ?? (node.entity === undefined ? id : `Entity ${node.entity}`)), typeKey,\n depth,\n kind: 'entity',\n ...(descendants.length ? { hasChildren: true, expanded: depth < 1 } : {}) });\n for (let i = descendants.length - 1; i >= 0; i--) stack.push({ node: descendants[i], depth: depth + 1 });\n }\n };\n for (const node of flat) if (!node.parentId || !byId.has(node.parentId)) visit(node);\n // Preserve discoverability for cyclic or partial parent projections.\n for (const node of flat) visit(node);\n return rows;\n}\n\n/** Counts describe the loaded rows; Engine owns only component identities. */\nexport function sceneTreeComponentFilters(rows: readonly HierarchyRow[]) {\n const counts = new Map();\n for (const row of rows) for (const name of row.componentNames ?? []) counts.set(name, (counts.get(name) ?? 0) + 1);\n return buildSceneTreeFilterOptions([...counts.keys()], counts);\n}\n\n/** This grouping row belongs only to View and is never sent as an entity reference. */\nexport const HIERARCHY_SCENE_FOLDER_ID = 'hierarchy:scene-root';\nexport function isSceneRootRow(row: HierarchyRow) { return row?.id === HIERARCHY_SCENE_FOLDER_ID; }\nexport function wrapWithVirtualSceneRoot(rows: HierarchyRow[]): HierarchyRow[] {\n if (rows.some(isSceneRootRow)) return rows.map(row => isSceneRootRow(row) ? { ...row, virtual: true } : row);\n return [{ id: HIERARCHY_SCENE_FOLDER_ID, name: 'Scene', typeKey: 'folder', depth: 0,\n kind: 'folder', virtual: true, hasChildren: rows.length > 0, expanded: true },\n ...rows.map(row => ({ ...row, depth: row.depth + 1 }))];\n}\nexport function normalizeSceneTreeRows(result: unknown) { return wrapWithVirtualSceneRoot(projectEntityRows(result)); }\nexport function normalizeSceneTreeResponse(result: unknown) {\n const rows = normalizeSceneTreeRows(result);\n return { rows, filterOptions: sceneTreeComponentFilters(rows) };\n}\n", "\n const css = \"/* packages/view-plugin-scene-tree/src/ui/scene-tree.css */\\n.outliner-panel {\\n --hier-w-caret: calc(var(--fx-ref-space-12) + var(--fx-ref-space-2));\\n --hier-w-type: calc(var(--fx-ref-space-48) + var(--fx-ref-space-16) + var(--fx-ref-space-4));\\n --hier-w-id: calc(var(--fx-ref-space-48) + var(--fx-ref-space-24));\\n --hier-indent-step: calc(var(--fx-ref-space-12) + var(--fx-ref-space-2));\\n display: flex;\\n flex-direction: column;\\n container-type: inline-size;\\n width: 100%;\\n height: 100%;\\n min-height: 0;\\n overflow: hidden;\\n position: relative;\\n background: var(--fx-color-surface-sidebar);\\n color: var(--fx-color-text-primary);\\n font: var(--fx-type-compact-font-weight) var(--fx-type-compact-font-size) / var(--fx-type-compact-line-height) var(--fx-type-compact-font-family);\\n}\\n.outliner-panel * {\\n box-sizing: border-box;\\n}\\n.outliner-panel button,\\n.outliner-panel input {\\n font: inherit;\\n}\\n.fx-hier-toolbar {\\n flex: 0 0 auto;\\n gap: var(--fx-ref-space-6);\\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8);\\n background: var(--fx-color-surface-sidebar);\\n}\\n.fx-hier-toolbar > .fx-panel-header__slot:nth-child(2) {\\n flex: 1;\\n}\\n.fx-hier-search {\\n flex: 1;\\n width: 100%;\\n min-width: 0;\\n}\\n.fx-hier-search .fx-input {\\n height: var(--fx-component-control-height-compact);\\n}\\n.outliner-panel .fx-button--icon.active {\\n border-color: var(--fx-color-brand-accent);\\n background: var(--fx-color-brand-soft);\\n color: var(--fx-color-brand-text);\\n}\\n.hier-filter-menu-body {\\n min-width: 220px;\\n padding: var(--fx-ref-space-4);\\n border: var(--fx-border-width) solid var(--fx-color-border-default);\\n border-radius: var(--fx-radius-popover);\\n background: var(--fx-color-surface-raised);\\n box-shadow: var(--fx-shadow-floating);\\n}\\n.hier-filter-section {\\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8) var(--fx-ref-space-4);\\n color: var(--fx-color-text-muted);\\n font-size: var(--fx-type-caption-font-size);\\n font-weight: var(--fx-ref-font-weight-600);\\n letter-spacing: var(--fx-type-caption-letter-spacing);\\n text-transform: uppercase;\\n}\\n.hier-filter-separator {\\n height: var(--fx-border-width);\\n margin: var(--fx-ref-space-4) 0;\\n background: var(--fx-color-border-subtle);\\n}\\n.hier-filter-option {\\n display: flex;\\n align-items: center;\\n gap: var(--fx-ref-space-8);\\n width: 100%;\\n min-height: var(--fx-component-editor-row-height);\\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\\n border: 0;\\n border-radius: var(--fx-radius-control);\\n background: transparent;\\n color: var(--fx-color-text-secondary);\\n font: inherit;\\n text-align: left;\\n cursor: pointer;\\n}\\n.hier-filter-option:hover:not(:disabled) {\\n background: var(--fx-color-surface-hover);\\n color: var(--fx-color-text-primary);\\n}\\n.hier-filter-option:disabled {\\n color: var(--fx-color-text-disabled);\\n cursor: default;\\n}\\n.hier-filter-option-icon {\\n display: grid;\\n flex: 0 0 14px;\\n place-items: center;\\n width: 14px;\\n color: var(--fx-color-text-muted);\\n}\\n.hier-filter-check {\\n flex: 0 0 var(--fx-component-choice-size);\\n pointer-events: none;\\n}\\n.hier-filter-check.fx-choice {\\n align-items: center;\\n gap: 0;\\n min-height: 0;\\n margin: 0;\\n}\\n.hier-filter-check .fx-choice__text {\\n display: none;\\n}\\n.hier-filter-clear {\\n justify-content: flex-start;\\n color: var(--fx-color-text-muted);\\n}\\n.ol-colhead {\\n display: flex;\\n align-items: center;\\n min-height: var(--fx-component-editor-row-height);\\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\\n border-bottom: var(--fx-border-width) solid var(--fx-color-border-subtle);\\n color: var(--fx-color-text-muted);\\n font: var(--fx-type-caption-font-weight) var(--fx-type-caption-font-size) / var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\\n letter-spacing: var(--fx-type-caption-letter-spacing);\\n text-transform: uppercase;\\n}\\n.ch-caret {\\n width: var(--hier-w-caret);\\n flex: 0 0 auto;\\n}\\n.ch-name {\\n flex: 1;\\n min-width: var(--fx-ref-space-16);\\n}\\n.ch-type {\\n width: var(--hier-w-type);\\n flex: 0 0 auto;\\n}\\n.ch-id {\\n width: var(--hier-w-id);\\n flex: 0 0 auto;\\n}\\n.ol-body {\\n flex: 1;\\n min-height: 0;\\n overflow: auto;\\n padding: var(--fx-ref-space-4) 0 var(--fx-ref-space-8);\\n}\\n.tn {\\n display: flex;\\n align-items: center;\\n min-height: var(--fx-component-editor-row-height);\\n padding-right: var(--fx-ref-space-8);\\n border: 0;\\n border-left: var(--fx-border-focus-width) solid transparent;\\n color: var(--fx-color-text-secondary);\\n white-space: nowrap;\\n cursor: default;\\n user-select: none;\\n}\\n.tn:hover {\\n background: var(--fx-color-surface-hover);\\n color: var(--fx-color-text-primary);\\n}\\n.tn.sel {\\n border-left-color: var(--fx-color-selection-indicator);\\n background: var(--fx-color-selection-bg);\\n color: var(--fx-color-selection-fg);\\n}\\n.tn.dim {\\n opacity: 0.45;\\n}\\n.tn .caret {\\n display: grid;\\n place-items: center;\\n width: var(--hier-w-caret);\\n height: var(--fx-ref-space-16);\\n flex: 0 0 auto;\\n padding: 0;\\n border: 0;\\n background: transparent;\\n color: var(--fx-color-text-muted);\\n}\\n.tn .caret:disabled {\\n opacity: 0;\\n pointer-events: none;\\n}\\n.tn .ico {\\n display: grid;\\n place-items: center;\\n width: calc(var(--fx-ref-space-16) + var(--fx-ref-space-2));\\n flex: 0 0 auto;\\n color: var(--fx-color-text-muted);\\n}\\n.tn .name-cell {\\n display: flex;\\n align-items: center;\\n flex: 1;\\n min-width: 0;\\n gap: var(--fx-ref-space-4);\\n overflow: hidden;\\n}\\n.tn .nm {\\n overflow: hidden;\\n text-overflow: ellipsis;\\n white-space: nowrap;\\n}\\n.tn.k-folder .nm,\\n.tn.k-grp .nm {\\n color: var(--fx-color-text-muted);\\n}\\n.tn .cell {\\n overflow: hidden;\\n color: var(--fx-color-text-muted);\\n font: var(--fx-type-caption-font-weight) var(--fx-type-caption-font-size) / var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\\n text-overflow: ellipsis;\\n}\\n.tn .cell.type {\\n width: var(--hier-w-type);\\n}\\n.tn .cell.id {\\n width: var(--hier-w-id);\\n}\\n.tn .kind {\\n color: var(--fx-color-text-secondary);\\n}\\n.tn.k-light .ico {\\n color: var(--fx-color-status-warning-fg);\\n}\\n.tn.k-camera .ico {\\n color: var(--fx-color-status-info-fg);\\n}\\n.tn.k-character .ico {\\n color: var(--fx-color-brand-text);\\n}\\n.tn.k-scene .ico,\\n.tn.k-group .ico,\\n.tn.k-folder .ico {\\n color: var(--fx-color-text-muted);\\n}\\n.tn.pdim {\\n opacity: 0.68;\\n}\\n.tn.drop-inside {\\n background: var(--fx-color-brand-soft);\\n outline: var(--fx-border-width) solid var(--fx-color-brand-accent);\\n outline-offset: calc(-1 * var(--fx-border-width));\\n}\\n.tn.drop-before::before,\\n.tn.drop-after::after {\\n content: \\\"\\\";\\n position: absolute;\\n z-index: var(--fx-layer-sticky);\\n right: var(--fx-ref-space-4);\\n left: var(--fx-ref-space-4);\\n height: var(--fx-ref-space-2);\\n background: var(--fx-color-brand-accent);\\n box-shadow: var(--fx-shadow-subtle);\\n}\\n.tn {\\n position: relative;\\n}\\n.tn.drop-before::before {\\n top: calc(-1 * var(--fx-border-width));\\n}\\n.tn.drop-after::after {\\n bottom: calc(-1 * var(--fx-border-width));\\n}\\n.hier-inline-rename {\\n width: 100%;\\n min-width: 0;\\n height: var(--fx-component-control-height-compact);\\n padding: var(--fx-ref-space-2) var(--fx-ref-space-4);\\n border: var(--fx-border-width) solid var(--fx-color-border-focus);\\n border-radius: var(--fx-ref-radius-4);\\n outline: 0;\\n background: var(--fx-color-surface-inset);\\n color: var(--fx-color-text-primary);\\n}\\n.hier-no-match {\\n padding: var(--fx-ref-space-8) var(--fx-ref-space-12);\\n}\\n.outliner-panel .hl {\\n border-radius: var(--fx-ref-radius-4);\\n background: var(--fx-color-brand-soft);\\n color: var(--fx-color-text-primary);\\n}\\n.outliner-panel .muted {\\n color: var(--fx-color-text-muted);\\n}\\n@container (max-width: 195px) {\\n .outliner-panel .col-type {\\n display: none;\\n }\\n}\\n@container (max-width: 280px) {\\n .outliner-panel .col-id {\\n display: none;\\n }\\n}\\n.hier-context-position {\\n position: fixed;\\n z-index: var(--fx-layer-tooltip);\\n color: var(--fx-color-text-secondary);\\n font: var(--fx-type-ui-font-weight) var(--fx-type-ui-font-size) / var(--fx-type-ui-line-height) var(--fx-type-ui-font-family);\\n}\\n.hier-context-menu,\\n.hier-context-submenu {\\n box-sizing: border-box;\\n display: flex;\\n flex-direction: column;\\n min-width: var(--fx-component-menu-min-width);\\n max-height: calc(100vh - var(--fx-ref-space-16));\\n padding: var(--fx-ref-space-6);\\n overflow: visible;\\n border: var(--fx-border-width) solid var(--fx-color-border-default);\\n border-radius: var(--fx-radius-popover);\\n background: var(--fx-color-surface-raised);\\n box-shadow: var(--fx-shadow-floating);\\n}\\n.hier-context-submenu {\\n position: absolute;\\n top: calc(-1 * var(--fx-ref-space-6));\\n left: calc(100% - var(--fx-ref-space-2));\\n min-width: var(--fx-component-panel-config-min-width);\\n}\\n.hier-context-title {\\n display: flex;\\n align-items: center;\\n gap: var(--fx-ref-space-6);\\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8);\\n color: var(--fx-color-text-muted);\\n font: var(--fx-type-caption-font-weight) var(--fx-type-caption-font-size) / var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\\n}\\n.hier-context-item-wrap {\\n position: relative;\\n}\\n.hier-context-item-wrap > button {\\n box-sizing: border-box;\\n display: flex;\\n align-items: center;\\n gap: var(--fx-ref-space-8);\\n width: 100%;\\n min-height: var(--fx-component-menu-row-height);\\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8);\\n border: 0;\\n border-radius: var(--fx-radius-control);\\n background: transparent;\\n color: inherit;\\n font: inherit;\\n text-align: left;\\n cursor: pointer;\\n}\\n.hier-context-item-wrap > button:hover:not(:disabled) {\\n background: var(--fx-color-surface-hover);\\n color: var(--fx-color-text-primary);\\n}\\n.hier-context-item-wrap > button:disabled {\\n opacity: 0.38;\\n cursor: default;\\n}\\n.hier-context-item-wrap > button[data-danger=true] {\\n color: var(--fx-color-status-error-fg);\\n}\\n.hier-context-item-wrap > button[data-forge=true] .hier-context-icon {\\n color: var(--fx-color-brand-text);\\n}\\n.hier-context-icon {\\n display: grid;\\n place-items: center;\\n width: var(--fx-component-control-icon-size);\\n flex: 0 0 var(--fx-component-control-icon-size);\\n color: var(--fx-color-text-muted);\\n}\\n.hier-context-item-wrap > button > span:nth-child(2) {\\n flex: 1;\\n}\\n.hier-context-item-wrap kbd {\\n color: var(--fx-color-text-muted);\\n font: var(--fx-type-caption-font-weight) var(--fx-type-caption-font-size) / var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\\n}\\n.hier-context-separator {\\n display: block;\\n height: var(--fx-border-width);\\n margin: var(--fx-ref-space-6);\\n background: var(--fx-color-border-subtle);\\n}\\n\";\n if (typeof document !== 'undefined' && !document.querySelector('style[data-forgeax-css=\"a9fd1866464288a4a4b490686e0c4225551e378d64dcb6499d18061c7e908e0d\"]')) {\n const style = document.createElement('style');\n style.dataset.forgeaxCss = \"a9fd1866464288a4a4b490686e0c4225551e378d64dcb6499d18061c7e908e0d\";\n style.textContent = css;\n document.head.append(style);\n }\n export default css;\n "],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["useCallback", "useSyncExternalStore", "t", "current", "t", "useSyncExternalStore", "useCallback", "next", "jsx"]
|
|
7
7
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FRONTEND_PLUGIN_ID,
|
|
3
3
|
identity_exports
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-C2AMOM7H.mjs";
|
|
5
5
|
import {
|
|
6
6
|
applyResourcePagePlugin
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-KPLESRQY.mjs";
|
|
8
8
|
|
|
9
9
|
// packages/view-plugin-mesh/src/frontend.ts
|
|
10
10
|
var VIEW_MESH_FRONTEND_PLUGIN_ID = FRONTEND_PLUGIN_ID;
|
|
@@ -22,4 +22,4 @@ export {
|
|
|
22
22
|
viewMeshFrontendPlugin,
|
|
23
23
|
frontend_default
|
|
24
24
|
};
|
|
25
|
-
//# sourceMappingURL=chunk-
|
|
25
|
+
//# sourceMappingURL=chunk-7MWZK7HS.mjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
mountRunObserver
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LBQ6DFMP.mjs";
|
|
4
4
|
import {
|
|
5
5
|
DISPLAY_SURFACE_ID,
|
|
6
6
|
DISPLAY_TARGET_ROLE,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
PAGE_TYPE,
|
|
10
10
|
VIEW_STATUS_SERVICE,
|
|
11
11
|
VIEW_STATUS_TOPIC
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-D2LZIQE2.mjs";
|
|
13
13
|
|
|
14
14
|
// packages/view-plugin-display/src/status.ts
|
|
15
15
|
var ViewDisplayStatus = class {
|
|
@@ -146,4 +146,4 @@ export {
|
|
|
146
146
|
ViewDisplayStatus,
|
|
147
147
|
frontend_default
|
|
148
148
|
};
|
|
149
|
-
//# sourceMappingURL=chunk-
|
|
149
|
+
//# sourceMappingURL=chunk-A7OGXJAV.mjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VIEW_PAGE_TYPES
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QJHQN6OD.mjs";
|
|
4
4
|
import {
|
|
5
5
|
__export
|
|
6
6
|
} from "./chunk-FLGC65SR.mjs";
|
|
@@ -39,4 +39,4 @@ export {
|
|
|
39
39
|
TITLE_I18N_KEY,
|
|
40
40
|
identity_exports
|
|
41
41
|
};
|
|
42
|
-
//# sourceMappingURL=chunk-
|
|
42
|
+
//# sourceMappingURL=chunk-AUINYWZP.mjs.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RESOURCE_PREVIEW_LAYOUT,
|
|
3
3
|
RESOURCE_PROPERTIES_LAYOUT
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KPLESRQY.mjs";
|
|
5
5
|
import {
|
|
6
6
|
VIEW_PAGE_TYPES
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QJHQN6OD.mjs";
|
|
8
8
|
import {
|
|
9
9
|
__export
|
|
10
10
|
} from "./chunk-FLGC65SR.mjs";
|
|
@@ -83,4 +83,4 @@ export {
|
|
|
83
83
|
TITLE_I18N_KEY,
|
|
84
84
|
identity_exports
|
|
85
85
|
};
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
86
|
+
//# sourceMappingURL=chunk-B24VYGHV.mjs.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VIEW_WORKSPACE_CORE_OPERATION_DESCRIPTIONS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-L6IHUN7X.mjs";
|
|
4
4
|
|
|
5
5
|
// packages/view-workspace-core/src/cli.ts
|
|
6
6
|
var workspaceCoreCliContributions = Object.freeze(
|
|
7
7
|
VIEW_WORKSPACE_CORE_OPERATION_DESCRIPTIONS.map((description) => ({
|
|
8
|
-
id: `
|
|
8
|
+
id: `view.workspace.${description.id}`,
|
|
9
9
|
path: ["view", "workspace", ...description.path],
|
|
10
10
|
summary: description.summary,
|
|
11
11
|
operation: description.id
|
|
@@ -15,4 +15,4 @@ var workspaceCoreCliContributions = Object.freeze(
|
|
|
15
15
|
export {
|
|
16
16
|
workspaceCoreCliContributions
|
|
17
17
|
};
|
|
18
|
-
//# sourceMappingURL=chunk-
|
|
18
|
+
//# sourceMappingURL=chunk-BIUWJROZ.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/view-workspace-core/src/cli.ts"],
|
|
4
|
-
"sourcesContent": ["import { VIEW_WORKSPACE_CORE_OPERATION_DESCRIPTIONS } from './api.ts';\n\nexport const workspaceCoreCliContributions = Object.freeze(\n VIEW_WORKSPACE_CORE_OPERATION_DESCRIPTIONS.map((description) => ({\n id: `
|
|
5
|
-
"mappings": ";;;;;AAEO,IAAM,gCAAgC,OAAO;AAAA,EAClD,2CAA2C,IAAI,CAAC,iBAAiB;AAAA,IAC/D,IAAI,
|
|
4
|
+
"sourcesContent": ["import { VIEW_WORKSPACE_CORE_OPERATION_DESCRIPTIONS } from './api.ts';\n\nexport const workspaceCoreCliContributions = Object.freeze(\n VIEW_WORKSPACE_CORE_OPERATION_DESCRIPTIONS.map((description) => ({\n id: `view.workspace.${description.id}`,\n path: ['view', 'workspace', ...description.path],\n summary: description.summary,\n operation: description.id,\n })),\n);\n"],
|
|
5
|
+
"mappings": ";;;;;AAEO,IAAM,gCAAgC,OAAO;AAAA,EAClD,2CAA2C,IAAI,CAAC,iBAAiB;AAAA,IAC/D,IAAI,kBAAkB,YAAY,EAAE;AAAA,IACpC,MAAM,CAAC,QAAQ,aAAa,GAAG,YAAY,IAAI;AAAA,IAC/C,SAAS,YAAY;AAAA,IACrB,WAAW,YAAY;AAAA,EACzB,EAAE;AACJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RESOURCE_PREVIEW_LAYOUT,
|
|
3
3
|
RESOURCE_PROPERTIES_LAYOUT
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KPLESRQY.mjs";
|
|
5
5
|
import {
|
|
6
6
|
VIEW_PAGE_TYPES
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QJHQN6OD.mjs";
|
|
8
8
|
import {
|
|
9
9
|
__export
|
|
10
10
|
} from "./chunk-FLGC65SR.mjs";
|
|
@@ -74,4 +74,4 @@ export {
|
|
|
74
74
|
PROPERTIES_TITLE_I18N_KEY,
|
|
75
75
|
identity_exports
|
|
76
76
|
};
|
|
77
|
-
//# sourceMappingURL=chunk-
|
|
77
|
+
//# sourceMappingURL=chunk-C2AMOM7H.mjs.map
|
|
@@ -16,20 +16,20 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
PAGE_TYPE,
|
|
18
18
|
RESOURCE_KINDS
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-B24VYGHV.mjs";
|
|
20
20
|
import {
|
|
21
21
|
bindWorkspacePreviewSurface
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-CXFQME65.mjs";
|
|
23
23
|
import {
|
|
24
24
|
selectWorkspaceResourcePreview,
|
|
25
25
|
selectWorkspaceResourceSubject
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-E4G4HDOC.mjs";
|
|
27
27
|
import {
|
|
28
28
|
createWorkspaceStateReader
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-WJNASQF2.mjs";
|
|
30
30
|
import {
|
|
31
31
|
VIEW_WORKSPACE_TAB_ID
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-QJHQN6OD.mjs";
|
|
33
33
|
import {
|
|
34
34
|
createWorkspaceId
|
|
35
35
|
} from "./chunk-4XEXLHX4.mjs";
|
|
@@ -410,4 +410,4 @@ export {
|
|
|
410
410
|
mountMaterialPropertiesPanel,
|
|
411
411
|
mountMaterialPreviewPanel
|
|
412
412
|
};
|
|
413
|
-
//# sourceMappingURL=chunk-
|
|
413
|
+
//# sourceMappingURL=chunk-C3WVSJZF.mjs.map
|
|
@@ -14,10 +14,10 @@ import {
|
|
|
14
14
|
} from "./chunk-ZYTHV373.mjs";
|
|
15
15
|
import {
|
|
16
16
|
createWorkspaceStateReader
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-WJNASQF2.mjs";
|
|
18
18
|
import {
|
|
19
19
|
VIEW_WORKSPACE_TAB_ID
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-QJHQN6OD.mjs";
|
|
21
21
|
|
|
22
22
|
// packages/view-plugin-asset/src/ui/mount.tsx
|
|
23
23
|
import { createRoot } from "react-dom/client";
|
|
@@ -118,4 +118,4 @@ async function mountAssetPropertiesPanel(props) {
|
|
|
118
118
|
export {
|
|
119
119
|
mountAssetPropertiesPanel
|
|
120
120
|
};
|
|
121
|
-
//# sourceMappingURL=chunk-
|
|
121
|
+
//# sourceMappingURL=chunk-CAXCOZ7Y.mjs.map
|