summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2024-03-01 21:17:01 +0900
committerGitHub <noreply@github.com>2024-03-01 21:17:01 +0900
commit7e706ea6693781fb8973800bb3d0c91b5ab91cdf (patch)
tree8abd91edd288284cf3cc47949e749f881cfaff8e
parentMerge pull request #13045 from misskey-dev/develop (diff)
parentNew translations ja-jp.yml (Chinese Traditional) (#13480) (diff)
downloadsharkey-7e706ea6693781fb8973800bb3d0c91b5ab91cdf.tar.gz
sharkey-7e706ea6693781fb8973800bb3d0c91b5ab91cdf.tar.bz2
sharkey-7e706ea6693781fb8973800bb3d0c91b5ab91cdf.zip
Merge pull request #13447 from misskey-dev/develop
Release: 2024.3.0
-rw-r--r--CHANGELOG.md38
-rw-r--r--locales/ar-SA.yml1
-rw-r--r--locales/ca-ES.yml1
-rw-r--r--locales/cs-CZ.yml1
-rw-r--r--locales/de-DE.yml1
-rw-r--r--locales/en-US.yml32
-rw-r--r--locales/es-ES.yml1
-rw-r--r--locales/fr-FR.yml10
-rw-r--r--locales/id-ID.yml1
-rw-r--r--locales/index.d.ts84
-rw-r--r--locales/it-IT.yml18
-rw-r--r--locales/ja-JP.yml23
-rw-r--r--locales/ja-KS.yml2
-rw-r--r--locales/ko-GS.yml1
-rw-r--r--locales/ko-KR.yml11
-rw-r--r--locales/no-NO.yml1
-rw-r--r--locales/pt-PT.yml1
-rw-r--r--locales/ru-RU.yml1
-rw-r--r--locales/th-TH.yml382
-rw-r--r--locales/vi-VN.yml1
-rw-r--r--locales/zh-CN.yml51
-rw-r--r--locales/zh-TW.yml34
-rw-r--r--package.json18
-rw-r--r--packages/backend/migration/1708266695091-repositoryUrl-from-syuilo-to-misskey-dev.js16
-rw-r--r--packages/backend/migration/1708399372194-per-instance-mod-note.js16
-rw-r--r--packages/backend/package.json62
-rw-r--r--packages/backend/src/core/AccountMoveService.ts4
-rw-r--r--packages/backend/src/core/CacheService.ts5
-rw-r--r--packages/backend/src/core/CoreModule.ts6
-rw-r--r--packages/backend/src/core/CustomEmojiService.ts5
-rw-r--r--packages/backend/src/core/DeleteAccountService.ts4
-rw-r--r--packages/backend/src/core/FileInfoService.ts9
-rw-r--r--packages/backend/src/core/GlobalEventService.ts3
-rw-r--r--packages/backend/src/core/NoteCreateService.ts37
-rw-r--r--packages/backend/src/core/NoteReadService.ts61
-rw-r--r--packages/backend/src/core/NotificationService.ts19
-rw-r--r--packages/backend/src/core/PushNotificationService.ts7
-rw-r--r--packages/backend/src/core/ReactionService.ts49
-rw-r--r--packages/backend/src/core/RoleService.ts22
-rw-r--r--packages/backend/src/core/UserFollowingService.ts43
-rw-r--r--packages/backend/src/core/UtilityService.ts14
-rw-r--r--packages/backend/src/core/WebAuthnService.ts2
-rw-r--r--packages/backend/src/core/activitypub/ApAudienceService.ts3
-rw-r--r--packages/backend/src/core/activitypub/ApInboxService.ts5
-rw-r--r--packages/backend/src/core/activitypub/ApRendererService.ts2
-rw-r--r--packages/backend/src/core/activitypub/models/ApMentionService.ts3
-rw-r--r--packages/backend/src/core/activitypub/models/ApNoteService.ts63
-rw-r--r--packages/backend/src/core/activitypub/models/ApPersonService.ts3
-rw-r--r--packages/backend/src/core/activitypub/models/ApQuestionService.ts3
-rw-r--r--packages/backend/src/core/activitypub/models/tag.ts3
-rw-r--r--packages/backend/src/core/entities/DriveFileEntityService.ts2
-rw-r--r--packages/backend/src/core/entities/InstanceEntityService.ts9
-rw-r--r--packages/backend/src/core/entities/MetaEntityService.ts154
-rw-r--r--packages/backend/src/core/entities/NoteReactionEntityService.ts15
-rw-r--r--packages/backend/src/core/entities/NotificationEntityService.ts269
-rw-r--r--packages/backend/src/core/entities/PageEntityService.ts3
-rw-r--r--packages/backend/src/core/entities/UserEntityService.ts3
-rw-r--r--packages/backend/src/misc/FileWriterStream.ts36
-rw-r--r--packages/backend/src/misc/JsonArrayStream.ts35
-rw-r--r--packages/backend/src/misc/cache.ts8
-rw-r--r--packages/backend/src/misc/is-not-null.ts4
-rw-r--r--packages/backend/src/misc/json-schema.ts10
-rw-r--r--packages/backend/src/models/Instance.ts5
-rw-r--r--packages/backend/src/models/Meta.ts2
-rw-r--r--packages/backend/src/models/Role.ts6
-rw-r--r--packages/backend/src/models/UserProfile.ts2
-rw-r--r--packages/backend/src/models/json-schema/federation-instance.ts4
-rw-r--r--packages/backend/src/models/json-schema/meta.ts328
-rw-r--r--packages/backend/src/models/json-schema/role.ts27
-rw-r--r--packages/backend/src/models/json-schema/user.ts5
-rw-r--r--packages/backend/src/queue/processors/ExportNotesProcessorService.ts164
-rw-r--r--packages/backend/src/queue/processors/InboxProcessorService.ts13
-rw-r--r--packages/backend/src/server/NodeinfoServerService.ts2
-rw-r--r--packages/backend/src/server/api/EndpointsModule.ts5
-rw-r--r--packages/backend/src/server/api/endpoints.ts2
-rw-r--r--packages/backend/src/server/api/endpoints/admin/emoji/add.ts5
-rw-r--r--packages/backend/src/server/api/endpoints/admin/emoji/update.ts27
-rw-r--r--packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts15
-rw-r--r--packages/backend/src/server/api/endpoints/antennas/notes.ts4
-rw-r--r--packages/backend/src/server/api/endpoints/federation/show-instance.ts2
-rw-r--r--packages/backend/src/server/api/endpoints/flash/update.ts12
-rw-r--r--packages/backend/src/server/api/endpoints/following/create.ts15
-rw-r--r--packages/backend/src/server/api/endpoints/gallery/posts/create.ts3
-rw-r--r--packages/backend/src/server/api/endpoints/gallery/posts/update.ts3
-rw-r--r--packages/backend/src/server/api/endpoints/hashtags/search.ts2
-rw-r--r--packages/backend/src/server/api/endpoints/i/notifications-grouped.ts15
-rw-r--r--packages/backend/src/server/api/endpoints/i/notifications.ts2
-rw-r--r--packages/backend/src/server/api/endpoints/i/update.ts6
-rw-r--r--packages/backend/src/server/api/endpoints/meta.ts417
-rw-r--r--packages/backend/src/server/api/endpoints/notes/create.ts24
-rw-r--r--packages/backend/src/server/api/endpoints/notifications/flush.ts33
-rw-r--r--packages/backend/src/server/api/endpoints/pinned-users.ts3
-rw-r--r--packages/backend/src/server/api/endpoints/sw/register.ts4
-rw-r--r--packages/backend/src/server/api/endpoints/sw/unregister.ts7
-rw-r--r--packages/backend/src/server/api/endpoints/sw/update-registration.ts5
-rw-r--r--packages/backend/src/server/api/endpoints/users/reactions.ts2
-rw-r--r--packages/backend/src/server/api/stream/channels/home-timeline.ts10
-rw-r--r--packages/backend/src/server/web/ClientServerService.ts26
-rw-r--r--packages/backend/src/server/web/views/base.pug3
-rw-r--r--packages/backend/src/types.ts17
-rw-r--r--packages/backend/test/e2e/mute.ts180
-rw-r--r--packages/backend/test/e2e/note.ts246
-rw-r--r--packages/backend/test/e2e/streaming.ts105
-rw-r--r--packages/backend/test/unit/ReactionService.ts41
-rw-r--r--packages/backend/test/unit/RoleService.ts28
-rw-r--r--packages/backend/test/utils.ts6
-rw-r--r--packages/frontend/.storybook/generate.tsx3
-rw-r--r--packages/frontend/package.json86
-rw-r--r--packages/frontend/src/account.ts2
-rw-r--r--packages/frontend/src/boot/main-boot.ts12
-rw-r--r--packages/frontend/src/components/MkAutocomplete.vue96
-rw-r--r--packages/frontend/src/components/MkChart.vue2
-rw-r--r--packages/frontend/src/components/MkCode.core.vue2
-rw-r--r--packages/frontend/src/components/MkDialog.vue29
-rw-r--r--packages/frontend/src/components/MkDriveSelectDialog.vue8
-rw-r--r--packages/frontend/src/components/MkEmojiPicker.section.vue3
-rw-r--r--packages/frontend/src/components/MkEmojiPicker.vue86
-rw-r--r--packages/frontend/src/components/MkEmojiPickerDialog.vue4
-rw-r--r--packages/frontend/src/components/MkEmojiPickerWindow.vue49
-rw-r--r--packages/frontend/src/components/MkFormDialog.vue56
-rw-r--r--packages/frontend/src/components/MkNotifications.vue5
-rw-r--r--packages/frontend/src/components/MkPostForm.vue3
-rw-r--r--packages/frontend/src/components/MkPostFormAttaches.vue4
-rw-r--r--packages/frontend/src/components/MkReactionsViewer.reaction.vue11
-rw-r--r--packages/frontend/src/components/MkVisibilityPicker.vue7
-rw-r--r--packages/frontend/src/components/global/MkA.stories.impl.ts4
-rw-r--r--packages/frontend/src/components/global/MkTime.stories.impl.ts5
-rw-r--r--packages/frontend/src/const.ts1
-rw-r--r--packages/frontend/src/directives/user-preview.ts1
-rw-r--r--packages/frontend/src/instance.ts30
-rw-r--r--packages/frontend/src/local-storage.ts1
-rw-r--r--packages/frontend/src/os.ts302
-rw-r--r--packages/frontend/src/pages/admin/RolesEditorFormula.vue9
-rw-r--r--packages/frontend/src/pages/admin/bot-protection.vue2
-rw-r--r--packages/frontend/src/pages/admin/branding.vue2
-rw-r--r--packages/frontend/src/pages/admin/email-settings.vue2
-rw-r--r--packages/frontend/src/pages/admin/external-services.vue2
-rw-r--r--packages/frontend/src/pages/admin/instance-block.vue2
-rw-r--r--packages/frontend/src/pages/admin/moderation.vue2
-rw-r--r--packages/frontend/src/pages/admin/modlog.ModLog.vue6
-rw-r--r--packages/frontend/src/pages/admin/modlog.vue2
-rw-r--r--packages/frontend/src/pages/admin/object-storage.vue2
-rw-r--r--packages/frontend/src/pages/admin/other-settings.vue2
-rw-r--r--packages/frontend/src/pages/admin/proxy-account.vue2
-rw-r--r--packages/frontend/src/pages/admin/roles.editor.vue19
-rw-r--r--packages/frontend/src/pages/admin/roles.vue7
-rw-r--r--packages/frontend/src/pages/admin/security.vue4
-rw-r--r--packages/frontend/src/pages/admin/server-rules.vue2
-rw-r--r--packages/frontend/src/pages/admin/settings.vue2
-rw-r--r--packages/frontend/src/pages/drop-and-fusion.game.vue120
-rw-r--r--packages/frontend/src/pages/drop-and-fusion.vue56
-rw-r--r--packages/frontend/src/pages/emoji-edit-dialog.vue2
-rw-r--r--packages/frontend/src/pages/instance-info.vue12
-rw-r--r--packages/frontend/src/pages/notifications.vue4
-rw-r--r--packages/frontend/src/pages/reversi/game.board.vue19
-rw-r--r--packages/frontend/src/pages/settings/drive.vue2
-rw-r--r--packages/frontend/src/pages/settings/emoji-picker.vue2
-rw-r--r--packages/frontend/src/pages/settings/notifications.notification-config.vue1
-rw-r--r--packages/frontend/src/pages/settings/notifications.vue13
-rw-r--r--packages/frontend/src/pages/settings/preferences-backups.vue2
-rw-r--r--packages/frontend/src/scripts/autocomplete.ts4
-rw-r--r--packages/frontend/src/scripts/check-reaction-permissions.ts6
-rw-r--r--packages/frontend/src/scripts/clear-cache.ts4
-rw-r--r--packages/frontend/src/scripts/emojilist.ts9
-rw-r--r--packages/frontend/src/scripts/form.ts17
-rw-r--r--packages/frontend/src/scripts/search-emoji.ts106
-rw-r--r--packages/frontend/src/scripts/sound.ts2
-rw-r--r--packages/frontend/src/style.scss33
-rw-r--r--packages/frontend/src/ui/deck.vue20
-rw-r--r--packages/frontend/src/ui/deck/channel-column.vue2
-rw-r--r--packages/frontend/src/widgets/WidgetSlideshow.vue4
-rw-r--r--packages/frontend/test/autocomplete.test.ts34
-rw-r--r--packages/frontend/test/scroll.test.ts6
-rw-r--r--packages/misskey-bubble-game/package.json6
-rw-r--r--packages/misskey-js/etc/misskey-js.api.md28
-rw-r--r--packages/misskey-js/package.json16
-rw-r--r--packages/misskey-js/src/autogen/apiClientJSDoc.ts11
-rw-r--r--packages/misskey-js/src/autogen/endpoint.ts4
-rw-r--r--packages/misskey-js/src/autogen/entities.ts1
-rw-r--r--packages/misskey-js/src/autogen/models.ts4
-rw-r--r--packages/misskey-js/src/autogen/types.ts360
-rw-r--r--packages/misskey-js/src/consts.ts7
-rw-r--r--packages/misskey-js/src/entities.ts3
-rw-r--r--packages/misskey-js/src/streaming.types.ts1
-rw-r--r--packages/misskey-reversi/package.json6
-rw-r--r--packages/sw/package.json6
-rw-r--r--pnpm-lock.yaml2656
187 files changed, 5046 insertions, 2988 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 32c9bd0aec..15028e7008 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,44 @@
-->
+## 2024.3.0
+
+### General
+- Enhance: 投稿者ã®ãƒ­ãƒ¼ãƒ«ã«å¿œã˜ã¦ã€ä¸€ã¤ã®ãƒŽãƒ¼ãƒˆã«å«ã‚€ã“ã¨ã®ã§ãるメンションã¨ãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆæŠ•稿ã®å®›å…ˆã®äººæ•°ã«ä¸Šé™ã‚’設定ã§ãるよã†ã«
+ * デフォルトã®ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³ä¸Šé™ã¯20アカウントã«è¨­å®šã•れã¾ã™ã€‚(管ç†è€…ã¯ãƒ™ãƒ¼ã‚¹ãƒ­ãƒ¼ãƒ«ã®è¨­å®šã§å¤‰æ›´å¯èƒ½ã§ã™ã€‚)
+ * 連åˆã®å•ã„åˆã‚ã›ã«å¿œç­”ã—ãªã„サーãƒãƒ¼ã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ¦ãƒ¼ã‚¶ãƒ¼ã¸ã®ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³ã¯ã€ä¸Šé™ã®äººæ•°ã«å«ã‚ãªã„実装ã«ãªã£ã¦ã„ã¾ã™ã€‚
+- Enhance: 通知ãŒãƒŸãƒ¥ãƒ¼ãƒˆã€å‡çµã‚’考慮ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã—ãŸ
+- Enhance: サーãƒãƒ¼ã”ã¨ã«ãƒ¢ãƒ‡ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãƒŽãƒ¼ãƒˆã‚’残ã›ã‚‹ã‚ˆã†ã«
+- Enhance: ã‚³ãƒ³ãƒ‡ã‚£ã‚·ãƒ§ãƒŠãƒ«ãƒ­ãƒ¼ãƒ«ã®æ¡ä»¶ã«ã€Œãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ãƒ­ãƒ¼ãƒ«ã¸ã®ã‚¢ã‚µã‚¤ãƒ³ã€ã‚’追加
+- Enhance: 通知ã®å—信設定ã«ã€Œãƒ•ォロー中ã¾ãŸã¯ãƒ•ォロワーã€ã‚’追加
+- Enhance: 通知ã®å±¥æ­´ã‚’リセットã§ãるよã†ã«
+- Fix: ダイレクトãªãƒŽãƒ¼ãƒˆã«å¯¾ã—ã¦ã¯ãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã§ã—ã‹è¿”ä¿¡ã§ããªã„よã†ã«
+
+### Client
+- Enhance: ノート作æˆç”»é¢ã®ãƒ•ァイル添付メニューã®åŒºåˆ‡ã‚Šç·šã®ä½ç½®ã‚’調整
+- Fix: syuilo/misskeyã®æ™‚代ã‹ã‚‰ã‚ã‚‹ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒæ”¹å¤‰ã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã‚ã‚‹ã¨èª¤èªè­˜ã•れるå•題
+- Fix: MFMã®ã‚ªãƒ¼ãƒˆã‚³ãƒ³ãƒ—リートãŒå‡ºã‚‹ã¹ã状æ³ã§å‡ºãªã„ã“ã¨ãŒã‚ã‚‹å•題を修正
+- Fix: ãƒãƒ£ãƒ¼ãƒˆã®ãƒ©ãƒ™ãƒ«ãŒæ¶ˆãˆã¦ã„ã‚‹å•題を修正
+- Fix: ç”»é¢è¡¨ç¤ºå¾Œæœ€åˆã®éŸ³å£°å†ç”ŸãŒçˆ†éŸ³ã«ãªã‚‹ã“ã¨ãŒã‚ã‚‹å•題を修正
+- Fix: 設定ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ä½œæˆæ™‚ã«åå‰ã‚’入力ã—ãªã‹ã£ãŸå ´åˆã€ãƒ­ãƒ¼ã‚«ãƒ©ã‚¤ã‚¼ãƒ¼ã‚·ãƒ§ãƒ³ãŒãŠã‹ã—ããªã‚‹å•題を修正
+- Fix: ページ`/admin/emojis`ã®çµµæ–‡å­—編集ダイアログã§ã€Œãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¨ã—ã¦ä½¿ãˆã‚‹ãƒ­ãƒ¼ãƒ«ã€ã‚’追加ã™ã‚‹éš›ã«ä½•ã‚‚é¸æŠžã›ãšOKを押下ã™ã‚‹ã¨ç”»é¢ãŒå›ºã¾ã‚‹å•題を修正
+- Fix: 絵文字サジェストã®é †ä½ã§ã€çµµæ–‡å­—自体ã®åå‰ãŒåŒã˜ã‚‚ã®ã‚ˆã‚Šã‚‚ã‚¿ã‚°ã§ä¸€è‡´ã—ã¦ã„ã‚‹ã‚‚ã®ãŒå„ªå…ˆã•れã¦ã—ã¾ã†å•題を修正
+- Fix: ãƒ¦ãƒ¼ã‚¶ã®æƒ…å ±ã®ãƒãƒƒãƒ—ã‚¢ãƒƒãƒ—ãŒæ¶ˆãˆãªããªã‚‹ã“ã¨ãŒã‚ã‚‹å•題を修正
+
+### Server
+- Enhance: エンドãƒã‚¤ãƒ³ãƒˆ`flash/update`ã®`flashId`以外ã®ãƒ‘ラメータã¯å¿…é ˆã§ã¯ãªããªã‚Šã¾ã—ãŸ
+- Fix: nodeinfoã«enableMcaptchaã¨enableTurnstileãŒç„¡ã„ã®ã‚’修正
+- Fix: ç ´æã—ãŸé€šçŸ¥ã‚’クライアントã«é€ä¿¡ã—ãªã„よã†ã«
+ * 通知欄ãŒç„¡é™ã«ãƒªãƒ­ãƒ¼ãƒ‰ã•れるå•é¡ŒãŒæ”¹å–„ã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™
+- Fix: ç¦æ­¢ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’å«ã‚€ãƒŽãƒ¼ãƒˆãŒDelayed Queueã«è¿½åŠ ã•れã¦å†å‡¦ç†ã•れるå•題を修正
+- Fix: 自分ãŒãƒ•ォローã—ã¦ã„ãªã„アカウントã®ãƒ•ォロワーé™å®šãƒŽãƒ¼ãƒˆãŒé–²è¦§ã§ãã‚‹ã“ã¨ãŒã‚ã‚‹å•題を修正
+- Fix: タイムラインã®ã‚ªãƒ—ションã§ã€ŒãƒªãƒŽãƒ¼ãƒˆã‚’表示ã€ã‚’無効ã«ã—ã¦ã„ã‚‹éš›ã€æŠ•ç¥¨ã®ã¿ã®å¼•ç”¨ãƒªãƒŽãƒ¼ãƒˆãŒæµã‚Œã¦ã“ãªã„å•題を修正
+- Fix: エンドãƒã‚¤ãƒ³ãƒˆ`admin/emoji/update`ã®å„種修正
+ - 必須パラメータを`id`ã¾ãŸã¯`name`ã®ã„ãšã‚Œã‹ã®ã¿ã«
+ - `id`ã®ä»£ã‚りã«`name`ã§çµµæ–‡å­—を指定å¯èƒ½ã«ï¼ˆ`id`・`name`両指定時ã¯å¾“æ¥é€šã‚Š`name`を変更ã™ã‚‹æŒ™å‹•)
+ - `category`ãŠã‚ˆã³`licence`ãŒæŒ‡å®šãªã—ã®æ™‚勿‰‹ã«nullã«ä¸Šæ›¸ãã•れる挙動を修正
+- Fix: 通知ã®å—信設定ã§ã€Œç›¸äº’フォローã€ãŒæ­£ã—ã動作ã—ãªã„å•題を修正
+
## 2024.2.0
### Note
diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml
index b0f7408587..17c8f24fa5 100644
--- a/locales/ar-SA.yml
+++ b/locales/ar-SA.yml
@@ -1014,6 +1014,7 @@ renotes: "أعد النشر"
sourceCode: "Ø§Ù„Ø´ÙØ±Ø© المصدرية"
flip: "اقلب"
lastNDays: "آخر {n} أيام"
+surrender: "ألغÙ"
_initialAccountSetting:
accountCreated: "نجح إنشاء حسابك!"
letsStartAccountSetup: "إذا كنت جديدًا لنعدّ حسابك الشخصي."
diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml
index af5329dc7e..2ea6bd9309 100644
--- a/locales/ca-ES.yml
+++ b/locales/ca-ES.yml
@@ -1210,6 +1210,7 @@ hemisphere: "Geolocalització"
withSensitive: "Incloure notes amb fitxers sensibles"
userSaysSomethingSensitive: "La publicació de {name} conte material sensible"
enableHorizontalSwipe: "Lliscar per canviar de pestanya"
+surrender: "Cancel·lar "
_bubbleGame:
howToPlay: "Com es juga"
_howToPlay:
diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml
index 3161ff275a..cbf5c33c18 100644
--- a/locales/cs-CZ.yml
+++ b/locales/cs-CZ.yml
@@ -1098,6 +1098,7 @@ renotes: "Přeposlat"
sourceCode: "Zdrojový kód"
flip: "OtoÄit"
lastNDays: "Posledních {n} dnů"
+surrender: "Zrušit"
_initialAccountSetting:
accountCreated: "Váš úÄet byl úspěšnÄ› vytvoÅ™en!"
letsStartAccountSetup: "Pro zaÄátek si nastavte svůj profil."
diff --git a/locales/de-DE.yml b/locales/de-DE.yml
index f733fa1ee9..9a22a7b445 100644
--- a/locales/de-DE.yml
+++ b/locales/de-DE.yml
@@ -1184,6 +1184,7 @@ decorate: "Dekorieren"
addMfmFunction: "MFM hinzufügen"
sfx: "Soundeffekte"
lastNDays: "Letzten {n} Tage"
+surrender: "Abbrechen"
_announcement:
forExistingUsers: "Nur für existierende Nutzer"
forExistingUsersDescription: "Ist diese Option aktiviert, wird diese Ankündigung nur Nutzern angezeigt, die zum Zeitpunkt der Ankündigung bereits registriert sind. Ist sie deaktiviert, wird sie auch Nutzern, die sich nach dessen Veröffentlichung registrieren, angezeigt."
diff --git a/locales/en-US.yml b/locales/en-US.yml
index 084f6b23b9..d00f23632c 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -991,6 +991,7 @@ neverShow: "Don't show again"
remindMeLater: "Maybe later"
didYouLikeMisskey: "Have you taken a liking to Misskey?"
pleaseDonate: "{host} uses the free software, Misskey. We would highly appreciate your donations so development of Misskey can continue!"
+correspondingSourceIsAvailable: "The corresponding source code is available at {anchor}"
roles: "Roles"
role: "Role"
noRole: "Role not found"
@@ -1041,6 +1042,8 @@ resetPasswordConfirm: "Really reset your password?"
sensitiveWords: "Sensitive words"
sensitiveWordsDescription: "The visibility of all notes containing any of the configured words will be set to \"Home\" automatically. You can list multiple by separating them via line breaks."
sensitiveWordsDescription2: "Using spaces will create AND expressions and surrounding keywords with slashes will turn them into a regular expression."
+prohibitedWords: "Prohibited words"
+prohibitedWordsDescription: "Enables an error when attempting to post a note containing the set word(s). Multiple words can be set, separated by a new line."
prohibitedWordsDescription2: "Using spaces will create AND expressions and surrounding keywords with slashes will turn them into a regular expression."
hiddenTags: "Hidden hashtags"
hiddenTagsDescription: "Select tags which will not shown on trend list.\nMultiple tags could be registered by lines."
@@ -1157,6 +1160,7 @@ showRenotes: "Show renotes"
edited: "Edited"
notificationRecieveConfig: "Notification Settings"
mutualFollow: "Mutual follow"
+followingOrFollower: "Following or follower"
fileAttachedOnly: "Only notes with files"
showRepliesToOthersInTimeline: "Show replies to others in timeline"
hideRepliesToOthersInTimeline: "Hide replies to others from timeline"
@@ -1166,6 +1170,12 @@ confirmShowRepliesAll: "This operation is irreversible. Would you really like to
confirmHideRepliesAll: "This operation is irreversible. Would you really like to hide replies to others from everyone you follow in your timeline?"
externalServices: "External Services"
sourceCode: "Source code"
+sourceCodeIsNotYetProvided: "Source code is not yet available. Contact the administrator to fix this problem."
+repositoryUrl: "Repository URL"
+repositoryUrlDescription: "If you are using Misskey as is (without any changes to the source code), enter https://github.com/misskey-dev/misskey"
+repositoryUrlOrTarballRequired: "If you have not published a repository, you must provide a tarball instead. See .config/example.yml for more information."
+feedback: "Feedback"
+feedbackUrl: "Feedback URL"
impressum: "Impressum"
impressumUrl: "Impressum URL"
impressumDescription: "In some countries, like germany, the inclusion of operator contact information (an Impressum) is legally required for commercial websites."
@@ -1201,6 +1211,8 @@ soundWillBePlayed: "Sound will be played"
showReplay: "View Replay"
replay: "Replay"
replaying: "Showing replay"
+endReplay: "Exit Replay"
+copyReplayData: "Copy replay data"
ranking: "Ranking"
lastNDays: "Last {n} days"
backToTitle: "Go back to title"
@@ -1208,8 +1220,20 @@ hemisphere: "Where are you located"
withSensitive: "Include notes with sensitive files"
userSaysSomethingSensitive: "Post by {name} contains sensitive content"
enableHorizontalSwipe: "Swipe to switch tabs"
+loading: "Loading"
+surrender: "Cancel"
+gameRetry: "Retry"
_bubbleGame:
howToPlay: "How to play"
+ hold: "Hold"
+ _score:
+ score: "Score"
+ scoreYen: "Amount of money earned"
+ highScore: "High score"
+ maxChain: "Maximum number of chains"
+ yen: "{yen} Yen"
+ estimatedQty: "{qty} Pieces"
+ scoreSweets: "{onigiriQtyWithUnit} Onigiri"
_howToPlay:
section1: "Adjust the position and drop the object into the box."
section2: "When two objects of the same type touch each other, they will change into a different object and you score points."
@@ -1631,6 +1655,7 @@ _role:
gtlAvailable: "Can view the global timeline"
ltlAvailable: "Can view the local timeline"
canPublicNote: "Can send public notes"
+ mentionMax: "Maximum number of mentions in a note"
canInvite: "Can create instance invite codes"
inviteLimit: "Invite limit"
inviteLimitCycle: "Invite limit cooldown"
@@ -1654,6 +1679,7 @@ _role:
canUseTranslator: "Translator usage"
avatarDecorationLimit: "Maximum number of avatar decorations that can be applied"
_condition:
+ roleAssignedTo: "Assigned to manual roles"
isLocal: "Local user"
isRemote: "Remote user"
createdLessThan: "Less than X has passed since account creation"
@@ -1754,6 +1780,8 @@ _aboutMisskey:
contributors: "Main contributors"
allContributors: "All contributors"
source: "Source code"
+ original: "Original"
+ thisIsModifiedVersion: "{name} uses a modified version of the original Misskey."
translation: "Translate Misskey"
donate: "Donate to Misskey"
morePatrons: "We also appreciate the support of many other helpers not listed here. Thank you! 🥰"
@@ -2272,6 +2300,7 @@ _notification:
reactedBySomeUsers: "{n} users reacted"
renotedBySomeUsers: "Renote from {n} users"
followedBySomeUsers: "Followed by {n} users"
+ flushNotification: "Clear notifications"
_types:
all: "All"
note: "New notes"
@@ -2369,6 +2398,7 @@ _moderationLogTypes:
resetPassword: "Password reset"
suspendRemoteInstance: "Remote instance suspended"
unsuspendRemoteInstance: "Remote instance unsuspended"
+ updateRemoteInstanceNote: "Moderation note updated for remote instance."
markSensitiveDriveFile: "File marked as sensitive"
unmarkSensitiveDriveFile: "File unmarked as sensitive"
resolveAbuseReport: "Report resolved"
@@ -2489,6 +2519,8 @@ _reversi:
opponentHasSettingsChanged: "The opponent has changed their settings."
allowIrregularRules: "Irregular rules (completely free)"
disallowIrregularRules: "No irregular rules"
+ showBoardLabels: "Display row and column numbering on the board"
+ useAvatarAsStone: "Turn stones into user avatars"
_offlineScreen:
title: "Offline - cannot connect to the server"
header: "Unable to connect to the server"
diff --git a/locales/es-ES.yml b/locales/es-ES.yml
index 2952e89f83..246ec23604 100644
--- a/locales/es-ES.yml
+++ b/locales/es-ES.yml
@@ -1209,6 +1209,7 @@ hemisphere: "Región"
withSensitive: "Mostrar notas que contengan material sensible"
userSaysSomethingSensitive: "La publicación de {name} contiene material sensible"
enableHorizontalSwipe: "Deslice para cambiar de pestaña"
+surrender: "detener"
_bubbleGame:
howToPlay: "Cómo jugar"
_howToPlay:
diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml
index 35fac49cdd..b7ab4d37c4 100644
--- a/locales/fr-FR.yml
+++ b/locales/fr-FR.yml
@@ -1164,7 +1164,11 @@ remainingN: "Restants : {n}"
overwriteContentConfirm: "Voulez-vous remplacer le contenu actuel ?"
seasonalScreenEffect: "Effet d'écran saisonnier"
decorate: "Décorer"
+sfx: "Effets sonores"
+showReplay: "Voir le replay"
+ranking: "Classement"
lastNDays: "Derniers {n} jours"
+surrender: "Annuler"
_announcement:
forExistingUsers: "Pour les utilisateurs existants seulement"
readConfirmTitle: "Marquer comme lu ?"
@@ -1302,10 +1306,13 @@ _achievements:
title: "Régulier III"
description: "Se connecter pour un total de 400 jours"
_login500:
+ title: "Expert I"
description: "Se connecter pour un total de 500 jours"
_login600:
+ title: "Expert II"
description: "Se connecter pour un total de 600 jours"
_login700:
+ title: "Expert III"
description: "Se connecter pour un total de 700 jours"
_login800:
description: "Se connecter pour un total de 800 jours"
@@ -1400,9 +1407,12 @@ _role:
description: "Description du rôle"
permission: "Rôle et autorisations"
assignTarget: "Attribuer"
+ manual: "Manuel"
manualRoles: "Rôles manuels"
+ conditional: "Conditionnel"
conditionalRoles: "Rôles conditionnels"
condition: "Condition"
+ isConditionalRole: "Ceci est un rôle conditionnel."
isPublic: "Rôle public"
options: "Options"
policies: "Stratégies"
diff --git a/locales/id-ID.yml b/locales/id-ID.yml
index 58a248996b..514a2866ca 100644
--- a/locales/id-ID.yml
+++ b/locales/id-ID.yml
@@ -1209,6 +1209,7 @@ hemisphere: "Letak kamu tinggal"
withSensitive: "Lampirkan catatan dengan berkas sensitif"
userSaysSomethingSensitive: "Postingan oleh {name} mengandung konten sensitif"
enableHorizontalSwipe: "Geser untuk mengganti tab"
+surrender: "Batalkan"
_bubbleGame:
howToPlay: "Cara bermain"
_howToPlay:
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 1bc99ab849..c1aa163f98 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -4657,6 +4657,10 @@ export interface Locale extends ILocale {
*/
"mutualFollow": string;
/**
+ * フォロー中ã¾ãŸã¯ãƒ•ォロワー
+ */
+ "followingOrFollower": string;
+ /**
* ファイル付ãã®ã¿
*/
"fileAttachedOnly": string;
@@ -4857,6 +4861,14 @@ export interface Locale extends ILocale {
*/
"replaying": string;
/**
+ * リプレイを終了
+ */
+ "endReplay": string;
+ /**
+ * リプレイデータをコピー
+ */
+ "copyReplayData": string;
+ /**
* ランキング
*/
"ranking": string;
@@ -4884,11 +4896,57 @@ export interface Locale extends ILocale {
* スワイプã—ã¦ã‚¿ãƒ–を切り替ãˆã‚‹
*/
"enableHorizontalSwipe": string;
+ /**
+ * 読ã¿è¾¼ã¿ä¸­
+ */
+ "loading": string;
+ /**
+ * ã‚„ã‚ã‚‹
+ */
+ "surrender": string;
+ /**
+ * リトライ
+ */
+ "gameRetry": string;
"_bubbleGame": {
/**
* éŠã³æ–¹
*/
"howToPlay": string;
+ /**
+ * ホールド
+ */
+ "hold": string;
+ "_score": {
+ /**
+ * スコア
+ */
+ "score": string;
+ /**
+ * 稼ã„ã é‡‘é¡
+ */
+ "scoreYen": string;
+ /**
+ * ãƒã‚¤ã‚¹ã‚³ã‚¢
+ */
+ "highScore": string;
+ /**
+ * 最大ãƒã‚§ãƒ¼ãƒ³æ•°
+ */
+ "maxChain": string;
+ /**
+ * {yen}円
+ */
+ "yen": ParameterizedString<"yen">;
+ /**
+ * {qty}個分
+ */
+ "estimatedQty": ParameterizedString<"qty">;
+ /**
+ * ãŠã«ãŽã‚Š {onigiriQtyWithUnit}
+ */
+ "scoreSweets": ParameterizedString<"onigiriQtyWithUnit">;
+ };
"_howToPlay": {
/**
* ä½ç½®ã‚’調整ã—ã¦ãƒã‚³ã«ãƒ¢ãƒŽã‚’è½ã¨ã—ã¾ã™ã€‚
@@ -6385,6 +6443,10 @@ export interface Locale extends ILocale {
*/
"canPublicNote": string;
/**
+ * ãƒŽãƒ¼ãƒˆå†…ã®æœ€å¤§ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³æ•°
+ */
+ "mentionMax": string;
+ /**
* サーãƒãƒ¼æ‹›å¾…コードã®ç™ºè¡Œ
*/
"canInvite": string;
@@ -6475,6 +6537,10 @@ export interface Locale extends ILocale {
};
"_condition": {
/**
+ * マニュアルロールã«ã‚¢ã‚µã‚¤ãƒ³æ¸ˆã¿
+ */
+ "roleAssignedTo": string;
+ /**
* ローカルユーザー
*/
"isLocal": string;
@@ -8851,6 +8917,10 @@ export interface Locale extends ILocale {
* {n}人ã«ãƒ•ォローã•れã¾ã—ãŸ
*/
"followedBySomeUsers": ParameterizedString<"n">;
+ /**
+ * 通知ã®å±¥æ­´ã‚’リセットã™ã‚‹
+ */
+ "flushNotification": string;
"_types": {
/**
* ã™ã¹ã¦
@@ -9172,7 +9242,7 @@ export interface Locale extends ILocale {
*/
"updateServerSettings": string;
/**
- * モデレーションノート更新
+ * ユーザーã®ãƒ¢ãƒ‡ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãƒŽãƒ¼ãƒˆæ›´æ–°
*/
"updateUserNote": string;
/**
@@ -9220,6 +9290,10 @@ export interface Locale extends ILocale {
*/
"unsuspendRemoteInstance": string;
/**
+ * リモートサーãƒãƒ¼ã®ãƒ¢ãƒ‡ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãƒŽãƒ¼ãƒˆæ›´æ–°
+ */
+ "updateRemoteInstanceNote": string;
+ /**
* ファイルをセンシティブ付与
*/
"markSensitiveDriveFile": string;
@@ -9655,6 +9729,14 @@ export interface Locale extends ILocale {
* 変則ãªã—
*/
"disallowIrregularRules": string;
+ /**
+ * 盤é¢ã«è¡Œãƒ»åˆ—番å·ã‚’表示
+ */
+ "showBoardLabels": string;
+ /**
+ * 石をアイコンã«ã™ã‚‹
+ */
+ "useAvatarAsStone": string;
};
"_offlineScreen": {
/**
diff --git a/locales/it-IT.yml b/locales/it-IT.yml
index 378036af6d..480d11b6ba 100644
--- a/locales/it-IT.yml
+++ b/locales/it-IT.yml
@@ -991,6 +991,7 @@ neverShow: "Non mostrare più"
remindMeLater: "Rimanda"
didYouLikeMisskey: "Ti piace Misskey?"
pleaseDonate: "Misskey è il software libero utilizzato su {host}. Offrendo una donazione è più facile continuare a svilupparlo!"
+correspondingSourceIsAvailable: ""
roles: "Ruoli"
role: "Ruolo"
noRole: "Ruolo non trovato"
@@ -1168,6 +1169,12 @@ confirmShowRepliesAll: "Questa è una attività irreversibile. Vuoi davvero incl
confirmHideRepliesAll: "Questa è una attività irreversibile. Vuoi davvero escludere tutte le risposte dei following in TL?"
externalServices: "Servizi esterni"
sourceCode: "Codice sorgente"
+sourceCodeIsNotYetProvided: ""
+repositoryUrl: "URL della repository"
+repositoryUrlDescription: "Se esiste un repository il cui il codice sorgente è disponibile pubblicamente, inserisci il suo URL. Se stai utilizzando Misskey così com'è (senza alcuna modifica al codice sorgente), inserisci https://github.com/misskey-dev/misskey."
+repositoryUrlOrTarballRequired: "Se non disponi di un repository pubblico, dovrai fornire un file tarball (tar). Vedere .config/example.yml per i dettagli."
+feedback: "Feedback"
+feedbackUrl: "URL di feedback"
impressum: "Dichiarazione di proprietà"
impressumUrl: "URL della dichiarazione di proprietà"
impressumDescription: "La dichiarazione di proprietà, è obbligatoria in alcuni paesi come la Germania (Impressum)."
@@ -1199,7 +1206,7 @@ addMfmFunction: "Aggiungi decorazioni"
enableQuickAddMfmFunction: "Attiva il selettore di funzioni MFM"
bubbleGame: "Bubble Game"
sfx: "Effetti sonori"
-soundWillBePlayed: "Verrà riprodotto il suono"
+soundWillBePlayed: "Con musica ed effetti sonori"
showReplay: "Vedi i replay"
replay: "Replay"
replaying: "Replay in corso"
@@ -1210,12 +1217,13 @@ hemisphere: "Geolocalizzazione"
withSensitive: "Mostra le Note con allegati espliciti"
userSaysSomethingSensitive: "Note da {name} con allegati espliciti"
enableHorizontalSwipe: "Trascina per invertire i tab"
+surrender: "Annulla"
_bubbleGame:
howToPlay: "Come giocare"
_howToPlay:
- section1: "Regola la posizione e rilascia l'oggetto nella casella."
- section2: "Ottieni un punteggio, quando due oggetti dello stesso tipo si toccano e si trasformano in un oggetto diverso."
- section3: "Se gli oggetti traboccano dalla scatola, il gioco finisce. Cerca di ottenere un punteggio elevato fondendo gli oggetti, evitando che escano dalla scatola!"
+ section1: "Scegli la posizione e rilascia l'oggetto nel contenitore."
+ section2: "Se due oggetti dello stesso tipo si toccano, si trasformano in un oggetto diverso, aumentando il punteggio."
+ section3: "Se gli oggetti escono dal limite superiore del contenitore, il gioco finisce. Cerca di ottenere un punteggio elevato fondendo gli oggetti, evitando che escano dal contenitore!"
_announcement:
forExistingUsers: "Solo ai profili attuali"
forExistingUsersDescription: "L'annuncio sarà visibile solo ai profili esistenti in questo momento. Se disabilitato, sarà visibile anche ai profili che verranno creati dopo la pubblicazione di questo annuncio."
@@ -1756,6 +1764,8 @@ _aboutMisskey:
contributors: "Principali sostenitori"
allContributors: "Tutti i sostenitori"
source: "Codice sorgente"
+ original: "Originale"
+ thisIsModifiedVersion: "{name} sta usando una versione modificata diversa da Misskey originale."
translation: "Tradurre Misskey"
donate: "Sostieni Misskey"
morePatrons: "Apprezziamo sinceramente il supporto di tante altre persone. Grazie mille! 🥰"
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 5993ec80d0..51380e49c5 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1160,6 +1160,7 @@ showRenotes: "リノートを表示"
edited: "編集済ã¿"
notificationRecieveConfig: "通知ã®å—信設定"
mutualFollow: "相互フォロー"
+followingOrFollower: "フォロー中ã¾ãŸã¯ãƒ•ォロワー"
fileAttachedOnly: "ファイル付ãã®ã¿"
showRepliesToOthersInTimeline: "TLã«ä»–ã®äººã¸ã®è¿”ä¿¡ã‚’å«ã‚ã‚‹"
hideRepliesToOthersInTimeline: "TLã«ä»–ã®äººã¸ã®è¿”ä¿¡ã‚’å«ã‚ãªã„"
@@ -1210,6 +1211,8 @@ soundWillBePlayed: "サウンドãŒå†ç”Ÿã•れã¾ã™"
showReplay: "リプレイを見る"
replay: "リプレイ"
replaying: "リプレイ中"
+endReplay: "リプレイを終了"
+copyReplayData: "リプレイデータをコピー"
ranking: "ランキング"
lastNDays: "ç›´è¿‘{n}æ—¥"
backToTitle: "タイトルã¸"
@@ -1217,9 +1220,21 @@ hemisphere: "ãŠä½ã¾ã„ã®åœ°åŸŸ"
withSensitive: "センシティブãªãƒ•ァイルをå«ã‚€ãƒŽãƒ¼ãƒˆã‚’表示"
userSaysSomethingSensitive: "{name}ã®ã‚»ãƒ³ã‚·ãƒ†ã‚£ãƒ–ãªãƒ•ァイルをå«ã‚€æŠ•稿"
enableHorizontalSwipe: "スワイプã—ã¦ã‚¿ãƒ–を切り替ãˆã‚‹"
+loading: "読ã¿è¾¼ã¿ä¸­"
+surrender: "ã‚„ã‚ã‚‹"
+gameRetry: "リトライ"
_bubbleGame:
howToPlay: "éŠã³æ–¹"
+ hold: "ホールド"
+ _score:
+ score: "スコア"
+ scoreYen: "稼ã„ã é‡‘é¡"
+ highScore: "ãƒã‚¤ã‚¹ã‚³ã‚¢"
+ maxChain: "最大ãƒã‚§ãƒ¼ãƒ³æ•°"
+ yen: "{yen}円"
+ estimatedQty: "{qty}個分"
+ scoreSweets: "ãŠã«ãŽã‚Š {onigiriQtyWithUnit}"
_howToPlay:
section1: "ä½ç½®ã‚’調整ã—ã¦ãƒã‚³ã«ãƒ¢ãƒŽã‚’è½ã¨ã—ã¾ã™ã€‚"
section2: "åŒã˜ç¨®é¡žã®ãƒ¢ãƒŽãŒãã£ã¤ãã¨åˆ¥ã®ãƒ¢ãƒŽã«å¤‰åŒ–ã—ã¦ã€ã‚¹ã‚³ã‚¢ãŒå¾—られã¾ã™ã€‚"
@@ -1650,6 +1665,7 @@ _role:
gtlAvailable: "グローãƒãƒ«ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ã®é–²è¦§"
ltlAvailable: "ローカルタイムラインã®é–²è¦§"
canPublicNote: "パブリック投稿ã®è¨±å¯"
+ mentionMax: "ãƒŽãƒ¼ãƒˆå†…ã®æœ€å¤§ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³æ•°"
canInvite: "サーãƒãƒ¼æ‹›å¾…コードã®ç™ºè¡Œ"
inviteLimit: "招待コードã®ä½œæˆå¯èƒ½æ•°"
inviteLimitCycle: "招待コードã®ç™ºè¡Œé–“éš”"
@@ -1673,6 +1689,7 @@ _role:
canUseTranslator: "翻訳機能ã®åˆ©ç”¨"
avatarDecorationLimit: "ã‚¢ã‚¤ã‚³ãƒ³ãƒ‡ã‚³ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®æœ€å¤§å–付個数"
_condition:
+ roleAssignedTo: "マニュアルロールã«ã‚¢ã‚µã‚¤ãƒ³æ¸ˆã¿"
isLocal: "ローカルユーザー"
isRemote: "リモートユーザー"
createdLessThan: "アカウント作æˆã‹ã‚‰ï½žä»¥å†…"
@@ -2340,6 +2357,7 @@ _notification:
reactedBySomeUsers: "{n}人ãŒãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã—ã¾ã—ãŸ"
renotedBySomeUsers: "{n}人ãŒãƒªãƒŽãƒ¼ãƒˆã—ã¾ã—ãŸ"
followedBySomeUsers: "{n}人ã«ãƒ•ォローã•れã¾ã—ãŸ"
+ flushNotification: "通知ã®å±¥æ­´ã‚’リセットã™ã‚‹"
_types:
all: "ã™ã¹ã¦"
@@ -2434,7 +2452,7 @@ _moderationLogTypes:
updateCustomEmoji: "カスタム絵文字更新"
deleteCustomEmoji: "カスタム絵文字削除"
updateServerSettings: "サーãƒãƒ¼è¨­å®šæ›´æ–°"
- updateUserNote: "モデレーションノート更新"
+ updateUserNote: "ユーザーã®ãƒ¢ãƒ‡ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãƒŽãƒ¼ãƒˆæ›´æ–°"
deleteDriveFile: "ファイルを削除"
deleteNote: "ノートを削除"
createGlobalAnnouncement: "全体ã®ãŠçŸ¥ã‚‰ã›ã‚’作æˆ"
@@ -2446,6 +2464,7 @@ _moderationLogTypes:
resetPassword: "パスワードをリセット"
suspendRemoteInstance: "リモートサーãƒãƒ¼ã‚’åœæ­¢"
unsuspendRemoteInstance: "リモートサーãƒãƒ¼ã‚’å†é–‹"
+ updateRemoteInstanceNote: "リモートサーãƒãƒ¼ã®ãƒ¢ãƒ‡ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãƒŽãƒ¼ãƒˆæ›´æ–°"
markSensitiveDriveFile: "ファイルをセンシティブ付与"
unmarkSensitiveDriveFile: "ファイルをセンシティブ解除"
resolveAbuseReport: "通報を解決"
@@ -2571,6 +2590,8 @@ _reversi:
opponentHasSettingsChanged: "相手ãŒè¨­å®šã‚’変更ã—ã¾ã—ãŸ"
allowIrregularRules: "å¤‰å‰‡è¨±å¯ (完全フリー)"
disallowIrregularRules: "変則ãªã—"
+ showBoardLabels: "盤é¢ã«è¡Œãƒ»åˆ—番å·ã‚’表示"
+ useAvatarAsStone: "石をアイコンã«ã™ã‚‹"
_offlineScreen:
title: "オフライン - サーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml
index 4b5f98e803..7ff26c757d 100644
--- a/locales/ja-KS.yml
+++ b/locales/ja-KS.yml
@@ -991,6 +991,7 @@ neverShow: "今後表示ã—ãªã„"
remindMeLater: "ã¾ãŸå¾Œã§"
didYouLikeMisskey: "Misskeyæ°—ã«å…¥ã£ã¦ãれãŸï¼Ÿ"
pleaseDonate: "Misskeyã¯{host}ãŒä½¿ã†ã¨ã‚‹ç„¡æ–™ã®ã‚½ãƒ•トウェアやã§ã€‚ã“れã‹ã‚‰ã‚‚開発を続ã‘れるよã†ã«ã€å¯„付ã—ãŸã£ã¦ãªï½žã€‚"
+correspondingSourceIsAvailable: "{anchor}"
roles: "ロール"
role: "ロール"
noRole: "ロールã¯ã‚りã¾ã¸ã‚“"
@@ -1208,6 +1209,7 @@ hemisphere: "ä½ã‚“ã§ã‚‹åœ°åŸŸ"
withSensitive: "センシティブãªãƒ•ァイルをå«ã‚€ãƒŽãƒ¼ãƒˆã‚’表示"
userSaysSomethingSensitive: "{name}ã®ã‚»ãƒ³ã‚·ãƒ†ã‚£ãƒ–ãªãƒ•ァイルをå«ã‚€æŠ•稿"
enableHorizontalSwipe: "スワイプã—ã¦ã‚¿ãƒ–を切り替ãˆã‚‹"
+surrender: "ã‚„ã‚ã¨ã"
_bubbleGame:
howToPlay: "éŠã³æ–¹"
_howToPlay:
diff --git a/locales/ko-GS.yml b/locales/ko-GS.yml
index b1702114be..39492d902f 100644
--- a/locales/ko-GS.yml
+++ b/locales/ko-GS.yml
@@ -640,6 +640,7 @@ icon: "아바타"
replies: "답하기"
renotes: "리노트"
attach: "옇기"
+surrender: "ì•„ì´ì˜ˆ"
_initialAccountSetting:
startTutorial: "길ë¼ìž¡ì´ 하기"
_initialTutorial:
diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml
index c4646b6a86..877ae6b217 100644
--- a/locales/ko-KR.yml
+++ b/locales/ko-KR.yml
@@ -991,6 +991,7 @@ neverShow: "다시 보지 않기"
remindMeLater: "ë‚˜ì¤‘ì— ì•Œë¦¼"
didYouLikeMisskey: "Misskeyê°€ 마ìŒì— 드시나요?"
pleaseDonate: "Misskey는 {host} ì„œë²„ì˜ ë¬´ë£Œ 소프트웨어입니다. ì•žìœ¼ë¡œë„ ê°œë°œì„ ì´ì–´ 나가려면 후ì›ì´ 절실히 필요합니다!"
+correspondingSourceIsAvailable: "소스 코드는 {anchor}ì—서 받아보실 수 있습니다."
roles: "ì—­í• "
role: "ì—­í• "
noRole: "ì—­í• ì´ ì—†ìŠµë‹ˆë‹¤"
@@ -1168,6 +1169,12 @@ confirmShowRepliesAll: "ì´ ì¡°ìž‘ì€ ë˜ëŒë¦´ 수 없습니다. ì •ë§ë¡œ 타ì
confirmHideRepliesAll: "ì´ ì¡°ìž‘ì€ ë˜ëŒë¦´ 수 없습니다. ì •ë§ë¡œ 타임ë¼ì¸ì— 현재 팔로우 ì¤‘ì¸ ì‚¬ëžŒ ì „ì›ì˜ ë‹µê¸€ì´ ë‚˜ì˜¤ì§€ 않게 하시겠습니까?"
externalServices: "외부 서비스"
sourceCode: "소스 코드"
+sourceCodeIsNotYetProvided: "소스 코드를 ì•„ì§ ì œê³µí•˜ì§€ 않습니다. ì´ ë¬¸ì œë¥¼ 해결하려면 관리ìžì—게 문ì˜í•´ 주세요."
+repositoryUrl: "저장소 URL"
+repositoryUrlDescription: "소스 코드를 공개한 저장소가 있는 경우, ê·¸ URLì„ ì ìŠµë‹ˆë‹¤. Misskey를 ì›ë³¸ 그대로 (소스 코드를 ì–´ë–¤ ì‹ìœ¼ë¡œë„ 변경하지 않고) ì“°ê³  있는 경우 https://github.com/misskey-dev/misskey ë¼ê³  ì ìŠµë‹ˆë‹¤."
+repositoryUrlOrTarballRequired: "저장소를 공개하지 ì•Šì€ ê²½ìš° 대신 tarballì„ ì œê³µí•  필요가 있습니다. ì„¸ë¶€ì‚¬í•­ì€ .config/example.ymlì„ ì°¸ì¡°í•´ 주세요."
+feedback: "피드백"
+feedbackUrl: "피드백 URL"
impressum: "ìš´ì˜ìž ì •ë³´"
impressumUrl: "ìš´ì˜ìž ì •ë³´ URL"
impressumDescription: "ë…ì¼ ë“±ì˜ ì¼ë¶€ 나ë¼ì™€ 지역ì—서는 ê¼­ 표시해야 합니다(Impressum)."
@@ -1210,6 +1217,7 @@ hemisphere: "거주 지역"
withSensitive: "민ê°í•œ 파ì¼ì´ í¬í•¨ëœ 노트 보기"
userSaysSomethingSensitive: "{name}ì˜ ë¯¼ê°í•œ 파ì¼ì´ í¬í•¨ëœ 게시물"
enableHorizontalSwipe: "스와ì´í”„하여 탭 전환"
+surrender: "그만ë‘기"
_bubbleGame:
howToPlay: "설명"
_howToPlay:
@@ -1756,6 +1764,8 @@ _aboutMisskey:
contributors: "주요 기여ìž"
allContributors: "모든 기여ìž"
source: "소스 코드"
+ original: "ì›ë³¸"
+ thisIsModifiedVersion: "{name}ì—서는 ì›ë³¸ 미스키를 수정한 ë²„ì „ì„ ì‚¬ìš©í•˜ê³  있습니다."
translation: "Misskey를 번역하기"
donate: "Misskeyì— ê¸°ë¶€í•˜ê¸°"
morePatrons: "ì´ ì™¸ì—ë„ ë‹¤ë¥¸ ë§Žì€ ë¶„ë“¤ì´ ë„ì›€ì„ ì£¼ì‹œê³  계십니다. ê°ì‚¬í•©ë‹ˆë‹¤ðŸ¥°"
@@ -2371,6 +2381,7 @@ _moderationLogTypes:
resetPassword: "비밀번호 재설정"
suspendRemoteInstance: "리모트 서버를 정지"
unsuspendRemoteInstance: "리모트 ì„œë²„ì˜ ì •ì§€ë¥¼ í•´ì œ"
+ updateRemoteInstanceNote: "리모트 ì„œë²„ì˜ ì¡°ì • ê¸°ë¡ ê°±ì‹ "
markSensitiveDriveFile: "파ì¼ì— 열람주ì˜ë¥¼ 설정"
unmarkSensitiveDriveFile: "파ì¼ì— 열람주ì˜ë¥¼ í•´ì œ"
resolveAbuseReport: "신고 처리"
diff --git a/locales/no-NO.yml b/locales/no-NO.yml
index 85ccd62566..098faa8add 100644
--- a/locales/no-NO.yml
+++ b/locales/no-NO.yml
@@ -463,6 +463,7 @@ options: "Alternativ"
icon: "Avatar"
replies: "Svar"
renotes: "Renote"
+surrender: "Avbryt"
_initialAccountSetting:
theseSettingsCanEditLater: "Du kan endre disse innstillingene senere."
_achievements:
diff --git a/locales/pt-PT.yml b/locales/pt-PT.yml
index bf8a8ca38b..f62557fb23 100644
--- a/locales/pt-PT.yml
+++ b/locales/pt-PT.yml
@@ -1011,6 +1011,7 @@ renotes: "Repostar"
keepScreenOn: "Manter a tela do dispositivo sempre ligada"
flip: "Inversão"
lastNDays: "Últimos {n} dias"
+surrender: "Cancelar"
_initialAccountSetting:
followUsers: "Siga usuários que lhe interessam para criar a sua linha do tempo."
_serverSettings:
diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml
index 6141eba5f0..d666b69490 100644
--- a/locales/ru-RU.yml
+++ b/locales/ru-RU.yml
@@ -1085,6 +1085,7 @@ loadReplies: "Показать ответы"
sourceCode: "ИÑходный код"
flip: "Переворот"
lastNDays: "ПоÑледние {n} Ñут"
+surrender: "Этот поÑÑ‚ не может быть отменен."
_initialAccountSetting:
accountCreated: "Ðккаунт уÑпешно Ñоздан!"
letsStartAccountSetup: "Давайте наÑтроим вашу учётную запиÑÑŒ."
diff --git a/locales/th-TH.yml b/locales/th-TH.yml
index b5a54a39ec..c0e79d5e16 100644
--- a/locales/th-TH.yml
+++ b/locales/th-TH.yml
@@ -8,12 +8,12 @@ search: "ค้นหา"
notifications: "à¸à¸²à¸£à¹€à¹€à¸ˆà¹‰à¸‡à¹€à¸•ือน"
username: "ชื่อผู้ใช้"
password: "รหัสผ่าน"
-forgotPassword: "ลืมรหัสผ่านใช่ไหม"
+forgotPassword: "ลืมรหัสผ่าน"
fetchingAsApObject: "à¸à¸³à¸¥à¸±à¸‡à¸”ึงข้อมูลจาà¸à¸ªà¸«à¸žà¸±à¸™à¸˜à¹Œ..."
ok: "ตà¸à¸¥à¸‡"
gotIt: "เข้าใจà¹à¸¥à¹‰à¸§ !"
cancel: "ยà¸à¹€à¸¥à¸´à¸"
-noThankYou: "ไม่เป็นไร"
+noThankYou: "ไม่เอาดีà¸à¸§à¹ˆà¸²"
enterUsername: "à¸à¸£à¸­à¸à¸Šà¸·à¹ˆà¸­à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰"
renotedBy: "รีโน้ตโดย {user}"
noNotes: "ไม่มีโน้ต"
@@ -31,16 +31,16 @@ login: "เข้าสู่ระบบ"
loggingIn: "à¸à¸³à¸¥à¸±à¸‡à¹€à¸‚้าสู่ระบบ"
logout: "ออà¸à¸ˆà¸²à¸à¸£à¸°à¸šà¸š"
signup: "สร้างบัà¸à¸Šà¸µà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰"
-uploading: "à¸à¸³à¸¥à¸±à¸‡à¸­à¸±à¸žà¹‚หลด..."
+uploading: "à¸à¸³à¸¥à¸±à¸‡à¸­à¸±à¸›à¹‚หลด"
save: "บันทึà¸"
users: "ผู้ใช้งาน"
addUser: "เพิ่มผู้ใช้"
favorite: "รายà¸à¸²à¸£à¹‚ปรด"
favorites: "รายà¸à¸²à¸£à¹‚ปรด"
unfavorite: "ลบออà¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸à¸²à¸£à¹‚ปรด"
-favorited: "เพิ่มà¹à¸¥à¹‰à¸§à¹ƒà¸™à¸£à¸²à¸¢à¸à¸²à¸£à¹‚ปรด"
-alreadyFavorited: "เพิ่มในรายà¸à¸²à¸£à¹‚ปรดอยู่à¹à¸¥à¹‰à¸§"
-cantFavorite: "ไม่สามารถเพิ่มในรายà¸à¸²à¸£à¹‚ปรดได้"
+favorited: "เพิ่มลงรายà¸à¸²à¸£à¹‚ปรดà¹à¸¥à¹‰à¸§"
+alreadyFavorited: "เพิ่มลงรายà¸à¸²à¸£à¹‚ปรดอยู่à¹à¸¥à¹‰à¸§"
+cantFavorite: "ไม่สามารถเพิ่มลงรายà¸à¸²à¸£à¹‚ปรดได้"
pin: "ปัà¸à¸«à¸¡à¸¸à¸”"
unpin: "เลิà¸à¸›à¸±à¸à¸«à¸¡à¸¸à¸”"
copyContent: "คัดลอà¸à¹€à¸™à¸·à¹‰à¸­à¸«à¸²"
@@ -65,18 +65,18 @@ loadMore: "à¹à¸ªà¸”งเพิ่มเติม"
showMore: "à¹à¸ªà¸”งเพิ่มเติม"
showLess: "ปิด"
youGotNewFollower: "ได้ติดตามคุณ"
-receiveFollowRequest: "คำขอผู้ติดตามที่ได้รับ"
-followRequestAccepted: "อนุมัติà¸à¸²à¸£à¸•ิดตามà¹à¸¥à¹‰à¸§"
+receiveFollowRequest: "มีคำขอติดตามส่งมาหา"
+followRequestAccepted: "à¸à¸²à¸£à¸•ิดตามได้รับà¸à¸²à¸£à¸­à¸™à¸¸à¸¡à¸±à¸•ิà¹à¸¥à¹‰à¸§"
mention: "à¸à¸¥à¹ˆà¸²à¸§à¸–ึง"
mentions: "พูดถึง"
-directNotes: "ไดเร็คโน้ต"
+directNotes: "โพสต์à¹à¸šà¸šà¹„ดเร็à¸à¸•์"
importAndExport: "นำเข้า / ส่งออà¸"
import: "นำเข้า"
export: "ส่งออà¸"
files: "ไฟล์"
download: "ดาวน์โหลด"
-driveFileDeleteConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¹„ฟล์ “{name}†ใช่หรือไม่? โน้ตที่à¹à¸™à¸šà¸¡à¸²à¸à¸±à¸šà¹„ฟล์นี้à¸à¹‡à¸ˆà¸°à¸–ูà¸à¸¥à¸šà¹„ปด้วย"
-unfollowConfirm: "ต้องà¸à¸²à¸£à¹€à¸¥à¸´à¸à¸•ิดตาม {name}?"
+driveFileDeleteConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¹„ฟล์ “{name}†ใช่ไหม? โน้ตที่à¹à¸™à¸šà¸¡à¸²à¸à¸±à¸šà¹„ฟล์นี้à¸à¹‡à¸ˆà¸°à¸–ูà¸à¸¥à¸šà¹„ปด้วย"
+unfollowConfirm: "ต้องà¸à¸²à¸£à¹€à¸¥à¸´à¸à¸•ิดตาม {name} ใช่ไหม?"
exportRequested: "คุณได้ร้องขอà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸ อาจใช้เวลาสัà¸à¸„รู่ à¹à¸¥à¸°à¸ˆà¸°à¸–ูà¸à¹€à¸žà¸´à¹ˆà¸¡à¹ƒà¸™à¹„ดรฟ์ของคุณเมื่อเสร็จสิ้นà¹à¸¥à¹‰à¸§"
importRequested: "คุณได้ร้องขอà¸à¸²à¸£à¸™à¸³à¹€à¸‚้า à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸™à¸µà¹‰à¸­à¸²à¸ˆà¹ƒà¸Šà¹‰à¹€à¸§à¸¥à¸²à¸ªà¸±à¸à¸„รู่"
lists: "รายชื่อ"
@@ -128,9 +128,9 @@ emojiPickerDisplay: "à¹à¸ªà¸”งตัวจิ้มเอโมจิ"
overwriteFromPinnedEmojisForReaction: "เขียนทับà¸à¸²à¸£à¸•ั้งค่ารีà¹à¸­à¸„ชั่น"
overwriteFromPinnedEmojis: "เขียนทับà¸à¸²à¸£à¸•ั้งค่าทั่วไป"
reactionSettingDescription2: "ลาà¸à¹€à¸žà¸·à¹ˆà¸­à¸ˆà¸±à¸”ลำดับใหม่ คลิà¸à¸—ี่เอโมจินั้นเพื่อลบ à¸à¸” “+†เพื่อเพิ่ม"
-rememberNoteVisibility: "จดจำà¸à¸²à¸£à¸•ั้งค่าà¸à¸²à¸£à¸¡à¸­à¸‡à¹€à¸«à¹‡à¸™à¸•ัวโน้ต"
-attachCancel: "ลบไฟล์ออà¸à¸—ี่à¹à¸™à¸šà¸¡à¸²"
-deleteFile: "ลบไฟล์ออà¸à¹à¸¥à¹‰à¸§"
+rememberNoteVisibility: "จำà¸à¸²à¸£à¸•ั้งค่าà¸à¸²à¸£à¸¡à¸­à¸‡à¹€à¸«à¹‡à¸™à¹‚น้ต"
+attachCancel: "ยà¸à¹€à¸¥à¸´à¸à¹à¸™à¸šà¹„ฟล์"
+deleteFile: "ลบไฟล์ออà¸"
markAsSensitive: "ทำเครื่องหมายว่ามีเนื้อหาละเอียดอ่อน"
unmarkAsSensitive: "ยà¸à¹€à¸¥à¸´à¸à¸—ำเครื่องหมายว่ามีเนื้อหาละเอียดอ่อน"
enterFileName: "พิมพ์ชื่อไฟล์"
@@ -138,14 +138,14 @@ mute: "ปิดเสียง"
unmute: "ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸›à¸´à¸”เสียง"
renoteMute: "ปิดเสียงรีโน้ต"
renoteUnmute: "เปิดเสียง รีโน้ต"
-block: "บล็อค"
-unblock: "เลิà¸à¸›à¸´à¸”à¸à¸±à¹‰à¸™"
-suspend: "ถูà¸à¸£à¸°à¸‡à¸±à¸š"
-unsuspend: "ยà¸à¹€à¸¥à¸´à¸à¸£à¸°à¸‡à¸±à¸š"
-blockConfirm: "ต้องà¸à¸²à¸£à¸šà¸¥à¹‡à¸­à¸à¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰?"
-unblockConfirm: "ต้องà¸à¸²à¸£à¸›à¸¥à¸”บล็อคบัà¸à¸Šà¸µà¸™à¸µà¹‰?"
-suspendConfirm: "ต้องà¸à¸²à¸£à¸£à¸°à¸‡à¸±à¸šà¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰?"
-unsuspendConfirm: "ต้องà¸à¸²à¸£à¸¢à¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸£à¸°à¸‡à¸±à¸šà¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰?"
+block: "บล็อà¸"
+unblock: "เลิà¸à¸šà¸¥à¹‡à¸­à¸"
+suspend: "ระงับ"
+unsuspend: "เลิà¸à¸£à¸°à¸‡à¸±à¸š"
+blockConfirm: "ต้องà¸à¸²à¸£à¸šà¸¥à¹‡à¸­à¸à¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¹ƒà¸Šà¹ˆà¹„หม?"
+unblockConfirm: "ต้องà¸à¸²à¸£à¹€à¸¥à¸´à¸à¸šà¸¥à¹‡à¸­à¸à¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¹ƒà¸Šà¹ˆà¹„หม?"
+suspendConfirm: "ต้องà¸à¸²à¸£à¸£à¸°à¸‡à¸±à¸šà¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¹ƒà¸Šà¹ˆà¹„หม?"
+unsuspendConfirm: "ต้องà¸à¸²à¸£à¸¢à¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸£à¸°à¸‡à¸±à¸šà¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¹ƒà¸Šà¹ˆà¹„หม?"
selectList: "เลือà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­"
editList: "à¹à¸à¹‰à¹„ขรายชื่อ"
selectChannel: "เลือà¸à¸Šà¹ˆà¸­à¸‡"
@@ -162,13 +162,13 @@ emojiUrl: "URL ของเอโมจิ"
addEmoji: "à¹à¸—รà¸à¹€à¸­à¹‚มจิ"
settingGuide: "à¸à¸²à¸£à¸•ั้งค่าที่à¹à¸™à¸°à¸™à¸³"
cacheRemoteFiles: "à¹à¸„ชไฟล์ระยะไà¸à¸¥"
-cacheRemoteFilesDescription: "เมื่อปิดใช้งานà¸à¸²à¸£à¸•ั้งค่านี้ ไฟล์ระยะไà¸à¸¥à¸™à¸±à¹‰à¸™à¸ˆà¸°à¸–ูà¸à¹‚หลดโดยตรงจาà¸à¸­à¸´à¸™à¸ªà¹à¸•นซ์ระยะไà¸à¸¥ à¹à¸•่à¸à¸£à¸“ีà¸à¸²à¸£à¸›à¸´à¸”ใช้งานนี้จะช่วยลดปริมาณà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸žà¸·à¹‰à¸™à¸—ี่จัดเà¸à¹‡à¸šà¸‚้อมูล à¹à¸•่เพิ่มปริมาณà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™ เพราะเนื่องจาà¸à¸ˆà¸°à¹„ม่มีà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸ à¸²à¸žà¸‚นาดย่อ"
+cacheRemoteFilesDescription: "หาà¸à¹€à¸›à¸´à¸”ใช้งาน ไฟล์ระยะไà¸à¸¥à¸ˆà¸°à¸–ูà¸à¹à¸„ชไว้ ทำให้à¹à¸ªà¸”งภาพเร็วขึ้น à¹à¸•่à¸à¹‡à¹ƒà¸Šà¹‰à¸žà¸·à¹‰à¸™à¸—ี่เà¸à¹‡à¸šà¸‚้อมูลของเซิร์ฟเวอร์มาà¸à¸‚ึ้นเช่นà¸à¸±à¸™ สำหรับขีดจำà¸à¸±à¸”ที่ผู้ใช้ระยะไà¸à¸¥à¸–ูà¸à¹à¸„ชไว้จะขึ้นอยู่à¸à¸±à¸šà¸„วามจุไดรฟ์ตามบทบาทของเขา เมื่อเà¸à¸´à¸™à¹à¸¥à¹‰à¸§à¹„ฟล์เà¸à¹ˆà¸²à¸ˆà¸°à¸–ูà¸à¸¥à¸šà¸­à¸­à¸à¹à¸¥à¸°à¹€à¸à¹‡à¸šà¹€à¸›à¹‡à¸™à¸¥à¸´à¸‡à¸à¹Œà¹à¸—น หาà¸à¸›à¸´à¸”ใช้งาน ไฟล์ระยะไà¸à¸¥à¸ˆà¸°à¸–ูà¸à¹€à¸à¹‡à¸šà¹€à¸›à¹‡à¸™à¸¥à¸´à¸‡à¸à¹Œà¸•ั้งà¹à¸•่ต้น เราà¹à¸™à¸°à¸™à¸³à¹ƒà¸«à¹‰à¸•ั้งค่า proxyRemoteFiles ใน default.yml เป็น true เพื่อสร้างธัมบ์เนลà¹à¸¥à¸°à¸›à¸à¸›à¹‰à¸­à¸‡à¸„วามเป็นส่วนตัวของผู้ใช้"
youCanCleanRemoteFilesCache: "คุณสามารถล้างà¹à¸„ชได้โดยคลิà¸à¸—ี่ปุ่ม ðŸ—‘ï¸ à¹ƒà¸™à¸¡à¸¸à¸¡à¸¡à¸­à¸‡à¸à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£à¹„ฟล์"
-cacheRemoteSensitiveFiles: "à¹à¸„ชไฟล์ระยะไà¸à¸¥à¸—ี่มีเครื่องหมายว่ามีเนื้อหาละเอียดอ่อน"
+cacheRemoteSensitiveFiles: "à¹à¸„ชไฟล์ระยะไà¸à¸¥à¸—ี่มีเนื้อหาละเอียดอ่อน"
cacheRemoteSensitiveFilesDescription: "เมื่อปิดà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸à¸²à¸£à¸•ั้งค่านี้ ไฟล์ระยะไà¸à¸¥à¸—ี่มีเครื่องหมายว่ามีเนื้อหาละเอียดอ่อนนั้นจะถูà¸à¹‚หลดโดยตรงจาà¸à¸­à¸´à¸™à¸ªà¹à¸•นซ์ระยะไà¸à¸¥à¹‚ดยที่ไม่มีà¸à¸²à¸£à¹à¸„ช"
-flagAsBot: "ทำเครื่องหมายบอà¸à¸§à¹ˆà¸²à¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¸šà¸­à¸—"
+flagAsBot: "ทำเครื่องหมายบอà¸à¸§à¹ˆà¸²à¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¸šà¸­à¸•"
flagAsBotDescription: "à¸à¸²à¸£à¹€à¸›à¸´à¸”ใช้งานตัวเลือà¸à¸™à¸µà¹‰à¸«à¸²à¸à¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¸–ูà¸à¸„วบคุมโดยนัà¸à¹€à¸‚ียนโปรà¹à¸à¸£à¸¡ หรือ ถ้าหาà¸à¹€à¸›à¸´à¸”ใช้งาน มันจะทำหน้าที่เป็นà¹à¸Ÿà¸¥à¹‡à¸à¸ªà¸³à¸«à¸£à¸±à¸šà¸™à¸±à¸à¸žà¸±à¸’นารายอื่นๆ à¹à¸¥à¸°à¹€à¸žà¸·à¹ˆà¸­à¸›à¹‰à¸­à¸‡à¸à¸±à¸™à¸à¸²à¸£à¹‚ต้ตอบà¹à¸šà¸šà¹„ม่มีที่สิ้นสุดà¸à¸±à¸šà¸šà¸­à¸—ตัวอื่นๆ à¹à¸¥à¸°à¸¢à¸±à¸‡à¸ªà¸²à¸¡à¸²à¸£à¸–ปรับเปลี่ยนระบบภายในของ Misskey เพื่อปà¸à¸´à¸šà¸±à¸•ิต่อบัà¸à¸Šà¸µà¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¸šà¸­à¸—"
-flagAsCat: "เมี้ยววววววว!!!!!!!!!!! (ทำเครื่องหมายว่าบัà¸à¸Šà¸µà¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¹à¸¡à¸§)"
+flagAsCat: "เมี้ยววววววววววววววว!!!!!!!!!!!"
flagAsCatDescription: "เหมียวเหมียวเมี้ยว??"
flagShowTimelineReplies: "à¹à¸ªà¸”งตอบà¸à¸¥à¸±à¸š ในไทม์ไลน์"
flagShowTimelineRepliesDescription: "à¹à¸ªà¸”งà¸à¸²à¸£à¸•อบà¸à¸¥à¸±à¸šà¸‚องผู้ใช้งานไปยังโน้ตของผู้ใช้งานรายอื่นๆในไทม์ไลน์หาà¸à¹„ด้เปิดเอาไว้"
@@ -180,7 +180,7 @@ showOnRemote: "ดูบนอินสà¹à¸•นซ์ระยะไà¸à¸¥"
general: "ทั่วไป"
wallpaper: "ภาพพื้นหลัง"
setWallpaper: "ตั้งค่าภาพพื้นหลัง"
-removeWallpaper: "น้ำภาพพื้นหลังออà¸"
+removeWallpaper: "นำภาพพื้นหลังออà¸"
searchWith: "ค้นหา: {q}"
youHaveNoLists: "คุณไม่มีรายชื่อใดๆ "
followConfirm: "ต้องà¸à¸²à¸£à¸•ิดตาม {name} ใช่ไหม?"
@@ -189,11 +189,11 @@ proxyAccountDescription: "บัà¸à¸Šà¸µà¸žà¸£à¹‡à¸­à¸à¸‹à¸µà¹ˆ คือ บà
host: "โฮสต์"
selectUser: "เลือà¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸‡à¸²à¸™"
recipient: "ผู้รับ"
-annotation: "ความคิดเห็น"
+annotation: "หมายเหตุประà¸à¸­à¸š"
federation: "สหพันธ์"
instances: "อินสà¹à¸•นซ์"
-registeredAt: "จดทะเบียนที่"
-latestRequestReceivedAt: "ได้รับคำขอล่าสุดไปà¹à¸¥à¹‰à¸§"
+registeredAt: "วันที่ลงทะเบียน"
+latestRequestReceivedAt: "คำขอล่าสุดที่ได้รับ"
latestStatus: "สถานะล่าสุด"
storageUsage: "พื้นที่จัดเà¸à¹‡à¸šà¸‚้อมูลที่ใช้ไป"
charts: "โดดเด่น"
@@ -215,10 +215,10 @@ disk: "ดิสà¸à¹Œ"
instanceInfo: "ข้อมูลอินสà¹à¸•นซ์"
statistics: "สถิติà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™"
clearQueue: "ล้างคิว"
-clearQueueConfirmTitle: "คุณà¹à¸™à¹ˆà¹ƒà¸ˆà¹à¸¥à¹‰à¸§à¸«à¸£à¸­à¸§à¹ˆà¸²à¸•้องà¸à¸²à¸£à¸—ี่จะล้างคิว?"
+clearQueueConfirmTitle: "ต้องà¸à¸²à¸£à¸¥à¹‰à¸²à¸‡à¸„ิวใช่ไหม?"
clearQueueConfirmText: "โพสต์ที่ยังค้างในคิวจะไม่ถูà¸à¸ˆà¸±à¸”ส่งอีà¸à¸•่อไป โดยปà¸à¸•ิà¹à¸¥à¹‰à¸§à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸™à¸µà¹‰à¹„ม่จำเป็น"
clearCachedFiles: "ล้างà¹à¸„ช"
-clearCachedFilesConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¹„ฟล์ระยะไà¸à¸¥à¸—ี่à¹à¸„ชไว้ทั้งหมด?"
+clearCachedFilesConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¹„ฟล์ระยะไà¸à¸¥à¸—ี่à¹à¸„ชไว้ทั้งหมดใช่ไหม?"
blockedInstances: "อินสà¹à¸•นซ์ที่ถูà¸à¸šà¸¥à¹‡à¸­à¸"
blockedInstancesDescription: "ระบุชื่อโฮสต์ของอินสà¹à¸•นซ์ที่คุณต้องà¸à¸²à¸£à¸šà¸¥à¹‡à¸­à¸ อินสà¹à¸•นซ์ที่อยู่ในรายà¸à¸²à¸£à¸™à¸±à¹‰à¸™à¸ˆà¸°à¹„ม่สามารถพูดคุยà¸à¸±à¸šà¸­à¸´à¸™à¸ªà¹à¸•นซ์นี้ได้อีà¸à¸•่อไป"
silencedInstances: "ปิดปาà¸à¸­à¸´à¸™à¸ªà¹à¸•นซ์นี้à¹à¸¥à¹‰à¸§"
@@ -228,7 +228,7 @@ mutedUsers: "ผู้ใช้ที่ถูà¸à¸›à¸´à¸”เสียง"
blockedUsers: "ผู้ใช้ที่ถูà¸à¸šà¸¥à¹‡à¸­à¸"
noUsers: "ไม่พบผู้ใช้งาน"
editProfile: "à¹à¸à¹‰à¹„ขโปรไฟล์"
-noteDeleteConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¹‚น้ตนี้?"
+noteDeleteConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¹‚น้ตนี้ใช่ไหม?"
pinLimitExceeded: "คุณไม่สามารถปัà¸à¸«à¸¡à¸¸à¸”โน้ตเพิ่มเติมใดๆได้อีà¸"
intro: "à¸à¸²à¸£à¸•ิดตั้ง Misskey เสร็จสิ้นà¹à¸¥à¹‰à¸§à¸™à¸°! โปรดสร้างผู้ใช้งานที่เป็นผู้ดูà¹à¸¥à¸£à¸°à¸šà¸š"
done: "เสร็จสิ้น"
@@ -237,7 +237,7 @@ preview: "à¹à¸ªà¸”งตัวอย่าง"
default: "ค่าเริ่มต้น"
defaultValueIs: "ค่าเริ่มต้น: {value}"
noCustomEmojis: "ไม่มีเอโมจิ"
-noJobs: "ไม่มีชิ้นงาน"
+noJobs: "ไม่มีงาน"
federating: "สหพันธ์"
blocked: "ถูà¸à¸šà¸¥à¹‡à¸­à¸"
suspended: "ถูà¸à¸£à¸°à¸‡à¸±à¸š"
@@ -261,11 +261,11 @@ usernameOrUserId: "ชื่อผู้ใช้หรือรหัสผูà
noSuchUser: "ไม่พบผู้ใช้"
lookup: "à¸à¸²à¸£à¸„้นหา"
announcements: "ประà¸à¸²à¸¨"
-imageUrl: "url รูปภาพ"
+imageUrl: "URL รูปภาพ"
remove: "ลบ"
removed: "ถูà¸à¸¥à¸šà¹„ปà¹à¸¥à¹‰à¸§"
-removeAreYouSure: "ต้องà¸à¸²à¸£à¸—ี่จะลบ “{x}†ออà¸?"
-deleteAreYouSure: "ต้องà¸à¸²à¸£à¸¥à¸š {x} หรือไม่คะ?"
+removeAreYouSure: "ต้องà¸à¸²à¸£à¸¥à¸š “{x}†ใช่ไหม?"
+deleteAreYouSure: "ต้องà¸à¸²à¸£à¸¥à¸š “{x}†ใช่ไหม?"
resetAreYouSure: "รีเซ็ตเลยไหม?"
areYouSure: "à¹à¸™à¹ˆà¹ƒà¸ˆà¹à¸¥à¹‰à¸§à¹ƒà¸Šà¹ˆà¹„หมคะ?"
saved: "บันทึà¸à¹à¸¥à¹‰à¸§"
@@ -275,7 +275,7 @@ keepOriginalUploading: "เà¸à¹‡à¸šà¸ à¸²à¸žà¸•้นฉบับ"
keepOriginalUploadingDescription: "เà¸à¹‡à¸šà¸ à¸²à¸žà¸•้นฉบับไว้เมื่ออัปโหลดภาพ หาà¸à¸›à¸´à¸” รูปภาพสำหรับà¸à¸²à¸£à¹€à¸œà¸¢à¹à¸žà¸£à¹ˆà¸—างเว็บจะถูà¸à¸ªà¸£à¹‰à¸²à¸‡à¸‚ึ้นในเบราว์เซอร์เมื่อทำà¸à¸²à¸£à¸­à¸±à¸›à¹‚หลด"
fromDrive: "จาà¸à¹„ดรฟ์"
fromUrl: "จาภURL"
-uploadFromUrl: "อัพโหลดจาภURL"
+uploadFromUrl: "อัปโหลดจาภURL"
uploadFromUrlDescription: "URL ของไฟล์ที่คุณต้องà¸à¸²à¸£à¸­à¸±à¸›à¹‚หลด"
uploadFromUrlRequested: "ร้องขอà¸à¸²à¸£à¸­à¸±à¸›à¹‚หลดà¹à¸¥à¹‰à¸§"
uploadFromUrlMayTakeTime: "à¸à¸²à¸£à¸­à¸±à¸›à¹‚หลดอาจใช้เวลาสัà¸à¸„รู่จึงจะเสร็จสมบูรณ์"
@@ -289,7 +289,7 @@ agree: "ยอมรับ"
agreeBelow: "ฉันยอมรับถึงด้านล่าง"
basicNotesBeforeCreateAccount: "หมายเหตุสำคัà¸"
termsOfService: "เงื่อนไขà¸à¸²à¸£à¹ƒà¸«à¹‰à¸šà¸£à¸´à¸à¸²à¸£"
-start: "เริ่มต้น​ใช้งาน​"
+start: "เริ่ม"
home: "หน้าà¹à¸£à¸"
remoteUserCaution: "ข้อมูลอาจไม่สมบูรณ์เนื่องจาà¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸£à¸²à¸¢à¸™à¸µà¹‰à¸¡à¸²à¸ˆà¸²à¸à¸­à¸´à¸™à¸ªà¹à¸•นซ์ระยะไà¸à¸¥"
activity: "à¸à¸´à¸ˆà¸à¸£à¸£à¸¡"
@@ -333,11 +333,11 @@ rename: "เปลี่ยนชื่อ"
avatar: "ไอคอน"
banner: "à¹à¸šà¸™à¹€à¸™à¸­à¸£à¹Œ"
displayOfSensitiveMedia: "à¹à¸ªà¸”งสื่อที่มีเนื้อหาละเอียดอ่อน"
-whenServerDisconnected: "สูà¸à¹€à¸ªà¸µà¸¢à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อà¸à¸±à¸šà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œ"
-disconnectedFromServer: "ถูà¸à¸•ัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อออà¸à¸ˆà¸²à¸à¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œ"
+whenServerDisconnected: "เมื่อสูà¸à¹€à¸ªà¸µà¸¢à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อà¸à¸±à¸šà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œ"
+disconnectedFromServer: "à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อเซิร์ฟเวอร์ถูà¸à¸•ัด"
reload: "รีโหลด"
doNothing: "เมิน"
-reloadConfirm: "นายต้องà¸à¸²à¸£à¸£à¸µà¹€à¸Ÿà¸£à¸Šà¹„ทม์ไลน์หรือป่าว?"
+reloadConfirm: "รีโหลดเลยไหม?"
watch: "ดู"
unwatch: "หยุดดู"
accept: "ยอมรับ"
@@ -347,7 +347,7 @@ instanceName: "ชื่ออินสà¹à¸•นซ์"
instanceDescription: "คำอธิบายอินสà¹à¸•นซ์"
maintainerName: "ผู้ดูà¹à¸¥"
maintainerEmail: "อีเมลผู้ดูà¹à¸¥à¸£à¸°à¸šà¸š"
-tosUrl: "เงื่อนไขà¸à¸²à¸£à¹ƒà¸«à¹‰à¸šà¸£à¸´à¸à¸²à¸£ URL"
+tosUrl: "URL เงื่อนไขà¸à¸²à¸£à¹ƒà¸«à¹‰à¸šà¸£à¸´à¸à¸²à¸£"
thisYear: "ปีนี้"
thisMonth: "เดือนนี้"
today: "วันนี้"
@@ -370,7 +370,7 @@ inMb: "เป็นเมà¸à¸°à¹„บต์"
bannerUrl: "URL รูปภาพà¹à¸šà¸™à¹€à¸™à¸­à¸£à¹Œ"
backgroundImageUrl: "URL ภาพพื้นหลัง"
basicInfo: "ข้อมูลเบื้องต้น"
-pinnedUsers: "ผู้ใช้งานที่ได้รับà¸à¸²à¸£à¸›à¸±à¸à¸«à¸¡à¸¸à¸”"
+pinnedUsers: "ผู้ใช้ที่ถูà¸à¸›à¸±à¸à¸«à¸¡à¸¸à¸”"
pinnedUsersDescription: "ป้อนชื่อผู้ใช้ที่คุณต้องà¸à¸²à¸£à¸›à¸±à¸à¸«à¸¡à¸¸à¸”ในหน้า “ค้นพบ†ฯลฯ คั่นด้วยà¸à¸²à¸£à¸‚ึ้นบรรทัดใหม่"
pinnedPages: "หน้าเพจที่ปัà¸à¸«à¸¡à¸¸à¸”"
pinnedPagesDescription: "ป้อนเส้นทางของหน้าเพจที่คุณต้องà¸à¸²à¸£à¸›à¸±à¸à¸«à¸¡à¸¸à¸”ไว้ที่หน้าà¹à¸£à¸à¸‚องอินสà¹à¸•นซ์นี้ คั่นด้วยขึ้นบรรทัดใหม่"
@@ -409,16 +409,16 @@ caseSensitive: "อัà¸à¸©à¸£à¸žà¸´à¸¡à¸žà¹Œà¹ƒà¸«à¸à¹ˆ-พิมพ์เล
withReplies: "รวมตอบà¸à¸¥à¸±à¸š"
connectedTo: "บัà¸à¸Šà¸µà¸”ังต่อไปนี้มีà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อà¸à¸±à¸™"
notesAndReplies: "โพสต์à¹à¸¥à¸°à¸à¸²à¸£à¸•อบà¸à¸¥à¸±à¸š"
-withFiles: "รวบรวมไฟล์"
+withFiles: "มีไฟล์"
silence: "ถูà¸à¸›à¸´à¸”ปาà¸"
-silenceConfirm: "ต้องà¸à¸²à¸£à¸—ี่จะ ปิดปาภผู้ใช้รายนี้?"
+silenceConfirm: "ต้องà¸à¸²à¸£à¸›à¸´à¸”ปาà¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸£à¸²à¸¢à¸™à¸µà¹‰à¹ƒà¸Šà¹ˆà¹„หม?"
unsilence: "ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸›à¸´à¸”ปาà¸"
-unsilenceConfirm: "ต้องà¸à¸²à¸£à¸¢à¸à¹€à¸¥à¸´à¸à¸›à¸´à¸”ปาà¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸£à¸²à¸¢à¸™à¸µà¹‰?"
+unsilenceConfirm: "ต้องà¸à¸²à¸£à¹€à¸¥à¸´à¸à¸›à¸´à¸”ปาà¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸£à¸²à¸¢à¸™à¸µà¹‰à¹ƒà¸Šà¹ˆà¹„หม?"
popularUsers: "ผู้ใช้ที่เป็นที่นิยม"
recentlyUpdatedUsers: "ผู้ใช้ที่เพิ่งใช้งานล่าสุด"
recentlyRegisteredUsers: "ผู้ใช้ที่เข้าร่วมใหม่"
recentlyDiscoveredUsers: "ผู้ใช้ที่เพิ่งค้นพบใหม่"
-exploreUsersCount: "มีผู้ใช้ {จำนวน} ราย"
+exploreUsersCount: "มีผู้ใช้ {count} ราย"
exploreFediverse: "สำรวจสหพันธ์"
popularTags: "à¹à¸—็à¸à¸¢à¸­à¸”นิยม"
userList: "ลิสต์"
@@ -435,7 +435,7 @@ moderation: "à¸à¸²à¸£à¸à¸¥à¸±à¹ˆà¸™à¸à¸£à¸­à¸‡"
moderationNote: "โน้ตà¸à¸²à¸£à¸à¸¥à¸±à¹ˆà¸™à¸à¸£à¸­à¸‡"
addModerationNote: "เพิ่มโน้ตà¸à¸²à¸£à¸à¸¥à¸±à¹ˆà¸™à¸à¸£à¸­à¸‡"
moderationLogs: "ปูมà¸à¸²à¸£à¹à¸à¹‰à¹„ข"
-nUsersMentioned: "à¸à¸¥à¹ˆà¸²à¸§à¸–ึงโดยผู้ใช้ {n} รายนี้"
+nUsersMentioned: "à¸à¸¥à¹ˆà¸²à¸§à¸–ึงโดยผู้ใช้ {n} ราย"
securityKeyAndPasskey: "ความปลอดภัยà¹à¸¥à¸°à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™"
securityKey: "à¸à¸¸à¸à¹à¸ˆà¸„วามปลอดภัย"
lastUsed: "ใช้ล่าสุด"
@@ -449,7 +449,7 @@ reduceUiAnimation: "ลดภาพเคลื่อนไหว UI"
share: "à¹à¸šà¹ˆà¸‡à¸›à¸±à¸™"
notFound: "ไม่พบหน้าที่ต้องà¸à¸²à¸£"
notFoundDescription: "ไม่พบหน้าตาม URL ที่ระบุ"
-uploadFolder: "โฟลเดอร์เริ่มต้นสำหรับอัพโหลด"
+uploadFolder: "โฟลเดอร์เริ่มต้นสำหรับอัปโหลด"
markAsReadAllNotifications: "ทำเครื่องหมายà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนทั้งหมดว่าอ่านà¹à¸¥à¹‰à¸§"
markAsReadAllUnreadNotes: "ทำเครื่องหมายโน้ตทั้งหมดว่าอ่านà¹à¸¥à¹‰à¸§"
markAsReadAllTalkMessages: "ทำเครื่องหมายข้อความทั้งหมดว่าอ่านà¹à¸¥à¹‰à¸§"
@@ -464,7 +464,7 @@ text: "ข้อความ"
enable: "เปิดใช้งาน"
next: "ถัด​ไป"
retype: "พิมพ์รหัสอีà¸à¸„รั้ง"
-noteOf: "โน้ต โดย {user}"
+noteOf: "โน้ตของ {user}"
quoteAttached: "อ้างอิง"
quoteQuestion: "ต้องà¸à¸²à¸£à¸—ี่จะà¹à¸™à¸šà¸¡à¸±à¸™à¹€à¸žà¸·à¹ˆà¸­à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡à¹ƒà¸Šà¹ˆà¹„หม?"
noMessagesYet: "ยังไม่มีข้อความ"
@@ -472,7 +472,7 @@ newMessageExists: "คุณมีข้อความใหม่"
onlyOneFileCanBeAttached: "สามารถà¹à¸™à¸šà¹„ฟล์ได้เพียงไฟล์เดียวต่อ 1 ข้อความ"
signinRequired: "à¸à¸£à¸¸à¸“าลงทะเบียนหรือลงชื่อเข้าใช้à¸à¹ˆà¸­à¸™à¸”ำเนินà¸à¸²à¸£à¸•่อ"
invitations: "คำเชิà¸"
-invitationCode: "รหัสคำเชิà¸"
+invitationCode: "รหัสเชิà¸"
checking: "Checking"
available: "พร้อมใช้งาน"
unavailable: "ไม่พร้อมใช้"
@@ -557,7 +557,7 @@ popout: "ป๊อปเอาต์"
volume: "ระดับเสียง"
masterVolume: "ระดับเสียงหลัà¸"
notUseSound: "ไม่ใช้เสียง"
-useSoundOnlyWhenActive: "มีเสียงออà¸à¹€à¸‰à¸žà¸²à¸°à¹€à¸¡à¸·à¹ˆà¸­ Misskey ทำงานอยู่"
+useSoundOnlyWhenActive: "มีเสียงออà¸à¹€à¸‰à¸žà¸²à¸°à¸•อนà¸à¸³à¸¥à¸±à¸‡à¹ƒà¸Šà¹‰ Misskey อยู่เท่านั้น"
details: "รายละเอียด"
chooseEmoji: "เลือà¸à¹€à¸­à¹‚มจิ"
unableToProcess: "ไม่สามารถดำเนินà¸à¸²à¸£à¹ƒà¸«à¹‰à¹€à¸ªà¸£à¹‡à¸ˆà¸ªà¸´à¹‰à¸™à¹„ด้"
@@ -570,8 +570,8 @@ installedDate: "วันที่ติดตั้ง"
lastUsedDate: "ใช้งานครั้งล่าสุด"
state: "สถานะ"
sort: "เรียงลำดับ"
-ascendingOrder: "เรียงจาà¸à¸™à¹‰à¸­à¸¢à¹„ปมาà¸"
-descendingOrder: "เรียงจาà¸à¸¡à¸²à¸à¹„ปน้อย"
+ascendingOrder: "เรียงลำดับขึ้น"
+descendingOrder: "เรียงลำดับลง"
scratchpad: "Scratchpad"
scratchpadDescription: "Scratchpad เป็นà¸à¸²à¸£à¸ˆà¸±à¸”เตรียมสภาพà¹à¸§à¸”ล้อมสำหรับà¸à¸²à¸£à¸—ดลอง AiScript à¹à¸•่คุณสามารถเขียน ดำเนินà¸à¸²à¸£ à¹à¸¥à¸°à¸•รวจสอบผลลัพธ์ของà¸à¸²à¸£à¹‚ต้ตอบà¸à¸±à¸š Misskey มันได้ด้วยนะ"
output: "เอาท์พุต"
@@ -579,15 +579,15 @@ script: "สคริปต์"
disablePagesScript: "ปิดà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™ AiScript บนเพจ"
updateRemoteUser: "อัปเดตข้อมูลผู้ใช้งานระยะไà¸à¸¥"
unsetUserAvatar: "เลิà¸à¸•ั้งอวตาร"
-unsetUserAvatarConfirm: "ต้องà¸à¸²à¸£à¹€à¸¥à¸´à¸à¸•ั้งอวตาร?"
+unsetUserAvatarConfirm: "ต้องà¸à¸²à¸£à¹€à¸¥à¸´à¸à¸•ั้งอวตารใข่ไหม?"
unsetUserBanner: "เลิà¸à¸•ั้งà¹à¸šà¸™à¹€à¸™à¸­à¸£à¹Œ"
unsetUserBannerConfirm: "ต้องà¸à¸²à¸£à¹€à¸¥à¸´à¸à¸•ั้งà¹à¸šà¸™à¹€à¸™à¸­à¸£à¹Œ?"
deleteAllFiles: "ลบไฟล์ทั้งหมด"
-deleteAllFilesConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¹„ฟล์ทั้งหมดหรือไม่?"
+deleteAllFilesConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¹„ฟล์ทั้งหมดใช่ไหม?"
removeAllFollowing: "เลิà¸à¸•ิดตามผู้ใช้ที่ติดตามทั้งหมด"
removeAllFollowingDescription: "เลิà¸à¸•ิดตามทั้งหมดจาภ{host} โปรดเรียà¸à¹ƒà¸Šà¹‰à¸ªà¸´à¹ˆà¸‡à¸™à¸µà¹‰à¹€à¸¡à¸·à¹ˆà¸­à¸­à¸´à¸™à¸ªà¹à¸•นซ์ดังà¸à¸¥à¹ˆà¸²à¸§à¹„ด้สูà¸à¸«à¸²à¸¢à¸•ายจาà¸à¹„ปà¹à¸¥à¹‰à¸§"
userSuspended: "ผู้ใช้รายนี้ถูà¸à¸£à¸°à¸‡à¸±à¸šà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™"
-userSilenced: "ผู้ใช้รายนี้à¸à¸³à¸¥à¸±à¸‡à¸–ูà¸à¸›à¸´à¸”à¸à¸±à¹‰à¸™"
+userSilenced: "ผู้ใช้รายนี้ถูà¸à¸›à¸´à¸”ปาà¸à¸­à¸¢à¸¹à¹ˆ"
yourAccountSuspendedTitle: "บัà¸à¸Šà¸µà¸™à¸µà¹‰à¸™à¸±à¹‰à¸™à¸–ูà¸à¸£à¸°à¸‡à¸±à¸š"
yourAccountSuspendedDescription: "บัà¸à¸Šà¸µà¸™à¸µà¹‰à¸–ูà¸à¸£à¸°à¸‡à¸±à¸š เนื่องจาà¸à¸¥à¸°à¹€à¸¡à¸´à¸”ข้อà¸à¸³à¸«à¸™à¸”ในà¸à¸²à¸£à¹ƒà¸«à¹‰à¸šà¸£à¸´à¸à¸²à¸£à¸‚องเซิร์ฟเวอร์หรืออาจจะละเมิดหลัà¸à¹€à¸à¸“ฑ์ชุมชน หรือ อาจจะโดนร้องเรียนเรื่องà¸à¸²à¸£à¸¥à¸°à¹€à¸¡à¸´à¸”ลิขสิทธิ์à¹à¸¥à¸°à¸­à¸·à¹ˆà¸™à¹†à¸­à¸¢à¹ˆà¸²à¸‡à¸•่อเนื่องซ้ำๆ หาà¸à¸„ุณคิดว่าไม่ได้ทำผิดจริงๆหรือตัดสินผิดพลาด ได้โปรดà¸à¸£à¸¸à¸“าติดต่อผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¸«à¸²à¸à¸„ุณต้องà¸à¸²à¸£à¸—ราบเหตุผลโดยละเอียดเพิ่มเติม à¹à¸¥à¸°à¸‚อความà¸à¸£à¸¸à¸“าอย่าสร้างบัà¸à¸Šà¸µà¹ƒà¸«à¸¡à¹ˆ"
tokenRevoked: "โทเค็นไม่ถูà¸à¸•้อง"
@@ -600,7 +600,7 @@ addItem: "เพิ่มรายà¸à¸²à¸£"
rearrange: "จัดใหม่"
relays: "รีเลย์"
addRelay: "เพิ่มรีเลย์"
-inboxUrl: "อินบ็อà¸à¸‹à¹Œ URL"
+inboxUrl: "URL ของอินบ็อà¸à¸‹à¹Œ"
addedRelays: "เพิ่มรีเลย์à¹à¸¥à¹‰à¸§"
serviceworkerInfo: "ต้องเปิดใช้งานสำหรับà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนà¹à¸šà¸šà¸žà¸¸à¸Š"
deletedNote: "โน้ตที่ถูà¸à¸¥à¸š"
@@ -617,7 +617,7 @@ description: "รายละเอียด"
describeFile: "เพิ่มà¹à¸„ปชั่น"
enterFileDescription: "ใส่à¹à¸„ปชั่น"
author: "ผู้เขียน"
-leaveConfirm: "คุณมีà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸—ี่ไม่ได้บันทึà¸à¸™à¸° นายต้องà¸à¸²à¸£à¸—ิ้งà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹€à¸«à¸¥à¹ˆà¸²à¸™à¸±à¹‰à¸™à¸«à¸£à¸­?"
+leaveConfirm: "มีà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸—ี่ยังไม่ได้บันทึภต้องà¸à¸²à¸£à¸¥à¸°à¸—ิ้งมันใช่ไหม?"
manage: "à¸à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£"
plugins: "ปลั๊à¸à¸­à¸´à¸™"
preferencesBackups: "ตั้งค่าà¸à¸²à¸£à¸ªà¸³à¸£à¸­à¸‡à¸‚้อมูล"
@@ -664,7 +664,7 @@ display: "à¹à¸ªà¸”งผล"
copy: "คัดลอà¸"
metrics: "เมตริà¸"
overview: "ภาพรวม"
-logs: "บันทึà¸à¸‚้อมูลระบบ"
+logs: "ปูม"
delayed: "ดีเลย์"
database: "à¸à¸²à¸™à¸‚้อมูล"
channel: "ช่อง"
@@ -672,26 +672,26 @@ create: "สร้าง"
notificationSetting: "ตั้งค่าà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือน"
notificationSettingDesc: "เลือà¸à¸›à¸£à¸°à¹€à¸ à¸—à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนที่ต้องà¸à¸²à¸£à¸ˆà¸°à¹à¸ªà¸”ง"
useGlobalSetting: "ใช้à¸à¸²à¸£à¸•ั้งค่าส่วนà¸à¸¥à¸²à¸‡"
-useGlobalSettingDesc: "หาà¸à¹€à¸›à¸´à¸”ไว้ ระบบจะใช้à¸à¸²à¸£à¸•ั้งค่าà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนของบัà¸à¸Šà¸µà¸‚องคุณ หาà¸à¸›à¸´à¸”อยู่ สามารถทำà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าà¹à¸•่ละรายà¸à¸²à¸£à¹„ด้นะ"
+useGlobalSettingDesc: "เมื่อเปิดใช้งาน ใช้à¸à¸²à¸£à¸•ั้งค่าà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนจาà¸à¸šà¸±à¸à¸Šà¸µà¸„ุณ เมื่อปิดใช้งาน สามารถตั้งค่าได้อย่างอิสระ"
other: "อื่น ๆ"
regenerateLoginToken: "สร้างโทเค็นà¸à¸²à¸£à¹€à¸‚้าสู่ระบบอีà¸à¸„รั้ง"
regenerateLoginTokenDescription: "สร้างโทเค็นใหม่ที่ใช้ภายในระหว่างà¸à¸²à¸£à¹€à¸‚้าสู่ระบบ โดยตามหลัà¸à¸›à¸à¸•ิà¹à¸¥à¹‰à¸§à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸™à¸µà¹‰à¹„ม่จำเป็น หาà¸à¸ªà¸£à¹‰à¸²à¸‡à¹ƒà¸«à¸¡à¹ˆ อุปà¸à¸£à¸“์ทั้งหมดจะถูà¸à¸­à¸­à¸à¸ˆà¸²à¸à¸£à¸°à¸šà¸šà¸™à¸°"
-theKeywordWhenSearchingForCustomEmoji: "คีย์เวิร์ดสำหรับใช้ค้นหาอีโมจิที่à¸à¸³à¸«à¸™à¸”เอง"
+theKeywordWhenSearchingForCustomEmoji: "คีย์เวิร์ดสำหรับใช้ค้นหาเอโมจิที่à¸à¸³à¸«à¸™à¸”เอง"
setMultipleBySeparatingWithSpace: "คั่นหลายรายà¸à¸²à¸£à¸”้วยช่องว่าง"
-fileIdOrUrl: "ไฟล์ ID หรือ URL"
+fileIdOrUrl: "ID ของไฟล์ หรือ URL"
behavior: "พฤติà¸à¸£à¸£à¸¡"
sample: "ตัวอย่าง"
abuseReports: "รายงาน"
reportAbuse: "รายงาน"
reportAbuseRenote: "รายงานรีโน้ต"
-reportAbuseOf: "รายงาน {ชื่อ}"
+reportAbuseOf: "รายงาน {name}"
fillAbuseReportDescription: "à¸à¸£à¸¸à¸“าà¸à¸£à¸­à¸à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”เà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸£à¸²à¸¢à¸‡à¸²à¸™à¸™à¸µà¹‰ หาà¸à¹€à¸›à¹‡à¸™à¹€à¸£à¸·à¹ˆà¸­à¸‡à¹€à¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¹‚น้ตโดยเฉพาะ ได้โปรดระบุ URL"
abuseReported: "เราได้ส่งรายงานของคุณไปà¹à¸¥à¹‰à¸§ ขอบคุณมาà¸à¹†à¸™à¸°"
-reporter: "นัà¸à¸‚่าว"
+reporter: "ผู้รายงาน"
reporteeOrigin: "รายงานต้นทาง"
-reporterOrigin: "นัà¸à¸‚่าวต้นทาง"
+reporterOrigin: "à¹à¸«à¸¥à¹ˆà¸‡à¸œà¸¹à¹‰à¸£à¸²à¸¢à¸‡à¸²à¸™"
forwardReport: "ส่งต่อรายงานไปยังอินสà¹à¸•นซ์ระยะไà¸à¸¥"
-forwardReportIsAnonymous: "à¹à¸—นที่จะเป็นบัà¸à¸Šà¸µà¸‚องคุณ บัà¸à¸Šà¸µà¸£à¸°à¸šà¸šà¸—ี่ไม่ระบุตัวตนจะà¹à¸ªà¸”งเป็นนัà¸à¸‚่าวที่อินสà¹à¸•นซ์ระยะไà¸à¸¥"
+forwardReportIsAnonymous: "ข้อมูลของคุณจะไม่ปราà¸à¸à¸šà¸™à¸­à¸´à¸™à¸ªà¹à¸•นซ์ระยะไà¸à¸¥à¹à¸¥à¸°à¸›à¸£à¸²à¸à¸à¹€à¸›à¹‡à¸™à¸šà¸±à¸à¸Šà¸µà¸£à¸°à¸šà¸šà¸—ี่ไม่ระบุชื่อ"
send: "ส่ง"
abuseMarkAsResolved: "ทำเครื่องหมายรายงานว่าà¹à¸à¹‰à¹„ขà¹à¸¥à¹‰à¸§"
openInNewTab: "เปิดในà¹à¸—็บใหม่"
@@ -699,7 +699,7 @@ openInSideView: "เปิดในมุมมองด้านข้าง"
defaultNavigationBehaviour: "พฤติà¸à¸£à¸£à¸¡à¸à¸²à¸£à¸™à¸³à¸—างที่เป็นค่าเริ่มต้น"
editTheseSettingsMayBreakAccount: "à¸à¸²à¸£à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸•ั้งค่าเหล่านี้อาจทำให้บัà¸à¸Šà¸µà¸‚องคุณเสียหายนะ"
instanceTicker: "ข้อมูลอินสà¹à¸•นซ์ของโน้ต"
-waitingFor: "à¸à¸³à¸¥à¸±à¸‡à¸£à¸­à¸„อย {x}"
+waitingFor: "à¸à¸³à¸¥à¸±à¸‡à¸£à¸­ {x}"
random: "สุ่มค่า"
system: "ระบบ"
switchUi: "สลับ UI"
@@ -709,7 +709,7 @@ createNew: "สร้างใหม่"
optional: "ไม่บังคับ"
createNewClip: "สร้างคลิปใหม่"
unclip: "ลบคลิป"
-confirmToUnclipAlreadyClippedNote: "โน้ตนี้เป็นส่วนหนึ่งของคลิป \"{name}\" à¹à¸¥à¹‰à¸§ คุณต้องà¸à¸²à¸£à¸¥à¸šà¸­à¸­à¸à¸ˆà¸²à¸à¸„ลิปนี้à¹à¸—นอย่างงั้นหรอ?"
+confirmToUnclipAlreadyClippedNote: "โน้ตนี้เป็นส่วนหนึ่งของคลิป “{name}†อยู่à¹à¸¥à¹‰à¸§ ต้องà¸à¸²à¸£à¸™à¸³à¸¡à¸±à¸™à¸­à¸­à¸à¸ˆà¸²à¸à¸„ลิปใช่ไหม?"
public: "สาธารณะ"
private: "ส่วนตัว"
i18nInfo: "Misskey à¸à¸³à¸¥à¸±à¸‡à¹„ด้รับà¸à¸²à¸£à¹à¸›à¸¥à¹€à¸›à¹‡à¸™à¸ à¸²à¸©à¸²à¸•่างๆ โดยอาสาสมัคร คุณสามารถช่วยเหลือได้ที่ {link}"
@@ -732,7 +732,7 @@ driveFilesCount: "จำนวนไฟล์ไดรฟ์"
driveUsage: "à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸žà¸·à¹‰à¸™à¸—ี่ไดรฟ์"
noCrawle: "ปà¸à¸´à¹€à¸ªà¸˜à¸à¸²à¸£à¸ˆà¸±à¸”ทำดัชนีของโปรà¹à¸à¸£à¸¡à¸£à¸§à¸šà¸£à¸§à¸¡à¸‚้อมูล"
noCrawleDescription: "ขอให้เครื่องมือค้นหาไม่จัดทำดัชนีหน้าโปรไฟล์ โน้ต หน้าเพจ ฯลฯ"
-lockedAccountInfo: "เว้นà¹à¸•่ว่าคุณจะต้องตั้งค่าà¸à¸²à¸£à¹€à¸›à¸´à¸”เผยโน้ตเป็น \"ผู้ติดตามเท่านั้น\" โน้ตย่อของคุณจะปราà¸à¸à¹à¸à¹ˆà¸—ุà¸à¸„น ถึงà¹à¸¡à¹‰à¸§à¹ˆà¸²à¸„ุณจะเป็นà¸à¸³à¸«à¸™à¸”ให้ผู้ติดตามต้องได้รับà¸à¸²à¸£à¸­à¸™à¸¸à¸¡à¸±à¸•ิด้วยตนเองà¸à¹‡à¸•าม"
+lockedAccountInfo: "à¹à¸¡à¹‰à¸§à¹ˆà¸²à¸à¸²à¸£à¸­à¸™à¸¸à¸¡à¸±à¸•ิà¸à¸²à¸£à¸•ิดตามถูà¸à¹€à¸›à¸´à¸”ใช้งานอยู่ทุà¸à¸„นà¸à¹‡à¸¢à¸±à¸‡à¸„งสามารถเห็นโน้ตของคุณได้ เว้นà¹à¸•่ว่าคุณจะเปลี่ยนà¸à¸²à¸£à¹€à¸›à¸´à¸”เผยโน้ตของคุณเป็น “เฉพาะผู้ติดตามâ€"
alwaysMarkSensitive: "ทำเครื่องหมายว่ามีเนื้อหาละเอียดอ่อนเป็นค่าเริ่มต้น"
loadRawImages: "โหลดภาพต้นฉบับà¹à¸—นà¸à¸²à¸£à¹à¸ªà¸”งภาพขนาดย่อ"
disableShowingAnimatedImages: "ไม่ต้องเล่นภาพเคลื่อนไหว"
@@ -768,29 +768,29 @@ nNotes: "{n} โน้ต"
sendErrorReports: "ส่งรายงานว่าข้อผิดพลาด"
sendErrorReportsDescription: "เมื่อเปิดใช้งาน ข้อมูลข้อผิดพลาดโดยรายละเอียดนั้นจะถูà¸à¹à¸Šà¸£à¹Œà¹ƒà¸«à¹‰à¸à¸±à¸š Misskey เมื่อเà¸à¸´à¸”ปัà¸à¸«à¸² ซึ่งช่วยปรับปรุงคุณภาพของ Misskey\nซึ่งจะรวมถึงข้อมูล เช่น เวอร์ชั่นของระบบปà¸à¸´à¸šà¸±à¸•ิà¸à¸²à¸£ เบราว์เซอร์ที่คุณใช้ à¸à¸´à¸ˆà¸à¸£à¸£à¸¡à¸‚องคุณใน Misskey เป็นต้น"
myTheme: "ธีมของฉัน"
-backgroundColor: "ภาพพื้นหลัง"
-accentColor: "รูปà¹à¸šà¸šà¸ªà¸µ"
+backgroundColor: "สีพื้นหลัง"
+accentColor: "สีหลัà¸"
textColor: "สีข้อความ"
saveAs: "บันทึà¸à¹€à¸›à¹‡à¸™..."
advanced: "ขั้นสูง"
advancedSettings: "à¸à¸²à¸£à¸•ั้งค่าขั้นสูง"
value: "ค่า"
createdAt: "สร้างเมื่อ"
-updatedAt: "อัพเดทล่าสุด"
+updatedAt: "อัปเดตล่าสุด"
saveConfirm: "บันทึà¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸¡à¸±à¹‰à¸¢?"
deleteConfirm: "ลบจริงๆเหรอ?"
invalidValue: "ค่านี้ไม่ถูà¸à¸•้อง"
registry: "ทะเบียน"
closeAccount: "ปิด บัà¸à¸Šà¸µ"
currentVersion: "เวอร์ชั่นปัจจุบัน"
-latestVersion: "รุ่นปัจจุบัน"
+latestVersion: "เวอร์ชั่นล่าสุด"
youAreRunningUpToDateClient: "คุณà¸à¸³à¸¥à¸±à¸‡à¹ƒà¸Šà¹‰à¹„คลเอ็นต์เวอร์ชันใหม่ล่าสุดนะ"
newVersionOfClientAvailable: "มีไคลเอ็นต์เวอร์ชันใหม่à¸à¸§à¹ˆà¸²à¸‚องคุณพร้อมใช้งานนะ"
usageAmount: "à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™"
capacity: "ความจุ"
inUse: "ใช้à¹à¸¥à¹‰à¸§"
editCode: "à¹à¸à¹‰à¹„ขโค้ด"
-apply: "ตà¸à¸¥à¸‡"
+apply: "นำไปใช้"
receiveAnnouncementFromInstance: "รับà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนจาà¸à¸­à¸´à¸™à¸ªà¹à¸•นซ์นี้"
emailNotification: "à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนทางอีเมล"
publish: "เผยà¹à¸žà¸£à¹ˆ"
@@ -802,7 +802,7 @@ showingPastTimeline: "à¸à¸³à¸¥à¸±à¸‡à¹à¸ªà¸”งผลไทม์ไลน์à
clear: "ล้าง"
markAllAsRead: "ทำเครื่องหมายทั้งหมดว่าอ่านà¹à¸¥à¹‰à¸§"
goBack: "ย้อนà¸à¸¥à¸±à¸š"
-unlikeConfirm: "เลิà¸à¸–ูà¸à¹ƒà¸ˆà¸ˆà¸£à¸´à¸‡à¹† หรือ?"
+unlikeConfirm: "ต้องà¸à¸²à¸£à¹€à¸¥à¸´à¸à¸–ูà¸à¹ƒà¸ˆà¹ƒà¸Šà¹ˆà¹„หม?"
fullView: "มุมมองà¹à¸šà¸šà¹€à¸•็ม"
quitFullView: "ออà¸à¸ˆà¸²à¸à¸¡à¸¸à¸¡à¸¡à¸­à¸‡à¹à¸šà¸šà¹€à¸•็ม"
addDescription: "เพิ่มคำอธิบาย"
@@ -813,12 +813,12 @@ userInfo: "ข้อมูลผู้ใช้"
unknown: "ไม่ทราบสถานะ"
onlineStatus: "สถานะออนไลน์"
hideOnlineStatus: "ซ่อนสถานะออนไลน์"
-hideOnlineStatusDescription: "à¸à¸²à¸£à¸‹à¹ˆà¸­à¸™à¸ªà¸–านะออนไลน์ของคุณช่วยลดความสะดวà¸à¸‚องคุณสมบัติบางอย่าง เช่น à¸à¸²à¸£à¸„้นหา อ่ะนะ"
+hideOnlineStatusDescription: "à¸à¸²à¸£à¸‹à¹ˆà¸­à¸™à¸ªà¸–านะออนไลน์อาจทำให้ฟังà¸à¹Œà¸Šà¸±à¸™à¸šà¸²à¸‡à¸­à¸¢à¹ˆà¸²à¸‡ เช่น à¸à¸²à¸£à¸„้นหา สะดวà¸à¸™à¹‰à¸­à¸¢à¸¥à¸‡"
online: "ออนไลน์"
active: "ใช้งานอยู่"
offline: "ออฟไลน์"
notRecommended: "ไม่à¹à¸™à¸°à¸™à¸³"
-botProtection: "à¸à¸²à¸£à¸›à¹‰à¸­à¸‡à¸à¸±à¸™ Bot (or AI)"
+botProtection: "à¸à¸²à¸£à¸›à¹‰à¸­à¸‡à¸à¸±à¸™ Bot"
instanceBlocking: "อินสà¹à¸•นซ์ที่ถูà¸à¸šà¸¥à¹‡à¸­à¸"
selectAccount: "เลือà¸à¸šà¸±à¸à¸Šà¸µ"
switchAccount: "สลับบัà¸à¸Šà¸µà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰"
@@ -880,7 +880,7 @@ itsOff: "ปิดใช้งาน"
on: "เปิด"
off: "ปิด"
emailRequiredForSignup: "จำเป็นต้องà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸—ี่อยู่อีเมลสำหรับà¸à¸²à¸£à¸ªà¸¡à¸±à¸„ร"
-unread: "ไม่ได้อ่าน"
+unread: "ยังไม่ได้อ่าน"
filter: "à¸à¸£à¸­à¸‡"
controlPanel: "à¹à¸œà¸‡à¸„วบคุม"
manageAccounts: "จัดà¸à¸²à¸£à¸šà¸±à¸à¸Šà¸µ"
@@ -888,13 +888,13 @@ makeReactionsPublic: "ตั้งค่าประวัติà¸à¸²à¸£à¸£à¸µà
makeReactionsPublicDescription: "à¸à¸²à¸£à¸—ำเช่นนี้จะทำให้รายà¸à¸²à¸£à¸£à¸µà¹à¸­à¸„ชั่นของคุณที่ผ่านมาทั้งหมดปราà¸à¸à¸•่อสาธารณะ"
classic: "คลาสสิค"
muteThread: "ปิดเสียงเธรด"
-unmuteThread: "เปิดเสียงเธรด"
+unmuteThread: "เลิà¸à¸›à¸´à¸”เสียงเธรด"
followingVisibility: "à¸à¸²à¸£à¸¡à¸­à¸‡à¹€à¸«à¹‡à¸™à¸—ี่เราà¸à¸³à¸¥à¸±à¸‡à¸•ิดตาม"
followersVisibility: "à¸à¸²à¸£à¸¡à¸­à¸‡à¹€à¸«à¹‡à¸™à¸œà¸¹à¹‰à¸—ี่à¸à¸³à¸¥à¸±à¸‡à¸•ิดตามเรา"
continueThread: "ดูความต่อเนื่องเธรด"
deleteAccountConfirm: "à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸™à¸µà¹‰à¸ˆà¸°à¸¥à¸šà¸šà¸±à¸à¸Šà¸µà¸‚องคุณอย่างถาวรเลยนะ à¹à¸™à¹ˆà¹ƒà¸ˆà¸«à¸£à¸­à¸”ำเนินà¸à¸²à¸£?"
incorrectPassword: "รหัสผ่านไม่ถูà¸à¸•้อง"
-voteConfirm: "ยืนยันà¸à¸²à¸£à¹‚หวต “{choice}†ไหม?"
+voteConfirm: "ต้องà¸à¸²à¸£à¹‚หวต “{choice}†ใช่ไหม?"
hide: "ซ่อน"
useDrawerReactionPickerForMobile: "à¹à¸ªà¸”ง ตัวจิ้มรีà¹à¸­à¸„ชั่น เป็นà¹à¸šà¸šà¸¥à¸´à¹‰à¸™à¸Šà¸±à¸ เมื่อใช้บนมือถือ"
welcomeBackWithName: "ยินดีต้อนรับà¸à¸²à¸£à¸à¸¥à¸±à¸šà¸¡à¸²à¸™à¸°à¸„ะ, คุณ{name}"
@@ -941,13 +941,13 @@ deleteAccount: "ลบบัà¸à¸Šà¸µ"
document: "เอà¸à¸ªà¸²à¸£"
numberOfPageCache: "จำนวนหน้าเพจที่à¹à¸„ช"
numberOfPageCacheDescription: "à¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡à¸ˆà¸³à¸™à¸§à¸™à¸™à¸µà¹‰à¸ˆà¸°à¸Šà¹ˆà¸§à¸¢à¹€à¸žà¸´à¹ˆà¸¡à¸„วามสะดวà¸à¹ƒà¸«à¹‰à¸à¸±à¸šà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸‡à¸²à¸™ à¹à¸•่จะทำให้เซิร์ฟเวอร์โหลดมาà¸à¸‚ึ้นà¹à¸¥à¸°à¸•้องใช้หน่วยความจำมาà¸à¸‚ึ้นอีà¸à¸”้วย"
-logoutConfirm: "ต้องà¸à¸²à¸£à¸­à¸­à¸à¸ˆà¸²à¸à¸£à¸°à¸šà¸š?"
-lastActiveDate: "ใช้งานล่าสุดที่"
+logoutConfirm: "ต้องà¸à¸²à¸£à¸­à¸­à¸à¸ˆà¸²à¸à¸£à¸°à¸šà¸šà¹ƒà¸Šà¹ˆà¹„หม?"
+lastActiveDate: "ใช้งานล่าสุดเมื่อ"
statusbar: "à¹à¸–บสถานะ"
pleaseSelect: "ตัวเลือà¸"
-reverse: "ย้อนà¸à¸¥à¸±à¸š"
+reverse: "พลิà¸"
colored: "สี"
-refreshInterval: "รอบà¸à¸²à¸£à¸­à¸±à¸žà¹€à¸”ต"
+refreshInterval: "ความถี่ในà¸à¸²à¸£à¸­à¸±à¸›à¹€à¸”ต"
label: "ป้ายชื่อ"
type: "รูปà¹à¸šà¸š"
speed: "ความเร็ว"
@@ -974,8 +974,8 @@ unsubscribePushNotification: "ปิดà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนà¹à¸
pushNotificationAlreadySubscribed: "à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนà¹à¸šà¸šà¸žà¸¸à¸Šà¹„ด้เปิดใช้งานà¹à¸¥à¹‰à¸§"
pushNotificationNotSupported: "เบราว์เซอร์หรืออินสà¹à¸•นซ์ของคุณนั้นไม่รองรับà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนà¹à¸šà¸šà¸žà¸¸à¸Š"
sendPushNotificationReadMessage: "ลบà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนà¹à¸šà¸šà¸žà¸¸à¸Šà¹€à¸¡à¸·à¹ˆà¸­à¸­à¹ˆà¸²à¸™à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนหรือข้อความที่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้องà¹à¸¥à¹‰à¸§"
-sendPushNotificationReadMessageCaption: "à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนที่มีข้อความ \"{emptyPushNotificationMessage}\" จะà¹à¸ªà¸”งขึ้นมาในช่วงระยะเวลาสั้นๆ à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸™à¸µà¹‰à¸­à¸²à¸ˆà¸—ำให้เพิ่มà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹à¸šà¸•เตอรี่ของอุปà¸à¸£à¸“์ถ้าหาà¸à¸¡à¸µà¸™à¸°"
-windowMaximize: "ขยายใหà¸à¹ˆà¸ªà¸¸à¸”à¹à¸¥à¹‰à¸§"
+sendPushNotificationReadMessageCaption: "อาจทำให้อุปà¸à¸£à¸“์ของคุณใช้พลังงานมาà¸à¸‚ึ้น"
+windowMaximize: "ขยายใหà¸à¹ˆà¸ªà¸¸à¸”"
windowMinimize: "ย่อเล็à¸à¸—ี่สุด"
windowRestore: "เลิà¸à¸—ำ"
caption: "คำอธิบาย"
@@ -991,6 +991,7 @@ neverShow: "ไม่ต้องà¹à¸ªà¸”งข้อความนี้อà¸
remindMeLater: "ไว้ครั้งหน้าà¹à¸¥à¹‰à¸§à¸à¸±à¸™"
didYouLikeMisskey: "คุณชอบ Misskey ไหม?"
pleaseDonate: "Misskey เป็นซอฟต์à¹à¸§à¸£à¹Œà¸Ÿà¸£à¸µà¸—ี่ใช้งานโดย {host} เราขอขอบคุณà¸à¸²à¸£à¸ªà¸™à¸±à¸šà¸ªà¸™à¸¸à¸™à¸‚องคุณอย่างสูงเพื่อให้à¸à¸²à¸£à¸žà¸±à¸’นา Misskey สามารถดำเนินต่อไปได้!"
+correspondingSourceIsAvailable: "ซอร์สโค้ดที่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้องมีอยู่ที่ {anchor}"
roles: "บทบาท"
role: "บทบาท"
noRole: "ไม่พบบทบาท"
@@ -1059,7 +1060,7 @@ enableChartsForFederatedInstances: "สร้างà¹à¸œà¸™à¸ à¸¹à¸¡à¸´à¸‚้à¸
showClipButtonInNoteFooter: "เพิ่ม “คลิป†ไปยังเมนูสั่งà¸à¸²à¸£à¸‚องโน้ต"
reactionsDisplaySize: "ขนาดของรีà¹à¸­à¸„ชั่น"
limitWidthOfReaction: "จำà¸à¸±à¸”ความà¸à¸§à¹‰à¸²à¸‡à¸ªà¸¹à¸‡à¸ªà¸¸à¸”ของรีà¹à¸­à¸„ชั่นà¹à¸¥à¸°à¹à¸ªà¸”งให้เล็à¸à¸¥à¸‡"
-noteIdOrUrl: "โน้ต ID หรือ URL"
+noteIdOrUrl: "ID ของโน้ต หรือ URL"
video: "วีดีโอ"
videos: "วีดีโอ"
audio: "เสียง"
@@ -1081,7 +1082,7 @@ leftBottom: "ล่างซ้าย"
rightBottom: "ล่างขวา"
stackAxis: "ทิศทางà¸à¸²à¸£à¸‹à¹‰à¸­à¸™"
vertical: "à¹à¸™à¸§à¸•ั้ง"
-horizontal: "ด้านข้าง"
+horizontal: "à¹à¸™à¸§à¸™à¸­à¸™"
position: "ตำà¹à¸«à¸™à¹ˆà¸‡"
serverRules: "à¸à¸Žà¸‚องเซิร์ฟเวอร์"
pleaseConfirmBelowBeforeSignup: "โปรดยืนยันที่ด้านล่างà¸à¹ˆà¸­à¸™à¸ªà¸¡à¸±à¸„รใช้งาน"
@@ -1097,17 +1098,17 @@ thisChannelArchived: "ช่องนี้ถูà¸à¹€à¸à¹‡à¸šà¸–าวรà¹à
displayOfNote: "à¸à¸²à¸£à¹à¸ªà¸”งโน้ต"
initialAccountSetting: "ตั้งค่าโปรไฟล์"
youFollowing: "ติดตามà¹à¸¥à¹‰à¸§"
-preventAiLearning: "ปà¸à¸´à¹€à¸ªà¸˜à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™ ในà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¸£à¸¹à¹‰à¸‚องเครื่อง (Generative AI)"
-preventAiLearningDescription: "à¸à¸²à¸£à¸ªà¹ˆà¸‡à¸„ำร้องขอโปรà¹à¸à¸£à¸¡à¸£à¸§à¸šà¸£à¸§à¸¡à¸‚้อมูลไม่ให้ใช้ข้อความที่โพสต์หรือรูปภาพ ฯลฯ ในชุดข้อมูลà¹à¸¡à¸Šà¸Šà¸µà¸™à¹€à¸¥à¸´à¸£à¹Œà¸™à¸™à¸´à¸‡ (Predictive / Generative AI) สิ่งนี้นั้นทำได้โดยà¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡à¹à¸Ÿà¸¥à¹‡à¸à¸à¸²à¸£à¸•อบสนอง \"noai\" HTML ให้à¸à¸±à¸šà¹€à¸™à¸·à¹‰à¸­à¸«à¸²à¸—ี่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้อง à¹à¸•่อย่างไรà¸à¹‡à¸•ามà¹à¸¥à¹‰à¸§ à¸à¸²à¸£à¸›à¹‰à¸­à¸‡à¸à¸±à¸™à¹‚ดยสมบูรณ์นั้นไม่สามารถทำได้ผ่านà¹à¸Ÿà¸¥à¹‡à¸à¸™à¸µà¹‰à¹€à¸™à¸·à¹ˆà¸­à¸‡à¸ˆà¸²à¸à¸­à¸²à¸ˆà¸ˆà¸°à¸—ำให้ถูà¸à¹€à¸žà¸´à¸à¹€à¸‰à¸¢à¹„ด้"
+preventAiLearning: "ปà¸à¸´à¹€à¸ªà¸˜à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¸£à¸¹à¹‰à¸”้วย generative AI"
+preventAiLearningDescription: "ส่งคำร้องขอไม่ให้ใช้ ข้อความในโน้ตที่โพสต์, หรือเนื้อหารูปภาพ ฯลฯ ในà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¸£à¸¹à¹‰à¸‚องเครื่อง(machine learning) / Predictive AI / Generative AI โดยà¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡à¹à¸Ÿà¸¥à¹‡à¸ “noai†ลง HTML-Response ให้à¸à¸±à¸šà¹€à¸™à¸·à¹‰à¸­à¸«à¸²à¸—ี่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้อง à¹à¸•่ทั้งนี้ ไม่ได้ป้องà¸à¸±à¸™ AI จาà¸à¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸™à¸£à¸¹à¹‰à¹„ด้อย่างสมบูรณ์ เนื่องจาà¸à¸¡à¸µ AI บางตัวเท่านั้นที่จะเคารพคำขอดังà¸à¸¥à¹ˆà¸²à¸§"
options: "ตัวเลือà¸à¸šà¸—บาท"
specifyUser: "ผู้ใช้เฉพาะ"
failedToPreviewUrl: "ไม่สามารถดูตัวอย่างได้"
update: "อัปเดต"
rolesThatCanBeUsedThisEmojiAsReaction: "บทบาทที่สามารถใช้เอโมจินี้เป็นรีà¹à¸­à¸„ชั่นได้"
-rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "ถ้าหาà¸à¹„ม่ได้ระบุบทบาท ทุà¸à¸„นนั้นà¸à¹‡à¸ªà¸²à¸¡à¸²à¸£à¸–ใช้เอโมจินี้เพื่อรีà¹à¸­à¸„ชั่นได้นะ"
+rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "ถ้าหาà¸à¹„ม่ได้ระบุบทบาท ใคร ๆ à¸à¹‡à¸ªà¸²à¸¡à¸²à¸£à¸–ใช้เอโมจินี้เพื่อรีà¹à¸­à¸„ชั่นได้"
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "บทบาทเหล่านี้ต้องเป็นสาธารณะ"
-cancelReactionConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¸£à¸µà¹à¸­à¸„ชั่นของคุณจริงๆหรอ?"
-changeReactionConfirm: "ต้องà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸µà¹à¸­à¸„ชั่นของคุณจริงๆหรอ?"
+cancelReactionConfirm: "ต้องà¸à¸²à¸£à¸¥à¸šà¸£à¸µà¹à¸­à¸„ชั่นใช่ไหม?"
+changeReactionConfirm: "ต้องà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸µà¹à¸­à¸„ชั่นใช่ไหม?"
later: "ไว้ทีหลัง"
goToMisskey: "ถึง Misskey"
additionalEmojiDictionary: "พจนานุà¸à¸£à¸¡à¹€à¸­à¹‚มจิเพิ่มเติม"
@@ -1116,20 +1117,20 @@ branding: "à¹à¸šà¸£à¸™à¸”ิ้ง"
enableServerMachineStats: "เผยà¹à¸žà¸£à¹ˆà¸ªà¸–านะฮาร์ดà¹à¸§à¸£à¹Œà¸‚องเซิร์ฟเวอร์"
enableIdenticonGeneration: "เปิดใช้งานผู้ใช้สร้างตัวระบุ"
turnOffToImprovePerformance: "à¸à¸²à¸£à¸›à¸´à¸”ส่วนนี้สามารถเพิ่มประสิทธิภาพได้"
-createInviteCode: "สร้างคำเชิà¸"
+createInviteCode: "สร้างรหัสเชิà¸"
createWithOptions: "สร้างด้วยตัวเลือà¸"
-createCount: "จำนวนà¸à¸²à¸£à¹€à¸Šà¸´à¸"
-inviteCodeCreated: "สร้างคำเชิà¸à¹à¸¥à¹‰à¸§"
-inviteLimitExceeded: "คุณสร้างคำเชิà¸à¹€à¸à¸´à¸™à¸–ึงขีดจำà¸à¸±à¸”à¹à¸¥à¹‰à¸§à¸™à¸°"
-createLimitRemaining: "ขีดจำà¸à¸±à¸”à¸à¸²à¸£à¹€à¸Šà¸´à¸: {limit} ที่เหลืออยู่"
-inviteLimitResetCycle: "ขีดจำà¸à¸±à¸”นี้จะถูà¸à¸£à¸µà¹€à¸‹à¹‡à¸•เป็น {limit} ที่ {time}."
+createCount: "จำนวนรหัสเชิà¸"
+inviteCodeCreated: "สร้างรหัสเชิà¸à¹à¸¥à¹‰à¸§"
+inviteLimitExceeded: "จำนวนรหัสเชิà¸à¸—ี่สามารถสร้างได้ถึงขีดจำà¸à¸±à¸”à¹à¸¥à¹‰à¸§"
+createLimitRemaining: "รหัสเชิà¸à¸—ี่สามารถสร้างได้: เหลืออยู่ {limit} รหัส"
+inviteLimitResetCycle: "สามารถสร้างรหัสเชิà¸à¹„ด้อีà¸à¸ªà¸¹à¸‡à¸ªà¸¸à¸” {limit} รหัส ภายใน {time}"
expirationDate: "วันที่หมดอายุ"
noExpirationDate: "ไม่มีหมดอายุ"
-inviteCodeUsedAt: "รหัสคำเชิà¸à¹ƒà¸Šà¹‰à¹à¸¥à¹‰à¸§à¸—ี่"
-registeredUserUsingInviteCode: "ใช้คำเชิà¸à¹à¸¥à¹‰à¸§à¹‚ดย"
+inviteCodeUsedAt: "วันเวลาที่ใช้รหัสเชิà¸"
+registeredUserUsingInviteCode: "ผู้ใช้ที่ใช้รหัสเชิà¸"
waitingForMailAuth: "à¸à¸³à¸¥à¸±à¸‡à¸£à¸­à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸­à¸µà¹€à¸¡à¸¥"
-inviteCodeCreator: "สร้างà¸à¸²à¸£à¹€à¸Šà¸´à¸à¹à¸¥à¹‰à¸§à¹‚ดย"
-usedAt: "ใช้à¹à¸¥à¹‰à¸§à¸—ี่"
+inviteCodeCreator: "ผู้ใช้ที่สร้างรหัสเชิà¸"
+usedAt: "วันเวลาที่ถูà¸à¹ƒà¸Šà¹‰"
unused: "ยังไม่ได้ใช้"
used: "ถูà¸à¹ƒà¸Šà¹‰à¹à¸¥à¹‰à¸§"
expired: "หมดอายุà¹à¸¥à¹‰à¸§"
@@ -1148,7 +1149,7 @@ renotes: "รีโน้ต"
loadReplies: "à¹à¸ªà¸”งà¸à¸²à¸£à¸•อบà¸à¸¥à¸±à¸š"
loadConversation: "à¹à¸ªà¸”งบทสนทนา"
pinnedList: "รายชื่อที่ปัà¸à¸«à¸¡à¸¸à¸”ไว้"
-keepScreenOn: "เปิดหน้าจอไว้"
+keepScreenOn: "เปิดหน้าจออุปà¸à¸£à¸“์ค้างไว้"
verifiedLink: "ความเป็นเจ้าของลิงà¸à¹Œà¹„ด้รับà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¹à¸¥à¹‰à¸§"
notifyNotes: "à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¹‚พสต์ใหม่"
unnotifyNotes: "หยุดà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¹‚น้ตใหม่"
@@ -1159,6 +1160,7 @@ showRenotes: "à¹à¸ªà¸”งรีโน้ต"
edited: "à¹à¸à¹‰à¹„ขà¹à¸¥à¹‰à¸§"
notificationRecieveConfig: "à¸à¸²à¸£à¸•ั้งค่าà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือน"
mutualFollow: "ติดตามซึ่งà¸à¸±à¸™à¹à¸¥à¸°à¸à¸±à¸™"
+followingOrFollower: "à¸à¸³à¸¥à¸±à¸‡à¸•ิดตามหรือผู้ติดตาม"
fileAttachedOnly: "เฉพาะโน้ตที่มีไฟล์เท่านั้น"
showRepliesToOthersInTimeline: "à¹à¸ªà¸”งà¸à¸²à¸£à¸•อบà¸à¸¥à¸±à¸šà¸œà¸¹à¹‰à¸­à¸·à¹ˆà¸™à¸¥à¸‡à¹ƒà¸™à¹„ทม์ไลน์"
hideRepliesToOthersInTimeline: "ไม่à¹à¸ªà¸”งà¸à¸²à¸£à¸•อบà¸à¸¥à¸±à¸šà¸œà¸¹à¹‰à¸­à¸·à¹ˆà¸™à¸¥à¸‡à¹ƒà¸™à¹„ทม์ไลน์"
@@ -1168,6 +1170,12 @@ confirmShowRepliesAll: "à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸™à¸µà¹‰à¹„ม่à¸
confirmHideRepliesAll: "à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸™à¸µà¹‰à¹„ม่สามารถย้อนà¸à¸¥à¸±à¸šà¹„ด้ คุณต้องà¸à¸²à¸£à¸‹à¹ˆà¸­à¸™à¸à¸²à¸£à¸•อบà¸à¸¥à¸±à¸šà¸œà¸¹à¹‰à¸­à¸·à¹ˆà¸™à¸ˆà¸²à¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸—ุà¸à¸„นที่คุณติดตามอยู่ในไทม์ไลน์ของคุณหรือไม่?"
externalServices: "บริà¸à¸²à¸£à¸ à¸²à¸¢à¸™à¸­à¸"
sourceCode: "ซอร์สโค้ด"
+sourceCodeIsNotYetProvided: "ซอร์สโค้ดยังไม่พร้อมใช้งาน โปรดติดต่อผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¸‚องคุณเพื่อà¹à¸à¹‰à¹„ขปัà¸à¸«à¸²à¸™à¸µà¹‰"
+repositoryUrl: "URL ของ repository"
+repositoryUrlDescription: "หาà¸à¸¡à¸µà¸—ี่เà¸à¹‡à¸šà¸‹à¸­à¸£à¹Œà¸ªà¹‚ค้ดที่เปิดเผยต่อสาธารณะ ให้ป้อน URL ที่เà¸à¹‡à¸šà¸‹à¸­à¸£à¹Œà¸ªà¹‚ค้ดนั้น à¹à¸•่หาà¸à¸„ุณใช้ Misskey ตามต้นฉบับ (ไม่มีà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸‹à¸­à¸£à¹Œà¸ªà¹‚ค้ด) ให้ป้อน https://github.com/misskey-dev/misskey"
+repositoryUrlOrTarballRequired: "หาà¸à¸„ุณไม่มี repository สาธารณะ คุณจะต้องจัดเตรียม tarball à¹à¸—น ดู .config/example.yml สำหรับรายละเอียด"
+feedback: "ฟีดà¹à¸šà¹‡à¸"
+feedbackUrl: "URLของฟีดà¹à¸šà¹‡à¸"
impressum: "อิมเพรสชั่น"
impressumUrl: "URL อิมเพรสชั่น"
impressumDescription: "à¸à¸²à¸£à¸•ิดป้ายà¸à¸³à¸à¸±à¸š (Impressum) มีผลบังคับใช้ในบางประเทศà¹à¸¥à¸°à¸ à¸¹à¸¡à¸´à¸ à¸²à¸„ เช่น ประเทศเยอรมนี"
@@ -1179,7 +1187,7 @@ attach: "à¹à¸™à¸š"
detach: "นำออà¸"
detachAll: "เอาออà¸à¸—ั้งหมด"
angle: "à¹à¸­à¸‡à¹€à¸à¸´à¸¥"
-flip: "ย้อนà¸à¸¥à¸±à¸š"
+flip: "พลิà¸"
showAvatarDecorations: "à¹à¸ªà¸”งตà¸à¹à¸•่งอวตาร"
releaseToRefresh: "ปล่อยเพื่อรีเฟรช"
refreshing: "à¸à¸³à¸¥à¸±à¸‡à¸£à¸µà¹€à¸Ÿà¸£à¸Š..."
@@ -1203,15 +1211,29 @@ soundWillBePlayed: "จะมีà¸à¸²à¸£à¹€à¸¥à¹ˆà¸™à¹€à¸­à¸Ÿà¹€à¸Ÿà¸à¸•์เ
showReplay: "ดูรีเพลย์"
replay: "รีเพลย์"
replaying: "à¸à¸³à¸¥à¸±à¸‡à¸£à¸µà¹€à¸žà¸¥à¸¢à¹Œ"
+endReplay: "ออà¸à¸ˆà¸²à¸à¸£à¸µà¹€à¸žà¸¥à¸¢à¹Œ"
+copyReplayData: "คัดลอà¸à¸‚้อมูลรีเพลย์"
ranking: "อันดับ"
lastNDays: "ล่าสุด {n} วันที่à¹à¸¥à¹‰à¸§"
backToTitle: "à¸à¸¥à¸±à¸šà¹„ปหน้าไตเติ้ล"
hemisphere: "พื้นที่ที่อาศัยอยู่"
-withSensitive: "à¹à¸ªà¸”งโน้ตที่มีไฟล์ที่ระบุว่ามีเนื้อหาละเอียดอ่อน"
+withSensitive: "à¹à¸ªà¸”งโน้ตที่มีไฟล์เนื้อหาละเอียดอ่อน"
userSaysSomethingSensitive: "โพสต์ที่มีไฟล์เนื้อหาละเอียดอ่อนของ {name}"
enableHorizontalSwipe: "ปัดเพื่อสลับà¹à¸—็บ"
+loading: "à¸à¸³à¸¥à¸±à¸‡à¹‚หลด"
+surrender: "ยอมà¹à¸žà¹‰"
+gameRetry: "เริ่มเà¸à¸¡à¹ƒà¸«à¸¡à¹ˆ"
_bubbleGame:
howToPlay: "วิธีเล่น"
+ hold: "หยุดชั่วคราว"
+ _score:
+ score: "คะà¹à¸™à¸™"
+ scoreYen: "จำนวนเงินที่ได้รับ"
+ highScore: "คะà¹à¸™à¸™à¸ªà¸¹à¸‡à¸ªà¸¸à¸”"
+ maxChain: "จำนวน chain สูงสุด"
+ yen: "{yen} เยน"
+ estimatedQty: "{qty} อัน"
+ scoreSweets: "โอนิงิริ {onigiriQtyWithUnit}"
_howToPlay:
section1: "ขยับตำà¹à¸«à¸™à¹ˆà¸‡à¹à¸¥à¸°à¸§à¸²à¸‡à¸§à¸±à¸•ถุลงในà¸à¸¥à¹ˆà¸­à¸‡"
section2: "เมื่อวัตถุประเภทเดียวà¸à¸±à¸™à¸¡à¸²à¸£à¸§à¸¡à¸à¸±à¸™ พวà¸à¸¡à¸±à¸™à¸ˆà¸°à¸à¸¥à¸²à¸¢à¹€à¸›à¹‡à¸™à¸§à¸±à¸•ถุใหม่à¹à¸¥à¸°à¸„ุณจะได้รับคะà¹à¸™à¸™"
@@ -1219,16 +1241,16 @@ _bubbleGame:
_announcement:
forExistingUsers: "ผู้ใช้งานที่มีอยู่เท่านั้น"
forExistingUsersDescription: "à¸à¸²à¸£à¸›à¸£à¸°à¸à¸²à¸¨à¸™à¸µà¹‰à¸ˆà¸°à¹à¸ªà¸”งต่อผู้ใช้ที่มีอยู่ ณ จุดที่เผยà¹à¸žà¸£à¹ˆà¸™à¸±à¹‰à¸™à¹†à¸–้าหาà¸à¹€à¸›à¸´à¸”ใช้งาน ถ้าหาà¸à¸›à¸´à¸”ใช้งานผู้ที่à¸à¸³à¸¥à¸±à¸‡à¸ªà¸¡à¸±à¸„รใหม่หลังจาà¸à¹‚พสต์à¹à¸¥à¹‰à¸§à¸™à¸±à¹‰à¸™à¸à¹‡à¸ˆà¸°à¹€à¸«à¹‡à¸™à¹€à¸Šà¹ˆà¸™à¸à¸±à¸™"
- needConfirmationToRead: "จำเป็นต้องยืนยันเพื่อทำเครื่องหมายบอà¸à¸§à¹ˆà¸²à¸­à¹ˆà¸²à¸™à¹à¸¥à¹‰à¸§"
- needConfirmationToReadDescription: "ข้อความà¹à¸ˆà¹‰à¸‡à¹à¸¢à¸ ถ้าหาà¸à¸•้องà¸à¸²à¸£à¹€à¸žà¸·à¹ˆà¸­à¸¢à¸·à¸™à¸¢à¸±à¸™à¸§à¹ˆà¸²à¸à¸³à¸¥à¸±à¸‡à¸—ำเครื่องหมายประà¸à¸²à¸¨à¸™à¸µà¹‰à¸§à¹ˆà¸²à¸­à¹ˆà¸²à¸™à¹à¸¥à¹‰à¸§à¸ˆà¸°à¹à¸ªà¸”งขึ้นถ้าหาà¸à¹€à¸›à¸´à¸”ใช้งาน à¸à¸²à¸£à¸›à¸£à¸°à¸à¸²à¸¨à¸™à¸±à¹‰à¸™à¸ˆà¸°à¹„ม่รวมอยู่ในฟังà¸à¹Œà¸Šà¸±à¹ˆà¸™à¸§à¹ˆà¸² \"ทำเครื่องหมายทั้งหมดว่าอ่านà¹à¸¥à¹‰à¸§\""
+ needConfirmationToRead: "จำเป็นต้องยืนยันว่าอ่านà¹à¸¥à¹‰à¸§"
+ needConfirmationToReadDescription: "à¸à¸¥à¹ˆà¸­à¸‡à¹‚ต้ตอบà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸ˆà¸°à¸›à¸£à¸²à¸à¸à¸‚ึ้นเมื่อจะทำเครื่องหมายว่าอ่านà¹à¸¥à¹‰à¸§ นอà¸à¸ˆà¸²à¸à¸™à¸µà¹‰à¸¢à¸±à¸‡à¸—ำให้ประà¸à¸²à¸¨à¸™à¸µà¹‰à¸¢à¸±à¸‡à¹„ม่ถูà¸à¸­à¹ˆà¸²à¸™à¹€à¸¡à¸·à¹ˆà¸­à¹ƒà¸Šà¹‰à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¹ˆà¸™ “ทำเครื่องหมายฯ ทั้งหมดว่าอ่านà¹à¸¥à¹‰à¸§â€"
end: "เà¸à¹‡à¸šà¸›à¸£à¸°à¸à¸²à¸¨"
tooManyActiveAnnouncementDescription: "à¸à¸²à¸£à¸¡à¸µà¸›à¸£à¸°à¸à¸²à¸¨à¸—ี่ใช้งานมาà¸à¹€à¸à¸´à¸™à¹„ปนั้นอาจจะทำให้ประสบà¸à¸²à¸£à¸“์ของผู้ใช้งานนั้นดูà¹à¸¢à¹ˆà¸¥à¸‡ โปรดà¸à¸£à¸¸à¸“าพิจารณาà¸à¸²à¸£à¹€à¸à¹‡à¸šà¸›à¸£à¸°à¸à¸²à¸¨à¸—ี่ล้าสมัยด้วยนะค่ะ"
- readConfirmTitle: "ทำเครื่องหมายบอà¸à¸§à¹ˆà¸²à¸­à¹ˆà¸²à¸™à¹à¸¥à¹‰à¸§à¹€à¸¥à¸¢à¸¡à¸±à¹‰à¸¢?"
- readConfirmText: "à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸™à¸µà¹‰à¸ˆà¸°à¸—ำเครื่องหมายเนื้อหาของ \"{title}\" บอà¸à¸§à¹ˆà¸²à¸­à¹ˆà¸²à¸™à¹à¸¥à¹‰à¸§à¸™à¸°"
+ readConfirmTitle: "ทำเครื่องหมายว่าอ่านà¹à¸¥à¹‰à¸§à¹€à¸¥à¸¢à¹„หม?"
+ readConfirmText: "จะทำเครื่องหมายใส่ “{title}†ว่าอ่านà¹à¸¥à¹‰à¸§"
shouldNotBeUsedToPresentPermanentInfo: "เราขอà¹à¸™à¸°à¸™à¸³à¹ƒà¸«à¹‰à¹ƒà¸Šà¹‰à¸›à¸£à¸°à¸à¸²à¸¨à¹€à¸žà¸·à¹ˆà¸­à¹‚พสต์ข้อมูลà¹à¸šà¸š flow มาà¸à¸à¸§à¹ˆà¸²à¸‚้อมูลà¹à¸šà¸š stock เนื่องจาà¸à¸¡à¸µà¹à¸™à¸§à¹‚น้มที่จะส่งผลเสียต่อ UX โดยเฉพาะสำหรับผู้ใช้ใหม่"
dialogAnnouncementUxWarn: "เราขอà¹à¸™à¸°à¸™à¸³à¹ƒà¸«à¹‰à¹ƒà¸Šà¹‰à¸”้วยความระมัดระวัง เนื่องจาà¸à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนà¹à¸šà¸šà¸à¸¥à¹ˆà¸­à¸‡à¹‚ต้ตอบตั้งà¹à¸•่ 2 รายà¸à¸²à¸£à¸‚ึ้นไปพร้อมà¸à¸±à¸™à¸­à¸²à¸ˆà¸ªà¹ˆà¸‡à¸œà¸¥à¹€à¸ªà¸µà¸¢à¸•่อ UX ได้อย่างมาà¸"
silence: "ไม่มีà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือน"
- silenceDescription: "หาà¸à¹€à¸›à¸´à¸”ใช้งาน จะไม่ได้à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนประà¸à¸²à¸¨à¸™à¸µà¹‰ à¹à¸¥à¸°à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸ˆà¸°à¹„ม่จำเป็นต้องอ่าน"
+ silenceDescription: "หาà¸à¹€à¸›à¸´à¸”ใช้งาน จะไม่มีà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนประà¸à¸²à¸¨à¸™à¸µà¹‰ à¹à¸¥à¸°à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸ˆà¸°à¹„ม่จำเป็นต้องทำเครื่องหมายว่าอ่านà¹à¸¥à¹‰à¸§"
_initialAccountSetting:
accountCreated: "คุณได้สร้างบัà¸à¸Šà¸µà¸‚องคุณสำเร็จเรียบร้อยà¹à¸¥à¹‰à¸§!"
letsStartAccountSetup: "สำหรับผู้เริ่มต้นมาตั้งค่าโปรไฟล์ของคุณà¸à¸±à¸™à¹€à¸–อะ"
@@ -1315,7 +1337,7 @@ _timelineDescription:
_serverRules:
description: "ชุดของà¸à¸Žà¸—ี่จะà¹à¸ªà¸”งà¸à¹ˆà¸­à¸™à¸à¸²à¸£à¸¥à¸‡à¸—ะเบียนเราขอà¹à¸™à¸°à¸™à¸³à¹ƒà¸«à¹‰à¸•ั้งค่าสรุปข้อà¸à¸³à¸«à¸™à¸”ในà¸à¸²à¸£à¹ƒà¸«à¹‰à¸šà¸£à¸´à¸à¸²à¸£"
_serverSettings:
- iconUrl: "ไอคอน URL"
+ iconUrl: "URL ไอคอน"
appIconDescription: "ระบุไอคอนที่จะใช้เมื่อ {host} à¹à¸ªà¸”งเป็นà¹à¸­à¸›"
appIconUsageExample: "E.g. เป็น PWA หรือเมื่อà¹à¸ªà¸”งผลเป็นบุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸«à¸™à¹‰à¸²à¸ˆà¸­à¸«à¸¥à¸±à¸à¸šà¸™à¹‚ทรศัพท์"
appIconStyleRecommendation: "เนื่องจาà¸à¹„อคอนอาจถูà¸à¸„รอบตัดเป็นสี่เหลี่ยมจัตุรัสหรือวงà¸à¸¥à¸¡ จึงà¹à¸™à¸°à¸™à¸³à¹ƒà¸«à¹‰à¹ƒà¸Šà¹‰à¹„อคอนที่มีขอบสีรอบๆ เนื้อหา"
@@ -1603,7 +1625,7 @@ _role:
assignTarget: "มอบหมาย"
descriptionOfAssignTarget: "à¹à¸šà¸š<b>ปรับเอง</b> เพิ่มถอนบทบาทนี้à¹à¸à¹ˆà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸”้วยตัวเอง\nà¹à¸šà¸š<b>มีเงื่อนไข</b> เพิ่มถอนบทบาทนี้à¹à¸à¹ˆà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¹‚ดยอัตโนมัติหาà¸à¹€à¸‚้าเงื่อนไขใดต่อไปนี้"
manual: "ปรับเอง"
- manualRoles: "บทบาทà¹à¸šà¸šà¸—ำเอง"
+ manualRoles: "บทบาทà¹à¸šà¸šà¸—ำมือ"
conditional: "มีเงื่อนไข"
conditionalRoles: "บทบาทà¹à¸šà¸šà¸¡à¸µà¹€à¸‡à¸·à¹ˆà¸­à¸™à¹„ข"
condition: "เงื่อนไข"
@@ -1615,13 +1637,13 @@ _role:
baseRole: "เทมเพลตบทบาท"
useBaseValue: "ใช้ตามเทมเพลตบทบาท"
chooseRoleToAssign: "เลือà¸à¸šà¸—บาทที่ต้องà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”"
- iconUrl: "ไอคอน URL"
+ iconUrl: "URL ไอคอน"
asBadge: "à¹à¸ªà¸”งเป็นตรา"
descriptionOfAsBadge: "เมื่อเปิดใช้งาน ไอคอนบทบาทจะปราà¸à¸à¸–ัดจาà¸à¸Šà¸·à¹ˆà¸­à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰"
isExplorable: "ค้นหาผู้ใช้ได้ง่ายขึ้นโดยดูจาà¸à¸šà¸—บาท"
descriptionOfIsExplorable: "เมื่อเปิดใช้งาน ไทมไลน์บทบาทนี้à¹à¸¥à¸°à¸ªà¸¡à¸²à¸Šà¸´à¸à¸—ี่มีบทบาทนี้จะเปิดเผยเป็นสาธารณะ"
- displayOrder: "ตำà¹à¸«à¸™à¹ˆà¸‡"
- descriptionOfDisplayOrder: "ยิ่งตัวเลขสูง ตำà¹à¸«à¸™à¹ˆà¸‡ UI à¸à¹‡à¸¢à¸´à¹ˆà¸‡à¸ªà¸¹à¸‡à¸‚ึ้นนะ"
+ displayOrder: "ลำดับà¸à¸²à¸£à¹à¸ªà¸”งผล"
+ descriptionOfDisplayOrder: "เลขที่สูงà¸à¸§à¹ˆà¸²à¸ˆà¸°à¹à¸ªà¸”งบน UI à¸à¹ˆà¸­à¸™"
canEditMembersByModerator: "อนุà¸à¸²à¸•ให้ผู้ควบคุมà¹à¸à¹‰à¹„ขสมาชิà¸"
descriptionOfCanEditMembersByModerator: "เมื่อเปิดใช้ นอà¸à¹€à¸«à¸™à¸·à¸­à¸ˆà¸²à¸à¸œà¸¹à¹‰à¸„วบคุมà¹à¸¥à¸°à¸œà¸¹à¹‰à¸”ูà¹à¸¥à¸£à¸°à¸šà¸šà¹à¸¥à¹‰à¸§ จะสามารถเพิ่มถอนบทบาทนี้à¹à¸à¹ˆà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¹„ด้ à¹à¸•่เมื่อปิดใช้ จะมีเฉพาะผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¹€à¸—่านั้นที่จะสามารถดำเนินà¸à¸²à¸£à¹„ด้"
priority: "ลำดับความสำคัà¸"
@@ -1633,6 +1655,7 @@ _role:
gtlAvailable: "à¸à¸²à¸£à¸”ูไทม์ไลน์ทั่วโลà¸"
ltlAvailable: "à¸à¸²à¸£à¸”ูไทม์ไลน์ในท้องถิ่น"
canPublicNote: "สามารถโพสต์à¹à¸šà¸šà¸ªà¸²à¸˜à¸²à¸£à¸“ะ"
+ mentionMax: "จำนวนà¸à¸²à¸£à¸à¸¥à¹ˆà¸²à¸§à¸–ึงสูงสุดต่อโน้ต"
canInvite: "สร้างรหัสเชิà¸à¸­à¸´à¸™à¸ªà¹à¸•นซ์"
inviteLimit: "จำà¸à¸±à¸”à¸à¸²à¸£à¹€à¸Šà¸´à¸"
inviteLimitCycle: "คูลดาวน์ในà¸à¸²à¸£à¹€à¸Šà¸´à¸"
@@ -1656,6 +1679,7 @@ _role:
canUseTranslator: "à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹à¸›à¸¥"
avatarDecorationLimit: "จำนวนà¸à¸²à¸£à¸•à¸à¹à¸•่งไอคอนสูงสุดที่สามารถติดตั้งได้"
_condition:
+ roleAssignedTo: "มอบหมายให้มีบทบาทà¹à¸šà¸šà¸—ำมือ"
isLocal: "ผู้ใช้ในพื้นที่"
isRemote: "ผู้ใช้ระยะไà¸à¸¥"
createdLessThan: "สร้างน้อยà¸à¸§à¹ˆà¸²"
@@ -1685,13 +1709,13 @@ _emailUnavailable:
smtp: "เซิร์ฟเวอร์อีเมลนี้ไม่มีà¸à¸²à¸£à¸•อบสนอง"
banned: "คุณไม่สามารถลงทะเบียนด้วยที่อยู่อีเมลนี้ได้"
_ffVisibility:
- public: "เผยà¹à¸žà¸£à¹ˆ"
+ public: "สาธารณะ"
followers: "ปราà¸à¸à¹ƒà¸«à¹‰à¹à¸à¹ˆà¸œà¸¹à¹‰à¸•ิดตามเท่านั้น"
private: "ส่วนตัว"
_signup:
almostThere: "เà¸à¸·à¸­à¸šà¸ˆà¸°à¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§"
emailAddressInfo: "à¸à¸£à¸¸à¸“าà¸à¸£à¸­à¸à¸—ี่อยู่อีเมลที่คุณใช้ ที่อยู่อีเมลของคุณจะไม่ถูà¸à¹€à¸œà¸¢à¹à¸žà¸£à¹ˆà¸ªà¸¹à¹ˆà¸ªà¸²à¸˜à¸²à¸£à¸“ชน"
- emailSent: "เราได้ส่งอีเมลยืนยันไปยังที่อยู่อีเมลของคุณà¹à¸¥à¹‰à¸§à¸™à¸° ({email}) โปรดคลิà¸à¸¥à¸´à¸‡à¸à¹Œà¸—ี่รวมไว้เพื่อสร้างบัà¸à¸Šà¸µà¹ƒà¸«à¹‰à¹€à¸ªà¸£à¹‡à¸ˆà¸ªà¸´à¹‰à¸™"
+ emailSent: "อีเมลยืนยันได้ถูà¸à¸ªà¹ˆà¸‡à¹„ปยังที่อยู่อีเมลที่คุณป้อน ({email}) à¹à¸¥à¹‰à¸§ à¸à¸£à¸¸à¸“าติดตามลิงà¸à¹Œà¹ƒà¸™à¸­à¸µà¹€à¸¡à¸¥à¹€à¸žà¸·à¹ˆà¸­à¸ªà¸£à¹‰à¸²à¸‡à¸šà¸±à¸à¸Šà¸µà¹ƒà¸«à¹‰à¹€à¸ªà¸£à¹‡à¸ˆà¸ªà¸¡à¸šà¸¹à¸£à¸“์ ลิงà¸à¹Œà¸—ี่ให้ไว้จะหมดอายุใน 30 นาที"
_accountDelete:
accountDelete: "ลบบัà¸à¸Šà¸µà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰"
mayTakeTime: "เนื่องจาà¸à¸à¸²à¸£à¸¥à¸šà¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¸ˆà¸°à¹€à¸›à¹‡à¸™à¸à¸£à¸°à¸šà¸§à¸™à¸à¸²à¸£à¸—ี่ต้องใช้ทรัพยาà¸à¸£à¸¡à¸²à¸ จึงอาจจะต้องใช้เวลาสัà¸à¸„รู่ถึงจะเสร็จสมบูรณ์ ทั้งนี้ขึ้นอยู่à¸à¸±à¸šà¸ˆà¸³à¸™à¸§à¸™à¹€à¸™à¸·à¹‰à¸­à¸«à¸²à¸—ี่คุณสร้างà¹à¸¥à¸°à¸ˆà¸³à¸™à¸§à¸™à¹„ฟล์ที่คุณอัปโหลดนะ"
@@ -1729,7 +1753,7 @@ _plugin:
viewSource: "ดูต้นฉบับ"
_preferencesBackups:
list: "สร้างà¸à¸²à¸£à¸ªà¸³à¸£à¸­à¸‡à¸‚้อมูล"
- saveNew: "บันทึà¸à¹ƒà¸«à¸¡à¹ˆ"
+ saveNew: "บันทึà¸à¸‚้อมูลสำรองใหม่"
loadFile: "โหลดจาà¸à¹„ฟล์"
apply: "นำไปใช้à¸à¸±à¸šà¸­à¸¸à¸›à¸à¸£à¸“์นี้"
save: "บันทึà¸"
@@ -1739,8 +1763,8 @@ _preferencesBackups:
applyConfirm: "คุณต้องà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‚้อมูลสำรอง \"{name}\" à¸à¸±à¸šà¸­à¸¸à¸›à¸à¸£à¸“์นี้อย่างงั้นจริงหรอ à¸à¸²à¸£à¸•ั้งค่าที่มีอยู่ของอุปà¸à¸£à¸“์นี้จะถูà¸à¹€à¸‚ียนทับนะ"
saveConfirm: "บันทึà¸à¸‚้อมูลสำรองเป็น {name} มั้ย?"
deleteConfirm: "ลบข้อมูลสำรอง {name} มั้ย?"
- renameConfirm: "เปลี่ยนชื่อข้อมูลสำรองนี้จาภ\"{old}\" เป็น \"{new}\" หรือไม่?"
- noBackups: "ไม่มีข้อมูลสำรองนะ คุณสามารถสำรองข้อมูลà¸à¸²à¸£à¸•ั้งค่าไคลเอนต์ของคุณบนเซิร์ฟเวอร์นี้โดยใช้ \"สร้างà¸à¸²à¸£à¸ªà¸³à¸£à¸­à¸‡à¸‚้อมูลใหม่\"ได้นะ"
+ renameConfirm: "ต้องà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸Šà¸·à¹ˆà¸­à¸‚้อมูลสำรองจาภ“{old}†เป็น “{new}†ใช่ไหม?"
+ noBackups: "ไม่มีข้อมูลสำรอง สามารถบันทึà¸à¸à¸²à¸£à¸•ั้งค่าไคลเอนต์ปัจจุบันไปยังเซิร์ฟเวอร์ด้วย “บันทึà¸à¸‚้อมูลสำรองใหม่â€"
createdAt: "สร้างเมื่อ: {date} {time}"
updatedAt: "อัปเดตเมื่อ: {date} {time}"
cannotLoad: "à¸à¸²à¸£à¹‚หลดล้มเหลว"
@@ -1756,14 +1780,16 @@ _aboutMisskey:
contributors: "ผู้สนับสนุนหลัà¸"
allContributors: "ผู้มีส่วนร่วมทั้งหมด"
source: "ซอร์สโค้ด"
+ original: "ต้นฉบับ"
+ thisIsModifiedVersion: "{name} ใช้ Misskey เวอร์ชันดัดà¹à¸›à¸¥à¸‡"
translation: "à¹à¸›à¸¥à¸ à¸²à¸©à¸² Misskey"
donate: "บริจาคให้à¸à¸±à¸š Misskey"
- morePatrons: " ขอบคุณทุà¸à¸—่านที่ร่วมà¸à¸±à¸™à¸Šà¹ˆà¸§à¸¢à¹€à¸«à¸¥à¸·à¸­à¸•ลอดมานะคะ 🥰"
- patrons: "สมาชิà¸à¸žà¸±à¸™à¸˜à¸¡à¸´à¸•ร"
+ morePatrons: "à¹à¸¥à¸°à¸­à¸µà¸à¸«à¸¥à¸²à¸¢à¸—่านที่ไม่ได้เอ่ยนาม ขอบคุณที่ร่วมช่วยเหลือตลอดมานะคะ 🥰"
+ patrons: "ผู้อุปถัมภ์"
projectMembers: "สมาชิà¸à¹ƒà¸™à¹‚ครงà¸à¸²à¸£"
_displayOfSensitiveMedia:
- respect: "ซ่อนสื่อที่ทำเครื่องหมายว่ามีเนื้อหาละเอียดอ่อน"
- ignore: "à¹à¸ªà¸”งสื่อที่ทำเครื่องหมายว่ามีเนื้อหาละเอียดอ่อน"
+ respect: "ซ่อนสื่อที่มีเนื้อหาละเอียดอ่อน"
+ ignore: "à¹à¸ªà¸”งสื่อที่มีเนื้อหาละเอียดอ่อน"
force: "ซ่อนสื่อทั้งหมด"
_instanceTicker:
none: "ไม่ต้องà¹à¸ªà¸”ง"
@@ -1831,8 +1857,8 @@ _theme:
importInfo: "ถ้าหาà¸à¸•้องà¸à¸²à¸£à¸›à¹‰à¸­à¸™à¹‚ค้ดที่นี่ คุณยังสามารถนำเข้าไปยังโปรà¹à¸à¸£à¸¡à¹à¸à¹‰à¹„ขธีมได้"
deleteConstantConfirm: "คุณต้องà¸à¸²à¸£à¸¥à¸šà¸„่าคงที่ {const} หรือป่าว?"
keys:
- accent: "เน้น"
- bg: "ภาพพื้นหลัง"
+ accent: "สีหลัà¸"
+ bg: "พื้นหลัง"
fg: "ข้อความ"
focus: "โฟà¸à¸±à¸ª"
indicator: "ตัวบ่งชี้"
@@ -1868,11 +1894,11 @@ _theme:
wallpaperOverlay: "วอลล์เปเปอร์ซ้อนทับ"
badge: "ตรา"
messageBg: "พื้นหลังà¹à¸Šà¸—"
- accentDarken: "เน้น (มืด)"
- accentLighten: "เน้น (สว่าง)"
+ accentDarken: "สีหลัภ(มืด)"
+ accentLighten: "สีหลัภ(สว่าง)"
fgHighlighted: "ข้อความที่ไฮไลต์"
_sfx:
- note: "หมายเหตุ"
+ note: "โน้ต"
noteMy: "โน้ตของตัวเอง"
notification: "à¸à¸²à¸£à¹€à¹€à¸ˆà¹‰à¸‡à¹€à¸•ือน"
antenna: "เสาอาà¸à¸²à¸¨"
@@ -1959,7 +1985,7 @@ _permissions:
"read:reactions": "ดูรีà¹à¸­à¸„ชั่นของคุณ"
"write:reactions": "à¹à¸à¹‰à¹„ขรีà¹à¸­à¸„ชั่นของคุณ"
"write:votes": "โหวตบนสำรวจความคิดเห็น"
- "read:pages": "ดหน้าเพจ"
+ "read:pages": "ดูหน้าเพจ"
"write:pages": "à¹à¸à¹‰à¹„ขหรือลบเพจของคุณ"
"read:page-likes": "ดูรายà¸à¸²à¸£à¹€à¸žà¸ˆà¸—ี่ถูà¸à¹ƒà¸ˆà¹„ว้"
"write:page-likes": "à¹à¸à¹‰à¹„ขรายà¸à¸²à¸£à¹€à¸žà¸ˆà¸—ี่ถูà¸à¹ƒà¸ˆ"
@@ -1971,8 +1997,8 @@ _permissions:
"write:gallery": "à¹à¸à¹‰à¹„ขà¹à¸à¸¥à¹€à¸¥à¸­à¸£à¸µà¹ˆà¸‚องคุณ"
"read:gallery-likes": "ดูรายà¸à¸²à¸£à¹‚พสต์à¹à¸à¸¥à¹€à¸¥à¸­à¸£à¸µà¸—ี่ถูà¸à¹ƒà¸ˆà¹„ว้"
"write:gallery-likes": "à¹à¸à¹‰à¹„ขรายà¸à¸²à¸£à¹‚พสต์à¹à¸à¸¥à¹€à¸¥à¸­à¸£à¸µà¸—ี่ถูà¸à¹ƒà¸ˆà¹„ว้"
- "read:flash": "วิว เพลย์"
- "write:flash": "à¹à¸à¹‰à¹„ขเพลย์"
+ "read:flash": "ดู Play"
+ "write:flash": "à¹à¸à¹‰à¹„ข Play"
"read:flash-likes": "ดูรายà¸à¸²à¸£ play ที่ถูà¸à¹ƒà¸ˆà¹„ว้"
"write:flash-likes": "à¹à¸à¹‰à¹„ขรายà¸à¸²à¸£ play ที่ถูà¸à¹ƒà¸ˆà¹„ว้"
"read:admin:abuse-user-reports": "ดูรายงานจาà¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰"
@@ -1999,8 +2025,8 @@ _permissions:
"read:admin:roles": "ดูบทบาท"
"write:admin:relays": "จัดà¸à¸²à¸£à¸£à¸µà¹€à¸¥à¸¢à¹Œ"
"read:admin:relays": "ดูรีเลย์"
- "write:admin:invite-codes": "จัดà¸à¸²à¸£à¸„ำเชิà¸"
- "read:admin:invite-codes": "ดูรหัสคำเชิà¸"
+ "write:admin:invite-codes": "จัดà¸à¸²à¸£à¸£à¸«à¸±à¸ªà¹€à¸Šà¸´à¸"
+ "read:admin:invite-codes": "ดูรหัสเชิà¸"
"write:admin:announcements": "จัดà¸à¸²à¸£à¸›à¸£à¸°à¸à¸²à¸¨"
"read:admin:announcements": "ดูประà¸à¸²à¸¨"
"write:admin:avatar-decorations": "จัดà¸à¸²à¸£à¸à¸²à¸£à¸•à¸à¹à¸•่งอวตาร"
@@ -2018,7 +2044,7 @@ _permissions:
"read:admin:stream": "ใช้ Websocket API สำหรับผู้ดูà¹à¸¥à¸£à¸°à¸šà¸š"
"write:admin:ad": "จัดà¸à¸²à¸£à¹‚ฆษณา"
"read:admin:ad": "ดูโฆษณา"
- "write:invite-codes": "สร้างรหัสคำเชิà¸"
+ "write:invite-codes": "สร้างรหัสเชิà¸"
"read:invite-codes": "รับรหัสเชิà¸"
"write:clip-favorite": "ควบคุมà¸à¸²à¸£à¸–ูà¸à¹ƒà¸ˆà¸‚องคลิป"
"read:clip-favorite": "ดูà¸à¸²à¸£à¸–ูà¸à¹ƒà¸ˆà¸‚องคลิป"
@@ -2071,8 +2097,8 @@ _widgets:
onlineUsers: "ผู้ใช้ที่ออนไลน์"
jobQueue: "คิวงาน"
serverMetric: "ตัวชี้วัดเซิร์ฟเวอร์"
- aiscript: "AiScript คอนโซล"
- aiscriptApp: "AiScript à¹à¸­à¸ž"
+ aiscript: " คอนโซล AiScript"
+ aiscriptApp: "à¹à¸­à¸› AiScript"
aichan: "ไอ"
userList: "รายชื่อผู้ใช้"
_userList:
@@ -2086,15 +2112,15 @@ _cw:
files: "{count} ไฟล์"
_poll:
noOnlyOneChoice: "จำเป็นต้องมีอย่างน้อยสองตัวเลือà¸"
- choiceN: "ตัวเลือภ{n}"
- noMore: "คุณไม่สามารถเพิ่มตัวเลือà¸à¸­à¸·à¹ˆà¸™à¹„ด้"
+ choiceN: "ตัวเลือà¸à¸—ี่ {n}"
+ noMore: "เพิ่มตัวเลือà¸à¸­à¸µà¸à¹„ม่ได้à¹à¸¥à¹‰à¸§"
canMultipleVote: "สามารถตอบได้หลายคำตอบ"
- expiration: "สิ้นสุดà¸à¸²à¸£à¸ªà¸³à¸£à¸§à¸ˆà¸„วามคิดเห็น"
- infinite: "ไม่ต้องเลย"
- at: "จบที่..."
- after: "สิ้นสุดหลัง..."
+ expiration: "สิ้นสุดโพล"
+ infinite: "ไม่à¸à¸³à¸«à¸™à¸”ระยะเวลา"
+ at: "ระบุวันเวลา"
+ after: "ระบุระยะเวลา"
deadlineDate: "วันสิ้นสุด"
- deadlineTime: "ชั่วโมง"
+ deadlineTime: "เวลา"
duration: "ระยะเวลา"
votesCount: "{n} คะà¹à¸™à¸™à¹€à¸ªà¸µà¸¢à¸‡"
totalVotes: "{n} คะà¹à¸™à¸™à¹€à¸ªà¸µà¸¢à¸‡à¸—ั้งหมด"
@@ -2102,17 +2128,17 @@ _poll:
showResult: "ดูผลลัพธ์"
voted: "โหวตà¹à¸¥à¹‰à¸§"
closed: "สิ้นสุดà¹à¸¥à¹‰à¸§"
- remainingDays: "จะเสร็จสิ้นในอีภ{d} วัน {h} ชั่วโมง"
- remainingHours: "{h} ชั่วโมง(s) {m} นาที(s) ที่เหลืออยู่"
- remainingMinutes: "{m} นาที(s) {s} วินาที(s) ที่เหลืออยู่"
- remainingSeconds: "{s} นาที(s) ที่เหลืออยู่"
+ remainingDays: "เหลืออีภ{d} วัน {h} ชั่วโมง"
+ remainingHours: "เหลืออีภ{h} ชั่วโมง {m} นาที"
+ remainingMinutes: "เหลืออีภ{m} นาที {s} วินาที"
+ remainingSeconds: "เหลืออีภ{s} วินาที"
_visibility:
public: "สาธารณะ"
publicDescription: "โน้ตของคุณจะปราà¸à¸à¹à¸à¹ˆà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸—ุà¸à¸„น"
home: "หน้าà¹à¸£à¸"
homeDescription: "โพสลงไทม์ไลน์ที่บ้านเท่านั้น"
followers: "ผู้ติดตาม"
- followersDescription: "ทำให้ผู้ติดตามนั้นมองเห็นà¹à¸„่คุณเท่านั้น"
+ followersDescription: "เฉพาะผู้ติดตามเท่านั้นที่มองเห็นได้"
specified: "ไดเร็ค"
specifiedDescription: "ทำให้มองเห็นได้เฉพาะผู้ใช้ที่ระบุเท่านั้น"
disableFederation: "ไม่มีสหพันธ์"
@@ -2122,11 +2148,11 @@ _postForm:
quotePlaceholder: "อ้างโน้ตนี้..."
channelPlaceholder: "โพสต์ลงช่อง..."
_placeholders:
- a: "คุณเป็นอะไรไปหรอ?"
- b: "เà¸à¸´à¸”อะไรขึ้นรอบตัวคุณ?"
- c: "คุณà¸à¸³à¸¥à¸±à¸‡à¸„ิดอะไรอยู่?"
- d: "คุณต้องà¸à¸²à¸£à¸ˆà¸°à¸žà¸¹à¸”อะไร?"
- e: "เริ่มเขียน..."
+ a: "ตอนนี้เป็นยังไงบ้าง?"
+ b: "มีอะไรเà¸à¸´à¸”ขึ้นหรือเปล่า?"
+ c: "à¸à¸³à¸¥à¸±à¸‡à¸„ิดอะไรอยู่?"
+ d: "ต้องà¸à¸²à¸£à¸ˆà¸°à¸žà¸¹à¸”อะไรไหม?"
+ e: "มาเขียนà¸à¸±à¸™à¹€à¸–อะ"
f: "à¸à¸³à¸¥à¸±à¸‡à¸£à¸­à¹ƒà¸«à¹‰à¸„ุณเขียน..."
_profile:
name: "ชื่อ"
@@ -2140,11 +2166,11 @@ _profile:
metadataContent: "เนื้อหา"
changeAvatar: "เปลี่ยนอวาตาร์"
changeBanner: "เปลี่ยนà¹à¸šà¸™à¹€à¸™à¸­à¸£à¹Œ"
- verifiedLinkDescription: "โดยà¸à¸²à¸£à¸›à¹‰à¸­à¸™ URL ที่มีลิงà¸à¹Œà¹„ปยังโปรไฟล์ของคุณตรงนี้ ส่วนไอคอนà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸„วามเป็นเจ้าของนั้นà¸à¹‡à¸ªà¸²à¸¡à¸²à¸£à¸–à¹à¸ªà¸”งถัดจาà¸à¸Ÿà¸´à¸¥à¸”์ได้นะ"
+ verifiedLinkDescription: "หาà¸à¸›à¹‰à¸­à¸™ URL ที่มีลิงà¸à¹Œà¹„ปยังโปรไฟล์ของคุณ ไอคอนà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸„วามเป็นเจ้าของจะà¹à¸ªà¸”งถัดจาà¸à¸Ÿà¸´à¸¥à¸”์นั้น ๆ"
avatarDecorationMax: "คุณสามารถเพิ่มà¸à¸²à¸£à¸•à¸à¹à¸•่งได้สูงสุด {max}"
_exportOrImport:
allNotes: "โน้ตทั้งหมด"
- favoritedNotes: "บันทึà¸à¸—ี่ชื่นชอบ"
+ favoritedNotes: "โน้ตที่ถูà¸à¹ƒà¸ˆà¹„ว้"
clips: "คลิป"
followingList: "à¸à¸³à¸¥à¸±à¸‡à¸•ิดตาม"
muteList: "ปิดเสียง"
@@ -2227,7 +2253,7 @@ _pages:
summary: "สรุปเพจ"
alignCenter: "เซ็นเตอร์"
hideTitleWhenPinned: "ซ่อนชื่อหน้าเพจเมื่อปัà¸à¸«à¸¡à¸¸à¸”ไว้ที่โปรไฟล์"
- font: "ตัวอัà¸à¸©à¸£"
+ font: "à¹à¸šà¸šà¸­à¸±à¸à¸©à¸£"
fontSerif: "Serif"
fontSansSerif: "Sans Serif"
eyeCatchingImageSet: "ตั้งค่าภาพขนาดย่อ"
@@ -2253,27 +2279,28 @@ _relayStatus:
accepted: "ได้รับà¸à¸²à¸£à¸­à¸™à¸¸à¸¡à¸±à¸•ิ"
rejected: "ถูà¸à¸›à¸à¸´à¹€à¸ªà¸˜"
_notification:
- fileUploaded: "ไฟล์ถูà¸à¸­à¸±à¸žà¹‚หลดà¹à¸¥à¹‰à¸§à¸™à¹ˆà¸°"
+ fileUploaded: "ไฟล์ถูà¸à¸­à¸±à¸›à¹‚หลดà¹à¸¥à¹‰à¸§"
youGotMention: "{name} à¸à¸¥à¹ˆà¸²à¸§à¸–ึงคุณ"
youGotReply: "{name} ตอบà¸à¸¥à¸±à¸šà¸–ึงคุณ"
- youGotQuote: "{name} อ้างถึงคุณ"
+ youGotQuote: "{name} อ้างอิงคุณ"
youRenoted: "รีโน้ตจาภ{name}"
youWereFollowed: "ได้ติดตามคุณ"
- youReceivedFollowRequest: "คุณมีคำขอติดตามใหม่น่ะ"
- yourFollowRequestAccepted: "คำขอติดตามของคุณได้รับà¸à¸²à¸£à¸¢à¸­à¸¡à¸£à¸±à¸šà¹à¸¥à¹‰à¸§à¸™à¹ˆà¸°"
- pollEnded: "โพลสำรวจความคิดเห็นผลลัพธ์มีพร้อมใช้งาน"
+ youReceivedFollowRequest: "ได้รับคำขอติดตาม"
+ yourFollowRequestAccepted: "คำขอติดตามได้รับà¸à¸²à¸£à¸­à¸™à¸¸à¸¡à¸±à¸•ิà¹à¸¥à¹‰à¸§"
+ pollEnded: "ผลโพลออà¸à¸¡à¸²à¹à¸¥à¹‰à¸§"
newNote: "โพสต์ใหม่"
unreadAntennaNote: "เสาอาà¸à¸²à¸¨ {name}"
roleAssigned: "ได้รับบทบาท"
- emptyPushNotificationMessage: "à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนà¹à¸šà¸šà¸žà¸¸à¸Šà¹„ด้รับà¸à¸²à¸£à¸­à¸±à¸žà¹€à¸”ทà¹à¸¥à¹‰à¸§"
+ emptyPushNotificationMessage: "อัปเดตà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนà¹à¸šà¸šà¸žà¸¸à¸Šà¹à¸¥à¹‰à¸§"
achievementEarned: "รับความสำเร็จ"
testNotification: "ทดสอบà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือน"
checkNotificationBehavior: "à¸à¸”เพื่อดูลัà¸à¸©à¸“ะà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือน"
sendTestNotification: "ส่งทดสอบà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือน"
notificationWillBeDisplayedLikeThis: "à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนมีลัà¸à¸©à¸“ะà¹à¸šà¸šà¸™à¸µà¹‰"
reactedBySomeUsers: "ถูà¸à¸£à¸µà¹à¸­à¸„ชั่นโดยผู้ใช้ {n} ราย"
- renotedBySomeUsers: "Renote จาà¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸ˆà¸³à¸™à¸§à¸™ {n} ราย"
+ renotedBySomeUsers: "รีโน้ตจาà¸à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰ {n} ราย"
followedBySomeUsers: "มีผู้ติดตาม {n} ราย"
+ flushNotification: "ล้างประวัติà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือน"
_types:
all: "ทั้งหมด"
note: "โน้ตใหม่"
@@ -2283,9 +2310,9 @@ _notification:
renote: "รีโน้ต"
quote: "อ้างคำพูด"
reaction: "รีà¹à¸­à¸„ชั่น"
- pollEnded: "โพลนี้สิ้นสุดลงà¹à¸¥à¹‰à¸§"
- receiveFollowRequest: "ได้รับคำขอติดตาม\n"
- followRequestAccepted: "ยอมรับคำขอติดตาม"
+ pollEnded: "โพลสิ้นสุดà¹à¸¥à¹‰à¸§"
+ receiveFollowRequest: "ได้รับคำร้องขอติดตาม"
+ followRequestAccepted: "อนุมัติให้ติดตามà¹à¸¥à¹‰à¸§"
roleAssigned: "ให้บทบาท"
achievementEarned: "ปลดล็อà¸à¸„วามสำเร็จà¹à¸¥à¹‰à¸§"
app: "à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•ือนจาà¸à¹à¸­à¸›à¸—ี่มีลิงà¸à¹Œ"
@@ -2322,7 +2349,7 @@ _deck:
list: "รายà¸à¸²à¸£"
channel: "ช่อง"
mentions: "พูดถึง"
- direct: "ไดเร็ค"
+ direct: "ไดเร็à¸à¸•์"
roleTimeline: "บทบาทไทม์ไลน์"
_dialog:
charactersExceeded: "คุณà¸à¸³à¸¥à¸±à¸‡à¸¡à¸µà¸•ัวอัà¸à¸‚ระเà¸à¸´à¸™à¸‚ีดจำà¸à¸±à¸”สูงสุดà¹à¸¥à¹‰à¸§à¸™à¸°! ปัจจุบันอยู่ที่ {current} จาภ{max}"
@@ -2353,8 +2380,8 @@ _moderationLogTypes:
updateRole: "อัปเดตบทบาทà¹à¸¥à¹‰à¸§"
assignRole: "ได้รับมอบหมายบทบาท"
unassignRole: "ถอดออà¸à¸ˆà¸²à¸à¸šà¸—บาทà¹à¸¥à¹‰à¸§"
- suspend: "ถูà¸à¸£à¸°à¸‡à¸±à¸š"
- unsuspend: "เลิà¸à¸–ูà¸à¸£à¸°à¸‡à¸±à¸š"
+ suspend: "ระงับ"
+ unsuspend: "เลิà¸à¸£à¸°à¸‡à¸±à¸š"
addCustomEmoji: "เพิ่มเอโมจิที่à¸à¸³à¸«à¸™à¸”เองà¹à¸¥à¹‰à¸§"
updateCustomEmoji: "อัปเดตเอโมจิที่à¸à¸³à¸«à¸™à¸”เองà¹à¸¥à¹‰à¸§"
deleteCustomEmoji: "ลบเอโมจิที่à¸à¸³à¸«à¸™à¸”เองออà¸à¹à¸¥à¹‰à¸§"
@@ -2369,12 +2396,13 @@ _moderationLogTypes:
deleteGlobalAnnouncement: "ลบประà¸à¸²à¸¨à¸—ั่วโลà¸à¸­à¸­à¸à¹à¸¥à¹‰à¸§"
deleteUserAnnouncement: "ลบประà¸à¸²à¸¨à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸­à¸­à¸à¹à¸¥à¹‰à¸§"
resetPassword: "รีเซ็ตรหัสผ่าน"
- suspendRemoteInstance: "อินสà¹à¸•นซ์ระยะไà¸à¸¥à¸–ูà¸à¸£à¸°à¸‡à¸±à¸š"
- unsuspendRemoteInstance: "อินสà¹à¸•นซ์ระยะไà¸à¸¥à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸£à¸°à¸‡à¸±à¸š"
+ suspendRemoteInstance: "ระงับอินสà¹à¸•นซ์ระยะไà¸à¸¥"
+ unsuspendRemoteInstance: "เลิà¸à¸£à¸°à¸‡à¸±à¸šà¸­à¸´à¸™à¸ªà¹à¸•นซ์ระยะไà¸à¸¥"
+ updateRemoteInstanceNote: "อัปเดตโน้ตà¸à¸²à¸£à¸à¸¥à¸±à¹ˆà¸™à¸à¸£à¸­à¸‡à¸‚องอินสà¹à¸•นซ์ระยะไà¸à¸¥à¹à¸¥à¹‰à¸§"
markSensitiveDriveFile: "ทำเครื่องหมายไฟล์ว่ามีเนื้อหาละเอียดอ่อน"
unmarkSensitiveDriveFile: "ยà¸à¹€à¸¥à¸´à¸à¸—ำเครื่องหมายไฟล์ว่ามีเนื้อหาละเอียดอ่อน"
resolveAbuseReport: "รายงานได้รับà¸à¸²à¸£à¹à¸à¹‰à¹„ขà¹à¸¥à¹‰à¸§"
- createInvitation: "สร้างคำเชิà¸"
+ createInvitation: "สร้างรหัสเชิà¸"
createAd: "สร้างโฆษณาà¹à¸¥à¹‰à¸§"
deleteAd: "ลบโฆษณาออà¸à¹à¸¥à¹‰à¸§"
updateAd: "อัปเดตโฆษณาà¹à¸¥à¹‰à¸§"
@@ -2491,6 +2519,8 @@ _reversi:
opponentHasSettingsChanged: "อีà¸à¸à¹ˆà¸²à¸¢à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸à¸²à¸£à¸•ั้งค่า"
allowIrregularRules: "อนุà¸à¸²à¸•à¸à¸Žà¸—ี่ไม่ปรà¸à¸•ิ (โหมดฟรีทุà¸à¸­à¸¢à¹ˆà¸²à¸‡)"
disallowIrregularRules: "ไม่อนุà¸à¸²à¸•à¸à¸Žà¸—ี่ไม่ปรà¸à¸•ิ"
+ showBoardLabels: "à¹à¸ªà¸”งหมายเลขà¹à¸–ว/คอลัมน์บนà¸à¸£à¸°à¸”าน"
+ useAvatarAsStone: "ใช้รูปอวตารเป็นหมาà¸"
_offlineScreen:
title: "ออฟไลน์ - ไม่สามารถเชื่อมต่อà¸à¸±à¸šà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹„ด้"
header: "ไม่สามารถเชื่อมต่อà¸à¸±à¸šà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹„ด้"
diff --git a/locales/vi-VN.yml b/locales/vi-VN.yml
index 7cfdde3204..59883f4a6c 100644
--- a/locales/vi-VN.yml
+++ b/locales/vi-VN.yml
@@ -1048,6 +1048,7 @@ verifiedLink: "Chúng tôi đã xác nhận bạn là chá»§ sở hữu cá»§a Ä‘Æ
sourceCode: "Mã nguồn"
flip: "Lật"
lastNDays: "{n} ngày trước"
+surrender: "Từ chối"
_announcement:
forExistingUsers: "Chỉ những ngưá»i dùng đã tồn tại"
forExistingUsersDescription: "Nếu được bật, thông báo này sẽ chỉ hiển thị vá»›i những ngưá»i dùng đã tồn tại vào lúc thông báo được tạo. Nếu tắt Ä‘i, những tài khoản má»›i đăng ký sau khi thông báo được đăng lên cÅ©ng sẽ thấy nó."
diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml
index d0891f0678..17ad6e7150 100644
--- a/locales/zh-CN.yml
+++ b/locales/zh-CN.yml
@@ -336,7 +336,7 @@ displayOfSensitiveMedia: "æ˜¾ç¤ºæ•æ„Ÿåª’体"
whenServerDisconnected: "与æœåŠ¡å™¨è¿žæŽ¥ä¸­æ–­æ—¶"
disconnectedFromServer: "已和æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥"
reload: "釿–°åŠ è½½"
-doNothing: "关闭弹窗"
+doNothing: "关闭"
reloadConfirm: "确定è¦é‡æ–°åŠ è½½å—?"
watch: "关注"
unwatch: "å–æ¶ˆå…³æ³¨"
@@ -991,6 +991,7 @@ neverShow: "ä¸å†æ˜¾ç¤º"
remindMeLater: "ç¨åŽæé†’æˆ‘"
didYouLikeMisskey: "您喜欢 Misskey å—?"
pleaseDonate: "Misskey 是 {host} 所使用的å…费软件。为了今åŽä¹Ÿèƒ½å¤Ÿç»´æŒ Misskey 的开å‘,请在有余力的情况下进行æåŠ©ï¼"
+correspondingSourceIsAvailable: "对应的æºä»£ç å¯åœ¨{anchor}找到"
roles: "角色"
role: "角色"
noRole: "角色ä¸å­˜åœ¨"
@@ -1042,6 +1043,7 @@ sensitiveWords: "æ•æ„Ÿè¯"
sensitiveWordsDescription: "将包å«è®¾ç½®è¯çš„帖å­çš„å¯è§èŒƒå›´è®¾ç½®ä¸ºé¦–页。å¯ä»¥é€šè¿‡ç”¨æ¢è¡Œç¬¦åˆ†éš”æ¥è®¾ç½®å¤šä¸ªã€‚"
sensitiveWordsDescription2: "AND æ¡ä»¶ç”¨ç©ºæ ¼åˆ†éš”,正则表达å¼ç”¨æ–œçº¿åŒ…裹。"
prohibitedWords: "ç¦ç”¨è¯"
+prohibitedWordsDescription: "å‘布包å«è®¾å®šè¯æ±‡çš„取孿—¶å°†å‡ºé”™ã€‚å¯ç”¨æ¢è¡Œè®¾å®šå¤šä¸ªå…³é”®å­—"
prohibitedWordsDescription2: "AND æ¡ä»¶ç”¨ç©ºæ ¼åˆ†éš”,正则表达å¼ç”¨æ–œçº¿åŒ…裹。"
hiddenTags: "éšè—标签"
hiddenTagsDescription: "设定的标签将ä¸ä¼šåœ¨æ—¶é—´çº¿ä¸Šæ˜¾ç¤ºã€‚å¯ä½¿ç”¨æ¢è¡Œæ¥è®¾ç½®å¤šä¸ªæ ‡ç­¾ã€‚"
@@ -1115,7 +1117,7 @@ branding: "å“牌"
enableServerMachineStats: "公开æœåŠ¡å™¨ç¡¬ä»¶ç»Ÿè®¡ä¿¡æ¯"
enableIdenticonGeneration: "å¯ç”¨ç”Ÿæˆç”¨æˆ· Identicon"
turnOffToImprovePerformance: "关闭该选项å¯ä»¥æé«˜æ€§èƒ½ã€‚"
-createInviteCode: "å‘行邀请ç "
+createInviteCode: "生æˆé‚€è¯·ç "
createWithOptions: "使用选项æ¥åˆ›å»º"
createCount: "å‘行数"
inviteCodeCreated: "已创建邀请ç "
@@ -1127,7 +1129,7 @@ noExpirationDate: "ä¸è®¾ç½®æœ‰æ•ˆæ—¥æœŸ"
inviteCodeUsedAt: "邀请ç è¢«ä½¿ç”¨çš„æ—¥æœŸå’Œæ—¶é—´"
registeredUserUsingInviteCode: "使用了邀请ç çš„用户"
waitingForMailAuth: "等待验è¯ç”µå­é‚®ä»¶"
-inviteCodeCreator: "å‘行邀请ç çš„用户"
+inviteCodeCreator: "生æˆé‚€è¯·ç çš„用户"
usedAt: "使用时间"
unused: "未使用"
used: "已使用"
@@ -1158,6 +1160,7 @@ showRenotes: "显示转帖"
edited: "已编辑"
notificationRecieveConfig: "通知接收设置"
mutualFollow: "互相关注"
+followingOrFollower: "关注中或关注者"
fileAttachedOnly: "ä»…é™åª’体"
showRepliesToOthersInTimeline: "在时间线中包å«ç»™åˆ«äººçš„回å¤"
hideRepliesToOthersInTimeline: "在时间线中éšè—给别人的回å¤"
@@ -1167,6 +1170,12 @@ confirmShowRepliesAll: "æ­¤æ“作ä¸å¯æ’¤é”€ã€‚确认è¦åœ¨æ—¶é—´çº¿ä¸­åŒ…å«çŽ
confirmHideRepliesAll: "æ­¤æ“作ä¸å¯æ’¤é”€ã€‚确认è¦åœ¨æ—¶é—´çº¿ä¸­éšè—现在关注的所有人的回å¤å—?"
externalServices: "外部æœåŠ¡"
sourceCode: "æºä»£ç "
+sourceCodeIsNotYetProvided: "还未æä¾›æºä»£ç ã€‚è¦è§£å†³æ­¤é—®é¢˜è¯·è”系管ç†å‘˜ã€‚"
+repositoryUrl: "仓库地å€"
+repositoryUrlDescription: "è‹¥æºä»£ç æ‰€åœ¨çš„仓库是公开的,请填入对应的 URL。若是按原样使用 Misskey(并未追加或者修改代ç ï¼‰çš„æƒ…况请填入 https://github.com/misskey-dev/misskey。"
+repositoryUrlOrTarballRequired: "è‹¥ä»“åº“å¹¶æœªå…¬å¼€ï¼Œåˆ™éœ€è¦æä¾› tarball 作为替代。详情请看 .config/example.yml。"
+feedback: "å馈"
+feedbackUrl: "å馈地å€"
impressum: "è¿è¥å•†ä¿¡æ¯"
impressumUrl: "è¿è¥å•†ä¿¡æ¯åœ°å€"
impressumDescription: "德国等国家和地区有义务展示此类信æ¯ï¼ˆImpressum)。"
@@ -1196,11 +1205,14 @@ seasonalScreenEffect: "åº”æ™¯çš„ç”»é¢æ•ˆæžœ"
decorate: "装饰"
addMfmFunction: "添加装饰"
enableQuickAddMfmFunction: "显示高级 MFM 选择器"
+bubbleGame: "泡泡游æˆ"
sfx: "音效"
soundWillBePlayed: "声音将会播放"
-showReplay: "æŸ¥çœ‹é‡æ’­"
+showReplay: "观看回放"
replay: "釿’­"
replaying: "釿’­ä¸­"
+endReplay: "结æŸå›žæ”¾"
+copyReplayData: "å¤åˆ¶å›žæ”¾æ•°æ®"
ranking: "排行榜"
lastNDays: "最近 {n} 天"
backToTitle: "返回标题"
@@ -1208,8 +1220,19 @@ hemisphere: "å±…ä½åœ°åŒº"
withSensitive: "æ˜¾ç¤ºåŒ…å«æ•感媒体的帖å­"
userSaysSomethingSensitive: "å« {name} æ•æ„Ÿæ–‡ä»¶çš„帖å­"
enableHorizontalSwipe: "æ»‘åŠ¨åˆ‡æ¢æ ‡ç­¾é¡µ"
+loading: "读å–中"
+surrender: "å–æ¶ˆ"
+gameRetry: "é‡è¯•"
_bubbleGame:
howToPlay: "游æˆè¯´æ˜Ž"
+ hold: "抓ä½"
+ _score:
+ score: "得分"
+ scoreYen: "赚到的钱"
+ highScore: "最高分"
+ maxChain: "最高连击数"
+ yen: "{yen} 日元"
+ estimatedQty: "约 {qty} 个"
_howToPlay:
section1: "对准ä½ç½®å°†Emoji投入盒å­ã€‚"
section2: "相åŒçš„Emojiç›¸äº’æŽ¥è§¦åˆæˆåŽä¼šå¾—到新的Emoji,以此获得分数。"
@@ -1298,8 +1321,8 @@ _initialTutorial:
description: "对于æœåŠ¡å™¨æ–¹é’ˆæ‰€è¦æ±‚è¦æ±‚çš„ï¼Œåˆæˆ–者ä¸é€‚åˆç›´æŽ¥å±•ç¤ºçš„é™„ä»¶ï¼Œè¯·æ·»åŠ ã€Œæ•æ„Ÿã€æ ‡è®°ã€‚\n"
tryThisFile: "试试看,将附加到此窗å£çš„å›¾åƒæ ‡æ³¨ä¸ºæ•感ï¼"
_exampleNote:
- note: "ä¸è¯¥æ‰“开纳豆的盖å­çš„……"
- method: "è¦æ ‡æ³¨é™„ä»¶ä¸ºæ•æ„Ÿå†…容,请å•击该文件以打开èœå•,然åŽå•å‡»â€œè®¾ç½®ä¸ºæ•æ„Ÿâ€ã€‚"
+ note: "拆纳豆包装时出错了…"
+ method: "è¦æ ‡æ³¨é™„ä»¶ä¸ºæ•æ„Ÿå†…容,请å•击该文件以打开èœå•,然åŽå•å‡»â€œæ ‡è®°ä¸ºæ•æ„Ÿå†…容â€ã€‚"
sensitiveSucceeded: "附加文件时,请éµå¾ªæœåŠ¡å™¨çš„æ¡æ¬¾æ¥è®¾ç½®æ­£ç¡®æ•感设定。\n"
doItToContinue: "å°†å›¾åƒæ ‡è®°ä¸ºæ•æ„ŸåŽæ‰èƒ½å¤Ÿç»§ç»­"
_done:
@@ -1630,8 +1653,9 @@ _role:
gtlAvailable: "查看全局时间线"
ltlAvailable: "查看本地时间线"
canPublicNote: "å…许公开å‘帖"
+ mentionMax: "帖å­å†…最多æåŠæ•°"
canInvite: "呿”¾æœåŠ¡å™¨é‚€è¯·ç "
- inviteLimit: "å¯å‘行邀请ç çš„æ•°é‡"
+ inviteLimit: "å¯ç”Ÿæˆé‚€è¯·ç çš„æ•°é‡"
inviteLimitCycle: "邀请ç çš„å‘行间隔"
inviteExpirationTime: "邀请ç çš„æœ‰æ•ˆæ—¥æœŸ"
canManageCustomEmojis: "管ç†è‡ªå®šä¹‰è¡¨æƒ…符å·"
@@ -1653,6 +1677,7 @@ _role:
canUseTranslator: "使用翻译功能"
avatarDecorationLimit: "坿·»åŠ å¤´åƒæŒ‚件的最大个数"
_condition:
+ roleAssignedTo: "已分é…给手动角色"
isLocal: "是本地用户"
isRemote: "是远程用户"
createdLessThan: "账户创建时间少于"
@@ -1753,6 +1778,8 @@ _aboutMisskey:
contributors: "主è¦è´¡çŒ®è€…"
allContributors: "全体贡献者"
source: "æºä»£ç "
+ original: "原版"
+ thisIsModifiedVersion: "{name}正在使用修改åŽçš„ Misskey。"
translation: "翻译 Misskey"
donate: "赞助 Misskey"
morePatrons: "è¿˜æœ‰å¾ˆå¤šå…¶å®ƒçš„äººä¹Ÿåœ¨æ”¯æŒæˆ‘们,éžå¸¸æ„Ÿè°¢ðŸ¥°"
@@ -2015,7 +2042,7 @@ _permissions:
"read:admin:stream": "使用管ç†å‘˜ç”¨çš„ Websocket API"
"write:admin:ad": "编辑广告"
"read:admin:ad": "查看广告"
- "write:invite-codes": "å‘行邀请ç "
+ "write:invite-codes": "生æˆé‚€è¯·ç "
"read:invite-codes": "获å–å·²å‘行的邀请ç "
"write:clip-favorite": "编辑便签的点赞"
"read:clip-favorite": "查看便签的点赞"
@@ -2271,6 +2298,7 @@ _notification:
reactedBySomeUsers: "{n} 人回应了"
renotedBySomeUsers: "{n} 人转å‘了"
followedBySomeUsers: "被 {n} 人关注"
+ flushNotification: "é‡ç½®é€šçŸ¥åކå²"
_types:
all: "全部"
note: "用户的新帖å­"
@@ -2368,10 +2396,11 @@ _moderationLogTypes:
resetPassword: "é‡ç½®å¯†ç "
suspendRemoteInstance: "åœæ­¢è¿œç¨‹æœåС噍"
unsuspendRemoteInstance: "æ¢å¤è¿œç¨‹æœåС噍"
+ updateRemoteInstanceNote: "更新远程æœåŠ¡å™¨çš„ç®¡ç†ç¬”è®°"
markSensitiveDriveFile: "æ ‡è®°ç½‘ç›˜æ–‡ä»¶ä¸ºæ•æ„Ÿåª’体"
unmarkSensitiveDriveFile: "å–æ¶ˆæ ‡è®°ç½‘ç›˜æ–‡ä»¶ä¸ºæ•æ„Ÿåª’体"
resolveAbuseReport: "处ç†ä¸¾æŠ¥"
- createInvitation: "å‘行邀请ç "
+ createInvitation: "生æˆé‚€è¯·ç "
createAd: "创建了广告"
deleteAd: "删除了广告"
updateAd: "更新了广告"
@@ -2462,6 +2491,8 @@ _reversi:
myTurn: "你的回åˆ"
turnOf: "{name}的回åˆ"
pastTurnOf: "{name}的回åˆ"
+ surrender: "认输"
+ surrendered: "已认输"
timeout: "è¶…æ—¶"
drawn: "平局"
won: "{name}获胜"
@@ -2483,6 +2514,8 @@ _reversi:
opponentHasSettingsChanged: "对手更改了设定"
allowIrregularRules: "å…许éžå¸¸è§„规则(完全自由)"
disallowIrregularRules: "ç¦æ­¢éžå¸¸è§„规则"
+ showBoardLabels: "显示行å·å’Œåˆ—å·"
+ useAvatarAsStone: "用头åƒä½œä¸ºæ£‹å­"
_offlineScreen:
title: "离线——无法连接到æœåС噍"
header: "无法连接到æœåС噍"
diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml
index 2762a612f5..5cdecc10ac 100644
--- a/locales/zh-TW.yml
+++ b/locales/zh-TW.yml
@@ -991,6 +991,7 @@ neverShow: "ä¸å†é¡¯ç¤º"
remindMeLater: "以後å†èªª"
didYouLikeMisskey: "您喜歡 Misskey 嗎?"
pleaseDonate: "Misskey 是由 {host} 使用的å…費軟體。請贊助我們,讓開發得以æŒçºŒï¼"
+correspondingSourceIsAvailable: "å°æ‡‰çš„原始碼å¯ä»¥åœ¨ {anchor} 處找到。"
roles: "角色"
role: "角色"
noRole: "沒有角色"
@@ -1159,6 +1160,7 @@ showRenotes: "顯示其他人的轉發貼文"
edited: "已編輯"
notificationRecieveConfig: "接å—通知的設定"
mutualFollow: "互相追隨"
+followingOrFollower: "追隨中或追隨者"
fileAttachedOnly: "顯示包å«é™„件的貼文"
showRepliesToOthersInTimeline: "顯示給其他人的回覆"
hideRepliesToOthersInTimeline: "在時間軸上隱è—給其他人的回覆"
@@ -1168,6 +1170,12 @@ confirmShowRepliesAll: "進行此æ“作後無法復原。您真的希望時間è»
confirmHideRepliesAll: "進行此æ“作後無法復原。您真的希望時間軸「ä¸åŒ…å«ã€æ‚¨ç›®å‰è¿½éš¨çš„æ‰€æœ‰äººçš„回覆嗎?"
externalServices: "外部æœå‹™"
sourceCode: "原始碼"
+sourceCodeIsNotYetProvided: "尚未æä¾›åŽŸå§‹ç¢¼ï¼Œè«‹æ´½è©¢ç®¡ç†å“¡è§£æ±ºé€™å€‹å•題。"
+repositoryUrl: "儲存庫 URL"
+repositoryUrlDescription: "如果存在å¯å…¬é–‹å–得原始碼的儲存庫,請輸入其 URL。 如果您按原樣使用 Misskey(ä¸å°åŽŸå§‹ç¢¼é€²è¡Œä»»ä½•æ›´æ”¹ï¼‰ï¼Œè«‹è¼¸å…¥ https://github.com/misskey-dev/misskey。"
+repositoryUrlOrTarballRequired: "å¦‚æžœå„²å­˜åº«ä¸æ˜¯å…¬é–‹çš„,則必須æä¾› tarball。 詳細資訊請åƒé–± .config/example.yml。"
+feedback: "æ„見回饋"
+feedbackUrl: "æ„見回饋 URL"
impressum: "營é‹è€…資訊"
impressumUrl: "營é‹è€…資訊網å€"
impressumDescription: "在德國與部份地å€å¿…é ˆè¦æ˜Žç¢ºé¡¯ç¤ºç‡Ÿé‹è€…資訊。"
@@ -1203,6 +1211,8 @@ soundWillBePlayed: "將播放音效"
showReplay: "è§€çœ‹é‡æ’­"
replay: "釿’­"
replaying: "釿’­ä¸­"
+endReplay: "é€€å‡ºé‡æ’­"
+copyReplayData: "è¤‡è£½é‡æ’­è³‡æ–™"
ranking: "排行榜"
lastNDays: "éŽåŽ» {n} 天"
backToTitle: "å›žåˆ°éŠæˆ²æ¨™é¡Œé "
@@ -1210,8 +1220,20 @@ hemisphere: "您居ä½çš„地å€"
withSensitive: "é¡¯ç¤ºåŒ…å«æ•感檔案的貼文"
userSaysSomethingSensitive: "åŒ…å« {name} æ•æ„Ÿæª”案的貼文"
enableHorizontalSwipe: "æ»‘å‹•åˆ‡æ›æ™‚間軸"
+loading: "載入中"
+surrender: "退出"
+gameRetry: "å†è©¦ä¸€æ¬¡"
_bubbleGame:
howToPlay: "玩法說明"
+ hold: "ä¿ç•™"
+ _score:
+ score: "分數"
+ scoreYen: "賺å–的金é¡"
+ highScore: "最高分"
+ maxChain: "最大çµåˆæ•¸"
+ yen: "{yen} 日圓"
+ estimatedQty: "{qty}個"
+ scoreSweets: "飯糰 {onigiriQtyWithUnit}"
_howToPlay:
section1: "調整ä½ç½®ä¸¦å°‡ç‰©é«”放入盒å­ä¸­ã€‚"
section2: "當相åŒé¡žåž‹çš„物體é»åœ¨ä¸€èµ·æ™‚,它們會變æˆä¸åŒçš„物體,您就會得到分數。"
@@ -1615,7 +1637,7 @@ _role:
baseRole: "基本角色"
useBaseValue: "使用基本角色的值"
chooseRoleToAssign: "鏿“‡è¦æŒ‡æ´¾çš„角色"
- iconUrl: "圖示的URL"
+ iconUrl: "圖示的 URL"
asBadge: "顯示為徽章"
descriptionOfAsBadge: "開啟的話,角色圖示會顯示在使用者å稱æ—邊。"
isExplorable: "讓使用者更容易找到您"
@@ -1633,6 +1655,7 @@ _role:
gtlAvailable: "ç€è¦½å…¨åŸŸæ™‚間軸"
ltlAvailable: "ç€è¦½æœ¬åœ°æ™‚間軸"
canPublicNote: "å…許公開貼文"
+ mentionMax: "貼文內的最大æåŠæ•¸"
canInvite: "發行伺æœå™¨é‚€è«‹ç¢¼"
inviteLimit: "å¯å»ºç«‹é‚€è«‹ç¢¼çš„æ•¸é‡"
inviteLimitCycle: "邀請碼的發放間隔"
@@ -1656,6 +1679,7 @@ _role:
canUseTranslator: "使用翻譯功能"
avatarDecorationLimit: "é ­åƒè£é£¾çš„æœ€å¤§è¨­ç½®é‡"
_condition:
+ roleAssignedTo: "手動指派角色完æˆ"
isLocal: "本地使用者"
isRemote: "é ç«¯ä½¿ç”¨è€…"
createdLessThan: "帳戶加入時間ä¸è¶…éŽ"
@@ -1756,6 +1780,8 @@ _aboutMisskey:
contributors: "主è¦è²¢ç»è€…"
allContributors: "全體貢ç»äººå“¡"
source: "原始碼"
+ original: "原始"
+ thisIsModifiedVersion: "{name} 使用原始 Misskey 的修改版本。"
translation: "翻譯 Misskey"
donate: "贊助 Misskey"
morePatrons: "還有許許多多幫助我們的其他人,éžå¸¸æ„Ÿè¬ä½ å€‘。 🥰"
@@ -2274,6 +2300,7 @@ _notification:
reactedBySomeUsers: "{n}人åšå‡ºäº†å應"
renotedBySomeUsers: "{n}人åšäº†è½‰ç™¼"
followedBySomeUsers: "被{n}人追隨了"
+ flushNotification: "é‡ç½®é€šçŸ¥æ­·å²ç´€éŒ„"
_types:
all: "全部 "
note: "使用者的最新貼文"
@@ -2359,7 +2386,7 @@ _moderationLogTypes:
updateCustomEmoji: "更新自訂表情符號"
deleteCustomEmoji: "刪除自訂表情符號"
updateServerSettings: "更新伺æœå™¨è¨­å®š"
- updateUserNote: "更新管ç†ç­†è¨˜"
+ updateUserNote: "更新了使用者的管ç†ç­†è¨˜"
deleteDriveFile: "刪除檔案"
deleteNote: "刪除貼文"
createGlobalAnnouncement: "建立全網通知"
@@ -2371,6 +2398,7 @@ _moderationLogTypes:
resetPassword: "é‡è¨­å¯†ç¢¼"
suspendRemoteInstance: "å°éŽ–é ç«¯ä¼ºæœå™¨"
unsuspendRemoteInstance: "解除å°éŽ–é ç«¯ä¼ºæœå™¨"
+ updateRemoteInstanceNote: "更新了é ç«¯ä¼ºæœå™¨çš„管ç†ç­†è¨˜"
markSensitiveDriveFile: "æ¨™è¨˜ç‚ºæ•æ„Ÿæª”案"
unmarkSensitiveDriveFile: "æ’¤éŠ·æ¨™è¨˜ç‚ºæ•æ„Ÿæª”案"
resolveAbuseReport: "解決檢舉"
@@ -2491,6 +2519,8 @@ _reversi:
opponentHasSettingsChanged: "å°æ‰‹æ›´æ”¹äº†è¨­å®š"
allowIrregularRules: "å…許異常è¦å‰‡ï¼ˆå®Œå…¨è‡ªç”±ï¼‰"
disallowIrregularRules: "ä¸å…許異常è¦å‰‡"
+ showBoardLabels: "在棋盤上顯示行ã€åˆ—號"
+ useAvatarAsStone: "用大頭貼當作棋å­"
_offlineScreen:
title: "離線ï¼ç„¡æ³•連接伺æœå™¨"
header: "無法連接伺æœå™¨"
diff --git a/package.json b/package.json
index 3f94448db7..dee4645ee3 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,12 @@
{
"name": "misskey",
- "version": "2024.2.0",
+ "version": "2024.3.0",
"codename": "nasubi",
"repository": {
"type": "git",
"url": "https://github.com/misskey-dev/misskey.git"
},
- "packageManager": "pnpm@8.15.1",
+ "packageManager": "pnpm@8.15.4",
"workspaces": [
"packages/frontend",
"packages/backend",
@@ -48,22 +48,22 @@
"lodash": "4.17.21"
},
"dependencies": {
- "cssnano": "6.0.3",
+ "cssnano": "6.0.5",
"execa": "8.0.1",
"fast-glob": "3.3.2",
"ignore-walk": "6.0.4",
"js-yaml": "4.1.0",
- "postcss": "8.4.33",
+ "postcss": "8.4.35",
"tar": "6.2.0",
- "terser": "5.27.0",
+ "terser": "5.28.1",
"typescript": "5.3.3"
},
"devDependencies": {
- "@typescript-eslint/eslint-plugin": "6.18.1",
- "@typescript-eslint/parser": "6.18.1",
+ "@typescript-eslint/eslint-plugin": "7.1.0",
+ "@typescript-eslint/parser": "7.1.0",
"cross-env": "7.0.3",
- "cypress": "13.6.3",
- "eslint": "8.56.0",
+ "cypress": "13.6.6",
+ "eslint": "8.57.0",
"ncp": "2.0.0",
"start-server-and-test": "2.0.3"
},
diff --git a/packages/backend/migration/1708266695091-repositoryUrl-from-syuilo-to-misskey-dev.js b/packages/backend/migration/1708266695091-repositoryUrl-from-syuilo-to-misskey-dev.js
new file mode 100644
index 0000000000..e4dbaa16d0
--- /dev/null
+++ b/packages/backend/migration/1708266695091-repositoryUrl-from-syuilo-to-misskey-dev.js
@@ -0,0 +1,16 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export class RepositoryUrlFromSyuiloToMisskeyDev1708266695091 {
+ name = 'RepositoryUrlFromSyuiloToMisskeyDev1708266695091'
+
+ async up(queryRunner) {
+ await queryRunner.query(`UPDATE "meta" SET "repositoryUrl" = 'https://github.com/misskey-dev/misskey' WHERE "repositoryUrl" = 'https://github.com/syuilo/misskey'`);
+ }
+
+ async down(queryRunner) {
+ // no valid down migration
+ }
+}
diff --git a/packages/backend/migration/1708399372194-per-instance-mod-note.js b/packages/backend/migration/1708399372194-per-instance-mod-note.js
new file mode 100644
index 0000000000..339a4d7af9
--- /dev/null
+++ b/packages/backend/migration/1708399372194-per-instance-mod-note.js
@@ -0,0 +1,16 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export class PerInstanceModNote1708399372194 {
+ name = 'PerInstanceModNote1708399372194'
+
+ async up(queryRunner) {
+ await queryRunner.query(`ALTER TABLE "instance" ADD "moderationNote" character varying(16384) NOT NULL DEFAULT ''`);
+ }
+
+ async down(queryRunner) {
+ await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "moderationNote"`);
+ }
+}
diff --git a/packages/backend/package.json b/packages/backend/package.json
index 86a52faa05..8680610441 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -67,9 +67,9 @@
"dependencies": {
"@aws-sdk/client-s3": "3.412.0",
"@aws-sdk/lib-storage": "3.412.0",
- "@bull-board/api": "5.14.0",
- "@bull-board/fastify": "5.14.0",
- "@bull-board/ui": "5.14.0",
+ "@bull-board/api": "5.14.2",
+ "@bull-board/fastify": "5.14.2",
+ "@bull-board/ui": "5.14.2",
"@discordapp/twemoji": "15.0.2",
"@fastify/accepts": "4.3.0",
"@fastify/cookie": "9.3.1",
@@ -79,13 +79,13 @@
"@fastify/multipart": "8.1.0",
"@fastify/static": "6.12.0",
"@fastify/view": "8.2.0",
- "@misskey-dev/sharp-read-bmp": "^1.1.1",
- "@misskey-dev/summaly": "^5.0.3",
- "@nestjs/common": "10.2.10",
- "@nestjs/core": "10.2.10",
- "@nestjs/testing": "10.2.10",
+ "@misskey-dev/sharp-read-bmp": "1.2.0",
+ "@misskey-dev/summaly": "5.0.3",
+ "@nestjs/common": "10.3.3",
+ "@nestjs/core": "10.3.3",
+ "@nestjs/testing": "10.3.3",
"@peertube/http-signature": "1.7.0",
- "@simplewebauthn/server": "9.0.2",
+ "@simplewebauthn/server": "9.0.3",
"@sinonjs/fake-timers": "11.2.2",
"@smithy/node-http-handler": "2.1.10",
"@swc/cli": "0.1.63",
@@ -98,7 +98,7 @@
"bcryptjs": "2.4.3",
"blurhash": "2.0.5",
"body-parser": "1.20.2",
- "bullmq": "5.1.9",
+ "bullmq": "5.4.0",
"cacheable-lookup": "7.0.0",
"cbor": "9.0.2",
"chalk": "5.3.0",
@@ -115,10 +115,11 @@
"file-type": "19.0.0",
"fluent-ffmpeg": "2.1.2",
"form-data": "4.0.0",
- "got": "14.1.0",
+ "got": "14.2.0",
"happy-dom": "10.0.3",
"hpagent": "1.2.0",
- "http-link-header": "1.1.1",
+ "htmlescape": "1.1.1",
+ "http-link-header": "1.1.2",
"ioredis": "5.3.2",
"ip-cidr": "3.1.0",
"ipaddr.js": "2.1.0",
@@ -127,7 +128,7 @@
"jsdom": "23.2.0",
"json5": "2.2.3",
"jsonld": "8.3.2",
- "jsrsasign": "11.0.0",
+ "jsrsasign": "11.1.0",
"meilisearch": "0.37.0",
"mfm-js": "0.24.0",
"microformats-parser": "2.0.2",
@@ -135,10 +136,10 @@
"misskey-js": "workspace:*",
"misskey-reversi": "workspace:*",
"ms": "3.0.0-canary.1",
- "nanoid": "5.0.4",
+ "nanoid": "5.0.6",
"nested-property": "4.0.0",
"node-fetch": "3.3.2",
- "nodemailer": "6.9.8",
+ "nodemailer": "6.9.10",
"nsfwjs": "2.4.2",
"oauth": "0.10.0",
"oauth2orize": "1.12.0",
@@ -158,19 +159,19 @@
"ratelimiter": "3.4.1",
"re2": "1.20.9",
"redis-lock": "0.1.4",
- "reflect-metadata": "0.1.14",
+ "reflect-metadata": "0.2.1",
"rename": "1.0.4",
"rss-parser": "3.13.0",
"rxjs": "7.8.1",
- "sanitize-html": "2.11.0",
+ "sanitize-html": "2.12.1",
"secure-json-parse": "2.7.0",
- "sharp": "0.32.6",
+ "sharp": "0.33.2",
"slacc": "0.0.10",
"strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0",
- "systeminformation": "5.21.24",
+ "systeminformation": "5.22.0",
"tinycolor2": "1.6.0",
- "tmp": "0.2.1",
+ "tmp": "0.2.2",
"tsc-alias": "1.8.8",
"tsconfig-paths": "4.2.0",
"typeorm": "0.3.20",
@@ -184,7 +185,7 @@
"devDependencies": {
"@jest/globals": "29.7.0",
"@misskey-dev/eslint-plugin": "1.0.0",
- "@nestjs/platform-express": "10.3.1",
+ "@nestjs/platform-express": "10.3.3",
"@simplewebauthn/types": "9.0.1",
"@swc/jest": "0.2.31",
"@types/accepts": "1.3.7",
@@ -194,6 +195,7 @@
"@types/color-convert": "2.0.3",
"@types/content-disposition": "0.5.8",
"@types/fluent-ffmpeg": "2.1.24",
+ "@types/htmlescape": "^1.1.3",
"@types/http-link-header": "1.0.5",
"@types/jest": "29.5.11",
"@types/js-yaml": "4.0.9",
@@ -202,21 +204,21 @@
"@types/jsrsasign": "10.5.12",
"@types/mime-types": "2.1.4",
"@types/ms": "0.7.34",
- "@types/node": "20.11.17",
+ "@types/node": "20.11.22",
"@types/node-fetch": "3.0.3",
"@types/nodemailer": "6.4.14",
"@types/oauth": "0.9.4",
"@types/oauth2orize": "1.11.3",
"@types/oauth2orize-pkce": "0.1.2",
- "@types/pg": "8.11.0",
+ "@types/pg": "8.11.2",
"@types/pug": "2.0.10",
- "@types/punycode": "2.1.3",
+ "@types/punycode": "2.1.4",
"@types/qrcode": "1.5.5",
"@types/random-seed": "0.3.5",
"@types/ratelimiter": "3.4.6",
"@types/rename": "1.0.7",
- "@types/sanitize-html": "2.9.5",
- "@types/semver": "7.5.6",
+ "@types/sanitize-html": "2.11.0",
+ "@types/semver": "7.5.8",
"@types/simple-oauth2": "5.0.7",
"@types/sinonjs__fake-timers": "8.1.5",
"@types/tinycolor2": "1.4.6",
@@ -224,17 +226,17 @@
"@types/vary": "1.1.3",
"@types/web-push": "3.6.3",
"@types/ws": "8.5.10",
- "@typescript-eslint/eslint-plugin": "6.18.1",
- "@typescript-eslint/parser": "6.18.1",
+ "@typescript-eslint/eslint-plugin": "7.1.0",
+ "@typescript-eslint/parser": "7.1.0",
"aws-sdk-client-mock": "3.0.1",
"cross-env": "7.0.3",
- "eslint": "8.56.0",
+ "eslint": "8.57.0",
"eslint-plugin-import": "2.29.1",
"execa": "8.0.1",
"fkill": "^9.0.0",
"jest": "29.7.0",
"jest-mock": "29.7.0",
- "nodemon": "3.0.3",
+ "nodemon": "3.1.0",
"pid-port": "1.0.0",
"simple-oauth2": "5.0.0"
}
diff --git a/packages/backend/src/core/AccountMoveService.ts b/packages/backend/src/core/AccountMoveService.ts
index b7796a5183..5bd885df40 100644
--- a/packages/backend/src/core/AccountMoveService.ts
+++ b/packages/backend/src/core/AccountMoveService.ts
@@ -20,7 +20,6 @@ import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js';
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
-import { CacheService } from '@/core/CacheService.js';
import { ProxyAccountService } from '@/core/ProxyAccountService.js';
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
import { MetaService } from '@/core/MetaService.js';
@@ -60,7 +59,6 @@ export class AccountMoveService {
private instanceChart: InstanceChart,
private metaService: MetaService,
private relayService: RelayService,
- private cacheService: CacheService,
private queueService: QueueService,
) {
}
@@ -84,7 +82,7 @@ export class AccountMoveService {
Object.assign(src, update);
// Update cache
- this.cacheService.uriPersonCache.set(srcUri, src);
+ this.globalEventService.publishInternalEvent('localUserUpdated', src);
const srcPerson = await this.apRendererService.renderPerson(src);
const updateAct = this.apRendererService.addContext(this.apRendererService.renderUpdate(srcPerson, src));
diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts
index 263df56476..d008e7ec52 100644
--- a/packages/backend/src/core/CacheService.ts
+++ b/packages/backend/src/core/CacheService.ts
@@ -128,10 +128,13 @@ export class CacheService implements OnApplicationShutdown {
const { type, body } = obj.message as GlobalEvents['internal']['payload'];
switch (type) {
case 'userChangeSuspendedState':
- case 'remoteUserUpdated': {
+ case 'userChangeDeletedState':
+ case 'remoteUserUpdated':
+ case 'localUserUpdated': {
const user = await this.usersRepository.findOneBy({ id: body.id });
if (user == null) {
this.userByIdCache.delete(body.id);
+ this.localUserByIdCache.delete(body.id);
for (const [k, v] of this.uriPersonCache.cache.entries()) {
if (v.value?.id === body.id) {
this.uriPersonCache.delete(k);
diff --git a/packages/backend/src/core/CoreModule.ts b/packages/backend/src/core/CoreModule.ts
index c31cef36e8..2c27d33c06 100644
--- a/packages/backend/src/core/CoreModule.ts
+++ b/packages/backend/src/core/CoreModule.ts
@@ -116,6 +116,7 @@ import { FlashEntityService } from './entities/FlashEntityService.js';
import { FlashLikeEntityService } from './entities/FlashLikeEntityService.js';
import { RoleEntityService } from './entities/RoleEntityService.js';
import { ReversiGameEntityService } from './entities/ReversiGameEntityService.js';
+import { MetaEntityService } from './entities/MetaEntityService.js';
import { ApAudienceService } from './activitypub/ApAudienceService.js';
import { ApDbResolverService } from './activitypub/ApDbResolverService.js';
@@ -254,6 +255,7 @@ const $FlashEntityService: Provider = { provide: 'FlashEntityService', useExisti
const $FlashLikeEntityService: Provider = { provide: 'FlashLikeEntityService', useExisting: FlashLikeEntityService };
const $RoleEntityService: Provider = { provide: 'RoleEntityService', useExisting: RoleEntityService };
const $ReversiGameEntityService: Provider = { provide: 'ReversiGameEntityService', useExisting: ReversiGameEntityService };
+const $MetaEntityService: Provider = { provide: 'MetaEntityService', useExisting: MetaEntityService };
const $ApAudienceService: Provider = { provide: 'ApAudienceService', useExisting: ApAudienceService };
const $ApDbResolverService: Provider = { provide: 'ApDbResolverService', useExisting: ApDbResolverService };
@@ -393,6 +395,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
FlashLikeEntityService,
RoleEntityService,
ReversiGameEntityService,
+ MetaEntityService,
ApAudienceService,
ApDbResolverService,
@@ -528,6 +531,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$FlashLikeEntityService,
$RoleEntityService,
$ReversiGameEntityService,
+ $MetaEntityService,
$ApAudienceService,
$ApDbResolverService,
@@ -663,6 +667,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
FlashLikeEntityService,
RoleEntityService,
ReversiGameEntityService,
+ MetaEntityService,
ApAudienceService,
ApDbResolverService,
@@ -797,6 +802,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$FlashLikeEntityService,
$RoleEntityService,
$ReversiGameEntityService,
+ $MetaEntityService,
$ApAudienceService,
$ApDbResolverService,
diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts
index 64a8c1acdf..edb9335b6e 100644
--- a/packages/backend/src/core/CustomEmojiService.ts
+++ b/packages/backend/src/core/CustomEmojiService.ts
@@ -394,6 +394,11 @@ export class CustomEmojiService implements OnApplicationShutdown {
}
@bindThis
+ public getEmojiByName(name: string): Promise<MiEmoji | null> {
+ return this.emojisRepository.findOneBy({ name, host: IsNull() });
+ }
+
+ @bindThis
public dispose(): void {
this.cache.dispose();
}
diff --git a/packages/backend/src/core/DeleteAccountService.ts b/packages/backend/src/core/DeleteAccountService.ts
index fc5d217ae0..79b614edba 100644
--- a/packages/backend/src/core/DeleteAccountService.ts
+++ b/packages/backend/src/core/DeleteAccountService.ts
@@ -9,6 +9,7 @@ import { QueueService } from '@/core/QueueService.js';
import { UserSuspendService } from '@/core/UserSuspendService.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
+import { GlobalEventService } from '@/core/GlobalEventService.js';
@Injectable()
export class DeleteAccountService {
@@ -18,6 +19,7 @@ export class DeleteAccountService {
private userSuspendService: UserSuspendService,
private queueService: QueueService,
+ private globalEventService: GlobalEventService,
) {
}
@@ -39,5 +41,7 @@ export class DeleteAccountService {
await this.usersRepository.update(user.id, {
isDeleted: true,
});
+
+ this.globalEventService.publishInternalEvent('userChangeDeletedState', { id: user.id, isDeleted: true });
}
}
diff --git a/packages/backend/src/core/FileInfoService.ts b/packages/backend/src/core/FileInfoService.ts
index b177367a16..b8babcb3a7 100644
--- a/packages/backend/src/core/FileInfoService.ts
+++ b/packages/backend/src/core/FileInfoService.ts
@@ -15,6 +15,7 @@ import isSvg from 'is-svg';
import probeImageSize from 'probe-image-size';
import { type predictionType } from 'nsfwjs';
import sharp from 'sharp';
+import { sharpBmp } from '@misskey-dev/sharp-read-bmp';
import { encode } from 'blurhash';
import { createTempDir } from '@/misc/create-temp.js';
import { AiService } from '@/core/AiService.js';
@@ -122,7 +123,7 @@ export class FileInfoService {
'image/avif',
'image/svg+xml',
].includes(type.mime)) {
- blurhash = await this.getBlurhash(path).catch(e => {
+ blurhash = await this.getBlurhash(path, type.mime).catch(e => {
warnings.push(`getBlurhash failed: ${e}`);
return undefined;
});
@@ -407,9 +408,9 @@ export class FileInfoService {
* Calculate average color of image
*/
@bindThis
- private getBlurhash(path: string): Promise<string> {
- return new Promise((resolve, reject) => {
- sharp(path)
+ private getBlurhash(path: string, type: string): Promise<string> {
+ return new Promise(async (resolve, reject) => {
+ (await sharpBmp(path, type))
.raw()
.ensureAlpha()
.resize(64, 64, { fit: 'inside' })
diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts
index 01dd133ead..90efd63f3a 100644
--- a/packages/backend/src/core/GlobalEventService.ts
+++ b/packages/backend/src/core/GlobalEventService.ts
@@ -69,6 +69,7 @@ export interface MainEventTypes {
file: Packed<'DriveFile'>;
};
readAllNotifications: undefined;
+ notificationFlushed: undefined;
unreadNotification: Packed<'Notification'>;
unreadMention: MiNote['id'];
readAllUnreadMentions: undefined;
@@ -209,8 +210,10 @@ type SerializedAll<T> = {
export interface InternalEventTypes {
userChangeSuspendedState: { id: MiUser['id']; isSuspended: MiUser['isSuspended']; };
+ userChangeDeletedState: { id: MiUser['id']; isDeleted: MiUser['isDeleted']; };
userTokenRegenerated: { id: MiUser['id']; oldToken: string; newToken: string; };
remoteUserUpdated: { id: MiUser['id']; };
+ localUserUpdated: { id: MiUser['id']; };
follow: { followerId: MiUser['id']; followeeId: MiUser['id']; };
unfollow: { followerId: MiUser['id']; followeeId: MiUser['id']; };
blockingCreated: { blockerId: MiUser['id']; blockeeId: MiUser['id']; };
diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index 9cec614d5c..81ae2908d3 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -59,6 +59,8 @@ import { UtilityService } from '@/core/UtilityService.js';
import { UserBlockingService } from '@/core/UserBlockingService.js';
import { isReply } from '@/misc/is-reply.js';
import { trackPromise } from '@/misc/promise-tracker.js';
+import { isNotNull } from '@/misc/is-not-null.js';
+import { IdentifiableError } from '@/misc/identifiable-error.js';
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
@@ -151,8 +153,6 @@ type Option = {
export class NoteCreateService implements OnApplicationShutdown {
#shutdownController = new AbortController();
- public static ContainsProhibitedWordsError = class extends Error {};
-
constructor(
@Inject(DI.config)
private config: Config,
@@ -263,8 +263,14 @@ export class NoteCreateService implements OnApplicationShutdown {
}
}
- if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', meta.prohibitedWords)) {
- throw new NoteCreateService.ContainsProhibitedWordsError();
+ const hasProhibitedWords = await this.checkProhibitedWordsContain({
+ cw: data.cw,
+ text: data.text,
+ pollChoices: data.poll?.choices,
+ }, meta.prohibitedWords);
+
+ if (hasProhibitedWords) {
+ throw new IdentifiableError('689ee33f-f97c-479a-ac49-1b9f8140af99', 'Note contains prohibited words');
}
const inSilencedInstance = this.utilityService.isSilencedHost(meta.silencedHosts, user.host);
@@ -379,6 +385,10 @@ export class NoteCreateService implements OnApplicationShutdown {
}
}
+ if (mentionedUsers.length > 0 && mentionedUsers.length > (await this.roleService.getUserPolicies(user.id)).mentionLimit) {
+ throw new IdentifiableError('9f466dab-c856-48cd-9e65-ff90ff750580', 'Note contains too many mentions');
+ }
+
const note = await this.insertNote(user, data, tags, emojis, mentionedUsers);
setImmediate('post created', { signal: this.#shutdownController.signal }).then(
@@ -817,7 +827,7 @@ export class NoteCreateService implements OnApplicationShutdown {
const mentions = extractMentions(tokens);
let mentionedUsers = (await Promise.all(mentions.map(m =>
this.remoteUserResolveService.resolveUser(m.username, m.host ?? user.host).catch(() => null),
- ))).filter(x => x != null) as MiUser[];
+ ))).filter(isNotNull);
// Drop duplicate users
mentionedUsers = mentionedUsers.filter((u, i, self) =>
@@ -991,6 +1001,23 @@ export class NoteCreateService implements OnApplicationShutdown {
}
}
+ public async checkProhibitedWordsContain(content: Parameters<UtilityService['concatNoteContentsForKeyWordCheck']>[0], prohibitedWords?: string[]) {
+ if (prohibitedWords == null) {
+ prohibitedWords = (await this.metaService.fetch()).prohibitedWords;
+ }
+
+ if (
+ this.utilityService.isKeyWordIncluded(
+ this.utilityService.concatNoteContentsForKeyWordCheck(content),
+ prohibitedWords,
+ )
+ ) {
+ return true;
+ }
+
+ return false;
+ }
+
@bindThis
public dispose(): void {
this.#shutdownController.abort();
diff --git a/packages/backend/src/core/NoteReadService.ts b/packages/backend/src/core/NoteReadService.ts
index feef024602..181c9f7649 100644
--- a/packages/backend/src/core/NoteReadService.ts
+++ b/packages/backend/src/core/NoteReadService.ts
@@ -88,46 +88,47 @@ export class NoteReadService implements OnApplicationShutdown {
userId: MiUser['id'],
notes: (MiNote | Packed<'Note'>)[],
): Promise<void> {
- const readMentions: (MiNote | Packed<'Note'>)[] = [];
- const readSpecifiedNotes: (MiNote | Packed<'Note'>)[] = [];
+ if (notes.length === 0) return;
+
+ const noteIds = new Set<MiNote['id']>();
for (const note of notes) {
if (note.mentions && note.mentions.includes(userId)) {
- readMentions.push(note);
+ noteIds.add(note.id);
} else if (note.visibleUserIds && note.visibleUserIds.includes(userId)) {
- readSpecifiedNotes.push(note);
+ noteIds.add(note.id);
}
}
- if ((readMentions.length > 0) || (readSpecifiedNotes.length > 0)) {
- // Remove the record
- await this.noteUnreadsRepository.delete({
- userId: userId,
- noteId: In([...readMentions.map(n => n.id), ...readSpecifiedNotes.map(n => n.id)]),
- });
+ if (noteIds.size === 0) return;
- // TODO: ↓ã¾ã¨ã‚ã¦ã‚¯ã‚¨ãƒªã—ãŸã„
+ // Remove the record
+ await this.noteUnreadsRepository.delete({
+ userId: userId,
+ noteId: In(Array.from(noteIds)),
+ });
- trackPromise(this.noteUnreadsRepository.countBy({
- userId: userId,
- isMentioned: true,
- }).then(mentionsCount => {
- if (mentionsCount === 0) {
- // å…¨ã¦æ—¢èª­ã«ãªã£ãŸã‚¤ãƒ™ãƒ³ãƒˆã‚’発行
- this.globalEventService.publishMainStream(userId, 'readAllUnreadMentions');
- }
- }));
+ // TODO: ↓ã¾ã¨ã‚ã¦ã‚¯ã‚¨ãƒªã—ãŸã„
- trackPromise(this.noteUnreadsRepository.countBy({
- userId: userId,
- isSpecified: true,
- }).then(specifiedCount => {
- if (specifiedCount === 0) {
- // å…¨ã¦æ—¢èª­ã«ãªã£ãŸã‚¤ãƒ™ãƒ³ãƒˆã‚’発行
- this.globalEventService.publishMainStream(userId, 'readAllUnreadSpecifiedNotes');
- }
- }));
- }
+ trackPromise(this.noteUnreadsRepository.countBy({
+ userId: userId,
+ isMentioned: true,
+ }).then(mentionsCount => {
+ if (mentionsCount === 0) {
+ // å…¨ã¦æ—¢èª­ã«ãªã£ãŸã‚¤ãƒ™ãƒ³ãƒˆã‚’発行
+ this.globalEventService.publishMainStream(userId, 'readAllUnreadMentions');
+ }
+ }));
+
+ trackPromise(this.noteUnreadsRepository.countBy({
+ userId: userId,
+ isSpecified: true,
+ }).then(specifiedCount => {
+ if (specifiedCount === 0) {
+ // å…¨ã¦æ—¢èª­ã«ãªã£ãŸã‚¤ãƒ™ãƒ³ãƒˆã‚’発行
+ this.globalEventService.publishMainStream(userId, 'readAllUnreadSpecifiedNotes');
+ }
+ }));
}
@bindThis
diff --git a/packages/backend/src/core/NotificationService.ts b/packages/backend/src/core/NotificationService.ts
index ee16193579..68ad92f396 100644
--- a/packages/backend/src/core/NotificationService.ts
+++ b/packages/backend/src/core/NotificationService.ts
@@ -126,6 +126,14 @@ export class NotificationService implements OnApplicationShutdown {
this.cacheService.userFollowingsCache.fetch(notifieeId).then(followings => Object.hasOwn(followings, notifierId)),
this.cacheService.userFollowingsCache.fetch(notifierId).then(followings => Object.hasOwn(followings, notifieeId)),
]);
+ if (!(isFollowing && isFollower)) {
+ return null;
+ }
+ } else if (recieveConfig?.type === 'followingOrFollower') {
+ const [isFollowing, isFollower] = await Promise.all([
+ this.cacheService.userFollowingsCache.fetch(notifieeId).then(followings => Object.hasOwn(followings, notifierId)),
+ this.cacheService.userFollowingsCache.fetch(notifierId).then(followings => Object.hasOwn(followings, notifieeId)),
+ ]);
if (!isFollowing && !isFollower) {
return null;
}
@@ -155,6 +163,8 @@ export class NotificationService implements OnApplicationShutdown {
const packed = await this.notificationEntityService.pack(notification, notifieeId, {});
+ if (packed == null) return null;
+
// Publish notification event
this.globalEventService.publishMainStream(notifieeId, 'notification', packed);
@@ -205,6 +215,15 @@ export class NotificationService implements OnApplicationShutdown {
}
@bindThis
+ public async flushAllNotifications(userId: MiUser['id']) {
+ await Promise.all([
+ this.redisClient.del(`notificationTimeline:${userId}`),
+ this.redisClient.del(`latestReadNotification:${userId}`),
+ ]);
+ this.globalEventService.publishMainStream(userId, 'notificationFlushed');
+ }
+
+ @bindThis
public dispose(): void {
this.#shutdownController.abort();
}
diff --git a/packages/backend/src/core/PushNotificationService.ts b/packages/backend/src/core/PushNotificationService.ts
index e630539fbc..3b706d9854 100644
--- a/packages/backend/src/core/PushNotificationService.ts
+++ b/packages/backend/src/core/PushNotificationService.ts
@@ -115,6 +115,8 @@ export class PushNotificationService implements OnApplicationShutdown {
endpoint: subscription.endpoint,
auth: subscription.auth,
publickey: subscription.publickey,
+ }).then(() => {
+ this.refreshCache(userId);
});
}
});
@@ -122,6 +124,11 @@ export class PushNotificationService implements OnApplicationShutdown {
}
@bindThis
+ public refreshCache(userId: string): void {
+ this.subscriptionsCache.refresh(userId);
+ }
+
+ @bindThis
public dispose(): void {
this.subscriptionsCache.dispose();
}
diff --git a/packages/backend/src/core/ReactionService.ts b/packages/backend/src/core/ReactionService.ts
index 5014156a5c..cb0b079df0 100644
--- a/packages/backend/src/core/ReactionService.ts
+++ b/packages/backend/src/core/ReactionService.ts
@@ -322,35 +322,36 @@ export class ReactionService {
//#endregion
}
+ /**
+ * 文字列タイプã®ãƒ¬ã‚¬ã‚·ãƒ¼ãªå½¢å¼ã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’ç¾åœ¨ã®å½¢å¼ã«å¤‰æ›ã—ã¤ã¤ã€
+ * データベース上ã«ã¯å­˜åœ¨ã™ã‚‹ã€Œ0個ã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ãŒã¤ã„ã¦ã„ã‚‹ã€ã¨ã„ã†æƒ…報を削除ã™ã‚‹ã€‚
+ */
@bindThis
- public convertLegacyReactions(reactions: Record<string, number>) {
- const _reactions = {} as Record<string, number>;
+ public convertLegacyReactions(reactions: MiNote['reactions']): MiNote['reactions'] {
+ return Object.entries(reactions)
+ .filter(([, count]) => {
+ // `ReactionService.prototype.delete`ã§ã¯ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³å‰Šé™¤æ™‚ã«ã€
+ // `MiNote['reactions']`ã®ã‚¨ãƒ³ãƒˆãƒªã®å€¤ã‚’デクリメントã—ã¦ã„ã‚‹ãŒã€
+ // デクリメントã—ã¦ã„ã‚‹ã ã‘ãªã®ã§ã‚¨ãƒ³ãƒˆãƒªè‡ªä½“ã¯0を値ã¨ã—ã¦æŒã¤å½¢ã§æ®‹ã‚Šç¶šã‘る。
+ // ãã®ãŸã‚ã€ã“ã®å‡¦ç†ãŒãªã‘れã°ã€ã€Œ0個ã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ãŒã¤ã„ã¦ã„ã‚‹ã€ã¨ã„ã†ã“ã¨ã«ãªã£ã¦ã—ã¾ã†ã€‚
+ return count > 0;
+ })
+ .map(([reaction, count]) => {
+ // unchecked indexed access
+ const convertedReaction = legacies[reaction] as string | undefined;
- for (const reaction of Object.keys(reactions)) {
- if (reactions[reaction] <= 0) continue;
+ const key = this.decodeReaction(convertedReaction ?? reaction).reaction;
- if (Object.keys(legacies).includes(reaction)) {
- if (_reactions[legacies[reaction]]) {
- _reactions[legacies[reaction]] += reactions[reaction];
- } else {
- _reactions[legacies[reaction]] = reactions[reaction];
- }
- } else {
- if (_reactions[reaction]) {
- _reactions[reaction] += reactions[reaction];
- } else {
- _reactions[reaction] = reactions[reaction];
- }
- }
- }
-
- const _reactions2 = {} as Record<string, number>;
+ return [key, count] as const;
+ })
+ .reduce<MiNote['reactions']>((acc, [key, count]) => {
+ // unchecked indexed access
+ const prevCount = acc[key] as number | undefined;
- for (const reaction of Object.keys(_reactions)) {
- _reactions2[this.decodeReaction(reaction).reaction] = _reactions[reaction];
- }
+ acc[key] = (prevCount ?? 0) + count;
- return _reactions2;
+ return acc;
+ }, {});
}
@bindThis
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index c5baaf3fff..09f3097114 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -35,6 +35,7 @@ export type RolePolicies = {
gtlAvailable: boolean;
ltlAvailable: boolean;
canPublicNote: boolean;
+ mentionLimit: number;
canInvite: boolean;
inviteLimit: number;
inviteLimitCycle: number;
@@ -62,6 +63,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
gtlAvailable: true,
ltlAvailable: true,
canPublicNote: true,
+ mentionLimit: 20,
canInvite: false,
inviteLimit: 0,
inviteLimitCycle: 60 * 24 * 7,
@@ -200,17 +202,20 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
}
@bindThis
- private evalCond(user: MiUser, value: RoleCondFormulaValue): boolean {
+ private evalCond(user: MiUser, roles: MiRole[], value: RoleCondFormulaValue): boolean {
try {
switch (value.type) {
case 'and': {
- return value.values.every(v => this.evalCond(user, v));
+ return value.values.every(v => this.evalCond(user, roles, v));
}
case 'or': {
- return value.values.some(v => this.evalCond(user, v));
+ return value.values.some(v => this.evalCond(user, roles, v));
}
case 'not': {
- return !this.evalCond(user, value.value);
+ return !this.evalCond(user, roles, value.value);
+ }
+ case 'roleAssignedTo': {
+ return roles.some(r => r.id === value.roleId);
}
case 'isLocal': {
return this.userEntityService.isLocalUser(user);
@@ -272,7 +277,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
const assigns = await this.getUserAssigns(userId);
const assignedRoles = roles.filter(r => assigns.map(x => x.roleId).includes(r.id));
const user = roles.some(r => r.target === 'conditional') ? await this.cacheService.findUserById(userId) : null;
- const matchedCondRoles = roles.filter(r => r.target === 'conditional' && this.evalCond(user!, r.condFormula));
+ const matchedCondRoles = roles.filter(r => r.target === 'conditional' && this.evalCond(user!, assignedRoles, r.condFormula));
return [...assignedRoles, ...matchedCondRoles];
}
@@ -285,13 +290,13 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
let assigns = await this.roleAssignmentByUserIdCache.fetch(userId, () => this.roleAssignmentsRepository.findBy({ userId }));
// 期é™åˆ‡ã‚Œã®ãƒ­ãƒ¼ãƒ«ã‚’除外
assigns = assigns.filter(a => a.expiresAt == null || (a.expiresAt.getTime() > now));
- const assignedRoleIds = assigns.map(x => x.roleId);
const roles = await this.rolesCache.fetch(() => this.rolesRepository.findBy({}));
- const assignedBadgeRoles = roles.filter(r => r.asBadge && assignedRoleIds.includes(r.id));
+ const assignedRoles = roles.filter(r => assigns.map(x => x.roleId).includes(r.id));
+ const assignedBadgeRoles = assignedRoles.filter(r => r.asBadge);
const badgeCondRoles = roles.filter(r => r.asBadge && (r.target === 'conditional'));
if (badgeCondRoles.length > 0) {
const user = roles.some(r => r.target === 'conditional') ? await this.cacheService.findUserById(userId) : null;
- const matchedBadgeCondRoles = badgeCondRoles.filter(r => this.evalCond(user!, r.condFormula));
+ const matchedBadgeCondRoles = badgeCondRoles.filter(r => this.evalCond(user!, assignedRoles, r.condFormula));
return [...assignedBadgeRoles, ...matchedBadgeCondRoles];
} else {
return assignedBadgeRoles;
@@ -325,6 +330,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
gtlAvailable: calc('gtlAvailable', vs => vs.some(v => v === true)),
ltlAvailable: calc('ltlAvailable', vs => vs.some(v => v === true)),
canPublicNote: calc('canPublicNote', vs => vs.some(v => v === true)),
+ mentionLimit: calc('mentionLimit', vs => Math.max(...vs)),
canInvite: calc('canInvite', vs => vs.some(v => v === true)),
inviteLimit: calc('inviteLimit', vs => Math.max(...vs)),
inviteLimitCycle: calc('inviteLimitCycle', vs => Math.max(...vs)),
diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts
index 8ad85391c6..0a492c06e4 100644
--- a/packages/backend/src/core/UserFollowingService.ts
+++ b/packages/backend/src/core/UserFollowingService.ts
@@ -30,6 +30,7 @@ import type { Config } from '@/config.js';
import { AccountMoveService } from '@/core/AccountMoveService.js';
import { UtilityService } from '@/core/UtilityService.js';
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
+import type { ThinUser } from '@/queue/types.js';
import Logger from '../logger.js';
const logger = new Logger('following/create');
@@ -95,20 +96,34 @@ export class UserFollowingService implements OnModuleInit {
}
@bindThis
+ public async deliverAccept(follower: MiRemoteUser, followee: MiPartialLocalUser, requestId?: string) {
+ const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee, requestId), followee));
+ this.queueService.deliver(followee, content, follower.inbox, false);
+ }
+
+ @bindThis
public async follow(
- _follower: { id: MiUser['id'] },
- _followee: { id: MiUser['id'] },
+ _follower: ThinUser,
+ _followee: ThinUser,
{ requestId, silent = false, withReplies }: {
requestId?: string,
silent?: boolean,
withReplies?: boolean,
} = {},
): Promise<void> {
+ /**
+ * å¿…ãšæœ€æ–°ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼æƒ…報をå–å¾—ã™ã‚‹
+ */
const [follower, followee] = await Promise.all([
this.usersRepository.findOneByOrFail({ id: _follower.id }),
this.usersRepository.findOneByOrFail({ id: _followee.id }),
]) as [MiLocalUser | MiRemoteUser, MiLocalUser | MiRemoteUser];
+ if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isRemoteUser(followee)) {
+ // What?
+ throw new Error('Remote user cannot follow remote user.');
+ }
+
// check blocking
const [blocking, blocked] = await Promise.all([
this.userBlockingService.checkBlocked(follower.id, followee.id),
@@ -129,6 +144,24 @@ export class UserFollowingService implements OnModuleInit {
if (blocked) throw new IdentifiableError('3338392a-f764-498d-8855-db939dcf8c48', 'blocked');
}
+ if (await this.followingsRepository.exists({
+ where: {
+ followerId: follower.id,
+ followeeId: followee.id,
+ },
+ })) {
+ // ã™ã§ã«ãƒ•ォロー関係ãŒå­˜åœ¨ã—ã¦ã„ã‚‹å ´åˆ
+ if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
+ // リモート → ローカル: acceptã‚’é€ã‚Šè¿”ã—ã¦ãŠã—ã¾ã„
+ this.deliverAccept(follower, followee, requestId);
+ return;
+ }
+ if (this.userEntityService.isLocalUser(follower)) {
+ // ローカル → リモート/ローカル: 例外
+ throw new IdentifiableError('ec3f65c0-a9d1-47d9-8791-b2e7b9dcdced', 'already following');
+ }
+ }
+
const followeeProfile = await this.userProfilesRepository.findOneByOrFail({ userId: followee.id });
// フォロー対象ãŒéµã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§ã‚ã‚‹ or
// フォロワーãŒBotã§ã‚りã€ãƒ•ォロー対象ãŒBotã‹ã‚‰ã®ãƒ•ã‚©ãƒ­ãƒ¼ã«æ…Žé‡ã§ã‚ã‚‹ or
@@ -189,8 +222,7 @@ export class UserFollowingService implements OnModuleInit {
await this.insertFollowingDoc(followee, follower, silent, withReplies);
if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
- const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee, requestId), followee));
- this.queueService.deliver(followee, content, follower.inbox, false);
+ this.deliverAccept(follower, followee, requestId);
}
}
@@ -571,8 +603,7 @@ export class UserFollowingService implements OnModuleInit {
await this.insertFollowingDoc(followee, follower, false, request.withReplies);
if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
- const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee as MiPartialLocalUser, request.requestId!), followee));
- this.queueService.deliver(followee, content, follower.inbox, false);
+ this.deliverAccept(follower, followee as MiPartialLocalUser, request.requestId ?? undefined);
}
this.userEntityService.pack(followee.id, followee, {
diff --git a/packages/backend/src/core/UtilityService.ts b/packages/backend/src/core/UtilityService.ts
index 638a0c019e..652e8f7449 100644
--- a/packages/backend/src/core/UtilityService.ts
+++ b/packages/backend/src/core/UtilityService.ts
@@ -43,6 +43,20 @@ export class UtilityService {
}
@bindThis
+ public concatNoteContentsForKeyWordCheck(content: {
+ cw?: string | null;
+ text?: string | null;
+ pollChoices?: string[] | null;
+ others?: string[] | null;
+ }): string {
+ /**
+ * ノートã®å†…容をçµåˆã—ã¦ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãƒã‚§ãƒƒã‚¯ç”¨ã®æ–‡å­—列を生æˆã™ã‚‹
+ * cwã¨textã¯å†…容ãŒç¹‹ãŒã£ã¦ã„ã‚‹ã‹ã‚‚ã—れãªã„ã®ã§é–“ã«ä½•も入れãšã«ãƒã‚§ãƒƒã‚¯ã™ã‚‹
+ */
+ return `${content.cw ?? ''}${content.text ?? ''}\n${(content.pollChoices ?? []).join('\n')}\n${(content.others ?? []).join('\n')}`;
+ }
+
+ @bindThis
public isKeyWordIncluded(text: string, keyWords: string[]): boolean {
if (keyWords.length === 0) return false;
if (text === '') return false;
diff --git a/packages/backend/src/core/WebAuthnService.ts b/packages/backend/src/core/WebAuthnService.ts
index 4d11865906..42fbed2110 100644
--- a/packages/backend/src/core/WebAuthnService.ts
+++ b/packages/backend/src/core/WebAuthnService.ts
@@ -191,7 +191,7 @@ export class WebAuthnService {
if (cert[0] === 0x04) { // å‰ã®å®Ÿè£…ã§ã¯ã„ã¤ã‚‚ 0x04 ã§å§‹ã¾ã£ã¦ã„ãŸ
const halfLength = (cert.length - 1) / 2;
- const cborMap = new Map<number, number | ArrayBufferLike>();
+ const cborMap = new Map<number, number | Uint8Array>();
cborMap.set(1, 2); // kty, EC2
cborMap.set(3, -7); // alg, ES256
cborMap.set(-1, 1); // crv, P256
diff --git a/packages/backend/src/core/activitypub/ApAudienceService.ts b/packages/backend/src/core/activitypub/ApAudienceService.ts
index d47be79441..0fccc7b950 100644
--- a/packages/backend/src/core/activitypub/ApAudienceService.ts
+++ b/packages/backend/src/core/activitypub/ApAudienceService.ts
@@ -8,6 +8,7 @@ import promiseLimit from 'promise-limit';
import type { MiRemoteUser, MiUser } from '@/models/User.js';
import { concat, unique } from '@/misc/prelude/array.js';
import { bindThis } from '@/decorators.js';
+import { isNotNull } from '@/misc/is-not-null.js';
import { getApIds } from './type.js';
import { ApPersonService } from './models/ApPersonService.js';
import type { ApObject } from './type.js';
@@ -40,7 +41,7 @@ export class ApAudienceService {
const limit = promiseLimit<MiUser | null>(2);
const mentionedUsers = (await Promise.all(
others.map(id => limit(() => this.apPersonService.resolvePerson(id, resolver).catch(() => null))),
- )).filter((x): x is MiUser => x != null);
+ )).filter(isNotNull);
if (toGroups.public.length > 0) {
return {
diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts
index 1cc54b6ff6..1621c41bcc 100644
--- a/packages/backend/src/core/activitypub/ApInboxService.ts
+++ b/packages/backend/src/core/activitypub/ApInboxService.ts
@@ -27,6 +27,7 @@ import { QueueService } from '@/core/QueueService.js';
import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserReportsRepository, FollowRequestsRepository } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import type { MiRemoteUser } from '@/models/User.js';
+import { isNotNull } from '@/misc/is-not-null.js';
import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js';
import { ApNoteService } from './models/ApNoteService.js';
import { ApLoggerService } from './ApLoggerService.js';
@@ -35,7 +36,6 @@ import { ApResolverService } from './ApResolverService.js';
import { ApAudienceService } from './ApAudienceService.js';
import { ApPersonService } from './models/ApPersonService.js';
import { ApQuestionService } from './models/ApQuestionService.js';
-import { CacheService } from '@/core/CacheService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import type { Resolver } from './ApResolverService.js';
import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, ILike, IObject, IReject, IRemove, IUndo, IUpdate, IMove } from './type.js';
@@ -84,7 +84,6 @@ export class ApInboxService {
private apPersonService: ApPersonService,
private apQuestionService: ApQuestionService,
private queueService: QueueService,
- private cacheService: CacheService,
private globalEventService: GlobalEventService,
) {
this.logger = this.apLoggerService.logger;
@@ -521,7 +520,7 @@ export class ApInboxService {
const userIds = uris
.filter(uri => uri.startsWith(this.config.url + '/users/'))
.map(uri => uri.split('/').at(-1))
- .filter((userId): userId is string => userId !== undefined);
+ .filter(isNotNull);
const users = await this.usersRepository.findBy({
id: In(userIds),
});
diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts
index 494622909a..d7fb977a99 100644
--- a/packages/backend/src/core/activitypub/ApRendererService.ts
+++ b/packages/backend/src/core/activitypub/ApRendererService.ts
@@ -315,7 +315,7 @@ export class ApRendererService {
const getPromisedFiles = async (ids: string[]): Promise<MiDriveFile[]> => {
if (ids.length === 0) return [];
const items = await this.driveFilesRepository.findBy({ id: In(ids) });
- return ids.map(id => items.find(item => item.id === id)).filter((item): item is MiDriveFile => item != null);
+ return ids.map(id => items.find(item => item.id === id)).filter(isNotNull);
};
let inReplyTo;
diff --git a/packages/backend/src/core/activitypub/models/ApMentionService.ts b/packages/backend/src/core/activitypub/models/ApMentionService.ts
index 73eea1edf0..0ced7e88af 100644
--- a/packages/backend/src/core/activitypub/models/ApMentionService.ts
+++ b/packages/backend/src/core/activitypub/models/ApMentionService.ts
@@ -8,6 +8,7 @@ import promiseLimit from 'promise-limit';
import type { MiUser } from '@/models/_.js';
import { toArray, unique } from '@/misc/prelude/array.js';
import { bindThis } from '@/decorators.js';
+import { isNotNull } from '@/misc/is-not-null.js';
import { isMention } from '../type.js';
import { Resolver } from '../ApResolverService.js';
import { ApPersonService } from './ApPersonService.js';
@@ -27,7 +28,7 @@ export class ApMentionService {
const limit = promiseLimit<MiUser | null>(2);
const mentionedUsers = (await Promise.all(
hrefs.map(x => limit(() => this.apPersonService.resolvePerson(x, resolver).catch(() => null))),
- )).filter((x): x is MiUser => x != null);
+ )).filter(isNotNull);
return mentionedUsers;
}
diff --git a/packages/backend/src/core/activitypub/models/ApNoteService.ts b/packages/backend/src/core/activitypub/models/ApNoteService.ts
index 8da9407216..b2fd435f93 100644
--- a/packages/backend/src/core/activitypub/models/ApNoteService.ts
+++ b/packages/backend/src/core/activitypub/models/ApNoteService.ts
@@ -24,6 +24,8 @@ import { StatusError } from '@/misc/status-error.js';
import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js';
import { checkHttps } from '@/misc/check-https.js';
+import { IdentifiableError } from '@/misc/identifiable-error.js';
+import { isNotNull } from '@/misc/is-not-null.js';
import { getOneApId, getApId, getOneApHrefNullable, validPost, isEmoji, getApType } from '../type.js';
import { ApLoggerService } from '../ApLoggerService.js';
import { ApMfmService } from '../ApMfmService.js';
@@ -151,11 +153,47 @@ export class ApNoteService {
throw new Error('invalid note.attributedTo: ' + note.attributedTo);
}
- const actor = await this.apPersonService.resolvePerson(getOneApId(note.attributedTo), resolver) as MiRemoteUser;
+ const uri = getOneApId(note.attributedTo);
- // 投稿者ãŒå‡çµã•れã¦ã„ãŸã‚‰ã‚¹ã‚­ãƒƒãƒ—
+ // ãƒ­ãƒ¼ã‚«ãƒ«ã§æŠ•ç¨¿è€…ã‚’æ¤œç´¢ã—ã€ã‚‚ã—å‡çµã•れã¦ã„ãŸã‚‰ã‚¹ã‚­ãƒƒãƒ—
+ const cachedActor = await this.apPersonService.fetchPerson(uri) as MiRemoteUser;
+ if (cachedActor && cachedActor.isSuspended) {
+ throw new IdentifiableError('85ab9bd7-3a41-4530-959d-f07073900109', 'actor has been suspended');
+ }
+
+ const apMentions = await this.apMentionService.extractApMentions(note.tag, resolver);
+ const apHashtags = extractApHashtags(note.tag);
+
+ const cw = note.summary === '' ? null : note.summary;
+
+ // テキストã®ãƒ‘ース
+ let text: string | null = null;
+ if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source.content === 'string') {
+ text = note.source.content;
+ } else if (typeof note._misskey_content !== 'undefined') {
+ text = note._misskey_content;
+ } else if (typeof note.content === 'string') {
+ text = this.apMfmService.htmlToMfm(note.content, note.tag);
+ }
+
+ const poll = await this.apQuestionService.extractPollFromQuestion(note, resolver).catch(() => undefined);
+
+ //#region Contents Check
+ // 添付ファイルã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’ã“ã®ã‚µãƒ¼ãƒãƒ¼ã§ç™»éŒ²ã™ã‚‹å‰ã«å†…容をãƒã‚§ãƒƒã‚¯ã™ã‚‹
+ /**
+ * ç¦æ­¢ãƒ¯ãƒ¼ãƒ‰ãƒã‚§ãƒƒã‚¯
+ */
+ const hasProhibitedWords = await this.noteCreateService.checkProhibitedWordsContain({ cw, text, pollChoices: poll?.choices });
+ if (hasProhibitedWords) {
+ throw new IdentifiableError('689ee33f-f97c-479a-ac49-1b9f8140af99', 'Note contains prohibited words');
+ }
+ //#endregion
+
+ const actor = cachedActor ?? await this.apPersonService.resolvePerson(uri, resolver) as MiRemoteUser;
+
+ // 解決ã—ãŸæŠ•ç¨¿è€…ãŒå‡çµã•れã¦ã„ãŸã‚‰ã‚¹ã‚­ãƒƒãƒ—
if (actor.isSuspended) {
- throw new Error('actor has been suspended');
+ throw new IdentifiableError('85ab9bd7-3a41-4530-959d-f07073900109', 'actor has been suspended');
}
const noteAudience = await this.apAudienceService.parseAudience(actor, note.to, note.cc, resolver);
@@ -170,9 +208,6 @@ export class ApNoteService {
}
}
- const apMentions = await this.apMentionService.extractApMentions(note.tag, resolver);
- const apHashtags = extractApHashtags(note.tag);
-
// 添付ファイル
// TODO: attachmentã¯å¿…ãšã—ã‚‚Imageã§ã¯ãªã„
// TODO: attachmentã¯å¿…ãšã—ã‚‚é…列ã§ã¯ãªã„
@@ -221,7 +256,7 @@ export class ApNoteService {
}
};
- const uris = unique([note._misskey_quote, note.quoteUrl].filter((x): x is string => typeof x === 'string'));
+ const uris = unique([note._misskey_quote, note.quoteUrl].filter(isNotNull));
const results = await Promise.all(uris.map(tryResolveNote));
quote = results.filter((x): x is { status: 'ok', res: MiNote } => x.status === 'ok').map(x => x.res).at(0);
@@ -232,18 +267,6 @@ export class ApNoteService {
}
}
- const cw = note.summary === '' ? null : note.summary;
-
- // テキストã®ãƒ‘ース
- let text: string | null = null;
- if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source.content === 'string') {
- text = note.source.content;
- } else if (typeof note._misskey_content !== 'undefined') {
- text = note._misskey_content;
- } else if (typeof note.content === 'string') {
- text = this.apMfmService.htmlToMfm(note.content, note.tag);
- }
-
// vote
if (reply && reply.hasPoll) {
const poll = await this.pollsRepository.findOneByOrFail({ noteId: reply.id });
@@ -273,8 +296,6 @@ export class ApNoteService {
const apEmojis = emojis.map(emoji => emoji.name);
- const poll = await this.apQuestionService.extractPollFromQuestion(note, resolver).catch(() => undefined);
-
try {
return await this.noteCreateService.create(actor, {
createdAt: note.published ? new Date(note.published) : null,
diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts
index e80cd34a56..744b1ea683 100644
--- a/packages/backend/src/core/activitypub/models/ApPersonService.ts
+++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts
@@ -38,6 +38,7 @@ import { MetaService } from '@/core/MetaService.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
import type { AccountMoveService } from '@/core/AccountMoveService.js';
import { checkHttps } from '@/misc/check-https.js';
+import { isNotNull } from '@/misc/is-not-null.js';
import { getApId, getApType, getOneApHrefNullable, isActor, isCollection, isCollectionOrOrderedCollection, isPropertyValue } from '../type.js';
import { extractApHashtags } from './tag.js';
import type { OnModuleInit } from '@nestjs/common';
@@ -636,7 +637,7 @@ export class ApPersonService implements OnModuleInit {
// ã¨ã‚Šã‚ãˆãšidã‚’åˆ¥ã®æ™‚é–“ã§ç”Ÿæˆã—ã¦é †ç•ªã‚’ç¶­æŒ
let td = 0;
- for (const note of featuredNotes.filter((note): note is MiNote => note != null)) {
+ for (const note of featuredNotes.filter(isNotNull)) {
td -= 1000;
transactionalEntityManager.insert(MiUserNotePining, {
id: this.idService.gen(Date.now() + td),
diff --git a/packages/backend/src/core/activitypub/models/ApQuestionService.ts b/packages/backend/src/core/activitypub/models/ApQuestionService.ts
index e78b3a3599..d1936cfe1d 100644
--- a/packages/backend/src/core/activitypub/models/ApQuestionService.ts
+++ b/packages/backend/src/core/activitypub/models/ApQuestionService.ts
@@ -10,6 +10,7 @@ import type { Config } from '@/config.js';
import type { IPoll } from '@/models/Poll.js';
import type Logger from '@/logger.js';
import { bindThis } from '@/decorators.js';
+import { isNotNull } from '@/misc/is-not-null.js';
import { isQuestion } from '../type.js';
import { ApLoggerService } from '../ApLoggerService.js';
import { ApResolverService } from '../ApResolverService.js';
@@ -51,7 +52,7 @@ export class ApQuestionService {
const choices = question[multiple ? 'anyOf' : 'oneOf']
?.map((x) => x.name)
- .filter((x): x is string => typeof x === 'string')
+ .filter(isNotNull)
?? [];
const votes = question[multiple ? 'anyOf' : 'oneOf']?.map((x) => x.replies?.totalItems ?? x._misskey_votes ?? 0);
diff --git a/packages/backend/src/core/activitypub/models/tag.ts b/packages/backend/src/core/activitypub/models/tag.ts
index ced101b764..e7ceec3262 100644
--- a/packages/backend/src/core/activitypub/models/tag.ts
+++ b/packages/backend/src/core/activitypub/models/tag.ts
@@ -4,6 +4,7 @@
*/
import { toArray } from '@/misc/prelude/array.js';
+import { isNotNull } from '@/misc/is-not-null.js';
import { isHashtag } from '../type.js';
import type { IObject, IApHashtag } from '../type.js';
@@ -15,7 +16,7 @@ export function extractApHashtags(tags: IObject | IObject[] | null | undefined):
return hashtags.map(tag => {
const m = tag.name.match(/^#(.+)/);
return m ? m[1] : null;
- }).filter((x): x is string => x != null);
+ }).filter(isNotNull);
}
export function extractApHashtagObjects(tags: IObject | IObject[] | null | undefined): IApHashtag[] {
diff --git a/packages/backend/src/core/entities/DriveFileEntityService.ts b/packages/backend/src/core/entities/DriveFileEntityService.ts
index 50f1c49b48..8affe2b3bf 100644
--- a/packages/backend/src/core/entities/DriveFileEntityService.ts
+++ b/packages/backend/src/core/entities/DriveFileEntityService.ts
@@ -259,7 +259,7 @@ export class DriveFileEntityService {
options?: PackOptions,
): Promise<Packed<'DriveFile'>[]> {
const items = await Promise.all(files.map(f => this.packNullable(f, options)));
- return items.filter((x): x is Packed<'DriveFile'> => x != null);
+ return items.filter(isNotNull);
}
@bindThis
diff --git a/packages/backend/src/core/entities/InstanceEntityService.ts b/packages/backend/src/core/entities/InstanceEntityService.ts
index 9287c98003..e46bd8b963 100644
--- a/packages/backend/src/core/entities/InstanceEntityService.ts
+++ b/packages/backend/src/core/entities/InstanceEntityService.ts
@@ -8,12 +8,15 @@ import type { Packed } from '@/misc/json-schema.js';
import type { MiInstance } from '@/models/Instance.js';
import { MetaService } from '@/core/MetaService.js';
import { bindThis } from '@/decorators.js';
-import { UtilityService } from '../UtilityService.js';
+import { UtilityService } from '@/core/UtilityService.js';
+import { RoleService } from '@/core/RoleService.js';
+import { MiUser } from '@/models/User.js';
@Injectable()
export class InstanceEntityService {
constructor(
private metaService: MetaService,
+ private roleService: RoleService,
private utilityService: UtilityService,
) {
@@ -22,8 +25,11 @@ export class InstanceEntityService {
@bindThis
public async pack(
instance: MiInstance,
+ me?: { id: MiUser['id']; } | null | undefined,
): Promise<Packed<'FederationInstance'>> {
const meta = await this.metaService.fetch();
+ const iAmModerator = me ? await this.roleService.isModerator(me as MiUser) : false;
+
return {
id: instance.id,
firstRetrievedAt: instance.firstRetrievedAt.toISOString(),
@@ -48,6 +54,7 @@ export class InstanceEntityService {
themeColor: instance.themeColor,
infoUpdatedAt: instance.infoUpdatedAt ? instance.infoUpdatedAt.toISOString() : null,
latestRequestReceivedAt: instance.latestRequestReceivedAt ? instance.latestRequestReceivedAt.toISOString() : null,
+ moderationNote: iAmModerator ? instance.moderationNote : null,
};
}
diff --git a/packages/backend/src/core/entities/MetaEntityService.ts b/packages/backend/src/core/entities/MetaEntityService.ts
new file mode 100644
index 0000000000..b50d76288f
--- /dev/null
+++ b/packages/backend/src/core/entities/MetaEntityService.ts
@@ -0,0 +1,154 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { Brackets } from 'typeorm';
+import { Inject, Injectable } from '@nestjs/common';
+import JSON5 from 'json5';
+import type { Packed } from '@/misc/json-schema.js';
+import type { MiMeta } from '@/models/Meta.js';
+import type { AdsRepository } from '@/models/_.js';
+import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
+import { MetaService } from '@/core/MetaService.js';
+import { bindThis } from '@/decorators.js';
+import { UserEntityService } from '@/core/entities/UserEntityService.js';
+import { InstanceActorService } from '@/core/InstanceActorService.js';
+import type { Config } from '@/config.js';
+import { DI } from '@/di-symbols.js';
+import { DEFAULT_POLICIES } from '@/core/RoleService.js';
+
+@Injectable()
+export class MetaEntityService {
+ constructor(
+ @Inject(DI.config)
+ private config: Config,
+
+ @Inject(DI.adsRepository)
+ private adsRepository: AdsRepository,
+
+ private userEntityService: UserEntityService,
+ private metaService: MetaService,
+ private instanceActorService: InstanceActorService,
+ ) { }
+
+ @bindThis
+ public async pack(meta?: MiMeta): Promise<Packed<'MetaLite'>> {
+ let instance = meta;
+
+ if (!instance) {
+ instance = await this.metaService.fetch();
+ }
+
+ const ads = await this.adsRepository.createQueryBuilder('ads')
+ .where('ads.expiresAt > :now', { now: new Date() })
+ .andWhere('ads.startsAt <= :now', { now: new Date() })
+ .andWhere(new Brackets(qb => {
+ // 曜日ã®ãƒ“ットフラグを確èªã™ã‚‹
+ qb.where('ads.dayOfWeek & :dayOfWeek > 0', { dayOfWeek: 1 << new Date().getDay() })
+ .orWhere('ads.dayOfWeek = 0');
+ }))
+ .getMany();
+
+ const packed: Packed<'MetaLite'> = {
+ maintainerName: instance.maintainerName,
+ maintainerEmail: instance.maintainerEmail,
+
+ version: this.config.version,
+ providesTarball: this.config.publishTarballInsteadOfProvideRepositoryUrl,
+
+ name: instance.name,
+ shortName: instance.shortName,
+ uri: this.config.url,
+ description: instance.description,
+ langs: instance.langs,
+ tosUrl: instance.termsOfServiceUrl,
+ repositoryUrl: instance.repositoryUrl,
+ feedbackUrl: instance.feedbackUrl,
+ impressumUrl: instance.impressumUrl,
+ privacyPolicyUrl: instance.privacyPolicyUrl,
+ disableRegistration: instance.disableRegistration,
+ emailRequiredForSignup: instance.emailRequiredForSignup,
+ enableHcaptcha: instance.enableHcaptcha,
+ hcaptchaSiteKey: instance.hcaptchaSiteKey,
+ enableMcaptcha: instance.enableMcaptcha,
+ mcaptchaSiteKey: instance.mcaptchaSitekey,
+ mcaptchaInstanceUrl: instance.mcaptchaInstanceUrl,
+ enableRecaptcha: instance.enableRecaptcha,
+ recaptchaSiteKey: instance.recaptchaSiteKey,
+ enableTurnstile: instance.enableTurnstile,
+ turnstileSiteKey: instance.turnstileSiteKey,
+ swPublickey: instance.swPublicKey,
+ themeColor: instance.themeColor,
+ mascotImageUrl: instance.mascotImageUrl ?? '/assets/ai.png',
+ bannerUrl: instance.bannerUrl,
+ infoImageUrl: instance.infoImageUrl,
+ serverErrorImageUrl: instance.serverErrorImageUrl,
+ notFoundImageUrl: instance.notFoundImageUrl,
+ iconUrl: instance.iconUrl,
+ backgroundImageUrl: instance.backgroundImageUrl,
+ logoImageUrl: instance.logoImageUrl,
+ maxNoteTextLength: MAX_NOTE_TEXT_LENGTH,
+ // ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã®æ‰‹é–“を減らã™ãŸã‚ã‚らã‹ã˜ã‚JSONã«å¤‰æ›ã—ã¦ãŠã
+ defaultLightTheme: instance.defaultLightTheme ? JSON.stringify(JSON5.parse(instance.defaultLightTheme)) : null,
+ defaultDarkTheme: instance.defaultDarkTheme ? JSON.stringify(JSON5.parse(instance.defaultDarkTheme)) : null,
+ ads: ads.map(ad => ({
+ id: ad.id,
+ url: ad.url,
+ place: ad.place,
+ ratio: ad.ratio,
+ imageUrl: ad.imageUrl,
+ dayOfWeek: ad.dayOfWeek,
+ })),
+ notesPerOneAd: instance.notesPerOneAd,
+ enableEmail: instance.enableEmail,
+ enableServiceWorker: instance.enableServiceWorker,
+
+ translatorAvailable: instance.deeplAuthKey != null,
+
+ serverRules: instance.serverRules,
+
+ policies: { ...DEFAULT_POLICIES, ...instance.policies },
+
+ mediaProxy: this.config.mediaProxy,
+ };
+
+ return packed;
+ }
+
+ @bindThis
+ public async packDetailed(meta?: MiMeta): Promise<Packed<'MetaDetailed'>> {
+ let instance = meta;
+
+ if (!instance) {
+ instance = await this.metaService.fetch();
+ }
+
+ const packed = await this.pack(instance);
+
+ const proxyAccount = instance.proxyAccountId ? await this.userEntityService.pack(instance.proxyAccountId).catch(() => null) : null;
+
+ const packDetailed: Packed<'MetaDetailed'> = {
+ ...packed,
+ cacheRemoteFiles: instance.cacheRemoteFiles,
+ cacheRemoteSensitiveFiles: instance.cacheRemoteSensitiveFiles,
+ requireSetup: !await this.instanceActorService.realLocalUsersPresent(),
+ proxyAccountName: proxyAccount ? proxyAccount.username : null,
+ features: {
+ localTimeline: instance.policies.ltlAvailable,
+ globalTimeline: instance.policies.gtlAvailable,
+ registration: !instance.disableRegistration,
+ emailRequiredForSignup: instance.emailRequiredForSignup,
+ hcaptcha: instance.enableHcaptcha,
+ recaptcha: instance.enableRecaptcha,
+ turnstile: instance.enableTurnstile,
+ objectStorage: instance.useObjectStorage,
+ serviceWorker: instance.enableServiceWorker,
+ miauth: true,
+ },
+ };
+
+ return packDetailed;
+ }
+}
+
diff --git a/packages/backend/src/core/entities/NoteReactionEntityService.ts b/packages/backend/src/core/entities/NoteReactionEntityService.ts
index 2799f58992..3f4fa3cf96 100644
--- a/packages/backend/src/core/entities/NoteReactionEntityService.ts
+++ b/packages/backend/src/core/entities/NoteReactionEntityService.ts
@@ -69,4 +69,19 @@ export class NoteReactionEntityService implements OnModuleInit {
} : {}),
};
}
+
+ @bindThis
+ public async packMany(
+ reactions: MiNoteReaction[],
+ me?: { id: MiUser['id'] } | null | undefined,
+ options?: {
+ withNote: boolean;
+ },
+ ): Promise<Packed<'NoteReaction'>[]> {
+ const opts = Object.assign({
+ withNote: false,
+ }, options);
+
+ return Promise.all(reactions.map(reaction => this.pack(reaction, me, opts)));
+ }
}
diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts
index 0663898edb..94d56c883b 100644
--- a/packages/backend/src/core/entities/NotificationEntityService.ts
+++ b/packages/backend/src/core/entities/NotificationEntityService.ts
@@ -14,14 +14,14 @@ import type { MiNote } from '@/models/Note.js';
import type { Packed } from '@/misc/json-schema.js';
import { bindThis } from '@/decorators.js';
import { isNotNull } from '@/misc/is-not-null.js';
-import { FilterUnionByProperty, notificationTypes } from '@/types.js';
+import { FilterUnionByProperty, groupedNotificationTypes } from '@/types.js';
+import { CacheService } from '@/core/CacheService.js';
import { RoleEntityService } from './RoleEntityService.js';
import type { OnModuleInit } from '@nestjs/common';
import type { UserEntityService } from './UserEntityService.js';
import type { NoteEntityService } from './NoteEntityService.js';
-const NOTE_REQUIRED_NOTIFICATION_TYPES = new Set(['note', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollEnded'] as (typeof notificationTypes[number])[]);
-const NOTE_REQUIRED_GROUPED_NOTIFICATION_TYPES = new Set(['note', 'mention', 'reply', 'renote', 'renote:grouped', 'quote', 'reaction', 'reaction:grouped', 'pollEnded']);
+const NOTE_REQUIRED_NOTIFICATION_TYPES = new Set(['note', 'mention', 'reply', 'renote', 'renote:grouped', 'quote', 'reaction', 'reaction:grouped', 'pollEnded'] as (typeof groupedNotificationTypes[number])[]);
@Injectable()
export class NotificationEntityService implements OnModuleInit {
@@ -41,6 +41,8 @@ export class NotificationEntityService implements OnModuleInit {
@Inject(DI.followRequestsRepository)
private followRequestsRepository: FollowRequestsRepository,
+ private cacheService: CacheService,
+
//private userEntityService: UserEntityService,
//private noteEntityService: NoteEntityService,
) {
@@ -52,130 +54,48 @@ export class NotificationEntityService implements OnModuleInit {
this.roleEntityService = this.moduleRef.get('RoleEntityService');
}
- @bindThis
- public async pack(
- src: MiNotification,
+ /**
+ * 通知をパックã™ã‚‹å…±é€šå‡¦ç†
+ */
+ async #packInternal <T extends MiNotification | MiGroupedNotification> (
+ src: T,
meId: MiUser['id'],
// eslint-disable-next-line @typescript-eslint/ban-types
options: {
-
+ checkValidNotifier?: boolean;
},
hint?: {
packedNotes: Map<MiNote['id'], Packed<'Note'>>;
packedUsers: Map<MiUser['id'], Packed<'UserLite'>>;
},
- ): Promise<Packed<'Notification'>> {
+ ): Promise<Packed<'Notification'> | null> {
const notification = src;
- const noteIfNeed = NOTE_REQUIRED_NOTIFICATION_TYPES.has(notification.type) && 'noteId' in notification ? (
- hint?.packedNotes != null
- ? hint.packedNotes.get(notification.noteId)
- : this.noteEntityService.pack(notification.noteId, { id: meId }, {
- detail: true,
- })
- ) : undefined;
- const userIfNeed = 'notifierId' in notification ? (
- hint?.packedUsers != null
- ? hint.packedUsers.get(notification.notifierId)
- : this.userEntityService.pack(notification.notifierId, { id: meId })
- ) : undefined;
- const role = notification.type === 'roleAssigned' ? await this.roleEntityService.pack(notification.roleId) : undefined;
-
- return await awaitAll({
- id: notification.id,
- createdAt: new Date(notification.createdAt).toISOString(),
- type: notification.type,
- userId: 'notifierId' in notification ? notification.notifierId : undefined,
- ...(userIfNeed != null ? { user: userIfNeed } : {}),
- ...(noteIfNeed != null ? { note: noteIfNeed } : {}),
- ...(notification.type === 'reaction' ? {
- reaction: notification.reaction,
- } : {}),
- ...(notification.type === 'roleAssigned' ? {
- role: role,
- } : {}),
- ...(notification.type === 'achievementEarned' ? {
- achievement: notification.achievement,
- } : {}),
- ...(notification.type === 'app' ? {
- body: notification.customBody,
- header: notification.customHeader,
- icon: notification.customIcon,
- } : {}),
- });
- }
-
- @bindThis
- public async packMany(
- notifications: MiNotification[],
- meId: MiUser['id'],
- ) {
- if (notifications.length === 0) return [];
-
- let validNotifications = notifications;
-
- const noteIds = validNotifications.map(x => 'noteId' in x ? x.noteId : null).filter(isNotNull);
- const notes = noteIds.length > 0 ? await this.notesRepository.find({
- where: { id: In(noteIds) },
- relations: ['user', 'reply', 'reply.user', 'renote', 'renote.user'],
- }) : [];
- const packedNotesArray = await this.noteEntityService.packMany(notes, { id: meId }, {
- detail: true,
- });
- const packedNotes = new Map(packedNotesArray.map(p => [p.id, p]));
-
- validNotifications = validNotifications.filter(x => !('noteId' in x) || packedNotes.has(x.noteId));
-
- const userIds = validNotifications.map(x => 'notifierId' in x ? x.notifierId : null).filter(isNotNull);
- const users = userIds.length > 0 ? await this.usersRepository.find({
- where: { id: In(userIds) },
- }) : [];
- const packedUsersArray = await this.userEntityService.packMany(users, { id: meId });
- const packedUsers = new Map(packedUsersArray.map(p => [p.id, p]));
-
- // æ—¢ã«è§£æ±ºã•れãŸãƒ•ォローリクエストã®é€šçŸ¥ã‚’除外
- const followRequestNotifications = validNotifications.filter((x): x is FilterUnionByProperty<MiGroupedNotification, 'type', 'receiveFollowRequest'> => x.type === 'receiveFollowRequest');
- if (followRequestNotifications.length > 0) {
- const reqs = await this.followRequestsRepository.find({
- where: { followerId: In(followRequestNotifications.map(x => x.notifierId)) },
- });
- validNotifications = validNotifications.filter(x => (x.type !== 'receiveFollowRequest') || reqs.some(r => r.followerId === x.notifierId));
- }
- return await Promise.all(validNotifications.map(x => this.pack(x, meId, {}, {
- packedNotes,
- packedUsers,
- })));
- }
+ if (options.checkValidNotifier !== false && !(await this.#isValidNotifier(notification, meId))) return null;
- @bindThis
- public async packGrouped(
- src: MiGroupedNotification,
- meId: MiUser['id'],
- // eslint-disable-next-line @typescript-eslint/ban-types
- options: {
-
- },
- hint?: {
- packedNotes: Map<MiNote['id'], Packed<'Note'>>;
- packedUsers: Map<MiUser['id'], Packed<'UserLite'>>;
- },
- ): Promise<Packed<'Notification'>> {
- const notification = src;
- const noteIfNeed = NOTE_REQUIRED_GROUPED_NOTIFICATION_TYPES.has(notification.type) && 'noteId' in notification ? (
+ const needsNote = NOTE_REQUIRED_NOTIFICATION_TYPES.has(notification.type) && 'noteId' in notification;
+ const noteIfNeed = needsNote ? (
hint?.packedNotes != null
? hint.packedNotes.get(notification.noteId)
: this.noteEntityService.pack(notification.noteId, { id: meId }, {
detail: true,
})
) : undefined;
- const userIfNeed = 'notifierId' in notification ? (
+ // if the note has been deleted, don't show this notification
+ if (needsNote && !noteIfNeed) return null;
+
+ const needsUser = 'notifierId' in notification;
+ const userIfNeed = needsUser ? (
hint?.packedUsers != null
? hint.packedUsers.get(notification.notifierId)
: this.userEntityService.pack(notification.notifierId, { id: meId })
) : undefined;
+ // if the user has been deleted, don't show this notification
+ if (needsUser && !userIfNeed) return null;
+ // #region Grouped notifications
if (notification.type === 'reaction:grouped') {
- const reactions = await Promise.all(notification.reactions.map(async reaction => {
+ const reactions = (await Promise.all(notification.reactions.map(async reaction => {
const user = hint?.packedUsers != null
? hint.packedUsers.get(reaction.userId)!
: await this.userEntityService.pack(reaction.userId, { id: meId });
@@ -183,7 +103,12 @@ export class NotificationEntityService implements OnModuleInit {
user,
reaction: reaction.reaction,
};
- }));
+ }))).filter(r => isNotNull(r.user));
+ // if all users have been deleted, don't show this notification
+ if (reactions.length === 0) {
+ return null;
+ }
+
return await awaitAll({
id: notification.id,
createdAt: new Date(notification.createdAt).toISOString(),
@@ -192,14 +117,19 @@ export class NotificationEntityService implements OnModuleInit {
reactions,
});
} else if (notification.type === 'renote:grouped') {
- const users = await Promise.all(notification.userIds.map(userId => {
+ const users = (await Promise.all(notification.userIds.map(userId => {
const packedUser = hint?.packedUsers != null ? hint.packedUsers.get(userId) : null;
if (packedUser) {
return packedUser;
}
return this.userEntityService.pack(userId, { id: meId });
- }));
+ }))).filter(isNotNull);
+ // if all users have been deleted, don't show this notification
+ if (users.length === 0) {
+ return null;
+ }
+
return await awaitAll({
id: notification.id,
createdAt: new Date(notification.createdAt).toISOString(),
@@ -208,8 +138,14 @@ export class NotificationEntityService implements OnModuleInit {
users,
});
}
+ // #endregion
- const role = notification.type === 'roleAssigned' ? await this.roleEntityService.pack(notification.roleId) : undefined;
+ const needsRole = notification.type === 'roleAssigned';
+ const role = needsRole ? await this.roleEntityService.pack(notification.roleId) : undefined;
+ // if the role has been deleted, don't show this notification
+ if (needsRole && !role) {
+ return null;
+ }
return await awaitAll({
id: notification.id,
@@ -235,15 +171,16 @@ export class NotificationEntityService implements OnModuleInit {
});
}
- @bindThis
- public async packGroupedMany(
- notifications: MiGroupedNotification[],
+ async #packManyInternal <T extends MiNotification | MiGroupedNotification> (
+ notifications: T[],
meId: MiUser['id'],
- ) {
+ ): Promise<T[]> {
if (notifications.length === 0) return [];
let validNotifications = notifications;
+ validNotifications = await this.#filterValidNotifier(validNotifications, meId);
+
const noteIds = validNotifications.map(x => 'noteId' in x ? x.noteId : null).filter(isNotNull);
const notes = noteIds.length > 0 ? await this.notesRepository.find({
where: { id: In(noteIds) },
@@ -269,7 +206,7 @@ export class NotificationEntityService implements OnModuleInit {
const packedUsers = new Map(packedUsersArray.map(p => [p.id, p]));
// æ—¢ã«è§£æ±ºã•れãŸãƒ•ォローリクエストã®é€šçŸ¥ã‚’除外
- const followRequestNotifications = validNotifications.filter((x): x is FilterUnionByProperty<MiGroupedNotification, 'type', 'receiveFollowRequest'> => x.type === 'receiveFollowRequest');
+ const followRequestNotifications = validNotifications.filter((x): x is FilterUnionByProperty<T, 'type', 'receiveFollowRequest'> => x.type === 'receiveFollowRequest');
if (followRequestNotifications.length > 0) {
const reqs = await this.followRequestsRepository.find({
where: { followerId: In(followRequestNotifications.map(x => x.notifierId)) },
@@ -277,9 +214,107 @@ export class NotificationEntityService implements OnModuleInit {
validNotifications = validNotifications.filter(x => (x.type !== 'receiveFollowRequest') || reqs.some(r => r.followerId === x.notifierId));
}
- return await Promise.all(validNotifications.map(x => this.packGrouped(x, meId, {}, {
- packedNotes,
- packedUsers,
- })));
+ const packPromises = validNotifications.map(x => {
+ return this.pack(
+ x,
+ meId,
+ { checkValidNotifier: false },
+ { packedNotes, packedUsers },
+ );
+ });
+
+ return (await Promise.all(packPromises)).filter(isNotNull);
+ }
+
+ @bindThis
+ public async pack(
+ src: MiNotification | MiGroupedNotification,
+ meId: MiUser['id'],
+ // eslint-disable-next-line @typescript-eslint/ban-types
+ options: {
+ checkValidNotifier?: boolean;
+ },
+ hint?: {
+ packedNotes: Map<MiNote['id'], Packed<'Note'>>;
+ packedUsers: Map<MiUser['id'], Packed<'UserLite'>>;
+ },
+ ): Promise<Packed<'Notification'> | null> {
+ return await this.#packInternal(src, meId, options, hint);
+ }
+
+ @bindThis
+ public async packMany(
+ notifications: MiNotification[],
+ meId: MiUser['id'],
+ ): Promise<MiNotification[]> {
+ return await this.#packManyInternal(notifications, meId);
+ }
+
+ @bindThis
+ public async packGroupedMany(
+ notifications: MiGroupedNotification[],
+ meId: MiUser['id'],
+ ): Promise<MiGroupedNotification[]> {
+ return await this.#packManyInternal(notifications, meId);
+ }
+
+ /**
+ * notifierãŒå­˜åœ¨ã™ã‚‹ã‹ã€ãƒŸãƒ¥ãƒ¼ãƒˆã•れã¦ã„ãªã„ã‹ã€ã‚µã‚¹ãƒšãƒ³ãƒ‰ã•れã¦ã„ãªã„ã‹ã‚’確èªã™ã‚‹validator
+ */
+ #validateNotifier <T extends MiNotification | MiGroupedNotification> (
+ notification: T,
+ userIdsWhoMeMuting: Set<MiUser['id']>,
+ userMutedInstances: Set<string>,
+ notifiers: MiUser[],
+ ): boolean {
+ if (!('notifierId' in notification)) return true;
+ if (userIdsWhoMeMuting.has(notification.notifierId)) return false;
+
+ const notifier = notifiers.find(x => x.id === notification.notifierId) ?? null;
+
+ if (notifier == null) return false;
+ if (notifier.host && userMutedInstances.has(notifier.host)) return false;
+
+ if (notifier.isSuspended) return false;
+
+ return true;
+ }
+
+ /**
+ * notifierãŒå­˜åœ¨ã™ã‚‹ã‹ã€ãƒŸãƒ¥ãƒ¼ãƒˆã•れã¦ã„ãªã„ã‹ã€ã‚µã‚¹ãƒšãƒ³ãƒ‰ã•れã¦ã„ãªã„ã‹ã‚’実際ã«ç¢ºèªã™ã‚‹
+ */
+ async #isValidNotifier(
+ notification: MiNotification | MiGroupedNotification,
+ meId: MiUser['id'],
+ ): Promise<boolean> {
+ return (await this.#filterValidNotifier([notification], meId)).length === 1;
+ }
+
+ /**
+ * notifierãŒå­˜åœ¨ã™ã‚‹ã‹ã€ãƒŸãƒ¥ãƒ¼ãƒˆã•れã¦ã„ãªã„ã‹ã€ã‚µã‚¹ãƒšãƒ³ãƒ‰ã•れã¦ã„ãªã„ã‹ã‚’実際ã«è¤‡æ•°ç¢ºèªã™ã‚‹
+ */
+ async #filterValidNotifier <T extends MiNotification | MiGroupedNotification> (
+ notifications: T[],
+ meId: MiUser['id'],
+ ): Promise<T[]> {
+ const [
+ userIdsWhoMeMuting,
+ userMutedInstances,
+ ] = await Promise.all([
+ this.cacheService.userMutingsCache.fetch(meId),
+ this.cacheService.userProfileCache.fetch(meId).then(p => new Set(p.mutedInstances)),
+ ]);
+
+ const notifierIds = notifications.map(notification => 'notifierId' in notification ? notification.notifierId : null).filter(isNotNull);
+ const notifiers = notifierIds.length > 0 ? await this.usersRepository.find({
+ where: { id: In(notifierIds) },
+ }) : [];
+
+ const filteredNotifications = ((await Promise.all(notifications.map(async (notification) => {
+ const isValid = this.#validateNotifier(notification, userIdsWhoMeMuting, userMutedInstances, notifiers);
+ return isValid ? notification : null;
+ }))) as [T | null] ).filter(isNotNull);
+
+ return filteredNotifications;
}
}
diff --git a/packages/backend/src/core/entities/PageEntityService.ts b/packages/backend/src/core/entities/PageEntityService.ts
index fe7b137bd2..65c69a49a7 100644
--- a/packages/backend/src/core/entities/PageEntityService.ts
+++ b/packages/backend/src/core/entities/PageEntityService.ts
@@ -14,6 +14,7 @@ import type { MiPage } from '@/models/Page.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
+import { isNotNull } from '@/misc/is-not-null.js';
import { UserEntityService } from './UserEntityService.js';
import { DriveFileEntityService } from './DriveFileEntityService.js';
@@ -102,7 +103,7 @@ export class PageEntityService {
script: page.script,
eyeCatchingImageId: page.eyeCatchingImageId,
eyeCatchingImage: page.eyeCatchingImageId ? await this.driveFileEntityService.pack(page.eyeCatchingImageId) : null,
- attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter((x): x is MiDriveFile => x != null)),
+ attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter(isNotNull)),
likedCount: page.likedCount,
isLiked: meId ? await this.pageLikesRepository.exists({ where: { pageId: page.id, userId: meId } }) : undefined,
});
diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts
index 53df32f210..14761357a5 100644
--- a/packages/backend/src/core/entities/UserEntityService.ts
+++ b/packages/backend/src/core/entities/UserEntityService.ts
@@ -25,6 +25,7 @@ import { IdService } from '@/core/IdService.js';
import type { AnnouncementService } from '@/core/AnnouncementService.js';
import type { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
+import { isNotNull } from '@/misc/is-not-null.js';
import type { OnModuleInit } from '@nestjs/common';
import type { NoteEntityService } from './NoteEntityService.js';
import type { DriveFileEntityService } from './DriveFileEntityService.js';
@@ -384,7 +385,7 @@ export class UserEntityService implements OnModuleInit {
movedTo: user.movedToUri ? this.apPersonService.resolvePerson(user.movedToUri).then(user => user.id).catch(() => null) : null,
alsoKnownAs: user.alsoKnownAs
? Promise.all(user.alsoKnownAs.map(uri => this.apPersonService.fetchPerson(uri).then(user => user?.id).catch(() => null)))
- .then(xs => xs.length === 0 ? null : xs.filter(x => x != null) as string[])
+ .then(xs => xs.length === 0 ? null : xs.filter(isNotNull))
: null,
createdAt: this.idService.parse(user.id).date.toISOString(),
updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
diff --git a/packages/backend/src/misc/FileWriterStream.ts b/packages/backend/src/misc/FileWriterStream.ts
new file mode 100644
index 0000000000..367a8eb560
--- /dev/null
+++ b/packages/backend/src/misc/FileWriterStream.ts
@@ -0,0 +1,36 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import * as fs from 'node:fs/promises';
+import type { PathLike } from 'node:fs';
+
+/**
+ * `fs.createWriteStream()`相当ã®ã“ã¨ã‚’行ã†`WritableStream` (Web標準)
+ */
+export class FileWriterStream extends WritableStream<Uint8Array> {
+ constructor(path: PathLike) {
+ let file: fs.FileHandle | null = null;
+
+ super({
+ start: async () => {
+ file = await fs.open(path, 'a');
+ },
+ write: async (chunk, controller) => {
+ if (file === null) {
+ controller.error();
+ throw new Error();
+ }
+
+ await file.write(chunk);
+ },
+ close: async () => {
+ await file?.close();
+ },
+ abort: async () => {
+ await file?.close();
+ },
+ });
+ }
+}
diff --git a/packages/backend/src/misc/JsonArrayStream.ts b/packages/backend/src/misc/JsonArrayStream.ts
new file mode 100644
index 0000000000..754938989d
--- /dev/null
+++ b/packages/backend/src/misc/JsonArrayStream.ts
@@ -0,0 +1,35 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { TransformStream } from 'node:stream/web';
+
+/**
+ * ã‚¹ãƒˆãƒªãƒ¼ãƒ ã«æµã‚Œã¦ããŸå„データã«ã¤ã„ã¦`JSON.stringify()`ã—ãŸä¸Šã§ã€ãれらを一ã¤ã®é…列ã«ã¾ã¨ã‚ã‚‹
+ */
+export class JsonArrayStream extends TransformStream<unknown, string> {
+ constructor() {
+ /** 最åˆã®è¦ç´ ã‹ã©ã†ã‹ã‚’変数ã«è¨˜éŒ² */
+ let isFirst = true;
+
+ super({
+ start(controller) {
+ controller.enqueue('[');
+ },
+ flush(controller) {
+ controller.enqueue(']');
+ },
+ transform(chunk, controller) {
+ if (isFirst) {
+ isFirst = false;
+ } else {
+ // 妥当ãªJSONé…列ã«ã™ã‚‹ãŸã‚ã«ã¯æœ€åˆä»¥å¤–ã®è¦ç´ ã®å‰ã«`,`を挿入ã—ãªã‘れã°ãªã‚‰ãªã„
+ controller.enqueue(',\n');
+ }
+
+ controller.enqueue(JSON.stringify(chunk));
+ },
+ });
+ }
+}
diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts
index 7f4d1521b5..bba64a06ef 100644
--- a/packages/backend/src/misc/cache.ts
+++ b/packages/backend/src/misc/cache.ts
@@ -187,6 +187,10 @@ export class RedisSingleCache<T> {
// TODO: メモリ節約ã®ãŸã‚ã‚ã¾ã‚Šå‚ç…§ã•れãªã„キーを定期的ã«å‰Šé™¤ã§ãるよã†ã«ã™ã‚‹ï¼Ÿ
export class MemoryKVCache<T> {
+ /**
+ * データをæŒã¤ãƒžãƒƒãƒ—
+ * @deprecated ã“れを直接æ“作ã™ã‚‹ã¹ãã§ã¯ãªã„
+ */
public cache: Map<string, { date: number; value: T; }>;
private lifetime: number;
private gcIntervalHandle: NodeJS.Timeout;
@@ -201,6 +205,10 @@ export class MemoryKVCache<T> {
}
@bindThis
+ /**
+ * Mapã«ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’セットã—ã¾ã™
+ * @deprecated ã“れを直接呼ã³å‡ºã™ã¹ãã§ã¯ãªã„。InternalEventãªã©ã§å¤‰æ›´ã‚’å…¨ã¦ã®ãƒ—ロセス/マシンã«é€šçŸ¥ã™ã‚‹ã¹ã
+ */
public set(key: string, value: T): void {
this.cache.set(key, {
date: Date.now(),
diff --git a/packages/backend/src/misc/is-not-null.ts b/packages/backend/src/misc/is-not-null.ts
index 584a09d35a..8d9dc8bb39 100644
--- a/packages/backend/src/misc/is-not-null.ts
+++ b/packages/backend/src/misc/is-not-null.ts
@@ -3,8 +3,6 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-// we are using {} as "any non-nullish value" as expected
-// eslint-disable-next-line @typescript-eslint/ban-types
-export function isNotNull<T extends {}>(input: T | undefined | null): input is T {
+export function isNotNull<T extends NonNullable<unknown>>(input: T | undefined | null): input is T {
return input != null;
}
diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts
index de38f145b2..46b0bb2fab 100644
--- a/packages/backend/src/misc/json-schema.ts
+++ b/packages/backend/src/misc/json-schema.ts
@@ -44,12 +44,18 @@ import {
packedRoleCondFormulaLogicsSchema,
packedRoleCondFormulaValueNot,
packedRoleCondFormulaValueIsLocalOrRemoteSchema,
+ packedRoleCondFormulaValueAssignedRoleSchema,
packedRoleCondFormulaValueCreatedSchema,
packedRoleCondFormulaFollowersOrFollowingOrNotesSchema,
packedRoleCondFormulaValueSchema,
} from '@/models/json-schema/role.js';
import { packedAdSchema } from '@/models/json-schema/ad.js';
import { packedReversiGameLiteSchema, packedReversiGameDetailedSchema } from '@/models/json-schema/reversi-game.js';
+import {
+ packedMetaLiteSchema,
+ packedMetaDetailedOnlySchema,
+ packedMetaDetailedSchema,
+} from '@/models/json-schema/meta.js';
export const refs = {
UserLite: packedUserLiteSchema,
@@ -91,6 +97,7 @@ export const refs = {
RoleCondFormulaLogics: packedRoleCondFormulaLogicsSchema,
RoleCondFormulaValueNot: packedRoleCondFormulaValueNot,
RoleCondFormulaValueIsLocalOrRemote: packedRoleCondFormulaValueIsLocalOrRemoteSchema,
+ RoleCondFormulaValueAssignedRole: packedRoleCondFormulaValueAssignedRoleSchema,
RoleCondFormulaValueCreated: packedRoleCondFormulaValueCreatedSchema,
RoleCondFormulaFollowersOrFollowingOrNotes: packedRoleCondFormulaFollowersOrFollowingOrNotesSchema,
RoleCondFormulaValue: packedRoleCondFormulaValueSchema,
@@ -99,6 +106,9 @@ export const refs = {
RolePolicies: packedRolePoliciesSchema,
ReversiGameLite: packedReversiGameLiteSchema,
ReversiGameDetailed: packedReversiGameDetailedSchema,
+ MetaLite: packedMetaLiteSchema,
+ MetaDetailedOnly: packedMetaDetailedOnlySchema,
+ MetaDetailed: packedMetaDetailedSchema,
};
export type Packed<x extends keyof typeof refs> = SchemaType<typeof refs[x]>;
diff --git a/packages/backend/src/models/Instance.ts b/packages/backend/src/models/Instance.ts
index 0632ef525b..9863c9d75d 100644
--- a/packages/backend/src/models/Instance.ts
+++ b/packages/backend/src/models/Instance.ts
@@ -144,4 +144,9 @@ export class MiInstance {
nullable: true,
})
public infoUpdatedAt: Date | null;
+
+ @Column('varchar', {
+ length: 16384, default: '',
+ })
+ public moderationNote: string;
}
diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts
index 6ed0ec6ce5..66f19ce197 100644
--- a/packages/backend/src/models/Meta.ts
+++ b/packages/backend/src/models/Meta.ts
@@ -253,6 +253,8 @@ export class MiMeta {
})
public turnstileSecretKey: string | null;
+ // chaptcha系を追加ã—ãŸéš›ã«ã¯nodeinfoã®ãƒ¬ã‚¹ãƒãƒ³ã‚¹ã«è¿½åŠ ã™ã‚‹ã®ã‚’忘れãªã„よã†ã«ã™ã‚‹ã“ã¨
+
@Column('enum', {
enum: ['none', 'all', 'local', 'remote'],
default: 'none',
diff --git a/packages/backend/src/models/Role.ts b/packages/backend/src/models/Role.ts
index fa05ea8637..058abe3118 100644
--- a/packages/backend/src/models/Role.ts
+++ b/packages/backend/src/models/Role.ts
@@ -29,6 +29,11 @@ type CondFormulaValueIsRemote = {
type: 'isRemote';
};
+type CondFormulaValueRoleAssignedTo = {
+ type: 'roleAssignedTo';
+ roleId: string;
+};
+
type CondFormulaValueCreatedLessThan = {
type: 'createdLessThan';
sec: number;
@@ -75,6 +80,7 @@ export type RoleCondFormulaValue = { id: string } & (
CondFormulaValueNot |
CondFormulaValueIsLocal |
CondFormulaValueIsRemote |
+ CondFormulaValueRoleAssignedTo |
CondFormulaValueCreatedLessThan |
CondFormulaValueCreatedMoreThan |
CondFormulaValueFollowersLessThanOrEq |
diff --git a/packages/backend/src/models/UserProfile.ts b/packages/backend/src/models/UserProfile.ts
index 1ca2f55850..7dbe0b3717 100644
--- a/packages/backend/src/models/UserProfile.ts
+++ b/packages/backend/src/models/UserProfile.ts
@@ -250,6 +250,8 @@ export class MiUserProfile {
} | {
type: 'mutualFollow';
} | {
+ type: 'followingOrFollower';
+ } | {
type: 'list';
userListId: MiUserList['id'];
};
diff --git a/packages/backend/src/models/json-schema/federation-instance.ts b/packages/backend/src/models/json-schema/federation-instance.ts
index 087a0e6967..42d98fe523 100644
--- a/packages/backend/src/models/json-schema/federation-instance.ts
+++ b/packages/backend/src/models/json-schema/federation-instance.ts
@@ -107,5 +107,9 @@ export const packedFederationInstanceSchema = {
optional: false, nullable: true,
format: 'date-time',
},
+ moderationNote: {
+ type: 'string',
+ optional: true, nullable: true,
+ },
},
} as const;
diff --git a/packages/backend/src/models/json-schema/meta.ts b/packages/backend/src/models/json-schema/meta.ts
new file mode 100644
index 0000000000..17789f3b46
--- /dev/null
+++ b/packages/backend/src/models/json-schema/meta.ts
@@ -0,0 +1,328 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export const packedMetaLiteSchema = {
+ type: 'object',
+ optional: false, nullable: false,
+ properties: {
+ maintainerName: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ maintainerEmail: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ version: {
+ type: 'string',
+ optional: false, nullable: false,
+ },
+ providesTarball: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ name: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ shortName: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ uri: {
+ type: 'string',
+ optional: false, nullable: false,
+ format: 'url',
+ example: 'https://misskey.example.com',
+ },
+ description: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ langs: {
+ type: 'array',
+ optional: false, nullable: false,
+ items: {
+ type: 'string',
+ optional: false, nullable: false,
+ },
+ },
+ tosUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ repositoryUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ default: 'https://github.com/misskey-dev/misskey',
+ },
+ feedbackUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ default: 'https://github.com/misskey-dev/misskey/issues/new',
+ },
+ defaultDarkTheme: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ defaultLightTheme: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ disableRegistration: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ emailRequiredForSignup: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ enableHcaptcha: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ hcaptchaSiteKey: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ enableMcaptcha: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ mcaptchaSiteKey: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ mcaptchaInstanceUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ enableRecaptcha: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ recaptchaSiteKey: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ enableTurnstile: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ turnstileSiteKey: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ swPublickey: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ mascotImageUrl: {
+ type: 'string',
+ optional: false, nullable: false,
+ default: '/assets/ai.png',
+ },
+ bannerUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ serverErrorImageUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ infoImageUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ notFoundImageUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ iconUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ maxNoteTextLength: {
+ type: 'number',
+ optional: false, nullable: false,
+ },
+ ads: {
+ type: 'array',
+ optional: false, nullable: false,
+ items: {
+ type: 'object',
+ optional: false, nullable: false,
+ properties: {
+ id: {
+ type: 'string',
+ optional: false, nullable: false,
+ format: 'id',
+ example: 'xxxxxxxxxx',
+ },
+ url: {
+ type: 'string',
+ optional: false, nullable: false,
+ format: 'url',
+ },
+ place: {
+ type: 'string',
+ optional: false, nullable: false,
+ },
+ ratio: {
+ type: 'number',
+ optional: false, nullable: false,
+ },
+ imageUrl: {
+ type: 'string',
+ optional: false, nullable: false,
+ format: 'url',
+ },
+ dayOfWeek: {
+ type: 'integer',
+ optional: false, nullable: false,
+ },
+ },
+ },
+ },
+ notesPerOneAd: {
+ type: 'number',
+ optional: false, nullable: false,
+ default: 0,
+ },
+ enableEmail: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ enableServiceWorker: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ translatorAvailable: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ mediaProxy: {
+ type: 'string',
+ optional: false, nullable: false,
+ },
+ backgroundImageUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ impressumUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ logoImageUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ privacyPolicyUrl: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ serverRules: {
+ type: 'array',
+ optional: false, nullable: false,
+ items: {
+ type: 'string',
+ },
+ },
+ themeColor: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ policies: {
+ type: 'object',
+ optional: false, nullable: false,
+ ref: 'RolePolicies',
+ },
+ },
+} as const;
+
+export const packedMetaDetailedOnlySchema = {
+ type: 'object',
+ optional: false, nullable: false,
+ properties: {
+ features: {
+ type: 'object',
+ optional: true, nullable: false,
+ properties: {
+ registration: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ emailRequiredForSignup: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ localTimeline: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ globalTimeline: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ hcaptcha: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ turnstile: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ recaptcha: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ objectStorage: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ serviceWorker: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ miauth: {
+ type: 'boolean',
+ optional: true, nullable: false,
+ default: true,
+ },
+ },
+ },
+ proxyAccountName: {
+ type: 'string',
+ optional: false, nullable: true,
+ },
+ requireSetup: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ example: false,
+ },
+ cacheRemoteFiles: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ cacheRemoteSensitiveFiles: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ },
+} as const;
+
+export const packedMetaDetailedSchema = {
+ type: 'object',
+ allOf: [
+ {
+ type: 'object',
+ ref: 'MetaLite',
+ },
+ {
+ type: 'object',
+ ref: 'MetaDetailedOnly',
+ },
+ ],
+} as const;
diff --git a/packages/backend/src/models/json-schema/role.ts b/packages/backend/src/models/json-schema/role.ts
index ef6b279bee..c770250503 100644
--- a/packages/backend/src/models/json-schema/role.ts
+++ b/packages/backend/src/models/json-schema/role.ts
@@ -57,6 +57,26 @@ export const packedRoleCondFormulaValueIsLocalOrRemoteSchema = {
},
} as const;
+export const packedRoleCondFormulaValueAssignedRoleSchema = {
+ type: 'object',
+ properties: {
+ id: {
+ type: 'string', optional: false,
+ },
+ type: {
+ type: 'string',
+ nullable: false, optional: false,
+ enum: ['roleAssignedTo'],
+ },
+ roleId: {
+ type: 'string',
+ nullable: false, optional: false,
+ format: 'id',
+ example: 'xxxxxxxxxx',
+ },
+ },
+} as const;
+
export const packedRoleCondFormulaValueCreatedSchema = {
type: 'object',
properties: {
@@ -116,6 +136,9 @@ export const packedRoleCondFormulaValueSchema = {
ref: 'RoleCondFormulaValueIsLocalOrRemote',
},
{
+ ref: 'RoleCondFormulaValueAssignedRole',
+ },
+ {
ref: 'RoleCondFormulaValueCreated',
},
{
@@ -140,6 +163,10 @@ export const packedRolePoliciesSchema = {
type: 'boolean',
optional: false, nullable: false,
},
+ mentionLimit: {
+ type: 'integer',
+ optional: false, nullable: false,
+ },
canInvite: {
type: 'boolean',
optional: false, nullable: false,
diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts
index c7f86635da..947a9317d7 100644
--- a/packages/backend/src/models/json-schema/user.ts
+++ b/packages/backend/src/models/json-schema/user.ts
@@ -13,7 +13,7 @@ export const notificationRecieveConfig = {
type: {
type: 'string',
nullable: false,
- enum: ['all', 'following', 'follower', 'mutualFollow', 'never'],
+ enum: ['all', 'following', 'follower', 'mutualFollow', 'followingOrFollower', 'never'],
},
},
required: ['type'],
@@ -148,6 +148,9 @@ export const packedUserLiteSchema = {
emojis: {
type: 'object',
nullable: false, optional: false,
+ additionalProperties: {
+ type: 'string',
+ },
},
onlineStatus: {
type: 'string',
diff --git a/packages/backend/src/queue/processors/ExportNotesProcessorService.ts b/packages/backend/src/queue/processors/ExportNotesProcessorService.ts
index f2ae0ce4b4..c7611012d7 100644
--- a/packages/backend/src/queue/processors/ExportNotesProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportNotesProcessorService.ts
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import * as fs from 'node:fs';
+import { ReadableStream, TextEncoderStream } from 'node:stream/web';
import { Inject, Injectable } from '@nestjs/common';
import { MoreThan } from 'typeorm';
import { format as dateFormat } from 'date-fns';
@@ -18,10 +18,82 @@ import { bindThis } from '@/decorators.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
import { Packed } from '@/misc/json-schema.js';
import { IdService } from '@/core/IdService.js';
+import { JsonArrayStream } from '@/misc/JsonArrayStream.js';
+import { FileWriterStream } from '@/misc/FileWriterStream.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';
import type { DbJobDataWithUser } from '../types.js';
+class NoteStream extends ReadableStream<Record<string, unknown>> {
+ constructor(
+ job: Bull.Job,
+ notesRepository: NotesRepository,
+ pollsRepository: PollsRepository,
+ driveFileEntityService: DriveFileEntityService,
+ idService: IdService,
+ userId: string,
+ ) {
+ let exportedNotesCount = 0;
+ let cursor: MiNote['id'] | null = null;
+
+ const serialize = (
+ note: MiNote,
+ poll: MiPoll | null,
+ files: Packed<'DriveFile'>[],
+ ): Record<string, unknown> => {
+ return {
+ id: note.id,
+ text: note.text,
+ createdAt: idService.parse(note.id).date.toISOString(),
+ fileIds: note.fileIds,
+ files: files,
+ replyId: note.replyId,
+ renoteId: note.renoteId,
+ poll: poll,
+ cw: note.cw,
+ visibility: note.visibility,
+ visibleUserIds: note.visibleUserIds,
+ localOnly: note.localOnly,
+ reactionAcceptance: note.reactionAcceptance,
+ };
+ };
+
+ super({
+ async pull(controller): Promise<void> {
+ const notes = await notesRepository.find({
+ where: {
+ userId,
+ ...(cursor !== null ? { id: MoreThan(cursor) } : {}),
+ },
+ take: 100, // 100ä»¶ãšã¤å–å¾—
+ order: { id: 1 },
+ });
+
+ if (notes.length === 0) {
+ job.updateProgress(100);
+ controller.close();
+ }
+
+ cursor = notes.at(-1)?.id ?? null;
+
+ for (const note of notes) {
+ const poll = note.hasPoll
+ ? await pollsRepository.findOneByOrFail({ noteId: note.id }) // N+1
+ : null;
+ const files = await driveFileEntityService.packManyByIds(note.fileIds); // N+1
+ const content = serialize(note, poll, files);
+
+ controller.enqueue(content);
+ exportedNotesCount++;
+ }
+
+ const total = await notesRepository.countBy({ userId });
+ job.updateProgress(exportedNotesCount / total);
+ },
+ });
+ }
+}
+
@Injectable()
export class ExportNotesProcessorService {
private logger: Logger;
@@ -59,67 +131,19 @@ export class ExportNotesProcessorService {
this.logger.info(`Temp file is ${path}`);
try {
- const stream = fs.createWriteStream(path, { flags: 'a' });
-
- const write = (text: string): Promise<void> => {
- return new Promise<void>((res, rej) => {
- stream.write(text, err => {
- if (err) {
- this.logger.error(err);
- rej(err);
- } else {
- res();
- }
- });
- });
- };
-
- await write('[');
-
- let exportedNotesCount = 0;
- let cursor: MiNote['id'] | null = null;
-
- while (true) {
- const notes = await this.notesRepository.find({
- where: {
- userId: user.id,
- ...(cursor ? { id: MoreThan(cursor) } : {}),
- },
- take: 100,
- order: {
- id: 1,
- },
- }) as MiNote[];
-
- if (notes.length === 0) {
- job.updateProgress(100);
- break;
- }
-
- cursor = notes.at(-1)?.id ?? null;
-
- for (const note of notes) {
- let poll: MiPoll | undefined;
- if (note.hasPoll) {
- poll = await this.pollsRepository.findOneByOrFail({ noteId: note.id });
- }
- const files = await this.driveFileEntityService.packManyByIds(note.fileIds);
- const content = JSON.stringify(this.serialize(note, poll, files));
- const isFirst = exportedNotesCount === 0;
- await write(isFirst ? content : ',\n' + content);
- exportedNotesCount++;
- }
-
- const total = await this.notesRepository.countBy({
- userId: user.id,
- });
+ // メモリãŒè¶³ã‚Šãªããªã‚‰ãªã„よã†ã«ã‚¹ãƒˆãƒªãƒ¼ãƒ ã§å‡¦ç†ã™ã‚‹
+ await new NoteStream(
+ job,
+ this.notesRepository,
+ this.pollsRepository,
+ this.driveFileEntityService,
+ this.idService,
+ user.id,
+ )
+ .pipeThrough(new JsonArrayStream())
+ .pipeThrough(new TextEncoderStream())
+ .pipeTo(new FileWriterStream(path));
- job.updateProgress(exportedNotesCount / total);
- }
-
- await write(']');
-
- stream.end();
this.logger.succ(`Exported to: ${path}`);
const fileName = 'notes-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.json';
@@ -130,22 +154,4 @@ export class ExportNotesProcessorService {
cleanup();
}
}
-
- private serialize(note: MiNote, poll: MiPoll | null = null, files: Packed<'DriveFile'>[]): Record<string, unknown> {
- return {
- id: note.id,
- text: note.text,
- createdAt: this.idService.parse(note.id).date.toISOString(),
- fileIds: note.fileIds,
- files: files,
- replyId: note.replyId,
- renoteId: note.renoteId,
- poll: poll,
- cw: note.cw,
- visibility: note.visibility,
- visibleUserIds: note.visibleUserIds,
- localOnly: note.localOnly,
- reactionAcceptance: note.reactionAcceptance,
- };
- }
}
diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts
index 7adadd799b..3addead058 100644
--- a/packages/backend/src/queue/processors/InboxProcessorService.ts
+++ b/packages/backend/src/queue/processors/InboxProcessorService.ts
@@ -24,6 +24,7 @@ import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
import { LdSignatureService } from '@/core/activitypub/LdSignatureService.js';
import { ApInboxService } from '@/core/activitypub/ApInboxService.js';
import { bindThis } from '@/decorators.js';
+import { IdentifiableError } from '@/misc/identifiable-error.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type { InboxJobData } from '../types.js';
@@ -180,7 +181,17 @@ export class InboxProcessorService {
});
// アクティビティを処ç†
- await this.apInboxService.performActivity(authUser.user, activity);
+ try {
+ await this.apInboxService.performActivity(authUser.user, activity);
+ } catch (e) {
+ if (e instanceof IdentifiableError) {
+ if (e.id === '689ee33f-f97c-479a-ac49-1b9f8140af99') {
+ return 'blocked notes with prohibited words';
+ }
+ if (e.id === '85ab9bd7-3a41-4530-959d-f07073900109') return 'actor has been suspended';
+ }
+ throw e;
+ }
return 'ok';
}
}
diff --git a/packages/backend/src/server/NodeinfoServerService.ts b/packages/backend/src/server/NodeinfoServerService.ts
index 81318ab5ac..c1e5af08c9 100644
--- a/packages/backend/src/server/NodeinfoServerService.ts
+++ b/packages/backend/src/server/NodeinfoServerService.ts
@@ -117,6 +117,8 @@ export class NodeinfoServerService {
emailRequiredForSignup: meta.emailRequiredForSignup,
enableHcaptcha: meta.enableHcaptcha,
enableRecaptcha: meta.enableRecaptcha,
+ enableMcaptcha: meta.enableMcaptcha,
+ enableTurnstile: meta.enableTurnstile,
maxNoteTextLength: MAX_NOTE_TEXT_LENGTH,
enableEmail: meta.enableEmail,
enableServiceWorker: meta.enableServiceWorker,
diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts
index 8a003725cd..88d3999eb0 100644
--- a/packages/backend/src/server/api/EndpointsModule.ts
+++ b/packages/backend/src/server/api/EndpointsModule.ts
@@ -293,6 +293,7 @@ import * as ep___notes_translate from './endpoints/notes/translate.js';
import * as ep___notes_unrenote from './endpoints/notes/unrenote.js';
import * as ep___notes_userListTimeline from './endpoints/notes/user-list-timeline.js';
import * as ep___notifications_create from './endpoints/notifications/create.js';
+import * as ep___notifications_flush from './endpoints/notifications/flush.js';
import * as ep___notifications_markAllAsRead from './endpoints/notifications/mark-all-as-read.js';
import * as ep___notifications_testNotification from './endpoints/notifications/test-notification.js';
import * as ep___pagePush from './endpoints/page-push.js';
@@ -664,6 +665,7 @@ const $notes_translate: Provider = { provide: 'ep:notes/translate', useClass: ep
const $notes_unrenote: Provider = { provide: 'ep:notes/unrenote', useClass: ep___notes_unrenote.default };
const $notes_userListTimeline: Provider = { provide: 'ep:notes/user-list-timeline', useClass: ep___notes_userListTimeline.default };
const $notifications_create: Provider = { provide: 'ep:notifications/create', useClass: ep___notifications_create.default };
+const $notifications_flush: Provider = { provide: 'ep:notifications/flush', useClass: ep___notifications_flush.default };
const $notifications_markAllAsRead: Provider = { provide: 'ep:notifications/mark-all-as-read', useClass: ep___notifications_markAllAsRead.default };
const $notifications_testNotification: Provider = { provide: 'ep:notifications/test-notification', useClass: ep___notifications_testNotification.default };
const $pagePush: Provider = { provide: 'ep:page-push', useClass: ep___pagePush.default };
@@ -1039,6 +1041,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$notes_unrenote,
$notes_userListTimeline,
$notifications_create,
+ $notifications_flush,
$notifications_markAllAsRead,
$notifications_testNotification,
$pagePush,
@@ -1408,7 +1411,9 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$notes_unrenote,
$notes_userListTimeline,
$notifications_create,
+ $notifications_flush,
$notifications_markAllAsRead,
+ $notifications_testNotification,
$pagePush,
$pages_create,
$pages_delete,
diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts
index e1c8be727e..f7e64a7356 100644
--- a/packages/backend/src/server/api/endpoints.ts
+++ b/packages/backend/src/server/api/endpoints.ts
@@ -293,6 +293,7 @@ import * as ep___notes_translate from './endpoints/notes/translate.js';
import * as ep___notes_unrenote from './endpoints/notes/unrenote.js';
import * as ep___notes_userListTimeline from './endpoints/notes/user-list-timeline.js';
import * as ep___notifications_create from './endpoints/notifications/create.js';
+import * as ep___notifications_flush from './endpoints/notifications/flush.js';
import * as ep___notifications_markAllAsRead from './endpoints/notifications/mark-all-as-read.js';
import * as ep___notifications_testNotification from './endpoints/notifications/test-notification.js';
import * as ep___pagePush from './endpoints/page-push.js';
@@ -662,6 +663,7 @@ const eps = [
['notes/unrenote', ep___notes_unrenote],
['notes/user-list-timeline', ep___notes_userListTimeline],
['notifications/create', ep___notifications_create],
+ ['notifications/flush', ep___notifications_flush],
['notifications/mark-all-as-read', ep___notifications_markAllAsRead],
['notifications/test-notification', ep___notifications_testNotification],
['page-push', ep___pagePush],
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts
index e32a19120d..796f273330 100644
--- a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts
+++ b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts
@@ -31,7 +31,10 @@ export const meta = {
},
},
- ref: 'EmojiDetailed',
+ res: {
+ type: 'object',
+ ref: 'EmojiDetailed',
+ },
} as const;
export const paramDef = {
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts
index a9ff4236d2..22609a16a3 100644
--- a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts
+++ b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts
@@ -57,7 +57,10 @@ export const paramDef = {
type: 'string',
} },
},
- required: ['id', 'name', 'aliases'],
+ anyOf: [
+ { required: ['id'] },
+ { required: ['name'] },
+ ],
} as const;
@Injectable()
@@ -70,27 +73,33 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
) {
super(meta, paramDef, async (ps, me) => {
let driveFile;
-
if (ps.fileId) {
driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
}
- const emoji = await this.customEmojiService.getEmojiById(ps.id);
- if (emoji != null) {
- if (ps.name !== emoji.name) {
+
+ let emojiId;
+ if (ps.id) {
+ emojiId = ps.id;
+ const emoji = await this.customEmojiService.getEmojiById(ps.id);
+ if (!emoji) throw new ApiError(meta.errors.noSuchEmoji);
+ if (ps.name && (ps.name !== emoji.name)) {
const isDuplicate = await this.customEmojiService.checkDuplicate(ps.name);
if (isDuplicate) throw new ApiError(meta.errors.sameNameEmojiExists);
}
} else {
- throw new ApiError(meta.errors.noSuchEmoji);
+ if (!ps.name) throw new Error('Invalid Params unexpectedly passed. This is a BUG. Please report it to the development team.');
+ const emoji = await this.customEmojiService.getEmojiByName(ps.name);
+ if (!emoji) throw new ApiError(meta.errors.noSuchEmoji);
+ emojiId = emoji.id;
}
- await this.customEmojiService.update(ps.id, {
+ await this.customEmojiService.update(emojiId, {
driveFile,
name: ps.name,
- category: ps.category ?? null,
+ category: ps.category,
aliases: ps.aliases,
- license: ps.license ?? null,
+ license: ps.license,
isSensitive: ps.isSensitive,
localOnly: ps.localOnly,
roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction,
diff --git a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts
index b989b99e47..0bcdc2a4b8 100644
--- a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts
+++ b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts
@@ -24,8 +24,9 @@ export const paramDef = {
properties: {
host: { type: 'string' },
isSuspended: { type: 'boolean' },
+ moderationNote: { type: 'string' },
},
- required: ['host', 'isSuspended'],
+ required: ['host'],
} as const;
@Injectable()
@@ -47,9 +48,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
await this.federatedInstanceService.update(instance.id, {
isSuspended: ps.isSuspended,
+ moderationNote: ps.moderationNote,
});
- if (instance.isSuspended !== ps.isSuspended) {
+ if (ps.isSuspended != null && instance.isSuspended !== ps.isSuspended) {
if (ps.isSuspended) {
this.moderationLogService.log(me, 'suspendRemoteInstance', {
id: instance.id,
@@ -62,6 +64,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
});
}
}
+
+ if (ps.moderationNote != null && instance.moderationNote !== ps.moderationNote) {
+ this.moderationLogService.log(me, 'updateRemoteInstanceNote', {
+ id: instance.id,
+ host: instance.host,
+ before: instance.moderationNote,
+ after: ps.moderationNote,
+ });
+ }
});
}
}
diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts
index 39f3fab21e..f4dfe1ecc4 100644
--- a/packages/backend/src/server/api/endpoints/antennas/notes.ts
+++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts
@@ -124,9 +124,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
notes.sort((a, b) => a.id > b.id ? -1 : 1);
}
- if (notes.length > 0) {
- this.noteReadService.read(me.id, notes);
- }
+ this.noteReadService.read(me.id, notes);
return await this.noteEntityService.packMany(notes, me);
});
diff --git a/packages/backend/src/server/api/endpoints/federation/show-instance.ts b/packages/backend/src/server/api/endpoints/federation/show-instance.ts
index e3c598d110..2972861a4b 100644
--- a/packages/backend/src/server/api/endpoints/federation/show-instance.ts
+++ b/packages/backend/src/server/api/endpoints/federation/show-instance.ts
@@ -43,7 +43,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
const instance = await this.instancesRepository
.findOneBy({ host: this.utilityService.toPuny(ps.host) });
- return instance ? await this.instanceEntityService.pack(instance) : null;
+ return instance ? await this.instanceEntityService.pack(instance, me) : null;
});
}
}
diff --git a/packages/backend/src/server/api/endpoints/flash/update.ts b/packages/backend/src/server/api/endpoints/flash/update.ts
index 7d7633daa5..e378669f0a 100644
--- a/packages/backend/src/server/api/endpoints/flash/update.ts
+++ b/packages/backend/src/server/api/endpoints/flash/update.ts
@@ -51,7 +51,7 @@ export const paramDef = {
} },
visibility: { type: 'string', enum: ['public', 'private'] },
},
- required: ['flashId', 'title', 'summary', 'script', 'permissions'],
+ required: ['flashId'],
} as const;
@Injectable()
@@ -71,11 +71,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
await this.flashsRepository.update(flash.id, {
updatedAt: new Date(),
- title: ps.title,
- summary: ps.summary,
- script: ps.script,
- permissions: ps.permissions,
- visibility: ps.visibility,
+ ...Object.fromEntries(
+ Object.entries(ps).filter(
+ ([key, val]) => (key !== 'flashId') && Object.hasOwn(paramDef.properties, key)
+ )
+ ),
});
});
}
diff --git a/packages/backend/src/server/api/endpoints/following/create.ts b/packages/backend/src/server/api/endpoints/following/create.ts
index ceaf32ccb2..db320e7129 100644
--- a/packages/backend/src/server/api/endpoints/following/create.ts
+++ b/packages/backend/src/server/api/endpoints/following/create.ts
@@ -71,7 +71,7 @@ export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
- withReplies: { type: 'boolean' }
+ withReplies: { type: 'boolean' },
},
required: ['userId'],
} as const;
@@ -100,22 +100,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw err;
});
- // Check if already following
- const exist = await this.followingsRepository.exists({
- where: {
- followerId: follower.id,
- followeeId: followee.id,
- },
- });
-
- if (exist) {
- throw new ApiError(meta.errors.alreadyFollowing);
- }
-
try {
await this.userFollowingService.follow(follower, followee, { withReplies: ps.withReplies });
} catch (e) {
if (e instanceof IdentifiableError) {
+ if (e.id === 'ec3f65c0-a9d1-47d9-8791-b2e7b9dcdced') throw new ApiError(meta.errors.alreadyFollowing);
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);
}
diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts
index 784ae5088f..b07cdf1ed9 100644
--- a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts
+++ b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts
@@ -12,6 +12,7 @@ import type { MiDriveFile } from '@/models/DriveFile.js';
import { IdService } from '@/core/IdService.js';
import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityService.js';
import { DI } from '@/di-symbols.js';
+import { isNotNull } from '@/misc/is-not-null.js';
export const meta = {
tags: ['gallery'],
@@ -69,7 +70,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
id: fileId,
userId: me.id,
}),
- ))).filter((file): file is MiDriveFile => file != null);
+ ))).filter(isNotNull);
if (files.length === 0) {
throw new Error();
diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts
index 8872b261dd..8bd83ff5ba 100644
--- a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts
+++ b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts
@@ -10,6 +10,7 @@ import type { DriveFilesRepository, GalleryPostsRepository } from '@/models/_.js
import type { MiDriveFile } from '@/models/DriveFile.js';
import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityService.js';
import { DI } from '@/di-symbols.js';
+import { isNotNull } from '@/misc/is-not-null.js';
export const meta = {
tags: ['gallery'],
@@ -67,7 +68,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
id: fileId,
userId: me.id,
}),
- ))).filter((file): file is MiDriveFile => file != null);
+ ))).filter(isNotNull);
if (files.length === 0) {
throw new Error();
diff --git a/packages/backend/src/server/api/endpoints/hashtags/search.ts b/packages/backend/src/server/api/endpoints/hashtags/search.ts
index 12d47fa512..d4eb851054 100644
--- a/packages/backend/src/server/api/endpoints/hashtags/search.ts
+++ b/packages/backend/src/server/api/endpoints/hashtags/search.ts
@@ -43,7 +43,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
super(meta, paramDef, async (ps, me) => {
const hashtags = await this.hashtagsRepository.createQueryBuilder('tag')
.where('tag.name like :q', { q: sqlLikeEscape(ps.query.toLowerCase()) + '%' })
- .orderBy('tag.count', 'DESC')
+ .orderBy('tag.mentionedLocalUsersCount', 'DESC')
.groupBy('tag.id')
.limit(ps.limit)
.offset(ps.offset)
diff --git a/packages/backend/src/server/api/endpoints/i/notifications-grouped.ts b/packages/backend/src/server/api/endpoints/i/notifications-grouped.ts
index 703808d279..dc6ffd3e02 100644
--- a/packages/backend/src/server/api/endpoints/i/notifications-grouped.ts
+++ b/packages/backend/src/server/api/endpoints/i/notifications-grouped.ts
@@ -3,11 +3,11 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { Brackets, In } from 'typeorm';
+import { In } from 'typeorm';
import * as Redis from 'ioredis';
import { Inject, Injectable } from '@nestjs/common';
import type { NotesRepository } from '@/models/_.js';
-import { obsoleteNotificationTypes, notificationTypes, FilterUnionByProperty } from '@/types.js';
+import { obsoleteNotificationTypes, groupedNotificationTypes, FilterUnionByProperty } from '@/types.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { NoteReadService } from '@/core/NoteReadService.js';
import { NotificationEntityService } from '@/core/entities/NotificationEntityService.js';
@@ -48,10 +48,10 @@ export const paramDef = {
markAsRead: { type: 'boolean', default: true },
// 後方互æ›ã®ãŸã‚ã€å»ƒæ­¢ã•れãŸé€šçŸ¥ã‚¿ã‚¤ãƒ—ã‚‚å—ã‘付ã‘ã‚‹
includeTypes: { type: 'array', items: {
- type: 'string', enum: [...notificationTypes, ...obsoleteNotificationTypes],
+ type: 'string', enum: [...groupedNotificationTypes, ...obsoleteNotificationTypes],
} },
excludeTypes: { type: 'array', items: {
- type: 'string', enum: [...notificationTypes, ...obsoleteNotificationTypes],
+ type: 'string', enum: [...groupedNotificationTypes, ...obsoleteNotificationTypes],
} },
},
required: [],
@@ -79,12 +79,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
return [];
}
// excludeTypes ã«å…¨æŒ‡å®šã•れã¦ã„ã‚‹å ´åˆã¯ã‚¯ã‚¨ãƒªã—ãªã„
- if (notificationTypes.every(type => ps.excludeTypes?.includes(type))) {
+ if (groupedNotificationTypes.every(type => ps.excludeTypes?.includes(type))) {
return [];
}
- const includeTypes = ps.includeTypes && ps.includeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][];
- const excludeTypes = ps.excludeTypes && ps.excludeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][];
+ const includeTypes = ps.includeTypes && ps.includeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof groupedNotificationTypes[number][];
+ const excludeTypes = ps.excludeTypes && ps.excludeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof groupedNotificationTypes[number][];
const limit = (ps.limit + EXTRA_LIMIT) + (ps.untilId ? 1 : 0) + (ps.sinceId ? 1 : 0); // untilIdã«æŒ‡å®šã—ãŸã‚‚ã®ã‚‚å«ã¾ã‚Œã‚‹ãŸã‚+1
const notificationsRes = await this.redisClient.xrevrange(
@@ -162,7 +162,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
}
groupedNotifications = groupedNotifications.slice(0, ps.limit);
-
const noteIds = groupedNotifications
.filter((notification): notification is FilterUnionByProperty<MiNotification, 'type', 'mention' | 'reply' | 'quote'> => ['mention', 'reply', 'quote'].includes(notification.type))
.map(notification => notification.noteId!);
diff --git a/packages/backend/src/server/api/endpoints/i/notifications.ts b/packages/backend/src/server/api/endpoints/i/notifications.ts
index 52b6749e3f..320d9fdb00 100644
--- a/packages/backend/src/server/api/endpoints/i/notifications.ts
+++ b/packages/backend/src/server/api/endpoints/i/notifications.ts
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { Brackets, In } from 'typeorm';
+import { In } from 'typeorm';
import * as Redis from 'ioredis';
import { Inject, Injectable } from '@nestjs/common';
import type { NotesRepository } from '@/models/_.js';
diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts
index bf6c53d8eb..84a1931a3d 100644
--- a/packages/backend/src/server/api/endpoints/i/update.ts
+++ b/packages/backend/src/server/api/endpoints/i/update.ts
@@ -456,9 +456,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
this.hashtagService.updateUsertags(user, tags);
//#endregion
- if (Object.keys(updates).length > 0) await this.usersRepository.update(user.id, updates);
- if (Object.keys(updates).includes('alsoKnownAs')) {
- this.cacheService.uriPersonCache.set(this.userEntityService.genLocalUserUri(user.id), { ...user, ...updates });
+ if (Object.keys(updates).length > 0) {
+ await this.usersRepository.update(user.id, updates);
+ this.globalEventService.publishInternalEvent('localUserUpdated', { id: user.id });
}
await this.userProfilesRepository.update(user.id, {
diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts
index 834158baf4..5460635e1d 100644
--- a/packages/backend/src/server/api/endpoints/meta.ts
+++ b/packages/backend/src/server/api/endpoints/meta.ts
@@ -3,18 +3,9 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { IsNull, LessThanOrEqual, MoreThan, Brackets } from 'typeorm';
-import { Inject, Injectable } from '@nestjs/common';
-import JSON5 from 'json5';
-import type { AdsRepository } from '@/models/_.js';
-import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
+import { Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
-import { UserEntityService } from '@/core/entities/UserEntityService.js';
-import { MetaService } from '@/core/MetaService.js';
-import { InstanceActorService } from '@/core/InstanceActorService.js';
-import type { Config } from '@/config.js';
-import { DI } from '@/di-symbols.js';
-import { DEFAULT_POLICIES } from '@/core/RoleService.js';
+import { MetaEntityService } from '@/core/entities/MetaEntityService.js';
export const meta = {
tags: ['meta'],
@@ -23,297 +14,10 @@ export const meta = {
res: {
type: 'object',
- optional: false, nullable: false,
- properties: {
- maintainerName: {
- type: 'string',
- optional: false, nullable: true,
- },
- maintainerEmail: {
- type: 'string',
- optional: false, nullable: true,
- },
- version: {
- type: 'string',
- optional: false, nullable: false,
- },
- providesTarball: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- name: {
- type: 'string',
- optional: false, nullable: false,
- },
- shortName: {
- type: 'string',
- optional: false, nullable: true,
- },
- uri: {
- type: 'string',
- optional: false, nullable: false,
- format: 'url',
- example: 'https://misskey.example.com',
- },
- description: {
- type: 'string',
- optional: false, nullable: true,
- },
- langs: {
- type: 'array',
- optional: false, nullable: false,
- items: {
- type: 'string',
- optional: false, nullable: false,
- },
- },
- tosUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- repositoryUrl: {
- type: 'string',
- optional: false, nullable: true,
- default: 'https://github.com/misskey-dev/misskey',
- },
- feedbackUrl: {
- type: 'string',
- optional: false, nullable: true,
- default: 'https://github.com/misskey-dev/misskey/issues/new',
- },
- defaultDarkTheme: {
- type: 'string',
- optional: false, nullable: true,
- },
- defaultLightTheme: {
- type: 'string',
- optional: false, nullable: true,
- },
- disableRegistration: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- cacheRemoteFiles: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- cacheRemoteSensitiveFiles: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- emailRequiredForSignup: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- enableHcaptcha: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- hcaptchaSiteKey: {
- type: 'string',
- optional: false, nullable: true,
- },
- enableMcaptcha: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- mcaptchaSiteKey: {
- type: 'string',
- optional: false, nullable: true,
- },
- mcaptchaInstanceUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- enableRecaptcha: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- recaptchaSiteKey: {
- type: 'string',
- optional: false, nullable: true,
- },
- enableTurnstile: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- turnstileSiteKey: {
- type: 'string',
- optional: false, nullable: true,
- },
- swPublickey: {
- type: 'string',
- optional: false, nullable: true,
- },
- mascotImageUrl: {
- type: 'string',
- optional: false, nullable: false,
- default: '/assets/ai.png',
- },
- bannerUrl: {
- type: 'string',
- optional: false, nullable: false,
- },
- serverErrorImageUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- infoImageUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- notFoundImageUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- iconUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- maxNoteTextLength: {
- type: 'number',
- optional: false, nullable: false,
- },
- ads: {
- type: 'array',
- optional: false, nullable: false,
- items: {
- type: 'object',
- optional: false, nullable: false,
- properties: {
- id: {
- type: 'string',
- optional: false, nullable: false,
- format: 'id',
- example: 'xxxxxxxxxx',
- },
- url: {
- type: 'string',
- optional: false, nullable: false,
- format: 'url',
- },
- place: {
- type: 'string',
- optional: false, nullable: false,
- },
- ratio: {
- type: 'number',
- optional: false, nullable: false,
- },
- imageUrl: {
- type: 'string',
- optional: false, nullable: false,
- format: 'url',
- },
- dayOfWeek: {
- type: 'integer',
- optional: false, nullable: false,
- },
- },
- },
- },
- notesPerOneAd: {
- type: 'number',
- optional: false, nullable: false,
- default: 0,
- },
- requireSetup: {
- type: 'boolean',
- optional: false, nullable: false,
- example: false,
- },
- enableEmail: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- enableServiceWorker: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- translatorAvailable: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- proxyAccountName: {
- type: 'string',
- optional: false, nullable: true,
- },
- mediaProxy: {
- type: 'string',
- optional: false, nullable: false,
- },
- features: {
- type: 'object',
- optional: true, nullable: false,
- properties: {
- registration: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- localTimeline: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- globalTimeline: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- hcaptcha: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- recaptcha: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- objectStorage: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- serviceWorker: {
- type: 'boolean',
- optional: false, nullable: false,
- },
- miauth: {
- type: 'boolean',
- optional: true, nullable: false,
- default: true,
- },
- },
- },
- backgroundImageUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- impressumUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- logoImageUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- privacyPolicyUrl: {
- type: 'string',
- optional: false, nullable: true,
- },
- serverRules: {
- type: 'array',
- optional: false, nullable: false,
- items: {
- type: 'string',
- },
- },
- themeColor: {
- type: 'string',
- optional: false, nullable: true,
- },
- policies: {
- type: 'object',
- optional: false, nullable: false,
- ref: 'RolePolicies',
- },
- },
+ oneOf: [
+ { type: 'object', ref: 'MetaLite' },
+ { type: 'object', ref: 'MetaDetailed' },
+ ],
},
} as const;
@@ -328,115 +32,10 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
- @Inject(DI.config)
- private config: Config,
-
- @Inject(DI.adsRepository)
- private adsRepository: AdsRepository,
-
- private userEntityService: UserEntityService,
- private metaService: MetaService,
- private instanceActorService: InstanceActorService,
+ private metaEntityService: MetaEntityService,
) {
super(meta, paramDef, async (ps, me) => {
- const instance = await this.metaService.fetch(true);
-
- const ads = await this.adsRepository.createQueryBuilder('ads')
- .where('ads.expiresAt > :now', { now: new Date() })
- .andWhere('ads.startsAt <= :now', { now: new Date() })
- .andWhere(new Brackets(qb => {
- // 曜日ã®ãƒ“ットフラグを確èªã™ã‚‹
- qb.where('ads.dayOfWeek & :dayOfWeek > 0', { dayOfWeek: 1 << new Date().getDay() })
- .orWhere('ads.dayOfWeek = 0');
- }))
- .getMany();
-
- const response: any = {
- maintainerName: instance.maintainerName,
- maintainerEmail: instance.maintainerEmail,
-
- version: this.config.version,
- providesTarball: this.config.publishTarballInsteadOfProvideRepositoryUrl,
-
- name: instance.name,
- shortName: instance.shortName,
- uri: this.config.url,
- description: instance.description,
- langs: instance.langs,
- tosUrl: instance.termsOfServiceUrl,
- repositoryUrl: instance.repositoryUrl,
- feedbackUrl: instance.feedbackUrl,
- impressumUrl: instance.impressumUrl,
- privacyPolicyUrl: instance.privacyPolicyUrl,
- disableRegistration: instance.disableRegistration,
- emailRequiredForSignup: instance.emailRequiredForSignup,
- enableHcaptcha: instance.enableHcaptcha,
- hcaptchaSiteKey: instance.hcaptchaSiteKey,
- enableMcaptcha: instance.enableMcaptcha,
- mcaptchaSiteKey: instance.mcaptchaSitekey,
- mcaptchaInstanceUrl: instance.mcaptchaInstanceUrl,
- enableRecaptcha: instance.enableRecaptcha,
- recaptchaSiteKey: instance.recaptchaSiteKey,
- enableTurnstile: instance.enableTurnstile,
- turnstileSiteKey: instance.turnstileSiteKey,
- swPublickey: instance.swPublicKey,
- themeColor: instance.themeColor,
- mascotImageUrl: instance.mascotImageUrl,
- bannerUrl: instance.bannerUrl,
- infoImageUrl: instance.infoImageUrl,
- serverErrorImageUrl: instance.serverErrorImageUrl,
- notFoundImageUrl: instance.notFoundImageUrl,
- iconUrl: instance.iconUrl,
- backgroundImageUrl: instance.backgroundImageUrl,
- logoImageUrl: instance.logoImageUrl,
- maxNoteTextLength: MAX_NOTE_TEXT_LENGTH,
- // ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã®æ‰‹é–“を減らã™ãŸã‚ã‚らã‹ã˜ã‚JSONã«å¤‰æ›ã—ã¦ãŠã
- defaultLightTheme: instance.defaultLightTheme ? JSON.stringify(JSON5.parse(instance.defaultLightTheme)) : null,
- defaultDarkTheme: instance.defaultDarkTheme ? JSON.stringify(JSON5.parse(instance.defaultDarkTheme)) : null,
- ads: ads.map(ad => ({
- id: ad.id,
- url: ad.url,
- place: ad.place,
- ratio: ad.ratio,
- imageUrl: ad.imageUrl,
- dayOfWeek: ad.dayOfWeek,
- })),
- notesPerOneAd: instance.notesPerOneAd,
- enableEmail: instance.enableEmail,
- enableServiceWorker: instance.enableServiceWorker,
-
- translatorAvailable: instance.deeplAuthKey != null,
-
- serverRules: instance.serverRules,
-
- policies: { ...DEFAULT_POLICIES, ...instance.policies },
-
- mediaProxy: this.config.mediaProxy,
-
- ...(ps.detail ? {
- cacheRemoteFiles: instance.cacheRemoteFiles,
- cacheRemoteSensitiveFiles: instance.cacheRemoteSensitiveFiles,
- requireSetup: !await this.instanceActorService.realLocalUsersPresent(),
- } : {}),
- };
-
- if (ps.detail) {
- const proxyAccount = instance.proxyAccountId ? await this.userEntityService.pack(instance.proxyAccountId).catch(() => null) : null;
-
- response.proxyAccountName = proxyAccount ? proxyAccount.username : null;
- response.features = {
- registration: !instance.disableRegistration,
- emailRequiredForSignup: instance.emailRequiredForSignup,
- hcaptcha: instance.enableHcaptcha,
- recaptcha: instance.enableRecaptcha,
- turnstile: instance.enableTurnstile,
- objectStorage: instance.useObjectStorage,
- serviceWorker: instance.enableServiceWorker,
- miauth: true,
- };
- }
-
- return response;
+ return ps.detail ? await this.metaEntityService.packDetailed() : await this.metaEntityService.pack();
});
}
}
diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts
index e6e4fcc745..bfb9214439 100644
--- a/packages/backend/src/server/api/endpoints/notes/create.ts
+++ b/packages/backend/src/server/api/endpoints/notes/create.ts
@@ -19,6 +19,7 @@ import { DI } from '@/di-symbols.js';
import { isPureRenote } from '@/misc/is-pure-renote.js';
import { MetaService } from '@/core/MetaService.js';
import { UtilityService } from '@/core/UtilityService.js';
+import { IdentifiableError } from '@/misc/identifiable-error.js';
import { ApiError } from '../../error.js';
export const meta = {
@@ -84,6 +85,12 @@ export const meta = {
id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15',
},
+ cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility: {
+ message: 'You cannot reply to a specified visibility note with extended visibility.',
+ code: 'CANNOT_REPLY_TO_SPECIFIED_VISIBILITY_NOTE_WITH_EXTENDED_VISIBILITY',
+ id: 'ed940410-535c-4d5e-bfa3-af798671e93c',
+ },
+
cannotCreateAlreadyExpiredPoll: {
message: 'Poll is already expired.',
code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL',
@@ -119,6 +126,12 @@ export const meta = {
code: 'CONTAINS_PROHIBITED_WORDS',
id: 'aa6e01d3-a85c-669d-758a-76aab43af334',
},
+
+ containsTooManyMentions: {
+ message: 'Cannot post because it exceeds the allowed number of mentions.',
+ code: 'CONTAINS_TOO_MANY_MENTIONS',
+ id: '4de0363a-3046-481b-9b0f-feff3e211025',
+ },
},
} as const;
@@ -312,6 +325,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError(meta.errors.cannotReplyToPureRenote);
} else if (!await this.noteEntityService.isVisibleForMe(reply, me.id)) {
throw new ApiError(meta.errors.cannotReplyToInvisibleNote);
+ } else if (reply.visibility === 'specified' && ps.visibility !== 'specified') {
+ throw new ApiError(meta.errors.cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility);
}
// Check blocking
@@ -376,10 +391,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
};
} catch (e) {
// TODO: ä»–ã®Errorã‚‚ã“ã“ã§ã‚­ãƒ£ãƒƒãƒã—ã¦ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’当ã¦ã‚‹ã‚ˆã†ã«ã—ãŸã„
- if (e instanceof NoteCreateService.ContainsProhibitedWordsError) {
- throw new ApiError(meta.errors.containsProhibitedWords);
+ if (e instanceof IdentifiableError) {
+ if (e.id === '689ee33f-f97c-479a-ac49-1b9f8140af99') {
+ throw new ApiError(meta.errors.containsProhibitedWords);
+ } else if (e.id === '9f466dab-c856-48cd-9e65-ff90ff750580') {
+ throw new ApiError(meta.errors.containsTooManyMentions);
+ }
}
-
throw e;
}
});
diff --git a/packages/backend/src/server/api/endpoints/notifications/flush.ts b/packages/backend/src/server/api/endpoints/notifications/flush.ts
new file mode 100644
index 0000000000..47c0642fd1
--- /dev/null
+++ b/packages/backend/src/server/api/endpoints/notifications/flush.ts
@@ -0,0 +1,33 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { Injectable } from '@nestjs/common';
+import { Endpoint } from '@/server/api/endpoint-base.js';
+import { NotificationService } from '@/core/NotificationService.js';
+
+export const meta = {
+ tags: ['notifications', 'account'],
+
+ requireCredential: true,
+
+ kind: 'write:notifications',
+} as const;
+
+export const paramDef = {
+ type: 'object',
+ properties: {},
+ required: [],
+} as const;
+
+@Injectable()
+export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
+ constructor(
+ private notificationService: NotificationService,
+ ) {
+ super(meta, paramDef, async (ps, me) => {
+ this.notificationService.flushAllNotifications(me.id);
+ });
+ }
+}
diff --git a/packages/backend/src/server/api/endpoints/pinned-users.ts b/packages/backend/src/server/api/endpoints/pinned-users.ts
index 1f4509764f..784766bcb5 100644
--- a/packages/backend/src/server/api/endpoints/pinned-users.ts
+++ b/packages/backend/src/server/api/endpoints/pinned-users.ts
@@ -12,6 +12,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
import { MetaService } from '@/core/MetaService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { DI } from '@/di-symbols.js';
+import { isNotNull } from '@/misc/is-not-null.js';
export const meta = {
tags: ['users'],
@@ -52,7 +53,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
host: acct.host ?? IsNull(),
})));
- return await this.userEntityService.packMany(users.filter(x => x !== null) as MiUser[], me, { schema: 'UserDetailed' });
+ return await this.userEntityService.packMany(users.filter(isNotNull), me, { schema: 'UserDetailed' });
});
}
}
diff --git a/packages/backend/src/server/api/endpoints/sw/register.ts b/packages/backend/src/server/api/endpoints/sw/register.ts
index 06c04b3f9a..a9a33149f9 100644
--- a/packages/backend/src/server/api/endpoints/sw/register.ts
+++ b/packages/backend/src/server/api/endpoints/sw/register.ts
@@ -9,6 +9,7 @@ import type { SwSubscriptionsRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { MetaService } from '@/core/MetaService.js';
import { DI } from '@/di-symbols.js';
+import { PushNotificationService } from '@/core/PushNotificationService.js';
export const meta = {
tags: ['account'],
@@ -66,6 +67,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private idService: IdService,
private metaService: MetaService,
+ private pushNotificationService: PushNotificationService,
) {
super(meta, paramDef, async (ps, me) => {
// if already subscribed
@@ -97,6 +99,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
sendReadMessage: ps.sendReadMessage,
});
+ this.pushNotificationService.refreshCache(me.id);
+
return {
state: 'subscribed' as const,
key: instance.swPublicKey,
diff --git a/packages/backend/src/server/api/endpoints/sw/unregister.ts b/packages/backend/src/server/api/endpoints/sw/unregister.ts
index 2bc91c7278..2edf7fab1b 100644
--- a/packages/backend/src/server/api/endpoints/sw/unregister.ts
+++ b/packages/backend/src/server/api/endpoints/sw/unregister.ts
@@ -7,6 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import type { SwSubscriptionsRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
+import { PushNotificationService } from '@/core/PushNotificationService.js';
export const meta = {
tags: ['account'],
@@ -29,12 +30,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
constructor(
@Inject(DI.swSubscriptionsRepository)
private swSubscriptionsRepository: SwSubscriptionsRepository,
+
+ private pushNotificationService: PushNotificationService,
) {
super(meta, paramDef, async (ps, me) => {
await this.swSubscriptionsRepository.delete({
...(me ? { userId: me.id } : {}),
endpoint: ps.endpoint,
});
+
+ if (me) {
+ this.pushNotificationService.refreshCache(me.id);
+ }
});
}
}
diff --git a/packages/backend/src/server/api/endpoints/sw/update-registration.ts b/packages/backend/src/server/api/endpoints/sw/update-registration.ts
index b56b07fd00..839a07c770 100644
--- a/packages/backend/src/server/api/endpoints/sw/update-registration.ts
+++ b/packages/backend/src/server/api/endpoints/sw/update-registration.ts
@@ -7,6 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import type { SwSubscriptionsRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
+import { PushNotificationService } from '@/core/PushNotificationService.js';
import { ApiError } from '../../error.js';
export const meta = {
@@ -58,6 +59,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
constructor(
@Inject(DI.swSubscriptionsRepository)
private swSubscriptionsRepository: SwSubscriptionsRepository,
+
+ private pushNotificationService: PushNotificationService,
) {
super(meta, paramDef, async (ps, me) => {
const swSubscription = await this.swSubscriptionsRepository.findOneBy({
@@ -77,6 +80,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
sendReadMessage: swSubscription.sendReadMessage,
});
+ this.pushNotificationService.refreshCache(me.id);
+
return {
userId: swSubscription.userId,
endpoint: swSubscription.endpoint,
diff --git a/packages/backend/src/server/api/endpoints/users/reactions.ts b/packages/backend/src/server/api/endpoints/users/reactions.ts
index e20d896248..aca883a052 100644
--- a/packages/backend/src/server/api/endpoints/users/reactions.ts
+++ b/packages/backend/src/server/api/endpoints/users/reactions.ts
@@ -98,7 +98,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
.limit(ps.limit)
.getMany();
- return await Promise.all(reactions.map(reaction => this.noteReactionEntityService.pack(reaction, me, { withNote: true })));
+ return await this.noteReactionEntityService.packMany(reactions, me, { withNote: true });
});
}
}
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 ce9d7f5647..f45bf8622e 100644
--- a/packages/backend/src/server/api/stream/channels/home-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts
@@ -71,7 +71,15 @@ class HomeTimelineChannel extends Channel {
}
}
- if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !this.withRenotes) return;
+ // 純粋ãªãƒªãƒŽãƒ¼ãƒˆï¼ˆå¼•用リノートã§ãªã„リノート)ã®å ´åˆ
+ if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && note.poll == null) {
+ if (!this.withRenotes) return;
+ if (note.renote.reply) {
+ const reply = note.renote.reply;
+ // 自分ã®ãƒ•ォローã—ã¦ã„ãªã„ユーザー㮠visibility: followers ãªæŠ•ç¨¿ã¸ã®è¿”ä¿¡ã®ãƒªãƒŽãƒ¼ãƒˆã¯å¼¾ã
+ if (reply.visibility === 'followers' && !Object.hasOwn(this.following, reply.userId)) return;
+ }
+ }
// æµã‚Œã¦ããŸNoteãŒãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーãŒé–¢ã‚ã‚‹ã‚‚ã®ã ã£ãŸã‚‰ç„¡è¦–ã™ã‚‹
if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts
index f255e28fc2..b1af0c3df6 100644
--- a/packages/backend/src/server/web/ClientServerService.ts
+++ b/packages/backend/src/server/web/ClientServerService.ts
@@ -19,6 +19,7 @@ import fastifyView from '@fastify/view';
import fastifyCookie from '@fastify/cookie';
import fastifyProxy from '@fastify/http-proxy';
import vary from 'vary';
+import htmlSafeJsonStringify from 'htmlescape';
import type { Config } from '@/config.js';
import { getNoteSummary } from '@/misc/get-note-summary.js';
import { DI } from '@/di-symbols.js';
@@ -28,12 +29,12 @@ import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, Obj
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { PageEntityService } from '@/core/entities/PageEntityService.js';
+import { MetaEntityService } from '@/core/entities/MetaEntityService.js';
import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityService.js';
import { ClipEntityService } from '@/core/entities/ClipEntityService.js';
import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js';
import type { ChannelsRepository, ClipsRepository, FlashsRepository, GalleryPostsRepository, MiMeta, NotesRepository, PagesRepository, ReversiGamesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import type Logger from '@/logger.js';
-import { deepClone } from '@/misc/clone.js';
import { handleRequestRedirectToOmitSearch } from '@/misc/fastify-hook-handlers.js';
import { bindThis } from '@/decorators.js';
import { FlashEntityService } from '@/core/entities/FlashEntityService.js';
@@ -93,6 +94,7 @@ export class ClientServerService {
private userEntityService: UserEntityService,
private noteEntityService: NoteEntityService,
private pageEntityService: PageEntityService,
+ private metaEntityService: MetaEntityService,
private galleryPostEntityService: GalleryPostEntityService,
private clipEntityService: ClipEntityService,
private channelEntityService: ChannelEntityService,
@@ -173,7 +175,7 @@ export class ClientServerService {
}
@bindThis
- private generateCommonPugData(meta: MiMeta) {
+ private async generateCommonPugData(meta: MiMeta) {
return {
instanceName: meta.name ?? 'Misskey',
icon: meta.iconUrl,
@@ -183,6 +185,8 @@ export class ClientServerService {
infoImageUrl: meta.infoImageUrl ?? 'https://xn--931a.moe/assets/info.jpg',
notFoundImageUrl: meta.notFoundImageUrl ?? 'https://xn--931a.moe/assets/not-found.jpg',
instanceUrl: this.config.url,
+ metaJson: htmlSafeJsonStringify(await this.metaEntityService.packDetailed(meta)),
+ now: Date.now(),
};
}
@@ -433,7 +437,7 @@ export class ClientServerService {
url: this.config.url,
title: meta.name ?? 'Misskey',
desc: meta.description,
- ...this.generateCommonPugData(meta),
+ ...await this.generateCommonPugData(meta),
});
};
@@ -520,7 +524,7 @@ export class ClientServerService {
user, profile, me,
avatarUrl: user.avatarUrl ?? this.userEntityService.getIdenticonUrl(user),
sub: request.params.sub,
- ...this.generateCommonPugData(meta),
+ ...await this.generateCommonPugData(meta),
});
} else {
// リモートユーザーãªã®ã§
@@ -570,7 +574,7 @@ export class ClientServerService {
avatarUrl: _note.user.avatarUrl,
// TODO: Let locale changeable by instance setting
summary: getNoteSummary(_note),
- ...this.generateCommonPugData(meta),
+ ...await this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
@@ -609,7 +613,7 @@ export class ClientServerService {
page: _page,
profile,
avatarUrl: _page.user.avatarUrl,
- ...this.generateCommonPugData(meta),
+ ...await this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
@@ -635,7 +639,7 @@ export class ClientServerService {
flash: _flash,
profile,
avatarUrl: _flash.user.avatarUrl,
- ...this.generateCommonPugData(meta),
+ ...await this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
@@ -661,7 +665,7 @@ export class ClientServerService {
clip: _clip,
profile,
avatarUrl: _clip.user.avatarUrl,
- ...this.generateCommonPugData(meta),
+ ...await this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
@@ -685,7 +689,7 @@ export class ClientServerService {
post: _post,
profile,
avatarUrl: _post.user.avatarUrl,
- ...this.generateCommonPugData(meta),
+ ...await this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
@@ -704,7 +708,7 @@ export class ClientServerService {
reply.header('Cache-Control', 'public, max-age=15');
return await reply.view('channel', {
channel: _channel,
- ...this.generateCommonPugData(meta),
+ ...await this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
@@ -723,7 +727,7 @@ export class ClientServerService {
reply.header('Cache-Control', 'public, max-age=3600');
return await reply.view('reversi-game', {
game: _game,
- ...this.generateCommonPugData(meta),
+ ...await this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug
index d167afe1e8..123336809b 100644
--- a/packages/backend/src/server/web/views/base.pug
+++ b/packages/backend/src/server/web/views/base.pug
@@ -68,6 +68,9 @@ html
var VERSION = "#{version}";
var CLIENT_ENTRY = "#{clientEntry.file}";
+ script(type='application/json' id='misskey_meta' data-generated-at=now)
+ != metaJson
+
script
include ../boot.js
diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts
index fdcd2c0629..929070d0d2 100644
--- a/packages/backend/src/types.ts
+++ b/packages/backend/src/types.ts
@@ -33,7 +33,15 @@ export const notificationTypes = [
'roleAssigned',
'achievementEarned',
'app',
- 'test'] as const;
+ 'test',
+] as const;
+
+export const groupedNotificationTypes = [
+ ...notificationTypes,
+ 'reaction:grouped',
+ 'renote:grouped',
+] as const;
+
export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const;
export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const;
@@ -69,6 +77,7 @@ export const moderationLogTypes = [
'resetPassword',
'suspendRemoteInstance',
'unsuspendRemoteInstance',
+ 'updateRemoteInstanceNote',
'markSensitiveDriveFile',
'unmarkSensitiveDriveFile',
'resolveAbuseReport',
@@ -209,6 +218,12 @@ export type ModerationLogPayloads = {
id: string;
host: string;
};
+ updateRemoteInstanceNote: {
+ id: string;
+ host: string;
+ before: string | null;
+ after: string | null;
+ };
markSensitiveDriveFile: {
fileId: string;
fileUserId: string | null;
diff --git a/packages/backend/test/e2e/mute.ts b/packages/backend/test/e2e/mute.ts
index e63067cd62..1d28e07b7d 100644
--- a/packages/backend/test/e2e/mute.ts
+++ b/packages/backend/test/e2e/mute.ts
@@ -117,5 +117,185 @@ describe('Mute', () => {
assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
});
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒªãƒ—ライãŒå«ã¾ã‚Œãªã„', async () => {
+ const aliceNote = await post(alice, { text: 'hi' });
+ await post(bob, { text: '@alice hi', replyId: aliceNote.id });
+ await post(carol, { text: '@alice hi', replyId: aliceNote.id });
+
+ const res = await api('/i/notifications', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒªãƒ—ライãŒå«ã¾ã‚Œãªã„', async () => {
+ await post(alice, { text: 'hi' });
+ await post(bob, { text: '@alice hi' });
+ await post(carol, { text: '@alice hi' });
+
+ const res = await api('/i/notifications', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®å¼•用リノートãŒå«ã¾ã‚Œãªã„', async () => {
+ const aliceNote = await post(alice, { text: 'hi' });
+ await post(bob, { text: 'hi', renoteId: aliceNote.id });
+ await post(carol, { text: 'hi', renoteId: aliceNote.id });
+
+ const res = await api('/i/notifications', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒªãƒŽãƒ¼ãƒˆãŒå«ã¾ã‚Œãªã„', async () => {
+ const aliceNote = await post(alice, { text: 'hi' });
+ await post(bob, { renoteId: aliceNote.id });
+ await post(carol, { renoteId: aliceNote.id });
+
+ const res = await api('/i/notifications', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒ•ォロー通知ãŒå«ã¾ã‚Œãªã„', async () => {
+ await api('/i/follow', { userId: alice.id }, bob);
+ await api('/i/follow', { userId: alice.id }, carol);
+
+ const res = await api('/i/notifications', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒ•ォローリクエストãŒå«ã¾ã‚Œãªã„', async () => {
+ await api('/i/update/', { isLocked: true }, alice);
+ await api('/following/create', { userId: alice.id }, bob);
+ await api('/following/create', { userId: alice.id }, carol);
+
+ const res = await api('/i/notifications', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+ });
+
+ describe('Notification (Grouped)', () => {
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã®é€šçŸ¥ãŒå«ã¾ã‚Œãªã„(リアクション)', async () => {
+ const aliceNote = await post(alice, { text: 'hi' });
+ await react(bob, aliceNote, 'like');
+ await react(carol, aliceNote, 'like');
+
+ const res = await api('/i/notifications-grouped', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒªãƒ—ライãŒå«ã¾ã‚Œãªã„', async () => {
+ const aliceNote = await post(alice, { text: 'hi' });
+ await post(bob, { text: '@alice hi', replyId: aliceNote.id });
+ await post(carol, { text: '@alice hi', replyId: aliceNote.id });
+
+ const res = await api('/i/notifications-grouped', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒªãƒ—ライãŒå«ã¾ã‚Œãªã„', async () => {
+ await post(alice, { text: 'hi' });
+ await post(bob, { text: '@alice hi' });
+ await post(carol, { text: '@alice hi' });
+
+ const res = await api('/i/notifications-grouped', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®å¼•用リノートãŒå«ã¾ã‚Œãªã„', async () => {
+ const aliceNote = await post(alice, { text: 'hi' });
+ await post(bob, { text: 'hi', renoteId: aliceNote.id });
+ await post(carol, { text: 'hi', renoteId: aliceNote.id });
+
+ const res = await api('/i/notifications-grouped', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒªãƒŽãƒ¼ãƒˆãŒå«ã¾ã‚Œãªã„', async () => {
+ const aliceNote = await post(alice, { text: 'hi' });
+ await post(bob, { renoteId: aliceNote.id });
+ await post(carol, { renoteId: aliceNote.id });
+
+ const res = await api('/i/notifications-grouped', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒ•ォロー通知ãŒå«ã¾ã‚Œãªã„', async () => {
+ await api('/i/follow', { userId: alice.id }, bob);
+ await api('/i/follow', { userId: alice.id }, carol);
+
+ const res = await api('/i/notifications-grouped', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
+
+ test('通知ã«ãƒŸãƒ¥ãƒ¼ãƒˆã—ã¦ã„るユーザーã‹ã‚‰ã®ãƒ•ォローリクエストãŒå«ã¾ã‚Œãªã„', async () => {
+ await api('/i/update/', { isLocked: true }, alice);
+ await api('/following/create', { userId: alice.id }, bob);
+ await api('/following/create', { userId: alice.id }, carol);
+
+ const res = await api('/i/notifications-grouped', {}, alice);
+
+ assert.strictEqual(res.status, 200);
+ assert.strictEqual(Array.isArray(res.body), true);
+
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
+ assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
+ });
});
});
diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts
index a5742d6e77..2406204f41 100644
--- a/packages/backend/test/e2e/note.ts
+++ b/packages/backend/test/e2e/note.ts
@@ -176,6 +176,87 @@ describe('Note', () => {
assert.strictEqual(deleteRes.status, 204);
});
+ test('visibility: followersãªãƒŽãƒ¼ãƒˆã«å¯¾ã—ã¦ãƒ•ォロワーã¯ãƒªãƒ—ライã§ãã‚‹', async () => {
+ await api('/following/create', {
+ userId: alice.id,
+ }, bob);
+
+ const aliceNote = await api('/notes/create', {
+ text: 'direct note to bob',
+ visibility: 'followers',
+ }, alice);
+
+ assert.strictEqual(aliceNote.status, 200);
+
+ const replyId = aliceNote.body.createdNote.id;
+ const bobReply = await api('/notes/create', {
+ text: 'reply to alice note',
+ replyId,
+ }, bob);
+
+ assert.strictEqual(bobReply.status, 200);
+ assert.strictEqual(bobReply.body.createdNote.replyId, replyId);
+
+ await api('/following/delete', {
+ userId: alice.id,
+ }, bob);
+ });
+
+ test('visibility: followersãªãƒŽãƒ¼ãƒˆã«å¯¾ã—ã¦ãƒ•ォロワーã§ãªã„ユーザーãŒãƒªãƒ—ライã—よã†ã¨ã™ã‚‹ã¨æ€’られる', async () => {
+ const aliceNote = await api('/notes/create', {
+ text: 'direct note to bob',
+ visibility: 'followers',
+ }, alice);
+
+ assert.strictEqual(aliceNote.status, 200);
+
+ const bobReply = await api('/notes/create', {
+ text: 'reply to alice note',
+ replyId: aliceNote.body.createdNote.id,
+ }, bob);
+
+ assert.strictEqual(bobReply.status, 400);
+ assert.strictEqual(bobReply.body.error.code, 'CANNOT_REPLY_TO_AN_INVISIBLE_NOTE');
+ });
+
+ test('visibility: specifiedãªãƒŽãƒ¼ãƒˆã«å¯¾ã—ã¦visibility: specifiedã§è¿”ä¿¡ã§ãã‚‹', async () => {
+ const aliceNote = await api('/notes/create', {
+ text: 'direct note to bob',
+ visibility: 'specified',
+ visibleUserIds: [bob.id],
+ }, alice);
+
+ assert.strictEqual(aliceNote.status, 200);
+
+ const bobReply = await api('/notes/create', {
+ text: 'reply to alice note',
+ replyId: aliceNote.body.createdNote.id,
+ visibility: 'specified',
+ visibleUserIds: [alice.id],
+ }, bob);
+
+ assert.strictEqual(bobReply.status, 200);
+ });
+
+ test('visibility: specifiedãªãƒŽãƒ¼ãƒˆã«å¯¾ã—ã¦visibility: follwersã§è¿”ä¿¡ã—よã†ã¨ã™ã‚‹ã¨æ€’られる', async () => {
+ const aliceNote = await api('/notes/create', {
+ text: 'direct note to bob',
+ visibility: 'specified',
+ visibleUserIds: [bob.id],
+ }, alice);
+
+ assert.strictEqual(aliceNote.status, 200);
+
+ const bobReply = await api('/notes/create', {
+ text: 'reply to alice note with visibility: followers',
+ replyId: aliceNote.body.createdNote.id,
+ visibility: 'followers',
+ }, bob);
+
+ assert.strictEqual(bobReply.status, 400);
+ assert.strictEqual(bobReply.body.error.code, 'CANNOT_REPLY_TO_SPECIFIED_VISIBILITY_NOTE_WITH_EXTENDED_VISIBILITY');
+ });
+
test('文字数ãŽã‚ŠãŽã‚Šã§æ€’られãªã„', async () => {
const post = {
text: '!'.repeat(MAX_NOTE_TEXT_LENGTH), // 3000文字
@@ -680,6 +761,171 @@ describe('Note', () => {
assert.strictEqual(note1.status, 400);
});
+
+ test('ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³ã®æ•°ãŒä¸Šé™ã‚’è¶…ãˆã‚‹ã¨ã‚¨ãƒ©ãƒ¼ã«ãªã‚‹', async () => {
+ const res = await api('admin/roles/create', {
+ name: 'test',
+ description: '',
+ color: null,
+ iconUrl: null,
+ displayOrder: 0,
+ target: 'manual',
+ condFormula: {},
+ isAdministrator: false,
+ isModerator: false,
+ isPublic: false,
+ isExplorable: false,
+ asBadge: false,
+ canEditMembersByModerator: false,
+ policies: {
+ mentionLimit: {
+ useDefault: false,
+ priority: 1,
+ value: 0,
+ },
+ },
+ }, alice);
+
+ assert.strictEqual(res.status, 200);
+
+ await new Promise(x => setTimeout(x, 2));
+
+ const assign = await api('admin/roles/assign', {
+ userId: alice.id,
+ roleId: res.body.id,
+ }, alice);
+
+ assert.strictEqual(assign.status, 204);
+
+ await new Promise(x => setTimeout(x, 2));
+
+ const note = await api('/notes/create', {
+ text: '@bob potentially annoying text',
+ }, alice);
+
+ assert.strictEqual(note.status, 400);
+ assert.strictEqual(note.body.error.code, 'CONTAINS_TOO_MANY_MENTIONS');
+
+ await api('admin/roles/unassign', {
+ userId: alice.id,
+ roleId: res.body.id,
+ });
+
+ await api('admin/roles/delete', {
+ roleId: res.body.id,
+ }, alice);
+ });
+
+ test('ダイレクト投稿もエラーã«ãªã‚‹', async () => {
+ const res = await api('admin/roles/create', {
+ name: 'test',
+ description: '',
+ color: null,
+ iconUrl: null,
+ displayOrder: 0,
+ target: 'manual',
+ condFormula: {},
+ isAdministrator: false,
+ isModerator: false,
+ isPublic: false,
+ isExplorable: false,
+ asBadge: false,
+ canEditMembersByModerator: false,
+ policies: {
+ mentionLimit: {
+ useDefault: false,
+ priority: 1,
+ value: 0,
+ },
+ },
+ }, alice);
+
+ assert.strictEqual(res.status, 200);
+
+ await new Promise(x => setTimeout(x, 2));
+
+ const assign = await api('admin/roles/assign', {
+ userId: alice.id,
+ roleId: res.body.id,
+ }, alice);
+
+ assert.strictEqual(assign.status, 204);
+
+ await new Promise(x => setTimeout(x, 2));
+
+ const note = await api('/notes/create', {
+ text: 'potentially annoying text',
+ visibility: 'specified',
+ visibleUserIds: [ bob.id ],
+ }, alice);
+
+ assert.strictEqual(note.status, 400);
+ assert.strictEqual(note.body.error.code, 'CONTAINS_TOO_MANY_MENTIONS');
+
+ await api('admin/roles/unassign', {
+ userId: alice.id,
+ roleId: res.body.id,
+ });
+
+ await api('admin/roles/delete', {
+ roleId: res.body.id,
+ }, alice);
+ });
+
+ test('ダイレクトã®å®›å…ˆã¨ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³ãŒåŒã˜å ´åˆã¯é‡è¤‡ã—ã¦ã‚«ã‚¦ãƒ³ãƒˆã—ãªã„', async () => {
+ const res = await api('admin/roles/create', {
+ name: 'test',
+ description: '',
+ color: null,
+ iconUrl: null,
+ displayOrder: 0,
+ target: 'manual',
+ condFormula: {},
+ isAdministrator: false,
+ isModerator: false,
+ isPublic: false,
+ isExplorable: false,
+ asBadge: false,
+ canEditMembersByModerator: false,
+ policies: {
+ mentionLimit: {
+ useDefault: false,
+ priority: 1,
+ value: 1,
+ },
+ },
+ }, alice);
+
+ assert.strictEqual(res.status, 200);
+
+ await new Promise(x => setTimeout(x, 2));
+
+ const assign = await api('admin/roles/assign', {
+ userId: alice.id,
+ roleId: res.body.id,
+ }, alice);
+
+ assert.strictEqual(assign.status, 204);
+
+ await new Promise(x => setTimeout(x, 2));
+
+ const note = await api('/notes/create', {
+ text: '@bob potentially annoying text',
+ visibility: 'specified',
+ visibleUserIds: [ bob.id ],
+ }, alice);
+
+ assert.strictEqual(note.status, 200);
+
+ await api('admin/roles/unassign', {
+ userId: alice.id,
+ roleId: res.body.id,
+ });
+
+ await api('admin/roles/delete', {
+ roleId: res.body.id,
+ }, alice);
+ });
});
describe('notes/delete', () => {
diff --git a/packages/backend/test/e2e/streaming.ts b/packages/backend/test/e2e/streaming.ts
index 071daa275f..57ce73ba60 100644
--- a/packages/backend/test/e2e/streaming.ts
+++ b/packages/backend/test/e2e/streaming.ts
@@ -40,9 +40,9 @@ describe('Streaming', () => {
let chinatsu: misskey.entities.SignupResponse;
let takumi: misskey.entities.SignupResponse;
- let kyokoNote: any;
- let kanakoNote: any;
- let takumiNote: any;
+ let kyokoNote: misskey.entities.Note;
+ let kanakoNote: misskey.entities.Note;
+ let takumiNote: misskey.entities.Note;
let list: any;
beforeAll(async () => {
@@ -68,6 +68,9 @@ describe('Streaming', () => {
// Follow: ayano => akari
await follow(ayano, akari);
+ // Follow: kyoko => chitose
+ await api('following/create', { userId: chitose.id }, kyoko);
+
// Mute: chitose => kanako
await api('mute/create', { userId: kanako.id }, chitose);
@@ -170,7 +173,28 @@ describe('Streaming', () => {
*/
test('フォローã—ã¦ã„るユーザーã®ãƒ•ォローã—ã¦ã„ãªã„ユーザー㮠visibility: followers ãªæŠ•ç¨¿ã¸ã®è¿”ä¿¡ãŒæµã‚Œãªã„', async () => {
- // TODO
+ const chitoseNote = await post(chitose, { text: 'followers-only post', visibility: 'followers' });
+
+ const fired = await waitFire(
+ ayano, 'homeTimeline', // ayano:home
+ () => api('notes/create', { text: 'reply to chitose\'s followers-only post', replyId: chitoseNote.id }, kyoko), // kyoko's reply to chitose's followers-only post
+ msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
+ );
+
+ assert.strictEqual(fired, false);
+ });
+
+ test('フォローã—ã¦ã„るユーザーã®ãƒ•ォローã—ã¦ã„ãªã„ユーザー㮠visibility: followers ãªæŠ•ç¨¿ã¸ã®è¿”ä¿¡ã®ãƒªãƒŽãƒ¼ãƒˆãŒæµã‚Œãªã„', async () => {
+ const chitoseNote = await post(chitose, { text: 'followers-only post', visibility: 'followers' });
+ const kyokoReply = await post(kyoko, { text: 'reply to followers-only post', replyId: chitoseNote.id });
+
+ const fired = await waitFire(
+ ayano, 'homeTimeline', // ayano:home
+ () => api('notes/create', { renoteId: kyokoReply.id }, kyoko), // kyoko's renote of kyoko's reply to chitose's followers-only post
+ msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
+ );
+
+ assert.strictEqual(fired, false);
});
test('フォローã—ã¦ã„ãªã„ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®æŠ•ç¨¿ã¯æµã‚Œãªã„', async () => {
@@ -202,6 +226,79 @@ describe('Streaming', () => {
assert.strictEqual(fired, false);
});
+
+ /**
+ * TODO: è½ã¡ã‚‹
+ * @see https://github.com/misskey-dev/misskey/issues/13474
+ test('visibility: specified ãªãƒŽãƒ¼ãƒˆã§ visibleUserIds ã«è‡ªåˆ†ãŒå«ã¾ã‚Œã¦ã„ã‚‹ã¨ããã®ãƒŽãƒ¼ãƒˆã¸ã®ãƒªãƒ—ãƒ©ã‚¤ãŒæµã‚Œã¦ãã‚‹', async () => {
+ const chitoseToKyokoAndAyano = await post(chitose, { text: 'direct note from chitose to kyoko and ayano', visibility: 'specified', visibleUserIds: [kyoko.id, ayano.id] });
+
+ const fired = await waitFire(
+ ayano, 'homeTimeline', // ayano:home
+ () => api('notes/create', { text: 'direct reply from kyoko to chitose and ayano', replyId: chitoseToKyokoAndAyano.id, visibility: 'specified', visibleUserIds: [chitose.id, ayano.id] }, kyoko),
+ msg => msg.type === 'note' && msg.body.userId === kyoko.id,
+ );
+
+ assert.strictEqual(fired, true);
+ });
+ */
+
+ test('visibility: specified ãªæŠ•ç¨¿ã«å¯¾ã™ã‚‹ãƒªãƒ—ライ㧠visibleUserIds ãŒæ‹¡å¼µã•れãŸã¨ãã€ãã®æ‹¡å¼µã•れãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã® HTL ã«ã¯ãã®ãƒªãƒ—ãƒ©ã‚¤ãŒæµã‚Œãªã„', async () => {
+ const chitoseToKyoko = await post(chitose, { text: 'direct note from chitose to kyoko', visibility: 'specified', visibleUserIds: [kyoko.id] });
+
+ const fired = await waitFire(
+ ayano, 'homeTimeline', // ayano:home
+ () => api('notes/create', { text: 'direct reply from kyoko to chitose and ayano', replyId: chitoseToKyoko.id, visibility: 'specified', visibleUserIds: [chitose.id, ayano.id] }, kyoko),
+ msg => msg.type === 'note' && msg.body.userId === kyoko.id,
+ );
+
+ assert.strictEqual(fired, false);
+ });
+
+ test('visibility: specified ãªæŠ•ç¨¿ã«å¯¾ã™ã‚‹ãƒªãƒ—ライ㧠visibleUserIds ãŒåŽç¸®ã•れãŸã¨ãã€ãã®åŽç¸®ã•れãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã® HTL ã«ã¯ãã®ãƒªãƒ—ãƒ©ã‚¤ãŒæµã‚Œãªã„', async () => {
+ const chitoseToKyokoAndAyano = await post(chitose, { text: 'direct note from chitose to kyoko and ayano', visibility: 'specified', visibleUserIds: [kyoko.id, ayano.id] });
+
+ const fired = await waitFire(
+ ayano, 'homeTimeline', // ayano:home
+ () => api('notes/create', { text: 'direct reply from kyoko to chitose', replyId: chitoseToKyokoAndAyano.id, visibility: 'specified', visibleUserIds: [chitose.id] }, kyoko),
+ msg => msg.type === 'note' && msg.body.userId === kyoko.id,
+ );
+
+ assert.strictEqual(fired, false);
+ });
+
+ test('withRenotes: false ã®ã¨ããƒªãƒŽãƒ¼ãƒˆãŒæµã‚Œãªã„', async () => {
+ const fired = await waitFire(
+ ayano, 'homeTimeline', // ayano:home
+ () => api('notes/create', { renoteId: kyokoNote.id }, kyoko), // kyoko renote
+ msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
+ { withRenotes: false },
+ );
+
+ assert.strictEqual(fired, false);
+ });
+
+ test('withRenotes: false ã®ã¨ãå¼•ç”¨ãƒªãƒŽãƒ¼ãƒˆãŒæµã‚Œã‚‹', async () => {
+ const fired = await waitFire(
+ ayano, 'homeTimeline', // ayano:home
+ () => api('notes/create', { text: 'quote', renoteId: kyokoNote.id }, kyoko), // kyoko quote
+ msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
+ { withRenotes: false },
+ );
+
+ assert.strictEqual(fired, true);
+ });
+
+ test('withRenotes: false ã®ã¨ã投票ã®ã¿ã®ãƒªãƒŽãƒ¼ãƒˆãŒæµã‚Œã‚‹', async () => {
+ const fired = await waitFire(
+ ayano, 'homeTimeline', // ayano:home
+ () => api('notes/create', { poll: { choices: ['kinoko', 'takenoko'] }, renoteId: kyokoNote.id }, kyoko), // kyoko renote with poll
+ msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
+ { withRenotes: false },
+ );
+
+ assert.strictEqual(fired, true);
+ });
}); // Home
describe('Local Timeline', () => {
diff --git a/packages/backend/test/unit/ReactionService.ts b/packages/backend/test/unit/ReactionService.ts
index d1c31cac3a..1957f4544c 100644
--- a/packages/backend/test/unit/ReactionService.ts
+++ b/packages/backend/test/unit/ReactionService.ts
@@ -90,4 +90,45 @@ describe('ReactionService', () => {
assert.strictEqual(await reactionService.normalize('unknown'), 'â¤');
});
});
+
+ describe('convertLegacyReactions', () => {
+ test('空ã®å…¥åŠ›ã«å¯¾ã—ã¦ã¯ä½•ã‚‚ã—ãªã„', () => {
+ const input = {};
+ assert.deepStrictEqual(reactionService.convertLegacyReactions(input), input);
+ });
+
+ test('Unicode絵文字リアクションを変æ›ã—ã¦ã—ã¾ã‚ãªã„', () => {
+ const input = { 'ðŸ‘': 1, 'ðŸ®': 2 };
+ assert.deepStrictEqual(reactionService.convertLegacyReactions(input), input);
+ });
+
+ test('カスタム絵文字リアクションを変æ›ã—ã¦ã—ã¾ã‚ãªã„', () => {
+ const input = { ':like@.:': 1, ':pudding@example.tld:': 2 };
+ assert.deepStrictEqual(reactionService.convertLegacyReactions(input), input);
+ });
+
+ test('文字列ã«ã‚ˆã‚‹ãƒ¬ã‚¬ã‚·ãƒ¼ãªãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’変æ›ã™ã‚‹', () => {
+ const input = { 'like': 1, 'pudding': 2 };
+ const output = { 'ðŸ‘': 1, 'ðŸ®': 2 };
+ assert.deepStrictEqual(reactionService.convertLegacyReactions(input), output);
+ });
+
+ test('host部分ãŒçœç•¥ã•れãŸãƒ¬ã‚¬ã‚·ãƒ¼ãªã‚«ã‚¹ã‚¿ãƒ çµµæ–‡å­—リアクションを変æ›ã™ã‚‹', () => {
+ const input = { ':custom_emoji:': 1 };
+ const output = { ':custom_emoji@.:': 1 };
+ assert.deepStrictEqual(reactionService.convertLegacyReactions(input), output);
+ });
+
+ test('「0個ã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã€æƒ…報を削除ã™ã‚‹', () => {
+ const input = { 'angry': 0 };
+ const output = {};
+ assert.deepStrictEqual(reactionService.convertLegacyReactions(input), output);
+ });
+
+ test('hostéƒ¨åˆ†ã®æœ‰ç„¡ã«ã‚ˆã‚Šãƒ‡ã‚³ãƒ¼ãƒ‰ã™ã‚‹ã¨åŒã˜è¡¨è¨˜ã«ãªã‚‹ã‚«ã‚¹ã‚¿ãƒ çµµæ–‡å­—リアクションã®å€‹æ•°æƒ…報を正ã—ãè¶³ã—åˆã‚ã›ã‚‹', () => {
+ const input = { ':custom_emoji:': 1, ':custom_emoji@.:': 2 };
+ const output = { ':custom_emoji@.:': 3 };
+ assert.deepStrictEqual(reactionService.convertLegacyReactions(input), output);
+ });
+ });
});
diff --git a/packages/backend/test/unit/RoleService.ts b/packages/backend/test/unit/RoleService.ts
index 5222745b7f..fe5ad31597 100644
--- a/packages/backend/test/unit/RoleService.ts
+++ b/packages/backend/test/unit/RoleService.ts
@@ -251,6 +251,34 @@ describe('RoleService', () => {
expect(user2Policies.canManageCustomEmojis).toBe(true);
});
+ test('コンディショナルロール: マニュアルロールã«ã‚¢ã‚µã‚¤ãƒ³æ¸ˆã¿', async () => {
+ const [user1, user2, role1] = await Promise.all([
+ createUser(),
+ createUser(),
+ createRole({
+ name: 'manual role',
+ }),
+ ]);
+ const role2 = await createRole({
+ name: 'conditional role',
+ target: 'conditional',
+ condFormula: {
+ // idã¯ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã®ãƒ­ã‚¸ãƒƒã‚¯ã«å¿…è¦ãªã„?
+ id: 'bdc612bd-9d54-4675-ae83-0499c82ea670',
+ type: 'roleAssignedTo',
+ roleId: role1.id,
+ },
+ });
+ await roleService.assign(user2.id, role1.id);
+
+ const [u1role, u2role] = await Promise.all([
+ roleService.getUserRoles(user1.id),
+ roleService.getUserRoles(user2.id),
+ ]);
+ expect(u1role.some(r => r.id === role2.id)).toBe(false);
+ expect(u2role.some(r => r.id === role2.id)).toBe(true);
+ });
+
test('expired role', async () => {
const user = await createUser();
const role = await createRole({
diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts
index a2220ffae6..cd5dddd68d 100644
--- a/packages/backend/test/utils.ts
+++ b/packages/backend/test/utils.ts
@@ -355,7 +355,7 @@ export const uploadUrl = async (user: UserToken, url: string): Promise<Packed<'D
return catcher;
};
-export function connectStream(user: UserToken, channel: string, listener: (message: Record<string, any>) => any, params?: any): Promise<WebSocket> {
+export function connectStream<C extends keyof misskey.Channels>(user: UserToken, channel: C, listener: (message: Record<string, any>) => any, params?: misskey.Channels[C]['params']): Promise<WebSocket> {
return new Promise((res, rej) => {
const url = new URL(`ws://127.0.0.1:${port}/streaming`);
const options: ClientOptions = {};
@@ -390,7 +390,7 @@ export function connectStream(user: UserToken, channel: string, listener: (messa
});
}
-export const waitFire = async (user: UserToken, channel: string, trgr: () => any, cond: (msg: Record<string, any>) => boolean, params?: any) => {
+export const waitFire = async <C extends keyof misskey.Channels>(user: UserToken, channel: C, trgr: () => any, cond: (msg: Record<string, any>) => boolean, params?: misskey.Channels[C]['params']) => {
return new Promise<boolean>(async (res, rej) => {
let timer: NodeJS.Timeout | null = null;
@@ -435,7 +435,7 @@ export const waitFire = async (user: UserToken, channel: string, trgr: () => any
*/
export function makeStreamCatcher<T>(
user: UserToken,
- channel: string,
+ channel: keyof misskey.Channels,
cond: (message: Record<string, any>) => boolean,
extractor: (message: Record<string, any>) => T,
timeout = 60 * 1000): Promise<T> {
diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx
index 76c5b6be4b..1e925aede6 100644
--- a/packages/frontend/.storybook/generate.tsx
+++ b/packages/frontend/.storybook/generate.tsx
@@ -401,7 +401,8 @@ function toStories(component: string): Promise<string> {
// glob('src/{components,pages,ui,widgets}/**/*.vue')
(async () => {
const globs = await Promise.all([
- glob('src/components/global/*.vue'),
+ glob('src/components/global/Mk*.vue'),
+ glob('src/components/global/RouterView.vue'),
glob('src/components/Mk{A,B}*.vue'),
glob('src/components/MkDigitalClock.vue'),
glob('src/components/MkGalleryPostPreview.vue'),
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index 91a391ac08..682def8e8d 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -27,19 +27,19 @@
"@syuilo/aiscript": "0.17.0",
"@tabler/icons-webfont": "2.44.0",
"@twemoji/parser": "15.0.0",
- "@vitejs/plugin-vue": "5.0.3",
- "@vue/compiler-sfc": "3.4.18",
+ "@vitejs/plugin-vue": "5.0.4",
+ "@vue/compiler-sfc": "3.4.21",
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.2",
"astring": "1.8.6",
"broadcast-channel": "7.0.0",
"buraha": "0.0.1",
- "canvas-confetti": "1.6.1",
- "chart.js": "4.4.1",
+ "canvas-confetti": "1.9.2",
+ "chart.js": "4.4.2",
"chartjs-adapter-date-fns": "3.0.0",
"chartjs-chart-matrix": "2.0.1",
"chartjs-plugin-gradient": "0.6.1",
"chartjs-plugin-zoom": "2.0.1",
- "chromatic": "10.6.1",
+ "chromatic": "11.0.0",
"compare-versions": "6.1.0",
"cropperjs": "2.0.0-beta.4",
"date-fns": "2.30.0",
@@ -57,79 +57,79 @@
"misskey-reversi": "workspace:*",
"photoswipe": "5.4.3",
"punycode": "2.3.1",
- "rollup": "4.9.6",
- "sanitize-html": "2.11.0",
- "sass": "1.70.0",
- "shiki": "1.0.0-beta.3",
+ "rollup": "4.12.0",
+ "sanitize-html": "2.12.1",
+ "sass": "1.71.1",
+ "shiki": "1.1.7",
"strict-event-emitter-types": "2.0.0",
"textarea-caret": "3.1.0",
- "three": "0.160.1",
+ "three": "0.162.0",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tsc-alias": "1.8.8",
"tsconfig-paths": "4.2.0",
"typescript": "5.3.3",
"uuid": "9.0.1",
- "v-code-diff": "1.7.2",
- "vite": "5.1.0",
- "vue": "3.4.18",
+ "v-code-diff": "1.9.0",
+ "vite": "5.1.4",
+ "vue": "3.4.21",
"vuedraggable": "next"
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "1.0.0",
"@misskey-dev/summaly": "5.0.3",
- "@storybook/addon-actions": "8.0.0-beta.2",
- "@storybook/addon-essentials": "8.0.0-beta.2",
- "@storybook/addon-interactions": "8.0.0-beta.2",
- "@storybook/addon-links": "8.0.0-beta.2",
- "@storybook/addon-mdx-gfm": "8.0.0-beta.2",
- "@storybook/addon-storysource": "8.0.0-beta.2",
- "@storybook/blocks": "8.0.0-beta.2",
- "@storybook/components": "8.0.0-beta.2",
- "@storybook/core-events": "8.0.0-beta.2",
- "@storybook/manager-api": "8.0.0-beta.2",
- "@storybook/preview-api": "8.0.0-beta.2",
- "@storybook/react": "8.0.0-beta.2",
- "@storybook/react-vite": "8.0.0-beta.2",
- "@storybook/test": "8.0.0-beta.2",
- "@storybook/theming": "8.0.0-beta.2",
- "@storybook/types": "8.0.0-beta.2",
- "@storybook/vue3": "8.0.0-beta.2",
- "@storybook/vue3-vite": "8.0.0-beta.2",
+ "@storybook/addon-actions": "8.0.0-beta.6",
+ "@storybook/addon-essentials": "8.0.0-beta.6",
+ "@storybook/addon-interactions": "8.0.0-beta.6",
+ "@storybook/addon-links": "8.0.0-beta.6",
+ "@storybook/addon-mdx-gfm": "8.0.0-beta.6",
+ "@storybook/addon-storysource": "8.0.0-beta.6",
+ "@storybook/blocks": "8.0.0-beta.6",
+ "@storybook/components": "8.0.0-beta.6",
+ "@storybook/core-events": "8.0.0-beta.6",
+ "@storybook/manager-api": "8.0.0-beta.6",
+ "@storybook/preview-api": "8.0.0-beta.6",
+ "@storybook/react": "8.0.0-beta.6",
+ "@storybook/react-vite": "8.0.0-beta.6",
+ "@storybook/test": "8.0.0-beta.6",
+ "@storybook/theming": "8.0.0-beta.6",
+ "@storybook/types": "8.0.0-beta.6",
+ "@storybook/vue3": "8.0.0-beta.6",
+ "@storybook/vue3-vite": "8.0.0-beta.6",
"@testing-library/vue": "8.0.2",
"@types/escape-regexp": "0.0.3",
"@types/estree": "1.0.5",
"@types/matter-js": "0.19.6",
"@types/micromatch": "4.0.6",
- "@types/node": "20.11.17",
- "@types/punycode": "2.1.3",
- "@types/sanitize-html": "2.9.5",
+ "@types/node": "20.11.22",
+ "@types/punycode": "2.1.4",
+ "@types/sanitize-html": "2.11.0",
"@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6",
"@types/uuid": "9.0.8",
"@types/ws": "8.5.10",
- "@typescript-eslint/eslint-plugin": "6.18.1",
- "@typescript-eslint/parser": "6.18.1",
+ "@typescript-eslint/eslint-plugin": "7.1.0",
+ "@typescript-eslint/parser": "7.1.0",
"@vitest/coverage-v8": "0.34.6",
- "@vue/runtime-core": "3.4.18",
+ "@vue/runtime-core": "3.4.21",
"acorn": "8.11.3",
"cross-env": "7.0.3",
- "cypress": "13.6.4",
- "eslint": "8.56.0",
+ "cypress": "13.6.6",
+ "eslint": "8.57.0",
"eslint-plugin-import": "2.29.1",
- "eslint-plugin-vue": "9.20.1",
+ "eslint-plugin-vue": "9.22.0",
"fast-glob": "3.3.2",
- "happy-dom": "10.0.3",
+ "happy-dom": "13.6.2",
"intersection-observer": "0.12.2",
"micromatch": "4.0.5",
"msw": "2.1.7",
"msw-storybook-addon": "2.0.0-beta.1",
- "nodemon": "3.0.3",
+ "nodemon": "3.1.0",
"prettier": "3.2.5",
"react": "18.2.0",
"react-dom": "18.2.0",
"start-server-and-test": "2.0.3",
- "storybook": "8.0.0-beta.2",
+ "storybook": "8.0.0-beta.6",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
"vite-plugin-turbosnap": "1.0.3",
"vitest": "0.34.6",
diff --git a/packages/frontend/src/account.ts b/packages/frontend/src/account.ts
index e606fe368c..7f20e0b1a2 100644
--- a/packages/frontend/src/account.ts
+++ b/packages/frontend/src/account.ts
@@ -290,7 +290,7 @@ export async function openAccountMenu(opts: {
text: i18n.ts.profile,
to: `/@${ $i.username }`,
avatar: $i,
- }, { type: 'divider' }, ...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises, {
+ }, { type: 'divider' as const }, ...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises, {
type: 'parent' as const,
icon: 'ti ti-plus',
text: i18n.ts.addAccount,
diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts
index b19d45a35e..61f04678bf 100644
--- a/packages/frontend/src/boot/main-boot.ts
+++ b/packages/frontend/src/boot/main-boot.ts
@@ -11,7 +11,7 @@ import { alert, confirm, popup, post, toast } from '@/os.js';
import { useStream } from '@/stream.js';
import * as sound from '@/scripts/sound.js';
import { $i, signout, updateAccount } from '@/account.js';
-import { fetchInstance, instance } from '@/instance.js';
+import { instance } from '@/instance.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { makeHotkey } from '@/scripts/hotkey.js';
import { reactionPicker } from '@/scripts/reaction-picker.js';
@@ -235,12 +235,10 @@ export async function mainBoot() {
}
}
- fetchInstance().then(() => {
- const modifiedVersionMustProminentlyOfferInAgplV3Section13Read = miLocalStorage.getItem('modifiedVersionMustProminentlyOfferInAgplV3Section13Read');
- if (modifiedVersionMustProminentlyOfferInAgplV3Section13Read !== 'true' && instance.repositoryUrl !== 'https://github.com/misskey-dev/misskey') {
- popup(defineAsyncComponent(() => import('@/components/MkSourceCodeAvailablePopup.vue')), {}, {}, 'closed');
- }
- });
+ const modifiedVersionMustProminentlyOfferInAgplV3Section13Read = miLocalStorage.getItem('modifiedVersionMustProminentlyOfferInAgplV3Section13Read');
+ if (modifiedVersionMustProminentlyOfferInAgplV3Section13Read !== 'true' && instance.repositoryUrl !== 'https://github.com/misskey-dev/misskey') {
+ popup(defineAsyncComponent(() => import('@/components/MkSourceCodeAvailablePopup.vue')), {}, {}, 'closed');
+ }
if ('Notification' in window) {
// 許å¯ã‚’å¾—ã¦ã„ãªã‹ã£ãŸã‚‰ãƒªã‚¯ã‚¨ã‚¹ãƒˆ
diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue
index 412325bfee..cae6bc7111 100644
--- a/packages/frontend/src/components/MkAutocomplete.vue
+++ b/packages/frontend/src/components/MkAutocomplete.vue
@@ -57,18 +57,7 @@ import { i18n } from '@/i18n.js';
import { miLocalStorage } from '@/local-storage.js';
import { customEmojis } from '@/custom-emojis.js';
import { MFM_TAGS, MFM_PARAMS } from '@/const.js';
-
-type EmojiDef = {
- emoji: string;
- name: string;
- url: string;
- aliasOf?: string;
-} | {
- emoji: string;
- name: string;
- aliasOf?: string;
- isCustomEmoji?: true;
-};
+import { searchEmoji, EmojiDef } from '@/scripts/search-emoji.js';
const lib = emojilist.filter(x => x.category !== 'flags');
@@ -249,7 +238,7 @@ function exec() {
return;
}
- emojis.value = emojiAutoComplete(props.q, emojiDb.value);
+ emojis.value = searchEmoji(props.q, emojiDb.value);
} else if (props.type === 'mfmTag') {
if (!props.q || props.q === '') {
mfmTags.value = MFM_TAGS;
@@ -267,87 +256,6 @@ function exec() {
}
}
-type EmojiScore = { emoji: EmojiDef, score: number };
-
-function emojiAutoComplete(query: string | null, emojiDb: EmojiDef[], max = 30): EmojiDef[] {
- if (!query) {
- return [];
- }
-
- const matched = new Map<string, EmojiScore>();
- // 完全一致(エイリアス込ã¿ï¼‰
- emojiDb.some(x => {
- if (x.name === query && !matched.has(x.aliasOf ?? x.name)) {
- matched.set(x.aliasOf ?? x.name, { emoji: x, score: query.length + 2 });
- }
- return matched.size === max;
- });
-
- // 剿–¹ä¸€è‡´ï¼ˆã‚¨ã‚¤ãƒªã‚¢ã‚¹ãªã—)
- if (matched.size < max) {
- emojiDb.some(x => {
- if (x.name.startsWith(query) && !x.aliasOf) {
- matched.set(x.name, { emoji: x, score: query.length + 1 });
- }
- return matched.size === max;
- });
- }
-
- // 剿–¹ä¸€è‡´ï¼ˆã‚¨ã‚¤ãƒªã‚¢ã‚¹è¾¼ã¿ï¼‰
- if (matched.size < max) {
- emojiDb.some(x => {
- if (x.name.startsWith(query) && !matched.has(x.aliasOf ?? x.name)) {
- matched.set(x.aliasOf ?? x.name, { emoji: x, score: query.length });
- }
- return matched.size === max;
- });
- }
-
- // 部分一致(エイリアス込ã¿ï¼‰
- if (matched.size < max) {
- emojiDb.some(x => {
- if (x.name.includes(query) && !matched.has(x.aliasOf ?? x.name)) {
- matched.set(x.aliasOf ?? x.name, { emoji: x, score: query.length - 1 });
- }
- return matched.size === max;
- });
- }
-
- // 簡易ã‚ã„ã¾ã„検索(3文字以上)
- if (matched.size < max && query.length > 3) {
- const queryChars = [...query];
- const hitEmojis = new Map<string, EmojiScore>();
-
- for (const x of emojiDb) {
- // 文字列ã®ä½ç½®ã‚’進ã‚ãªãŒã‚‰ã€ã‚¯ã‚¨ãƒªã®æ–‡å­—ã‚’é †ç•ªã«æŽ¢ã™
-
- let pos = 0;
- let hit = 0;
- for (const c of queryChars) {
- pos = x.name.indexOf(c, pos);
- if (pos <= -1) break;
- hit++;
- }
-
- // åŠåˆ†ä»¥ä¸Šã®æ–‡å­—ãŒå«ã¾ã‚Œã¦ã„れã°ãƒ’ットã¨ã™ã‚‹
- if (hit > Math.ceil(queryChars.length / 2) && hit - 2 > (matched.get(x.aliasOf ?? x.name)?.score ?? 0)) {
- hitEmojis.set(x.aliasOf ?? x.name, { emoji: x, score: hit - 2 });
- }
- }
-
- // ヒットã—ãŸã‚‚ã®ã‚’全部追加ã™ã‚‹ã¨é›‘多ã«ãªã‚‹ã®ã§ã€å…ˆé ­ã®6件程度ã ã‘ã«ã—ã¦ãŠã(6ä»¶ï¼ã‚ªãƒ¼ãƒˆã‚³ãƒ³ãƒ—リートã®ãƒãƒƒãƒ—アップã®ã‚µã‚¤ã‚ºåˆ†ï¼‰
- [...hitEmojis.values()]
- .sort((x, y) => y.score - x.score)
- .slice(0, 6)
- .forEach(it => matched.set(it.emoji.name, it));
- }
-
- return [...matched.values()]
- .sort((x, y) => y.score - x.score)
- .slice(0, max)
- .map(it => it.emoji);
-}
-
function onMousedown(event: Event) {
if (!contains(rootEl.value, event.target) && (rootEl.value !== event.target)) props.close();
}
diff --git a/packages/frontend/src/components/MkChart.vue b/packages/frontend/src/components/MkChart.vue
index dd745c2140..04b6d2f29c 100644
--- a/packages/frontend/src/components/MkChart.vue
+++ b/packages/frontend/src/components/MkChart.vue
@@ -240,7 +240,7 @@ const render = () => {
},
external: externalTooltipHandler,
callbacks: {
- label: (item) => chartData?.bytes ? bytes(item.parsed.y * 1000, 1) : item.parsed.y.toString(),
+ label: (item) => `${item.dataset.label}: ${chartData?.bytes ? bytes(item.parsed.y * 1000, 1) : item.parsed.y.toString()}`,
},
},
zoom: props.detailed ? {
diff --git a/packages/frontend/src/components/MkCode.core.vue b/packages/frontend/src/components/MkCode.core.vue
index f993e983e4..872517b6aa 100644
--- a/packages/frontend/src/components/MkCode.core.vue
+++ b/packages/frontend/src/components/MkCode.core.vue
@@ -52,7 +52,7 @@ async function fetchLanguage(to: string): Promise<void> {
return bundle.id === language || bundle.aliases?.includes(language);
});
if (bundles.length > 0) {
- console.log(`Loading language: ${language}`);
+ if (_DEV_) console.log(`Loading language: ${language}`);
await highlighter.loadLanguage(bundles[0].import);
codeLang.value = language;
} else {
diff --git a/packages/frontend/src/components/MkDialog.vue b/packages/frontend/src/components/MkDialog.vue
index 4b7584faaa..4577d37c08 100644
--- a/packages/frontend/src/components/MkDialog.vue
+++ b/packages/frontend/src/components/MkDialog.vue
@@ -38,11 +38,6 @@ SPDX-License-Identifier: AGPL-3.0-only
<template v-if="select.items">
<option v-for="item in select.items" :value="item.value">{{ item.text }}</option>
</template>
- <template v-else>
- <optgroup v-for="groupedItem in select.groupedItems" :label="groupedItem.label">
- <option v-for="item in groupedItem.items" :value="item.value">{{ item.text }}</option>
- </optgroup>
- </template>
</MkSelect>
<div v-if="(showOkButton || showCancelButton) && !actions" :class="$style.buttons">
<MkButton v-if="showOkButton" data-cy-modal-dialog-ok inline primary rounded :autofocus="!input && !select" :disabled="okButtonDisabledReason" @click="ok">{{ okText ?? ((showCancelButton || input || select) ? i18n.ts.ok : i18n.ts.gotIt) }}</MkButton>
@@ -64,7 +59,7 @@ import MkSelect from '@/components/MkSelect.vue';
import { i18n } from '@/i18n.js';
type Input = {
- type: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time' | 'search' | 'datetime-local';
+ type?: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time' | 'search' | 'datetime-local';
placeholder?: string | null;
autocomplete?: string;
default: string | number | null;
@@ -74,22 +69,17 @@ type Input = {
type Select = {
items: {
- value: string;
+ value: any;
text: string;
}[];
- groupedItems: {
- label: string;
- items: {
- value: string;
- text: string;
- }[];
- }[];
default: string | null;
};
+type Result = string | number | true | null;
+
const props = withDefaults(defineProps<{
type?: 'success' | 'error' | 'warning' | 'info' | 'question' | 'waiting';
- title: string;
+ title?: string;
text?: string;
input?: Input;
select?: Select;
@@ -113,7 +103,7 @@ const props = withDefaults(defineProps<{
});
const emit = defineEmits<{
- (ev: 'done', v: { canceled: boolean; result: any }): void;
+ (ev: 'done', v: { canceled: true } | { canceled: false, result: Result }): void;
(ev: 'closed'): void;
}>();
@@ -139,8 +129,11 @@ const okButtonDisabledReason = computed<null | 'charactersExceeded' | 'character
return null;
});
-function done(canceled: boolean, result?) {
- emit('done', { canceled, result });
+// overload function を使ã„ãŸã„ã®ã§ lint エラーを無視ã™ã‚‹
+function done(canceled: true): void;
+function done(canceled: false, result: Result): void; // eslint-disable-line no-redeclare
+function done(canceled: boolean, result?: Result): void { // eslint-disable-line no-redeclare
+ emit('done', { canceled, result } as { canceled: true } | { canceled: false, result: Result });
modal.value?.close();
}
diff --git a/packages/frontend/src/components/MkDriveSelectDialog.vue b/packages/frontend/src/components/MkDriveSelectDialog.vue
index 77b5532f79..f1ecc27123 100644
--- a/packages/frontend/src/components/MkDriveSelectDialog.vue
+++ b/packages/frontend/src/components/MkDriveSelectDialog.vue
@@ -39,13 +39,13 @@ withDefaults(defineProps<{
});
const emit = defineEmits<{
- (ev: 'done', r?: Misskey.entities.DriveFile[]): void;
+ (ev: 'done', r?: Misskey.entities.DriveFile[] | Misskey.entities.DriveFolder[]): void;
(ev: 'closed'): void;
}>();
const dialog = shallowRef<InstanceType<typeof MkModalWindow>>();
-const selected = ref<Misskey.entities.DriveFile[]>([]);
+const selected = ref<Misskey.entities.DriveFile[] | Misskey.entities.DriveFolder[]>([]);
function ok() {
emit('done', selected.value);
@@ -57,7 +57,7 @@ function cancel() {
dialog.value?.close();
}
-function onChangeSelection(files: Misskey.entities.DriveFile[]) {
- selected.value = files;
+function onChangeSelection(v: Misskey.entities.DriveFile[] | Misskey.entities.DriveFolder[]) {
+ selected.value = v;
}
</script>
diff --git a/packages/frontend/src/components/MkEmojiPicker.section.vue b/packages/frontend/src/components/MkEmojiPicker.section.vue
index 30ad2bcbbf..c295ab6bb7 100644
--- a/packages/frontend/src/components/MkEmojiPicker.section.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.section.vue
@@ -16,6 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:key="emoji"
:data-emoji="emoji"
class="_button item"
+ :disabled="disabledEmojis?.value.includes(emoji)"
@pointerenter="computeButtonTitle"
@click="emit('chosen', emoji, $event)"
>
@@ -48,6 +49,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:key="emoji"
:data-emoji="emoji"
class="_button item"
+ :disabled="disabledEmojis?.value.includes(emoji)"
@pointerenter="computeButtonTitle"
@click="emit('chosen', emoji, $event)"
>
@@ -67,6 +69,7 @@ import MkEmojiPickerSection from '@/components/MkEmojiPicker.section.vue';
const props = defineProps<{
emojis: string[] | Ref<string[]>;
+ disabledEmojis?: Ref<string[]>;
initialShown?: boolean;
hasChildSection?: boolean;
customEmojiTree?: CustomEmojiFolderTree[];
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue
index 366273118b..06243e5b04 100644
--- a/packages/frontend/src/components/MkEmojiPicker.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.vue
@@ -14,6 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
v-for="emoji in searchResultCustom"
:key="emoji.name"
class="_button item"
+ :disabled="!canReact(emoji)"
:title="emoji.name"
tabindex="0"
@click="chosen(emoji, $event)"
@@ -39,16 +40,17 @@ SPDX-License-Identifier: AGPL-3.0-only
<section v-if="showPinned && (pinned && pinned.length > 0)">
<div class="body">
<button
- v-for="emoji in pinned"
- :key="emoji"
- :data-emoji="emoji"
+ v-for="emoji in pinnedEmojisDef"
+ :key="getKey(emoji)"
+ :data-emoji="getKey(emoji)"
class="_button item"
+ :disabled="!canReact(emoji)"
tabindex="0"
@pointerenter="computeButtonTitle"
@click="chosen(emoji, $event)"
>
- <MkCustomEmoji v-if="emoji[0] === ':'" class="emoji" :name="emoji" :normal="true"/>
- <MkEmoji v-else class="emoji" :emoji="emoji" :normal="true"/>
+ <MkCustomEmoji v-if="!emoji.hasOwnProperty('char')" class="emoji" :name="getKey(emoji)" :normal="true"/>
+ <MkEmoji v-else class="emoji" :emoji="getKey(emoji)" :normal="true"/>
</button>
</div>
</section>
@@ -57,15 +59,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<header class="_acrylic"><i class="ti ti-clock ti-fw"></i> {{ i18n.ts.recentUsed }}</header>
<div class="body">
<button
- v-for="emoji in recentlyUsedEmojis"
- :key="emoji"
+ v-for="emoji in recentlyUsedEmojisDef"
+ :key="getKey(emoji)"
class="_button item"
- :data-emoji="emoji"
+ :disabled="!canReact(emoji)"
+ :data-emoji="getKey(emoji)"
@pointerenter="computeButtonTitle"
@click="chosen(emoji, $event)"
>
- <MkCustomEmoji v-if="emoji[0] === ':'" class="emoji" :name="emoji" :normal="true"/>
- <MkEmoji v-else class="emoji" :emoji="emoji" :normal="true"/>
+ <MkCustomEmoji v-if="!emoji.hasOwnProperty('char')" class="emoji" :name="getKey(emoji)" :normal="true"/>
+ <MkEmoji v-else class="emoji" :emoji="getKey(emoji)" :normal="true"/>
</button>
</div>
</section>
@@ -76,7 +79,8 @@ SPDX-License-Identifier: AGPL-3.0-only
v-for="child in customEmojiFolderRoot.children"
:key="`custom:${child.value}`"
:initialShown="false"
- :emojis="computed(() => customEmojis.filter(e => child.value === '' ? (e.category === 'null' || !e.category) : e.category === child.value).filter(filterAvailable).map(e => `:${e.name}:`))"
+ :emojis="computed(() => customEmojis.filter(e => filterCategory(e, child.value)).map(e => `:${e.name}:`))"
+ :disabledEmojis="computed(() => customEmojis.filter(e => filterCategory(e, child.value)).filter(e => !canReact(e)).map(e => `:${e.name}:`))"
:hasChildSection="child.children.length !== 0"
:customEmojiTree="child.children"
@chosen="chosen"
@@ -109,6 +113,7 @@ import {
unicodeEmojiCategories as categories,
getEmojiName,
CustomEmojiFolderTree,
+ getUnicodeEmoji,
} from '@/scripts/emojilist.js';
import MkRippleEffect from '@/components/MkRippleEffect.vue';
import * as os from '@/os.js';
@@ -146,6 +151,13 @@ const {
recentlyUsedEmojis,
} = defaultStore.reactiveState;
+const recentlyUsedEmojisDef = computed(() => {
+ return recentlyUsedEmojis.value.map(getDef);
+});
+const pinnedEmojisDef = computed(() => {
+ return pinned.value?.map(getDef);
+});
+
const pinned = computed(() => props.pinnedEmojis);
const size = computed(() => emojiPickerScale.value);
const width = computed(() => emojiPickerWidth.value);
@@ -337,14 +349,18 @@ watch(q, () => {
return matches;
};
- searchResultCustom.value = Array.from(searchCustom()).filter(filterAvailable);
+ searchResultCustom.value = Array.from(searchCustom());
searchResultUnicode.value = Array.from(searchUnicode());
});
-function filterAvailable(emoji: Misskey.entities.EmojiSimple): boolean {
+function canReact(emoji: Misskey.entities.EmojiSimple | UnicodeEmojiDef): boolean {
return !props.targetNote || checkReactionPermissions($i!, props.targetNote, emoji);
}
+function filterCategory(emoji: Misskey.entities.EmojiSimple, category: string): boolean {
+ return category === '' ? (emoji.category === 'null' || !emoji.category) : emoji.category === category;
+}
+
function focus() {
if (!['smartphone', 'tablet'].includes(deviceKind) && !isTouchUsing) {
searchEl.value?.focus({
@@ -362,6 +378,14 @@ function getKey(emoji: string | Misskey.entities.EmojiSimple | UnicodeEmojiDef):
return typeof emoji === 'string' ? emoji : 'char' in emoji ? emoji.char : `:${emoji.name}:`;
}
+function getDef(emoji: string) {
+ if (emoji.includes(':')) {
+ return customEmojisMap.get(emoji.replace(/:/g, ''))!;
+ } else {
+ return getUnicodeEmoji(emoji)!;
+ }
+}
+
/** @see MkEmojiPicker.section.vue */
function computeButtonTitle(ev: MouseEvent): void {
const elm = ev.target as HTMLElement;
@@ -526,6 +550,18 @@ defineExpose({
width: auto;
height: auto;
min-width: 0;
+
+ &:disabled {
+ cursor: not-allowed;
+ background: linear-gradient(-45deg, transparent 0% 48%, var(--X6) 48% 52%, transparent 52% 100%);
+ opacity: 1;
+
+ > .emoji {
+ filter: grayscale(1);
+ mix-blend-mode: exclusion;
+ opacity: 0.8;
+ }
+ }
}
}
}
@@ -548,6 +584,18 @@ defineExpose({
width: auto;
height: auto;
min-width: 0;
+
+ &:disabled {
+ cursor: not-allowed;
+ background: linear-gradient(-45deg, transparent 0% 48%, var(--X6) 48% 52%, transparent 52% 100%);
+ opacity: 1;
+
+ > .emoji {
+ filter: grayscale(1);
+ mix-blend-mode: exclusion;
+ opacity: 0.8;
+ }
+ }
}
}
}
@@ -663,6 +711,18 @@ defineExpose({
box-shadow: inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15);
}
+ &:disabled {
+ cursor: not-allowed;
+ background: linear-gradient(-45deg, transparent 0% 48%, var(--X6) 48% 52%, transparent 52% 100%);
+ opacity: 1;
+
+ > .emoji {
+ filter: grayscale(1);
+ mix-blend-mode: exclusion;
+ opacity: 0.8;
+ }
+ }
+
> .emoji {
height: 1.25em;
vertical-align: -.25em;
diff --git a/packages/frontend/src/components/MkEmojiPickerDialog.vue b/packages/frontend/src/components/MkEmojiPickerDialog.vue
index 59f4b51522..adcea839ee 100644
--- a/packages/frontend/src/components/MkEmojiPickerDialog.vue
+++ b/packages/frontend/src/components/MkEmojiPickerDialog.vue
@@ -56,7 +56,7 @@ const props = withDefaults(defineProps<{
});
const emit = defineEmits<{
- (ev: 'done', v: any): void;
+ (ev: 'done', v: string): void;
(ev: 'close'): void;
(ev: 'closed'): void;
}>();
@@ -64,7 +64,7 @@ const emit = defineEmits<{
const modal = shallowRef<InstanceType<typeof MkModal>>();
const picker = shallowRef<InstanceType<typeof MkEmojiPicker>>();
-function chosen(emoji: any) {
+function chosen(emoji: string) {
emit('done', emoji);
if (props.choseAndClose) {
modal.value?.close();
diff --git a/packages/frontend/src/components/MkEmojiPickerWindow.vue b/packages/frontend/src/components/MkEmojiPickerWindow.vue
deleted file mode 100644
index 6952943345..0000000000
--- a/packages/frontend/src/components/MkEmojiPickerWindow.vue
+++ /dev/null
@@ -1,49 +0,0 @@
-<!--
-SPDX-FileCopyrightText: syuilo and misskey-project
-SPDX-License-Identifier: AGPL-3.0-only
--->
-
-<template>
-<MkWindow
- ref="window"
- :initialWidth="300"
- :initialHeight="290"
- :canResize="true"
- :mini="true"
- :front="true"
- @closed="emit('closed')"
->
- <MkEmojiPicker :showPinned="showPinned" :asReactionPicker="asReactionPicker" :targetNote="targetNote" asWindow :class="$style.picker" @chosen="chosen"/>
-</MkWindow>
-</template>
-
-<script lang="ts" setup>
-import { } from 'vue';
-import * as Misskey from 'misskey-js';
-import MkWindow from '@/components/MkWindow.vue';
-import MkEmojiPicker from '@/components/MkEmojiPicker.vue';
-
-withDefaults(defineProps<{
- src?: HTMLElement;
- showPinned?: boolean;
- asReactionPicker?: boolean;
- targetNote?: Misskey.entities.Note
-}>(), {
- showPinned: true,
-});
-
-const emit = defineEmits<{
- (ev: 'chosen', v: any): void;
- (ev: 'closed'): void;
-}>();
-
-function chosen(emoji: any) {
- emit('chosen', emoji);
-}
-</script>
-
-<style lang="scss" module>
-.picker {
- height: 100%;
-}
-</style>
diff --git a/packages/frontend/src/components/MkFormDialog.vue b/packages/frontend/src/components/MkFormDialog.vue
index 0d8734799c..deedc5badb 100644
--- a/packages/frontend/src/components/MkFormDialog.vue
+++ b/packages/frontend/src/components/MkFormDialog.vue
@@ -21,37 +21,37 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer :marginMin="20" :marginMax="32">
<div v-if="Object.keys(form).filter(item => !form[item].hidden).length > 0" class="_gaps_m">
- <template v-for="item in Object.keys(form).filter(item => !form[item].hidden)">
- <MkInput v-if="form[item].type === 'number'" v-model="values[item]" type="number" :step="form[item].step || 1">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
- <template v-if="form[item].description" #caption>{{ form[item].description }}</template>
+ <template v-for="(v, k) in Object.fromEntries(Object.entries(form).filter(([_, v]) => !('hidden' in v) || 'hidden' in v && !v.hidden))">
+ <MkInput v-if="v.type === 'number'" v-model="values[k]" type="number" :step="v.step || 1">
+ <template #label><span v-text="v.label || k"></span><span v-if="v.required === false"> ({{ i18n.ts.optional }})</span></template>
+ <template v-if="v.description" #caption>{{ v.description }}</template>
</MkInput>
- <MkInput v-else-if="form[item].type === 'string' && !form[item].multiline" v-model="values[item]" type="text" :mfmAutocomplete="form[item].treatAsMfm">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
- <template v-if="form[item].description" #caption>{{ form[item].description }}</template>
+ <MkInput v-else-if="v.type === 'string' && !v.multiline" v-model="values[k]" type="text" :mfmAutocomplete="v.treatAsMfm">
+ <template #label><span v-text="v.label || k"></span><span v-if="v.required === false"> ({{ i18n.ts.optional }})</span></template>
+ <template v-if="v.description" #caption>{{ v.description }}</template>
</MkInput>
- <MkTextarea v-else-if="form[item].type === 'string' && form[item].multiline" v-model="values[item]" :mfmAutocomplete="form[item].treatAsMfm" :mfmPreview="form[item].treatAsMfm">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
- <template v-if="form[item].description" #caption>{{ form[item].description }}</template>
+ <MkTextarea v-else-if="v.type === 'string' && v.multiline" v-model="values[k]" :mfmAutocomplete="v.treatAsMfm" :mfmPreview="v.treatAsMfm">
+ <template #label><span v-text="v.label || k"></span><span v-if="v.required === false"> ({{ i18n.ts.optional }})</span></template>
+ <template v-if="v.description" #caption>{{ v.description }}</template>
</MkTextarea>
- <MkSwitch v-else-if="form[item].type === 'boolean'" v-model="values[item]">
- <span v-text="form[item].label || item"></span>
- <template v-if="form[item].description" #caption>{{ form[item].description }}</template>
+ <MkSwitch v-else-if="v.type === 'boolean'" v-model="values[k]">
+ <span v-text="v.label || k"></span>
+ <template v-if="v.description" #caption>{{ v.description }}</template>
</MkSwitch>
- <MkSelect v-else-if="form[item].type === 'enum'" v-model="values[item]">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
- <option v-for="option in form[item].enum" :key="option.value" :value="option.value">{{ option.label }}</option>
+ <MkSelect v-else-if="v.type === 'enum'" v-model="values[k]">
+ <template #label><span v-text="v.label || k"></span><span v-if="v.required === false"> ({{ i18n.ts.optional }})</span></template>
+ <option v-for="option in v.enum" :key="option.value" :value="option.value">{{ option.label }}</option>
</MkSelect>
- <MkRadios v-else-if="form[item].type === 'radio'" v-model="values[item]">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
- <option v-for="option in form[item].options" :key="option.value" :value="option.value">{{ option.label }}</option>
+ <MkRadios v-else-if="v.type === 'radio'" v-model="values[k]">
+ <template #label><span v-text="v.label || k"></span><span v-if="v.required === false"> ({{ i18n.ts.optional }})</span></template>
+ <option v-for="option in v.options" :key="option.value" :value="option.value">{{ option.label }}</option>
</MkRadios>
- <MkRange v-else-if="form[item].type === 'range'" v-model="values[item]" :min="form[item].min" :max="form[item].max" :step="form[item].step" :textConverter="form[item].textConverter">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
- <template v-if="form[item].description" #caption>{{ form[item].description }}</template>
+ <MkRange v-else-if="v.type === 'range'" v-model="values[k]" :min="v.min" :max="v.max" :step="v.step" :textConverter="v.textConverter">
+ <template #label><span v-text="v.label || k"></span><span v-if="v.required === false"> ({{ i18n.ts.optional }})</span></template>
+ <template v-if="v.description" #caption>{{ v.description }}</template>
</MkRange>
- <MkButton v-else-if="form[item].type === 'button'" @click="form[item].action($event, values)">
- <span v-text="form[item].content || item"></span>
+ <MkButton v-else-if="v.type === 'button'" @click="v.action($event, values)">
+ <span v-text="v.content || k"></span>
</MkButton>
</template>
</div>
@@ -72,19 +72,21 @@ import MkSelect from './MkSelect.vue';
import MkRange from './MkRange.vue';
import MkButton from './MkButton.vue';
import MkRadios from './MkRadios.vue';
+import type { Form } from '@/scripts/form.js';
import MkModalWindow from '@/components/MkModalWindow.vue';
import { i18n } from '@/i18n.js';
import { infoImageUrl } from '@/instance.js';
const props = defineProps<{
title: string;
- form: any;
+ form: Form;
}>();
const emit = defineEmits<{
(ev: 'done', v: {
- canceled?: boolean;
- result?: any;
+ canceled: true;
+ } | {
+ result: Record<string, any>;
}): void;
(ev: 'closed'): void;
}>();
diff --git a/packages/frontend/src/components/MkNotifications.vue b/packages/frontend/src/components/MkNotifications.vue
index a9f019dd9c..389987338d 100644
--- a/packages/frontend/src/components/MkNotifications.vue
+++ b/packages/frontend/src/components/MkNotifications.vue
@@ -35,6 +35,7 @@ import { notificationTypes } from '@/const.js';
import { infoImageUrl } from '@/instance.js';
import { defaultStore } from '@/store.js';
import MkPullToRefresh from '@/components/MkPullToRefresh.vue';
+import * as Misskey from 'misskey-js';
const props = defineProps<{
excludeTypes?: typeof notificationTypes[number][];
@@ -75,17 +76,19 @@ function reload() {
});
}
-let connection;
+let connection: Misskey.ChannelConnection<Misskey.Channels['main']>;
onMounted(() => {
connection = useStream().useChannel('main');
connection.on('notification', onNotification);
+ connection.on('notificationFlushed', reload);
});
onActivated(() => {
pagingComponent.value?.reload();
connection = useStream().useChannel('main');
connection.on('notification', onNotification);
+ connection.on('notificationFlushed', reload);
});
onUnmounted(() => {
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index 819f0f692c..e03faeaf55 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -172,7 +172,7 @@ const emit = defineEmits<{
const textareaEl = shallowRef<HTMLTextAreaElement | null>(null);
const cwInputEl = shallowRef<HTMLInputElement | null>(null);
const hashtagsInputEl = shallowRef<HTMLInputElement | null>(null);
-const visibilityButton = shallowRef<HTMLElement | null>(null);
+const visibilityButton = shallowRef<HTMLElement>();
const posting = ref(false);
const posted = ref(false);
@@ -461,6 +461,7 @@ function setVisibility() {
isSilenced: $i.isSilenced,
localOnly: localOnly.value,
src: visibilityButton.value,
+ ...(props.reply ? { isReplyVisibilitySpecified: props.reply.visibility === 'specified' } : {}),
}, {
changeVisibility: v => {
visibility.value = v;
diff --git a/packages/frontend/src/components/MkPostFormAttaches.vue b/packages/frontend/src/components/MkPostFormAttaches.vue
index 3f775bc6e2..95eb367318 100644
--- a/packages/frontend/src/components/MkPostFormAttaches.vue
+++ b/packages/frontend/src/components/MkPostFormAttaches.vue
@@ -152,12 +152,12 @@ function showFileMenu(file: Misskey.entities.DriveFile, ev: MouseEvent): void {
icon: 'ti ti-crop',
action: () : void => { crop(file); },
}] : [], {
+ type: 'divider',
+ }, {
text: i18n.ts.attachCancel,
icon: 'ti ti-circle-x',
action: () => { detachMedia(file.id); },
}, {
- type: 'divider',
- }, {
text: i18n.ts.deleteFile,
icon: 'ti ti-trash',
danger: true,
diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
index 0dcd8b0ea2..c41811febe 100644
--- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
@@ -33,7 +33,8 @@ import { defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
import * as sound from '@/scripts/sound.js';
import { checkReactionPermissions } from '@/scripts/check-reaction-permissions.js';
-import { customEmojis } from '@/custom-emojis.js';
+import { customEmojisMap } from '@/custom-emojis.js';
+import { getUnicodeEmoji } from '@/scripts/emojilist.js';
const props = defineProps<{
reaction: string;
@@ -50,13 +51,11 @@ const emit = defineEmits<{
const buttonEl = shallowRef<HTMLElement>();
-const isCustomEmoji = computed(() => props.reaction.includes(':'));
-const emoji = computed(() => isCustomEmoji.value ? customEmojis.value.find(emoji => emoji.name === props.reaction.replace(/:/g, '').replace(/@\./, '')) : null);
+const emojiName = computed(() => props.reaction.replace(/:/g, '').replace(/@\./, ''));
+const emoji = computed(() => customEmojisMap.get(emojiName.value) ?? getUnicodeEmoji(props.reaction));
const canToggle = computed(() => {
- return !props.reaction.match(/@\w/) && $i
- && (emoji.value && checkReactionPermissions($i, props.note, emoji.value))
- || !isCustomEmoji.value;
+ return !props.reaction.match(/@\w/) && $i && emoji.value && checkReactionPermissions($i, props.note, emoji.value);
});
const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':'));
diff --git a/packages/frontend/src/components/MkVisibilityPicker.vue b/packages/frontend/src/components/MkVisibilityPicker.vue
index 3439a751a0..5ecd41bfdf 100644
--- a/packages/frontend/src/components/MkVisibilityPicker.vue
+++ b/packages/frontend/src/components/MkVisibilityPicker.vue
@@ -9,21 +9,21 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="[$style.label, $style.item]">
{{ i18n.ts.visibility }}
</div>
- <button key="public" :disabled="isSilenced" class="_button" :class="[$style.item, { [$style.active]: v === 'public' }]" data-index="1" @click="choose('public')">
+ <button key="public" :disabled="isSilenced || isReplyVisibilitySpecified" class="_button" :class="[$style.item, { [$style.active]: v === 'public' }]" data-index="1" @click="choose('public')">
<div :class="$style.icon"><i class="ti ti-world"></i></div>
<div :class="$style.body">
<span :class="$style.itemTitle">{{ i18n.ts._visibility.public }}</span>
<span :class="$style.itemDescription">{{ i18n.ts._visibility.publicDescription }}</span>
</div>
</button>
- <button key="home" class="_button" :class="[$style.item, { [$style.active]: v === 'home' }]" data-index="2" @click="choose('home')">
+ <button key="home" :disabled="isReplyVisibilitySpecified" class="_button" :class="[$style.item, { [$style.active]: v === 'home' }]" data-index="2" @click="choose('home')">
<div :class="$style.icon"><i class="ti ti-home"></i></div>
<div :class="$style.body">
<span :class="$style.itemTitle">{{ i18n.ts._visibility.home }}</span>
<span :class="$style.itemDescription">{{ i18n.ts._visibility.homeDescription }}</span>
</div>
</button>
- <button key="followers" class="_button" :class="[$style.item, { [$style.active]: v === 'followers' }]" data-index="3" @click="choose('followers')">
+ <button key="followers" :disabled="isReplyVisibilitySpecified" class="_button" :class="[$style.item, { [$style.active]: v === 'followers' }]" data-index="3" @click="choose('followers')">
<div :class="$style.icon"><i class="ti ti-lock"></i></div>
<div :class="$style.body">
<span :class="$style.itemTitle">{{ i18n.ts._visibility.followers }}</span>
@@ -54,6 +54,7 @@ const props = withDefaults(defineProps<{
isSilenced: boolean;
localOnly: boolean;
src?: HTMLElement;
+ isReplyVisibilitySpecified?: boolean;
}>(), {
});
diff --git a/packages/frontend/src/components/global/MkA.stories.impl.ts b/packages/frontend/src/components/global/MkA.stories.impl.ts
index 9d57841f04..c1d8cf0ca6 100644
--- a/packages/frontend/src/components/global/MkA.stories.impl.ts
+++ b/packages/frontend/src/components/global/MkA.stories.impl.ts
@@ -32,7 +32,8 @@ export const Default = {
async play({ canvasElement }) {
const canvas = within(canvasElement);
const a = canvas.getByRole<HTMLAnchorElement>('link');
- await expect(a.href).toMatch(/^https?:\/\/.*#test$/);
+ // FIXME: 通るã‘ã©ãã®å¾Œè½ã¡ã‚‹ã®ã§ã‚³ãƒ¡ãƒ³ãƒˆã‚¢ã‚¦ãƒˆ
+ // await expect(a.href).toMatch(/^https?:\/\/.*#test$/);
await userEvent.pointer({ keys: '[MouseRight]', target: a });
await tick();
const menu = canvas.getByRole('menu');
@@ -44,6 +45,7 @@ export const Default = {
},
args: {
to: '#test',
+ behavior: 'browser',
},
parameters: {
layout: 'centered',
diff --git a/packages/frontend/src/components/global/MkTime.stories.impl.ts b/packages/frontend/src/components/global/MkTime.stories.impl.ts
index 2b4b1485fd..355c839113 100644
--- a/packages/frontend/src/components/global/MkTime.stories.impl.ts
+++ b/packages/frontend/src/components/global/MkTime.stories.impl.ts
@@ -10,7 +10,7 @@ import MkTime from './MkTime.vue';
import { i18n } from '@/i18n.js';
import { dateTimeFormat } from '@/scripts/intl-const.js';
const now = new Date('2023-04-01T00:00:00.000Z');
-const future = new Date(8640000000000000);
+const future = new Date('2024-04-01T00:00:00.000Z');
const oneHourAgo = new Date(now.getTime() - 3600000);
const oneDayAgo = new Date(now.getTime() - 86400000);
const oneWeekAgo = new Date(now.getTime() - 604800000);
@@ -49,11 +49,12 @@ export const Empty = {
export const RelativeFuture = {
...Empty,
async play({ canvasElement }) {
- await expect(canvasElement).toHaveTextContent(i18n.ts._ago.future);
+ await expect(canvasElement).toHaveTextContent(i18n.tsx._timeIn.years({ n: 1 })); // n (1) = future (2024) - now (2023)
},
args: {
...Empty.args,
time: future,
+ origin: now,
},
} satisfies StoryObj<typeof MkTime>;
export const AbsoluteFuture = {
diff --git a/packages/frontend/src/const.ts b/packages/frontend/src/const.ts
index 0bac4d0b7c..9e41926a97 100644
--- a/packages/frontend/src/const.ts
+++ b/packages/frontend/src/const.ts
@@ -75,6 +75,7 @@ export const ROLE_POLICIES = [
'gtlAvailable',
'ltlAvailable',
'canPublicNote',
+ 'mentionLimit',
'canInvite',
'inviteLimit',
'inviteLimitCycle',
diff --git a/packages/frontend/src/directives/user-preview.ts b/packages/frontend/src/directives/user-preview.ts
index 0d6c330da1..7a008a4486 100644
--- a/packages/frontend/src/directives/user-preview.ts
+++ b/packages/frontend/src/directives/user-preview.ts
@@ -99,7 +99,6 @@ export class UserPreview {
this.el.removeEventListener('mouseover', this.onMouseover);
this.el.removeEventListener('mouseleave', this.onMouseleave);
this.el.removeEventListener('click', this.onClick);
- window.clearInterval(this.checkTimer);
}
}
diff --git a/packages/frontend/src/instance.ts b/packages/frontend/src/instance.ts
index 2056023692..4232cbcd78 100644
--- a/packages/frontend/src/instance.ts
+++ b/packages/frontend/src/instance.ts
@@ -11,13 +11,24 @@ import { DEFAULT_INFO_IMAGE_URL, DEFAULT_NOT_FOUND_IMAGE_URL, DEFAULT_SERVER_ERR
// TODO: ä»–ã®ã‚¿ãƒ–ã¨æ°¸ç¶šåŒ–ã•れãŸstateã‚’åŒæœŸ
-const cached = miLocalStorage.getItem('instance');
+//#region loader
+const providedMetaEl = document.getElementById('misskey_meta');
+
+let cachedMeta = miLocalStorage.getItem('instance') ? JSON.parse(miLocalStorage.getItem('instance')!) : null;
+let cachedAt = miLocalStorage.getItem('instanceCachedAt') ? parseInt(miLocalStorage.getItem('instanceCachedAt')!) : 0;
+const providedMeta = providedMetaEl && providedMetaEl.textContent ? JSON.parse(providedMetaEl.textContent) : null;
+const providedAt = providedMetaEl && providedMetaEl.dataset.generatedAt ? parseInt(providedMetaEl.dataset.generatedAt) : 0;
+if (providedAt > cachedAt) {
+ miLocalStorage.setItem('instance', JSON.stringify(providedMeta));
+ miLocalStorage.setItem('instanceCachedAt', providedAt.toString());
+ cachedMeta = providedMeta;
+ cachedAt = providedAt;
+}
+//#endregion
// TODO: instanceをリアクティブã«ã™ã‚‹ã‹ã¯å†è€ƒã®ä½™åœ°ã‚り
-export const instance: Misskey.entities.MetaResponse = reactive(cached ? JSON.parse(cached) : {
- // TODO: set default values
-});
+export const instance: Misskey.entities.MetaResponse = reactive(cachedMeta ?? {});
export const serverErrorImageUrl = computed(() => instance.serverErrorImageUrl ?? DEFAULT_SERVER_ERROR_IMAGE_URL);
@@ -25,7 +36,15 @@ export const infoImageUrl = computed(() => instance.infoImageUrl ?? DEFAULT_INFO
export const notFoundImageUrl = computed(() => instance.notFoundImageUrl ?? DEFAULT_NOT_FOUND_IMAGE_URL);
-export async function fetchInstance() {
+export async function fetchInstance(force = false): Promise<void> {
+ if (!force) {
+ const cachedAt = miLocalStorage.getItem('instanceCachedAt') ? parseInt(miLocalStorage.getItem('instanceCachedAt')!) : 0;
+
+ if (Date.now() - cachedAt < 1000 * 60 * 60) {
+ return;
+ }
+ }
+
const meta = await misskeyApi('meta', {
detail: false,
});
@@ -35,4 +54,5 @@ export async function fetchInstance() {
}
miLocalStorage.setItem('instance', JSON.stringify(instance));
+ miLocalStorage.setItem('instanceCachedAt', Date.now().toString());
}
diff --git a/packages/frontend/src/local-storage.ts b/packages/frontend/src/local-storage.ts
index 3de81c9bb9..8029bca68d 100644
--- a/packages/frontend/src/local-storage.ts
+++ b/packages/frontend/src/local-storage.ts
@@ -7,6 +7,7 @@ type Keys =
'v' |
'lastVersion' |
'instance' |
+ 'instanceCachedAt' |
'account' |
'accounts' |
'latestDonationInfoShownAt' |
diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts
index a4fde6b701..c561e84a23 100644
--- a/packages/frontend/src/os.ts
+++ b/packages/frontend/src/os.ts
@@ -7,9 +7,9 @@
import { Component, markRaw, Ref, ref, defineAsyncComponent } from 'vue';
import { EventEmitter } from 'eventemitter3';
-import insertTextAtCursor from 'insert-text-at-cursor';
import * as Misskey from 'misskey-js';
-import type { ComponentProps } from 'vue-component-type-helpers';
+import type { ComponentProps as CP } from 'vue-component-type-helpers';
+import type { Form, GetFormResultType } from '@/scripts/form.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { i18n } from '@/i18n.js';
import MkPostFormDialog from '@/components/MkPostFormDialog.vue';
@@ -19,7 +19,6 @@ import MkToast from '@/components/MkToast.vue';
import MkDialog from '@/components/MkDialog.vue';
import MkPasswordDialog from '@/components/MkPasswordDialog.vue';
import MkEmojiPickerDialog from '@/components/MkEmojiPickerDialog.vue';
-import MkEmojiPickerWindow from '@/components/MkEmojiPickerWindow.vue';
import MkPopupMenu from '@/components/MkPopupMenu.vue';
import MkContextMenu from '@/components/MkContextMenu.vue';
import { MenuItem } from '@/types/menu.js';
@@ -28,15 +27,15 @@ import { showMovedDialog } from '@/scripts/show-moved-dialog.js';
export const openingWindowsCount = ref(0);
-export const apiWithDialog = ((
- endpoint: string,
- data: Record<string, any> = {},
+export const apiWithDialog = (<E extends keyof Misskey.Endpoints = keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req'] = Misskey.Endpoints[E]['req']>(
+ endpoint: E,
+ data: P = {} as any,
token?: string | null | undefined,
) => {
const promise = misskeyApi(endpoint, data, token);
promiseDialog(promise, null, async (err) => {
- let title = null;
- let text = err.message + '\n' + (err as any).id;
+ let title: string | undefined;
+ let text = err.message + '\n' + err.id;
if (err.code === 'INTERNAL_ERROR') {
title = i18n.ts.internalServerError;
text = i18n.ts.internalServerErrorDescription;
@@ -88,7 +87,7 @@ export const apiWithDialog = ((
export function promiseDialog<T extends Promise<any>>(
promise: T,
onSuccess?: ((res: any) => void) | null,
- onFailure?: ((err: Error) => void) | null,
+ onFailure?: ((err: Misskey.api.APIError) => void) | null,
text?: string,
): T {
const showing = ref(true);
@@ -149,14 +148,30 @@ export function claimZIndex(priority: keyof typeof zIndexes = 'low'): number {
// 使ã„物ã«ãªã‚‰ãªã„ã®ã§ã€ä»£ã‚り㫠['$props'] ã‹ã‚‰è‰²ã€…çœãã“ã¨ã§ emit ã®åž‹ã‚’生æˆã™ã‚‹
// FIXME: 何故㋠*.ts ファイルã‹ã‚‰ã ã¨åž‹ãŒã†ã¾ãå–れãªã„?ã“ã¨ãŒã‚ã‚‹ã®ã‚’ãªã‚“ã¨ã‹ã—ãŸã„
type ComponentEmit<T> = T extends new () => { $props: infer Props }
- ? EmitsExtractor<Props>
- : never;
+ ? [keyof Pick<T, Extract<keyof T, `on${string}`>>] extends [never]
+ ? Record<string, unknown> // *.ts ファイルã‹ã‚‰åž‹ãŒã†ã¾ãå–れãªã„ã¨ã用(ã“れãŒãªã„㨠{} ã«ãªã£ã¦åž‹ã‚¨ãƒ©ãƒ¼ãŒã†ã‚‹ã•ã„)
+ : EmitsExtractor<Props>
+ : T extends (...args: any) => any
+ ? ReturnType<T> extends { [x: string]: any; __ctx?: { [x: string]: any; props: infer Props } }
+ ? [keyof Pick<T, Extract<keyof T, `on${string}`>>] extends [never]
+ ? Record<string, unknown>
+ : EmitsExtractor<Props>
+ : never
+ : never;
+
+// props ã« ref を許å¯ã™ã‚‹ã‚ˆã†ã«ã™ã‚‹
+type ComponentProps<T extends Component> = { [K in keyof CP<T>]: CP<T>[K] | Ref<CP<T>[K]> };
type EmitsExtractor<T> = {
[K in keyof T as K extends `onVnode${string}` ? never : K extends `on${infer E}` ? Uncapitalize<E> : K extends string ? never : K]: T[K];
};
-export async function popup<T extends Component>(component: T, props: ComponentProps<T>, events: ComponentEmit<T> = {} as ComponentEmit<T>, disposeEvent?: keyof ComponentEmit<T>) {
+export async function popup<T extends Component>(
+ component: T,
+ props: ComponentProps<T>,
+ events: ComponentEmit<T> = {} as ComponentEmit<T>,
+ disposeEvent?: keyof ComponentEmit<T>,
+): Promise<{ dispose: () => void }> {
markRaw(component);
const id = ++popupIdCount;
@@ -197,12 +212,12 @@ export function toast(message: string) {
export function alert(props: {
type?: 'error' | 'info' | 'success' | 'warning' | 'waiting' | 'question';
- title?: string | null;
- text?: string | null;
+ title?: string;
+ text?: string;
}): Promise<void> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(MkDialog, props, {
- done: result => {
+ done: () => {
resolve();
},
}, 'closed');
@@ -211,12 +226,12 @@ export function alert(props: {
export function confirm(props: {
type: 'error' | 'info' | 'success' | 'warning' | 'waiting' | 'question';
- title?: string | null;
- text?: string | null;
+ title?: string;
+ text?: string;
okText?: string;
cancelText?: string;
}): Promise<{ canceled: boolean }> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(MkDialog, {
...props,
showCancelButton: true,
@@ -237,13 +252,15 @@ export function actions<T extends {
danger?: boolean,
}[]>(props: {
type: 'error' | 'info' | 'success' | 'warning' | 'waiting' | 'question';
- title?: string | null;
- text?: string | null;
+ title?: string;
+ text?: string;
actions: T;
-}): Promise<{ canceled: true; result: undefined; } | {
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
canceled: false; result: T[number]['value'];
}> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(MkDialog, {
...props,
actions: props.actions.map(a => ({
@@ -262,19 +279,50 @@ export function actions<T extends {
});
}
+// default ãŒæŒ‡å®šã•れã¦ã„ãŸã‚‰ result 㯠null ã«ãªã‚Šå¾—ãªã„ã“ã¨ã‚’ä¿è¨¼ã™ã‚‹ overload function
export function inputText(props: {
type?: 'text' | 'email' | 'password' | 'url';
- title?: string | null;
- text?: string | null;
+ title?: string;
+ text?: string;
placeholder?: string | null;
autocomplete?: string;
- default?: string | null;
+ default: string;
minLength?: number;
maxLength?: number;
-}): Promise<{ canceled: true; result: undefined; } | {
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
canceled: false; result: string;
+}>;
+export function inputText(props: {
+ type?: 'text' | 'email' | 'password' | 'url';
+ title?: string;
+ text?: string;
+ placeholder?: string | null;
+ autocomplete?: string;
+ default?: string | null;
+ minLength?: number;
+ maxLength?: number;
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
+ canceled: false; result: string | null;
+}>;
+export function inputText(props: {
+ type?: 'text' | 'email' | 'password' | 'url';
+ title?: string;
+ text?: string;
+ placeholder?: string | null;
+ autocomplete?: string;
+ default?: string | null;
+ minLength?: number;
+ maxLength?: number;
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
+ canceled: false; result: string | null;
}> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(MkDialog, {
title: props.title,
text: props.text,
@@ -282,7 +330,7 @@ export function inputText(props: {
type: props.type,
placeholder: props.placeholder,
autocomplete: props.autocomplete,
- default: props.default,
+ default: props.default ?? null,
minLength: props.minLength,
maxLength: props.maxLength,
},
@@ -294,16 +342,41 @@ export function inputText(props: {
});
}
+// default ãŒæŒ‡å®šã•れã¦ã„ãŸã‚‰ result 㯠null ã«ãªã‚Šå¾—ãªã„ã“ã¨ã‚’ä¿è¨¼ã™ã‚‹ overload function
export function inputNumber(props: {
- title?: string | null;
- text?: string | null;
+ title?: string;
+ text?: string;
placeholder?: string | null;
autocomplete?: string;
- default?: number | null;
-}): Promise<{ canceled: true; result: undefined; } | {
+ default: number;
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
canceled: false; result: number;
+}>;
+export function inputNumber(props: {
+ title?: string;
+ text?: string;
+ placeholder?: string | null;
+ autocomplete?: string;
+ default?: number | null;
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
+ canceled: false; result: number | null;
+}>;
+export function inputNumber(props: {
+ title?: string;
+ text?: string;
+ placeholder?: string | null;
+ autocomplete?: string;
+ default?: number | null;
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
+ canceled: false; result: number | null;
}> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(MkDialog, {
title: props.title,
text: props.text,
@@ -311,7 +384,7 @@ export function inputNumber(props: {
type: 'number',
placeholder: props.placeholder,
autocomplete: props.autocomplete,
- default: props.default,
+ default: props.default ?? null,
},
}, {
done: result => {
@@ -322,34 +395,38 @@ export function inputNumber(props: {
}
export function inputDate(props: {
- title?: string | null;
- text?: string | null;
+ title?: string;
+ text?: string;
placeholder?: string | null;
- default?: Date | null;
-}): Promise<{ canceled: true; result: undefined; } | {
+ default?: string | null;
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
canceled: false; result: Date;
}> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(MkDialog, {
title: props.title,
text: props.text,
input: {
type: 'date',
placeholder: props.placeholder,
- default: props.default,
+ default: props.default ?? null,
},
}, {
done: result => {
- resolve(result ? { result: new Date(result.result), canceled: false } : { canceled: true });
+ resolve(result ? { result: new Date(result.result), canceled: false } : { result: undefined, canceled: true });
},
}, 'closed');
});
}
-export function authenticateDialog(): Promise<{ canceled: true; result: undefined; } | {
+export function authenticateDialog(): Promise<{
+ canceled: true; result: undefined;
+} | {
canceled: false; result: { password: string; token: string | null; };
}> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(MkPasswordDialog, {}, {
done: result => {
resolve(result ? { canceled: false, result } : { canceled: true, result: undefined });
@@ -358,34 +435,53 @@ export function authenticateDialog(): Promise<{ canceled: true; result: undefine
});
}
+// default ãŒæŒ‡å®šã•れã¦ã„ãŸã‚‰ result 㯠null ã«ãªã‚Šå¾—ãªã„ã“ã¨ã‚’ä¿è¨¼ã™ã‚‹ overload function
export function select<C = any>(props: {
- title?: string | null;
- text?: string | null;
+ title?: string;
+ text?: string;
+ default: string;
+ items: {
+ value: C;
+ text: string;
+ }[];
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
+ canceled: false; result: C;
+}>;
+export function select<C = any>(props: {
+ title?: string;
+ text?: string;
default?: string | null;
-} & ({
items: {
value: C;
text: string;
}[];
+}): Promise<{
+ canceled: true; result: undefined;
} | {
- groupedItems: {
- label: string;
- items: {
- value: C;
- text: string;
- }[];
+ canceled: false; result: C | null;
+}>;
+export function select<C = any>(props: {
+ title?: string;
+ text?: string;
+ default?: string | null;
+ items: {
+ value: C;
+ text: string;
}[];
-})): Promise<{ canceled: true; result: undefined; } | {
- canceled: false; result: C;
+}): Promise<{
+ canceled: true; result: undefined;
+} | {
+ canceled: false; result: C | null;
}> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(MkDialog, {
title: props.title,
text: props.text,
select: {
items: props.items,
- groupedItems: props.groupedItems,
- default: props.default,
+ default: props.default ?? null,
},
}, {
done: result => {
@@ -396,7 +492,7 @@ export function select<C = any>(props: {
}
export function success(): Promise<void> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
const showing = ref(true);
window.setTimeout(() => {
showing.value = false;
@@ -411,7 +507,7 @@ export function success(): Promise<void> {
}
export function waiting(): Promise<void> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
const showing = ref(true);
popup(MkWaitingDialog, {
success: false,
@@ -422,9 +518,9 @@ export function waiting(): Promise<void> {
});
}
-export function form(title, form) {
- return new Promise((resolve, reject) => {
- popup(defineAsyncComponent(() => import('@/components/MkFormDialog.vue')), { title, form }, {
+export function form<F extends Form>(title: string, f: F): Promise<{ canceled: true } | { result: GetFormResultType<F> }> {
+ return new Promise(resolve => {
+ popup(defineAsyncComponent(() => import('@/components/MkFormDialog.vue')), { title, form: f }, {
done: result => {
resolve(result);
},
@@ -433,7 +529,7 @@ export function form(title, form) {
}
export async function selectUser(opts: { includeSelf?: boolean; localOnly?: boolean; } = {}): Promise<Misskey.entities.UserDetailed> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(defineAsyncComponent(() => import('@/components/MkUserSelectDialog.vue')), {
includeSelf: opts.includeSelf,
localOnly: opts.localOnly,
@@ -446,7 +542,7 @@ export async function selectUser(opts: { includeSelf?: boolean; localOnly?: bool
}
export async function selectDriveFile(multiple: boolean): Promise<Misskey.entities.DriveFile[]> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(defineAsyncComponent(() => import('@/components/MkDriveSelectDialog.vue')), {
type: 'file',
multiple,
@@ -460,23 +556,23 @@ export async function selectDriveFile(multiple: boolean): Promise<Misskey.entiti
});
}
-export async function selectDriveFolder(multiple: boolean) {
- return new Promise((resolve, reject) => {
+export async function selectDriveFolder(multiple: boolean): Promise<Misskey.entities.DriveFolder[]> {
+ return new Promise(resolve => {
popup(defineAsyncComponent(() => import('@/components/MkDriveSelectDialog.vue')), {
type: 'folder',
multiple,
}, {
done: folders => {
if (folders) {
- resolve(multiple ? folders : folders[0]);
+ resolve(folders);
}
},
}, 'closed');
});
}
-export async function pickEmoji(src: HTMLElement | null, opts) {
- return new Promise((resolve, reject) => {
+export async function pickEmoji(src: HTMLElement, opts: ComponentProps<typeof MkEmojiPickerDialog>): Promise<string> {
+ return new Promise(resolve => {
popup(MkEmojiPickerDialog, {
src,
...opts,
@@ -492,7 +588,7 @@ export async function cropImage(image: Misskey.entities.DriveFile, options: {
aspectRatio: number;
uploadFolder?: string | null;
}): Promise<Misskey.entities.DriveFile> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
popup(defineAsyncComponent(() => import('@/components/MkCropperDialog.vue')), {
file: image,
aspectRatio: options.aspectRatio,
@@ -505,67 +601,13 @@ export async function cropImage(image: Misskey.entities.DriveFile, options: {
});
}
-type AwaitType<T> =
- T extends Promise<infer U> ? U :
- T extends (...args: any[]) => Promise<infer V> ? V :
- T;
-let openingEmojiPicker: AwaitType<ReturnType<typeof popup>> | null = null;
-let activeTextarea: HTMLTextAreaElement | HTMLInputElement | null = null;
-export async function openEmojiPicker(src?: HTMLElement, opts, initialTextarea: typeof activeTextarea) {
- if (openingEmojiPicker) return;
-
- activeTextarea = initialTextarea;
-
- const textareas = document.querySelectorAll('textarea, input');
- for (const textarea of Array.from(textareas)) {
- textarea.addEventListener('focus', () => {
- activeTextarea = textarea;
- });
- }
-
- const observer = new MutationObserver(records => {
- for (const record of records) {
- for (const node of Array.from(record.addedNodes).filter(node => node instanceof HTMLElement) as HTMLElement[]) {
- const textareas = node.querySelectorAll('textarea, input') as NodeListOf<NonNullable<typeof activeTextarea>>;
- for (const textarea of Array.from(textareas).filter(textarea => textarea.dataset.preventEmojiInsert == null)) {
- if (document.activeElement === textarea) activeTextarea = textarea;
- textarea.addEventListener('focus', () => {
- activeTextarea = textarea;
- });
- }
- }
- }
- });
-
- observer.observe(document.body, {
- childList: true,
- subtree: true,
- attributes: false,
- characterData: false,
- });
-
- openingEmojiPicker = await popup(MkEmojiPickerWindow, {
- src,
- ...opts,
- }, {
- chosen: emoji => {
- insertTextAtCursor(activeTextarea, emoji);
- },
- closed: () => {
- openingEmojiPicker!.dispose();
- openingEmojiPicker = null;
- observer.disconnect();
- },
- });
-}
-
-export function popupMenu(items: MenuItem[] | Ref<MenuItem[]>, src?: HTMLElement | EventTarget | null, options?: {
+export function popupMenu(items: MenuItem[], src?: HTMLElement | EventTarget | null, options?: {
align?: string;
width?: number;
viaKeyboard?: boolean;
onClosing?: () => void;
}): Promise<void> {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
let dispose;
popup(MkPopupMenu, {
items,
@@ -587,9 +629,9 @@ export function popupMenu(items: MenuItem[] | Ref<MenuItem[]>, src?: HTMLElement
});
}
-export function contextMenu(items: MenuItem[] | Ref<MenuItem[]>, ev: MouseEvent): Promise<void> {
+export function contextMenu(items: MenuItem[], ev: MouseEvent): Promise<void> {
ev.preventDefault();
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
let dispose;
popup(MkContextMenu, {
items,
@@ -608,7 +650,7 @@ export function contextMenu(items: MenuItem[] | Ref<MenuItem[]>, ev: MouseEvent)
export function post(props: Record<string, any> = {}): Promise<void> {
showMovedDialog();
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
// NOTE: MkPostFormDialogã‚’dynamic importã™ã‚‹ã¨iOSã§ãƒ†ã‚­ã‚¹ãƒˆã‚¨ãƒªã‚¢ã«è‡ªå‹•フォーカスã§ããªã„
// NOTE: ãŸã ã€dynamic importã—ãªã„å ´åˆã€MkPostFormDialogインスタンスãŒä½¿ã„ã¾ã‚ã•れã€
// VueãŒæ¸¡ã•れãŸã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆã«å†…部的ã«__propsã¨ã„ã†ãƒ—ロパティを生やã™å½±éŸ¿ã§ã€
diff --git a/packages/frontend/src/pages/admin/RolesEditorFormula.vue b/packages/frontend/src/pages/admin/RolesEditorFormula.vue
index f4a8f44955..2f5b4c47d8 100644
--- a/packages/frontend/src/pages/admin/RolesEditorFormula.vue
+++ b/packages/frontend/src/pages/admin/RolesEditorFormula.vue
@@ -9,6 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSelect v-model="type" :class="$style.typeSelect">
<option value="isLocal">{{ i18n.ts._role._condition.isLocal }}</option>
<option value="isRemote">{{ i18n.ts._role._condition.isRemote }}</option>
+ <option value="roleAssignedTo">{{ i18n.ts._role._condition.roleAssignedTo }}</option>
<option value="createdLessThan">{{ i18n.ts._role._condition.createdLessThan }}</option>
<option value="createdMoreThan">{{ i18n.ts._role._condition.createdMoreThan }}</option>
<option value="followersLessThanOrEq">{{ i18n.ts._role._condition.followersLessThanOrEq }}</option>
@@ -51,6 +52,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkInput v-else-if="['followersLessThanOrEq', 'followersMoreThanOrEq', 'followingLessThanOrEq', 'followingMoreThanOrEq', 'notesLessThanOrEq', 'notesMoreThanOrEq'].includes(type)" v-model="v.value" type="number">
</MkInput>
+
+ <MkSelect v-else-if="type === 'roleAssignedTo'" v-model="v.roleId">
+ <option v-for="role in roles.filter(r => r.target === 'manual')" :key="role.id" :value="role.id">{{ role.name }}</option>
+ </MkSelect>
</div>
</template>
@@ -62,6 +67,7 @@ import MkSelect from '@/components/MkSelect.vue';
import MkButton from '@/components/MkButton.vue';
import { i18n } from '@/i18n.js';
import { deepClone } from '@/scripts/clone.js';
+import { rolesCache } from '@/cache.js';
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
@@ -77,6 +83,8 @@ const props = defineProps<{
const v = ref(deepClone(props.modelValue));
+const roles = await rolesCache.fetch();
+
watch(() => props.modelValue, () => {
if (JSON.stringify(props.modelValue) === JSON.stringify(v.value)) return;
v.value = deepClone(props.modelValue);
@@ -92,6 +100,7 @@ const type = computed({
if (t === 'and') v.value.values = [];
if (t === 'or') v.value.values = [];
if (t === 'not') v.value.value = { id: uuid(), type: 'isRemote' };
+ if (t === 'roleAssignedTo') v.value.roleId = '';
if (t === 'createdLessThan') v.value.sec = 86400;
if (t === 'createdMoreThan') v.value.sec = 86400;
if (t === 'followersLessThanOrEq') v.value.value = 10;
diff --git a/packages/frontend/src/pages/admin/bot-protection.vue b/packages/frontend/src/pages/admin/bot-protection.vue
index e5e04fdeb8..73c5e1919f 100644
--- a/packages/frontend/src/pages/admin/bot-protection.vue
+++ b/packages/frontend/src/pages/admin/bot-protection.vue
@@ -142,7 +142,7 @@ function save() {
turnstileSiteKey: turnstileSiteKey.value,
turnstileSecretKey: turnstileSecretKey.value,
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
</script>
diff --git a/packages/frontend/src/pages/admin/branding.vue b/packages/frontend/src/pages/admin/branding.vue
index 2b559f92c9..fe1b7c561d 100644
--- a/packages/frontend/src/pages/admin/branding.vue
+++ b/packages/frontend/src/pages/admin/branding.vue
@@ -169,7 +169,7 @@ function save() {
feedbackUrl: feedbackUrl.value === '' ? null : feedbackUrl.value,
manifestJsonOverride: manifestJsonOverride.value === '' ? '{}' : JSON.stringify(JSON5.parse(manifestJsonOverride.value)),
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
diff --git a/packages/frontend/src/pages/admin/email-settings.vue b/packages/frontend/src/pages/admin/email-settings.vue
index 839b9bee16..4a858887f3 100644
--- a/packages/frontend/src/pages/admin/email-settings.vue
+++ b/packages/frontend/src/pages/admin/email-settings.vue
@@ -124,7 +124,7 @@ function save() {
smtpUser: smtpUser.value,
smtpPass: smtpPass.value,
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
diff --git a/packages/frontend/src/pages/admin/external-services.vue b/packages/frontend/src/pages/admin/external-services.vue
index ba3eb05e72..e0b82eb02e 100644
--- a/packages/frontend/src/pages/admin/external-services.vue
+++ b/packages/frontend/src/pages/admin/external-services.vue
@@ -61,7 +61,7 @@ function save() {
deeplAuthKey: deeplAuthKey.value,
deeplIsPro: deeplIsPro.value,
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
diff --git a/packages/frontend/src/pages/admin/instance-block.vue b/packages/frontend/src/pages/admin/instance-block.vue
index 5167b2e6b2..6b14bd42c2 100644
--- a/packages/frontend/src/pages/admin/instance-block.vue
+++ b/packages/frontend/src/pages/admin/instance-block.vue
@@ -50,7 +50,7 @@ function save() {
silencedHosts: silencedHosts.value.split('\n') || [],
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
diff --git a/packages/frontend/src/pages/admin/moderation.vue b/packages/frontend/src/pages/admin/moderation.vue
index d6cb1e39a7..9efb34ac9a 100644
--- a/packages/frontend/src/pages/admin/moderation.vue
+++ b/packages/frontend/src/pages/admin/moderation.vue
@@ -110,7 +110,7 @@ function save() {
hiddenTags: hiddenTags.value.split('\n'),
preservedUsernames: preservedUsernames.value.split('\n'),
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
diff --git a/packages/frontend/src/pages/admin/modlog.ModLog.vue b/packages/frontend/src/pages/admin/modlog.ModLog.vue
index 21d68331cb..e33c882721 100644
--- a/packages/frontend/src/pages/admin/modlog.ModLog.vue
+++ b/packages/frontend/src/pages/admin/modlog.ModLog.vue
@@ -110,6 +110,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/>
</div>
</template>
+ <template v-else-if="log.type === 'updateRemoteInstanceNote'">
+ <div>{{ i18n.ts.user }}: {{ log.info.userId }}</div>
+ <div :class="$style.diff">
+ <CodeDiff :context="5" :hideHeader="true" :oldString="log.info.before ?? ''" :newString="log.info.after ?? ''" maxHeight="300px"/>
+ </div>
+ </template>
<details>
<summary>raw</summary>
diff --git a/packages/frontend/src/pages/admin/modlog.vue b/packages/frontend/src/pages/admin/modlog.vue
index 5e251b8a6f..8590ee1651 100644
--- a/packages/frontend/src/pages/admin/modlog.vue
+++ b/packages/frontend/src/pages/admin/modlog.vue
@@ -54,8 +54,6 @@ const pagination = {
})),
};
-console.log(Misskey);
-
const headerActions = computed(() => []);
const headerTabs = computed(() => []);
diff --git a/packages/frontend/src/pages/admin/object-storage.vue b/packages/frontend/src/pages/admin/object-storage.vue
index 4ff5ab09ca..5fddb715cd 100644
--- a/packages/frontend/src/pages/admin/object-storage.vue
+++ b/packages/frontend/src/pages/admin/object-storage.vue
@@ -143,7 +143,7 @@ function save() {
objectStorageSetPublicRead: objectStorageSetPublicRead.value,
objectStorageS3ForcePathStyle: objectStorageS3ForcePathStyle.value,
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
diff --git a/packages/frontend/src/pages/admin/other-settings.vue b/packages/frontend/src/pages/admin/other-settings.vue
index 651f0ef936..345cf333b5 100644
--- a/packages/frontend/src/pages/admin/other-settings.vue
+++ b/packages/frontend/src/pages/admin/other-settings.vue
@@ -73,7 +73,7 @@ function save() {
enableChartsForRemoteUser: enableChartsForRemoteUser.value,
enableChartsForFederatedInstances: enableChartsForFederatedInstances.value,
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
diff --git a/packages/frontend/src/pages/admin/proxy-account.vue b/packages/frontend/src/pages/admin/proxy-account.vue
index 02b506d13d..81db9f1da9 100644
--- a/packages/frontend/src/pages/admin/proxy-account.vue
+++ b/packages/frontend/src/pages/admin/proxy-account.vue
@@ -56,7 +56,7 @@ function save() {
os.apiWithDialog('admin/update-meta', {
proxyAccountId: proxyAccountId.value,
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index ad9df35dbf..eb8a59b34f 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -160,6 +160,25 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</MkFolder>
+ <MkFolder v-if="matchQuery([i18n.ts._role._options.mentionMax, 'mentionLimit'])">
+ <template #label>{{ i18n.ts._role._options.mentionMax }}</template>
+ <template #suffix>
+ <span v-if="role.policies.mentionLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
+ <span v-else>{{ role.policies.mentionLimit.value }}</span>
+ <span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.mentionLimit)"></i></span>
+ </template>
+ <div class="_gaps">
+ <MkSwitch v-model="role.policies.mentionLimit.useDefault" :readonly="readonly">
+ <template #label>{{ i18n.ts._role.useBaseValue }}</template>
+ </MkSwitch>
+ <MkInput v-model="role.policies.mentionLimit.value" :disabled="role.policies.mentionLimit.useDefault" type="number" :readonly="readonly">
+ </MkInput>
+ <MkRange v-model="role.policies.mentionLimit.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
+ <template #label>{{ i18n.ts._role.priority }}</template>
+ </MkRange>
+ </div>
+ </MkFolder>
+
<MkFolder v-if="matchQuery([i18n.ts._role._options.canInvite, 'canInvite'])">
<template #label>{{ i18n.ts._role._options.canInvite }}</template>
<template #suffix>
diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue
index 496cb09664..9753d9f6cb 100644
--- a/packages/frontend/src/pages/admin/roles.vue
+++ b/packages/frontend/src/pages/admin/roles.vue
@@ -48,6 +48,13 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch>
</MkFolder>
+ <MkFolder v-if="matchQuery([i18n.ts._role._options.mentionMax, 'mentionLimit'])">
+ <template #label>{{ i18n.ts._role._options.mentionMax }}</template>
+ <template #suffix>{{ policies.mentionLimit }}</template>
+ <MkInput v-model="policies.mentionLimit" type="number">
+ </MkInput>
+ </MkFolder>
+
<MkFolder v-if="matchQuery([i18n.ts._role._options.canInvite, 'canInvite'])">
<template #label>{{ i18n.ts._role._options.canInvite }}</template>
<template #suffix>{{ policies.canInvite ? i18n.ts.yes : i18n.ts.no }}</template>
diff --git a/packages/frontend/src/pages/admin/security.vue b/packages/frontend/src/pages/admin/security.vue
index cadcf5a8cc..c4745978df 100644
--- a/packages/frontend/src/pages/admin/security.vue
+++ b/packages/frontend/src/pages/admin/security.vue
@@ -196,7 +196,7 @@ async function init() {
enableTruemailApi.value = meta.enableTruemailApi;
truemailInstance.value = meta.truemailInstance;
truemailAuthKey.value = meta.truemailAuthKey;
- bannedEmailDomains.value = meta.bannedEmailDomains?.join('\n') || "";
+ bannedEmailDomains.value = meta.bannedEmailDomains?.join('\n') || '';
}
function save() {
@@ -221,7 +221,7 @@ function save() {
truemailAuthKey: truemailAuthKey.value,
bannedEmailDomains: bannedEmailDomains.value.split('\n'),
}).then(() => {
- fetchInstance();
+ fetchInstance(true);
});
}
diff --git a/packages/frontend/src/pages/admin/server-rules.vue b/packages/frontend/src/pages/admin/server-rules.vue
index 87318bccce..ff9b8d6299 100644
--- a/packages/frontend/src/pages/admin/server-rules.vue
+++ b/packages/frontend/src/pages/admin/server-rules.vue
@@ -58,7 +58,7 @@ const save = async () => {
await os.apiWithDialog('admin/update-meta', {
serverRules: serverRules.value,
});
- fetchInstance();
+ fetchInstance(true);
};
const remove = (index: number): void => {
diff --git a/packages/frontend/src/pages/admin/settings.vue b/packages/frontend/src/pages/admin/settings.vue
index c505d70aa9..9a198ee8a3 100644
--- a/packages/frontend/src/pages/admin/settings.vue
+++ b/packages/frontend/src/pages/admin/settings.vue
@@ -243,7 +243,7 @@ async function save(): void {
notesPerOneAd: notesPerOneAd.value,
});
- fetchInstance();
+ fetchInstance(true);
}
const headerTabs = computed(() => []);
diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue
index d9881cebbf..eba5b92154 100644
--- a/packages/frontend/src/pages/drop-and-fusion.game.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.game.vue
@@ -7,9 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer :contentMax="800">
<div :class="$style.root">
<div v-if="!gameLoaded" :class="$style.loadingScreen">
- <div>
- Loading...
- </div>
+ <div>{{ i18n.ts.loading }}<MkEllipsis/></div>
</div>
<!-- ↓ã«å¯¾ã—ã¦Transitionコンãƒãƒ¼ãƒãƒ³ãƒˆã‚’使ã†ã¨ä½•æ•…ã‹keyを指定ã—ã¦ã„ã¦ã‚‚キャッシュãŒåйã‹ãšæ§˜ã€…ãªã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆãŒéƒ½åº¦å†è©•価ã•れã¦ãƒ‘フォーマンスãŒä½Žä¸‹ã™ã‚‹ -->
<div v-show="gameLoaded" class="_gaps_s">
@@ -32,18 +30,18 @@ SPDX-License-Identifier: AGPL-3.0-only
</Transition>
<div :class="$style.header">
- <div :class="[$style.frame, $style.headerTitle]">
- <div :class="$style.frameInner">
- <b>BUBBLE GAME</b>
- <div>- {{ gameMode }} -</div>
+ <div class="_woodenFrame" :class="[$style.headerTitle]">
+ <div class="_woodenFrameInner">
+ <b>{{ i18n.ts.bubbleGame }}</b>
+ <div>- {{ gameMode.toUpperCase() }} -</div>
</div>
</div>
- <div :class="[$style.frame, $style.frameH]">
- <div :class="$style.frameInner">
- <MkButton inline small @click="hold">HOLD</MkButton>
+ <div class="_woodenFrame _woodenFrameH">
+ <div class="_woodenFrameInner">
+ <MkButton inline small @click="hold">{{ i18n.ts._bubbleGame.hold }}</MkButton>
<img v-if="holdingStock" :src="getTextureImageUrl(holdingStock.mono)" style="width: 32px; margin-left: 8px; vertical-align: bottom;"/>
</div>
- <div :class="[$style.frameInner, $style.stock]" style="text-align: center;">
+ <div class="_woodenFrameInner" :class="$style.stock" style="text-align: center;">
<TransitionGroup
:enterActiveClass="$style.transition_stock_enterActive"
:leaveActiveClass="$style.transition_stock_leaveActive"
@@ -90,58 +88,74 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-if="isGameOver && !replaying" :class="$style.gameOverLabel">
<div class="_gaps_s">
<img src="/client-assets/drop-and-fusion/gameover.png" style="width: 200px; max-width: 100%; display: block; margin: auto; margin-bottom: -5px;"/>
- <div>SCORE: <MkNumber :value="score"/>{{ getScoreUnit(gameMode) }}</div>
- <div>MAX CHAIN: <MkNumber :value="maxCombo"/></div>
- <div v-if="gameMode === 'yen'">TOTAL EARNINGS: <b><MkNumber :value="yenTotal ?? score"/>円</b></div>
- <div v-if="gameMode === 'sweets'"><b>ãŠã«ãŽã‚Š<MkNumber :value="score / 130"/>個分</b></div>
+ <div>{{ i18n.ts._bubbleGame._score.score }}: <MkNumber :value="score"/>{{ getScoreUnit(gameMode) }}</div>
+ <div>{{ i18n.ts._bubbleGame._score.maxChain }}: <MkNumber :value="maxCombo"/></div>
+ <div v-if="gameMode === 'yen'">
+ {{ i18n.ts._bubbleGame._score.scoreYen }}:
+ <I18n :src="i18n.ts._bubbleGame._score.yen" tag="b">
+ <template #yen><MkNumber :value="yenTotal ?? score"/></template>
+ </I18n>
+ </div>
+ <I18n v-if="gameMode === 'sweets'" :src="i18n.ts._bubbleGame._score.scoreSweets" tag="div">
+ <template #onigiriQtyWithUnit>
+ <I18n :src="i18n.ts._bubbleGame._score.estimatedQty" tag="b">
+ <template #qty><MkNumber :value="score / 130"/></template>
+ </I18n>
+ </template>
+ </I18n>
</div>
</div>
<div v-if="replaying" :class="$style.replayIndicator"><span :class="$style.replayIndicatorText"><i class="ti ti-player-play"></i> {{ i18n.ts.replaying }}</span></div>
</div>
- <div v-if="replaying" :class="$style.frame">
- <div :class="$style.frameInner">
+ <div v-if="replaying" class="_woodenFrame">
+ <div class="_woodenFrameInner">
<div style="background: #0004;">
<div style="height: 10px; background: var(--accent); will-change: width;" :style="{ width: `${(currentFrame / endedAtFrame) * 100}%` }"></div>
</div>
</div>
- <div :class="$style.frameInner">
+ <div class="_woodenFrameInner">
<div class="_buttonsCenter">
- <MkButton @click="endReplay"><i class="ti ti-player-stop"></i> END</MkButton>
+ <MkButton @click="endReplay"><i class="ti ti-player-stop"></i> {{ i18n.ts.endReplay }}</MkButton>
<MkButton :primary="replayPlaybackRate === 4" @click="replayPlaybackRate = replayPlaybackRate === 4 ? 1 : 4"><i class="ti ti-player-track-next"></i> x4</MkButton>
<MkButton :primary="replayPlaybackRate === 16" @click="replayPlaybackRate = replayPlaybackRate === 16 ? 1 : 16"><i class="ti ti-player-track-next"></i> x16</MkButton>
</div>
</div>
</div>
- <div v-if="isGameOver" :class="$style.frame">
- <div :class="$style.frameInner">
+ <div v-if="isGameOver" class="_woodenFrame">
+ <div class="_woodenFrameInner">
<div class="_buttonsCenter">
<MkButton primary rounded @click="backToTitle">{{ i18n.ts.backToTitle }}</MkButton>
<MkButton primary rounded @click="replay">{{ i18n.ts.showReplay }}</MkButton>
<MkButton primary rounded @click="share">{{ i18n.ts.share }}</MkButton>
- <MkButton rounded @click="exportLog">Copy replay data</MkButton>
+ <MkButton rounded @click="exportLog">{{ i18n.ts.copyReplayData }}</MkButton>
</div>
</div>
</div>
<div style="display: flex;">
- <div :class="$style.frame" style="flex: 1; margin-right: 10px;">
- <div :class="$style.frameInner">
- <div>SCORE: <b><MkNumber :value="score"/>{{ getScoreUnit(gameMode) }}</b></div>
- <div>HIGH SCORE: <b v-if="highScore"><MkNumber :value="highScore"/>{{ getScoreUnit(gameMode) }}</b><b v-else>-</b></div>
- <div v-if="gameMode === 'yen'">TOTAL EARNINGS: <b v-if="yenTotal"><MkNumber :value="yenTotal"/>円</b><b v-else>-</b></div>
+ <div class="_woodenFrame" style="flex: 1; margin-right: 10px;">
+ <div class="_woodenFrameInner">
+ <div>{{ i18n.ts._bubbleGame._score.score }}: <MkNumber :value="score"/>{{ getScoreUnit(gameMode) }}</div>
+ <div>{{ i18n.ts._bubbleGame._score.highScore }}: <b v-if="highScore"><MkNumber :value="highScore"/>{{ getScoreUnit(gameMode) }}</b><b v-else>-</b></div>
+ <div v-if="gameMode === 'yen'">
+ {{ i18n.ts._bubbleGame._score.scoreYen }}:
+ <I18n :src="i18n.ts._bubbleGame._score.yen" tag="b">
+ <template #yen><MkNumber :value="yenTotal ?? score"/></template>
+ </I18n>
+ </div>
</div>
</div>
- <div :class="[$style.frame]" style="margin-left: auto;">
- <div :class="$style.frameInner" style="text-align: center;">
+ <div class="_woodenFrame" style="margin-left: auto;">
+ <div class="_woodenFrameInner" style="text-align: center;">
<div @click="showConfig = !showConfig"><i class="ti ti-settings"></i></div>
</div>
</div>
</div>
- <div v-if="showConfig" :class="$style.frame">
- <div :class="$style.frameInner">
+ <div v-if="showConfig" class="_woodenFrame">
+ <div class="_woodenFrameInner">
<div class="_gaps">
<MkRange v-model="bgmVolume" :min="0" :max="1" :step="0.01" :textConverter="(v) => `${Math.floor(v * 100)}%`" :continuousUpdate="true" @dragEnded="(v) => updateSettings('bgmVolume', v)">
<template #label>BGM {{ i18n.ts.volume }}</template>
@@ -153,8 +167,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
- <div :class="$style.frame">
- <div :class="$style.frameInner">
+ <div class="_woodenFrame">
+ <div class="_woodenFrameInner">
<div>FUSION RECIPE</div>
<div>
<div v-for="(mono, i) in game.monoDefinitions.sort((a, b) => a.level - b.level)" :key="mono.id" style="display: inline-block;">
@@ -165,10 +179,10 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
- <div :class="$style.frame">
- <div :class="$style.frameInner">
- <MkButton v-if="!isGameOver && !replaying" full danger @click="surrender">Surrender</MkButton>
- <MkButton v-else full @click="restart">Retry</MkButton>
+ <div class="_woodenFrame">
+ <div class="_woodenFrameInner">
+ <MkButton v-if="!isGameOver && !replaying" full danger @click="surrender">{{ i18n.ts.surrender }}</MkButton>
+ <MkButton v-else full @click="restart">{{ i18n.ts.gameRetry }}</MkButton>
</div>
</div>
</div>
@@ -1313,38 +1327,6 @@ definePageMetadata(() => ({
max-width: 100%;
}
-.frame {
- padding: 7px;
- background: #8C4F26;
- box-shadow: 0 6px 16px #0007, 0 0 1px 1px #693410, inset 0 0 2px 1px #ce8a5c;
- border-radius: 10px;
-}
-
-.frameH {
- display: flex;
- gap: 6px;
-}
-
-.frameInner {
- padding: 8px;
- margin-top: 8px;
- background: #F1E8DC;
- box-shadow: 0 0 2px 1px #ce8a5c, inset 0 0 1px 1px #693410;
- border-radius: 6px;
- color: #693410;
-
- &:first-child {
- margin-top: 0;
- }
-}
-
-.frameDivider {
- height: 0;
- border: none;
- border-top: 1px solid #693410;
- border-bottom: 1px solid #ce8a5c;
-}
-
.header {
position: relative;
z-index: 10;
diff --git a/packages/frontend/src/pages/drop-and-fusion.vue b/packages/frontend/src/pages/drop-and-fusion.vue
index 1b11457988..54352c9b0d 100644
--- a/packages/frontend/src/pages/drop-and-fusion.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.vue
@@ -15,13 +15,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer v-if="!gameStarted" :contentMax="800">
<div :class="$style.root">
<div class="_gaps">
- <div :class="$style.frame" style="text-align: center;">
- <div :class="$style.frameInner">
+ <div class="_woodenFrame" style="text-align: center;">
+ <div class="_woodenFrameInner">
<img src="/client-assets/drop-and-fusion/logo.png" style="display: block; max-width: 100%; max-height: 200px; margin: auto;"/>
</div>
</div>
- <div :class="$style.frame" style="text-align: center;">
- <div :class="$style.frameInner">
+ <div class="_woodenFrame" style="text-align: center;">
+ <div class="_woodenFrameInner">
<div class="_gaps" style="padding: 16px;">
<MkSelect v-model="gameMode">
<option value="normal">NORMAL</option>
@@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkButton primary gradate large rounded inline @click="start">{{ i18n.ts.start }}</MkButton>
</div>
</div>
- <div :class="$style.frameInner">
+ <div class="_woodenFrameInner">
<div class="_gaps" style="padding: 16px;">
<div style="font-size: 90%;"><i class="ti ti-music"></i> {{ i18n.ts.soundWillBePlayed }}</div>
<MkSwitch v-model="mute">
@@ -42,10 +42,10 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
</div>
- <div :class="$style.frame">
- <div :class="$style.frameInner">
+ <div class="_woodenFrame">
+ <div class="_woodenFrameInner">
<div class="_gaps_s" style="padding: 16px;">
- <div><b>{{ i18n.tsx.lastNDays({ n: 7 }) }} {{ i18n.ts.ranking }}</b> ({{ gameMode }})</div>
+ <div><b>{{ i18n.tsx.lastNDays({ n: 7 }) }} {{ i18n.ts.ranking }}</b> ({{ gameMode.toUpperCase() }})</div>
<div v-if="ranking" class="_gaps_s">
<div v-for="r in ranking" :key="r.id" :class="$style.rankingRecord">
<MkAvatar :link="true" style="width: 24px; height: 24px; margin-right: 4px;" :user="r.user"/>
@@ -57,8 +57,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
</div>
- <div :class="$style.frame">
- <div :class="$style.frameInner" style="padding: 16px;">
+ <div class="_woodenFrame">
+ <div class="_woodenFrameInner" style="padding: 16px;">
<div style="font-weight: bold;">{{ i18n.ts._bubbleGame.howToPlay }}</div>
<ol>
<li>{{ i18n.ts._bubbleGame._howToPlay.section1 }}</li>
@@ -67,8 +67,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</ol>
</div>
</div>
- <div :class="$style.frame">
- <div :class="$style.frameInner">
+ <div class="_woodenFrame">
+ <div class="_woodenFrameInner">
<div class="_gaps_s" style="padding: 16px;">
<div><b>Credit</b></div>
<div>
@@ -149,38 +149,6 @@ definePageMetadata(() => ({
}
}
-.frame {
- padding: 7px;
- background: #8C4F26;
- box-shadow: 0 6px 16px #0007, 0 0 1px 1px #693410, inset 0 0 2px 1px #ce8a5c;
- border-radius: 10px;
-}
-
-.frameH {
- display: flex;
- gap: 6px;
-}
-
-.frameInner {
- padding: 8px;
- margin-top: 8px;
- background: #F1E8DC;
- box-shadow: 0 0 2px 1px #ce8a5c, inset 0 0 1px 1px #693410;
- border-radius: 6px;
- color: #693410;
-
- &:first-child {
- margin-top: 0;
- }
-}
-
-.frameDivider {
- height: 0;
- border: none;
- border-top: 1px solid #693410;
- border-bottom: 1px solid #ce8a5c;
-}
-
.rankingRecord {
display: flex;
line-height: 24px;
diff --git a/packages/frontend/src/pages/emoji-edit-dialog.vue b/packages/frontend/src/pages/emoji-edit-dialog.vue
index 12e9416f72..16769ef360 100644
--- a/packages/frontend/src/pages/emoji-edit-dialog.vue
+++ b/packages/frontend/src/pages/emoji-edit-dialog.vue
@@ -135,7 +135,7 @@ async function addRole() {
const { canceled, result: role } = await os.select({
items: roles.filter(r => r.isPublic).filter(r => !currentRoleIds.includes(r.id)).map(r => ({ text: r.name, value: r })),
});
- if (canceled) return;
+ if (canceled || role == null) return;
rolesThatCanBeUsedThisEmojiAsReaction.value.push(role);
}
diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue
index 2f1557182a..cb7fe2866c 100644
--- a/packages/frontend/src/pages/instance-info.vue
+++ b/packages/frontend/src/pages/instance-info.vue
@@ -39,6 +39,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="isBlocked" :disabled="!meta || !instance" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch>
<MkSwitch v-model="isSilenced" :disabled="!meta || !instance" @update:modelValue="toggleSilenced">{{ i18n.ts.silenceThisInstance }}</MkSwitch>
<MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton>
+ <MkTextarea v-model="moderationNote" manualSave>
+ <template #label>{{ i18n.ts.moderationNote }}</template>
+ </MkTextarea>
</div>
</FormSection>
@@ -119,7 +122,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
-import { ref, computed } from 'vue';
+import { ref, computed, watch } from 'vue';
import * as Misskey from 'misskey-js';
import MkChart from '@/components/MkChart.vue';
import MkObjectView from '@/components/MkObjectView.vue';
@@ -141,6 +144,7 @@ import MkPagination from '@/components/MkPagination.vue';
import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue';
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy.js';
import { dateString } from '@/filters/date.js';
+import MkTextarea from '@/components/MkTextarea.vue';
const props = defineProps<{
host: string;
@@ -155,6 +159,7 @@ const suspended = ref(false);
const isBlocked = ref(false);
const isSilenced = ref(false);
const faviconUrl = ref<string | null>(null);
+const moderationNote = ref('');
const usersPagination = {
endpoint: iAmModerator ? 'admin/show-users' : 'users' as const,
@@ -167,6 +172,10 @@ const usersPagination = {
offsetMode: true,
};
+watch(moderationNote, async () => {
+ await misskeyApi('admin/federation/update-instance', { host: instance.value.host, moderationNote: moderationNote.value });
+});
+
async function fetch(): Promise<void> {
if (iAmAdmin) {
meta.value = await misskeyApi('admin/meta');
@@ -178,6 +187,7 @@ async function fetch(): Promise<void> {
isBlocked.value = instance.value?.isBlocked ?? false;
isSilenced.value = instance.value?.isSilenced ?? false;
faviconUrl.value = getProxiedImageUrlNullable(instance.value?.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.value?.iconUrl, 'preview');
+ moderationNote.value = instance.value?.moderationNote;
}
async function toggleBlock(): Promise<void> {
diff --git a/packages/frontend/src/pages/notifications.vue b/packages/frontend/src/pages/notifications.vue
index 7db6fa5395..28f5838296 100644
--- a/packages/frontend/src/pages/notifications.vue
+++ b/packages/frontend/src/pages/notifications.vue
@@ -52,7 +52,7 @@ const directNotesPagination = {
function setFilter(ev) {
const typeItems = notificationTypes.map(t => ({
text: i18n.ts._notification._types[t],
- active: includeTypes.value && includeTypes.value.includes(t),
+ active: (includeTypes.value && includeTypes.value.includes(t)) ?? false,
action: () => {
includeTypes.value = [t];
},
@@ -63,7 +63,7 @@ function setFilter(ev) {
action: () => {
includeTypes.value = null;
},
- }, { type: 'divider' }, ...typeItems] : typeItems;
+ }, { type: 'divider' as const }, ...typeItems] : typeItems;
os.popupMenu(items, ev.currentTarget ?? ev.target);
}
diff --git a/packages/frontend/src/pages/reversi/game.board.vue b/packages/frontend/src/pages/reversi/game.board.vue
index cf7cec6b5e..5259dfa29a 100644
--- a/packages/frontend/src/pages/reversi/game.board.vue
+++ b/packages/frontend/src/pages/reversi/game.board.vue
@@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
- <div :class="$style.board">
+ <div class="_woodenFrame">
<div :class="$style.boardInner">
<div v-if="showBoardLabels" :class="$style.labelsX">
<span v-for="i in game.map[0].length" :key="i" :class="$style.labelsXLabel">{{ String.fromCharCode(64 + i) }}</span>
@@ -124,8 +124,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkFolder>
<template #label>{{ i18n.ts.options }}</template>
<div class="_gaps_s" style="text-align: left;">
- <MkSwitch v-model="showBoardLabels">Show labels</MkSwitch>
- <MkSwitch v-model="useAvatarAsStone">useAvatarAsStone</MkSwitch>
+ <MkSwitch v-model="showBoardLabels">{{ i18n.ts._reversi.showBoardLabels }}</MkSwitch>
+ <MkSwitch v-model="useAvatarAsStone">{{ i18n.ts._reversi.useAvatarAsStone }}</MkSwitch>
</div>
</MkFolder>
@@ -248,7 +248,7 @@ if (game.value.isStarted && !game.value.isEnded) {
crc32: crc32.toString(),
}).then((res) => {
if (res.desynced) {
- console.log('resynced');
+ if (_DEV_) console.log('resynced');
restoreGame(res.game!);
}
});
@@ -500,17 +500,6 @@ $gap: 4px;
text-align: center;
}
-.board {
- width: 100%;
- box-sizing: border-box;
- margin: 0 auto;
-
- padding: 7px;
- background: #8C4F26;
- box-shadow: 0 6px 16px #0007, 0 0 1px 1px #693410, inset 0 0 2px 1px #ce8a5c;
- border-radius: 12px;
-}
-
.boardInner {
padding: 32px;
diff --git a/packages/frontend/src/pages/settings/drive.vue b/packages/frontend/src/pages/settings/drive.vue
index cd38f9850f..1919f80864 100644
--- a/packages/frontend/src/pages/settings/drive.vue
+++ b/packages/frontend/src/pages/settings/drive.vue
@@ -113,7 +113,7 @@ if (defaultStore.state.uploadFolder) {
function chooseUploadFolder() {
os.selectDriveFolder(false).then(async folder => {
- defaultStore.set('uploadFolder', folder ? folder.id : null);
+ defaultStore.set('uploadFolder', folder[0] ? folder[0].id : null);
os.success();
if (defaultStore.state.uploadFolder) {
uploadFolder.value = await misskeyApi('drive/folders/show', {
diff --git a/packages/frontend/src/pages/settings/emoji-picker.vue b/packages/frontend/src/pages/settings/emoji-picker.vue
index 79969427ec..ce296ec183 100644
--- a/packages/frontend/src/pages/settings/emoji-picker.vue
+++ b/packages/frontend/src/pages/settings/emoji-picker.vue
@@ -213,7 +213,7 @@ async function pickEmoji(itemsRef: Ref<string[]>, ev: MouseEvent) {
os.pickEmoji(getHTMLElement(ev), {
showPinned: false,
}).then(it => {
- const emoji = it as string;
+ const emoji = it;
if (!itemsRef.value.includes(emoji)) {
itemsRef.value.push(emoji);
}
diff --git a/packages/frontend/src/pages/settings/notifications.notification-config.vue b/packages/frontend/src/pages/settings/notifications.notification-config.vue
index d6aac63674..a36f036303 100644
--- a/packages/frontend/src/pages/settings/notifications.notification-config.vue
+++ b/packages/frontend/src/pages/settings/notifications.notification-config.vue
@@ -10,6 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<option value="following">{{ i18n.ts.following }}</option>
<option value="follower">{{ i18n.ts.followers }}</option>
<option value="mutualFollow">{{ i18n.ts.mutualFollow }}</option>
+ <option value="followingOrFollower">{{ i18n.ts.followingOrFollower }}</option>
<option value="list">{{ i18n.ts.userList }}</option>
<option value="never">{{ i18n.ts.none }}</option>
</MkSelect>
diff --git a/packages/frontend/src/pages/settings/notifications.vue b/packages/frontend/src/pages/settings/notifications.vue
index febcfa32ed..70db6a5109 100644
--- a/packages/frontend/src/pages/settings/notifications.vue
+++ b/packages/frontend/src/pages/settings/notifications.vue
@@ -16,6 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
$i.notificationRecieveConfig[type]?.type === 'following' ? i18n.ts.following :
$i.notificationRecieveConfig[type]?.type === 'follower' ? i18n.ts.followers :
$i.notificationRecieveConfig[type]?.type === 'mutualFollow' ? i18n.ts.mutualFollow :
+ $i.notificationRecieveConfig[type]?.type === 'followingOrFollower' ? i18n.ts.followingOrFollower :
$i.notificationRecieveConfig[type]?.type === 'list' ? i18n.ts.userList :
i18n.ts.all
}}
@@ -34,6 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<FormSection>
<div class="_gaps_m">
<FormLink @click="testNotification">{{ i18n.ts._notification.sendTestNotification }}</FormLink>
+ <FormLink @click="flushNotification">{{ i18n.ts._notification.flushNotification }}</FormLink>
</div>
</FormSection>
<FormSection>
@@ -113,6 +115,17 @@ function testNotification(): void {
misskeyApi('notifications/test-notification');
}
+async function flushNotification() {
+ const { canceled } = await os.confirm({
+ type: 'warning',
+ text: i18n.ts.resetAreYouSure,
+ });
+
+ if (canceled) return;
+
+ os.apiWithDialog('notifications/flush');
+}
+
const headerActions = computed(() => []);
const headerTabs = computed(() => []);
diff --git a/packages/frontend/src/pages/settings/preferences-backups.vue b/packages/frontend/src/pages/settings/preferences-backups.vue
index 676159d1b5..942de19d82 100644
--- a/packages/frontend/src/pages/settings/preferences-backups.vue
+++ b/packages/frontend/src/pages/settings/preferences-backups.vue
@@ -203,6 +203,7 @@ async function saveNew(): Promise<void> {
const { canceled, result: name } = await os.inputText({
title: ts._preferencesBackups.inputName,
+ default: '',
});
if (canceled) return;
@@ -371,6 +372,7 @@ async function rename(id: string): Promise<void> {
const { canceled: cancel1, result: name } = await os.inputText({
title: ts._preferencesBackups.inputName,
+ default: '',
});
if (cancel1 || profiles.value[id].name === name) return;
diff --git a/packages/frontend/src/scripts/autocomplete.ts b/packages/frontend/src/scripts/autocomplete.ts
index fe515d81a1..9fc8f7843e 100644
--- a/packages/frontend/src/scripts/autocomplete.ts
+++ b/packages/frontend/src/scripts/autocomplete.ts
@@ -93,9 +93,11 @@ export class Autocomplete {
return;
}
+ const afterLastMfmParam = text.split(/\$\[[a-zA-Z]+/).pop();
+
const isMention = mentionIndex !== -1;
const isHashtag = hashtagIndex !== -1;
- const isMfmParam = mfmParamIndex !== -1 && text.split(/\$\[[a-zA-Z]+/).pop()?.includes('.');
+ const isMfmParam = mfmParamIndex !== -1 && afterLastMfmParam?.includes('.') && !afterLastMfmParam?.includes(' ');
const isMfmTag = mfmTagIndex !== -1 && !isMfmParam;
const isEmoji = emojiIndex !== -1 && text.split(/:[a-z0-9_+\-]+:/).pop()!.includes(':');
diff --git a/packages/frontend/src/scripts/check-reaction-permissions.ts b/packages/frontend/src/scripts/check-reaction-permissions.ts
index c9d2a5bfc6..da704717c1 100644
--- a/packages/frontend/src/scripts/check-reaction-permissions.ts
+++ b/packages/frontend/src/scripts/check-reaction-permissions.ts
@@ -1,6 +1,10 @@
import * as Misskey from 'misskey-js';
+import { UnicodeEmojiDef } from './emojilist.js';
-export function checkReactionPermissions(me: Misskey.entities.MeDetailed, note: Misskey.entities.Note, emoji: Misskey.entities.EmojiSimple): boolean {
+export function checkReactionPermissions(me: Misskey.entities.MeDetailed, note: Misskey.entities.Note, emoji: Misskey.entities.EmojiSimple | UnicodeEmojiDef): boolean {
+ if ('char' in emoji) return true; // UnicodeEmojiDefãªã‚‰å¸¸ã«ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³å¯èƒ½
+
+ emoji = emoji as Misskey.entities.EmojiSimple;
const roleIdsThatCanBeUsedThisEmojiAsReaction = emoji.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [];
return !(emoji.localOnly && note.user.host !== me.host)
&& !(emoji.isSensitive && (note.reactionAcceptance === 'nonSensitiveOnly' || note.reactionAcceptance === 'nonSensitiveOnlyForLocalLikeOnlyForRemote'))
diff --git a/packages/frontend/src/scripts/clear-cache.ts b/packages/frontend/src/scripts/clear-cache.ts
index f2db87c4fb..b20109ec72 100644
--- a/packages/frontend/src/scripts/clear-cache.ts
+++ b/packages/frontend/src/scripts/clear-cache.ts
@@ -2,14 +2,18 @@ import { unisonReload } from '@/scripts/unison-reload.js';
import * as os from '@/os.js';
import { miLocalStorage } from '@/local-storage.js';
import { fetchCustomEmojis } from '@/custom-emojis.js';
+import { fetchInstance } from '@/instance.js';
export async function clearCache() {
os.waiting();
+ miLocalStorage.removeItem('instance');
+ miLocalStorage.removeItem('instanceCachedAt');
miLocalStorage.removeItem('locale');
miLocalStorage.removeItem('localeVersion');
miLocalStorage.removeItem('theme');
miLocalStorage.removeItem('emojis');
miLocalStorage.removeItem('lastEmojisFetchedAt');
+ await fetchInstance(true);
await fetchCustomEmojis(true);
unisonReload();
}
diff --git a/packages/frontend/src/scripts/emojilist.ts b/packages/frontend/src/scripts/emojilist.ts
index 54d45e025f..f2fbeae0ed 100644
--- a/packages/frontend/src/scripts/emojilist.ts
+++ b/packages/frontend/src/scripts/emojilist.ts
@@ -20,6 +20,10 @@ export const emojilist: UnicodeEmojiDef[] = _emojilist.map(x => ({
category: unicodeEmojiCategories[x[2]],
}));
+const unicodeEmojisMap = new Map<string, UnicodeEmojiDef>(
+ emojilist.map(x => [x.char, x]),
+);
+
const _indexByChar = new Map<string, number>();
const _charGroupByCategory = new Map<string, string[]>();
for (let i = 0; i < emojilist.length; i++) {
@@ -35,6 +39,11 @@ for (let i = 0; i < emojilist.length; i++) {
export const emojiCharByCategory = _charGroupByCategory;
+export function getUnicodeEmoji(char: string): UnicodeEmojiDef | null {
+ // Colorize it because emojilist.json assumes that
+ return unicodeEmojisMap.get(colorizeEmoji(char)) ?? null;
+}
+
export function getEmojiName(char: string): string | null {
// Colorize it because emojilist.json assumes that
const idx = _indexByChar.get(colorizeEmoji(char));
diff --git a/packages/frontend/src/scripts/form.ts b/packages/frontend/src/scripts/form.ts
index 26a027f461..b0db404f28 100644
--- a/packages/frontend/src/scripts/form.ts
+++ b/packages/frontend/src/scripts/form.ts
@@ -12,29 +12,37 @@ export type FormItem = {
label?: string;
type: 'string';
default: string | null;
+ description?: string;
+ required?: boolean;
hidden?: boolean;
multiline?: boolean;
+ treatAsMfm?: boolean;
} | {
label?: string;
type: 'number';
default: number | null;
+ description?: string;
+ required?: boolean;
hidden?: boolean;
step?: number;
} | {
label?: string;
type: 'boolean';
default: boolean | null;
+ description?: string;
hidden?: boolean;
} | {
label?: string;
type: 'enum';
default: string | null;
+ required?: boolean;
hidden?: boolean;
enum: EnumItem[];
} | {
label?: string;
type: 'radio';
default: unknown | null;
+ required?: boolean;
hidden?: boolean;
options: {
label: string;
@@ -44,9 +52,12 @@ export type FormItem = {
label?: string;
type: 'range';
default: number | null;
- step: number;
+ description?: string;
+ required?: boolean;
+ step?: number;
min: number;
max: number;
+ textConverter?: (value: number) => string;
} | {
label?: string;
type: 'object';
@@ -57,6 +68,10 @@ export type FormItem = {
type: 'array';
default: unknown[] | null;
hidden: boolean;
+} | {
+ type: 'button';
+ content?: string;
+ action: (ev: MouseEvent, v: any) => void;
};
export type Form = Record<string, FormItem>;
diff --git a/packages/frontend/src/scripts/search-emoji.ts b/packages/frontend/src/scripts/search-emoji.ts
new file mode 100644
index 0000000000..371f69b9a7
--- /dev/null
+++ b/packages/frontend/src/scripts/search-emoji.ts
@@ -0,0 +1,106 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export type EmojiDef = {
+ emoji: string;
+ name: string;
+ url: string;
+ aliasOf?: string;
+} | {
+ emoji: string;
+ name: string;
+ aliasOf?: string;
+ isCustomEmoji?: true;
+};
+type EmojiScore = { emoji: EmojiDef, score: number };
+
+export function searchEmoji(query: string | null, emojiDb: EmojiDef[], max = 30): EmojiDef[] {
+ if (!query) {
+ return [];
+ }
+
+ const matched = new Map<string, EmojiScore>();
+ // 完全一致(エイリアスãªã—)
+ emojiDb.some(x => {
+ if (x.name === query && !x.aliasOf) {
+ matched.set(x.name, { emoji: x, score: query.length + 3 });
+ }
+ return matched.size === max;
+ });
+
+ // 完全一致(エイリアス込ã¿ï¼‰
+ if (matched.size < max) {
+ emojiDb.some(x => {
+ if (x.name === query && !matched.has(x.aliasOf ?? x.name)) {
+ matched.set(x.aliasOf ?? x.name, { emoji: x, score: query.length + 2 });
+ }
+ return matched.size === max;
+ });
+ }
+
+ // 剿–¹ä¸€è‡´ï¼ˆã‚¨ã‚¤ãƒªã‚¢ã‚¹ãªã—)
+ if (matched.size < max) {
+ emojiDb.some(x => {
+ if (x.name.startsWith(query) && !x.aliasOf && !matched.has(x.name)) {
+ matched.set(x.name, { emoji: x, score: query.length + 1 });
+ }
+ return matched.size === max;
+ });
+ }
+
+ // 剿–¹ä¸€è‡´ï¼ˆã‚¨ã‚¤ãƒªã‚¢ã‚¹è¾¼ã¿ï¼‰
+ if (matched.size < max) {
+ emojiDb.some(x => {
+ if (x.name.startsWith(query) && !matched.has(x.aliasOf ?? x.name)) {
+ matched.set(x.aliasOf ?? x.name, { emoji: x, score: query.length });
+ }
+ return matched.size === max;
+ });
+ }
+
+ // 部分一致(エイリアス込ã¿ï¼‰
+ if (matched.size < max) {
+ emojiDb.some(x => {
+ if (x.name.includes(query) && !matched.has(x.aliasOf ?? x.name)) {
+ matched.set(x.aliasOf ?? x.name, { emoji: x, score: query.length - 1 });
+ }
+ return matched.size === max;
+ });
+ }
+
+ // 簡易ã‚ã„ã¾ã„検索(3文字以上)
+ if (matched.size < max && query.length > 3) {
+ const queryChars = [...query];
+ const hitEmojis = new Map<string, EmojiScore>();
+
+ for (const x of emojiDb) {
+ // 文字列ã®ä½ç½®ã‚’進ã‚ãªãŒã‚‰ã€ã‚¯ã‚¨ãƒªã®æ–‡å­—ã‚’é †ç•ªã«æŽ¢ã™
+
+ let pos = 0;
+ let hit = 0;
+ for (const c of queryChars) {
+ pos = x.name.indexOf(c, pos);
+ if (pos <= -1) break;
+ hit++;
+ }
+
+ // åŠåˆ†ä»¥ä¸Šã®æ–‡å­—ãŒå«ã¾ã‚Œã¦ã„れã°ãƒ’ットã¨ã™ã‚‹
+ if (hit > Math.ceil(queryChars.length / 2) && hit - 2 > (matched.get(x.aliasOf ?? x.name)?.score ?? 0)) {
+ hitEmojis.set(x.aliasOf ?? x.name, { emoji: x, score: hit - 2 });
+ }
+ }
+
+ // ヒットã—ãŸã‚‚ã®ã‚’全部追加ã™ã‚‹ã¨é›‘多ã«ãªã‚‹ã®ã§ã€å…ˆé ­ã®6件程度ã ã‘ã«ã—ã¦ãŠã(6ä»¶ï¼ã‚ªãƒ¼ãƒˆã‚³ãƒ³ãƒ—リートã®ãƒãƒƒãƒ—アップã®ã‚µã‚¤ã‚ºåˆ†ï¼‰
+ [...hitEmojis.values()]
+ .sort((x, y) => y.score - x.score)
+ .slice(0, 6)
+ .forEach(it => matched.set(it.emoji.name, it));
+ }
+
+ return [...matched.values()]
+ .sort((x, y) => y.score - x.score)
+ .slice(0, max)
+ .map(it => it.emoji);
+}
diff --git a/packages/frontend/src/scripts/sound.ts b/packages/frontend/src/scripts/sound.ts
index 9555579e0d..fcd59510df 100644
--- a/packages/frontend/src/scripts/sound.ts
+++ b/packages/frontend/src/scripts/sound.ts
@@ -126,7 +126,7 @@ export async function loadAudio(url: string, options?: { useCache?: boolean; })
*/
export function playMisskeySfx(operationType: OperationType) {
const sound = defaultStore.state[`sound_${operationType}`];
- if (sound.type == null || !canPlay) return;
+ if (sound.type == null || !canPlay || ('userActivation' in navigator && !navigator.userActivation.hasBeenActive)) return;
canPlay = false;
playMisskeySfxFile(sound).finally(() => {
diff --git a/packages/frontend/src/style.scss b/packages/frontend/src/style.scss
index cbec377277..0951a7d98d 100644
--- a/packages/frontend/src/style.scss
+++ b/packages/frontend/src/style.scss
@@ -417,6 +417,39 @@ rt {
transition-timing-function: cubic-bezier(0,.5,.5,1);
}
+._woodenFrame {
+ padding: 7px;
+ background: #8C4F26;
+ box-shadow: 0 6px 16px #0007, 0 0 1px 1px #693410, inset 0 0 2px 1px #ce8a5c;
+ border-radius: 10px;
+
+ --bg: #F1E8DC;
+ --panel: #fff;
+ --fg: #693410;
+ --switchOffBg: rgba(0, 0, 0, 0.1);
+ --switchOffFg: rgb(255, 255, 255);
+ --switchOnBg: var(--accent);
+ --switchOnFg: rgb(255, 255, 255);
+}
+
+._woodenFrameH {
+ display: flex;
+ gap: 6px;
+}
+
+._woodenFrameInner {
+ padding: 8px;
+ margin-top: 8px;
+ background: var(--bg);
+ box-shadow: 0 0 2px 1px #ce8a5c, inset 0 0 1px 1px #693410;
+ border-radius: 6px;
+ color: var(--fg);
+
+ &:first-child {
+ margin-top: 0;
+ }
+}
+
._transition_zoom-enter-active, ._transition_zoom-leave-active {
transition: opacity 0.5s, transform 0.5s !important;
}
diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue
index 92d2e23d9b..bdb62dca15 100644
--- a/packages/frontend/src/ui/deck.vue
+++ b/packages/frontend/src/ui/deck.vue
@@ -117,6 +117,7 @@ import XMentionsColumn from '@/ui/deck/mentions-column.vue';
import XDirectColumn from '@/ui/deck/direct-column.vue';
import XRoleTimelineColumn from '@/ui/deck/role-timeline-column.vue';
import { mainRouter } from '@/router/main.js';
+import { MenuItem } from '@/types/menu.js';
const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue'));
const XAnnouncements = defineAsyncComponent(() => import('@/ui/_common_/announcements.vue'));
@@ -221,21 +222,19 @@ document.documentElement.style.scrollBehavior = 'auto';
loadDeck();
function changeProfile(ev: MouseEvent) {
- const items = ref([{
+ let items: MenuItem[] = [{
text: deckStore.state.profile,
- active: true.valueOf,
- }]);
+ active: true,
+ action: () => {},
+ }];
getProfiles().then(profiles => {
- items.value = [{
- text: deckStore.state.profile,
- active: true.valueOf,
- }, ...(profiles.filter(k => k !== deckStore.state.profile).map(k => ({
+ items.push(...(profiles.filter(k => k !== deckStore.state.profile).map(k => ({
text: k,
action: () => {
deckStore.set('profile', k);
unisonReload();
},
- }))), { type: 'divider' }, {
+ }))), { type: 'divider' as const }, {
text: i18n.ts._deck.newProfile,
icon: 'ti ti-plus',
action: async () => {
@@ -248,9 +247,10 @@ function changeProfile(ev: MouseEvent) {
deckStore.set('profile', name);
unisonReload();
},
- }];
+ });
+ }).then(() => {
+ os.popupMenu(items, ev.currentTarget ?? ev.target);
});
- os.popupMenu(items, ev.currentTarget ?? ev.target);
}
async function deleteProfile() {
diff --git a/packages/frontend/src/ui/deck/channel-column.vue b/packages/frontend/src/ui/deck/channel-column.vue
index 125c85130e..bd3b059497 100644
--- a/packages/frontend/src/ui/deck/channel-column.vue
+++ b/packages/frontend/src/ui/deck/channel-column.vue
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template v-if="column.channelId">
<div style="padding: 8px; text-align: center;">
- <MkButton primary gradate rounded inline @click="post"><i class="ti ti-pencil"></i></MkButton>
+ <MkButton primary gradate rounded inline small @click="post"><i class="ti ti-pencil"></i></MkButton>
</div>
<MkTimeline ref="timeline" src="channel" :channel="column.channelId"/>
</template>
diff --git a/packages/frontend/src/widgets/WidgetSlideshow.vue b/packages/frontend/src/widgets/WidgetSlideshow.vue
index 7a3671a240..b8efd3bda9 100644
--- a/packages/frontend/src/widgets/WidgetSlideshow.vue
+++ b/packages/frontend/src/widgets/WidgetSlideshow.vue
@@ -93,10 +93,10 @@ const fetch = () => {
const choose = () => {
os.selectDriveFolder(false).then(folder => {
- if (folder == null) {
+ if (folder[0] == null) {
return;
}
- widgetProps.folderId = folder.id;
+ widgetProps.folderId = folder[0].id;
save();
fetch();
});
diff --git a/packages/frontend/test/autocomplete.test.ts b/packages/frontend/test/autocomplete.test.ts
new file mode 100644
index 0000000000..394ac3a821
--- /dev/null
+++ b/packages/frontend/test/autocomplete.test.ts
@@ -0,0 +1,34 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { assert, describe, test } from 'vitest';
+import { searchEmoji } from '@/scripts/search-emoji.js';
+
+describe('emoji autocomplete', () => {
+ test('åå‰ã®å®Œå…¨ä¸€è‡´ã¯åå‰ã®å‰æ–¹ä¸€è‡´ã‚ˆã‚Šå„ªå…ˆã•れる', async () => {
+ const result = searchEmoji('foooo', [{ emoji: ':foooo:', name: 'foooo' }, { emoji: ':foooobaaar:', name: 'foooobaaar' }]);
+ assert.equal(result[0].emoji, ':foooo:');
+ });
+
+ test('åå‰ã®å‰æ–¹ä¸€è‡´ã¯åå‰ã®éƒ¨åˆ†ä¸€è‡´ã‚ˆã‚Šå„ªå…ˆã•れる', async () => {
+ const result = searchEmoji('baaa', [{ emoji: ':baaar:', name: 'baaar' }, { emoji: ':foooobaaar:', name: 'foooobaaar' }]);
+ assert.equal(result[0].emoji, ':baaar:');
+ });
+
+ test('åå‰ã®å®Œå…¨ä¸€è‡´ã¯ã‚¿ã‚°ã®å®Œå…¨ä¸€è‡´ã‚ˆã‚Šå„ªå…ˆã•れる', async () => {
+ const result = searchEmoji('foooo', [{ emoji: ':foooo:', name: 'foooo' }, { emoji: ':baaar:', name: 'foooo', aliasOf: 'baaar' }]);
+ assert.equal(result[0].emoji, ':foooo:');
+ });
+
+ test('åå‰ã®å‰æ–¹ä¸€è‡´ã¯ã‚¿ã‚°ã®å‰æ–¹ä¸€è‡´ã‚ˆã‚Šå„ªå…ˆã•れる', async () => {
+ const result = searchEmoji('foo', [{ emoji: ':foooo:', name: 'foooo' }, { emoji: ':baaar:', name: 'foooo', aliasOf: 'baaar' }]);
+ assert.equal(result[0].emoji, ':foooo:');
+ });
+
+ test('åå‰ã®éƒ¨åˆ†ä¸€è‡´ã¯ã‚¿ã‚°ã®éƒ¨åˆ†ä¸€è‡´ã‚ˆã‚Šå„ªå…ˆã•れる', async () => {
+ const result = searchEmoji('oooo', [{ emoji: ':foooo:', name: 'foooo' }, { emoji: ':baaar:', name: 'foooo', aliasOf: 'baaar' }]);
+ assert.equal(result[0].emoji, ':foooo:');
+ });
+});
diff --git a/packages/frontend/test/scroll.test.ts b/packages/frontend/test/scroll.test.ts
index e49ec270d5..a0b56b7221 100644
--- a/packages/frontend/test/scroll.test.ts
+++ b/packages/frontend/test/scroll.test.ts
@@ -9,6 +9,7 @@ import { onScrollBottom, onScrollTop } from '@/scripts/scroll.js';
describe('Scroll', () => {
describe('onScrollTop', () => {
+ /* 動作ã—ãªã„(happy-domã®ãƒã‚°ï¼Ÿ)
test('Initial onScrollTop callback for connected elements', () => {
const { document } = new Window();
const div = document.createElement('div');
@@ -21,6 +22,7 @@ describe('Scroll', () => {
assert.ok(called);
});
+ */
test('No onScrollTop callback for disconnected elements', () => {
const { document } = new Window();
@@ -35,11 +37,11 @@ describe('Scroll', () => {
});
describe('onScrollBottom', () => {
+ /* 動作ã—ãªã„(happy-domã®ãƒã‚°ï¼Ÿ)
test('Initial onScrollBottom callback for connected elements', () => {
const { document } = new Window();
const div = document.createElement('div');
assert.strictEqual(div.scrollTop, 0);
- (div as any).scrollHeight = 100; // happy-dom has no scrollHeight
document.body.append(div);
@@ -48,12 +50,12 @@ describe('Scroll', () => {
assert.ok(called);
});
+ */
test('No onScrollBottom callback for disconnected elements', () => {
const { document } = new Window();
const div = document.createElement('div');
assert.strictEqual(div.scrollTop, 0);
- (div as any).scrollHeight = 100; // happy-dom has no scrollHeight
let called = false;
onScrollBottom(div as any as HTMLElement, () => called = true);
diff --git a/packages/misskey-bubble-game/package.json b/packages/misskey-bubble-game/package.json
index 9de7ba005f..ddc4c2134b 100644
--- a/packages/misskey-bubble-game/package.json
+++ b/packages/misskey-bubble-game/package.json
@@ -29,9 +29,9 @@
"@types/matter-js": "0.19.6",
"@types/node": "20.11.5",
"@types/seedrandom": "3.0.8",
- "@typescript-eslint/eslint-plugin": "6.18.1",
- "@typescript-eslint/parser": "6.18.1",
- "eslint": "8.56.0",
+ "@typescript-eslint/eslint-plugin": "7.1.0",
+ "@typescript-eslint/parser": "7.1.0",
+ "eslint": "8.57.0",
"nodemon": "3.0.2",
"typescript": "5.3.3"
},
diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md
index f362f0b34e..2237d278f4 100644
--- a/packages/misskey-js/etc/misskey-js.api.md
+++ b/packages/misskey-js/etc/misskey-js.api.md
@@ -125,6 +125,9 @@ type AdminEmojiAddAliasesBulkRequest = operations['admin/emoji/add-aliases-bulk'
type AdminEmojiAddRequest = operations['admin/emoji/add']['requestBody']['content']['application/json'];
// @public (undocumented)
+type AdminEmojiAddResponse = operations['admin/emoji/add']['responses']['200']['content']['application/json'];
+
+// @public (undocumented)
type AdminEmojiCopyRequest = operations['admin/emoji/copy']['requestBody']['content']['application/json'];
// @public (undocumented)
@@ -527,6 +530,7 @@ export type Channels = {
unreadNotification: (payload: Notification_2) => void;
unreadMention: (payload: Note['id']) => void;
readAllUnreadMentions: () => void;
+ notificationFlushed: () => void;
unreadSpecifiedNote: (payload: Note['id']) => void;
readAllUnreadSpecifiedNotes: () => void;
readAllAntennas: () => void;
@@ -1154,6 +1158,7 @@ declare namespace entities {
AdminDriveShowFileResponse,
AdminEmojiAddAliasesBulkRequest,
AdminEmojiAddRequest,
+ AdminEmojiAddResponse,
AdminEmojiCopyRequest,
AdminEmojiCopyResponse,
AdminEmojiDeleteBulkRequest,
@@ -1708,6 +1713,7 @@ declare namespace entities {
RoleCondFormulaLogics,
RoleCondFormulaValueNot,
RoleCondFormulaValueIsLocalOrRemote,
+ RoleCondFormulaValueAssignedRole,
RoleCondFormulaValueCreated,
RoleCondFormulaFollowersOrFollowingOrNotes,
RoleCondFormulaValue,
@@ -1715,7 +1721,10 @@ declare namespace entities {
Role,
RolePolicies,
ReversiGameLite,
- ReversiGameDetailed
+ ReversiGameDetailed,
+ MetaLite,
+ MetaDetailedOnly,
+ MetaDetailed
}
}
export { entities }
@@ -2224,6 +2233,15 @@ type MeDetailed = components['schemas']['MeDetailed'];
type MeDetailedOnly = components['schemas']['MeDetailedOnly'];
// @public (undocumented)
+type MetaDetailed = components['schemas']['MetaDetailed'];
+
+// @public (undocumented)
+type MetaDetailedOnly = components['schemas']['MetaDetailedOnly'];
+
+// @public (undocumented)
+type MetaLite = components['schemas']['MetaLite'];
+
+// @public (undocumented)
type MetaRequest = operations['meta']['requestBody']['content']['application/json'];
// @public (undocumented)
@@ -2317,6 +2335,9 @@ type ModerationLog = {
type: 'unsuspendRemoteInstance';
info: ModerationLogPayloads['unsuspendRemoteInstance'];
} | {
+ type: 'updateRemoteInstanceNote';
+ info: ModerationLogPayloads['updateRemoteInstanceNote'];
+} | {
type: 'markSensitiveDriveFile';
info: ModerationLogPayloads['markSensitiveDriveFile'];
} | {
@@ -2355,7 +2376,7 @@ type ModerationLog = {
});
// @public (undocumented)
-export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "unsuspend", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration", "unsetUserAvatar", "unsetUserBanner"];
+export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "unsuspend", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance", "updateRemoteInstanceNote", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration", "unsetUserAvatar", "unsetUserBanner"];
// @public (undocumented)
type MuteCreateRequest = operations['mute/create']['requestBody']['content']['application/json'];
@@ -2713,6 +2734,9 @@ type RoleCondFormulaLogics = components['schemas']['RoleCondFormulaLogics'];
type RoleCondFormulaValue = components['schemas']['RoleCondFormulaValue'];
// @public (undocumented)
+type RoleCondFormulaValueAssignedRole = components['schemas']['RoleCondFormulaValueAssignedRole'];
+
+// @public (undocumented)
type RoleCondFormulaValueCreated = components['schemas']['RoleCondFormulaValueCreated'];
// @public (undocumented)
diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json
index 051c63cbe1..a7c629119c 100644
--- a/packages/misskey-js/package.json
+++ b/packages/misskey-js/package.json
@@ -1,7 +1,7 @@
{
"type": "module",
"name": "misskey-js",
- "version": "2024.2.0",
+ "version": "2024.3.0",
"description": "Misskey SDK for JavaScript",
"types": "./built/dts/index.d.ts",
"exports": {
@@ -38,18 +38,18 @@
"@microsoft/api-extractor": "7.39.1",
"@misskey-dev/eslint-plugin": "1.0.0",
"@swc/jest": "0.2.31",
- "@types/jest": "29.5.11",
- "@types/node": "20.11.17",
- "@typescript-eslint/eslint-plugin": "6.18.1",
- "@typescript-eslint/parser": "6.18.1",
- "eslint": "8.56.0",
+ "@types/jest": "29.5.12",
+ "@types/node": "20.11.22",
+ "@typescript-eslint/eslint-plugin": "7.1.0",
+ "@typescript-eslint/parser": "7.1.0",
+ "eslint": "8.57.0",
"jest": "29.7.0",
"jest-fetch-mock": "3.0.3",
"jest-websocket-mock": "2.5.0",
"mock-socket": "9.3.1",
"ncp": "2.0.0",
- "nodemon": "3.0.3",
- "tsd": "0.30.4",
+ "nodemon": "3.1.0",
+ "tsd": "0.30.7",
"typescript": "5.3.3"
},
"files": [
diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts
index d27413810c..5309350100 100644
--- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts
+++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts
@@ -3200,6 +3200,17 @@ declare module '../api.js' {
*
* **Credential required**: *Yes* / **Permission**: *write:notifications*
*/
+ request<E extends 'notifications/flush', P extends Endpoints[E]['req']>(
+ endpoint: E,
+ params: P,
+ credential?: string | null,
+ ): Promise<SwitchCaseResponseType<E, P>>;
+
+ /**
+ * No description provided.
+ *
+ * **Credential required**: *Yes* / **Permission**: *write:notifications*
+ */
request<E extends 'notifications/mark-all-as-read', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts
index 595d0d66c0..b0982e1e55 100644
--- a/packages/misskey-js/src/autogen/endpoint.ts
+++ b/packages/misskey-js/src/autogen/endpoint.ts
@@ -35,6 +35,7 @@ import type {
AdminDriveShowFileResponse,
AdminEmojiAddAliasesBulkRequest,
AdminEmojiAddRequest,
+ AdminEmojiAddResponse,
AdminEmojiCopyRequest,
AdminEmojiCopyResponse,
AdminEmojiDeleteBulkRequest,
@@ -578,7 +579,7 @@ export type Endpoints = {
'admin/drive/files': { req: AdminDriveFilesRequest; res: AdminDriveFilesResponse };
'admin/drive/show-file': { req: AdminDriveShowFileRequest; res: AdminDriveShowFileResponse };
'admin/emoji/add-aliases-bulk': { req: AdminEmojiAddAliasesBulkRequest; res: EmptyResponse };
- 'admin/emoji/add': { req: AdminEmojiAddRequest; res: EmptyResponse };
+ 'admin/emoji/add': { req: AdminEmojiAddRequest; res: AdminEmojiAddResponse };
'admin/emoji/copy': { req: AdminEmojiCopyRequest; res: AdminEmojiCopyResponse };
'admin/emoji/delete-bulk': { req: AdminEmojiDeleteBulkRequest; res: EmptyResponse };
'admin/emoji/delete': { req: AdminEmojiDeleteRequest; res: EmptyResponse };
@@ -840,6 +841,7 @@ export type Endpoints = {
'notes/unrenote': { req: NotesUnrenoteRequest; res: EmptyResponse };
'notes/user-list-timeline': { req: NotesUserListTimelineRequest; res: NotesUserListTimelineResponse };
'notifications/create': { req: NotificationsCreateRequest; res: EmptyResponse };
+ 'notifications/flush': { req: EmptyRequest; res: EmptyResponse };
'notifications/mark-all-as-read': { req: EmptyRequest; res: EmptyResponse };
'notifications/test-notification': { req: EmptyRequest; res: EmptyResponse };
'page-push': { req: PagePushRequest; res: EmptyResponse };
diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts
index e7ed146c43..a936931e99 100644
--- a/packages/misskey-js/src/autogen/entities.ts
+++ b/packages/misskey-js/src/autogen/entities.ts
@@ -37,6 +37,7 @@ export type AdminDriveShowFileRequest = operations['admin/drive/show-file']['req
export type AdminDriveShowFileResponse = operations['admin/drive/show-file']['responses']['200']['content']['application/json'];
export type AdminEmojiAddAliasesBulkRequest = operations['admin/emoji/add-aliases-bulk']['requestBody']['content']['application/json'];
export type AdminEmojiAddRequest = operations['admin/emoji/add']['requestBody']['content']['application/json'];
+export type AdminEmojiAddResponse = operations['admin/emoji/add']['responses']['200']['content']['application/json'];
export type AdminEmojiCopyRequest = operations['admin/emoji/copy']['requestBody']['content']['application/json'];
export type AdminEmojiCopyResponse = operations['admin/emoji/copy']['responses']['200']['content']['application/json'];
export type AdminEmojiDeleteBulkRequest = operations['admin/emoji/delete-bulk']['requestBody']['content']['application/json'];
diff --git a/packages/misskey-js/src/autogen/models.ts b/packages/misskey-js/src/autogen/models.ts
index 6400567a2d..6f61458600 100644
--- a/packages/misskey-js/src/autogen/models.ts
+++ b/packages/misskey-js/src/autogen/models.ts
@@ -38,6 +38,7 @@ export type Signin = components['schemas']['Signin'];
export type RoleCondFormulaLogics = components['schemas']['RoleCondFormulaLogics'];
export type RoleCondFormulaValueNot = components['schemas']['RoleCondFormulaValueNot'];
export type RoleCondFormulaValueIsLocalOrRemote = components['schemas']['RoleCondFormulaValueIsLocalOrRemote'];
+export type RoleCondFormulaValueAssignedRole = components['schemas']['RoleCondFormulaValueAssignedRole'];
export type RoleCondFormulaValueCreated = components['schemas']['RoleCondFormulaValueCreated'];
export type RoleCondFormulaFollowersOrFollowingOrNotes = components['schemas']['RoleCondFormulaFollowersOrFollowingOrNotes'];
export type RoleCondFormulaValue = components['schemas']['RoleCondFormulaValue'];
@@ -46,3 +47,6 @@ export type Role = components['schemas']['Role'];
export type RolePolicies = components['schemas']['RolePolicies'];
export type ReversiGameLite = components['schemas']['ReversiGameLite'];
export type ReversiGameDetailed = components['schemas']['ReversiGameDetailed'];
+export type MetaLite = components['schemas']['MetaLite'];
+export type MetaDetailedOnly = components['schemas']['MetaDetailedOnly'];
+export type MetaDetailed = components['schemas']['MetaDetailed'];
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index d0d8573b40..b1e6a194f9 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -2770,6 +2770,15 @@ export type paths = {
*/
post: operations['notifications/create'];
};
+ '/notifications/flush': {
+ /**
+ * notifications/flush
+ * @description No description provided.
+ *
+ * **Credential required**: *Yes* / **Permission**: *write:notifications*
+ */
+ post: operations['notifications/flush'];
+ };
'/notifications/mark-all-as-read': {
/**
* notifications/mark-all-as-read
@@ -3588,7 +3597,9 @@ export type components = {
faviconUrl: string | null;
themeColor: string | null;
};
- emojis: Record<string, never>;
+ emojis: {
+ [key: string]: string;
+ };
/** @enum {string} */
onlineStatus: 'unknown' | 'online' | 'active' | 'offline';
badgeRoles?: ({
@@ -3698,7 +3709,7 @@ export type components = {
notificationRecieveConfig: {
note?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3707,7 +3718,7 @@ export type components = {
}]>;
follow?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3716,7 +3727,7 @@ export type components = {
}]>;
mention?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3725,7 +3736,7 @@ export type components = {
}]>;
reply?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3734,7 +3745,7 @@ export type components = {
}]>;
renote?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3743,7 +3754,7 @@ export type components = {
}]>;
quote?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3752,7 +3763,7 @@ export type components = {
}]>;
reaction?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3761,7 +3772,7 @@ export type components = {
}]>;
pollEnded?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3770,7 +3781,7 @@ export type components = {
}]>;
receiveFollowRequest?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3779,7 +3790,7 @@ export type components = {
}]>;
followRequestAccepted?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3788,7 +3799,7 @@ export type components = {
}]>;
roleAssigned?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3797,7 +3808,7 @@ export type components = {
}]>;
achievementEarned?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3806,7 +3817,7 @@ export type components = {
}]>;
app?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -3815,7 +3826,7 @@ export type components = {
}]>;
test?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -4480,6 +4491,7 @@ export type components = {
infoUpdatedAt: string | null;
/** Format: date-time */
latestRequestReceivedAt: string | null;
+ moderationNote?: string | null;
};
GalleryPost: {
/**
@@ -4570,6 +4582,16 @@ export type components = {
/** @enum {string} */
type: 'isLocal' | 'isRemote';
};
+ RoleCondFormulaValueAssignedRole: {
+ id: string;
+ /** @enum {string} */
+ type: 'roleAssignedTo';
+ /**
+ * Format: id
+ * @example xxxxxxxxxx
+ */
+ roleId: string;
+ };
RoleCondFormulaValueCreated: {
id: string;
/** @enum {string} */
@@ -4582,7 +4604,7 @@ export type components = {
type: 'followersLessThanOrEq' | 'followersMoreThanOrEq' | 'followingLessThanOrEq' | 'followingMoreThanOrEq' | 'notesLessThanOrEq' | 'notesMoreThanOrEq';
value: number;
};
- RoleCondFormulaValue: components['schemas']['RoleCondFormulaLogics'] | components['schemas']['RoleCondFormulaValueNot'] | components['schemas']['RoleCondFormulaValueIsLocalOrRemote'] | components['schemas']['RoleCondFormulaValueCreated'] | components['schemas']['RoleCondFormulaFollowersOrFollowingOrNotes'];
+ RoleCondFormulaValue: components['schemas']['RoleCondFormulaLogics'] | components['schemas']['RoleCondFormulaValueNot'] | components['schemas']['RoleCondFormulaValueIsLocalOrRemote'] | components['schemas']['RoleCondFormulaValueAssignedRole'] | components['schemas']['RoleCondFormulaValueCreated'] | components['schemas']['RoleCondFormulaFollowersOrFollowingOrNotes'];
RoleLite: {
/**
* Format: id
@@ -4631,6 +4653,7 @@ export type components = {
gtlAvailable: boolean;
ltlAvailable: boolean;
canPublicNote: boolean;
+ mentionLimit: number;
canInvite: boolean;
inviteLimit: number;
inviteLimitCycle: number;
@@ -4723,6 +4746,96 @@ export type components = {
logs: number[][];
map: string[];
};
+ MetaLite: {
+ maintainerName: string | null;
+ maintainerEmail: string | null;
+ version: string;
+ providesTarball: boolean;
+ name: string | null;
+ shortName: string | null;
+ /**
+ * Format: url
+ * @example https://misskey.example.com
+ */
+ uri: string;
+ description: string | null;
+ langs: string[];
+ tosUrl: string | null;
+ /** @default https://github.com/misskey-dev/misskey */
+ repositoryUrl: string | null;
+ /** @default https://github.com/misskey-dev/misskey/issues/new */
+ feedbackUrl: string | null;
+ defaultDarkTheme: string | null;
+ defaultLightTheme: string | null;
+ disableRegistration: boolean;
+ emailRequiredForSignup: boolean;
+ enableHcaptcha: boolean;
+ hcaptchaSiteKey: string | null;
+ enableMcaptcha: boolean;
+ mcaptchaSiteKey: string | null;
+ mcaptchaInstanceUrl: string | null;
+ enableRecaptcha: boolean;
+ recaptchaSiteKey: string | null;
+ enableTurnstile: boolean;
+ turnstileSiteKey: string | null;
+ swPublickey: string | null;
+ /** @default /assets/ai.png */
+ mascotImageUrl: string;
+ bannerUrl: string | null;
+ serverErrorImageUrl: string | null;
+ infoImageUrl: string | null;
+ notFoundImageUrl: string | null;
+ iconUrl: string | null;
+ maxNoteTextLength: number;
+ ads: {
+ /**
+ * Format: id
+ * @example xxxxxxxxxx
+ */
+ id: string;
+ /** Format: url */
+ url: string;
+ place: string;
+ ratio: number;
+ /** Format: url */
+ imageUrl: string;
+ dayOfWeek: number;
+ }[];
+ /** @default 0 */
+ notesPerOneAd: number;
+ enableEmail: boolean;
+ enableServiceWorker: boolean;
+ translatorAvailable: boolean;
+ mediaProxy: string;
+ backgroundImageUrl: string | null;
+ impressumUrl: string | null;
+ logoImageUrl: string | null;
+ privacyPolicyUrl: string | null;
+ serverRules: string[];
+ themeColor: string | null;
+ policies: components['schemas']['RolePolicies'];
+ };
+ MetaDetailedOnly: {
+ features?: {
+ registration: boolean;
+ emailRequiredForSignup: boolean;
+ localTimeline: boolean;
+ globalTimeline: boolean;
+ hcaptcha: boolean;
+ turnstile: boolean;
+ recaptcha: boolean;
+ objectStorage: boolean;
+ serviceWorker: boolean;
+ /** @default true */
+ miauth?: boolean;
+ };
+ proxyAccountName: string | null;
+ /** @example false */
+ requireSetup: boolean;
+ cacheRemoteFiles: boolean;
+ cacheRemoteSensitiveFiles: boolean;
+ };
+ MetaDetailed: components['schemas']['MetaLite'] & components['schemas']['MetaDetailedOnly'];
};
responses: never;
parameters: never;
@@ -6385,9 +6498,11 @@ export type operations = {
};
};
responses: {
- /** @description OK (without any results) */
- 204: {
- content: never;
+ /** @description OK (with results) */
+ 200: {
+ content: {
+ 'application/json': components['schemas']['EmojiDetailed'];
+ };
};
/** @description Client error */
400: {
@@ -6998,13 +7113,13 @@ export type operations = {
content: {
'application/json': {
/** Format: misskey:id */
- id: string;
- name: string;
+ id?: string;
+ name?: string;
/** Format: misskey:id */
fileId?: string;
/** @description Use `null` to reset the category. */
category?: string | null;
- aliases: string[];
+ aliases?: string[];
license?: string | null;
isSensitive?: boolean;
localOnly?: boolean;
@@ -7213,7 +7328,8 @@ export type operations = {
content: {
'application/json': {
host: string;
- isSuspended: boolean;
+ isSuspended?: boolean;
+ moderationNote?: string;
};
};
};
@@ -8331,7 +8447,7 @@ export type operations = {
notificationRecieveConfig: {
note?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8340,7 +8456,7 @@ export type operations = {
}]>;
follow?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8349,7 +8465,7 @@ export type operations = {
}]>;
mention?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8358,7 +8474,7 @@ export type operations = {
}]>;
reply?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8367,7 +8483,7 @@ export type operations = {
}]>;
renote?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8376,7 +8492,7 @@ export type operations = {
}]>;
quote?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8385,7 +8501,7 @@ export type operations = {
}]>;
reaction?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8394,7 +8510,7 @@ export type operations = {
}]>;
pollEnded?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8403,7 +8519,7 @@ export type operations = {
}]>;
receiveFollowRequest?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8412,7 +8528,7 @@ export type operations = {
}]>;
followRequestAccepted?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8421,7 +8537,7 @@ export type operations = {
}]>;
roleAssigned?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8430,7 +8546,7 @@ export type operations = {
}]>;
achievementEarned?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8439,7 +8555,7 @@ export type operations = {
}]>;
app?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -8448,7 +8564,7 @@ export type operations = {
}]>;
test?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -17582,8 +17698,8 @@ export type operations = {
untilId?: string;
/** @default true */
markAsRead?: boolean;
- includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
- excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
+ includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[];
+ excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[];
};
};
};
@@ -18682,7 +18798,7 @@ export type operations = {
notificationRecieveConfig?: {
note?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18691,7 +18807,7 @@ export type operations = {
}]>;
follow?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18700,7 +18816,7 @@ export type operations = {
}]>;
mention?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18709,7 +18825,7 @@ export type operations = {
}]>;
reply?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18718,7 +18834,7 @@ export type operations = {
}]>;
renote?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18727,7 +18843,7 @@ export type operations = {
}]>;
quote?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18736,7 +18852,7 @@ export type operations = {
}]>;
reaction?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18745,7 +18861,7 @@ export type operations = {
}]>;
pollEnded?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18754,7 +18870,7 @@ export type operations = {
}]>;
receiveFollowRequest?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18763,7 +18879,7 @@ export type operations = {
}]>;
followRequestAccepted?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18772,7 +18888,7 @@ export type operations = {
}]>;
roleAssigned?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18781,7 +18897,7 @@ export type operations = {
}]>;
achievementEarned?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18790,7 +18906,7 @@ export type operations = {
}]>;
app?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -18799,7 +18915,7 @@ export type operations = {
}]>;
test?: OneOf<[{
/** @enum {string} */
- type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'never';
+ type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'followingOrFollower' | 'never';
}, {
/** @enum {string} */
type: 'list';
@@ -19446,91 +19562,7 @@ export type operations = {
/** @description OK (with results) */
200: {
content: {
- 'application/json': {
- maintainerName: string | null;
- maintainerEmail: string | null;
- version: string;
- providesTarball: boolean;
- name: string;
- shortName: string | null;
- /**
- * Format: url
- * @example https://misskey.example.com
- */
- uri: string;
- description: string | null;
- langs: string[];
- tosUrl: string | null;
- /** @default https://github.com/misskey-dev/misskey */
- repositoryUrl: string | null;
- /** @default https://github.com/misskey-dev/misskey/issues/new */
- feedbackUrl: string | null;
- defaultDarkTheme: string | null;
- defaultLightTheme: string | null;
- disableRegistration: boolean;
- cacheRemoteFiles: boolean;
- cacheRemoteSensitiveFiles: boolean;
- emailRequiredForSignup: boolean;
- enableHcaptcha: boolean;
- hcaptchaSiteKey: string | null;
- enableMcaptcha: boolean;
- mcaptchaSiteKey: string | null;
- mcaptchaInstanceUrl: string | null;
- enableRecaptcha: boolean;
- recaptchaSiteKey: string | null;
- enableTurnstile: boolean;
- turnstileSiteKey: string | null;
- swPublickey: string | null;
- /** @default /assets/ai.png */
- mascotImageUrl: string;
- bannerUrl: string;
- serverErrorImageUrl: string | null;
- infoImageUrl: string | null;
- notFoundImageUrl: string | null;
- iconUrl: string | null;
- maxNoteTextLength: number;
- ads: {
- /**
- * Format: id
- * @example xxxxxxxxxx
- */
- id: string;
- /** Format: url */
- url: string;
- place: string;
- ratio: number;
- /** Format: url */
- imageUrl: string;
- dayOfWeek: number;
- }[];
- /** @default 0 */
- notesPerOneAd: number;
- /** @example false */
- requireSetup: boolean;
- enableEmail: boolean;
- enableServiceWorker: boolean;
- translatorAvailable: boolean;
- proxyAccountName: string | null;
- mediaProxy: string;
- features?: {
- registration: boolean;
- localTimeline: boolean;
- globalTimeline: boolean;
- hcaptcha: boolean;
- recaptcha: boolean;
- objectStorage: boolean;
- serviceWorker: boolean;
- /** @default true */
- miauth?: boolean;
- };
- backgroundImageUrl: string | null;
- impressumUrl: string | null;
- logoImageUrl: string | null;
- privacyPolicyUrl: string | null;
- serverRules: string[];
- themeColor: string | null;
- policies: components['schemas']['RolePolicies'];
- };
+ 'application/json': components['schemas']['MetaLite'] | components['schemas']['MetaDetailed'];
};
};
/** @description Client error */
@@ -22036,6 +22068,50 @@ export type operations = {
};
};
/**
+ * notifications/flush
+ * @description No description provided.
+ *
+ * **Credential required**: *Yes* / **Permission**: *write:notifications*
+ */
+ 'notifications/flush': {
+ responses: {
+ /** @description OK (without any results) */
+ 204: {
+ content: never;
+ };
+ /** @description Client error */
+ 400: {
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
+ /** @description Authentication error */
+ 401: {
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
+ /** @description Forbidden error */
+ 403: {
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
+ /** @description I'm Ai */
+ 418: {
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
+ /** @description Internal server error */
+ 500: {
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
+ };
+ };
+ /**
* notifications/mark-all-as-read
* @description No description provided.
*
@@ -22925,10 +23001,10 @@ export type operations = {
'application/json': {
/** Format: misskey:id */
flashId: string;
- title: string;
- summary: string;
- script: string;
- permissions: string[];
+ title?: string;
+ summary?: string;
+ script?: string;
+ permissions?: string[];
/** @enum {string} */
visibility?: 'public' | 'private';
};
diff --git a/packages/misskey-js/src/consts.ts b/packages/misskey-js/src/consts.ts
index 0e446c1215..b690621e98 100644
--- a/packages/misskey-js/src/consts.ts
+++ b/packages/misskey-js/src/consts.ts
@@ -121,6 +121,7 @@ export const moderationLogTypes = [
'resetPassword',
'suspendRemoteInstance',
'unsuspendRemoteInstance',
+ 'updateRemoteInstanceNote',
'markSensitiveDriveFile',
'unmarkSensitiveDriveFile',
'resolveAbuseReport',
@@ -261,6 +262,12 @@ export type ModerationLogPayloads = {
id: string;
host: string;
};
+ updateRemoteInstanceNote: {
+ id: string;
+ host: string;
+ before: string | null;
+ after: string | null;
+ };
markSensitiveDriveFile: {
fileId: string;
fileUserId: string | null;
diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts
index 772d2bbfa1..35503d6d6f 100644
--- a/packages/misskey-js/src/entities.ts
+++ b/packages/misskey-js/src/entities.ts
@@ -96,6 +96,9 @@ export type ModerationLog = {
type: 'unsuspendRemoteInstance';
info: ModerationLogPayloads['unsuspendRemoteInstance'];
} | {
+ type: 'updateRemoteInstanceNote';
+ info: ModerationLogPayloads['updateRemoteInstanceNote'];
+} | {
type: 'markSensitiveDriveFile';
info: ModerationLogPayloads['markSensitiveDriveFile'];
} | {
diff --git a/packages/misskey-js/src/streaming.types.ts b/packages/misskey-js/src/streaming.types.ts
index 0ba5715d68..9a86e03d69 100644
--- a/packages/misskey-js/src/streaming.types.ts
+++ b/packages/misskey-js/src/streaming.types.ts
@@ -40,6 +40,7 @@ export type Channels = {
unreadNotification: (payload: Notification) => void;
unreadMention: (payload: Note['id']) => void;
readAllUnreadMentions: () => void;
+ notificationFlushed: () => void;
unreadSpecifiedNote: (payload: Note['id']) => void;
readAllUnreadSpecifiedNotes: () => void;
readAllAntennas: () => void;
diff --git a/packages/misskey-reversi/package.json b/packages/misskey-reversi/package.json
index 52d497d3f8..7bfc890fef 100644
--- a/packages/misskey-reversi/package.json
+++ b/packages/misskey-reversi/package.json
@@ -27,9 +27,9 @@
"devDependencies": {
"@misskey-dev/eslint-plugin": "1.0.0",
"@types/node": "20.11.5",
- "@typescript-eslint/eslint-plugin": "6.18.1",
- "@typescript-eslint/parser": "6.18.1",
- "eslint": "8.56.0",
+ "@typescript-eslint/eslint-plugin": "7.1.0",
+ "@typescript-eslint/parser": "7.1.0",
+ "eslint": "8.57.0",
"nodemon": "3.0.2",
"typescript": "5.3.3"
},
diff --git a/packages/sw/package.json b/packages/sw/package.json
index 244a676e86..bac0cc1ff5 100644
--- a/packages/sw/package.json
+++ b/packages/sw/package.json
@@ -15,11 +15,11 @@
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "1.0.0",
- "@typescript-eslint/parser": "6.18.1",
+ "@typescript-eslint/parser": "7.1.0",
"@typescript/lib-webworker": "npm:@types/serviceworker@0.0.67",
- "eslint": "8.56.0",
+ "eslint": "8.57.0",
"eslint-plugin-import": "2.29.1",
- "nodemon": "3.0.3",
+ "nodemon": "3.1.0",
"typescript": "5.3.3"
},
"type": "module"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f89f8a417d..5e29c1162b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -13,8 +13,8 @@ importers:
.:
dependencies:
cssnano:
- specifier: 6.0.3
- version: 6.0.3(postcss@8.4.33)
+ specifier: 6.0.5
+ version: 6.0.5(postcss@8.4.35)
execa:
specifier: 8.0.1
version: 8.0.1
@@ -28,14 +28,14 @@ importers:
specifier: 4.1.0
version: 4.1.0
postcss:
- specifier: 8.4.33
- version: 8.4.33
+ specifier: 8.4.35
+ version: 8.4.35
tar:
specifier: 6.2.0
version: 6.2.0
terser:
- specifier: 5.27.0
- version: 5.27.0
+ specifier: 5.28.1
+ version: 5.28.1
typescript:
specifier: 5.3.3
version: 5.3.3
@@ -45,20 +45,20 @@ importers:
version: 4.4.0
devDependencies:
'@typescript-eslint/eslint-plugin':
- specifier: 6.18.1
- version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/parser':
- specifier: 6.18.1
- version: 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(eslint@8.57.0)(typescript@5.3.3)
cross-env:
specifier: 7.0.3
version: 7.0.3
cypress:
- specifier: 13.6.3
- version: 13.6.3
+ specifier: 13.6.6
+ version: 13.6.6
eslint:
- specifier: 8.56.0
- version: 8.56.0
+ specifier: 8.57.0
+ version: 8.57.0
ncp:
specifier: 2.0.0
version: 2.0.0
@@ -75,14 +75,14 @@ importers:
specifier: 3.412.0
version: 3.412.0(@aws-sdk/client-s3@3.412.0)
'@bull-board/api':
- specifier: 5.14.0
- version: 5.14.0(@bull-board/ui@5.14.0)
+ specifier: 5.14.2
+ version: 5.14.2(@bull-board/ui@5.14.2)
'@bull-board/fastify':
- specifier: 5.14.0
- version: 5.14.0
+ specifier: 5.14.2
+ version: 5.14.2
'@bull-board/ui':
- specifier: 5.14.0
- version: 5.14.0
+ specifier: 5.14.2
+ version: 5.14.2
'@discordapp/twemoji':
specifier: 15.0.2
version: 15.0.2
@@ -111,26 +111,26 @@ importers:
specifier: 8.2.0
version: 8.2.0
'@misskey-dev/sharp-read-bmp':
- specifier: ^1.1.1
- version: 1.1.1
+ specifier: 1.2.0
+ version: 1.2.0
'@misskey-dev/summaly':
- specifier: ^5.0.3
+ specifier: 5.0.3
version: 5.0.3
'@nestjs/common':
- specifier: 10.2.10
- version: 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
+ specifier: 10.3.3
+ version: 10.3.3(reflect-metadata@0.2.1)(rxjs@7.8.1)
'@nestjs/core':
- specifier: 10.2.10
- version: 10.2.10(@nestjs/common@10.2.10)(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)
+ specifier: 10.3.3
+ version: 10.3.3(@nestjs/common@10.3.3)(@nestjs/platform-express@10.3.3)(reflect-metadata@0.2.1)(rxjs@7.8.1)
'@nestjs/testing':
- specifier: 10.2.10
- version: 10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(@nestjs/platform-express@10.3.1)
+ specifier: 10.3.3
+ version: 10.3.3(@nestjs/common@10.3.3)(@nestjs/core@10.3.3)(@nestjs/platform-express@10.3.3)
'@peertube/http-signature':
specifier: 1.7.0
version: 1.7.0
'@simplewebauthn/server':
- specifier: 9.0.2
- version: 9.0.2
+ specifier: 9.0.3
+ version: 9.0.3
'@sinonjs/fake-timers':
specifier: 11.2.2
version: 11.2.2
@@ -168,8 +168,8 @@ importers:
specifier: 1.20.2
version: 1.20.2
bullmq:
- specifier: 5.1.9
- version: 5.1.9
+ specifier: 5.4.0
+ version: 5.4.0
cacheable-lookup:
specifier: 7.0.0
version: 7.0.0
@@ -219,17 +219,20 @@ importers:
specifier: 4.0.0
version: 4.0.0
got:
- specifier: 14.1.0
- version: 14.1.0
+ specifier: 14.2.0
+ version: 14.2.0
happy-dom:
specifier: 10.0.3
version: 10.0.3
hpagent:
specifier: 1.2.0
version: 1.2.0
- http-link-header:
+ htmlescape:
specifier: 1.1.1
version: 1.1.1
+ http-link-header:
+ specifier: 1.1.2
+ version: 1.1.2
ioredis:
specifier: 5.3.2
version: 5.3.2
@@ -255,8 +258,8 @@ importers:
specifier: 8.3.2
version: 8.3.2
jsrsasign:
- specifier: 11.0.0
- version: 11.0.0
+ specifier: 11.1.0
+ version: 11.1.0
meilisearch:
specifier: 0.37.0
version: 0.37.0
@@ -279,8 +282,8 @@ importers:
specifier: 3.0.0-canary.1
version: 3.0.0-canary.1
nanoid:
- specifier: 5.0.4
- version: 5.0.4
+ specifier: 5.0.6
+ version: 5.0.6
nested-property:
specifier: 4.0.0
version: 4.0.0
@@ -288,8 +291,8 @@ importers:
specifier: 3.3.2
version: 3.3.2
nodemailer:
- specifier: 6.9.8
- version: 6.9.8
+ specifier: 6.9.10
+ version: 6.9.10
nsfwjs:
specifier: 2.4.2
version: 2.4.2(@tensorflow/tfjs@4.4.0)
@@ -348,8 +351,8 @@ importers:
specifier: 0.1.4
version: 0.1.4
reflect-metadata:
- specifier: 0.1.14
- version: 0.1.14
+ specifier: 0.2.1
+ version: 0.2.1
rename:
specifier: 1.0.4
version: 1.0.4
@@ -360,14 +363,14 @@ importers:
specifier: 7.8.1
version: 7.8.1
sanitize-html:
- specifier: 2.11.0
- version: 2.11.0
+ specifier: 2.12.1
+ version: 2.12.1
secure-json-parse:
specifier: 2.7.0
version: 2.7.0
sharp:
- specifier: 0.32.6
- version: 0.32.6
+ specifier: 0.33.2
+ version: 0.33.2
slacc:
specifier: 0.0.10
version: 0.0.10
@@ -378,14 +381,14 @@ importers:
specifier: 2.1.0
version: 2.1.0
systeminformation:
- specifier: 5.21.24
- version: 5.21.24
+ specifier: 5.22.0
+ version: 5.22.0
tinycolor2:
specifier: 1.6.0
version: 1.6.0
tmp:
- specifier: 0.2.1
- version: 0.2.1
+ specifier: 0.2.2
+ version: 0.2.2
tsc-alias:
specifier: 1.8.8
version: 1.8.8
@@ -507,10 +510,10 @@ importers:
version: 29.7.0
'@misskey-dev/eslint-plugin':
specifier: 1.0.0
- version: 1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@6.18.1)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
+ version: 1.0.0(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
'@nestjs/platform-express':
- specifier: 10.3.1
- version: 10.3.1(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)
+ specifier: 10.3.3
+ version: 10.3.3(@nestjs/common@10.3.3)(@nestjs/core@10.3.3)
'@simplewebauthn/types':
specifier: 9.0.1
version: 9.0.1
@@ -538,6 +541,9 @@ importers:
'@types/fluent-ffmpeg':
specifier: 2.1.24
version: 2.1.24
+ '@types/htmlescape':
+ specifier: ^1.1.3
+ version: 1.1.3
'@types/http-link-header':
specifier: 1.0.5
version: 1.0.5
@@ -563,8 +569,8 @@ importers:
specifier: 0.7.34
version: 0.7.34
'@types/node':
- specifier: 20.11.17
- version: 20.11.17
+ specifier: 20.11.22
+ version: 20.11.22
'@types/node-fetch':
specifier: 3.0.3
version: 3.0.3
@@ -581,14 +587,14 @@ importers:
specifier: 0.1.2
version: 0.1.2
'@types/pg':
- specifier: 8.11.0
- version: 8.11.0
+ specifier: 8.11.2
+ version: 8.11.2
'@types/pug':
specifier: 2.0.10
version: 2.0.10
'@types/punycode':
- specifier: 2.1.3
- version: 2.1.3
+ specifier: 2.1.4
+ version: 2.1.4
'@types/qrcode':
specifier: 1.5.5
version: 1.5.5
@@ -602,11 +608,11 @@ importers:
specifier: 1.0.7
version: 1.0.7
'@types/sanitize-html':
- specifier: 2.9.5
- version: 2.9.5
+ specifier: 2.11.0
+ version: 2.11.0
'@types/semver':
- specifier: 7.5.6
- version: 7.5.6
+ specifier: 7.5.8
+ version: 7.5.8
'@types/simple-oauth2':
specifier: 5.0.7
version: 5.0.7
@@ -629,11 +635,11 @@ importers:
specifier: 8.5.10
version: 8.5.10
'@typescript-eslint/eslint-plugin':
- specifier: 6.18.1
- version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/parser':
- specifier: 6.18.1
- version: 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(eslint@8.57.0)(typescript@5.3.3)
aws-sdk-client-mock:
specifier: 3.0.1
version: 3.0.1
@@ -641,11 +647,11 @@ importers:
specifier: 7.0.3
version: 7.0.3
eslint:
- specifier: 8.56.0
- version: 8.56.0
+ specifier: 8.57.0
+ version: 8.57.0
eslint-plugin-import:
specifier: 2.29.1
- version: 2.29.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)
+ version: 2.29.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)
execa:
specifier: 8.0.1
version: 8.0.1
@@ -654,13 +660,13 @@ importers:
version: 9.0.0
jest:
specifier: 29.7.0
- version: 29.7.0(@types/node@20.11.17)
+ version: 29.7.0(@types/node@20.11.22)
jest-mock:
specifier: 29.7.0
version: 29.7.0
nodemon:
- specifier: 3.0.3
- version: 3.0.3
+ specifier: 3.1.0
+ version: 3.1.0
pid-port:
specifier: 1.0.0
version: 1.0.0
@@ -684,13 +690,13 @@ importers:
version: 2024.1.0
'@rollup/plugin-json':
specifier: 6.1.0
- version: 6.1.0(rollup@4.9.6)
+ version: 6.1.0(rollup@4.12.0)
'@rollup/plugin-replace':
specifier: 5.0.5
- version: 5.0.5(rollup@4.9.6)
+ version: 5.0.5(rollup@4.12.0)
'@rollup/pluginutils':
specifier: 5.1.0
- version: 5.1.0(rollup@4.9.6)
+ version: 5.1.0(rollup@4.12.0)
'@syuilo/aiscript':
specifier: 0.17.0
version: 0.17.0
@@ -701,11 +707,11 @@ importers:
specifier: 15.0.0
version: 15.0.0
'@vitejs/plugin-vue':
- specifier: 5.0.3
- version: 5.0.3(vite@5.1.0)(vue@3.4.18)
+ specifier: 5.0.4
+ version: 5.0.4(vite@5.1.4)(vue@3.4.21)
'@vue/compiler-sfc':
- specifier: 3.4.18
- version: 3.4.18
+ specifier: 3.4.21
+ version: 3.4.21
aiscript-vscode:
specifier: github:aiscript-dev/aiscript-vscode#v0.1.2
version: github.com/aiscript-dev/aiscript-vscode/793211d40243c8775f6b85f015c221c82cbffb07
@@ -719,26 +725,26 @@ importers:
specifier: 0.0.1
version: 0.0.1
canvas-confetti:
- specifier: 1.6.1
- version: 1.6.1
+ specifier: 1.9.2
+ version: 1.9.2
chart.js:
- specifier: 4.4.1
- version: 4.4.1
+ specifier: 4.4.2
+ version: 4.4.2
chartjs-adapter-date-fns:
specifier: 3.0.0
- version: 3.0.0(chart.js@4.4.1)(date-fns@2.30.0)
+ version: 3.0.0(chart.js@4.4.2)(date-fns@2.30.0)
chartjs-chart-matrix:
specifier: 2.0.1
- version: 2.0.1(chart.js@4.4.1)
+ version: 2.0.1(chart.js@4.4.2)
chartjs-plugin-gradient:
specifier: 0.6.1
- version: 0.6.1(chart.js@4.4.1)
+ version: 0.6.1(chart.js@4.4.2)
chartjs-plugin-zoom:
specifier: 2.0.1
- version: 2.0.1(chart.js@4.4.1)
+ version: 2.0.1(chart.js@4.4.2)
chromatic:
- specifier: 10.6.1
- version: 10.6.1
+ specifier: 11.0.0
+ version: 11.0.0
compare-versions:
specifier: 6.1.0
version: 6.1.0
@@ -791,17 +797,17 @@ importers:
specifier: 2.3.1
version: 2.3.1
rollup:
- specifier: 4.9.6
- version: 4.9.6
+ specifier: 4.12.0
+ version: 4.12.0
sanitize-html:
- specifier: 2.11.0
- version: 2.11.0
+ specifier: 2.12.1
+ version: 2.12.1
sass:
- specifier: 1.70.0
- version: 1.70.0
+ specifier: 1.71.1
+ version: 1.71.1
shiki:
- specifier: 1.0.0-beta.3
- version: 1.0.0-beta.3
+ specifier: 1.1.7
+ version: 1.1.7
strict-event-emitter-types:
specifier: 2.0.0
version: 2.0.0
@@ -809,8 +815,8 @@ importers:
specifier: 3.1.0
version: 3.1.0
three:
- specifier: 0.160.1
- version: 0.160.1
+ specifier: 0.162.0
+ version: 0.162.0
throttle-debounce:
specifier: 5.0.0
version: 5.0.0
@@ -830,81 +836,81 @@ importers:
specifier: 9.0.1
version: 9.0.1
v-code-diff:
- specifier: 1.7.2
- version: 1.7.2(vue@3.4.18)
+ specifier: 1.9.0
+ version: 1.9.0(vue@3.4.21)
vite:
- specifier: 5.1.0
- version: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0)
+ specifier: 5.1.4
+ version: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1)
vue:
- specifier: 3.4.18
- version: 3.4.18(typescript@5.3.3)
+ specifier: 3.4.21
+ version: 3.4.21(typescript@5.3.3)
vuedraggable:
specifier: next
- version: 4.1.0(vue@3.4.18)
+ version: 4.1.0(vue@3.4.21)
devDependencies:
'@misskey-dev/eslint-plugin':
specifier: 1.0.0
- version: 1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@6.18.1)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
+ version: 1.0.0(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
'@misskey-dev/summaly':
specifier: 5.0.3
version: 5.0.3
'@storybook/addon-actions':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6
'@storybook/addon-essentials':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
'@storybook/addon-interactions':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6
'@storybook/addon-links':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(react@18.2.0)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(react@18.2.0)
'@storybook/addon-mdx-gfm':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6
'@storybook/addon-storysource':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6
'@storybook/blocks':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
'@storybook/components':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
'@storybook/core-events':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6
'@storybook/manager-api':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
'@storybook/preview-api':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6
'@storybook/react':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)
'@storybook/react-vite':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.1.0)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)(rollup@4.12.0)(typescript@5.3.3)(vite@5.1.4)
'@storybook/test':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(vitest@0.34.6)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(vitest@0.34.6)
'@storybook/theming':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
'@storybook/types':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6
'@storybook/vue3':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(vue@3.4.18)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(vue@3.4.21)
'@storybook/vue3-vite':
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)(vite@5.1.0)(vue@3.4.18)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)(vite@5.1.4)(vue@3.4.21)
'@testing-library/vue':
specifier: 8.0.2
- version: 8.0.2(@vue/compiler-sfc@3.4.18)(vue@3.4.18)
+ version: 8.0.2(@vue/compiler-sfc@3.4.21)(vue@3.4.21)
'@types/escape-regexp':
specifier: 0.0.3
version: 0.0.3
@@ -918,14 +924,14 @@ importers:
specifier: 4.0.6
version: 4.0.6
'@types/node':
- specifier: 20.11.17
- version: 20.11.17
+ specifier: 20.11.22
+ version: 20.11.22
'@types/punycode':
- specifier: 2.1.3
- version: 2.1.3
+ specifier: 2.1.4
+ version: 2.1.4
'@types/sanitize-html':
- specifier: 2.9.5
- version: 2.9.5
+ specifier: 2.11.0
+ version: 2.11.0
'@types/throttle-debounce':
specifier: 5.0.2
version: 5.0.2
@@ -939,17 +945,17 @@ importers:
specifier: 8.5.10
version: 8.5.10
'@typescript-eslint/eslint-plugin':
- specifier: 6.18.1
- version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/parser':
- specifier: 6.18.1
- version: 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(eslint@8.57.0)(typescript@5.3.3)
'@vitest/coverage-v8':
specifier: 0.34.6
version: 0.34.6(vitest@0.34.6)
'@vue/runtime-core':
- specifier: 3.4.18
- version: 3.4.18
+ specifier: 3.4.21
+ version: 3.4.21
acorn:
specifier: 8.11.3
version: 8.11.3
@@ -957,23 +963,23 @@ importers:
specifier: 7.0.3
version: 7.0.3
cypress:
- specifier: 13.6.4
- version: 13.6.4
+ specifier: 13.6.6
+ version: 13.6.6
eslint:
- specifier: 8.56.0
- version: 8.56.0
+ specifier: 8.57.0
+ version: 8.57.0
eslint-plugin-import:
specifier: 2.29.1
- version: 2.29.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)
+ version: 2.29.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)
eslint-plugin-vue:
- specifier: 9.20.1
- version: 9.20.1(eslint@8.56.0)
+ specifier: 9.22.0
+ version: 9.22.0(eslint@8.57.0)
fast-glob:
specifier: 3.3.2
version: 3.3.2
happy-dom:
- specifier: 10.0.3
- version: 10.0.3
+ specifier: 13.6.2
+ version: 13.6.2
intersection-observer:
specifier: 0.12.2
version: 0.12.2
@@ -987,8 +993,8 @@ importers:
specifier: 2.0.0-beta.1
version: 2.0.0-beta.1(msw@2.1.7)
nodemon:
- specifier: 3.0.3
- version: 3.0.3
+ specifier: 3.1.0
+ version: 3.1.0
prettier:
specifier: 3.2.5
version: 3.2.5
@@ -1002,17 +1008,17 @@ importers:
specifier: 2.0.3
version: 2.0.3
storybook:
- specifier: 8.0.0-beta.2
- version: 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
+ specifier: 8.0.0-beta.6
+ version: 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
storybook-addon-misskey-theme:
specifier: github:misskey-dev/storybook-addon-misskey-theme
- version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.0.0-beta.2)(@storybook/components@8.0.0-beta.2)(@storybook/core-events@8.0.0-beta.2)(@storybook/manager-api@8.0.0-beta.2)(@storybook/preview-api@8.0.0-beta.2)(@storybook/theming@8.0.0-beta.2)(@storybook/types@8.0.0-beta.2)(react-dom@18.2.0)(react@18.2.0)
+ version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.0.0-beta.6)(@storybook/components@8.0.0-beta.6)(@storybook/core-events@8.0.0-beta.6)(@storybook/manager-api@8.0.0-beta.6)(@storybook/preview-api@8.0.0-beta.6)(@storybook/theming@8.0.0-beta.6)(@storybook/types@8.0.0-beta.6)(react-dom@18.2.0)(react@18.2.0)
vite-plugin-turbosnap:
specifier: 1.0.3
version: 1.0.3
vitest:
specifier: 0.34.6
- version: 0.34.6(happy-dom@10.0.3)(sass@1.70.0)(terser@5.27.0)
+ version: 0.34.6(happy-dom@13.6.2)(sass@1.71.1)(terser@5.28.1)
vitest-fetch-mock:
specifier: 0.2.2
version: 0.2.2(vitest@0.34.6)
@@ -1021,7 +1027,7 @@ importers:
version: 1.8.27
vue-eslint-parser:
specifier: 9.4.2
- version: 9.4.2(eslint@8.56.0)
+ version: 9.4.2(eslint@8.57.0)
vue-tsc:
specifier: 1.8.27
version: 1.8.27(typescript@5.3.3)
@@ -1046,7 +1052,7 @@ importers:
devDependencies:
'@misskey-dev/eslint-plugin':
specifier: 1.0.0
- version: 1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@6.18.1)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
+ version: 1.0.0(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
'@types/matter-js':
specifier: 0.19.6
version: 0.19.6
@@ -1057,14 +1063,14 @@ importers:
specifier: 3.0.8
version: 3.0.8
'@typescript-eslint/eslint-plugin':
- specifier: 6.18.1
- version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/parser':
- specifier: 6.18.1
- version: 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(eslint@8.57.0)(typescript@5.3.3)
eslint:
- specifier: 8.56.0
- version: 8.56.0
+ specifier: 8.57.0
+ version: 8.57.0
nodemon:
specifier: 3.0.2
version: 3.0.2
@@ -1089,31 +1095,31 @@ importers:
devDependencies:
'@microsoft/api-extractor':
specifier: 7.39.1
- version: 7.39.1(@types/node@20.11.17)
+ version: 7.39.1(@types/node@20.11.22)
'@misskey-dev/eslint-plugin':
specifier: 1.0.0
- version: 1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@6.18.1)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
+ version: 1.0.0(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
'@swc/jest':
specifier: 0.2.31
version: 0.2.31(@swc/core@1.3.105)
'@types/jest':
- specifier: 29.5.11
- version: 29.5.11
+ specifier: 29.5.12
+ version: 29.5.12
'@types/node':
- specifier: 20.11.17
- version: 20.11.17
+ specifier: 20.11.22
+ version: 20.11.22
'@typescript-eslint/eslint-plugin':
- specifier: 6.18.1
- version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/parser':
- specifier: 6.18.1
- version: 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(eslint@8.57.0)(typescript@5.3.3)
eslint:
- specifier: 8.56.0
- version: 8.56.0
+ specifier: 8.57.0
+ version: 8.57.0
jest:
specifier: 29.7.0
- version: 29.7.0(@types/node@20.11.17)
+ version: 29.7.0(@types/node@20.11.22)
jest-fetch-mock:
specifier: 3.0.3
version: 3.0.3
@@ -1127,11 +1133,11 @@ importers:
specifier: 2.0.0
version: 2.0.0
nodemon:
- specifier: 3.0.3
- version: 3.0.3
+ specifier: 3.1.0
+ version: 3.1.0
tsd:
- specifier: 0.30.4
- version: 0.30.4
+ specifier: 0.30.7
+ version: 0.30.7
typescript:
specifier: 5.3.3
version: 5.3.3
@@ -1186,19 +1192,19 @@ importers:
devDependencies:
'@misskey-dev/eslint-plugin':
specifier: 1.0.0
- version: 1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@6.18.1)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
+ version: 1.0.0(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
'@types/node':
specifier: 20.11.5
version: 20.11.5
'@typescript-eslint/eslint-plugin':
- specifier: 6.18.1
- version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/parser':
- specifier: 6.18.1
- version: 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(eslint@8.57.0)(typescript@5.3.3)
eslint:
- specifier: 8.56.0
- version: 8.56.0
+ specifier: 8.57.0
+ version: 8.57.0
nodemon:
specifier: 3.0.2
version: 3.0.2
@@ -1220,22 +1226,22 @@ importers:
devDependencies:
'@misskey-dev/eslint-plugin':
specifier: 1.0.0
- version: 1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@6.18.1)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
+ version: 1.0.0(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
'@typescript-eslint/parser':
- specifier: 6.18.1
- version: 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ specifier: 7.1.0
+ version: 7.1.0(eslint@8.57.0)(typescript@5.3.3)
'@typescript/lib-webworker':
specifier: npm:@types/serviceworker@0.0.67
version: /@types/serviceworker@0.0.67
eslint:
- specifier: 8.56.0
- version: 8.56.0
+ specifier: 8.57.0
+ version: 8.57.0
eslint-plugin-import:
specifier: 2.29.1
- version: 2.29.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)
+ version: 2.29.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)
nodemon:
- specifier: 3.0.3
- version: 3.0.3
+ specifier: 3.1.0
+ version: 3.1.0
typescript:
specifier: 5.3.3
version: 5.3.3
@@ -1893,6 +1899,29 @@ packages:
- supports-color
dev: true
+ /@babel/core@7.24.0:
+ resolution: {integrity: sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@ampproject/remapping': 2.2.1
+ '@babel/code-frame': 7.23.5
+ '@babel/generator': 7.23.6
+ '@babel/helper-compilation-targets': 7.23.6
+ '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
+ '@babel/helpers': 7.24.0
+ '@babel/parser': 7.24.0
+ '@babel/template': 7.24.0
+ '@babel/traverse': 7.24.0
+ '@babel/types': 7.24.0
+ convert-source-map: 2.0.0
+ debug: 4.3.4(supports-color@8.1.1)
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@babel/generator@7.23.5:
resolution: {integrity: sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==}
engines: {node: '>=6.9.0'}
@@ -1903,6 +1932,16 @@ packages:
jsesc: 2.5.2
dev: true
+ /@babel/generator@7.23.6:
+ resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.24.0
+ '@jridgewell/gen-mapping': 0.3.2
+ '@jridgewell/trace-mapping': 0.3.18
+ jsesc: 2.5.2
+ dev: true
+
/@babel/helper-annotate-as-pure@7.22.5:
resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
engines: {node: '>=6.9.0'}
@@ -1928,6 +1967,17 @@ packages:
semver: 6.3.1
dev: true
+ /@babel/helper-compilation-targets@7.23.6:
+ resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/compat-data': 7.23.5
+ '@babel/helper-validator-option': 7.23.5
+ browserslist: 4.22.2
+ lru-cache: 5.1.1
+ semver: 6.3.1
+ dev: true
+
/@babel/helper-create-class-features-plugin@7.23.5(@babel/core@7.23.5):
resolution: {integrity: sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==}
engines: {node: '>=6.9.0'}
@@ -2021,6 +2071,20 @@ packages:
'@babel/helper-validator-identifier': 7.22.20
dev: true
+ /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.0):
+ resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.24.0
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-module-imports': 7.22.15
+ '@babel/helper-simple-access': 7.22.5
+ '@babel/helper-split-export-declaration': 7.22.6
+ '@babel/helper-validator-identifier': 7.22.20
+ dev: true
+
/@babel/helper-optimise-call-expression@7.22.5:
resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
engines: {node: '>=6.9.0'}
@@ -2111,6 +2175,17 @@ packages:
- supports-color
dev: true
+ /@babel/helpers@7.24.0:
+ resolution: {integrity: sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/template': 7.24.0
+ '@babel/traverse': 7.24.0
+ '@babel/types': 7.24.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@babel/highlight@7.23.4:
resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==}
engines: {node: '>=6.9.0'}
@@ -2127,6 +2202,14 @@ packages:
dependencies:
'@babel/types': 7.23.5
+ /@babel/parser@7.24.0:
+ resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+ dependencies:
+ '@babel/types': 7.24.0
+ dev: true
+
/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.5):
resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==}
engines: {node: '>=6.9.0'}
@@ -3094,6 +3177,15 @@ packages:
'@babel/types': 7.23.5
dev: true
+ /@babel/template@7.24.0:
+ resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.23.5
+ '@babel/parser': 7.24.0
+ '@babel/types': 7.24.0
+ dev: true
+
/@babel/traverse@7.23.5:
resolution: {integrity: sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==}
engines: {node: '>=6.9.0'}
@@ -3112,6 +3204,24 @@ packages:
- supports-color
dev: true
+ /@babel/traverse@7.24.0:
+ resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.23.5
+ '@babel/generator': 7.23.6
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-function-name': 7.23.0
+ '@babel/helper-hoist-variables': 7.22.5
+ '@babel/helper-split-export-declaration': 7.22.6
+ '@babel/parser': 7.24.0
+ '@babel/types': 7.24.0
+ debug: 4.3.4(supports-color@8.1.1)
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@babel/types@7.23.5:
resolution: {integrity: sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==}
engines: {node: '>=6.9.0'}
@@ -3120,6 +3230,15 @@ packages:
'@babel/helper-validator-identifier': 7.22.20
to-fast-properties: 2.0.0
+ /@babel/types@7.24.0:
+ resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-string-parser': 7.23.4
+ '@babel/helper-validator-identifier': 7.22.20
+ to-fast-properties: 2.0.0
+ dev: true
+
/@base2/pretty-print-object@1.0.1:
resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==}
dev: true
@@ -3128,29 +3247,29 @@ packages:
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
dev: true
- /@bull-board/api@5.14.0(@bull-board/ui@5.14.0):
- resolution: {integrity: sha512-ppN9GeCH8QmCzs47CpDFwVb4Q5W2nK2QvcnbxKpjktCTonZ+5PnoWyXQvLStbcKU9SbMKAM0/OXhj4xOcSRllQ==}
+ /@bull-board/api@5.14.2(@bull-board/ui@5.14.2):
+ resolution: {integrity: sha512-0wppAGPU7ZMwWMpzkmtrlmm7ySI5immymyaRS1cVNJ54rUiGOZP5tnm+Sj7MwPdf63rxqIM843un8+PvQyARGg==}
peerDependencies:
- '@bull-board/ui': 5.14.0
+ '@bull-board/ui': 5.14.2
dependencies:
- '@bull-board/ui': 5.14.0
+ '@bull-board/ui': 5.14.2
redis-info: 3.1.0
dev: false
- /@bull-board/fastify@5.14.0:
- resolution: {integrity: sha512-MEZbfUY74wL2dc9OJZGgYABZADlohp62MP1ZMOlC+6ZF4i7X95yxTQ9DmtIV6kkva7+abJgFGNUhtKi7Mq15Fg==}
+ /@bull-board/fastify@5.14.2:
+ resolution: {integrity: sha512-GQMK70tKOu2gjBi2pjWXMXcftzWRvQNSm+deLmGlJUgqUUbNlzIGRyvaTk7giT4CFzgKcP+hT+lphcAsGTKBQw==}
dependencies:
- '@bull-board/api': 5.14.0(@bull-board/ui@5.14.0)
- '@bull-board/ui': 5.14.0
+ '@bull-board/api': 5.14.2(@bull-board/ui@5.14.2)
+ '@bull-board/ui': 5.14.2
'@fastify/static': 6.12.0
'@fastify/view': 8.2.0
ejs: 3.1.9
dev: false
- /@bull-board/ui@5.14.0:
- resolution: {integrity: sha512-quustWmLsLbqdbCQd4Mud9Eo/2BQzfJSNSiyJt9OrtYT4AXHMgGtbFUy2Ycyda7iQjC4ScKl8f+WdFs4y+KUJA==}
+ /@bull-board/ui@5.14.2:
+ resolution: {integrity: sha512-NiyKWLjKjy29I6ySCnSYbzGX4ZJyPE4xlS5/Z5dVsF2bJLoAV+yD1obflxteJMt60FiEgLV7tfs6tMSVa+Htew==}
dependencies:
- '@bull-board/api': 5.14.0(@bull-board/ui@5.14.0)
+ '@bull-board/api': 5.14.2(@bull-board/ui@5.14.2)
dev: false
/@bundled-es-modules/cookie@2.0.0:
@@ -3169,54 +3288,6 @@ packages:
resolution: {integrity: sha512-BxOqI5LgsIQP1odU5KMwV9yoijleOPzHL18/YvNqF9KFSGF2K/DLlYAbDQsWqd/1nbaFuSkYD/191dpMtNh4vw==}
dev: false
- /@cbor-extract/cbor-extract-darwin-arm64@2.1.1:
- resolution: {integrity: sha512-blVBy5MXz6m36Vx0DfLd7PChOQKEs8lK2bD1WJn/vVgG4FXZiZmZb2GECHFvVPA5T7OnODd9xZiL3nMCv6QUhA==}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: false
- optional: true
-
- /@cbor-extract/cbor-extract-darwin-x64@2.1.1:
- resolution: {integrity: sha512-h6KFOzqk8jXTvkOftyRIWGrd7sKQzQv2jVdTL9nKSf3D2drCvQB/LHUxAOpPXo3pv2clDtKs3xnHalpEh3rDsw==}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: false
- optional: true
-
- /@cbor-extract/cbor-extract-linux-arm64@2.1.1:
- resolution: {integrity: sha512-SxAaRcYf8S0QHaMc7gvRSiTSr7nUYMqbUdErBEu+HYA4Q6UNydx1VwFE68hGcp1qvxcy9yT5U7gA+a5XikfwSQ==}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@cbor-extract/cbor-extract-linux-arm@2.1.1:
- resolution: {integrity: sha512-ds0uikdcIGUjPyraV4oJqyVE5gl/qYBpa/Wnh6l6xLE2lj/hwnjT2XcZCChdXwW/YFZ1LUHs6waoYN8PmK0nKQ==}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@cbor-extract/cbor-extract-linux-x64@2.1.1:
- resolution: {integrity: sha512-GVK+8fNIE9lJQHAlhOROYiI0Yd4bAZ4u++C2ZjlkS3YmO6hi+FUxe6Dqm+OKWTcMpL/l71N6CQAmaRcb4zyJuA==}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@cbor-extract/cbor-extract-win32-x64@2.1.1:
- resolution: {integrity: sha512-2Niq1C41dCRIDeD8LddiH+mxGlO7HJ612Ll3D/E73ZWBmycued+8ghTr/Ho3CMOWPUEr08XtyBMVXAjqF+TcKw==}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: false
- optional: true
-
/@colors/colors@1.5.0:
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
engines: {node: '>=0.1.90'}
@@ -3370,6 +3441,14 @@ packages:
engines: {node: '>=10.0.0'}
dev: true
+ /@emnapi/runtime@0.45.0:
+ resolution: {integrity: sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==}
+ requiresBuild: true
+ dependencies:
+ tslib: 2.6.2
+ dev: false
+ optional: true
+
/@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0):
resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==}
peerDependencies:
@@ -3770,13 +3849,13 @@ packages:
eslint-visitor-keys: 3.4.3
dev: true
- /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0):
+ /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
dependencies:
- eslint: 8.56.0
+ eslint: 8.57.0
eslint-visitor-keys: 3.4.3
dev: true
@@ -3807,8 +3886,8 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
- /@eslint/js@8.56.0:
- resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==}
+ /@eslint/js@8.57.0:
+ resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
@@ -4003,6 +4082,17 @@ packages:
- supports-color
dev: true
+ /@humanwhocodes/config-array@0.11.14:
+ resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
+ engines: {node: '>=10.10.0'}
+ dependencies:
+ '@humanwhocodes/object-schema': 2.0.2
+ debug: 4.3.4(supports-color@8.1.1)
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@humanwhocodes/module-importer@1.0.1:
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
engines: {node: '>=12.22'}
@@ -4017,6 +4107,198 @@ packages:
resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==}
dev: true
+ /@humanwhocodes/object-schema@2.0.2:
+ resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==}
+ dev: true
+
+ /@img/sharp-darwin-arm64@0.33.2:
+ resolution: {integrity: sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w==}
+ engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.0.1
+ dev: false
+ optional: true
+
+ /@img/sharp-darwin-x64@0.33.2:
+ resolution: {integrity: sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg==}
+ engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.0.1
+ dev: false
+ optional: true
+
+ /@img/sharp-libvips-darwin-arm64@1.0.1:
+ resolution: {integrity: sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw==}
+ engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@img/sharp-libvips-darwin-x64@1.0.1:
+ resolution: {integrity: sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog==}
+ engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@img/sharp-libvips-linux-arm64@1.0.1:
+ resolution: {integrity: sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA==}
+ engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@img/sharp-libvips-linux-arm@1.0.1:
+ resolution: {integrity: sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ==}
+ engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@img/sharp-libvips-linux-s390x@1.0.1:
+ resolution: {integrity: sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ==}
+ engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@img/sharp-libvips-linux-x64@1.0.1:
+ resolution: {integrity: sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw==}
+ engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@img/sharp-libvips-linuxmusl-arm64@1.0.1:
+ resolution: {integrity: sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg==}
+ engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@img/sharp-libvips-linuxmusl-x64@1.0.1:
+ resolution: {integrity: sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw==}
+ engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@img/sharp-linux-arm64@0.33.2:
+ resolution: {integrity: sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew==}
+ engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.0.1
+ dev: false
+ optional: true
+
+ /@img/sharp-linux-arm@0.33.2:
+ resolution: {integrity: sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA==}
+ engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.0.1
+ dev: false
+ optional: true
+
+ /@img/sharp-linux-s390x@0.33.2:
+ resolution: {integrity: sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA==}
+ engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.0.1
+ dev: false
+ optional: true
+
+ /@img/sharp-linux-x64@0.33.2:
+ resolution: {integrity: sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A==}
+ engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.0.1
+ dev: false
+ optional: true
+
+ /@img/sharp-linuxmusl-arm64@0.33.2:
+ resolution: {integrity: sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA==}
+ engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.0.1
+ dev: false
+ optional: true
+
+ /@img/sharp-linuxmusl-x64@0.33.2:
+ resolution: {integrity: sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A==}
+ engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.0.1
+ dev: false
+ optional: true
+
+ /@img/sharp-wasm32@0.33.2:
+ resolution: {integrity: sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [wasm32]
+ requiresBuild: true
+ dependencies:
+ '@emnapi/runtime': 0.45.0
+ dev: false
+ optional: true
+
+ /@img/sharp-win32-ia32@0.33.2:
+ resolution: {integrity: sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@img/sharp-win32-x64@0.33.2:
+ resolution: {integrity: sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
/@ioredis/commands@1.2.0:
resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==}
dev: false
@@ -4053,7 +4335,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
chalk: 4.1.2
jest-message-util: 29.7.0
jest-util: 29.7.0
@@ -4074,14 +4356,14 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
ansi-escapes: 4.3.2
chalk: 4.1.2
ci-info: 3.7.1
exit: 0.1.2
graceful-fs: 4.2.11
jest-changed-files: 29.7.0
- jest-config: 29.7.0(@types/node@20.11.17)
+ jest-config: 29.7.0(@types/node@20.11.22)
jest-haste-map: 29.7.0
jest-message-util: 29.7.0
jest-regex-util: 29.6.3
@@ -4116,7 +4398,7 @@ packages:
dependencies:
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
jest-mock: 29.7.0
dev: true
@@ -4143,7 +4425,7 @@ packages:
dependencies:
'@jest/types': 29.6.3
'@sinonjs/fake-timers': 10.3.0
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
jest-message-util: 29.7.0
jest-mock: 29.7.0
jest-util: 29.7.0
@@ -4176,7 +4458,7 @@ packages:
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
'@jridgewell/trace-mapping': 0.3.18
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
chalk: 4.1.2
collect-v8-coverage: 1.0.1
exit: 0.1.2
@@ -4263,7 +4545,7 @@ packages:
dependencies:
'@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
'@types/yargs': 16.0.5
chalk: 4.1.2
dev: true
@@ -4275,12 +4557,12 @@ packages:
'@jest/schemas': 29.6.3
'@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
'@types/yargs': 17.0.19
chalk: 4.1.2
dev: true
- /@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.3.3)(vite@5.1.0):
+ /@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.3.3)(vite@5.1.4):
resolution: {integrity: sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA==}
peerDependencies:
typescript: '>= 4.3.x'
@@ -4294,7 +4576,7 @@ packages:
magic-string: 0.27.0
react-docgen-typescript: 2.2.2(typescript@5.3.3)
typescript: 5.3.3
- vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0)
+ vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1)
dev: true
/@jridgewell/gen-mapping@0.3.2:
@@ -4339,6 +4621,10 @@ packages:
resolution: {integrity: sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==}
dev: false
+ /@levischuck/tiny-cbor@0.2.2:
+ resolution: {integrity: sha512-f5CnPw997Y2GQ8FAvtuVVC19FX8mwNNC+1XJcIi16n/LTJifKO6QBgGLgN3YEmqtGMk17SKSuoWES3imJVxAVw==}
+ dev: false
+
/@lukeed/csprng@1.0.1:
resolution: {integrity: sha512-uSvJdwQU5nK+Vdf6zxcWAY2A8r7uqe+gePwLWzJ+fsQehq18pc0I2hJKwypZ2aLM90+Er9u1xn4iLJPZ+xlL4g==}
engines: {node: '>=8'}
@@ -4389,24 +4675,24 @@ packages:
react: 18.2.0
dev: true
- /@microsoft/api-extractor-model@7.28.4(@types/node@20.11.17):
+ /@microsoft/api-extractor-model@7.28.4(@types/node@20.11.22):
resolution: {integrity: sha512-vucgyPmgHrJ/D4/xQywAmjTmSfxAx2/aDmD6TkIoLu51FdsAfuWRbijWA48AePy60OO+l+mmy9p2P/CEeBZqig==}
dependencies:
'@microsoft/tsdoc': 0.14.2
'@microsoft/tsdoc-config': 0.16.2
- '@rushstack/node-core-library': 3.63.0(@types/node@20.11.17)
+ '@rushstack/node-core-library': 3.63.0(@types/node@20.11.22)
transitivePeerDependencies:
- '@types/node'
dev: true
- /@microsoft/api-extractor@7.39.1(@types/node@20.11.17):
+ /@microsoft/api-extractor@7.39.1(@types/node@20.11.22):
resolution: {integrity: sha512-V0HtCufWa8hZZvSmlEzQZfINcJkHAU/bmpyJQj6w+zpI87EkR8DuBOW6RWrO9c7mUYFZoDaNgUTyKo83ytv+QQ==}
hasBin: true
dependencies:
- '@microsoft/api-extractor-model': 7.28.4(@types/node@20.11.17)
+ '@microsoft/api-extractor-model': 7.28.4(@types/node@20.11.22)
'@microsoft/tsdoc': 0.14.2
'@microsoft/tsdoc-config': 0.16.2
- '@rushstack/node-core-library': 3.63.0(@types/node@20.11.17)
+ '@rushstack/node-core-library': 3.63.0(@types/node@20.11.22)
'@rushstack/rig-package': 0.5.1
'@rushstack/ts-command-line': 4.17.1
colors: 1.2.5
@@ -4450,7 +4736,7 @@ packages:
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)
dev: true
- /@misskey-dev/eslint-plugin@1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@6.18.1)(eslint-plugin-import@2.29.1)(eslint@8.56.0):
+ /@misskey-dev/eslint-plugin@1.0.0(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0):
resolution: {integrity: sha512-dh6UbcrNDVg5DD8k8Qh4ab30OPpuEYIlJCqaBV/lkIV8wNN/AfCJ2V7iTP8V8KjryM4t+sf5IqzQLQnT0mWI4A==}
peerDependencies:
'@typescript-eslint/eslint-plugin': '>= 6'
@@ -4458,18 +4744,18 @@ packages:
eslint: '>= 3'
eslint-plugin-import: '>= 2'
dependencies:
- '@typescript-eslint/eslint-plugin': 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3)
- '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3)
- eslint: 8.56.0
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)
+ '@typescript-eslint/eslint-plugin': 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
+ eslint: 8.57.0
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)
dev: true
- /@misskey-dev/sharp-read-bmp@1.1.1:
- resolution: {integrity: sha512-X52BQYL/I9mafypQ+wBhst+BUlYiPWnHhKGcF6ybcYSLl+zhcV0q5mezIXHozhM0Sv0A7xCdrWmR7TCNxHLrtQ==}
+ /@misskey-dev/sharp-read-bmp@1.2.0:
+ resolution: {integrity: sha512-er4pRakXzHYfEgOFAFfQagqDouG+wLm+kwNq1I30oSdIHDa0wM3KjFpfIGQ25Fks4GcmOl1s7Zh6xoQu5dNjTw==}
dependencies:
decode-bmp: 0.2.1
decode-ico: 0.4.1
- sharp: 0.32.6
+ sharp: 0.33.2
dev: false
/@misskey-dev/summaly@5.0.3:
@@ -4571,12 +4857,12 @@ packages:
tar-fs: 2.1.1
dev: true
- /@nestjs/common@10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1):
- resolution: {integrity: sha512-fwAk931rjW8CNH2Mgwawq/7HWHH1dxkOLdcgs7U52ddLk8CtHXjejm1cbNahewlSbNhvlOl7y1STLHutE6sUqw==}
+ /@nestjs/common@10.3.3(reflect-metadata@0.2.1)(rxjs@7.8.1):
+ resolution: {integrity: sha512-LAkTe8/CF0uNWM0ecuDwUNTHCi1lVSITmmR4FQ6Ftz1E7ujQCnJ5pMRzd8JRN14vdBkxZZ8VbVF0BDUKoKNxMQ==}
peerDependencies:
class-transformer: '*'
class-validator: '*'
- reflect-metadata: ^0.1.12
+ reflect-metadata: ^0.1.12 || ^0.2.0
rxjs: ^7.1.0
peerDependenciesMeta:
class-transformer:
@@ -4585,20 +4871,20 @@ packages:
optional: true
dependencies:
iterare: 1.2.1
- reflect-metadata: 0.1.14
+ reflect-metadata: 0.2.1
rxjs: 7.8.1
tslib: 2.6.2
uid: 2.0.2
- /@nestjs/core@10.2.10(@nestjs/common@10.2.10)(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1):
- resolution: {integrity: sha512-+ckOI6BPi2ZMHikT9MCG4ctHDc4OnjhoIytrn7f2AYMMXI4bnutJhqyQKc30VDka5x3Wq6QAD57pgSP7y+JjJg==}
+ /@nestjs/core@10.3.3(@nestjs/common@10.3.3)(@nestjs/platform-express@10.3.3)(reflect-metadata@0.2.1)(rxjs@7.8.1):
+ resolution: {integrity: sha512-kxJWggQAPX3RuZx9JVec69eSLaYLNIox2emkZJpfBJ5Qq7cAq7edQIt1r4LGjTKq6kFubNTPsqhWf5y7yFRBPw==}
requiresBuild: true
peerDependencies:
'@nestjs/common': ^10.0.0
'@nestjs/microservices': ^10.0.0
'@nestjs/platform-express': ^10.0.0
'@nestjs/websockets': ^10.0.0
- reflect-metadata: ^0.1.12
+ reflect-metadata: ^0.1.12 || ^0.2.0
rxjs: ^7.1.0
peerDependenciesMeta:
'@nestjs/microservices':
@@ -4608,27 +4894,27 @@ packages:
'@nestjs/websockets':
optional: true
dependencies:
- '@nestjs/common': 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
- '@nestjs/platform-express': 10.3.1(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)
+ '@nestjs/common': 10.3.3(reflect-metadata@0.2.1)(rxjs@7.8.1)
+ '@nestjs/platform-express': 10.3.3(@nestjs/common@10.3.3)(@nestjs/core@10.3.3)
'@nuxtjs/opencollective': 0.3.2
fast-safe-stringify: 2.1.1
iterare: 1.2.1
path-to-regexp: 3.2.0
- reflect-metadata: 0.1.14
+ reflect-metadata: 0.2.1
rxjs: 7.8.1
tslib: 2.6.2
uid: 2.0.2
transitivePeerDependencies:
- encoding
- /@nestjs/platform-express@10.3.1(@nestjs/common@10.2.10)(@nestjs/core@10.2.10):
- resolution: {integrity: sha512-Rj21quI5h4Lry7q9an+nO4ADQiQUy9A6XK74o5aTUHo3Ysm25ujqh2NgU4XbT3M2oXU9qzhE59OfhkQ7ZUvTAg==}
+ /@nestjs/platform-express@10.3.3(@nestjs/common@10.3.3)(@nestjs/core@10.3.3):
+ resolution: {integrity: sha512-GGKSEU48Os7nYFIsUM0nutuFUGn5AbeP8gzFBiBCAtiuJWrXZXpZ58pMBYxAbMf7IrcOZFInHEukjHGAQU0OZw==}
peerDependencies:
'@nestjs/common': ^10.0.0
'@nestjs/core': ^10.0.0
dependencies:
- '@nestjs/common': 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
- '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)
+ '@nestjs/common': 10.3.3(reflect-metadata@0.2.1)(rxjs@7.8.1)
+ '@nestjs/core': 10.3.3(@nestjs/common@10.3.3)(@nestjs/platform-express@10.3.3)(reflect-metadata@0.2.1)(rxjs@7.8.1)
body-parser: 1.20.2
cors: 2.8.5
express: 4.18.2
@@ -4637,8 +4923,8 @@ packages:
transitivePeerDependencies:
- supports-color
- /@nestjs/testing@10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(@nestjs/platform-express@10.3.1):
- resolution: {integrity: sha512-IVLUnPz/+fkBtPATYfqTIP+phN9yjkXejmj+JyhmcfPJZpxBmD1i9VSMqa4u54l37j0xkGPscQ0IXpbhqMYUKw==}
+ /@nestjs/testing@10.3.3(@nestjs/common@10.3.3)(@nestjs/core@10.3.3)(@nestjs/platform-express@10.3.3):
+ resolution: {integrity: sha512-kX20GfjAImL5grd/i69uD/x7sc00BaqGcP2dRG3ilqshQUuy5DOmspLCr3a2C8xmVU7kzK4spT0oTxhe6WcCAA==}
peerDependencies:
'@nestjs/common': ^10.0.0
'@nestjs/core': ^10.0.0
@@ -4650,9 +4936,9 @@ packages:
'@nestjs/platform-express':
optional: true
dependencies:
- '@nestjs/common': 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
- '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)
- '@nestjs/platform-express': 10.3.1(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)
+ '@nestjs/common': 10.3.3(reflect-metadata@0.2.1)(rxjs@7.8.1)
+ '@nestjs/core': 10.3.3(@nestjs/common@10.3.3)(@nestjs/platform-express@10.3.3)(reflect-metadata@0.2.1)(rxjs@7.8.1)
+ '@nestjs/platform-express': 10.3.3(@nestjs/common@10.3.3)(@nestjs/core@10.3.3)
tslib: 2.6.2
dev: false
@@ -4872,7 +5158,7 @@ packages:
openapi-types: 12.1.3
dev: true
- /@rollup/plugin-json@6.1.0(rollup@4.9.6):
+ /@rollup/plugin-json@6.1.0(rollup@4.12.0):
resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==}
engines: {node: '>=14.0.0'}
peerDependencies:
@@ -4881,11 +5167,11 @@ packages:
rollup:
optional: true
dependencies:
- '@rollup/pluginutils': 5.1.0(rollup@4.9.6)
- rollup: 4.9.6
+ '@rollup/pluginutils': 5.1.0(rollup@4.12.0)
+ rollup: 4.12.0
dev: false
- /@rollup/plugin-replace@5.0.5(rollup@4.9.6):
+ /@rollup/plugin-replace@5.0.5(rollup@4.12.0):
resolution: {integrity: sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==}
engines: {node: '>=14.0.0'}
peerDependencies:
@@ -4894,12 +5180,12 @@ packages:
rollup:
optional: true
dependencies:
- '@rollup/pluginutils': 5.1.0(rollup@4.9.6)
+ '@rollup/pluginutils': 5.1.0(rollup@4.12.0)
magic-string: 0.30.7
- rollup: 4.9.6
+ rollup: 4.12.0
dev: false
- /@rollup/pluginutils@5.1.0(rollup@4.9.6):
+ /@rollup/pluginutils@5.1.0(rollup@4.12.0):
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
peerDependencies:
@@ -4911,100 +5197,100 @@ packages:
'@types/estree': 1.0.5
estree-walker: 2.0.2
picomatch: 2.3.1
- rollup: 4.9.6
+ rollup: 4.12.0
- /@rollup/rollup-android-arm-eabi@4.9.6:
- resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==}
+ /@rollup/rollup-android-arm-eabi@4.12.0:
+ resolution: {integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==}
cpu: [arm]
os: [android]
requiresBuild: true
optional: true
- /@rollup/rollup-android-arm64@4.9.6:
- resolution: {integrity: sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==}
+ /@rollup/rollup-android-arm64@4.12.0:
+ resolution: {integrity: sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==}
cpu: [arm64]
os: [android]
requiresBuild: true
optional: true
- /@rollup/rollup-darwin-arm64@4.9.6:
- resolution: {integrity: sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==}
+ /@rollup/rollup-darwin-arm64@4.12.0:
+ resolution: {integrity: sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
optional: true
- /@rollup/rollup-darwin-x64@4.9.6:
- resolution: {integrity: sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==}
+ /@rollup/rollup-darwin-x64@4.12.0:
+ resolution: {integrity: sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==}
cpu: [x64]
os: [darwin]
requiresBuild: true
optional: true
- /@rollup/rollup-linux-arm-gnueabihf@4.9.6:
- resolution: {integrity: sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==}
+ /@rollup/rollup-linux-arm-gnueabihf@4.12.0:
+ resolution: {integrity: sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==}
cpu: [arm]
os: [linux]
requiresBuild: true
optional: true
- /@rollup/rollup-linux-arm64-gnu@4.9.6:
- resolution: {integrity: sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==}
+ /@rollup/rollup-linux-arm64-gnu@4.12.0:
+ resolution: {integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==}
cpu: [arm64]
os: [linux]
requiresBuild: true
optional: true
- /@rollup/rollup-linux-arm64-musl@4.9.6:
- resolution: {integrity: sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==}
+ /@rollup/rollup-linux-arm64-musl@4.12.0:
+ resolution: {integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==}
cpu: [arm64]
os: [linux]
requiresBuild: true
optional: true
- /@rollup/rollup-linux-riscv64-gnu@4.9.6:
- resolution: {integrity: sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==}
+ /@rollup/rollup-linux-riscv64-gnu@4.12.0:
+ resolution: {integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==}
cpu: [riscv64]
os: [linux]
requiresBuild: true
optional: true
- /@rollup/rollup-linux-x64-gnu@4.9.6:
- resolution: {integrity: sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==}
+ /@rollup/rollup-linux-x64-gnu@4.12.0:
+ resolution: {integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==}
cpu: [x64]
os: [linux]
requiresBuild: true
optional: true
- /@rollup/rollup-linux-x64-musl@4.9.6:
- resolution: {integrity: sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==}
+ /@rollup/rollup-linux-x64-musl@4.12.0:
+ resolution: {integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==}
cpu: [x64]
os: [linux]
requiresBuild: true
optional: true
- /@rollup/rollup-win32-arm64-msvc@4.9.6:
- resolution: {integrity: sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==}
+ /@rollup/rollup-win32-arm64-msvc@4.12.0:
+ resolution: {integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==}
cpu: [arm64]
os: [win32]
requiresBuild: true
optional: true
- /@rollup/rollup-win32-ia32-msvc@4.9.6:
- resolution: {integrity: sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==}
+ /@rollup/rollup-win32-ia32-msvc@4.12.0:
+ resolution: {integrity: sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==}
cpu: [ia32]
os: [win32]
requiresBuild: true
optional: true
- /@rollup/rollup-win32-x64-msvc@4.9.6:
- resolution: {integrity: sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==}
+ /@rollup/rollup-win32-x64-msvc@4.12.0:
+ resolution: {integrity: sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==}
cpu: [x64]
os: [win32]
requiresBuild: true
optional: true
- /@rushstack/node-core-library@3.63.0(@types/node@20.11.17):
+ /@rushstack/node-core-library@3.63.0(@types/node@20.11.22):
resolution: {integrity: sha512-Q7B3dVpBQF1v+mUfxNcNZh5uHVR8ntcnkN5GYjbBLrxUYHBGKbnCM+OdcN+hzCpFlLBH6Ob0dEHhZ0spQwf24A==}
peerDependencies:
'@types/node': '*'
@@ -5012,7 +5298,7 @@ packages:
'@types/node':
optional: true
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
colors: 1.2.5
fs-extra: 7.0.1
import-lazy: 4.0.0
@@ -5038,8 +5324,8 @@ packages:
string-argv: 0.3.1
dev: true
- /@shikijs/core@1.0.0-beta.3:
- resolution: {integrity: sha512-SCwPom2Wn8XxNlEeqdzycU93SKgzYeVsedjqDsgZaz4XiiPpZUzlHt2NAEQTwTnPcHNZapZ6vbkwJ8P11ggL3Q==}
+ /@shikijs/core@1.1.7:
+ resolution: {integrity: sha512-gTYLUIuD1UbZp/11qozD3fWpUTuMqPSf3svDMMrL0UmlGU7D9dPw/V1FonwAorCUJBltaaESxq90jrSjQyGixg==}
dev: false
/@sideway/address@4.1.4:
@@ -5056,18 +5342,18 @@ packages:
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
dev: true
- /@simplewebauthn/server@9.0.2:
- resolution: {integrity: sha512-aaWA+qVOU4byk5IDb/l+M1+7dmrAJhTb4ISJHucpsgRQcMMEes76tbGIqO2JQuA7N50tc/OBrnGKBjoKYG1kSw==}
+ /@simplewebauthn/server@9.0.3:
+ resolution: {integrity: sha512-FMZieoBosrVLFxCnxPFD9Enhd1U7D8nidVDT4MsHc6l4fdVcjoeHjDueeXCloO1k5O/fZg1fsSXXPKbY2XTzDA==}
engines: {node: '>=16.0.0'}
dependencies:
'@hexagon/base64': 1.1.27
+ '@levischuck/tiny-cbor': 0.2.2
'@peculiar/asn1-android': 2.3.10
'@peculiar/asn1-ecc': 2.3.8
'@peculiar/asn1-rsa': 2.3.8
'@peculiar/asn1-schema': 2.3.8
'@peculiar/asn1-x509': 2.3.8
'@simplewebauthn/types': 9.0.1
- cbor-x: 1.5.4
cross-fetch: 4.0.0
transitivePeerDependencies:
- encoding
@@ -5076,10 +5362,6 @@ packages:
/@simplewebauthn/types@9.0.1:
resolution: {integrity: sha512-tGSRP1QvsAvsJmnOlRQyw/mvK9gnPtjEc5fg2+m8n+QUa+D7rvrKkOYyfpy42GTs90X3RDOnqJgfHt+qO67/+w==}
- /@sinclair/typebox@0.24.51:
- resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==}
- dev: true
-
/@sinclair/typebox@0.27.8:
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
dev: true
@@ -5564,10 +5846,10 @@ packages:
resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==}
dev: false
- /@storybook/addon-actions@8.0.0-beta.2:
- resolution: {integrity: sha512-sw51iot8E4aZP+z96fWLG7idrpCj/LqTV5lOcE06MU3T6/mW0OqoS7nFF+ncOtjcDsOjValmLiVQCL8m759mTQ==}
+ /@storybook/addon-actions@8.0.0-beta.6:
+ resolution: {integrity: sha512-g+X2M6Awg21vkXzRP7hWBYCdbXnxJ3BJWsP7BblYmPo2J7eJDzhQascNyTmSr0pb1/7nv+tworGviXThgvlUgw==}
dependencies:
- '@storybook/core-events': 8.0.0-beta.2
+ '@storybook/core-events': 8.0.0-beta.6
'@storybook/global': 5.0.0
'@types/uuid': 9.0.8
dequal: 2.0.3
@@ -5575,18 +5857,18 @@ packages:
uuid: 9.0.1
dev: true
- /@storybook/addon-backgrounds@8.0.0-beta.2:
- resolution: {integrity: sha512-cyDbV7srhuh/qaEMCvfz4dTLwnJV0VjHMivLtqSZgzhU24kekc7145KnLOOpDKzEQiAl1mVXb/7HBrykQcbKtg==}
+ /@storybook/addon-backgrounds@8.0.0-beta.6:
+ resolution: {integrity: sha512-C8MS635knAOSat5JbkpZXOiAqkDm1bKWvuVqiQfbX2into45/aAuyN3mYxveGIRTRjPJCv/UpostkLSNvfH/NQ==}
dependencies:
'@storybook/global': 5.0.0
memoizerific: 1.11.3
ts-dedent: 2.2.0
dev: true
- /@storybook/addon-controls@8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-9rvjv4Er7WJkSeXPvCJ78GnKeUqbc7NFGZVlWl2gS3gFeLrXRgtrA5raOR+XneI51UtvAPZX89Mdeg/bQueUvQ==}
+ /@storybook/addon-controls@8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-G96MH7yU/KShq3lTrkgtU1IbNQXLVc3BG7miaLqzQgWFN8SSAivlu3vk1Vffui3+3Dv52WZhMKi3hueNfnM1Xw==}
dependencies:
- '@storybook/blocks': 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/blocks': 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
lodash: 4.17.21
ts-dedent: 2.2.0
transitivePeerDependencies:
@@ -5597,22 +5879,22 @@ packages:
- supports-color
dev: true
- /@storybook/addon-docs@8.0.0-beta.2:
- resolution: {integrity: sha512-ax9Nto8pXGmNh13IfYalBoQ/6YLYjlQkhURM5eGDqhz6lZdMLQZF/GMz3gMwSXTD8edcfamXtmMOfzWc8qR1kw==}
+ /@storybook/addon-docs@8.0.0-beta.6:
+ resolution: {integrity: sha512-VLys4EuL8XVhmu1QxUiUG5keID8v/FsC5L71Y0Wcf5D+ll6ZD8vCqEtbMY3TiJJ9NqqNIcmcG3bG6JVXOYcD8g==}
dependencies:
'@babel/core': 7.23.5
'@mdx-js/react': 3.0.1(@types/react@18.0.28)(react@18.2.0)
- '@storybook/blocks': 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/components': 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/csf-plugin': 8.0.0-beta.2
- '@storybook/csf-tools': 8.0.0-beta.2
+ '@storybook/blocks': 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/components': 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/csf-plugin': 8.0.0-beta.6
+ '@storybook/csf-tools': 8.0.0-beta.6
'@storybook/global': 5.0.0
- '@storybook/node-logger': 8.0.0-beta.2
- '@storybook/preview-api': 8.0.0-beta.2
- '@storybook/react-dom-shim': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/theming': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/node-logger': 8.0.0-beta.6
+ '@storybook/preview-api': 8.0.0-beta.6
+ '@storybook/react-dom-shim': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/theming': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/types': 8.0.0-beta.6
'@types/react': 18.0.28
fs-extra: 11.1.1
react: 18.2.0
@@ -5625,22 +5907,22 @@ packages:
- supports-color
dev: true
- /@storybook/addon-essentials@8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-zB1sRf/ynxddBcWkzxZ55YVN5trbh2sMh9iPA+MLmKwz/tWK+f8/EoV8jfevu1ou2MS/2Jkjyk90jyZEXloVjg==}
+ /@storybook/addon-essentials@8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-6Vjf03c0oIavXqOK9DIN0UeH0iJFmBoVrFt1mTwydMxchyJBSP785MSd9DuFhLdYZPQTMHaR4/JhOIjdDV8mbA==}
dependencies:
- '@storybook/addon-actions': 8.0.0-beta.2
- '@storybook/addon-backgrounds': 8.0.0-beta.2
- '@storybook/addon-controls': 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/addon-docs': 8.0.0-beta.2
- '@storybook/addon-highlight': 8.0.0-beta.2
- '@storybook/addon-measure': 8.0.0-beta.2
- '@storybook/addon-outline': 8.0.0-beta.2
- '@storybook/addon-toolbars': 8.0.0-beta.2
- '@storybook/addon-viewport': 8.0.0-beta.2
- '@storybook/core-common': 8.0.0-beta.2
- '@storybook/manager-api': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/node-logger': 8.0.0-beta.2
- '@storybook/preview-api': 8.0.0-beta.2
+ '@storybook/addon-actions': 8.0.0-beta.6
+ '@storybook/addon-backgrounds': 8.0.0-beta.6
+ '@storybook/addon-controls': 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/addon-docs': 8.0.0-beta.6
+ '@storybook/addon-highlight': 8.0.0-beta.6
+ '@storybook/addon-measure': 8.0.0-beta.6
+ '@storybook/addon-outline': 8.0.0-beta.6
+ '@storybook/addon-toolbars': 8.0.0-beta.6
+ '@storybook/addon-viewport': 8.0.0-beta.6
+ '@storybook/core-common': 8.0.0-beta.6
+ '@storybook/manager-api': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/node-logger': 8.0.0-beta.6
+ '@storybook/preview-api': 8.0.0-beta.6
ts-dedent: 2.2.0
transitivePeerDependencies:
- '@types/react'
@@ -5650,24 +5932,24 @@ packages:
- supports-color
dev: true
- /@storybook/addon-highlight@8.0.0-beta.2:
- resolution: {integrity: sha512-Y5/I4WkhcwiE6/p3kaWz+wN1IMr6GNK8ytxsVnIQHOCUfpu1lArGuHzU4E6nN7/bmXahDO+Hz3dWGdnS5YeLXw==}
+ /@storybook/addon-highlight@8.0.0-beta.6:
+ resolution: {integrity: sha512-U+qz4TNLrw24t1eZ2Zmhl2FZKZKiwHbibq4qR5ruAFe9W5/aMHqPuBB0POroaGu3P+tyDP2G46dckMNXVraiWA==}
dependencies:
'@storybook/global': 5.0.0
dev: true
- /@storybook/addon-interactions@8.0.0-beta.2:
- resolution: {integrity: sha512-L4XLTkF8z3f6V9Z61N+t/8i1d0tECyHkaeexsRjWgXaiJst+9iSdDFCApalxemLzI6mA8tIiOkRH0+DqewvpNQ==}
+ /@storybook/addon-interactions@8.0.0-beta.6:
+ resolution: {integrity: sha512-KSigq+7vCA1tnj31MjhM7xaqickR1guZdjyXVRx7gi7qbdhSuCQv52gAkVpDapwlEuvGFCCYxzt7tmcn6dkLZQ==}
dependencies:
'@storybook/global': 5.0.0
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/types': 8.0.0-beta.6
jest-mock: 27.5.1
polished: 4.2.2
ts-dedent: 2.2.0
dev: true
- /@storybook/addon-links@8.0.0-beta.2(react@18.2.0):
- resolution: {integrity: sha512-hP1sBcG7/yVz6s81xW3mMS39G4rGcBiw4PWLKmILCqpBhAyog9EGXJrKrYMTdDlX9EcPd11fHbdLgRNw+UPIDg==}
+ /@storybook/addon-links@8.0.0-beta.6(react@18.2.0):
+ resolution: {integrity: sha512-+5knw5CHEb23n6Bm9Xp9nmoLRqWZ3QVGb1gNI3mGwmkpLwesohFR4fW7OrdRmzYHpS0PyYToZyfTCMYrmjBDvg==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
@@ -5680,50 +5962,50 @@ packages:
ts-dedent: 2.2.0
dev: true
- /@storybook/addon-mdx-gfm@8.0.0-beta.2:
- resolution: {integrity: sha512-yFRBEoJzeGsLcXKQmDfiT+tr1EjLJ1ktsFDjS3ymVK9DzxSbnZa1u+wIA8spAn6F5qC9uSSAng64UrVyU9JbWQ==}
+ /@storybook/addon-mdx-gfm@8.0.0-beta.6:
+ resolution: {integrity: sha512-b4pb59rrX+C/oYFeEiHb8jJn0h9WZSkHVkLIgaj0G64Nd9OpyKZXMbGpDxwMq4LTi1w65Wddi1UUQbUVVDNHRw==}
dependencies:
- '@storybook/node-logger': 8.0.0-beta.2
+ '@storybook/node-logger': 8.0.0-beta.6
remark-gfm: 4.0.0
ts-dedent: 2.2.0
transitivePeerDependencies:
- supports-color
dev: true
- /@storybook/addon-measure@8.0.0-beta.2:
- resolution: {integrity: sha512-V0kVtV9EihgsBHZ698QtH0tPr6bwFpwjLvK/Oz/PYh97jBfjzYI1A0qfAV1ixFAr12W/Aco1BBsw+ascI+0AjA==}
+ /@storybook/addon-measure@8.0.0-beta.6:
+ resolution: {integrity: sha512-D+KzWRULcbwR8/ysD7Qbw4uWBn9gwNm9s3IeVuhupawUb3u+H4XfVCOW2rA5qry/x8aroKOhAmyKd9v4i+l3pg==}
dependencies:
'@storybook/global': 5.0.0
tiny-invariant: 1.3.1
dev: true
- /@storybook/addon-outline@8.0.0-beta.2:
- resolution: {integrity: sha512-0FNcGgUvftiML5c5j9nRbKlaYcsXKISAdHxvku/dFBd16HctX/krf4neHVcSBpP1VfU2wT/782s3BXQcRwC/4Q==}
+ /@storybook/addon-outline@8.0.0-beta.6:
+ resolution: {integrity: sha512-U+5TFTj+gtkIiIJCk6h7zbrP588CUipzVVsiDTSLl4pc+H3ylGTGncq3ZGtOyl+DCoBsQCgKxy2YWQtKHrESOw==}
dependencies:
'@storybook/global': 5.0.0
ts-dedent: 2.2.0
dev: true
- /@storybook/addon-storysource@8.0.0-beta.2:
- resolution: {integrity: sha512-t3Nsr8MvcWlS+OONimYQ01CI3pPM5CKb+spS3BI7g89gnt7nz/OdrvbTZjOVLp6AqUo0lYnmVgEcjsOL09Zdfg==}
+ /@storybook/addon-storysource@8.0.0-beta.6:
+ resolution: {integrity: sha512-J9sCZ5/KQW2hbfKsom8LmgSWJxw+Kp/7LjIHGevFfov/i9DR8i9xbh5htUwC9fx+vWGR87tez03b+oUJbyHPog==}
dependencies:
- '@storybook/source-loader': 8.0.0-beta.2
+ '@storybook/source-loader': 8.0.0-beta.6
estraverse: 5.3.0
tiny-invariant: 1.3.1
dev: true
- /@storybook/addon-toolbars@8.0.0-beta.2:
- resolution: {integrity: sha512-VoTZeLZo156QE4ZkymIH2OFHaZvfDWNBG2YdG/2vcBz3XG5xqlBtM+8IIAwIQik4vHIGVqFVDwPpjzWayQFr2A==}
+ /@storybook/addon-toolbars@8.0.0-beta.6:
+ resolution: {integrity: sha512-ClT5spwh6S1rUvyFEIFQndE3VK6tpwI2cyIW4E20LajtfUmj3dOfJQX/ZbnhEH3sDBsCm97ysZ/mNR0mbBHZrg==}
dev: true
- /@storybook/addon-viewport@8.0.0-beta.2:
- resolution: {integrity: sha512-OZzMtkOSIvLGXbODGd5UZb3KXvJNAuXfqkcrrtkSnC+8baJi+3xscVDTU5Tn8gfLz7wsGInrWchxNnXX+DKfmg==}
+ /@storybook/addon-viewport@8.0.0-beta.6:
+ resolution: {integrity: sha512-KNYGM6nVrz/Ej25W3lcpaxxJDYVXBYeGl60FWN/WlqRnjo4c4Fyufl6Xev2plQ3eI8jIvWEdGNC/Z/NQnDx1+Q==}
dependencies:
memoizerific: 1.11.3
dev: true
- /@storybook/blocks@8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-IH8hEfPtR5N81PGydrPQdpBWGqOf6l1mXFjRjWwp1BkWvrvWv4lLk4bQ9JqpMF0zH2soKl5BUa5aP0yiufFtlg==}
+ /@storybook/blocks@8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-QkrWT0BELNv3UGv/dtNuB/ROZn0f9VpERbadhXLE/oNXMJLalyjEbRGM635l0lDeoqjYnWHl+tuM6DTe1Xpk2w==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -5733,18 +6015,18 @@ packages:
react-dom:
optional: true
dependencies:
- '@storybook/channels': 8.0.0-beta.2
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/components': 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/core-events': 8.0.0-beta.2
+ '@storybook/channels': 8.0.0-beta.6
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/components': 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/core-events': 8.0.0-beta.6
'@storybook/csf': 0.1.2
- '@storybook/docs-tools': 8.0.0-beta.2
+ '@storybook/docs-tools': 8.0.0-beta.6
'@storybook/global': 5.0.0
'@storybook/icons': 1.2.5(react-dom@18.2.0)(react@18.2.0)
- '@storybook/manager-api': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/preview-api': 8.0.0-beta.2
- '@storybook/theming': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/manager-api': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/preview-api': 8.0.0-beta.6
+ '@storybook/theming': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/types': 8.0.0-beta.6
'@types/lodash': 4.14.191
color-convert: 2.0.1
dequal: 2.0.3
@@ -5765,13 +6047,13 @@ packages:
- supports-color
dev: true
- /@storybook/builder-manager@8.0.0-beta.2:
- resolution: {integrity: sha512-YC9UFESllCLmo69R8xktieWcesCbJiDxeAhMdn9mosQLSOvPlZ/ElivTx423Ombrs3saXAxtLVY5rQJQKSUHEw==}
+ /@storybook/builder-manager@8.0.0-beta.6:
+ resolution: {integrity: sha512-bB/gSsPIpU22Tc6YTjPZdw1RM6nrsuJJ9aYXGqEJTqA4l4lBUN7fwIZQ1x/pS+5LbeUO0J9lAhGXurS+m8rI2A==}
dependencies:
'@fal-works/esbuild-plugin-global-externals': 2.1.2
- '@storybook/core-common': 8.0.0-beta.2
- '@storybook/manager': 8.0.0-beta.2
- '@storybook/node-logger': 8.0.0-beta.2
+ '@storybook/core-common': 8.0.0-beta.6
+ '@storybook/manager': 8.0.0-beta.6
+ '@storybook/node-logger': 8.0.0-beta.6
'@types/ejs': 3.1.2
'@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.18.20)
browser-assert: 1.2.1
@@ -5787,8 +6069,8 @@ packages:
- supports-color
dev: true
- /@storybook/builder-vite@8.0.0-beta.2(typescript@5.3.3)(vite@5.1.0):
- resolution: {integrity: sha512-dtkEef/pZMRkv3f+byj6rNlotXK3L+93q1kZRPkICq3V46F4D8EhPZmN/KYi8LHoyKHP/8zE9aI3Mi7GBjQZiA==}
+ /@storybook/builder-vite@8.0.0-beta.6(typescript@5.3.3)(vite@5.1.4):
+ resolution: {integrity: sha512-3P5uTZqwwcUW64Hep/VtJXpQYi5vTkmqAjwZvr8gmzr37NYq3YT/PiSGn4CaZswSx5Z/lSYq3In8oIwmj/a1/g==}
peerDependencies:
'@preact/preset-vite': '*'
typescript: '>= 4.3.x'
@@ -5802,14 +6084,15 @@ packages:
vite-plugin-glimmerx:
optional: true
dependencies:
- '@storybook/channels': 8.0.0-beta.2
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/core-common': 8.0.0-beta.2
- '@storybook/csf-plugin': 8.0.0-beta.2
- '@storybook/node-logger': 8.0.0-beta.2
- '@storybook/preview': 8.0.0-beta.2
- '@storybook/preview-api': 8.0.0-beta.2
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/channels': 8.0.0-beta.6
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/core-common': 8.0.0-beta.6
+ '@storybook/core-events': 8.0.0-beta.6
+ '@storybook/csf-plugin': 8.0.0-beta.6
+ '@storybook/node-logger': 8.0.0-beta.6
+ '@storybook/preview': 8.0.0-beta.6
+ '@storybook/preview-api': 8.0.0-beta.6
+ '@storybook/types': 8.0.0-beta.6
'@types/find-cache-dir': 3.2.1
browser-assert: 1.2.1
es-module-lexer: 0.9.3
@@ -5819,38 +6102,39 @@ packages:
magic-string: 0.30.7
ts-dedent: 2.2.0
typescript: 5.3.3
- vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0)
+ vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1)
transitivePeerDependencies:
- encoding
- supports-color
dev: true
- /@storybook/channels@8.0.0-beta.2:
- resolution: {integrity: sha512-6PoOkce/T3g5pf5wA/tE9JRo9ZoyhdjzZqS2gVsxKza1Ie3gICVKWA+Cu3IM7s05+fX5syHmTvzOLykwfMh9QQ==}
+ /@storybook/channels@8.0.0-beta.6:
+ resolution: {integrity: sha512-DjwJhty45gQifo+TvGqddLX+NX1iGTmZyGLxlqPMpdp+x/yq8WwVZ316Q7tLt6z6fyAmsroc3ma5p1iLhqpV7g==}
dependencies:
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/core-events': 8.0.0-beta.2
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/core-events': 8.0.0-beta.6
'@storybook/global': 5.0.0
qs: 6.11.1
telejson: 7.2.0
tiny-invariant: 1.3.1
dev: true
- /@storybook/cli@8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-IfCYCpkOZvMQnf3i+AIdTZ4x45lfuEYNRWZYAZT8Nmnuz2gc0AKui3So4IgNB276Zmbru+OCudf05xHgoxxu3A==}
+ /@storybook/cli@8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-sREQYnPds2bwQS7FLbRy7oaxGvOmYhPEYVf93pWKyo/qwSWyXEXbqGCGT6bNhSl/xzqXX7VryLDmuOoHmVTh1g==}
hasBin: true
dependencies:
+ '@babel/core': 7.23.5
'@babel/types': 7.23.5
'@ndelangen/get-tarball': 3.0.7
- '@storybook/codemod': 8.0.0-beta.2
- '@storybook/core-common': 8.0.0-beta.2
- '@storybook/core-events': 8.0.0-beta.2
- '@storybook/core-server': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/csf-tools': 8.0.0-beta.2
- '@storybook/node-logger': 8.0.0-beta.2
- '@storybook/telemetry': 8.0.0-beta.2
- '@storybook/types': 8.0.0-beta.2
- '@types/semver': 7.5.6
+ '@storybook/codemod': 8.0.0-beta.6
+ '@storybook/core-common': 8.0.0-beta.6
+ '@storybook/core-events': 8.0.0-beta.6
+ '@storybook/core-server': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/csf-tools': 8.0.0-beta.6
+ '@storybook/node-logger': 8.0.0-beta.6
+ '@storybook/telemetry': 8.0.0-beta.6
+ '@storybook/types': 8.0.0-beta.6
+ '@types/semver': 7.5.8
'@yarnpkg/fslib': 2.10.3
'@yarnpkg/libzip': 2.3.0
chalk: 4.1.2
@@ -5885,22 +6169,22 @@ packages:
- utf-8-validate
dev: true
- /@storybook/client-logger@8.0.0-beta.2:
- resolution: {integrity: sha512-Sp2tRQO7NmwUjFgN7WTptzJhcyT75rJ+PV9TeSi5BxJXSPTKvA/e6VKFA5k83MS5AI3VBzKV//rFsqyd5+EVkg==}
+ /@storybook/client-logger@8.0.0-beta.6:
+ resolution: {integrity: sha512-XX9CSWt9NDO/1K8tTYV+yuj0ur4HznM1Vc5mY5AwT5xh0RP5HtWZ+VoJfrWYXlBoRXaj0gf8si+FO+lSW82DcQ==}
dependencies:
'@storybook/global': 5.0.0
dev: true
- /@storybook/codemod@8.0.0-beta.2:
- resolution: {integrity: sha512-s0QcLCdFsMjQmMYRfLQwPaVaYwBmT+CYp0p43xLJ9EVMydSj+So9zs2L0Tp4BN+w9yMz+QvjSq0UZvexuFmC9Q==}
+ /@storybook/codemod@8.0.0-beta.6:
+ resolution: {integrity: sha512-ttQYDkhKmtU6Qbg+Kgn4K2XXf8XMpa2euuC6PmYffBD7/qLiGfABfBc4FHKRv4yScnvKK7Ehy7K0lvipfg6tXw==}
dependencies:
'@babel/core': 7.23.5
'@babel/preset-env': 7.23.5(@babel/core@7.23.5)
'@babel/types': 7.23.5
'@storybook/csf': 0.1.2
- '@storybook/csf-tools': 8.0.0-beta.2
- '@storybook/node-logger': 8.0.0-beta.2
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/csf-tools': 8.0.0-beta.6
+ '@storybook/node-logger': 8.0.0-beta.6
+ '@storybook/types': 8.0.0-beta.6
'@types/cross-spawn': 6.0.2
cross-spawn: 7.0.3
globby: 11.1.0
@@ -5913,19 +6197,19 @@ packages:
- supports-color
dev: true
- /@storybook/components@8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-FsY+Sk6i/62RSPRTupUkBJEBb02Ry5Cg9XEfAa7eH5MpaxxLLIBBDxJ8y1FPepvr0Hkzqo0sBa8w3KMbTfo2ow==}
+ /@storybook/components@8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-J3aJtPgaSco0sefvRMBLFsWbslhKMhaS3U+5baRqlV5bjPLZN+d4P18gP1RMaw/coh6DiKEQJZuHRoPIOdt4CA==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
'@radix-ui/react-slot': 1.0.2(@types/react@18.0.28)(react@18.2.0)
- '@storybook/client-logger': 8.0.0-beta.2
+ '@storybook/client-logger': 8.0.0-beta.6
'@storybook/csf': 0.1.2
'@storybook/global': 5.0.0
'@storybook/icons': 1.2.5(react-dom@18.2.0)(react@18.2.0)
- '@storybook/theming': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/theming': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/types': 8.0.0-beta.6
memoizerific: 1.11.3
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
@@ -5934,13 +6218,13 @@ packages:
- '@types/react'
dev: true
- /@storybook/core-common@8.0.0-beta.2:
- resolution: {integrity: sha512-il2D+GpFg0MdVrQ04f2g5dopynleY9SbkDIfd28RCwTuMefy2exe9DEQoGFiEgBx9inJPS7L3WR0h0p6OMO9KA==}
+ /@storybook/core-common@8.0.0-beta.6:
+ resolution: {integrity: sha512-Mah4Kx/VBNhHaX6neYHTiVwfD93yf3LVVfLTS9WcJFOpek74EAAqbARV3vzOn/utOI75N7yu2PCVoKi5KkDoVw==}
dependencies:
- '@storybook/core-events': 8.0.0-beta.2
- '@storybook/csf-tools': 8.0.0-beta.2
- '@storybook/node-logger': 8.0.0-beta.2
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/core-events': 8.0.0-beta.6
+ '@storybook/csf-tools': 8.0.0-beta.6
+ '@storybook/node-logger': 8.0.0-beta.6
+ '@storybook/types': 8.0.0-beta.6
'@yarnpkg/fslib': 2.10.3
'@yarnpkg/libzip': 2.3.0
chalk: 4.1.2
@@ -5970,35 +6254,36 @@ packages:
- supports-color
dev: true
- /@storybook/core-events@8.0.0-beta.2:
- resolution: {integrity: sha512-C2o0ShpfIFvSDyqaNaXwEfvJaaFlR0rRfvD1a65FMEFM6YAttA/es6z2yjUySUR2vfJ/vwnEtJxs7eGmuQuBmA==}
+ /@storybook/core-events@8.0.0-beta.6:
+ resolution: {integrity: sha512-ZyEVkOJ5gGGTfHjyasyeZgNGoeVJwVkLFRpV6cUl8hzOT29R5iDsf5PbJdrpF1x2pm1oLumeRckYQ7sYhr+R/w==}
dependencies:
ts-dedent: 2.2.0
dev: true
- /@storybook/core-server@8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-J96aic++0180m6KrIerWxNAbDxjUnUor7smbVWFWcvvZAM2cW77Th2tIXxs5gcyJ6LEEAea/jYV0P+/I+afdoA==}
+ /@storybook/core-server@8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-0ciJTWZs+mCnQOUzB3WuSfkhwXKpO033M5iYK92PKu9A6KSrwdc/WCwIJHeBNnIpmxC0GEh9j6/CgIsWehwJvg==}
dependencies:
'@aw-web-design/x-default-browser': 1.4.126
+ '@babel/core': 7.24.0
'@discoveryjs/json-ext': 0.5.7
- '@storybook/builder-manager': 8.0.0-beta.2
- '@storybook/channels': 8.0.0-beta.2
- '@storybook/core-common': 8.0.0-beta.2
- '@storybook/core-events': 8.0.0-beta.2
+ '@storybook/builder-manager': 8.0.0-beta.6
+ '@storybook/channels': 8.0.0-beta.6
+ '@storybook/core-common': 8.0.0-beta.6
+ '@storybook/core-events': 8.0.0-beta.6
'@storybook/csf': 0.1.2
- '@storybook/csf-tools': 8.0.0-beta.2
+ '@storybook/csf-tools': 8.0.0-beta.6
'@storybook/docs-mdx': 3.0.0
'@storybook/global': 5.0.0
- '@storybook/manager': 8.0.0-beta.2
- '@storybook/manager-api': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/node-logger': 8.0.0-beta.2
- '@storybook/preview-api': 8.0.0-beta.2
- '@storybook/telemetry': 8.0.0-beta.2
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/manager': 8.0.0-beta.6
+ '@storybook/manager-api': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/node-logger': 8.0.0-beta.6
+ '@storybook/preview-api': 8.0.0-beta.6
+ '@storybook/telemetry': 8.0.0-beta.6
+ '@storybook/types': 8.0.0-beta.6
'@types/detect-port': 1.3.2
'@types/node': 18.17.15
'@types/pretty-hrtime': 1.0.1
- '@types/semver': 7.5.6
+ '@types/semver': 7.5.8
better-opn: 3.0.2
chalk: 4.1.2
cli-table3: 0.6.3
@@ -6007,7 +6292,7 @@ packages:
express: 4.18.2
fs-extra: 11.1.1
globby: 11.1.0
- ip: 2.0.0
+ ip: 2.0.1
lodash: 4.17.21
open: 8.4.2
pretty-hrtime: 1.0.3
@@ -6030,24 +6315,24 @@ packages:
- utf-8-validate
dev: true
- /@storybook/csf-plugin@8.0.0-beta.2:
- resolution: {integrity: sha512-gdOiI57mkMwgPXnONE1bY4myX2dkol2UdzHYB12QEp9rxE+DHFudCYhxHIj4uyTybTXCjffXAgjlFyT8vBfYUA==}
+ /@storybook/csf-plugin@8.0.0-beta.6:
+ resolution: {integrity: sha512-cYI/4OndODf0utV0DxJs8AOKbmjCG+pEgxQGcmPtGnkSmEuieUwpQpN7v+fEIN7IPUQLYvs0wspR0njZQAIzyA==}
dependencies:
- '@storybook/csf-tools': 8.0.0-beta.2
+ '@storybook/csf-tools': 8.0.0-beta.6
unplugin: 1.4.0
transitivePeerDependencies:
- supports-color
dev: true
- /@storybook/csf-tools@8.0.0-beta.2:
- resolution: {integrity: sha512-vujr640EkjkCj8h9r579wugSuKdc3Hbd8GWWiWnCQCRMYW6j9Axj79W8lNOz+u3yWSy6FhqWXqUxr0eMcAv1NQ==}
+ /@storybook/csf-tools@8.0.0-beta.6:
+ resolution: {integrity: sha512-wwzbE6f8ykrvIeZlXYTba0IA8D5GPSyZ4L0+PqRAYHm3ozu0DXqtm4USDHKrjYAzuD+W+fG/6qIOQmsWYbNmpA==}
dependencies:
'@babel/generator': 7.23.5
'@babel/parser': 7.23.9
'@babel/traverse': 7.23.5
'@babel/types': 7.23.5
'@storybook/csf': 0.1.2
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/types': 8.0.0-beta.6
fs-extra: 11.1.1
recast: 0.23.4
ts-dedent: 2.2.0
@@ -6065,12 +6350,12 @@ packages:
resolution: {integrity: sha512-NmiGXl2HU33zpwTv1XORe9XG9H+dRUC1Jl11u92L4xr062pZtrShLmD4VKIsOQujxhhOrbxpwhNOt+6TdhyIdQ==}
dev: true
- /@storybook/docs-tools@8.0.0-beta.2:
- resolution: {integrity: sha512-uw2F9bhbotZ/v6+FFFv2jj+Oflfd+7gVj5vQttAVQ4o+f6hSsOQkvLeRc5pbs9/ANhB4OVKp23CZBcuySfDtTg==}
+ /@storybook/docs-tools@8.0.0-beta.6:
+ resolution: {integrity: sha512-fSKXEu0vegzqC2HT1RaOKqi0+W/vIn+qa5D+dZHkj2BnceYxWAGYsX9ZZPHW6DUvvwp0WZp1vz57nPUhsLvcQg==}
dependencies:
- '@storybook/core-common': 8.0.0-beta.2
- '@storybook/preview-api': 8.0.0-beta.2
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/core-common': 8.0.0-beta.6
+ '@storybook/preview-api': 8.0.0-beta.6
+ '@storybook/types': 8.0.0-beta.6
'@types/doctrine': 0.0.3
assert: 2.1.0
doctrine: 3.0.0
@@ -6095,29 +6380,29 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: true
- /@storybook/instrumenter@8.0.0-beta.2:
- resolution: {integrity: sha512-44W0krseJHhJ4u8auD2QB6civNjBWdAuc7pxJ/IYgIO7Hd3yGnJpDrcOUpaUpPT3WhLFpbbASjQIlauED0DiXw==}
+ /@storybook/instrumenter@8.0.0-beta.6:
+ resolution: {integrity: sha512-xJ3qkvj8dce7nJEa6hmp4PDDZJMBuP5UlSKPidiMAfEsB0MeUbDulTFNDb0t1DwcH9ywinDl8TilSzG4+r1kDA==}
dependencies:
- '@storybook/channels': 8.0.0-beta.2
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/core-events': 8.0.0-beta.2
+ '@storybook/channels': 8.0.0-beta.6
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/core-events': 8.0.0-beta.6
'@storybook/global': 5.0.0
- '@storybook/preview-api': 8.0.0-beta.2
+ '@storybook/preview-api': 8.0.0-beta.6
'@vitest/utils': 0.34.6
util: 0.12.5
dev: true
- /@storybook/manager-api@8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-LMgxSXqpB8Zdtmvs0rthityGE77rVgQ82gq+LBMaBEEFlwdSfYhoLLnlNLHrc3m8A2mTXJ4/aDhvTTjh9PPG5w==}
+ /@storybook/manager-api@8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-kOGOT/yGFgKzld9IL1HREouFwZ0LpFuXZZOHBih5ydK8XT+bkWF6e3SiqthB3qtqpd0eVLAbNiPfY9R8t3qfWg==}
dependencies:
- '@storybook/channels': 8.0.0-beta.2
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/core-events': 8.0.0-beta.2
+ '@storybook/channels': 8.0.0-beta.6
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/core-events': 8.0.0-beta.6
'@storybook/csf': 0.1.2
'@storybook/global': 5.0.0
- '@storybook/router': 8.0.0-beta.2
- '@storybook/theming': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/router': 8.0.0-beta.6
+ '@storybook/theming': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/types': 8.0.0-beta.6
dequal: 2.0.3
lodash: 4.17.21
memoizerific: 1.11.3
@@ -6129,23 +6414,23 @@ packages:
- react-dom
dev: true
- /@storybook/manager@8.0.0-beta.2:
- resolution: {integrity: sha512-eho+n+gUjuNlX5HQYoOKKvWjTcL96kwp9KdAmrhUn3KMNLkG8kax9iEUSFKG2p+tR+YAxsJJzDlC9gV4XzbBGA==}
+ /@storybook/manager@8.0.0-beta.6:
+ resolution: {integrity: sha512-FeQ2/CIasSOgcTMEE3QYMFa92KeMnfEMyUVO4hHEmPh3SqPsz6OOv8p0bQvN0SWWBgZarbhFR0dKC3W10yYrXg==}
dev: true
- /@storybook/node-logger@8.0.0-beta.2:
- resolution: {integrity: sha512-bBTayxV0B87FPL+suMGxpMfPzUhAwu/yO8c6glLJ4xVHJlUNn+tVQpLDehU6NeqgYTdAg9oh0fi9ufZoROVfMw==}
+ /@storybook/node-logger@8.0.0-beta.6:
+ resolution: {integrity: sha512-nmBlmZ8wzJiU1/ubhUmFeWQaJPBv6l6s0Cndk04omPSjROa+O1whoPhDTVGvWC28zm17tmAYVcQRujkdoi+YBA==}
dev: true
- /@storybook/preview-api@8.0.0-beta.2:
- resolution: {integrity: sha512-eekdhIwSOI3RnLDHJViLBBoTuSmQUo7Oa1FGU/gDx7ZEofNF+k2N4FdFPRc72Dkv4SI7hGmoJJWbPA6BR2ZHww==}
+ /@storybook/preview-api@8.0.0-beta.6:
+ resolution: {integrity: sha512-V07MF1ArjBGi2EPSjrEW8pjCoW/TIwxNDilcO9cD12LHrDQGXuo/iKyR47TGUYmcJ/u1I2Eu9cjyVj9DVyppag==}
dependencies:
- '@storybook/channels': 8.0.0-beta.2
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/core-events': 8.0.0-beta.2
+ '@storybook/channels': 8.0.0-beta.6
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/core-events': 8.0.0-beta.6
'@storybook/csf': 0.1.2
'@storybook/global': 5.0.0
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/types': 8.0.0-beta.6
'@types/qs': 6.9.7
dequal: 2.0.3
lodash: 4.17.21
@@ -6156,12 +6441,12 @@ packages:
util-deprecate: 1.0.2
dev: true
- /@storybook/preview@8.0.0-beta.2:
- resolution: {integrity: sha512-n9OqS5KRdUGD3oImCG5NzUIZabcV/A3LifD2YOYCyJHS4U9yg4Wse2o6Px8niklAstAdFFOP2iyMQxjt0iQ0DA==}
+ /@storybook/preview@8.0.0-beta.6:
+ resolution: {integrity: sha512-tp3Wyvjsbf5r5RhbCQSafArQWJAir1bmIJWGG2S4o2E3YT6TlHFpR078tNJtgXqsPyG0yhF9vhRRkDczrPX/Gw==}
dev: true
- /@storybook/react-dom-shim@8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-z372LCk+5WbSX/nWpnYaxP4oWoeKTtmq7CHqK7pWrdtZJRwZJbsIKZdZragzO4yyfZLEuAybw7kR9qgCqz1ToA==}
+ /@storybook/react-dom-shim@8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-l14oDKAW2jyrXynHKP6SoNGal78gXcWCgj0zLwSDWpKgAFWC7SuIneuxLv6weU1D4+f9Y9FBrz+K3CCaMgMtOA==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -6170,23 +6455,23 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: true
- /@storybook/react-vite@8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.1.0):
- resolution: {integrity: sha512-PKbOW0JP03e0x9cndFkCXoCUUQ+P7C7JzUnURRz/uRGXl/DUiR1IcjxL0aNT7uv9Gm+whpnGCP977RHFrvMlqA==}
+ /@storybook/react-vite@8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)(rollup@4.12.0)(typescript@5.3.3)(vite@5.1.4):
+ resolution: {integrity: sha512-Tvz25pTXmhncDxprjIYsnXc68Lfa9idDybpRTRRbtvjsJyVpZogUdgz2/kddGNTuX3mqz6vmTMWiLiIVh+ytQA==}
engines: {node: '>=18.0.0'}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
vite: ^4.0.0 || ^5.0.0
dependencies:
- '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.3.3)(vite@5.1.0)
- '@rollup/pluginutils': 5.1.0(rollup@4.9.6)
- '@storybook/builder-vite': 8.0.0-beta.2(typescript@5.3.3)(vite@5.1.0)
- '@storybook/react': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)
+ '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.3.3)(vite@5.1.4)
+ '@rollup/pluginutils': 5.1.0(rollup@4.12.0)
+ '@storybook/builder-vite': 8.0.0-beta.6(typescript@5.3.3)(vite@5.1.4)
+ '@storybook/react': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)
magic-string: 0.30.7
react: 18.2.0
react-docgen: 7.0.1
react-dom: 18.2.0(react@18.2.0)
- vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0)
+ vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1)
transitivePeerDependencies:
- '@preact/preset-vite'
- encoding
@@ -6196,8 +6481,8 @@ packages:
- vite-plugin-glimmerx
dev: true
- /@storybook/react@8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3):
- resolution: {integrity: sha512-6Snd+u9UQHrzYkmEYi/BxJMl1FNnJI+3aXdopiwdslze9bosZg0glK4TKBvhqGwCBYLnKgzKHXhttMECWQApFA==}
+ /@storybook/react@8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3):
+ resolution: {integrity: sha512-69B0c08HDYHEgZRRnkB+3z4dY/HO/GMSiRzRCNpzI0SBQzk1YwDzG9MOtkNgGqzdLK3e3DveSXb5Uyy1cB0ZiQ==}
engines: {node: '>=18.0.0'}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -6207,12 +6492,12 @@ packages:
typescript:
optional: true
dependencies:
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/docs-tools': 8.0.0-beta.2
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/docs-tools': 8.0.0-beta.6
'@storybook/global': 5.0.0
- '@storybook/preview-api': 8.0.0-beta.2
- '@storybook/react-dom-shim': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/preview-api': 8.0.0-beta.6
+ '@storybook/react-dom-shim': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/types': 8.0.0-beta.6
'@types/escodegen': 0.0.6
'@types/estree': 0.0.51
'@types/node': 18.17.15
@@ -6236,30 +6521,30 @@ packages:
- supports-color
dev: true
- /@storybook/router@8.0.0-beta.2:
- resolution: {integrity: sha512-bnNEayh3g4KZUVmH7zlJZ0tdSE6lJZZhUDE61bjPHjweLx3xYLlev0A8EwzAjz1BBpr4H8UtyYa32C7+G1Urxw==}
+ /@storybook/router@8.0.0-beta.6:
+ resolution: {integrity: sha512-JjLyDaVzCH3kmNsOkuJ8/U2bPIoReZZ/QsgHJdfvm22T2wKNjQ+lfNrQptBgNybfi1o/Tmn9VbCdRqurSlh9Dw==}
dependencies:
- '@storybook/client-logger': 8.0.0-beta.2
+ '@storybook/client-logger': 8.0.0-beta.6
memoizerific: 1.11.3
qs: 6.11.1
dev: true
- /@storybook/source-loader@8.0.0-beta.2:
- resolution: {integrity: sha512-nSGtn7y/o4aaHVI2mw2Xi/GIElfqMUah9uHFtEzl+vT0JIOs7jImR9dblpR5jGFRZM/2Waod8aXJ+hYkQ7MaQA==}
+ /@storybook/source-loader@8.0.0-beta.6:
+ resolution: {integrity: sha512-cYtjnuJZgm8MS9SsNsbuhuFz2d7j6BKRLZByBUqELrK+ftup0qqOWM+78w26qn3nPgA8myZXWxGa+V/Pjxio5w==}
dependencies:
'@storybook/csf': 0.1.2
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/types': 8.0.0-beta.6
estraverse: 5.3.0
lodash: 4.17.21
prettier: 3.2.5
dev: true
- /@storybook/telemetry@8.0.0-beta.2:
- resolution: {integrity: sha512-jc2w//1ZYn0EuDOjtBx27uTpThjFj2+0fNf0G83+BmZR8yJciBj+YXrzQB6FWdiKyT4WLaH4la1ZlaiJP+ZdYQ==}
+ /@storybook/telemetry@8.0.0-beta.6:
+ resolution: {integrity: sha512-3CU5Sdj8eVm0tb35GriMkDrxJyTpdGcfU/hgUnsuw+I4eHYdZsc4Boh9uXWTVNsaBaoqbD/MP1aqbfxkElqPxQ==}
dependencies:
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/core-common': 8.0.0-beta.2
- '@storybook/csf-tools': 8.0.0-beta.2
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/core-common': 8.0.0-beta.6
+ '@storybook/csf-tools': 8.0.0-beta.6
chalk: 4.1.2
detect-package-manager: 2.0.1
fetch-retry: 5.0.4
@@ -6270,16 +6555,16 @@ packages:
- supports-color
dev: true
- /@storybook/test@8.0.0-beta.2(vitest@0.34.6):
- resolution: {integrity: sha512-sMo5mUKMOLoPMOWvAvK++V9Db6qO5bgGr1JLmnX+1YTh3mzZzOlsKe5nEKdEBjT1iI1OstypDg+oKHAEfg5Oag==}
+ /@storybook/test@8.0.0-beta.6(vitest@0.34.6):
+ resolution: {integrity: sha512-GcV76EX3U77G+k8+0V+jAa/sJQZEuNb/4W+g/RaqGLRCEG73UADzkgRuFm60UQUBGtltvvRZU9sIPVbFTJFxuA==}
dependencies:
- '@storybook/client-logger': 8.0.0-beta.2
- '@storybook/core-events': 8.0.0-beta.2
- '@storybook/instrumenter': 8.0.0-beta.2
- '@storybook/preview-api': 8.0.0-beta.2
+ '@storybook/client-logger': 8.0.0-beta.6
+ '@storybook/core-events': 8.0.0-beta.6
+ '@storybook/instrumenter': 8.0.0-beta.6
+ '@storybook/preview-api': 8.0.0-beta.6
'@testing-library/dom': 9.3.3
'@testing-library/jest-dom': 6.4.2(vitest@0.34.6)
- '@testing-library/user-event': 14.3.0(@testing-library/dom@9.3.3)
+ '@testing-library/user-event': 14.5.2(@testing-library/dom@9.3.3)
'@vitest/expect': 1.1.3
'@vitest/spy': 1.2.2
chai: 4.3.10
@@ -6292,8 +6577,8 @@ packages:
- vitest
dev: true
- /@storybook/theming@8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-Nl3eCdsBVjh98sghb7YF/v+65bUWEyJfvhU7aQHxRcYoBw+UKJIX5FKSd+PFnC/BOkH0So2ngDU2XFoOdA6BPg==}
+ /@storybook/theming@8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-WXvDbV257fKbHM5jHd7hOHefRSBnyZec08NGpcVOG6muJjLu8nPjazcYgISqFc97MkFmxvEDPFfX8CvBEeefzA==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -6304,33 +6589,36 @@ packages:
optional: true
dependencies:
'@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0)
- '@storybook/client-logger': 8.0.0-beta.2
+ '@storybook/client-logger': 8.0.0-beta.6
'@storybook/global': 5.0.0
memoizerific: 1.11.3
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: true
- /@storybook/types@8.0.0-beta.2:
- resolution: {integrity: sha512-MK6QFpMGWxu+sLCw8VrXmL0gOJ3g6XPpV85T5s+CEMsfMhSH5wCMdhtWkCRbHGfVEPKa5fEtA0SaGLqJhnSpQw==}
+ /@storybook/types@8.0.0-beta.6:
+ resolution: {integrity: sha512-w3jq8mBcxir4P0RK3gQePeUJ0rXbnUbCKg91YBOKeitmU0+4jSr4e1EwTWOYgsyz7KtikzSNr8JXtMQn2TJD5A==}
dependencies:
- '@storybook/channels': 8.0.0-beta.2
+ '@storybook/channels': 8.0.0-beta.6
'@types/express': 4.17.17
file-system-cache: 2.3.0
dev: true
- /@storybook/vue3-vite@8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)(vite@5.1.0)(vue@3.4.18):
- resolution: {integrity: sha512-Pzth2PEEmLyI2hW827x+Cd4nYO6xayAsWk46JdXjfHOVnHDgp6CZPSi1zr79J+bbjvQtHHb+9BV4TljdiM0zxw==}
+ /@storybook/vue3-vite@8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)(vite@5.1.4)(vue@3.4.21):
+ resolution: {integrity: sha512-Pf9W7hcHjx1FE3JmhY1iSxGq9k/Tp5n/obOCd4FJGUdIttPYFclG9km49DrCJtNfhK7M6+d2QTZ6Uds4ORWZPg==}
engines: {node: '>=18.0.0'}
peerDependencies:
vite: ^4.0.0 || ^5.0.0
dependencies:
- '@storybook/builder-vite': 8.0.0-beta.2(typescript@5.3.3)(vite@5.1.0)
- '@storybook/core-server': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/vue3': 8.0.0-beta.2(vue@3.4.18)
+ '@storybook/builder-vite': 8.0.0-beta.6(typescript@5.3.3)(vite@5.1.4)
+ '@storybook/core-server': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/vue3': 8.0.0-beta.6(vue@3.4.21)
+ find-package-json: 1.2.0
magic-string: 0.30.7
- vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0)
- vue-docgen-api: 4.64.1(vue@3.4.18)
+ typescript: 5.3.3
+ vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1)
+ vue-component-meta: 1.8.27(typescript@5.3.3)
+ vue-docgen-api: 4.75.1(vue@3.4.21)
transitivePeerDependencies:
- '@preact/preset-vite'
- bufferutil
@@ -6338,27 +6626,26 @@ packages:
- react
- react-dom
- supports-color
- - typescript
- utf-8-validate
- vite-plugin-glimmerx
- vue
dev: true
- /@storybook/vue3@8.0.0-beta.2(vue@3.4.18):
- resolution: {integrity: sha512-lGupXqWl+/gx5in8jJEzxCHvtTfFHCemYFVMXUqNhJ+Chudwx7LRyy3frQ+0AE4FzGIIYWM/tJjkaKvtBQvEDg==}
+ /@storybook/vue3@8.0.0-beta.6(vue@3.4.21):
+ resolution: {integrity: sha512-027KDM1f6y0XzMK1yE5W4JKY/VsbGpr1kj0mvEKxaPUYgBJV9wTHADWgmluiJS/e/MWrCCZql5mE+D9lVJUjoA==}
engines: {node: '>=18.0.0'}
peerDependencies:
vue: ^3.0.0
dependencies:
- '@storybook/docs-tools': 8.0.0-beta.2
+ '@storybook/docs-tools': 8.0.0-beta.6
'@storybook/global': 5.0.0
- '@storybook/preview-api': 8.0.0-beta.2
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/preview-api': 8.0.0-beta.6
+ '@storybook/types': 8.0.0-beta.6
'@vue/compiler-core': 3.4.18
lodash: 4.17.21
ts-dedent: 2.2.0
type-fest: 2.19.0
- vue: 3.4.18(typescript@5.3.3)
+ vue: 3.4.21(typescript@5.3.3)
vue-component-type-helpers: 1.8.27
transitivePeerDependencies:
- encoding
@@ -6953,11 +7240,11 @@ packages:
dom-accessibility-api: 0.6.3
lodash: 4.17.21
redent: 3.0.0
- vitest: 0.34.6(happy-dom@10.0.3)(sass@1.70.0)(terser@5.27.0)
+ vitest: 0.34.6(happy-dom@13.6.2)(sass@1.71.1)(terser@5.28.1)
dev: true
- /@testing-library/user-event@14.3.0(@testing-library/dom@9.3.3):
- resolution: {integrity: sha512-P02xtBBa8yMaLhK8CzJCIns8rqwnF6FxhR9zs810flHOBXUYCFjLd8Io1rQrAkQRWEmW2PGdZIEdMxf/KLsqFA==}
+ /@testing-library/user-event@14.5.2(@testing-library/dom@9.3.3):
+ resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==}
engines: {node: '>=12', npm: '>=6'}
peerDependencies:
'@testing-library/dom': '>=7.21.4'
@@ -6965,7 +7252,7 @@ packages:
'@testing-library/dom': 9.3.3
dev: true
- /@testing-library/vue@8.0.2(@vue/compiler-sfc@3.4.18)(vue@3.4.18):
+ /@testing-library/vue@8.0.2(@vue/compiler-sfc@3.4.21)(vue@3.4.21):
resolution: {integrity: sha512-A8wWX+qQn0o0izpQWnGCpwQt8wAdpsVP8vPP2h5Q/jcGhZ5yKXz9PPUqhQv+45LTFaWlyRf8bArTVaB/KFFd5A==}
engines: {node: '>=14'}
peerDependencies:
@@ -6977,9 +7264,9 @@ packages:
dependencies:
'@babel/runtime': 7.23.4
'@testing-library/dom': 9.3.3
- '@vue/compiler-sfc': 3.4.18
- '@vue/test-utils': 2.4.1(vue@3.4.18)
- vue: 3.4.18(typescript@5.3.3)
+ '@vue/compiler-sfc': 3.4.21
+ '@vue/test-utils': 2.4.1(vue@3.4.21)
+ vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- '@vue/server-renderer'
dev: true
@@ -7005,7 +7292,7 @@ packages:
/@types/accepts@1.3.7:
resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/archiver@6.0.2:
@@ -7059,7 +7346,7 @@ packages:
resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
dependencies:
'@types/connect': 3.4.35
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/braces@3.0.1:
@@ -7071,7 +7358,7 @@ packages:
dependencies:
'@types/http-cache-semantics': 4.0.4
'@types/keyv': 3.1.4
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
'@types/responselike': 1.0.0
dev: false
@@ -7098,7 +7385,7 @@ packages:
/@types/connect@3.4.35:
resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/content-disposition@0.5.8:
@@ -7112,7 +7399,7 @@ packages:
/@types/cross-spawn@6.0.2:
resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/debug@4.1.12:
@@ -7170,7 +7457,7 @@ packages:
/@types/express-serve-static-core@4.17.33:
resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
'@types/qs': 6.9.7
'@types/range-parser': 1.2.4
dev: true
@@ -7191,20 +7478,20 @@ packages:
/@types/fluent-ffmpeg@2.1.24:
resolution: {integrity: sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/glob@7.2.0:
resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==}
dependencies:
'@types/minimatch': 5.1.2
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/graceful-fs@4.1.6:
resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/hast@3.0.4:
@@ -7213,13 +7500,17 @@ packages:
'@types/unist': 3.0.2
dev: true
+ /@types/htmlescape@1.1.3:
+ resolution: {integrity: sha512-tuC81YJXGUe0q8WRtBNW+uyx79rkkzWK651ALIXXYq5/u/IxjX4iHneGF2uUqzsNp+F+9J2mFZOv9jiLTtIq0w==}
+ dev: true
+
/@types/http-cache-semantics@4.0.4:
resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==}
/@types/http-link-header@1.0.5:
resolution: {integrity: sha512-AxhIKR8UbyoqCTNp9rRepkktHuUOw3DjfOfDCaO9kwI8AYzjhxyrvZq4+mRw/2daD3hYDknrtSeV6SsPwmc71w==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/istanbul-lib-coverage@2.0.4:
@@ -7245,6 +7536,13 @@ packages:
pretty-format: 29.7.0
dev: true
+ /@types/jest@29.5.12:
+ resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==}
+ dependencies:
+ expect: 29.7.0
+ pretty-format: 29.7.0
+ dev: true
+
/@types/js-yaml@4.0.9:
resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
dev: true
@@ -7252,7 +7550,7 @@ packages:
/@types/jsdom@21.1.6:
resolution: {integrity: sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
'@types/tough-cookie': 4.0.2
parse5: 7.1.2
dev: true
@@ -7276,7 +7574,7 @@ packages:
/@types/keyv@3.1.4:
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: false
/@types/lodash@4.14.191:
@@ -7332,7 +7630,7 @@ packages:
resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==}
requiresBuild: true
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
form-data: 3.0.1
dev: false
@@ -7347,8 +7645,8 @@ packages:
resolution: {integrity: sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==}
dev: true
- /@types/node@20.11.17:
- resolution: {integrity: sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==}
+ /@types/node@20.11.22:
+ resolution: {integrity: sha512-/G+IxWxma6V3E+pqK1tSl2Fo1kl41pK1yeCyDsgkF9WlVAme4j5ISYM2zR11bgLFJGLN5sVK40T4RJNuiZbEjA==}
dependencies:
undici-types: 5.26.5
@@ -7367,7 +7665,7 @@ packages:
/@types/nodemailer@6.4.14:
resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/normalize-package-data@2.4.1:
@@ -7384,13 +7682,13 @@ packages:
resolution: {integrity: sha512-Ali0fUUn+zgr4Yy/pCTFbuiaiJpq7l7OQwFnxYVchNbNGIx0c4Wkcdje6WO89I91RAaYF+gVc1pOaizA4YKZmA==}
dependencies:
'@types/express': 4.17.17
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/oauth@0.9.4:
resolution: {integrity: sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/offscreencanvas@2019.3.0:
@@ -7403,10 +7701,10 @@ packages:
requiresBuild: true
dev: false
- /@types/pg@8.11.0:
- resolution: {integrity: sha512-sDAlRiBNthGjNFfvt0k6mtotoVYVQ63pA8R4EMWka7crawSR60waVYR0HAgmPRs/e2YaeJTD/43OoZ3PFw80pw==}
+ /@types/pg@8.11.2:
+ resolution: {integrity: sha512-G2Mjygf2jFMU/9hCaTYxJrwdObdcnuQde1gndooZSOHsNSaCehAuwc7EIuSA34Do8Jx2yZ19KtvW8P0j4EuUXw==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
pg-protocol: 1.6.0
pg-types: 4.0.1
dev: true
@@ -7423,14 +7721,14 @@ packages:
resolution: {integrity: sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==}
dev: true
- /@types/punycode@2.1.3:
- resolution: {integrity: sha512-dFkH9Mz0yY5UfQVSrpj1grQyqRwe4TohTLlHFx4Gli8/fsaNyoOVUAsiEBZk5JBwbEJVZ49W6st8D5g6dRJb/w==}
+ /@types/punycode@2.1.4:
+ resolution: {integrity: sha512-trzh6NzBnq8yw5e35f8xe8VTYjqM3NE7bohBtvDVf/dtUer3zYTLK1Ka3DG3p7bdtoaOHZucma6FfVKlQ134pQ==}
dev: true
/@types/qrcode@1.5.5:
resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/qs@6.9.7:
@@ -7460,7 +7758,7 @@ packages:
/@types/readdir-glob@1.1.1:
resolution: {integrity: sha512-ImM6TmoF8bgOwvehGviEj3tRdRBbQujr1N+0ypaln/GWjaerOB26jb93vsRHmdMtvVQZQebOlqt2HROark87mQ==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/rename@1.0.7:
@@ -7474,11 +7772,11 @@ packages:
/@types/responselike@1.0.0:
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: false
- /@types/sanitize-html@2.9.5:
- resolution: {integrity: sha512-2Sr1vd8Dw+ypsg/oDDfZ57OMSG2Befs+l2CMyCC5bVSK3CpE7lTB2aNlbbWzazgVA+Qqfuholwom6x/mWd1qmw==}
+ /@types/sanitize-html@2.11.0:
+ resolution: {integrity: sha512-7oxPGNQHXLHE48r/r/qjn7q0hlrs3kL7oZnGj0Wf/h9tj/6ibFyRkNbsDxaBBZ4XUZ0Dx5LGCyDJ04ytSofacQ==}
dependencies:
htmlparser2: 8.0.1
dev: true
@@ -7496,15 +7794,15 @@ packages:
resolution: {integrity: sha512-TY1eezMU2zH2ozQoAFAQFOPpvP15g+ZgSfTZt31AUUH/Rxtnz3H+A/Sv1Snw2/amp//omibc+AEkTaA8KUeOLQ==}
dev: true
- /@types/semver@7.5.6:
- resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==}
+ /@types/semver@7.5.8:
+ resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
dev: true
/@types/serve-static@1.15.1:
resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==}
dependencies:
'@types/mime': 3.0.1
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/serviceworker@0.0.67:
@@ -7568,13 +7866,13 @@ packages:
/@types/vary@1.1.3:
resolution: {integrity: sha512-XJT8/ZQCL7NUut9QDLf6l24JfAEl7bnNdgxfj50cHIpEPRJLHHDDFOAq6i+GsEmeFfH7NamhBE4c4Thtb2egWg==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/web-push@3.6.3:
resolution: {integrity: sha512-v3oT4mMJsHeJ/rraliZ+7TbZtr5bQQuxcgD7C3/1q/zkAj29c8RE0F9lVZVu3hiQe5Z9fYcBreV7TLnfKR+4mg==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/webgl-ext@0.0.30:
@@ -7585,7 +7883,7 @@ packages:
/@types/ws@8.5.10:
resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/@types/yargs-parser@21.0.0:
@@ -7608,7 +7906,7 @@ packages:
resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==}
requiresBuild: true
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
optional: true
@@ -7641,29 +7939,29 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/eslint-plugin@6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3):
- resolution: {integrity: sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==}
+ /@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3):
+ resolution: {integrity: sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
- '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
- eslint: ^7.0.0 || ^8.0.0
+ '@typescript-eslint/parser': ^7.0.0
+ eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@eslint-community/regexpp': 4.6.2
- '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3)
- '@typescript-eslint/scope-manager': 6.18.1
- '@typescript-eslint/type-utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3)
- '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3)
- '@typescript-eslint/visitor-keys': 6.18.1
+ '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/scope-manager': 7.1.0
+ '@typescript-eslint/type-utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
+ '@typescript-eslint/visitor-keys': 7.1.0
debug: 4.3.4(supports-color@8.1.1)
- eslint: 8.56.0
+ eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.2.4
natural-compare: 1.4.0
- semver: 7.5.4
+ semver: 7.6.0
ts-api-utils: 1.0.1(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
@@ -7691,22 +7989,22 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3):
- resolution: {integrity: sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==}
+ /@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3):
+ resolution: {integrity: sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
- eslint: ^7.0.0 || ^8.0.0
+ eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
- '@typescript-eslint/scope-manager': 6.18.1
- '@typescript-eslint/types': 6.18.1
- '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3)
- '@typescript-eslint/visitor-keys': 6.18.1
+ '@typescript-eslint/scope-manager': 7.1.0
+ '@typescript-eslint/types': 7.1.0
+ '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
+ '@typescript-eslint/visitor-keys': 7.1.0
debug: 4.3.4(supports-color@8.1.1)
- eslint: 8.56.0
+ eslint: 8.57.0
typescript: 5.3.3
transitivePeerDependencies:
- supports-color
@@ -7720,12 +8018,12 @@ packages:
'@typescript-eslint/visitor-keys': 6.11.0
dev: true
- /@typescript-eslint/scope-manager@6.18.1:
- resolution: {integrity: sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==}
+ /@typescript-eslint/scope-manager@7.1.0:
+ resolution: {integrity: sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==}
engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
- '@typescript-eslint/types': 6.18.1
- '@typescript-eslint/visitor-keys': 6.18.1
+ '@typescript-eslint/types': 7.1.0
+ '@typescript-eslint/visitor-keys': 7.1.0
dev: true
/@typescript-eslint/type-utils@6.11.0(eslint@8.53.0)(typescript@5.3.3):
@@ -7748,20 +8046,20 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/type-utils@6.18.1(eslint@8.56.0)(typescript@5.3.3):
- resolution: {integrity: sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==}
+ /@typescript-eslint/type-utils@7.1.0(eslint@8.57.0)(typescript@5.3.3):
+ resolution: {integrity: sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
- eslint: ^7.0.0 || ^8.0.0
+ eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
- '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3)
- '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
+ '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
debug: 4.3.4(supports-color@8.1.1)
- eslint: 8.56.0
+ eslint: 8.57.0
ts-api-utils: 1.0.1(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
@@ -7773,8 +8071,8 @@ packages:
engines: {node: ^16.0.0 || >=18.0.0}
dev: true
- /@typescript-eslint/types@6.18.1:
- resolution: {integrity: sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==}
+ /@typescript-eslint/types@7.1.0:
+ resolution: {integrity: sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==}
engines: {node: ^16.0.0 || >=18.0.0}
dev: true
@@ -7799,8 +8097,8 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/typescript-estree@6.18.1(typescript@5.3.3):
- resolution: {integrity: sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==}
+ /@typescript-eslint/typescript-estree@7.1.0(typescript@5.3.3):
+ resolution: {integrity: sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
typescript: '*'
@@ -7808,13 +8106,13 @@ packages:
typescript:
optional: true
dependencies:
- '@typescript-eslint/types': 6.18.1
- '@typescript-eslint/visitor-keys': 6.18.1
+ '@typescript-eslint/types': 7.1.0
+ '@typescript-eslint/visitor-keys': 7.1.0
debug: 4.3.4(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.3
- semver: 7.5.4
+ semver: 7.6.0
ts-api-utils: 1.0.1(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
@@ -7829,7 +8127,7 @@ packages:
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0)
'@types/json-schema': 7.0.12
- '@types/semver': 7.5.6
+ '@types/semver': 7.5.8
'@typescript-eslint/scope-manager': 6.11.0
'@typescript-eslint/types': 6.11.0
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3)
@@ -7840,20 +8138,20 @@ packages:
- typescript
dev: true
- /@typescript-eslint/utils@6.18.1(eslint@8.56.0)(typescript@5.3.3):
- resolution: {integrity: sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==}
+ /@typescript-eslint/utils@7.1.0(eslint@8.57.0)(typescript@5.3.3):
+ resolution: {integrity: sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
- eslint: ^7.0.0 || ^8.0.0
+ eslint: ^8.56.0
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@types/json-schema': 7.0.12
- '@types/semver': 7.5.6
- '@typescript-eslint/scope-manager': 6.18.1
- '@typescript-eslint/types': 6.18.1
- '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3)
- eslint: 8.56.0
- semver: 7.5.4
+ '@types/semver': 7.5.8
+ '@typescript-eslint/scope-manager': 7.1.0
+ '@typescript-eslint/types': 7.1.0
+ '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
+ eslint: 8.57.0
+ semver: 7.6.0
transitivePeerDependencies:
- supports-color
- typescript
@@ -7867,11 +8165,11 @@ packages:
eslint-visitor-keys: 3.4.3
dev: true
- /@typescript-eslint/visitor-keys@6.18.1:
- resolution: {integrity: sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==}
+ /@typescript-eslint/visitor-keys@7.1.0:
+ resolution: {integrity: sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==}
engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
- '@typescript-eslint/types': 6.18.1
+ '@typescript-eslint/types': 7.1.0
eslint-visitor-keys: 3.4.3
dev: true
@@ -7879,15 +8177,15 @@ packages:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
dev: true
- /@vitejs/plugin-vue@5.0.3(vite@5.1.0)(vue@3.4.18):
- resolution: {integrity: sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==}
+ /@vitejs/plugin-vue@5.0.4(vite@5.1.4)(vue@3.4.21):
+ resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==}
engines: {node: ^18.0.0 || >=20.0.0}
peerDependencies:
vite: ^5.0.0
vue: ^3.2.25
dependencies:
- vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0)
- vue: 3.4.18(typescript@5.3.3)
+ vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1)
+ vue: 3.4.21(typescript@5.3.3)
dev: false
/@vitest/coverage-v8@0.34.6(vitest@0.34.6):
@@ -7906,7 +8204,7 @@ packages:
std-env: 3.7.0
test-exclude: 6.0.0
v8-to-istanbul: 9.2.0
- vitest: 0.34.6(happy-dom@10.0.3)(sass@1.70.0)(terser@5.27.0)
+ vitest: 0.34.6(happy-dom@13.6.2)(sass@1.71.1)(terser@5.28.1)
transitivePeerDependencies:
- supports-color
dev: true
@@ -8005,31 +8303,48 @@ packages:
entities: 4.5.0
estree-walker: 2.0.2
source-map-js: 1.0.2
+ dev: true
+
+ /@vue/compiler-core@3.4.21:
+ resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==}
+ dependencies:
+ '@babel/parser': 7.23.9
+ '@vue/shared': 3.4.21
+ entities: 4.5.0
+ estree-walker: 2.0.2
+ source-map-js: 1.0.2
/@vue/compiler-dom@3.4.18:
resolution: {integrity: sha512-24Eb8lcMfInefvQ6YlEVS18w5Q66f4+uXWVA+yb7praKbyjHRNuKVWGuinfSSjM0ZIiPi++QWukhkgznBaqpEA==}
dependencies:
'@vue/compiler-core': 3.4.18
'@vue/shared': 3.4.18
+ dev: true
- /@vue/compiler-sfc@3.4.18:
- resolution: {integrity: sha512-rG5tqtnzwrVpMqAQ7FHtvHaV70G6LLfJIWLYZB/jZ9m/hrnZmIQh+H3ewnC5onwe/ibljm9+ZupxeElzqCkTAw==}
+ /@vue/compiler-dom@3.4.21:
+ resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==}
+ dependencies:
+ '@vue/compiler-core': 3.4.21
+ '@vue/shared': 3.4.21
+
+ /@vue/compiler-sfc@3.4.21:
+ resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==}
dependencies:
'@babel/parser': 7.23.9
- '@vue/compiler-core': 3.4.18
- '@vue/compiler-dom': 3.4.18
- '@vue/compiler-ssr': 3.4.18
- '@vue/shared': 3.4.18
+ '@vue/compiler-core': 3.4.21
+ '@vue/compiler-dom': 3.4.21
+ '@vue/compiler-ssr': 3.4.21
+ '@vue/shared': 3.4.21
estree-walker: 2.0.2
magic-string: 0.30.7
- postcss: 8.4.33
+ postcss: 8.4.35
source-map-js: 1.0.2
- /@vue/compiler-ssr@3.4.18:
- resolution: {integrity: sha512-hSlv20oUhPxo2UYUacHgGaxtqP0tvFo6ixxxD6JlXIkwzwoZ9eKK6PFQN4hNK/R13JlNyldwWt/fqGBKgWJ6nQ==}
+ /@vue/compiler-ssr@3.4.21:
+ resolution: {integrity: sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==}
dependencies:
- '@vue/compiler-dom': 3.4.18
- '@vue/shared': 3.4.18
+ '@vue/compiler-dom': 3.4.21
+ '@vue/shared': 3.4.21
/@vue/language-core@1.8.27(typescript@5.3.3):
resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==}
@@ -8051,32 +8366,32 @@ packages:
vue-template-compiler: 2.7.14
dev: true
- /@vue/reactivity@3.4.18:
- resolution: {integrity: sha512-7uda2/I0jpLiRygprDo5Jxs2HJkOVXcOMlyVlY54yRLxoycBpwGJRwJT9EdGB4adnoqJDXVT2BilUAYwI7qvmg==}
+ /@vue/reactivity@3.4.21:
+ resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==}
dependencies:
- '@vue/shared': 3.4.18
+ '@vue/shared': 3.4.21
- /@vue/runtime-core@3.4.18:
- resolution: {integrity: sha512-7mU9diCa+4e+8/wZ7Udw5pwTH10A11sZ1nldmHOUKJnzCwvZxfJqAtw31mIf4T5H2FsLCSBQT3xgioA9vIjyDQ==}
+ /@vue/runtime-core@3.4.21:
+ resolution: {integrity: sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==}
dependencies:
- '@vue/reactivity': 3.4.18
- '@vue/shared': 3.4.18
+ '@vue/reactivity': 3.4.21
+ '@vue/shared': 3.4.21
- /@vue/runtime-dom@3.4.18:
- resolution: {integrity: sha512-2y1Mkzcw1niSfG7z3Qx+2ir9Gb4hdTkZe5p/I8x1aTIKQE0vY0tPAEUPhZm5tx6183gG3D/KwHG728UR0sIufA==}
+ /@vue/runtime-dom@3.4.21:
+ resolution: {integrity: sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==}
dependencies:
- '@vue/runtime-core': 3.4.18
- '@vue/shared': 3.4.18
+ '@vue/runtime-core': 3.4.21
+ '@vue/shared': 3.4.21
csstype: 3.1.3
- /@vue/server-renderer@3.4.18(vue@3.4.18):
- resolution: {integrity: sha512-YJd1wa7mzUN3NRqLEsrwEYWyO+PUBSROIGlCc3J/cvn7Zu6CxhNLgXa8Z4zZ5ja5/nviYO79J1InoPeXgwBTZA==}
+ /@vue/server-renderer@3.4.21(vue@3.4.21):
+ resolution: {integrity: sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==}
peerDependencies:
- vue: 3.4.18
+ vue: 3.4.21
dependencies:
- '@vue/compiler-ssr': 3.4.18
- '@vue/shared': 3.4.18
- vue: 3.4.18(typescript@5.3.3)
+ '@vue/compiler-ssr': 3.4.21
+ '@vue/shared': 3.4.21
+ vue: 3.4.21(typescript@5.3.3)
/@vue/shared@3.3.12:
resolution: {integrity: sha512-6p0Yin0pclvnER7BLNOQuod9Z+cxSYh8pSh7CzHnWNjAIP6zrTlCdHRvSCb1aYEx6i3Q3kvfuWU7nG16CgG1ag==}
@@ -8084,8 +8399,12 @@ packages:
/@vue/shared@3.4.18:
resolution: {integrity: sha512-CxouGFxxaW5r1WbrSmWwck3No58rApXgRSBxrqgnY1K+jk20F6DrXJkHdH9n4HVT+/B6G2CAn213Uq3npWiy8Q==}
+ dev: true
- /@vue/test-utils@2.4.1(vue@3.4.18):
+ /@vue/shared@3.4.21:
+ resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==}
+
+ /@vue/test-utils@2.4.1(vue@3.4.21):
resolution: {integrity: sha512-VO8nragneNzUZUah6kOjiFmD/gwRjUauG9DROh6oaOeFwX1cZRUNHhdeogE8635cISigXFTtGLUQWx5KCb0xeg==}
peerDependencies:
'@vue/server-renderer': ^3.0.1
@@ -8095,7 +8414,7 @@ packages:
optional: true
dependencies:
js-beautify: 1.14.9
- vue: 3.4.18(typescript@5.3.3)
+ vue: 3.4.21(typescript@5.3.3)
vue-component-type-helpers: 1.8.4
dev: true
@@ -8535,20 +8854,6 @@ packages:
resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
dev: true
- /ast-types@0.14.2:
- resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==}
- engines: {node: '>=4'}
- dependencies:
- tslib: 2.6.2
- dev: true
-
- /ast-types@0.15.2:
- resolution: {integrity: sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==}
- engines: {node: '>=4'}
- dependencies:
- tslib: 2.6.2
- dev: true
-
/ast-types@0.16.1:
resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
engines: {node: '>=4'}
@@ -8833,6 +9138,7 @@ packages:
buffer: 5.7.1
inherits: 2.0.4
readable-stream: 3.6.0
+ dev: true
/blob-util@2.0.2:
resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==}
@@ -8947,6 +9253,18 @@ packages:
electron-to-chromium: 1.4.601
node-releases: 2.0.14
update-browserslist-db: 1.0.13(browserslist@4.22.2)
+ dev: true
+
+ /browserslist@4.23.0:
+ resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+ dependencies:
+ caniuse-lite: 1.0.30001591
+ electron-to-chromium: 1.4.686
+ node-releases: 2.0.14
+ update-browserslist-db: 1.0.13(browserslist@4.23.0)
+ dev: false
/bser@2.1.1:
resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
@@ -8981,6 +9299,7 @@ packages:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
+ dev: true
/buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
@@ -8996,13 +9315,14 @@ packages:
dependencies:
node-gyp-build: 4.6.0
- /bullmq@5.1.9:
- resolution: {integrity: sha512-9MfcQxYyfkG8kxpIxRsRXWYlTRQ1o8xWqgdoFR5pLClVTjtMI8qeDO5basRQLZPfp/uiPtv+gpzJ3OTNrm2ZNg==}
+ /bullmq@5.4.0:
+ resolution: {integrity: sha512-QNOT+Vp/OFctwKa1/LYvrfIMXqb6Hu8a1VwXxQpa/JXoFAQ9E4ZcqW4fyEjx9iYrXakpV6cAGPbmdgWaKTGXOQ==}
dependencies:
cron-parser: 4.8.1
- glob: 8.1.0
+ fast-glob: 3.3.2
ioredis: 5.3.2
lodash: 4.17.21
+ minimatch: 9.0.3
msgpackr: 1.10.1
node-abort-controller: 3.1.1
semver: 7.5.4
@@ -9129,7 +9449,7 @@ packages:
/caniuse-api@3.0.0:
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
dependencies:
- browserslist: 4.22.2
+ browserslist: 4.23.0
caniuse-lite: 1.0.30001566
lodash.memoize: 4.1.2
lodash.uniq: 4.5.0
@@ -9138,39 +9458,21 @@ packages:
/caniuse-lite@1.0.30001566:
resolution: {integrity: sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==}
+ /caniuse-lite@1.0.30001591:
+ resolution: {integrity: sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==}
+ dev: false
+
/canonicalize@1.0.8:
resolution: {integrity: sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==}
dev: false
- /canvas-confetti@1.6.1:
- resolution: {integrity: sha512-CgGR5DL9+dkne4AwcpvWQc0LIQq43yDIxlwdZcyrq3yklricNfuPHoOSoM6Ya7yCQ+sXmZ2iNV2feiKjVG8C1g==}
+ /canvas-confetti@1.9.2:
+ resolution: {integrity: sha512-6Xi7aHHzKwxZsem4mCKoqP6YwUG3HamaHHAlz1hTNQPCqXhARFpSXnkC9TWlahHY5CG6hSL5XexNjxK8irVErg==}
dev: false
/caseless@0.12.0:
resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
- /cbor-extract@2.1.1:
- resolution: {integrity: sha512-1UX977+L+zOJHsp0mWFG13GLwO6ucKgSmSW6JTl8B9GUvACvHeIVpFqhU92299Z6PfD09aTXDell5p+lp1rUFA==}
- hasBin: true
- requiresBuild: true
- dependencies:
- node-gyp-build-optional-packages: 5.0.3
- optionalDependencies:
- '@cbor-extract/cbor-extract-darwin-arm64': 2.1.1
- '@cbor-extract/cbor-extract-darwin-x64': 2.1.1
- '@cbor-extract/cbor-extract-linux-arm': 2.1.1
- '@cbor-extract/cbor-extract-linux-arm64': 2.1.1
- '@cbor-extract/cbor-extract-linux-x64': 2.1.1
- '@cbor-extract/cbor-extract-win32-x64': 2.1.1
- dev: false
- optional: true
-
- /cbor-x@1.5.4:
- resolution: {integrity: sha512-PVKILDn+Rf6MRhhcyzGXi5eizn1i0i3F8Fe6UMMxXBnWkalq9+C5+VTmlIjAYM4iF2IYF2N+zToqAfYOp+3rfw==}
- optionalDependencies:
- cbor-extract: 2.1.1
- dev: false
-
/cbor@9.0.2:
resolution: {integrity: sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==}
engines: {node: '>=16'}
@@ -9248,45 +9550,45 @@ packages:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
dev: true
- /chart.js@4.4.1:
- resolution: {integrity: sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==}
- engines: {pnpm: '>=7'}
+ /chart.js@4.4.2:
+ resolution: {integrity: sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==}
+ engines: {pnpm: '>=8'}
dependencies:
'@kurkle/color': 0.3.2
dev: false
- /chartjs-adapter-date-fns@3.0.0(chart.js@4.4.1)(date-fns@2.30.0):
+ /chartjs-adapter-date-fns@3.0.0(chart.js@4.4.2)(date-fns@2.30.0):
resolution: {integrity: sha512-Rs3iEB3Q5pJ973J93OBTpnP7qoGwvq3nUnoMdtxO+9aoJof7UFcRbWcIDteXuYd1fgAvct/32T9qaLyLuZVwCg==}
peerDependencies:
chart.js: '>=2.8.0'
date-fns: '>=2.0.0'
dependencies:
- chart.js: 4.4.1
+ chart.js: 4.4.2
date-fns: 2.30.0
dev: false
- /chartjs-chart-matrix@2.0.1(chart.js@4.4.1):
+ /chartjs-chart-matrix@2.0.1(chart.js@4.4.2):
resolution: {integrity: sha512-BGfeY+/PHnITyDlc7WfnKJ1RyOfgOzIqWp/gxzzl7pUjyoGzHDcw51qd2xJF9gdT9Def7ZwOnOMm8GJUXDxI0w==}
peerDependencies:
chart.js: '>=3.0.0'
dependencies:
- chart.js: 4.4.1
+ chart.js: 4.4.2
dev: false
- /chartjs-plugin-gradient@0.6.1(chart.js@4.4.1):
+ /chartjs-plugin-gradient@0.6.1(chart.js@4.4.2):
resolution: {integrity: sha512-TGHNIh8KqQMLdb+UfY80cBHYRyOC47eeokmgkeajRdKGbFt462lJiyiq4ZJ25fiM7BGsmzoBLhmVyEw4B3gQxw==}
peerDependencies:
chart.js: '>=2.6.0'
dependencies:
- chart.js: 4.4.1
+ chart.js: 4.4.2
dev: false
- /chartjs-plugin-zoom@2.0.1(chart.js@4.4.1):
+ /chartjs-plugin-zoom@2.0.1(chart.js@4.4.2):
resolution: {integrity: sha512-ogOmLu6e+Q7E1XWOCOz9YwybMslz9qNfGV2a+qjfmqJYpsw5ZMoRHZBUyW+NGhkpQ5PwwPA/+rikHpBZb7PZuA==}
peerDependencies:
chart.js: '>=3.2.0'
dependencies:
- chart.js: 4.4.1
+ chart.js: 4.4.2
hammerjs: 2.0.8
dev: false
@@ -9345,16 +9647,16 @@ packages:
engines: {node: '>=10'}
requiresBuild: true
- /chromatic@10.6.1:
- resolution: {integrity: sha512-bd4C5sEEtN83uUmbc4Fu+x7+lJIPdMUdu4D6HRDQEIDl/Tatc8+By4bZluH1pzg/MbP9vllkL6Ua9vF4EEA7VA==}
+ /chromatic@11.0.0:
+ resolution: {integrity: sha512-utzRVqdMrpzYwZNf7dHWU0z0/rx6SH/FUVNozQxYHDtQfYUdEj+Ro4OSch5+Wsk2FoUmznJyLkaC2J839z1N7A==}
hasBin: true
peerDependencies:
- chromatic-cypress: ^0.4.0 || ^1.0.0
- chromatic-playwright: ^0.4.0 || ^1.0.0
+ '@chromatic-com/cypress': ^0.5.2 || ^1.0.0
+ '@chromatic-com/playwright': ^0.5.2 || ^1.0.0
peerDependenciesMeta:
- chromatic-cypress:
+ '@chromatic-com/cypress':
optional: true
- chromatic-playwright:
+ '@chromatic-com/playwright':
optional: true
dev: false
@@ -9717,7 +10019,7 @@ packages:
readable-stream: 3.6.0
dev: false
- /create-jest@29.7.0(@types/node@20.11.17):
+ /create-jest@29.7.0(@types/node@20.11.22):
resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -9726,7 +10028,7 @@ packages:
chalk: 4.1.2
exit: 0.1.2
graceful-fs: 4.2.11
- jest-config: 29.7.0(@types/node@20.11.17)
+ jest-config: 29.7.0(@types/node@20.11.22)
jest-util: 29.7.0
prompts: 2.4.2
transitivePeerDependencies:
@@ -9794,13 +10096,13 @@ packages:
engines: {node: '>=8'}
dev: true
- /css-declaration-sorter@7.1.1(postcss@8.4.33):
+ /css-declaration-sorter@7.1.1(postcss@8.4.35):
resolution: {integrity: sha512-dZ3bVTEEc1vxr3Bek9vGwfB5Z6ESPULhcRvO472mfjVnj8jRcTnKO8/JTczlvxM10Myb+wBM++1MtdO76eWcaQ==}
engines: {node: ^14 || ^16 || >=18}
peerDependencies:
postcss: ^8.0.9
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: false
/css-select@5.1.0:
@@ -9840,62 +10142,62 @@ packages:
engines: {node: '>=4'}
hasBin: true
- /cssnano-preset-default@6.0.3(postcss@8.4.33):
- resolution: {integrity: sha512-4y3H370aZCkT9Ev8P4SO4bZbt+AExeKhh8wTbms/X7OLDo5E7AYUUy6YPxa/uF5Grf+AJwNcCnxKhZynJ6luBA==}
+ /cssnano-preset-default@6.0.5(postcss@8.4.35):
+ resolution: {integrity: sha512-M+qRDEr5QZrfNl0B2ySdbTLGyNb8kBcSjuwR7WBamYBOEREH9t2efnB/nblekqhdGLZdkf4oZNetykG2JWRdZQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- css-declaration-sorter: 7.1.1(postcss@8.4.33)
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
- postcss-calc: 9.0.1(postcss@8.4.33)
- postcss-colormin: 6.0.2(postcss@8.4.33)
- postcss-convert-values: 6.0.2(postcss@8.4.33)
- postcss-discard-comments: 6.0.1(postcss@8.4.33)
- postcss-discard-duplicates: 6.0.1(postcss@8.4.33)
- postcss-discard-empty: 6.0.1(postcss@8.4.33)
- postcss-discard-overridden: 6.0.1(postcss@8.4.33)
- postcss-merge-longhand: 6.0.2(postcss@8.4.33)
- postcss-merge-rules: 6.0.3(postcss@8.4.33)
- postcss-minify-font-values: 6.0.1(postcss@8.4.33)
- postcss-minify-gradients: 6.0.1(postcss@8.4.33)
- postcss-minify-params: 6.0.2(postcss@8.4.33)
- postcss-minify-selectors: 6.0.2(postcss@8.4.33)
- postcss-normalize-charset: 6.0.1(postcss@8.4.33)
- postcss-normalize-display-values: 6.0.1(postcss@8.4.33)
- postcss-normalize-positions: 6.0.1(postcss@8.4.33)
- postcss-normalize-repeat-style: 6.0.1(postcss@8.4.33)
- postcss-normalize-string: 6.0.1(postcss@8.4.33)
- postcss-normalize-timing-functions: 6.0.1(postcss@8.4.33)
- postcss-normalize-unicode: 6.0.2(postcss@8.4.33)
- postcss-normalize-url: 6.0.1(postcss@8.4.33)
- postcss-normalize-whitespace: 6.0.1(postcss@8.4.33)
- postcss-ordered-values: 6.0.1(postcss@8.4.33)
- postcss-reduce-initial: 6.0.2(postcss@8.4.33)
- postcss-reduce-transforms: 6.0.1(postcss@8.4.33)
- postcss-svgo: 6.0.2(postcss@8.4.33)
- postcss-unique-selectors: 6.0.2(postcss@8.4.33)
+ css-declaration-sorter: 7.1.1(postcss@8.4.35)
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
+ postcss-calc: 9.0.1(postcss@8.4.35)
+ postcss-colormin: 6.0.3(postcss@8.4.35)
+ postcss-convert-values: 6.0.4(postcss@8.4.35)
+ postcss-discard-comments: 6.0.1(postcss@8.4.35)
+ postcss-discard-duplicates: 6.0.2(postcss@8.4.35)
+ postcss-discard-empty: 6.0.2(postcss@8.4.35)
+ postcss-discard-overridden: 6.0.1(postcss@8.4.35)
+ postcss-merge-longhand: 6.0.3(postcss@8.4.35)
+ postcss-merge-rules: 6.0.4(postcss@8.4.35)
+ postcss-minify-font-values: 6.0.2(postcss@8.4.35)
+ postcss-minify-gradients: 6.0.2(postcss@8.4.35)
+ postcss-minify-params: 6.0.3(postcss@8.4.35)
+ postcss-minify-selectors: 6.0.2(postcss@8.4.35)
+ postcss-normalize-charset: 6.0.1(postcss@8.4.35)
+ postcss-normalize-display-values: 6.0.1(postcss@8.4.35)
+ postcss-normalize-positions: 6.0.1(postcss@8.4.35)
+ postcss-normalize-repeat-style: 6.0.1(postcss@8.4.35)
+ postcss-normalize-string: 6.0.1(postcss@8.4.35)
+ postcss-normalize-timing-functions: 6.0.1(postcss@8.4.35)
+ postcss-normalize-unicode: 6.0.3(postcss@8.4.35)
+ postcss-normalize-url: 6.0.1(postcss@8.4.35)
+ postcss-normalize-whitespace: 6.0.1(postcss@8.4.35)
+ postcss-ordered-values: 6.0.1(postcss@8.4.35)
+ postcss-reduce-initial: 6.0.3(postcss@8.4.35)
+ postcss-reduce-transforms: 6.0.1(postcss@8.4.35)
+ postcss-svgo: 6.0.2(postcss@8.4.35)
+ postcss-unique-selectors: 6.0.2(postcss@8.4.35)
dev: false
- /cssnano-utils@4.0.1(postcss@8.4.33):
+ /cssnano-utils@4.0.1(postcss@8.4.35):
resolution: {integrity: sha512-6qQuYDqsGoiXssZ3zct6dcMxiqfT6epy7x4R0TQJadd4LWO3sPR6JH6ZByOvVLoZ6EdwPGgd7+DR1EmX3tiXQQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: false
- /cssnano@6.0.3(postcss@8.4.33):
- resolution: {integrity: sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==}
+ /cssnano@6.0.5(postcss@8.4.35):
+ resolution: {integrity: sha512-tpTp/ukgrElwu3ESFY4IvWnGn8eTt8cJhC2aAbtA3lvUlxp6t6UPv8YCLjNnEGiFreT1O0LiOM1U3QyTBVFl2A==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- cssnano-preset-default: 6.0.3(postcss@8.4.33)
- lilconfig: 3.0.0
- postcss: 8.4.33
+ cssnano-preset-default: 6.0.5(postcss@8.4.35)
+ lilconfig: 3.1.1
+ postcss: 8.4.35
dev: false
/csso@5.0.5:
@@ -9921,8 +10223,8 @@ packages:
uniq: 1.0.1
dev: false
- /cypress@13.6.3:
- resolution: {integrity: sha512-d/pZvgwjAyZsoyJ3FOsJT5lDsqnxQ/clMqnNc++rkHjbkkiF2h9s0JsZSyyH4QXhVFW3zPFg82jD25roFLOdZA==}
+ /cypress@13.6.6:
+ resolution: {integrity: sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==}
engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0}
hasBin: true
requiresBuild: true
@@ -9966,57 +10268,7 @@ packages:
request-progress: 3.0.0
semver: 7.5.4
supports-color: 8.1.1
- tmp: 0.2.1
- untildify: 4.0.0
- yauzl: 2.10.0
- dev: true
-
- /cypress@13.6.4:
- resolution: {integrity: sha512-pYJjCfDYB+hoOoZuhysbbYhEmNW7DEDsqn+ToCLwuVowxUXppIWRr7qk4TVRIU471ksfzyZcH+mkoF0CQUKnpw==}
- engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0}
- hasBin: true
- requiresBuild: true
- dependencies:
- '@cypress/request': 3.0.0
- '@cypress/xvfb': 1.2.4(supports-color@8.1.1)
- '@types/sinonjs__fake-timers': 8.1.1
- '@types/sizzle': 2.3.3
- arch: 2.2.0
- blob-util: 2.0.2
- bluebird: 3.7.2
- buffer: 5.7.1
- cachedir: 2.3.0
- chalk: 4.1.2
- check-more-types: 2.24.0
- cli-cursor: 3.1.0
- cli-table3: 0.6.3
- commander: 6.2.1
- common-tags: 1.8.2
- dayjs: 1.11.10
- debug: 4.3.4(supports-color@8.1.1)
- enquirer: 2.3.6
- eventemitter2: 6.4.7
- execa: 4.1.0
- executable: 4.1.1
- extract-zip: 2.0.1(supports-color@8.1.1)
- figures: 3.2.0
- fs-extra: 9.1.0
- getos: 3.2.1
- is-ci: 3.0.1
- is-installed-globally: 0.4.0
- lazy-ass: 1.6.0
- listr2: 3.14.0(enquirer@2.3.6)
- lodash: 4.17.21
- log-symbols: 4.1.0
- minimist: 1.2.8
- ospath: 1.2.2
- pretty-bytes: 5.6.0
- process: 0.11.10
- proxy-from-env: 1.0.0
- request-progress: 3.0.0
- semver: 7.5.4
- supports-color: 8.1.1
- tmp: 0.2.1
+ tmp: 0.2.2
untildify: 4.0.0
yauzl: 2.10.0
dev: true
@@ -10197,11 +10449,6 @@ packages:
which-typed-array: 1.1.11
dev: true
- /deep-extend@0.6.0:
- resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
- engines: {node: '>=4.0.0'}
- dev: false
-
/deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
@@ -10460,6 +10707,11 @@ packages:
/electron-to-chromium@1.4.601:
resolution: {integrity: sha512-SpwUMDWe9tQu8JX5QCO1+p/hChAi9AE9UpoC3rcHVc+gdCGlbT3SGb5I1klgb952HRIyvt9wZhSz9bNBYz9swA==}
+ dev: true
+
+ /electron-to-chromium@1.4.686:
+ resolution: {integrity: sha512-3avY1B+vUzNxEgkBDpKOP8WarvUAEwpRaiCL0He5OKWEFxzaOFiq4WoZEZe7qh0ReS7DiWoHMnYoQCKxNZNzSg==}
+ dev: false
/emittery@0.13.1:
resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
@@ -10798,7 +11050,7 @@ packages:
- supports-color
dev: true
- /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.18.1)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0):
+ /eslint-module-utils@2.8.0(@typescript-eslint/parser@7.1.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
engines: {node: '>=4'}
peerDependencies:
@@ -10819,9 +11071,9 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
- '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
debug: 3.2.7(supports-color@8.1.1)
- eslint: 8.56.0
+ eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
@@ -10862,7 +11114,7 @@ packages:
- supports-color
dev: true
- /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0):
+ /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0):
resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==}
engines: {node: '>=4'}
peerDependencies:
@@ -10872,16 +11124,16 @@ packages:
'@typescript-eslint/parser':
optional: true
dependencies:
- '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3)
+ '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
array-includes: 3.1.7
array.prototype.findlastindex: 1.2.3
array.prototype.flat: 1.3.2
array.prototype.flatmap: 1.3.2
debug: 3.2.7(supports-color@8.1.1)
doctrine: 2.1.0
- eslint: 8.56.0
+ eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.18.1)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0)
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
hasown: 2.0.0
is-core-module: 2.13.1
is-glob: 4.0.3
@@ -10897,19 +11149,19 @@ packages:
- supports-color
dev: true
- /eslint-plugin-vue@9.20.1(eslint@8.56.0):
- resolution: {integrity: sha512-GyCs8K3lkEvoyC1VV97GJhP1SvqsKCiWGHnbn0gVUYiUhaH2+nB+Dv1uekv1THFMPbBfYxukrzQdltw950k+LQ==}
+ /eslint-plugin-vue@9.22.0(eslint@8.57.0):
+ resolution: {integrity: sha512-7wCXv5zuVnBtZE/74z4yZ0CM8AjH6bk4MQGm7hZjUC2DBppKU5ioeOk5LGSg/s9a1ZJnIsdPLJpXnu1Rc+cVHg==}
engines: {node: ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
- eslint: 8.56.0
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
+ eslint: 8.57.0
natural-compare: 1.4.0
nth-check: 2.1.1
postcss-selector-parser: 6.0.15
- semver: 7.5.4
- vue-eslint-parser: 9.4.2(eslint@8.56.0)
+ semver: 7.6.0
+ vue-eslint-parser: 9.4.2(eslint@8.57.0)
xml-name-validator: 4.0.0
transitivePeerDependencies:
- supports-color
@@ -10979,16 +11231,16 @@ packages:
- supports-color
dev: true
- /eslint@8.56.0:
- resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==}
+ /eslint@8.57.0:
+ resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@eslint-community/regexpp': 4.6.2
'@eslint/eslintrc': 2.1.4
- '@eslint/js': 8.56.0
- '@humanwhocodes/config-array': 0.11.13
+ '@eslint/js': 8.57.0
+ '@humanwhocodes/config-array': 0.11.14
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
'@ungap/structured-clone': 1.2.0
@@ -11193,11 +11445,6 @@ packages:
engines: {node: '>= 0.8.0'}
dev: true
- /expand-template@2.0.3:
- resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
- engines: {node: '>=6'}
- dev: false
-
/expect@29.7.0:
resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -11540,6 +11787,10 @@ packages:
safe-regex2: 2.0.0
dev: false
+ /find-package-json@1.2.0:
+ resolution: {integrity: sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==}
+ dev: true
+
/find-up@3.0.0:
resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
engines: {node: '>=6'}
@@ -11688,6 +11939,7 @@ packages:
/fs-constants@1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
+ dev: true
/fs-extra@11.1.1:
resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==}
@@ -11905,10 +12157,6 @@ packages:
- supports-color
dev: true
- /github-from-package@0.0.0:
- resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
- dev: false
-
/github-slugger@2.0.0:
resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
dev: true
@@ -12053,8 +12301,8 @@ packages:
p-cancelable: 3.0.0
responselike: 3.0.0
- /got@14.1.0:
- resolution: {integrity: sha512-jGmSBfxa7jOGg464azcsf/cUlJBZldU8edFpiVebIJrVBE4vqVx0t3Z2f1kz1WrcMvLgQREoC/l2ttDmSHwyRg==}
+ /got@14.2.0:
+ resolution: {integrity: sha512-dBq2KkHcQl3AwPoIWsLsQScCPpUgRulz1qZVthjPYKYOPmYfBnekR3vxecjZbm91Vc3JUGnV9mqFX7B+Fe2quw==}
engines: {node: '>=20'}
dependencies:
'@sindresorhus/is': 6.1.0
@@ -12125,6 +12373,16 @@ packages:
webidl-conversions: 7.0.0
whatwg-encoding: 2.0.0
whatwg-mimetype: 3.0.0
+ dev: false
+
+ /happy-dom@13.6.2:
+ resolution: {integrity: sha512-Ku+wDqcF/KwFA0dI+xIMZd9Jn020RXjuSil/Vz7gu2yhDC3FsDYZ55qqV9k+SGC4opwb4acisXqVSRxUJMlPbQ==}
+ engines: {node: '>=16.0.0'}
+ dependencies:
+ entities: 4.5.0
+ webidl-conversions: 7.0.0
+ whatwg-mimetype: 3.0.0
+ dev: true
/har-schema@2.0.0:
resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==}
@@ -12235,8 +12493,8 @@ packages:
resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
dev: false
- /highlight.js@11.8.0:
- resolution: {integrity: sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==}
+ /highlight.js@11.9.0:
+ resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==}
engines: {node: '>=12.0.0'}
dev: false
@@ -12275,6 +12533,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /htmlescape@1.1.1:
+ resolution: {integrity: sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==}
+ engines: {node: '>=0.10'}
+ dev: false
+
/htmlparser2@8.0.1:
resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==}
dependencies:
@@ -12296,8 +12559,8 @@ packages:
statuses: 2.0.1
toidentifier: 1.0.1
- /http-link-header@1.1.1:
- resolution: {integrity: sha512-mW3N/rTYpCn99s1do0zx6nzFZSwLH9HGfUM4ZqLWJ16ylmYaC2v5eYGqrNTQlByx8AzUgGI+V/32gXPugs1+Sw==}
+ /http-link-header@1.1.2:
+ resolution: {integrity: sha512-6qz1XhMq/ryde52SZGzVhzi3jcG2KqO16KITkupyQxvW6u7iylm0Fq7r3OpCYsc0S0ELlCiFpuxDcccUwjbEqA==}
engines: {node: '>=6.0.0'}
dev: false
@@ -12481,6 +12744,7 @@ packages:
/ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+ dev: true
/ini@2.0.0:
resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==}
@@ -12573,6 +12837,11 @@ packages:
/ip@2.0.0:
resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==}
+ dev: false
+
+ /ip@2.0.1:
+ resolution: {integrity: sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==}
+ dev: true
/ipaddr.js@1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
@@ -13025,7 +13294,7 @@ packages:
'@jest/expect': 29.7.0
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
chalk: 4.1.2
co: 4.6.0
dedent: 1.3.0
@@ -13046,7 +13315,7 @@ packages:
- supports-color
dev: true
- /jest-cli@29.7.0(@types/node@20.11.17):
+ /jest-cli@29.7.0(@types/node@20.11.22):
resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -13060,10 +13329,10 @@ packages:
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
chalk: 4.1.2
- create-jest: 29.7.0(@types/node@20.11.17)
+ create-jest: 29.7.0(@types/node@20.11.22)
exit: 0.1.2
import-local: 3.1.0
- jest-config: 29.7.0(@types/node@20.11.17)
+ jest-config: 29.7.0(@types/node@20.11.22)
jest-util: 29.7.0
jest-validate: 29.7.0
yargs: 17.7.2
@@ -13074,7 +13343,7 @@ packages:
- ts-node
dev: true
- /jest-config@29.7.0(@types/node@20.11.17):
+ /jest-config@29.7.0(@types/node@20.11.22):
resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@@ -13089,7 +13358,7 @@ packages:
'@babel/core': 7.23.5
'@jest/test-sequencer': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
babel-jest: 29.7.0(@babel/core@7.23.5)
chalk: 4.1.2
ci-info: 3.7.1
@@ -13149,7 +13418,7 @@ packages:
'@jest/environment': 29.7.0
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
jest-mock: 29.7.0
jest-util: 29.7.0
dev: true
@@ -13174,7 +13443,7 @@ packages:
dependencies:
'@jest/types': 29.6.3
'@types/graceful-fs': 4.1.6
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.11
@@ -13225,7 +13494,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@jest/types': 27.5.1
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
dev: true
/jest-mock@29.7.0:
@@ -13233,7 +13502,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
jest-util: 29.7.0
dev: true
@@ -13288,7 +13557,7 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.11
@@ -13319,7 +13588,7 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
chalk: 4.1.2
cjs-module-lexer: 1.2.2
collect-v8-coverage: 1.0.1
@@ -13371,7 +13640,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
chalk: 4.1.2
ci-info: 3.7.1
graceful-fs: 4.2.11
@@ -13396,7 +13665,7 @@ packages:
dependencies:
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
@@ -13415,13 +13684,13 @@ packages:
resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
jest-util: 29.7.0
merge-stream: 2.0.0
supports-color: 8.1.1
dev: true
- /jest@29.7.0(@types/node@20.11.17):
+ /jest@29.7.0(@types/node@20.11.22):
resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -13434,7 +13703,7 @@ packages:
'@jest/core': 29.7.0
'@jest/types': 29.6.3
import-local: 3.1.0
- jest-cli: 29.7.0(@types/node@20.11.17)
+ jest-cli: 29.7.0(@types/node@20.11.22)
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
@@ -13693,8 +13962,8 @@ packages:
verror: 1.10.0
dev: true
- /jsrsasign@11.0.0:
- resolution: {integrity: sha512-BtRwVKS+5dsgPpAtzJcpo5OoWjSs1/zllSBG0+8o8/aV0Ki76m6iZwHnwnsqoTdhfFZDN1XIdcaZr5ZkP+H2gg==}
+ /jsrsasign@11.1.0:
+ resolution: {integrity: sha512-Ov74K9GihaK9/9WncTe1mPmvrO7Py665TUfUKvraXBpu+xcTWitrtuOwcjf4KMU9maPaYn0OuaWy0HOzy/GBXg==}
dev: false
/jssha@3.3.1:
@@ -13803,8 +14072,8 @@ packages:
set-cookie-parser: 2.6.0
dev: false
- /lilconfig@3.0.0:
- resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==}
+ /lilconfig@3.1.1:
+ resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==}
engines: {node: '>=14'}
dev: false
@@ -14697,6 +14966,7 @@ packages:
/mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
+ dev: true
/mkdirp@0.5.6:
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
@@ -14864,16 +15134,12 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
- /nanoid@5.0.4:
- resolution: {integrity: sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==}
+ /nanoid@5.0.6:
+ resolution: {integrity: sha512-rRq0eMHoGZxlvaFOUdK1Ev83Bd1IgzzR+WJ3IbDJ7QOSdAxYjlurSPqFs9s4lJg29RT6nPwizFtJhQS6V5xgiA==}
engines: {node: ^18 || >=20}
hasBin: true
dev: false
- /napi-build-utils@1.0.2:
- resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==}
- dev: false
-
/natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true
@@ -14948,21 +15214,10 @@ packages:
path-to-regexp: 1.8.0
dev: true
- /node-abi@3.31.0:
- resolution: {integrity: sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==}
- engines: {node: '>=10'}
- dependencies:
- semver: 7.5.4
- dev: false
-
/node-abort-controller@3.1.1:
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
dev: false
- /node-addon-api@6.1.0:
- resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==}
- dev: false
-
/node-bitmap@0.0.1:
resolution: {integrity: sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==}
engines: {node: '>=v0.6.5'}
@@ -15015,13 +15270,6 @@ packages:
fetch-blob: 3.2.0
formdata-polyfill: 4.0.10
- /node-gyp-build-optional-packages@5.0.3:
- resolution: {integrity: sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==}
- hasBin: true
- requiresBuild: true
- dev: false
- optional: true
-
/node-gyp-build-optional-packages@5.0.7:
resolution: {integrity: sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==}
hasBin: true
@@ -15060,8 +15308,8 @@ packages:
/node-releases@2.0.14:
resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
- /nodemailer@6.9.8:
- resolution: {integrity: sha512-cfrYUk16e67Ks051i4CntM9kshRYei1/o/Gi8K1d+R34OIs21xdFnW7Pt7EucmVKA0LKtqUGNcjMZ7ehjl49mQ==}
+ /nodemailer@6.9.10:
+ resolution: {integrity: sha512-qtoKfGFhvIFW5kLfrkw2R6Nm6Ur4LNUMykyqu6n9BRKJuyQrqEGwdXXUAbwWEKt33dlWUGXb7rzmJP/p4+O+CA==}
engines: {node: '>=6.0.0'}
dev: false
@@ -15082,8 +15330,8 @@ packages:
undefsafe: 2.0.5
dev: true
- /nodemon@3.0.3:
- resolution: {integrity: sha512-7jH/NXbFPxVaMwmBCC2B9F/V6X1VkEdNgx3iu9jji8WxWcvhMWkmhNWhI5077zknOnZnBzba9hZP6bCPJLSReQ==}
+ /nodemon@3.1.0:
+ resolution: {integrity: sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==}
engines: {node: '>=10'}
hasBin: true
dependencies:
@@ -15880,264 +16128,264 @@ packages:
'@babel/runtime': 7.23.4
dev: true
- /postcss-calc@9.0.1(postcss@8.4.33):
+ /postcss-calc@9.0.1(postcss@8.4.35):
resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.2.2
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
postcss-value-parser: 4.2.0
dev: false
- /postcss-colormin@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-TXKOxs9LWcdYo5cgmcSHPkyrLAh86hX1ijmyy6J8SbOhyv6ua053M3ZAM/0j44UsnQNIWdl8gb5L7xX2htKeLw==}
+ /postcss-colormin@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-ECpkS+UZRyAtu/kjive2/1mihP+GNtgC8kcdU8ueWZi1ZVxMNnRziCLdhrWECJhEtSWijfX2Cl9XTTCK/hjGaA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
+ browserslist: 4.23.0
caniuse-api: 3.0.0
colord: 2.9.3
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-convert-values@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-aeBmaTnGQ+NUSVQT8aY0sKyAD/BaLJenEKZ03YK0JnDE1w1Rr8XShoxdal2V2H26xTJKr3v5haByOhJuyT4UYw==}
+ /postcss-convert-values@6.0.4(postcss@8.4.35):
+ resolution: {integrity: sha512-YT2yrGzPXoQD3YeA2kBo/696qNwn7vI+15AOS2puXWEvSWqdCqlOyDWRy5GNnOc9ACRGOkuQ4ESQEqPJBWt/GA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
- postcss: 8.4.33
+ browserslist: 4.23.0
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-discard-comments@6.0.1(postcss@8.4.33):
+ /postcss-discard-comments@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-f1KYNPtqYLUeZGCHQPKzzFtsHaRuECe6jLakf/RjSRqvF5XHLZnM2+fXLhb8Qh/HBFHs3M4cSLb1k3B899RYIg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: false
- /postcss-discard-duplicates@6.0.1(postcss@8.4.33):
- resolution: {integrity: sha512-1hvUs76HLYR8zkScbwyJ8oJEugfPV+WchpnA+26fpJ7Smzs51CzGBHC32RS03psuX/2l0l0UKh2StzNxOrKCYg==}
+ /postcss-discard-duplicates@6.0.2(postcss@8.4.35):
+ resolution: {integrity: sha512-U2rsj4w6pAGROCCcD13LP2eBIi1whUsXs4kgE6xkIuGfkbxCBSKhkCTWyowFd66WdVlLv0uM1euJKIgmdmZObg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: false
- /postcss-discard-empty@6.0.1(postcss@8.4.33):
- resolution: {integrity: sha512-yitcmKwmVWtNsrrRqGJ7/C0YRy53i0mjexBDQ9zYxDwTWVBgbU4+C9jIZLmQlTDT9zhml+u0OMFJh8+31krmOg==}
+ /postcss-discard-empty@6.0.2(postcss@8.4.35):
+ resolution: {integrity: sha512-rj6pVC2dVCJrP0Y2RkYTQEbYaCf4HEm+R/2StQgJqGHxAa3+KcYslNQhcRqjLHtl/4wpzipJluaJLqBj6d5eDQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: false
- /postcss-discard-overridden@6.0.1(postcss@8.4.33):
+ /postcss-discard-overridden@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-qs0ehZMMZpSESbRkw1+inkf51kak6OOzNRaoLd/U7Fatp0aN2HQ1rxGOrJvYcRAN9VpX8kUF13R2ofn8OlvFVA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: false
- /postcss-merge-longhand@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-+yfVB7gEM8SrCo9w2lCApKIEzrTKl5yS1F4yGhV3kSim6JzbfLGJyhR1B6X+6vOT0U33Mgx7iv4X9MVWuaSAfw==}
+ /postcss-merge-longhand@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-kF/y3DU8CRt+SX3tP/aG+2gkZI2Z7OXDsPU7FgxIJmuyhQQ1EHceIYcsp/alvzCm2P4c37Sfdu8nNrHc+YeyLg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
- stylehacks: 6.0.2(postcss@8.4.33)
+ stylehacks: 6.0.3(postcss@8.4.35)
dev: false
- /postcss-merge-rules@6.0.3(postcss@8.4.33):
- resolution: {integrity: sha512-yfkDqSHGohy8sGYIJwBmIGDv4K4/WrJPX355XrxQb/CSsT4Kc/RxDi6akqn5s9bap85AWgv21ArcUWwWdGNSHA==}
+ /postcss-merge-rules@6.0.4(postcss@8.4.35):
+ resolution: {integrity: sha512-97iF3UJ5v8N1BWy38y+0l+Z8o5/9uGlEgtWic2PJPzoRrLB6Gxg8TVG93O0EK52jcLeMsywre26AUlX1YAYeHA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
+ browserslist: 4.23.0
caniuse-api: 3.0.0
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
dev: false
- /postcss-minify-font-values@6.0.1(postcss@8.4.33):
- resolution: {integrity: sha512-tIwmF1zUPoN6xOtA/2FgVk1ZKrLcCvE0dpZLtzyyte0j9zUeB8RTbCqrHZGjJlxOvNWKMYtunLrrl7HPOiR46w==}
+ /postcss-minify-font-values@6.0.2(postcss@8.4.35):
+ resolution: {integrity: sha512-IedzbVMoX0a7VZWjSYr5qJ6C37rws8kl8diPBeMZLJfWKkgXuMFY5R/OxPegn/q9tK9ztd0XRH3aR0u2t+A7uQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-minify-gradients@6.0.1(postcss@8.4.33):
- resolution: {integrity: sha512-M1RJWVjd6IOLPl1hYiOd5HQHgpp6cvJVLrieQYS9y07Yo8itAr6jaekzJphaJFR0tcg4kRewCk3kna9uHBxn/w==}
+ /postcss-minify-gradients@6.0.2(postcss@8.4.35):
+ resolution: {integrity: sha512-vP5mF7iI6/5fcpv+rSfwWQekOE+8I1i7/7RjZPGuIjj6eUaZVeG4XZYZrroFuw1WQd51u2V32wyQFZ+oYdE7CA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
colord: 2.9.3
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-minify-params@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-zwQtbrPEBDj+ApELZ6QylLf2/c5zmASoOuA4DzolyVGdV38iR2I5QRMsZcHkcdkZzxpN8RS4cN7LPskOkTwTZw==}
+ /postcss-minify-params@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-j4S74d3AAeCK5eGdQndXSrkxusV2ekOxbXGnlnZthMyZBBvSDiU34CihTASbJxuVB3bugudmwolS7+Dgs5OyOQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
+ browserslist: 4.23.0
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-minify-selectors@6.0.2(postcss@8.4.33):
+ /postcss-minify-selectors@6.0.2(postcss@8.4.35):
resolution: {integrity: sha512-0b+m+w7OAvZejPQdN2GjsXLv5o0jqYHX3aoV0e7RBKPCsB7TYG5KKWBFhGnB/iP3213Ts8c5H4wLPLMm7z28Sg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
dev: false
- /postcss-normalize-charset@6.0.1(postcss@8.4.33):
+ /postcss-normalize-charset@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-aW5LbMNRZ+oDV57PF9K+WI1Z8MPnF+A8qbajg/T8PP126YrGX1f9IQx21GI2OlGz7XFJi/fNi0GTbY948XJtXg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
dev: false
- /postcss-normalize-display-values@6.0.1(postcss@8.4.33):
+ /postcss-normalize-display-values@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-mc3vxp2bEuCb4LgCcmG1y6lKJu1Co8T+rKHrcbShJwUmKJiEl761qb/QQCfFwlrvSeET3jksolCR/RZuMURudw==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-normalize-positions@6.0.1(postcss@8.4.33):
+ /postcss-normalize-positions@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-HRsq8u/0unKNvm0cvwxcOUEcakFXqZ41fv3FOdPn916XFUrympjr+03oaLkuZENz3HE9RrQE9yU0Xv43ThWjQg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-normalize-repeat-style@6.0.1(postcss@8.4.33):
+ /postcss-normalize-repeat-style@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-Gbb2nmCy6tTiA7Sh2MBs3fj9W8swonk6lw+dFFeQT68B0Pzwp1kvisJQkdV6rbbMSd9brMlS8I8ts52tAGWmGQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-normalize-string@6.0.1(postcss@8.4.33):
+ /postcss-normalize-string@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-5Fhx/+xzALJD9EI26Aq23hXwmv97Zfy2VFrt5PLT8lAhnBIZvmaT5pQk+NuJ/GWj/QWaKSKbnoKDGLbV6qnhXg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-normalize-timing-functions@6.0.1(postcss@8.4.33):
+ /postcss-normalize-timing-functions@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-4zcczzHqmCU7L5dqTB9rzeqPWRMc0K2HoR+Bfl+FSMbqGBUcP5LRfgcH4BdRtLuzVQK1/FHdFoGT3F7rkEnY+g==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-normalize-unicode@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-Ff2VdAYCTGyMUwpevTZPZ4w0+mPjbZzLLyoLh/RMpqUqeQKZ+xMm31hkxBavDcGKcxm6ACzGk0nBfZ8LZkStKA==}
+ /postcss-normalize-unicode@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-T2Bb3gXz0ASgc3ori2dzjv6j/P2IantreaC6fT8tWjqYUiqMAh5jGIkdPwEV2FaucjQlCLeFJDJh2BeSugE1ig==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
- postcss: 8.4.33
+ browserslist: 4.23.0
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-normalize-url@6.0.1(postcss@8.4.33):
+ /postcss-normalize-url@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-jEXL15tXSvbjm0yzUV7FBiEXwhIa9H88JOXDGQzmcWoB4mSjZIsmtto066s2iW9FYuIrIF4k04HA2BKAOpbsaQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-normalize-whitespace@6.0.1(postcss@8.4.33):
+ /postcss-normalize-whitespace@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-76i3NpWf6bB8UHlVuLRxG4zW2YykF9CTEcq/9LGAiz2qBuX5cBStadkk0jSkg9a9TCIXbMQz7yzrygKoCW9JuA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-ordered-values@6.0.1(postcss@8.4.33):
+ /postcss-ordered-values@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-XXbb1O/MW9HdEhnBxitZpPFbIvDgbo9NK4c/5bOfiKpnIGZDoL2xd7/e6jW5DYLsWxBbs+1nZEnVgnjnlFViaA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- cssnano-utils: 4.0.1(postcss@8.4.33)
- postcss: 8.4.33
+ cssnano-utils: 4.0.1(postcss@8.4.35)
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
- /postcss-reduce-initial@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-YGKalhNlCLcjcLvjU5nF8FyeCTkCO5UtvJEt0hrPZVCTtRLSOH4z00T1UntQPj4dUmIYZgMj8qK77JbSX95hSw==}
+ /postcss-reduce-initial@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-w4QIR9pEa1N4xMx3k30T1vLZl6udVK2RmNqrDXhBXX9L0mBj2a8ADs8zkbaEH7eUy1m30Wyr5EBgHN31Yq1JvA==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
+ browserslist: 4.23.0
caniuse-api: 3.0.0
- postcss: 8.4.33
+ postcss: 8.4.35
dev: false
- /postcss-reduce-transforms@6.0.1(postcss@8.4.33):
+ /postcss-reduce-transforms@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-fUbV81OkUe75JM+VYO1gr/IoA2b/dRiH6HvMwhrIBSUrxq3jNZQZitSnugcTLDi1KkQh1eR/zi+iyxviUNBkcQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: false
@@ -16148,24 +16396,24 @@ packages:
cssesc: 3.0.0
util-deprecate: 1.0.2
- /postcss-svgo@6.0.2(postcss@8.4.33):
+ /postcss-svgo@6.0.2(postcss@8.4.35):
resolution: {integrity: sha512-IH5R9SjkTkh0kfFOQDImyy1+mTCb+E830+9SV1O+AaDcoHTvfsvt6WwJeo7KwcHbFnevZVCsXhDmjFiGVuwqFQ==}
engines: {node: ^14 || ^16 || >= 18}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-value-parser: 4.2.0
svgo: 3.2.0
dev: false
- /postcss-unique-selectors@6.0.2(postcss@8.4.33):
+ /postcss-unique-selectors@6.0.2(postcss@8.4.35):
resolution: {integrity: sha512-8IZGQ94nechdG7Y9Sh9FlIY2b4uS8/k8kdKRX040XHsS3B6d1HrJAkXrBSsSu4SuARruSsUjW3nlSw8BHkaAYQ==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- postcss: 8.4.33
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
dev: false
@@ -16173,14 +16421,6 @@ packages:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
dev: false
- /postcss@8.4.33:
- resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==}
- engines: {node: ^10 || ^12 || >=14}
- dependencies:
- nanoid: 3.3.7
- picocolors: 1.0.0
- source-map-js: 1.0.2
-
/postcss@8.4.35:
resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==}
engines: {node: ^10 || ^12 || >=14}
@@ -16237,25 +16477,6 @@ packages:
resolution: {integrity: sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==}
dev: true
- /prebuild-install@7.1.1:
- resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- detect-libc: 2.0.2
- expand-template: 2.0.3
- github-from-package: 0.0.0
- minimist: 1.2.8
- mkdirp-classic: 0.5.3
- napi-build-utils: 1.0.2
- node-abi: 3.31.0
- pump: 3.0.0
- rc: 1.2.8
- simple-get: 4.0.1
- tar-fs: 2.1.1
- tunnel-agent: 0.6.0
- dev: false
-
/prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
@@ -16655,16 +16876,6 @@ packages:
iconv-lite: 0.4.24
unpipe: 1.0.0
- /rc@1.2.8:
- resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
- hasBin: true
- dependencies:
- deep-extend: 0.6.0
- ini: 1.3.8
- minimist: 1.2.8
- strip-json-comments: 2.0.1
- dev: false
-
/rdf-canonize@3.4.0:
resolution: {integrity: sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==}
engines: {node: '>=12'}
@@ -16846,17 +17057,6 @@ packages:
engines: {node: '>= 12.13.0'}
dev: false
- /recast@0.22.0:
- resolution: {integrity: sha512-5AAx+mujtXijsEavc5lWXBPQqrM4+Dl5qNH96N2aNeuJFUzpiiToKPsxQD/zAIJHspz7zz0maX0PCtCTFVlixQ==}
- engines: {node: '>= 4'}
- dependencies:
- assert: 2.1.0
- ast-types: 0.15.2
- esprima: 4.0.1
- source-map: 0.6.1
- tslib: 2.6.2
- dev: true
-
/recast@0.23.4:
resolution: {integrity: sha512-qtEDqIZGVcSZCHniWwZWbRy79Dc6Wp3kT/UmDA2RJKBPg7+7k51aQBZirHmUGn5uvHf2rg8DkjizrN26k61ATw==}
engines: {node: '>= 4'}
@@ -16903,12 +17103,8 @@ packages:
redis-errors: 1.2.0
dev: false
- /reflect-metadata@0.1.14:
- resolution: {integrity: sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==}
-
/reflect-metadata@0.2.1:
resolution: {integrity: sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==}
- dev: false
/regenerate-unicode-properties@10.1.0:
resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==}
@@ -17175,26 +17371,33 @@ packages:
dependencies:
glob: 7.2.3
- /rollup@4.9.6:
- resolution: {integrity: sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==}
+ /rimraf@5.0.5:
+ resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==}
+ engines: {node: '>=14'}
+ hasBin: true
+ dependencies:
+ glob: 10.3.10
+
+ /rollup@4.12.0:
+ resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
dependencies:
'@types/estree': 1.0.5
optionalDependencies:
- '@rollup/rollup-android-arm-eabi': 4.9.6
- '@rollup/rollup-android-arm64': 4.9.6
- '@rollup/rollup-darwin-arm64': 4.9.6
- '@rollup/rollup-darwin-x64': 4.9.6
- '@rollup/rollup-linux-arm-gnueabihf': 4.9.6
- '@rollup/rollup-linux-arm64-gnu': 4.9.6
- '@rollup/rollup-linux-arm64-musl': 4.9.6
- '@rollup/rollup-linux-riscv64-gnu': 4.9.6
- '@rollup/rollup-linux-x64-gnu': 4.9.6
- '@rollup/rollup-linux-x64-musl': 4.9.6
- '@rollup/rollup-win32-arm64-msvc': 4.9.6
- '@rollup/rollup-win32-ia32-msvc': 4.9.6
- '@rollup/rollup-win32-x64-msvc': 4.9.6
+ '@rollup/rollup-android-arm-eabi': 4.12.0
+ '@rollup/rollup-android-arm64': 4.12.0
+ '@rollup/rollup-darwin-arm64': 4.12.0
+ '@rollup/rollup-darwin-x64': 4.12.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.12.0
+ '@rollup/rollup-linux-arm64-gnu': 4.12.0
+ '@rollup/rollup-linux-arm64-musl': 4.12.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.12.0
+ '@rollup/rollup-linux-x64-gnu': 4.12.0
+ '@rollup/rollup-linux-x64-musl': 4.12.0
+ '@rollup/rollup-win32-arm64-msvc': 4.12.0
+ '@rollup/rollup-win32-ia32-msvc': 4.12.0
+ '@rollup/rollup-win32-x64-msvc': 4.12.0
fsevents: 2.3.3
/rrweb-cssom@0.6.0:
@@ -17261,19 +17464,19 @@ packages:
/safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
- /sanitize-html@2.11.0:
- resolution: {integrity: sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==}
+ /sanitize-html@2.12.1:
+ resolution: {integrity: sha512-Plh+JAn0UVDpBRP/xEjsk+xDCoOvMBwQUf/K+/cBAVuTbtX8bj2VB7S1sL1dssVpykqp0/KPSesHrqXtokVBpA==}
dependencies:
deepmerge: 4.2.2
escape-string-regexp: 4.0.0
htmlparser2: 8.0.1
is-plain-object: 5.0.0
parse-srcset: 1.0.2
- postcss: 8.4.33
+ postcss: 8.4.35
dev: false
- /sass@1.70.0:
- resolution: {integrity: sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==}
+ /sass@1.71.1:
+ resolution: {integrity: sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==}
engines: {node: '>=14.0.0'}
hasBin: true
dependencies:
@@ -17334,6 +17537,14 @@ packages:
dependencies:
lru-cache: 6.0.0
+ /semver@7.6.0:
+ resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ lru-cache: 6.0.0
+ dev: true
+
/send@0.18.0:
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
engines: {node: '>= 0.8.0'}
@@ -17395,19 +17606,34 @@ packages:
kind-of: 6.0.3
dev: true
- /sharp@0.32.6:
- resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==}
- engines: {node: '>=14.15.0'}
+ /sharp@0.33.2:
+ resolution: {integrity: sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ==}
+ engines: {libvips: '>=8.15.1', node: ^18.17.0 || ^20.3.0 || >=21.0.0}
requiresBuild: true
dependencies:
color: 4.2.3
detect-libc: 2.0.2
- node-addon-api: 6.1.0
- prebuild-install: 7.1.1
semver: 7.5.4
- simple-get: 4.0.1
- tar-fs: 3.0.4
- tunnel-agent: 0.6.0
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.33.2
+ '@img/sharp-darwin-x64': 0.33.2
+ '@img/sharp-libvips-darwin-arm64': 1.0.1
+ '@img/sharp-libvips-darwin-x64': 1.0.1
+ '@img/sharp-libvips-linux-arm': 1.0.1
+ '@img/sharp-libvips-linux-arm64': 1.0.1
+ '@img/sharp-libvips-linux-s390x': 1.0.1
+ '@img/sharp-libvips-linux-x64': 1.0.1
+ '@img/sharp-libvips-linuxmusl-arm64': 1.0.1
+ '@img/sharp-libvips-linuxmusl-x64': 1.0.1
+ '@img/sharp-linux-arm': 0.33.2
+ '@img/sharp-linux-arm64': 0.33.2
+ '@img/sharp-linux-s390x': 0.33.2
+ '@img/sharp-linux-x64': 0.33.2
+ '@img/sharp-linuxmusl-arm64': 0.33.2
+ '@img/sharp-linuxmusl-x64': 0.33.2
+ '@img/sharp-wasm32': 0.33.2
+ '@img/sharp-win32-ia32': 0.33.2
+ '@img/sharp-win32-x64': 0.33.2
dev: false
/shebang-command@1.2.0:
@@ -17432,10 +17658,10 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
- /shiki@1.0.0-beta.3:
- resolution: {integrity: sha512-z7cHTNSSvwGx2DfeLwjSNLo+HcVxifgNIzLm6Ye52eXcIwNHXT0wHbhy7FDOKSKveuEHBwt9opfj3Hoc8LE1Yg==}
+ /shiki@1.1.7:
+ resolution: {integrity: sha512-9kUTMjZtcPH3i7vHunA6EraTPpPOITYTdA5uMrvsJRexktqP0s7P3s9HVK80b4pP42FRVe03D7fT3NmJv2yYhw==}
dependencies:
- '@shikijs/core': 1.0.0-beta.3
+ '@shikijs/core': 1.1.7
dev: false
/side-channel@1.0.4:
@@ -17456,18 +17682,6 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
- /simple-concat@1.0.1:
- resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
- dev: false
-
- /simple-get@4.0.1:
- resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
- dependencies:
- decompress-response: 6.0.0
- once: 1.4.0
- simple-concat: 1.0.1
- dev: false
-
/simple-oauth2@5.0.0:
resolution: {integrity: sha512-8291lo/z5ZdpmiOFzOs1kF3cxn22bMj5FFH+DNUppLJrpoIlM1QnFiE7KpshHu3J3i21TVcx4yW+gXYjdCKDLQ==}
dependencies:
@@ -17856,11 +18070,11 @@ packages:
resolution: {integrity: sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==}
dev: true
- /storybook@8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-iXPJck+USEAp9JIBgPvkHNOGzgbfcRoyrk18JMtypwoEXeMZgf6gPw9uKqH2rAoQ0opEYHKbU8FsJ2v+GX01yQ==}
+ /storybook@8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-8d9gpKPDY9Ix64f0560rXIifmnuoswDdvSdTz4NXHGvPt7WrKNmaDTvWGyt1/fbTbv2dvvVp7bsWPgq1KGbrcg==}
hasBin: true
dependencies:
- '@storybook/cli': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/cli': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
transitivePeerDependencies:
- '@babel/preset-env'
- bufferutil
@@ -18042,11 +18256,6 @@ packages:
min-indent: 1.0.1
dev: true
- /strip-json-comments@2.0.1:
- resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
- engines: {node: '>=0.10.0'}
- dev: false
-
/strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
@@ -18075,14 +18284,14 @@ packages:
peek-readable: 5.0.0
dev: false
- /stylehacks@6.0.2(postcss@8.4.33):
- resolution: {integrity: sha512-00zvJGnCu64EpMjX8b5iCZ3us2Ptyw8+toEkb92VdmkEaRaSGBNKAoK6aWZckhXxmQP8zWiTaFaiMGIU8Ve8sg==}
+ /stylehacks@6.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-KzBqjnqktc8/I0ERCb+lGq06giF/JxDbw2r9kEVhen9noHeIDRtMWUp9r62sOk+/2bbX6sFG1GhsS7ToXG0PEg==}
engines: {node: ^14 || ^16 || >=18.0}
peerDependencies:
postcss: ^8.4.31
dependencies:
- browserslist: 4.22.2
- postcss: 8.4.33
+ browserslist: 4.23.0
+ postcss: 8.4.35
postcss-selector-parser: 6.0.15
dev: false
@@ -18140,8 +18349,8 @@ packages:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
dev: false
- /systeminformation@5.21.24:
- resolution: {integrity: sha512-xQada8ByGGFoRXJaUptGgddn3i7IjtSdqNdCKzB8xkzsM7pHnfLYBWxkPdGzhZ0Z/l+W1yo+aZQZ74d2isj8kw==}
+ /systeminformation@5.22.0:
+ resolution: {integrity: sha512-oAP80ymt8ssrAzjX8k3frbL7ys6AotqC35oikG6/SG15wBw+tG9nCk4oPaXIhEaAOAZ8XngxUv3ORq2IuR3r4Q==}
engines: {node: '>=8.0.0'}
os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android]
hasBin: true
@@ -18154,14 +18363,7 @@ packages:
mkdirp-classic: 0.5.3
pump: 3.0.0
tar-stream: 2.2.0
-
- /tar-fs@3.0.4:
- resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==}
- dependencies:
- mkdirp-classic: 0.5.3
- pump: 3.0.0
- tar-stream: 3.1.6
- dev: false
+ dev: true
/tar-stream@2.2.0:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
@@ -18172,6 +18374,7 @@ packages:
fs-constants: 1.0.0
inherits: 2.0.4
readable-stream: 3.6.0
+ dev: true
/tar-stream@3.1.6:
resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==}
@@ -18243,8 +18446,8 @@ packages:
unique-string: 2.0.0
dev: true
- /terser@5.27.0:
- resolution: {integrity: sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==}
+ /terser@5.28.1:
+ resolution: {integrity: sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==}
engines: {node: '>=10'}
hasBin: true
dependencies:
@@ -18293,8 +18496,8 @@ packages:
real-require: 0.2.0
dev: false
- /three@0.160.1:
- resolution: {integrity: sha512-Bgl2wPJypDOZ1stAxwfWAcJ0WQf7QzlptsxkjYiURPz+n5k4RBDLsq+6f9Y75TYxn6aHLcWz+JNmwTOXWrQTBQ==}
+ /three@0.162.0:
+ resolution: {integrity: sha512-xfCYj4RnlozReCmUd+XQzj6/5OjDNHBy5nT6rVwrOKGENAvpXe2z1jL+DZYaMu4/9pNsjH/4Os/VvS9IrH7IOQ==}
dev: false
/throttle-debounce@5.0.0:
@@ -18354,11 +18557,11 @@ packages:
os-tmpdir: 1.0.2
dev: true
- /tmp@0.2.1:
- resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==}
- engines: {node: '>=8.17.0'}
+ /tmp@0.2.2:
+ resolution: {integrity: sha512-ETcvHhaIc9J2MDEAH6N67j9bvBvu/3Gb764qaGhwtFvjtvhegqoqSpofgeyq1Sc24mW5pdyUDs9HP5j3ehkxRw==}
+ engines: {node: '>=14'}
dependencies:
- rimraf: 3.0.2
+ rimraf: 5.0.5
/tmpl@1.0.5:
resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
@@ -18509,8 +18712,8 @@ packages:
strip-bom: 3.0.0
dev: false
- /tsd@0.30.4:
- resolution: {integrity: sha512-ncC4SwAeUk0OTcXt5h8l0/gOLHJSp9ogosvOADT6QYzrl0ITm398B3wkz8YESqefIsEEwvYAU8bvo7/rcN/M0Q==}
+ /tsd@0.30.7:
+ resolution: {integrity: sha512-oTiJ28D6B/KXoU3ww/Eji+xqHJojiuPVMwA12g4KYX1O72N93Nb6P3P3h2OAhhf92Xl8NIhb/xFmBZd5zw/xUw==}
engines: {node: '>=14.16'}
hasBin: true
dependencies:
@@ -18911,6 +19114,18 @@ packages:
browserslist: 4.22.2
escalade: 3.1.1
picocolors: 1.0.0
+ dev: true
+
+ /update-browserslist-db@1.0.13(browserslist@4.23.0):
+ resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+ dependencies:
+ browserslist: 4.23.0
+ escalade: 3.1.1
+ picocolors: 1.0.0
+ dev: false
/uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
@@ -18961,8 +19176,8 @@ packages:
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
hasBin: true
- /v-code-diff@1.7.2(vue@3.4.18):
- resolution: {integrity: sha512-y+q8ZHf8GfphYLhcZbjAKcId/h6vZujS71Ryq5u+dI6Jg4ZLTdLrBNVSzYpHywHSSFFfBMdilm6XvVryEaH4+A==}
+ /v-code-diff@1.9.0(vue@3.4.21):
+ resolution: {integrity: sha512-alg6krCxFvwTob/rJq+3LzjdIbLb/ni8tS8YmBbI0wckOkbJuN1cShFJ6XEkm82tMgpv5NYEeWLEWhggeV7BDg==}
requiresBuild: true
peerDependencies:
'@vue/composition-api': ^1.4.9
@@ -18973,9 +19188,9 @@ packages:
dependencies:
diff: 5.1.0
diff-match-patch: 1.0.5
- highlight.js: 11.8.0
- vue: 3.4.18(typescript@5.3.3)
- vue-demi: 0.13.11(vue@3.4.18)
+ highlight.js: 11.9.0
+ vue: 3.4.21(typescript@5.3.3)
+ vue-demi: 0.14.7(vue@3.4.21)
dev: false
/v8-to-istanbul@9.2.0:
@@ -19026,7 +19241,7 @@ packages:
vfile-message: 4.0.2
dev: true
- /vite-node@0.34.6(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0):
+ /vite-node@0.34.6(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1):
resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==}
engines: {node: '>=v14.18.0'}
hasBin: true
@@ -19036,7 +19251,7 @@ packages:
mlly: 1.5.0
pathe: 1.1.2
picocolors: 1.0.0
- vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0)
+ vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1)
transitivePeerDependencies:
- '@types/node'
- less
@@ -19052,8 +19267,8 @@ packages:
resolution: {integrity: sha512-p4D8CFVhZS412SyQX125qxyzOgIFouwOcvjZWk6bQbNPR1wtaEzFT6jZxAjf1dejlGqa6fqHcuCvQea6EWUkUA==}
dev: true
- /vite@5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0):
- resolution: {integrity: sha512-STmSFzhY4ljuhz14bg9LkMTk3d98IO6DIArnTY6MeBwiD1Za2StcQtz7fzOUnRCqrHSD5+OS2reg4HOz1eoLnw==}
+ /vite@5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1):
+ resolution: {integrity: sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
@@ -19080,12 +19295,12 @@ packages:
terser:
optional: true
dependencies:
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
esbuild: 0.19.11
postcss: 8.4.35
- rollup: 4.9.6
- sass: 1.70.0
- terser: 5.27.0
+ rollup: 4.12.0
+ sass: 1.71.1
+ terser: 5.28.1
optionalDependencies:
fsevents: 2.3.3
@@ -19096,12 +19311,12 @@ packages:
vitest: '>=0.16.0'
dependencies:
cross-fetch: 3.1.6
- vitest: 0.34.6(happy-dom@10.0.3)(sass@1.70.0)(terser@5.27.0)
+ vitest: 0.34.6(happy-dom@13.6.2)(sass@1.71.1)(terser@5.28.1)
transitivePeerDependencies:
- encoding
dev: true
- /vitest@0.34.6(happy-dom@10.0.3)(sass@1.70.0)(terser@5.27.0):
+ /vitest@0.34.6(happy-dom@13.6.2)(sass@1.71.1)(terser@5.28.1):
resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==}
engines: {node: '>=v14.18.0'}
hasBin: true
@@ -19134,7 +19349,7 @@ packages:
dependencies:
'@types/chai': 4.3.11
'@types/chai-subset': 1.3.5
- '@types/node': 20.11.17
+ '@types/node': 20.11.22
'@vitest/expect': 0.34.6
'@vitest/runner': 0.34.6
'@vitest/snapshot': 0.34.6
@@ -19145,7 +19360,7 @@ packages:
cac: 6.7.14
chai: 4.3.10
debug: 4.3.4(supports-color@8.1.1)
- happy-dom: 10.0.3
+ happy-dom: 13.6.2
local-pkg: 0.4.3
magic-string: 0.30.7
pathe: 1.1.2
@@ -19154,8 +19369,8 @@ packages:
strip-literal: 1.3.0
tinybench: 2.6.0
tinypool: 0.7.0
- vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0)
- vite-node: 0.34.6(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0)
+ vite: 5.1.4(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1)
+ vite-node: 0.34.6(@types/node@20.11.22)(sass@1.71.1)(terser@5.28.1)
why-is-node-running: 2.2.2
transitivePeerDependencies:
- less
@@ -19207,6 +19422,21 @@ packages:
vscode-languageserver-protocol: 3.17.5
dev: false
+ /vue-component-meta@1.8.27(typescript@5.3.3):
+ resolution: {integrity: sha512-j3WJsyQHP4TDlvnjHc/eseo0/eVkf0FaCpkqGwez5zD+Tj31onBzWZEXTnWKs8xRj0n3dMNYdy3SpiS6NubSvg==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@volar/typescript': 1.11.1
+ '@vue/language-core': 1.8.27(typescript@5.3.3)
+ path-browserify: 1.0.1
+ typescript: 5.3.3
+ vue-component-type-helpers: 1.8.27
+ dev: true
+
/vue-component-type-helpers@1.8.27:
resolution: {integrity: sha512-0vOfAtI67UjeO1G6UiX5Kd76CqaQ67wrRZiOe7UAb9Jm6GzlUr/fC7CV90XfwapJRjpCMaZFhv1V0ajWRmE9Dg==}
dev: true
@@ -19215,8 +19445,8 @@ packages:
resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==}
dev: true
- /vue-demi@0.13.11(vue@3.4.18):
- resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==}
+ /vue-demi@0.14.7(vue@3.4.21):
+ resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
@@ -19227,35 +19457,36 @@ packages:
'@vue/composition-api':
optional: true
dependencies:
- vue: 3.4.18(typescript@5.3.3)
+ vue: 3.4.21(typescript@5.3.3)
dev: false
- /vue-docgen-api@4.64.1(vue@3.4.18):
- resolution: {integrity: sha512-jbOf7ByE3Zvtuk+429Jorl+eIeh2aB2Fx1GUo3xJd1aByJWE8KDlSEa6b11PB1ze8f0sRUBraRDinICCk0KY7g==}
+ /vue-docgen-api@4.75.1(vue@3.4.21):
+ resolution: {integrity: sha512-MECZ3uExz+ssmhD/2XrFoQQs93y17IVO1KDYTp8nr6i9GNrk67AAto6QAtilW1H/pTDPMkQxJ7w/25ZIqVtfAA==}
+ peerDependencies:
+ vue: '>=2'
dependencies:
'@babel/parser': 7.23.9
'@babel/types': 7.23.5
'@vue/compiler-dom': 3.4.18
- '@vue/compiler-sfc': 3.4.18
- ast-types: 0.14.2
+ '@vue/compiler-sfc': 3.4.21
+ ast-types: 0.16.1
hash-sum: 2.0.0
lru-cache: 8.0.4
pug: 3.0.2
- recast: 0.22.0
+ recast: 0.23.4
ts-map: 1.0.3
- vue-inbrowser-compiler-independent-utils: 4.64.1(vue@3.4.18)
- transitivePeerDependencies:
- - vue
+ vue: 3.4.21(typescript@5.3.3)
+ vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.4.21)
dev: true
- /vue-eslint-parser@9.4.2(eslint@8.56.0):
+ /vue-eslint-parser@9.4.2(eslint@8.57.0):
resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==}
engines: {node: ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: '>=6.0.0'
dependencies:
debug: 4.3.4(supports-color@8.1.1)
- eslint: 8.56.0
+ eslint: 8.57.0
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3
espree: 9.6.1
@@ -19266,12 +19497,12 @@ packages:
- supports-color
dev: true
- /vue-inbrowser-compiler-independent-utils@4.64.1(vue@3.4.18):
- resolution: {integrity: sha512-Hn32n07XZ8j9W8+fmOXPQL+i+W2e/8i6mkH4Ju3H6nR0+cfvmWM95GhczYi5B27+Y8JlCKgAo04IUiYce4mKAw==}
+ /vue-inbrowser-compiler-independent-utils@4.71.1(vue@3.4.21):
+ resolution: {integrity: sha512-K3wt3iVmNGaFEOUR4JIThQRWfqokxLfnPslD41FDZB2ajXp789+wCqJyGYlIFsvEQ2P61PInw6/ph5iiqg51gg==}
peerDependencies:
vue: '>=2'
dependencies:
- vue: 3.4.18(typescript@5.3.3)
+ vue: 3.4.21(typescript@5.3.3)
dev: true
/vue-template-compiler@2.7.14:
@@ -19293,28 +19524,28 @@ packages:
typescript: 5.3.3
dev: true
- /vue@3.4.18(typescript@5.3.3):
- resolution: {integrity: sha512-0zLRYamFRe0wF4q2L3O24KQzLyLpL64ye1RUToOgOxuWZsb/FhaNRdGmeozdtVYLz6tl94OXLaK7/WQIrVCw1A==}
+ /vue@3.4.21(typescript@5.3.3):
+ resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
- '@vue/compiler-dom': 3.4.18
- '@vue/compiler-sfc': 3.4.18
- '@vue/runtime-dom': 3.4.18
- '@vue/server-renderer': 3.4.18(vue@3.4.18)
- '@vue/shared': 3.4.18
+ '@vue/compiler-dom': 3.4.21
+ '@vue/compiler-sfc': 3.4.21
+ '@vue/runtime-dom': 3.4.21
+ '@vue/server-renderer': 3.4.21(vue@3.4.21)
+ '@vue/shared': 3.4.21
typescript: 5.3.3
- /vuedraggable@4.1.0(vue@3.4.18):
+ /vuedraggable@4.1.0(vue@3.4.21):
resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==}
peerDependencies:
vue: ^3.0.1
dependencies:
sortablejs: 1.14.0
- vue: 3.4.18(typescript@5.3.3)
+ vue: 3.4.21(typescript@5.3.3)
dev: false
/w3c-xmlserializer@5.0.0:
@@ -19398,6 +19629,7 @@ packages:
engines: {node: '>=12'}
dependencies:
iconv-lite: 0.6.3
+ dev: false
/whatwg-encoding@3.1.1:
resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
@@ -19755,7 +19987,7 @@ packages:
vscode-languageclient: 9.0.1
dev: false
- github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.0.0-beta.2)(@storybook/components@8.0.0-beta.2)(@storybook/core-events@8.0.0-beta.2)(@storybook/manager-api@8.0.0-beta.2)(@storybook/preview-api@8.0.0-beta.2)(@storybook/theming@8.0.0-beta.2)(@storybook/types@8.0.0-beta.2)(react-dom@18.2.0)(react@18.2.0):
+ github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.0.0-beta.6)(@storybook/components@8.0.0-beta.6)(@storybook/core-events@8.0.0-beta.6)(@storybook/manager-api@8.0.0-beta.6)(@storybook/preview-api@8.0.0-beta.6)(@storybook/theming@8.0.0-beta.6)(@storybook/types@8.0.0-beta.6)(react-dom@18.2.0)(react@18.2.0):
resolution: {tarball: https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640}
id: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640
name: storybook-addon-misskey-theme
@@ -19776,13 +20008,13 @@ packages:
react-dom:
optional: true
dependencies:
- '@storybook/blocks': 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/components': 8.0.0-beta.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/core-events': 8.0.0-beta.2
- '@storybook/manager-api': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/preview-api': 8.0.0-beta.2
- '@storybook/theming': 8.0.0-beta.2(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 8.0.0-beta.2
+ '@storybook/blocks': 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/components': 8.0.0-beta.6(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/core-events': 8.0.0-beta.6
+ '@storybook/manager-api': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/preview-api': 8.0.0-beta.6
+ '@storybook/theming': 8.0.0-beta.6(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/types': 8.0.0-beta.6
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: true