@blueking/chat-x 0.0.45-dev.1 → 0.0.46-beta.1

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.
@@ -1,5 +1,6 @@
1
- import type { ComputedRef, Ref, ShallowRef } from 'vue';
1
+ import type { ComputedRef, MaybeRef, Ref, ShallowRef } from 'vue';
2
2
  import { type Message, APPROVAL_STATUS, InterruptReason, MessageContentType, MessageRole, MessageStatus } from '../ag-ui/types';
3
+ import { RenderMode } from '../common/constants';
3
4
  import type { UserQuestionInterrupt } from '../ag-ui/types/interrupt';
4
5
  export type MessageGroup = {
5
6
  checked: boolean;
@@ -14,6 +15,7 @@ export type MessageGroup = {
14
15
  export declare const useMessageGroup: (options: {
15
16
  keyword?: ShallowRef<string>;
16
17
  messages: ComputedRef<Message[]>;
18
+ renderMode?: MaybeRef<RenderMode>;
17
19
  selectedUserMessages: Ref<Message[] | undefined>;
18
20
  }) => {
19
21
  messageGroups: Ref<{
package/dist/index.js CHANGED
@@ -2457,7 +2457,7 @@ var Ur = () => _(Br), Wr = (() => {
2457
2457
  })) == null ? !1 : s
2458
2458
  });
2459
2459
  }
