diff --git a/.github/ISSUE_TEMPLATE/01_bug-report.md b/.github/ISSUE_TEMPLATE/01_bug-report.md
index 019f8c739ddf2d4e04a70c1fcccf677c514733c4..8734fc0c3645f3ec8bb64e8561fcf803f430483c 100644
--- a/.github/ISSUE_TEMPLATE/01_bug-report.md
+++ b/.github/ISSUE_TEMPLATE/01_bug-report.md
@@ -16,11 +16,11 @@ First, in order to avoid duplicate Issues, please search to see if the problem y
 
 <!-- Tell us what the bug is -->
 
-## 🙂 Expected Behavior
+## 🥰 Expected Behavior
 
 <!--- Tell us what should happen -->
 
-## ☹️ Actual Behavior
+## 🤬 Actual Behavior
 
 <!--- Tell us what happens instead of the expected behavior -->
 
@@ -33,3 +33,7 @@ First, in order to avoid duplicate Issues, please search to see if the problem y
 ## 📌 Environment
 
 <!-- Tell us where on the platform it happens -->
+
+Misskey version:
+Your OS:
+Your browser:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 65f5e01947ca278581693fa6fd5ce6828b15f89d..b60a85cf1ec54ddcb823fe846fb1ee69928c4a5e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,11 +2,46 @@
 ## 12.x.x (unreleased)
 
 ### Improvements
+- 
 
 ### Bugfixes
+- 
 
+You should also include the user name that made the change.
 -->
 
+## 12.104.0 (2022/02/09)
+
+### Note
+このリリースはマイグレーションの規模が大きいため、インスタンスによってはマイグレーションに時間がかかる可能性があります。
+マイグレーションが終わらない場合は、チャートの情報はリセットされてしまいますが`__chart__`で始まるテーブルの**レコード**を全て削除(テーブル自体は消さないでください)してから再度試す方法もあります。
+
+### Improvements
+- チャートエンジンの強化 @syuilo
+	- テーブルサイズの削減
+	- notes/instance/perUserNotesチャートに添付ファイル付きノートの数を追加
+	- activeUsersチャートに新しい項目を追加
+	- federationチャートに新しい項目を追加
+	- apRequestチャートを追加
+	- networkチャート廃止
+- クライアント: 自インスタンス情報ページでチャートを見れるように @syuilo
+- クライアント: デバイスの種類を手動指定できるように @syuilo
+- クライアント: UIのアイコンを更新 @syuilo
+- クライアント: UIのアイコンをセルフホスティングするように @syuilo
+- NodeInfo のユーザー数と投稿数の内容を見直す @xianonn
+
+### Bugfixes
+- Client: タイムライン種別を切り替えると「新しいノートがあります」の表示が残留してしまうのを修正 @tamaina
+- Client: UIのサイズがおかしくなる問題の修正 @tamaina
+- Client: Setting instance information of notes to always show breaks the timeline @Johann150
+- Client: 環境に依っては返信する際のカーソル位置が正しくない問題を修正 @syuilo
+- Client: コントロールパネルのユーザー、ファイルにて、インスタンスの表示範囲切り替えが機能しない問題を修正 @syuilo
+- Client: アップデートお知らせダイアログが出ないのを修正 @syuilo
+- Client: Follows/Followers Visibility changes won't be saved unless clicking on an other checkbox @Johann150
+- API: Fix API cast @mei23
+- add instance favicon where it's missing @solfisher
+- チャートの定期resyncが動作していない問題を修正 @syuilo
+
 ## 12.103.1 (2022/02/02)
 
 ### Bugfixes
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 662fa709b5251606e0dba6e42ad21e1537b5ca81..6e0f500be5d316e09cc083a56a11126b8486eb9d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -16,6 +16,9 @@ Before creating an issue, please check the following:
 ## Before implementation
 When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented.
 
+At this point, you also need to clarify the goals of the PR you will create, and make sure that the other members of the team are aware of them.
+PRs that do not have a clear set of do's and don'ts tend to be bloated and difficult to review.
+
 Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask another member to assign you). By expressing your intention to work the Issue, you can prevent conflicts in the work.
 
 ## Well-known branches
@@ -39,6 +42,23 @@ Thank you for your PR! Before creating a PR, please check the following:
 
 Thanks for your cooperation 🤗
 
+## Reviewers guide
+Be willing to comment on the good points and not just the things you want fixed 💯
+
+### Review perspective
+- Scope
+  - Are the goals of the PR clear?
+  - Is the granularity of the PR appropriate?
+- Security
+	- Does merging this PR create a vulnerability?
+- Performance
+	- Will merging this PR cause unexpected performance degradation?
+	- Is there a more efficient way?
+- Testing
+	- Does the test ensure the expected behavior?
+	- Are there any omissions or gaps?
+	- Does it check for anomalies?
+
 ## Localization (l10n)
 Misskey uses [Crowdin](https://crowdin.com/project/misskey) for localization management.
 You can improve our translations with your Crowdin account.
diff --git a/gulpfile.js b/gulpfile.js
index 3bc0b23beef6122bb7c1566bd7d6d2c2e270a3f8..b7aa4e328e1cbdf4e8169e057642d88f24e3b385 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -19,6 +19,10 @@ gulp.task('copy:client:fonts', () =>
 	gulp.src('./packages/client/node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/_client_dist_/fonts/'))
 );
 
+gulp.task('copy:client:fontawesome', () =>
+	gulp.src('./packages/client/node_modules/@fortawesome/fontawesome-free/**/*').pipe(gulp.dest('./built/_client_dist_/fontawesome/'))
+);
+
 gulp.task('copy:client:locales', cb => {
 	fs.mkdirSync('./built/_client_dist_/locales', { recursive: true });
 
@@ -50,7 +54,7 @@ gulp.task('build:backend:style', () => {
 });
 
 gulp.task('build', gulp.parallel(
-	'copy:client:locales', 'copy:backend:views', 'build:backend:script', 'build:backend:style', 'copy:client:fonts'
+	'copy:client:locales', 'copy:backend:views', 'build:backend:script', 'build:backend:style', 'copy:client:fonts', 'copy:client:fontawesome'
 ));
 
 gulp.task('default', gulp.task('build'));
diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml
index 5a053cdee918910035bd99558ad41868bba84a26..914a16bb2fafdffd3cfb2745a8250cd95099fbe1 100644
--- a/locales/ar-SA.yml
+++ b/locales/ar-SA.yml
@@ -1110,6 +1110,8 @@ _exportOrImport:
   blockingList: "المستخدمون المحجوبون"
   userLists: "القوائم"
 _charts:
+  federation: "الفديرالية"
+  apRequest: "الطلبات"
   usersIncDec: "اختلاف عدد المستخدمين"
   usersTotal: "مجموع عدد المستخدمين والمستخدمات"
   activeUsers: "المستخدمون النشطون"
diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml
index 02f18cd1e95be6ad5fa5d8b5ce1c684c16674843..fa18a8b3d0d69cf79b3463d129a2c0104dc62560 100644
--- a/locales/bn-BD.yml
+++ b/locales/bn-BD.yml
@@ -141,6 +141,8 @@ flagAsBot: "বট হিসাবে চিহ্নিত করুন"
 flagAsBotDescription: "এই অ্যাকাউন্টটি যদি একটি প্রোগ্রাম দ্বারা পরিচালিত হয়, তাহলে এই অপশনটি চালু করুন। ইন্টারঅ্যাকশান চেইনিং রোধ করতে, মিস্কির সিস্টেম পরিচালনাকে বট-বান্ধব করতে এবং অন্যান্য ডেভেলপারদের সাহায্য করতে আপনার বট এ এই অপশনটি চালু করুন৷"
 flagAsCat: "বিড়াল হিসাবে চিহ্নিত করুন"
 flagAsCatDescription: "অ্যাকাউন্টটিকে বিড়াল হিসাবে চিহ্নিত করার জন্য অপশনটি চালু করুন।"
+flagShowTimelineReplies: "টাইমলাইনে নোটগুলির রিপ্লাই দেখান"
+flagShowTimelineRepliesDescription: "চালু করলে, টাইমলাইন ব্যবহারকারীর নোট ছাড়াও ব্যবহারকারীর অন্যান্য নোটের জবাবগুলো দেখায়।"
 autoAcceptFollowed: "আপনি যেসব অ্যাকাউন্ট অনুসরণ করেন, স্বয়ংক্রিয়ভাবে তাদের অনুসরণের অনুরধ স্বীকার করুন"
 addAccount: "অ্যাকাউন্ট যোগ করুন"
 loginFailed: "প্রবেশ করা যায়নি"
@@ -297,8 +299,8 @@ disconnectedFromServer: "সার্ভার থেকে সংযোগ ব
 reload: "আবার লোড করুন"
 doNothing: "কিছু করবেন না"
 reloadConfirm: "আপনি কি রিলোড করতে চান?"
-watch: "দেখুন"
-unwatch: "দেখা বন্ধ করুন "
+watch: "বিজ্ঞপ্তি পান"
+unwatch: "বিজ্ঞপ্তি পাওয়া বন্ধ করুন "
 accept: "অনুমোদন"
 reject: "প্রত্যাখ্যান"
 normal: "স্বাভাবিক"
@@ -345,6 +347,8 @@ hcaptchaSecretKey: "সিক্রেট কী"
 recaptcha: "reCAPTCHA"
 enableRecaptcha: "reCAPTCHA চালু করুন"
 recaptchaSiteKey: "সাইট কী"
+recaptchaSecretKey: "সিক্রেট কী"
+avoidMultiCaptchaConfirm: "একাধিক Captcha ব্যবহার করলে তারা পরস্পরের কাজে বাধা দিতে পারে। আপনি কি অন্যান্য Captcha নিষ্ক্রিয় করতে চান? আপনি 'বাতিল' ক্লিক করার মাধ্যমে একাধিক Captcha চালু রাখতে পারেন।"
 antennas: "অ্যান্টেনা"
 manageAntennas: "অ্যান্টেনা ব্যবস্থাপনা"
 name: "নাম"
@@ -396,8 +400,56 @@ uploadFolder: "আপলোডের জন্য ডিফল্ট ফোল
 cacheClear: "ক্যাশ পরিষ্কার করুন"
 markAsReadAllNotifications: "সমস্ত বিজ্ঞপ্তিগুলি পঠিত হিসাবে চিহ্নিত করুন"
 markAsReadAllUnreadNotes: "সমস্ত নোটগুলি পঠিত হিসাবে চিহ্নিত করুন"
+markAsReadAllTalkMessages: "সমস্ত মেসেজ পঠিত হিসাবে চিহ্নিত করুন"
+help: "সহায়তা"
+inputMessageHere: "এখানে মেসেজ লিখুন"
+close: "বন্ধ"
+group: "গ্রুপ"
+groups: "গ্রুপসমূহ"
+createGroup: "গ্রুপ তৈরী করুন"
+ownedGroups: "আপনার গ্রুপগুলি"
+joinedGroups: "যেসব গ্রুপে আপনি আছেন"
 invites: "আমন্ত্রণ"
+groupName: "গ্রুপের নাম"
+members: "সদস্যবৃন্দ"
+transfer: "হস্তান্তর"
+messagingWithUser: "প্রাইভেট চ্যাট"
+messagingWithGroup: "গ্রুপ চ্যাট"
+title: "শিরোনাম"
+text: "পাঠ্য"
+enable: "সক্রিয়"
+next: "পরবর্তী"
+retype: "পুনঃ প্রবেশ"
+noteOf: "{user} এর নোট"
+inviteToGroup: "গ্রুপে আমন্ত্রণ জানান"
+maxNoteTextLength: "নোট এর সর্বোচ্চ দৈর্ঘ্য"
+quoteAttached: "উদ্ধৃত"
+quoteQuestion: "উদ্ধৃতি হিসাবে সংযুক্ত করবেন?"
+noMessagesYet: "কোন মেসেজ নেই"
+newMessageExists: "নতুন মেসেজ পেয়েছেন"
+onlyOneFileCanBeAttached: "আপনি মেসেজের সাথে সর্বোচ্চ একটি ফাইল যুক্ত করতে পারবেন"
+signinRequired: "দয়া করে লগ ইন করুন"
 invitations: "আমন্ত্রণ"
+invitationCode: "ইনভাইট কোড"
+checking: "পরীক্ষা করা হচ্ছে..."
+available: "উপলব্ধ"
+unavailable: "অনুপলব্ধ"
+usernameInvalidFormat: "আপনি কেবলমাত্র a-z, A-Z, 0-9, _ ব্যবহার করতে পারেন"
+tooShort: "খুব ছোট"
+tooLong: "খুব বড়"
+weakPassword: "দুর্বল পাসওয়ার্ড"
+normalPassword: "সাধারণ পাসওয়ার্ড"
+strongPassword: "শক্তিশালী পাসওয়ার্ড"
+passwordMatched: "মিলেছে"
+passwordNotMatched: "মিলেনি"
+signinWith: "{x} এর সাহায্যে সাইন ইন করুন"
+signinFailed: "লগ ইন করা যায়নি। আপনার ব্যবহারকারীর নাম এবং পাসওয়ার্ড চেক করুন."
+tapSecurityKey: "সিকিউরিটি কী স্পর্শ করুন"
+or: "অথবা"
+language: "ভাষা"
+uiLanguage: "UI এর ভাষা"
+groupInvited: "আপনি একটি গ্রুপে আমন্ত্রিত হয়েছেন"
+aboutX: "{x} সম্পর্কে"
 useOsNativeEmojis: "অপারেটিং সিস্টেমের নেটিভ ইমোজি ব্যবহার করুন"
 disableDrawer: "ড্রয়ার মেনু প্রদর্শন করবেন না"
 youHaveNoGroups: "আপনার কোন গ্রুপ নেই "
@@ -428,37 +480,704 @@ promotion: "প্রমোশন"
 promote: "প্রচার করুন"
 numberOfDays: "দিনের সংখ্যা"
 hideThisNote: "নোটটি লুকান"
+showFeaturedNotesInTimeline: "টাইমলাইনে সুপারিশকৃত নোটগুলি দেখান"
+objectStorage: "অবজেক্ট স্টোরেজ"
+useObjectStorage: "অবজেক্ট স্টোরেজ ব্যাবহার করুন"
+objectStorageBaseUrl: "Base URL"
+objectStorageBaseUrlDesc: "রেফারেন্স হিসাবে ব্যবহৃত URL। আপনি একটি CDN বা প্রক্সি ব্যবহার করলে URL, S3: 'https://<bucket>.s3.amazonaws.com', GCS: 'https://storage.googleapis.com/<bucket>'।"
+objectStorageBucket: "Bucket"
+objectStorageBucketDesc: "ব্যবহার করা পরিষেবার bucket এর নাম লিখুন। "
+objectStoragePrefix: "Prefix"
+objectStoragePrefixDesc: "ফাইলসমূহ এই prefix যুক্ত ফোল্ডারের অধীনে সংরক্ষণ করা হবে।"
+objectStorageEndpoint: "এন্ডপয়েন্ট"
+objectStorageEndpointDesc: "S3 এর জন্য ফাঁকা রাখুন, অন্যথায় প্রতিটি পরিষেবার এন্ডপয়েন্ট নির্দিষ্ট করুন। '<host>'বা'<host>: <port>' হিসেবে লিখুন।"
+objectStorageRegion: "Region"
+objectStorageRegionDesc: "'xx-east-1'-এর মতো একটি region নির্দিষ্ট করুন। যদি আপনার পরিষেবাতে region এর ধারণা না থাকে, তাহলে এটি খালি বা 'us-east-1' হওয়া উচিত।"
+objectStorageUseSSL: "SSL ব্যাবহার করুন"
+objectStorageUseSSLDesc: "API কানেকশনগুলির জন্য যদি https ব্যাবহার না করেন, তাহলে এই অপশনটি বন্ধ করুন"
+objectStorageUseProxy: "Proxy ব্যাবহার করুন"
+objectStorageUseProxyDesc: "আপনি API সংযোগের জন্য proxy ব্যবহার না করলে, এটি বন্ধ করুন।"
+objectStorageSetPublicRead: "আপলোডের উপর ''public-read' সেট করুন"
+serverLogs: "সার্ভার লগ"
+deleteAll: "সব মুছুন"
+showFixedPostForm: "টাইমলাইনের শীর্ষে পোস্ট করার ফর্মটি দেখান"
+newNoteRecived: "নতুন নোট আছে"
+sounds: "শব্দ"
+listen: "শুনুন"
+none: "কিছুই না"
+showInPage: "পেজে দেখান"
+popout: "পপ-আউট"
+volume: "আওয়াজের মাত্রা"
+masterVolume: "মাস্টার আওয়াজের মাত্রা"
+details: "আরও জানুন"
+chooseEmoji: "ইমোজি নির্বাচন করুন"
+unableToProcess: "কাজটি সম্পন্ন করা যায়নি"
+recentUsed: "সম্প্রতি ব্যবহৃত"
+install: "ইন্সটল"
+uninstall: "আনইন্সটল"
+installedApps: "ইন্সটল করা অ্যাপসমূহ"
+nothing: "এখানে কিছুই নাই"
+installedDate: "ইন্সটল করার তারিখ"
+lastUsedDate: "সর্বশেষ ব্যাবহৃত"
+state: "অবস্থা"
+sort: "সাজান"
+ascendingOrder: "ঊর্ধ্বক্রমে"
+descendingOrder: "নিম্নক্রমে"
+scratchpad: "স্ক্র্যাচপ্যাড"
+scratchpadDescription: "স্ক্র্যাচপ্যাড AiScript-এর জন্য একটি পরীক্ষামূলক পরিবেশ প্রদান করে। আপনি মিস্কির সাথে ইন্টারঅ্যাক্ট করে এমন কোড লিখতে, চালাতে এবং তার ফলাফল দেখতে পারেন।"
+output: "আউটপুট"
+script: "স্ক্রিপ্ট"
+disablePagesScript: "পেজগুলোতে AiScript অক্ষম করুন"
+updateRemoteUser: "রিমোট ব্যবহারকারীর তথ্য আপডেট করুন"
+deleteAllFiles: "সকল ফাইল ডিলিট করুন"
+deleteAllFilesConfirm: "সকল ফাইল ডিলিট করতে চান?"
+removeAllFollowing: "সকল অনুসরণ বাতিল করুন"
+removeAllFollowingDescription: "{host} এর সকল ব্যাবহারকারীকে আর ফলোও করবেন না । যদি ইন্সত্যান্সটির কোন সমস্যা (যেমনঃ ইন্সত্যান্সটি আর নেই) হয়ে থাকে তবে এটি ব্যাবহার করুন । "
+userSuspended: "এই ব্যাবহারকারির অ্যাকাউন্ট স্থগিত করা হয়েছে"
+userSilenced: "এই ব্যাবহারকারিকে মিউট করা হয়েছে"
+yourAccountSuspendedTitle: "এই অ্যাকাউন্টটি স্থগিত করা হয়েছে"
+yourAccountSuspendedDescription: "সার্ভারের ব্যবহারের শর্তাবলী লঙ্ঘনের মতো কারণে এই অ্যাকাউন্টটি স্থগিত করা হয়েছে৷ বিস্তারিত জানার জন্য প্রশাসকের সাথে যোগাযোগ করুন । একটি নতুন অ্যাকাউন্ট তৈরি করবেন না দয়া করে ।"
+menu: "মেনু"
+divider: "খন্ডক"
+addItem: "আইটেম যোগ করুন"
+relays: "রিলেগুলি"
+addRelay: "রিলে যোগ করুন"
+inboxUrl: "inbox এর URL"
+addedRelays: "যোগকৃত রিলেগুলি"
+serviceworkerInfo: "পুশ বিজ্ঞপ্তির জন্য চালু করা লাগবে।"
+deletedNote: "ডিলিট করা নোট"
+invisibleNote: "অদৃশ্য নোট"
+enableInfiniteScroll: "ইনফিনিট স্ক্রল চালু করুন"
+visibility: "দৃশ্যমানতা"
+poll: "জরিপ"
+useCw: "কন্টেন্ট লুকান"
+enablePlayer: "ভিডিও প্লেয়ার খুলুন"
+disablePlayer: "ভিডিও প্লেয়ার বন্ধ করুন"
+expandTweet: "টুইট বিস্তারিত করুন"
+themeEditor: "থিম সম্পাদক"
+description: "বর্ণনা"
+describeFile: "ক্যাপশন যোগ করুন"
+enterFileDescription: "ক্যাপশন যোগ করুন"
+author: "লেখক"
+leaveConfirm: "কিছু পরিবর্তন সেভ করা হয়নি। আপনি কি চলে যেতে চান?"
+manage: "পরিচালনা"
+plugins: "প্লাগইনসমূহ"
+deck: "ডেক"
+undeck: "ডেকমুক্ত করুন"
+useBlurEffectForModal: "মোডালের জন্য ব্লার ইফেক্ট ব্যবহার করুন"
+useFullReactionPicker: "সম্পূর্ণ বৈশিষ্ট্যযুক্ত রিঅ্যাকশন পিকার ব্যবহার করুন"
+width: "প্রস্থ"
+height: "উচ্চতা"
+large: "বড়"
+medium: "মাঝারি"
+small: "ছোট"
+generateAccessToken: "অ্যাক্সেস টোকেন তৈরি করুন"
+permission: "অনুমতি"
+enableAll: "সবগুলি সক্রিয় করুন"
+disableAll: "সবগুলি নিষ্ক্রিয় করুন"
+tokenRequested: "অ্যাকাউন্টে অ্যাক্সেস প্রদান করবেন"
+pluginTokenRequestedDescription: "এই প্লাগইনটি এখানে দেওয়া অনুমুতিসমূহ ব্যাবহার করবে"
+notificationType: "বিজ্ঞপ্তির ধরন"
+edit: "সম্পাদনা"
+useStarForReactionFallback: "রিঅ্যাকশনের ইমোজি না জানলে ★ ব্যবহার করুন"
+emailServer: "ইমেইল সার্ভার"
+enableEmail: "ইমেইল বিতরণ চালু করুন"
+emailConfigInfo: "আপনার ইমেল ঠিকানা নিশ্চিত করতে এবং আপনার পাসওয়ার্ড পুনরায় সেট করতে ব্যবহৃত হয়"
+email: "ইমেইল"
+emailAddress: "ইমেইল ঠিকানা"
+smtpConfig: "SMTP সার্ভার কনফিগারেশন"
 smtpHost: "হোস্ট"
+smtpPort: "পোর্ট"
 smtpUser: "ব্যবহারকারীর নাম"
 smtpPass: "পাসওয়ার্ড"
+emptyToDisableSmtpAuth: "আপনি ব্যবহারকারীর নাম এবং পাসওয়ার্ড ফাঁকা রেখে SMTP প্রমাণীকরণ নিষ্ক্রিয় করতে পারেন।"
+smtpSecure: "SMTP সংযোগের জন্য SSL/TLS ব্যবহার করুন"
+smtpSecureInfo: "STARTTLS ব্যবহার করার সময় এটি বন্ধ করুন।"
+testEmail: "ইমেল বিতরণ পরীক্ষা করুন"
+wordMute: "বিশেষ কোন শব্দকে মিউট করুন"
+instanceMute: "মিউট করা ইন্সত্যান্সগুলি"
+userSaysSomething: "{name} কিছু বলেছে"
+makeActive: "সক্রিয় করা"
+display: "প্রদর্শন"
+copy: "অনুলিপি"
+metrics: "মেট্রিক্স"
+overview: "সারাংশ"
+logs: "লগ"
+delayed: "দেরি করুন"
+database: "ডেটাবেজ"
+channel: "চ্যানেলগুলি"
+create: "তৈরি করুন"
+notificationSetting: "বিজ্ঞপ্তির সেটিংস"
+notificationSettingDesc: "কি ধরনের বিজ্ঞপ্তি পাবেন তা নির্ধারণ করুন"
+useGlobalSetting: "গ্লোবাল সেটিংস ব্যাবহার করুন"
+useGlobalSettingDesc: "চালু করলে, আপনার অ্যাকাউন্টের বিজ্ঞপ্তি সেটিংস ব্যবহার করা হবে। বন্ধ করলে, এটি পৃথকভাবে সেট করা যেতে পারে।"
+other: "অন্যান্য"
+regenerateLoginToken: "লগইন টোকেন আবার বানান"
+regenerateLoginTokenDescription: "লগ ইন করার জন্য ব্যবহৃত অভ্যন্তরীণ টোকেন পুনরায় তৈরি করে। সাধারণত আপনার এটি করার দরকার নেই। এটি করলে, আপনি সমস্ত ডিভাইসে লগ আউট হয়ে যাবেন৷"
+setMultipleBySeparatingWithSpace: "আপনি একটি স্পেস দিয়ে আলাদা করে একাধিক এন্ট্রি দিতে পারেন।"
+fileIdOrUrl: "ফাইল ID অথবা URL"
+behavior: "আচরণ"
+sample: "উদাহরণ"
+abuseReports: "অভিযোগ"
+reportAbuse: "অভিযোগ"
+reportAbuseOf: "{name} এ অভিযোগ করুন"
+fillAbuseReportDescription: "রিপোর্টের কারণ বর্ণনা করুন. একটি বিশেষ নোট এর জন্য রিপোর্টটি হয়ে থাকে তবে তার URL টি অন্তর্ভুক্ত করুন। "
+abuseReported: "আপনার অভিযোগটি দাখিল করা হয়েছে। আপনাকে ধন্যবাদ।"
+reporter: "অভিযোগকারী"
+reporteeOrigin: "অভিযোগটির উৎস"
+reporterOrigin: "অভিযোগকারীর উৎস"
+forwardReport: "রিমোট ইন্সত্যান্সে অভিযোগটি পাঠান"
+forwardReportIsAnonymous: "আপনার তথ্য রিমোট ইন্সত্যান্সে পাঠানো হবে না এবং একটি বেনামী সিস্টেম অ্যাকাউন্ট হিসাবে প্রদর্শিত হবে।"
+send: "পাঠান"
+abuseMarkAsResolved: "অভিযোগটিকে সমাধাকৃত হিসাবে চিহ্নিত করুন"
+openInNewTab: "নতুন ট্যাবে খুলুন"
+openInSideView: "সাইড ভিউতে খুলুন"
+defaultNavigationBehaviour: "ডিফল্ট নেভিগেশন"
+editTheseSettingsMayBreakAccount: "এসব সেটিংস সম্পাদনা করলে আপনার অ্যাকাউন্টের ক্ষতি হতে পারে। "
+instanceTicker: "ইন্সত্যান্সে নোটের তথ্য"
+waitingFor: "{x} এর জন্য অপেক্ষা করা হচ্ছে"
+random: "র‍্যান্ডম"
+system: "সিস্টেম"
+switchUi: "UI পরিবর্তন করুন"
+desktop: "ডেস্কটপ"
+clip: "ক্লিপ"
+createNew: "নতুন"
+optional: "প্রয়োজনীয় নয়"
+createNewClip: "নতুন ক্লিপ তৈরি করুন"
+public: "সর্বজনীন"
+i18nInfo: "Misskey স্বেচ্ছাসেবকদের দ্বারা বিভিন্ন ভাষায় অনুবাদ করা হচ্ছে। আপনি {link} এ গিয়ে অনুবাদে সহযোগিতা করতে পারেন।"
+manageAccessTokens: "অ্যাক্সেস টোকেন পরিচালনা করুন"
+accountInfo: "অ্যাকাউন্টের তথ্য"
+notesCount: "নোটের সংখ্যা"
+repliesCount: "জবাবের সংখ্যা"
+renotesCount: "রিনোটের সংখ্যা"
+repliedCount: "জবাব গ্রহন করা হয়েছে"
+renotedCount: "রিনোট পেয়েছেন"
+followingCount: "যাদেরকে অনুসরণ করেন, তাদের সংখ্যা"
+followersCount: "অনুসরণকারীদের সংখ্যা"
+sentReactionsCount: "রিঅ্যাকশন পাঠানো হয়েছে"
+receivedReactionsCount: "রিঅ্যাকশন পেয়েছেন"
+pollVotesCount: "পোল ভোট দিয়েছেন"
+pollVotedCount: "পোল ভোট পেয়েছেন"
+yes: "হ্যাঁ"
+no: "না"
+driveFilesCount: "ড্রাইভে ফাইল এর সংখ্যা"
+driveUsage: "ড্রাইভ এর ব্যাবহার"
+noCrawle: "ক্রলার ইন্ডেক্সিং বন্ধ করুন"
+noCrawleDescription: "সার্চ ইঞ্জিনগুলিকে আপনার প্রোফাইল, নোট, পেজ ইত্যাদি ইনডেক্স করতে নিষেধ করুন। "
+lockedAccountInfo: "এমনকি আপনি আপনার অনুসরণকারীদের বেছে বেছে অনুমোদন করলেও, যে কেউ আপনার নোটগুলি দেখতে পাবে, যতক্ষণ না আপনি আপনার নোটগুলিকে \"অনুসারীদের জন্য\" হিসাবে সেট না করেন৷"
+alwaysMarkSensitive: "সর্বদা স্পর্শকাতর হিসাবে চিহ্নিত করুন"
+loadRawImages: "সংযুক্ত ছবির থাম্বনেইলটি দেখানর পরিবর্তে আসল ছবি দেখান"
+disableShowingAnimatedImages: "অ্যানিমেটেড চিত্র দেখানো বন্ধ করুন"
+verificationEmailSent: "নিশ্চিতকরণ ইমেল পাঠানো হয়েছে। সেটআপ সম্পূর্ণ করতে ইমেল এর লিঙ্ক অনুসরণ করুন।"
+notSet: "সেট করা হয়নি"
+emailVerified: "ইমেইল নিশ্চিত করা হয়েছে"
+noteFavoritesCount: "পছন্দ করা নোটের সংখ্যা"
+pageLikesCount: "পেজ লাইক করেছেন"
+pageLikedCount: "পেজ লাইক পেয়েছেন"
+contact: "পরিচিতি সমূহ"
+useSystemFont: "সিস্টেম ফন্ট ব্যাবহার করুন"
+clips: "ক্লিপগুলি "
+experimentalFeatures: "পরীক্ষামূলক বৈশিষ্ট্যগুলি"
+developer: "ডেভেলপার"
+makeExplorable: "অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় দেখান"
+makeExplorableDescription: "আপনি এটি বন্ধ করলে, আপনার অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় প্রদর্শিত হবে না।"
+showGapBetweenNotesInTimeline: "টাইমলাইন এবং নোটের মাঝে ফাকা জায়গা রাখুন"
+duplicate: "প্রতিরূপ"
+left: "বাম"
+center: "মাঝখান"
+wide: "চওড়া"
+narrow: "সংকীর্ণ"
+reloadToApplySetting: "পৃষ্ঠাটি রিলোড করার পর সেটিংসটি প্রয়োগ করা হবে। আপনি কি এখন রিলোড করতে চান?"
+needReloadToApply: "পৃষ্ঠাটি রিলোড করার পর সেটিংসটি প্রয়োগ করা হবে।"
+showTitlebar: "টাইটেল বার দেখান"
 clearCache: "ক্যাশ পরিষ্কার করুন"
+onlineUsersCount: "{n} জন ব্যাবহারকারী অনলাইন"
+nUsers: "{n} জন ব্যাবহারকারী"
+nNotes: "{n} টি নোট"
+sendErrorReports: "ক্রুটি প্রতিবেদন পাঠান"
+sendErrorReportsDescription: "চালু থাকলে, বিস্তারিত ত্রুটির তথ্য Misskey-এর সাথে শেয়ার করা হয়। যা সফ্টওয়্যারটির গুণমান উন্নত করতে সাহায্য করে। ত্রুটির তথ্যের মধ্যে রয়েছে OS সংস্করণ, ব্রাউজারের ধরন, কর্মের ইতিহাস ইত্যাদি।"
+myTheme: "আমার থিম"
+backgroundColor: "পটভূমির রং"
+accentColor: "এক্সেন্টের রং"
+textColor: "লেখার রং"
+saveAs: "এইরূপে সংরক্ষণ করুন"
+advanced: "উন্নত"
+value: "মান"
+createdAt: "তৈরি হয়েছে"
+updatedAt: "শেষ হালনাগাদ হয়েছে"
+saveConfirm: "পরিবর্তনগুলি সংরক্ষণ করতে চান?"
+deleteConfirm: "আসলেই মুছে ফেলতে চান?"
+invalidValue: "অগ্রহণযোগ্য মান"
+registry: "রেজিস্ট্রি"
+closeAccount: "অ্যাকাউন্ট বন্ধ করুন"
+currentVersion: "বর্তমান সংস্করণ"
+latestVersion: "সর্বশেষ সংস্করণ"
+youAreRunningUpToDateClient: "আপনি সবচেয়ে নতুন ক্লায়েন্ট ব্যাবহার করছেন"
+newVersionOfClientAvailable: "আপনার ক্লায়েন্টের একটি নতুন ভার্সন চলে এসেছে"
+usageAmount: "ব্যাবহার"
+capacity: "ধারণক্ষমতা"
+inUse: "ব্যবহৃত"
+editCode: "কোড সম্পাদনা করুন"
+apply: "প্রয়োগ করুন"
+receiveAnnouncementFromInstance: "এই ইন্সট্যান্স থেকে বিজ্ঞপ্তি পান"
+emailNotification: "ইমেইল বিজ্ঞপ্তি"
+publish: "প্রকাশ"
+inChannelSearch: "চ্যানেলে খুঁজুন"
+useReactionPickerForContextMenu: "রাইট ক্লিকের মাধ্যমে রিঅ্যাকশন পিকার খুলুন"
+typingUsers: "{users} লেখছে"
+jumpToSpecifiedDate: "একটি নির্দিষ্ট তারিখে যান"
+showingPastTimeline: "অতীতের টাইমলাইন দেখানো হচ্ছে"
+clear: "পরিষ্কার"
+markAllAsRead: "সব পঠিত হিসেবে চিহ্নিত করুন"
+goBack: "পিছনে"
+unlikeConfirm: "আসলেই লাইক সরিয়ে নিবেন?"
+fullView: "ফুল ভিউ"
+quitFullView: "ফুল ভিউ বন্ধ করুন"
+addDescription: "বর্ণনা যোগ করুন"
+userPagePinTip: "আপনি প্রতিটি নোটের জন্য মেনু থেকে \"প্রোফাইলে পিন করুন\" নির্বাচন করে আপনার নোটগুলি এখানে প্রদর্শন করতে পারেন।"
+notSpecifiedMentionWarning: "প্রাপক ছাড়াও এই নোটে অন্য ব্যাবহারকারীদের উল্লেখ্য করা হয়েছে"
 info: "আপনার সম্পর্কে"
+userInfo: "ব্যবহারকারীর তথ্য"
+unknown: "অজানা"
+onlineStatus: "অনলাইন স্ট্যাটাস"
+hideOnlineStatus: "অনলাইন স্ট্যাটাস লুকান"
+hideOnlineStatusDescription: "অনলাইন স্ট্যাটাস লুকিয়ে রাখলে সার্চের মতো কিছু ফাংশনের সুবিধা কমে যায়।"
+online: "অনলাইন"
+active: "অ্যাকটিভ"
+offline: "অফলাইন"
+notRecommended: "সুপারিশ করা হয় না"
+botProtection: "বট প্রোটেকশন"
+instanceBlocking: "ব্লক করা ইন্সট্যান্সগুলি"
+selectAccount: "অ্যাকাউন্ট নির্বাচন"
+switchAccount: "অ্যাকাউন্ট পাল্টান"
+enabled: "চালু"
+disabled: "বন্ধ"
+quickAction: "কুইক অ্যাকশন"
 user: "ব্যবহারকারীগণ"
+administration: "পরিচালনা"
+accounts: "অ্যাকাউন্টগুলি"
+switch: "পাল্টান"
+noMaintainerInformationWarning: "প্রশাসকের তথ্য সেট করা হয়নি।"
+noBotProtectionWarning: "বট প্রোটেকশন সেট করা হয়নি।"
+configure: "কনফিগার করুন"
+postToGallery: "গ্যালারী পোস্ট তৈরি করুন"
+gallery: "গ্যালারী"
+recentPosts: "নতুন পোস্ট"
+popularPosts: "জনপ্রিয় পোস্ট"
+shareWithNote: "নোটের মাধ্যমে শেয়ার করুন"
+ads: "বিজ্ঞাপন"
+expiration: "নির্দিষ্ট সময়সীমা"
+memo: "মেমো"
+priority: "অগ্রাধিকার"
+high: "উচ্চ"
+middle: "মাঝারি"
+low: "নিম্ন"
+emailNotConfiguredWarning: "ইমেইল অ্যাড্রেস সেট করা হয়নি।"
+ratio: "অনুপাত"
+previewNoteText: "প্রিভিউ দেখান"
+customCss: "কাস্টম CSS"
+customCssWarn: "এই ব্যাপারে অভিজ্ঞতা না থাকলে এই সেটিংটি ব্যাবহার করবেন না। অনুপযুক্ত সেটিংস ক্লায়েন্টকে স্বাভাবিকভাবে ব্যবহার করতে বাধা দিতে পারে।"
+global: "গ্লোবাল"
+squareAvatars: "চারকোনা প্রোফাইল পিকচার দেখান "
+sent: "পাঠান"
+received: "প্রাপ্ত"
+searchResult: "অনুসন্ধানের ফলাফল"
+hashtags: "হ্যাশট্যাগ"
+troubleshooting: "ট্রাবলশুটিং"
+useBlurEffect: "UI তে ব্লার ইফেক্ট ব্যাবহার করুন"
+learnMore: "আরও জানুন"
+misskeyUpdated: "Misskey আপডেট করা হয়েছে!"
+whatIsNew: "পরিবর্তনগুলি দেখান"
+translate: "অনুবাদ"
+translatedFrom: "{x} হতে অনুবাদ করা"
+accountDeletionInProgress: "অ্যাকাউন্ট মুছে ফেলা হচ্ছে"
+usernameInfo: "একটি নাম যা সার্ভারে আপনার অ্যাকাউন্টটিকে অনন্যভাবে সনাক্ত করে। আপনি বর্ণমালা (a ~ z, A ~ Z), সংখ্যা (0 ~ 9), এবং আন্ডারস্কোর (_) ব্যবহার করতে পারেন। ব্যবহারকারীর নাম পরে পরিবর্তন করা যাবে না।"
+aiChanMode: "Ai মোড"
+keepCw: "CW রাখুন"
+pubSub: "Pub/Sub অ্যাকাউন্টগুলো"
+lastCommunication: "শেষ যোগাযোগ"
+resolved: "সমাধান হয়েছে"
+unresolved: "সমাধান হয়নি"
+breakFollow: "অনুসরণ করা বন্ধ"
+itsOn: "চালু"
+itsOff: "বন্ধ"
+emailRequiredForSignup: "অ্যাকাউন্ট তৈরির জন্য ইমেইল এর দরকার পড়বে"
+unread: "অপঠিত"
+filter: "ফিল্টার"
 controlPanel: "নিয়ন্ত্রন কেন্দ্র"
+manageAccounts: "অ্যাকাউন্টগুলি পরিচালনা করুন"
+makeReactionsPublic: "রিঅ্যাকশনের ইতিহাস উন্মুক্ত করুন"
+makeReactionsPublicDescription: "আপনার পূর্ববর্তী রিঅ্যাকশনগুলির তালিকা যে কারও কাছে দৃশ্যমান হবে।"
+classic: "ক্লাসিক"
+muteThread: "থ্রেড মিউট করুন"
+unmuteThread: "থ্রেড আনমিউট করুন"
+ffVisibility: "অনুসরণ/অনুসরণকারীদের দৃশ্যমান্যতা"
+ffVisibilityDescription: "আপনি কাকে অনুসরণ করেন এবং কে আপনাকে অনুসরণ করে, সেটা কারা দেখতে পাবে তা নির্ধারণ করে।"
+continueThread: "আরো থ্রেড দেখুন"
+deleteAccountConfirm: "আপনার অ্যাকাউন্ট মুছে ফেলা হবে। ঠিক আছে?"
+incorrectPassword: "আপনার দেওয়া পাসওয়ার্ডটি ভুল।"
+voteConfirm: "\"{choice}\" এ ভোট দিতে চান?"
+hide: "লুকান"
+leaveGroup: "গ্রুপ ছেড়ে চলে যান"
+leaveGroupConfirm: "\"{name}\" গ্রুপ ছেড়ে চলে যেতে চান?"
+useDrawerReactionPickerForMobile: "মোবাইলে রিঅ্যাকশন পিকারকে ড্রয়ারে প্রদর্শন করুন"
+welcomeBackWithName: "আবার স্বাগতম, {name}"
+clickToFinishEmailVerification: " [{ok}] ক্লিক করার মাধ্যমে আপনার ইমেল ঠিকানা নিশ্চিত করুন।"
+_emailUnavailable:
+  used: "এই ইমেইল ঠিকানাটি ইতোমধ্যে ব্যবহৃত হয়েছে"
+  format: "এই ইমেল ঠিকানাটি সঠিকভাবে লিখা হয়নি"
+  disposable: "অস্থায়ী ইমেইল ঠিকানা ব্যাবহার করা যাবে না"
+  mx: "ইমেইল ​​সার্ভারটি ঠিক নাই"
+  smtp: "ইমেইল সার্ভারটি সাড়া দিচ্ছে না"
+_ffVisibility:
+  public: "প্রকাশ"
+  followers: "শুধুমাত্র অনুসরণকারীদের কাছে দৃশ্যমান"
+  private: "ব্যাক্তিগত"
+_signup:
+  almostThere: "প্রায় শেষ"
+  emailAddressInfo: "আপনি যে ইমেল ঠিকানাটি ব্যবহার করবেন সেটি লিখুন। আপনার ইমেইল ঠিকানা প্রকাশ করা হবে না।"
+  emailSent: "আপনার দেওয়া ইমেল ঠিকানায় ({email}) একটি নিশ্চিতকরণ ইমেল পাঠানো হয়েছে। অ্যাকাউন্ট তৈরি সম্পূর্ণ করতে ইমেলের লিঙ্কটি অ্যাক্সেস করুন।"
+_accountDelete:
+  accountDelete: "অ্যাকাউন্ট মুছে ফেলুন"
+  mayTakeTime: "একটি অ্যাকাউন্ট মুছে ফেলা একটি দীর্ঘ প্রক্রিয়া এবং আপনি যদি প্রচুর পরিমাণে সামগ্রী তৈরি করে থাকেন বা ফাইল আপলোড করেন তবে এটি সম্পূর্ণ হতে দীর্ঘ সময় নিতে পারে।"
+  sendEmail: "অ্যাকাউন্ট মুছে ফেলা সম্পূর্ণ হলে, নিবন্ধিত ইমেল ঠিকানায় একটি বিজ্ঞপ্তি পাঠানো হবে।"
+  requestAccountDelete: "অ্যাকাউন্ট মুছে ফেলার অনুরোধ করুন"
+  started: "মুছে ফেলার প্রক্রিয়া শুরু হয়েছে।"
+  inProgress: "মুছে ফেলার কাজ চলছে"
+_ad:
+  back: "পিছনে"
+  reduceFrequencyOfThisAd: "এই বিজ্ঞাপনটি কম দেখান"
+_forgotPassword:
+  enterEmail: "আপনি আপনার অ্যাকাউন্টের জন্য নিবন্ধিত ইমেল ঠিকানা লিখুন. সেই ঠিকানায় একটি পাসওয়ার্ড রিসেট লিঙ্ক পাঠানো হবে।"
+  ifNoEmail: "আপনি যদি নিবন্ধনের সময় ই-মেইল ঠিকানা না দিয়ে থাকেন, তাহলে অনুগ্রহ করে প্রশাসকের সাথে যোগাযোগ করুন।"
+  contactAdmin: "এই ইন্সট্যান্সটি ইমেইল ব্যাবহার করে না, তাই আপনার পাসওয়ার্ড পুনরায় সেট করতে প্রশাসকের সাথে যোগাযোগ করুন৷"
+_gallery:
+  my: "আমার গ্যালারী"
+  liked: "পছন্দ করা পোস্ট"
+  like: "পছন্দ করা"
+  unlike: "পছন্দ সরান"
 _email:
   _follow:
     title: "আপনাকে অনুসরণ করছে"
+  _receiveFollowRequest:
+    title: "অনুসরণ করার অনুরোধ পেয়েছেন"
+_plugin:
+  install: "প্লাগইন ইন্সটল করুন"
+  installWarn: "অবিশ্বস্ত প্লাগইন ইনস্টল করবেন না।"
+  manage: "প্লাগইন ম্যানেজ করুন"
+_registry:
+  scope: "স্কোপ"
+  key: "কী"
+  keys: "কী - সমূহ"
+  domain: "ডোমেন"
+  createKey: "কী বানান"
+_aboutMisskey:
+  about: "Misskey, একটি ওপেন সোর্স সফ্টওয়্যার যা 2014 সাল থেকে syuilo তৈরি করছেন।"
+  contributors: "প্রধান কন্ট্রিবিউটারগণ"
+  allContributors: "সকল কন্ট্রিবিউটারগণ"
+  source: "সোর্স কোড"
+  translation: "Misskey অনুবাদ করুন"
+  donate: "Misskey তে দান করুন"
+  morePatrons: "আরও অনেকে আমাদের সাহায্য করছেন। তাদের সবাইকে ধন্যবাদ 🥰"
+  patrons: "সমর্থনকারী"
+_nsfw:
+  respect: "স্পর্শকাতর মিডিয়া লুকান"
+  ignore: "স্পর্শকাতর মিডিয়া লুকাবেন না"
+  force: "সকল মিডিয়া লুকান"
 _mfm:
+  cheatSheet: "MFM চিটশিট"
+  intro: "MFM একটি মার্কআপ ভাষা যা Misskey-এর মধ্যে বিভিন্ন জায়গায় ব্যবহার করা যেতে পারে। এখানে আপনি MFM-এর সিনট্যাক্সগুলির একটি তালিকা দেখতে পারবেন।"
+  dummy: "মিসকি ফেডিভার্সের বিশ্বকে প্রসারিত করে"
   mention: "উল্লেখ"
+  mentionDescription: "@ চিহ্ন + ব্যবহারকারীর নাম একটি নির্দিষ্ট ব্যবহারকারীকে নির্দেশ করতে ব্যবহার করা যায়।"
+  hashtag: "হ্যাশট্যাগ"
+  hashtagDescription: "আপনি একটি # চিহ্ন + ট্যাগ সহ একটি হ্যাশট্যাগ নির্দেশ করতে পারেন।"
+  url: "URL"
+  urlDescription: "URL দেখানো সম্ভব।"
+  link: "লিংক"
+  linkDescription: "আপনি পাঠ্যের একটি নির্দিষ্ট অংশকে URL হিসাবে দেখাতে পারেন৷"
+  bold: "গাঢ়"
+  boldDescription: "অক্ষরগুলিকে মোটাকরে প্রদর্শন করা হবে।"
+  small: "ছোট"
+  smallDescription: "লেখা ছোট এবং পাতলা করে দেখানো হবে।"
+  center: "সেন্টার"
+  centerDescription: "লেখা মাঝ বরাবর দেখানো হবে"
+  inlineCode: "কোড (ইনলাইন)"
+  inlineCodeDescription: " প্রোগ্রামের কোডের জন্য ইনলাইন সিনট্যাক্স হাইলাইটিং করা হবে"
+  blockCode: "কোড (ব্লক)"
+  blockCodeDescription: "মাল্টি-লাইন প্রোগ্রামের কোডের জন্য সিনট্যাক্স হাইলাইট করে।"
+  inlineMath: "গাণিতিক সূত্র (ইনলাইন)"
+  inlineMathDescription: "গাণিতিক সূত্র প্রদর্শন করুন (KaTeX) ইনলাইন।"
+  blockMath: "গাণিতিক সূত্র (ব্লক)"
+  blockMathDescription: "একটি ব্লকে একাধিক লাইনের গাণিতিক সূত্র প্রদর্শন করুন (KaTeX)।"
   quote: "উদ্ধৃতি"
+  quoteDescription: "বিষয়বস্তুকে একটি উদ্ধৃতি হিসাবে দেখানো হবে।"
   emoji: "স্বনির্ধারিত ইমোজিগুলি"
+  emojiDescription: "আপনি একটি কাস্টম ইমোজির নাম কোলনে আবদ্ধ করে কাস্টম ইমোজিটি দেখাতে পারেন৷"
   search: "খুঁজুন"
+  searchDescription: "পূর্ব-টাইপ করা পাঠ্য সহ একটি অনুসন্ধান বাক্স প্রদর্শন করে।"
+  flip: "উল্টান"
+  flipDescription: "বিষয়বস্তু উপরে/নীচে বা বাম/ডানে উল্টান।"
+  jelly: "অ্যানিমেশন (জেলি)"
+  jellyDescription: "জেলির মত অ্যানিমেশন দেখায়।"
+  tada: "অ্যানিমেশন (টাডা)"
+  tadaDescription: "\"টাডা!\" এর মত অ্যানিমেশন দেখায়।"
+  jump: "অ্যানিমেশন (লাফ)"
+  jumpDescription: "বিষয়বস্তুতে লাফ মারার মত অ্যানিমেশন দেখায়।"
+  bounce: "অ্যানিমেশন (তিড়িং বিড়িং)"
+  bounceDescription: "তিড়িং বিড়িং করার মত অ্যানিমেশন দেখায়।"
+  shake: "অ্যানিমেশন (ঝাঁকি)"
+  shakeDescription: "ঝাঁকির মত অ্যানিমেশন দেখায়।"
+  twitch: "অ্যানিমেশন (মোচড়ানো)"
+  twitchDescription: "মোচড়ানোর মত অ্যানিমেশন দেখায়।"
+  spin: "অ্যানিমেশন (ঘুরা)"
+  spinDescription: "ঘুরার মত অ্যানিমেশন দেখায়।"
+  x2: "বড়"
+  x2Description: "বিষয়বস্তু বড় করে দেখায়।"
+  x3: "অনেক বড়"
+  x3Description: "বিষয়বস্তু আরও বড় করে দেখায়।"
+  x4: "অস্বাভাবিক বড়"
+  x4Description: "বিষয়বস্তুকে আগের থেকেও আরও বড় করে দেখায়।"
+  blur: "ব্লার"
+  blurDescription: "বিষয়বস্তুকে ব্লার করতে পারেন। আপনি এর উপর মাউস কার্সার রাখলে, এটি পরিষ্কারভাবে দেখতে পাবেন।"
+  font: "ফন্ট"
+  fontDescription: "বিষয়বস্তুকে কোন ফন্টে দেখানো হবে তা নির্ধারণ করে।"
+  rainbow: "রেইনবো"
+  rainbowDescription: "বিষয়বস্তুকে রংধনুর রং গুলিতে প্রদর্শন করে।"
+  sparkle: "চিক চিক"
+  sparkleDescription: "বিষয়বস্তুকে একটি চিকচিকে কণা প্রভাব দেয়।"
+  rotate: "ঘুরান"
+  rotateDescription: "বিষয়বস্তুকে একটি নির্দিষ্ট কোনে ঘুরায়।"
+_instanceTicker:
+  none: "দেখাবেন না"
+  remote: "রিমোট ব্যাবহারকারীদের জন্য দেখান"
+  always: "সর্বদা দেখান"
+_serverDisconnectedBehavior:
+  reload: "স্বয়ংক্রিয়ভাবে রিলোড"
+  dialog: "সতর্কতা ডায়ালগ দেখান"
+  quiet: "অগচরী সতর্কতা দেখান"
+_channel:
+  create: "চ্যানেল বানান"
+  edit: "চ্যানেল সম্পাদনা করুন"
+  setBanner: "ব্যানার সেট করুন"
+  removeBanner: "ব্যানার সরান"
+  featured: "বর্তমানে জনপ্রিয়"
+  owned: "নিজের"
+  following: "অনুসরণ করা হচ্ছে"
+  usersCount: "{n} জন অংশগ্রহণকারী"
+  notesCount: "{n} টি নোট"
+_menuDisplay:
+  sideFull: "পাশে"
+  sideIcon: "পাশে (আইকন)"
+  top: "শীর্ষে"
+  hide: "লুকান"
+_wordMute:
+  muteWords: "নিঃশব্দ করা শব্দগুলি"
+  muteWordsDescription: "স্পেস দিয়ে আলাদা করলে AND শর্ত তৈরি হবে এবং আলাদা লাইনে লিখলে OR শর্ত তৈরি হবে।"
+  muteWordsDescription2: "রেগুলার এক্সপ্রেশন ব্যবহার করতে স্ল্যাশ দিয়ে কীওয়ার্ডকে ঘিরে রাখুন।"
+  softDescription: "টাইমলাইন থেকে নির্দিষ্ট শর্তানুযায়ী নোট লুকিয়ে রাখে।"
+  hardDescription: "নির্দিষ্ট শর্তানুযায়ী নোটগুলিকে টাইমলাইন থেকে বাদ দেয়। আপনি শর্ত পরিবর্তন করলেও যে নোটগুলি যোগ করা হয়নি সেগুলি বাদ দেওয়া হবে।"
+  soft: "নমনীয়"
+  hard: "কঠোর"
+  mutedNotes: "মিউট করা নোটগুলি"
+_instanceMute:
+  instanceMuteDescription: "কনফিগার করা ইন্সট্যান্সের সব নোট এবং রিনোট মিউট করুন, মিউট করা ইন্সট্যান্সের ব্যবহারকারীদের উত্তর সহ।"
+  instanceMuteDescription2: "প্রতিটিকে আলাদা লাইনে লিখুন"
+  title: "কনফিগার করা ইন্সট্যান্সের নোটগুলিকে লুকিয়ে রাখে।"
+  heading: "মিউট করা ইন্সত্যান্সের তালিকা"
 _theme:
+  explore: "থিমগুলি ঘুরে দেখুন"
+  install: "থিম ইনস্টল করুন"
+  manage: "থিম ব্যাবস্থাপনা"
+  code: "থিম কোড"
+  description: "বর্ণনা"
+  installed: "{name} ইন্সটল করা হয়েছে"
+  installedThemes: "ইন্সটল করা থিমসমূহ"
+  builtinThemes: "বিল্ট-ইন থিমসমূহ"
+  alreadyInstalled: "এই থিমটি ইতিমধ্যে ইন্সটল করা হয়েছে"
+  invalid: "থিমটির ফরম্যাট সঠিক নয়"
+  make: "থিম বানান"
+  base: "বেস"
+  addConstant: "ধ্রুবক যোগ করুন"
+  constant: "ধ্রুবক"
+  defaultValue: "ডিফল্ট মান"
+  color: "রং"
+  refProp: "প্রোপার্টি রেফারেন্স করুন"
+  refConst: "ধ্রুবক রেফারেন্স করুন"
+  key: "কী"
+  func: "ফাংশন"
+  funcKind: "ফাংশনের ধরন"
+  argument: "আর্গুমেন্ট"
+  basedProp: "রেফারেন্স করা প্রোপার্টি"
+  alpha: "অস্বচ্ছতা"
+  darken: "অন্ধকার করুন"
+  lighten: "উজ্জ্বল করুন"
+  inputConstantName: "ধ্রুবকটির নাম লিখুন"
+  importInfo: "আপনি এখানে থিম কোড পেস্ট করতে পারেন এবং সেটিকে এডিটরে ইম্পোর্ট করতে পারেন"
+  deleteConstantConfirm: "আপনি কি ধ্রুবক {const} মুছে ফেলতে চান?"
   keys:
+    accent: "অ্যাকসেন্ট"
+    bg: "পটভূমি"
+    fg: "লেখা"
+    focus: "ফোকাস"
+    indicator: "ইনডিকেটর"
+    panel: "প্যানেল"
+    shadow: "ছায়া"
+    header: "হেডার"
+    navBg: "সাইডবারের পটভূমি"
+    navFg: "সাইডবারের পাঠ্য"
+    navHoverFg: "সাইডবারের পাঠ্য (হভার)"
+    navActive: "সাইডবারের পাঠ্য (অ্যাকটিভ)"
+    navIndicator: "সাইডবারের ইনডিকেটর"
+    link: "লিংক"
+    hashtag: "হ্যাশট্যাগ"
     mention: "উল্লেখ"
+    mentionMe: "আপনাকে উল্লেখ্য করা"
     renote: "রিনোট"
+    modalBg: "মোডালের পটভূমি"
+    divider: "খন্ডক"
+    scrollbarHandle: "স্ক্রলবার হ্যান্ডেল"
+    scrollbarHandleHover: "স্ক্রলবার হ্যান্ডেল (হভার)"
+    dateLabelFg: "তারিখ লেবেলের পাঠ্য"
+    infoBg: "তথ্যের পটভূমি"
+    infoFg: "তথ্যের পাঠ্য"
+    infoWarnBg: "ওয়ার্নিং এর পটভূমি"
+    infoWarnFg: "ওয়ার্নিং এর পাঠ্য"
+    cwBg: "CW বাটনের পটভূমি"
+    cwFg: "CW বাটনের পাঠ্য"
+    cwHoverBg: "CW বাটনের পটভূমি (হভার)"
+    toastBg: "বিজ্ঞপ্তির পটভূমি"
+    toastFg: "বিজ্ঞপ্তির পাঠ্য"
+    buttonBg: "বাটনের পটভূমি"
+    buttonHoverBg: "বাটনের পটভূমি (হভার)"
+    inputBorder: "ইনপুট ফিল্ডের বর্ডার"
+    listItemHoverBg: "লিস্ট আইটেমের পটভূমি (হোভার)"
+    driveFolderBg: "ড্রাইভ ফোল্ডারের পটভূমি"
+    wallpaperOverlay: "ওয়ালপেপার ওভারলে"
+    badge: "ব্যাজ"
+    messageBg: "চ্যাটের পটভূমি"
+    accentDarken: "অ্যাকসেন্ট (গাঢ়)"
+    accentLighten: "অ্যাকসেন্ট (হাল্কা)"
+    fgHighlighted: "হাইলাইট করা পাঠ্য"
 _sfx:
   note: "নোটগুলি"
+  noteMy: "নোট (আপনার)"
   notification: "বিজ্ঞপ্তি"
   chat: "চ্যাট"
+  chatBg: "চ্যাট (ব্যাকগ্রাউন্ড)"
+  antenna: "অ্যান্টেনাগুলি"
+  channel: "চ্যানেলের বিজ্ঞপ্তি"
+_ago:
+  unknown: "অজানা"
+  future: "ভবিষ্যৎ"
+  justNow: "এইমাত্র"
+  secondsAgo: "{n} সেকেন্ড আগে"
+  minutesAgo: "{n} মিনিট আগে"
+  hoursAgo: "{n} ঘণ্টা আগে"
+  daysAgo: "{n} দিন আগে"
+  weeksAgo: "{n} সপ্তাহ আগে"
+  monthsAgo: "{n} মাস আগে"
+  yearsAgo: "{n} বছর আগে"
+_time:
+  second: "সেকেন্ড"
+  minute: "মিনিট"
+  hour: "ঘণ্টা"
+  day: "দিন"
+_tutorial:
+  title: "Misskey কিভাবে ব্যাবহার করবেন"
+  step1_1: "স্বাগতম!"
+  step1_2: "এই স্ক্রীনটিকে \"টাইমলাইন\" বলা হয় এবং কালানুক্রমিক ক্রমে আপনার এবং আপনি যাদের \"অনুসরণ করেন\" তাদের \"নোটগুলি\" দেখায়৷"
+  step1_3: "আপনি আপনার টাইমলাইনে কিছু দেখতে পাবেন না কারণ আপনি এখনও কোনো নোট পোস্ট করেননি এবং আপনি কাউকে অনুসরণ করছেন না৷"
+  step2_1: "নোট তৈরি করার আগে বা কাউকে অনুসরণ করার আগে প্রথমে আপনার প্রোফাইলটি সম্পূর্ণ করুন।"
+  step2_2: "আপনি কে তা জানা অনেক লোকের জন্য আপনার নোটগুলি দেখা এবং অনুসরণ করাকে সহজ করে তোলে৷"
+  step3_1: "আপনি কি সফলভাবে আপনার প্রোফাইল সেট আপ করেছেন?"
+  step3_2: "এখন, কিছু নোট পোস্ট করার চেষ্টা করুন। পোস্ট ফর্ম খুলতে পেন্সিল চিহ্নযুক্ত বাটনে ক্লিক করুন।"
+  step3_3: "বিষয়বস্তু লেখার পরে, আপনি ফর্মের উপরের ডানদিকের বাটনে ক্লিক করে পোস্ট করতে পারেন।"
+  step3_4: "পোস্ট করার মত কিছু মনে পরছে না? \"আমি মিসকি সেট আপ করছি\" বললে কেমন হয়?"
+  step4_1: "পোস্ট করেছেন?"
+  step4_2: "সাবাশ! এখন আপনার নোট টাইমলাইনে দেখা যাবে।"
+  step5_1: "এখন অন্যদেরকে অনুসরণ করে আপনার টাইমলাইনকে প্রাণবন্ত করে তুলুন।"
+  step5_2: "আপনি {featured}-এ জনপ্রিয় নোটগুলি দেখতে পারেন, যাতে আপনি যে ব্যক্তিকে পছন্দ করেন তাকে বেছে নিতে এবং অনুসরণ করতে পারেন, অথবা {explore}-এ জনপ্রিয় ব্যবহারকারীদের দেখতে পারেন৷"
+  step5_3: "একজন ব্যবহারকারীকে অনুসরণ করতে, ব্যবহারকারীর আইকনে ক্লিক করুন এবং ব্যবহারকারীর পৃষ্ঠাতে  \"অনুসরণ করুন\" বাটনে ক্লিক করুন।"
+  step5_4: "যদি ব্যবহারকারীর নামের পাশে একটি লক আইকন থাকে তাহলে আপনার অনুসরণের অনুরোধ গ্রহণ করার জন্য তারা কিছু সময় নিতে পারে।"
+  step6_1: "সবকিছু ঠিক থাকলে আপনি টাইমলাইনে অন্য ব্যবহারকারীদের নোট দেখতে পাবেন।"
+  step6_2: "আপনি সহজেই আপনার প্রতিক্রিয়া জানাতে অন্য ব্যক্তির নোটে \"রিঅ্যাকশন\" যোগ করতে পারেন।"
+  step6_3: "একটি রিঅ্যাকশন যোগ করতে, নোটে \"+\" চিহ্নে ক্লিক করুন এবং আপনার পছন্দের রিঅ্যাকশন নির্বাচন করুন।"
+  step7_1: "অভিনন্দন! আপনি এখন Misskey-র প্রাথমিক টিউটোরিয়ালটি শেষ করেছেন।"
+  step7_2: "আপনি যদি Misskey সম্পর্কে আরও জানতে চান, তাহলে {help} এ দেখুন।"
+  step7_3: "এখন Misskey উপভোগ করুন 🚀"
+_2fa:
+  alreadyRegistered: "আপনি ইতিমধ্যে একটি 2-ফ্যাক্টর অথেনটিকেশন ডিভাইস নিবন্ধন করেছেন৷"
+  registerDevice: "নতুন ডিভাইস নিবন্ধন করুন"
+  registerKey: "সিকিউরিটি কী নিবন্ধন করুন"
+  step1: "প্রথমে, আপনার ডিভাইসে {a} বা {b} এর মতো একটি অথেনটিকেশন অ্যাপ ইনস্টল করুন৷"
+_permissions:
+  "read:pages": "আপনার পেজগুলি দেখুন"
+  "write:pages": "পেজগুলি সম্পাদনা বা ডিলিট করুন"
+_auth:
+  pleaseGoBack: "দয়া করে অ্যাপ্লিকেশনে ফিরে যান"
+  callback: "অ্যাপ্লিকেশনে ফিরে যাচ্ছি"
+  denied: "প্রবেশ নিষেধ"
+_antennaSources:
+  all: "সকল নোট"
+  homeTimeline: "আপনি অনুসরণ করছেন, এমন ব্যবহারকারীদের নোট"
+  users: "এক বা একাধিক নির্দিষ্ট ব্যবহারকারীর নোট"
+  userList: "নির্দিষ্ট তালিকায় নাম থাকা ব্যবহারকারীদের নোট"
+  userGroup: "নির্দিষ্ট গ্রুপে থাকা ব্যবহারকারীদের নোট"
+_weekday:
+  sunday: "রবিবার"
+  monday: "সোমবার"
+  tuesday: "মঙ্গলবার"
+  wednesday: "বুধবার"
+  thursday: "বৃহস্পতিবার"
+  friday: "শুক্রবার"
+  saturday: "শনিবার"
 _widgets:
+  memo: "স্টিকি নোট"
   notifications: "বিজ্ঞপ্তি"
   timeline: "টাইমলাইন"
+  calendar: "ক্যালেন্ডার"
+  trends: "বর্তমানে জনপ্রিয়"
+  clock: "ঘড়ি"
+  rss: "RSS রিডার"
   activity: "কার্যকলাপ"
+  photos: "ফটোগুলি"
+  digitalClock: "ডিজিটাল ঘড়ি"
   federation: "ফেডিভার্স"
+  postForm: "নোট লিখুন"
+  slideshow: "স্লাইডশো"
+  button: "বাটন"
+  onlineUsers: "অনলাইনে থাকা ব্যবহারকারীগণ"
   jobQueue: "জব কিউ"
+  serverMetric: "সার্ভার মেট্রিক্স"
+  aiscript: "AiScript কনসোল"
+  aichan: "আই চান"
 _cw:
+  hide: "লুকান"
   show: "আরও দেখুন"
+  chars: "{count} টি অক্ষর"
+  files: "{count} টি ফাইল"
+_poll:
+  noOnlyOneChoice: "সর্বনিম্ন 2 টি অপশন বেছে নিতে হবে"
+  choiceN: "বিকল্পগুলি {n}"
+  noMore: "আপনি আর কোন বিকল্প যোগ করতে পারবেন না"
+  canMultipleVote: "একাধিক বিকল্প বাছাই করা যাবে"
+  expiration: "পোলের সময়সীমা"
+  infinite: "অনির্দিষ্ট"
+  at: "শেষ হবে"
+  after: "শেষ হবে"
+  deadlineDate: "শেষ হওয়ার তারিখ"
+  deadlineTime: "ঘণ্টা"
+  duration: "ব্যাপ্তিকাল"
+  votesCount: "{n} টি ভোট"
+  totalVotes: "সর্বমোট {n} টি ভোট"
+  vote: "ভোট দিন"
+  showResult: "রেজাল্ট দেখান"
+  voted: "ভোট দিয়েছেন"
+  closed: "শেষ হয়ে গেছে"
+  remainingDays: "আর {d} দিন {h} ঘণ্টা বাকি আছে"
+  remainingHours: "আর {h} ঘণ্টা {m} মিনিট বাকি আছে"
 _visibility:
   home: "মূল পাতা"
   followers: "অনুসরণকারী"
@@ -466,13 +1185,17 @@ _profile:
   name: "নাম"
   username: "ব্যবহারকারীর নাম"
 _exportOrImport:
+  allNotes: "সকল নোট"
   followingList: "অনুসরণ করা হচ্ছে"
   muteList: "মিউট"
   blockingList: "ব্লক"
   userLists: "লিস্ট"
+_charts:
+  federation: "ফেডিভার্স"
 _timelines:
   home: "মূল পাতা"
 _pages:
+  viewPage: "আপনার পেজগুলি দেখুন"
   blocks:
     image: "ছবি"
   script:
@@ -483,6 +1206,12 @@ _pages:
         arg1: "লিস্ট"
       _randomPick:
         arg1: "লিস্ট"
+      _dailyRandom:
+        arg1: "সম্ভাব্যতা"
+      dailyRannum: "র‍্যান্ডম সংখ্যা (প্রতিটি ব্যবহারকারীর জন্য প্রতিদিন পরিবর্তীত হয়)"
+      _dailyRannum:
+        arg1: "ন্যূনতম মান"
+        arg2: "সর্বোচ্চ মান"
       _dailyRandomPick:
         arg1: "লিস্ট"
       _seedRandomPick:
@@ -491,20 +1220,83 @@ _pages:
         arg1: "লিস্ট"
       _listLen:
         arg1: "লিস্ট"
+      _numberToString:
+        arg1: "সংখ্যা"
+      splitStrByLine: "পাঠ্যকে লাইনে বিভক্ত করুন"
+      _splitStrByLine:
+        arg1: "লেখা"
+      ref: "চলক"
+      aiScriptVar: "AiScript চলক"
+      fn: "ফাংশন"
+      _fn:
+        slots: "স্লটগুলি"
+        slots-info: "প্রতিটি স্লটকে আলাদা লাইনে লিখুন"
+        arg1: "আউটপুট"
+      for: "for-লুপ"
+      _for:
+        arg1: "কতবার চলবে"
+        arg2: "অ্যাকশন"
+    typeError: "স্লট {slot}, {expect} ধরনের মান গ্রহণ করে, কিন্তু {actual} ধরনের মান দেওয়া হয়েছে!"
+    thereIsEmptySlot: "স্লট {slot} খালি!"
     types:
+      string: "লেখা"
+      number: "সংখ্যা"
+      boolean: "ফ্ল্যাগ"
       array: "লিস্ট"
+      stringArray: "লেখার লিস্ট"
+    emptySlot: "খালি স্লট"
+    enviromentVariables: "এনভাইরনমেন্ট ভ্যারিয়েবল"
+    pageVariables: "পেজের চলক"
+    argVariables: "ইনপুটের জায়গা"
+_relayStatus:
+  requesting: "অপেক্ষমান"
+  accepted: "অনুমোদিত"
+  rejected: "প্রত্যাখিত"
 _notification:
+  fileUploaded: "ফাইল সফলভাবে আপলোড করা হয়েছে"
+  youGotMention: "{name} আপনাকে উল্লেখ্য করেছে"
+  youGotReply: "{name} আপনাকে জবাব দিয়েছে"
+  youGotQuote: "{name} আপনাকে উদ্ধৃত করেছে"
+  youRenoted: "{name} এর Renote"
+  youGotPoll: "{name} আপনার পোলে ভোট দিয়েছে"
+  youGotMessagingMessageFromUser: "{name} আপনাকে মেসেজ করেছে"
+  youGotMessagingMessageFromGroup: "{name} গ্রুপে একটি নতুন মেসেজ আছে"
   youWereFollowed: "আপনাকে অনুসরণ করছে"
+  youReceivedFollowRequest: "অনুসরণ করার জন্য অনুরোধ পাওয়া গেছে"
+  yourFollowRequestAccepted: "আপনার অনুসরণ করার অনুরোধ গৃহীত হয়েছে"
+  youWereInvitedToGroup: "আপনি একটি গ্রুপে আমন্ত্রিত হয়েছেন"
   _types:
+    all: "সকল"
     follow: "অনুসরণ করা হচ্ছে"
     mention: "উল্লেখ"
+    reply: "উত্তর দিন"
     renote: "রিনোট"
     quote: "উদ্ধৃতি"
     reaction: "প্রতিক্রিয়া"
+    pollVote: "পোলে ভোট আছে"
+    receiveFollowRequest: "প্রাপ্ত অনুসরণের অনুরোধসমূহ"
+    followRequestAccepted: "গৃহীত অনুসরণের অনুরোধসমূহ"
+    groupInvited: "গ্রুপের আমন্ত্রনসমূহ"
+    app: "লিঙ্ক করা অ্যাপ থেকে বিজ্ঞপ্তি"
 _deck:
+  alwaysShowMainColumn: "সর্বদা মেইন কলাম দেখান"
+  columnAlign: "কলাম সাজান"
+  columnMargin: "কলামের মধ্যবর্তী মার্জিন"
+  columnHeaderHeight: "কলামের হেডারের উচ্চতা"
+  addColumn: "কলাম যুক্ত করুন"
+  swapLeft: "বামে সরান"
+  swapRight: "ডানে সরান"
+  swapUp: "উপরে উঠান"
+  swapDown: "নিচে নামান"
+  stackLeft: "বাম কলামে সাজান"
+  popRight: "ডানদিকে রাখুন"
+  profile: "প্রোফাইল"
   _columns:
+    main: "প্রধান"
+    widgets: "উইজেটগুলি"
     notifications: "বিজ্ঞপ্তি"
     tl: "টাইমলাইন"
     antenna: "অ্যান্টেনা"
     list: "লিস্ট"
     mentions: "উল্লেখসমূহ"
+    direct: "ডাইরেক্ট নোটগুলি"
diff --git a/locales/de-DE.yml b/locales/de-DE.yml
index 05360e1703f7f547cd04808721950b3bf0e7d90b..cec230e10d7fa44ef2341647f61418eb2db3c128 100644
--- a/locales/de-DE.yml
+++ b/locales/de-DE.yml
@@ -141,6 +141,8 @@ flagAsBot: "Als Bot markieren"
 flagAsBotDescription: "Aktiviere diese Option, falls dieses Benutzerkonto durch ein Programm gesteuert wird. Falls aktiviert, agiert es als Flag für andere Entwickler zur Verhinderung von endlosen Kettenreaktionen mit anderen Bots und lässt Misskeys interne Systeme dieses Benutzerkonto als Bot behandeln."
 flagAsCat: "Als Katze markieren"
 flagAsCatDescription: "Aktiviere diese Option, um dieses Benutzerkonto als Katze zu markieren."
+flagShowTimelineReplies: "Antworten in der Chronik anzeigen"
+flagShowTimelineRepliesDescription: "Ist diese Option aktiviert, so werden Antworten von Benutzern auf die Notizen anderer Benuzter in der Chronik an angezeigt."
 autoAcceptFollowed: "Follow-Anfragen von Benutzern, denen du folgst, automatisch akzeptieren"
 addAccount: "Benutzerkonto hinzufügen"
 loginFailed: "Anmeldung fehlgeschlagen"
@@ -822,6 +824,10 @@ leaveGroupConfirm: "Möchtest du \"{name}\" wirklich verlassen?"
 useDrawerReactionPickerForMobile: "Auf mobilen Geräten ausfahrbare Reaktionsauswahl anzeigen"
 welcomeBackWithName: "Willkommen zurück, {name}"
 clickToFinishEmailVerification: "Drücke bitte auf [{ok}], um die Email-Bestätigung abzuschließen."
+overridedDeviceKind: "Gerätetyp"
+smartphone: "Smartphone"
+tablet: "Tablet"
+auto: "Automatisch"
 _emailUnavailable:
   used: "Diese Email-Adresse wird bereits verwendet"
   format: "Das Format dieser Email-Adresse ist ungültig"
@@ -1258,8 +1264,8 @@ _exportOrImport:
   excludeMutingUsers: "Stummgeschaltete Benutzer aussortieren"
   excludeInactiveUsers: "Inaktive Benutzer aussortieren"
 _charts:
-  federationInstancesIncDec: "Unterschied in der Anzahl von förderierenden Instanzen"
-  federationInstancesTotal: "Anzahl aller föderierenden Instanzen"
+  federation: "Föderation"
+  apRequest: "Anfragen"
   usersIncDec: "Unterschied in der Anzahl von Benutzern"
   usersTotal: "Anzahl aller Benutzer"
   activeUsers: "Aktive Benutzer"
diff --git a/locales/en-US.yml b/locales/en-US.yml
index 9a2b0bf5c59681988d4288105f5f56b665ccd0e2..43ecf98206c6bbe839fec8840187e1d7df6b868f 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -141,6 +141,8 @@ flagAsBot: "Mark this account as a bot"
 flagAsBotDescription: "Enable this option if this account is controlled by a program. If enabled, it will act as a flag for other developers to prevent endless interaction chains with other bots and adjust Misskey's internal systems to treat this account as a bot."
 flagAsCat: "Mark this account as a cat"
 flagAsCatDescription: "Enable this option to mark this account as a cat."
+flagShowTimelineReplies: "Show replies in timeline"
+flagShowTimelineRepliesDescription: "Shows replies of users to notes of other users in the timeline if turned on."
 autoAcceptFollowed: "Automatically approve follow requests from users you're following"
 addAccount: "Add account"
 loginFailed: "Failed to sign in"
@@ -822,6 +824,10 @@ leaveGroupConfirm: "Are you sure you want to leave \"{name}\"?"
 useDrawerReactionPickerForMobile: "Display reaction picker as drawer on mobile"
 welcomeBackWithName: "Welcome back, {name}"
 clickToFinishEmailVerification: "Please click [{ok}] to complete email verification."
+overridedDeviceKind: "Device type"
+smartphone: "Smartphone"
+tablet: "Tablet"
+auto: "Auto"
 _emailUnavailable:
   used: "This email address is already being used"
   format: "The format of this email address is invalid"
@@ -1258,8 +1264,8 @@ _exportOrImport:
   excludeMutingUsers: "Exclude muted users"
   excludeInactiveUsers: "Exclude inactive users"
 _charts:
-  federationInstancesIncDec: "Difference in # of federating instances"
-  federationInstancesTotal: "Total # of federating instances"
+  federation: "Federation"
+  apRequest: "Requests"
   usersIncDec: "Difference in # of users"
   usersTotal: "Total # of users"
   activeUsers: "Active users"
diff --git a/locales/eo-UY.yml b/locales/eo-UY.yml
index 0689834a1e293b74a3c32559e73eeac88573756e..286a0d857f6241bf489c853d72a120be1e4e5db5 100644
--- a/locales/eo-UY.yml
+++ b/locales/eo-UY.yml
@@ -65,6 +65,8 @@ files: "Dosieroj"
 download: "Elŝuti"
 driveFileDeleteConfirm: "Ĉu vi certas, ke vi volas forviŝi la dosieron \"{name}\"? Tio ankaŭ forviŝos la notojn kiuj citas ĝin."
 unfollowConfirm: "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?"
+exportRequested: "Vi petis elporton. Ĝi povas bezoni longan tempon. Elportaĵo estos aldonita al disko post elportado."
+importRequested: "Vi petis enportadon. Äœi povas bezoni longan tempon. "
 lists: "Listoj"
 noLists: "Neniu listo"
 note: "Noti"
@@ -77,7 +79,10 @@ manageLists: "Bonteni liston"
 error: "Eraro"
 somethingHappened: "Problemo okazis"
 retry: "Provi denove"
+pageLoadError: "Fuŝiĝis enlegi paĝon."
+pageLoadErrorDescription: "Ordinare tio okazas pro la retkondiĉo aŭ la staplo de retumilo.\nPurigu la staplon, aŭ refaru poste. "
 serverIsDead: "La servilo ne respondas. Vole atendu iom kaj penu denove."
+youShouldUpgradeClient: "Por montri ĉi paĝon, bonvolu enlegi refoje kaj uzi klienton novversian."
 enterListName: "Entajpu nomon de la listo"
 privacy: "Privateco"
 makeFollowManuallyApprove: "Eksekvi vin devas peti al vi"
@@ -132,6 +137,7 @@ settingGuide: "Agordaj rekomendoj"
 cacheRemoteFiles: "Stapli forajn dosierojn"
 flagAsBot: "Marki kiel esti uzanto de roboto"
 flagAsCat: "Marki kiel esti kato"
+flagShowTimelineReplies: "Montri respondon de notoj en templinio."
 autoAcceptFollowed: "AÅ­tomate akcepti la peton de sekvado far uzantoj kiujn vi sekvas"
 addAccount: "Aldoni konton"
 loginFailed: "Saluto malsukcesis"
@@ -178,6 +184,7 @@ noUsers: "Neniu uzanto"
 editProfile: "Redakti profilon"
 noteDeleteConfirm: "Ĉu vi certas ke vi volas forviŝi la noton?"
 pinLimitExceeded: "Vi ne povas alpingli pli"
+intro: "Instalado de Misskey finiĝis! Kreu administran konton."
 done: "Fini"
 processing: "Prilaborado…"
 preview: "AntaÅ­montro"
@@ -326,6 +333,7 @@ antennaExcludeKeywords: "Krom ĉefterminoj"
 notifyAntenna: "Oni sciigos novajn notojn"
 withFileAntenna: "Nur kun aldonaĵo"
 enableServiceworker: "Aktivigi ServiceWorker"
+caseSensitive: "Distingi usklecon"
 withReplies: "Inkluzive respondoj"
 connectedTo: "Sekva konto estas konektita"
 notesAndReplies: "Kun respondoj"
@@ -363,6 +371,7 @@ notFound: "Ne trovita"
 uploadFolder: "Dosierujo implicita por alŝuto"
 cacheClear: "Malplenigi staplon"
 markAsReadAllNotifications: "Marki ĉiujn sciigojn kiel legita"
+markAsReadAllUnreadNotes: "Marki ĉiujn afiŝojn kiel legita"
 markAsReadAllTalkMessages: "Marki ĉiujn retbabiladojn kiel legita"
 help: "Manlibro de uzado"
 inputMessageHere: "Entajpu mesaĝon tie"
@@ -385,6 +394,7 @@ next: "Sekve"
 retype: "Retajpu"
 noteOf: "Noto de {user}"
 inviteToGroup: "Inviti al grupo"
+maxNoteTextLength: "Limnombro de leteroj en noto"
 quoteAttached: "Kun citaĵo"
 quoteQuestion: "Ĉu vi volas aldoni citaĵon?"
 noMessagesYet: "Ankoraŭ neniu mesaĝo"
@@ -393,6 +403,7 @@ onlyOneFileCanBeAttached: "Oni povas aldoni nur unu dosieron po mesaĝo."
 signinRequired: "Bonvolu saluti"
 invitations: "Inviti"
 invitationCode: "Kodo de invito"
+checking: "kontrolante..."
 available: "Disposabla"
 unavailable: "Ne disponebla"
 usernameInvalidFormat: "La uzantnomo povas enhavi minusklajn kaj majusklajn literojn, numerojn, nur kaj '_'."
@@ -404,6 +415,7 @@ strongPassword: "Forta pasvorto"
 passwordMatched: "Konforma"
 passwordNotMatched: "Nekonforma"
 signinWith: "Saluti kun {x}"
+signinFailed: "Fuŝiĝis ensaluti. Bonvolu kontroli uzantnomon kaj pasvorton."
 or: "AÅ­"
 language: "Lingvo"
 uiLanguage: "Lingvo de fasado"
@@ -430,6 +442,7 @@ total: "Entute"
 appearance: "Eksteraĵo"
 clientSettings: "Agordoj de kliento"
 accountSettings: "Agordoj de konto"
+promote: "Reklamata"
 numberOfDays: "Nombro de tagoj"
 hideThisNote: "Kaŝi la noton"
 showFeaturedNotesInTimeline: "Montri en via templinio notojn de la tendenco"
@@ -465,11 +478,13 @@ scratchpad: "Malneta redaktilo"
 output: "Elmeto"
 script: "Skripto"
 disablePagesScript: "Malebligi AiScript en la paĝoj"
+updateRemoteUser: "Aktualigi informon de foraj uzantoj"
 deleteAllFiles: "Forviŝi ĉiujn dosierojn"
 deleteAllFilesConfirm: "Ĉu vi certas, ke vi volas forviŝi ĉiujn dosierojn?"
 removeAllFollowing: "Ĉesi sekvi ĉiujn sekvatojn"
 userSuspended: "La uzanto estas flostigita."
 userSilenced: "La uzanto estas mutigita."
+yourAccountSuspendedTitle: "La konto estas frostigita."
 menu: "Menuo"
 addItem: "Aldoni novaĵon"
 deletedNote: "Forviŝita noto"
@@ -499,6 +514,7 @@ generateAccessToken: "Generi aÅ­tentikigan pecon"
 permission: "Permesoj"
 enableAll: "Ebligi ĉiujn"
 disableAll: "Malebligi ĉiujn"
+tokenRequested: "Alirpermeso al konto"
 notificationType: "Tipo de sciigoj"
 edit: "Redakti"
 emailServer: "Retpoŝta servilo"
@@ -530,6 +546,7 @@ regenerateLoginToken: "Regeneri la aÅ­tentikigan pecon"
 fileIdOrUrl: "Dosiera identigilo aÅ­ URL"
 behavior: "Konduto"
 sample: "Ekzemplo"
+reporter: "Informanto"
 send: "Sendi"
 openInNewTab: "Malfermi en nova langeto"
 editTheseSettingsMayBreakAccount: "Redakti tiujn agordojn povas damaĝi vian konton."
@@ -553,6 +570,7 @@ followingCount: "La nombro de sekvatoj"
 followersCount: "La nombro de sekvantoj"
 sentReactionsCount: "La nombro de la reagoj senditaj"
 receivedReactionsCount: "La nombro de la reagoj ricevitaj"
+pollVotesCount: "Nombro de voĉdonado"
 yes: "Jes"
 no: "Ne"
 driveFilesCount: "La nombro de la dosieroj sur la disko"
@@ -587,6 +605,7 @@ createdAt: "Kreita je"
 updatedAt: "Laste ĝisdatigita"
 saveConfirm: "Ĉu vi konservas la ŝanĝon?"
 deleteConfirm: "Ĉu certas forviŝi?"
+invalidValue: "Nevalida valoro"
 closeAccount: "Forigi konton"
 currentVersion: "La aktuala versio"
 latestVersion: "La plej nova versio"
@@ -608,14 +627,18 @@ userInfo: "Informoj de uzanto"
 unknown: "Nekonata"
 online: "Surkonektita"
 offline: "Forkonektita"
+notRecommended: "Evitindaj"
 instanceBlocking: "Bloki specifajn nodojn"
 selectAccount: "Elekti konton"
 user: "Uzantoj"
 administration: "Bontenado"
 accounts: "Kontoj"
+configure: "Agordi"
 recentPosts: "Novaj afiŝoj"
+popularPosts: "Populara noto"
 shareWithNote: "Kundividi en noto"
 ads: "Reklamaĵo"
+expiration: "Limtempo"
 memo: "Memorigilo"
 high: "Alta"
 middle: "Meza"
@@ -629,12 +652,18 @@ searchResult: "Serĉorezultoj"
 hashtags: "Kradvorto"
 troubleshooting: "Problemsolvi"
 learnMore: "Lernu pli"
+misskeyUpdated: "Misskey ĝisdatiĝis!"
+whatIsNew: "Montri novaĵojn"
 translate: "Traduki"
 translatedFrom: "Tradukita el {x}"
+accountDeletionInProgress: "La konto estas forviŝanta."
+resolved: "Solvita"
+unresolved: "Nesolvita"
 breakFollow: "Ĉesigi la sekvadon al vi"
 itsOn: "Åœaltita"
 emailRequiredForSignup: "Registri konton devas konformi retpoŝtadreson"
 unread: "Nelegita"
+filter: "Filtrilo"
 controlPanel: "Åœaltpodio"
 manageAccounts: "Bonteni la kontojn"
 classic: "Klasika"
@@ -644,6 +673,7 @@ ffVisibility: "Videbleco de viaj sekvatoj/sekvantoj"
 ffVisibilityDescription: "Oni permesas agordi tiuln kiuj povas vidi la homojn kiujn vi sekvas, kaj la homojn kiuj sekvas vin."
 continueThread: "Pli vidi la mesaĝaron"
 incorrectPassword: "Nevalida pasvorto"
+voteConfirm: "Ĉu vi voĉdonas {choice}n?"
 leaveGroup: "Eliĝi el la grupo"
 leaveGroupConfirm: "Ĉu vi certas ke vi volas eliĝi el la grupo {name}?"
 welcomeBackWithName: "Bonrevenon, {name}!"
@@ -661,11 +691,14 @@ _signup:
   emailAddressInfo: "Entajpu vian retpoŝton"
 _accountDelete:
   accountDelete: "Forigi konton"
+  requestAccountDelete: "Peti forviŝi konton"
+  started: "Forviŝado komenciĝis."
 _ad:
   back: "Nuligi"
 _forgotPassword:
   enterEmail: "Entajpu la retpoŝton kiun vi registrigis al via konto. Ligilo por restarigi pasvorton estos sendita al la retadreso."
 _gallery:
+  my: "Mia afiŝo"
   liked: "Åœatitaj notoj"
   like: "Åœati"
 _email:
@@ -687,6 +720,7 @@ _aboutMisskey:
   allContributors: "Ĉiuj kontribuantoj"
   source: "Fontkodo"
   translation: "Traduki Misskey"
+  donate: "Mondonaci al Misskey"
   patrons: "Mecenatoj"
 _mfm:
   dummy: "Misskey evoluigas la mondon de Fediverso"
@@ -724,6 +758,7 @@ _channel:
   owned: "Bontenitaj de vi"
   following: "Sekvado"
   usersCount: "{n} partoprenantoj"
+  notesCount: "{n} notoj"
 _menuDisplay:
   sideFull: "Flanko"
   sideIcon: "Flanko (bildsimbolo)"
@@ -735,9 +770,15 @@ _wordMute:
   hard: "Per la servilo"
   mutedNotes: "Silentigitaj notoj"
 _theme:
+  explore: "Serĉi koloraron"
+  install: "Instali koloraron"
   manage: "Bonteni kolorarojn"
   code: "Kolorara kodo"
   description: "Priskribo"
+  installedThemes: "Instalita koloraro"
+  make: "Krei koloraron"
+  addConstant: "Aldoni konstanton"
+  constant: "Konstanto"
   defaultValue: "Implicitaĵa valoro"
   color: "Koloro"
   func: "Funkcio"
@@ -745,12 +786,14 @@ _theme:
   lighten: "Brileco"
   keys:
     bg: "Fono"
+    shadow: "Ombro"
     navBg: "Fono de flanka stango"
     link: "Ligilo"
     hashtag: "Kradvorto"
     mention: "Mencioj"
     mentionMe: "Mencio al vi"
     renote: "Plusendita"
+    infoBg: "Fono de informo"
     buttonBg: "Fono de butono"
     driveFolderBg: "Fono de dosierujo de la disko"
     messageBg: "Fono de la retbabilejo"
@@ -823,6 +866,7 @@ _widgets:
   timeline: "Templinio"
   clock: "Horloĝo"
   activity: "Aktiveco"
+  photos: "Fotoj"
   federation: "Federaĵo"
   slideshow: "Bildoprezento"
   button: "Butono"
@@ -830,10 +874,12 @@ _widgets:
   aichan: "Ai"
 _cw:
   show: "Vidi pli"
+  chars: "{count} literoj"
   files: "{count} dosiero(j)"
 _poll:
   choiceN: "Balotilo {n}"
   noMore: "Oni ne povas aldoni pli."
+  expiration: "Limtempo"
   infinite: "Neniam"
   deadlineTime: "hor"
   votesCount: "{n} balotiloj"
@@ -876,7 +922,7 @@ _exportOrImport:
   blockingList: "Blokitoj"
   userLists: "Listoj"
 _charts:
-  federationInstancesTotal: "La totala nombro de nodoj federantaj"
+  federation: "Federaĵo"
   usersTotal: "La totala nombro de la uzantoj"
   activeUsers: "La nombro de la uzantoj aktivaj"
   notesTotal: "La totala nombro de notoj"
@@ -965,6 +1011,45 @@ _pages:
       _join:
         arg1: "Listoj"
         arg2: "apartigilo"
+      _add:
+        arg1: "A"
+        arg2: "B"
+      _subtract:
+        arg1: "A"
+        arg2: "B"
+      _multiply:
+        arg1: "A"
+        arg2: "B"
+      _divide:
+        arg1: "A"
+        arg2: "B"
+      _mod:
+        arg1: "A"
+        arg2: "B"
+      _eq:
+        arg1: "A"
+        arg2: "B"
+      _notEq:
+        arg1: "A"
+        arg2: "B"
+      _and:
+        arg1: "A"
+        arg2: "B"
+      _or:
+        arg1: "A"
+        arg2: "B"
+      _lt:
+        arg1: "A"
+        arg2: "B"
+      _gt:
+        arg1: "A"
+        arg2: "B"
+      _ltEq:
+        arg1: "A"
+        arg2: "B"
+      _gtEq:
+        arg1: "A"
+        arg2: "B"
       random: "Hazardo"
       _randomPick:
         arg1: "Listoj"
diff --git a/locales/es-ES.yml b/locales/es-ES.yml
index a9339acf7b232a1f693785722ac4bb7371c2a02a..1e85e7d8c42047943e4a201d988e54dd2f923aa7 100644
--- a/locales/es-ES.yml
+++ b/locales/es-ES.yml
@@ -1091,8 +1091,8 @@ _exportOrImport:
   blockingList: "Bloqueados"
   userLists: "Listas"
 _charts:
-  federationInstancesIncDec: "Variación de instancias federando"
-  federationInstancesTotal: "Total de instancias federando"
+  federation: "Federación"
+  apRequest: "Pedidos"
   usersIncDec: "Variación de usuarios"
   usersTotal: "Total de usuarios"
   activeUsers: "Cantidad de usuarios activos"
diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml
index 62f85bef8de501e1189f94d22b5899390dec4b1b..1deda414ce7861ef73672752b88eeb75cccb904b 100644
--- a/locales/fr-FR.yml
+++ b/locales/fr-FR.yml
@@ -141,6 +141,7 @@ flagAsBot: "Ce compte est un robot"
 flagAsBotDescription: "Si ce compte est géré de manière automatisée, choisissez cette option. Si elle est activée, elle agira comme un marqueur pour les autres développeurs afin d'éviter des chaînes d'interaction sans fin avec d'autres robots et d'ajuster les systèmes internes de Misskey pour traiter ce compte comme un robot."
 flagAsCat: "Ce compte est un chat"
 flagAsCatDescription: "Activer l'option \" Je suis un chat \" pour ce compte."
+flagShowTimelineReplies: "Afficher les réponses dans le fil"
 autoAcceptFollowed: "Accepter automatiquement les demandes d’abonnement venant d’utilisateur·rice·s que vous suivez"
 addAccount: "Ajouter un compte"
 loginFailed: "Échec de la connexion"
@@ -811,6 +812,7 @@ ffVisibilityDescription: "Permet de configurer qui peut voir les personnes que t
 continueThread: "Afficher la suite du fil"
 deleteAccountConfirm: "Votre compte sera supprimé. Êtes vous certain ?"
 incorrectPassword: "Le mot de passe est incorrect."
+voteConfirm: "Confirmez-vous votre vote pour « {choice} » ?"
 hide: "Masquer"
 leaveGroup: "Quitter le groupe"
 leaveGroupConfirm: "Êtes vous sûr de vouloir quitter \"{name}\" ?"
@@ -972,6 +974,8 @@ _wordMute:
   hard: "Strict"
   mutedNotes: "Notes filtrées"
 _instanceMute:
+  instanceMuteDescription2: "Séparer avec de nouvelles lignes"
+  title: "Masque les notes venant des instances listées."
   heading: "Instances à mettre en sourdine"
 _theme:
   explore: "Explorer les thèmes"
@@ -1247,8 +1251,8 @@ _exportOrImport:
   excludeMutingUsers: "Exclure les utilisateur·rice·s mis en sourdine"
   excludeInactiveUsers: "Exclure les utilisateur·rice·s inactifs"
 _charts:
-  federationInstancesIncDec: "Variation du nombre d'instances fédérées"
-  federationInstancesTotal: "Nombre total d'instances fédérées"
+  federation: "Fédération"
+  apRequest: "Requêtes"
   usersIncDec: "Variation du nombre d'utilisateur·rice·s"
   usersTotal: "Nombre des utilisateur·rice·s au total"
   activeUsers: "Nombre d'utilisateurices actif·ve·s"
diff --git a/locales/id-ID.yml b/locales/id-ID.yml
index a1d52f6ef1b5e547c3dc1777e1eb68c8d0522eb4..be766e72c53bac9cd8dc692f3baea1759cd20e5b 100644
--- a/locales/id-ID.yml
+++ b/locales/id-ID.yml
@@ -106,6 +106,7 @@ clickToShow: "Klik untuk melihat"
 sensitive: "Konten sensitif"
 add: "Tambahkan"
 reaction: "Reaksi"
+reactionSetting: "Reaksi untuk dimunculkan di bilah reaksi"
 reactionSettingDescription2: "Geser untuk memindah urutkan, klik untuk menghapus, tekan \"+\" untuk menambahkan"
 rememberNoteVisibility: "Ingat pengaturan visibilitas catatan"
 attachCancel: "Hapus lampiran"
@@ -140,6 +141,8 @@ flagAsBot: "Atur akun ini sebagai Bot"
 flagAsBotDescription: "Jika akun ini dikendalikan oleh program, tetapkanlah opsi ini. Jika diaktifkan, ini akan berfungsi sebagai tanda bagi pengembang lain untuk mencegah interaksi berantai dengan bot lain dan menyesuaikan sistem internal Misskey untuk memperlakukan akun ini sebagai bot."
 flagAsCat: "Atur akun ini sebagai kucing"
 flagAsCatDescription: "Nyalakan tanda ini untuk menandai akun ini sebagai kucing."
+flagShowTimelineReplies: "Tampilkan balasan di linimasa"
+flagShowTimelineRepliesDescription: "Menampilkan balasan pengguna dari note pengguna lain di linimasa apabila dinyalakan."
 autoAcceptFollowed: "Setujui otomatis permintaan mengikuti dari pengguna yang kamu ikuti"
 addAccount: "Tambahkan akun"
 loginFailed: "Gagal untuk masuk"
@@ -234,6 +237,8 @@ resetAreYouSure: "Yakin mau atur ulang?"
 saved: "Telah disimpan"
 messaging: "Pesan"
 upload: "Unggah"
+keepOriginalUploading: "Simpan gambar asli"
+keepOriginalUploadingDescription: "Simpan gambar yang diunggah sebagaimana gambar aslinya. Bila dimatikan, versi tampilan web akan dihasilkan pada saat diunggah."
 fromDrive: "Dari Drive"
 fromUrl: "Dari URL"
 uploadFromUrl: "Unggah dari URL"
@@ -446,6 +451,7 @@ uiLanguage: "Bahasa antarmuka pengguna"
 groupInvited: "Telah diundang ke grup"
 aboutX: "Tentang {x}"
 useOsNativeEmojis: "Gunakan Emoji bawaan sistem operasi"
+disableDrawer: "Jangan gunakan menu bergaya laci"
 youHaveNoGroups: "Kamu tidak memiliki grup"
 joinOrCreateGroup: "Bergabunglah dengan grup atau kamu dapat membuat grupmu sendiri."
 noHistory: "Tidak ada riwayat"
@@ -589,6 +595,7 @@ smtpSecure: "Gunakan SSL/TLS implisit untuk koneksi SMTP"
 smtpSecureInfo: "Matikan ini ketika menggunakan STARTTLS"
 testEmail: "Tes pengiriman surel"
 wordMute: "Bisukan kata"
+instanceMute: "Bisuka instansi"
 userSaysSomething: "{name} mengatakan sesuatu"
 makeActive: "Aktifkan"
 display: "Tampilkan"
@@ -616,8 +623,11 @@ reportAbuse: "Laporkan"
 reportAbuseOf: "Laporkan {name}"
 fillAbuseReportDescription: "Mohon isi rincian laporan. Jika laporan ini mengenai catatan yang spesifik, mohon lampirkan serta URL catatan tersebut."
 abuseReported: "Laporan kamu telah dikirimkan. Terima kasih."
+reporter: "Pelapor"
 reporteeOrigin: "Yang dilaporkan"
 reporterOrigin: "Pelapor"
+forwardReport: "Teruskan laporan ke instansi luar"
+forwardReportIsAnonymous: "Untuk melindungi privasi akun kamu, akun anonim dari sistem akan digunakan sebagai pelapor pada instansi luar."
 send: "Kirim"
 abuseMarkAsResolved: "Tandai laporan sebagai selesai"
 openInNewTab: "Buka di tab baru"
@@ -679,6 +689,7 @@ center: "Tengah"
 wide: "Lebar"
 narrow: "Sempit"
 reloadToApplySetting: "Pengaturan ini akan diterapkan saat memuat halaman kembali. Apakah kamu ingin memuat halaman kembali sekarang?"
+needReloadToApply: "Pengaturan ini hanya akan diterapkan setelah memuat ulang halaman."
 showTitlebar: "Tampilkan bilah judul"
 clearCache: "Hapus tembolok"
 onlineUsersCount: "{n} orang sedang daring"
@@ -739,6 +750,7 @@ notRecommended: "Tidak disarankan"
 botProtection: "Perlindungan Bot"
 instanceBlocking: "Instansi yang diblokir"
 selectAccount: "Pilih akun"
+switchAccount: "Ganti akun"
 enabled: "Aktif"
 disabled: "Nonaktif"
 quickAction: "Aksi cepat"
@@ -787,6 +799,7 @@ pubSub: "Akun Pub/Sub"
 lastCommunication: "Komunikasi terakhir"
 resolved: "Selesai"
 unresolved: "Belum selesai"
+breakFollow: "Batalkan mengikuti"
 itsOn: "Aktif"
 itsOff: "Nonaktif"
 emailRequiredForSignup: "Membutuhkan alamat surel untuk mendaftar"
@@ -806,6 +819,15 @@ deleteAccountConfirm: "Akun akan dihapus. Apakah kamu yakin?"
 incorrectPassword: "Kata sandi salah."
 voteConfirm: "Konfirmasi suara kamu untuk ({choice})?"
 hide: "Sembunyikan"
+leaveGroup: "Keluar grup"
+leaveGroupConfirm: "Apakah kamu yakin untuk keluar dari \"{name}\"?"
+useDrawerReactionPickerForMobile: "Tampilkan bilah reaksi sebagai laci di ponsel"
+welcomeBackWithName: "Selamat datang kembali, {name}."
+clickToFinishEmailVerification: "Mohon klik [{ok}] untuk menyelesaikan verifikasi email."
+overridedDeviceKind: "Tipe perangkat"
+smartphone: "Ponsel"
+tablet: "Tablet"
+auto: "Otomatis"
 _emailUnavailable:
   used: "Alamat surel ini telah digunakan"
   format: "Format tidak valid."
@@ -963,6 +985,11 @@ _wordMute:
   soft: "Lembut"
   hard: "Keras"
   mutedNotes: "Catatan yang dibisukan"
+_instanceMute:
+  instanceMuteDescription: "Pengaturan ini akan membisukan note/renote apa saja dari instansi yang terdaftar, termasuk pengguna yang membalas pengguna lain dalam instansi yang dibisukan."
+  instanceMuteDescription2: "Pisah dengan baris baru"
+  title: "Sembunyikan note dari instansi terdaftar."
+  heading: "Daftar instansi yang akan dibisukan"
 _theme:
   explore: "Jelajahi tema"
   install: "Pasang tema"
@@ -1234,9 +1261,11 @@ _exportOrImport:
   muteList: "Bisukan"
   blockingList: "Blokir"
   userLists: "Daftar"
+  excludeMutingUsers: "Kecualikan pengguna yang dibisukan"
+  excludeInactiveUsers: "Kecualikan pengguna tidak aktif"
 _charts:
-  federationInstancesIncDec: "Perbedaan jumlah # instansi yang memfederasi"
-  federationInstancesTotal: "Jumlah # instansi yang memfederasi"
+  federation: "Federasi"
+  apRequest: "Permintaan"
   usersIncDec: "Perbedaan dalam # pengguna"
   usersTotal: "Jumlah # pengguna"
   activeUsers: "Pengguna aktif"
diff --git a/locales/it-IT.yml b/locales/it-IT.yml
index d13e53625fcdc60fb4196d14e58f2de092e746b1..c4ec4232a53c236f4fb461b08f991016fcaeeab3 100644
--- a/locales/it-IT.yml
+++ b/locales/it-IT.yml
@@ -1177,8 +1177,8 @@ _exportOrImport:
   blockingList: "Account bloccati"
   userLists: "Liste"
 _charts:
-  federationInstancesIncDec: "Variazione del numero di istanze federate"
-  federationInstancesTotal: "Numero totale di istanze federate"
+  federation: "Federazione"
+  apRequest: "Richieste"
   usersIncDec: "Variazione del numero di utenti"
   usersTotal: "Numero totale di utenti"
   activeUsers: "Numero di utenti attivi"
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 8fd41e533b30f6a49cfb848af3dea026117800a8..ac8d4951a8796a8edf955960bb1ba334ad1394a5 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -141,6 +141,8 @@ flagAsBot: "Botとして設定"
 flagAsBotDescription: "このアカウントがプログラムによって運用される場合は、このフラグをオンにします。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Misskeyのシステム上での扱いがBotに合ったものになります。"
 flagAsCat: "Catとして設定"
 flagAsCatDescription: "このアカウントが猫であることを示す場合は、このフラグをオンにします。"
+flagShowTimelineReplies: "タイムラインにノートへの返信を表示する"
+flagShowTimelineRepliesDescription: "オンにすると、タイムラインにユーザーのノート以外にもそのユーザーの他のノートへの返信を表示します。"
 autoAcceptFollowed: "フォロー中ユーザーからのフォロリクを自動承認"
 addAccount: "アカウントを追加"
 loginFailed: "ログインに失敗しました"
@@ -822,6 +824,10 @@ leaveGroupConfirm: "「{name}」から抜けますか?"
 useDrawerReactionPickerForMobile: "モバイルデバイスのときドロワーで表示"
 welcomeBackWithName: "おかえりなさい、{name}さん"
 clickToFinishEmailVerification: "[{ok}]を押して、メールアドレスの確認を完了してください。"
+overridedDeviceKind: "デバイスタイプ"
+smartphone: "スマートフォン"
+tablet: "タブレット"
+auto: "自動"
 
 _emailUnavailable:
   used: "既に使用されています"
@@ -1296,8 +1302,8 @@ _exportOrImport:
   excludeInactiveUsers: "使われていないアカウントを除外"
 
 _charts:
-  federationInstancesIncDec: "連合の増減"
-  federationInstancesTotal: "連合の合計"
+  federation: "連合"
+  apRequest: "リクエスト"
   usersIncDec: "ユーザーの増減"
   usersTotal: "ユーザーの合計"
   activeUsers: "アクティブユーザー数"
diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml
index 45ab9684d26b26ea2d54ffbb2d1e8239075dcb71..b5b4e72576125e6fde2e42b2d7ddd72c6de03c6a 100644
--- a/locales/ja-KS.yml
+++ b/locales/ja-KS.yml
@@ -81,6 +81,8 @@ somethingHappened: "なんかアカンことが起こったで"
 retry: "もっぺんやる?"
 pageLoadError: "ページの読み込みに失敗してしもうたで…"
 pageLoadErrorDescription: "これは普通、ネットワークかブラウザキャッシュが原因やからね。キャッシュをクリアするか、もうちっとだけ待ってくれへんか?"
+serverIsDead: "The server is not responding. Please wait for a while before trying again."
+youShouldUpgradeClient: "To display this page, please reload and use a new version client. "
 enterListName: "リスト名を入れてや"
 privacy: "プライバシー"
 makeFollowManuallyApprove: "自分が認めた人だけがこのアカウントをフォローできるようにする"
@@ -104,6 +106,7 @@ clickToShow: "押したら見えるで"
 sensitive: "ちょっとアカンやつやで"
 add: "増やす"
 reaction: "リアクション"
+reactionSetting: "Reaction that will be displayed in Picker. "
 reactionSettingDescription2: "ドラッグで並び替え、クリックで削除、+を押して追加やで。"
 rememberNoteVisibility: "公開範囲覚えといて"
 attachCancel: "のっけるのやめる"
@@ -138,6 +141,8 @@ flagAsBot: "Botやで"
 flagAsBotDescription: "もしこのアカウントがプログラムによって運用されるんやったら、このフラグをオンにしてたのむで。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Misskeyのシステム上での扱いがBotに合ったもんになるんやで。"
 flagAsCat: "Catやで"
 flagAsCatDescription: "ワレ、猫ちゃんならこのフラグをつけてみ?"
+flagShowTimelineReplies: "It will display the reply to the note in the timeline. "
+flagShowTimelineRepliesDescription: "It will display the reply to notes other than the user notes in the timeline when you turn it on. "
 autoAcceptFollowed: "フォローしとるユーザーからのフォローリクエストを勝手に許可しとく"
 addAccount: "アカウントを追加"
 loginFailed: "ログインに失敗してしもうた…"
@@ -232,6 +237,8 @@ resetAreYouSure: "リセットしてええん?"
 saved: "保存したで!"
 messaging: "チャット"
 upload: "アップロード"
+keepOriginalUploading: "Retain the original image. "
+keepOriginalUploadingDescription: "When uploading the clip, the original version will be retained. Turning it of then uploading will produce images for public use. "
 fromDrive: "ドライブから"
 fromUrl: "URLから"
 uploadFromUrl: "URLアップロード"
@@ -884,6 +891,8 @@ _exportOrImport:
   blockingList: "ブロック"
   userLists: "リスト"
 _charts:
+  federation: "連合"
+  apRequest: "リクエスト"
   usersTotal: "ユーザーの合計"
   activeUsers: "アクティブユーザー数"
   notesIncDec: "ノートの増減"
diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml
index 38a328862f50da706ae0cb75efe1f3511d87dd38..116e397ff558887cf167630b1be59b64c295e532 100644
--- a/locales/ko-KR.yml
+++ b/locales/ko-KR.yml
@@ -141,6 +141,8 @@ flagAsBot: "나는 봇입니다"
 flagAsBotDescription: "이 계정을 자동화된 수단으로 운용할 경우에 활성화해 주세요. 이 플래그를 활성화하면, 다른 봇이 이를 참고하여 봇 끼리의 무한 연쇄 반응을 회피하거나, 이 계정의 시스템 상에서의 취급이 Bot 운영에 최적화되는 등의 변화가 생깁니다."
 flagAsCat: "나는 고양이다냥"
 flagAsCatDescription: "이 계정이 고양이라면 활성화 해주세요."
+flagShowTimelineReplies: "타임라인에 노트의 답글을 표시하기"
+flagShowTimelineRepliesDescription: "이 설정을 활성화하면 타임라인에 다른 유저 간의 답글을 표시합니다."
 autoAcceptFollowed: "팔로우 중인 유저로부터의 팔로우 요청을 자동 수락"
 addAccount: "계정 추가"
 loginFailed: "로그인에 실패했습니다"
@@ -822,6 +824,10 @@ leaveGroupConfirm: "\"{name}\"에서 나갈까요?"
 useDrawerReactionPickerForMobile: "모바일에서 드로어 메뉴로 표시"
 welcomeBackWithName: "환영합니다, {name}님"
 clickToFinishEmailVerification: "[{ok}]를 눌러 이메일 인증을 완료하세요."
+overridedDeviceKind: "장치 유형"
+smartphone: "스마트폰"
+tablet: "태블릿"
+auto: "자동"
 _emailUnavailable:
   used: "이 메일 주소는 사용중입니다"
   format: "형식이 올바르지 않습니다"
@@ -1258,8 +1264,8 @@ _exportOrImport:
   excludeMutingUsers: "뮤트한 유저 제외하기"
   excludeInactiveUsers: "휴면 중인 계정 제외하기"
 _charts:
-  federationInstancesIncDec: "연합 인스턴스 수 증감"
-  federationInstancesTotal: "연합 인스턴스 수 합계"
+  federation: "ì—°í•©"
+  apRequest: "요청"
   usersIncDec: "유저 수 증감"
   usersTotal: "유저 수 합계"
   activeUsers: "활성 유저 수"
diff --git a/locales/nl-NL.yml b/locales/nl-NL.yml
index 386357f2d39ec823b7d07249626db86f9bb8c3f4..38f9a88af8e0241f42e0a870d73fe3f504590ad1 100644
--- a/locales/nl-NL.yml
+++ b/locales/nl-NL.yml
@@ -291,6 +291,8 @@ _exportOrImport:
   userLists: "Lijsten"
   excludeMutingUsers: "Negeer gedempte gebruikers"
   excludeInactiveUsers: "Negeer inactieve gebruikers"
+_charts:
+  federation: "Federatie"
 _timelines:
   home: "Startpagina"
 _pages:
diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml
index 27772663bcee03d138726334cd884efc80b294a9..0b57a3a46fa19e10e897287ba8218c7ba44a0c85 100644
--- a/locales/pl-PL.yml
+++ b/locales/pl-PL.yml
@@ -1084,7 +1084,8 @@ _exportOrImport:
   blockingList: "Zablokuj"
   userLists: "Listy"
 _charts:
-  federationInstancesTotal: "Łącznie sfederowanych instancji"
+  federation: "Federacja"
+  apRequest: "Żądania"
   usersTotal: "Łącznie # użytkowników"
   activeUsers: "Aktywni użytkownicy"
 _instanceCharts:
diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml
index 7de9f8ff950b007cd24db2393f52f0d47929a9f7..b29d2173c80cbeecb9fadfd35ebc2dfbc9b3c5d1 100644
--- a/locales/ru-RU.yml
+++ b/locales/ru-RU.yml
@@ -235,6 +235,7 @@ resetAreYouSure: "На самом деле сбросить?"
 saved: "Сохранено"
 messaging: "Сообщения"
 upload: "Загрузить"
+keepOriginalUploading: "Сохранить исходное изображение"
 fromDrive: "С «диска»"
 fromUrl: "По ссылке"
 uploadFromUrl: "Загрузить по ссылке"
@@ -743,6 +744,7 @@ notRecommended: "Не рекомендуется"
 botProtection: "Ботозащита"
 instanceBlocking: "Блокировка инстансов"
 selectAccount: "Выберите учётную запись"
+switchAccount: "Сменить учётную запись"
 enabled: "Вкл."
 disabled: "Откл."
 quickAction: "Быстрое действие"
@@ -1249,8 +1251,8 @@ _exportOrImport:
   excludeMutingUsers: "За исключением заглушенных пользователей"
   excludeInactiveUsers: "Без неактивных учётных записей"
 _charts:
-  federationInstancesIncDec: "Изменение внешних связей"
-  federationInstancesTotal: "Количество внешних связей"
+  federation: "Федерация"
+  apRequest: "Запросы"
   usersIncDec: "Изменение числа пользователей"
   usersTotal: "Количество пользователей"
   activeUsers: "Активные пользователи"
diff --git a/locales/sk-SK.yml b/locales/sk-SK.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7ee4f5be7933ad93993d7d60f850dcc7c2e90688
--- /dev/null
+++ b/locales/sk-SK.yml
@@ -0,0 +1,1636 @@
+---
+_lang_: "Slovenčina"
+headlineMisskey: "Sieť prepojená poznámkami"
+introMisskey: "Vitajte! Misskey je otvorená a decentralizovaná mikroblogovacia služba.\n\"Poznámkami\" môžete zdieľať svoje myšlienky so všetkými okolo. 📡\nPomocou \"reakcií\" môžete rýchlo vyjadri svoje pocity o každého poznámkach. 👍\nPoďte objavovať svet! 🚀"
+monthAndDay: "{day}. {month}."
+search: "Hľadať"
+notifications: "Oznámenia"
+username: "Meno používateľa"
+password: "Heslo"
+forgotPassword: "Zabudnuté heslo"
+fetchingAsApObject: "Načítam údaje z Fediverzu"
+ok: "OK"
+gotIt: "Rozumiem!"
+cancel: "Zrušiť"
+enterUsername: "Zadajte meno používateľa"
+renotedBy: "{user} preposlal/a"
+noNotes: "Žiadne poznámky"
+noNotifications: "Žiadne oznámenia"
+instance: "Inštancia"
+settings: "Nastavenia"
+basicSettings: "Všeobecné nastavenia"
+otherSettings: "Rozšírené nastavenia"
+openInWindow: "Otvoriť v novom okne"
+profile: "Profil"
+timeline: "Časová os"
+noAccountDescription: "Tento používateľ zatiaľ nenapísal o sebe."
+login: "Prihlásiť sa"
+loggingIn: "Prebieha prihlasovanie"
+logout: "Odhlásiť"
+signup: "Registrovať"
+uploading: "Nahrávanie..."
+save: "Uložiť"
+users: "Používatelia"
+addUser: "Pridať používateľa"
+favorite: "Páči sa mi"
+favorites: "Obľúbené"
+unfavorite: "Nepáči sa mi"
+favorited: "Pridané do obľúbených"
+alreadyFavorited: "Už je medzi obľúbenými"
+cantFavorite: "Nepodarilo sa pridať medzi obľúbené."
+pin: "Pripnúť"
+unpin: "Odopnúť"
+copyContent: "Kopírovať obsah"
+copyLink: "Kopírovať odkaz"
+delete: "Odstrániť"
+deleteAndEdit: "Odstrániť a upraviť"
+deleteAndEditConfirm: "Naozaj chcete odstrániť túto poznámku a upraviť ju? Stratíte tým všetky reakcie a odpovede na ňu."
+addToList: "Pridať do zoznamu"
+sendMessage: "Odoslať správu"
+copyUsername: "Kopírovať meno používateľa"
+searchUser: "Hľadať používateľov"
+reply: "Odpovedať"
+loadMore: "Zobraziť viac"
+showMore: "Zobraziť viac"
+youGotNewFollower: "Máte nového sledujúceho"
+receiveFollowRequest: "Žiadosť o sledovanie prijatá"
+followRequestAccepted: "Žiadosť o sledovanie akceptovaná"
+mention: "Zmienka"
+mentions: "Zmienky"
+directNotes: "Priame poznámky"
+importAndExport: "Import a export"
+import: "Importovať"
+export: "Exportovať"
+files: "Súbor/y"
+download: "Stiahnuť"
+driveFileDeleteConfirm: "Naozaj chcete odstrániť súbor \"{name}\"? Poznámky s týmto súborom sa odstránia tiež."
+unfollowConfirm: "Naozaj už nechcete sledovať {name}?"
+exportRequested: "Vyžiadali ste export. Môže to chvíľu trvať. Po skončení pribudne na vašom disku."
+importRequested: "Požiadali ste o export. Môže to chvíľu trvať."
+lists: "Zoznamy"
+noLists: "Nemáte žiadne zoznamy"
+note: "Poznámka"
+notes: "Poznámky"
+following: "Sledujete"
+followers: "Sledujúci"
+followsYou: "Sledujú vás"
+createList: "Vytvoriť zoznam"
+manageLists: "Spravovať zoznamy"
+error: "Chyba"
+somethingHappened: "Ups. Niečo sa nepodarilo."
+retry: "Opakovať"
+pageLoadError: "Nepodarilo sa načítať stránku"
+pageLoadErrorDescription: "Toto môže byť spôsobené problémami so sieťou alebo cachou prehliadača. Skúste vyčistiť cache a potom skúsiť znova po chvíli."
+serverIsDead: "Tento server nereaguje. Prosím chvíľu počkajte a skúste znova."
+youShouldUpgradeClient: "Na pozretie tejto stránky prosím obnovte svojho klienta."
+enterListName: "Zadajte názov zoznamu"
+privacy: "Súkromie"
+makeFollowManuallyApprove: "Žiadosti o sledovanie treba schváliť"
+defaultNoteVisibility: "Predvolená viditeľnosť"
+follow: "Sledovať"
+followRequest: "Požiadať o sledovanie"
+followRequests: "Žiadosti o sledovanie"
+unfollow: "Nesledovať"
+followRequestPending: "Žiadosť o sledovanie čaká"
+enterEmoji: "Zadajte emoji"
+renote: "Preposlať"
+unrenote: "Vrátiť preposlanie"
+renoted: "Preposlané."
+cantRenote: "Tento príspevok sa nedá preposlať."
+cantReRenote: "Odpoveď nemôže byť odstránená."
+quote: "Citovať"
+pinnedNote: "Pripnuté poznámky"
+pinned: "Pripnúť"
+you: "Vy"
+clickToShow: "Kliknutím zobrazíte"
+sensitive: "NSFW"
+add: "Pridať"
+reaction: "Reakcie"
+reactionSetting: "Reakcie zobrazené vo výbere reakcií"
+reactionSettingDescription2: "Ťahaním preusporiadate, kliknutím odstránite, Stlačením \"+\" pridáte"
+rememberNoteVisibility: "Zapamätať nastavenia viditeľnosti poznámky"
+attachCancel: "Odstrániť prílohu"
+markAsSensitive: "Označiť ako NSFW"
+unmarkAsSensitive: "Odznačiť NSFW"
+enterFileName: "Zadajte názov súboru"
+mute: "Vypnúť zvuk"
+unmute: "Zapnúť zvuk"
+block: "Zablokovať"
+unblock: "Odblokovať"
+suspend: "Zmraziť"
+unsuspend: "Odmraziť"
+blockConfirm: "Naozaj chcete zablokovať tento účet?"
+unblockConfirm: "Naozaj chcete odblokovať tento účet?"
+suspendConfirm: "Naozaj chcete zmraziť tento účet?"
+unsuspendConfirm: "Naozaj chcete odmraziť tento účet?"
+selectList: "Vyberte zoznam"
+selectAntenna: "Vyberte anténu"
+selectWidget: "Vyberte widget"
+editWidgets: "Upraviť widget"
+editWidgetsExit: "Hotovo"
+customEmojis: "Vlastné emoji"
+emoji: "Emoji"
+emojis: "Emoji"
+emojiName: "Názov emoji"
+emojiUrl: "URL obrázku"
+addEmoji: "Pridať emoji"
+settingGuide: "Odporúčané nastavenia"
+cacheRemoteFiles: "Cachovanie vzdialených súborov"
+cacheRemoteFilesDescription: "Zakázanie tohoto nastavenia spôsobí, že vzdialené súbory budú odkazované priamo, namiesto ukladania do cache. Ušetrí sa tak miesto na serveri, ale zvýši sa dátový tok, pretože sa negenerujú miniatúry."
+flagAsBot: "Tento účet je bot"
+flagAsBotDescription: "Ak je tento účet ovládaný programom, zaškrtnite túto voľbu. Ostatní uvidia, že je to bot a zabráni nekonečným interakciám s ďalšími botmi a upraví interné systémy Misskey, aby ho považoval za bota."
+flagAsCat: "Tento účet je mačka"
+flagAsCatDescription: "Zvoľte túto voľbu, aby bol tento účet označený ako mačka."
+flagShowTimelineReplies: "Zobraziť odpovede na poznámky v časovej osi"
+flagShowTimelineRepliesDescription: "Keď je zapnuté, na časovej osi sa zobrazia odpovede k poznámkam používateľov okrem samotných poznámok."
+autoAcceptFollowed: "Automaticky prijať sledovanie od účtov, ktoré sledujete"
+addAccount: "Pridať účet"
+loginFailed: "Prihlásenie sa nepodarilo."
+showOnRemote: "Zobraziť na vzdialenom serveri"
+general: "Všeobecné"
+wallpaper: "Tapeta"
+setWallpaper: "Nastaviť tapetu"
+removeWallpaper: "Odstrániť tapetu"
+searchWith: "Hľadať: {q}"
+youHaveNoLists: "Nemáte žiadne zoznamy"
+followConfirm: "Naozaj chcete sledovať {name}?"
+proxyAccount: "Proxy účet"
+proxyAccountDescription: "Proxy účet je účet, ktorý za určitých podmienok sleduje používateľov na diaľku vaším menom. Napríklad keď používateľ zaradí vzdialeného používateľa do zoznamu, pokiaľ nikto nesleduje používateľa na zozname, aktivita nebude doručená na server, takže namiesto toho bude používateľa sledova proxy účet."
+host: "Host"
+selectUser: "Vyberte používateľa"
+recipient: "Prijímateľ"
+annotation: "Komentáre"
+federation: "Federácia"
+instances: "Inštancia"
+registeredAt: "Registrácia"
+latestRequestSentAt: "Posledná odoslaná požiadavka"
+latestRequestReceivedAt: "Posledná prijatá požiadavka"
+latestStatus: "Posledný status"
+storageUsage: "Využité úložisko"
+charts: "Grafy"
+perHour: "za hodinu"
+perDay: "za deň"
+stopActivityDelivery: "Zastaviť posielanie aktivít"
+blockThisInstance: "Blokovať tento server"
+operations: "Operácie"
+software: "Softvér"
+version: "Verzia"
+metadata: "Metadáta"
+withNFiles: "{n} súbor(ov)"
+monitor: "Monitor"
+jobQueue: "Fronta úloh"
+cpuAndMemory: "CPU a pamäť"
+network: "Sieť"
+disk: "Disk"
+instanceInfo: "Informácie o serveri"
+statistics: "Å tatistiky"
+clearQueue: "Vyčistiť frontu"
+clearQueueConfirmTitle: "Naozaj chcete zrušiť všetky úlohy vo fronte?"
+clearQueueConfirmText: "Všetky nedoručené poznámky čakajúce vo fronte nebudú federované. Zvyčajne táto operácia nie je potrebná."
+clearCachedFiles: "Vyprázdniť cache"
+clearCachedFilesConfirm: "Naozaj chcete odstrániť všetky nacachované vzdialené súbory?"
+blockedInstances: "Blokované servery"
+blockedInstancesDescription: "Zoznam blokovaných serverov na riadkoch. Blokované servery nebudú môcť komunikovať s týmto serverom."
+muteAndBlock: "Umlčania a blokácie"
+mutedUsers: "Umlčaní používatelia"
+blockedUsers: "Blokovaní používatelia"
+noUsers: "Žiadni používatelia"
+editProfile: "Upraviť profil"
+noteDeleteConfirm: "Naozaj chcete odstrániť túto poznámku?"
+pinLimitExceeded: "Ďalšie poznámky už nemôžete pripnúť."
+intro: "Inštalácia Misskey je dokončená! Prosím vytvorte administrátora."
+done: "Hotovo"
+processing: "Pracujem..."
+preview: "Náhľad"
+default: "Predvolené"
+noCustomEmojis: "Žiadne emoji"
+noJobs: "Žiadne úlohy"
+federating: "Federácia"
+blocked: "Blokované"
+suspended: "Zmrazené"
+all: "VÅ¡etko"
+subscribing: "Odoberanie"
+publishing: "Zverejňovanie"
+notResponding: "Neodpovedá"
+instanceFollowing: "Sledujem na serveri"
+instanceFollowers: "Sledujúci zo servera"
+instanceUsers: "Používatelia servera"
+changePassword: "Zmeniť heslo"
+security: "Zabezpečenie"
+retypedNotMatch: "Zadané vstupy nesúhlasia"
+currentPassword: "Aktuálne heslo"
+newPassword: "Nové heslo"
+newPasswordRetype: "Nové heslo (znovu)"
+attachFile: "Priložiť súbor"
+more: "Viac!"
+featured: "Obľúbené poznámky"
+usernameOrUserId: "Meno používateľa alebo ID používateľa"
+noSuchUser: "Používateľ sa nenašiel"
+lookup: "Vyhľadať"
+announcements: "Oznamy"
+imageUrl: "URL obrázku"
+remove: "Odstrániť"
+removed: "Odstránené"
+removeAreYouSure: "Naozaj chcete odstrániť \"{x}\"?"
+deleteAreYouSure: "Naozaj chcete odstrániť \"{x}\"?"
+resetAreYouSure: "Naozaj resetovať?"
+saved: "Uložené"
+messaging: "Chat"
+upload: "Nahrať súbor"
+keepOriginalUploading: "Zachovať pôvodný obrázok"
+keepOriginalUploadingDescription: "Uloží pôvodný obrázok ako je. Ak je vypnuté, verzia pre web sa vygeneruje pri nahratí."
+fromDrive: "Z disku"
+fromUrl: "Z URL"
+uploadFromUrl: "Nahrať z URL adresy"
+uploadFromUrlDescription: "URL adresa nahrávaného súboru"
+uploadFromUrlRequested: "Upload vyžiadaný"
+uploadFromUrlMayTakeTime: "Nahrávanie môže nejaký čas trvať."
+explore: "Objavovať"
+messageRead: "Prečítané"
+noMoreHistory: "To je všetko"
+startMessaging: "Začať chat"
+nUsersRead: "prečítané {n} používateľmi"
+agreeTo: "Súhlasím s {0}"
+tos: "Podmienky používania"
+start: "Začať"
+home: "Domov"
+remoteUserCaution: "Tieto informácie nemusia byť aktuálne, keďže používateľ je na vzdialenom serveri."
+activity: "Aktivita"
+images: "Obrázky"
+birthday: "Dátum narodenia"
+yearsOld: "{age} rokov"
+registeredDate: "Dátum registrácie"
+location: "Lokalita"
+theme: "Téma"
+themeForLightMode: "Téma pri svetlom režime"
+themeForDarkMode: "Téma pri tmavom režime"
+light: "Svetlá"
+dark: "Tmavá"
+lightThemes: "Svetlá téma"
+darkThemes: "Tmavá téma"
+syncDeviceDarkMode: "Synchronizovať tmavú tému s nastavení vášho systému"
+drive: "Disk"
+fileName: "Názov súboru"
+selectFile: "Vyberte súbor"
+selectFiles: "Vyberte súbory"
+selectFolder: "Vyberte priečinok"
+selectFolders: "Vyberte priečinky"
+renameFile: "Premenovať súbor"
+folderName: "Názov priečinka"
+createFolder: "Vytvoriť priečinok"
+renameFolder: "Premenovať priečinok"
+deleteFolder: "Odstrániť priečinok"
+addFile: "Pridať súbor"
+emptyDrive: "Váš disk je prázdny"
+emptyFolder: "Tento priečinok je prázdny"
+unableToDelete: "Nedá sa odstrániť"
+inputNewFileName: "Zadajte nový názov"
+inputNewDescription: "Zadajte nový popis"
+inputNewFolderName: "Zadajte nový názov priečinka"
+circularReferenceFolder: "Cieľový priečinok je podpriečinkom priečinka, ktorý chcete presunúť."
+hasChildFilesOrFolders: "Nemôžete odstrániť priečinok sú súbormi."
+copyUrl: "Kopírovať URL"
+rename: "Premenovať"
+avatar: "Avatar"
+banner: "BAnner"
+nsfw: "NSFW"
+whenServerDisconnected: "Keď sa stratí spojenie so serverom"
+disconnectedFromServer: "Spojenie so serverom bolo prerušené"
+reload: "Obnoviť"
+doNothing: "Ignorovať"
+reloadConfirm: "Chcete obnoviť časovú os?"
+watch: "Sledovať"
+unwatch: "Nesledovať"
+accept: "Súhlasím"
+reject: "Nesúhlasím"
+normal: "Normálne"
+instanceName: "Názov servera"
+instanceDescription: "Popis servera"
+maintainerName: "Správca"
+maintainerEmail: "E-mailová adresa správcu"
+tosUrl: "URL zmluvných podmienok"
+thisYear: "Rok"
+thisMonth: "Mesiac"
+today: "Dnes"
+dayX: "{day}"
+monthX: "{month}"
+yearX: "{year}"
+pages: "Stránky"
+integration: "Integrácia"
+connectService: "Pripojiť"
+disconnectService: "Odpojiť"
+enableLocalTimeline: "Povoliť lokálnu časovú os"
+enableGlobalTimeline: "Povoliť globálnu časovú os"
+disablingTimelinesInfo: "Administrátori a moderátori majú vždy prístup ku všetkým časovým osiam, aj keď sú vypnuté."
+registration: "Registrácia"
+enableRegistration: "Povoliť registráciu nových používateľov"
+invite: "Pozvať"
+proxyRemoteFiles: "Proxy vzdialených súborov"
+proxyRemoteFilesDescription: "Ak je zapnuté, vzdialené súbory, ktoré nie sú uložené lokálne alebo boli odstránené kvôli obmedzeniam úložiska, budú vyžiadané cez proxy, vrátane generovani miniatúr. Neovplyvní to úložisko na serveri."
+driveCapacityPerLocalAccount: "Kapacita disku pre používateľa"
+driveCapacityPerRemoteAccount: "Kapacita disku pre vzdialeného používateľa"
+inMb: "V megabajtoch"
+iconUrl: "Favicon URL"
+bannerUrl: "URL obrázku bannera"
+backgroundImageUrl: "URL obrázku pozadia"
+basicInfo: "Základné informácie"
+pinnedUsers: "Pripnutí používatelia"
+pinnedUsersDescription: "Zoznam mien používateľov oddelených riadkami, ktorý budú pripnutí v záložke \"Objavovať\"."
+pinnedPages: "Pripnuté stránky"
+pinnedPagesDescription: "Na každý riadok zadajte cesty stránok, ktoré chcete pripnúť na vrch stránky tohoto servera."
+pinnedClipId: "ID pripnutého klipu"
+pinnedNotes: "Pripnuté poznámky"
+hcaptcha: "hCaptcha"
+enableHcaptcha: "Zapnúť hCaptchu"
+hcaptchaSiteKey: "Site key"
+hcaptchaSecretKey: "Secret key"
+recaptcha: "reCAPTCHA"
+enableRecaptcha: "Zapnúť ReCAPTCHA"
+recaptchaSiteKey: "Site key"
+recaptchaSecretKey: "Secret key"
+avoidMultiCaptchaConfirm: "Použitie viacerých Captcha systémov môže sposobiť problémy. Chcete radšej vypnúť ostatné Captcha systémy? Môžete ich povoliť viaceré stlačení Zrušiť."
+antennas: "Antény"
+manageAntennas: "Spravovať antény"
+name: "Názov"
+antennaSource: "Zdroj antény"
+antennaKeywords: "Počúvané kľúčové slová"
+antennaExcludeKeywords: "Vylúčené kľúčové slová"
+antennaKeywordsDescription: "Oddeľte medzerami pre podmienku AND alebo novými riadkami pre podmienku OR."
+notifyAntenna: "Upozorniť na nové poznámky"
+withFileAntenna: "Len poznámky so súbormi"
+enableServiceworker: "Povoliť Service Worker"
+antennaUsersDescription: "Zoznam používateľov jeden na riadok"
+caseSensitive: "Rozlišuje malé a veľké písmená"
+withReplies: "Vrátane odpovedí"
+connectedTo: "Nasledujúce účty sú pripojené"
+notesAndReplies: "Poznámky a odpovede"
+withFiles: "Vrátane súborov"
+silence: "Ticho"
+silenceConfirm: "Naozaj chcete utíšiť tohoto používateľa?"
+unsilence: "Vrátiť utíšenie"
+unsilenceConfirm: "Naozaj chcete vrátiť utíšenie tohoto používateľa?"
+popularUsers: "Populárni používatelia"
+recentlyUpdatedUsers: "Používatelia s najnovšou aktivitou"
+recentlyRegisteredUsers: "Najnovší používatelia"
+recentlyDiscoveredUsers: "Naposledy objavení používatelia"
+exploreUsersCount: "Existuje {count} používateľov"
+exploreFediverse: "Objavovať Fediverzum"
+popularTags: "Populárne značky"
+userList: "Zoznamy"
+about: "Informácie"
+aboutMisskey: "O Misskey"
+administrator: "Administrátor"
+token: "Token"
+twoStepAuthentication: "Dvojfaktorová autentifikácia"
+moderator: "Moderátor"
+nUsersMentioned: "{n} používateľov spomenulo"
+securityKey: "Bezpečnostný kľúč"
+securityKeyName: "Názov kľúča"
+registerSecurityKey: "Registrovať bezpečnostný kľúč"
+lastUsed: "Naposledy použité"
+unregister: "Odregistrovať"
+passwordLessLogin: "Nastaviť bezheslové prihlásenie"
+resetPassword: "Resetovať heslo"
+newPasswordIs: "Nové heslo je \"{password}\""
+reduceUiAnimation: "Menej UI animácií"
+share: "Zdieľať"
+notFound: "Nenájdené"
+notFoundDescription: "Nenašla sa žiadna stránka na zadanej URL."
+uploadFolder: "Predvolený priečinok pre nahrávanie"
+cacheClear: "Vyčistiť cache"
+markAsReadAllNotifications: "Označiť všetky oznámenia ako prečítané"
+markAsReadAllUnreadNotes: "Označiť všetky poznámky ako prečítané"
+markAsReadAllTalkMessages: "Označiť všetky správy ako prečítané"
+help: "Pomoc"
+inputMessageHere: "Sem napíšte správu"
+close: "Zavrieť"
+group: "Skupina"
+groups: "Skupiny"
+createGroup: "Vytvoriť skupinu"
+ownedGroups: "Vlastnené skupiny"
+joinedGroups: "Členstvo v skupinách"
+invites: "Pozvať"
+groupName: "Názov skupiny"
+members: "ÄŒlenovia"
+transfer: "Presun"
+messagingWithUser: "Súkromný chat"
+messagingWithGroup: "Skupinový chat"
+title: "Nadpis"
+text: "Text"
+enable: "Povoliť"
+next: "Ďalší"
+retype: "Zadajte znovu"
+noteOf: "Poznámky používateľa {user}"
+inviteToGroup: "Pozvať do skupiny"
+maxNoteTextLength: "Maximálny počet znakov poznámky"
+quoteAttached: "Citované"
+quoteQuestion: "Pripojiť ako citát?"
+noMessagesYet: "Zatiaľ žiadne správy"
+newMessageExists: "Máte novú správu"
+onlyOneFileCanBeAttached: "Ku správe môžete priložiť len jeden súbor"
+signinRequired: "Prihláste sa, prosím!"
+invitations: "Pozvať"
+invitationCode: "Kód pozvánky"
+checking: "Overujem..."
+available: "Dostupné"
+unavailable: "Nedostupné"
+usernameInvalidFormat: "Povolené sú písmená, čísla a _."
+tooShort: "Príliš krátke"
+tooLong: "Príliš dlhé"
+weakPassword: "Slabé heslo"
+normalPassword: "Dobré heslo"
+strongPassword: "Silné heslo"
+passwordMatched: "Heslá sú rovnaké"
+passwordNotMatched: "Heslá nie sú rovnaké"
+signinWith: "Prihlásiť sa použitím {x}"
+signinFailed: "Nedá sa prihlásiť. Skontrolujte prosím meno používateľa a heslo."
+tapSecurityKey: "Ťuknite na bezpečnostný kľúč"
+or: "Alebo"
+language: "Jazyk"
+uiLanguage: "Jazyk používateľského prostredia"
+groupInvited: "Pozvať do skupiny"
+aboutX: "O {x}"
+useOsNativeEmojis: "Používať natívne emoji z OS"
+disableDrawer: "Nepoužívať šuflíkové menu"
+youHaveNoGroups: "Nemáte žiadne skupiny"
+joinOrCreateGroup: "Požiadajte o pozvanie do existujúcej skupiny alebo vytvorte novú."
+noHistory: "Žiadna história"
+signinHistory: "História prihlásení"
+disableAnimatedMfm: "Vypnúť MFM s animáciou"
+doing: "Pracujem..."
+category: "Kategórie"
+tags: "Značky"
+docSource: "Zdroj tohoto dokumentu"
+createAccount: "Vytvoriť účet"
+existingAccount: "Existujúci účet"
+regenerate: "Pregenerovať"
+fontSize: "Veľkosť písma"
+noFollowRequests: "Nemáte nijaké čakajúce žiadosti o sledovanie"
+openImageInNewTab: "Otvoriť obrázok v novom tabe"
+dashboard: "Prehľad"
+local: "Lokálne"
+remote: "Vzdialené"
+total: "Celkom"
+weekOverWeekChanges: "Medzitýždňové zmeny"
+dayOverDayChanges: "Medzidenné zmeny"
+appearance: "Vzhľad"
+clientSettings: "Nastavenia klienta"
+accountSettings: "Nastavenia účtu"
+promotion: "Propagácia"
+promote: "Propagovať"
+numberOfDays: "Počet dní"
+hideThisNote: "Skryť túto poznámku"
+showFeaturedNotesInTimeline: "Zobraziť významné poznámky v časovej osi"
+objectStorage: "Objektové úložisko"
+useObjectStorage: "Použiť objektové úložisko"
+objectStorageBaseUrl: "Základná URL"
+objectStorageBaseUrlDesc: "URL použitá ako referencia. Zadajte URL svojho CDN alebo Proxy ak niektoré používate. S3: 'https://<bucket>.s3.amazonaws.com', GCS: 'https://storage.googleapis.com/<bucket>' atď."
+objectStorageBucket: "Bucket"
+objectStorageBucketDesc: "Prosím zadajte názov bucketu od svojho poskytovateľa."
+objectStoragePrefix: "Prefix"
+objectStoragePrefixDesc: "Súbory budú ukladané do priečinkov pod týmto prefixom."
+objectStorageEndpoint: "Endpoint"
+objectStorageEndpointDesc: "Nechajte prázdne ak používate AWS S3, inak zadajte endpoint ako \"<host>\" alebo \"<host>:<port>\". Záleží to od služby, ktorú používate."
+objectStorageRegion: "Región"
+objectStorageRegionDesc: "Zadajte región ako 'xx-east-1'. Ak vaša služba nerozlišuje regióny, nechajte prázdne alebo zadajte 'us-east-1'."
+objectStorageUseSSL: "Použiť SSL"
+objectStorageUseSSLDesc: "Vypnite to ak nechcete použiť HTTPS na API spojenia."
+objectStorageUseProxy: "Pripájať cez Proxy"
+objectStorageUseProxyDesc: "Vypnite ak nechcete, aby spojenia na API išli cez Proxy"
+objectStorageSetPublicRead: "Pri nahratí nastaviť \"public-read\""
+serverLogs: "Logy servera"
+deleteAll: "Odstrániť všetko"
+showFixedPostForm: "Zobraziť formulár na nové príspevky nad časovou osou"
+newNoteRecived: "Sú nové poznámky"
+sounds: "Zvuky"
+listen: "Počúvať"
+none: "Žiadne"
+showInPage: "Zobraziť v stránke"
+popout: "Pop-out"
+volume: "Hlasitosť"
+masterVolume: "Celková hlasitosť"
+details: "Detaily"
+chooseEmoji: "Vybrať emoji"
+unableToProcess: "Operáciu sa nepodarilo dokončiť."
+recentUsed: "Neposledy použité"
+install: "Nainštalovať"
+uninstall: "Odinštalovať"
+installedApps: "Autorizované aplikácie"
+nothing: "Nič tu nie je"
+installedDate: "Dátum autorizácie"
+lastUsedDate: "Naposledy použité"
+state: "Status"
+sort: "Zoradiť"
+ascendingOrder: "Vzostupne"
+descendingOrder: "Zostupne"
+scratchpad: "Zápisník"
+scratchpadDescription: "Zápisník poskytuje prostredia pre experimenty s AiScriptom. Môžete písať, spúšťať a skúšať vysledky pri interakcii s Misskey."
+output: "Výstup"
+script: "Skript"
+disablePagesScript: "Vypnúť AiScript na stránkach"
+updateRemoteUser: "Aktualizovať informácie o vzdialenom účte"
+deleteAllFiles: "Odstrániť všetky súbory"
+deleteAllFilesConfirm: "Naozaj chcete odstrániť všetky súbory"
+removeAllFollowing: "Zrušiť sledovani všetkých používateľov"
+removeAllFollowingDescription: "Týmto zrušíte sledovanie všetkých používateľov z {host}. Spustite to prosím, keď server napríklad už neexistuje."
+userSuspended: "Tento používateľ je zmrazený."
+userSilenced: "Tento používateľ je umlčaný."
+yourAccountSuspendedTitle: "Tento účet je zmrazený"
+yourAccountSuspendedDescription: "Tento účet bol zmrazený, lebo porušoval zmluvné podmienky. Kontaktujte administrátora ak chcete viac podrobností. Prosím nevytvárajte nový účet."
+menu: "Menu"
+divider: "Oddeľovač"
+addItem: "Pridať položku"
+relays: "Prenos"
+addRelay: "Pridať prenos"
+inboxUrl: "Inbox URL"
+addedRelays: "Pridané prenosy"
+serviceworkerInfo: "Musí byť zapnuté pre push notifikácie."
+deletedNote: "Odstránené príspevky"
+invisibleNote: "Skryté príspevky"
+enableInfiniteScroll: "Zapnúť nekonečné skrolovanie"
+visibility: "Viditeľnosť"
+poll: "Hlasovanie"
+useCw: "Skryť obsah"
+enablePlayer: "Otvoriť video prehrávač"
+disablePlayer: "Zavrieť video prehrávač"
+expandTweet: "Rozšíriť tweet"
+themeEditor: "Editor tém"
+description: "Popis"
+describeFile: "Pridať nadpis"
+enterFileDescription: "Zadajte nadpis"
+author: "Autor"
+leaveConfirm: "Máte neuložené zmeny. Chcete ich zahodiť?"
+manage: "Administrácia"
+plugins: "Pluginy"
+deck: "Deck"
+useBlurEffectForModal: "Použiť efekt rozmazania na okná"
+useFullReactionPicker: "Použiť plnú veľkosť výberu reakcií"
+width: "Šírka"
+height: "Výška"
+large: "Veľké"
+medium: "Stredné"
+small: "Malé"
+generateAccessToken: "Vygenerovať prístupový token"
+permission: "Oprávnenia"
+enableAll: "Povoliť všetko"
+disableAll: "Vypnúť všetko"
+tokenRequested: "Povoliť prístup k účtu"
+pluginTokenRequestedDescription: "Tento plugin bude môcť používať oprávnenia nastavené tu."
+notificationType: "Typ oznámenia"
+edit: "Upraviť"
+useStarForReactionFallback: "Použiť ★ keď emoji reakcie nie je známe"
+emailServer: "Email server"
+enableEmail: "Zapnúť email"
+emailConfigInfo: "Používa sa na overenie emaily pri registrácii alebo pri zabudnutí hesla"
+email: "Email"
+emailAddress: "Emailová adresa"
+smtpConfig: "Nastavenia SMTP servera"
+smtpHost: "Host"
+smtpPort: "Port"
+smtpUser: "Meno používateľa"
+smtpPass: "Heslo"
+emptyToDisableSmtpAuth: "Vynechaním mena hesla vypnete SMTP verifikáciu"
+smtpSecure: "Použiť implicitné SSL/TLS pre SMTP spojenia"
+smtpSecureInfo: "Toto vypnite keď používate STARTTLS"
+testEmail: "Doručenie testovacieho emailu"
+wordMute: "Stíšenie slova"
+instanceMute: "Stíšené servery"
+userSaysSomething: "{name} niečo povedal/a"
+makeActive: "Aktivovať"
+display: "Zobraziť"
+copy: "Kopírovať"
+metrics: "Metriky"
+overview: "Prehľad"
+logs: "Logy"
+delayed: "Oneskorené"
+database: "Databáza"
+channel: "Kanály"
+create: "Vytvoriť"
+notificationSetting: "Nastavenia oznámení"
+notificationSettingDesc: "Vyberte typ oznámení na zobrazenie"
+useGlobalSetting: "Použiť globálne nastavenie"
+useGlobalSettingDesc: "Ak je zapnuté, použijú sa oznámenia vášho účtu. Ak je vypnuté, použijú sa jednotlivé nastavenia."
+other: "Ostatní"
+regenerateLoginToken: "Pregenerovať prihlasovací token"
+regenerateLoginTokenDescription: "Pregeneruje token interne používaný počas prihlásenia. Normálne toto netreba robiť. Ak sa pregeneruje, všetky zariadenia sa odhlásia."
+setMultipleBySeparatingWithSpace: "Viaceré položky oddeľte medzerami."
+fileIdOrUrl: "ID alebo URL súboru"
+behavior: "Správanie"
+sample: "Ukážka"
+abuseReports: "Nahlásenia"
+reportAbuse: "Nahlásiť"
+reportAbuseOf: "Nahlásiť {name}"
+fillAbuseReportDescription: "Prosím vyplňte podrobnosti nahlásenia. Ak sa týka konkrétnej poznámky, prosím napíšte jej URL."
+abuseReported: "Vaše nahlásenie je odoslané. Veľmi pekne ďakujeme."
+reporter: "Nahlásil"
+reporteeOrigin: "Pôvod nahláseného"
+reporterOrigin: "Pôvod nahlasovača"
+forwardReport: "Preposlať nahlásenie na server"
+forwardReportIsAnonymous: "Namiesto vášho účtu bude zobrazený anonymný systémový účet na vzdialenom serveri ako autor nahlásenia."
+send: "Poslať"
+abuseMarkAsResolved: "Označiť nahlásenia ako vyriešené"
+openInNewTab: "Otvoriť v novom tabe"
+openInSideView: "Otvoriť v bočnom paneli"
+defaultNavigationBehaviour: "Predvolené správanie navigácie"
+editTheseSettingsMayBreakAccount: "Úpravou týchto nastavení si môžete pokaziť účet."
+instanceTicker: "Informácie servera o poznámkach"
+waitingFor: "Čaká sa na {x}"
+random: "Náhodné"
+system: "Systém"
+switchUi: "Prepnúť UI"
+desktop: "Desktop"
+clip: "Klip"
+createNew: "Vytvoriť nový"
+optional: "Voliteľné"
+createNewClip: "Vytvoriť nový klip"
+public: "Verejné"
+i18nInfo: "Misskey je prekladaný do rôznych jazykov dobrovoľníkmi. Pomôcť môžete na {link}."
+manageAccessTokens: "Spravovať prístupové tokeny"
+accountInfo: "Informácie o účte"
+notesCount: "Počet poznámok"
+repliesCount: "Počet odoslaných odpovedí"
+renotesCount: "Počet preposlaných poznámok"
+repliedCount: "Počet odpovedí prijatých"
+renotedCount: "Počet preposlaní prijatých"
+followingCount: "Počet sledovaných účtov"
+followersCount: "Počet sledujúcich"
+sentReactionsCount: "Počet poslaných reakcií"
+receivedReactionsCount: "Počet prijatých reakcií"
+pollVotesCount: "Počet odoslaných hlasov"
+pollVotedCount: "Počet prijatých hlasov"
+yes: "Áno"
+no: "Nie"
+driveFilesCount: "Počet súborov na disku"
+driveUsage: "Využité miesto na disku"
+noCrawle: "Odmietať indexovanie crawlerov"
+noCrawleDescription: "Požiadať vyhľadávače, aby neindexovali váš profil, poznámky, stránky, atď."
+lockedAccountInfo: "Pokým nenastavíte viditeľnosť poznámok na \"Len pre sledujúcich\", vaše príspevky bude vidieť hocikto, aj keď vyžadujete manuálne potvrdenie sledovania."
+alwaysMarkSensitive: "Predvolene označovať ako NSFW"
+loadRawImages: "Načítať originálne obrázky namiesto miniatúr"
+disableShowingAnimatedImages: "Neprehrávať animované obrázky"
+verificationEmailSent: "Odoslali sme overovací email. Overenie dokončíte kliknutím na odkaz v emaili."
+notSet: "Nenastavené"
+emailVerified: "Email overený"
+noteFavoritesCount: "Počet obľúbených poznámok"
+pageLikesCount: "Počet obľúbených stránok"
+pageLikedCount: "Počet prijatých \"páči sa mi\""
+contact: "Kontakt"
+useSystemFont: "Použiť predvolené systémové písmo"
+clips: "Klip"
+experimentalFeatures: "Experimentálne funkcie"
+developer: "Vývojár"
+makeExplorable: "Spraviť účet viditeľný v \"Objavovať\""
+makeExplorableDescription: "Ak toto vypnete, váš účet sa nezobrazí v sekcii \"Objavovat\"."
+showGapBetweenNotesInTimeline: "Zobraziť medzeru medzi príspevkami časovej osi."
+duplicate: "Duplikovať"
+left: "Naľavo"
+center: "Stred"
+wide: "Å iroko"
+narrow: "Úzko"
+reloadToApplySetting: "Toto nastavenia sa prejaví až po obnovení stránky. Obnoviť teraz?"
+needReloadToApply: "Toto nastavenie sa prejaví až po obnovení stránky."
+showTitlebar: "Zobraziť riadok s nadpisom"
+clearCache: "Vyprázdniť cache"
+onlineUsersCount: "{n} používateľov je online"
+nUsers: "{n} používateľov"
+nNotes: "{n} poznámok"
+sendErrorReports: "Poslať nahlásenie chyby"
+sendErrorReportsDescription: "Keď je zapnuté, v prípade problému sa odošlú podrobné informácie o chybe do Misskey. Pomôžete tak zvýšiť kvalitu Misskey.\nTieto informácie zahŕňajú verziu vášho OS, použitý prehliadač, históriu aktivít, atď."
+myTheme: "Moja téma"
+backgroundColor: "Pozadie"
+accentColor: "Akcent"
+textColor: "Text"
+saveAs: "Uložiť ako..."
+advanced: "Rozšírené"
+value: "Hodnoty"
+createdAt: "Vytvorené"
+updatedAt: "Upravené"
+saveConfirm: "Uložiť zmeny?"
+deleteConfirm: "Naozaj odstrániť?"
+invalidValue: "Nesprávna hodnota."
+registry: "Register"
+closeAccount: "Zavrieť účet"
+currentVersion: "Aktuálna verzia"
+latestVersion: "Najnovšia verzia"
+youAreRunningUpToDateClient: "Používate najnovšiu verziu vášho klienta."
+newVersionOfClientAvailable: "Je dostupná novšia verzia vášho klienta."
+usageAmount: "Využitie"
+capacity: "Kapacita"
+inUse: "Použité"
+editCode: "Upraviť kód"
+apply: "Použiť"
+receiveAnnouncementFromInstance: "Prijať notifikácie z tohoto servera"
+emailNotification: "Emailové upozornenia"
+publish: "Zverejniť"
+inChannelSearch: "Hľadať v kanáli"
+useReactionPickerForContextMenu: "Otvoriť výber reakcií na pravý klik"
+typingUsers: "{users} píše/u"
+jumpToSpecifiedDate: "Skočiť na konkrétny dátum"
+showingPastTimeline: "Práve vidíte starú časovú os"
+clear: "Vrátiť"
+markAllAsRead: "Označiť všetko ako prečítané"
+goBack: "Späť"
+unlikeConfirm: "Naozaj odstrániť váš like?"
+fullView: "Plný pohľad"
+quitFullView: "Zavrieť plný pohľad"
+addDescription: "Pridať popis"
+userPagePinTip: "Tu môžete zobraziť poznámky zvolením \"Pripnúť na profil\" z menu jednotlivých poznámok."
+notSpecifiedMentionWarning: "Táto poznámka obsahuje spomenutých používateľov, ktorí nie sú medzi adresátmi."
+info: "Informácie"
+userInfo: "Informácie o používateľovi"
+unknown: "Neznáme"
+onlineStatus: "Online status"
+hideOnlineStatus: "Skryť online status"
+hideOnlineStatusDescription: "Skrytie vášho online statusu zníži pohodlnosť niektorých funkcií ako napríklad vyhľadávanie."
+online: "Online"
+active: "Aktívny"
+offline: "Offline"
+notRecommended: "Neodporúčané"
+botProtection: "Bot ochrana"
+instanceBlocking: "Blokované servery"
+selectAccount: "Vyberte účet"
+switchAccount: "Prepnút účet"
+enabled: "Zapnuté"
+disabled: "Vypnuté"
+quickAction: "Rýchle akcie"
+user: "Používatelia"
+administration: "Spravovanie"
+accounts: "Účty"
+switch: "Prepnúť"
+noMaintainerInformationWarning: "Informácie správcu nie sú nastavené."
+noBotProtectionWarning: "Ochrana proti botom nie je nastavená."
+configure: "Konfigurovať"
+postToGallery: "Vytvoriť nový príspevok v galérii"
+gallery: "Galéria"
+recentPosts: "Najnovšie príspevky"
+popularPosts: "Populárne príspevky"
+shareWithNote: "Zdieľať s poznámkou"
+ads: "Reklamy"
+expiration: "Ukončiť hlasovanie"
+memo: "Memo"
+priority: "Priorita"
+high: "Vysoká"
+middle: "Stredné"
+low: "Málo"
+emailNotConfiguredWarning: "Nie je nastavená emailová adresa."
+ratio: "Pomer"
+previewNoteText: "Zobraziť náhľad"
+customCss: "Vlastné CSS"
+customCssWarn: "Toto nastavenie by sa malo používať iba ak viete čo robíte. Zadanie nesprávnych hodnôt môže spôsobiť nenormálne správanie klienta."
+global: "Globálne"
+squareAvatars: "Zobrazovať štvorcové avatary"
+sent: "Poslať"
+received: "Prijaté"
+searchResult: "Výsledky hľadania"
+hashtags: "Hashtagy"
+troubleshooting: "Riešenie problémov"
+useBlurEffect: "Používať efekty rozmazania v UI"
+learnMore: "Zistiť viac"
+misskeyUpdated: "Misskey sa aktualizoval!"
+whatIsNew: "Čo je nové?"
+translate: "Preložiť"
+translatedFrom: "Preložené z {x}"
+accountDeletionInProgress: "Odstraňovanie účtu prebieha"
+usernameInfo: "Meno, ktoré odlišuje váš účet od ostatných na tomto serveri. Môžete použiť abecedu (a~z, A~Z), čísla (0~9) alebo podtržník (_). Používateľské mená sa nedajú neskôr zmeniť."
+aiChanMode: "Ai režim"
+keepCw: "Nechať varovania obsahu"
+pubSub: "Pub/Sub účty"
+lastCommunication: "Posledná komunikácia"
+resolved: "Vyriešené"
+unresolved: "Nevyriešené"
+breakFollow: "Nesledovať"
+itsOn: "Zapnuté"
+itsOff: "Vypnuté"
+emailRequiredForSignup: "Registrácia vyžaduje emailovú adresu"
+unread: "Neprečítané"
+filter: "Filter"
+controlPanel: "Ovládací panel"
+manageAccounts: "Správa účtov"
+makeReactionsPublic: "Reakcie sú verejné"
+makeReactionsPublicDescription: "Toto spraví všetky vaše minulé reakcie viditeľné verejnosti."
+classic: "Klasika"
+muteThread: "Ztíšiť vlákno"
+unmuteThread: "Zrušiť stíšenie vlákna"
+ffVisibility: "Viditeľnosť sledujúcich/sledovaných"
+ffVisibilityDescription: "Umožňuje nastaviť kto vidí koho sledujete a kto vás sleduje."
+continueThread: "Zobraziť pokračovanie vlákna"
+deleteAccountConfirm: "Toto nezvrátiteľne vymaže váš účet. Pokračovať?"
+incorrectPassword: "Nesprávne heslo."
+voteConfirm: "Potvrdzujete svoj hlas za \"{choice}\"?"
+hide: "Skryť"
+leaveGroup: "Opustiť skupiny"
+leaveGroupConfirm: "Naozaj chcete opustiť \"{name}\"?"
+useDrawerReactionPickerForMobile: "Zobraziť výber reakcií ako šuflík na mobile"
+welcomeBackWithName: "Vitajte späť, {name}"
+clickToFinishEmailVerification: "Kliknutím na [{ok}] dokončíte overeniu emailu."
+overridedDeviceKind: "Typ zariadenia"
+smartphone: "Smartfón"
+tablet: "Tablet"
+auto: "Automaticky"
+_emailUnavailable:
+  used: "Táto emailová adresa sa už používa"
+  format: "Formát emailovej adresy je nesprávny"
+  disposable: "Jednorázové emailové adresy sa nemôžu používať."
+  mx: "Tento emailový server nefunguje."
+  smtp: "Tento emailový server neodpovedá."
+_ffVisibility:
+  public: "Zverejniť"
+  followers: "Len viditeľní sledujúci"
+  private: "Súkromné"
+_signup:
+  almostThere: "Skoro na konci"
+  emailAddressInfo: "Prosím zadajte svoju emailovú adresu!"
+  emailSent: "Na vašu emailovú adresu ({email}) sme odoslali email. Vytvorenie účtu dokončíte kliknutím na odkaz v emaili."
+_accountDelete:
+  accountDelete: "Odstrániť účet"
+  mayTakeTime: "Keďže odstránenie účtu je náročný proces, môže to nejaký čas trvať. Záleží koľko obsahu ste vytvorili a koľko súborov ste nahrali."
+  sendEmail: "Po odstránení účtu vám pošleme email na emailovú adresu zadanú pri registrácii tohoto účtu."
+  requestAccountDelete: "Požiadať o zmazanie účtu"
+  started: "Odstraňovanie začalo."
+  inProgress: "Odstraňovanie prebieha"
+_ad:
+  back: "Späť"
+  reduceFrequencyOfThisAd: "Túto reklamu zobrazovať menej"
+_forgotPassword:
+  enterEmail: "Zadajte emailovú adresu, ktorú ste použili pri registrácii. Pošleme vám na ňu odkaz, cez ktorý si môžete obnoviť heslo."
+  ifNoEmail: "Ak ste pri registrácii nepoužili email, prosím kontaktujte administrátora."
+  contactAdmin: "Tento server nepodporuje používanie emailových adries, prosím kontaktuje administrátor, ktorý vám resetuje heslo."
+_gallery:
+  my: "Moja galéria"
+  liked: "Obľúbené príspevky"
+  like: "Páči sa mi"
+  unlike: "Nepáči sa mi"
+_email:
+  _follow:
+    title: "Máte nového sledujúceho"
+  _receiveFollowRequest:
+    title: "Dostali ste žiadosť o sledovanie"
+_plugin:
+  install: "Inštalova pluginy"
+  installWarn: "Prosím neinštalujte nedôveryhodné pluginy."
+  manage: "Spravovanie pluginov"
+_registry:
+  scope: "Oblasť"
+  key: "Kľúč"
+  keys: "Kľúče"
+  domain: "Doména"
+  createKey: "Vytvoriť kľúč"
+_aboutMisskey:
+  about: "Misskey je open-source softvér, ktorý vyvíja syuilo od 2014."
+  contributors: "Hlavní prispievatelia"
+  allContributors: "VÅ¡etci prispievatelia"
+  source: "Zdrojový kód"
+  translation: "Preložiť Misskey"
+  donate: "Podporiť Misskey"
+  morePatrons: "Takisto oceňujeme podporu mnoých ďalších, ktorí tu nie sú uvedení. Ďakujeme! 🥰"
+  patrons: "Prispievatelia"
+_nsfw:
+  respect: "Skryť NSFW médiá"
+  ignore: "Neskrývať NSFW médiá"
+  force: "Skryť všetky médiá"
+_mfm:
+  cheatSheet: "MFM Cheatsheet"
+  intro: "MFM je Misskey exkluzívny značkovací jazyk, ktorý sa dá používať na viacerých miestach. Tu môžete vidieť zoznam všetkej dostupnej MFM syntaxe."
+  dummy: "Misskey rozširuje svet Fediverza"
+  mention: "Zmienka"
+  mentionDescription: "Používateľa spomeniete použítím zavináča a mena používateľa"
+  hashtag: "Hashtag"
+  hashtagDescription: "Môžete zadať hashtag použitím mriežky a textu"
+  url: "URL"
+  urlDescription: "URL sa dajú zobraziť."
+  link: "Odkaz"
+  linkDescription: "Jednotlivé časti texty sa dajú zobraziť ako URL."
+  bold: "Tučné"
+  boldDescription: "Zvýrazní písmená tým, že budú tučnejšie."
+  small: "Malé"
+  smallDescription: "Zobrazí obsah malý a tenký."
+  center: "Vystrediť prvky"
+  centerDescription: "Zobrazí obsah v strede"
+  inlineCode: "Kód (inline)"
+  inlineCodeDescription: "Zobrazí kód so zvýraznením syntaxe."
+  blockCode: "Kód (blok)"
+  blockCodeDescription: "Zobrazí viacriadkový kód so zvýraznením syntaxe v bloku."
+  inlineMath: "Vzorec (inline)"
+  inlineMathDescription: "Zobrazí matematický vzorec (KaTeX) v riadku."
+  blockMath: "Vzorec (blok)"
+  blockMathDescription: "Zobrazí viacriadkový matematický vzorec (KaTeX) v bloku"
+  quote: "Citovať"
+  quoteDescription: "Zobrazí obsah ako citát."
+  emoji: "Vlastné emoji"
+  emojiDescription: "Pridaním dvojbodiek pred a za názov vlastnej emoji, sa dá zobraziť vlastná emoji."
+  search: "Hľadať"
+  searchDescription: "Zobrazí vyhľadávacie pole so zadaným textom."
+  flip: "Preklopiť"
+  flipDescription: "Preklopí obsah horizontálne alebo vertikálne"
+  jelly: "Animácia (želé)"
+  jellyDescription: "Obsah sa bude hýbať ako želé."
+  tada: "Animácia (tadá)"
+  tadaDescription: "Obsah sa bude hýbať ako Tada!"
+  jump: "Animácia (skok)"
+  jumpDescription: "Obsah skočí."
+  bounce: "Animácia (odraz)"
+  bounceDescription: "Obsah sa bude odrážať."
+  shake: "Animácia (trasenie)"
+  shakeDescription: "Obsah sa bude triasť."
+  twitch: "Animácia (myknutie)"
+  twitchDescription: "Obsahu dá animáciu silného trasenia."
+  spin: "Animácia (rotácia)"
+  spinDescription: "Obsahu pridá otáčajúcu animáciu."
+  x2: "Veľký"
+  x2Description: "Zobrazí obsah väčší."
+  x3: "Veľmi veľký"
+  x3Description: "Zobrazí obsah ešte väčší."
+  x4: "Neuveriteľne veľký"
+  x4Description: "Zobrazí obsah ešte viac veľký než veľmi veľký."
+  blur: "Rozmazanie"
+  blurDescription: "Týmto efektom môže byť obsah rozmazaný. Zaostrí sa keď ned neho príde kurzor."
+  font: "Písmo"
+  fontDescription: "Nastaví písmo, ktorým sa zobrazí text."
+  rainbow: "Dúha"
+  rainbowDescription: "Zobrazí obsah vo farbách dúhy."
+  sparkle: "Trblietky"
+  sparkleDescription: "Obsahu dodá trblietajúci efekt."
+  rotate: "Otáčať"
+  rotateDescription: "Otočí obsah o určitý uhol."
+_instanceTicker:
+  none: "Nikdy nezobrazovať"
+  remote: "Zobraziť pre vzdialených používateľov"
+  always: "Zobraziť vždy"
+_serverDisconnectedBehavior:
+  reload: "Automaticky obnoviť"
+  dialog: "Zobraziť okno s varovaním"
+  quiet: "Zobraziť nerušivé varovanie"
+_channel:
+  create: "Vytvoriť kanál"
+  edit: "Upraviť kanál"
+  setBanner: "Nastaviť banner"
+  removeBanner: "Odstrániť banner"
+  featured: "Trendy"
+  owned: "Vlastnené"
+  following: "Sledované"
+  usersCount: "{n} účastníkov"
+  notesCount: "{n} poznámok"
+_menuDisplay:
+  sideFull: "Strana"
+  sideIcon: "Strana (Ikony)"
+  top: "Hore"
+  hide: "Skryť"
+_wordMute:
+  muteWords: "Umlčané slová"
+  muteWordsDescription: "Medzerami oddeľte pre podmienku AND a novými riadkami pre podmienku OR."
+  muteWordsDescription2: "Regulárne výrazy sa použijú keď použijete okolo lomítka."
+  softDescription: "Skryje poznámky z časovej osi, ktoré spĺňajú podmienky."
+  hardDescription: "Zabráni poznámky spĺňajúce množinu podmienok, aby boli pridané do časovej osi. Navyše tieto poznámky nepribudnú v časovej osi ani keď sa podmienky zmenia."
+  soft: "Mäkké"
+  hard: "Tvrdé"
+  mutedNotes: "Umlčané poznámky"
+_instanceMute:
+  instanceMuteDescription: "Toto umlčí všetky poznámky/preposlania zo zoznamu serverov, vrátane tých, na ktoré používatelia odpovedajú z umlčaného servera."
+  instanceMuteDescription2: "Oddeľte novými riadkami"
+  title: "Skryje poznámky z uvedených serverov."
+  heading: "Zoznam umlčaných inštancií"
+_theme:
+  explore: "Objavovať témy"
+  install: "Nainštalovať tému"
+  manage: "Spravovať témy"
+  code: "Kód témy"
+  description: "Popis"
+  installed: "{name} je nainštalovaná"
+  installedThemes: "Nainštalované témy"
+  builtinThemes: "Vstavané témy"
+  alreadyInstalled: "Táto téma je už nainštalovaná"
+  invalid: "Formát tejto témy je nesprávny"
+  make: "Vytvoriť tému"
+  base: "Základ"
+  addConstant: "Pridať konštantu"
+  constant: "Konštanta"
+  defaultValue: "Predvolená hodnota"
+  color: "Farba"
+  refProp: "Odkaz na vlastnosť"
+  refConst: "Odkaz na konštantu"
+  key: "Kľúč"
+  func: "Funkcie"
+  funcKind: "Typ funkcie"
+  argument: "Argument"
+  basedProp: "Odkazovaná vlastnosť"
+  alpha: "Priehľadnosť"
+  darken: "Stmaviť"
+  lighten: "Zosvetliť"
+  inputConstantName: "Zadajte názov tejto konštanty"
+  importInfo: "Ak sem zadáte kód témy, môžete ju importovať do editora tém."
+  deleteConstantConfirm: "Naozaj chcete odstrániť konštantu {const}?"
+  keys:
+    accent: "Akcent"
+    bg: "Pozadie"
+    fg: "Text"
+    focus: "Fokus"
+    indicator: "Indikátor"
+    panel: "Panel"
+    shadow: "Tieň"
+    header: "Hlavička"
+    navBg: "Pozadie bočného panela"
+    navFg: "Text bočného panela"
+    navHoverFg: "Text bočného panela (pod kurzorom)"
+    navActive: "Text bočného panela (aktívny)"
+    navIndicator: "Indikátor bočného panela"
+    link: "Odkaz"
+    hashtag: "Hashtag"
+    mention: "Zmienka"
+    mentionMe: "Zmienky (mňa)"
+    renote: "Preposlať"
+    modalBg: "Pozadie modálu"
+    divider: "Oddeľovač"
+    scrollbarHandle: "Rúčka scrollbaru"
+    scrollbarHandleHover: "Rúčka scrollbaru (pod kurzorom)"
+    dateLabelFg: "Text dátového popisku"
+    infoBg: "Pozadie informácií"
+    infoFg: "Informačný text"
+    infoWarnBg: "Pozadie varovania"
+    infoWarnFg: "Text varovania"
+    cwBg: "CW pozadie tlačidla"
+    cwFg: "CW text tlačidla"
+    cwHoverBg: "CW pozadie tlačidla (pod kurzorom)"
+    toastBg: "Pozadie upozornenia"
+    toastFg: "Text upozornenia"
+    buttonBg: "Pozadie tlačidla"
+    buttonHoverBg: "Pozadie tlačidla (pod kurzorom)"
+    inputBorder: "Okraj vstupného poľa"
+    listItemHoverBg: "Pozadie položky zoznamu (pod kurzorom)"
+    driveFolderBg: "Pozadie priečinu disku"
+    wallpaperOverlay: "Vrstvenie pozadia"
+    badge: "Odznak"
+    messageBg: "Pozadie chatu"
+    accentDarken: "Akcent (stmavené)"
+    accentLighten: "Akcent (zosvetlené)"
+    fgHighlighted: "Zvýraznený text"
+_sfx:
+  note: "Poznámky"
+  noteMy: "Vlastná poznámka"
+  notification: "Oznámenia"
+  chat: "Chat"
+  chatBg: "Chat (pozadie)"
+  antenna: "Antény"
+  channel: "Upozornenia kanála"
+_ago:
+  unknown: "Neznáme"
+  future: "Budúcnosť"
+  justNow: "Teraz"
+  secondsAgo: "pred {n} sekundami"
+  minutesAgo: "pred {n} minútami"
+  hoursAgo: "pred {n} hodinami"
+  daysAgo: "pred {n} dňami"
+  weeksAgo: "pred {n} týždňami"
+  monthsAgo: "pred {n} mesiacmi"
+  yearsAgo: "pred {n} rokmi"
+_time:
+  second: "s"
+  minute: "min"
+  hour: "hod"
+  day: "dní"
+_tutorial:
+  title: "Ako používať Misskey"
+  step1_1: "Vitajte!"
+  step1_2: "Táto stránka sa volá \"časová os\". Zobrazuje chronologicky zoradené \"poznámky\" od ľudí, ktorých sledujete."
+  step1_3: "Vaša časová os je teraz prázdna pretože ste nepridali žiadne poznámky ani nikoho zatiaľ nesledujete."
+  step2_1: "Podˇme dokončiť nastavenia vášho profilu pred napísaním poznámky alebo sledovaním niekoho."
+  step2_2: "Poskytnutím informácií o vás uľahčíte ostatným, či chcú vidieť alebo sledovať vaše poznámky."
+  step3_1: "Dokončili ste nastavovanie svojho profilu?"
+  step3_2: "Poďme vyskúšať napísať poznámku. Môžete to spraviť stlačením ikony ceruzky na vrchu obrazovky."
+  step3_3: "Vyplňte polia a stlačte tlačítko vpravo hore."
+  step3_4: "Nemáte čo povedať? Skúste \"len si nastavujem môj msky\"!"
+  step4_1: "Napísali ste svoju prvú poznámku?"
+  step4_2: "Hurá! Teraz by vaša prvá poznámka mala byť na vašej časovej osi."
+  step5_1: "Teraz skúsme oživiť časovú os sledovaním nejakých ľudí."
+  step5_2: "{featured} zobrazí populárne poznámku na tomto serveri. {explore} môžete objavovať populárnych používateľov. Skúste tam nájsť ľudí, ktorých by ste radi sledovali!"
+  step5_3: "Ak chcete sledovať ďalších používateľov, kliknite na ich ikonu a stlačte tlačidlo \"Sledovať\" na ich profile."
+  step5_4: "Ak má niektorý používateľ ikonu zámku vedľa svojho mena, znamená to, že môže trvať určitý čas, kým daný používateľ schváli vašu žiadosť o sledovanie."
+  step6_1: "Teraz by ste mali vidieť poznámky ďalších používateľov na svojej časovej osi."
+  step6_2: "Môžete dať \"reakcie\" na poznámky ďalších ľudí ako rýchlu odpoveď."
+  step6_3: "Reakciu pridáte kliknutím na \"+\" niekoho poznámke a vybratím emoji, ktorou chcete reagovať."
+  step7_1: "Gralujeme! Dokončili ste základného sprievodcu Misskey."
+  step7_2: "Ak sa chcete naučiť viac o Misskey, skúste sekciu {help}."
+  step7_3: "A teraz, veľa šťastia, bavte sa s Misskey! 🚀"
+_2fa:
+  alreadyRegistered: "Už ste zaregistrovali 2-faktorové autentifikačné zariadenie."
+  registerDevice: "Registrovať nové zariadenie"
+  registerKey: "Registrovať bezpečnostný kľúč"
+  step1: "Najprv si nainštalujte autentifikačnú aplikáciu (napríklad {a} alebo {b}) na svoje zariadenie."
+  step2: "Potom, naskenujte QR kód zobrazený na obrazovke."
+  step3: "Nastavenie dokončíte zadaním tokenu z vašej aplikácie."
+  step4: "Od teraz, všetky ďalšie prihlásenia budú vyžadovať prihlasovací token."
+  securityKeyInfo: "Okrem odtlačku prsta alebo PIN autentifikácie si môžete nastaviť autentifikáciu cez hardvérový bezpečnostný kľúč podporujúci FIDO2 a tak ešte viac zabezpečiť svoj účet."
+_permissions:
+  "read:account": "Vidieť informácie o vašom účte"
+  "write:account": "Upraviť informácie o vašom účte"
+  "read:blocks": "Vidieť zoznam blokovaných používateľov"
+  "write:blocks": "Upraviť zoznam blokovaných používateľov"
+  "read:drive": "Prístup k súborom a priečinkom na disku"
+  "write:drive": "Upraviť alebo odstrániť súbory a priečinky na disku"
+  "read:favorites": "Vidieť váš zoznam obľúbených"
+  "write:favorites": "Upraviť váš zoznam obľúbených"
+  "read:following": "Vidieť koho sledujete"
+  "write:following": "Sledovať alebo nesledovať ďalšie účty"
+  "read:messaging": "Vidieť vaše chaty"
+  "write:messaging": "Písať alebo odstraňovať správy v chate"
+  "read:mutes": "Vidieť váš zoznam stíšených používateľov"
+  "write:mutes": "Upravovať zoznam stíšených používateľov"
+  "write:notes": "Písať alebo odstrániť poznámky"
+  "read:notifications": "Vidieť vaše oznámenia"
+  "write:notifications": "Pracovať s vašimi notifikáciami"
+  "read:reactions": "Vidieť vaše reakcie"
+  "write:reactions": "Upravovať vaše reakcie"
+  "write:votes": "Hlasovať v hlasovaniach"
+  "read:pages": "Vidieť vaše stránky"
+  "write:pages": "Upraviť alebo odstrániť vaše stránky"
+  "read:page-likes": "Vidieť vaše páčiky na stránkach"
+  "write:page-likes": "Upraviť páčiky na stránkach"
+  "read:user-groups": "Vidieť vaše skupiny"
+  "write:user-groups": "Upraviť alebo odstrániť vaše skupiny"
+  "read:channels": "Čítať vaše kanály"
+  "write:channels": "Upravovať vaše kanály"
+  "read:gallery": "Vidieť vašu galériu"
+  "write:gallery": "Upravovať vašu galériu"
+  "read:gallery-likes": "Vidieť zoznam obľúbených príspevkov z galérie"
+  "write:gallery-likes": "Upraviť zoznam obľúbených príspevov z galérie"
+_auth:
+  shareAccess: "Prajete si povoliť \"{name}\", aby mal prístup k tomuto účtu?"
+  shareAccessAsk: "Naozaj chcete povoliť tejto aplikácii prístup k tomuto účtu?"
+  permissionAsk: "Táto aplikácia vyžaduje nasledujúce nastavenia"
+  pleaseGoBack: "Prosím prejdite späť na aplikáciu"
+  callback: "Vraciam sa späť na aplikáciu"
+  denied: "Prístup zamietnutý"
+_antennaSources:
+  all: "Všetky poznámky"
+  homeTimeline: "Poznámky od sledovaného používateľa"
+  users: "Poznámky od konkrétneho používateľa"
+  userList: "Poznámky od používateľov v zozname"
+  userGroup: "Poznámky od používateľov z konkrétnej skupiny."
+_weekday:
+  sunday: "Nedeľa"
+  monday: "Pondelok"
+  tuesday: "Utorok"
+  wednesday: "Streda"
+  thursday: "Å tvrtok"
+  friday: "Piatok"
+  saturday: "Sobota"
+_widgets:
+  memo: "Prilepené poznámky"
+  notifications: "Oznámenia"
+  timeline: "Časová os"
+  calendar: "Kalendár"
+  trends: "Trendy"
+  clock: "Hodiny"
+  rss: "RSS čítačka"
+  activity: "Aktivita"
+  photos: "Fotky"
+  digitalClock: "Digitálne hodiny"
+  federation: "Federácia"
+  postForm: "Napísať poznámku"
+  slideshow: "Prezentácia"
+  button: "Tlačidlo"
+  onlineUsers: "Online používatelia"
+  jobQueue: "Fronta úloh"
+  serverMetric: "Metriky servera"
+  aiscript: "Konzola AiScript"
+  aichan: "Ai"
+_cw:
+  hide: "Skryť"
+  show: "Zobraziť viac"
+  chars: "{count} znakov"
+  files: "{count} súbor/ov"
+_poll:
+  noOnlyOneChoice: "Treba aspoň dve voľby"
+  choiceN: "Voľba {n}"
+  noMore: "Nemôžete pridať viac volieb"
+  canMultipleVote: "Povoliť hlasovať za viac volieb."
+  expiration: "Ukončiť hlasovanie"
+  infinite: "Nikdy"
+  at: "Konkrétny dátum..."
+  after: "Ukončiť po..."
+  deadlineDate: "Dátum ukončenia"
+  deadlineTime: "hod"
+  duration: "Trvanie"
+  votesCount: "{n} hlasov"
+  totalVotes: "{n} hlasov celkom"
+  vote: "Hlasovať"
+  showResult: "Vidieť výsledky hlasovania"
+  voted: "Zahlasované"
+  closed: "Skončilo"
+  remainingDays: "zostáva {d} dní {h} hodín"
+  remainingHours: "zostáva {h} hodín {m} minút"
+  remainingMinutes: "zostáva {m} minút {s} sekúnd"
+  remainingSeconds: "zostáva {s} sekúnd"
+_visibility:
+  public: "Verejné"
+  publicDescription: "Vaša poznámku bude viditeľná všetkým používateľom"
+  home: "Domov"
+  homeDescription: "Pridať iba na domácu časovú os"
+  followers: "Sledujúci"
+  followersDescription: "Viditeľné iba tým, ktorí vás sledujú"
+  specified: "Priame"
+  specifiedDescription: "Viditeľné iba pre konkrétnych používateľov"
+  localOnly: "Iba lokálne"
+  localOnlyDescription: "Vzdialený používatelia nebudú vidieť"
+_postForm:
+  replyPlaceholder: "Odpoveď na túto poznámku..."
+  quotePlaceholder: "Citovanie tejto poznámky..."
+  channelPlaceholder: "Poslať do kanála..."
+  _placeholders:
+    a: "Čo máte v pláne?"
+    b: "ÄŒo sa deje?"
+    c: "O čom rozmýšľaš?"
+    d: "Čo chcete povedať?"
+    e: "Začnite písať..."
+    f: "Čaká sa na písanie..."
+_profile:
+  name: "Názov"
+  username: "Meno používateľa"
+  description: "Bio"
+  youCanIncludeHashtags: "Vo svojom bio môžete mať aj hashtagy."
+  metadata: "Dodatočné informácie"
+  metadataEdit: "Upraviť dodatočné informácie"
+  metadataDescription: "Vo svojom profile môžete uviesť až štyri dodatočné informačné polia."
+  metadataLabel: "Popisok"
+  metadataContent: "Obsah"
+  changeAvatar: "Zmeniť avatara"
+  changeBanner: "Zmeniť banner"
+_exportOrImport:
+  allNotes: "Všetky poznámky"
+  followingList: "Sledujete"
+  muteList: "Vypnúť zvuk"
+  blockingList: "Zablokovať"
+  userLists: "Zoznamy"
+  excludeMutingUsers: "Vylúčiť stíšených používateľov"
+  excludeInactiveUsers: "Vylúčiť neaktívnych používateľov"
+_charts:
+  federation: "Federácia"
+  apRequest: "Žiadosti"
+  usersIncDec: "Rozdiel v počte používateľov"
+  usersTotal: "Celkový počet používateľov"
+  activeUsers: "Aktívni používatelia"
+  notesIncDec: "Rozdiel v počte poznámok"
+  localNotesIncDec: "Rozdiel v počte lokálnych poznámok"
+  remoteNotesIncDec: "Rozdiel v počte vzdialených poznámok"
+  notesTotal: "Celkový počet poznámok"
+  filesIncDec: "Rozdiel v počte súborov"
+  filesTotal: "Celkový počet súborov"
+  storageUsageIncDec: "Rozdiel využitého úložiska"
+  storageUsageTotal: "Celkové využité úložisko"
+_instanceCharts:
+  requests: "Žiadosti"
+  users: "Rozdiel v počte používateľov"
+  usersTotal: "Celkom spolu počet používateľov"
+  notes: "Rozdiel v počte poznámok"
+  notesTotal: "Celkom spolu počet poznámok"
+  ff: "Rozdiel v počte sledovaných/sledujúcich"
+  ffTotal: "Celkom spolu počet sledovaných / sledujúcich"
+  cacheSize: "Rozdiel vo veľkosti cache"
+  cacheSizeTotal: "Celkom spolu veľkosť cache"
+  files: "Rozdiel v počte súborov"
+  filesTotal: "Celkom spolu počet súborov"
+_timelines:
+  home: "Domov"
+  local: "Lokálne"
+  social: "Sociálne"
+  global: "Globálne"
+_pages:
+  newPage: "Vytvoriť novú stránku"
+  editPage: "Upraviť túto stránku"
+  readPage: "Zobrazenie zdroja aktívne"
+  created: "Stránka úspešne vytvorená"
+  updated: "Stránka úspešne upravená"
+  deleted: "Stránka úspešne odstránená"
+  pageSetting: "Nastavenia stránky"
+  nameAlreadyExists: "Zadaná URL stránku už existuje"
+  invalidNameTitle: "Zadaná URL stránku je nesprávna"
+  invalidNameText: "Uistite sa, že nadpis stránky nie je prázdny"
+  editThisPage: "Upraviť túto stránku"
+  viewSource: "Ukázať zdroj"
+  viewPage: "Ukázať vaše stránky"
+  like: "Páči sa mi"
+  unlike: "Nepáči sa mi"
+  my: "Moje stránky"
+  liked: "Obľúbené stránky"
+  featured: "Význačné"
+  inspector: "Inšpektor"
+  contents: "Obsah"
+  content: "Blok stránky"
+  variables: "Premenné"
+  title: "Nadpis"
+  url: "URL stránky"
+  summary: "Zhrnutie stránky"
+  alignCenter: "Vystrediť prvky"
+  hideTitleWhenPinned: "Skryť nadpis stránky keď je pripnutá na profil"
+  font: "Písmo"
+  fontSerif: "Pätkové"
+  fontSansSerif: "Bezpätkové"
+  eyeCatchingImageSet: "Nastaviť miniatúru"
+  eyeCatchingImageRemove: "Odstrániť miniatúru"
+  chooseBlock: "Pridať blok"
+  selectType: "Vyberte typ"
+  enterVariableName: "Zadajte meno premennej"
+  variableNameIsAlreadyUsed: "Meno premennej s už používa"
+  contentBlocks: "Obsah"
+  inputBlocks: "Vstup"
+  specialBlocks: "Špeciálne"
+  blocks:
+    text: "Text"
+    textarea: "Textové pole"
+    section: "Sekcia"
+    image: "Obrázky"
+    button: "Tlačidlo"
+    if: "Ak"
+    _if:
+      variable: "Premenné"
+    post: "Napísať poznámku"
+    _post:
+      text: "Obsah"
+      attachCanvasImage: "Príspevok s obrázkom na plátne"
+      canvasId: "ID plátna"
+    textInput: "Textový vstup"
+    _textInput:
+      name: "Meno premennej"
+      text: "Nadpis"
+      default: "Predvolená hodnota"
+    textareaInput: "Viacriadkový textový vstup"
+    _textareaInput:
+      name: "Meno premennej"
+      text: "Nadpis"
+      default: "Predvolená hodnota"
+    numberInput: "Číselný vstup"
+    _numberInput:
+      name: "Meno premennej"
+      text: "Nadpis"
+      default: "Predvolená hodnota"
+    canvas: "Plátno"
+    _canvas:
+      id: "ID plátna"
+      width: "Šírka"
+      height: "Výška"
+    note: "Vložená poznámka"
+    _note:
+      id: "ID poznámky"
+      idDescription: "Alebo môžete vložiť URL poznámky sem"
+      detailed: "Podrobný pohľad"
+    switch: "Prepnúť"
+    _switch:
+      name: "Meno premennej"
+      text: "Nadpis"
+      default: "Predvolená hodnota"
+    counter: "Počítadlo"
+    _counter:
+      name: "Meno premennej"
+      text: "Nadpis"
+      inc: "Pripočítať"
+    _button:
+      text: "Nadpis"
+      colored: "Farebné"
+      action: "Operácia po stlačení tlačidla"
+      _action:
+        dialog: "Zobraziť dialóg"
+        _dialog:
+          content: "Obsah"
+        resetRandom: "Resetovať zdroj náhodnosti"
+        pushEvent: "Poslať udalosť"
+        _pushEvent:
+          event: "Názov udalosti"
+          message: "Zobrazená správa po aktivácii"
+          variable: "Odoslaná premenná"
+          no-variable: "Žiadne"
+        callAiScript: "Spustiť AiScript"
+        _callAiScript:
+          functionName: "Názov funkcie"
+    radioButton: "Možnosť"
+    _radioButton:
+      name: "Meno premennej"
+      title: "Nadpis"
+      values: "Zoznam možností oddelené novými riadkami"
+      default: "Predvolená hodnota"
+  script:
+    categories:
+      flow: "Riadenie behu"
+      logical: "Logická operácia"
+      operation: "Výpočet"
+      comparison: "Porovnanie"
+      random: "Náhodné"
+      value: "Hodnoty"
+      fn: "Funkcie"
+      text: "Textové operácie"
+      convert: "Transformácie"
+      list: "Zoznamy"
+    blocks:
+      text: "Text"
+      multiLineText: "Text (viacriadkový)"
+      textList: "Zoznam textov"
+      _textList:
+        info: "Oddeľte každú položku novým riadkom"
+      strLen: "Dĺžka textu"
+      _strLen:
+        arg1: "Text"
+      strPick: "Vybrať znak"
+      _strPick:
+        arg1: "Text"
+        arg2: "Pozícia znaku"
+      strReplace: "Náhradný text"
+      _strReplace:
+        arg1: "Text"
+        arg2: "Nahradený text"
+        arg3: "Nahradiť s"
+      strReverse: "Otočiť text"
+      _strReverse:
+        arg1: "Text"
+      join: "Spojiť texty"
+      _join:
+        arg1: "Zoznamy"
+        arg2: "Oddeľovač"
+      add: "Pridať"
+      _add:
+        arg1: "A"
+        arg2: "B"
+      subtract: "Odčítať"
+      _subtract:
+        arg1: "A"
+        arg2: "B"
+      multiply: "Násobiť"
+      _multiply:
+        arg1: "A"
+        arg2: "B"
+      divide: "Deliť"
+      _divide:
+        arg1: "A"
+        arg2: "B"
+      mod: "Zvyšok po delení"
+      _mod:
+        arg1: "A"
+        arg2: "B"
+      round: "Zaokrúhliť"
+      _round:
+        arg1: "Číslo"
+      eq: "A a B sa rovnajú"
+      _eq:
+        arg1: "A"
+        arg2: "B"
+      notEq: "A a B sa nerovnajú"
+      _notEq:
+        arg1: "A"
+        arg2: "B"
+      and: "A a zároveň B"
+      _and:
+        arg1: "A"
+        arg2: "B"
+      or: "A alebo B"
+      _or:
+        arg1: "A"
+        arg2: "B"
+      lt: "< A je menšie ako B"
+      _lt:
+        arg1: "A"
+        arg2: "B"
+      gt: "> A je väčšie ako B"
+      _gt:
+        arg1: "A"
+        arg2: "B"
+      ltEq: "<= A je menšie alebo rovné B"
+      _ltEq:
+        arg1: "A"
+        arg2: "B"
+      gtEq: ">= A je väčšie alebo rovné B"
+      _gtEq:
+        arg1: "A"
+        arg2: "B"
+      if: "Vetva"
+      _if:
+        arg1: "Ak"
+        arg2: "Potom"
+        arg3: "Inak"
+      not: "Opak"
+      _not:
+        arg1: "Opak"
+      random: "Náhodné"
+      _random:
+        arg1: "Pravdepodobnosť"
+      rannum: "Náhodné číslo"
+      _rannum:
+        arg1: "Minimálna hodnota"
+        arg2: "Maximálna hodnota"
+      randomPick: "Náhodný výber zo zoznamu"
+      _randomPick:
+        arg1: "Zoznam"
+      dailyRandom: "Náhodne (zmení sa raz denne pre každého používateľa)"
+      _dailyRandom:
+        arg1: "Pravdepodobnosť"
+      dailyRannum: "Náhodné číslo (Mení sa denne pre každého používateľa)"
+      _dailyRannum:
+        arg1: "Minimálna hodnota"
+        arg2: "Maximálna hodnota"
+      dailyRandomPick: "Náhodný výber zo zoznamu (Mení sa denne pre každého používateľa)"
+      _dailyRandomPick:
+        arg1: "Zoznam"
+      seedRandom: "Náhodne (so seedom)"
+      _seedRandom:
+        arg1: "Seed"
+        arg2: "Pravdepodobnosť"
+      seedRannum: "Náhodné číslo (so seedom)"
+      _seedRannum:
+        arg1: "Seed"
+        arg2: "Minimálna hodnota"
+        arg3: "Maximálna hodnota"
+      seedRandomPick: "Náhodný výber zo zoznamu (so seedom)"
+      _seedRandomPick:
+        arg1: "Seed"
+        arg2: "Zoznam"
+      DRPWPM: "Náhodný výber z váženého zoznamu (Mení sa denne pre každého používateľa)"
+      _DRPWPM:
+        arg1: "Zoznam textov"
+      pick: "Vybrať zo zoznamu"
+      _pick:
+        arg1: "Zoznam"
+        arg2: "Pozícia"
+      listLen: "Získať dĺžku zoznamu"
+      _listLen:
+        arg1: "Zoznam"
+      number: "Číslo"
+      stringToNumber: "Text na číslo"
+      _stringToNumber:
+        arg1: "Text"
+      numberToString: "Číslo na text"
+      _numberToString:
+        arg1: "Číslo"
+      splitStrByLine: "Rozdelí text po riadkoch"
+      _splitStrByLine:
+        arg1: "Text"
+      ref: "Premenné"
+      aiScriptVar: "AiScript premenná"
+      fn: "Funkcie"
+      _fn:
+        slots: "Sloty"
+        slots-info: "Oddeľte každý slot novým riadkom"
+        arg1: "Výstup"
+      for: "For cyklus"
+      _for:
+        arg1: "Počet opakovaní"
+        arg2: "Akcia"
+    typeError: "Slot {slot} akceptuje hodnoty typu \"{expect}\", ale dodaná hodnota je typu \"{actual}\"!"
+    thereIsEmptySlot: "Slot {slot} je prázdny!"
+    types:
+      string: "Text"
+      number: "Číslo"
+      boolean: "Boolean"
+      array: "Zoznamy"
+      stringArray: "Zoznam textov"
+    emptySlot: "Prázdny slot"
+    enviromentVariables: "Premenné prostredia"
+    pageVariables: "Premenné stránky"
+    argVariables: "Vstupné sloty"
+_relayStatus:
+  requesting: "Čaká sa"
+  accepted: "Akceptované"
+  rejected: "Odmietnuté"
+_notification:
+  fileUploaded: "Súbor sa úspešne nahral"
+  youGotMention: "{name} vás spomenul/a"
+  youGotReply: "{name} vám odpovedal/a"
+  youGotQuote: "{name} vás citoval/a"
+  youRenoted: "{name} preposlal/a vašu poznámku"
+  youGotPoll: "{name} hlasoval/a"
+  youGotMessagingMessageFromUser: "{name} vám poslal/a správu"
+  youGotMessagingMessageFromGroup: "Prišla správa do skupiny {name}"
+  youWereFollowed: "Máte nového sledujúceho"
+  youReceivedFollowRequest: "Dostali ste žiadosť o sledovanie"
+  yourFollowRequestAccepted: "Vaša žiadosť o sledovanie bola prijatá"
+  youWereInvitedToGroup: "Pozvať do skupiny"
+  _types:
+    all: "VÅ¡etky"
+    follow: "Sledujete"
+    mention: "Zmienka"
+    reply: "Odpovede"
+    renote: "Preposlať"
+    quote: "Citovať"
+    reaction: "Reakcie"
+    pollVote: "Hlasy v hlasovaniach"
+    receiveFollowRequest: "Doručené žiadosti o sledovanie"
+    followRequestAccepted: "Schválené žiadosti o sledovanie"
+    groupInvited: "Pozvánky do skupín"
+    app: "Oznámenia z prepojených aplikácií"
+_deck:
+  alwaysShowMainColumn: "Vždy zobraziť v hlavnom stĺpci"
+  columnAlign: "Zarovnať stĺpce"
+  columnMargin: "Rozostup medzi stĺpcami"
+  columnHeaderHeight: "Výška hlavičky stĺpca"
+  addColumn: "Pridať stĺpec"
+  swapLeft: "Vymeniť vľavo"
+  swapRight: "Vymeniť vpravo"
+  swapUp: "Vymeniť hore"
+  swapDown: "Vymeniť s nasledujúcim"
+  stackLeft: "Priložiť do ľavého stĺpca"
+  popRight: "Vybrať napravo"
+  profile: "Profil"
+  _columns:
+    main: "Hlavný"
+    widgets: "Widgety"
+    notifications: "Oznámenia"
+    tl: "Časová os"
+    antenna: "Antény"
+    list: "Zoznam"
+    mentions: "Zmienky"
+    direct: "Priame poznámky"
diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml
index 2dd605601143fc1cd3c7a6d927b0529822720fa8..588df8d3256eceef096833cb39e1e3f81562a5e2 100644
--- a/locales/uk-UA.yml
+++ b/locales/uk-UA.yml
@@ -1038,7 +1038,8 @@ _exportOrImport:
   blockingList: "Заблокувати"
   userLists: "Списки"
 _charts:
-  federationInstancesTotal: "Загальна кількість федеративних інстансів"
+  federation: "Федіверс"
+  apRequest: "Запити"
   usersTotal: "Загальна кількість користувачів"
   activeUsers: "Активні користувачі"
   notesTotal: "Загальна кількість нотаток"
diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml
index c54e64214a652a1e48b20c0c7415216c2166c660..f4f1680caa112a544ab26823544082fd09f114a6 100644
--- a/locales/zh-CN.yml
+++ b/locales/zh-CN.yml
@@ -141,6 +141,8 @@ flagAsBot: "这是一个机器人账号"
 flagAsBotDescription: "如果此帐户由程序控制,请启用此项。启用后,此标志可以帮助其他开发人员防止机器人之间产生无限互动的行为,并让Misskey的内部系统将此帐户识别为机器人。"
 flagAsCat: "将这个账户设定为一只猫"
 flagAsCatDescription: "如果您想表明此帐户是一只猫,请打开此标志。"
+flagShowTimelineReplies: "在时间线上显示帖子的回复"
+flagShowTimelineRepliesDescription: "启用时,时间线除了显示用户的帖子外,还会显示其他用户对帖子的回复。"
 autoAcceptFollowed: "自动允许关注"
 addAccount: "添加账户"
 loginFailed: "登录失败"
@@ -822,6 +824,10 @@ leaveGroupConfirm: "确定离开「{name}」?"
 useDrawerReactionPickerForMobile: "在移动设备上使用抽屉显示"
 welcomeBackWithName: "欢迎回来,{name}"
 clickToFinishEmailVerification: "点击 [{ok}] 完成电子邮件地址认证。"
+overridedDeviceKind: "设备类型"
+smartphone: "智能手机"
+tablet: "平板"
+auto: "自动"
 _emailUnavailable:
   used: "已经被使用过"
   format: "无效的格式"
@@ -1258,8 +1264,8 @@ _exportOrImport:
   excludeMutingUsers: "排除屏蔽用户"
   excludeInactiveUsers: "排除不活跃用户"
 _charts:
-  federationInstancesIncDec: "联合:增加/减少"
-  federationInstancesTotal: "联合总数"
+  federation: "联合"
+  apRequest: "请求"
   usersIncDec: "用户数量:增加/减少"
   usersTotal: "用户总数"
   activeUsers: "活跃用户数"
diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml
index 798398a6a9021a341ba4ee5f469ec69e6c432552..b10871ec1d9440eb45b67e97ebaea2ad37e6244b 100644
--- a/locales/zh-TW.yml
+++ b/locales/zh-TW.yml
@@ -1114,6 +1114,8 @@ _exportOrImport:
   blockingList: "封鎖"
   userLists: "清單"
 _charts:
+  federation: "站台聯邦"
+  apRequest: "請求"
   usersIncDec: "使用者増減"
   usersTotal: "使用者合共"
   activeUsers: "活躍使用者"
diff --git a/package.json b/package.json
index 27fd81cd869f1e0267efe97dc18a878f85ddd326..46dac95db3b3c32193934a1dbd6162a522a840f3 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "misskey",
-	"version": "12.103.1",
+	"version": "12.104.0",
 	"codename": "indigo",
 	"repository": {
 		"type": "git",
@@ -46,7 +46,7 @@
 		"@types/fluent-ffmpeg": "2.1.20",
 		"@typescript-eslint/parser": "5.10.0",
 		"cross-env": "7.0.3",
-		"cypress": "9.3.1",
+		"cypress": "9.4.1",
 		"start-server-and-test": "1.14.0",
 		"typescript": "4.5.5"
 	}
diff --git a/packages/backend/migration/1629833361000-AddShowTLReplies.js b/packages/backend/migration/1629833361000-AddShowTLReplies.js
new file mode 100644
index 0000000000000000000000000000000000000000..bfd4ab7ff78259aed09685a128defd208fe85d26
--- /dev/null
+++ b/packages/backend/migration/1629833361000-AddShowTLReplies.js
@@ -0,0 +1,15 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+class addShowTLReplies1629833361000 {
+	constructor() {
+		this.name = 'addShowTLReplies1629833361000';
+	}
+	async up(queryRunner) {
+		await queryRunner.query(`ALTER TABLE "user" ADD "showTimelineReplies" boolean NOT NULL DEFAULT false`);
+		await queryRunner.query(`COMMENT ON COLUMN "user"."showTimelineReplies" IS 'Whether to show users replying to other users in the timeline.'`);
+	}
+	async down(queryRunner) {
+		await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "showTimelineReplies"`);
+	}
+}
+exports.addShowTLReplies1629833361000 = addShowTLReplies1629833361000;
diff --git a/packages/backend/migration/1643963705770-chart-v4.js b/packages/backend/migration/1643963705770-chart-v4.js
new file mode 100644
index 0000000000000000000000000000000000000000..91b0a747e65fbb294b273bc87abc2660f249ad00
--- /dev/null
+++ b/packages/backend/migration/1643963705770-chart-v4.js
@@ -0,0 +1,63 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV41643963705770 {
+    name = 'chartV41643963705770'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart__instance" DROP COLUMN "___drive_totalUsage"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" DROP COLUMN "___drive_totalUsage"`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "___local_totalCount"`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "___local_totalSize"`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "___remote_totalCount"`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "___remote_totalSize"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" DROP COLUMN "___local_totalCount"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" DROP COLUMN "___local_totalSize"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" DROP COLUMN "___remote_totalCount"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" DROP COLUMN "___remote_totalSize"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_users" bigint NOT NULL DEFAULT 0`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_users" bigint NOT NULL DEFAULT 0`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___local_users" bigint NOT NULL DEFAULT 0`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___remote_users" bigint NOT NULL DEFAULT 0`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___local_users" bigint NOT NULL DEFAULT 0`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___remote_users" bigint NOT NULL DEFAULT 0`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "___local_users" bigint NOT NULL DEFAULT 0`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "___remote_users" bigint NOT NULL DEFAULT 0`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "___remote_users" character varying array NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "___local_users" character varying array NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___remote_users" character varying array NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___local_users" character varying array NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___remote_users" character varying array NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___local_users" character varying array NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_users" character varying array NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_users" character varying array NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ADD "___remote_totalSize" bigint NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ADD "___remote_totalCount" bigint NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ADD "___local_totalSize" bigint NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ADD "___local_totalCount" bigint NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "___remote_totalSize" bigint NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "___remote_totalCount" bigint NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "___local_totalSize" bigint NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "___local_totalCount" bigint NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ADD "___drive_totalUsage" bigint NOT NULL`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ADD "___drive_totalUsage" bigint NOT NULL`);
+    }
+}
diff --git a/packages/backend/migration/1643966656277-chart-v5.js b/packages/backend/migration/1643966656277-chart-v5.js
new file mode 100644
index 0000000000000000000000000000000000000000..9ff05be63b18fbd19fc001139fd1fdc20e94a084
--- /dev/null
+++ b/packages/backend/migration/1643966656277-chart-v5.js
@@ -0,0 +1,27 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV51643966656277 {
+    name = 'chartV51643966656277'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "unique_temp___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "unique_temp___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "unique_temp___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "unique_temp___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___local_users"`);
+    }
+}
diff --git a/packages/backend/migration/1643967331284-chart-v6.js b/packages/backend/migration/1643967331284-chart-v6.js
new file mode 100644
index 0000000000000000000000000000000000000000..86feade9d16518fe81b9b0f0b1ad2d182e6cc764
--- /dev/null
+++ b/packages/backend/migration/1643967331284-chart-v6.js
@@ -0,0 +1,343 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV61643967331284 {
+    name = 'chartV61643967331284'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_normal" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_reply" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_renote" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_normal" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_reply" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_renote" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_normal" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_reply" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_renote" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_normal" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_reply" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_renote" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingRequests" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingRequests" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___totalTime" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingBytes" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingBytes" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingRequests" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingRequests" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___totalTime" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingBytes" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingBytes" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_failed" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_succeeded" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_received" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_normal" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_reply" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_renote" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_totalFiles" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incFiles" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decFiles" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incUsage" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decUsage" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_failed" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_succeeded" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_received" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_normal" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_reply" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_renote" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_totalFiles" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incFiles" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decFiles" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incUsage" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decUsage" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_normal" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_reply" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_renote" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_normal" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_reply" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_renote" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___local_count" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___remote_count" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___local_count" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___remote_count" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_total" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_inc" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_dec" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incSize" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decCount" SET DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decSize" SET DEFAULT '0'`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___remote_count" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___local_count" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___remote_count" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___local_count" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incSize" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incCount" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_renote" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_reply" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_normal" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_renote" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_reply" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_normal" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decUsage" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incUsage" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decFiles" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incFiles" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_totalFiles" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_renote" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_reply" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_normal" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_received" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_succeeded" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_failed" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decUsage" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incUsage" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decFiles" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incFiles" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_totalFiles" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_renote" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_reply" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_normal" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_received" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_succeeded" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_failed" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingBytes" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingBytes" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___totalTime" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingRequests" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingRequests" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingBytes" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingBytes" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___totalTime" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingRequests" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingRequests" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_renote" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_reply" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_normal" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_renote" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_reply" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_normal" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_renote" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_reply" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_normal" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_renote" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_reply" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_normal" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_total" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_dec" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_inc" DROP DEFAULT`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_total" DROP DEFAULT`);
+    }
+}
diff --git a/packages/backend/migration/1644058404077-chart-v7.js b/packages/backend/migration/1644058404077-chart-v7.js
new file mode 100644
index 0000000000000000000000000000000000000000..a462a7cd36239ca2610b75280e451b320d40b61c
--- /dev/null
+++ b/packages/backend/migration/1644058404077-chart-v7.js
@@ -0,0 +1,511 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV71644058404077 {
+    name = 'chartV71644058404077'
+
+	async up(queryRunner) {
+		await queryRunner.query(`UPDATE "__chart__federation" SET "___instance_total"=2147483647 WHERE "___instance_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__federation" SET "___instance_inc"=32767 WHERE "___instance_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__federation" SET "___instance_dec"=32767 WHERE "___instance_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__federation" SET "___instance_total"=2147483647 WHERE "___instance_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__federation" SET "___instance_inc"=32767 WHERE "___instance_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__federation" SET "___instance_dec"=32767 WHERE "___instance_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___local_total"=2147483647 WHERE "___local_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___local_inc"=2147483647 WHERE "___local_inc" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___local_dec"=2147483647 WHERE "___local_dec" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___local_diffs_normal"=2147483647 WHERE "___local_diffs_normal" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___local_diffs_reply"=2147483647 WHERE "___local_diffs_reply" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___local_diffs_renote"=2147483647 WHERE "___local_diffs_renote" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_total"=2147483647 WHERE "___remote_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_inc"=2147483647 WHERE "___remote_inc" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_dec"=2147483647 WHERE "___remote_dec" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_diffs_normal"=2147483647 WHERE "___remote_diffs_normal" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_diffs_reply"=2147483647 WHERE "___remote_diffs_reply" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_diffs_renote"=2147483647 WHERE "___remote_diffs_renote" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_total"=2147483647 WHERE "___local_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_inc"=2147483647 WHERE "___local_inc" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_dec"=2147483647 WHERE "___local_dec" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_diffs_normal"=2147483647 WHERE "___local_diffs_normal" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_diffs_reply"=2147483647 WHERE "___local_diffs_reply" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_diffs_renote"=2147483647 WHERE "___local_diffs_renote" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_total"=2147483647 WHERE "___remote_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_inc"=2147483647 WHERE "___remote_inc" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_dec"=2147483647 WHERE "___remote_dec" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_diffs_normal"=2147483647 WHERE "___remote_diffs_normal" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_diffs_reply"=2147483647 WHERE "___remote_diffs_reply" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_diffs_renote"=2147483647 WHERE "___remote_diffs_renote" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__users" SET "___local_total"=2147483647 WHERE "___local_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__users" SET "___local_inc"=32767 WHERE "___local_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__users" SET "___local_dec"=32767 WHERE "___local_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__users" SET "___remote_total"=2147483647 WHERE "___remote_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__users" SET "___remote_inc"=32767 WHERE "___remote_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__users" SET "___remote_dec"=32767 WHERE "___remote_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__users" SET "___local_total"=2147483647 WHERE "___local_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__users" SET "___local_inc"=32767 WHERE "___local_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__users" SET "___local_dec"=32767 WHERE "___local_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__users" SET "___remote_total"=2147483647 WHERE "___remote_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__users" SET "___remote_inc"=32767 WHERE "___remote_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__users" SET "___remote_dec"=32767 WHERE "___remote_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__network" SET "___incomingRequests"=2147483647 WHERE "___incomingRequests" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__network" SET "___outgoingRequests"=2147483647 WHERE "___outgoingRequests" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__network" SET "___totalTime"=2147483647 WHERE "___totalTime" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__network" SET "___incomingBytes"=2147483647 WHERE "___incomingBytes" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__network" SET "___outgoingBytes"=2147483647 WHERE "___outgoingBytes" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__network" SET "___incomingRequests"=2147483647 WHERE "___incomingRequests" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__network" SET "___outgoingRequests"=2147483647 WHERE "___outgoingRequests" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__network" SET "___totalTime"=2147483647 WHERE "___totalTime" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__network" SET "___incomingBytes"=2147483647 WHERE "___incomingBytes" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__network" SET "___outgoingBytes"=2147483647 WHERE "___outgoingBytes" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___requests_failed"=32767 WHERE "___requests_failed" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___requests_succeeded"=32767 WHERE "___requests_succeeded" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___requests_received"=32767 WHERE "___requests_received" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_total"=2147483647 WHERE "___notes_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_inc"=2147483647 WHERE "___notes_inc" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_dec"=2147483647 WHERE "___notes_dec" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_diffs_normal"=2147483647 WHERE "___notes_diffs_normal" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_diffs_reply"=2147483647 WHERE "___notes_diffs_reply" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_diffs_renote"=2147483647 WHERE "___notes_diffs_renote" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___users_total"=2147483647 WHERE "___users_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___users_inc"=32767 WHERE "___users_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___users_dec"=32767 WHERE "___users_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___following_total"=2147483647 WHERE "___following_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___following_inc"=32767 WHERE "___following_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___following_dec"=32767 WHERE "___following_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___followers_total"=2147483647 WHERE "___followers_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___followers_inc"=32767 WHERE "___followers_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___followers_dec"=32767 WHERE "___followers_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_totalFiles"=2147483647 WHERE "___drive_totalFiles" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_incFiles"=2147483647 WHERE "___drive_incFiles" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_decFiles"=2147483647 WHERE "___drive_decFiles" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_incUsage"=2147483647 WHERE "___drive_incUsage" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_decUsage"=2147483647 WHERE "___drive_decUsage" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___requests_failed"=32767 WHERE "___requests_failed" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___requests_succeeded"=32767 WHERE "___requests_succeeded" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___requests_received"=32767 WHERE "___requests_received" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_total"=2147483647 WHERE "___notes_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_inc"=2147483647 WHERE "___notes_inc" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_dec"=2147483647 WHERE "___notes_dec" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_diffs_normal"=2147483647 WHERE "___notes_diffs_normal" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_diffs_reply"=2147483647 WHERE "___notes_diffs_reply" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_diffs_renote"=2147483647 WHERE "___notes_diffs_renote" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___users_total"=2147483647 WHERE "___users_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___users_inc"=32767 WHERE "___users_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___users_dec"=32767 WHERE "___users_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___following_total"=2147483647 WHERE "___following_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___following_inc"=32767 WHERE "___following_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___following_dec"=32767 WHERE "___following_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___followers_total"=2147483647 WHERE "___followers_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___followers_inc"=32767 WHERE "___followers_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___followers_dec"=32767 WHERE "___followers_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_totalFiles"=2147483647 WHERE "___drive_totalFiles" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_incFiles"=2147483647 WHERE "___drive_incFiles" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_decFiles"=2147483647 WHERE "___drive_decFiles" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_incUsage"=2147483647 WHERE "___drive_incUsage" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_decUsage"=2147483647 WHERE "___drive_decUsage" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___total"=2147483647 WHERE "___total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___inc"=32767 WHERE "___inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___dec"=32767 WHERE "___dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___diffs_normal"=32767 WHERE "___diffs_normal" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___diffs_reply"=32767 WHERE "___diffs_reply" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___diffs_renote"=32767 WHERE "___diffs_renote" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___total"=2147483647 WHERE "___total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___inc"=32767 WHERE "___inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___dec"=32767 WHERE "___dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___diffs_normal"=32767 WHERE "___diffs_normal" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___diffs_reply"=32767 WHERE "___diffs_reply" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___diffs_renote"=32767 WHERE "___diffs_renote" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__drive" SET "___local_incCount"=2147483647 WHERE "___local_incCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__drive" SET "___local_incSize"=2147483647 WHERE "___local_incSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__drive" SET "___local_decCount"=2147483647 WHERE "___local_decCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__drive" SET "___local_decSize"=2147483647 WHERE "___local_decSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__drive" SET "___remote_incCount"=2147483647 WHERE "___remote_incCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__drive" SET "___remote_incSize"=2147483647 WHERE "___remote_incSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__drive" SET "___remote_decCount"=2147483647 WHERE "___remote_decCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__drive" SET "___remote_decSize"=2147483647 WHERE "___remote_decSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__drive" SET "___local_incCount"=2147483647 WHERE "___local_incCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__drive" SET "___local_incSize"=2147483647 WHERE "___local_incSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__drive" SET "___local_decCount"=2147483647 WHERE "___local_decCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__drive" SET "___local_decSize"=2147483647 WHERE "___local_decSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__drive" SET "___remote_incCount"=2147483647 WHERE "___remote_incCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__drive" SET "___remote_incSize"=2147483647 WHERE "___remote_incSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__drive" SET "___remote_decCount"=2147483647 WHERE "___remote_decCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__drive" SET "___remote_decSize"=2147483647 WHERE "___remote_decSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_reaction" SET "___local_count"=32767 WHERE "___local_count" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_reaction" SET "___remote_count"=32767 WHERE "___remote_count" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_reaction" SET "___local_count"=32767 WHERE "___local_count" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_reaction" SET "___remote_count"=32767 WHERE "___remote_count" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followings_total"=2147483647 WHERE "___local_followings_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followings_inc"=32767 WHERE "___local_followings_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followings_dec"=32767 WHERE "___local_followings_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followers_total"=2147483647 WHERE "___local_followers_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followers_inc"=32767 WHERE "___local_followers_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followers_dec"=32767 WHERE "___local_followers_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followings_total"=2147483647 WHERE "___remote_followings_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followings_inc"=32767 WHERE "___remote_followings_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followings_dec"=32767 WHERE "___remote_followings_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followers_total"=2147483647 WHERE "___remote_followers_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followers_inc"=32767 WHERE "___remote_followers_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followers_dec"=32767 WHERE "___remote_followers_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followings_total"=2147483647 WHERE "___local_followings_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followings_inc"=32767 WHERE "___local_followings_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followings_dec"=32767 WHERE "___local_followings_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followers_total"=2147483647 WHERE "___local_followers_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followers_inc"=32767 WHERE "___local_followers_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followers_dec"=32767 WHERE "___local_followers_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followings_total"=2147483647 WHERE "___remote_followings_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followings_inc"=32767 WHERE "___remote_followings_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followings_dec"=32767 WHERE "___remote_followings_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followers_total"=2147483647 WHERE "___remote_followers_total" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followers_inc"=32767 WHERE "___remote_followers_inc" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followers_dec"=32767 WHERE "___remote_followers_dec" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___totalCount"=2147483647 WHERE "___totalCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___totalSize"=2147483647 WHERE "___totalSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___incCount"=32767 WHERE "___incCount" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___incSize"=2147483647 WHERE "___incSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___decCount"=32767 WHERE "___decCount" > 32767`);
+		await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___decSize"=2147483647 WHERE "___decSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___totalCount"=2147483647 WHERE "___totalCount" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___totalSize"=2147483647 WHERE "___totalSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___incCount"=32767 WHERE "___incCount" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___incSize"=2147483647 WHERE "___incSize" > 2147483647`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___decCount"=32767 WHERE "___decCount" > 32767`);
+		await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___decSize"=2147483647 WHERE "___decSize" > 2147483647`);
+
+		await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_total" TYPE integer USING "___instance_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_inc" TYPE smallint USING "___instance_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_dec" TYPE smallint USING "___instance_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_total" TYPE integer USING "___instance_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_inc" TYPE smallint USING "___instance_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_dec" TYPE smallint USING "___instance_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_total" TYPE integer USING "___local_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_inc" TYPE integer USING "___local_inc"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_dec" TYPE integer USING "___local_dec"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_normal" TYPE integer USING "___local_diffs_normal"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_reply" TYPE integer USING "___local_diffs_reply"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_renote" TYPE integer USING "___local_diffs_renote"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_total" TYPE integer USING "___remote_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_inc" TYPE integer USING "___remote_inc"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_dec" TYPE integer USING "___remote_dec"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_normal" TYPE integer USING "___remote_diffs_normal"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_reply" TYPE integer USING "___remote_diffs_reply"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_renote" TYPE integer USING "___remote_diffs_renote"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_total" TYPE integer USING "___local_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_inc" TYPE integer USING "___local_inc"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_dec" TYPE integer USING "___local_dec"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_normal" TYPE integer USING "___local_diffs_normal"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_reply" TYPE integer USING "___local_diffs_reply"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_renote" TYPE integer USING "___local_diffs_renote"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_total" TYPE integer USING "___remote_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_inc" TYPE integer USING "___remote_inc"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_dec" TYPE integer USING "___remote_dec"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_normal" TYPE integer USING "___remote_diffs_normal"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_reply" TYPE integer USING "___remote_diffs_reply"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_renote" TYPE integer USING "___remote_diffs_renote"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_total" TYPE integer USING "___local_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_inc" TYPE smallint USING "___local_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_dec" TYPE smallint USING "___local_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_total" TYPE integer USING "___remote_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_inc" TYPE smallint USING "___remote_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_dec" TYPE smallint USING "___remote_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_total" TYPE integer USING "___local_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_inc" TYPE smallint USING "___local_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_dec" TYPE smallint USING "___local_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_total" TYPE integer USING "___remote_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_inc" TYPE smallint USING "___remote_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_dec" TYPE smallint USING "___remote_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingRequests" TYPE integer USING "___incomingRequests"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingRequests" TYPE integer USING "___outgoingRequests"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___totalTime" TYPE integer USING "___totalTime"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingBytes" TYPE integer USING "___incomingBytes"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingBytes" TYPE integer USING "___outgoingBytes"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingRequests" TYPE integer USING "___incomingRequests"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingRequests" TYPE integer USING "___outgoingRequests"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___totalTime" TYPE integer USING "___totalTime"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingBytes" TYPE integer USING "___incomingBytes"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingBytes" TYPE integer USING "___outgoingBytes"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_failed" TYPE smallint USING "___requests_failed"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_succeeded" TYPE smallint USING "___requests_succeeded"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_received" TYPE smallint USING "___requests_received"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_total" TYPE integer USING "___notes_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_inc" TYPE integer USING "___notes_inc"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_dec" TYPE integer USING "___notes_dec"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_normal" TYPE integer USING "___notes_diffs_normal"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_reply" TYPE integer USING "___notes_diffs_reply"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_renote" TYPE integer USING "___notes_diffs_renote"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_total" TYPE integer USING "___users_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_inc" TYPE smallint USING "___users_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_dec" TYPE smallint USING "___users_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_total" TYPE integer USING "___following_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_inc" TYPE smallint USING "___following_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_dec" TYPE smallint USING "___following_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_total" TYPE integer USING "___followers_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_inc" TYPE smallint USING "___followers_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_dec" TYPE smallint USING "___followers_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_totalFiles" TYPE integer USING "___drive_totalFiles"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incFiles" TYPE integer USING "___drive_incFiles"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decFiles" TYPE integer USING "___drive_decFiles"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incUsage" TYPE integer USING "___drive_incUsage"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decUsage" TYPE integer USING "___drive_decUsage"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_failed" TYPE smallint USING "___requests_failed"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_succeeded" TYPE smallint USING "___requests_succeeded"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_received" TYPE smallint USING "___requests_received"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_total" TYPE integer USING "___notes_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_inc" TYPE integer USING "___notes_inc"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_dec" TYPE integer USING "___notes_dec"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_normal" TYPE integer USING "___notes_diffs_normal"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_reply" TYPE integer USING "___notes_diffs_reply"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_renote" TYPE integer USING "___notes_diffs_renote"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_total" TYPE integer USING "___users_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_inc" TYPE smallint USING "___users_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_dec" TYPE smallint USING "___users_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_total" TYPE integer USING "___following_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_inc" TYPE smallint USING "___following_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_dec" TYPE smallint USING "___following_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_total" TYPE integer USING "___followers_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_inc" TYPE smallint USING "___followers_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_dec" TYPE smallint USING "___followers_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_totalFiles" TYPE integer USING "___drive_totalFiles"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incFiles" TYPE integer USING "___drive_incFiles"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decFiles" TYPE integer USING "___drive_decFiles"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incUsage" TYPE integer USING "___drive_incUsage"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decUsage" TYPE integer USING "___drive_decUsage"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___total" TYPE integer USING "___total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___inc" TYPE smallint USING "___inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___dec" TYPE smallint USING "___dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_normal" TYPE smallint USING "___diffs_normal"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_reply" TYPE smallint USING "___diffs_reply"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_renote" TYPE smallint USING "___diffs_renote"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___total" TYPE integer USING "___total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___inc" TYPE smallint USING "___inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___dec" TYPE smallint USING "___dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_normal" TYPE smallint USING "___diffs_normal"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_reply" TYPE smallint USING "___diffs_reply"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_renote" TYPE smallint USING "___diffs_renote"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incCount" TYPE integer USING "___local_incCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incSize" TYPE integer USING "___local_incSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decCount" TYPE integer USING "___local_decCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decSize" TYPE integer USING "___local_decSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incCount" TYPE integer USING "___remote_incCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incSize" TYPE integer USING "___remote_incSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decCount" TYPE integer USING "___remote_decCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decSize" TYPE integer USING "___remote_decSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incCount" TYPE integer USING "___local_incCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incSize" TYPE integer USING "___local_incSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decCount" TYPE integer USING "___local_decCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decSize" TYPE integer USING "___local_decSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incCount" TYPE integer USING "___remote_incCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incSize" TYPE integer USING "___remote_incSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decCount" TYPE integer USING "___remote_decCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decSize" TYPE integer USING "___remote_decSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___local_count" TYPE smallint USING "___local_count"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___remote_count" TYPE smallint USING "___remote_count"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___local_count" TYPE smallint USING "___local_count"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___remote_count" TYPE smallint USING "___remote_count"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_total" TYPE integer USING "___local_followings_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_inc" TYPE smallint USING "___local_followings_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_dec" TYPE smallint USING "___local_followings_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_total" TYPE integer USING "___local_followers_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_inc" TYPE smallint USING "___local_followers_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_dec" TYPE smallint USING "___local_followers_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_total" TYPE integer USING "___remote_followings_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_inc" TYPE smallint USING "___remote_followings_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_dec" TYPE smallint USING "___remote_followings_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_total" TYPE integer USING "___remote_followers_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_inc" TYPE smallint USING "___remote_followers_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_dec" TYPE smallint USING "___remote_followers_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_total" TYPE integer USING "___local_followings_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_inc" TYPE smallint USING "___local_followings_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_dec" TYPE smallint USING "___local_followings_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_total" TYPE integer USING "___local_followers_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_inc" TYPE smallint USING "___local_followers_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_dec" TYPE smallint USING "___local_followers_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_total" TYPE integer USING "___remote_followings_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_inc" TYPE smallint USING "___remote_followings_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_dec" TYPE smallint USING "___remote_followings_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_total" TYPE integer USING "___remote_followers_total"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_inc" TYPE smallint USING "___remote_followers_inc"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_dec" TYPE smallint USING "___remote_followers_dec"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalCount" TYPE integer USING "___totalCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalSize" TYPE integer USING "___totalSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incCount" TYPE smallint USING "___incCount"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incSize" TYPE integer USING "___incSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decCount" TYPE smallint USING "___decCount"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decSize" TYPE integer USING "___decSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalCount" TYPE integer USING "___totalCount"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalSize" TYPE integer USING "___totalSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incCount" TYPE smallint USING "___incCount"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incSize" TYPE integer USING "___incSize"::integer`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decCount" TYPE smallint USING "___decCount"::smallint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decSize" TYPE integer USING "___decSize"::integer`);
+	}
+
+	async down(queryRunner) {
+
+		await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_total" TYPE bigint USING "___instance_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_inc" TYPE bigint USING "___instance_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_dec" TYPE bigint USING "___instance_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_total" TYPE bigint USING "___instance_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_inc" TYPE bigint USING "___instance_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_dec" TYPE bigint USING "___instance_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_total" TYPE bigint USING "___local_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_inc" TYPE bigint USING "___local_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_dec" TYPE bigint USING "___local_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_normal" TYPE bigint USING "___local_diffs_normal"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_reply" TYPE bigint USING "___local_diffs_reply"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_renote" TYPE bigint USING "___local_diffs_renote"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_total" TYPE bigint USING "___remote_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_inc" TYPE bigint USING "___remote_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_dec" TYPE bigint USING "___remote_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_normal" TYPE bigint USING "___remote_diffs_normal"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_reply" TYPE bigint USING "___remote_diffs_reply"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_renote" TYPE bigint USING "___remote_diffs_renote"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_total" TYPE bigint USING "___local_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_inc" TYPE bigint USING "___local_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_dec" TYPE bigint USING "___local_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_normal" TYPE bigint USING "___local_diffs_normal"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_reply" TYPE bigint USING "___local_diffs_reply"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_renote" TYPE bigint USING "___local_diffs_renote"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_total" TYPE bigint USING "___remote_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_inc" TYPE bigint USING "___remote_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_dec" TYPE bigint USING "___remote_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_normal" TYPE bigint USING "___remote_diffs_normal"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_reply" TYPE bigint USING "___remote_diffs_reply"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_renote" TYPE bigint USING "___remote_diffs_renote"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_total" TYPE bigint USING "___local_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_inc" TYPE bigint USING "___local_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_dec" TYPE bigint USING "___local_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_total" TYPE bigint USING "___remote_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_inc" TYPE bigint USING "___remote_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_dec" TYPE bigint USING "___remote_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_total" TYPE bigint USING "___local_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_inc" TYPE bigint USING "___local_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_dec" TYPE bigint USING "___local_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_total" TYPE bigint USING "___remote_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_inc" TYPE bigint USING "___remote_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_dec" TYPE bigint USING "___remote_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingRequests" TYPE bigint USING "___incomingRequests"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingRequests" TYPE bigint USING "___outgoingRequests"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___totalTime" TYPE bigint USING "___totalTime"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingBytes" TYPE bigint USING "___incomingBytes"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingBytes" TYPE bigint USING "___outgoingBytes"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingRequests" TYPE bigint USING "___incomingRequests"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingRequests" TYPE bigint USING "___outgoingRequests"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___totalTime" TYPE bigint USING "___totalTime"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingBytes" TYPE bigint USING "___incomingBytes"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingBytes" TYPE bigint USING "___outgoingBytes"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_failed" TYPE bigint USING "___requests_failed"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_succeeded" TYPE bigint USING "___requests_succeeded"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_received" TYPE bigint USING "___requests_received"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_total" TYPE bigint USING "___notes_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_inc" TYPE bigint USING "___notes_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_dec" TYPE bigint USING "___notes_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_normal" TYPE bigint USING "___notes_diffs_normal"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_reply" TYPE bigint USING "___notes_diffs_reply"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_renote" TYPE bigint USING "___notes_diffs_renote"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_total" TYPE bigint USING "___users_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_inc" TYPE bigint USING "___users_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_dec" TYPE bigint USING "___users_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_total" TYPE bigint USING "___following_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_inc" TYPE bigint USING "___following_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_dec" TYPE bigint USING "___following_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_total" TYPE bigint USING "___followers_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_inc" TYPE bigint USING "___followers_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_dec" TYPE bigint USING "___followers_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_totalFiles" TYPE bigint USING "___drive_totalFiles"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incFiles" TYPE bigint USING "___drive_incFiles"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decFiles" TYPE bigint USING "___drive_decFiles"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incUsage" TYPE bigint USING "___drive_incUsage"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decUsage" TYPE bigint USING "___drive_decUsage"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_failed" TYPE bigint USING "___requests_failed"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_succeeded" TYPE bigint USING "___requests_succeeded"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_received" TYPE bigint USING "___requests_received"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_total" TYPE bigint USING "___notes_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_inc" TYPE bigint USING "___notes_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_dec" TYPE bigint USING "___notes_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_normal" TYPE bigint USING "___notes_diffs_normal"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_reply" TYPE bigint USING "___notes_diffs_reply"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_renote" TYPE bigint USING "___notes_diffs_renote"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_total" TYPE bigint USING "___users_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_inc" TYPE bigint USING "___users_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_dec" TYPE bigint USING "___users_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_total" TYPE bigint USING "___following_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_inc" TYPE bigint USING "___following_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_dec" TYPE bigint USING "___following_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_total" TYPE bigint USING "___followers_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_inc" TYPE bigint USING "___followers_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_dec" TYPE bigint USING "___followers_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_totalFiles" TYPE bigint USING "___drive_totalFiles"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incFiles" TYPE bigint USING "___drive_incFiles"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decFiles" TYPE bigint USING "___drive_decFiles"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incUsage" TYPE bigint USING "___drive_incUsage"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decUsage" TYPE bigint USING "___drive_decUsage"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___total" TYPE bigint USING "___total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___inc" TYPE bigint USING "___inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___dec" TYPE bigint USING "___dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_normal" TYPE bigint USING "___diffs_normal"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_reply" TYPE bigint USING "___diffs_reply"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_renote" TYPE bigint USING "___diffs_renote"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___total" TYPE bigint USING "___total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___inc" TYPE bigint USING "___inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___dec" TYPE bigint USING "___dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_normal" TYPE bigint USING "___diffs_normal"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_reply" TYPE bigint USING "___diffs_reply"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_renote" TYPE bigint USING "___diffs_renote"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incCount" TYPE bigint USING "___local_incCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incSize" TYPE bigint USING "___local_incSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decCount" TYPE bigint USING "___local_decCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decSize" TYPE bigint USING "___local_decSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incCount" TYPE bigint USING "___remote_incCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incSize" TYPE bigint USING "___remote_incSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decCount" TYPE bigint USING "___remote_decCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decSize" TYPE bigint USING "___remote_decSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incCount" TYPE bigint USING "___local_incCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incSize" TYPE bigint USING "___local_incSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decCount" TYPE bigint USING "___local_decCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decSize" TYPE bigint USING "___local_decSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incCount" TYPE bigint USING "___remote_incCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incSize" TYPE bigint USING "___remote_incSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decCount" TYPE bigint USING "___remote_decCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decSize" TYPE bigint USING "___remote_decSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___local_count" TYPE bigint USING "___local_count"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___remote_count" TYPE bigint USING "___remote_count"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___local_count" TYPE bigint USING "___local_count"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___remote_count" TYPE bigint USING "___remote_count"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_total" TYPE bigint USING "___local_followings_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_inc" TYPE bigint USING "___local_followings_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_dec" TYPE bigint USING "___local_followings_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_total" TYPE bigint USING "___local_followers_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_inc" TYPE bigint USING "___local_followers_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_dec" TYPE bigint USING "___local_followers_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_total" TYPE bigint USING "___remote_followings_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_inc" TYPE bigint USING "___remote_followings_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_dec" TYPE bigint USING "___remote_followings_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_total" TYPE bigint USING "___remote_followers_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_inc" TYPE bigint USING "___remote_followers_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_dec" TYPE bigint USING "___remote_followers_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_total" TYPE bigint USING "___local_followings_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_inc" TYPE bigint USING "___local_followings_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_dec" TYPE bigint USING "___local_followings_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_total" TYPE bigint USING "___local_followers_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_inc" TYPE bigint USING "___local_followers_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_dec" TYPE bigint USING "___local_followers_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_total" TYPE bigint USING "___remote_followings_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_inc" TYPE bigint USING "___remote_followings_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_dec" TYPE bigint USING "___remote_followings_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_total" TYPE bigint USING "___remote_followers_total"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_inc" TYPE bigint USING "___remote_followers_inc"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_dec" TYPE bigint USING "___remote_followers_dec"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalCount" TYPE bigint USING "___totalCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalSize" TYPE bigint USING "___totalSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incCount" TYPE bigint USING "___incCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incSize" TYPE bigint USING "___incSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decCount" TYPE bigint USING "___decCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decSize" TYPE bigint USING "___decSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalCount" TYPE bigint USING "___totalCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalSize" TYPE bigint USING "___totalSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incCount" TYPE bigint USING "___incCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incSize" TYPE bigint USING "___incSize"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decCount" TYPE bigint USING "___decCount"::bigint`);
+		await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decSize" TYPE bigint USING "___decSize"::bigint`);
+	}
+}
diff --git a/packages/backend/migration/1644059847460-chart-v8.js b/packages/backend/migration/1644059847460-chart-v8.js
new file mode 100644
index 0000000000000000000000000000000000000000..7c5db0db337c0c0126dab035fdd0afa7d819e708
--- /dev/null
+++ b/packages/backend/migration/1644059847460-chart-v8.js
@@ -0,0 +1,25 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV81644059847460 {
+    name = 'chartV81644059847460'
+
+		async up(queryRunner) {
+			await queryRunner.query(`UPDATE "__chart__active_users" SET "___local_users"=2147483647 WHERE "___local_users" > 2147483647`);
+			await queryRunner.query(`UPDATE "__chart__active_users" SET "___remote_users"=2147483647 WHERE "___remote_users" > 2147483647`);
+			await queryRunner.query(`UPDATE "__chart_day__active_users" SET "___local_users"=2147483647 WHERE "___local_users" > 2147483647`);
+			await queryRunner.query(`UPDATE "__chart_day__active_users" SET "___remote_users"=2147483647 WHERE "___remote_users" > 2147483647`);
+
+			await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`);
+			await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`);
+			await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`);
+			await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`);
+		}
+	
+		async down(queryRunner) {
+	
+			await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`);
+			await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`);
+			await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`);
+			await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`);
+		}
+}
diff --git a/packages/backend/migration/1644060125705-chart-v9.js b/packages/backend/migration/1644060125705-chart-v9.js
new file mode 100644
index 0000000000000000000000000000000000000000..bc607067b328a54273672a884abcaf265deaa266
--- /dev/null
+++ b/packages/backend/migration/1644060125705-chart-v9.js
@@ -0,0 +1,25 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV91644060125705 {
+    name = 'chartV91644060125705'
+
+		async up(queryRunner) {
+			await queryRunner.query(`UPDATE "__chart__hashtag" SET "___local_users"=2147483647 WHERE "___local_users" > 2147483647`);
+			await queryRunner.query(`UPDATE "__chart__hashtag" SET "___remote_users"=2147483647 WHERE "___remote_users" > 2147483647`);
+			await queryRunner.query(`UPDATE "__chart_day__hashtag" SET "___local_users"=2147483647 WHERE "___local_users" > 2147483647`);
+			await queryRunner.query(`UPDATE "__chart_day__hashtag" SET "___remote_users"=2147483647 WHERE "___remote_users" > 2147483647`);
+
+			await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`);
+			await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`);
+			await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`);
+			await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`);
+		}
+	
+		async down(queryRunner) {
+	
+			await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`);
+			await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`);
+			await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`);
+			await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`);
+		}
+}
diff --git a/packages/backend/migration/1644073149413-chart-v10.js b/packages/backend/migration/1644073149413-chart-v10.js
new file mode 100644
index 0000000000000000000000000000000000000000..6ca568718f60d3c15745b053990d7063efca1c5a
--- /dev/null
+++ b/packages/backend/migration/1644073149413-chart-v10.js
@@ -0,0 +1,35 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV101644073149413 {
+    name = 'chartV101644073149413'
+
+    async up(queryRunner) {
+        await queryRunner.query(`CREATE TABLE "__chart__ap_request" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___deliverFailed" integer NOT NULL DEFAULT '0', "___deliverSucceeded" integer NOT NULL DEFAULT '0', "___inboxReceived" integer NOT NULL DEFAULT '0', CONSTRAINT "UQ_e56f4beac5746d44bc3e19c80d0" UNIQUE ("date"), CONSTRAINT "PK_56a25cd447c7ee08876b3baf8d8" PRIMARY KEY ("id"))`);
+        await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e56f4beac5746d44bc3e19c80d" ON "__chart__ap_request" ("date") `);
+        await queryRunner.query(`CREATE TABLE "__chart_day__ap_request" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___deliverFailed" integer NOT NULL DEFAULT '0', "___deliverSucceeded" integer NOT NULL DEFAULT '0', "___inboxReceived" integer NOT NULL DEFAULT '0', CONSTRAINT "UQ_a848f66d6cec11980a5dd595822" UNIQUE ("date"), CONSTRAINT "PK_9318b49daee320194e23f712e69" PRIMARY KEY ("id"))`);
+        await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a848f66d6cec11980a5dd59582" ON "__chart_day__ap_request" ("date") `);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "unique_temp___deliveredInstances" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "___deliveredInstances" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "unique_temp___inboxInstances" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "___inboxInstances" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "unique_temp___deliveredInstances" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "___deliveredInstances" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "unique_temp___inboxInstances" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "___inboxInstances" smallint NOT NULL DEFAULT '0'`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "___inboxInstances"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "unique_temp___inboxInstances"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "___deliveredInstances"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "unique_temp___deliveredInstances"`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "___inboxInstances"`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "unique_temp___inboxInstances"`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "___deliveredInstances"`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "unique_temp___deliveredInstances"`);
+        await queryRunner.query(`DROP INDEX "public"."IDX_a848f66d6cec11980a5dd59582"`);
+        await queryRunner.query(`DROP TABLE "__chart_day__ap_request"`);
+        await queryRunner.query(`DROP INDEX "public"."IDX_e56f4beac5746d44bc3e19c80d"`);
+        await queryRunner.query(`DROP TABLE "__chart__ap_request"`);
+    }
+}
diff --git a/packages/backend/migration/1644095659741-chart-v11.js b/packages/backend/migration/1644095659741-chart-v11.js
new file mode 100644
index 0000000000000000000000000000000000000000..40b1c3072b831c3ad6fbc3025cc68a7b980dfc2b
--- /dev/null
+++ b/packages/backend/migration/1644095659741-chart-v11.js
@@ -0,0 +1,91 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV111644095659741 {
+    name = 'chartV111644095659741'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___local_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___remote_users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___users" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___notedUsers" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___notedUsers" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredWithinWeek" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredWithinWeek" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredWithinMonth" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredWithinMonth" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredWithinYear" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredWithinYear" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredOutsideWeek" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredOutsideWeek" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredOutsideMonth" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredOutsideMonth" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredOutsideYear" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredOutsideYear" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___users" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___notedUsers" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___notedUsers" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredWithinWeek" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredWithinWeek" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredWithinMonth" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredWithinMonth" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredWithinYear" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredWithinYear" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredOutsideWeek" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredOutsideWeek" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredOutsideMonth" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredOutsideMonth" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredOutsideYear" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredOutsideYear" smallint NOT NULL DEFAULT '0'`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredOutsideYear"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredOutsideYear"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredOutsideMonth"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredOutsideMonth"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredOutsideWeek"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredOutsideWeek"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredWithinYear"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredWithinYear"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredWithinMonth"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredWithinMonth"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredWithinWeek"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredWithinWeek"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___notedUsers"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___notedUsers"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredOutsideYear"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredOutsideYear"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredOutsideMonth"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredOutsideMonth"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredOutsideWeek"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredOutsideWeek"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredWithinYear"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredWithinYear"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredWithinMonth"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredWithinMonth"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredWithinWeek"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredWithinWeek"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___notedUsers"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___notedUsers"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___remote_users" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___local_users" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_users" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_users" integer NOT NULL DEFAULT '0'`);
+    }
+}
diff --git a/packages/backend/migration/1644328606241-chart-v12.js b/packages/backend/migration/1644328606241-chart-v12.js
new file mode 100644
index 0000000000000000000000000000000000000000..226de6ece96262f8e16adb751c962400616dcdd6
--- /dev/null
+++ b/packages/backend/migration/1644328606241-chart-v12.js
@@ -0,0 +1,27 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV121644328606241 {
+    name = 'chartV121644328606241'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ADD "___local_diffs_withFile" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" ADD "___remote_diffs_withFile" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ADD "___local_diffs_withFile" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" ADD "___remote_diffs_withFile" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" ADD "___notes_diffs_withFile" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" ADD "___notes_diffs_withFile" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ADD "___diffs_withFile" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ADD "___diffs_withFile" smallint NOT NULL DEFAULT '0'`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" DROP COLUMN "___diffs_withFile"`);
+        await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" DROP COLUMN "___diffs_withFile"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__instance" DROP COLUMN "___notes_diffs_withFile"`);
+        await queryRunner.query(`ALTER TABLE "__chart__instance" DROP COLUMN "___notes_diffs_withFile"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" DROP COLUMN "___remote_diffs_withFile"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__notes" DROP COLUMN "___local_diffs_withFile"`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" DROP COLUMN "___remote_diffs_withFile"`);
+        await queryRunner.query(`ALTER TABLE "__chart__notes" DROP COLUMN "___local_diffs_withFile"`);
+    }
+}
diff --git a/packages/backend/migration/1644331238153-chart-v13.js b/packages/backend/migration/1644331238153-chart-v13.js
new file mode 100644
index 0000000000000000000000000000000000000000..ed36659b340b7d6d6cdf875d41ef92e87591a9f2
--- /dev/null
+++ b/packages/backend/migration/1644331238153-chart-v13.js
@@ -0,0 +1,19 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV131644331238153 {
+    name = 'chartV131644331238153'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "unique_temp___stalled" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "___stalled" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "unique_temp___stalled" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "___stalled" smallint NOT NULL DEFAULT '0'`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "___stalled"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "unique_temp___stalled"`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "___stalled"`);
+        await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "unique_temp___stalled"`);
+    }
+}
diff --git a/packages/backend/migration/1644344266289-chart-v14.js b/packages/backend/migration/1644344266289-chart-v14.js
new file mode 100644
index 0000000000000000000000000000000000000000..8496cc2d42e67453a9d52cd589b558f60c290542
--- /dev/null
+++ b/packages/backend/migration/1644344266289-chart-v14.js
@@ -0,0 +1,47 @@
+const { MigrationInterface, QueryRunner } = require("typeorm");
+
+module.exports = class chartV141644344266289 {
+    name = 'chartV141644344266289'
+
+    async up(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___users"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___notedUsers"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___notedUsers"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___users"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___notedUsers"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___notedUsers"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___readWrite" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___read" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___read" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___write" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___write" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___readWrite" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___read" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___read" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___write" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___write" smallint NOT NULL DEFAULT '0'`);
+    }
+
+    async down(queryRunner) {
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___write"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___write"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___read"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___read"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___readWrite"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___write"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___write"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___read"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___read"`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___readWrite"`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___notedUsers" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___notedUsers" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___users" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___users" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___notedUsers" smallint NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___notedUsers" character varying array NOT NULL DEFAULT '{}'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___users" integer NOT NULL DEFAULT '0'`);
+        await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___users" character varying array NOT NULL DEFAULT '{}'`);
+    }
+}
diff --git a/packages/backend/package.json b/packages/backend/package.json
index 3541e803f3667e7c916872a240c39b774f6b2f18..d81688cbfe67d928d2741de92130b9fdb418ec4a 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -19,12 +19,11 @@
 		"@koa/cors": "3.1.0",
 		"@koa/multer": "3.0.0",
 		"@koa/router": "9.0.1",
-		"@sinonjs/fake-timers": "7.1.2",
+		"@sinonjs/fake-timers": "9.1.0",
 		"@syuilo/aiscript": "0.11.1",
 		"@types/bcryptjs": "2.4.2",
 		"@types/bull": "3.15.7",
 		"@types/cbor": "6.0.0",
-		"@types/dateformat": "3.0.1",
 		"@types/escape-regexp": "0.0.1",
 		"@types/glob": "7.2.0",
 		"@types/is-url": "1.2.30",
@@ -43,7 +42,7 @@
 		"@types/koa__multer": "2.0.4",
 		"@types/koa__router": "8.0.11",
 		"@types/mocha": "8.2.3",
-		"@types/node": "17.0.10",
+		"@types/node": "17.0.14",
 		"@types/node-fetch": "3.0.3",
 		"@types/nodemailer": "6.4.4",
 		"@types/oauth": "0.9.1",
@@ -56,43 +55,40 @@
 		"@types/ratelimiter": "3.4.3",
 		"@types/redis": "4.0.11",
 		"@types/rename": "1.0.4",
-		"@types/request-stats": "3.0.0",
 		"@types/sanitize-html": "2.6.2",
-		"@types/seedrandom": "2.4.28",
+		"@types/seedrandom": "3.0.1",
 		"@types/sharp": "0.29.5",
-		"@types/sinonjs__fake-timers": "6.0.4",
+		"@types/sinonjs__fake-timers": "8.1.1",
 		"@types/speakeasy": "2.0.7",
 		"@types/throttle-debounce": "2.1.0",
 		"@types/tinycolor2": "1.4.3",
 		"@types/tmp": "0.2.3",
 		"@types/uuid": "8.3.4",
 		"@types/web-push": "3.3.2",
-		"@types/webpack": "5.28.0",
-		"@types/webpack-stream": "3.2.12",
-		"@types/websocket": "1.0.4",
+		"@types/websocket": "1.0.5",
 		"@types/ws": "8.2.2",
-		"@typescript-eslint/eslint-plugin": "5.10.0",
-		"@typescript-eslint/parser": "5.10.0",
+		"@typescript-eslint/eslint-plugin": "5.10.2",
+		"@typescript-eslint/parser": "5.10.2",
 		"abort-controller": "3.0.0",
 		"archiver": "5.3.0",
 		"autobind-decorator": "2.4.0",
 		"autwh": "0.1.0",
-		"aws-sdk": "2.1061.0",
+		"aws-sdk": "2.1067.0",
 		"bcryptjs": "2.4.3",
 		"blurhash": "1.1.4",
 		"broadcast-channel": "4.9.0",
-		"bull": "4.2.1",
+		"bull": "4.5.0",
 		"cacheable-lookup": "6.0.4",
 		"cafy": "15.2.1",
 		"cbor": "8.1.0",
 		"chalk": "4.1.2",
 		"cli-highlight": "2.1.11",
 		"content-disposition": "0.5.4",
-		"crc-32": "1.2.0",
-		"dateformat": "4.5.1",
+		"crc-32": "1.2.1",
+		"date-fns": "2.28.0",
 		"deep-email-validator": "0.1.21",
 		"escape-regexp": "0.0.1",
-		"eslint": "8.7.0",
+		"eslint": "8.8.0",
 		"eslint-plugin-import": "2.25.4",
 		"eventemitter3": "4.0.7",
 		"feed": "4.2.2",
@@ -105,7 +101,7 @@
 		"ip-cidr": "3.0.4",
 		"is-svg": "4.3.2",
 		"js-yaml": "4.1.0",
-		"jsdom": "16.7.0",
+		"jsdom": "19.0.0",
 		"json5": "2.2.0",
 		"json5-loader": "4.0.1",
 		"jsonld": "5.2.0",
@@ -134,7 +130,7 @@
 		"pg": "8.7.1",
 		"portscanner": "2.2.0",
 		"private-ip": "2.3.3",
-		"probe-image-size": "7.2.2",
+		"probe-image-size": "7.2.3",
 		"promise-limit": "2.7.0",
 		"pug": "3.0.2",
 		"punycode": "2.1.1",
@@ -147,20 +143,19 @@
 		"redis-lock": "0.1.4",
 		"reflect-metadata": "0.1.13",
 		"rename": "1.0.4",
-		"request-stats": "3.0.0",
 		"require-all": "3.0.0",
 		"rndstr": "1.0.0",
 		"s-age": "1.1.2",
 		"sanitize-html": "2.6.1",
 		"seedrandom": "3.0.5",
-		"sharp": "0.29.3",
+		"sharp": "0.30.0",
 		"speakeasy": "2.0.0",
 		"strict-event-emitter-types": "2.0.0",
 		"stringz": "2.1.0",
 		"style-loader": "3.3.1",
 		"summaly": "2.5.0",
 		"syslog-pro": "1.0.0",
-		"systeminformation": "5.9.9",
+		"systeminformation": "5.11.0",
 		"throttle-debounce": "3.0.1",
 		"tinycolor2": "1.4.2",
 		"tmp": "0.2.1",
diff --git a/packages/backend/@types/hcaptcha.d.ts b/packages/backend/src/@types/hcaptcha.d.ts
similarity index 100%
rename from packages/backend/@types/hcaptcha.d.ts
rename to packages/backend/src/@types/hcaptcha.d.ts
diff --git a/packages/backend/@types/http-signature.d.ts b/packages/backend/src/@types/http-signature.d.ts
similarity index 100%
rename from packages/backend/@types/http-signature.d.ts
rename to packages/backend/src/@types/http-signature.d.ts
diff --git a/packages/backend/@types/jsrsasign.d.ts b/packages/backend/src/@types/jsrsasign.d.ts
similarity index 100%
rename from packages/backend/@types/jsrsasign.d.ts
rename to packages/backend/src/@types/jsrsasign.d.ts
diff --git a/packages/backend/@types/koa-json-body.d.ts b/packages/backend/src/@types/koa-json-body.d.ts
similarity index 100%
rename from packages/backend/@types/koa-json-body.d.ts
rename to packages/backend/src/@types/koa-json-body.d.ts
diff --git a/packages/backend/@types/koa-slow.d.ts b/packages/backend/src/@types/koa-slow.d.ts
similarity index 100%
rename from packages/backend/@types/koa-slow.d.ts
rename to packages/backend/src/@types/koa-slow.d.ts
diff --git a/packages/backend/@types/langmap.d.ts b/packages/backend/src/@types/langmap.d.ts
similarity index 100%
rename from packages/backend/@types/langmap.d.ts
rename to packages/backend/src/@types/langmap.d.ts
diff --git a/packages/backend/@types/os-utils.d.ts b/packages/backend/src/@types/os-utils.d.ts
similarity index 100%
rename from packages/backend/@types/os-utils.d.ts
rename to packages/backend/src/@types/os-utils.d.ts
diff --git a/packages/backend/@types/package.json.d.ts b/packages/backend/src/@types/package.json.d.ts
similarity index 100%
rename from packages/backend/@types/package.json.d.ts
rename to packages/backend/src/@types/package.json.d.ts
diff --git a/packages/backend/@types/probe-image-size.d.ts b/packages/backend/src/@types/probe-image-size.d.ts
similarity index 100%
rename from packages/backend/@types/probe-image-size.d.ts
rename to packages/backend/src/@types/probe-image-size.d.ts
diff --git a/packages/backend/src/mfm/from-html.ts b/packages/backend/src/mfm/from-html.ts
index fc6d3b3062fc0c13b544dc371dfdf77d047a40c6..21e5ebb7a156e79c83834a05742c450254671d7b 100644
--- a/packages/backend/src/mfm/from-html.ts
+++ b/packages/backend/src/mfm/from-html.ts
@@ -5,9 +5,7 @@ import { URL } from 'url';
 const urlRegex     = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/;
 const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/;
 
-export function fromHtml(html: string, hashtagNames?: string[]): string | null {
-	if (html == null) return null;
-
+export function fromHtml(html: string, hashtagNames?: string[]): string {
 	const dom = parse5.parseFragment(html);
 
 	let text = '';
diff --git a/packages/backend/src/misc/before-shutdown.ts b/packages/backend/src/misc/before-shutdown.ts
index 33abf5fb4d95f7118699744cec23f77d4907b3df..93ac7a1f399e29f96ad348fb98414df5b24739b0 100644
--- a/packages/backend/src/misc/before-shutdown.ts
+++ b/packages/backend/src/misc/before-shutdown.ts
@@ -24,14 +24,14 @@ const SHUTDOWN_TIMEOUT = 15000;
  * down the process.
  * @type {BeforeShutdownListener[]}
  */
-const shutdownListeners = [];
+const shutdownListeners: ((signalOrEvent: string) => void)[] = [];
 
 /**
  * Listen for signals and execute given `fn` function once.
  * @param  {string[]} signals System signals to listen to.
  * @param  {function(string)} fn Function to execute on shutdown.
  */
-const processOnce = (signals, fn) => {
+const processOnce = (signals: string[], fn: (signalOrEvent: string) => void) => {
 	for (const sig of signals) {
 		process.once(sig, fn);
 	}
@@ -41,7 +41,7 @@ const processOnce = (signals, fn) => {
  * Sets a forced shutdown mechanism that will exit the process after `timeout` milliseconds.
  * @param {number} timeout Time to wait before forcing shutdown (milliseconds)
  */
-const forceExitAfter = timeout => () => {
+const forceExitAfter = (timeout: number) => () => {
 	setTimeout(() => {
 		// Force shutdown after timeout
 		console.warn(`Could not close resources gracefully after ${timeout}ms: forcing shutdown`);
@@ -55,7 +55,7 @@ const forceExitAfter = timeout => () => {
  * be logged out as a warning, but won't prevent other callbacks from executing.
  * @param {string} signalOrEvent The exit signal or event name received on the process.
  */
-async function shutdownHandler(signalOrEvent) {
+async function shutdownHandler(signalOrEvent: string) {
 	if (process.env.NODE_ENV === 'test') return process.exit(0);
 
 	console.warn(`Shutting down: received [${signalOrEvent}] signal`);
@@ -64,7 +64,9 @@ async function shutdownHandler(signalOrEvent) {
 		try {
 			await listener(signalOrEvent);
 		} catch (err) {
-			console.warn(`A shutdown handler failed before completing with: ${err.message || err}`);
+			if (err instanceof Error) {
+				console.warn(`A shutdown handler failed before completing with: ${err.message || err}`);
+			}
 		}
 	}
 
@@ -78,7 +80,7 @@ async function shutdownHandler(signalOrEvent) {
  * @param {BeforeShutdownListener} listener The shutdown listener to register.
  * @returns {BeforeShutdownListener} Echoes back the supplied `listener`.
  */
-export function beforeShutdown(listener) {
+export function beforeShutdown(listener: () => void) {
 	shutdownListeners.push(listener);
 	return listener;
 }
diff --git a/packages/backend/src/misc/download-url.ts b/packages/backend/src/misc/download-url.ts
index 8e1f7b9e249d86436b01e8634cc505d76cb1ed2e..ba2fa9fae07b1959c355357fb33d210965dff1ac 100644
--- a/packages/backend/src/misc/download-url.ts
+++ b/packages/backend/src/misc/download-url.ts
@@ -38,7 +38,9 @@ export async function downloadUrl(url: string, path: string): Promise<void> {
 			https: httpsAgent,
 		},
 		http2: false,	// default
-		retry: 0,
+		retry: {
+			limit: 0,
+		},
 	}).on('response', (res: Got.Response) => {
 		if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !config.proxy && res.ip) {
 			if (isPrivateIp(res.ip)) {
@@ -75,7 +77,7 @@ export async function downloadUrl(url: string, path: string): Promise<void> {
 	logger.succ(`Download finished: ${chalk.cyan(url)}`);
 }
 
-function isPrivateIp(ip: string) {
+function isPrivateIp(ip: string): boolean {
 	for (const net of config.allowedPrivateNetworks || []) {
 		const cidr = new IPCIDR(net);
 		if (cidr.contains(ip)) {
diff --git a/packages/backend/src/misc/gen-identicon.ts b/packages/backend/src/misc/gen-identicon.ts
index 5cedd7afaf8e532ef2f09dbd44084fa0caceefcc..fca67fcf21c94ea48445c1fae6e78dfe4e5f6f87 100644
--- a/packages/backend/src/misc/gen-identicon.ts
+++ b/packages/backend/src/misc/gen-identicon.ts
@@ -39,7 +39,7 @@ const sideN = Math.floor(n / 2);
  */
 export function genIdenticon(seed: string, stream: WriteStream): Promise<void> {
 	const rand = gen.create(seed);
-	const canvas = p.make(size, size);
+	const canvas = p.make(size, size, undefined);
 	const ctx = canvas.getContext('2d');
 
 	ctx.fillStyle = bg;
diff --git a/packages/backend/src/misc/is-duplicate-key-value-error.ts b/packages/backend/src/misc/is-duplicate-key-value-error.ts
index 23d8ceb1b7592ed722080f64b3c33c190395c039..04ff191e41339f6a0f97cbbb307d20f05fb4bda2 100644
--- a/packages/backend/src/misc/is-duplicate-key-value-error.ts
+++ b/packages/backend/src/misc/is-duplicate-key-value-error.ts
@@ -1,3 +1,3 @@
-export function isDuplicateKeyValueError(e: Error): boolean {
-	return e.message.startsWith('duplicate key value');
+export function isDuplicateKeyValueError(e: unknown | Error): boolean {
+	return (e as any).message && (e as Error).message.startsWith('duplicate key value');
 }
diff --git a/packages/backend/src/models/entities/user.ts b/packages/backend/src/models/entities/user.ts
index 0aa01ba00a7da1fc99152d5cef18c989364acaf0..e4d9a3ced9faf0b73bc2380ef30a05b66940ef1c 100644
--- a/packages/backend/src/models/entities/user.ts
+++ b/packages/backend/src/models/entities/user.ts
@@ -225,6 +225,12 @@ export class User {
 	})
 	public followersUri: string | null;
 
+	@Column('boolean', {
+		default: false,
+		comment: 'Whether to show users replying to other users in the timeline'
+	})
+	public showTimelineReplies: boolean;
+
 	@Index({ unique: true })
 	@Column('char', {
 		length: 16, nullable: true, unique: true,
diff --git a/packages/backend/src/models/repositories/abuse-user-report.ts b/packages/backend/src/models/repositories/abuse-user-report.ts
index 943b65eb647d63c30d66569564ab61c71804433d..144195855b071211fc25871868e61586f413c163 100644
--- a/packages/backend/src/models/repositories/abuse-user-report.ts
+++ b/packages/backend/src/models/repositories/abuse-user-report.ts
@@ -12,7 +12,7 @@ export class AbuseUserReportRepository extends Repository<AbuseUserReport> {
 
 		return await awaitAll({
 			id: report.id,
-			createdAt: report.createdAt,
+			createdAt: report.createdAt.toISOString(),
 			comment: report.comment,
 			resolved: report.resolved,
 			reporterId: report.reporterId,
diff --git a/packages/backend/src/models/repositories/moderation-logs.ts b/packages/backend/src/models/repositories/moderation-logs.ts
index 1585d5bfcf236aefc4fd79b311929e56dccb936b..f530613bcc89ca7611f735d655e9ea020217c10a 100644
--- a/packages/backend/src/models/repositories/moderation-logs.ts
+++ b/packages/backend/src/models/repositories/moderation-logs.ts
@@ -12,7 +12,7 @@ export class ModerationLogRepository extends Repository<ModerationLog> {
 
 		return await awaitAll({
 			id: log.id,
-			createdAt: log.createdAt,
+			createdAt: log.createdAt.toISOString(),
 			type: log.type,
 			info: log.info,
 			userId: log.userId,
diff --git a/packages/backend/src/models/repositories/note-favorite.ts b/packages/backend/src/models/repositories/note-favorite.ts
index c5de55c0c0e81e846858ea2a728d157468924309..f4cd64e39397f3dcf57b2eb622fbf7fdd29fa2c5 100644
--- a/packages/backend/src/models/repositories/note-favorite.ts
+++ b/packages/backend/src/models/repositories/note-favorite.ts
@@ -13,7 +13,7 @@ export class NoteFavoriteRepository extends Repository<NoteFavorite> {
 
 		return {
 			id: favorite.id,
-			createdAt: favorite.createdAt,
+			createdAt: favorite.createdAt.toISOString(),
 			noteId: favorite.noteId,
 			note: await Notes.pack(favorite.note || favorite.noteId, me),
 		};
diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts
index 2b8398832dfd54d3f7486ddc925b93071554d8ea..33b2b32fee01d7ce15b44cd270c639b9bcc463de 100644
--- a/packages/backend/src/models/repositories/user.ts
+++ b/packages/backend/src/models/repositories/user.ts
@@ -220,6 +220,7 @@ export class UserRepository extends Repository<User> {
 			isModerator: user.isModerator || falsy,
 			isBot: user.isBot || falsy,
 			isCat: user.isCat || falsy,
+			showTimelineReplies: user.showTimelineReplies || falsy,
 			instance: user.host ? Instances.findOne({ host: user.host }).then(instance => instance ? {
 				name: instance.name,
 				softwareName: instance.softwareName,
diff --git a/packages/backend/src/queue/index.ts b/packages/backend/src/queue/index.ts
index f9994c3b59c241a4a8663e1325b5152dc98ff26d..16acabfbf849ffb9ede57ec2a5cfceab5bffc2bd 100644
--- a/packages/backend/src/queue/index.ts
+++ b/packages/backend/src/queue/index.ts
@@ -6,7 +6,8 @@ import { envOption } from '../env';
 import processDeliver from './processors/deliver';
 import processInbox from './processors/inbox';
 import processDb from './processors/db/index';
-import procesObjectStorage from './processors/object-storage/index';
+import processObjectStorage from './processors/object-storage/index';
+import processSystemQueue from './processors/system/index';
 import { queueLogger } from './logger';
 import { DriveFile } from '@/models/entities/drive-file';
 import { getJobInfo } from './get-job-info';
@@ -255,12 +256,19 @@ export default function() {
 	deliverQueue.process(config.deliverJobConcurrency || 128, processDeliver);
 	inboxQueue.process(config.inboxJobConcurrency || 16, processInbox);
 	processDb(dbQueue);
-	procesObjectStorage(objectStorageQueue);
+	processObjectStorage(objectStorageQueue);
 
 	systemQueue.add('resyncCharts', {
 	}, {
 		repeat: { cron: '0 0 * * *' },
 	});
+
+	systemQueue.add('cleanCharts', {
+	}, {
+		repeat: { cron: '0 0 * * *' },
+	});
+
+	processSystemQueue(systemQueue);
 }
 
 export function destroy() {
diff --git a/packages/backend/src/queue/processors/db/export-blocking.ts b/packages/backend/src/queue/processors/db/export-blocking.ts
index 01edaaeb630d3d4654e81309fbed779e5b7a0a2d..f4de9ce0056b0f6a33a84e755a26829dee95803c 100644
--- a/packages/backend/src/queue/processors/db/export-blocking.ts
+++ b/packages/backend/src/queue/processors/db/export-blocking.ts
@@ -4,7 +4,7 @@ import * as fs from 'fs';
 
 import { queueLogger } from '../../logger';
 import { addFile } from '@/services/drive/add-file';
-import * as dateFormat from 'dateformat';
+import { format as dateFormat } from 'date-fns';
 import { getFullApAccount } from '@/misc/convert-host';
 import { Users, Blockings } from '@/models/index';
 import { MoreThan } from 'typeorm';
@@ -85,7 +85,7 @@ export async function exportBlocking(job: Bull.Job<DbUserJobData>, done: any): P
 	stream.end();
 	logger.succ(`Exported to: ${path}`);
 
-	const fileName = 'blocking-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
+	const fileName = 'blocking-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.csv';
 	const driveFile = await addFile({ user, path, name: fileName, force: true });
 
 	logger.succ(`Exported to: ${driveFile.id}`);
diff --git a/packages/backend/src/queue/processors/db/export-custom-emojis.ts b/packages/backend/src/queue/processors/db/export-custom-emojis.ts
index 240a542fecb11762000044f50b51ad5a1e40f79a..2f7505f1589c4f1798ee952c006d4e80db0e7727 100644
--- a/packages/backend/src/queue/processors/db/export-custom-emojis.ts
+++ b/packages/backend/src/queue/processors/db/export-custom-emojis.ts
@@ -7,7 +7,7 @@ const mime = require('mime-types');
 const archiver = require('archiver');
 import { queueLogger } from '../../logger';
 import { addFile } from '@/services/drive/add-file';
-import * as dateFormat from 'dateformat';
+import { format as dateFormat } from 'date-fns';
 import { Users, Emojis } from '@/models/index';
 import {  } from '@/queue/types';
 import { downloadUrl } from '@/misc/download-url';
@@ -110,7 +110,7 @@ export async function exportCustomEmojis(job: Bull.Job, done: () => void): Promi
 	archiveStream.on('close', async () => {
 		logger.succ(`Exported to: ${archivePath}`);
 
-		const fileName = 'custom-emojis-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.zip';
+		const fileName = 'custom-emojis-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.zip';
 		const driveFile = await addFile({ user, path: archivePath, name: fileName, force: true });
 
 		logger.succ(`Exported to: ${driveFile.id}`);
diff --git a/packages/backend/src/queue/processors/db/export-following.ts b/packages/backend/src/queue/processors/db/export-following.ts
index 06572acec1ffbbfeb95454265be2f2bdc7fec31e..2ac558381b68445de8d18fb68b97f3b991c1aa61 100644
--- a/packages/backend/src/queue/processors/db/export-following.ts
+++ b/packages/backend/src/queue/processors/db/export-following.ts
@@ -4,7 +4,7 @@ import * as fs from 'fs';
 
 import { queueLogger } from '../../logger';
 import { addFile } from '@/services/drive/add-file';
-import * as dateFormat from 'dateformat';
+import { format as dateFormat } from 'date-fns';
 import { getFullApAccount } from '@/misc/convert-host';
 import { Users, Followings, Mutings } from '@/models/index';
 import { In, MoreThan, Not } from 'typeorm';
@@ -86,7 +86,7 @@ export async function exportFollowing(job: Bull.Job<DbUserJobData>, done: () =>
 	stream.end();
 	logger.succ(`Exported to: ${path}`);
 
-	const fileName = 'following-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
+	const fileName = 'following-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.csv';
 	const driveFile = await addFile({ user, path, name: fileName, force: true });
 
 	logger.succ(`Exported to: ${driveFile.id}`);
diff --git a/packages/backend/src/queue/processors/db/export-mute.ts b/packages/backend/src/queue/processors/db/export-mute.ts
index 4a856f8ef93c641b146e32865bed36623f73218e..9e917ccbf3424f6fa4723bf2c6515b9d4ede27b9 100644
--- a/packages/backend/src/queue/processors/db/export-mute.ts
+++ b/packages/backend/src/queue/processors/db/export-mute.ts
@@ -4,7 +4,7 @@ import * as fs from 'fs';
 
 import { queueLogger } from '../../logger';
 import { addFile } from '@/services/drive/add-file';
-import * as dateFormat from 'dateformat';
+import { format as dateFormat } from 'date-fns';
 import { getFullApAccount } from '@/misc/convert-host';
 import { Users, Mutings } from '@/models/index';
 import { MoreThan } from 'typeorm';
@@ -85,7 +85,7 @@ export async function exportMute(job: Bull.Job<DbUserJobData>, done: any): Promi
 	stream.end();
 	logger.succ(`Exported to: ${path}`);
 
-	const fileName = 'mute-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
+	const fileName = 'mute-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.csv';
 	const driveFile = await addFile({ user, path, name: fileName, force: true });
 
 	logger.succ(`Exported to: ${driveFile.id}`);
diff --git a/packages/backend/src/queue/processors/db/export-notes.ts b/packages/backend/src/queue/processors/db/export-notes.ts
index 305abf44cf0c3a76655b29fad8094cd1a0ce34fc..0e65cb88492baf4febdc8f2206cfc8d0fa5603fb 100644
--- a/packages/backend/src/queue/processors/db/export-notes.ts
+++ b/packages/backend/src/queue/processors/db/export-notes.ts
@@ -4,7 +4,7 @@ import * as fs from 'fs';
 
 import { queueLogger } from '../../logger';
 import { addFile } from '@/services/drive/add-file';
-import * as dateFormat from 'dateformat';
+import { format as dateFormat } from 'date-fns';
 import { Users, Notes, Polls } from '@/models/index';
 import { MoreThan } from 'typeorm';
 import { Note } from '@/models/entities/note';
@@ -94,7 +94,7 @@ export async function exportNotes(job: Bull.Job<DbUserJobData>, done: any): Prom
 	stream.end();
 	logger.succ(`Exported to: ${path}`);
 
-	const fileName = 'notes-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.json';
+	const fileName = 'notes-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.json';
 	const driveFile = await addFile({ user, path, name: fileName, force: true });
 
 	logger.succ(`Exported to: ${driveFile.id}`);
diff --git a/packages/backend/src/queue/processors/db/export-user-lists.ts b/packages/backend/src/queue/processors/db/export-user-lists.ts
index f907cf9526e4200c5639062757f1a8098d1dfcf3..fcd2ba336c8064030db78b81c370190a68a1a37c 100644
--- a/packages/backend/src/queue/processors/db/export-user-lists.ts
+++ b/packages/backend/src/queue/processors/db/export-user-lists.ts
@@ -4,7 +4,7 @@ import * as fs from 'fs';
 
 import { queueLogger } from '../../logger';
 import { addFile } from '@/services/drive/add-file';
-import * as dateFormat from 'dateformat';
+import { format as dateFormat } from 'date-fns';
 import { getFullApAccount } from '@/misc/convert-host';
 import { Users, UserLists, UserListJoinings } from '@/models/index';
 import { In } from 'typeorm';
@@ -62,7 +62,7 @@ export async function exportUserLists(job: Bull.Job<DbUserJobData>, done: any):
 	stream.end();
 	logger.succ(`Exported to: ${path}`);
 
-	const fileName = 'user-lists-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv';
+	const fileName = 'user-lists-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.csv';
 	const driveFile = await addFile({ user, path, name: fileName, force: true });
 
 	logger.succ(`Exported to: ${driveFile.id}`);
diff --git a/packages/backend/src/queue/processors/db/import-custom-emojis.ts b/packages/backend/src/queue/processors/db/import-custom-emojis.ts
index 04e93671edff374865a7f9706a67cd708d98ffe0..b6c012653429ebd4b14f84889ba0f40c33e42d9c 100644
--- a/packages/backend/src/queue/processors/db/import-custom-emojis.ts
+++ b/packages/backend/src/queue/processors/db/import-custom-emojis.ts
@@ -41,7 +41,9 @@ export async function importCustomEmojis(job: Bull.Job<DbUserImportJobData>, don
 		fs.writeFileSync(destPath, '', 'binary');
 		await downloadUrl(file.url, destPath);
 	} catch (e) { // TODO: 何度か再試行
-		logger.error(e);
+		if (e instanceof Error || typeof e === 'string') {
+			logger.error(e);
+		}
 		throw e;
 	}
 
diff --git a/packages/backend/src/queue/processors/db/import-user-lists.ts b/packages/backend/src/queue/processors/db/import-user-lists.ts
index e060e86dd80fa38c86894cb71c8fcf164d04ba42..9b3c0ed60eef00d2a4d389a299d3ee8d52753f6b 100644
--- a/packages/backend/src/queue/processors/db/import-user-lists.ts
+++ b/packages/backend/src/queue/processors/db/import-user-lists.ts
@@ -51,7 +51,6 @@ export async function importUserLists(job: Bull.Job<DbUserImportJobData>, done:
 					createdAt: new Date(),
 					userId: user.id,
 					name: listName,
-					userIds: [],
 				}).then(x => UserLists.findOneOrFail(x.identifiers[0]));
 			}
 
@@ -67,9 +66,9 @@ export async function importUserLists(job: Bull.Job<DbUserImportJobData>, done:
 				target = await resolveUser(username, host);
 			}
 
-			if (await UserListJoinings.findOne({ userListId: list.id, userId: target.id }) != null) continue;
+			if (await UserListJoinings.findOne({ userListId: list!.id, userId: target.id }) != null) continue;
 
-			pushUserToUserList(target, list);
+			pushUserToUserList(target, list!);
 		} catch (e) {
 			logger.warn(`Error in line:${linenum} ${e}`);
 		}
diff --git a/packages/backend/src/queue/processors/deliver.ts b/packages/backend/src/queue/processors/deliver.ts
index 46aeb8cb7ee6bc3dade64d68f630f20a297b58d6..bd91dfc3b57255644f5e0dcc0c6c755f763238c8 100644
--- a/packages/backend/src/queue/processors/deliver.ts
+++ b/packages/backend/src/queue/processors/deliver.ts
@@ -4,7 +4,7 @@ import request from '@/remote/activitypub/request';
 import { registerOrFetchInstanceDoc } from '@/services/register-or-fetch-instance-doc';
 import Logger from '@/services/logger';
 import { Instances } from '@/models/index';
-import { instanceChart } from '@/services/chart/index';
+import { apRequestChart, federationChart, instanceChart } from '@/services/chart/index';
 import { fetchInstanceMetadata } from '@/services/fetch-instance-metadata';
 import { fetchMeta } from '@/misc/fetch-meta';
 import { toPuny } from '@/misc/convert-host';
@@ -61,6 +61,8 @@ export default async (job: Bull.Job<DeliverJobData>) => {
 			fetchInstanceMetadata(i);
 
 			instanceChart.requestSent(i.host, true);
+			apRequestChart.deliverSucc();
+			federationChart.deliverd(i.host, true);
 		});
 
 		return 'Success';
@@ -74,6 +76,8 @@ export default async (job: Bull.Job<DeliverJobData>) => {
 			});
 
 			instanceChart.requestSent(i.host, false);
+			apRequestChart.deliverFail();
+			federationChart.deliverd(i.host, false);
 		});
 
 		if (res instanceof StatusError) {
diff --git a/packages/backend/src/queue/processors/inbox.ts b/packages/backend/src/queue/processors/inbox.ts
index bfdebc007732d5e5b694dcd937cb2a0aea11c3f4..c189256c335682a238a25d2464d6181b89eebcfc 100644
--- a/packages/backend/src/queue/processors/inbox.ts
+++ b/packages/backend/src/queue/processors/inbox.ts
@@ -5,7 +5,7 @@ import perform from '@/remote/activitypub/perform';
 import Logger from '@/services/logger';
 import { registerOrFetchInstanceDoc } from '@/services/register-or-fetch-instance-doc';
 import { Instances } from '@/models/index';
-import { instanceChart } from '@/services/chart/index';
+import { apRequestChart, federationChart, instanceChart } from '@/services/chart/index';
 import { fetchMeta } from '@/misc/fetch-meta';
 import { toPuny, extractDbHost } from '@/misc/convert-host';
 import { getApId } from '@/remote/activitypub/type';
@@ -54,10 +54,12 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
 			authUser = await dbResolver.getAuthUserFromApId(getApId(activity.actor));
 		} catch (e) {
 			// 対象が4xxならスキップ
-			if (e instanceof StatusError && e.isClientError) {
-				return `skip: Ignored deleted actors on both ends ${activity.actor} - ${e.statusCode}`;
+			if (e instanceof StatusError) {
+				if (e.isClientError) {
+					return `skip: Ignored deleted actors on both ends ${activity.actor} - ${e.statusCode}`;
+				}
+				throw `Error in actor ${activity.actor} - ${e.statusCode || e}`;
 			}
-			throw `Error in actor ${activity.actor} - ${e.statusCode || e}`;
 		}
 	}
 
@@ -141,6 +143,8 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
 		fetchInstanceMetadata(i);
 
 		instanceChart.requestReceived(i.host);
+		apRequestChart.inbox();
+		federationChart.inbox(i.host);
 	});
 
 	// アクティビティを処理
diff --git a/packages/backend/src/queue/processors/system/clean-charts.ts b/packages/backend/src/queue/processors/system/clean-charts.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3ae0f495f8f2c3dbf7e1d16425e18a6a547e0e19
--- /dev/null
+++ b/packages/backend/src/queue/processors/system/clean-charts.ts
@@ -0,0 +1,28 @@
+import * as Bull from 'bull';
+
+import { queueLogger } from '../../logger';
+import { activeUsersChart, driveChart, federationChart, hashtagChart, instanceChart, notesChart, perUserDriveChart, perUserFollowingChart, perUserNotesChart, perUserReactionsChart, usersChart, apRequestChart } from '@/services/chart/index';
+
+const logger = queueLogger.createSubLogger('clean-charts');
+
+export async function cleanCharts(job: Bull.Job<Record<string, unknown>>, done: any): Promise<void> {
+	logger.info(`Clean charts...`);
+
+	await Promise.all([
+		federationChart.clean(),
+		notesChart.clean(),
+		usersChart.clean(),
+		activeUsersChart.clean(),
+		instanceChart.clean(),
+		perUserNotesChart.clean(),
+		driveChart.clean(),
+		perUserReactionsChart.clean(),
+		hashtagChart.clean(),
+		perUserFollowingChart.clean(),
+		perUserDriveChart.clean(),
+		apRequestChart.clean(),
+	]);
+
+	logger.succ(`All charts successfully cleaned.`);
+	done();
+}
diff --git a/packages/backend/src/queue/processors/system/index.ts b/packages/backend/src/queue/processors/system/index.ts
index 8460ea0a9b4280886e433297d33cd120fd6c5df3..636fefc4025c923bffa31f5d6dab37ca0c70c862 100644
--- a/packages/backend/src/queue/processors/system/index.ts
+++ b/packages/backend/src/queue/processors/system/index.ts
@@ -1,8 +1,10 @@
 import * as Bull from 'bull';
 import { resyncCharts } from './resync-charts';
+import { cleanCharts } from './clean-charts';
 
 const jobs = {
 	resyncCharts,
+	cleanCharts,
 } as Record<string, Bull.ProcessCallbackFunction<Record<string, unknown>> | Bull.ProcessPromiseFunction<Record<string, unknown>>>;
 
 export default function(dbQueue: Bull.Queue<Record<string, unknown>>) {
diff --git a/packages/backend/src/remote/activitypub/kernel/announce/note.ts b/packages/backend/src/remote/activitypub/kernel/announce/note.ts
index e9158f77526eea31d72fc3da2dc60f1111552973..eae92d4180a55f63268d7f64ec357be899df613b 100644
--- a/packages/backend/src/remote/activitypub/kernel/announce/note.ts
+++ b/packages/backend/src/remote/activitypub/kernel/announce/note.ts
@@ -42,11 +42,14 @@ export default async function(resolver: Resolver, actor: IRemoteUser, activity:
 			renote = await resolveNote(targetUri);
 		} catch (e) {
 			// 対象が4xxならスキップ
-			if (e instanceof StatusError && e.isClientError) {
-				logger.warn(`Ignored announce target ${targetUri} - ${e.statusCode}`);
-				return;
+			if (e instanceof StatusError) {
+				if (e.isClientError) {
+					logger.warn(`Ignored announce target ${targetUri} - ${e.statusCode}`);
+					return;
+				}
+
+				logger.warn(`Error in announce target ${targetUri} - ${e.statusCode || e}`);
 			}
-			logger.warn(`Error in announce target ${targetUri} - ${e.statusCode || e}`);
 			throw e;
 		}
 
diff --git a/packages/backend/src/remote/activitypub/kernel/flag/index.ts b/packages/backend/src/remote/activitypub/kernel/flag/index.ts
index aec6d2daaa7615116d1b7d9808e169561cde32eb..d910e2ebe239c9acd5ed60bdd3eb8f2bd572390e 100644
--- a/packages/backend/src/remote/activitypub/kernel/flag/index.ts
+++ b/packages/backend/src/remote/activitypub/kernel/flag/index.ts
@@ -10,7 +10,7 @@ export default async (actor: IRemoteUser, activity: IFlag): Promise<string> => {
 	// 対象ユーザーは一番最初のユーザー として あとはコメントとして格納する
 	const uris = getApIds(activity.object);
 
-	const userIds = uris.filter(uri => uri.startsWith(config.url + '/users/')).map(uri => uri.split('/').pop());
+	const userIds = uris.filter(uri => uri.startsWith(config.url + '/users/')).map(uri => uri.split('/').pop()!);
 	const users = await Users.find({
 		id: In(userIds),
 	});
diff --git a/packages/backend/src/remote/activitypub/kernel/index.ts b/packages/backend/src/remote/activitypub/kernel/index.ts
index 20df28eec62455bdf8df61b03b8658c78fa3ae24..a103e5a1be42c6d9f4a48d6b4328a6338b37877e 100644
--- a/packages/backend/src/remote/activitypub/kernel/index.ts
+++ b/packages/backend/src/remote/activitypub/kernel/index.ts
@@ -25,8 +25,10 @@ export async function performActivity(actor: IRemoteUser, activity: IObject) {
 			const act = await resolver.resolve(item);
 			try {
 				await performOneActivity(actor, act);
-			} catch (e) {
-				apLogger.error(e);
+			} catch (err) {
+				if (err instanceof Error || typeof err === 'string') {
+					apLogger.error(err);
+				}
 			}
 		}
 	} else {
diff --git a/packages/backend/src/remote/activitypub/misc/ld-signature.ts b/packages/backend/src/remote/activitypub/misc/ld-signature.ts
index 946914bfaa5ad2321962a911da573b514587b0d2..3b799c755c6a30d79f13d635b03b39e90a8e3efc 100644
--- a/packages/backend/src/remote/activitypub/misc/ld-signature.ts
+++ b/packages/backend/src/remote/activitypub/misc/ld-signature.ts
@@ -24,7 +24,7 @@ export class LdSignature {
 		} as {
 			type: string;
 			creator: string;
-			domain: string;
+			domain?: string;
 			nonce: string;
 			created: string;
 		};
@@ -114,7 +114,7 @@ export class LdSignature {
 				Accept: 'application/ld+json, application/json',
 			},
 			timeout: this.loderTimeout,
-			agent: u => u.protocol == 'http:' ? httpAgent : httpsAgent,
+			agent: u => u.protocol === 'http:' ? httpAgent : httpsAgent,
 		}).then(res => {
 			if (!res.ok) {
 				throw `${res.status} ${res.statusText}`;
diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts
index 19a7a70903b3ad520e8066c6d39ece6f47a50e98..aaccf51fa9ddeb0a3ada9f9dab9730f5758f608a 100644
--- a/packages/backend/src/remote/activitypub/models/person.ts
+++ b/packages/backend/src/remote/activitypub/models/person.ts
@@ -164,6 +164,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 				tags,
 				isBot,
 				isCat: (person as any).isCat === true,
+				showTimelineReplies: false,
 			})) as IRemoteUser;
 
 			await transactionalEntityManager.save(new UserProfile({
diff --git a/packages/backend/src/remote/activitypub/renderer/note.ts b/packages/backend/src/remote/activitypub/renderer/note.ts
index 4f9a372b2f4652d0dc6a9521f9236afd93bcdf71..654ab68123e45e595360a82e735c1d84572d6e2b 100644
--- a/packages/backend/src/remote/activitypub/renderer/note.ts
+++ b/packages/backend/src/remote/activitypub/renderer/note.ts
@@ -11,7 +11,7 @@ import { In } from 'typeorm';
 import { Emoji } from '@/models/entities/emoji';
 import { Poll } from '@/models/entities/poll';
 
-export default async function renderNote(note: Note, dive = true, isTalk = false): Promise<any> {
+export default async function renderNote(note: Note, dive = true, isTalk = false): Promise<Record<string, unknown>> {
 	const getPromisedFiles = async (ids: string[]) => {
 		if (!ids || ids.length === 0) return [];
 		const items = await DriveFiles.find({ id: In(ids) });
diff --git a/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts b/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts
index c4b4337af883cda5341a565ad29046ab23086cd6..ff9a77be3db2250d43e70f0d9e25f1acacdea7a0 100644
--- a/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts
+++ b/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts
@@ -6,7 +6,14 @@
  * @param last URL of last page (optional)
  * @param orderedItems attached objects (optional)
  */
-export default function(id: string | null, totalItems: any, first?: string, last?: string, orderedItems?: Record<string, unknown>) {
+export default function(id: string | null, totalItems: any, first?: string, last?: string, orderedItems?: Record<string, unknown>[]): {
+	id: string | null;
+	type: 'OrderedCollection';
+	totalItems: any;
+	first?: string;
+	last?: string;
+	orderedItems?: Record<string, unknown>[];
+} {
 	const page: any = {
 		id,
 		type: 'OrderedCollection',
diff --git a/packages/backend/src/server/activitypub/featured.ts b/packages/backend/src/server/activitypub/featured.ts
index 40b8d8cc817f170885c3fa203d6a6180ce63c3b3..ed5bfc4267bd77905749dc0a4a4878da64a44ef8 100644
--- a/packages/backend/src/server/activitypub/featured.ts
+++ b/packages/backend/src/server/activitypub/featured.ts
@@ -32,7 +32,7 @@ export default async (ctx: Router.RouterContext) => {
 
 	const rendered = renderOrderedCollection(
 		`${config.url}/users/${userId}/collections/featured`,
-		renderedNotes.length, undefined, undefined, renderedNotes
+		renderedNotes.length, undefined, undefined, renderedNotes,
 	);
 
 	ctx.body = renderActivity(rendered);
diff --git a/packages/backend/src/server/api/call.ts b/packages/backend/src/server/api/call.ts
index 5bc7d2f25e98feda0e4646392acdb30f62bf61f9..18143340ae8dc9e9f124d129f923a16cf5bf63d2 100644
--- a/packages/backend/src/server/api/call.ts
+++ b/packages/backend/src/server/api/call.ts
@@ -79,18 +79,28 @@ export default async (endpoint: string, user: User | null | undefined, token: Ac
 
 	// Cast non JSON input
 	if (ep.meta.requireFile && ep.meta.params) {
-		const body = (ctx!.request as any).body;
 		for (const k of Object.keys(ep.meta.params)) {
 			const param = ep.meta.params[k];
-			if (['Boolean', 'Number'].includes(param.validator.name) && typeof body[k] === 'string') {
-				body[k] = JSON.parse(body[k]);
+			if (['Boolean', 'Number'].includes(param.validator.name) && typeof data[k] === 'string') {
+				try {
+					data[k] = JSON.parse(data[k]);
+				} catch (e) {
+					throw	new ApiError({
+						message: 'Invalid param.',
+						code: 'INVALID_PARAM',
+						id: '0b5f1631-7c1a-41a6-b399-cce335f34d85',
+					}, {
+						param: k,
+						reason: `cannot cast to ${param.validator.name}`,
+					})
+				}
 			}
 		}
 	}
 
 	// API invoking
 	const before = performance.now();
-	return await ep.exec(data, user, token, ctx!.file).catch((e: Error) => {
+	return await ep.exec(data, user, token, ctx?.file).catch((e: Error) => {
 		if (e instanceof ApiError) {
 			throw e;
 		} else {
diff --git a/packages/backend/src/server/api/common/generate-replies-query.ts b/packages/backend/src/server/api/common/generate-replies-query.ts
index fbc41b2c253b75f2bec67ff2efcd64ce57c2743d..249064d5894ced164795cc90ab83ed1f1882cbc0 100644
--- a/packages/backend/src/server/api/common/generate-replies-query.ts
+++ b/packages/backend/src/server/api/common/generate-replies-query.ts
@@ -1,7 +1,7 @@
 import { User } from '@/models/entities/user';
 import { Brackets, SelectQueryBuilder } from 'typeorm';
 
-export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: { id: User['id'] } | null) {
+export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: Pick<User, 'id' | 'showTimelineReplies'> | null) {
 	if (me == null) {
 		q.andWhere(new Brackets(qb => { qb
 			.where(`note.replyId IS NULL`) // 返信ではない
@@ -10,7 +10,7 @@ export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: { id: User
 				.andWhere('note.replyUserId = note.userId');
 			}));
 		}));
-	} else {
+	} else if(!me.showTimelineReplies) {
 		q.andWhere(new Brackets(qb => { qb
 			.where(`note.replyId IS NULL`) // 返信ではない
 			.orWhere('note.replyUserId = :meId', { meId: me.id }) // 返信だけど自分のノートへの返信
diff --git a/packages/backend/src/server/api/define.ts b/packages/backend/src/server/api/define.ts
index 71e5fadde042d5265c7aebe7a1438d9242bebf0c..e0720e2adb80e91d9413100f816713c052b692a5 100644
--- a/packages/backend/src/server/api/define.ts
+++ b/packages/backend/src/server/api/define.ts
@@ -9,6 +9,7 @@ type NonOptional<T> = T extends undefined ? never : T;
 
 type SimpleUserInfo = {
 	id: ILocalUser['id'];
+	createdAt: ILocalUser['createdAt'];
 	host: ILocalUser['host'];
 	username: ILocalUser['username'];
 	uri: ILocalUser['uri'];
diff --git a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts
index b00457f0925b5ef8e86d6261e2ccc15dc5d34ff9..a47b69ec1a6f10538c1655c43b8162bd73833da3 100644
--- a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts
+++ b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts
@@ -36,9 +36,9 @@ export default define(meta, async (ps, me) => {
 
 	if (ps.forward && report.targetUserHost != null) {
 		const actor = await getInstanceActor();
-		const targetUser = await Users.findOne(report.targetUserId);
+		const targetUser = await Users.findOneOrFail(report.targetUserId);
 
-		deliver(actor, renderActivity(renderFlag(actor, [targetUser.uri], report.comment)), targetUser.inbox);
+		deliver(actor, renderActivity(renderFlag(actor, [targetUser.uri!], report.comment)), targetUser.inbox);
 	}
 
 	await AbuseUserReports.update(report.id, {
diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts
index c2a6a294b5ff2a2eb20d2c968a23a1a81ad41673..0d0cc9087a70dbc6eef569a9e6055d42b669f8cd 100644
--- a/packages/backend/src/server/api/endpoints/admin/show-user.ts
+++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts
@@ -18,144 +18,6 @@ export const meta = {
 	res: {
 		type: 'object',
 		nullable: false, optional: false,
-		properties: {
-			id: {
-				type: 'string',
-				nullable: false, optional: false,
-				format: 'id',
-			},
-			createdAt: {
-				type: 'string',
-				nullable: false, optional: false,
-				format: 'date-time',
-			},
-			updatedAt: {
-				type: 'string',
-				nullable: true, optional: false,
-				format: 'date-time',
-			},
-			lastFetchedAt: {
-				type: 'string',
-				nullable: true, optional: false,
-			},
-			username: {
-				type: 'string',
-				nullable: false, optional: false,
-			},
-			name: {
-				type: 'string',
-				nullable: true, optional: false,
-			},
-			folowersCount: {
-				type: 'number',
-				nullable: false, optional: true,
-			},
-			followingCount: {
-				type: 'number',
-				nullable: false, optional: false,
-			},
-			notesCount: {
-				type: 'number',
-				nullable: false, optional: false,
-			},
-			avatarId: {
-				type: 'string',
-				nullable: true, optional: false,
-			},
-			bannerId: {
-				type: 'string',
-				nullable: true, optional: false,
-			},
-			tags: {
-				type: 'array',
-				nullable: false, optional: false,
-				items: {
-					type: 'string',
-					nullable: false, optional: false,
-				},
-			},
-			avatarUrl: {
-				type: 'string',
-				nullable: true, optional: false,
-				format: 'url',
-			},
-			bannerUrl: {
-				type: 'string',
-				nullable: true, optional: false,
-				format: 'url',
-			},
-			avatarBlurhash: {
-				type: 'any',
-				nullable: true, optional: false,
-				default: null,
-			},
-			bannerBlurhash: {
-				type: 'any',
-				nullable: true, optional: false,
-				default: null,
-			},
-			isSuspended: {
-				type: 'boolean',
-				nullable: false, optional: false,
-			},
-			isSilenced: {
-				type: 'boolean',
-				nullable: false, optional: false,
-			},
-			isLocked: {
-				type: 'boolean',
-				nullable: false, optional: false,
-			},
-			isBot: {
-				type: 'boolean',
-				nullable: false, optional: false,
-			},
-			isCat: {
-				type: 'boolean',
-				nullable: false, optional: false,
-			},
-			isAdmin: {
-				type: 'boolean',
-				nullable: false, optional: false,
-			},
-			isModerator: {
-				type: 'boolean',
-				nullable: false, optional: false,
-			},
-			emojis: {
-				type: 'array',
-				nullable: false, optional: false,
-				items: {
-					type: 'string',
-					nullable: false, optional: false,
-				},
-			},
-			host: {
-				type: 'string',
-				nullable: true, optional: false,
-			},
-			inbox: {
-				type: 'string',
-				nullable: true, optional: false,
-			},
-			sharedInbox: {
-				type: 'string',
-				nullable: true, optional: false,
-			},
-			featured: {
-				type: 'string',
-				nullable: true, optional: false,
-			},
-			uri: {
-				type: 'string',
-				nullable: true, optional: false,
-			},
-			token: {
-				type: 'string',
-				nullable: true, optional: false,
-				default: '<MASKED>',
-			},
-		},
 	},
 } as const;
 
diff --git a/packages/backend/src/server/api/endpoints/announcements.ts b/packages/backend/src/server/api/endpoints/announcements.ts
index 0bd29607d68532cea1aa81fd1928ae0d1c2c303c..22c13743a8d50330530c5d0431bdc919fad1b874 100644
--- a/packages/backend/src/server/api/endpoints/announcements.ts
+++ b/packages/backend/src/server/api/endpoints/announcements.ts
@@ -89,5 +89,9 @@ export default define(meta, async (ps, user) => {
 		}
 	}
 
-	return ps.withUnreads ? announcements.filter((a: any) => !a.isRead) : announcements;
+	return (ps.withUnreads ? announcements.filter((a: any) => !a.isRead) : announcements).map((a) => ({
+		...a,
+		createdAt: a.createdAt.toISOString(),
+		updatedAt: a.updatedAt?.toISOString() ?? null,
+	}));
 });
diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts
index 927ce7c741a28f7d3a97133b1a5c6810b62fcc09..2639095f8af46ca23bac7bd2d7272b2189318a7f 100644
--- a/packages/backend/src/server/api/endpoints/channels/timeline.ts
+++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts
@@ -80,7 +80,7 @@ export default define(meta, async (ps, user) => {
 
 	const timeline = await query.take(ps.limit!).getMany();
 
-	if (user) activeUsersChart.update(user);
+	if (user) activeUsersChart.read(user);
 
 	return await Notes.packMany(timeline, user);
 });
diff --git a/packages/backend/src/server/api/endpoints/charts/active-users.ts b/packages/backend/src/server/api/endpoints/charts/active-users.ts
index f7eadc70893b60b876f503f852f249f2414eede7..a51cd00351c4af3744e722e45474bfa5dfa7dac3 100644
--- a/packages/backend/src/server/api/endpoints/charts/active-users.ts
+++ b/packages/backend/src/server/api/endpoints/charts/active-users.ts
@@ -22,7 +22,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(activeUsersChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/network.ts b/packages/backend/src/server/api/endpoints/charts/ap-request.ts
similarity index 71%
rename from packages/backend/src/server/api/endpoints/charts/network.ts
rename to packages/backend/src/server/api/endpoints/charts/ap-request.ts
index c5a39bbd7656881b302902af17d1a87283957321..38bbddb27a1d955a6d9d46d155b4c85e59015ab9 100644
--- a/packages/backend/src/server/api/endpoints/charts/network.ts
+++ b/packages/backend/src/server/api/endpoints/charts/ap-request.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import define from '../../define';
 import { convertLog } from '@/services/chart/core';
-import { networkChart } from '@/services/chart/index';
+import { apRequestChart } from '@/services/chart/index';
 
 export const meta = {
 	tags: ['charts'],
@@ -22,10 +22,10 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(networkChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
 export default define(meta, async (ps) => {
-	return await networkChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null);
+	return await apRequestChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null);
 });
diff --git a/packages/backend/src/server/api/endpoints/charts/drive.ts b/packages/backend/src/server/api/endpoints/charts/drive.ts
index 364279da95405b3ba71bbaddb8d2a157f90aaaac..4bbb9861f8e4013bb736e872285b4b1d764ce94d 100644
--- a/packages/backend/src/server/api/endpoints/charts/drive.ts
+++ b/packages/backend/src/server/api/endpoints/charts/drive.ts
@@ -22,7 +22,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(driveChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/federation.ts b/packages/backend/src/server/api/endpoints/charts/federation.ts
index 6feb82b6d91eeff8e6b6cfe1ce1b493cc7c08294..237678ffed116e272c33e79452e9b96be9265a49 100644
--- a/packages/backend/src/server/api/endpoints/charts/federation.ts
+++ b/packages/backend/src/server/api/endpoints/charts/federation.ts
@@ -22,7 +22,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(federationChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/hashtag.ts b/packages/backend/src/server/api/endpoints/charts/hashtag.ts
index 99dc77998e04f602bac4361cdf29449878f159ea..6c12cb063ec1a36bad065ecbb5ba5693c61c26f9 100644
--- a/packages/backend/src/server/api/endpoints/charts/hashtag.ts
+++ b/packages/backend/src/server/api/endpoints/charts/hashtag.ts
@@ -26,7 +26,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(hashtagChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/instance.ts b/packages/backend/src/server/api/endpoints/charts/instance.ts
index 23e6fbf2b00f2479f961ef8f9add48c6d0d45f9e..32a10d5a28026e4ad8f957991dc30eeb184ec18f 100644
--- a/packages/backend/src/server/api/endpoints/charts/instance.ts
+++ b/packages/backend/src/server/api/endpoints/charts/instance.ts
@@ -26,7 +26,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(instanceChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/notes.ts b/packages/backend/src/server/api/endpoints/charts/notes.ts
index dcbd80c3e9744b2fb0531c742afeff7ac1245679..09255f1d2da6d25cbcb6575a638ef53a27cdd284 100644
--- a/packages/backend/src/server/api/endpoints/charts/notes.ts
+++ b/packages/backend/src/server/api/endpoints/charts/notes.ts
@@ -22,7 +22,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(notesChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/user/drive.ts b/packages/backend/src/server/api/endpoints/charts/user/drive.ts
index 94787b4a578aee0c25cd4062401ebb73c53bb707..89379858d1a005d5348b3a4fd39bfee3ded25703 100644
--- a/packages/backend/src/server/api/endpoints/charts/user/drive.ts
+++ b/packages/backend/src/server/api/endpoints/charts/user/drive.ts
@@ -27,7 +27,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(perUserDriveChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/user/following.ts b/packages/backend/src/server/api/endpoints/charts/user/following.ts
index effe0c54b9969ce013d0a651c156dcadbfe19c4c..26c3f5c126ee1dd25cef1c6ad9eab12fa97058a5 100644
--- a/packages/backend/src/server/api/endpoints/charts/user/following.ts
+++ b/packages/backend/src/server/api/endpoints/charts/user/following.ts
@@ -27,7 +27,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(perUserFollowingChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/user/notes.ts b/packages/backend/src/server/api/endpoints/charts/user/notes.ts
index df68a5fe524185230da53b5ef4127e4c7d88880a..ecf85becfa2b01beda4681198fee6851ec4a6147 100644
--- a/packages/backend/src/server/api/endpoints/charts/user/notes.ts
+++ b/packages/backend/src/server/api/endpoints/charts/user/notes.ts
@@ -27,7 +27,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(perUserNotesChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/user/reactions.ts b/packages/backend/src/server/api/endpoints/charts/user/reactions.ts
index dcd067305ff9245d75cd31221fead953f2bdafa9..6e08d07511b724c070fd04f45b45d19e09d85aef 100644
--- a/packages/backend/src/server/api/endpoints/charts/user/reactions.ts
+++ b/packages/backend/src/server/api/endpoints/charts/user/reactions.ts
@@ -27,7 +27,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(perUserReactionsChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/charts/users.ts b/packages/backend/src/server/api/endpoints/charts/users.ts
index d32e14ad61210d4b63e0257976205fc98756a599..15a9ec038e4b53a63babc96942de9326b92915d6 100644
--- a/packages/backend/src/server/api/endpoints/charts/users.ts
+++ b/packages/backend/src/server/api/endpoints/charts/users.ts
@@ -22,7 +22,7 @@ export const meta = {
 		},
 	},
 
-	res: convertLog(usersChart.schema),
+	// TODO: response definition
 } as const;
 
 // eslint-disable-next-line import/no-default-export
diff --git a/packages/backend/src/server/api/endpoints/drive/files/create.ts b/packages/backend/src/server/api/endpoints/drive/files/create.ts
index 877e76677eabe078bae12ed8c63e77229a831757..ac7863ec7edb43ca3c5f30a171b9c5af6d62f300 100644
--- a/packages/backend/src/server/api/endpoints/drive/files/create.ts
+++ b/packages/backend/src/server/api/endpoints/drive/files/create.ts
@@ -86,7 +86,9 @@ export default define(meta, async (ps, user, _, file, cleanup) => {
 		const driveFile = await addFile({ user, path: file.path, name, comment: ps.comment, folderId: ps.folderId, force: ps.force, sensitive: ps.isSensitive });
 		return await DriveFiles.pack(driveFile, { self: true });
 	} catch (e) {
-		apiLogger.error(e);
+		if (e instanceof Error || typeof e === 'string') {
+			apiLogger.error(e);
+		}
 		throw new ApiError();
 	} finally {
 		cleanup!();
diff --git a/packages/backend/src/server/api/endpoints/following/create.ts b/packages/backend/src/server/api/endpoints/following/create.ts
index 96aede45502277127abf665384fe729de3411905..b840ab7696cd46931f456b230b83a36fffc5c197 100644
--- a/packages/backend/src/server/api/endpoints/following/create.ts
+++ b/packages/backend/src/server/api/endpoints/following/create.ts
@@ -6,6 +6,7 @@ import define from '../../define';
 import { ApiError } from '../../error';
 import { getUser } from '../../common/getters';
 import { Followings, Users } from '@/models/index';
+import { IdentifiableError } from '@/misc/identifiable-error';
 
 export const meta = {
 	tags: ['following', 'users'],
@@ -92,8 +93,10 @@ export default define(meta, async (ps, user) => {
 	try {
 		await create(follower, followee);
 	} catch (e) {
-		if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking);
-		if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked);
+		if (e instanceof IdentifiableError) {
+			if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking);
+			if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked);
+		}
 		throw e;
 	}
 
diff --git a/packages/backend/src/server/api/endpoints/following/requests/cancel.ts b/packages/backend/src/server/api/endpoints/following/requests/cancel.ts
index 19ed02c152f3ec266df5b8293741dd7cf6434c22..c9abbf36decd91616551fdc07fbf8f0aa20d49cc 100644
--- a/packages/backend/src/server/api/endpoints/following/requests/cancel.ts
+++ b/packages/backend/src/server/api/endpoints/following/requests/cancel.ts
@@ -5,6 +5,7 @@ import define from '../../../define';
 import { ApiError } from '../../../error';
 import { getUser } from '../../../common/getters';
 import { Users } from '@/models/index';
+import { IdentifiableError } from '@/misc/identifiable-error';
 
 export const meta = {
 	tags: ['following', 'account'],
@@ -51,7 +52,9 @@ export default define(meta, async (ps, user) => {
 	try {
 		await cancelFollowRequest(followee, user);
 	} catch (e) {
-		if (e.id === '17447091-ce07-46dd-b331-c1fd4f15b1e7') throw new ApiError(meta.errors.followRequestNotFound);
+		if (e instanceof IdentifiableError) {
+			if (e.id === '17447091-ce07-46dd-b331-c1fd4f15b1e7') throw new ApiError(meta.errors.followRequestNotFound);
+		}
 		throw e;
 	}
 
diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts
index 6b7e53aa1fbe201e43e8a8b7074f9fc229cc3618..eb57aa2bfc25e3145da894ef0b4d4fb9f0b0aff0 100644
--- a/packages/backend/src/server/api/endpoints/i/update.ts
+++ b/packages/backend/src/server/api/endpoints/i/update.ts
@@ -96,6 +96,10 @@ export const meta = {
 			validator: $.optional.bool,
 		},
 
+		showTimelineReplies: {
+			validator: $.optional.bool,
+		},
+
 		injectFeaturedNote: {
 			validator: $.optional.bool,
 		},
@@ -197,6 +201,7 @@ export default define(meta, async (ps, _user, token) => {
 	if (typeof ps.hideOnlineStatus === 'boolean') updates.hideOnlineStatus = ps.hideOnlineStatus;
 	if (typeof ps.publicReactions === 'boolean') profileUpdates.publicReactions = ps.publicReactions;
 	if (typeof ps.isBot === 'boolean') updates.isBot = ps.isBot;
+	if (typeof ps.showTimelineReplies === 'boolean') updates.showTimelineReplies = ps.showTimelineReplies;
 	if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot;
 	if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
 	if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle;
diff --git a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts
index cac8b7d8a99633196b7d8cdeba01cb69ac3e51ae..cdd110994e333985bb129d2562ac8e42cfe60d8e 100644
--- a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts
@@ -96,7 +96,7 @@ export default define(meta, async (ps, user) => {
 
 	process.nextTick(() => {
 		if (user) {
-			activeUsersChart.update(user);
+			activeUsersChart.read(user);
 		}
 	});
 
diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
index 9683df4611e5d0edf0885605de8711974677acc4..b43849102622a839ea66e900754624f9808ecc88 100644
--- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
@@ -153,7 +153,7 @@ export default define(meta, async (ps, user) => {
 
 	process.nextTick(() => {
 		if (user) {
-			activeUsersChart.update(user);
+			activeUsersChart.read(user);
 		}
 	});
 
diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
index 77766441242e59d7cb0ec854144dac77f667dc8d..ce0bcbeb7bab223094997f88556a05b0349545f6 100644
--- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
@@ -122,7 +122,7 @@ export default define(meta, async (ps, user) => {
 
 	process.nextTick(() => {
 		if (user) {
-			activeUsersChart.update(user);
+			activeUsersChart.read(user);
 		}
 	});
 
diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts
index 8be2861aece38d3f7717bf3f11506dcd73a1f72e..f8cd083249a76efd568e17ea4390006d264e38ff 100644
--- a/packages/backend/src/server/api/endpoints/notes/timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts
@@ -145,7 +145,7 @@ export default define(meta, async (ps, user) => {
 
 	process.nextTick(() => {
 		if (user) {
-			activeUsersChart.update(user);
+			activeUsersChart.read(user);
 		}
 	});
 
diff --git a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts
index 89de73fb9d2c78675268231f682abbcc26dae139..3512fb3638c408efde12a81cca5ad941ec1f11a5 100644
--- a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts
@@ -142,7 +142,7 @@ export default define(meta, async (ps, user) => {
 
 	const timeline = await query.take(ps.limit!).getMany();
 
-	activeUsersChart.update(user);
+	activeUsersChart.read(user);
 
 	return await Notes.packMany(timeline, user);
 });
diff --git a/packages/backend/src/server/api/endpoints/stats.ts b/packages/backend/src/server/api/endpoints/stats.ts
index 9879ef2adf3a4c30c134916a5ed0a5c9c3244e61..17281888a6d72fceb6f3e841e17760031a880eb7 100644
--- a/packages/backend/src/server/api/endpoints/stats.ts
+++ b/packages/backend/src/server/api/endpoints/stats.ts
@@ -56,8 +56,6 @@ export default define(meta, async () => {
 		reactionsCount,
 		//originalReactionsCount,
 		instances,
-		driveUsageLocal,
-		driveUsageRemote,
 	] = await Promise.all([
 		Notes.count({ cache: 3600000 }), // 1 hour
 		Notes.count({ where: { userHost: null }, cache: 3600000 }),
@@ -66,8 +64,6 @@ export default define(meta, async () => {
 		NoteReactions.count({ cache: 3600000 }), // 1 hour
 		//NoteReactions.count({ where: { userHost: null }, cache: 3600000 }),
 		federationChart.getChart('hour', 1, null).then(chart => chart.instance.total[0]),
-		driveChart.getChart('hour', 1, null).then(chart => chart.local.totalSize[0]),
-		driveChart.getChart('hour', 1, null).then(chart => chart.remote.totalSize[0]),
 	]);
 
 	return {
@@ -78,7 +74,7 @@ export default define(meta, async () => {
 		reactionsCount,
 		//originalReactionsCount,
 		instances,
-		driveUsageLocal,
-		driveUsageRemote,
+		driveUsageLocal: 0,
+		driveUsageRemote: 0,
 	};
 });
diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts
index d67625e624fd84ecdc64f8634b0464d4c780484b..72e79c88249ecb86b5df5c397a2429c84e651a45 100644
--- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts
+++ b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts
@@ -114,4 +114,6 @@ export default define(meta, async (ps, me) => {
 
 		return await Users.packMany(users, me, { detail: !!ps.detail });
 	}
+
+	return [];
 });
diff --git a/packages/backend/src/server/api/service/discord.ts b/packages/backend/src/server/api/service/discord.ts
index f574fe3878a97b58dae299837a14f0b588b39694..dd731c422e84f7102d74d658219e2f856ef2972c 100644
--- a/packages/backend/src/server/api/service/discord.ts
+++ b/packages/backend/src/server/api/service/discord.ts
@@ -11,18 +11,18 @@ import { fetchMeta } from '@/misc/fetch-meta';
 import { Users, UserProfiles } from '@/models/index';
 import { ILocalUser } from '@/models/entities/user';
 
-function getUserToken(ctx: Koa.Context) {
+function getUserToken(ctx: Koa.BaseContext): string | null {
 	return ((ctx.headers['cookie'] || '').match(/igi=(\w+)/) || [null, null])[1];
 }
 
-function compareOrigin(ctx: Koa.Context) {
-	function normalizeUrl(url: string) {
+function compareOrigin(ctx: Koa.BaseContext): boolean {
+	function normalizeUrl(url?: string): string {
 		return url ? url.endsWith('/') ? url.substr(0, url.length - 1) : url : '';
 	}
 
 	const referer = ctx.headers['referer'];
 
-	return (normalizeUrl(referer) == normalizeUrl(config.url));
+	return (normalizeUrl(referer) === normalizeUrl(config.url));
 }
 
 // Init router
diff --git a/packages/backend/src/server/api/service/github.ts b/packages/backend/src/server/api/service/github.ts
index 5e0839df9378ec8d99640e59ef21ad3cf4938cc1..b23219986a95b17390ff3d15c2199637aa620a2d 100644
--- a/packages/backend/src/server/api/service/github.ts
+++ b/packages/backend/src/server/api/service/github.ts
@@ -11,18 +11,18 @@ import { fetchMeta } from '@/misc/fetch-meta';
 import { Users, UserProfiles } from '@/models/index';
 import { ILocalUser } from '@/models/entities/user';
 
-function getUserToken(ctx: Koa.Context) {
+function getUserToken(ctx: Koa.BaseContext): string | null {
 	return ((ctx.headers['cookie'] || '').match(/igi=(\w+)/) || [null, null])[1];
 }
 
-function compareOrigin(ctx: Koa.Context) {
-	function normalizeUrl(url: string) {
+function compareOrigin(ctx: Koa.BaseContext): boolean {
+	function normalizeUrl(url?: string): string {
 		return url ? url.endsWith('/') ? url.substr(0, url.length - 1) : url : '';
 	}
 
 	const referer = ctx.headers['referer'];
 
-	return (normalizeUrl(referer) == normalizeUrl(config.url));
+	return (normalizeUrl(referer) === normalizeUrl(config.url));
 }
 
 // Init router
diff --git a/packages/backend/src/server/api/service/twitter.ts b/packages/backend/src/server/api/service/twitter.ts
index 8659b82cbe1d54063ec2087d5ad6e8afdcf56c95..bca00b7924a381299668fc638014d25edaec3eb5 100644
--- a/packages/backend/src/server/api/service/twitter.ts
+++ b/packages/backend/src/server/api/service/twitter.ts
@@ -10,18 +10,18 @@ import { fetchMeta } from '@/misc/fetch-meta';
 import { Users, UserProfiles } from '@/models/index';
 import { ILocalUser } from '@/models/entities/user';
 
-function getUserToken(ctx: Koa.Context) {
+function getUserToken(ctx: Koa.BaseContext): string | null {
 	return ((ctx.headers['cookie'] || '').match(/igi=(\w+)/) || [null, null])[1];
 }
 
-function compareOrigin(ctx: Koa.Context) {
-	function normalizeUrl(url: string) {
-		return url.endsWith('/') ? url.substr(0, url.length - 1) : url;
+function compareOrigin(ctx: Koa.BaseContext): boolean {
+	function normalizeUrl(url?: string): string {
+		return url == null ? '' : url.endsWith('/') ? url.substr(0, url.length - 1) : url;
 	}
 
 	const referer = ctx.headers['referer'];
 
-	return (normalizeUrl(referer) == normalizeUrl(config.url));
+	return (normalizeUrl(referer) === normalizeUrl(config.url));
 }
 
 // Init router
diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts
index f14f597aac414aeef73195b636533448177dcea8..ecd87d093dd79dbc07e4e9f8ac09f58b7dab43cf 100644
--- a/packages/backend/src/server/api/stream/channels/global-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts
@@ -43,7 +43,7 @@ export default class extends Channel {
 		}
 
 		// 関係ない返信は除外
-		if (note.reply) {
+		if (note.reply && !this.user!.showTimelineReplies) {
 			const reply = note.reply;
 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
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 3bd491421dbe55e21911ffed1fadb1b8abb86f60..445db5c382add75df378ccf4055c49dade808f32 100644
--- a/packages/backend/src/server/api/stream/channels/home-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts
@@ -54,7 +54,7 @@ export default class extends Channel {
 		}
 
 		// 関係ない返信は除外
-		if (note.reply) {
+		if (note.reply && !this.user!.showTimelineReplies) {
 			const reply = note.reply;
 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
index 0ae19aa7ce85df49f3c6566a7c85dc6a3ad663fe..c0be71fe2d5ef0828ae26b23661b2b0382faef85 100644
--- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
@@ -62,7 +62,7 @@ export default class extends Channel {
 		if (isInstanceMuted(note, new Set<string>(this.userProfile?.mutedInstances ?? []))) return;
 
 		// 関係ない返信は除外
-		if (note.reply) {
+		if (note.reply && !this.user!.showTimelineReplies) {
 			const reply = note.reply;
 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts
index 3178b1d511e4c99f9746e989eeed4aabd7a3c975..ae8f62ba6136e2118aa15481c53b59259597a48e 100644
--- a/packages/backend/src/server/api/stream/channels/local-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts
@@ -43,7 +43,7 @@ export default class extends Channel {
 		}
 
 		// 関係ない返信は除外
-		if (note.reply) {
+		if (note.reply && !this.user!.showTimelineReplies) {
 			const reply = note.reply;
 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts
index e70c26f5e556c1a35c2ee9b95dd53da4762907d9..e2f1c6fc9ca23ceb19358a43a09522e59bfa97b3 100644
--- a/packages/backend/src/server/api/stream/types.ts
+++ b/packages/backend/src/server/api/stream/types.ts
@@ -105,7 +105,10 @@ export interface NoteStreamTypes {
 	};
 	reacted: {
 		reaction: string;
-		emoji?: Emoji;
+		emoji?: {
+			name: string;
+			url: string;
+		} | null;
 		userId: User['id'];
 	};
 	unreacted: {
diff --git a/packages/backend/src/server/api/streaming.ts b/packages/backend/src/server/api/streaming.ts
index ad87311064f444dc7757699302822810ea663441..b706b1b8dfb0a6f89c69234e218195e53fd0562a 100644
--- a/packages/backend/src/server/api/streaming.ts
+++ b/packages/backend/src/server/api/streaming.ts
@@ -59,7 +59,7 @@ module.exports = (server: http.Server) => {
 		});
 
 		connection.on('message', async (data) => {
-			if (data.utf8Data === 'ping') {
+			if (data.type === 'utf8' && data.utf8Data === 'ping') {
 				connection.send('pong');
 			}
 		});
diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts
index 764306c7d82a071f1ee2017a0241200b87e99946..4d6b402e645c1bc0c78b1c88c89d4ccc2266c0cd 100644
--- a/packages/backend/src/server/index.ts
+++ b/packages/backend/src/server/index.ts
@@ -10,7 +10,6 @@ import * as Koa from 'koa';
 import * as Router from '@koa/router';
 import * as mount from 'koa-mount';
 import * as koaLogger from 'koa-logger';
-import * as requestStats from 'request-stats';
 import * as slow from 'koa-slow';
 
 import activityPub from './activitypub';
@@ -18,11 +17,9 @@ import nodeinfo from './nodeinfo';
 import wellKnown from './well-known';
 import config from '@/config/index';
 import apiServer from './api/index';
-import { sum } from '@/prelude/array';
 import Logger from '@/services/logger';
 import { envOption } from '../env';
 import { UserProfiles, Users } from '@/models/index';
-import { networkChart } from '@/services/chart/index';
 import { genIdenticon } from '@/misc/gen-identicon';
 import { createTemp } from '@/misc/create-temp';
 import { publishMainStream } from '@/services/stream';
@@ -153,27 +150,4 @@ export default () => new Promise(resolve => {
 
 	// Listen
 	server.listen(config.port, resolve);
-
-	//#region Network stats
-	let queue: any[] = [];
-
-	requestStats(server, (stats: any) => {
-		if (stats.ok) {
-			queue.push(stats);
-		}
-	});
-
-	// Bulk write
-	setInterval(() => {
-		if (queue.length === 0) return;
-
-		const requests = queue.length;
-		const time = sum(queue.map(x => x.time));
-		const incomingBytes = sum(queue.map(x => x.req.byets));
-		const outgoingBytes = sum(queue.map(x => x.res.byets));
-		queue = [];
-
-		networkChart.update(requests, time, incomingBytes, outgoingBytes);
-	}, 5000);
-	//#endregion
 });
diff --git a/packages/backend/src/server/nodeinfo.ts b/packages/backend/src/server/nodeinfo.ts
index 44f32bf882e16bcae36caea60dd800970ad798ea..4209fc7f14e49b4d31b31866f2ceebd37d3de67c 100644
--- a/packages/backend/src/server/nodeinfo.ts
+++ b/packages/backend/src/server/nodeinfo.ts
@@ -2,7 +2,7 @@ import * as Router from '@koa/router';
 import config from '@/config/index';
 import { fetchMeta } from '@/misc/fetch-meta';
 import { Users, Notes } from '@/models/index';
-import { Not, IsNull, MoreThan } from 'typeorm';
+import { MoreThan } from 'typeorm';
 
 const router = new Router();
 
@@ -25,14 +25,12 @@ const nodeinfo2 = async () => {
 		activeHalfyear,
 		activeMonth,
 		localPosts,
-		localComments,
 	] = await Promise.all([
 		fetchMeta(true),
 		Users.count({ where: { host: null } }),
-		Users.count({ where: { host: null, updatedAt: MoreThan(new Date(now - 15552000000)) } }),
-		Users.count({ where: { host: null, updatedAt: MoreThan(new Date(now - 2592000000)) } }),
-		Notes.count({ where: { userHost: null, replyId: null } }),
-		Notes.count({ where: { userHost: null, replyId: Not(IsNull()) } }),
+		Users.count({ where: { host: null, lastActiveDate: MoreThan(new Date(now - 15552000000)) } }),
+		Users.count({ where: { host: null, lastActiveDate: MoreThan(new Date(now - 2592000000)) } }),
+		Notes.count({ where: { userHost: null } }),
 	]);
 
 	const proxyAccount = meta.proxyAccountId ? await Users.pack(meta.proxyAccountId).catch(() => null) : null;
@@ -52,7 +50,7 @@ const nodeinfo2 = async () => {
 		usage: {
 			users: { total, activeHalfyear, activeMonth },
 			localPosts,
-			localComments,
+			localComments: 0,
 		},
 		metadata: {
 			nodeName: meta.name,
diff --git a/packages/backend/src/server/proxy/proxy-media.ts b/packages/backend/src/server/proxy/proxy-media.ts
index c234b70c5528f4a768630d1fe4a01b045c100562..b7dcd0292beb5fb5bf0449da222645d3903618cc 100644
--- a/packages/backend/src/server/proxy/proxy-media.ts
+++ b/packages/backend/src/server/proxy/proxy-media.ts
@@ -11,6 +11,11 @@ import { FILE_TYPE_BROWSERSAFE } from '@/const';
 export async function proxyMedia(ctx: Koa.Context) {
 	const url = 'url' in ctx.query ? ctx.query.url : 'https://' + ctx.params.url;
 
+	if (typeof url !== 'string') {
+		ctx.status = 400;
+		return;
+	}
+
 	// Create temp file
 	const [path, cleanup] = await createTemp();
 
diff --git a/packages/backend/src/server/web/index.ts b/packages/backend/src/server/web/index.ts
index e95a115aecec20c47552df9425d8abb0513361eb..a0667f0c200ebf75ae295e71b4f437c713f28a8e 100644
--- a/packages/backend/src/server/web/index.ts
+++ b/packages/backend/src/server/web/index.ts
@@ -276,6 +276,7 @@ router.get('/@:user/pages/:page', async (ctx, next) => {
 			page: _page,
 			profile,
 			instanceName: meta.name || 'Misskey',
+			icon: meta.iconUrl,
 		});
 
 		if (['public'].includes(page.visibility)) {
@@ -305,6 +306,7 @@ router.get('/clips/:clip', async (ctx, next) => {
 			clip: _clip,
 			profile,
 			instanceName: meta.name || 'Misskey',
+			icon: meta.iconUrl,
 		});
 
 		ctx.set('Cache-Control', 'public, max-age=180');
@@ -350,6 +352,7 @@ router.get('/channels/:channel', async (ctx, next) => {
 		await ctx.render('channel', {
 			channel: _channel,
 			instanceName: meta.name || 'Misskey',
+			icon: meta.iconUrl,
 		});
 
 		ctx.set('Cache-Control', 'public, max-age=180');
diff --git a/packages/backend/src/server/web/url-preview.ts b/packages/backend/src/server/web/url-preview.ts
index 71465c8083661cfcf9afb351f1a4cb05840af070..26fffbea88abe2eb8b985c2e7dd00700503c8096 100644
--- a/packages/backend/src/server/web/url-preview.ts
+++ b/packages/backend/src/server/web/url-preview.ts
@@ -9,22 +9,34 @@ import { getJson } from '@/misc/fetch';
 const logger = new Logger('url-preview');
 
 module.exports = async (ctx: Koa.Context) => {
+	const url = ctx.query.url;
+	if (typeof url !== 'string') {
+		ctx.status = 400;
+		return;
+	}
+
+	const lang = ctx.query.lang;
+	if (Array.isArray(lang)) {
+		ctx.status = 400;
+		return;
+	}
+
 	const meta = await fetchMeta();
 
 	logger.info(meta.summalyProxy
-		? `(Proxy) Getting preview of ${ctx.query.url}@${ctx.query.lang} ...`
-		: `Getting preview of ${ctx.query.url}@${ctx.query.lang} ...`);
+		? `(Proxy) Getting preview of ${url}@${lang} ...`
+		: `Getting preview of ${url}@${lang} ...`);
 
 	try {
 		const summary = meta.summalyProxy ? await getJson(`${meta.summalyProxy}?${query({
-			url: ctx.query.url,
-			lang: ctx.query.lang || 'ja-JP',
-		})}`) : await summaly(ctx.query.url, {
+			url: url,
+			lang: lang ?? 'ja-JP',
+		})}`) : await summaly(url, {
 			followRedirects: false,
-			lang: ctx.query.lang || 'ja-JP',
+			lang: lang ?? 'ja-JP',
 		});
 
-		logger.succ(`Got preview of ${ctx.query.url}: ${summary.title}`);
+		logger.succ(`Got preview of ${url}: ${summary.title}`);
 
 		summary.icon = wrap(summary.icon);
 		summary.thumbnail = wrap(summary.thumbnail);
@@ -33,8 +45,8 @@ module.exports = async (ctx: Koa.Context) => {
 		ctx.set('Cache-Control', 'max-age=604800, immutable');
 
 		ctx.body = summary;
-	} catch (e) {
-		logger.warn(`Failed to get preview of ${ctx.query.url}: ${e}`);
+	} catch (err) {
+		logger.warn(`Failed to get preview of ${url}: ${err}`);
 		ctx.status = 200;
 		ctx.set('Cache-Control', 'max-age=86400, immutable');
 		ctx.body = '{}';
diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug
index 42c068c403015d21b2ffaee53f7ae5bef15e4d07..b8b733dd6016109dc6d42008ec54948b6aa3c564 100644
--- a/packages/backend/src/server/web/views/base.pug
+++ b/packages/backend/src/server/web/views/base.pug
@@ -21,6 +21,7 @@ html
 		meta(name='referrer' content='origin')
 		meta(name='theme-color' content='#86b300')
 		meta(name='theme-color-orig' content='#86b300')
+		meta(property='twitter:card' content='summary')
 		meta(property='og:site_name' content= instanceName || 'Misskey')
 		meta(name='viewport' content='width=device-width, initial-scale=1')
 		link(rel='icon' href= icon || '/favicon.ico')
@@ -29,8 +30,8 @@ html
 		link(rel='prefetch' href='https://xn--931a.moe/assets/info.jpg')
 		link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.jpg')
 		link(rel='prefetch' href='https://xn--931a.moe/assets/error.jpg')
-		link(rel='preload' href='https://use.fontawesome.com/releases/v5.15.3/css/all.css' as='style')
-		link(rel='stylesheet' href='https://use.fontawesome.com/releases/v5.15.3/css/all.css')
+		link(rel='preload' href='/assets/fontawesome/css/all.css' as='style')
+		link(rel='stylesheet' href='/assets/fontawesome/css/all.css')
 
 		title
 			block title
@@ -42,7 +43,9 @@ html
 		block meta
 
 		block og
-			meta(property='og:image' content=img)
+			meta(property='og:title'       content= title || 'Misskey') 
+			meta(property='og:description' content= desc || '✨🌎✨ A interplanetary communication platform ✨🚀✨') 
+			meta(property='og:image'       content= img)
 
 		style
 			include ../style.css
diff --git a/packages/backend/src/server/web/views/channel.pug b/packages/backend/src/server/web/views/channel.pug
index 273632f0e0d97ff685ee9c1f09ef31a5abc9173b..486f0ecc47bc2cc1b5ec963b2dd627dcc1da62f0 100644
--- a/packages/backend/src/server/web/views/channel.pug
+++ b/packages/backend/src/server/web/views/channel.pug
@@ -16,6 +16,3 @@ block og
 	meta(property='og:description' content= channel.description)
 	meta(property='og:url'         content= url)
 	meta(property='og:image'       content= channel.bannerUrl)
-
-block meta
-	meta(name='twitter:card' content='summary')
diff --git a/packages/backend/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug
index 8de53f19d61f5e7784d3c1eb8713fd65ff4679cc..7a84d50f6cbb8bcd1370a9c3e00bccbbc34aa7d6 100644
--- a/packages/backend/src/server/web/views/clip.pug
+++ b/packages/backend/src/server/web/views/clip.pug
@@ -26,8 +26,6 @@ block meta
 	meta(name='misskey:user-id' content=user.id)
 	meta(name='misskey:clip-id' content=clip.id)
 
-	meta(name='twitter:card' content='summary')
-
 	// todo
 	if user.twitter
 		meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
diff --git a/packages/backend/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug
index 95bbb2437c2d1fb9e448420f3bda3c2c55b069ce..ca0663a4811edd549040876532318625856063cf 100644
--- a/packages/backend/src/server/web/views/gallery-post.pug
+++ b/packages/backend/src/server/web/views/gallery-post.pug
@@ -25,8 +25,6 @@ block meta
 	meta(name='misskey:user-username' content=user.username)
 	meta(name='misskey:user-id' content=user.id)
 
-	meta(name='twitter:card' content='summary')
-
 	// todo
 	if user.twitter
 		meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug
index fce91bdabeabdf3349ca6d0c5081c4fd46890975..34b03f9833a0a8931b1231ef5105bd1446ad04e8 100644
--- a/packages/backend/src/server/web/views/note.pug
+++ b/packages/backend/src/server/web/views/note.pug
@@ -26,9 +26,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)
-
-	meta(name='twitter:card' content='summary')
-
+	
 	// todo
 	if user.twitter
 		meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
diff --git a/packages/backend/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug
index cb9e1039e12a4efe52fd507817b9ef01bb2e5a33..b6c9548025a75cab7fdfd050bf7c4d26cbf74685 100644
--- a/packages/backend/src/server/web/views/page.pug
+++ b/packages/backend/src/server/web/views/page.pug
@@ -26,8 +26,6 @@ block meta
 	meta(name='misskey:user-id' content=user.id)
 	meta(name='misskey:page-id' content=page.id)
 
-	meta(name='twitter:card' content='summary')
-
 	// todo
 	if user.twitter
 		meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
diff --git a/packages/backend/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug
index 1a8a6b44139769342b60cc74cf3829a1b0b7fbd6..2adec0f8892aeda5484646e8ac2e8ff9d70c1a9b 100644
--- a/packages/backend/src/server/web/views/user.pug
+++ b/packages/backend/src/server/web/views/user.pug
@@ -25,8 +25,6 @@ block meta
 	meta(name='misskey:user-username' content=user.username)
 	meta(name='misskey:user-id' content=user.id)
 
-	meta(name='twitter:card' content='summary')
-
 	if profile.twitter
 		meta(name='twitter:creator' content=`@${profile.twitter.screenName}`)
 
diff --git a/packages/backend/src/services/chart/charts/active-users.ts b/packages/backend/src/services/chart/charts/active-users.ts
index 9490101e36ba462dc028f0aed0be0cce89c16391..87dd95f4dc169fc9d17773fd177cb25724a66f5d 100644
--- a/packages/backend/src/services/chart/charts/active-users.ts
+++ b/packages/backend/src/services/chart/charts/active-users.ts
@@ -1,51 +1,44 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
+import Chart, { KVs } from '../core';
 import { User } from '@/models/entities/user';
-import { SchemaType } from '@/misc/schema';
 import { Users } from '@/models/index';
 import { name, schema } from './entities/active-users';
 
-type ActiveUsersLog = SchemaType<typeof schema>;
+const week = 1000 * 60 * 60 * 24 * 7;
+const month = 1000 * 60 * 60 * 24 * 30;
+const year = 1000 * 60 * 60 * 24 * 365;
 
 /**
  * アクティブユーザーに関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class ActiveUsersChart extends Chart<ActiveUsersLog> {
+export default class ActiveUsersChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema);
 	}
 
 	@autobind
-	protected genNewLog(latest: ActiveUsersLog): DeepPartial<ActiveUsersLog> {
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
 		return {};
 	}
 
 	@autobind
-	protected aggregate(logs: ActiveUsersLog[]): ActiveUsersLog {
-		return {
-			local: {
-				users: logs.reduce((a, b) => a.concat(b.local.users), [] as ActiveUsersLog['local']['users']),
-			},
-			remote: {
-				users: logs.reduce((a, b) => a.concat(b.remote.users), [] as ActiveUsersLog['remote']['users']),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(): Promise<DeepPartial<ActiveUsersLog>> {
-		return {};
+	public async read(user: { id: User['id'], host: null, createdAt: User['createdAt'] }): Promise<void> {
+		await this.commit({
+			'read': [user.id],
+			'registeredWithinWeek': (Date.now() - user.createdAt.getTime() < week) ? [user.id] : [],
+			'registeredWithinMonth': (Date.now() - user.createdAt.getTime() < month) ? [user.id] : [],
+			'registeredWithinYear': (Date.now() - user.createdAt.getTime() < year) ? [user.id] : [],
+			'registeredOutsideWeek': (Date.now() - user.createdAt.getTime() > week) ? [user.id] : [],
+			'registeredOutsideMonth': (Date.now() - user.createdAt.getTime() > month) ? [user.id] : [],
+			'registeredOutsideYear': (Date.now() - user.createdAt.getTime() > year) ? [user.id] : [],
+		});
 	}
 
 	@autobind
-	public async update(user: { id: User['id'], host: User['host'] }): Promise<void> {
-		const update: Obj = {
-			users: [user.id],
-		};
-
-		await this.inc({
-			[Users.isLocalUser(user) ? 'local' : 'remote']: update,
+	public async write(user: { id: User['id'], host: null, createdAt: User['createdAt'] }): Promise<void> {
+		await this.commit({
+			'write': [user.id],
 		});
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/ap-request.ts b/packages/backend/src/services/chart/charts/ap-request.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bac5e425c80a61e894a7880b7aaf576969c7e918
--- /dev/null
+++ b/packages/backend/src/services/chart/charts/ap-request.ts
@@ -0,0 +1,39 @@
+import autobind from 'autobind-decorator';
+import Chart, { KVs } from '../core';
+import { name, schema } from './entities/ap-request';
+
+/**
+ * Chart about ActivityPub requests
+ */
+// eslint-disable-next-line import/no-default-export
+export default class ApRequestChart extends Chart<typeof schema> {
+	constructor() {
+		super(name, schema);
+	}
+
+	@autobind
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
+		return {};
+	}
+
+	@autobind
+	public async deliverSucc(): Promise<void> {
+		await this.commit({
+			'deliverSucceeded': 1,
+		});
+	}
+
+	@autobind
+	public async deliverFail(): Promise<void> {
+		await this.commit({
+			'deliverFailed': 1,
+		});
+	}
+
+	@autobind
+	public async inbox(): Promise<void> {
+		await this.commit({
+			'inboxReceived': 1,
+		});
+	}
+}
diff --git a/packages/backend/src/services/chart/charts/drive.ts b/packages/backend/src/services/chart/charts/drive.ts
index 06cf7ebeeba29b3bf1399aa2b616f042b2527523..2f00adae2b231e9d70dd6e12b591c4d246c37521 100644
--- a/packages/backend/src/services/chart/charts/drive.ts
+++ b/packages/backend/src/services/chart/charts/drive.ts
@@ -1,95 +1,37 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { DriveFiles } from '@/models/index';
 import { Not, IsNull } from 'typeorm';
 import { DriveFile } from '@/models/entities/drive-file';
 import { name, schema } from './entities/drive';
 
-type DriveLog = SchemaType<typeof schema>;
-
 /**
  * ドライブに関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class DriveChart extends Chart<DriveLog> {
+export default class DriveChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema);
 	}
 
 	@autobind
-	protected genNewLog(latest: DriveLog): DeepPartial<DriveLog> {
-		return {
-			local: {
-				totalCount: latest.local.totalCount,
-				totalSize: latest.local.totalSize,
-			},
-			remote: {
-				totalCount: latest.remote.totalCount,
-				totalSize: latest.remote.totalSize,
-			},
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: DriveLog[]): DriveLog {
-		return {
-			local: {
-				totalCount: logs[0].local.totalCount,
-				totalSize: logs[0].local.totalSize,
-				incCount: logs.reduce((a, b) => a + b.local.incCount, 0),
-				incSize: logs.reduce((a, b) => a + b.local.incSize, 0),
-				decCount: logs.reduce((a, b) => a + b.local.decCount, 0),
-				decSize: logs.reduce((a, b) => a + b.local.decSize, 0),
-			},
-			remote: {
-				totalCount: logs[0].remote.totalCount,
-				totalSize: logs[0].remote.totalSize,
-				incCount: logs.reduce((a, b) => a + b.remote.incCount, 0),
-				incSize: logs.reduce((a, b) => a + b.remote.incSize, 0),
-				decCount: logs.reduce((a, b) => a + b.remote.decCount, 0),
-				decSize: logs.reduce((a, b) => a + b.remote.decSize, 0),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(): Promise<DeepPartial<DriveLog>> {
-		const [localCount, remoteCount, localSize, remoteSize] = await Promise.all([
-			DriveFiles.count({ userHost: null }),
-			DriveFiles.count({ userHost: Not(IsNull()) }),
-			DriveFiles.calcDriveUsageOfLocal(),
-			DriveFiles.calcDriveUsageOfRemote(),
-		]);
-
-		return {
-			local: {
-				totalCount: localCount,
-				totalSize: localSize,
-			},
-			remote: {
-				totalCount: remoteCount,
-				totalSize: remoteSize,
-			},
-		};
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
+		return {};
 	}
 
 	@autobind
 	public async update(file: DriveFile, isAdditional: boolean): Promise<void> {
-		const update: Obj = {};
-
-		update.totalCount = isAdditional ? 1 : -1;
-		update.totalSize = isAdditional ? file.size : -file.size;
-		if (isAdditional) {
-			update.incCount = 1;
-			update.incSize = file.size;
-		} else {
-			update.decCount = 1;
-			update.decSize = file.size;
-		}
-
-		await this.inc({
-			[file.userHost === null ? 'local' : 'remote']: update,
+		const fileSizeKb = file.size / 1000;
+		await this.commit(file.userHost === null ? {
+			'local.incCount': isAdditional ? 1 : 0,
+			'local.incSize': isAdditional ? fileSizeKb : 0,
+			'local.decCount': isAdditional ? 0 : 1,
+			'local.decSize': isAdditional ? 0 : fileSizeKb,
+		} : {
+			'remote.incCount': isAdditional ? 1 : 0,
+			'remote.incSize': isAdditional ? fileSizeKb : 0,
+			'remote.decCount': isAdditional ? 0 : 1,
+			'remote.decSize': isAdditional ? 0 : fileSizeKb,
 		});
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/entities/active-users.ts b/packages/backend/src/services/chart/charts/entities/active-users.ts
index d6b49c86c364bb84f6b221654c08f0a780b87f79..843843836d6d9dc3e010b8710f15ad46e3bdd3dd 100644
--- a/packages/backend/src/services/chart/charts/entities/active-users.ts
+++ b/packages/backend/src/services/chart/charts/entities/active-users.ts
@@ -2,35 +2,16 @@ import Chart from '../../core';
 
 export const name = 'activeUsers';
 
-const logSchema = {
-	/**
-	 * アクティブユーザー
-	 */
-	users: {
-		type: 'array' as const,
-		optional: false as const, nullable: false as const,
-		items: {
-			type: 'string' as const,
-			optional: false as const, nullable: false as const,
-		},
-	},
-};
-
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		local: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-		remote: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-	},
-};
+	'readWrite': { intersection: ['read', 'write'], range: 'small' },
+	'read': { uniqueIncrement: true, range: 'small' },
+	'write': { uniqueIncrement: true, range: 'small' },
+	'registeredWithinWeek': { uniqueIncrement: true, range: 'small' },
+	'registeredWithinMonth': { uniqueIncrement: true, range: 'small' },
+	'registeredWithinYear': { uniqueIncrement: true, range: 'small' },
+	'registeredOutsideWeek': { uniqueIncrement: true, range: 'small' },
+	'registeredOutsideMonth': { uniqueIncrement: true, range: 'small' },
+	'registeredOutsideYear': { uniqueIncrement: true, range: 'small' },
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/ap-request.ts b/packages/backend/src/services/chart/charts/entities/ap-request.ts
new file mode 100644
index 0000000000000000000000000000000000000000..21fb40d1385b2333c98902c6070460f899f76403
--- /dev/null
+++ b/packages/backend/src/services/chart/charts/entities/ap-request.ts
@@ -0,0 +1,11 @@
+import Chart from '../../core';
+
+export const name = 'apRequest';
+
+export const schema = {
+	'deliverFailed': { },
+	'deliverSucceeded': { },
+	'inboxReceived': { },
+} as const;
+
+export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/drive.ts b/packages/backend/src/services/chart/charts/entities/drive.ts
index 3362cbd4cb0863d1970e04c0993f075677fe2850..c5cdfd85bd732549082971d8ccebb1397e75c7c2 100644
--- a/packages/backend/src/services/chart/charts/entities/drive.ts
+++ b/packages/backend/src/services/chart/charts/entities/drive.ts
@@ -2,71 +2,15 @@ import Chart from '../../core';
 
 export const name = 'drive';
 
-const logSchema = {
-	/**
-	 * 集計期間時点での、全ドライブファイル数
-	 */
-	totalCount: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	/**
-	 * 集計期間時点での、全ドライブファイルの合計サイズ
-	 */
-	totalSize: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	/**
-	 * 増加したドライブファイル数
-	 */
-	incCount: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	/**
-	 * 増加したドライブ使用量
-	 */
-	incSize: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	/**
-	 * 減少したドライブファイル数
-	 */
-	decCount: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	/**
-	 * 減少したドライブ使用量
-	 */
-	decSize: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-};
-
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		local: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-		remote: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-	},
-};
+	'local.incCount': {},
+	'local.incSize': {}, // in kilobyte
+	'local.decCount': {},
+	'local.decSize': {}, // in kilobyte
+	'remote.incCount': {},
+	'remote.incSize': {}, // in kilobyte
+	'remote.decCount': {},
+	'remote.decSize': {}, // in kilobyte
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/federation.ts b/packages/backend/src/services/chart/charts/entities/federation.ts
index 836116bd0600716fb4c3ed174370325a4c870764..0c8c20991d58d5c3245c8d2b1ef703a630d0f37e 100644
--- a/packages/backend/src/services/chart/charts/entities/federation.ts
+++ b/packages/backend/src/services/chart/charts/entities/federation.ts
@@ -3,28 +3,12 @@ import Chart from '../../core';
 export const name = 'federation';
 
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		instance: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				total: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				inc: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				dec: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-			},
-		},
-	},
-};
+	'instance.total': { accumulate: true },
+	'instance.inc': { range: 'small' },
+	'instance.dec': { range: 'small' },
+	'deliveredInstances': { uniqueIncrement: true, range: 'small' },
+	'inboxInstances': { uniqueIncrement: true, range: 'small' },
+	'stalled': { uniqueIncrement: true, range: 'small' },
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/hashtag.ts b/packages/backend/src/services/chart/charts/entities/hashtag.ts
index 43e15456a555c76664489e80cf05433e5d57728d..bd2ae38a165aa305b835a58bf8397466655cd991 100644
--- a/packages/backend/src/services/chart/charts/entities/hashtag.ts
+++ b/packages/backend/src/services/chart/charts/entities/hashtag.ts
@@ -2,35 +2,9 @@ import Chart from '../../core';
 
 export const name = 'hashtag';
 
-const logSchema = {
-	/**
-	 * 投稿したユーザー
-	 */
-	users: {
-		type: 'array' as const,
-		optional: false as const, nullable: false as const,
-		items: {
-			type: 'string' as const,
-			optional: false as const, nullable: false as const,
-		},
-	},
-};
-
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		local: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-		remote: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-	},
-};
+	'local.users': { uniqueIncrement: true },
+	'remote.users': { uniqueIncrement: true },
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/instance.ts b/packages/backend/src/services/chart/charts/entities/instance.ts
index 9d1f651dbbfe75678b56fcda2e0b21e369ff758e..b98e1640c8f1e7654d29ef15547e296a373c4751 100644
--- a/packages/backend/src/services/chart/charts/entities/instance.ts
+++ b/packages/backend/src/services/chart/charts/entities/instance.ts
@@ -3,156 +3,30 @@ import Chart from '../../core';
 export const name = 'instance';
 
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		requests: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				failed: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				succeeded: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				received: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-			},
-		},
-
-		notes: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				total: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				inc: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				dec: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-
-				diffs: {
-					type: 'object' as const,
-					optional: false as const, nullable: false as const,
-					properties: {
-						normal: {
-							type: 'number' as const,
-							optional: false as const, nullable: false as const,
-						},
-
-						reply: {
-							type: 'number' as const,
-							optional: false as const, nullable: false as const,
-						},
-
-						renote: {
-							type: 'number' as const,
-							optional: false as const, nullable: false as const,
-						},
-					},
-				},
-			},
-		},
-
-		users: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				total: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				inc: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				dec: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-			},
-		},
-
-		following: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				total: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				inc: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				dec: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-			},
-		},
-
-		followers: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				total: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				inc: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				dec: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-			},
-		},
-
-		drive: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				totalFiles: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				totalUsage: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				incFiles: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				incUsage: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				decFiles: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-				decUsage: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-			},
-		},
-	},
-};
+	'requests.failed': { range: 'small' },
+	'requests.succeeded': { range: 'small' },
+	'requests.received': { range: 'small' },
+	'notes.total': { accumulate: true },
+	'notes.inc': {},
+	'notes.dec': {},
+	'notes.diffs.normal': {},
+	'notes.diffs.reply': {},
+	'notes.diffs.renote': {},
+	'notes.diffs.withFile': {},
+	'users.total': { accumulate: true },
+	'users.inc': { range: 'small' },
+	'users.dec': { range: 'small' },
+	'following.total': { accumulate: true },
+	'following.inc': { range: 'small' },
+	'following.dec': { range: 'small' },
+	'followers.total': { accumulate: true },
+	'followers.inc': { range: 'small' },
+	'followers.dec': { range: 'small' },
+	'drive.totalFiles': { accumulate: true },
+	'drive.incFiles': {},
+	'drive.decFiles': {},
+	'drive.incUsage': {}, // in kilobyte
+	'drive.decUsage': {}, // in kilobyte
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/network.ts b/packages/backend/src/services/chart/charts/entities/network.ts
deleted file mode 100644
index 3d4fffb855de7939c6813451de9aa0a2cfe693b5..0000000000000000000000000000000000000000
--- a/packages/backend/src/services/chart/charts/entities/network.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import Chart from '../../core';
-
-export const name = 'network';
-
-export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		incomingRequests: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-		outgoingRequests: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-		totalTime: { // TIP: (totalTime / incomingRequests) でひとつのリクエストに平均でどれくらいの時間がかかったか知れる
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-		incomingBytes: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-		outgoingBytes: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-	},
-};
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/notes.ts b/packages/backend/src/services/chart/charts/entities/notes.ts
index 554d3abe126848828ffdea8f7b9c0b321cf31989..f9b9b20eedfd72d8b60e249008d325274989300e 100644
--- a/packages/backend/src/services/chart/charts/entities/notes.ts
+++ b/packages/backend/src/services/chart/charts/entities/notes.ts
@@ -2,59 +2,21 @@ import Chart from '../../core';
 
 export const name = 'notes';
 
-const logSchema = {
-	total: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	inc: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	dec: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	diffs: {
-		type: 'object' as const,
-		optional: false as const, nullable: false as const,
-		properties: {
-			normal: {
-				type: 'number' as const,
-				optional: false as const, nullable: false as const,
-			},
-
-			reply: {
-				type: 'number' as const,
-				optional: false as const, nullable: false as const,
-			},
-
-			renote: {
-				type: 'number' as const,
-				optional: false as const, nullable: false as const,
-			},
-		},
-	},
-};
-
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		local: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-		remote: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-	},
-};
+	'local.total': { accumulate: true },
+	'local.inc': {},
+	'local.dec': {},
+	'local.diffs.normal': {},
+	'local.diffs.reply': {},
+	'local.diffs.renote': {},
+	'local.diffs.withFile': {},
+	'remote.total': { accumulate: true },
+	'remote.inc': {},
+	'remote.dec': {},
+	'remote.diffs.normal': {},
+	'remote.diffs.reply': {},
+	'remote.diffs.renote': {},
+	'remote.diffs.withFile': {},
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/per-user-drive.ts b/packages/backend/src/services/chart/charts/entities/per-user-drive.ts
index ebf64e733e5ccd7b72c14fb4bcbf4e8f6449277d..00d85b1620fbae247dcb6e9d615423e65a11b8c7 100644
--- a/packages/backend/src/services/chart/charts/entities/per-user-drive.ts
+++ b/packages/backend/src/services/chart/charts/entities/per-user-drive.ts
@@ -3,57 +3,12 @@ import Chart from '../../core';
 export const name = 'perUserDrive';
 
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		/**
-		 * 集計期間時点での、全ドライブファイル数
-		 */
-		totalCount: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-
-		/**
-		 * 集計期間時点での、全ドライブファイルの合計サイズ
-		 */
-		totalSize: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-
-		/**
-		 * 増加したドライブファイル数
-		 */
-		incCount: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-
-		/**
-		 * 増加したドライブ使用量
-		 */
-		incSize: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-
-		/**
-		 * 減少したドライブファイル数
-		 */
-		decCount: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-
-		/**
-		 * 減少したドライブ使用量
-		 */
-		decSize: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-	},
-};
+	'totalCount': { accumulate: true },
+	'totalSize': { accumulate: true }, // in kilobyte
+	'incCount': { range: 'small' },
+	'incSize': {}, // in kilobyte
+	'decCount': { range: 'small' },
+	'decSize': {}, // in kilobyte
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/per-user-following.ts b/packages/backend/src/services/chart/charts/entities/per-user-following.ts
index 8016c5fe979953bba8340ae8196898b652d97661..1efd4977fcd5b84047e71be59cbc3eaa3c11be3b 100644
--- a/packages/backend/src/services/chart/charts/entities/per-user-following.ts
+++ b/packages/backend/src/services/chart/charts/entities/per-user-following.ts
@@ -2,89 +2,19 @@ import Chart from '../../core';
 
 export const name = 'perUserFollowing';
 
-const logSchema = {
-	/**
-	 * フォローしている
-	 */
-	followings: {
-		type: 'object' as const,
-		optional: false as const, nullable: false as const,
-		properties: {
-			/**
-			 * フォローしている合計
-			 */
-			total: {
-				type: 'number' as const,
-				optional: false as const, nullable: false as const,
-			},
-
-			/**
-			 * フォローした数
-			 */
-			inc: {
-				type: 'number' as const,
-				optional: false as const, nullable: false as const,
-			},
-
-			/**
-			 * フォロー解除した数
-			 */
-			dec: {
-				type: 'number' as const,
-				optional: false as const, nullable: false as const,
-			},
-		},
-	},
-
-	/**
-	 * フォローされている
-	 */
-	followers: {
-		type: 'object' as const,
-		optional: false as const, nullable: false as const,
-		properties: {
-			/**
-			 * フォローされている合計
-			 */
-			total: {
-				type: 'number' as const,
-				optional: false as const, nullable: false as const,
-			},
-
-			/**
-			 * フォローされた数
-			 */
-			inc: {
-				type: 'number' as const,
-				optional: false as const, nullable: false as const,
-			},
-
-			/**
-			 * フォロー解除された数
-			 */
-			dec: {
-				type: 'number' as const,
-				optional: false as const, nullable: false as const,
-			},
-		},
-	},
-};
-
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		local: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-		remote: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-	},
-};
+	'local.followings.total': { accumulate: true },
+	'local.followings.inc': { range: 'small' },
+	'local.followings.dec': { range: 'small' },
+	'local.followers.total': { accumulate: true },
+	'local.followers.inc': { range: 'small' },
+	'local.followers.dec': { range: 'small' },
+	'remote.followings.total': { accumulate: true },
+	'remote.followings.inc': { range: 'small' },
+	'remote.followings.dec': { range: 'small' },
+	'remote.followers.total': { accumulate: true },
+	'remote.followers.inc': { range: 'small' },
+	'remote.followers.dec': { range: 'small' },
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/per-user-notes.ts b/packages/backend/src/services/chart/charts/entities/per-user-notes.ts
index d8f645b36edd3ac0f8b0bb199e166fd023eaa612..562cde9b000e4e06c3c5a97faf4699754ea5c7a5 100644
--- a/packages/backend/src/services/chart/charts/entities/per-user-notes.ts
+++ b/packages/backend/src/services/chart/charts/entities/per-user-notes.ts
@@ -3,45 +3,13 @@ import Chart from '../../core';
 export const name = 'perUserNotes';
 
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		total: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-
-		inc: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-
-		dec: {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		},
-
-		diffs: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				normal: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-
-				reply: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-
-				renote: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-			},
-		},
-	},
-};
+	'total': { accumulate: true },
+	'inc': { range: 'small' },
+	'dec': { range: 'small' },
+	'diffs.normal': { range: 'small' },
+	'diffs.reply': { range: 'small' },
+	'diffs.renote': { range: 'small' },
+	'diffs.withFile': { range: 'small' },
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts b/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts
index bcb7012661e040f2e563f365faa4455d77762e4d..ab315d24c9ecc3511bb0a2f175b9ce670c406257 100644
--- a/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts
+++ b/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts
@@ -2,31 +2,9 @@ import Chart from '../../core';
 
 export const name = 'perUserReaction';
 
-const logSchema = {
-	/**
-	 * 被リアクション数
-	 */
-	count: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-};
-
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		local: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-		remote: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-	},
-};
+	'local.count': { range: 'small' },
+	'remote.count': { range: 'small' },
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/test-grouped.ts b/packages/backend/src/services/chart/charts/entities/test-grouped.ts
index ca1c8c57004345022bef565a5c75634aa5c60647..78c2bbd5480f5bee2bf7ce28177525bfab8d1814 100644
--- a/packages/backend/src/services/chart/charts/entities/test-grouped.ts
+++ b/packages/backend/src/services/chart/charts/entities/test-grouped.ts
@@ -3,30 +3,9 @@ import Chart from '../../core';
 export const name = 'testGrouped';
 
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		foo: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				total: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-
-				inc: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-
-				dec: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-			},
-		},
-	},
-};
+	'foo.total': { accumulate: true },
+	'foo.inc': {},
+	'foo.dec': {},
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/test-intersection.ts b/packages/backend/src/services/chart/charts/entities/test-intersection.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dc56eb93f5327e9f7293f4aa6db0ea206b22ef65
--- /dev/null
+++ b/packages/backend/src/services/chart/charts/entities/test-intersection.ts
@@ -0,0 +1,11 @@
+import Chart from '../../core';
+
+export const name = 'testIntersection';
+
+export const schema = {
+	'a': { uniqueIncrement: true },
+	'b': { uniqueIncrement: true },
+	'aAndB': { intersection: ['a', 'b'] },
+} as const;
+
+export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/test-unique.ts b/packages/backend/src/services/chart/charts/entities/test-unique.ts
index 2e917ee9edbe706a1d72e1a976ac8241a50af4d6..dc7c1520e1a0fb8dbf3ed69bc63d3f3959e7d228 100644
--- a/packages/backend/src/services/chart/charts/entities/test-unique.ts
+++ b/packages/backend/src/services/chart/charts/entities/test-unique.ts
@@ -3,18 +3,7 @@ import Chart from '../../core';
 export const name = 'testUnique';
 
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		foo: {
-			type: 'array' as const,
-			optional: false as const, nullable: false as const,
-			items: {
-				type: 'string' as const,
-				optional: false as const, nullable: false as const,
-			},
-		},
-	},
-};
+	'foo': { uniqueIncrement: true },
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/test.ts b/packages/backend/src/services/chart/charts/entities/test.ts
index fa536ff2cf24d764ff80919213b8e3a919aee15a..edfa4c524b98fc0c61687c8c874f3efdcdbfabad 100644
--- a/packages/backend/src/services/chart/charts/entities/test.ts
+++ b/packages/backend/src/services/chart/charts/entities/test.ts
@@ -3,30 +3,9 @@ import Chart from '../../core';
 export const name = 'test';
 
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		foo: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: {
-				total: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-
-				inc: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-
-				dec: {
-					type: 'number' as const,
-					optional: false as const, nullable: false as const,
-				},
-			},
-		},
-	},
-};
+	'foo.total': { accumulate: true },
+	'foo.inc': {},
+	'foo.dec': {},
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/users.ts b/packages/backend/src/services/chart/charts/entities/users.ts
index 08d51c941428ab5d0448362a7f942e13a3c0f8d4..d2cec724972034aa9bbaf8f9ac20b375a1594497 100644
--- a/packages/backend/src/services/chart/charts/entities/users.ts
+++ b/packages/backend/src/services/chart/charts/entities/users.ts
@@ -2,47 +2,13 @@ import Chart from '../../core';
 
 export const name = 'users';
 
-const logSchema = {
-	/**
-	 * 集計期間時点での、全ユーザー数
-	 */
-	total: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	/**
-	 * 増加したユーザー数
-	 */
-	inc: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-
-	/**
-	 * 減少したユーザー数
-	 */
-	dec: {
-		type: 'number' as const,
-		optional: false as const, nullable: false as const,
-	},
-};
-
 export const schema = {
-	type: 'object' as const,
-	optional: false as const, nullable: false as const,
-	properties: {
-		local: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-		remote: {
-			type: 'object' as const,
-			optional: false as const, nullable: false as const,
-			properties: logSchema,
-		},
-	},
-};
+	'local.total': { accumulate: true },
+	'local.inc': { range: 'small' },
+	'local.dec': { range: 'small' },
+	'remote.total': { accumulate: true },
+	'remote.inc': { range: 'small' },
+	'remote.dec': { range: 'small' },
+} as const;
 
 export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/federation.ts b/packages/backend/src/services/chart/charts/federation.ts
index 8abb18b51fe186407cc9803da962d7818967234e..19c75c98adedfbda45e21de0d451b1a2e744a11d 100644
--- a/packages/backend/src/services/chart/charts/federation.ts
+++ b/packages/backend/src/services/chart/charts/federation.ts
@@ -1,66 +1,50 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { Instances } from '@/models/index';
 import { name, schema } from './entities/federation';
 
-type FederationLog = SchemaType<typeof schema>;
-
 /**
  * フェデレーションに関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class FederationChart extends Chart<FederationLog> {
+export default class FederationChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema);
 	}
 
 	@autobind
-	protected genNewLog(latest: FederationLog): DeepPartial<FederationLog> {
-		return {
-			instance: {
-				total: latest.instance.total,
-			},
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: FederationLog[]): FederationLog {
-		return {
-			instance: {
-				total: logs[0].instance.total,
-				inc: logs.reduce((a, b) => a + b.instance.inc, 0),
-				dec: logs.reduce((a, b) => a + b.instance.dec, 0),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(): Promise<DeepPartial<FederationLog>> {
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
 		const [total] = await Promise.all([
 			Instances.count({}),
 		]);
 
 		return {
-			instance: {
-				total: total,
-			},
+			'instance.total': total,
 		};
 	}
 
 	@autobind
 	public async update(isAdditional: boolean): Promise<void> {
-		const update: Obj = {};
+		await this.commit({
+			'instance.total': isAdditional ? 1 : -1,
+			'instance.inc': isAdditional ? 1 : 0,
+			'instance.dec': isAdditional ? 0 : 1,
+		});
+	}
 
-		update.total = isAdditional ? 1 : -1;
-		if (isAdditional) {
-			update.inc = 1;
-		} else {
-			update.dec = 1;
-		}
+	@autobind
+	public async deliverd(host: string, succeeded: boolean): Promise<void> {
+		await this.commit(succeeded ? {
+			'deliveredInstances': [host],
+		} : {
+			'stalled': [host],
+		});
+	}
 
-		await this.inc({
-			instance: update,
+	@autobind
+	public async inbox(host: string): Promise<void> {
+		await this.commit({
+			'inboxInstances': [host],
 		});
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/hashtag.ts b/packages/backend/src/services/chart/charts/hashtag.ts
index 34e0614643abc7a21c6f324c80f3c3251eb5902a..0b7bc467d2507f18e0675d00e136703a27f57c7e 100644
--- a/packages/backend/src/services/chart/charts/hashtag.ts
+++ b/packages/backend/src/services/chart/charts/hashtag.ts
@@ -1,51 +1,28 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
+import Chart, { KVs } from '../core';
 import { User } from '@/models/entities/user';
-import { SchemaType } from '@/misc/schema';
 import { Users } from '@/models/index';
 import { name, schema } from './entities/hashtag';
 
-type HashtagLog = SchemaType<typeof schema>;
-
 /**
  * ハッシュタグに関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class HashtagChart extends Chart<HashtagLog> {
+export default class HashtagChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema, true);
 	}
 
 	@autobind
-	protected genNewLog(latest: HashtagLog): DeepPartial<HashtagLog> {
-		return {};
-	}
-
-	@autobind
-	protected aggregate(logs: HashtagLog[]): HashtagLog {
-		return {
-			local: {
-				users: logs.reduce((a, b) => a.concat(b.local.users), [] as HashtagLog['local']['users']),
-			},
-			remote: {
-				users: logs.reduce((a, b) => a.concat(b.remote.users), [] as HashtagLog['remote']['users']),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(): Promise<DeepPartial<HashtagLog>> {
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
 		return {};
 	}
 
 	@autobind
 	public async update(hashtag: string, user: { id: User['id'], host: User['host'] }): Promise<void> {
-		const update: Obj = {
-			users: [user.id],
-		};
-
-		await this.inc({
-			[Users.isLocalUser(user) ? 'local' : 'remote']: update,
+		await this.commit({
+			'local.users': Users.isLocalUser(user) ? [user.id] : [],
+			'remote.users': Users.isLocalUser(user) ? [] : [user.id],
 		}, hashtag);
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/instance.ts b/packages/backend/src/services/chart/charts/instance.ts
index 7f3419b69cf02e995763ba43e7997aa521b882bd..5ea4d567e108e16f4eab616071b68ecb5692014e 100644
--- a/packages/backend/src/services/chart/charts/instance.ts
+++ b/packages/backend/src/services/chart/charts/instance.ts
@@ -1,221 +1,110 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { DriveFiles, Followings, Users, Notes } from '@/models/index';
 import { DriveFile } from '@/models/entities/drive-file';
 import { Note } from '@/models/entities/note';
 import { toPuny } from '@/misc/convert-host';
 import { name, schema } from './entities/instance';
 
-type InstanceLog = SchemaType<typeof schema>;
-
 /**
  * インスタンスごとのチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class InstanceChart extends Chart<InstanceLog> {
+export default class InstanceChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema, true);
 	}
 
 	@autobind
-	protected genNewLog(latest: InstanceLog): DeepPartial<InstanceLog> {
-		return {
-			notes: {
-				total: latest.notes.total,
-			},
-			users: {
-				total: latest.users.total,
-			},
-			following: {
-				total: latest.following.total,
-			},
-			followers: {
-				total: latest.followers.total,
-			},
-			drive: {
-				totalFiles: latest.drive.totalFiles,
-				totalUsage: latest.drive.totalUsage,
-			},
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: InstanceLog[]): InstanceLog {
-		return {
-			requests: {
-				failed: logs.reduce((a, b) => a + b.requests.failed, 0),
-				succeeded: logs.reduce((a, b) => a + b.requests.succeeded, 0),
-				received: logs.reduce((a, b) => a + b.requests.received, 0),
-			},
-			notes: {
-				total: logs[0].notes.total,
-				inc: logs.reduce((a, b) => a + b.notes.inc, 0),
-				dec: logs.reduce((a, b) => a + b.notes.dec, 0),
-				diffs: {
-					reply: logs.reduce((a, b) => a + b.notes.diffs.reply, 0),
-					renote: logs.reduce((a, b) => a + b.notes.diffs.renote, 0),
-					normal: logs.reduce((a, b) => a + b.notes.diffs.normal, 0),
-				},
-			},
-			users: {
-				total: logs[0].users.total,
-				inc: logs.reduce((a, b) => a + b.users.inc, 0),
-				dec: logs.reduce((a, b) => a + b.users.dec, 0),
-			},
-			following: {
-				total: logs[0].following.total,
-				inc: logs.reduce((a, b) => a + b.following.inc, 0),
-				dec: logs.reduce((a, b) => a + b.following.dec, 0),
-			},
-			followers: {
-				total: logs[0].followers.total,
-				inc: logs.reduce((a, b) => a + b.followers.inc, 0),
-				dec: logs.reduce((a, b) => a + b.followers.dec, 0),
-			},
-			drive: {
-				totalFiles: logs[0].drive.totalFiles,
-				totalUsage: logs[0].drive.totalUsage,
-				incFiles: logs.reduce((a, b) => a + b.drive.incFiles, 0),
-				incUsage: logs.reduce((a, b) => a + b.drive.incUsage, 0),
-				decFiles: logs.reduce((a, b) => a + b.drive.decFiles, 0),
-				decUsage: logs.reduce((a, b) => a + b.drive.decUsage, 0),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(group: string): Promise<DeepPartial<InstanceLog>> {
+	protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> {
 		const [
 			notesCount,
 			usersCount,
 			followingCount,
 			followersCount,
 			driveFiles,
-			driveUsage,
+			//driveUsage,
 		] = await Promise.all([
 			Notes.count({ userHost: group }),
 			Users.count({ host: group }),
 			Followings.count({ followerHost: group }),
 			Followings.count({ followeeHost: group }),
 			DriveFiles.count({ userHost: group }),
-			DriveFiles.calcDriveUsageOfHost(group),
+			//DriveFiles.calcDriveUsageOfHost(group),
 		]);
 
 		return {
-			notes: {
-				total: notesCount,
-			},
-			users: {
-				total: usersCount,
-			},
-			following: {
-				total: followingCount,
-			},
-			followers: {
-				total: followersCount,
-			},
-			drive: {
-				totalFiles: driveFiles,
-				totalUsage: driveUsage,
-			},
+			'notes.total': notesCount,
+			'users.total': usersCount,
+			'following.total': followingCount,
+			'followers.total': followersCount,
+			'drive.totalFiles': driveFiles,
 		};
 	}
 
 	@autobind
 	public async requestReceived(host: string): Promise<void> {
-		await this.inc({
-			requests: {
-				received: 1,
-			},
+		await this.commit({
+			'requests.received': 1,
 		}, toPuny(host));
 	}
 
 	@autobind
 	public async requestSent(host: string, isSucceeded: boolean): Promise<void> {
-		const update: Obj = {};
-
-		if (isSucceeded) {
-			update.succeeded = 1;
-		} else {
-			update.failed = 1;
-		}
-
-		await this.inc({
-			requests: update,
+		await this.commit({
+			'requests.succeeded': isSucceeded ? 1 : 0,
+			'requests.failed': isSucceeded ? 0 : 1,
 		}, toPuny(host));
 	}
 
 	@autobind
 	public async newUser(host: string): Promise<void> {
-		await this.inc({
-			users: {
-				total: 1,
-				inc: 1,
-			},
+		await this.commit({
+			'users.total': 1,
+			'users.inc': 1,
 		}, toPuny(host));
 	}
 
 	@autobind
 	public async updateNote(host: string, note: Note, isAdditional: boolean): Promise<void> {
-		const diffs = {} as Record<string, unknown>;
-
-		if (note.replyId != null) {
-			diffs.reply = isAdditional ? 1 : -1;
-		} else if (note.renoteId != null) {
-			diffs.renote = isAdditional ? 1 : -1;
-		} else {
-			diffs.normal = isAdditional ? 1 : -1;
-		}
-
-		await this.inc({
-			notes: {
-				total: isAdditional ? 1 : -1,
-				inc: isAdditional ? 1 : 0,
-				dec: isAdditional ? 0 : 1,
-				diffs: diffs,
-			},
+		await this.commit({
+			'notes.total': isAdditional ? 1 : -1,
+			'notes.inc': isAdditional ? 1 : 0,
+			'notes.dec': isAdditional ? 0 : 1,
+			'notes.diffs.normal': note.replyId == null && note.renoteId == null ? (isAdditional ? 1 : -1) : 0,
+			'notes.diffs.renote': note.renoteId != null ? (isAdditional ? 1 : -1) : 0,
+			'notes.diffs.reply': note.replyId != null ? (isAdditional ? 1 : -1) : 0,
+			'notes.diffs.withFile': note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0,
 		}, toPuny(host));
 	}
 
 	@autobind
 	public async updateFollowing(host: string, isAdditional: boolean): Promise<void> {
-		await this.inc({
-			following: {
-				total: isAdditional ? 1 : -1,
-				inc: isAdditional ? 1 : 0,
-				dec: isAdditional ? 0 : 1,
-			},
+		await this.commit({
+			'following.total': isAdditional ? 1 : -1,
+			'following.inc': isAdditional ? 1 : 0,
+			'following.dec': isAdditional ? 0 : 1,
 		}, toPuny(host));
 	}
 
 	@autobind
 	public async updateFollowers(host: string, isAdditional: boolean): Promise<void> {
-		await this.inc({
-			followers: {
-				total: isAdditional ? 1 : -1,
-				inc: isAdditional ? 1 : 0,
-				dec: isAdditional ? 0 : 1,
-			},
+		await this.commit({
+			'followers.total': isAdditional ? 1 : -1,
+			'followers.inc': isAdditional ? 1 : 0,
+			'followers.dec': isAdditional ? 0 : 1,
 		}, toPuny(host));
 	}
 
 	@autobind
 	public async updateDrive(file: DriveFile, isAdditional: boolean): Promise<void> {
-		const update: Obj = {};
-
-		update.totalFiles = isAdditional ? 1 : -1;
-		update.totalUsage = isAdditional ? file.size : -file.size;
-		if (isAdditional) {
-			update.incFiles = 1;
-			update.incUsage = file.size;
-		} else {
-			update.decFiles = 1;
-			update.decUsage = file.size;
-		}
-
-		await this.inc({
-			drive: update,
+		const fileSizeKb = file.size / 1000;
+		await this.commit({
+			'drive.totalFiles': isAdditional ? 1 : -1,
+			'drive.incFiles': isAdditional ? 1 : 0,
+			'drive.incUsage': isAdditional ? fileSizeKb : 0,
+			'drive.decFiles': isAdditional ? 1 : 0,
+			'drive.decUsage': isAdditional ? fileSizeKb : 0,
 		}, file.userHost);
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/network.ts b/packages/backend/src/services/chart/charts/network.ts
deleted file mode 100644
index 73ea2f7e19201d41e9563ad5d2e66bd79c2236e2..0000000000000000000000000000000000000000
--- a/packages/backend/src/services/chart/charts/network.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import autobind from 'autobind-decorator';
-import Chart, { DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
-import { name, schema } from './entities/network';
-
-type NetworkLog = SchemaType<typeof schema>;
-
-/**
- * ネットワークに関するチャート
- */
-// eslint-disable-next-line import/no-default-export
-export default class NetworkChart extends Chart<NetworkLog> {
-	constructor() {
-		super(name, schema);
-	}
-
-	@autobind
-	protected genNewLog(latest: NetworkLog): DeepPartial<NetworkLog> {
-		return {};
-	}
-
-	@autobind
-	protected aggregate(logs: NetworkLog[]): NetworkLog {
-		return {
-			incomingRequests: logs.reduce((a, b) => a + b.incomingRequests, 0),
-			outgoingRequests: logs.reduce((a, b) => a + b.outgoingRequests, 0),
-			totalTime: logs.reduce((a, b) => a + b.totalTime, 0),
-			incomingBytes: logs.reduce((a, b) => a + b.incomingBytes, 0),
-			outgoingBytes: logs.reduce((a, b) => a + b.outgoingBytes, 0),
-		};
-	}
-
-	@autobind
-	protected async fetchActual(): Promise<DeepPartial<NetworkLog>> {
-		return {};
-	}
-
-	@autobind
-	public async update(incomingRequests: number, time: number, incomingBytes: number, outgoingBytes: number): Promise<void> {
-		const inc: DeepPartial<NetworkLog> = {
-			incomingRequests: incomingRequests,
-			totalTime: time,
-			incomingBytes: incomingBytes,
-			outgoingBytes: outgoingBytes,
-		};
-
-		await this.inc(inc);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/notes.ts b/packages/backend/src/services/chart/charts/notes.ts
index 86cda172254394146ceac87ab2d76ff8471ea4cd..5c56a9a7189eff2fb717da768ca6ac5b399daf5a 100644
--- a/packages/backend/src/services/chart/charts/notes.ts
+++ b/packages/backend/src/services/chart/charts/notes.ts
@@ -1,101 +1,44 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { Notes } from '@/models/index';
 import { Not, IsNull } from 'typeorm';
 import { Note } from '@/models/entities/note';
 import { name, schema } from './entities/notes';
 
-type NotesLog = SchemaType<typeof schema>;
-
 /**
  * ノートに関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class NotesChart extends Chart<NotesLog> {
+export default class NotesChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema);
 	}
 
 	@autobind
-	protected genNewLog(latest: NotesLog): DeepPartial<NotesLog> {
-		return {
-			local: {
-				total: latest.local.total,
-			},
-			remote: {
-				total: latest.remote.total,
-			},
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: NotesLog[]): NotesLog {
-		return {
-			local: {
-				total: logs[0].local.total,
-				inc: logs.reduce((a, b) => a + b.local.inc, 0),
-				dec: logs.reduce((a, b) => a + b.local.dec, 0),
-				diffs: {
-					reply: logs.reduce((a, b) => a + b.local.diffs.reply, 0),
-					renote: logs.reduce((a, b) => a + b.local.diffs.renote, 0),
-					normal: logs.reduce((a, b) => a + b.local.diffs.normal, 0),
-				},
-			},
-			remote: {
-				total: logs[0].remote.total,
-				inc: logs.reduce((a, b) => a + b.remote.inc, 0),
-				dec: logs.reduce((a, b) => a + b.remote.dec, 0),
-				diffs: {
-					reply: logs.reduce((a, b) => a + b.remote.diffs.reply, 0),
-					renote: logs.reduce((a, b) => a + b.remote.diffs.renote, 0),
-					normal: logs.reduce((a, b) => a + b.remote.diffs.normal, 0),
-				},
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(): Promise<DeepPartial<NotesLog>> {
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
 		const [localCount, remoteCount] = await Promise.all([
 			Notes.count({ userHost: null }),
 			Notes.count({ userHost: Not(IsNull()) }),
 		]);
 
 		return {
-			local: {
-				total: localCount,
-			},
-			remote: {
-				total: remoteCount,
-			},
+			'local.total': localCount,
+			'remote.total': remoteCount,
 		};
 	}
 
 	@autobind
 	public async update(note: Note, isAdditional: boolean): Promise<void> {
-		const update: Obj = {
-			diffs: {},
-		};
-
-		update.total = isAdditional ? 1 : -1;
-
-		if (isAdditional) {
-			update.inc = 1;
-		} else {
-			update.dec = 1;
-		}
-
-		if (note.replyId != null) {
-			update.diffs.reply = isAdditional ? 1 : -1;
-		} else if (note.renoteId != null) {
-			update.diffs.renote = isAdditional ? 1 : -1;
-		} else {
-			update.diffs.normal = isAdditional ? 1 : -1;
-		}
-
-		await this.inc({
-			[note.userHost === null ? 'local' : 'remote']: update,
+		const prefix = note.userHost === null ? 'local' : 'remote';
+
+		await this.commit({
+			[`${prefix}.total`]: isAdditional ? 1 : -1,
+			[`${prefix}.inc`]: isAdditional ? 1 : 0,
+			[`${prefix}.dec`]: isAdditional ? 0 : 1,
+			[`${prefix}.diffs.normal`]: note.replyId == null && note.renoteId == null ? (isAdditional ? 1 : -1) : 0,
+			[`${prefix}.diffs.renote`]: note.renoteId != null ? (isAdditional ? 1 : -1) : 0,
+			[`${prefix}.diffs.reply`]: note.replyId != null ? (isAdditional ? 1 : -1) : 0,
+			[`${prefix}.diffs.withFile`]: note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0,
 		});
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/per-user-drive.ts b/packages/backend/src/services/chart/charts/per-user-drive.ts
index fff790367f29b554af1912be6bd25add76b9b98c..969ed018f9019b826764274d426306e60f0313be 100644
--- a/packages/backend/src/services/chart/charts/per-user-drive.ts
+++ b/packages/backend/src/services/chart/charts/per-user-drive.ts
@@ -1,68 +1,41 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { DriveFiles } from '@/models/index';
 import { DriveFile } from '@/models/entities/drive-file';
 import { name, schema } from './entities/per-user-drive';
 
-type PerUserDriveLog = SchemaType<typeof schema>;
-
 /**
  * ユーザーごとのドライブに関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class PerUserDriveChart extends Chart<PerUserDriveLog> {
+export default class PerUserDriveChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema, true);
 	}
 
 	@autobind
-	protected genNewLog(latest: PerUserDriveLog): DeepPartial<PerUserDriveLog> {
-		return {
-			totalCount: latest.totalCount,
-			totalSize: latest.totalSize,
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: PerUserDriveLog[]): PerUserDriveLog {
-		return {
-			totalCount: logs[0].totalCount,
-			totalSize: logs[0].totalSize,
-			incCount: logs.reduce((a, b) => a + b.incCount, 0),
-			incSize: logs.reduce((a, b) => a + b.incSize, 0),
-			decCount: logs.reduce((a, b) => a + b.decCount, 0),
-			decSize: logs.reduce((a, b) => a + b.decSize, 0),
-		};
-	}
-
-	@autobind
-	protected async fetchActual(group: string): Promise<DeepPartial<PerUserDriveLog>> {
+	protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> {
 		const [count, size] = await Promise.all([
 			DriveFiles.count({ userId: group }),
 			DriveFiles.calcDriveUsageOf(group),
 		]);
 
 		return {
-			totalCount: count,
-			totalSize: size,
+			'totalCount': count,
+			'totalSize': size,
 		};
 	}
 
 	@autobind
 	public async update(file: DriveFile, isAdditional: boolean): Promise<void> {
-		const update: Obj = {};
-
-		update.totalCount = isAdditional ? 1 : -1;
-		update.totalSize = isAdditional ? file.size : -file.size;
-		if (isAdditional) {
-			update.incCount = 1;
-			update.incSize = file.size;
-		} else {
-			update.decCount = 1;
-			update.decSize = file.size;
-		}
-
-		await this.inc(update, file.userId);
+		const fileSizeKb = file.size / 1000;
+		await this.commit({
+			'totalCount': isAdditional ? 1 : -1,
+			'totalSize': isAdditional ? fileSizeKb : -fileSizeKb,
+			'incCount': isAdditional ? 1 : 0,
+			'incSize': isAdditional ? fileSizeKb : 0,
+			'decCount': isAdditional ? 0 : 1,
+			'decSize': isAdditional ? 0 : fileSizeKb,
+		}, file.userId);
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/per-user-following.ts b/packages/backend/src/services/chart/charts/per-user-following.ts
index d0a80abdafe541fa9050acf2f5c8374743e0966e..cdd0aad9470a471ea6de095a3fae54f2eaf1f3d3 100644
--- a/packages/backend/src/services/chart/charts/per-user-following.ts
+++ b/packages/backend/src/services/chart/charts/per-user-following.ts
@@ -1,76 +1,21 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { Followings, Users } from '@/models/index';
 import { Not, IsNull } from 'typeorm';
 import { User } from '@/models/entities/user';
 import { name, schema } from './entities/per-user-following';
 
-type PerUserFollowingLog = SchemaType<typeof schema>;
-
 /**
  * ユーザーごとのフォローに関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class PerUserFollowingChart extends Chart<PerUserFollowingLog> {
+export default class PerUserFollowingChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema, true);
 	}
 
 	@autobind
-	protected genNewLog(latest: PerUserFollowingLog): DeepPartial<PerUserFollowingLog> {
-		return {
-			local: {
-				followings: {
-					total: latest.local.followings.total,
-				},
-				followers: {
-					total: latest.local.followers.total,
-				},
-			},
-			remote: {
-				followings: {
-					total: latest.remote.followings.total,
-				},
-				followers: {
-					total: latest.remote.followers.total,
-				},
-			},
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: PerUserFollowingLog[]): PerUserFollowingLog {
-		return {
-			local: {
-				followings: {
-					total: logs[0].local.followings.total,
-					inc: logs.reduce((a, b) => a + b.local.followings.inc, 0),
-					dec: logs.reduce((a, b) => a + b.local.followings.dec, 0),
-				},
-				followers: {
-					total: logs[0].local.followers.total,
-					inc: logs.reduce((a, b) => a + b.local.followers.inc, 0),
-					dec: logs.reduce((a, b) => a + b.local.followers.dec, 0),
-				},
-			},
-			remote: {
-				followings: {
-					total: logs[0].remote.followings.total,
-					inc: logs.reduce((a, b) => a + b.remote.followings.inc, 0),
-					dec: logs.reduce((a, b) => a + b.remote.followings.dec, 0),
-				},
-				followers: {
-					total: logs[0].remote.followers.total,
-					inc: logs.reduce((a, b) => a + b.remote.followers.inc, 0),
-					dec: logs.reduce((a, b) => a + b.remote.followers.dec, 0),
-				},
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(group: string): Promise<DeepPartial<PerUserFollowingLog>> {
+	protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> {
 		const [
 			localFollowingsCount,
 			localFollowersCount,
@@ -84,42 +29,27 @@ export default class PerUserFollowingChart extends Chart<PerUserFollowingLog> {
 		]);
 
 		return {
-			local: {
-				followings: {
-					total: localFollowingsCount,
-				},
-				followers: {
-					total: localFollowersCount,
-				},
-			},
-			remote: {
-				followings: {
-					total: remoteFollowingsCount,
-				},
-				followers: {
-					total: remoteFollowersCount,
-				},
-			},
+			'local.followings.total': localFollowingsCount,
+			'local.followers.total': localFollowersCount,
+			'remote.followings.total': remoteFollowingsCount,
+			'remote.followers.total': remoteFollowersCount,
 		};
 	}
 
 	@autobind
 	public async update(follower: { id: User['id']; host: User['host']; }, followee: { id: User['id']; host: User['host']; }, isFollow: boolean): Promise<void> {
-		const update: Obj = {};
-
-		update.total = isFollow ? 1 : -1;
-
-		if (isFollow) {
-			update.inc = 1;
-		} else {
-			update.dec = 1;
-		}
+		const prefixFollower = Users.isLocalUser(follower) ? 'local' : 'remote';
+		const prefixFollowee = Users.isLocalUser(followee) ? 'local' : 'remote';
 
-		this.inc({
-			[Users.isLocalUser(follower) ? 'local' : 'remote']: { followings: update },
+		this.commit({
+			[`${prefixFollower}.followings.total`]: isFollow ? 1 : -1,
+			[`${prefixFollower}.followings.inc`]: isFollow ? 1 : 0,
+			[`${prefixFollower}.followings.dec`]: isFollow ? 0 : 1,
 		}, follower.id);
-		this.inc({
-			[Users.isLocalUser(followee) ? 'local' : 'remote']: { followers: update },
+		this.commit({
+			[`${prefixFollowee}.followers.total`]: isFollow ? 1 : -1,
+			[`${prefixFollowee}.followers.inc`]: isFollow ? 1 : 0,
+			[`${prefixFollowee}.followers.dec`]: isFollow ? 0 : 1,
 		}, followee.id);
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/per-user-notes.ts b/packages/backend/src/services/chart/charts/per-user-notes.ts
index d048c888856a329a385a1eacec344b15b02f63fb..6a4f0363b2d4dbf19ce3e44c7af595f122742d62 100644
--- a/packages/backend/src/services/chart/charts/per-user-notes.ts
+++ b/packages/backend/src/services/chart/charts/per-user-notes.ts
@@ -1,45 +1,21 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
+import Chart, { KVs } from '../core';
 import { User } from '@/models/entities/user';
-import { SchemaType } from '@/misc/schema';
 import { Notes } from '@/models/index';
 import { Note } from '@/models/entities/note';
 import { name, schema } from './entities/per-user-notes';
 
-type PerUserNotesLog = SchemaType<typeof schema>;
-
 /**
  * ユーザーごとのノートに関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class PerUserNotesChart extends Chart<PerUserNotesLog> {
+export default class PerUserNotesChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema, true);
 	}
 
 	@autobind
-	protected genNewLog(latest: PerUserNotesLog): DeepPartial<PerUserNotesLog> {
-		return {
-			total: latest.total,
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: PerUserNotesLog[]): PerUserNotesLog {
-		return {
-			total: logs[0].total,
-			inc: logs.reduce((a, b) => a + b.inc, 0),
-			dec: logs.reduce((a, b) => a + b.dec, 0),
-			diffs: {
-				reply: logs.reduce((a, b) => a + b.diffs.reply, 0),
-				renote: logs.reduce((a, b) => a + b.diffs.renote, 0),
-				normal: logs.reduce((a, b) => a + b.diffs.normal, 0),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(group: string): Promise<DeepPartial<PerUserNotesLog>> {
+	protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> {
 		const [count] = await Promise.all([
 			Notes.count({ userId: group }),
 		]);
@@ -51,26 +27,14 @@ export default class PerUserNotesChart extends Chart<PerUserNotesLog> {
 
 	@autobind
 	public async update(user: { id: User['id'] }, note: Note, isAdditional: boolean): Promise<void> {
-		const update: Obj = {
-			diffs: {},
-		};
-
-		update.total = isAdditional ? 1 : -1;
-
-		if (isAdditional) {
-			update.inc = 1;
-		} else {
-			update.dec = 1;
-		}
-
-		if (note.replyId != null) {
-			update.diffs.reply = isAdditional ? 1 : -1;
-		} else if (note.renoteId != null) {
-			update.diffs.renote = isAdditional ? 1 : -1;
-		} else {
-			update.diffs.normal = isAdditional ? 1 : -1;
-		}
-
-		await this.inc(update, user.id);
+		await this.commit({
+			'total': isAdditional ? 1 : -1,
+			'inc': isAdditional ? 1 : 0,
+			'dec': isAdditional ? 0 : 1,
+			'diffs.normal': note.replyId == null && note.renoteId == null ? (isAdditional ? 1 : -1) : 0,
+			'diffs.renote': note.renoteId != null ? (isAdditional ? 1 : -1) : 0,
+			'diffs.reply': note.replyId != null ? (isAdditional ? 1 : -1) : 0,
+			'diffs.withFile': note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0,
+		}, user.id);
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/per-user-reactions.ts b/packages/backend/src/services/chart/charts/per-user-reactions.ts
index 2f5353340de95b3ea61a342d76c2a79a3be404bc..2ec347f40ace4efb3ab341ce65526eea735e71a3 100644
--- a/packages/backend/src/services/chart/charts/per-user-reactions.ts
+++ b/packages/backend/src/services/chart/charts/per-user-reactions.ts
@@ -1,48 +1,29 @@
 import autobind from 'autobind-decorator';
-import Chart, { DeepPartial } from '../core';
+import Chart, { KVs } from '../core';
 import { User } from '@/models/entities/user';
 import { Note } from '@/models/entities/note';
-import { SchemaType } from '@/misc/schema';
 import { Users } from '@/models/index';
 import { name, schema } from './entities/per-user-reactions';
 
-type PerUserReactionsLog = SchemaType<typeof schema>;
-
 /**
  * ユーザーごとのリアクションに関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class PerUserReactionsChart extends Chart<PerUserReactionsLog> {
+export default class PerUserReactionsChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema, true);
 	}
 
 	@autobind
-	protected genNewLog(latest: PerUserReactionsLog): DeepPartial<PerUserReactionsLog> {
-		return {};
-	}
-
-	@autobind
-	protected aggregate(logs: PerUserReactionsLog[]): PerUserReactionsLog {
-		return {
-			local: {
-				count: logs.reduce((a, b) => a + b.local.count, 0),
-			},
-			remote: {
-				count: logs.reduce((a, b) => a + b.remote.count, 0),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(group: string): Promise<DeepPartial<PerUserReactionsLog>> {
+	protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> {
 		return {};
 	}
 
 	@autobind
 	public async update(user: { id: User['id'], host: User['host'] }, note: Note): Promise<void> {
-		this.inc({
-			[Users.isLocalUser(user) ? 'local' : 'remote']: { count: 1 },
+		const prefix = Users.isLocalUser(user) ? 'local' : 'remote';
+		this.commit({
+			[`${prefix}.count`]: 1,
 		}, note.userId);
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/test-grouped.ts b/packages/backend/src/services/chart/charts/test-grouped.ts
index c851d2df0140cc7734d720dcb1790b86ee0ed627..5f0b1aafdc6df74d256b5384b4572792902033cf 100644
--- a/packages/backend/src/services/chart/charts/test-grouped.ts
+++ b/packages/backend/src/services/chart/charts/test-grouped.ts
@@ -1,15 +1,12 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { name, schema } from './entities/test-grouped';
 
-type TestGroupedLog = SchemaType<typeof schema>;
-
 /**
  * For testing
  */
 // eslint-disable-next-line import/no-default-export
-export default class TestGroupedChart extends Chart<TestGroupedLog> {
+export default class TestGroupedChart extends Chart<typeof schema> {
 	private total = {} as Record<string, number>;
 
 	constructor() {
@@ -17,31 +14,9 @@ export default class TestGroupedChart extends Chart<TestGroupedLog> {
 	}
 
 	@autobind
-	protected genNewLog(latest: TestGroupedLog): DeepPartial<TestGroupedLog> {
-		return {
-			foo: {
-				total: latest.foo.total,
-			},
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: TestGroupedLog[]): TestGroupedLog {
+	protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> {
 		return {
-			foo: {
-				total: logs[0].foo.total,
-				inc: logs.reduce((a, b) => a + b.foo.inc, 0),
-				dec: logs.reduce((a, b) => a + b.foo.dec, 0),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(group: string): Promise<DeepPartial<TestGroupedLog>> {
-		return {
-			foo: {
-				total: this.total[group],
-			},
+			'foo.total': this.total[group],
 		};
 	}
 
@@ -49,14 +24,11 @@ export default class TestGroupedChart extends Chart<TestGroupedLog> {
 	public async increment(group: string): Promise<void> {
 		if (this.total[group] == null) this.total[group] = 0;
 
-		const update: Obj = {};
-
-		update.total = 1;
-		update.inc = 1;
 		this.total[group]++;
 
-		await this.inc({
-			foo: update,
+		await this.commit({
+			'foo.total': 1,
+			'foo.inc': 1,
 		}, group);
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/test-intersection.ts b/packages/backend/src/services/chart/charts/test-intersection.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6ba71a9567f52e356d30709d3dbcae810832789
--- /dev/null
+++ b/packages/backend/src/services/chart/charts/test-intersection.ts
@@ -0,0 +1,32 @@
+import autobind from 'autobind-decorator';
+import Chart, { KVs } from '../core';
+import { name, schema } from './entities/test-intersection';
+
+/**
+ * For testing
+ */
+// eslint-disable-next-line import/no-default-export
+export default class TestIntersectionChart extends Chart<typeof schema> {
+	constructor() {
+		super(name, schema);
+	}
+
+	@autobind
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
+		return {};
+	}
+
+	@autobind
+	public async addA(key: string): Promise<void> {
+		await this.commit({
+			a: [key],
+		});
+	}
+
+	@autobind
+	public async addB(key: string): Promise<void> {
+		await this.commit({
+			b: [key],
+		});
+	}
+}
diff --git a/packages/backend/src/services/chart/charts/test-unique.ts b/packages/backend/src/services/chart/charts/test-unique.ts
index 3564f675adfd1d7471d57c3310d8cd1b3cf90d73..e67036acefa048e14974547890c5ad08241067fe 100644
--- a/packages/backend/src/services/chart/charts/test-unique.ts
+++ b/packages/backend/src/services/chart/charts/test-unique.ts
@@ -1,39 +1,24 @@
 import autobind from 'autobind-decorator';
-import Chart, { DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { name, schema } from './entities/test-unique';
 
-type TestUniqueLog = SchemaType<typeof schema>;
-
 /**
  * For testing
  */
 // eslint-disable-next-line import/no-default-export
-export default class TestUniqueChart extends Chart<TestUniqueLog> {
+export default class TestUniqueChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema);
 	}
 
 	@autobind
-	protected genNewLog(latest: TestUniqueLog): DeepPartial<TestUniqueLog> {
-		return {};
-	}
-
-	@autobind
-	protected aggregate(logs: TestUniqueLog[]): TestUniqueLog {
-		return {
-			foo: logs.reduce((a, b) => a.concat(b.foo), [] as TestUniqueLog['foo']),
-		};
-	}
-
-	@autobind
-	protected async fetchActual(): Promise<DeepPartial<TestUniqueLog>> {
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
 		return {};
 	}
 
 	@autobind
 	public async uniqueIncrement(key: string): Promise<void> {
-		await this.inc({
+		await this.commit({
 			foo: [key],
 		});
 	}
diff --git a/packages/backend/src/services/chart/charts/test.ts b/packages/backend/src/services/chart/charts/test.ts
index 06add7ede9225143a0ce0d60162a002d0085aa9e..878acd51beb1be1e9e890d2f9e48703f5ed93acd 100644
--- a/packages/backend/src/services/chart/charts/test.ts
+++ b/packages/backend/src/services/chart/charts/test.ts
@@ -1,15 +1,12 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { name, schema } from './entities/test';
 
-type TestLog = SchemaType<typeof schema>;
-
 /**
  * For testing
  */
 // eslint-disable-next-line import/no-default-export
-export default class TestChart extends Chart<TestLog> {
+export default class TestChart extends Chart<typeof schema> {
 	public total = 0; // publicにするのはテストのため
 
 	constructor() {
@@ -17,57 +14,29 @@ export default class TestChart extends Chart<TestLog> {
 	}
 
 	@autobind
-	protected genNewLog(latest: TestLog): DeepPartial<TestLog> {
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
 		return {
-			foo: {
-				total: latest.foo.total,
-			},
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: TestLog[]): TestLog {
-		return {
-			foo: {
-				total: logs[0].foo.total,
-				inc: logs.reduce((a, b) => a + b.foo.inc, 0),
-				dec: logs.reduce((a, b) => a + b.foo.dec, 0),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(): Promise<DeepPartial<TestLog>> {
-		return {
-			foo: {
-				total: this.total,
-			},
+			'foo.total': this.total,
 		};
 	}
 
 	@autobind
 	public async increment(): Promise<void> {
-		const update: Obj = {};
-
-		update.total = 1;
-		update.inc = 1;
 		this.total++;
 
-		await this.inc({
-			foo: update,
+		await this.commit({
+			'foo.total': 1,
+			'foo.inc': 1,
 		});
 	}
 
 	@autobind
 	public async decrement(): Promise<void> {
-		const update: Obj = {};
-
-		update.total = -1;
-		update.dec = 1;
 		this.total--;
 
-		await this.inc({
-			foo: update,
+		await this.commit({
+			'foo.total': -1,
+			'foo.dec': 1,
 		});
 	}
 }
diff --git a/packages/backend/src/services/chart/charts/users.ts b/packages/backend/src/services/chart/charts/users.ts
index c36c6cd979694c5905f0c51391e30f9c83b3d7e0..50fca3a8d6b953208e97a0fb402a5a973946f47c 100644
--- a/packages/backend/src/services/chart/charts/users.ts
+++ b/packages/backend/src/services/chart/charts/users.ts
@@ -1,80 +1,40 @@
 import autobind from 'autobind-decorator';
-import Chart, { Obj, DeepPartial } from '../core';
-import { SchemaType } from '@/misc/schema';
+import Chart, { KVs } from '../core';
 import { Users } from '@/models/index';
 import { Not, IsNull } from 'typeorm';
 import { User } from '@/models/entities/user';
 import { name, schema } from './entities/users';
 
-type UsersLog = SchemaType<typeof schema>;
-
 /**
  * ユーザー数に関するチャート
  */
 // eslint-disable-next-line import/no-default-export
-export default class UsersChart extends Chart<UsersLog> {
+export default class UsersChart extends Chart<typeof schema> {
 	constructor() {
 		super(name, schema);
 	}
 
 	@autobind
-	protected genNewLog(latest: UsersLog): DeepPartial<UsersLog> {
-		return {
-			local: {
-				total: latest.local.total,
-			},
-			remote: {
-				total: latest.remote.total,
-			},
-		};
-	}
-
-	@autobind
-	protected aggregate(logs: UsersLog[]): UsersLog {
-		return {
-			local: {
-				total: logs[0].local.total,
-				inc: logs.reduce((a, b) => a + b.local.inc, 0),
-				dec: logs.reduce((a, b) => a + b.local.dec, 0),
-			},
-			remote: {
-				total: logs[0].remote.total,
-				inc: logs.reduce((a, b) => a + b.remote.inc, 0),
-				dec: logs.reduce((a, b) => a + b.remote.dec, 0),
-			},
-		};
-	}
-
-	@autobind
-	protected async fetchActual(): Promise<DeepPartial<UsersLog>> {
+	protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> {
 		const [localCount, remoteCount] = await Promise.all([
 			Users.count({ host: null }),
 			Users.count({ host: Not(IsNull()) }),
 		]);
 
 		return {
-			local: {
-				total: localCount,
-			},
-			remote: {
-				total: remoteCount,
-			},
+			'local.total': localCount,
+			'remote.total': remoteCount,
 		};
 	}
 
 	@autobind
 	public async update(user: { id: User['id'], host: User['host'] }, isAdditional: boolean): Promise<void> {
-		const update: Obj = {};
-
-		update.total = isAdditional ? 1 : -1;
-		if (isAdditional) {
-			update.inc = 1;
-		} else {
-			update.dec = 1;
-		}
+		const prefix = Users.isLocalUser(user) ? 'local' : 'remote';
 
-		await this.inc({
-			[Users.isLocalUser(user) ? 'local' : 'remote']: update,
+		await this.commit({
+			[`${prefix}.total`]: isAdditional ? 1 : -1,
+			[`${prefix}.inc`]: isAdditional ? 1 : 0,
+			[`${prefix}.dec`]: isAdditional ? 0 : 1,
 		});
 	}
 }
diff --git a/packages/backend/src/services/chart/core.ts b/packages/backend/src/services/chart/core.ts
index e406449f4f7b2e04710cae83d72ff825c0d7fada..5888e1a144af4679f23f8286f95ff5a80d52f9e6 100644
--- a/packages/backend/src/services/chart/core.ts
+++ b/packages/backend/src/services/chart/core.ts
@@ -7,24 +7,19 @@
 import * as nestedProperty from 'nested-property';
 import autobind from 'autobind-decorator';
 import Logger from '../logger';
-import { Schema } from '@/misc/schema';
 import { EntitySchema, getRepository, Repository, LessThan, Between } from 'typeorm';
 import { dateUTC, isTimeSame, isTimeBefore, subtractTime, addTime } from '@/prelude/time';
 import { getChartInsertLock } from '@/misc/app-lock';
 
 const logger = new Logger('chart', 'white', process.env.NODE_ENV !== 'test');
 
-export type Obj = { [key: string]: any };
+const columnPrefix = '___' as const;
+const uniqueTempColumnPrefix = 'unique_temp___' as const;
+const columnDot = '_' as const;
 
-export type DeepPartial<T> = {
-	[P in keyof T]?: DeepPartial<T[P]>;
-};
-
-type ArrayValue<T> = {
-	[P in keyof T]: T[P] extends number ? T[P][] : ArrayValue<T[P]>;
-};
+type KeyToColumnName<T extends string> = T extends `${infer R1}.${infer R2}` ? `${R1}${typeof columnDot}${KeyToColumnName<R2>}` : T;
 
-type Log = {
+type RawRecord<S extends Schema> = {
 	id: number;
 
 	/**
@@ -36,6 +31,10 @@ type Log = {
 	 * 集計日時のUnixタイムスタンプ(秒)
 	 */
 	date: number;
+} & {
+	[K in keyof S as `${typeof uniqueTempColumnPrefix}${KeyToColumnName<string & K>}`]: S[K]['uniqueIncrement'] extends true ? string[] : never;
+} & {
+	[K in keyof S as `${typeof columnPrefix}${KeyToColumnName<string & K>}`]: number;
 };
 
 const camelToSnake = (str: string): string => {
@@ -44,123 +43,74 @@ const camelToSnake = (str: string): string => {
 
 const removeDuplicates = (array: any[]) => Array.from(new Set(array));
 
+type Schema = Record<string, {
+	uniqueIncrement?: boolean;
+
+	intersection?: string[] | ReadonlyArray<string>;
+
+	range?: 'big' | 'small' | 'medium';
+
+	// previousな値を引き継ぐかどうか
+	accumulate?: boolean;
+}>;
+
+type Commit<S extends Schema> = {
+	[K in keyof S]?: S[K]['uniqueIncrement'] extends true ? string[] : number;
+};
+
+export type KVs<S extends Schema> = {
+	[K in keyof S]: number;
+};
+
+type ChartResult<T extends Schema> = {
+	[P in keyof T]: number[];
+};
+
 /**
  * 様々なチャートの管理を司るクラス
  */
 // eslint-disable-next-line import/no-default-export
-export default abstract class Chart<T extends Record<string, any>> {
-	private static readonly columnPrefix = '___';
-	private static readonly columnDot = '_';
+export default abstract class Chart<T extends Schema> {
+	public schema: T;
 
 	private name: string;
 	private buffer: {
-		diff: DeepPartial<T>;
+		diff: Commit<T>;
 		group: string | null;
 	}[] = [];
-	public schema: Schema;
-	protected repositoryForHour: Repository<Log>;
-	protected repositoryForDay: Repository<Log>;
-
-	protected abstract genNewLog(latest: T): DeepPartial<T>;
-
-	/**
-	 * @param logs 日時が新しい方が先頭
-	 */
-	protected abstract aggregate(logs: T[]): T;
+	protected repositoryForHour: Repository<RawRecord<T>>;
+	protected repositoryForDay: Repository<RawRecord<T>>;
 
-	protected abstract fetchActual(group: string | null): Promise<DeepPartial<T>>;
+	protected abstract queryCurrentState(group: string | null): Promise<Partial<KVs<T>>>;
 
 	@autobind
-	private static convertSchemaToFlatColumnDefinitions(schema: Schema) {
-		const columns = {} as Record<string, unknown>;
-		const flatColumns = (x: Obj, path?: string) => {
-			for (const [k, v] of Object.entries(x)) {
-				const p = path ? `${path}${this.columnDot}${k}` : k;
-				if (v.type === 'object') {
-					flatColumns(v.properties, p);
-				} else if (v.type === 'number') {
-					columns[this.columnPrefix + p] = {
-						type: 'bigint',
-					};
-				} else if (v.type === 'array' && v.items.type === 'string') {
-					columns[this.columnPrefix + p] = {
-						type: 'varchar',
-						array: true,
-					};
-				}
+	private static convertSchemaToColumnDefinitions(schema: Schema): Record<string, { type: string; array?: boolean; default?: any; }> {
+		const columns = {} as Record<string, { type: string; array?: boolean; default?: any; }>;
+		for (const [k, v] of Object.entries(schema)) {
+			const name = k.replaceAll('.', columnDot);
+			const type = v.range === 'big' ? 'bigint' : v.range === 'small' ? 'smallint' : 'integer';
+			if (v.uniqueIncrement) {
+				columns[uniqueTempColumnPrefix + name] = {
+					type: 'varchar',
+					array: true,
+					default: '{}',
+				};
+				columns[columnPrefix + name] = {
+					type,
+					default: 0,
+				};
+			} else {
+				columns[columnPrefix + name] = {
+					type,
+					default: 0,
+				};
 			}
-		};
-		flatColumns(schema.properties!);
-		return columns;
-	}
-
-	@autobind
-	private static convertFlattenColumnsToObject(x: Record<string, unknown>): Record<string, unknown> {
-		const obj = {} as Record<string, unknown>;
-		for (const k of Object.keys(x).filter(k => k.startsWith(Chart.columnPrefix))) {
-			// now k is ___x_y_z
-			const path = k.substr(Chart.columnPrefix.length).split(Chart.columnDot).join('.');
-			nestedProperty.set(obj, path, x[k]);
 		}
-		return obj;
-	}
-
-	@autobind
-	private static convertObjectToFlattenColumns(x: Record<string, unknown>) {
-		const columns = {} as Record<string, number | unknown[]>;
-		const flatten = (x: Obj, path?: string) => {
-			for (const [k, v] of Object.entries(x)) {
-				const p = path ? `${path}${this.columnDot}${k}` : k;
-				if (typeof v === 'object' && !Array.isArray(v)) {
-					flatten(v, p);
-				} else {
-					columns[this.columnPrefix + p] = v;
-				}
-			}
-		};
-		flatten(x);
 		return columns;
 	}
 
 	@autobind
-	private static countUniqueFields(x: Record<string, unknown>) {
-		const exec = (x: Obj) => {
-			const res = {} as Record<string, unknown>;
-			for (const [k, v] of Object.entries(x)) {
-				if (typeof v === 'object' && !Array.isArray(v)) {
-					res[k] = exec(v);
-				} else if (Array.isArray(v)) {
-					res[k] = Array.from(new Set(v)).length;
-				} else {
-					res[k] = v;
-				}
-			}
-			return res;
-		};
-		return exec(x);
-	}
-
-	@autobind
-	private static convertQuery(diff: Record<string, number | unknown[]>) {
-		const query: Record<string, () => string> = {};
-
-		for (const [k, v] of Object.entries(diff)) {
-			if (typeof v === 'number') {
-				if (v > 0) query[k] = () => `"${k}" + ${v}`;
-				if (v < 0) query[k] = () => `"${k}" - ${Math.abs(v)}`;
-			} else if (Array.isArray(v)) {
-				// TODO: item が文字列以外の場合も対応
-				// TODO: item をSQLエスケープ
-				const items = v.map(item => `"${item}"`).join(',');
-				query[k] = () => `array_cat("${k}", '{${items}}'::varchar[])`;
-			}
-		}
-
-		return query;
-	}
-
-	@autobind
-	private static dateToTimestamp(x: Date): Log['date'] {
+	private static dateToTimestamp(x: Date): number {
 		return Math.floor(x.getTime() / 1000);
 	}
 
@@ -207,7 +157,7 @@ export default abstract class Chart<T extends Record<string, any>> {
 						length: 128,
 					},
 				} : {}),
-				...Chart.convertSchemaToFlatColumnDefinitions(schema),
+				...Chart.convertSchemaToColumnDefinitions(schema),
 			},
 			indices: [{
 				columns: grouped ? ['date', 'group'] : ['date'],
@@ -233,37 +183,39 @@ export default abstract class Chart<T extends Record<string, any>> {
 		};
 	}
 
-	constructor(name: string, schema: Schema, grouped = false) {
+	constructor(name: string, schema: T, grouped = false) {
 		this.name = name;
 		this.schema = schema;
 
 		const { hour, day } = Chart.schemaToEntity(name, schema, grouped);
-		this.repositoryForHour = getRepository<Log>(hour);
-		this.repositoryForDay = getRepository<Log>(day);
+		this.repositoryForHour = getRepository<RawRecord<T>>(hour);
+		this.repositoryForDay = getRepository<RawRecord<T>>(day);
 	}
 
 	@autobind
-	private getNewLog(latest: T | null): T {
-		const log = latest ? this.genNewLog(latest) : {};
-		const flatColumns = (x: Obj, path?: string) => {
-			for (const [k, v] of Object.entries(x)) {
-				const p = path ? `${path}.${k}` : k;
-				if (v.type === 'object') {
-					flatColumns(v.properties, p);
-				} else {
-					if (nestedProperty.get(log, p) == null) {
-						const emptyValue = v.type === 'number' ? 0 : [];
-						nestedProperty.set(log, p, emptyValue);
-					}
-				}
+	private convertRawRecord(x: RawRecord<T>): KVs<T> {
+		const kvs = {} as KVs<T>;
+		for (const k of Object.keys(x).filter(k => k.startsWith(columnPrefix))) {
+			kvs[k.substr(columnPrefix.length).split(columnDot).join('.')] = x[k];
+		}
+		return kvs;
+	}
+
+	@autobind
+	private getNewLog(latest: KVs<T> | null): KVs<T> {
+		const log = {} as Record<keyof T, number>;
+		for (const [k, v] of Object.entries(this.schema)) {
+			if (v.accumulate && latest) {
+				log[k] = latest[k];
+			} else {
+				log[k] = 0;
 			}
-		};
-		flatColumns(this.schema.properties!);
-		return log as T;
+		}
+		return log as KVs<T>;
 	}
 
 	@autobind
-	private getLatestLog(group: string | null, span: 'hour' | 'day'): Promise<Log | null> {
+	private getLatestLog(group: string | null, span: 'hour' | 'day'): Promise<RawRecord<T> | null> {
 		const repository =
 			span === 'hour' ? this.repositoryForHour :
 			span === 'day' ? this.repositoryForDay :
@@ -282,7 +234,7 @@ export default abstract class Chart<T extends Record<string, any>> {
 	 * 現在(=今のHour or Day)のログをデータベースから探して、あればそれを返し、なければ作成して返します。
 	 */
 	@autobind
-	private async claimCurrentLog(group: string | null, span: 'hour' | 'day'): Promise<Log> {
+	private async claimCurrentLog(group: string | null, span: 'hour' | 'day'): Promise<RawRecord<T>> {
 		const [y, m, d, h] = Chart.getCurrentDate();
 
 		const current = dateUTC(
@@ -306,8 +258,8 @@ export default abstract class Chart<T extends Record<string, any>> {
 			return currentLog;
 		}
 
-		let log: Log;
-		let data: T;
+		let log: RawRecord<T>;
+		let data: KVs<T>;
 
 		// 集計期間が変わってから、初めてのチャート更新なら
 		// 最も最近のログを持ってくる
@@ -318,10 +270,8 @@ export default abstract class Chart<T extends Record<string, any>> {
 		const latest = await this.getLatestLog(group, span);
 
 		if (latest != null) {
-			const obj = Chart.convertFlattenColumnsToObject(latest) as T;
-
 			// 空ログデータを作成
-			data = this.getNewLog(obj);
+			data = this.getNewLog(this.convertRawRecord(latest));
 		} else {
 			// ログが存在しなかったら
 			// (Misskeyインスタンスを建てて初めてのチャート更新時など)
@@ -346,11 +296,17 @@ export default abstract class Chart<T extends Record<string, any>> {
 			// ログがあればそれを返して終了
 			if (currentLog != null) return currentLog;
 
+			const columns = {} as Record<string, number | unknown[]>;
+			for (const [k, v] of Object.entries(data)) {
+				const name = k.replaceAll('.', columnDot);
+				columns[columnPrefix + name] = v;
+			}
+
 			// 新規ログ挿入
 			log = await repository.insert({
 				date: date,
 				...(group ? { group: group } : {}),
-				...Chart.convertObjectToFlattenColumns(data),
+				...columns,
 			}).then(x => repository.findOneOrFail(x.identifiers[0]));
 
 			logger.info(`${this.name + (group ? `:${group}` : '')}(${span}): New commit created`);
@@ -362,7 +318,10 @@ export default abstract class Chart<T extends Record<string, any>> {
 	}
 
 	@autobind
-	protected commit(diff: DeepPartial<T>, group: string | null = null): void {
+	protected commit(diff: Commit<T>, group: string | null = null): void {
+		for (const [k, v] of Object.entries(diff)) {
+			if (v == null || v === 0 || (Array.isArray(v) && v.length === 0)) delete diff[k];
+		}
 		this.buffer.push({
 			diff, group,
 		});
@@ -381,13 +340,11 @@ export default abstract class Chart<T extends Record<string, any>> {
 		// そのログは本来は 01:00~ のログとしてDBに保存されて欲しいのに、02:00~ のログ扱いになってしまう。
 		// これを回避するための実装は複雑になりそうなため、一旦保留。
 
-		const update = async (logHour: Log, logDay: Log): Promise<void> => {
+		const update = async (logHour: RawRecord<T>, logDay: RawRecord<T>): Promise<void> => {
 			const finalDiffs = {} as Record<string, number | unknown[]>;
 
 			for (const diff of this.buffer.filter(q => q.group == null || (q.group === logHour.group)).map(q => q.diff)) {
-				const columns = Chart.convertObjectToFlattenColumns(diff);
-
-				for (const [k, v] of Object.entries(columns)) {
+				for (const [k, v] of Object.entries(diff)) {
 					if (finalDiffs[k] == null) {
 						finalDiffs[k] = v;
 					} else {
@@ -400,18 +357,72 @@ export default abstract class Chart<T extends Record<string, any>> {
 				}
 			}
 
-			const query = Chart.convertQuery(finalDiffs);
+			const queryForHour: Record<string, number | (() => string)> = {};
+			const queryForDay: Record<string, number | (() => string)> = {};
+			for (const [k, v] of Object.entries(finalDiffs)) {
+				if (typeof v === 'number') {
+					const name = columnPrefix + k.replaceAll('.', columnDot);
+					if (v > 0) queryForHour[name] = () => `"${name}" + ${v}`;
+					if (v < 0) queryForHour[name] = () => `"${name}" - ${Math.abs(v)}`;
+					if (v > 0) queryForDay[name] = () => `"${name}" + ${v}`;
+					if (v < 0) queryForDay[name] = () => `"${name}" - ${Math.abs(v)}`;
+				} else if (Array.isArray(v) && v.length > 0) { // ユニークインクリメント
+					const tempColumnName = uniqueTempColumnPrefix + k.replaceAll('.', columnDot);
+					// TODO: item をSQLエスケープ
+					const itemsForHour = v.filter(item => !logHour[tempColumnName].includes(item)).map(item => `"${item}"`);
+					const itemsForDay = v.filter(item => !logDay[tempColumnName].includes(item)).map(item => `"${item}"`);
+					if (itemsForHour.length > 0) queryForHour[tempColumnName] = () => `array_cat("${tempColumnName}", '{${itemsForHour.join(',')}}'::varchar[])`;
+					if (itemsForDay.length > 0) queryForDay[tempColumnName] = () => `array_cat("${tempColumnName}", '{${itemsForDay.join(',')}}'::varchar[])`;
+				}
+			}
+
+			// bake unique count
+			for (const [k, v] of Object.entries(finalDiffs)) {
+				if (this.schema[k].uniqueIncrement) {
+					const name = columnPrefix + k.replaceAll('.', columnDot);
+					const tempColumnName = uniqueTempColumnPrefix + k.replaceAll('.', columnDot);
+					queryForHour[name] = new Set([...v, ...logHour[tempColumnName]]).size;
+					queryForDay[name] = new Set([...v, ...logDay[tempColumnName]]).size;
+				}
+			}
+
+			// compute intersection
+			// TODO: intersectionに指定されたカラムがintersectionだった場合の対応
+			for (const [k, v] of Object.entries(this.schema)) {
+				const intersection = v.intersection;
+				if (intersection) {
+					const name = columnPrefix + k.replaceAll('.', columnDot);
+					const firstKey = intersection[0];
+					const firstTempColumnName = uniqueTempColumnPrefix + firstKey.replaceAll('.', columnDot);
+					const currentValuesForHour = new Set([...(finalDiffs[firstKey] ?? []), ...logHour[firstTempColumnName]]);
+					const currentValuesForDay = new Set([...(finalDiffs[firstKey] ?? []), ...logDay[firstTempColumnName]]);
+					for (let i = 1; i < intersection.length; i++) {
+						const targetKey = intersection[i];
+						const targetTempColumnName = uniqueTempColumnPrefix + targetKey.replaceAll('.', columnDot);
+						const targetValuesForHour = new Set([...(finalDiffs[targetKey] ?? []), ...logHour[targetTempColumnName]]);
+						const targetValuesForDay = new Set([...(finalDiffs[targetKey] ?? []), ...logDay[targetTempColumnName]]);
+						currentValuesForHour.forEach(v => {
+							if (!targetValuesForHour.has(v)) currentValuesForHour.delete(v);
+						});
+						currentValuesForDay.forEach(v => {
+							if (!targetValuesForDay.has(v)) currentValuesForDay.delete(v);
+						});
+					}
+					queryForHour[name] = currentValuesForHour.size;
+					queryForDay[name] = currentValuesForDay.size;
+				}
+			}
 
 			// ログ更新
 			await Promise.all([
 				this.repositoryForHour.createQueryBuilder()
 					.update()
-					.set(query)
+					.set(queryForHour)
 					.where('id = :id', { id: logHour.id })
 					.execute(),
 				this.repositoryForDay.createQueryBuilder()
 					.update()
-					.set(query)
+					.set(queryForDay)
 					.where('id = :id', { id: logDay.id })
 					.execute(),
 			]);
@@ -435,18 +446,28 @@ export default abstract class Chart<T extends Record<string, any>> {
 
 	@autobind
 	public async resync(group: string | null = null): Promise<void> {
-		const data = await this.fetchActual(group);
+		const data = await this.queryCurrentState(group);
 
-		const update = async (logHour: Log, logDay: Log): Promise<void> => {
+		const columns = {} as Record<string, number>;
+		for (const [k, v] of Object.entries(data)) {
+			const name = k.replaceAll('.', columnDot);
+			columns[columnPrefix + name] = v;
+		}
+
+		if (Object.keys(columns).length === 0) {
+			return;
+		}
+
+		const update = async (logHour: RawRecord<T>, logDay: RawRecord<T>): Promise<void> => {
 			await Promise.all([
 				this.repositoryForHour.createQueryBuilder()
 					.update()
-					.set(Chart.convertObjectToFlattenColumns(data))
+					.set(columns as any)
 					.where('id = :id', { id: logHour.id })
 					.execute(),
 				this.repositoryForDay.createQueryBuilder()
 					.update()
-					.set(Chart.convertObjectToFlattenColumns(data))
+					.set(columns as any)
 					.where('id = :id', { id: logDay.id })
 					.execute(),
 			]);
@@ -460,12 +481,43 @@ export default abstract class Chart<T extends Record<string, any>> {
 	}
 
 	@autobind
-	protected async inc(inc: DeepPartial<T>, group: string | null = null): Promise<void> {
-		await this.commit(inc, group);
+	public async clean(): Promise<void> {
+		const current = dateUTC(Chart.getCurrentDate());
+
+		// 一日以上前かつ三日以内
+		const gt = Chart.dateToTimestamp(current) - (60 * 60 * 24 * 3);
+		const lt = Chart.dateToTimestamp(current) - (60 * 60 * 24);
+
+		const columns = {} as Record<string, number>;
+		for (const [k, v] of Object.entries(this.schema)) {
+			if (v.uniqueIncrement) {
+				const name = k.replaceAll('.', columnDot);
+				columns[uniqueTempColumnPrefix + name] = [];
+			}
+		}
+
+		if (Object.keys(columns).length === 0) {
+			return;
+		}
+
+		await Promise.all([
+			this.repositoryForHour.createQueryBuilder()
+				.update()
+				.set(columns as any)
+				.where('date > :gt', { gt })
+				.andWhere('date < :lt', { lt })
+				.execute(),
+			this.repositoryForDay.createQueryBuilder()
+				.update()
+				.set(columns as any)
+				.where('date > :gt', { gt })
+				.andWhere('date < :lt', { lt })
+				.execute(),
+		]);
 	}
 
 	@autobind
-	public async getChart(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise<ArrayValue<T>> {
+	public async getChartRaw(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise<ChartResult<T>> {
 		const [y, m, d, h, _m, _s, _ms] = cursor ? Chart.parseDate(subtractTime(addTime(cursor, 1, span), 1)) : Chart.getCurrentDate();
 		const [y2, m2, d2, h2] = cursor ? Chart.parseDate(addTime(cursor, 1, span)) : [] as never;
 
@@ -526,7 +578,7 @@ export default abstract class Chart<T extends Record<string, any>> {
 			}
 		}
 
-		const chart: T[] = [];
+		const chart: KVs<T>[] = [];
 
 		for (let i = (amount - 1); i >= 0; i--) {
 			const current =
@@ -537,17 +589,16 @@ export default abstract class Chart<T extends Record<string, any>> {
 			const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current));
 
 			if (log) {
-				const data = Chart.convertFlattenColumnsToObject(log);
-				chart.unshift(Chart.countUniqueFields(data) as T);
+				chart.unshift(this.convertRawRecord(log));
 			} else {
 				// 隙間埋め
 				const latest = logs.find(l => isTimeBefore(new Date(l.date * 1000), current));
-				const data = latest ? Chart.convertFlattenColumnsToObject(latest) as T : null;
-				chart.unshift(Chart.countUniqueFields(this.getNewLog(data)) as T);
+				const data = latest ? this.convertRawRecord(latest) : null;
+				chart.unshift(this.getNewLog(data));
 			}
 		}
 
-		const res = {} as Record<string, unknown>;
+		const res = {} as ChartResult<T>;
 
 		/**
 		 * [{ foo: 1, bar: 5 }, { foo: 2, bar: 6 }, { foo: 3, bar: 7 }]
@@ -555,36 +606,26 @@ export default abstract class Chart<T extends Record<string, any>> {
 		 * { foo: [1, 2, 3], bar: [5, 6, 7] }
 		 * にする
 		 */
-		const compact = (x: Obj, path?: string): void => {
-			for (const [k, v] of Object.entries(x)) {
-				const p = path ? `${path}.${k}` : k;
-				if (typeof v === 'object' && !Array.isArray(v)) {
-					compact(v, p);
+		for (const record of chart) {
+			for (const [k, v] of Object.entries(record)) {
+				if (res[k]) {
+					res[k].push(v);
 				} else {
-					const values = chart.map(s => nestedProperty.get(s, p));
-					nestedProperty.set(res, p, values);
+					res[k] = [v];
 				}
 			}
-		};
-
-		compact(chart[0]);
+		}
 
-		return res as ArrayValue<T>;
+		return res;
 	}
-}
 
-export function convertLog(logSchema: Schema): Schema {
-	const v: Schema = JSON.parse(JSON.stringify(logSchema)); // copy
-	if (v.type === 'number') {
-		v.type = 'array';
-		v.items = {
-			type: 'number' as const,
-			optional: false as const, nullable: false as const,
-		};
-	} else if (v.type === 'object') {
-		for (const k of Object.keys(v.properties!)) {
-			v.properties![k] = convertLog(v.properties![k]);
+	@autobind
+	public async getChart(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise<Record<string, unknown>> {
+		const result = await this.getChartRaw(span, amount, cursor, group);
+		const object = {};
+		for (const [k, v] of Object.entries(result)) {
+			nestedProperty.set(object, k, v);
 		}
+		return object;
 	}
-	return v;
 }
diff --git a/packages/backend/src/services/chart/entities.ts b/packages/backend/src/services/chart/entities.ts
index dedbd470804b1e2f80e5014775554d56a031fbcf..569b3285573d5b66b7be310380587128d8b4c6b2 100644
--- a/packages/backend/src/services/chart/entities.ts
+++ b/packages/backend/src/services/chart/entities.ts
@@ -1,7 +1,6 @@
 import { entity as FederationChart } from './charts/entities/federation';
 import { entity as NotesChart } from './charts/entities/notes';
 import { entity as UsersChart } from './charts/entities/users';
-import { entity as NetworkChart } from './charts/entities/network';
 import { entity as ActiveUsersChart } from './charts/entities/active-users';
 import { entity as InstanceChart } from './charts/entities/instance';
 import { entity as PerUserNotesChart } from './charts/entities/per-user-notes';
@@ -10,12 +9,12 @@ import { entity as PerUserReactionsChart } from './charts/entities/per-user-reac
 import { entity as HashtagChart } from './charts/entities/hashtag';
 import { entity as PerUserFollowingChart } from './charts/entities/per-user-following';
 import { entity as PerUserDriveChart } from './charts/entities/per-user-drive';
+import { entity as ApRequestChart } from './charts/entities/ap-request';
 
 export const entities = [
 	FederationChart.hour, FederationChart.day,
 	NotesChart.hour, NotesChart.day,
 	UsersChart.hour, UsersChart.day,
-	NetworkChart.hour, NetworkChart.day,
 	ActiveUsersChart.hour, ActiveUsersChart.day,
 	InstanceChart.hour, InstanceChart.day,
 	PerUserNotesChart.hour, PerUserNotesChart.day,
@@ -24,4 +23,5 @@ export const entities = [
 	HashtagChart.hour, HashtagChart.day,
 	PerUserFollowingChart.hour, PerUserFollowingChart.day,
 	PerUserDriveChart.hour, PerUserDriveChart.day,
+	ApRequestChart.hour, ApRequestChart.day,
 ];
diff --git a/packages/backend/src/services/chart/index.ts b/packages/backend/src/services/chart/index.ts
index 0b9887b36f7226b688d85fc2df120380fd1a8fe3..1c0f7aadc15c8a0c4c4a4b4adc63ec34d6043fb5 100644
--- a/packages/backend/src/services/chart/index.ts
+++ b/packages/backend/src/services/chart/index.ts
@@ -3,7 +3,6 @@ import { beforeShutdown } from '@/misc/before-shutdown';
 import FederationChart from './charts/federation';
 import NotesChart from './charts/notes';
 import UsersChart from './charts/users';
-import NetworkChart from './charts/network';
 import ActiveUsersChart from './charts/active-users';
 import InstanceChart from './charts/instance';
 import PerUserNotesChart from './charts/per-user-notes';
@@ -12,11 +11,11 @@ import PerUserReactionsChart from './charts/per-user-reactions';
 import HashtagChart from './charts/hashtag';
 import PerUserFollowingChart from './charts/per-user-following';
 import PerUserDriveChart from './charts/per-user-drive';
+import ApRequestChart from './charts/ap-request';
 
 export const federationChart = new FederationChart();
 export const notesChart = new NotesChart();
 export const usersChart = new UsersChart();
-export const networkChart = new NetworkChart();
 export const activeUsersChart = new ActiveUsersChart();
 export const instanceChart = new InstanceChart();
 export const perUserNotesChart = new PerUserNotesChart();
@@ -25,12 +24,12 @@ export const perUserReactionsChart = new PerUserReactionsChart();
 export const hashtagChart = new HashtagChart();
 export const perUserFollowingChart = new PerUserFollowingChart();
 export const perUserDriveChart = new PerUserDriveChart();
+export const apRequestChart = new ApRequestChart();
 
 const charts = [
 	federationChart,
 	notesChart,
 	usersChart,
-	networkChart,
 	activeUsersChart,
 	instanceChart,
 	perUserNotesChart,
@@ -39,6 +38,7 @@ const charts = [
 	hashtagChart,
 	perUserFollowingChart,
 	perUserDriveChart,
+	apRequestChart,
 ];
 
 // 20分おきにメモリ情報をDBに書き込み
diff --git a/packages/backend/src/services/drive/add-file.ts b/packages/backend/src/services/drive/add-file.ts
index a89e068f45593349d3625e7d697505cf66d455d9..9a8a54390448e5a4da95b9deb882810efdd8e819 100644
--- a/packages/backend/src/services/drive/add-file.ts
+++ b/packages/backend/src/services/drive/add-file.ts
@@ -160,8 +160,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
 				webpublic: null,
 				thumbnail,
 			};
-		} catch (e) {
-			logger.warn(`GenerateVideoThumbnail failed: ${e}`);
+		} catch (err) {
+			logger.warn(`GenerateVideoThumbnail failed: ${err}`);
 			return {
 				webpublic: null,
 				thumbnail: null,
@@ -191,8 +191,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
 				thumbnail: null,
 			};
 		}
-	} catch (e) {
-		logger.warn(`sharp failed: ${e}`);
+	} catch (err) {
+		logger.warn(`sharp failed: ${err}`);
 		return {
 			webpublic: null,
 			thumbnail: null,
@@ -215,8 +215,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
 			} else {
 				logger.debug(`web image not created (not an required image)`);
 			}
-		} catch (e) {
-			logger.warn(`web image not created (an error occured)`, e);
+		} catch (err) {
+			logger.warn(`web image not created (an error occured)`, err as Error);
 		}
 	} else {
 		logger.info(`web image not created (from remote)`);
@@ -234,8 +234,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
 		} else {
 			logger.debug(`thumbnail not created (not an required file)`);
 		}
-	} catch (e) {
-		logger.warn(`thumbnail not created (an error occured)`, e);
+	} catch (err) {
+		logger.warn(`thumbnail not created (an error occured)`, err as Error);
 	}
 	// #endregion thumbnail
 
@@ -451,9 +451,9 @@ export async function addFile({
 			file.storedInternal = false;
 
 			file = await DriveFiles.insert(file).then(x => DriveFiles.findOneOrFail(x.identifiers[0]));
-		} catch (e) {
+		} catch (err) {
 			// duplicate key error (when already registered)
-			if (isDuplicateKeyValueError(e)) {
+			if (isDuplicateKeyValueError(err)) {
 				logger.info(`already registered ${file.uri}`);
 
 				file = await DriveFiles.findOne({
@@ -461,8 +461,8 @@ export async function addFile({
 					userId: user ? user.id : null,
 				}) as DriveFile;
 			} else {
-				logger.error(e);
-				throw e;
+				logger.error(err as Error);
+				throw err;
 			}
 		}
 	} else {
diff --git a/packages/backend/src/services/logger.ts b/packages/backend/src/services/logger.ts
index 626cc6b44cf2a7d643face25dd26c55fbed66a0f..1962088b639e8204a70ead8b37ff9dcb7fb03154 100644
--- a/packages/backend/src/services/logger.ts
+++ b/packages/backend/src/services/logger.ts
@@ -1,6 +1,6 @@
 import * as cluster from 'cluster';
 import * as chalk from 'chalk';
-import * as dateformat from 'dateformat';
+import { format as dateFormat } from 'date-fns';
 import { envOption } from '../env';
 import config from '@/config/index';
 
@@ -57,7 +57,7 @@ export default class Logger {
 			return;
 		}
 
-		const time = dateformat(new Date(), 'HH:MM:ss');
+		const time = dateFormat(new Date(), 'HH:mm:ss');
 		const worker = cluster.isPrimary ? '*' : cluster.worker.id;
 		const l =
 			level === 'error' ? important ? chalk.bgRed.white('ERR ') : chalk.red('ERR ') :
@@ -116,7 +116,7 @@ export default class Logger {
 	}
 
 	public debug(message: string, data?: Record<string, any> | null, important = false): void { // デバッグ用に使う(開発者に必要だが利用者に不要な情報)
-		if (process.env.NODE_ENV != 'production' || envOption.verbose) {
+		if (process.env.NODE_ENV !== 'production' || envOption.verbose) {
 			this.log('debug', message, data, important);
 		}
 	}
diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts
index fb22bd659396d749da06021d403053453215574b..7a4c2cef12c9b2856f8af9312d283e358d9f306d 100644
--- a/packages/backend/src/services/note/create.ts
+++ b/packages/backend/src/services/note/create.ts
@@ -59,7 +59,7 @@ class NotificationManager {
 
 		if (exist) {
 			// 「メンションされているかつ返信されている」場合は、メンションとしての通知ではなく返信としての通知にする
-			if (reason != 'mention') {
+			if (reason !== 'mention') {
 				exist.reason = reason;
 			}
 		} else {
@@ -111,7 +111,7 @@ type Option = {
 	app?: App | null;
 };
 
-export default async (user: { id: User['id']; username: User['username']; host: User['host']; isSilenced: User['isSilenced']; }, data: Option, silent = false) => new Promise<Note>(async (res, rej) => {
+export default async (user: { id: User['id']; username: User['username']; host: User['host']; isSilenced: User['isSilenced']; createdAt: User['createdAt']; }, data: Option, silent = false) => new Promise<Note>(async (res, rej) => {
 	// チャンネル外にリプライしたら対象のスコープに合わせる
 	// (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで)
 	if (data.reply && data.channel && data.reply.channelId !== data.channel.id) {
@@ -201,7 +201,7 @@ export default async (user: { id: User['id']; username: User['username']; host:
 		mentionedUsers.push(await Users.findOneOrFail(data.reply.userId));
 	}
 
-	if (data.visibility == 'specified') {
+	if (data.visibility === 'specified') {
 		if (data.visibleUsers == null) throw new Error('invalid param');
 
 		for (const u of data.visibleUsers) {
@@ -297,11 +297,10 @@ export default async (user: { id: User['id']; username: User['username']; host:
 	}
 
 	if (!silent) {
-		// ローカルユーザーのチャートはタイムライン取得時に更新しているのでリモートユーザーの場合だけでよい
-		if (Users.isRemoteUser(user)) activeUsersChart.update(user);
+		if (Users.isLocalUser(user)) activeUsersChart.write(user);
 
 		// 未読通知を作成
-		if (data.visibility == 'specified') {
+		if (data.visibility === 'specified') {
 			if (data.visibleUsers == null) throw new Error('invalid param');
 
 			for (const u of data.visibleUsers) {
@@ -439,7 +438,7 @@ export default async (user: { id: User['id']; username: User['username']; host:
 async function renderNoteOrRenoteActivity(data: Option, note: Note) {
 	if (data.localOnly) return null;
 
-	const content = data.renote && data.text == null && data.poll == null && (data.files == null || data.files.length == 0)
+	const content = data.renote && data.text == null && data.poll == null && (data.files == null || data.files.length === 0)
 		? renderAnnounce(data.renote.uri ? data.renote.uri : `${config.url}/notes/${data.renote.id}`, note)
 		: renderCreate(await renderNote(note, false), note);
 
@@ -478,7 +477,7 @@ async function insertNote(user: { id: User['id']; host: User['host']; }, data: O
 		userId: user.id,
 		localOnly: data.localOnly!,
 		visibility: data.visibility as any,
-		visibleUserIds: data.visibility == 'specified'
+		visibleUserIds: data.visibility === 'specified'
 			? data.visibleUsers
 				? data.visibleUsers.map(u => u.id)
 				: []
@@ -502,7 +501,7 @@ async function insertNote(user: { id: User['id']; host: User['host']; }, data: O
 		insert.mentions = mentionedUsers.map(u => u.id);
 		const profiles = await UserProfiles.find({ userId: In(insert.mentions) });
 		insert.mentionedRemoteUsers = JSON.stringify(mentionedUsers.filter(u => Users.isRemoteUser(u)).map(u => {
-			const profile = profiles.find(p => p.userId == u.id);
+			const profile = profiles.find(p => p.userId === u.id);
 			const url = profile != null ? profile.url : null;
 			return {
 				uri: u.uri,
diff --git a/packages/backend/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts
index 64383ee92838cfdafe50c35162bc2058965bc0a6..77723fe8b791d09f069f77b0eb2e2960720df398 100644
--- a/packages/backend/src/services/note/delete.ts
+++ b/packages/backend/src/services/note/delete.ts
@@ -39,7 +39,7 @@ export default async function(user: User, note: Note, quiet = false) {
 			let renote: Note | undefined;
 
 			// if deletd note is renote
-			if (note.renoteId && note.text == null && !note.hasPoll && (note.fileIds == null || note.fileIds.length == 0)) {
+			if (note.renoteId && note.text == null && !note.hasPoll && (note.fileIds == null || note.fileIds.length === 0)) {
 				renote = await Notes.findOne({
 					id: note.renoteId,
 				});
diff --git a/packages/backend/src/services/note/reaction/create.ts b/packages/backend/src/services/note/reaction/create.ts
index 47f46419ddbbe9968bed90dabeaa3746202b289c..c01d43c22117c474bb8281cd62281a30f354a1c0 100644
--- a/packages/backend/src/services/note/reaction/create.ts
+++ b/packages/backend/src/services/note/reaction/create.ts
@@ -76,7 +76,7 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
 	// カスタム絵文字リアクションだったら絵文字情報も送る
 	const decodedReaction = decodeReaction(reaction);
 
-	let emoji = await Emojis.findOne({
+	const emoji = await Emojis.findOne({
 		where: {
 			name: decodedReaction.name,
 			host: decodedReaction.host,
diff --git a/packages/backend/src/services/note/read.ts b/packages/backend/src/services/note/read.ts
index aaf1c5ed7148dafb63366bafee030ac0105b719d..032f1e84e604bffa9753b694cfa5bb5125421c19 100644
--- a/packages/backend/src/services/note/read.ts
+++ b/packages/backend/src/services/note/read.ts
@@ -52,7 +52,7 @@ export default async function(
 
 		if (note.user != null) { // たぶんnullになることは無いはずだけど一応
 			for (const antenna of myAntennas) {
-				if (await checkHitAntenna(antenna, note, note.user as any, undefined, Array.from(following))) {
+				if (await checkHitAntenna(antenna, note, note.user, undefined, Array.from(following))) {
 					readAntennaNotes.push(note);
 				}
 			}
diff --git a/packages/backend/src/services/send-email.ts b/packages/backend/src/services/send-email.ts
index f5f36148f6db630cd291d079a6d7ef55141b9110..1fd406cb685e5d90d5a00a300d77c9d29735a90b 100644
--- a/packages/backend/src/services/send-email.ts
+++ b/packages/backend/src/services/send-email.ts
@@ -114,9 +114,9 @@ export async function sendEmail(to: string, subject: string, html: string, text:
 </html>`,
 		});
 
-		logger.info('Message sent: %s', info.messageId);
-	} catch (e) {
-		logger.error(e);
-		throw e;
+		logger.info(`Message sent: ${info.messageId}`);
+	} catch (err) {
+		logger.error(err as Error);
+		throw err;
 	}
 }
diff --git a/packages/backend/test/chart.ts b/packages/backend/test/chart.ts
index 66000bc9285fd873bc22b1a518712e2a38925e21..bd8d4c8171046d0959dcba181eae945755508313 100644
--- a/packages/backend/test/chart.ts
+++ b/packages/backend/test/chart.ts
@@ -6,14 +6,17 @@ import { async, initTestDb } from './utils';
 import TestChart from '../src/services/chart/charts/test';
 import TestGroupedChart from '../src/services/chart/charts/test-grouped';
 import TestUniqueChart from '../src/services/chart/charts/test-unique';
+import TestIntersectionChart from '../src/services/chart/charts/test-intersection';
 import * as _TestChart from '../src/services/chart/charts/entities/test';
 import * as _TestGroupedChart from '../src/services/chart/charts/entities/test-grouped';
 import * as _TestUniqueChart from '../src/services/chart/charts/entities/test-unique';
+import * as _TestIntersectionChart from '../src/services/chart/charts/entities/test-intersection';
 
 describe('Chart', () => {
 	let testChart: TestChart;
 	let testGroupedChart: TestGroupedChart;
 	let testUniqueChart: TestUniqueChart;
+	let testIntersectionChart: TestIntersectionChart;
 	let clock: lolex.Clock;
 
 	beforeEach(async(async () => {
@@ -21,11 +24,13 @@ describe('Chart', () => {
 			_TestChart.entity.hour, _TestChart.entity.day,
 			_TestGroupedChart.entity.hour, _TestGroupedChart.entity.day,
 			_TestUniqueChart.entity.hour, _TestUniqueChart.entity.day,
+			_TestIntersectionChart.entity.hour, _TestIntersectionChart.entity.day,
 		]);
 
 		testChart = new TestChart();
 		testGroupedChart = new TestGroupedChart();
 		testUniqueChart = new TestUniqueChart();
+		testIntersectionChart = new TestIntersectionChart();
 
 		clock = lolex.install({
 			now: new Date(Date.UTC(2000, 0, 1, 0, 0, 0))
@@ -426,6 +431,53 @@ describe('Chart', () => {
 				foo: [2, 0, 0],
 			});
 		}));
+
+		describe('Intersection', () => {
+			it('条件が満たされていない場合はカウントされない', async(async () => {
+				await testIntersectionChart.addA('alice');
+				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],
+					aAndB: [0, 0, 0],
+				});
+			}));
+
+			it('条件が満たされている場合にカウントされる', async(async () => {
+				await testIntersectionChart.addA('alice');
+				await testIntersectionChart.addA('bob');
+				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],
+					aAndB: [1, 0, 0],
+				});
+			}));
+		});
 	});
 
 	describe('Resync', () => {
diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json
index 3311e117de8a3307aab872b2e325bba85030513b..f3252b2860036449dc024a707caa547e7dcfe23c 100644
--- a/packages/backend/tsconfig.json
+++ b/packages/backend/tsconfig.json
@@ -30,7 +30,7 @@
 		"outDir": "./built",
 		"typeRoots": [
 			"./node_modules/@types",
-			"./@types"
+			"./src/@types"
 		],
 		"lib": [
 			"esnext"
diff --git a/packages/backend/yarn.lock b/packages/backend/yarn.lock
index 5bf6e05a71986b063ca72b1db51620fbce82805b..c4afef8b5c416392b3afe60b971c55242e642da3 100644
--- a/packages/backend/yarn.lock
+++ b/packages/backend/yarn.lock
@@ -238,9 +238,9 @@
   integrity sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ==
 
 "@sindresorhus/is@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4"
-  integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ==
+  version "4.4.0"
+  resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.4.0.tgz#e277e5bdbdf7cb1e20d320f02f5e2ed113cd3185"
+  integrity sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==
 
 "@sinonjs/commons@^1.7.0":
   version "1.7.2"
@@ -249,10 +249,10 @@
   dependencies:
     type-detect "4.0.8"
 
-"@sinonjs/fake-timers@7.1.2":
-  version "7.1.2"
-  resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5"
-  integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==
+"@sinonjs/fake-timers@9.1.0":
+  version "9.1.0"
+  resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.0.tgz#8c92c56f195e0bed4c893ba59c8e3d55831ca0df"
+  integrity sha512-M8vapsv9qQupMdzrVzkn5rb9jG7aUTEPAZdMtME2PuBaefksFZVE2C1g4LBRTkF/k3nRDNbDc5tp5NFC1PEYxA==
   dependencies:
     "@sinonjs/commons" "^1.7.0"
 
@@ -289,6 +289,11 @@
   resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
   integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
 
+"@tootallnate/once@2":
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
+  integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
+
 "@tsconfig/node10@^1.0.7":
   version "1.0.7"
   resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.7.tgz#1eb1de36c73478a2479cc661ef5af1c16d86d606"
@@ -316,11 +321,6 @@
   dependencies:
     "@types/node" "*"
 
-"@types/anymatch@*":
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a"
-  integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==
-
 "@types/bcryptjs@2.4.2":
   version "2.4.2"
   resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-2.4.2.tgz#e3530eac9dd136bfdfb0e43df2c4c5ce1f77dfae"
@@ -386,11 +386,6 @@
     "@types/keygrip" "*"
     "@types/node" "*"
 
-"@types/dateformat@3.0.1":
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
-  integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
-
 "@types/disposable-email-domains@^1.0.1":
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/@types/disposable-email-domains/-/disposable-email-domains-1.0.2.tgz#0280f6b38fa7f14e54b056a434135ecd254483b1"
@@ -401,27 +396,6 @@
   resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.1.tgz#f1a977ccdf2ef059e9862bd3af5e92cbbe723e0e"
   integrity sha512-ogj/ZTIdeFkiuxDwawYuZSIgC6suFGgBeZPr6Xs5lHEcvIXTjXGtH+/n8f1XhZhespaUwJ5LIGRICPji972FLw==
 
-"@types/eslint-scope@^3.7.0":
-  version "3.7.0"
-  resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86"
-  integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==
-  dependencies:
-    "@types/eslint" "*"
-    "@types/estree" "*"
-
-"@types/eslint@*":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.0.tgz#eb5c5b575237334df24c53195e37b53d66478d7b"
-  integrity sha512-LpUXkr7fnmPXWGxB0ZuLEzNeTURuHPavkC5zuU4sg62/TgL5ZEjamr5Y8b6AftwHtx2bPJasI+CL0TT2JwQ7aA==
-  dependencies:
-    "@types/estree" "*"
-    "@types/json-schema" "*"
-
-"@types/estree@*", "@types/estree@^0.0.46":
-  version "0.0.46"
-  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.46.tgz#0fb6bfbbeabd7a30880504993369c4bf1deab1fe"
-  integrity sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==
-
 "@types/express-serve-static-core@*":
   version "4.17.5"
   resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.5.tgz#a00ac7dadd746ae82477443e4d480a6a93ea083c"
@@ -496,11 +470,6 @@
     "@types/parse5" "*"
     "@types/tough-cookie" "*"
 
-"@types/json-schema@*":
-  version "7.0.5"
-  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
-  integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
-
 "@types/json-schema@^7.0.6":
   version "7.0.6"
   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
@@ -665,10 +634,10 @@
   resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.2.tgz#331b7b9f8621c638284787c5559423822fdffc50"
   integrity sha512-LSw8TZt12ZudbpHc6EkIyDM3nHVWKYrAvGy6EAJfNfjusbwnThqjqxUKKRwuV3iWYeW/LYMzNgaq3MaLffQ2xA==
 
-"@types/node@17.0.10":
-  version "17.0.10"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.10.tgz#616f16e9d3a2a3d618136b1be244315d95bd7cab"
-  integrity sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog==
+"@types/node@17.0.14":
+  version "17.0.14"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.14.tgz#33b9b94f789a8fedd30a68efdbca4dbb06b61f20"
+  integrity sha512-SbjLmERksKOGzWzPNuW7fJM7fk3YXVTFiZWB/Hs99gwhk+/dnrQRPBQjPW9aO+fi1tAffi9PrwFvsmOKmDTyng==
 
 "@types/node@^14.11.8":
   version "14.17.9"
@@ -770,13 +739,6 @@
   resolved "https://registry.yarnpkg.com/@types/rename/-/rename-1.0.4.tgz#30c6f0306042591a560361ea02639e89647dd173"
   integrity sha512-eV81+6bVv2mdCBahkMefjEUwAjKDAP3AuyhqWCWRxcRaeVdUeHUBaoq2zSz+5HNHF2jzTajMcfLvJsy4K3cbwA==
 
-"@types/request-stats@3.0.0":
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/@types/request-stats/-/request-stats-3.0.0.tgz#d3909a9f778b8ae0b42fb8c1ed20cb936ed95f99"
-  integrity sha512-POsDF7nETH8up49iBNvbZuO0pEk9F+TG0rXCkvjxCClcOS99xfF+mKmJteYlwKYpuRKkixzysKlL8rwN1hU2lw==
-  dependencies:
-    "@types/node" "*"
-
 "@types/responselike@*", "@types/responselike@^1.0.0":
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
@@ -791,10 +753,10 @@
   dependencies:
     htmlparser2 "^6.0.0"
 
-"@types/seedrandom@2.4.28":
-  version "2.4.28"
-  resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.28.tgz#9ce8fa048c1e8c85cb71d7fe4d704e000226036f"
-  integrity sha512-SMA+fUwULwK7sd/ZJicUztiPs8F1yCPwF3O23Z9uQ32ME5Ha0NmDK9+QTsYE4O2tHXChzXomSWWeIhCnoN1LqA==
+"@types/seedrandom@3.0.1":
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-3.0.1.tgz#1254750a4fec4aff2ebec088ccd0bb02e91fedb4"
+  integrity sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw==
 
 "@types/serve-static@*":
   version "1.13.3"
@@ -811,15 +773,10 @@
   dependencies:
     "@types/node" "*"
 
-"@types/sinonjs__fake-timers@6.0.4":
-  version "6.0.4"
-  resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz#0ecc1b9259b76598ef01942f547904ce61a6a77d"
-  integrity sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==
-
-"@types/source-list-map@*":
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
-  integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==
+"@types/sinonjs__fake-timers@8.1.1":
+  version "8.1.1"
+  resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3"
+  integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==
 
 "@types/speakeasy@2.0.7":
   version "2.0.7"
@@ -828,11 +785,6 @@
   dependencies:
     "@types/node" "*"
 
-"@types/tapable@^1":
-  version "1.0.7"
-  resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.7.tgz#545158342f949e8fd3bfd813224971ecddc3fac4"
-  integrity sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ==
-
 "@types/throttle-debounce@2.1.0":
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/@types/throttle-debounce/-/throttle-debounce-2.1.0.tgz#1c3df624bfc4b62f992d3012b84c56d41eab3776"
@@ -853,13 +805,6 @@
   resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d"
   integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==
 
-"@types/uglify-js@*":
-  version "3.9.0"
-  resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.9.0.tgz#4490a140ca82aa855ad68093829e7fd6ae94ea87"
-  integrity sha512-3ZcoyPYHVOCcLpnfZwD47KFLr8W/mpUcgjpf1M4Q78TMJIw7KMAHSjiCLJp1z3ZrBR9pTLbe191O0TldFK5zcw==
-  dependencies:
-    source-map "^0.6.1"
-
 "@types/uuid@8.3.4":
   version "8.3.4"
   resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc"
@@ -872,48 +817,10 @@
   dependencies:
     "@types/node" "*"
 
-"@types/webpack-sources@*":
-  version "0.1.7"
-  resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.7.tgz#0a330a9456113410c74a5d64180af0cbca007141"
-  integrity sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==
-  dependencies:
-    "@types/node" "*"
-    "@types/source-list-map" "*"
-    source-map "^0.6.1"
-
-"@types/webpack-stream@3.2.12":
-  version "3.2.12"
-  resolved "https://registry.yarnpkg.com/@types/webpack-stream/-/webpack-stream-3.2.12.tgz#cf13e64067a662a7acd8cd0524b3f64c86b0ecb6"
-  integrity sha512-znMUl4kKT0V0SwkUgRgwUNSAO7J5I/jdTCBNy3utkCsgMJ3IHp4FBTDwsQC+tfQ73TWeKIH05QNmbUYmeGThGw==
-  dependencies:
-    "@types/node" "*"
-    "@types/webpack" "^4"
-
-"@types/webpack@5.28.0":
-  version "5.28.0"
-  resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-5.28.0.tgz#78dde06212f038d77e54116cfe69e88ae9ed2c03"
-  integrity sha512-8cP0CzcxUiFuA9xGJkfeVpqmWTk9nx6CWwamRGCj95ph1SmlRRk9KlCZ6avhCbZd4L68LvYT6l1kpdEnQXrF8w==
-  dependencies:
-    "@types/node" "*"
-    tapable "^2.2.0"
-    webpack "^5"
-
-"@types/webpack@^4":
-  version "4.41.27"
-  resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.27.tgz#f47da488c8037e7f1b2dbf2714fbbacb61ec0ffc"
-  integrity sha512-wK/oi5gcHi72VMTbOaQ70VcDxSQ1uX8S2tukBK9ARuGXrYM/+u4ou73roc7trXDNmCxCoerE8zruQqX/wuHszA==
-  dependencies:
-    "@types/anymatch" "*"
-    "@types/node" "*"
-    "@types/tapable" "^1"
-    "@types/uglify-js" "*"
-    "@types/webpack-sources" "*"
-    source-map "^0.6.0"
-
-"@types/websocket@1.0.4":
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.4.tgz#1dc497280d8049a5450854dd698ee7e6ea9e60b8"
-  integrity sha512-qn1LkcFEKK8RPp459jkjzsfpbsx36BBt3oC3pITYtkoBw/aVX+EZFa5j3ThCRTNpLFvIMr5dSTD4RaMdilIOpA==
+"@types/websocket@1.0.5":
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.5.tgz#3fb80ed8e07f88e51961211cd3682a3a4a81569c"
+  integrity sha512-NbsqiNX9CnEfC1Z0Vf4mE1SgAJ07JnRYcNex7AJ9zAVzmiGHmjKFEk7O4TJIsgv2B1sLEb6owKFZrACwdYngsQ==
   dependencies:
     "@types/node" "*"
 
@@ -929,14 +836,14 @@
   resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71"
   integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg==
 
-"@typescript-eslint/eslint-plugin@5.10.0":
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.0.tgz#e90afea96dff8620892ad216b0e4ccdf8ee32d3a"
-  integrity sha512-XXVKnMsq2fuu9K2KsIxPUGqb6xAImz8MEChClbXmE3VbveFtBUU5bzM6IPVWqzyADIgdkS2Ws/6Xo7W2TeZWjQ==
+"@typescript-eslint/eslint-plugin@5.10.2":
+  version "5.10.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.2.tgz#f8c1d59fc37bd6d9d11c97267fdfe722c4777152"
+  integrity sha512-4W/9lLuE+v27O/oe7hXJKjNtBLnZE8tQAFpapdxwSVHqtmIoPB1gph3+ahNwVuNL37BX7YQHyGF9Xv6XCnIX2Q==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.10.0"
-    "@typescript-eslint/type-utils" "5.10.0"
-    "@typescript-eslint/utils" "5.10.0"
+    "@typescript-eslint/scope-manager" "5.10.2"
+    "@typescript-eslint/type-utils" "5.10.2"
+    "@typescript-eslint/utils" "5.10.2"
     debug "^4.3.2"
     functional-red-black-tree "^1.0.1"
     ignore "^5.1.8"
@@ -944,69 +851,69 @@
     semver "^7.3.5"
     tsutils "^3.21.0"
 
-"@typescript-eslint/parser@5.10.0":
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.0.tgz#8f59e036f5f1cffc178cacbd5ccdd02aeb96c91c"
-  integrity sha512-pJB2CCeHWtwOAeIxv8CHVGJhI5FNyJAIpx5Pt72YkK3QfEzt6qAlXZuyaBmyfOdM62qU0rbxJzNToPTVeJGrQw==
+"@typescript-eslint/parser@5.10.2":
+  version "5.10.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.2.tgz#b6076d27cc5499ce3f2c625f5ccde946ecb7db9a"
+  integrity sha512-JaNYGkaQVhP6HNF+lkdOr2cAs2wdSZBoalE22uYWq8IEv/OVH0RksSGydk+sW8cLoSeYmC+OHvRyv2i4AQ7Czg==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.10.0"
-    "@typescript-eslint/types" "5.10.0"
-    "@typescript-eslint/typescript-estree" "5.10.0"
+    "@typescript-eslint/scope-manager" "5.10.2"
+    "@typescript-eslint/types" "5.10.2"
+    "@typescript-eslint/typescript-estree" "5.10.2"
     debug "^4.3.2"
 
-"@typescript-eslint/scope-manager@5.10.0":
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.10.0.tgz#bb5d872e8b9e36203908595507fbc4d3105329cb"
-  integrity sha512-tgNgUgb4MhqK6DoKn3RBhyZ9aJga7EQrw+2/OiDk5hKf3pTVZWyqBi7ukP+Z0iEEDMF5FDa64LqODzlfE4O/Dg==
+"@typescript-eslint/scope-manager@5.10.2":
+  version "5.10.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.10.2.tgz#92c0bc935ec00f3d8638cdffb3d0e70c9b879639"
+  integrity sha512-39Tm6f4RoZoVUWBYr3ekS75TYgpr5Y+X0xLZxXqcZNDWZdJdYbKd3q2IR4V9y5NxxiPu/jxJ8XP7EgHiEQtFnw==
   dependencies:
-    "@typescript-eslint/types" "5.10.0"
-    "@typescript-eslint/visitor-keys" "5.10.0"
+    "@typescript-eslint/types" "5.10.2"
+    "@typescript-eslint/visitor-keys" "5.10.2"
 
-"@typescript-eslint/type-utils@5.10.0":
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.10.0.tgz#8524b9479c19c478347a7df216827e749e4a51e5"
-  integrity sha512-TzlyTmufJO5V886N+hTJBGIfnjQDQ32rJYxPaeiyWKdjsv2Ld5l8cbS7pxim4DeNs62fKzRSt8Q14Evs4JnZyQ==
+"@typescript-eslint/type-utils@5.10.2":
+  version "5.10.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.10.2.tgz#ad5acdf98a7d2ab030bea81f17da457519101ceb"
+  integrity sha512-uRKSvw/Ccs5FYEoXW04Z5VfzF2iiZcx8Fu7DGIB7RHozuP0VbKNzP1KfZkHBTM75pCpsWxIthEH1B33dmGBKHw==
   dependencies:
-    "@typescript-eslint/utils" "5.10.0"
+    "@typescript-eslint/utils" "5.10.2"
     debug "^4.3.2"
     tsutils "^3.21.0"
 
-"@typescript-eslint/types@5.10.0":
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.0.tgz#beb3cb345076f5b088afe996d57bcd1dfddaa75c"
-  integrity sha512-wUljCgkqHsMZbw60IbOqT/puLfyqqD5PquGiBo1u1IS3PLxdi3RDGlyf032IJyh+eQoGhz9kzhtZa+VC4eWTlQ==
+"@typescript-eslint/types@5.10.2":
+  version "5.10.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.2.tgz#604d15d795c4601fffba6ecb4587ff9fdec68ce8"
+  integrity sha512-Qfp0qk/5j2Rz3p3/WhWgu4S1JtMcPgFLnmAKAW061uXxKSa7VWKZsDXVaMXh2N60CX9h6YLaBoy9PJAfCOjk3w==
 
-"@typescript-eslint/typescript-estree@5.10.0":
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.0.tgz#4be24a3dea0f930bb1397c46187d0efdd955a224"
-  integrity sha512-x+7e5IqfwLwsxTdliHRtlIYkgdtYXzE0CkFeV6ytAqq431ZyxCFzNMNR5sr3WOlIG/ihVZr9K/y71VHTF/DUQA==
+"@typescript-eslint/typescript-estree@5.10.2":
+  version "5.10.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.2.tgz#810906056cd3ddcb35aa333fdbbef3713b0fe4a7"
+  integrity sha512-WHHw6a9vvZls6JkTgGljwCsMkv8wu8XU8WaYKeYhxhWXH/atZeiMW6uDFPLZOvzNOGmuSMvHtZKd6AuC8PrwKQ==
   dependencies:
-    "@typescript-eslint/types" "5.10.0"
-    "@typescript-eslint/visitor-keys" "5.10.0"
+    "@typescript-eslint/types" "5.10.2"
+    "@typescript-eslint/visitor-keys" "5.10.2"
     debug "^4.3.2"
     globby "^11.0.4"
     is-glob "^4.0.3"
     semver "^7.3.5"
     tsutils "^3.21.0"
 
-"@typescript-eslint/utils@5.10.0":
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.10.0.tgz#c3d152a85da77c400e37281355561c72fb1b5a65"
-  integrity sha512-IGYwlt1CVcFoE2ueW4/ioEwybR60RAdGeiJX/iDAw0t5w0wK3S7QncDwpmsM70nKgGTuVchEWB8lwZwHqPAWRg==
+"@typescript-eslint/utils@5.10.2":
+  version "5.10.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.10.2.tgz#1fcd37547c32c648ab11aea7173ec30060ee87a8"
+  integrity sha512-vuJaBeig1NnBRkf7q9tgMLREiYD7zsMrsN1DA3wcoMDvr3BTFiIpKjGiYZoKPllfEwN7spUjv7ZqD+JhbVjEPg==
   dependencies:
     "@types/json-schema" "^7.0.9"
-    "@typescript-eslint/scope-manager" "5.10.0"
-    "@typescript-eslint/types" "5.10.0"
-    "@typescript-eslint/typescript-estree" "5.10.0"
+    "@typescript-eslint/scope-manager" "5.10.2"
+    "@typescript-eslint/types" "5.10.2"
+    "@typescript-eslint/typescript-estree" "5.10.2"
     eslint-scope "^5.1.1"
     eslint-utils "^3.0.0"
 
-"@typescript-eslint/visitor-keys@5.10.0":
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.0.tgz#770215497ad67cd15a572b52089991d5dfe06281"
-  integrity sha512-GMxj0K1uyrFLPKASLmZzCuSddmjZVbVj3Ouy5QVuIGKZopxvOr24JsS7gruz6C3GExE01mublZ3mIBOaon9zuQ==
+"@typescript-eslint/visitor-keys@5.10.2":
+  version "5.10.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.2.tgz#fdbf272d8e61c045d865bd6c8b41bea73d222f3d"
+  integrity sha512-zHIhYGGGrFJvvyfwHk5M08C5B5K4bewkm+rrvNTKk1/S15YHR+SA/QUF8ZWscXSfEaB8Nn2puZj+iHcoxVOD/Q==
   dependencies:
-    "@typescript-eslint/types" "5.10.0"
+    "@typescript-eslint/types" "5.10.2"
     eslint-visitor-keys "^3.0.0"
 
 "@ungap/promise-all-settled@1.1.2":
@@ -1014,137 +921,6 @@
   resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
   integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
 
-"@webassemblyjs/ast@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.0.tgz#a5aa679efdc9e51707a4207139da57920555961f"
-  integrity sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==
-  dependencies:
-    "@webassemblyjs/helper-numbers" "1.11.0"
-    "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
-
-"@webassemblyjs/floating-point-hex-parser@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz#34d62052f453cd43101d72eab4966a022587947c"
-  integrity sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==
-
-"@webassemblyjs/helper-api-error@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz#aaea8fb3b923f4aaa9b512ff541b013ffb68d2d4"
-  integrity sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==
-
-"@webassemblyjs/helper-buffer@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz#d026c25d175e388a7dbda9694e91e743cbe9b642"
-  integrity sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==
-
-"@webassemblyjs/helper-numbers@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz#7ab04172d54e312cc6ea4286d7d9fa27c88cd4f9"
-  integrity sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==
-  dependencies:
-    "@webassemblyjs/floating-point-hex-parser" "1.11.0"
-    "@webassemblyjs/helper-api-error" "1.11.0"
-    "@xtuc/long" "4.2.2"
-
-"@webassemblyjs/helper-wasm-bytecode@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz#85fdcda4129902fe86f81abf7e7236953ec5a4e1"
-  integrity sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==
-
-"@webassemblyjs/helper-wasm-section@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz#9ce2cc89300262509c801b4af113d1ca25c1a75b"
-  integrity sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==
-  dependencies:
-    "@webassemblyjs/ast" "1.11.0"
-    "@webassemblyjs/helper-buffer" "1.11.0"
-    "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
-    "@webassemblyjs/wasm-gen" "1.11.0"
-
-"@webassemblyjs/ieee754@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz#46975d583f9828f5d094ac210e219441c4e6f5cf"
-  integrity sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==
-  dependencies:
-    "@xtuc/ieee754" "^1.2.0"
-
-"@webassemblyjs/leb128@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.0.tgz#f7353de1df38aa201cba9fb88b43f41f75ff403b"
-  integrity sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==
-  dependencies:
-    "@xtuc/long" "4.2.2"
-
-"@webassemblyjs/utf8@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.0.tgz#86e48f959cf49e0e5091f069a709b862f5a2cadf"
-  integrity sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==
-
-"@webassemblyjs/wasm-edit@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz#ee4a5c9f677046a210542ae63897094c2027cb78"
-  integrity sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==
-  dependencies:
-    "@webassemblyjs/ast" "1.11.0"
-    "@webassemblyjs/helper-buffer" "1.11.0"
-    "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
-    "@webassemblyjs/helper-wasm-section" "1.11.0"
-    "@webassemblyjs/wasm-gen" "1.11.0"
-    "@webassemblyjs/wasm-opt" "1.11.0"
-    "@webassemblyjs/wasm-parser" "1.11.0"
-    "@webassemblyjs/wast-printer" "1.11.0"
-
-"@webassemblyjs/wasm-gen@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz#3cdb35e70082d42a35166988dda64f24ceb97abe"
-  integrity sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==
-  dependencies:
-    "@webassemblyjs/ast" "1.11.0"
-    "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
-    "@webassemblyjs/ieee754" "1.11.0"
-    "@webassemblyjs/leb128" "1.11.0"
-    "@webassemblyjs/utf8" "1.11.0"
-
-"@webassemblyjs/wasm-opt@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz#1638ae188137f4bb031f568a413cd24d32f92978"
-  integrity sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==
-  dependencies:
-    "@webassemblyjs/ast" "1.11.0"
-    "@webassemblyjs/helper-buffer" "1.11.0"
-    "@webassemblyjs/wasm-gen" "1.11.0"
-    "@webassemblyjs/wasm-parser" "1.11.0"
-
-"@webassemblyjs/wasm-parser@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz#3e680b8830d5b13d1ec86cc42f38f3d4a7700754"
-  integrity sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==
-  dependencies:
-    "@webassemblyjs/ast" "1.11.0"
-    "@webassemblyjs/helper-api-error" "1.11.0"
-    "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
-    "@webassemblyjs/ieee754" "1.11.0"
-    "@webassemblyjs/leb128" "1.11.0"
-    "@webassemblyjs/utf8" "1.11.0"
-
-"@webassemblyjs/wast-printer@1.11.0":
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz#680d1f6a5365d6d401974a8e949e05474e1fab7e"
-  integrity sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==
-  dependencies:
-    "@webassemblyjs/ast" "1.11.0"
-    "@xtuc/long" "4.2.2"
-
-"@xtuc/ieee754@^1.2.0":
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
-  integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
-
-"@xtuc/long@4.2.2":
-  version "4.2.2"
-  resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
-  integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
-
 abab@^2.0.3, abab@^2.0.5:
   version "2.0.5"
   resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a"
@@ -1198,22 +974,12 @@ acorn@^7.1.1:
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
   integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
 
-acorn@^8.0.4:
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe"
-  integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA==
-
-acorn@^8.2.4:
-  version "8.2.4"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0"
-  integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==
-
 acorn@^8.4.1:
   version "8.4.1"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c"
   integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==
 
-acorn@^8.7.0:
+acorn@^8.5.0, acorn@^8.7.0:
   version "8.7.0"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
   integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
@@ -1476,10 +1242,10 @@ autwh@0.1.0:
   dependencies:
     oauth "0.9.15"
 
-aws-sdk@2.1061.0:
-  version "2.1061.0"
-  resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1061.0.tgz#79c75e6856e5a59e0857d0d066a8ff5ff5e0d752"
-  integrity sha512-T29yV+EPo4Fis9hAArxAXS/u6utKnlBq3DEu85LTSIA8i6e6Xg7e9u7Rveo8DmrlVrf7EGCNThaeF9WERHnwLg==
+aws-sdk@2.1067.0:
+  version "2.1067.0"
+  resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1067.0.tgz#2e7f5a2d765fcf77a45f25fdd1f12a64942628a7"
+  integrity sha512-3Ys1k4cNQy4z37IpPjQ9c5ldkXMeZGbWoarKHynPPY3WCEj+Nw2u6zk484fA9/lTHNN3YesLuZ0OmEzGgjFEOw==
   dependencies:
     buffer "4.9.2"
     events "1.1.1"
@@ -1638,17 +1404,6 @@ browser-stdout@1.3.1:
   resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
   integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
 
-browserslist@^4.14.5:
-  version "4.16.3"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717"
-  integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==
-  dependencies:
-    caniuse-lite "^1.0.30001181"
-    colorette "^1.2.1"
-    electron-to-chromium "^1.3.649"
-    escalade "^3.1.1"
-    node-releases "^1.1.70"
-
 buffer-crc32@^0.2.1, buffer-crc32@^0.2.13:
   version "0.2.13"
   resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@@ -1711,16 +1466,17 @@ bufferutil@^4.0.1:
   dependencies:
     node-gyp-build "~3.7.0"
 
-bull@4.2.1:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/bull/-/bull-4.2.1.tgz#c5a7e1496c7903274ce90192e4e5cb18f6c866c0"
-  integrity sha512-YkCQZMOub++siHw3SbYYXZ5xGEn6Tt3BPoCVq/irPNCxUqUYzta8yDlXyyAsfMKMVj0M7PcnynUabfMf9PFpOA==
+bull@4.5.0:
+  version "4.5.0"
+  resolved "https://registry.yarnpkg.com/bull/-/bull-4.5.0.tgz#d6106b011b711ffb76c687d7f2db416955225f64"
+  integrity sha512-BejJxGwNNQPIrK1jFTN74kymFORYQ6ZyXWNsZx+6jtDtafQNUMHNSdoepabLLmeldmUvgAHvZDDIJWFGEo2MYg==
   dependencies:
-    cron-parser "^2.13.0"
+    cron-parser "^4.2.1"
     debuglog "^1.0.0"
     get-port "^5.1.1"
     ioredis "^4.27.0"
     lodash "^4.17.21"
+    msgpackr "^1.5.2"
     p-timeout "^3.2.0"
     semver "^7.3.2"
     uuid "^8.3.0"
@@ -1821,11 +1577,6 @@ camelcase@^6.0.0:
   resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
   integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
 
-caniuse-lite@^1.0.30001181:
-  version "1.0.30001191"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001191.tgz#bacb432b6701f690c8c5f7c680166b9a9f0843d9"
-  integrity sha512-xJJqzyd+7GCJXkcoBiQ1GuxEiOBCLQ0aVW9HMekifZsAVGdj5eJ4mFB9fEhSHipq9IOk/QXFJUiIr9lZT+EsGw==
-
 canonicalize@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.1.tgz#657b4f3fa38a6ecb97a9e5b7b26d7a19cc6e0da9"
@@ -1945,13 +1696,6 @@ chownr@^2.0.0:
   resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
   integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
 
-chrome-trace-event@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4"
-  integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==
-  dependencies:
-    tslib "^1.9.0"
-
 clean-stack@^2.0.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
@@ -2053,10 +1797,10 @@ color-name@^1.0.0, color-name@~1.1.4:
   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
   integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
 
-color-string@^1.6.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312"
-  integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==
+color-string@^1.9.0:
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.0.tgz#63b6ebd1bec11999d1df3a79a7569451ac2be8aa"
+  integrity sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==
   dependencies:
     color-name "^1.0.0"
     simple-swizzle "^0.2.2"
@@ -2066,15 +1810,15 @@ color-support@^1.1.2:
   resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
   integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
 
-color@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/color/-/color-4.0.1.tgz#21df44cd10245a91b1ccf5ba031609b0e10e7d67"
-  integrity sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA==
+color@^4.2.0:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/color/-/color-4.2.0.tgz#0c782459a3e98838ea01e4bc0fb43310ca35af78"
+  integrity sha512-hHTcrbvEnGjC7WBMk6ibQWFVDgEFTVmjrz2Q5HlU6ltwxv0JJN2Z8I7uRbWeQLF04dikxs8zgyZkazRJvSMtyQ==
   dependencies:
     color-convert "^2.0.1"
-    color-string "^1.6.0"
+    color-string "^1.9.0"
 
-colorette@^1.2.0, colorette@^1.2.1:
+colorette@^1.2.0:
   version "1.2.2"
   resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
   integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
@@ -2086,7 +1830,7 @@ combined-stream@^1.0.8:
   dependencies:
     delayed-stream "~1.0.0"
 
-commander@^2.19.0, commander@^2.20.0:
+commander@^2.19.0:
   version "2.20.3"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -2195,7 +1939,15 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
   integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
 
-crc-32@1.2.0, crc-32@^1.2.0:
+crc-32@1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.1.tgz#436d2bcaad27bcb6bd073a2587139d3024a16460"
+  integrity sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==
+  dependencies:
+    exit-on-epipe "~1.0.1"
+    printj "~1.3.1"
+
+crc-32@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
   integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==
@@ -2216,13 +1968,12 @@ create-require@^1.1.0:
   resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
   integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
 
-cron-parser@^2.13.0:
-  version "2.13.0"
-  resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.13.0.tgz#6f930bb6f2931790d2a9eec83b3ec276e27a6725"
-  integrity sha512-UWeIpnRb0eyoWPVk+pD3TDpNx3KCFQeezO224oJIkktBrcW6RoAPOx5zIKprZGfk6vcYSmA8yQXItejSaDBhbQ==
+cron-parser@^4.2.1:
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-4.2.1.tgz#b43205d05ccd5c93b097dae64f3bd811f5993af3"
+  integrity sha512-5sJBwDYyCp+0vU5b7POl8zLWfgV5fOHxlc45FWoWdHecGC7MQHCjx0CHivCMRnGFovghKhhyYM+Zm9DcY5qcHg==
   dependencies:
-    is-nan "^1.2.1"
-    moment-timezone "^0.5.25"
+    luxon "^1.28.0"
 
 cross-env@7.0.3:
   version "7.0.3"
@@ -2255,10 +2006,10 @@ css-what@2.1:
   resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
   integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
 
-cssom@^0.4.4:
-  version "0.4.4"
-  resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
-  integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==
+cssom@^0.5.0:
+  version "0.5.0"
+  resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36"
+  integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==
 
 cssom@~0.3.6:
   version "0.3.8"
@@ -2297,19 +2048,19 @@ data-uri-to-buffer@^4.0.0:
   resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b"
   integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==
 
-data-urls@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
-  integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==
+data-urls@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.1.tgz#597fc2ae30f8bc4dbcf731fcd1b1954353afc6f8"
+  integrity sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw==
   dependencies:
     abab "^2.0.3"
-    whatwg-mimetype "^2.3.0"
-    whatwg-url "^8.0.0"
+    whatwg-mimetype "^3.0.0"
+    whatwg-url "^10.0.0"
 
-dateformat@4.5.1:
-  version "4.5.1"
-  resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.5.1.tgz#c20e7a9ca77d147906b6dc2261a8be0a5bd2173c"
-  integrity sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q==
+date-fns@2.28.0:
+  version "2.28.0"
+  resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2"
+  integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==
 
 debug@2, debug@^2.2.0, debug@^2.5.2, debug@^2.6.9:
   version "2.6.9"
@@ -2368,10 +2119,10 @@ decamelize@^4.0.0:
   resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
   integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
 
-decimal.js@^10.2.1:
-  version "10.2.1"
-  resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3"
-  integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==
+decimal.js@^10.3.1:
+  version "10.3.1"
+  resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783"
+  integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
 
 decompress-response@^6.0.0:
   version "6.0.0"
@@ -2462,10 +2213,10 @@ detect-file@^1.0.0:
   resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
   integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
 
-detect-libc@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
-  integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
+detect-libc@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.0.tgz#c528bc09bc6d1aa30149228240917c225448f204"
+  integrity sha512-S55LzUl8HUav8l9E2PBTlC5PAJrHK7tkM+XXFGD+fbsbkTzhCpG6K05LxJcUOEWzMa4v6ptcMZ9s3fOdJDu0Zw==
 
 detect-node@2.1.0, detect-node@^2.1.0:
   version "2.1.0"
@@ -2566,12 +2317,12 @@ domelementtype@^2.2.0:
   resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
   integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
 
-domexception@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
-  integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==
+domexception@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673"
+  integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==
   dependencies:
-    webidl-conversions "^5.0.0"
+    webidl-conversions "^7.0.0"
 
 domhandler@^2.3.0:
   version "2.4.2"
@@ -2661,11 +2412,6 @@ ee-first@1.1.1:
   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
   integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
 
-electron-to-chromium@^1.3.649:
-  version "1.3.672"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.672.tgz#3a6e335016dab4bc584d5292adc4f98f54541f6a"
-  integrity sha512-gFQe7HBb0lbOMqK2GAS5/1F+B0IMdYiAgB9OT/w1F4M7lgJK2aNOMNOM622aEax+nS1cTMytkiT0uMOkbtFmHw==
-
 emoji-regex@^8.0.0:
   version "8.0.0"
   resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
@@ -2708,14 +2454,6 @@ enhanced-resolve@^5.0.0:
     graceful-fs "^4.2.4"
     tapable "^2.2.0"
 
-enhanced-resolve@^5.7.0:
-  version "5.7.0"
-  resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz#525c5d856680fbd5052de453ac83e32049958b5c"
-  integrity sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==
-  dependencies:
-    graceful-fs "^4.2.4"
-    tapable "^2.2.0"
-
 entities@^1.1.1, entities@~1.1.1:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
@@ -2762,11 +2500,6 @@ es-abstract@^1.19.0, es-abstract@^1.19.1:
     string.prototype.trimstart "^1.0.4"
     unbox-primitive "^1.0.1"
 
-es-module-lexer@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.0.tgz#21f4181cc8b7eee06855f1c59e6087c7bc4f77b0"
-  integrity sha512-iuEGihqqhKWFgh72Q/Jtch7V2t/ft8w8IPP2aEN8ArYKO+IWyo6hsi96hCdgyeEDQIV3InhYQ9BlwUFPGXrbEQ==
-
 es-to-primitive@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
@@ -2912,10 +2645,10 @@ eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.2.0:
   resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1"
   integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==
 
-eslint@8.7.0:
-  version "8.7.0"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.7.0.tgz#22e036842ee5b7cf87b03fe237731675b4d3633c"
-  integrity sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==
+eslint@8.8.0:
+  version "8.8.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.8.0.tgz#9762b49abad0cb4952539ffdb0a046392e571a2d"
+  integrity sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==
   dependencies:
     "@eslint/eslintrc" "^1.0.5"
     "@humanwhocodes/config-array" "^0.9.2"
@@ -3021,11 +2754,6 @@ events@1.1.1:
   resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
   integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=
 
-events@^3.2.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379"
-  integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==
-
 execa@6.0.0:
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/execa/-/execa-6.0.0.tgz#598b46f09ae44f5d8097a30cfb1681d0f0371503"
@@ -3241,10 +2969,10 @@ follow-redirects@^1.14.4:
   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
   integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
 
-form-data@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
-  integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==
+form-data@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
+  integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
   dependencies:
     asynckit "^0.4.0"
     combined-stream "^1.0.8"
@@ -3419,11 +3147,6 @@ glob-parent@^6.0.1:
   dependencies:
     is-glob "^4.0.3"
 
-glob-to-regexp@^0.4.1:
-  version "0.4.1"
-  resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
-  integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
-
 glob@7.1.6, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
   version "7.1.6"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
@@ -3619,12 +3342,12 @@ hpagent@^0.1.1:
   resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-0.1.1.tgz#66f67f16e5c7a8b59a068e40c2658c2c749ad5e2"
   integrity sha512-IxJWQiY0vmEjetHdoE9HZjD4Cx+mYTr25tR7JCxXaiI3QxW0YqYyM11KyZbHufoa/piWhMb2+D3FGpMgmA2cFQ==
 
-html-encoding-sniffer@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
-  integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==
+html-encoding-sniffer@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9"
+  integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==
   dependencies:
-    whatwg-encoding "^1.0.5"
+    whatwg-encoding "^2.0.0"
 
 html-entities@2.3.2:
   version "2.3.2"
@@ -3687,13 +3410,6 @@ http-errors@~1.6.2:
     setprototypeof "1.1.0"
     statuses ">= 1.4.0 < 2"
 
-http-headers@^3.0.1:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/http-headers/-/http-headers-3.0.2.tgz#5147771292f0b39d6778d930a3a59a76fc7ef44d"
-  integrity sha512-87E1I+2Wg4dxxz4rcxElo3dxO/w1ZtgL1yA0Sb6vH3qU16vRKq1NjWQv9SCY3ly2OQROcoxHZOUpmelS+k6wOw==
-  dependencies:
-    next-line "^1.1.0"
-
 http-proxy-agent@^4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
@@ -3703,6 +3419,15 @@ http-proxy-agent@^4.0.1:
     agent-base "6"
     debug "4"
 
+http-proxy-agent@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43"
+  integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==
+  dependencies:
+    "@tootallnate/once" "2"
+    agent-base "6"
+    debug "4"
+
 http-signature@1.3.6:
   version "1.3.6"
   resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9"
@@ -3712,7 +3437,7 @@ http-signature@1.3.6:
     jsprim "^2.0.2"
     sshpk "^1.14.1"
 
-http2-wrapper@^1.0.0-beta.5.0:
+http2-wrapper@^1.0.0-beta.5.0, http2-wrapper@^1.0.0-beta.5.2:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
   integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
@@ -3720,14 +3445,6 @@ http2-wrapper@^1.0.0-beta.5.0:
     quick-lru "^5.1.1"
     resolve-alpn "^1.0.0"
 
-http2-wrapper@^1.0.0-beta.5.2:
-  version "1.0.0-beta.5.2"
-  resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz#8b923deb90144aea65cf834b016a340fc98556f3"
-  integrity sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==
-  dependencies:
-    quick-lru "^5.1.1"
-    resolve-alpn "^1.0.0"
-
 http_ece@1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/http_ece/-/http_ece-1.1.0.tgz#74780c6eb32d8ddfe9e36a83abcd81fe0cd4fb75"
@@ -3767,6 +3484,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.4:
   dependencies:
     safer-buffer ">= 2.1.2 < 3"
 
+iconv-lite@0.6.3:
+  version "0.6.3"
+  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
+  integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
+  dependencies:
+    safer-buffer ">= 2.1.2 < 3.0.0"
+
 iconv-lite@^0.6.2:
   version "0.6.2"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01"
@@ -4043,13 +3767,6 @@ is-lambda@^1.0.1:
   resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5"
   integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=
 
-is-nan@^1.2.1:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.0.tgz#85d1f5482f7051c2019f5673ccebdb06f3b0db03"
-  integrity sha512-z7bbREymOqt2CCaZVly8aC4ML3Xhfi0ekuOnjO2L8vKdl+CttdVoGZQhd4adMFAsxQ5VeRVwORs4tU8RH+HFtQ==
-  dependencies:
-    define-properties "^1.1.3"
-
 is-negative-zero@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
@@ -4184,15 +3901,6 @@ isexe@^2.0.0:
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
   integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
 
-jest-worker@^26.6.2:
-  version "26.6.2"
-  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed"
-  integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==
-  dependencies:
-    "@types/node" "*"
-    merge-stream "^2.0.0"
-    supports-color "^7.0.0"
-
 jmespath@0.16.0:
   version "0.16.0"
   resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076"
@@ -4253,23 +3961,23 @@ jschardet@3.0.0:
   resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882"
   integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ==
 
-jsdom@16.7.0:
-  version "16.7.0"
-  resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
-  integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==
+jsdom@19.0.0:
+  version "19.0.0"
+  resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-19.0.0.tgz#93e67c149fe26816d38a849ea30ac93677e16b6a"
+  integrity sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==
   dependencies:
     abab "^2.0.5"
-    acorn "^8.2.4"
+    acorn "^8.5.0"
     acorn-globals "^6.0.0"
-    cssom "^0.4.4"
+    cssom "^0.5.0"
     cssstyle "^2.3.0"
-    data-urls "^2.0.0"
-    decimal.js "^10.2.1"
-    domexception "^2.0.1"
+    data-urls "^3.0.1"
+    decimal.js "^10.3.1"
+    domexception "^4.0.0"
     escodegen "^2.0.0"
-    form-data "^3.0.0"
-    html-encoding-sniffer "^2.0.1"
-    http-proxy-agent "^4.0.1"
+    form-data "^4.0.0"
+    html-encoding-sniffer "^3.0.0"
+    http-proxy-agent "^5.0.0"
     https-proxy-agent "^5.0.0"
     is-potential-custom-element-name "^1.0.1"
     nwsapi "^2.2.0"
@@ -4278,24 +3986,19 @@ jsdom@16.7.0:
     symbol-tree "^3.2.4"
     tough-cookie "^4.0.0"
     w3c-hr-time "^1.0.2"
-    w3c-xmlserializer "^2.0.0"
-    webidl-conversions "^6.1.0"
-    whatwg-encoding "^1.0.5"
-    whatwg-mimetype "^2.3.0"
-    whatwg-url "^8.5.0"
-    ws "^7.4.6"
-    xml-name-validator "^3.0.0"
+    w3c-xmlserializer "^3.0.0"
+    webidl-conversions "^7.0.0"
+    whatwg-encoding "^2.0.0"
+    whatwg-mimetype "^3.0.0"
+    whatwg-url "^10.0.0"
+    ws "^8.2.3"
+    xml-name-validator "^4.0.0"
 
 json-buffer@3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
   integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
 
-json-parse-better-errors@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
-  integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
-
 json-schema-traverse@^0.4.1:
   version "0.4.1"
   resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
@@ -4610,11 +4313,6 @@ listenercount@~1.0.1:
   resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937"
   integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=
 
-loader-runner@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
-  integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
-
 loader-utils@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
@@ -4731,17 +4429,12 @@ lodash.some@^4.4.0:
   resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
   integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=
 
-lodash.sortby@^4.7.0:
-  version "4.7.0"
-  resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
-  integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
-
 lodash.union@^4.6.0:
   version "4.6.0"
   resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
   integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=
 
-lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
+lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21:
   version "4.17.21"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
   integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -4773,6 +4466,11 @@ lru-cache@^6.0.0:
   dependencies:
     yallist "^4.0.0"
 
+luxon@^1.28.0:
+  version "1.28.0"
+  resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf"
+  integrity sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==
+
 mailcheck@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/mailcheck/-/mailcheck-1.1.1.tgz#d87cf6ba0b64ba512199dbf93f1489f479591e34"
@@ -4867,7 +4565,7 @@ mime-types@2.1.34:
   dependencies:
     mime-db "1.51.0"
 
-mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.27, mime-types@~2.1.24:
+mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.24:
   version "2.1.27"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
   integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
@@ -5029,14 +4727,7 @@ mocha@8.4.0:
     yargs-parser "20.2.4"
     yargs-unparser "2.0.0"
 
-moment-timezone@^0.5.25:
-  version "0.5.28"
-  resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.28.tgz#f093d789d091ed7b055d82aa81a82467f72e4338"
-  integrity sha512-TDJkZvAyKIVWg5EtVqRzU97w0Rb0YVbfpqyjgu6GwXCAohVRqwZjf4fOzDE6p1Ch98Sro/8hQQi65WDXW5STPw==
-  dependencies:
-    moment ">= 2.9.0"
-
-"moment@>= 2.9.0", moment@^2.22.2:
+moment@^2.22.2:
   version "2.24.0"
   resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
   integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
@@ -5061,6 +4752,21 @@ ms@3.0.0-canary.1:
   resolved "https://registry.yarnpkg.com/ms/-/ms-3.0.0-canary.1.tgz#c7b34fbce381492fd0b345d1cf56e14d67b77b80"
   integrity sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==
 
+msgpackr-extract@^1.0.14:
+  version "1.0.16"
+  resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-1.0.16.tgz#701c4f6e6f25c100ae84557092274e8fffeefe45"
+  integrity sha512-fxdRfQUxPrL/TizyfYfMn09dK58e+d65bRD/fcaVH4052vj30QOzzqxcQIS7B0NsqlypEQ/6Du3QmP2DhWFfCA==
+  dependencies:
+    nan "^2.14.2"
+    node-gyp-build "^4.2.3"
+
+msgpackr@^1.5.2:
+  version "1.5.4"
+  resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.5.4.tgz#2b6ea6cb7d79c0ad98fc76c68163c48eda50cf0d"
+  integrity sha512-Z7w5Jg+2Q9z9gJxeM68d7tSuWZZGnFIRhZnyqcZCa/1dKkhOCNvR1TUV3zzJ3+vj78vlwKRzUgVDlW4jiSOeDA==
+  optionalDependencies:
+    msgpackr-extract "^1.0.14"
+
 multer@1.4.4:
   version "1.4.4"
   resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.4.tgz#e2bc6cac0df57a8832b858d7418ccaa8ebaf7d8c"
@@ -5089,7 +4795,7 @@ mz@^2.4.0, mz@^2.7.0:
     object-assign "^4.0.1"
     thenify-all "^1.0.0"
 
-nan@^2.15.0:
+nan@^2.14.2, nan@^2.15.0:
   version "2.15.0"
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
   integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
@@ -5135,11 +4841,6 @@ negotiator@0.6.2, negotiator@^0.6.2:
   resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
   integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
 
-neo-async@^2.6.2:
-  version "2.6.2"
-  resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
-  integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
-
 nested-property@4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/nested-property/-/nested-property-4.0.0.tgz#a67b5a31991e701e03cdbaa6453bc5b1011bb88d"
@@ -5150,11 +4851,6 @@ netmask@^2.0.2:
   resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
   integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
 
-next-line@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/next-line/-/next-line-1.1.0.tgz#fcae57853052b6a9bae8208e40dd7d3c2d304603"
-  integrity sha1-/K5XhTBStqm66CCOQN19PC0wRgM=
-
 next-tick@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
@@ -5167,10 +4863,10 @@ node-abi@^3.3.0:
   dependencies:
     semver "^7.3.5"
 
-node-addon-api@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.2.0.tgz#117cbb5a959dff0992e1c586ae0393573e4d2a87"
-  integrity sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q==
+node-addon-api@^4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f"
+  integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==
 
 node-domexception@^1.0.0:
   version "1.0.0"
@@ -5199,6 +4895,11 @@ node-fetch@3.0.0-beta.9:
     data-uri-to-buffer "^3.0.1"
     fetch-blob "^2.1.1"
 
+node-gyp-build@^4.2.3:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3"
+  integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==
+
 node-gyp-build@~3.7.0:
   version "3.7.0"
   resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d"
@@ -5220,11 +4921,6 @@ node-gyp@^8.4.1:
     tar "^6.1.2"
     which "^2.0.2"
 
-node-releases@^1.1.70:
-  version "1.1.71"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb"
-  integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==
-
 nodemailer@6.7.2:
   version "6.7.2"
   resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.2.tgz#44b2ad5f7ed71b7067f7a21c4fedabaec62b85e0"
@@ -5464,13 +5160,6 @@ p-limit@^3.0.2:
   dependencies:
     p-try "^2.0.0"
 
-p-limit@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
-  integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
-  dependencies:
-    yocto-queue "^0.1.0"
-
 p-locate@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
@@ -5743,12 +5432,12 @@ postgres-interval@^1.1.0:
   dependencies:
     xtend "^4.0.0"
 
-prebuild-install@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.0.tgz#3c5ce3902f1cb9d6de5ae94ca53575e4af0c1574"
-  integrity sha512-IvSenf33K7JcgddNz2D5w521EgO+4aMMjFt73Uk9FRzQ7P+QZPKrp7qPsDydsSwjGt3T5xRNnM1bj1zMTD5fTA==
+prebuild-install@^7.0.1:
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.1.tgz#c10075727c318efe72412f333e0ef625beaf3870"
+  integrity sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg==
   dependencies:
-    detect-libc "^1.0.3"
+    detect-libc "^2.0.0"
     expand-template "^2.0.3"
     github-from-package "0.0.0"
     minimist "^1.2.3"
@@ -5786,6 +5475,11 @@ printj@~1.1.0:
   resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
   integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
 
+printj@~1.3.1:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/printj/-/printj-1.3.1.tgz#9af6b1d55647a1587ac44f4c1654a4b95b8e12cb"
+  integrity sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==
+
 private-ip@2.3.3:
   version "2.3.3"
   resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.3.3.tgz#1e80ff8443e5ac78f555631aec3ea6ff027fa6aa"
@@ -5796,10 +5490,10 @@ private-ip@2.3.3:
     is-ip "^3.1.0"
     netmask "^2.0.2"
 
-probe-image-size@7.2.2:
-  version "7.2.2"
-  resolved "https://registry.yarnpkg.com/probe-image-size/-/probe-image-size-7.2.2.tgz#e5851b9be7864f21e3bac5e6e4fac9da9055b412"
-  integrity sha512-QUm+w1S9WTsT5GZB830u0BHExrUmF0J4fyRm5kbLUMEP3fl9UVYXc3xOBVqZNnH9tnvVEJO8vDk3PMtsLqjxug==
+probe-image-size@7.2.3:
+  version "7.2.3"
+  resolved "https://registry.yarnpkg.com/probe-image-size/-/probe-image-size-7.2.3.tgz#d49c64be540ec8edea538f6f585f65a9b3ab4309"
+  integrity sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==
   dependencies:
     lodash.merge "^4.6.2"
     needle "^2.5.2"
@@ -6194,14 +5888,6 @@ rename@1.0.4:
   dependencies:
     debug "^2.5.2"
 
-request-stats@3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/request-stats/-/request-stats-3.0.0.tgz#769155dc8974d78d4a1cb87bbf14eaab985afe25"
-  integrity sha1-dpFV3Il0141KHLh7vxTqq5ha/iU=
-  dependencies:
-    http-headers "^3.0.1"
-    once "^1.4.0"
-
 require-all@3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/require-all/-/require-all-3.0.0.tgz#473d49704be310115ce124f77383b1ebd8671312"
@@ -6397,7 +6083,7 @@ semver@^7.3.5:
   dependencies:
     lru-cache "^6.0.0"
 
-serialize-javascript@5.0.1, serialize-javascript@^5.0.1:
+serialize-javascript@5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4"
   integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==
@@ -6432,17 +6118,17 @@ sha.js@^2.4.11:
     inherits "^2.0.1"
     safe-buffer "^5.0.1"
 
-sharp@0.29.3:
-  version "0.29.3"
-  resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2"
-  integrity sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA==
+sharp@0.30.0:
+  version "0.30.0"
+  resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.30.0.tgz#b2dd62d5f14088b11c72212354f31dff6511b070"
+  integrity sha512-L3m/l6yQFr3oGBUzcSAlN/R9yGFPYqM9FpMUe6Z4nHg4sWtP3hW1rcz+aaHklhD4wX5Jqh5PY9z+A1d4Qt3Hfg==
   dependencies:
-    color "^4.0.1"
-    detect-libc "^1.0.3"
-    node-addon-api "^4.2.0"
-    prebuild-install "^7.0.0"
+    color "^4.2.0"
+    detect-libc "^2.0.0"
+    node-addon-api "^4.3.0"
+    prebuild-install "^7.0.1"
     semver "^7.3.5"
-    simple-get "^4.0.0"
+    simple-get "^4.0.1"
     tar-fs "^2.1.1"
     tunnel-agent "^0.6.0"
 
@@ -6496,6 +6182,15 @@ simple-get@^4.0.0:
     once "^1.3.1"
     simple-concat "^1.0.0"
 
+simple-get@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
+  integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==
+  dependencies:
+    decompress-response "^6.0.0"
+    once "^1.3.1"
+    simple-concat "^1.0.0"
+
 simple-swizzle@^0.2.2:
   version "0.2.2"
   resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
@@ -6530,34 +6225,16 @@ socks@^2.6.1:
     ip "^1.1.5"
     smart-buffer "^4.1.0"
 
-source-list-map@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
-  integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
-
 source-map-js@^0.6.2:
   version "0.6.2"
   resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
   integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
 
-source-map-support@~0.5.19:
-  version "0.5.19"
-  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
-  integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
-  dependencies:
-    buffer-from "^1.0.0"
-    source-map "^0.6.0"
-
-source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
+source-map@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
   integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
 
-source-map@~0.7.2:
-  version "0.7.3"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
-  integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
-
 speakeasy@2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/speakeasy/-/speakeasy-2.0.0.tgz#85c91a071b09a5cb8642590d983566165f57613a"
@@ -6794,7 +6471,7 @@ supports-color@^5.3.0:
   dependencies:
     has-flag "^3.0.0"
 
-supports-color@^7.0.0, supports-color@^7.1.0:
+supports-color@^7.1.0:
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
   integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
@@ -6813,12 +6490,12 @@ syslog-pro@1.0.0:
   dependencies:
     moment "^2.22.2"
 
-systeminformation@5.9.9:
-  version "5.9.9"
-  resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.9.9.tgz#aa8234a138363bd988f438fed3273370f79d7e30"
-  integrity sha512-xciy6NKCLfs4dqMD1Tdlo7v1/g0NfdA1EKsIptUQjlcVvpwHyjifAbNOF7ppFezGSMXxYE8me+l2+RlFF4lyTg==
+systeminformation@5.11.0:
+  version "5.11.0"
+  resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.11.0.tgz#2060779e1e7c7372192dbcd850c65cfd85f4ea71"
+  integrity sha512-mI/5nFK7NUe9Qbmy65WoB5TlCWKAhP4kG0w6uR2mZM8Mpdi8b45b3hTIK3W5+kQYZnYFWeS9/O5nn5rdcSvqfA==
 
-tapable@^2.1.1, tapable@^2.2.0:
+tapable@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
   integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==
@@ -6889,27 +6566,6 @@ tar@^6.1.2:
     mkdirp "^1.0.3"
     yallist "^4.0.0"
 
-terser-webpack-plugin@^5.1.1:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz#7effadee06f7ecfa093dbbd3e9ab23f5f3ed8673"
-  integrity sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==
-  dependencies:
-    jest-worker "^26.6.2"
-    p-limit "^3.1.0"
-    schema-utils "^3.0.0"
-    serialize-javascript "^5.0.1"
-    source-map "^0.6.1"
-    terser "^5.5.1"
-
-terser@^5.5.1:
-  version "5.5.1"
-  resolved "https://registry.yarnpkg.com/terser/-/terser-5.5.1.tgz#540caa25139d6f496fdea056e414284886fb2289"
-  integrity sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==
-  dependencies:
-    commander "^2.20.0"
-    source-map "~0.7.2"
-    source-map-support "~0.5.19"
-
 text-table@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -6990,10 +6646,10 @@ tough-cookie@^4.0.0:
     punycode "^2.1.1"
     universalify "^0.1.2"
 
-tr46@^2.0.0, tr46@^2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479"
-  integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==
+tr46@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9"
+  integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==
   dependencies:
     punycode "^2.1.1"
 
@@ -7057,7 +6713,7 @@ tsconfig-paths@3.12.0, tsconfig-paths@^3.12.0:
     minimist "^1.2.0"
     strip-bom "^3.0.0"
 
-tslib@^1.8.1, tslib@^1.9.0:
+tslib@^1.8.1:
   version "1.11.1"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
   integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
@@ -7318,20 +6974,12 @@ w3c-hr-time@^1.0.2:
   dependencies:
     browser-process-hrtime "^1.0.0"
 
-w3c-xmlserializer@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"
-  integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==
-  dependencies:
-    xml-name-validator "^3.0.0"
-
-watchpack@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.0.0.tgz#b12248f32f0fd4799b7be0802ad1f6573a45955c"
-  integrity sha512-xSdCxxYZWNk3VK13bZRYhsQpfa8Vg63zXG+3pyU8ouqSLRCv4IGXIp9Kr226q6GBkGRlZrST2wwKtjfKz2m7Cg==
+w3c-xmlserializer@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923"
+  integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==
   dependencies:
-    glob-to-regexp "^0.4.1"
-    graceful-fs "^4.1.2"
+    xml-name-validator "^4.0.0"
 
 web-push@3.4.5:
   version "3.4.5"
@@ -7350,52 +6998,10 @@ web-streams-polyfill@^3.0.3:
   resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz#a6b74026b38e4885869fb5c589e90b95ccfc7965"
   integrity sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==
 
-webidl-conversions@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
-  integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==
-
-webidl-conversions@^6.1.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
-  integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
-
-webpack-sources@^2.1.1:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac"
-  integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==
-  dependencies:
-    source-list-map "^2.0.1"
-    source-map "^0.6.1"
-
-webpack@^5:
-  version "5.33.2"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.33.2.tgz#c049717c9b038febf5a72fd2f53319ad59a8c1fc"
-  integrity sha512-X4b7F1sYBmJx8mlh2B7mV5szEkE0jYNJ2y3akgAP0ERi0vLCG1VvdsIxt8lFd4st6SUy0lf7W0CCQS566MBpJg==
-  dependencies:
-    "@types/eslint-scope" "^3.7.0"
-    "@types/estree" "^0.0.46"
-    "@webassemblyjs/ast" "1.11.0"
-    "@webassemblyjs/wasm-edit" "1.11.0"
-    "@webassemblyjs/wasm-parser" "1.11.0"
-    acorn "^8.0.4"
-    browserslist "^4.14.5"
-    chrome-trace-event "^1.0.2"
-    enhanced-resolve "^5.7.0"
-    es-module-lexer "^0.4.0"
-    eslint-scope "^5.1.1"
-    events "^3.2.0"
-    glob-to-regexp "^0.4.1"
-    graceful-fs "^4.2.4"
-    json-parse-better-errors "^1.0.2"
-    loader-runner "^4.2.0"
-    mime-types "^2.1.27"
-    neo-async "^2.6.2"
-    schema-utils "^3.0.0"
-    tapable "^2.1.1"
-    terser-webpack-plugin "^5.1.1"
-    watchpack "^2.0.0"
-    webpack-sources "^2.1.1"
+webidl-conversions@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
+  integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
 
 websocket@1.0.34:
   version "1.0.34"
@@ -7409,35 +7015,25 @@ websocket@1.0.34:
     utf-8-validate "^5.0.2"
     yaeti "^0.0.6"
 
-whatwg-encoding@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
-  integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
+whatwg-encoding@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53"
+  integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==
   dependencies:
-    iconv-lite "0.4.24"
+    iconv-lite "0.6.3"
 
-whatwg-mimetype@^2.3.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
-  integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
-
-whatwg-url@^8.0.0:
-  version "8.0.0"
-  resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.0.0.tgz#37f256cb746398e19b107bd6ef820b4ae2d15871"
-  integrity sha512-41ou2Dugpij8/LPO5Pq64K5q++MnRCBpEHvQr26/mArEKTkCV5aoXIqyhuYtE0pkqScXwhf2JP57rkRTYM29lQ==
-  dependencies:
-    lodash.sortby "^4.7.0"
-    tr46 "^2.0.0"
-    webidl-conversions "^5.0.0"
+whatwg-mimetype@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7"
+  integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==
 
-whatwg-url@^8.5.0:
-  version "8.5.0"
-  resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3"
-  integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==
+whatwg-url@^10.0.0:
+  version "10.0.0"
+  resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-10.0.0.tgz#37264f720b575b4a311bd4094ed8c760caaa05da"
+  integrity sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==
   dependencies:
-    lodash "^4.7.0"
-    tr46 "^2.0.2"
-    webidl-conversions "^6.1.0"
+    tr46 "^3.0.0"
+    webidl-conversions "^7.0.0"
 
 which-boxed-primitive@^1.0.2:
   version "1.0.2"
@@ -7526,16 +7122,11 @@ wrappy@1:
   resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
   integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
 
-ws@8.4.2:
+ws@8.4.2, ws@^8.2.3:
   version "8.4.2"
   resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b"
   integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==
 
-ws@^7.4.6:
-  version "7.5.3"
-  resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74"
-  integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==
-
 xev@2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/xev/-/xev-2.0.1.tgz#24484173a22115bc8a990ef5d4d5129695b827a7"
@@ -7548,10 +7139,10 @@ xml-js@^1.6.11:
   dependencies:
     sax "^1.2.4"
 
-xml-name-validator@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
-  integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
+xml-name-validator@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"
+  integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==
 
 xml2js@0.4.19:
   version "0.4.19"
@@ -7695,11 +7286,6 @@ yn@3.1.1:
   resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
   integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
 
-yocto-queue@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
-  integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
-
 zen-observable-ts@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.0.0.tgz#30d1202b81d8ba4c489e3781e8ca09abf0075e70"
diff --git a/packages/client/package.json b/packages/client/package.json
index b840bafe8c370f8ea9414ce7e6ee53038cb8d846..cf4214e72b1aaf25e6fa619eaa1734f15ce58fb5 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -11,8 +11,8 @@
 	},
 	"dependencies": {
 		"@discordapp/twemoji": "13.1.0",
+		"@fortawesome/fontawesome-free": "6.0.0-beta3",
 		"@syuilo/aiscript": "0.11.1",
-		"@types/dateformat": "3.0.1",
 		"@types/escape-regexp": "0.0.1",
 		"@types/glob": "7.2.0",
 		"@types/gulp": "4.0.9",
@@ -26,7 +26,6 @@
 		"@types/punycode": "2.1.0",
 		"@types/qrcode": "1.4.2",
 		"@types/random-seed": "0.3.3",
-		"@types/request-stats": "3.0.0",
 		"@types/seedrandom": "2.4.28",
 		"@types/throttle-debounce": "2.1.0",
 		"@types/tinycolor2": "1.4.3",
@@ -47,6 +46,7 @@
 		"broadcast-channel": "4.9.0",
 		"chart.js": "3.7.0",
 		"chartjs-adapter-date-fns": "2.0.0",
+		"chartjs-plugin-gradient": "0.2.1",
 		"chartjs-plugin-zoom": "1.2.0",
 		"compare-versions": "4.1.3",
 		"content-disposition": "0.5.4",
@@ -87,7 +87,6 @@
 		"querystring": "0.2.1",
 		"random-seed": "0.3.0",
 		"reflect-metadata": "0.1.13",
-		"request-stats": "3.0.0",
 		"rndstr": "1.0.0",
 		"s-age": "1.1.2",
 		"sass": "1.49.0",
diff --git a/packages/client/src/components/chart-tooltip.vue b/packages/client/src/components/chart-tooltip.vue
index b080eaf2b45899ed22803289aaafc5d4a2731e70..20e094a5a7e82441146bd47cc2053272689e338a 100644
--- a/packages/client/src/components/chart-tooltip.vue
+++ b/packages/client/src/components/chart-tooltip.vue
@@ -1,5 +1,5 @@
 <template>
-<MkTooltip ref="tooltip" :showing="showing" :x="x" :y="y" :max-width="340" @closed="emit('closed')">
+<MkTooltip ref="tooltip" :showing="showing" :x="x" :y="y" :max-width="340" :direction="'left'" :inner-margin="16" @closed="emit('closed')">
 	<div v-if="title" class="qpcyisrl">
 		<div class="title">{{ title }}</div>
 		<div v-for="x in series" class="series">
diff --git a/packages/client/src/components/chart.vue b/packages/client/src/components/chart.vue
index 3e46c51b473dbce9c12c7c94ef72e469f6c392ae..ced0d481c49c662affaab2e9259de1a7af6cda16 100644
--- a/packages/client/src/components/chart.vue
+++ b/packages/client/src/components/chart.vue
@@ -29,6 +29,7 @@ import {
 import 'chartjs-adapter-date-fns';
 import { enUS } from 'date-fns/locale';
 import zoomPlugin from 'chartjs-plugin-zoom';
+import gradient from 'chartjs-plugin-gradient';
 import * as os from '@/os';
 import { defaultStore } from '@/store';
 import MkChartTooltip from '@/components/chart-tooltip.vue';
@@ -49,6 +50,7 @@ Chart.register(
 	SubTitle,
 	Filler,
 	zoomPlugin,
+	gradient,
 );
 
 const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b));
@@ -61,9 +63,17 @@ const alpha = (hex, a) => {
 	return `rgba(${r}, ${g}, ${b}, ${a})`;
 };
 
-const colors = ['#008FFB', '#00E396', '#FEB019', '#FF4560'];
+const colors = {
+	blue: '#008FFB',
+	green: '#00E396',
+	yellow: '#FEB019',
+	red: '#FF4560',
+	purple: '#e300db',
+	orange: '#fe6919',
+};
+const colorSets = [colors.blue, colors.green, colors.yellow, colors.red, colors.purple];
 const getColor = (i) => {
-	return colors[i % colors.length];
+	return colorSets[i % colorSets.length];
 };
 
 export default defineComponent({
@@ -95,6 +105,11 @@ export default defineComponent({
 			required: false,
 			default: false
 		},
+		bar: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
 		aspectRatio: {
 			type: Number,
 			required: false,
@@ -186,22 +201,36 @@ export default defineComponent({
 			// フォントカラー
 			Chart.defaults.color = getComputedStyle(document.documentElement).getPropertyValue('--fg');
 
+			const maxes = data.series.map((x, i) => Math.max(...x.data.map(d => d.y)));
+
 			chartInstance = new Chart(chartEl.value, {
-				type: 'line',
+				type: props.bar ? 'bar' : 'line',
 				data: {
 					labels: new Array(props.limit).fill(0).map((_, i) => getDate(i).toLocaleString()).slice().reverse(),
 					datasets: data.series.map((x, i) => ({
 						parsing: false,
 						label: x.name,
 						data: x.data.slice().reverse(),
+						tension: 0.3,
 						pointRadius: 0,
-						tension: 0,
 						borderWidth: 2,
 						borderColor: x.color ? x.color : getColor(i),
 						borderDash: x.borderDash || [],
 						borderJoinStyle: 'round',
 						backgroundColor: alpha(x.color ? x.color : getColor(i), 0.1),
+						gradient: {
+							backgroundColor: {
+								axis: 'y',
+								colors: {
+									0: alpha(x.color ? x.color : getColor(i), 0),
+									[maxes[i]]: alpha(x.color ? x.color : getColor(i), 0.1),
+								},
+							},
+						},
+						barPercentage: 0.9,
+						categoryPercentage: 0.9,
 						fill: x.type === 'area',
+						clip: 8,
 						hidden: !!x.hidden,
 					})),
 				},
@@ -210,7 +239,7 @@ export default defineComponent({
 					layout: {
 						padding: {
 							left: 0,
-							right: 0,
+							right: 8,
 							top: 0,
 							bottom: 0,
 						},
@@ -218,6 +247,7 @@ export default defineComponent({
 					scales: {
 						x: {
 							type: 'time',
+							stacked: props.stacked,
 							time: {
 								stepSize: 1,
 								unit: props.span === 'day' ? 'month' : 'day',
@@ -228,6 +258,8 @@ export default defineComponent({
 							},
 							ticks: {
 								display: props.detailed,
+								maxRotation: 0,
+								autoSkipPadding: 16,
 							},
 							adapters: {
 								date: {
@@ -245,12 +277,21 @@ export default defineComponent({
 							},
 							ticks: {
 								display: props.detailed,
+								//mirror: true,
 							},
 						},
 					},
 					interaction: {
 						intersect: false,
+						mode: 'index',
 					},
+					elements: {
+						point: {
+							hoverRadius: 5,
+							hoverBorderWidth: 2,
+						},
+					},
+					animation: false,
 					plugins: {
 						legend: {
 							display: props.detailed,
@@ -294,6 +335,7 @@ export default defineComponent({
 								},
 							}
 						},
+						gradient,
 					},
 				},
 				plugins: [{
@@ -324,20 +366,60 @@ export default defineComponent({
 			// TODO
 		};
 
-		const fetchFederationInstancesChart = async (total: boolean): Promise<typeof data> => {
+		const fetchFederationChart = async (): Promise<typeof data> => {
 			const raw = await os.api('charts/federation', { limit: props.limit, span: props.span });
 			return {
 				series: [{
-					name: 'Instances',
+					name: 'Total',
 					type: 'area',
-					data: format(total
-						? raw.instance.total
-						: sum(raw.instance.inc, negate(raw.instance.dec))
-					),
+					data: format(raw.instance.total),
+					color: '#888888',
+				}, {
+					name: 'Inc/Dec',
+					type: 'area',
+					data: format(sum(raw.instance.inc, negate(raw.instance.dec))),
+					color: colors.purple,
+				}, {
+					name: 'Received',
+					type: 'area',
+					data: format(raw.inboxInstances),
+					color: colors.blue,
+				}, {
+					name: 'Delivered',
+					type: 'area',
+					data: format(raw.deliveredInstances),
+					color: colors.green,
+				}, {
+					name: 'Stalled',
+					type: 'area',
+					data: format(raw.stalled),
+					color: colors.red,
 				}],
 			};
 		};
 
+		const fetchApRequestChart = async (): Promise<typeof data> => {
+			const raw = await os.api('charts/ap-request', { limit: props.limit, span: props.span });
+			return {
+				series: [{
+					name: 'In',
+					type: 'area',
+					color: '#008FFB',
+					data: format(raw.inboxReceived)
+				}, {
+					name: 'Out (succ)',
+					type: 'area',
+					color: '#00E396',
+					data: format(raw.deliverSucceeded)
+				}, {
+					name: 'Out (fail)',
+					type: 'area',
+					color: '#FEB019',
+					data: format(raw.deliverFailed)
+				}]
+			};
+		};
+
 		const fetchNotesChart = async (type: string): Promise<typeof data> => {
 			const raw = await os.api('charts/notes', { limit: props.limit, span: props.span });
 			return {
@@ -349,6 +431,7 @@ export default defineComponent({
 						? sum(raw.local.inc, negate(raw.local.dec), raw.remote.inc, negate(raw.remote.dec))
 						: sum(raw[type].inc, negate(raw[type].dec))
 					),
+					color: '#888888',
 				}, {
 					name: 'Renotes',
 					type: 'area',
@@ -356,6 +439,7 @@ export default defineComponent({
 						? sum(raw.local.diffs.renote, raw.remote.diffs.renote)
 						: raw[type].diffs.renote
 					),
+					color: colors.green,
 				}, {
 					name: 'Replies',
 					type: 'area',
@@ -363,6 +447,7 @@ export default defineComponent({
 						? sum(raw.local.diffs.reply, raw.remote.diffs.reply)
 						: raw[type].diffs.reply
 					),
+					color: colors.yellow,
 				}, {
 					name: 'Normal',
 					type: 'area',
@@ -370,6 +455,15 @@ export default defineComponent({
 						? sum(raw.local.diffs.normal, raw.remote.diffs.normal)
 						: raw[type].diffs.normal
 					),
+					color: colors.blue,
+				}, {
+					name: 'With file',
+					type: 'area',
+					data: format(type == 'combined'
+						? sum(raw.local.diffs.withFile, raw.remote.diffs.withFile)
+						: raw[type].diffs.withFile
+					),
+					color: colors.purple,
 				}],
 			};
 		};
@@ -425,17 +519,50 @@ export default defineComponent({
 			const raw = await os.api('charts/active-users', { limit: props.limit, span: props.span });
 			return {
 				series: [{
-					name: 'Combined',
-					type: 'line',
-					data: format(sum(raw.local.users, raw.remote.users)),
+					name: 'Read & Write',
+					type: 'area',
+					data: format(raw.readWrite),
+					color: colors.orange,
 				}, {
-					name: 'Local',
+					name: 'Write',
 					type: 'area',
-					data: format(raw.local.users),
+					data: format(raw.write),
+					color: colors.blue,
 				}, {
-					name: 'Remote',
+					name: 'Read',
+					type: 'area',
+					data: format(raw.read),
+					color: '#888888',
+				}, {
+					name: '< Week',
 					type: 'area',
-					data: format(raw.remote.users),
+					data: format(raw.registeredWithinWeek),
+					color: colors.green,
+				}, {
+					name: '< Month',
+					type: 'area',
+					data: format(raw.registeredWithinMonth),
+					color: colors.yellow,
+				}, {
+					name: '< Year',
+					type: 'area',
+					data: format(raw.registeredWithinYear),
+					color: colors.red,
+				}, {
+					name: '> Week',
+					type: 'area',
+					data: format(raw.registeredOutsideWeek),
+					color: colors.yellow,
+				}, {
+					name: '> Month',
+					type: 'area',
+					data: format(raw.registeredOutsideMonth),
+					color: colors.red,
+				}, {
+					name: '> Year',
+					type: 'area',
+					data: format(raw.registeredOutsideYear),
+					color: colors.purple,
 				}],
 			};
 		};
@@ -476,26 +603,6 @@ export default defineComponent({
 			};
 		};
 
-		const fetchDriveTotalChart = async (): Promise<typeof data> => {
-			const raw = await os.api('charts/drive', { limit: props.limit, span: props.span });
-			return {
-				bytes: true,
-				series: [{
-					name: 'Combined',
-					type: 'line',
-					data: format(sum(raw.local.totalSize, raw.remote.totalSize)),
-				}, {
-					name: 'Local',
-					type: 'area',
-					data: format(raw.local.totalSize),
-				}, {
-					name: 'Remote',
-					type: 'area',
-					data: format(raw.remote.totalSize),
-				}],
-			};
-		};
-
 		const fetchDriveFilesChart = async (): Promise<typeof data> => {
 			const raw = await os.api('charts/drive', { limit: props.limit, span: props.span });
 			return {
@@ -531,25 +638,6 @@ export default defineComponent({
 			};
 		};
 
-		const fetchDriveFilesTotalChart = async (): Promise<typeof data> => {
-			const raw = await os.api('charts/drive', { limit: props.limit, span: props.span });
-			return {
-				series: [{
-					name: 'Combined',
-					type: 'line',
-					data: format(sum(raw.local.totalCount, raw.remote.totalCount)),
-				}, {
-					name: 'Local',
-					type: 'area',
-					data: format(raw.local.totalCount),
-				}, {
-					name: 'Remote',
-					type: 'area',
-					data: format(raw.remote.totalCount),
-				}],
-			};
-		};
-
 		const fetchInstanceRequestsChart = async (): Promise<typeof data> => {
 			const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
 			return {
@@ -680,11 +768,26 @@ export default defineComponent({
 			};
 		};
 
+		const fetchPerUserDriveChart = async (): Promise<typeof data> => {
+			const raw = await os.api('charts/user/drive', { userId: props.args.user.id, limit: props.limit, span: props.span });
+			return {
+				series: [{
+					name: 'Inc',
+					type: 'area',
+					data: format(raw.incSize),
+				}, {
+					name: 'Dec',
+					type: 'area',
+					data: format(raw.decSize),
+				}],
+			};
+		};
+
 		const fetchAndRender = async () => {
 			const fetchData = () => {
 				switch (props.src) {
-					case 'federation-instances': return fetchFederationInstancesChart(false);
-					case 'federation-instances-total': return fetchFederationInstancesChart(true);
+					case 'federation': return fetchFederationChart();
+					case 'ap-request': return fetchApRequestChart();
 					case 'users': return fetchUsersChart(false);
 					case 'users-total': return fetchUsersChart(true);
 					case 'active-users': return fetchActiveUsersChart();
@@ -693,9 +796,7 @@ export default defineComponent({
 					case 'remote-notes': return fetchNotesChart('remote');
 					case 'notes-total': return fetchNotesTotalChart();
 					case 'drive': return fetchDriveChart();
-					case 'drive-total': return fetchDriveTotalChart();
 					case 'drive-files': return fetchDriveFilesChart();
-					case 'drive-files-total': return fetchDriveFilesTotalChart();
 					
 					case 'instance-requests': return fetchInstanceRequestsChart();
 					case 'instance-users': return fetchInstanceUsersChart(false);
@@ -710,6 +811,7 @@ export default defineComponent({
 					case 'instance-drive-files-total': return fetchInstanceDriveFilesChart(true);
 
 					case 'per-user-notes': return fetchPerUserNotesChart();
+					case 'per-user-drive': return fetchPerUserDriveChart();
 				}
 			};
 			fetching.value = true;
diff --git a/packages/client/src/components/emoji-picker.vue b/packages/client/src/components/emoji-picker.vue
index 6999ad6517853ee3b9a3b7483117a64b53c894f3..3e1208979f0b83209df09e2b86a130db97aed907 100644
--- a/packages/client/src/components/emoji-picker.vue
+++ b/packages/client/src/components/emoji-picker.vue
@@ -81,7 +81,7 @@ import { getStaticImageUrl } from '@/scripts/get-static-image-url';
 import Ripple from '@/components/ripple.vue';
 import * as os from '@/os';
 import { isTouchUsing } from '@/scripts/touch';
-import { isMobile } from '@/scripts/is-mobile';
+import { deviceKind } from '@/scripts/device-kind';
 import { emojiCategories, instance } from '@/instance';
 import XSection from './emoji-picker.section.vue';
 import { i18n } from '@/i18n';
@@ -263,7 +263,7 @@ watch(q, () => {
 });
 
 function focus() {
-	if (!isMobile && !isTouchUsing) {
+	if (!['smartphone', 'tablet'].includes(deviceKind) && !isTouchUsing) {
 		search.value?.focus({
 			preventScroll: true
 		});
diff --git a/packages/client/src/components/instance-stats.vue b/packages/client/src/components/instance-stats.vue
index 409c3a49caa9a71416d23461ff2d50c8eb2bc7a1..d2aa5a151aaa6db05eb50ca5f923de9a9c56432c 100644
--- a/packages/client/src/components/instance-stats.vue
+++ b/packages/client/src/components/instance-stats.vue
@@ -3,8 +3,8 @@
 	<div class="selects" style="display: flex;">
 		<MkSelect v-model="chartSrc" style="margin: 0; flex: 1;">
 			<optgroup :label="$ts.federation">
-				<option value="federation-instances">{{ $ts._charts.federationInstancesIncDec }}</option>
-				<option value="federation-instances-total">{{ $ts._charts.federationInstancesTotal }}</option>
+				<option value="federation">{{ $ts._charts.federation }}</option>
+				<option value="ap-request">{{ $ts._charts.apRequest }}</option>
 			</optgroup>
 			<optgroup :label="$ts.users">
 				<option value="users">{{ $ts._charts.usersIncDec }}</option>
@@ -19,9 +19,7 @@
 			</optgroup>
 			<optgroup :label="$ts.drive">
 				<option value="drive-files">{{ $ts._charts.filesIncDec }}</option>
-				<option value="drive-files-total">{{ $ts._charts.filesTotal }}</option>
 				<option value="drive">{{ $ts._charts.storageUsageIncDec }}</option>
-				<option value="drive-total">{{ $ts._charts.storageUsageTotal }}</option>
 			</optgroup>
 		</MkSelect>
 		<MkSelect v-model="chartSpan" style="margin: 0 0 0 10px;">
diff --git a/packages/client/src/components/instance-ticker.vue b/packages/client/src/components/instance-ticker.vue
index 77fd8bb344444c9fde50b0753aed7c128c8e4ab5..9b0a18ec90058b1168419f6d8c4e94d2522f5440 100644
--- a/packages/client/src/components/instance-ticker.vue
+++ b/packages/client/src/components/instance-ticker.vue
@@ -7,15 +7,27 @@
 
 <script lang="ts" setup>
 import { } from 'vue';
+import { instanceName } from '@/config';
 
 const props = defineProps<{
-	instance: any; // TODO
+	instance?: {
+		faviconUrl?: string
+		name: string
+		themeColor?: string
+	}
 }>();
 
-const themeColor = props.instance.themeColor || '#777777';
+// if no instance data is given, this is for the local instance
+const instance = props.instance ?? {
+	faviconUrl: '/favicon.ico',
+	name: instanceName,
+	themeColor: (document.querySelector('meta[name="theme-color-orig"]') as HTMLMetaElement)?.content
+};
+
+const themeColor = instance.themeColor ?? '#777777';
 
 const bg = {
-	background: `linear-gradient(90deg, ${themeColor}, ${themeColor + '00'})`
+	background: `linear-gradient(90deg, ${themeColor}, ${themeColor}00)`
 };
 </script>
 
diff --git a/packages/client/src/components/post-form.vue b/packages/client/src/components/post-form.vue
index 535218ecf984937c769c359a35d2a20982d6ef95..64a6478f45365edf1dbe7e7db52fa648d54d4876 100644
--- a/packages/client/src/components/post-form.vue
+++ b/packages/client/src/components/post-form.vue
@@ -342,6 +342,7 @@ function addTag(tag: string) {
 
 function focus() {
 	textareaEl.focus();
+	textareaEl.setSelectionRange(textareaEl.value.length, textareaEl.value.length);
 }
 
 function chooseFileFrom(ev) {
diff --git a/packages/client/src/components/ui/modal.vue b/packages/client/src/components/ui/modal.vue
index 3c3bb5c2266973fb04d34e41a30bb1a18806ca80..b42c0e4d426fe5f279ebc7ca4f87875d035dff48 100644
--- a/packages/client/src/components/ui/modal.vue
+++ b/packages/client/src/components/ui/modal.vue
@@ -14,6 +14,7 @@ import { nextTick, onMounted, computed, ref, watch, provide } from 'vue';
 import * as os from '@/os';
 import { isTouchUsing } from '@/scripts/touch';
 import { defaultStore } from '@/store';
+import { deviceKind } from '@/scripts/device-kind';
 
 function getFixedContainer(el: Element | null): Element | null {
 	if (el == null || el.tagName === 'BODY') return null;
@@ -62,7 +63,7 @@ const content = ref<HTMLElement>();
 const zIndex = os.claimZIndex(props.zPriority);
 const type = computed(() => {
 	if (props.preferType === 'auto') {
-		if (!defaultStore.state.disableDrawer && isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) {
+		if (!defaultStore.state.disableDrawer && isTouchUsing && deviceKind === 'smartphone') {
 			return 'drawer';
 		} else {
 			return props.src != null ? 'popup' : 'dialog';
diff --git a/packages/client/src/components/ui/tooltip.vue b/packages/client/src/components/ui/tooltip.vue
index 1892877cc106a809c2d33991bccbb10ccff37fee..3ccd1b73169396704eae874808689d4c7b403b94 100644
--- a/packages/client/src/components/ui/tooltip.vue
+++ b/packages/client/src/components/ui/tooltip.vue
@@ -17,8 +17,12 @@ const props = withDefaults(defineProps<{
 	y?: number;
 	text?: string;
 	maxWidth?: number;
+	direction?: 'top' | 'bottom' | 'right' | 'left';
+	innerMargin?: number;
 }>(), {
 	maxWidth: 250,
+	direction: 'top',
+	innerMargin: 0,
 });
 
 const emit = defineEmits<{
@@ -34,39 +38,144 @@ const setPosition = () => {
 	const contentWidth = el.value.offsetWidth;
 	const contentHeight = el.value.offsetHeight;
 
-	let left: number;
-	let top: number;
-
 	let rect: DOMRect;
 
 	if (props.targetElement) {
 		rect = props.targetElement.getBoundingClientRect();
+	}
+
+	const calcPosWhenTop = () => {
+		let left: number;
+		let top: number;
+
+		if (props.targetElement) {
+			left = rect.left + window.pageXOffset + (props.targetElement.offsetWidth / 2);
+			top = (rect.top + window.pageYOffset - contentHeight) - props.innerMargin;
+		} else {
+			left = props.x;
+			top = (props.y - contentHeight) - props.innerMargin;
+		}
+
+		left -= (el.value.offsetWidth / 2);
+
+		if (left + contentWidth - window.pageXOffset > window.innerWidth) {
+			left = window.innerWidth - contentWidth + window.pageXOffset - 1;
+		}
+
+		return [left, top];
+	}
+
+	const calcPosWhenBottom = () => {
+		let left: number;
+		let top: number;
+
+		if (props.targetElement) {
+			left = rect.left + window.pageXOffset + (props.targetElement.offsetWidth / 2);
+			top = (rect.top + window.pageYOffset + props.targetElement.offsetHeight) + props.innerMargin;
+		} else {
+			left = props.x;
+			top = (props.y) + props.innerMargin;
+		}
+
+		left -= (el.value.offsetWidth / 2);
 
-		left = rect.left + window.pageXOffset + (props.targetElement.offsetWidth / 2);
-		top = rect.top + window.pageYOffset - contentHeight;
+		if (left + contentWidth - window.pageXOffset > window.innerWidth) {
+			left = window.innerWidth - contentWidth + window.pageXOffset - 1;
+		}
 
-		el.value.style.transformOrigin = 'center bottom';
-	} else {
-		left = props.x;
-		top = props.y - contentHeight;
+		return [left, top];
 	}
 
-	left -= (el.value.offsetWidth / 2);
+	const calcPosWhenLeft = () => {
+		let left: number;
+		let top: number;
+
+		if (props.targetElement) {
+			left = (rect.left + window.pageXOffset - contentWidth) - props.innerMargin;
+			top = rect.top + window.pageYOffset + (props.targetElement.offsetHeight / 2);
+		} else {
+			left = (props.x - contentWidth) - props.innerMargin;
+			top = props.y;
+		}
+
+		top -= (el.value.offsetHeight / 2);
+
+		if (top + contentHeight - window.pageYOffset > window.innerHeight) {
+			top = window.innerHeight - contentHeight + window.pageYOffset - 1;
+		}
 
-	if (left + contentWidth - window.pageXOffset > window.innerWidth) {
-		left = window.innerWidth - contentWidth + window.pageXOffset - 1;
+		return [left, top];
 	}
 
-	// ツールチップを上に向かって表示するスペースがなければ下に向かって出す
-	if (top - window.pageYOffset < 0) {
+	const calcPosWhenRight = () => {
+		let left: number;
+		let top: number;
+
 		if (props.targetElement) {
-			top = rect.top + window.pageYOffset + props.targetElement.offsetHeight;
-			el.value.style.transformOrigin = 'center top';
+			left = (rect.left + window.pageXOffset) + props.innerMargin;
+			top = rect.top + window.pageYOffset + (props.targetElement.offsetHeight / 2);
 		} else {
+			left = props.x + props.innerMargin;
 			top = props.y;
 		}
+
+		top -= (el.value.offsetHeight / 2);
+
+		if (top + contentHeight - window.pageYOffset > window.innerHeight) {
+			top = window.innerHeight - contentHeight + window.pageYOffset - 1;
+		}
+
+		return [left, top];
+	}
+
+	const calc = (): {
+		left: number;
+		top: number;
+		transformOrigin: string;
+	} => {
+		switch (props.direction) {
+			case 'top': {
+				const [left, top] = calcPosWhenTop();
+
+				// ツールチップを上に向かって表示するスペースがなければ下に向かって出す
+				if (top - window.pageYOffset < 0) {
+					const [left, top] = calcPosWhenBottom();
+					return { left, top, transformOrigin: 'center top' };
+				}
+
+				return { left, top, transformOrigin: 'center bottom' };
+			}
+
+			case 'bottom': {
+				const [left, top] = calcPosWhenBottom();
+				// TODO: ツールチップを下に向かって表示するスペースがなければ上に向かって出す
+				return { left, top, transformOrigin: 'center top' };
+			}
+
+			case 'left': {
+				const [left, top] = calcPosWhenLeft();
+
+				// ツールチップを左に向かって表示するスペースがなければ右に向かって出す
+				if (left - window.pageXOffset < 0) {
+					const [left, top] = calcPosWhenRight();
+					return { left, top, transformOrigin: 'left center' };
+				}
+
+				return { left, top, transformOrigin: 'right center' };
+			}
+
+			case 'right': {
+				const [left, top] = calcPosWhenRight();
+				// TODO: ツールチップを右に向かって表示するスペースがなければ左に向かって出す
+				return { left, top, transformOrigin: 'left center' };
+			}
+		}
+
+		return null as never;
 	}
 
+	const { left, top, transformOrigin } = calc();
+	el.value.style.transformOrigin = transformOrigin;
 	el.value.style.left = left + 'px';
 	el.value.style.top = top + 'px';
 };
diff --git a/packages/client/src/directives/get-size.ts b/packages/client/src/directives/get-size.ts
index e3b5dea0f3337ea689d7fc256bae13208cec7c82..1fcd0718dc034808ad43c118fa47392005b9e9b9 100644
--- a/packages/client/src/directives/get-size.ts
+++ b/packages/client/src/directives/get-size.ts
@@ -1,34 +1,55 @@
 import { Directive } from 'vue';
 
-export default {
-	mounted(src, binding, vn) {
-		const calc = () => {
-			const height = src.clientHeight;
-			const width = src.clientWidth;
-
-			// 要素が(一時的に)DOMに存在しないときは計算スキップ
-			if (height === 0) return;
-
-			binding.value(width, height);
-		};
+const mountings = new Map<Element, {
+	resize: ResizeObserver;
+	intersection?: IntersectionObserver;
+	fn: (w: number, h: number) => void;
+}>();
+
+function calc(src: Element) {
+	const info = mountings.get(src);
+	const height = src.clientHeight;
+	const width = src.clientWidth;
+
+	if (!info) return;
+
+	// アクティベート前などでsrcが描画されていない場合
+	if (!height) {
+		// IntersectionObserverで表示検出する
+		if (!info.intersection) {
+			info.intersection = new IntersectionObserver(entries => {
+				if (entries.some(entry => entry.isIntersecting)) calc(src);
+			});
+		}
+		info.intersection.observe(src);
+		return;
+	}
+	if (info.intersection) {
+		info.intersection.disconnect()
+		delete info.intersection;
+	};
 
-		calc();
+	info.fn(width, height);
+};
 
-		// Vue3では使えなくなった
-		// 無くても大丈夫か...?
-		// TODO: ↑大丈夫じゃなかったので解決策を探す
-		//vn.context.$on('hook:activated', calc);
+export default {
+	mounted(src, binding, vn) {
 
-		const ro = new ResizeObserver((entries, observer) => {
-			calc();
+		const resize = new ResizeObserver((entries, observer) => {
+			calc(src);
 		});
-		ro.observe(src);
+		resize.observe(src);
 
-		src._get_size_ro_ = ro;
+		mountings.set(src, { resize, fn: binding.value, });
+		calc(src);
 	},
 
 	unmounted(src, binding, vn) {
 		binding.value(0, 0);
-		src._get_size_ro_.unobserve(src);
+		const info = mountings.get(src);
+		if (!info) return;
+		info.resize.disconnect();
+		if (info.intersection) info.intersection.disconnect();
+		mountings.delete(src);
 	}
-} as Directive;
+} as Directive<Element, (w: number, h: number) => void>;
diff --git a/packages/client/src/directives/size.ts b/packages/client/src/directives/size.ts
index a72a97abcc12c054293cb489218dcf0e38a8593b..36f649f1803650065c48aad1a19ff539d50ef434 100644
--- a/packages/client/src/directives/size.ts
+++ b/packages/client/src/directives/size.ts
@@ -1,68 +1,107 @@
 import { Directive } from 'vue';
 
+type Value = { max?: number[]; min?: number[]; };
+
 //const observers = new Map<Element, ResizeObserver>();
+const mountings = new Map<Element, {
+	value: Value;
+	resize: ResizeObserver;
+	intersection?: IntersectionObserver;
+	previousWidth: number;
+}>();
+
+type ClassOrder = {
+	add: string[];
+	remove: string[];
+};
+
+const cache = new Map<string, ClassOrder>();
+
+function getClassOrder(width: number, queue: Value): ClassOrder {
+	const getMaxClass = (v: number) => `max-width_${v}px`;
+	const getMinClass = (v: number) => `min-width_${v}px`;
+
+	return {
+		add: [
+			...(queue.max ? queue.max.filter(v => width <= v).map(getMaxClass) : []),
+			...(queue.min ? queue.min.filter(v => width >= v).map(getMinClass) : []),
+		],
+		remove: [
+			...(queue.max ? queue.max.filter(v => width  > v).map(getMaxClass) : []),
+			...(queue.min ? queue.min.filter(v => width  < v).map(getMinClass) : []),
+		]
+	};
+}
+
+function applyClassOrder(el: Element, order: ClassOrder) {
+	el.classList.add(...order.add);
+	el.classList.remove(...order.remove);
+}
+
+function getOrderName(width: number, queue: Value): string {
+	return `${width}|${queue.max ? queue.max.join(',') : ''}|${queue.min ? queue.min.join(',') : ''}`;
+}
+
+function calc(el: Element) {
+	const info = mountings.get(el);
+	const width = el.clientWidth;
+
+	if (!info || info.previousWidth === width) return;
+
+	// アクティベート前などでsrcが描画されていない場合
+	if (!width) {
+		// IntersectionObserverで表示検出する
+		if (!info.intersection) {
+			info.intersection = new IntersectionObserver(entries => {
+				if (entries.some(entry => entry.isIntersecting)) calc(el);
+			});
+		}
+		info.intersection.observe(el);
+		return;
+	}
+	if (info.intersection) {
+		info.intersection.disconnect()
+		delete info.intersection;
+	};
+
+	mountings.set(el, Object.assign(info, { previousWidth: width }));
+
+	const cached = cache.get(getOrderName(width, info.value));
+	if (cached) {
+		applyClassOrder(el, cached);
+	} else {
+		const order = getClassOrder(width, info.value);
+		cache.set(getOrderName(width, info.value), order);
+		applyClassOrder(el, order);
+	}
+}
 
 export default {
 	mounted(src, binding, vn) {
-		const query = binding.value;
-
-		const addClass = (el: Element, cls: string) => {
-			el.classList.add(cls);
-		};
-
-		const removeClass = (el: Element, cls: string) => {
-			el.classList.remove(cls);
-		};
-
-		const calc = () => {
-			const width = src.clientWidth;
-
-			// 要素が(一時的に)DOMに存在しないときは計算スキップ
-			if (width === 0) return;
-
-			if (query.max) {
-				for (const v of query.max) {
-					if (width <= v) {
-						addClass(src, 'max-width_' + v + 'px');
-					} else {
-						removeClass(src, 'max-width_' + v + 'px');
-					}
-				}
-			}
-			if (query.min) {
-				for (const v of query.min) {
-					if (width >= v) {
-						addClass(src, 'min-width_' + v + 'px');
-					} else {
-						removeClass(src, 'min-width_' + v + 'px');
-					}
-				}
-			}
-		};
-
-		calc();
-
-		window.addEventListener('resize', calc);
-
-		// Vue3では使えなくなった
-		// 無くても大丈夫か...?
-		// TODO: ↑大丈夫じゃなかったので解決策を探す
-		//vn.context.$on('hook:activated', calc);
-
-		//const ro = new ResizeObserver((entries, observer) => {
-		//	calc();
-		//});
-
-		//ro.observe(el);
-
-		// TODO: 新たにプロパティを作るのをやめMapを使う
-		// ただメモリ的には↓の方が省メモリかもしれないので検討中
-		//el._ro_ = ro;
-		src._calc_ = calc;
+		const resize = new ResizeObserver((entries, observer) => {
+			calc(src);
+		});
+
+		mountings.set(src, {
+			value: binding.value,
+			resize,
+			previousWidth: 0,
+		});
+
+		calc(src);
+		resize.observe(src);
+	},
+
+	updated(src, binding, vn) {
+		mountings.set(src, Object.assign({}, mountings.get(src), { value: binding.value }));
+		calc(src);
 	},
 
 	unmounted(src, binding, vn) {
-		//el._ro_.unobserve(el);
-		window.removeEventListener('resize', src._calc_);
+		const info = mountings.get(src);
+		if (!info) return;
+		info.resize.disconnect();
+		if (info.intersection) info.intersection.disconnect();
+		mountings.delete(src);
 	}
-} as Directive;
+} as Directive<Element, Value>;
diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts
index 81e41febd1886d8f2b5b40e0c3ae72d4c46a9570..b7fc8b1d1e438ca0d545bb0224a1678ed8863e31 100644
--- a/packages/client/src/init.ts
+++ b/packages/client/src/init.ts
@@ -14,7 +14,7 @@ if (localStorage.getItem('accounts') != null) {
 //#endregion
 
 import { computed, createApp, watch, markRaw, version as vueVersion } from 'vue';
-import * as compareVersions from 'compare-versions';
+import compareVersions from 'compare-versions';
 
 import widgets from '@/widgets';
 import directives from '@/directives';
@@ -32,7 +32,7 @@ import { defaultStore, ColdDeviceStorage } from '@/store';
 import { fetchInstance, instance } from '@/instance';
 import { makeHotkey } from '@/scripts/hotkey';
 import { search } from '@/scripts/search';
-import { isMobile } from '@/scripts/is-mobile';
+import { deviceKind } from '@/scripts/device-kind';
 import { initializeSw } from '@/scripts/initialize-sw';
 import { reloadChannel } from '@/scripts/unison-reload';
 import { reactionPicker } from '@/scripts/reaction-picker';
@@ -92,7 +92,7 @@ window.addEventListener('resize', () => {
 //#endregion
 
 // If mobile, insert the viewport meta tag
-if (isMobile || window.innerWidth <= 1024) {
+if (['smartphone', 'tablet'].includes(deviceKind)) {
 	const viewport = document.getElementsByName('viewport').item(0);
 	viewport.setAttribute('content',
 		`${viewport.getAttribute('content')},minimum-scale=1,maximum-scale=1,user-scalable=no`);
diff --git a/packages/client/src/pages/about.vue b/packages/client/src/pages/about.vue
index d5bab4baf84c9cf904df58b79117443db9e99aa0..6cc2e387ec40504155d5849579a98e364f7f5ae5 100644
--- a/packages/client/src/pages/about.vue
+++ b/packages/client/src/pages/about.vue
@@ -1,5 +1,5 @@
 <template>
-<MkSpacer :content-max="600" :margin-min="20">
+<MkSpacer v-if="tab === 'overview'" :content-max="600" :margin-min="20">
 	<div class="_formRoot">
 		<div class="_formBlock fwhjspax" :style="{ backgroundImage: `url(${ $instance.bannerUrl })` }">
 			<div class="content">
@@ -65,35 +65,50 @@
 		</FormSection>
 	</div>
 </MkSpacer>
+<MkSpacer v-else-if="tab === 'charts'" :content-max="1200" :margin-min="20">
+	<MkInstanceStats :chart-limit="500" :detailed="true"/>
+</MkSpacer>
 </template>
 
 <script lang="ts" setup>
-import { ref } from 'vue';
+import { ref, computed } from 'vue';
 import { version, instanceName } from '@/config';
 import FormLink from '@/components/form/link.vue';
 import FormSection from '@/components/form/section.vue';
 import FormSuspense from '@/components/form/suspense.vue';
 import FormSplit from '@/components/form/split.vue';
 import MkKeyValue from '@/components/key-value.vue';
+import MkInstanceStats from '@/components/instance-stats.vue';
 import * as os from '@/os';
 import number from '@/filters/number';
 import * as symbols from '@/symbols';
 import { host } from '@/config';
 import { i18n } from '@/i18n';
 
-const stats = ref(null);
+let stats = $ref(null);
+let tab = $ref('overview');
 
 const initStats = () => os.api('stats', {
 }).then((res) => {
-	stats.value = res;
+	stats = res;
 });
 
 defineExpose({
-	[symbols.PAGE_INFO]: {
+	[symbols.PAGE_INFO]: computed(() => ({
 		title: i18n.ts.instanceInfo,
 		icon: 'fas fa-info-circle',
 		bg: 'var(--bg)',
-	},
+		tabs: [{
+			active: tab === 'overview',
+			title: i18n.ts.overview,
+			onClick: () => { tab = 'overview'; },
+		}, {
+			active: tab === 'charts',
+			title: i18n.ts.charts,
+			icon: 'fas fa-chart-bar',
+			onClick: () => { tab = 'charts'; },
+		},],
+	})),
 });
 </script>
 
diff --git a/packages/client/src/pages/admin/files.vue b/packages/client/src/pages/admin/files.vue
index 87dd12f489528c603128f906ceaa869ddd651aa0..c62f053092bb85e267caf58eb128f54b79a9b789 100644
--- a/packages/client/src/pages/admin/files.vue
+++ b/packages/client/src/pages/admin/files.vue
@@ -28,7 +28,7 @@
 					<template #label>MIME type</template>
 				</MkInput>
 			</div>
-			<MkPagination v-slot="{items}" ref="files" :pagination="pagination" class="urempief">
+			<MkPagination v-slot="{items}" :pagination="pagination" class="urempief">
 				<button v-for="file in items" :key="file.id" class="file _panel _button _gap" @click="show(file, $event)">
 					<MkDriveFileThumbnail class="thumbnail" :file="file" fit="contain"/>
 					<div class="body">
@@ -54,8 +54,8 @@
 </div>
 </template>
 
-<script lang="ts">
-import { computed, defineComponent } from 'vue';
+<script lang="ts" setup>
+import { computed } from 'vue';
 import MkButton from '@/components/ui/button.vue';
 import MkInput from '@/components/form/input.vue';
 import MkSelect from '@/components/form/select.vue';
@@ -65,80 +65,63 @@ import MkDriveFileThumbnail from '@/components/drive-file-thumbnail.vue';
 import bytes from '@/filters/bytes';
 import * as os from '@/os';
 import * as symbols from '@/symbols';
+import { i18n } from '@/i18n';
+
+let q = $ref(null);
+let origin = $ref('local');
+let type = $ref(null);
+let searchHost = $ref('');
+const pagination = {
+	endpoint: 'admin/drive/files' as const,
+	limit: 10,
+	params: computed(() => ({
+		type: (type && type !== '') ? type : null,
+		origin: origin,
+		hostname: (searchHost && searchHost !== '') ? searchHost : null,
+	})),
+};
+
+function clear() {
+	os.confirm({
+		type: 'warning',
+		text: i18n.ts.clearCachedFilesConfirm,
+	}).then(({ canceled }) => {
+		if (canceled) return;
+
+		os.apiWithDialog('admin/drive/clean-remote-files', {});
+	});
+}
 
-export default defineComponent({
-	components: {
-		MkButton,
-		MkInput,
-		MkSelect,
-		MkPagination,
-		MkContainer,
-		MkDriveFileThumbnail,
-	},
-
-	emits: ['info'],
-
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: this.$ts.files,
-				icon: 'fas fa-cloud',
-				bg: 'var(--bg)',
-				actions: [{
-					text: this.$ts.clearCachedFiles,
-					icon: 'fas fa-trash-alt',
-					handler: this.clear
-				}]
-			},
-			q: null,
-			origin: 'local',
-			type: null,
-			searchHost: '',
-			pagination: {
-				endpoint: 'admin/drive/files' as const,
-				limit: 10,
-				params: computed(() => ({
-					type: (this.type && this.type !== '') ? this.type : null,
-					origin: this.origin,
-					hostname: (this.searchHost && this.searchHost !== '') ? this.searchHost : null,
-				})),
-			},
-		}
-	},
-
-	methods: {
-		clear() {
-			os.confirm({
-				type: 'warning',
-				text: this.$ts.clearCachedFilesConfirm,
-			}).then(({ canceled }) => {
-				if (canceled) return;
+function show(file) {
+	os.popup(import('./file-dialog.vue'), {
+		fileId: file.id
+	}, {}, 'closed');
+}
 
-				os.apiWithDialog('admin/drive/clean-remote-files', {});
+function find() {
+	os.api('admin/drive/show-file', q.startsWith('http://') || q.startsWith('https://') ? { url: q.trim() } : { fileId: q.trim() }).then(file => {
+		show(file);
+	}).catch(err => {
+		if (err.code === 'NO_SUCH_FILE') {
+			os.alert({
+				type: 'error',
+				text: i18n.ts.notFound
 			});
-		},
-
-		show(file, ev) {
-			os.popup(import('./file-dialog.vue'), {
-				fileId: file.id
-			}, {}, 'closed');
-		},
-
-		find() {
-			os.api('admin/drive/show-file', this.q.startsWith('http://') || this.q.startsWith('https://') ? { url: this.q.trim() } : { fileId: this.q.trim() }).then(file => {
-				this.show(file);
-			}).catch(e => {
-				if (e.code === 'NO_SUCH_FILE') {
-					os.alert({
-						type: 'error',
-						text: this.$ts.notFound
-					});
-				}
-			});
-		},
+		}
+	});
+}
 
-		bytes
-	}
+defineExpose({
+	[symbols.PAGE_INFO]: computed(() => ({
+		title: i18n.ts.files,
+		icon: 'fas fa-cloud',
+		bg: 'var(--bg)',
+		actions: [{
+			text: i18n.ts.clearCachedFiles,
+			icon: 'fas fa-trash-alt',
+			handler: clear,
+		}],
+	})),
 });
 </script>
 
diff --git a/packages/client/src/pages/admin/users.vue b/packages/client/src/pages/admin/users.vue
index 03e155ddcfc5cca731d8378188f94448f4a7e47f..f05aa5ff4531569730f66b1f032aa11b73dbc4f0 100644
--- a/packages/client/src/pages/admin/users.vue
+++ b/packages/client/src/pages/admin/users.vue
@@ -36,7 +36,7 @@
 			</MkInput>
 		</div>
 
-		<MkPagination v-slot="{items}" ref="users" :pagination="pagination" class="users">
+		<MkPagination v-slot="{items}" ref="paginationComponent" :pagination="pagination" class="users">
 			<button v-for="user in items" :key="user.id" class="user _panel _button _gap" @click="show(user)">
 				<MkAvatar class="avatar" :user="user" :disable-link="true" :show-indicator="true"/>
 				<div class="body">
@@ -61,9 +61,8 @@
 </div>
 </template>
 
-<script lang="ts">
-import { computed, defineComponent } from 'vue';
-import MkButton from '@/components/ui/button.vue';
+<script lang="ts" setup>
+import { computed } from 'vue';
 import MkInput from '@/components/form/input.vue';
 import MkSelect from '@/components/form/select.vue';
 import MkPagination from '@/components/ui/pagination.vue';
@@ -71,94 +70,79 @@ import { acct } from '@/filters/user';
 import * as os from '@/os';
 import * as symbols from '@/symbols';
 import { lookupUser } from '@/scripts/lookup-user';
+import { i18n } from '@/i18n';
+
+let paginationComponent = $ref<InstanceType<typeof MkPagination>>();
+
+let sort = $ref('+createdAt');
+let state = $ref('all');
+let origin = $ref('local');
+let searchUsername = $ref('');
+let searchHost = $ref('');
+const pagination = {
+	endpoint: 'admin/show-users' as const,
+	limit: 10,
+	params: computed(() => ({
+		sort: sort,
+		state: state,
+		origin: origin,
+		username: searchUsername,
+		hostname: searchHost,
+	})),
+	offsetMode: true
+};
+
+function searchUser() {
+	os.selectUser().then(user => {
+		show(user);
+	});
+}
 
-export default defineComponent({
-	components: {
-		MkButton,
-		MkInput,
-		MkSelect,
-		MkPagination,
-	},
-
-	emits: ['info'],
-
-	data() {
-		return {
-			[symbols.PAGE_INFO]: {
-				title: this.$ts.users,
-				icon: 'fas fa-users',
-				bg: 'var(--bg)',
-				actions: [{
-					icon: 'fas fa-search',
-					text: this.$ts.search,
-					handler: this.searchUser
-				}, {
-					asFullButton: true,
-					icon: 'fas fa-plus',
-					text: this.$ts.addUser,
-					handler: this.addUser
-				}, {
-					asFullButton: true,
-					icon: 'fas fa-search',
-					text: this.$ts.lookup,
-					handler: this.lookupUser
-				}],
-			},
-			sort: '+createdAt',
-			state: 'all',
-			origin: 'local',
-			searchUsername: '',
-			searchHost: '',
-			pagination: {
-				endpoint: 'admin/show-users' as const,
-				limit: 10,
-				params: computed(() => ({
-					sort: this.sort,
-					state: this.state,
-					origin: this.origin,
-					username: this.searchUsername,
-					hostname: this.searchHost,
-				})),
-				offsetMode: true
-			},
-		}
-	},
-
-	methods: {
-		lookupUser,
-
-		searchUser() {
-			os.selectUser().then(user => {
-				this.show(user);
-			});
-		},
-
-		async addUser() {
-			const { canceled: canceled1, result: username } = await os.inputText({
-				title: this.$ts.username,
-			});
-			if (canceled1) return;
-
-			const { canceled: canceled2, result: password } = await os.inputText({
-				title: this.$ts.password,
-				type: 'password'
-			});
-			if (canceled2) return;
-
-			os.apiWithDialog('admin/accounts/create', {
-				username: username,
-				password: password,
-			}).then(res => {
-				this.$refs.users.reload();
-			});
-		},
-
-		show(user) {
-			os.pageWindow(`/user-info/${user.id}`);
-		},
-
-		acct
-	}
+async function addUser() {
+	const { canceled: canceled1, result: username } = await os.inputText({
+		title: i18n.ts.username,
+	});
+	if (canceled1) return;
+
+	const { canceled: canceled2, result: password } = await os.inputText({
+		title: i18n.ts.password,
+		type: 'password'
+	});
+	if (canceled2) return;
+
+	os.apiWithDialog('admin/accounts/create', {
+		username: username,
+		password: password,
+	}).then(res => {
+		paginationComponent.reload();
+	});
+}
+
+function show(user) {
+	os.pageWindow(`/user-info/${user.id}`);
+}
+
+defineExpose({
+	[symbols.PAGE_INFO]: computed(() => ({
+		title: i18n.ts.users,
+		icon: 'fas fa-users',
+		bg: 'var(--bg)',
+		actions: [{
+			icon: 'fas fa-search',
+			text: i18n.ts.search,
+			handler: searchUser
+		}, {
+			asFullButton: true,
+			icon: 'fas fa-plus',
+			text: i18n.ts.addUser,
+			handler: addUser
+		}, {
+			asFullButton: true,
+			icon: 'fas fa-search',
+			text: i18n.ts.lookup,
+			handler: lookupUser
+		}],
+	})),
 });
 </script>
 
diff --git a/packages/client/src/pages/settings/drive.vue b/packages/client/src/pages/settings/drive.vue
index 134fa633080c1a5fe80fa350caaf09513ed55523..9309eb5ec76be0a5986a516997c1d3b808fa8da9 100644
--- a/packages/client/src/pages/settings/drive.vue
+++ b/packages/client/src/pages/settings/drive.vue
@@ -19,7 +19,7 @@
 
 	<FormSection>
 		<template #label>{{ $ts.statistics }}</template>
-		<div ref="chart"></div>
+		<MkChart src="per-user-drive" :args="{ user: $i }" span="day" :limit="7 * 5" :bar="true" :stacked="true" :detailed="false" :aspect-ratio="6"/>
 	</FormSection>
 
 	<FormSection>
@@ -45,8 +45,7 @@ import * as os from '@/os';
 import bytes from '@/filters/bytes';
 import * as symbols from '@/symbols';
 import { defaultStore } from '@/store';
-
-// TODO: render chart
+import MkChart from '@/components/chart.vue';
 
 export default defineComponent({
 	components: {
@@ -55,6 +54,7 @@ export default defineComponent({
 		FormSection,
 		MkKeyValue,
 		FormSplit,
+		MkChart,
 	},
 
 	emits: ['info'],
diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue
index 2e159e56a91e23c168d6e7f2503bed86d418ed37..c8f6f5832216f39b9027109fbe5114811d9dfcc6 100644
--- a/packages/client/src/pages/settings/general.vue
+++ b/packages/client/src/pages/settings/general.vue
@@ -12,6 +12,14 @@
 		</template>
 	</FormSelect>
 
+	<FormRadios v-model="overridedDeviceKind" class="_formBlock">
+		<template #label>{{ $ts.overridedDeviceKind }}</template>
+		<option :value="null">{{ $ts.auto }}</option>
+		<option value="smartphone"><i class="fas fa-mobile-alt"/> {{ $ts.smartphone }}</option>
+		<option value="tablet"><i class="fas fa-tablet-alt"/> {{ $ts.tablet }}</option>
+		<option value="desktop"><i class="fas fa-desktop"/> {{ $ts.desktop }}</option>
+	</FormRadios>
+
 	<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{ $ts.showFixedPostForm }}</FormSwitch>
 
 	<FormSection>
@@ -127,6 +135,7 @@ export default defineComponent({
 	},
 
 	computed: {
+		overridedDeviceKind: defaultStore.makeGetterSetter('overridedDeviceKind'),
 		serverDisconnectedBehavior: defaultStore.makeGetterSetter('serverDisconnectedBehavior'),
 		reduceAnimation: defaultStore.makeGetterSetter('animation', v => !v, v => !v),
 		useBlurEffectForModal: defaultStore.makeGetterSetter('useBlurEffectForModal'),
@@ -193,6 +202,10 @@ export default defineComponent({
 		instanceTicker() {
 			this.reloadAsk();
 		},
+
+		overridedDeviceKind() {
+			this.reloadAsk();
+		},
 	},
 
 	methods: {
diff --git a/packages/client/src/pages/settings/privacy.vue b/packages/client/src/pages/settings/privacy.vue
index cfae7e9ca8c1468285c5390cefe7e610ad8531b0..a84d2f8786d8480807eb97a8f6418023e3d36995 100644
--- a/packages/client/src/pages/settings/privacy.vue
+++ b/packages/client/src/pages/settings/privacy.vue
@@ -8,7 +8,7 @@
 		<template #caption>{{ $ts.makeReactionsPublicDescription }}</template>
 	</FormSwitch>
 		
-	<FormSelect v-model="ffVisibility" class="_formBlock">
+	<FormSelect v-model="ffVisibility" class="_formBlock" @update:modelValue="save()">
 		<template #label>{{ $ts.ffVisibility }}</template>
 		<option value="public">{{ $ts._ffVisibility.public }}</option>
 		<option value="followers">{{ $ts._ffVisibility.followers }}</option>
diff --git a/packages/client/src/pages/settings/profile.vue b/packages/client/src/pages/settings/profile.vue
index 66b654d87f6ecf37139371433330acab626c87bd..9b30d1c8e0ae510742585aa6ab54a4218566694d 100644
--- a/packages/client/src/pages/settings/profile.vue
+++ b/packages/client/src/pages/settings/profile.vue
@@ -38,7 +38,7 @@
 	</FormSlot>
 
 	<FormSwitch v-model="profile.isCat" class="_formBlock">{{ i18n.ts.flagAsCat }}<template #caption>{{ i18n.ts.flagAsCatDescription }}</template></FormSwitch>
-
+	<FormSwitch v-model="profile.showTimelineReplies" class="_formBlock">{{ i18n.ts.flagShowTimelineReplies }}<template #caption>{{ i18n.ts.flagShowTimelineRepliesDescription }}</template></FormSwitch>
 	<FormSwitch v-model="profile.isBot" class="_formBlock">{{ i18n.ts.flagAsBot }}<template #caption>{{ i18n.ts.flagAsBotDescription }}</template></FormSwitch>
 
 	<FormSwitch v-model="profile.alwaysMarkNsfw" class="_formBlock">{{ i18n.ts.alwaysMarkSensitive }}</FormSwitch>
@@ -68,6 +68,7 @@ const profile = reactive({
 	lang: $i.lang,
 	isBot: $i.isBot,
 	isCat: $i.isCat,
+	showTimelineReplies: $i.showTimelineReplies,
 	alwaysMarkNsfw: $i.alwaysMarkNsfw,
 });
 
@@ -97,6 +98,7 @@ function save() {
 		lang: profile.lang || null,
 		isBot: !!profile.isBot,
 		isCat: !!profile.isCat,
+		showTimelineReplies: !!profile.showTimelineReplies,
 		alwaysMarkNsfw: !!profile.alwaysMarkNsfw,
 	});
 }
diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue
index b2266d22c3ef4aab763da2715491779ba268210b..79f00c4b44899a5ab4832b8c3bcc0488de6c2ab9 100644
--- a/packages/client/src/pages/timeline.vue
+++ b/packages/client/src/pages/timeline.vue
@@ -46,8 +46,10 @@ const keymap = {
 const tlComponent = $ref<InstanceType<typeof XTimeline>>();
 const rootEl = $ref<HTMLElement>();
 
-let src = $ref<'home' | 'local' | 'social' | 'global'>(defaultStore.state.tl.src);
 let queue = $ref(0);
+const src = $computed(() => defaultStore.reactiveState.tl.value.src);
+
+watch ($$(src), () => queue = 0);
 
 function queueUpdated(q: number): void {
 	queue = q;
@@ -60,7 +62,7 @@ function top(): void {
 async function chooseList(ev: MouseEvent): Promise<void> {
 	const lists = await os.api('users/lists/list');
 	const items = lists.map(list => ({
-		type: 'link',
+		type: 'link' as const,
 		text: list.name,
 		to: `/timeline/list/${list.id}`,
 	}));
@@ -70,7 +72,7 @@ async function chooseList(ev: MouseEvent): Promise<void> {
 async function chooseAntenna(ev: MouseEvent): Promise<void> {
 	const antennas = await os.api('antennas/list');
 	const items = antennas.map(antenna => ({
-		type: 'link',
+		type: 'link' as const,
 		text: antenna.name,
 		indicate: antenna.hasUnreadNote,
 		to: `/timeline/antenna/${antenna.id}`,
@@ -81,7 +83,7 @@ async function chooseAntenna(ev: MouseEvent): Promise<void> {
 async function chooseChannel(ev: MouseEvent): Promise<void> {
 	const channels = await os.api('channels/followed');
 	const items = channels.map(channel => ({
-		type: 'link',
+		type: 'link' as const,
 		text: channel.name,
 		indicate: channel.hasUnreadNote,
 		to: `/channels/${channel.id}`,
@@ -89,9 +91,10 @@ async function chooseChannel(ev: MouseEvent): Promise<void> {
 	os.popupMenu(items, ev.currentTarget ?? ev.target);
 }
 
-function saveSrc(): void {
+function saveSrc(newSrc: 'home' | 'local' | 'social' | 'global'): void {
 	defaultStore.set('tl', {
-		src: src,
+		...defaultStore.state.tl,
+		src: newSrc,
 	});
 }
 
@@ -135,25 +138,25 @@ defineExpose({
 			title: i18n.ts._timelines.home,
 			icon: 'fas fa-home',
 			iconOnly: true,
-			onClick: () => { src = 'home'; saveSrc(); },
+			onClick: () => { saveSrc('home'); },
 		}, ...(isLocalTimelineAvailable ? [{
 			active: src === 'local',
 			title: i18n.ts._timelines.local,
 			icon: 'fas fa-comments',
 			iconOnly: true,
-			onClick: () => { src = 'local'; saveSrc(); },
+			onClick: () => { saveSrc('local'); },
 		}, {
 			active: src === 'social',
 			title: i18n.ts._timelines.social,
 			icon: 'fas fa-share-alt',
 			iconOnly: true,
-			onClick: () => { src = 'social'; saveSrc(); },
+			onClick: () => { saveSrc('social'); },
 		}] : []), ...(isGlobalTimelineAvailable ? [{
 			active: src === 'global',
 			title: i18n.ts._timelines.global,
 			icon: 'fas fa-globe',
 			iconOnly: true,
-			onClick: () => { src = 'global'; saveSrc(); },
+			onClick: () => { saveSrc('global'); },
 		}] : [])],
 	})),
 });
diff --git a/packages/client/src/pages/user/index.activity.vue b/packages/client/src/pages/user/index.activity.vue
index 43a4f476f1942ead8053ccedd16a30c95e07d3c7..ebb251d4ccee5b6bba17987be66d65423cbd4dad 100644
--- a/packages/client/src/pages/user/index.activity.vue
+++ b/packages/client/src/pages/user/index.activity.vue
@@ -3,7 +3,7 @@
 	<template #header><i class="fas fa-chart-bar" style="margin-right: 0.5em;"></i>{{ $ts.activity }}</template>
 
 	<div style="padding: 8px;">
-		<MkChart src="per-user-notes" :args="{ user, withoutAll: true }" span="day" :limit="limit" :stacked="true" :detailed="false" :aspect-ratio="6"/>
+		<MkChart src="per-user-notes" :args="{ user, withoutAll: true }" span="day" :limit="limit" :bar="true" :stacked="true" :detailed="false" :aspect-ratio="5"/>
 	</div>
 </MkContainer>
 </template>
diff --git a/packages/client/src/scripts/device-kind.ts b/packages/client/src/scripts/device-kind.ts
new file mode 100644
index 0000000000000000000000000000000000000000..544cac0604d3e370e703e93d509624f60a3cb8e3
--- /dev/null
+++ b/packages/client/src/scripts/device-kind.ts
@@ -0,0 +1,10 @@
+import { defaultStore } from '@/store';
+
+const ua = navigator.userAgent.toLowerCase();
+const isTablet = /ipad/.test(ua) || (/mobile|iphone|android/.test(ua) && window.innerWidth > 700);
+const isSmartphone = !isTablet && /mobile|iphone|android/.test(ua);
+
+export const deviceKind = defaultStore.state.overridedDeviceKind ? defaultStore.state.overridedDeviceKind
+	: isSmartphone ? 'smartphone'
+	: isTablet ? 'tablet'
+	: 'desktop';
diff --git a/packages/client/src/scripts/is-mobile.ts b/packages/client/src/scripts/is-mobile.ts
deleted file mode 100644
index 60cb59f91e7513859daf84c2784e00586b78e2b2..0000000000000000000000000000000000000000
--- a/packages/client/src/scripts/is-mobile.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-const ua = navigator.userAgent.toLowerCase();
-export const isMobile = /mobile|iphone|ipad|android/.test(ua);
diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts
index b80fc8bbe38d764747aa272bd0546ad46cecca76..0e71060cdaa6e96f850077ad753b8cebbe09cefe 100644
--- a/packages/client/src/store.ts
+++ b/packages/client/src/store.ts
@@ -106,6 +106,10 @@ export const defaultStore = markRaw(new Storage('base', {
 		}
 	},
 
+	overridedDeviceKind: {
+		where: 'device',
+		default: null as null | 'smartphone' | 'tablet' | 'desktop',
+	},
 	serverDisconnectedBehavior: {
 		where: 'device',
 		default: 'quiet' as 'quiet' | 'reload' | 'dialog'
diff --git a/packages/client/yarn.lock b/packages/client/yarn.lock
index 76be45f145874ba4e227d5381a7805095297b03d..e06e376bc5985eeaf167b769ca858d432cef1832 100644
--- a/packages/client/yarn.lock
+++ b/packages/client/yarn.lock
@@ -130,6 +130,11 @@
     minimatch "^3.0.4"
     strip-json-comments "^3.1.1"
 
+"@fortawesome/fontawesome-free@6.0.0-beta3":
+  version "6.0.0-beta3"
+  resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.0.0-beta3.tgz#120e4a158a0de983924ce151bc35f27de46398b7"
+  integrity sha512-4SqOuhC8tSLeQvbW1nDmq6T7+8vdSgHy/w7PRwCFzMQCbKuYFIir/3UuWsV1QblX1lt7SGlSgwbaCv9XhRt8HA==
+
 "@hapi/hoek@^9.0.0":
   version "9.2.0"
   resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131"
@@ -266,11 +271,6 @@
   resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
   integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
 
-"@types/dateformat@3.0.1":
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
-  integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
-
 "@types/escape-regexp@0.0.1":
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.1.tgz#f1a977ccdf2ef059e9862bd3af5e92cbbe723e0e"
@@ -460,13 +460,6 @@
   resolved "https://registry.yarnpkg.com/@types/random-seed/-/random-seed-0.3.3.tgz#7741f7b0a4513198a9396ce4ad25832f799a6727"
   integrity sha512-kHsCbIRHNXJo6EN5W8EA5b4i1hdT6jaZke5crBPLUcLqaLdZ0QBq8QVMbafHzhjFF83Cl9qlee2dChD18d/kPg==
 
-"@types/request-stats@3.0.0":
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/@types/request-stats/-/request-stats-3.0.0.tgz#d3909a9f778b8ae0b42fb8c1ed20cb936ed95f99"
-  integrity sha512-POsDF7nETH8up49iBNvbZuO0pEk9F+TG0rXCkvjxCClcOS99xfF+mKmJteYlwKYpuRKkixzysKlL8rwN1hU2lw==
-  dependencies:
-    "@types/node" "*"
-
 "@types/seedrandom@2.4.28":
   version "2.4.28"
   resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.28.tgz#9ce8fa048c1e8c85cb71d7fe4d704e000226036f"
@@ -1591,6 +1584,11 @@ chartjs-adapter-date-fns@2.0.0:
   resolved "https://registry.yarnpkg.com/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-2.0.0.tgz#5e53b2f660b993698f936f509c86dddf9ed44c6b"
   integrity sha512-rmZINGLe+9IiiEB0kb57vH3UugAtYw33anRiw5kS2Tu87agpetDDoouquycWc9pRsKtQo5j+vLsYHyr8etAvFw==
 
+chartjs-plugin-gradient@0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/chartjs-plugin-gradient/-/chartjs-plugin-gradient-0.2.1.tgz#9d6d4f1a04a8d2ffca769adb068df4d0678b8f8f"
+  integrity sha512-hcNQ+B0LuiK9QXhbEc0tUtW3s0a8lOBUJViOCw2xHbnNCIp3Pul/tQHR1aIjMo3HiHu4nOb7NKqFd4NTUEsi4Q==
+
 chartjs-plugin-zoom@1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/chartjs-plugin-zoom/-/chartjs-plugin-zoom-1.2.0.tgz#dad0861b2d171bca1f6d11b3e3e917bc12b950ff"
@@ -3224,13 +3222,6 @@ homedir-polyfill@^1.0.1:
   dependencies:
     parse-passwd "^1.0.0"
 
-http-headers@^3.0.1:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/http-headers/-/http-headers-3.0.2.tgz#5147771292f0b39d6778d930a3a59a76fc7ef44d"
-  integrity sha512-87E1I+2Wg4dxxz4rcxElo3dxO/w1ZtgL1yA0Sb6vH3qU16vRKq1NjWQv9SCY3ly2OQROcoxHZOUpmelS+k6wOw==
-  dependencies:
-    next-line "^1.1.0"
-
 http-signature@~1.3.6:
   version "1.3.6"
   resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9"
@@ -4248,11 +4239,6 @@ netmask@^2.0.2:
   resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
   integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
 
-next-line@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/next-line/-/next-line-1.1.0.tgz#fcae57853052b6a9bae8208e40dd7d3c2d304603"
-  integrity sha1-/K5XhTBStqm66CCOQN19PC0wRgM=
-
 next-tick@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
@@ -5177,14 +5163,6 @@ request-progress@^3.0.0:
   dependencies:
     throttleit "^1.0.0"
 
-request-stats@3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/request-stats/-/request-stats-3.0.0.tgz#769155dc8974d78d4a1cb87bbf14eaab985afe25"
-  integrity sha1-dpFV3Il0141KHLh7vxTqq5ha/iU=
-  dependencies:
-    http-headers "^3.0.1"
-    once "^1.4.0"
-
 require-directory@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
diff --git a/scripts/dev.js b/scripts/dev.js
index 7096f3bf6514363b1d72724225cf69a7f3c56cf6..b7dd870c4197b5b2cb23037988fe8a7b5c455ff8 100644
--- a/scripts/dev.js
+++ b/scripts/dev.js
@@ -1,6 +1,12 @@
 const execa = require('execa');
 
 (async () => {
+	await execa('npm', ['run', 'clean'], {
+		cwd: __dirname + '/../',
+		stdout: process.stdout,
+		stderr: process.stderr,
+	});
+
 	execa('npx', ['gulp', 'watch'], {
 		cwd: __dirname + '/../',
 		stdout: process.stdout,
diff --git a/yarn.lock b/yarn.lock
index 82d2272f6b215f73d8733e574d04ff5f65652ef3..739f06e831318acff7260463ac29b9ab0ebbee1f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1117,10 +1117,10 @@ csso@~2.3.1:
     clap "^1.0.9"
     source-map "^0.5.3"
 
-cypress@9.3.1:
-  version "9.3.1"
-  resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.3.1.tgz#8116f52d49d6daf90a91e88f3eafd940234d2958"
-  integrity sha512-BODdPesxX6bkVUnH8BVsV8I/jn57zQtO1FEOUTiuG2us3kslW7g0tcuwiny7CKCmJUZz8S/D587ppC+s58a+5Q==
+cypress@9.4.1:
+  version "9.4.1"
+  resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.4.1.tgz#1a4ba706435829c24b7edf350c2b059e05da9084"
+  integrity sha512-+JgMG9uT+QFx97JU9kOHE3jO3+0UdkQ9H1oCBiC7A74qme7Jkdy2sYDBCPjjGczutnWnGUTMRlwiNMP/Uq6LrQ==
   dependencies:
     "@cypress/request" "^2.88.10"
     "@cypress/xvfb" "^1.2.4"
@@ -1159,10 +1159,10 @@ cypress@9.3.1:
     pretty-bytes "^5.6.0"
     proxy-from-env "1.0.0"
     request-progress "^3.0.0"
+    semver "^7.3.2"
     supports-color "^8.1.1"
     tmp "~0.2.1"
     untildify "^4.0.0"
-    url "^0.11.0"
     yauzl "^2.10.0"
 
 d@1, d@^1.0.1:
@@ -3422,11 +3422,6 @@ pumpify@^1.3.5:
     inherits "^2.0.3"
     pump "^2.0.0"
 
-punycode@1.3.2:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
-  integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
-
 punycode@^2.1.0, punycode@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
@@ -3450,11 +3445,6 @@ query-string@^4.1.0:
     object-assign "^4.1.0"
     strict-uri-encode "^1.0.0"
 
-querystring@0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
-  integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
-
 queue-microtask@^1.2.2:
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -3736,7 +3726,7 @@ semver-greatest-satisfied-range@^1.1.0:
   resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
   integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
 
-semver@^7.3.5:
+semver@^7.3.2, semver@^7.3.5:
   version "7.3.5"
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
   integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
@@ -4353,14 +4343,6 @@ urix@^0.1.0:
   resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
   integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
 
-url@^0.11.0:
-  version "0.11.0"
-  resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
-  integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
-  dependencies:
-    punycode "1.3.2"
-    querystring "0.2.0"
-
 use@^3.1.0:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"