From ac4245dce1f2b957066ddc3cf10a1444fece7691 Mon Sep 17 00:00:00 2001
From: Kagami Sascha Rosylight <saschanaz@outlook.com>
Date: Wed, 5 Jul 2023 06:54:40 +0200
Subject: feat(frontend): allow cropping images on drive (#11092)

* feat(frontend): allow cropping images on drive

* nanka iroiro

* folder

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
---
 packages/frontend/src/components/MkDrive.vue | 1 +
 1 file changed, 1 insertion(+)

(limited to 'packages/frontend/src/components/MkDrive.vue')

diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue
index 52aef450d9..19508fe4de 100644
--- a/packages/frontend/src/components/MkDrive.vue
+++ b/packages/frontend/src/components/MkDrive.vue
@@ -65,6 +65,7 @@
 					v-anim="i"
 					:class="$style.file"
 					:file="file"
+					:folder="folder"
 					:selectMode="select === 'file'"
 					:isSelected="selectedFiles.some(x => x.id === file.id)"
 					@chosen="chooseFile"
-- 
cgit v1.2.3-freya


From d84796588c1472334ddaf696a817f015c245ce44 Mon Sep 17 00:00:00 2001
From: okayurisotto <okayurisotto@proton.me>
Date: Sat, 8 Jul 2023 07:08:16 +0900
Subject: cleanup: trim trailing whitespace (#11136)

* cleanup: trim trailing whitespace

* update(`.editorconfig`)

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
---
 .devcontainer/docker-compose.yml                   |   2 +-
 .editorconfig                                      |   4 +
 CONTRIBUTING.md                                    |   4 +-
 README.md                                          |   6 +-
 assets/title_float.svg                             |   4 +-
 cypress/e2e/basic.cy.js                            |   2 +-
 packages/backend/src/core/AccountMoveService.ts    |   2 +-
 packages/backend/src/core/AiService.ts             |   8 +-
 packages/backend/src/core/AntennaService.ts        |  30 +++---
 packages/backend/src/core/CaptchaService.ts        |  12 +--
 .../backend/src/core/CreateSystemUserService.ts    |  22 ++---
 packages/backend/src/core/CustomEmojiService.ts    |   6 +-
 packages/backend/src/core/DeleteAccountService.ts  |   4 +-
 packages/backend/src/core/EmailService.ts          |  18 ++--
 .../backend/src/core/FederatedInstanceService.ts   |  10 +-
 .../src/core/FetchInstanceMetadataService.ts       |  92 +++++++++---------
 packages/backend/src/core/FileInfoService.ts       |  16 +--
 packages/backend/src/core/HttpRequestService.ts    |   8 +-
 packages/backend/src/core/IdService.ts             |   2 +-
 packages/backend/src/core/InstanceActorService.ts  |   4 +-
 packages/backend/src/core/MetaService.ts           |   8 +-
 packages/backend/src/core/MfmService.ts            | 108 ++++++++++-----------
 packages/backend/src/core/NoteCreateService.ts     |   4 +-
 packages/backend/src/core/NoteDeleteService.ts     |   2 +-
 packages/backend/src/core/NoteReadService.ts       |   4 +-
 packages/backend/src/core/NotificationService.ts   |   2 +-
 packages/backend/src/core/PollService.ts           |  20 ++--
 .../backend/src/core/PushNotificationService.ts    |  12 +--
 packages/backend/src/core/QueryService.ts          |  40 ++++----
 packages/backend/src/core/RelayService.ts          |  28 +++---
 .../backend/src/core/RemoteUserResolveService.ts   |  30 +++---
 packages/backend/src/core/RoleService.ts           |   2 +-
 packages/backend/src/core/SignupService.ts         |  30 +++---
 .../src/core/TwoFactorAuthenticationService.ts     |  86 ++++++++--------
 packages/backend/src/core/UserSuspendService.ts    |  24 ++---
 .../backend/src/core/VideoProcessingService.ts     |   2 +-
 packages/backend/src/core/WebhookService.ts        |   2 +-
 .../src/core/activitypub/ApAudienceService.ts      |  24 ++---
 .../src/core/activitypub/ApDbResolverService.ts    |   4 +-
 .../core/activitypub/ApDeliverManagerService.ts    |   2 +-
 .../backend/src/core/activitypub/ApMfmService.ts   |   4 +-
 .../src/core/activitypub/models/ApImageService.ts  |   2 +-
 .../core/activitypub/models/ApMentionService.ts    |   4 +-
 .../src/core/activitypub/models/ApNoteService.ts   | 102 +++++++++----------
 .../src/core/activitypub/models/ApPersonService.ts |   4 +-
 .../src/core/entities/DriveFileEntityService.ts    |   2 +-
 .../backend/src/core/entities/NoteEntityService.ts |  10 +-
 .../src/core/entities/NoteReactionEntityService.ts |   2 +-
 .../src/core/entities/NotificationEntityService.ts |   2 +-
 .../backend/src/core/entities/UserEntityService.ts |   2 +-
 packages/backend/src/daemons/QueueStatsService.ts  |   2 +-
 packages/backend/src/misc/json-schema.ts           |   2 +-
 packages/backend/src/misc/prelude/url.ts           |   2 +-
 .../backend/src/models/entities/UserProfile.ts     |   2 +-
 .../backend/src/queue/QueueProcessorService.ts     |   2 +-
 .../processors/ExportAntennasProcessorService.ts   |   2 +-
 .../processors/ImportAntennasProcessorService.ts   |   6 +-
 .../ImportCustomEmojisProcessorService.ts          |   2 +-
 .../processors/WebhookDeliverProcessorService.ts   |  10 +-
 .../backend/src/server/api/AuthenticateService.ts  |  16 +--
 .../backend/src/server/api/RateLimiterService.ts   |  20 ++--
 packages/backend/src/server/api/SigninService.ts   |   2 +-
 packages/backend/src/server/api/endpoint-base.ts   |  10 +-
 .../api/endpoints/admin/announcements/update.ts    |   2 +-
 .../src/server/api/endpoints/admin/emoji/list.ts   |   2 +-
 .../src/server/api/endpoints/admin/emoji/update.ts |   2 +-
 .../server/api/endpoints/admin/queue/promote.ts    |   2 +-
 .../src/server/api/endpoints/admin/update-meta.ts  |   2 +-
 .../src/server/api/endpoints/channels/timeline.ts  |   2 +-
 .../src/server/api/endpoints/drive/files/update.ts |   2 +-
 packages/backend/src/server/api/endpoints/emoji.ts |   2 +-
 .../backend/src/server/api/endpoints/emojis.ts     |   2 +-
 .../src/server/api/endpoints/hashtags/users.ts     |   2 +-
 packages/backend/src/server/api/endpoints/i.ts     |   2 +-
 .../src/server/api/endpoints/i/2fa/update-key.ts   |   2 +-
 packages/backend/src/server/api/endpoints/meta.ts  |   2 +-
 packages/backend/src/server/api/endpoints/notes.ts |  16 +--
 .../src/server/api/endpoints/notes/search.ts       |   4 +-
 .../src/server/api/endpoints/notes/translate.ts    |   2 +-
 .../src/server/api/endpoints/roles/notes.ts        |   2 +-
 .../endpoints/users/lists/create-from-public.ts    |   4 +-
 .../server/api/endpoints/users/lists/favorite.ts   |   2 +-
 .../src/server/api/endpoints/users/search.ts       |   2 +-
 .../src/server/api/stream/ChannelsService.ts       |   2 +-
 .../src/server/api/stream/channels/hashtag.ts      |   2 +-
 .../server/api/stream/channels/home-timeline.ts    |   2 +-
 .../server/api/stream/channels/role-timeline.ts    |   2 +-
 .../src/server/api/stream/channels/user-list.ts    |   2 +-
 packages/backend/src/server/web/FeedService.ts     |  12 +--
 packages/backend/src/server/web/bios.js            |   6 +-
 packages/backend/src/server/web/cli.js             |   6 +-
 packages/backend/src/server/web/views/base.pug     |   4 +-
 packages/backend/src/server/web/views/error.pug    |   4 +-
 packages/backend/src/server/web/views/note.pug     |   2 +-
 packages/backend/test/prelude/get-api-validator.ts |   2 +-
 packages/backend/test/unit/DriveService.ts         |   2 +-
 packages/backend/test/unit/FileInfoService.ts      |  22 ++---
 packages/backend/test/unit/RelayService.ts         |   8 +-
 packages/backend/test/unit/chart.ts                |  12 +--
 packages/frontend/src/boot/main-boot.ts            |   2 +-
 .../frontend/src/components/MkDrive.folder.vue     |   6 +-
 .../frontend/src/components/MkDrive.navFolder.vue  |   6 +-
 packages/frontend/src/components/MkDrive.vue       |   6 +-
 .../frontend/src/components/MkFileListForAdmin.vue |   2 +-
 .../frontend/src/components/MkFlashPreview.vue     |   2 +-
 packages/frontend/src/components/MkMediaVideo.vue  |   4 +-
 .../frontend/src/components/MkNoteDetailed.vue     |   2 +-
 packages/frontend/src/components/MkSuperMenu.vue   |   2 +-
 packages/frontend/src/components/MkUserPopup.vue   |   2 +-
 .../MkUserSetupDialog.Follow.stories.impl.ts       |   2 +-
 .../MkUserSetupDialog.Privacy.stories.impl.ts      |   2 +-
 .../MkUserSetupDialog.Profile.stories.impl.ts      |   2 +-
 .../src/components/MkUserSetupDialog.User.vue      |   2 +-
 .../components/MkUserSetupDialog.stories.impl.ts   |   2 +-
 .../components/global/MkMisskeyFlavoredMarkdown.ts |   2 +-
 packages/frontend/src/directives/adaptive-bg.ts    |   2 +-
 .../frontend/src/directives/adaptive-border.ts     |   2 +-
 packages/frontend/src/directives/panel.ts          |   2 +-
 packages/frontend/src/filters/date.ts              |   2 +-
 packages/frontend/src/local-storage.ts             |   2 +-
 packages/frontend/src/nirax.ts                     |   6 +-
 packages/frontend/src/pages/about.emojis.vue       |   4 +-
 packages/frontend/src/pages/admin/index.vue        |   2 +-
 packages/frontend/src/pages/admin/moderation.vue   |   2 +-
 .../src/pages/admin/overview.ap-requests.vue       |   2 +-
 .../src/pages/admin/overview.federation.vue        |   2 +-
 .../frontend/src/pages/admin/overview.queue.vue    |   2 +-
 packages/frontend/src/pages/admin/overview.vue     |   2 +-
 packages/frontend/src/pages/admin/roles.editor.vue |   2 +-
 packages/frontend/src/pages/channel-editor.vue     |   6 +-
 packages/frontend/src/pages/clip.vue               |   2 +-
 .../frontend/src/pages/custom-emojis-manager.vue   |   4 +-
 packages/frontend/src/pages/follow.vue             |   2 +-
 packages/frontend/src/pages/instance-info.vue      |   2 +-
 packages/frontend/src/pages/list.vue               |   2 +-
 packages/frontend/src/pages/registry.keys.vue      |   2 +-
 packages/frontend/src/pages/registry.value.vue     |   2 +-
 packages/frontend/src/pages/reset-password.vue     |   2 +-
 .../frontend/src/pages/settings/drive-cleaner.vue  |   2 +-
 packages/frontend/src/pages/settings/navbar.vue    |   2 +-
 .../src/pages/settings/preferences-backups.vue     |   4 +-
 packages/frontend/src/pages/settings/privacy.vue   |   4 +-
 packages/frontend/src/pages/settings/roles.vue     |   2 +-
 packages/frontend/src/pages/settings/security.vue  |   2 +-
 packages/frontend/src/pizzax.ts                    |  10 +-
 packages/frontend/src/scripts/aiscript/ui.ts       |   2 +-
 packages/frontend/src/scripts/get-user-menu.ts     |   2 +-
 packages/frontend/src/scripts/lookup.ts            |   2 +-
 packages/frontend/src/scripts/url.ts               |   2 +-
 packages/frontend/src/scripts/use-note-capture.ts  |   4 +-
 packages/frontend/src/style.scss                   |   4 +-
 packages/frontend/src/themes/l-botanical.json5     |   2 +-
 packages/frontend/src/ui/classic.header.vue        |   4 +-
 packages/frontend/src/ui/classic.vue               |   2 +-
 .../frontend/src/widgets/WidgetAiscriptApp.vue     |   2 +-
 packages/frontend/src/widgets/WidgetClicker.vue    |   2 +-
 .../frontend/src/widgets/WidgetNotifications.vue   |   2 +-
 packages/misskey-js/src/streaming.ts               |   2 +-
 packages/misskey-js/test-d/streaming.ts            |   2 +-
 packages/misskey-js/test/api.ts                    |   8 +-
 packages/misskey-js/test/streaming.ts              |   2 +-
 161 files changed, 615 insertions(+), 609 deletions(-)

(limited to 'packages/frontend/src/components/MkDrive.vue')

diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml
index 8f8c5a13ab..2809cd2ca4 100644
--- a/.devcontainer/docker-compose.yml
+++ b/.devcontainer/docker-compose.yml
@@ -2,7 +2,7 @@ version: '3.8'
 
 services:
   app:
-    build: 
+    build:
       context: .
       dockerfile: Dockerfile
 
diff --git a/.editorconfig b/.editorconfig
index a6f988f8d7..def7baa1a8 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -6,6 +6,10 @@ indent_size = 2
 charset = utf-8
 insert_final_newline = true
 end_of_line = lf
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
 
 [*.{yml,yaml}]
 indent_style = space
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f6b3804f84..896fb6b089 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -106,7 +106,7 @@ If your language is not listed in Crowdin, please open an issue.
 ![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg)
 
 ## Development
-During development, it is useful to use the 
+During development, it is useful to use the
 
 ```
 pnpm dev
@@ -150,7 +150,7 @@ Prepare DB/Redis for testing.
 ```
 docker compose -f packages/backend/test/docker-compose.yml up
 ```
-Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`. 
+Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`.
 
 Run all test.
 ```
diff --git a/README.md b/README.md
index 2aae4bb865..ab4388c2eb 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
 <a href="https://misskey-hub.net">
 	<img src="./assets/title_float.svg" alt="Misskey logo" style="border-radius:50%" width="400"/>
 </a>
-	
+
 **🌎 **[Misskey](https://misskey-hub.net/)** is an open source, decentralized social media platform that's free forever! 🚀**
-	
+
 ---
 
 <a href="https://misskey-hub.net/instances.html">
@@ -21,7 +21,7 @@
 
 <a href="https://www.patreon.com/syuilo">
 		<img src="https://custom-icon-badges.herokuapp.com/badge/become_a-patron-F96854?logoColor=F96854&style=for-the-badge&logo=patreon&labelColor=363B40" alt="become a patron"/></a>
-	
+
 ---
 
 [![codecov](https://codecov.io/gh/misskey-dev/misskey/branch/develop/graph/badge.svg?token=R6IQZ3QJOL)](https://codecov.io/gh/misskey-dev/misskey)
diff --git a/assets/title_float.svg b/assets/title_float.svg
index 43205ac1c4..ed1749e321 100644
--- a/assets/title_float.svg
+++ b/assets/title_float.svg
@@ -23,13 +23,13 @@
     </rdf:RDF>
   </metadata>
 	<style>
-		#g8 { 
+		#g8 {
     	animation-name: floating;
     	animation-duration: 3s;
     	animation-iteration-count: infinite;
    	 	animation-timing-function: ease-in-out;
 		}
- 
+
 		@keyframes floating {
     	0% { transform: translate(0,  0px); }
     	50% { transform: translate(0, -5px); }
diff --git a/cypress/e2e/basic.cy.js b/cypress/e2e/basic.cy.js
index 2515c14ad6..2bf91cb009 100644
--- a/cypress/e2e/basic.cy.js
+++ b/cypress/e2e/basic.cy.js
@@ -56,7 +56,7 @@ describe('After setup instance', () => {
 		cy.get('[data-cy-signup-rules-notes-agree] [data-cy-switch-toggle]').click();
 		cy.get('[data-cy-signup-rules-continue]').should('not.be.disabled');
 		cy.get('[data-cy-signup-rules-continue]').click();
-	
+
 		cy.get('[data-cy-signup-submit]').should('be.disabled');
 		cy.get('[data-cy-signup-username] input').type('alice');
 		cy.get('[data-cy-signup-submit]').should('be.disabled');
diff --git a/packages/backend/src/core/AccountMoveService.ts b/packages/backend/src/core/AccountMoveService.ts
index ab11785e28..69d83b13b0 100644
--- a/packages/backend/src/core/AccountMoveService.ts
+++ b/packages/backend/src/core/AccountMoveService.ts
@@ -295,7 +295,7 @@ export class AccountMoveService {
 	 * dstユーザーのalsoKnownAsをfetchPersonしていき、本当にmovedToUrlをdstに指定するユーザーが存在するのかを調べる
 	 *
 	 * @param dst movedToUrlを指定するユーザー
-	 * @param check 
+	 * @param check
 	 * @param instant checkがtrueであるユーザーが最初に見つかったら即座にreturnするかどうか
 	 * @returns Promise<LocalUser | RemoteUser | null>
 	 */
diff --git a/packages/backend/src/core/AiService.ts b/packages/backend/src/core/AiService.ts
index 059e335eff..02501b832b 100644
--- a/packages/backend/src/core/AiService.ts
+++ b/packages/backend/src/core/AiService.ts
@@ -31,16 +31,16 @@ export class AiService {
 				const cpuFlags = await this.getCpuFlags();
 				isSupportedCpu = REQUIRED_CPU_FLAGS.every(required => cpuFlags.includes(required));
 			}
-	
+
 			if (!isSupportedCpu) {
 				console.error('This CPU cannot use TensorFlow.');
 				return null;
 			}
-	
+
 			const tf = await import('@tensorflow/tfjs-node');
-	
+
 			if (this.model == null) this.model = await nsfw.load(`file://${_dirname}/../../nsfw-model/`, { size: 299 });
-	
+
 			const buffer = await fs.promises.readFile(path);
 			const image = await tf.node.decodeImage(buffer, 3) as any;
 			try {
diff --git a/packages/backend/src/core/AntennaService.ts b/packages/backend/src/core/AntennaService.ts
index d8df371916..9310fd8b52 100644
--- a/packages/backend/src/core/AntennaService.ts
+++ b/packages/backend/src/core/AntennaService.ts
@@ -99,7 +99,7 @@ export class AntennaService implements OnApplicationShutdown {
 				'MAXLEN', '~', '200',
 				'*',
 				'note', note.id);
-			
+
 			this.globalEventService.publishAntennaStream(antenna.id, 'note', note);
 		}
 
@@ -112,16 +112,16 @@ export class AntennaService implements OnApplicationShutdown {
 	public async checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { id: User['id']; username: string; host: string | null; }): Promise<boolean> {
 		if (note.visibility === 'specified') return false;
 		if (note.visibility === 'followers') return false;
-	
+
 		if (!antenna.withReplies && note.replyId != null) return false;
-	
+
 		if (antenna.src === 'home') {
 			// TODO
 		} else if (antenna.src === 'list') {
 			const listUsers = (await this.userListJoiningsRepository.findBy({
 				userListId: antenna.userListId!,
 			})).map(x => x.userId);
-	
+
 			if (!listUsers.includes(note.userId)) return false;
 		} else if (antenna.src === 'users') {
 			const accts = antenna.users.map(x => {
@@ -130,32 +130,32 @@ export class AntennaService implements OnApplicationShutdown {
 			});
 			if (!accts.includes(this.utilityService.getFullApAccount(noteUser.username, noteUser.host).toLowerCase())) return false;
 		}
-	
+
 		const keywords = antenna.keywords
 			// Clean up
 			.map(xs => xs.filter(x => x !== ''))
 			.filter(xs => xs.length > 0);
-	
+
 		if (keywords.length > 0) {
 			if (note.text == null && note.cw == null) return false;
 
 			const _text = (note.text ?? '') + '\n' + (note.cw ?? '');
-	
+
 			const matched = keywords.some(and =>
 				and.every(keyword =>
 					antenna.caseSensitive
 						? _text.includes(keyword)
 						: _text.toLowerCase().includes(keyword.toLowerCase()),
 				));
-	
+
 			if (!matched) return false;
 		}
-	
+
 		const excludeKeywords = antenna.excludeKeywords
 			// Clean up
 			.map(xs => xs.filter(x => x !== ''))
 			.filter(xs => xs.length > 0);
-	
+
 		if (excludeKeywords.length > 0) {
 			if (note.text == null && note.cw == null) return false;
 
@@ -167,16 +167,16 @@ export class AntennaService implements OnApplicationShutdown {
 						? _text.includes(keyword)
 						: _text.toLowerCase().includes(keyword.toLowerCase()),
 				));
-	
+
 			if (matched) return false;
 		}
-	
+
 		if (antenna.withFile) {
 			if (note.fileIds && note.fileIds.length === 0) return false;
 		}
-	
+
 		// TODO: eval expression
-	
+
 		return true;
 	}
 
@@ -188,7 +188,7 @@ export class AntennaService implements OnApplicationShutdown {
 			});
 			this.antennasFetched = true;
 		}
-	
+
 		return this.antennas;
 	}
 
diff --git a/packages/backend/src/core/CaptchaService.ts b/packages/backend/src/core/CaptchaService.ts
index 1a52a229c5..10cfdba254 100644
--- a/packages/backend/src/core/CaptchaService.ts
+++ b/packages/backend/src/core/CaptchaService.ts
@@ -20,7 +20,7 @@ export class CaptchaService {
 			secret,
 			response,
 		});
-	
+
 		const res = await this.httpRequestService.send(url, {
 			method: 'POST',
 			body: params.toString(),
@@ -28,14 +28,14 @@ export class CaptchaService {
 				'Content-Type': 'application/x-www-form-urlencoded',
 			},
 		}, { throwErrorWhenResponseNotOk: false });
-	
+
 		if (!res.ok) {
 			throw new Error(`${res.status}`);
 		}
-	
+
 		return await res.json() as CaptchaResponse;
-	}	
-	
+	}
+
 	@bindThis
 	public async verifyRecaptcha(secret: string, response: string | null | undefined): Promise<void> {
 		if (response == null) {
@@ -73,7 +73,7 @@ export class CaptchaService {
 		if (response == null) {
 			throw new Error('turnstile-failed: no response provided');
 		}
-	
+
 		const result = await this.getCaptchaResponse('https://challenges.cloudflare.com/turnstile/v0/siteverify', secret, response).catch(err => {
 			throw new Error(`turnstile-request-failed: ${err}`);
 		});
diff --git a/packages/backend/src/core/CreateSystemUserService.ts b/packages/backend/src/core/CreateSystemUserService.ts
index 8f887d90f9..0bfbe2b173 100644
--- a/packages/backend/src/core/CreateSystemUserService.ts
+++ b/packages/backend/src/core/CreateSystemUserService.ts
@@ -25,27 +25,27 @@ export class CreateSystemUserService {
 	@bindThis
 	public async createSystemUser(username: string): Promise<User> {
 		const password = uuid();
-	
+
 		// Generate hash of password
 		const salt = await bcrypt.genSalt(8);
 		const hash = await bcrypt.hash(password, salt);
-	
+
 		// Generate secret
 		const secret = generateNativeUserToken();
-	
+
 		const keyPair = await genRsaKeyPair(4096);
-	
+
 		let account!: User;
-	
+
 		// Start transaction
 		await this.db.transaction(async transactionalEntityManager => {
 			const exist = await transactionalEntityManager.findOneBy(User, {
 				usernameLower: username.toLowerCase(),
 				host: IsNull(),
 			});
-	
+
 			if (exist) throw new Error('the user is already exists');
-	
+
 			account = await transactionalEntityManager.insert(User, {
 				id: this.idService.genId(),
 				createdAt: new Date(),
@@ -58,25 +58,25 @@ export class CreateSystemUserService {
 				isExplorable: false,
 				isBot: true,
 			}).then(x => transactionalEntityManager.findOneByOrFail(User, x.identifiers[0]));
-	
+
 			await transactionalEntityManager.insert(UserKeypair, {
 				publicKey: keyPair.publicKey,
 				privateKey: keyPair.privateKey,
 				userId: account.id,
 			});
-	
+
 			await transactionalEntityManager.insert(UserProfile, {
 				userId: account.id,
 				autoAcceptFollowed: false,
 				password: hash,
 			});
-	
+
 			await transactionalEntityManager.insert(UsedUsername, {
 				createdAt: new Date(),
 				username: username.toLowerCase(),
 			});
 		});
-	
+
 		return account;
 	}
 }
diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts
index 5f2ced77eb..661d956bd6 100644
--- a/packages/backend/src/core/CustomEmojiService.ts
+++ b/packages/backend/src/core/CustomEmojiService.ts
@@ -140,7 +140,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
 
 			this.globalEventService.publishBroadcastStream('emojiAdded', {
 				emoji: updated,
-			});	
+			});
 		}
 	}
 
@@ -194,7 +194,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
 		}
 
 		this.localEmojisCache.refresh();
-	
+
 		this.globalEventService.publishBroadcastStream('emojiUpdated', {
 			emojis: await this.emojiEntityService.packDetailedMany(ids),
 		});
@@ -215,7 +215,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
 			emojis: await this.emojiEntityService.packDetailedMany(ids),
 		});
 	}
