@hotmeshio/long-tail 0.10.4 → 0.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.d.ts +1 -0
- package/build/index.js +5 -3
- package/build/themes/midnight.d.ts +14 -0
- package/build/themes/midnight.js +67 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/dashboard/dist/assets/{AdminDashboard-Cma2NGsF.js → AdminDashboard-B5B8cf1A.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Cma2NGsF.js.map → AdminDashboard-B5B8cf1A.js.map} +1 -1
- package/dashboard/dist/assets/AgentConfigPage-BxuHbkDF.js +16 -0
- package/dashboard/dist/assets/{AgentConfigPage-CbIhM-fa.js.map → AgentConfigPage-BxuHbkDF.js.map} +1 -1
- package/dashboard/dist/assets/AgentDetailPage-Bv89ria_.js +4 -0
- package/dashboard/dist/assets/AgentDetailPage-Bv89ria_.js.map +1 -0
- package/dashboard/dist/assets/AgentsPage-BPgki44D.js +2 -0
- package/dashboard/dist/assets/AgentsPage-BPgki44D.js.map +1 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-Dq_FyUcB.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-Dq_FyUcB.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-CidlGr6f.js → BotPicker-D-WegFKH.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-CidlGr6f.js.map → BotPicker-D-WegFKH.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-C8Zxzh1x.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-BMNNTa0D.js.map → CapabilitiesPage-C8Zxzh1x.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-W9F9lziT.js → CollapsibleSection-Ca2iifr4.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-W9F9lziT.js.map → CollapsibleSection-Ca2iifr4.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-BUh-Dzba.js → ConfirmDeleteModal-DD7SEMeX.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-BUh-Dzba.js.map → ConfirmDeleteModal-DD7SEMeX.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-B1mxKfVb.js → CopyableId-BpB-NvDh.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-B1mxKfVb.js.map → CopyableId-BpB-NvDh.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-lkv_7msa.js → CountdownTimer-CQSukTT4.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-lkv_7msa.js.map → CountdownTimer-CQSukTT4.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-DyOgfnPB.js → CredentialsPage-BFf0p9CE.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-DyOgfnPB.js.map → CredentialsPage-BFf0p9CE.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-geum95dj.js → CronLabel-CvjUA6jF.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-geum95dj.js.map → CronLabel-CvjUA6jF.js.map} +1 -1
- package/dashboard/dist/assets/CustomDurationPicker-znQCEiPe.js +2 -0
- package/dashboard/dist/assets/CustomDurationPicker-znQCEiPe.js.map +1 -0
- package/dashboard/dist/assets/{DropZone-C3hOjJtC.js → DropZone-BrnAkQxF.js} +2 -2
- package/dashboard/dist/assets/{DropZone-C3hOjJtC.js.map → DropZone-BrnAkQxF.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-DFOW9T4b.js → ElapsedCell-C0pd3pO8.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-DFOW9T4b.js.map → ElapsedCell-C0pd3pO8.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-_IhqXIQu.js → EscalationListSchemaPage-BRrrftTq.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-_IhqXIQu.js.map → EscalationListSchemaPage-BRrrftTq.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-BCC7iscN.js → EscalationSchemaPage-ChawQh5H.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-BCC7iscN.js.map → EscalationSchemaPage-ChawQh5H.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-CvIdOtoP.js → EscalationsOverview-D3dFDffZ.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CvIdOtoP.js.map → EscalationsOverview-D3dFDffZ.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DJWJ7J0m.js → EventTable-C6vkJJcQ.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DJWJ7J0m.js.map → EventTable-C6vkJJcQ.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-BR3ztZ8y.js → FilterBar-OqpCEYW2.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-BR3ztZ8y.js.map → FilterBar-OqpCEYW2.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-Cwn-8Glr.js → GraphInvokePage-CJOyaU4g.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-Cwn-8Glr.js.map → GraphInvokePage-CJOyaU4g.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-DxJz7AQ7.js +2 -0
- package/dashboard/dist/assets/HomePage-DxJz7AQ7.js.map +1 -0
- package/dashboard/dist/assets/{ListToolbar-DuoEdVtK.js → ListToolbar-B6ZoJ4Rd.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-DuoEdVtK.js.map → ListToolbar-B6ZoJ4Rd.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-NXKsGiWU.js → McpOverview-YPY-lX3M.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-NXKsGiWU.js.map → McpOverview-YPY-lX3M.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-BC-iXfIx.js → McpQueryDetailPage-Ct3Mb1R2.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-BC-iXfIx.js.map → McpQueryDetailPage-Ct3Mb1R2.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-BPJmFYOY.js → McpQueryPage-C5-AQvnp.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-BPJmFYOY.js.map → McpQueryPage-C5-AQvnp.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-B49nUXEl.js → McpRunDetailPage-Bl12usuN.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-B49nUXEl.js.map → McpRunDetailPage-Bl12usuN.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-Ce_XIYpP.js → McpRunsPage-PRAQPR-H.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-Ce_XIYpP.js.map → McpRunsPage-PRAQPR-H.js.map} +1 -1
- package/dashboard/dist/assets/{Modal-D4afnAjc.js → Modal-CA2Iv02H.js} +2 -2
- package/dashboard/dist/assets/{Modal-D4afnAjc.js.map → Modal-CA2Iv02H.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-LWvZXt_g.js → NamespacePill-DQGzN0Ph.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-LWvZXt_g.js.map → NamespacePill-DQGzN0Ph.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-DLGNcE-b.js +2 -0
- package/dashboard/dist/assets/OperationsPage-DLGNcE-b.js.map +1 -0
- package/dashboard/dist/assets/{OperatorDashboard-DpXjhs-3.js → OperatorDashboard-353PWYOD.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-DpXjhs-3.js.map → OperatorDashboard-353PWYOD.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-DvEmMMP6.js → PageHeader-DlcE3U5L.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-DvEmMMP6.js.map → PageHeader-DlcE3U5L.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-X0eAmu-x.js → PageHeaderWithStats-BMhnR3-9.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-X0eAmu-x.js.map → PageHeaderWithStats-BMhnR3-9.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-DpYSMRj1.js → ProcessDetailPage-DyB979ge.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-DpYSMRj1.js.map → ProcessDetailPage-DyB979ge.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CQ9tSw7U.js → ProcessesListPage-BPi9CNxQ.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CQ9tSw7U.js.map → ProcessesListPage-BPi9CNxQ.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-DKeQKDkW.js → RoleDetailPage-D6K3tdNO.js} +3 -3
- package/dashboard/dist/assets/{RoleDetailPage-DKeQKDkW.js.map → RoleDetailPage-D6K3tdNO.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-CWhoLwef.js → RolePill-dzo14hB_.js} +2 -2
- package/dashboard/dist/assets/{RolePill-CWhoLwef.js.map → RolePill-dzo14hB_.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-D-6kIact.js → RolesPage-C_i2RLwv.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-D-6kIact.js.map → RolesPage-C_i2RLwv.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-DzYcpQTm.js → RunAsSelector-CWBQWKM0.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-DzYcpQTm.js.map → RunAsSelector-CWBQWKM0.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-BTGfmGV3.js → StickyPagination-4cY0OXWj.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-BTGfmGV3.js.map → StickyPagination-4cY0OXWj.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-DqRpzA_6.js → StreamMessageDetail-DxA7AzOR.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-DqRpzA_6.js.map → StreamMessageDetail-DxA7AzOR.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-CA106TYo.js → SwimlaneTimeline-BlinxMjc.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-CA106TYo.js.map → SwimlaneTimeline-BlinxMjc.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-CoR4MzsW.js → TagInput-cyhTZTwe.js} +2 -2
- package/dashboard/dist/assets/{TagInput-CoR4MzsW.js.map → TagInput-cyhTZTwe.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-BRg-w2Ev.js → TaskDetailPage-Cbr6Bzx3.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-BRg-w2Ev.js.map → TaskDetailPage-Cbr6Bzx3.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-Dw3YN8M-.js → TaskQueuePill-_zIpG4bG.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-Dw3YN8M-.js.map → TaskQueuePill-_zIpG4bG.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-kB_j9G8o.js → TasksListPage-DNjZbo42.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-kB_j9G8o.js.map → TasksListPage-DNjZbo42.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-D7dSIY7-.js → TimeAgo-BEOuisPG.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-D7dSIY7-.js.map → TimeAgo-BEOuisPG.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-BZe6bx18.js → TimestampCell--CLqQOJa.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-BZe6bx18.js.map → TimestampCell--CLqQOJa.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-xX-buQtY.js → ToolPill-CKHYG6eV.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-xX-buQtY.js.map → ToolPill-CKHYG6eV.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-U3NaF_T_.js → ToolTestPanel-x7po38Fn.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-U3NaF_T_.js.map → ToolTestPanel-x7po38Fn.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-BpALvXP1.js → TopicDetailPage-Bay2lUOW.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-BpALvXP1.js.map → TopicDetailPage-Bay2lUOW.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-Cy3chaca.js → TopicsPage-Ckh6ln0h.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-Cy3chaca.js.map → TopicsPage-Ckh6ln0h.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-VXM1oHMC.js → UserName-Doe8DDXc.js} +2 -2
- package/dashboard/dist/assets/{UserName-VXM1oHMC.js.map → UserName-Doe8DDXc.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-BCq2cR1V.js → WorkflowExecutionPage-DPymyMAM.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-BCq2cR1V.js.map → WorkflowExecutionPage-DPymyMAM.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-CQ1AmhlC.js → WorkflowPill-DlSVXnnj.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-CQ1AmhlC.js.map → WorkflowPill-DlSVXnnj.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-BbM69MnB.js → WorkflowsDashboard-CrwdULL7.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-BbM69MnB.js.map → WorkflowsDashboard-CrwdULL7.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-D5HthpAW.js → WorkflowsOverview-YoPFHjOb.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-D5HthpAW.js.map → WorkflowsOverview-YoPFHjOb.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CDDVMYWi.js → YamlWorkflowDetailPage-B4H8WvSt.js} +10 -10
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CDDVMYWi.js.map → YamlWorkflowDetailPage-B4H8WvSt.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-FFjWwydj.js → YamlWorkflowsPage-gburzX11.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-FFjWwydj.js.map → YamlWorkflowsPage-gburzX11.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BwiSNu73.js → agents-BwrYw_S8.js} +2 -2
- package/dashboard/dist/assets/{agents-BwiSNu73.js.map → agents-BwrYw_S8.js.map} +1 -1
- package/dashboard/dist/assets/{bots-ClgSrxel.js → bots-C0vU7IG9.js} +2 -2
- package/dashboard/dist/assets/{bots-ClgSrxel.js.map → bots-C0vU7IG9.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-JUaKsby4.js → capabilities-DOE8jqWc.js} +2 -2
- package/dashboard/dist/assets/{capabilities-JUaKsby4.js.map → capabilities-DOE8jqWc.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CuTQ7eUE.js → controlplane-TtPp8V9E.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CuTQ7eUE.js.map → controlplane-TtPp8V9E.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-Cyp-K89u.js +2 -0
- package/dashboard/dist/assets/escalation-columns-Cyp-K89u.js.map +1 -0
- package/dashboard/dist/assets/{index-C1t0YIXC.js → index-BTsTdaRt.js} +3 -3
- package/dashboard/dist/assets/{index-C1t0YIXC.js.map → index-BTsTdaRt.js.map} +1 -1
- package/dashboard/dist/assets/{index-CBj-vstO.js → index-Bl-09ECD.js} +2 -2
- package/dashboard/dist/assets/{index-CBj-vstO.js.map → index-Bl-09ECD.js.map} +1 -1
- package/dashboard/dist/assets/index-BmsZnbW1.js +63 -0
- package/dashboard/dist/assets/index-BmsZnbW1.js.map +1 -0
- package/dashboard/dist/assets/index-CR1_qhQf.js +2 -0
- package/dashboard/dist/assets/{index-Xd1jcHe7.js.map → index-CR1_qhQf.js.map} +1 -1
- package/dashboard/dist/assets/{index-BBA4AxmL.js → index-CVZOAQVo.js} +2 -2
- package/dashboard/dist/assets/{index-BBA4AxmL.js.map → index-CVZOAQVo.js.map} +1 -1
- package/dashboard/dist/assets/{index-CoPWHo_H.js → index-CkwNuQzx.js} +2 -2
- package/dashboard/dist/assets/{index-CoPWHo_H.js.map → index-CkwNuQzx.js.map} +1 -1
- package/dashboard/dist/assets/index-Cm42dgjx.css +1 -0
- package/dashboard/dist/assets/index-DFJm742Y.js +2 -0
- package/dashboard/dist/assets/{index-C9o2UNhC.js.map → index-DFJm742Y.js.map} +1 -1
- package/dashboard/dist/assets/{index-CnsPBTXL.js → index-Dh6F3Wbx.js} +2 -2
- package/dashboard/dist/assets/{index-CnsPBTXL.js.map → index-Dh6F3Wbx.js.map} +1 -1
- package/dashboard/dist/assets/index-Wu6GCvUq.js +5 -0
- package/dashboard/dist/assets/index-Wu6GCvUq.js.map +1 -0
- package/dashboard/dist/assets/{index-Cavwd8UU.js → index-b7P6Hjd3.js} +3 -3
- package/dashboard/dist/assets/{index-Cavwd8UU.js.map → index-b7P6Hjd3.js.map} +1 -1
- package/dashboard/dist/assets/{index-CUguKMXZ.js → index-j-X71wT4.js} +2 -2
- package/dashboard/dist/assets/{index-CUguKMXZ.js.map → index-j-X71wT4.js.map} +1 -1
- package/dashboard/dist/assets/{index-DSa-6Ux8.js → index-stu9QXmW.js} +2 -2
- package/dashboard/dist/assets/{index-DSa-6Ux8.js.map → index-stu9QXmW.js.map} +1 -1
- package/dashboard/dist/assets/{index-CwQVaa7x.js → index-zuK6pSyZ.js} +2 -2
- package/dashboard/dist/assets/{index-CwQVaa7x.js.map → index-zuK6pSyZ.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-BHBt-6kW.js → knowledge-DD9NIG9d.js} +2 -2
- package/dashboard/dist/assets/{knowledge-BHBt-6kW.js.map → knowledge-DD9NIG9d.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-CBcz4BCS.js → mcp-C4upVuuP.js} +2 -2
- package/dashboard/dist/assets/{mcp-CBcz4BCS.js.map → mcp-C4upVuuP.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-C4fKTOYo.js → mcp-query-JEk3cZyH.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-C4fKTOYo.js.map → mcp-query-JEk3cZyH.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-CmAAH3B6.js → pipelines-BkBpa2Y7.js} +2 -2
- package/dashboard/dist/assets/{pipelines-CmAAH3B6.js.map → pipelines-BkBpa2Y7.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BAEsqcz2.js → tasks-B7QVagGw.js} +2 -2
- package/dashboard/dist/assets/{tasks-BAEsqcz2.js.map → tasks-B7QVagGw.js.map} +1 -1
- package/dashboard/dist/assets/{topics-CY0pJ6_o.js → topics-C55xydgR.js} +2 -2
- package/dashboard/dist/assets/{topics-CY0pJ6_o.js.map → topics-C55xydgR.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-BlpwRvHO.js → useEventHooks-CKpFrpjc.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-BlpwRvHO.js.map → useEventHooks-CKpFrpjc.js.map} +1 -1
- package/dashboard/dist/assets/{useFilterParams-x-Dg0Vgz.js → useFilterParams-CvRyYHJN.js} +2 -2
- package/dashboard/dist/assets/{useFilterParams-x-Dg0Vgz.js.map → useFilterParams-CvRyYHJN.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-CoNUlZ6Z.js → useNamespace-BJbjZubz.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-CoNUlZ6Z.js.map → useNamespace-BJbjZubz.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-8GUn5Wie.js → useYamlActivityEvents-C80oooy6.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-8GUn5Wie.js.map → useYamlActivityEvents-C80oooy6.js.map} +1 -1
- package/dashboard/dist/assets/{users-uGtDRGxR.js → users-BdvakxB1.js} +2 -2
- package/dashboard/dist/assets/{users-uGtDRGxR.js.map → users-BdvakxB1.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-DKCAtTJ9.js → vendor-icons-BE_WrH2z.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-DKCAtTJ9.js.map → vendor-icons-BE_WrH2z.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-react-CXumBFUA.js → vendor-react-BpdAFEQc.js} +2 -2
- package/dashboard/dist/assets/{vendor-react-CXumBFUA.js.map → vendor-react-BpdAFEQc.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-DoX-AtHN.js → workflows-DYTqfgom.js} +2 -2
- package/dashboard/dist/assets/{workflows-DoX-AtHN.js.map → workflows-DYTqfgom.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-DM3jVem2.js → yaml-workflows-D3o7rHzN.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DM3jVem2.js.map → yaml-workflows-D3o7rHzN.js.map} +1 -1
- package/dashboard/dist/index.html +4 -4
- package/docs/hitl/x-lt-embed.md +213 -0
- package/docs/hitl/x-lt-widget.md +3 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentConfigPage-CbIhM-fa.js +0 -16
- package/dashboard/dist/assets/AgentDetailPage-DuLEKzRT.js +0 -4
- package/dashboard/dist/assets/AgentDetailPage-DuLEKzRT.js.map +0 -1
- package/dashboard/dist/assets/AgentsPage-DZO9i7Nl.js +0 -2
- package/dashboard/dist/assets/AgentsPage-DZO9i7Nl.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DlVoNd8B.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-DlVoNd8B.js.map +0 -1
- package/dashboard/dist/assets/CapabilitiesPage-BMNNTa0D.js +0 -2
- package/dashboard/dist/assets/CustomDurationPicker-ClufO2ew.js +0 -2
- package/dashboard/dist/assets/CustomDurationPicker-ClufO2ew.js.map +0 -1
- package/dashboard/dist/assets/HomePage-D8RVntg0.js +0 -2
- package/dashboard/dist/assets/HomePage-D8RVntg0.js.map +0 -1
- package/dashboard/dist/assets/OperationsPage-DI7AQO9f.js +0 -2
- package/dashboard/dist/assets/OperationsPage-DI7AQO9f.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-CS0c7cAr.js +0 -2
- package/dashboard/dist/assets/escalation-columns-CS0c7cAr.js.map +0 -1
- package/dashboard/dist/assets/index-C-8xXyvr.js +0 -63
- package/dashboard/dist/assets/index-C-8xXyvr.js.map +0 -1
- package/dashboard/dist/assets/index-C9o2UNhC.js +0 -2
- package/dashboard/dist/assets/index-DeMs_aBT.css +0 -1
- package/dashboard/dist/assets/index-Ikj_NTuy.js +0 -5
- package/dashboard/dist/assets/index-Ikj_NTuy.js.map +0 -1
- package/dashboard/dist/assets/index-Xd1jcHe7.js +0 -2
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HomePage-D8RVntg0.js","sources":["../../src/hooks/useTaskQueueRoles.ts","../../src/hooks/useMyEscalationCount.ts","../../src/pages/home/TaskQueueCard.tsx","../../src/pages/home/TaskQueueCards.tsx","../../src/pages/home/HomePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { useAuth } from './useAuth';\nimport { isSystemTierRole } from '../lib/task-queues';\n\n/**\n * The roles that surface as task queues for the current user: every role they\n * are a member of (a person or service account working that lane), minus the\n * capability tiers. Sorted and de-duplicated. Any further queue views a user\n * wants come from personal pins.\n */\nexport function useTaskQueueRoles(): string[] {\n const { user } = useAuth();\n\n return useMemo(() => {\n const names = (user?.roles ?? []).map((r) => r.role).filter((r) => !isSystemTierRole(r));\n return Array.from(new Set(names)).sort((a, b) => a.localeCompare(b));\n }, [user]);\n}\n","import { useQueryClient } from '@tanstack/react-query';\nimport { useAuth } from './useAuth';\nimport { useEscalations } from '../api/escalations';\nimport { useEventSubscription } from './useEventContext';\nimport { NATS_SUBJECT_PREFIX } from '../lib/nats/config';\n\n/**\n * Returns the number of active (non-expired) escalations assigned to the current user.\n * The API filters expired claims server-side (assigned_until > NOW()) when\n * assigned_to is provided, so the total from the query is accurate.\n */\nexport function useMyEscalationCount(): number {\n const { user } = useAuth();\n const userId = user?.userId;\n const qc = useQueryClient();\n\n const { data } = useEscalations({\n assigned_to: userId,\n status: 'pending',\n limit: 1,\n });\n\n useEventSubscription(`${NATS_SUBJECT_PREFIX}.system.escalation.>`, () => {\n if (userId) {\n qc.invalidateQueries({ queryKey: ['escalations'] });\n }\n });\n\n return data?.total ?? 0;\n}\n","import { useNavigate } from 'react-router-dom';\nimport { ExternalLink, TriangleAlert, Hand } from 'lucide-react';\nimport type { StationMetric } from '../../api/escalations';\nimport { jeopardyQueueLink } from '../operations/priority-link';\n\nfunction Stat({ n, label, tone }: { n: number; label: string; tone?: 'muted' }) {\n return (\n <div className=\"min-w-0\">\n <div className={`text-2xl font-light tabular-nums leading-none ${tone === 'muted' ? 'text-text-tertiary' : 'text-text-primary'}`}>\n {n}\n </div>\n <div className=\"text-2xs uppercase tracking-wider text-text-quaternary mt-1 truncate\">{label}</div>\n </div>\n );\n}\n\n/**\n * One lane's shape at a glance: pending / claimed / resolved over the selected\n * window, plus the jeopardy signal when items sit past the role's priority\n * threshold. The card opens the role's queue; the jeopardy pill opens it\n * sorted oldest-first so the at-risk items sit on top.\n */\nexport function TaskQueueCard({\n role,\n title,\n metric,\n priorityFacet,\n periodLabel,\n}: {\n role: string;\n title: string | null;\n metric: StationMetric | undefined;\n priorityFacet: string | null;\n periodLabel: string;\n}) {\n const navigate = useNavigate();\n const pending = metric?.pending ?? 0;\n const claimed = metric?.claimed ?? 0;\n const resolved = metric?.resolved ?? 0;\n const jeopardy = metric?.priority_count ?? 0;\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => navigate(`/escalations/available?role=${encodeURIComponent(role)}`)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigate(`/escalations/available?role=${encodeURIComponent(role)}`);\n }\n }}\n className=\"group h-full 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 >\n <div className=\"flex items-center justify-between gap-2 mb-3\">\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-secondary truncate\">\n {title || role}\n </span>\n <ExternalLink className=\"w-3 h-3 shrink-0 text-text-quaternary opacity-0 group-hover:opacity-100 transition-opacity\" strokeWidth={1.5} />\n </div>\n\n <div className=\"flex items-baseline gap-5\">\n <Stat n={pending} label=\"pending\" />\n <Stat n={claimed} label=\"claimed\" />\n <Stat n={resolved} label={`resolved · ${periodLabel}`} tone=\"muted\" />\n </div>\n\n <div className=\"mt-3 h-6 flex items-center\">\n {jeopardy > 0 ? (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n navigate(jeopardyQueueLink({ role, priority_facet: priorityFacet }));\n }}\n className=\"inline-flex items-center gap-1.5 pl-1.5 pr-2.5 py-1 rounded-full text-2xs font-semibold tabular-nums bg-status-error text-text-inverse transition-transform hover:scale-[1.05]\"\n title=\"Past the priority threshold — a hard limit; open oldest first\"\n >\n <TriangleAlert className=\"w-3 h-3\" strokeWidth={2.5} />\n {jeopardy} in jeopardy\n </button>\n ) : (\n <span className=\"text-2xs text-text-quaternary\">on pace</span>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * The runner's own work, across every lane. First and highlighted — what to\n * finish before pulling anything new. Opens their personal queue.\n */\nexport function ClaimedCard({ count }: { count: number }) {\n const navigate = useNavigate();\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => navigate('/escalations/queue')}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigate('/escalations/queue');\n }\n }}\n className=\"group h-full border-l-2 border-status-warning/70 bg-status-warning/[0.06] rounded-[0.125em] px-4 py-3.5 cursor-pointer transition-colors hover:bg-status-warning/[0.1] focus:outline-none focus-visible:ring-1 focus-visible:ring-status-warning/40\"\n >\n <div className=\"flex items-center justify-between gap-2 mb-3\">\n <span className=\"flex items-center gap-1.5 text-2xs font-semibold uppercase tracking-wider text-status-warning\">\n <Hand className=\"w-3 h-3\" strokeWidth={2} />\n Claimed\n </span>\n <ExternalLink className=\"w-3 h-3 shrink-0 text-text-quaternary opacity-0 group-hover:opacity-100 transition-opacity\" strokeWidth={1.5} />\n </div>\n\n <div className=\"text-2xl font-light tabular-nums leading-none text-text-primary\">{count}</div>\n <div className=\"text-2xs uppercase tracking-wider text-text-quaternary mt-1\">assigned to you</div>\n\n <div className=\"mt-3 h-6 flex items-center\">\n <span className=\"text-2xs font-medium text-status-warning\">\n {count > 0 ? 'Finish these first →' : 'Nothing claimed'}\n </span>\n </div>\n </div>\n );\n}\n","import { useState, useMemo } from 'react';\nimport { Layers } from 'lucide-react';\nimport { useStationMetrics } from '../../api/escalations';\nimport { useRoleDetails } from '../../api/roles';\nimport { useTaskQueueRoles } from '../../hooks/useTaskQueueRoles';\nimport { useMyEscalationCount } from '../../hooks/useMyEscalationCount';\nimport { TaskQueueCard, ClaimedCard } from './TaskQueueCard';\n\nconst PERIODS = ['15m', '1h', '24h', '7d'] as const;\ntype Period = (typeof PERIODS)[number];\n\n/**\n * The scoped runner's home: their own claimed work first, then one card per\n * lane they belong to — pending / claimed / resolved and a jeopardy signal over\n * a chosen window. A poor-man's Pace Board: no cross-role trend, just \"what is\n * in my lanes and what needs attention.\" Engineers get a single compact row\n * (workflows sit below); operators get the fuller two-row surface.\n */\nexport function TaskQueueCards({ maxRows }: { maxRows: 1 | 2 }) {\n const [period, setPeriod] = useState<Period>('24h');\n const roles = useTaskQueueRoles();\n const claimedCount = useMyEscalationCount();\n const metricsQ = useStationMetrics(period);\n const rolesQ = useRoleDetails();\n\n const metricByRole = useMemo(\n () => new Map((metricsQ.data?.stations ?? []).map((m) => [m.role, m])),\n [metricsQ.data],\n );\n const detailByRole = useMemo(\n () => new Map((rolesQ.data?.roles ?? []).map((r) => [r.role, r])),\n [rolesQ.data],\n );\n\n // Lanes lead with the most at-risk: sort by jeopardy count (a hard limit the\n // plant manager pulls to the front of the line), then alphabetically for a\n // stable order among ties. Card #1 is always Claimed, ahead of these.\n const sortedRoles = useMemo(() => {\n return [...roles].sort((a, b) => {\n const ja = metricByRole.get(a)?.priority_count ?? 0;\n const jb = metricByRole.get(b)?.priority_count ?? 0;\n if (jb !== ja) return jb - ja;\n return a.localeCompare(b);\n });\n }, [roles, metricByRole]);\n\n // The rest of the grid is lanes. Cap to the persona's row budget and surface\n // any overflow rather than hiding it.\n const slots = maxRows * 4;\n const laneBudget = slots - 1;\n const shownRoles = sortedRoles.slice(0, laneBudget);\n const overflow = sortedRoles.length - shownRoles.length;\n\n return (\n <div>\n <div className=\"flex items-center justify-between mb-4 pb-2 border-b border-surface-border\">\n <h2 className=\"flex items-center gap-2 text-sm font-medium text-text-primary\">\n <Layers className=\"w-4 h-4 text-accent\" strokeWidth={1.5} />\n Task Queues\n </h2>\n <div className=\"flex items-center gap-0.5\">\n {PERIODS.map((p) => (\n <button\n key={p}\n onClick={() => setPeriod(p)}\n className={`px-2.5 py-1 text-2xs font-mono rounded transition-colors ${\n period === p\n ? 'bg-accent/10 text-accent font-semibold'\n : 'text-text-quaternary hover:text-text-secondary'\n }`}\n >\n {p}\n </button>\n ))}\n </div>\n </div>\n\n {roles.length === 0 ? (\n <div className=\"grid grid-cols-1 @grp-cols:grid-cols-2 @wall:grid-cols-4 gap-4\">\n <ClaimedCard count={claimedCount} />\n <div className=\"lg:col-span-3 flex items-center px-4 py-3.5 text-sm text-text-tertiary\">\n You are not a member of a role. Task queues appear here once you join one.\n </div>\n </div>\n ) : (\n <>\n <div className=\"grid grid-cols-1 @grp-cols:grid-cols-2 @wall:grid-cols-4 gap-4 auto-rows-fr\">\n <ClaimedCard count={claimedCount} />\n {shownRoles.map((role) => (\n <TaskQueueCard\n key={role}\n role={role}\n title={detailByRole.get(role)?.title ?? null}\n metric={metricByRole.get(role)}\n priorityFacet={detailByRole.get(role)?.priority_facet ?? null}\n periodLabel={period}\n />\n ))}\n </div>\n {overflow > 0 && (\n <p className=\"mt-3 text-2xs text-text-quaternary\">\n +{overflow} more {overflow === 1 ? 'lane' : 'lanes'} in the Task Queues sidebar.\n </p>\n )}\n </>\n )}\n </div>\n );\n}\n","import { useState, useRef, useCallback, useEffect, useMemo } from 'react';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n Inbox, Code2, Workflow, LayoutDashboard, ExternalLink, BookOpen,\n} from 'lucide-react';\nimport { formatCountCompact } from '../../lib/format';\nimport { useAvailableEscalations, useEscalations, useStationMetrics } from '../../api/escalations';\nimport { useRoleDetails } from '../../api/roles';\nimport { useJobs } from '../../api/workflows';\nimport { useMcpRuns } from '../../api/pipelines';\nimport { useControlPlaneApps } from '../../api/controlplane';\nimport { useAuth } from '../../hooks/useAuth';\nimport { useAccess } from '../../hooks/useAccess';\nimport { usePersona } from '../../hooks/usePersona';\nimport { useEscalationStatsEvents, useWorkflowListEvents, useStationMetricsEvents } from '../../hooks/useEventHooks';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { RolePill } from '../../components/common/display/RolePill';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { PaceChart, type ChartStation } from '../operations/PaceChart';\nimport { buildFragments } from '../operations/OperationsPage';\nimport { TaskQueueCards } from './TaskQueueCards';\n\nconst STATUS_DOT: Record<string, string> = {\n completed: 'bg-status-success',\n active: 'bg-status-active',\n running: 'bg-status-active',\n pending: 'bg-status-pending',\n error: 'bg-status-error',\n failed: 'bg-status-error',\n};\nfunction statusDotClass(status: string): string {\n return STATUS_DOT[status] ?? 'bg-text-tertiary';\n}\n\n// ── Section header ──────────────────────────────────────────────────────────\n\nfunction SectionHeader({ icon: Icon, color, docsHash, count, children, actions }: { icon: React.ElementType; color?: string; docsHash?: string; count?: number; children: React.ReactNode; actions?: React.ReactNode }) {\n return (\n <div className=\"flex items-center justify-between mb-4 pb-2 border-b border-surface-border\">\n <div className=\"flex items-center gap-2\">\n <Icon className={`w-4.5 h-4.5 ${color || 'text-accent/60'}`} strokeWidth={1.5} />\n <h2 className=\"section-h2\">{children}</h2>\n {count !== undefined && count > 0 && (\n <span className=\"px-1.5 py-0.5 rounded-full bg-accent/10 text-accent text-2xs font-semibold tabular-nums\">\n {formatCountCompact(count)}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n {docsHash && (\n <button onClick={() => { window.location.hash = docsHash; }} className=\"text-text-quaternary hover:text-accent transition-colors\" title=\"Docs\">\n <BookOpen className=\"w-2.5 h-2.5\" strokeWidth={1.5} />\n </button>\n )}\n {actions}\n </div>\n </div>\n );\n}\n\nfunction EmptyPanel({ icon: Icon, text }: { icon: React.ElementType; text: string }) {\n return (\n <div className=\"flex flex-col items-center justify-center py-10 text-center\">\n <Icon className=\"w-6 h-6 text-text-quaternary/50 mb-2\" strokeWidth={1} />\n <p className=\"text-xs text-text-quaternary\">{text}</p>\n </div>\n );\n}\n\n/** Middle-ellipsis: keep first N and last N chars with ... in between */\nfunction midEllipsis(s: string, maxLen = 37): string {\n if (!s || s.length <= maxLen) return s;\n const keep = Math.floor((maxLen - 3) / 2);\n return `${s.slice(0, keep)}...${s.slice(-keep)}`;\n}\n\n/** Consistent console row for all execution lists. The COLUMN is the\n * container: with room (@dict-inline) the date shares the id line; in a\n * tight half column it drops below beside the pill — the row condenses,\n * the pair of columns never stacks. */\nfunction ExecutionRow({ dot, pill, id, date, onClick }: {\n dot: string;\n pill: React.ReactNode;\n id: string;\n date: string;\n onClick: () => void;\n}) {\n return (\n <button onClick={onClick} className=\"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className={`w-1.5 h-1.5 rounded-full dot-ring shrink-0 ${dot}`} />\n <span className=\"text-xs text-text-primary font-mono truncate flex-1 min-w-0\">{midEllipsis(id)}</span>\n <span className=\"hidden @dict-inline:inline text-2xs text-text-quaternary shrink-0 whitespace-nowrap\"><DateValue date={date} /></span>\n </div>\n <div className=\"pl-3.5 flex items-center gap-1 overflow-hidden\">\n {pill}\n <span className=\"flex-1 min-w-0\" />\n <span className=\"@dict-inline:hidden text-2xs text-text-quaternary shrink-0 whitespace-nowrap\"><DateValue date={date} /></span>\n </div>\n </button>\n );\n}\n\n/** Console row for the escalation firehose lists — same condensing law.\n * The workflow pill is enrichment (the column budget): it returns when the\n * column has room; the floor is priority, title, role, age. */\nfunction EscalationRow({ esc, onClick }: { esc: any; onClick: () => void }) {\n const date = <DateValue date={esc.updated_at ?? esc.created_at} />;\n return (\n <button onClick={onClick} className=\"w-full text-left hover:bg-surface-hover/50 rounded-md px-1 py-1.5 transition-colors\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-2xs text-text-quaternary font-medium shrink-0\">P{esc.priority ?? 2}</span>\n <span className=\"text-xs text-text-primary truncate flex-1 min-w-0\">{esc.description || esc.subtype || esc.type}</span>\n <span className=\"hidden @dict-inline:inline text-2xs text-text-quaternary shrink-0\">{date}</span>\n </div>\n <div className=\"flex items-center gap-2 pl-5 overflow-hidden\">\n <span className=\"hidden @dict-inline:inline-flex min-w-0\"><WorkflowPill type={esc.type || 'unknown'} size=\"xs\" /></span>\n <span className=\"flex-1 min-w-0\" />\n <RolePill role={esc.role} />\n <span className=\"@dict-inline:hidden text-2xs text-text-quaternary shrink-0\">{date}</span>\n </div>\n </button>\n );\n}\n\nfunction NavIcon({ to, icon: Icon, title }: { to: string; icon: React.ElementType; title: string }) {\n const navigate = useNavigate();\n return (\n <button\n onClick={() => navigate(to)}\n className=\"text-text-quaternary hover:text-accent transition-colors\"\n title={title}\n >\n <Icon className=\"w-2.5 h-2.5\" strokeWidth={1.5} />\n </button>\n );\n}\n\n// ── Namespace Picker ────────────────────────────────────────────────────────\n\nfunction AppPicker({ appIds, selected, onSelect }: {\n appIds: string[];\n selected: string;\n onSelect: (id: string) => void;\n}) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [open]);\n\n if (appIds.length <= 1) return null;\n\n return (\n <div className=\"relative mb-3 -mt-2\" ref={ref}>\n <button\n onClick={() => setOpen((v) => !v)}\n className=\"flex items-center gap-1 px-2 py-0.5 text-2xs rounded bg-accent/10 text-accent hover:bg-accent/20 transition-colors\"\n >\n {selected}\n <svg className={`w-2.5 h-2.5 transition-transform ${open ? 'rotate-180' : ''}`} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n {open && (\n <div className=\"absolute top-full left-0 mt-1 bg-surface-raised border border-surface-border rounded-md shadow-lg z-[100] py-1 min-w-[120px]\">\n {appIds.map((id) => (\n <button\n key={id}\n onClick={() => { onSelect(id); setOpen(false); }}\n className={`w-full text-left px-3 py-1.5 text-2xs transition-colors ${\n selected === id ? 'text-accent bg-accent/5' : 'text-text-secondary hover:bg-surface-hover'\n }`}\n >\n {id}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function HomePage() {\n const navigate = useNavigate();\n const { user } = useAuth();\n const { isBuilder } = useAccess();\n const persona = usePersona();\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: cpData } = useControlPlaneApps({ enabled: isBuilder });\n const allAppIds = useMemo(() => (cpData?.apps ?? []).map((a: any) => a.appId).sort(), [cpData]);\n const firstAppId = allAppIds[0] ?? '';\n const pipelineNs = searchParams.get('pipelinenamespace') || firstAppId;\n const durableNs = searchParams.get('durablenamespace') || firstAppId;\n const setNs = useCallback((key: string, ns: string) => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.set(key, ns);\n return next;\n }, { replace: false });\n }, [setSearchParams]);\n useEscalationStatsEvents();\n useWorkflowListEvents();\n useStationMetricsEvents();\n\n // The home page renders one of three layouts (see the return below):\n // - operator: their own lanes as task-queue cards, nothing else\n // - admin/superadmin: escalations left|right, then the Pace Board FULL WIDTH\n // (the chart is the story; full width is what scales it)\n // - engineer: a 2×2 console — escalations on the upper row, the workflow\n // execution columns on the lower row\n // Gate each data source to the tiers that render it, so no one fires a\n // request they can't access (403 on control-plane apps → empty namespace →\n // 400 on jobs). Superadmins reach the execution surfaces from the sidebar;\n // their home stays the operational story.\n const builderHome = !persona.showTaskQueueCards;\n const showWorkflowColumns = persona.canSeeWorkflows && !persona.canSeePaceBoard;\n const rolesQ = useRoleDetails({ enabled: persona.canSeePaceBoard });\n const stationQ = useStationMetrics('1h', { enabled: persona.canSeePaceBoard });\n const jobsQ = useJobs({ limit: 5, sort_by: 'updated_at', order: 'desc', namespace: durableNs }, { enabled: showWorkflowColumns });\n const durableAppIds = allAppIds;\n const pipelineAppIds = allAppIds;\n const mcpQ = useMcpRuns({ limit: 5, app_id: pipelineNs, sort_by: 'updated_at', order: 'desc' }, { enabled: showWorkflowColumns });\n const allEscQ = useAvailableEscalations({ limit: 5, sort_by: 'created_at', order: 'desc', enabled: builderHome });\n const myEscQ = useEscalations({ assigned_to: user?.userId, status: 'pending', limit: 5, sort_by: 'created_at', order: 'desc', enabled: builderHome });\n\n // Delayed refetch — allows signal-routed escalation resolutions\n // (durable activity) time to commit before refreshing the list\n useEffect(() => {\n const timer = setTimeout(() => {\n myEscQ.refetch();\n allEscQ.refetch();\n }, 2000);\n return () => clearTimeout(timer);\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Pace Board mini — the primary sequence (longest line) at the 1h window.\n const paceStations = useMemo((): ChartStation[] => {\n const fragments = buildFragments(rolesQ.data?.roles ?? []);\n const primary = fragments[0]?.stations ?? [];\n const metrics = stationQ.data?.stations ?? [];\n return primary.map(({ role: r }) => ({\n role: r.role,\n title: r.title,\n parent_role: r.parent_role,\n target_per_hour: r.target_per_hour ?? null,\n upstream_roles: r.upstream_roles ?? [],\n metric: metrics.find((m) => m.role === r.role),\n }));\n }, [rolesQ.data, stationQ.data]);\n\n const jobs = jobsQ.data?.jobs ?? [];\n const jobsTotal = jobsQ.data?.total;\n const mcpRuns = (mcpQ.data as any)?.jobs ?? [];\n const mcpTotal = (mcpQ.data as any)?.total as number | undefined;\n const allEscalations = allEscQ.data?.escalations ?? [];\n const allEscTotal = allEscQ.data?.total;\n const myEscalations = myEscQ.data?.escalations ?? [];\n const myEscTotal = myEscQ.data?.total;\n\n // The two workflow execution columns, shared by the builder branches (the\n // engineer layout below and the superadmin Row 2). Defined once so the JSX\n // has a single source of truth.\n const proceduralColumn = (\n <div className=\"@container min-w-0\">\n <SectionHeader icon={Code2} color=\"text-accent\" count={jobsTotal} docsHash=\"#docs:dashboard.md:procedural-executions\" actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar onRefresh={() => jobsQ.refetch()} isFetching={jobsQ.isFetching} apiPath={`/workflow-states/jobs?namespace=${durableNs}&limit=5`} />\n <NavIcon to=\"/workflows/executions\" icon={ExternalLink} title=\"All procedural executions\" />\n </div>\n }>\n Procedural\n </SectionHeader>\n <AppPicker appIds={durableAppIds} selected={durableNs} onSelect={(ns) => setNs('durablenamespace', ns)} />\n {jobs.length === 0 ? (\n <EmptyPanel icon={Code2} text=\"No recent procedural runs\" />\n ) : (\n <div className=\"space-y-1\">\n {jobs.map((job: any) => (\n <ExecutionRow\n key={job.workflow_id}\n dot={statusDotClass(job.status)}\n pill={<WorkflowPill type={job.entity || job.type || 'workflow'} size=\"xs\" />}\n id={job.workflow_id}\n date={job.updated_at ?? job.created_at}\n onClick={() => navigate(`/workflows/executions/${job.workflow_id}`)}\n />\n ))}\n </div>\n )}\n </div>\n );\n\n const graphColumn = (\n <div className=\"@container min-w-0\">\n <SectionHeader icon={Workflow} color=\"text-accent\" count={mcpTotal} docsHash=\"#docs:dashboard.md:graph-executions\" actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar onRefresh={() => mcpQ.refetch()} isFetching={mcpQ.isFetching} apiPath={`/pipelines?app_id=${pipelineNs}&limit=5`} />\n <NavIcon to=\"/mcp/executions\" icon={ExternalLink} title=\"All graph executions\" />\n </div>\n }>\n Graph\n </SectionHeader>\n <AppPicker appIds={pipelineAppIds} selected={pipelineNs} onSelect={(ns) => setNs('pipelinenamespace', ns)} />\n {mcpRuns.length === 0 ? (\n <EmptyPanel icon={Workflow} text=\"No recent graph runs\" />\n ) : (\n <div className=\"space-y-1\">\n {mcpRuns.map((run: any) => (\n <ExecutionRow\n key={run.workflow_id}\n dot={statusDotClass(run.status)}\n pill={<WorkflowPill type={run.entity || run.workflow_name || 'pipeline'} variant=\"pipeline\" size=\"xs\" />}\n id={run.workflow_id}\n date={run.updated_at ?? run.created_at}\n onClick={() => navigate(`/mcp/executions/${run.workflow_id}?namespace=${pipelineNs}`)}\n />\n ))}\n </div>\n )}\n </div>\n );\n\n // ── Operator: their own lanes as Task Queue cards, nothing else. Scoped to\n // the roles they belong to; no firehose, no Pace Board, no workflows.\n if (persona.showTaskQueueCards) {\n return (\n <div>\n <h1 className=\"heading-1 mb-10\">Recent Activity</h1>\n <TaskQueueCards maxRows={2} />\n </div>\n );\n }\n\n // ── Builder home. Admin/superadmin: escalations left|right, Pace Board full\n // width beneath — the operational story in two rows. Engineer: a 2×2\n // console — escalations up top, the workflow execution columns below.\n // The pairs stay side by side at EVERY width — the pair IS the console.\n // Each COLUMN is a container: its rows condense (date drops below, the\n // enrichment pill yields) when the column narrows, and the pair holds.\n return (\n <div>\n <h1 className=\"heading-1 mb-10\">Recent Activity</h1>\n\n {/* ── Row 1: All Escalations | My Escalations ──────────────────────── */}\n <div className=\"grid grid-cols-2 gap-x-4 @split:gap-x-col-gap\">\n\n {/* Col 1: All Escalations */}\n <div className=\"@container min-w-0\">\n <SectionHeader icon={Inbox} color=\"text-accent\" count={allEscTotal} docsHash=\"#docs:dashboard.md:all-escalations\" actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar onRefresh={() => allEscQ.refetch()} isFetching={allEscQ.isFetching} apiPath=\"/escalations?status=pending&limit=5&sort_by=created_at&order=desc\" />\n <NavIcon to=\"/escalations/available\" icon={ExternalLink} title=\"All escalations\" />\n </div>\n }>\n All Escalations\n </SectionHeader>\n {allEscalations.length === 0 ? (\n <EmptyPanel icon={Inbox} text=\"No pending escalations\" />\n ) : (\n <div className=\"space-y-1\">\n {allEscalations.map((esc: any) => (\n <EscalationRow key={esc.id} esc={esc} onClick={() => navigate(`/escalations/detail/${esc.id}`)} />\n ))}\n </div>\n )}\n </div>\n\n {/* Col 2: My Escalations */}\n <div className=\"@container min-w-0\">\n <SectionHeader icon={Inbox} color=\"text-accent\" count={myEscTotal} docsHash=\"#docs:dashboard.md:escalations-overview\" actions={\n <div className=\"flex items-center gap-2\">\n <ListToolbar onRefresh={() => myEscQ.refetch()} isFetching={myEscQ.isFetching} apiPath={`/escalations?assigned_to=${user?.userId ?? ''}&status=pending&limit=5&sort_by=created_at&order=desc`} />\n <NavIcon to=\"/escalations/queue\" icon={ExternalLink} title=\"My escalation queue\" />\n </div>\n }>\n My Escalations\n </SectionHeader>\n {myEscalations.length === 0 ? (\n <EmptyPanel icon={Inbox} text=\"No assigned escalations\" />\n ) : (\n <div className=\"space-y-1\">\n {myEscalations.map((esc: any) => (\n <EscalationRow key={esc.id} esc={esc} onClick={() => navigate(`/escalations/detail/${esc.id}`)} />\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* ── Row 2 (admin/superadmin): the Pace Board — 100% width, half the\n viewport tall. The chart is the story; this is the space it earns. */}\n {persona.canSeePaceBoard && (\n <div className=\"mt-14\">\n <SectionHeader icon={LayoutDashboard} color=\"text-accent\" docsHash=\"#docs:dashboard.md:pace-board\" actions={\n <NavIcon to=\"/operations\" icon={ExternalLink} title=\"Open the Pace Board\" />\n }>\n Pace Board\n </SectionHeader>\n {paceStations.length === 0 ? (\n <EmptyPanel icon={LayoutDashboard} text=\"No stations yet — mark roles visible in Operations\" />\n ) : (\n <div className=\"h-[50vh] cursor-pointer\" onClick={() => navigate('/operations')}>\n <PaceChart\n stations={paceStations}\n selectedRole={null}\n onSelect={() => navigate('/operations')}\n onUpstreamSelect={() => navigate('/operations')}\n periodHours={1}\n />\n </div>\n )}\n </div>\n )}\n\n {/* ── Row 2 (engineer): Procedural | Graph — the lower half of the 2×2,\n side by side at every width like the row above. */}\n {showWorkflowColumns && (\n <div className=\"grid grid-cols-2 gap-x-4 @split:gap-x-col-gap mt-14\">\n {proceduralColumn}\n {graphColumn}\n </div>\n )}\n </div>\n );\n}\n"],"names":["useTaskQueueRoles","user","useAuth","useMemo","names","r","isSystemTierRole","a","b","useMyEscalationCount","userId","qc","useQueryClient","data","useEscalations","useEventSubscription","NATS_SUBJECT_PREFIX","Stat","n","label","tone","jsxs","jsx","TaskQueueCard","role","title","metric","priorityFacet","periodLabel","navigate","useNavigate","pending","claimed","resolved","jeopardy","e","ExternalLink","jeopardyQueueLink","TriangleAlert","ClaimedCard","count","Hand","PERIODS","TaskQueueCards","maxRows","period","setPeriod","useState","roles","claimedCount","metricsQ","useStationMetrics","rolesQ","useRoleDetails","metricByRole","_a","m","detailByRole","sortedRoles","ja","jb","_b","laneBudget","shownRoles","overflow","Layers","p","Fragment","STATUS_DOT","statusDotClass","status","SectionHeader","Icon","color","docsHash","children","actions","formatCountCompact","BookOpen","EmptyPanel","text","midEllipsis","s","maxLen","keep","ExecutionRow","dot","pill","id","date","onClick","DateValue","EscalationRow","esc","WorkflowPill","RolePill","NavIcon","to","AppPicker","appIds","selected","onSelect","open","setOpen","ref","useRef","useEffect","handler","v","HomePage","isBuilder","useAccess","persona","usePersona","searchParams","setSearchParams","useSearchParams","cpData","useControlPlaneApps","allAppIds","firstAppId","pipelineNs","durableNs","setNs","useCallback","key","ns","prev","next","useEscalationStatsEvents","useWorkflowListEvents","useStationMetricsEvents","builderHome","showWorkflowColumns","stationQ","jobsQ","useJobs","durableAppIds","pipelineAppIds","mcpQ","useMcpRuns","allEscQ","useAvailableEscalations","myEscQ","timer","paceStations","primary","buildFragments","metrics","_c","jobs","jobsTotal","mcpRuns","mcpTotal","_d","allEscalations","_e","allEscTotal","_f","myEscalations","_g","myEscTotal","_h","proceduralColumn","Code2","ListToolbar","job","graphColumn","Workflow","run","Inbox","LayoutDashboard","PaceChart"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as g,j as e}from"./vendor-query-B2UbickB.js";import{ae as be,I as qe,a3 as Ee}from"./index-C-8xXyvr.js";import{i as Oe}from"./useEventHooks-BlpwRvHO.js";import{P as Ae}from"./PageHeader-DvEmMMP6.js";import{a as Z}from"./role-display-Dvo2lDpU.js";import{X as Fe,O as Ie,aP as Te,as as We,aO as De,p as Be,aQ as ze,aj as ve,E as He}from"./vendor-icons-DKCAtTJ9.js";import{L as q,f as Ue,c as Ve}from"./vendor-react-CXumBFUA.js";const Ne=800,ke=270,B=40,Ge=76,de=24,Ye=72,ce=Ne-B-Ge,we=ke-de-Ye,S=de+we,he=B+ce,$="0.5s cubic-bezier(0.4, 0, 0.2, 1)",fe=9;function Ke(t){return`M ${(t.x-fe).toFixed(1)} ${t.y.toFixed(1)} L ${(t.x+fe).toFixed(1)} ${t.y.toFixed(1)}`}function z(t){if(t.length===0)return"";if(t.length===1)return Ke(t[0]);const a=[];for(let c=0;c<t.length-1;c++){const d=t[Math.max(0,c-1)],l=t[c],u=t[c+1],n=t[Math.min(t.length-1,c+2)],i=(l.x+(u.x-d.x)/6).toFixed(1),p=(l.y+(u.y-d.y)/6).toFixed(1),r=(u.x-(n.x-l.x)/6).toFixed(1),o=(u.y-(n.y-l.y)/6).toFixed(1);c===0&&a.push(`M ${l.x.toFixed(1)} ${l.y.toFixed(1)}`),a.push(`C ${i} ${p}, ${r} ${o}, ${u.x.toFixed(1)} ${u.y.toFixed(1)}`)}return a.join(" ")}function Qe(t,a){if(t.length<2||a.length<2)return"";const c=z(t),d=[...a].reverse(),l=z(d),u=l.slice(l.indexOf("C"));return`${c} L ${d[0].x.toFixed(1)} ${d[0].y.toFixed(1)} ${u} Z`}function Xe(t){return t>=1e4?`${Math.round(t/1e3)}k`:t>=1e3?`${(t/1e3).toFixed(1)}k`:String(t)}function oe(t){return t.length>0?t[t.length-1]:void 0}const O="rgb(var(--lt-status-claimed-graphic))",H="rgb(var(--lt-status-queued-graphic))",M="rgb(var(--lt-status-success-graphic))",A="rgb(var(--lt-text-quaternary))",U="rgb(var(--lt-status-error))";function J(t,a){return t.replace(/\)$/,` / ${a})`)}const Ze=13;function Je(t,a){const c=[...t].sort((n,i)=>n.y-i.y);let d=-1/0;const l=c.map(n=>{const i=Math.max(n.y+3,d+Ze);return d=i,{...n,labelY:i}}),u=l.length>0?l[l.length-1].labelY-a:0;if(u>0)for(const n of l)n.labelY-=u;return l}function et({stations:t,selectedRole:a,onSelect:c,onUpstreamSelect:d,onCmdClick:l,periodHours:u}){const[n,i]=g.useState(null),p=t.length;if(p===0)return null;const r=s=>p===1?B+ce/2:B+s/(p-1)*ce,o=new Map(t.map((s,f)=>[s.role,r(f)])),h=t.map((s,f)=>{var P,Y,K,Q;const b=s.target_per_hour??null,v=b!=null?b*u:null;return{idx:f,x:r(f),expected:v,actual:((P=s.metric)==null?void 0:P.resolved)??0,active:((Y=s.metric)==null?void 0:Y.claimed)??0,pending:((K=s.metric)==null?void 0:K.pending)??0,priorityCount:((Q=s.metric)==null?void 0:Q.priority_count)??0}}),_=h.some(s=>s.expected!=null),L=Math.max(1,...h.map(s=>s.expected??0),...h.map(s=>s.actual),...h.map(s=>s.expected!=null?s.pending:0))*1.15,y=s=>de+we*(1-Math.max(0,Math.min(s,L))/L),m=h.filter(s=>s.expected!=null),C=m.map(s=>({...s,y:y(s.expected)})),F=m.map(s=>({...s,y:y(s.actual)})),k=m.map(s=>({...s,y:y(s.active)})),E=m.map(s=>({...s,y:y(s.pending)})),R=z(C),I=z(F),V=z(k),ee=z(E),T=oe(F),te=oe(C),W=oe(k),se=oe(E),ne=F.length>=2&&T?`${I} L ${T.x.toFixed(1)} ${S} L ${F[0].x.toFixed(1)} ${S} Z`:"",D=m.some(s=>s.pending>0||s.active>0),ae=D&&k.length>=2&&W?`${V} L ${W.x.toFixed(1)} ${S} L ${k[0].x.toFixed(1)} ${S} Z`:"",G=D?Qe(E,k):"",x=m.some(s=>s.active>0),j=m.some(s=>s.pending>s.active),w=Je([te?{key:"target",text:"Target",color:A,y:te.y}:null,T?{key:"actual",text:"Resolved",color:M,y:T.y}:null,x&&W?{key:"active",text:"Claimed",color:O,y:W.y}:null,j&&se?{key:"queued",text:"Pending",color:H,y:se.y}:null].filter(Boolean),S+4);return e.jsxs("svg",{viewBox:`0 0 ${Ne} ${ke}`,className:"w-full h-full",preserveAspectRatio:"xMidYMid meet",style:{display:"block"},children:[t.map(s=>{if(!s.parent_role)return null;const f=o.get(s.parent_role);if(f==null)return null;const b=r(t.findIndex(v=>v.role===s.role));return e.jsx("line",{x1:f,y1:S,x2:b,y2:S,className:"stroke-surface-border",strokeWidth:.75},`dep-${s.role}`)}),ne&&e.jsx("path",{d:ne,opacity:.05,style:{fill:M,transition:`d ${$}`}}),ae&&e.jsx("path",{d:ae,opacity:.12,style:{fill:O,transition:`d ${$}`}}),G&&e.jsx("path",{d:G,opacity:.12,style:{fill:H,transition:`d ${$}`}}),R&&e.jsx("path",{d:R,fill:"none",strokeWidth:.75,strokeDasharray:"2 3",strokeLinecap:"round",opacity:.7,style:{stroke:A,transition:`d ${$}`}}),C.map(s=>e.jsxs("g",{transform:`translate(${s.x} ${s.y})`,style:{transition:`transform ${$}`},children:[e.jsx("circle",{r:2,opacity:.8,style:{fill:A}}),e.jsx("text",{y:-5,textAnchor:"middle",fontSize:6.5,fontFamily:"ui-monospace, monospace",fontWeight:"500",opacity:.7,style:{fill:A},children:Math.round(s.expected)})]},`tval-${s.idx}`)),D&&ee&&e.jsx("path",{d:ee,fill:"none",strokeWidth:.75,strokeDasharray:"2 3",strokeLinecap:"round",opacity:.55,style:{stroke:H,transition:`d ${$}`}}),V&&e.jsx("path",{d:V,fill:"none",strokeWidth:.75,strokeDasharray:"2 3",strokeLinecap:"round",opacity:.5,style:{stroke:O,transition:`d ${$}`}}),I&&e.jsx("path",{d:I,fill:"none",strokeWidth:.6,strokeLinejoin:"round",strokeLinecap:"round",opacity:.65,style:{stroke:M,transition:`d ${$}`}}),k.map((s,f)=>{if(s.pending<=0&&s.active<=0)return null;const b=Math.max(2.5,Math.min(5,2.5+s.active/10)),v=s.pending>s.active,P=Math.min(E[f].y-4,s.y-b-4);return e.jsxs("g",{children:[s.pending>0&&e.jsx("text",{x:s.x,y:P,textAnchor:"middle",fontSize:7.5,fontFamily:"ui-monospace, monospace",fontWeight:"600",style:{fill:v?H:"rgb(var(--lt-text-tertiary))",transition:`y ${$}`},children:s.pending}),e.jsxs("g",{transform:`translate(${s.x} ${s.y})`,style:{transition:`transform ${$}`},children:[e.jsx("circle",{r:b,opacity:.85,style:{fill:O}}),s.active>0&&e.jsx("text",{y:b+9,textAnchor:"middle",fontSize:7.5,fontFamily:"ui-monospace, monospace",fontWeight:"600",style:{fill:O},children:s.active})]})]},`active-${s.idx}`)}),h.map(s=>{var me;const f=t[s.idx],b=s.x,v=s.expected!=null?y(s.actual):S,P=Math.max(2.25,Math.min(4,2.25+s.actual/160)),Y=f.role===a,K=n===s.idx,Q=s.expected==null?"idle · set a target rate to plot pace":`${s.actual} resolved · target ${Math.round(s.expected)}`+(s.pending>s.active?` · ${s.pending-s.active} pending`:"")+(s.active>0?` · ${s.active} claimed`:"")+(s.priorityCount>0?` · ${s.priorityCount} in jeopardy`:""),re=Q.length*5.5+20,ue=Math.max(B+re/2+4,Math.min(he-re/2-4,b)),pe=v-P-10;return e.jsxs("g",{onClick:X=>{X.metaKey||X.ctrlKey?(X.stopPropagation(),l==null||l(f.role)):c(f.role)},onMouseEnter:()=>i(s.idx),onMouseLeave:()=>i(null),style:{cursor:"pointer"},children:[e.jsxs("g",{transform:`translate(${b} ${v})`,style:{transition:`transform ${$}`},children:[e.jsx("circle",{r:22,fill:"transparent"}),e.jsx("circle",{r:P,opacity:.9,style:{fill:M,transition:`r ${$}`}}),s.expected!=null&&e.jsx("text",{y:-P-5,textAnchor:"middle",fontSize:9.5,fontFamily:"ui-monospace, monospace",fontWeight:"500",style:{fill:M},children:Xe(s.actual)}),K&&!Y&&e.jsx("circle",{r:P+3,fill:"none",strokeWidth:1,opacity:.4,style:{stroke:M}}),Y&&e.jsx("circle",{r:P+4,fill:"none",className:"stroke-accent",strokeWidth:2})]}),(((me=f.upstream_roles)==null?void 0:me.length)??0)>0&&e.jsxs("g",{transform:`translate(${b-20} ${S})`,onClick:X=>{X.stopPropagation(),d==null||d(f.upstream_roles[0])},style:{cursor:"pointer"},children:[e.jsx("title",{children:`Fed by ${f.upstream_roles.join(", ")} — click to view that sequence`}),e.jsx("circle",{r:9,cy:-6,fill:"transparent"}),e.jsx("path",{d:"M -7 -14 C -3 -14 -1 -9 0 -2",fill:"none",className:"stroke-text-quaternary",strokeWidth:1,strokeDasharray:"2 2",strokeLinecap:"round"}),e.jsx("path",{d:"M 0 -2 L 8 -2",className:"stroke-text-quaternary",strokeWidth:1,strokeLinecap:"round"}),e.jsx("path",{d:"M 8 -2 l -3.5 -2 v 4 z",className:"fill-text-quaternary"})]}),e.jsx("text",{x:b,y:S+(s.idx%2===0?14:27),textAnchor:"middle",fontSize:9.5,className:"fill-text-tertiary",fontFamily:"ui-sans-serif, sans-serif",fontWeight:"500",children:Z(f)}),K&&e.jsxs("g",{children:[e.jsx("rect",{x:ue-re/2,y:pe-16,width:re,height:19,rx:3,className:"fill-text-primary",opacity:.88}),e.jsx("text",{x:ue,y:pe-3,textAnchor:"middle",fontSize:8.5,className:"fill-surface",fontFamily:"ui-monospace, monospace",children:Q})]})]},f.role)}),!_&&e.jsx("text",{x:B+ce/2,y:S+48,textAnchor:"middle",fontSize:8.5,className:"fill-text-quaternary",fontFamily:"ui-sans-serif, sans-serif",children:"Set target_per_hour on each role in Admin → Roles to enable the pace chart"}),w.map(s=>e.jsx("text",{x:he+6,y:s.labelY,fontSize:8,fontFamily:"ui-sans-serif, sans-serif",fontWeight:s.key==="actual"?700:500,opacity:s.key==="active"?.85:1,style:{fill:s.color,transition:`y ${$}`},children:s.text},s.key))]})}function $e(t){const a=t.priority_facet?`metadata.${t.priority_facet}`:"created_at",c=JSON.stringify([{field:a,direction:"asc"}]);return`/escalations/available?role=${encodeURIComponent(t.role)}&jeopardy=1&view=table&orderBy=${encodeURIComponent(c)}`}const Se=["15m","1h","24h","7d","30d"],tt=t=>Se.includes(t);function le(t){if(t==null)return"—";if(t<1){const a=Math.round(t*60);return a<=0?"< 1s":`${a}s`}return t<60?`${t.toFixed(0)}m`:`${(t/60).toFixed(1)}h`}function ie({label:t,value:a}){return e.jsxs("div",{className:"flex items-center justify-between py-1.5",children:[e.jsx("span",{className:"text-2xs text-text-tertiary uppercase tracking-wider",children:t}),e.jsx("span",{className:"text-xs font-mono font-medium text-text-primary tabular-nums",children:a})]})}function st({period:t,onChange:a}){return e.jsx("div",{className:"flex items-center gap-1 mb-4",children:Se.map(c=>e.jsx("button",{onClick:()=>a(c),className:`px-2 py-0.5 text-2xs font-mono rounded transition-colors ${t===c?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:c},c))})}function nt({role:t,globalPeriod:a,onClose:c}){const[d,l]=g.useState(tt(a)?a:"24h"),{data:u}=be(d),n=u==null?void 0:u.stations.find(o=>o.role===t.role),i=t.sla_minutes??void 0,p=t.target_per_hour??void 0,r=t.worker_count??void 0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-start justify-between mb-4",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-baseline gap-1.5 flex-wrap",children:[e.jsx("span",{className:"text-sm font-bold text-text-primary",children:Z(t)}),e.jsx("span",{className:"text-2xs font-mono text-text-secondary",children:t.role})]}),t.description&&e.jsx("p",{className:"text-2xs text-text-tertiary mt-1 line-clamp-2 leading-relaxed",children:t.description})]}),e.jsx("button",{onClick:c,className:"text-text-quaternary hover:text-text-secondary transition-colors mt-0.5 shrink-0 ml-2",children:e.jsx(Fe,{className:"w-4 h-4"})})]}),e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsxs(q,{to:`/admin/roles/${encodeURIComponent(t.role)}`,className:"flex items-center gap-1 text-2xs text-accent hover:underline",children:[e.jsx(Ie,{className:"w-2.5 h-2.5"}),"Edit in Roles"]}),e.jsxs(q,{to:`/escalations/available?role=${encodeURIComponent(t.role)}`,className:"flex items-center gap-1 text-2xs text-accent hover:underline",children:[e.jsx(Te,{className:"w-2.5 h-2.5"}),"View full queue"]})]}),e.jsx(st,{period:d,onChange:l}),(p||i||r)&&e.jsxs("div",{className:"flex items-center gap-6 mb-6 text-2xs border-b border-surface-border/30 pb-5",children:[p&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono font-semibold text-text-primary text-sm",children:[p,"/h"]}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px] mt-0.5",children:"target"})]}),i&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-mono font-semibold text-text-primary text-sm",children:[i,"m"]}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px] mt-0.5",children:"SLA"})]}),r&&e.jsxs("div",{children:[e.jsx("div",{className:"font-mono font-semibold text-text-primary text-sm",children:r}),e.jsx("div",{className:"text-text-quaternary uppercase tracking-wider text-[8.5px] mt-0.5",children:"workers"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 mb-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-2xs text-text-quaternary uppercase tracking-wider mb-2",children:"Wait (queue)"}),e.jsx(ie,{label:"P99",value:le((n==null?void 0:n.wait.p99)??null)}),e.jsx(ie,{label:"avg",value:le((n==null?void 0:n.wait.avg)??null)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xs text-text-quaternary uppercase tracking-wider mb-2",children:"Work (proc.)"}),e.jsx(ie,{label:"P99",value:le((n==null?void 0:n.work.p99)??null)}),e.jsx(ie,{label:"avg",value:le((n==null?void 0:n.work.avg)??null)})]})]}),e.jsxs("div",{className:"border-t border-surface-border/40 pt-4 mt-5 space-y-2.5",children:[i&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-2xs text-text-tertiary",children:"SLA target"}),e.jsxs("span",{className:"text-xs font-mono text-text-secondary",children:[i,"m"]})]}),n&&n.priority_count>0&&e.jsxs(q,{to:$e(t),className:"flex items-center justify-between group",children:[e.jsxs("span",{className:"text-2xs",style:{color:U},children:[n.priority_count," in jeopardy — pull oldest first"]}),e.jsx(We,{className:"w-3 h-3 transition-colors",style:{color:U}})]})]})]})}function at({allMetrics:t,orderedRoles:a,period:c}){const d=t.reduce((r,o)=>r+o.pending,0),l=t.reduce((r,o)=>r+o.resolved,0),u=t.reduce((r,o)=>r+o.priority_count,0),n=new Map(t.map(r=>[r.role,r])),i=t.filter(r=>r.priority_count>0).length,p=t.filter(r=>r.pending>0).length;return e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-2xs text-text-quaternary uppercase tracking-wider mb-3",children:["Pipeline · ",c]}),e.jsx("div",{className:"mb-4",children:i>0?e.jsxs("p",{className:"text-2xs",style:{color:U},children:[i," station",i>1?"s":""," with items in jeopardy"]}):p>0?e.jsxs("p",{className:"text-2xs text-status-warning",children:[p," station",p>1?"s":""," with backlog"]}):l>0?e.jsx("p",{className:"text-2xs text-status-success",children:"Flowing — queue clear"}):e.jsx("p",{className:"text-2xs text-text-quaternary",children:"Quiet — awaiting work"})}),e.jsxs("div",{className:"space-y-1.5 mb-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-2xs text-text-quaternary uppercase tracking-wider",children:"Pending"}),e.jsx("span",{className:`text-xs font-mono tabular-nums ${d>0?"text-text-primary font-semibold":"text-text-quaternary"}`,children:d})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-2xs text-text-quaternary uppercase tracking-wider",children:["Resolved · ",c]}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-text-secondary",children:l})]}),u>0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-2xs text-text-quaternary uppercase tracking-wider",children:"Priority"}),e.jsx("span",{className:"text-xs font-mono tabular-nums font-semibold",style:{color:U},children:u})]})]}),e.jsx("div",{className:"border-t border-surface-border/40 pt-2 mb-1",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-2xs text-text-quaternary uppercase tracking-wider flex-1",children:"Station"}),e.jsx("span",{className:"text-2xs text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"pend"}),e.jsx("span",{className:"text-2xs text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"clmd"}),e.jsx("span",{className:"text-2xs text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0",children:"res"})]})}),e.jsx("div",{className:"space-y-0.5",children:a.map(r=>{const o=n.get(r.role),h=(o==null?void 0:o.pending)??0,_=(o==null?void 0:o.claimed)??0,N=(o==null?void 0:o.resolved)??0,L=(o==null?void 0:o.priority_count)??0,y=r.title||r.role,m=L>0,C=h>0;return e.jsxs("div",{className:"flex items-center gap-2 py-0.5",children:[e.jsxs("span",{className:`text-2xs font-mono flex-1 truncate ${C?"text-text-primary":"text-text-quaternary"}`,children:[y,m&&e.jsxs("span",{className:"ml-1 text-2xs font-semibold",style:{color:U},children:[L," PRIORITY"]})]}),e.jsx("span",{className:`text-2xs font-mono tabular-nums w-8 text-right shrink-0 ${C?"text-text-primary font-semibold":"text-text-quaternary"}`,children:h>0?h:"—"}),e.jsx("span",{className:`text-2xs font-mono tabular-nums w-8 text-right shrink-0 ${_>0?"text-accent font-semibold":"text-text-quaternary"}`,children:_>0?_:"—"}),e.jsx("span",{className:`text-2xs font-mono tabular-nums w-8 text-right shrink-0 ${N>0?"text-text-secondary":"text-text-quaternary"}`,children:N>0?N:"—"})]},r.role)})}),e.jsx("p",{className:"text-2xs text-text-quaternary mt-5",children:"Select a station for queue detail."})]})}function rt({role:t,allMetrics:a,orderedRoles:c,globalPeriod:d,onClose:l}){return e.jsx("div",{className:"w-[280px] shrink-0 px-7 py-10 flex flex-col overflow-y-auto min-h-0",children:t?e.jsx(nt,{role:t,globalPeriod:d,onClose:l}):e.jsx(at,{allMetrics:a,orderedRoles:c,period:d})})}const ot=A,_e=J(A,.09),Re=J(A,.09),Pe=J(H,.08),Le=J(O,.08),Ce=J(M,.08),Me="minmax(120px, 1.1fr) minmax(100px, 0.9fr) auto 72px 72px 104px 36px",lt=["15m","1h","24h","7d","30d"],it={"15m":.25,"1h":1,"24h":24,"7d":168,"30d":720};function xe(t){const a=t.filter(n=>n.ops_visible),c=new Map(a.map(n=>[n.role,n])),d=new Set,u=a.filter(n=>!n.parent_role||!c.has(n.parent_role)).map(n=>{const i=[],p=[{role:n,depth:0}];for(;p.length>0;){const r=p.shift();d.has(r.role.role)||(d.add(r.role.role),i.push(r),a.filter(o=>o.parent_role===r.role.role&&!d.has(o.role)).forEach(o=>p.push({role:o,depth:r.depth+1})))}return{origin:n,stations:i}});return a.filter(n=>!d.has(n.role)).forEach(n=>u.push({origin:n,stations:[{role:n,depth:0}]})),u.sort((n,i)=>i.stations.length-n.stations.length||n.origin.role.localeCompare(i.origin.role))}function ye(t){if(t==null)return"—";if(t<1){const a=Math.round(t*60);return a<=0?"< 1s":`${a}s`}return t<60?`${t.toFixed(0)}m`:`${(t/60).toFixed(1)}h`}function ct(t,a){if(!a||t===0)return{pct:null,color:"bg-surface-border"};const c=t/a,d=Math.round(c*100),l=c>1?"bg-status-warning":c<.2?"bg-status-draft":"bg-status-success";return{pct:d,color:l}}function ge({value:t,onSave:a}){const[c,d]=g.useState(t!=null?String(t):""),l=g.useRef(void 0),u=n=>{const i=parseInt(n,10);a(!n.trim()||isNaN(i)||i<0?null:i)};return e.jsx("input",{type:"number",min:0,step:1,value:c,onChange:n=>{const i=n.target.value;d(i),clearTimeout(l.current),l.current=setTimeout(()=>u(i),400)},onBlur:n=>{clearTimeout(l.current),u(n.target.value)},onClick:n=>n.stopPropagation(),onKeyDown:n=>n.stopPropagation(),className:"w-full bg-transparent text-xs font-mono tabular-nums text-right focus:outline-none"})}function xt({role:t,metric:a,selected:c,onClick:d}){var y;const l=Ee(),u=(a==null?void 0:a.pending)??0,n=(a==null?void 0:a.claimed)??0,i=(a==null?void 0:a.resolved)??0,p=(a==null?void 0:a.priority_count)??0,r=t.target_per_hour??null,{pct:o,color:h}=ct(u,r),_=o!=null?Math.min(100,o):0,N=m=>l.mutate({role:t.role,target_per_hour:m}),L=m=>l.mutate({role:t.role,sla_minutes:m});return e.jsx(e.Fragment,{children:e.jsxs("div",{role:"button",tabIndex:0,onClick:d,onKeyDown:m=>{m.key==="Enter"&&d()},className:`grid items-center gap-4 pr-3 cursor-pointer transition-colors ${c?"border-l-2 !border-l-accent pl-2.5":"pl-3"}`,style:{gridTemplateColumns:Me},children:[e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0 py-1.5",children:[e.jsx("span",{className:"font-bold text-text-primary truncate text-xs",children:Z(t)}),(((y=t.upstream_roles)==null?void 0:y.length)??0)>0&&e.jsx("span",{title:`Fed by ${t.upstream_roles.join(", ")}`,className:"shrink-0 leading-none",children:e.jsx(ze,{className:"w-3 h-3 text-text-quaternary"})})]}),e.jsx("span",{className:"font-mono text-2xs text-text-tertiary truncate py-1.5",children:t.role}),e.jsxs("div",{className:"self-stretch flex items-stretch",children:[e.jsx("div",{className:"w-16 shrink-0 flex items-center justify-end px-1.5",style:{backgroundColor:_e},children:e.jsx(ge,{value:t.target_per_hour??null,onSave:N})}),e.jsx("div",{className:"w-16 shrink-0 flex items-center justify-end px-1.5",style:{backgroundColor:Re},children:e.jsx(ge,{value:t.sla_minutes??null,onSave:L})}),e.jsx("div",{className:"w-16 shrink-0 flex items-center justify-end px-3",style:{backgroundColor:Pe},children:e.jsx(q,{to:`/escalations/available?role=${encodeURIComponent(t.role)}&status=available`,className:`text-xs font-mono tabular-nums hover:underline ${u>0?"text-text-primary font-semibold":"text-text-quaternary"}`,onClick:m=>m.stopPropagation(),children:u})}),e.jsx("div",{className:"w-16 shrink-0 flex items-center justify-end px-3",style:{backgroundColor:Le},children:e.jsx(q,{to:`/escalations/available?role=${encodeURIComponent(t.role)}&status=claimed`,className:`text-xs font-mono tabular-nums hover:underline ${n>0?"font-semibold":"text-text-quaternary"}`,style:n>0?{color:O}:void 0,onClick:m=>m.stopPropagation(),children:n})}),e.jsx("div",{className:"w-16 shrink-0 flex items-center justify-end px-3",style:{backgroundColor:Ce},children:e.jsx(q,{to:`/escalations/available?role=${encodeURIComponent(t.role)}&status=resolved`,className:`text-xs font-mono tabular-nums hover:underline ${i>0?"text-text-secondary":"text-text-quaternary"}`,style:i>0?{color:M}:void 0,onClick:m=>m.stopPropagation(),children:i})})]}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-right py-1.5 text-text-secondary",children:ye((a==null?void 0:a.wait.p99)??null)}),e.jsx("span",{className:"text-xs font-mono tabular-nums text-right py-1.5 text-text-secondary",children:ye((a==null?void 0:a.work.p99)??null)}),e.jsxs("div",{className:"flex items-center gap-2 py-1.5",children:[e.jsx("div",{className:"w-12 h-1.5 bg-surface-sunken rounded-full overflow-hidden shrink-0",children:e.jsx("div",{className:`h-full rounded-full ${h}`,style:{width:`${_}%`}})}),e.jsx("span",{className:`text-2xs font-mono tabular-nums ${o!=null&&o>100?"text-status-warning font-semibold":"text-text-quaternary"}`,children:o!=null?`${o}%`:"—"})]}),e.jsxs("div",{className:"flex items-center justify-center gap-2 py-1.5",children:[p>0&&e.jsx(q,{to:$e(t),className:"text-status-error hover:opacity-70 transition-opacity",title:`${p} item${p===1?"":"s"} in jeopardy — pull oldest first`,onClick:m=>m.stopPropagation(),children:e.jsx(ve,{className:"w-3.5 h-3.5",strokeWidth:2})}),e.jsx(q,{to:`/escalations/available?role=${encodeURIComponent(t.role)}&status=all`,className:"text-text-quaternary hover:text-accent transition-colors",title:"View all items in queue",onClick:m=>m.stopPropagation(),children:e.jsx(He,{className:"w-3.5 h-3.5"})})]})]})})}function je({n:t}){return t<=0?null:e.jsxs("span",{className:"inline-flex items-center gap-0.5 font-semibold tabular-nums",style:{color:U},title:`${t} in jeopardy`,children:[e.jsx(ve,{className:"w-3 h-3",strokeWidth:2.25}),t>9?"9+":t]})}function dt({fragments:t,aggregates:a,activeOrigin:c,onSelect:d}){const[l,u]=g.useState(!1),n=g.useRef(null);g.useEffect(()=>{if(!l)return;const r=h=>{n.current&&!n.current.contains(h.target)&&u(!1)},o=h=>{h.key==="Escape"&&u(!1)};return document.addEventListener("mousedown",r),document.addEventListener("keydown",o),()=>{document.removeEventListener("mousedown",r),document.removeEventListener("keydown",o)}},[l]);const i=t.find(r=>r.origin.role===c)??t[0];if(!i)return null;const p=a.get(i.origin.role);return e.jsxs("div",{ref:n,className:"relative px-4 pt-2",children:[e.jsxs("button",{type:"button",onClick:()=>u(r=>!r),className:"group flex items-baseline gap-2.5","aria-expanded":l,"aria-haspopup":"listbox",children:[e.jsx("span",{className:"text-sm font-medium text-text-primary group-hover:text-accent transition-colors",children:Z(i.origin)}),e.jsxs("span",{className:"text-2xs font-mono text-text-quaternary tabular-nums",children:[(p==null?void 0:p.stations)??i.stations.length," station",((p==null?void 0:p.stations)??i.stations.length)===1?"":"s"," · ",(p==null?void 0:p.pending)??0," pending"]}),e.jsx(je,{n:(p==null?void 0:p.jeopardy)??0}),e.jsx(Be,{className:`w-3.5 h-3.5 self-center shrink-0 text-text-tertiary group-hover:text-accent transition-transform ${l?"rotate-180":""}`,strokeWidth:1.5})]}),l&&e.jsx("div",{role:"listbox",className:"absolute z-[100] top-full left-4 mt-1.5 min-w-[20rem] max-h-80 overflow-y-auto bg-surface-raised border border-surface-border rounded-md shadow-lg py-1",children:t.map(r=>{const o=a.get(r.origin.role),h=r.origin.role===i.origin.role;return e.jsxs("button",{type:"button",role:"option","aria-selected":h,onClick:()=>{d(r.origin.role),u(!1)},className:`w-full text-left px-3 py-1.5 flex items-baseline gap-2.5 transition-colors ${h?"text-accent bg-accent/5":"text-text-primary hover:bg-surface-hover"}`,children:[e.jsx("span",{className:"text-xs font-medium truncate",children:Z(r.origin)}),e.jsxs("span",{className:"ml-auto text-2xs font-mono text-text-quaternary tabular-nums shrink-0",children:[(o==null?void 0:o.stations)??r.stations.length," st · ",(o==null?void 0:o.pending)??0," pending"]}),e.jsx("span",{className:"w-12 shrink-0 text-left text-2xs",children:e.jsx(je,{n:(o==null?void 0:o.jeopardy)??0})})]},r.origin.role)})})]})}function ut(){const t=[{label:"TARGET/H",band:_e,hue:A,w:"w-16"},{label:"SLA/M",band:Re,hue:ot,w:"w-16"},{label:"PENDING",band:Pe,hue:H,w:"w-16",px:"px-3"},{label:"CLAIMED",band:Le,hue:O,w:"w-16",px:"px-3"},{label:"RESOLVED",band:Ce,hue:M,w:"w-16",px:"px-3"}];return e.jsxs("div",{className:"grid items-center gap-4 px-3 border-b border-surface-border mb-0.5",style:{gridTemplateColumns:Me},children:[e.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5",children:"NAME"}),e.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5",children:"ROLE"}),e.jsx("div",{className:"self-stretch flex items-stretch",children:t.map(a=>e.jsx("div",{className:`${a.w} shrink-0 flex items-center justify-end ${"px"in a?a.px:"px-1.5"}`,style:{backgroundColor:a.band},children:e.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider",style:{color:a.hue},children:a.label})},a.label))}),e.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5 text-right",children:"P99 WAIT"}),e.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5 text-right",children:"P99 WORK"}),e.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5",children:"TREND"}),e.jsx("span",{className:"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5 text-center",children:"ACTIONS"})]})}function pt(){var G;const[t,a]=g.useState("1h"),[c,d]=g.useState(null),[l,u]=g.useState(!1);Oe();const{data:n,isLoading:i,refetch:p}=qe(),{data:r,isLoading:o,refetch:h}=be(t),_=(n==null?void 0:n.roles)??[],N=(r==null?void 0:r.stations)??[],L=g.useMemo(()=>{const x=new Map(N.map(w=>[w.role,w])),j=new Map;for(const w of xe((n==null?void 0:n.roles)??[])){let s=0,f=0;for(const b of w.stations){const v=x.get(b.role.role);s+=(v==null?void 0:v.pending)??0,f+=(v==null?void 0:v.priority_count)??0}j.set(w.origin.role,{stations:w.stations.length,pending:s,jeopardy:f})}return j},[N,n]),y=g.useMemo(()=>xe(_),[_]),[m,C]=Ue(),F=m.get("fragment"),k=y.find(x=>x.origin.role===F)??y[0]??null,E=g.useCallback(x=>{d(null),C(j=>{const w=new URLSearchParams(j);return w.set("fragment",x),w})},[C]),R=(k==null?void 0:k.stations)??[],I=g.useMemo(()=>new Set(R.map(({role:x})=>x.role)),[R]),V=g.useMemo(()=>N.filter(x=>I.has(x.role)),[N,I]),ee=g.useMemo(()=>R.map(({role:x})=>({role:x.role,title:x.title,parent_role:x.parent_role,target_per_hour:x.target_per_hour??null,upstream_roles:x.upstream_roles??[],metric:N.find(j=>j.role===x.role)})),[R,N]),T=g.useCallback(x=>{const j=y.find(w=>w.stations.some(({role:s})=>s.role===x));j&&E(j.origin.role)},[y,E]),te=Ve(),W=((G=R.find(({role:x})=>x.role===c))==null?void 0:G.role)??null,se=i||o,ne=async()=>{u(!0),await Promise.all([p(),h()]),u(!1)},D=x=>d(j=>j===x?null:x),ae=e.jsx("div",{className:"flex items-center gap-0.5",children:lt.map(x=>e.jsx("button",{onClick:()=>a(x),className:`px-2.5 py-1 text-2xs font-mono rounded transition-colors ${t===x?"bg-accent/10 text-accent font-semibold":"text-text-quaternary hover:text-text-secondary"}`,children:x},x))});return e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[e.jsx(Ae,{title:"Pace Board",docsHash:"#docs:dashboard.md:pace-board",center:ae,actions:e.jsx("button",{onClick:ne,disabled:l,className:"text-text-quaternary hover:text-text-secondary transition-colors disabled:opacity-40",children:e.jsx(De,{className:`w-3.5 h-3.5 ${l?"animate-spin":""}`})})}),se?e.jsxs("div",{className:"animate-pulse space-y-6 mt-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-64 bg-surface-sunken rounded w-full"}),e.jsx("div",{className:"space-y-3",children:[1,2,3].map(x=>e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-full"},x))})]}):y.length===0?e.jsxs("div",{className:"mt-8",children:[e.jsx("p",{className:"text-sm text-text-secondary mb-2",children:"Stations appear here once roles are marked visible in Operations."}),e.jsxs("p",{className:"text-xs text-text-tertiary",children:["Go to"," ",e.jsx(q,{to:"/admin/roles",className:"text-accent hover:underline",children:"Roles"})," ","and enable ",e.jsx("strong",{children:"Visible in Operations"})," on roles that represent pipeline stations."]})]}):e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[y.length>1&&e.jsx(dt,{fragments:y,aggregates:L,activeOrigin:(k==null?void 0:k.origin.role)??null,onSelect:E}),e.jsxs("div",{className:"flex-1 min-h-[40vh] flex items-stretch overflow-hidden",children:[e.jsx("div",{className:"flex-1 min-w-0 min-h-0 flex flex-col justify-center overflow-hidden p-4",children:e.jsx(et,{stations:ee,selectedRole:c,onSelect:D,onUpstreamSelect:T,onCmdClick:x=>te(`/escalations/available?role=${encodeURIComponent(x)}`),periodHours:it[t]})}),e.jsx("div",{className:"w-px bg-surface-border shrink-0 self-stretch"}),e.jsx(rt,{role:W,allMetrics:V,orderedRoles:R.map(x=>x.role),globalPeriod:t,onClose:()=>d(null)})]}),e.jsxs("div",{className:"max-h-[30vh] flex-none flex flex-col border-t border-surface-border overflow-hidden",children:[e.jsx(ut,{}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto divide-y divide-surface-border/30",children:R.map(({role:x})=>e.jsx(xt,{role:x,metric:N.find(j=>j.role===x.role),selected:c===x.role,onClick:()=>D(x.role)},x.role))})]})]})]})}const vt=Object.freeze(Object.defineProperty({__proto__:null,OperationsPage:pt,buildFragments:xe},Symbol.toStringTag,{value:"Module"}));export{vt as O,et as P,xe as b,$e as j};
|
|
2
|
-
//# sourceMappingURL=OperationsPage-DI7AQO9f.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OperationsPage-DI7AQO9f.js","sources":["../../src/pages/operations/PaceChart.tsx","../../src/pages/operations/priority-link.ts","../../src/pages/operations/StationDetailPanel.tsx","../../src/pages/operations/OperationsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { StationMetric } from '../../api/escalations';\nimport { displayRoleTitle } from '../../lib/role-display';\n\nexport interface ChartStation {\n role: string;\n title: string | null;\n target_per_hour: number | null;\n parent_role: string | null;\n /** Roles feeding this station from other sequences — drawn as a merge glyph, not a bend in the line. */\n upstream_roles?: string[];\n metric: StationMetric | undefined;\n}\n\ninterface PaceChartProps {\n stations: ChartStation[];\n selectedRole: string | null;\n onSelect: (role: string) => void;\n /** Merge-glyph click — jump to the sequence that feeds this station. */\n onUpstreamSelect?: (upstreamRole: string) => void;\n /** Priority-badge click — open the station's queue oldest-first by its age facet. */\n /** Cmd/meta+click on a resolved dot — navigate to the role's full queue. */\n onCmdClick?: (role: string) => void;\n /** Selected window length in hours — target count = target_per_hour × this. */\n periodHours: number;\n}\n\n// ── SVG layout ────────────────────────────────────────────────────────────────\n\nconst W = 800;\nconst H = 270;\nconst ML = 40;\nconst MR = 76;\nconst MT = 24;\nconst MB = 72;\n\nconst chartW = W - ML - MR;\nconst chartH = H - MT - MB;\nconst bottom = MT + chartH;\nconst right = ML + chartW;\n\n// Smooth transition applied when the window changes and values re-scale.\nconst EASE = '0.5s cubic-bezier(0.4, 0, 0.2, 1)';\n\n// ── Path builders ─────────────────────────────────────────────────────────────\n\n// A one-point curve still needs a stroke: a short segment — slightly longer\n// than an em dash — centered through the point. It anchors the dot and its\n// end label in vertical space when a sequence has a single station (or a\n// single station carries a target).\nconst SOLO_HALF = 9;\nfunction soloSegment(p: { x: number; y: number }): string {\n return `M ${(p.x - SOLO_HALF).toFixed(1)} ${p.y.toFixed(1)} L ${(p.x + SOLO_HALF).toFixed(1)} ${p.y.toFixed(1)}`;\n}\n\n/** Catmull-Rom → cubic bezier — smooth curves for the target, actual, and active lines. */\nfunction catmullPath(pts: { x: number; y: number }[]): string {\n if (pts.length === 0) return '';\n if (pts.length === 1) return soloSegment(pts[0]);\n const segs: string[] = [];\n for (let i = 0; i < pts.length - 1; i++) {\n const p0 = pts[Math.max(0, i - 1)];\n const p1 = pts[i];\n const p2 = pts[i + 1];\n const p3 = pts[Math.min(pts.length - 1, i + 2)];\n const cp1x = (p1.x + (p2.x - p0.x) / 6).toFixed(1);\n const cp1y = (p1.y + (p2.y - p0.y) / 6).toFixed(1);\n const cp2x = (p2.x - (p3.x - p1.x) / 6).toFixed(1);\n const cp2y = (p2.y - (p3.y - p1.y) / 6).toFixed(1);\n if (i === 0) segs.push(`M ${p1.x.toFixed(1)} ${p1.y.toFixed(1)}`);\n segs.push(`C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2.x.toFixed(1)} ${p2.y.toFixed(1)}`);\n }\n return segs.join(' ');\n}\n\n/**\n * Closed region between two curves — upper spline forward, lower spline back.\n * Used for the queue-composition bands: the vertical thickness at any station\n * is the count difference between the two curves.\n */\nfunction bandPath(upper: { x: number; y: number }[], lower: { x: number; y: number }[]): string {\n if (upper.length < 2 || lower.length < 2) return '';\n const forward = catmullPath(upper);\n const rev = [...lower].reverse();\n const back = catmullPath(rev);\n // Drop the back path's leading M — the L below connects the two curves.\n const backSegs = back.slice(back.indexOf('C'));\n return `${forward} L ${rev[0].x.toFixed(1)} ${rev[0].y.toFixed(1)} ${backSegs} Z`;\n}\n\nfunction compact(n: number): string {\n return n >= 10000 ? `${Math.round(n / 1000)}k` : n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n);\n}\n\nfunction last<T>(a: T[]): T | undefined {\n return a.length > 0 ? a[a.length - 1] : undefined;\n}\n\n// ── Colors ────────────────────────────────────────────────────────────────────\n\n// Shared queue-state palette — the chart bands and the station table columns\n// use the same hues so the two views read as one. Each hue resolves through\n// a --lt-* theme token so registered themes (including dark) restyle the\n// chart; the navy default keeps the original sky/orange/green/slate look.\nexport const ACTIVE_COLOR = 'rgb(var(--lt-status-claimed-graphic))'; // claimed, being worked right now — orange\nexport const QUEUED_COLOR = 'rgb(var(--lt-status-queued-graphic))'; // pending and unclaimed, waiting in the queue — sky\nexport const RESOLVED_COLOR = 'rgb(var(--lt-status-success-graphic))'; // done — green\nexport const TARGET_COLOR = 'rgb(var(--lt-text-quaternary))'; // target pace line — muted gray\n\n// Priority — unclaimed items past the role's age threshold, the count the\n// floor pulls to the front of the rack.\n// Jeopardy shares one red across the product (the pill, the table sub-row,\n// this chart's badge) — the hard-limit alarm, distinct from every pace hue.\nexport const PRIORITY_COLOR = 'rgb(var(--lt-status-error))';\nexport const PRIORITY_TEXT_COLOR = 'rgb(var(--lt-status-error))';\n\n/** Translucent tint of a token-based `rgb(var(--…))` color, for band fills. */\nexport function withAlpha(color: string, alpha: number): string {\n return color.replace(/\\)$/, ` / ${alpha})`);\n}\n\n// ── End-label stacking — spread close labels so text doesn't collide ────────────\n\nconst MIN_GAP = 13;\nfunction spreadLabels<T extends { y: number }>(labels: T[], maxY: number): (T & { labelY: number })[] {\n const sorted = [...labels].sort((a, b) => a.y - b.y);\n let prev = -Infinity;\n const placed = sorted.map((l) => {\n const labelY = Math.max(l.y + 3, prev + MIN_GAP);\n prev = labelY;\n return { ...l, labelY };\n });\n // On a quiet window every curve sits at zero and the stack would descend\n // past the floor into the station titles — lift the whole stack back above\n // maxY instead.\n const overflow = placed.length > 0 ? placed[placed.length - 1].labelY - maxY : 0;\n if (overflow > 0) {\n for (const l of placed) l.labelY -= overflow;\n }\n return placed;\n}\n\n// ── Chart ─────────────────────────────────────────────────────────────────────\n\nexport function PaceChart({ stations, selectedRole, onSelect, onUpstreamSelect, onCmdClick, periodHours }: PaceChartProps) {\n const [hoveredIdx, setHoveredIdx] = useState<number | null>(null);\n\n const n = stations.length;\n if (n === 0) return null;\n\n const xOf = (i: number) => (n === 1 ? ML + chartW / 2 : ML + (i / (n - 1)) * chartW);\n const xMap = new Map(stations.map((s, i) => [s.role, xOf(i)]));\n\n // Per-station counts for the selected window:\n // - target : expected units = target_per_hour × periodHours (e.g. 22/h · 15m ≈ 5).\n // - actual : units resolved in the window (\"the number we see\").\n // - active : units in the queue being worked right now (claimed).\n const rows = stations.map((s, i) => {\n const target = s.target_per_hour ?? null;\n const expected = target != null ? target * periodHours : null;\n return {\n idx: i,\n x: xOf(i),\n expected,\n actual: s.metric?.resolved ?? 0,\n active: s.metric?.claimed ?? 0,\n pending: s.metric?.pending ?? 0,\n priorityCount: s.metric?.priority_count ?? 0,\n };\n });\n\n const hasTargets = rows.some((r) => r.expected != null);\n\n const dataMax = Math.max(\n 1,\n ...rows.map((r) => r.expected ?? 0),\n ...rows.map((r) => r.actual),\n ...rows.map((r) => (r.expected != null ? r.pending : 0)),\n );\n const maxVal = dataMax * 1.15;\n const yScale = (v: number) => MT + chartH * (1 - Math.max(0, Math.min(v, maxVal)) / maxVal);\n\n const withTarget = rows.filter((r) => r.expected != null);\n const targetPts = withTarget.map((r) => ({ ...r, y: yScale(r.expected as number) }));\n const actualPts = withTarget.map((r) => ({ ...r, y: yScale(r.actual) }));\n const activePts = withTarget.map((r) => ({ ...r, y: yScale(r.active) }));\n const pendingPts = withTarget.map((r) => ({ ...r, y: yScale(r.pending) }));\n\n const targetLinePath = catmullPath(targetPts);\n const actualSplinePath = catmullPath(actualPts);\n const activeSplinePath = catmullPath(activePts);\n const pendingSplinePath = catmullPath(pendingPts);\n\n const lastActual = last(actualPts);\n const lastTarget = last(targetPts);\n const lastActive = last(activePts);\n const lastPending = last(pendingPts);\n\n const areaPath =\n actualPts.length >= 2 && lastActual\n ? `${actualSplinePath} L ${lastActual.x.toFixed(1)} ${bottom} L ${actualPts[0].x.toFixed(1)} ${bottom} Z`\n : '';\n\n // Queue composition — pending splits into two stacked bands:\n // floor → active curve = claimed, being worked (indigo)\n // active → pending curve = waiting, unclaimed (sky)\n // When workers claim everything the instant it lands, the sky band collapses\n // to zero and the whole queue reads as indigo.\n const hasQueue = withTarget.some((r) => r.pending > 0 || r.active > 0);\n const workedBandPath =\n hasQueue && activePts.length >= 2 && lastActive\n ? `${activeSplinePath} L ${lastActive.x.toFixed(1)} ${bottom} L ${activePts[0].x.toFixed(1)} ${bottom} Z`\n : '';\n const queuedBandPath = hasQueue ? bandPath(pendingPts, activePts) : '';\n\n // Quiet lines keep their curves (flat at zero) but skip their end labels —\n // a stack of names pointing at nothing is noise.\n const showActiveLabel = withTarget.some((r) => r.active > 0);\n const showQueuedLabel = withTarget.some((r) => r.pending > r.active);\n const endLabels = spreadLabels(\n [\n lastTarget ? { key: 'target', text: 'Target', color: TARGET_COLOR, y: lastTarget.y } : null,\n lastActual ? { key: 'actual', text: 'Resolved', color: RESOLVED_COLOR, y: lastActual.y } : null,\n showActiveLabel && lastActive\n ? { key: 'active', text: 'Claimed', color: ACTIVE_COLOR, y: lastActive.y }\n : null,\n showQueuedLabel && lastPending\n ? { key: 'queued', text: 'Pending', color: QUEUED_COLOR, y: lastPending.y }\n : null,\n ].filter(Boolean) as { key: string; text: string; color: string; y: number }[],\n bottom + 4,\n );\n\n return (\n <svg viewBox={`0 0 ${W} ${H}`} className=\"w-full h-full\" preserveAspectRatio=\"xMidYMid meet\" style={{ display: 'block' }}>\n {/* Dependency connector lines (parent → child), drawn at chart floor */}\n {stations.map((s) => {\n if (!s.parent_role) return null;\n const px = xMap.get(s.parent_role);\n if (px == null) return null;\n const cx = xOf(stations.findIndex((r) => r.role === s.role));\n return <line key={`dep-${s.role}`} x1={px} y1={bottom} x2={cx} y2={bottom} className=\"stroke-surface-border\" strokeWidth={0.75} />;\n })}\n\n {/* Area under the actual curve */}\n {areaPath && <path d={areaPath} opacity={0.05} style={{ fill: RESOLVED_COLOR, transition: `d ${EASE}` }} />}\n\n {/* Queue composition bands — the band heights split each station's\n pending total into claimed-and-worked (indigo, floor→active) and\n waiting-unclaimed (sky, active→pending). */}\n {workedBandPath && (\n <path d={workedBandPath} opacity={0.12} style={{ fill: ACTIVE_COLOR, transition: `d ${EASE}` }} />\n )}\n {queuedBandPath && (\n <path d={queuedBandPath} opacity={0.12} style={{ fill: QUEUED_COLOR, transition: `d ${EASE}` }} />\n )}\n\n {/* Target — dashed reference curve at the window's expected count */}\n {targetLinePath && (\n <path d={targetLinePath} fill=\"none\" strokeWidth={0.75} strokeDasharray=\"2 3\" strokeLinecap=\"round\" opacity={0.7} style={{ stroke: TARGET_COLOR, transition: `d ${EASE}` }} />\n )}\n\n {/* Per-station target markers — a small emerald dot on the target line\n (mirroring the Resolved line's dots) with the window's expected count\n (target_per_hour × duration) just above it */}\n {targetPts.map((tp) => (\n <g key={`tval-${tp.idx}`} transform={`translate(${tp.x} ${tp.y})`} style={{ transition: `transform ${EASE}` }}>\n <circle r={2} opacity={0.8} style={{ fill: TARGET_COLOR }} />\n <text\n y={-5}\n textAnchor=\"middle\"\n fontSize={6.5}\n fontFamily=\"ui-monospace, monospace\"\n fontWeight=\"500\"\n opacity={0.7}\n style={{ fill: TARGET_COLOR }}\n >\n {Math.round(tp.expected as number)}\n </text>\n </g>\n ))}\n\n {/* Pending — thin dotted sky edge along the queue total (top of the bands) */}\n {hasQueue && pendingSplinePath && (\n <path d={pendingSplinePath} fill=\"none\" strokeWidth={0.75} strokeDasharray=\"2 3\" strokeLinecap=\"round\" opacity={0.55} style={{ stroke: QUEUED_COLOR, transition: `d ${EASE}` }} />\n )}\n\n {/* Active — thin dotted indigo, how many are claimed and being worked */}\n {activeSplinePath && (\n <path d={activeSplinePath} fill=\"none\" strokeWidth={0.75} strokeDasharray=\"2 3\" strokeLinecap=\"round\" opacity={0.5} style={{ stroke: ACTIVE_COLOR, transition: `d ${EASE}` }} />\n )}\n\n {/* Actual — thin solid, primary line */}\n {actualSplinePath && (\n <path d={actualSplinePath} fill=\"none\" strokeWidth={0.6} strokeLinejoin=\"round\" strokeLinecap=\"round\" opacity={0.65} style={{ stroke: RESOLVED_COLOR, transition: `d ${EASE}` }} />\n )}\n\n {/* Queue markers — a dot on the active line per station.\n Above the dot, at the pending edge: the queue total (sky when part of\n it is still waiting, slate when everything is claimed).\n Below the dot: active (claimed, being worked right now). */}\n {activePts.map((ap, i) => {\n if (ap.pending <= 0 && ap.active <= 0) return null;\n const ar = Math.max(2.5, Math.min(5, 2.5 + ap.active / 10));\n const hasWaiting = ap.pending > ap.active;\n // Anchor the queue-total label to the pending edge so it rides the top\n // of the band; keep it clear of the dot when the two curves touch.\n const pendingLabelY = Math.min(pendingPts[i].y - 4, ap.y - ar - 4);\n return (\n <g key={`active-${ap.idx}`}>\n {ap.pending > 0 && (\n <text\n x={ap.x}\n y={pendingLabelY}\n textAnchor=\"middle\"\n fontSize={7.5}\n fontFamily=\"ui-monospace, monospace\"\n fontWeight=\"600\"\n style={{ fill: hasWaiting ? QUEUED_COLOR : 'rgb(var(--lt-text-tertiary))', transition: `y ${EASE}` }}\n >\n {ap.pending}\n </text>\n )}\n <g transform={`translate(${ap.x} ${ap.y})`} style={{ transition: `transform ${EASE}` }}>\n <circle r={ar} opacity={0.85} style={{ fill: ACTIVE_COLOR }} />\n {ap.active > 0 && (\n <text y={ar + 9} textAnchor=\"middle\" fontSize={7.5} fontFamily=\"ui-monospace, monospace\" fontWeight=\"600\" style={{ fill: ACTIVE_COLOR }}>\n {ap.active}\n </text>\n )}\n </g>\n </g>\n );\n })}\n\n {/* Station nodes — actual (resolved) as a dot on the actual line, styled like\n the active dot but a bit larger (actual is the most important number).\n The count sits below the dot so it stays legible as numbers grow. */}\n {rows.map((row) => {\n const s = stations[row.idx];\n const x = row.x;\n const cy = row.expected != null ? yScale(row.actual) : bottom;\n // Same small scale as the active dot — a hair larger.\n const r = Math.max(2.25, Math.min(4, 2.25 + row.actual / 160));\n const isSelected = s.role === selectedRole;\n const isHovered = hoveredIdx === row.idx;\n\n const tooltip =\n row.expected == null\n ? 'idle · set a target rate to plot pace'\n : `${row.actual} resolved · target ${Math.round(row.expected)}`\n + (row.pending > row.active ? ` · ${row.pending - row.active} pending` : '')\n + (row.active > 0 ? ` · ${row.active} claimed` : '')\n + (row.priorityCount > 0 ? ` · ${row.priorityCount} in jeopardy` : '');\n const tipW = tooltip.length * 5.5 + 20;\n const tipX = Math.max(ML + tipW / 2 + 4, Math.min(right - tipW / 2 - 4, x));\n const tipY = cy - r - 10;\n\n return (\n <g\n key={s.role}\n onClick={(e) => {\n if (e.metaKey || e.ctrlKey) {\n e.stopPropagation();\n onCmdClick?.(s.role);\n } else {\n onSelect(s.role);\n }\n }}\n onMouseEnter={() => setHoveredIdx(row.idx)}\n onMouseLeave={() => setHoveredIdx(null)}\n style={{ cursor: 'pointer' }}\n >\n {/* Animated marker group — slides vertically as the window rescales */}\n <g transform={`translate(${x} ${cy})`} style={{ transition: `transform ${EASE}` }}>\n <circle r={22} fill=\"transparent\" />\n <circle r={r} opacity={0.9} style={{ fill: RESOLVED_COLOR, transition: `r ${EASE}` }} />\n {row.expected != null && (\n <text y={-r - 5} textAnchor=\"middle\" fontSize={9.5} fontFamily=\"ui-monospace, monospace\" fontWeight=\"500\" style={{ fill: RESOLVED_COLOR }}>\n {compact(row.actual)}\n </text>\n )}\n {isHovered && !isSelected && <circle r={r + 3} fill=\"none\" strokeWidth={1} opacity={0.4} style={{ stroke: RESOLVED_COLOR }} />}\n {isSelected && <circle r={r + 4} fill=\"none\" className=\"stroke-accent\" strokeWidth={2} />}\n </g>\n\n\n {/* Merge affordance — this station also receives input from another\n sequence. The dashed drop into the floor says \"a side-quest\n lands here\"; clicking it opens that sequence. It is a symbol,\n deliberately not a line — the upstream is NOT a descendant. */}\n {(s.upstream_roles?.length ?? 0) > 0 && (\n <g\n transform={`translate(${x - 20} ${bottom})`}\n onClick={(e) => {\n e.stopPropagation();\n onUpstreamSelect?.(s.upstream_roles![0]);\n }}\n style={{ cursor: 'pointer' }}\n >\n <title>{`Fed by ${s.upstream_roles!.join(', ')} — click to view that sequence`}</title>\n <circle r={9} cy={-6} fill=\"transparent\" />\n <path d=\"M -7 -14 C -3 -14 -1 -9 0 -2\" fill=\"none\" className=\"stroke-text-quaternary\" strokeWidth={1} strokeDasharray=\"2 2\" strokeLinecap=\"round\" />\n <path d=\"M 0 -2 L 8 -2\" className=\"stroke-text-quaternary\" strokeWidth={1} strokeLinecap=\"round\" />\n <path d=\"M 8 -2 l -3.5 -2 v 4 z\" className=\"fill-text-quaternary\" />\n </g>\n )}\n\n {/* Station label — the display name (user-set title, or derived\n from the role id). The exact id lives in the table below.\n Adjacent labels alternate depth from the baseline so dense\n sequences don't collide. */}\n <text\n x={x}\n y={bottom + (row.idx % 2 === 0 ? 14 : 27)}\n textAnchor=\"middle\"\n fontSize={9.5}\n className=\"fill-text-tertiary\"\n fontFamily=\"ui-sans-serif, sans-serif\"\n fontWeight=\"500\"\n >\n {displayRoleTitle(s)}\n </text>\n\n {/* Tooltip */}\n {isHovered && (\n <g>\n <rect x={tipX - tipW / 2} y={tipY - 16} width={tipW} height={19} rx={3} className=\"fill-text-primary\" opacity={0.88} />\n <text x={tipX} y={tipY - 3} textAnchor=\"middle\" fontSize={8.5} className=\"fill-surface\" fontFamily=\"ui-monospace, monospace\">\n {tooltip}\n </text>\n </g>\n )}\n </g>\n );\n })}\n\n {/* No-target hint */}\n {!hasTargets && (\n <text x={ML + chartW / 2} y={bottom + 48} textAnchor=\"middle\" fontSize={8.5} className=\"fill-text-quaternary\" fontFamily=\"ui-sans-serif, sans-serif\">\n Set target_per_hour on each role in Admin → Roles to enable the pace chart\n </text>\n )}\n\n {/* End labels — text + count, rendered last so they sit above everything */}\n {endLabels.map((l) => (\n <text\n key={l.key}\n x={right + 6}\n y={l.labelY}\n fontSize={8}\n fontFamily=\"ui-sans-serif, sans-serif\"\n fontWeight={l.key === 'actual' ? 700 : 500}\n opacity={l.key === 'active' ? 0.85 : 1}\n style={{ fill: l.color, transition: `y ${EASE}` }}\n >\n {l.text}\n </text>\n ))}\n </svg>\n );\n}\n","import type { RoleDetail } from '../../api/roles';\n\n/**\n * The jeopardy deep link — the plant manager's \"focus on exactly these n items\".\n * One builder for every jeopardy pill (Pace Board chart, Home mini board, the\n * operator's Task Queue cards), producing a URL that reproduces the pill's set\n * precisely:\n *\n * - `jeopardy=1` — the server-side threshold predicate (the SAME expression\n * that produced the pill's count), so the list total equals the pill.\n * - `orderBy` on the role's age origin, ascending — oldest first. The metadata\n * facet when configured, else created_at; the sort control labels the field.\n * - `view=table` — a discrete, countable list, never the timeline.\n */\nexport function jeopardyQueueLink(role: Pick<RoleDetail, 'role' | 'priority_facet'>): string {\n const field = role.priority_facet ? `metadata.${role.priority_facet}` : 'created_at';\n const orderBy = JSON.stringify([{ field, direction: 'asc' }]);\n return `/escalations/available?role=${encodeURIComponent(role.role)}&jeopardy=1&view=table&orderBy=${encodeURIComponent(orderBy)}`;\n}\n","import { useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport { X, ExternalLink, Settings, List } from 'lucide-react';\nimport { useStationMetrics } from '../../api/escalations';\nimport type { StationMetric } from '../../api/escalations';\nimport type { RoleDetail } from '../../api/roles';\nimport { PRIORITY_TEXT_COLOR } from './PaceChart';\nimport { jeopardyQueueLink } from './priority-link';\nimport { displayRoleTitle } from '../../lib/role-display';\n\ninterface StationDetailPanelProps {\n role: RoleDetail | null;\n allMetrics: StationMetric[];\n orderedRoles: RoleDetail[];\n globalPeriod: string;\n onClose: () => void;\n}\n\n// Mirrors OperationsPage's selector — the panel reports the same windows the\n// chart can show, and opens on whichever one the chart has selected.\nconst PERIODS = ['15m', '1h', '24h', '7d', '30d'] as const;\ntype Period = (typeof PERIODS)[number];\n\nconst isPeriod = (p: string): p is Period => (PERIODS as readonly string[]).includes(p);\n\nfunction fmt(min: number | null): string {\n if (min == null) return '—';\n if (min < 1) {\n const s = Math.round(min * 60);\n return s <= 0 ? '< 1s' : `${s}s`;\n }\n if (min < 60) return `${min.toFixed(0)}m`;\n return `${(min / 60).toFixed(1)}h`;\n}\n\nfunction MetricRow({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"flex items-center justify-between py-1.5\">\n <span className=\"text-2xs text-text-tertiary uppercase tracking-wider\">{label}</span>\n <span className=\"text-xs font-mono font-medium text-text-primary tabular-nums\">{value}</span>\n </div>\n );\n}\n\nfunction PeriodSelector({ period, onChange }: { period: Period; onChange: (p: Period) => void }) {\n return (\n <div className=\"flex items-center gap-1 mb-4\">\n {PERIODS.map((p) => (\n <button\n key={p}\n onClick={() => onChange(p)}\n className={`px-2 py-0.5 text-2xs font-mono rounded transition-colors ${\n period === p\n ? 'bg-accent/10 text-accent font-semibold'\n : 'text-text-quaternary hover:text-text-secondary'\n }`}\n >\n {p}\n </button>\n ))}\n </div>\n );\n}\n\nfunction RoleView({ role, globalPeriod, onClose }: { role: RoleDetail; globalPeriod: string; onClose: () => void }) {\n // Open on the chart's selected window so the panel's numbers agree with the\n // chart beside it; the local selector still lets the viewer drill around.\n const [period, setPeriod] = useState<Period>(isPeriod(globalPeriod) ? globalPeriod : '24h');\n const { data } = useStationMetrics(period);\n const metric = data?.stations.find((s) => s.role === role.role);\n const slaMinutes = role.sla_minutes ?? undefined;\n const targetPerHour = role.target_per_hour ?? undefined;\n const workerCount = role.worker_count ?? undefined;\n\n return (\n <>\n {/* Header */}\n <div className=\"flex items-start justify-between mb-4\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-baseline gap-1.5 flex-wrap\">\n <span className=\"text-sm font-bold text-text-primary\">{displayRoleTitle(role)}</span>\n <span className=\"text-2xs font-mono text-text-secondary\">{role.role}</span>\n </div>\n {role.description && (\n <p className=\"text-2xs text-text-tertiary mt-1 line-clamp-2 leading-relaxed\">\n {role.description}\n </p>\n )}\n </div>\n <button\n onClick={onClose}\n className=\"text-text-quaternary hover:text-text-secondary transition-colors mt-0.5 shrink-0 ml-2\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n <div className=\"flex items-center gap-3 mb-6\">\n <Link\n to={`/admin/roles/${encodeURIComponent(role.role)}`}\n className=\"flex items-center gap-1 text-2xs text-accent hover:underline\"\n >\n <Settings className=\"w-2.5 h-2.5\" />\n Edit in Roles\n </Link>\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}`}\n className=\"flex items-center gap-1 text-2xs text-accent hover:underline\"\n >\n <List className=\"w-2.5 h-2.5\" />\n View full queue\n </Link>\n </div>\n\n <PeriodSelector period={period} onChange={setPeriod} />\n\n {/* Capacity settings */}\n {(targetPerHour || slaMinutes || workerCount) && (\n <div className=\"flex items-center gap-6 mb-6 text-2xs border-b border-surface-border/30 pb-5\">\n {targetPerHour && (\n <div>\n <div className=\"font-mono font-semibold text-text-primary text-sm\">{targetPerHour}/h</div>\n <div className=\"text-text-quaternary uppercase tracking-wider text-[8.5px] mt-0.5\">target</div>\n </div>\n )}\n {slaMinutes && (\n <div>\n <div className=\"font-mono font-semibold text-text-primary text-sm\">{slaMinutes}m</div>\n <div className=\"text-text-quaternary uppercase tracking-wider text-[8.5px] mt-0.5\">SLA</div>\n </div>\n )}\n {workerCount && (\n <div>\n <div className=\"font-mono font-semibold text-text-primary text-sm\">{workerCount}</div>\n <div className=\"text-text-quaternary uppercase tracking-wider text-[8.5px] mt-0.5\">workers</div>\n </div>\n )}\n </div>\n )}\n\n {/* Two-column wait / work grid */}\n <div className=\"grid grid-cols-2 gap-x-4 mb-2\">\n <div>\n <p className=\"text-2xs text-text-quaternary uppercase tracking-wider mb-2\">Wait (queue)</p>\n <MetricRow label=\"P99\" value={fmt(metric?.wait.p99 ?? null)} />\n <MetricRow label=\"avg\" value={fmt(metric?.wait.avg ?? null)} />\n </div>\n <div>\n <p className=\"text-2xs text-text-quaternary uppercase tracking-wider mb-2\">Work (proc.)</p>\n <MetricRow label=\"P99\" value={fmt(metric?.work.p99 ?? null)} />\n <MetricRow label=\"avg\" value={fmt(metric?.work.avg ?? null)} />\n </div>\n </div>\n\n {/* SLA + priority */}\n <div className=\"border-t border-surface-border/40 pt-4 mt-5 space-y-2.5\">\n {slaMinutes && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-2xs text-text-tertiary\">SLA target</span>\n <span className=\"text-xs font-mono text-text-secondary\">{slaMinutes}m</span>\n </div>\n )}\n {metric && metric.priority_count > 0 && (\n <Link\n to={jeopardyQueueLink(role)}\n className=\"flex items-center justify-between group\"\n >\n <span className=\"text-2xs\" style={{ color: PRIORITY_TEXT_COLOR }}>\n {metric.priority_count} in jeopardy — pull oldest first\n </span>\n <ExternalLink className=\"w-3 h-3 transition-colors\" style={{ color: PRIORITY_TEXT_COLOR }} />\n </Link>\n )}\n </div>\n\n </>\n );\n}\n\nfunction OverviewPanel({\n allMetrics,\n orderedRoles,\n period,\n}: {\n allMetrics: StationMetric[];\n orderedRoles: RoleDetail[];\n period: string;\n}) {\n const totalPending = allMetrics.reduce((s, m) => s + m.pending, 0);\n const totalResolved = allMetrics.reduce((s, m) => s + m.resolved, 0);\n const totalPriority = allMetrics.reduce((s, m) => s + m.priority_count, 0);\n\n const metricByRole = new Map(allMetrics.map((m) => [m.role, m]));\n const stationsAtRisk = allMetrics.filter((m) => m.priority_count > 0).length;\n const stationsWithLoad = allMetrics.filter((m) => m.pending > 0).length;\n\n return (\n <>\n <p className=\"text-2xs text-text-quaternary uppercase tracking-wider mb-3\">\n Pipeline · {period}\n </p>\n\n {/* Health headline */}\n <div className=\"mb-4\">\n {stationsAtRisk > 0 ? (\n <p className=\"text-2xs\" style={{ color: PRIORITY_TEXT_COLOR }}>\n {stationsAtRisk} station{stationsAtRisk > 1 ? 's' : ''} with items in jeopardy\n </p>\n ) : stationsWithLoad > 0 ? (\n <p className=\"text-2xs text-status-warning\">\n {stationsWithLoad} station{stationsWithLoad > 1 ? 's' : ''} with backlog\n </p>\n ) : totalResolved > 0 ? (\n <p className=\"text-2xs text-status-success\">Flowing — queue clear</p>\n ) : (\n <p className=\"text-2xs text-text-quaternary\">Quiet — awaiting work</p>\n )}\n </div>\n\n {/* Key counters */}\n <div className=\"space-y-1.5 mb-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-2xs text-text-quaternary uppercase tracking-wider\">Pending</span>\n <span className={`text-xs font-mono tabular-nums ${totalPending > 0 ? 'text-text-primary font-semibold' : 'text-text-quaternary'}`}>\n {totalPending}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-2xs text-text-quaternary uppercase tracking-wider\">Resolved · {period}</span>\n <span className=\"text-xs font-mono tabular-nums text-text-secondary\">{totalResolved}</span>\n </div>\n {totalPriority > 0 && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-2xs text-text-quaternary uppercase tracking-wider\">Priority</span>\n <span className=\"text-xs font-mono tabular-nums font-semibold\" style={{ color: PRIORITY_TEXT_COLOR }}>\n {totalPriority}\n </span>\n </div>\n )}\n </div>\n\n {/* Divider + column headers */}\n <div className=\"border-t border-surface-border/40 pt-2 mb-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-2xs text-text-quaternary uppercase tracking-wider flex-1\">Station</span>\n <span className=\"text-2xs text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0\">pend</span>\n <span className=\"text-2xs text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0\">clmd</span>\n <span className=\"text-2xs text-text-quaternary uppercase tracking-wider w-8 text-right shrink-0\">res</span>\n </div>\n </div>\n\n {/* Station list in pipeline order */}\n <div className=\"space-y-0.5\">\n {orderedRoles.map((r) => {\n const m = metricByRole.get(r.role);\n const pending = m?.pending ?? 0;\n const claimed = m?.claimed ?? 0;\n const resolved = m?.resolved ?? 0;\n const priorityCount = m?.priority_count ?? 0;\n const label = r.title || r.role;\n const hasAlert = priorityCount > 0;\n const hasLoad = pending > 0;\n\n return (\n <div key={r.role} className=\"flex items-center gap-2 py-0.5\">\n <span\n className={`text-2xs font-mono flex-1 truncate ${\n hasLoad ? 'text-text-primary' : 'text-text-quaternary'\n }`}\n >\n {label}\n {hasAlert && (\n <span className=\"ml-1 text-2xs font-semibold\" style={{ color: PRIORITY_TEXT_COLOR }}>\n {priorityCount} PRIORITY\n </span>\n )}\n </span>\n <span\n className={`text-2xs font-mono tabular-nums w-8 text-right shrink-0 ${\n hasLoad ? 'text-text-primary font-semibold' : 'text-text-quaternary'\n }`}\n >\n {pending > 0 ? pending : '—'}\n </span>\n <span className={`text-2xs font-mono tabular-nums w-8 text-right shrink-0 ${claimed > 0 ? 'text-accent font-semibold' : 'text-text-quaternary'}`}>\n {claimed > 0 ? claimed : '—'}\n </span>\n <span className={`text-2xs font-mono tabular-nums w-8 text-right shrink-0 ${resolved > 0 ? 'text-text-secondary' : 'text-text-quaternary'}`}>\n {resolved > 0 ? resolved : '—'}\n </span>\n </div>\n );\n })}\n </div>\n\n <p className=\"text-2xs text-text-quaternary mt-5\">\n Select a station for queue detail.\n </p>\n </>\n );\n}\n\nexport function StationDetailPanel({\n role,\n allMetrics,\n orderedRoles,\n globalPeriod,\n onClose,\n}: StationDetailPanelProps) {\n return (\n <div className=\"w-[280px] shrink-0 px-7 py-10 flex flex-col overflow-y-auto min-h-0\">\n {role ? (\n <RoleView role={role} globalPeriod={globalPeriod} onClose={onClose} />\n ) : (\n <OverviewPanel allMetrics={allMetrics} orderedRoles={orderedRoles} period={globalPeriod} />\n )}\n </div>\n );\n}\n","import { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport { Link, useNavigate, useSearchParams } from 'react-router-dom';\nimport { GitMerge, RefreshCw, Eye, TriangleAlert, ChevronDown } from 'lucide-react';\nimport { useRoleDetails, useUpdateRole, type RoleDetail } from '../../api/roles';\nimport { useStationMetrics } from '../../api/escalations';\nimport type { StationMetric } from '../../api/escalations';\nimport { useStationMetricsEvents } from '../../hooks/useEventHooks';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport {\n PaceChart,\n ACTIVE_COLOR,\n QUEUED_COLOR,\n RESOLVED_COLOR,\n TARGET_COLOR,\n PRIORITY_TEXT_COLOR,\n withAlpha,\n type ChartStation,\n} from './PaceChart';\nimport { StationDetailPanel } from './StationDetailPanel';\nimport { jeopardyQueueLink } from './priority-link';\nimport { displayRoleTitle } from '../../lib/role-display';\n\n// Column band tints — same hues as the chart bands (~8% alpha).\n// Semantic palette: pending=sky, claimed=orange, resolved=green, target=slate, sla=amber.\nconst SLA_COLOR = TARGET_COLOR;\nconst TARGET_BAND = withAlpha(TARGET_COLOR, 0.09);\nconst SLA_BAND = withAlpha(TARGET_COLOR, 0.09);\nconst PENDING_BAND = withAlpha(QUEUED_COLOR, 0.08);\nconst ACTIVE_BAND = withAlpha(ACTIVE_COLOR, 0.08);\nconst RESOLVED_BAND = withAlpha(RESOLVED_COLOR, 0.08);\n\n// Station table grid. The 5 colored columns are grouped into a single auto\n// cell rendered as a flex row with no internal gap so they touch each other.\nconst STATION_GRID_COLS = 'minmax(120px, 1.1fr) minmax(100px, 0.9fr) auto 72px 72px 104px 36px';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nconst PERIODS = ['15m', '1h', '24h', '7d', '30d'] as const;\ntype Period = (typeof PERIODS)[number];\n\n// Window length in hours — used to express the target as a count for the\n// selected window (target_per_hour × hours), e.g. 22/h over 15m ≈ 5 expected.\nconst PERIOD_HOURS: Record<Period, number> = {\n '15m': 0.25,\n '1h': 1,\n '24h': 24,\n '7d': 168,\n '30d': 720,\n};\n\ninterface OrderedStation {\n role: RoleDetail;\n depth: number;\n}\n\n/**\n * One sequence of stations, named by its origin role. Execution is a graph;\n * each fragment is the human-readable line the user composed via parent_role.\n * Cross-fragment edges live in upstream_roles and render as a merge affordance\n * on the chart, never as a bend in the line.\n */\ninterface SequenceFragment {\n origin: RoleDetail;\n stations: OrderedStation[];\n}\n\n// ── Fragment builder — BFS per parent_role root, tracking actual depth ────────\n\nexport function buildFragments(roles: RoleDetail[]): SequenceFragment[] {\n const opsRoles = roles.filter((r) => r.ops_visible);\n const roleMap = new Map(opsRoles.map((r) => [r.role, r]));\n const visited = new Set<string>();\n\n // Roots: no parent, or parent not in ops set — each roots its own fragment.\n const roots = opsRoles.filter((r) => !r.parent_role || !roleMap.has(r.parent_role));\n\n const fragments: SequenceFragment[] = roots.map((root) => {\n const stations: OrderedStation[] = [];\n const queue: OrderedStation[] = [{ role: root, depth: 0 }];\n while (queue.length > 0) {\n const item = queue.shift()!;\n if (visited.has(item.role.role)) continue;\n visited.add(item.role.role);\n stations.push(item);\n opsRoles\n .filter((c) => c.parent_role === item.role.role && !visited.has(c.role))\n .forEach((c) => queue.push({ role: c, depth: item.depth + 1 }));\n }\n return { origin: root, stations };\n });\n\n // Unreachable (cycles / dangling) — each stands alone rather than vanishing.\n opsRoles\n .filter((r) => !visited.has(r.role))\n .forEach((r) => fragments.push({ origin: r, stations: [{ role: r, depth: 0 }] }));\n\n // Longest line first — the primary sequence leads; side-quests follow.\n return fragments.sort(\n (a, b) => b.stations.length - a.stations.length || a.origin.role.localeCompare(b.origin.role),\n );\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction fmtMin(v: number | null): string {\n if (v == null) return '—';\n if (v < 1) {\n const s = Math.round(v * 60);\n return s <= 0 ? '< 1s' : `${s}s`;\n }\n if (v < 60) return `${v.toFixed(0)}m`;\n return `${(v / 60).toFixed(1)}h`;\n}\n\nfunction loadBar(pending: number, target: number | null) {\n // No target, or nothing pending — there is no live load to trend. Show the\n // empty state rather than inventing a rate from historical throughput.\n if (!target || pending === 0) return { pct: null, color: 'bg-surface-border' };\n\n const ratio = pending / target;\n const pct = Math.round(ratio * 100);\n // Amber: backlog. Orange: some work but well under pace. Green: healthy.\n const color = ratio > 1.0 ? 'bg-status-warning' : ratio < 0.2 ? 'bg-status-draft' : 'bg-status-success';\n return { pct, color };\n}\n\n// ── Editable numeric cell ─────────────────────────────────────────────────────\n\nfunction EditableNumber({ value, onSave }: { value: number | null; onSave: (n: number | null) => void }) {\n const [local, setLocal] = useState(value != null ? String(value) : '');\n const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const commit = (val: string) => {\n const n = parseInt(val, 10);\n onSave(!val.trim() || isNaN(n) || n < 0 ? null : n);\n };\n\n return (\n <input\n type=\"number\"\n min={0}\n step={1}\n value={local}\n onChange={(e) => {\n const val = e.target.value;\n setLocal(val);\n clearTimeout(timer.current);\n timer.current = setTimeout(() => commit(val), 400);\n }}\n onBlur={(e) => { clearTimeout(timer.current); commit(e.target.value); }}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n className=\"w-full bg-transparent text-xs font-mono tabular-nums text-right focus:outline-none\"\n />\n );\n}\n\n// ── Station table row ─────────────────────────────────────────────────────────\n\nfunction StationRow({\n role,\n metric,\n selected,\n onClick,\n}: {\n role: RoleDetail;\n metric: StationMetric | undefined;\n selected: boolean;\n onClick: () => void;\n}) {\n const updateRole = useUpdateRole();\n const pending = metric?.pending ?? 0;\n const claimed = metric?.claimed ?? 0;\n const resolved = metric?.resolved ?? 0;\n const priorityCount = metric?.priority_count ?? 0;\n const target = role.target_per_hour ?? null;\n const { pct, color } = loadBar(pending, target);\n const barWidth = pct != null ? Math.min(100, pct) : 0;\n\n const saveTarget = (n: number | null) => updateRole.mutate({ role: role.role, target_per_hour: n });\n const saveSla = (n: number | null) => updateRole.mutate({ role: role.role, sla_minutes: n });\n\n return (\n <>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(e) => { if (e.key === 'Enter') onClick(); }}\n className={`grid items-center gap-4 pr-3 cursor-pointer transition-colors ${\n selected ? 'border-l-2 !border-l-accent pl-2.5' : 'pl-3'\n }`}\n style={{ gridTemplateColumns: STATION_GRID_COLS }}\n >\n {/* Name — user-set title, or derived from the role id */}\n <div className=\"flex items-center gap-1.5 min-w-0 py-1.5\">\n <span className=\"font-bold text-text-primary truncate text-xs\">\n {displayRoleTitle(role)}\n </span>\n {(role.upstream_roles?.length ?? 0) > 0 && (\n <span title={`Fed by ${role.upstream_roles.join(', ')}`} className=\"shrink-0 leading-none\">\n <GitMerge className=\"w-3 h-3 text-text-quaternary\" />\n </span>\n )}\n </div>\n\n {/* Role id */}\n <span className=\"font-mono text-2xs text-text-tertiary truncate py-1.5\">\n {role.role}\n </span>\n\n {/* ── 5 colored columns in one touching flex group ── */}\n <div className=\"self-stretch flex items-stretch\">\n {/* Target/h — editable, slate band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-1.5\" style={{ backgroundColor: TARGET_BAND }}>\n <EditableNumber value={role.target_per_hour ?? null} onSave={saveTarget} />\n </div>\n {/* SLA/m — editable, amber band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-1.5\" style={{ backgroundColor: SLA_BAND }}>\n <EditableNumber value={role.sla_minutes ?? null} onSave={saveSla} />\n </div>\n {/* Pending — sky band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-3\" style={{ backgroundColor: PENDING_BAND }}>\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}&status=available`}\n className={`text-xs font-mono tabular-nums hover:underline ${\n pending > 0 ? 'text-text-primary font-semibold' : 'text-text-quaternary'\n }`}\n onClick={(e) => e.stopPropagation()}\n >\n {pending}\n </Link>\n </div>\n {/* Claimed — orange band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-3\" style={{ backgroundColor: ACTIVE_BAND }}>\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}&status=claimed`}\n className={`text-xs font-mono tabular-nums hover:underline ${\n claimed > 0 ? 'font-semibold' : 'text-text-quaternary'\n }`}\n style={claimed > 0 ? { color: ACTIVE_COLOR } : undefined}\n onClick={(e) => e.stopPropagation()}\n >\n {claimed}\n </Link>\n </div>\n {/* Resolved — green band */}\n <div className=\"w-16 shrink-0 flex items-center justify-end px-3\" style={{ backgroundColor: RESOLVED_BAND }}>\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}&status=resolved`}\n className={`text-xs font-mono tabular-nums hover:underline ${\n resolved > 0 ? 'text-text-secondary' : 'text-text-quaternary'\n }`}\n style={resolved > 0 ? { color: RESOLVED_COLOR } : undefined}\n onClick={(e) => e.stopPropagation()}\n >\n {resolved}\n </Link>\n </div>\n </div>\n\n {/* P99 wait */}\n <span className=\"text-xs font-mono tabular-nums text-right py-1.5 text-text-secondary\">\n {fmtMin(metric?.wait.p99 ?? null)}\n </span>\n\n {/* P99 work */}\n <span className=\"text-xs font-mono tabular-nums text-right py-1.5 text-text-secondary\">\n {fmtMin(metric?.work.p99 ?? null)}\n </span>\n\n {/* Load mini-bar */}\n <div className=\"flex items-center gap-2 py-1.5\">\n <div className=\"w-12 h-1.5 bg-surface-sunken rounded-full overflow-hidden shrink-0\">\n <div className={`h-full rounded-full ${color}`} style={{ width: `${barWidth}%` }} />\n </div>\n <span\n className={`text-2xs font-mono tabular-nums ${\n pct != null && pct > 100\n ? 'text-status-warning font-semibold'\n : 'text-text-quaternary'\n }`}\n >\n {pct != null ? `${pct}%` : '—'}\n </span>\n </div>\n\n {/* Actions — jeopardy first (the hard-limit alarm, hover names the\n count, click opens the exact counted set oldest-first), then the\n full-queue view. */}\n <div className=\"flex items-center justify-center gap-2 py-1.5\">\n {priorityCount > 0 && (\n <Link\n to={jeopardyQueueLink(role)}\n className=\"text-status-error hover:opacity-70 transition-opacity\"\n title={`${priorityCount} item${priorityCount === 1 ? '' : 's'} in jeopardy — pull oldest first`}\n onClick={(e) => e.stopPropagation()}\n >\n <TriangleAlert className=\"w-3.5 h-3.5\" strokeWidth={2} />\n </Link>\n )}\n <Link\n to={`/escalations/available?role=${encodeURIComponent(role.role)}&status=all`}\n className=\"text-text-quaternary hover:text-accent transition-colors\"\n title=\"View all items in queue\"\n onClick={(e) => e.stopPropagation()}\n >\n <Eye className=\"w-3.5 h-3.5\" />\n </Link>\n </div>\n </div>\n </>\n );\n}\n\n// ── Sequence menu ─────────────────────────────────────────────────────────────\n\ninterface SequenceAggregate {\n stations: number;\n pending: number;\n jeopardy: number;\n}\n\n/** Red jeopardy count, capped at 9+ — the same shorthand as the queue pills. */\nfunction JeopardyCount({ n }: { n: number }) {\n if (n <= 0) return null;\n return (\n <span\n className=\"inline-flex items-center gap-0.5 font-semibold tabular-nums\"\n style={{ color: PRIORITY_TEXT_COLOR }}\n title={`${n} in jeopardy`}\n >\n <TriangleAlert className=\"w-3 h-3\" strokeWidth={2.25} />\n {n > 9 ? '9+' : n}\n </span>\n );\n}\n\n/**\n * The segment selector for the 30k-foot view — compact at any segment count.\n * Collapsed, it names the ACTIVE sequence large with its aggregate story\n * (stations · pending · jeopardy) and a caret; expanded, it lists every\n * sequence with the same breakdown so trouble in an unselected segment is\n * visible from here and one click away. Metrics span every visible role, so\n * the numbers are live for all segments, not just the chosen one.\n */\nfunction SequenceMenu({ fragments, aggregates, activeOrigin, onSelect }: {\n fragments: SequenceFragment[];\n aggregates: Map<string, SequenceAggregate>;\n activeOrigin: string | null;\n onSelect: (origin: string) => void;\n}) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); };\n document.addEventListener('mousedown', onClick);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onClick);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const active = fragments.find((f) => f.origin.role === activeOrigin) ?? fragments[0];\n if (!active) return null;\n const agg = aggregates.get(active.origin.role);\n\n return (\n <div ref={ref} className=\"relative px-4 pt-2\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"group flex items-baseline gap-2.5\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n >\n <span className=\"text-sm font-medium text-text-primary group-hover:text-accent transition-colors\">\n {displayRoleTitle(active.origin)}\n </span>\n <span className=\"text-2xs font-mono text-text-quaternary tabular-nums\">\n {agg?.stations ?? active.stations.length} station{(agg?.stations ?? active.stations.length) === 1 ? '' : 's'} · {agg?.pending ?? 0} pending\n </span>\n <JeopardyCount n={agg?.jeopardy ?? 0} />\n <ChevronDown\n className={`w-3.5 h-3.5 self-center shrink-0 text-text-tertiary group-hover:text-accent transition-transform ${open ? 'rotate-180' : ''}`}\n strokeWidth={1.5}\n />\n </button>\n\n {open && (\n <div\n role=\"listbox\"\n className=\"absolute z-[100] top-full left-4 mt-1.5 min-w-[20rem] max-h-80 overflow-y-auto bg-surface-raised border border-surface-border rounded-md shadow-lg py-1\"\n >\n {fragments.map((f) => {\n const a = aggregates.get(f.origin.role);\n const isActive = f.origin.role === active.origin.role;\n return (\n <button\n key={f.origin.role}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n onClick={() => { onSelect(f.origin.role); setOpen(false); }}\n className={`w-full text-left px-3 py-1.5 flex items-baseline gap-2.5 transition-colors ${\n isActive ? 'text-accent bg-accent/5' : 'text-text-primary hover:bg-surface-hover'\n }`}\n >\n <span className=\"text-xs font-medium truncate\">{displayRoleTitle(f.origin)}</span>\n <span className=\"ml-auto text-2xs font-mono text-text-quaternary tabular-nums shrink-0\">\n {a?.stations ?? f.stations.length} st · {a?.pending ?? 0} pending\n </span>\n {/* Fixed-width, left-aligned jeopardy column: every ⚠ starts at\n the same x, so the icons stack vertically whether the count\n is 1 or 9+. */}\n <span className=\"w-12 shrink-0 text-left text-2xs\">\n <JeopardyCount n={a?.jeopardy ?? 0} />\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n// ── Table header ──────────────────────────────────────────────────────────────\n\nfunction TableHead() {\n const coloredCols = [\n { label: 'TARGET/H', band: TARGET_BAND, hue: TARGET_COLOR, w: 'w-16' },\n { label: 'SLA/M', band: SLA_BAND, hue: SLA_COLOR, w: 'w-16' },\n { label: 'PENDING', band: PENDING_BAND, hue: QUEUED_COLOR, w: 'w-16', px: 'px-3' },\n { label: 'CLAIMED', band: ACTIVE_BAND, hue: ACTIVE_COLOR, w: 'w-16', px: 'px-3' },\n { label: 'RESOLVED', band: RESOLVED_BAND, hue: RESOLVED_COLOR, w: 'w-16', px: 'px-3' },\n ];\n return (\n <div\n className=\"grid items-center gap-4 px-3 border-b border-surface-border mb-0.5\"\n style={{ gridTemplateColumns: STATION_GRID_COLS }}\n >\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5\">NAME</span>\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5\">ROLE</span>\n\n {/* Touching colored column group */}\n <div className=\"self-stretch flex items-stretch\">\n {coloredCols.map((col) => (\n <div\n key={col.label}\n className={`${col.w} shrink-0 flex items-center justify-end ${'px' in col ? col.px : 'px-1.5'}`}\n style={{ backgroundColor: col.band }}\n >\n <span className=\"text-2xs font-semibold uppercase tracking-wider\" style={{ color: col.hue }}>\n {col.label}\n </span>\n </div>\n ))}\n </div>\n\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5 text-right\">P99 WAIT</span>\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5 text-right\">P99 WORK</span>\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5\">TREND</span>\n <span className=\"text-2xs font-semibold uppercase tracking-wider text-text-quaternary py-1.5 text-center\">ACTIONS</span>\n </div>\n );\n}\n\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function OperationsPage() {\n // 1h default: long enough to show a whole simulation shift's shape,\n // short enough that stale history doesn't drown the current run.\n const [period, setPeriod] = useState<Period>('1h');\n const [selectedRole, setSelectedRole] = useState<string | null>(null);\n const [refreshing, setRefreshing] = useState(false);\n\n // Push-driven refresh: every escalation event invalidates ['stationMetrics']\n // through the central event system (debounced, transport-agnostic). The\n // header's refresh button covers user-initiated reloads.\n useStationMetricsEvents();\n\n const { data: roleData, isLoading: rolesLoading, refetch: refetchRoles } = useRoleDetails();\n const {\n data: metricsData,\n isLoading: metricsLoading,\n refetch: refetchMetrics,\n } = useStationMetrics(period);\n\n const roles = roleData?.roles ?? [];\n const metrics = metricsData?.stations ?? [];\n\n // Per-sequence aggregates for the segment menu — computed over ALL visible\n // roles, so unselected segments report their live pending/jeopardy too.\n const fragmentAggregates = useMemo(() => {\n const metricByRole = new Map(metrics.map((m) => [m.role, m]));\n const out = new Map<string, SequenceAggregate>();\n for (const f of buildFragments(roleData?.roles ?? [])) {\n let pending = 0, jeopardy = 0;\n for (const s of f.stations) {\n const m = metricByRole.get(s.role.role);\n pending += m?.pending ?? 0;\n jeopardy += m?.priority_count ?? 0;\n }\n out.set(f.origin.role, { stations: f.stations.length, pending, jeopardy });\n }\n return out;\n }, [metrics, roleData]);\n\n // Sequence fragments, one per parent_role root. The active one is\n // DEEP-LINKED (?fragment=<origin role>) and each switch is a history entry,\n // so a shared link opens the same sequence and back/forward walks them.\n const fragments = useMemo((): SequenceFragment[] => buildFragments(roles), [roles]);\n const [searchParams, setSearchParams] = useSearchParams();\n const fragmentParam = searchParams.get('fragment');\n const activeFragment =\n fragments.find((f) => f.origin.role === fragmentParam) ?? fragments[0] ?? null;\n const selectFragment = useCallback(\n (origin: string) => {\n setSelectedRole(null);\n setSearchParams((prev) => {\n const p = new URLSearchParams(prev);\n p.set('fragment', origin);\n return p;\n });\n },\n [setSearchParams],\n );\n\n const ordered = activeFragment?.stations ?? [];\n const fragmentRoleSet = useMemo(\n () => new Set(ordered.map(({ role }) => role.role)),\n [ordered],\n );\n const fragmentMetrics = useMemo(\n () => metrics.filter((m) => fragmentRoleSet.has(m.role)),\n [metrics, fragmentRoleSet],\n );\n\n const chartStations = useMemo(\n (): ChartStation[] =>\n ordered.map(({ role: r }) => ({\n role: r.role,\n title: r.title,\n parent_role: r.parent_role,\n target_per_hour: r.target_per_hour ?? null,\n upstream_roles: r.upstream_roles ?? [],\n metric: metrics.find((m) => m.role === r.role),\n })),\n [ordered, metrics],\n );\n\n // Jump to the sequence that feeds this station — the merge glyph's click.\n const handleUpstreamSelect = useCallback(\n (upstreamRole: string) => {\n const target = fragments.find((f) =>\n f.stations.some(({ role }) => role.role === upstreamRole),\n );\n if (target) selectFragment(target.origin.role);\n },\n [fragments, selectFragment],\n );\n\n const navigate = useNavigate();\n\n const selectedRoleDetail =\n ordered.find(({ role }) => role.role === selectedRole)?.role ?? null;\n\n const isLoading = rolesLoading || metricsLoading;\n\n const handleRefresh = async () => {\n setRefreshing(true);\n await Promise.all([refetchRoles(), refetchMetrics()]);\n setRefreshing(false);\n };\n\n const handleSelect = (role: string) =>\n setSelectedRole((prev) => (prev === role ? null : role));\n\n const periodSelector = (\n <div className=\"flex items-center gap-0.5\">\n {PERIODS.map((p) => (\n <button\n key={p}\n onClick={() => setPeriod(p)}\n className={`px-2.5 py-1 text-2xs font-mono rounded transition-colors ${\n period === p\n ? 'bg-accent/10 text-accent font-semibold'\n : 'text-text-quaternary hover:text-text-secondary'\n }`}\n >\n {p}\n </button>\n ))}\n </div>\n );\n\n return (\n <div className=\"flex flex-col flex-1 min-h-0\">\n <PageHeader\n title=\"Pace Board\"\n docsHash=\"#docs:dashboard.md:pace-board\"\n center={periodSelector}\n actions={\n <button\n onClick={handleRefresh}\n disabled={refreshing}\n className=\"text-text-quaternary hover:text-text-secondary transition-colors disabled:opacity-40\"\n >\n <RefreshCw className={`w-3.5 h-3.5 ${refreshing ? 'animate-spin' : ''}`} />\n </button>\n }\n />\n\n {isLoading ? (\n <div className=\"animate-pulse space-y-6 mt-4\">\n <div className=\"h-8 bg-surface-sunken rounded w-64\" />\n <div className=\"h-64 bg-surface-sunken rounded w-full\" />\n <div className=\"space-y-3\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"h-8 bg-surface-sunken rounded w-full\" />\n ))}\n </div>\n </div>\n ) : fragments.length === 0 ? (\n <div className=\"mt-8\">\n <p className=\"text-sm text-text-secondary mb-2\">Stations appear here once roles are marked visible in Operations.</p>\n <p className=\"text-xs text-text-tertiary\">\n Go to{' '}\n <Link to=\"/admin/roles\" className=\"text-accent hover:underline\">\n Roles\n </Link>{' '}\n and enable <strong>Visible in Operations</strong> on roles that represent pipeline\n stations.\n </p>\n </div>\n ) : (\n /* Console layout: fixed header (above) → chart row (min 40vh) → table row (max 30vh) */\n <div className=\"flex flex-col flex-1 min-h-0\">\n\n {/* Sequence menu — the active segment named large with its aggregate\n story; the caret opens the full segment list. Compact at any\n segment count. Only rendered when there is more than one story\n to tell. */}\n {fragments.length > 1 && (\n <SequenceMenu\n fragments={fragments}\n aggregates={fragmentAggregates}\n activeOrigin={activeFragment?.origin.role ?? null}\n onSelect={selectFragment}\n />\n )}\n\n {/* Middle row: flexible, never below 40vh — SVG fills left, sidebar fixed-width right */}\n <div className=\"flex-1 min-h-[40vh] flex items-stretch overflow-hidden\">\n {/* SVG chart — scales to fill available space */}\n <div className=\"flex-1 min-w-0 min-h-0 flex flex-col justify-center overflow-hidden p-4\">\n <PaceChart\n stations={chartStations}\n selectedRole={selectedRole}\n onSelect={handleSelect}\n onUpstreamSelect={handleUpstreamSelect}\n onCmdClick={(role) => navigate(`/escalations/available?role=${encodeURIComponent(role)}`)}\n periodHours={PERIOD_HOURS[period]}\n />\n </div>\n {/* Vertical divider */}\n <div className=\"w-px bg-surface-border shrink-0 self-stretch\" />\n {/* Right sidebar — fixed width, scrolls its own content */}\n <StationDetailPanel\n role={selectedRoleDetail}\n allMetrics={fragmentMetrics}\n orderedRoles={ordered.map((o) => o.role)}\n globalPeriod={period}\n onClose={() => setSelectedRole(null)}\n />\n </div>\n\n {/* Bottom row: sized to its rows up to 30vh — header sticky, rows scroll */}\n <div className=\"max-h-[30vh] flex-none flex flex-col border-t border-surface-border overflow-hidden\">\n <TableHead />\n <div className=\"flex-1 min-h-0 overflow-y-auto divide-y divide-surface-border/30\">\n {ordered.map(({ role }) => (\n <StationRow\n key={role.role}\n role={role}\n metric={metrics.find((m) => m.role === role.role)}\n selected={selectedRole === role.role}\n onClick={() => handleSelect(role.role)}\n />\n ))}\n </div>\n </div>\n\n </div>\n )}\n </div>\n );\n}\n"],"names":["W","H","ML","MR","MT","MB","chartW","chartH","bottom","right","EASE","SOLO_HALF","soloSegment","p","catmullPath","pts","segs","i","p0","p1","p2","p3","cp1x","cp1y","cp2x","cp2y","bandPath","upper","lower","forward","rev","back","backSegs","compact","n","last","a","ACTIVE_COLOR","QUEUED_COLOR","RESOLVED_COLOR","TARGET_COLOR","PRIORITY_TEXT_COLOR","withAlpha","color","alpha","MIN_GAP","spreadLabels","labels","maxY","sorted","b","prev","placed","l","labelY","overflow","PaceChart","stations","selectedRole","onSelect","onUpstreamSelect","onCmdClick","periodHours","hoveredIdx","setHoveredIdx","useState","xOf","xMap","rows","target","expected","_a","_b","_c","_d","hasTargets","r","maxVal","yScale","v","withTarget","targetPts","actualPts","activePts","pendingPts","targetLinePath","actualSplinePath","activeSplinePath","pendingSplinePath","lastActual","lastTarget","lastActive","lastPending","areaPath","hasQueue","workedBandPath","queuedBandPath","showActiveLabel","showQueuedLabel","endLabels","px","cx","jsx","tp","ap","ar","hasWaiting","pendingLabelY","row","s","x","cy","isSelected","isHovered","tooltip","tipW","tipX","tipY","jsxs","e","jeopardyQueueLink","role","field","orderBy","PERIODS","isPeriod","fmt","min","MetricRow","label","value","PeriodSelector","period","onChange","RoleView","globalPeriod","onClose","setPeriod","data","useStationMetrics","metric","slaMinutes","targetPerHour","workerCount","Fragment","displayRoleTitle","X","Link","Settings","List","ExternalLink","OverviewPanel","allMetrics","orderedRoles","totalPending","m","totalResolved","totalPriority","metricByRole","stationsAtRisk","stationsWithLoad","pending","claimed","resolved","priorityCount","hasAlert","hasLoad","StationDetailPanel","SLA_COLOR","TARGET_BAND","SLA_BAND","PENDING_BAND","ACTIVE_BAND","RESOLVED_BAND","STATION_GRID_COLS","PERIOD_HOURS","buildFragments","roles","opsRoles","roleMap","visited","fragments","root","queue","item","c","fmtMin","loadBar","ratio","pct","EditableNumber","onSave","local","setLocal","timer","useRef","commit","val","StationRow","selected","onClick","updateRole","useUpdateRole","barWidth","saveTarget","saveSla","GitMerge","TriangleAlert","Eye","JeopardyCount","SequenceMenu","aggregates","activeOrigin","open","setOpen","ref","useEffect","onKey","active","f","agg","ChevronDown","isActive","TableHead","coloredCols","col","OperationsPage","setSelectedRole","refreshing","setRefreshing","useStationMetricsEvents","roleData","rolesLoading","refetchRoles","useRoleDetails","metricsData","metricsLoading","refetchMetrics","metrics","fragmentAggregates","useMemo","out","jeopardy","searchParams","setSearchParams","useSearchParams","fragmentParam","activeFragment","selectFragment","useCallback","origin","ordered","fragmentRoleSet","fragmentMetrics","chartStations","handleUpstreamSelect","upstreamRole","navigate","useNavigate","selectedRoleDetail","isLoading","handleRefresh","handleSelect","periodSelector","PageHeader","RefreshCw","o"],"mappings":"mbA6BA,MAAMA,GAAI,IACJC,GAAI,IACJC,EAAK,GACLC,GAAK,GACLC,GAAK,GACLC,GAAK,GAELC,GAASN,GAAIE,EAAKC,GAClBI,GAASN,GAAIG,GAAKC,GAClBG,EAASJ,GAAKG,GACdE,GAAQP,EAAKI,GAGbI,EAAO,oCAQPC,GAAY,EAClB,SAASC,GAAYC,EAAqC,CACxD,MAAO,MAAMA,EAAE,EAAIF,IAAW,QAAQ,CAAC,CAAC,IAAIE,EAAE,EAAE,QAAQ,CAAC,CAAC,OAAOA,EAAE,EAAIF,IAAW,QAAQ,CAAC,CAAC,IAAIE,EAAE,EAAE,QAAQ,CAAC,CAAC,EAChH,CAGA,SAASC,EAAYC,EAAyC,CAC5D,GAAIA,EAAI,SAAW,EAAG,MAAO,GAC7B,GAAIA,EAAI,SAAW,SAAUH,GAAYG,EAAI,CAAC,CAAC,EAC/C,MAAMC,EAAiB,CAAA,EACvB,QAASC,EAAI,EAAGA,EAAIF,EAAI,OAAS,EAAGE,IAAK,CACvC,MAAMC,EAAKH,EAAI,KAAK,IAAI,EAAGE,EAAI,CAAC,CAAC,EAC3BE,EAAKJ,EAAIE,CAAC,EACVG,EAAKL,EAAIE,EAAI,CAAC,EACdI,EAAKN,EAAI,KAAK,IAAIA,EAAI,OAAS,EAAGE,EAAI,CAAC,CAAC,EACxCK,GAAQH,EAAG,GAAKC,EAAG,EAAIF,EAAG,GAAK,GAAG,QAAQ,CAAC,EAC3CK,GAAQJ,EAAG,GAAKC,EAAG,EAAIF,EAAG,GAAK,GAAG,QAAQ,CAAC,EAC3CM,GAAQJ,EAAG,GAAKC,EAAG,EAAIF,EAAG,GAAK,GAAG,QAAQ,CAAC,EAC3CM,GAAQL,EAAG,GAAKC,EAAG,EAAIF,EAAG,GAAK,GAAG,QAAQ,CAAC,EAC7CF,IAAM,GAAGD,EAAK,KAAK,KAAKG,EAAG,EAAE,QAAQ,CAAC,CAAC,IAAIA,EAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,EAChEH,EAAK,KAAK,KAAKM,CAAI,IAAIC,CAAI,KAAKC,CAAI,IAAIC,CAAI,KAAKL,EAAG,EAAE,QAAQ,CAAC,CAAC,IAAIA,EAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CACvF,CACA,OAAOJ,EAAK,KAAK,GAAG,CACtB,CAOA,SAASU,GAASC,EAAmCC,EAA2C,CAC9F,GAAID,EAAM,OAAS,GAAKC,EAAM,OAAS,EAAG,MAAO,GACjD,MAAMC,EAAUf,EAAYa,CAAK,EAC3BG,EAAM,CAAC,GAAGF,CAAK,EAAE,QAAA,EACjBG,EAAOjB,EAAYgB,CAAG,EAEtBE,EAAWD,EAAK,MAAMA,EAAK,QAAQ,GAAG,CAAC,EAC7C,MAAO,GAAGF,CAAO,MAAMC,EAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAIA,EAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAIE,CAAQ,IAC/E,CAEA,SAASC,GAAQC,EAAmB,CAClC,OAAOA,GAAK,IAAQ,GAAG,KAAK,MAAMA,EAAI,GAAI,CAAC,IAAMA,GAAK,IAAO,IAAIA,EAAI,KAAM,QAAQ,CAAC,CAAC,IAAM,OAAOA,CAAC,CACrG,CAEA,SAASC,GAAQC,EAAuB,CACtC,OAAOA,EAAE,OAAS,EAAIA,EAAEA,EAAE,OAAS,CAAC,EAAI,MAC1C,CAQO,MAAMC,EAAe,wCACfC,EAAe,uCACfC,EAAiB,wCACjBC,EAAe,iCAOfC,EAAsB,8BAG5B,SAASC,EAAUC,EAAeC,EAAuB,CAC9D,OAAOD,EAAM,QAAQ,MAAO,MAAMC,CAAK,GAAG,CAC5C,CAIA,MAAMC,GAAU,GAChB,SAASC,GAAsCC,EAAaC,EAA0C,CACpG,MAAMC,EAAS,CAAC,GAAGF,CAAM,EAAE,KAAK,CAACX,EAAGc,IAAMd,EAAE,EAAIc,EAAE,CAAC,EACnD,IAAIC,EAAO,KACX,MAAMC,EAASH,EAAO,IAAKI,GAAM,CAC/B,MAAMC,EAAS,KAAK,IAAID,EAAE,EAAI,EAAGF,EAAON,EAAO,EAC/C,OAAAM,EAAOG,EACA,CAAE,GAAGD,EAAG,OAAAC,CAAA,CACjB,CAAC,EAIKC,EAAWH,EAAO,OAAS,EAAIA,EAAOA,EAAO,OAAS,CAAC,EAAE,OAASJ,EAAO,EAC/E,GAAIO,EAAW,EACb,UAAWF,KAAKD,EAAQC,EAAE,QAAUE,EAEtC,OAAOH,CACT,CAIO,SAASI,GAAU,CAAE,SAAAC,EAAU,aAAAC,EAAc,SAAAC,EAAU,iBAAAC,EAAkB,WAAAC,EAAY,YAAAC,GAA+B,CACzH,KAAM,CAACC,EAAYC,CAAa,EAAIC,EAAAA,SAAwB,IAAI,EAE1D/B,EAAIuB,EAAS,OACnB,GAAIvB,IAAM,EAAG,OAAO,KAEpB,MAAMgC,EAAOjD,GAAeiB,IAAM,EAAIhC,EAAKI,GAAS,EAAIJ,EAAMe,GAAKiB,EAAI,GAAM5B,GACvE6D,EAAO,IAAI,IAAIV,EAAS,IAAI,CAAC,EAAGxC,IAAM,CAAC,EAAE,KAAMiD,EAAIjD,CAAC,CAAC,CAAC,CAAC,EAMvDmD,EAAOX,EAAS,IAAI,CAAC,EAAGxC,IAAM,aAClC,MAAMoD,EAAS,EAAE,iBAAmB,KAC9BC,EAAWD,GAAU,KAAOA,EAASP,EAAc,KACzD,MAAO,CACL,IAAK7C,EACL,EAAGiD,EAAIjD,CAAC,EACR,SAAAqD,EACA,SAAQC,EAAA,EAAE,SAAF,YAAAA,EAAU,WAAY,EAC9B,SAAQC,EAAA,EAAE,SAAF,YAAAA,EAAU,UAAW,EAC7B,UAASC,EAAA,EAAE,SAAF,YAAAA,EAAU,UAAW,EAC9B,gBAAeC,EAAA,EAAE,SAAF,YAAAA,EAAU,iBAAkB,CAAA,CAE/C,CAAC,EAEKC,EAAaP,EAAK,KAAMQ,GAAMA,EAAE,UAAY,IAAI,EAQhDC,EANU,KAAK,IACnB,EACA,GAAGT,EAAK,IAAKQ,GAAMA,EAAE,UAAY,CAAC,EAClC,GAAGR,EAAK,IAAKQ,GAAMA,EAAE,MAAM,EAC3B,GAAGR,EAAK,IAAKQ,GAAOA,EAAE,UAAY,KAAOA,EAAE,QAAU,CAAE,CAAA,EAEhC,KACnBE,EAAUC,GAAc3E,GAAKG,IAAU,EAAI,KAAK,IAAI,EAAG,KAAK,IAAIwE,EAAGF,CAAM,CAAC,EAAIA,GAE9EG,EAAaZ,EAAK,OAAQQ,GAAMA,EAAE,UAAY,IAAI,EAClDK,EAAYD,EAAW,IAAKJ,IAAO,CAAE,GAAGA,EAAG,EAAGE,EAAOF,EAAE,QAAkB,GAAI,EAC7EM,EAAYF,EAAW,IAAKJ,IAAO,CAAE,GAAGA,EAAG,EAAGE,EAAOF,EAAE,MAAM,GAAI,EACjEO,EAAYH,EAAW,IAAKJ,IAAO,CAAE,GAAGA,EAAG,EAAGE,EAAOF,EAAE,MAAM,GAAI,EACjEQ,EAAaJ,EAAW,IAAKJ,IAAO,CAAE,GAAGA,EAAG,EAAGE,EAAOF,EAAE,OAAO,GAAI,EAEnES,EAAiBvE,EAAYmE,CAAS,EACtCK,EAAmBxE,EAAYoE,CAAS,EACxCK,EAAmBzE,EAAYqE,CAAS,EACxCK,GAAoB1E,EAAYsE,CAAU,EAE1CK,EAAatD,GAAK+C,CAAS,EAC3BQ,GAAavD,GAAK8C,CAAS,EAC3BU,EAAaxD,GAAKgD,CAAS,EAC3BS,GAAczD,GAAKiD,CAAU,EAE7BS,GACJX,EAAU,QAAU,GAAKO,EACrB,GAAGH,CAAgB,MAAMG,EAAW,EAAE,QAAQ,CAAC,CAAC,IAAIjF,CAAM,MAAM0E,EAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAI1E,CAAM,KACnG,GAOAsF,EAAWd,EAAW,KAAMJ,GAAMA,EAAE,QAAU,GAAKA,EAAE,OAAS,CAAC,EAC/DmB,GACJD,GAAYX,EAAU,QAAU,GAAKQ,EACjC,GAAGJ,CAAgB,MAAMI,EAAW,EAAE,QAAQ,CAAC,CAAC,IAAInF,CAAM,MAAM2E,EAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAI3E,CAAM,KACnG,GACAwF,EAAiBF,EAAWpE,GAAS0D,EAAYD,CAAS,EAAI,GAI9Dc,EAAkBjB,EAAW,KAAMJ,GAAMA,EAAE,OAAS,CAAC,EACrDsB,EAAkBlB,EAAW,KAAMJ,GAAMA,EAAE,QAAUA,EAAE,MAAM,EAC7DuB,EAAYrD,GAChB,CACE4C,GAAa,CAAE,IAAK,SAAU,KAAM,SAAU,MAAOlD,EAAc,EAAGkD,GAAW,CAAA,EAAM,KACvFD,EAAa,CAAE,IAAK,SAAU,KAAM,WAAY,MAAOlD,EAAgB,EAAGkD,EAAW,CAAA,EAAM,KAC3FQ,GAAmBN,EACf,CAAE,IAAK,SAAU,KAAM,UAAW,MAAOtD,EAAc,EAAGsD,EAAW,CAAA,EACrE,KACJO,GAAmBN,GACf,CAAE,IAAK,SAAU,KAAM,UAAW,MAAOtD,EAAc,EAAGsD,GAAY,CAAA,EACtE,IAAA,EACJ,OAAO,OAAO,EAChBpF,EAAS,CAAA,EAGX,cACG,MAAA,CAAI,QAAS,OAAOR,EAAC,IAAIC,EAAC,GAAI,UAAU,gBAAgB,oBAAoB,gBAAgB,MAAO,CAAE,QAAS,SAE5G,SAAA,CAAAwD,EAAS,IAAK,GAAM,CACnB,GAAI,CAAC,EAAE,YAAa,OAAO,KAC3B,MAAM2C,EAAKjC,EAAK,IAAI,EAAE,WAAW,EACjC,GAAIiC,GAAM,KAAM,OAAO,KACvB,MAAMC,EAAKnC,EAAIT,EAAS,UAAWmB,GAAMA,EAAE,OAAS,EAAE,IAAI,CAAC,EAC3D,aAAQ,OAAA,CAA2B,GAAIwB,EAAI,GAAI5F,EAAQ,GAAI6F,EAAI,GAAI7F,EAAQ,UAAU,wBAAwB,YAAa,KAAxG,OAAO,EAAE,IAAI,EAAiG,CAClI,CAAC,EAGAqF,IAAYS,EAAAA,IAAC,OAAA,CAAK,EAAGT,GAAU,QAAS,IAAM,MAAO,CAAE,KAAMtD,EAAgB,WAAY,KAAK7B,CAAI,IAAM,EAKxGqF,IACCO,EAAAA,IAAC,OAAA,CAAK,EAAGP,GAAgB,QAAS,IAAM,MAAO,CAAE,KAAM1D,EAAc,WAAY,KAAK3B,CAAI,IAAM,EAEjGsF,GACCM,EAAAA,IAAC,OAAA,CAAK,EAAGN,EAAgB,QAAS,IAAM,MAAO,CAAE,KAAM1D,EAAc,WAAY,KAAK5B,CAAI,IAAM,EAIjG2E,SACE,OAAA,CAAK,EAAGA,EAAgB,KAAK,OAAO,YAAa,IAAM,gBAAgB,MAAM,cAAc,QAAQ,QAAS,GAAK,MAAO,CAAE,OAAQ7C,EAAc,WAAY,KAAK9B,CAAI,EAAA,CAAG,CAAG,EAM7KuE,EAAU,IAAKsB,UACb,IAAA,CAAyB,UAAW,aAAaA,EAAG,CAAC,IAAIA,EAAG,CAAC,IAAK,MAAO,CAAE,WAAY,aAAa7F,CAAI,IACvG,SAAA,CAAA4F,EAAAA,IAAC,SAAA,CAAO,EAAG,EAAG,QAAS,GAAK,MAAO,CAAE,KAAM9D,CAAA,CAAa,CAAG,EAC3D8D,EAAAA,IAAC,OAAA,CACC,EAAG,GACH,WAAW,SACX,SAAU,IACV,WAAW,0BACX,WAAW,MACX,QAAS,GACT,MAAO,CAAE,KAAM9D,CAAA,EAEd,SAAA,KAAK,MAAM+D,EAAG,QAAkB,CAAA,CAAA,CACnC,CAAA,EAZM,QAAQA,EAAG,GAAG,EAatB,CACD,EAGAT,GAAYN,IACXc,MAAC,OAAA,CAAK,EAAGd,GAAmB,KAAK,OAAO,YAAa,IAAM,gBAAgB,MAAM,cAAc,QAAQ,QAAS,IAAM,MAAO,CAAE,OAAQlD,EAAc,WAAY,KAAK5B,CAAI,EAAA,CAAG,CAAG,EAIjL6E,SACE,OAAA,CAAK,EAAGA,EAAkB,KAAK,OAAO,YAAa,IAAM,gBAAgB,MAAM,cAAc,QAAQ,QAAS,GAAK,MAAO,CAAE,OAAQlD,EAAc,WAAY,KAAK3B,CAAI,EAAA,CAAG,CAAG,EAI/K4E,SACE,OAAA,CAAK,EAAGA,EAAkB,KAAK,OAAO,YAAa,GAAK,eAAe,QAAQ,cAAc,QAAQ,QAAS,IAAM,MAAO,CAAE,OAAQ/C,EAAgB,WAAY,KAAK7B,CAAI,EAAA,CAAG,CAAG,EAOlLyE,EAAU,IAAI,CAACqB,EAAIvF,IAAM,CACxB,GAAIuF,EAAG,SAAW,GAAKA,EAAG,QAAU,EAAG,OAAO,KAC9C,MAAMC,EAAK,KAAK,IAAI,IAAK,KAAK,IAAI,EAAG,IAAMD,EAAG,OAAS,EAAE,CAAC,EACpDE,EAAaF,EAAG,QAAUA,EAAG,OAG7BG,EAAgB,KAAK,IAAIvB,EAAWnE,CAAC,EAAE,EAAI,EAAGuF,EAAG,EAAIC,EAAK,CAAC,EACjE,cACG,IAAA,CACE,SAAA,CAAAD,EAAG,QAAU,GACZF,EAAAA,IAAC,OAAA,CACC,EAAGE,EAAG,EACN,EAAGG,EACH,WAAW,SACX,SAAU,IACV,WAAW,0BACX,WAAW,MACX,MAAO,CAAE,KAAMD,EAAapE,EAAe,+BAAgC,WAAY,KAAK5B,CAAI,EAAA,EAE/F,SAAA8F,EAAG,OAAA,CAAA,SAGP,IAAA,CAAE,UAAW,aAAaA,EAAG,CAAC,IAAIA,EAAG,CAAC,IAAK,MAAO,CAAE,WAAY,aAAa9F,CAAI,IAChF,SAAA,CAAA4F,EAAAA,IAAC,SAAA,CAAO,EAAGG,EAAI,QAAS,IAAM,MAAO,CAAE,KAAMpE,CAAA,CAAa,CAAG,EAC5DmE,EAAG,OAAS,GACXF,EAAAA,IAAC,QAAK,EAAGG,EAAK,EAAG,WAAW,SAAS,SAAU,IAAK,WAAW,0BAA0B,WAAW,MAAM,MAAO,CAAE,KAAMpE,CAAA,EACtH,SAAAmE,EAAG,MAAA,CACN,CAAA,CAAA,CAEJ,CAAA,CAAA,EArBM,UAAUA,EAAG,GAAG,EAsBxB,CAEJ,CAAC,EAKApC,EAAK,IAAKwC,GAAQ,QACjB,MAAMC,EAAIpD,EAASmD,EAAI,GAAG,EACpBE,EAAIF,EAAI,EACRG,EAAKH,EAAI,UAAY,KAAO9B,EAAO8B,EAAI,MAAM,EAAIpG,EAEjDoE,EAAI,KAAK,IAAI,KAAM,KAAK,IAAI,EAAG,KAAOgC,EAAI,OAAS,GAAG,CAAC,EACvDI,EAAaH,EAAE,OAASnD,EACxBuD,EAAYlD,IAAe6C,EAAI,IAE/BM,EACJN,EAAI,UAAY,KACZ,wCACA,GAAGA,EAAI,MAAM,sBAAsB,KAAK,MAAMA,EAAI,QAAQ,CAAC,IACxDA,EAAI,QAAUA,EAAI,OAAS,MAAMA,EAAI,QAAUA,EAAI,MAAM,WAAa,KACtEA,EAAI,OAAS,EAAI,MAAMA,EAAI,MAAM,WAAa,KAC9CA,EAAI,cAAgB,EAAI,MAAMA,EAAI,aAAa,eAAiB,IACnEO,GAAOD,EAAQ,OAAS,IAAM,GAC9BE,GAAO,KAAK,IAAIlH,EAAKiH,GAAO,EAAI,EAAG,KAAK,IAAI1G,GAAQ0G,GAAO,EAAI,EAAGL,CAAC,CAAC,EACpEO,GAAON,EAAKnC,EAAI,GAEtB,OACE0C,EAAAA,KAAC,IAAA,CAEC,QAAUC,GAAM,CACVA,EAAE,SAAWA,EAAE,SACjBA,EAAE,gBAAA,EACF1D,GAAA,MAAAA,EAAagD,EAAE,OAEflD,EAASkD,EAAE,IAAI,CAEnB,EACA,aAAc,IAAM7C,EAAc4C,EAAI,GAAG,EACzC,aAAc,IAAM5C,EAAc,IAAI,EACtC,MAAO,CAAE,OAAQ,SAAA,EAGjB,SAAA,CAAAsD,EAAAA,KAAC,IAAA,CAAE,UAAW,aAAaR,CAAC,IAAIC,CAAE,IAAK,MAAO,CAAE,WAAY,aAAarG,CAAI,IAC3E,SAAA,CAAA4F,EAAAA,IAAC,SAAA,CAAO,EAAG,GAAI,KAAK,cAAc,EAClCA,EAAAA,IAAC,SAAA,CAAO,EAAA1B,EAAM,QAAS,GAAK,MAAO,CAAE,KAAMrC,EAAgB,WAAY,KAAK7B,CAAI,GAAG,CAAG,EACrFkG,EAAI,UAAY,MACfN,EAAAA,IAAC,OAAA,CAAK,EAAG,CAAC1B,EAAI,EAAG,WAAW,SAAS,SAAU,IAAK,WAAW,0BAA0B,WAAW,MAAM,MAAO,CAAE,KAAMrC,CAAA,EACtH,SAAAN,GAAQ2E,EAAI,MAAM,CAAA,CACrB,EAEDK,GAAa,CAACD,SAAe,SAAA,CAAO,EAAGpC,EAAI,EAAG,KAAK,OAAO,YAAa,EAAG,QAAS,GAAK,MAAO,CAAE,OAAQrC,GAAkB,EAC3HyE,GAAcV,EAAAA,IAAC,SAAA,CAAO,EAAG1B,EAAI,EAAG,KAAK,OAAO,UAAU,gBAAgB,YAAa,CAAA,CAAG,CAAA,EACzF,KAOEL,GAAAsC,EAAE,iBAAF,YAAAtC,GAAkB,SAAU,GAAK,GACjC+C,EAAAA,KAAC,IAAA,CACC,UAAW,aAAaR,EAAI,EAAE,IAAItG,CAAM,IACxC,QAAU+G,GAAM,CACdA,EAAE,gBAAA,EACF3D,GAAA,MAAAA,EAAmBiD,EAAE,eAAgB,CAAC,EACxC,EACA,MAAO,CAAE,OAAQ,SAAA,EAEjB,SAAA,CAAAP,EAAAA,IAAC,SAAO,SAAA,UAAUO,EAAE,eAAgB,KAAK,IAAI,CAAC,gCAAA,CAAiC,QAC9E,SAAA,CAAO,EAAG,EAAG,GAAI,GAAI,KAAK,cAAc,EACzCP,EAAAA,IAAC,OAAA,CAAK,EAAE,+BAA+B,KAAK,OAAO,UAAU,yBAAyB,YAAa,EAAG,gBAAgB,MAAM,cAAc,QAAQ,EAClJA,EAAAA,IAAC,QAAK,EAAE,gBAAgB,UAAU,yBAAyB,YAAa,EAAG,cAAc,OAAA,CAAQ,EACjGA,EAAAA,IAAC,OAAA,CAAK,EAAE,yBAAyB,UAAU,sBAAA,CAAuB,CAAA,CAAA,CAAA,EAQtEA,EAAAA,IAAC,OAAA,CACC,EAAAQ,EACA,EAAGtG,GAAUoG,EAAI,IAAM,IAAM,EAAI,GAAK,IACtC,WAAW,SACX,SAAU,IACV,UAAU,qBACV,WAAW,4BACX,WAAW,MAEV,WAAiBC,CAAC,CAAA,CAAA,EAIpBI,UACE,IAAA,CACC,SAAA,CAAAX,MAAC,QAAK,EAAGc,GAAOD,GAAO,EAAG,EAAGE,GAAO,GAAI,MAAOF,GAAM,OAAQ,GAAI,GAAI,EAAG,UAAU,oBAAoB,QAAS,IAAM,EACrHb,EAAAA,IAAC,OAAA,CAAK,EAAGc,GAAM,EAAGC,GAAO,EAAG,WAAW,SAAS,SAAU,IAAK,UAAU,eAAe,WAAW,0BAChG,SAAAH,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CAAA,EAvEGL,EAAE,IAAA,CA2Eb,CAAC,EAGA,CAAClC,GACA2B,MAAC,QAAK,EAAGpG,EAAKI,GAAS,EAAG,EAAGE,EAAS,GAAI,WAAW,SAAS,SAAU,IAAK,UAAU,uBAAuB,WAAW,4BAA4B,SAAA,6EAErJ,EAID2F,EAAU,IAAK9C,GACdiD,EAAAA,IAAC,OAAA,CAEC,EAAG7F,GAAQ,EACX,EAAG4C,EAAE,OACL,SAAU,EACV,WAAW,4BACX,WAAYA,EAAE,MAAQ,SAAW,IAAM,IACvC,QAASA,EAAE,MAAQ,SAAW,IAAO,EACrC,MAAO,CAAE,KAAMA,EAAE,MAAO,WAAY,KAAK3C,CAAI,EAAA,EAE5C,SAAA2C,EAAE,IAAA,EATEA,EAAE,GAAA,CAWV,CAAA,EACH,CAEJ,CC/bO,SAASmE,GAAkBC,EAA2D,CAC3F,MAAMC,EAAQD,EAAK,eAAiB,YAAYA,EAAK,cAAc,GAAK,aAClEE,EAAU,KAAK,UAAU,CAAC,CAAE,MAAAD,EAAO,UAAW,KAAA,CAAO,CAAC,EAC5D,MAAO,+BAA+B,mBAAmBD,EAAK,IAAI,CAAC,kCAAkC,mBAAmBE,CAAO,CAAC,EAClI,CCEA,MAAMC,GAAU,CAAC,MAAO,KAAM,MAAO,KAAM,KAAK,EAG1CC,GAAYhH,GAA4B+G,GAA8B,SAAS/G,CAAC,EAEtF,SAASiH,GAAIC,EAA4B,CACvC,GAAIA,GAAO,KAAM,MAAO,IACxB,GAAIA,EAAM,EAAG,CACX,MAAMlB,EAAI,KAAK,MAAMkB,EAAM,EAAE,EAC7B,OAAOlB,GAAK,EAAI,OAAS,GAAGA,CAAC,GAC/B,CACA,OAAIkB,EAAM,GAAW,GAAGA,EAAI,QAAQ,CAAC,CAAC,IAC/B,IAAIA,EAAM,IAAI,QAAQ,CAAC,CAAC,GACjC,CAEA,SAASC,GAAU,CAAE,MAAAC,EAAO,MAAAC,GAA2C,CACrE,OACEZ,EAAAA,KAAC,MAAA,CAAI,UAAU,2CACb,SAAA,CAAAhB,EAAAA,IAAC,OAAA,CAAK,UAAU,uDAAwD,SAAA2B,EAAM,EAC9E3B,EAAAA,IAAC,OAAA,CAAK,UAAU,+DAAgE,SAAA4B,CAAA,CAAM,CAAA,EACxF,CAEJ,CAEA,SAASC,GAAe,CAAE,OAAAC,EAAQ,SAAAC,GAA+D,CAC/F,aACG,MAAA,CAAI,UAAU,+BACZ,SAAAT,GAAQ,IAAK/G,GACZyF,EAAAA,IAAC,SAAA,CAEC,QAAS,IAAM+B,EAASxH,CAAC,EACzB,UAAW,4DACTuH,IAAWvH,EACP,yCACA,gDACN,GAEC,SAAAA,CAAA,EARIA,CAAA,CAUR,EACH,CAEJ,CAEA,SAASyH,GAAS,CAAE,KAAAb,EAAM,aAAAc,EAAc,QAAAC,GAA4E,CAGlH,KAAM,CAACJ,EAAQK,CAAS,EAAIxE,EAAAA,SAAiB4D,GAASU,CAAY,EAAIA,EAAe,KAAK,EACpF,CAAE,KAAAG,CAAA,EAASC,GAAkBP,CAAM,EACnCQ,EAASF,GAAA,YAAAA,EAAM,SAAS,KAAM7B,GAAMA,EAAE,OAASY,EAAK,MACpDoB,EAAapB,EAAK,aAAe,OACjCqB,EAAgBrB,EAAK,iBAAmB,OACxCsB,EAActB,EAAK,cAAgB,OAEzC,OACEH,EAAAA,KAAA0B,WAAA,CAEE,SAAA,CAAA1B,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAhB,MAAC,OAAA,CAAK,UAAU,sCAAuC,SAAA2C,EAAiBxB,CAAI,EAAE,EAC9EnB,EAAAA,IAAC,OAAA,CAAK,UAAU,yCAA0C,WAAK,IAAA,CAAK,CAAA,EACtE,EACCmB,EAAK,aACJnB,EAAAA,IAAC,KAAE,UAAU,gEACV,WAAK,WAAA,CACR,CAAA,EAEJ,EACAA,EAAAA,IAAC,SAAA,CACC,QAASkC,EACT,UAAU,wFAEV,SAAAlC,EAAAA,IAAC4C,GAAA,CAAE,UAAU,SAAA,CAAU,CAAA,CAAA,CACzB,EACF,EAEA5B,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAA,EAAAA,KAAC6B,EAAA,CACC,GAAI,gBAAgB,mBAAmB1B,EAAK,IAAI,CAAC,GACjD,UAAU,+DAEV,SAAA,CAAAnB,EAAAA,IAAC8C,GAAA,CAAS,UAAU,aAAA,CAAc,EAAE,eAAA,CAAA,CAAA,EAGtC9B,EAAAA,KAAC6B,EAAA,CACC,GAAI,+BAA+B,mBAAmB1B,EAAK,IAAI,CAAC,GAChE,UAAU,+DAEV,SAAA,CAAAnB,EAAAA,IAAC+C,GAAA,CAAK,UAAU,aAAA,CAAc,EAAE,iBAAA,CAAA,CAAA,CAElC,EACF,EAEA/C,EAAAA,IAAC6B,GAAA,CAAe,OAAAC,EAAgB,SAAUK,CAAA,CAAW,GAGnDK,GAAiBD,GAAcE,IAC/BzB,EAAAA,KAAC,MAAA,CAAI,UAAU,+EACZ,SAAA,CAAAwB,UACE,MAAA,CACC,SAAA,CAAAxB,EAAAA,KAAC,MAAA,CAAI,UAAU,oDAAqD,SAAA,CAAAwB,EAAc,IAAA,EAAE,EACpFxC,EAAAA,IAAC,MAAA,CAAI,UAAU,oEAAoE,SAAA,QAAA,CAAM,CAAA,EAC3F,EAEDuC,UACE,MAAA,CACC,SAAA,CAAAvB,EAAAA,KAAC,MAAA,CAAI,UAAU,oDAAqD,SAAA,CAAAuB,EAAW,GAAA,EAAC,EAChFvC,EAAAA,IAAC,MAAA,CAAI,UAAU,oEAAoE,SAAA,KAAA,CAAG,CAAA,EACxF,EAEDyC,UACE,MAAA,CACC,SAAA,CAAAzC,EAAAA,IAAC,MAAA,CAAI,UAAU,oDAAqD,SAAAyC,EAAY,EAChFzC,EAAAA,IAAC,MAAA,CAAI,UAAU,oEAAoE,SAAA,SAAA,CAAO,CAAA,CAAA,CAC5F,CAAA,EAEJ,EAIFgB,EAAAA,KAAC,MAAA,CAAI,UAAU,gCACb,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAhB,EAAAA,IAAC,IAAA,CAAE,UAAU,8DAA8D,SAAA,eAAY,EACvFA,EAAAA,IAAC0B,GAAA,CAAU,MAAM,MAAM,MAAOF,IAAIc,GAAA,YAAAA,EAAQ,KAAK,MAAO,IAAI,CAAA,CAAG,EAC7DtC,EAAAA,IAAC0B,GAAA,CAAU,MAAM,MAAM,MAAOF,IAAIc,GAAA,YAAAA,EAAQ,KAAK,MAAO,IAAI,CAAA,CAAG,CAAA,EAC/D,SACC,MAAA,CACC,SAAA,CAAAtC,EAAAA,IAAC,IAAA,CAAE,UAAU,8DAA8D,SAAA,eAAY,EACvFA,EAAAA,IAAC0B,GAAA,CAAU,MAAM,MAAM,MAAOF,IAAIc,GAAA,YAAAA,EAAQ,KAAK,MAAO,IAAI,CAAA,CAAG,EAC7DtC,EAAAA,IAAC0B,GAAA,CAAU,MAAM,MAAM,MAAOF,IAAIc,GAAA,YAAAA,EAAQ,KAAK,MAAO,IAAI,CAAA,CAAG,CAAA,CAAA,CAC/D,CAAA,EACF,EAGAtB,EAAAA,KAAC,MAAA,CAAI,UAAU,0DACZ,SAAA,CAAAuB,GACCvB,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAhB,EAAAA,IAAC,OAAA,CAAK,UAAU,8BAA8B,SAAA,aAAU,EACxDgB,EAAAA,KAAC,OAAA,CAAK,UAAU,wCAAyC,SAAA,CAAAuB,EAAW,GAAA,CAAA,CAAC,CAAA,EACvE,EAEDD,GAAUA,EAAO,eAAiB,GACjCtB,EAAAA,KAAC6B,EAAA,CACC,GAAI3B,GAAkBC,CAAI,EAC1B,UAAU,0CAEV,SAAA,CAAAH,OAAC,QAAK,UAAU,WAAW,MAAO,CAAE,MAAO7E,GACxC,SAAA,CAAAmG,EAAO,eAAe,kCAAA,EACzB,EACAtC,MAACgD,IAAa,UAAU,4BAA4B,MAAO,CAAE,MAAO7G,EAAoB,CAAG,CAAA,CAAA,CAAA,CAC7F,CAAA,CAEJ,CAAA,EAEF,CAEJ,CAEA,SAAS8G,GAAc,CACrB,WAAAC,EACA,aAAAC,EACA,OAAArB,CACF,EAIG,CACD,MAAMsB,EAAgBF,EAAW,OAAO,CAAC3C,EAAG8C,IAAM9C,EAAI8C,EAAE,QAAgB,CAAC,EACnEC,EAAgBJ,EAAW,OAAO,CAAC3C,EAAG8C,IAAM9C,EAAI8C,EAAE,SAAgB,CAAC,EACnEE,EAAgBL,EAAW,OAAO,CAAC3C,EAAG8C,IAAM9C,EAAI8C,EAAE,eAAgB,CAAC,EAEnEG,EAAkB,IAAI,IAAIN,EAAW,IAAKG,GAAM,CAACA,EAAE,KAAMA,CAAC,CAAC,CAAC,EAC5DI,EAAkBP,EAAW,OAAQG,GAAMA,EAAE,eAAiB,CAAC,EAAE,OACjEK,EAAmBR,EAAW,OAAQG,GAAMA,EAAE,QAAU,CAAC,EAAE,OAEjE,OACErC,EAAAA,KAAA0B,WAAA,CACE,SAAA,CAAA1B,EAAAA,KAAC,IAAA,CAAE,UAAU,8DAA8D,SAAA,CAAA,cAC7Dc,CAAA,EACd,EAGA9B,EAAAA,IAAC,MAAA,CAAI,UAAU,OACZ,WAAiB,EAChBgB,EAAAA,KAAC,IAAA,CAAE,UAAU,WAAW,MAAO,CAAE,MAAO7E,GACrC,SAAA,CAAAsH,EAAe,WAASA,EAAiB,EAAI,IAAM,GAAG,yBAAA,EACzD,EACEC,EAAmB,EACrB1C,EAAAA,KAAC,IAAA,CAAE,UAAU,+BACV,SAAA,CAAA0C,EAAiB,WAASA,EAAmB,EAAI,IAAM,GAAG,eAAA,EAC7D,EACEJ,EAAgB,EAClBtD,EAAAA,IAAC,KAAE,UAAU,+BAA+B,SAAA,uBAAA,CAAqB,EAEjEA,EAAAA,IAAC,IAAA,CAAE,UAAU,gCAAgC,iCAAqB,EAEtE,EAGAgB,EAAAA,KAAC,MAAA,CAAI,UAAU,mBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAhB,EAAAA,IAAC,OAAA,CAAK,UAAU,yDAAyD,SAAA,UAAO,EAChFA,EAAAA,IAAC,QAAK,UAAW,kCAAkCoD,EAAe,EAAI,kCAAoC,sBAAsB,GAC7H,SAAAA,CAAA,CACH,CAAA,EACF,EACApC,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,yDAAyD,SAAA,CAAA,cAAYc,CAAA,EAAO,EAC5F9B,EAAAA,IAAC,OAAA,CAAK,UAAU,qDAAsD,SAAAsD,CAAA,CAAc,CAAA,EACtF,EACCC,EAAgB,GACfvC,OAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAhB,EAAAA,IAAC,OAAA,CAAK,UAAU,yDAAyD,SAAA,WAAQ,EACjFA,EAAAA,IAAC,QAAK,UAAU,+CAA+C,MAAO,CAAE,MAAO7D,CAAA,EAC5E,SAAAoH,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,QAGC,MAAA,CAAI,UAAU,8CACb,SAAAvC,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAhB,EAAAA,IAAC,OAAA,CAAK,UAAU,gEAAgE,SAAA,UAAO,EACvFA,EAAAA,IAAC,OAAA,CAAK,UAAU,iFAAiF,SAAA,OAAI,EACrGA,EAAAA,IAAC,OAAA,CAAK,UAAU,iFAAiF,SAAA,OAAI,EACrGA,EAAAA,IAAC,OAAA,CAAK,UAAU,iFAAiF,SAAA,KAAA,CAAG,CAAA,CAAA,CACtG,CAAA,CACF,QAGC,MAAA,CAAI,UAAU,cACZ,SAAAmD,EAAa,IAAK,GAAM,CACvB,MAAME,EAAgBG,EAAa,IAAI,EAAE,IAAI,EACvCG,GAAgBN,GAAA,YAAAA,EAAG,UAAkB,EACrCO,GAAgBP,GAAA,YAAAA,EAAG,UAAkB,EACrCQ,GAAgBR,GAAA,YAAAA,EAAG,WAAkB,EACrCS,GAAgBT,GAAA,YAAAA,EAAG,iBAAkB,EACrC1B,EAAgB,EAAE,OAAS,EAAE,KAC7BoC,EAAgBD,EAAgB,EAChCE,EAAgBL,EAAU,EAEhC,OACE3C,EAAAA,KAAC,MAAA,CAAiB,UAAU,iCAC1B,SAAA,CAAAA,EAAAA,KAAC,OAAA,CACC,UAAW,sCACTgD,EAAU,oBAAsB,sBAClC,GAEC,SAAA,CAAArC,EACAoC,UACE,OAAA,CAAK,UAAU,8BAA8B,MAAO,CAAE,MAAO5H,CAAA,EAC3D,SAAA,CAAA2H,EAAc,WAAA,CAAA,CACjB,CAAA,CAAA,CAAA,EAGJ9D,EAAAA,IAAC,OAAA,CACC,UAAW,2DACTgE,EAAU,kCAAoC,sBAChD,GAEC,SAAAL,EAAU,EAAIA,EAAU,GAAA,CAAA,EAE3B3D,EAAAA,IAAC,OAAA,CAAK,UAAW,2DAA2D4D,EAAU,EAAI,4BAA8B,sBAAsB,GAC3I,SAAAA,EAAU,EAAIA,EAAU,IAC3B,EACA5D,EAAAA,IAAC,OAAA,CAAK,UAAW,2DAA2D6D,EAAW,EAAI,sBAAwB,sBAAsB,GACtI,SAAAA,EAAW,EAAIA,EAAW,GAAA,CAC7B,CAAA,CAAA,EAzBQ,EAAE,IA0BZ,CAEJ,CAAC,CAAA,CACH,EAEA7D,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAqC,SAAA,oCAAA,CAElD,CAAA,EACF,CAEJ,CAEO,SAASiE,GAAmB,CACjC,KAAA9C,EACA,WAAA+B,EACA,aAAAC,EACA,aAAAlB,EACA,QAAAC,CACF,EAA4B,CAC1B,aACG,MAAA,CAAI,UAAU,sEACZ,SAAAf,QACEa,GAAA,CAAS,KAAAb,EAAY,aAAAc,EAA4B,QAAAC,CAAA,CAAkB,EAEpElC,EAAAA,IAACiD,GAAA,CAAc,WAAAC,EAAwB,aAAAC,EAA4B,OAAQlB,EAAc,EAE7F,CAEJ,CCtSA,MAAMiC,GAAahI,EACbiI,GAAgB/H,EAAUF,EAAc,GAAI,EAC5CkI,GAAgBhI,EAAUF,EAAc,GAAI,EAC5CmI,GAAgBjI,EAAUJ,EAAc,GAAI,EAC5CsI,GAAgBlI,EAAUL,EAAc,GAAI,EAC5CwI,GAAgBnI,EAAUH,EAAgB,GAAI,EAI9CuI,GAAoB,sEAIpBlD,GAAU,CAAC,MAAO,KAAM,MAAO,KAAM,KAAK,EAK1CmD,GAAuC,CAC3C,MAAO,IACP,KAAM,EACN,MAAO,GACP,KAAM,IACN,MAAO,GACT,EAoBO,SAASC,GAAeC,EAAyC,CACtE,MAAMC,EAAWD,EAAM,OAAQrG,GAAMA,EAAE,WAAW,EAC5CuG,EAAU,IAAI,IAAID,EAAS,IAAKtG,GAAM,CAACA,EAAE,KAAMA,CAAC,CAAC,CAAC,EAClDwG,MAAc,IAKdC,EAFQH,EAAS,OAAQtG,GAAM,CAACA,EAAE,aAAe,CAACuG,EAAQ,IAAIvG,EAAE,WAAW,CAAC,EAEtC,IAAK0G,GAAS,CACxD,MAAM7H,EAA6B,CAAA,EAC7B8H,EAA0B,CAAC,CAAE,KAAMD,EAAM,MAAO,EAAG,EACzD,KAAOC,EAAM,OAAS,GAAG,CACvB,MAAMC,EAAOD,EAAM,MAAA,EACfH,EAAQ,IAAII,EAAK,KAAK,IAAI,IAC9BJ,EAAQ,IAAII,EAAK,KAAK,IAAI,EAC1B/H,EAAS,KAAK+H,CAAI,EAClBN,EACG,OAAQO,GAAMA,EAAE,cAAgBD,EAAK,KAAK,MAAQ,CAACJ,EAAQ,IAAIK,EAAE,IAAI,CAAC,EACtE,QAASA,GAAMF,EAAM,KAAK,CAAE,KAAME,EAAG,MAAOD,EAAK,MAAQ,CAAA,CAAG,CAAC,EAClE,CACA,MAAO,CAAE,OAAQF,EAAM,SAAA7H,CAAA,CACzB,CAAC,EAGD,OAAAyH,EACG,OAAQtG,GAAM,CAACwG,EAAQ,IAAIxG,EAAE,IAAI,CAAC,EAClC,QAASA,GAAMyG,EAAU,KAAK,CAAE,OAAQzG,EAAG,SAAU,CAAC,CAAE,KAAMA,EAAG,MAAO,CAAA,CAAG,CAAA,CAAG,CAAC,EAG3EyG,EAAU,KACf,CAACjJ,EAAGc,IAAMA,EAAE,SAAS,OAASd,EAAE,SAAS,QAAUA,EAAE,OAAO,KAAK,cAAcc,EAAE,OAAO,IAAI,CAAA,CAEhG,CAIA,SAASwI,GAAO3G,EAA0B,CACxC,GAAIA,GAAK,KAAM,MAAO,IACtB,GAAIA,EAAI,EAAG,CACT,MAAM8B,EAAI,KAAK,MAAM9B,EAAI,EAAE,EAC3B,OAAO8B,GAAK,EAAI,OAAS,GAAGA,CAAC,GAC/B,CACA,OAAI9B,EAAI,GAAW,GAAGA,EAAE,QAAQ,CAAC,CAAC,IAC3B,IAAIA,EAAI,IAAI,QAAQ,CAAC,CAAC,GAC/B,CAEA,SAAS4G,GAAQ1B,EAAiB5F,EAAuB,CAGvD,GAAI,CAACA,GAAU4F,IAAY,QAAU,CAAE,IAAK,KAAM,MAAO,mBAAA,EAEzD,MAAM2B,EAAQ3B,EAAU5F,EAClBwH,EAAM,KAAK,MAAMD,EAAQ,GAAG,EAE5BjJ,EAAQiJ,EAAQ,EAAM,oBAAsBA,EAAQ,GAAM,kBAAoB,oBACpF,MAAO,CAAE,IAAAC,EAAK,MAAAlJ,CAAA,CAChB,CAIA,SAASmJ,GAAe,CAAE,MAAA5D,EAAO,OAAA6D,GAAwE,CACvG,KAAM,CAACC,EAAOC,CAAQ,EAAIhI,EAAAA,SAASiE,GAAS,KAAO,OAAOA,CAAK,EAAI,EAAE,EAC/DgE,EAAQC,EAAAA,OAAkD,MAAS,EAEnEC,EAAUC,GAAgB,CAC9B,MAAMnK,EAAI,SAASmK,EAAK,EAAE,EAC1BN,EAAO,CAACM,EAAI,KAAA,GAAU,MAAMnK,CAAC,GAAKA,EAAI,EAAI,KAAOA,CAAC,CACpD,EAEA,OACEoE,EAAAA,IAAC,QAAA,CACC,KAAK,SACL,IAAK,EACL,KAAM,EACN,MAAO0F,EACP,SAAWzE,GAAM,CACf,MAAM8E,EAAM9E,EAAE,OAAO,MACrB0E,EAASI,CAAG,EACZ,aAAaH,EAAM,OAAO,EAC1BA,EAAM,QAAU,WAAW,IAAME,EAAOC,CAAG,EAAG,GAAG,CACnD,EACA,OAAS9E,GAAM,CAAE,aAAa2E,EAAM,OAAO,EAAGE,EAAO7E,EAAE,OAAO,KAAK,CAAG,EACtE,QAAUA,GAAMA,EAAE,gBAAA,EAClB,UAAYA,GAAMA,EAAE,gBAAA,EACpB,UAAU,oFAAA,CAAA,CAGhB,CAIA,SAAS+E,GAAW,CAClB,KAAA7E,EACA,OAAAmB,EACA,SAAA2D,EACA,QAAAC,CACF,EAKG,OACD,MAAMC,EAAaC,GAAA,EACbzC,GAAUrB,GAAA,YAAAA,EAAQ,UAAW,EAC7BsB,GAAUtB,GAAA,YAAAA,EAAQ,UAAW,EAC7BuB,GAAWvB,GAAA,YAAAA,EAAQ,WAAY,EAC/BwB,GAAgBxB,GAAA,YAAAA,EAAQ,iBAAkB,EAC1CvE,EAASoD,EAAK,iBAAmB,KACjC,CAAE,IAAAoE,EAAK,MAAAlJ,CAAA,EAAUgJ,GAAQ1B,EAAS5F,CAAM,EACxCsI,EAAWd,GAAO,KAAO,KAAK,IAAI,IAAKA,CAAG,EAAI,EAE9Ce,EAAc1K,GAAqBuK,EAAW,OAAO,CAAE,KAAMhF,EAAK,KAAM,gBAAiBvF,CAAA,CAAG,EAC5F2K,EAAc3K,GAAqBuK,EAAW,OAAO,CAAE,KAAMhF,EAAK,KAAM,YAAavF,CAAA,CAAG,EAE9F,OACEoE,MAAA0C,EAAAA,SAAA,CACE,SAAA1B,EAAAA,KAAC,MAAA,CACC,KAAK,SACL,SAAU,EACV,QAAAkF,EACA,UAAYjF,GAAM,CAAMA,EAAE,MAAQ,SAASiF,EAAA,CAAW,EACtD,UAAW,iEACTD,EAAW,qCAAuC,MACpD,GACA,MAAO,CAAE,oBAAqBzB,EAAA,EAG9B,SAAA,CAAAxD,EAAAA,KAAC,MAAA,CAAI,UAAU,2CACb,SAAA,CAAAhB,MAAC,OAAA,CAAK,UAAU,+CACb,SAAA2C,EAAiBxB,CAAI,EACxB,KACElD,EAAAkD,EAAK,iBAAL,YAAAlD,EAAqB,SAAU,GAAK,GACpC+B,MAAC,OAAA,CAAK,MAAO,UAAUmB,EAAK,eAAe,KAAK,IAAI,CAAC,GAAI,UAAU,wBACjE,SAAAnB,EAAAA,IAACwG,GAAA,CAAS,UAAU,8BAAA,CAA+B,CAAA,CACrD,CAAA,EAEJ,EAGAxG,EAAAA,IAAC,OAAA,CAAK,UAAU,wDACb,WAAK,KACR,EAGAgB,EAAAA,KAAC,MAAA,CAAI,UAAU,kCAEb,SAAA,CAAAhB,MAAC,OAAI,UAAU,qDAAqD,MAAO,CAAE,gBAAiBmE,EAAA,EAC5F,SAAAnE,EAAAA,IAACwF,GAAA,CAAe,MAAOrE,EAAK,iBAAmB,KAAM,OAAQmF,EAAY,EAC3E,QAEC,MAAA,CAAI,UAAU,qDAAqD,MAAO,CAAE,gBAAiBlC,EAAA,EAC5F,SAAApE,EAAAA,IAACwF,IAAe,MAAOrE,EAAK,aAAe,KAAM,OAAQoF,EAAS,EACpE,EAEAvG,MAAC,OAAI,UAAU,mDAAmD,MAAO,CAAE,gBAAiBqE,IAC1F,SAAArE,EAAAA,IAAC6C,EAAA,CACC,GAAI,+BAA+B,mBAAmB1B,EAAK,IAAI,CAAC,oBAChE,UAAW,kDACTwC,EAAU,EAAI,kCAAoC,sBACpD,GACA,QAAU1C,GAAMA,EAAE,gBAAA,EAEjB,SAAA0C,CAAA,CAAA,EAEL,EAEA3D,MAAC,OAAI,UAAU,mDAAmD,MAAO,CAAE,gBAAiBsE,IAC1F,SAAAtE,EAAAA,IAAC6C,EAAA,CACC,GAAI,+BAA+B,mBAAmB1B,EAAK,IAAI,CAAC,kBAChE,UAAW,kDACTyC,EAAU,EAAI,gBAAkB,sBAClC,GACA,MAAOA,EAAU,EAAI,CAAE,MAAO7H,GAAiB,OAC/C,QAAUkF,GAAMA,EAAE,gBAAA,EAEjB,SAAA2C,CAAA,CAAA,EAEL,EAEA5D,MAAC,OAAI,UAAU,mDAAmD,MAAO,CAAE,gBAAiBuE,IAC1F,SAAAvE,EAAAA,IAAC6C,EAAA,CACC,GAAI,+BAA+B,mBAAmB1B,EAAK,IAAI,CAAC,mBAChE,UAAW,kDACT0C,EAAW,EAAI,sBAAwB,sBACzC,GACA,MAAOA,EAAW,EAAI,CAAE,MAAO5H,GAAmB,OAClD,QAAUgF,GAAMA,EAAE,gBAAA,EAEjB,SAAA4C,CAAA,CAAA,CACH,CACF,CAAA,EACF,EAGA7D,EAAAA,IAAC,QAAK,UAAU,uEACb,aAAOsC,GAAA,YAAAA,EAAQ,KAAK,MAAO,IAAI,CAAA,CAClC,EAGAtC,EAAAA,IAAC,QAAK,UAAU,uEACb,aAAOsC,GAAA,YAAAA,EAAQ,KAAK,MAAO,IAAI,CAAA,CAClC,EAGAtB,EAAAA,KAAC,MAAA,CAAI,UAAU,iCACb,SAAA,CAAAhB,MAAC,OAAI,UAAU,qEACb,SAAAA,MAAC,MAAA,CAAI,UAAW,uBAAuB3D,CAAK,GAAI,MAAO,CAAE,MAAO,GAAGgK,CAAQ,KAAO,EACpF,EACArG,EAAAA,IAAC,OAAA,CACC,UAAW,mCACTuF,GAAO,MAAQA,EAAM,IACjB,oCACA,sBACN,GAEC,SAAAA,GAAO,KAAO,GAAGA,CAAG,IAAM,GAAA,CAAA,CAC7B,EACF,EAKAvE,EAAAA,KAAC,MAAA,CAAI,UAAU,gDACZ,SAAA,CAAA8C,EAAgB,GACf9D,EAAAA,IAAC6C,EAAA,CACC,GAAI3B,GAAkBC,CAAI,EAC1B,UAAU,wDACV,MAAO,GAAG2C,CAAa,QAAQA,IAAkB,EAAI,GAAK,GAAG,mCAC7D,QAAU7C,GAAMA,EAAE,gBAAA,EAElB,SAAAjB,EAAAA,IAACyG,GAAA,CAAc,UAAU,cAAc,YAAa,CAAA,CAAG,CAAA,CAAA,EAG3DzG,EAAAA,IAAC6C,EAAA,CACC,GAAI,+BAA+B,mBAAmB1B,EAAK,IAAI,CAAC,cAChE,UAAU,2DACV,MAAM,0BACN,QAAUF,GAAMA,EAAE,gBAAA,EAElB,SAAAjB,EAAAA,IAAC0G,GAAA,CAAI,UAAU,aAAA,CAAc,CAAA,CAAA,CAC/B,CAAA,CACF,CAAA,CAAA,CAAA,EAEJ,CAEJ,CAWA,SAASC,GAAc,CAAE,EAAA/K,GAAoB,CAC3C,OAAIA,GAAK,EAAU,KAEjBoF,EAAAA,KAAC,OAAA,CACC,UAAU,8DACV,MAAO,CAAE,MAAO7E,CAAA,EAChB,MAAO,GAAGP,CAAC,eAEX,SAAA,CAAAoE,EAAAA,IAACyG,GAAA,CAAc,UAAU,UAAU,YAAa,KAAM,EACrD7K,EAAI,EAAI,KAAOA,CAAA,CAAA,CAAA,CAGtB,CAUA,SAASgL,GAAa,CAAE,UAAA7B,EAAW,WAAA8B,EAAY,aAAAC,EAAc,SAAAzJ,GAK1D,CACD,KAAM,CAAC0J,EAAMC,CAAO,EAAIrJ,EAAAA,SAAS,EAAK,EAChCsJ,EAAMpB,EAAAA,OAAuB,IAAI,EAEvCqB,EAAAA,UAAU,IAAM,CACd,GAAI,CAACH,EAAM,OACX,MAAMb,EAAWjF,GAAkB,CAC7BgG,EAAI,SAAW,CAACA,EAAI,QAAQ,SAAShG,EAAE,MAAc,GAAG+F,EAAQ,EAAK,CAC3E,EACMG,EAASlG,GAAqB,CAAMA,EAAE,MAAQ,UAAU+F,EAAQ,EAAK,CAAG,EAC9E,gBAAS,iBAAiB,YAAad,CAAO,EAC9C,SAAS,iBAAiB,UAAWiB,CAAK,EACnC,IAAM,CACX,SAAS,oBAAoB,YAAajB,CAAO,EACjD,SAAS,oBAAoB,UAAWiB,CAAK,CAC/C,CACF,EAAG,CAACJ,CAAI,CAAC,EAET,MAAMK,EAASrC,EAAU,KAAMsC,GAAMA,EAAE,OAAO,OAASP,CAAY,GAAK/B,EAAU,CAAC,EACnF,GAAI,CAACqC,EAAQ,OAAO,KACpB,MAAME,EAAMT,EAAW,IAAIO,EAAO,OAAO,IAAI,EAE7C,OACEpG,EAAAA,KAAC,MAAA,CAAI,IAAAiG,EAAU,UAAU,qBACvB,SAAA,CAAAjG,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMgG,EAASvI,GAAM,CAACA,CAAC,EAChC,UAAU,oCACV,gBAAesI,EACf,gBAAc,UAEd,SAAA,CAAA/G,MAAC,QAAK,UAAU,kFACb,SAAA2C,EAAiByE,EAAO,MAAM,EACjC,EACApG,EAAAA,KAAC,OAAA,CAAK,UAAU,uDACb,SAAA,EAAAsG,GAAA,YAAAA,EAAK,WAAYF,EAAO,SAAS,OAAO,aAAUE,GAAA,YAAAA,EAAK,WAAYF,EAAO,SAAS,UAAY,EAAI,GAAK,IAAI,OAAIE,GAAA,YAAAA,EAAK,UAAW,EAAE,UAAA,EACrI,EACAtH,EAAAA,IAAC2G,GAAA,CAAc,GAAGW,GAAA,YAAAA,EAAK,WAAY,EAAG,EACtCtH,EAAAA,IAACuH,GAAA,CACC,UAAW,oGAAoGR,EAAO,aAAe,EAAE,GACvI,YAAa,GAAA,CAAA,CACf,CAAA,CAAA,EAGDA,GACC/G,EAAAA,IAAC,MAAA,CACC,KAAK,UACL,UAAU,0JAET,SAAA+E,EAAU,IAAKsC,GAAM,CACpB,MAAMvL,EAAI+K,EAAW,IAAIQ,EAAE,OAAO,IAAI,EAChCG,EAAWH,EAAE,OAAO,OAASD,EAAO,OAAO,KACjD,OACEpG,EAAAA,KAAC,SAAA,CAEC,KAAK,SACL,KAAK,SACL,gBAAewG,EACf,QAAS,IAAM,CAAEnK,EAASgK,EAAE,OAAO,IAAI,EAAGL,EAAQ,EAAK,CAAG,EAC1D,UAAW,8EACTQ,EAAW,0BAA4B,0CACzC,GAEA,SAAA,CAAAxH,MAAC,QAAK,UAAU,+BAAgC,SAAA2C,EAAiB0E,EAAE,MAAM,EAAE,EAC3ErG,EAAAA,KAAC,OAAA,CAAK,UAAU,wEACb,SAAA,EAAAlF,GAAA,YAAAA,EAAG,WAAYuL,EAAE,SAAS,OAAO,UAAOvL,GAAA,YAAAA,EAAG,UAAW,EAAE,UAAA,EAC3D,EAIAkE,EAAAA,IAAC,OAAA,CAAK,UAAU,mCACd,SAAAA,EAAAA,IAAC2G,IAAc,GAAG7K,GAAA,YAAAA,EAAG,WAAY,CAAA,CAAG,CAAA,CACtC,CAAA,CAAA,EAlBKuL,EAAE,OAAO,IAAA,CAqBpB,CAAC,CAAA,CAAA,CACH,EAEJ,CAEJ,CAIA,SAASI,IAAY,CACnB,MAAMC,EAAc,CAClB,CAAE,MAAO,WAAY,KAAMvD,GAAa,IAAKjI,EAAc,EAAG,MAAA,EAC9D,CAAE,MAAO,QAAY,KAAMkI,GAAa,IAAKF,GAAc,EAAG,MAAA,EAC9D,CAAE,MAAO,UAAY,KAAMG,GAAe,IAAKrI,EAAgB,EAAG,OAAQ,GAAI,MAAA,EAC9E,CAAE,MAAO,UAAY,KAAMsI,GAAe,IAAKvI,EAAgB,EAAG,OAAQ,GAAI,MAAA,EAC9E,CAAE,MAAO,WAAY,KAAMwI,GAAe,IAAKtI,EAAgB,EAAG,OAAQ,GAAI,MAAA,CAAO,EAEvF,OACE+E,EAAAA,KAAC,MAAA,CACC,UAAU,qEACV,MAAO,CAAE,oBAAqBwD,EAAA,EAE9B,SAAA,CAAAxE,EAAAA,IAAC,OAAA,CAAK,UAAU,8EAA8E,SAAA,OAAI,EAClGA,EAAAA,IAAC,OAAA,CAAK,UAAU,8EAA8E,SAAA,OAAI,QAGjG,MAAA,CAAI,UAAU,kCACZ,SAAA0H,EAAY,IAAKC,GAChB3H,EAAAA,IAAC,MAAA,CAEC,UAAW,GAAG2H,EAAI,CAAC,2CAA2C,OAAQA,EAAMA,EAAI,GAAK,QAAQ,GAC7F,MAAO,CAAE,gBAAiBA,EAAI,IAAA,EAE9B,SAAA3H,EAAAA,IAAC,OAAA,CAAK,UAAU,kDAAkD,MAAO,CAAE,MAAO2H,EAAI,GAAA,EACnF,SAAAA,EAAI,KAAA,CACP,CAAA,EANKA,EAAI,KAAA,CAQZ,EACH,EAEA3H,EAAAA,IAAC,OAAA,CAAK,UAAU,yFAAyF,SAAA,WAAQ,EACjHA,EAAAA,IAAC,OAAA,CAAK,UAAU,yFAAyF,SAAA,WAAQ,EACjHA,EAAAA,IAAC,OAAA,CAAK,UAAU,8EAA8E,SAAA,QAAK,EACnGA,EAAAA,IAAC,OAAA,CAAK,UAAU,0FAA0F,SAAA,SAAA,CAAO,CAAA,CAAA,CAAA,CAGvH,CAKO,SAAS4H,IAAiB,OAG/B,KAAM,CAAC9F,EAAQK,CAAS,EAAIxE,EAAAA,SAAiB,IAAI,EAC3C,CAACP,EAAcyK,CAAe,EAAIlK,EAAAA,SAAwB,IAAI,EAC9D,CAACmK,EAAYC,CAAa,EAAIpK,EAAAA,SAAS,EAAK,EAKlDqK,GAAA,EAEA,KAAM,CAAE,KAAMC,EAAU,UAAWC,EAAc,QAASC,CAAA,EAAiBC,GAAA,EACrE,CACJ,KAAMC,EACN,UAAWC,EACX,QAASC,CAAA,EACPlG,GAAkBP,CAAM,EAEtB6C,GAAQsD,GAAA,YAAAA,EAAU,QAAS,CAAA,EAC3BO,GAAUH,GAAA,YAAAA,EAAa,WAAY,CAAA,EAInCI,EAAqBC,EAAAA,QAAQ,IAAM,CACvC,MAAMlF,EAAe,IAAI,IAAIgF,EAAQ,IAAKnF,GAAM,CAACA,EAAE,KAAMA,CAAC,CAAC,CAAC,EACtDsF,MAAU,IAChB,UAAWtB,KAAK3C,IAAeuD,GAAA,YAAAA,EAAU,QAAS,CAAA,CAAE,EAAG,CACrD,IAAItE,EAAU,EAAGiF,EAAW,EAC5B,UAAWrI,KAAK8G,EAAE,SAAU,CAC1B,MAAMhE,EAAIG,EAAa,IAAIjD,EAAE,KAAK,IAAI,EACtCoD,IAAWN,GAAA,YAAAA,EAAG,UAAW,EACzBuF,IAAYvF,GAAA,YAAAA,EAAG,iBAAkB,CACnC,CACAsF,EAAI,IAAItB,EAAE,OAAO,KAAM,CAAE,SAAUA,EAAE,SAAS,OAAQ,QAAA1D,EAAS,SAAAiF,CAAA,CAAU,CAC3E,CACA,OAAOD,CACT,EAAG,CAACH,EAASP,CAAQ,CAAC,EAKhBlD,EAAY2D,EAAAA,QAAQ,IAA0BhE,GAAeC,CAAK,EAAG,CAACA,CAAK,CAAC,EAC5E,CAACkE,EAAcC,CAAe,EAAIC,GAAA,EAClCC,EAAgBH,EAAa,IAAI,UAAU,EAC3CI,EACJlE,EAAU,KAAMsC,GAAMA,EAAE,OAAO,OAAS2B,CAAa,GAAKjE,EAAU,CAAC,GAAK,KACtEmE,EAAiBC,EAAAA,YACpBC,GAAmB,CAClBvB,EAAgB,IAAI,EACpBiB,EAAiBjM,GAAS,CACxB,MAAMtC,EAAI,IAAI,gBAAgBsC,CAAI,EAClC,OAAAtC,EAAE,IAAI,WAAY6O,CAAM,EACjB7O,CACT,CAAC,CACH,EACA,CAACuO,CAAe,CAAA,EAGZO,GAAUJ,GAAA,YAAAA,EAAgB,WAAY,CAAA,EACtCK,EAAkBZ,EAAAA,QACtB,IAAM,IAAI,IAAIW,EAAQ,IAAI,CAAC,CAAE,KAAAlI,CAAA,IAAWA,EAAK,IAAI,CAAC,EAClD,CAACkI,CAAO,CAAA,EAEJE,EAAkBb,EAAAA,QACtB,IAAMF,EAAQ,OAAQnF,GAAMiG,EAAgB,IAAIjG,EAAE,IAAI,CAAC,EACvD,CAACmF,EAASc,CAAe,CAAA,EAGrBE,GAAgBd,EAAAA,QACpB,IACEW,EAAQ,IAAI,CAAC,CAAE,KAAM/K,MAAS,CAC5B,KAAMA,EAAE,KACR,MAAOA,EAAE,MACT,YAAaA,EAAE,YACf,gBAAiBA,EAAE,iBAAmB,KACtC,eAAgBA,EAAE,gBAAkB,CAAA,EACpC,OAAQkK,EAAQ,KAAMnF,GAAMA,EAAE,OAAS/E,EAAE,IAAI,CAAA,EAC7C,EACJ,CAAC+K,EAASb,CAAO,CAAA,EAIbiB,EAAuBN,EAAAA,YAC1BO,GAAyB,CACxB,MAAM3L,EAASgH,EAAU,KAAMsC,GAC7BA,EAAE,SAAS,KAAK,CAAC,CAAE,KAAAlG,CAAA,IAAWA,EAAK,OAASuI,CAAY,CAAA,EAEtD3L,GAAQmL,EAAenL,EAAO,OAAO,IAAI,CAC/C,EACA,CAACgH,EAAWmE,CAAc,CAAA,EAGtBS,GAAWC,GAAA,EAEXC,IACJ5L,EAAAoL,EAAQ,KAAK,CAAC,CAAE,KAAAlI,KAAWA,EAAK,OAAS/D,CAAY,IAArD,YAAAa,EAAwD,OAAQ,KAE5D6L,GAAY5B,GAAgBI,EAE5ByB,GAAgB,SAAY,CAChChC,EAAc,EAAI,EAClB,MAAM,QAAQ,IAAI,CAACI,IAAgBI,EAAA,CAAgB,CAAC,EACpDR,EAAc,EAAK,CACrB,EAEMiC,EAAgB7I,GACpB0G,EAAiBhL,GAAUA,IAASsE,EAAO,KAAOA,CAAK,EAEnD8I,SACH,MAAA,CAAI,UAAU,4BACZ,SAAA3I,GAAQ,IAAK/G,GACZyF,EAAAA,IAAC,SAAA,CAEC,QAAS,IAAMmC,EAAU5H,CAAC,EAC1B,UAAW,4DACTuH,IAAWvH,EACP,yCACA,gDACN,GAEC,SAAAA,CAAA,EARIA,CAAA,CAUR,EACH,EAGF,OACEyG,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAhB,EAAAA,IAACkK,GAAA,CACC,MAAM,aACN,SAAS,gCACT,OAAQD,GACR,QACEjK,EAAAA,IAAC,SAAA,CACC,QAAS+J,GACT,SAAUjC,EACV,UAAU,uFAEV,eAACqC,GAAA,CAAU,UAAW,eAAerC,EAAa,eAAiB,EAAE,EAAA,CAAI,CAAA,CAAA,CAC3E,CAAA,EAIHgC,GACC9I,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAhB,EAAAA,IAAC,MAAA,CAAI,UAAU,oCAAA,CAAqC,EACpDA,EAAAA,IAAC,MAAA,CAAI,UAAU,uCAAA,CAAwC,QACtD,MAAA,CAAI,UAAU,YACZ,SAAA,CAAC,EAAG,EAAG,CAAC,EAAE,IAAKrF,GACdqF,EAAAA,IAAC,MAAA,CAAY,UAAU,sCAAA,EAAbrF,CAAoD,CAC/D,CAAA,CACH,CAAA,EACF,EACEoK,EAAU,SAAW,EACvB/D,OAAC,MAAA,CAAI,UAAU,OACb,SAAA,CAAAhB,EAAAA,IAAC,IAAA,CAAE,UAAU,mCAAmC,SAAA,oEAAiE,EACjHgB,EAAAA,KAAC,IAAA,CAAE,UAAU,6BAA6B,SAAA,CAAA,QAClC,UACL6B,EAAA,CAAK,GAAG,eAAe,UAAU,8BAA8B,SAAA,QAEhE,EAAQ,IAAI,cACD7C,EAAAA,IAAC,UAAO,SAAA,uBAAA,CAAqB,EAAS,6CAAA,CAAA,CAEnD,CAAA,EACF,EAGAgB,EAAAA,KAAC,MAAA,CAAI,UAAU,+BAMZ,SAAA,CAAA+D,EAAU,OAAS,GAClB/E,EAAAA,IAAC4G,GAAA,CACC,UAAA7B,EACA,WAAY0D,EACZ,cAAcQ,GAAA,YAAAA,EAAgB,OAAO,OAAQ,KAC7C,SAAUC,CAAA,CAAA,EAKdlI,EAAAA,KAAC,MAAA,CAAI,UAAU,yDAEb,SAAA,CAAAhB,EAAAA,IAAC,MAAA,CAAI,UAAU,0EACb,SAAAA,EAAAA,IAAC9C,GAAA,CACC,SAAUsM,GACV,aAAApM,EACA,SAAU4M,EACV,iBAAkBP,EAClB,WAAatI,GAASwI,GAAS,+BAA+B,mBAAmBxI,CAAI,CAAC,EAAE,EACxF,YAAasD,GAAa3C,CAAM,CAAA,CAAA,EAEpC,EAEA9B,EAAAA,IAAC,MAAA,CAAI,UAAU,8CAAA,CAA+C,EAE9DA,EAAAA,IAACiE,GAAA,CACC,KAAM4F,EACN,WAAYN,EACZ,aAAcF,EAAQ,IAAKe,GAAMA,EAAE,IAAI,EACvC,aAActI,EACd,QAAS,IAAM+F,EAAgB,IAAI,CAAA,CAAA,CACrC,EACF,EAGA7G,EAAAA,KAAC,MAAA,CAAI,UAAU,sFACb,SAAA,CAAAhB,EAAAA,IAACyH,GAAA,EAAU,EACXzH,EAAAA,IAAC,OAAI,UAAU,mEACZ,WAAQ,IAAI,CAAC,CAAE,KAAAmB,CAAA,IACdnB,EAAAA,IAACgG,GAAA,CAEC,KAAA7E,EACA,OAAQqH,EAAQ,KAAMnF,GAAMA,EAAE,OAASlC,EAAK,IAAI,EAChD,SAAU/D,IAAiB+D,EAAK,KAChC,QAAS,IAAM6I,EAAa7I,EAAK,IAAI,CAAA,EAJhCA,EAAK,IAAA,CAMb,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CAAA,CAEF,CAAA,EAEJ,CAEJ"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as e,a as f}from"./vendor-query-B2UbickB.js";import{F as b,b as m,c as h,a as k}from"./FilterBar-BR3ztZ8y.js";import{P as C}from"./PriorityBadge-CCERr9vQ.js";import{R as S}from"./RolePill-CWhoLwef.js";import{W as P}from"./WorkflowPill-CQ1AmhlC.js";import{C as E,a as T,i as _}from"./CountdownTimer-lkv_7msa.js";import{k as F,m as v}from"./index-C-8xXyvr.js";import{al as O,am as $,an as u,ac as L,ad as A}from"./vendor-icons-DKCAtTJ9.js";import{L as w}from"./vendor-react-CXumBFUA.js";const d="text-text-secondary transition-colors group-hover/row:text-text-primary";function I({row:t}){if(T(t)){const s=t.status==="resolved"?"text-status-success":"text-text-tertiary";return e.jsx($,{className:`w-3 h-3 shrink-0 ${s}`})}return t.status==="resolved"?e.jsx(u,{className:"w-2.5 h-2.5 shrink-0 text-status-success",strokeWidth:2.5}):t.status==="cancelled"?e.jsx(u,{className:"w-2.5 h-2.5 shrink-0 text-status-error",strokeWidth:2.5}):_(t)?e.jsx(u,{className:"w-2.5 h-2.5 shrink-0 text-status-warning",strokeWidth:2.5}):e.jsx(u,{className:"w-2.5 h-2.5 shrink-0 text-status-active",strokeWidth:2.5})}function R({metadata:t,role:s,highlightKeys:y}){const[i,c]=f.useState(!1);if(!t||Object.keys(t).length===0)return e.jsx("span",{className:"text-2xs text-text-tertiary",children:"—"});const n=y??[],o=[...n.filter(r=>r in t),...Object.keys(t).filter(r=>!n.includes(r))],x=i?o:o.slice(0,1),a=o.length-1;return e.jsx("div",{className:"w-full",onClick:r=>r.stopPropagation(),children:e.jsx("div",{className:"space-y-px",children:x.map((r,N)=>{const p=typeof t[r]=="object"&&t[r]!==null?JSON.stringify(t[r]):String(t[r]),j=n.includes(r),g=N===x.length-1;return e.jsxs("div",{className:"group/mrow flex items-center gap-1 min-w-0",children:[e.jsx("span",{className:`shrink-0 w-14 text-2xs font-mono uppercase tracking-wide truncate ${j?"text-accent":"text-text-tertiary"}`,title:r,children:r}),e.jsx("span",{className:`flex-1 min-w-0 text-2xs font-medium truncate ${j?"text-text-primary":"text-text-secondary"}`,title:p,children:p}),e.jsxs("span",{className:"flex items-center gap-px shrink-0 opacity-50 group-hover/mrow:opacity-100 transition-opacity",children:[e.jsx(w,{to:v(r,t[r],s),className:"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors",title:`Filter ${s}: ${r} = ${p}`,onClick:l=>l.stopPropagation(),children:e.jsx(L,{className:"w-3 h-3"})}),e.jsx(w,{to:v(r,t[r]),className:"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors",title:`Search all: ${r} = ${p}`,onClick:l=>l.stopPropagation(),children:e.jsx(A,{className:"w-3 h-3"})})]}),!i&&a>0&&e.jsxs("button",{onClick:l=>{l.stopPropagation(),c(!0)},className:"shrink-0 text-2xs text-text-quaternary hover:text-accent transition-colors font-mono",title:`Show ${a} more fields`,children:["+",a]}),i&&g&&a>0&&e.jsx("button",{onClick:l=>{l.stopPropagation(),c(!1)},className:"shrink-0 text-2xs text-text-quaternary hover:text-accent transition-colors",title:"Show less",children:"↑"})]},r)})})})}function W(t={}){return[{key:"description",label:"Summary",priority:1,render:s=>e.jsxs("div",{className:"flex items-center gap-2 overflow-hidden",children:[e.jsx("span",{className:"shrink-0",children:e.jsx(I,{row:s})}),e.jsx("span",{className:`truncate text-xs ${d}`,children:s.description||s.type})]}),className:"max-w-0"},{key:"role",label:"Role",priority:2,render:s=>e.jsx("span",{className:d,children:e.jsx(S,{role:s.role,size:"md",tone:"inherit"})}),className:"w-28"},{key:"priority",label:"Priority",priority:2,render:s=>e.jsx("span",{className:d,children:e.jsx(C,{priority:s.priority,size:"sm",tone:"inherit"})}),className:"w-20"},{key:"workflow_type",label:"Workflow",priority:2,showFrom:"split",render:s=>e.jsx(P,{type:s.workflow_type||s.type}),className:"w-40 whitespace-nowrap"},{key:"metadata",label:"Metadata",priority:2,showFrom:"wall",render:s=>e.jsx(R,{metadata:s.metadata,role:s.role,highlightKeys:t.highlightKeys}),className:"w-80 max-w-[19rem] align-top"},{key:"created_at",label:"Ago",priority:1,render:s=>e.jsx("span",{className:`text-xs tabular-nums ${d}`,title:s.created_at,children:F(s.created_at)}),className:"w-14 whitespace-nowrap"}]}const G=W(),Q={key:"expires",label:e.jsx(O,{className:"w-3.5 h-3.5 text-text-tertiary"}),render:t=>t.assigned_until?e.jsx(E,{until:t.assigned_until}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"—"}),className:"w-16 whitespace-nowrap",priority:1},B=[{value:"1",label:"P1"},{value:"2",label:"P2"},{value:"3",label:"P3"},{value:"4",label:"P4"}],M=[{value:"all",label:"All"},{value:"available",label:"Available"},{value:"claimed",label:"Claimed"},{value:"resolved",label:"Resolved"},{value:"cancelled",label:"Cancelled"},{value:"expired",label:"Expired"}];function V({filters:t,setFilter:s,roles:y,types:i,showStatus:c=!1,showSearch:n=!0,actions:o}){const x=[t.role,t.type,t.priority,t.status&&t.status!=="all"?t.status:"",t.search??""].filter(Boolean).length;return e.jsxs(b,{actions:o,activeFilterCount:x,children:[c&&e.jsxs(e.Fragment,{children:[e.jsx(m,{label:"Status",value:t.status??"",onChange:a=>s("status",a),options:M}),e.jsx(h,{})]}),e.jsx(m,{label:"Role",value:t.role,onChange:a=>s("role",a),options:y.map(a=>({value:a,label:a}))}),e.jsx(h,{}),e.jsx(m,{label:"Priority",value:t.priority,onChange:a=>s("priority",a),options:B}),e.jsx(h,{}),e.jsx(m,{label:"Workflow Type",value:t.type,onChange:a=>s("type",a),options:i.map(a=>({value:a,label:a}))}),n&&e.jsxs(e.Fragment,{children:[e.jsx(h,{}),e.jsx(k,{label:"Search",value:t.search??"",onChange:a=>s("search",a),placeholder:"ID, workflow, origin…"})]})]})}export{V as E,Q as T,G as a,W as m};
|
|
2
|
-
//# sourceMappingURL=escalation-columns-CS0c7cAr.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"escalation-columns-CS0c7cAr.js","sources":["../../src/pages/operator/escalation-columns.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport { Circle, Bell, Clock, ListFilter, Search } from 'lucide-react';\nimport type { Column } from '../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect, FilterInput, FilterDivider } from '../../components/common/data/FilterBar';\nimport { PriorityBadge } from '../../components/common/display/PriorityBadge';\nimport { RolePill } from '../../components/common/display/RolePill';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { CountdownTimer } from '../../components/common/display/CountdownTimer';\nimport { formatAgoCompact } from '../../lib/format';\nimport { isEffectivelyClaimed, isAckEscalation } from '../../lib/escalation';\nimport { metadataFacetUrl } from '../../lib/facet-url';\nimport type { LTEscalationRecord } from '../../api/types';\n\nexport interface EscalationColumnOpts {\n highlightKeys?: string[];\n}\n\n// Shared cell text: a consistent resting shade for every cell, sharpening to\n// the primary text colour when the row is hovered. Cells (and pills via their\n// `inherit` tone) all read this single source so the whole row darkens as one.\nconst CELL_TEXT = 'text-text-secondary transition-colors group-hover/row:text-text-primary';\n\n/** Status dot — rendered inline before summary. */\nfunction StatusDot({ row }: { row: LTEscalationRecord }) {\n if (isAckEscalation(row)) {\n const color = row.status === 'resolved' ? 'text-status-success' : 'text-text-tertiary';\n return <Bell className={`w-3 h-3 shrink-0 ${color}`} />;\n }\n if (row.status === 'resolved') {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-success\" strokeWidth={2.5} />;\n }\n if (row.status === 'cancelled') {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-error\" strokeWidth={2.5} />;\n }\n if (isEffectivelyClaimed(row)) {\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-warning\" strokeWidth={2.5} />;\n }\n // pending (unclaimed)\n return <Circle className=\"w-2.5 h-2.5 shrink-0 text-status-active\" strokeWidth={2.5} />;\n}\n\n/** Key/value metadata dict with 1 row collapsed by default, expand for the rest. */\nexport function MetadataCell({\n metadata,\n role,\n highlightKeys,\n}: {\n metadata: Record<string, unknown> | null;\n role: string;\n highlightKeys?: string[];\n}) {\n const [expanded, setExpanded] = useState(false);\n\n if (!metadata || Object.keys(metadata).length === 0) {\n return <span className=\"text-2xs text-text-tertiary\">—</span>;\n }\n\n const hl = highlightKeys ?? [];\n // Highlighted keys first, then the rest in insertion order.\n const allKeys = [\n ...hl.filter((k) => k in metadata),\n ...Object.keys(metadata).filter((k) => !hl.includes(k)),\n ];\n\n const shown = expanded ? allKeys : allKeys.slice(0, 1);\n const hiddenCount = allKeys.length - 1;\n\n return (\n <div className=\"w-full\" onClick={(e) => e.stopPropagation()}>\n <div className=\"space-y-px\">\n {shown.map((k, i) => {\n const sv = typeof metadata[k] === 'object' && metadata[k] !== null\n ? JSON.stringify(metadata[k])\n : String(metadata[k]);\n const isHl = hl.includes(k);\n const isLastShown = i === shown.length - 1;\n return (\n <div key={k} className=\"group/mrow flex items-center gap-1 min-w-0\">\n <span\n className={`shrink-0 w-14 text-2xs font-mono uppercase tracking-wide truncate ${isHl ? 'text-accent' : 'text-text-tertiary'}`}\n title={k}\n >\n {k}\n </span>\n <span\n className={`flex-1 min-w-0 text-2xs font-medium truncate ${isHl ? 'text-text-primary' : 'text-text-secondary'}`}\n title={sv}\n >\n {sv}\n </span>\n <span className=\"flex items-center gap-px shrink-0 opacity-50 group-hover/mrow:opacity-100 transition-opacity\">\n <Link\n to={metadataFacetUrl(k, metadata[k], role)}\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Filter ${role}: ${k} = ${sv}`}\n onClick={(ev) => ev.stopPropagation()}\n >\n <ListFilter className=\"w-3 h-3\" />\n </Link>\n <Link\n to={metadataFacetUrl(k, metadata[k])}\n className=\"p-0.5 rounded text-text-quaternary hover:text-accent transition-colors\"\n title={`Search all: ${k} = ${sv}`}\n onClick={(ev) => ev.stopPropagation()}\n >\n <Search className=\"w-3 h-3\" />\n </Link>\n </span>\n {/* +N inline at end of single visible row when collapsed */}\n {!expanded && hiddenCount > 0 && (\n <button\n onClick={(ev) => { ev.stopPropagation(); setExpanded(true); }}\n className=\"shrink-0 text-2xs text-text-quaternary hover:text-accent transition-colors font-mono\"\n title={`Show ${hiddenCount} more fields`}\n >\n +{hiddenCount}\n </button>\n )}\n {/* ↑ inline at end of last row when expanded */}\n {expanded && isLastShown && hiddenCount > 0 && (\n <button\n onClick={(ev) => { ev.stopPropagation(); setExpanded(false); }}\n className=\"shrink-0 text-2xs text-text-quaternary hover:text-accent transition-colors\"\n title=\"Show less\"\n >\n ↑\n </button>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n/** Build the shared column set, optionally wiring metadata filter callbacks. */\nexport function makeEscalationColumns(opts: EscalationColumnOpts = {}): Column<LTEscalationRecord>[] {\n return [\n {\n key: 'description',\n label: 'Summary',\n priority: 1,\n render: (row) => (\n <div className=\"flex items-center gap-2 overflow-hidden\">\n <span className=\"shrink-0\"><StatusDot row={row} /></span>\n <span className={`truncate text-xs ${CELL_TEXT}`}>{row.description || row.type}</span>\n </div>\n ),\n className: 'max-w-0',\n },\n // The manufacturing-floor column budget: identity, owner, urgency, age.\n // Everything else (workflow type, metadata, exact timestamps) lives in\n // the facet drawer and the detail page — never as a scrolling column.\n {\n key: 'role',\n label: 'Role',\n priority: 2,\n render: (row) => (\n <span className={CELL_TEXT}>\n <RolePill role={row.role} size=\"md\" tone=\"inherit\" />\n </span>\n ),\n className: 'w-28',\n },\n {\n key: 'priority',\n label: 'Priority',\n priority: 2,\n render: (row) => (\n <span className={CELL_TEXT}>\n <PriorityBadge priority={row.priority} size=\"sm\" tone=\"inherit\" />\n </span>\n ),\n className: 'w-20',\n },\n // Enrichment columns — the jumping-off facets. The budget governs the\n // floor: these return only when the table has room (@split / @wall),\n // and in card mode they fold to pairs. The metadata cell carries the\n // clickable refine icons: filter within the role, search across roles\n // (admins), shift+click to AND facets.\n {\n key: 'workflow_type',\n label: 'Workflow',\n priority: 2,\n showFrom: 'split',\n render: (row) => <WorkflowPill type={row.workflow_type || row.type} />,\n className: 'w-40 whitespace-nowrap',\n },\n {\n key: 'metadata',\n label: 'Metadata',\n priority: 2,\n showFrom: 'wall',\n render: (row) => (\n <MetadataCell\n metadata={row.metadata}\n role={row.role}\n highlightKeys={opts.highlightKeys}\n />\n ),\n className: 'w-80 max-w-[19rem] align-top',\n },\n {\n key: 'created_at',\n label: 'Ago',\n priority: 1,\n render: (row) => (\n <span className={`text-xs tabular-nums ${CELL_TEXT}`} title={row.created_at}>\n {formatAgoCompact(row.created_at)}\n </span>\n ),\n className: 'w-14 whitespace-nowrap',\n },\n ];\n}\n\n/** Base columns shared by all escalation list pages (no filter callback). */\nexport const ESCALATION_COLUMNS: Column<LTEscalationRecord>[] = makeEscalationColumns();\n\n/** Time-remaining column for claimed escalations — aligns with checkbox column on All Escalations. */\nexport const TIME_LEFT_COLUMN: Column<LTEscalationRecord> = {\n key: 'expires',\n label: (<Clock className=\"w-3.5 h-3.5 text-text-tertiary\" />) as any,\n render: (row) =>\n row.assigned_until ? (\n <CountdownTimer until={row.assigned_until} />\n ) : (\n <span className=\"text-xs text-text-tertiary\">—</span>\n ),\n className: 'w-16 whitespace-nowrap',\n priority: 1,\n};\n\n/** Status icon column — color-coded filled circle, or bell for ACK/notification escalations. */\nexport const STATUS_COLUMN: Column<LTEscalationRecord> = {\n key: 'status',\n label: '',\n render: (row) => {\n if (isAckEscalation(row)) {\n const color = row.status === 'resolved' ? 'text-status-success' : 'text-text-tertiary';\n return <Bell className={`w-3 h-3 ${color}`} />;\n }\n if (row.status === 'resolved') {\n return <Circle className=\"w-2.5 h-2.5 text-status-success\" strokeWidth={2.5} />;\n }\n if (isEffectivelyClaimed(row)) {\n return <Circle className=\"w-2.5 h-2.5 text-status-warning\" strokeWidth={2.5} />;\n }\n // pending (unclaimed)\n return <Circle className=\"w-2.5 h-2.5 text-text-tertiary\" strokeWidth={2.5} />;\n },\n className: 'w-8',\n priority: 1,\n};\n\n/** Claimed-only status icon (always orange, or bell for ACK). */\nexport const CLAIMED_STATUS_COLUMN: Column<LTEscalationRecord> = {\n key: 'status',\n label: '',\n render: (row) =>\n isAckEscalation(row)\n ? <Bell className=\"w-3 h-3 text-status-warning\" />\n : <Circle className=\"w-2.5 h-2.5 text-status-warning\" strokeWidth={2.5} />,\n className: 'w-8',\n priority: 1,\n};\n\n/** Priority filter options shared by both pages. */\nexport const PRIORITY_OPTIONS = [\n { value: '1', label: 'P1' },\n { value: '2', label: 'P2' },\n { value: '3', label: 'P3' },\n { value: '4', label: 'P4' },\n];\n\n/** Status filter options for escalation list pages. `all` spans every status so a\n * metadata search (e.g. one order id) returns its escalations regardless of status. */\nexport const STATUS_OPTIONS = [\n { value: 'all', label: 'All' },\n { value: 'available', label: 'Available' },\n { value: 'claimed', label: 'Claimed' },\n { value: 'resolved', label: 'Resolved' },\n { value: 'cancelled', label: 'Cancelled' },\n { value: 'expired', label: 'Expired' },\n];\n\n/** Shared filter bar for escalation list pages. */\nexport function EscalationFilterBar({\n filters,\n setFilter,\n roles,\n types,\n showStatus = false,\n showSearch = true,\n actions,\n}: {\n filters: { role: string; type: string; priority: string; status?: string; search?: string };\n setFilter: (key: any, value: string) => void;\n roles: string[];\n types: string[];\n showStatus?: boolean;\n // Free-text search lives here by default, but the faceted page folds it into\n // the drawer instead so there's a single search surface.\n showSearch?: boolean;\n actions?: React.ReactNode;\n}) {\n // Non-default filters power the folded Filters button's badge.\n const activeFilterCount = [\n filters.role,\n filters.type,\n filters.priority,\n filters.status && filters.status !== 'all' ? filters.status : '',\n filters.search ?? '',\n ].filter(Boolean).length;\n\n return (\n <FilterBar actions={actions} activeFilterCount={activeFilterCount}>\n {showStatus && (\n <>\n <FilterSelect\n label=\"Status\"\n value={filters.status ?? ''}\n onChange={(v) => setFilter('status', v)}\n options={STATUS_OPTIONS}\n />\n <FilterDivider />\n </>\n )}\n {/* Role is the queue's primary facet — always present, always URL-driven\n (?role=). Pages whose title doubles as a queue selector share the same\n param, so the two controls mirror each other. */}\n <FilterSelect\n label=\"Role\"\n value={filters.role}\n onChange={(v) => setFilter('role', v)}\n options={roles.map((r) => ({ value: r, label: r }))}\n />\n <FilterDivider />\n <FilterSelect\n label=\"Priority\"\n value={filters.priority}\n onChange={(v) => setFilter('priority', v)}\n options={PRIORITY_OPTIONS}\n />\n <FilterDivider />\n <FilterSelect\n label=\"Workflow Type\"\n value={filters.type}\n onChange={(v) => setFilter('type', v)}\n options={types.map((t) => ({ value: t, label: t }))}\n />\n {showSearch && (\n <>\n <FilterDivider />\n <FilterInput\n label=\"Search\"\n value={filters.search ?? ''}\n onChange={(v) => setFilter('search', v)}\n placeholder=\"ID, workflow, origin…\"\n />\n </>\n )}\n </FilterBar>\n );\n}\n"],"names":["CELL_TEXT","StatusDot","row","isAckEscalation","color","jsx","Bell","Circle","isEffectivelyClaimed","MetadataCell","metadata","role","highlightKeys","expanded","setExpanded","useState","hl","allKeys","k","shown","hiddenCount","e","i","sv","isHl","isLastShown","jsxs","Link","metadataFacetUrl","ev","ListFilter","Search","makeEscalationColumns","opts","RolePill","PriorityBadge","WorkflowPill","formatAgoCompact","ESCALATION_COLUMNS","TIME_LEFT_COLUMN","Clock","CountdownTimer","PRIORITY_OPTIONS","STATUS_OPTIONS","EscalationFilterBar","filters","setFilter","roles","types","showStatus","showSearch","actions","activeFilterCount","FilterBar","Fragment","FilterSelect","v","FilterDivider","r","t","FilterInput"],"mappings":"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"}
|