소스 검색

feat(core): re-structure and tres custom renderer base

alvarosabu 2 년 전
부모
커밋
aad0953c2d
33개의 변경된 파일371개의 추가작업 그리고 48개의 파일을 삭제
  1. 1 1
      packages/cientos/src/core/usePamCameraMouse/index.ts
  2. 11 2
      packages/tres/src/App.vue
  3. 132 0
      packages/tres/src/components/TresCanvas.ts
  4. 10 1
      packages/tres/src/composables/index.ts
  5. 0 0
      packages/tres/src/composables/useCamera/index.ts
  6. 0 0
      packages/tres/src/composables/useCamera/useCamera.test.ts
  7. 1 1
      packages/tres/src/composables/useCatalogue/index.ts
  8. 0 0
      packages/tres/src/composables/useCatalogue/useCatalogue.test.ts
  9. 1 1
      packages/tres/src/composables/useInstanceCreator/index.ts
  10. 0 0
      packages/tres/src/composables/useInstanceCreator/useInstanceCreator.test.ts
  11. 1 1
      packages/tres/src/composables/useLoader/index.ts
  12. 0 0
      packages/tres/src/composables/useLoader/useLoader.test.ts
  13. 0 0
      packages/tres/src/composables/useRaycaster/index.ts
  14. 0 0
      packages/tres/src/composables/useRaycaster/useRaycaster.test.ts
  15. 0 0
      packages/tres/src/composables/useRenderLoop/index.ts
  16. 1 1
      packages/tres/src/composables/useRenderer/component.ts
  17. 0 0
      packages/tres/src/composables/useRenderer/const.ts
  18. 1 1
      packages/tres/src/composables/useRenderer/index.ts
  19. 1 1
      packages/tres/src/composables/useScene/component.ts
  20. 0 0
      packages/tres/src/composables/useScene/index.ts
  21. 0 0
      packages/tres/src/composables/useScene/useScene.test.ts
  22. 0 0
      packages/tres/src/composables/useTexture/index.ts
  23. 0 0
      packages/tres/src/composables/useTexture/useTexture.test.ts
  24. 0 0
      packages/tres/src/composables/useTres/index.ts
  25. 0 0
      packages/tres/src/composables/useTres/useTres.test.ts
  26. 4 0
      packages/tres/src/core/catalogue.ts
  27. 0 10
      packages/tres/src/core/index.ts
  28. 105 0
      packages/tres/src/core/nodeOps.ts
  29. 11 0
      packages/tres/src/core/renderer.ts
  30. 1 0
      packages/tres/src/iternal/index.ts
  31. 0 0
      packages/tres/src/iternal/useLogger.ts
  32. 1 2
      packages/tres/src/main.ts
  33. 89 26
      pnpm-lock.yaml

+ 1 - 1
packages/cientos/src/core/usePamCameraMouse/index.ts

@@ -1,7 +1,7 @@
 import { watchEffect, computed } from 'vue'
 import { Camera } from 'three'
 import { useWindowSize, useMouse } from '@vueuse/core'
