diff --git a/CHANGELOG.md b/CHANGELOG.md index 4194a0427a..a84ebbe3e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,12 +15,13 @@ ## 13.x.x (unreleased) ### General -- identicon生成を無効にしてパフォーマンスを向上させることができるようになりました -- サーバーのマシン情報の公開を無効にしてパフォーマンスを向上させることができるようになりました - 招待機能を改善しました * 過去に発行した招待コードを確認できるようになりました * ロールごとに招待コードの発行数制限と制限対象期間、有効期限を設定できるようになりました * 招待コードを作成したユーザーと使用したユーザーを確認できるようになりました +- ユーザーにロールが期限付きでアサインされている場合、その期限をユーザーのモデレーションページで確認できるようになりました +- identicon生成を無効にしてパフォーマンスを向上させることができるようになりました +- サーバーのマシン情報の公開を無効にしてパフォーマンスを向上させることができるようになりました ### Client - deck UIのカラムのメニューからアンテナとリストの編集画面を開けるように @@ -36,9 +37,12 @@ - フォローやお気に入り登録をしていないチャンネルを開く時は概要ページを開くように - 画面ビューワをタップした場合、マウスクリックと同様に画像ビューワを閉じるように - オフライン時の画面にリロードボタンを追加 +- Renote時に公開範囲のデフォルト設定が適用されるように - Deckで非ルートページにアクセスした際に簡易UIで表示しない設定を追加 - ロール設定画面でロールIDを確認できるように - コンテキストメニュー表示時のパフォーマンスを改善 +- フォロー/フォロワー非公開時の表示を改善 +- AiScriptを0.15.0に更新 - Fix: サーバーメトリクスが90度傾いている - Fix: 非ログイン時にクレデンシャルが必要なページに行くとエラーが出る問題を修正 - Fix: sparkle内にリンクを入れるとクリック不能になる問題の修正 @@ -59,9 +63,11 @@ - MeilisearchにIndexするノートの範囲を設定できるように - Export notes with file detail - Add unix socket support +- Fix: リモートサーバーに無意味なActivityPubの配信を行うことがあるのを修正 - Fix: Remove Meilisearch index when notes are deleted - Fix: 非英語環境でのPostgreSQLのエラーハンドリングを修正 - Fix: インスタンスのアイコンがbase64の場合の挙動を修正 +- Fix: ローカルの `Person` を指す `acct` URI を解析するときのバグを修正しました ## 13.13.2 diff --git a/cypress/e2e/basic.cy.js b/cypress/e2e/basic.cy.js index 447dd83d2b..adcca0bd40 100644 --- a/cypress/e2e/basic.cy.js +++ b/cypress/e2e/basic.cy.js @@ -54,6 +54,7 @@ describe('After setup instance', () => { cy.get('[data-cy-signup]').click(); cy.get('[data-cy-signup-rules-continue]').should('be.disabled'); cy.get('[data-cy-signup-rules-notes-agree] [data-cy-switch-toggle]').click(); + cy.get('[data-cy-modal-dialog-ok]').click(); cy.get('[data-cy-signup-rules-continue]').should('not.be.disabled'); cy.get('[data-cy-signup-rules-continue]').click(); @@ -78,6 +79,7 @@ describe('After setup instance', () => { cy.get('[data-cy-signup]').click(); cy.get('[data-cy-signup-rules-continue]').should('be.disabled'); cy.get('[data-cy-signup-rules-notes-agree] [data-cy-switch-toggle]').click(); + cy.get('[data-cy-modal-dialog-ok]').click(); cy.get('[data-cy-signup-rules-continue]').should('not.be.disabled'); cy.get('[data-cy-signup-rules-continue]').click(); diff --git a/locales/de-DE.yml b/locales/de-DE.yml index c1206b37a6..dd5eb8afbf 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -1105,6 +1105,9 @@ usedAt: "Benutzt am" unused: "Unbenutzt" used: "Benutzt" expired: "Abgelaufen" +doYouAgree: "Zustimmen?" +beSureToReadThisAsItIsImportant: "Lies bitte diese wichtige Informationen." +iHaveReadXCarefullyAndAgree: "Ich habe den Text \"{x}\" gelesen und stimme zu." _initialAccountSetting: accountCreated: "Dein Konto wurde erfolgreich erstellt!" letsStartAccountSetup: "Lass uns nun dein Konto einrichten." @@ -2082,6 +2085,7 @@ _deck: introduction: "Erstelle eine auf dich zugeschneiderte Benutzeroberfläche durch das Aneinanderreihen von Spalten!" introduction2: "Klicke auf das + rechts um wann immer du möchtest neue Spalten hinzuzufügen." widgetsIntroduction: "Drücke bitte \"Widgets bearbeiten\" im Spaltenmenü und füge ein Widget hinzu." + useSimpleUiForNonRootPages: "Simple Benutzeroberfläche für navigierte Seiten verwenden" _columns: main: "Hauptspalte" widgets: "Widgets" diff --git a/locales/en-US.yml b/locales/en-US.yml index ec71516df3..30b1b1564f 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1146,6 +1146,9 @@ usedAt: "Used at" unused: "Unused" used: "Used" expired: "Expired" +doYouAgree: "Agree?" +beSureToReadThisAsItIsImportant: "Please read this important information." +iHaveReadXCarefullyAndAgree: "I have read the text \"{x}\" and agree." additionalPermissionsForFlash: "Allow to add permission to Play" thisFlashRequiresTheFollowingPermissions: "This Play requires the following permissions" doYouWantToAllowThisPlayToAccessYourAccount: "Do you want to allow this Play to access your account?" @@ -2212,6 +2215,7 @@ _deck: introduction: "Create the perfect interface for you by arranging columns freely!" introduction2: "Click on the + on the right of the screen to add new colums whenever you want." widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget." + useSimpleUiForNonRootPages: "Use simple UI for navigated pages" _columns: main: "Main" widgets: "Widgets" diff --git a/locales/index.d.ts b/locales/index.d.ts index 1e3ff3d361..9726fa6334 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -1149,6 +1149,9 @@ export interface Locale { "unused": string; "used": string; "expired": string; + "doYouAgree": string; + "beSureToReadThisAsItIsImportant": string; + "iHaveReadXCarefullyAndAgree": string; "additionalPermissionsForFlash": string; "thisFlashRequiresTheFollowingPermissions": string; "doYouWantToAllowThisPlayToAccessYourAccount": string; diff --git a/locales/it-IT.yml b/locales/it-IT.yml index c775f004ba..40580b1776 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -791,10 +791,10 @@ info: "Informazioni" userInfo: "Informazioni utente" unknown: "Sconosciuto" onlineStatus: "Stato di connessione" -hideOnlineStatus: "Stato invisibile" -hideOnlineStatusDescription: "Abilitare l'opzione di stato invisibile può guastare la praticità di singole funzioni, come la ricerca." +hideOnlineStatus: "Modalità invisibile" +hideOnlineStatusDescription: "Attivando questa opzione potresti ridurre l'usabilità di alcune funzioni, come la ricerca." online: "Online" -active: "Attiv@" +active: "Attività" offline: "Offline" notRecommended: "Sconsigliato" botProtection: "Protezione contro i bot" @@ -868,8 +868,8 @@ makeReactionsPublicDescription: "La lista delle reazioni che avete fatto è a di classic: "Classico" muteThread: "Silenzia la conversazione" unmuteThread: "Riattiva la conversazione" -ffVisibility: "Ambito pubblico del collegamento" -ffVisibilityDescription: "È possibile impostare la portata pubblica delle informazioni sui propri follower/seguaci." +ffVisibility: "Visibilità delle connessioni" +ffVisibilityDescription: "Puoi scegliere a chi mostrare le tue relazioni con altri profili nel fediverso." continueThread: "Altri thread." deleteAccountConfirm: "Così verrà eliminato il profilo. Vuoi procedere?" incorrectPassword: "La password è errata." @@ -2082,6 +2082,7 @@ _deck: introduction: "Combinate le colonne per creare la vostra interfaccia!" introduction2: "È possibile aggiungere colonne in qualsiasi momento premendo + sulla destra dello schermo." widgetsIntroduction: "Dal menu della colonna, selezionare \"Modifica i riquadri\" per aggiungere un un riquadro con funzionalità" + useSimpleUiForNonRootPages: "Visualizza sotto pagine con interfaccia web semplice" _columns: main: "Principale" widgets: "Riquadri" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 498914d53b..751893e97c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1097,7 +1097,7 @@ vertical: "縦" horizontal: "横" position: "位置" serverRules: "サーバールール" -pleaseConfirmBelowBeforeSignup: "このサーバーに登録する前に、以下を確認してください。" +pleaseConfirmBelowBeforeSignup: "このサーバーに登録するには、以下の内容を確認し同意する必要があります。" pleaseAgreeAllToContinue: "続けるには、全ての「同意する」にチェックが入っている必要があります。" continue: "続ける" preservedUsernames: "予約ユーザー名" @@ -1146,6 +1146,9 @@ usedAt: "使用日時" unused: "未使用" used: "使用済み" expired: "期限切れ" +doYouAgree: "同意しますか?" +beSureToReadThisAsItIsImportant: "重要ですので必ずお読みください。" +iHaveReadXCarefullyAndAgree: "「{x}」の内容をよく読み、同意します。" additionalPermissionsForFlash: "Playへの追加許可" thisFlashRequiresTheFollowingPermissions: "このPlayは以下の権限を要求しています" doYouWantToAllowThisPlayToAccessYourAccount: "このPlayによるアカウントへのアクセスを許可しますか?" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 669fe921aa..d815688bf2 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -1081,6 +1081,9 @@ branding: "あ" enableServerMachineStats: "サーバーのマシン情報見せびらかすで" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" turnOffToImprovePerformance: "オフにしたらえらい軽うなるで。" +inviteCodeCreated: "招待コード作ったで" +inviteLimitExceeded: "招待コード作りすぎやで。" +createLimitRemaining: "作成できる招待コード: 残り {limit} 個やで" unused: "つこてへん" used: "もうつこてる" _initialAccountSetting: diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index efe6d5d620..9df05caab2 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -81,11 +81,15 @@ deleteAndEditConfirm: "이 노트를 삭제한 뒤 다시 편집할까요? 이 copyAndEdit: "복사 후 편집" copyAndEditConfirm: "이 노트를 복사하고 편집할까요? 노트에 포함된 미디어도 같이 복사돼요!" addToList: "리스트에 추가" +addToAntenna: "안테나에 추가" sendMessage: "메시지 보내기" copyRSS: "RSS 복사" copyUsername: "유저명 복사" copyUserId: "유저 ID 복사" copyNoteId: "노트 ID 복사" +copyFileId: "파일 ID 복사" +copyFolderId: "폴더 ID 복사" +copyProfileUrl: "프로필 URL 복사" searchUser: "사용자 검색" reply: "답글" loadMore: "더 보기" @@ -135,8 +139,8 @@ enterEmoji: "이모지 입력" renote: "리노트" unrenote: "리노트 취소" renoted: "리노트 했어요!" -cantRenote: "이 게시물은 리노트 할 수 없어요." -cantReRenote: "리노트된 노트는 리노트 할 수 없어요." +cantRenote: "이 게시물은 리노트할 수 없어요." +cantReRenote: "리노트된 노트는 리노트할 수 없어요." quote: "인용" inChannelRenote: "채널 내 리노트" inChannelQuote: "채널 내 인용" @@ -184,10 +188,12 @@ addEmoji: "이모지 추가" settingGuide: "추천 설정" cacheRemoteFiles: "리모트 파일을 캐시" cacheRemoteFilesDescription: "이 설정을 해지하면 리모트 파일을 캐시하지 않고 해당 파일을 직접 링크해요. 그에 따라 서버의 저장 공간을 절약할 수 있지만, 썸네일이 생성되지 않기 때문에 통신량이 증가하게 돼요." +cacheRemoteSensitiveFiles: "리모트의 민감한 파일을 캐시" +cacheRemoteSensitiveFilesDescription: "이 설정을 비활성화하면 리모트의 민감한 파일은 캐시하지 않고 리모트에서 직접 가져오도록 설정해요." flagAsBot: "삐릭, 삐리리릭? 저는 봇입니다." flagAsBotDescription: "이 계정을 자동화된 수단으로 운용할 경우에 활성화해 주세요. 이 플래그를 활성화하면, 다른 봇이 이를 참고하여 봇 끼리의 무한 연쇄 반응을 회피하거나, 이 계정의 시스템 상에서의 취급이 봇 운영에 최적화되는 등의 변화가 생겨요" flagAsCat: "나는 고양이다냥" -flagAsCatDescription: "이 계정이 고양이라면 활성화 해달라냥" +flagAsCatDescription: "이 계정이 고양이라면 활성화해 달라냥" flagShowTimelineReplies: "타임라인에 노트의 답글을 표시하기" flagShowTimelineRepliesDescription: "이 설정을 활성화하면 타임라인에 다른 유저 간의 답글을 표시해요." autoAcceptFollowed: "팔로우 중인 유저로부터의 팔로우 요청을 자동 수락" @@ -345,6 +351,7 @@ copyUrl: "URL 복사" rename: "이름 변경" avatar: "아바타" banner: "배너" +displayOfSensitiveMedia: "민감한 미디어 표시" whenServerDisconnected: "서버와의 접속이 끊겼을 때" disconnectedFromServer: "접속이 끊어졌어요!" reload: "새로고침" @@ -1122,6 +1129,24 @@ installed: "설치됨" branding: "브랜딩" enableServerMachineStats: "서버의 머신 사양을 공개하기" enableIdenticonGeneration: "유저마다 Identicon 생성 유효화" +turnOffToImprovePerformance: "이 기능을 끄면 성능이 향상될 수 있어요." +createInviteCode: "초대 코드 생성" +createWithOptions: "옵션을 지정하여 생성" +createCount: "초대 수" +inviteCodeCreated: "초대 코드 생성됨" +inviteLimitExceeded: "초대 코드의 생성 한도를 초과했어요." +createLimitRemaining: "초대 한도: {limit}회 남음" +inviteLimitResetCycle: " {time}시간 이내에 최대 {limit}개의 초대 코드를 생성할 수 있어요." +expirationDate: "만료 날짜" +noExpirationDate: "만료기간 없음" +inviteCodeUsedAt: "다음에 사용된 초대 코드" +registeredUserUsingInviteCode: "초대 코드 사용 대상" +waitingForMailAuth: "이메일 인증 보류 중" +inviteCodeCreator: "초대 코드 생성자" +usedAt: "사용 시각" +unused: "사용되지 않음" +used: "사용됨" +expired: "만료됨" additionalPermissionsForFlash: "Play에 대한 추가 권한" thisFlashRequiresTheFollowingPermissions: "이 Play는 다음 권한을 요구해요" doYouWantToAllowThisPlayToAccessYourAccount: "이 Play가 계정에 접근하도록 허용할까요?" @@ -1496,6 +1521,9 @@ _role: ctlAvailable: "고양이 타임라인 보이기" canPublicNote: "공개 노트 허용" canInvite: "서버 초대 코드 발행" + inviteLimit: "초대 한도" + inviteLimitCycle: "초대 발급 간격" + inviteExpirationTime: "초대 만료 기간" canManageCustomEmojis: "커스텀 이모지 관리" driveCapacity: "드라이브 용량" alwaysMarkNsfw: "파일을 항상 NSFW로 지정" @@ -1562,6 +1590,7 @@ _ad: back: "뒤로" reduceFrequencyOfThisAd: "이 광고의 표시 빈도 낮추기" hide: "보이지 않음" + timezoneinfo: "요일은 서버의 표준 시간대에 따라 결정됩니다." _forgotPassword: enterEmail: "여기에 계정에 등록한 메일 주소를 입력해 주세요. 입력한 메일 주소로 비밀번호를 재설정할 수 있는 링크를 보내드릴 거예요." ifNoEmail: "만약 메일 주소를 등록하지 않았다면 관리자에게 문의해 주세요." @@ -1622,6 +1651,10 @@ _aboutMisskey: donate: "CherryPick에 기부하기" relayServer: "릴레이 서버" community: "커뮤니티" +_displayOfSensitiveMedia: + respect: "민감한 콘텐츠로 표시된 미디어 숨기기" + ignore: "민감한 콘텐츠로 표시된 미디어 보이기" + force: "미디어 항상 숨기기" _mfm: cheatSheet: "MFM 도움말" intro: "MFM는 Misskey 기반 클라이언트의 다양한 곳에서 사용할 수 있는 전용 마크업 언어에요. 여기에서 MFM에서 사용할 수 있는 구문을 확인할 수 있어요." @@ -2180,6 +2213,7 @@ _deck: introduction: "칼럼을 조합해서 나만의 인터페이스를 구성해 보세요!" introduction2: "언제든지 화면 우측의 + 버튼을 눌러 새 칼럼을 추가할 수 있어요." widgetsIntroduction: "칼럼 메뉴의 \"위젯 편집\"에서 위젯을 추가해 주세요" + useSimpleUiForNonRootPages: "루트 이외의 페이지로 접속한 경우 UI 간략화하기" _columns: main: "메인" widgets: "위젯" diff --git a/locales/lo-LA.yml b/locales/lo-LA.yml index b54d65b702..0948703e22 100644 --- a/locales/lo-LA.yml +++ b/locales/lo-LA.yml @@ -20,6 +20,7 @@ noNotes: "ບໍ່ມີຫມາຍເຫດ" noNotifications: "ບໍ່ມີການແຈ້ງເຕືອນ" instance: "ອີນສະແຕນ" settings: "ກຳນົດຄ່າ" +notificationSettings: "ຕັ້ງຄ່າການແຈ້ງເຕືອນ" basicSettings: "ການຕັ້ງຄ່າພື້ນຖານ" otherSettings: "ການຕັ້ງຄ່າອື່ນໆ" openInWindow: "ເປີດຢູ່ໃນປ່ອງຢ້ຽມ" @@ -48,9 +49,15 @@ delete: "ລຶບ" deleteAndEdit: "ລົບ​ແລະ​ແກ້​ໄຂ​" deleteAndEditConfirm: "ເຈົ້າ​ແນ່​ໃຈ​ບໍ່? ທີ່ທ່ານຕ້ອງການທີ່ຈະລຶບບັນທຶກນີ້ແລະແກ້ໄຂມັນ ທ່ານອາດຈະສູນເສຍການໂຕ້ຕອບ, ບັນທຶກ, ແລະການຕອບກັບທັງໝົດ" addToList: "ເພີ່ມໃສ່ລາຍຊື່" +addToAntenna: "ເພີ່ມໃສ່ເສົາອາກາດ" sendMessage: "ສົ່ງຂໍ້ຄວາມ" copyRSS: "ສຳເນົາ RSS" copyUsername: "ສຳເນົາຊື່ຜູ້ໃຊ້" +copyUserId: "ສຳເນົາ ID ຜູ້ໃຊ້" +copyNoteId: "ສຳເນົາ ID ບັນທຶກ" +copyFileId: "ສຳເນົາ ID ໄຟລ໌" +copyFolderId: "ສຳເນົາ ID ໂຟນເດີ" +copyProfileUrl: "ສຳເນົາ URL ໂປຣໄຟລ໌" searchUser: "ຄົ້ນຫາຜູ້ໃຊ້" reply: "ຕອບ​ໄປ​ທີ" loadMore: "ໂຫຼດເພີ່ມເຕີມ" @@ -109,6 +116,7 @@ sensitive: "NSFW" add: "ເພີ່ມ" reaction: "ປະຕິກິລິຍາ" reactions: "ປະຕິກິລິຍາ" +attachCancel: "ເອົາໄຟລ໌ແນບ" mute: "ປີດສຽງ" unmute: "ເປີດສຽງ" block: "ບ໋ອກ" @@ -116,6 +124,10 @@ unblock: "ຍົກເລີກກາຮົບລັອກ" suspend: "ລະງັບ" unsuspend: "ເຊົາ​ລະ​ງັບ" selectList: "ເລືອກບັນຊີລາຍການ" +editList: "ແກ້ໄຂລາຍຊື່" +selectChannel: "ເລືອກຊ່ອງ" +selectAntenna: "ເລືອກເສົາອາກາດ" +editAntenna: "ແກ້ໄຂເສົາອາກາດ" selectWidget: "ເລືອກວິກເຈັດ" editWidgets: "ແກ້ໄຂ Widget" editWidgetsExit: "ສຳເລັດແລ້ວ" @@ -125,6 +137,7 @@ emojis: "ອີໂມຈິ" emojiName: "ຊື່ Emoji" emojiUrl: "URL ອີໂມຈິ" addEmoji: "ຕື່ມອີໂມຈິ" +settingGuide: "ການຕັ້ງຄ່າທີ່ແນະນໍາ" flagAsBot: "ໝາຍບັນຊີນີ້ເປັນບັອດ" flagAsCat: "ໝາຍບັນຊີນີ້ເປັນແມວ" flagAsCatDescription: "ເປີດໃຊ້ຕົວເລືອກນີ້ເພື່ອໝາຍບັນຊີນີ້ເປັນແມວ" @@ -133,10 +146,13 @@ flagShowTimelineRepliesDescription: "ສະແດງການຕອບກັບ autoAcceptFollowed: "ອະນຸມັດອັດຕະໂນມັດຕາມຄຳຮ້ອງຂໍຈາກຜູ້ໃຊ້ທີ່ທ່ານກຳລັງຕິດຕາມຢູ່" addAccount: "ເພີ່ມບັນຊີ" loginFailed: "ການເຂົ້າສູ່ລະບົບບໍ່ສຳເລັດ" +showOnRemote: "ເບິ່ງຢູ່ໃນຕົວຢ່າງໄລຍະໄກ" general: "ທົ່ວໄປ" wallpaper: "ພາບພື້ນຫລັງ" setWallpaper: "ຕັ້ງເປັນພາບພື້ນຫຼັງ" +removeWallpaper: "ລຶບຮູບວໍເປເປີອອກ" searchWith: "ຊອກຫາ: {q}" +youHaveNoLists: "ທ່ານ​ບໍ່​ມີ​ລາຍ​ການ​ໃດໆ​" proxyAccount: "ບັນຊີພຣັອກຊີ" host: "ໂຮດສ" selectUser: "ເລືອກຜູ້ໃຊ້" @@ -155,7 +171,9 @@ operations: "ການດຳເນີນງານ" software: "ຊອບແວ" version: "ສະບັບ" metadata: "Metadata" +withNFiles: "{n} ໄຟລ໌(s)" monitor: "ຈໍພາບ" +jobQueue: "ຄິວວຽກ" cpuAndMemory: "CPU ແລະ ຫນ່ວຍຄວາມຈໍາ" network: "ເຄືອຂ່າຍ" disk: "ດິສກ໌" @@ -343,6 +361,7 @@ _widgets: timeline: "​ເສັ້ນກຳ​ນົດ​ເວ​ລາ​" activity: "ກິດຈະກຳ" federation: "ສະຫະພັນ" + jobQueue: "ຄິວວຽກ" _userList: chooseList: "ເລືອກບັນຊີລາຍການ" _cw: diff --git a/locales/sv-SE.yml b/locales/sv-SE.yml index e6b393a1ee..af9eb8062c 100644 --- a/locales/sv-SE.yml +++ b/locales/sv-SE.yml @@ -481,6 +481,7 @@ windowMinimize: "Minimera" windowRestore: "Återställ" pleaseDonate: "CherryPick är en gratis programvara som används på {host}. Donera gärna för att göra utvecklingen ständigt, tack!" resetPasswordConfirm: "Återställ verkligen ditt lösenord?" +dataSaver: "Databesparing" _achievements: _types: _open3windows: diff --git a/locales/th-TH.yml b/locales/th-TH.yml index 8cd542597a..ac4c8e293a 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -1,7 +1,7 @@ --- _lang_: "ภาษาไทย" -headlineMisskey: "เชื่อมต่อเครือข่ายโดยโน้ต" -introMisskey: "ยินดีต้อนรับจ้าาา! CherryPick เป็นบริการไมโครบล็อกโอเพ่นซอร์ส แบบการกระจายอำนาจ\nสร้าง \"โน้ต\" เพื่อแบ่งปันความคิดของคุณกับทุกคนรอบตัวคุณกันเถอะ 📡\nด้วยการ \"รีแอคชั่นผู้คน\" คุณยังสามารถแสดงความรู้สึกของคุณเกี่ยวกับบันทึกของทุกคนได้อย่างรวดเร็ว 👍\n\nแล้วมาท่องสำรวจโลกใบใหม่กันเถอะ! 🚀" +headlineMisskey: "เชื่อมต่อระบบ Network ด้วย Note" +introMisskey: "ยินดีต้อนรับทุกคนจ้า! CherryPick คือ บริการไมโครบล็อกกิ้ง (MicroBlogging) แบบกระจายศูนย์อำนาจ (Decentralized) \n\nเขียน \"โน้ต (Note)\" เพื่อส่งต่อเรื่องราวของคุณให้ทั้งโลกได้รับรู้📡\nและอย่าลืมที่จะ \"React\" กับเรื่องราวของคนอื่น ๆ ด้วย! 👍\n\nมุ่งสู่โลกใบใหม่กันเถอะ🚀" poweredByMisskeyDescription: "{name} เป็นส่วนหนึ่งในบริการที่ถูกขับเคลื่อนโดยแพลตฟอร์มโอเพ่นซอร์ส CherryPick (เรียกว่า \"อินสแตนซ์ CherryPick\")" monthAndDay: "{month}/{day}" search: "ค้นหา" @@ -339,7 +339,7 @@ thisYear: "ปีนี้" thisMonth: "เดือนนี้" today: "วันนี้" dayX: "{day}" -monthX: "{เดือน}" +monthX: "เดือน {month}" yearX: "{year}" pages: "หน้า" integration: "รวบรวม" @@ -2082,6 +2082,7 @@ _deck: introduction: "สร้างอินเทอร์เฟซที่สมบูรณ์แบบสำหรับคุณโดยจัดเรียงคอลัมน์ได้อย่างอิสระ!" introduction2: "คลิกที่เครื่องหมาย + ทางขวาของหน้าจอเพื่อเพิ่มคอลัมน์ใหม่ทุกครั้งที่คุณต้องการ" widgetsIntroduction: "กรุณาเลือก \"แก้ไขวิดเจ็ต\" ในเมนูคอลัมน์และเพิ่มวิดเจ็ต" + useSimpleUiForNonRootPages: "แสดง UI ของ Root Page อย่างง่าย " _columns: main: "หลัก" widgets: "วิดเจ็ต" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 849422ff8e..cada2bbd2b 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -156,6 +156,8 @@ addEmoji: "添加表情符号" settingGuide: "推荐配置" cacheRemoteFiles: "缓存远程文件" cacheRemoteFilesDescription: "当禁用此设定时远程文件将直接从远程服务器载入。禁用后会减小储存空间需求,但是会增加流量,因为缩略图不会被生成。" +cacheRemoteSensitiveFiles: "缓存远程敏感媒体文件" +cacheRemoteSensitiveFilesDescription: "如果禁用这项设定,远程服务器的敏感媒体将不会被缓存,而是直接链接。" flagAsBot: "这是一个机器人账号" flagAsBotDescription: "如果此账户由程序控制,请启用此项。启用后,此标志可以帮助其他开发人员防止机器人之间产生无限互动的行为,并让 CherryPick 的内部系统将此账户识别为机器人。" flagAsCat: "将这个账户设定为一只猫" @@ -1086,7 +1088,20 @@ branding: "品牌" enableServerMachineStats: "公开服务器硬件统计信息" enableIdenticonGeneration: "启用生成用户 Identicon" turnOffToImprovePerformance: "关闭该选项可以提高性能。" +createInviteCode: "发行邀请码" +createWithOptions: "使用选项来创建" +createCount: "发行数" inviteCodeCreated: "已创建邀请码" +inviteLimitExceeded: "可供发行的邀请码已达上限。" +createLimitRemaining: "可供发行的邀请码:剩余{limit}个" +inviteLimitResetCycle: "可以在{time}内发行最多{limit}个邀请码。" +expirationDate: "有效日期" +noExpirationDate: "不设置有效日期" +inviteCodeUsedAt: "邀请码被使用的日期和时间" +registeredUserUsingInviteCode: "使用了邀请码的用户" +waitingForMailAuth: "等待验证电子邮件" +inviteCodeCreator: "发行邀请码的用户" +usedAt: "使用时间" unused: "未使用" used: "已使用" expired: "已过期" @@ -1400,6 +1415,9 @@ _role: ltlAvailable: "查看本地时间线" canPublicNote: "允许公开发帖" canInvite: "发放服务器邀请码" + inviteLimit: "可发行邀请码的数量" + inviteLimitCycle: "邀请码的发行间隔" + inviteExpirationTime: "邀请码的有效日期" canManageCustomEmojis: "管理自定义表情符号" driveCapacity: "网盘容量" alwaysMarkNsfw: "总是将文件标记为 NSFW" @@ -2064,6 +2082,7 @@ _deck: introduction: "将各列进行组合以创建您自己的界面!" introduction2: "您可以随时通过屏幕右侧的 + 来添加列" widgetsIntroduction: "从列菜单中,选择“小工具编辑”来添加小工具" + useSimpleUiForNonRootPages: "用简易UI表示非根页面" _columns: main: "主列" widgets: "小工具" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 0b87458d8d..7e4e3a0b7d 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -152,7 +152,7 @@ emoji: "表情符號" emojis: "表情符號" emojiName: "表情符號名稱" emojiUrl: "表情符號URL" -addEmoji: "加入表情符號" +addEmoji: "新增表情符號" settingGuide: "推薦設定" cacheRemoteFiles: "快取遠端檔案" cacheRemoteFilesDescription: "禁用此設定會停止遠端檔案的緩存,從而節省儲存空間,但資料會因直接連線從而產生額外連接數據。" @@ -160,12 +160,12 @@ cacheRemoteSensitiveFiles: "快取遠端的敏感檔案" cacheRemoteSensitiveFilesDescription: "若停用這個設定,則不會快取遠端的敏感檔案,而是直接連結。" flagAsBot: "此使用者是機器人" flagAsBotDescription: "如果本帳戶是由程式控制,請啟用此選項。啟用後,會作為標示幫助其他開發者防止機器人之間產生無限互動的行為,並會調整CherryPick內部系統將本帳戶識別為機器人。" -flagAsCat: "喵~~~~~~~~~~~~~~!!!!!!!!!!!!" +flagAsCat: "此帳戶是一隻貓,喵~~~!!!" flagAsCatDescription: "如果想將本帳戶標示為一隻貓,請開啟此標示" flagShowTimelineReplies: "在時間軸上顯示貼文的回覆" flagShowTimelineRepliesDescription: "啟用時,時間線除了顯示用戶的貼文以外,還會顯示用戶對其他貼文的回覆。" autoAcceptFollowed: "自動允許來自追隨中使用者的追隨請求" -addAccount: "添加帳戶" +addAccount: "新增帳戶" reloadAccountsList: "更新帳戶清單的資訊" loginFailed: "登入失敗" showOnRemote: "轉到所在實例顯示" @@ -260,7 +260,7 @@ saved: "已儲存" messaging: "聊天" upload: "上傳" keepOriginalUploading: "保留原圖" -keepOriginalUploadingDescription: "上傳圖片時保留原始圖片。關閉時,瀏覽器會在上傳時生成一張用於web發布的圖片。" +keepOriginalUploadingDescription: "上傳圖片時保留原始圖片。關閉時,瀏覽器會在上傳時生成適用於網路傳送的版本。" fromDrive: "從雲端空間" fromUrl: "從URL" uploadFromUrl: "從網址上傳" @@ -279,7 +279,7 @@ basicNotesBeforeCreateAccount: "基本注意事項" termsOfService: "服務條款" start: "開始" home: "首頁" -remoteUserCaution: "由於該使用者來自遠端實例,因此資訊可能非即時的。" +remoteUserCaution: "由於該使用者來自其他實例,因此其資訊可能不完整。" activity: "動態" images: "圖片" image: "圖片" @@ -289,12 +289,12 @@ registeredDate: "註冊日期" location: "位置" theme: "外觀主題" themeForLightMode: "在淺色模式下使用的主題" -themeForDarkMode: "在黑暗模式下使用的主題" +themeForDarkMode: "在深色模式下使用的主題" light: "淺色" -dark: "黑暗" +dark: "深色" lightThemes: "明亮主題" darkThemes: "黑暗主題" -syncDeviceDarkMode: "將黑暗模式與設備設置同步" +syncDeviceDarkMode: "同步至此裝置的深色模式設定" drive: "雲端硬碟" fileName: "檔案名稱" selectFile: "選擇檔案" @@ -319,7 +319,7 @@ copyUrl: "複製URL" rename: "重新命名" avatar: "大頭貼" banner: "橫幅" -displayOfSensitiveMedia: "敏感性媒體的顯示" +displayOfSensitiveMedia: "顯示敏感媒體" whenServerDisconnected: "與伺服器的連接中斷時" disconnectedFromServer: "與伺服器中斷連線" reload: "重新整理" @@ -343,18 +343,18 @@ monthX: "{month}月" yearX: "{year}年" pages: "頁面" integration: "整合" -connectService: "己連結" -disconnectService: "己斷開 " -enableLocalTimeline: "開啟本地時間軸" +connectService: "已連結" +disconnectService: "已斷開 " +enableLocalTimeline: "啟用本地時間軸" enableGlobalTimeline: "啟用全域時間軸" disablingTimelinesInfo: "為了方便,即使您關閉了時間線功能,管理員和審查員仍可以繼續使用。" registration: "註冊" -enableRegistration: "開啟新使用者註冊" +enableRegistration: "開放新使用者註冊" invite: "邀請" driveCapacityPerLocalAccount: "每個本地用戶的雲端空間大小" driveCapacityPerRemoteAccount: "每個非本地用戶的雲端空間大小" inMb: "以Mbps為單位" -iconUrl: "圖標URL (例如 favicon)" +iconUrl: "圖標 URL(例如 favicon)" bannerUrl: "橫幅圖片URL" backgroundImageUrl: "背景圖片的來源網址 " basicInfo: "基本資訊" @@ -376,26 +376,26 @@ turnstile: "Turnstile" enableTurnstile: "啟用 Turnstile" turnstileSiteKey: "網站金鑰" turnstileSecretKey: "金鑰" -avoidMultiCaptchaConfirm: "使用多種驗證方式可能會造成干擾,您要關閉其他驗證方式嗎?您可以按“取消”保留多種驗證方式。" +avoidMultiCaptchaConfirm: "使用多種驗證方式可能會造成干擾,您要關閉其他驗證方式嗎?您可以按「取消」保留多種驗證方式。" antennas: "天線" manageAntennas: "管理天線" name: "名稱" antennaSource: "接收來源" antennaKeywords: "包含關鍵字" antennaExcludeKeywords: "排除關鍵字" -antennaKeywordsDescription: "用空格分隔指定AND、用換行符分隔指定OR" +antennaKeywordsDescription: "空格代表「以及」(AND),換行代表「或者」(OR)" notifyAntenna: "通知有新貼文" withFileAntenna: "僅帶有附件的貼文" -enableServiceworker: "開啟 ServiceWorker" -antennaUsersDescription: "指定用換行符分隔的用戶名" +enableServiceworker: "啟用 ServiceWorker" +antennaUsersDescription: "填寫使用者名稱,以換行分隔" caseSensitive: "區分大小寫" withReplies: "包含回覆" connectedTo: "您的帳戶已連接到以下社交帳戶" notesAndReplies: "貼文與回覆" withFiles: "附件" silence: "禁言" -silenceConfirm: "確定要靜音此使用者嗎?" -unsilence: "解除靜音" +silenceConfirm: "確定要禁言此帳戶嗎?" +unsilence: "解除禁言" unsilenceConfirm: "確定要解除禁言嗎?" popularUsers: "熱門使用者" recentlyUpdatedUsers: "最近發文的使用者" @@ -409,25 +409,25 @@ about: "關於" aboutMisskey: "關於 CherryPick" administrator: "管理員" token: "權杖" -2fa: "雙因素驗證" +2fa: "雙重驗證" totp: "驗證應用程式" totpDescription: "以驗證應用程式輸入一次性密碼" moderator: "審查員" moderation: "審查" nUsersMentioned: "被提及到 {n} 次" -securityKeyAndPasskey: "安全金鑰・Passkey" +securityKeyAndPasskey: "安全金鑰、Passkey" securityKey: "安全金鑰" lastUsed: "上次使用" -lastUsedAt: "最後使用:{t}" +lastUsedAt: "上次使用:{t}" unregister: "註銷帳戶" passwordLessLogin: "設置無密碼登入" passwordLessLoginDescription: "不使用密碼,以安全金鑰或 Passkey 登入" -resetPassword: "重置密碼" +resetPassword: "重設密碼" newPasswordIs: "新密碼為「{password}」" reduceUiAnimation: "減少介面的動態視覺" share: "分享" notFound: "找不到" -notFoundDescription: "找不到與指定URL回應的頁面" +notFoundDescription: "找不到該 URL 的頁面" uploadFolder: "預設上傳資料夾" cacheClear: "清除快取" markAsReadAllNotifications: "標記所有通知為已讀" @@ -488,17 +488,17 @@ joinOrCreateGroup: "請加入現有群組,或創建新群組。" showNoteActionsOnlyHover: "僅在游標停留時顯示貼文的操作選項" noHistory: "沒有歷史紀錄" signinHistory: "登入歷史" -enableAdvancedMfm: "啟用高級MFM" -enableAnimatedMfm: "啟用MFM動畫" +enableAdvancedMfm: "啟用高級 MFM" +enableAnimatedMfm: "啟用 MFM 動畫" doing: "正在進行" category: "類別" tags: "標籤" docSource: "文件來源" createAccount: "建立帳戶" existingAccount: "現有帳戶" -regenerate: "再生" +regenerate: "再次生成" fontSize: "字體大小" -mediaListWithOneImageAppearance: "僅1枚圖片的媒體列表高度" +mediaListWithOneImageAppearance: "只有一張圖片時的媒體列表高度" limitTo: "上限為{x}" noFollowRequests: "沒有追隨您的請求" openImageInNewTab: "於新分頁中開啟圖片" @@ -507,7 +507,7 @@ local: "本地" remote: "遠端" total: "合計" weekOverWeekChanges: "與上週相比" -dayOverDayChanges: "與前一日相比" +dayOverDayChanges: "與昨日相比" appearance: "外觀" clientSettings: "客戶端設定" accountSettings: "帳戶設定" @@ -519,26 +519,26 @@ showFeaturedNotesInTimeline: "在時間軸上顯示熱門推薦" objectStorage: "Object Storage (物件儲存)" useObjectStorage: "使用Object Storage" objectStorageBaseUrl: "Base URL" -objectStorageBaseUrlDesc: "引用時的URL。如果您使用的是CDN或反向代理,請指定其URL,例如S3:'https://.s3.amazonaws.com'、GCS:'https://storage.googleapis.com/'。" +objectStorageBaseUrlDesc: "引用時的 URL。如果您使用的是 CDN 或反向代理,請指定其 URL,例如 S3(https://.s3.amazonaws.com)、GCS(https://storage.googleapis.com/)。" objectStorageBucket: "儲存空間(Bucket)" -objectStorageBucketDesc: "請指定您正在使用的服務的存儲桶名稱。 " +objectStorageBucketDesc: "請填寫所用服務的儲存空間(Bucket)名稱。 " objectStoragePrefix: "前綴" -objectStoragePrefixDesc: "它存儲在此前綴目錄下。" +objectStoragePrefixDesc: "它儲存在此前綴目錄下。" objectStorageEndpoint: "端點(Endpoint)" -objectStorageEndpointDesc: "如要使用AWS S3,請留空。否則請依照你使用的服務商的說明書進行設定,以''或 ':'的形式設定端點(Endpoint)。" +objectStorageEndpointDesc: "如使用 AWS S3,請留空。如使用其他服務,請按照其說明文件以「」或「:」的形式設定端點(Endpoint)。" objectStorageRegion: "地域(Region)" -objectStorageRegionDesc: "指定一個分區,例如“xx-east-1”。 如果您使用的服務沒有分區的概念,請留空或填寫“us-east-1”。" -objectStorageUseSSL: "使用SSL" -objectStorageUseSSLDesc: "如果不使用https進行API連接,請關閉" +objectStorageRegionDesc: "請填寫一個分區,例如「xx-east-1」。 如果您使用的服務不設分區,請留空或填寫「us-east-1」。" +objectStorageUseSSL: "使用 SSL" +objectStorageUseSSLDesc: "請在不使用 https 連接 API 時關閉" objectStorageUseProxy: "使用網路代理" -objectStorageUseProxyDesc: "如果不使用代理進行API連接,請關閉" -objectStorageSetPublicRead: "上傳時設定為\"public-read\"" -s3ForcePathStyleDesc: "啟用 s3ForcePathStyle 會強制將儲存槽名稱指定為 URL 中路徑的一部分,而不是主機名。 使用自託管 Minio 之類的可能需要啟用。" +objectStorageUseProxyDesc: "請在不使用網路代理連接 API 時關閉" +objectStorageSetPublicRead: "上傳時設定為「public-read」" +s3ForcePathStyleDesc: "啟用 s3ForcePathStyle 將強制填寫儲存空間(Bucket)名稱至 URL 路徑內,而非寫入主機名。 使用如 Minio 等自行託管服務時可能需要啟用。" serverLogs: "伺服器日誌" deleteAll: "刪除所有記錄" showFixedPostForm: "於時間軸頁頂顯示「發送貼文」方框" showFixedPostFormInChannel: "於時間軸頁頂顯示「發送貼文」方框(頻道)" -newNoteRecived: "發現新的貼文" +newNoteRecived: "發現新貼文" sounds: "音效" sound: "音效" listen: "聆聽" @@ -562,19 +562,19 @@ sort: "排序" ascendingOrder: "昇冪" descendingOrder: "降冪" scratchpad: "暫存記憶體" -scratchpadDescription: "AiScript控制台為AiScript提供了實驗環境。您可以在此編寫、執行和確認代碼與CherryPick互動的结果。" +scratchpadDescription: "AiScript 控制台為 AiScript 的實驗環境。您可以在此編寫、執行和確認程式碼與 CherryPick 互動的结果。" output: "輸出" script: "腳本" -disablePagesScript: "停用頁面的AiScript腳本" +disablePagesScript: "停用頁面的 AiScript 腳本" updateRemoteUser: "更新遠端使用者資訊" deleteAllFiles: "刪除所有檔案" -deleteAllFilesConfirm: "要删除所有檔案嗎?" +deleteAllFilesConfirm: "要刪除所有檔案嗎?" removeAllFollowing: "解除所有追隨" removeAllFollowingDescription: "解除{host}所有的追隨。在伺服器不再存在時執行。" userSuspended: "該使用者已被停用" userSilenced: "該用戶已被禁言。" yourAccountSuspendedTitle: "帳戶已被凍結" -yourAccountSuspendedDescription: "由於違反了伺服器的服務條款或其他原因,該帳戶已被凍結。 您可以與管理員連繫以了解更多訊息。 請不要創建一個新的帳戶。" +yourAccountSuspendedDescription: "該帳戶已因違反伺服器服務條款或其他原因而被凍結。您可以向管理員查詢更多資訊。請不要建立新帳戶。" tokenRevoked: "權杖無效" tokenRevokedDescription: "登入權杖失效,請重新登入。" accountDeleted: "帳戶已被刪除" @@ -587,22 +587,22 @@ relays: "中繼" addRelay: "新增中繼" inboxUrl: "收件夾URL" addedRelays: "已加入的中繼" -serviceworkerInfo: "您需要啟用推送通知" -deletedNote: "已删除的貼文" -invisibleNote: "私密的貼文" +serviceworkerInfo: "您需要啟用推送通知。" +deletedNote: "已刪除的貼文" +invisibleNote: "隱藏的貼文" enableInfiniteScroll: "啟用自動滾動頁面模式" visibility: "可見性" poll: "投票" useCw: "隱藏內容" -enablePlayer: "打開播放器" +enablePlayer: "開啟播放器" disablePlayer: "關閉播放器" expandTweet: "展開推文" themeEditor: "主題編輯器" description: "描述" -describeFile: "添加標題 " -enterFileDescription: "輸入標題 " +describeFile: "新增標題" +enterFileDescription: "輸入標題" author: "作者" -leaveConfirm: "有未保存的更改。要放棄嗎?" +leaveConfirm: "尚未儲存修改。要放棄嗎?" manage: "管理" plugins: "外掛" preferencesBackups: "備份設定檔" @@ -628,14 +628,14 @@ enableEmail: "啟用發送電郵功能" emailConfigInfo: "用於確認電郵地址及密碼重置" email: "電子郵件" emailAddress: "電郵地址" -smtpConfig: "SMTP伺服器設定" +smtpConfig: "SMTP 伺服器設定" smtpHost: "主機" smtpPort: "埠" smtpUser: "使用者名稱" smtpPass: "密碼" emptyToDisableSmtpAuth: "留空使用者名稱和密碼以關閉SMTP驗證。" smtpSecure: "在 SMTP 連接中使用隱式 SSL/TLS" -smtpSecureInfo: "使用STARTTLS時關閉。" +smtpSecureInfo: "使用 STARTTLS 時關閉。" testEmail: "測試郵件發送" wordMute: "被靜音的文字" regexpError: "正規表達式錯誤" @@ -658,16 +658,16 @@ useGlobalSetting: "使用全域設定" useGlobalSettingDesc: "啟用時,將使用帳戶通知設定。停用時,則可以單獨設定。" other: "其他" regenerateLoginToken: "重新產生登入權杖" -regenerateLoginTokenDescription: "重新產生用於登入的內部權杖。一般情況下是不需要這樣做的。一旦重產,所有裝置將會被登出。" +regenerateLoginTokenDescription: "重新產生用於登入的內部權杖。一般情況下是不需要這樣做的。重新產生後,所有裝置將會被登出。" setMultipleBySeparatingWithSpace: "您可以使用空格分隔多個項目。" -fileIdOrUrl: "檔案ID或URL" +fileIdOrUrl: "檔案 ID 或 URL" behavior: "行為" sample: "範例" abuseReports: "檢舉" reportAbuse: "檢舉" reportAbuseOf: "檢舉{name}" -fillAbuseReportDescription: "請填寫檢舉的詳細理由。可以的話,請附上針對的URL網址。" -abuseReported: "回報已送出。感謝您的報告。" +fillAbuseReportDescription: "請填寫檢舉的詳細理由。如有需要,請附上相關 URL。" +abuseReported: "檢舉完成。感謝您的報告。" reporter: "檢舉者" reporteeOrigin: "檢舉來源" reporterOrigin: "檢舉者來源" @@ -677,7 +677,7 @@ send: "發送" abuseMarkAsResolved: "處理完畢" openInNewTab: "在新分頁中開啟" openInSideView: "在側欄中開啟" -defaultNavigationBehaviour: "默認導航" +defaultNavigationBehaviour: "預設導航" editTheseSettingsMayBreakAccount: "修改這些設定可能會毀損您的帳戶" instanceTicker: "貼文的實例來源" waitingFor: "等待{x}" @@ -692,7 +692,7 @@ createNewClip: "建立新摘錄" unclip: "解除摘錄" confirmToUnclipAlreadyClippedNote: "此貼文已包含在摘錄「{name}」中。 你想將貼文從這個摘錄中排除嗎?" public: "公開" -i18nInfo: "CherryPick已經被志願者們翻譯成各種語言版本,如果想要幫忙的話,可以進入{link}幫助翻譯。" +i18nInfo: "CherryPick 已被志願者們翻譯成各種語言版本。您可以瀏覽{link}幫助翻譯。" manageAccessTokens: "管理存取權杖" accountInfo: "帳戶資訊" notesCount: "貼文數量" @@ -713,7 +713,7 @@ driveUsage: "雲端硬碟使用量" noCrawle: "拒絕搜尋引擎索引" noCrawleDescription: "要求網路搜尋引擎不要索引你的個人資料頁、貼文及頁面等。" lockedAccountInfo: "即使你通過了追隨者請求,除非你將貼文的可見性設定為 「追隨者」,否則任何人都能看見你的貼文。" -alwaysMarkSensitive: "默認將圖像/影像標記為敏感內容" +alwaysMarkSensitive: "預設將多媒體標記為敏感內容" loadRawImages: "以原始圖檔顯示附件圖檔的縮圖" disableShowingAnimatedImages: "不播放動態圖檔" verificationEmailSent: "已發送驗證電子郵件。請點擊進入電子郵件中的鏈接完成驗證。" @@ -750,7 +750,7 @@ myTheme: "我的佈景主題" backgroundColor: "背景" accentColor: "重點色彩" textColor: "文字" -saveAs: "另存為..." +saveAs: "另存新檔" advanced: "進階" advancedSettings: "進階設定" value: "數值" @@ -775,7 +775,7 @@ emailNotification: "郵件通知" publish: "發布" inChannelSearch: "頻道内搜尋" useReactionPickerForContextMenu: "點擊右鍵開啟反應工具欄" -typingUsers: "{users}輸入中..." +typingUsers: "{users}輸入中" jumpToSpecifiedDate: "跳轉到特定日期" showingPastTimeline: "顯示過往的時間線" clear: "清除" @@ -783,21 +783,21 @@ markAllAsRead: "全部標示為已讀" goBack: "返回" unlikeConfirm: "要取消按讚嗎?" fullView: "全熒幕顯示" -quitFullView: "退出全熒幕顯示" -addDescription: "添加描述" +quitFullView: "退出全螢幕顯示" +addDescription: "新增描述" userPagePinTip: "在貼文的選單中選擇\"置頂\",即可置頂該貼文至您的個人檔案頁面。" notSpecifiedMentionWarning: "此貼文有未指定的提及" info: "資訊" userInfo: "用戶資料" unknown: "未知" -onlineStatus: "在線狀態" -hideOnlineStatus: "隱藏在線狀態" -hideOnlineStatusDescription: "隱藏在線狀態後,可能會降低檢索等功能的便利性。" +onlineStatus: "上線狀態" +hideOnlineStatus: "隱藏上線狀態" +hideOnlineStatusDescription: "隱藏上線狀態後,可能會降低搜尋等功能的便利性。" online: "線上" active: "最近活躍" offline: "離線" notRecommended: "不推薦" -botProtection: "Bot防護" +botProtection: "Bot 防護" instanceBlocking: "已封鎖的實例" selectAccount: "選擇帳戶" switchAccount: "切換帳戶" @@ -808,11 +808,11 @@ user: "使用者" administration: "管理" accounts: "帳戶" switch: "切換" -noMaintainerInformationWarning: "尚未設定管理員信息。" -noBotProtectionWarning: "尚未設定Bot防護。" +noMaintainerInformationWarning: "尚未設定管理員訊息。" +noBotProtectionWarning: "尚未設定 Bot 防護。" configure: "設定" postToGallery: "發佈到相簿" -postToHashtag: "以此主題標籤發布" +postToHashtag: "以此主題標籤發佈" gallery: "相簿" recentPosts: "最新貼文" popularPosts: "熱門的貼文" @@ -847,7 +847,7 @@ accountDeletionInProgress: "正在刪除帳戶" usernameInfo: "在伺服器上您的帳戶是唯一的識別名稱。您可以使用字母 (a ~ z, A ~ Z)、數字 (0 ~ 9) 和下底線 (_)。之後帳戶名是不能更改的。" aiChanMode: "小藍模式" devMode: "開發者模式" -keepCw: "保持CW" +keepCw: "保持 CW" pubSub: "Pub/Sub 帳戶" lastCommunication: "最近的通信" resolved: "已解決" @@ -869,7 +869,7 @@ classic: "經典" muteThread: "將貼文串設為靜音" unmuteThread: "將貼文串的靜音解除" ffVisibility: "連繫的可見性" -ffVisibilityDescription: "您可以設定您的關注/關注者資訊的公開範圍" +ffVisibilityDescription: "您可以設定追隨或追隨者資訊的公開範圍" continueThread: "查看更多貼文" deleteAccountConfirm: "將要刪除帳戶。是否確定?" incorrectPassword: "密碼錯誤。" @@ -890,15 +890,15 @@ numberOfColumn: "列數" searchByGoogle: "搜尋" instanceDefaultLightTheme: "實例預設的淺色主題" instanceDefaultDarkTheme: "實例預設的深色主題" -instanceDefaultThemeDescription: "輸入物件形式的主题代碼" +instanceDefaultThemeDescription: "輸入物件形式的主題代碼" mutePeriod: "靜音的期限" period: "期限" indefinitely: "無期限" -tenMinutes: "10分鐘" -oneHour: "1小時" -oneDay: "1天" -oneWeek: "1週" -oneMonth: "1個月" +tenMinutes: "十分鐘" +oneHour: "一小時" +oneDay: "一天" +oneWeek: "一週" +oneMonth: "一個月" reflectMayTakeTime: "可能需要一些時間才會出現效果。" failedToFetchAccountInformation: "取得帳戶資訊失敗" rateLimitExceeded: "已超過速率限制" @@ -914,7 +914,7 @@ thereIsUnresolvedAbuseReportWarning: "有尚未處理的檢舉。" recommended: "推薦" check: "檢查" driveCapOverrideLabel: "更改這個使用者的雲端硬碟容量上限" -driveCapOverrideCaption: "如果指定0以下的值,就會被取消。" +driveCapOverrideCaption: "如果指定 0 以下的值,就會被取消。" requireAdminForView: "必須以管理員帳戶登入才可以檢視。" isSystemAccount: "由系統自動建立與管理的帳戶。" typeToConfirm: "要執行這項操作,請輸入 {x} " @@ -941,21 +941,21 @@ failedToUpload: "上傳失敗" cannotUploadBecauseInappropriate: "由於判定可能包含不適當的內容,因此無法上傳。" cannotUploadBecauseNoFreeSpace: "由於雲端硬碟沒有可用空間,因此無法上傳。" cannotUploadBecauseExceedsFileSizeLimit: "由於超過了檔案大小的限制,無法上傳。" -beta: "Beta" -enableAutoSensitive: "自動NSFW判定" -enableAutoSensitiveDescription: "如果可用,請利用機器學習在媒體上自動設置 NSFW 旗標。 即使關閉此功能,依實例而定也可能會自動設置。" -activeEmailValidationDescription: "積極地驗證用戶的電子郵件地址,判斷它是否為免洗地址,或者它是否可以通信。 若關閉,則只會檢查字元是否正確。" +beta: "測試版" +enableAutoSensitive: "自動 NSFW 判定" +enableAutoSensitiveDescription: "如果可用,它將使用機器學習技術判斷多媒體內容是否需要標記 NSFW。即使關閉此功能,也可能會依實例規則而自動啟用。" +activeEmailValidationDescription: "積極驗證帳戶的電郵地址,以判斷它是否可以通訊。關閉此選項代表只會檢查地址是否符合格式。" navbar: "導覽列" shuffle: "隨機" account: "帳戶" move: "移動 " pushNotification: "推播通知" subscribePushNotification: "啟用推播通知" -unsubscribePushNotification: "停止推播通知" +unsubscribePushNotification: "停用推播通知" pushNotificationAlreadySubscribed: "推播通知啟用中" pushNotificationNotSupported: "瀏覽器或實例不支援推播通知" -sendPushNotificationReadMessage: "通知與訊息如果已讀的話,就將推播通知刪除" -sendPushNotificationReadMessageCaption: "「{emptyPushNotificationMessage}」通知將立刻顯示。可能會增加設備的電池消耗。" +sendPushNotificationReadMessage: "如果已閱讀通知與訊息,就刪除推播通知" +sendPushNotificationReadMessageCaption: "「{emptyPushNotificationMessage}」通知將立刻顯示。可能會更消耗裝置電池。" windowMaximize: "最大化" windowMinimize: "最小化" windowRestore: "復原" @@ -970,8 +970,8 @@ numberOfLikes: "讚數" show: "檢視" neverShow: "不再顯示" remindMeLater: "以後再說" -didYouLikeMisskey: "您是否喜愛CherryPick呢?" -pleaseDonate: "CherryPick是由{host}使用的免費軟體。請贊助我們,讓開發能夠持續!" +didYouLikeMisskey: "您喜歡 CherryPick 嗎?" +pleaseDonate: "CherryPick 是由 {host} 使用的免費軟體。請贊助我們,讓開發得以持續!" roles: "角色" role: "角色" noRole: "沒有角色" @@ -983,23 +983,23 @@ color: "顏色" manageCustomEmojis: "管理自訂表情符號" youCannotCreateAnymore: "您無法再建立更多了。" cannotPerformTemporary: "暫時無法進行" -cannotPerformTemporaryDescription: "由於超過操作次數限制,暫時無法進行。請過一段時間之後再嘗試。" +cannotPerformTemporaryDescription: "由於超過操作次數限制,因此暫時無法進行。請稍後再嘗試。" invalidParamError: "參數錯誤" -invalidParamErrorDescription: "請求參數有問題。通常是bug造成的,但也有輸入的字元數過多之類的可能性。" +invalidParamErrorDescription: "請求參數有問題。這可能是漏洞或輸入過多字元所致。" permissionDeniedError: "操作被拒絕" -permissionDeniedErrorDescription: "本帳號沒有執行這個操作的權限。" +permissionDeniedErrorDescription: "此帳戶沒有執行這個操作的權限。" preset: "預設值" selectFromPresets: "從預設值中選擇" achievements: "成就" gotInvalidResponseError: "伺服器的回應無效" gotInvalidResponseErrorDescription: "伺服器可能已關閉或者在維護中,請稍後再試。" thisPostMayBeAnnoying: "這篇貼文可能會造成別人的困擾。" -thisPostMayBeAnnoyingHome: "發布到首頁" +thisPostMayBeAnnoyingHome: "發佈到首頁" thisPostMayBeAnnoyingCancel: "退出" -thisPostMayBeAnnoyingIgnore: "直接發布貼文" +thisPostMayBeAnnoyingIgnore: "直接發佈貼文" collapseRenotes: "省略顯示已看過的轉發貼文" internalServerError: "內部伺服器錯誤" -internalServerErrorDescription: "內部伺服器發生了非預期的錯誤。" +internalServerErrorDescription: "內部伺服器出現意外錯誤。" copyErrorInfo: "複製錯誤資訊" joinThisServer: "在此伺服器上註冊" exploreOtherServers: "探索其他伺服器" @@ -1009,7 +1009,7 @@ disableFederationConfirmWarn: "即使停止了聯邦功能,貼文也不會變 disableFederationOk: "停止聯邦功能" invitationRequiredToRegister: "目前這個伺服器為邀請制,必須擁有邀請碼才能註冊。" emailNotSupported: "這個伺服器不支援寄送郵件" -postToTheChannel: "發布到頻道" +postToTheChannel: "發佈到頻道" cannotBeChangedLater: "之後不能變更。" reactionAcceptance: "接受表情反應" likeOnly: "僅限讚" @@ -1020,7 +1020,7 @@ rolesAssignedToMe: "指派給自己的角色" resetPasswordConfirm: "重設密碼?" sensitiveWords: "敏感詞" sensitiveWordsDescription: "將含有設定詞彙的貼文可見性設為發送至首頁。可以用換行來進行複數的設定。" -sensitiveWordsDescription2: "用空格分隔關鍵詞構成AND格式,用斜線包圍關鍵字構成正規表達式。" +sensitiveWordsDescription2: "空格代表「以及」(AND),斜線包圍關鍵字代表使用正規表達式。" notesSearchNotAvailable: "無法使用搜尋貼文功能。" license: "授權" unfavoriteConfirm: "要取消收錄我的最愛嗎?" @@ -1031,8 +1031,8 @@ retryAllQueuesConfirmTitle: "要現在重試嗎?" retryAllQueuesConfirmText: "伺服器的負荷可能會暫時增加。" enableChartsForRemoteUser: "生成遠端用戶的圖表" enableChartsForFederatedInstances: "生成遠端伺服器的圖表" -showClipButtonInNoteFooter: "將摘錄添加至貼文" -largeNoteReactions: "將貼文的反應放大顯示" +showClipButtonInNoteFooter: "新增摘錄至貼文" +largeNoteReactions: "放大顯示貼文反應" noteIdOrUrl: "貼文ID或URL" video: "影片" videos: "影片" @@ -1060,33 +1060,33 @@ pleaseConfirmBelowBeforeSignup: "在本伺服器註冊之前,請確認下列 pleaseAgreeAllToContinue: "必須全部勾選「同意」才能繼續。" continue: "繼續" preservedUsernames: "保留的使用者名稱" -preservedUsernamesDescription: "換行列舉要保留的使用者名稱。此處指定的使用者名稱,在建立帳戶時無法使用,但由管理者所建立的帳戶不受此限。此外,既有的帳戶也不受影響。" +preservedUsernamesDescription: "換行列舉要保留的使用者名稱。此處出現的名稱將在註冊時禁用,但由管理者建立帳戶則不受此限。此外,既有的帳戶也不受影響。" createNoteFromTheFile: "由此檔案建立貼文" archive: "封存" channelArchiveConfirmTitle: "要封存{name}嗎?" -channelArchiveConfirmDescription: "封存以後,在頻道列表與搜索結果中不會顯示,也無法發布新的貼文。" +channelArchiveConfirmDescription: "封存後,將不會在頻道列表與搜尋結果中顯示,也無法發佈新貼文。" thisChannelArchived: "這個頻道已被封存。" displayOfNote: "顯示貼文" initialAccountSetting: "初始設定" youFollowing: "追隨中" preventAiLearning: "拒絕接受生成式AI的訓練" -preventAiLearningDescription: "要求外部的文章生成式AI或圖像生成式AI不以發布的貼文和圖像等內容為學習對象。這是透過在HTML響應中包含noai旗標來實現的,但不能完全防止AI的學習,因為這要看該AI是否遵守這個要求。" +preventAiLearningDescription: "要求站外生成式 AI 不使用您發佈的內容訓練模型。此功能會使伺服器於 HTML 回應新增「noai」標籤,而因為要視乎 AI 會否遵守該標籤,所以此功能無法完全阻止所有 AI 使用您的內容。" options: "選項" specifyUser: "指定使用者" failedToPreviewUrl: "無法預覽" update: "更新" -rolesThatCanBeUsedThisEmojiAsReaction: "可以用這個做為反應的角色" -rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "未指定角色的情況,則任何人都可以將它用做反應。" -rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "角色必須是公開的角色。" -cancelReactionConfirm: "要取消做出的反應嗎?" -changeReactionConfirm: "要變更做出的反應嗎?" +rolesThatCanBeUsedThisEmojiAsReaction: "可以使用此表情符號為反應的角色" +rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "如沒有指定角色,任何人都可使用此表情回應。" +rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "必須為公開角色。" +cancelReactionConfirm: "要取消此反應嗎?" +changeReactionConfirm: "要更改反應嗎?" later: "稍後再說" -goToMisskey: "往CherryPick" +goToMisskey: "往 CherryPick" additionalEmojiDictionary: "表情符號的附加辭典" installed: "已安裝" branding: "品牌宣傳" -enableServerMachineStats: "公布伺服器的機器資訊" -enableIdenticonGeneration: "啟用每個使用者的Identicon" +enableServerMachineStats: "公佈伺服器的機器資訊" +enableIdenticonGeneration: "啟用生成使用者的 Identicon " turnOffToImprovePerformance: "關閉時會提高性能。" createInviteCode: "建立邀請碼" createWithOptions: "使用選項建立" @@ -1105,6 +1105,9 @@ usedAt: "使用的日期和時間" unused: "未使用" used: "已使用" expired: "過期" +doYouAgree: "你同意嗎?" +beSureToReadThisAsItIsImportant: "重要,請務必閱讀。" +iHaveReadXCarefullyAndAgree: "我已仔細閱讀並同意「{x}」的内容。" _initialAccountSetting: accountCreated: "帳戶已建立完成!" letsStartAccountSetup: "來進行帳戶的初始設定吧。" @@ -1121,7 +1124,7 @@ _initialAccountSetting: skipAreYouSure: "要略過初始設定嗎?" laterAreYouSure: "稍後再重新進行初始設定嗎?" _serverRules: - description: "設定伺服器的簡要規則,在新的註冊之前顯示。建議的內容是使用條款的摘要。" + description: "設定在註冊頁面顯示的伺服器簡要規則。建議是服務條款的摘要。" _accountMigration: moveFrom: "從其他帳戶遷移到這個帳戶" moveFromSub: "為另一個帳戶建立別名" @@ -1135,111 +1138,111 @@ _accountMigration: startMigration: "遷移" migrationConfirm: "確定要將這個帳戶遷移至 {account} 嗎?一旦遷移就無法撤銷,也就無法以原來的狀態使用這個帳戶。\n另外,請確認在要遷移到的帳戶已經建立了一個別名。" movedAndCannotBeUndone: "帳戶已遷移。\n遷移無法撤消。" - postMigrationNote: "在遷移操作後的24小時之後解除此帳戶的追隨。此帳戶的追隨中、追隨者數量變為0。由於不會解除追隨者,你的追隨者仍然可以繼續檢視這個帳戶發布給追隨者的貼文。" + postMigrationNote: "在完成遷移的 24 小時後解除此帳戶的追隨。此帳戶的追隨中、追隨者數量變為 0。由於不會解除追隨者,你的追隨者仍然可以繼續檢視這個帳戶發布給追隨者的貼文。" movedTo: "要遷移到的帳戶:" _achievements: earnedAt: "獲得日期" _types: _notes1: - title: "just setting up my msky" + title: "歡迎!" description: "發出了第一則貼文" - flavor: "祝您的CherryPick生活愉快!" + flavor: "祝您的 CherryPick 生活愉快!" _notes10: title: "若干貼文" - description: "發表了10則貼文" + description: "發佈了十篇貼文" _notes100: title: "許多貼文" - description: "發表了100則貼文" + description: "發佈了一百篇貼文" _notes500: title: "滿滿的貼文" - description: "發表了500則貼文" + description: "發佈了五百篇貼文" _notes1000: title: "堆積如山的貼文" - description: "發表了1000則貼文" + description: "發佈了一千篇貼文" _notes5000: title: "滔滔不絕的貼文" - description: "發表了5000則貼文" + description: "發佈了五千篇貼文" _notes10000: title: "超級貼文" - description: "發表了10000則貼文" + description: "發佈了一萬篇貼文" _notes20000: - title: "需要更多的貼文" - description: "發表了20000則貼文" + title: "需要更多貼文" + description: "發佈了兩萬篇貼文" _notes30000: title: "貼文貼文貼文" - description: "發表了30000則貼文" + description: "發佈了三萬篇貼文" _notes40000: title: "貼文工廠" - description: "發表了40000則貼文" + description: "發佈了四萬篇貼文" _notes50000: title: "貼文星球" - description: "發表了50000則貼文" + description: "發佈了五萬篇貼文" _notes60000: title: "貼文類星體" - description: "發表了60000則貼文" + description: "發佈了六萬篇貼文" _notes70000: title: "貼文黑洞" - description: "發表了70000則貼文" + description: "發佈了七萬篇貼文" _notes80000: title: "貼文銀河" - description: "發表了80000則貼文" + description: "發佈了八萬篇貼文" _notes90000: title: "貼文宇宙" - description: "發表了90000則貼文" + description: "發佈了九萬篇貼文" _notes100000: title: "ALL YOUR NOTE ARE BELONG TO US" - description: "發表了100,000則貼文" + description: "發佈了十萬篇貼文" flavor: "有這麼多東西要寫嗎?" _login3: title: "初學者Ⅰ" - description: "總登入天數為3天" - flavor: "從今天開始,我就是Misskist" + description: "總登入天數為三天" + flavor: "從今天開始,我就是 Misskist" _login7: title: "初學者ⅠⅠ" - description: "總登入天數為7天" + description: "總登入天數為七天" flavor: "您開始習慣了嗎?" _login15: title: "初學者ⅠⅠⅠ" - description: "總登入天數為15天" + description: "總登入天數為十五天" _login30: title: "Misskist Ⅰ" - description: "總登入天數為30天" + description: "總登入天數為三十天" _login60: title: "Misskist ⅠⅠ" - description: "總登入天數為60天" + description: "總登入天數為六十天" _login100: title: "Misskist ⅠⅠⅠ" - description: "總登入天數為100天" - flavor: "辣個 Misskist 用戶" + description: "總登入天數為一百天" + flavor: "凶暴的 Misskist" _login200: title: "普通Ⅰ" - description: "總登入天數為200天" + description: "總登入天數為兩百天" _login300: - title: "普通IⅠ" - description: "總登入天數為300天" + title: "普通ⅠⅠ" + description: "總登入天數為三百天" _login400: - title: "普通IIⅠ" - description: "總登入天數為400天" + title: "普通ⅠⅠⅠ" + description: "總登入天數為四百天" _login500: title: "老兵Ⅰ" - description: "總登入天數為500天" + description: "總登入天數為五百天" flavor: "諸君,我喜歡貼文" _login600: title: "老兵ⅠⅠ" - description: "總登入天數為600天" + description: "總登入天數為六百天" _login700: title: "老兵ⅠⅠⅠ" - description: "總登入天數為700天" + description: "總登入天數為七百天" _login800: title: "貼文大師Ⅰ" - description: "總登入天數為800天" + description: "總登入天數為八百天" _login900: title: "貼文大師ⅠⅠ" - description: "總登入天數為900天" + description: "總登入天數為九百天" _login1000: title: "貼文大師ⅠⅠⅠ" - description: "總登入天數為1,000天" - flavor: "感謝您使用CherryPick!" + description: "總登入天數為一千天" + flavor: "感謝您使用 CherryPick!" _noteClipped1: title: "忍不住要收進摘錄裡" description: "第一次將貼文收進摘錄" @@ -1266,7 +1269,7 @@ _achievements: title: "朋友很多" description: "追隨超過50人了" _following100: - title: "100位朋友" + title: "一百位朋友" description: "追隨超過100人了" _following300: title: "朋友過多" @@ -1288,20 +1291,20 @@ _achievements: description: "追隨者超過300人了" _followers500: title: "基地台" - description: "超過500名追隨者了" + description: "超過五百名追隨者了" _followers1000: title: "影響者" - description: "超過1000名追隨者了" + description: "超過一千名追隨者了" _collectAchievements30: title: "成就收藏家" - description: "獲得30個以上的成就" + description: "獲得三十個以上的成就" _viewAchievements3min: title: "喜愛成就" - description: "看成就列表要花3分鐘以上" - _iLoveCherryPick: + description: "看成就列表要花三分鐘以上" + _iLoveMisskey: title: "I Love CherryPick" - description: "發布「I ❤ #CherryPick」" - flavor: "感謝您使用CherryPick! by 開發團隊" + description: "發佈「I ❤ #CherryPick」" + flavor: "感謝您使用 CherryPick!by 開發團隊" _foundTreasure: title: "尋寶" description: "發現了隱藏的寶藏" @@ -1424,7 +1427,7 @@ _role: pinMax: "置頂貼文的最大數量" antennaMax: "可建立的天線數量" wordMuteMax: "靜音文字的最大字數" - webhookMax: "可建立的Webhook數量" + webhookMax: "可建立的 Webhook 數量" clipMax: "可建立的摘錄數量" noteEachClipsMax: "摘錄內貼文的最大數量" userListMax: "可建立的使用者清單數量" @@ -1442,21 +1445,21 @@ _role: followersMoreThanOrEq: "追隨者人數在~以上" followingLessThanOrEq: "追隨人數在~以下" followingMoreThanOrEq: "追隨人數在~以上" - notesLessThanOrEq: "發布數在~以下" - notesMoreThanOrEq: "發布數在~以上" - and: "~和~" + notesLessThanOrEq: "貼文數在~以下" + notesMoreThanOrEq: "貼文數在~以上" + and: "~及~" or: "~或~" not: "~否" _sensitiveMediaDetection: description: "您可以使用機器學習自動檢測敏感媒體並將其用於審查。 伺服器的負荷會稍微增加。" sensitivity: "檢測敏感度" sensitivityDescription: "敏感度低時,誤檢測(偽陽性)會減少。敏感度高時,漏檢(偽陰性)會減少。" - setSensitiveFlagAutomatically: "設定 NSFW 旗標" + setSensitiveFlagAutomatically: "設定 NSFW 標籤" setSensitiveFlagAutomaticallyDescription: "即使將此設定關閉,判定結果也會保留在內部。" analyzeVideos: "啟用影片分析" analyzeVideosDescription: "除了靜止影像以外,也分析影片。伺服器的負荷會稍微增加。" _emailUnavailable: - used: "已經在使用中" + used: "已被使用" format: "格式無效" disposable: "不是永久可用的地址" mx: "郵件伺服器不正確" @@ -1468,11 +1471,11 @@ _ffVisibility: _signup: almostThere: "即將完成" emailAddressInfo: "請輸入您所使用的電子郵件地址。電子郵件地址不會被公開。" - emailSent: "已將確認郵件發送至您輸入的電子郵件地址 ({email})。請開啟電子郵件中的連結以完成帳戶創建。" + emailSent: "已發送確認郵件至您輸入的電子郵件地址({email})。請開啟電子郵件中的連結完成註冊。" _accountDelete: accountDelete: "刪除帳戶" - mayTakeTime: "刪除帳戶的處理負荷較大,如果帳戶產生的內容數量上傳的檔案數量較多的話,就需要花费一段時間才能完成。" - sendEmail: "帳戶删除完成後,將向註冊地電子郵件地址發送通知。" + mayTakeTime: "刪除帳戶的處理負荷較大,如果帳戶發佈的內容以及上傳的檔案數量較多,則需要一段時間才能完成。" + sendEmail: "帳戶刪除完成後,將向其電子郵件地址發送通知。" requestAccountDelete: "刪除帳戶請求" started: "已開始刪除作業。" inProgress: "正在刪除" @@ -1488,8 +1491,8 @@ _forgotPassword: _gallery: my: "我的貼文" liked: "喜歡的貼文" - like: "讚" - unlike: "收回喜歡" + like: "讚好" + unlike: "收回讚好" _email: _follow: title: "您有新的追隨者" @@ -1497,7 +1500,7 @@ _email: title: "收到追隨請求" _plugin: install: "安裝外掛組件" - installWarn: "請不要安裝來源不明的外掛組件。" + installWarn: "請不要安裝來源不明的外掛。" manage: "管理外掛" _preferencesBackups: list: "已備份的設定檔" @@ -1507,7 +1510,7 @@ _preferencesBackups: save: "覆蓋存檔" inputName: "輸入備份檔名稱" cannotSave: "無法儲存" - nameAlreadyExists: "備份檔名稱「{name}」已經存在。請指定不同的名稱。" + nameAlreadyExists: "備份檔名稱「{name}」已經存在。請填寫其他名稱。" applyConfirm: "將備份檔「{name}」套用在現在的裝置嗎?現在的裝置設定將會消失。" saveConfirm: "要覆蓋存檔{name}嗎?" deleteConfirm: "要刪除{name}嗎?" @@ -1528,14 +1531,14 @@ _aboutMisskey: contributors: "主要貢獻者" allContributors: "全體貢獻人員" source: "原始碼" - translation: "翻譯Misskey" - donate: "贊助Misskey" + translation: "翻譯 Misskey" + donate: "贊助 Misskey" morePatrons: "還有許許多多幫助我們的其他人,非常感謝你們。 🥰" patrons: "贊助者" _displayOfSensitiveMedia: - respect: "隱藏設定為敏感的媒體" - ignore: "不隱藏設定為敏感的媒體" - force: "隱藏所有媒體" + respect: "隱藏被標記為敏感的多媒體內容" + ignore: "不隱藏被標記為敏感的多媒體內容" + force: "隱藏所有多媒體內容" _mfm: cheatSheet: "MFM代碼小抄" intro: "MFM是Misskey專用的標記語言,可以在Misskey中的各個位置使用。 您可以這裏看到MFM可用語法列表。" @@ -1629,17 +1632,17 @@ _menuDisplay: hide: "隱藏" _wordMute: muteWords: "加入靜音文字" - muteWordsDescription: "用空格分隔指定AND,用換行分隔指定OR。" - muteWordsDescription2: "將關鍵字用斜線括起來表示正規表達式。" - softDescription: "隱藏時間軸中指定條件的貼文。" - hardDescription: "具有指定條件的貼文將不添加到時間軸。 即使您更改條件,未被添加的貼文也會被排除在外。" + muteWordsDescription: "空格代表「以及」(AND),換行代表「或者」(OR)。" + muteWordsDescription2: "用斜線包圍關鍵字代表正規表達式。" + softDescription: "隱藏時間軸中符合特定條件的貼文。" + hardDescription: "符合特定條件的貼文將不會新增至時間軸。 即使您更改條件,未被新增的貼文也會被排除在外。" soft: "軟性靜音" hard: "硬性靜音" mutedNotes: "已靜音的貼文" _instanceMute: instanceMuteDescription: "包括對被靜音實例上的用戶的回覆,被設定的實例上所有貼文及轉發都會被靜音。" - instanceMuteDescription2: "設定時以換行進行分隔" - title: "被設定的實例,貼文將被隱藏。" + instanceMuteDescription2: "換行以分隔" + title: "將隱藏被設定的實例貼文。" heading: "將實例靜音" _theme: explore: "取得佈景主題" @@ -1664,13 +1667,13 @@ _theme: func: "函数" funcKind: "功能類型" argument: "參數" - basedProp: "要基於的屬性的名稱 " + basedProp: "基於的屬性名稱 " alpha: "透明度" darken: "暗度" lighten: "亮度" - inputConstantName: "請輸入常數的名稱" + inputConstantName: "請輸入常數名稱" importInfo: "您可以在此貼上主題代碼,將其匯入編輯器中" - deleteConstantConfirm: "確定要删除常數{const}嗎?" + deleteConstantConfirm: "確定要刪除常數{const}嗎?" keys: accent: "重點色彩" bg: "背景" @@ -1678,14 +1681,14 @@ _theme: focus: "聚焦" indicator: "指標" panel: "面板" - shadow: "陰影" + shadow: "影子" header: "標題" navBg: "側邊欄的背景 " navFg: "側邊欄的文字" - navHoverFg: "側邊欄文字(懸停) " - navActive: "側邊欄文本 (活動)" + navHoverFg: "側邊欄文字(懸浮) " + navActive: "側邊欄文字(活動)" navIndicator: "側邊欄指示符" - link: "鏈接" + link: "連結" hashtag: "標籤" mention: "提到" mentionMe: "提到了我" @@ -1693,15 +1696,15 @@ _theme: modalBg: "對話框背景" divider: "分割線" scrollbarHandle: "捲動條" - scrollbarHandleHover: "捲動條 (漂浮)" + scrollbarHandleHover: "捲動條(懸浮)" dateLabelFg: "日期標籤文字" infoBg: "資訊背景" infoFg: "資訊內容" infoWarnBg: "警告背景" - infoWarnFg: "警告字元" + infoWarnFg: "警告文字" cwBg: "CW 按鈕背景" - cwFg: "CW 按鈕文本" - cwHoverBg: "CW 按鈕背景 (漂浮)" + cwFg: "CW 按鈕文字" + cwHoverBg: "CW 按鈕背景(懸浮)" toastBg: "通知背景" toastFg: "通知文本" buttonBg: "按鈕背景" @@ -1710,11 +1713,11 @@ _theme: listItemHoverBg: "列表物品背景 (漂浮)" driveFolderBg: "雲端硬碟文件夾背景" wallpaperOverlay: "壁紙覆蓋層" - badge: "獎章" + badge: "徽章" messageBg: "私訊背景" - accentDarken: "強調色(偏暗)" - accentLighten: "強調色(明亮)" - fgHighlighted: "高亮顯示文本" + accentDarken: "強調色(黑暗)" + accentLighten: "強調色(明亮)" + fgHighlighted: "突顯文字" _sfx: note: "貼文" noteMy: "我的貼文" @@ -1730,7 +1733,7 @@ _ago: minutesAgo: "{n}分鐘前" hoursAgo: "{n}小時前" daysAgo: "{n}天前" - weeksAgo: "{n}周前" + weeksAgo: "{n}週前" monthsAgo: "{n}個月前" yearsAgo: "{n}年前" invalid: "未發現" @@ -1740,33 +1743,33 @@ _time: hour: "小時" day: "日" _timelineTutorial: - title: "CherryPick的使用方法" - step1_1: "這個畫面是「時間軸」。發布到{name}的「貼文」會按照時間順序顯示。" - step1_2: "時間軸有多種類型,例如在「首頁時間軸」中流動的是您追蹤的人的貼文;而在「本地時間軸」流動的是{name}全體的貼文。" - step2_1: "試試看,發布個貼文吧!按畫面上鉛筆圖示的按鈕開啟表格。" - step2_2: "初次貼文的內容,建議包括自我介紹以及「開始使用{name}」。" + title: "CherryPick 的使用方法" + step1_1: "這個畫面是「時間軸」。發佈到{name}的「貼文」會按照時間順序顯示。" + step1_2: "時間軸有多種類型,例如「首頁時間軸」是您追蹤帳戶的貼文、「本地時間軸」是{name}內所有帳戶的貼文。" + step2_1: "不如現在就嘗試發文吧!按鉛筆圖示的按鈕開啟發文頁面。" + step2_2: "您可以在第一篇貼文裡寫自我介紹,或是「我來到 {name} 了」之類的話。" step3_1: "貼文發出去了嗎?" - step3_2: "如果你的貼文出現在時間軸上,就代表發文成功。" + step3_2: "如果您的貼文出現在時間軸上,就代表發文成功。" step4_1: "可以對貼文標記「反應」。" - step4_2: "點擊貼文的「+」圖示,即可選擇喜好的表情符號來標記反應。" + step4_2: "點擊貼文的「+」圖示,即可選擇表情符號來反應。" _2fa: - alreadyRegistered: "此設備已經被註冊過了" + alreadyRegistered: "此裝置已被註冊過了" registerTOTP: "開始設定驗證應用程式" passwordToTOTP: "請輸入密碼" - step1: "首先,在您的設備上安裝二步驗證程式,例如{a}或{b}。" - step2: "然後,掃描螢幕上的QR code。" - step2Click: "點擊QR code,可以使用設備上安裝的驗證應用程式或金鑰環進行註冊。" - step2Url: "在桌面版應用中,請輸入以下的URL:" + step1: "首先,在您的裝置上安裝驗證程式,例如 {a} 或 {b}。" + step2: "然後,掃描螢幕上的 QR 碼。" + step2Click: "您可以點擊 QR 碼,以使用裝置上的驗證應用程式或金鑰環註冊。" + step2Url: "請在桌面版應用程式中輸入以下的 URL:" step3Title: "輸入驗證碼" - step3: "輸入您的App提供的權杖以完成設定。" + step3: "輸入應用程式所提供的權杖以完成設定。" step4: "從現在開始,任何登入操作都將要求您提供權杖。" securityKeyNotSupported: "您的瀏覽器不支援安全金鑰。" - registerTOTPBeforeKey: "要註冊安全金鑰・Passkey,請先設定驗證應用程式。" - securityKeyInfo: "您可以設定使用支援FIDO2的硬體安全鎖、終端設備的指纹認證或者PIN碼來登入。" - chromePasskeyNotSupported: "目前不支援Chrome的Passkey。" - registerSecurityKey: "註冊安全金鑰・Passkey" + registerTOTPBeforeKey: "如要註冊安全金鑰或 Passkey,請先設定驗證應用程式。" + securityKeyInfo: "您可以設定使用支援 FIDO2 的硬體安全鎖、終端設備的指紋認證,或者 PIN 碼來登入。" + chromePasskeyNotSupported: "目前不支援 Chrome 的 Passkey。" + registerSecurityKey: "註冊安全金鑰或 Passkey" securityKeyName: "輸入金鑰名稱" - tapSecurityKey: "按照瀏覽器的說明操作,註冊安全金鑰和Passkey。" + tapSecurityKey: "按照瀏覽器的說明註冊安全金鑰或 Passkey。" removeKey: "刪除安全金鑰" removeKeyConfirm: "要刪除{name}嗎?" whyTOTPOnlyRenew: "如果註冊了安全金鑰,則無法解除驗證應用程式的設定。" @@ -1784,9 +1787,9 @@ _permissions: "read:favorites": "瀏覽我的最愛" "write:favorites": "編輯我的最愛列表" "read:following": "查看追隨中的用戶資訊" - "write:following": "追隨/解除追隨" + "write:following": "追隨/解除追隨" "read:messaging": "顯示訊息" - "write:messaging": "撰寫或刪除私人訊息" + "write:messaging": "撰寫或刪除訊息" "read:mutes": "顯示已靜音列表" "write:mutes": "編輯已靜音列表" "write:notes": "撰寫或刪除貼文" @@ -1840,12 +1843,12 @@ _widgets: calendar: "行事曆" trends: "發燒貼文" clock: "時鐘" - rss: "RSS閱讀器" - rssTicker: "RSS跑馬燈" + rss: "RSS 閱讀器" + rssTicker: "RSS 跑馬燈" activity: "動態" photos: "照片" digitalClock: "電子時鐘" - unixClock: "UNIX時間" + unixClock: "UNIX 時間" federation: "站台聯邦" instanceCloud: "實例雲" postForm: "發佈窗口" @@ -1853,8 +1856,8 @@ _widgets: button: "按鈕" onlineUsers: "線上的用戶" jobQueue: "佇列" - serverMetric: "服務器指標 " - aiscript: "AiScript控制台" + serverMetric: "伺服器指標 " + aiscript: "AiScript 控制台" aiscriptApp: "AiScript App" aichan: "小藍" userList: "使用者列表" @@ -1864,33 +1867,33 @@ _widgets: _cw: hide: "隱藏" show: "瀏覽更多" - chars: "{count}字元" + chars: "{count} 個字元" files: "{count} 個檔案" _poll: noOnlyOneChoice: "至少需要兩個選項。" - choiceN: "選擇{n}" + choiceN: "選擇 {n}" noMore: "沒辦法再添加選項了" canMultipleVote: "可以多次投票" expiration: "期限" infinite: "無期限" at: "結束時間" - after: "進度指定 " + after: "指定時效" deadlineDate: "截止日期" deadlineTime: "小時" duration: "時長" - votesCount: "{n}票" - totalVotes: "一共{n}票" + votesCount: "{n} 票" + totalVotes: "合共 {n} 票" vote: "投票" showResult: "顯示結果" voted: "已投票" closed: "已結束" - remainingDays: "{d}天{h}小時後結束" - remainingHours: "{h}小時{m}分後結束" - remainingMinutes: "{m}分{s}秒後結束" - remainingSeconds: "{s}秒後截止" + remainingDays: "{d} 天 {h} 小時後結束" + remainingHours: "{h} 小時 {m} 分後結束" + remainingMinutes: "{m} 分 {s} 秒後結束" + remainingSeconds: "{s} 秒後截止" _visibility: public: "公開" - publicDescription: "發布給所有用戶 " + publicDescription: "發佈給所有帳戶" home: "首頁" homeDescription: "僅發布至首頁的時間軸" followers: "追隨者" @@ -1904,12 +1907,12 @@ _postForm: quotePlaceholder: "引用此貼文..." channelPlaceholder: "發佈到頻道" _placeholders: - a: "今天過得如何?" - b: "有什麼新鮮事嗎?" + a: "今天過得如何?" + b: "有什麼新鮮事嗎?" c: "有什麼新鮮想法嗎?" - d: "想要發布些什麼嗎?" - e: "寫些什麼吧..." - f: "期待你發佈的內容..." + d: "想要發佈些什麼嗎?" + e: "寫些什麼吧……" + f: "靜待發文……" _profile: name: "名稱" username: "使用者名稱" @@ -1934,29 +1937,29 @@ _exportOrImport: _charts: federation: "站台聯邦" apRequest: "請求" - usersIncDec: "使用者増減" + usersIncDec: "使用者增減" usersTotal: "使用者合共" activeUsers: "活躍使用者" notesIncDec: "貼文増減" localNotesIncDec: "本地貼文増減" remoteNotesIncDec: "遠端貼文數目增减" notesTotal: "貼文合共" - filesIncDec: "檔案増減" - filesTotal: "累計檔案" - storageUsageIncDec: "儲存空間的増減" - storageUsageTotal: "已使用的儲存空間合共" + filesIncDec: "檔案增減" + filesTotal: "檔案總數" + storageUsageIncDec: "儲存空間增減" + storageUsageTotal: "儲存空間用量" _instanceCharts: requests: "請求" - users: "使用者増減" - usersTotal: "總計使用者" - notes: "貼文増減" + users: "使用者增減" + usersTotal: "使用者總數" + notes: "貼文增減" notesTotal: "累計貼文" - ff: "追隨/追隨者的増減" - ffTotal: "追隨/追隨者累計" - cacheSize: "增加或減少快取用量" - cacheSizeTotal: "快取大小總計" - files: "檔案數量的増減" - filesTotal: "檔案數量總計" + ff: "追隨/追隨者增減" + ffTotal: "追隨/追隨者總數" + cacheSize: "快取用量增減" + cacheSizeTotal: "快取用量總數" + files: "檔案總數增減" + filesTotal: "檔案總數累計" _timelines: home: "首頁" local: "本地" @@ -1964,16 +1967,16 @@ _timelines: social: "社交" global: "公開" _play: - new: "新增Play" - edit: "編輯Play" - created: "已新增Play" - updated: "已更新Play" - deleted: "已刪除Play" + new: "新增 Play" + edit: "編輯 Play" + created: "已新增Play " + updated: "已更新Play " + deleted: "已刪除 Play" pageSetting: "Play設定" - editThisPage: "編輯這個Play" + editThisPage: "編輯此 Play" viewSource: "檢視原始碼" - my: "自己的Play" - liked: "按了讚的Play" + my: "自己的 Play" + liked: "按讚的 Play" featured: "人氣" title: "標題" script: "腳本" @@ -1986,16 +1989,16 @@ _pages: updated: "頁面已更新" deleted: "頁面已被刪除" pageSetting: "頁面設定" - nameAlreadyExists: "指定的頁面URL已經存在" - invalidNameTitle: "指定的頁面URL無效" + nameAlreadyExists: "該頁面 URL 已存在" + invalidNameTitle: "無效的頁面 URL" invalidNameText: "請確定是否為非空白" editThisPage: "編輯此頁面" viewSource: "檢視原始碼" viewPage: "顯示頁面" - like: "喜歡" - unlike: "收回喜歡" + like: "讚好" + unlike: "收回讚好" my: "我的頁面" - liked: "已喜歡的頁面" + liked: "已讚好的頁面" featured: "人氣" inspector: "面板檢查" contents: "內容" @@ -2017,7 +2020,7 @@ _pages: inputBlocks: "輸入" specialBlocks: "特殊" blocks: - text: "字串" + text: "文字" textarea: "字串區域" section: "區段" image: "圖片" @@ -2062,7 +2065,7 @@ _notification: achievementEarned: "獲得成就" app: "應用程式通知" _actions: - followBack: "回關" + followBack: "追隨回去" reply: "回覆" renote: "轉發" _deck: @@ -2079,9 +2082,10 @@ _deck: profile: "個人檔案" newProfile: "新建個人檔案" deleteProfile: "刪除個人檔案" - introduction: "組合欄位來製作屬於自己的介面吧!" - introduction2: "您可以隨時透過按畫面右方的 + 來添加欄位。" - widgetsIntroduction: "請從欄位的選單中,選擇「編輯小工具」來添加小工具" + introduction: "組合多個欄位,製作屬於自己的介面吧!" + introduction2: "您可以隨時按畫面右方的「+」新增欄位。" + widgetsIntroduction: "請從欄位選單中選擇「編輯小工具」新增小工具。" + useSimpleUiForNonRootPages: "用簡易 UI 顯示非根頁面" _columns: main: "主列" widgets: "小工具" @@ -2094,24 +2098,24 @@ _deck: direct: "指定使用者" roleTimeline: "角色時間軸" _dialog: - charactersExceeded: "已超過最大字數!現在 {current} / 限制 {max}" - charactersBelow: "低於最少字數!現在 {current} / 限制 {max}" + charactersExceeded: "您的貼文太長了!現時字數 {current}/限制字數 {max}" + charactersBelow: "您的貼文太短了!現時字數 {current}/限制字數 {min}" _disabledTimeline: - title: "停用的時間軸" - description: "目前的角色無法使用這個時間軸。" + title: "時間軸已停用" + description: "目前角色無法使用這個時間軸。" _drivecleaner: - orderBySizeDesc: "檔案由大到小" - orderByCreatedAtAsc: "依照加入的日期順序" + orderBySizeDesc: "按大小降序排列" + orderByCreatedAtAsc: "按新增日期降序排列" _webhookSettings: createWebhook: "建立 Webhook" name: "名稱" - secret: "秘密" - events: "什麼時候運行Webhook" + secret: "密鑰" + events: "何時運行 Webhook" active: "已啟用" _events: follow: "當你追隨時" followed: "當被追隨時" - note: "當發布貼文時" + note: "當發佈貼文時" reply: "當收到回覆時" renote: "當被轉發時" reaction: "當獲得反應時" diff --git a/package.json b/package.json index d7b39f8391..f68acc660d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cherrypick", - "version": "13.14.0-beta.5", + "version": "13.14.0-beta.7", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/backend/package.json b/packages/backend/package.json index 622d2191fc..784bc0f896 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -57,35 +57,34 @@ "@aws-sdk/client-s3": "3.367.0", "@aws-sdk/lib-storage": "3.367.0", "@aws-sdk/node-http-handler": "3.360.0", - "@bull-board/api": "5.6.0", - "@bull-board/fastify": "5.6.0", - "@bull-board/ui": "5.6.0", + "@bull-board/api": "5.6.1", + "@bull-board/fastify": "5.6.1", + "@bull-board/ui": "5.6.1", "@discordapp/twemoji": "14.1.2", "@fastify/accepts": "4.2.0", "@fastify/cookie": "8.3.0", "@fastify/cors": "8.3.0", "@fastify/http-proxy": "9.2.1", - "@fastify/multipart": "7.7.0", + "@fastify/multipart": "7.7.1", "@fastify/static": "6.10.2", "@fastify/view": "8.0.0", "@google-cloud/logging": "^10.5.0", "@google-cloud/translate": "^7.2.1", - "@nestjs/common": "10.0.5", - "@nestjs/core": "10.0.5", - "@nestjs/testing": "10.0.5", + "@nestjs/common": "10.1.0", + "@nestjs/core": "10.1.0", + "@nestjs/testing": "10.1.0", "@peertube/http-signature": "1.7.0", "@sinonjs/fake-timers": "10.3.0", "@swc/cli": "0.1.62", - "@swc/core": "1.3.69", + "@swc/core": "1.3.70", "@vitalets/google-translate-api": "9.2.0", "accepts": "1.3.8", "ajv": "8.12.0", "archiver": "5.3.1", "async-mutex": "^0.4.0", - "autwh": "0.1.0", "bcryptjs": "2.4.3", "blurhash": "2.0.5", - "bullmq": "4.3.0", + "bullmq": "4.4.0", "cacheable-lookup": "7.0.0", "cbor": "9.0.0", "chalk": "5.3.0", @@ -98,8 +97,7 @@ "content-disposition": "0.5.4", "date-fns": "2.30.0", "deep-email-validator": "0.1.21", - "escape-regexp": "0.0.1", - "fastify": "4.19.2", + "fastify": "4.20.0", "feed": "4.2.2", "file-type": "18.5.0", "fluent-ffmpeg": "2.1.2", @@ -142,7 +140,6 @@ "rename": "1.0.4", "rss-parser": "3.13.0", "rxjs": "7.8.1", - "s-age": "1.1.2", "sanitize-html": "2.11.0", "semver": "7.5.4", "sharp": "0.32.3", @@ -176,7 +173,6 @@ "@types/cbor": "6.0.0", "@types/color-convert": "2.0.0", "@types/content-disposition": "0.5.5", - "@types/escape-regexp": "0.0.1", "@types/fluent-ffmpeg": "2.1.21", "@types/jest": "29.5.3", "@types/js-yaml": "4.0.5", @@ -195,7 +191,6 @@ "@types/qrcode": "1.5.1", "@types/random-seed": "0.3.3", "@types/ratelimiter": "3.4.4", - "@types/redis": "4.0.11", "@types/rename": "1.0.4", "@types/sanitize-html": "2.9.0", "@types/semver": "7.5.0", @@ -206,7 +201,6 @@ "@types/unzipper": "0.10.6", "@types/vary": "1.1.0", "@types/web-push": "3.3.2", - "@types/websocket": "1.0.5", "@types/ws": "8.5.5", "@typescript-eslint/eslint-plugin": "5.61.0", "@typescript-eslint/parser": "5.61.0", diff --git a/packages/backend/src/core/AccountMoveService.ts b/packages/backend/src/core/AccountMoveService.ts index 69d83b13b0..111fcfd734 100644 --- a/packages/backend/src/core/AccountMoveService.ts +++ b/packages/backend/src/core/AccountMoveService.ts @@ -4,10 +4,9 @@ import { IsNull, In, MoreThan, Not } from 'typeorm'; import { bindThis } from '@/decorators.js'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; -import type { LocalUser, RemoteUser } from '@/models/entities/User.js'; +import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js'; import type { BlockingsRepository, FollowingsRepository, InstancesRepository, Muting, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/index.js'; import type { RelationshipJobData, ThinUser } from '@/queue/types.js'; -import type { User } from '@/models/entities/User.js'; import { IdService } from '@/core/IdService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; diff --git a/packages/backend/src/core/FetchInstanceMetadataService.ts b/packages/backend/src/core/FetchInstanceMetadataService.ts index 9e8d17442f..88706f1a48 100644 --- a/packages/backend/src/core/FetchInstanceMetadataService.ts +++ b/packages/backend/src/core/FetchInstanceMetadataService.ts @@ -2,6 +2,7 @@ import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; import { JSDOM } from 'jsdom'; import tinycolor from 'tinycolor2'; +import * as Redis from 'ioredis'; import type { Instance } from '@/models/entities/Instance.js'; import type Logger from '@/logger.js'; import { DI } from '@/di-symbols.js'; @@ -10,7 +11,6 @@ import { HttpRequestService } from '@/core/HttpRequestService.js'; import { bindThis } from '@/decorators.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import type { DOMWindow } from 'jsdom'; -import * as Redis from 'ioredis'; type NodeInfo = { openRegistrations?: unknown; diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index a1d9ea496c..59bab0436b 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -597,7 +597,7 @@ export class NoteCreateService implements OnApplicationShutdown { where: { userId: data.reply.userId, threadId: data.reply.threadId ?? data.reply.id, - } + }, }); if (!isThreadMuted) { diff --git a/packages/backend/src/core/RemoteUserResolveService.ts b/packages/backend/src/core/RemoteUserResolveService.ts index 952d244823..e19a245e18 100644 --- a/packages/backend/src/core/RemoteUserResolveService.ts +++ b/packages/backend/src/core/RemoteUserResolveService.ts @@ -8,8 +8,9 @@ import type { LocalUser, RemoteUser } from '@/models/entities/User.js'; import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { UtilityService } from '@/core/UtilityService.js'; -import { WebfingerService } from '@/core/WebfingerService.js'; +import { ILink, WebfingerService } from '@/core/WebfingerService.js'; import { RemoteLoggerService } from '@/core/RemoteLoggerService.js'; +import { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js'; import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js'; import { bindThis } from '@/decorators.js'; @@ -27,6 +28,7 @@ export class RemoteUserResolveService { private utilityService: UtilityService, private webfingerService: WebfingerService, private remoteLoggerService: RemoteLoggerService, + private apDbResolverService: ApDbResolverService, private apPersonService: ApPersonService, ) { this.logger = this.remoteLoggerService.logger.createSubLogger('resolve-user'); @@ -67,6 +69,22 @@ export class RemoteUserResolveService { if (user == null) { const self = await this.resolveSelf(acctLower); + if (self.href.startsWith(this.config.url)) { + const local = this.apDbResolverService.parseUri(self.href); + if (local.local && local.type === 'users') { + // the LR points to local + return (await this.apDbResolverService + .getUserFromApId(self.href) + .then((u) => { + if (u == null) { + throw new Error('local user not found'); + } else { + return u; + } + })) as LocalUser; + } + } + this.logger.succ(`return new remote user: ${chalk.magenta(acctLower)}`); return await this.apPersonService.createPerson(self.href); } @@ -119,7 +137,7 @@ export class RemoteUserResolveService { } @bindThis - private async resolveSelf(acctLower: string) { + private async resolveSelf(acctLower: string): Promise { this.logger.info(`WebFinger for ${chalk.yellow(acctLower)}`); const finger = await this.webfingerService.webfinger(acctLower).catch(err => { this.logger.error(`Failed to WebFinger for ${chalk.yellow(acctLower)}: ${ err.statusCode ?? err.message }`); diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index c2f6746ac6..c28ba6ef24 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -224,14 +224,19 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getUserRoles(userId: User['id']) { + public async getUserAssigns(userId: User['id']) { const now = Date.now(); 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); + return assigns; + } + + @bindThis + public async getUserRoles(userId: User['id']) { const roles = await this.rolesCache.fetch(() => this.rolesRepository.findBy({})); - const assignedRoles = roles.filter(r => assignedRoleIds.includes(r.id)); + 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)); return [...assignedRoles, ...matchedCondRoles]; diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index 4d7bfeaf23..44269d3b8a 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -1,5 +1,6 @@ import { Inject, Injectable, OnModuleInit, forwardRef } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; +import { IsNull } from 'typeorm'; import type { LocalUser, PartialLocalUser, PartialRemoteUser, RemoteUser, User } from '@/models/entities/User.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; import { QueueService } from '@/core/QueueService.js'; @@ -21,9 +22,8 @@ import { UserBlockingService } from '@/core/UserBlockingService.js'; import { MetaService } from '@/core/MetaService.js'; import { CacheService } from '@/core/CacheService.js'; import type { Config } from '@/config.js'; -import Logger from '../logger.js'; -import { IsNull } from 'typeorm'; import { AccountMoveService } from '@/core/AccountMoveService.js'; +import Logger from '../logger.js'; const logger = new Logger('following/create'); @@ -322,7 +322,7 @@ export class UserFollowingService implements OnModuleInit { where: { followerId: follower.id, followeeId: followee.id, - } + }, }); if (following === null || !following.follower || !following.followee) { @@ -412,8 +412,8 @@ export class UserFollowingService implements OnModuleInit { followerId: user.id, followee: { movedToUri: IsNull(), - } - } + }, + }, }); const nonMovedFollowers = await this.followingsRepository.count({ relations: { @@ -423,8 +423,8 @@ export class UserFollowingService implements OnModuleInit { followeeId: user.id, follower: { movedToUri: IsNull(), - } - } + }, + }, }); await this.usersRepository.update( { id: user.id }, @@ -646,7 +646,7 @@ export class UserFollowingService implements OnModuleInit { where: { followeeId: followee.id, followerId: follower.id, - } + }, }); if (!following || !following.followee || !following.follower) return; diff --git a/packages/backend/src/core/VideoProcessingService.ts b/packages/backend/src/core/VideoProcessingService.ts index 89681f3372..06f832ab09 100644 --- a/packages/backend/src/core/VideoProcessingService.ts +++ b/packages/backend/src/core/VideoProcessingService.ts @@ -52,7 +52,7 @@ export class VideoProcessingService { query({ thumbnail: '1', url, - }) + }), ); } } diff --git a/packages/backend/src/core/WebfingerService.ts b/packages/backend/src/core/WebfingerService.ts index ac9a6f5bd8..ae715853b1 100644 --- a/packages/backend/src/core/WebfingerService.ts +++ b/packages/backend/src/core/WebfingerService.ts @@ -6,12 +6,12 @@ import { query as urlQuery } from '@/misc/prelude/url.js'; import { HttpRequestService } from '@/core/HttpRequestService.js'; import { bindThis } from '@/decorators.js'; -type ILink = { +export type ILink = { href: string; rel?: string; }; -type IWebFinger = { +export type IWebFinger = { links: ILink[]; subject: string; }; diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index e89ee4632c..8fc083719d 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -220,6 +220,23 @@ export class ApPersonService implements OnModuleInit { return null; } + private async resolveAvatarAndBanner(user: RemoteUser, icon: any, image: any): Promise> { + const [avatar, banner] = await Promise.all([icon, image].map(img => { + if (img == null) return null; + if (user == null) throw new Error('failed to create user: user is null'); + return this.apImageService.resolveImage(user, img).catch(() => null); + })); + + return { + avatarId: avatar?.id ?? null, + bannerId: banner?.id ?? null, + avatarUrl: avatar ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null, + bannerUrl: banner ? this.driveFileEntityService.getPublicUrl(banner) : null, + avatarBlurhash: avatar?.blurhash ?? null, + bannerBlurhash: banner?.blurhash ?? null, + }; + } + /** * Personを作成します。 */ @@ -259,6 +276,16 @@ export class ApPersonService implements OnModuleInit { // Create user let user: RemoteUser | null = null; + + //#region カスタム絵文字取得 + const emojis = await this.apNoteService.extractEmojis(person.tag ?? [], host) + .then(_emojis => _emojis.map(emoji => emoji.name)) + .catch(err => { + this.logger.error(`error occured while fetching user emojis`, { stack: err }); + return []; + }); + //#endregion + try { // Start transaction await this.db.transaction(async transactionalEntityManager => { @@ -285,6 +312,7 @@ export class ApPersonService implements OnModuleInit { tags, isBot, isCat: (person as any).isCat === true, + emojis, })) as RemoteUser; await transactionalEntityManager.save(new UserProfile({ @@ -321,6 +349,9 @@ export class ApPersonService implements OnModuleInit { if (user == null) throw new Error('failed to create user: user is null'); + // Register to the cache + this.cacheService.uriPersonCache.set(user.uri, user); + // Register host this.federatedInstanceService.fetch(host).then(async i => { this.instancesRepository.increment({ id: i.id }, 'usersCount', 1); @@ -336,45 +367,16 @@ export class ApPersonService implements OnModuleInit { this.hashtagService.updateUsertags(user, tags); //#region アバターとヘッダー画像をフェッチ - const [avatar, banner] = await Promise.all([person.icon, person.image].map(img => { - if (img == null) return null; - if (user == null) throw new Error('failed to create user: user is null'); - return this.apImageService.resolveImage(user, img).catch(() => null); - })); + try { + const updates = await this.resolveAvatarAndBanner(user, person.icon, person.image); + await this.usersRepository.update(user.id, updates); + user = { ...user, ...updates }; - const avatarId = avatar?.id ?? null; - const bannerId = banner?.id ?? null; - const avatarUrl = avatar ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null; - const bannerUrl = banner ? this.driveFileEntityService.getPublicUrl(banner) : null; - const avatarBlurhash = avatar?.blurhash ?? null; - const bannerBlurhash = banner?.blurhash ?? null; - - await this.usersRepository.update(user.id, { - avatarId, - bannerId, - avatarUrl, - bannerUrl, - avatarBlurhash, - bannerBlurhash, - }); - - user.avatarId = avatarId; - user.bannerId = bannerId; - user.avatarUrl = avatarUrl; - user.bannerUrl = bannerUrl; - user.avatarBlurhash = avatarBlurhash; - user.bannerBlurhash = bannerBlurhash; - //#endregion - - //#region カスタム絵文字取得 - const emojis = await this.apNoteService.extractEmojis(person.tag ?? [], host).catch(err => { - this.logger.info(`extractEmojis: ${err}`); - return []; - }); - - const emojiNames = emojis.map(emoji => emoji.name); - - await this.usersRepository.update(user.id, { emojis: emojiNames }); + // Register to the cache + this.cacheService.uriPersonCache.set(user.uri, user); + } catch (err) { + this.logger.error('error occured while fetching user avatar/banner', { stack: err }); + } //#endregion await this.updateFeatured(user.id, resolver).catch(err => this.logger.error(err)); @@ -400,7 +402,7 @@ export class ApPersonService implements OnModuleInit { if (uri.startsWith(`${this.config.url}/`)) return; //#region このサーバーに既に登録されているか - const exist = await this.usersRepository.findOneBy({ uri }) as RemoteUser | null; + const exist = await this.fetchPerson(uri) as RemoteUser | null; if (exist === null) return; //#endregion @@ -413,12 +415,6 @@ export class ApPersonService implements OnModuleInit { this.logger.info(`Updating the Person: ${person.id}`); - // アバターとヘッダー画像をフェッチ - const [avatar, banner] = await Promise.all([person.icon, person.image].map(img => { - if (img == null) return null; - return this.apImageService.resolveImage(exist, img).catch(() => null); - })); - // カスタム絵文字取得 const emojis = await this.apNoteService.extractEmojis(person.tag ?? [], exist.host).catch(e => { this.logger.info(`extractEmojis: ${e}`); @@ -454,6 +450,7 @@ export class ApPersonService implements OnModuleInit { movedToUri: person.movedTo ?? null, alsoKnownAs: person.alsoKnownAs ?? null, isExplorable: person.discoverable, + ...(await this.resolveAvatarAndBanner(exist, person.icon, person.image).catch(() => ({}))), } as Partial & Pick; const moving = ((): boolean => { @@ -476,18 +473,6 @@ export class ApPersonService implements OnModuleInit { if (moving) updates.movedAt = new Date(); - if (avatar) { - updates.avatarId = avatar.id; - updates.avatarUrl = this.driveFileEntityService.getPublicUrl(avatar, 'avatar'); - updates.avatarBlurhash = avatar.blurhash; - } - - if (banner) { - updates.bannerId = banner.id; - updates.bannerUrl = this.driveFileEntityService.getPublicUrl(banner); - updates.bannerBlurhash = banner.blurhash; - } - // Update user await this.usersRepository.update(exist.id, updates); diff --git a/packages/backend/src/core/entities/AbuseUserReportEntityService.ts b/packages/backend/src/core/entities/AbuseUserReportEntityService.ts index 7f8240b8b2..94ae1856b9 100644 --- a/packages/backend/src/core/entities/AbuseUserReportEntityService.ts +++ b/packages/backend/src/core/entities/AbuseUserReportEntityService.ts @@ -3,8 +3,8 @@ import { DI } from '@/di-symbols.js'; import type { AbuseUserReportsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js'; -import { UserEntityService } from './UserEntityService.js'; import { bindThis } from '@/decorators.js'; +import { UserEntityService } from './UserEntityService.js'; @Injectable() export class AbuseUserReportEntityService { diff --git a/packages/backend/src/core/entities/AuthSessionEntityService.ts b/packages/backend/src/core/entities/AuthSessionEntityService.ts index b7edc8494e..a1874c63ab 100644 --- a/packages/backend/src/core/entities/AuthSessionEntityService.ts +++ b/packages/backend/src/core/entities/AuthSessionEntityService.ts @@ -4,8 +4,8 @@ import type { AuthSessionsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { AuthSession } from '@/models/entities/AuthSession.js'; import type { User } from '@/models/entities/User.js'; -import { AppEntityService } from './AppEntityService.js'; import { bindThis } from '@/decorators.js'; +import { AppEntityService } from './AppEntityService.js'; @Injectable() export class AuthSessionEntityService { diff --git a/packages/backend/src/core/entities/ChannelEntityService.ts b/packages/backend/src/core/entities/ChannelEntityService.ts index d24657260f..de99ce72c4 100644 --- a/packages/backend/src/core/entities/ChannelEntityService.ts +++ b/packages/backend/src/core/entities/ChannelEntityService.ts @@ -50,7 +50,7 @@ export class ChannelEntityService { const hasUnreadNote = meId ? await this.noteUnreadsRepository.exist({ where: { noteChannelId: channel.id, - userId: meId + userId: meId, }, }) : undefined; diff --git a/packages/backend/src/core/entities/FollowRequestEntityService.ts b/packages/backend/src/core/entities/FollowRequestEntityService.ts index c2edc6a13a..6f6f4be412 100644 --- a/packages/backend/src/core/entities/FollowRequestEntityService.ts +++ b/packages/backend/src/core/entities/FollowRequestEntityService.ts @@ -4,8 +4,8 @@ import type { FollowRequestsRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; import type { User } from '@/models/entities/User.js'; import type { FollowRequest } from '@/models/entities/FollowRequest.js'; -import { UserEntityService } from './UserEntityService.js'; import { bindThis } from '@/decorators.js'; +import { UserEntityService } from './UserEntityService.js'; @Injectable() export class FollowRequestEntityService { diff --git a/packages/backend/src/core/entities/GalleryLikeEntityService.ts b/packages/backend/src/core/entities/GalleryLikeEntityService.ts index db46045db3..73c264da94 100644 --- a/packages/backend/src/core/entities/GalleryLikeEntityService.ts +++ b/packages/backend/src/core/entities/GalleryLikeEntityService.ts @@ -3,8 +3,8 @@ import { DI } from '@/di-symbols.js'; import type { GalleryLikesRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; import type { GalleryLike } from '@/models/entities/GalleryLike.js'; -import { GalleryPostEntityService } from './GalleryPostEntityService.js'; import { bindThis } from '@/decorators.js'; +import { GalleryPostEntityService } from './GalleryPostEntityService.js'; @Injectable() export class GalleryLikeEntityService { diff --git a/packages/backend/src/core/entities/ModerationLogEntityService.ts b/packages/backend/src/core/entities/ModerationLogEntityService.ts index 7058e38af9..59815d2639 100644 --- a/packages/backend/src/core/entities/ModerationLogEntityService.ts +++ b/packages/backend/src/core/entities/ModerationLogEntityService.ts @@ -4,8 +4,8 @@ import type { ModerationLogsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { } from '@/models/entities/Blocking.js'; import type { ModerationLog } from '@/models/entities/ModerationLog.js'; -import { UserEntityService } from './UserEntityService.js'; import { bindThis } from '@/decorators.js'; +import { UserEntityService } from './UserEntityService.js'; @Injectable() export class ModerationLogEntityService { diff --git a/packages/backend/src/core/entities/NoteFavoriteEntityService.ts b/packages/backend/src/core/entities/NoteFavoriteEntityService.ts index 8a7727b4cd..badb8fb816 100644 --- a/packages/backend/src/core/entities/NoteFavoriteEntityService.ts +++ b/packages/backend/src/core/entities/NoteFavoriteEntityService.ts @@ -4,8 +4,8 @@ import type { NoteFavoritesRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; import type { User } from '@/models/entities/User.js'; import type { NoteFavorite } from '@/models/entities/NoteFavorite.js'; -import { NoteEntityService } from './NoteEntityService.js'; import { bindThis } from '@/decorators.js'; +import { NoteEntityService } from './NoteEntityService.js'; @Injectable() export class NoteFavoriteEntityService { diff --git a/packages/backend/src/core/entities/PageLikeEntityService.ts b/packages/backend/src/core/entities/PageLikeEntityService.ts index 3460c1e422..99465d0ea3 100644 --- a/packages/backend/src/core/entities/PageLikeEntityService.ts +++ b/packages/backend/src/core/entities/PageLikeEntityService.ts @@ -4,8 +4,8 @@ import type { PageLikesRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; import type { User } from '@/models/entities/User.js'; import type { PageLike } from '@/models/entities/PageLike.js'; -import { PageEntityService } from './PageEntityService.js'; import { bindThis } from '@/decorators.js'; +import { PageEntityService } from './PageEntityService.js'; @Injectable() export class PageLikeEntityService { diff --git a/packages/backend/src/core/entities/SigninEntityService.ts b/packages/backend/src/core/entities/SigninEntityService.ts index 51fa7543d9..a6c4407ce8 100644 --- a/packages/backend/src/core/entities/SigninEntityService.ts +++ b/packages/backend/src/core/entities/SigninEntityService.ts @@ -3,8 +3,8 @@ import { DI } from '@/di-symbols.js'; import type { SigninsRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; import type { Signin } from '@/models/entities/Signin.js'; -import { UserEntityService } from './UserEntityService.js'; import { bindThis } from '@/decorators.js'; +import { UserEntityService } from './UserEntityService.js'; @Injectable() export class SigninEntityService { diff --git a/packages/backend/src/misc/dev-null.ts b/packages/backend/src/misc/dev-null.ts index 38b9d82669..6706af5e52 100644 --- a/packages/backend/src/misc/dev-null.ts +++ b/packages/backend/src/misc/dev-null.ts @@ -1,11 +1,11 @@ -import { Writable, WritableOptions } from "node:stream"; +import { Writable, WritableOptions } from 'node:stream'; export class DevNull extends Writable implements NodeJS.WritableStream { - constructor(opts?: WritableOptions) { - super(opts); - } + constructor(opts?: WritableOptions) { + super(opts); + } - _write (chunk: any, encoding: BufferEncoding, cb: (err?: Error | null) => void) { - setImmediate(cb); - } + _write (chunk: any, encoding: BufferEncoding, cb: (err?: Error | null) => void) { + setImmediate(cb); + } } diff --git a/packages/backend/src/misc/id/ulid.ts b/packages/backend/src/misc/id/ulid.ts index e8aa752890..bfbc363cf5 100644 --- a/packages/backend/src/misc/id/ulid.ts +++ b/packages/backend/src/misc/id/ulid.ts @@ -5,10 +5,10 @@ const CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; export const ulidRegExp = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$/; export function parseUlid(id: string): { date: Date; } { - const timestamp = id.slice(0, 10); - let time = 0; - for (let i = 0; i < 10; i++) { - time = time * 32 + CHARS.indexOf(timestamp[i]); - } - return { date: new Date(time) }; + const timestamp = id.slice(0, 10); + let time = 0; + for (let i = 0; i < 10; i++) { + time = time * 32 + CHARS.indexOf(timestamp[i]); + } + return { date: new Date(time) }; } diff --git a/packages/backend/src/misc/prelude/await-all.ts b/packages/backend/src/misc/prelude/await-all.ts index b955c3a5d8..fd9832d6f8 100644 --- a/packages/backend/src/misc/prelude/await-all.ts +++ b/packages/backend/src/misc/prelude/await-all.ts @@ -10,7 +10,7 @@ export async function awaitAll(obj: Promiseable): Promise { const resolvedValues = await Promise.all(values.map(value => (!value || !value.constructor || value.constructor.name !== 'Object') ? value - : awaitAll(value) + : awaitAll(value), )); for (let i = 0; i < keys.length; i++) { diff --git a/packages/backend/src/models/index.ts b/packages/backend/src/models/index.ts index 6faf1e8f44..3c3ae3492d 100644 --- a/packages/backend/src/models/index.ts +++ b/packages/backend/src/models/index.ts @@ -54,7 +54,6 @@ import { UserGroupJoining } from '@/models/entities/UserGroupJoining.js'; import { UserIp } from '@/models/entities/UserIp.js'; import { UserKeypair } from '@/models/entities/UserKeypair.js'; import { UserList } from '@/models/entities/UserList.js'; -import { UserListFavorite } from './entities/UserListFavorite.js'; import { UserListJoining } from '@/models/entities/UserListJoining.js'; import { UserNotePining } from '@/models/entities/UserNotePining.js'; import { UserPending } from '@/models/entities/UserPending.js'; @@ -69,6 +68,7 @@ import { Role } from '@/models/entities/Role.js'; import { RoleAssignment } from '@/models/entities/RoleAssignment.js'; import { Flash } from '@/models/entities/Flash.js'; import { FlashLike } from '@/models/entities/FlashLike.js'; +import { UserListFavorite } from './entities/UserListFavorite.js'; import type { Repository } from 'typeorm'; export { diff --git a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts index 3e8969252a..95cdf5e826 100644 --- a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts +++ b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts @@ -9,10 +9,10 @@ import type { DriveFile } from '@/models/entities/DriveFile.js'; import type { Note } from '@/models/entities/Note.js'; import { EmailService } from '@/core/EmailService.js'; import { bindThis } from '@/decorators.js'; +import { SearchService } from '@/core/SearchService.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type * as Bull from 'bullmq'; import type { DbUserDeleteJobData } from '../types.js'; -import { SearchService } from "@/core/SearchService.js"; @Injectable() export class DeleteAccountProcessorService { diff --git a/packages/backend/src/queue/processors/RelationshipProcessorService.ts b/packages/backend/src/queue/processors/RelationshipProcessorService.ts index 722260d948..816c5fc5ec 100644 --- a/packages/backend/src/queue/processors/RelationshipProcessorService.ts +++ b/packages/backend/src/queue/processors/RelationshipProcessorService.ts @@ -1,16 +1,16 @@ import { Inject, Injectable } from '@nestjs/common'; -import type * as Bull from 'bullmq'; import { UserFollowingService } from '@/core/UserFollowingService.js'; import { UserBlockingService } from '@/core/UserBlockingService.js'; import { bindThis } from '@/decorators.js'; import type Logger from '@/logger.js'; -import { QueueLoggerService } from '../QueueLoggerService.js'; -import { RelationshipJobData } from '../types.js'; import type { UsersRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { LocalUser, RemoteUser } from '@/models/entities/User.js'; +import { RelationshipJobData } from '../types.js'; +import { QueueLoggerService } from '../QueueLoggerService.js'; +import type * as Bull from 'bullmq'; @Injectable() export class RelationshipProcessorService { diff --git a/packages/backend/src/server/FileServerService.ts b/packages/backend/src/server/FileServerService.ts index 98329ddffa..2547d73365 100644 --- a/packages/backend/src/server/FileServerService.ts +++ b/packages/backend/src/server/FileServerService.ts @@ -3,6 +3,8 @@ import { fileURLToPath } from 'node:url'; import { dirname } from 'node:path'; import { Inject, Injectable } from '@nestjs/common'; import rename from 'rename'; +import sharp from 'sharp'; +import { sharpBmp } from 'sharp-read-bmp'; import type { Config } from '@/config.js'; import type { DriveFile, DriveFilesRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; @@ -18,11 +20,9 @@ import { contentDisposition } from '@/misc/content-disposition.js'; import { FileInfoService } from '@/core/FileInfoService.js'; import { LoggerService } from '@/core/LoggerService.js'; import { bindThis } from '@/decorators.js'; -import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify'; import { isMimeImage } from '@/misc/is-mime-image.js'; -import sharp from 'sharp'; -import { sharpBmp } from 'sharp-read-bmp'; import { correctFilename } from '@/misc/correct-filename.js'; +import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify'; const _filename = fileURLToPath(import.meta.url); const _dirname = dirname(_filename); @@ -180,8 +180,8 @@ export class FileServerService { reply.header('Content-Disposition', contentDisposition( 'inline', - correctFilename(file.filename, image.ext) - ) + correctFilename(file.filename, image.ext), + ), ); return image.data; } @@ -278,11 +278,11 @@ export class FileServerService { }; } else { const data = (await sharpBmp(file.path, file.mime, { animated: !('static' in request.query) })) - .resize({ - height: 'emoji' in request.query ? 128 : 320, - withoutEnlargement: true, - }) - .webp(webpDefault); + .resize({ + height: 'emoji' in request.query ? 128 : 320, + withoutEnlargement: true, + }) + .webp(webpDefault); image = { data, @@ -355,8 +355,8 @@ export class FileServerService { reply.header('Content-Disposition', contentDisposition( 'inline', - correctFilename(file.filename, image.ext) - ) + correctFilename(file.filename, image.ext), + ), ); return image.data; } catch (e) { diff --git a/packages/backend/src/server/WellKnownServerService.ts b/packages/backend/src/server/WellKnownServerService.ts index 9bf8deb221..aabe631fb2 100644 --- a/packages/backend/src/server/WellKnownServerService.ts +++ b/packages/backend/src/server/WellKnownServerService.ts @@ -1,18 +1,18 @@ import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import vary from 'vary'; +import fastifyAccepts from '@fastify/accepts'; import { DI } from '@/di-symbols.js'; import type { UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import { escapeAttribute, escapeValue } from '@/misc/prelude/xml.js'; import type { User } from '@/models/entities/User.js'; import * as Acct from '@/misc/acct.js'; -import { NodeinfoServerService } from './NodeinfoServerService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; -import type { FindOptionsWhere } from 'typeorm'; import { bindThis } from '@/decorators.js'; +import { NodeinfoServerService } from './NodeinfoServerService.js'; +import type { FindOptionsWhere } from 'typeorm'; import type { FastifyInstance, FastifyPluginOptions } from 'fastify'; -import fastifyAccepts from '@fastify/accepts'; @Injectable() export class WellKnownServerService { diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts index d681bf8e21..7b215cea79 100644 --- a/packages/backend/src/server/api/SignupApiService.ts +++ b/packages/backend/src/server/api/SignupApiService.ts @@ -13,9 +13,9 @@ import { EmailService } from '@/core/EmailService.js'; import { LocalUser } from '@/models/entities/User.js'; import { FastifyReplyError } from '@/misc/fastify-reply-error.js'; import { bindThis } from '@/decorators.js'; +import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js'; import { SigninService } from './SigninService.js'; import type { FastifyRequest, FastifyReply } from 'fastify'; -import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js'; @Injectable() export class SignupApiService { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts index 80acdd1910..29b20fab86 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts @@ -91,7 +91,7 @@ export default class extends Endpoint { if (queryarry) { emojis = emojis.filter(emoji => - queryarry.includes(`:${emoji.name}:`) + queryarry.includes(`:${emoji.name}:`), ); } else { emojis = emojis.filter(emoji => diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index f49d2a0966..6f805b6b4e 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -61,6 +61,7 @@ export default class extends Endpoint { const signins = await this.signinsRepository.findBy({ userId: user.id }); + const roleAssigns = await this.roleService.getUserAssigns(user.id); const roles = await this.roleService.getUserRoles(user.id); return { @@ -85,6 +86,11 @@ export default class extends Endpoint { signins, policies: await this.roleService.getUserPolicies(user.id), roles: await this.roleEntityService.packMany(roles, me), + roleAssigns: roleAssigns.map(a => ({ + createdAt: a.createdAt.toISOString(), + expiresAt: a.expiresAt ? a.expiresAt.toISOString() : null, + roleId: a.roleId, + })), }; }); } diff --git a/packages/backend/src/server/api/endpoints/blocking/delete.ts b/packages/backend/src/server/api/endpoints/blocking/delete.ts index 38913ae932..ad3d9f22b3 100644 --- a/packages/backend/src/server/api/endpoints/blocking/delete.ts +++ b/packages/backend/src/server/api/endpoints/blocking/delete.ts @@ -5,8 +5,8 @@ import type { UsersRepository, BlockingsRepository } from '@/models/index.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserBlockingService } from '@/core/UserBlockingService.js'; import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; export const meta = { tags: ['account'], @@ -88,7 +88,7 @@ export default class extends Endpoint { where: { blockerId: blocker.id, blockeeId: blockee.id, - } + }, }); if (!exist) { diff --git a/packages/backend/src/server/api/endpoints/clips/remove-note.ts b/packages/backend/src/server/api/endpoints/clips/remove-note.ts index 50c5d758bd..d0ef795819 100644 --- a/packages/backend/src/server/api/endpoints/clips/remove-note.ts +++ b/packages/backend/src/server/api/endpoints/clips/remove-note.ts @@ -2,8 +2,8 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; export const meta = { tags: ['account', 'notes', 'clips'], diff --git a/packages/backend/src/server/api/endpoints/following/delete.ts b/packages/backend/src/server/api/endpoints/following/delete.ts index 570c4eb81e..77ef263169 100644 --- a/packages/backend/src/server/api/endpoints/following/delete.ts +++ b/packages/backend/src/server/api/endpoints/following/delete.ts @@ -5,8 +5,8 @@ import type { UsersRepository, FollowingsRepository } from '@/models/index.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js'; import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; export const meta = { tags: ['following', 'users'], diff --git a/packages/backend/src/server/api/endpoints/following/invalidate.ts b/packages/backend/src/server/api/endpoints/following/invalidate.ts index 22304cacda..0e57f6328f 100644 --- a/packages/backend/src/server/api/endpoints/following/invalidate.ts +++ b/packages/backend/src/server/api/endpoints/following/invalidate.ts @@ -5,8 +5,8 @@ import type { UsersRepository, FollowingsRepository } from '@/models/index.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js'; import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; export const meta = { tags: ['following', 'users'], diff --git a/packages/backend/src/server/api/endpoints/i.ts b/packages/backend/src/server/api/endpoints/i.ts index 24ad2ba756..cdc72e3368 100644 --- a/packages/backend/src/server/api/endpoints/i.ts +++ b/packages/backend/src/server/api/endpoints/i.ts @@ -23,7 +23,7 @@ export const meta = { id: 'e5b3b9f0-2b8f-4b9f-9c1f-8c5c1b2e1b1a', kind: 'permission', }, - } + }, } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index 01075d9bb5..a92f25e89a 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -267,7 +267,7 @@ export default class extends Endpoint { super(meta, paramDef, async (ps, me) => { const instance = await this.metaService.fetch(true); - const ads = await this.adsRepository.createQueryBuilder("ads") + 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 => { diff --git a/packages/backend/src/server/api/endpoints/notes/conversation.ts b/packages/backend/src/server/api/endpoints/notes/conversation.ts index 5ecf7cf458..10f43b04c0 100644 --- a/packages/backend/src/server/api/endpoints/notes/conversation.ts +++ b/packages/backend/src/server/api/endpoints/notes/conversation.ts @@ -4,8 +4,8 @@ import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; export const meta = { tags: ['notes'], diff --git a/packages/backend/src/server/api/endpoints/notes/show.ts b/packages/backend/src/server/api/endpoints/notes/show.ts index 6b1b84a18e..2aec7d64dd 100644 --- a/packages/backend/src/server/api/endpoints/notes/show.ts +++ b/packages/backend/src/server/api/endpoints/notes/show.ts @@ -3,8 +3,8 @@ import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; export const meta = { tags: ['notes'], diff --git a/packages/backend/src/server/api/endpoints/promo/read.ts b/packages/backend/src/server/api/endpoints/promo/read.ts index 9baa930f5f..a76866fe14 100644 --- a/packages/backend/src/server/api/endpoints/promo/read.ts +++ b/packages/backend/src/server/api/endpoints/promo/read.ts @@ -3,8 +3,8 @@ import type { PromoReadsRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; export const meta = { tags: ['notes'], 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 9f08c8148d..b82c4bf49d 100644 --- a/packages/backend/src/server/api/endpoints/sw/update-registration.ts +++ b/packages/backend/src/server/api/endpoints/sw/update-registration.ts @@ -35,7 +35,7 @@ export const meta = { code: 'NO_SUCH_REGISTRATION', id: ' b09d8066-8064-5613-efb6-0e963b21d012', }, - } + }, } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts index 09f6acde9c..b4c1e2ec87 100644 --- a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts +++ b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts @@ -5,8 +5,8 @@ import type { NotesRepository, UsersRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; export const meta = { tags: ['users'], diff --git a/packages/backend/src/server/api/stream/channels/role-timeline.ts b/packages/backend/src/server/api/stream/channels/role-timeline.ts index 4f36832e42..6218fada97 100644 --- a/packages/backend/src/server/api/stream/channels/role-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/role-timeline.ts @@ -3,9 +3,9 @@ import { isUserRelated } from '@/misc/is-user-related.js'; import type { Packed } from '@/misc/json-schema.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { bindThis } from '@/decorators.js'; +import { RoleService } from '@/core/RoleService.js'; import Channel from '../channel.js'; import { StreamMessages } from '../types.js'; -import { RoleService } from '@/core/RoleService.js'; class RoleTimelineChannel extends Channel { public readonly chName = 'roleTimeline'; diff --git a/packages/frontend/package.json b/packages/frontend/package.json index a454559754..9fa0a86d29 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -19,10 +19,10 @@ "@rollup/plugin-json": "6.0.0", "@rollup/plugin-replace": "5.0.2", "@rollup/pluginutils": "5.0.2", - "@syuilo/aiscript": "0.13.3", + "@syuilo/aiscript": "0.15.0", "@tabler/icons-webfont": "2.25.0", "@vitejs/plugin-vue": "4.2.3", - "@vue-macros/reactivity-transform": "0.3.14", + "@vue-macros/reactivity-transform": "0.3.15", "@vue/compiler-sfc": "3.3.4", "astring": "1.8.6", "autosize": "6.0.1", @@ -55,7 +55,7 @@ "prismjs": "1.29.0", "punycode": "2.3.0", "querystring": "0.2.1", - "rollup": "3.26.2", + "rollup": "3.26.3", "s-age": "1.1.2", "sanitize-html": "2.11.0", "sass": "1.63.6", diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 0b9317e327..53d55254e5 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -300,6 +300,17 @@ useTooltip(renoteButton, async (showing) => { }, {}, 'closed'); }); +type Visibility = 'public' | 'home' | 'followers' | 'specified'; + +// defaultStore.state.visibilityがstringなためstringも受け付けている +function smallerVisibility(a: Visibility | string, b: Visibility | string): Visibility { + if (a === 'specified' || b === 'specified') return 'specified'; + if (a === 'followers' || b === 'followers') return 'followers'; + if (a === 'home' || b === 'home') return 'home'; + // if (a === 'public' || b === 'public') + return 'public'; +} + async function renote() { pleaseLogin(); showMovedDialog(); @@ -335,7 +346,12 @@ async function renote() { os.popup(MkRippleEffect, { x, y }, {}, 'end'); } + const configuredVisibility = defaultStore.state.rememberNoteVisibility ? defaultStore.state.visibility : defaultStore.state.defaultNoteVisibility; + const localOnly = defaultStore.state.rememberNoteVisibility ? defaultStore.state.localOnly : defaultStore.state.defaultNoteLocalOnly; + os.api('notes/create', { + localOnly, + visibility: smallerVisibility(appearNote.visibility, configuredVisibility), renoteId: appearNote.id, }).then(() => { os.noteToast(i18n.ts.renoted); diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index fb1f17c443..dd720ddbde 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -972,6 +972,7 @@ defineExpose({ flex-wrap: nowrap; gap: 4px; padding: 8px 12px; + margin-bottom: -10px; } .headerLeft { diff --git a/packages/frontend/src/components/MkSignupDialog.rules.vue b/packages/frontend/src/components/MkSignupDialog.rules.vue index b6ffba6cc7..de5195ab4f 100644 --- a/packages/frontend/src/components/MkSignupDialog.rules.vue +++ b/packages/frontend/src/components/MkSignupDialog.rules.vue @@ -9,7 +9,10 @@ {{ i18n.ts.invitationRequiredToRegister }} -
{{ i18n.ts.pleaseConfirmBelowBeforeSignup }}
+
+
{{ i18n.ts.pleaseConfirmBelowBeforeSignup }}
+
{{ i18n.ts.beSureToReadThisAsItIsImportant }}
+
@@ -19,7 +22,7 @@
  • - {{ i18n.ts.agree }} + {{ i18n.ts.agree }}
    @@ -28,7 +31,7 @@ {{ i18n.ts.termsOfService }} - {{ i18n.ts.agree }} + {{ i18n.ts.agree }} @@ -37,7 +40,7 @@ {{ i18n.ts.basicNotesBeforeCreateAccount }} - {{ i18n.ts.agree }} + {{ i18n.ts.agree }}
    {{ i18n.ts.pleaseAgreeAllToContinue }}
    @@ -52,13 +55,14 @@ diff --git a/packages/frontend/src/components/MkUserPopup.vue b/packages/frontend/src/components/MkUserPopup.vue index 197eb03757..240afbdfaa 100644 --- a/packages/frontend/src/components/MkUserPopup.vue +++ b/packages/frontend/src/components/MkUserPopup.vue @@ -30,26 +30,14 @@
    {{ i18n.ts.notes }}
    {{ number(user.notesCount) }}
    - - +
    +
    {{ i18n.ts.following }}
    +
    {{ number(user.followingCount) }}
    +
    +
    +
    {{ i18n.ts.followers }}
    +
    {{ number(user.followersCount) }}
    +
    @@ -73,7 +61,7 @@ import number from '@/filters/number'; import { i18n } from '@/i18n'; import { defaultStore } from '@/store'; import { $i } from '@/account'; -import { isFfVisibility } from '@/scripts/is-ff-visibility'; +import { isFfVisibleForMe } from '@/scripts/isFfVisibleForMe'; const props = defineProps<{ showing: boolean; @@ -88,9 +76,6 @@ const emit = defineEmits<{ }>(); const zIndex = os.claimZIndex('middle'); - -const animation = $ref(defaultStore.state.animation); - let user = $ref(null); let top = $ref(0); let left = $ref(0); @@ -259,37 +244,4 @@ onMounted(() => { top: 8px; right: 8px; } - -.keyWiggleArea { - display: block; - margin: 0 auto; -} - -@keyframes keywiggle { - 0% { transform: translate(-3px,-1px) rotate(-8deg); } - 5% { transform: translateY(-1px) rotate(-10deg); } - 10% { transform: translate(1px,-3px) rotate(0); } - 15% { transform: translate(1px,1px) rotate(11deg); } - 20% { transform: translate(-2px,1px) rotate(1deg); } - 25% { transform: translate(-1px,-2px) rotate(-2deg); } - 30% { transform: translate(-1px,2px) rotate(-3deg); } - 35% { transform: translate(2px,1px) rotate(6deg); } - 40% { transform: translate(-2px,-3px) rotate(-9deg); } - 45% { transform: translateY(-1px) rotate(-12deg); } - 50% { transform: translate(1px,2px) rotate(10deg); } - 55% { transform: translateY(-3px) rotate(8deg); } - 60% { transform: translate(1px,-1px) rotate(8deg); } - 65% { transform: translateY(-1px) rotate(-7deg); } - 70% { transform: translate(-1px,-3px) rotate(6deg); } - 75% { transform: translateY(-2px) rotate(4deg); } - 80% { transform: translate(-2px,-1px) rotate(3deg); } - 85% { transform: translate(1px,-3px) rotate(-10deg); } - 90% { transform: translate(1px) rotate(3deg); } - 95% { transform: translate(-2px) rotate(-3deg); } - to { transform: translate(2px,1px) rotate(2deg); } -} - -.animation:hover { - animation: keywiggle 1s; -} diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue index 6323497bfb..fbe3500e96 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -275,6 +275,9 @@ const patronsWithIconWithMisskey = [{ }, { name: 'カガミ', icon: 'https://misskey-hub.net/patrons/226ea3a4617749548580ec2d9a263e24.jpg', +}, { + name: 'フランギ・シュウ', + icon: 'https://misskey-hub.net/patrons/3016d37e35f3430b90420176c912d304.jpg', }]; const patronsWithCherryPick = [ @@ -376,6 +379,7 @@ const patronsWithMisskey = [ 'ぷーざ', '越貝鯛丸', 'Nick / pprmint.', + 'kino3277', ]; let isKokonect = false; diff --git a/packages/frontend/src/pages/admin/roles.role.vue b/packages/frontend/src/pages/admin/roles.role.vue index 6cbe7ae658..789c9da277 100644 --- a/packages/frontend/src/pages/admin/roles.role.vue +++ b/packages/frontend/src/pages/admin/roles.role.vue @@ -40,7 +40,7 @@
    Assigned:
    -
    Period: {{ item.expiresAt.toLocaleString() }}
    +
    Period: {{ new Date(item.expiresAt).toLocaleString() }}
    Period: {{ i18n.ts.indefinitely }}
    diff --git a/packages/frontend/src/pages/flash/flash-edit.vue b/packages/frontend/src/pages/flash/flash-edit.vue index 6a16cd1c4a..86aaad8f53 100644 --- a/packages/frontend/src/pages/flash/flash-edit.vue +++ b/packages/frontend/src/pages/flash/flash-edit.vue @@ -33,7 +33,7 @@ import MkTextarea from '@/components/MkTextarea.vue'; import MkInput from '@/components/MkInput.vue'; import { useRouter } from '@/router'; -const PRESET_DEFAULT = `/// @ 0.13.3 +const PRESET_DEFAULT = `/// @ 0.15.0 var name = "" @@ -51,7 +51,7 @@ Ui:render([ ]) `; -const PRESET_OMIKUJI = `/// @ 0.13.3 +const PRESET_OMIKUJI = `/// @ 0.15.0 // ユーザーごとに日替わりのおみくじのプリセット // 選択肢 @@ -94,7 +94,7 @@ Ui:render([ ]) `; -const PRESET_SHUFFLE = `/// @ 0.13.3 +const PRESET_SHUFFLE = `/// @ 0.15.0 // 巻き戻し可能な文字シャッフルのプリセット let string = "ペペロンチーノ" @@ -173,7 +173,7 @@ var cursor = 0 do() `; -const PRESET_QUIZ = `/// @ 0.13.3 +const PRESET_QUIZ = `/// @ 0.15.0 let title = '地理クイズ' let qas = [{ @@ -286,7 +286,7 @@ qaEls.push(Ui:C:container({ Ui:render(qaEls) `; -const PRESET_TIMELINE = `/// @ 0.13.3 +const PRESET_TIMELINE = `/// @ 0.15.0 // APIリクエストを行いローカルタイムラインを表示するプリセット @fetch() { diff --git a/packages/frontend/src/pages/gallery/post.vue b/packages/frontend/src/pages/gallery/post.vue index dfa6c0bac0..39b2c2c90b 100644 --- a/packages/frontend/src/pages/gallery/post.vue +++ b/packages/frontend/src/pages/gallery/post.vue @@ -236,6 +236,7 @@ definePageMetadata(computed(() => post ? { border-top: solid 0.5px var(--divider); display: flex; align-items: center; + flex-wrap: wrap; > .avatar { width: 52px; diff --git a/packages/frontend/src/pages/settings/mute-block.vue b/packages/frontend/src/pages/settings/mute-block.vue index e0785ab9fe..e1f3c6bed9 100644 --- a/packages/frontend/src/pages/settings/mute-block.vue +++ b/packages/frontend/src/pages/settings/mute-block.vue @@ -55,7 +55,7 @@
    Muted at:
    -
    Period: {{ item.expiresAt.toLocaleString() }}
    +
    Period: {{ new Date(item.expiresAt).toLocaleString() }}
    Period: {{ i18n.ts.indefinitely }}
    @@ -85,7 +85,7 @@
    Blocked at:
    -
    Period: {{ item.expiresAt.toLocaleString() }}
    +
    Period: {{ new Date(item.expiresAt).toLocaleString() }}
    Period: {{ i18n.ts.indefinitely }}
    diff --git a/packages/frontend/src/pages/user-info.vue b/packages/frontend/src/pages/user-info.vue index 50539ab5b1..57c394481f 100644 --- a/packages/frontend/src/pages/user-info.vue +++ b/packages/frontend/src/pages/user-info.vue @@ -112,9 +112,17 @@ {{ i18n.ts.assign }}
    - - - +
    + + + + +
    +
    +
    Assigned:
    +
    Period: {{ new Date(info.roleAssigns.find(a => a.roleId === role.id).expiresAt).toLocaleString() }}
    +
    Period: {{ i18n.ts.indefinitely }}
    +
    @@ -220,6 +228,7 @@ const filesPagination = { userId: props.userId, })), }; +let expandedRoles = $ref([]); function createFetcher() { if (iAmModerator) { @@ -384,6 +393,14 @@ async function unassignRole(role, ev) { }], ev.currentTarget ?? ev.target); } +function toggleRoleItem(role) { + if (expandedRoles.includes(role.id)) { + expandedRoles = expandedRoles.filter(x => x !== role.id); + } else { + expandedRoles.push(role.id); + } +} + watch(() => props.userId, () => { init = createFetcher(); }, { @@ -523,11 +540,22 @@ definePageMetadata(computed(() => ({ } .roleItem { +} + +.roleItemMain { display: flex; } .role { flex: 1; + min-width: 0; + margin-right: 8px; +} + +.roleItemSub { + padding: 6px 12px; + font-size: 85%; + color: var(--fgTransparentWeak); } .roleUnassign { diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue index 08b6c77761..5ae47f47dd 100644 --- a/packages/frontend/src/pages/user/home.vue +++ b/packages/frontend/src/pages/user/home.vue @@ -117,30 +117,18 @@
    - + {{ number(user.notesCount) }} {{ i18n.ts.notes }} - - + + {{ number(user.followingCount) }} + {{ i18n.ts.following }} + + + {{ number(user.followersCount) }} + {{ i18n.ts.followers }} +
    @@ -189,7 +177,7 @@ import { dateString } from '@/filters/date'; import { confetti } from '@/scripts/confetti'; import MkNotes from '@/components/MkNotes.vue'; import { api } from '@/os'; -import { isFfVisibility } from '@/scripts/is-ff-visibility'; +import { isFfVisibleForMe } from '@/scripts/isFfVisibleForMe'; import { defaultStore } from '@/store'; import { miLocalStorage } from '@/local-storage'; import { editNickname } from '@/scripts/edit-nickname'; @@ -243,8 +231,6 @@ const age = $computed(() => { return calcAge(props.user.birthday); }); -const animation = $ref(defaultStore.state.animation); - function menu(ev) { os.popupMenu(getUserMenu(props.user, router), ev.currentTarget ?? ev.target); } @@ -424,18 +410,6 @@ onUnmounted(() => { font-weight: bold; font-size: 1.8em; text-shadow: 0 0 8px #000; - - > .nickname-button { - -webkit-backdrop-filter: var(--blur, blur(8px)); - backdrop-filter: var(--blur, blur(8px)); - background: rgba(0, 0, 0, 0.2); - color: #ccc; - font-size: 0.7em; - line-height: 1; - width: 1.8em; - height: 1.8em; - border-radius: 100%; - } } > .bottom { @@ -477,10 +451,6 @@ onUnmounted(() => { opacity: 0.8; } } - - > .nickname-button { - margin-left: 8px; - } } > .avatar { @@ -759,32 +729,4 @@ onUnmounted(() => { border-radius: var(--radius); overflow: clip; } - -@keyframes keywiggle { - 0% { transform: translate(-3px,-1px) rotate(-8deg); } - 5% { transform: translateY(-1px) rotate(-10deg); } - 10% { transform: translate(1px,-3px) rotate(0); } - 15% { transform: translate(1px,1px) rotate(11deg); } - 20% { transform: translate(-2px,1px) rotate(1deg); } - 25% { transform: translate(-1px,-2px) rotate(-2deg); } - 30% { transform: translate(-1px,2px) rotate(-3deg); } - 35% { transform: translate(2px,1px) rotate(6deg); } - 40% { transform: translate(-2px,-3px) rotate(-9deg); } - 45% { transform: translateY(-1px) rotate(-12deg); } - 50% { transform: translate(1px,2px) rotate(10deg); } - 55% { transform: translateY(-3px) rotate(8deg); } - 60% { transform: translate(1px,-1px) rotate(8deg); } - 65% { transform: translateY(-1px) rotate(-7deg); } - 70% { transform: translate(-1px,-3px) rotate(6deg); } - 75% { transform: translateY(-2px) rotate(4deg); } - 80% { transform: translate(-2px,-1px) rotate(3deg); } - 85% { transform: translate(1px,-3px) rotate(-10deg); } - 90% { transform: translate(1px) rotate(3deg); } - 95% { transform: translate(-2px) rotate(-3deg); } - to { transform: translate(2px,1px) rotate(2deg); } -} - -.animation:hover { - animation: keywiggle 1s; -} diff --git a/packages/frontend/src/scripts/is-ff-visibility.ts b/packages/frontend/src/scripts/is-ff-visibility.ts deleted file mode 100644 index bcd3e0876f..0000000000 --- a/packages/frontend/src/scripts/is-ff-visibility.ts +++ /dev/null @@ -1,30 +0,0 @@ -export function isFfVisibility(i, user):boolean { - let checkFlag:boolean; - - switch (user.ffVisibility) { - case 'private': - checkFlag = false; - break; - case 'followers': - if (!user.isFollowing) { - checkFlag = false; - break; - } - // fallthrough - default: checkFlag = true; - } - - if (!i) { - if (checkFlag) { - return true; - } - return false; - } - - //自分自身の場合は一律true - if (i.id === user.id) { - return true; - } - - return checkFlag; -} diff --git a/packages/frontend/src/scripts/isFfVisibleForMe.ts b/packages/frontend/src/scripts/isFfVisibleForMe.ts new file mode 100644 index 0000000000..ea5d4d32bc --- /dev/null +++ b/packages/frontend/src/scripts/isFfVisibleForMe.ts @@ -0,0 +1,11 @@ +import * as misskey from 'cherrypick-js'; +import { $i } from '@/account'; + +export function isFfVisibleForMe(user: misskey.entities.UserDetailed): boolean { + if ($i && $i.id === user.id) return true; + + if (user.ffVisibility === 'private') return false; + if (user.ffVisibility === 'followers' && !user.isFollowing) return false; + + return true; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 568bb48605..b769feded7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,14 +78,14 @@ importers: specifier: 3.360.0 version: 3.360.0 '@bull-board/api': - specifier: 5.6.0 - version: 5.6.0(@bull-board/ui@5.6.0) + specifier: 5.6.1 + version: 5.6.1(@bull-board/ui@5.6.1) '@bull-board/fastify': - specifier: 5.6.0 - version: 5.6.0 + specifier: 5.6.1 + version: 5.6.1 '@bull-board/ui': - specifier: 5.6.0 - version: 5.6.0 + specifier: 5.6.1 + version: 5.6.1 '@discordapp/twemoji': specifier: 14.1.2 version: 14.1.2 @@ -102,8 +102,8 @@ importers: specifier: 9.2.1 version: 9.2.1(bufferutil@4.0.7)(utf-8-validate@6.0.3) '@fastify/multipart': - specifier: 7.7.0 - version: 7.7.0 + specifier: 7.7.1 + version: 7.7.1 '@fastify/static': specifier: 6.10.2 version: 6.10.2 @@ -117,14 +117,14 @@ importers: specifier: ^7.2.1 version: 7.2.1 '@nestjs/common': - specifier: 10.0.5 - version: 10.0.5(reflect-metadata@0.1.13)(rxjs@7.8.1) + specifier: 10.1.0 + version: 10.1.0(reflect-metadata@0.1.13)(rxjs@7.8.1) '@nestjs/core': - specifier: 10.0.5 - version: 10.0.5(@nestjs/common@10.0.5)(reflect-metadata@0.1.13)(rxjs@7.8.1) + specifier: 10.1.0 + version: 10.1.0(@nestjs/common@10.1.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) '@nestjs/testing': - specifier: 10.0.5 - version: 10.0.5(@nestjs/common@10.0.5)(@nestjs/core@10.0.5) + specifier: 10.1.0 + version: 10.1.0(@nestjs/common@10.1.0)(@nestjs/core@10.1.0) '@peertube/http-signature': specifier: 1.7.0 version: 1.7.0 @@ -133,10 +133,10 @@ importers: version: 10.3.0 '@swc/cli': specifier: 0.1.62 - version: 0.1.62(@swc/core@1.3.69)(chokidar@3.5.3) + version: 0.1.62(@swc/core@1.3.70)(chokidar@3.5.3) '@swc/core': - specifier: 1.3.69 - version: 1.3.69 + specifier: 1.3.70 + version: 1.3.70 '@vitalets/google-translate-api': specifier: 9.2.0 version: 9.2.0 @@ -152,9 +152,6 @@ importers: async-mutex: specifier: ^0.4.0 version: 0.4.0 - autwh: - specifier: 0.1.0 - version: 0.1.0 bcryptjs: specifier: 2.4.3 version: 2.4.3 @@ -162,8 +159,8 @@ importers: specifier: 2.0.5 version: 2.0.5 bullmq: - specifier: 4.3.0 - version: 4.3.0 + specifier: 4.4.0 + version: 4.4.0 cacheable-lookup: specifier: 7.0.0 version: 7.0.0 @@ -200,12 +197,9 @@ importers: deep-email-validator: specifier: 0.1.21 version: 0.1.21 - escape-regexp: - specifier: 0.0.1 - version: 0.0.1 fastify: - specifier: 4.19.2 - version: 4.19.2 + specifier: 4.20.0 + version: 4.20.0 feed: specifier: 4.2.2 version: 4.2.2 @@ -332,9 +326,6 @@ importers: rxjs: specifier: 7.8.1 version: 7.8.1 - s-age: - specifier: 1.1.2 - version: 1.1.2 sanitize-html: specifier: 2.11.0 version: 2.11.0 @@ -361,7 +352,7 @@ importers: version: 7.1.0 summaly: specifier: github:misskey-dev/summaly - version: github.com/misskey-dev/summaly/77dd5654bb82280b38c1f50e51a771c33f3df503 + version: github.com/misskey-dev/summaly/089a0ad8e8c780e5c088b1c528aa95c5827cbdcc systeminformation: specifier: 5.18.7 version: 5.18.7 @@ -492,7 +483,7 @@ importers: version: 29.6.1 '@swc/jest': specifier: 0.2.26 - version: 0.2.26(@swc/core@1.3.69) + version: 0.2.26(@swc/core@1.3.70) '@types/accepts': specifier: 1.3.5 version: 1.3.5 @@ -511,9 +502,6 @@ importers: '@types/content-disposition': specifier: 0.5.5 version: 0.5.5 - '@types/escape-regexp': - specifier: 0.0.1 - version: 0.0.1 '@types/fluent-ffmpeg': specifier: 2.1.21 version: 2.1.21 @@ -568,9 +556,6 @@ importers: '@types/ratelimiter': specifier: 3.4.4 version: 3.4.4 - '@types/redis': - specifier: 4.0.11 - version: 4.0.11 '@types/rename': specifier: 1.0.4 version: 1.0.4 @@ -601,9 +586,6 @@ importers: '@types/web-push': specifier: 3.3.2 version: 3.3.2 - '@types/websocket': - specifier: 1.0.5 - version: 1.0.5 '@types/ws': specifier: 8.5.5 version: 8.5.5 @@ -639,7 +621,7 @@ importers: dependencies: '@swc/cli': specifier: 0.1.62 - version: 0.1.62(@swc/core@1.3.69)(chokidar@3.5.3) + version: 0.1.62(@swc/core@1.3.70)(chokidar@3.5.3) '@swc/core': specifier: 1.3.69 version: 1.3.69 @@ -697,19 +679,19 @@ importers: version: 14.1.2 '@rollup/plugin-alias': specifier: 5.0.0 - version: 5.0.0(rollup@3.26.2) + version: 5.0.0(rollup@3.26.3) '@rollup/plugin-json': specifier: 6.0.0 - version: 6.0.0(rollup@3.26.2) + version: 6.0.0(rollup@3.26.3) '@rollup/plugin-replace': specifier: 5.0.2 - version: 5.0.2(rollup@3.26.2) + version: 5.0.2(rollup@3.26.3) '@rollup/pluginutils': specifier: 5.0.2 - version: 5.0.2(rollup@3.26.2) + version: 5.0.2(rollup@3.26.3) '@syuilo/aiscript': - specifier: 0.13.3 - version: 0.13.3 + specifier: 0.15.0 + version: 0.15.0 '@tabler/icons-webfont': specifier: 2.25.0 version: 2.25.0 @@ -717,8 +699,8 @@ importers: specifier: 4.2.3 version: 4.2.3(vite@4.4.4)(vue@3.3.4) '@vue-macros/reactivity-transform': - specifier: 0.3.14 - version: 0.3.14(rollup@3.26.2)(vue@3.3.4) + specifier: 0.3.15 + version: 0.3.15(rollup@3.26.3)(vue@3.3.4) '@vue/compiler-sfc': specifier: 3.3.4 version: 3.3.4 @@ -816,8 +798,8 @@ importers: specifier: 0.2.1 version: 0.2.1 rollup: - specifier: 3.26.2 - version: 3.26.2 + specifier: 3.26.3 + version: 3.26.3 s-age: specifier: 1.1.2 version: 1.1.2 @@ -1052,7 +1034,7 @@ importers: version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.0.27)(@storybook/components@7.0.27)(@storybook/core-events@7.0.27)(@storybook/manager-api@7.0.27)(@storybook/preview-api@7.0.27)(@storybook/theming@7.0.27)(@storybook/types@7.0.27)(react-dom@18.2.0)(react@18.2.0) summaly: specifier: github:misskey-dev/summaly - version: github.com/misskey-dev/summaly/77dd5654bb82280b38c1f50e51a771c33f3df503 + version: github.com/misskey-dev/summaly/089a0ad8e8c780e5c088b1c528aa95c5827cbdcc vite-plugin-turbosnap: specifier: 1.0.2 version: 1.0.2 @@ -4099,29 +4081,29 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true - /@bull-board/api@5.6.0(@bull-board/ui@5.6.0): - resolution: {integrity: sha512-a2O15p5oEm+/E/0I2l2nE2NKK0dkgNNTaamu+0gGyfUxWoCS3fCGX6LLEyl3jgOz0IC3GKRnwtVgbZFzk42sGQ==} + /@bull-board/api@5.6.1(@bull-board/ui@5.6.1): + resolution: {integrity: sha512-iq+VpvCt7v2kYCtapDDmgHFyTyHiCbJkSeYbgIDtMIspXfsKxz0ZWKsqaY/VOCRE26jAX2asK17S2XSrANEU0A==} peerDependencies: - '@bull-board/ui': 5.6.0 + '@bull-board/ui': 5.6.1 dependencies: - '@bull-board/ui': 5.6.0 + '@bull-board/ui': 5.6.1 redis-info: 3.1.0 dev: false - /@bull-board/fastify@5.6.0: - resolution: {integrity: sha512-JIGSrNxRko2cc4KTcU1Pp1iROKuAZGi2aLCx87nlgjmdtK51qbBfpDCsNEEc4ZspdddBKvaTUu67/3/n+3J67w==} + /@bull-board/fastify@5.6.1: + resolution: {integrity: sha512-Gh7dWtGN13nrQ2AL+Hx+cz9hEy9IPlBYUmhP6aIpA5s1eMjQnwhAHSURt0dSaGIyp7rvU7hj1zFx4rcKHeaSXA==} dependencies: - '@bull-board/api': 5.6.0(@bull-board/ui@5.6.0) - '@bull-board/ui': 5.6.0 + '@bull-board/api': 5.6.1(@bull-board/ui@5.6.1) + '@bull-board/ui': 5.6.1 '@fastify/static': 6.10.2 '@fastify/view': 7.4.1 ejs: 3.1.8 dev: false - /@bull-board/ui@5.6.0: - resolution: {integrity: sha512-mc9T+kijDX5ZJMJCzeKPk9uLfOtcuefdDLPqWi961EiiNKfkDex+Gh41DAfcyrNjYsAkBsphvgBgcvundHPGIw==} + /@bull-board/ui@5.6.1: + resolution: {integrity: sha512-cy4fEXxOBHR5+3Ez3bfax+Cd2TUTPyuSYRyQWL0WIwd3bivn/3zov9IThcnHu1YmJ8rjmUNoMHz7JIDXwUg8zg==} dependencies: - '@bull-board/api': 5.6.0(@bull-board/ui@5.6.0) + '@bull-board/api': 5.6.1(@bull-board/ui@5.6.1) dev: false /@canvas/image-data@1.0.0: @@ -4770,8 +4752,8 @@ packages: - utf-8-validate dev: false - /@fastify/multipart@7.7.0: - resolution: {integrity: sha512-lE5v6+MVbLYmPL8yUHrvyezEOLQbZulEPL8itwGqPbNxL2pWdAN1HWEZ7f3VdwyR6wmQdOcpfZ0zdCU4BbWKzw==} + /@fastify/multipart@7.7.1: + resolution: {integrity: sha512-D2S6XH8pbQj0GxfSP10G/MaQye3UACVNUH/D4ssw3ne9pcQ4DSKqojVIGcwa5XI7pdR91gXRHSWXFx8koCzBlg==} dependencies: '@fastify/busboy': 1.1.0 '@fastify/deepmerge': 1.3.0 @@ -5508,8 +5490,8 @@ packages: tar-fs: 2.1.1 dev: true - /@nestjs/common@10.0.5(reflect-metadata@0.1.13)(rxjs@7.8.1): - resolution: {integrity: sha512-0E+SBI+SKswXbFG+Nwtnctrei5dvdFJ7b9/fQDL6KzDBtZwsglJpD86S3ooxnc7ek4vRG57oN2iLmMTjrcesMg==} + /@nestjs/common@10.1.0(reflect-metadata@0.1.13)(rxjs@7.8.1): + resolution: {integrity: sha512-3GNOuDjeAqEVt5Zjia3ZSK55Jg80hIIkq52BOzU+LkCjFgbuEhDot80lCKu05WyntAMAq5wREoDRGEGlSVxENw==} peerDependencies: class-transformer: '*' class-validator: '*' @@ -5528,8 +5510,8 @@ packages: uid: 2.0.2 dev: false - /@nestjs/core@10.0.5(@nestjs/common@10.0.5)(reflect-metadata@0.1.13)(rxjs@7.8.1): - resolution: {integrity: sha512-9A8nixBfE33TWAmmWvNoxdmHrRmHJY0oO3O4Iue0FVkawWJc0YOhSqdNs87McwvKE4InJMI7GVv01NYMEROdPA==} + /@nestjs/core@10.1.0(@nestjs/common@10.1.0)(reflect-metadata@0.1.13)(rxjs@7.8.1): + resolution: {integrity: sha512-3ogHxrRAktQZNBSV709QxhNJQPsVInZRqxAK2fV7JDnfoBMu1lM3xI7cO498iViqq5xme3o/46+AdfjW9W2E2A==} requiresBuild: true peerDependencies: '@nestjs/common': ^10.0.0 @@ -5546,7 +5528,7 @@ packages: '@nestjs/websockets': optional: true dependencies: - '@nestjs/common': 10.0.5(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.1.0(reflect-metadata@0.1.13)(rxjs@7.8.1) '@nuxtjs/opencollective': 0.3.2 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -5559,8 +5541,8 @@ packages: - encoding dev: false - /@nestjs/testing@10.0.5(@nestjs/common@10.0.5)(@nestjs/core@10.0.5): - resolution: {integrity: sha512-TQcFOxR+kIibMbYg71yajic3289/Iw7B5LliYiZ4Pz36BZvU0TRMYqpxaGAlX/Srk0BCpP99ZHoofm8dqZKmxw==} + /@nestjs/testing@10.1.0(@nestjs/common@10.1.0)(@nestjs/core@10.1.0): + resolution: {integrity: sha512-TqV/21PuU5GJ543oqLTrmQhWUiWwB7DDRcj5cknUdaOst+Kkwp0Sad3/5svcWgOB+QfFbwYlvIDeCkKJshZzPg==} peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/core': ^10.0.0 @@ -5572,8 +5554,8 @@ packages: '@nestjs/platform-express': optional: true dependencies: - '@nestjs/common': 10.0.5(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@nestjs/core': 10.0.5(@nestjs/common@10.0.5)(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/common': 10.1.0(reflect-metadata@0.1.13)(rxjs@7.8.1) + '@nestjs/core': 10.1.0(@nestjs/common@10.1.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) tslib: 2.6.0 dev: false @@ -5695,56 +5677,7 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false - /@redis/bloom@1.1.0(@redis/client@1.4.2): - resolution: {integrity: sha512-9QovlxmpRtvxVbN0UBcv8WfdSMudNZZTFqCsnBszcQXqaZb/TVe30ScgGEO7u1EAIacTPAo7/oCYjYAxiHLanQ==} - peerDependencies: - '@redis/client': ^1.0.0 - dependencies: - '@redis/client': 1.4.2 - dev: true - - /@redis/client@1.4.2: - resolution: {integrity: sha512-oUdEjE0I7JS5AyaAjkD3aOXn9NhO7XKyPyXEyrgFDu++VrVBHUPnV6dgEya9TcMuj5nIJRuCzCm8ZP+c9zCHPw==} - engines: {node: '>=14'} - dependencies: - cluster-key-slot: 1.1.1 - generic-pool: 3.9.0 - yallist: 4.0.0 - dev: true - - /@redis/graph@1.1.0(@redis/client@1.4.2): - resolution: {integrity: sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==} - peerDependencies: - '@redis/client': ^1.0.0 - dependencies: - '@redis/client': 1.4.2 - dev: true - - /@redis/json@1.0.4(@redis/client@1.4.2): - resolution: {integrity: sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==} - peerDependencies: - '@redis/client': ^1.0.0 - dependencies: - '@redis/client': 1.4.2 - dev: true - - /@redis/search@1.1.0(@redis/client@1.4.2): - resolution: {integrity: sha512-NyFZEVnxIJEybpy+YskjgOJRNsfTYqaPbK/Buv6W2kmFNaRk85JiqjJZA5QkRmWvGbyQYwoO5QfDi2wHskKrQQ==} - peerDependencies: - '@redis/client': ^1.0.0 - dependencies: - '@redis/client': 1.4.2 - dev: true - - /@redis/time-series@1.0.4(@redis/client@1.4.2): - resolution: {integrity: sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng==} - peerDependencies: - '@redis/client': ^1.0.0 - dependencies: - '@redis/client': 1.4.2 - dev: true - - /@rollup/plugin-alias@5.0.0(rollup@3.26.2): + /@rollup/plugin-alias@5.0.0(rollup@3.26.3): resolution: {integrity: sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -5753,11 +5686,11 @@ packages: rollup: optional: true dependencies: - rollup: 3.26.2 + rollup: 3.26.3 slash: 4.0.0 dev: false - /@rollup/plugin-json@6.0.0(rollup@3.26.2): + /@rollup/plugin-json@6.0.0(rollup@3.26.3): resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==} engines: {node: '>=14.0.0'} peerDependencies: @@ -5766,11 +5699,11 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2(rollup@3.26.2) - rollup: 3.26.2 + '@rollup/pluginutils': 5.0.2(rollup@3.26.3) + rollup: 3.26.3 dev: false - /@rollup/plugin-replace@5.0.2(rollup@3.26.2): + /@rollup/plugin-replace@5.0.2(rollup@3.26.3): resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -5779,9 +5712,9 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2(rollup@3.26.2) + '@rollup/pluginutils': 5.0.2(rollup@3.26.3) magic-string: 0.27.0 - rollup: 3.26.2 + rollup: 3.26.3 dev: false /@rollup/pluginutils@4.2.1: @@ -5792,7 +5725,7 @@ packages: picomatch: 2.3.1 dev: true - /@rollup/pluginutils@5.0.2(rollup@3.26.2): + /@rollup/pluginutils@5.0.2(rollup@3.26.3): resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -5804,7 +5737,7 @@ packages: '@types/estree': 1.0.1 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 3.26.2 + rollup: 3.26.3 dev: false /@rushstack/node-core-library@3.59.5(@types/node@20.4.2): @@ -6729,7 +6662,7 @@ packages: magic-string: 0.27.0 remark-external-links: 8.0.0 remark-slug: 6.1.0 - rollup: 3.26.2 + rollup: 3.26.3 typescript: 5.1.6 vite: 4.4.4(@types/node@20.4.2)(sass@1.63.6) transitivePeerDependencies: @@ -7359,7 +7292,7 @@ packages: - supports-color dev: true - /@swc/cli@0.1.62(@swc/core@1.3.69)(chokidar@3.5.3): + /@swc/cli@0.1.62(@swc/core@1.3.70)(chokidar@3.5.3): resolution: {integrity: sha512-kOFLjKY3XH1DWLfXL1/B5MizeNorHR8wHKEi92S/Zi9Md/AK17KSqR8MgyRJ6C1fhKHvbBCl8wboyKAFXStkYw==} engines: {node: '>= 12.13'} hasBin: true @@ -7371,7 +7304,7 @@ packages: optional: true dependencies: '@mole-inc/bin-wrapper': 8.0.1 - '@swc/core': 1.3.69 + '@swc/core': 1.3.70 chokidar: 3.5.3 commander: 7.2.0 fast-glob: 3.2.12 @@ -7408,6 +7341,14 @@ packages: requiresBuild: true optional: true + /@swc/core-darwin-arm64@1.3.70: + resolution: {integrity: sha512-31+mcl0dgdRHvZRjhLOK9V6B+qJ7nxDZYINr9pBlqGWxknz37Vld5KK19Kpr79r0dXUZvaaelLjCnJk9dA2PcQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + /@swc/core-darwin-x64@1.3.56: resolution: {integrity: sha512-VH5saqYFasdRXJy6RAT+MXm0+IjkMZvOkohJwUei+oA65cKJofQwrJ1jZro8yOJFYvUSI3jgNRGsdBkmo/4hMw==} engines: {node: '>=10'} @@ -7425,6 +7366,14 @@ packages: requiresBuild: true optional: true + /@swc/core-darwin-x64@1.3.70: + resolution: {integrity: sha512-GMFJ65E18zQC80t0os+TZvI+8lbRuitncWVge/RXmXbVLPRcdykP4EJ87cqzcG5Ah0z18/E0T+ixD6jHRisrYQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + /@swc/core-linux-arm-gnueabihf@1.3.56: resolution: {integrity: sha512-LWwPo6NnJkH01+ukqvkoNIOpMdw+Zundm4vBeicwyVrkP+mC3kwVfi03TUFpQUz3kRKdw/QEnxGTj+MouCPbtw==} engines: {node: '>=10'} @@ -7442,6 +7391,14 @@ packages: requiresBuild: true optional: true + /@swc/core-linux-arm-gnueabihf@1.3.70: + resolution: {integrity: sha512-wjhCwS8LCiAq2VedF1b4Bryyw68xZnfMED4pLRazAl8BaUlDFANfRBORNunxlfHQj4V3x39IaiLgCZRHMdzXBg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + /@swc/core-linux-arm64-gnu@1.3.56: resolution: {integrity: sha512-GzsUy/4egJ4cMlxbM+Ub7AMi5CKAc+pxBxrh8MUPQbyStW8jGgnQsJouTnGy0LHawtdEnsCOl6PcO6OgvktXuQ==} engines: {node: '>=10'} @@ -7459,6 +7416,14 @@ packages: requiresBuild: true optional: true + /@swc/core-linux-arm64-gnu@1.3.70: + resolution: {integrity: sha512-9D/Rx67cAOnMiexvCqARxvhj7coRajTp5HlJHuf+rfwMqI2hLhpO9/pBMQxBUAWxODO/ksQ/OF+GJRjmtWw/2A==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + /@swc/core-linux-arm64-musl@1.3.56: resolution: {integrity: sha512-9gxL09BIiAv8zY0DjfnFf19bo8+P4T9tdhzPwcm+1yPJcY5yr1+YFWLNFzz01agtOj6VlZ2/wUJTaOfdjjtc+A==} engines: {node: '>=10'} @@ -7476,6 +7441,14 @@ packages: requiresBuild: true optional: true + /@swc/core-linux-arm64-musl@1.3.70: + resolution: {integrity: sha512-gkjxBio7XD+1GlQVVyPP/qeFkLu83VhRHXaUrkNYpr5UZG9zZurBERT9nkS6Y+ouYh+Q9xmw57aIyd2KvD2zqQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + /@swc/core-linux-x64-gnu@1.3.56: resolution: {integrity: sha512-n0ORNknl50vMRkll3BDO1E4WOqY6iISlPV1ZQCRLWQ6YQ2q8/WAryBxc2OAybcGHBUFkxyACpJukeU1QZ/9tNw==} engines: {node: '>=10'} @@ -7493,6 +7466,14 @@ packages: requiresBuild: true optional: true + /@swc/core-linux-x64-gnu@1.3.70: + resolution: {integrity: sha512-/nCly+V4xfMVwfEUoLLAukxUSot/RcSzsf6GdsGTjFcrp5sZIntAjokYRytm3VT1c2TK321AfBorsi9R5w8Y7Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + /@swc/core-linux-x64-musl@1.3.56: resolution: {integrity: sha512-r+D34WLAOAlJtfw1gaVWpHRwCncU9nzW9i7w9kSw4HpWYnHJOz54jLGSEmNsrhdTCz1VK2ar+V2ktFUsrlGlDA==} engines: {node: '>=10'} @@ -7510,6 +7491,14 @@ packages: requiresBuild: true optional: true + /@swc/core-linux-x64-musl@1.3.70: + resolution: {integrity: sha512-HoOsPJbt361KGKaivAK0qIiYARkhzlxeAfvF5NlnKxkIMOZpQ46Lwj3tR0VWohKbrhS+cYKFlVuDi5XnDkx0XA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + /@swc/core-win32-arm64-msvc@1.3.56: resolution: {integrity: sha512-29Yt75Is6X24z3x8h/xZC1HnDPkPpyLH9mDQiM6Cuc0I9mVr1XSriPEUB2N/awf5IE4SA8c+3IVq1DtKWbkJIw==} engines: {node: '>=10'} @@ -7527,6 +7516,14 @@ packages: requiresBuild: true optional: true + /@swc/core-win32-arm64-msvc@1.3.70: + resolution: {integrity: sha512-hm4IBK/IaRil+aj1cWU6f0GyAdHpw/Jr5nyFYLM2c/tt7w2t5hgb8NjzM2iM84lOClrig1fG6edj2vCF1dFzNQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + /@swc/core-win32-ia32-msvc@1.3.56: resolution: {integrity: sha512-mplp0zbYDrcHtfvkniXlXdB04e2qIjz2Gq/XHKr4Rnc6xVORJjjXF91IemXKpavx2oZYJws+LNJL7UFQ8jyCdQ==} engines: {node: '>=10'} @@ -7544,6 +7541,14 @@ packages: requiresBuild: true optional: true + /@swc/core-win32-ia32-msvc@1.3.70: + resolution: {integrity: sha512-5cgKUKIT/9Fp5fCA+zIjYCQ4dSvjFYOeWGZR3QiTXGkC4bGa1Ji9SEPyeIAX0iruUnKjYaZB9RvHK2tNn7RLrQ==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + /@swc/core-win32-x64-msvc@1.3.56: resolution: {integrity: sha512-zp8MBnrw/bjdLenO/ifYzHrImSjKunqL0C2IF4LXYNRfcbYFh2NwobsVQMZ20IT0474lKRdlP8Oxdt+bHuXrzA==} engines: {node: '>=10'} @@ -7561,6 +7566,14 @@ packages: requiresBuild: true optional: true + /@swc/core-win32-x64-msvc@1.3.70: + resolution: {integrity: sha512-LE8lW46+TQBzVkn2mHBlk8DIElPIZ2dO5P8AbJiARNBAnlqQWu67l9gWM89UiZ2l33J2cI37pHzON3tKnT8f9g==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + /@swc/core@1.3.69: resolution: {integrity: sha512-Khc/DE9D5+2tYTHgAIp5DZARbs8kldWg3b0Jp6l8FQLjelcLFmlQWSwKhVZrgv4oIbgZydIp8jInsvTalMHqnQ==} engines: {node: '>=10'} @@ -7582,6 +7595,27 @@ packages: '@swc/core-win32-ia32-msvc': 1.3.69 '@swc/core-win32-x64-msvc': 1.3.69 + /@swc/core@1.3.70: + resolution: {integrity: sha512-LWVWlEDLlOD25PvA2NEz41UzdwXnlDyBiZbe69s3zM0DfCPwZXLUm79uSqH9ItsOjTrXSL5/1+XUL6C/BZwChA==} + engines: {node: '>=10'} + requiresBuild: true + peerDependencies: + '@swc/helpers': ^0.5.0 + peerDependenciesMeta: + '@swc/helpers': + optional: true + optionalDependencies: + '@swc/core-darwin-arm64': 1.3.70 + '@swc/core-darwin-x64': 1.3.70 + '@swc/core-linux-arm-gnueabihf': 1.3.70 + '@swc/core-linux-arm64-gnu': 1.3.70 + '@swc/core-linux-arm64-musl': 1.3.70 + '@swc/core-linux-x64-gnu': 1.3.70 + '@swc/core-linux-x64-musl': 1.3.70 + '@swc/core-win32-arm64-msvc': 1.3.70 + '@swc/core-win32-ia32-msvc': 1.3.70 + '@swc/core-win32-x64-msvc': 1.3.70 + /@swc/jest@0.2.26(@swc/core@1.3.69): resolution: {integrity: sha512-7lAi7q7ShTO3E5Gt1Xqf3pIhRbERxR1DUxvtVa9WKzIB+HGQ7wZP5sYx86zqnaEoKKGhmOoZ7gyW0IRu8Br5+A==} engines: {npm: '>= 7.0.0'} @@ -7593,14 +7627,25 @@ packages: jsonc-parser: 3.2.0 dev: true + /@swc/jest@0.2.26(@swc/core@1.3.70): + resolution: {integrity: sha512-7lAi7q7ShTO3E5Gt1Xqf3pIhRbERxR1DUxvtVa9WKzIB+HGQ7wZP5sYx86zqnaEoKKGhmOoZ7gyW0IRu8Br5+A==} + engines: {npm: '>= 7.0.0'} + peerDependencies: + '@swc/core': '*' + dependencies: + '@jest/create-cache-key-function': 27.5.1 + '@swc/core': 1.3.70 + jsonc-parser: 3.2.0 + dev: true + /@swc/wasm@1.2.130: resolution: {integrity: sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==} requiresBuild: true dev: false optional: true - /@syuilo/aiscript@0.13.3: - resolution: {integrity: sha512-0YFlWA+7YhyRRsp+9Nl72SoSUg5ghskthjCdLvj4qdGyLedeyanKZWJlH2A9d47Nes03UYY8CRDsMHHv64IWcg==} + /@syuilo/aiscript@0.15.0: + resolution: {integrity: sha512-vauMbqacuHufE4W7bAm5BDWlci3mWg1ZaerPNHKBMrRXDjEfvBkBGZNXKSWvi+zmhiYAbWyozPIlV6byttYpCw==} dependencies: autobind-decorator: 2.4.0 seedrandom: 3.0.5 @@ -8307,12 +8352,6 @@ packages: '@types/node': 20.4.2 dev: true - /@types/redis@4.0.11: - resolution: {integrity: sha512-bI+gth8La8Wg/QCR1+V1fhrL9+LZUSWfcqpOj2Kc80ZQ4ffbdL173vQd5wovmoV9i071FU9oP2g6etLuEwb6Rg==} - dependencies: - redis: 4.5.1 - dev: true - /@types/rename@1.0.4: resolution: {integrity: sha512-eV81+6bVv2mdCBahkMefjEUwAjKDAP3AuyhqWCWRxcRaeVdUeHUBaoq2zSz+5HNHF2jzTajMcfLvJsy4K3cbwA==} dev: true @@ -8752,7 +8791,7 @@ packages: '@volar/language-core': 1.9.0 dev: true - /@vue-macros/common@1.5.0(rollup@3.26.2)(vue@3.3.4): + /@vue-macros/common@1.5.0(rollup@3.26.3)(vue@3.3.4): resolution: {integrity: sha512-/Xtmxigolh4NwyLQfrBv+8PAIhlB3doBH7JcA0WuSMmi5LzGOK3YzDCp5jMzpXB6OoUGmm1ZaDkJcBsEmijFPw==} engines: {node: '>=16.14.0'} peerDependencies: @@ -8762,9 +8801,9 @@ packages: optional: true dependencies: '@babel/types': 7.22.5 - '@rollup/pluginutils': 5.0.2(rollup@3.26.2) + '@rollup/pluginutils': 5.0.2(rollup@3.26.3) '@vue/compiler-sfc': 3.3.4 - ast-kit: 0.6.9(rollup@3.26.2) + ast-kit: 0.6.9(rollup@3.26.3) local-pkg: 0.4.3 magic-string-ast: 0.1.3 vue: 3.3.4 @@ -8772,14 +8811,14 @@ packages: - rollup dev: false - /@vue-macros/reactivity-transform@0.3.14(rollup@3.26.2)(vue@3.3.4): - resolution: {integrity: sha512-JiC09q/qlj69hLJ20zNFTlI8y45NwMe1bmC6IIr4FJ1/6uth/U9SE/zcVG0TLnAaykiRaU7OMU4qI0wQx8e3OA==} + /@vue-macros/reactivity-transform@0.3.15(rollup@3.26.3)(vue@3.3.4): + resolution: {integrity: sha512-gDer+sjmKX2wxHNR/epv6RolmRwVuMszoaQ5bZEivrE9LLVEoQwy9RGYVtGR5sAzvSJ2wokb4beHh7f8+l6Rbw==} engines: {node: '>=16.14.0'} peerDependencies: vue: ^2.7.0 || ^3.2.25 dependencies: '@babel/parser': 7.22.7 - '@vue-macros/common': 1.5.0(rollup@3.26.2)(vue@3.3.4) + '@vue-macros/common': 1.5.0(rollup@3.26.3)(vue@3.3.4) '@vue/compiler-core': 3.3.4 '@vue/shared': 3.3.4 magic-string: 0.30.1 @@ -9423,12 +9462,12 @@ packages: engines: {node: '>=0.10.0'} dev: false - /ast-kit@0.6.9(rollup@3.26.2): + /ast-kit@0.6.9(rollup@3.26.3): resolution: {integrity: sha512-2XZi+wqlluYQcxJ1G8qE/U0IeO5CbxUyv1lnSdD7ByJtd5Z3+1063Q6IHbRaYkka1Kb6WgGqEkBrSMaBtbHuFQ==} engines: {node: '>=16.14.0'} dependencies: '@babel/parser': 7.22.7 - '@rollup/pluginutils': 5.0.2(rollup@3.26.2) + '@rollup/pluginutils': 5.0.2(rollup@3.26.3) pathe: 1.1.1 transitivePeerDependencies: - rollup @@ -9533,12 +9572,6 @@ packages: resolution: {integrity: sha512-f86EjiUKE6Xvczc4ioP1JBlWG7FKrE13qe/DxBCpe8GCipCq2nFw73aO8QEBKHfSbYGDN5eB9jXWKen7tspDqQ==} dev: false - /autwh@0.1.0: - resolution: {integrity: sha512-IkGZ4kjVlZMkEmDiVtZpGG3lDGHPqsMBIh4IpQKN7idYOJ5EGedqKPO+ychNqh8zrJEEqYsN0NcBkcmoE2uFAw==} - dependencies: - oauth: 0.9.15 - dev: false - /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} @@ -10047,8 +10080,8 @@ packages: dependencies: node-gyp-build: 4.6.0 - /bullmq@4.3.0: - resolution: {integrity: sha512-0icxNkg1JqS44wnAQW27iNVG6hH0Cfx1XeXBoeZPfWKyqqJgePDbljk0o8iYyTgK/J2I38NGyN7MTGHCnOFVyQ==} + /bullmq@4.4.0: + resolution: {integrity: sha512-2fpKxT9wQUTaOfAxaVXztYM3krvngi91lG340jz0rHcKADbkl1sSqzELystXFbormW98lhfWo6V72Cqs84biPA==} dependencies: cron-parser: 4.8.1 glob: 8.1.0 @@ -10619,11 +10652,6 @@ packages: readable-stream: 2.3.7 dev: false - /cluster-key-slot@1.1.1: - resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==} - engines: {node: '>=0.10.0'} - dev: true - /cluster-key-slot@1.1.2: resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} @@ -12567,8 +12595,8 @@ packages: resolution: {integrity: sha512-79ak0JxddO0utAXAQ5ccKhvs6vX2MGyHHMMsmZkBANrq3hXc1CHzvNPHOcvTsVMEPl5I+NT+RO4YKMGehOfSIg==} dev: false - /fastify@4.19.2: - resolution: {integrity: sha512-2unheeIRWFf9/Jjcz7djOpKuXCTzZjlyFfiBwKqpldkHMN2rfTLu/f9pYTdwlhzC9Cdj0S2H12zlug0Kd5uZ1w==} + /fastify@4.20.0: + resolution: {integrity: sha512-zWWi5KGAb1YZ6fyrnFnA1CA1EZHkGM6YuELgB3QpS3l4lLRy14W1cc16b4KGPH/zQ98WCSdS+T41JkHY3eq1oA==} dependencies: '@fastify/ajv-compiler': 3.5.0 '@fastify/error': 3.2.0 @@ -13149,11 +13177,6 @@ packages: - supports-color dev: false - /generic-pool@3.9.0: - resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} - engines: {node: '>= 4'} - dev: true - /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -16926,10 +16949,6 @@ packages: resolution: {integrity: sha512-1orQ9MT1vHFGQxhuy7E/0gECD3fd2fCC+PIX+/jgmU/gI3EpRocXtmtvxCO5x3WZ443FLTLFWNDjl5MPJf9u+Q==} dev: false - /oauth@0.9.15: - resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} - dev: false - /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -18805,17 +18824,6 @@ packages: redis-errors: 1.2.0 dev: false - /redis@4.5.1: - resolution: {integrity: sha512-oxXSoIqMJCQVBTfxP6BNTCtDMyh9G6Vi5wjdPdV/sRKkufyZslDqCScSGcOr6XGR/reAWZefz7E4leM31RgdBA==} - dependencies: - '@redis/bloom': 1.1.0(@redis/client@1.4.2) - '@redis/client': 1.4.2 - '@redis/graph': 1.1.0(@redis/client@1.4.2) - '@redis/json': 1.0.4(@redis/client@1.4.2) - '@redis/search': 1.1.0(@redis/client@1.4.2) - '@redis/time-series': 1.0.4(@redis/client@1.4.2) - dev: true - /reduce-css-calc@1.3.0: resolution: {integrity: sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==} dependencies: @@ -19166,8 +19174,8 @@ packages: dependencies: glob: 7.2.3 - /rollup@3.26.2: - resolution: {integrity: sha512-6umBIGVz93er97pMgQO08LuH3m6PUb3jlDUUGFsNJB6VgTCUaDFpupf5JfU30529m/UKOgmiX+uY6Sx8cOYpLA==} + /rollup@3.26.3: + resolution: {integrity: sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: @@ -21397,7 +21405,7 @@ packages: '@types/node': 20.4.2 esbuild: 0.18.11 postcss: 8.4.25 - rollup: 3.26.2 + rollup: 3.26.3 sass: 1.63.6 optionalDependencies: fsevents: 2.3.2 @@ -22139,8 +22147,8 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - github.com/misskey-dev/summaly/77dd5654bb82280b38c1f50e51a771c33f3df503: - resolution: {tarball: https://codeload.github.com/misskey-dev/summaly/tar.gz/77dd5654bb82280b38c1f50e51a771c33f3df503} + github.com/misskey-dev/summaly/089a0ad8e8c780e5c088b1c528aa95c5827cbdcc: + resolution: {tarball: https://codeload.github.com/misskey-dev/summaly/tar.gz/089a0ad8e8c780e5c088b1c528aa95c5827cbdcc} name: summaly version: 4.0.2 dependencies: