diff --git a/packages/client/src/widgets/activity.calendar.vue b/packages/client/src/widgets/activity.calendar.vue
index b833bd65c..2388edefc 100644
--- a/packages/client/src/widgets/activity.calendar.vue
+++ b/packages/client/src/widgets/activity.calendar.vue
@@ -23,45 +23,41 @@
 </svg>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as os from '@/os';
+<script lang="ts" setup>
+const props = defineProps<{
+	activity: any[]
+}>();
 
-export default defineComponent({
-	props: ['data'],
-	created() {
-		for (const d of this.data) {
-			d.total = d.notes + d.replies + d.renotes;
-		}
-		const peak = Math.max.apply(null, this.data.map(d => d.total));
+for (const d of props.activity) {
+	d.total = d.notes + d.replies + d.renotes;
+}
+const peak = Math.max(...props.activity.map(d => d.total));
 
-		const now = new Date();
-		const year = now.getFullYear();
-		const month = now.getMonth();
-		const day = now.getDate();
+const now = new Date();
+const year = now.getFullYear();
+const month = now.getMonth();
+const day = now.getDate();
 
-		let x = 20;
-		this.data.slice().forEach((d, i) => {
-			d.x = x;
+let x = 20;
+props.activity.slice().forEach((d, i) => {
+	d.x = x;
 
-			const date = new Date(year, month, day - i);
-			d.date = {
-				year: date.getFullYear(),
-				month: date.getMonth(),
-				day: date.getDate(),
-				weekday: date.getDay()
-			};
+	const date = new Date(year, month, day - i);
+	d.date = {
+		year: date.getFullYear(),
+		month: date.getMonth(),
+		day: date.getDate(),
+		weekday: date.getDay()
+	};
 
-			d.v = peak === 0 ? 0 : d.total / (peak / 2);
-			if (d.v > 1) d.v = 1;
-			const ch = d.date.weekday === 0 || d.date.weekday === 6 ? 275 : 170;
-			const cs = d.v * 100;
-			const cl = 15 + ((1 - d.v) * 80);
-			d.color = `hsl(${ch}, ${cs}%, ${cl}%)`;
+	d.v = peak === 0 ? 0 : d.total / (peak / 2);
+	if (d.v > 1) d.v = 1;
+	const ch = d.date.weekday === 0 || d.date.weekday === 6 ? 275 : 170;
+	const cs = d.v * 100;
+	const cl = 15 + ((1 - d.v) * 80);
+	d.color = `hsl(${ch}, ${cs}%, ${cl}%)`;
 
-			if (d.date.weekday === 0) x--;
-		});
-	}
+	if (d.date.weekday === 0) x--;
 });
 </script>
 
diff --git a/packages/client/src/widgets/activity.chart.vue b/packages/client/src/widgets/activity.chart.vue
index 9702d6666..b7db2af58 100644
--- a/packages/client/src/widgets/activity.chart.vue
+++ b/packages/client/src/widgets/activity.chart.vue
@@ -24,9 +24,19 @@
 </svg>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-import * as os from '@/os';
+<script lang="ts" setup>
+const props = defineProps<{
+	activity: any[]
+}>();
+
+let viewBoxX: number = $ref(147);
+let viewBoxY: number = $ref(60);
+let zoom: number = $ref(1);
+let pos: number = $ref(0);
+let pointsNote: any = $ref(null);
+let pointsReply: any = $ref(null);
+let pointsRenote: any = $ref(null);
+let pointsTotal: any = $ref(null);
 
 function dragListen(fn) {
 	window.addEventListener('mousemove',  fn);
@@ -40,60 +50,35 @@ function dragClear(fn) {
 	window.removeEventListener('mouseup',    dragClear);
 }
 
-export default defineComponent({
-	props: ['data'],
-	data() {
-		return {
-			viewBoxX: 147,
-			viewBoxY: 60,
-			zoom: 1,
-			pos: 0,
-			pointsNote: null,
-			pointsReply: null,
-			pointsRenote: null,
-			pointsTotal: null
-		};
-	},
-	created() {
-		for (const d of this.data) {
-			d.total = d.notes + d.replies + d.renotes;
-		}
+function onMousedown(ev) {
+	const clickX = ev.clientX;
+	const clickY = ev.clientY;
+	const baseZoom = zoom;
+	const basePos = pos;
 
-		this.render();
-	},
-	methods: {
-		render() {
-			const peak = Math.max.apply(null, this.data.map(d => d.total));
-			if (peak != 0) {
-				const data = this.data.slice().reverse();
-				this.pointsNote = data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.notes / peak)) * this.viewBoxY}`).join(' ');
-				this.pointsReply = data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * this.viewBoxY}`).join(' ');
-				this.pointsRenote = data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.renotes / peak)) * this.viewBoxY}`).join(' ');
-				this.pointsTotal = data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / peak)) * this.viewBoxY}`).join(' ');
-			}
-		},
-		onMousedown(e) {
-			const clickX = e.clientX;
-			const clickY = e.clientY;
-			const baseZoom = this.zoom;
-			const basePos = this.pos;
+	// 動かした時
+	dragListen(me => {
+		let moveLeft = me.clientX - clickX;
+		let moveTop = me.clientY - clickY;
 
-			// 動かした時
-			dragListen(me => {
-				let moveLeft = me.clientX - clickX;
-				let moveTop = me.clientY - clickY;
+		zoom = Math.max(1, baseZoom + (-moveTop / 20));
+		pos = Math.min(0, basePos + moveLeft);
+		if (pos < -(((props.activity.length - 1) * zoom) - viewBoxX)) pos = -(((props.activity.length - 1) * zoom) - viewBoxX);
 
-				this.zoom = baseZoom + (-moveTop / 20);
-				this.pos = basePos + moveLeft;
-				if (this.zoom < 1) this.zoom = 1;
-				if (this.pos > 0) this.pos = 0;
-				if (this.pos < -(((this.data.length - 1) * this.zoom) - this.viewBoxX)) this.pos = -(((this.data.length - 1) * this.zoom) - this.viewBoxX);
+		render();
+	});
+}
 
-				this.render();
-			});
-		}
+function render() {
+	const peak = Math.max(...props.activity.map(d => d.total));
+	if (peak !== 0) {
+		const activity = props.activity.slice().reverse();
+		pointsNote = activity.map((d, i) => `${(i * zoom) + pos},${(1 - (d.notes / peak)) * viewBoxY}`).join(' ');
+		pointsReply = activity.map((d, i) => `${(i * zoom) + pos},${(1 - (d.replies / peak)) * viewBoxY}`).join(' ');
+		pointsRenote = activity.map((d, i) => `${(i * zoom) + pos},${(1 - (d.renotes / peak)) * viewBoxY}`).join(' ');
+		pointsTotal = activity.map((d, i) => `${(i * zoom) + pos},${(1 - (d.total / peak)) * viewBoxY}`).join(' ');
 	}
-});
+}
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/widgets/activity.vue b/packages/client/src/widgets/activity.vue
index acbbb7a97..631beceb7 100644
--- a/packages/client/src/widgets/activity.vue
+++ b/packages/client/src/widgets/activity.vue
@@ -6,8 +6,8 @@
 	<div>
 		<MkLoading v-if="fetching"/>
 		<template v-else>
