vue-devui 1.6.23 → 1.6.25

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.
@@ -3,19 +3,11 @@ import type { LineSide, CodeReviewProps } from '../code-review-types';
3
3
  export declare function useCodeReviewComment(reviewContentRef: Ref<HTMLElement>, props: CodeReviewProps, ctx: SetupContext): {
4
4
  commentLeft: Ref<number>;
5
5
  commentTop: Ref<number>;
6
- mouseEvent: {
7
- onMousemove: (e: MouseEvent) => void;
8
- onMouseleave: (e: MouseEvent) => void;
9
- } | {
10
- onMousemove?: undefined;
11
- onMouseleave?: undefined;
12
- };
6
+ mouseEvent: Record<string, (e: MouseEvent) => void>;
13
7
  updateCheckedLineClass: () => void;
14
8
  clearCheckedLines: () => void;
15
9
  onCommentMouseLeave: (e: MouseEvent) => void;
16
10
  onCommentIconClick: (e: Event) => void;
17
- onCommentKeyDown: () => void;
18
- unCommentKeyDown: () => void;
19
11
  insertComment: (lineNumber: number, lineSide: LineSide, commentDom: HTMLElement) => void;
20
12
  removeComment: (lineNumber: number, lineSide: LineSide) => void;
21
13
  };
@@ -0,0 +1,5 @@
1
+ import type { Ref } from 'vue';
2
+ import type { CodeReviewProps } from '../code-review-types';
3
+ export declare function useCodeReviewLineSelection(reviewContentRef: Ref<HTMLElement>, props: CodeReviewProps, mouseMoveCb: (moveDirection: 'up' | 'down') => void, mouseupCb: () => void): {
4
+ onMousedown: (e: MouseEvent) => void;
5
+ };
@@ -18,3 +18,4 @@ export declare function addCommentToPageForSingleColumn(lineHost: HTMLElement, c
18
18
  export declare function addCommentToPageForDoubleColumn(lineHost: HTMLElement, commentDom: HTMLElement, lineSide: LineSide): void;
19
19
  export declare function findReferenceDomForSingleColumn(parentNode: HTMLElement, lineNumber: number, lineSide: LineSide): HTMLTableRowElement | undefined;
20
20
  export declare function findReferenceDomForDoubleColumn(parentNode: HTMLElement, lineNumber: number, lineSide: LineSide): HTMLTableRowElement | undefined;
21
+ export declare function findParentTrNode(node: HTMLElement | null): any;
package/vue-devui.es.js CHANGED
@@ -17514,6 +17514,15 @@ function findReferenceDomForDoubleColumn(parentNode, lineNumber, lineSide) {
17514
17514
  }
17515
17515
  }
17516
17516
  }
17517
+ function findParentTrNode(node) {
17518
+ if (!node) {
17519
+ return null;
17520
+ }
17521
+ if (node.tagName === "TR") {
17522
+ return node;
17523
+ }
17524
+ return findParentTrNode(node.parentElement);
17525
+ }
17517
17526
  function useCodeReviewExpand(reviewContentRef, props) {
17518
17527
  const { outputFormat, expandThreshold, expandLoader } = toRefs(props);
17519
17528
  const processSideBySide = () => {
@@ -17741,25 +17750,163 @@ function useCodeReviewFold(props, ctx2) {
17741
17750
  });
17742
17751
  return { isFold, toggleFold };
17743
17752
  }
