@weppy/roblox-mcp 2.17.4 → 2.17.6
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/CHANGELOG.md +14 -0
- package/README.md +2 -2
- package/dashboard/dist/assets/{AiPromptExamples-B3LZ06_M.js → AiPromptExamples-CbfCoFve.js} +1 -1
- package/dashboard/dist/assets/{AssetsPage-DBMNmn9Z.js → AssetsPage-DTCXBoYA.js} +1 -1
- package/dashboard/dist/assets/{ChangelogPage-D_G_HjiK.js → ChangelogPage-Cadbq_zL.js} +1 -1
- package/dashboard/dist/assets/{ConfirmModal-CL0Z5xwJ.js → ConfirmModal-DQEfv0Ep.js} +1 -1
- package/dashboard/dist/assets/{ConnectionPage-DaYME7QT.js → ConnectionPage-Clnx4gBI.js} +1 -1
- package/dashboard/dist/assets/{ControlsPage-gnKyi48F.js → ControlsPage-CT8JR9CW.js} +1 -1
- package/dashboard/dist/assets/{CurrentPlaceScope-CHRh7s-z.js → CurrentPlaceScope-peMPRcro.js} +1 -1
- package/dashboard/dist/assets/{GameChangeDetail-CbYXbvWl.js → GameChangeDetail-B_Bk0OE2.js} +1 -1
- package/dashboard/dist/assets/{InfoLabel-BaayM8hW.js → InfoLabel-Bi2B4_BK.js} +1 -1
- package/dashboard/dist/assets/{OverviewPage-DuPB7VBe.js → OverviewPage-CGKpvE5d.js} +1 -1
- package/dashboard/dist/assets/{PageHeader-C1A4pFFD.js → PageHeader-PYyDz5EU.js} +1 -1
- package/dashboard/dist/assets/{PlaceSelectOptions-DU7Ka-gE.js → PlaceSelectOptions-DFWeNtyn.js} +1 -1
- package/dashboard/dist/assets/{PlaytestAiPromptExamples-Bf494cNk.js → PlaytestAiPromptExamples-DCLVUPo3.js} +1 -1
- package/dashboard/dist/assets/PlaytestPage-BPQd3nrz.js +127 -0
- package/dashboard/dist/assets/{SettingsPage-Om-hGqIQ.js → SettingsPage-rgVEr-he.js} +1 -1
- package/dashboard/dist/assets/{StatusBadge-CiHSf_o_.js → StatusBadge-LnSy3DVI.js} +1 -1
- package/dashboard/dist/assets/{SyncPage-BTADHgCn.js → SyncPage-BrQDt7-3.js} +1 -1
- package/dashboard/dist/assets/{Tabs-C0QQfjUl.js → Tabs-BQ9tpG0z.js} +1 -1
- package/dashboard/dist/assets/{TierPromoPanel-DI3EP06A.js → TierPromoPanel--_qegOQx.js} +1 -1
- package/dashboard/dist/assets/{ToolsPage-CCsd60Kh.js → ToolsPage-C-E6yB34.js} +1 -1
- package/dashboard/dist/assets/{TooltipText-INE_h7BS.js → TooltipText-qTYKP233.js} +1 -1
- package/dashboard/dist/assets/{UiStudioPage-TfbhZvt5.js → UiStudioPage-BjXizccO.js} +1 -1
- package/dashboard/dist/assets/{WhatsNewPage-BPKMcfVs.js → WhatsNewPage-C--5gRKm.js} +1 -1
- package/dashboard/dist/assets/{bot-TMxhORyF.js → bot-lfjvzKzF.js} +1 -1
- package/dashboard/dist/assets/{check-C5Uo2cs_.js → check-D3G1Hmd8.js} +1 -1
- package/dashboard/dist/assets/{copy-BENnfclm.js → copy-BzIAPDmY.js} +1 -1
- package/dashboard/dist/assets/{index-ZP3F-qh6.js → index-BAIOgi4p.js} +11 -11
- package/dashboard/dist/assets/{sample-requests-DVllzgEu.js → sample-requests-CmQWgVaq.js} +1 -1
- package/dashboard/dist/assets/{trash-2-C7bZq3Km.js → trash-2-Sy4mcZS-.js} +1 -1
- package/dashboard/dist/assets/{useLiveUptime-CBpmama-.js → useLiveUptime-BiwNNavN.js} +1 -1
- package/dashboard/dist/assets/{useSettings-Ug_fLuUn.js → useSettings-lRz2zeoV.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dist/index.js +135 -135
- package/package.json +1 -1
- package/roblox-plugin/WeppyRobloxMCP.rbxm +0 -0
- package/dashboard/dist/assets/PlaytestPage-JPS-_xPE.js +0 -127
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weppy/roblox-mcp",
|
|
3
|
-
"version": "2.17.
|
|
3
|
+
"version": "2.17.6",
|
|
4
4
|
"description": "MCP (Model Context Protocol) server for Roblox Studio integration - enables AI coding agents to interact with Roblox Studio in real-time",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
Binary file
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import{f as Te,j as t,X as Vt,r,b as De,u as re,D as zt,p as Wt,k as Jt,s as Yt,c as Qt,o as Xt,a as Zt,e as ea,d as ta,i as aa,T as sa}from"./index-ZP3F-qh6.js";import{T as na}from"./TierPromoPanel-DI3EP06A.js";import{P as ia,a as la}from"./PageHeader-C1A4pFFD.js";import{I as ra}from"./InfoLabel-BaayM8hW.js";import{C as oa}from"./CurrentPlaceScope-CHRh7s-z.js";import{T as it}from"./TooltipText-INE_h7BS.js";import{C as mt}from"./ConfirmModal-CL0Z5xwJ.js";import{T as ca,C as Ke}from"./Tabs-C0QQfjUl.js";import{P as jt}from"./PlaytestAiPromptExamples-Bf494cNk.js";import{B as da}from"./bot-TMxhORyF.js";import{T as St}from"./trash-2-C7bZq3Km.js";import{C as ua}from"./check-C5Uo2cs_.js";import"./PlaceSelectOptions-DU7Ka-gE.js";import"./ConfirmModal.module-DJksQHBd.js";import"./AiPromptExamples-B3LZ06_M.js";import"./copy-BENnfclm.js";/**
|
|
2
|
-
* @license lucide-react v1.8.0 - ISC
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the ISC license.
|
|
5
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const pa=[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]],fa=Te("arrow-down",pa);/**
|
|
7
|
-
* @license lucide-react v1.8.0 - ISC
|
|
8
|
-
*
|
|
9
|
-
* This source code is licensed under the ISC license.
|
|
10
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
-
*/const ma=[["path",{d:"m5 12 7-7 7 7",key:"hav0vg"}],["path",{d:"M12 19V5",key:"x0mq9r"}]],ha=Te("arrow-up",ma);/**
|
|
12
|
-
* @license lucide-react v1.8.0 - ISC
|
|
13
|
-
*
|
|
14
|
-
* This source code is licensed under the ISC license.
|
|
15
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
-
*/const ya=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],ht=Te("chevron-down",ya);/**
|
|
17
|
-
* @license lucide-react v1.8.0 - ISC
|
|
18
|
-
*
|
|
19
|
-
* This source code is licensed under the ISC license.
|
|
20
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
-
*/const va=[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]],Nt=Te("chevron-up",va);/**
|
|
22
|
-
* @license lucide-react v1.8.0 - ISC
|
|
23
|
-
*
|
|
24
|
-
* This source code is licensed under the ISC license.
|
|
25
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
26
|
-
*/const ga=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}]],ba=Te("circle-dot",ga);/**
|
|
27
|
-
* @license lucide-react v1.8.0 - ISC
|
|
28
|
-
*
|
|
29
|
-
* This source code is licensed under the ISC license.
|
|
30
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
31
|
-
*/const _a=[["circle",{cx:"9",cy:"12",r:"1",key:"1vctgf"}],["circle",{cx:"9",cy:"5",r:"1",key:"hp0tcf"}],["circle",{cx:"9",cy:"19",r:"1",key:"fkjjf6"}],["circle",{cx:"15",cy:"12",r:"1",key:"1tmaij"}],["circle",{cx:"15",cy:"5",r:"1",key:"19l28e"}],["circle",{cx:"15",cy:"19",r:"1",key:"f4zoj3"}]],wt=Te("grip-vertical",_a);/**
|
|
32
|
-
* @license lucide-react v1.8.0 - ISC
|
|
33
|
-
*
|
|
34
|
-
* This source code is licensed under the ISC license.
|
|
35
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
36
|
-
*/const xa=[["path",{d:"M16 5H3",key:"m91uny"}],["path",{d:"M11 12H3",key:"51ecnj"}],["path",{d:"M16 19H3",key:"zzsher"}],["path",{d:"M18 9v6",key:"1twb98"}],["path",{d:"M21 12h-6",key:"bt1uis"}]],ja=Te("list-plus",xa);/**
|
|
37
|
-
* @license lucide-react v1.8.0 - ISC
|
|
38
|
-
*
|
|
39
|
-
* This source code is licensed under the ISC license.
|
|
40
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
41
|
-
*/const Sa=[["circle",{cx:"12",cy:"16",r:"1",key:"1au0dj"}],["rect",{x:"3",y:"10",width:"18",height:"12",rx:"2",key:"6s8ecr"}],["path",{d:"M7 10V7a5 5 0 0 1 10 0v3",key:"1pqi11"}]],Na=Te("lock-keyhole",Sa);/**
|
|
42
|
-
* @license lucide-react v1.8.0 - ISC
|
|
43
|
-
*
|
|
44
|
-
* This source code is licensed under the ISC license.
|
|
45
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
46
|
-
*/const wa=[["path",{d:"M14 4.1 12 6",key:"ita8i4"}],["path",{d:"m5.1 8-2.9-.8",key:"1go3kf"}],["path",{d:"m6 12-1.9 2",key:"mnht97"}],["path",{d:"M7.2 2.2 8 5.1",key:"1cfko1"}],["path",{d:"M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z",key:"s0h3yz"}]],Ca=Te("mouse-pointer-click",wa);/**
|
|
47
|
-
* @license lucide-react v1.8.0 - ISC
|
|
48
|
-
*
|
|
49
|
-
* This source code is licensed under the ISC license.
|
|
50
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
51
|
-
*/const Ra=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],Pa=Te("pencil",Ra);/**
|
|
52
|
-
* @license lucide-react v1.8.0 - ISC
|
|
53
|
-
*
|
|
54
|
-
* This source code is licensed under the ISC license.
|
|
55
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
56
|
-
*/const ka=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],Ot=Te("plus",ka);/**
|
|
57
|
-
* @license lucide-react v1.8.0 - ISC
|
|
58
|
-
*
|
|
59
|
-
* This source code is licensed under the ISC license.
|
|
60
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
61
|
-
*/const Aa=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],Ea=Te("rotate-ccw",Aa);/**
|
|
62
|
-
* @license lucide-react v1.8.0 - ISC
|
|
63
|
-
*
|
|
64
|
-
* This source code is licensed under the ISC license.
|
|
65
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
66
|
-
*/const Da=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],Ta=Te("triangle-alert",Da),Ia="_header_6e369_1",La="_copy_6e369_16",Ma="_close_6e369_39",rt={header:Ia,copy:La,close:Ma};function ze(e){return t.jsxs("header",{className:rt.header,children:[t.jsxs("div",{className:rt.copy,children:[t.jsx("h2",{children:e.title}),e.description&&t.jsx("p",{children:e.description})]}),t.jsx("button",{type:"button",className:rt.close,"aria-label":e.closeLabel,disabled:e.closeDisabled,onClick:e.onRequestClose,children:t.jsx(Vt,{size:18,"aria-hidden":"true"})})]})}const $a=5e3;function Ct(e){return typeof e=="number"?{placeId:String(e)}:void 0}function Va(e,a){return typeof a=="number"?`${e}?placeId=${encodeURIComponent(String(a))}`:e}function Oa(e){const a=e.context;return{...e,...typeof(a==null?void 0:a.contextId)=="string"?{contextId:a.contextId}:{},...a!=null&&a.contextSummary&&typeof a.contextSummary=="object"?{contextSummary:a.contextSummary}:{},...a!=null&&a.replayMetadata&&typeof a.replayMetadata=="object"?{replayMetadata:a.replayMetadata}:{}}}function Rt(e){return e instanceof Error?e.message:String(e)}function Ba(e){const a=(e==null?void 0:e.enabled)??!0,n=(e==null?void 0:e.placeId)??null,[i,c]=r.useState([]),[o,d]=r.useState(a?"loading":"idle"),[y,h]=r.useState(null),[_,N]=r.useState(null),[C,j]=r.useState(a),[f,$]=r.useState(!1),[w,T]=r.useState(null),S=r.useRef(null),F=r.useRef(0),R=r.useRef(null),E=r.useCallback(async()=>{try{const B=Ct(n),L=B?await De.get("/api/dashboard/playtest/history",B):await De.get("/api/dashboard/playtest/history");c(L.entries??[]),d("ready"),h(null)}catch(B){d("error"),h(Rt(B))}},[n]),K=r.useCallback(async()=>{if(!a){j(!1);return}await E(),j(!1)},[a,E]),I=r.useCallback(()=>{F.current+=1,R.current=null,N(null),$(!1),T(null)},[]);r.useEffect(()=>{I()},[I,a,n]);const W=r.useCallback(async B=>{if(!a)return;R.current=B;const L=++F.current;N(null),$(!0),T(null);try{const X=Ct(n),oe=`/api/dashboard/playtest/detail/${encodeURIComponent(B)}`,ce=X?await De.get(oe,X):await De.get(oe);L===F.current&&N(Oa(ce))}catch(X){L===F.current&&T(Rt(X))}finally{L===F.current&&$(!1)}},[a,n]),Z=r.useCallback(async()=>{const B=R.current;B&&await W(B)},[W]),G=r.useCallback(async()=>{a&&(d("loading"),h(null),await E())},[a,E]),O=r.useCallback(async()=>{a&&(await De.post(Va("/api/dashboard/playtest/history/clear",n)),c([]),d("ready"),h(null),I())},[I,a,n]);return r.useEffect(()=>{if(!a){j(!1),d("idle"),h(null);return}return d("loading"),h(null),K(),S.current=setInterval(K,$a),()=>{S.current&&clearInterval(S.current)}},[a,K]),{history:i,historyLoadState:o,historyError:y,selectedReport:_,loading:C,detailLoading:f,detailError:w,loadReport:W,retryReport:Z,retryHistory:G,clearSelectedReport:I,clearHistory:O}}function Fa(e){const a="2026-03-27T15:26:00.000Z",n={testScenario:e("playtest.sample.context.why","Spawn into the arena, survive the opener, and verify the HUD responds immediately."),expectedBehavior:e("playtest.sample.context.expected","The player spawns safely, the countdown UI appears within one second, and the first wave starts without errors."),observedBehavior:e("playtest.sample.context.observed","Spawn protection held, the HUD updated on time, and wave one completed with no gameplay regressions.")};return{history:[{recordId:"sample_playtest_preview",directoryName:"sample-playtest-preview",recordKind:"structured",timestamp:a,testName:e("playtest.sample.history.name","Sample Arena Smoke Test"),mode:"play",executionKind:"structured_session",overallStatus:"passed",status:"passed",durationMs:4820,contextId:"sample_playtest_preview",contextSummary:n,evidenceSummary:{server:{required:!0,status:"passed",stepIds:["wave-started"]},clientUi:{required:!0,status:"passed",stepIds:["hud-visible"]},interaction:{required:!0,status:"passed",provider:"virtual_input",stepIds:["start-click"]},visual:{required:!1,status:"not_requested",reason:"not_requested",stepIds:[]}},agentCounts:{server:1,client:1},limitation:{code:"play_screenshot_unsupported",message:e("playtest.sample.limit.visual","Play screenshot evidence is unavailable in structured session v1")}}],report:{recordId:"sample_playtest_preview",directoryName:"sample-playtest-preview",recordKind:"structured",markdown:e("playtest.sample.report.markdown",`# Sample Arena Smoke Test
|
|
67
|
-
|
|
68
|
-
- Spawn flow: PASS
|
|
69
|
-
- HUD countdown: PASS
|
|
70
|
-
- Wave bootstrap: PASS
|
|
71
|
-
|
|
72
|
-
This is a sample preview. Live playtests and real reports are available with Pro.`),logs:e("playtest.sample.report.logs",`[sample] boot playtest preview
|
|
73
|
-
[sample] spawn protection active
|
|
74
|
-
[sample] hud countdown rendered
|
|
75
|
-
[sample] wave one completed
|
|
76
|
-
[sample] preview report finished`),contextId:"sample_playtest_preview",contextSummary:n,artifactErrors:[],result:{schemaVersion:1,sessionId:"sample-session",recordId:"sample_playtest_preview",testName:e("playtest.sample.history.name","Sample Arena Smoke Test"),executionKind:"structured_session",overallStatus:"passed",overallPassed:!0,terminalReason:{code:"all_required_evidence_passed",message:e("playtest.sample.terminal","All required evidence passed")},mode:"play",place:{placeName:e("playtest.sample.place","Sample Arena")},startedAt:a,endedAt:"2026-03-27T15:26:04.820Z",durationMs:4820,agents:[{agentId:"sample-server-agent",role:"server"},{agentId:"sample-client-agent",role:"client",clientId:"client-1"}],capabilities:{semanticUiSnapshot:!0,virtualInput:!0,fixedBootstrap:!0,projectTestAdapter:!1},requiredEvidence:{server:!0,clientUi:!0,interaction:!0,visual:!1},dimensions:{server:{required:!0,status:"passed",stepIds:["wave-started"]},clientUi:{required:!0,status:"passed",stepIds:["hud-visible"]},interaction:{required:!0,status:"passed",provider:"virtual_input",stepIds:["start-click"]},visual:{required:!1,status:"not_requested",reason:"not_requested",stepIds:[]}},limitations:[{code:"play_screenshot_unsupported",message:e("playtest.sample.limit.visual","Play screenshot evidence is unavailable in structured session v1")}],steps:[{index:0,stepId:"start-click",target:{role:"client",clientId:"client-1"},action:"input_click",dimension:"interaction",required:!0,status:"passed",startedAt:a,endedAt:"2026-03-27T15:26:00.120Z",durationMs:120,expected:{activated:!0},observed:{activated:!0},evidence:{delivery:"VirtualInput",observation:"GuiButton.Activated"}}],cleanup:{status:"passed",errors:[]},artifacts:{status:"complete",files:["test-result.json","test-report.md","test-log.txt","test-context.json"]}}}}}function Ve(e,a){switch(a){case"passed":return e("playtest.result.status.passed","Passed");case"failed":return e("playtest.result.status.failed","Failed");case"timed_out":return e("playtest.result.status.timedOut","Timed out");case"cancelled":return e("playtest.result.status.cancelled","Cancelled");case"insufficient_evidence":return e("playtest.result.status.insufficientEvidence","Insufficient evidence");case"unavailable":return e("playtest.result.status.unavailable","Unavailable");case"skipped":return e("playtest.result.status.skipped","Skipped");case"not_requested":return e("playtest.result.status.notRequested","Not requested");default:return e("playtest.result.status.unknown","Unknown")}}function gt(e){return e==="passed"?"✓":e==="failed"||e==="timed_out"?"×":e==="cancelled"||e==="insufficient_evidence"||e==="unavailable"?"!":"–"}function Bt(e){return e<1e3?`${e}ms`:`${(e/1e3).toFixed(1)}s`}function at(e){return JSON.stringify(e,null,2)}function Ft(e,a,n){return a==="play_screenshot_unsupported"?e("playtest.limitations.visualUnsupported","Visual evidence unavailable — Play screenshots are not supported in structured session v1."):a==="virtual_input_unavailable"?e("playtest.limitations.virtualInputUnavailable","Virtual input is unavailable for this session."):n}function Ga(e,a){return a==="play_screenshot_unsupported"?e("playtest.limitations.visualUnsupportedReason","Play screenshots are not supported in structured session v1."):a==="not_requested"?e("playtest.result.status.notRequested","Not requested"):a==="required_evidence_missing"?e("playtest.dimension.reason.missing","Required evidence is missing."):a==="required_capability_unavailable"?e("playtest.dimension.reason.capability","The required capability is unavailable."):a}const Ha="_page_14ipf_2",qa="_sampleBanner_14ipf_10",Ua="_sampleBannerRow_14ipf_22",Ka="_sampleBannerMain_14ipf_29",za="_sampleBadge_14ipf_36",Wa="_sampleTitle_14ipf_51",Ja="_sampleMessage_14ipf_58",Ya="_sampleActions_14ipf_65",Qa="_primaryAction_14ipf_73",Xa="_secondaryAction_14ipf_74",Za="_resetAction_14ipf_75",es="_card_14ipf_124",ts="_cardHeader_14ipf_131",as="_clearButton_14ipf_144",ss="_statusRow_14ipf_173",ns="_statusIndicator_14ipf_180",is="_statusRunning_14ipf_188",ls="_statusPaused_14ipf_193",rs="_statusNotRunning_14ipf_197",os="_statusLabel_14ipf_201",cs="_statusMeta_14ipf_208",ds="_controlButtons_14ipf_214",us="_btn_14ipf_221",ps="_btnPrimary_14ipf_243",fs="_btnDanger_14ipf_253",ms="_historyList_14ipf_265",hs="_historyItem_14ipf_271",ys="_stepDisclosure_14ipf_291",vs="_historyItemSelected_14ipf_296",gs="_historyItemHeader_14ipf_301",bs="_historyIcon_14ipf_307",_s="_historyTimestamp_14ipf_312",xs="_historyName_14ipf_319",js="_recordKind_14ipf_330",Ss="_historyItemMeta_14ipf_344",Ns="_historyMode_14ipf_354",ws="_historyDuration_14ipf_358",Cs="_historyStatus_14ipf_362",Rs="_status_passed_14ipf_369",Ps="_status_failed_14ipf_373",ks="_status_running_14ipf_377",As="_status_timed_out_14ipf_381",Es="_status_cancelled_14ipf_385",Ds="_status_insufficient_evidence_14ipf_386",Ts="_historyError_14ipf_390",Is="_historyEvidence_14ipf_400",Ls="_historyLimitation_14ipf_410",Ms="_detailShell_14ipf_421",$s="_detailHeader_14ipf_429",Vs="_detailHeading_14ipf_440",Os="_detailRecordName_14ipf_451",Bs="_detailCloseButton_14ipf_460",Fs="_detailRetryButton_14ipf_480",Gs="_detailBody_14ipf_485",Hs="_detailState_14ipf_494",qs="_detailErrorTitle_14ipf_505",Us="_detailErrorMessage_14ipf_512",Ks="_reportContainer_14ipf_534",zs="_runSummary_14ipf_540",Ws="_viewerSection_14ipf_541",Js="_summaryLead_14ipf_554",Ys="_summaryStatusMark_14ipf_560",Qs="_viewerHeading_14ipf_573",Xs="_summaryName_14ipf_583",Zs="_summaryReason_14ipf_594",en="_summaryFacts_14ipf_601",tn="_subsectionLabel_14ipf_614",an="_sectionHeadingRow_14ipf_629",sn="_sectionHint_14ipf_637",nn="_dimensionGrid_14ipf_642",ln="_dimensionCard_14ipf_649",rn="_dimensionHeader_14ipf_657",on="_statusMark_14ipf_663",cn="_dimensionName_14ipf_676",dn="_requirementBadge_14ipf_686",un="_dimensionStatus_14ipf_694",pn="_dimensionMeta_14ipf_701",fn="_tone_passed_14ipf_709",mn="_tone_failed_14ipf_710",hn="_tone_timed_out_14ipf_711",yn="_tone_cancelled_14ipf_712",vn="_tone_insufficient_evidence_14ipf_713",gn="_tone_unavailable_14ipf_714",bn="_tone_skipped_14ipf_715",_n="_tone_not_requested_14ipf_716",xn="_stepList_14ipf_718",jn="_stepItem_14ipf_725",Sn="_stepIndex_14ipf_749",Nn="_stepIdentity_14ipf_756",wn="_stepName_14ipf_763",Cn="_stepMeta_14ipf_773",Rn="_stepStatus_14ipf_774",Pn="_chevron_14ipf_782",kn="_chevronOpen_14ipf_788",An="_stepDetails_14ipf_790",En="_evidenceBlock_14ipf_799",Dn="_evidenceLabel_14ipf_803",Tn="_stepError_14ipf_830",In="_recordProblem_14ipf_831",Ln="_capabilityGrid_14ipf_846",Mn="_capabilityItem_14ipf_853",$n="_capabilityYes_14ipf_866",Vn="_capabilityNo_14ipf_867",On="_capabilityState_14ipf_868",Bn="_limitations_14ipf_870",Fn="_artifactList_14ipf_871",Gn="_agentList_14ipf_872",Hn="_artifactDisclosures_14ipf_889",qn="_artifactDisclosure_14ipf_889",Un="_artifactButton_14ipf_903",Kn="_artifactContent_14ipf_928",zn="_limitationItem_14ipf_948",Wn="_reportContextPanel_14ipf_965",Jn="_reportContextRow_14ipf_975",Yn="_reportContextLabel_14ipf_983",Qn="_reportSection_14ipf_991",Xn="_reportSectionHeader_14ipf_997",Zn="_reportMarkdown_14ipf_1009",ei="_reportLogs_14ipf_1022",ti="_emptyState_14ipf_1037",ai="_emptyStateTitle_14ipf_1044",si="_emptyStateMessage_14ipf_1052",ni="_upgradePanel_14ipf_1061",ii="_upgradePanelIcon_14ipf_1069",li="_upgradePanelTitle_14ipf_1074",ri="_upgradePanelDesc_14ipf_1082",oi="_benefitList_14ipf_1092",ci="_benefitItem_14ipf_1103",di="_upgradeActions_14ipf_1118",ui="_workspaceTabs_14ipf_1124",pi="_sessionHelp_14ipf_1137",fi="_stopAction_14ipf_1143",mi="_controlEditor_14ipf_1144",hi="_profileToolbar_14ipf_1146",yi="_profileDialog_14ipf_1147",vi="_sessionBar_14ipf_1152",gi="_sessionIdentity_14ipf_1165",bi="_sessionActions_14ipf_1195",_i="_profileActions_14ipf_1196",xi="_profileDialogActions_14ipf_1197",ji="_liveWorkspace_14ipf_1238",Si="_profileLabelRow_14ipf_1254",Ni="_profileHint_14ipf_1262",wi="_actualValue_14ipf_1271",Ci="_watchReading_14ipf_1272",Ri="_liveGrid_14ipf_1308",Pi="_livePanel_14ipf_1315",ki="_panelEmpty_14ipf_1352",Ai="_controlAvailability_14ipf_1358",Ei="_controlGate_14ipf_1361",Di="_controlGateTrigger_14ipf_1364",Ti="_controlGateHint_14ipf_1366",Ii="_editorLabel_14ipf_1367",Li="_editorHeading_14ipf_1368",Mi="_savedValueState_14ipf_1369",$i="_valueToolbar_14ipf_1373",Vi="_valueFilters_14ipf_1383",Oi="_valuePagination_14ipf_1390",Bi="_valueListStatus_14ipf_1391",Fi="_valueCount_14ipf_1392",Gi="_layoutHint_14ipf_1394",Hi="_srOnly_14ipf_1395",qi="_unifiedValueRows_14ipf_1396",Ui="_liveRows_14ipf_1397",Ki="_watchRows_14ipf_1397",zi="_valueGroup_14ipf_1398",Wi="_valueGroupToggle_14ipf_1400",Ji="_valueGroupRows_14ipf_1406",Yi="_controlRow_14ipf_1406",Qi="_watchRow_14ipf_1397",Xi="_actionRow_14ipf_1408",Zi="_historyBrowser_14ipf_1412",el="_historyToolbar_14ipf_1413",tl="_rowIdentity_14ipf_1437",al="_freshness_14ipf_1440",sl="_presentationMeta_14ipf_1461",nl="_rowFeedback_14ipf_1462",il="_controlEditorRow_14ipf_1468",ll="_controlActions_14ipf_1469",rl="_applyOnStartOption_14ipf_1472",ol="_valueDetails_14ipf_1474",cl="_valueDetailButton_14ipf_1480",dl="_valueDetailShell_14ipf_1483",ul="_valueDetailBody_14ipf_1484",pl="_valueDetailList_14ipf_1485",fl="_valueDetailActions_14ipf_1489",ml="_valueDetailFeedback_14ipf_1490",hl="_defaultValueEditor_14ipf_1493",yl="_defaultBooleanEditor_14ipf_1497",vl="_booleanEditor_14ipf_1500",gl="_rangeEditor_14ipf_1509",bl="_valueWorkspacePanel_14ipf_1524",_l="_valueWorkspaceHeader_14ipf_1525",xl="_valueSections_14ipf_1526",jl="_valueSection_14ipf_1526",Sl="_valueSectionHeader_14ipf_1528",Nl="_valueSectionHeading_14ipf_1529",wl="_valueSectionCount_14ipf_1531",Cl="_valueSectionHeaderActions_14ipf_1532",Rl="_sectionDragHandle_14ipf_1533",Pl="_sectionMoveButton_14ipf_1534",kl="_valueReorderControls_14ipf_1535",Al="_dragHandle_14ipf_1537",El="_runtimeSettings_14ipf_1549",Dl="_runtimeSettingSwitch_14ipf_1550",Tl="_runtimeSettingSwitchInput_14ipf_1553",Il="_runtimeSettingSwitchTrack_14ipf_1554",Ll="_runtimeSettingSwitchThumb_14ipf_1555",Ml="_layoutError_14ipf_1559",$l="_controlValueList_14ipf_1560",Vl="_watchValueGrid_14ipf_1561",Ol="_actionValueList_14ipf_1562",Bl="_valueEntryShell_14ipf_1563",Fl="_watchCardMain_14ipf_1576",Gl="_watchDetails_14ipf_1583",Hl="_actionSummary_14ipf_1592",ql="_actionExecution_14ipf_1592",Ul="_actionParameter_14ipf_1593",Kl="_actionInactiveReason_14ipf_1597",zl="_actionParameterGrid_14ipf_1602",Wl="_actionParameterError_14ipf_1608",Jl="_deploymentGuide_14ipf_1634",Yl="_deploymentScope_14ipf_1646",Ql="_deploymentLifecycle_14ipf_1649",Xl="_deploymentNotice_14ipf_1650",Zl="_deploymentChecklist_14ipf_1652",er="_deploymentDescription_14ipf_1656",tr="_deploymentDetails_14ipf_1659",ar="_inlineError_14ipf_1679",sr="_profileEditorDialog_14ipf_1682",nr="_profileDialogBody_14ipf_1683",ir="_profileDeleteAction_14ipf_1686",lr="_profileDeleteReason_14ipf_1687",rr="_bindingTabs_14ipf_1688",or="_bindingList_14ipf_1692",cr="_bindingEmpty_14ipf_1693",dr="_bindingItem_14ipf_1694",ur="_bindingItemCopy_14ipf_1699",pr="_bindingPresentation_14ipf_1700",fr="_bindingPin_14ipf_1703",mr="_bindingItemActions_14ipf_1705",hr="_bindingDelete_14ipf_1709",yr="_addBindingButton_14ipf_1711",vr="_bindingForm_14ipf_1712",gr="_bindingFormGrid_14ipf_1713",br="_bindingBooleanDefault_14ipf_1716",_r="_bindingPathField_14ipf_1718",xr="_rangeFields_14ipf_1719",jr="_selectionButton_14ipf_1720",Sr="_bindingFormActions_14ipf_1721",Nr="_bindingError_14ipf_1722",wr="_valueManagerShell_14ipf_1723",Cr="_valueSourceTabs_14ipf_1724",Rr="_valueManagerBody_14ipf_1728",Pr="_valueSourcePanel_14ipf_1729",kr="_registeredIntro_14ipf_1730",Ar="_registeredEmpty_14ipf_1734",Er="_registeredSteps_14ipf_1737",Dr="_registeredEmptyActions_14ipf_1740",Tr="_adapterSetupList_14ipf_1745",Ir="_adapterSetupRow_14ipf_1749",Lr="_adapterMethods_14ipf_1756",Mr="_connectionGuide_14ipf_1757",$r="_registrationGuide_14ipf_1760",Vr="_adapterSetupContext_14ipf_1761",Or="_valueSearch_14ipf_1762",Br="_firstProfileName_14ipf_1763",Fr="_sourceIntro_14ipf_1767",Gr="_catalogGroups_14ipf_1771",Hr="_catalogRow_14ipf_1772",qr="_candidateActions_14ipf_1780",Ur="_candidateEntry_14ipf_1782",Kr="_propertySelection_14ipf_1783",zr="_propertySelectionHeader_14ipf_1784",Wr="_selectedInstance_14ipf_1785",Jr="_propertyPickerLabel_14ipf_1786",Yr="_propertyPicker_14ipf_1786",Qr="_propertyPickerTrigger_14ipf_1792",Xr="_propertyPickerPanel_14ipf_1794",Zr="_propertyPickerSearchRow_14ipf_1796",eo="_propertyPickerList_14ipf_1800",to="_propertyPickerGroup_14ipf_1802",ao="_propertyPickerOption_14ipf_1805",so="_compoundEditor_14ipf_1811",no="_compoundCoordinates_14ipf_1812",io="_colorSwatch_14ipf_1819",lo="_candidateAction_14ipf_1780",ro="_candidateActionSizer_14ipf_1836",oo="_candidateError_14ipf_1840",co="_valueManagerFooter_14ipf_1842",uo="_catalogDetails_14ipf_1843",po="_inlineNotice_14ipf_1852",fo="_subscriptionUsage_14ipf_1853",mo="_pendingProfileAction_14ipf_1854",ho="_registrationExample_14ipf_1859",yo="_registrationActions_14ipf_1862",s={page:Ha,sampleBanner:qa,sampleBannerRow:Ua,sampleBannerMain:Ka,sampleBadge:za,sampleTitle:Wa,sampleMessage:Ja,sampleActions:Ya,primaryAction:Qa,secondaryAction:Xa,resetAction:Za,card:es,cardHeader:ts,clearButton:as,statusRow:ss,statusIndicator:ns,statusRunning:is,statusPaused:ls,statusNotRunning:rs,statusLabel:os,statusMeta:cs,controlButtons:ds,btn:us,btnPrimary:ps,btnDanger:fs,historyList:ms,historyItem:hs,stepDisclosure:ys,historyItemSelected:vs,historyItemHeader:gs,historyIcon:bs,historyTimestamp:_s,historyName:xs,recordKind:js,historyItemMeta:Ss,historyMode:Ns,historyDuration:ws,historyStatus:Cs,status_passed:Rs,status_failed:Ps,status_running:ks,status_timed_out:As,status_cancelled:Es,status_insufficient_evidence:Ds,historyError:Ts,historyEvidence:Is,historyLimitation:Ls,detailShell:Ms,detailHeader:$s,detailHeading:Vs,detailRecordName:Os,detailCloseButton:Bs,detailRetryButton:Fs,detailBody:Gs,detailState:Hs,detailErrorTitle:qs,detailErrorMessage:Us,reportContainer:Ks,runSummary:zs,viewerSection:Ws,summaryLead:Js,summaryStatusMark:Ys,viewerHeading:Qs,summaryName:Xs,summaryReason:Zs,summaryFacts:en,subsectionLabel:tn,sectionHeadingRow:an,sectionHint:sn,dimensionGrid:nn,dimensionCard:ln,dimensionHeader:rn,statusMark:on,dimensionName:cn,requirementBadge:dn,dimensionStatus:un,dimensionMeta:pn,tone_passed:fn,tone_failed:mn,tone_timed_out:hn,tone_cancelled:yn,tone_insufficient_evidence:vn,tone_unavailable:gn,tone_skipped:bn,tone_not_requested:_n,stepList:xn,stepItem:jn,stepIndex:Sn,stepIdentity:Nn,stepName:wn,stepMeta:Cn,stepStatus:Rn,chevron:Pn,chevronOpen:kn,stepDetails:An,evidenceBlock:En,evidenceLabel:Dn,stepError:Tn,recordProblem:In,capabilityGrid:Ln,capabilityItem:Mn,capabilityYes:$n,capabilityNo:Vn,capabilityState:On,limitations:Bn,artifactList:Fn,agentList:Gn,artifactDisclosures:Hn,artifactDisclosure:qn,artifactButton:Un,artifactContent:Kn,limitationItem:zn,reportContextPanel:Wn,reportContextRow:Jn,reportContextLabel:Yn,reportSection:Qn,reportSectionHeader:Xn,reportMarkdown:Zn,reportLogs:ei,emptyState:ti,emptyStateTitle:ai,emptyStateMessage:si,upgradePanel:ni,upgradePanelIcon:ii,upgradePanelTitle:li,upgradePanelDesc:ri,benefitList:oi,benefitItem:ci,upgradeActions:di,workspaceTabs:ui,sessionHelp:pi,stopAction:fi,controlEditor:mi,profileToolbar:hi,profileDialog:yi,sessionBar:vi,sessionIdentity:gi,sessionActions:bi,profileActions:_i,profileDialogActions:xi,liveWorkspace:ji,profileLabelRow:Si,profileHint:Ni,actualValue:wi,watchReading:Ci,liveGrid:Ri,livePanel:Pi,panelEmpty:ki,controlAvailability:Ai,controlGate:Ei,controlGateTrigger:Di,controlGateHint:Ti,editorLabel:Ii,editorHeading:Li,savedValueState:Mi,valueToolbar:$i,valueFilters:Vi,valuePagination:Oi,valueListStatus:Bi,valueCount:Fi,layoutHint:Gi,srOnly:Hi,unifiedValueRows:qi,liveRows:Ui,watchRows:Ki,valueGroup:zi,valueGroupToggle:Wi,valueGroupRows:Ji,controlRow:Yi,watchRow:Qi,actionRow:Xi,historyBrowser:Zi,historyToolbar:el,rowIdentity:tl,freshness:al,presentationMeta:sl,rowFeedback:nl,controlEditorRow:il,controlActions:ll,applyOnStartOption:rl,valueDetails:ol,valueDetailButton:cl,valueDetailShell:dl,valueDetailBody:ul,valueDetailList:pl,valueDetailActions:fl,valueDetailFeedback:ml,defaultValueEditor:hl,defaultBooleanEditor:yl,booleanEditor:vl,rangeEditor:gl,valueWorkspacePanel:bl,valueWorkspaceHeader:_l,valueSections:xl,valueSection:jl,valueSectionHeader:Sl,valueSectionHeading:Nl,valueSectionCount:wl,valueSectionHeaderActions:Cl,sectionDragHandle:Rl,sectionMoveButton:Pl,valueReorderControls:kl,dragHandle:Al,runtimeSettings:El,runtimeSettingSwitch:Dl,runtimeSettingSwitchInput:Tl,runtimeSettingSwitchTrack:Il,runtimeSettingSwitchThumb:Ll,layoutError:Ml,controlValueList:$l,watchValueGrid:Vl,actionValueList:Ol,valueEntryShell:Bl,watchCardMain:Fl,watchDetails:Gl,actionSummary:Hl,actionExecution:ql,actionParameter:Ul,actionInactiveReason:Kl,actionParameterGrid:zl,actionParameterError:Wl,deploymentGuide:Jl,deploymentScope:Yl,deploymentLifecycle:Ql,deploymentNotice:Xl,deploymentChecklist:Zl,deploymentDescription:er,deploymentDetails:tr,inlineError:ar,profileEditorDialog:sr,profileDialogBody:nr,profileDeleteAction:ir,profileDeleteReason:lr,bindingTabs:rr,bindingList:or,bindingEmpty:cr,bindingItem:dr,bindingItemCopy:ur,bindingPresentation:pr,bindingPin:fr,bindingItemActions:mr,bindingDelete:hr,addBindingButton:yr,bindingForm:vr,bindingFormGrid:gr,bindingBooleanDefault:br,bindingPathField:_r,rangeFields:xr,selectionButton:jr,bindingFormActions:Sr,bindingError:Nr,valueManagerShell:wr,valueSourceTabs:Cr,valueManagerBody:Rr,valueSourcePanel:Pr,registeredIntro:kr,registeredEmpty:Ar,registeredSteps:Er,registeredEmptyActions:Dr,adapterSetupList:Tr,adapterSetupRow:Ir,adapterMethods:Lr,connectionGuide:Mr,registrationGuide:$r,adapterSetupContext:Vr,valueSearch:Or,firstProfileName:Br,sourceIntro:Fr,catalogGroups:Gr,catalogRow:Hr,candidateActions:qr,candidateEntry:Ur,propertySelection:Kr,propertySelectionHeader:zr,selectedInstance:Wr,propertyPickerLabel:Jr,propertyPicker:Yr,propertyPickerTrigger:Qr,propertyPickerPanel:Xr,propertyPickerSearchRow:Zr,propertyPickerList:eo,propertyPickerGroup:to,propertyPickerOption:ao,compoundEditor:so,compoundCoordinates:no,colorSwatch:io,candidateAction:lo,candidateActionSizer:ro,candidateError:oo,valueManagerFooter:co,catalogDetails:uo,inlineNotice:po,subscriptionUsage:fo,pendingProfileAction:mo,registrationExample:ho,registrationActions:yo};function We(e){return e.trim().toLowerCase()}function vo(e){switch(We(e)){case"passed":return"✓";case"failed":case"timed_out":return"×";case"running":return"◔";case"cancelled":case"insufficient_evidence":return"!";default:return"–"}}function go(e,a){switch(We(a)){case"run":return e("playtest.status.mode.run","Run");case"server":return e("playtest.status.mode.server","Server");case"edit":return e("playtest.status.mode.edit","Edit");case"play":return e("playtest.status.mode.play","Play");default:return a}}function bo(e,a){const n=We(a);return n==="running"?e("playtest.history.status.running","Running"):Ve(e,n)}function _o(e){return e<1e3?`${e}ms`:`${(e/1e3).toFixed(1)}s`}function xo(e){const a=/^(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})$/.exec(e);if(a){const[,i,c,o,d,y,h]=a,_=new Date(Date.UTC(Number(i),Number(c)-1,Number(o),Number(d),Number(y),Number(h)));return _.getUTCFullYear()===Number(i)&&_.getUTCMonth()===Number(c)-1&&_.getUTCDate()===Number(o)&&_.getUTCHours()===Number(d)&&_.getUTCMinutes()===Number(y)&&_.getUTCSeconds()===Number(h)?_:null}const n=Date.parse(e);return Number.isNaN(n)?null:new Date(n)}function jo(e,a){const n=xo(e);return n?new Intl.DateTimeFormat(a,{dateStyle:"medium",timeStyle:"short"}).format(n):e}function So({entries:e,onSelect:a,selectedRecordId:n}){const{t:i,locale:c}=re(),[o,d]=r.useState(""),[y,h]=r.useState("all"),[_,N]=r.useState(0),C=r.useMemo(()=>{const w=o.trim().toLocaleLowerCase();return e.filter(T=>(y==="all"||We(T.status)===y)&&(!w||[T.testName,T.status,T.mode,T.recordKind].join(" ").toLocaleLowerCase().includes(w)))},[e,o,y]),j=Math.max(1,Math.ceil(C.length/50)),f=Math.min(_,j-1),$=C.slice(f*50,(f+1)*50);return e.length===0?t.jsx("div",{className:s.emptyState,children:i("playtest.history.empty","No test results yet")}):t.jsxs("div",{className:s.historyBrowser,children:[t.jsxs("div",{className:s.historyToolbar,children:[t.jsxs("label",{children:[t.jsx("span",{children:i("playtest.history.search","Search test results")}),t.jsx("input",{type:"search",value:o,onChange:w=>{d(w.target.value),N(0)}})]}),t.jsxs("label",{children:[t.jsx("span",{children:i("playtest.history.filter","Result")}),t.jsxs("select",{value:y,onChange:w=>{h(w.target.value),N(0)},children:[t.jsx("option",{value:"all",children:i("playtest.history.filterAll","All results")}),t.jsx("option",{value:"passed",children:i("playtest.result.status.passed","Passed")}),t.jsx("option",{value:"failed",children:i("playtest.result.status.failed","Failed")}),t.jsx("option",{value:"insufficient_evidence",children:i("playtest.result.status.insufficientEvidence","Insufficient evidence")}),t.jsx("option",{value:"timed_out",children:i("playtest.result.status.timedOut","Timed out")})]})]})]}),t.jsx("div",{className:s.valueCount,role:"status",children:i("playtest.history.filteredCount","{{visible}} of {{total}} results").replace("{{visible}}",String(C.length)).replace("{{total}}",String(e.length))}),t.jsx("div",{className:s.historyList,children:$.map(w=>{const T=w.recordId===n;return t.jsxs("button",{className:`${s.historyItem} ${T?s.historyItemSelected:""}`,onClick:S=>a(w.recordId,S.currentTarget),"aria-current":T?"true":void 0,"aria-haspopup":"dialog",children:[t.jsxs("div",{className:s.historyItemHeader,children:[t.jsx("span",{className:s.historyIcon,children:vo(w.status)}),t.jsx("span",{className:s.historyTimestamp,children:jo(w.timestamp,c)}),t.jsx("span",{className:s.historyName,children:w.testName}),t.jsx("span",{className:s.recordKind,children:w.recordKind==="structured"?i("playtest.history.kind.structured","Structured"):w.recordKind==="legacy"?i("playtest.history.kind.legacy","Legacy"):i("playtest.history.kind.attention","Needs attention")})]}),t.jsxs("div",{className:s.historyItemMeta,children:[t.jsx(it,{text:i("playtest.history.mode.tooltip","Playtest mode used for this recorded test run."),children:t.jsxs("span",{className:s.historyMode,children:[i("playtest.history.mode","Mode"),": ",go(i,w.mode)]})}),t.jsx("span",{className:s.historyDuration,children:_o(w.durationMs)}),t.jsx(it,{text:i("playtest.history.status.tooltip","Recorded result state for this automated playtest run."),children:t.jsx("span",{className:`${s.historyStatus} ${s[`status_${We(w.status)}`]??""}`,children:bo(i,w.status)})})]}),w.evidenceSummary&&t.jsxs("div",{className:s.historyEvidence,children:[t.jsxs("span",{children:[i("playtest.dimension.server","Server"),": ",Ve(i,w.evidenceSummary.server.status)]}),t.jsxs("span",{children:[i("playtest.dimension.clientUi","Client UI"),": ",Ve(i,w.evidenceSummary.clientUi.status)]}),w.agentCounts&&t.jsx("span",{children:i("playtest.history.agentCounts","Server {server} · Client {client}").replace("{server}",String(w.agentCounts.server)).replace("{client}",String(w.agentCounts.client))})]}),w.errorMessage&&t.jsx("div",{className:s.historyError,children:w.errorMessage}),!w.errorMessage&&w.limitation&&t.jsx("div",{className:s.historyLimitation,children:Ft(i,w.limitation.code,w.limitation.message)})]},w.recordId)})}),j>1&&t.jsxs("div",{className:s.valuePagination,children:[t.jsx("button",{type:"button",disabled:f===0,onClick:()=>N(w=>w-1),children:i("playtest.values.previous","Previous")}),t.jsxs("span",{children:[f+1," / ",j]}),t.jsx("button",{type:"button",disabled:f+1>=j,onClick:()=>N(w=>w+1),children:i("playtest.values.next","Next")})]})]})}function ot({label:e,open:a,onToggle:n,children:i,tooltip:c}){const o=r.useId();return t.jsxs("div",{className:s.artifactDisclosure,children:[t.jsxs("button",{className:s.artifactButton,onClick:n,onKeyDown:d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),n())},"aria-expanded":a,"aria-controls":o,children:[c?t.jsx(it,{text:c,children:t.jsx("span",{children:e})}):t.jsx("span",{children:e}),t.jsx("span",{"aria-hidden":"true",className:`${s.chevron} ${a?s.chevronOpen:""}`,children:"⌄"})]}),a&&t.jsx("div",{className:s.artifactContent,id:o,children:i})]})}function No({detail:e}){const{t:a}=re(),[n,i]=r.useState(()=>new Set(e.recordKind==="legacy"?["report","logs"]:[])),c=y=>i(h=>{const _=new Set(h);return _.has(y)?_.delete(y):_.add(y),_}),o=e.result?{schemaVersion:e.result.schemaVersion,sessionId:e.result.sessionId,recordId:e.result.recordId,startedAt:e.result.startedAt,endedAt:e.result.endedAt,files:e.result.artifacts.files}:null,d=e.artifactErrors??[];return!o&&!e.markdown&&!e.logs&&d.length===0?null:t.jsxs("section",{className:s.viewerSection,"aria-labelledby":"playtest-artifacts-heading",children:[t.jsx("h3",{id:"playtest-artifacts-heading",className:s.viewerHeading,children:a("playtest.artifacts.title","Artifacts")}),t.jsxs("div",{className:s.artifactDisclosures,children:[o&&t.jsx(ot,{label:a("playtest.artifacts.metadata","Result metadata"),open:n.has("metadata"),onToggle:()=>c("metadata"),children:t.jsx("pre",{children:at(o)})}),e.markdown&&t.jsx(ot,{label:a("playtest.report.content","Report"),tooltip:a("playtest.report.content.tooltip","Markdown summary for the selected automated playtest run."),open:n.has("report"),onToggle:()=>c("report"),children:t.jsx("pre",{children:e.markdown})}),e.logs&&t.jsx(ot,{label:a("playtest.report.logs","Logs"),tooltip:a("playtest.report.logs.tooltip","Execution logs captured for the selected automated playtest run."),open:n.has("logs"),onToggle:()=>c("logs"),children:t.jsx("pre",{children:e.logs})})]}),d.map(y=>t.jsx("div",{className:s.stepError,children:y.message},`${y.code}-${y.message}`))]})}function wo({result:e}){const{t:a}=re(),n=[[a("playtest.capability.semanticUi","Semantic UI snapshot"),e.capabilities.semanticUiSnapshot],[a("playtest.capability.virtualInput","Virtual input"),e.capabilities.virtualInput],[a("playtest.capability.fixedBootstrap","Fixed agent bootstrap"),e.capabilities.fixedBootstrap],[a("playtest.capability.projectAdapter","Project test adapter"),e.capabilities.projectTestAdapter]];return t.jsxs("section",{className:s.viewerSection,"aria-labelledby":"playtest-capabilities-heading",children:[t.jsx("h3",{id:"playtest-capabilities-heading",className:s.viewerHeading,children:a("playtest.capability.title","Capabilities and limits")}),t.jsx("div",{className:s.capabilityGrid,children:n.map(([i,c])=>t.jsxs("div",{className:s.capabilityItem,children:[t.jsx("span",{className:c?s.capabilityYes:s.capabilityNo,"aria-hidden":"true",children:c?"✓":"–"}),t.jsx("span",{children:i}),t.jsx("span",{className:s.capabilityState,children:c?a("playtest.capability.available","Available"):a("playtest.capability.unavailable","Unavailable")})]},i))}),e.agents.length>0&&t.jsxs("div",{className:s.agentList,children:[t.jsx("span",{className:s.subsectionLabel,children:a("playtest.agents.title","Test agents")}),e.agents.map((i,c)=>{const o=typeof i.agentId=="string"?i.agentId:`${a("playtest.agents.unknown","Agent")} ${c+1}`,d=typeof i.role=="string"?i.role:"unknown",y=typeof i.clientId=="string"?` · ${i.clientId}`:"";return t.jsxs("code",{children:[o," · ",d,y]},`${o}-${c}`)})]}),e.limitations.length>0&&t.jsxs("div",{className:s.limitations,children:[t.jsx("div",{className:s.subsectionLabel,children:a("playtest.limitations.title","Limitations")}),e.limitations.map(i=>t.jsxs("div",{className:s.limitationItem,children:["! ",Ft(a,i.code,i.message)]},i.code))]})]})}const Co=["server","clientUi","interaction","visual"];function Ro({result:e}){const{t:a}=re(),n={server:a("playtest.dimension.server","Server"),clientUi:a("playtest.dimension.clientUi","Client UI"),interaction:a("playtest.dimension.interaction","Interaction"),visual:a("playtest.dimension.visual","Visual")};return t.jsxs("section",{className:s.viewerSection,"aria-labelledby":"playtest-dimensions-heading",children:[t.jsxs("div",{className:s.sectionHeadingRow,children:[t.jsx("h3",{id:"playtest-dimensions-heading",className:s.viewerHeading,children:a("playtest.dimension.title","Evidence dimensions")}),t.jsx("span",{className:s.sectionHint,children:a("playtest.dimension.hint","Required evidence is marked below.")})]}),t.jsx("div",{className:s.dimensionGrid,children:Co.map(i=>{const c=e.dimensions[i];return t.jsxs("div",{className:s.dimensionCard,children:[t.jsxs("div",{className:s.dimensionHeader,children:[t.jsx("span",{className:`${s.statusMark} ${s[`tone_${c.status}`]??""}`,"aria-hidden":"true",children:gt(c.status)}),t.jsx("span",{className:s.dimensionName,children:n[i]}),t.jsx("span",{className:s.requirementBadge,children:c.required?a("playtest.dimension.required","Required"):a("playtest.dimension.optional","Optional")})]}),t.jsx("div",{className:s.dimensionStatus,children:Ve(a,c.status)}),c.provider&&t.jsx("div",{className:s.dimensionMeta,children:c.provider}),c.reason&&t.jsx("div",{className:s.dimensionMeta,children:Ga(a,c.reason)}),t.jsxs("div",{className:s.dimensionMeta,children:[a("playtest.dimension.steps","Steps"),": ",c.stepIds.length]})]},i)})})]})}function Po({result:e}){const{t:a}=re(),n=r.useId(),[i,c]=r.useState(()=>new Set),o=d=>{c(y=>{const h=new Set(y);return h.has(d)?h.delete(d):h.add(d),h})};return t.jsxs("section",{className:s.viewerSection,"aria-labelledby":`${n}-heading`,children:[t.jsx("h3",{id:`${n}-heading`,className:s.viewerHeading,children:a("playtest.steps.title","Step timeline")}),t.jsx("div",{className:s.stepList,children:e.steps.map(d=>{const y=i.has(d.stepId),h=`${n}-${d.index}-details`,_=d.target.role==="server"?a("playtest.steps.server","Server"):d.target.clientId;return t.jsxs("div",{className:s.stepItem,children:[t.jsxs("button",{className:s.stepDisclosure,onClick:()=>o(d.stepId),onKeyDown:N=>{(N.key==="Enter"||N.key===" ")&&(N.preventDefault(),o(d.stepId))},"aria-expanded":y,"aria-controls":h,children:[t.jsx("span",{className:`${s.statusMark} ${s[`tone_${d.status}`]??""}`,"aria-hidden":"true",children:gt(d.status)}),t.jsx("span",{className:s.stepIndex,children:d.index+1}),t.jsxs("span",{className:s.stepIdentity,children:[t.jsx("span",{className:s.stepName,children:d.stepId}),t.jsxs("span",{className:s.stepMeta,children:[_," · ",d.action," · ",Bt(d.durationMs)]})]}),t.jsx("span",{className:s.stepStatus,children:Ve(a,d.status)}),t.jsx("span",{className:`${s.chevron} ${y?s.chevronOpen:""}`,"aria-hidden":"true",children:"⌄"})]}),y&&t.jsxs("div",{className:s.stepDetails,id:h,role:"region","aria-label":`${d.stepId} ${a("playtest.steps.details","details")}`,children:[d.expected!==void 0&&t.jsxs("div",{className:s.evidenceBlock,children:[t.jsx("div",{className:s.evidenceLabel,children:a("playtest.steps.expected","Expected")}),t.jsx("pre",{children:at(d.expected)})]}),d.observed!==void 0&&t.jsxs("div",{className:s.evidenceBlock,children:[t.jsx("div",{className:s.evidenceLabel,children:a("playtest.steps.observed","Observed")}),t.jsx("pre",{children:at(d.observed)})]}),d.evidence!==void 0&&t.jsxs("div",{className:s.evidenceBlock,children:[t.jsx("div",{className:s.evidenceLabel,children:a("playtest.steps.evidence","Evidence")}),t.jsx("pre",{children:at(d.evidence)})]}),d.error&&t.jsxs("div",{className:s.stepError,children:[t.jsx("strong",{children:d.error.code})," — ",d.error.message]})]})]},d.stepId)})})]})}function ko({report:e}){var i;const{t:a}=re(),n=e.recordKind==="incomplete_structured"?a("playtest.record.incomplete","Structured result is incomplete"):e.recordKind==="corrupt_structured"?a("playtest.record.corrupt","Structured result is damaged"):a("playtest.record.unsupported","Structured result version is unsupported");return t.jsxs("div",{className:s.recordProblem,role:"status",children:[t.jsx("strong",{children:n}),t.jsx("span",{children:((i=e.error)==null?void 0:i.message)??a("playtest.record.unavailable","Result details are unavailable.")})]})}function Ao({report:e}){var c,o,d,y,h,_;const{t:a}=re(),n=!!((c=e.contextSummary)!=null&&c.testScenario||(o=e.contextSummary)!=null&&o.expectedBehavior||(d=e.contextSummary)!=null&&d.observedBehavior),i=e.recordKind==="structured"?e.result:void 0;return t.jsxs("div",{className:s.reportContainer,children:[i&&t.jsxs(t.Fragment,{children:[t.jsxs("section",{className:s.runSummary,"aria-labelledby":"playtest-summary-heading",children:[t.jsxs("div",{className:s.summaryLead,children:[t.jsx("span",{className:`${s.summaryStatusMark} ${s[`tone_${i.overallStatus}`]??""}`,"aria-hidden":"true",children:gt(i.overallStatus)}),t.jsxs("div",{children:[t.jsx("h3",{id:"playtest-summary-heading",className:s.viewerHeading,children:a("playtest.summary.title","Run summary")}),t.jsx("div",{className:s.summaryName,children:i.testName}),t.jsx("div",{className:s.summaryReason,children:i.terminalReason.message})]})]}),t.jsxs("div",{className:s.summaryFacts,children:[t.jsxs("div",{children:[t.jsx("span",{children:a("playtest.summary.status","Status")}),t.jsx("strong",{children:Ve(a,i.overallStatus)})]}),t.jsxs("div",{children:[t.jsx("span",{children:a("playtest.summary.mode","Mode")}),t.jsx("strong",{children:i.mode==="play"?a("playtest.status.mode.play","Play"):a("playtest.status.mode.run","Run")})]}),t.jsxs("div",{children:[t.jsx("span",{children:a("playtest.summary.duration","Duration")}),t.jsx("strong",{children:Bt(i.durationMs)})]}),t.jsxs("div",{children:[t.jsx("span",{children:a("playtest.summary.cleanup","Cleanup")}),t.jsx("strong",{children:Ve(a,i.cleanup.status)})]})]})]}),t.jsx(Ro,{result:i}),t.jsx(Po,{result:i}),t.jsx(wo,{result:i})]}),e.recordKind!=="structured"&&e.recordKind!=="legacy"&&t.jsx(ko,{report:e}),n&&t.jsxs("div",{className:s.reportContextPanel,children:[((y=e.contextSummary)==null?void 0:y.testScenario)&&t.jsxs("div",{className:s.reportContextRow,children:[t.jsx("span",{className:s.reportContextLabel,children:a("playtest.context.why","Why this test ran")}),t.jsx("span",{children:e.contextSummary.testScenario})]}),((h=e.contextSummary)==null?void 0:h.expectedBehavior)&&t.jsxs("div",{className:s.reportContextRow,children:[t.jsx("span",{className:s.reportContextLabel,children:a("playtest.context.expected","Expected")}),t.jsx("span",{children:e.contextSummary.expectedBehavior})]}),((_=e.contextSummary)==null?void 0:_.observedBehavior)&&t.jsxs("div",{className:s.reportContextRow,children:[t.jsx("span",{className:s.reportContextLabel,children:a("playtest.context.observed","Observed")}),t.jsx("span",{children:e.contextSummary.observedBehavior})]})]}),t.jsx(No,{detail:e},e.recordId),!i&&!e.markdown&&!e.logs&&e.recordKind==="legacy"&&t.jsx("div",{className:s.emptyState,children:a("playtest.report.empty","No report content available")})]})}function Pt(e){return typeof e=="number"?{placeId:String(e)}:void 0}const Re={listProfiles:async e=>De.get("/api/dashboard/playtest/control-profiles",Pt(e)),liveStatus:async(e,a)=>De.get("/api/dashboard/playtest/live",{...Pt(e)??{},...a?{leaseId:a}:{}}),liveAction:async e=>De.post("/api/dashboard/playtest/live",e),bindingDraft:async(e,a)=>De.post("/api/dashboard/playtest/binding-draft",{...e,...typeof a=="number"?{placeId:a}:{}}),bindingCandidates:async e=>De.post("/api/dashboard/playtest/binding-candidates",{...typeof e=="number"?{placeId:e}:{}}),saveProfile:async(e,a,n)=>De.put(`/api/dashboard/playtest/control-profiles/${encodeURIComponent(e.id)}`,{profile:e,expectedRevision:a,...typeof n=="number"?{placeId:n}:{}}),saveProfileMetadata:async(e,a,n,i)=>De.patch(`/api/dashboard/playtest/control-profiles/${encodeURIComponent(e)}/metadata`,{expectedRevision:a,...n,...typeof i=="number"?{placeId:i}:{}}),deleteProfile:async(e,a,n)=>{const i=new URLSearchParams({expectedRevision:String(a)});return n.placeId!==void 0&&i.set("placeId",String(n.placeId)),De.delete(`/api/dashboard/playtest/control-profiles/${encodeURIComponent(e)}?${i.toString()}`,n.clientId?{clientId:n.clientId}:void 0)}},Gt="weppy-playtest-workspace-v1",Eo="weppy-playtest-profile-v1:";function Je(){try{return window.localStorage}catch{return null}}function Do(){var e;try{const a=(e=Je())==null?void 0:e.getItem(Gt);return a==="live"||a==="results"?a:"live"}catch{return"live"}}function To(e){var a;try{(a=Je())==null||a.setItem(Gt,e)}catch{}}function bt(e){return`${Eo}${e}`}function Io(e){var a;if(e===null)return null;try{return((a=Je())==null?void 0:a.getItem(bt(e)))||null}catch{return null}}function He(e,a){var n;if(e!==null)try{(n=Je())==null||n.setItem(bt(e),a)}catch{}}function kt(e){var a;if(e!==null)try{(a=Je())==null||a.removeItem(bt(e))}catch{}}const Ye={entries:[],diagnostics:[]},Qe={hasManagedAdapterWithoutStudioGuard:!1};function Xe(e){return typeof e=="object"&&e!==null&&"error"in e&&typeof e.error=="string"?e.error:e instanceof Error?e.message:String(e)}function Lo(e){if(typeof e!="object"||e===null||!("payload"in e))return!1;const a=e.payload;return(a==null?void 0:a.errorCode)==="lease_agents_unavailable"}function Mo(e){const{enabled:a,canMutate:n,placeId:i,studioSnapshot:c}=e,[o,d]=r.useState([]),[y,h]=r.useState(!1),[_,N]=r.useState(null),[C,j]=r.useState(null),[f,$]=r.useState(Ye),[w,T]=r.useState(Qe),[S,F]=r.useState({}),[R,E]=r.useState({}),[K,I]=r.useState({}),[W,Z]=r.useState(!0),[G,O]=r.useState(null),B=r.useRef(null),L=r.useRef(null),X=r.useRef([]),oe=r.useRef(!1),ce=r.useRef(Promise.resolve()),ae=r.useRef(0),me=r.useRef(0),U=r.useRef(null),D=r.useRef(Promise.resolve()),ee=r.useRef(null),Pe=r.useRef(i);Pe.current=i;const[de,fe]=r.useState(0);B.current=C;const pe=r.useMemo(()=>o.find(u=>u.id===_)??null,[o,_]);L.current=pe,X.current=o;const he=r.useCallback(()=>{E(u=>Object.fromEntries(Object.entries(u).map(([b,k])=>{const{observed:v,...A}=k;return[b,{...A,status:"unavailable",fresh:!1,...v!==void 0?{lastObserved:v}:{},reason:"session_ended"}]})))},[]),V=r.useCallback(async()=>{U.current&&(clearTimeout(U.current),U.current=null),me.current=0;const u=B.current;if(u){B.current=null,j(null),F({}),I({}),he();try{await Re.liveAction({action:"close",leaseId:u.leaseId,...typeof i=="number"?{placeId:i}:{}})}catch{}}},[he,i]),te=r.useCallback(async()=>{const u=L.current;if(!(B.current||oe.current)){oe.current=!0;try{const b=await Re.liveAction({action:u?"observe":"discover",...u?{profileId:u.id}:{},...typeof i=="number"?{placeId:i}:{}});B.current=b.lease,j(b.lease),b.lease.catalog&&$(b.lease.catalog),F({});const k=await Re.liveStatus(i,b.lease.leaseId);E(Object.fromEntries(k.watches.map(v=>[v.subscriptionId,v]))),U.current&&clearTimeout(U.current),U.current=null,me.current=0,O(null)}catch(b){if(O(Xe(b)),Lo(b)&&!U.current){const k=me.current;me.current+=1;const v=Math.min(2e3,250*2**Math.min(k,3));U.current=setTimeout(()=>{U.current=null,fe(A=>A+1)},v)}}finally{oe.current=!1}}},[i]);r.useEffect(()=>{a||V()},[V,a]),r.useEffect(()=>()=>{V()},[V]),r.useEffect(()=>{let u=!1;return Z(!0),h(!1),d([]),N(null),ee.current=null,j(null),F({}),E({}),I({}),$(Ye),T(Qe),(async()=>{const k=Re.listProfiles(i).then(v=>{var z,Y;if(u)return;d(v.profiles),ee.current=(z=v.scope)!=null&&z.placeId?{placeId:v.scope.placeId}:v.targetClientId?{clientId:v.targetClientId}:typeof i=="number"?{placeId:i}:null,$(v.catalog??Ye),T(v.releaseGuidance??Qe);const A=Io(i),H=v.profiles.some(m=>m.id===A)?A:((Y=v.profiles[0])==null?void 0:Y.id)??null;N(H),H&&He(i,H),h(!0)}).catch(v=>{u||(O(Xe(v)),h(!0))});try{await k}finally{u||Z(!1)}})(),()=>{u=!0}},[a,i]),r.useEffect(()=>{const u=++ae.current,b=a&&y&&c.targetClientId!==null&&(c.state==="Running"||c.state==="Paused");!b&&U.current&&(clearTimeout(U.current),U.current=null,me.current=0),ce.current=ce.current.catch(()=>{}).then(async()=>{var A;if(u!==ae.current)return;const k=B.current,v=((A=L.current)==null?void 0:A.id)??"__weppy_catalog__";k&&(!b||k.target.clientId!==c.targetClientId||k.profileId!==v)&&await V(),u===ae.current&&b&&!B.current&&await te()})},[V,a,te,de,y,_,c.state,c.mode,c.targetClientId]),r.useEffect(()=>{if(!a)return;const u=new zt,b=u.on("playtest_watch",k=>{var A;const v=k;!(v!=null&&v.subscriptionId)||v.leaseId!==((A=B.current)==null?void 0:A.leaseId)||E(H=>{const z=H[v.subscriptionId];if(z&&v.sequence<=z.sequence&&v.sequence!==0)return H;const m=z&&v.sequence>0&&z.sequence>0&&v.sequence!==z.sequence+1?(()=>{const{observed:J,...l}=v;return{...l,status:"stale",fresh:!1,...J!==void 0?{lastObserved:J}:{},reason:"sequence_gap"}})():v;return{...H,[v.subscriptionId]:m}})});return u.connect(),()=>{b(),u.disconnect()}},[a]);const se=r.useCallback(u=>{B.current||(N(u),He(i,u))},[i]),ne=r.useCallback(async(u,b)=>{const k=B.current;if(!(!k||!n)){F(v=>({...v,[u]:{...v[u],status:"applying",draft:b}}));try{const v=await Re.liveAction({action:"apply",leaseId:k.leaseId,expectedRevision:k.revision,values:{[u]:b},...typeof i=="number"?{placeId:i}:{}}),A=v.result.bindings.find(H=>H.bindingId===u);j(H=>H&&{...H,revision:v.result.revision}),F(H=>{var z,Y;return{...H,[u]:v.result.status==="applied"?{status:"applied",draft:b,requested:(A==null?void 0:A.requested)??b,observed:A==null?void 0:A.observed,original:A==null?void 0:A.original}:{...H[u],status:((z=v.result.error)==null?void 0:z.code)==="requires_adapter"?"requires_adapter":"error",draft:b,message:(Y=v.result.error)==null?void 0:Y.message}}})}catch(v){const A=typeof v=="object"&&v!==null&&"status"in v&&v.status===409;F(H=>({...H,[u]:{...H[u],status:A?"conflict":"error",draft:b,message:Xe(v)}}))}}},[n,i]),ge=r.useCallback(async()=>{const u=B.current;if(!u||!n)return;const b=await Re.liveAction({action:"reset",leaseId:u.leaseId,...typeof i=="number"?{placeId:i}:{}});j(b.lease),F({})},[n,i]),je=r.useCallback(async(u,b,k)=>{const v=B.current,A=L.current;if(!v||!A||!n||c.state!=="Running")return;const H=structuredClone(b);I(z=>({...z,[u]:{status:"running",requestId:k,actionId:u,arguments:H,executedAtMs:Date.now()}}));try{const z=await Re.liveAction({action:"execute_action",leaseId:v.leaseId,profileId:A.id,actionId:u,requestId:k,expectedProfileRevision:A.revision,expectedRevision:v.revision,arguments:H,...typeof i=="number"?{placeId:i}:{}});I(Y=>({...Y,[u]:z.result}))}catch(z){const Y=typeof z=="object"&&z!==null&&"payload"in z?z.payload:void 0,m=(Y==null?void 0:Y.errorCode)==="action_result_unknown"||(Y==null?void 0:Y.errorCode)==="plugin_disconnected"||(Y==null?void 0:Y.errorCode)==="command_timeout";I(J=>({...J,[u]:{status:m?"unknown":"failed",requestId:k,actionId:u,arguments:H,executedAtMs:Date.now(),error:{code:(Y==null?void 0:Y.errorCode)??"action_failed",message:Xe(z)}}}))}},[n,i,c.state]),Se=r.useCallback(async u=>{const b=u.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||`profile-${Date.now()}`,k=await Re.saveProfile({schemaVersion:4,id:b,name:u.trim(),controls:[],watches:[],actions:[],presentation:{},settings:{applyDefaultsOnManualPlayStart:!1,runtimeApplyMode:"manual"},sectionOrder:["watches","controls","actions"]},0,i);return d(v=>[...v,k.profile]),N(k.profile.id),He(i,k.profile.id),k.profile},[i]),ke=r.useCallback(async u=>{const{revision:b,...k}=u,v=await Re.saveProfile(k,b,i);d(A=>A.map(H=>H.id===v.profile.id?v.profile:H))},[i]),be=r.useCallback(async(u,b,k)=>{if(!L.current)throw new Error("Select a test profile before saving a value.");await new Promise((A,H)=>{D.current=D.current.catch(()=>{}).then(async()=>{const z=L.current;if(!z)throw new Error("Select a test profile before saving a value.");const Y=await Re.saveProfileMetadata(z.id,z.revision,{defaults:{[u]:b}},i);L.current=Y.profile,d(m=>m.map(J=>J.id===Y.profile.id?Y.profile:J))}),D.current.then(A,H)})},[i]),_e=r.useCallback(async u=>{await new Promise((b,k)=>{D.current=D.current.catch(()=>{}).then(async()=>{const v=L.current;if(!v)throw new Error("Select a test profile before saving display settings.");const A=await Re.saveProfileMetadata(v.id,v.revision,u,i);L.current=A.profile,d(H=>H.map(z=>z.id===A.profile.id?A.profile:z))}),D.current.then(b,k)})},[i]),xe=r.useCallback(async(u,b)=>{await _e({actionDefaults:{[u]:b}})},[_e]),Ne=r.useCallback(async u=>({path:(await Re.bindingDraft(u,i)).binding.path}),[i]),Ce=r.useCallback(async()=>await Re.bindingCandidates(i),[i]),p=r.useCallback(async(u,b)=>{var z,Y;const k=ee.current,v=i;if(!k)throw Object.assign(new Error("profile_scope_unavailable"),{code:"profile_scope_unavailable"});await Re.deleteProfile(u,b,k);let A;try{A=await Re.listProfiles(v)}catch{if(Pe.current!==v)return{refreshFailed:!0};const m=X.current.filter(l=>l.id!==u),J=((z=m[0])==null?void 0:z.id)??null;return d(m),N(J),J?He(v,J):kt(v),F({}),E({}),I({}),{refreshFailed:!0}}if(Pe.current!==v)return{refreshFailed:!1};d(A.profiles),$(A.catalog??Ye),T(A.releaseGuidance??Qe);const H=((Y=A.profiles[0])==null?void 0:Y.id)??null;return N(H),H?He(v,H):kt(v),F({}),E({}),{refreshFailed:!1}},[i]);return{profiles:o,selectedProfileId:_,profile:pe,catalog:f,releaseGuidance:w,lease:C,controls:S,watches:R,actions:K,studioState:c.state,studioMode:c.mode,canMutate:n,loading:W,error:G,selectProfile:se,apply:ne,executeAction:je,resetAll:ge,createProfile:Se,saveProfile:ke,saveControlValue:be,saveActionDefaults:xe,saveProfileMetadata:_e,resolveSelection:Ne,resolveSelectionCandidates:Ce,deleteProfile:p}}function $o(e){const{t:a}=re(),n=[{key:"live",label:a("playtest.view.liveSession","Test Values")},{key:"results",label:a("playtest.view.testResults","Automated Test Results")}];return t.jsx(ca,{items:n,value:e.value,onChange:e.onChange,ariaLabel:a("playtest.view.workspaceLabel","Playtest workspace"),className:s.workspaceTabs})}function Vo(e){const{t:a}=re(),n=e.studioState==="Running"&&e.studioMode==="run"?a("playtest.session.state.runRunning","Run running"):e.studioState==="Running"&&e.studioMode==="play"?a("playtest.session.state.playRunning","Play running"):a(`playtest.session.state.${e.studioState.toLowerCase()}`,e.studioState),i=e.studioState==="Disconnected"?a("playtest.session.disconnectedDescription","Connect Roblox Studio and WEPPY Plugin to observe Playtest values."):e.studioState==="Edit"?null:e.studioState==="Paused"?a("playtest.session.pausedDescription","Studio Play is paused. Observations remain connected, and Pro value changes stay available."):e.lease?`${e.profileName??e.lease.profileId} · ${e.lease.target.targetAlias??e.lease.target.clientId}`:a("playtest.session.connectingDescription","Studio is playing. Connecting runtime observations…");return t.jsx("section",{className:s.sessionBar,"aria-label":a("playtest.session.label","Playtest session"),children:t.jsxs("div",{className:s.sessionIdentity,children:[t.jsx(ba,{size:16,"aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("strong",{children:n}),i&&t.jsx("span",{children:i})]})]})})}function Oe(e){const{t:a}=re(),[n,i]=r.useState(!1),c=r.useRef(null),o=r.useRef(null),d=r.useRef(null),[y,h]=r.useState({top:0,left:0});return r.useLayoutEffect(()=>{var w;if(!n||e.active||!o.current||!d.current)return;const N=(((w=c.current)==null?void 0:w.querySelector("input, select, button"))??o.current).getBoundingClientRect(),C=d.current.getBoundingClientRect(),j=N.top-C.height-6,f=N.bottom+6,$=j<8&&f+C.height<=window.innerHeight-8?f:j;h({top:Math.max(8,Math.min($,window.innerHeight-C.height-8)),left:Math.max(8,Math.min(N.left+N.width/2-C.width/2,window.innerWidth-C.width-8))})},[n,e.active,e.reason]),r.useEffect(()=>{if(!n)return;const _=()=>i(!1);return window.addEventListener("scroll",_,!0),window.addEventListener("resize",_),()=>{window.removeEventListener("scroll",_,!0),window.removeEventListener("resize",_)}},[n]),t.jsxs("div",{ref:c,className:s.controlGate,children:[e.children,!e.active&&t.jsxs(t.Fragment,{children:[t.jsx("button",{ref:o,type:"button",className:s.controlGateTrigger,"aria-label":a("playtest.controls.lockedHelp","Why is {{label}} unavailable?").replace("{{label}}",e.label),"aria-describedby":"playtest-controls-availability","aria-expanded":n,onClick:()=>i(!0),onFocus:()=>i(!0),onBlur:()=>i(!1),onKeyDown:_=>{_.key==="Escape"&&i(!1)}}),n&&Wt.createPortal(t.jsx("span",{ref:d,className:s.controlGateHint,style:y,role:"status",children:e.reason}),document.body)]})]})}function _t(e){var a,n,i;return t.jsx(Ke,{open:e.open,ariaLabel:e.ariaLabel,onClose:e.onClose,returnFocusTo:e.returnFocusTo,testId:"playtest-value-detail-layer",children:t.jsxs("div",{className:s.valueDetailShell,children:[t.jsx(ze,{title:e.title,description:e.description,closeLabel:e.closeLabel,onRequestClose:e.onClose}),t.jsxs("div",{className:s.valueDetailBody,children:[t.jsx("dl",{className:s.valueDetailList,children:e.items.map(c=>t.jsxs("div",{children:[t.jsx("dt",{children:c.label}),t.jsx("dd",{children:c.value})]},c.label))}),t.jsx("div",{className:s.valueDetailFeedback,"data-state":e.error?"error":((a=e.feedback)==null?void 0:a.state)??"idle",role:e.error||((n=e.feedback)==null?void 0:n.state)==="error"?"alert":"status","aria-live":"polite",children:e.error??((i=e.feedback)==null?void 0:i.message)??" "}),e.actions&&e.actions.length>0&&t.jsx("div",{className:s.valueDetailActions,children:e.actions.map(c=>{var o,d,y;return t.jsx(Oe,{active:((o=c.gate)==null?void 0:o.active)??!0,label:((d=c.gate)==null?void 0:d.label)??c.label,reason:((y=c.gate)==null?void 0:y.reason)??"",children:t.jsx("button",{type:"button",className:c.variant==="secondary"?s.secondaryAction:s.primaryAction,"aria-label":c.accessibleLabel,disabled:c.disabled,onClick:c.onClick,children:c.label})},c.accessibleLabel)})})]})]})})}function Ge(e){return e==="vector3"||e==="color3"||e==="cframe"}function Ht(e){return e==="vector3"?["x","y","z"]:e==="color3"?["r","g","b"]:["X","Y","Z","R00","R01","R02","R10","R11","R12","R20","R21","R22"]}function xt(e,a){try{const n=JSON.parse(a),i=Ht(e);if(e==="cframe"?!Array.isArray(n)||n.length!==12:!n||Array.isArray(n)||typeof n!="object"||Object.keys(n).length!==3)return;const c=i.map((o,d)=>e==="cframe"?n[d]:n[o]);if(!c.every(o=>typeof o=="number"&&Number.isFinite(o))||e==="color3"&&c.some(o=>o<0||o>1))return;if(e==="cframe"){const o=c,d=(h,_)=>o[h]*o[_]+o[h+1]*o[_+1]+o[h+2]*o[_+2],y=o[3]*(o[7]*o[11]-o[8]*o[10])-o[4]*(o[6]*o[11]-o[8]*o[9])+o[5]*(o[6]*o[10]-o[7]*o[9]);if([3,6,9].some(h=>Math.abs(d(h,h)-1)>1e-5)||[[3,6],[3,9],[6,9]].some(([h,_])=>Math.abs(d(h,_))>1e-5)||Math.abs(y-1)>1e-5)return}return n}catch{return}}function st(e){if(e===void 0)return"—";if(typeof e=="string")return e.replace(/^Enum\.[^.]+\./,"");if(e&&typeof e=="object"&&!Array.isArray(e)){const a="x"in e?["x","y","z"]:"r"in e?["r","g","b"]:[];if(a.length===3&&a.every(n=>typeof e[n]=="number"))return a.map(n=>`${n.toUpperCase()} ${Number(e[n].toPrecision(6))}`).join(" · ")}return JSON.stringify(e)}function yt(e){const a=r.useRef(!1),n=Ht(e.type);let i={};try{i=JSON.parse(e.draft)??{}}catch{}const c=n.map((h,_)=>{const N=e.type==="cframe"?i[_]:i[h];return N==null?"":String(N)}),o=(h,_)=>{const C=c.map((j,f)=>f===h?_:j).map(j=>j.trim()!==""&&!/[.eE+-]$/.test(j)&&Number.isFinite(Number(j))?Number(j):j);e.onChange(JSON.stringify(e.type==="cframe"?C:Object.fromEntries(n.map((j,f)=>[j,C[f]]))))},d=xt(e.type,e.draft),y=d&&!Array.isArray(d)&&typeof d=="object"?`#${["r","g","b"].map(h=>Math.round(Number(d[h])*255).toString(16).padStart(2,"0")).join("")}`:"#000000";return t.jsxs("div",{className:s.compoundEditor,role:"group","aria-label":e.label,onFocus:()=>{var h;return(h=e.onFocusChange)==null?void 0:h.call(e,!0)},onBlur:h=>{var _,N;h.currentTarget.contains(h.relatedTarget)||((_=e.onFocusChange)==null||_.call(e,!1),a.current||(N=e.onCommit)==null||N.call(e))},onCompositionStart:()=>{a.current=!0},onCompositionEnd:()=>{a.current=!1},onKeyDown:h=>{var _;h.key==="Enter"&&!h.nativeEvent.isComposing&&!a.current&&((_=e.onCommit)==null||_.call(e))},children:[e.type==="color3"&&t.jsx("input",{className:s.colorSwatch,type:"color",value:y,disabled:e.disabled,"aria-label":`${e.label} RGB`,"aria-describedby":e.describedBy,onChange:h=>{const _=h.target.value.slice(1);e.onChange(JSON.stringify({r:parseInt(_.slice(0,2),16)/255,g:parseInt(_.slice(2,4),16)/255,b:parseInt(_.slice(4,6),16)/255}))}}),t.jsx("div",{className:s.compoundCoordinates,children:n.map((h,_)=>t.jsxs("label",{children:[t.jsxs("span",{children:[h.toUpperCase(),e.type==="color3"?" (0–1)":""]}),t.jsx("input",{inputMode:"decimal",value:c[_],disabled:e.disabled,"aria-label":`${e.label} ${h.toUpperCase()}`,"aria-describedby":e.describedBy,"aria-invalid":e.draft!==""&&d===void 0||void 0,onChange:N=>o(_,N.target.value)})]},h))})]})}function Ae(e){return e===void 0?"—":typeof e=="string"?e:JSON.stringify(e)}function Oo(e,a,n){const i=n!=null&&n.fresh?n.observed:n==null?void 0:n.lastObserved,c=(a==null?void 0:a.draft)??i??e.value;return c===void 0?"":Ae(c)}function qe(e,a){var n;if(Ge(e.valueType))return xt(e.valueType,a);if(e.valueType==="number"){if(a.trim()==="")return;const i=Number(a);return Number.isFinite(i)?i:void 0}return e.valueType==="boolean"?a==="true":e.valueType==="enum"?((n=e.enumValues)==null?void 0:n.find(i=>Ae(i)===a))??a:a}function Be(e){return e&&typeof e=="object"&&!Array.isArray(e)?`object:${Object.keys(e).sort().map(a=>`${JSON.stringify(a)}:${Be(e[a])}`).join(",")}`:`${typeof e}:${JSON.stringify(e)}`}function Ue(e){var a;return e.value!==void 0?Ae(e.value):e.valueType==="boolean"?"false":e.valueType==="enum"?Ae((a=e.enumValues)==null?void 0:a[0]):""}function Bo(e){var i;const{t:a}=re();if(!e.profile||e.profile.controls.length===0)return t.jsx("div",{className:s.panelEmpty,children:a("playtest.controls.empty","No test controls in this profile yet.")});const n=((i=e.profile.settings)==null?void 0:i.runtimeApplyMode)??"manual";return t.jsx("div",{className:s.liveRows,children:e.profile.controls.map(c=>{var o,d,y;return t.jsx(Fo,{control:c,active:e.active,inactiveReason:e.inactiveReason,profileSaveLocked:e.profileSaveLocked,runtimeApplyMode:n,state:e.states[c.id],watch:e.watches[`control:${c.id}`],presentation:(d=(o=e.profile)==null?void 0:o.presentation)==null?void 0:d[c.id],draftState:(y=e.drafts)==null?void 0:y[c.id],onDraftChange:e.onDraftChange,onApply:e.onApply,onSaveValue:e.onSaveValue,onRemoveValue:e.onRemoveValue},`${e.draftScope??"profile"}:${c.id}`)})})}function Fo(e){var ge,je,Se,ke,be,_e,xe,Ne,Ce,p,u,b,k,v,A,H,z,Y,m,J,l;const{t:a}=re(),n=Oo(e.control,e.state,e.watch),[i,c]=r.useState(n),[o,d]=r.useState(!1),[y,h]=r.useState("idle"),[_,N]=r.useState(null),[C,j]=r.useState(()=>Ue(e.control)),[f,$]=r.useState(e.control.value),[w,T]=r.useState(null),[S,F]=r.useState(!1),R=r.useRef(null),E=r.useRef(!1),K=r.useRef(!1),I=r.useRef(null),W=((ge=e.draftState)==null?void 0:ge.value)??i,Z=((je=e.draftState)==null?void 0:je.dirty)??o;r.useEffect(()=>{c(n),d(!1),j(Ue(e.control)),$(e.control.value),T(null),N(null),I.current=null},[e.control.id]),r.useEffect(()=>{j(Ue(e.control)),$(e.control.value)},[e.control.value]),r.useEffect(()=>{!e.draftState&&!Z&&!E.current&&c(n)},[Z,n,e.draftState]),r.useEffect(()=>{var g,x,q;(((g=e.state)==null?void 0:g.status)==="error"||((x=e.state)==null?void 0:x.status)==="conflict"||((q=e.state)==null?void 0:q.status)==="requires_adapter")&&(I.current=null)},[(Se=e.state)==null?void 0:Se.status]);const G=()=>qe(e.control,W),O=g=>{if(!e.active||K.current)return;const x=g??G();if(x===void 0)return;const q=Be(x);I.current!==q&&(I.current=q,e.onApply(e.control.id,x))},B=g=>{var q;c(g),d(!0),(q=e.onDraftChange)==null||q.call(e,e.control.id,g,!0);const x=qe(e.control,g);(x===void 0||Be(x)!==I.current)&&(I.current=null)},L=async()=>{const g=qe(e.control,C);if(!(g===void 0||!e.onSaveValue||e.profileSaveLocked||y!=="idle")){h("saving"),N(null),T(null);try{await e.onSaveValue(e.control.id,g,e.control.applyOnStart??!1),$(g),T({state:"saved",value:Ae(g)})}catch(x){N(x instanceof Error?x.message:String(x))}finally{h("idle")}}},X=async()=>{if(!(f===void 0||!e.onRemoveValue||e.profileSaveLocked||y!=="idle")){h("removing"),N(null),T(null);try{await e.onRemoveValue(e.control.id),j(Ue({...e.control,value:void 0})),$(void 0),T({state:"removed"})}catch(g){N(g instanceof Error?g.message:String(g))}finally{h("idle")}}},oe=a("playtest.controls.inputLabel","Input value for {{label}}").replace("{{label}}",e.control.label),ce=e.active?void 0:"playtest-controls-availability",ae=e.inactiveReason??a("playtest.values.playRequired","Start Play in Studio to change test values."),me=e.control.valueType==="number"&&((ke=e.control.constraints)==null?void 0:ke.minimum)!==void 0&&((be=e.control.constraints)==null?void 0:be.maximum)!==void 0,U=(_e=e.watch)!=null&&_e.fresh?e.watch.observed:(xe=e.watch)==null?void 0:xe.lastObserved,D=(Ne=e.watch)!=null&&Ne.fresh?a("playtest.controls.currentObserved","Current value"):U!==void 0?a("playtest.watch.lastObserved","Last observed"):a("playtest.watch.notObserved","Not observed yet"),ee=((Ce=e.state)==null?void 0:Ce.status)??"idle",Pe=e.control.origin?`ServerStorage.WeppyTestAdapters.${e.control.origin.adapter}`:e.control.path?[e.control.path.root,...e.control.path.segments].join("."):"adapter",de=e.runtimeApplyMode==="auto",fe=G(),pe=ee==="applying"||ee==="pending_resume",he=!de&&e.active&&Z&&fe!==void 0&&U!==void 0&&Be(fe)!==Be(U)&&Be(fe)!==I.current&&!pe,V=f===void 0?a("playtest.controls.noSavedValue","No saved default"):Ae(f),te=a("playtest.controls.defaultInputLabel","Saved default for {{label}}").replace("{{label}}",e.control.label);let se;Ge(e.control.valueType)?se=t.jsx(yt,{type:e.control.valueType,draft:W,label:oe,disabled:!e.active,describedBy:ce,onChange:B,onFocusChange:g=>{E.current=g},onCommit:()=>{de&&O()}}):e.control.valueType==="boolean"?se=t.jsxs("label",{className:s.booleanEditor,children:[t.jsx("input",{type:"checkbox",checked:W==="true",disabled:!e.active,"aria-label":oe,"aria-describedby":ce,onFocus:()=>{E.current=!0},onBlur:()=>{E.current=!1},onChange:g=>{const x=g.target.checked;B(String(x)),de&&O(x)}}),t.jsx("span",{children:W==="true"?a("common.true","True"):a("common.false","False")})]}):e.control.valueType==="enum"?se=t.jsx("select",{"aria-label":oe,"aria-describedby":ce,value:W,disabled:!e.active,onFocus:()=>{E.current=!0},onBlur:()=>{E.current=!1},onChange:g=>{B(g.target.value);const x=qe(e.control,g.target.value);de&&x!==void 0&&O(x)},children:(e.control.enumValues??[]).map(g=>t.jsx("option",{value:Ae(g),children:st(g)},Ae(g)))}):me?se=t.jsxs("div",{className:s.rangeEditor,children:[t.jsx("input",{type:"range",value:W||String(((p=e.control.constraints)==null?void 0:p.minimum)??0),min:(u=e.control.constraints)==null?void 0:u.minimum,max:(b=e.control.constraints)==null?void 0:b.maximum,step:((k=e.control.constraints)==null?void 0:k.step)??1,disabled:!e.active,"aria-label":oe,"aria-describedby":ce,onFocus:()=>{E.current=!0},onBlur:()=>{E.current=!1},onChange:g=>B(g.target.value),onPointerUp:()=>{de&&O()},onKeyUp:g=>{de&&(g.key.startsWith("Arrow")||g.key==="Home"||g.key==="End")&&O()}}),t.jsx("output",{children:W||"—"})]}):se=t.jsx("input",{value:W,disabled:!e.active,inputMode:e.control.valueType==="number"?"decimal":void 0,onFocus:()=>{E.current=!0},onChange:g=>B(g.target.value),onCompositionStart:()=>{K.current=!0},onCompositionEnd:()=>{K.current=!1},onKeyDown:g=>{de&&g.key==="Enter"&&!g.nativeEvent.isComposing&&O()},onBlur:()=>{E.current=!1,de&&O()},"aria-label":oe,"aria-describedby":ce});let ne;return Ge(e.control.valueType)?ne=t.jsx(yt,{type:e.control.valueType,draft:C,label:te,disabled:!e.onSaveValue||e.profileSaveLocked||y!=="idle",onChange:g=>{j(g),T(null),N(null)}}):e.control.valueType==="boolean"?ne=t.jsxs("label",{className:s.defaultBooleanEditor,children:[t.jsx("input",{type:"checkbox",checked:C==="true",disabled:!e.onSaveValue||e.profileSaveLocked||y!=="idle","aria-label":te,onChange:g=>{j(String(g.target.checked)),T(null),N(null)}}),t.jsx("span",{children:C==="true"?a("common.true","True"):a("common.false","False")})]}):e.control.valueType==="enum"?ne=t.jsx("select",{value:C,disabled:!e.onSaveValue||e.profileSaveLocked||y!=="idle","aria-label":te,onChange:g=>{j(g.target.value),T(null),N(null)},children:(e.control.enumValues??[]).map(g=>t.jsx("option",{value:Ae(g),children:st(g)},Ae(g)))}):ne=t.jsx("input",{type:e.control.valueType==="number"?"number":"text",value:C,min:(v=e.control.constraints)==null?void 0:v.minimum,max:(A=e.control.constraints)==null?void 0:A.maximum,step:(H=e.control.constraints)==null?void 0:H.step,disabled:!e.onSaveValue||e.profileSaveLocked||y!=="idle","aria-label":te,onChange:g=>{j(g.target.value),T(null),N(null)}}),t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:s.controlRow,children:[t.jsxs("div",{className:s.rowIdentity,children:[t.jsx("strong",{children:e.control.label}),(((z=e.presentation)==null?void 0:z.pinned)||((Y=e.presentation)==null?void 0:Y.group))&&t.jsxs("span",{className:s.presentationMeta,children:[e.presentation.pinned?a("playtest.values.pinned","Pinned"):"",e.presentation.pinned&&e.presentation.group?" · ":"",e.presentation.group??""]}),t.jsx("button",{ref:R,type:"button",className:s.valueDetailButton,"aria-label":a("playtest.values.detailsFor","Value details for {{label}}").replace("{{label}}",e.control.label),onClick:()=>{j(Ue({...e.control,value:f})),T(null),N(null),F(!0)},children:a("playtest.values.viewDetails","View details")})]}),t.jsxs("div",{className:s.actualValue,"aria-label":`${D} ${Ae(U)}`,children:[t.jsx("span",{children:D}),t.jsx("strong",{children:st(U)})]}),t.jsxs("div",{className:s.controlEditor,children:[t.jsxs("div",{className:s.editorHeading,children:[t.jsx("span",{className:s.editorLabel,children:a("playtest.controls.inputValue","Input value")}),t.jsxs("span",{className:s.savedValueState,title:V,"aria-label":a("playtest.controls.savedDefaultState","Saved default for {{label}}: {{value}}").replace("{{label}}",e.control.label).replace("{{value}}",V),children:[a("playtest.controls.defaultValue","Saved default")," ",t.jsx("strong",{children:V})]})]}),t.jsxs("div",{className:s.controlEditorRow,children:[t.jsx(Oe,{active:e.active,label:`${e.control.label} input`,reason:ae,children:se}),t.jsx("div",{className:s.controlActions,children:t.jsx(Oe,{active:e.active,label:`${e.control.label} apply`,reason:ae,children:t.jsx("button",{type:"button",className:s.secondaryAction,disabled:!he,"aria-label":a("playtest.controls.applyLabel","Apply the input value for {{label}}").replace("{{label}}",e.control.label),onClick:()=>O(),children:a("playtest.controls.applyRuntime","Apply manually")})})})]}),t.jsx("span",{className:s.rowFeedback,"data-state":_?"error":ee,"aria-live":"polite",children:_??(ee==="applying"?a("playtest.controls.applying","Applying…"):ee==="pending_resume"?a("playtest.controls.pendingResume","Apply on resume"):ee==="applied"?a("playtest.controls.applied","Applied · readback {{value}}").replace("{{value}}",Ae((m=e.state)==null?void 0:m.observed)):ee==="conflict"?a("playtest.controls.conflict","Conflict · reload the current revision"):ee==="requires_adapter"?a("playtest.controls.requiresAdapter","Requires reviewed adapter"):ee==="error"?((J=e.state)==null?void 0:J.message)??a("playtest.controls.applyFailed","Apply failed"):e.active?de?a("playtest.controls.autoApplyReady","Changes apply automatically when the input is confirmed"):a("playtest.controls.readyToApply","Input value is ready to apply or save as the default"):" ")})]})]}),t.jsx(_t,{open:S,title:e.control.label,description:a("playtest.controls.details","Value details"),ariaLabel:a("playtest.values.detailsDialog","{{label}} value details").replace("{{label}}",e.control.label),closeLabel:a("common.close","Close"),returnFocusTo:R.current,onClose:()=>F(!1),items:[{label:D,value:Ae(U)},{label:a("playtest.controls.defaultValue","Saved default"),value:t.jsx("div",{className:s.defaultValueEditor,children:ne})},{label:a("playtest.controls.originalValue","Original runtime value"),value:Ae((l=e.state)==null?void 0:l.original)},{label:a("playtest.controls.registration","Registration"),value:`${e.control.target.role} · ${e.control.access.kind}`},{label:a("playtest.values.location","Location"),value:Pe},{label:a("playtest.values.valueType","Value type"),value:e.control.valueType}],error:_,feedback:(w==null?void 0:w.state)==="saved"?{state:"success",message:a("playtest.controls.defaultSavedFeedback","Saved default {{value}} · Saved").replace("{{value}}",w.value??"")}:(w==null?void 0:w.state)==="removed"?{state:"success",message:a("playtest.controls.defaultRemovedFeedback","No saved default · Removed")}:null,actions:[{label:y==="removing"?a("playtest.controls.removingDefault","Removing…"):a("playtest.controls.removeDefault","Remove default"),accessibleLabel:a("playtest.controls.removeDefaultLabel","Remove saved default for {{label}}").replace("{{label}}",e.control.label),disabled:f===void 0||!e.onRemoveValue||e.profileSaveLocked||y!=="idle",variant:"secondary",onClick:()=>void X()},{label:y==="saving"?a("playtest.profile.saving","Saving…"):a("playtest.controls.saveDefault","Save default"),accessibleLabel:a("playtest.controls.saveLabel","Save default for {{label}}").replace("{{label}}",e.control.label),disabled:!e.onSaveValue||e.profileSaveLocked||y!=="idle"||qe(e.control,C)===void 0,onClick:()=>void L()}]})]})}function Ze(e){return e===void 0?"—":typeof e=="string"?e:JSON.stringify(e)}function Go(e){var N;const{t:a}=re(),n=[...((N=e.profile)==null?void 0:N.watches.map(C=>({...C,subscriptionId:`watch:${C.id}`})))??[]],[i,c]=r.useState(null),o=r.useRef(null);if(n.length===0)return t.jsx("div",{className:s.panelEmpty,children:a("playtest.watch.empty","Observed values appear here during Play.")});const d=n.find(C=>C.id===i),y=d?e.watches[d.subscriptionId]:void 0,h=y!=null&&y.fresh?y.observed:y==null?void 0:y.lastObserved,_=d!=null&&d.path?[d.path.root,...d.path.segments].join("."):(d==null?void 0:d.access.adapter)??"adapter";return t.jsxs(t.Fragment,{children:[t.jsx("div",{className:s.watchRows,children:n.map(C=>{var T,S;const j=e.watches[C.subscriptionId],f=(S=(T=e.profile)==null?void 0:T.presentation)==null?void 0:S[C.id],$=j!=null&&j.fresh?j.observed:j==null?void 0:j.lastObserved,w=j!=null&&j.fresh?a("playtest.watch.currentValue","Current value"):$!==void 0?a("playtest.watch.lastObserved","Last observed"):a("playtest.watch.notObserved","Not observed yet");return t.jsxs("div",{className:s.watchRow,"data-value-type":C.valueType,children:[t.jsxs("div",{className:s.watchCardMain,children:[t.jsx("strong",{children:C.label}),((f==null?void 0:f.pinned)||(f==null?void 0:f.group))&&t.jsxs("span",{className:s.presentationMeta,children:[f.pinned?a("playtest.values.pinned","Pinned"):"",f.pinned&&f.group?" · ":"",f.group??""]}),t.jsx("button",{type:"button",className:s.valueDetailButton,"aria-label":a("playtest.values.detailsFor","Value details for {{label}}").replace("{{label}}",C.label),onClick:F=>{o.current=F.currentTarget,c(C.id)},children:a("playtest.values.viewDetails","View details")})]}),t.jsxs("div",{className:s.watchReading,children:[!(j!=null&&j.fresh)&&t.jsx("span",{children:w}),t.jsx("strong",{title:Ze($),"aria-label":`${w} ${Ze($)}`,children:Ze($)})]}),j&&j.status!=="fresh"&&t.jsx("span",{className:s.freshness,"data-status":j.status,children:(j==null?void 0:j.status)==="stale"?a("playtest.watch.stale","Stale"):a("playtest.watch.unavailable","Unavailable")})]},C.subscriptionId)})}),d&&t.jsx(_t,{open:i!==null,title:d.label,description:a("playtest.watch.details","Observation details"),ariaLabel:a("playtest.values.detailsDialog","{{label}} value details").replace("{{label}}",d.label),closeLabel:a("common.close","Close"),returnFocusTo:o.current,onClose:()=>c(null),items:[{label:a("playtest.watch.registration","Registration"),value:`${d.target.role} · ${d.access.kind}`},{label:a("playtest.values.location","Location"),value:_},{label:a("playtest.values.valueType","Value type"),value:d.valueType},{label:y!=null&&y.fresh?a("playtest.watch.currentValue","Current value"):h!==void 0?a("playtest.watch.lastObserved","Last observed"):a("playtest.watch.notObserved","Not observed yet"),value:Ze(h)},...y!=null&&y.observedAtMs?[{label:a("playtest.watch.observedAt","Observed at"),value:t.jsx("time",{children:new Date(y.observedAtMs).toLocaleTimeString()})}]:[]]})]})}function nt(e,a){return Object.prototype.hasOwnProperty.call(e,a)}function Ho(e,a){var n;if(e.type==="string")return typeof a=="string"?a:void 0;if(e.type==="boolean")return typeof a=="boolean"?a:void 0;if(e.type==="number"||e.type==="integer"){const i=typeof a=="number"?a:typeof a=="string"&&a.trim()!==""?Number(a):NaN;return Number.isFinite(i)?i:void 0}return(n=e.enumValues)==null?void 0:n.find(i=>i===a)}function qo(e,a){if(e.type==="integer"&&!Number.isInteger(a))return"Enter a whole number.";if(typeof a=="number"){if(e.minimum!==void 0&&a<e.minimum)return`Enter ${e.minimum} or more.`;if(e.maximum!==void 0&&a>e.maximum)return`Enter ${e.maximum} or less.`}if(typeof a=="string"){if(e.minLength!==void 0&&a.length<e.minLength)return`Enter at least ${e.minLength} characters.`;if(e.maxLength!==void 0&&a.length>e.maxLength)return`Enter no more than ${e.maxLength} characters.`}return null}function qt(e){return Object.fromEntries(e.parameters.map(a=>[a.name,e.defaultArguments&&nt(e.defaultArguments,a.name)?e.defaultArguments[a.name]:a.defaultValue]))}function At(e,a){const n={},i=new Set(e.parameters.map(o=>o.name));for(const o of Object.keys(a))nt(e.fixedArguments,o)?n[o]="This argument is fixed and cannot be changed.":i.has(o)||(n[o]="This argument is not declared.");const c=structuredClone(e.fixedArguments);for(const o of[...e.parameters].sort((d,y)=>d.order-y.order)){const d=nt(a,o.name)?a[o.name]:e.defaultArguments&&nt(e.defaultArguments,o.name)?e.defaultArguments[o.name]:o.defaultValue;if(d===void 0){o.required&&(n[o.name]="This value is required.");continue}const y=Ho(o,d);if(y===void 0){n[o.name]=o.type==="enum"?"Choose one of the available values.":"Enter a valid value.";continue}const h=qo(o,y);h?n[o.name]=h:c[o.name]=y}return Object.keys(n).length>0?{ok:!1,errors:n}:{ok:!0,arguments:c}}function Et(e){const{t:a}=re();return t.jsx("div",{className:s.actionParameterGrid,children:[...e.action.parameters].sort((n,i)=>n.order-i.order).map(n=>{var h,_;const i=(h=e.errors)==null?void 0:h[n.name],c=`playtest-action-${e.action.id}-${n.name}-error`,o=e.draft[n.name],d=`${n.label}${n.unit?` (${n.unit})`:""}`;let y;if(n.type==="boolean")y=t.jsx("input",{type:"checkbox","aria-label":d,checked:o===!0,disabled:e.disabled,"aria-invalid":!!i,"aria-describedby":i?c:void 0,onChange:N=>e.onChange(n.name,N.target.checked)});else if(n.type==="enum"){const N=((_=n.enumValues)==null?void 0:_.findIndex(C=>C===o))??-1;y=t.jsxs("select",{"aria-label":d,value:N<0?"":String(N),disabled:e.disabled,"aria-invalid":!!i,"aria-describedby":i?c:void 0,onChange:C=>{var f;const j=Number(C.target.value);e.onChange(n.name,Number.isInteger(j)?(f=n.enumValues)==null?void 0:f[j]:void 0)},children:[t.jsx("option",{value:"",children:n.required?a("playtest.actions.chooseValue","Choose a value"):a("playtest.actions.omitValue","Do not use")}),(n.enumValues??[]).map((C,j)=>t.jsx("option",{value:j,children:String(C)},`${j}:${String(C)}`))]})}else y=t.jsx("input",{type:n.type==="string"?"text":"number",inputMode:n.type==="string"?void 0:"decimal",step:n.type==="integer"?1:"any",min:n.minimum,max:n.maximum,minLength:n.minLength,maxLength:n.maxLength,"aria-label":d,"aria-invalid":!!i,"aria-describedby":i?c:void 0,disabled:e.disabled,value:typeof o=="string"||typeof o=="number"?String(o):"",onChange:N=>e.onChange(n.name,N.target.value)});return t.jsxs("label",{className:s.actionParameter,children:[t.jsxs("span",{children:[d,n.required?" *":""]}),y,n.description&&t.jsx("small",{children:n.description}),i&&t.jsx("small",{id:c,className:s.actionParameterError,role:"alert",children:i})]},n.name)})})}function ct(e){return e===void 0?"—":typeof e=="string"?e:JSON.stringify(e)}function Uo(e){var R,E,K,I,W,Z;const{t:a}=re(),[n,i]=r.useState(!1),[c,o]=r.useState({}),d=r.useRef(null),y=e.draft??qt(e.action),h=r.useMemo(()=>[...e.action.parameters].sort((G,O)=>G.order-O.order),[e.action.parameters]),_=At(e.action,y),N=((R=e.state)==null?void 0:R.status)??"idle",C=N==="running",j=e.inactiveReason??a("playtest.actions.playRequired","Start Studio Play before running this action."),f=h.length===0?a("playtest.actions.noParameters","No input required"):h.map(G=>`${G.label}: ${ct(y[G.name])}`).join(" · "),$=Object.entries(e.action.fixedArguments).map(([G,O])=>`${G}: ${ct(O)}`).join(" · "),w=N==="running"?a("playtest.actions.running","Running…"):N==="succeeded"?a("playtest.actions.succeeded","Succeeded"):N==="failed"?((K=(E=e.state)==null?void 0:E.error)==null?void 0:K.message)??a("playtest.actions.failed","Failed"):N==="unknown"?a("playtest.actions.unknown","Result unknown"):" ",T=(G,O)=>{const B={...y,[G]:O};o(L=>{const X={...L};return delete X[G],X}),e.onDraftChange(e.action.id,B)},S=()=>{const G=At(e.action,y);if(!G.ok){o(G.errors);return}e.onExecute(e.action.id,structuredClone(G.arguments))},F=()=>{if(!_.ok){o(_.errors);return}const G=new Set(e.action.parameters.map(O=>O.name));e.onSaveDefaults(e.action.id,Object.fromEntries(Object.entries(_.arguments).filter(([O])=>G.has(O))))};return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:s.actionRow,"data-state":N,children:[t.jsxs("div",{className:s.rowIdentity,children:[t.jsx("strong",{children:e.action.label}),e.action.description&&t.jsx("span",{children:e.action.description}),(((I=e.presentation)==null?void 0:I.pinned)||((W=e.presentation)==null?void 0:W.group))&&t.jsxs("span",{className:s.presentationMeta,children:[e.presentation.pinned?a("playtest.values.pinned","Pinned"):"",e.presentation.pinned&&e.presentation.group?" · ":"",e.presentation.group??""]}),h.length>1&&t.jsx("button",{ref:d,type:"button",className:s.valueDetailButton,"aria-label":a("playtest.actions.settingsFor","Execution settings for {{label}}").replace("{{label}}",e.action.label),onClick:()=>i(!0),children:a("playtest.actions.settings","Execution settings")})]}),t.jsxs("div",{className:s.actionSummary,children:[t.jsx("span",{children:a("playtest.actions.parameters","Parameters")}),t.jsx("strong",{children:f})]}),t.jsxs("div",{className:s.actionExecution,children:[h.length===1&&t.jsx(Et,{action:e.action,draft:y,errors:c,disabled:C,onChange:T}),t.jsx(Oe,{active:e.active,label:e.action.label,reason:j,children:t.jsx("button",{type:"button",className:s.primaryAction,"aria-label":a("playtest.actions.runLabel","Run {{label}}").replace("{{label}}",e.action.label),disabled:!e.active||C,onClick:S,children:C?a("playtest.actions.running","Running…"):a("playtest.actions.run","Run")})}),t.jsx("span",{className:s.rowFeedback,"data-state":N,"aria-live":"polite",children:w}),!e.active&&t.jsx("span",{className:s.actionInactiveReason,children:j})]})]}),t.jsx(_t,{open:n,title:e.action.label,description:a("playtest.actions.settings","Execution settings"),ariaLabel:a("playtest.actions.settingsDialog","{{label}} execution settings").replace("{{label}}",e.action.label),closeLabel:a("common.close","Close"),returnFocusTo:d.current,onClose:()=>i(!1),items:[{label:a("playtest.actions.parameters","Parameters"),value:t.jsx(Et,{action:e.action,draft:y,errors:c,disabled:C,onChange:T})},{label:a("playtest.actions.fixedArguments","Fixed arguments"),value:$||"—"},{label:a("playtest.actions.lastResult","Last result"),value:((Z=e.state)==null?void 0:Z.result)===void 0?w.trim()||"—":ct(e.state.result)}],actions:[{label:a("playtest.actions.saveDefaults","Save default inputs"),accessibleLabel:a("playtest.actions.saveDefaultsFor","Save default inputs for {{label}}").replace("{{label}}",e.action.label),variant:"secondary",disabled:C||!_.ok,onClick:F}]})]})}function Ko(e,a,n,i){const c=e.indexOf(a),o=e.indexOf(n);if(c<0||o<0||a===n)return[...e];const d=e.filter(_=>_!==a),y=d.indexOf(n),h=i==="after"?y+1:y;return d.splice(h,0,a),d}const Dt=["watches","controls","actions"];function zo(e,a){const n="path"in e&&e.path?[e.path.root,...e.path.segments].join("."):"",i="access"in e?e.access.adapter:e.executor.kind==="adapter"?e.executor.adapter:"",c="access"in e?e.access.name:e.executor.kind;return[e.id,e.label,a,n,i,c].filter(Boolean).join(" ").toLocaleLowerCase()}function Wo(e,a){if(a.kind==="action")return"unobserved";const n=e.watches[`${a.kind}:${a.binding.id}`];return(n==null?void 0:n.status)??"unobserved"}function Jo(e){var u,b,k,v,A,H,z,Y;const{t:a}=re(),[n,i]=r.useState(""),[c,o]=r.useState("all"),[d,y]=r.useState("all"),[h,_]=r.useState("all"),[N,C]=r.useState(new Set),[j,f]=r.useState(0),[$,w]=r.useState(50),[T,S]=r.useState(!1),[F,R]=r.useState(((b=(u=e.live.profile)==null?void 0:u.sectionOrder)==null?void 0:b.length)===3?e.live.profile.sectionOrder:Dt),[E,K]=r.useState(null),[I,W]=r.useState(null),[Z,G]=r.useState(null),[O,B]=r.useState(!1),[L,X]=r.useState(!1),[oe,ce]=r.useState(""),[ae,me]=r.useState(null),[U,D]=r.useState(()=>{var m;return((m=e.live.profile)==null?void 0:m.presentation)??{}}),[ee,Pe]=r.useState({}),[de,fe]=r.useState({}),[pe,he]=r.useState(()=>{var m;return((m=e.live.profile)==null?void 0:m.settings)??{applyDefaultsOnManualPlayStart:!1,runtimeApplyMode:"manual"}}),V=e.live.profile,te=a("playtest.values.ungrouped","Ungrouped");r.useEffect(()=>{var m,J,l;R(((J=(m=e.live.profile)==null?void 0:m.sectionOrder)==null?void 0:J.length)===3?e.live.profile.sectionOrder:Dt),D(((l=e.live.profile)==null?void 0:l.presentation)??{}),B(!1)},[(k=e.live.profile)==null?void 0:k.id,(v=e.live.profile)==null?void 0:v.presentation,(A=e.live.profile)==null?void 0:A.sectionOrder]),r.useEffect(()=>{var m;he(((m=e.live.profile)==null?void 0:m.settings)??{applyDefaultsOnManualPlayStart:!1,runtimeApplyMode:"manual"})},[(H=e.live.profile)==null?void 0:H.id,(z=e.live.profile)==null?void 0:z.settings]);const se=r.useMemo(()=>{if(!V)return{entries:[],total:0,pages:1,safePage:0,groups:[]};const m=[...V.controls.map((P,M)=>({kind:"control",binding:P,sourceOrder:M})),...V.watches.map((P,M)=>({kind:"watch",binding:P,sourceOrder:V.controls.length+M})),...(V.actions??[]).map((P,M)=>({kind:"action",binding:P,sourceOrder:V.controls.length+V.watches.length+M}))],J=Array.from(new Set(m.map(P=>{var M;return((M=U[P.binding.id])==null?void 0:M.group)??te}))).sort((P,M)=>P.localeCompare(M)),l=n.trim().toLocaleLowerCase(),g=m.filter(P=>{var Q;const M=((Q=U[P.binding.id])==null?void 0:Q.group)??te;return(c==="all"||P.kind===c)&&(h==="all"||M===h)&&(d==="all"||P.kind==="action"||Wo(e.live,P)===d)&&(!l||zo(P.binding,M).includes(l))}).sort((P,M)=>{if(P.kind!==M.kind){const ye=Ie=>Ie==="watch"?"watches":Ie==="control"?"controls":"actions";return F.indexOf(ye(P.kind))-F.indexOf(ye(M.kind))}const Q=U[P.binding.id],ie=U[M.binding.id];return!!(Q!=null&&Q.pinned)!=!!(ie!=null&&ie.pinned)?Q!=null&&Q.pinned?-1:1:((Q==null?void 0:Q.order)??P.sourceOrder)-((ie==null?void 0:ie.order)??M.sourceOrder)}),x=Math.max(1,Math.ceil(g.length/$)),q=Math.min(j,x-1);return{entries:g.slice(q*$,(q+1)*$),total:g.length,pages:x,safePage:q,groups:J}},[h,c,d,j,$,U,V,e.live,n,F,te]),ne=((V==null?void 0:V.controls.length)??0)+((V==null?void 0:V.watches.length)??0)+(((Y=V==null?void 0:V.actions)==null?void 0:Y.length)??0),ge=n.trim()!==""||c!=="all"||d!=="all"||h!=="all",je={watches:a("playtest.values.observedSection","Observed values"),controls:a("playtest.values.changeSection","Change values"),actions:a("playtest.actions.section","Actions")},Se=async m=>{G(null);try{await e.live.saveProfileMetadata(m)}catch(J){throw G(J instanceof Error?J.message:a("playtest.values.layoutSaveFailed","Could not save the display order")),J}},ke=m=>{he(m),Se({settings:m}).catch(()=>he((V==null?void 0:V.settings)??{applyDefaultsOnManualPlayStart:!1,runtimeApplyMode:"manual"}))},be=m=>{if(!O||L||!F.includes(m))return;const J=F,l=F.indexOf(m),g=l===0?1:l-1,x=[...F];[x[l],x[g]]=[x[g],x[l]];const q=x;R(q),X(!0),Se({sectionOrder:q}).then(()=>ce(a("playtest.values.layoutSaved","Display order saved"))).catch(()=>R(J)).finally(()=>X(!1))},_e=m=>se.entries.filter(J=>J.kind===m),xe=(m,J,l,g)=>{var ye,Ie,Me;if(!V||!O||L)return;const x=U,q=J.map(we=>we.binding.id),P=Ko(q,m.binding.id,l,g);if(q.every((we,ve)=>we===P[ve]))return;const M={...U},Q=J.map(we=>{var ve;return((ve=U[we.binding.id])==null?void 0:ve.order)??we.sourceOrder}).sort((we,ve)=>we-ve);for(const[we,ve]of P.entries())M[ve]={order:Q[we],pinned:((ye=U[ve])==null?void 0:ye.pinned)??!1,...(Ie=U[ve])!=null&&Ie.group?{group:(Me=U[ve])==null?void 0:Me.group}:{}};D(M),X(!0);const ie=P.indexOf(m.binding.id)+1;Se({presentation:M}).then(()=>ce(a("playtest.values.movedTo","{{label}} moved to position {{position}}").replace("{{label}}",m.binding.label).replace("{{position}}",String(ie)))).catch(()=>D(x)).finally(()=>X(!1))},Ne=m=>C(J=>{const l=new Set(J);return l.has(m)?l.delete(m):l.add(m),l}),Ce=(m,J)=>{var Ie,Me,we,ve;const l=((Ie=U[m.binding.id])==null?void 0:Ie.group)??te,g=((Me=U[m.binding.id])==null?void 0:Me.pinned)??!1,x=J.filter(le=>{var ue,Le;return(((ue=U[le.binding.id])==null?void 0:ue.group)??te)===l&&(((Le=U[le.binding.id])==null?void 0:Le.pinned)??!1)===g}),q=x.findIndex(le=>le.binding.id===m.binding.id),P=le=>a(le==="previous"?"playtest.values.movePrevious":"playtest.values.moveNext",`Move {{label}} ${le}`).replace("{{label}}",m.binding.label),M=a("playtest.values.drag","Drag {{label}} to reorder").replace("{{label}}",m.binding.label),Q=e.active&&(e.live.studioMode!=="run"||m.binding.target.role==="server"),ie=e.live.studioMode==="run"&&m.binding.target.role==="client"?a("playtest.controls.playModeRequired","Client test values are available in Play."):e.inactiveReason,ye=`${V.id}:${((we=e.live.lease)==null?void 0:we.leaseId)??"edit"}:${m.binding.id}`;return t.jsxs("div",{className:s.valueEntryShell,"data-layout-editing":O,"data-drop-position":(ae==null?void 0:ae.id)===m.binding.id?ae.placement:void 0,onDragOver:le=>{if((E==null?void 0:E.kind)!==m.kind||!x.some(Kt=>Kt.binding.id===E.id))return;le.preventDefault();const ue=le.currentTarget.getBoundingClientRect(),lt=m.kind==="watch"?le.clientX>=ue.left+ue.width/2?"after":"before":le.clientY>=ue.top+ue.height/2?"after":"before";me({id:m.binding.id,placement:lt})},onDrop:le=>{if(le.preventDefault(),(E==null?void 0:E.kind)===m.kind&&E.id!==m.binding.id&&(ae==null?void 0:ae.id)===m.binding.id){const ue=x.find(Le=>Le.binding.id===E.id);ue&&xe(ue,x,m.binding.id,ae.placement)}K(null),me(null)},children:[O&&t.jsxs("div",{className:s.valueReorderControls,children:[t.jsx("button",{type:"button",className:s.dragHandle,draggable:!0,"aria-label":M,disabled:L,onDragStart:()=>K({kind:m.kind,id:m.binding.id}),onDragEnd:()=>{K(null),me(null)},children:t.jsx(wt,{size:14,"aria-hidden":"true"})}),t.jsx("button",{type:"button","aria-label":P("previous"),"aria-describedby":q<=0?"playtest-layout-boundary":void 0,disabled:L||q<=0,onClick:()=>xe(m,x,x[q-1].binding.id,"before"),children:t.jsx(Nt,{size:13,"aria-hidden":"true"})}),t.jsx("button",{type:"button","aria-label":P("next"),"aria-describedby":q===x.length-1?"playtest-layout-boundary":void 0,disabled:L||q<0||q===x.length-1,onClick:()=>xe(m,x,x[q+1].binding.id,"after"),children:t.jsx(ht,{size:13,"aria-hidden":"true"})})]}),m.kind==="control"?t.jsx(Bo,{profile:{...V,controls:[m.binding],watches:[],settings:pe},active:Q,inactiveReason:ie,states:e.live.controls,watches:e.live.watches,draftScope:`${V.id}:${((ve=e.live.lease)==null?void 0:ve.leaseId)??"edit"}`,drafts:ee[ye]?{[m.binding.id]:ee[ye]}:void 0,onDraftChange:(le,ue,Le)=>Pe(lt=>({...lt,[ye]:{value:ue,dirty:Le}})),profileSaveLocked:!1,onApply:(le,ue)=>void e.live.apply(le,ue),onSaveValue:e.live.saveControlValue,onRemoveValue:le=>e.live.saveProfileMetadata({removeDefaults:[le]})}):m.kind==="watch"?t.jsx(Go,{profile:{...V,controls:[],watches:[m.binding]},watches:e.live.watches}):t.jsx(Uo,{action:m.binding,state:e.live.actions[m.binding.id],draft:de[`${V.id}:${m.binding.id}`]??qt(m.binding),active:e.active&&e.live.studioState==="Running"&&(e.live.studioMode!=="run"||m.binding.target.role==="server"),inactiveReason:e.live.studioState==="Paused"?a("playtest.actions.resumeRequired","Resume Studio before running this action."):e.live.studioMode==="run"&&m.binding.target.role==="client"?a("playtest.actions.playModeRequired","This action is available in Play."):e.inactiveReason,presentation:U[m.binding.id],onDraftChange:(le,ue)=>fe(Le=>({...Le,[`${V.id}:${m.binding.id}`]:ue})),onExecute:(le,ue)=>void e.live.executeAction(le,ue,crypto.randomUUID()),onSaveDefaults:e.live.saveActionDefaults})]},`${m.kind}:${m.binding.id}`)},p=m=>{var q;const l=_e(m==="watches"?"watch":m==="controls"?"control":"action"),g=new Map;for(const P of l){const M=((q=U[P.binding.id])==null?void 0:q.group)??te;g.set(M,[...g.get(M)??[],P])}const x=je[m];return t.jsxs("section",{className:s.valueSection,"aria-label":x,onDragOver:P=>{I&&I!==m&&P.preventDefault()},onDrop:P=>{!I||I===m||(P.preventDefault(),be(I),W(null))},children:[t.jsxs("header",{className:s.valueSectionHeader,children:[t.jsxs("div",{className:s.valueSectionHeading,children:[O&&t.jsx("button",{type:"button",className:s.sectionDragHandle,draggable:!0,"aria-label":a("playtest.values.drag","Drag {{label}} to reorder").replace("{{label}}",x),disabled:L,onDragStart:()=>W(m),onDragEnd:()=>W(null),children:t.jsx(wt,{size:15,"aria-hidden":"true"})}),t.jsx("h3",{children:x}),t.jsx("span",{className:s.valueSectionCount,children:l.length})]}),t.jsxs("div",{className:s.valueSectionHeaderActions,children:[m==="controls"&&V&&t.jsxs("div",{className:s.runtimeSettings,children:[t.jsx(Oe,{active:e.live.canMutate,label:a("playtest.settings.applyChangesAutomatically","Apply changes automatically"),reason:e.inactiveReason??a("playtest.controls.proRequired","Real-time value editing and Reset all are available with Pro."),children:t.jsxs("label",{className:s.runtimeSettingSwitch,children:[t.jsx("span",{children:a("playtest.settings.applyChangesAutomatically","Apply changes automatically")}),t.jsx("input",{className:s.runtimeSettingSwitchInput,type:"checkbox",role:"switch",checked:pe.runtimeApplyMode==="auto",disabled:!e.live.canMutate,onChange:P=>{ke({...pe,runtimeApplyMode:P.target.checked?"auto":"manual"})}}),t.jsx("span",{className:s.runtimeSettingSwitchTrack,"aria-hidden":"true",children:t.jsx("span",{className:s.runtimeSettingSwitchThumb})})]})}),t.jsx(Oe,{active:e.live.canMutate,label:a("playtest.settings.applyDefaultsOnPlayStart","Apply saved defaults when Play starts"),reason:e.inactiveReason??a("playtest.controls.proRequired","Real-time value editing and Reset all are available with Pro."),children:t.jsxs("label",{className:s.runtimeSettingSwitch,children:[t.jsx("span",{children:a("playtest.settings.applyDefaultsOnPlayStart","Apply saved defaults when Play starts")}),t.jsx("input",{className:s.runtimeSettingSwitchInput,type:"checkbox",role:"switch",checked:pe.applyDefaultsOnManualPlayStart,disabled:!e.live.canMutate,onChange:P=>ke({...pe,applyDefaultsOnManualPlayStart:P.target.checked})}),t.jsx("span",{className:s.runtimeSettingSwitchTrack,"aria-hidden":"true",children:t.jsx("span",{className:s.runtimeSettingSwitchThumb})})]})})]}),O&&t.jsx("button",{type:"button",className:s.sectionMoveButton,disabled:L,"aria-label":a(F[0]===m?"playtest.values.moveDown":"playtest.values.moveUp",F[0]===m?"Move {{label}} down":"Move {{label}} up").replace("{{label}}",x),onClick:()=>be(m),children:F[0]===m?t.jsx(ht,{size:14,"aria-hidden":"true"}):t.jsx(Nt,{size:14,"aria-hidden":"true"})})]})]}),l.length===0?t.jsx("div",{className:s.panelEmpty,children:m==="watches"?a("playtest.watch.empty","Observed values appear here during Play."):m==="controls"?a("playtest.controls.empty","No test controls in this profile yet."):a("playtest.actions.empty","No actions in this profile yet.")}):t.jsx("div",{className:m==="watches"?s.watchValueGrid:m==="controls"?s.controlValueList:s.actionValueList,children:Array.from(g.entries()).map(([P,M])=>{const Q=N.has(`${m}:${P}`),ie=t.jsx("div",{className:s.valueGroupRows,children:M.map(ye=>Ce(ye,l))});return g.size===1&&P===te?t.jsx("div",{className:s.valueGroup,children:ie},`${m}:${P}`):t.jsxs("section",{className:s.valueGroup,children:[t.jsxs("button",{type:"button",className:s.valueGroupToggle,"aria-expanded":!Q,"aria-label":`${Q?a("playtest.values.expandGroup","Expand"):a("playtest.values.collapseGroup","Collapse")} ${P}`,onClick:()=>Ne(`${m}:${P}`),children:[t.jsx("span",{children:P}),t.jsx("span",{children:M.length})]}),!Q&&ie]},`${m}:${P}`)})})]},m)};return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:s.valueToolbar,children:[t.jsxs("label",{className:s.valueSearch,children:[t.jsx("span",{className:s.srOnly,children:a("playtest.values.search","Search test values")}),t.jsx("input",{type:"search","aria-label":a("playtest.values.search","Search test values"),value:n,onChange:m=>{i(m.target.value),f(0)},placeholder:a("playtest.values.searchPlaceholder","Name, group, source, or path")})]}),t.jsxs("button",{type:"button",className:s.secondaryAction,"aria-expanded":T,"aria-controls":"playtest-value-filters",onClick:()=>S(m=>!m),children:[a("playtest.values.filters","Filters"),ge?` (${[n.trim()!=="",c!=="all",d!=="all",h!=="all"].filter(Boolean).length})`:""]})]}),T&&t.jsxs("div",{className:s.valueFilters,id:"playtest-value-filters",children:[t.jsxs("label",{children:[t.jsx("span",{children:a("playtest.values.kind","Value type")}),t.jsxs("select",{"aria-label":a("playtest.values.kind","Value type"),value:c,onChange:m=>{o(m.target.value),f(0)},children:[t.jsx("option",{value:"all",children:a("playtest.values.all","All values")}),t.jsx("option",{value:"control",children:a("playtest.values.controls","Controls")}),t.jsx("option",{value:"watch",children:a("playtest.values.watches","Watch Values")}),t.jsx("option",{value:"action",children:a("playtest.actions.section","Actions")})]})]}),t.jsxs("label",{children:[t.jsx("span",{children:a("playtest.values.status","Observation status")}),t.jsxs("select",{"aria-label":a("playtest.values.status","Observation status"),value:d,onChange:m=>{y(m.target.value),f(0)},children:[t.jsx("option",{value:"all",children:a("playtest.values.statusAll","All statuses")}),t.jsx("option",{value:"fresh",children:a("playtest.watch.fresh","Fresh")}),t.jsx("option",{value:"stale",children:a("playtest.watch.stale","Stale")}),t.jsx("option",{value:"unavailable",children:a("playtest.watch.unavailable","Unavailable")}),t.jsx("option",{value:"unobserved",children:a("playtest.watch.notObserved","Not observed yet")})]})]}),t.jsxs("label",{children:[t.jsx("span",{children:a("playtest.values.group","Group")}),t.jsxs("select",{"aria-label":a("playtest.values.group","Group"),value:h,onChange:m=>{_(m.target.value),f(0)},children:[t.jsx("option",{value:"all",children:a("playtest.values.allGroups","All groups")}),se.groups.map(m=>t.jsx("option",{value:m,children:m},m))]})]}),t.jsxs("label",{children:[t.jsx("span",{children:a("playtest.values.pageSize","Rows")}),t.jsxs("select",{"aria-label":a("playtest.values.pageSize","Rows"),value:$,onChange:m=>{w(Number(m.target.value)),f(0)},children:[t.jsx("option",{value:"25",children:"25"}),t.jsx("option",{value:"50",children:"50"}),t.jsx("option",{value:"100",children:"100"})]})]})]}),t.jsxs("div",{className:s.valueListStatus,children:[t.jsx("div",{className:s.valueCount,role:"status",children:a("playtest.values.count","{{visible}} of {{total}} values").replace("{{visible}}",String(se.total)).replace("{{total}}",String(ne))}),t.jsx("button",{type:"button",className:s.secondaryAction,disabled:L||ne===0,onClick:()=>{if(O){B(!1);return}ge&&(i(""),o("all"),y("all"),_("all"),f(0)),B(!0)},children:O?a("playtest.values.doneLayout","Done editing layout"):ge?a("playtest.values.editFullList","Edit full list"):a("playtest.values.editLayout","Edit layout")})]}),O&&t.jsx("div",{className:s.layoutHint,id:"playtest-layout-boundary",children:a("playtest.values.layoutBoundary","Move items within the current group and pinned section.")}),t.jsx("span",{className:s.srOnly,"aria-live":"polite",children:oe}),Z&&t.jsx("div",{className:s.layoutError,role:"alert",children:Z}),se.total===0&&ne>0?t.jsx("div",{className:s.panelEmpty,children:a("playtest.values.noResults","No values match these filters.")}):t.jsx("div",{className:s.valueSections,children:F.map(p)}),se.pages>1&&t.jsxs("div",{className:s.valuePagination,children:[t.jsx("button",{type:"button",disabled:se.safePage===0,onClick:()=>f(m=>m-1),children:a("playtest.values.previous","Previous")}),t.jsxs("span",{children:[se.safePage+1," / ",se.pages]}),t.jsx("button",{type:"button",disabled:se.safePage+1>=se.pages,onClick:()=>f(m=>m+1),children:a("playtest.values.next","Next")})]})]})}const Yo="_emptyState_10pjf_1",Qo="_header_10pjf_11",Xo="_method_10pjf_12",Zo="_methods_10pjf_39",ec="_singleMethod_10pjf_45",tc="_methodTitle_10pjf_57",ac="_moreExamples_10pjf_70",sc="_hint_10pjf_88",nc="_tierNote_10pjf_89",ic="_disabledReason_10pjf_90",lc="_primaryAction_10pjf_102",Ee={emptyState:Yo,header:Qo,method:Xo,methods:Zo,singleMethod:ec,methodTitle:tc,moreExamples:ac,hint:sc,tierNote:nc,disabledReason:ic,primaryAction:lc};function Ut(e){const{t:a}=re(),n=e.kind==="no-results",i=e.kind==="no-profile",c=n?a("playtest.emptyResults.title","Ask AI to check your game"):i?a("playtest.emptyValues.noProfileTitle","Prepare values and actions to test"):a("playtest.emptyValues.noValuesTitle","Add test values and actions to this profile"),o=n?a("playtest.emptyResults.description","When AI finishes the test, you can review pass, failure, and the reason here."):i?a("playtest.emptyValues.noProfileDescription","Ask AI to prepare values to observe or change and actions to run during Play, or select an object in Studio and add one directly."):a("playtest.emptyValues.noValuesDescription","Use the selected profile, {{name}}, to collect values to observe or change and actions to run during Play.").replace("{{name}}",e.profileName??"");return t.jsxs("section",{className:Ee.emptyState,children:[t.jsxs("header",{className:Ee.header,children:[t.jsx("h3",{children:c}),t.jsx("p",{children:o})]}),t.jsxs("div",{className:`${Ee.methods} ${n?Ee.singleMethod:""}`,children:[t.jsxs("section",{className:Ee.method,children:[t.jsxs("div",{className:Ee.methodTitle,children:[t.jsx(da,{size:16,"aria-hidden":"true"}),t.jsx("h4",{children:a("playtest.emptyValues.aiTitle","Ask AI")})]}),!n&&t.jsx("p",{children:a("playtest.emptyValues.aiDescription","Copy a request and paste it into an AI chat connected to WEPPY.")}),t.jsx(jt,{exampleIds:n?["automated-check"]:["character"]}),!n&&t.jsxs("details",{className:Ee.moreExamples,children:[t.jsx("summary",{children:a("playtest.ai.otherExamples","Other request examples")}),t.jsx(jt,{exampleIds:["selection","game-state","action"]})]}),n&&e.isBasic&&t.jsx("p",{className:Ee.tierNote,children:a("playtest.emptyResults.proDescription","Automated test runs and actual saved results are available with Pro.")})]}),!n&&t.jsxs("section",{className:Ee.method,children:[t.jsxs("div",{className:Ee.methodTitle,children:[t.jsx(Ca,{size:16,"aria-hidden":"true"}),t.jsx("h4",{children:a("playtest.emptyValues.directTitle","Select and add it yourself")})]}),t.jsx("p",{children:a("playtest.emptyValues.directDescription","Select an object in Studio, then choose a supported value to observe or change, or an available action.")}),i&&t.jsx("p",{className:Ee.hint,children:a("playtest.emptyValues.firstProfileHint","When you add the first item, enter a profile name to keep related test settings together.")}),t.jsx("button",{type:"button",className:Ee.primaryAction,disabled:!!e.directAddDisabledReason,"aria-describedby":e.directAddDisabledReason?"playtest-empty-direct-reason":void 0,onClick:e.onAddFromSelection,children:a("playtest.emptyValues.directAction","Add selected Studio value")}),e.directAddDisabledReason&&t.jsx("p",{className:Ee.disabledReason,id:"playtest-empty-direct-reason",children:e.directAddDisabledReason})]})]})]})}function rc(e){var h,_,N,C,j,f,$;const{live:a}=e,{t:n}=re(),i=((h=a.lease)==null?void 0:h.state)==="active"&&(a.studioState==="Running"||a.studioState==="Paused"),c=i&&a.canMutate,o=c&&(a.studioMode!=="run"||!!((_=a.profile)!=null&&_.controls.some(w=>w.target.role==="server"))),d=e.inactiveReason??n("playtest.values.playRequired","Start Play in Studio to change test values."),y=(((N=a.profile)==null?void 0:N.controls.length)??0)+(((C=a.profile)==null?void 0:C.watches.length)??0)+(((f=(j=a.profile)==null?void 0:j.actions)==null?void 0:f.length)??0);return t.jsxs("div",{className:s.liveWorkspace,role:"tabpanel","aria-label":n("playtest.view.liveSession","Test Values"),children:[t.jsxs("section",{className:s.profileToolbar,children:[t.jsxs("div",{children:[t.jsxs("div",{className:s.profileLabelRow,children:[t.jsx("label",{htmlFor:"playtest-profile",children:n("playtest.profile.label","Test profiles")}),t.jsx("span",{children:n("playtest.profile.savedCount","{{count}} profiles saved").replace("{{count}}",String(a.profiles.length))})]}),t.jsxs("select",{id:"playtest-profile",value:a.selectedProfileId??"",disabled:!!a.lease,onChange:w=>a.selectProfile(w.target.value),children:[a.profiles.length===0&&t.jsx("option",{value:"",children:n("playtest.profile.empty","No profiles yet")}),a.profiles.map(w=>t.jsx("option",{value:w.id,children:w.name},w.id))]})]}),t.jsxs("div",{className:s.profileActions,children:[t.jsxs("button",{type:"button",className:s.primaryAction,onClick:e.onManageValues,children:[t.jsx(ja,{size:14,"aria-hidden":"true"})," ",n("playtest.values.addValue","Add value")]}),t.jsxs("button",{type:"button",className:s.secondaryAction,disabled:!a.profile||!!a.lease,onClick:e.onEditProfile,children:[t.jsx(Pa,{size:14,"aria-hidden":"true"})," ",n("playtest.profile.edit","Edit profile")]}),t.jsxs("button",{type:"button",className:s.secondaryAction,disabled:!!a.lease,onClick:e.onNewProfile,children:[t.jsx(Ot,{size:14,"aria-hidden":"true"})," ",n("playtest.profile.new","New profile")]})]})]}),a.loading?t.jsx("div",{className:s.panelEmpty,children:n("common.loading","Loading...")}):y===0?t.jsx(Ut,{kind:a.profile?"no-values":"no-profile",profileName:($=a.profile)==null?void 0:$.name,onAddFromSelection:e.onManageValues,directAddDisabledReason:e.directAddDisabledReason}):t.jsx("div",{className:s.liveGrid,children:t.jsxs("section",{className:`${s.livePanel} ${s.valueWorkspacePanel}`,"data-runtime-state":i?"active":"inactive",children:[t.jsxs("header",{className:s.valueWorkspaceHeader,children:[t.jsxs("div",{children:[t.jsx("strong",{children:n("playtest.values.title","Test values")}),!c&&t.jsxs("span",{className:s.controlAvailability,"data-warning":a.studioState==="Edit",id:"playtest-controls-availability",role:"status",children:[a.studioState==="Edit"&&t.jsx(Ta,{size:14,"aria-hidden":"true"}),d]})]}),t.jsx(Oe,{active:o,label:n("playtest.session.reset","Reset all"),reason:d,children:t.jsxs("button",{type:"button",className:s.resetAction,disabled:!o,"aria-describedby":o?void 0:"playtest-controls-availability",onClick:()=>void a.resetAll(),children:[a.canMutate?t.jsx(Ea,{size:14,"aria-hidden":"true"}):t.jsx(Na,{size:14,"aria-hidden":"true"}),n("playtest.session.reset","Reset all")]})})]}),t.jsx(Jo,{live:a,active:c,inactiveReason:d})]})})]})}const dt={label:"",role:"server",path:"Workspace",accessKind:"attribute",fieldName:"",editorType:"number",defaultValue:"0",minimum:"0",maximum:"100",step:"1"};function oc(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"binding"}function Tt(e){const a=e.split(".").map(n=>n.trim()).filter(Boolean);return a.length>0?{root:a[0],segments:a.slice(1)}:null}function $e(e){return e==="range"?"number":e}function cc(e){var n;if(Ge($e(e.editorType)))return xt($e(e.editorType),e.defaultValue)??null;if(e.editorType==="enum")return((n=e.enumValues)==null?void 0:n.find(i=>String(i)===e.defaultValue))??null;if(e.editorType==="boolean")return e.defaultValue==="true";if(e.editorType==="string")return e.defaultValue;const a=Number(e.defaultValue);return Number.isFinite(a)?a:null}function It(e){return e.accessKind==="value"?{kind:"value"}:{kind:e.accessKind,name:e.fieldName.trim()}}function dc(e){var c,o;if("executor"in e)return`${e.target.role} · ${e.executor.kind} · ${e.parameters.length} parameters`;const a=e.path?[e.path.root,...e.path.segments].join("."):"adapter",n=e.access.kind==="value"?"Value":e.access.name??e.access.kind,i="constraints"in e&&((c=e.constraints)==null?void 0:c.minimum)!==void 0&&((o=e.constraints)==null?void 0:o.maximum)!==void 0;return`${e.target.role} · ${a} · ${n} · ${i?"range":e.valueType}`}function uc(e){var ke,be,_e,xe,Ne,Ce;const{t:a}=re(),n=!!e.profile,[i,c]=r.useState(""),[o,d]=r.useState([]),[y,h]=r.useState([]),[_,N]=r.useState([]),[C,j]=r.useState({}),[f,$]=r.useState("controls"),[w,T]=r.useState(!1),[S,F]=r.useState(dt),[R,E]=r.useState(!1),[K,I]=r.useState(!1),[W,Z]=r.useState(!1),[G,O]=r.useState(!1),[B,L]=r.useState(null),[X,oe]=r.useState(null),ce=r.useRef(null);r.useEffect(()=>{var p,u,b,k,v;e.open&&(c(((p=e.profile)==null?void 0:p.name)??""),d(((u=e.profile)==null?void 0:u.controls)??[]),h(((b=e.profile)==null?void 0:b.watches)??[]),N(((k=e.profile)==null?void 0:k.actions)??[]),j(((v=e.profile)==null?void 0:v.presentation)??{}),$("controls"),T(!1),F(dt),I(!1),Z(!1),O(!1),oe(null),L(null))},[e.open,e.profile]);const ae=f==="controls"?o:f==="watches"?y:_,me=i!==(((ke=e.profile)==null?void 0:ke.name)??"")||JSON.stringify(o)!==JSON.stringify(((be=e.profile)==null?void 0:be.controls)??[])||JSON.stringify(y)!==JSON.stringify(((_e=e.profile)==null?void 0:_e.watches)??[])||JSON.stringify(_)!==JSON.stringify(((xe=e.profile)==null?void 0:xe.actions)??[])||JSON.stringify(C)!==JSON.stringify(((Ne=e.profile)==null?void 0:Ne.presentation)??{})||w,U=r.useMemo(()=>new Set([...o,...y,..._].map(p=>p.id)),[_,o,y]),D=(p,u)=>{F(b=>({...b,[p]:u})),L(null)},ee=()=>{const p=oc(S.label);let u=p,b=2;for(;U.has(u);)u=`${p}-${b}`,b+=1;return u},Pe=(p,u)=>C[p]??{order:u,pinned:!1},de=(p,u,b)=>j(k=>({...k,[p]:{...Pe(p,u),...b}})),fe=ae.map((p,u)=>({binding:p,sourceOrder:u,entry:Pe(p.id,u)})).sort((p,u)=>p.entry.order-u.entry.order),pe=(p,u)=>{const b=fe.findIndex(A=>A.binding.id===p),k=fe[b+u],v=fe[b];!v||!k||j(A=>({...A,[v.binding.id]:{...v.entry,order:k.entry.order},[k.binding.id]:{...k.entry,order:v.entry.order}}))},he=()=>{const p=Tt(S.path),u=cc(S);if(!S.label.trim()||!p||S.accessKind!=="value"&&!S.fieldName.trim()||u===null)return null;const b=S.editorType==="range",k=Number(S.minimum),v=Number(S.maximum),A=Number(S.step);return b&&(typeof u!="number"||!Number.isFinite(k)||!Number.isFinite(v)||!Number.isFinite(A)||k>=v||A<=0||u<k||u>v)?null:{id:ee(),label:S.label.trim(),target:{role:S.role},path:p,access:It(S),valueType:$e(S.editorType),value:u,...S.editorType==="enum"?{enumValues:S.enumValues}:{},applyTiming:"after_agents_ready",restorePolicy:"session_end",...b?{constraints:{minimum:k,maximum:v,step:A}}:{}}},V=()=>{const p=Tt(S.path);return!S.label.trim()||!p||S.accessKind!=="value"&&!S.fieldName.trim()?null:{id:ee(),label:S.label.trim(),target:{role:S.role},path:p,access:It(S),valueType:$e(S.editorType)}},te=()=>{const p=f==="controls"?he():V();if(!p){L(a("playtest.profile.binding.invalid","Complete the label, path, field, and type values."));return}f==="controls"?d(u=>[...u,p]):h(u=>[...u,p]),j(u=>({...u,[p.id]:{order:o.length+y.length,pinned:!1}})),T(!1),F(dt)},se=async()=>{if(e.onResolveSelectionCandidates){try{const u=await e.onResolveSelectionCandidates();if(!u.selected.path||u.candidates.length===0){L(a("playtest.profile.binding.selectionEmpty","The selected instance has no supported fields."));return}oe(u),ne(u,0)}catch(u){L(u instanceof Error?u.message:String(u))}return}if(!e.onResolveSelection)return;const p=f==="controls"?he():V();if(!p){L(a("playtest.profile.binding.selectionNeedsFields","Enter the label, field, and type before using the Studio selection."));return}try{const u=await e.onResolveSelection({kind:f==="controls"?"control":"watch",id:p.id,label:p.label,role:p.target.role,access:p.access,valueType:p.valueType,..."value"in p?{value:p.value}:{},..."constraints"in p&&p.constraints?{constraints:p.constraints}:{},..."enumValues"in p&&p.enumValues?{enumValues:p.enumValues}:{}});u.path&&D("path",[u.path.root,...u.path.segments].join("."))}catch(u){L(u instanceof Error?u.message:String(u))}},ne=(p,u)=>{const b=p.candidates[u];if(!b||!p.selected.path)return;const k=b.fieldName??"Value";F(v=>({...v,label:`${p.selected.name??"Selected"} ${k}`,path:[p.selected.path.root,...p.selected.path.segments].join("."),accessKind:b.accessKind,fieldName:b.fieldName??"",editorType:b.valueType,defaultValue:typeof b.value=="object"?JSON.stringify(b.value):String(b.value),enumValues:b.enumValues})),L(null)},ge=async()=>{if(!(!e.profile||!e.onSave||!i.trim())){E(!0),L(null);try{await e.onSave({...e.profile,schemaVersion:4,name:i.trim(),controls:o,watches:y,actions:_,presentation:C}),e.onClose()}catch(p){L(p instanceof Error?p.message:String(p))}finally{E(!1)}}},je=()=>{if(!(R||G)){if(me){I(!0);return}e.onClose()}},Se=async()=>{var p;if(!(!e.profile||!e.onDelete||G||e.deleteDisabledReason)){O(!0),L(null);try{await e.onDelete(e.profile.id,e.profile.revision),Z(!1),e.onClose()}catch(u){const b=u&&typeof u=="object"?String("payload"in u&&((p=u.payload)==null?void 0:p.errorCode)||"error"in u&&u.error||"code"in u&&u.code||""):"";L(a(b==="profile_active"?"playtest.profile.deleteActive":b==="profile_revision_conflict"?"playtest.profile.deleteConflict":b==="profile_not_found"?"playtest.profile.deleteNotFound":b==="profile_scope_unavailable"?"playtest.profile.deleteScopeUnavailable":"playtest.profile.deleteFailed",u instanceof Error?u.message:"Could not delete the profile."))}finally{O(!1)}}};return t.jsxs(Ke,{open:e.open,onClose:je,dismissDisabled:R||G,initialFocusRef:ce,ariaLabel:n?a("playtest.profile.editTitle","Edit test profile"):a("playtest.profile.createTitle","Create test profile"),children:[t.jsxs("div",{className:`${s.profileDialog} ${n?s.profileEditorDialog:""}`,children:[t.jsx(ze,{title:n?a("playtest.profile.editTitle","Edit test profile"):a("playtest.profile.createTitle","Create test profile"),description:n?a("playtest.profile.editDescription","Add controls you can change during Play and Watch Values you only want to observe."):a("playtest.profile.createDescription","Profiles are stored locally for the selected Place. Add controls after creating it."),closeLabel:a("common.close","Close"),closeDisabled:R||G,onRequestClose:je}),t.jsxs("div",{className:s.profileDialogBody,children:[t.jsxs("label",{children:[a("playtest.profile.name","Profile name"),t.jsx("input",{ref:ce,value:i,onChange:p=>c(p.target.value)})]}),n&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:s.bindingTabs,role:"tablist","aria-label":a("playtest.profile.bindingTabs","Profile values"),children:[t.jsxs("button",{type:"button",role:"tab","aria-selected":f==="controls",onClick:()=>{$("controls"),T(!1)},children:[a("playtest.profile.controlsTab","Controls")," ",t.jsx("span",{children:o.length})]}),t.jsxs("button",{type:"button",role:"tab","aria-selected":f==="watches",onClick:()=>{$("watches"),T(!1)},children:[a("playtest.profile.watchesTab","Watch Values")," ",t.jsx("span",{children:y.length})]}),t.jsxs("button",{type:"button",role:"tab","aria-selected":f==="actions",onClick:()=>{$("actions"),T(!1)},children:[a("playtest.actions.section","Actions")," ",t.jsx("span",{children:_.length})]})]}),t.jsx("div",{className:s.bindingList,children:ae.length===0?t.jsx("div",{className:s.bindingEmpty,children:f==="controls"?a("playtest.profile.controlsEmpty","No controls added yet."):f==="watches"?a("playtest.profile.watchesEmpty","No Watch Values added yet."):a("playtest.actions.empty","No actions in this profile yet.")}):fe.map(({binding:p,entry:u,sourceOrder:b},k)=>t.jsxs("div",{className:s.bindingItem,children:[t.jsxs("div",{className:s.bindingItemCopy,children:[t.jsx("strong",{children:p.label}),t.jsx("span",{children:dc(p)}),t.jsxs("div",{className:s.bindingPresentation,children:[t.jsxs("label",{children:[a("playtest.profile.group","Group"),t.jsx("input",{"aria-label":a("playtest.profile.groupFor","Group for {{label}}").replace("{{label}}",p.label),value:u.group??"",onChange:v=>de(p.id,b,{group:v.target.value||void 0})})]}),t.jsxs("label",{className:s.bindingPin,children:[t.jsx("input",{type:"checkbox","aria-label":a("playtest.profile.pinLabel","Pin {{label}}").replace("{{label}}",p.label),checked:u.pinned,onChange:v=>de(p.id,b,{pinned:v.target.checked})}),a("playtest.profile.pin","Pin")]})]})]}),t.jsxs("div",{className:s.bindingItemActions,children:[t.jsx("button",{type:"button","aria-label":a("playtest.profile.moveUp","Move {{label}} up").replace("{{label}}",p.label),disabled:k===0,onClick:()=>pe(p.id,-1),children:t.jsx(ha,{size:13,"aria-hidden":"true"})}),t.jsx("button",{type:"button","aria-label":a("playtest.profile.moveDown","Move {{label}} down").replace("{{label}}",p.label),disabled:k===fe.length-1,onClick:()=>pe(p.id,1),children:t.jsx(fa,{size:13,"aria-hidden":"true"})}),t.jsx("button",{type:"button",className:s.bindingDelete,"aria-label":a("playtest.profile.removeBinding","Remove {{label}}").replace("{{label}}",p.label),onClick:()=>{f==="controls"?d(v=>v.filter(A=>A.id!==p.id)):f==="watches"?h(v=>v.filter(A=>A.id!==p.id)):N(v=>v.filter(A=>A.id!==p.id)),j(v=>Object.fromEntries(Object.entries(v).filter(([A])=>A!==p.id)))},children:t.jsx(St,{size:14,"aria-hidden":"true"})})]})]},p.id))}),f!=="actions"&&(w?t.jsxs("fieldset",{className:s.bindingForm,"aria-label":f==="controls"?a("playtest.profile.newControl","New control"):a("playtest.profile.newWatch","New watch"),children:[(e.onResolveSelectionCandidates||e.onResolveSelection)&&t.jsx("button",{type:"button",className:s.selectionButton,onClick:()=>void se(),children:a("playtest.profile.binding.useSelection","Use current Studio selection")}),X&&X.candidates.length>1&&t.jsxs("label",{children:[a("playtest.profile.binding.selectedField","Selected field"),t.jsx("select",{onChange:p=>ne(X,Number(p.target.value)),children:X.candidates.map((p,u)=>t.jsx("option",{value:u,children:p.accessKind==="value"?"ValueBase.Value":`${p.accessKind} · ${p.fieldName}`},`${p.accessKind}:${p.fieldName??"Value"}`))})]}),t.jsxs("div",{className:s.bindingFormGrid,children:[t.jsxs("label",{children:[a("playtest.profile.binding.label","Label"),t.jsx("input",{value:S.label,onChange:p=>D("label",p.target.value)})]}),t.jsxs("label",{children:[a("playtest.profile.binding.role","Target"),t.jsxs("select",{value:S.role,onChange:p=>D("role",p.target.value),children:[t.jsx("option",{value:"server",children:a("playtest.profile.binding.server","Server")}),t.jsx("option",{value:"client",children:a("playtest.profile.binding.client","Client")})]})]}),t.jsxs("label",{className:s.bindingPathField,children:[a("playtest.profile.binding.path","Runtime path"),t.jsx("input",{value:S.path,placeholder:a("playtest.profile.binding.pathPlaceholder","Workspace.Config"),onChange:p=>D("path",p.target.value)})]}),t.jsxs("label",{children:[a("playtest.profile.binding.access","Access"),t.jsxs("select",{value:S.accessKind,onChange:p=>D("accessKind",p.target.value),children:[t.jsx("option",{value:"attribute",children:a("playtest.profile.binding.attribute","Attribute")}),t.jsx("option",{value:"value",children:a("playtest.profile.binding.valueBase","ValueBase.Value")}),t.jsx("option",{value:"property",children:a("playtest.profile.binding.property","Property")})]})]}),S.accessKind!=="value"&&t.jsxs("label",{children:[a("playtest.profile.binding.field","Field name"),t.jsx("input",{value:S.fieldName,onChange:p=>D("fieldName",p.target.value)})]}),t.jsxs("label",{children:[f==="controls"?a("playtest.profile.binding.inputType","Input type"):a("playtest.profile.binding.valueType","Value type"),t.jsxs("select",{value:S.editorType,onChange:p=>D("editorType",p.target.value),children:[t.jsx("option",{value:"number",children:a("playtest.profile.binding.number","Number")}),f==="controls"&&t.jsx("option",{value:"range",children:a("playtest.profile.binding.range","Range")}),t.jsx("option",{value:"string",children:a("playtest.profile.binding.string","String")}),t.jsx("option",{value:"boolean",children:a("playtest.profile.binding.boolean","Boolean")}),t.jsx("option",{value:"vector3",children:a("playtest.profile.binding.vector3","Vector3")}),t.jsx("option",{value:"color3",children:a("playtest.profile.binding.color3","Color3")}),t.jsx("option",{value:"cframe",children:a("playtest.profile.binding.cframe","CFrame")}),S.enumValues&&t.jsx("option",{value:"enum",children:a("playtest.profile.binding.enum","Enum")})]})]}),f==="controls"&&Ge($e(S.editorType))&&t.jsx(yt,{type:$e(S.editorType),draft:S.defaultValue,label:a("playtest.profile.binding.defaultValue","Default value"),onChange:p=>D("defaultValue",p)}),f==="controls"&&S.editorType==="enum"&&t.jsxs("label",{children:[a("playtest.profile.binding.defaultValue","Default value"),t.jsx("select",{value:S.defaultValue,onChange:p=>D("defaultValue",p.target.value),children:(Ce=S.enumValues)==null?void 0:Ce.map(p=>t.jsx("option",{value:String(p),children:String(p)},String(p)))})]}),f==="controls"&&!Ge($e(S.editorType))&&S.editorType!=="boolean"&&S.editorType!=="enum"&&t.jsxs("label",{children:[a("playtest.profile.binding.defaultValue","Default value"),t.jsx("input",{type:S.editorType==="string"?"text":"number",value:S.defaultValue,onChange:p=>D("defaultValue",p.target.value)})]}),f==="controls"&&S.editorType==="boolean"&&t.jsxs("label",{className:s.bindingBooleanDefault,children:[t.jsx("input",{type:"checkbox","aria-label":a("playtest.profile.binding.defaultValue","Default value"),checked:S.defaultValue==="true",onChange:p=>D("defaultValue",String(p.target.checked))}),t.jsx("span",{children:a("playtest.profile.binding.defaultValue","Default value")})]}),f==="controls"&&S.editorType==="range"&&t.jsxs("div",{className:s.rangeFields,children:[t.jsxs("label",{children:[a("playtest.profile.binding.minimum","Minimum"),t.jsx("input",{type:"number",value:S.minimum,onChange:p=>D("minimum",p.target.value)})]}),t.jsxs("label",{children:[a("playtest.profile.binding.maximum","Maximum"),t.jsx("input",{type:"number",value:S.maximum,onChange:p=>D("maximum",p.target.value)})]}),t.jsxs("label",{children:[a("playtest.profile.binding.step","Step"),t.jsx("input",{type:"number",value:S.step,onChange:p=>D("step",p.target.value)})]})]})]}),B&&t.jsx("div",{className:s.bindingError,role:"alert",children:B}),t.jsxs("div",{className:s.bindingFormActions,children:[t.jsx("button",{type:"button",className:s.secondaryAction,onClick:()=>{T(!1),L(null)},children:a("common.cancel","Cancel")}),t.jsx("button",{type:"button",className:s.primaryAction,onClick:te,children:a("playtest.profile.binding.add","Add to profile")})]})]}):t.jsxs("button",{type:"button",className:s.addBindingButton,onClick:()=>T(!0),children:[t.jsx(Ot,{size:14,"aria-hidden":"true"})," ",f==="controls"?a("playtest.profile.addControl","Add control"):a("playtest.profile.addWatch","Add watch")]}))]}),B&&!w&&t.jsx("div",{className:s.bindingError,role:"alert",children:B})]}),t.jsxs("div",{className:s.profileDialogActions,children:[n&&e.onDelete&&t.jsxs("button",{type:"button",className:`${s.stopAction} ${s.profileDeleteAction}`,disabled:R||G||!!e.deleteDisabledReason,title:e.deleteDisabledReason,onClick:()=>Z(!0),children:[t.jsx(St,{size:14,"aria-hidden":"true"})," ",a("playtest.profile.delete","Delete profile")]}),n&&e.deleteDisabledReason&&t.jsx("span",{className:s.profileDeleteReason,role:"status",children:e.deleteDisabledReason}),t.jsx("button",{type:"button",className:s.secondaryAction,disabled:R||G,onClick:je,children:a("common.cancel","Cancel")}),n?t.jsx("button",{type:"button",className:s.primaryAction,disabled:!i.trim()||R,onClick:()=>void ge(),children:R?a("playtest.profile.saving","Saving…"):a("playtest.profile.save","Save profile")}):t.jsx("button",{type:"button",className:s.primaryAction,disabled:!i.trim()||R,onClick:async()=>{E(!0);try{await e.onCreate(i),c(""),e.onClose()}finally{E(!1)}},children:R?a("playtest.profile.creating","Creating…"):a("playtest.profile.createTitle","Create test profile")})]})]}),t.jsx(mt,{open:K,title:a("playtest.profile.discardTitle","Discard profile changes?"),message:a("playtest.profile.discardMessage","Your unsaved profile changes will be lost."),cancelLabel:a("playtest.profile.keepEditing","Keep editing"),confirmLabel:a("playtest.profile.discard","Discard changes"),onCancel:()=>I(!1),onConfirm:()=>{I(!1),e.onClose()}}),t.jsx(mt,{open:W,title:a("playtest.profile.deleteConfirmTitle","Delete test profile?"),message:e.profile?[a("playtest.profile.deleteConfirmMessage","Delete “{{name}}”? Its {{controls}} control values and {{watches}} observed values will be removed. Game objects, scripts, test connection code, other profiles, and automated test results will remain.").replace("{{name}}",e.profile.name).replace("{{controls}}",String(e.profile.controls.length)).replace("{{watches}}",String(e.profile.watches.length)),me?a("playtest.profile.deleteDirty","Unsaved edits will also be discarded."):""].filter(Boolean).join(" "):"",cancelLabel:a("common.cancel","Cancel"),confirmLabel:a("playtest.profile.delete","Delete profile"),loading:G,onCancel:()=>{G||Z(!1)},onConfirm:()=>void Se()})]})}function Fe(e){return`${e.accessKind}:${e.fieldName??"Value"}`}function et(e){return e.fieldName??"Value"}function pc(e){const{t:a}=re(),n=r.useId(),[i,c]=r.useState(!1),[o,d]=r.useState(""),y=r.useRef(null),h=r.useRef(null),_=r.useRef(null),N=o.trim().toLocaleLowerCase(),C=r.useMemo(()=>e.candidates.filter(R=>`${et(R)} ${R.accessKind}`.toLocaleLowerCase().includes(N)),[N,e.candidates]),j=["attribute","value","property"].map(R=>({kind:R,candidates:C.filter(E=>E.accessKind===R)})).filter(R=>R.candidates.length>0),f=et(e.selected);r.useEffect(()=>{var R;i&&((R=h.current)==null||R.focus())},[i]);const $=(R=!0)=>{var E;c(!1),d(""),R&&((E=y.current)==null||E.focus())},w=()=>{var R;return Array.from(((R=_.current)==null?void 0:R.querySelectorAll('[role="option"]'))??[])},T=R=>{var K;const E=w();(K=E[Math.max(0,Math.min(R,E.length-1))])==null||K.focus()},S=R=>{e.onSelect(R),$()},F=R=>R==="attribute"?a("playtest.profile.binding.attribute","Attribute"):R==="value"?a("playtest.profile.binding.valueBase","ValueBase.Value"):a("playtest.profile.binding.property","Property");return t.jsxs("div",{className:s.propertyPicker,children:[t.jsx("span",{className:s.propertyPickerLabel,children:a("playtest.values.selectProperty","Property")}),t.jsxs("button",{ref:y,type:"button",className:s.propertyPickerTrigger,disabled:e.disabled,"aria-haspopup":"listbox","aria-expanded":i,"aria-controls":i?n:void 0,"aria-label":`${a("playtest.values.propertyPickerAction","Select property")}: ${f}`,onClick:()=>{i?$(!1):c(!0)},children:[t.jsx("span",{children:f}),t.jsx(ht,{size:16,"aria-hidden":"true"})]}),i&&t.jsxs("div",{ref:_,className:s.propertyPickerPanel,onKeyDown:R=>{R.key==="Escape"&&(R.preventDefault(),R.stopPropagation(),$())},children:[t.jsxs("div",{className:s.propertyPickerSearchRow,children:[t.jsxs("label",{children:[a("playtest.values.searchProperties","Search properties"),t.jsx("input",{ref:h,type:"search",value:o,onChange:R=>d(R.target.value),onKeyDown:R=>{R.key==="ArrowDown"&&(R.preventDefault(),T(0))}})]}),t.jsx("button",{type:"button","aria-label":a("playtest.values.propertyPickerClose","Close property picker"),onClick:()=>$(),children:t.jsx(Vt,{size:16,"aria-hidden":"true"})})]}),t.jsxs("div",{id:n,className:s.propertyPickerList,role:"listbox","aria-label":a("playtest.values.availableProperties","Available properties"),children:[j.map(R=>t.jsxs("div",{className:s.propertyPickerGroup,role:"group","aria-label":F(R.kind),children:[t.jsx("span",{children:F(R.kind)}),R.candidates.map(E=>{const K=Fe(E)===Fe(e.selected);return t.jsxs("div",{role:"option",tabIndex:0,"aria-selected":K,"aria-label":et(E),className:s.propertyPickerOption,onClick:()=>S(E),onKeyDown:I=>{var G;const Z=w().indexOf(I.currentTarget);I.key==="ArrowDown"&&(I.preventDefault(),T(Z+1)),I.key==="ArrowUp"&&(I.preventDefault(),Z===0?(G=h.current)==null||G.focus():T(Z-1)),(I.key==="Enter"||I.key===" ")&&(I.preventDefault(),S(E))},children:[t.jsx("span",{children:et(E)}),t.jsx("small",{children:E.valueType}),K&&t.jsx(ua,{size:15,"aria-hidden":"true"})]},Fe(E))})]},R.kind)),C.length===0&&t.jsx("p",{role:"status",children:a("playtest.values.noProperties","No matching properties")})]})]})]})}const Lt=`local RunService = game:GetService("RunService")
|
|
77
|
-
local Workspace = game:GetService("Workspace")
|
|
78
|
-
|
|
79
|
-
local function requireStudioSession(context)
|
|
80
|
-
assert(RunService:IsStudio(), "Test Adapter is only available in Studio")
|
|
81
|
-
assert(type(context) == "table" and type(context.sessionId) == "string", "Active WEPPY test session is required")
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
schemaVersion = 1,
|
|
86
|
-
name = "combat-test-values",
|
|
87
|
-
version = "1.0.0",
|
|
88
|
-
studioOnly = true,
|
|
89
|
-
methods = {
|
|
90
|
-
enemyCount = {
|
|
91
|
-
argsSchema = { type = "object", properties = {}, additionalProperties = false },
|
|
92
|
-
timeoutSeconds = 2,
|
|
93
|
-
sideEffectClass = "read_only",
|
|
94
|
-
run = function(context)
|
|
95
|
-
requireStudioSession(context)
|
|
96
|
-
local enemies = Workspace:FindFirstChild("Enemies")
|
|
97
|
-
return enemies and #enemies:GetChildren() or 0
|
|
98
|
-
end,
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
dashboard = {
|
|
102
|
-
schemaVersion = 1,
|
|
103
|
-
entries = {{
|
|
104
|
-
id = "enemy-count",
|
|
105
|
-
label = "Enemy count",
|
|
106
|
-
group = "Combat",
|
|
107
|
-
kind = "watch",
|
|
108
|
-
valueType = "number",
|
|
109
|
-
read = { method = "enemyCount", arguments = {}, pollIntervalMs = 1000 },
|
|
110
|
-
}},
|
|
111
|
-
},
|
|
112
|
-
}`;function fc(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"value"}function tt(e,a){const n=new Set([...e.controls,...e.watches,...e.actions??[]].map(o=>o.id));let i=a,c=2;for(;n.has(i);)i=`${a}-${c}`,c+=1;return i}function ut(e){return`adapter-${e.adapter}-${e.id}`.toLowerCase().replace(/[^a-z0-9-]+/g,"-")}function mc(e){return e.accessKind==="value"?{kind:"value"}:{kind:e.accessKind,name:e.fieldName}}function vt(e){return e.fieldName??"Value"}function Mt(e,a){return`${e.selected.name??"Selected"} ${vt(a)}`}function pt(e,a,n,i){const c=a.selected.path;return!e||!c?!1:(i==="watch"?e.watches:e.controls).some(o=>{var d;return o.target.role==="server"&&((d=o.path)==null?void 0:d.root)===c.root&&JSON.stringify(o.path.segments)===JSON.stringify(c.segments)&&o.access.kind===n.accessKind&&(n.accessKind==="value"||o.access.name===n.fieldName)})}function ft(e,a,n){var i,c;return JSON.stringify([(i=e.selected.path)==null?void 0:i.root,(c=e.selected.path)==null?void 0:c.segments,a.accessKind,a.fieldName??"value",n])}function $t(e,a){var i;if(e instanceof Jt&&((i=e.error)!=null&&i.trim()))return e.error;const n=e instanceof Error?e.message:String(e);return n.startsWith("API ")?`${a} ${n}`:n}function hc(e){var z,Y,m,J;const{t:a,locale:n="en"}=re(),[i,c]=r.useState("selection"),[o,d]=r.useState(""),[y,h]=r.useState(0),[_,N]=r.useState("My test profile"),[C,j]=r.useState(!e.profile),[f,$]=r.useState(null),[w,T]=r.useState(""),[S,F]=r.useState(!1),[R,E]=r.useState(null),[K,I]=r.useState(null),W=r.useRef(!1),Z=r.useRef({open:!1,profileId:null}),[G,O]=r.useState(null),[B,L]=r.useState(null),[X,oe]=r.useState(null),[ce,ae]=r.useState(!1),[me,U]=r.useState(null),D=R??e.profile,ee=((z=e.catalog.adapters)==null?void 0:z.find(l=>l.name===me))??null,de=[ee?a("playtest.values.adapterAiContext","Use the existing Test Adapter {{adapter}} at {{path}}. Detected methods: {{methods}}. Review their schemas before adding dashboard entries; do not run a method or guess value types and fixed arguments.").replace("{{adapter}}",ee.name).replace("{{path}}",ee.sourcePath??ee.name).replace("{{methods}}",ee.methods.map(l=>`${l.name} (${l.sideEffectClass})`).join(", ")):"",a("playtest.values.aiRequest")].filter(Boolean).join(`
|
|
113
|
-
|
|
114
|
-
`);r.useEffect(()=>{var q;const l=Z.current,g=((q=e.profile)==null?void 0:q.id)??null;Z.current={open:e.open,profileId:g};const x=l.open&&l.profileId===null&&g!==null&&W.current;!e.open||x||l.open&&l.profileId===g||(c("selection"),j(!e.profile),d(""),h(0),$(null),T(""),E(null),I(null),L(null),O(null),ae(!1),U(null))},[e.open,(Y=e.profile)==null?void 0:Y.id]);const fe=r.useMemo(()=>{const l=o.trim().toLocaleLowerCase();return e.catalog.entries.filter(g=>!l||[g.label,g.group,g.adapter,g.sourcePath,g.id].filter(Boolean).join(" ").toLocaleLowerCase().includes(l))},[e.catalog.entries,o]),pe=((f==null?void 0:f.candidates)??[]).find(l=>Fe(l)===w)??(f==null?void 0:f.candidates[0]),he=Math.max(1,Math.ceil(fe.length/50)),V=Math.min(y,he-1),te=fe.slice(V*50,(V+1)*50),se=new Set([...(D==null?void 0:D.controls)??[],...(D==null?void 0:D.watches)??[],...(D==null?void 0:D.actions)??[]].map(l=>l.origin?`${l.origin.adapter}/${l.origin.entryId}`:"")),ne=[...(D==null?void 0:D.controls)??[],...(D==null?void 0:D.watches)??[]],ge=ne.filter(l=>l.access.kind==="adapter"||l.access.kind==="adapter_read").length,je=ne.length-ge,Se=je>=64,ke=ge>=10,be=((m=e.catalog.adapters)==null?void 0:m.filter(l=>l.entryCount===0))??[],_e=!!(e.catalog.catalogRevision&&e.catalog.verifiedAt&&!Number.isNaN(Date.parse(e.catalog.verifiedAt))),xe=_e&&e.catalog.verifiedAt?new Intl.DateTimeFormat(n,{dateStyle:"medium",timeStyle:"short"}).format(new Date(e.catalog.verifiedAt)):null,Ne=l=>{c(l),d(""),h(0)},Ce=async()=>{if(D)return D;if(e.activeLease)throw new Error(a("playtest.values.stopBeforeCreate","Stop Studio Play before creating the first profile."));if(!e.onCreateProfile||!_.trim())throw new Error(a("playtest.values.profileNameRequired","Enter a profile name before adding the first value."));return e.onCreateProfile(_.trim())},p=async l=>{var x;const g={...l,schemaVersion:4,actions:l.actions??[],settings:l.settings??{applyDefaultsOnManualPlayStart:!1,runtimeApplyMode:"manual"},sectionOrder:((x=l.sectionOrder)==null?void 0:x.length)===3?l.sectionOrder:["watches","controls","actions"]};if(e.activeLease){E(g);return}await e.onSave(g),E(null)},u=async(l,g)=>{if(!W.current){W.current=!0,I(`adapter:${l.id}`),L(null);try{const x=await Ce(),q={kind:"adapter",adapter:l.adapter,entryId:l.id,version:l.adapterVersion},P=M=>{var Q;return((Q=M.origin)==null?void 0:Q.adapter)===l.adapter&&M.origin.entryId===l.id};if(g)await p({...x,controls:x.controls.filter(M=>!P(M)),watches:x.watches.filter(M=>!P(M)),actions:(x.actions??[]).filter(M=>!P(M))});else if(l.kind==="action"){const M={id:tt(x,ut(l)),label:l.label,target:{role:"server"},executor:{kind:"adapter",adapter:l.adapter,method:l.execute.method},parameters:l.execute.parameters,fixedArguments:l.execute.fixedArguments,origin:q};await p({...x,schemaVersion:4,actions:[...x.actions??[],M]})}else l.kind==="watch"?await p({...x,schemaVersion:4,watches:[...x.watches,{id:tt(x,ut(l)),label:l.label,target:{role:"server"},access:{kind:"adapter_read",adapter:l.adapter,...l.read},valueType:l.valueType,origin:q}]}):l.write&&await p({...x,schemaVersion:4,controls:[...x.controls,{id:tt(x,ut(l)),label:l.label,target:{role:"server"},access:{kind:"adapter",adapter:l.adapter,...l.write},observation:{kind:"adapter_read",adapter:l.adapter,...l.read},valueType:l.valueType,applyOnStart:!1,constraints:l.constraints,enumValues:l.enumValues,applyTiming:"after_agents_ready",restorePolicy:"session_end",origin:q}]})}catch(x){L(x instanceof Error?x.message:String(x))}finally{W.current=!1,I(null)}}},b=async(l,g,x)=>{if(!l.selected.path||S||W.current||pt(D,l,g,x))return;const q=ft(l,g,x);W.current=!0,I(q),L(null),O(null);try{const P=await Ce(),M=Mt(l,g),ie={id:tt(P,`direct-${fc([l.selected.path.root,...l.selected.path.segments,vt(g)].join("-"))}`),label:M,target:{role:"server"},path:l.selected.path,access:mc(g),valueType:g.valueType};x==="watch"?await p({...P,schemaVersion:4,watches:[...P.watches,ie]}):await p({...P,schemaVersion:4,controls:[...P.controls,{...ie,...g.enumValues?{enumValues:g.enumValues}:{},applyOnStart:!1,applyTiming:"after_agents_ready",restorePolicy:"session_end"}]})}catch(P){O({key:q,kind:x,message:$t(P,a("playtest.profile.saveFailed","Could not save profile."))})}finally{W.current=!1,I(null)}},k=async()=>{if(!(!e.onResolveSelectionCandidates||S||W.current)){F(!0),L(null),O(null);try{const l=await e.onResolveSelectionCandidates();$(l),T(l.candidates[0]?Fe(l.candidates[0]):""),(!l.selected.path||l.candidates.length===0)&&L(a("playtest.values.selectionEmpty","Select an Instance with a supported Attribute, Value, or property in Studio."))}catch(l){$(null),L($t(l,a("playtest.values.selectionFailed","Could not read the Studio selection. Select one Instance in Explorer and try again.")))}finally{F(!1)}}},v=async()=>{if(!(!R||e.activeLease||W.current)){W.current=!0,I("pending"),L(null);try{await e.onSave(R),E(null)}catch(l){L(l instanceof Error?l.message:String(l))}finally{W.current=!1,I(null)}}},A=async(l,g)=>{var x;await((x=navigator.clipboard)==null?void 0:x.writeText(g)),oe(l)},H=[{id:"selection",label:a("playtest.values.sourceSelection","Studio selection")},{id:"registered",label:a("playtest.values.sourceRegistered","Test Adapter")}];return t.jsx(Ke,{open:e.open,ariaLabel:a("playtest.values.addTitle","Add a test value"),onClose:e.onClose,dismissDisabled:K!==null,children:t.jsxs("div",{className:s.valueManagerShell,children:[t.jsx(ze,{title:a("playtest.values.addTitle","Add a test value"),description:a("playtest.values.addDescription","Choose where the value exists. WEPPY uses the simplest available connection and shows where it came from."),closeLabel:a("common.close","Close"),closeDisabled:K!==null,onRequestClose:e.onClose}),t.jsx("div",{className:s.valueSourceTabs,role:"tablist","aria-label":a("playtest.values.sources","Value source"),children:H.map((l,g)=>t.jsx("button",{type:"button",role:"tab","aria-selected":i===l.id,"aria-controls":`playtest-value-source-${l.id}`,tabIndex:i===l.id?0:-1,onClick:()=>Ne(l.id),onKeyDown:x=>{var Q,ie;if(x.key!=="ArrowLeft"&&x.key!=="ArrowRight")return;x.preventDefault();const q=x.key==="ArrowRight"?1:-1,P=(g+q+H.length)%H.length,M=H[P];if(M){Ne(M.id);const ye=(Q=x.currentTarget.parentElement)==null?void 0:Q.querySelectorAll('[role="tab"]');(ie=ye==null?void 0:ye[P])==null||ie.focus()}},children:l.label},l.id))}),t.jsxs("div",{className:s.valueManagerBody,children:[C&&t.jsxs("label",{className:s.firstProfileName,children:[t.jsx("span",{children:a("playtest.profile.name","Profile name")}),t.jsx("input",{value:((J=e.profile)==null?void 0:J.name)??_,readOnly:!!e.profile,"aria-label":a("playtest.profile.name","Profile name"),onChange:l=>N(l.target.value)}),t.jsx("small",{children:a("playtest.values.firstProfileHint","The first value and this profile are saved together for the selected Place.")})]}),e.activeLease&&t.jsx("div",{className:s.inlineNotice,role:"status",children:R?a("playtest.values.draftReady","This change is kept as a draft. Save it after Studio Play stops."):a("playtest.values.stopBeforeSave","You can prepare changes now. Save the active profile after Studio Play stops.")}),t.jsx("div",{className:s.subscriptionUsage,role:"status",children:a("playtest.values.subscriptionUsage","Runtime subscriptions · Direct {{direct}}/64 · Adapter {{adapter}}/10").replace("{{direct}}",String(je)).replace("{{adapter}}",String(ge))}),i==="selection"&&t.jsxs("section",{id:"playtest-value-source-selection",role:"tabpanel",className:s.valueSourcePanel,children:[t.jsxs("div",{className:s.sourceIntro,children:[t.jsxs("div",{children:[t.jsx("strong",{children:a("playtest.values.selectionTitle","Use the actual Studio selection")}),t.jsx("p",{children:a("playtest.values.selectionDescription","Select an Instance in Explorer, then read its Attributes, Value, and supported properties. This path does not add test code.")})]}),t.jsx("button",{type:"button",className:s.primaryAction,disabled:!e.onResolveSelectionCandidates||S||K!==null,onClick:()=>void k(),children:S?a("playtest.values.readingSelection","Reading selection…"):a("playtest.values.readSelection","Read current Studio selection")})]}),(f==null?void 0:f.selected.path)&&f.candidates.length>0&&t.jsxs("div",{className:s.propertySelection,"aria-busy":S,children:[t.jsxs("div",{className:s.propertySelectionHeader,children:[t.jsxs("div",{className:s.selectedInstance,children:[t.jsx("span",{children:a("playtest.values.selectedInstance","Instance")}),t.jsx("strong",{children:f.selected.name??"Selected"}),f.selected.className&&t.jsx("span",{children:f.selected.className}),t.jsxs("details",{children:[t.jsx("summary",{children:a("playtest.values.location","Location")}),t.jsx("code",{children:[f.selected.path.root,...f.selected.path.segments].join(".")})]})]}),pe&&t.jsx(pc,{candidates:f.candidates,selected:pe,disabled:S||K!==null,onSelect:l=>T(Fe(l))})]}),(pe?[pe]:[]).map(l=>{const g=Mt(f,l),x=vt(l),q=G&&G.key===ft(f,l,G.kind)?G:null;return t.jsxs("div",{className:s.candidateEntry,children:[t.jsxs("div",{className:s.catalogRow,children:[t.jsxs("div",{children:[t.jsxs("strong",{children:[f.selected.name??"Selected"," · ",x]}),t.jsxs("span",{children:[a("playtest.values.actualNow","Actual now"),": ",st(l.value)]})]}),t.jsx("div",{className:s.candidateActions,children:["watch","control"].map(P=>{const M=pt(D,f,l,P),Q=M&&!pt(e.profile,f,l,P),ie=K===ft(f,l,P),ye=P==="watch"?a("playtest.values.addWatch","Add as Watch Value"):a("playtest.values.addControl","Add as Control"),Ie=P==="watch"?a("playtest.values.addedWatch","Added as Watch Value"):a("playtest.values.addedControl","Added as Control"),Me=P==="watch"?a("playtest.values.pendingWatch","Watch Value · save pending"):a("playtest.values.pendingControl","Control · save pending"),we=a("playtest.values.adding","Adding…"),ve=ie?we:Q?Me:M?Ie:ye,le=P==="watch"?a("playtest.values.addWatchLabel","Add {{label}} as Watch Value"):a("playtest.values.addControlLabel","Add {{label}} as Control");return t.jsxs("button",{type:"button",className:s.candidateAction,"data-state":ie?"saving":Q?"pending":M?"saved":"idle",disabled:S||!M&&(Se||!D&&e.activeLease),"aria-disabled":M||K!==null||void 0,"aria-label":M||ie?`${ve} · ${g}`:le.replace("{{label}}",g),onClick:()=>void b(f,l,P),children:[[ye,`✓ ${Ie}`,Me,we].map(ue=>t.jsx("span",{className:s.candidateActionSizer,"aria-hidden":"true",children:ue},ue)),t.jsx("span",{className:s.candidateActionLabel,"aria-live":"polite","aria-atomic":"true",children:M&&!Q&&!ie?`✓ ${ve}`:ve})]},P)})})]}),q&&t.jsxs("div",{className:s.candidateError,role:"alert",children:[t.jsx("span",{children:q.message}),t.jsx("button",{type:"button",disabled:K!==null,onClick:()=>void b(f,l,q.kind),children:a("playtest.values.retryAddition","Try again")})]})]},`${l.accessKind}:${x}`)})]})]}),i==="registered"&&t.jsxs("section",{id:"playtest-value-source-registered",role:"tabpanel",className:s.valueSourcePanel,children:[t.jsxs("div",{className:s.registeredIntro,children:[t.jsx("strong",{children:a("playtest.values.registeredTitle","Reuse values your game already exposes for testing.")}),t.jsx("p",{children:a("playtest.values.registeredDescription","These values come from Test Adapter entries checked during the last Studio Play or Run. Adding one saves it to this profile and does not change the running game.")}),xe&&t.jsx("span",{children:a("playtest.values.lastChecked","Last checked: {{time}}").replace("{{time}}",xe)})]}),be.length>0&&t.jsxs("section",{className:s.adapterSetupList,"aria-label":a("playtest.values.adaptersNeedingSetup","Adapters that need value setup"),children:[t.jsxs("header",{children:[t.jsx("strong",{children:a("playtest.values.adaptersFound","Test Adapters found")}),t.jsx("span",{children:a("playtest.values.adaptersFoundDescription","These adapters are available to tests but do not expose a value you can select yet.")})]}),be.map(l=>t.jsxs("div",{className:s.adapterSetupRow,children:[t.jsxs("div",{children:[t.jsx("strong",{children:l.name}),t.jsxs("span",{children:[a("playtest.values.adapterSetupRequired","Value setup required")," · ",a("playtest.values.adapterVersion","Version")," ",l.version]}),l.sourcePath&&t.jsx("code",{children:l.sourcePath}),t.jsx("div",{className:s.adapterMethods,children:l.methods.map(g=>t.jsxs("span",{children:[g.name," · ",g.sideEffectClass==="read_only"?a("playtest.values.methodReadOnly","Read only"):g.sideEffectClass==="session_action"?a("playtest.actions.sessionAction","Session action"):a("playtest.values.methodReversible","Reversible fixture")]},g.name))})]}),t.jsx("button",{type:"button","aria-label":a("playtest.values.configureAdapterLabel","Configure values for {{adapter}}").replace("{{adapter}}",l.name),onClick:()=>{U(l.name),ae(!0)},children:a("playtest.values.configureAdapter","Configure values")})]},l.name))]}),e.catalog.entries.length>0&&t.jsxs("label",{className:s.valueSearch,children:[t.jsx("span",{children:a("playtest.values.searchRegistered","Search registered values")}),t.jsx("input",{type:"search","aria-label":a("playtest.values.searchRegistered","Search registered values"),value:o,onChange:l=>{d(l.target.value),h(0)},placeholder:a("playtest.values.searchPlaceholder","Name, group, source, or path")})]}),e.catalog.entries.length>0&&t.jsx("div",{className:s.valueCount,role:"status",children:a("playtest.values.count","{{visible}} of {{total}} values").replace("{{visible}}",String(fe.length)).replace("{{total}}",String(e.catalog.entries.length))}),te.length>0?t.jsx("div",{className:s.catalogGroups,children:te.map(l=>{const g=se.has(`${l.adapter}/${l.id}`);return t.jsxs("div",{className:s.catalogRow,children:[t.jsxs("div",{children:[t.jsx("strong",{children:l.label}),t.jsxs("span",{children:[l.group," · ",l.kind==="control"?a("playtest.values.control","Control"):l.kind==="watch"?a("playtest.values.watch","Watch"):a("playtest.actions.action","Action")]}),t.jsx("code",{children:l.sourcePath??l.adapter}),t.jsxs("details",{className:s.catalogDetails,children:[t.jsx("summary",{children:a("playtest.values.registrationDetails","Registration details")}),t.jsxs("dl",{children:[t.jsxs("div",{children:[t.jsx("dt",{children:a("playtest.values.sourceLocation","Source location")}),t.jsx("dd",{children:t.jsx("code",{children:l.sourcePath??`ServerStorage.WeppyTestAdapters.${l.adapter}`})})]}),t.jsxs("div",{children:[t.jsx("dt",{children:a("playtest.values.profileUsage","Current profile")}),t.jsx("dd",{children:g?D==null?void 0:D.name:a("playtest.values.notInProfile","Not included")})]}),t.jsxs("div",{children:[t.jsx("dt",{children:a("playtest.values.sourceHash","Source hash")}),t.jsx("dd",{children:a("playtest.values.hashAtPlan","Verified when a removal plan is created")})]})]}),t.jsx("p",{children:a("playtest.values.profileRemovalImpact","Removing from this profile keeps the original adapter code.")}),t.jsx("p",{children:a("playtest.values.sourceRemovalImpact","Removing the original registration changes project test code and can affect other profiles or automated tests. Review the source hash, diff, and known usages first.")}),t.jsx("button",{type:"button","aria-label":a("playtest.values.copyRemovalRequest","Copy original registration removal request"),onClick:()=>void A(`remove:${l.adapter}/${l.id}`,`Review removal of the WEPPY Playtest adapter registration ${l.adapter}/${l.id}.
|
|
115
|
-
|
|
116
|
-
- Call manage_studio.playtest_adapter_plan with adapterOperation=remove_entry, adapterId=${l.adapter}, and adapterRegistrationId=${l.id}.
|
|
117
|
-
- Show the current source SHA-256, unified diff, profile and scenario usages, dynamic-reference coverage, and production exclusion strategy.
|
|
118
|
-
- Do not change source until I review the plan.
|
|
119
|
-
- Apply only the returned unexpired plan token and expected source hash.
|
|
120
|
-
- After apply, start a new Play and confirm the catalog no longer includes this entry.`),children:X===`remove:${l.adapter}/${l.id}`?a("playtest.values.copied","Copied"):a("playtest.values.copyRemovalRequest","Copy original registration removal request")})]})]}),t.jsx("button",{type:"button",disabled:K!==null||!g&&ke||!D&&e.activeLease,"aria-label":g?`${a("playtest.values.remove","Remove")} ${l.label} ${a("playtest.values.fromProfile","from profile")}`:`${a("playtest.values.add","Add")} ${l.label}`,onClick:()=>void u(l,g),children:g?a("playtest.values.removeFromProfile","Remove from profile"):K===`adapter:${l.id}`?a("playtest.profile.saving","Saving…"):a("playtest.values.add","Add")})]},`${l.adapter}/${l.id}`)})}):e.catalog.entries.length===0&&be.length===0?t.jsxs("div",{className:s.registeredEmpty,children:[t.jsx("strong",{children:_e?a("playtest.values.registeredEmptyChecked","The last Play or Run found no registered values."):a("playtest.values.registeredNotChecked","Test Adapters have not been checked yet.")}),t.jsx("p",{children:_e?a("playtest.values.registeredEmptyDescription","Use Studio selection for values visible in Explorer. Connect a game internal value when the value only exists in code."):a("playtest.values.registeredNotCheckedDescription","Connect a game internal value, then start Play or Run in Studio so WEPPY can check it.")}),t.jsxs("ol",{className:s.registeredSteps,"aria-label":a("playtest.values.registeredSteps","How registered values appear"),children:[t.jsx("li",{children:a("playtest.values.registeredStepConnect","Connect the value")}),t.jsx("li",{children:a("playtest.values.registeredStepPlay","Start Play or Run in Studio")}),t.jsx("li",{children:a("playtest.values.registeredStepCheck","Return here and check the list")}),t.jsx("li",{children:a("playtest.values.registeredStepAdd","Add the value to this profile")})]}),t.jsx("div",{className:s.registeredEmptyActions,children:t.jsx("button",{type:"button",onClick:()=>Ne("selection"),children:a("playtest.values.useStudioSelection","Use Studio selection")})})]}):e.catalog.entries.length>0?t.jsxs("div",{className:s.registeredEmpty,children:[t.jsx("strong",{children:a("playtest.values.registeredNoResults","No registered values match your search.")}),t.jsx("button",{type:"button",onClick:()=>{d(""),h(0)},children:a("playtest.values.clearSearch","Clear search")})]}):null,he>1&&t.jsxs("div",{className:s.valuePagination,children:[t.jsx("button",{type:"button",disabled:V===0,onClick:()=>h(l=>l-1),children:a("playtest.values.previous","Previous")}),t.jsxs("span",{children:[V+1," / ",he]}),t.jsx("button",{type:"button",disabled:V+1>=he,onClick:()=>h(l=>l+1),children:a("playtest.values.next","Next")})]}),e.catalog.diagnostics.map(l=>t.jsxs("div",{className:s.bindingError,role:"alert",children:[l.adapter,l.entryId?`/${l.entryId}`:"",": ",l.message]},`${l.adapter}/${l.entryId??l.code}`)),t.jsxs("details",{className:s.connectionGuide,open:ce,onToggle:l=>ae(l.currentTarget.open),children:[t.jsx("summary",{children:a("playtest.values.connectValues","Connect a value")}),t.jsxs("div",{className:s.registrationGuide,children:[t.jsx("strong",{children:a("playtest.values.registerTitle","Register values in a Test Adapter")}),t.jsx("p",{children:a("playtest.values.registerDescription","Use a Test Adapter only for game state that cannot be reached through an Instance Attribute, Value, or supported property.")}),ee&&t.jsx("p",{className:s.adapterSetupContext,children:a("playtest.values.configuringAdapter","Configuring {{adapter}} using its detected methods.").replace("{{adapter}}",ee.name)}),t.jsx("code",{children:a("playtest.values.adapterPath","ServerStorage.WeppyTestAdapters")}),t.jsx("p",{children:a("playtest.values.registerSafety")}),t.jsx("p",{children:a("playtest.values.deploymentHint")}),t.jsxs("details",{className:s.registrationExample,children:[t.jsx("summary",{children:a("playtest.values.showExample","Show Luau registration example")}),t.jsx("pre",{children:Lt})]}),t.jsxs("details",{className:s.registrationExample,children:[t.jsx("summary",{children:a("playtest.values.showAiExample","Show AI request example")}),t.jsx("pre",{children:de})]}),t.jsxs("div",{className:s.registrationActions,children:[t.jsx("button",{type:"button",onClick:()=>void A("example",Lt),children:X==="example"?a("playtest.values.copied","Copied"):a("playtest.values.copyExample","Copy Luau example")}),t.jsx("button",{type:"button",onClick:()=>void A("ai",de),children:X==="ai"?a("playtest.values.copied","Copied"):a("playtest.values.copyAi","Copy AI request")})]}),t.jsxs("ol",{className:s.registeredSteps,"aria-label":a("playtest.values.afterRegistration","After connecting the value"),children:[t.jsx("li",{children:a("playtest.values.afterRegistrationPlay","Start a new Play or Run so WEPPY can check the connection.")}),t.jsx("li",{children:a("playtest.values.afterRegistrationAdd","Stop, return to Test Adapter, and add it to the profile.")}),t.jsx("li",{children:a("playtest.values.afterRegistrationObserve","Start Play or Run again to observe the value.")})]})]})]})]}),R&&t.jsxs("div",{className:s.pendingProfileAction,children:[t.jsx("span",{children:a("playtest.values.pendingCount","Profile changes are ready to save.")}),t.jsx("button",{type:"button",className:s.primaryAction,disabled:e.activeLease||K!==null,onClick:()=>void v(),children:e.activeLease?a("playtest.values.stopToSave","Stop Play to save"):a("playtest.profile.save","Save profile")})]}),B&&t.jsx("div",{className:s.bindingError,role:"alert",children:B})]}),t.jsx("div",{className:s.valueManagerFooter,children:t.jsx("button",{type:"button",className:s.primaryAction,disabled:K!==null||R!==null||ne.length===0,onClick:e.onClose,children:a("playtest.values.viewAdded","View added values")})})]})})}const yc=`{
|
|
121
|
-
"name": "Production",
|
|
122
|
-
"globIgnorePaths": ["src/ServerStorage/WeppyTestAdapters/**"],
|
|
123
|
-
"tree": {
|
|
124
|
-
"$className": "DataModel",
|
|
125
|
-
"ServerStorage": { "$path": "src/ServerStorage" }
|
|
126
|
-
}
|
|
127
|
-
}`;function vc(e){const{t:a}=re();return t.jsxs("section",{className:s.deploymentGuide,"aria-label":a("playtest.guide.title"),children:[t.jsxs("header",{className:s.deploymentLifecycle,children:[e.showHeading!==!1&&t.jsx("h2",{children:a("playtest.guide.title")}),t.jsx("p",{children:a("playtest.guide.runtime")}),t.jsx("p",{children:a("playtest.guide.local")}),t.jsx("p",{children:a("playtest.guide.methodIntro")}),t.jsx("p",{children:a("playtest.guide.actionEffects")})]}),e.hasManagedAdapterWithoutStudioGuard&&t.jsxs("section",{className:s.deploymentNotice,children:[t.jsx("h3",{children:a("playtest.guide.studioGuardNoticeTitle")}),t.jsx("p",{children:a("playtest.guide.studioGuardNotice")})]}),t.jsxs("section",{className:s.deploymentChecklist,"aria-labelledby":"playtest-publish-checklist-title",children:[t.jsx("h3",{id:"playtest-publish-checklist-title",children:a("playtest.guide.checklistTitle")}),t.jsxs("ul",{children:[t.jsx("li",{children:a("playtest.guide.checklistTarget")}),t.jsx("li",{children:a("playtest.guide.checklistBehavior")})]})]}),t.jsxs("div",{className:s.deploymentScope,children:[t.jsxs("section",{className:s.deploymentLifecycle,children:[t.jsx("h3",{children:a("playtest.guide.excludeTitle")}),t.jsx("p",{children:a("playtest.guide.exclude")})]}),t.jsxs("section",{className:s.deploymentLifecycle,children:[t.jsx("h3",{children:a("playtest.guide.conditionalDataTitle")}),t.jsx("p",{children:a("playtest.guide.checklistData")})]})]}),t.jsxs("section",{className:s.deploymentLifecycle,children:[t.jsx("h3",{children:a("playtest.guide.afterPublishTitle")}),t.jsx("p",{children:a("playtest.guide.final")})]}),t.jsxs("details",{className:s.deploymentDetails,children:[t.jsx("summary",{children:a("playtest.guide.studioTitle")}),t.jsx("p",{children:a("playtest.guide.include")}),t.jsx("p",{children:a("playtest.guide.studio")})]}),t.jsxs("details",{className:s.deploymentDetails,children:[t.jsx("summary",{children:a("playtest.guide.rojoTitle")}),t.jsx("p",{children:a("playtest.guide.rojo")}),t.jsx("pre",{children:yc}),t.jsx("p",{children:a("playtest.guide.rojoExample")})]}),t.jsxs("details",{className:s.deploymentDetails,children:[t.jsx("summary",{children:a("playtest.guide.dataTitle")}),t.jsx("p",{children:a("playtest.guide.data")})]}),t.jsx("p",{className:s.deploymentDescription,children:a("playtest.guide.description")})]})}function gc(e){return e.studioState==="running"?"Running":e.studioState==="paused"?"Paused":"Edit"}function bc(e,a){const n=((e==null?void 0:e.pluginClients)??[]).filter(c=>c.connectionState==="connected");let i;if(a!==null){const c=n.filter(o=>o.placeId===a);i=c.length===1?c[0]:void 0}else i=Yt(n,(e==null?void 0:e.studioRoutingMode)??"recentPriority",(e==null?void 0:e.pinnedTargetClientId)??null)[0];return i?{state:gc(i),targetClientId:i.clientId,...i.studioStateUpdatedAt!==void 0?{updatedAt:i.studioStateUpdatedAt}:{},...i.playtestMode!==void 0?{mode:i.playtestMode}:{}}:{state:"Edit",targetClientId:null}}function Mc(){var xe,Ne,Ce,p,u;const{t:e}=re(),a=Qt(),n=Xt(),{trackEvent:i}=Zt(),{tier:c,loading:o}=ea(),{level:d,status:y}=ta(),h=!o&&c==="basic",[_,N]=r.useState(null),C=Ba({enabled:!h,placeId:_}),j=bc(y,_),f=Mo({enabled:!o&&d==="studioConnected",canMutate:!h,placeId:_,studioSnapshot:j}),[$,w]=r.useState(Do),[T,S]=r.useState(!1),[F,R]=r.useState(!1),[E,K]=r.useState(!1),I=r.useRef(null),[W,Z]=r.useState(!1),{show:G}=aa(),[O,B]=r.useState(null),[L,X]=r.useState(!1),[oe,ce]=r.useState(!1);r.useEffect(()=>{const b=new URLSearchParams(a.search);if(b.get("add")!=="value")return;w("live"),R(!0),b.delete("add");const k=b.toString();n(`${a.pathname}${k?`?${k}`:""}${a.hash}`,{replace:!0})},[a.hash,a.pathname,a.search,n]);const ae=d==="studioConnected",me=ae?f.profile?f.studioState==="Edit"?e("playtest.values.playRequired","Start Play or Run in Studio to change test values."):h?e("playtest.controls.proRequired","Real-time value editing and Reset all are available with Pro."):e("playtest.controls.connectingDescription","Preparing runtime controls for the selected profile…"):e("playtest.controls.profileRequired","Select or create a test profile to change values."):e("playtest.controls.studioRequired","Connect Roblox Studio and WEPPY Plugin to change test values."),U=ae?f.studioState:"Disconnected",D=r.useRef(null),{history:ee,historyLoadState:Pe,historyError:de,selectedReport:fe,loading:pe,detailLoading:he,detailError:V}=C,te=h?Fa(e):null,se=((xe=te==null?void 0:te.history[0])==null?void 0:xe.recordId)??null,ne=(te==null?void 0:te.history)??ee,ge=te&&O===se?te.report:fe,je=h?!1:pe,Se=ne.find(b=>b.recordId===O),ke=(b,k)=>{D.current=k,B(b),!h&&C.loadReport(b)},be=r.useCallback(()=>{B(null),C.clearSelectedReport()},[C.clearSelectedReport]),_e=async()=>{ce(!0);try{await C.clearHistory(),G(e("toast.clearSuccess","Cleared successfully"),"success"),X(!1),B(null)}catch{G(e("toast.clearFailed","Failed to clear data"),"error")}finally{ce(!1)}};return t.jsxs("div",{className:s.page,children:[t.jsx(ia,{title:e("page.playtest.title","Playtest"),description:e("page.playtest.description","Review automated playtest runs, saved reports, and result history."),helpTopicId:"playtest",helpState:{tier:c},actions:t.jsx(la,{ref:I,type:"button",variant:"secondary",size:"sm",onClick:()=>K(!0),children:e("playtest.guide.open","Before publishing")})}),!o&&t.jsx(oa,{surface:"playtest",selectable:!0,selectedPlaceId:_,onSelectedPlaceIdChange:b=>{N(b),B(null),C.clearSelectedReport()}}),!o&&t.jsxs(t.Fragment,{children:[t.jsx($o,{value:$,onChange:b=>{w(b),To(b)}}),t.jsx(Vo,{lease:f.lease,profileName:(Ne=f.profile)==null?void 0:Ne.name,studioState:U,studioMode:j.mode}),h&&t.jsx(na,{title:e("playtest.upgrade.title","Real-time Playtest controls are available with Pro"),description:e("playtest.upgrade.description","Basic includes test profiles and live runtime observation. Upgrade when you need to change values during Play."),benefits:[e("playtest.upgrade.benefit1","Change test values while Studio Play is running"),e("playtest.upgrade.benefit2","Reset every override to its original value"),e("playtest.upgrade.benefit3","Review actual saved automated test results instead of sample data")],upgradeLabel:e("tier.upgrade","View Pro"),upgradeHref:sa.playtest}),f.error&&t.jsx("div",{className:s.inlineError,role:"alert",children:f.error}),$==="live"&&t.jsx(rc,{live:f,inactiveReason:me,onManageValues:()=>R(!0),onNewProfile:()=>{Z(!1),S(!0)},onEditProfile:()=>{Z(!0),S(!0)},directAddDisabledReason:ae?void 0:e("playtest.controls.studioRequired","Connect Roblox Studio and WEPPY Plugin to change test values.")})]}),$==="results"&&t.jsxs("div",{className:s.card,role:"tabpanel","aria-label":e("playtest.view.testResults","Automated Test Results"),children:[t.jsxs("div",{className:s.cardHeader,children:[t.jsx(ra,{label:e("playtest.history.title","Test History"),tooltip:e("playtest.history.title.tooltip","Recorded automated playtest runs for this project.")}),h?t.jsx(it,{text:e("playtest.sample.clearDisabled","Available with Pro for live playtest history."),children:t.jsx("span",{children:t.jsx("button",{className:s.clearButton,disabled:!0,children:e("common.clear","Clear")})})}):t.jsx("button",{className:s.clearButton,onClick:()=>{i("dashboard_click_event",{click_target:"playtest_clear_history",page:"playtest"}),X(!0)},children:e("common.clear","Clear")})]}),(h||!je&&Pe==="ready"&&ne.length===0)&&t.jsx(Ut,{kind:"no-results",isBasic:h}),!h&&Pe==="error"&&ne.length===0&&t.jsxs("div",{className:s.inlineError,role:"alert",children:[t.jsx("span",{children:de??e("playtest.emptyResults.loadFailed","Could not load test results.")}),t.jsx("button",{type:"button",className:s.secondaryAction,onClick:()=>void C.retryHistory(),children:e("common.retry","Try again")})]}),je?t.jsx("div",{className:s.emptyState,children:e("common.loading","Loading...")}):ne.length===0?null:t.jsx(So,{entries:ne,onSelect:ke,selectedRecordId:O??void 0})]}),t.jsx(Ke,{open:E,ariaLabel:e("playtest.guide.title","Publishing your game after playtesting"),onClose:()=>K(!1),returnFocusTo:I.current,children:t.jsxs("div",{className:s.detailShell,children:[t.jsx(ze,{title:e("playtest.guide.title","Publishing your game after playtesting"),description:e("playtest.guide.dialogDescription","Review what remains after testing and what to check before publishing."),closeLabel:e("common.close","Close"),onRequestClose:()=>K(!1)}),t.jsx("div",{className:s.detailBody,children:t.jsx(vc,{showHeading:!1,hasManagedAdapterWithoutStudioGuard:((Ce=f.releaseGuidance)==null?void 0:Ce.hasManagedAdapterWithoutStudioGuard)===!0})})]})}),t.jsx(Ke,{open:O!==null,ariaLabel:e("playtest.detail.dialogLabel","Playtest report detail"),onClose:be,returnFocusTo:D.current,testId:"playtest-detail-popup-layer",children:t.jsxs("div",{className:s.detailShell,children:[t.jsx(ze,{title:e("playtest.report.title","Selected Report"),description:Se==null?void 0:Se.testName,closeLabel:e("common.close","Close"),onRequestClose:be}),t.jsx("div",{className:s.detailBody,children:he?t.jsx("div",{className:s.detailState,role:"status",children:e("playtest.detail.loading","Loading report...")}):V?t.jsxs("div",{className:s.detailState,role:"alert",children:[t.jsx("div",{className:s.detailErrorTitle,children:e("playtest.detail.errorTitle","Report unavailable")}),t.jsx("div",{className:s.detailErrorMessage,children:V}),t.jsx("button",{type:"button",className:s.detailRetryButton,onClick:()=>void C.retryReport(),children:e("common.retry","Retry")})]}):ge?t.jsx(Ao,{report:ge}):t.jsx("div",{className:s.detailState,role:"status",children:e("playtest.detail.loading","Loading report...")})})]})}),!o&&t.jsxs(t.Fragment,{children:[!h&&t.jsx(mt,{open:L,title:e("playtest.clear.title","Clear test history?"),message:e("playtest.clear.message","This permanently removes the stored playtest reports for the current place."),cancelLabel:e("common.cancel","Cancel"),confirmLabel:e("common.clear","Clear"),loading:oe,onCancel:()=>!oe&&X(!1),onConfirm:_e}),t.jsx(uc,{open:T,onClose:()=>S(!1),profile:W?f.profile:null,onCreate:f.createProfile,onSave:f.saveProfile,onDelete:async(b,k)=>{const v=await f.deleteProfile(b,k);G(v.refreshFailed?e("playtest.profile.deleteRefreshFailed","Profile deleted. Reload the profile list to confirm the latest state."):e("playtest.profile.deleteSuccess","Profile deleted."),v.refreshFailed?"warning":"success")},deleteDisabledReason:((p=f.lease)==null?void 0:p.profileId)===((u=f.profile)==null?void 0:u.id)?e("playtest.profile.deleteActive","This profile is in use. Stop Play or Run in Studio before deleting it."):void 0,onResolveSelection:f.resolveSelection,onResolveSelectionCandidates:f.resolveSelectionCandidates}),t.jsx(hc,{open:F,profile:f.profile,catalog:f.catalog,activeLease:!!f.lease,onClose:()=>R(!1),onSave:f.saveProfile,onCreateProfile:f.createProfile,onResolveSelectionCandidates:f.resolveSelectionCandidates})]})]})}export{Mc as Component};
|