Browse Source

feat: 更新代码编辑器部分组件,优化样式,调试其他页面的代码编辑器的使用

yanglzh 1 year ago
parent
commit
a716299c56

+ 1 - 0
package.json

@@ -30,6 +30,7 @@
     "axios": "^0.26.0",
     "clipboard": "^2.0.11",
     "codemirror": "^5.65.9",
+    "codemirror-editor-vue3": "^2.5.8",
     "countup.js": "^2.1.0",
     "cropperjs": "^1.5.12",
     "dayjs": "^1.11.8",

+ 47 - 103
src/components/codeEditor/index.vue

@@ -1,53 +1,19 @@
 <template>
-  <div>
-    <textarea ref="editor"></textarea>
-  </div>
+  <codemirror style="min-height: 200px;max-height: calc(100vh - 300px);background-color: #282A35;" v-model:value="code" :options="options" />
 </template>
 <script setup lang="ts">
-// 引入全局实例
-import _CodeMirror from "codemirror/lib/codemirror.js";
-// 核心样式
+import { reactive, ref, watch } from 'vue';
+import Codemirror from 'codemirror-editor-vue3';
+// 编辑器代码格式
+import 'codemirror/mode/javascript/javascript.js';
+// 自动刷新
+import 'codemirror/addon/display/autorefresh';
+// 主题
+import 'codemirror/theme/dracula.css';
 
-import "codemirror/theme/oceanic-next.css";
-import "codemirror/theme/ayu-mirage.css";
-import "codemirror/theme/abcdef.css";
-import "codemirror/theme/abbott.css";
-import "codemirror/theme/3024-day.css";
-import "codemirror/theme/3024-night.css";
-import "codemirror/lib/codemirror.css";
-import "codemirror/theme/monokai.css";
-import "codemirror/theme/material-ocean.css";
-import "codemirror/addon/fold/foldgutter.css";
-import "codemirror/addon/display/fullscreen.css";
-import "codemirror/addon/dialog/dialog.css";
-import "codemirror/addon/search/matchesonscrollbar.css";
-import "codemirror/addon/scroll/simplescrollbars.css";
-import "codemirror/addon/fold/foldcode.js";
-import "codemirror/addon/edit/closetag.js";
-import "codemirror/addon/fold/foldgutter.js";
-import "codemirror/addon/fold/brace-fold.js";
-import "codemirror/addon/fold/xml-fold.js";
-import "codemirror/addon/fold/indent-fold.js";
-import "codemirror/addon/fold/comment-fold.js";
-import "codemirror/addon/edit/closebrackets.js";
-import "codemirror/addon/fold/xml-fold.js";
-import "codemirror/addon/edit/matchtags.js";
-import "codemirror/addon/display/fullscreen.js";
-import "codemirror/addon/dialog/dialog.js";
-import "codemirror/addon/search/searchcursor.js";
-import "codemirror/addon/search/search.js";
-import "codemirror/addon/scroll/annotatescrollbar.js";
-import "codemirror/addon/search/matchesonscrollbar.js";
-import "codemirror/addon/search/jump-to-line.js";
-import "codemirror/addon/scroll/simplescrollbars.js";
-import "codemirror/mode/htmlmixed/htmlmixed.js";
-import "codemirror/mode/javascript/javascript.js";
-import "codemirror/mode/xml/xml.js";
-import "codemirror/mode/css/css.js";
-import { ref, nextTick } from "vue";
-import "codemirror/mode/javascript/javascript.js";
+const emit = defineEmits(['update:modelValue']);
 
