lianghongjie 1 vuosi sitten
vanhempi
commit
6bda40d92a

+ 1 - 0
package.json

@@ -49,6 +49,7 @@
     "dayjs": "^1.11.7",
     "file-saver": "^2.0.5",
     "hotkeys-js": "^3.10.2",
+    "html2canvas": "^1.4.1",
     "jszip": "^3.10.1",
     "load-asset": "^1.2.0",
     "lodash": "^4.17.21",

+ 9 - 2
src/modules/editor/components/CompUI/basicUI/Container/component.tsx

@@ -4,6 +4,7 @@ import { useCompData } from ".";
 import { useEditor } from "../../../..";
 import { DesignComp } from "../../../../objects/DesignTemp/DesignComp";
 import { View } from "../View";
+import { CompUI } from "../..";
 
 export const Component = defineComponent({
   props: {
@@ -16,8 +17,14 @@ export const Component = defineComponent({
       <View compId={props.compId}>
         {children.default.map((compId) => {
           const compItem = helper.findComp(compId) as DesignComp;
-          const Comp = controls.compUICtrl.state.components.get(compItem.compKey)?.Component;
-          return <Comp key={compItem.id} compId={compItem.id} />;
+          const Comp =
+            controls.compUICtrl.state.components.get(compItem.compKey)
+              ?.Component || CompUI.Container.Component;
+          return (
+            <div class="flex flex-col" key={compItem.id}>
+              <Comp compId={compItem.id} />
+            </div>
+          );
         })}
       </View>
     );

+ 2 - 6
src/modules/editor/components/CompUI/basicUI/Image/component.tsx

@@ -3,7 +3,6 @@ import { defineComponent } from "vue";
 import { object, string } from "vue-types";
 import { useCompData } from ".";
 import { View } from "../View";
-import { css } from "@linaria/core";
 
 export const Component = defineComponent({
   props: {
@@ -45,7 +44,8 @@ export const Component = defineComponent({
           onDblclick={store.isEditMode ? changeVal : undefined}
         >
           <img
-            class={imgStyle}
+            crossorigin="anonymous"
+            class="pointer-events-none"
             style={{
               transform: `scale(${scale}) translate(${ox}%,${oy}%)`,
               objectFit,
@@ -57,7 +57,3 @@ export const Component = defineComponent({
     };
   },
 });
-
-const imgStyle = css`
-  @apply overflow-hidden object-cover pointer-events-none;
-`;

+ 1 - 1
src/modules/editor/components/CompUI/basicUI/Page/component.tsx

@@ -14,7 +14,7 @@ export const Component = defineComponent({
 
     return () => (
       <div style={helper.createStyle(layout)}>
-        <div class="page-content relative">
+        <div class="page-editing-content relative">
           {slots.Container?.(
             children.default.map((compId) => {
               const comp = helper.findComp(compId);

+ 86 - 87
src/modules/editor/components/CompUI/basicUI/Transfer/index.tsx

@@ -4,29 +4,6 @@ import { useEditor } from "../../../..";
 import { TransferCtrl } from "@/modules/editor/controllers/TransferCtrl";
 import { CompToolbars } from "@/modules/editor/objects/Toolbars";
 
-const btnStyles = {
-  top: {
-    top: 0,
-    left: "50%",
-    transform: "translate(-50%, -50%)",
-  },
-  bottom: {
-    bottom: 0,
-    left: "50%",
-    transform: "rotate(180deg) translate(50%, -50%)",
-  },
-  left: {
-    top: "50%",
-    left: 0,
-    transform: "rotate(-90deg) translate(50%, -50%)",
-  },
-  right: {
-    top: "50%",
-    right: 0,
-    transform: "rotate(90deg) translate(-50%, -50%)",
-  },
-};
-
 export const Transfer = defineComponent({
   setup() {
     const editor = useEditor();
@@ -36,7 +13,7 @@ export const Transfer = defineComponent({
 
     onMounted(() => {
       setTimeout(() => {
-        const pageEl = document.querySelector(".page-content");
+        const pageEl = document.querySelector(".page-editing-content");
         if (pageEl) {
           transferCtrl.init(pageEl as HTMLElement);
         }
@@ -55,6 +32,9 @@ export const Transfer = defineComponent({
       const comp = store.currComp;
       const toolbarOpts =
         CompToolbars[store.currComp.compKey] || CompToolbars.default;
+
+      const showTransfer =
+        store.isEditComp || store.pageCompIds.includes(comp.id);
       return (
         transferStyle.width && (
           <div
@@ -71,55 +51,59 @@ export const Transfer = defineComponent({
                 width: transferStyle.width,
                 height: transferStyle.height,
               }}
-            ></div>
-            <div
-              class={resizeStyle}
-              style={{ marginBottom: "-" + transferStyle.height }}
-              onMousedown={(e) => transferCtrl.mousedown(e, "scale")}
-            ></div>
-            <div class={toolbarStyle}>
-              {toolbarOpts.map((item) => {
-                return item.getVisible.call(editor, comp) ? (
-                  <item.component
-                    class="p-4px"
-                    value={item.getValue?.(comp)}
-                    onClick={() => item.onClick.call(editor, comp)}
-                  />
-                ) : null;
-              })}
-            </div>
-
-            <div
-              class={transformBtnsStyle}
-              style={{ marginBottom: "-" + transferStyle.height }}
-            >
-              <div
-                class={transBtnStyle}
-                onMousedown={(e) => transferCtrl.mousedown(e, "move")}
-              >
-                +
-              </div>
-              <div
-                class={transBtnStyle}
-                onMousedown={(e) => transferCtrl.mousedown(e, "rotate")}
-              >
-                -
-              </div>
-            </div>
-            {/* {Object.entries(btnStyles).map(([name, style]) => (
-            <div
-              class={[fanBtnStyle, "drag-disable"]}
-              style={style}
-              onMousedown={(e) =>
-                transferCtrl.mousedown(
-                  e,
-                  `offset_${name as keyof typeof btnStyles}`
-                )
-              }
-            >
-              ↑
-            </div>
-          ))} */}
+            />
+            {showTransfer && (
+              <>
+                <div
+                  class={resizeStyle}
+                  style={{ marginBottom: "-" + transferStyle.height }}
+                  onMousedown={(e) =>
+                    transferCtrl.mousedown(
+                      e,
+                      comp.compKey === "Image" ? "resizeXY" : "scale"
+                    )
+                  }
+                />
+                <div class={toolbarStyle}>
+                  {toolbarOpts.map((item) => {
+                    return item.getVisible.call(editor, comp) ? (
+                      <item.component
+                        class="p-4px"
+                        value={item.getValue?.(comp)}
+                        onClick={() => item.onClick.call(editor, comp)}
+                      />
+                    ) : null;
+                  })}
+                </div>
+                <div
+                  class={transformBtnsStyle}
+                  style={{ marginBottom: "-" + transferStyle.height }}
+                >
+                  <div
+                    class={transBtnStyle}
+                    onMousedown={(e) => transferCtrl.mousedown(e, "move")}
+                  >
+                    偏移
+                  </div>
+                  <div
+                    class={transBtnStyle}
+                    onMousedown={(e) => transferCtrl.mousedown(e, "rotate")}
+                  >
+                    旋转
+                  </div>
+                </div>
+                <div
+                  class={resizeHeightBtnCls}
+                  style={{ top: transferStyle.height }}
+                  onMousedown={(e) => transferCtrl.mousedown(e, "resizeY")}
+                />
+                <div
+                  class={resizeWidthBtnCls}
+                  style={{ top: parseInt(transferStyle.height) / 2 + "px" }}
+                  onMousedown={(e) => transferCtrl.mousedown(e, "resizeX")}
+                />
+              </>
+            )}
           </div>
         )
       );
@@ -185,28 +169,43 @@ const transBtnStyle = css`
   }
 `;
 
-const fanBtnStyle = css`
+const toolbarStyle = css`
+  @apply bg-white shadow rounded space-x-4px p-4px whitespace-nowrap;
   position: absolute;
-  width: 30px;
-  height: 30px;
-  border-radius: 50%;
-  background-color: rgba(255, 255, 255, 0.3);
-  font-size: 12px;
-  text-align: center;
-  clip-path: polygon(0 0, 100% 0, 100% 50%, 0 50%);
-  cursor: grab;
+  top: 0;
+  left: 50%;
+  transform: translate(-50%, -40px);
   z-index: 999;
+`;
 
+const resizeHeightBtnCls = css`
+  position: absolute;
+  width: 30px;
+  height: 8px;
+  border-radius: 4px;
+  left: 50%;
+  transform: translate(-50%, -4px);
+  cursor: ns-resize;
+  background: rgba(255, 255, 255, 0.3);
   &:hover {
     background: @inf-primary-color;
   }
+  @apply shadow;
+  z-index: 999;
 `;
 
-const toolbarStyle = css`
-  @apply bg-white shadow rounded space-x-4px p-4px whitespace-nowrap;
+const resizeWidthBtnCls = css`
   position: absolute;
-  top: 0;
-  left: 50%;
-  transform: translate(-50%, -40px);
+  width: 8px;
+  height: 30px;
+  border-radius: 4px;
+  right: 0;
+  transform: translate(4px, -50%);
+  cursor: ew-resize;
+  background: rgba(255, 255, 255, 0.3);
+  &:hover {
+    background: @inf-primary-color;
+  }
+  @apply shadow;
   z-index: 999;
 `;

+ 5 - 3
src/modules/editor/components/CompUI/basicUI/View.tsx

@@ -15,12 +15,14 @@ export const View = defineComponent({
     onMounted(() => {
       const comp = helper.findComp(props.compId);
       if (comp) {
-        Object.defineProperty(comp, "$el", { value: compRef.value, configurable: true });
+        Object.defineProperty(comp, "$el", {
+          value: compRef.value,
+          configurable: true,
+        });
       }
     });
 
     return () => {
-      const isSelected = store.currCompId === props.compId;
       const comp = helper.findComp(props.compId);
       if (!comp) return store.isEditMode ? <div>无效组件</div> : null;
 
@@ -31,7 +33,7 @@ export const View = defineComponent({
           style={helper.createStyle(comp.layout)}
           onClick={(e) => {
             e.stopPropagation();
-            if (store.isEditMode && !isSelected) {
+            if (store.isEditMode) {
               actions.pickComp(props.compId);
             }
           }}

+ 37 - 27
src/modules/editor/components/CompUI/customUI/Covers/Cover/component.tsx

@@ -1,49 +1,59 @@
 import { css } from "@linaria/core";
-import { isPc } from "@queenjs/utils";
-import { onMounted, ref } from "vue";
 import { string } from "vue-types";
 import { useCompData } from ".";
-import { Text } from "../../../basicUI";
+import { Image, Text } from "../../../basicUI";
+import { View } from "../../../basicUI/View";
 import { createUIComp } from "../../../defines/createUIComp";
+import { useEditor } from "@/modules/editor";
 
 export const Component = createUIComp({
   props: {
     compId: string().isRequired,
   },
   setup(props) {
+    const editor = useEditor();
     const { children } = useCompData(props.compId);
 
-    const elRef = ref();
-    onMounted(() => {
-      elRef.value.style.height = isPc()
-        ? "12.8rem"
-        : document.documentElement.clientHeight + "px";
-    });
+    function clickArrow() {
+      if (editor.store.isEditMode) return;
+      document.scrollingElement?.scrollTo({
+        top: document.documentElement.clientHeight,
+      });
+    }
 
     return () => {
       return (
-        <div class={compStyle} ref={elRef}>
-          <Text.Component compId={children.title} />
-          <div class="arrow">↓</div>
+        <div class="!<md:h-100vh !md:h-10.8rem">
+          <Image.Component class="w-full h-full" compId={children.bg} />
+          <Text.Component class={titleCls} compId={children.title} />
+          <div class={arrowCls} onClick={clickArrow}>
+            ↓
+          </div>
         </div>
       );
     };
   },
 });
 
-const compStyle = css`
-  .arrow {
-    position: absolute;
-    left: 50%;
-    bottom: 0.42rem;
-    width: 0.7rem;
-    height: 0.7rem;
-    line-height: 0.7rem;
-    font-size: 0.36rem;
-    text-align: center;
-    color: #fff;
-    border: 2px solid #fff;
-    border-radius: 50%;
-    transform: translateX(-50%);
-  }
+const titleCls = css`
+  position: absolute;
+  left: 50%;
+  top: 20%;
+  width: 7rem;
+  transform: translateX(-50%);
+`;
+
+const arrowCls = css`
+  position: absolute;
+  left: 50%;
+  bottom: 0.42rem;
+  width: 0.7rem;
+  height: 0.7rem;
+  line-height: 0.7rem;
+  font-size: 0.36rem;
+  text-align: center;
+  color: #fff;
+  border: 2px solid #fff;
+  border-radius: 50%;
+  transform: translateX(-50%);
 `;

+ 6 - 8
src/modules/editor/components/CompUI/customUI/Covers/Cover/index.ts

@@ -1,4 +1,3 @@
-import { Dict_Imgs } from "@/dict";
 import { createAttrsForm } from "../../../defines/createAttrsForm";
 import { createCompHooks } from "../../../defines/createCompHooks";
 import { createCompId } from "../../../defines/createCompId";
@@ -12,17 +11,16 @@ export const options = {
 
 export const { createComp, useCompData } = createCompHooks({
   value: {},
-  background: {
-    image:
-      "https://infishwaibao.oss-cn-chengdu.aliyuncs.com/release/sku3d/img/partner_bg.5e324d05.png",
-  },
   children: {
+    bg: () =>
+      createCompId("Image", {
+        value: {
+          url: "https://infishwaibao.oss-cn-chengdu.aliyuncs.com/release/sku3d/img/partner_bg.5e324d05.png",
+        },
+      }),
     title: () =>
       createCompId("Text", {
         value: `<p style="text-align:center;"><span style="color:hsl(0,0%,100%);font-size:28px;">新科技反光面料</span></p><p style="text-align:center;"><span style="color:hsl(0,0%,100%);font-size:28px;">引领潮流新风尚</span></p><p style="text-align:center;">&nbsp;</p><p style="text-align:center;"><span style="color:hsl(0,0%,100%);font-size:16px;">时尚 | 精致 | 百搭</span></p>`,
-        layout: {
-          margin: "1.4rem auto 0",
-        },
       }),
   },
 });

+ 9 - 3
src/modules/editor/components/Preview/index.tsx

@@ -6,11 +6,17 @@ export default defineUI({
   setup() {
     const { store } = useEditor();
     return () => (
-      <div class="flex flex-col">
+      <div>
         {store.pageCompIds.map((id) => {
           const compKey = store.designData.compMap[id]?.compKey;
-          const Comp: any = CompUI[compKey]?.Component;
-          return Comp && <Comp key={id} compId={id} />;
+          const Comp: any = (CompUI[compKey] || CompUI.Container).Component;
+          return (
+            Comp && (
+              <div class="flex flex-col" key={id}>
+                <Comp compId={id} />
+              </div>
+            )
+          );
         })}
       </div>
     );

+ 2 - 2
src/modules/editor/components/Viewport/Content/index.tsx

@@ -33,7 +33,7 @@ export default defineUI({
               return (
                 <>
                   <Container
-                    class="!min-h-750px"
+                    class={store.isEditPage ? "!min-h-750px" : ""}
                     group-name="canvas"
                     onDrop={(e: any) => {
                       if (e.payload) {
@@ -59,7 +59,7 @@ export default defineUI({
                 comp.compKey
               )?.Component;
               return (
-                <Draggable class="!flex flex-col">
+                <Draggable class="!flex flex-col" key={comp.id}>
                   <Comp compId={comp.id} />
                 </Draggable>
               );

+ 4 - 4
src/modules/editor/components/Viewport/Slider/SliderRight/index.tsx

@@ -9,14 +9,14 @@ export default defineUI({
 
     return () => {
       const { currComp } = editor.store;
-
+      const Form = editor.controls.compUICtrl.state.components.get(
+        currComp?.compKey
+      )?.Form;
       return (
         <div class="flex flex-col h-1/1">
           <div class="p-16px border-bottom !border-2px">设置栏</div>
           <div class="flex-1 p-16px scrollbar">
-            {currComp?.compKey
-              ? h(editor.controls.compUICtrl.state.components.get(currComp.compKey)?.Form, { component: currComp })
-              : null}
+            <Form component={currComp} />
           </div>
           <div class="p-16px border-bottom !border-2px border-top">组件树</div>
           <div class="h-300px py-20px pr-20px scrollbar">

+ 1 - 1
src/modules/editor/components/Viewport/index.tsx

@@ -21,7 +21,7 @@ export default defineUI({
           <slots.SliderLeft class="w-300px bg-component border-right !border-2px" />
           <div class="flex-1 h-1/1 scrollbar overflow-y-auto">
             {/* <slots.Toolbar /> */}
-            <slots.Content class="w-375px min-h-750px mx-auto my-60px bg-white" />
+            <slots.Content class="w-375px mx-auto my-60px bg-white" />
           </div>
           <slots.SliderRight class="w-360px bg-component border-left !border-2px" />
         </div>

+ 25 - 14
src/modules/editor/controllers/TransferCtrl/transforms/resize.ts

@@ -1,20 +1,31 @@
-import { TransCreateFn } from "..";
+import { TransCreateFn, TransferCtrl } from "..";
 
-export const resize: TransCreateFn = () => ({
+function getResize(this: TransferCtrl, direction: string) {
+  const { transEvent, currComp } = this;
+  const size = currComp.layout.size || [0, 0];
+  if (direction.indexOf("x") != -1) {
+    size[0] = transEvent.width + transEvent.offsetX * 2;
+  }
+  if (direction.indexOf("y") != -1) {
+    size[1] = transEvent.height + transEvent.offsetY * 2;
+  }
+  return size;
+}
+
+const resize: TransCreateFn = (direction: string) => ({
   mousemove() {
-    const { transEvent, compEl } = this;
-    compEl.style.width = this.module.helper.designToNaturalSize(
-      transEvent.width + transEvent.offsetX * 2
-    );
-    compEl.style.height = this.module.helper.designToNaturalSize(
-      transEvent.height + transEvent.offsetY * 2
-    );
+    const style = this.module.helper.createStyle({
+      size: getResize.call(this, direction),
+    });
+    Object.entries(style).forEach(([key, value]: any[]) => {
+      this.compEl.style[key] = value;
+    });
   },
   mouseup() {
-    const { transEvent } = this;
-    const { currComp } = this.module.store;
-    currComp.layout.size || (currComp.layout.size = [0, 0]);
-    currComp.layout.size[0] = transEvent.width + transEvent.offsetX * 2;
-    currComp.layout.size[1] = transEvent.height + transEvent.offsetY * 2;
+    this.currComp.layout.size = getResize.call(this, direction);
   },
 });
+
+export const resizeX = resize.bind(null, "x");
+export const resizeY = resize.bind(null, "y");
+export const resizeXY = resize.bind(null, "xy");

+ 0 - 1
src/modules/editor/controllers/TransferCtrl/transforms/transform.ts

@@ -19,7 +19,6 @@ function getTransform(this: TransferCtrl, transType: string) {
       break;
     case "scale":
       offset.s = +((offset.s * (1 + (transEvent.offsetX * 2) / transEvent.width)).toFixed(2))
-      console.log(offset.s);
   }
 
   return offset;

+ 20 - 2
src/modules/editor/module/actions/edit.ts

@@ -8,7 +8,10 @@ export const editActions = EditorModule.action({
   async addCompToDesign(compKey: ICompKeys, index?: number) {
     let compId: string;
     if (index === undefined && this.store.currComp?.compKey === "Container") {
-      compId = await this.store.insertCompContainer(compKey, this.store.currComp);
+      compId = await this.store.insertCompContainer(
+        compKey,
+        this.store.currComp
+      );
     } else {
       compId = await this.store.insertDesignContent(compKey, index);
     }
@@ -16,7 +19,14 @@ export const editActions = EditorModule.action({
   },
   // 切换当前组件
   pickComp(compId: string) {
-    this.store.setCurrComp(compId);
+    // let nextCompId = compId;
+    // if (this.store.isEditPage) {
+    //   const comps = this.helper.getCompTrees(compId);
+    //   nextCompId = comps[1].id;
+    // }
+    if (compId !== this.store.currCompId) {
+      this.store.setCurrComp(compId);
+    }
   },
   // 切换到父组件
   pickParentComp(compId: string) {
@@ -35,11 +45,19 @@ export const editActions = EditorModule.action({
     if (selIndex === targetIndex) return;
     this.store.moveComp(selIndex, targetIndex);
   },
+
   // 保存项目
   async saveDesign() {
     try {
       queenApi.showLoading("保存中");
+      // 清除多余组件
+      this.store.setCurrComp("");
       this.store.clearUnusedComps();
+
+      // 封面截屏
+      const blob = await this.helper.screenshot();
+      this.store.designData.thumbnail = URL.createObjectURL(blob);
+      await this.controls.uploader.uploadBlobs(this.store.designData);
       await this.https[this.store.isEditPage ? "saveDesign" : "saveComp"](
         this.store.designData
       );

+ 19 - 0
src/modules/editor/module/helpers/index.ts

@@ -3,6 +3,8 @@ import { EditorModule } from "..";
 import { DesignComp } from "../../objects/DesignTemp/DesignComp";
 import { createCompStyle } from "../../objects/DesignTemp/creates/createCompStyle";
 import { Layout } from "../../typings";
+import html2canvas from "html2canvas";
+import { Exception } from "queenjs";
 
 export const helpers = EditorModule.helper({
   designToNaturalSize(value: number) {
@@ -42,4 +44,21 @@ export const helpers = EditorModule.helper({
       parentComp.children.default?.findIndex((d) => d === comp.id) ?? -1;
     return i >= 0;
   },
+  async screenshot() {
+    // 解决html2canvas不支持object-fit的问题
+    // https://github.com/niklasvh/html2canvas/issues/1064
+    const dom = document.querySelector(".page-editing-content") as HTMLElement;
+    const canvas = await html2canvas(dom, {
+      useCORS: true,
+    });
+    return new Promise<Blob>((resolve, reject) => {
+      canvas.toBlob((blob) => {
+        if (blob) {
+          resolve(blob);
+        } else {
+          reject("截屏失败");
+        }
+      });
+    });
+  },
 });

+ 7 - 0
src/modules/editor/module/index.ts

@@ -10,6 +10,7 @@ import { initActions } from "./actions/init";
 import { helpers } from "./helpers";
 import { https } from "./https";
 import { store } from "./stores";
+import { UploadController } from "@queenjs/controllers";
 
 export class EditorModule extends ModuleRoot {
   config = this.setConfig({
@@ -25,6 +26,12 @@ export class EditorModule extends ModuleRoot {
   helper = this.createHelper(helpers);
 
   controls = {
+    uploader: new UploadController({
+      httpConfig: {
+        baseURL: Dict_Apis.queentree,
+      },
+      dir: "queenshow",
+    }),
     historyCtrl: new HistoryCtrl(this),
     pickCtrl: new ImagePickController(),
     compUICtrl: new CompUICtrl(this),

+ 1 - 0
src/modules/editor/objects/DesignTemp/index.ts

@@ -8,6 +8,7 @@ export class DesignTemp {
   title = "";
   pageStyle?: any;
   content: string[] = ["root"];
+  thumbnail?: string;
   compMap: { [compId: string]: DesignComp } = {};
 
   constructor(data?: Partial<DesignTemp>) {

+ 1 - 1
src/pages/website/MyComps/components/CompItem.tsx

@@ -17,7 +17,7 @@ export default defineUI({
       return (
         <div class={cx(itemStyles, "relative")}>
           <View ratio={1.4} class="overflow-hidden relative">
-            <Image class="h-1/1 w-1/1" src={record?.thumbnail?.url} />
+            <Image class="h-1/1 w-1/1 object-cover object-top" src={record?.thumbnail} />
             <Tag
               color="#E88B00"
               // color="rgba(0, 0, 0, 0.4)"

+ 1 - 1
src/pages/website/Promotion2/components/PromotionItem.tsx

@@ -50,7 +50,7 @@ export default defineUI({
       return (
         <div class={cx(itemStyles, "relative")}>
           <View ratio={1.4} class="overflow-hidden relative">
-            <Image class="h-1/1 w-1/1" src={record?.thumbnail?.url} />
+            <Image class="h-1/1 w-1/1 object-cover object-top" src={record?.thumbnail} />
             <Tag
               color="#E88B00"
               // color="rgba(0, 0, 0, 0.4)"

+ 34 - 0
yarn.lock

@@ -3024,6 +3024,11 @@ balanced-match@^1.0.0:
   resolved "http://124.70.149.18:4873/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
   integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
 
+base64-arraybuffer@^1.0.2:
+  version "1.0.2"
+  resolved "http://124.70.149.18:4873/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
+  integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
+
 base64-js@^1.3.1:
   version "1.5.1"
   resolved "http://124.70.149.18:4873/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@@ -3648,6 +3653,13 @@ css-declaration-sorter@^6.3.1:
   resolved "http://124.70.149.18:4873/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz#630618adc21724484b3e9505bce812def44000ad"
   integrity sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew==
 
+css-line-break@^2.1.0:
+  version "2.1.0"
+  resolved "http://124.70.149.18:4873/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0"
+  integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
+  dependencies:
+    utrie "^1.0.2"
+
 css-loader@^5.2.7:
   version "5.2.7"
   resolved "http://124.70.149.18:4873/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae"
@@ -5038,6 +5050,14 @@ html-webpack-plugin@^5.1.0:
     pretty-error "^4.0.0"
     tapable "^2.0.0"
 
+html2canvas@^1.4.1:
+  version "1.4.1"
+  resolved "http://124.70.149.18:4873/html2canvas/-/html2canvas-1.4.1.tgz#7cef1888311b5011d507794a066041b14669a543"
+  integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
+  dependencies:
+    css-line-break "^2.1.0"
+    text-segmentation "^1.0.3"
+
 htmlparser2@^6.1.0:
   version "6.1.0"
   resolved "http://124.70.149.18:4873/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
@@ -8052,6 +8072,13 @@ terser@^5.10.0, terser@^5.16.8, terser@^5.3.4:
     commander "^2.20.0"
     source-map-support "~0.5.20"
 
+text-segmentation@^1.0.3:
+  version "1.0.3"
+  resolved "http://124.70.149.18:4873/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943"
+  integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
+  dependencies:
+    utrie "^1.0.2"
+
 text-table@^0.2.0:
   version "0.2.0"
   resolved "http://124.70.149.18:4873/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -8339,6 +8366,13 @@ utils-merge@1.0.1:
   resolved "http://124.70.149.18:4873/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
   integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
 
+utrie@^1.0.2:
+  version "1.0.2"
+  resolved "http://124.70.149.18:4873/utrie/-/utrie-1.0.2.tgz#d42fe44de9bc0119c25de7f564a6ed1b2c87a645"
+  integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
+  dependencies:
+    base64-arraybuffer "^1.0.2"
+
 uuid@^8.3.2:
   version "8.3.2"
   resolved "http://124.70.149.18:4873/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"