17753
+ function useCodeReviewLineSelection(reviewContentRef, props, mouseMoveCb, mouseupCb) {
17754
+ const ns2 = useNamespace$1("code-review");
17755
+ let dragging = false;
17756
+ let startTrNode;
17757
+ let trNodes;
17758
+ let isClickedLeft;
17759
+ let shouldClear;
17760
+ let isMouseMoved;
17761
+ let startClientY;
17762
+ const onMousedown2 = (e) => {
17763
+ if (e.button === 0) {
17764
+ const composedPath = e.composedPath();
17765
+ const lineNumberBox = composedPath.find(
17766
+ (item) => {
17767
+ var _a, _b;
17768
+ return ((_a = item.classList) == null ? void 0 : _a.contains("comment-icon-hover")) || ((_b = item.classList) == null ? void 0 : _b.contains("comment-icon"));
17769
+ }
17770
+ );
17771
+ trNodes = Array.from(reviewContentRef.value.querySelectorAll("tr")).filter((item) => {
17772
+ var _a;
17773
+ return !((_a = item.classList) == null ? void 0 : _a.contains("expand-line"));
17774
+ });
17775
+ if (!lineNumberBox) {
17776
+ return;
17777
+ }
17778
+ const parentTrNode = findParentTrNode(e.target);
17779
+ if (parentTrNode && (parentTrNode == null ? void 0 : parentTrNode.classList.contains("expand-line"))) {
17780
+ return;
17781
+ }
17782
+ startTrNode = parentTrNode;
17783
+ if (props.outputFormat === "side-by-side") {
17784
+ isClickedLeft = composedPath.some((item) => {
17785
+ var _a;
17786
+ return (_a = item.classList) == null ? void 0 : _a.contains("d-code-left");
17787
+ });
17788
+ } else {
17789
+ isClickedLeft = void 0;
17790
+ }
17791
+ dragging = true;
17792
+ shouldClear = true;
17793
+ isMouseMoved = false;
17794
+ startClientY = e.clientY;
17795
+ e.preventDefault();
17796
+ e.stopPropagation();
17797
+ document.addEventListener("mousemove", onMousemove);
17798
+ document.addEventListener("mouseup", onMouseup);
17799
+ }
17800
+ };
17801
+ function onMousemove(e) {
17802
+ if (!dragging) {
17803
+ return;
17804
+ }
17805
+ isMouseMoved = true;
17806
+ if (shouldClear) {
17807
+ clearCommentChecked();
17808
+ shouldClear = false;
17809
+ }
17810
+ const composedPath = e.composedPath();
17811
+ const inReviewContent = composedPath.some((item) => {
17812
+ var _a;
17813
+ return (_a = item.classList) == null ? void 0 : _a.contains(ns2.e("content"));
17814
+ });
17815
+ if (!inReviewContent) {
17816
+ return;
17817
+ }
17818
+ const endTrNode = findParentTrNode(e.target);
17819
+ if (!endTrNode) {
17820
+ return;
17821
+ }
17822
+ let startIndex = trNodes.indexOf(startTrNode);
17823
+ let endIndex = trNodes.indexOf(endTrNode);
17824
+ if (endIndex === -1) {
17825
+ return;
17826
+ }
17827
+ mouseMoveCb(e.clientY > startClientY ? "down" : "up");
17828
+ if (startIndex > endIndex) {
17829
+ [startIndex, endIndex] = [endIndex, startIndex];
17830
+ }
17831
+ let position;
17832
+ if (isClickedLeft === void 0) {
17833
+ position = "all";
17834
+ } else if (isClickedLeft) {
17835
+ position = "left";
17836
+ } else {
17837
+ position = "right";
17838
+ }
17839
+ for (let i = 0; i < trNodes.length; i++) {
17840
+ if (i >= startIndex && i <= endIndex) {
17841
+ toggleCommentCheckedClass(trNodes[i], true, position);
17842
+ } else {
17843
+ toggleCommentCheckedClass(trNodes[i], false, position);
17844
+ }
17845
+ }
17846
+ }
17847
+ function onMouseup() {
17848
+ dragging = false;
17849
+ if (isMouseMoved) {
17850
+ mouseupCb();
17851
+ }
17852
+ document.removeEventListener("mouseup", onMouseup);
17853
+ document.removeEventListener("mousemove", onMousemove);
17854
+ }
17855
+ function clearCommentChecked() {
17856
+ for (let i = 0; i < trNodes.length; i++) {
17857
+ toggleCommentCheckedClass(trNodes[i], false, "all");
17858
+ }
17859
+ }
17860
+ function toggleCommentCheckedClass(trNode, isAddClass, position) {
17861
+ var _a;
17862
+ const tdNodes = Array.from(trNode.children);
17863
+ let toDoNodes;
17864
+ if (position === "all") {
17865
+ toDoNodes = tdNodes;
17866
+ } else if (position === "left") {
17867
+ toDoNodes = tdNodes.slice(0, 2);
17868
+ } else {
17869
+ toDoNodes = tdNodes.slice(2);
17870
+ }
17871
+ if ((position === "left" || position === "right") && isNaN(parseInt((_a = toDoNodes[0]) == null ? void 0 : _a.innerHTML))) {
17872
+ return;
17873
+ }
17874
+ toDoNodes.forEach((item) => {
17875
+ if (item.tagName === "TD") {
17876
+ if (isAddClass) {
17877
+ item.classList.add("comment-checked");
17878
+ } else {
17879
+ item.classList.remove("comment-checked");
17880
+ }
17881
+ }
17882
+ });
17883
+ }
17884
+ return { onMousedown: onMousedown2 };
17885
+ }
17744
17886
  function useCodeReviewComment(reviewContentRef, props, ctx2) {
17745
17887
  const { outputFormat, allowComment, allowChecked } = toRefs(props);
17746
17888
  const ns2 = useNamespace$1("code-review");
17889
+ const { onMousedown: onMousedown2 } = useCodeReviewLineSelection(reviewContentRef, props, updateLineNumbers, afterCheckLines);
17747
17890
  const commentLeft = ref(-100);
17748
17891
  const commentTop = ref(-100);
17749
17892
  let currentLeftLineNumber = -1;
17750
17893
  let currentRightLineNumber = -1;
17751
17894
  let lastLineNumberContainer;
17752
17895
  let checkedLineNumberContainer = [];
17753
- let isShift = false;
17754
17896
  let currentLeftLineNumbers = [];
17755
17897
  let currentRightLineNumbers = [];
17756
17898
  let checkedLineCodeString = {};
17757
- watch(() => outputFormat.value, () => {
17758
- checkedLineNumberContainer = [];
17759
- currentLeftLineNumbers = [];
17760
- currentRightLineNumbers = [];
17761
- checkedLineCodeString = [];
17762
- });
17899
+ let allTrNodes = [];
17900
+ let afterCheckLinesEmitData;
17901
+ watch(
17902
+ () => outputFormat.value,
17903
+ () => {
17904
+ checkedLineNumberContainer = [];
17905
+ currentLeftLineNumbers = [];
17906
+ currentRightLineNumbers = [];
17907
+ checkedLineCodeString = [];
17908
+ }
17909
+ );
17763
17910
  const resetLeftTop = () => {
17764
17911
  commentLeft.value = -100;
17765
17912
  commentTop.value = -100;
@@ -17842,30 +17989,7 @@ function useCodeReviewComment(reviewContentRef, props, ctx2) {
17842
17989
  resetLeftTop();
17843
17990
  }
17844
17991
  };
17845
- function commentKeyDown(e) {
17846
- switch (e.key) {
17847
- case "Shift":
17848
- isShift = true;
17849
- break;
17850
- }
17851
- }
17852
- function commentKeyUp(e) {
17853
- e.preventDefault();
17854
- switch (e.key) {
17855
- case "Shift":
17856
- isShift = false;
17857
- break;
17858
- }
17859
- }
17860
- const unCommentKeyDown = () => {
17861
- document.removeEventListener("keydown", commentKeyDown);
17862
- document.removeEventListener("keyup", commentKeyUp);
17863
- };
17864
- const onCommentKeyDown = () => {
17865
- document.addEventListener("keydown", commentKeyDown);
17866
- document.addEventListener("keyup", commentKeyUp);
17867
- };
17868
- const getLineNumbers = (currentNumber, currentNumbers, e) => {
17992
+ const getLineNumbers = (currentNumber, currentNumbers, moveDirection) => {
17869
17993
  if (currentNumber === -1) {
17870
17994
  return currentNumbers;
17871
17995
  }
@@ -17874,26 +17998,27 @@ function useCodeReviewComment(reviewContentRef, props, ctx2) {
17874
17998
  }
17875
17999
  const numbers = [...currentNumbers];
17876
18000
  let max = Math.max(...numbers);
17877
- const min = Math.min(...numbers);
17878
- if (currentNumber > max) {
18001
+ let min = Math.min(...numbers);
18002
+ if (moveDirection === "down") {
17879
18003
  max = currentNumber;
17880
18004
  }
18005
+ if (moveDirection === "up") {
18006
+ min = currentNumber;
18007
+ }
17881
18008
  return Array.from({ length: max - min + 1 }, (_, i) => i + min);
17882
18009
  };
17883
- const getCommonClassAndJudge = (side) => {
17884
- const lineClassName = side === "line-by-line" ? ".d2h-code-linenumber" : ".d2h-code-side-linenumber";
17885
- const linenumberDom = reviewContentRef.value.querySelectorAll(lineClassName);
18010
+ const getCommonClassAndJudge = () => {
17886
18011
  const checkedLine = [currentLeftLineNumbers, currentRightLineNumbers];
17887
18012
  return {
17888
- linenumberDom,
18013
+ linenumberDom: allTrNodes,
17889
18014
  checkedLine
17890
18015
  };
17891
18016
  };
17892
18017
  const addCommentCheckedClass = (Dom) => {
17893
18018
  !Dom.classList.contains("comment-checked") && Dom.classList.add("comment-checked");
17894
18019
  };
17895
- const addCommentClassSingle = (side) => {
17896
- const { linenumberDom, checkedLine } = getCommonClassAndJudge(side);
18020
+ function getSingleCheckedLineCode(shouldRenderClass) {
18021
+ const { linenumberDom, checkedLine } = getCommonClassAndJudge();
17897
18022
  const checkedCodeContent = [];
17898
18023
  for (let i = 0; i < linenumberDom.length; i++) {
17899
18024
  const lineNumberDomLeft = linenumberDom[i].children[0];
@@ -17903,25 +18028,29 @@ function useCodeReviewComment(reviewContentRef, props, ctx2) {
17903
18028
  const codeLineNumberRight = parseInt(lineNumberDomRight == null ? void 0 : lineNumberDomRight.innerText);
17904
18029
  if (checkedLine[0].includes(codeLineNumberLeft) || checkedLine[1].includes(codeLineNumberRight)) {
17905
18030
  checkedLineNumberContainer.push(linenumberDom[i]);
17906
- const codeNode = linenumberDom[i].nextSibling.nodeName === "#text" ? linenumberDom[i].nextSibling.nextSibling : linenumberDom[i].nextSibling;
18031
+ const codeNode = linenumberDom[i].nextElementSibling;
17907
18032
  checkedCodeContent.push(codeNode == null ? void 0 : codeNode.innerText);
17908
- addCommentCheckedClass(linenumberDom[i]);
17909
- addCommentCheckedClass(codeNode);
18033
+ if (shouldRenderClass) {
18034
+ addCommentCheckedClass(linenumberDom[i]);
18035
+ addCommentCheckedClass(codeNode);
18036
+ }
17910
18037
  }
17911
18038
  }
17912
18039
  }
17913
18040
  checkedLineCodeString = checkedCodeContent;
17914
- };
17915
- const addCommentClassDouble = (side) => {
18041
+ }
18042
+ function getDoubleCheckedLineCode(shouldRenderClass) {
17916
18043
  var _a;
17917
- const { linenumberDom, checkedLine } = getCommonClassAndJudge(side);
18044
+ const { linenumberDom, checkedLine } = getCommonClassAndJudge();
17918
18045
  const checkedCodeContentLeft = [];
17919
18046
  const checkedCodeContentRight = [];
17920
18047
  function checkedFunc(Dom) {
17921
18048
  checkedLineNumberContainer.push(Dom);
17922
- const codeNode = Dom.nextSibling.nodeName === "#text" ? Dom.nextSibling.nextSibling : Dom.nextSibling;
17923
- addCommentCheckedClass(Dom);
17924
- addCommentCheckedClass(codeNode);
18049
+ const codeNode = Dom.nextElementSibling;
18050
+ if (shouldRenderClass) {
18051
+ addCommentCheckedClass(Dom);
18052
+ addCommentCheckedClass(codeNode);
18053
+ }
17925
18054
  return codeNode == null ? void 0 : codeNode.innerText;
17926
18055
  }
17927
18056
  for (let i = 0; i < linenumberDom.length; i++) {
@@ -17937,38 +18066,53 @@ function useCodeReviewComment(reviewContentRef, props, ctx2) {
17937
18066
  }
17938
18067
  }
17939
18068
  checkedLineCodeString = { leftCode: checkedCodeContentLeft, rightCode: checkedCodeContentRight };
17940
- };
17941
- const updateCheckedLineClass = () => {
17942
- if (outputFormat.value === "line-by-line") {
17943
- addCommentClassSingle(outputFormat.value);
17944
- return;
18069
+ }
18070
+ function getCheckedLineCode(shouldRenderClass) {
18071
+ if (props.outputFormat === "line-by-line") {
18072
+ return getSingleCheckedLineCode(shouldRenderClass);
17945
18073
  }
17946
- addCommentClassDouble(outputFormat.value);
18074
+ getDoubleCheckedLineCode(shouldRenderClass);
18075
+ }
18076
+ function updateLineNumbers(moveDirection) {
18077
+ currentLeftLineNumbers = currentLeftLineNumber === -1 ? currentLeftLineNumbers : getLineNumbers(currentLeftLineNumber, currentLeftLineNumbers, moveDirection);
18078
+ currentRightLineNumbers = currentRightLineNumber === -1 ? currentRightLineNumbers : getLineNumbers(currentRightLineNumber, currentRightLineNumbers, moveDirection);
18079
+ getCheckedLineCode(false);
18080
+ afterCheckLinesEmitData = {
18081
+ left: currentLeftLineNumber,
18082
+ right: currentRightLineNumber,
18083
+ details: {
18084
+ lefts: currentLeftLineNumbers,
18085
+ rights: currentRightLineNumbers,
18086
+ codes: checkedLineCodeString
18087
+ }
18088
+ };
18089
+ }
18090
+ const updateCheckedLineClass = () => {
18091
+ getCheckedLineCode(true);
17947
18092
  };
17948
18093
  const resetCommentClass = () => {
17949
18094
  for (let i = 0; i < checkedLineNumberContainer.length; i++) {
17950
18095
  checkedLineNumberContainer[i].classList.remove("comment-checked");
17951
- const codeNode = checkedLineNumberContainer[i].nextSibling.nodeName === "#text" ? checkedLineNumberContainer[i].nextSibling.nextSibling : checkedLineNumberContainer[i].nextSibling;
18096
+ const codeNode = checkedLineNumberContainer[i].nextElementSibling;
17952
18097
  codeNode == null ? void 0 : codeNode.classList.remove("comment-checked");
17953
18098
  }
17954
18099
  checkedLineNumberContainer = [];
17955
18100
  };
17956
- const commentShiftClick = (e) => {
17957
- currentLeftLineNumbers = currentLeftLineNumber === -1 ? currentLeftLineNumbers : getLineNumbers(currentLeftLineNumber, currentLeftLineNumbers);
17958
- currentRightLineNumbers = currentRightLineNumber === -1 ? currentRightLineNumbers : getLineNumbers(currentRightLineNumber, currentRightLineNumbers);
17959
- updateCheckedLineClass();
17960
- };
17961
- const commentClick = (e) => {
18101
+ const commentClick = () => {
17962
18102
  let obj = { left: currentLeftLineNumber, right: currentRightLineNumber };
17963
- if (currentLeftLineNumbers.length >= 1 || currentRightLineNumbers.length >= 1 && allowChecked.value) {
18103
+ if ((currentLeftLineNumbers.length >= 1 || currentRightLineNumbers.length >= 1) && allowChecked.value) {
17964
18104
  const maxCurrentLeftLineNumber = currentLeftLineNumbers[currentLeftLineNumbers.length - 1];
17965
18105
  const maxCurrentRightLineNumber = currentRightLineNumbers[currentRightLineNumbers.length - 1];
17966
18106
  if (maxCurrentLeftLineNumber === currentLeftLineNumber || maxCurrentRightLineNumber === currentRightLineNumber) {
17967
- obj = { left: currentLeftLineNumber, right: currentRightLineNumber, details: {
17968
- lefts: currentLeftLineNumbers,
17969
- rights: currentRightLineNumbers,
17970
- codes: checkedLineCodeString
17971
- } };
18107
+ obj = {
18108
+ left: currentLeftLineNumber,
18109
+ right: currentRightLineNumber,
18110
+ details: {
18111
+ lefts: currentLeftLineNumbers,
18112
+ rights: currentRightLineNumbers,
18113
+ codes: checkedLineCodeString
18114
+ }
18115
+ };
17972
18116
  } else {
17973
18117
  currentLeftLineNumbers = [];
17974
18118
  currentRightLineNumbers = [];
@@ -17977,6 +18121,9 @@ function useCodeReviewComment(reviewContentRef, props, ctx2) {
17977
18121
  }
17978
18122
  ctx2.emit("addComment", obj);
17979
18123
  };
18124
+ function afterCheckLines() {
18125
+ ctx2.emit("afterCheckLines", afterCheckLinesEmitData);
18126
+ }
17980
18127
  const onCommentIconClick = (e) => {
17981
18128
  if (e) {
17982
18129
  const composedPath = e.composedPath();
@@ -17990,10 +18137,6 @@ function useCodeReviewComment(reviewContentRef, props, ctx2) {
17990
18137
  return;
17991
18138
  }
17992
18139
  }
17993
- if (isShift && allowChecked.value) {
17994
- commentShiftClick();
17995
- return;
17996
- }
17997
18140
  commentClick();
17998
18141
  };
17999
18142
  const insertComment = (lineNumber, lineSide, commentDom) => {
@@ -18040,7 +18183,19 @@ function useCodeReviewComment(reviewContentRef, props, ctx2) {
18040
18183
  checkedLineCodeString = [];
18041
18184
  resetCommentClass();
18042
18185
  };
18043
- const mouseEvent = allowComment.value ? { onMousemove: onMouseMove, onMouseleave } : {};
18186
+ const handleMouseDown = (e) => {
18187
+ const lineClassName = props.outputFormat === "line-by-line" ? ".d2h-code-linenumber" : ".d2h-code-side-linenumber";
18188
+ allTrNodes = reviewContentRef.value.querySelectorAll(lineClassName);
18189
+ onMousedown2(e);
18190
+ };
18191
+ const mouseEvent = {};
18192
+ if (allowComment.value) {
18193
+ mouseEvent.onMousemove = onMouseMove;
18194
+ mouseEvent.onMouseleave = onMouseleave;
18195
+ }
18196
+ if (props.allowChecked) {
18197
+ mouseEvent.onMousedown = handleMouseDown;
18198
+ }
18044
18199
  window.addEventListener("scroll", resetLeftTop);
18045
18200
  onUnmounted(() => {
18046
18201
  window.removeEventListener("scroll", resetLeftTop);
@@ -18053,8 +18208,6 @@ function useCodeReviewComment(reviewContentRef, props, ctx2) {
18053
18208
  clearCheckedLines,
18054
18209
  onCommentMouseLeave,
18055
18210
  onCommentIconClick,
18056
- onCommentKeyDown,
18057
- unCommentKeyDown,
18058
18211
  insertComment,
18059
18212
  removeComment
18060
18213
  };
@@ -18063,7 +18216,7 @@ var codeReview = "";
18063
18216
  var CodeReview = defineComponent({
18064
18217
  name: "DCodeReview",
18065
18218
  props: codeReviewProps,
18066
- emits: ["foldChange", "addComment", "afterViewInit", "contentRefresh"],
18219
+ emits: ["foldChange", "addComment", "afterViewInit", "contentRefresh", "afterCheckLines"],
18067
18220
  setup(props, ctx2) {
18068
18221
  const ns2 = useNamespace$1("code-review");
18069
18222
  const {
@@ -18085,8 +18238,6 @@ var CodeReview = defineComponent({
18085
18238
  mouseEvent,
18086
18239
  onCommentMouseLeave,
18087
18240
  onCommentIconClick,
18088
- onCommentKeyDown,
18089
- unCommentKeyDown,
18090
18241
  insertComment,
18091
18242
  removeComment,
18092
18243
  updateCheckedLineClass,
@@ -18100,10 +18251,6 @@ var CodeReview = defineComponent({
18100
18251
  updateCheckedLineClass,
18101
18252
  clearCheckedLines
18102
18253
  });
18103
- onCommentKeyDown();
18104
- });
18105
- onBeforeUnmount(() => {
18106
- unCommentKeyDown();
18107
18254
  });
18108
18255
  provide(CodeReviewInjectionKey, {
18109
18256
  diffType,
@@ -54140,7 +54287,7 @@ const installs = [
54140
54287
  VirtualListInstall
54141
54288
  ];
54142
54289
  var vueDevui = {
54143
- version: "1.6.23",
54290
+ version: "1.6.25",
54144
54291
  install(app) {
54145
54292
  installs.forEach((p) => app.use(p));
54146
54293
  }