-import { useLogger } from '/@/composables/useLogger'
+import { useLogger } from '@tresjs/core/src/iternal/useLogger'
 
 export function usePamCameraMouse(disabled = false, factor = 5, camera: Camera | undefined) {
   const { x, y } = useMouse()

+ 11 - 2
packages/tres/src/App.vue

@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { useTweakPane } from '@tresjs/cientos'
-import Shapes from '/@/components/Shapes.vue'
+import TresCanvas from './components/TresCanvas'
 // import TheEvents from '/@/components/TheEvents.vue'
 
 useTweakPane()
@@ -8,7 +8,16 @@ useTweakPane()
 
 <template>
   <Suspense>
-    <Shapes />
+    <TresCanvas>
+      <TresPerspectiveCamera :args="[45, 1, 0.1, 1000]" />
+      <TresAmbientLight />
+      <TresDirectionalLight :intensity="1" color="yellow" :position="[-2, 0, 3]" />
+      <TresGridHelper :args="[4, 4]"></TresGridHelper>
+      <TresMesh>
+        <TresSphereGeometry :args="[2, 32, 16]" />
+        <TresMeshToonMaterial color="teal" />
+      </TresMesh>
+    </TresCanvas>
   </Suspense>
 </template>
 

+ 132 - 0
packages/tres/src/components/TresCanvas.ts

@@ -0,0 +1,132 @@
+import { defineComponent, h, onUnmounted, PropType, ref, watchEffect } from 'vue'
+/* eslint-disable vue/one-component-per-file */
+import * as THREE from 'three'
+import { ShadowMapType, TextureEncoding, ToneMapping } from 'three'
+/* import { OrbitControls } from '@tresjs/cientos' */
+import { extend, createTres } from '/@/core/renderer'
+
+export const TresCanvas = defineComponent({
+  name: 'TresCanvas',
+  props: {
+    shadows: Boolean,
+    shadowMapType: Number as PropType<ShadowMapType>,
+    physicallyCorrectLights: {
+      type: Boolean,
+      default: false,
+      validator: (value: boolean) => {
+        if (value) {
+          console.warn('physicallyCorrectLights is deprecated. Use useLegacyLights instead.')
+        }
+        return true
+      },
+    },
+    useLegacyLights: Boolean,
+    outputEncoding: Number as PropType<TextureEncoding>,
+    toneMapping: Number as PropType<ToneMapping>,
+    toneMappingExposure: Number,
+    context: Object as PropType<WebGLRenderingContext>,
+    powerPreference: String as PropType<'high-performance' | 'low-power' | 'default'>,
+    preserveDrawingBuffer: Boolean,
+    clearColor: String,
+    windowSize: { type: Boolean, default: false },
+  },
+  setup(props, { slots, attrs }) {
+    const container = ref<HTMLElement>()
+    const canvas = ref<HTMLCanvasElement>()
+
+    watchEffect(() => {
+      const renderer = new THREE.WebGLRenderer({
+        canvas: canvas.value,
+        antialias: true,
+        alpha: true,
+        powerPreference: 'high-performance',
+      })
+      renderer.outputEncoding = THREE.sRGBEncoding
+      renderer.toneMapping = THREE.ACESFilmicToneMapping
+      renderer.setSize(window.innerWidth, window.innerHeight)
+
+      const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight)
+      camera.position.set(0, 2, 7)
+
+      /* const controls = new OrbitControls(camera, renderer.domElement)
+      controls.enableDamping = true */
+
+      const scene = new THREE.Scene()
+
+      window.addEventListener('resize', () => {
+        renderer.setSize(window.innerWidth, window.innerHeight)
+        camera.aspect = window.innerWidth / window.innerHeight
+        camera.updateProjectionMatrix()
+      })
+
+      renderer.setAnimationLoop(() => {
+        /* controls.update() */
+        renderer.render(scene, camera)
+      })
+
+      const internal = slots?.default() || []
+
+      const internalComponent = defineComponent({
+        name: 'Wrapper',
+        setup() {
+          return () => internal
+        },
+      })
+
+      const app = createTres(internalComponent)
+      app.mount(scene)
+
+      console.log(app)
+
+      onUnmounted(() => {
+        app.unmount()
+      })
+    })
+
+    return () => {
+      return h(
+        h(
+          'div',
+          {
+            ref: container,
+            style: {
+              position: 'relative',
+              width: '100%',
+              height: '100%',
+
+              pointerEvents: 'auto',
+              touchAction: 'none',
+              ...(attrs.style as Record<string, unknown>),
+            },
+          },
+          [
+            h(
+              'div',
+              {
+                style: {
+                  width: '100%',
+                  height: '100%',
+                },
+              },
+              [
+                h('canvas', {
+                  ref: canvas,
+                  style: {
+                    display: 'block',
+                    width: '100%',
+                    height: '100%',
+                    position: props.windowSize ? 'fixed' : 'absolute',
+                    top: 0,
+                    left: 0,
+                  },
+                }),
+              ],
+            ),
+          ],
+        ),
+      )
+    }
+  },
+})
+
+export default TresCanvas

+ 10 - 1
packages/tres/src/composables/index.ts

@@ -1 +1,10 @@
-export * from './useLogger'
+export * from './useCamera'
+export * from './useCatalogue'
+export * from './useInstanceCreator'
+export * from './useRenderLoop/'
+export * from './useRenderer/'
+export * from './useScene/'
+export * from './useLoader'
+export * from './useTexture'
+export * from './useTres'
+export * from './useRaycaster'

+ 0 - 0
packages/tres/src/core/useCamera/index.ts → packages/tres/src/composables/useCamera/index.ts