-	
+
 	@bindThis
 	public async setLicenseBulk(ids: Emoji['id'][], license: string | null) {
 		await this.emojisRepository.update({
diff --git a/packages/backend/src/core/DeleteAccountService.ts b/packages/backend/src/core/DeleteAccountService.ts
index 327283106f..3a0592441b 100644
--- a/packages/backend/src/core/DeleteAccountService.ts
+++ b/packages/backend/src/core/DeleteAccountService.ts
@@ -28,11 +28,11 @@ export class DeleteAccountService {
 
 		// 物理削除する前にDelete activityを送信する
 		await this.userSuspendService.doPostSuspend(user).catch(e => {});
-	
+
 		this.queueService.createDeleteAccountJob(user, {
 			soft: false,
 		});
-	
+
 		await this.usersRepository.update(user.id, {
 			isDeleted: true,
 		});
diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts
index 59932a5b88..a04e9c1225 100644
--- a/packages/backend/src/core/EmailService.ts
+++ b/packages/backend/src/core/EmailService.ts
@@ -29,12 +29,12 @@ export class EmailService {
 	@bindThis
 	public async sendEmail(to: string, subject: string, html: string, text: string) {
 		const meta = await this.metaService.fetch(true);
-	
+
 		const iconUrl = `${this.config.url}/static-assets/mi-white.png`;
 		const emailSettingUrl = `${this.config.url}/settings/email`;
-	
+
 		const enableAuth = meta.smtpUser != null && meta.smtpUser !== '';
-	
+
 		const transporter = nodemailer.createTransport({
 			host: meta.smtpHost,
 			port: meta.smtpPort,
@@ -46,7 +46,7 @@ export class EmailService {
 				pass: meta.smtpPass,
 			} : undefined,
 		} as any);
-	
+
 		try {
 			// TODO: htmlサニタイズ
 			const info = await transporter.sendMail({
@@ -135,7 +135,7 @@ export class EmailService {
 	</body>
 </html>`,
 			});
-	
+
 			this.logger.info(`Message sent: ${info.messageId}`);
 		} catch (err) {
 			this.logger.error(err as Error);
@@ -149,12 +149,12 @@ export class EmailService {
 		reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp';
 	}> {
 		const meta = await this.metaService.fetch();
-	
+
 		const exist = await this.userProfilesRepository.countBy({
 			emailVerified: true,
 			email: emailAddress,
 		});
-	
+
 		const validated = meta.enableActiveEmailValidation ? await validateEmail({
 			email: emailAddress,
 			validateRegex: true,
@@ -163,9 +163,9 @@ export class EmailService {
 			validateDisposable: true, // 捨てアドかどうかチェック
 			validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
 		}) : { valid: true, reason: null };
-	
+
 		const available = exist === 0 && validated.valid;
-	
+
 		return {
 			available,
 			reason: available ? null :
diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts
index 3603d59dcc..a762038942 100644
--- a/packages/backend/src/core/FederatedInstanceService.ts
+++ b/packages/backend/src/core/FederatedInstanceService.ts
@@ -43,19 +43,19 @@ export class FederatedInstanceService implements OnApplicationShutdown {
 	@bindThis
 	public async fetch(host: string): Promise<Instance> {
 		host = this.utilityService.toPuny(host);
-	
+
 		const cached = await this.federatedInstanceCache.get(host);
 		if (cached) return cached;
-	
+
 		const index = await this.instancesRepository.findOneBy({ host });
-	
+
 		if (index == null) {
 			const i = await this.instancesRepository.insert({
 				id: this.idService.genId(),
 				host,
 				firstRetrievedAt: new Date(),
 			}).then(x => this.instancesRepository.findOneByOrFail(x.identifiers[0]));
-	
+
 			this.federatedInstanceCache.set(host, i);
 			return i;
 		} else {
@@ -74,7 +74,7 @@ export class FederatedInstanceService implements OnApplicationShutdown {
 			.then((response) => {
 				return response.raw[0];
 			});
-	
+
 		this.federatedInstanceCache.set(result.host, result);
 	}
 
diff --git a/packages/backend/src/core/FetchInstanceMetadataService.ts b/packages/backend/src/core/FetchInstanceMetadataService.ts
index 96ee77d056..127c4c3155 100644
--- a/packages/backend/src/core/FetchInstanceMetadataService.ts
+++ b/packages/backend/src/core/FetchInstanceMetadataService.ts
@@ -58,6 +58,8 @@ export class FetchInstanceMetadataService {
 
 	@bindThis
 	public async fetchInstanceMetadata(instance: Instance, force = false): Promise<void> {
+		try {
+
 		const host = instance.host;
 		// Acquire mutex to ensure no parallel runs
 		if (!await this.tryLock(host)) return;
@@ -72,13 +74,13 @@ export class FetchInstanceMetadataService {
 			}
 	
 			this.logger.info(`Fetching metadata of ${instance.host} ...`);
-	
+ 
 			const [info, dom, manifest] = await Promise.all([
 				this.fetchNodeinfo(instance).catch(() => null),
 				this.fetchDom(instance).catch(() => null),
 				this.fetchManifest(instance).catch(() => null),
 			]);
-	
+
 			const [favicon, icon, themeColor, name, description] = await Promise.all([
 				this.fetchFaviconUrl(instance, dom).catch(() => null),
 				this.fetchIconUrl(instance, dom, manifest).catch(() => null),
@@ -86,13 +88,13 @@ export class FetchInstanceMetadataService {
 				this.getSiteName(info, dom, manifest).catch(() => null),
 				this.getDescription(info, dom, manifest).catch(() => null),
 			]);
-	
+
 			this.logger.succ(`Successfuly fetched metadata of ${instance.host}`);
-	
+
 			const updates = {
 				infoUpdatedAt: new Date(),
 			} as Record<string, any>;
-	
+
 			if (info) {
 				updates.softwareName = typeof info.software?.name === 'string' ? info.software.name.toLowerCase() : '?';
 				updates.softwareVersion = info.software?.version;
@@ -100,15 +102,15 @@ export class FetchInstanceMetadataService {
 				updates.maintainerName = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.name ?? null) : null : null;
 				updates.maintainerEmail = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.email ?? null) : null : null;
 			}
-	
+
 			if (name) updates.name = name;
 			if (description) updates.description = description;
 			if (icon || favicon) updates.iconUrl = icon ?? favicon;
 			if (favicon) updates.faviconUrl = favicon;
 			if (themeColor) updates.themeColor = themeColor;
-	
+
 			await this.federatedInstanceService.update(instance.id, updates);
-	
+
 			this.logger.succ(`Successfuly updated metadata of ${instance.host}`);
 		} catch (e) {
 			this.logger.error(`Failed to update metadata of ${instance.host}: ${e}`);
@@ -120,7 +122,7 @@ export class FetchInstanceMetadataService {
 	@bindThis
 	private async fetchNodeinfo(instance: Instance): Promise<NodeInfo> {
 		this.logger.info(`Fetching nodeinfo of ${instance.host} ...`);
-	
+
 		try {
 			const wellknown = await this.httpRequestService.getJson('https://' + instance.host + '/.well-known/nodeinfo')
 				.catch(err => {
@@ -130,33 +132,33 @@ export class FetchInstanceMetadataService {
 						throw err.statusCode ?? err.message;
 					}
 				}) as Record<string, unknown>;
-	
+
 			if (wellknown.links == null || !Array.isArray(wellknown.links)) {
 				throw new Error('No wellknown links');
 			}
-	
+
 			const links = wellknown.links as any[];
-	
+
 			const lnik1_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/1.0');
 			const lnik2_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.0');
 			const lnik2_1 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.1');
 			const link = lnik2_1 ?? lnik2_0 ?? lnik1_0;
-	
+
 			if (link == null) {
 				throw new Error('No nodeinfo link provided');
 			}
-	
+
 			const info = await this.httpRequestService.getJson(link.href)
 				.catch(err => {
 					throw err.statusCode ?? err.message;
 				});
-	
+
 			this.logger.succ(`Successfuly fetched nodeinfo of ${instance.host}`);
-	
+
 			return info as NodeInfo;
 		} catch (err) {
 			this.logger.error(`Failed to fetch nodeinfo of ${instance.host}: ${err}`);
-	
+
 			throw err;
 		}
 	}
@@ -164,51 +166,51 @@ export class FetchInstanceMetadataService {
 	@bindThis
 	private async fetchDom(instance: Instance): Promise<DOMWindow['document']> {
 		this.logger.info(`Fetching HTML of ${instance.host} ...`);
-	
+
 		const url = 'https://' + instance.host;
-	
+
 		const html = await this.httpRequestService.getHtml(url);
-	
+
 		const { window } = new JSDOM(html);
 		const doc = window.document;
-	
+
 		return doc;
 	}
 
 	@bindThis
 	private async fetchManifest(instance: Instance): Promise<Record<string, unknown> | null> {
 		const url = 'https://' + instance.host;
-	
+
 		const manifestUrl = url + '/manifest.json';
-	
+
 		const manifest = await this.httpRequestService.getJson(manifestUrl) as Record<string, unknown>;
-	
+
 		return manifest;
 	}
 
 	@bindThis
 	private async fetchFaviconUrl(instance: Instance, doc: DOMWindow['document'] | null): Promise<string | null> {
 		const url = 'https://' + instance.host;
-	
+
 		if (doc) {
 			// https://github.com/misskey-dev/misskey/pull/8220#issuecomment-1025104043
 			const href = Array.from(doc.getElementsByTagName('link')).reverse().find(link => link.relList.contains('icon'))?.href;
-	
+
 			if (href) {
 				return (new URL(href, url)).href;
 			}
 		}
-	
+
 		const faviconUrl = url + '/favicon.ico';
-	
+
 		const favicon = await this.httpRequestService.send(faviconUrl, {
 			method: 'HEAD',
 		}, { throwErrorWhenResponseNotOk: false });
-	
+
 		if (favicon.ok) {
 			return faviconUrl;
 		}
-	
+
 		return null;
 	}
 
@@ -218,38 +220,38 @@ export class FetchInstanceMetadataService {
 			const url = 'https://' + instance.host;
 			return (new URL(manifest.icons[0].src, url)).href;
 		}
-	
+
 		if (doc) {
 			const url = 'https://' + instance.host;
-	
+
 			// https://github.com/misskey-dev/misskey/pull/8220#issuecomment-1025104043
 			const links = Array.from(doc.getElementsByTagName('link')).reverse();
 			// https://github.com/misskey-dev/misskey/pull/8220/files/0ec4eba22a914e31b86874f12448f88b3e58dd5a#r796487559
-			const href = 
+			const href =
 				[
 					links.find(link => link.relList.contains('apple-touch-icon-precomposed'))?.href,
 					links.find(link => link.relList.contains('apple-touch-icon'))?.href,
 					links.find(link => link.relList.contains('icon'))?.href,
 				]
 					.find(href => href);
-	
+
 			if (href) {
 				return (new URL(href, url)).href;
 			}
 		}
-	
+
 		return null;
 	}
 
 	@bindThis
 	private async getThemeColor(info: NodeInfo | null, doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> {
 		const themeColor = info?.metadata?.themeColor ?? doc?.querySelector('meta[name="theme-color"]')?.getAttribute('content') ?? manifest?.theme_color;
-	
+
 		if (themeColor) {
 			const color = new tinycolor(themeColor);
 			if (color.isValid()) return color.toHexString();
 		}
-	
+
 		return null;
 	}
 
@@ -262,19 +264,19 @@ export class FetchInstanceMetadataService {
 				return info.metadata.name;
 			}
 		}
-	
+
 		if (doc) {
 			const og = doc.querySelector('meta[property="og:title"]')?.getAttribute('content');
-	
+
 			if (og) {
 				return og;
 			}
 		}
-	
+
 		if (manifest) {
 			return manifest.name ?? manifest.short_name;
 		}
-	
+
 		return null;
 	}
 
@@ -287,23 +289,23 @@ export class FetchInstanceMetadataService {
 				return info.metadata.description;
 			}
 		}
-	
+
 		if (doc) {
 			const meta = doc.querySelector('meta[name="description"]')?.getAttribute('content');
 			if (meta) {
 				return meta;
 			}
-	
+
 			const og = doc.querySelector('meta[property="og:description"]')?.getAttribute('content');
 			if (og) {
 				return og;
 			}
 		}
-	
+
 		if (manifest) {
 			return manifest.name ?? manifest.short_name;
 		}
-	
+
 		return null;
 	}
 }
diff --git a/packages/backend/src/core/FileInfoService.ts b/packages/backend/src/core/FileInfoService.ts
index d6c51ad559..d43575b336 100644
--- a/packages/backend/src/core/FileInfoService.ts
+++ b/packages/backend/src/core/FileInfoService.ts
@@ -161,20 +161,20 @@ export class FileInfoService {
 	private async detectSensitivity(source: string, mime: string, sensitiveThreshold: number, sensitiveThresholdForPorn: number, analyzeVideo: boolean): Promise<[sensitive: boolean, porn: boolean]> {
 		let sensitive = false;
 		let porn = false;
-	
+
 		function judgePrediction(result: readonly predictionType[]): [sensitive: boolean, porn: boolean] {
 			let sensitive = false;
 			let porn = false;
-	
+
 			if ((result.find(x => x.className === 'Sexy')?.probability ?? 0) > sensitiveThreshold) sensitive = true;
 			if ((result.find(x => x.className === 'Hentai')?.probability ?? 0) > sensitiveThreshold) sensitive = true;
 			if ((result.find(x => x.className === 'Porn')?.probability ?? 0) > sensitiveThreshold) sensitive = true;
-	
+
 			if ((result.find(x => x.className === 'Porn')?.probability ?? 0) > sensitiveThresholdForPorn) porn = true;
-	
+
 			return [sensitive, porn];
 		}
-	
+
 		if ([
 			'image/jpeg',
 			'image/png',
@@ -253,10 +253,10 @@ export class FileInfoService {
 				disposeOutDir();
 			}
 		}
-	
+
 		return [sensitive, porn];
 	}
-	
+
 	private async *asyncIterateFrames(cwd: string, command: FFmpeg.FfmpegCommand): AsyncGenerator<string, void> {
 		const watcher = new FSWatcher({
 			cwd,
@@ -295,7 +295,7 @@ export class FileInfoService {
 			}
 		}
 	}
-	
+
 	@bindThis
 	private exists(path: string): Promise<boolean> {
 		return fs.promises.access(path).then(() => true, () => false);
diff --git a/packages/backend/src/core/HttpRequestService.ts b/packages/backend/src/core/HttpRequestService.ts
index 375aa846cb..4f2c261140 100644
--- a/packages/backend/src/core/HttpRequestService.ts
+++ b/packages/backend/src/core/HttpRequestService.ts
@@ -42,21 +42,21 @@ export class HttpRequestService {
 			errorTtl: 30,	// 30secs
 			lookup: false,	// nativeのdns.lookupにfallbackしない
 		});
-		
+
 		this.http = new http.Agent({
 			keepAlive: true,
 			keepAliveMsecs: 30 * 1000,
 			lookup: cache.lookup,
 		} as http.AgentOptions);
-		
+
 		this.https = new https.Agent({
 			keepAlive: true,
 			keepAliveMsecs: 30 * 1000,
 			lookup: cache.lookup,
 		} as https.AgentOptions);
-		
+
 		const maxSockets = Math.max(256, config.deliverJobConcurrency ?? 128);
-		
+
 		this.httpAgent = config.proxy
 			? new HttpProxyAgent({
 				keepAlive: true,
diff --git a/packages/backend/src/core/IdService.ts b/packages/backend/src/core/IdService.ts
index 60098bc81c..4d129407cb 100644
--- a/packages/backend/src/core/IdService.ts
+++ b/packages/backend/src/core/IdService.ts
@@ -23,7 +23,7 @@ export class IdService {
 	@bindThis
 	public genId(date?: Date): string {
 		if (!date || (date > new Date())) date = new Date();
-	
+
 		switch (this.method) {
 			case 'aid': return genAid(date);
 			case 'meid': return genMeid(date);
diff --git a/packages/backend/src/core/InstanceActorService.ts b/packages/backend/src/core/InstanceActorService.ts
index 4fb3fc5b4f..2e047dc5c1 100644
--- a/packages/backend/src/core/InstanceActorService.ts
+++ b/packages/backend/src/core/InstanceActorService.ts
@@ -26,12 +26,12 @@ export class InstanceActorService {
 	public async getInstanceActor(): Promise<LocalUser> {
 		const cached = this.cache.get();
 		if (cached) return cached;
-	
+
 		const user = await this.usersRepository.findOneBy({
 			host: IsNull(),
 			username: ACTOR_USERNAME,
 		}) as LocalUser | undefined;
-	
+
 		if (user) {
 			this.cache.set(user);
 			return user;
diff --git a/packages/backend/src/core/MetaService.ts b/packages/backend/src/core/MetaService.ts
index 5acc9ad9ad..aae0a9134b 100644
--- a/packages/backend/src/core/MetaService.ts
+++ b/packages/backend/src/core/MetaService.ts
@@ -56,7 +56,7 @@ export class MetaService implements OnApplicationShutdown {
 	@bindThis
 	public async fetch(noCache = false): Promise<Meta> {
 		if (!noCache && this.cache) return this.cache;
-	
+
 		return await this.db.transaction(async transactionalEntityManager => {
 			// 過去のバグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する
 			const metas = await transactionalEntityManager.find(Meta, {
@@ -64,9 +64,9 @@ export class MetaService implements OnApplicationShutdown {
 					id: 'DESC',
 				},
 			});
-	
+
 			const meta = metas[0];
-	
+
 			if (meta) {
 				this.cache = meta;
 				return meta;
@@ -81,7 +81,7 @@ export class MetaService implements OnApplicationShutdown {
 						['id'],
 					)
 					.then((x) => transactionalEntityManager.findOneByOrFail(Meta, x.identifiers[0]));
-	
+
 				this.cache = saved;
 				return saved;
 			}
diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts
index dffee16e08..38aaa84524 100644
--- a/packages/backend/src/core/MfmService.ts
+++ b/packages/backend/src/core/MfmService.ts
@@ -27,29 +27,29 @@ export class MfmService {
 	public fromHtml(html: string, hashtagNames?: string[]): string {
 		// some AP servers like Pixelfed use br tags as well as newlines
 		html = html.replace(/<br\s?\/?>\r?\n/gi, '\n');
-	
+
 		const dom = parse5.parseFragment(html);
-	
+
 		let text = '';
-	
+
 		for (const n of dom.childNodes) {
 			analyze(n);
 		}
-	
+
 		return text.trim();
-	
+
 		function getText(node: TreeAdapter.Node): string {
 			if (treeAdapter.isTextNode(node)) return node.value;
 			if (!treeAdapter.isElementNode(node)) return '';
 			if (node.nodeName === 'br') return '\n';
-	
+
 			if (node.childNodes) {
 				return node.childNodes.map(n => getText(n)).join('');
 			}
-	
+
 			return '';
 		}
-	
+
 		function appendChildren(childNodes: TreeAdapter.ChildNode[]): void {
 			if (childNodes) {
 				for (const n of childNodes) {
@@ -57,35 +57,35 @@ export class MfmService {
 				}
 			}
 		}
-	
+
 		function analyze(node: TreeAdapter.Node) {
 			if (treeAdapter.isTextNode(node)) {
 				text += node.value;
 				return;
 			}
-	
+
 			// Skip comment or document type node
 			if (!treeAdapter.isElementNode(node)) return;
-	
+
 			switch (node.nodeName) {
 				case 'br': {
 					text += '\n';
 					break;
 				}
-	
+
 				case 'a':
 				{
 					const txt = getText(node);
 					const rel = node.attrs.find(x => x.name === 'rel');
 					const href = node.attrs.find(x => x.name === 'href');
-	
+
 					// ハッシュタグ
 					if (hashtagNames && href && hashtagNames.map(x => x.toLowerCase()).includes(txt.toLowerCase())) {
 						text += txt;
 					// メンション
 					} else if (txt.startsWith('@') && !(rel && rel.value.startsWith('me '))) {
 						const part = txt.split('@');
-	
+
 						if (part.length === 2 && href) {
 							//#region ホスト名部分が省略されているので復元する
 							const acct = `${txt}@${(new URL(href.value)).hostname}`;
@@ -116,12 +116,12 @@ export class MfmService {
 								return `[${txt}](${href.value})`;
 							}
 						};
-	
+
 						text += generateLink();
 					}
 					break;
 				}
-	
+
 				case 'h1':
 				{
 					text += '【';
@@ -129,7 +129,7 @@ export class MfmService {
 					text += '】\n';
 					break;
 				}
-	
+
 				case 'b':
 				case 'strong':
 				{
@@ -138,7 +138,7 @@ export class MfmService {
 					text += '**';
 					break;
 				}
-	
+
 				case 'small':
 				{
 					text += '<small>';
@@ -146,7 +146,7 @@ export class MfmService {
 					text += '</small>';
 					break;
 				}
-	
+
 				case 's':
 				case 'del':
 				{
@@ -155,7 +155,7 @@ export class MfmService {
 					text += '~~';
 					break;
 				}
-	
+
 				case 'i':
 				case 'em':
 				{
@@ -164,7 +164,7 @@ export class MfmService {
 					text += '</i>';
 					break;
 				}
-	
+
 				// block code (<pre><code>)
 				case 'pre': {
 					if (node.childNodes.length === 1 && node.childNodes[0].nodeName === 'code') {
@@ -176,7 +176,7 @@ export class MfmService {
 					}
 					break;
 				}
-	
+
 				// inline code (<code>)
 				case 'code': {
 					text += '`';
@@ -184,7 +184,7 @@ export class MfmService {
 					text += '`';
 					break;
 				}
-	
+
 				case 'blockquote': {
 					const t = getText(node);
 					if (t) {
@@ -193,7 +193,7 @@ export class MfmService {
 					}
 					break;
 				}
-	
+
 				case 'p':
 				case 'h2':
 				case 'h3':
@@ -205,7 +205,7 @@ export class MfmService {
 					appendChildren(node.childNodes);
 					break;
 				}
-	
+
 				// other block elements
 				case 'div':
 				case 'header':
@@ -219,7 +219,7 @@ export class MfmService {
 					appendChildren(node.childNodes);
 					break;
 				}
-	
+
 				default:	// includes inline elements
 				{
 					appendChildren(node.childNodes);
@@ -234,48 +234,48 @@ export class MfmService {
 		if (nodes == null) {
 			return null;
 		}
-	
+
 		const { window } = new Window();
-	
+
 		const doc = window.document;
-	
+
 		function appendChildren(children: mfm.MfmNode[], targetElement: any): void {
 			if (children) {
 				for (const child of children.map(x => (handlers as any)[x.type](x))) targetElement.appendChild(child);
 			}
 		}
-	
+
 		const handlers: { [K in mfm.MfmNode['type']]: (node: mfm.NodeType<K>) => any } = {
 			bold: (node) => {
 				const el = doc.createElement('b');
 				appendChildren(node.children, el);
 				return el;
 			},
-	
+
 			small: (node) => {
 				const el = doc.createElement('small');
 				appendChildren(node.children, el);
 				return el;
 			},
-	
+
 			strike: (node) => {
 				const el = doc.createElement('del');
 				appendChildren(node.children, el);
 				return el;
 			},
-	
+
 			italic: (node) => {
 				const el = doc.createElement('i');
 				appendChildren(node.children, el);
 				return el;
 			},
-	
+
 			fn: (node) => {
 				const el = doc.createElement('i');
 				appendChildren(node.children, el);
 				return el;
 			},
-	
+
 			blockCode: (node) => {
 				const pre = doc.createElement('pre');
 				const inner = doc.createElement('code');
@@ -283,21 +283,21 @@ export class MfmService {
 				pre.appendChild(inner);
 				return pre;
 			},
-	
+
 			center: (node) => {
 				const el = doc.createElement('div');
 				appendChildren(node.children, el);
 				return el;
 			},
-	
+
 			emojiCode: (node) => {
 				return doc.createTextNode(`\u200B:${node.props.name}:\u200B`);
 			},
-	
+
 			unicodeEmoji: (node) => {
 				return doc.createTextNode(node.props.emoji);
 			},
-	
+
 			hashtag: (node) => {
 				const a = doc.createElement('a');
 				a.setAttribute('href', `${this.config.url}/tags/${node.props.hashtag}`);
@@ -305,32 +305,32 @@ export class MfmService {
 				a.setAttribute('rel', 'tag');
 				return a;
 			},
-	
+
 			inlineCode: (node) => {
 				const el = doc.createElement('code');
 				el.textContent = node.props.code;
 				return el;
 			},
-	
+
 			mathInline: (node) => {
 				const el = doc.createElement('code');
 				el.textContent = node.props.formula;
 				return el;
 			},
-	
+
 			mathBlock: (node) => {
 				const el = doc.createElement('code');
 				el.textContent = node.props.formula;
 				return el;
 			},
-	
+
 			link: (node) => {
 				const a = doc.createElement('a');
 				a.setAttribute('href', node.props.url);
 				appendChildren(node.children, a);
 				return a;
 			},
-	
+
 			mention: (node) => {
 				const a = doc.createElement('a');
 				const { username, host, acct } = node.props;
@@ -340,47 +340,47 @@ export class MfmService {
 				a.textContent = acct;
 				return a;
 			},
-	
+
 			quote: (node) => {
 				const el = doc.createElement('blockquote');
 				appendChildren(node.children, el);
 				return el;
 			},
-	
+
 			text: (node) => {
 				const el = doc.createElement('span');
 				const nodes = node.props.text.split(/\r\n|\r|\n/).map(x => doc.createTextNode(x));
-	
+
 				for (const x of intersperse<FIXME | 'br'>('br', nodes)) {
 					el.appendChild(x === 'br' ? doc.createElement('br') : x);
 				}
-	
+
 				return el;
 			},
-	
+
 			url: (node) => {
 				const a = doc.createElement('a');
 				a.setAttribute('href', node.props.url);
 				a.textContent = node.props.url;
 				return a;
 			},
-	
+
 			search: (node) => {
 				const a = doc.createElement('a');
 				a.setAttribute('href', `https://www.google.com/search?q=${node.props.query}`);
 				a.textContent = node.props.content;
 				return a;
 			},
-	
+
 			plain: (node) => {
 				const el = doc.createElement('span');
 				appendChildren(node.children, el);
 				return el;
 			},
 		};
-	
+
 		appendChildren(nodes, doc.body);
-	
+
 		return `<p>${doc.body.innerHTML}</p>`;
-	}	
+	}
 }
diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index 1c8491bf57..fb36ca3b6a 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -672,7 +672,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 		// Register to search database
 		this.index(note);
 	}
-	
+
 	@bindThis
 	private isSensitive(note: Option, sensitiveWord: string[]): boolean {
 		if (sensitiveWord.length > 0) {
@@ -758,7 +758,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 	@bindThis
 	private index(note: Note) {
 		if (note.text == null && note.cw == null) return;
-		
+
 		this.searchService.indexNote(note);
 	}
 
diff --git a/packages/backend/src/core/NoteDeleteService.ts b/packages/backend/src/core/NoteDeleteService.ts
index 3612ac806f..10381c7e65 100644
--- a/packages/backend/src/core/NoteDeleteService.ts
+++ b/packages/backend/src/core/NoteDeleteService.ts
@@ -45,7 +45,7 @@ export class NoteDeleteService {
 		private perUserNotesChart: PerUserNotesChart,
 		private instanceChart: InstanceChart,
 	) {}
-	
+
 	/**
 	 * 投稿を削除します。
 	 * @param user 投稿者
diff --git a/packages/backend/src/core/NoteReadService.ts b/packages/backend/src/core/NoteReadService.ts
index e57e57d310..b84591e26d 100644
--- a/packages/backend/src/core/NoteReadService.ts
+++ b/packages/backend/src/core/NoteReadService.ts
@@ -99,7 +99,7 @@ export class NoteReadService implements OnApplicationShutdown {
 			});
 
 			// TODO: ↓まとめてクエリしたい
-	
+
 			this.noteUnreadsRepository.countBy({
 				userId: userId,
 				isMentioned: true,
@@ -109,7 +109,7 @@ export class NoteReadService implements OnApplicationShutdown {
 					this.globalEventService.publishMainStream(userId, 'readAllUnreadMentions');
 				}
 			});
-	
+
 			this.noteUnreadsRepository.countBy({
 				userId: userId,
 				isSpecified: true,
diff --git a/packages/backend/src/core/NotificationService.ts b/packages/backend/src/core/NotificationService.ts
index ed47165f7b..8e25f82284 100644
--- a/packages/backend/src/core/NotificationService.ts
+++ b/packages/backend/src/core/NotificationService.ts
@@ -46,7 +46,7 @@ export class NotificationService implements OnApplicationShutdown {
 		force = false,
 	) {
 		const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${userId}`);
-		
+
 		const latestNotificationIdsRes = await this.redisClient.xrevrange(
 			`notificationTimeline:${userId}`,
 			'+',
diff --git a/packages/backend/src/core/PollService.ts b/packages/backend/src/core/PollService.ts
index 368753d9a7..be19400052 100644
--- a/packages/backend/src/core/PollService.ts
+++ b/packages/backend/src/core/PollService.ts
@@ -39,12 +39,12 @@ export class PollService {
 	@bindThis
 	public async vote(user: User, note: Note, choice: number) {
 		const poll = await this.pollsRepository.findOneBy({ noteId: note.id });
-	
+
 		if (poll == null) throw new Error('poll not found');
-	
+
 		// Check whether is valid choice
 		if (poll.choices[choice] == null) throw new Error('invalid choice param');
-	
+
 		// Check blocking
 		if (note.userId !== user.id) {
 			const blocked = await this.userBlockingService.checkBlocked(note.userId, user.id);
@@ -52,13 +52,13 @@ export class PollService {
 				throw new Error('blocked');
 			}
 		}
-	
+
 		// if already voted
 		const exist = await this.pollVotesRepository.findBy({
 			noteId: note.id,
 			userId: user.id,
 		});
-	
+
 		if (poll.multiple) {
 			if (exist.some(x => x.choice === choice)) {
 				throw new Error('already voted');
@@ -66,7 +66,7 @@ export class PollService {
 		} else if (exist.length !== 0) {
 			throw new Error('already voted');
 		}
-	
+
 		// Create vote
 		await this.pollVotesRepository.insert({
 			id: this.idService.genId(),
@@ -75,11 +75,11 @@ export class PollService {
 			userId: user.id,
 			choice: choice,
 		});
-	
+
 		// Increment votes count
 		const index = choice + 1; // In SQL, array index is 1 based
 		await this.pollsRepository.query(`UPDATE poll SET votes[${index}] = votes[${index}] + 1 WHERE "noteId" = '${poll.noteId}'`);
-	
+
 		this.globalEventService.publishNoteStream(note.id, 'pollVoted', {
 			choice: choice,
 			userId: user.id,
@@ -90,10 +90,10 @@ export class PollService {
 	public async deliverQuestionUpdate(noteId: Note['id']) {
 		const note = await this.notesRepository.findOneBy({ id: noteId });
 		if (note == null) throw new Error('note not found');
-	
+
 		const user = await this.usersRepository.findOneBy({ id: note.userId });
 		if (user == null) throw new Error('note not found');
-	
+
 		if (this.userEntityService.isLocalUser(user)) {
 			const content = this.apRendererService.addContext(this.apRendererService.renderUpdate(await this.apRendererService.renderNote(note, false), user));
 			this.apDeliverManagerService.deliverToFollowers(user, content);
diff --git a/packages/backend/src/core/PushNotificationService.ts b/packages/backend/src/core/PushNotificationService.ts
index 9ee83df644..e1c3d3943c 100644
--- a/packages/backend/src/core/PushNotificationService.ts
+++ b/packages/backend/src/core/PushNotificationService.ts
@@ -31,7 +31,7 @@ function truncateBody<T extends keyof PushNotificationsTypes>(type: T, body: Pus
 				...body.note,
 				// textをgetNoteSummaryしたものに置き換える
 				text: getNoteSummary(('type' in body && body.type === 'renote') ? body.note.renote as Packed<'Note'> : body.note),
-	
+
 				cw: undefined,
 				reply: undefined,
 				renote: undefined,
@@ -69,16 +69,16 @@ export class PushNotificationService implements OnApplicationShutdown {
 	@bindThis
 	public async pushNotification<T extends keyof PushNotificationsTypes>(userId: string, type: T, body: PushNotificationsTypes[T]) {
 		const meta = await this.metaService.fetch();
-	
+
 		if (!meta.enableServiceWorker || meta.swPublicKey == null || meta.swPrivateKey == null) return;
-	
+
 		// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
 		push.setVapidDetails(this.config.url,
 			meta.swPublicKey,
 			meta.swPrivateKey);
-	
+
 		const subscriptions = await this.subscriptionsCache.fetch(userId);
-	
+
 		for (const subscription of subscriptions) {
 			if ([
 				'readAllNotifications',
@@ -103,7 +103,7 @@ export class PushNotificationService implements OnApplicationShutdown {
 				//swLogger.info(err.statusCode);
 				//swLogger.info(err.headers);
 				//swLogger.info(err.body);
-	
+
 				if (err.statusCode === 410) {
 					this.swSubscriptionsRepository.delete({
 						userId: userId,
diff --git a/packages/backend/src/core/QueryService.ts b/packages/backend/src/core/QueryService.ts
index bf50a1cded..435d5d2389 100644
--- a/packages/backend/src/core/QueryService.ts
+++ b/packages/backend/src/core/QueryService.ts
@@ -60,8 +60,8 @@ export class QueryService {
 			q.orderBy(`${q.alias}.id`, 'DESC');
 		}
 		return q;
-	}	
-	
+	}
+
 	// ここでいうBlockedは被Blockedの意
 	@bindThis
 	public generateBlockedUserQuery(q: SelectQueryBuilder<any>, me: { id: User['id'] }): void {
@@ -109,18 +109,18 @@ export class QueryService {
 			q.andWhere('note.channelId IS NULL');
 		} else {
 			q.leftJoinAndSelect('note.channel', 'channel');
-	
+
 			const channelFollowingQuery = this.channelFollowingsRepository.createQueryBuilder('channelFollowing')
 				.select('channelFollowing.followeeId')
 				.where('channelFollowing.followerId = :followerId', { followerId: me.id });
-	
+
 			q.andWhere(new Brackets(qb => { qb
 				// チャンネルのノートではない
 				.where('note.channelId IS NULL')
 				// または自分がフォローしているチャンネルのノート
 				.orWhere(`note.channelId IN (${ channelFollowingQuery.getQuery() })`);
 			}));
-	
+
 			q.setParameters(channelFollowingQuery.getParameters());
 		}
 	}
@@ -130,9 +130,9 @@ export class QueryService {
 		const mutedQuery = this.mutedNotesRepository.createQueryBuilder('muted')
 			.select('muted.noteId')
 			.where('muted.userId = :userId', { userId: me.id });
-	
+
 		q.andWhere(`note.id NOT IN (${ mutedQuery.getQuery() })`);
-	
+
 		q.setParameters(mutedQuery.getParameters());
 	}
 
@@ -141,13 +141,13 @@ export class QueryService {
 		const mutedQuery = this.noteThreadMutingsRepository.createQueryBuilder('threadMuted')
 			.select('threadMuted.threadId')
 			.where('threadMuted.userId = :userId', { userId: me.id });
-	
+
 		q.andWhere(`note.id NOT IN (${ mutedQuery.getQuery() })`);
 		q.andWhere(new Brackets(qb => { qb
 			.where('note.threadId IS NULL')
 			.orWhere(`note.threadId NOT IN (${ mutedQuery.getQuery() })`);
 		}));
-	
+
 		q.setParameters(mutedQuery.getParameters());
 	}
 
@@ -156,15 +156,15 @@ export class QueryService {
 		const mutingQuery = this.mutingsRepository.createQueryBuilder('muting')
 			.select('muting.muteeId')
 			.where('muting.muterId = :muterId', { muterId: me.id });
-	
+
 		if (exclude) {
 			mutingQuery.andWhere('muting.muteeId != :excludeId', { excludeId: exclude.id });
 		}
-	
+
 		const mutingInstanceQuery = this.userProfilesRepository.createQueryBuilder('user_profile')
 			.select('user_profile.mutedInstances')
 			.where('user_profile.userId = :muterId', { muterId: me.id });
-	
+
 		// 投稿の作者をミュートしていない かつ
 		// 投稿の返信先の作者をミュートしていない かつ
 		// 投稿の引用元の作者をミュートしていない
@@ -191,7 +191,7 @@ export class QueryService {
 				.where('note.renoteUserHost IS NULL')
 				.orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.renoteUserHost)`);
 			}));
-	
+
 		q.setParameters(mutingQuery.getParameters());
 		q.setParameters(mutingInstanceQuery.getParameters());
 	}
@@ -201,9 +201,9 @@ export class QueryService {
 		const mutingQuery = this.mutingsRepository.createQueryBuilder('muting')
 			.select('muting.muteeId')
 			.where('muting.muterId = :muterId', { muterId: me.id });
-	
+
 		q.andWhere(`user.id NOT IN (${ mutingQuery.getQuery() })`);
-	
+
 		q.setParameters(mutingQuery.getParameters());
 	}
 
@@ -245,7 +245,7 @@ export class QueryService {
 			const followingQuery = this.followingsRepository.createQueryBuilder('following')
 				.select('following.followeeId')
 				.where('following.followerId = :meId');
-	
+
 			q.andWhere(new Brackets(qb => { qb
 				// 公開投稿である
 				.where(new Brackets(qb => { qb
@@ -268,7 +268,7 @@ export class QueryService {
 					}));
 				}));
 			}));
-	
+
 			q.setParameters({ meId: me.id });
 		}
 	}
@@ -278,10 +278,10 @@ export class QueryService {
 		const mutingQuery = this.renoteMutingsRepository.createQueryBuilder('renote_muting')
 			.select('renote_muting.muteeId')
 			.where('renote_muting.muterId = :muterId', { muterId: me.id });
-	
+
 		q.andWhere(new Brackets(qb => {
 			qb
-				.where(new Brackets(qb => { 
+				.where(new Brackets(qb => {
 					qb.where('note.renoteId IS NOT NULL');
 					qb.andWhere('note.text IS NULL');
 					qb.andWhere(`note.userId NOT IN (${ mutingQuery.getQuery() })`);
@@ -289,7 +289,7 @@ export class QueryService {
 				.orWhere('note.renoteId IS NULL')
 				.orWhere('note.text IS NOT NULL');
 		}));
-		
+
 		q.setParameters(mutingQuery.getParameters());
 	}
 }
diff --git a/packages/backend/src/core/RelayService.ts b/packages/backend/src/core/RelayService.ts
index 9d34d82be2..c0113a21d7 100644
--- a/packages/backend/src/core/RelayService.ts
+++ b/packages/backend/src/core/RelayService.ts
@@ -39,9 +39,9 @@ export class RelayService {
 			host: IsNull(),
 			username: ACTOR_USERNAME,
 		});
-	
+
 		if (user) return user as LocalUser;
-	
+
 		const created = await this.createSystemUserService.createSystemUser(ACTOR_USERNAME);
 		return created as LocalUser;
 	}
@@ -53,12 +53,12 @@ export class RelayService {
 			inbox,
 			status: 'requesting',
 		}).then(x => this.relaysRepository.findOneByOrFail(x.identifiers[0]));
-	
+
 		const relayActor = await this.getRelayActor();
 		const follow = await this.apRendererService.renderFollowRelay(relay, relayActor);
 		const activity = this.apRendererService.addContext(follow);
 		this.queueService.deliver(relayActor, activity, relay.inbox, false);
-	
+
 		return relay;
 	}
 
@@ -67,17 +67,17 @@ export class RelayService {
 		const relay = await this.relaysRepository.findOneBy({
 			inbox,
 		});
-	
+
 		if (relay == null) {
 			throw new Error('relay not found');
 		}
-	
+
 		const relayActor = await this.getRelayActor();
 		const follow = this.apRendererService.renderFollowRelay(relay, relayActor);
 		const undo = this.apRendererService.renderUndo(follow, relayActor);
 		const activity = this.apRendererService.addContext(undo);
 		this.queueService.deliver(relayActor, activity, relay.inbox, false);
-	
+
 		await this.relaysRepository.delete(relay.id);
 	}
 
@@ -86,13 +86,13 @@ export class RelayService {
 		const relays = await this.relaysRepository.find();
 		return relays;
 	}
-	
+
 	@bindThis
 	public async relayAccepted(id: string): Promise<string> {
 		const result = await this.relaysRepository.update(id, {
 			status: 'accepted',
 		});
-	
+
 		return JSON.stringify(result);
 	}
 
@@ -101,24 +101,24 @@ export class RelayService {
 		const result = await this.relaysRepository.update(id, {
 			status: 'rejected',
 		});
-	
+
 		return JSON.stringify(result);
 	}
 
 	@bindThis
 	public async deliverToRelays(user: { id: User['id']; host: null; }, activity: any): Promise<void> {
 		if (activity == null) return;
-	
+
 		const relays = await this.relaysCache.fetch(() => this.relaysRepository.findBy({
 			status: 'accepted',
 		}));
 		if (relays.length === 0) return;
-	
+
 		const copy = deepClone(activity);
 		if (!copy.to) copy.to = ['https://www.w3.org/ns/activitystreams#Public'];
-	
+
 		const signed = await this.apRendererService.attachLdSignature(copy, user);
-	
+
 		for (const relay of relays) {
 			this.queueService.deliver(user, signed, relay.inbox, false);
 		}
diff --git a/packages/backend/src/core/RemoteUserResolveService.ts b/packages/backend/src/core/RemoteUserResolveService.ts
index ff68c24219..ed15a1f1ce 100644
--- a/packages/backend/src/core/RemoteUserResolveService.ts
+++ b/packages/backend/src/core/RemoteUserResolveService.ts
@@ -35,7 +35,7 @@ export class RemoteUserResolveService {
 	@bindThis
 	public async resolveUser(username: string, host: string | null): Promise<LocalUser | RemoteUser> {
 		const usernameLower = username.toLowerCase();
-	
+
 		if (host == null) {
 			this.logger.info(`return local user: ${usernameLower}`);
 			return await this.usersRepository.findOneBy({ usernameLower, host: IsNull() }).then(u => {
@@ -46,9 +46,9 @@ export class RemoteUserResolveService {
 				}
 			}) as LocalUser;
 		}
-	
+
 		host = this.utilityService.toPuny(host);
-	
+
 		if (this.config.host === host) {
 			this.logger.info(`return local user: ${usernameLower}`);
 			return await this.usersRepository.findOneBy({ usernameLower, host: IsNull() }).then(u => {
@@ -59,39 +59,39 @@ export class RemoteUserResolveService {
 				}
 			}) as LocalUser;
 		}
-	
+
 		const user = await this.usersRepository.findOneBy({ usernameLower, host }) as RemoteUser | null;
-	
+
 		const acctLower = `${usernameLower}@${host}`;
-	
+
 		if (user == null) {
 			const self = await this.resolveSelf(acctLower);
-	
+
 			this.logger.succ(`return new remote user: ${chalk.magenta(acctLower)}`);
 			return await this.apPersonService.createPerson(self.href);
 		}
-	
+
 		// ユーザー情報が古い場合は、WebFilgerからやりなおして返す
 		if (user.lastFetchedAt == null || Date.now() - user.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) {
 			// 繋がらないインスタンスに何回も試行するのを防ぐ, 後続の同様処理の連続試行を防ぐ ため 試行前にも更新する
 			await this.usersRepository.update(user.id, {
 				lastFetchedAt: new Date(),
 			});
-	
+
 			this.logger.info(`try resync: ${acctLower}`);
 			const self = await this.resolveSelf(acctLower);
-	
+
 			if (user.uri !== self.href) {
 				// if uri mismatch, Fix (user@host <=> AP's Person id(RemoteUser.uri)) mapping.
 				this.logger.info(`uri missmatch: ${acctLower}`);
 				this.logger.info(`recovery missmatch uri for (username=${username}, host=${host}) from ${user.uri} to ${self.href}`);
-	
+
 				// validate uri
 				const uri = new URL(self.href);
 				if (uri.hostname !== host) {
 					throw new Error('Invalid uri');
 				}
-	
+
 				await this.usersRepository.update({
 					usernameLower,
 					host: host,
@@ -101,9 +101,9 @@ export class RemoteUserResolveService {
 			} else {
 				this.logger.info(`uri is fine: ${acctLower}`);
 			}
-	
+
 			await this.apPersonService.updatePerson(self.href);
-	
+
 			this.logger.info(`return resynced remote user: ${acctLower}`);
 			return await this.usersRepository.findOneBy({ uri: self.href }).then(u => {
 				if (u == null) {
@@ -113,7 +113,7 @@ export class RemoteUserResolveService {
 				}
 			});
 		}
-	
+
 		this.logger.info(`return existing remote user: ${acctLower}`);
 		return user;
 	}
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index 23ecf0157d..b0bfb44dc2 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -392,7 +392,7 @@ export class RoleService implements OnApplicationShutdown {
 	@bindThis
 	public async unassign(userId: User['id'], roleId: Role['id']): Promise<void> {
 		const now = new Date();
-	
+
 		const existing = await this.roleAssignmentsRepository.findOneBy({ roleId, userId });
 		if (existing == null) {
 			throw new RoleService.NotAssignedError();
diff --git a/packages/backend/src/core/SignupService.ts b/packages/backend/src/core/SignupService.ts
index 29eb65fda4..e6b17a8741 100644
--- a/packages/backend/src/core/SignupService.ts
+++ b/packages/backend/src/core/SignupService.ts
@@ -50,31 +50,31 @@ export class SignupService {
 	}) {
 		const { username, password, passwordHash, host } = opts;
 		let hash = passwordHash;
-	
+
 		// Validate username
 		if (!this.userEntityService.validateLocalUsername(username)) {
 			throw new Error('INVALID_USERNAME');
 		}
-	
+
 		if (password != null && passwordHash == null) {
 			// Validate password
 			if (!this.userEntityService.validatePassword(password)) {
 				throw new Error('INVALID_PASSWORD');
 			}
-	
+
 			// Generate hash of password
 			const salt = await bcrypt.genSalt(8);
 			hash = await bcrypt.hash(password, salt);
 		}
-	
+
 		// Generate secret
 		const secret = generateUserToken();
-	
+
 		// Check username duplication
 		if (await this.usersRepository.findOneBy({ usernameLower: username.toLowerCase(), host: IsNull() })) {
 			throw new Error('DUPLICATED_USERNAME');
 		}
-	
+
 		// Check deleted username duplication
 		if (await this.usedUsernamesRepository.findOneBy({ username: username.toLowerCase() })) {
 			throw new Error('USED_USERNAME');
@@ -106,18 +106,18 @@ export class SignupService {
 			}, (err, publicKey, privateKey) =>
 				err ? rej(err) : res([publicKey, privateKey]),
 			));
-	
+
 		let account!: User;
-	
+
 		// Start transaction
 		await this.db.transaction(async transactionalEntityManager => {
 			const exist = await transactionalEntityManager.findOneBy(User, {
 				usernameLower: username.toLowerCase(),
 				host: IsNull(),
 			});
-	
+
 			if (exist) throw new Error(' the username is already used');
-	
+
 			account = await transactionalEntityManager.save(new User({
 				id: this.idService.genId(),
 				createdAt: new Date(),
@@ -127,27 +127,27 @@ export class SignupService {
 				token: secret,
 				isRoot: isTheFirstUser,
 			}));
-	
+
 			await transactionalEntityManager.save(new UserKeypair({
 				publicKey: keyPair[0],
 				privateKey: keyPair[1],
 				userId: account.id,
 			}));
-	
+
 			await transactionalEntityManager.save(new UserProfile({
 				userId: account.id,
 				autoAcceptFollowed: true,
 				password: hash,
 			}));
-	
+
 			await transactionalEntityManager.save(new UsedUsername({
 				createdAt: new Date(),
 				username: username.toLowerCase(),
 			}));
 		});
-	
+
 		this.usersChart.update(account, true);
-	
+
 		return { account, secret };
 	}
 }
diff --git a/packages/backend/src/core/TwoFactorAuthenticationService.ts b/packages/backend/src/core/TwoFactorAuthenticationService.ts
index dda78236e9..d4cf186a24 100644
--- a/packages/backend/src/core/TwoFactorAuthenticationService.ts
+++ b/packages/backend/src/core/TwoFactorAuthenticationService.ts
@@ -69,7 +69,7 @@ function verifyCertificateChain(certificates: string[]) {
 
 		const certStruct = jsrsasign.ASN1HEX.getTLVbyList(certificate.hex!, 0, [0]);
 		if (certStruct == null) throw new Error('certStruct is null');
-		
+
 		const algorithm = certificate.getSignatureAlgorithmField();
 		const signatureHex = certificate.getSignatureValueHex();
 
@@ -143,19 +143,19 @@ export class TwoFactorAuthenticationService {
 		if (clientData.type !== 'webauthn.get') {
 			throw new Error('type is not webauthn.get');
 		}
-	
+
 		if (this.hash(clientData.challenge).toString('hex') !== challenge) {
 			throw new Error('challenge mismatch');
 		}
 		if (clientData.origin !== this.config.scheme + '://' + this.config.host) {
 			throw new Error('origin mismatch');
 		}
-	
+
 		const verificationData = Buffer.concat(
 			[authenticatorData, this.hash(clientDataJSON)],
 			32 + authenticatorData.length,
 		);
-	
+
 		return crypto
 			.createVerify('SHA256')
 			.update(verificationData)
@@ -168,7 +168,7 @@ export class TwoFactorAuthenticationService {
 			none: {
 				verify({ publicKey }: { publicKey: Map<number, Buffer> }) {
 					const negTwo = publicKey.get(-2);
-		
+
 					if (!negTwo || negTwo.length !== 32) {
 						throw new Error('invalid or no -2 key given');
 					}
@@ -176,12 +176,12 @@ export class TwoFactorAuthenticationService {
 					if (!negThree || negThree.length !== 32) {
 						throw new Error('invalid or no -3 key given');
 					}
-		
+
 					const publicKeyU2F = Buffer.concat(
 						[ECC_PRELUDE, negTwo, negThree],
 						1 + 32 + 32,
 					);
-		
+
 					return {
 						publicKey: publicKeyU2F,
 						valid: true,
@@ -207,16 +207,16 @@ export class TwoFactorAuthenticationService {
 					if (attStmt.alg !== -7) {
 						throw new Error('alg mismatch');
 					}
-		
+
 					const verificationData = Buffer.concat([
 						authenticatorData,
 						clientDataHash,
 					]);
-		
+
 					const attCert: Buffer = attStmt.x5c[0];
-		
+
 					const negTwo = publicKey.get(-2);
-		
+
 					if (!negTwo || negTwo.length !== 32) {
 						throw new Error('invalid or no -2 key given');
 					}
@@ -224,23 +224,23 @@ export class TwoFactorAuthenticationService {
 					if (!negThree || negThree.length !== 32) {
 						throw new Error('invalid or no -3 key given');
 					}
-		
+
 					const publicKeyData = Buffer.concat(
 						[ECC_PRELUDE, negTwo, negThree],
 						1 + 32 + 32,
 					);
-		
+
 					if (!attCert.equals(publicKeyData)) {
 						throw new Error('public key mismatch');
 					}
-		
+
 					const isValid = crypto
 						.createVerify('SHA256')
 						.update(verificationData)
 						.verify(PEMString(attCert), attStmt.sig);
-		
+
 					// TODO: Check 'attestationChallenge' field in extension of cert matches hash(clientDataJSON)
-		
+
 					return {
 						valid: isValid,
 						publicKey: publicKeyData,
@@ -267,43 +267,43 @@ export class TwoFactorAuthenticationService {
 					const verificationData = this.hash(
 						Buffer.concat([authenticatorData, clientDataHash]),
 					);
-		
+
 					const jwsParts = attStmt.response.toString('utf-8').split('.');
-		
+
 					const header = JSON.parse(base64URLDecode(jwsParts[0]).toString('utf-8'));
 					const response = JSON.parse(
 						base64URLDecode(jwsParts[1]).toString('utf-8'),
 					);
 					const signature = jwsParts[2];
-		
+
 					if (!verificationData.equals(Buffer.from(response.nonce, 'base64'))) {
 						throw new Error('invalid nonce');
 					}
-		
+
 					const certificateChain = header.x5c
 						.map((key: any) => PEMString(key))
 						.concat([GSR2]);
-		
+
 					if (getCertSubject(certificateChain[0]).CN !== 'attest.android.com') {
 						throw new Error('invalid common name');
 					}
-		
+
 					if (!verifyCertificateChain(certificateChain)) {
 						throw new Error('Invalid certificate chain!');
 					}
-		
+
 					const signatureBase = Buffer.from(
 						jwsParts[0] + '.' + jwsParts[1],
 						'utf-8',
 					);
-		
+
 					const valid = crypto
 						.createVerify('sha256')
 						.update(signatureBase)
 						.verify(certificateChain[0], base64URLDecode(signature));
-		
+
 					const negTwo = publicKey.get(-2);
-		
+
 					if (!negTwo || negTwo.length !== 32) {
 						throw new Error('invalid or no -2 key given');
 					}
@@ -311,7 +311,7 @@ export class TwoFactorAuthenticationService {
 					if (!negThree || negThree.length !== 32) {
 						throw new Error('invalid or no -3 key given');
 					}
-		
+
 					const publicKeyData = Buffer.concat(
 						[ECC_PRELUDE, negTwo, negThree],
 						1 + 32 + 32,
@@ -342,17 +342,17 @@ export class TwoFactorAuthenticationService {
 						authenticatorData,
 						clientDataHash,
 					]);
-		
+
 					if (attStmt.x5c) {
 						const attCert = attStmt.x5c[0];
-		
+
 						const validSignature = crypto
 							.createVerify('SHA256')
 							.update(verificationData)
 							.verify(PEMString(attCert), attStmt.sig);
-		
+
 						const negTwo = publicKey.get(-2);
-		
+
 						if (!negTwo || negTwo.length !== 32) {
 							throw new Error('invalid or no -2 key given');
 						}
@@ -360,12 +360,12 @@ export class TwoFactorAuthenticationService {
 						if (!negThree || negThree.length !== 32) {
 							throw new Error('invalid or no -3 key given');
 						}
-		
+
 						const publicKeyData = Buffer.concat(
 							[ECC_PRELUDE, negTwo, negThree],
 							1 + 32 + 32,
 						);
-		
+
 						return {
 							valid: validSignature,
 							publicKey: publicKeyData,
@@ -375,12 +375,12 @@ export class TwoFactorAuthenticationService {
 						throw new Error('ECDAA-Verify is not supported');
 					} else {
 						if (attStmt.alg !== -7) throw new Error('alg mismatch');
-		
+
 						throw new Error('self attestation is not supported');
 					}
 				},
 			},
-		
+
 			'fido-u2f': {
 				verify({
 					attStmt,
@@ -401,13 +401,13 @@ export class TwoFactorAuthenticationService {
 					if (x5c.length !== 1) {
 						throw new Error('x5c length does not match expectation');
 					}
-		
+
 					const attCert = x5c[0];
-		
+
 					// TODO: make sure attCert is an Elliptic Curve (EC) public key over the P-256 curve
-		
+
 					const negTwo: Buffer = publicKey.get(-2);
-		
+
 					if (!negTwo || negTwo.length !== 32) {
 						throw new Error('invalid or no -2 key given');
 					}
@@ -415,12 +415,12 @@ export class TwoFactorAuthenticationService {
 					if (!negThree || negThree.length !== 32) {
 						throw new Error('invalid or no -3 key given');
 					}
-		
+
 					const publicKeyU2F = Buffer.concat(
 						[ECC_PRELUDE, negTwo, negThree],
 						1 + 32 + 32,
 					);
-		
+
 					const verificationData = Buffer.concat([
 						NULL_BYTE,
 						rpIdHash,
@@ -428,12 +428,12 @@ export class TwoFactorAuthenticationService {
 						credentialId,
 						publicKeyU2F,
 					]);
-		
+
 					const validSignature = crypto
 						.createVerify('SHA256')
 						.update(verificationData)
 						.verify(PEMString(attCert), attStmt.sig);
-		
+
 					return {
 						valid: validSignature,
 						publicKey: publicKeyU2F,
diff --git a/packages/backend/src/core/UserSuspendService.ts b/packages/backend/src/core/UserSuspendService.ts
index b197d335d8..28ae32681d 100644
--- a/packages/backend/src/core/UserSuspendService.ts
+++ b/packages/backend/src/core/UserSuspendService.ts
@@ -32,13 +32,13 @@ export class UserSuspendService {
 	@bindThis
 	public async doPostSuspend(user: { id: User['id']; host: User['host'] }): Promise<void> {
 		this.globalEventService.publishInternalEvent('userChangeSuspendedState', { id: user.id, isSuspended: true });
-	
+
 		if (this.userEntityService.isLocalUser(user)) {
 			// 知り得る全SharedInboxにDelete配信
 			const content = this.apRendererService.addContext(this.apRendererService.renderDelete(this.userEntityService.genLocalUserUri(user.id), user));
-	
+
 			const queue: string[] = [];
-	
+
 			const followings = await this.followingsRepository.find({
 				where: [
 					{ followerSharedInbox: Not(IsNull()) },
@@ -46,13 +46,13 @@ export class UserSuspendService {
 				],
 				select: ['followerSharedInbox', 'followeeSharedInbox'],
 			});
-	
+
 			const inboxes = followings.map(x => x.followerSharedInbox ?? x.followeeSharedInbox);
-	
+
 			for (const inbox of inboxes) {
 				if (inbox != null && !queue.includes(inbox)) queue.push(inbox);
 			}
-	
+
 			for (const inbox of queue) {
 				this.queueService.deliver(user, content, inbox, true);
 			}
@@ -62,13 +62,13 @@ export class UserSuspendService {
 	@bindThis
 	public async doPostUnsuspend(user: User): Promise<void> {
 		this.globalEventService.publishInternalEvent('userChangeSuspendedState', { id: user.id, isSuspended: false });
-	
+
 		if (this.userEntityService.isLocalUser(user)) {
 			// 知り得る全SharedInboxにUndo Delete配信
 			const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderDelete(this.userEntityService.genLocalUserUri(user.id), user), user));
-	
+
 			const queue: string[] = [];
-	
+
 			const followings = await this.followingsRepository.find({
 				where: [
 					{ followerSharedInbox: Not(IsNull()) },
@@ -76,13 +76,13 @@ export class UserSuspendService {
 				],
 				select: ['followerSharedInbox', 'followeeSharedInbox'],
 			});
-	
+
 			const inboxes = followings.map(x => x.followerSharedInbox ?? x.followeeSharedInbox);
-	
+
 			for (const inbox of inboxes) {
 				if (inbox != null && !queue.includes(inbox)) queue.push(inbox);
 			}
-	
+
 			for (const inbox of queue) {
 				this.queueService.deliver(user as any, content, inbox, true);
 			}
diff --git a/packages/backend/src/core/VideoProcessingService.ts b/packages/backend/src/core/VideoProcessingService.ts
index 5869905db0..89681f3372 100644
--- a/packages/backend/src/core/VideoProcessingService.ts
+++ b/packages/backend/src/core/VideoProcessingService.ts
@@ -21,7 +21,7 @@ export class VideoProcessingService {
 	@bindThis
 	public async generateVideoThumbnail(source: string): Promise<IImage> {
 		const [dir, cleanup] = await createTempDir();
-	
+
 		try {
 			await new Promise((res, rej) => {
 				FFmpeg({
diff --git a/packages/backend/src/core/WebhookService.ts b/packages/backend/src/core/WebhookService.ts
index 467755a072..b6f5263901 100644
--- a/packages/backend/src/core/WebhookService.ts
+++ b/packages/backend/src/core/WebhookService.ts
@@ -31,7 +31,7 @@ export class WebhookService implements OnApplicationShutdown {
 			});
 			this.webhooksFetched = true;
 		}
-	
+
 		return this.webhooks;
 	}
 
diff --git a/packages/backend/src/core/activitypub/ApAudienceService.ts b/packages/backend/src/core/activitypub/ApAudienceService.ts
index 8282a6324c..0eab7fa335 100644
--- a/packages/backend/src/core/activitypub/ApAudienceService.ts
+++ b/packages/backend/src/core/activitypub/ApAudienceService.ts
@@ -27,14 +27,14 @@ export class ApAudienceService {
 	public async parseAudience(actor: RemoteUser, to?: ApObject, cc?: ApObject, resolver?: Resolver): Promise<AudienceInfo> {
 		const toGroups = this.groupingAudience(getApIds(to), actor);
 		const ccGroups = this.groupingAudience(getApIds(cc), actor);
-	
+
 		const others = unique(concat([toGroups.other, ccGroups.other]));
-	
+
 		const limit = promiseLimit<User | null>(2);
 		const mentionedUsers = (await Promise.all(
 			others.map(id => limit(() => this.apPersonService.resolvePerson(id, resolver).catch(() => null))),
 		)).filter((x): x is User => x != null);
-	
+
 		if (toGroups.public.length > 0) {
 			return {
 				visibility: 'public',
@@ -42,7 +42,7 @@ export class ApAudienceService {
 				visibleUsers: [],
 			};
 		}
-	
+
 		if (ccGroups.public.length > 0) {
 			return {
 				visibility: 'home',
@@ -50,7 +50,7 @@ export class ApAudienceService {
 				visibleUsers: [],
 			};
 		}
-	
+
 		if (toGroups.followers.length > 0) {
 			return {
 				visibility: 'followers',
@@ -58,14 +58,14 @@ export class ApAudienceService {
 				visibleUsers: [],
 			};
 		}
-	
+
 		return {
 			visibility: 'specified',
 			mentionedUsers,
 			visibleUsers: mentionedUsers,
 		};
 	}
-	
+
 	@bindThis
 	private groupingAudience(ids: string[], actor: RemoteUser) {
 		const groups = {
@@ -73,7 +73,7 @@ export class ApAudienceService {
 			followers: [] as string[],
 			other: [] as string[],
 		};
-	
+
 		for (const id of ids) {
 			if (this.isPublic(id)) {
 				groups.public.push(id);
@@ -83,12 +83,12 @@ export class ApAudienceService {
 				groups.other.push(id);
 			}
 		}
-	
+
 		groups.other = unique(groups.other);
-	
+
 		return groups;
 	}
-	
+
 	@bindThis
 	private isPublic(id: string) {
 		return [
@@ -97,7 +97,7 @@ export class ApAudienceService {
 			'Public',
 		].includes(id);
 	}
-	
+
 	@bindThis
 	private isFollowers(id: string, actor: RemoteUser) {
 		return (
diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts
index ca148916dc..20283a163c 100644
--- a/packages/backend/src/core/activitypub/ApDbResolverService.ts
+++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts
@@ -121,7 +121,7 @@ export class ApDbResolverService implements OnApplicationShutdown {
 			const key = await this.userPublickeysRepository.findOneBy({
 				keyId,
 			});
-	
+
 			if (key == null) return null;
 
 			return key;
@@ -147,7 +147,7 @@ export class ApDbResolverService implements OnApplicationShutdown {
 
 		if (user == null) return null;
 
-		const key = await this.publicKeyByUserIdCache.fetch(user.id, () => this.userPublickeysRepository.findOneBy({ userId: user.id }), v => v != null); 
+		const key = await this.publicKeyByUserIdCache.fetch(user.id, () => this.userPublickeysRepository.findOneBy({ userId: user.id }), v => v != null);
 
 		return {
 			user,
diff --git a/packages/backend/src/core/activitypub/ApDeliverManagerService.ts b/packages/backend/src/core/activitypub/ApDeliverManagerService.ts
index 6e910eb538..82c2c9f71f 100644
--- a/packages/backend/src/core/activitypub/ApDeliverManagerService.ts
+++ b/packages/backend/src/core/activitypub/ApDeliverManagerService.ts
@@ -90,7 +90,7 @@ export class ApDeliverManagerService {
 			this.followingsRepository,
 			this.queueService,
 
-			actor, 
+			actor,
 			activity,
 		);
 	}
diff --git a/packages/backend/src/core/activitypub/ApMfmService.ts b/packages/backend/src/core/activitypub/ApMfmService.ts
index 6116822f7a..411cf17d19 100644
--- a/packages/backend/src/core/activitypub/ApMfmService.ts
+++ b/packages/backend/src/core/activitypub/ApMfmService.ts
@@ -21,7 +21,7 @@ export class ApMfmService {
 	@bindThis
 	public htmlToMfm(html: string, tag?: IObject | IObject[]) {
 		const hashtagNames = extractApHashtagObjects(tag).map(x => x.name).filter((x): x is string => x != null);
-	
+
 		return this.mfmService.fromHtml(html, hashtagNames);
 	}
 
@@ -29,5 +29,5 @@ export class ApMfmService {
 	public getNoteHtml(note: Note) {
 		if (!note.text) return '';
 		return this.mfmService.toHtml(mfm.parse(note.text), JSON.parse(note.mentionedRemoteUsers));
-	}	
+	}
 }
diff --git a/packages/backend/src/core/activitypub/models/ApImageService.ts b/packages/backend/src/core/activitypub/models/ApImageService.ts
index 0043907c21..79c5ae958a 100644
--- a/packages/backend/src/core/activitypub/models/ApImageService.ts
+++ b/packages/backend/src/core/activitypub/models/ApImageService.ts
@@ -32,7 +32,7 @@ export class ApImageService {
 	) {
 		this.logger = this.apLoggerService.logger;
 	}
-	
+
 	/**
 	 * Imageを作成します。
 	 */
diff --git a/packages/backend/src/core/activitypub/models/ApMentionService.ts b/packages/backend/src/core/activitypub/models/ApMentionService.ts
index c581840ca9..9beefc8fcb 100644
--- a/packages/backend/src/core/activitypub/models/ApMentionService.ts
+++ b/packages/backend/src/core/activitypub/models/ApMentionService.ts
@@ -29,10 +29,10 @@ export class ApMentionService {
 		const mentionedUsers = (await Promise.all(
 			hrefs.map(x => limit(() => this.apPersonService.resolvePerson(x, resolver).catch(() => null))),
 		)).filter((x): x is User => x != null);
-	
+
 		return mentionedUsers;
 	}
-	
+
 	@bindThis
 	public extractApMentionObjects(tags: IObject | IObject[] | null | undefined): IApMention[] {
 		if (tags == null) return [];
diff --git a/packages/backend/src/core/activitypub/models/ApNoteService.ts b/packages/backend/src/core/activitypub/models/ApNoteService.ts
index 76757f530a..60a3e56800 100644
--- a/packages/backend/src/core/activitypub/models/ApNoteService.ts
+++ b/packages/backend/src/core/activitypub/models/ApNoteService.ts
@@ -55,7 +55,7 @@ export class ApNoteService {
 		// 循環参照のため / for circular dependency
 		@Inject(forwardRef(() => ApPersonService))
 		private apPersonService: ApPersonService,
-	
+
 		private utilityService: UtilityService,
 		private apAudienceService: ApAudienceService,
 		private apMentionService: ApMentionService,
@@ -74,15 +74,15 @@ export class ApNoteService {
 	@bindThis
 	public validateNote(object: IObject, uri: string) {
 		const expectHost = this.utilityService.extractDbHost(uri);
-	
+
 		if (object == null) {
 			return new Error('invalid Note: object is null');
 		}
-	
+
 		if (!validPost.includes(getApType(object))) {
 			return new Error(`invalid Note: invalid object type ${getApType(object)}`);
 		}
-	
+
 		if (object.id && this.utilityService.extractDbHost(object.id) !== expectHost) {
 			return new Error(`invalid Note: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`);
 		}
@@ -91,10 +91,10 @@ export class ApNoteService {
 		if (object.attributedTo && actualHost !== expectHost) {
 			return new Error(`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`);
 		}
-	
+
 		return null;
 	}
-	
+
 	/**
 	 * Noteをフェッチします。
 	 *
@@ -104,16 +104,16 @@ export class ApNoteService {
 	public async fetchNote(object: string | IObject): Promise<Note | null> {
 		return await this.apDbResolverService.getNoteFromApId(object);
 	}
-	
+
 	/**
 	 * Noteを作成します。
 	 */
 	@bindThis
 	public async createNote(value: string | IObject, resolver?: Resolver, silent = false): Promise<Note | null> {
 		if (resolver == null) resolver = this.apResolverService.createResolver();
-	
+
 		const object = await resolver.resolve(value);
-	
+
 		const entryUri = getApId(value);
 		const err = this.validateNote(object, entryUri);
 		if (err) {
@@ -126,9 +126,9 @@ export class ApNoteService {
 			});
 			throw new Error('invalid note');
 		}
-	
+
 		const note = object as IPost;
-	
+
 		this.logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`);
 
 		if (note.id && !checkHttps(note.id)) {
@@ -140,21 +140,21 @@ export class ApNoteService {
 		if (url && !checkHttps(url)) {
 			throw new Error('unexpected shcema of note url: ' + url);
 		}
-	
+
 		this.logger.info(`Creating the Note: ${note.id}`);
-	
+
 		// 投稿者をフェッチ
 		const actor = await this.apPersonService.resolvePerson(getOneApId(note.attributedTo!), resolver) as RemoteUser;
-	
+
 		// 投稿者が凍結されていたらスキップ
 		if (actor.isSuspended) {
 			throw new Error('actor has been suspended');
 		}
-		
+
 		const noteAudience = await this.apAudienceService.parseAudience(actor, note.to, note.cc, resolver);
 		let visibility = noteAudience.visibility;
 		const visibleUsers = noteAudience.visibleUsers;
-	
+
 		// Audience (to, cc) が指定されてなかった場合
 		if (visibility === 'specified' && visibleUsers.length === 0) {
 			if (typeof value === 'string') {	// 入力がstringならばresolverでGETが発生している
@@ -162,23 +162,23 @@ export class ApNoteService {
 				visibility = 'public';
 			}
 		}
-	
+
 		const apMentions = await this.apMentionService.extractApMentions(note.tag, resolver);
 		const apHashtags = await extractApHashtags(note.tag);
-	
+
 		// 添付ファイル
 		// TODO: attachmentは必ずしもImageではない
 		// TODO: attachmentは必ずしも配列ではない
 		// Noteがsensitiveなら添付もsensitiveにする
 		const limit = promiseLimit(2);
-	
+
 		note.attachment = Array.isArray(note.attachment) ? note.attachment : note.attachment ? [note.attachment] : [];
 		const files = note.attachment
 			.map(attach => attach.sensitive = note.sensitive)
 			? (await Promise.all(note.attachment.map(x => limit(() => this.apImageService.resolveImage(actor, x)) as Promise<DriveFile>)))
 				.filter(image => image != null)
 			: [];
-	
+
 		// リプライ
 		const reply: Note | null = note.inReplyTo
 			? await this.resolveNote(note.inReplyTo, resolver).then(x => {
@@ -193,10 +193,10 @@ export class ApNoteService {
 				throw err;
 			})
 			: null;
-	
+
 		// 引用
 		let quote: Note | undefined | null;
-	
+
 		if (note._misskey_quote || note.quoteUrl) {
 			const tryResolveNote = async (uri: string): Promise<{
 				status: 'ok';
@@ -223,10 +223,10 @@ export class ApNoteService {
 					};
 				}
 			};
-	
+
 			const uris = unique([note._misskey_quote, note.quoteUrl].filter((x): x is string => typeof x === 'string'));
 			const results = await Promise.all(uris.map(uri => tryResolveNote(uri)));
-	
+
 			quote = results.filter((x): x is { status: 'ok', res: Note | null } => x.status === 'ok').map(x => x.res).find(x => x);
 			if (!quote) {
 				if (results.some(x => x.status === 'temperror')) {
@@ -234,9 +234,9 @@ export class ApNoteService {
 				}
 			}
 		}
-	
+
 		const cw = note.summary === '' ? null : note.summary;
-	
+
 		// テキストのパース
 		let text: string | null = null;
 		if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source.content === 'string') {
@@ -246,38 +246,38 @@ export class ApNoteService {
 		} else if (typeof note.content === 'string') {
 			text = this.apMfmService.htmlToMfm(note.content, note.tag);
 		}
-	
+
 		// vote
 		if (reply && reply.hasPoll) {
 			const poll = await this.pollsRepository.findOneByOrFail({ noteId: reply.id });
-	
+
 			const tryCreateVote = async (name: string, index: number): Promise<null> => {
 				if (poll.expiresAt && Date.now() > new Date(poll.expiresAt).getTime()) {
 					this.logger.warn(`vote to expired poll from AP: actor=${actor.username}@${actor.host}, note=${note.id}, choice=${name}`);
 				} else if (index >= 0) {
 					this.logger.info(`vote from AP: actor=${actor.username}@${actor.host}, note=${note.id}, choice=${name}`);
 					await this.pollService.vote(actor, reply, index);
-	
+
 					// リモートフォロワーにUpdate配信
 					this.pollService.deliverQuestionUpdate(reply.id);
 				}
 				return null;
 			};
-	
+
 			if (note.name) {
 				return await tryCreateVote(note.name, poll.choices.findIndex(x => x === note.name));
 			}
 		}
-	
+
 		const emojis = await this.extractEmojis(note.tag ?? [], actor.host).catch(e => {
 			this.logger.info(`extractEmojis: ${e}`);
 			return [] as Emoji[];
 		});
-	
+
 		const apEmojis = emojis.map(emoji => emoji.name);
-	
+
 		const poll = await this.apQuestionService.extractPollFromQuestion(note, resolver).catch(() => undefined);
-		
+
 		return await this.noteCreateService.create(actor, {
 			createdAt: note.published ? new Date(note.published) : null,
 			files,
@@ -297,7 +297,7 @@ export class ApNoteService {
 			url: url,
 		}, silent);
 	}
-	
+
 	/**
 	 * Noteを解決します。
 	 *
@@ -308,26 +308,26 @@ export class ApNoteService {
 	public async resolveNote(value: string | IObject, resolver?: Resolver): Promise<Note | null> {
 		const uri = typeof value === 'string' ? value : value.id;
 		if (uri == null) throw new Error('missing uri');
-	
+
 		// ブロックしてたら中断
 		const meta = await this.metaService.fetch();
 		if (this.utilityService.isBlockedHost(meta.blockedHosts, this.utilityService.extractDbHost(uri))) throw new StatusError('blocked host', 451);
-	
+
 		const unlock = await this.appLockService.getApLock(uri);
-	
+
 		try {
 			//#region このサーバーに既に登録されていたらそれを返す
 			const exist = await this.fetchNote(uri);
-	
+
 			if (exist) {
 				return exist;
 			}
 			//#endregion
-	
+
 			if (uri.startsWith(this.config.url)) {
 				throw new StatusError('cannot resolve local note', 400, 'cannot resolve local note');
 			}
-	
+
 			// リモートサーバーからフェッチしてきて登録
 			// ここでuriの代わりに添付されてきたNote Objectが指定されていると、サーバーフェッチを経ずにノートが生成されるが
 			// 添付されてきたNote Objectは偽装されている可能性があるため、常にuriを指定してサーバーフェッチを行う。
@@ -336,26 +336,26 @@ export class ApNoteService {
 			unlock();
 		}
 	}
-	
+
 	@bindThis
 	public async extractEmojis(tags: IObject | IObject[], host: string): Promise<Emoji[]> {
 		host = this.utilityService.toPuny(host);
-	
+
 		if (!tags) return [];
-	
+
 		const eomjiTags = toArray(tags).filter(isEmoji);
 
 		const existingEmojis = await this.emojisRepository.findBy({
 			host,
 			name: In(eomjiTags.map(tag => tag.name!.replaceAll(':', ''))),
 		});
-	
+
 		return await Promise.all(eomjiTags.map(async tag => {
 			const name = tag.name!.replaceAll(':', '');
 			tag.icon = toSingle(tag.icon);
-	
+
 			const exists = existingEmojis.find(x => x.name === name);
-	
+
 			if (exists) {
 				if ((tag.updated != null && exists.updatedAt == null)
 					|| (tag.id != null && exists.uri == null)
@@ -371,18 +371,18 @@ export class ApNoteService {
 						publicUrl: tag.icon!.url,
 						updatedAt: new Date(),
 					});
-	
+
 					return await this.emojisRepository.findOneBy({
 						host,
 						name,
 					}) as Emoji;
 				}
-	
+
 				return exists;
 			}
-	
+
 			this.logger.info(`register emoji host=${host}, name=${name}`);
-	
+
 			return await this.emojisRepository.insert({
 				id: this.idService.genId(),
 				host,
diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts
index f52ebed107..afe89e5a11 100644
--- a/packages/backend/src/core/activitypub/models/ApPersonService.ts
+++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts
@@ -415,7 +415,7 @@ export class ApPersonService implements OnModuleInit {
 	 * Personの情報を更新します。
 	 * Misskeyに対象のPersonが登録されていなければ無視します。
 	 * もしアカウントの移行が確認された場合、アカウント移行処理を行います。
-	 * 
+	 *
 	 * @param uri URI of Person
 	 * @param resolver Resolver
 	 * @param hint Hint of Person object (この値が正当なPersonの場合、Remote resolveをせずに更新に利用します)
@@ -688,7 +688,7 @@ export class ApPersonService implements OnModuleInit {
 			// (uriが存在しなかったり応答がなかったりする場合resolvePersonはthrow Errorする)
 			dst = await this.resolvePerson(src.movedToUri);
 		}
- 
+
 		if (dst.movedToUri === dst.uri) return 'skip: movedTo itself (dst)'; // ？？？
 		if (src.movedToUri !== dst.uri) return 'skip: missmatch uri'; // ？？？
 		if (dst.movedToUri === src.uri) return 'skip: dst.movedToUri === src.uri';
diff --git a/packages/backend/src/core/entities/DriveFileEntityService.ts b/packages/backend/src/core/entities/DriveFileEntityService.ts
index d82f36d971..80442af09b 100644
--- a/packages/backend/src/core/entities/DriveFileEntityService.ts
+++ b/packages/backend/src/core/entities/DriveFileEntityService.ts
@@ -47,7 +47,7 @@ export class DriveFileEntityService {
 		private videoProcessingService: VideoProcessingService,
 	) {
 	}
-	
+
 	@bindThis
 	public validateFileName(name: string): boolean {
 		return (
diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts
index 32269a4101..e730c0eb8f 100644
--- a/packages/backend/src/core/entities/NoteEntityService.ts
+++ b/packages/backend/src/core/entities/NoteEntityService.ts
@@ -24,7 +24,7 @@ export class NoteEntityService implements OnModuleInit {
 	private driveFileEntityService: DriveFileEntityService;
 	private customEmojiService: CustomEmojiService;
 	private reactionService: ReactionService;
-	
+
 	constructor(
 		private moduleRef: ModuleRef,
 
@@ -68,7 +68,7 @@ export class NoteEntityService implements OnModuleInit {
 		this.customEmojiService = this.moduleRef.get('CustomEmojiService');
 		this.reactionService = this.moduleRef.get('ReactionService');
 	}
-	
+
 	@bindThis
 	private async hideNote(packedNote: Packed<'Note'>, meId: User['id'] | null) {
 	// TODO: isVisibleForMe を使うようにしても良さそう(型違うけど)
@@ -457,12 +457,12 @@ export class NoteEntityService implements OnModuleInit {
 		const query = this.notesRepository.createQueryBuilder('note')
 			.where('note.userId = :userId', { userId })
 			.andWhere('note.renoteId = :renoteId', { renoteId });
-	
+
 		// 指定した投稿を除く
 		if (excludeNoteId) {
 			query.andWhere('note.id != :excludeNoteId', { excludeNoteId });
 		}
-	
+
 		return await query.getCount();
-	}	
+	}
 }
diff --git a/packages/backend/src/core/entities/NoteReactionEntityService.ts b/packages/backend/src/core/entities/NoteReactionEntityService.ts
index 8f943ba24c..d454ddb70a 100644
--- a/packages/backend/src/core/entities/NoteReactionEntityService.ts
+++ b/packages/backend/src/core/entities/NoteReactionEntityService.ts
@@ -17,7 +17,7 @@ export class NoteReactionEntityService implements OnModuleInit {
 	private userEntityService: UserEntityService;
 	private noteEntityService: NoteEntityService;
 	private reactionService: ReactionService;
-	
+
 	constructor(
 		private moduleRef: ModuleRef,
 
diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts
index d76b863957..02c6982847 100644
--- a/packages/backend/src/core/entities/NotificationEntityService.ts
+++ b/packages/backend/src/core/entities/NotificationEntityService.ts
@@ -59,7 +59,7 @@ export class NotificationEntityService implements OnModuleInit {
 		meId: User['id'],
 		// eslint-disable-next-line @typescript-eslint/ban-types
 		options: {
-			
+
 		},
 		hint?: {
 			packedNotes: Map<Note['id'], Packed<'Note'>>;
diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts
index f1a4e56c02..6dacaa1032 100644
--- a/packages/backend/src/core/entities/UserEntityService.ts
+++ b/packages/backend/src/core/entities/UserEntityService.ts
@@ -113,7 +113,7 @@ export class UserEntityService implements OnModuleInit {
 
 		@Inject(DI.pagesRepository)
 		private pagesRepository: PagesRepository,
-		
+
 		@Inject(DI.userMemosRepository)
 		private userMemosRepository: UserMemoRepository,
 
diff --git a/packages/backend/src/daemons/QueueStatsService.ts b/packages/backend/src/daemons/QueueStatsService.ts
index 53a0d14cd7..4d0cb96a2f 100644
--- a/packages/backend/src/daemons/QueueStatsService.ts
+++ b/packages/backend/src/daemons/QueueStatsService.ts
@@ -81,7 +81,7 @@ export class QueueStatsService implements OnApplicationShutdown {
 
 		this.intervalId = setInterval(tick, interval);
 	}
-	
+
 	@bindThis
 	public dispose(): void {
 		clearInterval(this.intervalId);
diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts
index e748f93a26..7579040c68 100644
--- a/packages/backend/src/misc/json-schema.ts
+++ b/packages/backend/src/misc/json-schema.ts
@@ -131,7 +131,7 @@ type NullOrUndefined<p extends Schema, T> =
 	| T;
 
 // https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection
-// Get intersection from union 
+// Get intersection from union
 type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
 type PartialIntersection<T> = Partial<UnionToIntersection<T>>;
 
diff --git a/packages/backend/src/misc/prelude/url.ts b/packages/backend/src/misc/prelude/url.ts
index 9b1dabc789..5239678280 100644
--- a/packages/backend/src/misc/prelude/url.ts
+++ b/packages/backend/src/misc/prelude/url.ts
@@ -2,7 +2,7 @@
  * 1. 配列に何も入っていない時はクエリを付けない
  * 2. プロパティがundefinedの時はクエリを付けない
  * （new URLSearchParams(obj)ではそこまで丁寧なことをしてくれない）
- */ 
+ */
 export function query(obj: Record<string, unknown>): string {
 	const params = Object.entries(obj)
 		.filter(([, v]) => Array.isArray(v) ? v.length : v !== undefined)
diff --git a/packages/backend/src/models/entities/UserProfile.ts b/packages/backend/src/models/entities/UserProfile.ts
index 236ee8f988..c4ed9db9bb 100644
--- a/packages/backend/src/models/entities/UserProfile.ts
+++ b/packages/backend/src/models/entities/UserProfile.ts
@@ -207,7 +207,7 @@ export class UserProfile {
 	public mutedInstances: string[];
 
 	@Column('enum', {
-		enum: [ 
+		enum: [
 			...notificationTypes,
 			// マイグレーションで削除が困難なので古いenumは残しておく
 			...obsoleteNotificationTypes,
diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts
index 42f9c1af7d..f575b1718e 100644
--- a/packages/backend/src/queue/QueueProcessorService.ts
+++ b/packages/backend/src/queue/QueueProcessorService.ts
@@ -283,7 +283,7 @@ export class QueueProcessorService implements OnApplicationShutdown {
 		});
 
 		const relationshipLogger = this.logger.createSubLogger('relationship');
-	
+
 		this.relationshipQueueWorker
 			.on('active', (job) => relationshipLogger.debug(`active id=${job.id}`))
 			.on('completed', (job, result) => relationshipLogger.debug(`completed(${result}) id=${job.id}`))
diff --git a/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts b/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts
index ac52325c8d..21c0bfe80e 100644
--- a/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts
@@ -30,7 +30,7 @@ export class ExportAntennasProcessorService {
 
 		@Inject(DI.userListJoiningsRepository)
 		private userListJoiningsRepository: UserListJoiningsRepository,
-	
+
 		private driveService: DriveService,
 		private utilityService: UtilityService,
 		private queueLoggerService: QueueLoggerService,
diff --git a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts
index 0c09f2796f..74ef20fdd8 100644
--- a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts
@@ -17,11 +17,11 @@ const validate = new Ajv().compile({
 	properties: {
 		name: { type: 'string', minLength: 1, maxLength: 100 },
 		src: { type: 'string', enum: ['home', 'all', 'users', 'list'] },
-		userListAccts: { 
-			type: 'array', 
+		userListAccts: {
+			type: 'array',
 			items: {
 				type: 'string',
-			}, 
+			},
 			nullable: true,
 		},
 		keywords: { type: 'array', items: {
diff --git a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
index d862567871..4ba749ec52 100644
--- a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
@@ -113,7 +113,7 @@ export class ImportCustomEmojisProcessorService {
 			}
 
 			cleanup();
-	
+
 			this.logger.succ('Imported');
 		});
 		unzipStream.pipe(extractor);
diff --git a/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts b/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts
index 8b40c16749..25e91761ef 100644
--- a/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts
+++ b/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts
@@ -31,7 +31,7 @@ export class WebhookDeliverProcessorService {
 	public async process(job: Bull.Job<WebhookDeliverJobData>): Promise<string> {
 		try {
 			this.logger.debug(`delivering ${job.data.webhookId}`);
-	
+
 			const res = await this.httpRequestService.send(job.data.to, {
 				method: 'POST',
 				headers: {
@@ -50,25 +50,25 @@ export class WebhookDeliverProcessorService {
 					body: job.data.content,
 				}),
 			});
-	
+
 			this.webhooksRepository.update({ id: job.data.webhookId }, {
 				latestSentAt: new Date(),
 				latestStatus: res.status,
 			});
-	
+
 			return 'Success';
 		} catch (res) {
 			this.webhooksRepository.update({ id: job.data.webhookId }, {
 				latestSentAt: new Date(),
 				latestStatus: res instanceof StatusError ? res.statusCode : 1,
 			});
-	
+
 			if (res instanceof StatusError) {
 				// 4xx
 				if (res.isClientError) {
 					throw new Bull.UnrecoverableError(`${res.statusCode} ${res.statusMessage}`);
 				}
-	
+
 				// 5xx etc.
 				throw new Error(`${res.statusCode} ${res.statusMessage}`);
 			} else {
diff --git a/packages/backend/src/server/api/AuthenticateService.ts b/packages/backend/src/server/api/AuthenticateService.ts
index 4ad0197d87..8b0fff80d9 100644
--- a/packages/backend/src/server/api/AuthenticateService.ts
+++ b/packages/backend/src/server/api/AuthenticateService.ts
@@ -40,15 +40,15 @@ export class AuthenticateService implements OnApplicationShutdown {
 		if (token == null) {
 			return [null, null];
 		}
-	
+
 		if (isNativeToken(token)) {
 			const user = await this.cacheService.localUserByNativeTokenCache.fetch(token,
 				() => this.usersRepository.findOneBy({ token }) as Promise<LocalUser | null>);
-	
+
 			if (user == null) {
 				throw new AuthenticationError('user not found');
 			}
-	
+
 			return [user, null];
 		} else {
 			const accessToken = await this.accessTokensRepository.findOne({
@@ -58,24 +58,24 @@ export class AuthenticateService implements OnApplicationShutdown {
 					token: token, // miauth
 				}],
 			});
-	
+
 			if (accessToken == null) {
 				throw new AuthenticationError('invalid signature');
 			}
-	
+
 			this.accessTokensRepository.update(accessToken.id, {
 				lastUsedAt: new Date(),
 			});
-	
+
 			const user = await this.cacheService.localUserByIdCache.fetch(accessToken.userId,
 				() => this.usersRepository.findOneBy({
 					id: accessToken.userId,
 				}) as Promise<LocalUser>);
-	
+
 			if (accessToken.appId) {
 				const app = await this.appCache.fetch(accessToken.appId,
 					() => this.appsRepository.findOneByOrFail({ id: accessToken.appId! }));
-	
+
 				return [user, {
 					id: accessToken.id,
 					permission: app.permission,
diff --git a/packages/backend/src/server/api/RateLimiterService.ts b/packages/backend/src/server/api/RateLimiterService.ts
index fe2db1d66a..f6ffbfab50 100644
--- a/packages/backend/src/server/api/RateLimiterService.ts
+++ b/packages/backend/src/server/api/RateLimiterService.ts
@@ -38,14 +38,14 @@ export class RateLimiterService {
 					max: 1,
 					db: this.redisClient,
 				});
-		
+
 				minIntervalLimiter.get((err, info) => {
 					if (err) {
 						return reject('ERR');
 					}
-		
+
 					this.logger.debug(`${actor} ${limitation.key} min remaining: ${info.remaining}`);
-		
+
 					if (info.remaining === 0) {
 						reject('BRIEF_REQUEST_INTERVAL');
 					} else {
@@ -57,7 +57,7 @@ export class RateLimiterService {
 					}
 				});
 			};
-		
+
 			// Long term limit
 			const max = (): void => {
 				const limiter = new Limiter({
@@ -66,14 +66,14 @@ export class RateLimiterService {
 					max: limitation.max! / factor,
 					db: this.redisClient,
 				});
-		
+
 				limiter.get((err, info) => {
 					if (err) {
 						return reject('ERR');
 					}
-		
+
 					this.logger.debug(`${actor} ${limitation.key} max remaining: ${info.remaining}`);
-		
+
 					if (info.remaining === 0) {
 						reject('RATE_LIMIT_EXCEEDED');
 					} else {
@@ -81,13 +81,13 @@ export class RateLimiterService {
 					}
 				});
 			};
-		
+
 			const hasShortTermLimit = typeof limitation.minInterval === 'number';
-		
+
 			const hasLongTermLimit =
 				typeof limitation.duration === 'number' &&
 				typeof limitation.max === 'number';
-		
+
 			if (hasShortTermLimit) {
 				min();
 			} else if (hasLongTermLimit) {
diff --git a/packages/backend/src/server/api/SigninService.ts b/packages/backend/src/server/api/SigninService.ts
index aaf1d10b42..96666f1f49 100644
--- a/packages/backend/src/server/api/SigninService.ts
+++ b/packages/backend/src/server/api/SigninService.ts
@@ -36,7 +36,7 @@ export class SigninService {
 				headers: request.headers as any,
 				success: true,
 			}).then(x => this.signinsRepository.findOneByOrFail(x.identifiers[0]));
-	
+
 			// Publish signin event
 			this.globalEventService.publishMainStream(user.id, 'signin', await this.signinEntityService.pack(record));
 		});
diff --git a/packages/backend/src/server/api/endpoint-base.ts b/packages/backend/src/server/api/endpoint-base.ts
index 05141854c7..364fa7a19b 100644
--- a/packages/backend/src/server/api/endpoint-base.ts
+++ b/packages/backend/src/server/api/endpoint-base.ts
@@ -34,23 +34,23 @@ export abstract class Endpoint<T extends IEndpointMeta, Ps extends Schema> {
 
 		this.exec = (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, ip?: string | null, headers?: Record<string, string> | null) => {
 			let cleanup: undefined | (() => void) = undefined;
-	
+
 			if (meta.requireFile) {
 				cleanup = () => {
 					if (file) fs.unlink(file.path, () => {});
 				};
-	
+
 				if (file == null) return Promise.reject(new ApiError({
 					message: 'File required.',
 					code: 'FILE_REQUIRED',
 					id: '4267801e-70d1-416a-b011-4ee502885d8b',
 				}));
 			}
-	
+
 			const valid = validate(params);
 			if (!valid) {
 				if (file) cleanup!();
-	
+
 				const errors = validate.errors!;
 				const err = new ApiError({
 					message: 'Invalid param.',
@@ -62,7 +62,7 @@ export abstract class Endpoint<T extends IEndpointMeta, Ps extends Schema> {
 				});
 				return Promise.reject(err);
 			}
-	
+
 			return cb(params as SchemaType<Ps>, user, token, file, cleanup, ip, headers);
 		};
 	}
diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts
index 12db1f78fb..8cf9341a71 100644
--- a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts
+++ b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts
@@ -47,7 +47,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 				title: ps.title,
 				text: ps.text,
 				/* eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- 空の文字列の場合、nullを渡すようにするため */
-				imageUrl: ps.imageUrl || null, 
+				imageUrl: ps.imageUrl || null,
 			});
 		});
 	}
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts
index 4aa4ad82b4..1a6a361683 100644
--- a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts
+++ b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts
@@ -90,7 +90,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 				const queryarry = ps.query.match(/\:([a-z0-9_]*)\:/g);
 
 				if (queryarry) {
-					emojis = emojis.filter(emoji => 
+					emojis = emojis.filter(emoji =>
 						queryarry.includes(`:${emoji.name}:`)
 					);
 				} else {
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts
index fb22bdc477..edc1af5a53 100644
--- a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts
+++ b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts
@@ -70,7 +70,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 				driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
 				if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
 			}
-	
+
 			await this.customEmojiService.update(ps.id, {
 				driveFile,
 				name: ps.name,
diff --git a/packages/backend/src/server/api/endpoints/admin/queue/promote.ts b/packages/backend/src/server/api/endpoints/admin/queue/promote.ts
index 4e57e6613e..9140f392cd 100644
--- a/packages/backend/src/server/api/endpoints/admin/queue/promote.ts
+++ b/packages/backend/src/server/api/endpoints/admin/queue/promote.ts
@@ -36,7 +36,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 						await queue.promote();
 					}
 					break;
-				
+
 				case 'inbox':
 					delayedQueues = await this.queueService.inboxQueue.getDelayed();
 					for (let queueIndex = 0; queueIndex < delayedQueues.length; queueIndex++) {
diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
index 5c9d8e3fac..0b20b058fd 100644
--- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
@@ -136,7 +136,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 			if (Array.isArray(ps.sensitiveWords)) {
 				set.sensitiveWords = ps.sensitiveWords.filter(Boolean);
 			}
-		
+
 			if (ps.themeColor !== undefined) {
 				set.themeColor = ps.themeColor;
 			}
diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts
index c881074bab..833bd63c1c 100644
--- a/packages/backend/src/server/api/endpoints/channels/timeline.ts
+++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts
@@ -77,7 +77,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 
 			const limit = ps.limit + (ps.untilId ? 1 : 0); // untilIdに指定したものも含まれるため+1
 			let noteIdsRes: [string, string[]][] = [];
-			
+
 			if (!ps.sinceId && !ps.sinceDate) {
 				noteIdsRes = await this.redisClient.xrevrange(
 					`channelTimeline:${channel.id}`,
diff --git a/packages/backend/src/server/api/endpoints/drive/files/update.ts b/packages/backend/src/server/api/endpoints/drive/files/update.ts
index 3ecbba22b5..c43f812e2f 100644
--- a/packages/backend/src/server/api/endpoints/drive/files/update.ts
+++ b/packages/backend/src/server/api/endpoints/drive/files/update.ts
@@ -40,7 +40,7 @@ export const meta = {
 			code: 'NO_SUCH_FOLDER',
 			id: 'ea8fb7a5-af77-4a08-b608-c0218176cd73',
 		},
-		
+
 		restrictedByRole: {
 			message: 'This feature is restricted by your role.',
 			code: 'RESTRICTED_BY_ROLE',
diff --git a/packages/backend/src/server/api/endpoints/emoji.ts b/packages/backend/src/server/api/endpoints/emoji.ts
index 681d3e649e..51027f35c0 100644
--- a/packages/backend/src/server/api/endpoints/emoji.ts
+++ b/packages/backend/src/server/api/endpoints/emoji.ts
@@ -36,7 +36,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 	constructor(
 		@Inject(DI.config)
 		private config: Config,
-	
+
 		@Inject(DI.emojisRepository)
 		private emojisRepository: EmojisRepository,
 
diff --git a/packages/backend/src/server/api/endpoints/emojis.ts b/packages/backend/src/server/api/endpoints/emojis.ts
index 13cc709d31..3c2d0ce4a4 100644
--- a/packages/backend/src/server/api/endpoints/emojis.ts
+++ b/packages/backend/src/server/api/endpoints/emojis.ts
@@ -43,7 +43,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 	constructor(
 		@Inject(DI.config)
 		private config: Config,
-	
+
 		@Inject(DI.emojisRepository)
 		private emojisRepository: EmojisRepository,
 
diff --git a/packages/backend/src/server/api/endpoints/hashtags/users.ts b/packages/backend/src/server/api/endpoints/hashtags/users.ts
index dd3549020e..a86faf41a4 100644
--- a/packages/backend/src/server/api/endpoints/hashtags/users.ts
+++ b/packages/backend/src/server/api/endpoints/hashtags/users.ts
@@ -39,7 +39,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 	constructor(
 		@Inject(DI.usersRepository)
 		private usersRepository: UsersRepository,
-		
+
 		private userEntityService: UserEntityService,
 	) {
 		super(meta, paramDef, async (ps, me) => {
diff --git a/packages/backend/src/server/api/endpoints/i.ts b/packages/backend/src/server/api/endpoints/i.ts
index a3e3e02a12..743e3f8abc 100644
--- a/packages/backend/src/server/api/endpoints/i.ts
+++ b/packages/backend/src/server/api/endpoints/i.ts
@@ -68,7 +68,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 				});
 				userProfile.loggedInDates = [...userProfile.loggedInDates, today];
 			}
-			
+
 			return await this.userEntityService.pack<true, true>(userProfile.user!, userProfile.user!, {
 				detail: true,
 				includeSecrets: isSecure,
diff --git a/packages/backend/src/server/api/endpoints/i/2fa/update-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/update-key.ts
index d98f60fa5f..2ef5e5a279 100644
--- a/packages/backend/src/server/api/endpoints/i/2fa/update-key.ts
+++ b/packages/backend/src/server/api/endpoints/i/2fa/update-key.ts
@@ -61,7 +61,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 			if (key.userId !== me.id) {
 				throw new ApiError(meta.errors.accessDenied);
 			}
-	
+
 			await this.userSecurityKeysRepository.update(key.id, {
 				name: ps.name,
 			});
diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts
index 3b3c5caa00..6ef5f0d5c8 100644
--- a/packages/backend/src/server/api/endpoints/meta.ts
+++ b/packages/backend/src/server/api/endpoints/meta.ts
@@ -250,7 +250,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 	constructor(
 		@Inject(DI.config)
 		private config: Config,
-	
+
 		@Inject(DI.usersRepository)
 		private usersRepository: UsersRepository,
 
diff --git a/packages/backend/src/server/api/endpoints/notes.ts b/packages/backend/src/server/api/endpoints/notes.ts
index 5fbc7aba58..a6e9707d38 100644
--- a/packages/backend/src/server/api/endpoints/notes.ts
+++ b/packages/backend/src/server/api/endpoints/notes.ts
@@ -53,34 +53,34 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 				.leftJoinAndSelect('note.renote', 'renote')
 				.leftJoinAndSelect('reply.user', 'replyUser')
 				.leftJoinAndSelect('renote.user', 'renoteUser');
-		
+
 			if (ps.local) {
 				query.andWhere('note.userHost IS NULL');
 			}
-		
+
 			if (ps.reply !== undefined) {
 				query.andWhere(ps.reply ? 'note.replyId IS NOT NULL' : 'note.replyId IS NULL');
 			}
-		
+
 			if (ps.renote !== undefined) {
 				query.andWhere(ps.renote ? 'note.renoteId IS NOT NULL' : 'note.renoteId IS NULL');
 			}
-		
+
 			if (ps.withFiles !== undefined) {
 				query.andWhere(ps.withFiles ? 'note.fileIds != \'{}\'' : 'note.fileIds = \'{}\'');
 			}
-		
+
 			if (ps.poll !== undefined) {
 				query.andWhere(ps.poll ? 'note.hasPoll = TRUE' : 'note.hasPoll = FALSE');
 			}
-		
+
 			// TODO
 			//if (bot != undefined) {
 			//	query.isBot = bot;
 			//}
-		
+
 			const notes = await query.take(ps.limit).getMany();
-		
+
 			return await this.noteEntityService.packMany(notes);
 		});
 	}
diff --git a/packages/backend/src/server/api/endpoints/notes/search.ts b/packages/backend/src/server/api/endpoints/notes/search.ts
index f6385400c3..cd0e351e45 100644
--- a/packages/backend/src/server/api/endpoints/notes/search.ts
+++ b/packages/backend/src/server/api/endpoints/notes/search.ts
@@ -58,7 +58,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 	constructor(
 		@Inject(DI.config)
 		private config: Config,
-	
+
 		private noteEntityService: NoteEntityService,
 		private searchService: SearchService,
 		private roleService: RoleService,
@@ -68,7 +68,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 			if (!policies.canSearchNotes) {
 				throw new ApiError(meta.errors.unavailable);
 			}
-	
+
 			const notes = await this.searchService.searchNote(ps.query, me, {
 				userId: ps.userId,
 				channelId: ps.channelId,
diff --git a/packages/backend/src/server/api/endpoints/notes/translate.ts b/packages/backend/src/server/api/endpoints/notes/translate.ts
index 66655234a1..b91bc7b5ec 100644
--- a/packages/backend/src/server/api/endpoints/notes/translate.ts
+++ b/packages/backend/src/server/api/endpoints/notes/translate.ts
@@ -44,7 +44,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 	constructor(
 		@Inject(DI.config)
 		private config: Config,
-	
+
 		@Inject(DI.notesRepository)
 		private notesRepository: NotesRepository,
 
diff --git a/packages/backend/src/server/api/endpoints/roles/notes.ts b/packages/backend/src/server/api/endpoints/roles/notes.ts
index 42e36cb04a..a30c31b727 100644
--- a/packages/backend/src/server/api/endpoints/roles/notes.ts
+++ b/packages/backend/src/server/api/endpoints/roles/notes.ts
@@ -71,7 +71,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 			if (role == null) {
 				throw new ApiError(meta.errors.noSuchRole);
 			}
-			if (!role.isExplorable) { 
+			if (!role.isExplorable) {
 				return [];
 			}
 			const limit = ps.limit + (ps.untilId ? 1 : 0) + (ps.sinceId ? 1 : 0); // untilIdに指定したものも含まれるため+1
diff --git a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts
index 8591e4ab96..cccffcdad4 100644
--- a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts
+++ b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts
@@ -95,7 +95,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 			if (currentCount > (await this.roleService.getUserPolicies(me.id)).userListLimit) {
 				throw new ApiError(meta.errors.tooManyUserLists);
 			}
-			
+
 			const userList = await this.userListsRepository.insert({
 				id: this.idService.genId(),
 				createdAt: new Date(),
@@ -127,7 +127,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 					userListId: userList.id,
 					userId: currentUser.id,
 				});
-	
+
 				if (exist) {
 					throw new ApiError(meta.errors.alreadyAdded);
 				}
diff --git a/packages/backend/src/server/api/endpoints/users/lists/favorite.ts b/packages/backend/src/server/api/endpoints/users/lists/favorite.ts
index 263852fde1..ea1a022bec 100644
--- a/packages/backend/src/server/api/endpoints/users/lists/favorite.ts
+++ b/packages/backend/src/server/api/endpoints/users/lists/favorite.ts
@@ -41,7 +41,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 		private idService: IdService,
 	) {
 		super(meta, paramDef, async (ps, me) => {
-			const userList = await this.userListsRepository.findOneBy({ 
+			const userList = await this.userListsRepository.findOneBy({
 				id: ps.listId,
 				isPublic: true,
 			});
diff --git a/packages/backend/src/server/api/endpoints/users/search.ts b/packages/backend/src/server/api/endpoints/users/search.ts
index d7a60f0437..5ffe3e84aa 100644
--- a/packages/backend/src/server/api/endpoints/users/search.ts
+++ b/packages/backend/src/server/api/endpoints/users/search.ts
@@ -78,7 +78,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 					.getMany();
 			} else {
 				const nameQuery = this.usersRepository.createQueryBuilder('user')
-					.where(new Brackets(qb => { 
+					.where(new Brackets(qb => {
 						qb.where('user.name ILIKE :query', { query: '%' + sqlLikeEscape(ps.query) + '%' });
 
 						// Also search username if it qualifies as username
diff --git a/packages/backend/src/server/api/stream/ChannelsService.ts b/packages/backend/src/server/api/stream/ChannelsService.ts
index c77ba66028..4a544fadfe 100644
--- a/packages/backend/src/server/api/stream/ChannelsService.ts
+++ b/packages/backend/src/server/api/stream/ChannelsService.ts
@@ -52,7 +52,7 @@ export class ChannelsService {
 			case 'serverStats': return this.serverStatsChannelService;
 			case 'queueStats': return this.queueStatsChannelService;
 			case 'admin': return this.adminChannelService;
-		
+
 			default:
 				throw new Error(`no such channel: ${name}`);
 		}
diff --git a/packages/backend/src/server/api/stream/channels/hashtag.ts b/packages/backend/src/server/api/stream/channels/hashtag.ts
index 0268fdedde..94ebf86418 100644
--- a/packages/backend/src/server/api/stream/channels/hashtag.ts
+++ b/packages/backend/src/server/api/stream/channels/hashtag.ts
@@ -49,7 +49,7 @@ class HashtagChannel extends Channel {
 		if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
 		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
 		if (isUserRelated(note, this.userIdsWhoBlockingMe)) return;
-		
+
 		if (note.renote && !note.text && isUserRelated(note, this.userIdsWhoMeMutingRenotes)) return;
 
 		this.connection.cacheNote(note);
diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts
index 1755aa94cf..fe0cc37b6b 100644
--- a/packages/backend/src/server/api/stream/channels/home-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts
@@ -26,7 +26,7 @@ class HomeTimelineChannel extends Channel {
 	@bindThis
 	public async init(params: any) {
 		this.withReplies = params.withReplies as boolean;
-	
+
 		this.subscriber.on('notesStream', this.onNote);
 	}
 
diff --git a/packages/backend/src/server/api/stream/channels/role-timeline.ts b/packages/backend/src/server/api/stream/channels/role-timeline.ts
index ab9c1aa0b5..4f36832e42 100644
--- a/packages/backend/src/server/api/stream/channels/role-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/role-timeline.ts
@@ -12,7 +12,7 @@ class RoleTimelineChannel extends Channel {
 	public static shouldShare = false;
 	public static requireCredential = false;
 	private roleId: string;
-	
+
 	constructor(
 		private noteEntityService: NoteEntityService,
 		private roleservice: RoleService,
diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts
index 8802fc5ab8..d97d2b8ba9 100644
--- a/packages/backend/src/server/api/stream/channels/user-list.ts
+++ b/packages/backend/src/server/api/stream/channels/user-list.ts
@@ -20,7 +20,7 @@ class UserListChannel extends Channel {
 		private userListsRepository: UserListsRepository,
 		private userListJoiningsRepository: UserListJoiningsRepository,
 		private noteEntityService: NoteEntityService,
-		
+
 		id: string,
 		connection: Channel['connection'],
 	) {
diff --git a/packages/backend/src/server/web/FeedService.ts b/packages/backend/src/server/web/FeedService.ts
index 0c0e92cc04..0bd0d3c692 100644
--- a/packages/backend/src/server/web/FeedService.ts
+++ b/packages/backend/src/server/web/FeedService.ts
@@ -38,9 +38,9 @@ export class FeedService {
 			link: `${this.config.url}/@${user.username}`,
 			name: user.name ?? user.username,
 		};
-	
+
 		const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id });
-	
+
 		const notes = await this.notesRepository.find({
 			where: {
 				userId: user.id,
@@ -50,7 +50,7 @@ export class FeedService {
 			order: { createdAt: -1 },
 			take: 20,
 		});
-	
+
 		const feed = new Feed({
 			id: author.link,
 			title: `${author.name} (@${user.username}@${this.config.host})`,
@@ -66,13 +66,13 @@ export class FeedService {
 			author,
 			copyright: user.name ?? user.username,
 		});
-	
+
 		for (const note of notes) {
 			const files = note.fileIds.length > 0 ? await this.driveFilesRepository.findBy({
 				id: In(note.fileIds),
 			}) : [];
 			const file = files.find(file => file.type.startsWith('image/'));
-	
+
 			feed.addItem({
 				title: `New note by ${author.name}`,
 				link: `${this.config.url}/notes/${note.id}`,
@@ -82,7 +82,7 @@ export class FeedService {
 				image: file ? this.driveFileEntityService.getPublicUrl(file) ?? undefined : undefined,
 			});
 		}
-	
+
 		return feed;
 	}
 }
diff --git a/packages/backend/src/server/web/bios.js b/packages/backend/src/server/web/bios.js
index c2ce5c3814..51899dd3a3 100644
--- a/packages/backend/src/server/web/bios.js
+++ b/packages/backend/src/server/web/bios.js
@@ -8,7 +8,7 @@ window.onload = async () => {
 		const promise = new Promise((resolve, reject) => {
 			// Append a credential
 			if (i) data.i = i;
-	
+
 			// Send request
 			window.fetch(endpoint.indexOf('://') > -1 ? endpoint : `/api/${endpoint}`, {
 				method: 'POST',
@@ -17,7 +17,7 @@ window.onload = async () => {
 				cache: 'no-cache'
 			}).then(async (res) => {
 				const body = res.status === 204 ? null : await res.json();
-	
+
 				if (res.status === 200) {
 					resolve(body);
 				} else if (res.status === 204) {
@@ -27,7 +27,7 @@ window.onload = async () => {
 				}
 			}).catch(reject);
 		});
-		
+
 		return promise;
 	};
 
diff --git a/packages/backend/src/server/web/cli.js b/packages/backend/src/server/web/cli.js
index 3467f7ac2a..5bb576a27b 100644
--- a/packages/backend/src/server/web/cli.js
+++ b/packages/backend/src/server/web/cli.js
@@ -8,7 +8,7 @@ window.onload = async () => {
 		const promise = new Promise((resolve, reject) => {
 			// Append a credential
 			if (i) data.i = i;
-	
+
 			// Send request
 			fetch(endpoint.indexOf('://') > -1 ? endpoint : `/api/${endpoint}`, {
 				headers: {
@@ -20,7 +20,7 @@ window.onload = async () => {
 				cache: 'no-cache'
 			}).then(async (res) => {
 				const body = res.status === 204 ? null : await res.json();
-	
+
 				if (res.status === 200) {
 					resolve(body);
 				} else if (res.status === 204) {
@@ -30,7 +30,7 @@ window.onload = async () => {
 				}
 			}).catch(reject);
 		});
-		
+
 		return promise;
 	};
 
diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug
index d23a1d49c9..69a4e37322 100644
--- a/packages/backend/src/server/web/views/base.pug
+++ b/packages/backend/src/server/web/views/base.pug
@@ -55,8 +55,8 @@ html
 		block meta
 
 		block og
-			meta(property='og:title'       content= title || 'Misskey') 
-			meta(property='og:description' content= desc || '✨🌎✨ A interplanetary communication platform ✨🚀✨') 
+			meta(property='og:title'       content= title || 'Misskey')
+			meta(property='og:description' content= desc || '✨🌎✨ A interplanetary communication platform ✨🚀✨')
 			meta(property='og:image'       content= img)
 			meta(property='twitter:card'   content='summary')
 
diff --git a/packages/backend/src/server/web/views/error.pug b/packages/backend/src/server/web/views/error.pug
index b177ae4110..44ebf53cf7 100644
--- a/packages/backend/src/server/web/views/error.pug
+++ b/packages/backend/src/server/web/views/error.pug
@@ -32,12 +32,12 @@ body
 		path(stroke="none", d="M0 0h24v24H0z", fill="none")
 		path(d="M12 9v2m0 4v.01")
 		path(d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75")
-	
+
 	h1 An error has occurred!
 
 	button.button-big(onclick="location.reload();")
 		span.button-label-big Refresh
-	
+
 	p.dont-worry Don't worry, it's (probably) not your fault.
 
 	p If reloading after a period of time does not resolve the problem, contact the server administrator with the following ERROR ID.
diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug
index ea0917a80e..98d0c9a789 100644
--- a/packages/backend/src/server/web/views/note.pug
+++ b/packages/backend/src/server/web/views/note.pug
@@ -43,7 +43,7 @@ block meta
 	meta(name='misskey:user-username' content=user.username)
 	meta(name='misskey:user-id' content=user.id)
 	meta(name='misskey:note-id' content=note.id)
-	
+
 	// todo
 	if user.twitter
 		meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
diff --git a/packages/backend/test/prelude/get-api-validator.ts b/packages/backend/test/prelude/get-api-validator.ts
index 1f4a2dbc95..f095774760 100644
--- a/packages/backend/test/prelude/get-api-validator.ts
+++ b/packages/backend/test/prelude/get-api-validator.ts
@@ -5,7 +5,7 @@ export const getValidator = (paramDef: Schema) => {
     const ajv = new Ajv({
         useDefaults: true,
     });
-    ajv.addFormat('misskey:id', /^[a-zA-Z0-9]+$/);		
+    ajv.addFormat('misskey:id', /^[a-zA-Z0-9]+$/);
 
     return ajv.compile(paramDef);
 }
diff --git a/packages/backend/test/unit/DriveService.ts b/packages/backend/test/unit/DriveService.ts
index 4065665579..9ee6d4bcfb 100644
--- a/packages/backend/test/unit/DriveService.ts
+++ b/packages/backend/test/unit/DriveService.ts
@@ -34,7 +34,7 @@ describe('DriveService', () => {
 		test('delete a file', async () => {
 			s3Mock.on(DeleteObjectCommand)
 				.resolves({} as DeleteObjectCommandOutput);
-			
+
 			await driveService.deleteObjectStorageFile('peace of the world');
 		});
 
diff --git a/packages/backend/test/unit/FileInfoService.ts b/packages/backend/test/unit/FileInfoService.ts
index f378184c74..efb9bdacc3 100644
--- a/packages/backend/test/unit/FileInfoService.ts
+++ b/packages/backend/test/unit/FileInfoService.ts
@@ -94,7 +94,7 @@ describe('FileInfoService', () => {
 				orientation: undefined,
 			});
 		});
-	
+
 		test('Generic APNG', async () => {
 			const path = `${resources}/anime.png`;
 			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -114,7 +114,7 @@ describe('FileInfoService', () => {
 				orientation: undefined,
 			});
 		});
-	
+
 		test('Generic AGIF', async () => {
 			const path = `${resources}/anime.gif`;
 			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -134,7 +134,7 @@ describe('FileInfoService', () => {
 				orientation: undefined,
 			});
 		});
-	
+
 		test('PNG with alpha', async () => {
 			const path = `${resources}/with-alpha.png`;
 			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -154,7 +154,7 @@ describe('FileInfoService', () => {
 				orientation: undefined,
 			});
 		});
-	
+
 		test('Generic SVG', async () => {
 			const path = `${resources}/image.svg`;
 			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -174,7 +174,7 @@ describe('FileInfoService', () => {
 				orientation: undefined,
 			});
 		});
-	
+
 		test('SVG with XML definition', async () => {
 			// https://github.com/misskey-dev/misskey/issues/4413
 			const path = `${resources}/with-xml-def.svg`;
@@ -195,7 +195,7 @@ describe('FileInfoService', () => {
 				orientation: undefined,
 			});
 		});
-	
+
 		test('Dimension limit', async () => {
 			const path = `${resources}/25000x25000.png`;
 			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -215,7 +215,7 @@ describe('FileInfoService', () => {
 				orientation: undefined,
 			});
 		});
-	
+
 		test('Rotate JPEG', async () => {
 			const path = `${resources}/rotate.jpg`;
 			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -257,7 +257,7 @@ describe('FileInfoService', () => {
 				},
 			});
 		});
-	
+
 		test('WAV', async () => {
 			const path = `${resources}/kick_gaba7.wav`;
 			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -277,7 +277,7 @@ describe('FileInfoService', () => {
 				},
 			});
 		});
-	
+
 		test('AAC', async () => {
 			const path = `${resources}/kick_gaba7.aac`;
 			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -297,7 +297,7 @@ describe('FileInfoService', () => {
 				},
 			});
 		});
-	
+
 		test('FLAC', async () => {
 			const path = `${resources}/kick_gaba7.flac`;
 			const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -317,7 +317,7 @@ describe('FileInfoService', () => {
 				},
 			});
 		});
-	
+
 		/*
 		 * video/webmとして検出されてしまう
 		test('WEBM AUDIO', async () => {
diff --git a/packages/backend/test/unit/RelayService.ts b/packages/backend/test/unit/RelayService.ts
index c2280142a6..6bf08f5091 100644
--- a/packages/backend/test/unit/RelayService.ts
+++ b/packages/backend/test/unit/RelayService.ts
@@ -61,7 +61,7 @@ describe('RelayService', () => {
 		await app.close();
 	});
 
-	test('addRelay', async () => {	
+	test('addRelay', async () => {
 		const result = await relayService.addRelay('https://example.com');
 
 		expect(result.inbox).toBe('https://example.com');
@@ -72,7 +72,7 @@ describe('RelayService', () => {
 		//expect(queueService.deliver.mock.lastCall![0].username).toBe('relay.actor');
 	});
 
-	test('listRelay', async () => {	
+	test('listRelay', async () => {
 		const result = await relayService.listRelay();
 
 		expect(result.length).toBe(1);
@@ -80,7 +80,7 @@ describe('RelayService', () => {
 		expect(result[0].status).toBe('requesting');
 	});
 
-	test('removeRelay: succ', async () => {	
+	test('removeRelay: succ', async () => {
 		await relayService.removeRelay('https://example.com');
 
 		expect(queueService.deliver).toHaveBeenCalled();
@@ -93,7 +93,7 @@ describe('RelayService', () => {
 		expect(list.length).toBe(0);
 	});
 
-	test('removeRelay: fail', async () => {	
+	test('removeRelay: fail', async () => {
 		await expect(relayService.removeRelay('https://x.example.com'))
 			.rejects.toThrow('relay not found');
 	});
diff --git a/packages/backend/test/unit/chart.ts b/packages/backend/test/unit/chart.ts
index 5ac4cc18a2..40554d3a47 100644
--- a/packages/backend/test/unit/chart.ts
+++ b/packages/backend/test/unit/chart.ts
@@ -475,16 +475,16 @@ describe('Chart', () => {
 				await testIntersectionChart.addA('bob');
 				await testIntersectionChart.addB('carol');
 				await testIntersectionChart.save();
-	
+
 				const chartHours = await testIntersectionChart.getChart('hour', 3, null);
 				const chartDays = await testIntersectionChart.getChart('day', 3, null);
-	
+
 				assert.deepStrictEqual(chartHours, {
 					a: [2, 0, 0],
 					b: [1, 0, 0],
 					aAndB: [0, 0, 0],
 				});
-	
+
 				assert.deepStrictEqual(chartDays, {
 					a: [2, 0, 0],
 					b: [1, 0, 0],
@@ -498,16 +498,16 @@ describe('Chart', () => {
 				await testIntersectionChart.addB('carol');
 				await testIntersectionChart.addB('alice');
 				await testIntersectionChart.save();
-	
+
 				const chartHours = await testIntersectionChart.getChart('hour', 3, null);
 				const chartDays = await testIntersectionChart.getChart('day', 3, null);
-	
+
 				assert.deepStrictEqual(chartHours, {
 					a: [2, 0, 0],
 					b: [2, 0, 0],
 					aAndB: [1, 0, 0],
 				});
-	
+
 				assert.deepStrictEqual(chartDays, {
 					a: [2, 0, 0],
 					b: [2, 0, 0],
diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts
index 76e8c50724..d2db5e98be 100644
--- a/packages/frontend/src/boot/main-boot.ts
+++ b/packages/frontend/src/boot/main-boot.ts
@@ -87,7 +87,7 @@ export async function mainBoot() {
 		const now = new Date();
 		const m = now.getMonth() + 1;
 		const d = now.getDate();
-		
+
 		if ($i.birthday) {
 			const bm = parseInt($i.birthday.split('-')[1]);
 			const bd = parseInt($i.birthday.split('-')[2]);
diff --git a/packages/frontend/src/components/MkDrive.folder.vue b/packages/frontend/src/components/MkDrive.folder.vue
index 1969342402..3594978729 100644
--- a/packages/frontend/src/components/MkDrive.folder.vue
+++ b/packages/frontend/src/components/MkDrive.folder.vue
@@ -93,9 +93,9 @@ function onDragover(ev: DragEvent) {
 		switch (ev.dataTransfer.effectAllowed) {
 			case 'all':
 			case 'uninitialized':
-			case 'copy': 
-			case 'copyLink': 
-			case 'copyMove': 
+			case 'copy':
+			case 'copyLink':
+			case 'copyMove':
 				ev.dataTransfer.dropEffect = 'copy';
 				break;
 			case 'linkMove':
diff --git a/packages/frontend/src/components/MkDrive.navFolder.vue b/packages/frontend/src/components/MkDrive.navFolder.vue
index 3349603d3b..df4c209c2b 100644
--- a/packages/frontend/src/components/MkDrive.navFolder.vue
+++ b/packages/frontend/src/components/MkDrive.navFolder.vue
@@ -61,9 +61,9 @@ function onDragover(ev: DragEvent) {
 		switch (ev.dataTransfer.effectAllowed) {
 			case 'all':
 			case 'uninitialized':
-			case 'copy': 
-			case 'copyLink': 
-			case 'copyMove': 
+			case 'copy':
+			case 'copyLink':
+			case 'copyMove':
 				ev.dataTransfer.dropEffect = 'copy';
 				break;
 			case 'linkMove':
diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue
index 19508fe4de..917e785139 100644
--- a/packages/frontend/src/components/MkDrive.vue
+++ b/packages/frontend/src/components/MkDrive.vue
@@ -202,9 +202,9 @@ function onDragover(ev: DragEvent): any {
 		switch (ev.dataTransfer.effectAllowed) {
 			case 'all':
 			case 'uninitialized':
-			case 'copy': 
-			case 'copyLink': 
-			case 'copyMove': 
+			case 'copy':
+			case 'copyLink':
+			case 'copyMove':
 				ev.dataTransfer.dropEffect = 'copy';
 				break;
 			case 'linkMove':
diff --git a/packages/frontend/src/components/MkFileListForAdmin.vue b/packages/frontend/src/components/MkFileListForAdmin.vue
index 71a35ae6e8..77b38b4bbf 100644
--- a/packages/frontend/src/components/MkFileListForAdmin.vue
+++ b/packages/frontend/src/components/MkFileListForAdmin.vue
@@ -89,7 +89,7 @@ const props = defineProps<{
 		> .file {
 			position: relative;
 			aspect-ratio: 1;
-		
+
 			> .thumbnail {
 				width: 100%;
 				height: 100%;
diff --git a/packages/frontend/src/components/MkFlashPreview.vue b/packages/frontend/src/components/MkFlashPreview.vue
index 7c9ae155ab..b5505ac8fd 100644
--- a/packages/frontend/src/components/MkFlashPreview.vue
+++ b/packages/frontend/src/components/MkFlashPreview.vue
@@ -87,7 +87,7 @@ const props = defineProps<{
 
 	@media (max-width: 500px) {
 		font-size: 10px;
-		
+
 		> article {
 			padding: 8px;
 
diff --git a/packages/frontend/src/components/MkMediaVideo.vue b/packages/frontend/src/components/MkMediaVideo.vue
index 40bae90b5e..dc5807b2dd 100644
--- a/packages/frontend/src/components/MkMediaVideo.vue
+++ b/packages/frontend/src/components/MkMediaVideo.vue
@@ -17,8 +17,8 @@
 		controls
 		@contextmenu.stop
 	>
-		<source 
-			:src="video.url" 
+		<source
+			:src="video.url"
 			:type="video.type"
 		>
 	</video>
diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue
index a65039277b..1f8a36b8de 100644
--- a/packages/frontend/src/components/MkNoteDetailed.vue
+++ b/packages/frontend/src/components/MkNoteDetailed.vue
@@ -293,7 +293,7 @@ function renote(viaKeyboard = false) {
 				const y = rect.top + (el.offsetHeight / 2);
 				os.popup(MkRippleEffect, { x, y }, {}, 'end');
 			}
-				
+
 			os.api('notes/create', {
 				renoteId: appearNote.id,
 			}).then(() => {
diff --git a/packages/frontend/src/components/MkSuperMenu.vue b/packages/frontend/src/components/MkSuperMenu.vue
index 72b70416d9..0bc9b03160 100644
--- a/packages/frontend/src/components/MkSuperMenu.vue
+++ b/packages/frontend/src/components/MkSuperMenu.vue
@@ -46,7 +46,7 @@ defineProps<{
 			margin: 0 0 8px 0;
 			font-size: 0.9em;
 		}
-	
+
 		> .items {
 			> .item {
 				display: flex;
diff --git a/packages/frontend/src/components/MkUserPopup.vue b/packages/frontend/src/components/MkUserPopup.vue
index c3b777a12e..937e0f0798 100644
--- a/packages/frontend/src/components/MkUserPopup.vue
+++ b/packages/frontend/src/components/MkUserPopup.vue
@@ -195,7 +195,7 @@ onMounted(() => {
 .mfm {
 	display: -webkit-box;
 	-webkit-line-clamp: 5;
-	-webkit-box-orient: vertical;  
+	-webkit-box-orient: vertical;
 	overflow: hidden;
 }
 
diff --git a/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts b/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts
index 7d5a65f41a..67243b78f3 100644
--- a/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts
+++ b/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts
@@ -26,7 +26,7 @@ export const Default = {
 		};
 	},
 	args: {
-		
+
 	},
 	parameters: {
 		layout: 'centered',
diff --git a/packages/frontend/src/components/MkUserSetupDialog.Privacy.stories.impl.ts b/packages/frontend/src/components/MkUserSetupDialog.Privacy.stories.impl.ts
index 70817d83c3..0726289722 100644
--- a/packages/frontend/src/components/MkUserSetupDialog.Privacy.stories.impl.ts
+++ b/packages/frontend/src/components/MkUserSetupDialog.Privacy.stories.impl.ts
@@ -23,7 +23,7 @@ export const Default = {
 		};
 	},
 	args: {
-		
+
 	},
 	parameters: {
 		layout: 'centered',
diff --git a/packages/frontend/src/components/MkUserSetupDialog.Profile.stories.impl.ts b/packages/frontend/src/components/MkUserSetupDialog.Profile.stories.impl.ts
index f4930aa26b..3444605e97 100644
--- a/packages/frontend/src/components/MkUserSetupDialog.Profile.stories.impl.ts
+++ b/packages/frontend/src/components/MkUserSetupDialog.Profile.stories.impl.ts
@@ -23,7 +23,7 @@ export const Default = {
 		};
 	},
 	args: {
-		
+
 	},
 	parameters: {
 		layout: 'centered',
diff --git a/packages/frontend/src/components/MkUserSetupDialog.User.vue b/packages/frontend/src/components/MkUserSetupDialog.User.vue
index d66f34f165..b35f27c5b0 100644
--- a/packages/frontend/src/components/MkUserSetupDialog.User.vue
+++ b/packages/frontend/src/components/MkUserSetupDialog.User.vue
@@ -90,7 +90,7 @@ async function follow() {
 .mfm {
 	display: -webkit-box;
 	-webkit-line-clamp: 5;
-	-webkit-box-orient: vertical;  
+	-webkit-box-orient: vertical;
 	overflow: hidden;
 }
 
diff --git a/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts b/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts
index 55790602d5..f47f4c13d5 100644
--- a/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts
+++ b/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts
@@ -26,7 +26,7 @@ export const Default = {
 		};
 	},
 	args: {
-		
+
 	},
 	parameters: {
 		layout: 'centered',
diff --git a/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts b/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts
index 2a50a34390..3e756cae90 100644
--- a/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts
+++ b/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts
@@ -199,7 +199,7 @@ export default function(props: {
 						}
 						const x = Math.min(parseFloat(token.props.args.x ?? '1'), 5);
 						const y = Math.min(parseFloat(token.props.args.y ?? '1'), 5);
-						style = `transform: scale(${x}, ${y});`; 
+						style = `transform: scale(${x}, ${y});`;
 						scale = scale * Math.max(x, y);
 						break;
 					}
diff --git a/packages/frontend/src/directives/adaptive-bg.ts b/packages/frontend/src/directives/adaptive-bg.ts
index 313aad7996..83bcd7089d 100644
--- a/packages/frontend/src/directives/adaptive-bg.ts
+++ b/packages/frontend/src/directives/adaptive-bg.ts
@@ -10,7 +10,7 @@ export default {
 				return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
 			}
 		};
-	
+
 		const parentBg = getBgColor(src.parentElement);
 
 		const myBg = window.getComputedStyle(src).backgroundColor;
diff --git a/packages/frontend/src/directives/adaptive-border.ts b/packages/frontend/src/directives/adaptive-border.ts
index 619c9f0b6d..5bd04024be 100644
--- a/packages/frontend/src/directives/adaptive-border.ts
+++ b/packages/frontend/src/directives/adaptive-border.ts
@@ -10,7 +10,7 @@ export default {
 				return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
 			}
 		};
-	
+
 		const parentBg = getBgColor(src.parentElement);
 
 		const myBg = window.getComputedStyle(src).backgroundColor;
diff --git a/packages/frontend/src/directives/panel.ts b/packages/frontend/src/directives/panel.ts
index d31dc41ed4..8727183d36 100644
--- a/packages/frontend/src/directives/panel.ts
+++ b/packages/frontend/src/directives/panel.ts
@@ -10,7 +10,7 @@ export default {
 				return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
 			}
 		};
-	
+
 		const parentBg = getBgColor(src.parentElement);
 
 		const myBg = getComputedStyle(document.documentElement).getPropertyValue('--panel');
diff --git a/packages/frontend/src/filters/date.ts b/packages/frontend/src/filters/date.ts
index 706b7d60cc..9bc9bfe8ab 100644
--- a/packages/frontend/src/filters/date.ts
+++ b/packages/frontend/src/filters/date.ts
@@ -1,4 +1,4 @@
 import { dateTimeFormat } from '@/scripts/intl-const';
 
-export default (d: Date | number | undefined) => dateTimeFormat.format(d); 
+export default (d: Date | number | undefined) => dateTimeFormat.format(d);
 export const dateString = (d: string) => dateTimeFormat.format(new Date(d));
diff --git a/packages/frontend/src/local-storage.ts b/packages/frontend/src/local-storage.ts
index ca4f21f79b..f9d04f7950 100644
--- a/packages/frontend/src/local-storage.ts
+++ b/packages/frontend/src/local-storage.ts
@@ -14,7 +14,7 @@ type Keys =
 	'wallpaper' |
 	'theme' |
 	'colorScheme' |
-	'useSystemFont' | 
+	'useSystemFont' |
 	'fontSize' |
 	'ui' |
 	'ui_temp' |
diff --git a/packages/frontend/src/nirax.ts b/packages/frontend/src/nirax.ts
index 68977ed796..40348ded17 100644
--- a/packages/frontend/src/nirax.ts
+++ b/packages/frontend/src/nirax.ts
@@ -159,11 +159,11 @@ export class Router extends EventEmitter<{
 					if (route.hash != null && hash != null) {
 						props.set(route.hash, safeURIDecode(hash));
 					}
-	
+
 					if (route.query != null && queryString != null) {
 						const queryObject = [...new URLSearchParams(queryString).entries()]
 							.reduce((obj, entry) => ({ ...obj, [entry[0]]: entry[1] }), {});
-	
+
 						for (const q in route.query) {
 							const as = route.query[q];
 							if (queryObject[q]) {
@@ -171,7 +171,7 @@ export class Router extends EventEmitter<{
 							}
 						}
 					}
-	
+
 					return {
 						route,
 						props,
diff --git a/packages/frontend/src/pages/about.emojis.vue b/packages/frontend/src/pages/about.emojis.vue
index 3744bed10f..cc0bf2eed2 100644
--- a/packages/frontend/src/pages/about.emojis.vue
+++ b/packages/frontend/src/pages/about.emojis.vue
@@ -20,7 +20,7 @@
 			<XEmoji v-for="emoji in searchEmojis" :key="emoji.name" :emoji="emoji"/>
 		</div>
 	</MkFoldableSection>
-	
+
 	<MkFoldableSection v-for="category in customEmojiCategories" v-once :key="category">
 		<template #header>{{ category || i18n.ts.other }}</template>
 		<div :class="$style.emojis">
@@ -56,7 +56,7 @@ function search() {
 		const queryarry = q.match(/\:([a-z0-9_]*)\:/g);
 
 		if (queryarry) {
-			searchEmojis = customEmojis.value.filter(emoji => 
+			searchEmojis = customEmojis.value.filter(emoji =>
 				queryarry.includes(`:${emoji.name}:`),
 			);
 		} else {
diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue
index 8b083bc896..226eb8d026 100644
--- a/packages/frontend/src/pages/admin/index.vue
+++ b/packages/frontend/src/pages/admin/index.vue
@@ -1,6 +1,6 @@
 <template>
 <div ref="el" class="hiyeyicy" :class="{ wide: !narrow }">
-	<div v-if="!narrow || currentPage?.route.name == null" class="nav">	
+	<div v-if="!narrow || currentPage?.route.name == null" class="nav">
 		<MkSpacer :contentMax="700" :marginMin="16">
 			<div class="lxpfedzu">
 				<div class="banner">
diff --git a/packages/frontend/src/pages/admin/moderation.vue b/packages/frontend/src/pages/admin/moderation.vue
index e36c9ac91d..13789820a0 100644
--- a/packages/frontend/src/pages/admin/moderation.vue
+++ b/packages/frontend/src/pages/admin/moderation.vue
@@ -24,7 +24,7 @@
 						<template #label>{{ i18n.ts.preservedUsernames }}</template>
 						<template #caption>{{ i18n.ts.preservedUsernamesDescription }}</template>
 					</MkTextarea>
-					
+
 					<MkTextarea v-model="sensitiveWords">
 						<template #label>{{ i18n.ts.sensitiveWords }}</template>
 						<template #caption>{{ i18n.ts.sensitiveWordsDescription }}<br>{{ i18n.ts.sensitiveWordsDescription2 }}</template>
diff --git a/packages/frontend/src/pages/admin/overview.ap-requests.vue b/packages/frontend/src/pages/admin/overview.ap-requests.vue
index ad8e623415..bde5580366 100644
--- a/packages/frontend/src/pages/admin/overview.ap-requests.vue
+++ b/packages/frontend/src/pages/admin/overview.ap-requests.vue
@@ -259,7 +259,7 @@ onMounted(async () => {
 		},
 		plugins: [chartVLine(vLineColor)],
 	});
-	
+
 	fetching = false;
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/overview.federation.vue b/packages/frontend/src/pages/admin/overview.federation.vue
index ab78c4c393..469d2e6927 100644
--- a/packages/frontend/src/pages/admin/overview.federation.vue
+++ b/packages/frontend/src/pages/admin/overview.federation.vue
@@ -58,7 +58,7 @@ let federationSubActiveDiff = $ref<number | null>(null);
 let fetching = $ref(true);
 
 const { handler: externalTooltipHandler } = useChartTooltip();
-	
+
 onMounted(async () => {
 	const chart = await os.apiGet('charts/federation', { limit: 2, span: 'day' });
 	federationPubActive = chart.pubActive[0];
diff --git a/packages/frontend/src/pages/admin/overview.queue.vue b/packages/frontend/src/pages/admin/overview.queue.vue
index 69ca89e226..b08757aeb8 100644
--- a/packages/frontend/src/pages/admin/overview.queue.vue
+++ b/packages/frontend/src/pages/admin/overview.queue.vue
@@ -122,4 +122,4 @@ onUnmounted(() => {
 		}
 	}
 }
-</style>	
+</style>
diff --git a/packages/frontend/src/pages/admin/overview.vue b/packages/frontend/src/pages/admin/overview.vue
index e8295c81b5..838c197f05 100644
--- a/packages/frontend/src/pages/admin/overview.vue
+++ b/packages/frontend/src/pages/admin/overview.vue
@@ -30,7 +30,7 @@
 			<template #header>Federation</template>
 			<XFederation/>
 		</MkFoldableSection>
-		
+
 		<MkFoldableSection class="item">
 			<template #header>Instances</template>
 			<XInstances/>
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index a1fa9d2932..02a2d4366a 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -210,7 +210,7 @@
 					</MkRange>
 				</div>
 			</MkFolder>
-			
+
 			<MkFolder v-if="matchQuery([i18n.ts._role._options.driveCapacity, 'driveCapacityMb'])">
 				<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
 				<template #suffix>
diff --git a/packages/frontend/src/pages/channel-editor.vue b/packages/frontend/src/pages/channel-editor.vue
index 0a358a141b..cacdab040f 100644
--- a/packages/frontend/src/pages/channel-editor.vue
+++ b/packages/frontend/src/pages/channel-editor.vue
@@ -25,11 +25,11 @@
 
 			<MkFolder :defaultOpen="true">
 				<template #label>{{ i18n.ts.pinnedNotes }}</template>
-				
+
 				<div class="_gaps">
 					<MkButton primary rounded @click="addPinnedNote()"><i class="ti ti-plus"></i></MkButton>
 
-					<Sortable 
+					<Sortable
 						v-model="pinnedNotes"
 						itemKey="id"
 						:handle="'.' + $style.pinnedNoteHandle"
@@ -160,7 +160,7 @@ async function archive() {
 	});
 
 	if (canceled) return;
-	
+
 	os.api('channels/update', {
 		channelId: props.channelId,
 		isArchived: true,
diff --git a/packages/frontend/src/pages/clip.vue b/packages/frontend/src/pages/clip.vue
index d5313099da..b09f787b5b 100644
--- a/packages/frontend/src/pages/clip.vue
+++ b/packages/frontend/src/pages/clip.vue
@@ -55,7 +55,7 @@ watch(() => props.clipId, async () => {
 	favorited = clip.isFavorited;
 }, {
 	immediate: true,
-}); 
+});
 
 provide('currentClip', $$(clip));
 
diff --git a/packages/frontend/src/pages/custom-emojis-manager.vue b/packages/frontend/src/pages/custom-emojis-manager.vue
index 901fbc1eea..dde4d67f18 100644
--- a/packages/frontend/src/pages/custom-emojis-manager.vue
+++ b/packages/frontend/src/pages/custom-emojis-manager.vue
@@ -311,13 +311,13 @@ definePageMetadata(computed(() => ({
 		.empty {
 			margin: var(--margin);
 		}
-		
+
 		.ldhfsamy {
 			display: grid;
 			grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
 			grid-gap: 12px;
 			margin: var(--margin) 0;
-	
+
 			> .emoji {
 				display: flex;
 				align-items: center;
diff --git a/packages/frontend/src/pages/follow.vue b/packages/frontend/src/pages/follow.vue
index d14b663364..2d08b66868 100644
--- a/packages/frontend/src/pages/follow.vue
+++ b/packages/frontend/src/pages/follow.vue
@@ -20,7 +20,7 @@ async function follow(user): Promise<void> {
 		window.close();
 		return;
 	}
-	
+
 	os.apiWithDialog('following/create', {
 		userId: user.id,
 	});
diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue
index 83997b2555..ac765e88b7 100644
--- a/packages/frontend/src/pages/instance-info.vue
+++ b/packages/frontend/src/pages/instance-info.vue
@@ -49,7 +49,7 @@
 					<template #value><MkTime v-if="instance.latestRequestReceivedAt" :time="instance.latestRequestReceivedAt"/><span v-else>N/A</span></template>
 				</MkKeyValue>
 			</FormSection>
-	
+
 			<FormSection>
 				<MkKeyValue oneline style="margin: 1em 0;">
 					<template #key>Following (Pub)</template>
diff --git a/packages/frontend/src/pages/list.vue b/packages/frontend/src/pages/list.vue
index 40934fb71d..3307eef359 100644
--- a/packages/frontend/src/pages/list.vue
+++ b/packages/frontend/src/pages/list.vue
@@ -112,7 +112,7 @@ definePageMetadata(computed(() => list ? {
 	flex: 1;
 	min-width: 0;
 	margin-right: 8px;
-	
+
 	&:hover {
 		text-decoration: none;
 	}
diff --git a/packages/frontend/src/pages/registry.keys.vue b/packages/frontend/src/pages/registry.keys.vue
index b1d41fe2c7..59f1f7fdb5 100644
--- a/packages/frontend/src/pages/registry.keys.vue
+++ b/packages/frontend/src/pages/registry.keys.vue
@@ -13,7 +13,7 @@
 					<template #value>{{ scope.join('/') }}</template>
 				</MkKeyValue>
 			</FormSplit>
-			
+
 			<MkButton primary @click="createKey">{{ i18n.ts._registry.createKey }}</MkButton>
 
 			<FormSection v-if="keys">
diff --git a/packages/frontend/src/pages/registry.value.vue b/packages/frontend/src/pages/registry.value.vue
index 513a2f8feb..ed01381d57 100644
--- a/packages/frontend/src/pages/registry.value.vue
+++ b/packages/frontend/src/pages/registry.value.vue
@@ -20,7 +20,7 @@
 						<template #value>{{ key }}</template>
 					</MkKeyValue>
 				</FormSplit>
-				
+
 				<MkTextarea v-model="valueForEditor" tall class="_monospace">
 					<template #label>{{ i18n.ts.value }} (JSON)</template>
 				</MkTextarea>
diff --git a/packages/frontend/src/pages/reset-password.vue b/packages/frontend/src/pages/reset-password.vue
index 9d57307314..fbd109b3f0 100644
--- a/packages/frontend/src/pages/reset-password.vue
+++ b/packages/frontend/src/pages/reset-password.vue
@@ -7,7 +7,7 @@
 				<template #prefix><i class="ti ti-lock"></i></template>
 				<template #label>{{ i18n.ts.newPassword }}</template>
 			</MkInput>
-		
+
 			<MkButton primary @click="save">{{ i18n.ts.save }}</MkButton>
 		</div>
 	</MkSpacer>
diff --git a/packages/frontend/src/pages/settings/drive-cleaner.vue b/packages/frontend/src/pages/settings/drive-cleaner.vue
index 8178343bbb..98471e94db 100644
--- a/packages/frontend/src/pages/settings/drive-cleaner.vue
+++ b/packages/frontend/src/pages/settings/drive-cleaner.vue
@@ -80,7 +80,7 @@ watch(sortModeSelect, () => {
 			sortMode.value = '+size';
 			fetchDriveInfo();
 			break;
-		
+
 		case 'createdAtAsc':
 			sortMode.value = '-createdAt';
 			fetchDriveInfo();
diff --git a/packages/frontend/src/pages/settings/navbar.vue b/packages/frontend/src/pages/settings/navbar.vue
index 8780bfbc1e..f0e9a1c3d9 100644
--- a/packages/frontend/src/pages/settings/navbar.vue
+++ b/packages/frontend/src/pages/settings/navbar.vue
@@ -3,7 +3,7 @@
 	<FormSlot>
 		<template #label>{{ i18n.ts.navbar }}</template>
 		<MkContainer :showHeader="false">
-			<Sortable 
+			<Sortable
 				v-model="items"
 				itemKey="id"
 				:animation="150"
diff --git a/packages/frontend/src/pages/settings/preferences-backups.vue b/packages/frontend/src/pages/settings/preferences-backups.vue
index e34901cd11..1aa1a5f81c 100644
--- a/packages/frontend/src/pages/settings/preferences-backups.vue
+++ b/packages/frontend/src/pages/settings/preferences-backups.vue
@@ -144,7 +144,7 @@ function validate(profile: unknown): void {
 
 	if (!profile.name) throw new Error('Missing required prop: name');
 	if (!profile.misskeyVersion) throw new Error('Missing required prop: misskeyVersion');
-	
+
 	// Check if createdAt and updatedAt is Date
 	// https://zenn.dev/lollipop_onl/articles/eoz-judge-js-invalid-date
 	if (!profile.createdAt || Number.isNaN(new Date(profile.createdAt).getTime())) throw new Error('createdAt is falsy or not Date');
@@ -273,7 +273,7 @@ async function applyProfile(id: string): Promise<void> {
 			defaultStore.set(key, settings.hot[key]);
 		}
 	}
-	
+
 	// coldDeviceStorage
 	for (const key of coldDeviceStorageSaveKeys) {
 		if (settings.cold[key] !== undefined) {
diff --git a/packages/frontend/src/pages/settings/privacy.vue b/packages/frontend/src/pages/settings/privacy.vue
index 7fd4d6d34e..88d109c021 100644
--- a/packages/frontend/src/pages/settings/privacy.vue
+++ b/packages/frontend/src/pages/settings/privacy.vue
@@ -7,7 +7,7 @@
 		{{ i18n.ts.makeReactionsPublic }}
 		<template #caption>{{ i18n.ts.makeReactionsPublicDescription }}</template>
 	</MkSwitch>
-		
+
 	<MkSelect v-model="ffVisibility" @update:modelValue="save()">
 		<template #label>{{ i18n.ts.ffVisibility }}</template>
 		<option value="public">{{ i18n.ts._ffVisibility.public }}</option>
@@ -15,7 +15,7 @@
 		<option value="private">{{ i18n.ts._ffVisibility.private }}</option>
 		<template #caption>{{ i18n.ts.ffVisibilityDescription }}</template>
 	</MkSelect>
-		
+
 	<MkSwitch v-model="hideOnlineStatus" @update:modelValue="save()">
 		{{ i18n.ts.hideOnlineStatus }}
 		<template #caption>{{ i18n.ts.hideOnlineStatusDescription }}</template>
diff --git a/packages/frontend/src/pages/settings/roles.vue b/packages/frontend/src/pages/settings/roles.vue
index 05753c9b60..4b842f56fd 100644
--- a/packages/frontend/src/pages/settings/roles.vue
+++ b/packages/frontend/src/pages/settings/roles.vue
@@ -37,7 +37,7 @@ import MkRolePreview from '@/components/MkRolePreview.vue';
 
 function save() {
 	os.apiWithDialog('i/update', {
-		
+
 	});
 }
 
diff --git a/packages/frontend/src/pages/settings/security.vue b/packages/frontend/src/pages/settings/security.vue
index 2da84763a3..bd5e2e350a 100644
--- a/packages/frontend/src/pages/settings/security.vue
+++ b/packages/frontend/src/pages/settings/security.vue
@@ -78,7 +78,7 @@ async function change() {
 		});
 		return;
 	}
-	
+
 	os.apiWithDialog('i/change-password', {
 		currentPassword,
 		newPassword,
diff --git a/packages/frontend/src/pizzax.ts b/packages/frontend/src/pizzax.ts
index d97bd4be62..996610602b 100644
--- a/packages/frontend/src/pizzax.ts
+++ b/packages/frontend/src/pizzax.ts
@@ -70,7 +70,7 @@ export class Storage<T extends StateDef> {
 			this.state[k] = v.default;
 			this.reactiveState[k] = ref(v.default);
 		}
-	
+
 		this.ready = this.init();
 		this.loaded = this.ready.then(() => this.load());
 	}
@@ -81,7 +81,7 @@ export class Storage<T extends StateDef> {
 		const deviceState: State<T> = await get(this.deviceStateKeyName) || {};
 		const deviceAccountState = $i ? await get(this.deviceAccountStateKeyName) || {} : {};
 		const registryCache = $i ? await get(this.registryCacheKeyName) || {} : {};
-	
+
 		for (const [k, v] of Object.entries(this.def) as [keyof T, T[keyof T]['default']][]) {
 			if (v.where === 'device' && Object.prototype.hasOwnProperty.call(deviceState, k)) {
 				this.reactiveState[k].value = this.state[k] = deviceState[k];
@@ -110,7 +110,7 @@ export class Storage<T extends StateDef> {
 				if (!scope || scope.length !== 2 || scope[0] !== 'client' || scope[1] !== this.key || this.state[key] === value) return;
 
 				this.reactiveState[key].value = this.state[key] = value;
-	
+
 				this.addIdbSetJob(async () => {
 					const cache = await get(this.registryCacheKeyName);
 					if (cache[key] !== value) {
@@ -142,7 +142,7 @@ export class Storage<T extends StateDef> {
 									}
 								}
 							}
-	
+
 							return set(this.registryCacheKeyName, cache);
 						})
 						.then(() => resolve());
@@ -252,7 +252,7 @@ export class Storage<T extends StateDef> {
 	// localStorage => indexedDBのマイグレーション
 	private async migrate() {
 		const deviceState = localStorage.getItem(this.deviceStateKeyName);
-		if (deviceState) { 
+		if (deviceState) {
 			await set(this.deviceStateKeyName, JSON.parse(deviceState));
 			localStorage.removeItem(this.deviceStateKeyName);
 		}
diff --git a/packages/frontend/src/scripts/aiscript/ui.ts b/packages/frontend/src/scripts/aiscript/ui.ts
index 2ca1b164ae..c26ae5a4df 100644
--- a/packages/frontend/src/scripts/aiscript/ui.ts
+++ b/packages/frontend/src/scripts/aiscript/ui.ts
@@ -510,7 +510,7 @@ export function registerAsUiLib(components: Ref<AsUiComponent>[], done: (root: R
 		// Ui:root.update({ children: [...] }) の糖衣構文
 		'Ui:render': values.FN_NATIVE(([children], opts) => {
 			utils.assertArray(children);
-		
+
 			rootComponent.value.children = children.value.map(v => {
 				utils.assertObject(v);
 				return v.value.get('id').value;
diff --git a/packages/frontend/src/scripts/get-user-menu.ts b/packages/frontend/src/scripts/get-user-menu.ts
index b055d26473..c884ed76cb 100644
--- a/packages/frontend/src/scripts/get-user-menu.ts
+++ b/packages/frontend/src/scripts/get-user-menu.ts
@@ -196,7 +196,7 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router
 								default: 'indefinitely',
 							});
 							if (canceled) return;
-						
+
 							const expiresAt = period === 'indefinitely' ? null
 								: period === 'oneHour' ? Date.now() + (1000 * 60 * 60)
 								: period === 'oneDay' ? Date.now() + (1000 * 60 * 60 * 24)
diff --git a/packages/frontend/src/scripts/lookup.ts b/packages/frontend/src/scripts/lookup.ts
index ce5b03fc38..0b594e3412 100644
--- a/packages/frontend/src/scripts/lookup.ts
+++ b/packages/frontend/src/scripts/lookup.ts
@@ -10,7 +10,7 @@ export async function lookup(router?: Router) {
 		title: i18n.ts.lookup,
 	});
 	if (canceled) return;
-	
+
 	if (query.startsWith('@') && !query.includes(' ')) {
 		_router.push(`/${query}`);
 		return;
diff --git a/packages/frontend/src/scripts/url.ts b/packages/frontend/src/scripts/url.ts
index b6a997449a..07737d6228 100644
--- a/packages/frontend/src/scripts/url.ts
+++ b/packages/frontend/src/scripts/url.ts
@@ -2,7 +2,7 @@
  * 1. 配列に何も入っていない時はクエリを付けない
  * 2. プロパティがundefinedの時はクエリを付けない
  * （new URLSearchParams(obj)ではそこまで丁寧なことをしてくれない）
- */ 
+ */
 export function query(obj: Record<string, any>): string {
 	const params = Object.entries(obj)
 		.filter(([, v]) => Array.isArray(v) ? v.length : v !== undefined)
diff --git a/packages/frontend/src/scripts/use-note-capture.ts b/packages/frontend/src/scripts/use-note-capture.ts
index 22a01e066a..d057386b13 100644
--- a/packages/frontend/src/scripts/use-note-capture.ts
+++ b/packages/frontend/src/scripts/use-note-capture.ts
@@ -93,12 +93,12 @@ export function useNoteCapture(props: {
 	function onStreamConnected() {
 		capture(false);
 	}
-	
+
 	capture(true);
 	if (connection) {
 		connection.on('_connected_', onStreamConnected);
 	}
-	
+
 	onUnmounted(() => {
 		decapture(true);
 		if (connection) {
diff --git a/packages/frontend/src/style.scss b/packages/frontend/src/style.scss
index b376e4c42d..b4b80a4bbe 100644
--- a/packages/frontend/src/style.scss
+++ b/packages/frontend/src/style.scss
@@ -7,7 +7,7 @@
 
 	--margin: var(--marginFull);
 	--minBottomSpacing: 0px;
-	
+
 	@media (max-width: 500px) {
 		--margin: var(--marginHalf);
 		--minBottomSpacing: calc(72px + max(12px, env(safe-area-inset-bottom, 0px)));
@@ -19,7 +19,7 @@
 ::selection {
 	color: var(--fgOnAccent);
 	background-color: var(--accent);
-} 
+}
 
 html {
 	background-color: var(--bg);
diff --git a/packages/frontend/src/themes/l-botanical.json5 b/packages/frontend/src/themes/l-botanical.json5
index 5c98927896..17e9ca246f 100644
--- a/packages/frontend/src/themes/l-botanical.json5
+++ b/packages/frontend/src/themes/l-botanical.json5
@@ -5,7 +5,7 @@
 	author: 'ThinaticSystem',
 
   base: 'light',
-	
+
 	props: {
 		accent: '#77b58c',
 		bg: 'e2deda',
diff --git a/packages/frontend/src/ui/classic.header.vue b/packages/frontend/src/ui/classic.header.vue
index 747d4edcb4..2c41e7759b 100644
--- a/packages/frontend/src/ui/classic.header.vue
+++ b/packages/frontend/src/ui/classic.header.vue
@@ -82,7 +82,7 @@ function openAccountMenu(ev: MouseEvent) {
 onMounted(() => {
 	window.addEventListener('resize', () => {
 		settingsWindowed = (window.innerWidth >= WINDOW_THRESHOLD);
-	}, { passive: true });	
+	}, { passive: true });
 });
 
 </script>
@@ -177,7 +177,7 @@ onMounted(() => {
 
 			> .post {
 				display: inline-block;
-			
+
 				> .button {
 					width: 40px;
 					height: 40px;
diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue
index d50f2b0454..2c58c29840 100644
--- a/packages/frontend/src/ui/classic.vue
+++ b/packages/frontend/src/ui/classic.vue
@@ -219,7 +219,7 @@ onMounted(() => {
 
 		&.fullView {
 			margin: 0;
-		
+
 			> .sidebar {
 				display: none;
 			}
diff --git a/packages/frontend/src/widgets/WidgetAiscriptApp.vue b/packages/frontend/src/widgets/WidgetAiscriptApp.vue
index 3b67972e40..94d2d922d2 100644
--- a/packages/frontend/src/widgets/WidgetAiscriptApp.vue
+++ b/packages/frontend/src/widgets/WidgetAiscriptApp.vue
@@ -37,7 +37,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 
 const props = defineProps<WidgetComponentProps<WidgetProps>>();
 const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
-	
+
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
 	props,
diff --git a/packages/frontend/src/widgets/WidgetClicker.vue b/packages/frontend/src/widgets/WidgetClicker.vue
index b7be2e8c83..6a997f7da8 100644
--- a/packages/frontend/src/widgets/WidgetClicker.vue
+++ b/packages/frontend/src/widgets/WidgetClicker.vue
@@ -25,7 +25,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 
 const props = defineProps<WidgetComponentProps<WidgetProps>>();
 const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
-	
+
 const { widgetProps, configure } = useWidgetPropsManager(name,
 	widgetPropsDef,
 	props,
diff --git a/packages/frontend/src/widgets/WidgetNotifications.vue b/packages/frontend/src/widgets/WidgetNotifications.vue
index a24aa9b2e9..d4f9a07cb5 100644
--- a/packages/frontend/src/widgets/WidgetNotifications.vue
+++ b/packages/frontend/src/widgets/WidgetNotifications.vue
@@ -41,7 +41,7 @@ type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
 
 const props = defineProps<WidgetComponentProps<WidgetProps>>();
 const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
-	
+
 const { widgetProps, configure, save } = useWidgetPropsManager(name,
 	widgetPropsDef,
 	props,
diff --git a/packages/misskey-js/src/streaming.ts b/packages/misskey-js/src/streaming.ts
index 92a220b496..c641706a4b 100644
--- a/packages/misskey-js/src/streaming.ts
+++ b/packages/misskey-js/src/streaming.ts
@@ -218,7 +218,7 @@ class Pool {
 		this.dec = this.dec.bind(this);
 		this.connect = this.connect.bind(this);
 		this.disconnect = this.disconnect.bind(this);
-	
+
 		this.channel = channel;
 		this.stream = stream;
 		this.id = id;
diff --git a/packages/misskey-js/test-d/streaming.ts b/packages/misskey-js/test-d/streaming.ts
index 7ff7f95999..853f376e6c 100644
--- a/packages/misskey-js/test-d/streaming.ts
+++ b/packages/misskey-js/test-d/streaming.ts
@@ -16,7 +16,7 @@ describe('Streaming', () => {
 		// {
 		//   otherparty?: User['id'] | null;
 		//   group?: UserGroup['id'] | null;
-		// } 
+		// }
 		// になっている」というテストを行いたいけどtsdでの書き方がわからない
 		const messagingChannel = stream.useChannel('messaging', { otherparty: 'aaa' });
 		messagingChannel.on('message', message => {
diff --git a/packages/misskey-js/test/api.ts b/packages/misskey-js/test/api.ts
index 84b1fc0933..6f9e656fef 100644
--- a/packages/misskey-js/test/api.ts
+++ b/packages/misskey-js/test/api.ts
@@ -137,7 +137,7 @@ describe('API', () => {
 				origin: 'https://misskey.test',
 				credential: 'TOKEN',
 			});
-	
+
 			await cli.request('i', {}, null);
 		} catch (e) {
 			expect(isAPIError(e)).toEqual(true);
@@ -165,7 +165,7 @@ describe('API', () => {
 				origin: 'https://misskey.test',
 				credential: 'TOKEN',
 			});
-	
+
 			await cli.request('i');
 		} catch (e: any) {
 			expect(isAPIError(e)).toEqual(true);
@@ -182,7 +182,7 @@ describe('API', () => {
 				origin: 'https://misskey.test',
 				credential: 'TOKEN',
 			});
-	
+
 			await cli.request('i');
 		} catch (e) {
 			expect(isAPIError(e)).toEqual(false);
@@ -203,7 +203,7 @@ describe('API', () => {
 				origin: 'https://misskey.test',
 				credential: 'TOKEN',
 			});
-	
+
 			await cli.request('i');
 		} catch (e) {
 			expect(isAPIError(e)).toEqual(false);
diff --git a/packages/misskey-js/test/streaming.ts b/packages/misskey-js/test/streaming.ts
index 913db8b287..9f6615a8d8 100644
--- a/packages/misskey-js/test/streaming.ts
+++ b/packages/misskey-js/test/streaming.ts
@@ -131,7 +131,7 @@ describe('Streaming', () => {
 		main.on('meUpdated', payload => {
 			mainChannelReceived.push(payload);
 		});
-		
+
 		const ws = await server.connected;
 		expect(new URLSearchParams(new URL(ws.url).search).get('i')).toEqual('TOKEN');
 
-- 
cgit v1.2.3-freya


From 36d5deeb611153ba3624384b6aca947784cc1e64 Mon Sep 17 00:00:00 2001
From: yupix <yupi0982@outlook.jp>
Date: Sat, 8 Jul 2023 17:48:10 +0900
Subject: fix: フォルダーのページネーションが機能しない (#11187)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* fix: フォルダーのページネーションが機能しない close #11180

* Update MkDrive.vue

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
---
 CHANGELOG.md                                 |  1 +
 packages/frontend/src/components/MkDrive.vue | 24 +++++++++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

(limited to 'packages/frontend/src/components/MkDrive.vue')

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a271902159..0a58750aae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,6 +29,7 @@
 - Fix: sparkle内にリンクを入れるとクリック不能になる問題の修正
 - Fix: ZenUIでポップアップの表示位置がおかしい問題を修正
 - Fix: ページ遷移でスクロール位置が保持されない問題を修正
+- Fix: フォルダーのページネーションが機能しない #11180
 
 ### Server
 - JSON.parse の回数を削減することで、ストリーミングのパフォーマンスを向上しました
diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue
index 917e785139..201a6ccdc8 100644
--- a/packages/frontend/src/components/MkDrive.vue
+++ b/packages/frontend/src/components/MkDrive.vue
@@ -56,7 +56,7 @@
 				/>
 				<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
 				<div v-for="(n, i) in 16" :key="i" :class="$style.padding"></div>
-				<MkButton v-if="moreFolders" ref="moreFolders">{{ i18n.ts.loadMore }}</MkButton>
+				<MkButton v-if="moreFolders" ref="moreFolders" @click="fetchMoreFolders">{{ i18n.ts.loadMore }}</MkButton>
 			</div>
 			<div v-show="files.length > 0" ref="filesContainer" :class="$style.files">
 				<XFile
@@ -560,6 +560,28 @@ async function fetch() {
 	fetching.value = false;
 }
 
+function fetchMoreFolders() {
+	fetching.value = true;
+
+	const max = 30;
+
+	os.api('drive/folders', {
+		folderId: folder.value ? folder.value.id : null,
+		type: props.type,
+		untilId: folders.value[folders.value.length - 1].id,
+		limit: max + 1,
+	}).then(folders => {
+		if (folders.length === max + 1) {
+			moreFolders.value = true;
+			folders.pop();
+		} else {
+			moreFolders.value = false;
+		}
+		for (const x of folders) appendFolder(x);
+		fetching.value = false;
+	});
+}
+
 function fetchMoreFiles() {
 	fetching.value = true;
 
-- 
cgit v1.2.3-freya


From 2b6dbd4fcbec380d65b0c318932d9eeb3fcb3f7b Mon Sep 17 00:00:00 2001
From: okayurisotto <okayurisotto@proton.me>
Date: Fri, 14 Jul 2023 10:45:01 +0900
Subject: refactor: 可読性のため一部で`Array.prototype.at`を使うように (#11274)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* refactor: `Array.prototype.at`を使うように

* fixup! refactor: `Array.prototype.at`を使うように
---
 packages/backend/src/core/chart/core.ts                           | 2 +-
 packages/backend/src/misc/prelude/array.ts                        | 5 +++--
 .../src/queue/processors/CleanRemoteFilesProcessorService.ts      | 6 +++---
 .../backend/src/queue/processors/DeleteAccountProcessorService.ts | 4 ++--
 .../src/queue/processors/DeleteDriveFilesProcessorService.ts      | 6 +++---
 .../src/queue/processors/ExportBlockingProcessorService.ts        | 6 +++---
 .../src/queue/processors/ExportFavoritesProcessorService.ts       | 2 +-
 .../src/queue/processors/ExportFollowingProcessorService.ts       | 2 +-
 .../backend/src/queue/processors/ExportMutingProcessorService.ts  | 6 +++---
 .../backend/src/queue/processors/ExportNotesProcessorService.ts   | 2 +-
 packages/backend/src/server/ActivityPubServerService.ts           | 6 +++---
 packages/backend/test/utils.ts                                    | 8 ++++----
 packages/frontend/src/components/MkDrive.vue                      | 4 ++--
 packages/frontend/src/components/MkMiniChart.vue                  | 4 ++--
 packages/frontend/src/components/MkPageWindow.vue                 | 2 +-
 packages/frontend/src/components/MkPagination.vue                 | 4 ++--
 packages/frontend/src/scripts/array.ts                            | 5 +++--
 packages/frontend/src/widgets/server-metric/cpu-mem.vue           | 8 ++++----
 packages/frontend/src/widgets/server-metric/net.vue               | 8 ++++----
 19 files changed, 46 insertions(+), 44 deletions(-)

(limited to 'packages/frontend/src/components/MkDrive.vue')

diff --git a/packages/backend/src/core/chart/core.ts b/packages/backend/src/core/chart/core.ts
index 5717024351..7a89233eda 100644
--- a/packages/backend/src/core/chart/core.ts
+++ b/packages/backend/src/core/chart/core.ts
@@ -627,7 +627,7 @@ export default abstract class Chart<T extends Schema> {
 			}
 
 		// 要求された範囲の最も古い箇所に位置するログが存在しなかったら
-		} else if (!isTimeSame(new Date(logs[logs.length - 1].date * 1000), gt)) {
+		} else if (!isTimeSame(new Date(logs.at(-1)!.date * 1000), gt)) {
 			// 要求された範囲の最も古い箇所時点での最も新しいログを持ってきて末尾に追加する
 			// (隙間埋めできないため)
 			const outdatedLog = await repository.findOne({
diff --git a/packages/backend/src/misc/prelude/array.ts b/packages/backend/src/misc/prelude/array.ts
index 0b2830cb7b..2524eacfb3 100644
--- a/packages/backend/src/misc/prelude/array.ts
+++ b/packages/backend/src/misc/prelude/array.ts
@@ -67,8 +67,9 @@ export function maximum(xs: number[]): number {
 export function groupBy<T>(f: EndoRelation<T>, xs: T[]): T[][] {
 	const groups = [] as T[][];
 	for (const x of xs) {
-		if (groups.length !== 0 && f(groups[groups.length - 1][0], x)) {
-			groups[groups.length - 1].push(x);
+		const lastGroup = groups.at(-1);
+		if (lastGroup !== undefined && f(lastGroup[0], x)) {
+			lastGroup.push(x);
 		} else {
 			groups.push([x]);
 		}
diff --git a/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts b/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts
index c54bf59ae4..6f887089eb 100644
--- a/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts
+++ b/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts
@@ -1,7 +1,7 @@
 import { Inject, Injectable } from '@nestjs/common';
 import { IsNull, MoreThan, Not } from 'typeorm';
 import { DI } from '@/di-symbols.js';
-import type { DriveFilesRepository } from '@/models/index.js';
+import type { DriveFile, DriveFilesRepository } from '@/models/index.js';
 import type { Config } from '@/config.js';
 import type Logger from '@/logger.js';
 import { DriveService } from '@/core/DriveService.js';
@@ -31,7 +31,7 @@ export class CleanRemoteFilesProcessorService {
 		this.logger.info('Deleting cached remote files...');
 
 		let deletedCount = 0;
-		let cursor: any = null;
+		let cursor: DriveFile['id'] | null = null;
 
 		while (true) {
 			const files = await this.driveFilesRepository.find({
@@ -51,7 +51,7 @@ export class CleanRemoteFilesProcessorService {
 				break;
 			}
 
-			cursor = files[files.length - 1].id;
+			cursor = files.at(-1)?.id ?? null;
 
 			await Promise.all(files.map(file => this.driveService.deleteFileSync(file, true)));
 
diff --git a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts
index 65ded170b7..b2886563f4 100644
--- a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts
+++ b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts
@@ -70,7 +70,7 @@ export class DeleteAccountProcessorService {
 					break;
 				}
 
-				cursor = notes[notes.length - 1].id;
+				cursor = notes.at(-1)?.id ?? null;
 
 				await this.notesRepository.delete(notes.map(note => note.id));
 
@@ -101,7 +101,7 @@ export class DeleteAccountProcessorService {
 					break;
 				}
 
-				cursor = files[files.length - 1].id;
+				cursor = files.at(-1)?.id ?? null;
 
 				for (const file of files) {
 					await this.driveService.deleteFileSync(file);
diff --git a/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts b/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts
index 6772c5dc76..07e3762330 100644
--- a/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts
+++ b/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts
@@ -1,7 +1,7 @@
 import { Inject, Injectable } from '@nestjs/common';
 import { MoreThan } from 'typeorm';
 import { DI } from '@/di-symbols.js';
-import type { UsersRepository, DriveFilesRepository } from '@/models/index.js';
+import type { UsersRepository, DriveFilesRepository, DriveFile } from '@/models/index.js';
 import type { Config } from '@/config.js';
 import type Logger from '@/logger.js';
 import { DriveService } from '@/core/DriveService.js';
@@ -40,7 +40,7 @@ export class DeleteDriveFilesProcessorService {
 		}
 
 		let deletedCount = 0;
-		let cursor: any = null;
+		let cursor: DriveFile['id'] | null = null;
 
 		while (true) {
 			const files = await this.driveFilesRepository.find({
@@ -59,7 +59,7 @@ export class DeleteDriveFilesProcessorService {
 				break;
 			}
 
-			cursor = files[files.length - 1].id;
+			cursor = files.at(-1)?.id ?? null;
 
 			for (const file of files) {
 				await this.driveService.deleteFileSync(file);
diff --git a/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts b/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts
index eb758e162d..d100c6d09f 100644
--- a/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts
@@ -3,7 +3,7 @@ import { Inject, Injectable } from '@nestjs/common';
 import { MoreThan } from 'typeorm';
 import { format as dateFormat } from 'date-fns';
 import { DI } from '@/di-symbols.js';
-import type { UsersRepository, BlockingsRepository } from '@/models/index.js';
+import type { UsersRepository, BlockingsRepository, Blocking } from '@/models/index.js';
 import type { Config } from '@/config.js';
 import type Logger from '@/logger.js';
 import { DriveService } from '@/core/DriveService.js';
@@ -53,7 +53,7 @@ export class ExportBlockingProcessorService {
 			const stream = fs.createWriteStream(path, { flags: 'a' });
 
 			let exportedCount = 0;
-			let cursor: any = null;
+			let cursor: Blocking['id'] | null = null;
 
 			while (true) {
 				const blockings = await this.blockingsRepository.find({
@@ -72,7 +72,7 @@ export class ExportBlockingProcessorService {
 					break;
 				}
 
-				cursor = blockings[blockings.length - 1].id;
+				cursor = blockings.at(-1)?.id ?? null;
 
 				for (const block of blockings) {
 					const u = await this.usersRepository.findOneBy({ id: block.blockeeId });
diff --git a/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts b/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts
index 76c38a6b86..2be42b1a7a 100644
--- a/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts
@@ -94,7 +94,7 @@ export class ExportFavoritesProcessorService {
 					break;
 				}
 
-				cursor = favorites[favorites.length - 1].id;
+				cursor = favorites.at(-1)?.id ?? null;
 
 				for (const favorite of favorites) {
 					let poll: Poll | undefined;
diff --git a/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts b/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts
index 8726cb1402..d54e5e0b34 100644
--- a/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts
@@ -79,7 +79,7 @@ export class ExportFollowingProcessorService {
 					break;
 				}
 
-				cursor = followings[followings.length - 1].id;
+				cursor = followings.at(-1)?.id ?? null;
 
 				for (const following of followings) {
 					const u = await this.usersRepository.findOneBy({ id: following.followeeId });
diff --git a/packages/backend/src/queue/processors/ExportMutingProcessorService.ts b/packages/backend/src/queue/processors/ExportMutingProcessorService.ts
index 0f11a9e843..030e38931e 100644
--- a/packages/backend/src/queue/processors/ExportMutingProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportMutingProcessorService.ts
@@ -3,7 +3,7 @@ import { Inject, Injectable } from '@nestjs/common';
 import { IsNull, MoreThan } from 'typeorm';
 import { format as dateFormat } from 'date-fns';
 import { DI } from '@/di-symbols.js';
-import type { MutingsRepository, UsersRepository, BlockingsRepository } from '@/models/index.js';
+import type { MutingsRepository, UsersRepository, BlockingsRepository, Muting } from '@/models/index.js';
 import type { Config } from '@/config.js';
 import type Logger from '@/logger.js';
 import { DriveService } from '@/core/DriveService.js';
@@ -56,7 +56,7 @@ export class ExportMutingProcessorService {
 			const stream = fs.createWriteStream(path, { flags: 'a' });
 
 			let exportedCount = 0;
-			let cursor: any = null;
+			let cursor: Muting['id'] | null = null;
 
 			while (true) {
 				const mutes = await this.mutingsRepository.find({
@@ -76,7 +76,7 @@ export class ExportMutingProcessorService {
 					break;
 				}
 
-				cursor = mutes[mutes.length - 1].id;
+				cursor = mutes.at(-1)?.id ?? null;
 
 				for (const mute of mutes) {
 					const u = await this.usersRepository.findOneBy({ id: mute.muteeId });
diff --git a/packages/backend/src/queue/processors/ExportNotesProcessorService.ts b/packages/backend/src/queue/processors/ExportNotesProcessorService.ts
index 24fb331883..75f32ffee3 100644
--- a/packages/backend/src/queue/processors/ExportNotesProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportNotesProcessorService.ts
@@ -90,7 +90,7 @@ export class ExportNotesProcessorService {
 					break;
 				}
 
-				cursor = notes[notes.length - 1].id;
+				cursor = notes.at(-1)?.id ?? null;
 
 				for (const note of notes) {
 					let poll: Poll | undefined;
diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts
index f751709345..634f5f0a4e 100644
--- a/packages/backend/src/server/ActivityPubServerService.ts
+++ b/packages/backend/src/server/ActivityPubServerService.ts
@@ -181,7 +181,7 @@ export class ActivityPubServerService {
 				undefined,
 				inStock ? `${partOf}?${url.query({
 					page: 'true',
-					cursor: followings[followings.length - 1].id,
+					cursor: followings.at(-1)!.id,
 				})}` : undefined,
 			);
 
@@ -273,7 +273,7 @@ export class ActivityPubServerService {
 				undefined,
 				inStock ? `${partOf}?${url.query({
 					page: 'true',
-					cursor: followings[followings.length - 1].id,
+					cursor: followings.at(-1)!.id,
 				})}` : undefined,
 			);
 
@@ -398,7 +398,7 @@ export class ActivityPubServerService {
 				})}` : undefined,
 				notes.length ? `${partOf}?${url.query({
 					page: 'true',
-					until_id: notes[notes.length - 1].id,
+					until_id: notes.at(-1)!.id,
 				})}` : undefined,
 			);
 
diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts
index 48947072e3..31ea3e5ab8 100644
--- a/packages/backend/test/utils.ts
+++ b/packages/backend/test/utils.ts
@@ -447,12 +447,12 @@ export async function testPaginationConsistency<Entity extends { id: string, cre
 	for (const limit of [1, 5, 10, 100, undefined]) {
 		// 1. sinceId/DateとuntilId/Dateで両端を指定して取得した結果が期待通りになっていること
 		if (ordering === 'desc') {
-			const end = expected[expected.length - 1];
+			const end = expected.at(-1)!;
 			let last = await fetchEntities(rangeToParam({ limit, since: end }));
 			const actual: Entity[] = [];
 			while (last.length !== 0) {
 				actual.push(...last);
-				last = await fetchEntities(rangeToParam({ limit, until: last[last.length - 1], since: end }));
+				last = await fetchEntities(rangeToParam({ limit, until: last.at(-1), since: end }));
 			}
 			actual.push(end);
 			assert.deepStrictEqual(
@@ -467,7 +467,7 @@ export async function testPaginationConsistency<Entity extends { id: string, cre
 			const actual: Entity[] = [];
 			while (last.length !== 0) {
 				actual.push(...last);
-				last = await fetchEntities(rangeToParam({ limit, since: last[last.length - 1] }));
+				last = await fetchEntities(rangeToParam({ limit, since: last.at(-1) }));
 			}
 			assert.deepStrictEqual(
 				actual.map(({ id, createdAt }) => id + ':' + createdAt),
@@ -480,7 +480,7 @@ export async function testPaginationConsistency<Entity extends { id: string, cre
 			const actual: Entity[] = [];
 			while (last.length !== 0) {
 				actual.push(...last);
-				last = await fetchEntities(rangeToParam({ limit, until: last[last.length - 1] }));
+				last = await fetchEntities(rangeToParam({ limit, until: last.at(-1) }));
 			}
 			assert.deepStrictEqual(
 				actual.map(({ id, createdAt }) => id + ':' + createdAt),
diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue
index 201a6ccdc8..aff227da40 100644
--- a/packages/frontend/src/components/MkDrive.vue
+++ b/packages/frontend/src/components/MkDrive.vue
@@ -568,7 +568,7 @@ function fetchMoreFolders() {
 	os.api('drive/folders', {
 		folderId: folder.value ? folder.value.id : null,
 		type: props.type,
-		untilId: folders.value[folders.value.length - 1].id,
+		untilId: folders.value.at(-1)?.id,
 		limit: max + 1,
 	}).then(folders => {
 		if (folders.length === max + 1) {
@@ -591,7 +591,7 @@ function fetchMoreFiles() {
 	os.api('drive/files', {
 		folderId: folder.value ? folder.value.id : null,
 		type: props.type,
-		untilId: files.value[files.value.length - 1].id,
+		untilId: files.value.at(-1)?.id,
 		limit: max + 1,
 	}).then(files => {
 		if (files.length === max + 1) {
diff --git a/packages/frontend/src/components/MkMiniChart.vue b/packages/frontend/src/components/MkMiniChart.vue
index 89050e10f0..e884455709 100644
--- a/packages/frontend/src/components/MkMiniChart.vue
+++ b/packages/frontend/src/components/MkMiniChart.vue
@@ -59,8 +59,8 @@ function draw(): void {
 
 	polygonPoints = `0,${ viewBoxY } ${ polylinePoints } ${ viewBoxX },${ viewBoxY }`;
 
-	headX = _polylinePoints[_polylinePoints.length - 1][0];
-	headY = _polylinePoints[_polylinePoints.length - 1][1];
+	headX = _polylinePoints.at(-1)![0];
+	headY = _polylinePoints.at(-1)![1];
 }
 
 watch(() => props.src, draw, { immediate: true });
diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue
index 6318a9fd70..6e35ad4241 100644
--- a/packages/frontend/src/components/MkPageWindow.vue
+++ b/packages/frontend/src/components/MkPageWindow.vue
@@ -120,7 +120,7 @@ const contextmenu = $computed(() => ([{
 
 function back() {
 	history.pop();
-	router.replace(history[history.length - 1].path, history[history.length - 1].key);
+	router.replace(history.at(-1)!.path, history.at(-1)!.key);
 }
 
 function reload() {
diff --git a/packages/frontend/src/components/MkPagination.vue b/packages/frontend/src/components/MkPagination.vue
index 661b04c365..b9a75f6002 100644
--- a/packages/frontend/src/components/MkPagination.vue
+++ b/packages/frontend/src/components/MkPagination.vue
@@ -233,7 +233,7 @@ const fetchMore = async (): Promise<void> => {
 		...(props.pagination.offsetMode ? {
 			offset: offset.value,
 		} : {
-			untilId: Array.from(items.value.keys())[items.value.size - 1],
+			untilId: Array.from(items.value.keys()).at(-1),
 		}),
 	}).then(res => {
 		for (let i = 0; i < res.length; i++) {
@@ -297,7 +297,7 @@ const fetchMoreAhead = async (): Promise<void> => {
 		...(props.pagination.offsetMode ? {
 			offset: offset.value,
 		} : {
-			sinceId: Array.from(items.value.keys())[items.value.size - 1],
+			sinceId: Array.from(items.value.keys()).at(-1),
 		}),
 	}).then(res => {
 		if (res.length === 0) {
diff --git a/packages/frontend/src/scripts/array.ts b/packages/frontend/src/scripts/array.ts
index 4620c8b735..c9a146e707 100644
--- a/packages/frontend/src/scripts/array.ts
+++ b/packages/frontend/src/scripts/array.ts
@@ -78,8 +78,9 @@ export function maximum(xs: number[]): number {
 export function groupBy<T>(f: EndoRelation<T>, xs: T[]): T[][] {
 	const groups = [] as T[][];
 	for (const x of xs) {
-		if (groups.length !== 0 && f(groups[groups.length - 1][0], x)) {
-			groups[groups.length - 1].push(x);
+		const lastGroup = groups.at(-1);
+		if (lastGroup !== undefined && f(lastGroup[0], x)) {
+			lastGroup.push(x);
 		} else {
 			groups.push([x]);
 		}
diff --git a/packages/frontend/src/widgets/server-metric/cpu-mem.vue b/packages/frontend/src/widgets/server-metric/cpu-mem.vue
index c178ba5171..b9ba400b4d 100644
--- a/packages/frontend/src/widgets/server-metric/cpu-mem.vue
+++ b/packages/frontend/src/widgets/server-metric/cpu-mem.vue
@@ -121,10 +121,10 @@ function onStats(connStats) {
 	cpuPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${cpuPolylinePoints} ${viewBoxX},${viewBoxY}`;
 	memPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${memPolylinePoints} ${viewBoxX},${viewBoxY}`;
 
-	cpuHeadX = cpuPolylinePointsStats[cpuPolylinePointsStats.length - 1][0];
-	cpuHeadY = cpuPolylinePointsStats[cpuPolylinePointsStats.length - 1][1];
-	memHeadX = memPolylinePointsStats[memPolylinePointsStats.length - 1][0];
-	memHeadY = memPolylinePointsStats[memPolylinePointsStats.length - 1][1];
+	cpuHeadX = cpuPolylinePointsStats.at(-1)![0];
+	cpuHeadY = cpuPolylinePointsStats.at(-1)![1];
+	memHeadX = memPolylinePointsStats.at(-1)![0];
+	memHeadY = memPolylinePointsStats.at(-1)![1];
 
 	cpuP = (connStats.cpu * 100).toFixed(0);
 	memP = (connStats.mem.active / props.meta.mem.total * 100).toFixed(0);
diff --git a/packages/frontend/src/widgets/server-metric/net.vue b/packages/frontend/src/widgets/server-metric/net.vue
index 5a9134078d..817a422e63 100644
--- a/packages/frontend/src/widgets/server-metric/net.vue
+++ b/packages/frontend/src/widgets/server-metric/net.vue
@@ -94,10 +94,10 @@ function onStats(connStats) {
 	inPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${inPolylinePoints} ${viewBoxX},${viewBoxY}`;
 	outPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${outPolylinePoints} ${viewBoxX},${viewBoxY}`;
 
-	inHeadX = inPolylinePointsStats[inPolylinePointsStats.length - 1][0];
-	inHeadY = inPolylinePointsStats[inPolylinePointsStats.length - 1][1];
-	outHeadX = outPolylinePointsStats[outPolylinePointsStats.length - 1][0];
-	outHeadY = outPolylinePointsStats[outPolylinePointsStats.length - 1][1];
+	inHeadX = inPolylinePointsStats.at(-1)![0];
+	inHeadY = inPolylinePointsStats.at(-1)![1];
+	outHeadX = outPolylinePointsStats.at(-1)![0];
+	outHeadY = outPolylinePointsStats.at(-1)![1];
 
 	inRecent = connStats.net.rx;
 	outRecent = connStats.net.tx;
-- 
cgit v1.2.3-freya