-let props = defineProps({
+const props = defineProps({
   mode: {
     type: String,
     required: false,
@@ -55,7 +21,7 @@ let props = defineProps({
   },
   content: {
     type: String,
-    required: false,
+    required: true,
     default: ''
   },
   readOnly: {
@@ -75,67 +41,45 @@ let props = defineProps({
   }
 })
 
-const editor = ref();
+const code = ref('');
 
-let coder: any;
+const defaultOptions = {
+  autorefresh: true, // 是否自动刷新
+  smartIndent: true, // 自动缩进
+  tabSize: 4, // 缩进单元格为 4 个空格
+  mode: 'application/json', //编辑器的编程语言,比如:'javascript'
+  theme: 'dracula', // 主题,使用主体需要引入相应的 css 文件
+  line: true, // 是否显示行数
+  highlightDifferences: true,
+  autofocus: false,
+  indentUnit: 2,
+  height: 200,
+  readOnly: false, // 只读
+  showCursorWhenSelecting: true,
+  firstLineNumber: 1,
+  matchBrackets: true,//括号匹配
+}
 
-nextTick(() => {
-  coder = _CodeMirror.fromTextArea(editor.value, {
-    mode: props.mode, // 不设置的话,默认使用第一个引用
-    // 缩进格式
-    tabSize: 2,
-    // 显示行号
-    autofocus: true,
-    lineNumbers: true,
-    lineWrapping: true,
-    showCursorWhenSelecting: true,
-    cursorBlinkRate: 530,
-    theme: "ayu-mirage",
-    matchTags: { bothTags: true },
-    foldGutter: true,
-    autoCloseTags: true,
-    autoCloseBrackets: true,
-    scrollbarStyle: "simple",
-    extraKeys: {
-      "Alt-F": "findPersistent",
-    },
-    readOnly: props.readOnly,
-    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "breakpoints"]
-  });
-  coder.setValue(props.content)
-  coder.on('change', props.onchange)
-  coder.setOption('cursorBlinkRate', props.cursorBlinkRate);
-});
+const options = reactive({
+  ...defaultOptions
+})
 
-/**
- * 对外提供赋值
- */
-const setValue = (val: string) => {
-  coder.setValue(val);
-};
+watch(() => props.content, (newVal) => {
+  code.value = newVal;
+}, { immediate: true })
 
-/**
- * 设置模式
- */
-const setMode = (mode: string) => {
-  coder.setOption("mode", mode);
-}
+watch(() => props.mode, (mode) => {
+  options.mode = mode;
+}, { immediate: true })
 
-/**
- * 对外提供取值
- */
-const getValue = () => {
-  return coder.getValue();
-};
+watch(() => props.readOnly, (readOnly) => {
+  options.readOnly = readOnly;
+}, { immediate: true })
 
-const setOption = (name: string, value: any) => {
-  return coder.setOption(name, value)
-}
+const getValue = () => code.value
+const setValue = (val: string) => code.value = val
+const setMode = (mode: string) => options.mode = mode
+const setOption = (name: keyof typeof defaultOptions, value: never) => options[name] = value
 
-defineExpose({
-  setValue,
-  getValue,
-  setMode,
-  setOption,
-})
-</script>
+defineExpose({ getValue, setValue, setMode, setOption })
+</script>

+ 85 - 0
src/components/codeEditor/new.vue

@@ -0,0 +1,85 @@
+<template>
+  <codemirror style="min-height: 200px;max-height: calc(100vh - 300px);background-color: #282A35;" v-model:value="code" :options="options" />
+</template>
+<script setup lang="ts">
+import { reactive, ref, watch } from 'vue';
+import Codemirror from 'codemirror-editor-vue3';
+// 编辑器代码格式
+import 'codemirror/mode/javascript/javascript.js';
+// 自动刷新
+import 'codemirror/addon/display/autorefresh';
+// 主题
+import 'codemirror/theme/dracula.css';
+
+const emit = defineEmits(['update:modelValue']);
+
+const props = defineProps({
+  mode: {
+    type: String,
+    required: false,
+    default: 'htmlmixed'
+  },
+  content: {
+    type: String,
+    required: true,
+    default: ''
+  },
+  readOnly: {
+    type: Boolean,
+    required: false,
+    default: false,
+  },
+  onchange: {
+    type: Object as any,
+    required: false,
+    default: () => { },
+  },
+  cursorBlinkRate: {
+    type: Number,
+    required: false,
+    default: -1,
+  }
+})
+
+const code = ref('');
+
+const defaultOptions = {
+  autorefresh: true, // 是否自动刷新
+  smartIndent: true, // 自动缩进
+  tabSize: 4, // 缩进单元格为 4 个空格
+  mode: 'application/json', //编辑器的编程语言,比如:'javascript'
+  theme: 'dracula', // 主题,使用主体需要引入相应的 css 文件
+  line: true, // 是否显示行数
+  highlightDifferences: true,
+  autofocus: false,
+  indentUnit: 2,
+  height: 200,
+  readOnly: false, // 只读
+  showCursorWhenSelecting: true,
+  firstLineNumber: 1,
+  matchBrackets: true,//括号匹配
+}
+
+const options = reactive({
+  ...defaultOptions
+})
+
+watch(() => props.content, (newVal) => {
+  code.value = newVal;
+}, { immediate: true })
+
+watch(() => props.mode, (mode) => {
+  options.mode = mode;
+}, { immediate: true })
+
+watch(() => props.readOnly, (readOnly) => {
+  options.readOnly = readOnly;
+}, { immediate: true })
+
+const getValue = () => code.value
+const setValue = (val: string) => code.value = val
+const setMode = (mode: string) => options.mode = mode
+const setOption = (name: keyof typeof defaultOptions, value: never) => options[name] = value
+
+defineExpose({ getValue, setValue, setMode, setOption })
+</script>

+ 141 - 0
src/components/codeEditor/old.vue

@@ -0,0 +1,141 @@
+<template>
+  <div>
+    <textarea ref="editor"></textarea>
+  </div>
+</template>
+<script setup lang="ts">
+// 引入全局实例
+import _CodeMirror from "codemirror/lib/codemirror.js";
+// 核心样式
+
+import "codemirror/theme/oceanic-next.css";
+import "codemirror/theme/ayu-mirage.css";
+import "codemirror/theme/abcdef.css";
+import "codemirror/theme/abbott.css";
+import "codemirror/theme/3024-day.css";
+import "codemirror/theme/3024-night.css";
+import "codemirror/lib/codemirror.css";
+import "codemirror/theme/monokai.css";
+import "codemirror/theme/material-ocean.css";
+import "codemirror/addon/fold/foldgutter.css";
+import "codemirror/addon/display/fullscreen.css";
+import "codemirror/addon/dialog/dialog.css";
+import "codemirror/addon/search/matchesonscrollbar.css";
+import "codemirror/addon/scroll/simplescrollbars.css";
+import "codemirror/addon/fold/foldcode.js";
+import "codemirror/addon/edit/closetag.js";
+import "codemirror/addon/fold/foldgutter.js";
+import "codemirror/addon/fold/brace-fold.js";
+import "codemirror/addon/fold/xml-fold.js";
+import "codemirror/addon/fold/indent-fold.js";
+import "codemirror/addon/fold/comment-fold.js";
+import "codemirror/addon/edit/closebrackets.js";
+import "codemirror/addon/fold/xml-fold.js";
+import "codemirror/addon/edit/matchtags.js";
+import "codemirror/addon/display/fullscreen.js";
+import "codemirror/addon/dialog/dialog.js";
+import "codemirror/addon/search/searchcursor.js";
+import "codemirror/addon/search/search.js";
+import "codemirror/addon/scroll/annotatescrollbar.js";
+import "codemirror/addon/search/matchesonscrollbar.js";
+import "codemirror/addon/search/jump-to-line.js";
+import "codemirror/addon/scroll/simplescrollbars.js";
+import "codemirror/mode/htmlmixed/htmlmixed.js";
+import "codemirror/mode/javascript/javascript.js";
+import "codemirror/mode/xml/xml.js";
+import "codemirror/mode/css/css.js";
+import { ref, nextTick } from "vue";
+import "codemirror/mode/javascript/javascript.js";
+
+let props = defineProps({
+  mode: {
+    type: String,
+    required: false,
+    default: 'htmlmixed'
+  },
+  content: {
+    type: String,
+    required: false,
+    default: ''
+  },
+  readOnly: {
+    type: Boolean,
+    required: false,
+    default: false,
+  },
+  onchange: {
+    type: Object as any,
+    required: false,
+    default: () => { },
+  },
+  cursorBlinkRate: {
+    type: Number,
+    required: false,
+    default: -1,
+  }
+})
+
+const editor = ref();
+
+let coder: any;
+
+nextTick(() => {
+  coder = _CodeMirror.fromTextArea(editor.value, {
+    mode: props.mode, // 不设置的话,默认使用第一个引用
+    // 缩进格式
+    tabSize: 2,
+    // 显示行号
+    autofocus: true,
+    lineNumbers: true,
+    lineWrapping: true,
+    showCursorWhenSelecting: true,
+    cursorBlinkRate: 530,
+    theme: "ayu-mirage",
+    matchTags: { bothTags: true },
+    foldGutter: true,
+    autoCloseTags: true,
+    autoCloseBrackets: true,
+    scrollbarStyle: "simple",
+    extraKeys: {
+      "Alt-F": "findPersistent",
+    },
+    readOnly: props.readOnly,
+    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "breakpoints"]
+  });
+  coder.setValue(props.content)
+  coder.on('change', props.onchange)
+  coder.setOption('cursorBlinkRate', props.cursorBlinkRate);
+});
+
+/**
+ * 对外提供赋值
+ */
+const setValue = (val: string) => {
+  coder.setValue(val);
+};
+
+/**
+ * 设置模式
+ */
+const setMode = (mode: string) => {
+  coder.setOption("mode", mode);
+}
+
+/**
+ * 对外提供取值
+ */
+const getValue = () => {
+  return coder.getValue();
+};
+
+const setOption = (name: string, value: any) => {
+  return coder.setOption(name, value)
+}
+
+defineExpose({
+  setValue,
+  getValue,
+  setMode,
+  setOption,
+})
+</script>

+ 2 - 2
src/views/iot/device/product/component/dataParse.vue

@@ -1,6 +1,6 @@
 <template>
-	<div class="flex">
-		<codeEditor class="params flex1" ref="mirrorRef" mode="" :content="content"></codeEditor>
+	<div class="flex" style="align-items: stretch;">
+		<codeEditor class="params flex1" ref="mirrorRef" style="height: calc(100vh - 340px)" mode="application/json" :content="content"></codeEditor>
 		<div class="mock" style="width: 300px;margin-left: 20px;">
 			<el-radio-group v-model="functionName">
 				<el-radio-button label="parse">parse</el-radio-button>

+ 2 - 2
src/views/iot/network/server/create.vue

@@ -253,7 +253,7 @@ export default defineComponent({
       state.messageData = res || [];
     });
 
-    const mirrorRef = ref('mirrorRef')
+    const mirrorRef = ref()
     const activeName = ref('first')
     const getDetail = () => {
       const id = route.params && route.params.id;
@@ -272,7 +272,7 @@ export default defineComponent({
         }
       }
       if (mirrorRef.value.getValue()) {
-        state.form.protocol.options = eval("(" + mirrorRef.value.getValue() + ")")
+        params.protocol.options = eval("(" + mirrorRef.value.getValue() + ")")
       }
       // return
       api.server.addItem(params).then((res: any) => {

+ 2 - 2
src/views/iot/network/server/edit.vue

@@ -252,7 +252,7 @@ export default defineComponent({
       state.messageData = res || [];
     });
 
-    const mirrorRef = ref('mirrorRef')
+    const mirrorRef = ref()
     const activeName = ref('first')
     const getDetail = () => {
       const id = route.params && route.params.id;
@@ -308,7 +308,7 @@ export default defineComponent({
         }
       }
       if (mirrorRef.value.getValue()) {
-        state.form.protocol.options = eval("(" + mirrorRef.value.getValue() + ")")
+        params.protocol.options = eval("(" + mirrorRef.value.getValue() + ")")
       }
       // return
       api.server.editItem(params).then((res: any) => {

+ 1 - 1
src/views/iot/network/tunnel/create.vue

@@ -193,7 +193,7 @@ export default defineComponent({
       state.messageData = res || [];
     });
 
-    const mirrorRef = ref('mirrorRef')
+    const mirrorRef = ref()
     const activeName = ref('first')
 
     const getDetail = () => {

+ 1 - 1
src/views/iot/network/tunnel/edit.vue

@@ -189,7 +189,7 @@ export default defineComponent({
     });
 
     const activeName = ref('first')
-    const mirrorRef = ref('mirrorRef')
+    const mirrorRef = ref()
     const submit = () => {
       // 串口参数-检验位-无
       if (state.form.serial.parity == 0) {

+ 278 - 2
yarn.lock

@@ -197,6 +197,11 @@
   resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.18.11.tgz"
   integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==
 
+"@babel/parser@^7.24.4":
+  version "7.24.7"
+  resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85"
+  integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==
+
 "@babel/runtime-corejs3@^7.11.2":
   version "7.18.9"
   resolved "https://registry.npmmirror.com/@babel/runtime-corejs3/-/runtime-corejs3-7.18.9.tgz"
@@ -486,6 +491,11 @@
     "@intlify/runtime" "9.1.10"
     "@intlify/shared" "9.1.10"
 
+"@jridgewell/sourcemap-codec@^1.4.15":
+  version "1.4.15"
+  resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
+  integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
+
 "@lezer/common@^1.0.0":
   version "1.0.1"
   resolved "https://registry.npmjs.org/@lezer/common/-/common-1.0.1.tgz"
@@ -663,6 +673,28 @@
     "@typescript-eslint/types" "5.33.0"
     eslint-visitor-keys "^3.3.0"
 
+"@unocss/core@0.58.9", "@unocss/core@^0.58.9":
+  version "0.58.9"
+  resolved "https://registry.npmjs.org/@unocss/core/-/core-0.58.9.tgz#a613e9d88160c5b260b1406082a9f73d789b9ea9"
+  integrity sha512-wYpPIPPsOIbIoMIDuH8ihehJk5pAZmyFKXIYO/Kro98GEOFhz6lJoLsy6/PZuitlgp2/TSlubUuWGjHWvp5osw==
+
+"@unocss/rule-utils@0.58.9":
+  version "0.58.9"
+  resolved "https://registry.npmjs.org/@unocss/rule-utils/-/rule-utils-0.58.9.tgz#279fcf162e7a1d10829410aca00f8a3cac5e974f"
+  integrity sha512-45bDa+elmlFLthhJmKr2ltKMAB0yoXnDMQ6Zp5j3OiRB7dDMBkwYRPvHLvIe+34Ey7tDt/kvvDPtWMpPl2quUQ==
+  dependencies:
+    "@unocss/core" "^0.58.9"
+    magic-string "^0.30.8"
+
+"@unocss/transformer-directives@^0.58.8":
+  version "0.58.9"
+  resolved "https://registry.npmjs.org/@unocss/transformer-directives/-/transformer-directives-0.58.9.tgz#ca40556b205f33a04232c353dd3d605cb35ee279"
+  integrity sha512-pLOUsdoY2ugVntJXg0xuGjO9XZ2xCiMxTPRtpZ4TsEzUtdEzMswR06Y8VWvNciTB/Zqxcz9ta8rD0DKePOfSuw==
+  dependencies:
+    "@unocss/core" "0.58.9"
+    "@unocss/rule-utils" "0.58.9"
+    css-tree "^2.3.1"
+
 "@vitejs/plugin-vue@^2.2.4":
   version "2.3.4"
   resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-2.3.4.tgz"
@@ -678,6 +710,17 @@
     estree-walker "^2.0.2"
     source-map "^0.6.1"
 
+"@vue/compiler-core@3.4.27":
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz#e69060f4b61429fe57976aa5872cfa21389e4d91"
+  integrity sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==
+  dependencies:
+    "@babel/parser" "^7.24.4"
+    "@vue/shared" "3.4.27"
+    entities "^4.5.0"
+    estree-walker "^2.0.2"
+    source-map-js "^1.2.0"
+
 "@vue/compiler-dom@3.2.37":
   version "3.2.37"
   resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz"
@@ -686,6 +729,14 @@
     "@vue/compiler-core" "3.2.37"
     "@vue/shared" "3.2.37"
 
+"@vue/compiler-dom@3.4.27":
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz#d51d35f40d00ce235d7afc6ad8b09dfd92b1cc1c"
+  integrity sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==
+  dependencies:
+    "@vue/compiler-core" "3.4.27"
+    "@vue/shared" "3.4.27"
+
 "@vue/compiler-sfc@3.2.37", "@vue/compiler-sfc@^3.2.31":
   version "3.2.37"
   resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz"
@@ -702,6 +753,21 @@
     postcss "^8.1.10"
     source-map "^0.6.1"
 
+"@vue/compiler-sfc@3.4.27":
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz#399cac1b75c6737bf5440dc9cf3c385bb2959701"
+  integrity sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==
+  dependencies:
+    "@babel/parser" "^7.24.4"
+    "@vue/compiler-core" "3.4.27"
+    "@vue/compiler-dom" "3.4.27"
+    "@vue/compiler-ssr" "3.4.27"
+    "@vue/shared" "3.4.27"
+    estree-walker "^2.0.2"
+    magic-string "^0.30.10"
+    postcss "^8.4.38"
+    source-map-js "^1.2.0"
+
 "@vue/compiler-ssr@3.2.37":
   version "3.2.37"
   resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz"
@@ -710,6 +776,14 @@
     "@vue/compiler-dom" "3.2.37"
     "@vue/shared" "3.2.37"
 
+"@vue/compiler-ssr@3.4.27":
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz#2a8ecfef1cf448b09be633901a9c020360472e3d"
+  integrity sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==
+  dependencies:
+    "@vue/compiler-dom" "3.4.27"
+    "@vue/shared" "3.4.27"
+
 "@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.0.0-beta.7", "@vue/devtools-api@^6.1.4":
   version "6.2.1"
   resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz"
@@ -733,6 +807,13 @@
   dependencies:
     "@vue/shared" "3.2.37"
 
+"@vue/reactivity@3.4.27":
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz#6ece72331bf719953f5eaa95ec60b2b8d49e3791"
+  integrity sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==
+  dependencies:
+    "@vue/shared" "3.4.27"
+
 "@vue/runtime-core@3.2.37":
   version "3.2.37"
   resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.37.tgz"
@@ -741,6 +822,14 @@
     "@vue/reactivity" "3.2.37"
     "@vue/shared" "3.2.37"
 
+"@vue/runtime-core@3.4.27":
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz#1b6e1d71e4604ba7442dd25ed22e4a1fc6adbbda"
+  integrity sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==
+  dependencies:
+    "@vue/reactivity" "3.4.27"
+    "@vue/shared" "3.4.27"
+
 "@vue/runtime-dom@3.2.37":
   version "3.2.37"
   resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz"
@@ -750,6 +839,15 @@
     "@vue/shared" "3.2.37"
     csstype "^2.6.8"
 
+"@vue/runtime-dom@3.4.27":
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz#fe8d1ce9bbe8921d5dd0ad5c10df0e04ef7a5ee7"
+  integrity sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==
+  dependencies:
+    "@vue/runtime-core" "3.4.27"
+    "@vue/shared" "3.4.27"
+    csstype "^3.1.3"
+
 "@vue/server-renderer@3.2.37":
   version "3.2.37"
   resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.37.tgz"
@@ -758,11 +856,24 @@
     "@vue/compiler-ssr" "3.2.37"
     "@vue/shared" "3.2.37"
 
+"@vue/server-renderer@3.4.27":
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz#3306176f37e648ba665f97dda3ce705687be63d2"
+  integrity sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==
+  dependencies:
+    "@vue/compiler-ssr" "3.4.27"
+    "@vue/shared" "3.4.27"
+
 "@vue/shared@3.2.37":
   version "3.2.37"
   resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.37.tgz"
   integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==
 
+"@vue/shared@3.4.27":
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz#f05e3cd107d157354bb4ae7a7b5fc9cf73c63b50"
+  integrity sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==
+
 "@vueuse/core@^9.1.0":
   version "9.13.0"
   resolved "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz"
@@ -785,6 +896,21 @@
   dependencies:
     vue-demi "*"
 
+"@wdns/vue-code-block@^2.3.2":
+  version "2.3.2"
+  resolved "https://registry.npmjs.org/@wdns/vue-code-block/-/vue-code-block-2.3.2.tgz#efad7f18749764ad1be2ea63693a1ad19da5f7e2"
+  integrity sha512-wFqSzaB+587XbWjq+L+IYZAZsCILNZVgRZ+FAoPH5n1TQoBpxfJGUsG8GrTHHIgiuz7txL79DqvRj3oy+ziC1g==
+  dependencies:
+    highlight.js "^11.8.0"
+    prismjs "^1.29.0"
+    ua-parser-js "^1.0.35"
+    vue "^3.4.10"
+
+JSV@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57"
+  integrity sha512-ZJ6wx9xaKJ3yFUhq5/sk82PJMuUyLk277I8mQeyDgCTjGdjWJIvPfaU5LIXaMuaN2UO1X3kZH4+lgphublZUHw==
+
 acorn-jsx@^5.3.2:
   version "5.3.2"
   resolved "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
@@ -847,6 +973,13 @@ ansi-styles@^2.2.1:
   resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
   integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==
 
+ansi-styles@^3.2.1:
+  version "3.2.1"
+  resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
+  integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
+  dependencies:
+    color-convert "^1.9.0"
+
 ansi-styles@^4.1.0:
   version "4.3.0"
   resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz"
@@ -1001,6 +1134,15 @@ chalk@^1.1.1:
     strip-ansi "^3.0.0"
     supports-color "^2.0.0"
 
+chalk@^2.4.2:
+  version "2.4.2"
+  resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
+  integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+  dependencies:
+    ansi-styles "^3.2.1"
+    escape-string-regexp "^1.0.5"
+    supports-color "^5.3.0"
+
 chalk@^4.0.0, chalk@^4.1.2:
   version "4.1.2"
   resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz"
@@ -1047,6 +1189,22 @@ cliui@^2.1.0:
     right-align "^0.1.1"
     wordwrap "0.0.2"
 
+codemirror-editor-vue3@^2.5.8:
+  version "2.5.8"
+  resolved "https://registry.npmjs.org/codemirror-editor-vue3/-/codemirror-editor-vue3-2.5.8.tgz#dcb0abd51cf798579b2a151d761489861ce795d7"
+  integrity sha512-X3PQIYHNhBxghnkbWT7Ft+WVzYB8nT/Q9arcKa0NpxeqxZm+GH1wDTNXI4eVyLrMJxQeX3a9DQCnHm8e5+hXnw==
+  dependencies:
+    "@unocss/transformer-directives" "^0.58.8"
+    "@wdns/vue-code-block" "^2.3.2"
+    codemirror "^5"
+    diff-match-patch "^1.0.5"
+    jsonlint-mod "^1.7.6"
+
+codemirror@^5:
+  version "5.65.16"
+  resolved "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz#efc0661be6bf4988a6a1c2fe6893294638cdb334"
+  integrity sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==
+
 codemirror@^5.65.9:
   version "5.65.9"
   resolved "https://registry.npmjs.org/codemirror/-/codemirror-5.65.9.tgz"
@@ -1060,6 +1218,13 @@ codepage@~1.14.0:
     commander "~2.14.1"
     exit-on-epipe "~1.0.1"
 
+color-convert@^1.9.0:
+  version "1.9.3"
+  resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
+  integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+  dependencies:
+    color-name "1.1.3"
+
 color-convert@^2.0.1:
   version "2.0.1"
   resolved "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz"
@@ -1067,6 +1232,11 @@ color-convert@^2.0.1:
   dependencies:
     color-name "~1.1.4"
 
+color-name@1.1.3:
+  version "1.1.3"
+  resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+  integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
+
 color-name@~1.1.4:
   version "1.1.4"
   resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz"
@@ -1126,6 +1296,14 @@ cross-spawn@^7.0.2:
     shebang-command "^2.0.0"
     which "^2.0.1"
 
+css-tree@^2.3.1:
+  version "2.3.1"
+  resolved "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20"
+  integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==
+  dependencies:
+    mdn-data "2.0.30"
+    source-map-js "^1.0.1"
+
 cssesc@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz"
@@ -1141,6 +1319,11 @@ csstype@^3.0.8:
   resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.0.tgz"
   integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==
 
+csstype@^3.1.3:
+  version "3.1.3"
+  resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
+  integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
+
 d3-color@1:
   version "1.4.1"
   resolved "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz"
@@ -1230,6 +1413,11 @@ detect-browser@^5.0.0, detect-browser@^5.1.0:
   resolved "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz"
   integrity sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==
 
+diff-match-patch@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
+  integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==
+
 dir-glob@^3.0.1:
   version "3.0.1"
   resolved "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz"
@@ -1324,6 +1512,11 @@ element-resize-detector@^1.2.1:
   dependencies:
     batch-processor "1.0.0"
 
+entities@^4.5.0:
+  version "4.5.0"
+  resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
+  integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+
 es-abstract@^1.19.0, es-abstract@^1.19.5:
   version "1.20.3"
   resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.3.tgz"
@@ -1495,7 +1688,7 @@ escape-html@^1.0.3:
   resolved "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz"
   integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
 
-escape-string-regexp@^1.0.2:
+escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
   version "1.0.5"
   resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
   integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
@@ -1894,6 +2087,11 @@ has-bigints@^1.0.1, has-bigints@^1.0.2:
   resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz"
   integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
 
+has-flag@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+  integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
+
 has-flag@^4.0.0:
   version "4.0.0"
   resolved "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz"
@@ -1925,6 +2123,11 @@ has@^1.0.3, has@~1.0.3:
   dependencies:
     function-bind "^1.1.1"
 
+highlight.js@^11.8.0:
+  version "11.9.0"
+  resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz#04ab9ee43b52a41a047432c8103e2158a1b8b5b0"
+  integrity sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==
+
 ignore@^5.2.0:
   version "5.2.0"
   resolved "https://registry.npmmirror.com/ignore/-/ignore-5.2.0.tgz"
@@ -2096,7 +2299,7 @@ isexe@^2.0.0:
 
 js-cookie@^3.0.5:
   version "3.0.5"
-  resolved "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc"
+  resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc"
   integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==
 
 js-yaml@^4.1.0:
@@ -2132,6 +2335,15 @@ jsonfile@^6.0.1:
   optionalDependencies:
     graceful-fs "^4.1.6"
 
+jsonlint-mod@^1.7.6:
+  version "1.7.6"
+  resolved "https://registry.npmjs.org/jsonlint-mod/-/jsonlint-mod-1.7.6.tgz#6f1c4c51fdb5c2002489a0665e3e19a316743319"
+  integrity sha512-oGuk6E1ehmIpw0w9ttgb2KsDQQgGXBzZczREW8OfxEm9eCQYL9/LCexSnh++0z3AiYGcXpBgqDSx9AAgzl/Bvg==
+  dependencies:
+    JSV "^4.0.2"
+    chalk "^2.4.2"
+    underscore "^1.9.1"
+
 jsplumb@^2.15.6:
   version "2.15.6"
   resolved "https://registry.npmmirror.com/jsplumb/-/jsplumb-2.15.6.tgz"
@@ -2218,6 +2430,18 @@ magic-string@^0.25.7:
   dependencies:
     sourcemap-codec "^1.4.8"
 
+magic-string@^0.30.10, magic-string@^0.30.8:
+  version "0.30.10"
+  resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e"
+  integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==
+  dependencies:
+    "@jridgewell/sourcemap-codec" "^1.4.15"
+
+mdn-data@2.0.30:
+  version "2.0.30"
+  resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc"
+  integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==
+
 memoize-one@^6.0.0:
   version "6.0.0"
   resolved "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz"
@@ -2268,6 +2492,11 @@ nanoid@^3.3.4:
   resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz"
   integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
 
+nanoid@^3.3.7:
+  version "3.3.7"
+  resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
+  integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
+
 natural-compare@^1.4.0:
   version "1.4.0"
   resolved "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz"
@@ -2435,6 +2664,15 @@ postcss@^8.1.10, postcss@^8.4.13:
     picocolors "^1.0.0"
     source-map-js "^1.0.2"
 
+postcss@^8.4.38:
+  version "8.4.38"
+  resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e"
+  integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==
+  dependencies:
+    nanoid "^3.3.7"
+    picocolors "^1.0.0"
+    source-map-js "^1.2.0"
+
 prelude-ls@^1.2.1:
   version "1.2.1"
   resolved "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz"
@@ -2455,6 +2693,11 @@ printj@~1.1.0:
   resolved "https://registry.npmmirror.com/printj/-/printj-1.1.2.tgz"
   integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
 
+prismjs@^1.29.0:
+  version "1.29.0"
+  resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12"
+  integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==
+
 punycode@^2.1.0:
   version "2.1.1"
   resolved "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz"
@@ -2663,6 +2906,11 @@ sortablejs@^1.14.0:
   resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz"
   integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
 
+source-map-js@^1.0.1, source-map-js@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
+  integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
+
 source-map-support@^0.3.2:
   version "0.3.3"
   resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.3.3.tgz"
@@ -2760,6 +3008,13 @@ supports-color@^2.0.0:
   resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
   integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==
 
+supports-color@^5.3.0:
+  version "5.5.0"
+  resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
+  integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
+  dependencies:
+    has-flag "^3.0.0"
+
 supports-color@^7.1.0:
   version "7.2.0"
   resolved "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz"
@@ -2854,6 +3109,11 @@ typescript@^4.6.2:
   resolved "https://registry.npmmirror.com/typescript/-/typescript-4.7.4.tgz"
   integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
 
+ua-parser-js@^1.0.35:
+  version "1.0.38"
+  resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz#66bb0c4c0e322fe48edfe6d446df6042e62f25e2"
+  integrity sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==
+
 uglify-js@^2.6.2:
   version "2.8.29"
   resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz"
@@ -2879,6 +3139,11 @@ unbox-primitive@^1.0.2:
     has-symbols "^1.0.3"
     which-boxed-primitive "^1.0.2"
 
+underscore@^1.9.1:
+  version "1.13.6"
+  resolved "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441"
+  integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==
+
 universalify@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"
@@ -3045,6 +3310,17 @@ vue@^3.0.0, vue@^3.2.25, vue@^3.2.37:
     "@vue/server-renderer" "3.2.37"
     "@vue/shared" "3.2.37"
 
+vue@^3.4.10:
+  version "3.4.27"
+  resolved "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz#40b7d929d3e53f427f7f5945386234d2854cc2a1"
+  integrity sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==
+  dependencies:
+    "@vue/compiler-dom" "3.4.27"
+    "@vue/compiler-sfc" "3.4.27"
+    "@vue/runtime-dom" "3.4.27"
+    "@vue/server-renderer" "3.4.27"
+    "@vue/shared" "3.4.27"
+
 vuex@^4.0.2:
   version "4.0.2"
   resolved "https://registry.npmmirror.com/vuex/-/vuex-4.0.2.tgz"