+ 0 - 0
packages/tres/src/core/useCamera/useCamera.test.ts → packages/tres/src/composables/useCamera/useCamera.test.ts


+ 1 - 1
packages/tres/src/core/useCatalogue/index.ts → packages/tres/src/composables/useCatalogue/index.ts

@@ -1,7 +1,7 @@
 import { App, ref, Component, Ref } from 'vue'
 import * as THREE from 'three'
 import { useInstanceCreator } from '/@/core'
-import { useLogger } from '/@/composables'
+import { useLogger } from '../../iternal'
 import { TresCatalogue } from '/@/types'
 
 const catalogue: Ref<TresCatalogue> = ref({ ...THREE, uuid: THREE.MathUtils.generateUUID() })

+ 0 - 0
packages/tres/src/core/useCatalogue/useCatalogue.test.ts → packages/tres/src/composables/useCatalogue/useCatalogue.test.ts


+ 1 - 1
packages/tres/src/core/useInstanceCreator/index.ts → packages/tres/src/composables/useInstanceCreator/index.ts

@@ -7,7 +7,7 @@ import { useEventListener } from '@vueuse/core'
 import { isArray, isDefined, isFunction } from '@alvarosabu/utils'
 import { normalizeVectorFlexibleParam } from '/@/utils/normalize'
 import { useCamera, useCatalogue, useRenderLoop, useTres } from '/@/core/'
-import { useLogger } from '/@/composables'
+import { useLogger } from '../../iternal'
 import { TresAttributes, TresCatalogue, TresInstance, TresVNode, TresVNodeType, TresEvent } from '/@/types'
 
 const VECTOR3_PROPS = ['rotation', 'scale', 'position']

+ 0 - 0
packages/tres/src/core/useInstanceCreator/useInstanceCreator.test.ts → packages/tres/src/composables/useInstanceCreator/useInstanceCreator.test.ts


+ 1 - 1
packages/tres/src/core/useLoader/index.ts → packages/tres/src/composables/useLoader/index.ts

@@ -1,6 +1,6 @@
 import { isArray } from '@alvarosabu/utils'
 import { Object3D } from 'three'