-			<XCalendar v-show="widgetProps.view === 0" :data="[].concat(activity)"/>
-			<XChart v-show="widgetProps.view === 1" :data="[].concat(activity)"/>
+			<XCalendar v-show="widgetProps.view === 0" :activity="[].concat(activity)"/>
+			<XChart v-show="widgetProps.view === 1" :activity="[].concat(activity)"/>
 		</template>
 	</div>
 </MkContainer>
@@ -47,7 +47,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure, save } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/aichan.vue b/packages/client/src/widgets/aichan.vue
index 03e394b97..70e47f2af 100644
--- a/packages/client/src/widgets/aichan.vue
+++ b/packages/client/src/widgets/aichan.vue
@@ -24,7 +24,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/aiscript.vue b/packages/client/src/widgets/aiscript.vue
index 0a5c0d614..b74e2258a 100644
--- a/packages/client/src/widgets/aiscript.vue
+++ b/packages/client/src/widgets/aiscript.vue
@@ -43,7 +43,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
@@ -94,7 +94,7 @@ const run = async () => {
 	let ast;
 	try {
 		ast = parse(widgetProps.script);
-	} catch (e) {
+	} catch (err) {
 		os.alert({
 			type: 'error',
 			text: 'Syntax error :(',
@@ -103,10 +103,10 @@ const run = async () => {
 	}
 	try {
 		await aiscript.exec(ast);
-	} catch (e) {
+	} catch (err) {
 		os.alert({
 			type: 'error',
-			text: e,
+			text: err,
 		});
 	}
 };
diff --git a/packages/client/src/widgets/button.vue b/packages/client/src/widgets/button.vue
index a33afd6e7..ee4e9c642 100644
--- a/packages/client/src/widgets/button.vue
+++ b/packages/client/src/widgets/button.vue
@@ -40,7 +40,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
@@ -73,7 +73,7 @@ const run = async () => {
 	let ast;
 	try {
 		ast = parse(widgetProps.script);
-	} catch (e) {
+	} catch (err) {
 		os.alert({
 			type: 'error',
 			text: 'Syntax error :(',
@@ -82,10 +82,10 @@ const run = async () => {
 	}
 	try {
 		await aiscript.exec(ast);
-	} catch (e) {
+	} catch (err) {
 		os.alert({
 			type: 'error',
-			text: e,
+			text: err,
 		});
 	}
 };
diff --git a/packages/client/src/widgets/calendar.vue b/packages/client/src/widgets/calendar.vue
index c6a69b3fb..2a2b03554 100644
--- a/packages/client/src/widgets/calendar.vue
+++ b/packages/client/src/widgets/calendar.vue
@@ -53,7 +53,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/clock.vue b/packages/client/src/widgets/clock.vue
index 6acb10d74..0a35c4c5a 100644
--- a/packages/client/src/widgets/clock.vue
+++ b/packages/client/src/widgets/clock.vue
@@ -39,7 +39,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/digital-clock.vue b/packages/client/src/widgets/digital-clock.vue
index 62f052a69..a17ed040c 100644
--- a/packages/client/src/widgets/digital-clock.vue
+++ b/packages/client/src/widgets/digital-clock.vue
@@ -41,7 +41,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/federation.vue b/packages/client/src/widgets/federation.vue
index 5f1131dce..1bfb068a2 100644
--- a/packages/client/src/widgets/federation.vue
+++ b/packages/client/src/widgets/federation.vue
@@ -41,7 +41,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps> & { foldable?: boolean; scrollable?: boolean; }>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; foldable?: boolean; scrollable?: boolean; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/job-queue.vue b/packages/client/src/widgets/job-queue.vue
index 4a2a3cf23..8897f240b 100644
--- a/packages/client/src/widgets/job-queue.vue
+++ b/packages/client/src/widgets/job-queue.vue
@@ -73,7 +73,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/memo.vue b/packages/client/src/widgets/memo.vue
index 450598f65..f2d1bbc04 100644
--- a/packages/client/src/widgets/memo.vue
+++ b/packages/client/src/widgets/memo.vue
@@ -32,7 +32,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/notifications.vue b/packages/client/src/widgets/notifications.vue
index 7f0055bb4..f51e983a0 100644
--- a/packages/client/src/widgets/notifications.vue
+++ b/packages/client/src/widgets/notifications.vue
@@ -41,7 +41,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure, save } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/online-users.vue b/packages/client/src/widgets/online-users.vue
index 1746a8314..eb3184fe9 100644
--- a/packages/client/src/widgets/online-users.vue
+++ b/packages/client/src/widgets/online-users.vue
@@ -27,7 +27,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/photos.vue b/packages/client/src/widgets/photos.vue
index 8f948dc64..8e3076529 100644
--- a/packages/client/src/widgets/photos.vue
+++ b/packages/client/src/widgets/photos.vue
@@ -43,7 +43,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/post-form.vue b/packages/client/src/widgets/post-form.vue
index 51aa8fcf6..5b74602c8 100644
--- a/packages/client/src/widgets/post-form.vue
+++ b/packages/client/src/widgets/post-form.vue
@@ -19,7 +19,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/rss.vue b/packages/client/src/widgets/rss.vue
index 9e2e50360..6b057cdd0 100644
--- a/packages/client/src/widgets/rss.vue
+++ b/packages/client/src/widgets/rss.vue
@@ -38,7 +38,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/server-metric/cpu-mem.vue b/packages/client/src/widgets/server-metric/cpu-mem.vue
index ad9e6a8b0..7cbc7fa15 100644
--- a/packages/client/src/widgets/server-metric/cpu-mem.vue
+++ b/packages/client/src/widgets/server-metric/cpu-mem.vue
@@ -69,79 +69,72 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { onMounted, onBeforeUnmount } from 'vue';
 import { v4 as uuid } from 'uuid';
 
-export default defineComponent({
-	props: {
-		connection: {
-			required: true,
-		},
-		meta: {
-			required: true,
-		}
-	},
-	data() {
-		return {
-			viewBoxX: 50,
-			viewBoxY: 30,
-			stats: [],
-			cpuGradientId: uuid(),
-			cpuMaskId: uuid(),
-			memGradientId: uuid(),
-			memMaskId: uuid(),
-			cpuPolylinePoints: '',
-			memPolylinePoints: '',
-			cpuPolygonPoints: '',
-			memPolygonPoints: '',
-			cpuHeadX: null,
-			cpuHeadY: null,
-			memHeadX: null,
-			memHeadY: null,
-			cpuP: '',
-			memP: ''
-		};
-	},
-	mounted() {
-		this.connection.on('stats', this.onStats);
-		this.connection.on('statsLog', this.onStatsLog);
-		this.connection.send('requestLog', {
-			id: Math.random().toString().substr(2, 8)
-		});
-	},
-	beforeUnmount() {
-		this.connection.off('stats', this.onStats);
-		this.connection.off('statsLog', this.onStatsLog);
-	},
-	methods: {
-		onStats(stats) {
-			this.stats.push(stats);
-			if (this.stats.length > 50) this.stats.shift();
+const props = defineProps<{
+	connection: any,
+	meta: any
+}>();
 
-			const cpuPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - s.cpu) * this.viewBoxY]);
-			const memPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - (s.mem.active / this.meta.mem.total)) * this.viewBoxY]);
-			this.cpuPolylinePoints = cpuPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
-			this.memPolylinePoints = memPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
+let viewBoxX: number = $ref(50);
+let viewBoxY: number = $ref(30);
+let stats: any[] = $ref([]);
+const cpuGradientId = uuid();
+const cpuMaskId = uuid();
+const memGradientId = uuid();
+const memMaskId = uuid();
+let cpuPolylinePoints: string = $ref('');
+let memPolylinePoints: string = $ref('');
+let cpuPolygonPoints: string = $ref('');
+let memPolygonPoints: string = $ref('');
+let cpuHeadX: any = $ref(null);
+let cpuHeadY: any = $ref(null);
+let memHeadX: any = $ref(null);
+let memHeadY: any = $ref(null);
+let cpuP: string = $ref('');
+let memP: string = $ref('');
 
-			this.cpuPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${this.viewBoxY} ${this.cpuPolylinePoints} ${this.viewBoxX},${this.viewBoxY}`;
-			this.memPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${this.viewBoxY} ${this.memPolylinePoints} ${this.viewBoxX},${this.viewBoxY}`;
-
-			this.cpuHeadX = cpuPolylinePoints[cpuPolylinePoints.length - 1][0];
-			this.cpuHeadY = cpuPolylinePoints[cpuPolylinePoints.length - 1][1];
-			this.memHeadX = memPolylinePoints[memPolylinePoints.length - 1][0];
-			this.memHeadY = memPolylinePoints[memPolylinePoints.length - 1][1];
-
-			this.cpuP = (stats.cpu * 100).toFixed(0);
-			this.memP = (stats.mem.active / this.meta.mem.total * 100).toFixed(0);
-		},
-		onStatsLog(statsLog) {
-			for (const stats of [...statsLog].reverse()) {
-				this.onStats(stats);
-			}
-		}
-	}
+onMounted(() => {
+	props.connection.on('stats', onStats);
+	props.connection.on('statsLog', onStatsLog);
+	props.connection.send('requestLog', {
+		id: Math.random().toString().substr(2, 8)
+	});
 });
+
+onBeforeUnmount(() => {
+	props.connection.off('stats', onStats);
+	props.connection.off('statsLog', onStatsLog);
+});
+
+function onStats(connStats) {
+	stats.push(connStats);
+	if (stats.length > 50) stats.shift();
+
+	let cpuPolylinePointsStats = stats.map((s, i) => [viewBoxX - ((stats.length - 1) - i), (1 - s.cpu) * viewBoxY]);
+	let memPolylinePointsStats = stats.map((s, i) => [viewBoxX - ((stats.length - 1) - i), (1 - (s.mem.active / props.meta.mem.total)) * viewBoxY]);
+	cpuPolylinePoints = cpuPolylinePointsStats.map(xy => `${xy[0]},${xy[1]}`).join(' ');
+	memPolylinePoints = memPolylinePointsStats.map(xy => `${xy[0]},${xy[1]}`).join(' ');
+
+	cpuPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${cpuPolylinePoints} ${viewBoxX},${viewBoxY}`;
+	memPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${memPolylinePoints} ${viewBoxX},${viewBoxY}`;
+
+	cpuHeadX = cpuPolylinePoints[cpuPolylinePoints.length - 1][0];
+	cpuHeadY = cpuPolylinePoints[cpuPolylinePoints.length - 1][1];
+	memHeadX = memPolylinePoints[memPolylinePoints.length - 1][0];
+	memHeadY = memPolylinePoints[memPolylinePoints.length - 1][1];
+
+	cpuP = (connStats.cpu * 100).toFixed(0);
+	memP = (connStats.mem.active / props.meta.mem.total * 100).toFixed(0);
+}
+
+function onStatsLog(statsLog) {
+	for (const revStats of [...statsLog].reverse()) {
+		onStats(revStats);
+	}
+}
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/widgets/server-metric/cpu.vue b/packages/client/src/widgets/server-metric/cpu.vue
index 4478ee306..baf802cb8 100644
--- a/packages/client/src/widgets/server-metric/cpu.vue
+++ b/packages/client/src/widgets/server-metric/cpu.vue
@@ -9,38 +9,27 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { onMounted, onBeforeUnmount } from 'vue';
 import XPie from './pie.vue';
 
-export default defineComponent({
-	components: {
-		XPie
-	},
-	props: {
-		connection: {
-			required: true,
-		},
-		meta: {
-			required: true,
-		}
-	},
-	data() {
-		return {
-			usage: 0,
-		};
-	},
-	mounted() {
-		this.connection.on('stats', this.onStats);
-	},
-	beforeUnmount() {
-		this.connection.off('stats', this.onStats);
-	},
-	methods: {
-		onStats(stats) {
-			this.usage = stats.cpu;
-		}
-	}
+const props = defineProps<{
+	connection: any,
+	meta: any
+}>();
+
+let usage: number = $ref(0);
+
+function onStats(stats) {
+	usage = stats.cpu;
+}
+
+onMounted(() => {
+	props.connection.on('stats', onStats);
+});
+
+onBeforeUnmount(() => {
+	props.connection.off('stats', onStats);
 });
 </script>
 
diff --git a/packages/client/src/widgets/server-metric/index.vue b/packages/client/src/widgets/server-metric/index.vue
index 2caa73fa7..9e86b811d 100644
--- a/packages/client/src/widgets/server-metric/index.vue
+++ b/packages/client/src/widgets/server-metric/index.vue
@@ -50,7 +50,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure, save } = useWidgetPropsManager(name,
 	widgetPropsDef,
@@ -65,7 +65,7 @@ os.api('server-info', {}).then(res => {
 });
 
 const toggleView = () => {
-	if (widgetProps.view == 4) {
+	if (widgetProps.view === 4) {
 		widgetProps.view = 0;
 	} else {
 		widgetProps.view++;
diff --git a/packages/client/src/widgets/server-metric/mem.vue b/packages/client/src/widgets/server-metric/mem.vue
index a6ca7b117..6018eb426 100644
--- a/packages/client/src/widgets/server-metric/mem.vue
+++ b/packages/client/src/widgets/server-metric/mem.vue
@@ -10,46 +10,34 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { onMounted, onBeforeUnmount } from 'vue';
 import XPie from './pie.vue';
 import bytes from '@/filters/bytes';
 
-export default defineComponent({
-	components: {
-		XPie
-	},
-	props: {
-		connection: {
-			required: true,
-		},
-		meta: {
-			required: true,
-		}
-	},
-	data() {
-		return {
-			usage: 0,
-			total: 0,
-			used: 0,
-			free: 0,
-		};
-	},
-	mounted() {
-		this.connection.on('stats', this.onStats);
-	},
-	beforeUnmount() {
-		this.connection.off('stats', this.onStats);
-	},
-	methods: {
-		onStats(stats) {
-			this.usage = stats.mem.active / this.meta.mem.total;
-			this.total = this.meta.mem.total;
-			this.used = stats.mem.active;
-			this.free = this.meta.mem.total - stats.mem.active;
-		},
-		bytes
-	}
+const props = defineProps<{
+	connection: any,
+	meta: any
+}>();
+
+let usage: number = $ref(0);
+let total: number = $ref(0);
+let used: number = $ref(0);
+let free: number = $ref(0);
+
+function onStats(stats) {
+	usage = stats.mem.active / props.meta.mem.total;
+	total = props.meta.mem.total;
+	used = stats.mem.active;
+	free = total - used;
+}
+
+onMounted(() => {
+	props.connection.on('stats', onStats);
+});
+
+onBeforeUnmount(() => {
+	props.connection.off('stats', onStats);
 });
 </script>
 
diff --git a/packages/client/src/widgets/server-metric/net.vue b/packages/client/src/widgets/server-metric/net.vue
index 23c148eeb..82b3a67d7 100644
--- a/packages/client/src/widgets/server-metric/net.vue
+++ b/packages/client/src/widgets/server-metric/net.vue
@@ -43,79 +43,71 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { onMounted, onBeforeUnmount } from 'vue';
 import bytes from '@/filters/bytes';
 
-export default defineComponent({
-	props: {
-		connection: {
-			required: true,
-		},
-		meta: {
-			required: true,
-		}
-	},
-	data() {
-		return {
-			viewBoxX: 50,
-			viewBoxY: 30,
-			stats: [],
-			inPolylinePoints: '',
-			outPolylinePoints: '',
-			inPolygonPoints: '',
-			outPolygonPoints: '',
-			inHeadX: null,
-			inHeadY: null,
-			outHeadX: null,
-			outHeadY: null,
-			inRecent: 0,
-			outRecent: 0
-		};
-	},
-	mounted() {
-		this.connection.on('stats', this.onStats);
-		this.connection.on('statsLog', this.onStatsLog);
-		this.connection.send('requestLog', {
-			id: Math.random().toString().substr(2, 8)
-		});
-	},
-	beforeUnmount() {
-		this.connection.off('stats', this.onStats);
-		this.connection.off('statsLog', this.onStatsLog);
-	},
-	methods: {
-		onStats(stats) {
-			this.stats.push(stats);
-			if (this.stats.length > 50) this.stats.shift();
+const props = defineProps<{
+	connection: any,
+	meta: any
+}>();
 
-			const inPeak = Math.max(1024 * 64, Math.max(...this.stats.map(s => s.net.rx)));
-			const outPeak = Math.max(1024 * 64, Math.max(...this.stats.map(s => s.net.tx)));
+let viewBoxX: number = $ref(50);
+let viewBoxY: number = $ref(30);
+let stats: any[] = $ref([]);
+let inPolylinePoints: string = $ref('');
+let outPolylinePoints: string = $ref('');
+let inPolygonPoints: string = $ref('');
+let outPolygonPoints: string = $ref('');
+let inHeadX: any = $ref(null);
+let inHeadY: any = $ref(null);
+let outHeadX: any = $ref(null);
+let outHeadY: any = $ref(null);
+let inRecent: number = $ref(0);
+let outRecent: number = $ref(0);
 
-			const inPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - (s.net.rx / inPeak)) * this.viewBoxY]);
-			const outPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - (s.net.tx / outPeak)) * this.viewBoxY]);
-			this.inPolylinePoints = inPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
-			this.outPolylinePoints = outPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
-
-			this.inPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${this.viewBoxY} ${this.inPolylinePoints} ${this.viewBoxX},${this.viewBoxY}`;
-			this.outPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${this.viewBoxY} ${this.outPolylinePoints} ${this.viewBoxX},${this.viewBoxY}`;
-
-			this.inHeadX = inPolylinePoints[inPolylinePoints.length - 1][0];
-			this.inHeadY = inPolylinePoints[inPolylinePoints.length - 1][1];
-			this.outHeadX = outPolylinePoints[outPolylinePoints.length - 1][0];
-			this.outHeadY = outPolylinePoints[outPolylinePoints.length - 1][1];
-
-			this.inRecent = stats.net.rx;
-			this.outRecent = stats.net.tx;
-		},
-		onStatsLog(statsLog) {
-			for (const stats of [...statsLog].reverse()) {
-				this.onStats(stats);
-			}
-		},
-		bytes
-	}
+onMounted(() => {
+	props.connection.on('stats', onStats);
+	props.connection.on('statsLog', onStatsLog);
+	props.connection.send('requestLog', {
+		id: Math.random().toString().substr(2, 8)
+	});
 });
+
+onBeforeUnmount(() => {
+	props.connection.off('stats', onStats);
+	props.connection.off('statsLog', onStatsLog);
+});
+
+function onStats(connStats) {
+	stats.push(connStats);
+	if (stats.length > 50) stats.shift();
+
+	const inPeak = Math.max(1024 * 64, Math.max(...stats.map(s => s.net.rx)));
+	const outPeak = Math.max(1024 * 64, Math.max(...stats.map(s => s.net.tx)));
+
+	let inPolylinePointsStats = stats.map((s, i) => [viewBoxX - ((stats.length - 1) - i), (1 - (s.net.rx / inPeak)) * viewBoxY]);
+	let outPolylinePointsStats = stats.map((s, i) => [viewBoxX - ((stats.length - 1) - i), (1 - (s.net.tx / outPeak)) * viewBoxY]);
+	inPolylinePoints = inPolylinePointsStats.map(xy => `${xy[0]},${xy[1]}`).join(' ');
+	outPolylinePoints = outPolylinePointsStats.map(xy => `${xy[0]},${xy[1]}`).join(' ');
+
+	inPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${inPolylinePoints} ${viewBoxX},${viewBoxY}`;
+	outPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${outPolylinePoints} ${viewBoxX},${viewBoxY}`;
+
+	inHeadX = inPolylinePoints[inPolylinePoints.length - 1][0];
+	inHeadY = inPolylinePoints[inPolylinePoints.length - 1][1];
+	outHeadX = outPolylinePoints[outPolylinePoints.length - 1][0];
+	outHeadY = outPolylinePoints[outPolylinePoints.length - 1][1];
+
+	inRecent = connStats.net.rx;
+	outRecent = connStats.net.tx;
+}
+
+function onStatsLog(statsLog) {
+	for (const revStats of [...statsLog].reverse()) {
+		onStats(revStats);
+	}
+}
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/widgets/slideshow.vue b/packages/client/src/widgets/slideshow.vue
index 7b2e53968..1b6c2d766 100644
--- a/packages/client/src/widgets/slideshow.vue
+++ b/packages/client/src/widgets/slideshow.vue
@@ -37,7 +37,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure, save } = useWidgetPropsManager(name,
 	widgetPropsDef,
@@ -51,7 +51,7 @@ const slideA = ref<HTMLElement>();
 const slideB = ref<HTMLElement>();
 
 const change = () => {
-	if (images.value.length == 0) return;
+	if (images.value.length === 0) return;
 
 	const index = Math.floor(Math.random() * images.value.length);
 	const img = `url(${ images.value[index].url })`;
diff --git a/packages/client/src/widgets/timeline.vue b/packages/client/src/widgets/timeline.vue
index 34e3b20e3..c9a9e68bb 100644
--- a/packages/client/src/widgets/timeline.vue
+++ b/packages/client/src/widgets/timeline.vue
@@ -63,7 +63,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure, save } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/trends.vue b/packages/client/src/widgets/trends.vue
index a34710eae..34bbc16a8 100644
--- a/packages/client/src/widgets/trends.vue
+++ b/packages/client/src/widgets/trends.vue
@@ -40,7 +40,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 //const props = defineProps<WidgetComponentProps<WidgetProps>>();
 //const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
 const props = defineProps<{ widget?: Widget<WidgetProps>; }>();
-const emit = defineEmits<{ (e: 'updateProps', props: WidgetProps); }>();
+const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>();
 
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
diff --git a/packages/client/src/widgets/widget.ts b/packages/client/src/widgets/widget.ts
index 81239bfb3..db164c2bc 100644
--- a/packages/client/src/widgets/widget.ts
+++ b/packages/client/src/widgets/widget.ts
@@ -13,7 +13,7 @@ export type WidgetComponentProps<P extends Record<string, unknown>> = {
 };
 
 export type WidgetComponentEmits<P extends Record<string, unknown>> = {
-	(e: 'updateProps', props: P);
+	(ev: 'updateProps', props: P);
 };
 
 export type WidgetComponentExpose = {