├── .env ├── .npmrc ├── docs └── video.png ├── .vscode └── extensions.json ├── src ├── composables │ ├── index.ts │ ├── dark.ts │ ├── global.ts │ ├── actions.ts │ └── detect.ts ├── styles │ └── main.css ├── utils │ ├── gpu.ts │ ├── labels.json │ └── renderBox.ts ├── components │ ├── FullScreenBtn.vue │ ├── Hello.vue │ ├── Tabs │ │ ├── TabsWebRTC.vue │ │ ├── TabsPicture.vue │ │ ├── TabsVideo.vue │ │ └── TabsWebCam.vue │ └── VideoRtc.vue ├── App.vue ├── main.ts └── pages │ └── index.vue ├── .env.development ├── public ├── yolov8n_web_model │ ├── group1-shard1of4.bin │ ├── group1-shard2of4.bin │ ├── group1-shard3of4.bin │ ├── group1-shard4of4.bin │ └── metadata.yaml └── vite.svg ├── shims.d.ts ├── .editorconfig ├── netlify.toml ├── .gitignore ├── eslint.config.js ├── tsconfig.json ├── index.html ├── components.d.ts ├── unocss.config.ts ├── LICENSE ├── package.json ├── README.md ├── vite.config.ts └── auto-imports.d.ts /.env: -------------------------------------------------------------------------------- 1 | # open url 2 | VITE_HOST=0.0.0.0 3 | VITE_PORT=3333 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | -------------------------------------------------------------------------------- /docs/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanseria/yolov8-tfjs-vue-webrtc-demo/HEAD/docs/video.png -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /src/composables/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dark' 2 | export * from './global' 3 | export * from './actions' 4 | -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | NODE_ENV=development 2 | # proxy url 3 | VITE_PROXY_URL= 4 | # open url 5 | VITE_HOST=0.0.0.0 6 | VITE_PORT=3333 7 | -------------------------------------------------------------------------------- /public/yolov8n_web_model/group1-shard1of4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanseria/yolov8-tfjs-vue-webrtc-demo/HEAD/public/yolov8n_web_model/group1-shard1of4.bin -------------------------------------------------------------------------------- /public/yolov8n_web_model/group1-shard2of4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanseria/yolov8-tfjs-vue-webrtc-demo/HEAD/public/yolov8n_web_model/group1-shard2of4.bin -------------------------------------------------------------------------------- /public/yolov8n_web_model/group1-shard3of4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanseria/yolov8-tfjs-vue-webrtc-demo/HEAD/public/yolov8n_web_model/group1-shard3of4.bin -------------------------------------------------------------------------------- /public/yolov8n_web_model/group1-shard4of4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanseria/yolov8-tfjs-vue-webrtc-demo/HEAD/public/yolov8n_web_model/group1-shard4of4.bin -------------------------------------------------------------------------------- /shims.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { DefineComponent } from 'vue' 3 | const component: DefineComponent<{}, {}, any> 4 | export default component 5 | } 6 | -------------------------------------------------------------------------------- /src/styles/main.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | #app { 4 | height: 100%; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | html.dark { 10 | background: #121212; 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /src/utils/gpu.ts: -------------------------------------------------------------------------------- 1 | export function isWebGPUSupported(): boolean { 2 | return ((typeof window !== 'undefined') || 3 | //@ts-ignore 4 | (typeof WorkerGlobalScope !== 'undefined')) && 5 | !!navigator.gpu; 6 | } 7 | -------------------------------------------------------------------------------- /src/components/FullScreenBtn.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build.environment] 2 | NODE_VERSION = "18" 3 | 4 | [build] 5 | publish = "dist" 6 | command = "pnpm run build" 7 | 8 | [[redirects]] 9 | from = "/*" 10 | to = "/index.html" 11 | status = 200 12 | 13 | [[headers]] 14 | for = "/manifest.webmanifest" 15 | [headers.values] 16 | Content-Type = "application/manifest+json" 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | // eslint.config.js 2 | import antfu from '@antfu/eslint-config' 3 | 4 | export default antfu({ 5 | unocss: true, 6 | formatters: { 7 | css: true, // by default use Prettier 8 | html: true, // by default use Prettier 9 | toml: 'dprint', // use dprint for TOML 10 | markdown: 'prettier', // use prettier for markdown 11 | }, 12 | ignores: [ 13 | 'node_modules/', 14 | 'public/', 15 | 'dist/', 16 | ], 17 | }) 18 | -------------------------------------------------------------------------------- /src/components/Hello.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | -------------------------------------------------------------------------------- /src/composables/dark.ts: -------------------------------------------------------------------------------- 1 | export const isDark = useDark({ 2 | onChanged(dark: boolean) { 3 | if (dark) { 4 | // 设置为暗黑主题 5 | document.documentElement.classList.remove('light') 6 | document.documentElement.classList.add('dark') 7 | document.body.setAttribute('arco-theme', 'dark') 8 | } 9 | else { 10 | // 恢复亮色主题 11 | document.documentElement.classList.remove('dark') 12 | document.documentElement.classList.add('light') 13 | document.body.removeAttribute('arco-theme') 14 | } 15 | }, 16 | }) 17 | export const toggleDark = useToggle(isDark) 18 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import { createRouter, createWebHistory } from 'vue-router' 3 | import routes from 'virtual:generated-pages' 4 | import ArcoVue from '@arco-design/web-vue' 5 | import ArcoVueIcon from '@arco-design/web-vue/es/icon' 6 | import App from './App.vue' 7 | 8 | import '@arco-design/web-vue/dist/arco.css' 9 | import '@unocss/reset/tailwind.css' 10 | import './styles/main.css' 11 | import 'uno.css' 12 | 13 | const app = createApp(App) 14 | const router = createRouter({ 15 | history: createWebHistory(import.meta.env.BASE_URL), 16 | routes, 17 | }) 18 | app.use(ArcoVue, {}) 19 | app.use(ArcoVueIcon) 20 | app.use(router) 21 | app.mount('#app') 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "module": "ESNext", 5 | "target": "es2016", 6 | "lib": ["DOM", "ESNext"], 7 | "strict": true, 8 | "jsx": "preserve", 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "moduleResolution": "node", 12 | "resolveJsonModule": true, 13 | "noUnusedLocals": true, 14 | "strictNullChecks": true, 15 | "allowJs": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "types": [ 18 | "vite/client", 19 | "vite-plugin-pages/client" 20 | ], 21 | "paths": { 22 | "~/*": ["src/*"] 23 | } 24 | }, 25 | "exclude": ["dist", "node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /src/composables/global.ts: -------------------------------------------------------------------------------- 1 | import type { GraphModel, io } from '@tensorflow/tfjs' 2 | // import { isWebGPUSupported } from '~/utils/gpu'; 3 | // import '@tensorflow/tfjs-backend-webgpu'; 4 | import '@tensorflow/tfjs-backend-webgl'; 5 | 6 | export * as tf from '@tensorflow/tfjs' 7 | 8 | export const model: { 9 | net: GraphModel | null 10 | } = { 11 | net: null, 12 | } 13 | export const inputShape = ref([1, 0, 0, 3]) 14 | // model configs 15 | export const modelName = 'yolov8n' 16 | 17 | export const tfjsLoading = ref(true) 18 | export const tfjsProgress = ref(0) 19 | export const tfjsSpinTip = computed(() => { 20 | return `Loading model... ${(tfjsProgress.value * 100).toFixed(2)}%` 21 | }) 22 | 23 | export const globalActiveKey = ref('1') 24 | -------------------------------------------------------------------------------- /src/utils/labels.json: -------------------------------------------------------------------------------- 1 | ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"] 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | yolov8-tfjs-vue-webrtc-demo 8 | 9 | 10 | 11 |
12 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // Generated by unplugin-vue-components 5 | // Read more: https://github.com/vuejs/core/pull/3399 6 | export {} 7 | 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | FullScreenBtn: typeof import('./src/components/FullScreenBtn.vue')['default'] 11 | Hello: typeof import('./src/components/Hello.vue')['default'] 12 | RouterLink: typeof import('vue-router')['RouterLink'] 13 | RouterView: typeof import('vue-router')['RouterView'] 14 | TabsPicture: typeof import('./src/components/Tabs/TabsPicture.vue')['default'] 15 | TabsVideo: typeof import('./src/components/Tabs/TabsVideo.vue')['default'] 16 | TabsWebCam: typeof import('./src/components/Tabs/TabsWebCam.vue')['default'] 17 | TabsWebRTC: typeof import('./src/components/Tabs/TabsWebRTC.vue')['default'] 18 | VideoRtc: typeof import('./src/components/VideoRtc.vue')['default'] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/pages/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 34 | -------------------------------------------------------------------------------- /unocss.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, 3 | presetAttributify, 4 | presetIcons, 5 | presetUno, 6 | presetWebFonts, 7 | // transformerDirectives, 8 | // transformerVariantGroup, 9 | } from 'unocss' 10 | 11 | export default defineConfig({ 12 | shortcuts: [ 13 | ['btn', 'px-4 py-1 rounded inline-block bg-teal-600 text-white cursor-pointer hover:bg-teal-700 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'], 14 | ['icon-btn', 'text-[0.9em] inline-block cursor-pointer select-none opacity-75 transition duration-200 ease-in-out hover:opacity-100 hover:text-teal-600 !outline-none'], 15 | ], 16 | presets: [ 17 | presetUno(), 18 | presetAttributify(), 19 | presetIcons({ 20 | scale: 1.2, 21 | warn: true, 22 | }), 23 | presetWebFonts({ 24 | fonts: { 25 | sans: 'DM Sans', 26 | serif: 'DM Serif Display', 27 | mono: 'DM Mono', 28 | }, 29 | }), 30 | ], 31 | // transformers: [ 32 | // transformerDirectives(), 33 | // transformerVariantGroup(), 34 | // ], 35 | }) 36 | -------------------------------------------------------------------------------- /src/composables/actions.ts: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs' 2 | 3 | import '@tensorflow/tfjs-backend-webgl' 4 | import { tfjsLoading, tfjsProgress } from './global' 5 | 6 | export function loadTfModels() { 7 | tf.ready().then(async () => { 8 | const yolov8 = await tf.loadGraphModel( 9 | `${window.location.href}/${modelName}_web_model/model.json`, 10 | { 11 | onProgress: (fractions) => { 12 | tfjsLoading.value = true 13 | tfjsProgress.value = fractions 14 | }, 15 | }, 16 | ) // load model 17 | 18 | // warming up model 19 | if (yolov8.inputs[0].shape) { 20 | const dummyInput = tf.ones(yolov8.inputs[0].shape) 21 | const warmupResults = yolov8.execute(dummyInput) 22 | tfjsLoading.value = false 23 | tfjsProgress.value = 1 24 | model.net = yolov8 25 | inputShape.value = yolov8.inputs[0].shape 26 | tf.dispose([warmupResults, dummyInput]) // cleanup memory 27 | } 28 | }) 29 | } 30 | 31 | export function initNet() { 32 | tf.disposeVariables() 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-PRESENT lanseria 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/components/Tabs/TabsWebRTC.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "arco-uno-basic-template", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite --host", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview", 11 | "up": "taze major -I" 12 | }, 13 | "dependencies": { 14 | "@arco-design/web-vue": "2.54.2", 15 | "@tensorflow/tfjs": "^4.16.0", 16 | "@tensorflow/tfjs-backend-webgl": "^4.16.0", 17 | "@tensorflow/tfjs-backend-webgpu": "4.16.0", 18 | "@vueuse/core": "^10.7.2", 19 | "vue": "^3.4.13", 20 | "vue-router": "^4.2.5" 21 | }, 22 | "devDependencies": { 23 | "@antfu/eslint-config": "^2.6.2", 24 | "@iconify-json/carbon": "^1.1.27", 25 | "@types/node": "^18.19.7", 26 | "@unocss/eslint-plugin": "^0.58.3", 27 | "@unocss/reset": "^0.58.3", 28 | "@vitejs/plugin-vue": "^5.0.3", 29 | "eslint": "^8.56.0", 30 | "eslint-plugin-format": "^0.1.0", 31 | "pnpm": "^8.14.1", 32 | "taze": "^0.13.1", 33 | "typescript": "^5.3.3", 34 | "unocss": "^0.58.3", 35 | "unplugin-auto-import": "^0.17.3", 36 | "unplugin-vue-components": "^0.26.0", 37 | "vite": "^5.0.11", 38 | "vite-plugin-pages": "^0.32.0", 39 | "vue-tsc": "^1.8.27" 40 | }, 41 | "eslintConfig": { 42 | "extends": "@antfu" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Tabs/TabsPicture.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 50 | -------------------------------------------------------------------------------- /src/components/Tabs/TabsVideo.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 53 | -------------------------------------------------------------------------------- /public/yolov8n_web_model/metadata.yaml: -------------------------------------------------------------------------------- 1 | description: Ultralytics YOLOv8n model trained on coco.yaml 2 | author: Ultralytics 3 | license: GPL-3.0 https://ultralytics.com/license 4 | version: 8.0.57 5 | stride: 32 6 | task: detect 7 | batch: 1 8 | imgsz: 9 | - 640 10 | - 640 11 | names: 12 | 0: person 13 | 1: bicycle 14 | 2: car 15 | 3: motorcycle 16 | 4: airplane 17 | 5: bus 18 | 6: train 19 | 7: truck 20 | 8: boat 21 | 9: traffic light 22 | 10: fire hydrant 23 | 11: stop sign 24 | 12: parking meter 25 | 13: bench 26 | 14: bird 27 | 15: cat 28 | 16: dog 29 | 17: horse 30 | 18: sheep 31 | 19: cow 32 | 20: elephant 33 | 21: bear 34 | 22: zebra 35 | 23: giraffe 36 | 24: backpack 37 | 25: umbrella 38 | 26: handbag 39 | 27: tie 40 | 28: suitcase 41 | 29: frisbee 42 | 30: skis 43 | 31: snowboard 44 | 32: sports ball 45 | 33: kite 46 | 34: baseball bat 47 | 35: baseball glove 48 | 36: skateboard 49 | 37: surfboard 50 | 38: tennis racket 51 | 39: bottle 52 | 40: wine glass 53 | 41: cup 54 | 42: fork 55 | 43: knife 56 | 44: spoon 57 | 45: bowl 58 | 46: banana 59 | 47: apple 60 | 48: sandwich 61 | 49: orange 62 | 50: broccoli 63 | 51: carrot 64 | 52: hot dog 65 | 53: pizza 66 | 54: donut 67 | 55: cake 68 | 56: chair 69 | 57: couch 70 | 58: potted plant 71 | 59: bed 72 | 60: dining table 73 | 61: toilet 74 | 62: tv 75 | 63: laptop 76 | 64: mouse 77 | 65: remote 78 | 66: keyboard 79 | 67: cell phone 80 | 68: microwave 81 | 69: oven 82 | 70: toaster 83 | 71: sink 84 | 72: refrigerator 85 | 73: book 86 | 74: clock 87 | 75: vase 88 | 76: scissors 89 | 77: teddy bear 90 | 78: hair drier 91 | 79: toothbrush 92 | -------------------------------------------------------------------------------- /src/components/Tabs/TabsWebCam.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yolov8-tfjs-vue-webrtc-demo 2 | 3 | ## Description 4 | 5 | "yolov8-tfjs-vue-webrtc-demo"是一个利用深度学习目标检测模型YOLOv8、TensorFlow.js框架、Vue.js框架和WebRTC技术实现的演示项目。该项目可以通过前端界面实时展示视频流,并对视频中的目标进行实时检测和识别。借助GPU加速的WebGL后端,该项目能够实现快速高效的模型推理,同时通过WebRTC技术,还能够实现点对点的视频传输,为实时应用提供了强大的支持。" 6 | 7 | "yolov8-tfjs-vue-webrtc-demo" is a demonstration project that utilizes the YOLOv8 deep learning object detection model, the TensorFlow.js framework, the Vue.js framework, and WebRTC technology. This project can display video streams in real-time through a front-end interface, and perform real-time detection and recognition of objects in the video. With the GPU-accelerated WebGL backend, this project can achieve fast and efficient model inference. Additionally, using WebRTC technology, it can enable peer-to-peer video transmission, providing powerful support for real-time applications. 8 | 9 | ## Demo 10 | 11 | link: https://yolov8-tfjs-vue-webrtc-demo.netlify.app/ 12 | 13 | ![demo](docs/video.png) 14 | 15 | ## how to use 如何使用 16 | 17 | 将 YOLOv8 转换为 tfjs 模型,并将其放入 public 文件夹中。 18 | 打开 [global.ts](src/composables/global.ts) 文件并将以下代码块: 19 | ```ts 20 | // if chrome version 113 above you can use webgpu 21 | import '@tensorflow/tfjs-backend-webgpu' 22 | 23 | export const modelName = 'yolov8n' 24 | // replace 25 | export const modelName = 'your model prefix name ' 26 | 27 | // import '@tensorflow/tfjs-backend-webgl'; 28 | ``` 29 | 编辑 labels.json 文件以匹配您的模型输出标签。 30 | 31 | [labels.json](src/utils/labels.json)文件 32 | 33 | 在终端中运行以下命令: 34 | 35 | ```bash 36 | pnpm i && pnpm dev 37 | ``` 38 | 39 | ## useable models 可用模型 40 | 41 | - 安全帽检测 https://huggingface.co/lanseria/yolov8n-hard-hat-detection_web_model 42 | 43 | ## webRTC 依赖项目请使用 go2RTC 44 | 45 | - go2rtc https://github.com/AlexxIT/go2rtc 46 | 47 | ## yolov8 model 转为 tfjs model 方式 48 | 49 | - reference https://github.com/Hyuto/yolov8-tfjs 50 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { ConfigEnv, UserConfig, loadEnv } from 'vite' 3 | import vue from '@vitejs/plugin-vue' 4 | import Pages from 'vite-plugin-pages' 5 | import Components from 'unplugin-vue-components/vite' 6 | import AutoImport from 'unplugin-auto-import/vite' 7 | import Unocss from 'unocss/vite' 8 | import { ArcoResolver } from 'unplugin-vue-components/resolvers' 9 | 10 | export default ({ mode }: ConfigEnv): UserConfig => { 11 | const root = process.cwd() 12 | const env = loadEnv(mode, root) 13 | return { 14 | server: { 15 | host: env.VITE_HOST, 16 | port: +env.VITE_PORT, 17 | // proxy: { 18 | // '^\/api\/': { 19 | // target: env.VITE_PROXY_URL, 20 | // changeOrigin: true, 21 | // xfwd: true, 22 | // rewrite: (path) => { 23 | // const replacePath = path.replace(/^\/api/, '') 24 | // return replacePath 25 | // }, 26 | // }, 27 | // }, 28 | }, 29 | resolve: { 30 | alias: { 31 | '~/': `${path.resolve(__dirname, 'src')}/`, 32 | 'vue': 'vue/dist/vue.esm-bundler.js', 33 | }, 34 | }, 35 | build: { 36 | sourcemap: true, 37 | }, 38 | plugins: [ 39 | vue({ 40 | reactivityTransform: true, 41 | }), 42 | 43 | // https://github.com/hannoeru/vite-plugin-pages 44 | Pages(), 45 | 46 | // https://github.com/antfu/unplugin-auto-import 47 | AutoImport({ 48 | resolvers: [ArcoResolver()], 49 | imports: [ 50 | 'vue', 51 | 'vue/macros', 52 | 'vue-router', 53 | '@vueuse/core', 54 | ], 55 | dts: true, 56 | dirs: [ 57 | './src/composables', 58 | ], 59 | vueTemplate: true, 60 | }), 61 | 62 | // https://github.com/antfu/vite-plugin-components 63 | Components({ 64 | dts: true, 65 | }), 66 | 67 | // https://github.com/antfu/unocss 68 | // see unocss.config.ts for config 69 | Unocss(), 70 | ], 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/utils/renderBox.ts: -------------------------------------------------------------------------------- 1 | import labels from './labels.json' 2 | 3 | /** 4 | * Render prediction boxes 5 | * @param {HTMLCanvasElement} canvasRef canvas tag reference 6 | * @param {Array} boxes_data boxes array 7 | * @param {Array} scores_data scores array 8 | * @param {Array} classes_data class array 9 | * @param {Array[Number]} ratios boxes ratio [xRatio, yRatio] 10 | */ 11 | export function renderBoxes(canvasRef: HTMLCanvasElement, boxes_data: Float32Array | Int32Array | Uint8Array, scores_data: Float32Array | Int32Array | Uint8Array, classes_data: Float32Array | Int32Array | Uint8Array, ratios: any[]) { 12 | const ctx = canvasRef.getContext('2d') 13 | if (ctx) { 14 | ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height) // clean canvas 15 | 16 | const colors = new Colors() 17 | 18 | // font configs 19 | const font = `${Math.max( 20 | Math.round(Math.max(ctx.canvas.width, ctx.canvas.height) / 40), 21 | 14, 22 | )}px Arial` 23 | ctx.font = font 24 | ctx.textBaseline = 'top' 25 | 26 | for (let i = 0; i < scores_data.length; ++i) { 27 | // filter based on class threshold 28 | const klass = labels[classes_data[i]] 29 | const color = colors.get(classes_data[i]) 30 | const score = (scores_data[i] * 100).toFixed(1) 31 | 32 | let [y1, x1, y2, x2] = boxes_data.slice(i * 4, (i + 1) * 4) 33 | x1 *= ratios[0] 34 | x2 *= ratios[0] 35 | y1 *= ratios[1] 36 | y2 *= ratios[1] 37 | const width = x2 - x1 38 | const height = y2 - y1 39 | 40 | // draw box. 41 | ctx.fillStyle = Colors.hexToRgba(color, 0.2)! 42 | ctx.fillRect(x1, y1, width, height) 43 | 44 | // draw border box. 45 | ctx.strokeStyle = color 46 | ctx.lineWidth = Math.max(Math.min(ctx.canvas.width, ctx.canvas.height) / 200, 2.5) 47 | ctx.strokeRect(x1, y1, width, height) 48 | 49 | // Draw the label background. 50 | ctx.fillStyle = color 51 | const textWidth = ctx.measureText(`${klass} - ${score}%`).width 52 | const textHeight = parseInt(font, 10) // base 10 53 | const yText = y1 - (textHeight + ctx.lineWidth) 54 | ctx.fillRect( 55 | x1 - 1, 56 | yText < 0 ? 0 : yText, // handle overflow label box 57 | textWidth + ctx.lineWidth, 58 | textHeight + ctx.lineWidth, 59 | ) 60 | 61 | // Draw labels 62 | ctx.fillStyle = '#ffffff' 63 | ctx.fillText(`${klass} - ${score}%`, x1 - 1, yText < 0 ? 0 : yText) 64 | } 65 | } 66 | } 67 | 68 | class Colors { 69 | palette: string[] 70 | n: number 71 | // ultralytics color palette https://ultralytics.com/ 72 | constructor() { 73 | this.palette = [ 74 | '#FF3838', 75 | '#FF9D97', 76 | '#FF701F', 77 | '#FFB21D', 78 | '#CFD231', 79 | '#48F90A', 80 | '#92CC17', 81 | '#3DDB86', 82 | '#1A9334', 83 | '#00D4BB', 84 | '#2C99A8', 85 | '#00C2FF', 86 | '#344593', 87 | '#6473FF', 88 | '#0018EC', 89 | '#8438FF', 90 | '#520085', 91 | '#CB38FF', 92 | '#FF95C8', 93 | '#FF37C7', 94 | ] 95 | this.n = this.palette.length 96 | } 97 | 98 | get = (i: number) => this.palette[Math.floor(i) % this.n] 99 | 100 | static hexToRgba = (hex: string, alpha: number) => { 101 | const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) 102 | return result 103 | ? `rgba(${[parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)].join( 104 | ', ', 105 | )}, ${alpha})` 106 | : null 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/composables/detect.ts: -------------------------------------------------------------------------------- 1 | import type { Rank, Tensor, Tensor1D, Tensor2D, Tensor3D } from '@tensorflow/tfjs' 2 | import labels from '~/utils/labels.json' 3 | import { renderBoxes } from '~/utils/renderBox' 4 | 5 | const numClass = labels.length 6 | let animationId = -1 7 | /** 8 | * Preprocess image / frame before forwarded into the model 9 | * @param {HTMLVideoElement|HTMLImageElement} source 10 | * @param {Number} modelWidth 11 | * @param {Number} modelHeight 12 | * @returns input tensor, xRatio and yRatio 13 | */ 14 | function preprocess(source: HTMLVideoElement | HTMLImageElement, modelWidth: number, modelHeight: number): [Tensor, number, number] { 15 | let xRatio = 0 16 | let yRatio = 0 17 | // ratios for boxes 18 | 19 | const input = tf.tidy(() => { 20 | const img = tf.browser.fromPixels(source) 21 | 22 | // padding image to square => [n, m] to [n, n], n > m 23 | const [h, w] = img.shape.slice(0, 2) // get source width and height 24 | const maxSize = Math.max(w, h) // get max size 25 | const imgPadded = img.pad([ 26 | [0, maxSize - h], // padding y [bottom only] 27 | [0, maxSize - w], // padding x [right only] 28 | [0, 0], 29 | ]) as Tensor3D 30 | 31 | xRatio = maxSize / w // update xRatio 32 | yRatio = maxSize / h // update yRatio 33 | 34 | return tf.image 35 | .resizeBilinear(imgPadded, [modelWidth, modelHeight]) // resize frame 36 | .div(255.0) // normalize 37 | .expandDims(0) // add batch 38 | }) 39 | 40 | return [input, xRatio, yRatio] 41 | } 42 | 43 | /** 44 | * Function run inference and do detection from source. 45 | * @param {HTMLImageElement|HTMLVideoElement} source 46 | * @param {tf.GraphModel} model loaded YOLOv8 tensorflow.js model 47 | * @param {HTMLCanvasElement} canvasRef canvas reference 48 | * @param {VoidFunction} callback function to run after detection process 49 | */ 50 | export async function detect(source: HTMLImageElement | HTMLVideoElement, canvasRef: HTMLCanvasElement, callback = () => {}) { 51 | tf.engine().startScope() // start scoping tf engine 52 | const [modelWidth, modelHeight] = inputShape.value.slice(1, 3) // get model width and height 53 | // console.log(modelWidth, modelHeight) 54 | const [input, xRatio, yRatio] = preprocess(source, modelWidth, modelHeight) // preprocess image 55 | // console.log(model.net) 56 | 57 | const res = model.net!.execute(input!) as Tensor // inference model 58 | const transRes = res.transpose([0, 2, 1]) // transpose result [b, det, n] => [b, n, det] 59 | const boxes = tf.tidy(() => { 60 | const w = transRes.slice([0, 0, 2], [-1, -1, 1]) // get width 61 | const h = transRes.slice([0, 0, 3], [-1, -1, 1]) // get height 62 | const x1 = tf.sub(transRes.slice([0, 0, 0], [-1, -1, 1]), tf.div(w, 2)) // x1 63 | const y1 = tf.sub(transRes.slice([0, 0, 1], [-1, -1, 1]), tf.div(h, 2)) // y1 64 | return tf 65 | .concat( 66 | [ 67 | y1, 68 | x1, 69 | tf.add(y1, h), // y2 70 | tf.add(x1, w), // x2 71 | ], 72 | 2, 73 | ) 74 | .squeeze() 75 | }) as Tensor2D // process boxes [y1, x1, y2, x2] 76 | 77 | const [scores, classes] = tf.tidy(() => { 78 | const rawScores = transRes.slice([0, 0, 4], [-1, -1, numClass]).squeeze() // class scores 79 | return [rawScores.max(1), rawScores.argMax(1)] 80 | }) as [Tensor1D, Tensor2D ] // get max scores and classes index 81 | 82 | const nms = await tf.image.nonMaxSuppressionAsync(boxes, scores, 500, 0.45, 0.2) // NMS to filter boxes 83 | 84 | const boxes_data = await boxes.gather(nms, 0).data() 85 | const scores_data = await scores.gather(nms, 0).data() 86 | const classes_data = await classes.gather(nms, 0).data() 87 | 88 | renderBoxes(canvasRef, boxes_data, scores_data, classes_data, [xRatio, yRatio]) 89 | 90 | tf.dispose([res, transRes, boxes, scores, classes, nms]) 91 | callback() 92 | tf.engine().endScope() 93 | } 94 | 95 | /** 96 | * Function to detect video from every source. 97 | * @param {HTMLVideoElement} vidSource video source 98 | * @param {tf.GraphModel} model loaded YOLOv8 tensorflow.js model 99 | * @param {HTMLCanvasElement} canvasRef canvas reference 100 | */ 101 | export function detectVideo(vidSource: HTMLVideoElement, canvasRef: HTMLCanvasElement) { 102 | /** 103 | * Function to detect every frame from video 104 | */ 105 | // console.log(vidSource, canvasRef) 106 | const detectFrame = async () => { 107 | if (vidSource.videoWidth === 0 && vidSource.srcObject === null) { 108 | console.warn('vidSource.srcObject === null') 109 | const ctx = canvasRef.getContext('2d') 110 | ctx && ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height) // clean canvas 111 | return // handle if source is closed 112 | } 113 | 114 | detect(vidSource, canvasRef, () => { 115 | animationId = requestAnimationFrame(detectFrame) // get another frame 116 | }) 117 | } 118 | 119 | detectFrame() // initialize to detect every frame 120 | } 121 | export function unDetectVideo() { 122 | console.warn('unDetectVideo') 123 | cancelAnimationFrame(animationId) 124 | } 125 | -------------------------------------------------------------------------------- /src/components/VideoRtc.vue: -------------------------------------------------------------------------------- 1 | 284 | 285 | 296 | 297 | 307 | -------------------------------------------------------------------------------- /auto-imports.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // noinspection JSUnusedGlobalSymbols 5 | // Generated by unplugin-auto-import 6 | export {} 7 | declare global { 8 | const $: typeof import('vue/macros')['$'] 9 | const $$: typeof import('vue/macros')['$$'] 10 | const $computed: typeof import('vue/macros')['$computed'] 11 | const $customRef: typeof import('vue/macros')['$customRef'] 12 | const $ref: typeof import('vue/macros')['$ref'] 13 | const $shallowRef: typeof import('vue/macros')['$shallowRef'] 14 | const $toRef: typeof import('vue/macros')['$toRef'] 15 | const EffectScope: typeof import('vue')['EffectScope'] 16 | const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] 17 | const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] 18 | const computed: typeof import('vue')['computed'] 19 | const computedAsync: typeof import('@vueuse/core')['computedAsync'] 20 | const computedEager: typeof import('@vueuse/core')['computedEager'] 21 | const computedInject: typeof import('@vueuse/core')['computedInject'] 22 | const computedWithControl: typeof import('@vueuse/core')['computedWithControl'] 23 | const controlledComputed: typeof import('@vueuse/core')['controlledComputed'] 24 | const controlledRef: typeof import('@vueuse/core')['controlledRef'] 25 | const createApp: typeof import('vue')['createApp'] 26 | const createEventHook: typeof import('@vueuse/core')['createEventHook'] 27 | const createGlobalState: typeof import('@vueuse/core')['createGlobalState'] 28 | const createInjectionState: typeof import('@vueuse/core')['createInjectionState'] 29 | const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn'] 30 | const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate'] 31 | const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] 32 | const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise'] 33 | const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn'] 34 | const customRef: typeof import('vue')['customRef'] 35 | const debouncedRef: typeof import('@vueuse/core')['debouncedRef'] 36 | const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch'] 37 | const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] 38 | const defineComponent: typeof import('vue')['defineComponent'] 39 | const detect: typeof import('./src/composables/detect')['detect'] 40 | const detectVideo: typeof import('./src/composables/detect')['detectVideo'] 41 | const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] 42 | const effectScope: typeof import('vue')['effectScope'] 43 | const extendRef: typeof import('@vueuse/core')['extendRef'] 44 | const getCurrentInstance: typeof import('vue')['getCurrentInstance'] 45 | const getCurrentScope: typeof import('vue')['getCurrentScope'] 46 | const globalActiveKey: typeof import('./src/composables/global')['globalActiveKey'] 47 | const h: typeof import('vue')['h'] 48 | const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] 49 | const initNet: typeof import('./src/composables/actions')['initNet'] 50 | const inject: typeof import('vue')['inject'] 51 | const injectLocal: typeof import('@vueuse/core')['injectLocal'] 52 | const inputShape: typeof import('./src/composables/global')['inputShape'] 53 | const isDark: typeof import('./src/composables/dark')['isDark'] 54 | const isDefined: typeof import('@vueuse/core')['isDefined'] 55 | const isProxy: typeof import('vue')['isProxy'] 56 | const isReactive: typeof import('vue')['isReactive'] 57 | const isReadonly: typeof import('vue')['isReadonly'] 58 | const isRef: typeof import('vue')['isRef'] 59 | const loadTfModels: typeof import('./src/composables/actions')['loadTfModels'] 60 | const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] 61 | const markRaw: typeof import('vue')['markRaw'] 62 | const model: typeof import('./src/composables/global')['model'] 63 | const modelName: typeof import('./src/composables/global')['modelName'] 64 | const nextTick: typeof import('vue')['nextTick'] 65 | const onActivated: typeof import('vue')['onActivated'] 66 | const onBeforeMount: typeof import('vue')['onBeforeMount'] 67 | const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] 68 | const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] 69 | const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] 70 | const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] 71 | const onClickOutside: typeof import('@vueuse/core')['onClickOutside'] 72 | const onDeactivated: typeof import('vue')['onDeactivated'] 73 | const onErrorCaptured: typeof import('vue')['onErrorCaptured'] 74 | const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke'] 75 | const onLongPress: typeof import('@vueuse/core')['onLongPress'] 76 | const onMounted: typeof import('vue')['onMounted'] 77 | const onRenderTracked: typeof import('vue')['onRenderTracked'] 78 | const onRenderTriggered: typeof import('vue')['onRenderTriggered'] 79 | const onScopeDispose: typeof import('vue')['onScopeDispose'] 80 | const onServerPrefetch: typeof import('vue')['onServerPrefetch'] 81 | const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] 82 | const onUnmounted: typeof import('vue')['onUnmounted'] 83 | const onUpdated: typeof import('vue')['onUpdated'] 84 | const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] 85 | const provide: typeof import('vue')['provide'] 86 | const provideLocal: typeof import('@vueuse/core')['provideLocal'] 87 | const reactify: typeof import('@vueuse/core')['reactify'] 88 | const reactifyObject: typeof import('@vueuse/core')['reactifyObject'] 89 | const reactive: typeof import('vue')['reactive'] 90 | const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed'] 91 | const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit'] 92 | const reactivePick: typeof import('@vueuse/core')['reactivePick'] 93 | const readonly: typeof import('vue')['readonly'] 94 | const ref: typeof import('vue')['ref'] 95 | const refAutoReset: typeof import('@vueuse/core')['refAutoReset'] 96 | const refDebounced: typeof import('@vueuse/core')['refDebounced'] 97 | const refDefault: typeof import('@vueuse/core')['refDefault'] 98 | const refThrottled: typeof import('@vueuse/core')['refThrottled'] 99 | const refWithControl: typeof import('@vueuse/core')['refWithControl'] 100 | const resolveComponent: typeof import('vue')['resolveComponent'] 101 | const resolveRef: typeof import('@vueuse/core')['resolveRef'] 102 | const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] 103 | const shallowReactive: typeof import('vue')['shallowReactive'] 104 | const shallowReadonly: typeof import('vue')['shallowReadonly'] 105 | const shallowRef: typeof import('vue')['shallowRef'] 106 | const syncRef: typeof import('@vueuse/core')['syncRef'] 107 | const syncRefs: typeof import('@vueuse/core')['syncRefs'] 108 | const templateRef: typeof import('@vueuse/core')['templateRef'] 109 | const tf: typeof import('./src/composables/global')['tf'] 110 | const tfjsLoading: typeof import('./src/composables/global')['tfjsLoading'] 111 | const tfjsProgress: typeof import('./src/composables/global')['tfjsProgress'] 112 | const tfjsSpinTip: typeof import('./src/composables/global')['tfjsSpinTip'] 113 | const throttledRef: typeof import('@vueuse/core')['throttledRef'] 114 | const throttledWatch: typeof import('@vueuse/core')['throttledWatch'] 115 | const toRaw: typeof import('vue')['toRaw'] 116 | const toReactive: typeof import('@vueuse/core')['toReactive'] 117 | const toRef: typeof import('vue')['toRef'] 118 | const toRefs: typeof import('vue')['toRefs'] 119 | const toValue: typeof import('vue')['toValue'] 120 | const toggleDark: typeof import('./src/composables/dark')['toggleDark'] 121 | const triggerRef: typeof import('vue')['triggerRef'] 122 | const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] 123 | const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] 124 | const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted'] 125 | const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose'] 126 | const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted'] 127 | const unDetectVideo: typeof import('./src/composables/detect')['unDetectVideo'] 128 | const unref: typeof import('vue')['unref'] 129 | const unrefElement: typeof import('@vueuse/core')['unrefElement'] 130 | const until: typeof import('@vueuse/core')['until'] 131 | const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] 132 | const useAnimate: typeof import('@vueuse/core')['useAnimate'] 133 | const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference'] 134 | const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery'] 135 | const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter'] 136 | const useArrayFind: typeof import('@vueuse/core')['useArrayFind'] 137 | const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex'] 138 | const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast'] 139 | const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes'] 140 | const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin'] 141 | const useArrayMap: typeof import('@vueuse/core')['useArrayMap'] 142 | const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce'] 143 | const useArraySome: typeof import('@vueuse/core')['useArraySome'] 144 | const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique'] 145 | const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue'] 146 | const useAsyncState: typeof import('@vueuse/core')['useAsyncState'] 147 | const useAttrs: typeof import('vue')['useAttrs'] 148 | const useBase64: typeof import('@vueuse/core')['useBase64'] 149 | const useBattery: typeof import('@vueuse/core')['useBattery'] 150 | const useBluetooth: typeof import('@vueuse/core')['useBluetooth'] 151 | const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints'] 152 | const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel'] 153 | const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] 154 | const useCached: typeof import('@vueuse/core')['useCached'] 155 | const useClipboard: typeof import('@vueuse/core')['useClipboard'] 156 | const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems'] 157 | const useCloned: typeof import('@vueuse/core')['useCloned'] 158 | const useColorMode: typeof import('@vueuse/core')['useColorMode'] 159 | const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog'] 160 | const useCounter: typeof import('@vueuse/core')['useCounter'] 161 | const useCssModule: typeof import('vue')['useCssModule'] 162 | const useCssVar: typeof import('@vueuse/core')['useCssVar'] 163 | const useCssVars: typeof import('vue')['useCssVars'] 164 | const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement'] 165 | const useCycleList: typeof import('@vueuse/core')['useCycleList'] 166 | const useDark: typeof import('@vueuse/core')['useDark'] 167 | const useDateFormat: typeof import('@vueuse/core')['useDateFormat'] 168 | const useDebounce: typeof import('@vueuse/core')['useDebounce'] 169 | const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn'] 170 | const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory'] 171 | const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion'] 172 | const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation'] 173 | const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio'] 174 | const useDevicesList: typeof import('@vueuse/core')['useDevicesList'] 175 | const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia'] 176 | const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility'] 177 | const useDraggable: typeof import('@vueuse/core')['useDraggable'] 178 | const useDropZone: typeof import('@vueuse/core')['useDropZone'] 179 | const useElementBounding: typeof import('@vueuse/core')['useElementBounding'] 180 | const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint'] 181 | const useElementHover: typeof import('@vueuse/core')['useElementHover'] 182 | const useElementSize: typeof import('@vueuse/core')['useElementSize'] 183 | const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility'] 184 | const useEventBus: typeof import('@vueuse/core')['useEventBus'] 185 | const useEventListener: typeof import('@vueuse/core')['useEventListener'] 186 | const useEventSource: typeof import('@vueuse/core')['useEventSource'] 187 | const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper'] 188 | const useFavicon: typeof import('@vueuse/core')['useFavicon'] 189 | const useFetch: typeof import('@vueuse/core')['useFetch'] 190 | const useFileDialog: typeof import('@vueuse/core')['useFileDialog'] 191 | const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess'] 192 | const useFocus: typeof import('@vueuse/core')['useFocus'] 193 | const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin'] 194 | const useFps: typeof import('@vueuse/core')['useFps'] 195 | const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] 196 | const useGamepad: typeof import('@vueuse/core')['useGamepad'] 197 | const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] 198 | const useIdle: typeof import('@vueuse/core')['useIdle'] 199 | const useImage: typeof import('@vueuse/core')['useImage'] 200 | const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] 201 | const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver'] 202 | const useInterval: typeof import('@vueuse/core')['useInterval'] 203 | const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn'] 204 | const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier'] 205 | const useLastChanged: typeof import('@vueuse/core')['useLastChanged'] 206 | const useLink: typeof import('vue-router')['useLink'] 207 | const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage'] 208 | const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys'] 209 | const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory'] 210 | const useMediaControls: typeof import('@vueuse/core')['useMediaControls'] 211 | const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] 212 | const useMemoize: typeof import('@vueuse/core')['useMemoize'] 213 | const useMemory: typeof import('@vueuse/core')['useMemory'] 214 | const useMounted: typeof import('@vueuse/core')['useMounted'] 215 | const useMouse: typeof import('@vueuse/core')['useMouse'] 216 | const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] 217 | const useMousePressed: typeof import('@vueuse/core')['useMousePressed'] 218 | const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] 219 | const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] 220 | const useNetwork: typeof import('@vueuse/core')['useNetwork'] 221 | const useNow: typeof import('@vueuse/core')['useNow'] 222 | const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl'] 223 | const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] 224 | const useOnline: typeof import('@vueuse/core')['useOnline'] 225 | const usePageLeave: typeof import('@vueuse/core')['usePageLeave'] 226 | const useParallax: typeof import('@vueuse/core')['useParallax'] 227 | const useParentElement: typeof import('@vueuse/core')['useParentElement'] 228 | const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver'] 229 | const usePermission: typeof import('@vueuse/core')['usePermission'] 230 | const usePointer: typeof import('@vueuse/core')['usePointer'] 231 | const usePointerLock: typeof import('@vueuse/core')['usePointerLock'] 232 | const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe'] 233 | const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme'] 234 | const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast'] 235 | const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark'] 236 | const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages'] 237 | const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion'] 238 | const usePrevious: typeof import('@vueuse/core')['usePrevious'] 239 | const useRafFn: typeof import('@vueuse/core')['useRafFn'] 240 | const useRefHistory: typeof import('@vueuse/core')['useRefHistory'] 241 | const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver'] 242 | const useRoute: typeof import('vue-router')['useRoute'] 243 | const useRouter: typeof import('vue-router')['useRouter'] 244 | const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation'] 245 | const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea'] 246 | const useScriptTag: typeof import('@vueuse/core')['useScriptTag'] 247 | const useScroll: typeof import('@vueuse/core')['useScroll'] 248 | const useScrollLock: typeof import('@vueuse/core')['useScrollLock'] 249 | const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage'] 250 | const useShare: typeof import('@vueuse/core')['useShare'] 251 | const useSlots: typeof import('vue')['useSlots'] 252 | const useSorted: typeof import('@vueuse/core')['useSorted'] 253 | const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition'] 254 | const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis'] 255 | const useStepper: typeof import('@vueuse/core')['useStepper'] 256 | const useStorage: typeof import('@vueuse/core')['useStorage'] 257 | const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync'] 258 | const useStyleTag: typeof import('@vueuse/core')['useStyleTag'] 259 | const useSupported: typeof import('@vueuse/core')['useSupported'] 260 | const useSwipe: typeof import('@vueuse/core')['useSwipe'] 261 | const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] 262 | const useTextDirection: typeof import('@vueuse/core')['useTextDirection'] 263 | const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] 264 | const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize'] 265 | const useThrottle: typeof import('@vueuse/core')['useThrottle'] 266 | const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn'] 267 | const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory'] 268 | const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo'] 269 | const useTimeout: typeof import('@vueuse/core')['useTimeout'] 270 | const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn'] 271 | const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll'] 272 | const useTimestamp: typeof import('@vueuse/core')['useTimestamp'] 273 | const useTitle: typeof import('@vueuse/core')['useTitle'] 274 | const useToNumber: typeof import('@vueuse/core')['useToNumber'] 275 | const useToString: typeof import('@vueuse/core')['useToString'] 276 | const useToggle: typeof import('@vueuse/core')['useToggle'] 277 | const useTransition: typeof import('@vueuse/core')['useTransition'] 278 | const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams'] 279 | const useUserMedia: typeof import('@vueuse/core')['useUserMedia'] 280 | const useVModel: typeof import('@vueuse/core')['useVModel'] 281 | const useVModels: typeof import('@vueuse/core')['useVModels'] 282 | const useVibrate: typeof import('@vueuse/core')['useVibrate'] 283 | const useVirtualList: typeof import('@vueuse/core')['useVirtualList'] 284 | const useWakeLock: typeof import('@vueuse/core')['useWakeLock'] 285 | const useWebNotification: typeof import('@vueuse/core')['useWebNotification'] 286 | const useWebSocket: typeof import('@vueuse/core')['useWebSocket'] 287 | const useWebWorker: typeof import('@vueuse/core')['useWebWorker'] 288 | const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn'] 289 | const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus'] 290 | const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll'] 291 | const useWindowSize: typeof import('@vueuse/core')['useWindowSize'] 292 | const watch: typeof import('vue')['watch'] 293 | const watchArray: typeof import('@vueuse/core')['watchArray'] 294 | const watchAtMost: typeof import('@vueuse/core')['watchAtMost'] 295 | const watchDebounced: typeof import('@vueuse/core')['watchDebounced'] 296 | const watchDeep: typeof import('@vueuse/core')['watchDeep'] 297 | const watchEffect: typeof import('vue')['watchEffect'] 298 | const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] 299 | const watchImmediate: typeof import('@vueuse/core')['watchImmediate'] 300 | const watchOnce: typeof import('@vueuse/core')['watchOnce'] 301 | const watchPausable: typeof import('@vueuse/core')['watchPausable'] 302 | const watchPostEffect: typeof import('vue')['watchPostEffect'] 303 | const watchSyncEffect: typeof import('vue')['watchSyncEffect'] 304 | const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] 305 | const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable'] 306 | const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] 307 | const whenever: typeof import('@vueuse/core')['whenever'] 308 | } 309 | // for type re-export 310 | declare global { 311 | // @ts-ignore 312 | export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue' 313 | import('vue') 314 | } 315 | // for vue template auto import 316 | import { UnwrapRef } from 'vue' 317 | declare module 'vue' { 318 | interface ComponentCustomProperties { 319 | readonly $$: UnwrapRef 320 | readonly $: UnwrapRef 321 | readonly $computed: UnwrapRef 322 | readonly $customRef: UnwrapRef 323 | readonly $ref: UnwrapRef 324 | readonly $shallowRef: UnwrapRef 325 | readonly $toRef: UnwrapRef 326 | readonly EffectScope: UnwrapRef 327 | readonly asyncComputed: UnwrapRef 328 | readonly autoResetRef: UnwrapRef 329 | readonly computed: UnwrapRef 330 | readonly computedAsync: UnwrapRef 331 | readonly computedEager: UnwrapRef 332 | readonly computedInject: UnwrapRef 333 | readonly computedWithControl: UnwrapRef 334 | readonly controlledComputed: UnwrapRef 335 | readonly controlledRef: UnwrapRef 336 | readonly createApp: UnwrapRef 337 | readonly createEventHook: UnwrapRef 338 | readonly createGlobalState: UnwrapRef 339 | readonly createInjectionState: UnwrapRef 340 | readonly createReactiveFn: UnwrapRef 341 | readonly createReusableTemplate: UnwrapRef 342 | readonly createSharedComposable: UnwrapRef 343 | readonly createTemplatePromise: UnwrapRef 344 | readonly createUnrefFn: UnwrapRef 345 | readonly customRef: UnwrapRef 346 | readonly debouncedRef: UnwrapRef 347 | readonly debouncedWatch: UnwrapRef 348 | readonly defineAsyncComponent: UnwrapRef 349 | readonly defineComponent: UnwrapRef 350 | readonly detect: UnwrapRef 351 | readonly detectVideo: UnwrapRef 352 | readonly eagerComputed: UnwrapRef 353 | readonly effectScope: UnwrapRef 354 | readonly extendRef: UnwrapRef 355 | readonly getCurrentInstance: UnwrapRef 356 | readonly getCurrentScope: UnwrapRef 357 | readonly globalActiveKey: UnwrapRef 358 | readonly h: UnwrapRef 359 | readonly ignorableWatch: UnwrapRef 360 | readonly initNet: UnwrapRef 361 | readonly inject: UnwrapRef 362 | readonly injectLocal: UnwrapRef 363 | readonly inputShape: UnwrapRef 364 | readonly isDark: UnwrapRef 365 | readonly isDefined: UnwrapRef 366 | readonly isProxy: UnwrapRef 367 | readonly isReactive: UnwrapRef 368 | readonly isReadonly: UnwrapRef 369 | readonly isRef: UnwrapRef 370 | readonly loadTfModels: UnwrapRef 371 | readonly makeDestructurable: UnwrapRef 372 | readonly markRaw: UnwrapRef 373 | readonly model: UnwrapRef 374 | readonly modelName: UnwrapRef 375 | readonly nextTick: UnwrapRef 376 | readonly onActivated: UnwrapRef 377 | readonly onBeforeMount: UnwrapRef 378 | readonly onBeforeRouteLeave: UnwrapRef 379 | readonly onBeforeRouteUpdate: UnwrapRef 380 | readonly onBeforeUnmount: UnwrapRef 381 | readonly onBeforeUpdate: UnwrapRef 382 | readonly onClickOutside: UnwrapRef 383 | readonly onDeactivated: UnwrapRef 384 | readonly onErrorCaptured: UnwrapRef 385 | readonly onKeyStroke: UnwrapRef 386 | readonly onLongPress: UnwrapRef 387 | readonly onMounted: UnwrapRef 388 | readonly onRenderTracked: UnwrapRef 389 | readonly onRenderTriggered: UnwrapRef 390 | readonly onScopeDispose: UnwrapRef 391 | readonly onServerPrefetch: UnwrapRef 392 | readonly onStartTyping: UnwrapRef 393 | readonly onUnmounted: UnwrapRef 394 | readonly onUpdated: UnwrapRef 395 | readonly pausableWatch: UnwrapRef 396 | readonly provide: UnwrapRef 397 | readonly provideLocal: UnwrapRef 398 | readonly reactify: UnwrapRef 399 | readonly reactifyObject: UnwrapRef 400 | readonly reactive: UnwrapRef 401 | readonly reactiveComputed: UnwrapRef 402 | readonly reactiveOmit: UnwrapRef 403 | readonly reactivePick: UnwrapRef 404 | readonly readonly: UnwrapRef 405 | readonly ref: UnwrapRef 406 | readonly refAutoReset: UnwrapRef 407 | readonly refDebounced: UnwrapRef 408 | readonly refDefault: UnwrapRef 409 | readonly refThrottled: UnwrapRef 410 | readonly refWithControl: UnwrapRef 411 | readonly resolveComponent: UnwrapRef 412 | readonly resolveRef: UnwrapRef 413 | readonly resolveUnref: UnwrapRef 414 | readonly shallowReactive: UnwrapRef 415 | readonly shallowReadonly: UnwrapRef 416 | readonly shallowRef: UnwrapRef 417 | readonly syncRef: UnwrapRef 418 | readonly syncRefs: UnwrapRef 419 | readonly templateRef: UnwrapRef 420 | readonly tf: UnwrapRef 421 | readonly tfjsLoading: UnwrapRef 422 | readonly tfjsProgress: UnwrapRef 423 | readonly tfjsSpinTip: UnwrapRef 424 | readonly throttledRef: UnwrapRef 425 | readonly throttledWatch: UnwrapRef 426 | readonly toRaw: UnwrapRef 427 | readonly toReactive: UnwrapRef 428 | readonly toRef: UnwrapRef 429 | readonly toRefs: UnwrapRef 430 | readonly toValue: UnwrapRef 431 | readonly toggleDark: UnwrapRef 432 | readonly triggerRef: UnwrapRef 433 | readonly tryOnBeforeMount: UnwrapRef 434 | readonly tryOnBeforeUnmount: UnwrapRef 435 | readonly tryOnMounted: UnwrapRef 436 | readonly tryOnScopeDispose: UnwrapRef 437 | readonly tryOnUnmounted: UnwrapRef 438 | readonly unDetectVideo: UnwrapRef 439 | readonly unref: UnwrapRef 440 | readonly unrefElement: UnwrapRef 441 | readonly until: UnwrapRef 442 | readonly useActiveElement: UnwrapRef 443 | readonly useAnimate: UnwrapRef 444 | readonly useArrayDifference: UnwrapRef 445 | readonly useArrayEvery: UnwrapRef 446 | readonly useArrayFilter: UnwrapRef 447 | readonly useArrayFind: UnwrapRef 448 | readonly useArrayFindIndex: UnwrapRef 449 | readonly useArrayFindLast: UnwrapRef 450 | readonly useArrayIncludes: UnwrapRef 451 | readonly useArrayJoin: UnwrapRef 452 | readonly useArrayMap: UnwrapRef 453 | readonly useArrayReduce: UnwrapRef 454 | readonly useArraySome: UnwrapRef 455 | readonly useArrayUnique: UnwrapRef 456 | readonly useAsyncQueue: UnwrapRef 457 | readonly useAsyncState: UnwrapRef 458 | readonly useAttrs: UnwrapRef 459 | readonly useBase64: UnwrapRef 460 | readonly useBattery: UnwrapRef 461 | readonly useBluetooth: UnwrapRef 462 | readonly useBreakpoints: UnwrapRef 463 | readonly useBroadcastChannel: UnwrapRef 464 | readonly useBrowserLocation: UnwrapRef 465 | readonly useCached: UnwrapRef 466 | readonly useClipboard: UnwrapRef 467 | readonly useClipboardItems: UnwrapRef 468 | readonly useCloned: UnwrapRef 469 | readonly useColorMode: UnwrapRef 470 | readonly useConfirmDialog: UnwrapRef 471 | readonly useCounter: UnwrapRef 472 | readonly useCssModule: UnwrapRef 473 | readonly useCssVar: UnwrapRef 474 | readonly useCssVars: UnwrapRef 475 | readonly useCurrentElement: UnwrapRef 476 | readonly useCycleList: UnwrapRef 477 | readonly useDark: UnwrapRef 478 | readonly useDateFormat: UnwrapRef 479 | readonly useDebounce: UnwrapRef 480 | readonly useDebounceFn: UnwrapRef 481 | readonly useDebouncedRefHistory: UnwrapRef 482 | readonly useDeviceMotion: UnwrapRef 483 | readonly useDeviceOrientation: UnwrapRef 484 | readonly useDevicePixelRatio: UnwrapRef 485 | readonly useDevicesList: UnwrapRef 486 | readonly useDisplayMedia: UnwrapRef 487 | readonly useDocumentVisibility: UnwrapRef 488 | readonly useDraggable: UnwrapRef 489 | readonly useDropZone: UnwrapRef 490 | readonly useElementBounding: UnwrapRef 491 | readonly useElementByPoint: UnwrapRef 492 | readonly useElementHover: UnwrapRef 493 | readonly useElementSize: UnwrapRef 494 | readonly useElementVisibility: UnwrapRef 495 | readonly useEventBus: UnwrapRef 496 | readonly useEventListener: UnwrapRef 497 | readonly useEventSource: UnwrapRef 498 | readonly useEyeDropper: UnwrapRef 499 | readonly useFavicon: UnwrapRef 500 | readonly useFetch: UnwrapRef 501 | readonly useFileDialog: UnwrapRef 502 | readonly useFileSystemAccess: UnwrapRef 503 | readonly useFocus: UnwrapRef 504 | readonly useFocusWithin: UnwrapRef 505 | readonly useFps: UnwrapRef 506 | readonly useFullscreen: UnwrapRef 507 | readonly useGamepad: UnwrapRef 508 | readonly useGeolocation: UnwrapRef 509 | readonly useIdle: UnwrapRef 510 | readonly useImage: UnwrapRef 511 | readonly useInfiniteScroll: UnwrapRef 512 | readonly useIntersectionObserver: UnwrapRef 513 | readonly useInterval: UnwrapRef 514 | readonly useIntervalFn: UnwrapRef 515 | readonly useKeyModifier: UnwrapRef 516 | readonly useLastChanged: UnwrapRef 517 | readonly useLink: UnwrapRef 518 | readonly useLocalStorage: UnwrapRef 519 | readonly useMagicKeys: UnwrapRef 520 | readonly useManualRefHistory: UnwrapRef 521 | readonly useMediaControls: UnwrapRef 522 | readonly useMediaQuery: UnwrapRef 523 | readonly useMemoize: UnwrapRef 524 | readonly useMemory: UnwrapRef 525 | readonly useMounted: UnwrapRef 526 | readonly useMouse: UnwrapRef 527 | readonly useMouseInElement: UnwrapRef 528 | readonly useMousePressed: UnwrapRef 529 | readonly useMutationObserver: UnwrapRef 530 | readonly useNavigatorLanguage: UnwrapRef 531 | readonly useNetwork: UnwrapRef 532 | readonly useNow: UnwrapRef 533 | readonly useObjectUrl: UnwrapRef 534 | readonly useOffsetPagination: UnwrapRef 535 | readonly useOnline: UnwrapRef 536 | readonly usePageLeave: UnwrapRef 537 | readonly useParallax: UnwrapRef 538 | readonly useParentElement: UnwrapRef 539 | readonly usePerformanceObserver: UnwrapRef 540 | readonly usePermission: UnwrapRef 541 | readonly usePointer: UnwrapRef 542 | readonly usePointerLock: UnwrapRef 543 | readonly usePointerSwipe: UnwrapRef 544 | readonly usePreferredColorScheme: UnwrapRef 545 | readonly usePreferredContrast: UnwrapRef 546 | readonly usePreferredDark: UnwrapRef 547 | readonly usePreferredLanguages: UnwrapRef 548 | readonly usePreferredReducedMotion: UnwrapRef 549 | readonly usePrevious: UnwrapRef 550 | readonly useRafFn: UnwrapRef 551 | readonly useRefHistory: UnwrapRef 552 | readonly useResizeObserver: UnwrapRef 553 | readonly useRoute: UnwrapRef 554 | readonly useRouter: UnwrapRef 555 | readonly useScreenOrientation: UnwrapRef 556 | readonly useScreenSafeArea: UnwrapRef 557 | readonly useScriptTag: UnwrapRef 558 | readonly useScroll: UnwrapRef 559 | readonly useScrollLock: UnwrapRef 560 | readonly useSessionStorage: UnwrapRef 561 | readonly useShare: UnwrapRef 562 | readonly useSlots: UnwrapRef 563 | readonly useSorted: UnwrapRef 564 | readonly useSpeechRecognition: UnwrapRef 565 | readonly useSpeechSynthesis: UnwrapRef 566 | readonly useStepper: UnwrapRef 567 | readonly useStorage: UnwrapRef 568 | readonly useStorageAsync: UnwrapRef 569 | readonly useStyleTag: UnwrapRef 570 | readonly useSupported: UnwrapRef 571 | readonly useSwipe: UnwrapRef 572 | readonly useTemplateRefsList: UnwrapRef 573 | readonly useTextDirection: UnwrapRef 574 | readonly useTextSelection: UnwrapRef 575 | readonly useTextareaAutosize: UnwrapRef 576 | readonly useThrottle: UnwrapRef 577 | readonly useThrottleFn: UnwrapRef 578 | readonly useThrottledRefHistory: UnwrapRef 579 | readonly useTimeAgo: UnwrapRef 580 | readonly useTimeout: UnwrapRef 581 | readonly useTimeoutFn: UnwrapRef 582 | readonly useTimeoutPoll: UnwrapRef 583 | readonly useTimestamp: UnwrapRef 584 | readonly useTitle: UnwrapRef 585 | readonly useToNumber: UnwrapRef 586 | readonly useToString: UnwrapRef 587 | readonly useToggle: UnwrapRef 588 | readonly useTransition: UnwrapRef 589 | readonly useUrlSearchParams: UnwrapRef 590 | readonly useUserMedia: UnwrapRef 591 | readonly useVModel: UnwrapRef 592 | readonly useVModels: UnwrapRef 593 | readonly useVibrate: UnwrapRef 594 | readonly useVirtualList: UnwrapRef 595 | readonly useWakeLock: UnwrapRef 596 | readonly useWebNotification: UnwrapRef 597 | readonly useWebSocket: UnwrapRef 598 | readonly useWebWorker: UnwrapRef 599 | readonly useWebWorkerFn: UnwrapRef 600 | readonly useWindowFocus: UnwrapRef 601 | readonly useWindowScroll: UnwrapRef 602 | readonly useWindowSize: UnwrapRef 603 | readonly watch: UnwrapRef 604 | readonly watchArray: UnwrapRef 605 | readonly watchAtMost: UnwrapRef 606 | readonly watchDebounced: UnwrapRef 607 | readonly watchDeep: UnwrapRef 608 | readonly watchEffect: UnwrapRef 609 | readonly watchIgnorable: UnwrapRef 610 | readonly watchImmediate: UnwrapRef 611 | readonly watchOnce: UnwrapRef 612 | readonly watchPausable: UnwrapRef 613 | readonly watchPostEffect: UnwrapRef 614 | readonly watchSyncEffect: UnwrapRef 615 | readonly watchThrottled: UnwrapRef 616 | readonly watchTriggerable: UnwrapRef 617 | readonly watchWithFilter: UnwrapRef 618 | readonly whenever: UnwrapRef 619 | } 620 | } 621 | declare module '@vue/runtime-core' { 622 | interface ComponentCustomProperties { 623 | readonly $$: UnwrapRef 624 | readonly $: UnwrapRef 625 | readonly $computed: UnwrapRef 626 | readonly $customRef: UnwrapRef 627 | readonly $ref: UnwrapRef 628 | readonly $shallowRef: UnwrapRef 629 | readonly $toRef: UnwrapRef 630 | readonly EffectScope: UnwrapRef 631 | readonly asyncComputed: UnwrapRef 632 | readonly autoResetRef: UnwrapRef 633 | readonly computed: UnwrapRef 634 | readonly computedAsync: UnwrapRef 635 | readonly computedEager: UnwrapRef 636 | readonly computedInject: UnwrapRef 637 | readonly computedWithControl: UnwrapRef 638 | readonly controlledComputed: UnwrapRef 639 | readonly controlledRef: UnwrapRef 640 | readonly createApp: UnwrapRef 641 | readonly createEventHook: UnwrapRef 642 | readonly createGlobalState: UnwrapRef 643 | readonly createInjectionState: UnwrapRef 644 | readonly createReactiveFn: UnwrapRef 645 | readonly createReusableTemplate: UnwrapRef 646 | readonly createSharedComposable: UnwrapRef 647 | readonly createTemplatePromise: UnwrapRef 648 | readonly createUnrefFn: UnwrapRef 649 | readonly customRef: UnwrapRef 650 | readonly debouncedRef: UnwrapRef 651 | readonly debouncedWatch: UnwrapRef 652 | readonly defineAsyncComponent: UnwrapRef 653 | readonly defineComponent: UnwrapRef 654 | readonly detect: UnwrapRef 655 | readonly detectVideo: UnwrapRef 656 | readonly eagerComputed: UnwrapRef 657 | readonly effectScope: UnwrapRef 658 | readonly extendRef: UnwrapRef 659 | readonly getCurrentInstance: UnwrapRef 660 | readonly getCurrentScope: UnwrapRef 661 | readonly globalActiveKey: UnwrapRef 662 | readonly h: UnwrapRef 663 | readonly ignorableWatch: UnwrapRef 664 | readonly initNet: UnwrapRef 665 | readonly inject: UnwrapRef 666 | readonly injectLocal: UnwrapRef 667 | readonly inputShape: UnwrapRef 668 | readonly isDark: UnwrapRef 669 | readonly isDefined: UnwrapRef 670 | readonly isProxy: UnwrapRef 671 | readonly isReactive: UnwrapRef 672 | readonly isReadonly: UnwrapRef 673 | readonly isRef: UnwrapRef 674 | readonly loadTfModels: UnwrapRef 675 | readonly makeDestructurable: UnwrapRef 676 | readonly markRaw: UnwrapRef 677 | readonly model: UnwrapRef 678 | readonly modelName: UnwrapRef 679 | readonly nextTick: UnwrapRef 680 | readonly onActivated: UnwrapRef 681 | readonly onBeforeMount: UnwrapRef 682 | readonly onBeforeRouteLeave: UnwrapRef 683 | readonly onBeforeRouteUpdate: UnwrapRef 684 | readonly onBeforeUnmount: UnwrapRef 685 | readonly onBeforeUpdate: UnwrapRef 686 | readonly onClickOutside: UnwrapRef 687 | readonly onDeactivated: UnwrapRef 688 | readonly onErrorCaptured: UnwrapRef 689 | readonly onKeyStroke: UnwrapRef 690 | readonly onLongPress: UnwrapRef 691 | readonly onMounted: UnwrapRef 692 | readonly onRenderTracked: UnwrapRef 693 | readonly onRenderTriggered: UnwrapRef 694 | readonly onScopeDispose: UnwrapRef 695 | readonly onServerPrefetch: UnwrapRef 696 | readonly onStartTyping: UnwrapRef 697 | readonly onUnmounted: UnwrapRef 698 | readonly onUpdated: UnwrapRef 699 | readonly pausableWatch: UnwrapRef 700 | readonly provide: UnwrapRef 701 | readonly provideLocal: UnwrapRef 702 | readonly reactify: UnwrapRef 703 | readonly reactifyObject: UnwrapRef 704 | readonly reactive: UnwrapRef 705 | readonly reactiveComputed: UnwrapRef 706 | readonly reactiveOmit: UnwrapRef 707 | readonly reactivePick: UnwrapRef 708 | readonly readonly: UnwrapRef 709 | readonly ref: UnwrapRef 710 | readonly refAutoReset: UnwrapRef 711 | readonly refDebounced: UnwrapRef 712 | readonly refDefault: UnwrapRef 713 | readonly refThrottled: UnwrapRef 714 | readonly refWithControl: UnwrapRef 715 | readonly resolveComponent: UnwrapRef 716 | readonly resolveRef: UnwrapRef 717 | readonly resolveUnref: UnwrapRef 718 | readonly shallowReactive: UnwrapRef 719 | readonly shallowReadonly: UnwrapRef 720 | readonly shallowRef: UnwrapRef 721 | readonly syncRef: UnwrapRef 722 | readonly syncRefs: UnwrapRef 723 | readonly templateRef: UnwrapRef 724 | readonly tf: UnwrapRef 725 | readonly tfjsLoading: UnwrapRef 726 | readonly tfjsProgress: UnwrapRef 727 | readonly tfjsSpinTip: UnwrapRef 728 | readonly throttledRef: UnwrapRef 729 | readonly throttledWatch: UnwrapRef 730 | readonly toRaw: UnwrapRef 731 | readonly toReactive: UnwrapRef 732 | readonly toRef: UnwrapRef 733 | readonly toRefs: UnwrapRef 734 | readonly toValue: UnwrapRef 735 | readonly toggleDark: UnwrapRef 736 | readonly triggerRef: UnwrapRef 737 | readonly tryOnBeforeMount: UnwrapRef 738 | readonly tryOnBeforeUnmount: UnwrapRef 739 | readonly tryOnMounted: UnwrapRef 740 | readonly tryOnScopeDispose: UnwrapRef 741 | readonly tryOnUnmounted: UnwrapRef 742 | readonly unDetectVideo: UnwrapRef 743 | readonly unref: UnwrapRef 744 | readonly unrefElement: UnwrapRef 745 | readonly until: UnwrapRef 746 | readonly useActiveElement: UnwrapRef 747 | readonly useAnimate: UnwrapRef 748 | readonly useArrayDifference: UnwrapRef 749 | readonly useArrayEvery: UnwrapRef 750 | readonly useArrayFilter: UnwrapRef 751 | readonly useArrayFind: UnwrapRef 752 | readonly useArrayFindIndex: UnwrapRef 753 | readonly useArrayFindLast: UnwrapRef 754 | readonly useArrayIncludes: UnwrapRef 755 | readonly useArrayJoin: UnwrapRef 756 | readonly useArrayMap: UnwrapRef 757 | readonly useArrayReduce: UnwrapRef 758 | readonly useArraySome: UnwrapRef 759 | readonly useArrayUnique: UnwrapRef 760 | readonly useAsyncQueue: UnwrapRef 761 | readonly useAsyncState: UnwrapRef 762 | readonly useAttrs: UnwrapRef 763 | readonly useBase64: UnwrapRef 764 | readonly useBattery: UnwrapRef 765 | readonly useBluetooth: UnwrapRef 766 | readonly useBreakpoints: UnwrapRef 767 | readonly useBroadcastChannel: UnwrapRef 768 | readonly useBrowserLocation: UnwrapRef 769 | readonly useCached: UnwrapRef 770 | readonly useClipboard: UnwrapRef 771 | readonly useClipboardItems: UnwrapRef 772 | readonly useCloned: UnwrapRef 773 | readonly useColorMode: UnwrapRef 774 | readonly useConfirmDialog: UnwrapRef 775 | readonly useCounter: UnwrapRef 776 | readonly useCssModule: UnwrapRef 777 | readonly useCssVar: UnwrapRef 778 | readonly useCssVars: UnwrapRef 779 | readonly useCurrentElement: UnwrapRef 780 | readonly useCycleList: UnwrapRef 781 | readonly useDark: UnwrapRef 782 | readonly useDateFormat: UnwrapRef 783 | readonly useDebounce: UnwrapRef 784 | readonly useDebounceFn: UnwrapRef 785 | readonly useDebouncedRefHistory: UnwrapRef 786 | readonly useDeviceMotion: UnwrapRef 787 | readonly useDeviceOrientation: UnwrapRef 788 | readonly useDevicePixelRatio: UnwrapRef 789 | readonly useDevicesList: UnwrapRef 790 | readonly useDisplayMedia: UnwrapRef 791 | readonly useDocumentVisibility: UnwrapRef 792 | readonly useDraggable: UnwrapRef 793 | readonly useDropZone: UnwrapRef 794 | readonly useElementBounding: UnwrapRef 795 | readonly useElementByPoint: UnwrapRef 796 | readonly useElementHover: UnwrapRef 797 | readonly useElementSize: UnwrapRef 798 | readonly useElementVisibility: UnwrapRef 799 | readonly useEventBus: UnwrapRef 800 | readonly useEventListener: UnwrapRef 801 | readonly useEventSource: UnwrapRef 802 | readonly useEyeDropper: UnwrapRef 803 | readonly useFavicon: UnwrapRef 804 | readonly useFetch: UnwrapRef 805 | readonly useFileDialog: UnwrapRef 806 | readonly useFileSystemAccess: UnwrapRef 807 | readonly useFocus: UnwrapRef 808 | readonly useFocusWithin: UnwrapRef 809 | readonly useFps: UnwrapRef 810 | readonly useFullscreen: UnwrapRef 811 | readonly useGamepad: UnwrapRef 812 | readonly useGeolocation: UnwrapRef 813 | readonly useIdle: UnwrapRef 814 | readonly useImage: UnwrapRef 815 | readonly useInfiniteScroll: UnwrapRef 816 | readonly useIntersectionObserver: UnwrapRef 817 | readonly useInterval: UnwrapRef 818 | readonly useIntervalFn: UnwrapRef 819 | readonly useKeyModifier: UnwrapRef 820 | readonly useLastChanged: UnwrapRef 821 | readonly useLink: UnwrapRef 822 | readonly useLocalStorage: UnwrapRef 823 | readonly useMagicKeys: UnwrapRef 824 | readonly useManualRefHistory: UnwrapRef 825 | readonly useMediaControls: UnwrapRef 826 | readonly useMediaQuery: UnwrapRef 827 | readonly useMemoize: UnwrapRef 828 | readonly useMemory: UnwrapRef 829 | readonly useMounted: UnwrapRef 830 | readonly useMouse: UnwrapRef 831 | readonly useMouseInElement: UnwrapRef 832 | readonly useMousePressed: UnwrapRef 833 | readonly useMutationObserver: UnwrapRef 834 | readonly useNavigatorLanguage: UnwrapRef 835 | readonly useNetwork: UnwrapRef 836 | readonly useNow: UnwrapRef 837 | readonly useObjectUrl: UnwrapRef 838 | readonly useOffsetPagination: UnwrapRef 839 | readonly useOnline: UnwrapRef 840 | readonly usePageLeave: UnwrapRef 841 | readonly useParallax: UnwrapRef 842 | readonly useParentElement: UnwrapRef 843 | readonly usePerformanceObserver: UnwrapRef 844 | readonly usePermission: UnwrapRef 845 | readonly usePointer: UnwrapRef 846 | readonly usePointerLock: UnwrapRef 847 | readonly usePointerSwipe: UnwrapRef 848 | readonly usePreferredColorScheme: UnwrapRef 849 | readonly usePreferredContrast: UnwrapRef 850 | readonly usePreferredDark: UnwrapRef 851 | readonly usePreferredLanguages: UnwrapRef 852 | readonly usePreferredReducedMotion: UnwrapRef 853 | readonly usePrevious: UnwrapRef 854 | readonly useRafFn: UnwrapRef 855 | readonly useRefHistory: UnwrapRef 856 | readonly useResizeObserver: UnwrapRef 857 | readonly useRoute: UnwrapRef 858 | readonly useRouter: UnwrapRef 859 | readonly useScreenOrientation: UnwrapRef 860 | readonly useScreenSafeArea: UnwrapRef 861 | readonly useScriptTag: UnwrapRef 862 | readonly useScroll: UnwrapRef 863 | readonly useScrollLock: UnwrapRef 864 | readonly useSessionStorage: UnwrapRef 865 | readonly useShare: UnwrapRef 866 | readonly useSlots: UnwrapRef 867 | readonly useSorted: UnwrapRef 868 | readonly useSpeechRecognition: UnwrapRef 869 | readonly useSpeechSynthesis: UnwrapRef 870 | readonly useStepper: UnwrapRef 871 | readonly useStorage: UnwrapRef 872 | readonly useStorageAsync: UnwrapRef 873 | readonly useStyleTag: UnwrapRef 874 | readonly useSupported: UnwrapRef 875 | readonly useSwipe: UnwrapRef 876 | readonly useTemplateRefsList: UnwrapRef 877 | readonly useTextDirection: UnwrapRef 878 | readonly useTextSelection: UnwrapRef 879 | readonly useTextareaAutosize: UnwrapRef 880 | readonly useThrottle: UnwrapRef 881 | readonly useThrottleFn: UnwrapRef 882 | readonly useThrottledRefHistory: UnwrapRef 883 | readonly useTimeAgo: UnwrapRef 884 | readonly useTimeout: UnwrapRef 885 | readonly useTimeoutFn: UnwrapRef 886 | readonly useTimeoutPoll: UnwrapRef 887 | readonly useTimestamp: UnwrapRef 888 | readonly useTitle: UnwrapRef 889 | readonly useToNumber: UnwrapRef 890 | readonly useToString: UnwrapRef 891 | readonly useToggle: UnwrapRef 892 | readonly useTransition: UnwrapRef 893 | readonly useUrlSearchParams: UnwrapRef 894 | readonly useUserMedia: UnwrapRef 895 | readonly useVModel: UnwrapRef 896 | readonly useVModels: UnwrapRef 897 | readonly useVibrate: UnwrapRef 898 | readonly useVirtualList: UnwrapRef 899 | readonly useWakeLock: UnwrapRef 900 | readonly useWebNotification: UnwrapRef 901 | readonly useWebSocket: UnwrapRef 902 | readonly useWebWorker: UnwrapRef 903 | readonly useWebWorkerFn: UnwrapRef 904 | readonly useWindowFocus: UnwrapRef 905 | readonly useWindowScroll: UnwrapRef 906 | readonly useWindowSize: UnwrapRef 907 | readonly watch: UnwrapRef 908 | readonly watchArray: UnwrapRef 909 | readonly watchAtMost: UnwrapRef 910 | readonly watchDebounced: UnwrapRef 911 | readonly watchDeep: UnwrapRef 912 | readonly watchEffect: UnwrapRef 913 | readonly watchIgnorable: UnwrapRef 914 | readonly watchImmediate: UnwrapRef 915 | readonly watchOnce: UnwrapRef 916 | readonly watchPausable: UnwrapRef 917 | readonly watchPostEffect: UnwrapRef 918 | readonly watchSyncEffect: UnwrapRef 919 | readonly watchThrottled: UnwrapRef 920 | readonly watchTriggerable: UnwrapRef 921 | readonly watchWithFilter: UnwrapRef 922 | readonly whenever: UnwrapRef 923 | } 924 | } 925 | --------------------------------------------------------------------------------