mirror of
https://git.kescher.at/CatCatNya/catstodon.git
synced 2024-11-22 07:08:07 +01:00
Bump version to v4.3.0-alpha.4+glitch+cat+1.0.0
This commit is contained in:
commit
cb080ca3ef
99 changed files with 849 additions and 553 deletions
|
@ -2,6 +2,7 @@ version: '3'
|
|||
|
||||
services:
|
||||
app:
|
||||
working_dir: /workspaces/mastodon/
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
|
|
|
@ -176,12 +176,6 @@ Style/SafeNavigation:
|
|||
Exclude:
|
||||
- 'app/models/concerns/account/finder_concern.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: Mode.
|
||||
Style/StringConcatenation:
|
||||
Exclude:
|
||||
- 'config/initializers/paperclip.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: WordRegex.
|
||||
# SupportedStyles: percent, brackets
|
||||
|
|
|
@ -5,6 +5,7 @@ All changes to Catstodon that aren't Mastodon or glitch-soc Mastodon changes wil
|
|||
## [v4.3.0-alpha.3+glitch+cat+1.2.7] - 2024-05-29
|
||||
|
||||
- Upstream changes
|
||||
- Includes security fixes announced in version 4.2.9!
|
||||
- Add ability to disable the suspicious sign-in detector
|
||||
- The CatCatNya~ production config has an IP retention period of one day. That will cause suspicious login emails to
|
||||
be sent out simply because we don't have any known IP data. Therefore, this fix is being applied.
|
||||
|
|
|
@ -2,6 +2,61 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [4.2.9] - 2024-05-30
|
||||
|
||||
### Security
|
||||
|
||||
- Update dependencies
|
||||
- Fix private mention filtering ([GHSA-5fq7-3p3j-9vrf](https://github.com/mastodon/mastodon/security/advisories/GHSA-5fq7-3p3j-9vrf))
|
||||
- Fix password change endpoint not being rate-limited ([GHSA-q3rg-xx5v-4mxh](https://github.com/mastodon/mastodon/security/advisories/GHSA-q3rg-xx5v-4mxh))
|
||||
- Add hardening around rate-limit bypass ([GHSA-c2r5-cfqr-c553](https://github.com/mastodon/mastodon/security/advisories/GHSA-c2r5-cfqr-c553))
|
||||
|
||||
### Added
|
||||
|
||||
- Add rate-limit on OAuth application registration ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30316))
|
||||
- Add fallback redirection when getting a webfinger query `WEB_DOMAIN@WEB_DOMAIN` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28592))
|
||||
- Add `digest` attribute to `Admin::DomainBlock` entity in REST API ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/29092))
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove superfluous application-level caching in some controllers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29862))
|
||||
- Remove aggressive OAuth application vacuuming ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30316))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix leaking Elasticsearch connections in Sidekiq processes ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30450))
|
||||
- Fix language of remote posts not being recognized when using unusual casing ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30403))
|
||||
- Fix off-by-one in `tootctl media` commands ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30306))
|
||||
- Fix removal of allowed domains (in `LIMITED_FEDERATION_MODE`) not being recorded in the audit log ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30125))
|
||||
- Fix not being able to block a subdomain of an already-blocked domain through the API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30119))
|
||||
- Fix `Idempotency-Key` being ignored when scheduling a post ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30084))
|
||||
- Fix crash when supplying the `FFMPEG_BINARY` environment variable ([timothyjrogers](https://github.com/mastodon/mastodon/pull/30022))
|
||||
- Fix improper email address validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29838))
|
||||
- Fix results/query in `api/v1/featured_tags/suggestions` ([mjankowski](https://github.com/mastodon/mastodon/pull/29597))
|
||||
- Fix unblocking internationalized domain names under certain conditions ([tribela](https://github.com/mastodon/mastodon/pull/29530))
|
||||
- Fix admin account created by `mastodon:setup` not being auto-approved ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29379))
|
||||
- Fix reference to non-existent var in CLI maintenance command ([mjankowski](https://github.com/mastodon/mastodon/pull/28363))
|
||||
|
||||
## [4.2.8] - 2024-02-23
|
||||
|
||||
### Added
|
||||
|
||||
- Add hourly task to automatically require approval for new registrations in the absence of moderators ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29318), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/29355))
|
||||
In order to prevent future abandoned Mastodon servers from being used for spam, harassment and other malicious activity, Mastodon will now automatically switch new user registrations to require moderator approval whenever they are left open and no activity (including non-moderation actions from apps) from any logged-in user with permission to access moderation reports has been detected in a full week.
|
||||
When this happens, users with the permission to change server settings will receive an email notification.
|
||||
This feature is disabled when `EMAIL_DOMAIN_ALLOWLIST` is used, and can also be disabled with `DISABLE_AUTOMATIC_SWITCHING_TO_APPROVED_REGISTRATIONS=true`.
|
||||
|
||||
### Changed
|
||||
|
||||
- Change registrations to be closed by default on new installations ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29280))
|
||||
If you are running a server and never changed your registrations mode from the default, updating will automatically close your registrations.
|
||||
Simply re-enable them through the administration interface or using `tootctl settings registrations open` if you want to enable them again.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix processing of remote ActivityPub actors making use of `Link` objects as `Image` `url` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29335))
|
||||
- Fix link verifications when page size exceeds 1MB ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29358))
|
||||
|
||||
## [4.2.7] - 2024-02-16
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -237,7 +237,7 @@ GEM
|
|||
tzinfo
|
||||
excon (0.110.0)
|
||||
fabrication (2.31.0)
|
||||
faker (3.3.1)
|
||||
faker (3.4.1)
|
||||
i18n (>= 1.8.11, < 2)
|
||||
faraday (1.10.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
|
@ -431,7 +431,7 @@ GEM
|
|||
mime-types-data (3.2024.0507)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.6)
|
||||
minitest (5.23.0)
|
||||
minitest (5.23.1)
|
||||
msgpack (1.7.2)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.4.0)
|
||||
|
@ -805,7 +805,7 @@ GEM
|
|||
thor (>= 0.20, < 3.0)
|
||||
simple-navigation (4.4.0)
|
||||
activesupport (>= 2.3.2)
|
||||
simple_form (5.3.0)
|
||||
simple_form (5.3.1)
|
||||
actionpack (>= 5.2)
|
||||
activemodel (>= 5.2)
|
||||
simplecov (0.22.0)
|
||||
|
|
|
@ -106,11 +106,11 @@ class Api::V1::AccountsController < Api::BaseController
|
|||
end
|
||||
|
||||
def account_ids
|
||||
Array(accounts_params[:ids]).uniq.map(&:to_i)
|
||||
Array(accounts_params[:id]).uniq.map(&:to_i)
|
||||
end
|
||||
|
||||
def accounts_params
|
||||
params.permit(ids: [])
|
||||
params.permit(id: [])
|
||||
end
|
||||
|
||||
def account_params
|
||||
|
|
|
@ -38,15 +38,15 @@ class Api::V1::ConversationsController < Api::BaseController
|
|||
def paginated_conversations
|
||||
AccountConversation.where(account: current_account)
|
||||
.includes(
|
||||
account: :account_stat,
|
||||
account: [:account_stat, user: :role],
|
||||
last_status: [
|
||||
:media_attachments,
|
||||
:status_stat,
|
||||
:tags,
|
||||
{
|
||||
preview_cards_status: :preview_card,
|
||||
active_mentions: [account: :account_stat],
|
||||
account: :account_stat,
|
||||
preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } },
|
||||
active_mentions: :account,
|
||||
account: [:account_stat, user: :role],
|
||||
},
|
||||
]
|
||||
)
|
||||
|
|
|
@ -143,11 +143,11 @@ class Api::V1::StatusesController < Api::BaseController
|
|||
end
|
||||
|
||||
def status_ids
|
||||
Array(statuses_params[:ids]).uniq.map(&:to_i)
|
||||
Array(statuses_params[:id]).uniq.map(&:to_i)
|
||||
end
|
||||
|
||||
def statuses_params
|
||||
params.permit(ids: [])
|
||||
params.permit(id: [])
|
||||
end
|
||||
|
||||
def status_params
|
||||
|
|
|
@ -65,7 +65,7 @@ window.addEventListener('message', (e) => {
|
|||
{
|
||||
type: 'setHeight',
|
||||
id: data.id,
|
||||
height: document.getElementsByTagName('html')[0].scrollHeight,
|
||||
height: document.getElementsByTagName('html')[0]?.scrollHeight,
|
||||
},
|
||||
'*',
|
||||
);
|
||||
|
@ -135,7 +135,7 @@ function loaded() {
|
|||
);
|
||||
};
|
||||
const todayFormat = new IntlMessageFormat(
|
||||
localeData['relative_format.today'] || 'Today at {time}',
|
||||
localeData['relative_format.today'] ?? 'Today at {time}',
|
||||
locale,
|
||||
);
|
||||
|
||||
|
@ -288,13 +288,13 @@ function loaded() {
|
|||
if (statusEl.dataset.spoiler === 'expanded') {
|
||||
statusEl.dataset.spoiler = 'folded';
|
||||
this.textContent = new IntlMessageFormat(
|
||||
localeData['status.show_more'] || 'Show more',
|
||||
localeData['status.show_more'] ?? 'Show more',
|
||||
locale,
|
||||
).format() as string;
|
||||
} else {
|
||||
statusEl.dataset.spoiler = 'expanded';
|
||||
this.textContent = new IntlMessageFormat(
|
||||
localeData['status.show_less'] || 'Show less',
|
||||
localeData['status.show_less'] ?? 'Show less',
|
||||
locale,
|
||||
).format() as string;
|
||||
}
|
||||
|
@ -316,8 +316,8 @@ function loaded() {
|
|||
|
||||
const message =
|
||||
statusEl.dataset.spoiler === 'expanded'
|
||||
? localeData['status.show_less'] || 'Show less'
|
||||
: localeData['status.show_more'] || 'Show more';
|
||||
? localeData['status.show_less'] ?? 'Show less'
|
||||
: localeData['status.show_more'] ?? 'Show more';
|
||||
spoilerLink.textContent = new IntlMessageFormat(
|
||||
message,
|
||||
locale,
|
||||
|
|
|
@ -67,7 +67,9 @@ const fetchInteractionURLFailure = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const isValidDomain = (value: string) => {
|
||||
const isValidDomain = (value: unknown) => {
|
||||
if (typeof value !== 'string') return false;
|
||||
|
||||
const url = new URL('https:///path');
|
||||
url.hostname = value;
|
||||
return url.hostname === value;
|
||||
|
@ -124,6 +126,11 @@ const fromAcct = (acct: string) => {
|
|||
const domain = segments[1];
|
||||
const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`;
|
||||
|
||||
if (!domain) {
|
||||
fetchInteractionURLFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
axios
|
||||
.get(`https://${domain}/.well-known/webfinger`, {
|
||||
params: { resource: `acct:${acct}` },
|
||||
|
|
|
@ -63,8 +63,9 @@ export const AnimatedNumber: React.FC<Props> = ({ value, obfuscate }) => {
|
|||
<span
|
||||
key={key}
|
||||
style={{
|
||||
position: direction * style.y > 0 ? 'absolute' : 'static',
|
||||
transform: `translateY(${style.y * 100}%)`,
|
||||
position:
|
||||
direction * (style.y ?? 0) > 0 ? 'absolute' : 'static',
|
||||
transform: `translateY(${(style.y ?? 0) * 100}%)`,
|
||||
}}
|
||||
>
|
||||
{obfuscate ? (
|
||||
|
|
|
@ -52,7 +52,10 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) {
|
|||
);
|
||||
|
||||
return Object.values(groups).map((tags) => {
|
||||
if (tags.length === 1) return tags[0];
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know that the array has at least one element
|
||||
const firstTag = tags[0]!;
|
||||
|
||||
if (tags.length === 1) return firstTag;
|
||||
|
||||
// The best match is the one where we have the less difference between upper and lower case letter count
|
||||
const best = minBy(tags, (tag) => {
|
||||
|
@ -66,7 +69,7 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) {
|
|||
return Math.abs(lowerCase - upperCase);
|
||||
});
|
||||
|
||||
return best ?? tags[0];
|
||||
return best ?? firstTag;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ const ShortNumberCounter: React.FC<ShortNumberCounterProps> = ({ value }) => {
|
|||
|
||||
const count = (
|
||||
<FormattedNumber
|
||||
value={rawNumber}
|
||||
value={rawNumber ?? 0}
|
||||
maximumFractionDigits={maxFractionDigits}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -65,7 +65,7 @@ window.addEventListener('message', (e) => {
|
|||
{
|
||||
type: 'setHeight',
|
||||
id: data.id,
|
||||
height: document.getElementsByTagName('html')[0].scrollHeight,
|
||||
height: document.getElementsByTagName('html')[0]?.scrollHeight,
|
||||
},
|
||||
'*',
|
||||
);
|
||||
|
@ -135,7 +135,7 @@ function loaded() {
|
|||
);
|
||||
};
|
||||
const todayFormat = new IntlMessageFormat(
|
||||
localeData['relative_format.today'] || 'Today at {time}',
|
||||
localeData['relative_format.today'] ?? 'Today at {time}',
|
||||
locale,
|
||||
);
|
||||
|
||||
|
@ -288,13 +288,13 @@ function loaded() {
|
|||
if (statusEl.dataset.spoiler === 'expanded') {
|
||||
statusEl.dataset.spoiler = 'folded';
|
||||
this.textContent = new IntlMessageFormat(
|
||||
localeData['status.show_more'] || 'Show more',
|
||||
localeData['status.show_more'] ?? 'Show more',
|
||||
locale,
|
||||
).format() as string;
|
||||
} else {
|
||||
statusEl.dataset.spoiler = 'expanded';
|
||||
this.textContent = new IntlMessageFormat(
|
||||
localeData['status.show_less'] || 'Show less',
|
||||
localeData['status.show_less'] ?? 'Show less',
|
||||
locale,
|
||||
).format() as string;
|
||||
}
|
||||
|
@ -316,8 +316,8 @@ function loaded() {
|
|||
|
||||
const message =
|
||||
statusEl.dataset.spoiler === 'expanded'
|
||||
? localeData['status.show_less'] || 'Show less'
|
||||
: localeData['status.show_more'] || 'Show more';
|
||||
? localeData['status.show_less'] ?? 'Show less'
|
||||
: localeData['status.show_more'] ?? 'Show more';
|
||||
spoilerLink.textContent = new IntlMessageFormat(
|
||||
message,
|
||||
locale,
|
||||
|
|
|
@ -67,7 +67,9 @@ const fetchInteractionURLFailure = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const isValidDomain = (value: string) => {
|
||||
const isValidDomain = (value: unknown) => {
|
||||
if (typeof value !== 'string') return false;
|
||||
|
||||
const url = new URL('https:///path');
|
||||
url.hostname = value;
|
||||
return url.hostname === value;
|
||||
|
@ -124,6 +126,11 @@ const fromAcct = (acct: string) => {
|
|||
const domain = segments[1];
|
||||
const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`;
|
||||
|
||||
if (!domain) {
|
||||
fetchInteractionURLFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
axios
|
||||
.get(`https://${domain}/.well-known/webfinger`, {
|
||||
params: { resource: `acct:${acct}` },
|
||||
|
|
|
@ -29,7 +29,10 @@ const emojis: Emojis = {};
|
|||
|
||||
// decompress
|
||||
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
|
||||
const [_filenameData, searchData] = shortCodesToEmojiData[shortCode];
|
||||
const emojiData = shortCodesToEmojiData[shortCode];
|
||||
if (!emojiData) return;
|
||||
|
||||
const [_filenameData, searchData] = emojiData;
|
||||
const [native, short_names, search, unified] = searchData;
|
||||
|
||||
emojis[shortCode] = {
|
||||
|
|
|
@ -46,7 +46,10 @@ function processEmojiMapData(
|
|||
Object.keys(shortCodesToEmojiData).forEach(
|
||||
(shortCode: ShortCodesToEmojiDataKey) => {
|
||||
if (shortCode === undefined) return;
|
||||
const [filenameData, _searchData] = shortCodesToEmojiData[shortCode];
|
||||
|
||||
const emojiData = shortCodesToEmojiData[shortCode];
|
||||
if (!emojiData) return;
|
||||
const [filenameData, _searchData] = emojiData;
|
||||
filenameData.forEach((emojiMapData) => {
|
||||
processEmojiMapData(emojiMapData, shortCode);
|
||||
});
|
||||
|
|
|
@ -11,8 +11,10 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
|||
import DescriptionIcon from '@/material-icons/400-24px/description-fill.svg?react';
|
||||
import OpenInNewIcon from '@/material-icons/400-24px/open_in_new.svg?react';
|
||||
import PlayArrowIcon from '@/material-icons/400-24px/play_arrow-fill.svg?react';
|
||||
import { Avatar } from 'flavours/glitch/components/avatar';
|
||||
import { Blurhash } from 'flavours/glitch/components/blurhash';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { Permalink } from 'flavours/glitch/components/permalink';
|
||||
import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp';
|
||||
import { useBlurhash } from 'flavours/glitch/initial_state';
|
||||
import { decode as decodeIDNA } from 'flavours/glitch/utils/idna';
|
||||
|
@ -46,6 +48,20 @@ const addAutoPlay = html => {
|
|||
return html;
|
||||
};
|
||||
|
||||
const MoreFromAuthor = ({ author }) => (
|
||||
<div className='more-from-author'>
|
||||
<svg viewBox='0 0 79 79' className='logo logo--icon' role='img'>
|
||||
<use xlinkHref='#logo-symbol-icon' />
|
||||
</svg>
|
||||
|
||||
<FormattedMessage id='link_preview.more_from_author' defaultMessage='More from {name}' values={{ name: <Permalink href={author.get('url')} to={`/@${author.get('acct')}`}><Avatar account={author} size={16} /> {author.get('display_name')}</Permalink> }} />
|
||||
</div>
|
||||
);
|
||||
|
||||
MoreFromAuthor.propTypes = {
|
||||
author: ImmutablePropTypes.map,
|
||||
};
|
||||
|
||||
export default class Card extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
|
@ -126,6 +142,7 @@ export default class Card extends PureComponent {
|
|||
const interactive = card.get('type') === 'video';
|
||||
const language = card.get('language') || '';
|
||||
const largeImage = (card.get('image')?.length > 0 && card.get('width') > card.get('height')) || interactive;
|
||||
const showAuthor = !!card.get('author_account');
|
||||
|
||||
const description = (
|
||||
<div className='status-card__content'>
|
||||
|
@ -136,7 +153,7 @@ export default class Card extends PureComponent {
|
|||
|
||||
<strong className='status-card__title' title={card.get('title')} lang={language}>{card.get('title')}</strong>
|
||||
|
||||
{card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>}
|
||||
{!showAuthor && (card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>)}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -225,10 +242,14 @@ export default class Card extends PureComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
|
||||
{embed}
|
||||
{description}
|
||||
</a>
|
||||
<>
|
||||
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage, bottomless: showAuthor })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
|
||||
{embed}
|
||||
{description}
|
||||
</a>
|
||||
|
||||
{showAuthor && <MoreFromAuthor author={card.get('author_account')} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,8 +74,9 @@ export const soundsMiddleware = (): Middleware<
|
|||
if (isActionWithMetaSound(action)) {
|
||||
const sound = action.meta.sound;
|
||||
|
||||
if (sound && Object.hasOwn(soundCache, sound)) {
|
||||
play(soundCache[sound]);
|
||||
if (sound) {
|
||||
const s = soundCache[sound];
|
||||
if (s) play(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,21 +89,17 @@ type OnData<LoadDataResult, ReturnedData> = (
|
|||
},
|
||||
) => ReturnedData | DiscardLoadData | Promise<ReturnedData | DiscardLoadData>;
|
||||
|
||||
type ArgsType = Record<string, unknown> | undefined;
|
||||
|
||||
// Overload when there is no `onData` method, the payload is the `onData` result
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
>(
|
||||
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
||||
name: string,
|
||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
||||
thunkOptions?: AppThunkOptions,
|
||||
): ReturnType<typeof createThunk<Args, LoadDataResult>>;
|
||||
|
||||
// Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
>(
|
||||
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
||||
name: string,
|
||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
||||
onDataOrThunkOptions?:
|
||||
|
@ -113,10 +109,7 @@ export function createDataLoadingThunk<
|
|||
): ReturnType<typeof createThunk<Args, void>>;
|
||||
|
||||
// Overload when the `onData` method returns nothing, then the mayload is the `onData` result
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
>(
|
||||
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
||||
name: string,
|
||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
||||
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, void>,
|
||||
|
@ -126,7 +119,7 @@ export function createDataLoadingThunk<
|
|||
// Overload when there is an `onData` method returning something
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
Args extends ArgsType,
|
||||
Returned,
|
||||
>(
|
||||
name: string,
|
||||
|
@ -162,7 +155,7 @@ export function createDataLoadingThunk<
|
|||
*/
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
Args extends ArgsType,
|
||||
Returned,
|
||||
>(
|
||||
name: string,
|
||||
|
|
|
@ -4146,6 +4146,10 @@ input.glitch-setting-text {
|
|||
border: 1px solid var(--background-border-color);
|
||||
border-radius: 8px;
|
||||
|
||||
&.bottomless {
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
bottom: 0;
|
||||
inset-inline-start: 0;
|
||||
|
@ -10830,3 +10834,42 @@ noscript {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.more-from-author {
|
||||
font-size: 14px;
|
||||
color: $darker-text-color;
|
||||
background: var(--surface-background-color);
|
||||
border: 1px solid var(--background-border-color);
|
||||
border-top: 0;
|
||||
border-radius: 0 0 8px 8px;
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.logo {
|
||||
height: 16px;
|
||||
color: $darker-text-color;
|
||||
}
|
||||
|
||||
& > span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-weight: 500;
|
||||
color: $primary-text-color;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
color: $highlight-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,9 @@ export const AnimatedNumber: React.FC<Props> = ({ value }) => {
|
|||
<span
|
||||
key={key}
|
||||
style={{
|
||||
position: direction * style.y > 0 ? 'absolute' : 'static',
|
||||
transform: `translateY(${style.y * 100}%)`,
|
||||
position:
|
||||
direction * (style.y ?? 0) > 0 ? 'absolute' : 'static',
|
||||
transform: `translateY(${(style.y ?? 0) * 100}%)`,
|
||||
}}
|
||||
>
|
||||
<ShortNumber value={data as number} />
|
||||
|
|
|
@ -52,7 +52,10 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) {
|
|||
);
|
||||
|
||||
return Object.values(groups).map((tags) => {
|
||||
if (tags.length === 1) return tags[0];
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know that the array has at least one element
|
||||
const firstTag = tags[0]!;
|
||||
|
||||
if (tags.length === 1) return firstTag;
|
||||
|
||||
// The best match is the one where we have the less difference between upper and lower case letter count
|
||||
const best = minBy(tags, (tag) => {
|
||||
|
@ -66,7 +69,7 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) {
|
|||
return Math.abs(lowerCase - upperCase);
|
||||
});
|
||||
|
||||
return best ?? tags[0];
|
||||
return best ?? firstTag;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ const ShortNumberCounter: React.FC<ShortNumberCounterProps> = ({ value }) => {
|
|||
|
||||
const count = (
|
||||
<FormattedNumber
|
||||
value={rawNumber}
|
||||
value={rawNumber ?? 0}
|
||||
maximumFractionDigits={maxFractionDigits}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -29,7 +29,10 @@ const emojis: Emojis = {};
|
|||
|
||||
// decompress
|
||||
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
|
||||
const [_filenameData, searchData] = shortCodesToEmojiData[shortCode];
|
||||
const emojiData = shortCodesToEmojiData[shortCode];
|
||||
if (!emojiData) return;
|
||||
|
||||
const [_filenameData, searchData] = emojiData;
|
||||
const [native, short_names, search, unified] = searchData;
|
||||
|
||||
emojis[shortCode] = {
|
||||
|
|
|
@ -46,7 +46,10 @@ function processEmojiMapData(
|
|||
Object.keys(shortCodesToEmojiData).forEach(
|
||||
(shortCode: ShortCodesToEmojiDataKey) => {
|
||||
if (shortCode === undefined) return;
|
||||
const [filenameData, _searchData] = shortCodesToEmojiData[shortCode];
|
||||
|
||||
const emojiData = shortCodesToEmojiData[shortCode];
|
||||
if (!emojiData) return;
|
||||
const [filenameData, _searchData] = emojiData;
|
||||
filenameData.forEach((emojiMapData) => {
|
||||
processEmojiMapData(emojiMapData, shortCode);
|
||||
});
|
||||
|
|
|
@ -6,6 +6,8 @@ import { PureComponent } from 'react';
|
|||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
|
||||
import Immutable from 'immutable';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
@ -13,6 +15,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
|||
import DescriptionIcon from '@/material-icons/400-24px/description-fill.svg?react';
|
||||
import OpenInNewIcon from '@/material-icons/400-24px/open_in_new.svg?react';
|
||||
import PlayArrowIcon from '@/material-icons/400-24px/play_arrow-fill.svg?react';
|
||||
import { Avatar } from 'mastodon/components/avatar';
|
||||
import { Blurhash } from 'mastodon/components/blurhash';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
|
||||
|
@ -56,6 +59,20 @@ const addAutoPlay = html => {
|
|||
return html;
|
||||
};
|
||||
|
||||
const MoreFromAuthor = ({ author }) => (
|
||||
<div className='more-from-author'>
|
||||
<svg viewBox='0 0 79 79' className='logo logo--icon' role='img'>
|
||||
<use xlinkHref='#logo-symbol-icon' />
|
||||
</svg>
|
||||
|
||||
<FormattedMessage id='link_preview.more_from_author' defaultMessage='More from {name}' values={{ name: <Link to={`/@${author.get('acct')}`}><Avatar account={author} size={16} /> {author.get('display_name')}</Link> }} />
|
||||
</div>
|
||||
);
|
||||
|
||||
MoreFromAuthor.propTypes = {
|
||||
author: ImmutablePropTypes.map,
|
||||
};
|
||||
|
||||
export default class Card extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
|
@ -136,6 +153,7 @@ export default class Card extends PureComponent {
|
|||
const interactive = card.get('type') === 'video';
|
||||
const language = card.get('language') || '';
|
||||
const largeImage = (card.get('image')?.length > 0 && card.get('width') > card.get('height')) || interactive;
|
||||
const showAuthor = !!card.get('author_account');
|
||||
|
||||
const description = (
|
||||
<div className='status-card__content'>
|
||||
|
@ -146,7 +164,7 @@ export default class Card extends PureComponent {
|
|||
|
||||
<strong className='status-card__title' title={card.get('title')} lang={language}>{card.get('title')}</strong>
|
||||
|
||||
{card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>}
|
||||
{!showAuthor && (card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>)}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -235,10 +253,14 @@ export default class Card extends PureComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
|
||||
{embed}
|
||||
{description}
|
||||
</a>
|
||||
<>
|
||||
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage, bottomless: showAuthor })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
|
||||
{embed}
|
||||
{description}
|
||||
</a>
|
||||
|
||||
{showAuthor && <MoreFromAuthor author={card.get('author_account')} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Mostra el perfil de totes maneres",
|
||||
"limited_account_hint.title": "Aquest perfil l'han amagat els moderadors de {domain}.",
|
||||
"link_preview.author": "Per {name}",
|
||||
"link_preview.more_from_author": "Més de {name}",
|
||||
"lists.account.add": "Afegeix a la llista",
|
||||
"lists.account.remove": "Elimina de la llista",
|
||||
"lists.delete": "Elimina la llista",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Show profile anyway",
|
||||
"limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
|
||||
"link_preview.author": "By {name}",
|
||||
"link_preview.more_from_author": "More from {name}",
|
||||
"lists.account.add": "Add to list",
|
||||
"lists.account.remove": "Remove from list",
|
||||
"lists.delete": "Delete list",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Mostrar perfil de todos modos",
|
||||
"limited_account_hint.title": "Este perfil fue ocultado por los moderadores de {domain}.",
|
||||
"link_preview.author": "Por {name}",
|
||||
"link_preview.more_from_author": "Más de {name}",
|
||||
"lists.account.add": "Agregar a lista",
|
||||
"lists.account.remove": "Quitar de lista",
|
||||
"lists.delete": "Eliminar lista",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Näytä profiili joka tapauksessa",
|
||||
"limited_account_hint.title": "Palvelimen {domain} valvojat ovat piilottaneet tämän käyttäjätilin.",
|
||||
"link_preview.author": "Julkaissut {name}",
|
||||
"link_preview.more_from_author": "Lisää käyttäjältä {name}",
|
||||
"lists.account.add": "Lisää listalle",
|
||||
"lists.account.remove": "Poista listalta",
|
||||
"lists.delete": "Poista lista",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Mostrar perfil igualmente",
|
||||
"limited_account_hint.title": "Este perfil foi agochado pola moderación de {domain}.",
|
||||
"link_preview.author": "Por {name}",
|
||||
"link_preview.more_from_author": "Máis de {name}",
|
||||
"lists.account.add": "Engadir á listaxe",
|
||||
"lists.account.remove": "Eliminar da listaxe",
|
||||
"lists.delete": "Eliminar listaxe",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Mostra comunque il profilo",
|
||||
"limited_account_hint.title": "Questo profilo è stato nascosto dai moderatori di {domain}.",
|
||||
"link_preview.author": "Di {name}",
|
||||
"link_preview.more_from_author": "Altro da {name}",
|
||||
"lists.account.add": "Aggiungi all'elenco",
|
||||
"lists.account.remove": "Rimuovi dall'elenco",
|
||||
"lists.delete": "Elimina elenco",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "그래도 프로필 보기",
|
||||
"limited_account_hint.title": "이 프로필은 {domain}의 중재자에 의해 숨겨진 상태입니다.",
|
||||
"link_preview.author": "{name}",
|
||||
"link_preview.more_from_author": "{name} 더 둘러보기",
|
||||
"lists.account.add": "리스트에 추가",
|
||||
"lists.account.remove": "리스트에서 제거",
|
||||
"lists.delete": "리스트 삭제",
|
||||
|
|
|
@ -466,6 +466,7 @@
|
|||
"notification.follow_request": "{name} paprašė tave sekti",
|
||||
"notification.mention": "{name} paminėjo tave",
|
||||
"notification.moderation-warning.learn_more": "Sužinoti daugiau",
|
||||
"notification.moderation_warning": "Gavai prižiūrėjimo įspėjimą",
|
||||
"notification.moderation_warning.action_delete_statuses": "Kai kurie tavo įrašai buvo pašalintos.",
|
||||
"notification.moderation_warning.action_disable": "Tavo paskyra buvo išjungta.",
|
||||
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Kai kurie tavo įrašai buvo pažymėtos kaip jautrios.",
|
||||
|
|
|
@ -673,7 +673,7 @@
|
|||
"search.quick_action.account_search": "Profiler som samsvarer med {x}",
|
||||
"search.quick_action.go_to_account": "Gå til profil {x}",
|
||||
"search.quick_action.go_to_hashtag": "Gå til emneknagg {x}",
|
||||
"search.quick_action.open_url": "Åpne URL i Mastodon",
|
||||
"search.quick_action.open_url": "Opne adressa i Mastodon",
|
||||
"search.quick_action.status_search": "Innlegg som samsvarer med {x}",
|
||||
"search.search_or_paste": "Søk eller lim inn URL",
|
||||
"search_popout.full_text_search_disabled_message": "Ikkje tilgjengeleg på {domain}.",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Pokaż profil mimo to",
|
||||
"limited_account_hint.title": "Ten profil został ukryty przez moderatorów {domain}.",
|
||||
"link_preview.author": "{name}",
|
||||
"link_preview.more_from_author": "Więcej od {name}",
|
||||
"lists.account.add": "Dodaj do listy",
|
||||
"lists.account.remove": "Usunąć z listy",
|
||||
"lists.delete": "Usuń listę",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Exibir perfil mesmo assim",
|
||||
"limited_account_hint.title": "Este perfil foi ocultado pelos moderadores do {domain}.",
|
||||
"link_preview.author": "Por {name}",
|
||||
"link_preview.more_from_author": "Mais de {name}",
|
||||
"lists.account.add": "Adicionar à lista",
|
||||
"lists.account.remove": "Remover da lista",
|
||||
"lists.delete": "Excluir lista",
|
||||
|
@ -474,6 +475,7 @@
|
|||
"notification.follow_request": "{name} quer te seguir",
|
||||
"notification.mention": "{name} te mencionou",
|
||||
"notification.moderation-warning.learn_more": "Aprender mais",
|
||||
"notification.moderation_warning": "Você recebeu um aviso de moderação",
|
||||
"notification.moderation_warning.action_delete_statuses": "Algumas das suas publicações foram removidas.",
|
||||
"notification.moderation_warning.action_disable": "Sua conta foi desativada.",
|
||||
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Algumas de suas publicações foram marcadas por ter conteúdo sensível.",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Exibir perfil mesmo assim",
|
||||
"limited_account_hint.title": "Este perfil foi ocultado pelos moderadores de {domain}.",
|
||||
"link_preview.author": "Por {name}",
|
||||
"link_preview.more_from_author": "Mais de {name}",
|
||||
"lists.account.add": "Adicionar à lista",
|
||||
"lists.account.remove": "Remover da lista",
|
||||
"lists.delete": "Eliminar lista",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"account.edit_profile": "පැතිකඩ සංස්කරණය",
|
||||
"account.enable_notifications": "@{name} පළ කරන විට මට දැනුම් දෙන්න",
|
||||
"account.endorse": "පැතිකඩෙහි විශේෂාංගය",
|
||||
"account.featured_tags.last_status_at": "අවසාන ලිපිය: {date}",
|
||||
"account.featured_tags.last_status_never": "ලිපි නැත",
|
||||
"account.follow": "අනුගමනය",
|
||||
"account.followers": "අනුගාමිකයින්",
|
||||
|
@ -104,6 +105,7 @@
|
|||
"compose_form.poll.duration": "මත විමසීමේ කාලය",
|
||||
"compose_form.poll.switch_to_multiple": "තේරීම් කිහිපයකට මත විමසුම වෙනස් කරන්න",
|
||||
"compose_form.poll.switch_to_single": "තනි තේරීමකට මත විමසුම වෙනස් කරන්න",
|
||||
"compose_form.publish": "ප්රකාශනය",
|
||||
"compose_form.publish_form": "නව ලිපිය",
|
||||
"compose_form.spoiler.marked": "අන්තර්ගත අවවාදය ඉවත් කරන්න",
|
||||
"compose_form.spoiler.unmarked": "අන්තර්ගත අවවාදයක් එක් කරන්න",
|
||||
|
@ -154,6 +156,7 @@
|
|||
"empty_column.bookmarked_statuses": "ඔබ සතුව පොත්යොමු තබන ලද ලිපි කිසිවක් නැත. ඔබ පොත්යොමුවක් තබන විට, එය මෙහි දිස්වනු ඇත.",
|
||||
"empty_column.domain_blocks": "අවහිර කරන ලද වසම් නැත.",
|
||||
"empty_column.explore_statuses": "දැන් කිසිවක් නැඹුරු නොවේ. පසුව නැවත පරීක්ෂා කරන්න!",
|
||||
"empty_column.favourited_statuses": "ඔබ සතුව ප්රියතම ලිපි කිසිවක් නැත. ඔබ යමකට ප්රිය කළ විට එය මෙහි පෙන්වනු ඇත.",
|
||||
"empty_column.follow_requests": "ඔබට තවමත් අනුගමන ඉල්ලීම් ලැබී නැත. ඉල්ලීමක් ලැබුණු විට, එය මෙහි පෙන්වනු ඇත.",
|
||||
"empty_column.home": "මුල් පිටුව හිස් ය! මෙය පිරවීමට බොහෝ පුද්ගලයින් අනුගමනය කරන්න.",
|
||||
"empty_column.lists": "ඔබට තවමත් ලැයිස්තු කිසිවක් නැත. ඔබ එකක් සාදන විට, එය මෙහි පෙන්වනු ඇත.",
|
||||
|
@ -205,6 +208,7 @@
|
|||
"interaction_modal.on_this_server": "මෙම සේවාදායකයෙහි",
|
||||
"interaction_modal.title.favourite": "{name}ගේ ලිපිය ප්රිය කරන්න",
|
||||
"interaction_modal.title.follow": "{name} අනුගමනය",
|
||||
"interaction_modal.title.reply": "{name}ගේ ලිපියට පිළිතුරු",
|
||||
"intervals.full.days": "{number, plural, one {දවස් #} other {දවස් #}}",
|
||||
"intervals.full.hours": "{number, plural, one {පැය #} other {පැය #}}",
|
||||
"intervals.full.minutes": "{number, plural, one {විනාඩි #} other {විනාඩි #}}",
|
||||
|
@ -239,6 +243,7 @@
|
|||
"lists.delete": "ලැයිස්තුව මකන්න",
|
||||
"lists.edit": "ලැයිස්තුව සංස්කරණය",
|
||||
"lists.edit.submit": "සිරැසිය සංශෝධනය",
|
||||
"lists.new.create": "එකතු",
|
||||
"lists.new.title_placeholder": "නව ලැයිස්තුවේ සිරැසිය",
|
||||
"lists.replies_policy.list": "ලැයිස්තුවේ සාමාජිකයින්",
|
||||
"lists.replies_policy.none": "කිසිවෙක් නැත",
|
||||
|
@ -266,6 +271,7 @@
|
|||
"navigation_bar.search": "සොයන්න",
|
||||
"navigation_bar.security": "ආරක්ෂාව",
|
||||
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
|
||||
"notification.favourite": "{name} ඔබගේ ලිපියට ප්රිය කළා",
|
||||
"notification.follow": "{name} ඔබව අනුගමනය කළා",
|
||||
"notification.mention": "{name} ඔබව සඳහන් කර ඇත",
|
||||
"notification.own_poll": "ඔබගේ මත විමසුම නිමයි",
|
||||
|
@ -395,6 +401,7 @@
|
|||
"status.admin_status": "මෙම ලිපිය මැදිහත්කරණ අතුරුමුහුණතෙහි අරින්න",
|
||||
"status.block": "@{name} අවහිර",
|
||||
"status.bookmark": "පොත්යොමුවක්",
|
||||
"status.copy": "ලිපියට සබැඳියේ පිටපතක්",
|
||||
"status.delete": "මකන්න",
|
||||
"status.detailed_status": "විස්තරාත්මක සංවාද දැක්ම",
|
||||
"status.edit": "සංස්කරණය",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Vseeno pokaži profil",
|
||||
"limited_account_hint.title": "Profil so moderatorji strežnika {domain} skrili.",
|
||||
"link_preview.author": "Avtor_ica {name}",
|
||||
"link_preview.more_from_author": "Več od {name}",
|
||||
"lists.account.add": "Dodaj na seznam",
|
||||
"lists.account.remove": "Odstrani s seznama",
|
||||
"lists.delete": "Izbriši seznam",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "Vẫn cứ xem",
|
||||
"limited_account_hint.title": "Người này đã bị ẩn bởi quản trị viên của {domain}.",
|
||||
"link_preview.author": "Bởi {name}",
|
||||
"link_preview.more_from_author": "Thêm từ {name}",
|
||||
"lists.account.add": "Thêm vào danh sách",
|
||||
"lists.account.remove": "Xóa khỏi danh sách",
|
||||
"lists.delete": "Xóa danh sách",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "仍要显示个人资料",
|
||||
"limited_account_hint.title": "此账号资料已被 {domain} 管理员隐藏。",
|
||||
"link_preview.author": "由 {name}",
|
||||
"link_preview.more_from_author": "查看 {name} 的更多内容",
|
||||
"lists.account.add": "添加到列表",
|
||||
"lists.account.remove": "从列表中移除",
|
||||
"lists.delete": "删除列表",
|
||||
|
|
|
@ -414,6 +414,7 @@
|
|||
"limited_account_hint.action": "一律顯示個人檔案",
|
||||
"limited_account_hint.title": "此個人檔案已被 {domain} 的管理員隱藏。",
|
||||
"link_preview.author": "來自 {name}",
|
||||
"link_preview.more_from_author": "來自 {name} 之更多內容",
|
||||
"lists.account.add": "新增至列表",
|
||||
"lists.account.remove": "自列表中移除",
|
||||
"lists.delete": "刪除列表",
|
||||
|
|
|
@ -74,8 +74,9 @@ export const soundsMiddleware = (): Middleware<
|
|||
if (isActionWithMetaSound(action)) {
|
||||
const sound = action.meta.sound;
|
||||
|
||||
if (sound && Object.hasOwn(soundCache, sound)) {
|
||||
play(soundCache[sound]);
|
||||
if (sound) {
|
||||
const s = soundCache[sound];
|
||||
if (s) play(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,21 +89,17 @@ type OnData<LoadDataResult, ReturnedData> = (
|
|||
},
|
||||
) => ReturnedData | DiscardLoadData | Promise<ReturnedData | DiscardLoadData>;
|
||||
|
||||
type ArgsType = Record<string, unknown> | undefined;
|
||||
|
||||
// Overload when there is no `onData` method, the payload is the `onData` result
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
>(
|
||||
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
||||
name: string,
|
||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
||||
thunkOptions?: AppThunkOptions,
|
||||
): ReturnType<typeof createThunk<Args, LoadDataResult>>;
|
||||
|
||||
// Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
>(
|
||||
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
||||
name: string,
|
||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
||||
onDataOrThunkOptions?:
|
||||
|
@ -113,10 +109,7 @@ export function createDataLoadingThunk<
|
|||
): ReturnType<typeof createThunk<Args, void>>;
|
||||
|
||||
// Overload when the `onData` method returns nothing, then the mayload is the `onData` result
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
>(
|
||||
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
||||
name: string,
|
||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
||||
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, void>,
|
||||
|
@ -126,7 +119,7 @@ export function createDataLoadingThunk<
|
|||
// Overload when there is an `onData` method returning something
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
Args extends ArgsType,
|
||||
Returned,
|
||||
>(
|
||||
name: string,
|
||||
|
@ -162,7 +155,7 @@ export function createDataLoadingThunk<
|
|||
*/
|
||||
export function createDataLoadingThunk<
|
||||
LoadDataResult,
|
||||
Args extends Record<string, unknown>,
|
||||
Args extends ArgsType,
|
||||
Returned,
|
||||
>(
|
||||
name: string,
|
||||
|
|
|
@ -3896,6 +3896,10 @@ $ui-header-logo-wordmark-width: 99px;
|
|||
border: 1px solid var(--background-border-color);
|
||||
border-radius: 8px;
|
||||
|
||||
&.bottomless {
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
bottom: 0;
|
||||
inset-inline-start: 0;
|
||||
|
@ -10223,3 +10227,42 @@ noscript {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.more-from-author {
|
||||
font-size: 14px;
|
||||
color: $darker-text-color;
|
||||
background: var(--surface-background-color);
|
||||
border: 1px solid var(--background-border-color);
|
||||
border-top: 0;
|
||||
border-radius: 0 0 8px 8px;
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.logo {
|
||||
height: 16px;
|
||||
color: $darker-text-color;
|
||||
}
|
||||
|
||||
& > span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-weight: 500;
|
||||
color: $primary-text-color;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
color: $highlight-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
def process_status_params
|
||||
@status_parser = ActivityPub::Parser::StatusParser.new(@json, followers_collection: @account.followers_url, object: @object)
|
||||
|
||||
attachment_ids = process_attachments.take(4).map(&:id)
|
||||
attachment_ids = process_attachments.take(Status::MEDIA_ATTACHMENTS_LIMIT).map(&:id)
|
||||
|
||||
@params = {
|
||||
uri: @status_parser.uri,
|
||||
|
@ -278,7 +278,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
as_array(@object['attachment']).each do |attachment|
|
||||
media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment)
|
||||
|
||||
next if media_attachment_parser.remote_url.blank? || media_attachments.size >= 4
|
||||
next if media_attachment_parser.remote_url.blank? || media_attachments.size >= Status::MEDIA_ATTACHMENTS_LIMIT
|
||||
|
||||
begin
|
||||
media_attachment = MediaAttachment.create(
|
||||
|
|
|
@ -195,6 +195,10 @@ class LinkDetailsExtractor
|
|||
structured_data&.author_url
|
||||
end
|
||||
|
||||
def author_account
|
||||
opengraph_tag('fediverse:creator')
|
||||
end
|
||||
|
||||
def embed_url
|
||||
valid_url_or_nil(opengraph_tag('twitter:player:stream'))
|
||||
end
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Vacuum::ApplicationsVacuum
|
||||
def perform
|
||||
Doorkeeper::Application.where(owner_id: nil)
|
||||
.where.missing(:created_users, :access_tokens, :access_grants)
|
||||
.where(created_at: ...1.day.ago)
|
||||
.in_batches.delete_all
|
||||
end
|
||||
end
|
|
@ -142,6 +142,8 @@ class Account < ApplicationRecord
|
|||
scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) }
|
||||
scope :not_domain_blocked_by_account, ->(account) { where(arel_table[:domain].eq(nil).or(arel_table[:domain].not_in(account.excluded_from_timeline_domains))) }
|
||||
scope :dormant, -> { joins(:account_stat).merge(AccountStat.without_recent_activity) }
|
||||
scope :with_username, ->(value) { where arel_table[:username].lower.eq(value.to_s.downcase) }
|
||||
scope :with_domain, ->(value) { where arel_table[:domain].lower.eq(value&.to_s&.downcase) }
|
||||
|
||||
after_update_commit :trigger_update_webhooks
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
||||
def get(account, limit: DEFAULT_LIMIT)
|
||||
if setting_enabled?
|
||||
base_account_scope(account).where(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle)
|
||||
base_account_scope(account).merge(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
@ -25,11 +25,9 @@ class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
|||
|
||||
def setting_to_where_condition
|
||||
usernames_and_domains.map do |(username, domain)|
|
||||
Arel::Nodes::Grouping.new(
|
||||
Account.arel_table[:username].lower.eq(username.downcase).and(
|
||||
Account.arel_table[:domain].lower.eq(domain&.downcase)
|
||||
)
|
||||
)
|
||||
Account
|
||||
.with_username(username)
|
||||
.with_domain(domain)
|
||||
end.reduce(:or)
|
||||
end
|
||||
|
||||
|
|
|
@ -25,42 +25,11 @@ module Account::FinderConcern
|
|||
end
|
||||
|
||||
def find_remote(username, domain)
|
||||
AccountFinder.new(username, domain).account
|
||||
end
|
||||
end
|
||||
|
||||
class AccountFinder
|
||||
attr_reader :username, :domain
|
||||
|
||||
def initialize(username, domain)
|
||||
@username = username
|
||||
@domain = domain
|
||||
end
|
||||
|
||||
def account
|
||||
scoped_accounts.order(id: :asc).take
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scoped_accounts
|
||||
Account.unscoped.tap do |scope|
|
||||
scope.merge! with_usernames
|
||||
scope.merge! matching_username
|
||||
scope.merge! matching_domain
|
||||
end
|
||||
end
|
||||
|
||||
def with_usernames
|
||||
Account.where.not(Account.arel_table[:username].lower.eq '')
|
||||
end
|
||||
|
||||
def matching_username
|
||||
Account.where(Account.arel_table[:username].lower.eq username.to_s.downcase)
|
||||
end
|
||||
|
||||
def matching_domain
|
||||
Account.where(Account.arel_table[:domain].lower.eq(domain.nil? ? nil : domain.to_s.downcase))
|
||||
Account
|
||||
.with_username(username)
|
||||
.with_domain(domain)
|
||||
.order(id: :asc)
|
||||
.take
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,7 +22,7 @@ module User::LdapAuthenticable
|
|||
safe_username = safe_username.gsub(keys, replacement)
|
||||
end
|
||||
|
||||
resource = joins(:account).merge(Account.where(Account.arel_table[:username].lower.eq safe_username.downcase)).take
|
||||
resource = joins(:account).merge(Account.with_username(safe_username)).take
|
||||
|
||||
if resource.blank?
|
||||
resource = new(
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
# link_type :integer
|
||||
# published_at :datetime
|
||||
# image_description :string default(""), not null
|
||||
# author_account_id :bigint(8)
|
||||
#
|
||||
|
||||
class PreviewCard < ApplicationRecord
|
||||
|
@ -54,6 +55,7 @@ class PreviewCard < ApplicationRecord
|
|||
has_many :statuses, through: :preview_cards_statuses
|
||||
|
||||
has_one :trend, class_name: 'PreviewCardTrend', inverse_of: :preview_card, dependent: :destroy
|
||||
belongs_to :author_account, class_name: 'Account', optional: true
|
||||
|
||||
has_attached_file :image, processors: [:thumbnail, :blurhash_transcoder], styles: ->(f) { image_styles(f) }, convert_options: { all: '-quality 90 +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' }, validate_media_type: false
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ class Status < ApplicationRecord
|
|||
include Status::SnapshotConcern
|
||||
include Status::ThreadingConcern
|
||||
|
||||
MEDIA_ATTACHMENTS_LIMIT = 4
|
||||
|
||||
rate_limit by: :account, family: :statuses
|
||||
|
||||
self.discard_column = :deleted_at
|
||||
|
@ -163,9 +165,9 @@ class Status < ApplicationRecord
|
|||
:status_stat,
|
||||
:tags,
|
||||
:preloadable_poll,
|
||||
preview_cards_status: [:preview_card],
|
||||
preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } },
|
||||
account: [:account_stat, user: :role],
|
||||
active_mentions: { account: :account_stat },
|
||||
active_mentions: :account,
|
||||
reblog: [
|
||||
:application,
|
||||
:tags,
|
||||
|
@ -173,11 +175,11 @@ class Status < ApplicationRecord
|
|||
:conversation,
|
||||
:status_stat,
|
||||
:preloadable_poll,
|
||||
preview_cards_status: [:preview_card],
|
||||
preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } },
|
||||
account: [:account_stat, user: :role],
|
||||
active_mentions: { account: :account_stat },
|
||||
active_mentions: :account,
|
||||
],
|
||||
thread: { account: :account_stat }
|
||||
thread: :account
|
||||
|
||||
delegate :domain, to: :account, prefix: true
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
|||
|
||||
statuses: {
|
||||
max_characters: StatusLengthValidator::MAX_CHARS,
|
||||
max_media_attachments: 4,
|
||||
max_media_attachments: Status::MEDIA_ATTACHMENTS_LIMIT,
|
||||
characters_reserved_per_url: StatusLengthValidator::URL_PLACEHOLDER_CHARS,
|
||||
supported_mime_types: HtmlAwareFormatter::STATUS_MIME_TYPES,
|
||||
},
|
||||
|
|
|
@ -8,6 +8,8 @@ class REST::PreviewCardSerializer < ActiveModel::Serializer
|
|||
:provider_url, :html, :width, :height,
|
||||
:image, :image_description, :embed_url, :blurhash, :published_at
|
||||
|
||||
has_one :author_account, serializer: REST::AccountSerializer, if: -> { object.author_account.present? }
|
||||
|
||||
def url
|
||||
object.original_url.presence || object.url
|
||||
end
|
||||
|
|
|
@ -78,7 +78,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
|
|||
|
||||
statuses: {
|
||||
max_characters: StatusLengthValidator::MAX_CHARS,
|
||||
max_media_attachments: 4,
|
||||
max_media_attachments: Status::MEDIA_ATTACHMENTS_LIMIT,
|
||||
characters_reserved_per_url: StatusLengthValidator::URL_PLACEHOLDER_CHARS,
|
||||
supported_mime_types: HtmlAwareFormatter::STATUS_MIME_TYPES,
|
||||
},
|
||||
|
|
|
@ -73,7 +73,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
|||
as_array(@json['attachment']).each do |attachment|
|
||||
media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment)
|
||||
|
||||
next if media_attachment_parser.remote_url.blank? || @next_media_attachments.size > 4
|
||||
next if media_attachment_parser.remote_url.blank? || @next_media_attachments.size > Status::MEDIA_ATTACHMENTS_LIMIT
|
||||
|
||||
begin
|
||||
media_attachment = previous_media_attachments.find { |previous_media_attachment| previous_media_attachment.remote_url == media_attachment_parser.remote_url }
|
||||
|
|
|
@ -147,9 +147,12 @@ class FetchLinkCardService < BaseService
|
|||
return if html.nil?
|
||||
|
||||
link_details_extractor = LinkDetailsExtractor.new(@url, @html, @html_charset)
|
||||
provider = PreviewCardProvider.matching_domain(Addressable::URI.parse(link_details_extractor.canonical_url).normalized_host)
|
||||
linked_account = ResolveAccountService.new.call(link_details_extractor.author_account, suppress_errors: true) if link_details_extractor.author_account.present? && provider&.trendable?
|
||||
|
||||
@card = PreviewCard.find_or_initialize_by(url: link_details_extractor.canonical_url) if link_details_extractor.canonical_url != @card.url
|
||||
@card.assign_attributes(link_details_extractor.to_preview_card_attributes)
|
||||
@card.author_account = linked_account
|
||||
@card.save_with_optional_image! unless @card.title.blank? && @card.html.blank?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -147,6 +147,9 @@ class NotifyService < BaseService
|
|||
end
|
||||
|
||||
def statuses_that_mention_sender
|
||||
# This queries private mentions from the recipient to the sender up in the thread.
|
||||
# This allows up to 100 messages that do not match in the thread, allowing conversations
|
||||
# involving multiple people.
|
||||
Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @sender.id, depth_limit: 100])
|
||||
WITH RECURSIVE ancestors(id, in_reply_to_id, mention_id, path, depth) AS (
|
||||
SELECT s.id, s.in_reply_to_id, m.id, ARRAY[s.id], 0
|
||||
|
@ -154,16 +157,17 @@ class NotifyService < BaseService
|
|||
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id
|
||||
WHERE s.id = :id
|
||||
UNION ALL
|
||||
SELECT s.id, s.in_reply_to_id, m.id, st.path || s.id, st.depth + 1
|
||||
FROM ancestors st
|
||||
JOIN statuses s ON s.id = st.in_reply_to_id
|
||||
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id
|
||||
WHERE st.mention_id IS NULL AND NOT s.id = ANY(path) AND st.depth < :depth_limit
|
||||
SELECT s.id, s.in_reply_to_id, m.id, ancestors.path || s.id, ancestors.depth + 1
|
||||
FROM ancestors
|
||||
JOIN statuses s ON s.id = ancestors.in_reply_to_id
|
||||
/* early exit if we already have a mention matching our requirements */
|
||||
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id AND s.account_id = :recipient_id
|
||||
WHERE ancestors.mention_id IS NULL AND NOT s.id = ANY(path) AND ancestors.depth < :depth_limit
|
||||
)
|
||||
SELECT COUNT(*)
|
||||
FROM ancestors st
|
||||
JOIN statuses s ON s.id = st.id
|
||||
WHERE st.mention_id IS NOT NULL AND s.visibility = 3
|
||||
FROM ancestors
|
||||
JOIN statuses s ON s.id = ancestors.id
|
||||
WHERE ancestors.mention_id IS NOT NULL AND s.account_id = :recipient_id AND s.visibility = 3
|
||||
SQL
|
||||
end
|
||||
end
|
||||
|
|
|
@ -146,9 +146,9 @@ class PostStatusService < BaseService
|
|||
return
|
||||
end
|
||||
|
||||
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present?
|
||||
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > Status::MEDIA_ATTACHMENTS_LIMIT || @options[:poll].present?
|
||||
|
||||
@media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i))
|
||||
@media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(Status::MEDIA_ATTACHMENTS_LIMIT).map(&:to_i))
|
||||
|
||||
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:audio_or_video?)
|
||||
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if @media.any?(&:not_processed?)
|
||||
|
|
|
@ -81,7 +81,7 @@ class ReportService < BaseService
|
|||
|
||||
# If the account making reports is remote, it is likely anonymized so we have to relax the requirements for attaching statuses.
|
||||
domain = @source_account.domain.to_s.downcase
|
||||
has_followers = @target_account.followers.where(Account.arel_table[:domain].lower.eq(domain)).exists?
|
||||
has_followers = @target_account.followers.with_domain(domain).exists?
|
||||
visibility = has_followers ? %i(public unlisted private) : %i(public unlisted)
|
||||
scope = @target_account.statuses.with_discarded
|
||||
scope.merge!(scope.where(visibility: visibility).or(scope.where('EXISTS (SELECT 1 FROM mentions m JOIN accounts a ON m.account_id = a.id WHERE lower(a.domain) = ?)', domain)))
|
||||
|
|
|
@ -70,9 +70,9 @@ class UpdateStatusService < BaseService
|
|||
def validate_media!
|
||||
return [] if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
|
||||
|
||||
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present?
|
||||
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > Status::MEDIA_ATTACHMENTS_LIMIT || @options[:poll].present?
|
||||
|
||||
media_attachments = @status.account.media_attachments.where(status_id: [nil, @status.id]).where(scheduled_status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i)).to_a
|
||||
media_attachments = @status.account.media_attachments.where(status_id: [nil, @status.id]).where(scheduled_status_id: nil).where(id: @options[:media_ids].take(Status::MEDIA_ATTACHMENTS_LIMIT).map(&:to_i)).to_a
|
||||
|
||||
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if media_attachments.size > 1 && media_attachments.find(&:audio_or_video?)
|
||||
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if media_attachments.any?(&:not_processed?)
|
||||
|
|
|
@ -6,10 +6,7 @@ class UniqueUsernameValidator < ActiveModel::Validator
|
|||
def validate(account)
|
||||
return if account.username.blank?
|
||||
|
||||
normalized_username = account.username.downcase
|
||||
normalized_domain = account.domain&.downcase
|
||||
|
||||
scope = Account.where(Account.arel_table[:username].lower.eq normalized_username).where(Account.arel_table[:domain].lower.eq normalized_domain)
|
||||
scope = Account.with_username(account.username).with_domain(account.domain)
|
||||
scope = scope.where.not(id: account.id) if account.persisted?
|
||||
|
||||
account.errors.add(:username, :taken) if scope.exists?
|
||||
|
|
|
@ -22,7 +22,6 @@ class Scheduler::VacuumScheduler
|
|||
preview_cards_vacuum,
|
||||
backups_vacuum,
|
||||
access_tokens_vacuum,
|
||||
applications_vacuum,
|
||||
feeds_vacuum,
|
||||
imports_vacuum,
|
||||
]
|
||||
|
@ -56,10 +55,6 @@ class Scheduler::VacuumScheduler
|
|||
Vacuum::ImportsVacuum.new
|
||||
end
|
||||
|
||||
def applications_vacuum
|
||||
Vacuum::ApplicationsVacuum.new
|
||||
end
|
||||
|
||||
def content_retention_policy
|
||||
ContentRetentionPolicy.current
|
||||
end
|
||||
|
|
|
@ -48,6 +48,7 @@ require_relative '../lib/chewy/strategy/bypass_with_warning'
|
|||
require_relative '../lib/webpacker/manifest_extensions'
|
||||
require_relative '../lib/webpacker/helper_extensions'
|
||||
require_relative '../lib/rails/engine_extensions'
|
||||
require_relative '../lib/action_dispatch/remote_ip_extensions'
|
||||
require_relative '../lib/active_record/database_tasks_extensions'
|
||||
require_relative '../lib/active_record/batches'
|
||||
require_relative '../lib/simple_navigation/item_extensions'
|
||||
|
|
|
@ -13,7 +13,7 @@ end
|
|||
|
||||
Paperclip.interpolates :prefix_path do |attachment, _style|
|
||||
if attachment.storage_schema_version >= 1 && attachment.instance.respond_to?(:local?) && !attachment.instance.local?
|
||||
'cache' + File::SEPARATOR
|
||||
"cache#{File::SEPARATOR}"
|
||||
else
|
||||
''
|
||||
end
|
||||
|
@ -159,7 +159,7 @@ else
|
|||
Paperclip::Attachment.default_options.merge!(
|
||||
storage: :filesystem,
|
||||
path: File.join(ENV.fetch('PAPERCLIP_ROOT_PATH', File.join(':rails_root', 'public', 'system')), ':prefix_path:class', ':attachment', ':id_partition', ':style', ':filename'),
|
||||
url: ENV.fetch('PAPERCLIP_ROOT_URL', '/system') + '/:prefix_url:class/:attachment/:id_partition/:style/:filename'
|
||||
url: "#{ENV.fetch('PAPERCLIP_ROOT_URL', '/system')}/:prefix_url:class/:attachment/:id_partition/:style/:filename"
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -37,6 +37,10 @@ class Rack::Attack
|
|||
authenticated_token&.id
|
||||
end
|
||||
|
||||
def warden_user_id
|
||||
@env['warden']&.user&.id
|
||||
end
|
||||
|
||||
def unauthenticated?
|
||||
!authenticated_user_id
|
||||
end
|
||||
|
@ -58,10 +62,6 @@ class Rack::Attack
|
|||
end
|
||||
end
|
||||
|
||||
Rack::Attack.safelist('allow from localhost') do |req|
|
||||
req.remote_ip == '127.0.0.1' || req.remote_ip == '::1'
|
||||
end
|
||||
|
||||
Rack::Attack.blocklist('deny from blocklist') do |req|
|
||||
IpBlock.blocked?(req.remote_ip)
|
||||
end
|
||||
|
@ -105,6 +105,10 @@ class Rack::Attack
|
|||
req.authenticated_user_id if (req.post? && req.path.match?(API_DELETE_REBLOG_REGEX)) || (req.delete? && req.path.match?(API_DELETE_STATUS_REGEX))
|
||||
end
|
||||
|
||||
throttle('throttle_oauth_application_registrations/ip', limit: 5, period: 10.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.post? && req.path == '/api/v1/apps'
|
||||
end
|
||||
|
||||
throttle('throttle_sign_up_attempts/ip', limit: 25, period: 5.minutes) do |req|
|
||||
req.throttleable_remote_ip if req.post? && req.path_matches?('/auth')
|
||||
end
|
||||
|
@ -137,6 +141,10 @@ class Rack::Attack
|
|||
req.session[:attempt_user_id] || req.params.dig('user', 'email').presence if req.post? && req.path_matches?('/auth/sign_in')
|
||||
end
|
||||
|
||||
throttle('throttle_password_change/account', limit: 10, period: 10.minutes) do |req|
|
||||
req.warden_user_id if req.put? || (req.patch? && req.path_matches?('/auth'))
|
||||
end
|
||||
|
||||
self.throttled_responder = lambda do |request|
|
||||
now = Time.now.utc
|
||||
match_data = request.env['rack.attack.match_data']
|
||||
|
|
|
@ -282,6 +282,7 @@ ja:
|
|||
update_custom_emoji_html: "%{name}さんがカスタム絵文字 %{target}を更新しました"
|
||||
update_domain_block_html: "%{name}さんが%{target}のドメインブロックを更新しました"
|
||||
update_ip_block_html: "%{name} さんがIP %{target} のルールを更新しました"
|
||||
update_report_html: "%{name}さんが通報 %{target} を更新しました"
|
||||
update_status_html: "%{name}さんが%{target}さんの投稿を更新しました"
|
||||
update_user_role_html: "%{name}さんがロール『%{target}』を変更しました"
|
||||
deleted_account: 削除されたアカウント
|
||||
|
@ -939,6 +940,7 @@ ja:
|
|||
delete: 削除
|
||||
edit_preset: プリセット警告文を編集
|
||||
empty: まだプリセット警告文が作成されていません。
|
||||
title: プリセット警告文
|
||||
webhooks:
|
||||
add_new: エンドポイントを追加
|
||||
delete: 削除
|
||||
|
|
|
@ -291,6 +291,7 @@ lt:
|
|||
update_custom_emoji_html: "%{name} atnaujino jaustuką %{target}"
|
||||
update_domain_block_html: "%{name} atnaujino domeno bloką %{target}"
|
||||
update_ip_block_html: "%{name} pakeitė taisyklę IP %{target}"
|
||||
update_report_html: "%{name} atnaujino ataskaitą %{target}"
|
||||
update_status_html: "%{name} atnaujino įrašą %{target}"
|
||||
update_user_role_html: "%{name} pakeitė %{target} vaidmenį"
|
||||
deleted_account: ištrinta paskyra
|
||||
|
@ -344,6 +345,8 @@ lt:
|
|||
shortcode: Trumpas kodas
|
||||
shortcode_hint: Bent du ženklai, tik raidiniai skaitmeniniai ženklai bei akcentai(_)
|
||||
title: Asmeniniai jaustukai
|
||||
uncategorized: Be kategorijos
|
||||
unlist: Išbraukti iš sąrašo
|
||||
unlisted: Neįtrauktas į sąrašą
|
||||
update_failed_msg: Jaustukas negalėjo būti pakeistas
|
||||
updated_msg: Jaustukas sėkmingai pakeistas!
|
||||
|
@ -391,8 +394,16 @@ lt:
|
|||
created_msg: Domenas buvo sėkmingai leistas federacijai.
|
||||
destroyed_msg: Domenas buvo neleistas federacijai.
|
||||
export: Eksportuoti
|
||||
import: Importuoti
|
||||
undo: Neleisti federavimo su domenu
|
||||
domain_blocks:
|
||||
add_new: Pridėti naują domeno bloką
|
||||
confirm_suspension:
|
||||
cancel: Atšaukti
|
||||
confirm: Pristabdyti
|
||||
permanent_action: Atšaukus pristabdymą jokie duomenys ar sąryšiai nebus atkurti.
|
||||
preamble_html: Jūs pristabdysite <strong>%{domain}</strong> ir jo subdomenus.
|
||||
remove_all_data: Taip iš serverio bus pašalintas visas šio domeno paskyrų turinys, medija ir profilio duomenys.
|
||||
created_msg: Domeno užblokavimas nagrinėjamas
|
||||
destroyed_msg: Domeno blokas pašalintas
|
||||
domain: Domenas
|
||||
|
@ -410,6 +421,7 @@ lt:
|
|||
silence: Riboti
|
||||
suspend: Pristabdyti
|
||||
title: Naujos domeno blokas
|
||||
private_comment: Privatus komentaras
|
||||
public_comment: Viešas komentaras
|
||||
public_comment_hint: Komentaras apie šį domeno apribojimą plačiajai visuomenei, jei įjungtas domenų apribojimų sąrašo reklamavimas.
|
||||
reject_media: Atmesti medijos failus
|
||||
|
@ -417,6 +429,7 @@ lt:
|
|||
reject_reports: Atmesti ataskaitas
|
||||
reject_reports_hint: Ignoruoti visus skundus, kurie siunčiami iš šio domeno. Neliečia užblokavimu
|
||||
undo: Atkurti domeno bloką
|
||||
view: Peržiūrėti domeno bloką
|
||||
email_domain_blocks:
|
||||
add_new: Pridėti naują
|
||||
allow_registrations_with_approval: Leisti registracijas su patvirtinimu
|
||||
|
@ -428,10 +441,16 @@ lt:
|
|||
title: Naujas el pašto juodojo sąrašo įtraukimas
|
||||
title: El pašto juodasis sąrašas
|
||||
instances:
|
||||
availability:
|
||||
title: Prieinamumas
|
||||
back_to_all: Visi
|
||||
back_to_limited: Apribotas
|
||||
back_to_warning: Įspėjimas
|
||||
by_domain: Domenas
|
||||
content_policies:
|
||||
policy: Politika
|
||||
reason: Viešoji priežastis
|
||||
title: Turinio politika
|
||||
delivery:
|
||||
all: Visi
|
||||
delivery_available: Pristatymas galimas
|
||||
|
@ -624,6 +643,7 @@ lt:
|
|||
add_new: Pridėti naują
|
||||
delete: Ištrinti
|
||||
edit_preset: Keisti įspėjimo nustatymus
|
||||
title: Įspėjamieji numatytieji
|
||||
webhooks:
|
||||
description_html: "<strong>Webhook</strong> leidžia Mastodon siųsti <strong>realaus laiko pranešimus</strong> apie pasirinktus įvykius į tavo programą, kad programa galėtų <strong>automatiškai paleisti reakcijas</strong>."
|
||||
events: Įvykiai
|
||||
|
|
|
@ -461,13 +461,13 @@ nn:
|
|||
title: Importer domeneblokkeringar
|
||||
no_file: Inga fil vald
|
||||
follow_recommendations:
|
||||
description_html: "<strong>Følgjeforslag hjelper nye brukarar å raskt finna interessant innhald</strong>. Om ein brukar ikkje har interagera nok med andre til å danne personlege følgjeforslag, vert disse kontiane føreslått i staden. Dei vert gjenkalkulert på dagleg basis ut frå ei blanding av dei konti med flest nylege engasjement og flest lokale følgjarar for eit gitt språk."
|
||||
description_html: "<strong>Fylgjeforslag hjelper nye brukarar å finna interessant innhald raskt</strong>. Om ein brukar ikkje har samhandla nok med andre til å få tilpassa fylgjeforslag, blir desse kontoane føreslått i staden. Dei blir rekna ut på nytt kvar dag ut frå ei blanding av kva kontoar som har mykje nyleg aktivitet og høgast tal på fylgjarar på eit bestemt språk."
|
||||
language: For språk
|
||||
status: Status
|
||||
suppress: Demp følgjeforslag
|
||||
suppressed: Dempa
|
||||
title: Følgjeforslag
|
||||
unsuppress: Tilbakestill følgjeforslag
|
||||
title: Fylgjeforslag
|
||||
unsuppress: Nullstill fylgjeforslag
|
||||
instances:
|
||||
availability:
|
||||
description_html:
|
||||
|
@ -746,7 +746,7 @@ nn:
|
|||
preamble: Tilpasse web-grensesnittet.
|
||||
title: Utsjånad
|
||||
branding:
|
||||
preamble: Profileringa av tenaren din skil den frå andre tenarar i nettverket. Informasjonen kan bli vist ulike stadar, til dømes i Mastodon sitt web-grensesnitt, i eigne applikasjonar, i førehandsvisningar på andre nettsider, i meldingsappar og så bortetter. På grunn av dette er det best å halde informasjonen enkel, kort og treffande.
|
||||
preamble: Profileringa av tenaren din skil den frå andre tenarar i nettverket. Informasjonen kan bli vist ulike stader, til dømes i Mastodon sitt web-grensesnitt, i eigne applikasjonar, i førehandsvisningar på andre nettsider, i meldingsappar og så bortetter. På grunn av dette er det best at denne informasjonen er enkel, kort og treffande.
|
||||
title: Profilering
|
||||
captcha_enabled:
|
||||
desc_html: Dette baserer seg på eksterne skript frå hCaptcha, noko som kan vera eit tryggleiks- og personvernsproblem. <strong>I tillegg kan dette gjera registreringsprosessen monaleg mindre tilgjengeleg (særleg for folk med nedsett funksjonsevne)</strong>. Dette gjer at du bør du vurdera alternative tiltak, som til dømes godkjennings- eller invitasjonsbasert registrering.
|
||||
|
@ -759,7 +759,7 @@ nn:
|
|||
desc_html: Påverkar alle brukarar som ikkje har justert denne innstillinga sjølve
|
||||
title: Ikkje la brukarar indekserast av søkjemotorar som standard
|
||||
discovery:
|
||||
follow_recommendations: Følgjeforslag
|
||||
follow_recommendations: Fylgjeforslag
|
||||
preamble: Å framheva interessant innhald er vitalt i mottakinga av nye brukarar som ikkje nødvendigvis kjenner nokon på Mastodon. Kontroller korleis oppdagingsfunksjonane på tenaren din fungerar.
|
||||
profile_directory: Profilkatalog
|
||||
public_timelines: Offentlege tidsliner
|
||||
|
@ -1562,7 +1562,7 @@ nn:
|
|||
activity: Kontoaktivitet
|
||||
confirm_follow_selected_followers: Er du sikker på at du ynskjer å fylgja dei valde fylgjarane?
|
||||
confirm_remove_selected_followers: Er du sikker på at du ynskjer å fjerna dei valde fylgjarane?
|
||||
confirm_remove_selected_follows: Er du sikker på at du ynskjer å fjerna det valde følgjet?
|
||||
confirm_remove_selected_follows: Er du sikker på at du ikkje vil fylgja desse?
|
||||
dormant: I dvale
|
||||
follow_failure: Greidde ikkje fylgja alle kontoane du valde.
|
||||
follow_selected_followers: Følg valgte tilhengere
|
||||
|
|
|
@ -285,6 +285,7 @@ pt-BR:
|
|||
update_custom_emoji_html: "%{name} atualizou o emoji %{target}"
|
||||
update_domain_block_html: "%{name} atualizou o bloqueio de domínio de %{target}"
|
||||
update_ip_block_html: "%{name} alterou a regra para o IP %{target}"
|
||||
update_report_html: "%{name} atualizou o relatório %{target}"
|
||||
update_status_html: "%{name} atualizou a publicação de %{target}"
|
||||
update_user_role_html: "%{name} alterou o cargo %{target}"
|
||||
deleted_account: conta excluída
|
||||
|
@ -950,6 +951,7 @@ pt-BR:
|
|||
delete: Excluir
|
||||
edit_preset: Editar o aviso pré-definido
|
||||
empty: Você ainda não definiu nenhuma predefinição de alerta.
|
||||
title: Predefinições de aviso
|
||||
webhooks:
|
||||
add_new: Adicionar endpoint
|
||||
delete: Excluir
|
||||
|
|
|
@ -66,7 +66,7 @@ si:
|
|||
inbox_url: එන ලිපි URL
|
||||
invite_request_text: එක්වීමට හේතුව
|
||||
invited_by: විසින් ආරාධනා කරන ලදී
|
||||
ip: අ.ජා. කෙ. (IP)
|
||||
ip: අ.ජා.කෙ. (IP)
|
||||
joined: එක් වූ දිනය
|
||||
location:
|
||||
all: සියල්ල
|
||||
|
@ -87,7 +87,7 @@ si:
|
|||
title: මැදිහත්කරණය
|
||||
moderation_notes: මැදිහත්කරණ සටහන්
|
||||
most_recent_activity: වඩාත්ම මෑත ක්රියාකාරිත්වය
|
||||
most_recent_ip: මෑත අ.ජා.කෙ. (IP)
|
||||
most_recent_ip: මෑත අ.ජා.කෙ.
|
||||
no_account_selected: කිසිවක් තෝරා නොගත් බැවින් ගිණුම් කිසිවක් වෙනස් කර නැත
|
||||
no_limits_imposed: සීමාවන් පනවා නැත
|
||||
not_subscribed: දායක වී නැත
|
||||
|
@ -160,7 +160,7 @@ si:
|
|||
create_custom_emoji: අභිරුචි ඉමොජි සාදන්න
|
||||
create_domain_allow: වසමකට ඉඩදීම සාදන්න
|
||||
create_email_domain_block: ඊමේල් ඩොමේන් බ්ලොක් එකක් සාදන්න
|
||||
create_ip_block: අ.ජා. කෙ. (IP) නීතියක් සාදන්න
|
||||
create_ip_block: අ.ජා.කෙ. නීතියක් සාදන්න
|
||||
create_unavailable_domain: ලබා ගත නොහැකි වසම සාදන්න
|
||||
create_user_role: භූමිකාව සාදන්න
|
||||
demote_user: පරිශීලකයා පහත් කරන්න
|
||||
|
@ -473,7 +473,7 @@ si:
|
|||
new:
|
||||
title: නව අ.ජා.කෙ. නීතියක් සාදන්න
|
||||
no_ip_block_selected: IP රීති කිසිවක් තෝරා නොගත් බැවින් වෙනස් කර නැත
|
||||
title: අ.ජා. කෙ. (IP) නීති
|
||||
title: අ.ජා.කෙ. (IP) නීති
|
||||
relationships:
|
||||
title: "%{acct}හි සබඳතා"
|
||||
relays:
|
||||
|
@ -1239,7 +1239,7 @@ si:
|
|||
current_session: වත්මන් වාරය
|
||||
description: "%{platform} හි %{browser}"
|
||||
explanation: ඔබගේ මාස්ටඩන් ගිණුමට පිවිසීම සඳහා භාවිතා කර තිබෙන අතිරික්සු.
|
||||
ip: අ.ජා. කෙ. (IP)
|
||||
ip: අ.ජා.කෙ.
|
||||
platforms:
|
||||
adobe_air: ඇඩෝබි එයාර්
|
||||
android: ඇන්ඩ්රොයිඩ්
|
||||
|
@ -1399,7 +1399,7 @@ si:
|
|||
details: 'ප්රවේශයට අදාළ විස්තර:'
|
||||
explanation: ඔබගේ ගිණුමට නව අ.ජා.කෙ. (IP) ලිපිනයකින් ප්රවේශයක් අනාවරණය වී ඇත.
|
||||
further_actions_html: මේ ඔබ නොවේ නම්, වහාම %{action}. ඔබගේ ගිණුම සුරක්ෂිතව තබා ගැනීමට ද්වි-සාධකය සබල කරන්න.
|
||||
subject: ඔබගේ ගිණුමට නව අ.ජා.කෙ. (IP) ලිපිනයකින් ප්රවේශ වී ඇත
|
||||
subject: ඔබගේ ගිණුමට නව අ.ජා.කෙ. ලිපිනයකින් ප්රවේශ වී ඇත
|
||||
title: නව ප්රවේශයක්
|
||||
warning:
|
||||
appeal: අභියාචනයක් ඉදිරිපත් කරන්න
|
||||
|
|
|
@ -74,8 +74,10 @@ lt:
|
|||
warn: Slėpti filtruojamą turinį po įspėjimu, paminint filtro pavadinimą
|
||||
form_admin_settings:
|
||||
activity_api_enabled: Vietinių paskelbtų įrašų, aktyvių naudotojų ir naujų registracijų skaičiai kas savaitę
|
||||
app_icon: WEBP, PNG, GIF arba JPG. Pakeičia numatytąją programos piktogramą mobiliuosiuose įrenginiuose pasirinktine piktograma.
|
||||
backups_retention_period: Naudotojai gali generuoti savo įrašų archyvus, kuriuos vėliau galės atsisiųsti. Nustačius teigiamą reikšmę, šie archyvai po nurodyto dienų skaičiaus bus automatiškai ištrinti iš saugyklos.
|
||||
content_cache_retention_period: Visi įrašai iš kitų serverių (įskaitant pakėlimus ir atsakymus) bus ištrinti po nurodyto dienų skaičiaus, neatsižvelgiant į bet kokią vietinio naudotojo sąveiką su tais įrašais. Tai taikoma ir tiems įrašams, kuriuos vietinis naudotojas yra pažymėjęs kaip žymes ar mėgstamus. Privačios paminėjimai tarp naudotojų iš skirtingų instancijų taip pat bus prarastos ir jų bus neįmanoma atkurti. Šis nustatymas skirtas naudoti ypatingos paskirties instancijose, o įgyvendinus jį bendram naudojimui, pažeidžiami daugelio naudotojų lūkesčiai.
|
||||
favicon: WEBP, PNG, GIF arba JPG. Pakeičia numatytąją Mastodon svetaines piktogramą pasirinktine piktograma.
|
||||
mascot: Pakeičia išplėstinės žiniatinklio sąsajos iliustraciją.
|
||||
media_cache_retention_period: Nuotolinių naudotojų įrašytų įrašų medijos failai talpinami tavo serveryje. Nustačius teigiamą reikšmę, medijos bus ištrinamos po nurodyto dienų skaičiaus. Jei medijos duomenų bus paprašyta po to, kai jie bus ištrinti, jie bus atsiųsti iš naujo, jei šaltinio turinys vis dar prieinamas. Dėl apribojimų, susijusių su nuorodų peržiūros kortelių apklausos dažnumu trečiųjų šalių svetainėse, rekomenduojama nustatyti šią reikšmę ne trumpesnę kaip 14 dienų, kitaip nuorodų peržiūros kortelės nebus atnaujinamos pagal pareikalavimą iki to laiko.
|
||||
peers_api_enabled: Domenų pavadinimų sąrašas, su kuriais šis serveris susidūrė fediverse. Čia nėra duomenų apie tai, ar tu bendrauji su tam tikru serveriu, tik apie tai, kad tavo serveris apie jį žino. Tai naudojama tarnybose, kurios renka federacijos statistiką bendrąja prasme.
|
||||
|
|
|
@ -8,8 +8,8 @@ nn:
|
|||
fields: Heimesida di, pronomen, alder, eller kva du måtte ynskje.
|
||||
indexable: Dei offentlege innlegga dine kan dukka opp i søkjeresultat på Mastodon. Folk som har reagert på oinnlegga dine kan uansett søkja gjennom dei.
|
||||
note: 'Du kan @nemne folk eller #emneknaggar.'
|
||||
show_collections: Andre kan sjå kven du følgjer og kven som følgjer deg. Dei du følgjer kan alltid sjå at du følgjer dei.
|
||||
unlocked: Alle kan følgje deg utan å måtte spørje om det. Vel bort om du vil gå gjennom førespurnadar om å følgje deg og seie ja eller nei.
|
||||
show_collections: Andre kan sjå kven du fylgjer og kven som fylgjer deg. Dei du fylgjer kan alltid sjå at du fylgjer dei.
|
||||
unlocked: Alle kan fylgja deg utan å måtta be om det. Vel bort dersom du vil gå gjennom førespurnader om å fylgja deg og seia ja eller nei til kvar av dei.
|
||||
account_alias:
|
||||
acct: Angi brukarnamn@domene til brukaren du ynskjer å flytta frå
|
||||
account_migration:
|
||||
|
@ -148,7 +148,7 @@ nn:
|
|||
name: Merkelapp
|
||||
value: Innhald
|
||||
indexable: Ta med offentlege innlegg i søkjeresultat
|
||||
show_collections: Vis følgjer og følgjare på profilen
|
||||
show_collections: Vis dei du fylgjer og dei som fylgjer deg på profilen din
|
||||
unlocked: Godta nye følgjare automatisk
|
||||
account_alias:
|
||||
acct: Brukarnamnet på den gamle kontoen
|
||||
|
|
|
@ -190,7 +190,7 @@ si:
|
|||
text: ඔබට එක් වීමට අවශ්ය ඇයි?
|
||||
ip_block:
|
||||
comment: අදහස
|
||||
ip: අ.ජා. කෙ. (IP)
|
||||
ip: අ.ජා.කෙ. (IP)
|
||||
severities:
|
||||
no_access: ප්රවේශය අවහිර කරන්න
|
||||
sign_up_requires_approval: ලියාපදිංචි වීම සීමා කරන්න
|
||||
|
|
|
@ -77,10 +77,15 @@ uk:
|
|||
warn: Сховати відфільтрований вміст за попередженням, у якому вказано заголовок фільтра
|
||||
form_admin_settings:
|
||||
activity_api_enabled: Кількість локальних опублікованих дописів, активних і нових користувачів у тижневих розрізах
|
||||
app_icon: WEBP, PNG, GIF або JPG. Замінює іконку програми за замовчуванням на мобільних пристроях на власну іконку.
|
||||
backups_retention_period: Користувачі мають можливість створювати архіви своїх дописів, щоб завантажити їх пізніше. Якщо встановлено додатне значення, ці архіви будуть автоматично видалені з вашого сховища через вказану кількість днів.
|
||||
bootstrap_timeline_accounts: Ці облікові записи будуть закріплені в топі пропозицій для нових користувачів.
|
||||
closed_registrations_message: Показується, коли реєстрація закрита
|
||||
content_cache_retention_period: Усі дописи з інших серверів (включно з коментарями та відповідями) будуть видалені через певну кількість днів, незважаючи на будь-яку локальну взаємодію користувачів з цими дописами. Сюди входять дописи, які локальний користувач позначив як закладки або вибране. Приватні згадки між користувачами з різних інстанцій також будуть втрачені і не підлягатимуть відновленню. Використання цього параметра призначено для екземплярів спеціального призначення і порушує багато очікувань користувачів, якщо його застосовано для загального використання.
|
||||
custom_css: Ви можете застосувати користувацькі стилі у вебверсії Mastodon.
|
||||
favicon: WEBP, PNG, GIF або JPG. Замінює стандартну піктограму Mastodon на власну піктограму.
|
||||
mascot: Змінює ілюстрацію в розширеному вебінтерфейсі.
|
||||
media_cache_retention_period: Медіафайли з дописів віддалених користувачів кешуються на вашому сервері. Якщо встановлено додатне значення, медіа буде видалено через вказану кількість днів. Якщо медіа-дані будуть запитані після видалення, вони будуть завантажені повторно, якщо вихідний вміст все ще доступний. Через обмеження на частоту опитування карток попереднього перегляду посилань на сторонніх сайтах, рекомендується встановити це значення не менше 14 днів, інакше картки попереднього перегляду посилань не будуть оновлюватися на вимогу раніше цього часу.
|
||||
peers_api_enabled: Список доменів імен цього сервера з'явився у федівсесвіті. Сюди не входять дані чи ви пов'язані федерацією з цим сервером, а лише відомості, що вашому серверу відомо про нього. Його використовують служби, які збирають загальну статистику про федерації.
|
||||
profile_directory: У каталозі профілів перераховані всі користувачі, які погодились бути видимими.
|
||||
require_invite_text: Якщо реєстрація вимагає власноручного затвердження, зробіть текстове поле «Чому ви хочете приєднатися?» обов'язковим, а не додатковим
|
||||
|
|
|
@ -934,6 +934,7 @@ th:
|
|||
delete: ลบ
|
||||
edit_preset: แก้ไขคำเตือนที่ตั้งไว้ล่วงหน้า
|
||||
empty: คุณยังไม่ได้กำหนดคำเตือนที่ตั้งไว้ล่วงหน้าใด ๆ
|
||||
title: คำเตือนที่ตั้งไว้ล่วงหน้า
|
||||
webhooks:
|
||||
add_new: เพิ่มปลายทาง
|
||||
delete: ลบ
|
||||
|
|
|
@ -291,6 +291,7 @@ uk:
|
|||
update_custom_emoji_html: "%{name} оновлює емодзі %{target}"
|
||||
update_domain_block_html: "%{name} оновлює блокування домену для %{target}"
|
||||
update_ip_block_html: "%{name} змінює правило для IP %{target}"
|
||||
update_report_html: "%{name} оновлений звіт %{target}"
|
||||
update_status_html: "%{name} оновлює допис %{target}"
|
||||
update_user_role_html: "%{name} змінює роль %{target}"
|
||||
deleted_account: видалений обліковий запис
|
||||
|
@ -984,6 +985,7 @@ uk:
|
|||
delete: Видалити
|
||||
edit_preset: Редагувати шаблон попередження
|
||||
empty: Ви ще не визначили жодних попереджень.
|
||||
title: Попереджувальні пресети
|
||||
webhooks:
|
||||
add_new: Додати кінцеву точку
|
||||
delete: Видалити
|
||||
|
|
|
@ -934,6 +934,7 @@ vi:
|
|||
delete: Xóa bỏ
|
||||
edit_preset: Sửa mẫu có sẵn
|
||||
empty: Bạn chưa thêm mẫu cảnh cáo nào cả.
|
||||
title: Cảnh báo cài sẵn
|
||||
webhooks:
|
||||
add_new: Thêm endpoint
|
||||
delete: Xóa bỏ
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddAuthorAccountIdToPreviewCards < ActiveRecord::Migration[7.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def change
|
||||
safety_assured { add_reference :preview_cards, :author_account, null: true, foreign_key: { to_table: 'accounts', on_delete: :nullify }, index: false }
|
||||
add_index :preview_cards, :author_account_id, algorithm: :concurrently, where: 'author_account_id IS NOT NULL'
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.1].define(version: 2024_05_10_192043) do
|
||||
ActiveRecord::Schema[7.1].define(version: 2024_05_22_041528) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
|
@ -877,6 +877,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_10_192043) do
|
|||
t.integer "link_type"
|
||||
t.datetime "published_at"
|
||||
t.string "image_description", default: "", null: false
|
||||
t.bigint "author_account_id"
|
||||
t.index ["author_account_id"], name: "index_preview_cards_on_author_account_id", where: "(author_account_id IS NOT NULL)"
|
||||
t.index ["url"], name: "index_preview_cards_on_url", unique: true
|
||||
end
|
||||
|
||||
|
@ -1367,6 +1369,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_10_192043) do
|
|||
add_foreign_key "polls", "accounts", on_delete: :cascade
|
||||
add_foreign_key "polls", "statuses", on_delete: :cascade
|
||||
add_foreign_key "preview_card_trends", "preview_cards", on_delete: :cascade
|
||||
add_foreign_key "preview_cards", "accounts", column: "author_account_id", on_delete: :nullify
|
||||
add_foreign_key "report_notes", "accounts", on_delete: :cascade
|
||||
add_foreign_key "report_notes", "reports", on_delete: :cascade
|
||||
add_foreign_key "reports", "accounts", column: "action_taken_by_account_id", name: "fk_bca45b75fd", on_delete: :nullify
|
||||
|
|
|
@ -55,7 +55,7 @@ services:
|
|||
|
||||
web:
|
||||
build: .
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.7
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.9
|
||||
restart: always
|
||||
env_file: .env.production
|
||||
command: bundle exec puma -C config/puma.rb
|
||||
|
@ -76,7 +76,7 @@ services:
|
|||
|
||||
streaming:
|
||||
build: .
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.7
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.9
|
||||
restart: always
|
||||
env_file: .env.production
|
||||
command: node ./streaming
|
||||
|
@ -94,7 +94,7 @@ services:
|
|||
|
||||
sidekiq:
|
||||
build: .
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.7
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.9
|
||||
restart: always
|
||||
env_file: .env.production
|
||||
command: bundle exec sidekiq
|
||||
|
|
72
lib/action_dispatch/remote_ip_extensions.rb
Normal file
72
lib/action_dispatch/remote_ip_extensions.rb
Normal file
|
@ -0,0 +1,72 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Mastodon is not made to be directly accessed without a reverse proxy.
|
||||
# This monkey-patch prevents remote IP address spoofing when being accessed
|
||||
# directly.
|
||||
#
|
||||
# See PR: https://github.com/rails/rails/pull/51610
|
||||
|
||||
# In addition to the PR above, it also raises an error if a request with
|
||||
# `X-Forwarded-For` or `Client-Ip` comes directly from a client without
|
||||
# going through a trusted proxy.
|
||||
|
||||
# rubocop:disable all -- This is a mostly vendored file
|
||||
|
||||
module ActionDispatch
|
||||
class RemoteIp
|
||||
module GetIpExtensions
|
||||
def calculate_ip
|
||||
# Set by the Rack web server, this is a single value.
|
||||
remote_addr = ips_from(@req.remote_addr).last
|
||||
|
||||
# Could be a CSV list and/or repeated headers that were concatenated.
|
||||
client_ips = ips_from(@req.client_ip).reverse!
|
||||
forwarded_ips = ips_from(@req.x_forwarded_for).reverse!
|
||||
|
||||
# `Client-Ip` and `X-Forwarded-For` should not, generally, both be set. If they
|
||||
# are both set, it means that either:
|
||||
#
|
||||
# 1) This request passed through two proxies with incompatible IP header
|
||||
# conventions.
|
||||
#
|
||||
# 2) The client passed one of `Client-Ip` or `X-Forwarded-For`
|
||||
# (whichever the proxy servers weren't using) themselves.
|
||||
#
|
||||
# Either way, there is no way for us to determine which header is the right one
|
||||
# after the fact. Since we have no idea, if we are concerned about IP spoofing
|
||||
# we need to give up and explode. (If you're not concerned about IP spoofing you
|
||||
# can turn the `ip_spoofing_check` option off.)
|
||||
should_check_ip = @check_ip && client_ips.last && forwarded_ips.last
|
||||
if should_check_ip && !forwarded_ips.include?(client_ips.last)
|
||||
# We don't know which came from the proxy, and which from the user
|
||||
raise IpSpoofAttackError, "IP spoofing attack?! " \
|
||||
"HTTP_CLIENT_IP=#{@req.client_ip.inspect} " \
|
||||
"HTTP_X_FORWARDED_FOR=#{@req.x_forwarded_for.inspect}"
|
||||
end
|
||||
|
||||
# NOTE: Mastodon addition to make sure we don't get requests from a non-trusted client
|
||||
if @check_ip && (forwarded_ips.last || client_ips.last) && !@proxies.any? { |proxy| proxy === remote_addr }
|
||||
raise IpSpoofAttackError, "IP spoofing attack?! client #{remote_addr} is not a trusted proxy " \
|
||||
"HTTP_CLIENT_IP=#{@req.client_ip.inspect} " \
|
||||
"HTTP_X_FORWARDED_FOR=#{@req.x_forwarded_for.inspect}"
|
||||
end
|
||||
|
||||
# We assume these things about the IP headers:
|
||||
#
|
||||
# - X-Forwarded-For will be a list of IPs, one per proxy, or blank
|
||||
# - Client-Ip is propagated from the outermost proxy, or is blank
|
||||
# - REMOTE_ADDR will be the IP that made the request to Rack
|
||||
ips = forwarded_ips + client_ips
|
||||
ips.compact!
|
||||
|
||||
# If every single IP option is in the trusted list, return the IP that's
|
||||
# furthest away
|
||||
filter_proxies([remote_addr] + ips).first || ips.last || remote_addr
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActionDispatch::RemoteIp::GetIp.prepend(ActionDispatch::RemoteIp::GetIpExtensions)
|
||||
|
||||
# rubocop:enable all
|
|
@ -8,6 +8,7 @@ class Mastodon::SidekiqMiddleware
|
|||
rescue Mastodon::HostValidationError
|
||||
# Do not retry
|
||||
rescue => e
|
||||
clean_up_elasticsearch_connections!
|
||||
limit_backtrace_and_raise(e)
|
||||
ensure
|
||||
clean_up_sockets!
|
||||
|
@ -25,6 +26,32 @@ class Mastodon::SidekiqMiddleware
|
|||
clean_up_statsd_socket!
|
||||
end
|
||||
|
||||
# This is a hack to immediately free up unused Elasticsearch connections.
|
||||
#
|
||||
# Indeed, Chewy creates one `Elasticsearch::Client` instance per thread,
|
||||
# and each such client manages its long-lasting connection to
|
||||
# Elasticsearch.
|
||||
#
|
||||
# As far as I know, neither `chewy`, `elasticsearch-transport` or even
|
||||
# `faraday` provide a reliable way to immediately close a connection, and
|
||||
# rely on the underlying object to be garbage-collected instead.
|
||||
#
|
||||
# Furthermore, `sidekiq` creates a new thread each time a job throws an
|
||||
# exception, meaning that each failure will create a new connection, and
|
||||
# the old one will only be closed on full garbage collection.
|
||||
def clean_up_elasticsearch_connections!
|
||||
return unless Chewy.enabled? && Chewy.current[:chewy_client].present?
|
||||
|
||||
Chewy.client.transport.transport.connections.each do |connection|
|
||||
# NOTE: This bit of code is tailored for the HTTPClient Faraday adapter
|
||||
connection.connection.app.instance_variable_get(:@client)&.reset_all
|
||||
end
|
||||
|
||||
Chewy.current.delete(:chewy_client)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
def clean_up_redis_socket!
|
||||
RedisConfiguration.pool.checkin if Thread.current[:redis]
|
||||
Thread.current[:redis] = nil
|
||||
|
|
|
@ -17,7 +17,7 @@ module Mastodon
|
|||
end
|
||||
|
||||
def default_prerelease
|
||||
'alpha.3'
|
||||
'alpha.4'
|
||||
end
|
||||
|
||||
def prerelease
|
||||
|
@ -25,7 +25,7 @@ module Mastodon
|
|||
end
|
||||
|
||||
def catstodon_revision
|
||||
'1.2.7'
|
||||
'1.0.0'
|
||||
end
|
||||
|
||||
def build_metadata
|
||||
|
|
|
@ -181,7 +181,7 @@
|
|||
"eslint-plugin-import": "~2.29.0",
|
||||
"eslint-plugin-jsdoc": "^48.0.0",
|
||||
"eslint-plugin-jsx-a11y": "~6.8.0",
|
||||
"eslint-plugin-promise": "~6.1.1",
|
||||
"eslint-plugin-promise": "~6.2.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"husky": "^9.0.11",
|
||||
|
|
|
@ -56,7 +56,7 @@ describe Rack::Attack, type: :request do
|
|||
end
|
||||
|
||||
def throttle_count
|
||||
described_class.cache.read("#{counter_prefix}:#{throttle}:#{remote_ip}") || 0
|
||||
described_class.cache.read("#{counter_prefix}:#{throttle}:#{discriminator}") || 0
|
||||
end
|
||||
|
||||
def counter_prefix
|
||||
|
@ -64,11 +64,12 @@ describe Rack::Attack, type: :request do
|
|||
end
|
||||
|
||||
def increment_counter
|
||||
described_class.cache.count("#{throttle}:#{remote_ip}", period)
|
||||
described_class.cache.count("#{throttle}:#{discriminator}", period)
|
||||
end
|
||||
end
|
||||
|
||||
let(:remote_ip) { '1.2.3.5' }
|
||||
let(:discriminator) { remote_ip }
|
||||
|
||||
describe 'throttle excessive sign-up requests by IP address' do
|
||||
context 'when accessed through the website' do
|
||||
|
@ -131,4 +132,48 @@ describe Rack::Attack, type: :request do
|
|||
it_behaves_like 'throttled endpoint'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'throttle excessive oauth application registration requests by IP address' do
|
||||
let(:throttle) { 'throttle_oauth_application_registrations/ip' }
|
||||
let(:limit) { 5 }
|
||||
let(:period) { 10.minutes }
|
||||
let(:path) { '/api/v1/apps' }
|
||||
let(:params) do
|
||||
{
|
||||
client_name: 'Throttle Test',
|
||||
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
||||
scopes: 'read',
|
||||
}
|
||||
end
|
||||
|
||||
let(:request) { -> { post path, params: params, headers: { 'REMOTE_ADDR' => remote_ip } } }
|
||||
|
||||
it_behaves_like 'throttled endpoint'
|
||||
end
|
||||
|
||||
describe 'throttle excessive password change requests by account' do
|
||||
let(:user) { Fabricate(:user, email: 'user@host.example') }
|
||||
let(:throttle) { 'throttle_password_change/account' }
|
||||
let(:limit) { 10 }
|
||||
let(:period) { 10.minutes }
|
||||
let(:request) { -> { put path, headers: { 'REMOTE_ADDR' => remote_ip } } }
|
||||
let(:path) { '/auth' }
|
||||
let(:discriminator) { user.id }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
|
||||
# Unfortunately, devise's `sign_in` helper causes the `session` to be
|
||||
# loaded in the next request regardless of whether it's actually accessed
|
||||
# by the client code.
|
||||
#
|
||||
# So, we make an extra query to clear issue a session cookie instead.
|
||||
#
|
||||
# A less resource-intensive way to deal with that would be to generate the
|
||||
# session cookie manually, but this seems pretty involved.
|
||||
get '/'
|
||||
end
|
||||
|
||||
it_behaves_like 'throttled endpoint'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Vacuum::ApplicationsVacuum do
|
||||
subject { described_class.new }
|
||||
|
||||
describe '#perform' do
|
||||
let!(:app_with_token) { Fabricate(:application, created_at: 1.month.ago) }
|
||||
let!(:app_with_grant) { Fabricate(:application, created_at: 1.month.ago) }
|
||||
let!(:app_with_signup) { Fabricate(:application, created_at: 1.month.ago) }
|
||||
let!(:app_with_owner) { Fabricate(:application, created_at: 1.month.ago, owner: Fabricate(:user)) }
|
||||
let!(:unused_app) { Fabricate(:application, created_at: 1.month.ago) }
|
||||
let!(:recent_app) { Fabricate(:application, created_at: 1.hour.ago) }
|
||||
|
||||
before do
|
||||
Fabricate(:access_token, application: app_with_token)
|
||||
Fabricate(:access_grant, application: app_with_grant)
|
||||
Fabricate(:user, created_by_application: app_with_signup)
|
||||
|
||||
subject.perform
|
||||
end
|
||||
|
||||
it 'does not delete applications with valid access tokens' do
|
||||
expect { app_with_token.reload }.to_not raise_error
|
||||
end
|
||||
|
||||
it 'does not delete applications with valid access grants' do
|
||||
expect { app_with_grant.reload }.to_not raise_error
|
||||
end
|
||||
|
||||
it 'does not delete applications that were used to create users' do
|
||||
expect { app_with_signup.reload }.to_not raise_error
|
||||
end
|
||||
|
||||
it 'does not delete owned applications' do
|
||||
expect { app_with_owner.reload }.to_not raise_error
|
||||
end
|
||||
|
||||
it 'does not delete applications registered less than a day ago' do
|
||||
expect { recent_app.reload }.to_not raise_error
|
||||
end
|
||||
|
||||
it 'deletes unused applications' do
|
||||
expect { unused_app.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,13 +8,13 @@ describe '/api/v1/accounts' do
|
|||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/accounts?ids[]=:id' do
|
||||
describe 'GET /api/v1/accounts?id[]=:id' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:other_account) { Fabricate(:account) }
|
||||
let(:scopes) { 'read:accounts' }
|
||||
|
||||
it 'returns expected response' do
|
||||
get '/api/v1/accounts', headers: headers, params: { ids: [account.id, other_account.id, 123_123] }
|
||||
get '/api/v1/accounts', headers: headers, params: { id: [account.id, other_account.id, 123_123] }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to contain_exactly(
|
||||
|
|
|
@ -9,13 +9,13 @@ describe '/api/v1/statuses' do
|
|||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, application: client_app, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/statuses?ids[]=:id' do
|
||||
describe 'GET /api/v1/statuses?id[]=:id' do
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:other_status) { Fabricate(:status) }
|
||||
let(:scopes) { 'read:statuses' }
|
||||
|
||||
it 'returns expected response' do
|
||||
get '/api/v1/statuses', headers: headers, params: { ids: [status.id, other_status.id, 123_123] }
|
||||
get '/api/v1/statuses', headers: headers, params: { id: [status.id, other_status.id, 123_123] }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to contain_exactly(
|
||||
|
|
|
@ -45,7 +45,7 @@ describe 'Instances' do
|
|||
),
|
||||
statuses: include(
|
||||
max_characters: StatusLengthValidator::MAX_CHARS,
|
||||
max_media_attachments: 4 # TODO, move to constant somewhere
|
||||
max_media_attachments: Status::MEDIA_ATTACHMENTS_LIMIT
|
||||
),
|
||||
polls: include(
|
||||
max_options: PollValidator::MAX_OPTIONS
|
||||
|
|
|
@ -309,6 +309,19 @@ RSpec.describe NotifyService do
|
|||
expect(subject.filter?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the sender is mentioned in an unrelated message chain' do
|
||||
before do
|
||||
original_status = Fabricate(:status, visibility: :direct)
|
||||
intermediary_status = Fabricate(:status, visibility: :direct, thread: original_status)
|
||||
notification.target_status.update(thread: intermediary_status)
|
||||
Fabricate(:mention, status: original_status, account: notification.from_account)
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
expect(subject.filter?).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -228,14 +228,15 @@ RSpec.describe PostStatusService do
|
|||
expect(media.reload.status).to be_nil
|
||||
end
|
||||
|
||||
it 'does not allow attaching more than 4 files' do
|
||||
it 'does not allow attaching more files than configured limit' do
|
||||
stub_const('Status::MEDIA_ATTACHMENTS_LIMIT', 1)
|
||||
account = Fabricate(:account)
|
||||
|
||||
expect do
|
||||
subject.call(
|
||||
account,
|
||||
text: 'test status update',
|
||||
media_ids: Array.new(5) { Fabricate(:media_attachment, account: account) }.map(&:id)
|
||||
media_ids: Array.new(2) { Fabricate(:media_attachment, account: account) }.map(&:id)
|
||||
)
|
||||
end.to raise_error(
|
||||
Mastodon::ValidationError,
|
||||
|
|
|
@ -45,8 +45,8 @@ RSpec.describe StatusPinValidator do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when pin.account.status_pins.count > 4 && pin.account.local?' do
|
||||
let(:count) { 5 }
|
||||
context 'when pin account is local and has too many pins' do
|
||||
let(:count) { described_class::PIN_LIMIT + 1 }
|
||||
let(:local) { true }
|
||||
|
||||
it 'calls errors.add' do
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
"allowJs": true,
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": "./",
|
||||
|
|
518
yarn.lock
518
yarn.lock
|
@ -1590,7 +1590,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/css-parser-algorithms@npm:^2.6.1, @csstools/css-parser-algorithms@npm:^2.6.3":
|
||||
"@csstools/css-parser-algorithms@npm:^2.6.3":
|
||||
version: 2.6.3
|
||||
resolution: "@csstools/css-parser-algorithms@npm:2.6.3"
|
||||
peerDependencies:
|
||||
|
@ -1599,14 +1599,14 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/css-tokenizer@npm:^2.2.4, @csstools/css-tokenizer@npm:^2.3.1":
|
||||
"@csstools/css-tokenizer@npm:^2.3.1":
|
||||
version: 2.3.1
|
||||
resolution: "@csstools/css-tokenizer@npm:2.3.1"
|
||||
checksum: 10c0/fed6619fb5108e109d4dd10b0e967035a92793bae8fb84544e1342058b6df4e306d9d075623e2201fe88831b1ada797aea3546a8d12229d2d81cd7a5dfee4444
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/media-query-list-parser@npm:^2.1.11, @csstools/media-query-list-parser@npm:^2.1.9":
|
||||
"@csstools/media-query-list-parser@npm:^2.1.11":
|
||||
version: 2.1.11
|
||||
resolution: "@csstools/media-query-list-parser@npm:2.1.11"
|
||||
peerDependencies:
|
||||
|
@ -1982,7 +1982,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/selector-specificity@npm:^3.0.3, @csstools/selector-specificity@npm:^3.1.1":
|
||||
"@csstools/selector-specificity@npm:^3.1.1":
|
||||
version: 3.1.1
|
||||
resolution: "@csstools/selector-specificity@npm:3.1.1"
|
||||
peerDependencies:
|
||||
|
@ -2007,10 +2007,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@dual-bundle/import-meta-resolve@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@dual-bundle/import-meta-resolve@npm:4.0.0"
|
||||
checksum: 10c0/868b8314fc753b7767887108535afe3288de941d92bc8453164dbcb1abe886b171e338f6f7d02ff556256dee69c90e4ac6360e0c6a856a5ad7190274ab52de2e
|
||||
"@dual-bundle/import-meta-resolve@npm:^4.1.0":
|
||||
version: 4.1.0
|
||||
resolution: "@dual-bundle/import-meta-resolve@npm:4.1.0"
|
||||
checksum: 10c0/55069e550ee2710e738dd8bbd34aba796cede456287454b50c3be46fbef8695d00625677f3f41f5ffbec1174c0f57f314da9a908388bc9f8ad41a8438db884d9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -2248,16 +2248,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/ecma402-abstract@npm:1.18.2":
|
||||
version: 1.18.2
|
||||
resolution: "@formatjs/ecma402-abstract@npm:1.18.2"
|
||||
dependencies:
|
||||
"@formatjs/intl-localematcher": "npm:0.5.4"
|
||||
tslib: "npm:^2.4.0"
|
||||
checksum: 10c0/87afb37dd937555e712ca85d5142a9083d617c491d1dddf8d660fdfb6186272d2bc75b78809b076388d26f016200c8bddbce73281fd707eb899da2bf3bc9b7ca
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/ecma402-abstract@npm:2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "@formatjs/ecma402-abstract@npm:2.0.0"
|
||||
|
@ -2277,17 +2267,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/icu-messageformat-parser@npm:2.7.6":
|
||||
version: 2.7.6
|
||||
resolution: "@formatjs/icu-messageformat-parser@npm:2.7.6"
|
||||
dependencies:
|
||||
"@formatjs/ecma402-abstract": "npm:1.18.2"
|
||||
"@formatjs/icu-skeleton-parser": "npm:1.8.0"
|
||||
tslib: "npm:^2.4.0"
|
||||
checksum: 10c0/9fc72c2075333a969601e2be4260638940b1abefd1a5fc15b93b0b10d2319c9df5778aa51fc2a173ce66ca5e8a47b4b64caca85a32d0eb6095e16e8d65cb4b00
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/icu-messageformat-parser@npm:2.7.8":
|
||||
version: 2.7.8
|
||||
resolution: "@formatjs/icu-messageformat-parser@npm:2.7.8"
|
||||
|
@ -2299,16 +2278,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/icu-skeleton-parser@npm:1.8.0":
|
||||
version: 1.8.0
|
||||
resolution: "@formatjs/icu-skeleton-parser@npm:1.8.0"
|
||||
dependencies:
|
||||
"@formatjs/ecma402-abstract": "npm:1.18.2"
|
||||
tslib: "npm:^2.4.0"
|
||||
checksum: 10c0/10956732d70cc67049d216410b5dc3ef048935d1ea2ae76f5755bb9d0243af37ddeabd5d140ddbf5f6c7047068c3d02a05f93c68a89cedfaf7488d5062885ea4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/icu-skeleton-parser@npm:1.8.2":
|
||||
version: 1.8.2
|
||||
resolution: "@formatjs/icu-skeleton-parser@npm:1.8.2"
|
||||
|
@ -2381,26 +2350,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/ts-transformer@npm:3.13.12":
|
||||
version: 3.13.12
|
||||
resolution: "@formatjs/ts-transformer@npm:3.13.12"
|
||||
dependencies:
|
||||
"@formatjs/icu-messageformat-parser": "npm:2.7.6"
|
||||
"@types/json-stable-stringify": "npm:^1.0.32"
|
||||
"@types/node": "npm:14 || 16 || 17"
|
||||
chalk: "npm:^4.0.0"
|
||||
json-stable-stringify: "npm:^1.0.1"
|
||||
tslib: "npm:^2.4.0"
|
||||
typescript: "npm:5"
|
||||
peerDependencies:
|
||||
ts-jest: ">=27"
|
||||
peerDependenciesMeta:
|
||||
ts-jest:
|
||||
optional: true
|
||||
checksum: 10c0/68f72ee6379b87b7ef6340e118a5370cb2fa18cbbae08f5f3d10893803a52f0533e644002e0b5e9ffeded5b2f0aa9daad6adf8b487b10f5d2b61f9fb3fed0dbd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/ts-transformer@npm:3.13.14":
|
||||
version: 3.13.14
|
||||
resolution: "@formatjs/ts-transformer@npm:3.13.14"
|
||||
|
@ -2874,7 +2823,7 @@ __metadata:
|
|||
eslint-plugin-import: "npm:~2.29.0"
|
||||
eslint-plugin-jsdoc: "npm:^48.0.0"
|
||||
eslint-plugin-jsx-a11y: "npm:~6.8.0"
|
||||
eslint-plugin-promise: "npm:~6.1.1"
|
||||
eslint-plugin-promise: "npm:~6.2.0"
|
||||
eslint-plugin-react: "npm:^7.33.2"
|
||||
eslint-plugin-react-hooks: "npm:^4.6.0"
|
||||
exif-js: "npm:^2.3.0"
|
||||
|
@ -3736,7 +3685,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8":
|
||||
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8":
|
||||
version: 7.0.15
|
||||
resolution: "@types/json-schema@npm:7.0.15"
|
||||
checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db
|
||||
|
@ -3979,12 +3928,12 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"@types/react@npm:*, @types/react@npm:16 || 17 || 18, @types/react@npm:>=16.9.11, @types/react@npm:^18.2.7":
|
||||
version: 18.3.2
|
||||
resolution: "@types/react@npm:18.3.2"
|
||||
version: 18.3.3
|
||||
resolution: "@types/react@npm:18.3.3"
|
||||
dependencies:
|
||||
"@types/prop-types": "npm:*"
|
||||
csstype: "npm:^3.0.2"
|
||||
checksum: 10c0/9fb2f1fcf7e889ee4ea7c3c5978df595c66e770e5fd3a245dbdd2589b9b911524c11dab25a6275d8af4e336e4cb5fa850d447884b84c335a187a338c89df99ba
|
||||
checksum: 10c0/fe455f805c5da13b89964c3d68060cebd43e73ec15001a68b34634604a78140e6fc202f3f61679b9d809dde6d7a7c2cb3ed51e0fd1462557911db09879b55114
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -4012,7 +3961,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/semver@npm:^7.5.0, @types/semver@npm:^7.5.8":
|
||||
"@types/semver@npm:^7.5.0":
|
||||
version: 7.5.8
|
||||
resolution: "@types/semver@npm:7.5.8"
|
||||
checksum: 10c0/8663ff927234d1c5fcc04b33062cb2b9fcfbe0f5f351ed26c4d1e1581657deebd506b41ff7fdf89e787e3d33ce05854bc01686379b89e9c49b564c4cfa988efa
|
||||
|
@ -4163,19 +4112,17 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"@typescript-eslint/eslint-plugin@npm:^7.0.0":
|
||||
version: 7.8.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:7.8.0"
|
||||
version: 7.10.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:7.10.0"
|
||||
dependencies:
|
||||
"@eslint-community/regexpp": "npm:^4.10.0"
|
||||
"@typescript-eslint/scope-manager": "npm:7.8.0"
|
||||
"@typescript-eslint/type-utils": "npm:7.8.0"
|
||||
"@typescript-eslint/utils": "npm:7.8.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.8.0"
|
||||
debug: "npm:^4.3.4"
|
||||
"@typescript-eslint/scope-manager": "npm:7.10.0"
|
||||
"@typescript-eslint/type-utils": "npm:7.10.0"
|
||||
"@typescript-eslint/utils": "npm:7.10.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.10.0"
|
||||
graphemer: "npm:^1.4.0"
|
||||
ignore: "npm:^5.3.1"
|
||||
natural-compare: "npm:^1.4.0"
|
||||
semver: "npm:^7.6.0"
|
||||
ts-api-utils: "npm:^1.3.0"
|
||||
peerDependencies:
|
||||
"@typescript-eslint/parser": ^7.0.0
|
||||
|
@ -4183,25 +4130,25 @@ __metadata:
|
|||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/37ca22620d1834ff0baa28fa4b8fd92039a3903cb95748353de32d56bae2a81ce50d1bbaed27487eebc884e0a0f9387fcb0f1647593e4e6df5111ef674afa9f0
|
||||
checksum: 10c0/bf3f0118ea5961c3eb01894678246458a329d82dda9ac7c2f5bfe77896410d05a08a4655e533bcb1ed2a3132ba6421981ec8c2ed0a3545779d9603ea231947ae
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/parser@npm:^7.0.0":
|
||||
version: 7.8.0
|
||||
resolution: "@typescript-eslint/parser@npm:7.8.0"
|
||||
version: 7.10.0
|
||||
resolution: "@typescript-eslint/parser@npm:7.10.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager": "npm:7.8.0"
|
||||
"@typescript-eslint/types": "npm:7.8.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.8.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.8.0"
|
||||
"@typescript-eslint/scope-manager": "npm:7.10.0"
|
||||
"@typescript-eslint/types": "npm:7.10.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.10.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.10.0"
|
||||
debug: "npm:^4.3.4"
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/0dd994c1b31b810c25e1b755b8d352debb7bf21a31f9a91acaec34acf4e471320bcceaa67cf64c110c0b8f5fac10a037dbabac6ec423e17adf037e59a7bce9c1
|
||||
checksum: 10c0/4c4fbf43b5b05d75b766acb803d3dd078c6e080641a77f9e48ba005713466738ea4a71f0564fa3ce520988d65158d14c8c952ba01ccbc431ab4a05935db5ce6d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -4215,22 +4162,22 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/scope-manager@npm:7.8.0":
|
||||
version: 7.8.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:7.8.0"
|
||||
"@typescript-eslint/scope-manager@npm:7.10.0":
|
||||
version: 7.10.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:7.10.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:7.8.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.8.0"
|
||||
checksum: 10c0/c253b98e96d4bf0375f473ca2c4d081726f1fd926cdfa65ee14c9ee99cca8eddb763b2d238ac365daa7246bef21b0af38180d04e56e9df7443c0e6f8474d097c
|
||||
"@typescript-eslint/types": "npm:7.10.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.10.0"
|
||||
checksum: 10c0/1d4f7ee137b95bd423b5a1b0d03251202dfc19bd8b6adfa5ff5df25fd5aa30e2d8ca50ab0d8d2e92441670ecbc2a82b3c2dbe39a4f268ec1ee1c1e267f7fd1d1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/type-utils@npm:7.8.0":
|
||||
version: 7.8.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:7.8.0"
|
||||
"@typescript-eslint/type-utils@npm:7.10.0":
|
||||
version: 7.10.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:7.10.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree": "npm:7.8.0"
|
||||
"@typescript-eslint/utils": "npm:7.8.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.10.0"
|
||||
"@typescript-eslint/utils": "npm:7.10.0"
|
||||
debug: "npm:^4.3.4"
|
||||
ts-api-utils: "npm:^1.3.0"
|
||||
peerDependencies:
|
||||
|
@ -4238,7 +4185,7 @@ __metadata:
|
|||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/00f6315626b64f7dbc1f7fba6f365321bb8d34141ed77545b2a07970e59a81dbdf768c1e024225ea00953750d74409ddd8a16782fc4a39261e507c04192dacab
|
||||
checksum: 10c0/55e9a6690f9cedb79d30abb1990b161affaa2684dac246b743223353812c9c1e3fd2d923c67b193c6a3624a07e1c82c900ce7bf5b6b9891c846f04cb480ebd9f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -4249,10 +4196,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/types@npm:7.8.0, @typescript-eslint/types@npm:^7.2.0":
|
||||
version: 7.8.0
|
||||
resolution: "@typescript-eslint/types@npm:7.8.0"
|
||||
checksum: 10c0/b2fdbfc21957bfa46f7d8809b607ad8c8b67c51821d899064d09392edc12f28b2318a044f0cd5d523d782e84e8f0558778877944964cf38e139f88790cf9d466
|
||||
"@typescript-eslint/types@npm:7.10.0, @typescript-eslint/types@npm:^7.2.0":
|
||||
version: 7.10.0
|
||||
resolution: "@typescript-eslint/types@npm:7.10.0"
|
||||
checksum: 10c0/f01d9330b93cc362ba7967ab5037396f64742076450e1f93139fa69cbe93a6ece3ed55d68ab780c9b7d07ef4a7c645da410305216a2cfc5dec7eba49ee65ab23
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -4275,12 +4222,12 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/typescript-estree@npm:7.8.0":
|
||||
version: 7.8.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:7.8.0"
|
||||
"@typescript-eslint/typescript-estree@npm:7.10.0":
|
||||
version: 7.10.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:7.10.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:7.8.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.8.0"
|
||||
"@typescript-eslint/types": "npm:7.10.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.10.0"
|
||||
debug: "npm:^4.3.4"
|
||||
globby: "npm:^11.1.0"
|
||||
is-glob: "npm:^4.0.3"
|
||||
|
@ -4290,24 +4237,21 @@ __metadata:
|
|||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/1690b62679685073dcb0f62499f0b52b445b37ae6e12d02aa4acbafe3fb023cf999b01f714b6282e88f84fd934fe3e2eefb21a64455d19c348d22bbc68ca8e47
|
||||
checksum: 10c0/6200695834c566e52e2fa7331f1a05019f7815969d8c1e1e237b85a99664d36f41ccc16384eff3f8582a0ecb75f1cc315b56ee9283b818da37f24fa4d42f1d7a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/utils@npm:7.8.0":
|
||||
version: 7.8.0
|
||||
resolution: "@typescript-eslint/utils@npm:7.8.0"
|
||||
"@typescript-eslint/utils@npm:7.10.0":
|
||||
version: 7.10.0
|
||||
resolution: "@typescript-eslint/utils@npm:7.10.0"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.4.0"
|
||||
"@types/json-schema": "npm:^7.0.15"
|
||||
"@types/semver": "npm:^7.5.8"
|
||||
"@typescript-eslint/scope-manager": "npm:7.8.0"
|
||||
"@typescript-eslint/types": "npm:7.8.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.8.0"
|
||||
semver: "npm:^7.6.0"
|
||||
"@typescript-eslint/scope-manager": "npm:7.10.0"
|
||||
"@typescript-eslint/types": "npm:7.10.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.10.0"
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
checksum: 10c0/31fb58388d15b082eb7bd5bce889cc11617aa1131dfc6950471541b3df64c82d1c052e2cccc230ca4ae80456d4f63a3e5dccb79899a8f3211ce36c089b7d7640
|
||||
checksum: 10c0/6724471f94f2788f59748f7efa2a3a53ea910099993bee2fa5746ab5acacecdc9fcb110c568b18099ddc946ea44919ed394bff2bd055ba81fc69f5e6297b73bf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -4338,13 +4282,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/visitor-keys@npm:7.8.0":
|
||||
version: 7.8.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:7.8.0"
|
||||
"@typescript-eslint/visitor-keys@npm:7.10.0":
|
||||
version: 7.10.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:7.10.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:7.8.0"
|
||||
"@typescript-eslint/types": "npm:7.10.0"
|
||||
eslint-visitor-keys: "npm:^3.4.3"
|
||||
checksum: 10c0/5892fb5d9c58efaf89adb225f7dbbb77f9363961f2ff420b6b130bdd102dddd7aa8a16c46a5a71c19889d27b781e966119a89270555ea2cb5653a04d8994123d
|
||||
checksum: 10c0/049e812bcd28869059d04c7bf3543bb55f5205f468b777439c4f120417fb856fb6024cb1d25291aa12556bd08e84f043a96d754ffb2cde37abb604d6f3c51634
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -5619,12 +5563,12 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"braces@npm:^3.0.2, braces@npm:~3.0.2":
|
||||
version: 3.0.2
|
||||
resolution: "braces@npm:3.0.2"
|
||||
"braces@npm:^3.0.3, braces@npm:~3.0.2":
|
||||
version: 3.0.3
|
||||
resolution: "braces@npm:3.0.3"
|
||||
dependencies:
|
||||
fill-range: "npm:^7.0.1"
|
||||
checksum: 10c0/321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381
|
||||
fill-range: "npm:^7.1.1"
|
||||
checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -5927,13 +5871,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chalk@npm:5.3.0":
|
||||
version: 5.3.0
|
||||
resolution: "chalk@npm:5.3.0"
|
||||
checksum: 10c0/8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chalk@npm:^2.4.1, chalk@npm:^2.4.2":
|
||||
version: 2.4.2
|
||||
resolution: "chalk@npm:2.4.2"
|
||||
|
@ -5965,6 +5902,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chalk@npm:~5.3.0":
|
||||
version: 5.3.0
|
||||
resolution: "chalk@npm:5.3.0"
|
||||
checksum: 10c0/8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"char-regex@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "char-regex@npm:1.0.2"
|
||||
|
@ -6257,13 +6201,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"commander@npm:11.1.0":
|
||||
version: 11.1.0
|
||||
resolution: "commander@npm:11.1.0"
|
||||
checksum: 10c0/13cc6ac875e48780250f723fb81c1c1178d35c5decb1abb1b628b3177af08a8554e76b2c0f29de72d69eef7c864d12613272a71fabef8047922bc622ab75a179
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"commander@npm:^2.20.0":
|
||||
version: 2.20.3
|
||||
resolution: "commander@npm:2.20.3"
|
||||
|
@ -6278,6 +6215,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"commander@npm:~12.1.0":
|
||||
version: 12.1.0
|
||||
resolution: "commander@npm:12.1.0"
|
||||
checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"comment-parser@npm:1.4.1":
|
||||
version: 1.4.1
|
||||
resolution: "comment-parser@npm:1.4.1"
|
||||
|
@ -6957,7 +6901,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4":
|
||||
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:~4.3.4":
|
||||
version: 4.3.4
|
||||
resolution: "debug@npm:4.3.4"
|
||||
dependencies:
|
||||
|
@ -7835,11 +7779,11 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"eslint-plugin-formatjs@npm:^4.10.1":
|
||||
version: 4.13.1
|
||||
resolution: "eslint-plugin-formatjs@npm:4.13.1"
|
||||
version: 4.13.3
|
||||
resolution: "eslint-plugin-formatjs@npm:4.13.3"
|
||||
dependencies:
|
||||
"@formatjs/icu-messageformat-parser": "npm:2.7.6"
|
||||
"@formatjs/ts-transformer": "npm:3.13.12"
|
||||
"@formatjs/icu-messageformat-parser": "npm:2.7.8"
|
||||
"@formatjs/ts-transformer": "npm:3.13.14"
|
||||
"@types/eslint": "npm:7 || 8"
|
||||
"@types/picomatch": "npm:^2.3.0"
|
||||
"@typescript-eslint/utils": "npm:^6.18.1"
|
||||
|
@ -7851,7 +7795,7 @@ __metadata:
|
|||
unicode-emoji-utils: "npm:^1.2.0"
|
||||
peerDependencies:
|
||||
eslint: 7 || 8
|
||||
checksum: 10c0/ce18141dff84e8fe026127085c1a63279acb3a1bc0b70dc1ddce2fc65bb37d68ccf6d097231428745eda2caea42080e1c80a01a1895803155c15123a01bfeee3
|
||||
checksum: 10c0/5e98f487a097189e3bdc64b678d19f4c83502c32d7c89a8959eda4ed9cb664bf16f13ad8871be89ca192cb39c1007d6a158c39bbf5b23c56962d949dbe9abfab
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -7883,8 +7827,8 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"eslint-plugin-jsdoc@npm:^48.0.0":
|
||||
version: 48.2.4
|
||||
resolution: "eslint-plugin-jsdoc@npm:48.2.4"
|
||||
version: 48.2.6
|
||||
resolution: "eslint-plugin-jsdoc@npm:48.2.6"
|
||||
dependencies:
|
||||
"@es-joy/jsdoccomment": "npm:~0.43.0"
|
||||
are-docs-informative: "npm:^0.0.2"
|
||||
|
@ -7892,12 +7836,11 @@ __metadata:
|
|||
debug: "npm:^4.3.4"
|
||||
escape-string-regexp: "npm:^4.0.0"
|
||||
esquery: "npm:^1.5.0"
|
||||
is-builtin-module: "npm:^3.2.1"
|
||||
semver: "npm:^7.6.0"
|
||||
semver: "npm:^7.6.1"
|
||||
spdx-expression-parse: "npm:^4.0.0"
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
|
||||
checksum: 10c0/601c9d6ee41de56102c7813106ceb0b8b8342223670f7add010a8f89753c250cde4cc93e353e3911b7b29677f2634f3f4be45f27abb7a95c6fdbd058adfa3343
|
||||
checksum: 10c0/9f01b3000aa31f17767786c62caf62f1e8c4b88bfef04b207d3b1de785be287cc2da3ad16ed32afacd5f6e6a9b76ebf3369069be416ce2228c44cd6d084fcd8f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -7927,12 +7870,12 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-plugin-promise@npm:~6.1.1":
|
||||
version: 6.1.1
|
||||
resolution: "eslint-plugin-promise@npm:6.1.1"
|
||||
"eslint-plugin-promise@npm:~6.2.0":
|
||||
version: 6.2.0
|
||||
resolution: "eslint-plugin-promise@npm:6.2.0"
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0
|
||||
checksum: 10c0/ec705741c110cd1cb4d702776e1c7f7fe60b671b71f706c88054ab443cf2767aae5a663928fb426373ba1095eaeda312a740a4f880546631f0e0727f298b3393
|
||||
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
|
||||
checksum: 10c0/5f42ee774023c089453ecb792076c64c6d0739ea6e9d6cdc9d6a63da5ba928c776e349d01cc110548f2c67045ec55343136aa7eb8b486e4ab145ac016c06a492
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -8175,23 +8118,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"execa@npm:8.0.1":
|
||||
version: 8.0.1
|
||||
resolution: "execa@npm:8.0.1"
|
||||
dependencies:
|
||||
cross-spawn: "npm:^7.0.3"
|
||||
get-stream: "npm:^8.0.1"
|
||||
human-signals: "npm:^5.0.0"
|
||||
is-stream: "npm:^3.0.0"
|
||||
merge-stream: "npm:^2.0.0"
|
||||
npm-run-path: "npm:^5.1.0"
|
||||
onetime: "npm:^6.0.0"
|
||||
signal-exit: "npm:^4.1.0"
|
||||
strip-final-newline: "npm:^3.0.0"
|
||||
checksum: 10c0/2c52d8775f5bf103ce8eec9c7ab3059909ba350a5164744e9947ed14a53f51687c040a250bda833f906d1283aa8803975b84e6c8f7a7c42f99dc8ef80250d1af
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"execa@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "execa@npm:1.0.0"
|
||||
|
@ -8224,6 +8150,23 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"execa@npm:~8.0.1":
|
||||
version: 8.0.1
|
||||
resolution: "execa@npm:8.0.1"
|
||||
dependencies:
|
||||
cross-spawn: "npm:^7.0.3"
|
||||
get-stream: "npm:^8.0.1"
|
||||
human-signals: "npm:^5.0.0"
|
||||
is-stream: "npm:^3.0.0"
|
||||
merge-stream: "npm:^2.0.0"
|
||||
npm-run-path: "npm:^5.1.0"
|
||||
onetime: "npm:^6.0.0"
|
||||
signal-exit: "npm:^4.1.0"
|
||||
strip-final-newline: "npm:^3.0.0"
|
||||
checksum: 10c0/2c52d8775f5bf103ce8eec9c7ab3059909ba350a5164744e9947ed14a53f51687c040a250bda833f906d1283aa8803975b84e6c8f7a7c42f99dc8ef80250d1af
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"exif-js@npm:^2.3.0":
|
||||
version: 2.3.0
|
||||
resolution: "exif-js@npm:2.3.0"
|
||||
|
@ -8356,10 +8299,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-copy@npm:^3.0.0":
|
||||
version: 3.0.1
|
||||
resolution: "fast-copy@npm:3.0.1"
|
||||
checksum: 10c0/a8310dbcc4c94ed001dc3e0bbc3c3f0491bb04e6c17163abe441a54997ba06cdf1eb532c2f05e54777c6f072c84548c23ef0ecd54665cd611be1d42f37eca258
|
||||
"fast-copy@npm:^3.0.2":
|
||||
version: 3.0.2
|
||||
resolution: "fast-copy@npm:3.0.2"
|
||||
checksum: 10c0/02e8b9fd03c8c024d2987760ce126456a0e17470850b51e11a1c3254eed6832e4733ded2d93316c82bc0b36aeb991ad1ff48d1ba95effe7add7c3ab8d8eb554a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -8517,12 +8460,12 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fill-range@npm:^7.0.1":
|
||||
version: 7.0.1
|
||||
resolution: "fill-range@npm:7.0.1"
|
||||
"fill-range@npm:^7.1.1":
|
||||
version: 7.1.1
|
||||
resolution: "fill-range@npm:7.1.1"
|
||||
dependencies:
|
||||
to-regex-range: "npm:^5.0.1"
|
||||
checksum: 10c0/7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f
|
||||
checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -9416,13 +9359,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"http-proxy-agent@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "http-proxy-agent@npm:7.0.0"
|
||||
"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.2":
|
||||
version: 7.0.2
|
||||
resolution: "http-proxy-agent@npm:7.0.2"
|
||||
dependencies:
|
||||
agent-base: "npm:^7.1.0"
|
||||
debug: "npm:^4.3.4"
|
||||
checksum: 10c0/a11574ff39436cee3c7bc67f259444097b09474605846ddd8edf0bf4ad8644be8533db1aa463426e376865047d05dc22755e638632819317c0c2f1b2196657c8
|
||||
checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -9466,13 +9409,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2":
|
||||
version: 7.0.2
|
||||
resolution: "https-proxy-agent@npm:7.0.2"
|
||||
"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.4":
|
||||
version: 7.0.4
|
||||
resolution: "https-proxy-agent@npm:7.0.4"
|
||||
dependencies:
|
||||
agent-base: "npm:^7.0.2"
|
||||
debug: "npm:4"
|
||||
checksum: 10c0/7735eb90073db087e7e79312e3d97c8c04baf7ea7ca7b013382b6a45abbaa61b281041a98f4e13c8c80d88f843785bcc84ba189165b4b4087b1e3496ba656d77
|
||||
checksum: 10c0/bc4f7c38da32a5fc622450b6cb49a24ff596f9bd48dcedb52d2da3fa1c1a80e100fb506bd59b326c012f21c863c69b275c23de1a01d0b84db396822fdf25e52b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -11034,36 +10977,36 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"jsdom@npm:^24.0.0":
|
||||
version: 24.0.0
|
||||
resolution: "jsdom@npm:24.0.0"
|
||||
version: 24.1.0
|
||||
resolution: "jsdom@npm:24.1.0"
|
||||
dependencies:
|
||||
cssstyle: "npm:^4.0.1"
|
||||
data-urls: "npm:^5.0.0"
|
||||
decimal.js: "npm:^10.4.3"
|
||||
form-data: "npm:^4.0.0"
|
||||
html-encoding-sniffer: "npm:^4.0.0"
|
||||
http-proxy-agent: "npm:^7.0.0"
|
||||
https-proxy-agent: "npm:^7.0.2"
|
||||
http-proxy-agent: "npm:^7.0.2"
|
||||
https-proxy-agent: "npm:^7.0.4"
|
||||
is-potential-custom-element-name: "npm:^1.0.1"
|
||||
nwsapi: "npm:^2.2.7"
|
||||
nwsapi: "npm:^2.2.10"
|
||||
parse5: "npm:^7.1.2"
|
||||
rrweb-cssom: "npm:^0.6.0"
|
||||
rrweb-cssom: "npm:^0.7.0"
|
||||
saxes: "npm:^6.0.0"
|
||||
symbol-tree: "npm:^3.2.4"
|
||||
tough-cookie: "npm:^4.1.3"
|
||||
tough-cookie: "npm:^4.1.4"
|
||||
w3c-xmlserializer: "npm:^5.0.0"
|
||||
webidl-conversions: "npm:^7.0.0"
|
||||
whatwg-encoding: "npm:^3.1.1"
|
||||
whatwg-mimetype: "npm:^4.0.0"
|
||||
whatwg-url: "npm:^14.0.0"
|
||||
ws: "npm:^8.16.0"
|
||||
ws: "npm:^8.17.0"
|
||||
xml-name-validator: "npm:^5.0.0"
|
||||
peerDependencies:
|
||||
canvas: ^2.11.2
|
||||
peerDependenciesMeta:
|
||||
canvas:
|
||||
optional: true
|
||||
checksum: 10c0/7b35043d7af39ad6dcaef0fa5679d8c8a94c6c9b6cc4a79222b7c9987d57ab7150c50856684ae56b473ab28c7d82aec0fb7ca19dcbd4c3f46683c807d717a3af
|
||||
checksum: 10c0/34eadd8a7ae20c1505abe7a0f3988b2f0881cce7e27d75c4f5224f440f81f8ac08f4f449695b0f4178f048ed1c1709f3594e9d3f2fe0406c28e8da6eddd44f5a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -11253,10 +11196,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"known-css-properties@npm:^0.30.0":
|
||||
version: 0.30.0
|
||||
resolution: "known-css-properties@npm:0.30.0"
|
||||
checksum: 10c0/8b487a6b33487affcec41eb392ceb77acf4d093558dde5c88b5ea06b9a3c81781876d7cb09872e0518b9602f27c8f4112c9ac333e02c90a91c8fbd12e202ed48
|
||||
"known-css-properties@npm:^0.31.0":
|
||||
version: 0.31.0
|
||||
resolution: "known-css-properties@npm:0.31.0"
|
||||
checksum: 10c0/8e643cbed32d7733278ba215c43dfc38fc7e77d391f66b81f07228af97d69ce2cebba03a9bc1ac859479e162aea812e258b30f4c93cb7b7adfd0622a141d36da
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -11293,14 +11236,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lilconfig@npm:3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "lilconfig@npm:3.0.0"
|
||||
checksum: 10c0/7f5ee7a658dc016cacf146815e8d88b06f06f4402823b8b0934e305a57a197f55ccc9c5cd4fb5ea1b2b821c8ccaf2d54abd59602a4931af06eabda332388d3e6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lilconfig@npm:^3.1.1":
|
||||
"lilconfig@npm:^3.1.1, lilconfig@npm:~3.1.1":
|
||||
version: 3.1.1
|
||||
resolution: "lilconfig@npm:3.1.1"
|
||||
checksum: 10c0/311b559794546894e3fe176663427326026c1c644145be9e8041c58e268aa9328799b8dfe7e4dd8c6a4ae305feae95a1c9e007db3569f35b42b6e1bc8274754c
|
||||
|
@ -11315,36 +11251,36 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"lint-staged@npm:^15.0.0":
|
||||
version: 15.2.2
|
||||
resolution: "lint-staged@npm:15.2.2"
|
||||
version: 15.2.5
|
||||
resolution: "lint-staged@npm:15.2.5"
|
||||
dependencies:
|
||||
chalk: "npm:5.3.0"
|
||||
commander: "npm:11.1.0"
|
||||
debug: "npm:4.3.4"
|
||||
execa: "npm:8.0.1"
|
||||
lilconfig: "npm:3.0.0"
|
||||
listr2: "npm:8.0.1"
|
||||
micromatch: "npm:4.0.5"
|
||||
pidtree: "npm:0.6.0"
|
||||
string-argv: "npm:0.3.2"
|
||||
yaml: "npm:2.3.4"
|
||||
chalk: "npm:~5.3.0"
|
||||
commander: "npm:~12.1.0"
|
||||
debug: "npm:~4.3.4"
|
||||
execa: "npm:~8.0.1"
|
||||
lilconfig: "npm:~3.1.1"
|
||||
listr2: "npm:~8.2.1"
|
||||
micromatch: "npm:~4.0.7"
|
||||
pidtree: "npm:~0.6.0"
|
||||
string-argv: "npm:~0.3.2"
|
||||
yaml: "npm:~2.4.2"
|
||||
bin:
|
||||
lint-staged: bin/lint-staged.js
|
||||
checksum: 10c0/a1ba6c7ee53e30a0f6ea9a351d95d3d0d2be916a41b561e22907e9ea513eb18cb3dbe65bff3ec13fad15777999efe56b2e2a95427e31d12a9b7e7948c3630ee2
|
||||
checksum: 10c0/89c54489783510f86df15756659facade82e849c0cbfb564fe047b82be91c5d2b1b5608a4bfc5237bd7b9fd0e1206e66aa3e4f8cad3ac51e37a098b8492c2fa6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"listr2@npm:8.0.1":
|
||||
version: 8.0.1
|
||||
resolution: "listr2@npm:8.0.1"
|
||||
"listr2@npm:~8.2.1":
|
||||
version: 8.2.1
|
||||
resolution: "listr2@npm:8.2.1"
|
||||
dependencies:
|
||||
cli-truncate: "npm:^4.0.0"
|
||||
colorette: "npm:^2.0.20"
|
||||
eventemitter3: "npm:^5.0.1"
|
||||
log-update: "npm:^6.0.0"
|
||||
rfdc: "npm:^1.3.0"
|
||||
rfdc: "npm:^1.3.1"
|
||||
wrap-ansi: "npm:^9.0.0"
|
||||
checksum: 10c0/b565d6ceb3a4c2dbe0c1735c0fd907afd0d6f89de21aced8e05187b2d88ca2f8f9ebc5d743885396a00f05f13146f6be744d098a56ce0402cf1cd131485a7ff1
|
||||
checksum: 10c0/ac32cba8e5c79bcf0dbbb43c2fcc73e47902320c1fa1891074fefb3aa3dfaeef9c76348da22909f65334ba9bee1140bfc903e2f0c64427dd08ef4ba8f6b1dbd0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -11786,16 +11722,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"micromatch@npm:4.0.5, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
|
||||
version: 4.0.5
|
||||
resolution: "micromatch@npm:4.0.5"
|
||||
dependencies:
|
||||
braces: "npm:^3.0.2"
|
||||
picomatch: "npm:^2.3.1"
|
||||
checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"micromatch@npm:^3.0.4, micromatch@npm:^3.1.10, micromatch@npm:^3.1.4":
|
||||
version: 3.1.10
|
||||
resolution: "micromatch@npm:3.1.10"
|
||||
|
@ -11817,6 +11743,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"micromatch@npm:^4.0.4, micromatch@npm:^4.0.5, micromatch@npm:~4.0.7":
|
||||
version: 4.0.7
|
||||
resolution: "micromatch@npm:4.0.7"
|
||||
dependencies:
|
||||
braces: "npm:^3.0.3"
|
||||
picomatch: "npm:^2.3.1"
|
||||
checksum: 10c0/58fa99bc5265edec206e9163a1d2cec5fabc46a5b473c45f4a700adce88c2520456ae35f2b301e4410fb3afb27e9521fb2813f6fc96be0a48a89430e0916a772
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"miller-rabin@npm:^4.0.0":
|
||||
version: 4.0.1
|
||||
resolution: "miller-rabin@npm:4.0.1"
|
||||
|
@ -12363,10 +12299,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nwsapi@npm:^2.2.2, nwsapi@npm:^2.2.7":
|
||||
version: 2.2.7
|
||||
resolution: "nwsapi@npm:2.2.7"
|
||||
checksum: 10c0/44be198adae99208487a1c886c0a3712264f7bbafa44368ad96c003512fed2753d4e22890ca1e6edb2690c3456a169f2a3c33bfacde1905cf3bf01c7722464db
|
||||
"nwsapi@npm:^2.2.10, nwsapi@npm:^2.2.2":
|
||||
version: 2.2.10
|
||||
resolution: "nwsapi@npm:2.2.10"
|
||||
checksum: 10c0/43dfa150387bd2a578e37556d0ae3330d5617f99e5a7b64e3400d4c2785620762aa6169caf8f5fbce17b7ef29c372060b602594320c374fba0a39da4163d77ed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -13010,10 +12946,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"picocolors@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "picocolors@npm:1.0.0"
|
||||
checksum: 10c0/20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7
|
||||
"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "picocolors@npm:1.0.1"
|
||||
checksum: 10c0/c63cdad2bf812ef0d66c8db29583802355d4ca67b9285d846f390cc15c2f6ccb94e8cb7eb6a6e97fc5990a6d3ad4ae42d86c84d3146e667c739a4234ed50d400
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -13024,7 +12960,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pidtree@npm:0.6.0":
|
||||
"pidtree@npm:~0.6.0":
|
||||
version: 0.6.0
|
||||
resolution: "pidtree@npm:0.6.0"
|
||||
bin:
|
||||
|
@ -13093,12 +13029,12 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"pino-pretty@npm:^11.0.0":
|
||||
version: 11.0.0
|
||||
resolution: "pino-pretty@npm:11.0.0"
|
||||
version: 11.1.0
|
||||
resolution: "pino-pretty@npm:11.1.0"
|
||||
dependencies:
|
||||
colorette: "npm:^2.0.7"
|
||||
dateformat: "npm:^4.6.3"
|
||||
fast-copy: "npm:^3.0.0"
|
||||
fast-copy: "npm:^3.0.2"
|
||||
fast-safe-stringify: "npm:^2.1.1"
|
||||
help-me: "npm:^5.0.0"
|
||||
joycon: "npm:^3.1.1"
|
||||
|
@ -13108,11 +13044,11 @@ __metadata:
|
|||
pump: "npm:^3.0.0"
|
||||
readable-stream: "npm:^4.0.0"
|
||||
secure-json-parse: "npm:^2.4.0"
|
||||
sonic-boom: "npm:^3.0.0"
|
||||
sonic-boom: "npm:^4.0.1"
|
||||
strip-json-comments: "npm:^3.1.1"
|
||||
bin:
|
||||
pino-pretty: bin.js
|
||||
checksum: 10c0/d42213f3fdf19d92152b0a14683b2bb8443423739c81ab7c1181a5dac0e0ca7621d232c8264ece81edc01106ca2a8e165783daca0a902f0fde480027075d5540
|
||||
checksum: 10c0/418be6f854b0d62c83c65e75b0969d5311792bfadeefbfe77d8a7f8c5ba26b8bea40f549222b5f500439f440eb4d6c2fa99d712bdd02881ebae7be3a0193b581
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -15224,10 +15160,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rfdc@npm:^1.3.0":
|
||||
version: 1.3.0
|
||||
resolution: "rfdc@npm:1.3.0"
|
||||
checksum: 10c0/a17fd7b81f42c7ae4cb932abd7b2f677b04cc462a03619fb46945ae1ccae17c3bc87c020ffdde1751cbfa8549860a2883486fdcabc9b9de3f3108af32b69a667
|
||||
"rfdc@npm:^1.3.1":
|
||||
version: 1.3.1
|
||||
resolution: "rfdc@npm:1.3.1"
|
||||
checksum: 10c0/69f65e3ed30970f8055fac9fbbef9ce578800ca19554eab1dcbffe73a4b8aef536bc4248313889cf25e3b4e38b212c721eabe30856575bf2b2bc3d90f8ba93ef
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -15295,6 +15231,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rrweb-cssom@npm:^0.7.0":
|
||||
version: 0.7.0
|
||||
resolution: "rrweb-cssom@npm:0.7.0"
|
||||
checksum: 10c0/278350b1f383f76db20e37394361b709740bd4f5f27f924e1c3c3fdd7112b2ae37ed9bc7cee63776f7df395b9b0f644d1f8be104990e3028d276a3288cd7e564
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"run-parallel@npm:^1.1.9":
|
||||
version: 1.2.0
|
||||
resolution: "run-parallel@npm:1.2.0"
|
||||
|
@ -15511,14 +15454,12 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0":
|
||||
version: 7.6.0
|
||||
resolution: "semver@npm:7.6.0"
|
||||
dependencies:
|
||||
lru-cache: "npm:^6.0.0"
|
||||
"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.1":
|
||||
version: 7.6.2
|
||||
resolution: "semver@npm:7.6.2"
|
||||
bin:
|
||||
semver: bin/semver.js
|
||||
checksum: 10c0/fbfe717094ace0aa8d6332d7ef5ce727259815bd8d8815700853f4faf23aacbd7192522f0dc5af6df52ef4fa85a355ebd2f5d39f554bd028200d6cf481ab9b53
|
||||
checksum: 10c0/97d3441e97ace8be4b1976433d1c32658f6afaff09f143e52c593bae7eef33de19e3e369c88bd985ce1042c6f441c80c6803078d1de2a9988080b66684cbb30c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -15889,15 +15830,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sonic-boom@npm:^3.0.0":
|
||||
version: 3.7.0
|
||||
resolution: "sonic-boom@npm:3.7.0"
|
||||
dependencies:
|
||||
atomic-sleep: "npm:^1.0.0"
|
||||
checksum: 10c0/57a3d560efb77f4576db111168ee2649c99e7869fda6ce0ec2a4e5458832d290ba58d74b073ddb5827d9a30f96d23cff79157993d919e1a6d5f28d8b6391c7f0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sonic-boom@npm:^4.0.1":
|
||||
version: 4.0.1
|
||||
resolution: "sonic-boom@npm:4.0.1"
|
||||
|
@ -16204,7 +16136,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"string-argv@npm:0.3.2":
|
||||
"string-argv@npm:~0.3.2":
|
||||
version: 0.3.2
|
||||
resolution: "string-argv@npm:0.3.2"
|
||||
checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82
|
||||
|
@ -16528,14 +16460,14 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"stylelint@npm:^16.0.2":
|
||||
version: 16.5.0
|
||||
resolution: "stylelint@npm:16.5.0"
|
||||
version: 16.6.0
|
||||
resolution: "stylelint@npm:16.6.0"
|
||||
dependencies:
|
||||
"@csstools/css-parser-algorithms": "npm:^2.6.1"
|
||||
"@csstools/css-tokenizer": "npm:^2.2.4"
|
||||
"@csstools/media-query-list-parser": "npm:^2.1.9"
|
||||
"@csstools/selector-specificity": "npm:^3.0.3"
|
||||
"@dual-bundle/import-meta-resolve": "npm:^4.0.0"
|
||||
"@csstools/css-parser-algorithms": "npm:^2.6.3"
|
||||
"@csstools/css-tokenizer": "npm:^2.3.1"
|
||||
"@csstools/media-query-list-parser": "npm:^2.1.11"
|
||||
"@csstools/selector-specificity": "npm:^3.1.1"
|
||||
"@dual-bundle/import-meta-resolve": "npm:^4.1.0"
|
||||
balanced-match: "npm:^2.0.0"
|
||||
colord: "npm:^2.9.3"
|
||||
cosmiconfig: "npm:^9.0.0"
|
||||
|
@ -16552,16 +16484,16 @@ __metadata:
|
|||
ignore: "npm:^5.3.1"
|
||||
imurmurhash: "npm:^0.1.4"
|
||||
is-plain-object: "npm:^5.0.0"
|
||||
known-css-properties: "npm:^0.30.0"
|
||||
known-css-properties: "npm:^0.31.0"
|
||||
mathml-tag-names: "npm:^2.1.3"
|
||||
meow: "npm:^13.2.0"
|
||||
micromatch: "npm:^4.0.5"
|
||||
normalize-path: "npm:^3.0.0"
|
||||
picocolors: "npm:^1.0.0"
|
||||
picocolors: "npm:^1.0.1"
|
||||
postcss: "npm:^8.4.38"
|
||||
postcss-resolve-nested-selector: "npm:^0.1.1"
|
||||
postcss-safe-parser: "npm:^7.0.0"
|
||||
postcss-selector-parser: "npm:^6.0.16"
|
||||
postcss-selector-parser: "npm:^6.1.0"
|
||||
postcss-value-parser: "npm:^4.2.0"
|
||||
resolve-from: "npm:^5.0.0"
|
||||
string-width: "npm:^4.2.3"
|
||||
|
@ -16572,7 +16504,7 @@ __metadata:
|
|||
write-file-atomic: "npm:^5.0.1"
|
||||
bin:
|
||||
stylelint: bin/stylelint.mjs
|
||||
checksum: 10c0/9281693ff6c1918e07fdcf7a950531f79678a28261a0d5bd36ca2fcf524e53d7305158d20ba890f5dd01c0ff90c09a13453dce2fe6887f4c157d8c2c0acf3666
|
||||
checksum: 10c0/acfb7983a0b71677d066b2aa570eefdac0a7be2e21351bac8884b8156deaeec19e53ad128ae7ae7933c79f6045f1de8d759ba06cfbc373b2711015860805a3e7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -16973,15 +16905,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tough-cookie@npm:^4.1.2, tough-cookie@npm:^4.1.3":
|
||||
version: 4.1.3
|
||||
resolution: "tough-cookie@npm:4.1.3"
|
||||
"tough-cookie@npm:^4.1.2, tough-cookie@npm:^4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "tough-cookie@npm:4.1.4"
|
||||
dependencies:
|
||||
psl: "npm:^1.1.33"
|
||||
punycode: "npm:^2.1.1"
|
||||
universalify: "npm:^0.2.0"
|
||||
url-parse: "npm:^1.5.3"
|
||||
checksum: 10c0/4fc0433a0cba370d57c4b240f30440c848906dee3180bb6e85033143c2726d322e7e4614abb51d42d111ebec119c4876ed8d7247d4113563033eebbc1739c831
|
||||
checksum: 10c0/aca7ff96054f367d53d1e813e62ceb7dd2eda25d7752058a74d64b7266fd07be75908f3753a32ccf866a2f997604b414cfb1916d6e7f69bc64d9d9939b0d6c45
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -18395,7 +18327,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.16.0":
|
||||
"ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.17.0":
|
||||
version: 8.17.0
|
||||
resolution: "ws@npm:8.17.0"
|
||||
peerDependencies:
|
||||
|
@ -18466,13 +18398,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yaml@npm:2.3.4":
|
||||
version: 2.3.4
|
||||
resolution: "yaml@npm:2.3.4"
|
||||
checksum: 10c0/cf03b68f8fef5e8516b0f0b54edaf2459f1648317fc6210391cf606d247e678b449382f4bd01f77392538429e306c7cba8ff46ff6b37cac4de9a76aff33bd9e1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yaml@npm:^1.10.0":
|
||||
version: 1.10.2
|
||||
resolution: "yaml@npm:1.10.2"
|
||||
|
@ -18480,6 +18405,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yaml@npm:~2.4.2":
|
||||
version: 2.4.2
|
||||
resolution: "yaml@npm:2.4.2"
|
||||
bin:
|
||||
yaml: bin.mjs
|
||||
checksum: 10c0/280ddb2e43ffa7d91a95738e80c8f33e860749cdc25aa6d9e4d350a28e174fd7e494e4aa023108aaee41388e451e3dc1292261d8f022aabcf90df9c63d647549
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yargs-parser@npm:^13.1.2":
|
||||
version: 13.1.2
|
||||
resolution: "yargs-parser@npm:13.1.2"
|
||||
|
|
Loading…
Reference in a new issue