@sparkelf/dsh-task-bus 0.1.6 → 0.1.7
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/lib/client.js +235 -3
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -785,6 +785,202 @@ window.__ModuleLoader__.load({
|
|
|
785
785
|
]
|
|
786
786
|
});
|
|
787
787
|
};
|
|
788
|
+
const KB_TASK_QUEUE_KEY = "dataops-kb-task-queue-v1";
|
|
789
|
+
const KB_TASK_TTL_MS = 6048e5;
|
|
790
|
+
const KB_TASK_MAX = 200;
|
|
791
|
+
const KB_STAGE_LABEL = {
|
|
792
|
+
uploading: "上传中",
|
|
793
|
+
uploaded: "上传完成",
|
|
794
|
+
extracting: "提取中",
|
|
795
|
+
done: "提取完成",
|
|
796
|
+
failed: "失败"
|
|
797
|
+
};
|
|
798
|
+
/** Read the KB task queue from the shared localStorage key. */
|
|
799
|
+
function readKbTasks(now = Date.now()) {
|
|
800
|
+
try {
|
|
801
|
+
const raw = window.localStorage.getItem(KB_TASK_QUEUE_KEY);
|
|
802
|
+
if (raw === null || raw === "") return [];
|
|
803
|
+
const parsed = JSON.parse(raw);
|
|
804
|
+
if (!Array.isArray(parsed)) return [];
|
|
805
|
+
const records = [];
|
|
806
|
+
for (const entry of parsed) {
|
|
807
|
+
if (entry === null || typeof entry !== "object") continue;
|
|
808
|
+
const row = entry;
|
|
809
|
+
if (typeof row.id !== "string" || row.id === "") continue;
|
|
810
|
+
if (typeof row.fileName !== "string" || row.fileName === "") continue;
|
|
811
|
+
if (row.kind !== "upload" && row.kind !== "extract") continue;
|
|
812
|
+
if (typeof row.stage !== "string" || !(row.stage in KB_STAGE_LABEL)) continue;
|
|
813
|
+
if (typeof row.startedAt !== "number" || !Number.isFinite(row.startedAt)) continue;
|
|
814
|
+
if (now - row.startedAt > KB_TASK_TTL_MS) continue;
|
|
815
|
+
records.push({
|
|
816
|
+
id: row.id,
|
|
817
|
+
fileName: row.fileName,
|
|
818
|
+
kind: row.kind,
|
|
819
|
+
stage: row.stage,
|
|
820
|
+
...typeof row.progress === "number" && Number.isFinite(row.progress) ? { progress: row.progress } : {},
|
|
821
|
+
startedAt: row.startedAt,
|
|
822
|
+
...typeof row.finishedAt === "number" && Number.isFinite(row.finishedAt) ? { finishedAt: row.finishedAt } : {},
|
|
823
|
+
...typeof row.error === "string" && row.error !== "" ? { error: row.error } : {}
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
return records.sort((a, b) => b.startedAt - a.startedAt).slice(0, KB_TASK_MAX);
|
|
827
|
+
} catch {
|
|
828
|
+
return [];
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
/** The "notifications" tab: the KB task queue, read from the shared key. */
|
|
832
|
+
function KbNotificationPanel({ tasks, onClear }) {
|
|
833
|
+
const done = tasks.filter((task) => task.stage === "done" || task.stage === "uploaded").length;
|
|
834
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
835
|
+
style: {
|
|
836
|
+
display: "flex",
|
|
837
|
+
flexDirection: "column",
|
|
838
|
+
gap: 10
|
|
839
|
+
},
|
|
840
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
841
|
+
style: {
|
|
842
|
+
display: "flex",
|
|
843
|
+
alignItems: "center",
|
|
844
|
+
justifyContent: "space-between",
|
|
845
|
+
gap: 8
|
|
846
|
+
},
|
|
847
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
848
|
+
style: {
|
|
849
|
+
display: "flex",
|
|
850
|
+
alignItems: "baseline",
|
|
851
|
+
gap: 8
|
|
852
|
+
},
|
|
853
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
854
|
+
style: {
|
|
855
|
+
fontSize: 13,
|
|
856
|
+
fontWeight: 600,
|
|
857
|
+
color: colors.text
|
|
858
|
+
},
|
|
859
|
+
children: "任务队列"
|
|
860
|
+
}), tasks.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
861
|
+
style: {
|
|
862
|
+
fontSize: 12,
|
|
863
|
+
color: "#8ea6c6"
|
|
864
|
+
},
|
|
865
|
+
children: [
|
|
866
|
+
done,
|
|
867
|
+
"/",
|
|
868
|
+
tasks.length
|
|
869
|
+
]
|
|
870
|
+
}) : null]
|
|
871
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
872
|
+
size: "sm",
|
|
873
|
+
variant: "ghost",
|
|
874
|
+
disabled: tasks.length === 0,
|
|
875
|
+
onClick: onClear,
|
|
876
|
+
children: "清空记录"
|
|
877
|
+
})]
|
|
878
|
+
}), tasks.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
879
|
+
style: {
|
|
880
|
+
padding: 18,
|
|
881
|
+
textAlign: "center",
|
|
882
|
+
color: colors.muted,
|
|
883
|
+
fontSize: 12
|
|
884
|
+
},
|
|
885
|
+
children: "暂无通知"
|
|
886
|
+
}) : tasks.map((task) => {
|
|
887
|
+
const percent = Math.max(0, Math.min(100, Math.round(task.progress ?? (task.stage === "done" ? 100 : task.stage === "uploaded" ? 25 : 0))));
|
|
888
|
+
const tone = task.stage === "failed" ? colors.danger : task.stage === "done" || task.stage === "uploaded" ? colors.success : colors.accent;
|
|
889
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
890
|
+
style: {
|
|
891
|
+
padding: "10px 12px",
|
|
892
|
+
border: "1px solid " + colors.line,
|
|
893
|
+
borderRadius: 8,
|
|
894
|
+
background: colors.panelAlt,
|
|
895
|
+
display: "flex",
|
|
896
|
+
flexDirection: "column",
|
|
897
|
+
gap: 6
|
|
898
|
+
},
|
|
899
|
+
children: [
|
|
900
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
901
|
+
style: {
|
|
902
|
+
display: "flex",
|
|
903
|
+
alignItems: "center",
|
|
904
|
+
gap: 8
|
|
905
|
+
},
|
|
906
|
+
children: [
|
|
907
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
908
|
+
style: {
|
|
909
|
+
flex: 1,
|
|
910
|
+
minWidth: 0,
|
|
911
|
+
overflow: "hidden",
|
|
912
|
+
textOverflow: "ellipsis",
|
|
913
|
+
whiteSpace: "nowrap",
|
|
914
|
+
fontSize: 12,
|
|
915
|
+
fontWeight: 500,
|
|
916
|
+
color: colors.text
|
|
917
|
+
},
|
|
918
|
+
children: task.fileName
|
|
919
|
+
}),
|
|
920
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
921
|
+
style: {
|
|
922
|
+
fontSize: 10,
|
|
923
|
+
color: colors.muted
|
|
924
|
+
},
|
|
925
|
+
children: new Date(task.startedAt).toLocaleTimeString("zh-CN", {
|
|
926
|
+
hour: "2-digit",
|
|
927
|
+
minute: "2-digit"
|
|
928
|
+
})
|
|
929
|
+
}),
|
|
930
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
931
|
+
style: {
|
|
932
|
+
fontSize: 10,
|
|
933
|
+
color: tone,
|
|
934
|
+
whiteSpace: "nowrap"
|
|
935
|
+
},
|
|
936
|
+
children: KB_STAGE_LABEL[task.stage]
|
|
937
|
+
})
|
|
938
|
+
]
|
|
939
|
+
}),
|
|
940
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
941
|
+
style: {
|
|
942
|
+
display: "flex",
|
|
943
|
+
alignItems: "center",
|
|
944
|
+
gap: 8
|
|
945
|
+
},
|
|
946
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
947
|
+
style: {
|
|
948
|
+
flex: 1,
|
|
949
|
+
height: 6,
|
|
950
|
+
borderRadius: 999,
|
|
951
|
+
background: "rgba(255,255,255,.08)",
|
|
952
|
+
overflow: "hidden"
|
|
953
|
+
},
|
|
954
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
955
|
+
width: String(percent) + "%",
|
|
956
|
+
height: "100%",
|
|
957
|
+
borderRadius: 999,
|
|
958
|
+
background: tone,
|
|
959
|
+
transition: "width 120ms linear"
|
|
960
|
+
} })
|
|
961
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
962
|
+
style: {
|
|
963
|
+
minWidth: 34,
|
|
964
|
+
textAlign: "right",
|
|
965
|
+
fontSize: 11,
|
|
966
|
+
color: colors.muted,
|
|
967
|
+
fontVariantNumeric: "tabular-nums"
|
|
968
|
+
},
|
|
969
|
+
children: String(percent) + "%"
|
|
970
|
+
})]
|
|
971
|
+
}),
|
|
972
|
+
task.error !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
973
|
+
style: {
|
|
974
|
+
fontSize: 11,
|
|
975
|
+
color: colors.danger
|
|
976
|
+
},
|
|
977
|
+
children: task.error
|
|
978
|
+
}) : null
|
|
979
|
+
]
|
|
980
|
+
}, task.id);
|
|
981
|
+
})]
|
|
982
|
+
});
|
|
983
|
+
}
|
|
788
984
|
const TaskCenterButton = ({ openSession }) => {
|
|
789
985
|
const [open, setOpen] = (0, react.useState)(false);
|
|
790
986
|
const [tasks, setTasks] = (0, react.useState)([]);
|
|
@@ -796,6 +992,7 @@ window.__ModuleLoader__.load({
|
|
|
796
992
|
const [selected, setSelected] = (0, react.useState)(null);
|
|
797
993
|
const [anchor, setAnchor] = (0, react.useState)(null);
|
|
798
994
|
const [pendingCount, setPendingCount] = (0, react.useState)(0);
|
|
995
|
+
const [kbTasks, setKbTasks] = (0, react.useState)(() => readKbTasks());
|
|
799
996
|
(0, react.useEffect)(() => {
|
|
800
997
|
if (document.getElementById(TASK_BUS_STYLE_ID) !== null) return;
|
|
801
998
|
const style = document.createElement("style");
|
|
@@ -877,6 +1074,28 @@ window.__ModuleLoader__.load({
|
|
|
877
1074
|
window.clearInterval(timer);
|
|
878
1075
|
};
|
|
879
1076
|
}, []);
|
|
1077
|
+
(0, react.useEffect)(() => {
|
|
1078
|
+
let alive = true;
|
|
1079
|
+
const sync = () => {
|
|
1080
|
+
if (alive) setKbTasks(readKbTasks());
|
|
1081
|
+
};
|
|
1082
|
+
const timer = window.setInterval(sync, 1e3);
|
|
1083
|
+
const onStorage = (event) => {
|
|
1084
|
+
if (event.key === KB_TASK_QUEUE_KEY) sync();
|
|
1085
|
+
};
|
|
1086
|
+
window.addEventListener("storage", onStorage);
|
|
1087
|
+
return () => {
|
|
1088
|
+
alive = false;
|
|
1089
|
+
window.clearInterval(timer);
|
|
1090
|
+
window.removeEventListener("storage", onStorage);
|
|
1091
|
+
};
|
|
1092
|
+
}, []);
|
|
1093
|
+
const clearKbTasks = () => {
|
|
1094
|
+
try {
|
|
1095
|
+
window.localStorage.removeItem(KB_TASK_QUEUE_KEY);
|
|
1096
|
+
} catch {}
|
|
1097
|
+
setKbTasks([]);
|
|
1098
|
+
};
|
|
880
1099
|
const filtered = (0, react.useMemo)(() => {
|
|
881
1100
|
if (tab === "group") return tasks.filter((task) => task.sourceType === "task_bus" && task.source.type.includes("group"));
|
|
882
1101
|
if (tab === "mine") return tasks.filter((task) => task.status !== "completed" && task.status !== "cancelled");
|
|
@@ -884,6 +1103,7 @@ window.__ModuleLoader__.load({
|
|
|
884
1103
|
return tasks;
|
|
885
1104
|
}, [tasks, tab]);
|
|
886
1105
|
const actionable = tasks.filter((task) => task.status !== "completed" && task.status !== "cancelled").length;
|
|
1106
|
+
const kbPending = kbTasks.filter((task) => task.stage === "uploading" || task.stage === "extracting").length;
|
|
887
1107
|
const tabItems = [
|
|
888
1108
|
{
|
|
889
1109
|
value: "all",
|
|
@@ -920,6 +1140,15 @@ window.__ModuleLoader__.load({
|
|
|
920
1140
|
style: { opacity: .55 },
|
|
921
1141
|
children: tasks.filter((task) => task.sourceType === "task_bus" && task.source.type.includes("group")).length
|
|
922
1142
|
})] })
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
value: "notifications",
|
|
1146
|
+
id: "task-bus-tab-notifications",
|
|
1147
|
+
panelId: "task-bus-panel-notifications",
|
|
1148
|
+
label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["通知 ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1149
|
+
style: { opacity: .55 },
|
|
1150
|
+
children: kbPending
|
|
1151
|
+
})] })
|
|
923
1152
|
}
|
|
924
1153
|
];
|
|
925
1154
|
const transition = async (task, action) => {
|
|
@@ -996,7 +1225,7 @@ window.__ModuleLoader__.load({
|
|
|
996
1225
|
strokeLinejoin: "round",
|
|
997
1226
|
"aria-hidden": "true",
|
|
998
1227
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M13.7 21a2 2 0 0 1-3.4 0" })]
|
|
999
|
-
}), pendingCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1228
|
+
}), pendingCount + kbPending > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1000
1229
|
style: {
|
|
1001
1230
|
position: "absolute",
|
|
1002
1231
|
bottom: -2,
|
|
@@ -1012,7 +1241,7 @@ window.__ModuleLoader__.load({
|
|
|
1012
1241
|
lineHeight: "14px",
|
|
1013
1242
|
textAlign: "center"
|
|
1014
1243
|
},
|
|
1015
|
-
children: pendingCount > 99 ? "99+" : pendingCount
|
|
1244
|
+
children: pendingCount + kbPending > 99 ? "99+" : pendingCount + kbPending
|
|
1016
1245
|
}) : null]
|
|
1017
1246
|
}) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1018
1247
|
open,
|
|
@@ -1108,7 +1337,10 @@ window.__ModuleLoader__.load({
|
|
|
1108
1337
|
overflowY: "auto",
|
|
1109
1338
|
flex: 1
|
|
1110
1339
|
},
|
|
1111
|
-
children:
|
|
1340
|
+
children: tab === "notifications" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(KbNotificationPanel, {
|
|
1341
|
+
tasks: kbTasks,
|
|
1342
|
+
onClear: clearKbTasks
|
|
1343
|
+
}) : selected !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TaskDetail, {
|
|
1112
1344
|
task: selected,
|
|
1113
1345
|
onBack: () => setSelected(null)
|
|
1114
1346
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["Tag","Button","useState","useMemo","Modal","IconCloseOutlineRegular","SegmentedTabs"],"sources":["../src/client/theme.ts","../src/client/index.tsx"],"sourcesContent":["/** Palette aliases the Task Center draws with; the shell owns the values. */\n\nexport const colors = {\n panel: 'var(--dsw-alias-bg-layer-1, #ffffff)',\n panelAlt: 'var(--dsw-alias-bg-layer-2, #f7f8fa)',\n text: 'var(--dsw-alias-label-primary, #111827)',\n muted: 'var(--dsw-alias-label-secondary, #6b7280)',\n line: 'var(--dsw-alias-border-l1, #e5e7eb)',\n accent: 'var(--dsw-alias-brand-primary, #2563eb)',\n accentSoft: 'var(--dsw-alias-brand-primary-alpha, #eff6ff)',\n warning: 'var(--dsw-alias-state-warning, #b45309)',\n success: 'var(--dsw-alias-state-success, #047857)',\n danger: 'var(--dsw-alias-state-danger, #b91c1c)',\n}","/**\n * The Task Center surface in the frame-wide overlay.\n *\n * The button is global because a task can arrive while the reader is in any\n * session. The panel only renders cards returned by the Host bridge; it never\n * talks to DataOps directly and never derives a second approval status.\n */\nimport { useEffect, useMemo, useState, type CSSProperties } from 'react'\nimport {\n Button,\n IconCloseOutlineRegular,\n Modal,\n SegmentedTabs,\n Tag,\n type SegmentedTab,\n type TagTone,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport { colors } from './theme.ts'\n\nexport const inject = ['slots', 'locale', 'uiWorkspace', 'sessions', 'sidebarRight']\n\ninterface TaskItem {\n id: string\n sourceType: 'dataops_approval' | 'task_bus'\n title: string\n code?: string\n description?: string | null\n status: string\n statusLabel: string\n priority?: string | null\n tags?: string[]\n source: {\n type: string\n id?: string | null\n label?: string | null\n workflowCode?: string | null\n deepLink?: string | null\n }\n assignee?: { type: string; id: string } | null\n creator?: { type: string; id: string } | null\n actions?: string[]\n dueAt?: string | null\n updatedAt: string\n /** Connector that produced the row, when the Host carries it. */\n connectorId?: string\n /** Capability that produced the row, when the Host carries it. */\n capabilityId?: string\n}\n\nconst ROUTE = '/dsh-task-bus/api'\n\nconst TASK_BUS_MODAL_CLASS = 'task-bus-center-modal'\nconst TASK_BUS_HISTORY_CLASS = 'task-bus-history-modal'\nconst TASK_BUS_STYLE_ID = 'task-bus-center-modal-style'\nconst TASK_BUS_MODAL_CSS = `\n.${TASK_BUS_MODAL_CLASS} {\n width: min(960px, calc(100vw - 64px)) !important;\n height: min(760px, calc(100vh - 64px)) !important;\n gap: 0 !important;\n padding: 0 !important;\n}\n@media (max-width: 700px) {\n .${TASK_BUS_MODAL_CLASS} {\n width: calc(100vw - 24px) !important;\n height: calc(100vh - 24px) !important;\n }\n}\n.${TASK_BUS_HISTORY_CLASS} {\n width: min(960px, 92vw) !important;\n max-width: calc(100vw - 32px) !important;\n height: auto !important;\n max-height: min(780px, calc(100vh - 48px)) !important;\n}\n@media (max-width: 700px) {\n .${TASK_BUS_HISTORY_CLASS} {\n width: calc(100vw - 24px) !important;\n max-width: calc(100vw - 24px) !important;\n max-height: calc(100vh - 24px) !important;\n }\n}\n`\n\nconst HISTORY_NS = 'task-bus.history'\nconst HISTORY_COPY = {\n zh: {\n title: '消息记录',\n open: '消息记录',\n close: '关闭',\n searchPlaceholder: '搜索消息或发送人…',\n searchLabel: '搜索消息记录',\n clear: '清空搜索',\n initial: '输入关键词搜索消息或发送人',\n initialHint: '可按消息正文或发送人筛选,点结果跳到原消息。',\n loading: '正在加载消息记录…',\n error: '消息记录加载失败',\n empty: '暂无消息记录',\n noResults: '没有匹配的消息',\n jump: '跳到该消息',\n me: '我',\n assistant: '助手',\n dateLocale: 'zh-CN',\n },\n en: {\n title: 'Message history',\n open: 'Message history',\n close: 'Close',\n searchPlaceholder: 'Search messages or senders…',\n searchLabel: 'Search message history',\n clear: 'Clear search',\n initial: 'Search messages or senders to begin',\n initialHint: 'Filter by message text or sender, then click a result to jump to it.',\n loading: 'Loading message history…',\n error: 'Could not load message history',\n empty: 'No message history',\n noResults: 'No matching messages',\n jump: 'Jump to message',\n me: 'Me',\n assistant: 'Assistant',\n dateLocale: 'en-US',\n },\n} as const\n\ntype HistoryCopyKey = keyof typeof HISTORY_COPY.zh\ntype HistoryTranslate = (key: HistoryCopyKey) => string\n\nconst buttonStyle: CSSProperties = {\n border: '1px solid ' + colors.line,\n background: colors.panel,\n color: colors.text,\n borderRadius: 8,\n padding: '7px 11px',\n fontSize: 12,\n cursor: 'pointer',\n}\n\nconst statusTagTone = (status: string): TagTone => {\n if (status === 'completed') return 'success'\n if (status === 'cancelled') return 'neutral'\n if (status === 'blocked') return 'danger'\n if (status === 'pending_confirm' || status === 'returned' || status === 'pending_accept') return 'warning'\n return 'info'\n}\n\nconst relativeTime = (value: string) => {\n const time = Date.parse(value)\n if (!Number.isFinite(time)) return ''\n const minutes = Math.max(0, Math.round((Date.now() - time) / 60_000))\n if (minutes < 1) return '刚刚'\n if (minutes < 60) return String(minutes) + ' 分钟前'\n const hours = Math.round(minutes / 60)\n if (hours < 24) return String(hours) + ' 小时前'\n return String(Math.round(hours / 24)) + ' 天前'\n}\n\nconst fetchJson = async <T,>(path: string, options: { signal?: AbortSignal } = {}): Promise<T> => {\n const attempt = async () => {\n const response = await fetch(ROUTE + path, { headers: { accept: 'application/json' }, signal: options.signal })\n // Read the body as text first: a 502 from the flow service may carry a JSON\n // error object, plain text, or an empty body, and `response.json()` turns the\n // last two into a parse error that hides the status from the caller.\n let text = ''\n let bodyFailure = false\n try { text = await response.text() } catch { bodyFailure = true }\n let payload: unknown = null\n if (text.trim() !== '') {\n try { payload = JSON.parse(text) as unknown } catch { payload = null }\n }\n return { response, status: response.status, payload, text, bodyFailure }\n }\n // One retry covers a connection reset that drops the response body: the host\n // proxy can lose the upstream 502 on the first connection while the next\n // request reads the very same error. An abort from the caller never retries.\n const request = async () => {\n try {\n const first = await attempt()\n if (!first.bodyFailure) return first\n await new Promise((resolve) => setTimeout(resolve, 250))\n return await attempt()\n } catch (cause) {\n if (options.signal?.aborted) throw cause\n await new Promise((resolve) => setTimeout(resolve, 250))\n return await attempt()\n }\n }\n let result = await request()\n // The managed session handshake runs in parallel with the panel mount; a 401\n // here is usually \"the cookie is not set yet\", not an authorization failure.\n if (result.status === 401) {\n await new Promise((resolve) => setTimeout(resolve, 900))\n result = await request()\n }\n if (!result.response.ok) {\n const serverMessage = result.payload !== null && typeof result.payload === 'object'\n ? (typeof (result.payload as { error?: unknown }).error === 'string' ? (result.payload as { error: string }).error\n : typeof (result.payload as { message?: unknown }).message === 'string' ? (result.payload as { message: string }).message\n : '')\n : ''\n // A server answer that carries readable text always wins over the status\n // fallback, so an explicit {\"error\":\"…\"} stays exactly as the server sent it.\n const message = serverMessage !== ''\n ? serverMessage\n : result.bodyFailure\n ? 'HTTP ' + result.status + '(响应体读取失败)'\n : result.text.trim() !== ''\n ? result.text.trim().slice(0, 200)\n : 'HTTP ' + result.status\n throw new Error(message)\n }\n if (result.bodyFailure) throw new Error('HTTP ' + result.status + '(响应体读取失败)')\n return result.payload as T\n}\n\n\nconst approvalHref = (raw: string | null): string | null => {\n if (raw === null) return null\n try {\n const target = new URL(raw)\n const referrer = document.referrer ? new URL(document.referrer) : null\n if (referrer !== null && referrer.origin !== target.origin) {\n return referrer.origin + target.pathname + target.search + target.hash\n }\n return target.href\n } catch {\n return raw\n }\n}\n\nconst TaskCard = ({\n task,\n busy,\n aiBusy,\n onTransition,\n onAiAccept,\n onOpen,\n}: {\n task: TaskItem\n busy: boolean\n aiBusy: boolean\n onTransition: (task: TaskItem, action: string) => void\n onAiAccept: (task: TaskItem) => void\n onOpen: (task: TaskItem) => void\n}) => {\n const isApproval = task.sourceType === 'dataops_approval'\n const deepLink = approvalHref(task.source.deepLink ?? null)\n return (\n <article\n style={{\n border: '1px solid ' + colors.line,\n borderRadius: 10,\n background: colors.panel,\n padding: '12px 13px',\n display: 'grid',\n gap: 8,\n }}\n >\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 7, flexWrap: 'wrap', marginBottom: 4 }}>\n <Tag tone={isApproval ? 'info' : 'neutral'}>\n {isApproval ? (task.source.label ?? 'DataOps 审批') : '任务总线'}\n </Tag>\n {task.tags?.map((tag) => (\n <Tag key={tag} tone=\"quiet\">{tag}</Tag>\n ))}\n </div>\n <div style={{ fontSize: 13, fontWeight: 650, color: colors.text, lineHeight: 1.45 }}>\n {task.title}\n </div>\n {task.description ? (\n <div style={{ fontSize: 11, color: colors.muted, marginTop: 4, lineHeight: 1.5 }}>\n {task.description}\n </div>\n ) : null}\n </div>\n <span style={{ flex: 'none' }}><Tag tone={statusTagTone(task.status)}>{task.statusLabel}</Tag></span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', fontSize: 10, color: colors.muted }}>\n <span>{isApproval ? '审批任务' : '任务'}</span>\n {task.assignee?.id ? <span>受理人:{task.assignee.id}</span> : null}\n <span style={{ marginLeft: 'auto' }}>{relativeTime(task.updatedAt)}</span>\n </div>\n <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>\n {isApproval && deepLink ? (\n <Button size=\"sm\" variant=\"primary\" onClick={() => window.open(deepLink, '_blank', 'noopener,noreferrer')}>\n 办理\n </Button>\n ) : null}\n {task.status !== 'completed' && task.status !== 'cancelled' ? (\n <Button size=\"sm\" variant=\"outline\" disabled={aiBusy || busy} onClick={() => onAiAccept(task)}>\n {aiBusy ? '受理中…' : 'AI受理'}\n </Button>\n ) : null}\n <Button size=\"sm\" variant=\"ghost\" onClick={() => onOpen(task)}>详情</Button>\n {!isApproval && task.status === 'pending_accept' ? (\n <Button size=\"sm\" variant=\"primary\" disabled={busy} onClick={() => onTransition(task, 'accept')}>受理</Button>\n ) : null}\n {!isApproval && task.status === 'in_progress' ? (\n <Button size=\"sm\" variant=\"outline\" disabled={busy} onClick={() => onTransition(task, 'submit')}>提交确认</Button>\n ) : null}\n {!isApproval && task.status === 'pending_confirm' ? (\n <Button size=\"sm\" variant=\"primary\" disabled={busy} onClick={() => onTransition(task, 'complete')}>完成</Button>\n ) : null}\n {!isApproval && task.status !== 'completed' && task.status !== 'cancelled' ? (\n <Button size=\"sm\" variant=\"ghost\" disabled={busy} onClick={() => onTransition(task, 'cancel')}>取消</Button>\n ) : null}\n </div>\n </article>\n )\n}\n\n\ninterface TaskAttachmentRecord {\n id: string\n originalName: string\n contentType: string\n sizeBytes: number\n kind: string\n}\n\ninterface FormFieldData {\n key: string\n label: string\n value: unknown\n type?: 'multiline' | 'resources'\n span?: 1 | 2\n}\n\ninterface FormSectionData {\n title: string\n fields: FormFieldData[]\n}\n\ninterface TaskDetailPayload {\n id?: number | string\n payload?: {\n form?: Record<string, unknown>\n selectedItems?: Array<Record<string, unknown>>\n resourceAccessRequest?: {\n form?: Record<string, unknown>\n selectedItems?: Array<Record<string, unknown>>\n }\n }\n form?: { sections?: FormSectionData[] }\n attachments?: TaskAttachmentRecord[]\n}\n\nconst FORM_LABELS: Record<string, string> = {\n applicationMode: '申请方式',\n requestKind: '申请类型',\n requestedPermissions: '申请权限',\n requesterDepartment: '申请人部门',\n requesterPhone: '申请人电话',\n validFrom: '授权开始时间',\n expiresAt: '授权结束时间',\n selectionSummary: '资源摘要',\n code: '应用编码',\n name: '应用名称',\n reason: '申请理由',\n description: '应用说明',\n departmentName: '归属部门',\n departmentCode: '归属部门编码',\n ownerName: '归属负责人',\n ownerPhone: '归属负责人电话',\n constructionUnit: '建设单位',\n constructionOwner: '建设单位负责人',\n constructionOwnerPhone: '建设单位负责人电话',\n operationsUnit: '运维单位',\n operationsOwner: '运维单位负责人',\n operationsOwnerPhone: '运维单位负责人电话',\n requestTime: '申请时间',\n resourceName: '资源名称',\n resourceType: '资源类型',\n accessType: '访问方式',\n accessScope: '访问范围',\n applicationName: '所属应用',\n applicationCode: '应用编码',\n environment: '环境',\n accountCount: '账号数量',\n}\n\nconst SKIP_FORM_KEYS = new Set([\n 'ownerUserId',\n 'requesterUserId',\n 'requesterDept',\n 'existingApplicationId',\n 'applicationId',\n 'taskType',\n])\n\nconst formatBytes = (bytes: number) => {\n if (!Number.isFinite(bytes) || bytes < 0) return ''\n if (bytes < 1024) return bytes + ' B'\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB'\n}\n\nconst humanizeField = (key: string) => key\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .trim()\n\nconst formatFormValue = (key: string, value: unknown): string => {\n if (key === 'applicationMode') {\n if (value === 'EXISTING') return '使用已有应用'\n if (value === 'NEW') return '新建应用'\n }\n if (typeof value === 'boolean') return value ? '是' : '否'\n if (Array.isArray(value)) return value.map((item) => String(item)).join('、')\n if (value !== null && typeof value === 'object') {\n const record = value as Record<string, unknown>\n if (typeof record.name === 'string') return record.name\n return JSON.stringify(value)\n }\n return String(value)\n}\n\nconst toFormField = (key: string, value: unknown): FormFieldData => ({\n key,\n label: FORM_LABELS[key] ?? humanizeField(key),\n value,\n ...(key === 'reason' || key === 'description' || key === 'accessScope'\n ? { type: 'multiline' as const, span: 2 as const }\n : {}),\n})\n\nconst formFields = (form: Record<string, unknown> | undefined): FormFieldData[] => (\n form === undefined\n ? []\n : Object.entries(form)\n .filter(([key, value]) => !SKIP_FORM_KEYS.has(key) && value !== null && value !== undefined && value !== '')\n .map(([key, value]) => toFormField(key, value))\n)\n\nconst approvalFormSections = (detail: TaskDetailPayload | null): FormSectionData[] => {\n if (detail === null) return []\n const sections: FormSectionData[] = []\n const applicationFields = formFields(detail.payload?.form)\n if (applicationFields.length > 0) sections.push({ title: '申请信息', fields: applicationFields })\n const resourceFields = formFields(detail.payload?.resourceAccessRequest?.form)\n if (resourceFields.length > 0) sections.push({ title: '资源申请', fields: resourceFields })\n const resources = [\n ...(detail.payload?.selectedItems ?? []),\n ...(detail.payload?.resourceAccessRequest?.selectedItems ?? []),\n ]\n if (resources.length > 0) {\n sections.push({\n title: '申请资源',\n fields: [{ key: 'resources', label: '资源', value: resources, type: 'resources', span: 2 }],\n })\n }\n return sections\n}\n\nconst ResourceValue = ({ items }: { items: Array<Record<string, unknown>> }) => (\n <div style={{ display: 'grid', gap: 5 }}>\n {items.map((item, index) => {\n const label = typeof item.title === 'string' ? item.title : typeof item.name === 'string' ? item.name : `资源 ${index + 1}`\n const detail = [item.scope, item.urn, item.id].filter((value) => typeof value === 'string' || typeof value === 'number').join(' · ')\n return (\n <div key={String(item.urn ?? item.id ?? index)} style={{ display: 'flex', alignItems: 'baseline', gap: 8, minWidth: 0 }}>\n <span style={{ fontSize: 12, color: colors.text }}>{label}</span>\n {detail ? <span style={{ fontSize: 10, color: colors.muted, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{detail}</span> : null}\n </div>\n )\n })}\n </div>\n)\n\nconst FormDescriptions = ({ sections }: { sections: FormSectionData[] }) => {\n if (sections.length === 0) return null\n return (\n <div style={{ display: 'grid', gap: 10 }}>\n {sections.map((section, sectionIndex) => (\n <section key={section.title + sectionIndex} style={{ border: '1px solid ' + colors.line, borderRadius: 10, background: colors.panel, padding: 14 }}>\n <div style={{ fontSize: 12, fontWeight: 650, color: colors.text, marginBottom: 9 }}>{section.title}</div>\n <dl style={{ margin: 0, display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: '9px 24px' }}>\n {section.fields.map((field) => (\n <div\n key={field.key}\n style={{\n display: 'grid',\n gridTemplateColumns: '94px minmax(0, 1fr)',\n alignItems: 'start',\n gap: 8,\n minWidth: 0,\n gridColumn: field.span === 2 ? '1 / -1' : undefined,\n }}\n >\n <dt style={{ fontSize: 10, lineHeight: 1.6, color: colors.muted }}>{field.label}</dt>\n <dd style={{ margin: 0, fontSize: 12, lineHeight: 1.6, color: colors.text, whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' }}>\n {field.type === 'resources' && Array.isArray(field.value)\n ? <ResourceValue items={field.value as Array<Record<string, unknown>>} />\n : field.value === null || field.value === undefined || field.value === ''\n ? '—'\n : formatFormValue(field.key, field.value)}\n </dd>\n </div>\n ))}\n </dl>\n </section>\n ))}\n </div>\n )\n}\n\n/** Detail requests fail after this long instead of leaving the panel waiting forever. */\nconst DETAIL_TIMEOUT_MS = 15_000\n/** Show a secondary hint once the flow service is slow, so the panel never looks frozen. */\nconst DETAIL_SLOW_HINT_MS = 5_000\n\n/** Turn a detail failure into the message the panel shows; the server text stays verbatim. */\nconst describeDetailFailure = (cause: unknown, timedOut: boolean): string => {\n if (timedOut) return '请求超时(15 秒无响应),流程服务可能暂时不可用,请重试。'\n const raw = cause instanceof Error ? cause.message : String(cause)\n if (/^(fetch failed|Failed to fetch|NetworkError|Load failed)/iu.test(raw)) {\n return '无法连接服务(网络错误),请检查网络或稍后重试。'\n }\n return raw\n}\n\nconst TaskDetail = ({ task, onBack }: { task: TaskItem; onBack: () => void }) => {\n const isApproval = task.sourceType === 'dataops_approval'\n const [detail, setDetail] = useState<TaskDetailPayload | null>(null)\n const [detailLoading, setDetailLoading] = useState(true)\n const [detailError, setDetailError] = useState<string | null>(null)\n const [detailSlow, setDetailSlow] = useState(false)\n const [detailAttempt, setDetailAttempt] = useState(0)\n\n useEffect(() => {\n let alive = true\n const controller = new AbortController()\n let timedOut = false\n const timeout = window.setTimeout(() => { timedOut = true; controller.abort() }, DETAIL_TIMEOUT_MS)\n const slowHint = window.setTimeout(() => { if (alive) setDetailSlow(true) }, DETAIL_SLOW_HINT_MS)\n setDetail(null)\n setDetailLoading(true)\n setDetailError(null)\n setDetailSlow(false)\n void fetchJson<{ detail?: TaskDetailPayload }>('/items/' + encodeURIComponent(task.id), { signal: controller.signal })\n .then((payload) => { if (alive) setDetail(payload.detail ?? null) })\n .catch((cause) => { if (alive) setDetailError(describeDetailFailure(cause, timedOut)) })\n .finally(() => {\n window.clearTimeout(timeout)\n window.clearTimeout(slowHint)\n if (alive) {\n setDetailLoading(false)\n setDetailSlow(false)\n }\n })\n return () => {\n alive = false\n controller.abort()\n window.clearTimeout(timeout)\n window.clearTimeout(slowHint)\n }\n }, [task.id, detailAttempt])\n\n const sections = isApproval ? approvalFormSections(detail) : detail?.form?.sections ?? []\n const attachments = detail?.attachments ?? []\n const approvalTaskId = isApproval && typeof detail?.id === 'number' ? detail.id : null\n const attachmentHref = (attachment: TaskAttachmentRecord) => approvalTaskId === null\n ? null\n : ROUTE + '/attachment?taskId=' + encodeURIComponent(String(approvalTaskId))\n + '&attachmentId=' + encodeURIComponent(attachment.id)\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10, flex: 1, minHeight: '100%' }}>\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 14, fontWeight: 700, color: colors.text, lineHeight: 1.45 }}>{task.title}</div>\n <div style={{ marginTop: 3, fontSize: 10, color: colors.muted }}>\n {task.source.label ?? (isApproval ? 'DataOps 审批' : '任务总线')} · {relativeTime(task.updatedAt)}\n </div>\n </div>\n <Tag tone={statusTagTone(task.status)}>{task.statusLabel}</Tag>\n </div>\n\n {detailLoading ? (\n <div style={{ padding: 18, textAlign: 'center', color: colors.muted, fontSize: 12, display: 'grid', gap: 4 }}>\n <span>正在加载表单…</span>\n {detailSlow ? <span style={{ fontSize: 10 }}>流程服务响应较慢,正在继续等待…</span> : null}\n </div>\n ) : null}\n {detailError ? (\n <div role=\"alert\" style={{ padding: '8px 10px', borderRadius: 8, background: '#fef2f2', color: colors.danger, fontSize: 11, display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{ flex: 1, minWidth: 0, lineHeight: 1.6 }}>{detailError}</span>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setDetailAttempt((value) => value + 1)}>重试</Button>\n </div>\n ) : null}\n {!detailLoading && detailError === null && sections.length > 0 ? <FormDescriptions sections={sections} /> : null}\n {!detailLoading && detailError === null && sections.length === 0 && !isApproval && task.description ? (\n <div style={{ border: '1px solid ' + colors.line, borderRadius: 10, background: colors.panel, padding: 14, fontSize: 12, lineHeight: 1.6, color: colors.text, whiteSpace: 'pre-wrap' }}>{task.description}</div>\n ) : null}\n {!detailLoading && detailError === null && sections.length === 0 && (isApproval || !task.description) ? (\n <div style={{ padding: 18, textAlign: 'center', color: colors.muted, fontSize: 12 }}>暂无表单信息</div>\n ) : null}\n\n {isApproval || attachments.length > 0 ? (\n <section style={{ border: '1px solid ' + colors.line, borderRadius: 10, background: colors.panel, padding: 14 }}>\n <div style={{ fontSize: 12, fontWeight: 650, color: colors.text, marginBottom: 8 }}>附件</div>\n {attachments.length === 0 ? <div style={{ fontSize: 11, color: colors.muted }}>暂无附件</div> : (\n <div style={{ display: 'grid', gap: 6 }}>\n {attachments.map((attachment) => {\n const href = attachmentHref(attachment)\n return (\n <div key={attachment.id} style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>\n <span style={{ flex: 1, minWidth: 0, fontSize: 11, color: colors.text, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{attachment.originalName}</span>\n <span style={{ flex: 'none', fontSize: 10, color: colors.muted }}>{formatBytes(attachment.sizeBytes)}</span>\n {href !== null ? <Button size=\"sm\" variant=\"ghost\" onClick={() => window.open(href, '_blank', 'noopener,noreferrer')}>下载</Button> : null}\n </div>\n )\n })}\n </div>\n )}\n </section>\n ) : null}\n\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, flexWrap: 'wrap', marginTop: 'auto', paddingTop: 2 }}>\n <Button size=\"sm\" variant=\"ghost\" onClick={onBack}>← 返回列表</Button>\n {isApproval && task.source.deepLink ? (\n <Button size=\"sm\" variant=\"outline\" onClick={() => window.open(approvalHref(task.source.deepLink ?? null) ?? '#', '_blank', 'noopener,noreferrer')}>\n 打开 DataOps 审批详情\n </Button>\n ) : null}\n </div>\n </div>\n )\n}\n\ntype TaskTab = 'all' | 'mine' | 'personal' | 'group'\n\nconst TaskCenterButton = ({ openSession }: {\n openSession: (sessionId: string) => void\n}) => {\n const [open, setOpen] = useState(false)\n const [tasks, setTasks] = useState<TaskItem[]>([])\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [tab, setTab] = useState<TaskTab>('all')\n const [busyId, setBusyId] = useState<string | null>(null)\n const [aiBusyId, setAiBusyId] = useState<string | null>(null)\n const [selected, setSelected] = useState<TaskItem | null>(null)\n const [anchor, setAnchor] = useState<{ left: number; top: number } | null>(null)\n const [pendingCount, setPendingCount] = useState(0)\n\n useEffect(() => {\n if (document.getElementById(TASK_BUS_STYLE_ID) !== null) return\n const style = document.createElement('style')\n style.id = TASK_BUS_STYLE_ID\n style.textContent = TASK_BUS_MODAL_CSS\n document.head.append(style)\n return () => { style.remove() }\n }, [])\n\n useEffect(() => {\n const update = () => {\n const collapsed = document.querySelector('[data-sidebar-collapsed=\"true\"]') !== null\n if (collapsed) {\n setAnchor((current) => (current === null ? current : null))\n return\n }\n const buttons = Array.from(document.querySelectorAll('button'))\n const toggle = buttons.find((button) => /收起侧边栏|Collapse sidebar/i.test((button.getAttribute('aria-label') ?? '').trim()))\n if (!toggle) {\n setAnchor((current) => (current === null ? current : null))\n return\n }\n const label = (toggle.getAttribute('aria-label') ?? '').trim()\n if (/展开侧边栏|Expand sidebar/i.test(label)) {\n setAnchor((current) => (current === null ? current : null))\n return\n }\n const rect = toggle.getBoundingClientRect()\n if (rect.width === 0 || rect.height === 0) return\n const next = { left: Math.max(8, rect.left - 36), top: rect.top + (rect.height - 28) / 2 }\n setAnchor((current) => (\n current !== null && Math.abs(current.left - next.left) < 0.5 && Math.abs(current.top - next.top) < 0.5\n ? current\n : next\n ))\n }\n update()\n const timer = window.setInterval(update, 400)\n window.addEventListener('resize', update)\n return () => {\n window.clearInterval(timer)\n window.removeEventListener('resize', update)\n }\n }, [])\n\n const load = async (silent = false) => {\n if (!silent) setLoading(true)\n setError(null)\n try {\n const overview = await fetchJson<{ items: TaskItem[] }>('/overview')\n setTasks([...overview.items].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)))\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n if (!silent) setLoading(false)\n }\n }\n\n useEffect(() => {\n if (!open) return\n void load()\n const timer = window.setInterval(() => { void load(true) }, 60_000)\n return () => { window.clearInterval(timer) }\n }, [open])\n\n useEffect(() => {\n let alive = true\n const refresh = async () => {\n try {\n const result = await fetchJson<{ count?: number }>('/count')\n if (alive) setPendingCount(Math.max(0, Math.trunc(Number(result.count) || 0)))\n } catch {\n // The panel's overview error is the visible connection state; the badge keeps its last value.\n }\n }\n void refresh()\n const timer = window.setInterval(() => { void refresh() }, 300_000)\n return () => { alive = false; window.clearInterval(timer) }\n }, [])\n\n const filtered = useMemo(() => {\n if (tab === 'group') return tasks.filter((task) => task.sourceType === 'task_bus' && task.source.type.includes('group'))\n if (tab === 'mine') return tasks.filter((task) => task.status !== 'completed' && task.status !== 'cancelled')\n if (tab === 'personal') return tasks.filter((task) => task.sourceType === 'task_bus' && !task.source.type.includes('group'))\n return tasks\n }, [tasks, tab])\n\n const actionable = tasks.filter((task) => task.status !== 'completed' && task.status !== 'cancelled').length\n const tabItems: [SegmentedTab<TaskTab>, ...SegmentedTab<TaskTab>[]] = [\n { value: 'all', id: 'task-bus-tab-all', panelId: 'task-bus-panel-all', label: <span>全部 <span style={{ opacity: 0.55 }}>{tasks.length}</span></span> },\n { value: 'mine', id: 'task-bus-tab-mine', panelId: 'task-bus-panel-mine', label: <span>待我处理 <span style={{ opacity: 0.55 }}>{actionable}</span></span> },\n { value: 'personal', id: 'task-bus-tab-personal', panelId: 'task-bus-panel-personal', label: <span>个人 <span style={{ opacity: 0.55 }}>{tasks.filter((task) => task.sourceType === 'task_bus' && !task.source.type.includes('group')).length}</span></span> },\n { value: 'group', id: 'task-bus-tab-group', panelId: 'task-bus-panel-group', label: <span>群聊 <span style={{ opacity: 0.55 }}>{tasks.filter((task) => task.sourceType === 'task_bus' && task.source.type.includes('group')).length}</span></span> },\n ]\n\n const transition = async (task: TaskItem, action: string) => {\n setBusyId(task.id)\n setError(null)\n try {\n await fetch(ROUTE + '/generic/' + encodeURIComponent(task.id.slice(5)) + '/transition', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ action }),\n }).then(async (response) => {\n if (!response.ok) {\n const payload = await response.json().catch(() => null) as { error?: string } | null\n throw new Error(payload?.error ?? '任务操作失败')\n }\n })\n await load()\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusyId(null)\n }\n }\n\n const aiAccept = async (task: TaskItem) => {\n setAiBusyId(task.id)\n setError(null)\n try {\n const response = await fetch(ROUTE + '/ai-accept', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id: task.id }),\n })\n const payload = await response.json() as { sessionId?: string; error?: string }\n if (!response.ok || typeof payload.sessionId !== 'string') {\n throw new Error(payload.error ?? 'AI 受理会话创建失败')\n }\n openSession(payload.sessionId)\n setOpen(false)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setAiBusyId(null)\n }\n }\n\n return (\n <>\n {anchor !== null ? (\n <button\n type=\"button\"\n aria-label=\"任务中心\"\n title=\"任务中心\"\n onClick={() => setOpen((value) => !value)}\n style={{\n position: 'fixed',\n left: anchor.left,\n top: anchor.top,\n zIndex: 45,\n width: 28,\n height: 28,\n padding: 0,\n border: 'none',\n borderRadius: 8,\n background: 'transparent',\n color: actionable > 0 ? colors.accent : colors.muted,\n cursor: 'pointer',\n pointerEvents: 'auto',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9\" />\n <path d=\"M13.7 21a2 2 0 0 1-3.4 0\" />\n </svg>\n {pendingCount > 0 ? (\n <span style={{ position: 'absolute', bottom: -2, right: -2, minWidth: 14, height: 14, padding: '0 3px', boxSizing: 'border-box', borderRadius: 999, background: '#2563eb', color: '#fff', fontSize: 9, lineHeight: '14px', textAlign: 'center' }}>\n {pendingCount > 99 ? '99+' : pendingCount}\n </span>\n ) : null}\n </button>\n ) : null}\n\n <Modal open={open} onClose={() => setOpen(false)} title=\"任务中心\" headless className={TASK_BUS_MODAL_CLASS}>\n <div style={{ display: 'flex', flexDirection: 'column', width: '100%', height: '100%', minHeight: 0 }}>\n <header style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '22px 24px 12px' }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <h2 style={{ margin: 0, fontSize: 16, lineHeight: '24px', fontWeight: 500, color: colors.text }}>任务中心</h2>\n </div>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>刷新</Button>\n <Button size=\"sm\" variant=\"ghost\" aria-label=\"关闭\" title=\"关闭\" onClick={() => setOpen(false)} icon={<IconCloseOutlineRegular size={14} />} style={{ width: 28, padding: 0 }} />\n </header>\n <div style={{ padding: '0 24px 14px', borderBottom: '1px solid ' + colors.line }}>\n <SegmentedTabs items={tabItems} value={tab} onChange={setTab} label=\"任务中心分类\" />\n </div>\n {error ? <div style={{ padding: '8px 10px', borderRadius: 8, background: '#fef2f2', color: colors.danger, fontSize: 11, margin: '0 24px 12px' }}>{error}</div> : null}\n <div id={'task-bus-panel-' + tab} role=\"tabpanel\" aria-labelledby={'task-bus-tab-' + tab} style={{ padding: '16px 24px 24px', display: 'flex', flexDirection: 'column', gap: 10, overflowY: 'auto', flex: 1 }}>\n {selected !== null ? (\n <TaskDetail task={selected} onBack={() => setSelected(null)} />\n ) : (\n <>\n {loading ? <div style={{ padding: 18, textAlign: 'center', color: colors.muted, fontSize: 12 }}>正在加载…</div> : null}\n {!loading && filtered.length === 0 ? <div style={{ padding: 18, textAlign: 'center', color: colors.muted, fontSize: 12 }}>暂无任务</div> : null}\n {!loading && filtered.map((task) => (\n <TaskCard key={task.id} task={task} busy={busyId === task.id} aiBusy={aiBusyId === task.id} onTransition={(item, action) => void transition(item, action)} onAiAccept={(item) => void aiAccept(item)} onOpen={setSelected} />\n ))}\n </>\n )}\n </div>\n </div>\n </Modal>\n </>\n )\n}\n\n\n\ninterface HistoryEntry {\n key: string\n role: 'user' | 'assistant'\n author: string\n time: number | undefined\n text: string\n jumpId?: string\n}\n\nconst HISTORY_CONTENT_TYPES = new Set(['user/message', 'assistant/message'])\n\nconst historyText = (content: unknown): string => {\n if (!Array.isArray(content)) return ''\n return content.map((block) => {\n if (block === null || typeof block !== 'object') return ''\n const record = block as Record<string, unknown>\n return record.type === 'text' && typeof record.text === 'string' ? record.text : ''\n }).filter(Boolean).join('\\n').trim()\n}\n\nconst historyRole = (event: Record<string, unknown>): 'user' | 'assistant' => {\n const data = event.data as Record<string, unknown> | undefined\n return data?.role === 'user' || event.type === 'user/message' ? 'user' : 'assistant'\n}\n\nconst historyAuthor = (event: Record<string, unknown>, role: 'user' | 'assistant', t: HistoryTranslate): string => {\n const data = event.data as Record<string, unknown> | undefined\n const source = data?.source as Record<string, unknown> | undefined\n const memberName = typeof source?.memberName === 'string' ? source.memberName.trim() : ''\n if (memberName !== '') return memberName\n return role === 'user' ? t('me') : t('assistant')\n}\n\nconst groupHistory = async (roomId: string, t: HistoryTranslate): Promise<HistoryEntry[]> => {\n const entries: HistoryEntry[] = []\n let cursor: string | null = null\n for (let page = 0; page < 20; page += 1) {\n const suffix = cursor === null ? '' : '?cursor=' + encodeURIComponent(cursor)\n const response = await fetch('/dsh-group-chat/api/rooms/' + encodeURIComponent(roomId) + '/events' + suffix)\n if (!response.ok) throw new Error(t('error'))\n const payload = await response.json() as { events?: Array<{ id?: string; event?: Record<string, unknown>; createdAt?: string }>; nextCursor?: string | null; hasMore?: boolean }\n for (const record of payload.events ?? []) {\n const event = record.event\n if (event === undefined || typeof event.type !== 'string' || !HISTORY_CONTENT_TYPES.has(event.type)) continue\n const data = event.data as Record<string, unknown> | undefined\n const role = historyRole(event)\n const text = historyText(data?.content)\n if (text === '') continue\n entries.push({ key: record.id ?? String(event.seq ?? entries.length), role, author: historyAuthor(event, role, t), time: typeof event.time === 'number' ? event.time : undefined, text, jumpId: record.id })\n }\n if (payload.hasMore !== true || payload.nextCursor === null || payload.nextCursor === undefined) break\n cursor = payload.nextCursor\n }\n return entries.sort((left, right) => (right.time ?? 0) - (left.time ?? 0))\n}\n\nconst sessionHistory = async (sessionId: string, sessions: unknown, t: HistoryTranslate): Promise<HistoryEntry[]> => {\n const service = sessions as {\n retain?: (id: string, options: { source: string }) => {\n ready?: Promise<unknown>\n binding?: {\n eventSource?: { getSnapshot(): { entries?: Array<{ type?: string; event?: Record<string, unknown> }> } }\n session?: { loadOlder?: () => Promise<void> }\n }\n release?: () => void\n }\n }\n if (service.retain === undefined) return []\n const reference = service.retain(sessionId, { source: 'gateway' })\n try {\n await reference.ready\n const binding = reference.binding\n if (binding === undefined) return []\n await binding.session?.loadOlder?.().catch(() => undefined)\n const entries = binding.eventSource?.getSnapshot().entries ?? []\n return entries\n .filter((entry): entry is { type: 'event'; event: Record<string, unknown> } => entry.type === 'event' && entry.event !== undefined)\n .filter((entry) => typeof entry.event.type === 'string' && HISTORY_CONTENT_TYPES.has(entry.event.type))\n .map((entry) => {\n const event = entry.event\n const data = event.data as Record<string, unknown> | undefined\n const role = historyRole(event)\n return {\n key: String(event.seq ?? entries.indexOf(entry)),\n role,\n author: historyAuthor(event, role, t),\n time: typeof event.time === 'number' ? event.time : undefined,\n text: historyText(data?.content),\n }\n })\n .filter((entry) => entry.text !== '')\n .sort((left, right) => (right.time ?? 0) - (left.time ?? 0))\n } finally {\n reference.release?.()\n }\n}\n\n\n\ninterface FileAttachmentRef {\n attachmentId: string\n name: string\n bytes: number\n}\n\nconst fileAttachmentIn = (content: unknown, name: string): FileAttachmentRef | undefined => {\n if (!Array.isArray(content)) return undefined\n for (const block of content) {\n if (block === null || typeof block !== 'object') continue\n const record = block as Record<string, unknown>\n if (record.type !== 'file') continue\n const attachment = record.attachment as Record<string, unknown> | undefined\n if (attachment?.name === name && typeof attachment.attachmentId === 'string' && typeof attachment.bytes === 'number') {\n return { attachmentId: attachment.attachmentId, name, bytes: attachment.bytes }\n }\n }\n return undefined\n}\n\nconst sessionFileAttachment = async (sessionId: string, sessions: unknown, name: string): Promise<FileAttachmentRef | undefined> => {\n const service = sessions as {\n retain?: (id: string, options: { source: string }) => {\n ready?: Promise<unknown>\n binding?: {\n eventSource?: { getSnapshot(): { entries?: Array<{ type?: string; event?: Record<string, unknown> }> } }\n session?: { loadOlder?: () => Promise<void> }\n }\n release?: () => void\n }\n }\n if (service.retain === undefined) return undefined\n const reference = service.retain(sessionId, { source: 'gateway' })\n try {\n await reference.ready\n const binding = reference.binding\n if (binding === undefined) return undefined\n const find = (): FileAttachmentRef | undefined => {\n const entries = binding.eventSource?.getSnapshot().entries ?? []\n for (const entry of entries) {\n if (entry.type !== 'event' || entry.event === undefined) continue\n if (entry.event.type !== 'user/message') continue\n const data = entry.event.data as Record<string, unknown> | undefined\n const found = fileAttachmentIn(data?.content, name)\n if (found !== undefined) return found\n }\n return undefined\n }\n let found = find()\n for (let page = 0; page < 5 && found === undefined; page += 1) {\n await binding.session?.loadOlder?.().catch(() => undefined)\n found = find()\n }\n return found\n } finally {\n reference.release?.()\n }\n}\n\n/**\n * The design system's standard 16-unit clock glyph, drawn locally.\n *\n * The client primitives package this runtime serves (0.2.2-alpha.2) exports\n * `IconClockOutline`, `IconClockOutlineRegular`, and `IconClockOutlineMedium`,\n * not the newer `IconClockOutline16` name. A missing named export resolves to\n * `undefined`, so importing it crashed this header slot with React error #130\n * and removed the button entirely; the standard geometry is inlined instead.\n *\n * Weight is 1, matching the shell's own header glyphs: those render 16x16 with\n * `stroke-width=\"1\"` on a `0 0 16 16` viewBox, so a 1.5 stroke read as a bold\n * clock beside them. The glyph must also stay square inside the 28px button,\n * hence its block display and disabled flex shrink.\n */\nconst MessageHistoryIcon = ({ size = 16 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n strokeWidth=\"1\"\n preserveAspectRatio=\"xMidYMid meet\"\n style={{ display: 'block', flexShrink: 0 }}\n >\n <circle cx=\"8\" cy=\"8\" r=\"6.375\" stroke=\"currentColor\" />\n <path d=\"M8 4.4V8.3L10.7 9.85\" stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n)\n\nconst HistoryButton = ({ sessionId, sessions, t }: { sessionId: string; sessions: unknown; t: HistoryTranslate }) => {\n const [open, setOpen] = useState(false)\n const [entries, setEntries] = useState<HistoryEntry[]>([])\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState('')\n const [query, setQuery] = useState('')\n const isGroup = sessionId.startsWith('group-room-')\n\n useEffect(() => {\n if (!open) return\n let alive = true\n setLoading(true)\n setError('')\n setQuery('')\n setEntries([])\n const load = isGroup ? groupHistory(sessionId.slice('group-room-'.length), t) : sessionHistory(sessionId, sessions, t)\n void load.then((items) => { if (alive) setEntries(items) })\n .catch((cause) => { if (alive) setError(cause instanceof Error ? cause.message : String(cause)) })\n .finally(() => { if (alive) setLoading(false) })\n return () => { alive = false }\n }, [open, isGroup, sessionId, sessions, t])\n\n const needle = query.trim().toLocaleLowerCase()\n const results = useMemo(() => {\n if (needle === '') return []\n return entries.filter((entry) =>\n entry.text.toLocaleLowerCase().includes(needle) || entry.author.toLocaleLowerCase().includes(needle))\n }, [entries, needle])\n\n const jump = (entry: HistoryEntry) => {\n setOpen(false)\n window.setTimeout(() => {\n let target: HTMLElement | null = entry.jumpId === undefined\n ? null\n : document.querySelector<HTMLElement>('[data-group-chat-message=\"' + CSS.escape(entry.jumpId) + '\"]')\n if (target === null) {\n const text = entry.text.slice(0, 80)\n target = [...document.querySelectorAll<HTMLElement>('[data-group-chat-message], [data-slot=\"conversation.user.text.node\"]')]\n .find((element) => (element.innerText ?? '').includes(text)) ?? null\n }\n if (target === null && (window as unknown as { find: (...args: unknown[]) => boolean }).find(entry.text.slice(0, 80), false, false, true, false, false, false)) {\n const selection = window.getSelection()\n const node = selection?.anchorNode\n target = node instanceof HTMLElement ? node : node?.parentElement ?? null\n }\n target?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n if (target !== null) {\n target.style.outline = '2px solid #2563eb'\n target.style.outlineOffset = '4px'\n window.setTimeout(() => { target!.style.outline = ''; target!.style.outlineOffset = '' }, 1800)\n }\n }, 80)\n }\n\n const searchInputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n height: 36,\n padding: '0 34px 0 12px',\n borderRadius: 8,\n border: '1px solid ' + colors.line,\n background: colors.panel,\n color: colors.text,\n fontSize: 13,\n outline: 'none',\n }\n\n return (\n <>\n <button\n type=\"button\"\n aria-label={t('open')}\n title={t('open')}\n data-session-id={sessionId}\n onClick={() => setOpen(true)}\n style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 28, height: 28, border: 'none', borderRadius: 6, background: 'transparent', color: 'inherit', cursor: 'pointer' }}\n >\n <MessageHistoryIcon size={16} />\n </button>\n <Modal open={open} onClose={() => setOpen(false)} title={t('title')} closeLabel={t('close')} className={TASK_BUS_HISTORY_CLASS}>\n <div style={{ width: '100%', maxHeight: 'min(68vh, 620px)', overflowY: 'auto', display: 'grid', gap: 10, padding: '4px 0 8px' }}>\n <div style={{ position: 'relative', width: '100%' }}>\n <input\n type=\"text\"\n value={query}\n autoFocus\n spellCheck={false}\n placeholder={t('searchPlaceholder')}\n aria-label={t('searchLabel')}\n onChange={(event) => { setQuery(event.target.value) }}\n style={searchInputStyle}\n />\n {query !== '' ? (\n <button\n type=\"button\"\n aria-label={t('clear')}\n title={t('clear')}\n onClick={() => { setQuery('') }}\n style={{ position: 'absolute', right: 6, top: '50%', transform: 'translateY(-50%)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 24, height: 24, border: 'none', borderRadius: 5, background: 'transparent', color: colors.muted, cursor: 'pointer' }}\n >\n <IconCloseOutlineRegular size={14} />\n </button>\n ) : null}\n </div>\n\n {loading ? <div style={{ padding: 28, textAlign: 'center', color: colors.muted, fontSize: 12 }}>{t('loading')}</div> : null}\n {!loading && error !== '' ? <div role=\"alert\" style={{ padding: 12, color: colors.danger, fontSize: 12 }}>{error}</div> : null}\n {!loading && error === '' && needle === '' ? (\n <div style={{ display: 'grid', justifyItems: 'center', gap: 8, padding: '36px 20px 40px', color: colors.muted, textAlign: 'center' }}>\n <span style={{ display: 'inline-flex', width: 36, height: 36, alignItems: 'center', justifyContent: 'center', borderRadius: 18, background: colors.panelAlt, color: colors.muted }}>\n <MessageHistoryIcon size={16} />\n </span>\n <span style={{ fontSize: 13, fontWeight: 600, color: colors.text }}>{t('initial')}</span>\n <span style={{ fontSize: 12, lineHeight: 1.6 }}>{t('initialHint')}</span>\n </div>\n ) : null}\n {!loading && error === '' && needle !== '' && results.length === 0 ? (\n <div style={{ padding: 28, textAlign: 'center', color: colors.muted, fontSize: 12 }}>\n {entries.length === 0 ? t('empty') : t('noResults')}\n </div>\n ) : null}\n {!loading && error === '' && needle !== '' && results.map((entry) => (\n <button\n key={entry.key}\n type=\"button\"\n onClick={() => jump(entry)}\n style={{ display: 'grid', gap: 6, width: '100%', minWidth: 0, textAlign: 'left', padding: '10px 12px', borderRadius: 8, border: '1px solid ' + colors.line, background: colors.panelAlt, color: colors.text, cursor: 'pointer' }}\n >\n <span style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0, flexWrap: 'wrap', fontSize: 10, color: colors.muted }}>\n <span style={{ fontWeight: 650, color: entry.role === 'user' ? '#2563eb' : colors.text }}>{entry.author}</span>\n {entry.time === undefined ? null : <span>{new Date(entry.time).toLocaleString(t('dateLocale'))}</span>}\n <span style={{ marginLeft: 'auto' }}>{t('jump')}</span>\n </span>\n <span style={{ display: 'block', minWidth: 0, fontSize: 13, lineHeight: 1.65, whiteSpace: 'pre-wrap', overflowWrap: 'anywhere', wordBreak: 'break-word' }}>{entry.text}</span>\n </button>\n ))}\n </div>\n </Modal>\n </>\n )\n}\n\nexport const apply = (ctx: Context) => {\n const locale = (ctx as unknown as {\n locale: {\n register(namespace: string, dictionaries: { zh: typeof HISTORY_COPY.zh; en: typeof HISTORY_COPY.en }): () => void\n bind(namespace: string): (key: HistoryCopyKey) => string\n }\n }).locale\n ctx.effect(() => locale.register(HISTORY_NS, { zh: HISTORY_COPY.zh, en: HISTORY_COPY.en }), 'task-bus: history copy')\n const t = locale.bind(HISTORY_NS)\n const surface = ctx as unknown as {\n slots: {\n inject(name: string, factory: () => () => void): () => void\n register(options: Record<string, unknown>, component: (props: never) => JSX.Element | null): () => void\n }\n uiWorkspace: { openSession(sessionId: string): void }\n }\n const surfaceWithServices = surface as unknown as {\n sidebarRight?: { openResource?(address: string): void }\n get?: (name: string) => unknown\n }\n const sidebarRight = (surfaceWithServices.sidebarRight ?? surfaceWithServices.get?.('sidebarRight')) as\n { openResource?(address: string): void } | undefined\n // Native file cards are spans owned by the official Chat renderer, so delegate from the\n // document. The active Session header carries its id; group rooms have their own handler.\n ctx.effect(() => {\n const onFileClick = (event: MouseEvent): void => {\n const target = event.target\n if (!(target instanceof Element)) return\n const card = target.closest('[data-message-attachments] > *')\n if (!(card instanceof HTMLElement)) return\n const header = document.querySelector<HTMLElement>('button[aria-label=\"消息记录\"][data-session-id]')\n const sessionId = header?.getAttribute('data-session-id') ?? ''\n if (sessionId === '' || sessionId.startsWith('group-room-')) return\n const name = (card.getAttribute('title') ?? card.innerText.split('\\n')[0] ?? '').trim()\n if (name === '') return\n void (async () => {\n const attachment = await sessionFileAttachment(sessionId, (ctx as unknown as { sessions: unknown }).sessions, name)\n if (attachment === undefined) return\n const sessionState = (ctx as unknown as {\n sessions?: { list?: { getSnapshot(): { byId?: Record<string, { cwd?: string }> } } }\n }).sessions?.list?.getSnapshot()\n const cwd = sessionState?.byId?.[sessionId]?.cwd ?? ''\n const query = 'attachmentId=' + encodeURIComponent(attachment.attachmentId)\n + '&name=' + encodeURIComponent(attachment.name)\n + '&bytes=' + encodeURIComponent(String(attachment.bytes))\n + (cwd === '' ? '' : '&cwd=' + encodeURIComponent(cwd))\n const response = await fetch(ROUTE + '/attachment-materialize?' + query)\n if (!response.ok) throw new Error('附件预览准备失败')\n const materialized = await response.json() as { path?: string }\n if (typeof materialized.path !== 'string') throw new Error('附件预览路径缺失')\n const address = 'dsh-resource://file/session/' + encodeURIComponent(sessionId)\n + '/' + materialized.path.split('/').map((part) => encodeURIComponent(part)).join('/')\n const right = (ctx as unknown as { sidebarRight?: { openResource?(address: string): void } }).sidebarRight\n if (right?.openResource !== undefined) right.openResource(address)\n else window.open(new URL('/dsh-task-bus/api/attachment-materialize?' + query, window.location.origin).toString(), '_blank', 'noopener,noreferrer')\n })().catch((cause) => { console.error('[task-bus] file preview failed', cause) })\n }\n document.addEventListener('click', onFileClick, true)\n return () => { document.removeEventListener('click', onFileClick, true) }\n }, 'task-bus: native file card preview')\n const Surface = () => (\n <TaskCenterButton\n openSession={(sessionId) => surface.uiWorkspace.openSession(sessionId)}\n />\n )\n ctx.effect(() => surface.slots.inject('shell.overlay', () => surface.slots.register(\n { name: 'shell.overlay', id: 'task-bus.center' },\n Surface,\n )), 'task-bus: Task Center overlay')\n\n // The history seat replaces the host's open-in-app jump. That control is a split\n // group: `[data-open-target=\"directory\"]` wraps the primary button and an optional\n // chevron. Hiding only the primary button left the wrapper's 1px left/right border\n // as a 2px-wide, 24px-tall rule beside this button, so the entry that owns the\n // split group is hidden instead.\n //\n // The slot renders every registered entry as one direct child of the\n // `[data-slot=\"conversation.session.header.utilities\"]` wrapper; this button is a\n // sibling of that entry, so the selectors below never match its own container.\n // They are scoped to the utilities slot so the file and directory launchers\n // elsewhere in the shell keep working.\n ctx.effect(() => {\n const style = document.createElement('style')\n style.id = 'task-bus-history-replaces-file-manager'\n style.textContent = [\n '[data-slot=\"conversation.session.header.utilities\"] > *:has([data-open-target]) { display: none !important; }',\n '[data-message-attachments] > * { cursor: pointer; }',\n ].join('\\n')\n document.head.appendChild(style)\n return () => { style.remove() }\n }, 'task-bus: replace file manager header button')\n\n ctx.effect(() => surface.slots.inject('conversation.session.header.utilities', () => surface.slots.register({\n name: 'conversation.session.header.utilities',\n id: 'task-bus.history',\n order: -4,\n inject: ((sessionId: string) => ({ sessionId, sessions: (ctx as unknown as { sessions: unknown }).sessions, t })) as never,\n } as never, HistoryButton as never)), 'task-bus: message history')\n}"],"mappings":";;;;;;;;;;;EAEA,MAAa,SAAS;GACpB,OAAO;GACP,UAAU;GACV,MAAM;GACN,OAAO;GACP,MAAM;GACN,QAAQ;GACR,YAAY;GACZ,SAAS;GACT,SAAS;GACT,QAAQ;EACV;;;;;;;;;;ECUA,MAAa,SAAS;GAAC;GAAS;GAAU;GAAe;GAAY;EAAc;EA8BnF,MAAM,QAAQ;EAEd,MAAM,uBAAuB;EAC7B,MAAM,yBAAyB;EAC/B,MAAM,oBAAoB;EAC1B,MAAM,qBAAqB;GACxB,qBAAqB;;;;;;;KAOnB,qBAAqB;;;;;GAKvB,uBAAuB;;;;;;;KAOrB,uBAAuB;;;;;;;EAQ5B,MAAM,aAAa;EACnB,MAAM,eAAe;GACnB,IAAI;IACF,OAAO;IACP,MAAM;IACN,OAAO;IACP,mBAAmB;IACnB,aAAa;IACb,OAAO;IACP,SAAS;IACT,aAAa;IACb,SAAS;IACT,OAAO;IACP,OAAO;IACP,WAAW;IACX,MAAM;IACN,IAAI;IACJ,WAAW;IACX,YAAY;GACd;GACA,IAAI;IACF,OAAO;IACP,MAAM;IACN,OAAO;IACP,mBAAmB;IACnB,aAAa;IACb,OAAO;IACP,SAAS;IACT,aAAa;IACb,SAAS;IACT,OAAO;IACP,OAAO;IACP,WAAW;IACX,MAAM;IACN,IAAI;IACJ,WAAW;IACX,YAAY;GACd;EACF;EAMU,KAAe,OAAO,MAClB,OAAO,OACZ,OAAO;EAOhB,MAAM,iBAAiB,WAA4B;GACjD,IAAI,WAAW,aAAa,OAAO;GACnC,IAAI,WAAW,aAAa,OAAO;GACnC,IAAI,WAAW,WAAW,OAAO;GACjC,IAAI,WAAW,qBAAqB,WAAW,cAAc,WAAW,kBAAkB,OAAO;GACjG,OAAO;EACT;EAEA,MAAM,gBAAgB,UAAkB;GACtC,MAAM,OAAO,KAAK,MAAM,KAAK;GAC7B,IAAI,CAAC,OAAO,SAAS,IAAI,GAAG,OAAO;GACnC,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,IAAI,IAAI,QAAQ,GAAM,CAAC;GACpE,IAAI,UAAU,GAAG,OAAO;GACxB,IAAI,UAAU,IAAI,OAAO,OAAO,OAAO,IAAI;GAC3C,MAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;GACrC,IAAI,QAAQ,IAAI,OAAO,OAAO,KAAK,IAAI;GACvC,OAAO,OAAO,KAAK,MAAM,QAAQ,EAAE,CAAC,IAAI;EAC1C;EAEA,MAAM,YAAY,OAAW,MAAc,UAAoC,CAAC,MAAkB;GAChG,MAAM,UAAU,YAAY;IAC1B,MAAM,WAAW,MAAM,MAAM,QAAQ,MAAM;KAAE,SAAS,EAAE,QAAQ,mBAAmB;KAAG,QAAQ,QAAQ;IAAO,CAAC;IAI9G,IAAI,OAAO;IACX,IAAI,cAAc;IAClB,IAAI;KAAE,OAAO,MAAM,SAAS,KAAK;IAAE,QAAQ;KAAE,cAAc;IAAK;IAChE,IAAI,UAAmB;IACvB,IAAI,KAAK,KAAK,MAAM,IAClB,IAAI;KAAE,UAAU,KAAK,MAAM,IAAI;IAAa,QAAQ;KAAE,UAAU;IAAK;IAEvE,OAAO;KAAE;KAAU,QAAQ,SAAS;KAAQ;KAAS;KAAM;IAAY;GACzE;GAIA,MAAM,UAAU,YAAY;IAC1B,IAAI;KACF,MAAM,QAAQ,MAAM,QAAQ;KAC5B,IAAI,CAAC,MAAM,aAAa,OAAO;KAC/B,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;KACvD,OAAO,MAAM,QAAQ;IACvB,SAAS,OAAO;KACd,IAAI,QAAQ,QAAQ,SAAS,MAAM;KACnC,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;KACvD,OAAO,MAAM,QAAQ;IACvB;GACF;GACA,IAAI,SAAS,MAAM,QAAQ;GAG3B,IAAI,OAAO,WAAW,KAAK;IACzB,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;IACvD,SAAS,MAAM,QAAQ;GACzB;GACA,IAAI,CAAC,OAAO,SAAS,IAAI;IACvB,MAAM,gBAAgB,OAAO,YAAY,QAAQ,OAAO,OAAO,YAAY,WACtE,OAAQ,OAAO,QAAgC,UAAU,WAAY,OAAO,QAA8B,QACzG,OAAQ,OAAO,QAAkC,YAAY,WAAY,OAAO,QAAgC,UAC9G,KACJ;IAGJ,MAAM,UAAU,kBAAkB,KAC9B,gBACA,OAAO,cACL,UAAU,OAAO,SAAS,cAC1B,OAAO,KAAK,KAAK,MAAM,KACrB,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,GAAG,GAAG,IAC/B,UAAU,OAAO;IACzB,MAAM,IAAI,MAAM,OAAO;GACzB;GACA,IAAI,OAAO,aAAa,MAAM,IAAI,MAAM,UAAU,OAAO,SAAS,WAAW;GAC7E,OAAO,OAAO;EAChB;EAGA,MAAM,gBAAgB,QAAsC;GAC1D,IAAI,QAAQ,MAAM,OAAO;GACzB,IAAI;IACF,MAAM,SAAS,IAAI,IAAI,GAAG;IAC1B,MAAM,WAAW,SAAS,WAAW,IAAI,IAAI,SAAS,QAAQ,IAAI;IAClE,IAAI,aAAa,QAAQ,SAAS,WAAW,OAAO,QAClD,OAAO,SAAS,SAAS,OAAO,WAAW,OAAO,SAAS,OAAO;IAEpE,OAAO,OAAO;GAChB,QAAQ;IACN,OAAO;GACT;EACF;EAEA,MAAM,YAAY,EAChB,MACA,MACA,QACA,cACA,YACA,aAQI;GACJ,MAAM,aAAa,KAAK,eAAe;GACvC,MAAM,WAAW,aAAa,KAAK,OAAO,YAAY,IAAI;GAC1D,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;IACE,OAAO;KACL,QAAQ,eAAe,OAAO;KAC9B,cAAc;KACd,YAAY,OAAO;KACnB,SAAS;KACT,SAAS;KACT,KAAK;IACP;IARF,UAAA;KAUE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAQ,YAAY;OAAc,KAAK;MAAG;MAAjE,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QAAE,MAAM;QAAG,UAAU;OAAE;OAAnC,UAAA;QACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,OAAO;UAAE,SAAS;UAAQ,YAAY;UAAU,KAAK;UAAG,UAAU;UAAQ,cAAc;SAAE;SAA/F,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,KAAD;UAAK,MAAM,aAAa,SAAS;UAC9B,UAAA,aAAc,KAAK,OAAO,SAAS,eAAgB;SACjD,CAAA,GACJ,KAAK,MAAM,KAAK,QACf,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,KAAD;UAAe,MAAK;UAAS,UAAA;SAAS,GAA5B,GAA4B,CACvC,CACE;;QACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,OAAO;UAAE,UAAU;UAAI,YAAY;UAAK,OAAO,OAAO;UAAM,YAAY;SAAK;SAC/E,UAAA,KAAK;QACH,CAAA;QACJ,KAAK,cACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,OAAO;UAAE,UAAU;UAAI,OAAO,OAAO;UAAO,WAAW;UAAG,YAAY;SAAI;SAC5E,UAAA,KAAK;QACH,CAAA,IACH;OACD;MACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,OAAO,EAAE,MAAM,OAAO;OAAG,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,KAAD;QAAK,MAAM,cAAc,KAAK,MAAM;QAAI,UAAA,KAAK;OAAiB,CAAA;MAAO,CAAA,CACjG;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAQ,YAAY;OAAU,KAAK;OAAG,UAAU;OAAQ,UAAU;OAAI,OAAO,OAAO;MAAM;MAAjH,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,aAAa,SAAS,KAAW,CAAA;OACvC,KAAK,UAAU,KAAK,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,QAAK,KAAK,SAAS,EAAS,EAAA,CAAA,IAAI;OAC3D,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO,EAAE,YAAY,OAAO;QAAI,UAAA,aAAa,KAAK,SAAS;OAAQ,CAAA;MACtE;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAQ,KAAK;OAAG,UAAU;MAAO;MAAxD,UAAA;OACG,cAAc,WACb,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;QAAQ,MAAK;QAAK,SAAQ;QAAU,eAAe,OAAO,KAAK,UAAU,UAAU,qBAAqB;QAAG,UAAA;OAEnG,CAAA,IACN;OACH,KAAK,WAAW,eAAe,KAAK,WAAW,cAC9C,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,MAAK;QAAK,SAAQ;QAAU,UAAU,UAAU;QAAM,eAAe,WAAW,IAAI;QACzF,UAAA,SAAS,SAAS;OACb,CAAA,IACN;OACJ,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,MAAK;QAAK,SAAQ;QAAQ,eAAe,OAAO,IAAI;QAAG,UAAA;OAAU,CAAA;OACxE,CAAC,cAAc,KAAK,WAAW,mBAC9B,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,MAAK;QAAK,SAAQ;QAAU,UAAU;QAAM,eAAe,aAAa,MAAM,QAAQ;QAAG,UAAA;OAAU,CAAA,IACzG;OACH,CAAC,cAAc,KAAK,WAAW,gBAC9B,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,MAAK;QAAK,SAAQ;QAAU,UAAU;QAAM,eAAe,aAAa,MAAM,QAAQ;QAAG,UAAA;OAAY,CAAA,IAC3G;OACH,CAAC,cAAc,KAAK,WAAW,oBAC9B,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,MAAK;QAAK,SAAQ;QAAU,UAAU;QAAM,eAAe,aAAa,MAAM,UAAU;QAAG,UAAA;OAAU,CAAA,IAC3G;OACH,CAAC,cAAc,KAAK,WAAW,eAAe,KAAK,WAAW,cAC7D,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;QAAQ,MAAK;QAAK,SAAQ;QAAQ,UAAU;QAAM,eAAe,aAAa,MAAM,QAAQ;QAAG,UAAA;OAAU,CAAA,IACvG;MACD;;IACE;;EAEb;EAsCA,MAAM,cAAsC;GAC1C,iBAAiB;GACjB,aAAa;GACb,sBAAsB;GACtB,qBAAqB;GACrB,gBAAgB;GAChB,WAAW;GACX,WAAW;GACX,kBAAkB;GAClB,MAAM;GACN,MAAM;GACN,QAAQ;GACR,aAAa;GACb,gBAAgB;GAChB,gBAAgB;GAChB,WAAW;GACX,YAAY;GACZ,kBAAkB;GAClB,mBAAmB;GACnB,wBAAwB;GACxB,gBAAgB;GAChB,iBAAiB;GACjB,sBAAsB;GACtB,aAAa;GACb,cAAc;GACd,cAAc;GACd,YAAY;GACZ,aAAa;GACb,iBAAiB;GACjB,iBAAiB;GACjB,aAAa;GACb,cAAc;EAChB;EAEA,MAAM,iCAAiB,IAAI,IAAI;GAC7B;GACA;GACA;GACA;GACA;GACA;EACF,CAAC;EAED,MAAM,eAAe,UAAkB;GACrC,IAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG,OAAO;GACjD,IAAI,QAAQ,MAAM,OAAO,QAAQ;GACjC,IAAI,QAAQ,SAAa,QAAQ,QAAQ,KAAA,CAAM,QAAQ,CAAC,IAAI;GAC5D,QAAQ,QAAS,QAAA,CAAc,QAAQ,CAAC,IAAI;EAC9C;EAEA,MAAM,iBAAiB,QAAgB,IACpC,QAAQ,sBAAsB,OAAO,CAAC,CACtC,QAAQ,UAAU,GAAG,CAAC,CACtB,KAAK;EAER,MAAM,mBAAmB,KAAa,UAA2B;GAC/D,IAAI,QAAQ,mBAAmB;IAC7B,IAAI,UAAU,YAAY,OAAO;IACjC,IAAI,UAAU,OAAO,OAAO;GAC9B;GACA,IAAI,OAAO,UAAU,WAAW,OAAO,QAAQ,MAAM;GACrD,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,KAAK,SAAS,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;GAC3E,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;IAC/C,MAAM,SAAS;IACf,IAAI,OAAO,OAAO,SAAS,UAAU,OAAO,OAAO;IACnD,OAAO,KAAK,UAAU,KAAK;GAC7B;GACA,OAAO,OAAO,KAAK;EACrB;EAEA,MAAM,eAAe,KAAa,WAAmC;GACnE;GACA,OAAO,YAAY,QAAQ,cAAc,GAAG;GAC5C;GACA,GAAI,QAAQ,YAAY,QAAQ,iBAAiB,QAAQ,gBACrD;IAAE,MAAM;IAAsB,MAAM;GAAW,IAC/C,CAAC;EACP;EAEA,MAAM,cAAc,SAClB,SAAS,KAAA,IACL,CAAC,IACD,OAAO,QAAQ,IAAI,CAAC,CACnB,QAAQ,CAAC,KAAK,WAAW,CAAC,eAAe,IAAI,GAAG,KAAK,UAAU,QAAQ,UAAU,KAAA,KAAa,UAAU,EAAE,CAAC,CAC3G,KAAK,CAAC,KAAK,WAAW,YAAY,KAAK,KAAK,CAAC;EAGpD,MAAM,wBAAwB,WAAwD;GACpF,IAAI,WAAW,MAAM,OAAO,CAAC;GAC7B,MAAM,WAA8B,CAAC;GACrC,MAAM,oBAAoB,WAAW,OAAO,SAAS,IAAI;GACzD,IAAI,kBAAkB,SAAS,GAAG,SAAS,KAAK;IAAE,OAAO;IAAQ,QAAQ;GAAkB,CAAC;GAC5F,MAAM,iBAAiB,WAAW,OAAO,SAAS,uBAAuB,IAAI;GAC7E,IAAI,eAAe,SAAS,GAAG,SAAS,KAAK;IAAE,OAAO;IAAQ,QAAQ;GAAe,CAAC;GACtF,MAAM,YAAY,CAChB,GAAI,OAAO,SAAS,iBAAiB,CAAC,GACtC,GAAI,OAAO,SAAS,uBAAuB,iBAAiB,CAAC,CAC/D;GACA,IAAI,UAAU,SAAS,GACrB,SAAS,KAAK;IACZ,OAAO;IACP,QAAQ,CAAC;KAAE,KAAK;KAAa,OAAO;KAAM,OAAO;KAAW,MAAM;KAAa,MAAM;IAAE,CAAC;GAC1F,CAAC;GAEH,OAAO;EACT;EAEA,MAAM,iBAAiB,EAAE,YACvB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GAAK,OAAO;IAAE,SAAS;IAAQ,KAAK;GAAE;GACnC,UAAA,MAAM,KAAK,MAAM,UAAU;IAC1B,MAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,MAAM,QAAQ;IACtH,MAAM,SAAS;KAAC,KAAK;KAAO,KAAK;KAAK,KAAK;IAAE,CAAC,CAAC,QAAQ,UAAU,OAAO,UAAU,YAAY,OAAO,UAAU,QAAQ,CAAC,CAAC,KAAK,KAAK;IACnI,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAgD,OAAO;MAAE,SAAS;MAAQ,YAAY;MAAY,KAAK;MAAG,UAAU;KAAE;KAAtH,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,OAAO;OAAE,UAAU;OAAI,OAAO,OAAO;MAAK;MAAI,UAAA;KAAY,CAAA,GAC/D,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,OAAO;OAAE,UAAU;OAAI,OAAO,OAAO;OAAO,UAAU;OAAU,cAAc;OAAY,YAAY;MAAS;MAAI,UAAA;KAAa,CAAA,IAAI,IACjJ;IAHK,GAAA,OAAO,KAAK,OAAO,KAAK,MAAM,KAAK,CAGxC;GAET,CAAC;EACE,CAAA;EAGP,MAAM,oBAAoB,EAAE,eAAgD;GAC1E,IAAI,SAAS,WAAW,GAAG,OAAO;GAClC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAO;KAAE,SAAS;KAAQ,KAAK;IAAG;IACpC,UAAA,SAAS,KAAK,SAAS,iBACtB,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;KAA4C,OAAO;MAAE,QAAQ,eAAe,OAAO;MAAM,cAAc;MAAI,YAAY,OAAO;MAAO,SAAS;KAAG;KAAjJ,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO;OAAE,UAAU;OAAI,YAAY;OAAK,OAAO,OAAO;OAAM,cAAc;MAAE;MAAI,UAAA,QAAQ;KAAW,CAAA,GACxG,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,OAAO;OAAE,QAAQ;OAAG,SAAS;OAAQ,qBAAqB;OAA6B,KAAK;MAAW;MACxG,UAAA,QAAQ,OAAO,KAAK,UACnB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAEE,OAAO;QACL,SAAS;QACT,qBAAqB;QACrB,YAAY;QACZ,KAAK;QACL,UAAU;QACV,YAAY,MAAM,SAAS,IAAI,WAAW,KAAA;OAC5C;OATF,UAAA,CAWE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAI,OAAO;SAAE,UAAU;SAAI,YAAY;SAAK,OAAO,OAAO;QAAM;QAAI,UAAA,MAAM;OAAU,CAAA,GACpF,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAI,OAAO;SAAE,QAAQ;SAAG,UAAU;SAAI,YAAY;SAAK,OAAO,OAAO;SAAM,YAAY;SAAY,cAAc;QAAW;QACzH,UAAA,MAAM,SAAS,eAAe,MAAM,QAAQ,MAAM,KAAK,IACpD,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD,EAAe,OAAO,MAAM,MAA0C,CAAA,IACtE,MAAM,UAAU,QAAQ,MAAM,UAAU,KAAA,KAAa,MAAM,UAAU,KACnE,MACA,gBAAgB,MAAM,KAAK,MAAM,KAAK;OAC1C,CAAA,CACD;MAlBE,GAAA,MAAM,GAkBR,CACN;KACC,CAAA,CACG;IA1BK,GAAA,QAAQ,QAAQ,YA0BrB,CACV;GACE,CAAA;EAET;;EAGA,MAAM,oBAAoB;;EAE1B,MAAM,sBAAsB;;EAG5B,MAAM,yBAAyB,OAAgB,aAA8B;GAC3E,IAAI,UAAU,OAAO;GACrB,MAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GACjE,IAAI,6DAA6D,KAAK,GAAG,GACvE,OAAO;GAET,OAAO;EACT;EAEA,MAAM,cAAc,EAAE,MAAM,aAAqD;GAC/E,MAAM,aAAa,KAAK,eAAe;GACvC,MAAM,CAAC,QAAQ,cAAA,GAAaC,MAAAA,SAAAA,CAAmC,IAAI;GACnE,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAAS,IAAI;GACvD,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAwB,IAAI;GAClE,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAS,KAAK;GAClD,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAAS,CAAC;GAEpD,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,QAAQ;IACZ,MAAM,aAAa,IAAI,gBAAgB;IACvC,IAAI,WAAW;IACf,MAAM,UAAU,OAAO,iBAAiB;KAAE,WAAW;KAAM,WAAW,MAAM;IAAE,GAAG,iBAAiB;IAClG,MAAM,WAAW,OAAO,iBAAiB;KAAE,IAAI,OAAO,cAAc,IAAI;IAAE,GAAG,mBAAmB;IAChG,UAAU,IAAI;IACd,iBAAiB,IAAI;IACrB,eAAe,IAAI;IACnB,cAAc,KAAK;IACnB,UAA+C,YAAY,mBAAmB,KAAK,EAAE,GAAG,EAAE,QAAQ,WAAW,OAAO,CAAC,CAAC,CACnH,MAAM,YAAY;KAAE,IAAI,OAAO,UAAU,QAAQ,UAAU,IAAI;IAAE,CAAC,CAAC,CACnE,OAAO,UAAU;KAAE,IAAI,OAAO,eAAe,sBAAsB,OAAO,QAAQ,CAAC;IAAE,CAAC,CAAC,CACvF,cAAc;KACb,OAAO,aAAa,OAAO;KAC3B,OAAO,aAAa,QAAQ;KAC5B,IAAI,OAAO;MACT,iBAAiB,KAAK;MACtB,cAAc,KAAK;KACrB;IACF,CAAC;IACH,aAAa;KACX,QAAQ;KACR,WAAW,MAAM;KACjB,OAAO,aAAa,OAAO;KAC3B,OAAO,aAAa,QAAQ;IAC9B;GACF,GAAG,CAAC,KAAK,IAAI,aAAa,CAAC;GAE3B,MAAM,WAAW,aAAa,qBAAqB,MAAM,IAAI,QAAQ,MAAM,YAAY,CAAC;GACxF,MAAM,cAAc,QAAQ,eAAe,CAAC;GAC5C,MAAM,iBAAiB,cAAc,OAAO,QAAQ,OAAO,WAAW,OAAO,KAAK;GAClF,MAAM,kBAAkB,eAAqC,mBAAmB,OAC5E,OACA,QAAQ,wBAAwB,mBAAmB,OAAO,cAAc,CAAC,IACvE,mBAAmB,mBAAmB,WAAW,EAAE;GAEzD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;KAAE,SAAS;KAAQ,eAAe;KAAU,KAAK;KAAI,MAAM;KAAG,WAAW;IAAO;IAA5F,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAQ,YAAY;OAAc,KAAK;MAAG;MAAjE,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QAAE,MAAM;QAAG,UAAU;OAAE;OAAnC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,OAAO;SAAE,UAAU;SAAI,YAAY;SAAK,OAAO,OAAO;SAAM,YAAY;QAAK;QAAI,UAAA,KAAK;OAAW,CAAA,GACtG,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,OAAO;SAAE,WAAW;SAAG,UAAU;SAAI,OAAO,OAAO;QAAM;QAA9D,UAAA;SACG,KAAK,OAAO,UAAU,aAAa,eAAe;SAAQ;SAAI,aAAa,KAAK,SAAS;QACvF;OACF,CAAA,CAAA;MACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAACF,sCAAAA,KAAD;OAAK,MAAM,cAAc,KAAK,MAAM;OAAI,UAAA,KAAK;MAAiB,CAAA,CAC3D;;KAEJ,gBACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAI,WAAW;OAAU,OAAO,OAAO;OAAO,UAAU;OAAI,SAAS;OAAQ,KAAK;MAAE;MAA3G,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,UAAa,CAAA,GAClB,aAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,OAAO,EAAE,UAAU,GAAG;OAAG,UAAA;MAAsB,CAAA,IAAI,IACpE;KACH,CAAA,IAAA;KACH,cACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,MAAK;MAAQ,OAAO;OAAE,SAAS;OAAY,cAAc;OAAG,YAAY;OAAW,OAAO,OAAO;OAAQ,UAAU;OAAI,SAAS;OAAQ,YAAY;OAAU,KAAK;MAAE;MAA1K,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,OAAO;QAAE,MAAM;QAAG,UAAU;QAAG,YAAY;OAAI;OAAI,UAAA;MAAkB,CAAA,GAC3E,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,QAAD;OAAQ,MAAK;OAAK,SAAQ;OAAU,eAAe,kBAAkB,UAAU,QAAQ,CAAC;OAAG,UAAA;MAAU,CAAA,CAClG;KACH,CAAA,IAAA;KACH,CAAC,iBAAiB,gBAAgB,QAAQ,SAAS,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAD,EAA4B,SAAW,CAAA,IAAI;KAC3G,CAAC,iBAAiB,gBAAgB,QAAQ,SAAS,WAAW,KAAK,CAAC,cAAc,KAAK,cACtF,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO;OAAE,QAAQ,eAAe,OAAO;OAAM,cAAc;OAAI,YAAY,OAAO;OAAO,SAAS;OAAI,UAAU;OAAI,YAAY;OAAK,OAAO,OAAO;OAAM,YAAY;MAAW;MAAI,UAAA,KAAK;KAAiB,CAAA,IAC7M;KACH,CAAC,iBAAiB,gBAAgB,QAAQ,SAAS,WAAW,MAAM,cAAc,CAAC,KAAK,eACvF,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAI,WAAW;OAAU,OAAO,OAAO;OAAO,UAAU;MAAG;MAAG,UAAA;KAAW,CAAA,IAC9F;KAEH,cAAc,YAAY,SAAS,IAClC,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;MAAS,OAAO;OAAE,QAAQ,eAAe,OAAO;OAAM,cAAc;OAAI,YAAY,OAAO;OAAO,SAAS;MAAG;MAA9G,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,UAAU;QAAI,YAAY;QAAK,OAAO,OAAO;QAAM,cAAc;OAAE;OAAG,UAAA;MAAO,CAAA,GAC1F,YAAY,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,UAAU;QAAI,OAAO,OAAO;OAAM;OAAG,UAAA;MAAS,CAAA,IACtF,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,KAAK;OAAE;OACnC,UAAA,YAAY,KAAK,eAAe;QAC/B,MAAM,OAAO,eAAe,UAAU;QACtC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAyB,OAAO;UAAE,SAAS;UAAQ,YAAY;UAAU,KAAK;UAAG,UAAU;SAAE;SAA7F,UAAA;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,OAAO;YAAE,MAAM;YAAG,UAAU;YAAG,UAAU;YAAI,OAAO,OAAO;YAAM,UAAU;YAAU,cAAc;YAAY,YAAY;WAAS;WAAI,UAAA,WAAW;UAAmB,CAAA;UAC5K,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,OAAO;YAAE,MAAM;YAAQ,UAAU;YAAI,OAAO,OAAO;WAAM;WAAI,UAAA,YAAY,WAAW,SAAS;UAAQ,CAAA;UAC1G,SAAS,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;WAAQ,MAAK;WAAK,SAAQ;WAAQ,eAAe,OAAO,KAAK,MAAM,UAAU,qBAAqB;WAAG,UAAA;UAAU,CAAA,IAAI;SACjI;QAJK,GAAA,WAAW,EAIhB;OAET,CAAC;MACE,CAAA,CAEA;KACP,CAAA,IAAA;KAEJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;OAAE,SAAS;OAAQ,gBAAgB;OAAY,KAAK;OAAG,UAAU;OAAQ,WAAW;OAAQ,YAAY;MAAE;MAAtH,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;OAAQ,MAAK;OAAK,SAAQ;OAAQ,SAAS;OAAQ,UAAA;MAAc,CAAA,GAChE,cAAc,KAAK,OAAO,WACzB,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;OAAQ,MAAK;OAAK,SAAQ;OAAU,eAAe,OAAO,KAAK,aAAa,KAAK,OAAO,YAAY,IAAI,KAAK,KAAK,UAAU,qBAAqB;OAAG,UAAA;MAE5I,CAAA,IACN,IACD;;IACF;;EAET;EAIA,MAAM,oBAAoB,EAAE,kBAEtB;GACJ,MAAM,CAAC,MAAM,YAAA,GAAWC,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAqB,CAAC,CAAC;GACjD,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,KAAK;GAC5C,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAwB,IAAI;GACtD,MAAM,CAAC,KAAK,WAAA,GAAUA,MAAAA,SAAAA,CAAkB,KAAK;GAC7C,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAwB,IAAI;GACxD,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAwB,IAAI;GAC5D,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAA0B,IAAI;GAC9D,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAA+C,IAAI;GAC/E,MAAM,CAAC,cAAc,oBAAA,GAAmBA,MAAAA,SAAAA,CAAS,CAAC;GAElD,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,SAAS,eAAe,iBAAiB,MAAM,MAAM;IACzD,MAAM,QAAQ,SAAS,cAAc,OAAO;IAC5C,MAAM,KAAK;IACX,MAAM,cAAc;IACpB,SAAS,KAAK,OAAO,KAAK;IAC1B,aAAa;KAAE,MAAM,OAAO;IAAE;GAChC,GAAG,CAAC,CAAC;GAEL,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,MAAM,eAAe;KAEnB,IADkB,SAAS,cAAc,mCAAiC,MAAM,MACjE;MACb,WAAW,YAAa,YAAY,OAAO,UAAU,IAAK;MAC1D;KACF;KAEA,MAAM,SADU,MAAM,KAAK,SAAS,iBAAiB,QAAQ,CACxC,CAAC,CAAC,MAAM,WAAW,0BAA0B,MAAM,OAAO,aAAa,YAAY,KAAK,GAAA,CAAI,KAAK,CAAC,CAAC;KACxH,IAAI,CAAC,QAAQ;MACX,WAAW,YAAa,YAAY,OAAO,UAAU,IAAK;MAC1D;KACF;KACA,MAAM,SAAS,OAAO,aAAa,YAAY,KAAK,GAAA,CAAI,KAAK;KAC7D,IAAI,wBAAwB,KAAK,KAAK,GAAG;MACvC,WAAW,YAAa,YAAY,OAAO,UAAU,IAAK;MAC1D;KACF;KACA,MAAM,OAAO,OAAO,sBAAsB;KAC1C,IAAI,KAAK,UAAU,KAAK,KAAK,WAAW,GAAG;KAC3C,MAAM,OAAO;MAAE,MAAM,KAAK,IAAI,GAAG,KAAK,OAAO,EAAE;MAAG,KAAK,KAAK,OAAO,KAAK,SAAS,MAAM;KAAE;KACzF,WAAW,YACT,YAAY,QAAQ,KAAK,IAAI,QAAQ,OAAO,KAAK,IAAI,IAAI,MAAO,KAAK,IAAI,QAAQ,MAAM,KAAK,GAAG,IAAI,KAC/F,UACA,IACL;IACH;IACA,OAAO;IACP,MAAM,QAAQ,OAAO,YAAY,QAAQ,GAAG;IAC5C,OAAO,iBAAiB,UAAU,MAAM;IACxC,aAAa;KACX,OAAO,cAAc,KAAK;KAC1B,OAAO,oBAAoB,UAAU,MAAM;IAC7C;GACF,GAAG,CAAC,CAAC;GAEL,MAAM,OAAO,OAAO,SAAS,UAAU;IACrC,IAAI,CAAC,QAAQ,WAAW,IAAI;IAC5B,SAAS,IAAI;IACb,IAAI;KACF,MAAM,WAAW,MAAM,UAAiC,WAAW;KACnE,SAAS,CAAC,GAAG,SAAS,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC,CAAC;IACrF,SAAS,OAAO;KACd,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;IACjE,UAAU;KACR,IAAI,CAAC,QAAQ,WAAW,KAAK;IAC/B;GACF;GAEA,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,CAAC,MAAM;IACX,KAAU;IACV,MAAM,QAAQ,OAAO,kBAAkB;KAAE,KAAU,IAAI;IAAE,GAAG,GAAM;IAClE,aAAa;KAAE,OAAO,cAAc,KAAK;IAAE;GAC7C,GAAG,CAAC,IAAI,CAAC;GAET,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,QAAQ;IACZ,MAAM,UAAU,YAAY;KAC1B,IAAI;MACF,MAAM,SAAS,MAAM,UAA8B,QAAQ;MAC3D,IAAI,OAAO,gBAAgB,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC;KAC/E,QAAQ,CAER;IACF;IACA,QAAa;IACb,MAAM,QAAQ,OAAO,kBAAkB;KAAE,QAAa;IAAE,GAAG,GAAO;IAClE,aAAa;KAAE,QAAQ;KAAO,OAAO,cAAc,KAAK;IAAE;GAC5D,GAAG,CAAC,CAAC;GAEL,MAAM,YAAA,GAAWC,MAAAA,QAAAA,OAAc;IAC7B,IAAI,QAAQ,SAAS,OAAO,MAAM,QAAQ,SAAS,KAAK,eAAe,cAAc,KAAK,OAAO,KAAK,SAAS,OAAO,CAAC;IACvH,IAAI,QAAQ,QAAQ,OAAO,MAAM,QAAQ,SAAS,KAAK,WAAW,eAAe,KAAK,WAAW,WAAW;IAC5G,IAAI,QAAQ,YAAY,OAAO,MAAM,QAAQ,SAAS,KAAK,eAAe,cAAc,CAAC,KAAK,OAAO,KAAK,SAAS,OAAO,CAAC;IAC3H,OAAO;GACT,GAAG,CAAC,OAAO,GAAG,CAAC;GAEf,MAAM,aAAa,MAAM,QAAQ,SAAS,KAAK,WAAW,eAAe,KAAK,WAAW,WAAW,CAAC,CAAC;GACtG,MAAM,WAAgE;IACpE;KAAE,OAAO;KAAO,IAAI;KAAoB,SAAS;KAAsB,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,OAAG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,OAAO,EAAE,SAAS,IAAK;MAAI,UAAA,MAAM;KAAa,CAAA,CAAO,EAAA,CAAA;IAAE;IACpJ;KAAE,OAAO;KAAQ,IAAI;KAAqB,SAAS;KAAuB,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,SAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,OAAO,EAAE,SAAS,IAAK;MAAI,UAAA;KAAiB,CAAA,CAAO,EAAA,CAAA;IAAE;IACvJ;KAAE,OAAO;KAAY,IAAI;KAAyB,SAAS;KAA2B,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,OAAG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,OAAO,EAAE,SAAS,IAAK;MAAI,UAAA,MAAM,QAAQ,SAAS,KAAK,eAAe,cAAc,CAAC,KAAK,OAAO,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC;KAAa,CAAA,CAAO,EAAA,CAAA;IAAE;IAC3P;KAAE,OAAO;KAAS,IAAI;KAAsB,SAAS;KAAwB,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,OAAG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,OAAO,EAAE,SAAS,IAAK;MAAI,UAAA,MAAM,QAAQ,SAAS,KAAK,eAAe,cAAc,KAAK,OAAO,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC;KAAa,CAAA,CAAO,EAAA,CAAA;IAAE;GACnP;GAEA,MAAM,aAAa,OAAO,MAAgB,WAAmB;IAC3D,UAAU,KAAK,EAAE;IACjB,SAAS,IAAI;IACb,IAAI;KACF,MAAM,MAAM,QAAQ,cAAc,mBAAmB,KAAK,GAAG,MAAM,CAAC,CAAC,IAAI,eAAe;MACtF,QAAQ;MACR,SAAS,EAAE,gBAAgB,mBAAmB;MAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,CAAC;KACjC,CAAC,CAAC,CAAC,KAAK,OAAO,aAAa;MAC1B,IAAI,CAAC,SAAS,IAAI;OAChB,MAAM,UAAU,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,IAAI;OACtD,MAAM,IAAI,MAAM,SAAS,SAAS,QAAQ;MAC5C;KACF,CAAC;KACD,MAAM,KAAK;IACb,SAAS,OAAO;KACd,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;IACjE,UAAU;KACR,UAAU,IAAI;IAChB;GACF;GAEA,MAAM,WAAW,OAAO,SAAmB;IACzC,YAAY,KAAK,EAAE;IACnB,SAAS,IAAI;IACb,IAAI;KACF,MAAM,WAAW,MAAM,MAAM,QAAQ,cAAc;MACjD,QAAQ;MACR,SAAS,EAAE,gBAAgB,mBAAmB;MAC9C,MAAM,KAAK,UAAU,EAAE,IAAI,KAAK,GAAG,CAAC;KACtC,CAAC;KACD,MAAM,UAAU,MAAM,SAAS,KAAK;KACpC,IAAI,CAAC,SAAS,MAAM,OAAO,QAAQ,cAAc,UAC/C,MAAM,IAAI,MAAM,QAAQ,SAAS,aAAa;KAEhD,YAAY,QAAQ,SAAS;KAC7B,QAAQ,KAAK;IACf,SAAS,OAAO;KACd,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;IACjE,UAAU;KACR,YAAY,IAAI;IAClB;GACF;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACG,WAAW,OACV,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;IACE,MAAK;IACL,cAAW;IACX,OAAM;IACN,eAAe,SAAS,UAAU,CAAC,KAAK;IACxC,OAAO;KACL,UAAU;KACV,MAAM,OAAO;KACb,KAAK,OAAO;KACZ,QAAQ;KACR,OAAO;KACP,QAAQ;KACR,SAAS;KACT,QAAQ;KACR,cAAc;KACd,YAAY;KACZ,OAAO,aAAa,IAAI,OAAO,SAAS,OAAO;KAC/C,QAAQ;KACR,eAAe;KACf,SAAS;KACT,YAAY;KACZ,gBAAgB;IAClB;IAtBF,UAAA,CAwBE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,OAAM;KAAK,QAAO;KAAK,SAAQ;KAAY,MAAK;KAAO,QAAO;KAAe,aAAY;KAAM,eAAc;KAAQ,gBAAe;KAAQ,eAAY;KAA7J,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,GAAE,kDAAmD,CAAA,GAC3D,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,GAAE,2BAA4B,CAAA,CACjC;IACJ,CAAA,GAAA,eAAe,IACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,OAAO;MAAE,UAAU;MAAY,QAAQ;MAAI,OAAO;MAAI,UAAU;MAAI,QAAQ;MAAI,SAAS;MAAS,WAAW;MAAc,cAAc;MAAK,YAAY;MAAW,OAAO;MAAQ,UAAU;MAAG,YAAY;MAAQ,WAAW;KAAS;KAC5O,UAAA,eAAe,KAAK,QAAQ;IACzB,CAAA,IACJ,IACE;GACN,CAAA,IAAA,MAEJ,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;IAAa;IAAM,eAAe,QAAQ,KAAK;IAAG,OAAM;IAAO,UAAA;IAAS,WAAW;IACjF,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,OAAO;MAAE,SAAS;MAAQ,eAAe;MAAU,OAAO;MAAQ,QAAQ;MAAQ,WAAW;KAAE;KAApG,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,OAAO;QAAE,SAAS;QAAQ,YAAY;QAAU,KAAK;QAAG,SAAS;OAAiB;OAA1F,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,OAAO;UAAE,MAAM;UAAG,UAAU;SAAE;SACjC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;UAAI,OAAO;WAAE,QAAQ;WAAG,UAAU;WAAI,YAAY;WAAQ,YAAY;WAAK,OAAO,OAAO;UAAK;UAAG,UAAA;SAAQ,CAAA;QACtG,CAAA;QACL,iBAAA,GAAA,kBAAA,IAAA,CAACH,sCAAAA,QAAD;SAAQ,MAAK;SAAK,SAAQ;SAAQ,eAAe,KAAK,KAAK;SAAG,UAAA;QAAU,CAAA;QACxE,iBAAA,GAAA,kBAAA,IAAA,CAACA,sCAAAA,QAAD;SAAQ,MAAK;SAAK,SAAQ;SAAQ,cAAW;SAAK,OAAM;SAAK,eAAe,QAAQ,KAAK;SAAG,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAACI,sCAAAA,yBAAD,EAAyB,MAAM,GAAK,CAAA;SAAG,OAAO;UAAE,OAAO;UAAI,SAAS;SAAE;QAAI,CAAA;OACtK;;MACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAe,cAAc,eAAe,OAAO;OAAK;OAC7E,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,eAAD;QAAe,OAAO;QAAU,OAAO;QAAK,UAAU;QAAQ,OAAM;OAAU,CAAA;MAC3E,CAAA;MACJ,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAY,cAAc;QAAG,YAAY;QAAW,OAAO,OAAO;QAAQ,UAAU;QAAI,QAAQ;OAAc;OAAI,UAAA;MAAW,CAAA,IAAI;MACjK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,IAAI,oBAAoB;OAAK,MAAK;OAAW,mBAAiB,kBAAkB;OAAK,OAAO;QAAE,SAAS;QAAkB,SAAS;QAAQ,eAAe;QAAU,KAAK;QAAI,WAAW;QAAQ,MAAM;OAAE;OACzM,UAAA,aAAa,OACZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;QAAY,MAAM;QAAU,cAAc,YAAY,IAAI;OAAI,CAAA,IAE9D,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;QACG,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,OAAO;UAAE,SAAS;UAAI,WAAW;UAAU,OAAO,OAAO;UAAO,UAAU;SAAG;SAAG,UAAA;QAAU,CAAA,IAAI;QAC7G,CAAC,WAAW,SAAS,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,OAAO;UAAE,SAAS;UAAI,WAAW;UAAU,OAAO,OAAO;UAAO,UAAU;SAAG;SAAG,UAAA;QAAS,CAAA,IAAI;QACtI,CAAC,WAAW,SAAS,KAAK,SACzB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAA8B;SAAM,MAAM,WAAW,KAAK;SAAI,QAAQ,aAAa,KAAK;SAAI,eAAe,MAAM,WAAW,KAAK,WAAW,MAAM,MAAM;SAAG,aAAa,SAAS,KAAK,SAAS,IAAI;SAAG,QAAQ;QAAc,GAA7M,KAAK,EAAwM,CAC7N;OACD,EAAA,CAAA;MAED,CAAA;KACF;;GACA,CAAA,CACP,EAAA,CAAA;EAEN;EAaA,MAAM,wCAAwB,IAAI,IAAI,CAAC,gBAAgB,mBAAmB,CAAC;EAE3E,MAAM,eAAe,YAA6B;GAChD,IAAI,CAAC,MAAM,QAAQ,OAAO,GAAG,OAAO;GACpC,OAAO,QAAQ,KAAK,UAAU;IAC5B,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO;IACxD,MAAM,SAAS;IACf,OAAO,OAAO,SAAS,UAAU,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;GACnF,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK;EACrC;EAEA,MAAM,eAAe,UAAyD;GAE5E,OADa,MAAM,MACN,SAAS,UAAU,MAAM,SAAS,iBAAiB,SAAS;EAC3E;EAEA,MAAM,iBAAiB,OAAgC,MAA4B,MAAgC;GAEjH,MAAM,SADO,MAAM,MACE;GACrB,MAAM,aAAa,OAAO,QAAQ,eAAe,WAAW,OAAO,WAAW,KAAK,IAAI;GACvF,IAAI,eAAe,IAAI,OAAO;GAC9B,OAAO,SAAS,SAAS,EAAE,IAAI,IAAI,EAAE,WAAW;EAClD;EAEA,MAAM,eAAe,OAAO,QAAgB,MAAiD;GAC3F,MAAM,UAA0B,CAAC;GACjC,IAAI,SAAwB;GAC5B,KAAK,IAAI,OAAO,GAAG,OAAO,IAAI,QAAQ,GAAG;IACvC,MAAM,SAAS,WAAW,OAAO,KAAK,aAAa,mBAAmB,MAAM;IAC5E,MAAM,WAAW,MAAM,MAAM,+BAA+B,mBAAmB,MAAM,IAAI,YAAY,MAAM;IAC3G,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM,EAAE,OAAO,CAAC;IAC5C,MAAM,UAAU,MAAM,SAAS,KAAK;IACpC,KAAK,MAAM,UAAU,QAAQ,UAAU,CAAC,GAAG;KACzC,MAAM,QAAQ,OAAO;KACrB,IAAI,UAAU,KAAA,KAAa,OAAO,MAAM,SAAS,YAAY,CAAC,sBAAsB,IAAI,MAAM,IAAI,GAAG;KACrG,MAAM,OAAO,MAAM;KACnB,MAAM,OAAO,YAAY,KAAK;KAC9B,MAAM,OAAO,YAAY,MAAM,OAAO;KACtC,IAAI,SAAS,IAAI;KACjB,QAAQ,KAAK;MAAE,KAAK,OAAO,MAAM,OAAO,MAAM,OAAO,QAAQ,MAAM;MAAG;MAAM,QAAQ,cAAc,OAAO,MAAM,CAAC;MAAG,MAAM,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,KAAA;MAAW;MAAM,QAAQ,OAAO;KAAG,CAAC;IAC7M;IACA,IAAI,QAAQ,YAAY,QAAQ,QAAQ,eAAe,QAAQ,QAAQ,eAAe,KAAA,GAAW;IACjG,SAAS,QAAQ;GACnB;GACA,OAAO,QAAQ,MAAM,MAAM,WAAW,MAAM,QAAQ,MAAM,KAAK,QAAQ,EAAE;EAC3E;EAEA,MAAM,iBAAiB,OAAO,WAAmB,UAAmB,MAAiD;GACnH,MAAM,UAAU;GAUhB,IAAI,QAAQ,WAAW,KAAA,GAAW,OAAO,CAAC;GAC1C,MAAM,YAAY,QAAQ,OAAO,WAAW,EAAE,QAAQ,UAAU,CAAC;GACjE,IAAI;IACF,MAAM,UAAU;IAChB,MAAM,UAAU,UAAU;IAC1B,IAAI,YAAY,KAAA,GAAW,OAAO,CAAC;IACnC,MAAM,QAAQ,SAAS,YAAY,CAAC,CAAC,YAAY,KAAA,CAAS;IAC1D,MAAM,UAAU,QAAQ,aAAa,YAAY,CAAC,CAAC,WAAW,CAAC;IAC/D,OAAO,QACJ,QAAQ,UAAsE,MAAM,SAAS,WAAW,MAAM,UAAU,KAAA,CAAS,CAAC,CAClI,QAAQ,UAAU,OAAO,MAAM,MAAM,SAAS,YAAY,sBAAsB,IAAI,MAAM,MAAM,IAAI,CAAC,CAAC,CACtG,KAAK,UAAU;KACd,MAAM,QAAQ,MAAM;KACpB,MAAM,OAAO,MAAM;KACnB,MAAM,OAAO,YAAY,KAAK;KAC9B,OAAO;MACL,KAAK,OAAO,MAAM,OAAO,QAAQ,QAAQ,KAAK,CAAC;MAC/C;MACA,QAAQ,cAAc,OAAO,MAAM,CAAC;MACpC,MAAM,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,KAAA;MACpD,MAAM,YAAY,MAAM,OAAO;KACjC;IACF,CAAC,CAAC,CACD,QAAQ,UAAU,MAAM,SAAS,EAAE,CAAC,CACpC,MAAM,MAAM,WAAW,MAAM,QAAQ,MAAM,KAAK,QAAQ,EAAE;GAC/D,UAAU;IACR,UAAU,UAAU;GACtB;EACF;EAUA,MAAM,oBAAoB,SAAkB,SAAgD;GAC1F,IAAI,CAAC,MAAM,QAAQ,OAAO,GAAG,OAAO,KAAA;GACpC,KAAK,MAAM,SAAS,SAAS;IAC3B,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;IACjD,MAAM,SAAS;IACf,IAAI,OAAO,SAAS,QAAQ;IAC5B,MAAM,aAAa,OAAO;IAC1B,IAAI,YAAY,SAAS,QAAQ,OAAO,WAAW,iBAAiB,YAAY,OAAO,WAAW,UAAU,UAC1G,OAAO;KAAE,cAAc,WAAW;KAAc;KAAM,OAAO,WAAW;IAAM;GAElF;EAEF;EAEA,MAAM,wBAAwB,OAAO,WAAmB,UAAmB,SAAyD;GAClI,MAAM,UAAU;GAUhB,IAAI,QAAQ,WAAW,KAAA,GAAW,OAAO,KAAA;GACzC,MAAM,YAAY,QAAQ,OAAO,WAAW,EAAE,QAAQ,UAAU,CAAC;GACjE,IAAI;IACF,MAAM,UAAU;IAChB,MAAM,UAAU,UAAU;IAC1B,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;IAClC,MAAM,aAA4C;KAChD,MAAM,UAAU,QAAQ,aAAa,YAAY,CAAC,CAAC,WAAW,CAAC;KAC/D,KAAK,MAAM,SAAS,SAAS;MAC3B,IAAI,MAAM,SAAS,WAAW,MAAM,UAAU,KAAA,GAAW;MACzD,IAAI,MAAM,MAAM,SAAS,gBAAgB;MACzC,MAAM,OAAO,MAAM,MAAM;MACzB,MAAM,QAAQ,iBAAiB,MAAM,SAAS,IAAI;MAClD,IAAI,UAAU,KAAA,GAAW,OAAO;KAClC;IAEF;IACA,IAAI,QAAQ,KAAK;IACjB,KAAK,IAAI,OAAO,GAAG,OAAO,KAAK,UAAU,KAAA,GAAW,QAAQ,GAAG;KAC7D,MAAM,QAAQ,SAAS,YAAY,CAAC,CAAC,YAAY,KAAA,CAAS;KAC1D,QAAQ,KAAK;IACf;IACA,OAAO;GACT,UAAU;IACR,UAAU,UAAU;GACtB;EACF;;;;;;;;;;;;;;;EAgBA,MAAM,sBAAsB,EAAE,OAAO,SACnC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;GACE,OAAO;GACP,QAAQ;GACR,SAAQ;GACR,MAAK;GACL,OAAM;GACN,eAAY;GACZ,aAAY;GACZ,qBAAoB;GACpB,OAAO;IAAE,SAAS;IAAS,YAAY;GAAE;GAT3C,UAAA,CAWE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IAAQ,IAAG;IAAI,IAAG;IAAI,GAAE;IAAQ,QAAO;GAAgB,CAAA,GACvD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,GAAE;IAAuB,QAAO;IAAe,eAAc;IAAQ,gBAAe;GAAS,CAAA,CAChG;;EAGP,MAAM,iBAAiB,EAAE,WAAW,UAAU,QAAuE;GACnH,MAAM,CAAC,MAAM,YAAA,GAAWJ,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAyB,CAAC,CAAC;GACzD,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,KAAK;GAC5C,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,EAAE;GACrC,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,EAAE;GACrC,MAAM,UAAU,UAAU,WAAW,aAAa;GAElD,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,CAAC,MAAM;IACX,IAAI,QAAQ;IACZ,WAAW,IAAI;IACf,SAAS,EAAE;IACX,SAAS,EAAE;IACX,WAAW,CAAC,CAAC;IAEb,CADa,UAAU,aAAa,UAAU,MAAM,EAAoB,GAAG,CAAC,IAAI,eAAe,WAAW,UAAU,CAAC,EAAA,CAC3G,MAAM,UAAU;KAAE,IAAI,OAAO,WAAW,KAAK;IAAE,CAAC,CAAC,CACxD,OAAO,UAAU;KAAE,IAAI,OAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;IAAE,CAAC,CAAC,CACjG,cAAc;KAAE,IAAI,OAAO,WAAW,KAAK;IAAE,CAAC;IACjD,aAAa;KAAE,QAAQ;IAAM;GAC/B,GAAG;IAAC;IAAM;IAAS;IAAW;IAAU;GAAC,CAAC;GAE1C,MAAM,SAAS,MAAM,KAAK,CAAC,CAAC,kBAAkB;GAC9C,MAAM,WAAA,GAAUC,MAAAA,QAAAA,OAAc;IAC5B,IAAI,WAAW,IAAI,OAAO,CAAC;IAC3B,OAAO,QAAQ,QAAQ,UACrB,MAAM,KAAK,kBAAkB,CAAC,CAAC,SAAS,MAAM,KAAK,MAAM,OAAO,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC;GACxG,GAAG,CAAC,SAAS,MAAM,CAAC;GAEpB,MAAM,QAAQ,UAAwB;IACpC,QAAQ,KAAK;IACb,OAAO,iBAAiB;KACtB,IAAI,SAA6B,MAAM,WAAW,KAAA,IAC9C,OACA,SAAS,cAA2B,gCAA+B,IAAI,OAAO,MAAM,MAAM,IAAI,KAAI;KACtG,IAAI,WAAW,MAAM;MACnB,MAAM,OAAO,MAAM,KAAK,MAAM,GAAG,EAAE;MACnC,SAAS,CAAC,GAAG,SAAS,iBAA8B,wEAAsE,CAAC,CAAC,CACzH,MAAM,aAAa,QAAQ,aAAa,GAAA,CAAI,SAAS,IAAI,CAAC,KAAK;KACpE;KACA,IAAI,WAAW,QAAS,OAAgE,KAAK,MAAM,KAAK,MAAM,GAAG,EAAE,GAAG,OAAO,OAAO,MAAM,OAAO,OAAO,KAAK,GAAG;MAE9J,MAAM,OADY,OAAO,aACJ,CAAC,EAAE;MACxB,SAAS,gBAAgB,cAAc,OAAO,MAAM,iBAAiB;KACvE;KACA,QAAQ,eAAe;MAAE,UAAU;MAAU,OAAO;KAAS,CAAC;KAC9D,IAAI,WAAW,MAAM;MACnB,OAAO,MAAM,UAAU;MACvB,OAAO,MAAM,gBAAgB;MAC7B,OAAO,iBAAiB;OAAE,OAAQ,MAAM,UAAU;OAAI,OAAQ,MAAM,gBAAgB;MAAG,GAAG,IAAI;KAChG;IACF,GAAG,EAAE;GACP;GAEA,MAAM,mBAAkC;IACtC,OAAO;IACP,WAAW;IACX,QAAQ;IACR,SAAS;IACT,cAAc;IACd,QAAQ,eAAe,OAAO;IAC9B,YAAY,OAAO;IACnB,OAAO,OAAO;IACd,UAAU;IACV,SAAS;GACX;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IACE,MAAK;IACL,cAAY,EAAE,MAAM;IACpB,OAAO,EAAE,MAAM;IACf,mBAAiB;IACjB,eAAe,QAAQ,IAAI;IAC3B,OAAO;KAAE,SAAS;KAAe,YAAY;KAAU,gBAAgB;KAAU,OAAO;KAAI,QAAQ;KAAI,QAAQ;KAAQ,cAAc;KAAG,YAAY;KAAe,OAAO;KAAW,QAAQ;IAAU;IAExM,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD,EAAoB,MAAM,GAAK,CAAA;GACzB,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,OAAD;IAAa;IAAM,eAAe,QAAQ,KAAK;IAAG,OAAO,EAAE,OAAO;IAAG,YAAY,EAAE,OAAO;IAAG,WAAW;IACtG,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,OAAO;MAAE,OAAO;MAAQ,WAAW;MAAoB,WAAW;MAAQ,SAAS;MAAQ,KAAK;MAAI,SAAS;KAAY;KAA9H,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QAAE,UAAU;QAAY,OAAO;OAAO;OAAlD,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,MAAK;QACL,OAAO;QACP,WAAA;QACA,YAAY;QACZ,aAAa,EAAE,mBAAmB;QAClC,cAAY,EAAE,aAAa;QAC3B,WAAW,UAAU;SAAE,SAAS,MAAM,OAAO,KAAK;QAAE;QACpD,OAAO;OACR,CAAA,GACA,UAAU,KACT,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,MAAK;QACL,cAAY,EAAE,OAAO;QACrB,OAAO,EAAE,OAAO;QAChB,eAAe;SAAE,SAAS,EAAE;QAAE;QAC9B,OAAO;SAAE,UAAU;SAAY,OAAO;SAAG,KAAK;SAAO,WAAW;SAAoB,SAAS;SAAe,YAAY;SAAU,gBAAgB;SAAU,OAAO;SAAI,QAAQ;SAAI,QAAQ;SAAQ,cAAc;SAAG,YAAY;SAAe,OAAO,OAAO;SAAO,QAAQ;QAAU;QAEtR,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,yBAAD,EAAyB,MAAM,GAAK,CAAA;OAC9B,CAAA,IACN,IACD;;MAEJ,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAI,WAAW;QAAU,OAAO,OAAO;QAAO,UAAU;OAAG;OAAI,UAAA,EAAE,SAAS;MAAO,CAAA,IAAI;MACtH,CAAC,WAAW,UAAU,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,MAAK;OAAQ,OAAO;QAAE,SAAS;QAAI,OAAO,OAAO;QAAQ,UAAU;OAAG;OAAI,UAAA;MAAW,CAAA,IAAI;MACzH,CAAC,WAAW,UAAU,MAAM,WAAW,KACtC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAQ,cAAc;QAAU,KAAK;QAAG,SAAS;QAAkB,OAAO,OAAO;QAAO,WAAW;OAAS;OAAnI,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,OAAO;UAAE,SAAS;UAAe,OAAO;UAAI,QAAQ;UAAI,YAAY;UAAU,gBAAgB;UAAU,cAAc;UAAI,YAAY,OAAO;UAAU,OAAO,OAAO;SAAM;SAC/K,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD,EAAoB,MAAM,GAAK,CAAA;QAC3B,CAAA;QACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,OAAO;UAAE,UAAU;UAAI,YAAY;UAAK,OAAO,OAAO;SAAK;SAAI,UAAA,EAAE,SAAS;QAAQ,CAAA;QACxF,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,OAAO;UAAE,UAAU;UAAI,YAAY;SAAI;SAAI,UAAA,EAAE,aAAa;QAAQ,CAAA;OACrE;MACH,CAAA,IAAA;MACH,CAAC,WAAW,UAAU,MAAM,WAAW,MAAM,QAAQ,WAAW,IAC/D,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,OAAO;QAAE,SAAS;QAAI,WAAW;QAAU,OAAO,OAAO;QAAO,UAAU;OAAG;OAC/E,UAAA,QAAQ,WAAW,IAAI,EAAE,OAAO,IAAI,EAAE,WAAW;MAC/C,CAAA,IACH;MACH,CAAC,WAAW,UAAU,MAAM,WAAW,MAAM,QAAQ,KAAK,UACzD,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAEE,MAAK;OACL,eAAe,KAAK,KAAK;OACzB,OAAO;QAAE,SAAS;QAAQ,KAAK;QAAG,OAAO;QAAQ,UAAU;QAAG,WAAW;QAAQ,SAAS;QAAa,cAAc;QAAG,QAAQ,eAAe,OAAO;QAAM,YAAY,OAAO;QAAU,OAAO,OAAO;QAAM,QAAQ;OAAU;OAJjO,UAAA,CAME,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,OAAO;SAAE,SAAS;SAAQ,YAAY;SAAU,KAAK;SAAG,UAAU;SAAG,UAAU;SAAQ,UAAU;SAAI,OAAO,OAAO;QAAM;QAA/H,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,OAAO;WAAE,YAAY;WAAK,OAAO,MAAM,SAAS,SAAS,YAAY,OAAO;UAAK;UAAI,UAAA,MAAM;SAAa,CAAA;SAC7G,MAAM,SAAS,KAAA,IAAY,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,eAAe,EAAE,YAAY,CAAC,EAAQ,CAAA;SACrG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,OAAO,EAAE,YAAY,OAAO;UAAI,UAAA,EAAE,MAAM;SAAQ,CAAA;QAClD;OACN,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO;SAAE,SAAS;SAAS,UAAU;SAAG,UAAU;SAAI,YAAY;SAAM,YAAY;SAAY,cAAc;SAAY,WAAW;QAAa;QAAI,UAAA,MAAM;OAAW,CAAA,CACvK;MAXD,GAAA,MAAM,GAWL,CACT;KACE;;GACA,CAAA,CACP,EAAA,CAAA;EAEN;EAEA,MAAa,SAAS,QAAiB;GACrC,MAAM,SAAU,IAKb;GACH,IAAI,aAAa,OAAO,SAAS,YAAY;IAAE,IAAI,aAAa;IAAI,IAAI,aAAa;GAAG,CAAC,GAAG,wBAAwB;GACpH,MAAM,IAAI,OAAO,KAAK,UAAU;GAChC,MAAM,UAAU;GAOhB,MAAM,sBAAsB;GAIN,oBAAoB,gBAAgB,oBAAoB,MAAM,cAAc;GAIlG,IAAI,aAAa;IACf,MAAM,eAAe,UAA4B;KAC/C,MAAM,SAAS,MAAM;KACrB,IAAI,EAAE,kBAAkB,UAAU;KAClC,MAAM,OAAO,OAAO,QAAQ,gCAAgC;KAC5D,IAAI,EAAE,gBAAgB,cAAc;KAEpC,MAAM,YADS,SAAS,cAA2B,8CAC5B,CAAC,EAAE,aAAa,iBAAiB,KAAK;KAC7D,IAAI,cAAc,MAAM,UAAU,WAAW,aAAa,GAAG;KAC7D,MAAM,QAAQ,KAAK,aAAa,OAAO,KAAK,KAAK,UAAU,MAAM,IAAI,CAAC,CAAC,MAAM,GAAA,CAAI,KAAK;KACtF,IAAI,SAAS,IAAI;KACjB,CAAM,YAAY;MAChB,MAAM,aAAa,MAAM,sBAAsB,WAAY,IAAyC,UAAU,IAAI;MAClH,IAAI,eAAe,KAAA,GAAW;MAI9B,MAAM,OAHgB,IAEnB,UAAU,MAAM,YAAY,EAAA,EACL,OAAO,UAAU,EAAE,OAAO;MACpD,MAAM,QAAQ,kBAAkB,mBAAmB,WAAW,YAAY,IACtE,WAAW,mBAAmB,WAAW,IAAI,IAC7C,YAAY,mBAAmB,OAAO,WAAW,KAAK,CAAC,KACtD,QAAQ,KAAK,KAAK,UAAU,mBAAmB,GAAG;MACvD,MAAM,WAAW,MAAM,MAAM,QAAQ,6BAA6B,KAAK;MACvE,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM,UAAU;MAC5C,MAAM,eAAe,MAAM,SAAS,KAAK;MACzC,IAAI,OAAO,aAAa,SAAS,UAAU,MAAM,IAAI,MAAM,UAAU;MACrE,MAAM,UAAU,iCAAiC,mBAAmB,SAAS,IACzE,MAAM,aAAa,KAAK,MAAM,GAAG,CAAC,CAAC,KAAK,SAAS,mBAAmB,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;MACvF,MAAM,QAAS,IAA+E;MAC9F,IAAI,OAAO,iBAAiB,KAAA,GAAW,MAAM,aAAa,OAAO;WAC5D,OAAO,KAAK,IAAI,IAAI,8CAA8C,OAAO,OAAO,SAAS,MAAM,CAAC,CAAC,SAAS,GAAG,UAAU,qBAAqB;KACnJ,EAAA,CAAG,CAAC,CAAC,OAAO,UAAU;MAAE,QAAQ,MAAM,kCAAkC,KAAK;KAAE,CAAC;IAClF;IACA,SAAS,iBAAiB,SAAS,aAAa,IAAI;IACpD,aAAa;KAAE,SAAS,oBAAoB,SAAS,aAAa,IAAI;IAAE;GAC1E,GAAG,oCAAoC;GACvC,MAAM,gBACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAD,EACE,cAAc,cAAc,QAAQ,YAAY,YAAY,SAAS,EACtE,CAAA;GAEH,IAAI,aAAa,QAAQ,MAAM,OAAO,uBAAuB,QAAQ,MAAM,SACzE;IAAE,MAAM;IAAiB,IAAI;GAAkB,GAC/C,OACF,CAAC,GAAG,+BAA+B;GAanC,IAAI,aAAa;IACf,MAAM,QAAQ,SAAS,cAAc,OAAO;IAC5C,MAAM,KAAK;IACX,MAAM,cAAc,CAClB,mHACA,qDACF,CAAC,CAAC,KAAK,IAAI;IACX,SAAS,KAAK,YAAY,KAAK;IAC/B,aAAa;KAAE,MAAM,OAAO;IAAE;GAChC,GAAG,8CAA8C;GAEjD,IAAI,aAAa,QAAQ,MAAM,OAAO,+CAA+C,QAAQ,MAAM,SAAS;IAC1G,MAAM;IACN,IAAI;IACJ,OAAO;IACP,UAAU,eAAuB;KAAE;KAAW,UAAW,IAAyC;KAAU;IAAE;GAChH,GAAY,aAAsB,CAAC,GAAG,2BAA2B;EACnE"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["Tag","Button","useState","useMemo","Modal","IconCloseOutlineRegular","SegmentedTabs"],"sources":["../src/client/theme.ts","../src/client/index.tsx"],"sourcesContent":["/** Palette aliases the Task Center draws with; the shell owns the values. */\n\nexport const colors = {\n panel: 'var(--dsw-alias-bg-layer-1, #ffffff)',\n panelAlt: 'var(--dsw-alias-bg-layer-2, #f7f8fa)',\n text: 'var(--dsw-alias-label-primary, #111827)',\n muted: 'var(--dsw-alias-label-secondary, #6b7280)',\n line: 'var(--dsw-alias-border-l1, #e5e7eb)',\n accent: 'var(--dsw-alias-brand-primary, #2563eb)',\n accentSoft: 'var(--dsw-alias-brand-primary-alpha, #eff6ff)',\n warning: 'var(--dsw-alias-state-warning, #b45309)',\n success: 'var(--dsw-alias-state-success, #047857)',\n danger: 'var(--dsw-alias-state-danger, #b91c1c)',\n}","/**\n * The Task Center surface in the frame-wide overlay.\n *\n * The button is global because a task can arrive while the reader is in any\n * session. The panel only renders cards returned by the Host bridge; it never\n * talks to DataOps directly and never derives a second approval status.\n */\nimport { useEffect, useMemo, useState, type CSSProperties } from 'react'\nimport {\n Button,\n IconCloseOutlineRegular,\n Modal,\n SegmentedTabs,\n Tag,\n type SegmentedTab,\n type TagTone,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport { colors } from './theme.ts'\n\nexport const inject = ['slots', 'locale', 'uiWorkspace', 'sessions', 'sidebarRight']\n\ninterface TaskItem {\n id: string\n sourceType: 'dataops_approval' | 'task_bus'\n title: string\n code?: string\n description?: string | null\n status: string\n statusLabel: string\n priority?: string | null\n tags?: string[]\n source: {\n type: string\n id?: string | null\n label?: string | null\n workflowCode?: string | null\n deepLink?: string | null\n }\n assignee?: { type: string; id: string } | null\n creator?: { type: string; id: string } | null\n actions?: string[]\n dueAt?: string | null\n updatedAt: string\n /** Connector that produced the row, when the Host carries it. */\n connectorId?: string\n /** Capability that produced the row, when the Host carries it. */\n capabilityId?: string\n}\n\nconst ROUTE = '/dsh-task-bus/api'\n\nconst TASK_BUS_MODAL_CLASS = 'task-bus-center-modal'\nconst TASK_BUS_HISTORY_CLASS = 'task-bus-history-modal'\nconst TASK_BUS_STYLE_ID = 'task-bus-center-modal-style'\nconst TASK_BUS_MODAL_CSS = `\n.${TASK_BUS_MODAL_CLASS} {\n width: min(960px, calc(100vw - 64px)) !important;\n height: min(760px, calc(100vh - 64px)) !important;\n gap: 0 !important;\n padding: 0 !important;\n}\n@media (max-width: 700px) {\n .${TASK_BUS_MODAL_CLASS} {\n width: calc(100vw - 24px) !important;\n height: calc(100vh - 24px) !important;\n }\n}\n.${TASK_BUS_HISTORY_CLASS} {\n width: min(960px, 92vw) !important;\n max-width: calc(100vw - 32px) !important;\n height: auto !important;\n max-height: min(780px, calc(100vh - 48px)) !important;\n}\n@media (max-width: 700px) {\n .${TASK_BUS_HISTORY_CLASS} {\n width: calc(100vw - 24px) !important;\n max-width: calc(100vw - 24px) !important;\n max-height: calc(100vh - 24px) !important;\n }\n}\n`\n\nconst HISTORY_NS = 'task-bus.history'\nconst HISTORY_COPY = {\n zh: {\n title: '消息记录',\n open: '消息记录',\n close: '关闭',\n searchPlaceholder: '搜索消息或发送人…',\n searchLabel: '搜索消息记录',\n clear: '清空搜索',\n initial: '输入关键词搜索消息或发送人',\n initialHint: '可按消息正文或发送人筛选,点结果跳到原消息。',\n loading: '正在加载消息记录…',\n error: '消息记录加载失败',\n empty: '暂无消息记录',\n noResults: '没有匹配的消息',\n jump: '跳到该消息',\n me: '我',\n assistant: '助手',\n dateLocale: 'zh-CN',\n },\n en: {\n title: 'Message history',\n open: 'Message history',\n close: 'Close',\n searchPlaceholder: 'Search messages or senders…',\n searchLabel: 'Search message history',\n clear: 'Clear search',\n initial: 'Search messages or senders to begin',\n initialHint: 'Filter by message text or sender, then click a result to jump to it.',\n loading: 'Loading message history…',\n error: 'Could not load message history',\n empty: 'No message history',\n noResults: 'No matching messages',\n jump: 'Jump to message',\n me: 'Me',\n assistant: 'Assistant',\n dateLocale: 'en-US',\n },\n} as const\n\ntype HistoryCopyKey = keyof typeof HISTORY_COPY.zh\ntype HistoryTranslate = (key: HistoryCopyKey) => string\n\nconst buttonStyle: CSSProperties = {\n border: '1px solid ' + colors.line,\n background: colors.panel,\n color: colors.text,\n borderRadius: 8,\n padding: '7px 11px',\n fontSize: 12,\n cursor: 'pointer',\n}\n\nconst statusTagTone = (status: string): TagTone => {\n if (status === 'completed') return 'success'\n if (status === 'cancelled') return 'neutral'\n if (status === 'blocked') return 'danger'\n if (status === 'pending_confirm' || status === 'returned' || status === 'pending_accept') return 'warning'\n return 'info'\n}\n\nconst relativeTime = (value: string) => {\n const time = Date.parse(value)\n if (!Number.isFinite(time)) return ''\n const minutes = Math.max(0, Math.round((Date.now() - time) / 60_000))\n if (minutes < 1) return '刚刚'\n if (minutes < 60) return String(minutes) + ' 分钟前'\n const hours = Math.round(minutes / 60)\n if (hours < 24) return String(hours) + ' 小时前'\n return String(Math.round(hours / 24)) + ' 天前'\n}\n\nconst fetchJson = async <T,>(path: string, options: { signal?: AbortSignal } = {}): Promise<T> => {\n const attempt = async () => {\n const response = await fetch(ROUTE + path, { headers: { accept: 'application/json' }, signal: options.signal })\n // Read the body as text first: a 502 from the flow service may carry a JSON\n // error object, plain text, or an empty body, and `response.json()` turns the\n // last two into a parse error that hides the status from the caller.\n let text = ''\n let bodyFailure = false\n try { text = await response.text() } catch { bodyFailure = true }\n let payload: unknown = null\n if (text.trim() !== '') {\n try { payload = JSON.parse(text) as unknown } catch { payload = null }\n }\n return { response, status: response.status, payload, text, bodyFailure }\n }\n // One retry covers a connection reset that drops the response body: the host\n // proxy can lose the upstream 502 on the first connection while the next\n // request reads the very same error. An abort from the caller never retries.\n const request = async () => {\n try {\n const first = await attempt()\n if (!first.bodyFailure) return first\n await new Promise((resolve) => setTimeout(resolve, 250))\n return await attempt()\n } catch (cause) {\n if (options.signal?.aborted) throw cause\n await new Promise((resolve) => setTimeout(resolve, 250))\n return await attempt()\n }\n }\n let result = await request()\n // The managed session handshake runs in parallel with the panel mount; a 401\n // here is usually \"the cookie is not set yet\", not an authorization failure.\n if (result.status === 401) {\n await new Promise((resolve) => setTimeout(resolve, 900))\n result = await request()\n }\n if (!result.response.ok) {\n const serverMessage = result.payload !== null && typeof result.payload === 'object'\n ? (typeof (result.payload as { error?: unknown }).error === 'string' ? (result.payload as { error: string }).error\n : typeof (result.payload as { message?: unknown }).message === 'string' ? (result.payload as { message: string }).message\n : '')\n : ''\n // A server answer that carries readable text always wins over the status\n // fallback, so an explicit {\"error\":\"…\"} stays exactly as the server sent it.\n const message = serverMessage !== ''\n ? serverMessage\n : result.bodyFailure\n ? 'HTTP ' + result.status + '(响应体读取失败)'\n : result.text.trim() !== ''\n ? result.text.trim().slice(0, 200)\n : 'HTTP ' + result.status\n throw new Error(message)\n }\n if (result.bodyFailure) throw new Error('HTTP ' + result.status + '(响应体读取失败)')\n return result.payload as T\n}\n\n\nconst approvalHref = (raw: string | null): string | null => {\n if (raw === null) return null\n try {\n const target = new URL(raw)\n const referrer = document.referrer ? new URL(document.referrer) : null\n if (referrer !== null && referrer.origin !== target.origin) {\n return referrer.origin + target.pathname + target.search + target.hash\n }\n return target.href\n } catch {\n return raw\n }\n}\n\nconst TaskCard = ({\n task,\n busy,\n aiBusy,\n onTransition,\n onAiAccept,\n onOpen,\n}: {\n task: TaskItem\n busy: boolean\n aiBusy: boolean\n onTransition: (task: TaskItem, action: string) => void\n onAiAccept: (task: TaskItem) => void\n onOpen: (task: TaskItem) => void\n}) => {\n const isApproval = task.sourceType === 'dataops_approval'\n const deepLink = approvalHref(task.source.deepLink ?? null)\n return (\n <article\n style={{\n border: '1px solid ' + colors.line,\n borderRadius: 10,\n background: colors.panel,\n padding: '12px 13px',\n display: 'grid',\n gap: 8,\n }}\n >\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 7, flexWrap: 'wrap', marginBottom: 4 }}>\n <Tag tone={isApproval ? 'info' : 'neutral'}>\n {isApproval ? (task.source.label ?? 'DataOps 审批') : '任务总线'}\n </Tag>\n {task.tags?.map((tag) => (\n <Tag key={tag} tone=\"quiet\">{tag}</Tag>\n ))}\n </div>\n <div style={{ fontSize: 13, fontWeight: 650, color: colors.text, lineHeight: 1.45 }}>\n {task.title}\n </div>\n {task.description ? (\n <div style={{ fontSize: 11, color: colors.muted, marginTop: 4, lineHeight: 1.5 }}>\n {task.description}\n </div>\n ) : null}\n </div>\n <span style={{ flex: 'none' }}><Tag tone={statusTagTone(task.status)}>{task.statusLabel}</Tag></span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', fontSize: 10, color: colors.muted }}>\n <span>{isApproval ? '审批任务' : '任务'}</span>\n {task.assignee?.id ? <span>受理人:{task.assignee.id}</span> : null}\n <span style={{ marginLeft: 'auto' }}>{relativeTime(task.updatedAt)}</span>\n </div>\n <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>\n {isApproval && deepLink ? (\n <Button size=\"sm\" variant=\"primary\" onClick={() => window.open(deepLink, '_blank', 'noopener,noreferrer')}>\n 办理\n </Button>\n ) : null}\n {task.status !== 'completed' && task.status !== 'cancelled' ? (\n <Button size=\"sm\" variant=\"outline\" disabled={aiBusy || busy} onClick={() => onAiAccept(task)}>\n {aiBusy ? '受理中…' : 'AI受理'}\n </Button>\n ) : null}\n <Button size=\"sm\" variant=\"ghost\" onClick={() => onOpen(task)}>详情</Button>\n {!isApproval && task.status === 'pending_accept' ? (\n <Button size=\"sm\" variant=\"primary\" disabled={busy} onClick={() => onTransition(task, 'accept')}>受理</Button>\n ) : null}\n {!isApproval && task.status === 'in_progress' ? (\n <Button size=\"sm\" variant=\"outline\" disabled={busy} onClick={() => onTransition(task, 'submit')}>提交确认</Button>\n ) : null}\n {!isApproval && task.status === 'pending_confirm' ? (\n <Button size=\"sm\" variant=\"primary\" disabled={busy} onClick={() => onTransition(task, 'complete')}>完成</Button>\n ) : null}\n {!isApproval && task.status !== 'completed' && task.status !== 'cancelled' ? (\n <Button size=\"sm\" variant=\"ghost\" disabled={busy} onClick={() => onTransition(task, 'cancel')}>取消</Button>\n ) : null}\n </div>\n </article>\n )\n}\n\n\ninterface TaskAttachmentRecord {\n id: string\n originalName: string\n contentType: string\n sizeBytes: number\n kind: string\n}\n\ninterface FormFieldData {\n key: string\n label: string\n value: unknown\n type?: 'multiline' | 'resources'\n span?: 1 | 2\n}\n\ninterface FormSectionData {\n title: string\n fields: FormFieldData[]\n}\n\ninterface TaskDetailPayload {\n id?: number | string\n payload?: {\n form?: Record<string, unknown>\n selectedItems?: Array<Record<string, unknown>>\n resourceAccessRequest?: {\n form?: Record<string, unknown>\n selectedItems?: Array<Record<string, unknown>>\n }\n }\n form?: { sections?: FormSectionData[] }\n attachments?: TaskAttachmentRecord[]\n}\n\nconst FORM_LABELS: Record<string, string> = {\n applicationMode: '申请方式',\n requestKind: '申请类型',\n requestedPermissions: '申请权限',\n requesterDepartment: '申请人部门',\n requesterPhone: '申请人电话',\n validFrom: '授权开始时间',\n expiresAt: '授权结束时间',\n selectionSummary: '资源摘要',\n code: '应用编码',\n name: '应用名称',\n reason: '申请理由',\n description: '应用说明',\n departmentName: '归属部门',\n departmentCode: '归属部门编码',\n ownerName: '归属负责人',\n ownerPhone: '归属负责人电话',\n constructionUnit: '建设单位',\n constructionOwner: '建设单位负责人',\n constructionOwnerPhone: '建设单位负责人电话',\n operationsUnit: '运维单位',\n operationsOwner: '运维单位负责人',\n operationsOwnerPhone: '运维单位负责人电话',\n requestTime: '申请时间',\n resourceName: '资源名称',\n resourceType: '资源类型',\n accessType: '访问方式',\n accessScope: '访问范围',\n applicationName: '所属应用',\n applicationCode: '应用编码',\n environment: '环境',\n accountCount: '账号数量',\n}\n\nconst SKIP_FORM_KEYS = new Set([\n 'ownerUserId',\n 'requesterUserId',\n 'requesterDept',\n 'existingApplicationId',\n 'applicationId',\n 'taskType',\n])\n\nconst formatBytes = (bytes: number) => {\n if (!Number.isFinite(bytes) || bytes < 0) return ''\n if (bytes < 1024) return bytes + ' B'\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB'\n}\n\nconst humanizeField = (key: string) => key\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .trim()\n\nconst formatFormValue = (key: string, value: unknown): string => {\n if (key === 'applicationMode') {\n if (value === 'EXISTING') return '使用已有应用'\n if (value === 'NEW') return '新建应用'\n }\n if (typeof value === 'boolean') return value ? '是' : '否'\n if (Array.isArray(value)) return value.map((item) => String(item)).join('、')\n if (value !== null && typeof value === 'object') {\n const record = value as Record<string, unknown>\n if (typeof record.name === 'string') return record.name\n return JSON.stringify(value)\n }\n return String(value)\n}\n\nconst toFormField = (key: string, value: unknown): FormFieldData => ({\n key,\n label: FORM_LABELS[key] ?? humanizeField(key),\n value,\n ...(key === 'reason' || key === 'description' || key === 'accessScope'\n ? { type: 'multiline' as const, span: 2 as const }\n : {}),\n})\n\nconst formFields = (form: Record<string, unknown> | undefined): FormFieldData[] => (\n form === undefined\n ? []\n : Object.entries(form)\n .filter(([key, value]) => !SKIP_FORM_KEYS.has(key) && value !== null && value !== undefined && value !== '')\n .map(([key, value]) => toFormField(key, value))\n)\n\nconst approvalFormSections = (detail: TaskDetailPayload | null): FormSectionData[] => {\n if (detail === null) return []\n const sections: FormSectionData[] = []\n const applicationFields = formFields(detail.payload?.form)\n if (applicationFields.length > 0) sections.push({ title: '申请信息', fields: applicationFields })\n const resourceFields = formFields(detail.payload?.resourceAccessRequest?.form)\n if (resourceFields.length > 0) sections.push({ title: '资源申请', fields: resourceFields })\n const resources = [\n ...(detail.payload?.selectedItems ?? []),\n ...(detail.payload?.resourceAccessRequest?.selectedItems ?? []),\n ]\n if (resources.length > 0) {\n sections.push({\n title: '申请资源',\n fields: [{ key: 'resources', label: '资源', value: resources, type: 'resources', span: 2 }],\n })\n }\n return sections\n}\n\nconst ResourceValue = ({ items }: { items: Array<Record<string, unknown>> }) => (\n <div style={{ display: 'grid', gap: 5 }}>\n {items.map((item, index) => {\n const label = typeof item.title === 'string' ? item.title : typeof item.name === 'string' ? item.name : `资源 ${index + 1}`\n const detail = [item.scope, item.urn, item.id].filter((value) => typeof value === 'string' || typeof value === 'number').join(' · ')\n return (\n <div key={String(item.urn ?? item.id ?? index)} style={{ display: 'flex', alignItems: 'baseline', gap: 8, minWidth: 0 }}>\n <span style={{ fontSize: 12, color: colors.text }}>{label}</span>\n {detail ? <span style={{ fontSize: 10, color: colors.muted, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{detail}</span> : null}\n </div>\n )\n })}\n </div>\n)\n\nconst FormDescriptions = ({ sections }: { sections: FormSectionData[] }) => {\n if (sections.length === 0) return null\n return (\n <div style={{ display: 'grid', gap: 10 }}>\n {sections.map((section, sectionIndex) => (\n <section key={section.title + sectionIndex} style={{ border: '1px solid ' + colors.line, borderRadius: 10, background: colors.panel, padding: 14 }}>\n <div style={{ fontSize: 12, fontWeight: 650, color: colors.text, marginBottom: 9 }}>{section.title}</div>\n <dl style={{ margin: 0, display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: '9px 24px' }}>\n {section.fields.map((field) => (\n <div\n key={field.key}\n style={{\n display: 'grid',\n gridTemplateColumns: '94px minmax(0, 1fr)',\n alignItems: 'start',\n gap: 8,\n minWidth: 0,\n gridColumn: field.span === 2 ? '1 / -1' : undefined,\n }}\n >\n <dt style={{ fontSize: 10, lineHeight: 1.6, color: colors.muted }}>{field.label}</dt>\n <dd style={{ margin: 0, fontSize: 12, lineHeight: 1.6, color: colors.text, whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' }}>\n {field.type === 'resources' && Array.isArray(field.value)\n ? <ResourceValue items={field.value as Array<Record<string, unknown>>} />\n : field.value === null || field.value === undefined || field.value === ''\n ? '—'\n : formatFormValue(field.key, field.value)}\n </dd>\n </div>\n ))}\n </dl>\n </section>\n ))}\n </div>\n )\n}\n\n/** Detail requests fail after this long instead of leaving the panel waiting forever. */\nconst DETAIL_TIMEOUT_MS = 15_000\n/** Show a secondary hint once the flow service is slow, so the panel never looks frozen. */\nconst DETAIL_SLOW_HINT_MS = 5_000\n\n/** Turn a detail failure into the message the panel shows; the server text stays verbatim. */\nconst describeDetailFailure = (cause: unknown, timedOut: boolean): string => {\n if (timedOut) return '请求超时(15 秒无响应),流程服务可能暂时不可用,请重试。'\n const raw = cause instanceof Error ? cause.message : String(cause)\n if (/^(fetch failed|Failed to fetch|NetworkError|Load failed)/iu.test(raw)) {\n return '无法连接服务(网络错误),请检查网络或稍后重试。'\n }\n return raw\n}\n\nconst TaskDetail = ({ task, onBack }: { task: TaskItem; onBack: () => void }) => {\n const isApproval = task.sourceType === 'dataops_approval'\n const [detail, setDetail] = useState<TaskDetailPayload | null>(null)\n const [detailLoading, setDetailLoading] = useState(true)\n const [detailError, setDetailError] = useState<string | null>(null)\n const [detailSlow, setDetailSlow] = useState(false)\n const [detailAttempt, setDetailAttempt] = useState(0)\n\n useEffect(() => {\n let alive = true\n const controller = new AbortController()\n let timedOut = false\n const timeout = window.setTimeout(() => { timedOut = true; controller.abort() }, DETAIL_TIMEOUT_MS)\n const slowHint = window.setTimeout(() => { if (alive) setDetailSlow(true) }, DETAIL_SLOW_HINT_MS)\n setDetail(null)\n setDetailLoading(true)\n setDetailError(null)\n setDetailSlow(false)\n void fetchJson<{ detail?: TaskDetailPayload }>('/items/' + encodeURIComponent(task.id), { signal: controller.signal })\n .then((payload) => { if (alive) setDetail(payload.detail ?? null) })\n .catch((cause) => { if (alive) setDetailError(describeDetailFailure(cause, timedOut)) })\n .finally(() => {\n window.clearTimeout(timeout)\n window.clearTimeout(slowHint)\n if (alive) {\n setDetailLoading(false)\n setDetailSlow(false)\n }\n })\n return () => {\n alive = false\n controller.abort()\n window.clearTimeout(timeout)\n window.clearTimeout(slowHint)\n }\n }, [task.id, detailAttempt])\n\n const sections = isApproval ? approvalFormSections(detail) : detail?.form?.sections ?? []\n const attachments = detail?.attachments ?? []\n const approvalTaskId = isApproval && typeof detail?.id === 'number' ? detail.id : null\n const attachmentHref = (attachment: TaskAttachmentRecord) => approvalTaskId === null\n ? null\n : ROUTE + '/attachment?taskId=' + encodeURIComponent(String(approvalTaskId))\n + '&attachmentId=' + encodeURIComponent(attachment.id)\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10, flex: 1, minHeight: '100%' }}>\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 14, fontWeight: 700, color: colors.text, lineHeight: 1.45 }}>{task.title}</div>\n <div style={{ marginTop: 3, fontSize: 10, color: colors.muted }}>\n {task.source.label ?? (isApproval ? 'DataOps 审批' : '任务总线')} · {relativeTime(task.updatedAt)}\n </div>\n </div>\n <Tag tone={statusTagTone(task.status)}>{task.statusLabel}</Tag>\n </div>\n\n {detailLoading ? (\n <div style={{ padding: 18, textAlign: 'center', color: colors.muted, fontSize: 12, display: 'grid', gap: 4 }}>\n <span>正在加载表单…</span>\n {detailSlow ? <span style={{ fontSize: 10 }}>流程服务响应较慢,正在继续等待…</span> : null}\n </div>\n ) : null}\n {detailError ? (\n <div role=\"alert\" style={{ padding: '8px 10px', borderRadius: 8, background: '#fef2f2', color: colors.danger, fontSize: 11, display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{ flex: 1, minWidth: 0, lineHeight: 1.6 }}>{detailError}</span>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setDetailAttempt((value) => value + 1)}>重试</Button>\n </div>\n ) : null}\n {!detailLoading && detailError === null && sections.length > 0 ? <FormDescriptions sections={sections} /> : null}\n {!detailLoading && detailError === null && sections.length === 0 && !isApproval && task.description ? (\n <div style={{ border: '1px solid ' + colors.line, borderRadius: 10, background: colors.panel, padding: 14, fontSize: 12, lineHeight: 1.6, color: colors.text, whiteSpace: 'pre-wrap' }}>{task.description}</div>\n ) : null}\n {!detailLoading && detailError === null && sections.length === 0 && (isApproval || !task.description) ? (\n <div style={{ padding: 18, textAlign: 'center', color: colors.muted, fontSize: 12 }}>暂无表单信息</div>\n ) : null}\n\n {isApproval || attachments.length > 0 ? (\n <section style={{ border: '1px solid ' + colors.line, borderRadius: 10, background: colors.panel, padding: 14 }}>\n <div style={{ fontSize: 12, fontWeight: 650, color: colors.text, marginBottom: 8 }}>附件</div>\n {attachments.length === 0 ? <div style={{ fontSize: 11, color: colors.muted }}>暂无附件</div> : (\n <div style={{ display: 'grid', gap: 6 }}>\n {attachments.map((attachment) => {\n const href = attachmentHref(attachment)\n return (\n <div key={attachment.id} style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>\n <span style={{ flex: 1, minWidth: 0, fontSize: 11, color: colors.text, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{attachment.originalName}</span>\n <span style={{ flex: 'none', fontSize: 10, color: colors.muted }}>{formatBytes(attachment.sizeBytes)}</span>\n {href !== null ? <Button size=\"sm\" variant=\"ghost\" onClick={() => window.open(href, '_blank', 'noopener,noreferrer')}>下载</Button> : null}\n </div>\n )\n })}\n </div>\n )}\n </section>\n ) : null}\n\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, flexWrap: 'wrap', marginTop: 'auto', paddingTop: 2 }}>\n <Button size=\"sm\" variant=\"ghost\" onClick={onBack}>← 返回列表</Button>\n {isApproval && task.source.deepLink ? (\n <Button size=\"sm\" variant=\"outline\" onClick={() => window.open(approvalHref(task.source.deepLink ?? null) ?? '#', '_blank', 'noopener,noreferrer')}>\n 打开 DataOps 审批详情\n </Button>\n ) : null}\n </div>\n </div>\n )\n}\n\ntype TaskTab = 'all' | 'mine' | 'personal' | 'group' | 'notifications'\n\n/** One KB task record, as the knowledge-base plugin persists it. */\ninterface KbTaskRecord {\n id: string\n fileName: string\n kind: 'upload' | 'extract'\n stage: 'uploading' | 'uploaded' | 'extracting' | 'done' | 'failed'\n progress?: number\n startedAt: number\n finishedAt?: number\n error?: string\n}\n\nconst KB_TASK_QUEUE_KEY = 'dataops-kb-task-queue-v1'\nconst KB_TASK_TTL_MS = 7 * 24 * 60 * 60 * 1000\nconst KB_TASK_MAX = 200\nconst KB_STAGE_LABEL: Record<KbTaskRecord['stage'], string> = {\n uploading: '上传中',\n uploaded: '上传完成',\n extracting: '提取中',\n done: '提取完成',\n failed: '失败',\n}\n\n/** Read the KB task queue from the shared localStorage key. */\nfunction readKbTasks(now: number = Date.now()): KbTaskRecord[] {\n try {\n const raw = window.localStorage.getItem(KB_TASK_QUEUE_KEY)\n if (raw === null || raw === '') return []\n const parsed: unknown = JSON.parse(raw)\n if (!Array.isArray(parsed)) return []\n const records: KbTaskRecord[] = []\n for (const entry of parsed) {\n if (entry === null || typeof entry !== 'object') continue\n const row = entry as Record<string, unknown>\n if (typeof row.id !== 'string' || row.id === '') continue\n if (typeof row.fileName !== 'string' || row.fileName === '') continue\n if (row.kind !== 'upload' && row.kind !== 'extract') continue\n if (typeof row.stage !== 'string' || !(row.stage in KB_STAGE_LABEL)) continue\n if (typeof row.startedAt !== 'number' || !Number.isFinite(row.startedAt)) continue\n if (now - row.startedAt > KB_TASK_TTL_MS) continue\n records.push({\n id: row.id,\n fileName: row.fileName,\n kind: row.kind,\n stage: row.stage as KbTaskRecord['stage'],\n ...(typeof row.progress === 'number' && Number.isFinite(row.progress) ? { progress: row.progress } : {}),\n startedAt: row.startedAt,\n ...(typeof row.finishedAt === 'number' && Number.isFinite(row.finishedAt) ? { finishedAt: row.finishedAt } : {}),\n ...(typeof row.error === 'string' && row.error !== '' ? { error: row.error } : {}),\n })\n }\n return records.sort((a, b) => b.startedAt - a.startedAt).slice(0, KB_TASK_MAX)\n } catch {\n return []\n }\n}\n\n/** The \"notifications\" tab: the KB task queue, read from the shared key. */\nfunction KbNotificationPanel({ tasks, onClear }: {\n tasks: readonly KbTaskRecord[]\n onClear: () => void\n}) {\n const done = tasks.filter(task => task.stage === 'done' || task.stage === 'uploaded').length\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>\n <span style={{ fontSize: 13, fontWeight: 600, color: colors.text }}>任务队列</span>\n {tasks.length > 0 ? <span style={{ fontSize: 12, color: '#8ea6c6' }}>{done}/{tasks.length}</span> : null}\n </div>\n <Button size=\"sm\" variant=\"ghost\" disabled={tasks.length === 0} onClick={onClear}>清空记录</Button>\n </div>\n {tasks.length === 0 ? (\n <div style={{ padding: 18, textAlign: 'center', color: colors.muted, fontSize: 12 }}>暂无通知</div>\n ) : tasks.map(task => {\n const percent = Math.max(0, Math.min(100, Math.round(task.progress ?? (task.stage === 'done' ? 100 : task.stage === 'uploaded' ? 25 : 0))))\n const tone = task.stage === 'failed' ? colors.danger\n : task.stage === 'done' || task.stage === 'uploaded' ? colors.success : colors.accent\n return (\n <div key={task.id} style={{ padding: '10px 12px', border: '1px solid ' + colors.line, borderRadius: 8, background: colors.panelAlt, display: 'flex', flexDirection: 'column', gap: 6 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontSize: 12, fontWeight: 500, color: colors.text }}>{task.fileName}</span>\n <span style={{ fontSize: 10, color: colors.muted }}>{new Date(task.startedAt).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}</span>\n <span style={{ fontSize: 10, color: tone, whiteSpace: 'nowrap' }}>{KB_STAGE_LABEL[task.stage]}</span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <div style={{ flex: 1, height: 6, borderRadius: 999, background: 'rgba(255,255,255,.08)', overflow: 'hidden' }}>\n <div style={{ width: String(percent) + '%', height: '100%', borderRadius: 999, background: tone, transition: 'width 120ms linear' }} />\n </div>\n <span style={{ minWidth: 34, textAlign: 'right', fontSize: 11, color: colors.muted, fontVariantNumeric: 'tabular-nums' }}>{String(percent) + '%'}</span>\n </div>\n {task.error !== undefined ? <div style={{ fontSize: 11, color: colors.danger }}>{task.error}</div> : null}\n </div>\n )\n })}\n </div>\n )\n}\n\nconst TaskCenterButton = ({ openSession }: {\n openSession: (sessionId: string) => void\n}) => {\n const [open, setOpen] = useState(false)\n const [tasks, setTasks] = useState<TaskItem[]>([])\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [tab, setTab] = useState<TaskTab>('all')\n const [busyId, setBusyId] = useState<string | null>(null)\n const [aiBusyId, setAiBusyId] = useState<string | null>(null)\n const [selected, setSelected] = useState<TaskItem | null>(null)\n const [anchor, setAnchor] = useState<{ left: number; top: number } | null>(null)\n const [pendingCount, setPendingCount] = useState(0)\n const [kbTasks, setKbTasks] = useState<KbTaskRecord[]>(() => readKbTasks())\n\n useEffect(() => {\n if (document.getElementById(TASK_BUS_STYLE_ID) !== null) return\n const style = document.createElement('style')\n style.id = TASK_BUS_STYLE_ID\n style.textContent = TASK_BUS_MODAL_CSS\n document.head.append(style)\n return () => { style.remove() }\n }, [])\n\n useEffect(() => {\n const update = () => {\n const collapsed = document.querySelector('[data-sidebar-collapsed=\"true\"]') !== null\n if (collapsed) {\n setAnchor((current) => (current === null ? current : null))\n return\n }\n const buttons = Array.from(document.querySelectorAll('button'))\n const toggle = buttons.find((button) => /收起侧边栏|Collapse sidebar/i.test((button.getAttribute('aria-label') ?? '').trim()))\n if (!toggle) {\n setAnchor((current) => (current === null ? current : null))\n return\n }\n const label = (toggle.getAttribute('aria-label') ?? '').trim()\n if (/展开侧边栏|Expand sidebar/i.test(label)) {\n setAnchor((current) => (current === null ? current : null))\n return\n }\n const rect = toggle.getBoundingClientRect()\n if (rect.width === 0 || rect.height === 0) return\n const next = { left: Math.max(8, rect.left - 36), top: rect.top + (rect.height - 28) / 2 }\n setAnchor((current) => (\n current !== null && Math.abs(current.left - next.left) < 0.5 && Math.abs(current.top - next.top) < 0.5\n ? current\n : next\n ))\n }\n update()\n const timer = window.setInterval(update, 400)\n window.addEventListener('resize', update)\n return () => {\n window.clearInterval(timer)\n window.removeEventListener('resize', update)\n }\n }, [])\n\n const load = async (silent = false) => {\n if (!silent) setLoading(true)\n setError(null)\n try {\n const overview = await fetchJson<{ items: TaskItem[] }>('/overview')\n setTasks([...overview.items].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)))\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n if (!silent) setLoading(false)\n }\n }\n\n useEffect(() => {\n if (!open) return\n void load()\n const timer = window.setInterval(() => { void load(true) }, 60_000)\n return () => { window.clearInterval(timer) }\n }, [open])\n\n useEffect(() => {\n let alive = true\n const refresh = async () => {\n try {\n const result = await fetchJson<{ count?: number }>('/count')\n if (alive) setPendingCount(Math.max(0, Math.trunc(Number(result.count) || 0)))\n } catch {\n // The panel's overview error is the visible connection state; the badge keeps its last value.\n }\n }\n void refresh()\n const timer = window.setInterval(() => { void refresh() }, 300_000)\n return () => { alive = false; window.clearInterval(timer) }\n }, [])\n\n useEffect(() => {\n let alive = true\n const sync = (): void => { if (alive) setKbTasks(readKbTasks()) }\n const timer = window.setInterval(sync, 1000)\n const onStorage = (event: StorageEvent): void => { if (event.key === KB_TASK_QUEUE_KEY) sync() }\n window.addEventListener('storage', onStorage)\n return () => {\n alive = false\n window.clearInterval(timer)\n window.removeEventListener('storage', onStorage)\n }\n }, [])\n\n const clearKbTasks = (): void => {\n try { window.localStorage.removeItem(KB_TASK_QUEUE_KEY) } catch { /* private mode */ }\n setKbTasks([])\n }\n\n const filtered = useMemo(() => {\n if (tab === 'group') return tasks.filter((task) => task.sourceType === 'task_bus' && task.source.type.includes('group'))\n if (tab === 'mine') return tasks.filter((task) => task.status !== 'completed' && task.status !== 'cancelled')\n if (tab === 'personal') return tasks.filter((task) => task.sourceType === 'task_bus' && !task.source.type.includes('group'))\n return tasks\n }, [tasks, tab])\n\n const actionable = tasks.filter((task) => task.status !== 'completed' && task.status !== 'cancelled').length\n const kbPending = kbTasks.filter(task => task.stage === 'uploading' || task.stage === 'extracting').length\n const tabItems: [SegmentedTab<TaskTab>, ...SegmentedTab<TaskTab>[]] = [\n { value: 'all', id: 'task-bus-tab-all', panelId: 'task-bus-panel-all', label: <span>全部 <span style={{ opacity: 0.55 }}>{tasks.length}</span></span> },\n { value: 'mine', id: 'task-bus-tab-mine', panelId: 'task-bus-panel-mine', label: <span>待我处理 <span style={{ opacity: 0.55 }}>{actionable}</span></span> },\n { value: 'personal', id: 'task-bus-tab-personal', panelId: 'task-bus-panel-personal', label: <span>个人 <span style={{ opacity: 0.55 }}>{tasks.filter((task) => task.sourceType === 'task_bus' && !task.source.type.includes('group')).length}</span></span> },\n { value: 'group', id: 'task-bus-tab-group', panelId: 'task-bus-panel-group', label: <span>群聊 <span style={{ opacity: 0.55 }}>{tasks.filter((task) => task.sourceType === 'task_bus' && task.source.type.includes('group')).length}</span></span> },\n { value: 'notifications', id: 'task-bus-tab-notifications', panelId: 'task-bus-panel-notifications', label: <span>通知 <span style={{ opacity: 0.55 }}>{kbPending}</span></span> },\n ]\n\n const transition = async (task: TaskItem, action: string) => {\n setBusyId(task.id)\n setError(null)\n try {\n await fetch(ROUTE + '/generic/' + encodeURIComponent(task.id.slice(5)) + '/transition', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ action }),\n }).then(async (response) => {\n if (!response.ok) {\n const payload = await response.json().catch(() => null) as { error?: string } | null\n throw new Error(payload?.error ?? '任务操作失败')\n }\n })\n await load()\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusyId(null)\n }\n }\n\n const aiAccept = async (task: TaskItem) => {\n setAiBusyId(task.id)\n setError(null)\n try {\n const response = await fetch(ROUTE + '/ai-accept', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id: task.id }),\n })\n const payload = await response.json() as { sessionId?: string; error?: string }\n if (!response.ok || typeof payload.sessionId !== 'string') {\n throw new Error(payload.error ?? 'AI 受理会话创建失败')\n }\n openSession(payload.sessionId)\n setOpen(false)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setAiBusyId(null)\n }\n }\n\n return (\n <>\n {anchor !== null ? (\n <button\n type=\"button\"\n aria-label=\"任务中心\"\n title=\"任务中心\"\n onClick={() => setOpen((value) => !value)}\n style={{\n position: 'fixed',\n left: anchor.left,\n top: anchor.top,\n zIndex: 45,\n width: 28,\n height: 28,\n padding: 0,\n border: 'none',\n borderRadius: 8,\n background: 'transparent',\n color: actionable > 0 ? colors.accent : colors.muted,\n cursor: 'pointer',\n pointerEvents: 'auto',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9\" />\n <path d=\"M13.7 21a2 2 0 0 1-3.4 0\" />\n </svg>\n {pendingCount + kbPending > 0 ? (\n <span style={{ position: 'absolute', bottom: -2, right: -2, minWidth: 14, height: 14, padding: '0 3px', boxSizing: 'border-box', borderRadius: 999, background: '#2563eb', color: '#fff', fontSize: 9, lineHeight: '14px', textAlign: 'center' }}>\n {pendingCount + kbPending > 99 ? '99+' : pendingCount + kbPending}\n </span>\n ) : null}\n </button>\n ) : null}\n\n <Modal open={open} onClose={() => setOpen(false)} title=\"任务中心\" headless className={TASK_BUS_MODAL_CLASS}>\n <div style={{ display: 'flex', flexDirection: 'column', width: '100%', height: '100%', minHeight: 0 }}>\n <header style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '22px 24px 12px' }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <h2 style={{ margin: 0, fontSize: 16, lineHeight: '24px', fontWeight: 500, color: colors.text }}>任务中心</h2>\n </div>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>刷新</Button>\n <Button size=\"sm\" variant=\"ghost\" aria-label=\"关闭\" title=\"关闭\" onClick={() => setOpen(false)} icon={<IconCloseOutlineRegular size={14} />} style={{ width: 28, padding: 0 }} />\n </header>\n <div style={{ padding: '0 24px 14px', borderBottom: '1px solid ' + colors.line }}>\n <SegmentedTabs items={tabItems} value={tab} onChange={setTab} label=\"任务中心分类\" />\n </div>\n {error ? <div style={{ padding: '8px 10px', borderRadius: 8, background: '#fef2f2', color: colors.danger, fontSize: 11, margin: '0 24px 12px' }}>{error}</div> : null}\n <div id={'task-bus-panel-' + tab} role=\"tabpanel\" aria-labelledby={'task-bus-tab-' + tab} style={{ padding: '16px 24px 24px', display: 'flex', flexDirection: 'column', gap: 10, overflowY: 'auto', flex: 1 }}>\n {tab === 'notifications' ? (\n <KbNotificationPanel tasks={kbTasks} onClear={clearKbTasks} />\n ) : selected !== null ? (\n <TaskDetail task={selected} onBack={() => setSelected(null)} />\n ) : (\n <>\n {loading ? <div style={{ padding: 18, textAlign: 'center', color: colors.muted, fontSize: 12 }}>正在加载…</div> : null}\n {!loading && filtered.length === 0 ? <div style={{ padding: 18, textAlign: 'center', color: colors.muted, fontSize: 12 }}>暂无任务</div> : null}\n {!loading && filtered.map((task) => (\n <TaskCard key={task.id} task={task} busy={busyId === task.id} aiBusy={aiBusyId === task.id} onTransition={(item, action) => void transition(item, action)} onAiAccept={(item) => void aiAccept(item)} onOpen={setSelected} />\n ))}\n </>\n )}\n </div>\n </div>\n </Modal>\n </>\n )\n}\n\n\n\ninterface HistoryEntry {\n key: string\n role: 'user' | 'assistant'\n author: string\n time: number | undefined\n text: string\n jumpId?: string\n}\n\nconst HISTORY_CONTENT_TYPES = new Set(['user/message', 'assistant/message'])\n\nconst historyText = (content: unknown): string => {\n if (!Array.isArray(content)) return ''\n return content.map((block) => {\n if (block === null || typeof block !== 'object') return ''\n const record = block as Record<string, unknown>\n return record.type === 'text' && typeof record.text === 'string' ? record.text : ''\n }).filter(Boolean).join('\\n').trim()\n}\n\nconst historyRole = (event: Record<string, unknown>): 'user' | 'assistant' => {\n const data = event.data as Record<string, unknown> | undefined\n return data?.role === 'user' || event.type === 'user/message' ? 'user' : 'assistant'\n}\n\nconst historyAuthor = (event: Record<string, unknown>, role: 'user' | 'assistant', t: HistoryTranslate): string => {\n const data = event.data as Record<string, unknown> | undefined\n const source = data?.source as Record<string, unknown> | undefined\n const memberName = typeof source?.memberName === 'string' ? source.memberName.trim() : ''\n if (memberName !== '') return memberName\n return role === 'user' ? t('me') : t('assistant')\n}\n\nconst groupHistory = async (roomId: string, t: HistoryTranslate): Promise<HistoryEntry[]> => {\n const entries: HistoryEntry[] = []\n let cursor: string | null = null\n for (let page = 0; page < 20; page += 1) {\n const suffix = cursor === null ? '' : '?cursor=' + encodeURIComponent(cursor)\n const response = await fetch('/dsh-group-chat/api/rooms/' + encodeURIComponent(roomId) + '/events' + suffix)\n if (!response.ok) throw new Error(t('error'))\n const payload = await response.json() as { events?: Array<{ id?: string; event?: Record<string, unknown>; createdAt?: string }>; nextCursor?: string | null; hasMore?: boolean }\n for (const record of payload.events ?? []) {\n const event = record.event\n if (event === undefined || typeof event.type !== 'string' || !HISTORY_CONTENT_TYPES.has(event.type)) continue\n const data = event.data as Record<string, unknown> | undefined\n const role = historyRole(event)\n const text = historyText(data?.content)\n if (text === '') continue\n entries.push({ key: record.id ?? String(event.seq ?? entries.length), role, author: historyAuthor(event, role, t), time: typeof event.time === 'number' ? event.time : undefined, text, jumpId: record.id })\n }\n if (payload.hasMore !== true || payload.nextCursor === null || payload.nextCursor === undefined) break\n cursor = payload.nextCursor\n }\n return entries.sort((left, right) => (right.time ?? 0) - (left.time ?? 0))\n}\n\nconst sessionHistory = async (sessionId: string, sessions: unknown, t: HistoryTranslate): Promise<HistoryEntry[]> => {\n const service = sessions as {\n retain?: (id: string, options: { source: string }) => {\n ready?: Promise<unknown>\n binding?: {\n eventSource?: { getSnapshot(): { entries?: Array<{ type?: string; event?: Record<string, unknown> }> } }\n session?: { loadOlder?: () => Promise<void> }\n }\n release?: () => void\n }\n }\n if (service.retain === undefined) return []\n const reference = service.retain(sessionId, { source: 'gateway' })\n try {\n await reference.ready\n const binding = reference.binding\n if (binding === undefined) return []\n await binding.session?.loadOlder?.().catch(() => undefined)\n const entries = binding.eventSource?.getSnapshot().entries ?? []\n return entries\n .filter((entry): entry is { type: 'event'; event: Record<string, unknown> } => entry.type === 'event' && entry.event !== undefined)\n .filter((entry) => typeof entry.event.type === 'string' && HISTORY_CONTENT_TYPES.has(entry.event.type))\n .map((entry) => {\n const event = entry.event\n const data = event.data as Record<string, unknown> | undefined\n const role = historyRole(event)\n return {\n key: String(event.seq ?? entries.indexOf(entry)),\n role,\n author: historyAuthor(event, role, t),\n time: typeof event.time === 'number' ? event.time : undefined,\n text: historyText(data?.content),\n }\n })\n .filter((entry) => entry.text !== '')\n .sort((left, right) => (right.time ?? 0) - (left.time ?? 0))\n } finally {\n reference.release?.()\n }\n}\n\n\n\ninterface FileAttachmentRef {\n attachmentId: string\n name: string\n bytes: number\n}\n\nconst fileAttachmentIn = (content: unknown, name: string): FileAttachmentRef | undefined => {\n if (!Array.isArray(content)) return undefined\n for (const block of content) {\n if (block === null || typeof block !== 'object') continue\n const record = block as Record<string, unknown>\n if (record.type !== 'file') continue\n const attachment = record.attachment as Record<string, unknown> | undefined\n if (attachment?.name === name && typeof attachment.attachmentId === 'string' && typeof attachment.bytes === 'number') {\n return { attachmentId: attachment.attachmentId, name, bytes: attachment.bytes }\n }\n }\n return undefined\n}\n\nconst sessionFileAttachment = async (sessionId: string, sessions: unknown, name: string): Promise<FileAttachmentRef | undefined> => {\n const service = sessions as {\n retain?: (id: string, options: { source: string }) => {\n ready?: Promise<unknown>\n binding?: {\n eventSource?: { getSnapshot(): { entries?: Array<{ type?: string; event?: Record<string, unknown> }> } }\n session?: { loadOlder?: () => Promise<void> }\n }\n release?: () => void\n }\n }\n if (service.retain === undefined) return undefined\n const reference = service.retain(sessionId, { source: 'gateway' })\n try {\n await reference.ready\n const binding = reference.binding\n if (binding === undefined) return undefined\n const find = (): FileAttachmentRef | undefined => {\n const entries = binding.eventSource?.getSnapshot().entries ?? []\n for (const entry of entries) {\n if (entry.type !== 'event' || entry.event === undefined) continue\n if (entry.event.type !== 'user/message') continue\n const data = entry.event.data as Record<string, unknown> | undefined\n const found = fileAttachmentIn(data?.content, name)\n if (found !== undefined) return found\n }\n return undefined\n }\n let found = find()\n for (let page = 0; page < 5 && found === undefined; page += 1) {\n await binding.session?.loadOlder?.().catch(() => undefined)\n found = find()\n }\n return found\n } finally {\n reference.release?.()\n }\n}\n\n/**\n * The design system's standard 16-unit clock glyph, drawn locally.\n *\n * The client primitives package this runtime serves (0.2.2-alpha.2) exports\n * `IconClockOutline`, `IconClockOutlineRegular`, and `IconClockOutlineMedium`,\n * not the newer `IconClockOutline16` name. A missing named export resolves to\n * `undefined`, so importing it crashed this header slot with React error #130\n * and removed the button entirely; the standard geometry is inlined instead.\n *\n * Weight is 1, matching the shell's own header glyphs: those render 16x16 with\n * `stroke-width=\"1\"` on a `0 0 16 16` viewBox, so a 1.5 stroke read as a bold\n * clock beside them. The glyph must also stay square inside the 28px button,\n * hence its block display and disabled flex shrink.\n */\nconst MessageHistoryIcon = ({ size = 16 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n strokeWidth=\"1\"\n preserveAspectRatio=\"xMidYMid meet\"\n style={{ display: 'block', flexShrink: 0 }}\n >\n <circle cx=\"8\" cy=\"8\" r=\"6.375\" stroke=\"currentColor\" />\n <path d=\"M8 4.4V8.3L10.7 9.85\" stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n)\n\nconst HistoryButton = ({ sessionId, sessions, t }: { sessionId: string; sessions: unknown; t: HistoryTranslate }) => {\n const [open, setOpen] = useState(false)\n const [entries, setEntries] = useState<HistoryEntry[]>([])\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState('')\n const [query, setQuery] = useState('')\n const isGroup = sessionId.startsWith('group-room-')\n\n useEffect(() => {\n if (!open) return\n let alive = true\n setLoading(true)\n setError('')\n setQuery('')\n setEntries([])\n const load = isGroup ? groupHistory(sessionId.slice('group-room-'.length), t) : sessionHistory(sessionId, sessions, t)\n void load.then((items) => { if (alive) setEntries(items) })\n .catch((cause) => { if (alive) setError(cause instanceof Error ? cause.message : String(cause)) })\n .finally(() => { if (alive) setLoading(false) })\n return () => { alive = false }\n }, [open, isGroup, sessionId, sessions, t])\n\n const needle = query.trim().toLocaleLowerCase()\n const results = useMemo(() => {\n if (needle === '') return []\n return entries.filter((entry) =>\n entry.text.toLocaleLowerCase().includes(needle) || entry.author.toLocaleLowerCase().includes(needle))\n }, [entries, needle])\n\n const jump = (entry: HistoryEntry) => {\n setOpen(false)\n window.setTimeout(() => {\n let target: HTMLElement | null = entry.jumpId === undefined\n ? null\n : document.querySelector<HTMLElement>('[data-group-chat-message=\"' + CSS.escape(entry.jumpId) + '\"]')\n if (target === null) {\n const text = entry.text.slice(0, 80)\n target = [...document.querySelectorAll<HTMLElement>('[data-group-chat-message], [data-slot=\"conversation.user.text.node\"]')]\n .find((element) => (element.innerText ?? '').includes(text)) ?? null\n }\n if (target === null && (window as unknown as { find: (...args: unknown[]) => boolean }).find(entry.text.slice(0, 80), false, false, true, false, false, false)) {\n const selection = window.getSelection()\n const node = selection?.anchorNode\n target = node instanceof HTMLElement ? node : node?.parentElement ?? null\n }\n target?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n if (target !== null) {\n target.style.outline = '2px solid #2563eb'\n target.style.outlineOffset = '4px'\n window.setTimeout(() => { target!.style.outline = ''; target!.style.outlineOffset = '' }, 1800)\n }\n }, 80)\n }\n\n const searchInputStyle: CSSProperties = {\n width: '100%',\n boxSizing: 'border-box',\n height: 36,\n padding: '0 34px 0 12px',\n borderRadius: 8,\n border: '1px solid ' + colors.line,\n background: colors.panel,\n color: colors.text,\n fontSize: 13,\n outline: 'none',\n }\n\n return (\n <>\n <button\n type=\"button\"\n aria-label={t('open')}\n title={t('open')}\n data-session-id={sessionId}\n onClick={() => setOpen(true)}\n style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 28, height: 28, border: 'none', borderRadius: 6, background: 'transparent', color: 'inherit', cursor: 'pointer' }}\n >\n <MessageHistoryIcon size={16} />\n </button>\n <Modal open={open} onClose={() => setOpen(false)} title={t('title')} closeLabel={t('close')} className={TASK_BUS_HISTORY_CLASS}>\n <div style={{ width: '100%', maxHeight: 'min(68vh, 620px)', overflowY: 'auto', display: 'grid', gap: 10, padding: '4px 0 8px' }}>\n <div style={{ position: 'relative', width: '100%' }}>\n <input\n type=\"text\"\n value={query}\n autoFocus\n spellCheck={false}\n placeholder={t('searchPlaceholder')}\n aria-label={t('searchLabel')}\n onChange={(event) => { setQuery(event.target.value) }}\n style={searchInputStyle}\n />\n {query !== '' ? (\n <button\n type=\"button\"\n aria-label={t('clear')}\n title={t('clear')}\n onClick={() => { setQuery('') }}\n style={{ position: 'absolute', right: 6, top: '50%', transform: 'translateY(-50%)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 24, height: 24, border: 'none', borderRadius: 5, background: 'transparent', color: colors.muted, cursor: 'pointer' }}\n >\n <IconCloseOutlineRegular size={14} />\n </button>\n ) : null}\n </div>\n\n {loading ? <div style={{ padding: 28, textAlign: 'center', color: colors.muted, fontSize: 12 }}>{t('loading')}</div> : null}\n {!loading && error !== '' ? <div role=\"alert\" style={{ padding: 12, color: colors.danger, fontSize: 12 }}>{error}</div> : null}\n {!loading && error === '' && needle === '' ? (\n <div style={{ display: 'grid', justifyItems: 'center', gap: 8, padding: '36px 20px 40px', color: colors.muted, textAlign: 'center' }}>\n <span style={{ display: 'inline-flex', width: 36, height: 36, alignItems: 'center', justifyContent: 'center', borderRadius: 18, background: colors.panelAlt, color: colors.muted }}>\n <MessageHistoryIcon size={16} />\n </span>\n <span style={{ fontSize: 13, fontWeight: 600, color: colors.text }}>{t('initial')}</span>\n <span style={{ fontSize: 12, lineHeight: 1.6 }}>{t('initialHint')}</span>\n </div>\n ) : null}\n {!loading && error === '' && needle !== '' && results.length === 0 ? (\n <div style={{ padding: 28, textAlign: 'center', color: colors.muted, fontSize: 12 }}>\n {entries.length === 0 ? t('empty') : t('noResults')}\n </div>\n ) : null}\n {!loading && error === '' && needle !== '' && results.map((entry) => (\n <button\n key={entry.key}\n type=\"button\"\n onClick={() => jump(entry)}\n style={{ display: 'grid', gap: 6, width: '100%', minWidth: 0, textAlign: 'left', padding: '10px 12px', borderRadius: 8, border: '1px solid ' + colors.line, background: colors.panelAlt, color: colors.text, cursor: 'pointer' }}\n >\n <span style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0, flexWrap: 'wrap', fontSize: 10, color: colors.muted }}>\n <span style={{ fontWeight: 650, color: entry.role === 'user' ? '#2563eb' : colors.text }}>{entry.author}</span>\n {entry.time === undefined ? null : <span>{new Date(entry.time).toLocaleString(t('dateLocale'))}</span>}\n <span style={{ marginLeft: 'auto' }}>{t('jump')}</span>\n </span>\n <span style={{ display: 'block', minWidth: 0, fontSize: 13, lineHeight: 1.65, whiteSpace: 'pre-wrap', overflowWrap: 'anywhere', wordBreak: 'break-word' }}>{entry.text}</span>\n </button>\n ))}\n </div>\n </Modal>\n </>\n )\n}\n\nexport const apply = (ctx: Context) => {\n const locale = (ctx as unknown as {\n locale: {\n register(namespace: string, dictionaries: { zh: typeof HISTORY_COPY.zh; en: typeof HISTORY_COPY.en }): () => void\n bind(namespace: string): (key: HistoryCopyKey) => string\n }\n }).locale\n ctx.effect(() => locale.register(HISTORY_NS, { zh: HISTORY_COPY.zh, en: HISTORY_COPY.en }), 'task-bus: history copy')\n const t = locale.bind(HISTORY_NS)\n const surface = ctx as unknown as {\n slots: {\n inject(name: string, factory: () => () => void): () => void\n register(options: Record<string, unknown>, component: (props: never) => JSX.Element | null): () => void\n }\n uiWorkspace: { openSession(sessionId: string): void }\n }\n const surfaceWithServices = surface as unknown as {\n sidebarRight?: { openResource?(address: string): void }\n get?: (name: string) => unknown\n }\n const sidebarRight = (surfaceWithServices.sidebarRight ?? surfaceWithServices.get?.('sidebarRight')) as\n { openResource?(address: string): void } | undefined\n // Native file cards are spans owned by the official Chat renderer, so delegate from the\n // document. The active Session header carries its id; group rooms have their own handler.\n ctx.effect(() => {\n const onFileClick = (event: MouseEvent): void => {\n const target = event.target\n if (!(target instanceof Element)) return\n const card = target.closest('[data-message-attachments] > *')\n if (!(card instanceof HTMLElement)) return\n const header = document.querySelector<HTMLElement>('button[aria-label=\"消息记录\"][data-session-id]')\n const sessionId = header?.getAttribute('data-session-id') ?? ''\n if (sessionId === '' || sessionId.startsWith('group-room-')) return\n const name = (card.getAttribute('title') ?? card.innerText.split('\\n')[0] ?? '').trim()\n if (name === '') return\n void (async () => {\n const attachment = await sessionFileAttachment(sessionId, (ctx as unknown as { sessions: unknown }).sessions, name)\n if (attachment === undefined) return\n const sessionState = (ctx as unknown as {\n sessions?: { list?: { getSnapshot(): { byId?: Record<string, { cwd?: string }> } } }\n }).sessions?.list?.getSnapshot()\n const cwd = sessionState?.byId?.[sessionId]?.cwd ?? ''\n const query = 'attachmentId=' + encodeURIComponent(attachment.attachmentId)\n + '&name=' + encodeURIComponent(attachment.name)\n + '&bytes=' + encodeURIComponent(String(attachment.bytes))\n + (cwd === '' ? '' : '&cwd=' + encodeURIComponent(cwd))\n const response = await fetch(ROUTE + '/attachment-materialize?' + query)\n if (!response.ok) throw new Error('附件预览准备失败')\n const materialized = await response.json() as { path?: string }\n if (typeof materialized.path !== 'string') throw new Error('附件预览路径缺失')\n const address = 'dsh-resource://file/session/' + encodeURIComponent(sessionId)\n + '/' + materialized.path.split('/').map((part) => encodeURIComponent(part)).join('/')\n const right = (ctx as unknown as { sidebarRight?: { openResource?(address: string): void } }).sidebarRight\n if (right?.openResource !== undefined) right.openResource(address)\n else window.open(new URL('/dsh-task-bus/api/attachment-materialize?' + query, window.location.origin).toString(), '_blank', 'noopener,noreferrer')\n })().catch((cause) => { console.error('[task-bus] file preview failed', cause) })\n }\n document.addEventListener('click', onFileClick, true)\n return () => { document.removeEventListener('click', onFileClick, true) }\n }, 'task-bus: native file card preview')\n const Surface = () => (\n <TaskCenterButton\n openSession={(sessionId) => surface.uiWorkspace.openSession(sessionId)}\n />\n )\n ctx.effect(() => surface.slots.inject('shell.overlay', () => surface.slots.register(\n { name: 'shell.overlay', id: 'task-bus.center' },\n Surface,\n )), 'task-bus: Task Center overlay')\n\n // The history seat replaces the host's open-in-app jump. That control is a split\n // group: `[data-open-target=\"directory\"]` wraps the primary button and an optional\n // chevron. Hiding only the primary button left the wrapper's 1px left/right border\n // as a 2px-wide, 24px-tall rule beside this button, so the entry that owns the\n // split group is hidden instead.\n //\n // The slot renders every registered entry as one direct child of the\n // `[data-slot=\"conversation.session.header.utilities\"]` wrapper; this button is a\n // sibling of that entry, so the selectors below never match its own container.\n // They are scoped to the utilities slot so the file and directory launchers\n // elsewhere in the shell keep working.\n ctx.effect(() => {\n const style = document.createElement('style')\n style.id = 'task-bus-history-replaces-file-manager'\n style.textContent = [\n '[data-slot=\"conversation.session.header.utilities\"] > *:has([data-open-target]) { display: none !important; }',\n '[data-message-attachments] > * { cursor: pointer; }',\n ].join('\\n')\n document.head.appendChild(style)\n return () => { style.remove() }\n }, 'task-bus: replace file manager header button')\n\n ctx.effect(() => surface.slots.inject('conversation.session.header.utilities', () => surface.slots.register({\n name: 'conversation.session.header.utilities',\n id: 'task-bus.history',\n order: -4,\n inject: ((sessionId: string) => ({ sessionId, sessions: (ctx as unknown as { sessions: unknown }).sessions, t })) as never,\n } as never, HistoryButton as never)), 'task-bus: message history')\n}"],"mappings":"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"}
|