@hotmeshio/long-tail 0.10.7 → 0.10.8
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/build/types/index.d.ts +1 -1
- package/dashboard/dist/assets/{AdminDashboard-CYlm0_J0.js → AdminDashboard-D0HdEkT9.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-CYlm0_J0.js.map → AdminDashboard-D0HdEkT9.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-BttOMcj_.js → AgentConfigPage-CtURUMOV.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-BttOMcj_.js.map → AgentConfigPage-CtURUMOV.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-D9JdkWV8.js → AgentDetailPage-C5AnjpD9.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-D9JdkWV8.js.map → AgentDetailPage-C5AnjpD9.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-AqGtEOL1.js → AgentsPage-DBequneI.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-AqGtEOL1.js.map → AgentsPage-DBequneI.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-rKbrcY8Y.js → AvailableEscalationsPage-Bk7fFV2e.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-rKbrcY8Y.js.map → AvailableEscalationsPage-Bk7fFV2e.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-Bj4MB_so.js → BotPicker-BMXokkH7.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-Bj4MB_so.js.map → BotPicker-BMXokkH7.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-DzLP5-ad.js → CapabilitiesPage-w-D6xraE.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-DzLP5-ad.js.map → CapabilitiesPage-w-D6xraE.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-CReMhtzK.js → CollapsibleSection-IPL1H1bQ.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-CReMhtzK.js.map → CollapsibleSection-IPL1H1bQ.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-Z8N8ccJ1.js → CountdownTimer-D-CpxYDO.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-Z8N8ccJ1.js.map → CountdownTimer-D-CpxYDO.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-D_2T6vSb.js → CredentialsPage-DR48hDES.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-D_2T6vSb.js.map → CredentialsPage-DR48hDES.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DBmKrLvL.js → CronLabel-KQEj0cDS.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DBmKrLvL.js.map → CronLabel-KQEj0cDS.js.map} +1 -1
- package/dashboard/dist/assets/CustomDurationPicker-_KceggR9.js +2 -0
- package/dashboard/dist/assets/CustomDurationPicker-_KceggR9.js.map +1 -0
- package/dashboard/dist/assets/{ElapsedCell-C0LbM8o2.js → ElapsedCell-Cflz7Pb5.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-C0LbM8o2.js.map → ElapsedCell-Cflz7Pb5.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CkEJnFKd.js → EscalationListSchemaPage-BTBZ8OBY.js} +2 -2
- package/dashboard/dist/assets/{EscalationListSchemaPage-CkEJnFKd.js.map → EscalationListSchemaPage-BTBZ8OBY.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-CnlwGAIE.js → EscalationSchemaPage-Cd9fR2EA.js} +2 -2
- package/dashboard/dist/assets/{EscalationSchemaPage-CnlwGAIE.js.map → EscalationSchemaPage-Cd9fR2EA.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-DFM-f7do.js → EscalationsOverview-BzNFcA0i.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-DFM-f7do.js.map → EscalationsOverview-BzNFcA0i.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-Q3iICRf_.js → EventTable-S2BJqOt2.js} +2 -2
- package/dashboard/dist/assets/{EventTable-Q3iICRf_.js.map → EventTable-S2BJqOt2.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-B0taDH7I.js → FilterBar-CeXwNVn6.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-B0taDH7I.js.map → FilterBar-CeXwNVn6.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-B_P3pJeA.js → GraphInvokePage-CBjXjOLX.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-B_P3pJeA.js.map → GraphInvokePage-CBjXjOLX.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-lu88PzQH.js → HomePage-NMLaXTvf.js} +2 -2
- package/dashboard/dist/assets/{HomePage-lu88PzQH.js.map → HomePage-NMLaXTvf.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-ueCQtu5C.js → ListToolbar-Dx6DuFdR.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-ueCQtu5C.js.map → ListToolbar-Dx6DuFdR.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-DMaRUXnA.js → McpOverview-Cj8_UyWJ.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-DMaRUXnA.js.map → McpOverview-Cj8_UyWJ.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-D6YSD94n.js → McpQueryDetailPage-Bqh8GChr.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-D6YSD94n.js.map → McpQueryDetailPage-Bqh8GChr.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-CNGNB59o.js → McpQueryPage-CqFkBwBR.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-CNGNB59o.js.map → McpQueryPage-CqFkBwBR.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-CJ9hDTNs.js → McpRunDetailPage-BqhRwkGk.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-CJ9hDTNs.js.map → McpRunDetailPage-BqhRwkGk.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-_UaoIwzX.js → McpRunsPage-CNXYU4iX.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-_UaoIwzX.js.map → McpRunsPage-CNXYU4iX.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-C7UB_d-X.js +2 -0
- package/dashboard/dist/assets/OperationsPage-C7UB_d-X.js.map +1 -0
- package/dashboard/dist/assets/OperatorDashboard-DwbPAPaf.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-DwbPAPaf.js.map +1 -0
- package/dashboard/dist/assets/{ProcessDetailPage-CxJ5BSDk.js → ProcessDetailPage-ChGWcwSp.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-CxJ5BSDk.js.map → ProcessDetailPage-ChGWcwSp.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-GQMOo5Wo.js → ProcessesListPage-DatKHVkd.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-GQMOo5Wo.js.map → ProcessesListPage-DatKHVkd.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-Bh5qdI0w.js → RoleDetailPage-GJ_coHsM.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-Bh5qdI0w.js.map → RoleDetailPage-GJ_coHsM.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-BIg3_Em6.js → RolesPage-CPKw336d.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-BIg3_Em6.js.map → RolesPage-CPKw336d.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-DQp_keSD.js → RunAsSelector-VbBn0o7s.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-DQp_keSD.js.map → RunAsSelector-VbBn0o7s.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-qLaLa33X.js → StickyPagination-BI8tDf2V.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-qLaLa33X.js.map → StickyPagination-BI8tDf2V.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-Bi37x95H.js → StreamMessageDetail-BObbEz7P.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-Bi37x95H.js.map → StreamMessageDetail-BObbEz7P.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BdNhoiW8.js → SwimlaneTimeline-BHjAtOGC.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BdNhoiW8.js.map → SwimlaneTimeline-BHjAtOGC.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-ngdXRgQp.js → TaskDetailPage-B-E1dqUw.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-ngdXRgQp.js.map → TaskDetailPage-B-E1dqUw.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-BIE7nrdE.js → TasksListPage-urJ4XiUi.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-BIE7nrdE.js.map → TasksListPage-urJ4XiUi.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-C6FZSNZp.js → TimeAgo-D6Dg0SQs.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-C6FZSNZp.js.map → TimeAgo-D6Dg0SQs.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DI5zPUgV.js → TimestampCell-DG__Gr-e.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DI5zPUgV.js.map → TimestampCell-DG__Gr-e.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-Dli94RPI.js → ToolTestPanel-D-hGLf95.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-Dli94RPI.js.map → ToolTestPanel-D-hGLf95.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-vPtXb7gD.js → TopicDetailPage-B10i4xV2.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-vPtXb7gD.js.map → TopicDetailPage-B10i4xV2.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-BwiEX0pU.js → TopicsPage-C5THflVQ.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-BwiEX0pU.js.map → TopicsPage-C5THflVQ.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-YozoXJA1.js → UserName-CZTpouta.js} +2 -2
- package/dashboard/dist/assets/{UserName-YozoXJA1.js.map → UserName-CZTpouta.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-Bce8g08l.js → WorkflowExecutionPage-mbnj6saI.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-Bce8g08l.js.map → WorkflowExecutionPage-mbnj6saI.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DpVAH35I.js → WorkflowsDashboard-DC_9GrpY.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DpVAH35I.js.map → WorkflowsDashboard-DC_9GrpY.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-Bp2pxXJO.js → WorkflowsOverview-ClSH1UwG.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-Bp2pxXJO.js.map → WorkflowsOverview-ClSH1UwG.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CL_kD0mX.js → YamlWorkflowDetailPage-BkgoB7oD.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CL_kD0mX.js.map → YamlWorkflowDetailPage-BkgoB7oD.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-Dtt3x3_T.js → YamlWorkflowsPage-Db_REA2f.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-Dtt3x3_T.js.map → YamlWorkflowsPage-Db_REA2f.js.map} +1 -1
- package/dashboard/dist/assets/{agents-xhtLVBwq.js → agents-Dvb8j9AB.js} +2 -2
- package/dashboard/dist/assets/{agents-xhtLVBwq.js.map → agents-Dvb8j9AB.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DZ1MQUms.js → bots-D9jYHjBM.js} +2 -2
- package/dashboard/dist/assets/{bots-DZ1MQUms.js.map → bots-D9jYHjBM.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-B8j2h7Jn.js → capabilities-BAto9JcQ.js} +2 -2
- package/dashboard/dist/assets/{capabilities-B8j2h7Jn.js.map → capabilities-BAto9JcQ.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-DKijNA6h.js → controlplane-2Aic2Tfm.js} +2 -2
- package/dashboard/dist/assets/{controlplane-DKijNA6h.js.map → controlplane-2Aic2Tfm.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-DjoZ4dDb.js → escalation-columns-DPKPJtw3.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-DjoZ4dDb.js.map → escalation-columns-DPKPJtw3.js.map} +1 -1
- package/dashboard/dist/assets/{index-DrPWIFSv.js → index-4zRmxPwA.js} +2 -2
- package/dashboard/dist/assets/{index-DrPWIFSv.js.map → index-4zRmxPwA.js.map} +1 -1
- package/dashboard/dist/assets/{index-BqeQGQ4K.js → index-B5JgykZD.js} +2 -2
- package/dashboard/dist/assets/{index-BqeQGQ4K.js.map → index-B5JgykZD.js.map} +1 -1
- package/dashboard/dist/assets/{index-BCIJE--_.js → index-BW7-Q9Qf.js} +2 -2
- package/dashboard/dist/assets/{index-BCIJE--_.js.map → index-BW7-Q9Qf.js.map} +1 -1
- package/dashboard/dist/assets/{index-DYCCUmSM.js → index-BZbDwh_Y.js} +2 -2
- package/dashboard/dist/assets/{index-DYCCUmSM.js.map → index-BZbDwh_Y.js.map} +1 -1
- package/dashboard/dist/assets/{index-CMv6YMJY.js → index-BzQIzZfd.js} +2 -2
- package/dashboard/dist/assets/{index-CMv6YMJY.js.map → index-BzQIzZfd.js.map} +1 -1
- package/dashboard/dist/assets/{index-DcDEJ6b_.js → index-C-T1Wq0Z.js} +2 -2
- package/dashboard/dist/assets/{index-DcDEJ6b_.js.map → index-C-T1Wq0Z.js.map} +1 -1
- package/dashboard/dist/assets/{index-C6UuVkz7.js → index-CKxFjMtw.js} +4 -4
- package/dashboard/dist/assets/{index-C6UuVkz7.js.map → index-CKxFjMtw.js.map} +1 -1
- package/dashboard/dist/assets/{index-0SzWFShg.js → index-CeM012DJ.js} +2 -2
- package/dashboard/dist/assets/{index-0SzWFShg.js.map → index-CeM012DJ.js.map} +1 -1
- package/dashboard/dist/assets/{index-ChHD9p_I.js → index-KkikDsJ2.js} +2 -2
- package/dashboard/dist/assets/{index-ChHD9p_I.js.map → index-KkikDsJ2.js.map} +1 -1
- package/dashboard/dist/assets/index-Pmvw74oY.css +1 -0
- package/dashboard/dist/assets/{index-B0ktIiOY.js → index-_Q1Wf2A8.js} +2 -2
- package/dashboard/dist/assets/{index-B0ktIiOY.js.map → index-_Q1Wf2A8.js.map} +1 -1
- package/dashboard/dist/assets/index-jkVeGCkD.js +5 -0
- package/dashboard/dist/assets/index-jkVeGCkD.js.map +1 -0
- package/dashboard/dist/assets/{index-Cp1jJHm1.js → index-oHU-ramT.js} +2 -2
- package/dashboard/dist/assets/{index-Cp1jJHm1.js.map → index-oHU-ramT.js.map} +1 -1
- package/dashboard/dist/assets/{index-DWDEa8jS.js → index-peRHL38z.js} +2 -2
- package/dashboard/dist/assets/{index-DWDEa8jS.js.map → index-peRHL38z.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-Dl3cOfFR.js → knowledge-DO8idX0e.js} +2 -2
- package/dashboard/dist/assets/{knowledge-Dl3cOfFR.js.map → knowledge-DO8idX0e.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-BwjeqkHn.js → mcp-BGpQlkFp.js} +2 -2
- package/dashboard/dist/assets/{mcp-BwjeqkHn.js.map → mcp-BGpQlkFp.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-C1Rlt4az.js → mcp-query-DT0SCB9l.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-C1Rlt4az.js.map → mcp-query-DT0SCB9l.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-BGIUgIH_.js → pipelines-CYk7cN6-.js} +2 -2
- package/dashboard/dist/assets/{pipelines-BGIUgIH_.js.map → pipelines-CYk7cN6-.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CnC1xEaD.js → tasks-B4Y5xbF0.js} +2 -2
- package/dashboard/dist/assets/{tasks-CnC1xEaD.js.map → tasks-B4Y5xbF0.js.map} +1 -1
- package/dashboard/dist/assets/{topics-C6EcHi07.js → topics-CVnqDw3B.js} +2 -2
- package/dashboard/dist/assets/{topics-C6EcHi07.js.map → topics-CVnqDw3B.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-Cyq4DiQA.js → useEventHooks-D8bVEx-w.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-Cyq4DiQA.js.map → useEventHooks-D8bVEx-w.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-Ci_oA5Tq.js → useNamespace-B1t3hsGf.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-Ci_oA5Tq.js.map → useNamespace-B1t3hsGf.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-u8RUiMma.js → useYamlActivityEvents-B8Ru07xQ.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-u8RUiMma.js.map → useYamlActivityEvents-B8Ru07xQ.js.map} +1 -1
- package/dashboard/dist/assets/{users-DtiYvg8z.js → users-C8H4jjTq.js} +2 -2
- package/dashboard/dist/assets/{users-DtiYvg8z.js.map → users-C8H4jjTq.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-BysPDsh9.js → workflows-BAdI5k--.js} +2 -2
- package/dashboard/dist/assets/{workflows-BysPDsh9.js.map → workflows-BAdI5k--.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-31qtxg5W.js → yaml-workflows-Bf2aQS-M.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-31qtxg5W.js.map → yaml-workflows-Bf2aQS-M.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/http/escalations.md +1 -1
- package/docs/hitl/escalation.md +1 -1
- package/docs/hitl/x-lt-embed.md +41 -12
- package/docs/hitl/x-lt-list-schema.md +15 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/CustomDurationPicker-BTmpAQOL.js +0 -2
- package/dashboard/dist/assets/CustomDurationPicker-BTmpAQOL.js.map +0 -1
- package/dashboard/dist/assets/OperationsPage-CTfwuWXR.js +0 -2
- package/dashboard/dist/assets/OperationsPage-CTfwuWXR.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-DMPJmgP_.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-DMPJmgP_.js.map +0 -1
- package/dashboard/dist/assets/index-Dh5Y3hq7.js +0 -5
- package/dashboard/dist/assets/index-Dh5Y3hq7.js.map +0 -1
- package/dashboard/dist/assets/index-WSGppNeK.css +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as o,b as t,c as n}from"./vendor-query-B2UbickB.js";import{d as u}from"./index-
|
|
2
|
-
//# sourceMappingURL=users-
|
|
1
|
+
import{u as o,b as t,c as n}from"./vendor-query-B2UbickB.js";import{d as u}from"./index-CKxFjMtw.js";function d(e={}){const s=new URLSearchParams;return e.role&&s.set("role",e.role),e.roleType&&s.set("roleType",e.roleType),e.status&&s.set("status",e.status),e.search&&s.set("search",e.search),e.limit&&s.set("limit",String(e.limit)),e.offset!==void 0&&s.set("offset",String(e.offset)),o({queryKey:["users",e],queryFn:()=>u(`/users?${s}`)})}function l(e){return o({queryKey:["users",e],queryFn:()=>u(`/users/${e}`),enabled:!!e})}function q(){const e=t();return n({mutationFn:s=>u("/users",{method:"POST",body:JSON.stringify(s)}),onSuccess:()=>{e.invalidateQueries({queryKey:["users"]})}})}function f(){const e=t();return n({mutationFn:({id:s,...r})=>u(`/users/${s}`,{method:"PUT",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:["users"]})}})}function S(){const e=t();return n({mutationFn:s=>u(`/users/${s}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:["users"]})}})}function U(){const e=t();return n({mutationFn:({userId:s,role:r,type:i,read_scope:a,write_scope:y})=>u(`/users/${s}/roles`,{method:"POST",body:JSON.stringify({role:r,type:i,read_scope:a,write_scope:y})}),onSuccess:()=>{e.invalidateQueries({queryKey:["users"]})}})}function h(){const e=t();return n({mutationFn:({userId:s,role:r})=>u(`/users/${s}/roles/${encodeURIComponent(r)}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:["users"]})}})}export{l as a,q as b,f as c,U as d,h as e,S as f,d as u};
|
|
2
|
+
//# sourceMappingURL=users-C8H4jjTq.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users-
|
|
1
|
+
{"version":3,"file":"users-C8H4jjTq.js","sources":["../../src/api/users.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { LTUserRecord, LTRoleType, LTReadScope, LTWriteScope } from './types';\n\ninterface UserListResponse {\n users: LTUserRecord[];\n total: number;\n}\n\ninterface UserFilters {\n role?: string;\n roleType?: string;\n status?: string;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport function useUsers(filters: UserFilters = {}) {\n const params = new URLSearchParams();\n if (filters.role) params.set('role', filters.role);\n if (filters.roleType) params.set('roleType', filters.roleType);\n if (filters.status) params.set('status', filters.status);\n if (filters.search) params.set('search', filters.search);\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n\n return useQuery<UserListResponse>({\n queryKey: ['users', filters],\n queryFn: () => apiFetch(`/users?${params}`),\n });\n}\n\nexport function useUser(id: string) {\n return useQuery<LTUserRecord>({\n queryKey: ['users', id],\n queryFn: () => apiFetch(`/users/${id}`),\n enabled: !!id,\n });\n}\n\nexport function useCreateUser() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (data: {\n external_id: string;\n email?: string;\n display_name?: string;\n password?: string;\n roles?: { role: string; type: LTRoleType }[];\n }) =>\n apiFetch('/users', {\n method: 'POST',\n body: JSON.stringify(data),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['users'] });\n },\n });\n}\n\nexport function useUpdateUser() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n id,\n ...data\n }: {\n id: string;\n email?: string;\n display_name?: string;\n status?: string;\n }) =>\n apiFetch(`/users/${id}`, {\n method: 'PUT',\n body: JSON.stringify(data),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['users'] });\n },\n });\n}\n\nexport function useDeleteUser() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch(`/users/${id}`, { method: 'DELETE' }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['users'] });\n },\n });\n}\n\nexport function useAddUserRole() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n userId,\n role,\n type,\n read_scope,\n write_scope,\n }: {\n userId: string;\n role: string;\n type: LTRoleType;\n read_scope?: LTReadScope;\n write_scope?: LTWriteScope;\n }) =>\n apiFetch(`/users/${userId}/roles`, {\n method: 'POST',\n body: JSON.stringify({ role, type, read_scope, write_scope }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['users'] });\n },\n });\n}\n\nexport function useRemoveUserRole() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ userId, role }: { userId: string; role: string }) =>\n apiFetch(`/users/${userId}/roles/${encodeURIComponent(role)}`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['users'] });\n },\n });\n}\n"],"names":["useUsers","filters","params","useQuery","apiFetch","useUser","id","useCreateUser","queryClient","useQueryClient","useMutation","data","useUpdateUser","useDeleteUser","useAddUserRole","userId","role","type","read_scope","write_scope","useRemoveUserRole"],"mappings":"qGAkBO,SAASA,EAASC,EAAuB,GAAI,CAClD,MAAMC,EAAS,IAAI,gBACnB,OAAID,EAAQ,MAAMC,EAAO,IAAI,OAAQD,EAAQ,IAAI,EAC7CA,EAAQ,UAAUC,EAAO,IAAI,WAAYD,EAAQ,QAAQ,EACzDA,EAAQ,QAAQC,EAAO,IAAI,SAAUD,EAAQ,MAAM,EACnDA,EAAQ,QAAQC,EAAO,IAAI,SAAUD,EAAQ,MAAM,EACnDA,EAAQ,OAAOC,EAAO,IAAI,QAAS,OAAOD,EAAQ,KAAK,CAAC,EACxDA,EAAQ,SAAW,QAAWC,EAAO,IAAI,SAAU,OAAOD,EAAQ,MAAM,CAAC,EAEtEE,EAA2B,CAChC,SAAU,CAAC,QAASF,CAAO,EAC3B,QAAS,IAAMG,EAAS,UAAUF,CAAM,EAAE,CAAA,CAC3C,CACH,CAEO,SAASG,EAAQC,EAAY,CAClC,OAAOH,EAAuB,CAC5B,SAAU,CAAC,QAASG,CAAE,EACtB,QAAS,IAAMF,EAAS,UAAUE,CAAE,EAAE,EACtC,QAAS,CAAC,CAACA,CAAA,CACZ,CACH,CAEO,SAASC,GAAgB,CAC9B,MAAMC,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAaC,GAOXP,EAAS,SAAU,CACjB,OAAQ,OACR,KAAM,KAAK,UAAUO,CAAI,CAAA,CAC1B,EACH,UAAW,IAAM,CACfH,EAAY,kBAAkB,CAAE,SAAU,CAAC,OAAO,EAAG,CACvD,CAAA,CACD,CACH,CAEO,SAASI,GAAgB,CAC9B,MAAMJ,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAY,CAAC,CACX,GAAAJ,EACA,GAAGK,CAAA,IAOHP,EAAS,UAAUE,CAAE,GAAI,CACvB,OAAQ,MACR,KAAM,KAAK,UAAUK,CAAI,CAAA,CAC1B,EACH,UAAW,IAAM,CACfH,EAAY,kBAAkB,CAAE,SAAU,CAAC,OAAO,EAAG,CACvD,CAAA,CACD,CACH,CAEO,SAASK,GAAgB,CAC9B,MAAML,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAaJ,GACXF,EAAS,UAAUE,CAAE,GAAI,CAAE,OAAQ,SAAU,EAC/C,UAAW,IAAM,CACfE,EAAY,kBAAkB,CAAE,SAAU,CAAC,OAAO,EAAG,CACvD,CAAA,CACD,CACH,CAEO,SAASM,GAAiB,CAC/B,MAAMN,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAY,CAAC,CACX,OAAAK,EACA,KAAAC,EACA,KAAAC,EACA,WAAAC,EACA,YAAAC,CAAA,IAQAf,EAAS,UAAUW,CAAM,SAAU,CACjC,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,KAAAC,EAAM,KAAAC,EAAM,WAAAC,EAAY,YAAAC,EAAa,CAAA,CAC7D,EACH,UAAW,IAAM,CACfX,EAAY,kBAAkB,CAAE,SAAU,CAAC,OAAO,EAAG,CACvD,CAAA,CACD,CACH,CAEO,SAASY,GAAoB,CAClC,MAAMZ,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAY,CAAC,CAAE,OAAAK,EAAQ,KAAAC,CAAA,IACrBZ,EAAS,UAAUW,CAAM,UAAU,mBAAmBC,CAAI,CAAC,GAAI,CAC7D,OAAQ,QAAA,CACT,EACH,UAAW,IAAM,CACfR,EAAY,kBAAkB,CAAE,SAAU,CAAC,OAAO,EAAG,CACvD,CAAA,CACD,CACH"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as n,b as t,c as u}from"./vendor-query-B2UbickB.js";import{d as s}from"./index-
|
|
2
|
-
//# sourceMappingURL=workflows-
|
|
1
|
+
import{u as n,b as t,c as u}from"./vendor-query-B2UbickB.js";import{d as s}from"./index-CKxFjMtw.js";function f(){return n({queryKey:["activeWorkers"],queryFn:async()=>(await s("/workflows/workers")).workers})}function w(){return n({queryKey:["discoveredWorkflows"],queryFn:async()=>(await s("/workflows/discovered")).workflows})}function l(){return n({queryKey:["workflowConfigs"],queryFn:async()=>(await s("/workflows/config")).workflows})}function d(){return n({queryKey:["cronStatus"],queryFn:async()=>(await s("/workflows/cron/status")).schedules})}function k(e){return n({queryKey:["workflowExecution",e],queryFn:()=>s(`/workflow-states/${e}/execution`),enabled:!!e})}function m(e,o){const r=new URLSearchParams;return e.limit&&r.set("limit",String(e.limit)),e.offset!==void 0&&r.set("offset",String(e.offset)),e.entity&&r.set("entity",e.entity),e.search&&r.set("search",e.search),e.status&&r.set("status",e.status),e.sort_by&&r.set("sort_by",e.sort_by),e.order&&r.set("order",e.order),e.registered&&r.set("registered",e.registered),e.namespace&&r.set("namespace",e.namespace),n({queryKey:["jobs",e],queryFn:()=>s(`/workflow-states/jobs?${r}`),enabled:(o==null?void 0:o.enabled)??!0})}function q(){const e=t();return u({mutationFn:o=>s(`/workflows/${o}/terminate`,{method:"POST"}),onSuccess:(o,r)=>{e.invalidateQueries({queryKey:["workflowExecution",r],refetchType:"all"}),e.invalidateQueries({queryKey:["jobs"],refetchType:"all"})}})}function g(){const e=t();return u({mutationFn:({workflow_type:o,...r})=>s(`/workflows/${encodeURIComponent(o)}/config`,{method:"PUT",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:["workflowConfigs"],refetchType:"all"})}})}function h(){const e=t();return u({mutationFn:o=>s(`/workflows/${encodeURIComponent(o)}/config`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:["workflowConfigs"],refetchType:"all"})}})}function b(){const e=t();return u({mutationFn:({workflowType:o,data:r,metadata:i,execute_as:a})=>s(`/workflows/${o}/invoke`,{method:"POST",body:JSON.stringify({data:r,metadata:i,...a?{execute_as:a}:{}})}),onSuccess:()=>{e.invalidateQueries({queryKey:["tasks"],refetchType:"all"}),e.invalidateQueries({queryKey:["jobs"],refetchType:"all"})}})}export{k as a,m as b,b as c,w as d,d as e,q as f,f as g,h,g as i,l as u};
|
|
2
|
+
//# sourceMappingURL=workflows-BAdI5k--.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflows-
|
|
1
|
+
{"version":3,"file":"workflows-BAdI5k--.js","sources":["../../src/api/workflows.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { ActiveWorker, CronScheduleEntry, DiscoveredWorkflow, LTJob, LTWorkflowConfig, WorkflowExecution } from './types';\n\nexport function useActiveWorkers() {\n return useQuery<ActiveWorker[]>({\n queryKey: ['activeWorkers'],\n queryFn: async () => {\n const res = await apiFetch<{ workers: ActiveWorker[] }>('/workflows/workers');\n return res.workers;\n },\n });\n}\n\nexport function useDiscoveredWorkflows() {\n return useQuery<DiscoveredWorkflow[]>({\n queryKey: ['discoveredWorkflows'],\n queryFn: async () => {\n const res = await apiFetch<{ workflows: DiscoveredWorkflow[] }>('/workflows/discovered');\n return res.workflows;\n },\n });\n}\n\nexport function useWorkflowConfigs() {\n return useQuery<LTWorkflowConfig[]>({\n queryKey: ['workflowConfigs'],\n queryFn: async () => {\n const res = await apiFetch<{ workflows: LTWorkflowConfig[] }>('/workflows/config');\n return res.workflows;\n },\n });\n}\n\nexport function useCronStatus() {\n return useQuery<CronScheduleEntry[]>({\n queryKey: ['cronStatus'],\n queryFn: async () => {\n const res = await apiFetch<{ schedules: CronScheduleEntry[] }>('/workflows/cron/status');\n return res.schedules;\n },\n });\n}\n\nexport function useWorkflowExecution(workflowId: string) {\n return useQuery<WorkflowExecution>({\n queryKey: ['workflowExecution', workflowId],\n queryFn: () =>\n apiFetch(`/workflow-states/${workflowId}/execution`),\n enabled: !!workflowId,\n });\n}\n\nexport function useWorkflowState(workflowId: string) {\n return useQuery<{ workflow_id: string; state: Record<string, unknown> }>({\n queryKey: ['workflowState', workflowId],\n queryFn: () => apiFetch(`/workflow-states/${workflowId}/state`),\n enabled: !!workflowId,\n });\n}\n\nexport function useJobs(filters: {\n limit?: number;\n offset?: number;\n entity?: string;\n search?: string;\n status?: string;\n sort_by?: string;\n order?: string;\n registered?: string;\n namespace?: string;\n}, options?: { enabled?: boolean }) {\n const params = new URLSearchParams();\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n if (filters.entity) params.set('entity', filters.entity);\n if (filters.search) params.set('search', filters.search);\n if (filters.status) params.set('status', filters.status);\n if (filters.sort_by) params.set('sort_by', filters.sort_by);\n if (filters.order) params.set('order', filters.order);\n if (filters.registered) params.set('registered', filters.registered);\n if (filters.namespace) params.set('namespace', filters.namespace);\n\n return useQuery<{ jobs: LTJob[]; total: number }>({\n queryKey: ['jobs', filters],\n queryFn: () => apiFetch(`/workflow-states/jobs?${params}`),\n enabled: options?.enabled ?? true,\n });\n}\n\nexport function useTerminateWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (workflowId: string) =>\n apiFetch(`/workflows/${workflowId}/terminate`, { method: 'POST' }),\n onSuccess: (_data, workflowId) => {\n queryClient.invalidateQueries({ queryKey: ['workflowExecution', workflowId], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['jobs'], refetchType: 'all' });\n },\n });\n}\n\nexport function useUpsertWorkflowConfig() {\n const queryClient = useQueryClient();\n return useMutation<\n LTWorkflowConfig,\n Error,\n {\n workflow_type: string;\n description?: string | null;\n\n invocable?: boolean;\n certified?: boolean;\n task_queue?: string | null;\n default_role?: string;\n roles?: string[];\n invocation_roles?: string[];\n consumes?: string[];\n envelope_schema?: Record<string, unknown> | null;\n resolver_schema?: Record<string, unknown> | null;\n cron_schedule?: string | null;\n execute_as?: string | null;\n }\n >({\n mutationFn: ({ workflow_type, ...body }) =>\n apiFetch(`/workflows/${encodeURIComponent(workflow_type)}/config`, {\n method: 'PUT',\n body: JSON.stringify(body),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['workflowConfigs'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeleteWorkflowConfig() {\n const queryClient = useQueryClient();\n return useMutation<{ deleted: boolean; workflow_type: string }, Error, string>({\n mutationFn: (workflowType) =>\n apiFetch(`/workflows/${encodeURIComponent(workflowType)}/config`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['workflowConfigs'], refetchType: 'all' });\n },\n });\n}\n\nexport function useSetCronSchedule() {\n const queryClient = useQueryClient();\n return useMutation<\n LTWorkflowConfig,\n Error,\n { config: LTWorkflowConfig; cron_schedule: string | null; envelope_schema?: Record<string, unknown> | null }\n >({\n mutationFn: ({ config, cron_schedule, envelope_schema }) =>\n apiFetch(`/workflows/${encodeURIComponent(config.workflow_type)}/config`, {\n method: 'PUT',\n body: JSON.stringify({\n ...config,\n cron_schedule,\n ...(envelope_schema !== undefined ? { envelope_schema } : {}),\n }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['workflowConfigs'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['cronStatus'], refetchType: 'all' });\n },\n });\n}\n\nexport function useInvokeWorkflow() {\n const queryClient = useQueryClient();\n return useMutation<\n { workflowId: string; message: string },\n Error,\n { workflowType: string; data: Record<string, unknown>; metadata?: Record<string, unknown>; execute_as?: string }\n >({\n mutationFn: ({ workflowType, data, metadata, execute_as }) =>\n apiFetch(`/workflows/${workflowType}/invoke`, {\n method: 'POST',\n body: JSON.stringify({ data, metadata, ...(execute_as ? { execute_as } : {}) }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['tasks'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['jobs'], refetchType: 'all' });\n },\n });\n}\n"],"names":["useActiveWorkers","useQuery","apiFetch","useDiscoveredWorkflows","useWorkflowConfigs","useCronStatus","useWorkflowExecution","workflowId","useJobs","filters","options","params","useTerminateWorkflow","queryClient","useQueryClient","useMutation","_data","useUpsertWorkflowConfig","workflow_type","body","useDeleteWorkflowConfig","workflowType","useInvokeWorkflow","data","metadata","execute_as"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as l,b as a,c as s}from"./vendor-query-B2UbickB.js";import{d as r}from"./index-
|
|
2
|
-
//# sourceMappingURL=yaml-workflows-
|
|
1
|
+
import{u as l,b as a,c as s}from"./vendor-query-B2UbickB.js";import{d as r}from"./index-CKxFjMtw.js";function f(e={}){const o=new URLSearchParams;return e.status&&o.set("status",e.status),e.graph_topic&&o.set("graph_topic",e.graph_topic),e.app_id&&o.set("app_id",e.app_id),e.search&&o.set("search",e.search),e.set_id&&o.set("set_id",e.set_id),e.limit&&o.set("limit",String(e.limit)),e.offset!==void 0&&o.set("offset",String(e.offset)),l({queryKey:["yamlWorkflows",e],queryFn:()=>r(`/yaml-workflows?${o}`)})}function m(){return l({queryKey:["yamlWorkflowAppIds"],queryFn:()=>r("/yaml-workflows/app-ids")})}function c(e){return l({queryKey:["yamlWorkflows",e],queryFn:()=>r(`/yaml-workflows/${e}`),enabled:!!e})}function w(){const e=a();return s({mutationFn:o=>r("/yaml-workflows",{method:"POST",body:JSON.stringify(o)}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function k(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/deploy`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function p(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/activate`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function d(){const e=a();return s({mutationFn:({id:o,data:t,sync:n,execute_as:u})=>r(`/yaml-workflows/${o}/invoke`,{method:"POST",body:JSON.stringify({data:t,sync:n,...u?{execute_as:u}:{}})}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function h(){const e=a();return s({mutationFn:({id:o,task_queue:t,compilation_feedback:n})=>r(`/yaml-workflows/${o}/regenerate`,{method:"POST",body:JSON.stringify({task_queue:t,compilation_feedback:n})}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function q(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/archive`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function W(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/restore`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"}),e.invalidateQueries({queryKey:["yamlWorkflow"],refetchType:"all"})}})}function S(){const e=a();return s({mutationFn:({id:o,...t})=>r(`/yaml-workflows/${o}`,{method:"PUT",body:JSON.stringify(t)}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function v(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function T(e){return l({queryKey:["yamlWorkflows",e,"versions"],queryFn:()=>r(`/yaml-workflows/${e}/versions`),enabled:!!e})}function F(e,o){return l({queryKey:["yamlWorkflows",e,"versions",o],queryFn:()=>r(`/yaml-workflows/${e}/versions/${o}`),enabled:!!e&&o!==null})}export{m as a,S as b,c,T as d,k as e,p as f,q as g,W as h,v as i,h as j,F as k,d as l,w as m,f as u};
|
|
2
|
+
//# sourceMappingURL=yaml-workflows-Bf2aQS-M.js.map
|
package/dashboard/dist/assets/{yaml-workflows-31qtxg5W.js.map → yaml-workflows-Bf2aQS-M.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml-workflows-31qtxg5W.js","sources":["../../src/api/yaml-workflows.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { LTYamlWorkflowRecord, LTYamlWorkflowStatus, LTYamlWorkflowVersion } from './types';\n\ninterface YamlWorkflowListResponse {\n workflows: LTYamlWorkflowRecord[];\n total: number;\n}\n\ninterface YamlWorkflowFilters {\n status?: LTYamlWorkflowStatus;\n graph_topic?: string;\n app_id?: string;\n search?: string;\n set_id?: string;\n limit?: number;\n offset?: number;\n}\n\nexport function useYamlWorkflows(filters: YamlWorkflowFilters = {}) {\n const params = new URLSearchParams();\n if (filters.status) params.set('status', filters.status);\n if (filters.graph_topic) params.set('graph_topic', filters.graph_topic);\n if (filters.app_id) params.set('app_id', filters.app_id);\n if (filters.search) params.set('search', filters.search);\n if (filters.set_id) params.set('set_id', filters.set_id);\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', filters],\n queryFn: () => apiFetch(`/yaml-workflows?${params}`),\n });\n}\n\nexport function useYamlWorkflowAppIds() {\n return useQuery<{ app_ids: string[] }>({\n queryKey: ['yamlWorkflowAppIds'],\n queryFn: () => apiFetch('/yaml-workflows/app-ids'),\n });\n}\n\nexport function useYamlWorkflowByTopic(graphTopic: string | undefined, appId?: string) {\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', 'byTopic', graphTopic, appId],\n queryFn: () => {\n const params = new URLSearchParams({ graph_topic: graphTopic!, limit: '1' });\n if (appId) params.set('app_id', appId);\n return apiFetch(`/yaml-workflows?${params}`);\n },\n enabled: !!graphTopic,\n });\n}\n\nexport function useYamlWorkflow(id: string) {\n return useQuery<LTYamlWorkflowRecord>({\n queryKey: ['yamlWorkflows', id],\n queryFn: () => apiFetch(`/yaml-workflows/${id}`),\n enabled: !!id,\n });\n}\n\nexport function useCreateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (input: {\n workflow_id: string;\n task_queue: string;\n workflow_name: string;\n name: string;\n description?: string;\n app_id?: string;\n subscribes?: string;\n tags?: string[];\n compilation_feedback?: string;\n }) =>\n apiFetch<LTYamlWorkflowRecord>('/yaml-workflows', {\n method: 'POST',\n body: JSON.stringify(input),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeployYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/deploy`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useActivateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/activate`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useInvokeYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data, sync, execute_as }: { id: string; data: Record<string, unknown>; sync?: boolean; execute_as?: string }) =>\n apiFetch<{ result?: unknown; job_id?: string }>(`/yaml-workflows/${id}/invoke`, {\n method: 'POST',\n body: JSON.stringify({ data, sync, ...(execute_as ? { execute_as } : {}) }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRegenerateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, task_queue, compilation_feedback }: { id: string; task_queue?: string; compilation_feedback?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/regenerate`, {\n method: 'POST',\n body: JSON.stringify({ task_queue, compilation_feedback }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useArchiveYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/archive`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRestoreYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/restore`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflow'], refetchType: 'all' });\n },\n });\n}\n\nexport function useUpdateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, ...updates }: { id: string; yaml_content?: string; name?: string; description?: string; input_schema?: Record<string, unknown>; output_schema?: Record<string, unknown>; tags?: string[]; app_id?: string; graph_topic?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}`, {\n method: 'PUT',\n body: JSON.stringify(updates),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeleteYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<{ deleted: boolean }>(`/yaml-workflows/${id}`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Cron scheduling ─────────────────────────────────────────────\n\nexport function useSetYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, cron_schedule, cron_envelope, execute_as }: {\n id: string;\n cron_schedule: string;\n cron_envelope?: Record<string, unknown> | null;\n execute_as?: string | null;\n }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'PUT',\n body: JSON.stringify({ cron_schedule, cron_envelope, execute_as }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useClearYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Version history ─────────────────────────────────────────────\n\nexport function useYamlWorkflowVersions(id: string) {\n return useQuery<{ versions: LTYamlWorkflowVersion[]; total: number }>({\n queryKey: ['yamlWorkflows', id, 'versions'],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions`),\n enabled: !!id,\n });\n}\n\nexport function useYamlWorkflowVersion(id: string, version: number | null) {\n return useQuery<LTYamlWorkflowVersion>({\n queryKey: ['yamlWorkflows', id, 'versions', version],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions/${version}`),\n enabled: !!id && version !== null,\n });\n}\n"],"names":["useYamlWorkflows","filters","params","useQuery","apiFetch","useYamlWorkflowAppIds","useYamlWorkflow","id","useCreateYamlWorkflow","queryClient","useQueryClient","useMutation","input","useDeployYamlWorkflow","useActivateYamlWorkflow","useInvokeYamlWorkflow","data","sync","execute_as","useRegenerateYamlWorkflow","task_queue","compilation_feedback","useArchiveYamlWorkflow","useRestoreYamlWorkflow","useUpdateYamlWorkflow","updates","useDeleteYamlWorkflow","useYamlWorkflowVersions","useYamlWorkflowVersion","version"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"yaml-workflows-Bf2aQS-M.js","sources":["../../src/api/yaml-workflows.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { LTYamlWorkflowRecord, LTYamlWorkflowStatus, LTYamlWorkflowVersion } from './types';\n\ninterface YamlWorkflowListResponse {\n workflows: LTYamlWorkflowRecord[];\n total: number;\n}\n\ninterface YamlWorkflowFilters {\n status?: LTYamlWorkflowStatus;\n graph_topic?: string;\n app_id?: string;\n search?: string;\n set_id?: string;\n limit?: number;\n offset?: number;\n}\n\nexport function useYamlWorkflows(filters: YamlWorkflowFilters = {}) {\n const params = new URLSearchParams();\n if (filters.status) params.set('status', filters.status);\n if (filters.graph_topic) params.set('graph_topic', filters.graph_topic);\n if (filters.app_id) params.set('app_id', filters.app_id);\n if (filters.search) params.set('search', filters.search);\n if (filters.set_id) params.set('set_id', filters.set_id);\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', filters],\n queryFn: () => apiFetch(`/yaml-workflows?${params}`),\n });\n}\n\nexport function useYamlWorkflowAppIds() {\n return useQuery<{ app_ids: string[] }>({\n queryKey: ['yamlWorkflowAppIds'],\n queryFn: () => apiFetch('/yaml-workflows/app-ids'),\n });\n}\n\nexport function useYamlWorkflowByTopic(graphTopic: string | undefined, appId?: string) {\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', 'byTopic', graphTopic, appId],\n queryFn: () => {\n const params = new URLSearchParams({ graph_topic: graphTopic!, limit: '1' });\n if (appId) params.set('app_id', appId);\n return apiFetch(`/yaml-workflows?${params}`);\n },\n enabled: !!graphTopic,\n });\n}\n\nexport function useYamlWorkflow(id: string) {\n return useQuery<LTYamlWorkflowRecord>({\n queryKey: ['yamlWorkflows', id],\n queryFn: () => apiFetch(`/yaml-workflows/${id}`),\n enabled: !!id,\n });\n}\n\nexport function useCreateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (input: {\n workflow_id: string;\n task_queue: string;\n workflow_name: string;\n name: string;\n description?: string;\n app_id?: string;\n subscribes?: string;\n tags?: string[];\n compilation_feedback?: string;\n }) =>\n apiFetch<LTYamlWorkflowRecord>('/yaml-workflows', {\n method: 'POST',\n body: JSON.stringify(input),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeployYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/deploy`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useActivateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/activate`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useInvokeYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data, sync, execute_as }: { id: string; data: Record<string, unknown>; sync?: boolean; execute_as?: string }) =>\n apiFetch<{ result?: unknown; job_id?: string }>(`/yaml-workflows/${id}/invoke`, {\n method: 'POST',\n body: JSON.stringify({ data, sync, ...(execute_as ? { execute_as } : {}) }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRegenerateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, task_queue, compilation_feedback }: { id: string; task_queue?: string; compilation_feedback?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/regenerate`, {\n method: 'POST',\n body: JSON.stringify({ task_queue, compilation_feedback }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useArchiveYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/archive`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRestoreYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/restore`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflow'], refetchType: 'all' });\n },\n });\n}\n\nexport function useUpdateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, ...updates }: { id: string; yaml_content?: string; name?: string; description?: string; input_schema?: Record<string, unknown>; output_schema?: Record<string, unknown>; tags?: string[]; app_id?: string; graph_topic?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}`, {\n method: 'PUT',\n body: JSON.stringify(updates),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeleteYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<{ deleted: boolean }>(`/yaml-workflows/${id}`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Cron scheduling ─────────────────────────────────────────────\n\nexport function useSetYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, cron_schedule, cron_envelope, execute_as }: {\n id: string;\n cron_schedule: string;\n cron_envelope?: Record<string, unknown> | null;\n execute_as?: string | null;\n }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'PUT',\n body: JSON.stringify({ cron_schedule, cron_envelope, execute_as }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useClearYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Version history ─────────────────────────────────────────────\n\nexport function useYamlWorkflowVersions(id: string) {\n return useQuery<{ versions: LTYamlWorkflowVersion[]; total: number }>({\n queryKey: ['yamlWorkflows', id, 'versions'],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions`),\n enabled: !!id,\n });\n}\n\nexport function useYamlWorkflowVersion(id: string, version: number | null) {\n return useQuery<LTYamlWorkflowVersion>({\n queryKey: ['yamlWorkflows', id, 'versions', version],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions/${version}`),\n enabled: !!id && version !== null,\n });\n}\n"],"names":["useYamlWorkflows","filters","params","useQuery","apiFetch","useYamlWorkflowAppIds","useYamlWorkflow","id","useCreateYamlWorkflow","queryClient","useQueryClient","useMutation","input","useDeployYamlWorkflow","useActivateYamlWorkflow","useInvokeYamlWorkflow","data","sync","execute_as","useRegenerateYamlWorkflow","task_queue","compilation_feedback","useArchiveYamlWorkflow","useRestoreYamlWorkflow","useUpdateYamlWorkflow","updates","useDeleteYamlWorkflow","useYamlWorkflowVersions","useYamlWorkflowVersion","version"],"mappings":"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"}
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
9
9
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
10
10
|
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
+
<script type="module" crossorigin src="./assets/index-CKxFjMtw.js"></script>
|
|
12
12
|
<link rel="modulepreload" crossorigin href="./assets/vendor-query-B2UbickB.js">
|
|
13
13
|
<link rel="modulepreload" crossorigin href="./assets/vendor-react-BpdAFEQc.js">
|
|
14
14
|
<link rel="modulepreload" crossorigin href="./assets/vendor-icons-BE_WrH2z.js">
|
|
15
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
15
|
+
<link rel="stylesheet" crossorigin href="./assets/index-Pmvw74oY.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
18
18
|
<div id="root"></div>
|
|
@@ -641,7 +641,7 @@ The query form is one atomic statement: selection and claim happen in the same U
|
|
|
641
641
|
**Example request (query form):**
|
|
642
642
|
|
|
643
643
|
```json
|
|
644
|
-
{ "query": { "role": "
|
|
644
|
+
{ "query": { "role": "order-items", "facets": { "orderId": "ORD-1042" } }, "targetUserId": "user-x1y2z3", "durationMinutes": 60 }
|
|
645
645
|
```
|
|
646
646
|
|
|
647
647
|
**Response 200:** Result object with assignment outcomes.
|
package/docs/hitl/escalation.md
CHANGED
|
@@ -63,7 +63,7 @@ import type { EscalationResolution } from '@hotmeshio/long-tail';
|
|
|
63
63
|
const decision = await conditionLT<{
|
|
64
64
|
approved: boolean;
|
|
65
65
|
$resolution?: EscalationResolution;
|
|
66
|
-
}>(signalId, { role: '
|
|
66
|
+
}>(signalId, { role: 'order-reviewer', metadata: { orderId } });
|
|
67
67
|
|
|
68
68
|
if (decision && decision.$resolution) {
|
|
69
69
|
const { escalationId, resolvedBy, resolvedByEmail } = decision.$resolution;
|
package/docs/hitl/x-lt-embed.md
CHANGED
|
@@ -143,13 +143,32 @@ A structured query object. String values inside `facets` support `{{domain.path}
|
|
|
143
143
|
| Field | Type | Description |
|
|
144
144
|
|-------|------|-------------|
|
|
145
145
|
| `role` | `string` | Role queue to query |
|
|
146
|
-
| `status` | `string` | `"pending"
|
|
146
|
+
| `status` | `string` | `"pending"` (default), `"resolved"`, `"cancelled"`, `"expired"` |
|
|
147
147
|
| `facets` | `Record<string, string>` | Metadata containment filter; string values support `{{domain.path}}` tokens |
|
|
148
|
-
| `
|
|
148
|
+
| `assigned` | `"me"` \| `"any"` | Ownership scope — see below |
|
|
149
149
|
| `limit` | `number` | Max rows to show (default: 5) |
|
|
150
|
+
| `available` | `boolean` | Legacy availability flag; superseded by `assigned` |
|
|
150
151
|
|
|
151
152
|
The widget is disabled (shows no list and makes no API call) when neither `role` nor any facet value is set — both are required to avoid broad unbounded queries.
|
|
152
153
|
|
|
154
|
+
### Ownership scope (`assigned`)
|
|
155
|
+
|
|
156
|
+
Ownership is one more dimension of the same faceted query language — "claimed" is the implied status the API manages (pending, held, claim window live), not a separate list:
|
|
157
|
+
|
|
158
|
+
- `"me"` — rows claimed by the **viewing user**. The batch case: an earlier step assigned a set of order items to whoever claimed the batch; the follow-up form shows that person their own items with working inline actions.
|
|
159
|
+
- `"any"` — all matching rows regardless of claim state.
|
|
160
|
+
- omitted — available rows only (unclaimed, or claim window lapsed).
|
|
161
|
+
|
|
162
|
+
The scope resolves through ONE shared mapping consumed by the escalation-list widget, its `x-lt-actions`, and `x-lt-submit-guard` — a guard and an embed declaring the same query always agree on count and rows. Inline actions on claimed-to-me rows fire the standard resolve endpoint as the claim holder; RBAC and `enforce_schema` apply unchanged.
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
"x-lt-query": {
|
|
166
|
+
"role": "order-items",
|
|
167
|
+
"facets": { "orderId": "{{metadata.orderId}}" },
|
|
168
|
+
"assigned": "me"
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
153
172
|
### `x-lt-columns` (optional)
|
|
154
173
|
|
|
155
174
|
An array of `{ label, value, format? }` — the same shape as `x-lt-columns` in list schemas. The `value` strings use `{{domain.path}}` tokens resolved against each **displayed** escalation's own context (its row, metadata, envelope, payload, resolver).
|
|
@@ -167,13 +186,13 @@ Inline row actions: each row gains a button that fires a canned resolve against
|
|
|
167
186
|
```json
|
|
168
187
|
"x-lt-actions": [
|
|
169
188
|
{
|
|
170
|
-
"label": "
|
|
189
|
+
"label": "Picked ✓",
|
|
171
190
|
"resolverPayload": {
|
|
172
191
|
"approved": true,
|
|
173
|
-
"checks": { "
|
|
192
|
+
"checks": { "picked": true, "scanned": true },
|
|
174
193
|
"orderId": "{{metadata.orderId}}"
|
|
175
194
|
},
|
|
176
|
-
"confirm": "
|
|
195
|
+
"confirm": "Mark {{metadata.sku}} picked for {{metadata.orderId}}?"
|
|
177
196
|
}
|
|
178
197
|
]
|
|
179
198
|
```
|
|
@@ -186,7 +205,7 @@ Inline row actions: each row gains a button that fires a canned resolve against
|
|
|
186
205
|
|
|
187
206
|
On success the row updates in place through the standard query invalidation — no navigation. A rejected resolve (validation failure, lost claim) shows the server's message inline in the row; the detail link stays available, so the full form remains the path for rejects and anything the canned payload can't express.
|
|
188
207
|
|
|
189
|
-
Declare one action for the happy path and leave the exception path to the form. A
|
|
208
|
+
Declare one action for the happy path and leave the exception path to the form. A batch of N sibling items collapses from N navigations to N clicks on one page.
|
|
190
209
|
|
|
191
210
|
### Empty and loading states
|
|
192
211
|
|
|
@@ -203,12 +222,12 @@ A top-level form_schema token (a peer of `x-lt-help`) that keeps the resolve but
|
|
|
203
222
|
{
|
|
204
223
|
"x-lt-submit-guard": {
|
|
205
224
|
"query": {
|
|
206
|
-
"role": "
|
|
207
|
-
"
|
|
208
|
-
"
|
|
225
|
+
"role": "order-items",
|
|
226
|
+
"facets": { "orderId": "{{metadata.orderId}}" },
|
|
227
|
+
"assigned": "me"
|
|
209
228
|
},
|
|
210
229
|
"mustBeEmpty": true,
|
|
211
|
-
"message": "{{count}}
|
|
230
|
+
"message": "{{count}} item(s) still pending — pick them before closing the order."
|
|
212
231
|
},
|
|
213
232
|
"type": "object",
|
|
214
233
|
"properties": { ... }
|
|
@@ -217,10 +236,12 @@ A top-level form_schema token (a peer of `x-lt-help`) that keeps the resolve but
|
|
|
217
236
|
|
|
218
237
|
| Field | Type | Description |
|
|
219
238
|
|-------|------|-------------|
|
|
220
|
-
| `query` | `object` | Same shape as `x-lt-query
|
|
239
|
+
| `query` | `object` | Same shape as `x-lt-query` — including the `assigned` ownership scope; facet string values interpolate against the host escalation's context |
|
|
221
240
|
| `mustBeEmpty` | `boolean` | The gate condition (default `true`) |
|
|
222
241
|
| `message` | `string` | Shown beside the disabled submit; `{{count}}` carries the live row count, `{{domain.path}}` tokens also interpolate |
|
|
223
242
|
|
|
243
|
+
The guard and an escalation-list embed declaring the same query resolve through one shared mapping — the count and the visible rows always agree, whatever the scope.
|
|
244
|
+
|
|
224
245
|
Pair it with an `escalation-list` embed on the same query so the operator sees exactly which rows are holding the gate.
|
|
225
246
|
|
|
226
247
|
The guard is a UI layer: it makes the form honest, it does not enforce. A resolve arriving through the raw API bypasses it by design — the consuming workflow's own verification (reject and re-park with the remainder) is the durable backstop. Triage is never gated: when the guarded work itself is the problem, "Send to Triage" stays available.
|
|
@@ -270,4 +291,12 @@ The link widget generates a client-side URL; the queue it points to applies its
|
|
|
270
291
|
|
|
271
292
|
## Example workflow
|
|
272
293
|
|
|
273
|
-
The `examples/workflows/related-escalations/` workflow demonstrates all three widgets in a realistic two-stage review scenario. See `forms.ts` in that directory for the complete form
|
|
294
|
+
The `examples/workflows/related-escalations/` workflow demonstrates all three widgets in a realistic two-stage review scenario, followed by a claimed walk. See `forms.ts` and `forms-walk.ts` in that directory for the complete form schemas.
|
|
295
|
+
|
|
296
|
+
The claimed walk (stage 3, after the manager approves) is the ownership-scope reference:
|
|
297
|
+
|
|
298
|
+
1. Three plate rows park in `rel-plate`, each faceted with the walk's `originId`.
|
|
299
|
+
2. A walk-claim row parks in `rel-walker`. Resolving it IS the "start walk" button — the resolver's identity arrives on the workflow via `$resolution`, and one atomic query-form bulk assign claims every plate for that person.
|
|
300
|
+
3. The closeout row parks in `rel-closer`. Its form declares the walk query ONCE — `{ role: "rel-plate", facets: { originId: "{{metadata.originId}}" }, assigned: "me" }` — consumed by the embedded list, its `Bagged ✓` inline actions, and the submit guard. The walker bags each plate in place; the count beside the locked submit falls with each click; the last plate unlocks the submit.
|
|
301
|
+
|
|
302
|
+
The whole journey is two form submits and N inline clicks, with zero navigation.
|
|
@@ -19,11 +19,26 @@ Every string is a markdown/text template run through the same `{{domain.path}}`
|
|
|
19
19
|
| `x-lt-columns` | schema | Column definitions for `facet-table` layout: `[{ label, value, format? }]` |
|
|
20
20
|
| `x-lt-group-by` | schema | `facet-board`: the `"domain.path"` whose value identifies each entity |
|
|
21
21
|
| `x-lt-card` | schema | `facet-board`: the per-entity card — `{ title, state?, fields?: [{ label, value, format? }] }` |
|
|
22
|
+
| `x-lt-row-action` | schema | The per-row action button: `{ action?, label?, durationMinutes? }` — see below |
|
|
22
23
|
|
|
23
24
|
`format: "age"` on a `facet-table` column or `facet-board` field renders a timestamp as a compact age (`12m`, `3h`, `2d`) with the absolute time as its tooltip, repainted each minute — aging interim states are scannable at a glance.
|
|
24
25
|
|
|
25
26
|
The **active** item is the first non-terminal escalation. The **history** column is lazy-loaded — a "Load full history" link fetches resolved items on demand (`status` defaults to `"resolved"`, `limit` to 25). Unknown or absent `x-lt-layout` is a safe no-op that falls back to the table.
|
|
26
27
|
|
|
28
|
+
### Row action (`x-lt-row-action`)
|
|
29
|
+
|
|
30
|
+
Every layout carries a persistent action button — the active card's CTA, a trailing button on each `facet-table` row, a footer button on each `facet-board` card. The template sets what it does:
|
|
31
|
+
|
|
32
|
+
```jsonc
|
|
33
|
+
"x-lt-row-action": {
|
|
34
|
+
"action": "claim", // "claim" | "view" — default "claim"
|
|
35
|
+
"label": "Service", // button text; defaults "Claim" / "View"
|
|
36
|
+
"durationMinutes": 60 // claim hold time; default 30
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`claim` is one click: the row is claimed for the template's duration and the detail page opens already claimed — the fast path for working a queue. The button appears only on claimable rows (pending, no live claim window), and a rejected claim (someone else won the race) surfaces its message inline. `view` opens the detail page — for read-only templates where claiming from the list is wrong. Row and card clicks continue to navigate; the button is the deliberate gesture.
|
|
41
|
+
|
|
27
42
|
---
|
|
28
43
|
|
|
29
44
|
## Layouts
|
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as t,a as j}from"./vendor-query-B2UbickB.js";import{M as Y}from"./Modal-CA2Iv02H.js";import{Q as _,m as M,K as W,b as q,P as z,u as J}from"./index-C6UuVkz7.js";import{a as C}from"./StatusBadge-BbqghFMi.js";import{S as D}from"./StickyPagination-qLaLa33X.js";import{i as O}from"./CountdownTimer-Z8N8ccJ1.js";import{ab as Q,ac as Z,ar as B}from"./vendor-icons-BE_WrH2z.js";import{D as X,f as P}from"./constants-BHkpVaqx.js";function wt({open:e,onClose:s,onConfirm:a,selectedCount:r,isPending:n,error:l}){const i=r&&r>1?`Cancel ${r} escalations`:"Cancel escalation";return t.jsx(Y,{open:e,onClose:s,title:i,children:t.jsxs("div",{className:"space-y-4",children:[t.jsx("p",{className:"text-sm text-text-secondary",children:r&&r>1?`This will permanently cancel ${r} escalations. Any waiting workflows will be unblocked and receive a cancellation signal.`:"This will permanently cancel this escalation. Any waiting workflow will be unblocked and receive a cancellation signal."}),t.jsx("p",{className:"text-xs text-text-tertiary",children:"This action cannot be undone."}),l&&t.jsx("p",{className:"text-xs text-status-error",children:l.message}),t.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[t.jsx("button",{onClick:s,disabled:n,className:"btn-secondary text-xs",children:"Keep"}),t.jsx("button",{onClick:a,disabled:n,className:"bg-status-error text-text-inverse px-3 py-1.5 rounded-md text-xs hover:opacity-90 transition-opacity disabled:opacity-50",children:n?"Cancelling...":"Yes, Cancel"})]})]})})}const G=new Set(["__proto__","constructor","prototype"]);function F(e){const s=[];for(const a of e.split(".")){const r=a.match(/^([^[\]]*)((?:\[\d+\])*)$/);if(!r)throw new Error(`invalid x-lt-bind path segment: "${a}"`);const[,n,l]=r;if(n){if(G.has(n))throw new Error(`x-lt-bind path may not target "${n}"`);s.push({key:n})}for(const i of l.match(/\d+/g)??[])s.push({index:Number(i)})}if(s.length===0)throw new Error(`empty x-lt-bind path: "${e}"`);return s}function R(e,s,a){const r=F(s);let n=e;for(let i=0;i<r.length-1;i++){const o=r[i],x=r[i+1],u="key"in o?o.key:o.index,c="index"in x;(n[u]==null||typeof n[u]!="object")&&(n[u]=c?[]:{}),n=n[u]}const l=r[r.length-1];n["key"in l?l.key:l.index]=a}function E(e,s){let a=e;for(const r of F(s)){if(a==null||typeof a!="object")return;a=a["key"in r?r.key:r.index]}return a}function U(e,s){const a=s==null?void 0:s["x-lt-bind"];return typeof a=="string"&&a.length>0?a:e}function kt(e,s){const a=s==null?void 0:s.properties;if(!a)return{...e};const r={};for(const[n,l]of Object.entries(a))n in e&&R(r,U(n,l),e[n]);return r}function Tt(e,s){const a=s==null?void 0:s.properties;if(!a)return e?{...e}:{};const r={};for(const[n,l]of Object.entries(a)){const i=E(e,U(n,l));i!==void 0&&(r[n]=i)}return r}const tt=["escalation","metadata","envelope","payload","resolver"],et=/\{\{\s*([^{}]+?)\s*\}\}/g,T="—";function L(e){if(e==null)return T;if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);try{return JSON.stringify(e)}catch{return T}}function p(e,s){return e.replace(et,(a,r)=>{const n=r.indexOf("."),l=n===-1?r:r.slice(0,n);if(!tt.includes(l))return T;const i=s[l];if(n===-1)return L(i);try{return L(E(i,r.slice(n+1)))}catch{return T}})}function st(e){const s=e==null?void 0:e["x-lt-help"];if(typeof s=="string"&&s.trim().length>0)return s;const a=e==null?void 0:e["x-lt-context"];return typeof a=="string"&&a.trim().length>0?a:null}function _t(e,s){const a=st(e);return a?p(a,s):null}function Et({isTerminal:e,status:s,claimed:a,claimedByMe:r}){return e?s==="cancelled"?"This escalation was cancelled. The record is shown for reference.":"This escalation has been resolved. The submitted form is shown for reference.":r?"You have claimed this escalation. Fill out the form and submit to resolve it.":a?"Another user has claimed this escalation. It unlocks if their claim expires or is released.":"Claim this escalation to enable the form."}const I=[{text:"text-rose-400",bg:"bg-rose-400/[0.08]"},{text:"text-pink-400",bg:"bg-pink-400/[0.08]"},{text:"text-fuchsia-400",bg:"bg-fuchsia-400/[0.08]"},{text:"text-purple-400",bg:"bg-purple-400/[0.08]"},{text:"text-violet-400",bg:"bg-violet-400/[0.08]"},{text:"text-indigo-400",bg:"bg-indigo-400/[0.08]"},{text:"text-blue-400",bg:"bg-blue-400/[0.08]"},{text:"text-sky-400",bg:"bg-sky-400/[0.08]"},{text:"text-cyan-400",bg:"bg-cyan-400/[0.08]"},{text:"text-teal-400",bg:"bg-teal-400/[0.08]"},{text:"text-emerald-400",bg:"bg-emerald-400/[0.08]"},{text:"text-green-400",bg:"bg-green-400/[0.08]"},{text:"text-lime-400",bg:"bg-lime-400/[0.08]"},{text:"text-yellow-400",bg:"bg-yellow-400/[0.08]"},{text:"text-amber-400",bg:"bg-amber-400/[0.08]"},{text:"text-orange-400",bg:"bg-orange-400/[0.08]"},{text:"text-red-400",bg:"bg-red-400/[0.08]"},{text:"text-stone-400",bg:"bg-stone-400/[0.08]"},{text:"text-rose-300",bg:"bg-rose-300/[0.08]"},{text:"text-violet-300",bg:"bg-violet-300/[0.08]"},{text:"text-sky-300",bg:"bg-sky-300/[0.08]"},{text:"text-teal-300",bg:"bg-teal-300/[0.08]"},{text:"text-amber-300",bg:"bg-amber-300/[0.08]"},{text:"text-pink-300",bg:"bg-pink-300/[0.08]"}];function at(e){let s=0;for(let a=0;a<e.length;a++)s=(s<<5)-s+e.charCodeAt(a)|0;return Math.abs(s)}function rt(e){return I[at(e)%I.length]}function nt(e){const[,s]=j.useState(0);j.useEffect(()=>{if(!e)return;const a=window.setInterval(()=>s(r=>r+1),6e4);return()=>window.clearInterval(a)},[e])}function it(e){var s;return[...e["x-lt-columns"]??[],...((s=e["x-lt-card"])==null?void 0:s.fields)??[]].some(a=>a.format==="age")}function N(e){const s=a=>{if(!a)return null;try{const r=JSON.parse(a);return r&&typeof r=="object"?r:null}catch{return null}};return{escalation:e,metadata:e.metadata??null,envelope:s(e.envelope),payload:s(e.escalation_payload),resolver:s(e.resolver_payload)}}const lt=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/,K="—";function S({raw:e,format:s}){if(!e||e===K)return t.jsx("span",{className:"text-text-quaternary",children:K});if(s==="age"){const a=new Date(e);if(!Number.isNaN(a.getTime()))return t.jsx("span",{title:a.toLocaleString(),className:"tabular-nums whitespace-nowrap",children:z(e)})}return lt.test(e)?t.jsx(q,{date:e,format:"datetime",className:"text-text-primary"}):t.jsx(t.Fragment,{children:e})}function ct({esc:e,card:s,onOpen:a}){const r=N(e),n=s.title?p(s.title,r):e.type,l=e.status==="pending"&&!O(e);return t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-start justify-between gap-6",children:[t.jsxs("button",{onClick:a,className:"text-left group min-w-0",children:[t.jsx("h3",{className:"heading-2 group-hover:text-accent transition-colors leading-tight",children:n}),s.subtitle&&t.jsx("p",{className:"text-xs text-text-tertiary mt-1.5",children:p(s.subtitle,r)})]}),l&&t.jsxs("button",{onClick:a,className:"inline-flex items-center gap-1.5 px-4 py-2 rounded-md bg-accent text-text-inverse text-xs font-medium hover:bg-accent-hover transition-colors shrink-0",children:["Claim",t.jsx(B,{className:"w-3.5 h-3.5"})]})]}),s.fields&&s.fields.length>0&&t.jsx("dl",{className:"flex flex-wrap gap-x-10 gap-y-4 mt-6",children:s.fields.map((i,o)=>t.jsxs("div",{children:[t.jsx("dt",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary",children:i.label}),t.jsx("dd",{className:"text-xs text-text-primary mt-1",children:t.jsx(S,{raw:p(i.value,r)})})]},o))}),s.body&&t.jsx("div",{className:"mt-7 pt-6 border-t border-surface-border/50",children:t.jsx(_,{content:p(s.body,r)})})]})}function ot({role:e,def:s,onRowClick:a}){var u,c;const[r,n]=j.useState(!1),l=W({role:e,status:s.status??"resolved",sort_by:"resolved_at",order:"desc",limit:s.limit??25,enabled:r}),i=((u=l.data)==null?void 0:u.escalations)??[],o=((c=l.data)==null?void 0:c.total)??0,x=s.row??{};return r?l.isLoading?t.jsx("p",{className:"text-xs text-text-tertiary italic",children:"Loading history…"}):i.length===0?t.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No past revisions."}):t.jsxs("div",{children:[t.jsx("div",{className:"divide-y divide-surface-border/40",children:i.map(d=>{const b=N(d);return t.jsxs("button",{onClick:()=>a==null?void 0:a(d),className:"w-full text-left py-2.5 group flex items-center gap-3",children:[t.jsx("span",{className:`w-1.5 h-1.5 shrink-0 rounded-full dot-ring ${C[d.status]??"bg-status-pending"}`,title:d.status}),t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsx("span",{className:"block text-xs text-text-primary group-hover:text-accent transition-colors truncate",children:x.title?p(x.title,b):d.type}),x.subtitle&&t.jsx("span",{className:"block text-2xs text-text-tertiary truncate",children:p(x.subtitle,b)})]}),x.meta?t.jsx("span",{className:"text-2xs text-text-tertiary shrink-0",children:p(x.meta,b)}):d.resolved_at&&t.jsx(q,{date:d.resolved_at,format:"relative",className:"text-2xs text-text-tertiary shrink-0 whitespace-nowrap"})]},d.id)})}),o>i.length&&t.jsxs("p",{className:"text-2xs text-text-quaternary mt-3",children:["Showing ",i.length," of ",o,"."]})]}):t.jsx("button",{onClick:()=>n(!0),className:"text-xs text-accent hover:underline","data-testid":"load-history",children:"Load full history →"})}function xt({schema:e,rows:s,onRowClick:a}){const r=e["x-lt-columns"]??[];return s.length===0?t.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No pending items."}):t.jsx("div",{className:"overflow-x-auto",children:t.jsxs("table",{className:"w-full text-xs",children:[t.jsx("thead",{children:t.jsxs("tr",{className:"border-b border-surface-border/60",children:[t.jsx("th",{className:"w-4 pb-2 pr-3","aria-label":"Status"}),r.map((n,l)=>t.jsx("th",{className:"text-left pb-2 pr-8 text-2xs font-semibold uppercase tracking-widest text-text-tertiary whitespace-nowrap",children:n.label},l))]})}),t.jsx("tbody",{className:"divide-y divide-surface-border/30",children:s.map(n=>{const l=N(n);return t.jsxs("tr",{onClick:()=>a==null?void 0:a(n),className:a?"group cursor-pointer hover:bg-surface-hover":"group","data-testid":"facet-table-row",children:[t.jsx("td",{className:"py-2.5 pr-3",children:t.jsx("span",{className:`w-1.5 h-1.5 inline-block rounded-full dot-ring ${C[n.status]??"bg-status-pending"}`,title:n.status})}),r.map((i,o)=>t.jsx("td",{className:"py-2.5 pr-8 text-text-secondary group-hover:text-text-primary transition-colors",children:t.jsx(S,{raw:p(i.value,l),format:i.format})},o))]},n.id)})})]})})}function H({children:e}){return t.jsx("p",{className:"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3",children:e})}function dt(e,s){var l;const a=s.indexOf("."),r=s.startsWith("metadata.")?s.slice(9):null,n=new Map;for(const i of e){const o=N(i);let x;try{x=a===-1?o[s]:E(o[s.slice(0,a)],s.slice(a+1))}catch{x=void 0}if(x==null||x==="")continue;const u=String(x),c=r?((l=i.metadata)==null?void 0:l[r])??x:x,d=n.get(u);d?(d.count+=1,new Date(i.created_at)>new Date(d.latest.created_at)&&(d.latest=i)):n.set(u,{key:u,rawValue:c,latest:i,count:1})}return[...n.values()].sort((i,o)=>i.key.localeCompare(o.key))}const ut=/^\{\{\s*metadata\.([a-zA-Z0-9_]+)\s*\}\}$/;function mt({schema:e,rows:s,role:a,onOpenDetail:r,onOpenGroup:n,onAddFacet:l}){const i=e["x-lt-group-by"],o=e["x-lt-card"]??{};if(!i)return t.jsx("p",{className:"text-xs text-text-tertiary italic",children:"facet-board needs an x-lt-group-by path."});const x=i.startsWith("metadata.")?i.slice(9):null,u=dt(s,i);return u.length===0?t.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No entities in scope."}):t.jsx("div",{className:"grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-4","data-testid":"facet-board",children:u.map(c=>{const d=N(c.latest),b=o.title?p(o.title,d):c.key,w=o.state?p(o.state,d):c.latest.subtype||c.latest.status,h=rt(w),y=m=>{if(m.shiftKey&&x&&l){l(x,c.rawValue);return}r==null||r(c.latest)};return t.jsxs("div",{role:"button",tabIndex:0,onClick:y,onKeyDown:m=>{(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),y(m))},title:x?"Open the latest item · ⇧ click to filter the board":"Open the latest item",className:"group/card border-l-2 border-accent/30 bg-surface-sunken/40 rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-surface-sunken/70 focus:outline-none focus-visible:ring-1 focus-visible:ring-accent/40","data-testid":"facet-board-card",children:[t.jsxs("div",{className:"flex items-center justify-between gap-2 mb-2.5",children:[t.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider text-text-secondary truncate",children:b}),t.jsx("span",{className:"shrink-0 px-1.5 py-0.5 rounded text-2xs font-mono font-medium",style:{color:h.text,backgroundColor:h.bg},title:w,children:w})]}),o.fields&&o.fields.length>0&&t.jsx("dl",{className:"space-y-1",children:o.fields.map((m,v)=>{var A,$;const f=(A=m.value.match(ut))==null?void 0:A[1],g=f?($=c.latest.metadata)==null?void 0:$[f]:void 0,V=f!=null&&g!==void 0&&g!==null&&g!=="";return t.jsxs("div",{className:"group/frow flex items-baseline justify-between gap-3",children:[t.jsx("dt",{className:"text-2xs uppercase tracking-wider text-text-quaternary shrink-0",children:m.label}),t.jsxs("dd",{className:"min-w-0 flex items-baseline gap-1 text-2xs text-text-primary",children:[t.jsx("span",{className:"truncate",children:t.jsx(S,{raw:p(m.value,d),format:m.format})}),t.jsx("span",{className:"shrink-0 w-9 self-center flex items-center justify-end gap-px",children:V&&(n||l)&&t.jsxs("span",{className:"flex items-center gap-px opacity-0 group-hover/frow:opacity-100 transition-opacity",children:[t.jsx("button",{onClick:k=>{k.stopPropagation(),k.shiftKey&&l?l(f,g):n==null||n(M(f,g,a))},className:"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors",title:`Filter ${a}: ${f} = ${String(g)} · ⇧ click adds to current filters`,"data-testid":"facet-field-filter",children:t.jsx(Q,{className:"w-3 h-3"})}),t.jsx("button",{onClick:k=>{k.stopPropagation(),n==null||n(M(f,g))},className:"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors",title:`Search all: ${f} = ${String(g)}`,"data-testid":"facet-field-search",children:t.jsx(Z,{className:"w-3 h-3"})})]})})]})]},v)})})]},c.key)})})}function St({role:e,listSchema:s,activeEscalations:a,onRowClick:r,onOpenGroup:n,onAddFacet:l,total:i,page:o,totalPages:x,pageSize:u,onPageChange:c,onPageSizeChange:d}){const b=s["x-lt-layout"],w=s["x-lt-active"]??{},h=a[0],y=s["x-lt-help"];nt(it(s));const m=h?t.jsx(ct,{esc:h,card:w,onOpen:()=>r==null?void 0:r(h)}):t.jsx("p",{className:"text-xs text-text-tertiary italic",children:"No active item right now."}),v=y&&h?t.jsx("div",{className:"mb-8",children:t.jsx(_,{content:p(y,N(h))})}):y?t.jsx("div",{className:"mb-8",children:t.jsx(_,{content:y})}):null;if(b==="facet-table"){const f=i??a.length;return t.jsxs("div",{children:[v,f>0&&t.jsxs("p",{className:"text-2xs text-text-tertiary mb-3 tabular-nums",children:[f.toLocaleString()," result",f!==1?"s":""]}),t.jsx(xt,{schema:s,rows:a,onRowClick:r}),o!==void 0&&x!==void 0&&c&&t.jsx(D,{page:o,totalPages:x,onPageChange:c,total:f,pageSize:u??25,onPageSizeChange:d})]})}return b==="facet-board"?t.jsxs("div",{children:[v,t.jsx(mt,{schema:s,rows:a,role:e,onOpenDetail:r,onOpenGroup:n,onAddFacet:l}),o!==void 0&&x!==void 0&&c&&x>1&&t.jsx(D,{page:o,totalPages:x,onPageChange:c,total:i??a.length,pageSize:u??25,onPageSizeChange:d})]}):b==="active-history"?t.jsxs("div",{children:[v,t.jsxs("div",{className:"grid grid-cols-1 @split:grid-cols-[1.6fr_1fr] gap-12 items-start",children:[t.jsxs("div",{children:[t.jsx(H,{children:"Active"}),m]}),t.jsxs("div",{children:[t.jsx(H,{children:"History"}),t.jsx(ot,{role:e,def:s["x-lt-history"]??{},onRowClick:r})]})]})]}):t.jsxs("div",{children:[v,m]})}function At(){const{data:e}=J();return j.useMemo(()=>{var a;return(((a=e==null?void 0:e.escalation)==null?void 0:a.claimDurations)??X).map(r=>({value:String(r),label:P(r)}))},[e])}const ft=[{value:1,label:"minutes"},{value:60,label:"hours"}];function $t({onChange:e,compact:s,autoFocus:a,"data-testid":r="custom-duration-input"}){const[n,l]=j.useState(""),[i,o]=j.useState(1);j.useEffect(()=>{const c=parseInt(n);e(c>0?c*i:0)},[n,i,e]);const x=s?"text-xs":"text-sm",u=s?"w-16":"w-20";return t.jsxs("div",{className:"flex items-center gap-2","data-testid":r,children:[t.jsx("input",{type:"number",min:1,max:i===60?24:1440,value:n,onChange:c=>l(c.target.value),placeholder:i===60?"hrs":"min",className:`input ${x} ${u} text-center`,autoFocus:a,"data-testid":`${r}-quantity`}),t.jsx("select",{value:i,onChange:c=>o(parseInt(c.target.value)),className:`select ${x} py-1`,"data-testid":`${r}-unit`,children:ft.map(c=>t.jsx("option",{value:c.value,children:c.label},c.value))})]})}export{$t as C,St as E,tt as H,wt as a,_t as b,Tt as c,Et as d,E as g,p as i,kt as m,N as r,At as u};
|
|
2
|
-
//# sourceMappingURL=CustomDurationPicker-BTmpAQOL.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CustomDurationPicker-BTmpAQOL.js","sources":["../../src/components/common/modal/ConfirmCancelModal.tsx","../../../shared/form-validation/x-lt-bind.ts","../../../shared/form-validation/x-lt-help.ts","../../src/lib/type-color.ts","../../src/components/escalation/EscalationListView.tsx","../../src/hooks/useClaimDurations.ts","../../src/components/common/form/CustomDurationPicker.tsx"],"sourcesContent":["import { Modal } from './Modal';\n\ninterface ConfirmCancelModalProps {\n open: boolean;\n onClose: () => void;\n onConfirm: () => void;\n selectedCount?: number;\n isPending?: boolean;\n error?: Error | null;\n}\n\nexport function ConfirmCancelModal({\n open,\n onClose,\n onConfirm,\n selectedCount,\n isPending,\n error,\n}: ConfirmCancelModalProps) {\n const title = selectedCount && selectedCount > 1\n ? `Cancel ${selectedCount} escalations`\n : 'Cancel escalation';\n\n return (\n <Modal open={open} onClose={onClose} title={title}>\n <div className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">\n {selectedCount && selectedCount > 1\n ? `This will permanently cancel ${selectedCount} escalations. Any waiting workflows will be unblocked and receive a cancellation signal.`\n : 'This will permanently cancel this escalation. Any waiting workflow will be unblocked and receive a cancellation signal.'}\n </p>\n <p className=\"text-xs text-text-tertiary\">This action cannot be undone.</p>\n {error && <p className=\"text-xs text-status-error\">{error.message}</p>}\n <div className=\"flex justify-end gap-3 pt-2\">\n <button onClick={onClose} disabled={isPending} className=\"btn-secondary text-xs\">\n Keep\n </button>\n <button\n onClick={onConfirm}\n disabled={isPending}\n className=\"bg-status-error text-text-inverse px-3 py-1.5 rounded-md text-xs hover:opacity-90 transition-opacity disabled:opacity-50\"\n >\n {isPending ? 'Cancelling...' : 'Yes, Cancel'}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n","/**\n * x-lt-bind — maps the escalation FORM (flat field values the user edits) to and\n * from the PAYLOAD (the nested JSON the workflow consumes). A form_schema property\n * may declare `x-lt-bind: \"a.b[0].c\"`, the path its value occupies in the payload;\n * a property with no bind sits at its own name at the root (1:1). This module is\n * isomorphic — the dashboard renders forms with it, and the API layer inverts a\n * submitted payload through it to validate against the form contract. One\n * implementation, both sides.\n *\n * mapPayloadToForm — payload → flat form values, to PREFILL/display the form\n * (server-side: to validate a submitted payload)\n * mapFormToPayload — flat form values → payload, the shape submitted/stored\n */\n\ntype PathSeg = { key: string } | { index: number };\n\nconst BLOCKED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** Parse a bind path — dot keys with optional `[n]` indices. Rejects pollution keys. */\nexport function parsePath(path: string): PathSeg[] {\n const segs: PathSeg[] = [];\n for (const raw of path.split('.')) {\n const m = raw.match(/^([^[\\]]*)((?:\\[\\d+\\])*)$/);\n if (!m) throw new Error(`invalid x-lt-bind path segment: \"${raw}\"`);\n const [, name, brackets] = m;\n if (name) {\n if (BLOCKED_KEYS.has(name)) throw new Error(`x-lt-bind path may not target \"${name}\"`);\n segs.push({ key: name });\n }\n for (const b of brackets.match(/\\d+/g) ?? []) segs.push({ index: Number(b) });\n }\n if (segs.length === 0) throw new Error(`empty x-lt-bind path: \"${path}\"`);\n return segs;\n}\n\n/** Set `value` at `path` inside `root`, creating intermediate objects/arrays. */\nexport function setDeep(root: Record<string, any>, path: string, value: unknown): void {\n const segs = parsePath(path);\n let node: any = root;\n for (let i = 0; i < segs.length - 1; i++) {\n const seg = segs[i];\n const next = segs[i + 1];\n const childKey = 'key' in seg ? seg.key : seg.index;\n const wantArray = 'index' in next;\n if (node[childKey] == null || typeof node[childKey] !== 'object') {\n node[childKey] = wantArray ? [] : {};\n }\n node = node[childKey];\n }\n const last = segs[segs.length - 1];\n node['key' in last ? last.key : last.index] = value;\n}\n\n/** Read the value at `path` inside `root` (undefined if any segment is missing). */\nexport function getDeep(root: unknown, path: string): unknown {\n let node: any = root;\n for (const seg of parsePath(path)) {\n if (node == null || typeof node !== 'object') return undefined;\n node = node['key' in seg ? seg.key : seg.index];\n }\n return node;\n}\n\n/** The bind path for a form property (its `x-lt-bind`, or the property name). */\nexport function bindPathFor(propName: string, propDef: Record<string, any> | undefined): string {\n const bind = propDef?.['x-lt-bind'];\n return typeof bind === 'string' && bind.length > 0 ? bind : propName;\n}\n\n/**\n * Assemble the payload from the form's flat values. A field absent from\n * `formValues` is omitted (so clearing/deleting a field drops it from the\n * payload). Unknown keys not declared in the schema are dropped. With no schema\n * properties, values pass through unchanged.\n */\nexport function mapFormToPayload(\n formValues: Record<string, any>,\n formSchema: Record<string, any> | null | undefined,\n): Record<string, any> {\n const props = formSchema?.properties as Record<string, any> | undefined;\n if (!props) return { ...formValues };\n const payload: Record<string, any> = {};\n for (const [name, def] of Object.entries(props)) {\n if (!(name in formValues)) continue;\n setDeep(payload, bindPathFor(name, def as Record<string, any>), formValues[name]);\n }\n return payload;\n}\n\n/**\n * Reverse of {@link mapFormToPayload}: pull each form field's value out of the\n * payload via its bind path, to prefill/display the form. A field whose bound\n * path is missing from the payload is omitted (the caller falls back to the\n * schema default).\n */\nexport function mapPayloadToForm(\n payload: Record<string, any> | null | undefined,\n formSchema: Record<string, any> | null | undefined,\n): Record<string, any> {\n const props = formSchema?.properties as Record<string, any> | undefined;\n if (!props) return payload ? { ...payload } : {};\n const form: Record<string, any> = {};\n for (const [name, def] of Object.entries(props)) {\n const v = getDeep(payload, bindPathFor(name, def as Record<string, any>));\n if (v !== undefined) form[name] = v;\n }\n return form;\n}\n","/**\n * x-lt-help — the form's guidance content, rendered in the side panel beside\n * the resolve form. A form_schema may declare schema-level `x-lt-help`: a\n * markdown string whose `{{domain.path}}` tokens interpolate values from the\n * escalation surface, so help text can reference the live record:\n *\n * {{escalation.role}} — any column on the escalation row\n * {{metadata.schema_version}} — the row's metadata dict\n * {{envelope.formDefaults.customer.name}} — the workflow-sent input envelope\n * {{payload.category}} — the escalation context payload\n * {{resolver.notes}} — the submitted resolver payload\n *\n * Paths reuse the x-lt-bind syntax (`a.b[0].c`). A missing value renders as an\n * em dash. `x-lt-context` is accepted as the plain-text fallback source when\n * `x-lt-help` is absent.\n */\nimport { getDeep } from './x-lt-bind';\n\n/** The token domains a help template may reference. */\nexport const HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver'] as const;\nexport type HelpDomain = (typeof HELP_DOMAINS)[number];\n\nexport type HelpTokenContext = Partial<Record<HelpDomain, Record<string, unknown> | null>>;\n\nconst TOKEN_PATTERN = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\nconst MISSING_VALUE = '—';\n\nfunction formatTokenValue(value: unknown): string {\n if (value === undefined || value === null) return MISSING_VALUE;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n try {\n return JSON.stringify(value);\n } catch {\n return MISSING_VALUE;\n }\n}\n\n/** Replace every `{{domain.path}}` token with its value from the context. */\nexport function interpolateHelp(template: string, ctx: HelpTokenContext): string {\n return template.replace(TOKEN_PATTERN, (_match, rawPath: string) => {\n const dot = rawPath.indexOf('.');\n const domain = (dot === -1 ? rawPath : rawPath.slice(0, dot)) as HelpDomain;\n if (!HELP_DOMAINS.includes(domain)) return MISSING_VALUE;\n const root = ctx[domain];\n if (dot === -1) return formatTokenValue(root);\n try {\n return formatTokenValue(getDeep(root, rawPath.slice(dot + 1)));\n } catch {\n return MISSING_VALUE;\n }\n });\n}\n\n/** The schema's help source: `x-lt-help` first, `x-lt-context` as fallback. */\nexport function resolveHelpSource(schema: Record<string, unknown> | null | undefined): string | null {\n const help = schema?.['x-lt-help'];\n if (typeof help === 'string' && help.trim().length > 0) return help;\n const context = schema?.['x-lt-context'];\n if (typeof context === 'string' && context.trim().length > 0) return context;\n return null;\n}\n\n/** The schema's help content, interpolated. Null when the schema declares none. */\nexport function buildHelpMarkdown(\n schema: Record<string, unknown> | null | undefined,\n ctx: HelpTokenContext,\n): string | null {\n const source = resolveHelpSource(schema);\n return source ? interpolateHelp(source, ctx) : null;\n}\n\nexport interface HelpStateHint {\n isTerminal: boolean;\n status?: string;\n claimed: boolean;\n claimedByMe: boolean;\n}\n\n/**\n * State-aware guidance shown when the schema carries no help content — the\n * panel always tells the user what this page expects of them right now.\n */\nexport function defaultHelpMarkdown({ isTerminal, status, claimed, claimedByMe }: HelpStateHint): string {\n if (isTerminal) {\n return status === 'cancelled'\n ? 'This escalation was cancelled. The record is shown for reference.'\n : 'This escalation has been resolved. The submitted form is shown for reference.';\n }\n if (claimedByMe) return 'You have claimed this escalation. Fill out the form and submit to resolve it.';\n if (claimed) return 'Another user has claimed this escalation. It unlocks if their claim expires or is released.';\n return 'Claim this escalation to enable the form.';\n}\n","/**\n * Deterministic color assignment for workflow type names.\n *\n * Maps any string to a consistent color from a curated 24-color palette.\n * The same type name always produces the same color across the entire UI.\n * Uses a simple hash to distribute names evenly across the palette.\n *\n * Each entry provides:\n * text — icon and text color (Tailwind class)\n * bg — subtle background tint (Tailwind class)\n */\n\nconst PALETTE: Array<{ text: string; bg: string }> = [\n { text: 'text-rose-400', bg: 'bg-rose-400/[0.08]' },\n { text: 'text-pink-400', bg: 'bg-pink-400/[0.08]' },\n { text: 'text-fuchsia-400', bg: 'bg-fuchsia-400/[0.08]' },\n { text: 'text-purple-400', bg: 'bg-purple-400/[0.08]' },\n { text: 'text-violet-400', bg: 'bg-violet-400/[0.08]' },\n { text: 'text-indigo-400', bg: 'bg-indigo-400/[0.08]' },\n { text: 'text-blue-400', bg: 'bg-blue-400/[0.08]' },\n { text: 'text-sky-400', bg: 'bg-sky-400/[0.08]' },\n { text: 'text-cyan-400', bg: 'bg-cyan-400/[0.08]' },\n { text: 'text-teal-400', bg: 'bg-teal-400/[0.08]' },\n { text: 'text-emerald-400', bg: 'bg-emerald-400/[0.08]' },\n { text: 'text-green-400', bg: 'bg-green-400/[0.08]' },\n { text: 'text-lime-400', bg: 'bg-lime-400/[0.08]' },\n { text: 'text-yellow-400', bg: 'bg-yellow-400/[0.08]' },\n { text: 'text-amber-400', bg: 'bg-amber-400/[0.08]' },\n { text: 'text-orange-400', bg: 'bg-orange-400/[0.08]' },\n { text: 'text-red-400', bg: 'bg-red-400/[0.08]' },\n { text: 'text-stone-400', bg: 'bg-stone-400/[0.08]' },\n { text: 'text-rose-300', bg: 'bg-rose-300/[0.08]' },\n { text: 'text-violet-300', bg: 'bg-violet-300/[0.08]' },\n { text: 'text-sky-300', bg: 'bg-sky-300/[0.08]' },\n { text: 'text-teal-300', bg: 'bg-teal-300/[0.08]' },\n { text: 'text-amber-300', bg: 'bg-amber-300/[0.08]' },\n { text: 'text-pink-300', bg: 'bg-pink-300/[0.08]' },\n];\n\nfunction hash(str: string): number {\n let h = 0;\n for (let i = 0; i < str.length; i++) {\n h = ((h << 5) - h + str.charCodeAt(i)) | 0;\n }\n return Math.abs(h);\n}\n\nexport function typeColor(typeName: string): { text: string; bg: string } {\n return PALETTE[hash(typeName) % PALETTE.length];\n}\n","import { useState, useEffect } from 'react';\nimport { interpolateHelp, type HelpTokenContext } from '../../lib/x-lt-help';\nimport { ArrowRight, ListFilter, Search } from 'lucide-react';\nimport { MarkdownRenderer } from '../common/display/MarkdownRenderer';\nimport { STATUS_DOT_STYLES } from '../common/display/StatusBadge';\nimport { DateValue } from '../common/display/DateValue';\nimport { StickyPagination } from '../common/data/StickyPagination';\nimport { useEscalations } from '../../api/escalations';\nimport { isEffectivelyClaimed } from '../../lib/escalation';\nimport { formatAgoCompact } from '../../lib/format';\nimport { metadataFacetUrl } from '../../lib/facet-url';\nimport { getDeep } from '../../lib/x-lt-bind';\nimport { typeColor } from '../../lib/type-color';\nimport type { LTEscalationRecord } from '../../api/types';\n\n/**\n * EscalationListView — the role-authored rich view of an escalation list, driven\n * by a versioned `list_schema` (x-lt-* markup). The list-page analog of the\n * resolve form: the same `{{domain.path}}` token binding (via interpolateHelp)\n * against each row's context, and MarkdownRenderer for rich bodies.\n *\n * Layouts:\n * active-history — single live item as a card on the left + history column on right\n * active — just the single live item card (no history)\n * facet-table — full pending queue as a table, columns from x-lt-columns\n * facet-board — one card per x-lt-group-by facet value (an entity board:\n * machines, stations), rendered from each group's latest row\n */\n\ninterface CardDef {\n title?: string;\n subtitle?: string;\n body?: string;\n fields?: { label: string; value: string; format?: string }[];\n}\n\ninterface HistoryDef {\n row?: { title?: string; subtitle?: string; meta?: string };\n limit?: number;\n status?: string;\n}\n\nexport interface ColumnDef {\n label: string;\n value: string;\n /** \"age\" renders an ISO timestamp as a compact age with an absolute tooltip. */\n format?: string;\n}\n\ninterface BoardCardDef {\n title?: string;\n /** Status chip — any token (commonly {{escalation.subtype}}). */\n state?: string;\n fields?: { label: string; value: string; format?: string }[];\n}\n\ninterface ListSchema {\n 'x-lt-layout'?: string;\n 'x-lt-help'?: string;\n 'x-lt-active'?: CardDef;\n 'x-lt-history'?: HistoryDef;\n 'x-lt-columns'?: ColumnDef[];\n /** facet-board: the \"domain.path\" whose value identifies each entity. */\n 'x-lt-group-by'?: string;\n /** facet-board: the per-entity card definition. */\n 'x-lt-card'?: BoardCardDef;\n}\n\n/**\n * Repaint-only minute tick so `format: \"age\"` values stay current. Pure\n * re-render — no network. Mounted once at the view root, only when the\n * schema actually uses ages.\n */\nfunction useAgeTick(enabled: boolean): void {\n const [, setTick] = useState(0);\n useEffect(() => {\n if (!enabled) return;\n const t = window.setInterval(() => setTick((n) => n + 1), 60_000);\n return () => window.clearInterval(t);\n }, [enabled]);\n}\n\nfunction schemaUsesAge(schema: ListSchema): boolean {\n return [...(schema['x-lt-columns'] ?? []), ...(schema['x-lt-card']?.fields ?? [])]\n .some((f) => f.format === 'age');\n}\n\n/** Build the token context for one escalation row (payloads are JSON strings). */\nexport function rowContext(e: LTEscalationRecord): HelpTokenContext {\n const parse = (s: string | null | undefined): Record<string, unknown> | null => {\n if (!s) return null;\n try {\n const v = JSON.parse(s);\n return v && typeof v === 'object' ? v : null;\n } catch {\n return null;\n }\n };\n return {\n escalation: e as unknown as Record<string, unknown>,\n metadata: e.metadata ?? null,\n envelope: parse(e.envelope),\n payload: parse(e.escalation_payload),\n resolver: parse(e.resolver_payload),\n };\n}\n\nconst ISO_DATETIME = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/;\nconst EM_DASH = '—';\n\n/**\n * Render an interpolated field value with a little care: `format: \"age\"` turns\n * a timestamp into a compact age (\"12m\", \"3h\") with the absolute time as its\n * tooltip; a full ISO datetime becomes a friendly, hoverable date; an empty\n * value a quiet em dash; anything else plain text. Authors bind tokens; we\n * make the common shapes look right.\n */\nfunction FieldValue({ raw, format }: { raw: string; format?: string }) {\n if (!raw || raw === EM_DASH) return <span className=\"text-text-quaternary\">{EM_DASH}</span>;\n if (format === 'age') {\n const d = new Date(raw);\n if (!Number.isNaN(d.getTime())) {\n return <span title={d.toLocaleString()} className=\"tabular-nums whitespace-nowrap\">{formatAgoCompact(raw)}</span>;\n }\n }\n if (ISO_DATETIME.test(raw)) return <DateValue date={raw} format=\"datetime\" className=\"text-text-primary\" />;\n return <>{raw}</>;\n}\n\nfunction ActiveCard({ esc, card, onOpen }: {\n esc: LTEscalationRecord;\n card: CardDef;\n onOpen?: () => void;\n}) {\n const ctx = rowContext(esc);\n const title = card.title ? interpolateHelp(card.title, ctx) : esc.type;\n const claimable = esc.status === 'pending' && !isEffectivelyClaimed(esc);\n return (\n <div>\n <div className=\"flex items-start justify-between gap-6\">\n <button onClick={onOpen} className=\"text-left group min-w-0\">\n <h3 className=\"heading-2 group-hover:text-accent transition-colors leading-tight\">\n {title}\n </h3>\n {card.subtitle && (\n <p className=\"text-xs text-text-tertiary mt-1.5\">{interpolateHelp(card.subtitle, ctx)}</p>\n )}\n </button>\n\n {/* Explicit way through to the detail page to claim the open item. */}\n {claimable && (\n <button\n onClick={onOpen}\n className=\"inline-flex items-center gap-1.5 px-4 py-2 rounded-md bg-accent text-text-inverse text-xs font-medium hover:bg-accent-hover transition-colors shrink-0\"\n >\n Claim\n <ArrowRight className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n\n {card.fields && card.fields.length > 0 && (\n <dl className=\"flex flex-wrap gap-x-10 gap-y-4 mt-6\">\n {card.fields.map((f, i) => (\n <div key={i}>\n <dt className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary\">{f.label}</dt>\n <dd className=\"text-xs text-text-primary mt-1\"><FieldValue raw={interpolateHelp(f.value, ctx)} /></dd>\n </div>\n ))}\n </dl>\n )}\n\n {card.body && (\n <div className=\"mt-7 pt-6 border-t border-surface-border/50\">\n <MarkdownRenderer content={interpolateHelp(card.body, ctx)} />\n </div>\n )}\n </div>\n );\n}\n\nfunction HistoryColumn({ role, def, onRowClick }: {\n role: string;\n def: HistoryDef;\n onRowClick?: (row: LTEscalationRecord) => void;\n}) {\n const [show, setShow] = useState(false);\n const query = useEscalations({\n role,\n status: def.status ?? 'resolved',\n sort_by: 'resolved_at',\n order: 'desc',\n limit: def.limit ?? 25,\n enabled: show,\n });\n const rows = query.data?.escalations ?? [];\n const total = query.data?.total ?? 0;\n const rowDef = def.row ?? {};\n\n if (!show) {\n return (\n <button\n onClick={() => setShow(true)}\n className=\"text-xs text-accent hover:underline\"\n data-testid=\"load-history\"\n >\n Load full history →\n </button>\n );\n }\n\n if (query.isLoading) {\n return <p className=\"text-xs text-text-tertiary italic\">Loading history…</p>;\n }\n\n if (rows.length === 0) {\n return <p className=\"text-xs text-text-tertiary italic\">No past revisions.</p>;\n }\n\n return (\n <div>\n <div className=\"divide-y divide-surface-border/40\">\n {rows.map((e) => {\n const ctx = rowContext(e);\n return (\n <button\n key={e.id}\n onClick={() => onRowClick?.(e)}\n className=\"w-full text-left py-2.5 group flex items-center gap-3\"\n >\n {/* Status as a bare outlined dot — colour carries the meaning. */}\n <span\n className={`w-1.5 h-1.5 shrink-0 rounded-full dot-ring ${STATUS_DOT_STYLES[e.status] ?? 'bg-status-pending'}`}\n title={e.status}\n />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-xs text-text-primary group-hover:text-accent transition-colors truncate\">\n {rowDef.title ? interpolateHelp(rowDef.title, ctx) : e.type}\n </span>\n {rowDef.subtitle && (\n <span className=\"block text-2xs text-text-tertiary truncate\">\n {interpolateHelp(rowDef.subtitle, ctx)}\n </span>\n )}\n </span>\n {rowDef.meta\n ? <span className=\"text-2xs text-text-tertiary shrink-0\">{interpolateHelp(rowDef.meta, ctx)}</span>\n : e.resolved_at && <DateValue date={e.resolved_at} format=\"relative\" className=\"text-2xs text-text-tertiary shrink-0 whitespace-nowrap\" />}\n </button>\n );\n })}\n </div>\n {total > rows.length && (\n <p className=\"text-2xs text-text-quaternary mt-3\">Showing {rows.length} of {total}.</p>\n )}\n </div>\n );\n}\n\n/** Multi-row pending queue as a facet table. Columns defined by x-lt-columns. */\nfunction FacetTable({ schema, rows, onRowClick }: {\n schema: ListSchema;\n rows: LTEscalationRecord[];\n onRowClick?: (row: LTEscalationRecord) => void;\n}) {\n const columns = schema['x-lt-columns'] ?? [];\n\n if (rows.length === 0) {\n return <p className=\"text-xs text-text-tertiary italic\">No pending items.</p>;\n }\n\n return (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-xs\">\n <thead>\n <tr className=\"border-b border-surface-border/60\">\n <th className=\"w-4 pb-2 pr-3\" aria-label=\"Status\" />\n {columns.map((col, i) => (\n <th\n key={i}\n className=\"text-left pb-2 pr-8 text-2xs font-semibold uppercase tracking-widest text-text-tertiary whitespace-nowrap\"\n >\n {col.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-surface-border/30\">\n {rows.map((row) => {\n const ctx = rowContext(row);\n return (\n <tr\n key={row.id}\n onClick={() => onRowClick?.(row)}\n className={onRowClick ? 'group cursor-pointer hover:bg-surface-hover' : 'group'}\n data-testid=\"facet-table-row\"\n >\n <td className=\"py-2.5 pr-3\">\n <span\n className={`w-1.5 h-1.5 inline-block rounded-full dot-ring ${STATUS_DOT_STYLES[row.status] ?? 'bg-status-pending'}`}\n title={row.status}\n />\n </td>\n {columns.map((col, i) => (\n <td\n key={i}\n className=\"py-2.5 pr-8 text-text-secondary group-hover:text-text-primary transition-colors\"\n >\n <FieldValue raw={interpolateHelp(col.value, ctx)} format={col.format} />\n </td>\n ))}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\nfunction SectionLabel({ children }: { children: React.ReactNode }) {\n return (\n <p className=\"text-2xs font-semibold uppercase tracking-widest text-text-tertiary mb-3\">{children}</p>\n );\n}\n\n// ── facet-board — one card per entity (machine, station) ─────────────────────\n\ninterface BoardGroup {\n key: string;\n /** The group's identity as stored (native type preserved for the facet URL). */\n rawValue: unknown;\n latest: LTEscalationRecord;\n count: number;\n}\n\n/**\n * Group rows by the resolved x-lt-group-by value; each card renders from the\n * group's most recent row (by created_at). Rows without the facet are skipped —\n * the board reflects the scope, it doesn't invent entities.\n */\nexport function groupBoardRows(rows: LTEscalationRecord[], groupBy: string): BoardGroup[] {\n const dot = groupBy.indexOf('.');\n const facetKey = groupBy.startsWith('metadata.') ? groupBy.slice('metadata.'.length) : null;\n const groups = new Map<string, BoardGroup>();\n for (const row of rows) {\n const ctx = rowContext(row);\n let v: unknown;\n try {\n v = dot === -1\n ? (ctx as unknown as Record<string, unknown>)[groupBy]\n : getDeep((ctx as unknown as Record<string, unknown>)[groupBy.slice(0, dot)], groupBy.slice(dot + 1));\n } catch {\n v = undefined;\n }\n if (v === undefined || v === null || v === '') continue;\n const key = String(v);\n const rawValue = facetKey ? (row.metadata?.[facetKey] ?? v) : v;\n const existing = groups.get(key);\n if (!existing) {\n groups.set(key, { key, rawValue, latest: row, count: 1 });\n } else {\n existing.count += 1;\n if (new Date(row.created_at) > new Date(existing.latest.created_at)) existing.latest = row;\n }\n }\n return [...groups.values()].sort((a, b) => a.key.localeCompare(b.key));\n}\n\n/** A field value token that is a pure metadata binding — facet-linkable. */\nconst METADATA_TOKEN = /^\\{\\{\\s*metadata\\.([a-zA-Z0-9_]+)\\s*\\}\\}$/;\n\nfunction FacetBoard({ schema, rows, role, onOpenDetail, onOpenGroup, onAddFacet }: {\n schema: ListSchema;\n rows: LTEscalationRecord[];\n role: string;\n /** Plain card click — the group's latest row opens in the detail view. */\n onOpenDetail?: (row: LTEscalationRecord) => void;\n /** History affordances — receive a filtered table/timeline deep link. */\n onOpenGroup?: (url: string) => void;\n /** Shift+click — merge one facet into the live filter set (additive). */\n onAddFacet?: (key: string, value: unknown) => void;\n}) {\n const groupBy = schema['x-lt-group-by'];\n const card = schema['x-lt-card'] ?? {};\n\n if (!groupBy) {\n return <p className=\"text-xs text-text-tertiary italic\">facet-board needs an x-lt-group-by path.</p>;\n }\n const facetKey = groupBy.startsWith('metadata.') ? groupBy.slice('metadata.'.length) : null;\n const groups = groupBoardRows(rows, groupBy);\n if (groups.length === 0) {\n return <p className=\"text-xs text-text-tertiary italic\">No entities in scope.</p>;\n }\n\n return (\n <div className=\"grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-4\" data-testid=\"facet-board\">\n {groups.map((g) => {\n const ctx = rowContext(g.latest);\n const title = card.title ? interpolateHelp(card.title, ctx) : g.key;\n const state = card.state ? interpolateHelp(card.state, ctx) : (g.latest.subtype || g.latest.status);\n const stateHue = typeColor(state);\n\n const activate = (e: { shiftKey: boolean }) => {\n if (e.shiftKey && facetKey && onAddFacet) {\n onAddFacet(facetKey, g.rawValue);\n return;\n }\n onOpenDetail?.(g.latest);\n };\n\n return (\n <div\n key={g.key}\n role=\"button\"\n tabIndex={0}\n onClick={activate}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); activate(e); }\n }}\n title={facetKey ? 'Open the latest item · ⇧ click to filter the board' : 'Open the latest item'}\n className=\"group/card border-l-2 border-accent/30 bg-surface-sunken/40 rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-surface-sunken/70 focus:outline-none focus-visible:ring-1 focus-visible:ring-accent/40\"\n data-testid=\"facet-board-card\"\n >\n <div className=\"flex items-center justify-between gap-2 mb-2.5\">\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-secondary truncate\">\n {title}\n </span>\n <span\n className=\"shrink-0 px-1.5 py-0.5 rounded text-2xs font-mono font-medium\"\n style={{ color: stateHue.text, backgroundColor: stateHue.bg }}\n title={state}\n >\n {state}\n </span>\n </div>\n {card.fields && card.fields.length > 0 && (\n <dl className=\"space-y-1\">\n {card.fields.map((f, i) => {\n // Pure metadata bindings get the same hover filter affordance\n // the table's MetadataCell offers; ⇧ click adds instead of replacing.\n const bound = f.value.match(METADATA_TOKEN)?.[1];\n const raw = bound ? g.latest.metadata?.[bound] : undefined;\n const linkable = bound != null && raw !== undefined && raw !== null && raw !== '';\n return (\n <div key={i} className=\"group/frow flex items-baseline justify-between gap-3\">\n <dt className=\"text-2xs uppercase tracking-wider text-text-quaternary shrink-0\">{f.label}</dt>\n <dd className=\"min-w-0 flex items-baseline gap-1 text-2xs text-text-primary\">\n <span className=\"truncate\">\n <FieldValue raw={interpolateHelp(f.value, ctx)} format={f.format} />\n </span>\n {/* Fixed-width trailing slot on EVERY row — linkable rows\n fill it with the filter/search pair the table's\n metadata cells offer — so all values share one right\n rail regardless of linkability. */}\n <span className=\"shrink-0 w-9 self-center flex items-center justify-end gap-px\">\n {linkable && (onOpenGroup || onAddFacet) && (\n <span className=\"flex items-center gap-px opacity-0 group-hover/frow:opacity-100 transition-opacity\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n if (e.shiftKey && onAddFacet) onAddFacet(bound, raw);\n else onOpenGroup?.(metadataFacetUrl(bound, raw, role));\n }}\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Filter ${role}: ${bound} = ${String(raw)} · ⇧ click adds to current filters`}\n data-testid=\"facet-field-filter\"\n >\n <ListFilter className=\"w-3 h-3\" />\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n onOpenGroup?.(metadataFacetUrl(bound, raw));\n }}\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Search all: ${bound} = ${String(raw)}`}\n data-testid=\"facet-field-search\"\n >\n <Search className=\"w-3 h-3\" />\n </button>\n </span>\n )}\n </span>\n </dd>\n </div>\n );\n })}\n </dl>\n )}\n\n </div>\n );\n })}\n </div>\n );\n}\n\nexport function EscalationListView({ role, listSchema, activeEscalations, onRowClick, onOpenGroup, onAddFacet, total, page, totalPages, pageSize, onPageChange, onPageSizeChange }: {\n role: string;\n listSchema: ListSchema;\n activeEscalations: LTEscalationRecord[];\n onRowClick?: (row: LTEscalationRecord) => void;\n /** facet-board history affordances — receive a filtered deep link. */\n onOpenGroup?: (url: string) => void;\n /** facet-board ⇧ click — merge one facet into the live filter set. */\n onAddFacet?: (key: string, value: unknown) => void;\n total?: number;\n page?: number;\n totalPages?: number;\n pageSize?: number;\n onPageChange?: (page: number) => void;\n onPageSizeChange?: (size: number) => void;\n}) {\n const layout = listSchema['x-lt-layout'];\n const card = listSchema['x-lt-active'] ?? {};\n const active = activeEscalations[0];\n const help = listSchema['x-lt-help'];\n useAgeTick(schemaUsesAge(listSchema));\n\n const activeBlock = active ? (\n <ActiveCard esc={active} card={card} onOpen={() => onRowClick?.(active)} />\n ) : (\n <p className=\"text-xs text-text-tertiary italic\">No active item right now.</p>\n );\n\n const header = help && active ? (\n <div className=\"mb-8\"><MarkdownRenderer content={interpolateHelp(help, rowContext(active))} /></div>\n ) : help ? (\n <div className=\"mb-8\"><MarkdownRenderer content={help} /></div>\n ) : null;\n\n if (layout === 'facet-table') {\n const resolvedTotal = total ?? activeEscalations.length;\n return (\n <div>\n {header}\n {resolvedTotal > 0 && (\n <p className=\"text-2xs text-text-tertiary mb-3 tabular-nums\">\n {resolvedTotal.toLocaleString()} result{resolvedTotal !== 1 ? 's' : ''}\n </p>\n )}\n <FacetTable schema={listSchema} rows={activeEscalations} onRowClick={onRowClick} />\n {page !== undefined && totalPages !== undefined && onPageChange && (\n <StickyPagination\n page={page}\n totalPages={totalPages}\n onPageChange={onPageChange}\n total={resolvedTotal}\n pageSize={pageSize ?? 25}\n onPageSizeChange={onPageSizeChange}\n />\n )}\n </div>\n );\n }\n\n if (layout === 'facet-board') {\n return (\n <div>\n {header}\n <FacetBoard\n schema={listSchema}\n rows={activeEscalations}\n role={role}\n onOpenDetail={onRowClick}\n onOpenGroup={onOpenGroup}\n onAddFacet={onAddFacet}\n />\n {page !== undefined && totalPages !== undefined && onPageChange && totalPages > 1 && (\n <StickyPagination\n page={page}\n totalPages={totalPages}\n onPageChange={onPageChange}\n total={total ?? activeEscalations.length}\n pageSize={pageSize ?? 25}\n onPageSizeChange={onPageSizeChange}\n />\n )}\n </div>\n );\n }\n\n if (layout === 'active-history') {\n return (\n <div>\n {header}\n <div className=\"grid grid-cols-1 @split:grid-cols-[1.6fr_1fr] gap-12 items-start\">\n <div>\n <SectionLabel>Active</SectionLabel>\n {activeBlock}\n </div>\n <div>\n <SectionLabel>History</SectionLabel>\n <HistoryColumn role={role} def={listSchema['x-lt-history'] ?? {}} onRowClick={onRowClick} />\n </div>\n </div>\n </div>\n );\n }\n\n // \"active\" (or any non-table layout): just the active card.\n return (\n <div>\n {header}\n {activeBlock}\n </div>\n );\n}\n","import { useMemo } from 'react';\nimport { useSettings } from '../api/settings';\nimport { DEFAULT_CLAIM_DURATIONS, formatClaimDuration } from '../lib/constants';\n\nexport interface ClaimDurationOption {\n value: string;\n label: string;\n}\n\n/**\n * Returns claim duration presets from server settings (with fallback).\n * Options are formatted for use in selects and tab rows.\n */\nexport function useClaimDurations(): ClaimDurationOption[] {\n const { data: settings } = useSettings();\n\n return useMemo(() => {\n const minutes = settings?.escalation?.claimDurations ?? DEFAULT_CLAIM_DURATIONS;\n return minutes.map((m) => ({\n value: String(m),\n label: formatClaimDuration(m),\n }));\n }, [settings]);\n}\n","import { useState, useEffect } from 'react';\n\nconst UNITS = [\n { value: 1, label: 'minutes' },\n { value: 60, label: 'hours' },\n] as const;\n\ninterface CustomDurationPickerProps {\n /** Called with the computed duration in minutes whenever quantity or unit changes */\n onChange: (minutes: number) => void;\n /** Compact variant for inline use (e.g. action bars) */\n compact?: boolean;\n /** Auto-focus the quantity input */\n autoFocus?: boolean;\n 'data-testid'?: string;\n}\n\nexport function CustomDurationPicker({\n onChange,\n compact,\n autoFocus,\n 'data-testid': testId = 'custom-duration-input',\n}: CustomDurationPickerProps) {\n const [quantity, setQuantity] = useState('');\n const [multiplier, setMultiplier] = useState(1);\n\n useEffect(() => {\n const q = parseInt(quantity);\n onChange(q > 0 ? q * multiplier : 0);\n }, [quantity, multiplier, onChange]);\n\n const textSize = compact ? 'text-xs' : 'text-sm';\n const inputWidth = compact ? 'w-16' : 'w-20';\n\n return (\n <div className=\"flex items-center gap-2\" data-testid={testId}>\n <input\n type=\"number\"\n min={1}\n max={multiplier === 60 ? 24 : 1440}\n value={quantity}\n onChange={(e) => setQuantity(e.target.value)}\n placeholder={multiplier === 60 ? 'hrs' : 'min'}\n className={`input ${textSize} ${inputWidth} text-center`}\n autoFocus={autoFocus}\n data-testid={`${testId}-quantity`}\n />\n <select\n value={multiplier}\n onChange={(e) => setMultiplier(parseInt(e.target.value))}\n className={`select ${textSize} py-1`}\n data-testid={`${testId}-unit`}\n >\n {UNITS.map((u) => (\n <option key={u.value} value={u.value}>{u.label}</option>\n ))}\n </select>\n </div>\n );\n}\n"],"names":["ConfirmCancelModal","open","onClose","onConfirm","selectedCount","isPending","error","title","jsx","Modal","jsxs","BLOCKED_KEYS","parsePath","path","segs","raw","m","name","brackets","b","setDeep","root","value","node","seg","next","childKey","wantArray","last","getDeep","bindPathFor","propName","propDef","bind","mapFormToPayload","formValues","formSchema","props","payload","def","mapPayloadToForm","form","v","HELP_DOMAINS","TOKEN_PATTERN","MISSING_VALUE","formatTokenValue","interpolateHelp","template","ctx","_match","rawPath","dot","domain","resolveHelpSource","schema","help","context","buildHelpMarkdown","source","defaultHelpMarkdown","isTerminal","status","claimed","claimedByMe","PALETTE","hash","str","h","i","typeColor","typeName","useAgeTick","enabled","setTick","useState","useEffect","t","n","schemaUsesAge","_a","f","rowContext","parse","s","ISO_DATETIME","EM_DASH","FieldValue","format","d","formatAgoCompact","DateValue","ActiveCard","esc","card","onOpen","claimable","isEffectivelyClaimed","ArrowRight","MarkdownRenderer","HistoryColumn","role","onRowClick","show","setShow","query","useEscalations","rows","total","_b","rowDef","e","STATUS_DOT_STYLES","FacetTable","columns","col","row","SectionLabel","children","groupBoardRows","groupBy","facetKey","groups","key","rawValue","existing","a","METADATA_TOKEN","FacetBoard","onOpenDetail","onOpenGroup","onAddFacet","g","state","stateHue","activate","bound","linkable","metadataFacetUrl","ListFilter","Search","EscalationListView","listSchema","activeEscalations","page","totalPages","pageSize","onPageChange","onPageSizeChange","layout","active","activeBlock","header","resolvedTotal","StickyPagination","useClaimDurations","settings","useSettings","useMemo","DEFAULT_CLAIM_DURATIONS","formatClaimDuration","UNITS","CustomDurationPicker","onChange","compact","autoFocus","testId","quantity","setQuantity","multiplier","setMultiplier","q","textSize","inputWidth","u"],"mappings":"8aAWO,SAASA,GAAmB,CACjC,KAAAC,EACA,QAAAC,EACA,UAAAC,EACA,cAAAC,EACA,UAAAC,EACA,MAAAC,CACF,EAA4B,CAC1B,MAAMC,EAAQH,GAAiBA,EAAgB,EAC3C,UAAUA,CAAa,eACvB,oBAEJ,OACEI,EAAAA,IAACC,GAAM,KAAAR,EAAY,QAAAC,EAAkB,MAAAK,EACnC,SAAAG,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAF,EAAAA,IAAC,IAAA,CAAE,UAAU,8BACV,SAAAJ,GAAiBA,EAAgB,EAC9B,gCAAgCA,CAAa,2FAC7C,yHAAA,CACN,EACAI,EAAAA,IAAC,IAAA,CAAE,UAAU,6BAA6B,SAAA,gCAA6B,EACtEF,GAASE,EAAAA,IAAC,IAAA,CAAE,UAAU,4BAA6B,WAAM,QAAQ,EAClEE,EAAAA,KAAC,MAAA,CAAI,UAAU,8BACb,SAAA,CAAAF,EAAAA,IAAC,UAAO,QAASN,EAAS,SAAUG,EAAW,UAAU,wBAAwB,SAAA,MAAA,CAEjF,EACAG,EAAAA,IAAC,SAAA,CACC,QAASL,EACT,SAAUE,EACV,UAAU,2HAET,WAAY,gBAAkB,aAAA,CAAA,CACjC,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CChCA,MAAMM,EAAe,IAAI,IAAI,CAAC,YAAa,cAAe,WAAW,CAAC,EAG/D,SAASC,EAAUC,EAAyB,CACjD,MAAMC,EAAkB,CAAA,EACxB,UAAWC,KAAOF,EAAK,MAAM,GAAG,EAAG,CACjC,MAAMG,EAAID,EAAI,MAAM,2BAA2B,EAC/C,GAAI,CAACC,EAAG,MAAM,IAAI,MAAM,oCAAoCD,CAAG,GAAG,EAClE,KAAM,CAAA,CAAGE,EAAMC,CAAQ,EAAIF,EAC3B,GAAIC,EAAM,CACR,GAAIN,EAAa,IAAIM,CAAI,QAAS,IAAI,MAAM,kCAAkCA,CAAI,GAAG,EACrFH,EAAK,KAAK,CAAE,IAAKG,CAAA,CAAM,CACzB,CACA,UAAWE,KAAKD,EAAS,MAAM,MAAM,GAAK,CAAA,EAAIJ,EAAK,KAAK,CAAE,MAAO,OAAOK,CAAC,EAAG,CAC9E,CACA,GAAIL,EAAK,SAAW,EAAG,MAAM,IAAI,MAAM,0BAA0BD,CAAI,GAAG,EACxE,OAAOC,CACT,CAGO,SAASM,EAAQC,EAA2BR,EAAcS,EAAsB,CACrF,MAAMR,EAAOF,EAAUC,CAAI,EAC3B,IAAIU,EAAYF,EAChB,QAAS,EAAI,EAAG,EAAIP,EAAK,OAAS,EAAG,IAAK,CACxC,MAAMU,EAAMV,EAAK,CAAC,EACZW,EAAOX,EAAK,EAAI,CAAC,EACjBY,EAAW,QAASF,EAAMA,EAAI,IAAMA,EAAI,MACxCG,EAAY,UAAWF,GACzBF,EAAKG,CAAQ,GAAK,MAAQ,OAAOH,EAAKG,CAAQ,GAAM,YACtDH,EAAKG,CAAQ,EAAIC,EAAY,CAAA,EAAK,CAAA,GAEpCJ,EAAOA,EAAKG,CAAQ,CACtB,CACA,MAAME,EAAOd,EAAKA,EAAK,OAAS,CAAC,EACjCS,EAAK,QAASK,EAAOA,EAAK,IAAMA,EAAK,KAAK,EAAIN,CAChD,CAGO,SAASO,EAAQR,EAAeR,EAAuB,CAC5D,IAAIU,EAAYF,EAChB,UAAWG,KAAOZ,EAAUC,CAAI,EAAG,CACjC,GAAIU,GAAQ,MAAQ,OAAOA,GAAS,SAAU,OAC9CA,EAAOA,EAAK,QAASC,EAAMA,EAAI,IAAMA,EAAI,KAAK,CAChD,CACA,OAAOD,CACT,CAGO,SAASO,EAAYC,EAAkBC,EAAkD,CAC9F,MAAMC,EAAOD,GAAA,YAAAA,EAAU,aACvB,OAAO,OAAOC,GAAS,UAAYA,EAAK,OAAS,EAAIA,EAAOF,CAC9D,CAQO,SAASG,GACdC,EACAC,EACqB,CACrB,MAAMC,EAAQD,GAAA,YAAAA,EAAY,WAC1B,GAAI,CAACC,EAAO,MAAO,CAAE,GAAGF,CAAA,EACxB,MAAMG,EAA+B,CAAA,EACrC,SAAW,CAACrB,EAAMsB,CAAG,IAAK,OAAO,QAAQF,CAAK,EACtCpB,KAAQkB,GACdf,EAAQkB,EAASR,EAAYb,EAAMsB,CAA0B,EAAGJ,EAAWlB,CAAI,CAAC,EAElF,OAAOqB,CACT,CAQO,SAASE,GACdF,EACAF,EACqB,CACrB,MAAMC,EAAQD,GAAA,YAAAA,EAAY,WAC1B,GAAI,CAACC,EAAO,OAAOC,EAAU,CAAE,GAAGA,CAAA,EAAY,CAAA,EAC9C,MAAMG,EAA4B,CAAA,EAClC,SAAW,CAACxB,EAAMsB,CAAG,IAAK,OAAO,QAAQF,CAAK,EAAG,CAC/C,MAAMK,EAAIb,EAAQS,EAASR,EAAYb,EAAMsB,CAA0B,CAAC,EACpEG,IAAM,SAAWD,EAAKxB,CAAI,EAAIyB,EACpC,CACA,OAAOD,CACT,CCxFO,MAAME,GAAe,CAAC,aAAc,WAAY,WAAY,UAAW,UAAU,EAKlFC,GAAgB,2BAChBC,EAAgB,IAEtB,SAASC,EAAiBxB,EAAwB,CAChD,GAA2BA,GAAU,KAAM,OAAOuB,EAClD,GAAI,OAAOvB,GAAU,SAAU,OAAOA,EACtC,GAAI,OAAOA,GAAU,UAAY,OAAOA,GAAU,UAAW,OAAO,OAAOA,CAAK,EAChF,GAAI,CACF,OAAO,KAAK,UAAUA,CAAK,CAC7B,MAAQ,CACN,OAAOuB,CACT,CACF,CAGO,SAASE,EAAgBC,EAAkBC,EAA+B,CAC/E,OAAOD,EAAS,QAAQJ,GAAe,CAACM,EAAQC,IAAoB,CAClE,MAAMC,EAAMD,EAAQ,QAAQ,GAAG,EACzBE,EAAUD,IAAQ,GAAKD,EAAUA,EAAQ,MAAM,EAAGC,CAAG,EAC3D,GAAI,CAACT,GAAa,SAASU,CAAM,EAAG,OAAOR,EAC3C,MAAMxB,EAAO4B,EAAII,CAAM,EACvB,GAAID,IAAQ,GAAI,OAAON,EAAiBzB,CAAI,EAC5C,GAAI,CACF,OAAOyB,EAAiBjB,EAAQR,EAAM8B,EAAQ,MAAMC,EAAM,CAAC,CAAC,CAAC,CAC/D,MAAQ,CACN,OAAOP,CACT,CACF,CAAC,CACH,CAGO,SAASS,GAAkBC,EAAmE,CACnG,MAAMC,EAAOD,GAAA,YAAAA,EAAS,aACtB,GAAI,OAAOC,GAAS,UAAYA,EAAK,OAAO,OAAS,EAAG,OAAOA,EAC/D,MAAMC,EAAUF,GAAA,YAAAA,EAAS,gBACzB,OAAI,OAAOE,GAAY,UAAYA,EAAQ,OAAO,OAAS,EAAUA,EAC9D,IACT,CAGO,SAASC,GACdH,EACAN,EACe,CACf,MAAMU,EAASL,GAAkBC,CAAM,EACvC,OAAOI,EAASZ,EAAgBY,EAAQV,CAAG,EAAI,IACjD,CAaO,SAASW,GAAoB,CAAE,WAAAC,EAAY,OAAAC,EAAQ,QAAAC,EAAS,YAAAC,GAAsC,CACvG,OAAIH,EACKC,IAAW,YACd,oEACA,gFAEFE,EAAoB,gFACpBD,EAAgB,8FACb,2CACT,CChFA,MAAME,EAA+C,CACnD,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,mBAAqB,GAAI,uBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,eAAqB,GAAI,mBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,mBAAqB,GAAI,uBAAA,EACjC,CAAE,KAAM,iBAAqB,GAAI,qBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,iBAAqB,GAAI,qBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,eAAqB,GAAI,mBAAA,EACjC,CAAE,KAAM,iBAAqB,GAAI,qBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,eAAqB,GAAI,mBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,iBAAqB,GAAI,qBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,CACnC,EAEA,SAASC,GAAKC,EAAqB,CACjC,IAAIC,EAAI,EACR,QAASC,EAAI,EAAGA,EAAIF,EAAI,OAAQE,IAC9BD,GAAMA,GAAK,GAAKA,EAAID,EAAI,WAAWE,CAAC,EAAK,EAE3C,OAAO,KAAK,IAAID,CAAC,CACnB,CAEO,SAASE,GAAUC,EAAgD,CACxE,OAAON,EAAQC,GAAKK,CAAQ,EAAIN,EAAQ,MAAM,CAChD,CCwBA,SAASO,GAAWC,EAAwB,CAC1C,KAAM,EAAGC,CAAO,EAAIC,EAAAA,SAAS,CAAC,EAC9BC,EAAAA,UAAU,IAAM,CACd,GAAI,CAACH,EAAS,OACd,MAAMI,EAAI,OAAO,YAAY,IAAMH,EAASI,GAAMA,EAAI,CAAC,EAAG,GAAM,EAChE,MAAO,IAAM,OAAO,cAAcD,CAAC,CACrC,EAAG,CAACJ,CAAO,CAAC,CACd,CAEA,SAASM,GAAcxB,EAA6B,OAClD,MAAO,CAAC,GAAIA,EAAO,cAAc,GAAK,CAAA,EAAK,KAAIyB,EAAAzB,EAAO,WAAW,IAAlB,YAAAyB,EAAqB,SAAU,CAAA,CAAG,EAC9E,KAAMC,GAAMA,EAAE,SAAW,KAAK,CACnC,CAGO,SAASC,EAAW,EAAyC,CAClE,MAAMC,EAASC,GAAiE,CAC9E,GAAI,CAACA,EAAG,OAAO,KACf,GAAI,CACF,MAAM1C,EAAI,KAAK,MAAM0C,CAAC,EACtB,OAAO1C,GAAK,OAAOA,GAAM,SAAWA,EAAI,IAC1C,MAAQ,CACN,OAAO,IACT,CACF,EACA,MAAO,CACL,WAAY,EACZ,SAAU,EAAE,UAAY,KACxB,SAAUyC,EAAM,EAAE,QAAQ,EAC1B,QAASA,EAAM,EAAE,kBAAkB,EACnC,SAAUA,EAAM,EAAE,gBAAgB,CAAA,CAEtC,CAEA,MAAME,GAAe,iCACfC,EAAU,IAShB,SAASC,EAAW,CAAE,IAAAxE,EAAK,OAAAyE,GAA4C,CACrE,GAAI,CAACzE,GAAOA,IAAQuE,SAAgB9E,EAAAA,IAAC,OAAA,CAAK,UAAU,uBAAwB,SAAA8E,CAAA,CAAQ,EACpF,GAAIE,IAAW,MAAO,CACpB,MAAMC,EAAI,IAAI,KAAK1E,CAAG,EACtB,GAAI,CAAC,OAAO,MAAM0E,EAAE,QAAA,CAAS,EAC3B,OAAOjF,EAAAA,IAAC,OAAA,CAAK,MAAOiF,EAAE,eAAA,EAAkB,UAAU,iCAAkC,SAAAC,EAAiB3E,CAAG,CAAA,CAAE,CAE9G,CACA,OAAIsE,GAAa,KAAKtE,CAAG,EAAUP,EAAAA,IAACmF,EAAA,CAAU,KAAM5E,EAAK,OAAO,WAAW,UAAU,mBAAA,CAAoB,oBAC/F,SAAAA,CAAA,CAAI,CAChB,CAEA,SAAS6E,GAAW,CAAE,IAAAC,EAAK,KAAAC,EAAM,OAAAC,GAI9B,CACD,MAAM9C,EAAMiC,EAAWW,CAAG,EACpBtF,EAAQuF,EAAK,MAAQ/C,EAAgB+C,EAAK,MAAO7C,CAAG,EAAI4C,EAAI,KAC5DG,EAAYH,EAAI,SAAW,WAAa,CAACI,EAAqBJ,CAAG,EACvE,cACG,MAAA,CACC,SAAA,CAAAnF,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,QAASqF,EAAQ,UAAU,0BACjC,SAAA,CAAAvF,EAAAA,IAAC,KAAA,CAAG,UAAU,oEACX,SAAAD,EACH,EACCuF,EAAK,UACJtF,MAAC,IAAA,CAAE,UAAU,oCAAqC,SAAAuC,EAAgB+C,EAAK,SAAU7C,CAAG,CAAA,CAAE,CAAA,EAE1F,EAGC+C,GACCtF,EAAAA,KAAC,SAAA,CACC,QAASqF,EACT,UAAU,yJACX,SAAA,CAAA,QAECvF,EAAAA,IAAC0F,EAAA,CAAW,UAAU,aAAA,CAAc,CAAA,CAAA,CAAA,CACtC,EAEJ,EAECJ,EAAK,QAAUA,EAAK,OAAO,OAAS,GACnCtF,EAAAA,IAAC,KAAA,CAAG,UAAU,uCACX,WAAK,OAAO,IAAI,CAACyE,EAAGZ,WAClB,MAAA,CACC,SAAA,CAAA7D,EAAAA,IAAC,KAAA,CAAG,UAAU,sEAAuE,SAAAyE,EAAE,MAAM,EAC7FzE,EAAAA,IAAC,KAAA,CAAG,UAAU,iCAAiC,SAAAA,EAAAA,IAAC+E,EAAA,CAAW,IAAKxC,EAAgBkC,EAAE,MAAOhC,CAAG,CAAA,CAAG,CAAA,CAAE,CAAA,GAFzFoB,CAGV,CACD,EACH,EAGDyB,EAAK,MACJtF,MAAC,MAAA,CAAI,UAAU,8CACb,SAAAA,EAAAA,IAAC2F,EAAA,CAAiB,QAASpD,EAAgB+C,EAAK,KAAM7C,CAAG,EAAG,CAAA,CAC9D,CAAA,EAEJ,CAEJ,CAEA,SAASmD,GAAc,CAAE,KAAAC,EAAM,IAAA9D,EAAK,WAAA+D,GAIjC,SACD,KAAM,CAACC,EAAMC,CAAO,EAAI7B,EAAAA,SAAS,EAAK,EAChC8B,EAAQC,EAAe,CAC3B,KAAAL,EACA,OAAQ9D,EAAI,QAAU,WACtB,QAAS,cACT,MAAO,OACP,MAAOA,EAAI,OAAS,GACpB,QAASgE,CAAA,CACV,EACKI,IAAO3B,EAAAyB,EAAM,OAAN,YAAAzB,EAAY,cAAe,CAAA,EAClC4B,IAAQC,EAAAJ,EAAM,OAAN,YAAAI,EAAY,QAAS,EAC7BC,EAASvE,EAAI,KAAO,CAAA,EAE1B,OAAKgE,EAYDE,EAAM,UACDjG,EAAAA,IAAC,IAAA,CAAE,UAAU,oCAAoC,SAAA,mBAAgB,EAGtEmG,EAAK,SAAW,EACXnG,EAAAA,IAAC,IAAA,CAAE,UAAU,oCAAoC,SAAA,qBAAkB,SAIzE,MAAA,CACC,SAAA,CAAAA,MAAC,OAAI,UAAU,oCACZ,SAAAmG,EAAK,IAAKI,GAAM,CACf,MAAM9D,EAAMiC,EAAW6B,CAAC,EACxB,OACErG,EAAAA,KAAC,SAAA,CAEC,QAAS,IAAM4F,GAAA,YAAAA,EAAaS,GAC5B,UAAU,wDAGV,SAAA,CAAAvG,EAAAA,IAAC,OAAA,CACC,UAAW,8CAA8CwG,EAAkBD,EAAE,MAAM,GAAK,mBAAmB,GAC3G,MAAOA,EAAE,MAAA,CAAA,EAEXrG,EAAAA,KAAC,OAAA,CAAK,UAAU,iBACd,SAAA,CAAAF,EAAAA,IAAC,OAAA,CAAK,UAAU,qFACb,SAAAsG,EAAO,MAAQ/D,EAAgB+D,EAAO,MAAO7D,CAAG,EAAI8D,EAAE,IAAA,CACzD,EACCD,EAAO,UACNtG,MAAC,OAAA,CAAK,UAAU,6CACb,SAAAuC,EAAgB+D,EAAO,SAAU7D,CAAG,CAAA,CACvC,CAAA,EAEJ,EACC6D,EAAO,KACJtG,MAAC,OAAA,CAAK,UAAU,uCAAwC,SAAAuC,EAAgB+D,EAAO,KAAM7D,CAAG,CAAA,CAAE,EAC1F8D,EAAE,mBAAgBpB,EAAA,CAAU,KAAMoB,EAAE,YAAa,OAAO,WAAW,UAAU,wDAAA,CAAyD,CAAA,CAAA,EArBrIA,EAAE,EAAA,CAwBb,CAAC,CAAA,CACH,EACCH,EAAQD,EAAK,QACZjG,EAAAA,KAAC,IAAA,CAAE,UAAU,qCAAqC,SAAA,CAAA,WAASiG,EAAK,OAAO,OAAKC,EAAM,GAAA,CAAA,CAAC,CAAA,EAEvF,EAtDEpG,EAAAA,IAAC,SAAA,CACC,QAAS,IAAMgG,EAAQ,EAAI,EAC3B,UAAU,sCACV,cAAY,eACb,SAAA,qBAAA,CAAA,CAoDP,CAGA,SAASS,GAAW,CAAE,OAAA1D,EAAQ,KAAAoD,EAAM,WAAAL,GAIjC,CACD,MAAMY,EAAU3D,EAAO,cAAc,GAAK,CAAA,EAE1C,OAAIoD,EAAK,SAAW,EACXnG,EAAAA,IAAC,IAAA,CAAE,UAAU,oCAAoC,SAAA,oBAAiB,QAIxE,MAAA,CAAI,UAAU,kBACb,SAAAE,EAAAA,KAAC,QAAA,CAAM,UAAU,iBACf,SAAA,CAAAF,MAAC,QAAA,CACC,SAAAE,EAAAA,KAAC,KAAA,CAAG,UAAU,oCACZ,SAAA,CAAAF,EAAAA,IAAC,KAAA,CAAG,UAAU,gBAAgB,aAAW,SAAS,EACjD0G,EAAQ,IAAI,CAACC,EAAK9C,IACjB7D,EAAAA,IAAC,KAAA,CAEC,UAAU,4GAET,SAAA2G,EAAI,KAAA,EAHA9C,CAAA,CAKR,CAAA,CAAA,CACH,CAAA,CACF,QACC,QAAA,CAAM,UAAU,oCACd,SAAAsC,EAAK,IAAKS,GAAQ,CACjB,MAAMnE,EAAMiC,EAAWkC,CAAG,EAC1B,OACE1G,EAAAA,KAAC,KAAA,CAEC,QAAS,IAAM4F,GAAA,YAAAA,EAAac,GAC5B,UAAWd,EAAa,8CAAgD,QACxE,cAAY,kBAEZ,SAAA,CAAA9F,EAAAA,IAAC,KAAA,CAAG,UAAU,cACZ,SAAAA,EAAAA,IAAC,OAAA,CACC,UAAW,kDAAkDwG,EAAkBI,EAAI,MAAM,GAAK,mBAAmB,GACjH,MAAOA,EAAI,MAAA,CAAA,EAEf,EACCF,EAAQ,IAAI,CAACC,EAAK9C,IACjB7D,EAAAA,IAAC,KAAA,CAEC,UAAU,kFAEV,SAAAA,EAAAA,IAAC+E,EAAA,CAAW,IAAKxC,EAAgBoE,EAAI,MAAOlE,CAAG,EAAG,OAAQkE,EAAI,MAAA,CAAQ,CAAA,EAHjE9C,CAAA,CAKR,CAAA,CAAA,EAlBI+C,EAAI,EAAA,CAqBf,CAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CAEA,SAASC,EAAa,CAAE,SAAAC,GAA2C,CACjE,OACE9G,EAAAA,IAAC,IAAA,CAAE,UAAU,2EAA4E,SAAA8G,CAAA,CAAS,CAEtG,CAiBO,SAASC,GAAeZ,EAA4Ba,EAA+B,OACxF,MAAMpE,EAAMoE,EAAQ,QAAQ,GAAG,EACzBC,EAAWD,EAAQ,WAAW,WAAW,EAAIA,EAAQ,MAAM,CAAkB,EAAI,KACjFE,MAAa,IACnB,UAAWN,KAAOT,EAAM,CACtB,MAAM1D,EAAMiC,EAAWkC,CAAG,EAC1B,IAAI1E,EACJ,GAAI,CACFA,EAAIU,IAAQ,GACPH,EAA2CuE,CAAO,EACnD3F,EAASoB,EAA2CuE,EAAQ,MAAM,EAAGpE,CAAG,CAAC,EAAGoE,EAAQ,MAAMpE,EAAM,CAAC,CAAC,CACxG,MAAQ,CACNV,EAAI,MACN,CACA,GAAuBA,GAAM,MAAQA,IAAM,GAAI,SAC/C,MAAMiF,EAAM,OAAOjF,CAAC,EACdkF,EAAWH,IAAYzC,EAAAoC,EAAI,WAAJ,YAAApC,EAAeyC,KAAa/E,EAAKA,EACxDmF,EAAWH,EAAO,IAAIC,CAAG,EAC1BE,GAGHA,EAAS,OAAS,EACd,IAAI,KAAKT,EAAI,UAAU,EAAI,IAAI,KAAKS,EAAS,OAAO,UAAU,IAAGA,EAAS,OAAST,IAHvFM,EAAO,IAAIC,EAAK,CAAE,IAAAA,EAAK,SAAAC,EAAU,OAAQR,EAAK,MAAO,EAAG,CAK5D,CACA,MAAO,CAAC,GAAGM,EAAO,OAAA,CAAQ,EAAE,KAAK,CAACI,EAAG3G,IAAM2G,EAAE,IAAI,cAAc3G,EAAE,GAAG,CAAC,CACvE,CAGA,MAAM4G,GAAiB,4CAEvB,SAASC,GAAW,CAAE,OAAAzE,EAAQ,KAAAoD,EAAM,KAAAN,EAAM,aAAA4B,EAAc,YAAAC,EAAa,WAAAC,GAUlE,CACD,MAAMX,EAAUjE,EAAO,eAAe,EAChCuC,EAAOvC,EAAO,WAAW,GAAK,CAAA,EAEpC,GAAI,CAACiE,EACH,OAAOhH,EAAAA,IAAC,IAAA,CAAE,UAAU,oCAAoC,SAAA,2CAAwC,EAElG,MAAMiH,EAAWD,EAAQ,WAAW,WAAW,EAAIA,EAAQ,MAAM,CAAkB,EAAI,KACjFE,EAASH,GAAeZ,EAAMa,CAAO,EAC3C,OAAIE,EAAO,SAAW,EACblH,EAAAA,IAAC,IAAA,CAAE,UAAU,oCAAoC,SAAA,wBAAqB,EAI7EA,MAAC,OAAI,UAAU,6DAA6D,cAAY,cACrF,SAAAkH,EAAO,IAAKU,GAAM,CACjB,MAAMnF,EAAMiC,EAAWkD,EAAE,MAAM,EACzB7H,EAAQuF,EAAK,MAAQ/C,EAAgB+C,EAAK,MAAO7C,CAAG,EAAImF,EAAE,IAC1DC,EAAQvC,EAAK,MAAQ/C,EAAgB+C,EAAK,MAAO7C,CAAG,EAAKmF,EAAE,OAAO,SAAWA,EAAE,OAAO,OACtFE,EAAWhE,GAAU+D,CAAK,EAE1BE,EAAYxB,GAA6B,CAC7C,GAAIA,EAAE,UAAYU,GAAYU,EAAY,CACxCA,EAAWV,EAAUW,EAAE,QAAQ,EAC/B,MACF,CACAH,GAAA,MAAAA,EAAeG,EAAE,OACnB,EAEA,OACE1H,EAAAA,KAAC,MAAA,CAEC,KAAK,SACL,SAAU,EACV,QAAS6H,EACT,UAAYxB,GAAM,EACZA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OAAOA,EAAE,eAAA,EAAkBwB,EAASxB,CAAC,EAC1E,EACA,MAAOU,EAAW,qDAAuD,uBACzE,UAAU,6NACV,cAAY,mBAEZ,SAAA,CAAA/G,EAAAA,KAAC,MAAA,CAAI,UAAU,iDACb,SAAA,CAAAF,EAAAA,IAAC,OAAA,CAAK,UAAU,+EACb,SAAAD,EACH,EACAC,EAAAA,IAAC,OAAA,CACC,UAAU,gEACV,MAAO,CAAE,MAAO8H,EAAS,KAAM,gBAAiBA,EAAS,EAAA,EACzD,MAAOD,EAEN,SAAAA,CAAA,CAAA,CACH,EACF,EACCvC,EAAK,QAAUA,EAAK,OAAO,OAAS,GACnCtF,EAAAA,IAAC,KAAA,CAAG,UAAU,YACX,SAAAsF,EAAK,OAAO,IAAI,CAACb,EAAGZ,IAAM,SAGzB,MAAMmE,GAAQxD,EAAAC,EAAE,MAAM,MAAM8C,EAAc,IAA5B,YAAA/C,EAAgC,GACxCjE,EAAMyH,GAAQ3B,EAAAuB,EAAE,OAAO,WAAT,YAAAvB,EAAoB2B,GAAS,OAC3CC,EAAWD,GAAS,MAAQzH,IAAQ,QAAaA,IAAQ,MAAQA,IAAQ,GAC/E,OACEL,EAAAA,KAAC,MAAA,CAAY,UAAU,uDACrB,SAAA,CAAAF,EAAAA,IAAC,KAAA,CAAG,UAAU,kEAAmE,SAAAyE,EAAE,MAAM,EACzFvE,EAAAA,KAAC,KAAA,CAAG,UAAU,+DACZ,SAAA,CAAAF,EAAAA,IAAC,OAAA,CAAK,UAAU,WACd,SAAAA,EAAAA,IAAC+E,GAAW,IAAKxC,EAAgBkC,EAAE,MAAOhC,CAAG,EAAG,OAAQgC,EAAE,OAAQ,EACpE,EAKAzE,EAAAA,IAAC,OAAA,CAAK,UAAU,gEACb,SAAAiI,IAAaP,GAAeC,IAC3BzH,EAAAA,KAAC,OAAA,CAAK,UAAU,qFACd,SAAA,CAAAF,EAAAA,IAAC,SAAA,CACC,QAAUuG,GAAM,CACdA,EAAE,gBAAA,EACEA,EAAE,UAAYoB,EAAYA,EAAWK,EAAOzH,CAAG,EAC9CmH,GAAA,MAAAA,EAAcQ,EAAiBF,EAAOzH,EAAKsF,CAAI,EACtD,EACA,UAAU,yEACV,MAAO,UAAUA,CAAI,KAAKmC,CAAK,MAAM,OAAOzH,CAAG,CAAC,qCAChD,cAAY,qBAEZ,SAAAP,EAAAA,IAACmI,EAAA,CAAW,UAAU,SAAA,CAAU,CAAA,CAAA,EAElCnI,EAAAA,IAAC,SAAA,CACC,QAAUuG,GAAM,CACdA,EAAE,gBAAA,EACFmB,GAAA,MAAAA,EAAcQ,EAAiBF,EAAOzH,CAAG,EAC3C,EACA,UAAU,yEACV,MAAO,eAAeyH,CAAK,MAAM,OAAOzH,CAAG,CAAC,GAC5C,cAAY,qBAEZ,SAAAP,EAAAA,IAACoI,EAAA,CAAO,UAAU,SAAA,CAAU,CAAA,CAAA,CAC9B,CAAA,CACF,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,CAAA,EAvCQvE,CAwCV,CAEJ,CAAC,CAAA,CACH,CAAA,CAAA,EA3EG+D,EAAE,GAAA,CAgFb,CAAC,CAAA,CACH,CAEJ,CAEO,SAASS,GAAmB,CAAE,KAAAxC,EAAM,WAAAyC,EAAY,kBAAAC,EAAmB,WAAAzC,EAAY,YAAA4B,EAAa,WAAAC,EAAY,MAAAvB,EAAO,KAAAoC,EAAM,WAAAC,EAAY,SAAAC,EAAU,aAAAC,EAAc,iBAAAC,GAe7J,CACD,MAAMC,EAASP,EAAW,aAAa,EACjChD,EAAOgD,EAAW,aAAa,GAAK,CAAA,EACpCQ,EAASP,EAAkB,CAAC,EAC5BvF,EAAOsF,EAAW,WAAW,EACnCtE,GAAWO,GAAc+D,CAAU,CAAC,EAEpC,MAAMS,EAAcD,EAClB9I,MAACoF,GAAA,CAAW,IAAK0D,EAAQ,KAAAxD,EAAY,OAAQ,IAAMQ,GAAA,YAAAA,EAAagD,EAAM,CAAG,QAExE,IAAA,CAAE,UAAU,oCAAoC,SAAA,4BAAyB,EAGtEE,EAAShG,GAAQ8F,EACrB9I,EAAAA,IAAC,MAAA,CAAI,UAAU,OAAO,SAAAA,EAAAA,IAAC2F,EAAA,CAAiB,QAASpD,EAAgBS,EAAM0B,EAAWoE,CAAM,CAAC,CAAA,CAAG,CAAA,CAAE,EAC5F9F,EACFhD,EAAAA,IAAC,MAAA,CAAI,UAAU,OAAO,SAAAA,EAAAA,IAAC2F,EAAA,CAAiB,QAAS3C,CAAA,CAAM,CAAA,CAAE,EACvD,KAEJ,GAAI6F,IAAW,cAAe,CAC5B,MAAMI,EAAgB7C,GAASmC,EAAkB,OACjD,cACG,MAAA,CACE,SAAA,CAAAS,EACAC,EAAgB,GACf/I,OAAC,IAAA,CAAE,UAAU,gDACV,SAAA,CAAA+I,EAAc,eAAA,EAAiB,UAAQA,IAAkB,EAAI,IAAM,EAAA,EACtE,QAEDxC,GAAA,CAAW,OAAQ6B,EAAY,KAAMC,EAAmB,WAAAzC,EAAwB,EAChF0C,IAAS,QAAaC,IAAe,QAAaE,GACjD3I,EAAAA,IAACkJ,EAAA,CACC,KAAAV,EACA,WAAAC,EACA,aAAAE,EACA,MAAOM,EACP,SAAUP,GAAY,GACtB,iBAAAE,CAAA,CAAA,CACF,EAEJ,CAEJ,CAEA,OAAIC,IAAW,qBAEV,MAAA,CACE,SAAA,CAAAG,EACDhJ,EAAAA,IAACwH,GAAA,CACC,OAAQc,EACR,KAAMC,EACN,KAAA1C,EACA,aAAcC,EACd,YAAA4B,EACA,WAAAC,CAAA,CAAA,EAEDa,IAAS,QAAaC,IAAe,QAAaE,GAAgBF,EAAa,GAC9EzI,EAAAA,IAACkJ,EAAA,CACC,KAAAV,EACA,WAAAC,EACA,aAAAE,EACA,MAAOvC,GAASmC,EAAkB,OAClC,SAAUG,GAAY,GACtB,iBAAAE,CAAA,CAAA,CACF,EAEJ,EAIAC,IAAW,wBAEV,MAAA,CACE,SAAA,CAAAG,EACD9I,EAAAA,KAAC,MAAA,CAAI,UAAU,mEACb,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAF,EAAAA,IAAC6G,GAAa,SAAA,QAAA,CAAM,EACnBkC,CAAA,EACH,SACC,MAAA,CACC,SAAA,CAAA/I,EAAAA,IAAC6G,GAAa,SAAA,SAAA,CAAO,EACrB7G,MAAC4F,IAAc,KAAAC,EAAY,IAAKyC,EAAW,cAAc,GAAK,CAAA,EAAI,WAAAxC,CAAA,CAAwB,CAAA,CAAA,CAC5F,CAAA,CAAA,CACF,CAAA,EACF,SAMD,MAAA,CACE,SAAA,CAAAkD,EACAD,CAAA,EACH,CAEJ,CCnlBO,SAASI,IAA2C,CACzD,KAAM,CAAE,KAAMC,CAAA,EAAaC,EAAA,EAE3B,OAAOC,EAAAA,QAAQ,IAAM,OAEnB,SADgB9E,EAAA4E,GAAA,YAAAA,EAAU,aAAV,YAAA5E,EAAsB,iBAAkB+E,GACzC,IAAK/I,IAAO,CACzB,MAAO,OAAOA,CAAC,EACf,MAAOgJ,EAAoBhJ,CAAC,CAAA,EAC5B,CACJ,EAAG,CAAC4I,CAAQ,CAAC,CACf,CCrBA,MAAMK,GAAQ,CACZ,CAAE,MAAO,EAAG,MAAO,SAAA,EACnB,CAAE,MAAO,GAAI,MAAO,OAAA,CACtB,EAYO,SAASC,GAAqB,CACnC,SAAAC,EACA,QAAAC,EACA,UAAAC,EACA,cAAeC,EAAS,uBAC1B,EAA8B,CAC5B,KAAM,CAACC,EAAUC,CAAW,EAAI7F,EAAAA,SAAS,EAAE,EACrC,CAAC8F,EAAYC,CAAa,EAAI/F,EAAAA,SAAS,CAAC,EAE9CC,EAAAA,UAAU,IAAM,CACd,MAAM+F,EAAI,SAASJ,CAAQ,EAC3BJ,EAASQ,EAAI,EAAIA,EAAIF,EAAa,CAAC,CACrC,EAAG,CAACF,EAAUE,EAAYN,CAAQ,CAAC,EAEnC,MAAMS,EAAWR,EAAU,UAAY,UACjCS,EAAaT,EAAU,OAAS,OAEtC,OACE1J,EAAAA,KAAC,MAAA,CAAI,UAAU,0BAA0B,cAAa4J,EACpD,SAAA,CAAA9J,EAAAA,IAAC,QAAA,CACC,KAAK,SACL,IAAK,EACL,IAAKiK,IAAe,GAAK,GAAK,KAC9B,MAAOF,EACP,SAAWxD,GAAMyD,EAAYzD,EAAE,OAAO,KAAK,EAC3C,YAAa0D,IAAe,GAAK,MAAQ,MACzC,UAAW,SAASG,CAAQ,IAAIC,CAAU,eAC1C,UAAAR,EACA,cAAa,GAAGC,CAAM,WAAA,CAAA,EAExB9J,EAAAA,IAAC,SAAA,CACC,MAAOiK,EACP,SAAW1D,GAAM2D,EAAc,SAAS3D,EAAE,OAAO,KAAK,CAAC,EACvD,UAAW,UAAU6D,CAAQ,QAC7B,cAAa,GAAGN,CAAM,QAErB,SAAAL,GAAM,IAAKa,GACVtK,EAAAA,IAAC,SAAA,CAAqB,MAAOsK,EAAE,MAAQ,SAAAA,EAAE,KAAA,EAA5BA,EAAE,KAAgC,CAChD,CAAA,CAAA,CACH,EACF,CAEJ"}
|