2460
- ((n = e.messages.value.at(-1)) == null ? void 0 : n.role) === K.User && i.push({
2460
+ ((n = e.messages.value.at(-1)) == null ? void 0 : n.role) === K.User && R(e.renderMode) !== Pt.Share && i.push({
2461
2461
  messages: [{
2462
2462
  role: K.Loading,
2463
2463
  content: "",
@@ -8013,61 +8013,70 @@ var Fd = ["src"], Id = {
8013
8013
  onResume: { type: Function }
8014
8014
  },
8015
8015
  setup(t) {
8016
- let n = t, r = mi(), i = F(!1), { questions: o, answeredCount: u, totalCount: p, completed: m, getAnswer: h, setAnswer: g, buildResolvePayload: _, buildSkipPayload: v } = Af(() => n.interrupt), y = a(() => {
8016
+ let n = t, r = mi(), i = F(!1), { questions: u, answeredCount: p, totalCount: m, completed: h, getAnswer: g, setAnswer: _, buildResolvePayload: v, buildSkipPayload: y } = Af(() => n.interrupt), x = a(() => {
8017
8017
  var e;
8018
8018
  return ((e = n.interrupt.metadata) == null || (e = e.questions) == null || (e = e[0]) == null ? void 0 : e.header) || n.interrupt.message || "";
8019
- }), x = () => {
8019
+ }), C = () => {
8020
8020
  i.value = !i.value;
8021
- }, C = () => {
8022
- i.value && (i.value = !1);
8023
8021
  }, T = () => {
8022
+ i.value && (i.value = !1);
8023
+ }, E = F(null), D = () => {
8024
8024
  var e;
8025
- m.value && ((e = n.onResume) == null || e.call(n, _(), n.interrupt));
8026
- }, E = () => {
8025
+ !h.value || E.value !== null || (E.value = "complete", (e = n.onResume) == null || e.call(n, v(), n.interrupt));
8026
+ }, O = () => {
8027
8027
  var e;
8028
- (e = n.onResume) == null || e.call(n, v(), n.interrupt);
8028
+ E.value === null && (E.value = "skip", (e = n.onResume) == null || e.call(n, y(), n.interrupt));
8029
8029
  };
8030
8030
  return (t, n) => (k(), c("section", { class: S(["ai-user-question-card", { "ai-user-question-card--collapsed": i.value }]) }, [
8031
8031
  l("header", {
8032
8032
  class: "ai-user-question-card__header",
8033
- onClick: C
8034
- }, [l("div", Jf, [f(z(Dn), { class: "ai-user-question-card__help-icon" }), U((k(), c("span", Yf, [d(I(y.value), 1)])), [[z(_i), Y({}, z(r))]])]), l("div", Xf, [l("span", Zf, I(z(u)) + " / " + I(z(p)), 1), f(z(mn), {
8033
+ onClick: T
8034
+ }, [l("div", Jf, [f(z(Dn), { class: "ai-user-question-card__help-icon" }), U((k(), c("span", Yf, [d(I(x.value), 1)])), [[z(_i), Y({}, z(r))]])]), l("div", Xf, [l("span", Zf, I(z(p)) + " / " + I(z(m)), 1), f(z(mn), {
8035
8035
  class: "ai-user-question-card__arrow",
8036
8036
  style: w({ transform: i.value ? "rotate(180deg)" : "rotate(-90deg)" }),
8037
- onClick: le(x, ["stop"])
8037
+ onClick: le(C, ["stop"])
8038
8038
  }, null, 8, ["style"])])]),
8039
- U(l("div", Qf, [(k(!0), c(e, null, M(z(o), (e, n) => (k(), c("div", {
8039
+ U(l("div", Qf, [(k(!0), c(e, null, M(z(u), (e, n) => (k(), c("div", {
8040
8040
  key: n,
8041
8041
  class: "ai-user-question-card__question"
8042
8042
  }, [l("div", $f, [l("span", ep, I(n + 1) + ". " + I(e.question), 1), e.multiSelect === void 0 ? s("", !0) : (k(), c("span", tp, I(e.multiSelect ? z(W)("多选") : z(W)("单选")), 1))]), l("div", np, [N(t.$slots, "question", b({ ref_for: !0 }, {
8043
8043
  question: e,
8044
8044
  qIndex: n,
8045
- answer: z(h)(n),
8046
- setAnswer: (e) => z(g)(n, e),
8047
- confirm: T
8045
+ answer: z(g)(n),
8046
+ setAnswer: (e) => z(_)(n, e),
8047
+ confirm: D
8048
8048
  }), () => [f(qf, {
8049
8049
  question: e,
8050
- onAnswer: (e) => z(g)(n, e),
8051
- onConfirm: T
8050
+ onAnswer: (e) => z(_)(n, e),
8051
+ onConfirm: D
8052
8052
  }, null, 8, ["question", "onAnswer"])])])]))), 128))], 512), [[ae, !i.value]]),
8053
8053
  U(l("footer", rp, [f(z(ue), {
8054
8054
  class: "ai-user-question-card__complete",
8055
- disabled: !z(m),
8055
+ disabled: !z(h) || E.value === "skip",
8056
+ loading: E.value === "complete",
8056
8057
  size: "small",
8057
8058
  theme: "primary",
8058
- onClick: T
8059
+ onClick: D
8059
8060
  }, {
8060
- default: H(() => [f(z(kn), { class: "ai-user-question-card__enter-icon" }), d(" " + I(z(W)("完成")), 1)]),
8061
+ default: H(() => [E.value === "complete" ? s("", !0) : (k(), o(z(kn), {
8062
+ key: 0,
8063
+ class: "ai-user-question-card__enter-icon"
8064
+ })), d(" " + I(z(W)("完成")), 1)]),
8061
8065
  _: 1
8062
- }, 8, ["disabled"]), f(z(ue), {
8066
+ }, 8, ["disabled", "loading"]), f(z(ue), {
8063
8067
  class: "ai-user-question-card__skip",
8068
+ disabled: E.value === "complete",
8069
+ loading: E.value === "skip",
8064
8070
  size: "small",
8065
8071
  text: "",
8066
- onClick: E
8072
+ onClick: O
8067
8073
  }, {
8068
- default: H(() => [f(z(An), { class: "ai-user-question-card__skip-icon" }), d(" " + I(z(W)("跳过")), 1)]),
8074
+ default: H(() => [E.value === "skip" ? s("", !0) : (k(), o(z(An), {
8075
+ key: 0,
8076
+ class: "ai-user-question-card__skip-icon"
8077
+ })), d(" " + I(z(W)("跳过")), 1)]),
8069
8078
  _: 1
8070
- })], 512), [[ae, !i.value]])
8079
+ }, 8, ["disabled", "loading"])], 512), [[ae, !i.value]])
8071
8080
  ], 2));
8072
8081
  }
8073
8082
  }), ap = { class: "ai-delete-confirm" }, op = { class: "ai-delete-confirm__title" }, sp = { class: "ai-delete-confirm__desc" }, cp = { class: "ai-delete-confirm__actions" }, lp = /* @__PURE__ */ m({
@@ -9218,12 +9227,12 @@ var Fd = ["src"], Id = {
9218
9227
  readonly: { type: Boolean }
9219
9228
  },
9220
9229
  setup(e) {
9221
- let t = e, n = mi(), { copy: r } = Pr(), i = new Set([G.PENDING, G.DRAFT]), u = new Set([
9230
+ let t = e, n = mi(), r = di(), i = a(() => r.value === Pt.Share), { copy: u } = Pr(), p = new Set([G.PENDING, G.DRAFT]), m = new Set([
9222
9231
  G.ABANDONED,
9223
9232
  G.CANCELLED,
9224
9233
  G.EXPIRED,
9225
9234
  G.REJECTED
9226
- ]), p = a(() => {
9235
+ ]), h = a(() => {
9227
9236
  var e, n;
9228
9237
  return (e = (n = t.interrupt.metadata) == null ? void 0 : n.ticket) == null ? {
9229
9238
  approvers: [],
@@ -9233,68 +9242,70 @@ var Fd = ["src"], Id = {
9233
9242
  title: "",
9234
9243
  url: ""
9235
9244
  } : e;
9236
- }), m = a(() => i.has(p.value.status)), h = a(() => m.value ? "pending" : p.value.status), g = a(() => {
9245
+ }), g = a(() => p.has(h.value.status)), _ = a(() => g.value ? "pending" : h.value.status), v = a(() => {
9237
9246
  var e;
9238
- return m.value ? W("评审中") : (e = vt[p.value.status]) == null ? p.value.status : e;
9239
- }), _ = a(() => p.value.approvers.filter(Boolean).join("、") || W("无")), v = a(() => p.value.url || p.value.sn), y = () => {
9240
- p.value.url && window.open(p.value.url, "_blank", "noopener");
9241
- }, b = () => {
9242
- v.value && r(v.value);
9243
- }, x = () => {
9247
+ return g.value ? W("评审中") : (e = vt[h.value.status]) == null ? h.value.status : e;
9248
+ }), y = a(() => h.value.approvers.filter(Boolean).join("、") || W("无")), b = a(() => h.value.url || h.value.sn), x = () => {
9249
+ h.value.url && window.open(h.value.url, "_blank", "noopener");
9250
+ }, C = () => {
9251
+ b.value && u(b.value);
9252
+ }, w = F(!1), T = () => {
9244
9253
  var e;
9245
- (e = t.onInterruptResume) == null || e.call(t, {
9254
+ w.value || (w.value = !0, (e = t.onInterruptResume) == null || e.call(t, {
9246
9255
  operation: yt.ApprovalCancel,
9247
9256
  payload: { interrupt_id: t.interrupt.id }
9248
- }, t.interrupt);
9257
+ }, t.interrupt));
9249
9258
  };
9250
9259
  return (t, r) => (k(), c("section", oh, [
9251
9260
  l("header", sh, [l("div", ch, [
9252
9261
  r[0] || (r[0] = l("span", { class: "ai-tool-approval-card__title-bar" }, null, -1)),
9253
- l("span", lh, I(p.value.title || z(W)("算法方案评审单")), 1),
9262
+ l("span", lh, I(h.value.title || z(W)("算法方案评审单")), 1),
9254
9263
  U(f(z(Wn), {
9255
- class: S(["ai-tool-approval-card__copy-icon", { "is-disabled": !v.value }]),
9256
- onClick: b
9264
+ class: S(["ai-tool-approval-card__copy-icon", { "is-disabled": !b.value }]),
9265
+ onClick: C
9257
9266
  }, null, 8, ["class"]), [[z(Ce), Y(Y({}, z(n)), {}, {
9258
9267
  content: z(W)("复制单据链接"),
9259
9268
  theme: "ai-chat-box",
9260
9269
  offset: [0, 8]
9261
9270
  })]])
9262
- ]), l("span", { class: S(["ai-tool-approval-card__status", `ai-tool-approval-card__status--${h.value}`]) }, [p.value.status === z(G).APPROVED ? (k(), o(z(Cn), {
9271
+ ]), l("span", { class: S(["ai-tool-approval-card__status", `ai-tool-approval-card__status--${_.value}`]) }, [h.value.status === z(G).APPROVED ? (k(), o(z(Cn), {
9263
9272
  key: 0,
9264
9273
  class: "ai-tool-approval-card__status-icon"
9265
- })) : z(u).has(p.value.status) ? (k(), o(z(Tn), {
9274
+ })) : z(m).has(h.value.status) ? (k(), o(z(Tn), {
9266
9275
  key: 1,
9267
9276
  class: "ai-tool-approval-card__status-icon"
9268
- })) : p.value.status === z(G).REVOKED ? (k(), o(z(En), {
9277
+ })) : h.value.status === z(G).REVOKED ? (k(), o(z(En), {
9269
9278
  key: 2,
9270
- class: S(["ai-tool-approval-card__status-icon", { "ai-tool-approval-card__status-icon--revoked": p.value.status === z(G).REVOKED }])
9279
+ class: S(["ai-tool-approval-card__status-icon", { "ai-tool-approval-card__status-icon--revoked": h.value.status === z(G).REVOKED }])
9271
9280
  }, null, 8, ["class"])) : (k(), o(z(he), {
9272
9281
  key: 3,
9273
9282
  class: "ai-tool-approval-card__status-icon",
9274
9283
  mode: "spin",
9275
9284
  size: "mini",
9276
9285
  theme: "primary"
9277
- })), d(" " + I(g.value), 1)], 2)]),
9278
- l("dl", uh, [l("div", dh, [l("dt", null, I(z(W)("单据编号")), 1), l("dd", null, I(p.value.sn || "--"), 1)]), l("div", fh, [l("dt", null, I(z(W)("提交时间")), 1), l("dd", null, I(p.value.submit_time || "--"), 1)])]),
9279
- l("div", ph, [f(z(wn), { class: "ai-tool-approval-card__processor-icon" }), U((k(), c("span", mh, [d(I(z(W)("当前处理人")) + ":" + I(_.value), 1)])), [[z(_i), Y({}, z(n))]])]),
9286
+ })), d(" " + I(v.value), 1)], 2)]),
9287
+ l("dl", uh, [l("div", dh, [l("dt", null, I(z(W)("单据编号")), 1), l("dd", null, I(h.value.sn || "--"), 1)]), l("div", fh, [l("dt", null, I(z(W)("提交时间")), 1), l("dd", null, I(h.value.submit_time || "--"), 1)])]),
9288
+ l("div", ph, [f(z(wn), { class: "ai-tool-approval-card__processor-icon" }), U((k(), c("span", mh, [d(I(z(W)("当前处理人")) + ":" + I(y.value), 1)])), [[z(_i), Y({}, z(n))]])]),
9280
9289
  l("div", hh, [f(z(ue), {
9281
9290
  class: "ai-tool-approval-card__detail",
9282
- disabled: !p.value.url,
9291
+ disabled: !h.value.url,
9283
9292
  theme: "primary",
9284
- onClick: y
9293
+ onClick: x
9285
9294
  }, {
9286
9295
  default: H(() => [d(I(z(W)("查看单据详情")) + " ", 1), r[1] || (r[1] = l("span", { class: "ai-tool-approval-card__detail-icon" }, null, -1))]),
9287
9296
  _: 1
9288
- }, 8, ["disabled"]), m.value && !e.readonly ? (k(), o(z(ue), {
9297
+ }, 8, ["disabled"]), g.value && !e.readonly ? (k(), o(z(ue), {
9289
9298
  key: 0,
9290
9299
  class: "ai-tool-approval-card__cancel",
9300
+ disabled: w.value || i.value,
9301
+ loading: w.value,
9291
9302
  outline: "",
9292
9303
  theme: "primary",
9293
- onClick: x
9304
+ onClick: T
9294
9305
  }, {
9295
9306
  default: H(() => [d(I(z(W)("取消审批")), 1)]),
9296
9307
  _: 1
9297
- })) : s("", !0)])
9308
+ }, 8, ["disabled", "loading"])) : s("", !0)])
9298
9309
  ]));
9299
9310
  }
9300
9311
  }), _h = { class: "ai-interrupt-message" }, vh = {
@@ -9715,15 +9726,15 @@ var Fd = ["src"], Id = {
9715
9726
  }),
9716
9727
  emits: /* @__PURE__ */ y(["stopStreaming"], ["update:selectedUserMessages"]),
9717
9728
  setup(t) {
9718
- let n = t, r = re(t, "selectedUserMessages"), i = B("messageContainerRef"), d = B("messageContainerBottomRef"), { toScrollBottom: p, debouncedShowScrollBottomBtn: m } = Rr(i, d), { copy: h } = Pr(), g = a(() => Ot.filter((e) => n.renderMode !== Pt.Test || e.id !== "share")), _ = (e) => {
9729
+ let n = t, r = re(t, "selectedUserMessages"), i = B("messageContainerRef"), d = B("messageContainerBottomRef"), { toScrollBottom: p, debouncedShowScrollBottomBtn: m } = Rr(i, d), { copy: h } = Pr(), g = a(() => Ot.filter((e) => n.renderMode !== Pt.Test || e.id !== "share")), _ = a(() => n.renderMode === Pt.Share ? n.messageGroups.filter((e) => e.type !== K.Loading) : n.messageGroups), v = (e) => {
9719
9730
  var t;
9720
9731
  let n = (t = e.messages) == null ? void 0 : t.at(-1);
9721
9732
  (n == null ? void 0 : n.role) !== K.Interrupt && (e.isHover = !0);
9722
- }, v = (e, t) => {
9733
+ }, y = (e, t) => {
9723
9734
  var n;
9724
9735
  let r = (n = t.toElement) == null ? t.relatedTarget : n;
9725
9736
  r instanceof Element && r.classList.contains("ai-user-feedback") || (e.isHover = !1);
9726
- }, y = (e, t) => {
9737
+ }, x = (e, t) => {
9727
9738
  var i, a;
9728
9739
  let o = e.type === K.User;
9729
9740
  (i = n.messageGroups) == null || i.forEach((r, i) => {
@@ -9733,7 +9744,7 @@ var Fd = ["src"], Id = {
9733
9744
  e && (e.checked = t);
9734
9745
  }
9735
9746
  }), r.value = (a = n.messageGroups) == null ? void 0 : a.filter((e) => e.checked).map((e) => e.messages).flat();
9736
- }, x = function() {
9747
+ }, C = function() {
9737
9748
  var e = X(function* (e, t) {
9738
9749
  var r;
9739
9750
  return e.id === "copy" && h(t.filter((e) => e.role !== K.Reasoning).map((e) => typeof e.content == "string" ? e.content : JSON.stringify(e.content || "")).join("\n")), (r = n.onAgentAction) == null ? void 0 : r.call(n, e, t);
@@ -9741,7 +9752,7 @@ var Fd = ["src"], Id = {
9741
9752
  return function(t, n) {
9742
9753
  return e.apply(this, arguments);
9743
9754
  };
9744
- }(), C = function() {
9755
+ }(), T = function() {
9745
9756
  var e = X(function* (e, t) {
9746
9757
  var r;
9747
9758
  (r = n.onUserAction) == null || r.call(n, e, t);
@@ -9749,7 +9760,7 @@ var Fd = ["src"], Id = {
9749
9760
  return function(t, n) {
9750
9761
  return e.apply(this, arguments);
9751
9762
  };
9752
- }(), T = function() {
9763
+ }(), E = function() {
9753
9764
  var e = X(function* (e, t, r) {
9754
9765
  var i;
9755
9766
  (i = n.onUserInputConfirm) == null || i.call(n, e, t, r);
@@ -9757,7 +9768,7 @@ var Fd = ["src"], Id = {
9757
9768
  return function(t, n, r) {
9758
9769
  return e.apply(this, arguments);
9759
9770
  };
9760
- }(), E = function() {
9771
+ }(), D = function() {
9761
9772
  var e = X(function* (e, t) {
9762
9773
  var r;
9763
9774
  (r = n.onUserShortcutConfirm) == null || r.call(n, e, t);
@@ -9771,18 +9782,18 @@ var Fd = ["src"], Id = {
9771
9782
  ref: i,
9772
9783
  class: "ai-message-container"
9773
9784
  }, [
9774
- (k(!0), c(e, null, M(t.messageGroups, (i, a) => (k(), c("div", {
9785
+ (k(!0), c(e, null, M(_.value, (i, a) => (k(), c("div", {
9775
9786
  id: i.uid,
9776
9787
  key: a,
9777
9788
  class: "message-group",
9778
9789
  style: w({ backgroundColor: i.checked ? "#f5f7fa" : "transparent" }),
9779
- onMouseenter: (e) => _(i),
9780
- onMouseleave: (e) => v(i, e)
9790
+ onMouseenter: (e) => v(i),
9791
+ onMouseleave: (e) => y(i, e)
9781
9792
  }, [N(r.$slots, "group", b({ ref_for: !0 }, { group: i }), () => [t.enableSelection && i.type !== z(K).Loading ? (k(), o(z(de), {
9782
9793
  key: 0,
9783
9794
  class: "message-group-checkbox",
9784
9795
  "model-value": i.checked,
9785
- "onUpdate:modelValue": (e) => y(i, e)
9796
+ "onUpdate:modelValue": (e) => x(i, e)
9786
9797
  }, null, 8, ["model-value", "onUpdate:modelValue"])) : s("", !0), l("div", {
9787
9798
  class: S(["message-group-messages", { "message-group-enabled-selection": t.renderMode === z(Pt).Share || t.enableSelection && i.type !== z(K).Loading }]),
9788
9799
  style: w({ width: t.enableSelection && i.type !== z(K).Loading ? "calc(100% - 16px)" : "100%" })
@@ -9797,10 +9808,10 @@ var Fd = ["src"], Id = {
9797
9808
  key: i,
9798
9809
  message: e,
9799
9810
  "message-tools-status": t.messageToolsStatus,
9800
- "on-action": (t) => C(t, e),
9801
- "on-input-confirm": (t, n) => T(e, t, n),
9811
+ "on-action": (t) => T(t, e),
9812
+ "on-input-confirm": (t, n) => E(e, t, n),
9802
9813
  "on-interrupt-resume": n.onInterruptResume,
9803
- "on-shortcut-confirm": (t) => E(e, t),
9814
+ "on-shortcut-confirm": (t) => D(e, t),
9804
9815
  "tippy-options": t.messageToolsTippyOptions
9805
9816
  }, u({ _: 2 }, [r.$slots.answeredQuestion ? {
9806
9817
  name: "answeredQuestion",
@@ -9818,7 +9829,7 @@ var Fd = ["src"], Id = {
9818
9829
  key: 0,
9819
9830
  "message-tools": g.value,
9820
9831
  "message-tools-status": t.messageToolsStatus,
9821
- "on-action": (e) => x(e, i.messages),
9832
+ "on-action": (e) => C(e, i.messages),
9822
9833
  style: w({ visibility: i.isHover ? "visible" : "hidden" }),
9823
9834
  "tippy-options": n.messageToolsTippyOptions,
9824
9835
  onFeedback: (e, t, r) => {
@@ -9846,7 +9857,7 @@ var Fd = ["src"], Id = {
9846
9857
  }, {
9847
9858
  icon: H(() => [f(z(yn))]),
9848
9859
  _: 1
9849
- }, 8, ["loading", "title"]), [[ae, t.messageStatus === z(q).Streaming || t.messageStatus === z(q).StopLoading || t.messageStatus === z(q).Fetching || t.messageStatus === z(q).Pending]]), U(f(nr, {
9860
+ }, 8, ["loading", "title"]), [[ae, t.renderMode !== z(Pt).Share && (t.messageStatus === z(q).Streaming || t.messageStatus === z(q).StopLoading || t.messageStatus === z(q).Fetching || t.messageStatus === z(q).Pending)]]), U(f(nr, {
9850
9861
  title: z(W)("返回底部"),
9851
9862
  onClick: z(p)
9852
9863
  }, {
@@ -10124,6 +10135,7 @@ var Fd = ["src"], Id = {
10124
10135
  }() }), se = F(""), ce = te([]), le = F(400), de = a(() => `calc(100% - ${le.value}px)`), { messageGroups: fe, executionGroups: pe, isShareMode: me, isAllSelected: he, onToggleShareAll: ge, onCancelShare: _e, onConfirmShare: ye, pendingApprovalTipText: be, activeUserQuestionInterrupt: Se } = ri({
10125
10136
  keyword: se,
10126
10137
  messages: a(() => u.messages),
10138
+ renderMode: a(() => p.value),
10127
10139
  selectedUserMessages: ce
10128
10140
  });
10129
10141
  V(R, (e) => {