-import { useLogger } from '/@/composables'
+import { useLogger } from '../../iternal'
 
 export interface TresLoader<T> extends THREE.Loader {
   load(

+ 0 - 0
packages/tres/src/core/useLoader/useLoader.test.ts → packages/tres/src/composables/useLoader/useLoader.test.ts


+ 0 - 0
packages/tres/src/core/useRaycaster/index.ts → packages/tres/src/composables/useRaycaster/index.ts


+ 0 - 0
packages/tres/src/core/useRaycaster/useRaycaster.test.ts → packages/tres/src/composables/useRaycaster/useRaycaster.test.ts


+ 0 - 0
packages/tres/src/core/useRenderLoop/index.ts → packages/tres/src/composables/useRenderLoop/index.ts


+ 1 - 1
packages/tres/src/core/useRenderer/component.ts → packages/tres/src/composables/useRenderer/component.ts

@@ -2,7 +2,7 @@ import { RendererPresetsType } from './const'
 import { ShadowMapType, TextureEncoding, ToneMapping } from 'three'
 import { h, defineComponent, ref, provide, onBeforeUnmount, PropType } from 'vue'
 import { useRenderer } from '.'
-import { useLogger } from '/@/composables'
+import { useLogger } from '../../iternal'
 import { TresVNodeType } from '/@/types'
 
 /**

+ 0 - 0
packages/tres/src/core/useRenderer/const.ts → packages/tres/src/composables/useRenderer/const.ts


+ 1 - 1
packages/tres/src/core/useRenderer/index.ts → packages/tres/src/composables/useRenderer/index.ts

@@ -24,7 +24,7 @@ import { normalizeColor } from '/@/utils/normalize'
 import { TresColor } from '/@/types'
 import { rendererPresets, RendererPresetsType } from './const'
 import { merge } from '/@/utils'
-import { useLogger } from '/@/composables'
+import { useLogger } from '../../iternal'
 
 export interface UseRendererOptions extends WebGLRendererParameters {
   /**

+ 1 - 1
packages/tres/src/core/useScene/component.ts → packages/tres/src/composables/useScene/component.ts

@@ -1,6 +1,6 @@
 import { defineComponent, inject, provide, Ref } from 'vue'
 import type { Renderer } from 'three'
-import { useCamera, useTres, useRenderLoop, useScene, useRaycaster } from '/@/core/'
+import { useCamera, useTres, useRenderLoop, useScene, useRaycaster } from '..'
 
 /**
  * Vue component for rendering a Tres component.

+ 0 - 0
packages/tres/src/core/useScene/index.ts → packages/tres/src/composables/useScene/index.ts


+ 0 - 0
packages/tres/src/core/useScene/useScene.test.ts → packages/tres/src/composables/useScene/useScene.test.ts


+ 0 - 0
packages/tres/src/core/useTexture/index.ts → packages/tres/src/composables/useTexture/index.ts


+ 0 - 0
packages/tres/src/core/useTexture/useTexture.test.ts → packages/tres/src/composables/useTexture/useTexture.test.ts


+ 0 - 0
packages/tres/src/core/useTres/index.ts → packages/tres/src/composables/useTres/index.ts


+ 0 - 0
packages/tres/src/core/useTres/useTres.test.ts → packages/tres/src/composables/useTres/useTres.test.ts


+ 4 - 0
packages/tres/src/core/catalogue.ts

@@ -0,0 +1,4 @@
+export const catalogue = {}
+export const extend = objects => void Object.assign(catalogue, objects)
+
+export default { catalogue, extend }

+ 0 - 10
packages/tres/src/core/index.ts

@@ -1,10 +0,0 @@
-export * from './useCamera'
-export * from './useCatalogue'
-export * from './useInstanceCreator'
-export * from './useRenderLoop/'
-export * from './useRenderer/'
-export * from './useScene/'
-export * from './useLoader'
-export * from './useTexture'
-export * from './useTres'
-export * from './useRaycaster'

+ 105 - 0
packages/tres/src/core/nodeOps.ts

@@ -0,0 +1,105 @@
+import { useCamera } from '@tresjs/core'
+import { RendererOptions } from 'vue'
+import { catalogue } from './catalogue'
+
+export const nodeOps: RendererOptions<Node, Element> = {
+  createElement(type, _isSVG, _isCustomizedBuiltIn, props) {
+    if (type === 'template') return null
+    let instance
+
+    if (props === null) {
+      props = {}
+    }
+
+    if (props.arg) {
+      instance = new catalogue[type.replace('Tres', '')](...props.args)
+    } else {
+      instance = new catalogue[type.replace('Tres', '')]()
+    }
+
+    if (instance.isCamera) {
+      const { pushCamera } = useCamera()
+      pushCamera(instance)
+    }
+
+    if (props.attach === undefined) {
+      if (instance.isMaterial) instance.attach = 'material'
+      else if (instance.isBufferGeometry) instance.attach = 'geometry'
+    }
+
+    console.log({
+      type,
+      instance,
+      threeObj: catalogue[type.replace('Tres', '')],
+    })
+
+    return instance
+  },
+  insert(child, parent, beforeChild) {
+    if (parent?.isObject3D && child?.isObject3D) {
+      const index = beforeChild ? parent.children.indexOf(beforeChild) : 0
+      child.parent = parent
+      parent.children.splice(index, 0, child)
+      child.dispatchEvent({ type: 'added' })
+    } else if (typeof child?.attach === 'string') {
+      child.__previousAttach = child[parent.attach]
+      parent[child.attach] = child
+    }
+  },
+  remove(node) {
+    const parent = node.parent
+    if (parent) {
+      if (parent.isObject3D && node.isObject3D) {
+        parent.remove(node)
+      } else if (typeof child.attach === 'string') {
+        parent[child.attach] = child.__previousAttach
+        delete child.__previousAttach
+        node.parent = null
+      }
+    }
+
+    node.dispose?.()
+    node.traverse?.(node => node.dispose?.())
+  },
+  patchProp(node, prop, prevValue, nextValue) {
+    let root = node
+    let key = prop
+    let target = root[key]
+
+    // Traverse pierced props (e.g. foo-bar=value => foo.bar = value)
+    if (key.includes('-')) {
+      const chain = key.split('-')
+      target = chain.reduce((acc, key) => acc[key], root)
+      key = chain.pop()
+
+      if (!target?.set) root = chain.reduce((acc, key) => acc[key], root)
+    }
+
+    let value = nextValue
+    try {
+      const num = parseFloat(value)
+      value = isNaN(num) ? JSON.parse(value) : num
+    } catch (_) {}
+
+    // Set prop, prefer atomic methods if applicable
+    if (!target?.set) root[key] = value
+    else if (target.constructor === value.constructor) target.copy(value)
+    else if (Array.isArray(value)) target.set(...value)
+    else if (!target.isColor && target.setScalar) target.setScalar(value)
+    else target.set(value)
+  },
+  createText(text) {},
+  createComment(text) {},
+  setText(node, text) {},
+  setElementText(node, text) {},
+  parentNode(node) {
+    return node?.parent || null
+  },
+  nextSibling(node) {
+    if (node?.parent?.children) {
+      const index = node.parent.children.indexOf(node)
+      if (index !== -1) return node.parent.children[index + 1]
+    }
+    return null
+  },
+}

+ 11 - 0
packages/tres/src/core/renderer.ts

@@ -0,0 +1,11 @@
+import * as THREE from 'three'
+
+import { createRenderer } from 'vue'
+import { extend } from './catalogue'
+import { nodeOps } from './nodeOps'
+
+export const { createApp: createTres } = createRenderer(nodeOps)
+
+extend(THREE)
+
+export default { createTres, extend }

+ 1 - 0
packages/tres/src/iternal/index.ts

@@ -0,0 +1 @@
+export * from './useLogger'

+ 0 - 0
packages/tres/src/composables/useLogger.ts → packages/tres/src/iternal/useLogger.ts


+ 1 - 2
packages/tres/src/main.ts

@@ -1,9 +1,8 @@
 import { createApp } from 'vue'
 import App from './App.vue'
-import plugin from '.'
+
 import './style.css'
 
 export const app = createApp(App)
 
-app.use(plugin)
 app.mount('#app')

+ 89 - 26
pnpm-lock.yaml

@@ -76,6 +76,23 @@ importers:
       vite-plugin-banner: 0.7.0
       vite-plugin-dts: 2.0.0-beta.1_vite@4.1.4
 
+  packages/renderer:
+    specifiers:
+      '@vitejs/plugin-vue': ^4.0.0
+      three: ^0.150.1
+      typescript: ^4.9.3
+      vite: ^4.1.0
+      vue: ^3.2.45
+      vue-tsc: ^1.0.24
+    dependencies:
+      three: 0.150.1
+      vue: 3.2.47
+    devDependencies:
+      '@vitejs/plugin-vue': 4.0.0_vite@4.1.4+vue@3.2.47
+      typescript: 4.9.5
+      vite: 4.1.4
+      vue-tsc: 1.2.0_typescript@4.9.5
+
   packages/tres:
     specifiers:
       '@alvarosabu/utils': ^2.3.0
@@ -321,12 +338,10 @@ packages:
   /@babel/helper-string-parser/7.19.4:
     resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==}
     engines: {node: '>=6.9.0'}
-    dev: true
 
   /@babel/helper-validator-identifier/7.19.1:
     resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
     engines: {node: '>=6.9.0'}
-    dev: true
 
   /@babel/highlight/7.18.6:
     resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
@@ -343,7 +358,6 @@ packages:
     hasBin: true
     dependencies:
       '@babel/types': 7.21.0
-    dev: true
 
   /@babel/runtime/7.21.0:
     resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==}
@@ -385,7 +399,6 @@ packages:
       '@babel/helper-string-parser': 7.19.4
       '@babel/helper-validator-identifier': 7.19.1
       to-fast-properties: 2.0.0
-    dev: true
 
   /@bcoe/v8-coverage/0.2.3:
     resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
@@ -1564,6 +1577,45 @@ packages:
       pretty-format: 27.5.1
     dev: true
 
+  /@volar/language-core/1.3.0-alpha.0:
+    resolution: {integrity: sha512-W3uMzecHPcbwddPu4SJpUcPakRBK/y/BP+U0U6NiPpUX1tONLC4yCawt+QBJqtgJ+sfD6ztf5PyvPL3hQRqfOA==}
+    dependencies:
+      '@volar/source-map': 1.3.0-alpha.0
+    dev: true
+
+  /@volar/source-map/1.3.0-alpha.0:
+    resolution: {integrity: sha512-jSdizxWFvDTvkPYZnO6ew3sBZUnS0abKCbuopkc0JrIlFbznWC/fPH3iPFIMS8/IIkRxq1Jh9VVG60SmtsdaMQ==}
+    dependencies:
+      muggle-string: 0.2.2
+    dev: true
+
+  /@volar/typescript/1.3.0-alpha.0:
+    resolution: {integrity: sha512-5UItyW2cdH2mBLu4RrECRNJRgtvvzKrSCn2y3v/D61QwIDkGx4aeil6x8RFuUL5TFtV6QvVHXnsOHxNgd+sCow==}
+    dependencies:
+      '@volar/language-core': 1.3.0-alpha.0
+    dev: true
+
+  /@volar/vue-language-core/1.2.0:
+    resolution: {integrity: sha512-w7yEiaITh2WzKe6u8ZdeLKCUz43wdmY/OqAmsB/PGDvvhTcVhCJ6f0W/RprZL1IhqH8wALoWiwEh/Wer7ZviMQ==}
+    dependencies:
+      '@volar/language-core': 1.3.0-alpha.0
+      '@volar/source-map': 1.3.0-alpha.0
+      '@vue/compiler-dom': 3.2.47
+      '@vue/compiler-sfc': 3.2.47
+      '@vue/reactivity': 3.2.47
+      '@vue/shared': 3.2.47
+      minimatch: 6.2.0
+      muggle-string: 0.2.2
+      vue-template-compiler: 2.7.14
+    dev: true
+
+  /@volar/vue-typescript/1.2.0:
+    resolution: {integrity: sha512-zjmRi9y3J1EkG+pfuHp8IbHmibihrKK485cfzsHjiuvJMGrpkWvlO5WVEk8oslMxxeGC5XwBFE9AOlvh378EPA==}
+    dependencies:
+      '@volar/typescript': 1.3.0-alpha.0
+      '@volar/vue-language-core': 1.2.0
+    dev: true
+
   /@vue/compiler-core/3.2.47:
     resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==}
     dependencies:
@@ -1571,14 +1623,12 @@ packages:
       '@vue/shared': 3.2.47
       estree-walker: 2.0.2
       source-map: 0.6.1
-    dev: true
 
   /@vue/compiler-dom/3.2.47:
     resolution: {integrity: sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==}
     dependencies:
       '@vue/compiler-core': 3.2.47
       '@vue/shared': 3.2.47
-    dev: true
 
   /@vue/compiler-sfc/3.2.47:
     resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==}
@@ -1593,14 +1643,12 @@ packages:
       magic-string: 0.25.9
       postcss: 8.4.21
       source-map: 0.6.1
-    dev: true
 
   /@vue/compiler-ssr/3.2.47:
     resolution: {integrity: sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==}
     dependencies:
       '@vue/compiler-dom': 3.2.47
       '@vue/shared': 3.2.47
-    dev: true
 
   /@vue/devtools-api/6.5.0:
     resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==}
@@ -1614,20 +1662,17 @@ packages:
       '@vue/shared': 3.2.47
       estree-walker: 2.0.2
       magic-string: 0.25.9
-    dev: true
 
   /@vue/reactivity/3.2.47:
     resolution: {integrity: sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==}
     dependencies:
       '@vue/shared': 3.2.47
-    dev: true
 
   /@vue/runtime-core/3.2.47:
     resolution: {integrity: sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==}
     dependencies:
       '@vue/reactivity': 3.2.47
       '@vue/shared': 3.2.47
-    dev: true
 
   /@vue/runtime-dom/3.2.47:
     resolution: {integrity: sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==}
@@ -1635,7 +1680,6 @@ packages:
       '@vue/runtime-core': 3.2.47
       '@vue/shared': 3.2.47
       csstype: 2.6.21
-    dev: true
 
   /@vue/server-renderer/3.2.47:
     resolution: {integrity: sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==}
@@ -1655,11 +1699,9 @@ packages:
       '@vue/compiler-ssr': 3.2.47
       '@vue/shared': 3.2.47
       vue: 3.2.47
-    dev: true
 
   /@vue/shared/3.2.47:
     resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==}
-    dev: true
 
   /@vue/test-utils/2.3.0:
     resolution: {integrity: sha512-S8/9Z+B4VSsTUNtZtzS7J1TfxJbf10n+gcH9X8cASbG0Tp7qD6vqs/sUNlmpzk6i7+pP00ptauJp9rygyW89Ww==}
@@ -2443,7 +2485,6 @@ packages:
 
   /csstype/2.6.21:
     resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==}
-    dev: true
 
   /csv-generate/3.4.3:
     resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==}
@@ -2489,6 +2530,10 @@ packages:
     resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==}
     dev: true
 
+  /de-indent/1.0.2:
+    resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+    dev: true
+
   /debug/4.3.4:
     resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
     engines: {node: '>=6.0'}
@@ -2952,7 +2997,6 @@ packages:
 
   /estree-walker/2.0.2:
     resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
-    dev: true
 
   /esutils/2.0.3:
     resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
@@ -4024,7 +4068,6 @@ packages:
     resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
     dependencies:
       sourcemap-codec: 1.4.8
-    dev: true
 
   /magic-string/0.27.0:
     resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
@@ -4151,6 +4194,13 @@ packages:
       brace-expansion: 2.0.1
     dev: true
 
+  /minimatch/6.2.0:
+    resolution: {integrity: sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==}
+    engines: {node: '>=10'}
+    dependencies:
+      brace-expansion: 2.0.1
+    dev: true
+
   /minimist-options/4.1.0:
     resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==}
     engines: {node: '>= 6'}
@@ -4202,11 +4252,14 @@ packages:
     resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
     dev: true
 
+  /muggle-string/0.2.2:
+    resolution: {integrity: sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==}
+    dev: true
+
   /nanoid/3.3.4:
     resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
     hasBin: true
-    dev: true
 
   /natural-compare-lite/1.4.0:
     resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
@@ -4533,7 +4586,6 @@ packages:
 
   /picocolors/1.0.0:
     resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
-    dev: true
 
   /picomatch/2.3.1:
     resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
@@ -4585,7 +4637,6 @@ packages:
       nanoid: 3.3.4
       picocolors: 1.0.0
       source-map-js: 1.0.2
-    dev: true
 
   /potpack/1.0.2:
     resolution: {integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==}
@@ -5001,7 +5052,6 @@ packages:
   /source-map-js/1.0.2:
     resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
     engines: {node: '>=0.10.0'}
-    dev: true
 
   /source-map-support/0.5.21:
     resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
@@ -5013,7 +5063,6 @@ packages:
   /source-map/0.6.1:
     resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
     engines: {node: '>=0.10.0'}
-    dev: true
 
   /source-map/0.7.4:
     resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
@@ -5023,7 +5072,6 @@ packages:
   /sourcemap-codec/1.4.8:
     resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
     deprecated: Please use @jridgewell/sourcemap-codec instead
-    dev: true
 
   /spawndamnit/2.0.0:
     resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==}
@@ -5278,7 +5326,6 @@ packages:
 
   /three/0.150.1:
     resolution: {integrity: sha512-5C1MqKUWaHYo13BX0Q64qcdwImgnnjSOFgBscOzAo8MYCzEtqfQqorEKMcajnA3FHy1yVlIe9AmaMQ0OQracNA==}
-    dev: true
 
   /through/2.3.8:
     resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
@@ -5325,7 +5372,6 @@ packages:
   /to-fast-properties/2.0.0:
     resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
     engines: {node: '>=4'}
-    dev: true
 
   /to-regex-range/5.0.1:
     resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
@@ -5902,6 +5948,24 @@ packages:
       - supports-color
     dev: true
 
+  /vue-template-compiler/2.7.14:
+    resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==}
+    dependencies:
+      de-indent: 1.0.2
+      he: 1.2.0
+    dev: true
+
+  /vue-tsc/1.2.0_typescript@4.9.5:
+    resolution: {integrity: sha512-rIlzqdrhyPYyLG9zxsVRa+JEseeS9s8F2BbVVVWRRsTZvJO2BbhLEb2HW3MY+DFma0378tnIqs+vfTzbcQtRFw==}
+    hasBin: true
+    peerDependencies:
+      typescript: '*'
+    dependencies:
+      '@volar/vue-language-core': 1.2.0
+      '@volar/vue-typescript': 1.2.0
+      typescript: 4.9.5
+    dev: true
+
   /vue/3.2.47:
     resolution: {integrity: sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==}
     dependencies:
@@ -5910,7 +5974,6 @@ packages:
       '@vue/runtime-dom': 3.2.47
       '@vue/server-renderer': 3.2.47_vue@3.2.47
       '@vue/shared': 3.2.47
-    dev: true
 
   /w3c-xmlserializer/4.0.0:
     resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==}